1 /*! \file atmel_radio.c
2 \author bx forked from neighbor Travis Goodspeed
3 \brief Atmel Radio Register Interface
7 //Higher level left to client application.
11 #include <stdlib.h> //added for itoa
13 #include "atmel_radio.h"
16 //! Handles a Chipcon SPI command.
17 void atmel_radio_handle_fn( uint8_t const app,
21 // define the atmel_radio app's app_t
22 app_t const atmel_radio_app = {
28 atmel_radio_handle_fn,
34 "\tThe ATMEL_RADIO app adds support for the atmel radio.\n"
37 #define TRX_REGISTER_BASEADDR 0x140
38 inline void reg_write(u16 addr, u8 val)
40 *(u8*)(TRX_REGISTER_BASEADDR + addr) = val;
43 inline u8 reg_read(u16 addr)
45 return *(u8*)(TRX_REGISTER_BASEADDR + addr);
47 inline void reg_bit_write(u16 addr, u8 pos, u8 value)
51 old = reg_read(addr) & ~mask; //bits to keep
52 old = old | (value << pos); //bit to add
53 reg_write(addr, old); //write byte
57 void atmel_radio_set_state(u8 state) //based on zigduino-radio, radio_rfa.c
60 /* ensure not in state transition */
61 while (STATE_TRANSITION_IN_PROGRESS == (STATE_TRANSITION_IN_PROGRESS &TRX_STATE)) {}
72 default: //doesn't exist
78 retries = 140; /* enough to receive ongoing frame */
80 if (state == (state & TRX_STATUS)) {
88 void atmel_radiosetup(){
90 /* initialize transceiver
91 code based on zigduino-radio
94 TRXPR &= ~(1 << TRXRST);
96 //TRX_SLPTR_LOW. Make sure radio isn't sleeping
97 TRXPR &= ~(1 << SLPTR);
101 TRXPR |= (1 << TRXRST);
103 /* disable IRQ and clear any pending IRQs */
106 /* clear IRQ history by reading status*/
111 TRX_CTRL_1 &= 0xDF & ~(1 << TX_AUTO_CRC_ON);
113 /* enter TRX_OFF state */
114 atmel_radio_set_state(TRX_OFF);
116 /* enter RX_ON state */
117 atmel_radio_set_state(RX_ON);
122 void atmel_radio_pokebyte(u16 addr, u8 data) {
123 reg_write(addr, data);
126 u8 atmel_radio_peekbyte(u16 addr) {
127 return reg_read(addr);
130 //! Writes bytes into the Atmel's ram
131 void atmel_radio_pokeram(u16 addr, u8 *data, u16 len){
133 for (i = 0; i < len; i++ ) {
134 atmel_radio_pokebyte(addr+i, data[i]);
138 //! Read bytes from the Atmel's RAM.
139 void atmel_radio_peekram(u16 addr, u8 *data, u16 len){
142 for (i = 0; i < len; i++){
143 *data++=atmel_radio_peekbyte(addr+i);
147 int atmel_radio_is_frame_buffer_empty() {
151 void atmel_radio_clear_frame_buffer() {
152 TRXFBST = 0; //reset the frame buffer pointer to signal it was read
155 //! Handles a Chipcon SPI command.
156 void atmel_radio_handle_fn( uint8_t const app,
167 length=cmddataword[1]; // Backup length. Second byte
168 atmel_radio_peekram(cmddataword[0], // First word is address
169 cmddata, // Return in same buffer
171 txdata(app,verb,length);
175 atmel_radio_pokeram(cmddataword[0], // First word is address
176 cmddata+2, // Remainder of buffer is data
177 len-2); //Length implied by packet length
178 txdata(app,verb,len-2); //return number of poked bytes
187 // set to PLL_ON so frame buffer isn't clobbered
188 atmel_radio_set_state(PLL_ON);
190 if (!atmel_radio_is_frame_buffer_empty()) { //only if we recieved something new
191 len8 = TST_RX_LENGTH; //register contains frame length
193 if ((len8 > 0x80) ) { //frame too big
196 memcpy(cmddata, (void *) &TRXFBST, len8); //return in same buffer
197 atmel_radio_clear_frame_buffer();
198 txdata(app, verb, len8);
201 // didn't recieve anything new
204 // receive packets again
205 atmel_radio_set_state(RX_ON);
209 //prevent radio from recieving new packets
210 atmel_radio_set_state(PLL_ON);
211 if (cmddata[0] > 127) { //truncate too long packets
215 memcpy((void *) &TRXFBST, cmddata, cmddata[0]+1); //copy length + packet
216 atmel_radio_set_state(BUSY_TX); //send packet
218 while (PLL_ON != (PLL_ON & TRX_STATUS)) {} //wait for TX done
219 //reset the frame buffer pointer to signal it was read
220 atmel_radio_clear_frame_buffer();
221 atmel_radio_set_state(RX_ON);
222 txdata(app, verb, len8);
226 case ATMEL_RADIO_RX_FLUSH:
227 case ATMEL_RADIO_TX_FLUSH:
229 debugstr("Not yet supported in ATMEL_RADIO");