mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
cpu/stm32/periph_adc: fix register access
The register access to SMPR1/SMPR2 was incorrect in three aspects: 1. For channels < 10, SMPR1 was cleared but SMPR2 should have been cleared 2. The code was not thread-safe 3. An unneeded write was issued. (The compiler won't combine the in-place bitwise operations into a single read-modify-write sequence on `volatile` memory.) Fixes https://github.com/RIOT-OS/RIOT/issues/20261
This commit is contained in:
parent
e2e5c3a834
commit
4ed287cec8
@ -20,10 +20,11 @@
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "irq.h"
|
||||
#include "mutex.h"
|
||||
#include "periph/adc.h"
|
||||
#include "periph_conf.h"
|
||||
#include "periph/vbat.h"
|
||||
#include "periph_conf.h"
|
||||
|
||||
/**
|
||||
* @brief Maximum allowed ADC clock speed
|
||||
@ -100,14 +101,20 @@ int adc_init(adc_t line)
|
||||
}
|
||||
ADC->CCR = ((clk_div / 2) - 1) << 16;
|
||||
/* set sampling time to the maximum */
|
||||
unsigned irq_state = irq_disable();
|
||||
if (adc_config[line].chan >= 10) {
|
||||
dev(line)->SMPR1 &= ~(MAX_ADC_SMP << (3 * (adc_config[line].chan - 10)));
|
||||
dev(line)->SMPR1 |= MAX_ADC_SMP << (3 * (adc_config[line].chan - 10));
|
||||
uint32_t smpr1 = dev(line)->SMPR1;
|
||||
smpr1 &= ~(MAX_ADC_SMP << (3 * (adc_config[line].chan - 10)));
|
||||
smpr1 |= MAX_ADC_SMP << (3 * (adc_config[line].chan - 10));
|
||||
dev(line)->SMPR1 = smpr1;
|
||||
}
|
||||
else {
|
||||
dev(line)->SMPR1 &= ~(MAX_ADC_SMP << (3 * adc_config[line].chan));
|
||||
dev(line)->SMPR2 |= MAX_ADC_SMP << (3 * adc_config[line].chan);
|
||||
uint32_t smpr2 = dev(line)->SMPR2;
|
||||
smpr2 &= ~(MAX_ADC_SMP << (3 * adc_config[line].chan));
|
||||
smpr2 |= MAX_ADC_SMP << (3 * adc_config[line].chan);
|
||||
dev(line)->SMPR2 = smpr2;
|
||||
}
|
||||
irq_restore(irq_state);
|
||||
/* free the device again */
|
||||
done(line);
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user