/***************************************************************************** * Private types/enumerations/variables ****************************************************************************/ /* Size of the source and destination buffers in 32-bit words. Allowable values = 128, 256, 512, or 1024 */ #define SIZE_BUFFER (512) /* Source and destination buffers */ uint32_t adc_buf[SIZE_BUFFER]; /* DMA completion flag */ static volatile bool dmaDone; /***************************************************************************** * Public types/enumerations/variables ****************************************************************************/ /***************************************************************************** * Private functions ****************************************************************************/ /***************************************************************************** * Public functions ****************************************************************************/ /** * @briefDMA Interrupt Handler * @returnNone */ void DMA_IRQHandler(void) { /* Error interrupt on channel 0? */ if ((Chip_DMA_GetIntStatus(LPC_DMA) & DMA_INTSTAT_ACTIVEERRINT) != 0) { /* This shouldn't happen for this simple DMA example, so set the LED to indicate an error occurred. This is the correct method to clear an abort. */ Chip_DMA_DisableChannel(LPC_DMA, DMA_CH0); while ((Chip_DMA_GetBusyChannels(LPC_DMA) & (1 << DMA_CH0)) != 0) {} Chip_DMA_AbortChannel(LPC_DMA, DMA_CH0); Chip_DMA_ClearErrorIntChannel(LPC_DMA, DMA_CH0); Chip_DMA_EnableChannel(LPC_DMA, DMA_CH0); Board_LED_Set(0, true); } /* Clear DMA interrupt for the channel */ Chip_DMA_ClearActiveIntAChannel(LPC_DMA, DMA_CH0); dmaDone = true; } void DMA_init( void ) { DMA_CHDESC_T dmaDesc; /* DMA initialization - enable DMA clocking and reset DMA if needed */ Chip_DMA_Init(LPC_DMA); /* Enable DMA controller and use driver provided DMA table for current descriptors */ Chip_DMA_Enable(LPC_DMA); Chip_DMA_SetSRAMBase(LPC_DMA, DMA_ADDR(Chip_DMA_Table)); /* Setup channel 0 for the following configuration: - High channel priority - Interrupt A fires on descriptor completion - trigger on ACD1 seq A completion - burst size is 1 */ Chip_DMA_EnableChannel(LPC_DMA, DMA_CH0); Chip_DMA_EnableIntChannel(LPC_DMA, DMA_CH0); Chip_INMUX_SetDMATrigger(DMA_CH0, DMATRIG_ADC1_SEQA_IRQ); Chip_DMA_SetupChannelConfig(LPC_DMA, DMA_CH0, (DMA_CFG_PERIPHREQEN | DMA_CFG_HWTRIGEN | DMA_CFG_TRIGTYPE_EDGE | DMA_CFG_TRIGPOL_HIGH | DMA_CFG_BURSTPOWER_1 | DMA_CFG_CHPRIORITY(0))); /* DMA descriptor for peripheral to memory operation - note that addresses must be the END address for src and destination, not the starting address. DMA operations moves from end to start. */ dmaDesc.source = DMA_ADDR(&(LPC_ADC1->DR[ADC1_IBUS_CH])); dmaDesc.dest = DMA_ADDR(&adc_buf[SIZE_BUFFER - 1]) + 3; dmaDesc.next = DMA_ADDR(0); /* Setup transfer descriptor and validate it */ Chip_DMA_SetupTranChannel(LPC_DMA, DMA_CH0, &dmaDesc); Chip_DMA_SetValidChannel(LPC_DMA, DMA_CH0); NVIC_EnableIRQ(DMA_IRQn);// Enable DMA interrupt /* Setup data transfer and software trigger in same call */ Chip_DMA_SetupChannelTransfer(LPC_DMA, DMA_CH0, (DMA_XFERCFG_CFGVALID | DMA_XFERCFG_SETINTA | DMA_XFERCFG_WIDTH_32 | DMA_XFERCFG_SRCINC_0 | DMA_XFERCFG_DSTINC_1 | DMA_XFERCFG_XFERCOUNT(SIZE_BUFFER))); dmaDone = false; } |
/** * Init ADC1 to perform periodical reads on channels 0 and 1, whith threshold detection */ void ADC1_init( void ) { /* --- ADC Init --- */ /* Setup ADC for 12-bit mode and normal power */ Chip_ADC_Init(ADC, 0); /* Setup for maximum ADC clock rate */ Chip_ADC_SetClockRate(ADC, ADC_MAX_SAMPLE_RATE); /* For ADC1, sequencer A will be used with threshold events. It will run continuously in burst mode and will monitor the CH0 & CH1 input. */ Chip_ADC_SetupSequencer(ADC, ADC_SEQA_IDX,(ADC_SEQ_CTRL_CHANSEL(ADC1_VBUS_CH) | ADC_SEQ_CTRL_CHANSEL(ADC1_IBUS_CH) | ADC_SEQ_CTRL_BURST | ADC_SEQ_CTRL_MODE_EOS)); /* Need to do a calibration after initialization and trim */ Chip_ADC_StartCalibration(ADC); while (!(Chip_ADC_IsCalibrationDone(ADC))) {} /* ACD clock must be set after calibration !! (bug in lib) */ Chip_ADC_SetClockRate(ADC, ADC_MAX_SAMPLE_RATE); /* setup thresholds so that they are never crossed. * They will be set by application, through ADC1_set_thr(...) */ // ch 0 Chip_ADC_SelectTH0Channels(ADC, ADC_SEQ_CTRL_CHANSEL(ADC1_VBUS_CH)); Chip_ADC_SetThrLowValue(ADC, 0, 0x000); Chip_ADC_SetThrHighValue(ADC, 0, 0xFFF); // ch 1 Chip_ADC_SelectTH1Channels(ADC, ADC_SEQ_CTRL_CHANSEL(ADC1_IBUS_CH)); Chip_ADC_SetThrLowValue(ADC, 1, 0x000); Chip_ADC_SetThrHighValue(ADC, 1, 0xFFF); /* Clear all pending interrupts */ Chip_ADC_ClearFlags(ADC, Chip_ADC_GetFlags(ADC)); /* Enable sequence A completion and threshold crossing interrupts for ADC1_0 and ADC 1_1 */ Chip_ADC_EnableInt(ADC, ADC_INTEN_CMP_ENABLE(ADC_INTEN_CMP_CROSSTH, ADC1_VBUS_CH) | ADC_INTEN_CMP_ENABLE(ADC_INTEN_CMP_CROSSTH, ADC1_IBUS_CH) | ADC_INTEN_SEQA_ENABLE); Chip_ADC_SetThresholdInt(ADC, ADC1_VBUS_CH, ADC_INTEN_THCMP_CROSSING); Chip_ADC_SetThresholdInt(ADC, ADC1_IBUS_CH, ADC_INTEN_THCMP_CROSSING); // DO NOT ACTIVATE NVIC (for dma operation) //_NVIC_ClearEnableIRQ(ADC1_SEQA_IRQn); /* Enable sequencers */ Chip_ADC_EnableSequencer(ADC, ADC_SEQA_IDX); } /** * ADC Mux PIN enable */ void ADC1_init_PinMux( void ) { /* Disables pullups/pulldowns and disable digital mode */ Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 9, (IOCON_MODE_INACT | IOCON_ADMODE_EN)); Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 32+1, (IOCON_MODE_INACT | IOCON_ADMODE_EN)); /* Assign ADC1_1 to PIO0_9 via SWM (fixed pin) */ Chip_SWM_EnableFixedPin(SWM_FIXED_ADC1_0);/*!< ADC0_0 fixed pin enable/disable on pin P1_1 */ Chip_SWM_EnableFixedPin(SWM_FIXED_ADC1_1);/*!< ADC0_1 fixed pin enable/disable on pin P0_9 */ } |
Hi Tom,
Did you have success in the meantime?
I have a rather similar use case and still cannot find any examples / application notes on this topic :-(
Regards, Martin