X-Git-Url: http://git.droids-corp.org/?p=aversive.git;a=blobdiff_plain;f=projects%2Fmicrob2010%2Ftests%2Fstatic_beacon%2Fstatic_beacon.c;h=c34838c0757e1c304433736ced4d847393277290;hp=b8a2adba60ab114881e537335f3b5864982b3020;hb=7e6058416582109d4b73ec4e0c923eb471c36844;hpb=5918edd6f4f713ef3c8b0b0020dd30a4fb8222ae diff --git a/projects/microb2010/tests/static_beacon/static_beacon.c b/projects/microb2010/tests/static_beacon/static_beacon.c index b8a2adb..c34838c 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,27 @@ #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 */ +/* XXX to be recalculated */ #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 */ /* in ms */ #define INTER_LASER_TIME 10 +//#define NO_MODULATION #define WAIT_LASER /* basic functions to transmit on IR */ @@ -100,18 +97,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,23 +136,18 @@ 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(); } @@ -156,56 +156,54 @@ static void xmit_bits(uint8_t *buf, uint8_t nbit) static inline int8_t wait_laser(void) { uint8_t photos; - uint8_t time; + uint8_t time1, time2; uint8_t diff; - /* wait until all is off */ - while (READ_PHOTOS() != PHOTOS_ALL_OFF); + /* + wait photo on + wait photo off + wait photo on or timeout + wait photo off + should return the amount of time to wait + */ - /* wait an event, it must be photo1 on */ - while ((photos = READ_PHOTOS()) == PHOTOS_ALL_OFF); + /* wait until all is off */ + while (READ_PHOTO() != 0); - if (photos != PHOTOS_1ON_2OFF) - return -1; - time = TCNT0; + /* wait until photo is on */ + while (READ_PHOTO() != 1); + time1 = TCNT0; LED1_ON(); - /* wait an event, it must be photo1 off */ - while ((photos = READ_PHOTOS()) == PHOTOS_1ON_2OFF) { - diff = TCNT0 - time; + /* wait until photo is off, if it takes too long time, + * return. */ + while (READ_PHOTO() != 0) { + diff = TCNT0 - time1; 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 photo on. */ + while (READ_PHOTO() != 1) { + diff = TCNT0 - 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 = TCNT0; - /* wait an event, it must be photo2 off */ - while ((photos = READ_PHOTOS()) == PHOTOS_1OFF_2ON) { - diff = TCNT0 - time; + /* wait until photo is off, if it takes too long time, + * return. */ + while (READ_PHOTO() != 0) { + diff = TCNT0 - time2; if (diff > MAX_PHOTO_TIME) return -1; } - if (photos != PHOTOS_ALL_OFF) + + LED2_ON(); + + diff = time2 - time1; + if (diff < MIN_INTER_TIME) return -1; -#endif /* laser ok */ return 0; @@ -216,15 +214,23 @@ static inline int8_t wait_laser(void) int main(void) { /* must be odd */ - uint8_t frame = FRAME; + uint32_t frame = FRAME; int8_t ret; + int16_t c; /* 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) { + c = uart_recv_nowait(0); + if (c != -1) + printf("%c", (char)(c+1)); LED1_ON(); wait_ms(500); LED1_OFF(); @@ -241,11 +247,13 @@ int main(void) } #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); @@ -254,19 +262,19 @@ int main(void) #ifdef WAIT_LASER ret = wait_laser(); - + LED1_OFF(); LED2_OFF(); if (ret) continue; #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();