Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

TWI I2C problem with implementation.

Hello,

I have a problem through which unfortunately I'm not able to come across alone. I'm using nRF52832 with softdevice and UART central example from SDK14.2 (..\examples\ble_central\ble_app_uart_c\pca10040\s132\arm5_no_packs). Right now I'm trying to communicate my nordic device with LED display which is using ssd1306 libraries. Problem occures at the moment when I'm trying to use nrf_drv_twi_tx() function to transmit datas over TWI.

Of course I've set all necessary items in sdk_config file as below:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// <e> TWI_ENABLED - nrf_drv_twi - TWI/TWIM peripheral driver
//==========================================================
#ifndef TWI_ENABLED
#define TWI_ENABLED 1
#endif
// <o> TWI_DEFAULT_CONFIG_FREQUENCY - Frequency
// <26738688=> 100k
// <67108864=> 250k
// <104857600=> 400k
#ifndef TWI_DEFAULT_CONFIG_FREQUENCY
#define TWI_DEFAULT_CONFIG_FREQUENCY 26738688
#endif
// <q> TWI_DEFAULT_CONFIG_CLR_BUS_INIT - Enables bus clearing procedure during init
#ifndef TWI_DEFAULT_CONFIG_CLR_BUS_INIT
#define TWI_DEFAULT_CONFIG_CLR_BUS_INIT 0
#endif
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Below I've paste  my twi init code:

Fullscreen
1
2
3
4
5
6
7
8
9
#define SSD1306_CONFIG_SCL_PIN ARDUINO_SCL_PIN //from pca10040.h 27 SCL signal pin
#define SSD1306_CONFIG_SDA_PIN ARDUINO_SDA_PIN //from pca10040.h 26 SDA signal pin
...
void ssd1306init() {
ssd1306_init_i2c(SSD1306_CONFIG_SCL_PIN, SSD1306_CONFIG_SDA_PIN);
ssd1306_begin(SSD1306_EXTERNALVCC, SSD1306_I2C_ADDRESS, false);
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Than in ssd1306_init_i2c() function:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void ssd1306_init_i2c(uint32_t scl, uint32_t sda)
{
_i2caddr = SSD1306_I2C_ADDRESS;
use_i2c = true;
twi_master_init(scl, sda);
}
void twi_master_init(uint32_t scl, uint32_t sda)
{
ret_code_t ret;
const nrf_drv_twi_config_t config = {
.scl = scl,
.sda = sda,
.frequency = NRF_TWI_FREQ_100K,
.interrupt_priority = APP_IRQ_PRIORITY_HIGH,
.clear_bus_init = true
};
do {
ret = nrf_drv_twi_init(&m_twi_master, &config, twi_handler, NULL);
if (NRF_SUCCESS != ret) {
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

And than in ssd1306_begin() function i call ssd1306_command() function  which looks like this:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void ssd1306_command(uint8_t c)
{
if (use_i2c) {
ret_code_t ret;
uint8_t dta_send[] = {0x00, c};
while(!m_xfer_done);
m_xfer_done = false;
ret = nrf_drv_twi_tx(&m_twi_master, _i2caddr, dta_send, 2, false);
APP_ERROR_CHECK(ret);
UNUSED_VARIABLE(ret);
}
else {
_HI_CS();
_LO_DC();
_LO_CS();
_HI_CS();
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


m_xfer_done is hendled in twi_hendler which looks like this:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
switch (p_event->type)
{
case NRF_DRV_TWI_EVT_DONE:
m_xfer_done = true;
break;
default:
break;
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Summarazing whole problem. All code stucks because NRF_DRV_TWI_EVT_DONE is never done actually. Something cosue that nrf_drv_twi_tx() function doesn't work properly and I can not figure out why. I'll be super grateful if someone could help me in solving this problem. So far I've been trying to use higher priority levels for example because I've read on this formu that it could cause some problems regarding to softdevice, but of course it didn't help.