Hi!
I’m working on a project and am wondering how Klipper handles pins that are connected to three ADC channels (e.g. ADC123_IN11). Particularly, using this datasheet, page 47, say I have the following pinout:
Sensor 1 → PC1/ADC123_IN11
Sensor 2 → PC2/ADC123_IN12
Sensor 3 → PC3/ADC123_IN13
Can I simply setup that pin (PC1/2/3) as an ADC in Klipper and read from it? Or do I have to somehow tell Klipper which ADC channel to use?
Any help would be appreciated!
IIRC, it is solved underneath.
// Try to sample a value. Returns zero if sample ready, otherwise
// returns the number of clock ticks the caller should wait before
// retrying this function.
uint32_t
gpio_adc_sample(struct gpio_adc g)
{
ADC_TypeDef *adc = g.adc;
uint32_t sr = adc->SR;
if (sr & ADC_SR_STRT) {
if (!(sr & ADC_SR_EOC) || adc->SQR3 != g.chan)
// Conversion still in progress or busy on another channel
goto need_delay;
// Conversion ready
return 0;
}
// Start sample
adc->SQR3 = g.chan;
adc->CR2 = ADC_CR2_SWSTART | CR2_FLAGS;
need_delay:
ADC internally polled for the data; there is no stream/continuous conversion.
And high-level code simply schedules the queries:
uint32_t rest_time, sample_time, next_begin_time;
uint16_t value, min_value, max_value;
struct gpio_adc pin;
uint8_t invalid_count, range_check_count;
uint8_t state, sample_count;
};
static struct task_wake analog_wake;
static uint_fast8_t
analog_in_event(struct timer *timer)
{
struct analog_in *a = container_of(timer, struct analog_in, timer);
uint32_t sample_delay = gpio_adc_sample(a->pin);
if (sample_delay) {
a->timer.waketime += sample_delay;
return SF_RESCHEDULE;
}
uint16_t value = gpio_adc_read(a->pin);
uint8_t state = a->state;
if (state >= a->sample_count) {
So, you should have no problem doing so, as long as those pins are correctly defined within the code.
1 Like