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

SSD1306 TWI SDK 15.2.0 Troubles

Hi Nordic folks!

I'm in troubles with a Nordic nRF52 DK and a SSD1306 Display. I'm not able to print anything in the oled screen, I don't really sure if it the problem it's in the SSD1306 code functions, or it's in the TWI library. I'm using the SDK 15.2.0 TWI_SCANNER example adding this code in the main file.

I was trying to debugging but the code and it crash in the twi_tx() function. 

Could someone test it??

I leave you here the code and a photo from my trouble.

#include <stdio.h>
#include "boards.h"
#include "app_util_platform.h"
#include "app_error.h"
#include "nrf_drv_twi.h"
#include "nrf_delay.h"



#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

/* TWI instance ID. */
#if TWI0_ENABLED
#define TWI_INSTANCE_ID     0
#elif TWI1_ENABLED
#define TWI_INSTANCE_ID     1
#endif

 /* Number of possible TWI addresses. */
 #define TWI_ADDRESSES      127

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

static volatile bool use_i2c = true;
static uint8_t _i2caddr, _vccstate;
static uint32_t _dc, _rs, _cs;
static int16_t _width, _height, WIDTH, HEIGHT, cursor_x, cursor_y;
static uint8_t textsize, rotation;
static uint16_t textcolor, textbgcolor;
bool wrap,   // If set, 'wrap' text at right edge of display
     _cp437; // If set, use correct CP437 charset (default is off)

static uint8_t buffer[SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
    0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x80, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80,
    0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xFF,
#if (SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH > 96*16)
    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
    0x80, 0xFF, 0xFF, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x8C, 0x8E, 0x84, 0x00, 0x00, 0x80, 0xF8,
    0xF8, 0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x80,
    0x00, 0xE0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0x01, 0x01,
    0x01, 0x01, 0x83, 0xFF, 0xFF, 0x00, 0x00, 0x7C, 0xFE, 0xC7, 0x01, 0x01, 0x01, 0x01, 0x83, 0xFF,
    0xFF, 0xFF, 0x00, 0x38, 0xFE, 0xC7, 0x83, 0x01, 0x01, 0x01, 0x83, 0xC7, 0xFF, 0xFF, 0x00, 0x00,
    0x01, 0xFF, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x07, 0x01, 0x01, 0x01, 0x00, 0x00, 0x7F, 0xFF,
    0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF,
    0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x03, 0x0F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC7, 0xC7, 0x8F,
    0x8F, 0x9F, 0xBF, 0xFF, 0xFF, 0xC3, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC,
    0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x03, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01,
    0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x00, 0x00,
    0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
    0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x03,
    0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
#if (SSD1306_LCDHEIGHT == 64)
    0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x0F,
    0x87, 0xC7, 0xF7, 0xFF, 0xFF, 0x1F, 0x1F, 0x3D, 0xFC, 0xF8, 0xF8, 0xF8, 0xF8, 0x7C, 0x7D, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x0F, 0x07, 0x00, 0x30, 0x30, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xC0, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0xC0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x3F, 0x1F,
    0x0F, 0x07, 0x1F, 0x7F, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xE0,
    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00,
    0x00, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x0E, 0xFC, 0xF8, 0x00, 0x00, 0xF0, 0xF8, 0x1C, 0x0E,
    0x06, 0x06, 0x06, 0x0C, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFC,
    0xFE, 0xFC, 0x00, 0x18, 0x3C, 0x7E, 0x66, 0xE6, 0xCE, 0x84, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0x06,
    0x06, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x06, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0xC0, 0xF8,
    0xFC, 0x4E, 0x46, 0x46, 0x46, 0x4E, 0x7C, 0x78, 0x40, 0x18, 0x3C, 0x76, 0xE6, 0xCE, 0xCC, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x03,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00,
    0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x03, 0x07, 0x0E, 0x0C,
    0x18, 0x18, 0x0C, 0x06, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0E, 0x0C, 0x18, 0x0C, 0x0F,
    0x07, 0x01, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00,
    0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x07,
    0x07, 0x0C, 0x0C, 0x18, 0x1C, 0x0C, 0x06, 0x06, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
#endif
#endif
};
/**
 * @brief TWI initialization.
 */
void twi_init (void)
{
    ret_code_t err_code;
    nrf_gpio_cfg_input(ARDUINO_SCL_PIN, NRF_GPIO_PIN_PULLUP);
    nrf_delay_us(4);
    nrf_gpio_cfg_input(ARDUINO_SDA_PIN, NRF_GPIO_PIN_PULLUP);
    nrf_delay_us(4);
    const nrf_drv_twi_config_t twi_config = {
       .scl                = ARDUINO_SCL_PIN,
       .sda                = ARDUINO_SDA_PIN,
       .frequency          = NRF_DRV_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
       .clear_bus_init     = false
    };

    err_code = nrf_drv_twi_init(&m_twi, &twi_config, NULL, NULL);
    nrf_delay_us(4);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&m_twi);
}

