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.

BUSY bit in ADCACTSS



Dear support.

I use Tiva4C123AH6PM whith CCS5.5

I have a stepping motor application and use two digital comparators simultaneously for current control.

Occasionally happens that a digital comparator is blocked and no longer trigger the ADC interrupt.

When this happens it the CCS reset not solve the problem, is neccessary power off !!

I do not understand why as this happens, the only thing that changes is that the BUSY bit in the register ADCACTSS is high, and rmain high forever !!!

This bit indicate that there is a conversion run, but in my case is always high.

What is this bit? What does it mean? How can I unlock it?

Thanks

Stefano

  • Hi,

    Did you tried this function from driverlib: ADCComparatorReset(…)? 

    Petrei

  • Hello Stefano,

    As you mentioned. The bit indicates when the ADC is performing a conversion.

    How are you triggering the ADC? Please take note of ADC#01 Errata.

    If it gets locked then the only way is to reset ADC and reconfigure it.

    Regards

    Amit

  • Is possible that I re-triger the ADC befor end of conversion

    The WA for errata ADC#01 is test the BUSY bit or other pending ?


    Thanks

    Stefano

  • Hello Stefano,

    Yes. Before doing a processor trigger check if the busy bit is set. if not then do a processor trigger,

    If using a timer trigger then do make sure that the time between triggers is greater than the time it takes for the ADC conversion for all the samples

    Regards

    Amit

  • Thanks very much Amit

    The #ADC1 errata lock the BUSY bit ?

    I use the processor trigger, then when I must trig using PSSI in ADCEMUX register if the BUSY is set I not trig, correct ?

    Thanks

    Stefano

  • Hello Stefano,

    That is correct.

    Regards

    Amit

  • Thanks Amit

    But . . . .  a question, if I NEED to re-triggr and the BUSY bit is high what must be do for avoid the ADC1 errata ?

    Before re-trigger I use ADCSequenceDisable and ADCComparatorIntDisable, in this way, how is possible that the BUSY is set is the sequencer is disable ?

  • Hello Stefano,

    The code should look like the following

    while(ADCBusy(ADC0_BASE);

    ADCProcessorTrigger(ADC0_BASE, (ADC_TRIGGER_SIGNAL|ADC_SEQUENCER));

    Where ADC_SEQUENCER is the Sequencer you are using.

    Regards

    Amit

  • Thanks Amit

    Sorry sorry, I was wrong.

    I use the digital comparator with ADC_TRIGGER_ALWAYS, then when I enable without start.

    The ADC01 errata i spossible also in this case ?

  • Hello Stefano,

    No, in this case it is perfectly fine that the ADC_BUSY bit is set as the ADC is always converting

    My suspicion is that you have run into the next Errata.

    ADC#04 Digital Comparator Interrupts do not Trigger or Interrupt as Expected

    To work around this one, you would need to setup the digital comparator twice, so that if the wrong code gets sampled, then the next occurrence will cause an interrupt.

    Regards

    Amit

  • I do not understand where this problem can occur.
    Also this errata could lock the BUSY?

     If i use the SS3, with only one sample, can I have the errata 3 and 4 ?

    Thanks

  • Hello Stefano,

    Earlier we were thinking that it is PROCESSOR TRIGGER being used, until a couple of posts back you mentioned it is  ALWAYS TRIGGER. Since it is ALWAYS TRIGGER, then the ADC will convert one channel and then move on to the next channel in a loop. As a result the BUSY bit when read by the CPU will always remain set as the conversion is being done continuously. To check this after running your code, please use the debugger to change the Trigger Mode to None and you should see that the BUS bit becomes 0.

    Now, to the issue you are facing. It could be possible that the previous digital comparator data may get fed to the next causing it not to give an interrupt. Hence if you have two conversions being done for the Digital Comparators in the ADCSSCTL register like

    DIGCMP0 DIGCMP1

    the please do 4 conversions such that the Digital Comparators can be triggered as following.

    DIGCMP0 DIGCMP0 DIGCMP1 DIGCMP1

    Regards

    Amit

  • Thanks for your suggestions

    I was used the SS1 whith 4 sample, but I need only one input, I used the SS1 only for avoid to enter in ADC3 errata.

    If I use the SS3 with only one sample and only one input can I avoid the ADC3 errata and avoid your hypothesis ?

    Thanks

    Stefano

  • Hello Stefano,

    Your first post mentions that you are using two digital comparators

    "I have a stepping motor application and use two digital comparators simultaneously for current control."

    I think a code post would be helpful.

    Regards

    Amit

  • Dear Amit, I insert my simplified code :

    The code continues to drive the output until it reaches the desired current (ADC1IntHandler), when the current reaches the output and the ADC are switched off, until the next pilot (SET THE OUT).

    All this is duplicated for ADC0 and ADC1

    --------------------  INIT ----------------------
        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);
        //
        // Initialize the ADC0 POLO1
        //
        HWREG(ADC0_BASE + ADC_O_IM) = 0x00;
        ADCIntDisable (ADC0_BASE, 3);
        ADCSequenceDisable(ADC0_BASE, 3);
        ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_ALWAYS, 0);
        ADCSequenceStepConfigure(ADC0_BASE, 3, 0,ADC_CTL_CH2 | ADC_CTL_END | ADC_CTL_CMP0);
    
        // Configure the comparators
        ADCComparatorConfigure(ADC0_BASE, 0, ADC_COMP_INT_HIGH_HALWAYS);		//  ADC_COMP_INT_HIGH_ONCE
        ADCComparatorRegionSet(ADC0_BASE, 0, 346, 346);
        ADCComparatorIntEnable(ADC0_BASE, 3);
        IntPendClear(INT_ADC0SS3);
        ADCComparatorReset(ADC0_BASE, 0, true, true);
        HWREG(ADC0_BASE + ADC_O_USTAT) = 0x0F;
        ADCSequenceEnable(ADC0_BASE, 3);
        ADCComparatorIntClear(ADC0_BASE, 0x08);     //Clear interrupt to proceed to  data capture
        IntEnable(INT_ADC0SS3);
    
        //
        // Initialize the ADC1 corrente POLO2
        //
        HWREG(ADC1_BASE + ADC_O_IM) = 0x00;
        ADCIntDisable (ADC1_BASE, 3);
        ADCSequenceUnderflowClear (ADC1_BASE, 3);
        ADCSequenceDisable(ADC1_BASE, 3); //It is always a good practice to disable ADC prior                                                        //to usage ,else the ADC may not be accurate                                                               //   due to previous initializations
        ADCSequenceConfigure(ADC1_BASE, 3, ADC_TRIGGER_ALWAYS, 0); //Use the 3rd Sample sequencer
        ADCSequenceStepConfigure(ADC1_BASE, 3, 0,ADC_CTL_CH3 | ADC_CTL_END | ADC_CTL_CMP0);
        // Configure the comparators
        ADCComparatorConfigure(ADC1_BASE, 0, ADC_COMP_INT_HIGH_HALWAYS);
        ADCComparatorRegionSet(ADC1_BASE, 0, 346, 346);
        ADCComparatorIntEnable(ADC1_BASE, 3);
        IntPendClear(INT_ADC1SS3);
        ADCComparatorReset(ADC1_BASE, 0, true, true);
        HWREG(ADC1_BASE + ADC_O_USTAT) = 0x0F;
        ADCSequenceEnable(ADC1_BASE, 3); //It is always a good practice to disable ADC prior                                                        //to usage ,else the ADC may not be accurate                                                               //   due to previous initializations
        ADCComparatorIntClear(ADC1_BASE, 0x08);     //Clear interrupt to proceed to  data capture
        IntEnable(INT_ADC1SS3);
    
    
    
    --------------------  SET THE OUT duplicate for ADC0 and ADC1 DURING EXTERNAL IN TERRUPT ----------------------
        // disable ADC for avoid noise
        ADCSequenceDisable(ADC0_BASE, 3);
        ADCComparatorIntDisable(ADC0_BASE, 3);
        ADCComparatorReset(ADC0_BASE, 0, true, true);
        HWREG(ADC0_BASE + ADC_O_OSTAT) = ADC_OSTAT_OV3;
        HWREG(ADC0_BASE + ADC_O_USTAT) = ADC_USTAT_UV3;
        ADCComparatorIntClear(ADC0_BASE, 0x08);     //Clear interrupt to proceed to  data capture
        IntPendClear(INT_ADC0SS3);
    
        ......
        // drive the output pin
        HWREG (GPIO_PORTA_BASE + (0x80 << 2)) = StepTable[pStepTable][POLO1];
        HWREG (GPIO_PORTF_BASE + (0x01 << 2)) = StepTable[pStepTable][POLO1];
    
        SysCtlDelay(50);            // waiting for noise
    
        // and than set ADC digital comparator
        ADCComparatorRegionSet(ADC0_BASE, 0, SogliaCorrente, SogliaCorrente);
        ADCComparatorIntClear(ADC0_BASE, 0x01);     //Clear interrupt to proceed to  data capture
        IntPendClear(INT_ADC0SS3);
        ADCIntClear(ADC0_BASE, 3);
        HWREG(ADC0_BASE + ADC_O_IM) |= 0x80000;
        ADCSequenceOverflowClear (ADC0_BASE, 3);
        ADCSequenceUnderflow (ADC0_BASE, 3);
        ADCSequenceEnable(ADC0_BASE, 3);
    
    
    --------------- DIGITAL COMPARATOR INTERRUPT equal for ADC0 and ADC1---------------
    void ADC0IntHandler(void)
    {
      uint32_t tempo;
    
      HWREG (GPIO_PORTA_BASE + (0x80 << 2)) = 0x00;            // RESET polo 1A
      HWREG (GPIO_PORTF_BASE + (0x01 << 2)) = 0x00;            // RESET polo 1B
    
      ..............................
    
    
      ADCComparatorIntDisable(ADC0_BASE, 3);
      ADCComparatorIntClear(ADC0_BASE, 0x08);     //Clear interrupt
      IntPendClear(INT_ADC0SS3);
    
    }
    

  • Hello Stefano

    Thanks for the code. I would need to study the code and then port it to the TM4C123 device to see what the issue is

    Regards

    Amit