The thing is that I need to implement to functions: spiRegisterRead(uint16_t reg_addr) and spiRegisterWrite(uint_16t reg_addr, uit32_t reg_value). These two functions have a main goal of reading the full 32-bit register and writing to it. The read function works as expected, but the write function does not write anything. I have tried multiple versions of that, including using the TXDATA instead of TXBUFFERS etc.
Working spiRegisterRead():
uint32_t spiRegisterRead(uint16_t reg_addr) {
uint8_t rx_buffer[5];
spi_transaction_t t;
memset(&t, 0, sizeof(spi_transaction_t));
t.cmd = SPI_READ_OPCODE;
t.addr = reg_addr;
t.length = 5 * 8; // length byte
t.rxlength = 5 * 8;
t.rx_buffer = rx_buffer;
t.tx_buffer = NULL;
// Transmit the dummy bytes to read the actual data
spi_device_transmit(spi, &t);
// Combine the received bytes into a 32-bit value
uint32_t reg_value = ((uint64_t)rx_buffer[1] << 24) |
((uint64_t)rx_buffer[2] << 16) | ((uint64_t)rx_buffer[3] << 8) | (rx_buffer[4]);
return reg_value;
}
Not working spiRegisterWrite():
uint8_t spiRegisterWrite(uint16_t reg_addr, uint32_t reg_value, uint32_t * pointer) {
uint8_t tx_buffer[4];
//uint8_t rx_buffer[4];
tx_buffer[0] = (uint8_t)reg_value;
tx_buffer[1] = (uint8_t)(reg_value >> 8);
tx_buffer[2] = (uint8_t)(reg_value >> 16);
tx_buffer[3] = (uint8_t)(reg_value >> 24);
//memcpy(tx_buffer, ®_value, sizeof(uint32_t));
printf("Writing %lX into %Xn", reg_value, reg_addr);
spi_transaction_t t;
memset(&t, 0, sizeof(t));
t.cmd = SPI_WRITE_OPCODE; // Not sure
t.addr = reg_addr;
t.length = 4 * 8; // length byte + 4*bytes data
//t.flags = SPI_TRANS_USE_TXDATA;
//t.rxlength = 4 * 8;
//t.rx_buffer = NULL;
t.tx_buffer = tx_buffer;
//memcpy(t.tx_data, ®_value, sizeof(uint32_t));
spi_device_polling_transmit(spi, &t);
/*if (pointer != NULL)
{
memcpy(pointer, rx_buffer, sizeof(uint32_t));
}*/
// uint8_t data_to_send = 0x45;
// spi_transaction_t t;
// memset(&t, 0, sizeof(t)); //Zero out the transaction
// t.length=8; //Command is 8 bits
// t.tx_buffer=&data_to_send; //The data is the cmd itself
// t.user=(void*)1; //D/C needs to be set to 1
// t.addr = 0x0808;
// t.cmd = SPI_WRITE_OPCODE;
// spi_device_transmit(spi, &t);
return 0;
}
In the comments above you can see, what has been tested already.
Here is the intialisation of SPI:
void spi_init() {
esp_err_t ret;
// Configure the SPI bus
spi_bus_config_t buscfg = {
.miso_io_num = PIN_NUM_MISO,
.mosi_io_num = PIN_NUM_MOSI,
.sclk_io_num = PIN_NUM_CLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 4096,
};
// Initialize the SPI bus
ret = spi_bus_initialize(HSPI_HOST, &buscfg, 1);
assert(ret == ESP_OK);
// Configure the SPI device
spi_device_interface_config_t devcfg = {
.clock_speed_hz = 10 * 1000 * 1000, // Clock out at 10 MHz
.mode = 0, // SPI mode 0
.spics_io_num = PIN_NUM_CS, // CS pin
.queue_size = 7,
.pre_cb = NULL,
.post_cb = NULL,
.command_bits = 8, // Important!
.address_bits = 16 // Important!
};
// Attach the SPI device to the SPI bus
ret = spi_bus_add_device(HSPI_HOST, &devcfg, &spi);
assert(ret == ESP_OK);
}
I develop this driver to interact with TCAN4550. As a matter of testing the driver, I wrote the following code:
uint32_t check;
value = spiRegisterRead(0x0808);
printf("Reg content: %lXn", value);
spiRegisterWrite(0x0808, 0x87650000, &check);
usleep(1000);
value = spiRegisterRead(0x0808);
printf("Prev reg value: %lXn", check);
printf("New reg content: %lXn", value);
The register I am writing to is intended as a testing register for writing and reading.
dabrag is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.