cancel
Showing results for 
Search instead for 
Did you mean: 

Save ADC Data in Flash

Martin.Sergio
Associate III
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,
3 REPLIES 3
Martin.Sergio
Associate III
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,

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 Venmo
Up vote any posts that you find helpful, it shows what's working..
Martin.Sergio
Associate III
Posted on July 26, 2013 at 13:15

Thank you very much

I will try with a SPI External Flash