Electronic – IST3042 – compatible device

driverstn

I was recently given a display which is powered by a IST3042. According to the datasheet this is a 160×2 TN/STN-LCD Driver. I need to use the SPI mode as this is the interface I have access to.

The first thing I stumbled upon was, that it uses a 9-bit data transfer which is similar to I2C but doesn't make use of the ACK/NACK signals. I tried writing to the display RAM and "something" happens but I'm not quite sure what I'm really doing. If I understand that controller correctly, I need to write the command to set the data pointer to position 0, and then start writing values. Each bit corresponds to a single segment as far as I understand but I am getting strange results depending on what I write. I think that the SPI write is ok because I get correct values on my scope (also the mode should be correct).

Now for the main question:
Does anyone know of a "similar" device where I could find an already existing driver as sample code to take a look at. I haven't really found something similar because maybe I am lacking the correct search terms.

After some search, I have found that this datasheet from the PCF8576C has some .. interesting similarities but I'm not quite there yet.

Best Answer

Since it was asked in a question below, I'll post the solution for a working driver (excerpts) here:

// Initialization of the SPI interface for that specific IC
spi_set_clock_polarity(SPI, CSID_SPI_DISP, SPI_DISP_CPOL);
spi_set_clock_phase(SPI, CSID_SPI_DISP, SPI_DISP_CPHA);
spi_set_bits_per_transfer(SPI, CSID_SPI_DISP, SPI_CSR_BITS_9_BIT); //<- 9bit SPI interface
spi_set_baudrate_div(SPI, CSID_SPI_DISP, (uint8_t)(sysclk_get_peripheral_hz() / SPI_DISP_FREQUENCY));
spi_set_transfer_delay(SPI, CSID_SPI_DISP, SPI_DLYBS, SPI_DLYBCT);

// Initialization for the display so after these lines you should at least see something, also some defines so you can see what's actually being sent and can compare it to the datasheet

#define IST3042_NOT_LAST_CMD            0x80    //!< Is NOT last command in sequence bit pattern
#define IST3042_CMD_MISC                0x7C    //!< Bit pattern to select miscellaneous options
void disp_init(void) {

    ist3042ca1_init(&ist3042);

    uint8_t cmd;

    cmd = IST3042_NOT_LAST_CMD | IST3042_CMD_MISC | 0x02;
    ist3042ca1_write(&ist3042, &cmd, 1);        // Preload
    delay_ms(1);

    cmd = IST3042_NOT_LAST_CMD | IST3042_CMD_POWER_CONTROL | 0x04;
    ist3042ca1_write(&ist3042, &cmd, 1);        // VFOFF
    delay_ms(1);

    cmd = IST3042_NOT_LAST_CMD | IST3042_CMD_DISPLAY_CONTROL | 0x00;
    ist3042ca1_write(&ist3042, &cmd, 1);        // Turn all segments on, do not show them, display on
    delay_ms(100);

    cmd = IST3042_NOT_LAST_CMD | IST3042_CMD_DCK_DIVIDER | 0x0F;
    ist3042ca1_write(&ist3042, &cmd, 1);        // DCK divider

}


// Aaaaand the write_packet function
static status_code_t ist3042ca1_write_packet(const ist3042ca1_t* ist3042_device, const uint8_t *data, size_t len)
{
    uint32_t timeout = SPI_TIMEOUT;
    uint32_t i = 0;
    uint16_t val;

    while (len) {
        timeout = SPI_TIMEOUT;
        while (!spi_is_tx_ready(ist3042_device->spi)) {
            if (!timeout--) {
                return ERR_TIMEOUT;
            }
        }
        //val = data[i];
        val = data[i] << 1;     // This accounts for the ACK cycle the display requires
        spi_put(ist3042_device->spi, val);
        i++;
        len--;
    }

    return STATUS_OK;
}