Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP32S3的SPI2_HOST使用spi_master外设时,用"spi_bus_add_device"添加大于三个从机时报错 (IDFGH-7288) #8876

Closed
ou2356 opened this issue May 2, 2022 · 9 comments
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally

Comments

@ou2356
Copy link

ou2356 commented May 2, 2022

Environment

  • Module or chip used: [ESP32S3-WROOM-1]
  • IDF version (run git describe --tags to find it):
    // Release v4.4
  • Build System: [CMake]
  • Compiler version (run xtensa-esp32-elf-gcc --version to find it):
    // xtensa-esp32-elf-gcc (crosstool-NG esp-2021r2-patch2) 8.4.0
  • Operating System: [Windows]
  • (Windows only) environment type: [ESP Command Prompt].
  • Using an IDE?: [Yes (Eclipse + IDF插件)]
  • Power Supply: [USB]

Problem Description

ESP32S3的SPI外设的SPI2在官方文档中说到最大支持6个设备,但是当我添加第4个设备时就出现了错误。

Expected behavior

4个SPI设备可以同时正常添加且使用。

Actual behavior

只能同时添加3个SPI设备(当我在4个SPI设备的添加中注释掉任何一个SPI设备的添加都可以正常运行)

Code to reproduce this issue

    esp_err_t ret;
    spi_bus_config_t SPI2_buscfg={
        .sclk_io_num=SPI_PIN_CLK,
        .mosi_io_num=SPI_PIN_MOSI,
        .miso_io_num=SPI_PIN_MISO,
        .quadwp_io_num=-1,
        .quadhd_io_num=-1,
//        .max_transfer_sz=8,
    };

    gpio_set_pull_mode(SPI_PIN_CLK, GPIO_PULLUP_ONLY);
    gpio_set_pull_mode(SPI_PIN_MOSI, GPIO_PULLUP_ONLY);
    gpio_set_pull_mode(SPI_PIN_MISO, GPIO_PULLUP_ONLY);
    
    //Initialize the SPI bus
    ret=spi_bus_initialize(SPI2_HOST, &SPI2_buscfg, SPI_DMA_CH_AUTO);
    ESP_ERROR_CHECK(ret);

    spi_device_interface_config_t devcfg={
    	.address_bits = 8,
        .clock_speed_hz=BMM150_SPI_SPEED,            	//Clock out at 10 MHz
        .mode=BMM150_SPI_MODE,                         //SPI mode (CPOL, CPHA)
        .spics_io_num=BMM150_PIN_CS,            //CS pin
        .queue_size=1,                          //We want to be able to queue 1 transactions at a time
        .flags = /*SPI_DEVICE_3WIRE | */SPI_DEVICE_HALFDUPLEX,
        .cs_ena_pretrans = 1,
    };
    //Attach the BMM150 to the SPI bus
    ret=spi_bus_add_device(SPI2_HOST, &devcfg, &spi);
    ESP_ERROR_CHECK(ret);

    spi_device_interface_config_t devcfg={
    	.address_bits = 8,
        .clock_speed_hz=BMP390_SPI_SPEED,            	//Clock out at 10 MHz
        .mode=BMP390_SPI_MODE,                         //SPI mode (CPOL, CPHA)
        .spics_io_num=BMP390_PIN_CS,            //CS pin
        .queue_size=1,                          //We want to be able to queue 1 transactions at a time
        .flags = /*SPI_DEVICE_3WIRE | */SPI_DEVICE_HALFDUPLEX,
        .cs_ena_pretrans = 1,
    };
    //Attach the BMP390 to the SPI bus
    ret=spi_bus_add_device(SPI2_HOST, &devcfg, &spi);
    ESP_ERROR_CHECK(ret);

    spi_device_interface_config_t devcfg_acc={
    	.address_bits = 8,
        .clock_speed_hz=BMI088_SPI_SPEED,            	//Clock out at 10 MHz
        .mode=BMI088_SPI_MODE,                         //SPI mode (CPOL, CPHA)
        .spics_io_num=BMI088_A_PIN_CS,            //CS pin
        .queue_size=1,                          //We want to be able to queue 1 transactions at a time
        .flags = /*SPI_DEVICE_3WIRE | */SPI_DEVICE_HALFDUPLEX,
        .cs_ena_pretrans = 1,
    };
    //Attach the BMI088 to the SPI bus
    ret=spi_bus_add_device(SPI2_HOST, &devcfg_acc, &spi_acc);
    ESP_ERROR_CHECK(ret);

    spi_device_interface_config_t devcfg_gyr={
    	.address_bits = 8,
        .clock_speed_hz=BMI088_SPI_SPEED,            	//Clock out at 10 MHz
        .mode=BMI088_SPI_MODE,                         //SPI mode (CPOL, CPHA)
        .spics_io_num=BMI088_G_PIN_CS,            //CS pin
        .queue_size=1,                          //We want to be able to queue 1 transactions at a time
        .flags = /*SPI_DEVICE_3WIRE | */SPI_DEVICE_HALFDUPLEX,
        .cs_ena_pretrans = 1,
    };
    //Attach the BMI088 to the SPI bus
    ret=spi_bus_add_device(SPI2_HOST, &devcfg_gyr, &spi_gyr);
    ESP_ERROR_CHECK(ret); //在这里返回错误信息

