From 630e6dd0e05c849b0534a2f3f02420e504d5a867 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Fri, 9 Apr 2010 19:54:46 +0200 Subject: digital/io/src: handle US sensors synchronisation, closes #113 --- digital/io/src/usdist.c | 97 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 19 deletions(-) (limited to 'digital/io/src/usdist.c') diff --git a/digital/io/src/usdist.c b/digital/io/src/usdist.c index 342358ea..d7f69975 100644 --- a/digital/io/src/usdist.c +++ b/digital/io/src/usdist.c @@ -24,41 +24,100 @@ * }}} */ #include "common.h" #include "usdist.h" +#include "main_timer.h" #include "modules/adc/adc.h" #include "modules/utils/utils.h" #include "io.h" +#include "simu.host.h" + uint16_t usdist_mm[USDIST_NB]; +/** Describe a sensor. */ +struct usdist_sensor_t +{ + /** ADC number. */ + uint8_t adc; + /** Sync PORT. */ + volatile uint8_t *sync_port; + /** Sync DDR. */ + volatile uint8_t *sync_ddr; + /** Sync bit mask. */ + uint8_t sync_bv; +}; + +/** Define sensors configuration. */ +#define USDIST_SENSOR(adc, p, n) \ + { adc, &IO_PORT_ (p, n), &IO_DDR_ (p, n), IO_BV_ (p, n) } +struct usdist_sensor_t usdist_sensors[USDIST_NB] = { + USDIST_SENSOR (0, G, 3), + USDIST_SENSOR (1, G, 1), + USDIST_SENSOR (2, C, 7), + USDIST_SENSOR (3, D, 4), +}; + void usdist_init (void) { + uint8_t i; adc_init (); + for (i = 0; i < USDIST_NB; i++) + { + usdist_mm[i] = 0xffff; + *usdist_sensors[i].sync_port |= usdist_sensors[i].sync_bv; + *usdist_sensors[i].sync_ddr |= usdist_sensors[i].sync_bv; + } } -void +uint8_t usdist_update (void) { - uint8_t i; - /* Simple algorithm, just make a conversion for every sensor. This should - * be improved because it takes too long. */ - for (i = 0; i < USDIST_NB; i++) + /* Current measuring sensor. */ + static uint8_t current; + /* Number of cycles until the measure ends. */ + static uint8_t wait; + /* Set to one once first cycle is done. */ + static uint8_t init; + /* Time to measure? */ + if (wait == 0) + { + if (init) + { + /* Stop sensor. */ + *usdist_sensors[current].sync_port |= + usdist_sensors[current].sync_bv; + /* Read ADC value. */ + adc_start (usdist_sensors[current].adc); + while (!adc_checkf ()) + ; + uint16_t v = adc_read (); + /* Our sensors return a value between 1 and 5 V proportional to + * the distance between calibrated values. */ + if (v <= 1024 / 5) + usdist_mm[current] = USDIST_MM_MIN; + else + usdist_mm[current] = USDIST_MM_MIN + + ((uint32_t) (v - 1024 / 5) + * (USDIST_MM_MAX - USDIST_MM_MIN) + / (4 * 1024 / 5)); + if (usdist_mm[current] >= USDIST_MM_TOO_FAR) + usdist_mm[current] = 0xffff; + /* Next. */ + current = (current + 1) % USDIST_NB; + } + init = 1; + /* Prepare next measure. */ + *usdist_sensors[current].sync_port &= + ~usdist_sensors[current].sync_bv; + wait = USDIST_PERIOD_CYCLE; + /* New mesure done. */ + return 1; + } + else { - adc_start (i); - while (!adc_checkf ()) - ; - uint16_t v = adc_read (); - /* Our sensors return a value between 1 and 5 V proportional to the - * distance between calibrated values. */ - if (v <= 1024 / 5) - usdist_mm[i] = USDIST_MM_MIN; - else - usdist_mm[i] = USDIST_MM_MIN - + (uint32_t) (v - 1024 / 5) * (USDIST_MM_MAX - USDIST_MM_MIN) - / (4 * 1024 / 5); - if (usdist_mm[i] >= USDIST_MM_TOO_FAR) - usdist_mm[i] = 0xffff; + wait--; + return 0; } } -- cgit v1.2.3