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.

LP-MSPM0G3507: ADC DMA Measuring PWM Amplitude - positive and negative

Part Number: LP-MSPM0G3507
Other Parts Discussed in Thread: MSPM0G3507, SYSCONFIG

Tool/software:

I would like to measure RED and GREEN points separately coming from the same ADC channel on the launchpad. Frequency of signal is fixed, always 1kHz, duty cycle varies from 10% to 90%.

Ideally, all RED samples are grouped together in one array, and all GREEN signals are grouped together in one array. In this case, i would every 100 periods, in this case 100ms, process them and find out what was the average positive and average negative amplitude for last 100 periods.

How to do this using MSPM0G3507, with least CPU intervention? I can oversample x20 probably get the accurate enough result for what I need, but this would interrupt CPU quite a lot.

In case one DMA signal is used I would have RED and GREEN in same array without nice way of filtering positives together and negatives together, as noise could be induced causing this logic to fail.

  • Hi Predrag,

    Is the signal on the pin going to have varying high / low voltages with each pulse, or is it a binary 3.3V and 0V?

    I ask because it seems like you're just trying to measure the duty cycle on a square wave input, in which case you could utilize a timer peripheral in capture mode to measure the time between each rising and falling edge. Then you'd save on power consumption and be able to measure the high vs low time quite easily. If this is the case I'd encourage you to look at the capture duty cycle example in our SDK, found at [SDK Install Path]\examples\nortos\LP_MSPM0G3507\driverlib\timx_timer_mode_capture_duty_and_period

    If the high and low levels are changing, you could set an ADC to continuously sample the signal, and utilize the window comparator mode in order to indicate if the sample is above or below a set threshold. Then you could use these interrupts to populate a memory buffer. You could also consider using DMA to transfer the data into the buffer to reduce CPU activity.  For this I'd recommend starting with the window comparator mode in the ADC - found at [SDK Install Path]\examples\nortos\LP_MSPM0G3507\driverlib\adc12_window_comparator

  • Hi Dylan.

    First of all, thank you for quick feedback.

    Let me clarify a bit further, high and low levels are changing in terms of amplitude, whilst still being PWM signals with modulated amplitude.

    They can be 3.3-0-3.3-0 or they can be 3.1-0-3.1-0 or 3.3-0.5-3.3-0.5, so both high level and low level voltage values can change.

    We can assume that 0.5*3.3V is a safe threshold for comparator, as in no high amplitude will go below 0.5*3.3V nor will low level amplitude go above 0.5*3.3V.

    Unsure about what you meant with window comparator ADC mode. Here is a block diagram of ADC on M0G family:

    ADC would generate DATAOUT which will update one of the MEMRES and windows comparator can compare that result against the threshold, and then what? Slight smile

    I can't trigger DMA, I can GEN_EVENT in case of HIGH that will start sampling and generate the DMA transfer to a ARRAY1(lets say containing high values, red dots on the plot), and in case of LOW change the DMA address(I need CPU for this?) to store low values to ARRAY2(containing low values, green dots on the plot)?

  • Hi Predrag,

    For information on ADC Window Comparator mode, please see section 12.2.12.2 Window Comparator in the G Series TRM

    You may also want to take a look at the IO characteristics in section 7.10 of the device datasheet, specifically at the high level and low level input voltage thresholds, which are 0.7*VDD and 0.3*VDD respectively. With this in mind, along with the possible voltages you mentioned above, you may not need an ADC or comparator at all to get the information you mention.

    You may be able to accomplish this just using a timer to sample the input to a GPIO pin every x microseconds to then calculate the duty cycle.

    I still think the easiest thing to do would be to adapt that timer duty cycle and period example to save a series of duty cycles, average them, then use that value. Considering the expected input voltages and high/low thresholds mentioned above, I think this should work fine and would allow you to put the device into low power mode except waking up to save the duty cycle and change the trigger to/from rising and falling edge.

    If the signal waveform will go between 0.3*VDD and 0.7*VDD, then you'd need to use the ADC window comparator mode. In this case you could set the window comparator's high and low thresholds as needed, then use that interrupt to save each sample that is high or low to a buffer. Potentially you could use two DMA channels to save these to a buffer while remaining asleep then wake the device after 1000 samples to calculate duty cycle, perform some action, then repeat. You are able to generate events for when a given ADC channel samples above or below the window comparator threshold (and can easily configure this in sysconfig), so that should not be too difficult. This may be the preferred option anyways as this option allows you to leave the device asleep for multiple periods of the input signal and wake up when you want to after a certain amount of time or number of periods. The other method with the timer requires you to briefly wake up every period.

    There are probably more options, including using the comparator, but the two listed above are not too hard to implement and allow the CPU to remain inactive for a good portion of operation.

  • Hi Dylan

    Maybe you misunderstood, but there is no requirement to measure duty cycle at all. I need to know the Voltage value in each of the half-cycle.


    So far, after digging a bit more, here is what I have been thinking of, so maybe you can help and cross-check. 

    The PWM signal output will be generated by TIMA0, in centre-aligned mode allowing same source to trigger on the ADC - in this case of a LOAD event is a centre point of positive half-cycle, and ZERO event is centre point in negative half-cycle. I would then setup the averaging mode to sample N times and then right shift accordingly to get the correct average value. With this I can collect 2 samples per one period, and can transfer this to memory block by using DMA. I could set destination block as a size of 2*50*16bit and when that has been filled, I will interrupt the processor to process the results and tell me the average positive half-cycle amplitude, and average negative half-cycle amplitude, in the last 50 cycles. There is, as I said, no need to measure any period/duty cycles here, I only care about the amplitude as this is where the information is.

  • Ah yes I must've misunderstood the first time around. Thanks for clarifying.

    Your proposed solution here sounds like it should address the problem statement well. The only thing that I want to point out is that the hardware averaging will populate the ADC MEMRES with the averaged value, so you shouldn't need to manually sample and then right shift, you can set the sampling rate + HW averaging mode, then the result the ADC finds will be the averaged value. 

    Or of course you can just manually perform the averaging as you mention.

    Glad you found a suitable procedure here, feel free to create a new thread if you have an implementation issue.