Debug Logs

ESP_ERROR_CHECK failed: esp_err_t 0x101 (ESP_ERR_NO_MEM) at 0x4037ac08
file: "../components/BMI088/UserBmi088.c" line 74
func: mbmi088_user_config_spi_bus
expression: ret

Other items

然后我试图查找产生这个错误的原因:
1、触发"ESP_ERR_NO_MEM"错误的位置为:

err = spi_bus_lock_register_dev(bus_attr->lock, &lock_config, &dev_handle);
if (err != ESP_OK) {
goto nomem;

2、间接原因位置:
static int try_acquire_free_dev(spi_bus_lock_t *lock, bool cs_required)
{
if (cs_required) {
int i;
for (i = 0; i < lock->periph_cs_num; i++) {
intptr_t null = (intptr_t) NULL;
//use 1 to occupy the slot, actual setup comes later
if (atomic_compare_exchange_strong(&lock->dev[i], &null, (intptr_t) 1)) {
break;
}
}
return ((i == lock->periph_cs_num)? -1: i);
} else {
int i;
for (i = DEV_NUM_MAX - 1; i >= 0; i--) {
intptr_t null = (intptr_t) NULL;
//use 1 to occupy the slot, actual setup comes later
if (atomic_compare_exchange_strong(&lock->dev[i], &null, (intptr_t) 1)) {
break;
}
}
return i;
}
}

spi_bus_lock_config_t lock_config = {
.host_id = host_id,
.cs_num = SOC_SPI_PERIPH_CS_NUM(host_id),
};
err = spi_bus_init_lock(&bus_attr->lock, &lock_config);

3、我推测的根本原因位置:
#define SOC_SPI_PERIPH_CS_NUM(i) 3

(这里的宏定义恒为3,与官方文档中说到最大支持6个设备不符合)

##后续的自我尝试

当我推测到这个根本原因位置后,把

#define SOC_SPI_PERIPH_CS_NUM(i) 3

更改成

#if CONFIG_IDF_TARGET_ESP32
#define SOC_SPI_PERIPH_CS_NUM(i)            3
#else
#define SOC_SPI_PERIPH_CS_NUM(i)            ((i == SPI2_HOST)? 6 : 3)
#endif

编译运行之后,虽然可以成功添加4个SPI设备,但是第四个添加的设备读取到的数据全是0xFF,估计就是通信失败。

@espressif-bot espressif-bot added the Status: Opened Issue is new label May 2, 2022
@github-actions github-actions bot changed the title ESP32S3的SPI2_HOST使用spi_master外设时,用"spi_bus_add_device"添加大于三个从机时报错 ESP32S3的SPI2_HOST使用spi_master外设时,用"spi_bus_add_device"添加大于三个从机时报错 (IDFGH-7288) May 2, 2022
@Huckies
Copy link

Huckies commented May 4, 2022

用逻辑分析仪抓下cs线的电平看看?六个设备指的是三根cs线分别在高低电平的时候使能一个设备

@ou2356
Copy link
Author

ou2356 commented May 4, 2022

@Huckies
感谢你的建议,但是很遗憾我没有逻辑分析仪。
但是六个设备真的是指3根片选控制六个设备吗?我也不太确定,可能是自己看漏了官方的文档,如果你方便的话可以发一下截图或者网址吗?我非常需要确认这一点以便后续硬件设计做出合理的更改。
我的推测是ESP32的SPI2是最大支持3个设备的,但是后来出的ESP32S2和S3等都是支持6个的,我只是怀疑是不是官方忘记更改成6个设备了,但感觉也不太可能,一切都只是我的猜测。

@ou2356
Copy link
Author

ou2356 commented May 4, 2022

好消息是我找到一个折中的解决方法:

    gpio_set_pull_mode(BMP390_PIN_CS, GPIO_PULLUP_ONLY);
    gpio_set_direction(BMP390_PIN_CS, GPIO_MODE_OUTPUT);
    gpio_set_level(BMP390_PIN_CS, 1);

    esp_err_t ret;
    spi_device_interface_config_t devcfg={
    	.address_bits = 8,
        .clock_speed_hz=BMP390_SPI_SPEED,            	//Clock out at 10 MHz
        .mode=BMP390_SPI_MODE,                         //SPI mode (CPOL, CPHA)
        .spics_io_num=/*BMP390_PIN_CS*/-1,            //禁用CS pin
        .queue_size=1,                          //We want to be able to queue 1 transactions at a time
        .flags = /*SPI_DEVICE_3WIRE | */SPI_DEVICE_HALFDUPLEX,
        .pre_cb = bmp390_pre_cb, //把CS置低
        .post_cb = bmp390_post_cb, //把CS置高
    };
    //Attach the BMP390 to the SPI bus
    ret=spi_bus_add_device(BMP390_SPI_HOST, &devcfg, &spi);
    ESP_ERROR_CHECK(ret);

就是上面的配置,我把它理解为用软件片选代替硬件片选,就是把CS脚设置为-1(即禁用CS脚),然后把通信前调用的回调函数设置为把CS置低,通信后调用的回调函数设置为把CS置高,这样也能用。

@espressif-bot espressif-bot added Status: Selected for Development Issue is selected for development and removed Status: Opened Issue is new labels Jun 13, 2022
@espressif-bot espressif-bot added Status: In Progress Work is in progress Status: Reviewing Issue is being reviewed and removed Status: Selected for Development Issue is selected for development Status: In Progress Work is in progress labels Aug 25, 2022
@wanckl
Copy link
Contributor

wanckl commented Sep 9, 2022

@ou2356 你好,确实是官方忘记更改CS对应引脚信号的问题,很抱歉给你造成了困扰。目前S2,S3,C2,C3都有这个问题,并将在这个Issue关闭后得到解决,届时将可以使用6个引脚添加6个设备来使用。同时,感谢你的反馈。

@ou2356
Copy link
Author

ou2356 commented Sep 10, 2022

@ou2356 你好,确实是官方忘记更改CS对应引脚信号的问题,很抱歉给你造成了困扰。目前S2,S3,C2,C3都有这个问题,并将在这个Issue关闭后得到解决,届时将可以使用6个引脚添加6个设备来使用。同时,感谢你的反馈。

好的,加油!

@espressif-bot espressif-bot added Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Resolution: Done Issue is done internally and removed Status: Reviewing Issue is being reviewed Resolution: NA Issue resolution is unavailable labels Sep 14, 2022
@wanckl
Copy link
Contributor

wanckl commented Sep 19, 2022

@ou2356 这个问题在master上已经修复,你可以切换到master分支进行测试。如果你使用release版本,则还需要等待内部测试完成发布下一个小版本的时候才能使用。感谢!

antmak pushed a commit to antmak/dev-idf that referenced this issue Sep 28, 2022
update gpio_sig at `spics_out` array in each spi_periph.c of chips later than s2
then `spi_bus_add_device` can correctly distribute gpio_signals for cs_signal

Closes espressif#8876
espressif-bot pushed a commit that referenced this issue Nov 1, 2022
update gpio_sig at `spics_out` array in each spi_periph.c of chips later than s2
then `spi_bus_add_device` can correctly distribute gpio_signals for cs_signal

Closes #8876
espressif-bot pushed a commit that referenced this issue Nov 1, 2022
update gpio_sig at `spics_out` array in each spi_periph.c of chips later than s2
then `spi_bus_add_device` can correctly distribute gpio_signals for cs_signal

Closes #8876
espressif-bot pushed a commit that referenced this issue Nov 3, 2022
update gpio_sig at `spics_out` array in each spi_periph.c of chips later than s2
then `spi_bus_add_device` can correctly distribute gpio_signals for cs_signal

Closes #8876
@jinsonli
Copy link

jinsonli commented Jul 19, 2023

你好, 我也遇到了类似问题。
芯片: ESP32S3
环境: ESP-IDF4.4版本 release/v4.4 拉了官方最新的V4.4
场景:需要使用SPI2外挂 4个 从机设备,能够操作两个设备没问题(CS0/CS1),第三个设备初始化时,通讯全是0XFFFF,底层代码,CS有正常初始化,也有正常添加从机设备。
#8876
所以我怀疑这个问题还没有真正关闭。

@wanckl
Copy link
Contributor

wanckl commented Jul 20, 2023

@jinsonli 可以提供一下你使用的commit id吗,
此外,GPSPI2才可以挂6个设备,GPSPI3只能3个。CS不需要额外手动初始化,通信成功但数据不对,也可能是从机没有发出数据,你可以交换你的几个设备试试,如果你有逻辑分析仪就更好了

@uta-guy
Copy link

uta-guy commented Apr 20, 2024

为了简化操作在ARDUINO 2.3.2内安装ESP32 V2.0.15测试运行SPI2外接6个SPI设备(需要6个CS端口)失败。 只能支持4个。查看ARDUINO下载的2.0.15库找到ESP32S3对应的soc_caps.h仍然显示限制数3. 查看最新版ESP-IDF V5.2.1中同一文件soc_caps.h确认已经修改为6,拷贝过去覆盖2.0.15库同文件,烧录无效。看来还有其他文件需要修改。 已经定制了上百片ESP32S3产品PCB,如短期内不能解决此问题只能全部报废换方案了。因为之前用的方案是METRO M4,主控是很老的SAMD21, 人家支持6个SPI毫无问题。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally
Projects
None yet
Development

No branches or pull requests

6 participants