Ill give u my Setup SPI routine, a Write 1 byte routine and a Read 1 byte routine.
This device has the following command structure,
To write: 1 Cmd Write Byte, 2 or 3 Address bytes(depends on the version of the device it needs 16 or 24 bits of address) and the byte to write. Total bytes to write, 4 or 5, total 32 or 40 bits.
To read: 1 Cmd Read byte, 2 or 3 Address bytes and the requested byte.
Total 24 or 32 to send and 1 byte to read
Code follows
Code: Select all
void spiconf(int spimode)
{
spi_bus_config_t buscfg;
spi_device_interface_config_t devcfg;
esp_err_t ret;
memset(&buscfg,0,sizeof(buscfg));
memset(&devcfg,0,sizeof(devcfg));
buscfg.mosi_io_num=GPIO_NUM_XX; //MOSI pin
buscfg .miso_io_num=GPIO_NUM_YY; //MISO Pin
buscfg.sclk_io_num=GPIO_NUM_ZZ; // Clock Pin
buscfg.quadwp_io_num=-1;
buscfg .quadhd_io_num=-1;
//Initialize the SPI bus
ret=spi_bus_initialize(VSPI_HOST, &buscfg, 1); //1 is for dma channel, can be 2 but its the same basically
assert(ret == ESP_OK);
devcfg .clock_speed_hz=20000000; //Clock out at 20 MHz or whatever u need
devcfg.mode=spimode; //SPI mode 0 or 3
devcfg.spics_io_num=GPIO_NUM_CS; //CS pin
devcfg.queue_size=1; //Can NOT be 0
devcfg.flags=SPI_DEVICE_HALFDUPLEX; //If full duplex remember when receiving drop the SENT/WRITE bytes reply
//Attach the LCD to the SPI bus
ret=spi_bus_add_device(VSPI_HOST, &devcfg, &spi); //Only two Option HSPI or VSPI. Pins (mosi,miso,clk and cs) can be "almost" any (some restrictions regarding certains predefined pins in ESP32 . Google it)
assert(ret==ESP_OK);
// Start using the spi
}
To write to the spi
Code: Select all
int FramSPI::write8 (uint32_t framAddr, uint8_t value)
{
esp_err_t ret=0;
spi_transaction_t t;
uint8_t data[5];
memset(&t, 0, sizeof(t)); //Zero out the transaction
data[0]=MBRSPI_WRITE; //The Write Cmd for this chip
if(addressBytes==2) //COuld be 2 or three bytes address
{
data[1]=framAddr &0xff00;
data[2]=framAddr& 0xff;
data[3]=value;
t.length=32; //Command is 4 bytes *8 =32 bits
}
else
{
data[1]=framAddr & 0xff0000;
data[2]=framAddr& 0xff00;
data[3]=framAddr& 0xff;
data[4]=value;
t.length=40; //Command is 5 bytes *8 =40 bits
}
t.tx_buffer=&data;
t.rxlength=0;
t.rx_buffer=NULL;
ret=spi_device_transmit(spi, &t); //Transmit!
return ret;
}
and to read 1 byte
Code: Select all
uint8_t FramSPI::read8 (uint32_t framAddr)
{
spi_transaction_t t;
uint8_t data[4]={0},rxdata[4]={0};
memset(&t, 0, sizeof(t)); //Zero out the transaction
data[0]=MBRSPI_READ; //Read Cmd for this device
if(addressBytes==2)
{
data[1]=framAddr &0xff00;
data[2]=framAddr& 0xff;
t.length=24; //Command is 3 btyes *8 =24 bits
}
else
{
data[1]=framAddr & 0xff0000;
data[2]=framAddr& 0xff00;
data[3]=framAddr& 0xff;
t.length=32; //Command is 4 btyes *8 =32 bits
}
t.rxlength=8;
t.rx_buffer=&rxdata;
t.tx_buffer=&data;
spi_device_transmit(spi, &t); //Transmit!
return rxdata[0]; //first byte only.
//If you set spi to full duplex you would have received 4 bytes, 1 for each sent byte (3) and the one u really needed (4).
// Setting to half duplex you only get the requested read byte.
}
Hope it helps