void ssd1306_command(uint8_t c)
{
    if (use_i2c) {
        ret_code_t ret;
        uint8_t dta_send[] = {0x00, c};
        ret = nrf_drv_twi_tx(&m_twi, _i2caddr, dta_send, 2, false);
        nrf_delay_us(4);
        UNUSED_VARIABLE(ret);
    }
    #ifdef SSD1306_USE_SPI
    else {
        _HI_CS();
        _LO_DC();
        _LO_CS();
        UNUSED_VARIABLE(spi_transfer(&c, 1));
        _HI_CS();
    }
    #endif
}

void ssd1306_begin(uint8_t vccstate, uint8_t i2caddr, bool reset)
{
    _vccstate = vccstate;
    _i2caddr = i2caddr;
    UNUSED_VARIABLE(_i2caddr);

    _width    = WIDTH;
    _height   = HEIGHT;
    cursor_y  = cursor_x    = 0;
    textsize  = 1;
    textcolor = textbgcolor = 0xFFFF;
    wrap      = true;
    _cp437    = false;

    _width = WIDTH = SSD1306_LCDWIDTH;
    _height = HEIGHT = SSD1306_LCDHEIGHT;
    rotation  = 0;


   /* if (reset) {
        // Setup reset pin direction (used by both SPI and I2C)
        _HI_RS();
        // VDD (3.3V) goes high at start, lets just chill for a ms
        nrf_delay_ms(1);
        // bring reset low
        _LO_RS();
        // wait 10ms
        nrf_delay_ms(10);
        // bring out of reset
        _HI_RS();
        // turn on VCC (9V?)
    }*/

#if defined SSD1306_128_32
    // Init sequence for 128x32 OLED module
    ssd1306_command(SSD1306_DISPLAYOFF);                    // 0xAE
    ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV);            // 0xD5
    ssd1306_command(0x80);                                  // the suggested ratio 0x80

    ssd1306_command(SSD1306_SETMULTIPLEX);                  // 0xA8
    ssd1306_command(0x1F);
    ssd1306_command(SSD1306_SETDISPLAYOFFSET);              // 0xD3
    ssd1306_command(0x0);                                   // no offset
    ssd1306_command(SSD1306_SETSTARTLINE | 0x0);            // line #0
    ssd1306_command(SSD1306_CHARGEPUMP);                    // 0x8D
    if (vccstate == SSD1306_EXTERNALVCC) {
        ssd1306_command(0x10);
    }
    else {
        ssd1306_command(0x14);
    }
    ssd1306_command(SSD1306_MEMORYMODE);                    // 0x20
    ssd1306_command(0x00);                                  // 0x0 act like ks0108
    ssd1306_command(SSD1306_SEGREMAP | 0x1);
    ssd1306_command(SSD1306_COMSCANDEC);
    ssd1306_command(SSD1306_SETCOMPINS);                    // 0xDA
    ssd1306_command(0x02);
    ssd1306_command(SSD1306_SETCONTRAST);                   // 0x81
    ssd1306_command(0x8F);
    ssd1306_command(SSD1306_SETPRECHARGE);                  // 0xd9
    if (vccstate == SSD1306_EXTERNALVCC) {
        ssd1306_command(0x22);
    }
    else {
        ssd1306_command(0xF1);
    }
    ssd1306_command(SSD1306_SETVCOMDETECT);                 // 0xDB
    ssd1306_command(0x40);
    ssd1306_command(SSD1306_DISPLAYALLON_RESUME);           // 0xA4
    ssd1306_command(SSD1306_NORMALDISPLAY);                 // 0xA6
#endif

#if defined SSD1306_128_64
    // Init sequence for 128x64 OLED module
    ssd1306_command(SSD1306_DISPLAYOFF);                    // 0xAE
    ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV);            // 0xD5
    ssd1306_command(0x80);                                  // the suggested ratio 0x80
    ssd1306_command(SSD1306_SETMULTIPLEX);                  // 0xA8
    ssd1306_command(0x3F);
    ssd1306_command(SSD1306_SETDISPLAYOFFSET);              // 0xD3
    ssd1306_command(0x0);                                   // no offset
    ssd1306_command(SSD1306_SETSTARTLINE | 0x0);            // line #0
    ssd1306_command(SSD1306_CHARGEPUMP);                    // 0x8D
    if (vccstate == SSD1306_EXTERNALVCC) {
        ssd1306_command(0x10);
    }
    else {
        ssd1306_command(0x14);
    }
    ssd1306_command(SSD1306_MEMORYMODE);                    // 0x20
    ssd1306_command(0x00);                                  // 0x0 act like ks0108
    ssd1306_command(SSD1306_SEGREMAP | 0x1);
    ssd1306_command(SSD1306_COMSCANDEC);
    ssd1306_command(SSD1306_SETCOMPINS);                    // 0xDA
    ssd1306_command(0x12);
    ssd1306_command(SSD1306_SETCONTRAST);                   // 0x81
    if (vccstate == SSD1306_EXTERNALVCC) {
        ssd1306_command(0x9F);
    }
    else {
        ssd1306_command(0xCF);
    }
    ssd1306_command(SSD1306_SETPRECHARGE);                  // 0xd9
    if (vccstate == SSD1306_EXTERNALVCC) {
        ssd1306_command(0x22);
    }
    else {
        ssd1306_command(0xF1);
    }
    ssd1306_command(SSD1306_SETVCOMDETECT);                 // 0xDB
    ssd1306_command(0x40);
    ssd1306_command(SSD1306_DISPLAYALLON_RESUME);           // 0xA4
    ssd1306_command(SSD1306_NORMALDISPLAY);                 // 0xA6
