TMDS64EVM: Oled screen issue

Part Number: TMDS64EVM
Other Parts Discussed in Thread: SYSCONFIG

Hi TI,

 

Hi have a problem with my TMDS64EVM, I cannot use the Oled screen on the board. I think that I communicate with it. I unblocked the reset pin 16 of the GPIO to see the oled screen on the I2C bus but nothing appears on the screen when I execut emy code. Can you help me?

here is my code

#include <kernel/dpl/DebugP.h>
#include <kernel/dpl/ClockP.h>
#include <kernel/dpl/SystemP.h>

#include <drivers/i2c.h>

#include "ti_drivers_config.h"
#include "ti_drivers_open_close.h"
#include "ti_board_open_close.h"

#define OLED_ADDR      (0x3C)
#define IOEXP_ADDR     (0x22)

#define OLED_RST_REG   (0x05)   /* Port1 Output */
#define OLED_CFG_REG   (0x0D)   /* Port1 Config */
#define OLED_RST_BIT   (6)      /* P16 */

/* ========================================================= */

static int32_t TCA_WriteReg(
        I2C_Handle hI2c,
        uint8_t reg,
        uint8_t value)
{
    uint8_t tx[2];
    I2C_Transaction trans;

    tx[0] = reg;
    tx[1] = value;

    I2C_Transaction_init(&trans);

    trans.writeBuf     = tx;
    trans.writeCount   = 2;
    trans.slaveAddress = IOEXP_ADDR;

    return I2C_transfer(hI2c, &trans);
}

static int32_t TCA_ReadReg(
        I2C_Handle hI2c,
        uint8_t reg,
        uint8_t *value)
{
    I2C_Transaction trans;

    I2C_Transaction_init(&trans);

    trans.writeBuf     = &reg;
    trans.writeCount   = 1;

    trans.readBuf      = value;
    trans.readCount    = 1;

    trans.slaveAddress = IOEXP_ADDR;

    return I2C_transfer(hI2c, &trans);
}

/* ========================================================= */

static int32_t OLED_Cmd(
        I2C_Handle hI2c,
        uint8_t cmd)
{
    uint8_t tx[2];
    I2C_Transaction trans;

    tx[0] = 0x00;
    tx[1] = cmd;

    I2C_Transaction_init(&trans);

    trans.writeBuf     = tx;
    trans.writeCount   = 2;
    trans.slaveAddress = OLED_ADDR;

    return I2C_transfer(hI2c, &trans);
}

/* ========================================================= */

static void OLED_Reset(I2C_Handle hI2c)
{
    uint8_t val;

    DebugP_log("OLED RESET START\r\n");

    TCA_ReadReg(hI2c, OLED_CFG_REG, &val);

    val &= ~(1U << OLED_RST_BIT);

    TCA_WriteReg(hI2c,
                 OLED_CFG_REG,
                 val);

    TCA_ReadReg(hI2c, OLED_RST_REG, &val);

    val &= ~(1U << OLED_RST_BIT);

    TCA_WriteReg(hI2c,
                 OLED_RST_REG,
                 val);

    ClockP_usleep(10000);

    val |= (1U << OLED_RST_BIT);

    TCA_WriteReg(hI2c,
                 OLED_RST_REG,
                 val);

    ClockP_usleep(100000);

    DebugP_log("OLED RESET DONE\r\n");
}

/* ========================================================= */

static void OLED_Init(I2C_Handle hI2c)
{
    OLED_Cmd(hI2c, 0xAE);

    OLED_Cmd(hI2c, 0xD5);
    OLED_Cmd(hI2c, 0x80);

    OLED_Cmd(hI2c, 0xA8);
    OLED_Cmd(hI2c, 0x0F);

    OLED_Cmd(hI2c, 0xD3);
    OLED_Cmd(hI2c, 0x00);

    OLED_Cmd(hI2c, 0x40);

    OLED_Cmd(hI2c, 0x8D);
    OLED_Cmd(hI2c, 0x14);

    OLED_Cmd(hI2c, 0x20);
    OLED_Cmd(hI2c, 0x00);

    OLED_Cmd(hI2c, 0xA1);
    OLED_Cmd(hI2c, 0xC8);

    OLED_Cmd(hI2c, 0xDA);
    OLED_Cmd(hI2c, 0x02);

    OLED_Cmd(hI2c, 0x81);
    OLED_Cmd(hI2c, 0x8F);

    OLED_Cmd(hI2c, 0xD9);
    OLED_Cmd(hI2c, 0xF1);

    OLED_Cmd(hI2c, 0xDB);
    OLED_Cmd(hI2c, 0x40);

    OLED_Cmd(hI2c, 0xA4);
    OLED_Cmd(hI2c, 0xA6);

    OLED_Cmd(hI2c, 0xAF);

    DebugP_log("OLED INIT DONE\r\n");
}

