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.

MSPM0G3507: Change ADC Timer Trigger event in runtime

Part Number: MSPM0G3507

Hello Support team,

I am using ADC in repeat sequence mode with DMA(FIFO_EN).

Conversion is being triggered by pwm timer. and i want to change trigger event between different CCx events in runtime, but i am facing ADC overflow/underflow interrupts when i am changing ADC trigger event at runtime.

Can you mention the correct smooth sequence to execute this transitions?

Regards,

  • This is a event switch sequence that I am using for switch event between COMP and GPIO:

    Disable all event, then switch, then enable all event.

                    /**
                     * Strictly forbidden to modify the switching code sequence below.
                     * Or will cause the Event switching to fail.
                     * 1. Close all Event channel by disable and set event = 0.
                     * 2. Switch GPION and GPIOP's event line.
                     * 3. Recovery all event channel
                     */
                    DL_COMP_disableEvent(COMP_0_INST, (DL_COMP_EVENT_OUTPUT_EDGE));
                    DL_TimerG_disableEvent(DEADBAND_INST, DL_TIMERG_EVENT_ROUTE_1, (DL_TIMERG_EVENT_CC0_DN_EVENT));
                    DL_COMP_setPublisherChanID(COMP_0_INST, 0);
                    DL_TimerG_setSubscriberChanID(DEADBAND_INST, DL_TIMER_SUBSCRIBER_INDEX_0, 0);
                    DL_TimerG_setPublisherChanID(DEADBAND_INST, DL_TIMERG_PUBLISHER_INDEX_0, 0);
                    DL_GPIO_setSubscriberChanID(GPIO_PWM_PORT, DL_GPIO_SUBSCRIBER_INDEX_1, 0);
                    DL_GPIO_setSubscriberChanID(GPIO_PWM_PORT, DL_GPIO_SUBSCRIBER_INDEX_0, 0);
                    DL_GPIO_configSubscriber(GPIO_PWM_PORT,
                                             DL_GPIO_SUBSCRIBER_INDEX_0,
                                             DL_GPIO_SUBSCRIBER_OUT_POLICY_SET,
                                             DL_GPIO_SUBSCRIBER0_PIN_12);
                    DL_GPIO_setSubscriberChanID(GPIO_PWM_PORT,
                                                DL_GPIO_SUBSCRIBER_INDEX_0,
                                                GPIOA_EVENT_SUBSCRIBER_1_CHANNEL);
                    DL_GPIO_configSubscriber(GPIO_PWM_PORT,
                                             DL_GPIO_SUBSCRIBER_INDEX_1,
                                             DL_GPIO_SUBSCRIBER_OUT_POLICY_CLEAR,
                                             DL_GPIO_SUBSCRIBER1_PIN_28);
                    DL_GPIO_setSubscriberChanID(GPIO_PWM_PORT,
                                                DL_GPIO_SUBSCRIBER_INDEX_1,
                                                GPIOA_EVENT_SUBSCRIBER_0_CHANNEL);
                    DL_TimerG_setPublisherChanID(DEADBAND_INST, DL_TIMERG_PUBLISHER_INDEX_0, DEADBAND_INST_PUB_0_CH);
                    DL_TimerG_setSubscriberChanID(DEADBAND_INST, DL_TIMER_SUBSCRIBER_INDEX_0, DEADBAND_INST_SUB_0_CH);
                    DL_COMP_setPublisherChanID(COMP_0_INST, COMP_0_INST_PUB_CH);
                    DL_TimerG_enableEvent(DEADBAND_INST, DL_TIMERG_EVENT_ROUTE_1, (DL_TIMERG_EVENT_CC0_DN_EVENT));
                    DL_COMP_enableEvent(COMP_0_INST, (DL_COMP_EVENT_OUTPUT_EDGE));

    Can you mention the correct smooth sequence to execute this transitions?

    At least, you need to stop ADC manually and then switch event, then enable the trigger source.

    Or if you don't want to disable ADC, you need to find a timing that ADC conversion is done, then disable ADC and switch event.

  • At least, you need to stop ADC manually and then switch event, then enable the trigger source.

    Or if you don't want to disable ADC, you need to find a timing that ADC conversion is done, then disable ADC and switch event.

    How to detect ADC is done, i see BUSY flag always true once ADC is enabled.

    I have tried the following but still facing overflow.

    		DL_TimerA_disableEvent(PWM_0_INST, DL_TIMERG_EVENT_ROUTE_1, (ALL_EVENTS));
    		DL_TimerA_setPublisherChanID(PWM_0_INST,DL_TIMERA_PUBLISHER_INDEX_0, 0);
    
    		DL_ADC12_setPublisherChanID(ADC12_1_INST,0);
    		DL_ADC12_setSubscriberChanID(ADC12_0_INST,0);
    		DL_ADC12_setSubscriberChanID(ADC12_1_INST,0);
    
    		DL_ADC12_setSubscriberChanID(ADC12_0_INST,ADC12_0_INST_SUB_CH);
    		DL_ADC12_setSubscriberChanID(ADC12_1_INST,ADC12_1_INST_SUB_CH);
    		DL_ADC12_setPublisherChanID(ADC12_1_INST,ADC12_1_INST_PUB_CH);
    
    		DL_TimerA_setPublisherChanID(PWM_0_INST,DL_TIMERA_PUBLISHER_INDEX_0, PWM_0_INST_PUB_0_CH);
    		
    		DL_TimerA_enableEvent(PWM_0_INST, DL_TIMERA_EVENT_ROUTE_1, (DL_TIMERA_EVENT_CCx_UP_EVENT));

    ALL_EVENTS is 0xFFFFFFFF

    Regards,

  • I am using ADC in repeat sequence mode with DMA(FIFO_EN).

    In repeat mode, ADC won't stop unless you stop and disable conversion manually.

    Or if you are using event triggered repeat mode, you need stop event source and then wait for conversion done (memory RIS set), this is more elegant.

    You can even violently stop ADC directly, and wait for busy bit clear.

    But please notice, after start conversion, busy bit need 14 ULPCLKs to set, and then after conversion finished, busy cleared.

    ADC conversion time: 12 bit mode takes about 200ns finished conversion + your sampling time set in syscfg.

  • So what options i do have with the mentioned setup?

    ADC Sequence Repeat Mode + DMA, Triggered by TIMA CCx UP event, how to switch between these events without facing over/underflow errors?

  • Stop timer first, then wait for ADC busy = 0, DMA will read ADC result, then switch event.

    This will be my plan.

  • -Disable/Enable conversion doesn't clear busy flag for some reason (SW stuck in this while loop).

    -Also if Busy status is ignored and in addition to delay caused by disable/re-enable ADC conversion i can see underflow/overflow events after re-enable ADC/Events don't know why.

    So do you have any other options?

  • What's kind of ADC result read function are you using?

    Usually, if ADC conversion is running, then wait for corresponding CPU_INT_RIS bit, when conversion done, then read the ADC result.

  • I am using DMA so i just read the data from RAM buffers after receiving DMA_DONE ADC interrupt

  • can you share your syscfg with me? Need to check your ADC event detailed config.

    And it better to tell me how you use ADC, Timer, DMA with event trigger.

  • Sure, but how we can move this to be by email or something? not sure i can share this data here.

  • Seems your function is one PWM trigger, a sequence of ADC channel converted, then a DMA done triggered.

    Stop PWM

    if adc is converting,

        then wait for both ADC0 and ADC1 DMA done

    then switch event

    This doesn't work?

    Another question:

    You enable PWM channel 1, 2, and 3.

    But enable PWM event CC0 and CC1 up.

  • Stop PWM

    Do i need to stop the PWM not just the event?

    if adc is converting,

        then wait for both ADC0 and ADC1 DMA done

    How to check if conversion currently ongoing? as i mentioned BUSY flag is always set once conversion is enabled in startup and is not cleared even when all trigger events are disabled.

    Another question:

    You enable PWM channel 1, 2, and 3.

    But enable PWM event CC0 and CC1 up.

    CC0 is just mistake, it is already dimmed in syscfg as it is not used, it was workaround extra channel i set as fixed trigger source and changed its PWM value in runtime to avoid changing ADC trigger source's issue mentioned.

    And Changing trigger source between 1,2,3 is done by software not in syscfg:

    DL_TimerA_disableEvent(PWM_0_INST, DL_TIMERA_EVENT_ROUTE_1, 0xFFFFFFFF);

    DL_TimerA_enableEvent(PWM_0_INST, DL_TIMERA_EVENT_ROUTE_1,DL_TIMERA_EVENT_CCx_UP_EVENT);     where x is {1,2,3}
  • Do i need to stop the PWM not just the event?

    Just need to avoid using PWM trigger ADC anymore, usually, just stop PWM's counter is OK.

    How to check if conversion currently ongoing? as i mentioned BUSY flag is always set once conversion is enabled in startup and is not cleared even when all trigger events are disabled.

    Busy flag.

    But from your feedback, it shouldn't.

    You max ADC conversion time should be within 5us (actually ADC1 conversion time is about 2.7us), there is enough time for ADC to finish conversion.