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.

MSP430FR5969: ADC12SC is not reset automatically after PUC

Part Number: MSP430FR5969


Note: This is a follow up to expand on the 'related question' which discusses a problem where the ADC module stops working despite being configured in repeat-sequence-of-channels. I no longer believe that ADC42 from the device errata explains the behavior.

Behavior
While doing system testing, I discovered that I was able to reproduce the ADC freeze consistently by inducing PUCs with watchdog trips and MPU violations. Now that I was able to reproduce the problem, I used GDB to monitor the ADC12CTL0, ADC12CTL1, ADC12CTL2, and ADC12CTL3 before, during, and after a PUC reset in order to identify the issue. The only difference occurs in ADC12CTL0 with the ADC12SC bit.

ADC config & init
My ADC init process includes the following:

/* adc control register config */
ADC12CTL0 = 0;                 // Disable ADC, Enable config
ADC12CTL0 |= ADC12SHT1_2;      // 16 ADC12CLK cycles (ADC12MEM8 - ADC12MEM23)
ADC12CTL0 |= ADC12SHT0_2;      // 16 ADC12CLK cycles (ADC12MEM0 - ADC12MEM7, ADC12MEM24 - ADC12MEM31)
ADC12CTL0 |= ADC12MSC;         // Multiple sample and conversion mode
ADC12CTL0 |= ADC12ON;          // Turn on ADC

/* ... config for other ADC12CTLs and ADC12MCTLs ... */

/* Enable ADC conversions, Start ADC conversions */
ADC12CTL0 |= ADC12ENC | ADC12SC;


The board init process passes through this init regardless of the source of the reset. This means that whether the reset was caused by a PUC or BOR, the config is the same. And indeed, in all cases the first 5 lines produce the same result. The ADC12CTL0 register is set to 0 and then configured to 0010001010010000.

Error Mechanism
The error is produced in the last line of the config when the ADC is enabled and conversions are started.

ADC12CTL0, normal operation:        0010001010010010
ADC12CTL0, error mode operation: 0010001010010011

After a variable number of PUCs (usually 1-3), the ADC12SC bit is not reset after being toggled high despite the user guide stating that ADC12SC is reset automatically:

Conclusion
The observed ADC module "freeze" has been observed on multiple MSP430FR5969s and is caused by the ADC12SC bit. The ADC12SC bit fails to reset automatically after a PUC reset. Any insight into what might cause this would be appreciated.

  • Update
    There is more to the ADC freeze problem than the ADC12SC bit being stuck high. I added the following to my ADC config:

    /* Enable ADC conversions, Start ADC conversions */
    ADC12CTL0 |= ADC12ENC | ADC12SC;
    ADC12CTL0 &= ~ADC12SC;

    I confirmed that this sets the SC bit low like it should be but it does not fix the ADC freeze.

  • Is the initial "ADC12CTL0 = 0; " really working, i.e. does CTL0 end up 0?

    I'm pretty sure the ADC12 keeps running through a PUC. If it happens to be active at the moment you are trying to initialize it, clearing ENC doesn't stop it immediately [Ref UG (SLAU367O) Sec 34.2.8.6]. Also, as I recall you have to set ENC=0 as a separate step before you can set e.g. ON=0.

    Part of the "heavy hammer" sets CONSEQ=0. I don't have my code here, but as I recall I ended up with something like "CTL0=0;CTL1=0;CTL0=0;" or maybe vice versa.

  • I should have made that more clear in my post. ADC12CTL0 does indeed work consistently. I checked it in GDB immediately before and after the operation.

    That's a really interesting point about it being actively running while trying to reinit. I'll dig into that section now. Thanks for the quick response.

  • *ADC12CTL0 = 0* does indeed work consistently... quarantine must be getting to me...

  • Update

    I've been investigating whether the information in section about stopping conversions recommended by Bruce could be used to solve the problem. The section states the following:

    Solution 1
    I first tried resetting ADC12ENC at the top of my ADC init. This improved but did not fix the problem. Instead of freezing after 1-2 PUCs, the ADC freezes after 5-10 PUCs usually.

    Solution 2
    I then tried setting CONSEQx=0 and resetting ADC12ENC and ADC12ON. This similarly improved but did not fix the problem.

    ADC12CTL1 &= ~(ADC12CONSEQ0_L | ADC12CONSEQ1_L);
    ADC12CTL0 &= ~(ADC12ENC | ADC12ON);

    Solution 3
    Just to cover my bases I added ADC12SC. Same result as the first two.

    ADC12CTL1 &= ~(ADC12CONSEQ0_L | ADC12CONSEQ1_L);
    ADC12CTL0 &= ~(ADC12ENC | ADC12ON);

    I'm not really sure what to do next. The registers seem to be set properly but stopping the ADC before reinit does not prevent the ADC freeze.

  • Solution 3 should read

    ADC12CTL1 &= ~(ADC12CONSEQ0_L | ADC12CONSEQ1_L);
    ADC12CTL0 &= ~(ADC12ENC | ADC12ON | ADC12SC);

    This ADC is getting the best of me ¯\_(ツ)_/¯

  • Hey Mike,

    Unfortunate issue.  I was just looking through the errata document, and it seems there are several errata's with this specific ADC that result in  "ADC stop sampling" or "subsequent conversions halted."    I'm guessing the behavior you are seeing is coming from some of these errata or a combination of them. Looks like ADC38 and ADC42 cause the module to stop, but say they can be recovered by resetting the ADC module.  ADC66 and ADC69 do not seem to be recoverable (outside of a power cycle.)

    For ADC42 specifically, it states that you can recover from a "conversion halt" by disabling the ADC module and then re-enabling it. Have you tried doing this periodically in the code to see if it recovers the ADC once in this failed state?   Did this work?   

    But, becareful toggling ADCON for ADC42 workaround as this could also trigger ADC66.  ADC66 states "ADC stops converting when the ADC12ON bit is toggled during conversion"  during a few ADC modes including repeat-sequence.  ADC66 seems like a somewhat likely culprit to me since this errata seems like it would require a power cycle.  

    So, I wonder if your software resets are triggering this errata somehow since it never seems to happen at initial power-up... Honestly, I'm not quite sure how to exactly test this.  

    Maybe you can try a quick test on your setup.  Can you try forcing the conversion to stop before resetting?  (You included the instructions to do this is a previous post.)

    Other related questions:

    Is this always happening with the programmer connected or is this been somehow detected with the device running standalone?  

    What about clocking the ADC?  Are you sourcing the module from the ADC_osc or something else?  (errata ADC69)

    Thanks,

    JD

  • Thanks for investigating, your advice helped me resolve the problem. After reviewing the documentation, I agree that ADC66 is the cause and that the PUC reset caused ADC12ON to be set low during an active conversion. I wouldn't have expected the ADC to remain active during a reset, but the behavior fits with my observations now that I know. I followed the suggestions in the device errata and added this code to the beginning of my adc init:

    ADC12CTL0 &= ~ADC12ENC;       // disable conversions
    while(ADC12CTL1 & ADC12BUSY); // wait for active conversion to finish 

    This workaround seems to have totally resolved the problem!

**Attention** This is a public forum