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=b8a2adba60ab114881e537335f3b5864982b3020;hb=5787cfdb9987e3e5cf650e6ad1586663b191af20;hpb=5918edd6f4f713ef3c8b0b0020dd30a4fb8222ae diff --git a/projects/microb2010/tests/static_beacon/static_beacon.c b/projects/microb2010/tests/static_beacon/static_beacon.c index b8a2adb..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 @@ -23,6 +23,8 @@ #include #include +#include + /* * Leds: PD5 -> PD7 * Photodiodes: PC0 PC1 @@ -31,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 @@ -67,32 +69,26 @@ #define IR_BIT 1 /* FRAME must be odd */ -#define FRAME 0x0B /* in little endian 1-1-0-1 */ -#define FRAME_LEN 4 +/* #define FRAME 0x0B /\* in little endian 1-1-0-1 *\/ */ +/* #define FRAME_LEN 4 */ +#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 /* basic functions to transmit on IR */ @@ -100,18 +96,26 @@ static inline void xmit_0(void) { uint8_t t = ((N_CYCLES_PERIOD * N_PERIODS) / 3); +#ifdef NO_MODULATION + cbi(IR_PORT, IR_BIT); +#else TCCR1B = 0; TCCR1A = 0; +#endif _delay_loop_1(t); /* 3 cycles per loop */ } static inline void xmit_1(void) { uint8_t t = ((N_CYCLES_PERIOD * N_PERIODS) / 3); +#ifdef NO_MODULATION + sbi(IR_PORT, IR_BIT); +#else TCCR1B = _BV(WGM13) | _BV(WGM12); TCNT1 = N_CYCLES_PERIOD-1; TCCR1A = _BV(COM1A1) | _BV(WGM11); TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); +#endif _delay_loop_1(t); /* 3 cycles per loop */ } @@ -131,81 +135,58 @@ static inline void xmit_manchester_1(void) /* transmit a full frame. Each byte is lsb first. */ -static void xmit_bits(uint8_t *buf, uint8_t nbit) +static void xmit_bits(uint32_t frame, uint8_t nbit) { uint8_t i; - uint8_t byte = *buf; for (i=0; i>= 1; - - /* next byte */ - if (((i & 0x07) == 0) && (i != 0)) - byte = *(++buf); + frame >>= 1UL; } 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; + uint16_t time1, time2; + uint16_t diff; - /* wait until all is off */ - while (READ_PHOTOS() != PHOTOS_ALL_OFF); + /* set timer to 16Mhz, we will use ICP */ + TCCR1A = 0; + TCCR1B = _BV(CS10); - /* wait an event, it must be photo1 on */ - while ((photos = READ_PHOTOS()) == PHOTOS_ALL_OFF); + /* wait until all is off */ + while (READ_PHOTO() != 0); + TIFR = _BV(ICF1); - if (photos != PHOTOS_1ON_2OFF) - return -1; - time = TCNT0; - LED1_ON(); + /* wait rising edge */ + while ((TIFR & _BV(ICF1)) == 0); + time1 = ICR1; + 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 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; @@ -216,15 +197,24 @@ static inline int8_t wait_laser(void) int main(void) { /* must be odd */ - uint8_t frame = FRAME; + uint32_t frame = FRAME; int8_t ret; + uint16_t when = 0; /* LEDS */ LED_DDR = _BV(LED1_BIT) | _BV(LED2_BIT) | _BV(LED3_BIT); IR_DDR |= _BV(IR_BIT); + uart_init(); + fdevopen(uart0_dev_send, uart0_dev_recv); + sei(); + #if 0 while (1) { + int16_t c; + c = uart_recv_nowait(0); + if (c != -1) + printf("%c", (char)(c+1)); LED1_ON(); wait_ms(500); LED1_OFF(); @@ -234,18 +224,20 @@ int main(void) #if 0 while (1) { - if (READ_PHOTO() & _BV(PHOTO1_BIT)) + if (READ_PHOTO()) LED1_ON(); else LED1_OFF(); } #endif +#ifndef NO_MODULATION /* configure PWM */ ICR1 = N_CYCLES_PERIOD; OCR1A = N_CYCLES_1; TCCR1A = _BV(COM1A1) | _BV(WGM11); TCCR1B = _BV(WGM13) | _BV(WGM12); +#endif /* configure timer 0, prescaler = 64 */ TCCR0 = _BV(CS01) | _BV(CS00); @@ -253,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); - + xmit_bits(frame, FRAME_LEN); + /* don't watch a laser during this time */ wait_ms(INTER_LASER_TIME); LED3_OFF();