Part Number: MSP432P401R
Hello everybody,
I'm working on sampling 4 channels about 800kSample/s (200k each channel). My first try with a simple interrupt to retrieve data from the channels wasn't successful (with one channel the data retrieved seemed good, with 4 channels it looked like the data got corrupted/half converted), so I'm trying to solve it with the DMA. However, while inspecting the destination buffer, it writes nothing on it. The CodeComposerStudio interface is correctly configured to not block IRQs, and about all configurations work as intended. Also, I'm using the rev-C launchpad, so the errata described in this topic should not affect me. The relevant parts of code are below:
#include "msp432.h" #include "driverlib.h" // Burst frequency = 50kHz #define Burst_Freq 50 // External sample pulse width = 1us (3 / SMCLK) #define Ext_Pulse_Width 3 // Start of A/D conversion delay = 1us (3 / SMCLK) #define Start_ADC_Delay 3 // Number of samples to be acquired (2048 is enough for 300MS/s) #define Num_of_Results 2048 const uint16_t igs[] = {119, 256, 393, 530, 668, 805, 942, 1079}, ins = 1353; // gain step timings for fs = 200kS/s (TL851 datasheet) uint8_t nbp = 64; // number of burst pulses uint16_t index, gain, pulse; uint16_t gainstep[8]; uint16_t nsamp, ntick; volatile uint16_t A0results[Num_of_Results] __attribute__ ((section (".noinit"))); // Large vectors will take forever volatile uint16_t A1results[Num_of_Results] __attribute__ ((section (".noinit"))); // to be intitialised, so we do not volatile uint16_t A2results[Num_of_Results] __attribute__ ((section (".noinit"))); // initialise them! :-) volatile uint16_t A3results[Num_of_Results] __attribute__ ((section (".noinit"))); volatile uint16_t ADCresults[Num_of_Results][4] __attribute__ ((section (".noinit"))); // One array to rule them all uint8_t activeSpeakers = 0; /** * DMA control table. */ #if defined(__TI_COMPILER_VERSION__) #pragma DATA_ALIGN(MSP_EXP432P401RLP_DMAControlTable, 1024) #elif defined(__IAR_SYSTEMS_ICC__) #pragma data_alignment=1024 #elif defined(__GNUC__) __attribute__ ((aligned (1024))) #elif defined(__CC_ARM) __align(1024) #endif static DMA_ControlTable MSP_EXP432P401RLP_DMAControlTable[32]; // Initialize system clock and FPU void OurSystemInit(){ WDT_A_hold(WDT_A_BASE); // disable watchdog timer FPU_enableModule(); // enable floating point unit MAP_PCM_setCoreVoltageLevel(PCM_VCORE1); // set core voltage level to 1.4V MAP_FlashCtl_setWaitState(FLASH_BANK0, 2); // set read wait states for FLASH memory bank 0 MAP_FlashCtl_setWaitState(FLASH_BANK1, 2); // set read wait states for FLASH memory bank 1 MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_PJ, GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION); // enable HFXTIN MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ, GPIO_PIN2, GPIO_PRIMARY_MODULE_FUNCTION); // enable HFXTOUT MAP_CS_setExternalClockSourceFrequency(32768, 48000000); // LFXT = 32.768kHz, HFXT = 48MHz MAP_CS_startHFXT(false); // start HFXTCLK MAP_CS_initClockSignal(CS_MCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1); // MCLK = 48MHz MAP_CS_initClockSignal(CS_SMCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_16); // SMCLK = 3MHz //*** clock output for debug (must be used without any BoosterPack attached to the LaunchPad! ***// // MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P4, GPIO_PIN4, GPIO_PRIMARY_MODULE_FUNCTION); // enable HSMCLK in P4.4 } // SystemInit void ADC14Init(){ // Configure GPIO MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN5, GPIO_PRIMARY_MODULE_FUNCTION); // channel A8 MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN4 |GPIO_PIN3 |GPIO_PIN2, GPIO_TERTIARY_MODULE_FUNCTION); // channels A9-A11 //*** simulation of max analog input for debug (must be used without any BoosterPack attached to the LaunchPad! ***// // GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN5 /**/| GPIO_PIN4 | GPIO_PIN3 | GPIO_PIN2/**/); // enable pull-up resistors // Configure ADC14, <20us for 4 conversions, i.e. >200kS/s ADC14->CTL0 = ADC14_CTL0_ON; // Turn on ADC14 module ADC14->CTL0 |= ADC_CLOCKSOURCE_MCLK | ADC_PREDIVIDER_1 | ADC_DIVIDER_2; // fclock = MCLK / 2 ADC14->CTL0 |= ADC14_CTL0_SHS_5; // ADC14_CTL0_SHS_5 = TA2.1; ADC14_CTL0_SHS_0 = software ADC14->CTL1 = ADC_14BIT; // 14-bit resolution ADC14->CTL0 |= ADC14_CTL0_CONSEQ_3 | ADC14_CTL0_MSC; // software trigger, sequence of channels // ADC14CONSEQ3 = repeat sequence of channels ADC14->CTL0 |= ADC14_CTL0_SHT1__4 |ADC14_CTL0_SHT0__4 | ADC14_CTL0_SHP; // sampling time = 4 ticks ADC14->MCTL[0] = ADC14_MCTLN_INCH_8; // ref+=AVcc, channel = A8 ADC14->MCTL[1] = ADC14_MCTLN_INCH_9; // ref+=AVcc, channel = A9 ADC14->MCTL[2] = ADC14_MCTLN_INCH_10; // ref+=AVcc, channel = A10 ADC14->MCTL[3] = ADC14_MCTLN_INCH_11 | ADC14_MCTLN_EOS; // ref+=AVcc, channel = A11, end sequence ADC14->IER0 = ADC14_IER0_IE3; // Enable ADC14IFG.3 SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk; // Wake up on exit from ISR // Enable ADC interrupt in NVIC module __disable_interrupt(); NVIC->ISER[0] = 1 << ((INT_ADC14 - 16) & 31); // (SLAS826A table 6-12) __enable_interrupt(); } // ADC14Init void ADC14Enable(){ ADC14->CTL0 |= ADC14_CTL0_ENC; } // ADC14Enable void ADC14Disable(){ ADC14->CTL0 &= ~ADC14_CTL0_ENC; } // ADC14Disable // ADC14 interrupt service routine void ADC14IsrHandler(){ if (ADC14->IFGR0 & ADC14_IFGR0_IFG3){ ADC14->CTL0 &= ~ADC14_CTL0_ENC; // ADC14Disable(); // disable acquisition sequence (necessary for hardware trigger) //P2->OUT = gain; /** * Old method for buffering data **/ // A0results[index] = ADC14->MEM[0]; // Move A8 results, IFG is cleared // A1results[index] = ADC14->MEM[1]; // Move A9 results, IFG is cleared // A2results[index] = ADC14->MEM[2]; // Move A10 results, IFG is cleared // A3results[index] = ADC14->MEM[3]; // Move A11 results, IFG is cleared ADC14->CTL0 |= ADC14_CTL0_ENC; // ADC14Enable(); // enable next acquisition sequence // index++; // Increment index // if (index == nsamp) // { // TIMER_A0->CTL &= ~TIMER_A_UP_MODE; // TimerA0Stop(); // stop Timer A0 //dataReturn(); // } } // ADC14IsrHandler void DMAInit() { /* Configuring DMA module */ DMA_enableModule(); DMA_setControlBase(MSP_EXP432P401RLP_DMAControlTable); DMA_assignChannel(DMA_CH7_ADC14); DMA_disableChannelAttribute(DMA_CH7_ADC14, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); /* Setting Control Indexes. In this case we will set the source of the * DMA transfer to ADC14 Memory 0 * and the destination to the * destination data array. */ DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH7_ADC14, UDMA_SIZE_16 | UDMA_SRC_INC_32 | UDMA_DST_INC_16 | UDMA_ARB_1); DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH7_ADC14, UDMA_MODE_BASIC, (void*) &ADC14->MEM[0], &ADCresults[0][0], 4); /* Assigning/Enabling Interrupts */ DMA_assignInterrupt(DMA_INT1, 7); //Interrupt_enableInterrupt(INT_DMA_INT1); // Enable DMA-1 interrupt in NVIC module __disable_interrupt(); NVIC->ISER[0] = 1 << ((DMA_INT1 - 16) & 31); // (SLAS826A table 6-12) __enable_interrupt(); MAP_DMA_enableChannel(7); } void DMA_IRQHandler(void) { index++; // Increment index DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH7_ADC14, UDMA_MODE_BASIC, (void*) &ADC14->MEM[0], &ADCresults[index][0], 4); MAP_DMA_enableChannel(7); if (index == nsamp) { TIMER_A0->CTL &= ~TIMER_A_UP_MODE; // TimerA0Stop(); // stop Timer A0 //dataReturn(); } } int main(){ OurSystemInit(); SonarInit(200); // fs = 200kS/s TimerA0Init(); // fb = 50kHz TimerA2Init(); ADC14Init(); UARTInit(); DMAInit(); ADC14Enable(); SonarBurst(); // start aquisition __sleep(); } // main