最近购买了 c3 进行测试,发现了一个奇怪的问题!
当 SPI 啟用的 DMA 功能之后, 此时 SPI 会以十分怪异的方式出错!
(1) 不使用 DMA , SPI 以长度 64byte 读写正常
(2) 啟用 DMA , 写入不限制大小, 读取使用 FIFO 一个 byte 读取,读写正常
(3) 啟用 DMA , 读取不限制大小, 写入使用 FIFO 一个 byte 读取,读写正常
(4) 啟用 DMA , 读写不限制大小,此时读取正常,但是写入的资料第一笔正常 (350byte) , 之后所有的资料,出现了错误 了。 但是此时若是有用 SPI FIFO 方式的写入 (一个 byte 写入)这样的操作是正常的!
也就是说当啟用了 DMA , SPI 只能啟用 上面 (2) 或 (3) 的方式才能正常工作, 但是这样就丧失了 DMA 加速的功能了。 运行起来还没有 (1 ) 快
同样的駆动方式,在 S2 上 SPI 啟用 DMA 是正常的。
备注: 我买到的 c3 是版本 2 的, 不知是否是 版本 2 芯片的问题! 因為买不到 版本 3 无法证实!
[已解决」C3 SPI 运行 DMA 功能是否有问题!
[已解决」C3 SPI 运行 DMA 功能是否有问题!
Last edited by axwfae on Fri Oct 15, 2021 7:09 am, edited 1 time in total.
Re: C3 SPI 运行 DMA 功能是否有问题!
参考资料! 使用 IDF v4.3.1
使用 esp-idf\examples\ethernet\iperf 修改测试 芯片使用 dm9051 当 SPI 读写测试芯片
修改 esp-idf\examples\ethernet\iperf \mani\cmd_ethernet.c
关闭 DMA
或 啟用 DMA
修改 esp-idf\components\esp_eth\src\esp_eth_mac_dm9051.c
SPI操作部分的驅動
加入测试的代码运行
(1) 関闭 DMA 以 64byte 分批读写 , PASS
(2) 啟用 DMA , 写以 byte 写入, 读取以 64byte 区块读出, PASS
(3) 啟用 DMA , 读写以 64byte 区块写入读出, FAIL
Code: Select all
--- idf_monitor on com3 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ESP-ROM:esp32c3-20200918
Build:Sep 18 2020
rst:0x1 (POWERON),boot:0xd (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd6100,len:0x17c4
load:0x403ce000,len:0x8dc
load:0x403d0000,len:0x2984
entry 0x403ce000
I (32) boot: ESP-IDF v4.3.1-dirty 2nd stage bootloader
I (32) boot: compile time 16:15:06
I (32) boot: chip revision: 2
I (34) boot.esp32c3: SPI Speed : 80MHz
I (39) boot.esp32c3: SPI Mode : DIO
I (44) boot.esp32c3: SPI Flash Size : 2MB
I (49) boot: Enabling RNG early entropy source...
I (54) boot: Partition Table:
I (58) boot: ## Label Usage Type ST Offset Length
I (65) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (72) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (80) boot: 2 factory factory app 00 00 00010000 00080000
I (87) boot: 3 storage Unknown data 01 81 00090000 00020000
I (95) boot: End of partition table
I (99) esp_image: segment 0: paddr=00010020 vaddr=3c060020 size=13fc4h ( 81860) map
I (120) esp_image: segment 1: paddr=00023fec vaddr=3fc8e800 size=01ce8h ( 7400) load
I (121) esp_image: segment 2: paddr=00025cdc vaddr=40380000 size=0a33ch ( 41788) load
I (133) esp_image: segment 3: paddr=00030020 vaddr=42000020 size=572f0h (357104) map
I (187) esp_image: segment 4: paddr=00087318 vaddr=4038a33c size=042ech ( 17132) load
I (191) esp_image: segment 5: paddr=0008b60c vaddr=50000000 size=00010h ( 16) load
I (198) boot: Loaded app from partition at offset 0x10000
I (199) boot: Disabling RNG early entropy source...
I (216) cpu_start: Pro cpu up.
I (228) cpu_start: Pro cpu start user code
I (228) cpu_start: cpu freq: 160000000
I (228) cpu_start: Application information:
I (231) cpu_start: Project name: ethernet_iperf
I (237) cpu_start: App version: 1
I (241) cpu_start: Compile time: Oct 6 2021 16:11:07
I (247) cpu_start: ELF file SHA256: 2658ee3667091e2d...
I (253) cpu_start: ESP-IDF: v4.3.1-dirty
I (259) heap_init: Initializing. RAM available for dynamic allocation:
I (266) heap_init: At 3FC92550 len 0002DAB0 (182 KiB): DRAM
I (272) heap_init: At 3FCC0000 len 0001F260 (124 KiB): STACK/DRAM
I (279) heap_init: At 50000010 len 00001FF0 (7 KiB): RTCRAM
I (285) spi_flash: detected chip: generic
I (290) spi_flash: flash io: dio
I (294) sleep: Configure to isolate all GPIO pins in sleep state
I (301) sleep: Enable automatic switching of GPIO sleep configuration
I (308) cpu_start: Starting scheduler.
W (313) vfs_fat_spiflash: f_mount failed (13)
I (313) vfs_fat_spiflash: Formatting FATFS partition, allocation unit size=4096
E (323) vfs_fat_spiflash: f_mkfs failed (14)
E (323) eth_example: Failed to mount FATFS (ESP_FAIL)
Type 'help' to get the list of commands.
Use UP/DOWN arrows to navigate through command history.
Press TAB when typing command name to auto-complete.
Your terminal application does not support escape sequences.
Line editing and history features are disabled.
On Windows, try using Putty instead.
spi rw test 100byte 1 ==>
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
60 61 62 63
spi rw test 100byte 2 ==>
02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21
22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31
32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41
42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51
52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61
62 63 64 65
修改 esp-idf\examples\ethernet\iperf \mani\cmd_ethernet.c
关闭 DMA
Code: Select all
ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, 0));
Code: Select all
ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, 3));
SPI操作部分的驅動
Code: Select all
/**
* @brief write value to dm9051 internal register
*/
static esp_err_t dm9051_register_write(emac_dm9051_t *emac, uint8_t reg_addr, uint8_t value)
{
esp_err_t ret = ESP_OK;
spi_transaction_t trans = {
.cmd = DM9051_SPI_WR,
.addr = reg_addr,
.length = 8,
.flags = SPI_TRANS_USE_TXDATA
};
trans.tx_data[0] = value;
if (dm9051_lock(emac)) {
if (spi_device_polling_transmit(emac->spi_hdl, &trans) != ESP_OK) {
ESP_LOGE(TAG, "%s(%d): spi transmit failed", __FUNCTION__, __LINE__);
ret = ESP_FAIL;
}
dm9051_unlock(emac);
} else {
ret = ESP_ERR_TIMEOUT;
}
return ret;
}
/**
* @brief write buffer to dm9051 internal memory
*/
static esp_err_t dm9051_memory_write(emac_dm9051_t *emac, uint8_t *buffer, uint32_t len)
{
esp_err_t ret = ESP_OK;
spi_transaction_t trans = {
.cmd = DM9051_SPI_WR,
.addr = DM9051_MWCMD,
.length = len * 8,
.tx_buffer = buffer
};
if (dm9051_lock(emac)) {
if (spi_device_polling_transmit(emac->spi_hdl, &trans) != ESP_OK) {
ESP_LOGE(TAG, "%s(%d): spi transmit failed", __FUNCTION__, __LINE__);
ret = ESP_FAIL;
}
dm9051_unlock(emac);
} else {
ret = ESP_ERR_TIMEOUT;
}
return ret;
}
/**
* @brief read buffer from dm9051 internal memory
*/
static esp_err_t dm9051_memory_read(emac_dm9051_t *emac, uint8_t *buffer, uint32_t len)
{
esp_err_t ret = ESP_OK;
spi_transaction_t trans = {
.cmd = DM9051_SPI_RD,
.addr = DM9051_MRCMD,
.length = len * 8,
.rx_buffer = buffer
};
if (dm9051_lock(emac)) {
if (spi_device_polling_transmit(emac->spi_hdl, &trans) != ESP_OK) {
ESP_LOGE(TAG, "%s(%d): spi transmit failed", __FUNCTION__, __LINE__);
ret = ESP_FAIL;
}
dm9051_unlock(emac);
} else {
ret = ESP_ERR_TIMEOUT;
}
return ret;
}
#define SPI_NO_DMA_LEN 64
/**
* @brief write buffer to dm9051 internal memory in no dma mode
*/
static esp_err_t dm9051_block_write(emac_dm9051_t *emac, uint8_t *buffer, uint32_t len)
{
esp_err_t ret = ESP_OK;
uint32_t wlTx_cnt = 0;
for(wlTx_cnt = 0; wlTx_cnt < len; wlTx_cnt+= SPI_NO_DMA_LEN)
{
if(ESP_OK != dm9051_memory_write(emac,buffer+wlTx_cnt, ((len - wlTx_cnt) > SPI_NO_DMA_LEN) ? SPI_NO_DMA_LEN : (len - wlTx_cnt) ))
{
return ESP_FAIL;
}
}
return ret;
}
static esp_err_t dm9051_one_write(emac_dm9051_t *emac, uint8_t *buffer, uint32_t len)
{
esp_err_t ret = ESP_OK;
uint32_t wlTx_cnt = 0;
for(wlTx_cnt = 0; wlTx_cnt < len; wlTx_cnt++)
{
if(ESP_OK != dm9051_register_write(emac, DM9051_MWCMD , buffer[wlTx_cnt]))
{
return ESP_FAIL;
}
}
return ret;
}
/**
* @brief read buffer from dm9051 internal memory in no dma mode
*/
static esp_err_t dm9051_block_read(emac_dm9051_t *emac, uint8_t *buffer, uint32_t len)
{
esp_err_t ret = ESP_OK;
uint32_t wlRx_cnt = 0;
for(wlRx_cnt = 0; wlRx_cnt < len; wlRx_cnt+=SPI_NO_DMA_LEN)
{
if(ESP_OK != dm9051_memory_read(emac,buffer+wlRx_cnt, ((len - wlRx_cnt) > SPI_NO_DMA_LEN) ? SPI_NO_DMA_LEN : (len - wlRx_cnt) ))
{
return ESP_FAIL;
}
}
return ret;
}
Code: Select all
static esp_err_t spi_rw_test(emac_dm9051_t *emac)
{
esp_err_t ret = ESP_OK;
uint8_t tx_value[100];
uint8_t rx_data[100];
uint8_t nCnt;
for(nCnt = 0; nCnt <100; nCnt++)
{
tx_value[nCnt] = nCnt;
rx_data[nCnt] = 0;
}
// MAC_CHECK(dm9051_block_write(emac, tx_value, 100) == ESP_OK, "write memory failed", err, ESP_FAIL);
MAC_CHECK(dm9051_one_write(emac, tx_value, 100) == ESP_OK, "write memory failed", err, ESP_FAIL);
MAC_CHECK(dm9051_block_read(emac, rx_data, 100) == ESP_OK, "read rx data failed", err, ESP_FAIL);
printf("\n spi rw test 100byte 1 ==>");
for(nCnt = 0; nCnt <100; nCnt++)
{
if(0 == (nCnt % 16)) printf("\n");
printf(" %02x ", rx_data[nCnt]);
rx_data[nCnt] = 0;
tx_value[nCnt] = nCnt + 2;
}
// MAC_CHECK(dm9051_block_write(emac, tx_value, 100) == ESP_OK, "write memory failed", err, ESP_FAIL);
MAC_CHECK(dm9051_one_write(emac, tx_value, 100) == ESP_OK, "write memory failed", err, ESP_FAIL);
MAC_CHECK(dm9051_block_read(emac, rx_data, 100) == ESP_OK, "read rx data failed", err, ESP_FAIL);
printf("\n spi rw test 100byte 2 ==>");
for(nCnt = 0; nCnt <100; nCnt++)
{
if(0 == (nCnt % 16)) printf("\n");
printf(" %02x ", rx_data[nCnt]);
// rx_data[nCnt] = 0;
// tx_value[nCnt] = nCnt + 2;
}
err:
return ret;
}
(1) 関闭 DMA 以 64byte 分批读写 , PASS
Code: Select all
spi rw test 100byte 1 ==>
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
60 61 62 63
spi rw test 100byte 2 ==>
02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21
22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31
32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41
42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51
52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61
62 63 64 65
Code: Select all
spi rw test 100byte 1 ==>
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
60 61 62 63
spi rw test 100byte 2 ==>
02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21
22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31
32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41
42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51
52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61
62 63 64 65
Code: Select all
spi rw test 100byte 1 ==>
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
60 61 62 63
spi rw test 100byte 2 ==>
02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42
Last edited by axwfae on Fri Oct 15, 2021 1:39 am, edited 1 time in total.
Re: C3 SPI 运行 DMA 功能是否有问题!
Hi, 从观察到的情况看,似乎通过 DMA 读取 64bytes 数据出错时,只正确读到了第一个字节,后面的数据是重复的。从你的示例看是 SPI 与 网卡进行通信,你能否试一下两个 C3 进行通信,看看是否有问题,这样能确定问题是 SPI 驱动的问题还是网卡这边驱动的问题
Re: C3 SPI 运行 DMA 功能是否有问题!
我手上只有一片 C3 ,此段代码是放在 dm9051 的 init 段之前,也就是把 dm9051 当做一个 ram 读写使用!
同样的代码在 S2 上运行是正常的,不管 DMA 长度為多少! (也使用 64byte 区块读写测试过)
我用 64byte 是因為 c3 非使用 dma 模式时,只能使用 64byte 最大长度来读写,為了避免环境不同,导致误判。所以我改成 2 种皆是使用 64byte 区块方式来读写!
而且就像我之前所述! 把 读改成 byte 读取, 写改成不限长度 dma , 运行也是正常的! 所以我才会认為是否 c3 的 spi 是否 dma 操作有啥问题!
或者是 c3 ver2 这个版本有问题!
Re: C3 SPI 运行 DMA 功能是否有问题!
十分感谢你的回讯!
刚刚已解决问题了,问题是 SDK V4.3.1 的问题! 出错点不知在何处! 重新下载了 master 重新测试过,就一切正常了! 测试速度也由 10Mbps -> 15Mbps 以上了!
Code: Select all
mode=tcp-client sip=192.168.123.167:5001, dip=192.168.123.150:5001, interval=3, time=30
I (12646) iperf: Successfully connected
Interval Bandwidth
0- 3 sec 14.77 Mbits/sec
3- 6 sec 15.38 Mbits/sec
6- 9 sec 15.20 Mbits/sec
9- 12 sec 15.42 Mbits/sec
12- 15 sec 15.34 Mbits/sec
15- 18 sec 15.34 Mbits/sec
18- 21 sec 15.38 Mbits/sec
21- 24 sec 15.34 Mbits/sec
24- 27 sec 15.34 Mbits/sec
27- 30 sec 15.38 Mbits/sec
0- 30 sec 15.29 Mbits/sec
I (42656) iperf: TCP Socket client is closed.
再次感谢你!
Who is online
Users browsing this forum: No registered users and 21 guests