/* ========================================================= */

static void OLED_AllPixelsOn(I2C_Handle hI2c)
{
    DebugP_log("FORCE ALL PIXELS ON\r\n");

    OLED_Cmd(hI2c, 0xA5);
}

/* ========================================================= */

void i2c_oled_main(void *args)
{
    I2C_Handle i2cHandle;

    Drivers_open();
    Board_driversOpen();

    i2cHandle = gI2cHandle[CONFIG_I2C0];

    DebugP_log("\r\n");
    DebugP_log("OLED PROBE = %d\r\n",
               I2C_probe(i2cHandle, OLED_ADDR));

    DebugP_log("TCA  PROBE = %d\r\n",
               I2C_probe(i2cHandle, IOEXP_ADDR));

    OLED_Reset(i2cHandle);

    OLED_Init(i2cHandle);

    ClockP_sleep(1);

    OLED_AllPixelsOn(i2cHandle);

    while(1)
    {
        ClockP_sleep(1);
    }
}
  • Hi,

    Please allow some time to review the above code and revert back.

    Meanwhile please tell us which version of SDK are you using? What I2C instance are you using?

    From which core are you running the code?

    Regards,

    Tushar

  • Hi Tushar,

    I am using the I2C temperature example that uses the I2C1 with gI2cHandle[CONFIG_I2C0]. CONFIG_I2C0 is wel configured to I2C1 in the sysconfig file (yes, confusing but it is the TI code...).

    The oled adress 0x3C is wel present when I am scanning the I2C bus after enabling GPIO pin 16.

    For the SDK, I am using mcu_plus_sdk_am64x_08_01_00_36 on windows.

    Regards,

    François

  • Hi Francois,

    For the SDK, I am using mcu_plus_sdk_am64x_08_01_00_36 on windows.

    This is very old version old version of the SDK. I will need to check, there are a lot of bug fixes happen after this version of SDK.

    We recommend you to use the latest version of SDK which implements a lot of bug fixes and new features.

    Please allow some time to check the above.

    Regards,

    Tushar

  • Hi, I tried with the mcu_plus_sdk_am64x_12_01_00_33 sdk with this code and it still doesn't work:

    #include <kernel/dpl/DebugP.h>
    #include <kernel/dpl/ClockP.h>
    #include <drivers/i2c.h>

    #include "ti_drivers_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"

    #define OLED_ADDR   (0x3C)
    #define IOEXP_ADDR  (0x22)

    /* -------------------------------------------------------------------------- */
    /* I2C helpers                                                                 */
    /* -------------------------------------------------------------------------- */

    static int32_t i2c_write(I2C_Handle i2cHandle,
                             uint8_t addr,
                             uint8_t *buf,
                             uint16_t len)
    {
        I2C_Transaction t;

        I2C_Transaction_init(&t);

        t.targetAddress = addr;
        t.writeBuf      = buf;
        t.writeCount    = len;

        return I2C_transfer(i2cHandle, &t);
    }

    /* -------------------------------------------------------------------------- */
    /* OLED RESET via IO Expander                                                  */
    /* -------------------------------------------------------------------------- */

    static void oled_hw_reset(I2C_Handle i2cHandle)
    {
        uint8_t tx[2];

        /* Port1 bit6 = output */
        tx[0] = 0x0D;
        tx[1] = 0xBF;
        i2c_write(i2cHandle, IOEXP_ADDR, tx, 2);

        /* RESETn = 0 */
        tx[0] = 0x05;
        tx[1] = 0x00;
        i2c_write(i2cHandle, IOEXP_ADDR, tx, 2);

        ClockP_usleep(10000);

        /* RESETn = 1 */
        tx[0] = 0x05;
        tx[1] = 0x40;
        i2c_write(i2cHandle, IOEXP_ADDR, tx, 2);

        ClockP_usleep(10000);
    }

    /* -------------------------------------------------------------------------- */
    /* SSD1306 commands                                                            */
    /* -------------------------------------------------------------------------- */

    static void oled_cmd(I2C_Handle i2cHandle, uint8_t cmd)
    {
        uint8_t tx[2];

        tx[0] = 0x00;   /* command */
        tx[1] = cmd;

        i2c_write(i2cHandle, OLED_ADDR, tx, sizeof(tx));
    }

    static void oled_set_window(I2C_Handle i2cHandle)
    {
        /* Column 0..127 */
        oled_cmd(i2cHandle, 0x21);
        oled_cmd(i2cHandle, 0x00);
        oled_cmd(i2cHandle, 0x7F);

        /* Pages 0..1 (128x16 => 2 pages) */
        oled_cmd(i2cHandle, 0x22);
        oled_cmd(i2cHandle, 0x00);
        oled_cmd(i2cHandle, 0x01);
    }

    static void oled_init(I2C_Handle i2cHandle)
    {
        oled_cmd(i2cHandle, 0xAE);      /* Display OFF */

        oled_cmd(i2cHandle, 0xA8);      /* Multiplex ratio */
        oled_cmd(i2cHandle, 0x0F);      /* 16 rows */

        oled_cmd(i2cHandle, 0x20);      /* Memory mode */
        oled_cmd(i2cHandle, 0x00);      /* Horizontal */

        oled_cmd(i2cHandle, 0xDA);      /* COM pins */
        oled_cmd(i2cHandle, 0x02);

        oled_cmd(i2cHandle, 0x81);      /* Contrast */
        oled_cmd(i2cHandle, 0x7F);

        /* Charge pump ON */
        oled_cmd(i2cHandle, 0x8D);
        oled_cmd(i2cHandle, 0x14);

        oled_cmd(i2cHandle, 0xA4);      /* Resume RAM display */
        oled_cmd(i2cHandle, 0xA6);      /* Normal display */

        oled_cmd(i2cHandle, 0xAF);      /* Display ON */
    }

    /* -------------------------------------------------------------------------- */
    /* Fill screen                                                                 */
    /* -------------------------------------------------------------------------- */

    static void oled_fill(I2C_Handle i2cHandle, uint8_t pattern)
    {
        uint8_t tx[17];

        tx[0] = 0x40;   /* data */

        for(int i = 1; i < 17; i++)
        {
            tx[i] = pattern;
        }

        oled_set_window(i2cHandle);

        /*
         * 128 x 16 pixels
         * => 256 bytes framebuffer
         * => 16 transfers of 16 bytes
         */
        for(int i = 0; i < 16; i++)
        {
            i2c_write(i2cHandle, OLED_ADDR, tx, sizeof(tx));
        }
    }

    /* -------------------------------------------------------------------------- */
    /* Main                                                                         */
    /* -------------------------------------------------------------------------- */

    void i2c_oled_screen_main(void)
    {
        int32_t status;
        I2C_Handle i2cHandle;

        Drivers_open();
        Board_driversOpen();

    #if defined(SOC_AM65X)
        I2C_intr_router_configInit();
    #endif

        i2cHandle = gI2cHandle[CONFIG_I2C0];

        status = I2C_probe(i2cHandle, OLED_ADDR);

        if(status != SystemP_SUCCESS)
        {
            DebugP_logError("SSD1306 not found at 0x3C\r\n");
            goto cleanup;
        }

        DebugP_log("SSD1306 found at 0x3C\r\n");

        oled_hw_reset(i2cHandle);

        oled_init(i2cHandle);

        /* All pixels ON */
        oled_fill(i2cHandle, 0xFF);

        DebugP_log("OLED initialization done\r\n");

    cleanup:

    #if defined(SOC_AM65X)
        I2C_intr_router_configDeinit();
    #endif

        Board_driversClose();
        Drivers_close();
    }
  • Hi,

    I tried running the above provided code and I can see the Oled is turning on. All the pixels are set and the screen appears to be white. 

    Are you observing a different behaviour?

    Regards,

    Tushar

  • Hi Tushar,

    Ok then it is an hardware issue. Thank you for your help! You can close the ticket.

    Regards,

    François Schoors

  • Hi Franois,

    Thanks for the confirmation.

    Regards,

    Tushar