This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
I am seeing some issues using DMA with ADC2 configured for continuous mode. I believe this is due to some DMA channel delays/collisions. I am seeing the exact behavior described in this post:
[https://e2e.ti.com/support/microcontrollers/hercules/f/312/t/119037?TMS570-ADC-DMA]
The DMA channel 0 is configured to read from the ADC2 group fifo. ADC2 has only one group configured to trigger the DMA after 16 conversions. The DMA destination address sometimes gets conversions with the ADC result empty flag set. which implies that the DMA is reading 'too many' ADC conversion results, but this seems to be a result of the ADC conversion counter crossing the +1 to 0 threshold.
Is there any way to configure the DMA or ADC to avoid the timing issue described in the link above?
Jeremy,
Continuous conversion mode on the ADC is useful mainly for channels that are monitored using the "Magnitude threshold compare interrupt" feature of the ADC. For conversion results actually being read by the CPU or DMA this mode has issues as stated in the post you referenced.
It is recommended to set up single conversion sequences that are periodically triggered using one of the several trigger options supported.
Regards, Sunil
Hi Sunil,
Thanks for the reply. We are trying do to sinusoidal amplitude demodulation on up to 25 inputs at 8KHz every 2ms or so. Do you have any recommendations for ADC/DMA configuration for oversampling these signals?
Thanks,
Jeremy
Hi Jeremy,
The best option is to set up the same channels in multiple conversion groups and trigger then alternately (possibly with alternate edges of the same "PWM" like signal). This allows you to use the DMA to transfer data for one conversion group while the other is converting, and then switching between the two. It takes two DMA channels for this to work.
Please let me know if you need an example setup and I can make one for you (could take a couple of days).
Regards, Sunil
Hi Sunil,
An example would be great! That configuration sounds like it should work.
Thanks,
Jeremy
Hi Jeremy,
I have attached three source files and the HALCoGen project used to generate these files that you can use as reference.
Both group0 (Event group) and group1 are used to convert the same 25 channels (0 to 24), one after another. Group0 is triggered by a rising edge on the RTI compare 0 interrupt, while group1 is triggered by the falling edge of this signal. I have enabled auto-clear for the compare 0 interrupt flag so no interrupt service routine is required to continue to generate edges. I have set it up for a 100us period (50us for a sequence of 25 conversions).
The conversion results are transferred by DMA to two separate arrays in RAM. Note that no data processing is implemented in this example. You can choose to generate an interrupt to the CPU when the DMA block transfer is completed in order to process these results.6406.adc_dma.hcg0820.adc_dma.dil1452.HL_adc.c4532.HL_rti.c7612.HL_sys_main.c
Regards, Sunil
Hi Sunil,
I want to use the PWM (instead of the RTI) to trigger the SOC on the 2 ADC groups (one on rising edge and one on falling edge). If I use EPWM_B as the trigger for both ADC groups, how can I control the SOC_B pulse width? The PWM event-trigger submodule allows me to select an SOC B event trigger, but that just determines when the SOC B pulse will be generated. I don't see how the pulse width is determined, the falling edge time is important in this case since it would be the trigger for the other ADC group.
If the pulse width for SOC events is not configurable, then I think I can work around it by using 2 different SOC triggers, EPWM_B and EPWM_A1 for example, with different event trigger selections.
Hi Jeremy,
HALCoGen includes a good example for how to trigger ADC conversions using ePWM_B. You can do this by generating a 50% duty cycle signal on ePWM1B, for example. I was able to generate a signal with a 60us period, so that each half-phase is 30us wide. This provides enough time for each group to be converted and the data transferred using DMA to CPU RAM. I have attached a scope shot, showing there is time to spare, so the period could have even been shorter for the given 25 channels.
Note that I have enabled output of the ePWM1B signal (ch 3 on scope shot) as well as the AD1_EXT_ENA signal (ch 1) to their respective muxed terminals. AD1_EXT_ENA rising edge represents the start of the sampling phase for each ADC conversion.
Let me know if you have questions or trouble following the example from HALCoGen.
Regards, Sunil
Actually both the groups were triggered by the falling edge of ePWM1B in the above scope shot, so the 50 conversions are stacked back-to-back.
Regards, Sunil
Thanks Sunil,
In your example above, I would like to trigger group 1 on the rising edge and group 2 on the falling edge of the PWM signal. Is that possible with the PWM SOC pulse? or would I have to use a HW trigger and connect the PWM output pin to the ADC SOC pin?
I need a constant time between the start of conversion of each ADC group.
Jeremy,
Yes, this is easy to set up as well. The ePWM SOCx signals are different from the normal PWM outputs, so you cannot use both edges of this signal to trigger two separate ADC groups with configurable timing. Instead, you can use SOCA to trigger one group and SOCB to trigger another group. I will try this tomorrow and let you know.
Regards, Sunil
Attached is a scope shot using ePWM_A1 to trigger group0 and ePWM_B to trigger group1, each group configured to convert the same 25 channels. SOCA is generated when the TBCTR = CMPA and SOCB is generated when TBCTR = PRD, to line up with the rising and falling edges of the PWM output.
I am also attaching the relevant HCG files for reference.
Regards, Sunil
Hi Sunil,
Are you able to attach your user code that generated the scope plot above with your attached halcogen project? My coworker and I are encountering some issues with our implementation. Our DMA buffers are sometimes filled with junk/offset data from the sinusoidal ADC input, other times the data looks correct. We are using a PWM of 30KHz and triggering the 25 channel samples on each edge using SOC A1 and SOC B to trigger ADC groups 1 and 2 respectively (we are not using the event group like your halcogen project). We are unable to see the AD1_EXT_ENA pin output, even though we have set the IOMM settings for pin G16 and V8 to the AD1_EXT_ENA setting.
Hi Jeremy,
I am usually hesitant to upload complete code projects, but will do so in this case. I am attaching the zipped CCS project. Note that I have enabled only V8 to output the AD1EXT_ENA signal, as you only need one terminal to output.
Also note that the PWM frequency I have used is almost half of what you are using. I have a ePWM_A period of 60us, which would be a 16.67KHz PWM. Each edge of this PWM triggers conversion of 25 ADC inputs, so both Event group and Group1 are used to convert the same 25 channels. The channel sampling frequency is ~33KHz.
Sampling of the 25 channels takes about 22.6us as reported by HCG and confirmed by the scope shot. So there is a 7.4us delay between end of the first sampling group and the next, which could be filled in by using a slightly faster PWM. However, there is not enough slack to double the PWM frequency. This may be why you are seeing multiple conversion groups triggered at the same time.
Hope this helps.1512.LC43_ePWM_ADC.zip
Regards, Sunil