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