From 31b666597c0014c64be6230df6451ec062524522 Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Thu, 3 Oct 2013 20:11:24 +0200 Subject: [PATCH] poll input capture register currently value are not send through spi, only saved in ram Signed-off-by: Olivier Matz --- main.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/main.c b/main.c index 3509874..82739b0 100644 --- a/main.c +++ b/main.c @@ -39,6 +39,10 @@ static volatile uint8_t done; static uint8_t portval; static uint8_t rxidx; +static uint8_t icp_idx = NB_SERVO; +static uint16_t icp_servos[NB_SERVO]; +static uint16_t icp_prev; + #define BYPASS_ENABLE 14 #define BYPASS_DISABLE 15 @@ -126,6 +130,53 @@ static void poll_spi(void) rxidx ^= 1; } +static void poll_input_capture(void) +{ + uint16_t icp, diff; + uint8_t rising; + + /* no new sample, return */ + if ((TIFR1 & _BV(ICF1)) == 0) + return; + + sei(); + icp = ICR1; + cli(); + + rising = TCCR1B & _BV(ICES1); + + /* change the edge type */ + TCCR1B ^= _BV(ICES1); + + /* clear the flag */ + TIFR1 = TIFR1 | _BV(ICF1); + + diff = icp - icp_prev; + icp_prev = icp; + + /* a rising edge with at least 2ms of state 0 means that we + * get the first servo */ + if (rising == 1 && diff > 2000) { + icp_idx = 0; + return; + } + + /* get the value for the servo */ + if (rising == 0 && icp_idx < NB_SERVO) { + if (diff < 1000) + icp_servos[icp_idx] = 0; + else + icp_servos[icp_idx] = diff - 1000; + icp_idx++; + } +} + +static void poll(void) +{ + poll_spi(); + poll_input_capture(); +} + static void load_timer_at(uint16_t t) { OCR1A = t; @@ -143,7 +194,7 @@ static void do_one_servo(struct servo *s) t = TCNT1; load_timer_at(t + 20); while (done == 0) - poll_spi(); + poll(); /* reset bit */ done = 0; @@ -151,7 +202,7 @@ static void do_one_servo(struct servo *s) //portval = PORTC & (~(1 << s->bit)); load_timer_at(t + 20 + 1000 + s->command); while (done == 0) - poll_spi(); + poll(); } int main(void) @@ -178,9 +229,10 @@ int main(void) /* servo outputs PD2-PD7 */ DDRD = 0xfc; - /* start timer1 at clk/8 (1Mhz) */ + /* start timer1 at clk/8 (1Mhz), enable noise canceler on + * input capture, capture rising edge */ TCNT1 = 0; - TCCR1B = _BV(CS11); + TCCR1B = _BV(CS11) | _BV(ICNC1) | _BV(ICES1); /* start timer0 at clk/1024 (~8Khz) */ TCNT0 = 0; @@ -202,7 +254,7 @@ int main(void) diff = TCNT0 - t; if (diff >= 160) break; - poll_spi(); + poll(); } /* bypass mode */ if (bypass == 1) { @@ -213,7 +265,7 @@ int main(void) tmp &= 0x3f; tmp <<= 2; PORTD = tmp; - poll_spi(); + poll(); } LED_OFF(); } -- 2.20.1