Hello, I’m having problems making the SPI communication to work, it stops mid-transfer…
My setup:
VSCode with Platformio, Espressif32 v6.10.0 using esp-idf
Microcontroller: ESP32S3
IC to communicate with via SPI: BL0942
I’ve made a very simple implementation, just to try out SPI master API, following this example code from esp-idf github repository.
This is my resulting test code:
#include "bl0942.h"
#include <stdlib.h>
#include <string.h>
#include "esp_log.h"
#include "driver/spi_master.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
const char *TAG = "BL0942";
#define PIN_SPI_MOSI 13
#define PIN_SPI_MISO 11
#define PIN_SPI_SCK 12
#define BL0942_REG_VOLTAGE 0x08
bl0942_config_t *BL0942_PARAMS = nullptr;
spi_device_handle_t spi_bl0942_handle;
bl0942_status_t bl0942_spi_init(void);
bl0942_status_t bl0942_read_reg_spi(uint8_t reg_id, uint8_t *res, size_t size_reg);
bl0942_status_t bl0942_init(bl0942_config_t *config)
{
if (config == nullptr)
{
ESP_LOGE(TAG, "%s - Null params", __func__);
return BL0942_STATUS_ERR;
}
BL0942_PARAMS = config;
if (bl0942_spi_init() != BL0942_STATUS_OK)
{
ESP_LOGE(TAG, "%s - Error SPI init", __func__);
return BL0942_STATUS_ERR;
}
ESP_LOGI(TAG, "%s - BL0942 initialized", __func__);
return BL0942_STATUS_OK;
}
bl0942_status_t bl0942_get_data(bl0942_data_t *data)
{
if (data == nullptr)
{
ESP_LOGE(TAG, "%s - Null params", __func__);
return BL0942_STATUS_ERR;
}
uint8_t buffer[4] = {0};
//Read voltage value
bl0942_read_reg_spi(BL0942_REG_VOLTAGE, buffer, sizeof(buffer));
return BL0942_STATUS_OK;
}
bl0942_status_t bl0942_spi_init(void)
{
//Init the SPI bus
spi_bus_config_t buscfg = {
.mosi_io_num = PIN_SPI_MOSI,
.miso_io_num = PIN_SPI_MISO,
.sclk_io_num = PIN_SPI_SCK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 32,
};
esp_err_t ret = spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO);
ESP_ERROR_CHECK(ret);
//Init device
spi_device_interface_config_t devcfg = {
.command_bits = 0, //No command bits
.address_bits = 0, //No address bits
.dummy_bits = 0, //No dummy bits
.mode = 1, //SPI mode 1: CPOL=0 CPHA=1
.clock_source = SPI_CLK_SRC_DEFAULT, //Use APB clock
.duty_cycle_pos = 128, //50% duty cycle
.cs_ena_pretrans = 0, //No CS activation before transaction
.cs_ena_posttrans = 0, //No CS deactivation after transaction
.clock_speed_hz = 9 * 100 * 1000, //Clock out at 900 kHz
.input_delay_ns = 0, //No input delay
.spics_io_num = 10, //CS pin
.flags = 0, //No flags
.queue_size = 7, //We want to be able to queue 7 transactions at a time
.pre_cb = nullptr, //Specify pre-transfer callback to handle D/C line,
.post_cb = nullptr
};
//add device to the bus
ret = spi_bus_add_device(SPI2_HOST, &devcfg, &spi_bl0942_handle);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "%s - Error to add SPI device to the bus: %s", __func__, esp_err_to_name(ret));
return BL0942_STATUS_ERR;
}
return BL0942_STATUS_OK;
}
bl0942_status_t bl0942_read_reg_spi(uint8_t reg_id, uint8_t *res, size_t size_reg)
{
spi_transaction_t t;
memset(&t, 0, sizeof(t));
t.length = 32;
t.tx_data[0] = reg_id;
t.rxlength = 24;
t.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA;
if (spi_device_transmit(spi_bl0942_handle, &t) != ESP_OK)
{
ESP_LOGE(TAG, "%s - Error to read SPI register", __func__);
return BL0942_STATUS_ERR;
}
ESP_LOGI(TAG, "%s - Data read: %02X%02X%02X%02X", __func__, t.rx_data[0], t.rx_data[1], t.rx_data[2], t.rx_data[3]);
//Copy data
memcpy(res, t.rx_data, size_reg);
return BL0942_STATUS_OK;
}
Here is the esp32 logs of the firmware (you can see there are no error in initialization):
I (316) main_task: Started on CPU0
I (326) main_task: Calling app_main()
I (326) BL0942: bl0942_init - BL0942 initialized
I (326) BL0942: bl0942_read_reg_spi - Data read: FFFFFFFF
And here is what happens looking at the gpios with the logic analyzer:
Is like the SPI lines don’t work properly, I’m very confused.
I’ve tried to change various configurations to the device and the bus, I’ve followed the SPI connections for the SPI2_HOST pinout from the SPI Master Driver API reference
If someone has any input on this, perhaps very silly, problem I will appreciate it very much