#endif

#if defined SSD1306_96_16
    // Init sequence for 96x16 OLED module
    ssd1306_command(SSD1306_DISPLAYOFF);                    // 0xAE
    ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV);            // 0xD5
    ssd1306_command(0x80);                                  // the suggested ratio 0x80
    ssd1306_command(SSD1306_SETMULTIPLEX);                  // 0xA8
    ssd1306_command(0x0F);
    ssd1306_command(SSD1306_SETDISPLAYOFFSET);              // 0xD3
    ssd1306_command(0x00);                                   // no offset
    ssd1306_command(SSD1306_SETSTARTLINE | 0x0);            // line #0
    ssd1306_command(SSD1306_CHARGEPUMP);                    // 0x8D
    if (vccstate == SSD1306_EXTERNALVCC) {
        ssd1306_command(0x10);
    }
    else {
        ssd1306_command(0x14);
    }
    ssd1306_command(SSD1306_MEMORYMODE);                    // 0x20
    ssd1306_command(0x00);                                  // 0x0 act like ks0108
    ssd1306_command(SSD1306_SEGREMAP | 0x1);
    ssd1306_command(SSD1306_COMSCANDEC);
    ssd1306_command(SSD1306_SETCOMPINS);                    // 0xDA
    ssd1306_command(0x2);	//ada x12
    ssd1306_command(SSD1306_SETCONTRAST);                   // 0x81
    if (vccstate == SSD1306_EXTERNALVCC) {
        ssd1306_command(0x10);
    }
    else {
        ssd1306_command(0xAF);
    }
    ssd1306_command(SSD1306_SETPRECHARGE);                  // 0xd9
    if (vccstate == SSD1306_EXTERNALVCC) {
        ssd1306_command(0x22);
    }
    else {
        ssd1306_command(0xF1);
    }
    ssd1306_command(SSD1306_SETVCOMDETECT);                 // 0xDB
    ssd1306_command(0x40);
    ssd1306_command(SSD1306_DISPLAYALLON_RESUME);           // 0xA4
    ssd1306_command(SSD1306_NORMALDISPLAY);                 // 0xA6
#endif

    ssd1306_command(SSD1306_DISPLAYON);//--turn on oled panel
}
void ssd1306_clear_display(void)
{
    memset(buffer, 0, (SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8));
}

void ssd1306_display(void)
{
    ssd1306_command(SSD1306_COLUMNADDR);
    ssd1306_command(0);   // Column start address (0 = reset)
    ssd1306_command(SSD1306_LCDWIDTH - 1); // Column end address (127 = reset)

    ssd1306_command(SSD1306_PAGEADDR);
    ssd1306_command(0); // Page start address (0 = reset)
#if SSD1306_LCDHEIGHT == 64
    ssd1306_command(7); // Page end address
#endif
#if SSD1306_LCDHEIGHT == 32
    ssd1306_command(3); // Page end address
#endif
#if SSD1306_LCDHEIGHT == 16
    ssd1306_command(1); // Page end address
#endif

    if (use_i2c) {
        static uint8_t control = 0x40;
        nrf_delay_ms(100);
        nrf_drv_twi_tx(&m_twi, _i2caddr, &control, 1, true);
        nrf_delay_ms(100);
        nrf_drv_twi_tx(&m_twi, _i2caddr, buffer, (SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8), false);
        nrf_delay_ms(100);
    }
    #ifdef SSD1306_USE_SPI
    else {
        _HI_CS();
        _HI_DC();
        _LO_CS();
        for (uint16_t i = 0; i < (SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8); i++) {
            UNUSED_VARIABLE(spi_transfer(&buffer[i], 1));
        }
        _HI_CS();
    }
    #endif
}
#define ssd1306_swap(a, b) { int16_t t = a; a = b; b = t; }
int16_t ssd1306_width(void)
{
    return _width;
}

int16_t ssd1306_height(void)
{
    return _height;
}

