I'm trying to use the spi_master driver to communicate with an CS5463 Energy monitoring IC..
I have no problems with writing to the registers of the chip, but if i try to read them, I only recieve the first byte of the data sent on SDO. I have attached a logic analyzer, and i can see that the chip actually sends all the data, so it seems to be an issue on the ESP32 side.
I will write the most relevant pieces of code below, but it can be seen in its entirety at Github.
Code: Select all
#define SYNC0 0xFE
#define SYNC1 0xFF
CS5463::CS5463(gpio_num_t slave_select)
{
printf("Creating device with CS %d\n", slave_select);
spi_device_interface_config_t devcfg;
memset(&devcfg, 0, sizeof(devcfg));
devcfg.clock_speed_hz=2000000, //Clock out at 2 MHz
devcfg.mode=0, //SPI mode 0
devcfg.spics_io_num = slave_select, //CS pin
devcfg.queue_size = 1,
devcfg.pre_cb = nullptr;
devcfg.command_bits = 8;
ESP_ERROR_CHECK(spi_bus_add_device(HSPI_HOST, &devcfg, &this->spi));
}
void CS5463::init_spi(gpio_num_t miso, gpio_num_t mosi, gpio_num_t clk)
{
if(CS5463::initialised == false)
{ //Init spi device.
printf("initialising SPI bus\n");
spi_bus_config_t buscfg;
memset(&buscfg, 0, sizeof(buscfg));
buscfg.miso_io_num = miso;
buscfg.mosi_io_num = mosi;
buscfg.sclk_io_num = clk;
buscfg.quadwp_io_num=-1;
buscfg.quadhd_io_num=-1;
ESP_ERROR_CHECK(spi_bus_initialize(HSPI_HOST, &buscfg, 1));
CS5463::initialised = true;
}
else
printf("SPI already initialised");
}
int CS5463::read_temperature(float *temp)
{
int err;
uint8_t data_out[3];
err = this->read_register(registers::temperature, data_out);
printf("0x%.2x%.2x%.2x\n", data_out[0], data_out[1], data_out[2]);
*temp = (*(int8_t *)data_out);
*temp += data_out[1] / float(1 << 7);
*temp += data_out[2] / float(1 << 15);
return err;
}
int CS5463::read_register(registers the_register, uint8_t *databuff)
{
uint8_t data_out[3] = {SYNC1, SYNC1, SYNC1};
return this->do_spi_transaction(the_register << 1, sizeof(data_out), data_out, databuff);
}
int CS5463::do_spi_transaction(uint8_t cmd, uint8_t len, uint8_t *data_out, uint8_t *data_in)
{
spi_transaction_t t;
printf("cmd: 0x%.2x, len: %d\n", cmd, len);
memset(&t, 0, sizeof(t)); //Zero out the transaction
t.length = len * 8;
t.tx_buffer = data_out;
t.rx_buffer = data_in;
t.command = cmd;
esp_err_t ret;
xSemaphoreTake(this->spi_mux, portMAX_DELAY);
ret = spi_device_transmit(this->spi, &t); //Transmit!
xSemaphoreGive(this->spi_mux);
return ret;
}
However, with a logic analyser attached, i can see that the chip actually sends data in the last two bytes:cmd: 0x26, len: 3
0x120000
Am I using the spi driver wrong, or what reasons can there be for the last two bytes not showing up in the rx_buffer?
Regards
Stefan