0

I am working on a project in which I have to store the datas of an ADC Stream on a µSD card. However even if I use a 16 bits buffer, I lose data from the ADC stream. My ADC is used with DMA and I use FATFS (WITHOUT DMA) and the SDMMC1 peripheral to fill a .bin file with the datas.

Do you have an idea to avoid this loss ?

Here is my project : https://github.com/mathieuchene/STM32H743ZI

I use a nucleo-h743zi2 Board, CubeIDE, and CubeMx in their last version.

EDIT 1

I tried to implement Colin's solution, it's better but I have a strange things in the middle of my acquisition. However when I increase the maximal count value or try to debug, the HardFault_Handler appears. I modified main.c file by creating 2 blocks (uint16_t blockX[BUFFERLENGTH/2]) and 2 flags for when adcBuffer is half filled or completely filled. I also changed the while(1) part in main function like this

    if (flagHlfCplt){
          //flagCplt=0;
          res = f_write(&SDFile, block1, strlen((char*)block1), (void *)&byteswritten);
          memcpy(block2, adcBuffer, BUFFERLENGTH/2);
          flagHlfCplt = 0;
          count++;
      }
      if (flagCplt){
          //flagHlfCplt=0;
          res = f_write(&SDFile, block2, strlen((char*)block2), (void *)&byteswritten);
          memcpy(block1, adcBuffer[(BUFFERLENGTH/2)-1], BUFFERLENGTH/2);
          flagCplt = 0;
          count++;
          }

      if (count == 10){
          f_close(&SDFile);
          HAL_ADC_Stop_DMA(&hadc1);
          while(1){
              HAL_GPIO_TogglePin(LD1_GPIO_Port, LD1_Pin);
              HAL_Delay(1000);
          }
      }
  }

EDIT 2

I modified my program. I set block 1 and block 2 with the length of BUFFERLENGTH and I added a pointer (*idx) to change the buffer which is filled. I don't have HardFault_Handler anymore but I still loose some datas from my adc's stream. Here are the modification I made:

// my pointer and buffers
uint16_t  block1[BUFFERLENGTH], block2[BUFFERLENGTH], *idx;
// init of pointer and adc start
idx=block1;
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)idx, BUFFERLENGTH);
// while(1) part
while (1)
  {
      if (flagCplt){
        if (flagToChangeBuffer) {
            idx=block1;
            res = f_write(&SDFile, block2, strlen((char*)block2), (void *)&byteswritten);
            flagCplt = 0;
            flagToChangeBuffer=0;
            count++;
        }
        else {
            idx=block2;
            res = f_write(&SDFile, block1, strlen((char*)block1), (void *)&byteswritten);
            flagCplt = 0;
            flagToChangeBuffer=1;
            count++;
        }
      }

      if (count == 150){
          f_close(&SDFile);
          HAL_ADC_Stop_DMA(&hadc1);
          while(1){
              HAL_GPIO_TogglePin(LD1_GPIO_Port, LD1_Pin);
              HAL_Delay(1000);
          }
      }
  }

Does someone know how to solve my matter with these loss?

Best Regards

Mathieu

M.Chêne
  • 1
  • 1
  • Buffer the data in RAM on your MCU before writing to the SD, but if the ADC is producing data faster than it can be written to the SD card then you're out of luck. – Colin Aug 04 '20 at 08:14
  • I looked at your project code, at the moment it looks like there's a single buffer, read up on ping pong/double buffering. Have a block of memory to read into, and a block to write from to disk and swap them at sensible times. Have the DMA generate an interrupt when it's filled its buffer and switch, then your foreground code can write that to disk while the ADC fills the new buffer. – Colin Aug 04 '20 at 08:18

0 Answers0