I am using uDMA (ping pong mode) to save ADC (at 1 MSP.... I hope so) data in two buffers, while one buffers is getting filled, i operate the data from the another, in order to get a real time application without loosing information , the problem is that the destination buffers change a lot and when I am operating the values from one of them their values get changed and I do not finish to operate all the buffer. In the code as an operation I use a loop to save the data from the the destination buffer in another buffers (salida1 and salida2), they do not get filled completely.
At the end of the code I finish the program after the variable (flag1) reach the value of 2, so, I am just going to save 2048 ADC values in the buffers (salida1 and salida2)
#include <stdbool.h> #include <stdint.h> #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_adc.h" #include "inc/hw_types.h" #include "inc/hw_udma.h" #include "inc/hw_emac.h" #include "driverlib/debug.h" #include "driverlib/gpio.h" #include "driverlib/interrupt.h" #include "driverlib/pin_map.h" #include "driverlib/rom.h" #include "driverlib/sysctl.h" #include "driverlib/uart.h" #include "driverlib/adc.h" #include "driverlib/udma.h" #include "driverlib/emac.h" #pragma DATA_ALIGN(pui8ControlTable, 1024) uint8_t pui8ControlTable[1024]; #define MEM_BUFFER_SIZE 1024 static uint32_t g_ui8RxBufA[MEM_BUFFER_SIZE]; static uint32_t g_ui8RxBufB[MEM_BUFFER_SIZE]; volatile uint32_t salida1[MEM_BUFFER_SIZE]; volatile uint32_t salida2[MEM_BUFFER_SIZE]; int bug=29; uint32_t sysclock; uint32_t TX_BUFFER; volatile uint32_t count = 0; volatile uint32_t flag = 0; volatile uint32_t flag1 = 0; volatile int m,k,n; //***************************************************************************** // //! \addtogroup adc_examples_list //! <h1>Single Ended ADC (single_ended)</h1> //! //***************************************************************************** void uDMAErrorHandler(void) { uint32_t ui32Status; ui32Status = uDMAErrorStatusGet(); // Check for uDMA error bit if(ui32Status) // If there is a uDMA error { uDMAErrorStatusClear(); //Clear the error status } } //***************************************************************************** void ADCseq0Handler() { uint32_t ui32Status = ADCIntStatus(ADC0_BASE, 0, false); uint32_t ui32Mode; ROM_ADCIntClear(ADC0_BASE, 0); //se puede eliminar ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS0); ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT); if(ui32Mode == UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO0), g_ui8RxBufA, MEM_BUFFER_SIZE); } ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT); if(ui32Mode == UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO0), g_ui8RxBufB, MEM_BUFFER_SIZE); } uDMAChannelEnable(UDMA_CHANNEL_ADC0); } //***************************************************************************** void InitConsole(void) /*Configuracion de periferico UART*/ { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // Habilitacion de periferico GPIOA GPIOPinConfigure(GPIO_PA0_U0RX); // Configurar pin PA0 para recepción GPIOPinConfigure(GPIO_PA1_U0TX); // Configurar pin PA0 para transmision SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); // Habilita periferico UART0 UARTClockSourceSet(UART0_BASE, UART_CLOCK_SYSTEM); // Fuente de Clock para uart sacada del clock del sistema 120MHz GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); // PA0 y PA1 tipo UART // UARTStdioConfig(0, 115200, 120000000); UARTConfigSetExpClk(UART0_BASE ,sysclock //Fuente de señal de Configurar pin PA0 para recepciónConfigurar pin PA0 para recepciónclock ,115200 //Baud rate ,(UART_CONFIG_WLEN_8 //Longitud de trama 8 bits |UART_CONFIG_STOP_ONE //Un bit de stop |UART_CONFIG_PAR_NONE)); //No hay bit de paridad } //***************************************************************************** void ADCconfigure(uint32_t sysclock) { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); //Habilita puerto E SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3|GPIO_PIN_2|GPIO_PIN_1); //PE3 PE2 PE1 tipo ADC SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_ADC0); ADCClockConfigSet(ADC0_BASE,ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL, 1); //Clock source (Precision Internal Clock) // ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 30); ADCSequenceConfigure(ADC0_BASE, 0 /*SS0*/, ADC_TRIGGER_ALWAYS, 3 /*priority*/); // SS0-SS3 priorities must always be different ADCSequenceStepConfigure(ADC0_BASE, 0 /*SS0*/, 0, ADC_CTL_CH0); // ADC_CTL_TS = read temp sensor ADCSequenceStepConfigure(ADC0_BASE, 0 /*SS0*/, 1, ADC_CTL_CH0); ADCSequenceStepConfigure(ADC0_BASE, 0 /*SS0*/, 2, ADC_CTL_CH0); ADCSequenceStepConfigure(ADC0_BASE, 0 /*SS0*/, 3, ADC_CTL_CH0); ADCSequenceStepConfigure(ADC0_BASE, 0 /*SS0*/, 4, ADC_CTL_CH0); ADCSequenceStepConfigure(ADC0_BASE, 0 /*SS0*/, 5, ADC_CTL_CH0); ADCSequenceStepConfigure(ADC0_BASE, 0 /*SS0*/, 6, ADC_CTL_CH0); ADCSequenceStepConfigure(ADC0_BASE, 0 /*SS0*/, 7, ADC_CTL_CH0 | ADC_CTL_END | ADC_CTL_IE); // ADC_CTL_IE fires every 8 samples ADCSequenceEnable(ADC0_BASE, 0); ADCSequenceDMAEnable(ADC0_BASE, 0); uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_ARB_256); uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_ARB_256); uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO0), g_ui8RxBufA, MEM_BUFFER_SIZE); uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO0), g_ui8RxBufB, MEM_BUFFER_SIZE); uDMAChannelEnable(UDMA_CHANNEL_ADC0); ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS0); IntEnable(INT_ADC0SS0); } int main(void) { sysclock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); InitConsole(); for(k=0;k<=bug-1;k++) { UARTCharPut(UART0_BASE,0x69); } SysCtlDelay(sysclock / 10); // Delay for a bit. ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION); // Enable the GPIO port that is used for the on-board LED. ROM_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0); // Enable the GPIO pins for the LED (PN0). SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA); IntMasterEnable(); IntEnable(INT_UDMAERR); uDMAEnable(); uDMAControlBaseSet(pui8ControlTable); ADCconfigure(sysclock); while(1) { if(flag == 0) { for(n=0;n<MEM_BUFFER_SIZE;n++) { salida1[n] = (int16_t)(g_ui8RxBufA[n]); } flag = 1; flag1++; } if(flag == 1) { for(n=0;n<MEM_BUFFER_SIZE;n++) { salida2[n] = (int16_t)(g_ui8RxBufB[n]); } flag = 0; flag1++; } if (flag1 == 2) { while(1){} } } }
how can I solve the problem in order to operate the values from the ADC(at 1MSPS and more) in a real time aplication.
Thanks in Advance