ā2022-12-11 05:20 AM
The stm32wb55 writes data to the sd card in real time through FATFS, and the function f_write() will take tens of ms. I want to use two buffers, one buffer to store data, and one buffer to write data to and from the sd card (can this avoid the delay of f_write?). How should I write the program?
ā2022-12-11 06:55 AM
>writes data to the sd card in real time
no.
access SDcard is minimum 1ms + data transfer time , on read. on write maybe 100ms delay...
+ data transfer time depends on setting port speed/1/4bit mode + real card speed + data size
ā2022-12-11 07:05 AM
Thank you for your help, if I collect data continuously (1mSPS), there must be missing data. That is to say, FATFS cannot store data in real time.
ā2022-12-11 07:15 AM
right, at 1 MSPS (i think you want Mega - not milli ?? ) and 100ms delay on write, you need buffering > 100 KB (if 8b sampels, if 16 bit -> 200KB minimum !
and to get "real time" , = continuos data stream , need 2 buffers (circular , maybe DMA mode )
and high quality sdcard, cheap may do 200ms delay sometimes š
ā2022-12-11 07:25 AM
Thanks again. It's "k", sorry I made a typo. Originally, I wanted two buffers, one for storing data and one for writing to the SD card, simultaneously. I found out that it's not possible to do concurrently because stm32 is single threaded...
ā2022-12-11 08:05 AM
single threaded is no problem, you have DMA with about 100 channels, so fixed transfers are done by another "cpu", the dma.
and 1ksmps --- no problem . š (1000x slower than before..)
so data coming from ? adc ? anyway, set up circular dma , maybe 2x16KB , then on callback (enable callbacks for ..adc.. dma in hal /Cube ) half or full -> write 16K to sdcard, (while dma writing to other half buffer) and on next callback write next16K to sdcard ;
no gap, no stress, and good time for sdcard to write (1ksmps * 16K -> > 8 sec buffer )
ā2022-12-12 03:15 AM
Thanks againš . The data comes from ads1299. I use the spi driver (spi mode, no dma) of adafruit shield in the example of stm32wb55. After I add dma, it does not work (spi is ok). It should be a problem with my dma configuration. Is there any example that can make it Shall I take a look?
dma configuration
static void SPIx_Init(void)
{
if(HAL_SPI_GetState(&hnucleo_Spi) == HAL_SPI_STATE_RESET)
{
/* SPI Config */
hnucleo_Spi.Instance = NUCLEO_SPIx;
/* SPI baudrate is set to 8 MHz maximum (PCLK2/SPI_BaudRatePrescaler = 32/4 = 8 MHz)
to verify these constraints:
- ST7735 LCD SPI interface max baudrate is 15MHz for write and 6.66MHz for read
Since the provided driver doesn't use read capability from LCD, only constraint
on write baudrate is considered.
- SD card SPI interface max baudrate is 25MHz for write/read
- PCLK2 max frequency is 32 MHz
*/
hnucleo_Spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hnucleo_Spi.Init.Direction = SPI_DIRECTION_2LINES;
hnucleo_Spi.Init.CLKPhase = SPI_PHASE_2EDGE;
hnucleo_Spi.Init.CLKPolarity = SPI_POLARITY_HIGH;
hnucleo_Spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hnucleo_Spi.Init.CRCPolynomial = 7;
hnucleo_Spi.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hnucleo_Spi.Init.DataSize = SPI_DATASIZE_8BIT;
hnucleo_Spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
hnucleo_Spi.Init.NSS = SPI_NSS_SOFT;
hnucleo_Spi.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
hnucleo_Spi.Init.TIMode = SPI_TIMODE_DISABLE;
hnucleo_Spi.Init.Mode = SPI_MODE_MASTER;
SPIx_MspInit();
HAL_SPI_Init(&hnucleo_Spi);
hdma_spi1_tx.Instance = DMA1_Channel1;
hdma_spi1_tx.Init.Request = DMA_REQUEST_SPI1_TX;
hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_tx.Init.Mode = DMA_CIRCULAR;
hdma_spi1_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
if (HAL_DMA_Init(&hdma_spi1_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(&hnucleo_Spi,hdmatx,hdma_spi1_tx);
/* SPI1_RX Init */
hdma_spi1_rx.Instance = DMA1_Channel2;
hdma_spi1_rx.Init.Request = DMA_REQUEST_SPI1_RX;
hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_rx.Init.Mode = DMA_CIRCULAR;
hdma_spi1_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
if (HAL_DMA_Init(&hdma_spi1_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(&hnucleo_Spi,hdmarx,hdma_spi1_rx);
}
}
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMAMUX1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
/* DMA1_Channel2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
/* DMAMUX1_OVR_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMAMUX1_OVR_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMAMUX1_OVR_IRQn);
}
āinterrupt configuration
void DMA1_Channel1_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
/* USER CODE END DMA1_Channel1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_spi1_tx);
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
/* USER CODE END DMA1_Channel1_IRQn 1 */
}
/**
* @brief This function handles DMA1 channel2 global interrupt.
*/
void DMA1_Channel2_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel2_IRQn 0 */
/* USER CODE END DMA1_Channel2_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_spi1_rx);
/* USER CODE BEGIN DMA1_Channel2_IRQn 1 */
/* USER CODE END DMA1_Channel2_IRQn 1 */
}
write data function (about fatfs driver)
ā2022-12-12 03:42 AM
Ive had this issues with FATFS also, and its non deterministic long active waits between SPI communications.
It would be good if you come back once you get it working.
ā2022-12-12 12:16 PM
in spix_write : data is not set ! should be "1" , not pointer. right ?
ā2022-12-12 06:22 PM
Thanks again. I just use SPIx_ReadWriteData() in my sd driver.š