Other Parts Discussed in Thread: HALCOGEN
Tool/software:
Hi (Jagadish),
I have been following the span227 to implement ADC with DMA. I need to get 20 samples from a specific (single) channel and store them to the RAM. To make things simpler, I started with triggering a DMA request over a single sample.
// // Inside void main() // adcInit(); adcREG1->ADG1CHNSELMODECTRL = 0x0A; // enable enhanced channel selection mode for group1 adcREG1->ADG1MAXCOUNT = 1; // 1 conversion total adcREG1->ADG1CURRCOUNT = 0; // clear group1 current_count counter adcREG1->G1DMACR = 0x09; // DMA request on group1 conversion end adcEnableNotification(adcREG1, adcGROUP1);
// // Inside void main() // dmaEnable(); dmaReqAssign(1, 10); dmaConfigCtrlPacket( ADG1_ptr, // control packet for group1 (uint32)(&adcREG1->GxBUF[1]), // group1 results FIFO (uint32)(&adc1_G1_results), // group1 results in CPU data RAM 1, // number of frames to be transferred 1, // number of elements per frame 0, // next channel to be chained, 0 = disable chaining 2, // read element size (32 bits) 2, // write element size (32 bits) 1, // transfer type = 1 ==> block transfer 0, // read addressing mode = 0 ==> fixed 1, // write addressing mode = 1 ==> post-incremented 1, // autoinit enabled 0, // read address element index offset = 0 0, // write address element index offset = 0 0, // read address frame index offset = 0 0 // write address frame index offset = 0 ); dmaSetCtrlPacket(DMA_CH1, *ADG1_ptr); dmaEnableInterrupt(DMA_CH1, BTC); dmaSetChEnable(DMA_CH1, DMA_HW);
And printing the results in a task with sufficient stack allocation:
// // Inside task // while (1) { adcStartConversion(adcREG1, adcGROUP1); printf("ADC: %u\n", adc1_G1_results[0]); vTaskDelay(xDelay); }
After playing with different number of elements per frame (1, 5, 20), I was able see with the debugger that the DMA engine transfers the requested count into the destination RAM buffer. I do not use continuous conversion - after reading the response from Sunil Oak in the following thread: e2e.ti.com/.../tms570lc4357-dma-with-adc-in-continuous-mode
Unfortunately, I get really weird results from the phototransistor on the Launchpad kit, channel 6, without changing the illumination level. I know it prints the whole uint32 including the flags and channel ID, but still quite large difference in the readings (in the context of a single constant channel). It looks as follows:
ADC: 0 ADC: 68347 ADC: 68347 ADC: 68347 ADC: 68348 ADC: 2812 ADC: 2811 ADC: 68347 ADC: 2812 ADC: 2811
I am also struggling to understand the following:
1. Neither the ADC, nor the DMA interrupt notifications get triggered. I tried not only with the HALCoGen functions (as in the above snippets), but also by assigning the proper bit field values in the INT Enable registers.
void dmaGroupANotification(dmaInterrupt_t inttype, uint32 channel) { sciSendByte(scilinREG, 'D'); return; } void adcNotification(adcBASE_t *adc, uint32 group) { sciSendByte(scilinREG, 'A'); return; }
My GIO and SCI interrupts (FIQ/IRQ) work properly (in FreeRTOS environment).
2. What is the relation between the ADC storage objects mentioned in the API and the TRM:
- (API) GxBUF[...] - array of (8 * (uint32_t)) = (8 * 4Bytes) = 32Bytes per group
- (TRM) ADC FIFO RAM - "Conversion results are stored in a 64-word memory (SRAM)." That means 64 * 4 = 256 bytes in total and ~85Bytes per group
- (TRM) "ADBNDEND contains a 3-bit field called BNDEND that configures the total memory available. The ADC
module can support up to 1024 buffers. The device supports a maximum of 64 buffers for both the ADC
modules."
3. Based on the above, what should be taken into consideration for the DMA transfer? How should the ADC FIFO be configured for optimal DMA transfer efficiency?
I hope my post is not that overwhelming, but I literally spent about a week on research and I am going nowhere.
Any other up-to-date example code will be much appreciated as well...
Thanks for the understanding and kind regards,
Varban