X-Git-Url: http://git.droids-corp.org/?p=aversive.git;a=blobdiff_plain;f=projects%2Fmicrob2010%2Ftests%2Fstatic_beacon%2Fstatic_beacon.c;h=c8e54c07352160c216477e64cf90009a8512db45;hp=c5572b363e53d8321110fb36aa9d87d6305cc90b;hb=5787cfdb9987e3e5cf650e6ad1586663b191af20;hpb=dccae820e0f5c68a3a9c496b63eb8d02102d6ebc diff --git a/projects/microb2010/tests/static_beacon/static_beacon.c b/projects/microb2010/tests/static_beacon/static_beacon.c index c5572b3..c8e54c0 100755 --- a/projects/microb2010/tests/static_beacon/static_beacon.c +++ b/projects/microb2010/tests/static_beacon/static_beacon.c @@ -1,7 +1,7 @@ -/* +/* * Copyright Droids Corporation (2009) * Olivier Matz - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -33,7 +33,7 @@ /* * hfuse: RSTDISBL=1 WTDON=1 SPIEN=0 CKOPT=0 EESAVE=1 BOOTSZ1=0 BOOTSZ0=0 BOOTRST=1 - * lfuse: BODLEVEL=1 BODEN=1 SUT1=1 SUT0=1 CKSEL3=1 CKSEL2=1 CKSEL1=1 CKSEL0=1 + * lfuse: BODLEVEL=1 BODEN=1 SUT1=1 SUT0=1 CKSEL3=1 CKSEL2=1 CKSEL1=1 CKSEL0=1 */ #define N_PERIODS 10 @@ -74,31 +74,22 @@ #define FRAME 0xAA5B /* in little endian */ #define FRAME_LEN 16 -/* pin returns 1 when nothing, and 0 when laser is on photodiode */ +/* pin returns !0 when nothing, and 0 when laser is on photodiode */ #define PHOTO_PIN PINC -#define PHOTO1_BIT 0 -#define PHOTO2_BIT 1 -#define READ_PHOTOS() (PHOTO_PIN & (_BV(PHOTO1_BIT) | _BV(PHOTO2_BIT))) -#define READ_PHOTO1() (PHOTO_PIN & _BV(PHOTO1_BIT)) -#define READ_PHOTO2() (PHOTO_PIN & _BV(PHOTO2_BIT)) - -#define PHOTOS_ALL_OFF (_BV(PHOTO1_BIT) | _BV(PHOTO2_BIT)) -#define PHOTOS_ALL_ON (0) -#define PHOTOS_1ON_2OFF (_BV(PHOTO2_BIT)) -#define PHOTOS_1OFF_2ON (_BV(PHOTO1_BIT)) - +#define PHOTO_BIT 0 +#define READ_PHOTO() (!!(PHOTO_PIN & (_BV(PHOTO_BIT)))) -/* in cycles/64 (unit is 4 us at 16Mhz) */ -#define MAX_PHOTO_TIME ((uint8_t)25) /* t=100us len=5mm rps=40Hz dist=20cm */ +#define MIN_INTER_TIME (50*16) /* t~=50us dist=350cm */ +#define MAX_INTER_TIME (2000*16) /* t=2ms dist=20cm */ -#define MIN_INTER_TIME ((uint8_t)12) /* t=50us len=50mm rps=40Hz dist=350cm */ -#define MAX_INTER_TIME ((uint8_t)250) /* t=1000us len=50mm rps=40Hz dist=20cm */ +/* xmit 2ms after virtual laser: must be < 32768 */ +#define IR_DELAY (2000*16) /* in ms */ #define INTER_LASER_TIME 10 -#define NO_MODULATION -//#define WAIT_LASER +//#define NO_MODULATION +#define WAIT_LASER /* basic functions to transmit on IR */ @@ -160,60 +151,42 @@ static void xmit_bits(uint32_t frame, uint8_t nbit) xmit_0(); } -/* */ -static inline int8_t wait_laser(void) +/* Wait 2 consecutive rising edges on photodiode. Return 0 on success, + * in this case, the 'when' pointed area is assigned to the time when + * IR signal should be sent. */ +static inline int8_t wait_laser(uint16_t *when) { - uint8_t photos; - uint8_t time; - uint8_t diff; - - /* wait until all is off */ - while (READ_PHOTOS() != PHOTOS_ALL_OFF); + uint16_t time1, time2; + uint16_t diff; - /* wait an event, it must be photo1 on */ - while ((photos = READ_PHOTOS()) == PHOTOS_ALL_OFF); + /* set timer to 16Mhz, we will use ICP */ + TCCR1A = 0; + TCCR1B = _BV(CS10); - if (photos != PHOTOS_1ON_2OFF) - return -1; - time = TCNT0; - LED1_ON(); + /* wait until all is off */ + while (READ_PHOTO() != 0); + TIFR = _BV(ICF1); - /* wait an event, it must be photo1 off */ - while ((photos = READ_PHOTOS()) == PHOTOS_1ON_2OFF) { - diff = TCNT0 - time; - if (diff > MAX_PHOTO_TIME) - return -1; - } - if (photos != PHOTOS_ALL_OFF) - return -1; - //time = TCNT0; + /* wait rising edge */ + while ((TIFR & _BV(ICF1)) == 0); + time1 = ICR1; + TIFR = _BV(ICF1); - /* wait an event, it must be photo2 on */ - while ((photos = READ_PHOTOS()) == PHOTOS_ALL_OFF) { - diff = TCNT0 - time; + /* wait next rising edge + timeout */ + while ((TIFR & _BV(ICF1)) == 0) { + diff = TCNT1 - time1; if (diff > MAX_INTER_TIME) return -1; } - LED2_ON(); - - diff = TCNT0 - time; - if (diff < MIN_INTER_TIME) - return -1; - if (photos != PHOTOS_1OFF_2ON) - return -1; -#if 0 - time = TCNT0; + time2 = ICR1; + TIFR = _BV(ICF1); - /* wait an event, it must be photo2 off */ - while ((photos = READ_PHOTOS()) == PHOTOS_1OFF_2ON) { - diff = TCNT0 - time; - if (diff > MAX_PHOTO_TIME) - return -1; - } - if (photos != PHOTOS_ALL_OFF) + diff = time2 - time1; + if (diff < MIN_INTER_TIME) return -1; -#endif + + *when = time1 + (diff/2) + IR_DELAY; /* laser ok */ return 0; @@ -226,7 +199,7 @@ int main(void) /* must be odd */ uint32_t frame = FRAME; int8_t ret; - int16_t c; + uint16_t when = 0; /* LEDS */ LED_DDR = _BV(LED1_BIT) | _BV(LED2_BIT) | _BV(LED3_BIT); @@ -238,8 +211,9 @@ int main(void) #if 0 while (1) { + int16_t c; c = uart_recv_nowait(0); - if (c != -1) + if (c != -1) printf("%c", (char)(c+1)); LED1_ON(); wait_ms(500); @@ -250,7 +224,7 @@ int main(void) #if 0 while (1) { - if (READ_PHOTO() & _BV(PHOTO1_BIT)) + if (READ_PHOTO()) LED1_ON(); else LED1_OFF(); @@ -271,20 +245,23 @@ int main(void) while (1) { #ifdef WAIT_LASER - ret = wait_laser(); - + ret = wait_laser(&when); + LED1_OFF(); LED2_OFF(); if (ret) continue; + + /* wait before IR xmit */ + while ((int16_t)(when-TCNT1) > 0); #endif - + #if 1 LED3_ON(); /* ok, transmit frame */ xmit_bits(frame, FRAME_LEN); - + /* don't watch a laser during this time */ wait_ms(INTER_LASER_TIME); LED3_OFF();