Skip to main content
Martin.Sergio
Associate III
July 26, 2013
Question

Save ADC Data in Flash

  • July 26, 2013
  • 3 replies
  • 865 views
Posted on July 26, 2013 at 09:54

Hi,

   I'm trying to sample a signal with the ADC and store data in the Micro Internal Flash.

   At the moment I sample the data with the ADC in continous mode and save the Data from ADC1_DR_Address with the DMA in RAM Area, but I need store more data.

   Is it possible that the DMA write it directly in Flash Area?

   I tried to save the data using ''FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);'' function but the time it takes to write the buffer is more time than it takes to fill completely.

For example if my Ram Area is 70Kb i can save 70*1024/2 samples, and i fill that in 1 second (aprox I sample at 35Khz), but if I want to write 35K samples with FLASH_ProgramWord it takes arrond 1.25 seconds if I do so:

    /* Reset flags */

    FLASH_ClearFlag(FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR | FLASH_FLAG_EOP);

    /* Fill the flash buffer */

    addr = (uint32_t)

INIT

_FLASH_ADDR_DATA_REGION;

    FLASH_Unlock();

    nw = TS_FLASH_size >> 2;

    for (i=0 ; i<nw ; i++) {

        status = FLASH_ProgramWord(addr, 2datasamples[i]);

        if (status != FLASH_COMPLETE) {

            FLASH_Lock();

            /* Fail saving data */

           

for(;;);

        }

        addr += 4;

    }

    FLASH_Lock();

so I can't record the Data when the interruption DMA_IT_HT of the DMA, occurrs.

Is possible write in flash faster??

Best Regards,
    This topic has been closed for replies.

    3 replies

    Martin.Sergio
    Associate III
    July 26, 2013
    Posted on July 26, 2013 at 10:11

    Added More Info:

    I'm using STM32F103RG (72Mhz Clock, 1MB Flash and 96Kb Ram) [STM32F10X_XL]

    ADC and DMA Config:

       

    SystemInit();

        /* ADCCLK = PCLK2/8 */

        RCC_ADCCLKConfig(RCC_PCLK2_Div8);

        /* Enable DMA1 clock */

        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

        /* Enable ADC1 and GPIOC clock */

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);

        GPIO_InitTypeDef GPIO_InitStructure;

        /* Configure PC.03 (ADC Channel13) as analog input */

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

        GPIO_Init(GPIOC, &GPIO_InitStructure);

        /* DMA1 channel1 configuration */

        DMA_DeInit(DMA1_Channel1);

        DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;

        DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADCConvertedValue;

        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

        DMA_InitStructure.DMA_BufferSize = MAX_SAMPLES;

        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

        DMA_InitStructure.DMA_Priority = DMA_Priority_High;

        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

        DMA_Init(DMA1_Channel1, &DMA_InitStructure);

        /* Enable DMA1 channel1 */

        DMA_Cmd(DMA1_Channel1, ENABLE);

        /* ADC1 configuration */

        ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

        ADC_InitStructure.ADC_ScanConvMode = ENABLE;

        ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

        ADC_InitStructure.ADC_NbrOfChannel = 1;

        ADC_Init(ADC1, &ADC_InitStructure);

        /* ADC1 regular channel13 configuration */

        ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 1, ADC_SampleTime_239Cycles5);

        /* Enable ADC1 DMA */

        ADC_DMACmd(ADC1, ENABLE);

        /* Enable ADC1 */

        ADC_Cmd(ADC1, ENABLE);

        /* Enable ADC1 reset calibration register */

        ADC_ResetCalibration(ADC1);

        /* Check the end of ADC1 reset calibration register */

        while(ADC_GetResetCalibrationStatus(ADC1));

        /* Start ADC1 calibration */

        ADC_StartCalibration(ADC1);

        /* Check the end of ADC1 calibration */

        while(ADC_GetCalibrationStatus(ADC1));

    SYSCLK/AHB Prescaler/APB2 Prescaler/ADC Prescaler/ADC_SampleTime

    72Mhz/1/1/8/239=37Khz

    The Signal to Sample is a 10Khz signal --> ADC need Sample at 20Khz.

    Best Regards,

    Tesla DeLorean
    Guru
    July 26, 2013
    Posted on July 26, 2013 at 12:36

    No, DMA not usable, or at least not practical.

    Flash is SLOW.

    Provide VPP to the device (F2/F4).

    Suggest you use SDIO for streamed data.
    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    Martin.Sergio
    Associate III
    July 26, 2013
    Posted on July 26, 2013 at 13:15

    Thank you very much

    I will try with a SPI External Flash