avr: Rework adc and pwm pin search to be more clear

Rework the pin search loop.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2017-04-10 17:46:45 -04:00
parent f9ebb8b23e
commit 15d5837322
1 changed files with 72 additions and 66 deletions

View File

@ -1,6 +1,6 @@
// GPIO functions on AVR. // GPIO functions on AVR.
// //
// Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net> // Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net>
// //
// This file may be distributed under the terms of the GNU GPLv3 license. // This file may be distributed under the terms of the GNU GPLv3 license.
@ -165,10 +165,16 @@ static const uint8_t pwm_pins[ARRAY_SIZE(pwm_regs)] PROGMEM = {
struct gpio_pwm struct gpio_pwm
gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint8_t val) gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint8_t val)
{ {
// Find pin in pwm_pins table
uint8_t chan; uint8_t chan;
for (chan=0; chan<ARRAY_SIZE(pwm_regs); chan++) { for (chan=0; ; chan++) {
if (READP(pwm_pins[chan]) != pin) if (chan >= ARRAY_SIZE(pwm_pins))
continue; shutdown("Not a valid PWM pin");
if (READP(pwm_pins[chan]) == pin)
break;
}
// Map cycle_time to pwm clock divisor
const struct gpio_pwm_info *p = &pwm_regs[chan]; const struct gpio_pwm_info *p = &pwm_regs[chan];
uint8_t flags = READP(p->flags), cs; uint8_t flags = READP(p->flags), cs;
if (flags & GP_AFMT) { if (flags & GP_AFMT) {
@ -192,12 +198,12 @@ gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint8_t val)
} }
volatile uint8_t *rega = READP(p->rega), *regb = READP(p->regb); volatile uint8_t *rega = READP(p->rega), *regb = READP(p->regb);
uint8_t en_bit = READP(p->en_bit); uint8_t en_bit = READP(p->en_bit);
struct gpio_digital_regs *regs = GPIO2REGS(pin); struct gpio_digital_regs *gpio_regs = GPIO2REGS(pin);
uint8_t bit = GPIO2BIT(pin); uint8_t gpio_bit = GPIO2BIT(pin);
struct gpio_pwm g = (struct gpio_pwm) { struct gpio_pwm g = (struct gpio_pwm) {
(void*)READP(p->ocr), flags & GP_8BIT }; (void*)READP(p->ocr), flags & GP_8BIT };
if (rega == &TCCR1A) if (rega == &TCCR1A)
shutdown("Can not user timer1 for PWM; timer1 is used for timers"); shutdown("Can not use timer1 for PWM; timer1 is used for timers");
// Setup PWM timer // Setup PWM timer
irqstatus_t flag = irq_save(); irqstatus_t flag = irq_save();
@ -209,13 +215,11 @@ gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint8_t val)
// Set default value and enable output // Set default value and enable output
gpio_pwm_write(g, val); gpio_pwm_write(g, val);
*rega |= (1<<WGM00) | en_bit; *rega |= (1<<WGM00) | en_bit;
regs->mode |= bit; gpio_regs->mode |= gpio_bit;
irq_restore(flag); irq_restore(flag);
return g; return g;
} }
shutdown("Not a valid PWM pin");
}
void void
gpio_pwm_write(struct gpio_pwm g, uint8_t val) gpio_pwm_write(struct gpio_pwm g, uint8_t val)
@ -259,10 +263,14 @@ DECL_CONSTANT(ADC_MAX, 1024);
struct gpio_adc struct gpio_adc
gpio_adc_setup(uint8_t pin) gpio_adc_setup(uint8_t pin)
{ {
// Find pin in adc_pins table
uint8_t chan; uint8_t chan;
for (chan=0; chan<ARRAY_SIZE(adc_pins); chan++) { for (chan=0; ; chan++) {
if (READP(adc_pins[chan]) != pin) if (chan >= ARRAY_SIZE(adc_pins))
continue; shutdown("Not a valid ADC pin");
if (READP(adc_pins[chan]) == pin)
break;
}
// Enable ADC // Enable ADC
ADCSRA |= (1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2)|(1<<ADEN); ADCSRA |= (1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2)|(1<<ADEN);
@ -277,8 +285,6 @@ gpio_adc_setup(uint8_t pin)
return (struct gpio_adc){ chan }; return (struct gpio_adc){ chan };
} }
shutdown("Not a valid ADC pin");
}
enum { ADC_DUMMY=0xff }; enum { ADC_DUMMY=0xff };
static uint8_t last_analog_read = ADC_DUMMY; static uint8_t last_analog_read = ADC_DUMMY;