Tool/software: TI-RTOS
Hello,
guys I am using Code Composer Studio 8.0 on a Windows 7 machine and was already able to write simple application with the EK-TM4C129EXL in combination with and without TI-RTOS Tivac 2_16_00_08.
I am working on an application where the 2 ADC's should sample the 20 available analog inputs with a sampling rate of 50 kHz for a single analog input. The ADC modules run with 1MHz sampling rate. Each ADC module samples 10 channels with the help of 2 sequencers. The mapping from analog input to sequencer position is as following:
ADC0 | ADC1
Sequencer0: AIN0 |Sequencer0: AIN10
AIN1 | AIN11
AIN2 | AIN12
AIN3 | AIN13
AIN4 | AIN14
AIN5 | AIN15
AIN6 | AIN16
AIN7 | AIN17
Sequencer1: AIN8 |Sequencer1: AIN18
AIN9 | AIN19
The data from the sequencer FIFOs to the SRAM should be done by the uDMA with Ping-Pong transfers. Later the application should be able to sent the data in the Ping buffer via TCP/IP to a PC, while the uDMA is filling the Pong buffer and vice versa. This feature is not yet implemented, but is my motivation to use TI-RTOS. Without TI-RTOS the above described behavior of the ADC and uDMA is perfectly fine for every transfersize I'm choosing. The following code implements the above described behavior without TI-RTOS and is fine:
#include <stdint.h> //Variable definitions for C99 standard #include <stdbool.h> //Boolean definitions for the C99 standard #include "inc/tm4c129encpdt.h" #include "inc/hw_memmap.h" //Macros defining the memory map of Tiva C. #include "inc/hw_types.h" //Defines common types and macros #include "driverlib/sysctl.h" //Includes API functions such as SysCtlClockSet and SysCtlClockGet #include "driverlib/interrupt.h" #include "driverlib/gpio.h" //Includes API functions such as GPIOPinTypeGPIOOutput and GPIOPinWrite #include "driverlib/timer.h" #include "driverlib/adc.h" #include "driverlib/fpu.h" #include "driverlib/udma.h" //constants //TODO: All constant defines written in CAPSLOCK #define ADCFrq 50000 #define FIFO0 8 #define FIFO1 4 #define ResultLength 2048 #define NumberOfSequsForTimingError 1024 #define SamplePosiForTimingTest 200 #define NumberOfAinChannels 20 #define UDMATRANSFERSIZEFIFO0 8 #define UDMATRANSFERSIZEFIFO1 4 //ADCClockingDefinesVJ #define PIOSC16MHZ 0x00000000 #define PLL480MHZTO32MHZ 0x00000001 //DMATransferDefinesVJ #define ADC0SS0VJ 0x00000000 #define ADC0SS1VJ 0x00000001 #define ADC1SS0VJ 0x00000002 #define ADC1SS1VJ 0x00000003 #define DMATRANSFERSIZE_SS0 1024 #define DMATRANSFERSIZE_SS1 (DMATRANSFERSIZE_SS0/8)*2 //Since the DMA control table needs to be aligned to a 1024 address #pragma DATA_ALIGN(pui8ControlTable, 1024) //control structure itself uint8_t pui8ControlTable[1024]; //prototyping void ErrorFunction(void); void TimingErrorEval(void); void VJADCClockingSetting(uint32_t ui32Setting); void DMATransferReEnable(uint32_t NumOfTransfer); void DMASetup(void); uint16_t Adc0_FIFO0_UDMA_A[DMATRANSFERSIZE_SS0]; uint16_t Adc0_FIFO1_UDMA_A[DMATRANSFERSIZE_SS1]; uint16_t Adc1_FIFO0_UDMA_A[DMATRANSFERSIZE_SS0]; uint16_t Adc1_FIFO1_UDMA_A[DMATRANSFERSIZE_SS1]; uint16_t Adc0_FIFO0_UDMA_B[DMATRANSFERSIZE_SS0]; uint16_t Adc0_FIFO1_UDMA_B[DMATRANSFERSIZE_SS1]; uint16_t Adc1_FIFO0_UDMA_B[DMATRANSFERSIZE_SS0]; uint16_t Adc1_FIFO1_UDMA_B[DMATRANSFERSIZE_SS1]; uint16_t ADCTest[DMATRANSFERSIZE_SS0]; uint32_t ADCTestIndex=0; uint32_t i=0; uint32_t TIMER2=0, ADC0SEQUENCER0=0, ADC0SEQUENCER1=0, ADC1SEQUENCER0=0, ADC1SEQUENCER1=0, ui32Mode=0, ADC0Sequencer0SWI=0, ADC0Sequencer1SWI=0, ADC0Sequencer0SWI_A=0, ADC0Sequencer0SWI_B=0,ADC0Sequencer1SWI_A=0,ADC0Sequencer1SWI_B=0, ADC1Sequencer0SWI=0, ADC1Sequencer1SWI=0, ADC1Sequencer0SWI_A=0, ADC1Sequencer0SWI_B=0,ADC1Sequencer1SWI_A=0,ADC1Sequencer1SWI_B=0, DebugPrint=0 ,DmaErrors=0; void DMATransferReEnable(uint32_t NumOfTransfer) { uint32_t ui32Mode; switch (NumOfTransfer) { case ADC0SS0VJ: ui32Mode=uDMAChannelModeGet(UDMA_CHANNEL_ADC0|UDMA_PRI_SELECT); if(ui32Mode==UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_CHANNEL_ADC0|UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 0x40038048, Adc0_FIFO0_UDMA_A, DMATRANSFERSIZE_SS0); for(i=0;i<128;i++) { ADCTest[ADCTestIndex+i]= Adc0_FIFO0_UDMA_A[8*i]; } ADCTestIndex=ADCTestIndex+128; ADC0Sequencer0SWI_A++; } ui32Mode=uDMAChannelModeGet(UDMA_CHANNEL_ADC0|UDMA_ALT_SELECT); if(ui32Mode==UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_CHANNEL_ADC0|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 0x40038048, Adc0_FIFO0_UDMA_B, DMATRANSFERSIZE_SS0); for(i=0;i<128;i++) { ADCTest[ADCTestIndex+i]= Adc0_FIFO0_UDMA_B[8*i]; } ADCTestIndex=ADCTestIndex+128; ADC0Sequencer0SWI_B++; } if(ADCTestIndex>=DMATRANSFERSIZE_SS0) { ADCTestIndex=0; } if(uDMAChannelIsEnabled(UDMA_CHANNEL_ADC0)==0) { uDMAChannelEnable(UDMA_CHANNEL_ADC0); ADC0Sequencer0SWI++; } break; case ADC0SS1VJ: ui32Mode=uDMAChannelModeGet(UDMA_CHANNEL_ADC1|UDMA_PRI_SELECT); if(ui32Mode==UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_CHANNEL_ADC1|UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 0x40038068, Adc0_FIFO1_UDMA_A, DMATRANSFERSIZE_SS1); ADC0Sequencer1SWI_A++; } ui32Mode=uDMAChannelModeGet(UDMA_CHANNEL_ADC1|UDMA_ALT_SELECT); if(ui32Mode==UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_CHANNEL_ADC1|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 0x40038068, Adc0_FIFO1_UDMA_B, DMATRANSFERSIZE_SS1); ADC0Sequencer1SWI_B++; } if(uDMAChannelIsEnabled(UDMA_CHANNEL_ADC1)==0) { uDMAChannelEnable(UDMA_CHANNEL_ADC1); ADC0Sequencer1SWI++; } break; case ADC1SS0VJ: ui32Mode=uDMAChannelModeGet(UDMA_SEC_CHANNEL_ADC10|UDMA_PRI_SELECT); if(ui32Mode==UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC10|UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 0x40039048, Adc1_FIFO0_UDMA_A, DMATRANSFERSIZE_SS0); ADC1Sequencer0SWI_A++; } ui32Mode=uDMAChannelModeGet(UDMA_SEC_CHANNEL_ADC10|UDMA_ALT_SELECT); if(ui32Mode==UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC10|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 0x40039048, Adc1_FIFO0_UDMA_B, DMATRANSFERSIZE_SS0); ADC1Sequencer0SWI_B++; } if(uDMAChannelIsEnabled(UDMA_SEC_CHANNEL_ADC10)==0) { uDMAChannelEnable(UDMA_SEC_CHANNEL_ADC10); ADC1Sequencer0SWI++; } break; case ADC1SS1VJ: ui32Mode=uDMAChannelModeGet(UDMA_SEC_CHANNEL_ADC11|UDMA_PRI_SELECT); if(ui32Mode==UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC11|UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 0x40039068, Adc1_FIFO1_UDMA_A, DMATRANSFERSIZE_SS1); ADC1Sequencer1SWI_A++; } ui32Mode=uDMAChannelModeGet(UDMA_SEC_CHANNEL_ADC11|UDMA_ALT_SELECT); if(ui32Mode==UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC11|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 0x40039068, Adc1_FIFO1_UDMA_B, DMATRANSFERSIZE_SS1); ADC1Sequencer1SWI_B++; } if(uDMAChannelIsEnabled(UDMA_SEC_CHANNEL_ADC11)==0) { uDMAChannelEnable(UDMA_SEC_CHANNEL_ADC11); ADC1Sequencer1SWI++; } break; } } void DMASetup(void) { uint8_t *CheckTable=0xFFFFFFFF; uint8_t *CheckTable1=0xFFFFFFFF; uint8_t *CheckTable2=0xFFFFFFFF; CheckTable = uDMAControlBaseGet(); uDMAEnable(); CheckTable1 = uDMAControlBaseGet(); uDMAControlBaseSet(pui8ControlTable);//set the pointer to the control table array CheckTable2 = uDMAControlBaseGet(); uDMAChannelAssign(UDMA_CH14_ADC0_0);//DMAChannel 14 is used by ADC0 Sequencer0 uDMAChannelAssign(UDMA_CH15_ADC0_1);//DMAChannel 15 is used by ADC0 Sequencer1 uDMAChannelAssign(UDMA_CH24_ADC1_0);//DMAChannel 24 is used by ADC1 Sequencer0 uDMAChannelAssign(UDMA_CH25_ADC1_1);//DMAChannel 25 is used by ADC1 Sequencer1 // disable all channel attributes for channel 14,15,24,25 uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0, UDMA_ATTR_ALL); uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC1, UDMA_ATTR_ALL); uDMAChannelAttributeDisable(UDMA_SEC_CHANNEL_ADC10, UDMA_ATTR_ALL); uDMAChannelAttributeDisable(UDMA_SEC_CHANNEL_ADC11, UDMA_ATTR_ALL); /* enable for channel 14,15,24,25 burst mode->only burst modes will be processed by DMA *set the priority to high for channel 14 and 24, channel 15 and 25 will remain as default priority *the order of execution if multiple channels request a DMA are dependent on the channel number AND the priority setting, the lower the channel number the more important *Priority-List:0=most important,3=least important *-0. Channel 14 *-1. Channel 15 *-2. Channel 24 *-3. Channel 25 */ uDMAChannelAttributeEnable(UDMA_CHANNEL_ADC0, UDMA_ATTR_USEBURST|UDMA_ATTR_HIGH_PRIORITY); uDMAChannelAttributeEnable(UDMA_CHANNEL_ADC1, UDMA_ATTR_USEBURST); uDMAChannelAttributeEnable(UDMA_SEC_CHANNEL_ADC10, UDMA_ATTR_USEBURST|UDMA_ATTR_HIGH_PRIORITY); uDMAChannelAttributeEnable(UDMA_SEC_CHANNEL_ADC11, UDMA_ATTR_USEBURST); /* setup the primary control structure for channel 14,15,24,25 * a transfer item is 16 bit->UDMA_SIZE_16 * the sources are the FIFOs of the ADC sequencers, after a value is read from the FIFO this value is poped->UDMA_SRC_INC_NONE * the destination array is a uint16 array. each cell is 16 bit->UDMA_DST_INC_16 * the FIFOs request a DMA transfer if they are half full, for sequencer0 this is after 4 samples and for sequencer1 this is after 2 samples * the DMA should therefore always rearbitary after one burst if a higher priority channel requests a transfer-> UDMA_ARB_4 for sequencer 0, UDMA_ARB_2 for sequencer 1 */ uDMAChannelControlSet(UDMA_CHANNEL_ADC0|UDMA_PRI_SELECT, UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16|UDMA_ARB_4); uDMAChannelControlSet(UDMA_CHANNEL_ADC1|UDMA_PRI_SELECT, UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16|UDMA_ARB_2); uDMAChannelControlSet(UDMA_SEC_CHANNEL_ADC10|UDMA_PRI_SELECT, UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16|UDMA_ARB_4); uDMAChannelControlSet(UDMA_SEC_CHANNEL_ADC11|UDMA_PRI_SELECT, UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16|UDMA_ARB_2); /* setup the alternative control structure for channel 14,15,24,25 * the same settings as for the primary */ uDMAChannelControlSet(UDMA_CHANNEL_ADC0|UDMA_ALT_SELECT, UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16|UDMA_ARB_4); uDMAChannelControlSet(UDMA_CHANNEL_ADC1|UDMA_ALT_SELECT, UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16|UDMA_ARB_2); uDMAChannelControlSet(UDMA_SEC_CHANNEL_ADC10|UDMA_ALT_SELECT, UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16|UDMA_ARB_4); uDMAChannelControlSet(UDMA_SEC_CHANNEL_ADC11|UDMA_ALT_SELECT, UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16|UDMA_ARB_2); /* set second the primary transfer function active -> | UDMA_PRI_SELECT * Ping-Pong transfer -> UDMA_MODE_PINGPONG * source adresses -> FIFO adresse TODO:remove hard coded adresses * destination adresses -> adress of the first element of the ping buffers * number of items (16 bit) -> 1024 (WHICH IS THE MAXIMUM VALUE!) */ uDMAChannelTransferSet(UDMA_CHANNEL_ADC0|UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 0x40038048, Adc0_FIFO0_UDMA_A, DMATRANSFERSIZE_SS0); uDMAChannelTransferSet(UDMA_CHANNEL_ADC1|UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 0x40038068, Adc0_FIFO1_UDMA_A, DMATRANSFERSIZE_SS1); uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC10|UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 0x40039048, Adc1_FIFO0_UDMA_A, DMATRANSFERSIZE_SS0); uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC11|UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 0x40039068, Adc1_FIFO1_UDMA_A, DMATRANSFERSIZE_SS1); /* set first the alternative transfer function active -> | UDMA_ALT_SELECT * Ping-Pong transfer -> UDMA_MODE_PINGPONG * source adresses -> FIFO adresse TODO:remove hard coded adresses * destination adresses -> adress of the first element of the pong buffers * number of items (16 bit) -> 1024 (WHICH IS THE MAXIMUM VALUE!) */ uDMAChannelTransferSet(UDMA_CHANNEL_ADC0|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 0x40038048, Adc0_FIFO0_UDMA_B, DMATRANSFERSIZE_SS0); uDMAChannelTransferSet(UDMA_CHANNEL_ADC1|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 0x40038068, Adc0_FIFO1_UDMA_B, DMATRANSFERSIZE_SS1); uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC10|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 0x40039048, Adc1_FIFO0_UDMA_B, DMATRANSFERSIZE_SS0); uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC11|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 0x40039068, Adc1_FIFO1_UDMA_B, DMATRANSFERSIZE_SS1); /* activate the channels * first transfer is with the primary control structure */ uDMAChannelEnable(UDMA_CHANNEL_ADC0); uDMAChannelEnable(UDMA_CHANNEL_ADC1); uDMAChannelEnable(UDMA_SEC_CHANNEL_ADC10); uDMAChannelEnable(UDMA_SEC_CHANNEL_ADC11); } int main(void) { uint32_t ui32Period; uint32_t ui32SysClkFreq; ui32SysClkFreq = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); //enable floating point unite for statistic calculations, only for timing error debugg version required FPUEnable(); //configure the fpu to perform lazy stacking of the fp state FPULazyStackingEnable(); // enable Port N for Led0, Led1 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION); // enable Port E for AIN0,1,2,3,8,9 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); // enable Port D for AIN4,5,6,7,12,13 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); // enable Port K for AIN16,17,18,19 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK); // enable Port B for AIN10,11 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); // enable Timer0 which will trigger ADC0 and ADC1 in synchronized fashion SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); // enable ADC0 SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); // enable ADC1 SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1); // enable the DMA, this must be done before the setup routine is called!!!! SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); // set Port E Pin 0 to 5 as analog input for AIN0 to AIN3 and AIN8 and AIN9 GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_4|GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_5); // set Port D Pin 7,6,5,4,3,2,1,0 as analog input for AIN4, AIN5 ,AIN6 ,AIN7 ,AIN12 ,AIN13 ,AIN14 , AIN15 GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_7|GPIO_PIN_6|GPIO_PIN_5|GPIO_PIN_4|GPIO_PIN_3|GPIO_PIN_2|GPIO_PIN_1|GPIO_PIN_0); // set Port K Pin 0,1,2,3 as analog input for AIN16, AIN17, AIN18, AIN19 GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3); // set Port B Pin Pin 4,5 as analog input for AIN12 , AIN13 GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3); // set Port N Pin 0,1 as output to enable LEDs GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0|GPIO_PIN_1); //set the ADC module frq either to 16MHz(1Megasamples/s) by using the PIOSC //or to 32MHz(2Megasamples/s) by using the VCO(@480MHz) and a 15 divider //TODO: DOES NOT WORK WITH 32 MHz!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! VJADCClockingSetting(PIOSC16MHZ); //uDMAChannelTransferSet(UDMA_CHANNEL_ADC0|UDMA_PRI_SELECT, UDMA_MODE_BASIC, 0x40038048, Adc0_FIFO0_UDMA, ResultLength); //uDMAChannelTransferSet(UDMA_CHANNEL_ADC1|UDMA_PRI_SELECT, UDMA_MODE_BASIC, 0x40038068, Adc0_FIFO1_UDMA, ResultLength); //uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC10|UDMA_PRI_SELECT, UDMA_MODE_BASIC, 0x40039048, Adc1_FIFO0_UDMA, ResultLength); //uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC11|UDMA_PRI_SELECT, UDMA_MODE_BASIC, 0x40039068, Adc1_FIFO1_UDMA, ResultLength); DMASetup(); //Configures the 0ths sequencer of ADC0 as triggered by a Timer with highest priority //ADC_adress|Sequencer_number|Trigger_source|Priority needs to be between 0 to 3, 0 highest prio; 3 lowest prio ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_TIMER, 0); ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_TIMER, 1); ADCSequenceConfigure(ADC1_BASE, 0, ADC_TRIGGER_TIMER, 0); ADCSequenceConfigure(ADC1_BASE, 1, ADC_TRIGGER_TIMER, 1); //program sequencer 0 of ADC0 to sample AIN0 to AIN7 ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_CH0); ADCSequenceStepConfigure(ADC0_BASE, 0, 1, ADC_CTL_CH1); ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_CH2); ADCSequenceStepConfigure(ADC0_BASE, 0, 3, ADC_CTL_CH3); ADCSequenceStepConfigure(ADC0_BASE, 0, 4, ADC_CTL_CH4); ADCSequenceStepConfigure(ADC0_BASE, 0, 5, ADC_CTL_CH5); ADCSequenceStepConfigure(ADC0_BASE, 0, 6, ADC_CTL_CH6); ADCSequenceStepConfigure(ADC0_BASE, 0, 7, ADC_CTL_CH7|ADC_CTL_IE|ADC_CTL_END); //program sequencer 1 of ADC0 to sample AIN8 to AIN9 ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH8); ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH9|ADC_CTL_IE|ADC_CTL_END); //program sequencer 0 of ADC1 to sample AIN10 to AIN17 ADCSequenceStepConfigure(ADC1_BASE, 0, 0, ADC_CTL_CH10); ADCSequenceStepConfigure(ADC1_BASE, 0, 1, ADC_CTL_CH11); ADCSequenceStepConfigure(ADC1_BASE, 0, 2, ADC_CTL_CH12); ADCSequenceStepConfigure(ADC1_BASE, 0, 3, ADC_CTL_CH13); ADCSequenceStepConfigure(ADC1_BASE, 0, 4, ADC_CTL_CH14); ADCSequenceStepConfigure(ADC1_BASE, 0, 5, ADC_CTL_CH15); ADCSequenceStepConfigure(ADC1_BASE, 0, 6, ADC_CTL_CH16); ADCSequenceStepConfigure(ADC1_BASE, 0, 7, ADC_CTL_CH17|ADC_CTL_IE|ADC_CTL_END); //program sequencer 1 of ADC1 to sample AIN0 to AIN7 ADCSequenceStepConfigure(ADC1_BASE, 1, 0, ADC_CTL_CH18); ADCSequenceStepConfigure(ADC1_BASE, 1, 1, ADC_CTL_CH19|ADC_CTL_IE|ADC_CTL_END); //enable the adc to generate dma transfer requests //enable ADC0sequencer0 to request a dma transfer ADCSequenceDMAEnable(ADC0_BASE, 0); //enable ADC0sequencer1 to request a dma transfer ADCSequenceDMAEnable(ADC0_BASE, 1); //enable ADC1sequencer0 to request a dma transfer ADCSequenceDMAEnable(ADC1_BASE, 0); //enable ADC1sequencer1 to request a dma transfer ADCSequenceDMAEnable(ADC1_BASE, 1); ADCSequenceEnable(ADC0_BASE, 0);//enable sequencer 0 of ADC0 ADCSequenceEnable(ADC0_BASE, 1);//enable sequencer 1 of ADC0 ADCSequenceEnable(ADC1_BASE, 0);//enable sequencer 0 of ADC1 ADCSequenceEnable(ADC1_BASE, 1);//enable sequencer 0 of ADC1 TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);//configure timer0 as a periodic timer ui32Period = ui32SysClkFreq/ADCFrq;//calculate number of ticks in order that the timer will trigger the adc in the desired frequency TimerLoadSet(TIMER0_BASE, TIMER_A, ui32Period-1);//load the calculated number of ticks into timer0 TimerControlTrigger(TIMER0_BASE, TIMER_A, true);//enables timer0 to trigger the ADCs TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);//enable the specific interrupt in timer0 ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS0);//enable the specific sequencer0 interrupt in ADC0 ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS1);//enable the specific sequencer1 interrupt in ADC0 ADCIntEnableEx(ADC1_BASE, ADC_INT_DMA_SS0);//enable the specific sequencer0 interrupt in ADC1 ADCIntEnableEx(ADC1_BASE, ADC_INT_DMA_SS1);//enable the specific sequencer1 interrupt in ADC1 IntEnable(INT_UDMA); IntEnable(INT_UDMAERR); IntEnable(INT_TIMER0A);//enable the interrupt for timer0 IntEnable(INT_ADC0SS0);//enable the interrupt for sequencer0 of ADC0 IntEnable(INT_ADC0SS1);//enable the interrupt for sequencer1 of ADC0 IntEnable(INT_ADC1SS0);//enable the interrupt for sequencer0 of ADC1 IntEnable(INT_ADC1SS1);//enable the interrupt for sequencer0 of ADC0 IntMasterEnable();//enable global interrupt TimerEnable(TIMER0_BASE, TIMER_A);//start timer0 GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, 0); while(1) { } } void uDMAIntHandler(void) { int vj=0; vj++; } void uDMAErrorHandler(void) { uint32_t ui32Status; ui32Status = uDMAErrorStatusGet(); if(ui32Status) { uDMAErrorStatusClear(); } } void VJADCClockingSetting(uint32_t ui32Setting) { //TODO: DOES NOT WORK WITH 32 MHz!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! switch (ui32Setting) { case PIOSC16MHZ: //The standard settings, nothing at all needs to be done. The ADC modules will run with 1 Megasample/s //Nothing to do here break; case PLL480MHZTO32MHZ: //The 480 MHZ VCO clock is divided by 15 to provide the ADC with 32MHZ which will result in 2 Megasample/s ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL|ADC_CLOCK_RATE_FULL, 8); break; } } void Adc0Sequencer0IntHandle(void) { ADCIntClear(ADC0_BASE,0); ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS0); ADC0SEQUENCER0++; DMATransferReEnable(ADC0SS0VJ); } void Adc0Sequencer1IntHandle(void) { ADCIntClear(ADC0_BASE,1); ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS1); ADC0SEQUENCER1++; DMATransferReEnable(ADC0SS1VJ); } void Adc1Sequencer0IntHandle(void) { ADCIntClear(ADC1_BASE,0); ADCIntClearEx(ADC1_BASE, ADC_INT_DMA_SS0); ADC1SEQUENCER0++; DMATransferReEnable(ADC1SS0VJ); } void Adc1Sequencer1IntHandle(void) { ADCIntClear(ADC1_BASE,1); ADCIntClearEx(ADC1_BASE, ADC_INT_DMA_SS1); ADC1SEQUENCER1++; DMATransferReEnable(ADC1SS1VJ); } void Timer0IntHandler(void) { // Clear the timer interrupt TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT); TIMER2++; } void TimingErrorEval(void) { /*float TimingErrorMean[NumberOfAinChannels]; uint_fast32_t ui32SumOfErrors=0; uint_fast32_t i,ii; float fSumOfErrors=0; for (i=0;i<NumberOfAinChannels;i++) { ui32SumOfErrors =0; fSumOfErrors =0; for (ii=0;ii<ResultLength;ii++) { ui32SumOfErrors=ui32SumOfErrors+*(AdcResultHandler[i]+ii); } fSumOfErrors=(float)ui32SumOfErrors; TimingErrorMean[i]=fSumOfErrors/ResultLength; } fSumOfErrors=0;*/ } //if an error occurred enable the leds and stay in this function void ErrorFunction(void) { GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1|GPIO_PIN_0, 3); IntMasterDisable(); while(1) { } }
The tranfersize for this code is set to 1024 (the maximum number of items for a uDMA transfer).
Now I wanted to to implement this exact application with the help of TI-RTOS. The ISR's should post a SWI where the DMA channels are checked and the required transfer, either Ping or Pong, are set again if they are finished. The HWIs are working as expected and the SWIs as well. Everything works fine till I set the transfersize for the uDMA transfers to 1024, which is no problem without the TI-RTOS. In order for you guys to comprehend the bug/error here is the same application as above but with TI-RTOS support:
/* * Copyright (c) 2015, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * ======== empty_min.c ======== */ /* XDCtools Header files */ #include <xdc/std.h> #include <xdc/runtime/System.h> #include <xdc/cfg/global.h> #include <xdc/runtime/Log.h> /* BIOS Header files */ #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Task.h> #include <ti/sysbios/knl/Swi.h> /* TI-RTOS Header files */ // #include <ti/drivers/EMAC.h> #include <ti/drivers/GPIO.h> // #include <ti/drivers/I2C.h> // #include <ti/drivers/SDSPI.h> // #include <ti/drivers/SPI.h> // #include <ti/drivers/UART.h> // #include <ti/drivers/USBMSCHFatFs.h> // #include <ti/drivers/Watchdog.h> // #include <ti/drivers/WiFi.h> /* Board Header file */ #include "Board.h" /* */ #include <stdint.h> //Variable definitions for C99 standard #include <stdbool.h> //Boolean definitions for the C99 standard #include "inc/tm4c129encpdt.h" #include "inc/hw_memmap.h" //Macros defining the memory map of Tiva C. #include "inc/hw_types.h" //Defines common types and macros #include "driverlib/sysctl.h" //Includes API functions such as SysCtlClockSet and SysCtlClockGet #include "driverlib/interrupt.h" //Defines for interrupt and register assignments #include "driverlib/gpio.h" //Includes API functions such as GPIOPinTypeGPIOOutput and GPIOPinWrite #include "driverlib/udma.h" /* Timer Header File */ #include "driverlib/timer.h" /* ADC Header File */ #include "driverlib/adc.h" /* Defines */ #define VJSYSFRQ 120000000 //CPU Frequency #define VJADCSINGLECHANNELRATE 50000 //Sample Rate of a single microphone channel #define VJNUMOFCHANNELS_SS0 8 //Number of Microphone channels served by AdcXSequencer0 #define VJNUMOFCHANNELS_SS1 2 //Number of Microphone channels served by AdcXSequencer1 #define VJDMATRANSFERSIZE_SS0 1016 //Number of items till a dma channel related to Sequencer 0 will cause an interrupt (AdcXSequencer0 interrupt) //In order that the samples of the 2 channels sampled by Sequencer1 are sent at the same time as the 8 sampled by Sequencer 1 the corresponding dma channel needs only to transfer 1/4th of the items of Sequencer0 #define VJDMATRANSFERSIZE_SS1 (VJDMATRANSFERSIZE_SS0/VJNUMOFCHANNELS_SS0)*VJNUMOFCHANNELS_SS1 //Number of items till a dma channel related to Sequencer 0 will cause an interrupt (AdcXSequencer1 interrupt) #define VJNUMOFSAMPLEPERTRANSFER VJDMATRANSFERSIZE_SS0/VJNUMOFCHANNELS_SS0 //Number of samples of one microphone channel in a single dma transfer /* * Prototypes */ void VJ_initAnalogInputs(void); void VJ_initADC0WithOutDMA(void); void VJ_initADC1WithOutDMA(void); void VJ_initADC0WithDMA(void); void VJ_initADC1WithDMA(void); void VJ_initTimer2ForADC(uint32_t ui32SysClkFreq); void ISR_Timer2(void); void ISR_Adc1Sequencer1(void); void ISR_Adc1Sequencer0(void); void ISR_Adc0Sequencer1(void); void ISR_Adc0Sequencer0(void); void VJ_initDMATransForADC1SS1(void); void VJ_initDMATransForADC1SS0(void); void VJ_initDMATransForADC0SS1(void); void VJ_initDMATransForADC0SS0(void); void SWI_Adc0Sequencer0(void); void SWI_Adc0Sequencer1(void); void SWI_Adc1Sequencer0(void); void SWI_Adc1Sequencer1(void); /* Debug Variable */ uint32_t TIMER2=0, ADC0SEQUENCER0=0, ADC0SEQUENCER1=0, ADC1SEQUENCER0=0, ADC1SEQUENCER1=0, ui32Mode=0, ADC0Sequencer0SWI=0, ADC0Sequencer1SWI=0, ADC0Sequencer0SWI_A=0, ADC0Sequencer0SWI_B=0,ADC0Sequencer1SWI_A=0,ADC0Sequencer1SWI_B=0, ADC1Sequencer0SWI=0, ADC1Sequencer1SWI=0, ADC1Sequencer0SWI_A=0, ADC1Sequencer0SWI_B=0,ADC1Sequencer1SWI_A=0,ADC1Sequencer1SWI_B=0, DebugPrint=0 ,DmaErrors=0; /* DMA Memory */ uint16_t Adc0_FIFO0_UDMA_A[VJDMATRANSFERSIZE_SS0]; uint16_t Adc0_FIFO1_UDMA_A[VJDMATRANSFERSIZE_SS1]; uint16_t Adc1_FIFO0_UDMA_A[VJDMATRANSFERSIZE_SS0]; uint16_t Adc1_FIFO1_UDMA_A[VJDMATRANSFERSIZE_SS1]; uint16_t Adc0_FIFO0_UDMA_B[VJDMATRANSFERSIZE_SS0]; uint16_t Adc0_FIFO1_UDMA_B[VJDMATRANSFERSIZE_SS1]; uint16_t Adc1_FIFO0_UDMA_B[VJDMATRANSFERSIZE_SS0]; uint16_t Adc1_FIFO1_UDMA_B[VJDMATRANSFERSIZE_SS1]; /* VJ_initAnalogInputs: put all 20 required pins to analog pins * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 * Port E: Pin0->AIN0 , Pin1->AIN1 , Pin2->AIN2 , Pin3->AIN3 , Pin4->AIN8 , Pin5->AIN9 * Port D: Pin0->AIN15, Pin1->AIN14 , Pin2->AIN13 , Pin3->AIN12 , Pin4->AIN7 , Pin5->AIN6 , Pin6->AIN5 , Pin7->AIN4 * Port K: Pin0->AIN16, Pin1->AIN17 , Pin2->AIN18 , Pin3->AIN19 * Port B: Pin4->AIN12, Pin5->AIN13 */ void VJ_initAnalogInputs(void) { while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOE)) { } while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOD)) { } while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOK)) { } while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOB)) { } // set Port E Pin 0 to 5 as analog input for AIN0 to AIN3 and AIN8 and AIN9 GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_4|GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_5); // set Port D Pin 7,6,5,4,3,2,1,0 as analog input for AIN4, AIN5 ,AIN6 ,AIN7 ,AIN12 ,AIN13 ,AIN14 , AIN15 GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_7|GPIO_PIN_6|GPIO_PIN_5|GPIO_PIN_4|GPIO_PIN_3|GPIO_PIN_2|GPIO_PIN_1|GPIO_PIN_0); // set Port K Pin 0,1,2,3 as analog input for AIN16, AIN17, AIN18, AIN19 GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3); // set Port B Pin Pin 4,5 as analog input for AIN12 , AIN13 GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3); } void VJ_initADC0WithOutDMA(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0)) { } //Configures the 0ths sequencer of ADC0 as triggered by a Timer with highest priority //ADC_adress|Sequencer_number|Trigger_source|Priority needs to be between 0 to 3, 0 highest prio; 3 lowest prio ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_TIMER, 0); ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_TIMER, 1); //program sequencer 0 of ADC0 to sample AIN0 to AIN7 ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_CH0); ADCSequenceStepConfigure(ADC0_BASE, 0, 1, ADC_CTL_CH1); ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_CH2); ADCSequenceStepConfigure(ADC0_BASE, 0, 3, ADC_CTL_CH3); ADCSequenceStepConfigure(ADC0_BASE, 0, 4, ADC_CTL_CH4); ADCSequenceStepConfigure(ADC0_BASE, 0, 5, ADC_CTL_CH5); ADCSequenceStepConfigure(ADC0_BASE, 0, 6, ADC_CTL_CH6); ADCSequenceStepConfigure(ADC0_BASE, 0, 7, ADC_CTL_CH7|ADC_CTL_IE|ADC_CTL_END); //program sequencer 1 of ADC0 to sample AIN8 to AIN9 ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH8); ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH9|ADC_CTL_IE|ADC_CTL_END); ADCSequenceEnable(ADC0_BASE, 0);//enable sequencer 0 of ADC0 ADCSequenceEnable(ADC0_BASE, 1);//enable sequencer 1 of ADC0 ADCIntEnable(ADC0_BASE, 0); ADCIntEnable(ADC0_BASE, 1); IntEnable(INT_ADC0SS0);//enable the interrupt for sequencer0 of ADC0 IntEnable(INT_ADC0SS1);//enable the interrupt for sequencer1 of ADC0 } void VJ_initADC1WithOutDMA(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_ADC1)) { } ADCSequenceConfigure(ADC1_BASE, 0, ADC_TRIGGER_TIMER, 0); ADCSequenceConfigure(ADC1_BASE, 1, ADC_TRIGGER_TIMER, 1); //program sequencer 0 of ADC1 to sample AIN10 to AIN17 ADCSequenceStepConfigure(ADC1_BASE, 0, 0, ADC_CTL_CH10); ADCSequenceStepConfigure(ADC1_BASE, 0, 1, ADC_CTL_CH11); ADCSequenceStepConfigure(ADC1_BASE, 0, 2, ADC_CTL_CH12); ADCSequenceStepConfigure(ADC1_BASE, 0, 3, ADC_CTL_CH13); ADCSequenceStepConfigure(ADC1_BASE, 0, 4, ADC_CTL_CH14); ADCSequenceStepConfigure(ADC1_BASE, 0, 5, ADC_CTL_CH15); ADCSequenceStepConfigure(ADC1_BASE, 0, 6, ADC_CTL_CH16); ADCSequenceStepConfigure(ADC1_BASE, 0, 7, ADC_CTL_CH17|ADC_CTL_IE|ADC_CTL_END); //program sequencer 1 of ADC1 to sample AIN0 to AIN7 ADCSequenceStepConfigure(ADC1_BASE, 1, 0, ADC_CTL_CH18); ADCSequenceStepConfigure(ADC1_BASE, 1, 1, ADC_CTL_CH19|ADC_CTL_IE|ADC_CTL_END); ADCSequenceEnable(ADC1_BASE, 0);//enable sequencer 0 of ADC1 ADCSequenceEnable(ADC1_BASE, 1);//enable sequencer 0 of ADC1 ADCIntEnable(ADC1_BASE, 0); ADCIntEnable(ADC1_BASE, 1); IntEnable(INT_ADC1SS0);//enable the interrupt for sequencer0 of ADC1 IntEnable(INT_ADC1SS1);//enable the interrupt for sequencer1 of ADC0 } void VJ_initADC0WithDMA(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0)) { } //Configures the 0ths sequencer of ADC0 as triggered by a Timer with highest priority //ADC_adress|Sequencer_number|Trigger_source|Priority needs to be between 0 to 3, 0 highest prio; 3 lowest prio ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_TIMER, 0); ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_TIMER, 1); //program sequencer 0 of ADC0 to sample AIN0 to AIN7 ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_CH0); ADCSequenceStepConfigure(ADC0_BASE, 0, 1, ADC_CTL_CH1); ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_CH2); ADCSequenceStepConfigure(ADC0_BASE, 0, 3, ADC_CTL_CH3); ADCSequenceStepConfigure(ADC0_BASE, 0, 4, ADC_CTL_CH4); ADCSequenceStepConfigure(ADC0_BASE, 0, 5, ADC_CTL_CH5); ADCSequenceStepConfigure(ADC0_BASE, 0, 6, ADC_CTL_CH6); ADCSequenceStepConfigure(ADC0_BASE, 0, 7, ADC_CTL_CH7|ADC_CTL_IE|ADC_CTL_END); //program sequencer 1 of ADC0 to sample AIN8 to AIN9 ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH8); ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH9|ADC_CTL_IE|ADC_CTL_END); //enable the adc to generate dma transfer requests //enable ADC0sequencer0 to request a dma transfer ADCSequenceDMAEnable(ADC0_BASE, 0); //enable ADC0sequencer1 to request a dma transfer ADCSequenceDMAEnable(ADC0_BASE, 1); ADCSequenceEnable(ADC0_BASE, 0);//enable sequencer 0 of ADC0 ADCSequenceEnable(ADC0_BASE, 1);//enable sequencer 1 of ADC0 ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS0);//enable the specific sequencer0 interrupt in ADC0 ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS1);//enable the specific sequencer1 interrupt in ADC0 } void VJ_initADC1WithDMA(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_ADC1)) { } //Configures the 0ths sequencer of ADC1 as triggered by a Timer with highest priority //ADC_adress|Sequencer_number|Trigger_source|Priority needs to be between 0 to 3, 0 highest prio; 3 lowest prio ADCSequenceConfigure(ADC1_BASE, 0, ADC_TRIGGER_TIMER, 0); ADCSequenceConfigure(ADC1_BASE, 1, ADC_TRIGGER_TIMER, 1); //program sequencer 0 of ADC1 to sample AIN10 to AIN17 ADCSequenceStepConfigure(ADC1_BASE, 0, 0, ADC_CTL_CH10); ADCSequenceStepConfigure(ADC1_BASE, 0, 1, ADC_CTL_CH11); ADCSequenceStepConfigure(ADC1_BASE, 0, 2, ADC_CTL_CH12); ADCSequenceStepConfigure(ADC1_BASE, 0, 3, ADC_CTL_CH13); ADCSequenceStepConfigure(ADC1_BASE, 0, 4, ADC_CTL_CH14); ADCSequenceStepConfigure(ADC1_BASE, 0, 5, ADC_CTL_CH15); ADCSequenceStepConfigure(ADC1_BASE, 0, 6, ADC_CTL_CH16); ADCSequenceStepConfigure(ADC1_BASE, 0, 7, ADC_CTL_CH17|ADC_CTL_IE|ADC_CTL_END); //program sequencer 1 of ADC1 to sample AIN0 to AIN7 ADCSequenceStepConfigure(ADC1_BASE, 1, 0, ADC_CTL_CH18); ADCSequenceStepConfigure(ADC1_BASE, 1, 1, ADC_CTL_CH19|ADC_CTL_IE|ADC_CTL_END); //enable ADC1sequencer0 to request a dma transfer ADCSequenceDMAEnable(ADC1_BASE, 0); //enable ADC1sequencer1 to request a dma transfer ADCSequenceDMAEnable(ADC1_BASE, 1); ADCSequenceEnable(ADC1_BASE, 0);//enable sequencer 0 of ADC1 ADCSequenceEnable(ADC1_BASE, 1);//enable sequencer 0 of ADC1 ADCIntEnableEx(ADC1_BASE, ADC_INT_DMA_SS0);//enable the specific sequencer0 interrupt in ADC1 ADCIntEnableEx(ADC1_BASE, ADC_INT_DMA_SS1);//enable the specific sequencer1 interrupt in ADC1 } void VJ_initDMATransForADC1SS1(void) { uint8_t *CheckTable=0xFFFFFFFF; while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA)) { } CheckTable=uDMAControlBaseGet(); if(CheckTable==0|CheckTable==0xFFFFFFFF) { while(1) {} } uDMAChannelAssign(UDMA_CH25_ADC1_1);//DMAChannel 25 is used by ADC1 Sequencer1 // disable all channel attributes for channel 14,15,24,25 uDMAChannelAttributeDisable(UDMA_SEC_CHANNEL_ADC11, UDMA_ATTR_ALL); /* enable for channel 14,15,24,25 burst mode->only burst modes will be processed by DMA *set the priority to high for channel 14 and 24, channel 15 and 25 will remain as default priority *the order of execution if multiple channels request a DMA are dependent on the channel number AND the priority setting, the lower the channel number the more important *Priority-List:0=most important,3=least important *-0. Channel 14 *-1. Channel 15 *-2. Channel 24 *-3. Channel 25 */ uDMAChannelAttributeEnable(UDMA_SEC_CHANNEL_ADC11, UDMA_ATTR_USEBURST); /* setup the primary control structure for channel 14,15,24,25 * a transfer item is 16 bit->UDMA_SIZE_16 * the sources are the FIFOs of the ADC sequencers, after a value is read from the FIFO this value is poped->UDMA_SRC_INC_NONE * the destination array is a uint16 array. each cell is 16 bit->UDMA_DST_INC_16 * the FIFOs request a DMA transfer if they are half full, for sequencer0 this is after 4 samples and for sequencer1 this is after 2 samples * the DMA should therefore always rearbitary after one burst if a higher priority channel requests a transfer-> UDMA_ARB_4 for sequencer 0, UDMA_ARB_2 for sequencer 1 */ uDMAChannelControlSet(UDMA_SEC_CHANNEL_ADC11|UDMA_PRI_SELECT, UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16|UDMA_ARB_2); /* setup the alternative control structure for channel 14,15,24,25 * the same settings as for the primary */ uDMAChannelControlSet(UDMA_SEC_CHANNEL_ADC11|UDMA_ALT_SELECT, UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16|UDMA_ARB_2); /* set second the primary transfer function active -> | UDMA_ALT_SELECT * Ping-Pong transfer -> UDMA_MODE_PINGPONG * source adresses -> FIFO adresse TODO:remove hard coded adresses * destination adresses -> adress of the first element of the ping buffers * number of items (16 bit) -> 1024 (WHICH IS THE MAXIMUM VALUE!) */ uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC11|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 0x40039068, Adc1_FIFO1_UDMA_B, VJDMATRANSFERSIZE_SS1); /* set second the primary transfer function active -> | UDMA_PRI_SELECT * Ping-Pong transfer -> UDMA_MODE_PINGPONG * source adresses -> FIFO adresse TODO:remove hard coded adresses * destination adresses -> adress of the first element of the ping buffers * number of items (16 bit) -> 1024 (WHICH IS THE MAXIMUM VALUE!) */ uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC11|UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 0x40039068, Adc1_FIFO1_UDMA_A, VJDMATRANSFERSIZE_SS1); /* activate the channels * first transfer is with the primary control structure */ uDMAChannelEnable(UDMA_SEC_CHANNEL_ADC11); } void VJ_initDMATransForADC1SS0(void) { uint8_t *CheckTable=0xFFFFFFFF; while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA)) { } CheckTable=uDMAControlBaseGet(); if(CheckTable==0|CheckTable==0xFFFFFFFF) { while(1) {} } uDMAChannelAssign(UDMA_CH24_ADC1_0);//DMAChannel 24 is used by ADC1 Sequencer0 // disable all channel attributes for channel 14,15,24,25 uDMAChannelAttributeDisable(UDMA_SEC_CHANNEL_ADC10, UDMA_ATTR_ALL); /* enable for channel 14,15,24,25 burst mode->only burst modes will be processed by DMA *set the priority to high for channel 14 and 24, channel 15 and 25 will remain as default priority *the order of execution if multiple channels request a DMA are dependent on the channel number AND the priority setting, the lower the channel number the more important *Priority-List:0=most important,3=least important *-0. Channel 14 *-1. Channel 15 *-2. Channel 24 *-3. Channel 25 */ uDMAChannelAttributeEnable(UDMA_SEC_CHANNEL_ADC10, UDMA_ATTR_USEBURST|UDMA_ATTR_HIGH_PRIORITY); /* setup the primary control structure for channel 14,15,24,25 * a transfer item is 16 bit->UDMA_SIZE_16 * the sources are the FIFOs of the ADC sequencers, after a value is read from the FIFO this value is poped->UDMA_SRC_INC_NONE * the destination array is a uint16 array. each cell is 16 bit->UDMA_DST_INC_16 * the FIFOs request a DMA transfer if they are half full, for sequencer0 this is after 4 samples and for sequencer1 this is after 2 samples * the DMA should therefore always rearbitary after one burst if a higher priority channel requests a transfer-> UDMA_ARB_4 for sequencer 0, UDMA_ARB_2 for sequencer 1 */ uDMAChannelControlSet(UDMA_SEC_CHANNEL_ADC10|UDMA_PRI_SELECT, UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16|UDMA_ARB_4); /* setup the alternative control structure for channel 14,15,24,25 * the same settings as for the primary */ uDMAChannelControlSet(UDMA_SEC_CHANNEL_ADC10|UDMA_ALT_SELECT, UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16|UDMA_ARB_4); /* set second the primary transfer function active -> | UDMA_PRI_SELECT * Ping-Pong transfer -> UDMA_MODE_PINGPONG * source adresses -> FIFO adresse TODO:remove hard coded adresses * destination adresses -> adress of the first element of the ping buffers * number of items (16 bit) -> 1024 (WHICH IS THE MAXIMUM VALUE!) */ uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC10|UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 0x40039048, Adc1_FIFO0_UDMA_A, VJDMATRANSFERSIZE_SS0); /* set first the alternative transfer function active -> | UDMA_ALT_SELECT * Ping-Pong transfer -> UDMA_MODE_PINGPONG * source adresses -> FIFO adresse TODO:remove hard coded adresses * destination adresses -> adress of the first element of the pong buffers * number of items (16 bit) -> 1024 (WHICH IS THE MAXIMUM VALUE!) */ uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC10|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 0x40039048, Adc1_FIFO0_UDMA_B, VJDMATRANSFERSIZE_SS0); /* activate the channels * first transfer is with the primary control structure */ uDMAChannelEnable(UDMA_SEC_CHANNEL_ADC10); } void VJ_initDMATransForADC0SS1(void) { uint8_t *CheckTable=0xFFFFFFFF; while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA)) { } CheckTable=uDMAControlBaseGet(); if(CheckTable==0|CheckTable==0xFFFFFFFF) { while(1) {} } uDMAChannelAssign(UDMA_CH15_ADC0_1);//DMAChannel 15 is used by ADC0 Sequencer1 // disable all channel attributes for channel 14,15,24,25 uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC1, UDMA_ATTR_ALL); /* enable for channel 14,15,24,25 burst mode->only burst modes will be processed by DMA *set the priority to high for channel 14 and 24, channel 15 and 25 will remain as default priority *the order of execution if multiple channels request a DMA are dependent on the channel number AND the priority setting, the lower the channel number the more important *Priority-List:0=most important,3=least important *-0. Channel 14 *-1. Channel 15 *-2. Channel 24 *-3. Channel 25 */ uDMAChannelAttributeEnable(UDMA_CHANNEL_ADC1, UDMA_ATTR_USEBURST); /* setup the primary control structure for channel 14,15,24,25 * a transfer item is 16 bit->UDMA_SIZE_16 * the sources are the FIFOs of the ADC sequencers, after a value is read from the FIFO this value is poped->UDMA_SRC_INC_NONE * the destination array is a uint16 array. each cell is 16 bit->UDMA_DST_INC_16 * the FIFOs request a DMA transfer if they are half full, for sequencer0 this is after 4 samples and for sequencer1 this is after 2 samples * the DMA should therefore always rearbitary after one burst if a higher priority channel requests a transfer-> UDMA_ARB_4 for sequencer 0, UDMA_ARB_2 for sequencer 1 */ uDMAChannelControlSet(UDMA_CHANNEL_ADC1|UDMA_PRI_SELECT, UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16|UDMA_ARB_2); /* setup the alternative control structure for channel 14,15,24,25 * the same settings as for the primary */ uDMAChannelControlSet(UDMA_CHANNEL_ADC1|UDMA_ALT_SELECT, UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16|UDMA_ARB_2); /* set second the primary transfer function active -> | UDMA_PRI_SELECT * Ping-Pong transfer -> UDMA_MODE_PINGPONG * source adresses -> FIFO adresse TODO:remove hard coded adresses * destination adresses -> adress of the first element of the ping buffers * number of items (16 bit) -> 1024 (WHICH IS THE MAXIMUM VALUE!) */ uDMAChannelTransferSet(UDMA_CHANNEL_ADC1|UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 0x40038068, Adc0_FIFO1_UDMA_A, VJDMATRANSFERSIZE_SS1); /* set first the alternative transfer function active -> | UDMA_ALT_SELECT * Ping-Pong transfer -> UDMA_MODE_PINGPONG * source adresses -> FIFO adresse TODO:remove hard coded adresses * destination adresses -> adress of the first element of the pong buffers * number of items (16 bit) -> 1024 (WHICH IS THE MAXIMUM VALUE!) */ uDMAChannelTransferSet(UDMA_CHANNEL_ADC1|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 0x40038068, Adc0_FIFO1_UDMA_B, VJDMATRANSFERSIZE_SS1); /* activate the channels * first transfer is with the primary control structure */ uDMAChannelEnable(UDMA_CHANNEL_ADC1); } void VJ_initDMATransForADC0SS0(void) { uint8_t *CheckTable=0xFFFFFFFF; while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA)) { } CheckTable=uDMAControlBaseGet(); if(CheckTable==0|CheckTable==0xFFFFFFFF) { while(1) {} } uDMAChannelAssign(UDMA_CH14_ADC0_0);//DMAChannel 14 is used by ADC0 Sequencer0 // disable all channel attributes for channel 14 uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0, UDMA_ATTR_ALL);//TODO:DEBUG burst channel disabled /* enable for channel 14,15,24,25 burst mode->only burst modes will be processed by DMA *set the priority to high for channel 14 and 24, channel 15 and 25 will remain as default priority *the order of execution if multiple channels request a DMA are dependent on the channel number AND the priority setting, the lower the channel number the more important *Priority-List:0=most important,3=least important *-0. Channel 14 *-1. Channel 15 *-2. Channel 24 *-3. Channel 25 */ uDMAChannelAttributeEnable(UDMA_CHANNEL_ADC0, UDMA_ATTR_USEBURST|UDMA_ATTR_HIGH_PRIORITY); /* setup the primary control structure for channel 14,15,24,25 * a transfer item is 16 bit->UDMA_SIZE_16 * the sources are the FIFOs of the ADC sequencers, after a value is read from the FIFO this value is poped->UDMA_SRC_INC_NONE * the destination array is a uint16 array. each cell is 16 bit->UDMA_DST_INC_16 * the FIFOs request a DMA transfer if they are half full, for sequencer0 this is after 4 samples and for sequencer1 this is after 2 samples * the DMA should therefore always rearbitary after one burst if a higher priority channel requests a transfer-> UDMA_ARB_4 for sequencer 0, UDMA_ARB_2 for sequencer 1 */ uDMAChannelControlSet(UDMA_CHANNEL_ADC0|UDMA_PRI_SELECT, UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16|UDMA_ARB_4); /* setup the alternative control structure for channel 14,15,24,25 * the same settings as for the primary */ uDMAChannelControlSet(UDMA_CHANNEL_ADC0|UDMA_ALT_SELECT, UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16|UDMA_ARB_4); /* set second the primary transfer function active -> | UDMA_PRI_SELECT * Ping-Pong transfer -> UDMA_MODE_PINGPONG * source adresses -> FIFO adresse TODO:remove hard coded adresses * destination adresses -> adress of the first element of the ping buffers * number of items (16 bit) -> 1024 (WHICH IS THE MAXIMUM VALUE!) */ uDMAChannelTransferSet(UDMA_CHANNEL_ADC0|UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 0x40038048, Adc0_FIFO0_UDMA_A, VJDMATRANSFERSIZE_SS0); /* set first the alternative transfer function active -> | UDMA_ALT_SELECT * Ping-Pong transfer -> UDMA_MODE_PINGPONG * source adresses -> FIFO adresse TODO:remove hard coded adresses * destination adresses -> adress of the first element of the pong buffers * number of items (16 bit) -> 1024 (WHICH IS THE MAXIMUM VALUE!) */ uDMAChannelTransferSet(UDMA_CHANNEL_ADC0|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 0x40038048, Adc0_FIFO0_UDMA_B, VJDMATRANSFERSIZE_SS0); /* activate the channels * first transfer is with the primary control structure */ uDMAChannelEnable(UDMA_CHANNEL_ADC0); } void VJ_initTimer2ForADC(uint32_t ui32SysClkFreq) { SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER2)) { } uint32_t ui32Period = ui32SysClkFreq/VJADCSINGLECHANNELRATE; TimerConfigure(TIMER2_BASE, TIMER_CFG_PERIODIC);//configure timer2 as a periodic timer TimerLoadSet(TIMER2_BASE, TIMER_A, ui32Period-1);//load the calculated number of ticks into timer0 TimerControlTrigger(TIMER2_BASE, TIMER_A, true);//enables timer2 to trigger the ADCs TimerIntEnable(TIMER2_BASE, TIMER_TIMA_TIMEOUT);//enable the specific interrupt in timer0 TimerEnable(TIMER2_BASE, TIMER_A); } void ISR_Adc0Sequencer0(void) { ADCIntClear(ADC0_BASE,0);//TODO:Under- and Overflowcheck ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS0); Swi_post(Adc0Sequencer0); ADC0SEQUENCER0++; } void ISR_Adc0Sequencer1(void) { ADCIntClear(ADC0_BASE,1);//TODO:Under- and Overflowcheck ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS1); Swi_post(Adc0Sequencer1); ADC0SEQUENCER1++; } void ISR_Adc1Sequencer0(void) { ADCIntClear(ADC1_BASE,0);//TODO:Under- and Overflowcheck ADCIntClearEx(ADC1_BASE, ADC_INT_DMA_SS0); Swi_post(Adc1Sequencer0); ADC1SEQUENCER0++; } void ISR_Adc1Sequencer1(void) { ADCIntClear(ADC1_BASE,1);//TODO:Under- and Overflowcheck ADCIntClearEx(ADC1_BASE, ADC_INT_DMA_SS1); Swi_post(Adc1Sequencer1); ADC1SEQUENCER1++; } void ISR_Timer2(void) { // Clear the timer interrupt TimerIntClear(TIMER2_BASE, TIMER_TIMA_TIMEOUT); TIMER2++; DebugPrint=(TIMER2%(VJNUMOFSAMPLEPERTRANSFER)); switch (DebugPrint) { case 0: Log_info5("HWI !!! Timer2: [%u]| Adc0Sequencer0 : [%u] | Adc0Sequencer1 : [%u] | Adc1Sequencer0 : [%u] | Adc1Sequencer1 : [%u] ",TIMER2,ADC0SEQUENCER0,ADC0SEQUENCER1,ADC1SEQUENCER0,ADC1SEQUENCER1); break; case 1: Log_info5("SWI !!! Timer2: [%u]| Adc0Sequencer0_A: [%u] | Adc0Sequencer1_A: [%u] | Adc1Sequencer0_A: [%u] | Adc1Sequencer1_A: [%u] ",TIMER2,ADC0Sequencer0SWI_A,ADC0Sequencer1SWI_A,ADC1Sequencer0SWI_A,ADC1Sequencer1SWI_A); break; case 2: Log_info5("SWI !!! Timer2: [%u]| Adc0Sequencer0_B: [%u] | Adc0Sequencer1_B: [%u] | Adc1Sequencer0_B: [%u] | Adc1Sequencer1_B: [%u] ",TIMER2,ADC0Sequencer0SWI_B,ADC0Sequencer1SWI_B,ADC1Sequencer0SWI_B,ADC1Sequencer1SWI_B); break; case 3: Log_info5("DMA Enables!!! Timer2: [%u]| Adc0Sequencer0: [%u] | Adc0Sequencer1: [%u] | Adc1Sequencer0 : [%u] | Adc1Sequencer1 : [%u] ",TIMER2,ADC0Sequencer0SWI ,ADC0Sequencer1SWI ,ADC1Sequencer0SWI ,ADC1Sequencer1SWI ); break; } } void SWI_Adc0Sequencer0(void) { if(!uDMAChannelIsEnabled(UDMA_CHANNEL_ADC0)) { uDMAChannelEnable(UDMA_CHANNEL_ADC0); ADC0Sequencer0SWI++; } ui32Mode=uDMAChannelModeGet(UDMA_CHANNEL_ADC0|UDMA_PRI_SELECT); if(ui32Mode==UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_CHANNEL_ADC0|UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 0x40038048, Adc0_FIFO0_UDMA_A, VJDMATRANSFERSIZE_SS0); ADC0Sequencer0SWI_A++; } ui32Mode=uDMAChannelModeGet(UDMA_CHANNEL_ADC0|UDMA_ALT_SELECT); if(ui32Mode==UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_CHANNEL_ADC0|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 0x40038048, Adc0_FIFO0_UDMA_B, VJDMATRANSFERSIZE_SS0); ADC0Sequencer0SWI_B++; } } void SWI_Adc0Sequencer1(void) { if(!uDMAChannelIsEnabled(UDMA_CHANNEL_ADC1)) { uDMAChannelEnable(UDMA_CHANNEL_ADC1); ADC0Sequencer1SWI++; } ui32Mode=uDMAChannelModeGet(UDMA_CHANNEL_ADC1|UDMA_PRI_SELECT); if(ui32Mode==UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_CHANNEL_ADC1|UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 0x40038068, Adc0_FIFO1_UDMA_A, VJDMATRANSFERSIZE_SS1); ADC0Sequencer1SWI_A++; } ui32Mode=uDMAChannelModeGet(UDMA_CHANNEL_ADC1|UDMA_ALT_SELECT); if(ui32Mode==UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_CHANNEL_ADC1|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 0x40038068, Adc0_FIFO1_UDMA_B, VJDMATRANSFERSIZE_SS1); ADC0Sequencer1SWI_B++; } } void SWI_Adc1Sequencer0(void) { if(!uDMAChannelIsEnabled(UDMA_SEC_CHANNEL_ADC10)) { uDMAChannelEnable(UDMA_SEC_CHANNEL_ADC10); ADC1Sequencer0SWI++; } ui32Mode=uDMAChannelModeGet(UDMA_SEC_CHANNEL_ADC10|UDMA_PRI_SELECT); if(ui32Mode==UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC10|UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 0x40039048, Adc1_FIFO0_UDMA_A, VJDMATRANSFERSIZE_SS0); ADC1Sequencer0SWI_A++; } ui32Mode=uDMAChannelModeGet(UDMA_SEC_CHANNEL_ADC10|UDMA_ALT_SELECT); if(ui32Mode==UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC10|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 0x40039048, Adc1_FIFO0_UDMA_B, VJDMATRANSFERSIZE_SS0); ADC1Sequencer0SWI_B++; } } void SWI_Adc1Sequencer1(void) { if(!uDMAChannelIsEnabled(UDMA_SEC_CHANNEL_ADC11)) { uDMAChannelEnable(UDMA_SEC_CHANNEL_ADC11); ADC1Sequencer1SWI++; } ui32Mode=uDMAChannelModeGet(UDMA_SEC_CHANNEL_ADC11|UDMA_PRI_SELECT); if(ui32Mode==UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC11|UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 0x40039068, Adc1_FIFO1_UDMA_A, VJDMATRANSFERSIZE_SS1); ADC1Sequencer1SWI_A++; } ui32Mode=uDMAChannelModeGet(UDMA_SEC_CHANNEL_ADC11|UDMA_ALT_SELECT); if(ui32Mode==UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_SEC_CHANNEL_ADC11|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 0x40039068, Adc1_FIFO1_UDMA_B, VJDMATRANSFERSIZE_SS1); ADC1Sequencer1SWI_B++; } } /* * ======== main ======== */ int main(void) { uint32_t ui32SysClkFreq = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), VJSYSFRQ); /* Call board init functions */ Board_initGeneral(); EK_TM4C129EXL_initDMA(); // Board_initEMAC(); Board_initGPIO(); // Board_initI2C(); // Board_initSDSPI(); // Board_initSPI(); // Board_initUART(); // Board_initUSB(Board_USBDEVICE); // Board_initUSBMSCHFatFs(); // Board_initWatchdog(); // Board_initWiFi(); VJ_initAnalogInputs(); VJ_initADC0WithDMA(); //VJ_initADC0WithOutDMA(); VJ_initDMATransForADC0SS0(); VJ_initDMATransForADC0SS1(); //VJ_initADC1WithOutDMA(); VJ_initADC1WithDMA(); VJ_initDMATransForADC1SS0(); VJ_initDMATransForADC1SS1(); VJ_initTimer2ForADC(ui32SysClkFreq); /* Start BIOS */ BIOS_start(); return (0); }
At the moment the transfersize is set to 1016 which works perfectly fine (I also tried 1023 which works as well). With the define
#define VJDMATRANSFERSIZE_SS0
the transfersize can be changed. In order to debug the application the application increments debug variables and print them to a log every 1016 timer2 interrupts.
My TI-RTOS settings (.cfg) are the following:
/* * Copyright (c) 2015-2016, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* ================ Clock configuration ================ */ var Clock = xdc.useModule('ti.sysbios.knl.Clock'); var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup'); /* * Default value is family dependent. For example, Linux systems often only * support a minimum period of 10000 us and multiples of 10000 us. * TI platforms have a default of 1000 us. */ Clock.tickPeriod = 1000; /* ================ Defaults (module) configuration ================ */ var Defaults = xdc.useModule('xdc.runtime.Defaults'); /* * A flag to allow module names to be loaded on the target. Module name * strings are placed in the .const section for debugging purposes. * * Pick one: * - true (default) * Setting this parameter to true will include name strings in the .const * section so that Errors and Asserts are easier to debug. * - false * Setting this parameter to false will reduce footprint in the .const * section. As a result, Error and Assert messages will contain an * "unknown module" prefix instead of the actual module name. */ Defaults.common$.namedModule = true; //Defaults.common$.namedModule = false; /* ================ Error configuration ================ */ var Error = xdc.useModule('xdc.runtime.Error'); /* * This function is called to handle all raised errors, but unlike * Error.raiseHook, this function is responsible for completely handling the * error with an appropriately initialized Error_Block. * * Pick one: * - Error.policyDefault (default) * Calls Error.raiseHook with an initialized Error_Block structure and logs * the error using the module's logger. * - Error.policySpin * Simple alternative that traps on a while(1) loop for minimized target * footprint. * Using Error.policySpin, the Error.raiseHook will NOT called. */ Error.policyFxn = Error.policyDefault; //Error.policyFxn = Error.policySpin; /* * If Error.policyFxn is set to Error.policyDefault, this function is called * whenever an error is raised by the Error module. * * Pick one: * - Error.print (default) * Errors are formatted and output via System_printf() for easier * debugging. * - null * Errors are not formatted or logged. This option reduces code footprint. * - non-null function * Errors invoke custom user function. See the Error module documentation * for more details. */ Error.raiseHook = Error.print; //Error.raiseHook = null; //Error.raiseHook = "&myErrorFxn"; /* * If Error.policyFxn is set to Error.policyDefault, this option applies to the * maximum number of times the Error.raiseHook function can be recursively * invoked. This option limits the possibility of an infinite recursion that * could lead to a stack overflow. * The default value is 16. */ Error.maxDepth = 2; /* ================ Hwi configuration ================ */ var halHwi = xdc.useModule('ti.sysbios.hal.Hwi'); var m3Hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi'); /* * Checks for Hwi (system) stack overruns while in the Idle loop. * * Pick one: * - true (default) * Checks the top word for system stack overflows during the idle loop and * raises an Error if one is detected. * - false * Disabling the runtime check improves runtime performance and yields a * reduced flash footprint. */ //halHwi.checkStackFlag = true; halHwi.checkStackFlag = false; /* * The following options alter the system's behavior when a hardware exception * is detected. * * Pick one: * - Hwi.enableException = true * This option causes the default m3Hwi.excHandlerFunc function to fully * decode an exception and dump the registers to the system console. * This option raises errors in the Error module and displays the * exception in ROV. * - Hwi.enableException = false * This option reduces code footprint by not decoding or printing the * exception to the system console. * It however still raises errors in the Error module and displays the * exception in ROV. * - Hwi.excHandlerFunc = null * This is the most aggressive option for code footprint savings; but it * can difficult to debug exceptions. It reduces flash footprint by * plugging in a default while(1) trap when exception occur. This option * does not raise an error with the Error module. */ m3Hwi.enableException = true; //m3Hwi.enableException = false; //m3Hwi.excHandlerFunc = null; /* * Enable hardware exception generation when dividing by zero. * * Pick one: * - 0 (default) * Disables hardware exceptions when dividing by zero * - 1 * Enables hardware exceptions when dividing by zero */ m3Hwi.nvicCCR.DIV_0_TRP = 0; //m3Hwi.nvicCCR.DIV_0_TRP = 1; /* * Enable hardware exception generation for invalid data alignment. * * Pick one: * - 0 (default) * Disables hardware exceptions for data alignment * - 1 * Enables hardware exceptions for data alignment */ m3Hwi.nvicCCR.UNALIGN_TRP = 0; //m3Hwi.nvicCCR.UNALIGN_TRP = 1; /* ================ Idle configuration ================ */ var Idle = xdc.useModule('ti.sysbios.knl.Idle'); /* * The Idle module is used to specify a list of functions to be called when no * other tasks are running in the system. * * Functions added here will be run continuously within the idle task. * * Function signature: * Void func(Void); */ //Idle.addFunc("&myIdleFunc"); /* ================ Kernel (SYS/BIOS) configuration ================ */ var BIOS = xdc.useModule('ti.sysbios.BIOS'); /* * Enable asserts in the BIOS library. * * Pick one: * - true (default) * Enables asserts for debugging purposes. * - false * Disables asserts for a reduced code footprint and better performance. */ //BIOS.assertsEnabled = true; BIOS.assertsEnabled = true; /* * Specify default heap size for BIOS. */ BIOS.heapSize = 512; /* * A flag to determine if xdc.runtime sources are to be included in a custom * built BIOS library. * * Pick one: * - false (default) * The pre-built xdc.runtime library is provided by the respective target * used to build the application. * - true * xdc.runtime library sources are to be included in the custom BIOS * library. This option yields the most efficient library in both code * footprint and runtime performance. */ BIOS.includeXdcRuntime = false; //BIOS.includeXdcRuntime = true; /* * The SYS/BIOS runtime is provided in the form of a library that is linked * with the application. Several forms of this library are provided with the * SYS/BIOS product. * * Pick one: * - BIOS.LibType_Custom * Custom built library that is highly optimized for code footprint and * runtime performance. * - BIOS.LibType_Debug * Custom built library that is non-optimized that can be used to * single-step through APIs with a debugger. * */ BIOS.libType = BIOS.LibType_Custom; //BIOS.libType = BIOS.LibType_Debug; /* * Runtime instance creation enable flag. * * Pick one: * - true (default) * Allows Mod_create() and Mod_delete() to be called at runtime which * requires a default heap for dynamic memory allocation. * - false * Reduces code footprint by disallowing Mod_create() and Mod_delete() to * be called at runtime. Object instances are constructed via * Mod_construct() and destructed via Mod_destruct(). */ BIOS.runtimeCreatesEnabled = true; //BIOS.runtimeCreatesEnabled = false; /* * Enable logs in the BIOS library. * * Pick one: * - true (default) * Enables logs for debugging purposes. * - false * Disables logging for reduced code footprint and improved runtime * performance. */ //BIOS.logsEnabled = true; BIOS.logsEnabled = true; /* ================ Memory configuration ================ */ var Memory = xdc.useModule('xdc.runtime.Memory'); /* * The Memory module itself simply provides a common interface for any * variety of system and application specific memory management policies * implemented by the IHeap modules(Ex. HeapMem, HeapBuf). */ /* ================ Program configuration ================ */ /* * Program.stack is ignored with IAR. Use the project options in * IAR Embedded Workbench to alter the system stack size. */ if (!Program.build.target.$name.match(/iar/)) { /* * Reducing the system stack size (used by ISRs and Swis) to reduce * RAM usage. */ Program.stack = 1024; } /* * Enable Semihosting for GNU targets to print to CCS console */ if (Program.build.target.$name.match(/gnu/)) { var SemiHost = xdc.useModule('ti.sysbios.rts.gnu.SemiHostSupport'); } /* ================ Semaphore configuration ================ */ var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore'); /* * Enables global support for Task priority pend queuing. * * Pick one: * - true (default) * This allows pending tasks to be serviced based on their task priority. * - false * Pending tasks are services based on first in, first out basis. * * When using BIOS in ROM: * This option must be set to false. */ //Semaphore.supportsPriority = true; Semaphore.supportsPriority = false; /* * Allows for the implicit posting of events through the semaphore, * disable for additional code saving. * * Pick one: * - true * This allows the Semaphore module to post semaphores and events * simultaneously. * - false (default) * Events must be explicitly posted to unblock tasks. * */ //Semaphore.supportsEvents = true; Semaphore.supportsEvents = false; /* ================ Swi configuration ================ */ var Swi = xdc.useModule('ti.sysbios.knl.Swi'); /* * A software interrupt is an object that encapsulates a function to be * executed and a priority. Software interrupts are prioritized, preempt tasks * and are preempted by hardware interrupt service routines. * * This module is included to allow Swi's in a users' application. */ /* ================ System configuration ================ */ var System = xdc.useModule('xdc.runtime.System'); /* * The Abort handler is called when the system exits abnormally. * * Pick one: * - System.abortStd (default) * Call the ANSI C Standard 'abort()' to terminate the application. * - System.abortSpin * A lightweight abort function that loops indefinitely in a while(1) trap * function. * - A custom abort handler * A user-defined function. See the System module documentation for * details. */ System.abortFxn = System.abortStd; //System.abortFxn = System.abortSpin; //System.abortFxn = "&myAbortSystem"; /* * The Exit handler is called when the system exits normally. * * Pick one: * - System.exitStd (default) * Call the ANSI C Standard 'exit()' to terminate the application. * - System.exitSpin * A lightweight exit function that loops indefinitely in a while(1) trap * function. * - A custom exit function * A user-defined function. See the System module documentation for * details. */ System.exitFxn = System.exitStd; //System.exitFxn = System.exitSpin; //System.exitFxn = "&myExitSystem"; /* * Minimize exit handler array in the System module. The System module includes * an array of functions that are registered with System_atexit() which is * called by System_exit(). The default value is 8. */ System.maxAtexitHandlers = 2; /* * The System.SupportProxy defines a low-level implementation of System * functions such as System_printf(), System_flush(), etc. * * Pick one pair: * - SysMin * This module maintains an internal configurable circular buffer that * stores the output until System_flush() is called. * The size of the circular buffer is set via SysMin.bufSize. * - SysCallback * SysCallback allows for user-defined implementations for System APIs. * The SysCallback support proxy has a smaller code footprint and can be * used to supply custom System_printf services. * The default SysCallback functions point to stub functions. See the * SysCallback module's documentation. */ var SysMin = xdc.useModule('xdc.runtime.SysMin'); SysMin.bufSize = 128; System.SupportProxy = SysMin; //var SysCallback = xdc.useModule('xdc.runtime.SysCallback'); //System.SupportProxy = SysCallback; //SysCallback.abortFxn = "&myUserAbort"; //SysCallback.exitFxn = "&myUserExit"; //SysCallback.flushFxn = "&myUserFlush"; //SysCallback.putchFxn = "&myUserPutch"; //SysCallback.readyFxn = "&myUserReady"; /* ================ Task configuration ================ */ var Task = xdc.useModule('ti.sysbios.knl.Task'); /* * Check task stacks for overflow conditions. * * Pick one: * - true (default) * Enables runtime checks for task stack overflow conditions during * context switching ("from" and "to") * - false * Disables runtime checks for task stack overflow conditions. */ //Task.checkStackFlag = true; Task.checkStackFlag = false; /* * Set the default task stack size when creating tasks. * * The default is dependent on the device being used. Reducing the default stack * size yields greater memory savings. */ Task.defaultStackSize = 512; /* * Enables the idle task. * * Pick one: * - true (default) * Creates a task with priority of 0 which calls idle hook functions. This * option must be set to true to gain power savings provided by the Power * module. * - false * No idle task is created. This option consumes less memory as no * additional default task stack is needed. * To gain power savings by the Power module without having the idle task, * add Idle.run as the Task.allBlockedFunc. */ //Task.enableIdleTask = true; Task.enableIdleTask = false; //Task.allBlockedFunc = Idle.run; /* * If Task.enableIdleTask is set to true, this option sets the idle task's * stack size. * * Reducing the idle stack size yields greater memory savings. */ Task.idleTaskStackSize = 512; /* * Reduce the number of task priorities. * The default is 16. * Decreasing the number of task priorities yield memory savings. */ Task.numPriorities = 16; /* * Idle Function list. * * Functions added here will be run continously within the idle task. * * Function signature: * Void func(Void); */ //Idle.addFunc("&myIdleFunc"); /* ================ Text configuration ================ */ var Text = xdc.useModule('xdc.runtime.Text'); /* * These strings are placed in the .const section. Setting this parameter to * false will save space in the .const section. Error, Assert and Log messages * will print raw ids and args instead of a formatted message. * * Pick one: * - true (default) * This option loads test string into the .const for easier debugging. * - false * This option reduces the .const footprint. */ Text.isLoaded = true; //Text.isLoaded = false; /* ================ Types configuration ================ */ var Types = xdc.useModule('xdc.runtime.Types'); /* * This module defines basic constants and types used throughout the * xdc.runtime package. */ /* ================ TI-RTOS middleware configuration ================ */ var mwConfig = xdc.useModule('ti.mw.Config'); /* * Include TI-RTOS middleware libraries */ /* ================ TI-RTOS drivers' configuration ================ */ var driversConfig = xdc.useModule('ti.drivers.Config'); /* * Include TI-RTOS drivers * * Pick one: * - driversConfig.LibType_NonInstrumented (default) * Use TI-RTOS drivers library optimized for footprint and performance * without asserts or logs. * - driversConfig.LibType_Instrumented * Use TI-RTOS drivers library for debugging with asserts and logs enabled. */ driversConfig.libType = driversConfig.LibType_NonInstrumented; //driversConfig.libType = driversConfig.LibType_Instrumented; /* ================ Application Specific Instances ================ */ var m3Hwi0Params = new m3Hwi.Params(); m3Hwi0Params.instance.name = "HwiHandle_Timer2"; m3Hwi0Params.priority = 0; Program.global.HwiHandle_Timer2 = m3Hwi.create(39, "&ISR_Timer2", m3Hwi0Params); LoggingSetup.sysbiosSwiLogging = false; LoggingSetup.sysbiosHwiLogging = false; var m3Hwi1Params = new m3Hwi.Params(); m3Hwi1Params.instance.name = "HwiHandle_Adc0Sequencer0"; m3Hwi1Params.priority = 1; Program.global.HwiHandle_Adc0Sequencer0 = m3Hwi.create(30, "&ISR_Adc0Sequencer0", m3Hwi1Params); var m3Hwi2Params = new m3Hwi.Params(); m3Hwi2Params.instance.name = "HwiHandle_Adc0Sequencer1"; m3Hwi2Params.priority = 1; Program.global.HwiHandle_Adc0Sequencer1 = m3Hwi.create(31, "&ISR_Adc0Sequencer1", m3Hwi2Params); var m3Hwi3Params = new m3Hwi.Params(); m3Hwi3Params.instance.name = "HwiHandle_Adc1Sequencer0"; m3Hwi3Params.priority = 1; Program.global.HwiHandle_Adc1Sequencer0 = m3Hwi.create(62, "&ISR_Adc1Sequencer0", m3Hwi3Params); var m3Hwi4Params = new m3Hwi.Params(); m3Hwi4Params.instance.name = "HwiHandle_Adc1Sequencer1"; m3Hwi4Params.priority = 1; Program.global.HwiHandle_Adc1Sequencer1 = m3Hwi.create(63, "&ISR_Adc1Sequencer1", m3Hwi4Params); m3Hwi.dispatcherAutoNestingSupport = false; var swi0Params = new Swi.Params(); swi0Params.instance.name = "Adc0Sequencer0"; swi0Params.priority = 0; Program.global.Adc0Sequencer0 = Swi.create("&SWI_Adc0Sequencer0", swi0Params); var swi1Params = new Swi.Params(); swi1Params.instance.name = "Adc0Sequencer1"; swi1Params.priority = 0; Program.global.Adc0Sequencer1 = Swi.create("&SWI_Adc0Sequencer1", swi1Params); LoggingSetup.loadTaskLogging = false; LoggingSetup.loadSwiLogging = false; LoggingSetup.loadHwiLogging = true; LoggingSetup.enableTaskProfiler = false; LoggingSetup.loadLoggerSize = 1024; LoggingSetup.mainLoggerSize = 2048; var swi2Params = new Swi.Params(); swi2Params.instance.name = "Adc1Sequencer0"; swi2Params.priority = 0; Program.global.Adc1Sequencer0 = Swi.create("&SWI_Adc1Sequencer0", swi2Params); var swi3Params = new Swi.Params(); swi3Params.instance.name = "Adc1Sequencer1"; swi3Params.priority = 0; Program.global.Adc1Sequencer1 = Swi.create("&SWI_Adc1Sequencer1", swi3Params);
If you know what I did wrong please let me know, also if its a common bug, ( I allready tried to search for it). I am also gratefull on any tipps on how to debug this strange behavior.
Best greetings,
Richard