I'm using the TM4C1233H6PM and attempting to use the built in digital comparators to alert me when either a high or low threshold is crossed on three different analog accelerometer channels. The following code is a very much simplified example code from my application. You can assume all peripherals are being enabled correctly prior to the following code being executed. This is because if I use only a single channel and two digital comparators to watch for low or high thresholds it works correctly. This includes any combination of comparators and channels. However the following does not work it will always tell me comparator 0 and 1 are triggered despite the stimulus. Any help would be much appreciated.
ADCSequenceDisable( ADC0_BASE, 0 ); // Set up the ADC trigger to be from the processor (software) ADCSequenceConfigure( ADC0_BASE, 0, ADC_TRIGGER_ALWAYS, 0 ); // Set up the ADC interrupt steps ADCSequenceStepConfigure( ADC0_BASE, 0, 0, XOUT_CHANNEL | ADC_CTL_CMP0 ); ADCSequenceStepConfigure( ADC0_BASE, 0, 1, XOUT_CHANNEL | ADC_CTL_CMP1 ); ADCSequenceStepConfigure( ADC0_BASE, 0, 2, YOUT_CHANNEL | ADC_CTL_CMP2 ); ADCSequenceStepConfigure( ADC0_BASE, 0, 3, YOUT_CHANNEL | ADC_CTL_CMP3 ); ADCSequenceStepConfigure( ADC0_BASE, 0, 4, ZOUT_CHANNEL | ADC_CTL_CMP4 ); ADCSequenceStepConfigure( ADC0_BASE, 0, 5, ZOUT_CHANNEL | ADC_CTL_CMP5 | ADC_CTL_END ); // Configure the comparators ADCComparatorConfigure( ADC0_BASE, 0, ADC_COMP_INT_LOW_ONCE ); ADCComparatorConfigure( ADC0_BASE, 1, ADC_COMP_INT_HIGH_ONCE ); ADCComparatorConfigure( ADC0_BASE, 2, ADC_COMP_INT_LOW_ONCE ); ADCComparatorConfigure( ADC0_BASE, 3, ADC_COMP_INT_HIGH_ONCE ); ADCComparatorConfigure( ADC0_BASE, 4, ADC_COMP_INT_LOW_ONCE ); ADCComparatorConfigure( ADC0_BASE, 5, ADC_COMP_INT_HIGH_ONCE ); ADCComparatorRegionSet( ADC0_BASE, 0, 1000, 3000 ); ADCComparatorRegionSet( ADC0_BASE, 1, 1000, 3000 ); ADCComparatorRegionSet( ADC0_BASE, 2, 1000, 3000 ); ADCComparatorRegionSet( ADC0_BASE, 3, 1000, 3000 ); ADCComparatorRegionSet( ADC0_BASE, 4, 1000, 3000 ); ADCComparatorRegionSet( ADC0_BASE, 5, 1000, 3000 ); // Enable each ADC sequence ADCSequenceEnable( ADC0_BASE, 0 ); while( true ) { uint32_t intStatus = ADCComparatorIntStatus( ADC0_BASE ); if( intStatus != 0 ) { ADCComparatorIntClear(ADC0_BASE, intStatus); } }
Also, while debugging this problem I found what I believe to be an error in TivaWare 2.0.1xxxx. There is an assert check if the comparator value is less than 1024 but the actual check should be against 4096. I believe this was not updated since stellaris which had 10 bit ADC's vs. the Tiva 12 bit ADC's.
void ADCComparatorRegionSet(uint32_t ui32Base, uint32_t ui32Comp, uint32_t ui32LowRef, uint32_t ui32HighRef) { // // Check the arguments. // ASSERT((ui32Base == ADC0_BASE) || (ui32Base == ADC1_BASE)); ASSERT(ui32Comp < 8); ASSERT((ui32LowRef < 1024) && (ui32LowRef <= ui32HighRef)); ASSERT(ui32HighRef < 1024); // // Save the new region settings. // HWREG(ui32Base + ADC_O_DCCMP0 + (ui32Comp * 4)) = ((ui32HighRef << 16) | ui32LowRef); }