X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=firmware%2Fapps%2Fradios%2Fatmel_radio.c;h=a81ccdfb7ec2d8329b205dabb8b5b602d1e3075a;hp=c1cd4ab68abf1e4402d3abe611d3da6fc99c94dc;hb=7709570a1640165f33552ce52284c4fca2a54d91;hpb=c6d09f2d0dda59d5da9eb9ed3cb4c97c2898e57c diff --git a/firmware/apps/radios/atmel_radio.c b/firmware/apps/radios/atmel_radio.c index c1cd4ab..a81ccdf 100644 --- a/firmware/apps/radios/atmel_radio.c +++ b/firmware/apps/radios/atmel_radio.c @@ -8,15 +8,16 @@ #include "platform.h" #include "command.h" -#include //added for itoa #include "atmel_radio.h" #include "spi.h" +uint8_t AACK_enabled; + //! Handles a Chipcon SPI command. void atmel_radio_handle_fn( uint8_t const app, uint8_t const verb, - uint32_t const len); + uint32_t const datalen32); // define the atmel_radio app's app_t app_t const atmel_radio_app = { @@ -44,6 +45,7 @@ inline u8 reg_read(u16 addr) { return *(u8*)(TRX_REGISTER_BASEADDR + addr); } + inline void reg_bit_write(u16 addr, u8 pos, u8 value) { u8 old, mask; @@ -53,8 +55,12 @@ inline void reg_bit_write(u16 addr, u8 pos, u8 value) reg_write(addr, old); //write byte } +void atmel_radio_clear_frame_buffer() { + TRXFBST = 0; //reset the frame buffer pointer to signal it was read (resets the PHR - length value) +} + -void atmel_radio_set_state(u8 state) //based on zigduino-radio, radio_rfa.c +u16 atmel_radio_set_state(u8 state) //based on zigduino-radio, radio_rfa.c { u8 cmd, retries; /* ensure not in state transition */ @@ -69,13 +75,19 @@ void atmel_radio_set_state(u8 state) //based on zigduino-radio, radio_rfa.c case BUSY_TX: cmd = CMD_TX_START; break; - default: //doesn't exist - cmd = CMD_RX_ON; + case RX_ON: + default: + if (AACK_enabled) { + cmd = CMD_RX_AACK_ON; + state = RX_AACK_ON; + } else { + cmd = CMD_RX_ON; + } break; } TRX_STATE = cmd; - retries = 140; /* enough to receive ongoing frame */ + retries = 180; // enough to receive ongoing frame do { if (state == (state & TRX_STATUS)) { break; @@ -83,10 +95,15 @@ void atmel_radio_set_state(u8 state) //based on zigduino-radio, radio_rfa.c retries--; _delay_ms(32); } while (retries); + if (state != (state & TRX_STATUS)) { + return (state & TRX_STATUS); + }else{ + return 0; + } } -void atmel_radiosetup(){ - u8 status; +u16 atmel_radiosetup(){ + u16 status; /* initialize transceiver code based on zigduino-radio */ @@ -106,15 +123,36 @@ void atmel_radiosetup(){ /* clear IRQ history by reading status*/ status = IRQ_STATUS; } + atmel_radio_set_state(TRX_OFF); + + /* setup options for extended operating sniffing mode */ + + // disable auto ack + CSMA_SEED_1 &= 0xEF & ~(1 << AACK_DIS_ACK); + + // disable filtering of reserved frame types and reserve frame type processing + XAH_CTRL_1 &= 0xDF & ~(1 << AACK_FLTR_RES_FT); + XAH_CTRL_1 &= 0xEF & ~(1 << AACK_UPLD_RES_FT); + + // enable promiscuous mode + XAH_CTRL_1 |= 1 << AACK_PROM_MODE; + + + // disable frame protection + TRX_CTRL_2 &= 0x7F & ~(1 << RX_SAFE_MODE); // unset auto crc TRX_CTRL_1 &= 0xDF & ~(1 << TX_AUTO_CRC_ON); - /* enter TRX_OFF state */ - atmel_radio_set_state(TRX_OFF); + + atmel_radio_clear_frame_buffer(); + + // extended operation mode disabled by default + AACK_enabled = 0; + /* enter RX_ON state */ - atmel_radio_set_state(RX_ON); + return atmel_radio_set_state(RX_ON); } @@ -145,86 +183,121 @@ void atmel_radio_peekram(u16 addr, u8 *data, u16 len){ } int atmel_radio_is_frame_buffer_empty() { - return TRXFBST == 0; + return 0 == TRXFBST; } -void atmel_radio_clear_frame_buffer() { - TRXFBST = 0; //reset the frame buffer pointer to signal it was read -} -//! Handles a Chipcon SPI command. void atmel_radio_handle_fn( uint8_t const app, uint8_t const verb, - uint32_t const len){ - - u16 length; - u8 len8; - + uint32_t const datalen32){ + + // cmddata -> byte + // cmddataword -> int + // cmddatalong -> long + u16 readlen16; + u16 ret; + u8 retries; + uint8_t framelen8; switch(verb){ case PEEK: - - case READ: - length=cmddataword[1]; // Backup length. Second byte + //case READ: + readlen16 = cmddataword[1]; // Backup length. Second byte atmel_radio_peekram(cmddataword[0], // First word is address cmddata, // Return in same buffer - length); - txdata(app,verb,length); + readlen16); // length + txdata(app,verb,readlen16); break; - case WRITE: + //case WRITE: case POKE: atmel_radio_pokeram(cmddataword[0], // First word is address cmddata+2, // Remainder of buffer is data - len-2); //Length implied by packet length - txdata(app,verb,len-2); //return number of poked bytes + (u16) datalen32-2); //Length implied by packet length + txdata(app,verb, datalen32-2); //return number of poked bytes break; case SETUP: - atmel_radiosetup(); - txdata(app,verb,0); + ret = atmel_radiosetup(); + txdata(app, verb, ret); break; case ATMEL_RADIO_RX: - - // set to PLL_ON so frame buffer isn't clobbered + // ensure radio is not in the middle or receiving a packet + atmel_radio_set_state(RX_ON); + // set state to PLL_ON so frame buffer isn't clobbered atmel_radio_set_state(PLL_ON); - len8 = 8; + if (!atmel_radio_is_frame_buffer_empty()) { //only if we recieved something new - len8 = TST_RX_LENGTH; //register contains frame length - - if ((len8 > 0x80) ) { //frame too big - txdata(app,verb,0); - } else { - memcpy(cmddata, (void *) &TRXFBST, len8); //return in same buffer - atmel_radio_clear_frame_buffer(); - txdata(app, verb, len8); + framelen8 = TST_RX_LENGTH; //register contains frame length + if ((framelen8 > 127) ) { //frame too big + framelen8 = 127; } - }else{ - // didn't recieve anything new - txdata(app,verb,0); + memcpy(cmddata, (void *) &TRXFBST, framelen8); //return in same buffer + atmel_radio_clear_frame_buffer(); + } else { + framelen8 = 0; //didn't receive anything new } // receive packets again atmel_radio_set_state(RX_ON); + txdata(app, verb, framelen8); break; case ATMEL_RADIO_TX: //prevent radio from recieving new packets atmel_radio_set_state(PLL_ON); - if (cmddata[0] > 127) { //truncate too long packets - cmddata[0] = 127; + uint8_t maxlen = 127; + if (cmddata[0] > maxlen) { //truncate too long packets + cmddata[0] = maxlen; } - memcpy((void *) &TRXFBST, cmddata, cmddata[0]+1); //copy length + packet + memcpy((void *) &TRXFBST, cmddata, datalen32); //copy length + packet atmel_radio_set_state(BUSY_TX); //send packet + while (PLL_ON != (PLL_ON & TRX_STATUS)) {} //wait for TX done //reset the frame buffer pointer to signal it was read atmel_radio_clear_frame_buffer(); atmel_radio_set_state(RX_ON); - txdata(app, verb, len8); + txdata(app, verb, 0); break; + case ATMEL_RADIO_AACK_ON: + if (!AACK_enabled) { + AACK_enabled = 1; + /* enter PLL_ON state */ + atmel_radio_set_state(PLL_ON); + /* enter RX_ON state */ + atmel_radio_set_state(RX_ON); + } + txdata(app, verb, 0); + break; + case ATMEL_RADIO_AACK_OFF: + if (AACK_enabled) { + AACK_enabled = 0; + /* enter PLL_ON state */ + atmel_radio_set_state(PLL_ON); + /* enter RX_ON state */ + atmel_radio_set_state(RX_ON); + } + txdata(app, verb, 0); + break; + case ATMEL_RADIO_AUTOCRC_ON: + if (0 == (TRX_CTRL_1 & (1 << TX_AUTO_CRC_ON))) { //not enabled + atmel_radio_set_state(TRX_OFF); + // can only be safely set in TRX_OFF mode + TRX_CTRL_1 |= 1 << TX_AUTO_CRC_ON; + atmel_radio_set_state(RX_ON); + } - case ATMEL_RADIO_RX_FLUSH: - case ATMEL_RADIO_TX_FLUSH: + txdata(app, verb, 0); + break; + case ATMEL_RADIO_AUTOCRC_OFF: + if (TRX_CTRL_1 & (1 << TX_AUTO_CRC_ON)) { //enabled + atmel_radio_set_state(TRX_OFF); + // can only be safely set in TRX_OFF mode + TRX_CTRL_1 &= 0xDF & ~(1 << TX_AUTO_CRC_ON); + atmel_radio_set_state(RX_ON); + } + txdata(app, verb, 0); + break; default: debugstr("Not yet supported in ATMEL_RADIO"); txdata(app,verb,-1);