1 /*******************************************************************
2 Copyright (C) 2009 FreakLabs
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 2. Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 3. Neither the name of the the copyright holder nor the names of its contributors
15 may be used to endorse or promote products derived from this software
16 without specific prior written permission.
18 THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
22 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 Originally written by Christopher Wang aka Akiba.
31 Please post support questions to the FreakLabs forum.
33 *******************************************************************/
39 #include "chb_eeprom.h"
41 #include "core/systick/systick.h"
42 #include "core/timer16/timer16.h"
44 // store string messages in flash rather than RAM
45 const char chb_err_overflow
[] = "BUFFER FULL. TOSSING INCOMING DATA\r\n";
46 const char chb_err_init
[] = "RADIO NOT INITIALIZED PROPERLY\r\n";
47 /**************************************************************************/
51 /**************************************************************************/
52 static U8
chb_get_state()
54 return chb_reg_read(TRX_STATUS
) & 0x1f;
57 /**************************************************************************/
61 /**************************************************************************/
62 static U8
chb_get_status()
64 return chb_reg_read(TRX_STATE
) >> CHB_TRAC_STATUS_POS
;
67 /**************************************************************************/
69 Cause a blocking delay for x microseconds
71 /**************************************************************************/
72 static void chb_delay_us(U16 usec
)
74 // Determine maximum delay using a 16 bit timer
75 // ToDo: Move this to a macro or fixed value!
76 uint32_t maxus
= 0xFFFF / (CFG_CPU_CCLK
/ 1000000);
78 // Check if delay can be done in one operation
81 timer16DelayUS(0, usec
);
85 // Split delay into several steps (to stay within limit of 16-bit timer)
90 timer16DelayUS(0, maxus
);
95 timer16DelayUS(0, usec
);
101 /**************************************************************************/
105 /**************************************************************************/
111 // wait a bit while transceiver wakes up
112 chb_delay_us(TIME_P_ON_TO_CLKM_AVAIL
);
116 chb_delay_us(TIME_RST_PULSE_WIDTH
);
119 // check that we have the part number that we're expecting
122 // if you're stuck in this loop, that means that you're not reading
123 // the version and part number register correctly. possible that version number
124 // changes. if so, update version num in header file
125 if ((chb_reg_read(VERSION_NUM
) == CHB_AT86RF212_VER_NUM
) && (chb_reg_read(PART_NUM
) == CHB_AT86RF212_PART_NUM
))
132 /**************************************************************************/
136 /**************************************************************************/
137 U8
chb_reg_read(U8 addr
)
141 /* Add the register read command to the register address. */
147 /*Send Register address and read register content.*/
148 val
= chb_xfer_byte(addr
);
149 val
= chb_xfer_byte(val
);
157 /**************************************************************************/
161 /**************************************************************************/
162 U16
chb_reg_read16(U8 addr
)
169 addr
|= chb_reg_read(addr
+ i
) << (8 * i
);
174 /**************************************************************************/
178 /**************************************************************************/
179 void chb_reg_write(U8 addr
, U8 val
)
183 /* Add the Register Write command to the address. */
189 /*Send Register address and write register content.*/
190 dummy
= chb_xfer_byte(addr
);
191 dummy
= chb_xfer_byte(val
);
197 /**************************************************************************/
201 /**************************************************************************/
202 void chb_reg_write16(U8 addr
, U16 val
)
208 chb_reg_write(addr
+ i
, val
>> (8 * i
));
212 /**************************************************************************/
216 /**************************************************************************/
217 void chb_reg_write64(U8 addr
, U8
*val
)
223 chb_reg_write(addr
+ i
, *(val
+ i
));
227 /**************************************************************************/
231 /**************************************************************************/
232 void chb_reg_read_mod_write(U8 addr
, U8 val
, U8 mask
)
236 tmp
= chb_reg_read(addr
);
237 val
&= mask
; // mask off stray bits from val
238 tmp
&= ~mask
; // mask off bits in reg val
239 tmp
|= val
; // copy val into reg val
240 chb_reg_write(addr
, tmp
); // write back to reg
243 /**************************************************************************/
247 /**************************************************************************/
248 void chb_frame_write(U8
*hdr
, U8 hdr_len
, U8
*data
, U8 data_len
)
252 // dont allow transmission longer than max frame size
253 if ((hdr_len
+ data_len
) > 127)
258 // initiate spi transaction
262 // send fifo write command
263 dummy
= chb_xfer_byte(CHB_SPI_CMD_FW
);
265 // write hdr contents to fifo
266 for (i
=0; i
<hdr_len
; i
++)
268 dummy
= chb_xfer_byte(*hdr
++);
271 // write data contents to fifo
272 for (i
=0; i
<data_len
; i
++)
274 dummy
= chb_xfer_byte(*data
++);
277 // terminate spi transaction
282 /**************************************************************************/
286 /**************************************************************************/
287 static void chb_frame_read()
294 /*Send frame read command and read the length.*/
295 chb_xfer_byte(CHB_SPI_CMD_FR
);
296 len
= chb_xfer_byte(0);
298 /*Check for correct frame length.*/
299 if ((len
>= CHB_MIN_FRAME_LENGTH
) && (len
<= CHB_MAX_FRAME_LENGTH
))
301 // check to see if there is room to write the frame in the buffer. if not, then drop it
302 if (len
< (CFG_CHIBI_BUFFERSIZE
- chb_buf_get_len()))
306 for (i
=0; i
<len
; i
++)
308 data
= chb_xfer_byte(0);
314 // we've overflowed the buffer. toss the data and do some housekeeping
315 chb_pcb_t
*pcb
= chb_get_pcb();
317 // read out the data and throw it away
318 for (i
=0; i
<len
; i
++)
320 data
= chb_xfer_byte(0);
323 // Increment the overflow stat
326 // print the error message
327 printf(chb_err_overflow
);
335 /**************************************************************************/
337 Read directly from the SRAM on the radio. This is only used for debugging
340 /**************************************************************************/
342 void chb_sram_read(U8 addr
, U8 len
, U8
*data
)
349 /*Send SRAM read command.*/
350 dummy
= chb_xfer_byte(CHB_SPI_CMD_SR
);
352 /*Send address where to start reading.*/
353 dummy
= chb_xfer_byte(addr
);
355 for (i
=0; i
<len
; i
++)
357 *data
++ = chb_xfer_byte(0);
364 /**************************************************************************/
368 /**************************************************************************/
369 void chb_sram_write(U8 addr
, U8 len
, U8
*data
)
376 /*Send SRAM write command.*/
377 dummy
= chb_xfer_byte(CHB_SPI_CMD_SW
);
379 /*Send address where to start writing to.*/
380 dummy
= chb_xfer_byte(addr
);
382 for (i
=0; i
<len
; i
++)
384 dummy
= chb_xfer_byte(*data
++);
392 /**************************************************************************/
394 Set the channel mode, BPSK, OQPSK, etc...
396 /**************************************************************************/
397 void chb_set_mode(U8 mode
)
402 chb_reg_read_mod_write(TRX_CTRL_2
, 0x08, 0x3f); // 802.15.4-2006, channel page 2, channel 0 (868 MHz, Europe)
403 chb_reg_read_mod_write(RF_CTRL_0
, CHB_OQPSK_TX_OFFSET
, 0x3); // this is according to table 7-16 in at86rf212 datasheet
406 chb_reg_read_mod_write(TRX_CTRL_2
, 0x0c, 0x3f); // 802.15.4-2006, channel page 2, channels 1-10 (915 MHz, US)
407 chb_reg_read_mod_write(RF_CTRL_0
, CHB_OQPSK_TX_OFFSET
, 0x3); // this is according to table 7-16 in at86rf212 datasheet
410 chb_reg_read_mod_write(TRX_CTRL_2
, 0x1c, 0x3f); // 802.15.4-2006, channel page 5, channel 0-3 (780 MHz, China)
411 chb_reg_read_mod_write(RF_CTRL_0
, CHB_OQPSK_TX_OFFSET
, 0x3); // this is according to table 7-16 in at86rf212 datasheet
414 chb_reg_read_mod_write(TRX_CTRL_2
, 0x00, 0x3f); // 802.15.4-2006, BPSK, 40 kbps
415 chb_reg_read_mod_write(RF_CTRL_0
, CHB_BPSK_TX_OFFSET
, 0x3); // this is according to table 7-16 in at86rf212 datasheet
418 chb_reg_read_mod_write(TRX_CTRL_2
, 0x00, 0x3f); // 802.15.4-2006, BPSK, 20 kbps
419 chb_reg_read_mod_write(RF_CTRL_0
, CHB_BPSK_TX_OFFSET
, 0x3); // this is according to table 7-16 in at86rf212 datasheet
424 /**************************************************************************/
428 /**************************************************************************/
429 U8
chb_set_channel(U8 channel
)
435 // this if for China only which uses a 780 MHz frequency band
436 if ((chb_reg_read(TRX_CTRL2
) & 0x3f) != 0x1c)
438 chb_reg_read_mod_write(TRX_CTRL2
, 0x1c, 0x3f);
446 channel
= (channel
<< 1) + 11;
448 chb_reg_read_mod_write(CC_CTRL_1
, 0x4, 0x7); // set 769 MHz base frequency for China
449 chb_reg_write(CC_CTRL_0
, channel
); // set the center frequency for the channel
454 // // Channel 0 is for European use only. make sure we are using channel page 2,
455 // // channel 0 settings for 100 kbps
456 // if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x08)
458 // chb_reg_read_mod_write(TRX_CTRL_2, 0x08, 0x3f);
461 //else if (channel > 10)
463 // // if the channel is out of bounds for page 2, then default to channel 1 and
464 // // assume we're on the US frequency of 915 MHz
466 // if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x0c)
468 // chb_reg_read_mod_write(TRX_CTRL_2, 0x0c, 0x3f);
473 // // Channels 1-10 are for US frequencies of 915 MHz
474 // if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x0c)
476 // chb_reg_read_mod_write(TRX_CTRL_2, 0x0c, 0x3f);
480 chb_reg_read_mod_write(PHY_CC_CCA
, channel
, 0x1f);
483 // add a delay to allow the PLL to lock if in active mode.
484 state
= chb_get_state();
485 if ((state
== RX_ON
) || (state
== PLL_ON
))
487 chb_delay_us(TIME_PLL_LOCK_TIME
);
490 return ((chb_reg_read(PHY_CC_CCA
) & 0x1f) == channel
) ? RADIO_SUCCESS
: RADIO_TIMED_OUT
;
493 /**************************************************************************/
497 /**************************************************************************/
498 void chb_set_pwr(U8 val
)
500 chb_reg_write(PHY_TX_PWR
, val
);
503 /**************************************************************************/
505 Set the TX/RX state machine state. Some manual manipulation is required
506 for certain operations. Check the datasheet for more details on the state
507 machine and manipulations.
509 /**************************************************************************/
510 U8
chb_set_state(U8 state
)
512 U8 curr_state
, delay
;
514 // if we're sleeping then don't allow transition
515 if (gpioGetValue(CHB_SLPTRPORT
, CHB_SLPTRPIN
))
517 return RADIO_WRONG_STATE
;
520 // if we're in a transition state, wait for the state to become stable
521 curr_state
= chb_get_state();
522 if ((curr_state
== BUSY_TX_ARET
) || (curr_state
== BUSY_RX_AACK
) || (curr_state
== BUSY_RX
) || (curr_state
== BUSY_TX
))
524 while (chb_get_state() == curr_state
);
527 // At this point it is clear that the requested new_state is:
528 // TRX_OFF, RX_ON, PLL_ON, RX_AACK_ON or TX_ARET_ON.
529 // we need to handle some special cases before we transition to the new state
533 /* Go to TRX_OFF from any state. */
535 chb_reg_read_mod_write(TRX_STATE
, CMD_FORCE_TRX_OFF
, 0x1f);
536 chb_delay_us(TIME_ALL_STATES_TRX_OFF
);
540 if (curr_state
== RX_AACK_ON
)
542 /* First do intermediate state transition to PLL_ON, then to TX_ARET_ON. */
543 chb_reg_read_mod_write(TRX_STATE
, CMD_PLL_ON
, 0x1f);
544 chb_delay_us(TIME_RX_ON_PLL_ON
);
549 if (curr_state
== TX_ARET_ON
)
551 /* First do intermediate state transition to RX_ON, then to RX_AACK_ON. */
552 chb_reg_read_mod_write(TRX_STATE
, CMD_PLL_ON
, 0x1f);
553 chb_delay_us(TIME_RX_ON_PLL_ON
);
558 /* Now we're okay to transition to any new state. */
559 chb_reg_read_mod_write(TRX_STATE
, state
, 0x1f);
561 /* When the PLL is active most states can be reached in 1us. However, from */
562 /* TRX_OFF the PLL needs time to activate. */
563 delay
= (curr_state
== TRX_OFF
) ? TIME_TRX_OFF_PLL_ON
: TIME_RX_ON_PLL_ON
;
566 if (chb_get_state() == state
)
568 return RADIO_SUCCESS
;
570 return RADIO_TIMED_OUT
;
573 /**************************************************************************/
577 /**************************************************************************/
578 void chb_set_ieee_addr(U8
*addr
)
580 chb_eeprom_write(CFG_EEPROM_CHIBI_IEEEADDR
, addr
, 8);
581 chb_reg_write64(IEEE_ADDR_0
, addr
);
584 /**************************************************************************/
588 /**************************************************************************/
589 void chb_get_ieee_addr(U8
*addr
)
591 chb_eeprom_read(CFG_EEPROM_CHIBI_IEEEADDR
, addr
, 8);
594 /**************************************************************************/
598 /**************************************************************************/
599 void chb_set_short_addr(U16 addr
)
601 U8
*addr_ptr
= (U8
*)&addr
;
602 chb_pcb_t
*pcb
= chb_get_pcb();
604 chb_eeprom_write(CFG_EEPROM_CHIBI_SHORTADDR
, addr_ptr
, 2);
605 chb_reg_write16(SHORT_ADDR_0
, addr
);
606 pcb
->src_addr
= addr
;
609 /**************************************************************************/
613 /**************************************************************************/
614 U16
chb_get_short_addr()
618 chb_eeprom_read(CFG_EEPROM_CHIBI_SHORTADDR
, (uint8_t*)&addr
, 2);
621 /**************************************************************************/
623 Set the high gain mode pin for the CC1190
625 /**************************************************************************/
626 #if (CHB_CC1190_PRESENT)
627 void chb_set_hgm(U8 enb
)
631 gpioSetValue(CHB_CC1190_HGM_PORT
, CHB_CC1190_HGM_PIN
, 1);
635 gpioSetValue(CHB_CC1190_HGM_PORT
, CHB_CC1190_HGM_PIN
, 0);
640 /**************************************************************************/
642 Load the data into the fifo, initiate a transmission attempt,
643 and return the status of the transmission attempt.
645 /**************************************************************************/
646 U8
chb_tx(U8
*hdr
, U8
*data
, U8 len
)
648 U8 state
= chb_get_state();
649 chb_pcb_t
*pcb
= chb_get_pcb();
651 if ((state
== BUSY_TX
) || (state
== BUSY_TX_ARET
))
653 return RADIO_WRONG_STATE
;
656 // TODO: check why we need to transition to the off state before we go to tx_aret_on
657 chb_set_state(TRX_OFF
);
658 chb_set_state(TX_ARET_ON
);
660 // TODO: try and start the frame transmission by writing TX_START command instead of toggling
661 // sleep pin...i just feel like it's kind of weird...
663 // write frame to buffer. first write header into buffer (add 1 for len byte), then data.
664 chb_frame_write(hdr
, CHB_HDR_SZ
+ 1, data
, len
);
666 //Do frame transmission
667 chb_reg_read_mod_write(TRX_STATE
, CMD_TX_START
, 0x1F);
669 // wait for the transmission to end, signalled by the TRX END flag
670 while (!pcb
->tx_end
);
673 // check the status of the transmission
674 return chb_get_status();
677 /**************************************************************************/
681 /**************************************************************************/
682 static void chb_radio_init()
689 // disable intps while we config the radio
690 chb_reg_write(IRQ_MASK
, 0);
692 // force transceiver off while we configure the intps
693 chb_reg_read_mod_write(TRX_STATE
, CMD_FORCE_TRX_OFF
, 0x1F);
695 // make sure the transceiver is in the off state before proceeding
696 while ((chb_reg_read(TRX_STATUS
) & 0x1f) != TRX_OFF
);
698 // set radio cfg parameters
699 // **note** uncomment if these will be set to something other than default
700 //chb_reg_read_mod_write(XAH_CTRL_0, CHB_MAX_FRAME_RETRIES << CHB_MAX_FRAME_RETRIES_POS, 0xF << CHB_MAX_FRAME_RETRIES_POS);
701 //chb_reg_read_mod_write(XAH_CTRL_0, CHB_MAX_CSMA_RETRIES << CHB_MAX_CSMA_RETIRES_POS, 0x7 << CHB_MAX_CSMA_RETIRES_POS);
702 //chb_reg_read_mod_write(CSMA_SEED_1, CHB_CSMA_SEED1 << CHB_CSMA_SEED1_POS, 0x7 << CHB_CSMA_SEED1_POS);
703 //chb_ret_write(CSMA_SEED0, CHB_CSMA_SEED0);
704 //chb_reg_read_mod_write(PHY_CC_CCA, CHB_CCA_MODE << CHB_CCA_MODE_POS,0x3 << CHB_CCA_MODE_POS);
705 //chb_reg_write(CCA_THRES, CHB_CCA_ED_THRES);
707 // set frame version that we'll accept
708 chb_reg_read_mod_write(CSMA_SEED_1
, CHB_FRM_VER
<< CHB_FVN_POS
, 3 << CHB_FVN_POS
);
710 // set interrupt mask
711 // re-enable intps while we config the radio
712 chb_reg_write(IRQ_MASK
, (1<<IRQ_RX_START
) | (1<<IRQ_TRX_END
));
714 #if (CFG_CHIBI_PROMISCUOUS == 0)
716 chb_reg_read_mod_write(TRX_CTRL_1
, 1 << CHB_AUTO_CRC_POS
, 1 << CHB_AUTO_CRC_POS
);
718 // set up default phy modulation, data rate and power (Ex. OQPSK, 100 kbps, 868 MHz, 3dBm)
719 chb_set_mode(CFG_CHIBI_MODE
); // Defined in projectconfig.h
720 chb_set_pwr(CFG_CHIBI_POWER
); // Defined in projectconfig.h
721 chb_set_channel(CFG_CHIBI_CHANNEL
); // Defined in projectconfig.h
724 // put trx in rx auto ack mode
725 chb_set_state(RX_STATE
);
728 chb_reg_write16(PAN_ID_0
, CFG_CHIBI_PANID
); // Defined in projectconfig.h
731 // NOTE: Possibly get this from EEPROM
732 chb_reg_write16(SHORT_ADDR_0
, chb_get_short_addr());
735 // NOTE: Possibly get this from EEPROM
736 chb_get_ieee_addr(ieee_addr
);
737 chb_reg_write64(IEEE_ADDR_0
, ieee_addr
);
739 #if (CHB_CC1190_PRESENT)
740 // set high gain mode pin to output and init to zero
741 gpioSetDir (CHB_CC1190_HGM_PORT
, CHB_CC1190_HGM_PIN
, 1);
742 gpioSetPullup (&CHB_CC1190_HGM_IOCONREG
, gpioPullupMode_Inactive
);
743 gpioSetValue (CHB_CC1190_HGM_PORT
, CHB_CC1190_HGM_PIN
, 0);
745 // set external power amp on AT86RF212
746 chb_reg_read_mod_write(TRX_CTRL_1
, 1<<CHB_PA_EXT_EN_POS
, 1<<CHB_PA_EXT_EN_POS
);
748 // set power to lowest level possible
749 chb_set_pwr(0xd); // set to -11 dBm
752 // set interrupt/gpio pin to input
753 gpioSetDir (CHB_EINTPORT
, CHB_EINTPIN
, 0);
755 // set internal resistor on EINT pin to inactive
756 gpioSetPullup (&CHB_EINTPIN_IOCONREG
, gpioPullupMode_Inactive
);
758 // configure pin for interrupt
759 gpioSetInterrupt (CHB_EINTPORT
,
761 gpioInterruptSense_Edge
, // Edge-sensitive
762 gpioInterruptEdge_Single
, // Single edge
763 gpioInterruptEvent_ActiveHigh
); // High triggers interrupt
766 gpioIntEnable (CHB_EINTPORT
,
769 if (chb_get_state() != RX_STATE
)
771 // ERROR occurred initializing the radio. Print out error message.
772 printf(chb_err_init
);
776 /**************************************************************************/
780 /**************************************************************************/
783 // ToDo: Make sure gpioInit has been called
784 // ToDo: Make sure CT32B0 has been initialised and enabled
786 // config SPI for at86rf230 access
789 // Setup 16-bit timer 0 (used for us delays)
790 timer16Init(0, 0xFFFF);
793 // Set sleep and reset as output
794 gpioSetDir(CHB_SLPTRPORT
, CHB_SLPTRPIN
, 1);
795 gpioSetDir(CHB_RSTPORT
, CHB_RSTPIN
, 1);
798 gpioSetValue(CHB_SLPTRPORT
, CHB_SLPTRPIN
, 1); // Set sleep high
799 gpioSetValue(CHB_RSTPORT
, CHB_RSTPIN
, 1); // Set reset high
801 // Set internal resistors
802 gpioSetPullup (&CHB_SLPTRPIN_IOCONREG
, gpioPullupMode_Inactive
);
803 gpioSetPullup (&CHB_RSTPIN_IOCONREG
, gpioPullupMode_Inactive
);
809 /**************************************************************************/
811 Enable or disable the radio's sleep mode.
813 /**************************************************************************/
814 void chb_sleep(U8 enb
)
818 // first we need to go to TRX OFF state
819 chb_set_state(TRX_OFF
);
822 // CHB_SLPTR_PORT |= _BV(CHB_SLPTR_PIN);
827 // make sure the SLPTR pin is low first
828 // CHB_SLPTR_PORT &= ~(_BV(CHB_SLPTR_PIN));
831 // we need to allow some time for the PLL to lock
832 chb_delay_us(TIME_SLEEP_TO_TRX_OFF
);
834 // Turn the transceiver back on
835 chb_set_state(RX_STATE
);
838 /**************************************************************************/
842 /**************************************************************************/
843 void chb_ISR_Handler (void)
845 U8 dummy
, state
, intp_src
= 0;
846 chb_pcb_t
*pcb
= chb_get_pcb();
850 /*Read Interrupt source.*/
853 /*Send Register address and read register content.*/
854 dummy
= chb_xfer_byte(IRQ_STATUS
| CHB_SPI_CMD_RR
);
855 intp_src
= chb_xfer_byte(0);
861 /*Handle the incomming interrupt. Prioritized.*/
862 if ((intp_src
& CHB_IRQ_RX_START_MASK
))
864 intp_src
&= ~CHB_IRQ_RX_START_MASK
;
866 else if (intp_src
& CHB_IRQ_TRX_END_MASK
)
868 state
= chb_get_state();
870 if ((state
== RX_ON
) || (state
== RX_AACK_ON
) || (state
== BUSY_RX_AACK
))
872 // get the ed measurement
873 pcb
->ed
= chb_reg_read(PHY_ED_LEVEL
);
876 pcb
->crc
= (chb_reg_read(PHY_RSSI
) & (1<<7)) ? 1 : 0;
878 // if the crc is not valid, then do not read the frame and set the rx flag
884 pcb
->data_rcv
= true;
891 intp_src
&= ~CHB_IRQ_TRX_END_MASK
;
892 while (chb_set_state(RX_STATE
) != RADIO_SUCCESS
);
894 else if (intp_src
& CHB_IRQ_TRX_UR_MASK
)
896 intp_src
&= ~CHB_IRQ_TRX_UR_MASK
;
899 else if (intp_src
& CHB_IRQ_PLL_UNLOCK_MASK
)
901 intp_src
&= ~CHB_IRQ_PLL_UNLOCK_MASK
;
903 else if (intp_src
& CHB_IRQ_PLL_LOCK_MASK
)
905 intp_src
&= ~CHB_IRQ_PLL_LOCK_MASK
;
907 else if (intp_src
& CHB_IRQ_BAT_LOW_MASK
)
909 intp_src
&= ~CHB_IRQ_BAT_LOW_MASK
;