I do have a 3wire device (STLED316S) connected to an esp32s2
When using SPI2_HOST as SPi host it wroks fine and I can read the bus, but when using SPI3_HOST it does not work. And I do need to use the SPI3_HOST, the #2 host is connected to another device.
Here is a simple single file test C source code in order to reproducde the problem, I do the test with idf 5.5.1
Code: Select all
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"
#define NBR_OF_DIGIT 6
#define STB_PIN 10
#define CLK_PIN 14
#define DATA_PIN 15
static spi_host_device_t _host=SPI3_HOST;
static spi_device_handle_t _spiDev;
// STLED316S driver object
#define SEVEN_DOT (0x80)
const uint8_t _digitTable[10] = {
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F, // 9
};
const uint8_t _digitSymbols[] = {
0x08, // _
0x40, // -
0x30, // | L
0x06, // | R
SEVEN_DOT, // dot
0x01, // _ up
};
/******************************************************************************/
/* Typedef */
/******************************************************************************/
typedef enum
{
DIGITall = 0,
DIGITn1 = 1,
DIGITn2 = 2,
DIGITn3 = 3,
DIGITn4 = 4,
DIGITn5 = 5,
DIGITn6 = 6
} DIGITnum_t;
static uint8_t _dispDataBuffer[7]; //!< Memory buffer used for display
static uint8_t _nbrOfDigit=6;
const uint8_t STLED316S_DISP_ON_CMD = 0x0D;
const uint8_t STLED316S_DISP_OFF_CMD = 0x0E;
const uint8_t STLED316S_DATA_WR = 0x00;
const uint8_t STLED316S_DATA_RD = 0x40;
const uint8_t STLED316S_ADDR_INC = 0x00;
const uint8_t STLED316S_ADDR_FIXED = 0x20;
const uint8_t STLED316S_CONF1_PAGE = 0x10;
const uint8_t STLED316S_DIG_PAGE = 0x00;
const uint8_t STLED316S_LED_PAGE = 0x08;
const uint8_t STLED316S_BRT_LED_PAGE = 0x18;
const uint8_t STLED316S_READ_PAGE = 0x08;
const uint8_t STLED316S_ADDR_LED_DATA = 0x00;
const uint8_t STLED316S_ADDR_KEY_DATA1 = 0x01;
const uint8_t STLED316S_ADDR_KEY_DATA2 = 0x02;
const uint8_t STLED316S_CONF_BRT_CONSTANT = 0x18;
const uint8_t STLED316S_CONF_BRT_VARIABLE = 0x00;
void initSTLed(void)
{
esp_err_t err;
spi_bus_config_t buscfg = {};
buscfg.mosi_io_num = DATA_PIN;
buscfg.miso_io_num = -1; // Half-duplex uses MOSI for RX
buscfg.sclk_io_num = CLK_PIN;
buscfg.quadwp_io_num = -1;
buscfg.quadhd_io_num = -1;
buscfg.max_transfer_sz = 64;
ESP_ERROR_CHECK(spi_bus_initialize(_host, &buscfg, SPI_DMA_CH_AUTO)); //SPI_DMA_CH_AUTO));
spi_device_interface_config_t devcfg = {};
devcfg.clock_speed_hz = 500000; //clock_speed_hz
devcfg.mode = 0;
devcfg.spics_io_num = STB_PIN;
devcfg.queue_size = 4;
devcfg.flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_NO_DUMMY |SPI_DEVICE_BIT_LSBFIRST|SPI_DEVICE_3WIRE;
devcfg.command_bits = 8;
devcfg.address_bits = 0;
devcfg.dummy_bits = 0;
err=spi_bus_add_device(_host, &devcfg, &_spiDev);
printf("[initSTLed] %s %d\n",esp_err_to_name(err),STB_PIN);
}
uint8_t readData(uint8_t address)
{
uint8_t rxData=0;
spi_transaction_t t = {};
t.cmd=STLED316S_DATA_RD | STLED316S_READ_PAGE | address;
t.length = 0;
t.rxlength = 8;
t.tx_buffer = NULL;
t.rx_buffer = &rxData;
t.flags = 0; //SPI_TRANS_USE_TXDATA;
esp_err_t ret = spi_device_polling_transmit(_spiDev, &t);
// printf("%02x\n",rxData);
return rxData;
}
uint16_t readKeyScan(void)
{
uint16_t keyState = 0;
keyState = readData(STLED316S_ADDR_KEY_DATA2) << 8;
keyState |= readData(STLED316S_ADDR_KEY_DATA1);
return keyState;
}
void writeData(uint8_t *data, uint8_t lenght)
{
spi_transaction_t t = {};
t.cmd=data[0];
t.length = lenght > 1?(size_t)(lenght-1) * 8:0;
t.tx_buffer = lenght > 1?&data[1]:NULL;
t.flags = 0; //SPI_TRANS_USE_TXDATA;
esp_err_t ret = spi_device_polling_transmit(_spiDev, &t);
}
/**
* @brief Controls the LEDs of a digit with raw data
*
* @param DIGITnum : DIGITall->All or Digit number (DIGITn1..DIGITn6)
* @param raw : b7->SEG8 / b6->SEG7 / b5->SEG6 / b4->SEG5 / b3->SEG4 / b2->SEG3 / b1->SEG2 / b0->SEG1
*/
void dispRAW(DIGITnum_t DIGITnum, uint8_t raw)
{
uint8_t i;
if (DIGITnum > _nbrOfDigit)
return;
if (DIGITnum == DIGITall)
for (i = 0; i < _nbrOfDigit; i++)
_dispDataBuffer[i + 1] = raw;
else
_dispDataBuffer[DIGITnum] = raw;
_dispDataBuffer[0] = STLED316S_DATA_WR | STLED316S_DIG_PAGE | STLED316S_ADDR_INC;
// writeData(&_dispDataBuffer[0], 1);
writeData(&_dispDataBuffer[0], _nbrOfDigit+1);
}
void SevenSet(int value)
{
dispRAW(DIGITn1, _digitTable[(value / 1000) % 10]);
dispRAW(DIGITn2, _digitTable[(value / 100) % 10]);
dispRAW(DIGITn3, _digitTable[(value/ 10) % 10]);
dispRAW(DIGITn4, _digitTable[(value/ 1) % 10]);
}
void app_main(void)
{
uint16_t v=1234;
/* Print chip information */
esp_chip_info_t chip_info;
uint32_t flash_size;
esp_chip_info(&chip_info);
printf("This is %s chip with %d CPU core(s), %s%s%s%s, ",
CONFIG_IDF_TARGET,
chip_info.cores,
(chip_info.features & CHIP_FEATURE_WIFI_BGN) ? "WiFi/" : "",
(chip_info.features & CHIP_FEATURE_BT) ? "BT" : "",
(chip_info.features & CHIP_FEATURE_BLE) ? "BLE" : "",
(chip_info.features & CHIP_FEATURE_IEEE802154) ? ", 802.15.4 (Zigbee/Thread)" : "");
unsigned major_rev = chip_info.revision / 100;
unsigned minor_rev = chip_info.revision % 100;
printf("silicon revision v%d.%d, ", major_rev, minor_rev);
if(esp_flash_get_size(NULL, &flash_size) != ESP_OK) {
printf("Get flash size failed");
return;
}
printf("%" PRIu32 "MB %s flash\n", flash_size / (uint32_t)(1024 * 1024),
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
printf("Minimum free heap size: %" PRIu32 " bytes\n", esp_get_minimum_free_heap_size());
initSTLed();
SevenSet(v++);
for (int i = 10; i >= 0; i--) {
SevenSet(v++);
printf("key=%x\n",readKeyScan());
printf("Restarting in %d seconds...\n", i);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
printf("Restarting now.\n");
fflush(stdout);
esp_restart();
}