2024-02-27 02:27 PM
I'm seeing strange behavior trying to write to the ADC1_JSQR register. This register controls the channel sequence and the trigger source of injected conversions. After enabling the ADC (ADEN=1), a write to bits 7:0 (JEXTEN, JEXTSEL & JL) locks out further writes to ADC1_JSQR so that subsequent writes are ignored. Writes from both C and gdb seem to exhibit the same behavior.
Paragraph 15.3.10 "Constraints when writing the ADC control bits" in RM0365 makes me wonder if writing to the ADC registers in the wrong order. For all bit fields in ADC1_JSQR, the manual states:
Note: Software is allowed to write these bits at any time, once the ADC is enabled (ADEN=1).
I have two Nucleo-F302R8 boards and both work the same.
Is this a hardware bug or am I doing something wrong?
static void setup_adc(uint32_t adc)
{
uint8_t regular_sequence[] = { 6, 7, 6, 8, 6, 16, 6, 18 };
uint8_t injected_sequence[] = { 7, 7, 7, 7 };
adc_power_off(adc);
adc_enable_temperature_sensor(); // CCR
adc_set_clk_prescale(adc, ADC_CCR_CKMODE_DIV2); // CCR
adc_set_single_conversion_mode(adc); // CFGR1(CONT) = ~CONT
adc_calibrate(adc); // CR(ADCAL) = 1
adc_power_on(adc); // CR(ADEN) = 1
adc_set_resolution(adc, ADC_CFGR1_RES_12_BIT); // CFGR1
adc_set_sample_time_on_all_channels(adc, ADC_SMPR_SMP_19DOT5CYC ); // SMPR1 & SMPR2
adc_enable_dma_circular_mode(adc); // CFGR1(DMACFG) = 1
adc_set_right_aligned(adc); // CFGR1(ALIGN) = 0
adc_enable_dma(adc); // CFGR1(DMAEN) = 1
adc_enable_external_trigger_regular(adc, // CFGR1(EXTSEL,EXTEN)
ADC_CFGR1_EXTSEL_VAL(13), 1<<10 ); // TIM6; rising edge
adc_set_regular_sequence(adc, ADC_CHAN, regular_sequence); // SQRx
adc_set_injected_sequence(adc, 4, injected_sequence); // JSQR(JL) = 4
adc_enable_external_trigger_injected(adc, // JSQR(JEXTSEL,JEXTEN)
ADC_JSQR_JEXTSEL_EVENT_1, // TIM1_OC4REF event
ADC_JSQR_JEXTEN_FALLING_EDGE );
}