void ssd1306_draw_pixel(int16_t x, int16_t y, uint16_t color)
{
    if ((x < 0) || (x >= ssd1306_width()) || (y < 0) || (y >= ssd1306_height()))
        return;

    // check rotation, move pixel around if necessary
    switch (rotation) {
    case 1:
        ssd1306_swap(x, y);
        x = WIDTH - x - 1;
        break;
    case 2:
        x = WIDTH - x - 1;
        y = HEIGHT - y - 1;
        break;
    case 3:
        ssd1306_swap(x, y);
        y = HEIGHT - y - 1;
        break;
    }

    // x is which column
    switch (color) {
    case WHITE:
        buffer[x + (y / 8)*SSD1306_LCDWIDTH] |=  (1 << (y & 7));
        break;
    case BLACK:
        buffer[x + (y / 8)*SSD1306_LCDWIDTH] &= ~(1 << (y & 7));
        break;
    case INVERSE:
        buffer[x + (y / 8)*SSD1306_LCDWIDTH] ^=  (1 << (y & 7));
        break;
    }
}
/**
 * @brief Function for main application entry.
 */

int main(void)
{
    ret_code_t err_code;
    uint8_t address;
    uint8_t sample_data;
    bool detected_device = false;

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    nrf_gpio_cfg_output(2);
    nrf_gpio_pin_set(2);

    NRF_LOG_INFO("TWI scanner started.");
    NRF_LOG_FLUSH();
    twi_init();

    for (address = 1; address <= TWI_ADDRESSES; address++)
    {
        err_code = nrf_drv_twi_rx(&m_twi, address, &sample_data, sizeof(sample_data));
        if (err_code == NRF_SUCCESS)
        {
            detected_device = true;
            NRF_LOG_INFO("TWI device detected at address 0x%x.", address);
        }
        NRF_LOG_FLUSH();
    }

    if (!detected_device)
    {
        NRF_LOG_INFO("No device was found.");
        NRF_LOG_FLUSH();
    }

    ssd1306_begin(SSD1306_SWITCHCAPVCC, SSD1306_I2C_ADDRESS, false);

    NRF_LOG_INFO("SSD1306 Begin OK\n");
    NRF_LOG_FLUSH();
    //ssd1306_display();
    nrf_delay_ms(1000);
    ssd1306_clear_display();
    nrf_delay_ms(1000);
    ssd1306_draw_pixel(10,10,WHITE);
    ssd1306_display();
    NRF_LOG_INFO("Pixel Drawn\n");
    NRF_LOG_FLUSH();


    while (true)
    {
        /* Empty loop. */
    }
}

