gpio: Merge gpio_adc_sample_time() into gpio_adc_sample()

Return the number of clock ticks to wait directly from
gpio_adc_sample().  This simplifies the ADC interface.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2016-11-02 17:30:34 -04:00
parent 5419c456ac
commit 7c8addc5c5
5 changed files with 29 additions and 34 deletions

View File

@ -22,8 +22,9 @@ static uint8_t
analog_in_event(struct timer *timer) analog_in_event(struct timer *timer)
{ {
struct analog_in *a = container_of(timer, struct analog_in, timer); struct analog_in *a = container_of(timer, struct analog_in, timer);
if (gpio_adc_sample(a->pin)) { uint32_t sample_delay = gpio_adc_sample(a->pin);
a->timer.waketime += gpio_adc_sample_time(); if (sample_delay) {
a->timer.waketime += sample_delay;
return SF_RESCHEDULE; return SF_RESCHEDULE;
} }
uint16_t value = gpio_adc_read(a->pin); uint16_t value = gpio_adc_read(a->pin);
@ -62,7 +63,7 @@ command_query_analog_in(uint32_t *args)
{ {
struct analog_in *a = lookup_oid(args[0], command_config_analog_in); struct analog_in *a = lookup_oid(args[0], command_config_analog_in);
sched_del_timer(&a->timer); sched_del_timer(&a->timer);
gpio_adc_clear_sample(a->pin); gpio_adc_cancel_sample(a->pin);
a->next_begin_time = args[1]; a->next_begin_time = args[1];
a->timer.waketime = a->next_begin_time; a->timer.waketime = a->next_begin_time;
a->sample_time = args[2]; a->sample_time = args[2];
@ -111,7 +112,7 @@ analog_in_shutdown(void)
uint8_t i; uint8_t i;
struct analog_in *a; struct analog_in *a;
foreach_oid(i, a, command_config_analog_in) { foreach_oid(i, a, command_config_analog_in) {
gpio_adc_clear_sample(a->pin); gpio_adc_cancel_sample(a->pin);
} }
} }
DECL_SHUTDOWN(analog_in_shutdown); DECL_SHUTDOWN(analog_in_shutdown);

View File

@ -282,27 +282,24 @@ gpio_adc_setup(uint8_t pin)
shutdown("Not a valid ADC pin"); shutdown("Not a valid ADC pin");
} }
uint32_t
gpio_adc_sample_time(void)
{
return (13 + 1) * 128 + 200;
}
enum { ADC_DUMMY=0xff }; enum { ADC_DUMMY=0xff };
static uint8_t last_analog_read = ADC_DUMMY; static uint8_t last_analog_read = ADC_DUMMY;
uint8_t // 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) gpio_adc_sample(struct gpio_adc g)
{ {
if (ADCSRA & (1<<ADSC)) if (ADCSRA & (1<<ADSC))
// Busy // Busy
return 1; goto need_delay;
if (last_analog_read == g.chan) if (last_analog_read == g.chan)
// Sample now ready // Sample now ready
return 0; return 0;
if (last_analog_read != ADC_DUMMY) if (last_analog_read != ADC_DUMMY)
// Sample on another channel in progress // Sample on another channel in progress
return 1; goto need_delay;
last_analog_read = g.chan; last_analog_read = g.chan;
#if defined(ADCSRB) && defined(MUX5) #if defined(ADCSRB) && defined(MUX5)
@ -315,16 +312,11 @@ gpio_adc_sample(struct gpio_adc g)
// start the conversion // start the conversion
ADCSRA |= 1<<ADSC; ADCSRA |= 1<<ADSC;
return 1; need_delay:
} return (13 + 1) * 128 + 200;
void
gpio_adc_clear_sample(struct gpio_adc g)
{
if (last_analog_read == g.chan)
last_analog_read = ADC_DUMMY;
} }
// Read a value; use only after gpio_adc_sample() returns zero
uint16_t uint16_t
gpio_adc_read(struct gpio_adc g) gpio_adc_read(struct gpio_adc g)
{ {
@ -332,6 +324,14 @@ gpio_adc_read(struct gpio_adc g)
return ADC; return ADC;
} }
// Cancel a sample that may have been started with gpio_adc_sample()
void
gpio_adc_cancel_sample(struct gpio_adc g)
{
if (last_analog_read == g.chan)
last_analog_read = ADC_DUMMY;
}
void void
spi_config(void) spi_config(void)

View File

@ -2,7 +2,6 @@
#define __AVR_GPIO_H #define __AVR_GPIO_H
#include <stdint.h> #include <stdint.h>
#include "compiler.h" // __always_inline
struct gpio_out { struct gpio_out {
struct gpio_digital_regs *regs; struct gpio_digital_regs *regs;
@ -31,10 +30,9 @@ struct gpio_adc {
uint8_t chan; uint8_t chan;
}; };
struct gpio_adc gpio_adc_setup(uint8_t pin); struct gpio_adc gpio_adc_setup(uint8_t pin);
uint32_t gpio_adc_sample_time(void); uint32_t gpio_adc_sample(struct gpio_adc g);
uint8_t gpio_adc_sample(struct gpio_adc g);
void gpio_adc_clear_sample(struct gpio_adc g);
uint16_t gpio_adc_read(struct gpio_adc g); uint16_t gpio_adc_read(struct gpio_adc g);
void gpio_adc_cancel_sample(struct gpio_adc g);
void spi_config(void); void spi_config(void);
void spi_transfer(char *data, uint8_t len); void spi_transfer(char *data, uint8_t len);

View File

@ -26,10 +26,9 @@ struct gpio_adc {
uint8_t pin; uint8_t pin;
}; };
struct gpio_adc gpio_adc_setup(uint8_t pin); struct gpio_adc gpio_adc_setup(uint8_t pin);
uint32_t gpio_adc_sample_time(void); uint32_t gpio_adc_sample(struct gpio_adc g);
uint8_t gpio_adc_sample(struct gpio_adc g);
void gpio_adc_clear_sample(struct gpio_adc g);
uint16_t gpio_adc_read(struct gpio_adc g); uint16_t gpio_adc_read(struct gpio_adc g);
void gpio_adc_cancel_sample(struct gpio_adc g);
void spi_config(void); void spi_config(void);
void spi_transfer(char *data, uint8_t len); void spi_transfer(char *data, uint8_t len);

View File

@ -27,17 +27,14 @@ void gpio_pwm_write(struct gpio_pwm g, uint8_t val) {
struct gpio_adc gpio_adc_setup(uint8_t pin) { struct gpio_adc gpio_adc_setup(uint8_t pin) {
return (struct gpio_adc){.pin=pin}; return (struct gpio_adc){.pin=pin};
} }
uint32_t gpio_adc_sample_time(void) { uint32_t gpio_adc_sample(struct gpio_adc g) {
return 0; return 0;
} }
uint8_t gpio_adc_sample(struct gpio_adc g) {
return 0;
}
void gpio_adc_clear_sample(struct gpio_adc g) {
}
uint16_t gpio_adc_read(struct gpio_adc g) { uint16_t gpio_adc_read(struct gpio_adc g) {
return 0; return 0;
} }
void gpio_adc_cancel_sample(struct gpio_adc g) {
}
void spi_config(void) { void spi_config(void) {
} }