Page 1 of 1

SPI transfer with reading data in ESP-IDF

Posted: Wed Oct 18, 2023 9:31 pm
by hellish
Hi.

I am working on a project that requires SPI communication with IT8951 (ePaper driver). And not only sending data but reading as well.

I found some examples for Arduino and I made it work using arduino-core. However, I need to write it in pure esp-idf, using (spi_master) library. And I can't make it work.

Is there any SPI expert that would help me, or at least give a hint on how to write working code for bi-directional SPI transfer?

Here is the working arduino based code:

Code: Select all

#include <arduino.h>
#include <SPI.h>

extern "C"
{

#include <stdio.h>
#include <driver/gpio.h>

#define PIN_MISO 12  // data in
#define PIN_MOSI 13  // data out
#define PIN_SCK 18   // clock
#define PIN_CS 5     // chip select
#define PIN_RESET 23 // PIN_RESET
#define PIN_HRDY 25  // busy

#define IT8951_TCON_REG_WR 0x0011

  typedef struct
  {
    uint16_t usPanelW;
    uint16_t usPanelH;
    uint16_t usImgBufAddrL;
    uint16_t usImgBufAddrH;
    uint16_t usFWVersion[8];  // 16 Bytes String
    uint16_t usLUTVersion[8]; // 16 Bytes String
  } IT8951DevInfo;

  IT8951DevInfo gstI80DevInfo;

  void init()
  {
    // arduino
    pinMode(PIN_SCK, OUTPUT);
    pinMode(PIN_CS, OUTPUT);
    pinMode(PIN_RESET, OUTPUT);
    pinMode(PIN_HRDY, INPUT);

    SPI.begin(PIN_SCK, PIN_MISO, PIN_MOSI, PIN_CS);
    SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
  }

  void IT8951WaitForReady()
  {
    uint8_t ulData = digitalRead(PIN_HRDY);
    while (ulData == 0)
    {
      ulData = digitalRead(PIN_HRDY);
    }
  }

  void IT8951WriteCmdCode(uint16_t usCmdCode)
  {
    // Set Preamble for Write Command
    uint16_t wPreamble = 0x6000;

    IT8951WaitForReady();

    digitalWrite(PIN_CS, LOW);

    SPI.transfer(wPreamble >> 8);
    SPI.transfer(wPreamble);

    IT8951WaitForReady();

    SPI.transfer(usCmdCode >> 8);
    SPI.transfer(usCmdCode);

    digitalWrite(PIN_CS, HIGH);
  }

  void IT8951WriteData(uint16_t usData)
  {
    // Set Preamble for Write Data
    uint16_t wPreamble = 0x0000;

    IT8951WaitForReady();

    digitalWrite(PIN_CS, LOW);

    SPI.transfer(wPreamble >> 8);
    SPI.transfer(wPreamble);

    IT8951WaitForReady();

    SPI.transfer(usData >> 8);
    SPI.transfer(usData);

    digitalWrite(PIN_CS, HIGH);
  }

  void IT8951ReadNData(uint16_t *pwBuf, uint32_t ulSizeWordCnt)
  {
    uint32_t i;

    uint16_t wPreamble = 0x1000;

    IT8951WaitForReady();

    digitalWrite(PIN_CS, LOW);

    SPI.transfer(wPreamble >> 8);
    SPI.transfer(wPreamble);

    IT8951WaitForReady();

    pwBuf[0] = SPI.transfer(0x00); // dummy
    pwBuf[0] = SPI.transfer(0x00); // dummy

    IT8951WaitForReady();

    for (i = 0; i < ulSizeWordCnt; i++)
    {
      pwBuf[i] = SPI.transfer(0x00) << 8;
      pwBuf[i] |= SPI.transfer(0x00);
    }

    digitalWrite(PIN_CS, HIGH);
  }

  void GetIT8951SystemInfo(void *pBuf)
  {
    uint16_t *pusWord = (uint16_t *)pBuf;
    IT8951DevInfo *pstDevInfo;

    digitalWrite(PIN_CS, HIGH);
    digitalWrite(PIN_RESET, LOW);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    digitalWrite(PIN_RESET, HIGH);

    IT8951WriteCmdCode(0x0302);
    IT8951ReadNData(pusWord, sizeof(IT8951DevInfo) / 2); // Polling PIN_HRDY for each words(2-bytes) if possible

    digitalWrite(PIN_CS, LOW);

    pstDevInfo = (IT8951DevInfo *)pBuf;

    printf("Panel(W,H) = (%d,%d)\r\n",
           pstDevInfo->usPanelW, pstDevInfo->usPanelH);
    printf("Image Buffer Address = %X\r\n",
           pstDevInfo->usImgBufAddrL | (pstDevInfo->usImgBufAddrH << 16));
    printf("FW Version = %s\r\n", (uint8_t *)pstDevInfo->usFWVersion);
    printf("LUT Version = %s\r\n", (uint8_t *)pstDevInfo->usLUTVersion);
  }

  int app_main(void)
  {
    init();
    GetIT8951SystemInfo(&gstI80DevInfo);
    return 0;
  }
}

Re: SPI transfer with reading data in ESP-IDF

Posted: Mon Oct 23, 2023 7:34 am
by pacucha42
Hi @hellish,
take a look into https://gitlab.espressif.cn:6688/espres ... type=heads - the example provides both sender and receiver code. Hope this helps