aboutsummaryrefslogtreecommitdiffstats
path: root/src/avr/gpio.c
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2017-04-10 17:46:45 -0400
committerKevin O'Connor <kevin@koconnor.net>2017-04-11 10:01:22 -0400
commit15d5837322db5298f29d0d2ba92416fd5a40cc8c (patch)
tree19d729a0000118d88e2292091954cc4a735c923d /src/avr/gpio.c
parentf9ebb8b23ec80c4462408a46a0ec7d4fa2690467 (diff)
downloadkutter-15d5837322db5298f29d0d2ba92416fd5a40cc8c.tar.gz
kutter-15d5837322db5298f29d0d2ba92416fd5a40cc8c.tar.xz
kutter-15d5837322db5298f29d0d2ba92416fd5a40cc8c.zip
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>
Diffstat (limited to 'src/avr/gpio.c')
-rw-r--r--src/avr/gpio.c124
1 files changed, 65 insertions, 59 deletions
diff --git a/src/avr/gpio.c b/src/avr/gpio.c
index 330e8d63..5dfc34c4 100644
--- a/src/avr/gpio.c
+++ b/src/avr/gpio.c
@@ -1,6 +1,6 @@
// 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.
@@ -165,56 +165,60 @@ static const uint8_t pwm_pins[ARRAY_SIZE(pwm_regs)] PROGMEM = {
struct gpio_pwm
gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint8_t val)
{
+ // Find pin in pwm_pins table
uint8_t chan;
- for (chan=0; chan<ARRAY_SIZE(pwm_regs); chan++) {
- if (READP(pwm_pins[chan]) != pin)
- continue;
- const struct gpio_pwm_info *p = &pwm_regs[chan];
- uint8_t flags = READP(p->flags), cs;
- if (flags & GP_AFMT) {
- switch (cycle_time) {
- case 0 ... 8*510L - 1: cs = 1; break;
- case 8*510L ... 32*510L - 1: cs = 2; break;
- case 32*510L ... 64*510L - 1: cs = 3; break;
- case 64*510L ... 128*510L - 1: cs = 4; break;
- case 128*510L ... 256*510L - 1: cs = 5; break;
- case 256*510L ... 1024*510L - 1: cs = 6; break;
- default: cs = 7; break;
- }
- } else {
- switch (cycle_time) {
- case 0 ... 8*510L - 1: cs = 1; break;
- case 8*510L ... 64*510L - 1: cs = 2; break;
- case 64*510L ... 256*510L - 1: cs = 3; break;
- case 256*510L ... 1024*510L - 1: cs = 4; break;
- default: cs = 5; break;
- }
+ for (chan=0; ; chan++) {
+ if (chan >= ARRAY_SIZE(pwm_pins))
+ 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];
+ uint8_t flags = READP(p->flags), cs;
+ if (flags & GP_AFMT) {
+ switch (cycle_time) {
+ case 0 ... 8*510L - 1: cs = 1; break;
+ case 8*510L ... 32*510L - 1: cs = 2; break;
+ case 32*510L ... 64*510L - 1: cs = 3; break;
+ case 64*510L ... 128*510L - 1: cs = 4; break;
+ case 128*510L ... 256*510L - 1: cs = 5; break;
+ case 256*510L ... 1024*510L - 1: cs = 6; break;
+ default: cs = 7; break;
+ }
+ } else {
+ switch (cycle_time) {
+ case 0 ... 8*510L - 1: cs = 1; break;
+ case 8*510L ... 64*510L - 1: cs = 2; break;
+ case 64*510L ... 256*510L - 1: cs = 3; break;
+ case 256*510L ... 1024*510L - 1: cs = 4; break;
+ default: cs = 5; break;
}
- volatile uint8_t *rega = READP(p->rega), *regb = READP(p->regb);
- uint8_t en_bit = READP(p->en_bit);
- struct gpio_digital_regs *regs = GPIO2REGS(pin);
- uint8_t bit = GPIO2BIT(pin);
- struct gpio_pwm g = (struct gpio_pwm) {
- (void*)READP(p->ocr), flags & GP_8BIT };
- if (rega == &TCCR1A)
- shutdown("Can not user timer1 for PWM; timer1 is used for timers");
+ }
+ volatile uint8_t *rega = READP(p->rega), *regb = READP(p->regb);
+ uint8_t en_bit = READP(p->en_bit);
+ struct gpio_digital_regs *gpio_regs = GPIO2REGS(pin);
+ uint8_t gpio_bit = GPIO2BIT(pin);
+ struct gpio_pwm g = (struct gpio_pwm) {
+ (void*)READP(p->ocr), flags & GP_8BIT };
+ if (rega == &TCCR1A)
+ shutdown("Can not use timer1 for PWM; timer1 is used for timers");
- // Setup PWM timer
- irqstatus_t flag = irq_save();
- uint8_t old_cs = *regb & 0x07;
- if (old_cs && old_cs != cs)
- shutdown("PWM already programmed at different speed");
- *regb = cs;
+ // Setup PWM timer
+ irqstatus_t flag = irq_save();
+ uint8_t old_cs = *regb & 0x07;
+ if (old_cs && old_cs != cs)
+ shutdown("PWM already programmed at different speed");
+ *regb = cs;
- // Set default value and enable output
- gpio_pwm_write(g, val);
- *rega |= (1<<WGM00) | en_bit;
- regs->mode |= bit;
- irq_restore(flag);
+ // Set default value and enable output
+ gpio_pwm_write(g, val);
+ *rega |= (1<<WGM00) | en_bit;
+ gpio_regs->mode |= gpio_bit;
+ irq_restore(flag);
- return g;
- }
- shutdown("Not a valid PWM pin");
+ return g;
}
void
@@ -259,25 +263,27 @@ DECL_CONSTANT(ADC_MAX, 1024);
struct gpio_adc
gpio_adc_setup(uint8_t pin)
{
+ // Find pin in adc_pins table
uint8_t chan;
- for (chan=0; chan<ARRAY_SIZE(adc_pins); chan++) {
- if (READP(adc_pins[chan]) != pin)
- continue;
+ for (chan=0; ; chan++) {
+ if (chan >= ARRAY_SIZE(adc_pins))
+ shutdown("Not a valid ADC pin");
+ if (READP(adc_pins[chan]) == pin)
+ break;
+ }
- // Enable ADC
- ADCSRA |= (1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2)|(1<<ADEN);
+ // Enable ADC
+ ADCSRA |= (1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2)|(1<<ADEN);
- // Disable digital input for this pin
+ // Disable digital input for this pin
#ifdef DIDR2
- if (chan >= 8)
- DIDR2 |= 1 << (chan & 0x07);
- else
+ if (chan >= 8)
+ DIDR2 |= 1 << (chan & 0x07);
+ else
#endif
- DIDR0 |= 1 << chan;
+ DIDR0 |= 1 << chan;
- return (struct gpio_adc){ chan };
- }
- shutdown("Not a valid ADC pin");
+ return (struct gpio_adc){ chan };
}
enum { ADC_DUMMY=0xff };