/** @} */

  • Hi,

    Did you check the TWI bus with a logic analyzer to see if all commands are sent correctly to the display?

    Note that the nrf_drv_twi_tx/rx API has only 8bit length fields due to a limitation in supported EasyDMA size in nRF52832 chips. If you need to write more data than 255 bytes in one transfer you need to use the legacy TWI with nrfx_twi.c driver. Alternatively, you can split the data into multiple transfers if the slave supports this.

    Best regards,
    Jørgen

  • Hi Jorgen,

    I'm going to try with the Logic Analyzer the response with an Arduino device, and with the libraries too, and I'll check the differents between frames.

    I'll notice you. 

    Although, I've started to develop my own TWI function to test if the problems are in the SDK libs.

    I leave you here the code if you want or can try it with a logic analyzer.

    #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "nrf_drv_twi.h"
    #include "nrf_delay.h"
    
    
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    /**
     * @brief Function for main application entry.
     */
    //------------------------------------------//
    
    void twi_write(uint8_t address, uint8_t data){
      uint8_t tx_buf[3];
    
      tx_buf[0] = address;
      tx_buf[1] = data;
      tx_buf[2] = 0xF0;
    
      NRF_TWIM0->SHORTS = TWIM_SHORTS_LASTTX_STOP_Enabled <<TWIM_SHORTS_LASTTX_STOP_Pos;
    
      NRF_TWIM0->TXD.MAXCNT = sizeof(tx_buf);
      NRF_TWIM0->TXD.PTR = (uint32_t)&tx_buf[0];
    
      NRF_TWIM0->EVENTS_STOPPED = 0;
      NRF_TWIM0->TASKS_STARTTX = 1;
      while(NRF_TWIM0->EVENTS_TXSTARTED == 0){};
      nrf_delay_us(100);
      while (NRF_TWIM0->EVENTS_STOPPED == 0){};
    
    }
    
    void twi_owner_init(uint32_t address){
        NRF_GPIO->PIN_CNF[2] |= (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
        NRF_GPIO->OUTSET |= (1<<2);
    
        NRF_GPIO->PIN_CNF[ARDUINO_SCL_PIN] |= (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos ) | ( GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos ) | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos); // 3 PULL_UP | 0 DIR | 8 Drive sense
        NRF_GPIO->PIN_CNF[ARDUINO_SDA_PIN] |= (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos ) | ( GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos ) | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos); // 3 PULL_UP | 0 DIR | 1 INPUT Buffer | 8 Drive sense
    
        NRF_TWIM0->ENABLE = TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos; //Turn off TWIM0
    
        NRF_TWIM0->PSEL.SCL = 0x1A; //SCL Pin
        NRF_TWIM0->PSEL.SDA = 0x1B; //SDA Pin
    
        NRF_TWIM0->ADDRESS = address; //Slave device address
        NRF_TWIM0->FREQUENCY = 0x01980000; //100kHz TWI frecuency
    
        NRF_TWIM0->ENABLE = TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos;
    }
    int main(void)
    {
    
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
        
        NRF_LOG_INFO("TWI scanner started.");
        NRF_LOG_FLUSH();
    
        twi_owner_init(0x3C);
        
        NRF_LOG_INFO("TWI init\n");
        NRF_LOG_FLUSH();
    
        //Begin function
        twi_write(0x3C, 0xAE);
        nrf_delay_us(100);
        twi_write(0x3C, 0xD5);
        nrf_delay_us(100);
        twi_write(0x3C, 0x80);
        twi_write(0x3C, 0xA8);
        twi_write(0x3C, 0x1F);
        twi_write(0x3C, 0xD3);
        twi_write(0x3C, 0x0);
        twi_write(0x3C, 0x40|0x0);
        twi_write(0x3C, 0x8D);
        twi_write(0x3C, 0x14);
        twi_write(0x3C, 0x20);
        twi_write(0x3C, 0x0);
        twi_write(0x3C, 0xA0|0x1);
        twi_write(0x3C, 0xC8);
        twi_write(0x3C, 0xDA);
        twi_write(0x3C, 0x02);
        twi_write(0x3C, 0x81);
        twi_write(0x3C, 0x8F);
        twi_write(0x3C, 0xD9);
        twi_write(0x3C, 0xF1);
        twi_write(0x3C, 0xDB);
        twi_write(0x3C, 0xA4);
        twi_write(0x3C, 0xA6);
        twi_write(0x3C, 0xAF);
        NRF_LOG_INFO("Begin funct\n");
        NRF_LOG_FLUSH();
        //Display function
        twi_write(0x3C, 0x21);
        twi_write(0x3C, 0x0);
        twi_write(0x3C, 127);
        twi_write(0x3C, 0x22);
        twi_write(0x3C, 0x0);
        twi_write(0x3C, 0x3);
        twi_write(0x3C, 0x40);
    
        NRF_LOG_INFO("Display funct\n");
        NRF_LOG_FLUSH();
    
        NRF_LOG_INFO("TWI end\n");
        NRF_LOG_FLUSH();
        
    
        while(1){
         __WFE();
        }
    }

  • Hi folks!!

    Finally, I achieve that the SSD1206 Oled works!! The problem was, as you suggest, in the buffer limitation.

    As the SSD1306 is 128x32, the number of bytes that you have to send is about 514 bytes. So, you have to distribute it in 3 TWI transmissions. And that's all it finally works.

    I leave you here a video with the results.

    And also the code, for if it could help someone else.

    #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "nrf_drv_twi.h"
    #include "nrf_delay.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
     //https://www.reddit.com/r/embedded/comments/9w9gm7/nrf52832_with_mcp4725/
      static uint8_t Logo [SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8] = {
      // 'Logo, 32x32px
    0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0xff, 0xff, 0x00, 
    0x01, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xff, 0xf0, 
    0x1f, 0xff, 0xff, 0xf8, 0x1f, 0xbb, 0xb9, 0xf8, 0x3f, 0xb9, 0xbd, 0xfc, 0x3f, 0xb9, 0xb9, 0xfc, 
    0x3f, 0xbb, 0xbf, 0xfc, 0x7f, 0xff, 0xff, 0xfc, 0x7e, 0x03, 0xc0, 0xfe, 0x7e, 0x79, 0x9e, 0x7e, 
    0x7e, 0xfe, 0xbf, 0x3e, 0x7e, 0xfe, 0xbf, 0x7e, 0x7e, 0xfe, 0x3f, 0xfe, 0x7e, 0xfe, 0x3f, 0xfc, 
    0x3e, 0xfe, 0x3f, 0xfc, 0x3e, 0xfe, 0x3f, 0xfc, 0x3e, 0xfe, 0xbf, 0x38, 0x1e, 0xfc, 0xbf, 0x38, 
    0x1e, 0x71, 0x8e, 0x70, 0x0e, 0x03, 0xc0, 0xe0, 0x07, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0x80, 
    0x01, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    static uint8_t buffer[SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8] = {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
        0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x80, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80,
        0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xFF,
    };
    
    static volatile bool use_i2c = true;
    static uint8_t _i2caddr, _vccstate;
    static uint32_t _dc, _rs, _cs;
    static int16_t _width, _height, WIDTH, HEIGHT, cursor_x, cursor_y;
    static uint8_t textsize, rotation;
    static uint16_t textcolor, textbgcolor;
    bool wrap,   // If set, 'wrap' text at right edge of display
         _cp437; // If set, use correct CP437 charset (default is off)
    
    #define ssd1306_swap(a, b) { int16_t t = a; a = b; b = t; }
    int16_t ssd1306_width(void)
    {
        return _width;
    }
    
    int16_t ssd1306_height(void)
    {
        return _height;
    }
    
    void ssd1306_draw_pixel(int16_t x, int16_t y, uint16_t color)
    {
       // if ((x < 0) || (x >= ssd1306_width()) || (y < 0) || (y >= ssd1306_height()))
       //      return;
    
        // check rotation, move pixel around if necessary
    
        switch (rotation) {
        case 1:
            ssd1306_swap(x, y);
            x = WIDTH - x - 1;
            break;
        case 2:
            x = WIDTH - x - 1;
            y = HEIGHT - y - 1;
            break;
        case 3:
            ssd1306_swap(x, y);
            y = HEIGHT - y - 1;
            break;
        }
    
        // x is which column
        switch (color) {
        case WHITE:
            buffer[x + (y / 8)*SSD1306_LCDWIDTH] |=  (1 << (y & 7));
            break;
        case BLACK:
            buffer[x + (y / 8)*SSD1306_LCDWIDTH] &= ~(1 << (y & 7));
            break;
        case INVERSE:
            buffer[x + (y / 8)*SSD1306_LCDWIDTH] ^=  (1 << (y & 7));
            break;
    
        }
    }
    void ssd1306_cleardisplay(void){
      for(int i = 0; i < (SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8); i++){
          buffer[i] = 0x00;
        }
    }
    /**
     * @brief Function for main application entry.
     */
    //------------------------------------------//
    
    void twi_write(uint8_t address, uint8_t data){
      uint8_t tx_buf[2];
    
      tx_buf[0] = 0x3C;
      tx_buf[1] = data;
    
    
      NRF_TWIM0->SHORTS = TWIM_SHORTS_LASTTX_STOP_Enabled <<TWIM_SHORTS_LASTTX_STOP_Pos;
    
      NRF_TWIM0->TXD.MAXCNT = sizeof(tx_buf);
      NRF_TWIM0->TXD.PTR = (uint32_t)&tx_buf[0];
    
      NRF_TWIM0->EVENTS_STOPPED = 0;
      NRF_TWIM0->TASKS_STARTTX = 1;
      while(NRF_TWIM0->EVENTS_TXSTARTED == 0){};
      while(NRF_TWIM0->EVENTS_LASTTX == 0){};
      nrf_delay_us(100);
      while (NRF_TWIM0->EVENTS_STOPPED == 0){};
    
    }
    
    void twi_owner_init(uint32_t address){
        NRF_GPIO->PIN_CNF[2] |= (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
        NRF_GPIO->OUTSET |= (1<<2);
        NRF_GPIO->PIN_CNF[3] |= (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
        NRF_GPIO->OUTSET |= (1<<3);
    
        NRF_GPIO->PIN_CNF[26] |= (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos ) | ( GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos ) | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos); // 3 PULL_UP | 0 DIR | 8 Drive sense
        NRF_GPIO->PIN_CNF[27] |= (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos ) | ( GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos ) | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos); // 3 PULL_UP | 0 DIR | 1 INPUT Buffer | 8 Drive sense
    
        NRF_TWIM0->ENABLE = TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos; //Turn off TWIM0
    
        NRF_TWIM0->PSEL.SCL = 0x1A; //SCL Pin
        NRF_TWIM0->PSEL.SDA = 0x1B; //SDA Pin
    
        NRF_TWIM0->ADDRESS = address; //Slave device address
        NRF_TWIM0->FREQUENCY = 0x01980000; //100kHz TWI frecuency
    
        NRF_TWIM0->ENABLE = TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos;
    }
    int main(void)
    {
    
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
        NRF_GPIO->PIN_CNF[18] |= (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
        NRF_GPIO->OUTCLR |= (1<<18);
    
        NRF_LOG_INFO("TWI scanner started.");
        NRF_LOG_FLUSH();
    
        twi_owner_init(0x3C);
        
        NRF_TWIM0->SHORTS = TWIM_SHORTS_LASTTX_STOP_Enabled <<TWIM_SHORTS_LASTTX_STOP_Pos;
    
        NRF_LOG_INFO("TWI init\n");
        NRF_LOG_FLUSH();
    
        uint8_t tx_buf[]={0x00,0xAE,0xD5,0x80,0xA8};
    
    
        NRF_TWIM0->TXD.MAXCNT = sizeof(tx_buf);
        NRF_TWIM0->TXD.PTR = (uint32_t)&tx_buf[0];
    
        NRF_TWIM0->EVENTS_STOPPED = 0;
        NRF_TWIM0->TASKS_STARTTX = 1;
        while(NRF_TWIM0->EVENTS_TXSTARTED == 0){};
        while(NRF_TWIM0->EVENTS_LASTTX == 0){};
        nrf_delay_us(100);
        while (NRF_TWIM0->EVENTS_STOPPED == 0){};
    
        uint8_t tx_buf1[]={0x00,0x1F};
    
        NRF_TWIM0->TXD.MAXCNT = sizeof(tx_buf1);
        NRF_TWIM0->TXD.PTR = (uint32_t)&tx_buf1[0];
    
        NRF_TWIM0->EVENTS_STOPPED = 0;
        NRF_TWIM0->TASKS_STARTTX = 1;
        while(NRF_TWIM0->EVENTS_TXSTARTED == 0){};
        while(NRF_TWIM0->EVENTS_LASTTX == 0){};
        nrf_delay_us(100);
        while (NRF_TWIM0->EVENTS_STOPPED == 0){};
    
        uint8_t tx_buf2[]={0x00,0xD3,0x00,0x40,0x8D};
    
        NRF_TWIM0->TXD.MAXCNT = sizeof(tx_buf2);
        NRF_TWIM0->TXD.PTR = (uint32_t)&tx_buf2[0];
    
        NRF_TWIM0->EVENTS_STOPPED = 0;
        NRF_TWIM0->TASKS_STARTTX = 1;
        while(NRF_TWIM0->EVENTS_TXSTARTED == 0){};
        while(NRF_TWIM0->EVENTS_LASTTX == 0){};
        nrf_delay_us(100);
        while (NRF_TWIM0->EVENTS_STOPPED == 0){};
    
        uint8_t tx_buf3[]={0x00,0x14};
    
        NRF_TWIM0->TXD.MAXCNT = sizeof(tx_buf3);
        NRF_TWIM0->TXD.PTR = (uint32_t)&tx_buf3[0];
    
        NRF_TWIM0->EVENTS_STOPPED = 0;
        NRF_TWIM0->TASKS_STARTTX = 1;
        while(NRF_TWIM0->EVENTS_TXSTARTED == 0){};
        while(NRF_TWIM0->EVENTS_LASTTX == 0){};
        nrf_delay_us(100);
        while (NRF_TWIM0->EVENTS_STOPPED == 0){};
    
        uint8_t tx_buf4[]={0x00,0x20,0x00,0xA1,0xC8};
    
        NRF_TWIM0->TXD.MAXCNT = sizeof(tx_buf4);
        NRF_TWIM0->TXD.PTR = (uint32_t)&tx_buf4[0];
    
        NRF_TWIM0->EVENTS_STOPPED = 0;
        NRF_TWIM0->TASKS_STARTTX = 1;
        while(NRF_TWIM0->EVENTS_TXSTARTED == 0){};
        while(NRF_TWIM0->EVENTS_LASTTX == 0){};
        nrf_delay_us(100);
        while (NRF_TWIM0->EVENTS_STOPPED == 0){};
    
        uint8_t tx_buf5[]={0x00,0xDA,0x02,0x81,0x8F};
    
        NRF_TWIM0->TXD.MAXCNT = sizeof(tx_buf5);
        NRF_TWIM0->TXD.PTR = (uint32_t)&tx_buf5[0];
    
        NRF_TWIM0->EVENTS_STOPPED = 0;
        NRF_TWIM0->TASKS_STARTTX = 1;
        while(NRF_TWIM0->EVENTS_TXSTARTED == 0){};
        while(NRF_TWIM0->EVENTS_LASTTX == 0){};
        nrf_delay_us(100);
        while (NRF_TWIM0->EVENTS_STOPPED == 0){};
    
        uint8_t tx_buf6[]={0x00,0xD9};
    
        NRF_TWIM0->TXD.MAXCNT = sizeof(tx_buf6);
        NRF_TWIM0->TXD.PTR = (uint32_t)&tx_buf6[0];
    
        NRF_TWIM0->EVENTS_STOPPED = 0;
        NRF_TWIM0->TASKS_STARTTX = 1;
        while(NRF_TWIM0->EVENTS_TXSTARTED == 0){};
        while(NRF_TWIM0->EVENTS_LASTTX == 0){};
        nrf_delay_us(100);
        while (NRF_TWIM0->EVENTS_STOPPED == 0){};
        
        uint8_t tx_buf7[]={0x00,0xF1};
    
        NRF_TWIM0->TXD.MAXCNT = sizeof(tx_buf7);
        NRF_TWIM0->TXD.PTR = (uint32_t)&tx_buf7[0];
    
        NRF_TWIM0->EVENTS_STOPPED = 0;
        NRF_TWIM0->TASKS_STARTTX = 1;
        while(NRF_TWIM0->EVENTS_TXSTARTED == 0){};
        while(NRF_TWIM0->EVENTS_LASTTX == 0){};
        nrf_delay_us(100);
        while (NRF_TWIM0->EVENTS_STOPPED == 0){};
    
        uint8_t tx_buf8[]={0x00,0xD8,0x40,0xA4,0xA6,0x2E,0xAF};
    
        NRF_TWIM0->TXD.MAXCNT = sizeof(tx_buf8);
        NRF_TWIM0->TXD.PTR = (uint32_t)&tx_buf8[0];
    
        NRF_TWIM0->EVENTS_STOPPED = 0;
        NRF_TWIM0->TASKS_STARTTX = 1;
        while(NRF_TWIM0->EVENTS_TXSTARTED == 0){};
        while(NRF_TWIM0->EVENTS_LASTTX == 0){};
        nrf_delay_us(100);
        while (NRF_TWIM0->EVENTS_STOPPED == 0){};
    
        nrf_delay_ms(2000);
    
        ssd1306_cleardisplay();
    
        for(int i = 0; i < 127; i++) ssd1306_draw_pixel(i,25,WHITE);
            for(int i = 0; i < 127; i++) ssd1306_draw_pixel(i,17,WHITE);
                for(int i = 0; i < 127; i++) ssd1306_draw_pixel(i,10,WHITE);
    
    
        uint8_t tx_buf9[]={0x00,0x22,0x00,0xFF,0x21,0x00};
    
        NRF_TWIM0->TXD.MAXCNT = sizeof(tx_buf9);
        NRF_TWIM0->TXD.PTR = (uint32_t)&tx_buf9[0];
    
        NRF_TWIM0->EVENTS_STOPPED = 0;
        NRF_TWIM0->TASKS_STARTTX = 1;
        while(NRF_TWIM0->EVENTS_TXSTARTED == 0){};
        while(NRF_TWIM0->EVENTS_LASTTX == 0){};
        nrf_delay_us(100);
        while (NRF_TWIM0->EVENTS_STOPPED == 0){};
    
        uint8_t tx_buf10[]={0x00,0x7F};
    
        NRF_TWIM0->TXD.MAXCNT = sizeof(tx_buf10);
        NRF_TWIM0->TXD.PTR = (uint32_t)&tx_buf10[0];
    
        NRF_TWIM0->EVENTS_STOPPED = 0;
        NRF_TWIM0->TASKS_STARTTX = 1;
        while(NRF_TWIM0->EVENTS_TXSTARTED == 0){};
        while(NRF_TWIM0->EVENTS_LASTTX == 0){};
        nrf_delay_us(100);
        while (NRF_TWIM0->EVENTS_STOPPED == 0){};
    
        uint8_t tx_buf11[255];
    
        tx_buf11[0]=0x40;
    
        for(int i = 1; i < 255; i++){
          tx_buf11[i] = buffer[i];
        }
    
        NRF_TWIM0->TXD.MAXCNT = sizeof(tx_buf11);
        NRF_TWIM0->TXD.PTR = (uint32_t)&tx_buf11[0];
    
        NRF_TWIM0->EVENTS_STOPPED = 0;
        NRF_TWIM0->TASKS_STARTTX = 1;
        while(NRF_TWIM0->EVENTS_TXSTARTED == 0){};
        while(NRF_TWIM0->EVENTS_LASTTX == 0){};
        nrf_delay_ms(100);
        while (NRF_TWIM0->EVENTS_STOPPED == 0){};
    
        uint8_t tx_buf12[255];
    
        tx_buf12[0]=0x40;
    
        for(int i = 1; i < 255; i++){
          tx_buf12[i] = buffer[i+255];
        }
    
        NRF_TWIM0->TXD.MAXCNT = sizeof(tx_buf12);
        NRF_TWIM0->TXD.PTR = (uint32_t)&tx_buf12[0];
    
        NRF_TWIM0->EVENTS_STOPPED = 0;
        NRF_TWIM0->TASKS_STARTTX = 1;
        while(NRF_TWIM0->EVENTS_TXSTARTED == 0){};
        while(NRF_TWIM0->EVENTS_LASTTX == 0){};
        nrf_delay_ms(100);
        while (NRF_TWIM0->EVENTS_STOPPED == 0){};
    
        uint8_t tx_buf13[]={0x40,0x00,0x00};
    
        NRF_TWIM0->TXD.MAXCNT = sizeof(tx_buf13);
        NRF_TWIM0->TXD.PTR = (uint32_t)&tx_buf13[0];
    
        NRF_LOG_INFO("%d\n",sizeof(tx_buf13));
        NRF_LOG_FLUSH();
        NRF_TWIM0->EVENTS_STOPPED = 0;
        NRF_TWIM0->TASKS_STARTTX = 1;
        while(NRF_TWIM0->EVENTS_TXSTARTED == 0){};
        while(NRF_TWIM0->EVENTS_LASTTX == 0){};
        nrf_delay_ms(100);
        while (NRF_TWIM0->EVENTS_STOPPED == 0){};
    
        while(1){
         __WFE();
        }
    }

Related