Hi, i was interfacing oled with nrf52 board. I got some example and modified bit to use it with GCC. But it is now working. Oled not at all starting. oled is 0.96 inch, I2C based 128x64. Vdd = 5v sda = p0.26 scl = p0.27
Here is code github.com/.../
Hi, i was interfacing oled with nrf52 board. I got some example and modified bit to use it with GCC. But it is now working. Oled not at all starting. oled is 0.96 inch, I2C based 128x64. Vdd = 5v sda = p0.26 scl = p0.27
Here is code github.com/.../
Hi,
The problem seems to be that you are using the TWI driver in non-blocking mode, but you do not have any mechanism implemented to make sure that the previous transfer is done before starting a new transfer. If you check the return code of your calls to nrf_drv_twi_tx()
in ssd1306_command()
, you will see that you get a lot of error code 0x11 - NRF_ERROR_BUSY. This leads to that the commands is not sent to the OLED.
A simple fix to this problem is to switch to blocking mode for the TWI instance. This is done by passing NULL
to event_handler argument of nrf_drv_twi_init()
.
Best regards,
Jørgen
An alternative if splitting the data does not work, is to use legacy TWI without EasyDMA. This can be selected by setting TWIx_USE_EASY_DMA 0
in sdk_config.h. Unfortunately the TWI master driver and HAL does not seem to have support for length parameters of more than 8 bits. You will have to change the driver/HAL implementations to support 16-bit lengths, or use the registers directly. I will check if I can make an example for you, but something like this code should work to do a TWI transfer using the registers:
uint32_t byte_number = 0;
NRF_TWI0->ENABLE = (TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos);
NRF_TWI0->PSELSCL = 27;
NRF_TWI0->PSELSDA = 26;
NRF_TWI0->FREQUENCY = TWI_FREQUENCY_FREQUENCY_K100;
NRF_TWI0->INTENCLR = 0xFFFFFFFFUL; //Disable all interrupts
NRF_TWI0->SHORTS = 0x00000000;
NRF_TWI0->ADDRESS = 0x3C;
NRF_TWI0->EVENTS_TXDSENT = 0;
NRF_TWI0->TXD = 0x40; //control byte
NRF_TWI0->TASKS_STARTTX = 1;
while (byte_number < sizeof(buffer)) {
// wait for the transaction complete
while (NRF_TWI0->EVENTS_TXDSENT == 0);
NRF_TWI0->TXD = buffer[byte_number];
NRF_TWI0->EVENTS_TXDSENT = 0;
byte_number++;
}
while (NRF_TWI0->EVENTS_TXDSENT == 0); //Wait for last byte
NRF_TWI0->EVENTS_STOPPED = 0;
NRF_TWI0->TASKS_STOP = 1;
while (NRF_TWI0->EVENTS_STOPPED == 0);
An alternative if splitting the data does not work, is to use legacy TWI without EasyDMA. This can be selected by setting TWIx_USE_EASY_DMA 0
in sdk_config.h. Unfortunately the TWI master driver and HAL does not seem to have support for length parameters of more than 8 bits. You will have to change the driver/HAL implementations to support 16-bit lengths, or use the registers directly. I will check if I can make an example for you, but something like this code should work to do a TWI transfer using the registers:
uint32_t byte_number = 0;
NRF_TWI0->ENABLE = (TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos);
NRF_TWI0->PSELSCL = 27;
NRF_TWI0->PSELSDA = 26;
NRF_TWI0->FREQUENCY = TWI_FREQUENCY_FREQUENCY_K100;
NRF_TWI0->INTENCLR = 0xFFFFFFFFUL; //Disable all interrupts
NRF_TWI0->SHORTS = 0x00000000;
NRF_TWI0->ADDRESS = 0x3C;
NRF_TWI0->EVENTS_TXDSENT = 0;
NRF_TWI0->TXD = 0x40; //control byte
NRF_TWI0->TASKS_STARTTX = 1;
while (byte_number < sizeof(buffer)) {
// wait for the transaction complete
while (NRF_TWI0->EVENTS_TXDSENT == 0);
NRF_TWI0->TXD = buffer[byte_number];
NRF_TWI0->EVENTS_TXDSENT = 0;
byte_number++;
}
while (NRF_TWI0->EVENTS_TXDSENT == 0); //Wait for last byte
NRF_TWI0->EVENTS_STOPPED = 0;
NRF_TWI0->TASKS_STOP = 1;
while (NRF_TWI0->EVENTS_STOPPED == 0);