I play with WSPI and I noticed weird issue. If I call twice wspiReceive(), then NDRT register for DMA is not cleared.
Simple code for test:
Code: Select all
#include "ch.h"
#include "hal.h"
int main(void) {
halInit();
chSysInit();
wspiStart(&WSPID1, &config);
/* NCSS */
palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(10) | PAL_STM32_OSPEED_HIGHEST);
/* SCK */
palSetPadMode(GPIOF, 10, PAL_MODE_ALTERNATE(9) | PAL_STM32_OSPEED_HIGHEST);
/* IO0 */
palSetPadMode(GPIOF, 8, PAL_MODE_ALTERNATE(10) | PAL_STM32_OSPEED_HIGHEST);
/* IO1 */
palSetPadMode(GPIOF, 9, PAL_MODE_ALTERNATE(10) | PAL_STM32_OSPEED_HIGHEST);
wspi_command_t mode;
static uint8_t buffer1[512];
static uint8_t buffer2[512];
static uint8_t buffer3[512];
mode.cmd = 0x9f;
mode.cfg = (WSPI_CFG_CMD_MODE_ONE_LINE | \
WSPI_CFG_ADDR_MODE_NONE | \
WSPI_CFG_ALT_MODE_NONE | \
WSPI_CFG_DATA_MODE_ONE_LINE | \
WSPI_CFG_CMD_SIZE_8 | \
WSPI_CFG_ADDR_SIZE_24);
mode.addr = 0U;
mode.alt = 0U;
mode.dummy = 0U;
wspiReceive(&WSPID1, &mode, 3, buffer1);
//ends in infinity while wspi_lld_serve_interrupt "while (dmaStreamGetTransactionSize(wspip->dma) > 0U)"
wspiReceive(&WSPID1, &mode, 3, buffer2);
wspiReceive(&WSPID1, &mode, 3, buffer3);
while (true) {
chThdSleepMilliseconds(1000);
}
Second calling of " wspiReceive(&WSPID1, &mode, 3, buffer2);" ends in infinity "while" because NDTR is not cleared, I checked communication in QSPI pin and all what should be send, were send.
Infinity while:
Code: Select all
static void wspi_lld_serve_interrupt(WSPIDriver *wspip) {
/* Portable WSPI ISR code defined in the high level driver, note, it is
a macro.*/
_wspi_isr_code(wspip);
/* Stop everything, we need to give DMA enough time to complete the ongoing
operation. Race condition hidden here.*/
while (dmaStreamGetTransactionSize(wspip->dma) > 0U) <-------------------------
;
/* Handling of errata: Extra data written in the FIFO at the end of a
read transfer.*/
if (wspip->state == WSPI_RECEIVE) {
while ((wspip->qspi->SR & QUADSPI_SR_BUSY) != 0U) {
(void) wspip->qspi->DR;
}
}
}
Does not metter whether memory is connected or not, in both case same behavior. If memory is connected then firts calling "wspiReceive" fills buffer1 with propper data, so communication with memory works, at least for first "wspiReceive" calling.
My mcuconf.h
https://pastebin.com/GXneeyy7
/*
* WSPI driver system settings.
*/
#define STM32_WSPI_USE_QUADSPI1 TRUE
#define STM32_WSPI_QUADSPI1_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) // stream (2, 7) = the same issue
#define STM32_WSPI_QUADSPI1_PRESCALER_VALUE 255
* Latest CHibiOs from github
* STM32F767Zi nucleo 144