I am trying to send bytes via SPI but it does not seem to work. I have an LCD attached at the other end of the cable and I can drive it with Arduino Due just fine. Now I am trying to port the code to ESP8266.
I do not have a logic analyzer with me at the moment so it's kinda hard to figure out what's wrong. Maybe you guys can spot something obvious or give some hints.
I am driving CS, DC and Reset for LCD myself, I want to use big-endian (sending high byte then low byte) and I only want to send the Data stored in W0, W1,... (no Cmd, no Dummy, no Addr, no MISO). Here's how I set the pins:
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); //clear bit9
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12);// GPIO12 - Reset for LCD (I do not need MISO)
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode GPIO13 - MOSI
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure io to spi mode GPIO14 - CLK
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15);// GPIO15 - CS
gpio16_output_conf(); // GPIO16 - DC
SET_PERI_REG_MASK(SPI_USER(HSPI), SPI_USR_MOSI ); // use data only (no addr, no cmd, no dummy, command/data for LCD is defined by the DC pin low/high status)
CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_FLASH_MODE | SPI_WR_BYTE_ORDER | SPI_USR_MISO | SPI_USR_ADDR | SPI_USR_COMMAND | SPI_USR_DUMMY); // big endian (MSB)
// SPI clock=CPU clock/8
WRITE_PERI_REG(SPI_CLOCK(HSPI),
((1 & SPI_CLKDIV_PRE) << SPI_CLKDIV_PRE_S) |
((3 & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) |
((1 & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) |
((3 & SPI_CLKCNT_L) << SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div
After that I have code that send a sequence of bytes (byte by byte) to initialize the screen. The function for sending a byte looks like this:
void spiwrite(uint8_t c) {
uint32 regvalue;
uint32 data = (uint32)c;
while (READ_PERI_REG(SPI_CMD(HSPI))&SPI_USR); //waiting for spi module available
SET_PERI_REG_MASK(SPI_USER(HSPI), SPI_USR_MOSI);
CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_FLASH_MODE | SPI_WR_BYTE_ORDER | SPI_USR_MISO | SPI_USR_ADDR | SPI_USR_DUMMY | SPI_USR_COMMAND);
WRITE_PERI_REG(SPI_USER1(HSPI), (7 & SPI_USR_MOSI_BITLEN) << SPI_USR_MOSI_BITLEN_S); // 8 bits
WRITE_PERI_REG(SPI_W0(HSPI), data); // I also tried data << 24 to shift the byte I want to send to the highest/most significant byte of 32 bits of W0 but it did not make a difference
SET_PERI_REG_MASK(SPI_CMD(HSPI), SPI_USR); // send
}
Not sure if I need to call SET_PERI_REG_MASK and CLEAR_PERI_REG_MASK on every send, probably not.
And if you guys have some of your working code (especially when using SPI_USR_MOSI and SPI_W0) then please send a link or attach here. Thanks a lot.