arduino / ArduinoCore-sam

80 stars 107 forks source link

adc_configure_trigger bug #130

Open avsteele opened 2 years ago

avsteele commented 2 years ago

in adc.c

the library code:

/**
 * \brief Configure conversion trigger and free run mode.
 *
 * \param p_adc Pointer to an ADC instance.
 * \param trigger Conversion trigger.
 * \param uc_freerun ADC_MR_FREERUN_ON enables freerun mode,
 * ADC_MR_FREERUN_OFF disables freerun mode.
 *
 */
void adc_configure_trigger(Adc *p_adc, const enum adc_trigger_t trigger,
        uint8_t uc_freerun)
{
    //Warning ADC_MR_TRGSEL_Msk does not include ADC_MR_TRGEN.
    p_adc->ADC_MR &= ~(ADC_MR_TRGEN | ADC_MR_TRGSEL_Msk | ADC_MR_FREERUN); //Clear all bits related to triggers and freerun

    //Configure FreeRun
    if(uc_freerun & ADC_MR_FREERUN == ADC_MR_FREERUN_ON) {                 //FreeRun is enabled
        p_adc->ADC_MR |= ADC_MR_FREERUN_ON;

        //Free Run Mode: Never wait for any trigger
        //No need to continue and enable hardware triggers
        return;
    }

    //Configure hardware triggers
    if(trigger & ADC_MR_TRGEN == ADC_MR_TRGEN_EN) {                       //Hardware trigger is enabled
        p_adc->ADC_MR |= (trigger & ADC_MR_TRGSEL_Msk) | ADC_MR_TRGEN_EN; //Set trigger selection bits and enable hardware trigger
    }
}

...will not enable frerrun if passed ADC_ML_FREERUN_ON (0x1u<<7). Because == has higher precedence than & The function will enable freerun only when passed 1. It will not enable freerun when passed ADC_MR_FREERUN_ON .

The corrected line can simply be

if(uc_freerun == ADC_MR_FREERUN_ON) ...

Which is probably the desired behavior according to the documentation, but may break existing usage. Alternatively

if(uc_freerun != ADC_MR_FREERUN_OFF) ...

will enable freerun when passing anything other than ADC_FREERUN_OFF.