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);
199 /**************************************************************************/
203 /**************************************************************************/
204 void chb_reg_write16(U8 addr
, U16 val
)
210 chb_reg_write(addr
+ i
, val
>> (8 * i
));
214 /**************************************************************************/
218 /**************************************************************************/
219 void chb_reg_write64(U8 addr
, U8
*val
)
225 chb_reg_write(addr
+ i
, *(val
+ i
));
229 /**************************************************************************/
233 /**************************************************************************/
234 void chb_reg_read_mod_write(U8 addr
, U8 val
, U8 mask
)
238 tmp
= chb_reg_read(addr
);
239 val
&= mask
; // mask off stray bits from val
240 tmp
&= ~mask
; // mask off bits in reg val
241 tmp
|= val
; // copy val into reg val
242 chb_reg_write(addr
, tmp
); // write back to reg
245 /**************************************************************************/
249 /**************************************************************************/
250 void chb_frame_write(U8
*hdr
, U8 hdr_len
, U8
*data
, U8 data_len
)
255 // dont allow transmission longer than max frame size
256 if ((hdr_len
+ data_len
) > 127)
261 // initiate spi transaction
265 // send fifo write command
266 // dummy = chb_xfer_byte(CHB_SPI_CMD_FW);
267 chb_xfer_byte(CHB_SPI_CMD_FW
);
269 // write hdr contents to fifo
270 for (i
=0; i
<hdr_len
; i
++)
272 // dummy = chb_xfer_byte(*hdr++);
273 chb_xfer_byte(*hdr
++);
276 // write data contents to fifo
277 for (i
=0; i
<data_len
; i
++)
279 // dummy = chb_xfer_byte(*data++);
280 chb_xfer_byte(*data
++);
283 // terminate spi transaction
288 /**************************************************************************/
292 /**************************************************************************/
293 static void chb_frame_read()
300 /*Send frame read command and read the length.*/
301 chb_xfer_byte(CHB_SPI_CMD_FR
);
302 len
= chb_xfer_byte(0);
304 /*Check for correct frame length.*/
305 if ((len
>= CHB_MIN_FRAME_LENGTH
) && (len
<= CHB_MAX_FRAME_LENGTH
))
307 // check to see if there is room to write the frame in the buffer. if not, then drop it
308 if (len
< (CFG_CHIBI_BUFFERSIZE
- chb_buf_get_len()))
312 for (i
=0; i
<len
; i
++)
314 data
= chb_xfer_byte(0);
320 // we've overflowed the buffer. toss the data and do some housekeeping
321 chb_pcb_t
*pcb
= chb_get_pcb();
323 // read out the data and throw it away
324 for (i
=0; i
<len
; i
++)
326 data
= chb_xfer_byte(0);
329 // Increment the overflow stat
332 // print the error message
333 printf(chb_err_overflow
);
341 /**************************************************************************/
343 Read directly from the SRAM on the radio. This is only used for debugging
346 /**************************************************************************/
348 void chb_sram_read(U8 addr
, U8 len
, U8
*data
)
355 /*Send SRAM read command.*/
356 dummy
= chb_xfer_byte(CHB_SPI_CMD_SR
);
358 /*Send address where to start reading.*/
359 dummy
= chb_xfer_byte(addr
);
361 for (i
=0; i
<len
; i
++)
363 *data
++ = chb_xfer_byte(0);
370 /**************************************************************************/
374 /**************************************************************************/
375 void chb_sram_write(U8 addr
, U8 len
, U8
*data
)
382 /*Send SRAM write command.*/
383 dummy
= chb_xfer_byte(CHB_SPI_CMD_SW
);
385 /*Send address where to start writing to.*/
386 dummy
= chb_xfer_byte(addr
);
388 for (i
=0; i
<len
; i
++)
390 dummy
= chb_xfer_byte(*data
++);
398 /**************************************************************************/
400 Set the channel mode, BPSK, OQPSK, etc...
402 /**************************************************************************/
403 void chb_set_mode(U8 mode
)
408 chb_reg_read_mod_write(TRX_CTRL_2
, 0x08, 0x3f); // 802.15.4-2006, channel page 2, channel 0 (868 MHz, Europe)
409 chb_reg_read_mod_write(RF_CTRL_0
, CHB_OQPSK_TX_OFFSET
, 0x3); // this is according to table 7-16 in at86rf212 datasheet
412 chb_reg_read_mod_write(TRX_CTRL_2
, 0x0c, 0x3f); // 802.15.4-2006, channel page 2, channels 1-10 (915 MHz, US)
413 chb_reg_read_mod_write(RF_CTRL_0
, CHB_OQPSK_TX_OFFSET
, 0x3); // this is according to table 7-16 in at86rf212 datasheet
416 chb_reg_read_mod_write(TRX_CTRL_2
, 0x1c, 0x3f); // 802.15.4-2006, channel page 5, channel 0-3 (780 MHz, China)
417 chb_reg_read_mod_write(RF_CTRL_0
, CHB_OQPSK_TX_OFFSET
, 0x3); // this is according to table 7-16 in at86rf212 datasheet
420 chb_reg_read_mod_write(TRX_CTRL_2
, 0x00, 0x3f); // 802.15.4-2006, BPSK, 40 kbps
421 chb_reg_read_mod_write(RF_CTRL_0
, CHB_BPSK_TX_OFFSET
, 0x3); // this is according to table 7-16 in at86rf212 datasheet
424 chb_reg_read_mod_write(TRX_CTRL_2
, 0x00, 0x3f); // 802.15.4-2006, BPSK, 20 kbps
425 chb_reg_read_mod_write(RF_CTRL_0
, CHB_BPSK_TX_OFFSET
, 0x3); // this is according to table 7-16 in at86rf212 datasheet
430 /**************************************************************************/
434 /**************************************************************************/
435 U8
chb_set_channel(U8 channel
)
441 // this if for China only which uses a 780 MHz frequency band
442 if ((chb_reg_read(TRX_CTRL2
) & 0x3f) != 0x1c)
444 chb_reg_read_mod_write(TRX_CTRL2
, 0x1c, 0x3f);
452 channel
= (channel
<< 1) + 11;
454 chb_reg_read_mod_write(CC_CTRL_1
, 0x4, 0x7); // set 769 MHz base frequency for China
455 chb_reg_write(CC_CTRL_0
, channel
); // set the center frequency for the channel
460 // // Channel 0 is for European use only. make sure we are using channel page 2,
461 // // channel 0 settings for 100 kbps
462 // if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x08)
464 // chb_reg_read_mod_write(TRX_CTRL_2, 0x08, 0x3f);
467 //else if (channel > 10)
469 // // if the channel is out of bounds for page 2, then default to channel 1 and
470 // // assume we're on the US frequency of 915 MHz
472 // if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x0c)
474 // chb_reg_read_mod_write(TRX_CTRL_2, 0x0c, 0x3f);
479 // // Channels 1-10 are for US frequencies of 915 MHz
480 // if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x0c)
482 // chb_reg_read_mod_write(TRX_CTRL_2, 0x0c, 0x3f);
486 chb_reg_read_mod_write(PHY_CC_CCA
, channel
, 0x1f);
489 // add a delay to allow the PLL to lock if in active mode.
490 state
= chb_get_state();
491 if ((state
== RX_ON
) || (state
== PLL_ON
))
493 chb_delay_us(TIME_PLL_LOCK_TIME
);
496 return ((chb_reg_read(PHY_CC_CCA
) & 0x1f) == channel
) ? RADIO_SUCCESS
: RADIO_TIMED_OUT
;
499 /**************************************************************************/
503 /**************************************************************************/
504 void chb_set_pwr(U8 val
)
506 chb_reg_write(PHY_TX_PWR
, val
);
509 /**************************************************************************/
511 Set the TX/RX state machine state. Some manual manipulation is required
512 for certain operations. Check the datasheet for more details on the state
513 machine and manipulations.
515 /**************************************************************************/
516 U8
chb_set_state(U8 state
)
518 U8 curr_state
, delay
;
520 // if we're sleeping then don't allow transition
521 if (gpioGetValue(CHB_SLPTRPORT
, CHB_SLPTRPIN
))
523 return RADIO_WRONG_STATE
;
526 // if we're in a transition state, wait for the state to become stable
527 curr_state
= chb_get_state();
528 if ((curr_state
== BUSY_TX_ARET
) || (curr_state
== BUSY_RX_AACK
) || (curr_state
== BUSY_RX
) || (curr_state
== BUSY_TX
))
530 while (chb_get_state() == curr_state
);
533 // At this point it is clear that the requested new_state is:
534 // TRX_OFF, RX_ON, PLL_ON, RX_AACK_ON or TX_ARET_ON.
535 // we need to handle some special cases before we transition to the new state
539 /* Go to TRX_OFF from any state. */
541 chb_reg_read_mod_write(TRX_STATE
, CMD_FORCE_TRX_OFF
, 0x1f);
542 chb_delay_us(TIME_ALL_STATES_TRX_OFF
);
546 if (curr_state
== RX_AACK_ON
)
548 /* First do intermediate state transition to PLL_ON, then to TX_ARET_ON. */
549 chb_reg_read_mod_write(TRX_STATE
, CMD_PLL_ON
, 0x1f);
550 chb_delay_us(TIME_RX_ON_PLL_ON
);
555 if (curr_state
== TX_ARET_ON
)
557 /* First do intermediate state transition to RX_ON, then to RX_AACK_ON. */
558 chb_reg_read_mod_write(TRX_STATE
, CMD_PLL_ON
, 0x1f);
559 chb_delay_us(TIME_RX_ON_PLL_ON
);
564 /* Now we're okay to transition to any new state. */
565 chb_reg_read_mod_write(TRX_STATE
, state
, 0x1f);
567 /* When the PLL is active most states can be reached in 1us. However, from */
568 /* TRX_OFF the PLL needs time to activate. */
569 delay
= (curr_state
== TRX_OFF
) ? TIME_TRX_OFF_PLL_ON
: TIME_RX_ON_PLL_ON
;
572 if (chb_get_state() == state
)
574 return RADIO_SUCCESS
;
576 return RADIO_TIMED_OUT
;
579 /**************************************************************************/
583 /**************************************************************************/
584 void chb_set_ieee_addr(U8
*addr
)
586 chb_eeprom_write(CFG_EEPROM_CHIBI_IEEEADDR
, addr
, 8);
587 chb_reg_write64(IEEE_ADDR_0
, addr
);
590 /**************************************************************************/
594 /**************************************************************************/
595 void chb_get_ieee_addr(U8
*addr
)
597 chb_eeprom_read(CFG_EEPROM_CHIBI_IEEEADDR
, addr
, 8);
600 /**************************************************************************/
604 /**************************************************************************/
605 void chb_set_short_addr(U16 addr
)
607 U8
*addr_ptr
= (U8
*)&addr
;
608 chb_pcb_t
*pcb
= chb_get_pcb();
610 chb_eeprom_write(CFG_EEPROM_CHIBI_SHORTADDR
, addr_ptr
, 2);
611 chb_reg_write16(SHORT_ADDR_0
, addr
);
612 pcb
->src_addr
= addr
;
615 /**************************************************************************/
619 /**************************************************************************/
620 U16
chb_get_short_addr()
624 chb_eeprom_read(CFG_EEPROM_CHIBI_SHORTADDR
, (uint8_t*)&addr
, 2);
627 /**************************************************************************/
629 Set the high gain mode pin for the CC1190
631 /**************************************************************************/
632 #if (CHB_CC1190_PRESENT)
633 void chb_set_hgm(U8 enb
)
637 gpioSetValue(CHB_CC1190_HGM_PORT
, CHB_CC1190_HGM_PIN
, 1);
641 gpioSetValue(CHB_CC1190_HGM_PORT
, CHB_CC1190_HGM_PIN
, 0);
646 /**************************************************************************/
648 Load the data into the fifo, initiate a transmission attempt,
649 and return the status of the transmission attempt.
651 /**************************************************************************/
652 U8
chb_tx(U8
*hdr
, U8
*data
, U8 len
)
654 U8 state
= chb_get_state();
655 chb_pcb_t
*pcb
= chb_get_pcb();
657 if ((state
== BUSY_TX
) || (state
== BUSY_TX_ARET
))
659 return RADIO_WRONG_STATE
;
662 // TODO: check why we need to transition to the off state before we go to tx_aret_on
663 chb_set_state(TRX_OFF
);
664 chb_set_state(TX_ARET_ON
);
666 // TODO: try and start the frame transmission by writing TX_START command instead of toggling
667 // sleep pin...i just feel like it's kind of weird...
669 // write frame to buffer. first write header into buffer (add 1 for len byte), then data.
670 chb_frame_write(hdr
, CHB_HDR_SZ
+ 1, data
, len
);
672 //Do frame transmission
673 chb_reg_read_mod_write(TRX_STATE
, CMD_TX_START
, 0x1F);
675 // wait for the transmission to end, signalled by the TRX END flag
676 while (!pcb
->tx_end
);
679 // check the status of the transmission
680 return chb_get_status();
683 /**************************************************************************/
687 /**************************************************************************/
688 static void chb_radio_init()
695 // disable intps while we config the radio
696 chb_reg_write(IRQ_MASK
, 0);
698 // force transceiver off while we configure the intps
699 chb_reg_read_mod_write(TRX_STATE
, CMD_FORCE_TRX_OFF
, 0x1F);
701 // make sure the transceiver is in the off state before proceeding
702 while ((chb_reg_read(TRX_STATUS
) & 0x1f) != TRX_OFF
);
704 // set radio cfg parameters
705 // **note** uncomment if these will be set to something other than default
706 //chb_reg_read_mod_write(XAH_CTRL_0, CHB_MAX_FRAME_RETRIES << CHB_MAX_FRAME_RETRIES_POS, 0xF << CHB_MAX_FRAME_RETRIES_POS);
707 //chb_reg_read_mod_write(XAH_CTRL_0, CHB_MAX_CSMA_RETRIES << CHB_MAX_CSMA_RETIRES_POS, 0x7 << CHB_MAX_CSMA_RETIRES_POS);
708 //chb_reg_read_mod_write(CSMA_SEED_1, CHB_CSMA_SEED1 << CHB_CSMA_SEED1_POS, 0x7 << CHB_CSMA_SEED1_POS);
709 //chb_ret_write(CSMA_SEED0, CHB_CSMA_SEED0);
710 //chb_reg_read_mod_write(PHY_CC_CCA, CHB_CCA_MODE << CHB_CCA_MODE_POS,0x3 << CHB_CCA_MODE_POS);
711 //chb_reg_write(CCA_THRES, CHB_CCA_ED_THRES);
713 // set frame version that we'll accept
714 chb_reg_read_mod_write(CSMA_SEED_1
, CHB_FRM_VER
<< CHB_FVN_POS
, 3 << CHB_FVN_POS
);
716 // set interrupt mask
717 // re-enable intps while we config the radio
718 chb_reg_write(IRQ_MASK
, (1<<IRQ_RX_START
) | (1<<IRQ_TRX_END
));
720 #if (CFG_CHIBI_PROMISCUOUS == 0)
722 chb_reg_read_mod_write(TRX_CTRL_1
, 1 << CHB_AUTO_CRC_POS
, 1 << CHB_AUTO_CRC_POS
);
724 // set up default phy modulation, data rate and power (Ex. OQPSK, 100 kbps, 868 MHz, 3dBm)
725 chb_set_mode(CFG_CHIBI_MODE
); // Defined in projectconfig.h
726 chb_set_pwr(CFG_CHIBI_POWER
); // Defined in projectconfig.h
727 chb_set_channel(CFG_CHIBI_CHANNEL
); // Defined in projectconfig.h
730 // put trx in rx auto ack mode
731 chb_set_state(RX_STATE
);
734 chb_reg_write16(PAN_ID_0
, CFG_CHIBI_PANID
); // Defined in projectconfig.h
737 // NOTE: Possibly get this from EEPROM
738 chb_reg_write16(SHORT_ADDR_0
, chb_get_short_addr());
741 // NOTE: Possibly get this from EEPROM
742 chb_get_ieee_addr(ieee_addr
);
743 chb_reg_write64(IEEE_ADDR_0
, ieee_addr
);
745 #if (CHB_CC1190_PRESENT)
746 // set high gain mode pin to output and init to zero
747 gpioSetDir (CHB_CC1190_HGM_PORT
, CHB_CC1190_HGM_PIN
, 1);
748 gpioSetPullup (&CHB_CC1190_HGM_IOCONREG
, gpioPullupMode_Inactive
);
749 gpioSetValue (CHB_CC1190_HGM_PORT
, CHB_CC1190_HGM_PIN
, 0);
751 // set external power amp on AT86RF212
752 chb_reg_read_mod_write(TRX_CTRL_1
, 1<<CHB_PA_EXT_EN_POS
, 1<<CHB_PA_EXT_EN_POS
);
754 // set power to lowest level possible
755 chb_set_pwr(0xd); // set to -11 dBm
758 // set interrupt/gpio pin to input
759 gpioSetDir (CHB_EINTPORT
, CHB_EINTPIN
, 0);
761 // set internal resistor on EINT pin to inactive
762 gpioSetPullup (&CHB_EINTPIN_IOCONREG
, gpioPullupMode_Inactive
);
764 // configure pin for interrupt
765 gpioSetInterrupt (CHB_EINTPORT
,
767 gpioInterruptSense_Edge
, // Edge-sensitive
768 gpioInterruptEdge_Single
, // Single edge
769 gpioInterruptEvent_ActiveLow
); // High triggers interrupt
772 gpioIntEnable (CHB_EINTPORT
,
775 if (chb_get_state() != RX_STATE
)
777 // ERROR occurred initializing the radio. Print out error message.
778 printf(chb_err_init
);
782 /**************************************************************************/
786 /**************************************************************************/
789 // ToDo: Make sure gpioInit has been called
790 // ToDo: Make sure CT32B0 has been initialised and enabled
792 // config SPI for at86rf230 access
795 // Setup 16-bit timer 0 (used for us delays)
796 timer16Init(0, 0xFFFF);
799 // Set sleep and reset as output
800 gpioSetDir(CHB_SLPTRPORT
, CHB_SLPTRPIN
, 1);
801 gpioSetDir(CHB_RSTPORT
, CHB_RSTPIN
, 1);
804 gpioSetValue(CHB_SLPTRPORT
, CHB_SLPTRPIN
, 1); // Set sleep high
805 gpioSetValue(CHB_RSTPORT
, CHB_RSTPIN
, 1); // Set reset high
807 // Set internal resistors
808 gpioSetPullup (&CHB_SLPTRPIN_IOCONREG
, gpioPullupMode_Inactive
);
809 gpioSetPullup (&CHB_RSTPIN_IOCONREG
, gpioPullupMode_Inactive
);
815 /**************************************************************************/
817 Enable or disable the radio's sleep mode.
819 /**************************************************************************/
820 void chb_sleep(U8 enb
)
824 // first we need to go to TRX OFF state
825 chb_set_state(TRX_OFF
);
828 // CHB_SLPTR_PORT |= _BV(CHB_SLPTR_PIN);
833 // make sure the SLPTR pin is low first
834 // CHB_SLPTR_PORT &= ~(_BV(CHB_SLPTR_PIN));
837 // we need to allow some time for the PLL to lock
838 chb_delay_us(TIME_SLEEP_TO_TRX_OFF
);
840 // Turn the transceiver back on
841 chb_set_state(RX_STATE
);
844 /**************************************************************************/
848 /**************************************************************************/
849 void chb_ISR_Handler (void)
851 // U8 dummy, state, intp_src = 0;
852 U8 state
, intp_src
= 0;
853 chb_pcb_t
*pcb
= chb_get_pcb();
857 /*Read Interrupt source.*/
860 /*Send Register address and read register content.*/
861 // dummy = chb_xfer_byte(IRQ_STATUS | CHB_SPI_CMD_RR);
862 chb_xfer_byte(IRQ_STATUS
| CHB_SPI_CMD_RR
);
863 intp_src
= chb_xfer_byte(0);
869 /*Handle the incomming interrupt. Prioritized.*/
870 if ((intp_src
& CHB_IRQ_RX_START_MASK
))
872 intp_src
&= ~CHB_IRQ_RX_START_MASK
;
874 else if (intp_src
& CHB_IRQ_TRX_END_MASK
)
876 state
= chb_get_state();
878 if ((state
== RX_ON
) || (state
== RX_AACK_ON
) || (state
== BUSY_RX_AACK
))
880 // get the ed measurement
881 pcb
->ed
= chb_reg_read(PHY_ED_LEVEL
);
884 pcb
->crc
= (chb_reg_read(PHY_RSSI
) & (1<<7)) ? 1 : 0;
886 // if the crc is not valid, then do not read the frame and set the rx flag
892 pcb
->data_rcv
= true;
899 intp_src
&= ~CHB_IRQ_TRX_END_MASK
;
900 while (chb_set_state(RX_STATE
) != RADIO_SUCCESS
);
902 else if (intp_src
& CHB_IRQ_TRX_UR_MASK
)
904 intp_src
&= ~CHB_IRQ_TRX_UR_MASK
;
907 else if (intp_src
& CHB_IRQ_PLL_UNLOCK_MASK
)
909 intp_src
&= ~CHB_IRQ_PLL_UNLOCK_MASK
;
911 else if (intp_src
& CHB_IRQ_PLL_LOCK_MASK
)
913 intp_src
&= ~CHB_IRQ_PLL_LOCK_MASK
;
915 else if (intp_src
& CHB_IRQ_BAT_LOW_MASK
)
917 intp_src
&= ~CHB_IRQ_BAT_LOW_MASK
;