This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

OLED SSD1306 with nRF52840 DK Not Working

Hi,

I am trying to interface OLED(SSD1306 driver) module/break-out with nRF52840 D.K, PCA10056 1.0.0 but it's showing some noise/dots/garbage.
Code: nRF5_SDK_15.2.0_9412b96\examples\ble_peripheral\ble_app_uart
Merged: ssd1306 driver & enabled twi_sensor for i2c communication.
Softdevice: nRF5_SDK_15.2.0_9412b96\components\softdevice\s140


#define OLED_SCL NRF_GPIO_PIN_MAP(0,14)
#define OLED_SDA NRF_GPIO_PIN_MAP(0,13)


Code Snippet of twi:

/* TWI instance ID. */
#define TWI_INSTANCE_ID     		1

/* Indicates if operation on TWI has ended. */
static volatile bool m_xfer_done = false;

/* TWI instance. */
static const nrf_drv_twi_t m_twi_master = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);

void twi_init (uint32_t scl, uint32_t sda)
{
    ret_code_t err_code;

    const nrf_drv_twi_config_t twi_m_config = {
       .scl                = scl,
       .sda                = sda,
       .frequency          = NRF_DRV_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
       .clear_bus_init     = false
    };

    err_code = nrf_drv_twi_init(&m_twi_master, &twi_m_config, NULL, NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&m_twi_master);
}

*
Rest is same as ssd1306_init(sda,scl)

I have tried following:

  1. Same OLED(SSD1306 driver) module/break-out works with nRF51422 D.K, PCA10028 using same ssd1306 drivers but twi_init() is like this which works properly:
    /**
     * @brief TWI master instance
     *
     * Instance of TWI master driver that would be used for communication with simulated
     * eeprom memory.
     */
    static const nrf_drv_twi_t m_twi_master = {
        .p_reg       = NRF_TWI0,
        .irq         = TWI0_IRQ,
        .instance_id = TWI0_INSTANCE_INDEX
    };
    
    
    void twi_evt_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
    {
    #if 0
        if (p_event->type == NRF_DRV_TWI_ERROR) {
            printf("E\r\n");
        }
    
        if (p_event->type == NRF_DRV_TWI_TX_DONE) {
            printf("T\r\n");
        }
    
        if (p_event->type == NRF_DRV_TWI_RX_DONE) {
            printf("R\r\n");
        }
    #endif
    }
    
    
    ret_code_t 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          = TWI0_CONFIG_FREQUENCY,
            .interrupt_priority = TWI0_CONFIG_IRQ_PRIORITY
        };
    
        do {
            ret = nrf_drv_twi_init(&m_twi_master, &config, /*twi_evt_handler*/ NULL,NULL);
            if (NRF_SUCCESS != ret) {
                break;
            }
            nrf_drv_twi_enable(&m_twi_master);
        }
        while (0);
        return ret;
    }
    


  2. Checked other devzone posts with same issues but didn't worked.
  3. Checked slave address of ssd1306.
  4. Checked i2c bus.

Check attached images & OLED module is powered via nRF52840D.K  VDD PIN. Also same was the case with nRF51422 D.K VDD PIN used to power OLED which worked. Please reply for possible solutions to debug this issue.


Regards

Vishal Aditya
Embedded Software Engineer

Parents Reply Children
  • I think he wants you to fix his code for him?

    Getting the display initialisation correct & working is your job.

    Have you checked your initialisation sequence against the display's specifications?

    Have you used a scope or analyser yet to see what is actually being sent to the display?

    Have you compared that to the "working" case ?

  • I think he wants you to fix his code for him?

    I don't want code fix, I know my job I will do it myself. The issue is all other i2c peripherals are working properly with the same twi_init() & sdk_config.h except for OLED & all the display sequence initialization is correct. I have checked the OLED sequence begin multiple times.

    i2c bus line on Oscilloscope I get this in nrf51422 device:

    Yellow: SCL
    Blue: SDA

    & no proper pattern on nrf52840 device. 

    Let me know if you need any more info further!

  • Can't your oscilloscope do screenshots?

    Show the oscilloscope trace for the nRF52840.

  • Hi, i am working on OLED with Vishal. 

    Current situation : OLED working well on the nrf51422 target board and DK PCA10028. 

                                 OLED is not working as expected in the target board (mdbt module housing nrf52840)                                 or with the PCA10056 DK

                                The ssd1306 driver file used is the same in both the cases. 

    After going through the c files, we have narrowed the problem to the TWI function calls. 

    In the working code (nrf51422 SDK 10) the nrf_drv_twi_tx function has a length of type uint32_t but the SDK 15.2 has a length of uint8_t. The max value of length that can be passed to the TWI tx function call is MAXUINT8 (0xFF).

    The OLED driver requires us to send more than 0xFF bytes at once. 

    We think the previous developer has modified the nrf_drv_twi files and made it support a larger value of length. However, I do not want to introduce changes in the library files as this might lead to other bugs. 

    So, I would like to know how to send more than 0xFF bytes in a single TWI command?

    I have tried splitting the data into multiple buffers of size 256 and then calling the TWI TX function repeatedly but this is not working either. (the reason could be that on each function call, the SLAVE ADDRESS will be produced on the bus. This is not part of the OLED command sequence and would lead to unexpected behavior). 

    Please let me know how I can proceed with this. 

    Thanks in advance. 

    Gautham

Related