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 *******************************************************************/
38 #include "projectconfig.h"
39 #include "core/gpio/gpio.h"
41 #define CHB_CC1190_PRESENT 0 /// Set to 1 if CC1190 is being used
43 #define CHB_EEPROM_IEEE_ADDR CFG_CHIBI_EEPROM_IEEEADDR
44 #define CHB_EEPROM_SHORT_ADDR CFG_CHIBI_EEPROM_SHORTADDR
45 #define CHB_AT86RF212_VER_NUM 0x01
46 #define CHB_AT86RF212_PART_NUM 0x07
47 // #define CHB_BPSK 0 // set to 1 if want to use BPSK rather than OQPSK
49 #define CHB_SPI_CMD_RW 0xC0 /**< Register Write (short mode). */
50 #define CHB_SPI_CMD_RR 0x80 /**< Register Read (short mode). */
51 #define CHB_SPI_CMD_FW 0x60 /**< Frame Transmit Mode (long mode). */
52 #define CHB_SPI_CMD_FR 0x20 /**< Frame Receive Mode (long mode). */
53 #define CHB_SPI_CMD_SW 0x40 /**< SRAM Write. */
54 #define CHB_SPI_CMD_SR 0x00 /**< SRAM Read. */
55 #define CHB_SPI_CMD_RADDRM 0x7F /**< Register Address Mask. */
57 #define CHB_IRQ_BAT_LOW_MASK 0x80 /**< Mask for the BAT_LOW interrupt. */
58 #define CHB_IRQ_TRX_UR_MASK 0x40 /**< Mask for the TRX_UR interrupt. */
59 #define CHB_IRQ_TRX_END_MASK 0x08 /**< Mask for the TRX_END interrupt. */
60 #define CHB_IRQ_RX_START_MASK 0x04 /**< Mask for the RX_START interrupt. */
61 #define CHB_IRQ_PLL_UNLOCK_MASK 0x02 /**< Mask for the PLL_UNLOCK interrupt. */
62 #define CHB_IRQ_PLL_LOCK_MASK 0x01 /**< Mask for the PLL_LOCK interrupt. */
64 #define CHB_EINTPORT 1
66 #define CHB_EINTPIN_IOCONREG IOCON_PIO1_8
69 #define CHB_RSTPIN_IOCONREG IOCON_PIO1_9
70 #define CHB_SLPTRPORT 1
71 #define CHB_SLPTRPIN 10
72 #define CHB_SLPTRPIN_IOCONREG IOCON_PIO1_10
74 // if CC1190 present, set up the ports and pins for high gain mode control
75 #if (CHB_CC1190_PRESENT)
76 #define CHB_CC1190_HGM_PORT 1
77 #define CHB_CC1190_HGM_PIN 11
78 #define CHB_CC1190_HGM_IOCONREG IOCON_PIO1_11
81 //#define CHB_DDR_SLPTR DDRF
82 //#define CHB_DDR_RST DDRF
83 //#define CHB_RADIO_IRQ INT6_vect
84 //#define CHB_RADIO_IRQ_PIN INT6
86 #define CHB_ENTER_CRIT() __disable_irq()
87 #define CHB_LEAVE_CRIT() __enable_irq()
88 #define CHB_RST_ENABLE() do {gpioSetValue(CHB_RSTPORT, CHB_RSTPIN, 0); } while (0)
89 #define CHB_RST_DISABLE() do {gpioSetValue(CHB_RSTPORT, CHB_RSTPIN, 1); } while (0)
90 #define CHB_SLPTR_ENABLE() do {gpioSetValue(CHB_SLPTRPORT, CHB_SLPTRPIN, 1); } while (0)
91 #define CHB_SLPTR_DISABLE() do {gpioSetValue(CHB_SLPTRPORT, CHB_SLPTRPIN, 0); } while (0)
96 CCA_ED
= 1, /**< Use energy detection above threshold mode. */
97 CCA_CARRIER_SENSE
= 2, /**< Use carrier sense mode. */
98 CCA_CARRIER_SENSE_WITH_ED
= 3 /**< Use a combination of both energy detection and carrier sense. */
101 // configuration parameters
104 CHB_CHANNEL
= 1, // Replaced in projectconfig.h with CFG_CHIBI_CHANNEL
105 CHB_PAN_ID
= 0x1234, // Replaced in projectconfig.h with CFG_CHIBI_PANID
107 CHB_SHORT_ADDR
= 0x0,
109 CHB_MAX_FRAME_RETRIES
= 3,
110 CHB_MAX_CSMA_RETRIES
= 4,
111 CHB_CCA_MODE
= CCA_ED
,
114 CHB_CCA_ED_THRES
= 0x7,
117 CHB_FRM_VER
= 1 // accept 802.15.4 ver 0 or 1 frames
120 // register addresses
175 CHB_MAX_FRAME_RETRIES_POS
= 4,
176 CHB_MAX_CSMA_RETIRES_POS
= 1,
177 CHB_CSMA_SEED1_POS
= 0,
178 CHB_CCA_MODE_POS
= 5,
179 CHB_AUTO_CRC_POS
= 5,
181 CHB_TRAC_STATUS_POS
= 5,
183 CHB_OQPSK_TX_OFFSET
= 2,
184 CHB_BPSK_TX_OFFSET
= 3,
185 CHB_MIN_FRAME_LENGTH
= 3,
186 CHB_MAX_FRAME_LENGTH
= 0x7f,
187 CHB_PA_EXT_EN_POS
= 7
190 // transceiver timing
192 TIME_RST_PULSE_WIDTH
= 1,
193 TIME_P_ON_TO_CLKM_AVAIL
= 380,
194 TIME_SLEEP_TO_TRX_OFF
= 240,
195 TIME_TRX_OFF_TO_SLEEP
= 35,
196 TIME_PLL_ON_TRX_OFF
= 1,
197 TIME_TRX_OFF_RX_ON
= 110,
198 TIME_RX_ON_TRX_OFF
= 1,
199 TIME_PLL_ON_RX_ON
= 1,
200 TIME_RX_ON_PLL_ON
= 1,
201 TIME_PLL_LOCK_TIME
= 110,
202 TIME_BUSY_TX_PLL_ON
= 32,
203 TIME_ALL_STATES_TRX_OFF
= 1,
204 TIME_RESET_TRX_OFF
= 26,
205 TIME_TRX_IRQ_DELAY
= 9,
206 TIME_TRX_OFF_PLL_ON
= 110,
207 TIME_IRQ_PROCESSING_DLY
= 32
213 TRAC_SUCCESS_DATA_PENDING
= 1,
214 TRAC_WAIT_FOR_ACK
= 2,
215 TRAC_CHANNEL_ACCESS_FAIL
= 3,
222 RADIO_SUCCESS
= 0x40, /**< The requested service was performed successfully. */
223 RADIO_UNSUPPORTED_DEVICE
, /**< The connected device is not an Atmel AT86RF212. */
224 RADIO_INVALID_ARGUMENT
, /**< One or more of the supplied function arguments are invalid. */
225 RADIO_TIMED_OUT
, /**< The requested service timed out. */
226 RADIO_WRONG_STATE
, /**< The end-user tried to do an invalid state transition. */
227 RADIO_BUSY_STATE
, /**< The radio transceiver is busy receiving or transmitting. */
228 RADIO_STATE_TRANSITION_FAILED
, /**< The requested state transition could not be completed. */
229 RADIO_CCA_IDLE
, /**< Channel is clear, available to transmit a new frame. */
230 RADIO_CCA_BUSY
, /**< Channel busy. */
231 RADIO_TRX_BUSY
, /**< Transceiver is busy receiving or transmitting data. */
232 RADIO_BAT_LOW
, /**< Measured battery voltage is lower than voltage threshold. */
233 RADIO_BAT_OK
, /**< Measured battery voltage is above the voltage threshold. */
234 RADIO_CRC_FAILED
, /**< The CRC failed for the actual frame. */
235 RADIO_CHANNEL_ACCESS_FAILURE
, /**< The channel access failed during the auto mode. */
236 RADIO_NO_ACK
, /**< No acknowledge frame was received. */
239 // transceiver commands
244 CMD_FORCE_TRX_OFF
= 3,
245 CMD_FORCE_PLL_ON
= 4,
253 // transceiver states
268 RX_AACK_ON_NOCLK
= 29,
269 BUSY_RX_AACK_NOCLK
= 30,
273 // transceiver interrupt register
280 IRQ_CCA_ED_READY
= 4,
296 // See Table 7-15 for details
299 CHB_PWR_EU1_2DBM
= 0x63, // EU (868MHz) Linearized PA mode
300 CHB_PWR_EU1_1DBM
= 0x64, // Note: BPSK 20kbit/s only!
301 CHB_PWR_EU1_0DBM
= 0x65,
302 CHB_PWR_EU2_5DBM
= 0xE7, // EU (868MHz) Boost mode (but > supply current)
303 CHB_PWR_EU2_4DBM
= 0xE8, // 4-5dBM BPSK 20 kbit/s only!
304 CHB_PWR_EU2_3DBM
= 0xE9, // 0-3dBM O-QPSK 100/200/400 kbit/s or BPSK
305 CHB_PWR_EU2_2DBM
= 0xEA,
306 CHB_PWR_EU2_1DBM
= 0xCB,
307 CHB_PWR_EU2_0DBM
= 0xAB,
308 CHB_PWR_NA_10DBM
= 0xC0, // North America (915MHz)
309 CHB_PWR_NA_9DBM
= 0xA1,
310 CHB_PWR_NA_8DBM
= 0x81,
311 CHB_PWR_NA_7DBM
= 0x82,
312 CHB_PWR_NA_6DBM
= 0x83,
313 CHB_PWR_NA_5DBM
= 0x60,
314 CHB_PWR_NA_4DBM
= 0x61,
315 CHB_PWR_NA_3DBM
= 0x41,
316 CHB_PWR_NA_2DBM
= 0x42,
317 CHB_PWR_NA_1DBM
= 0x22,
318 CHB_PWR_NA_0DBM
= 0x23,
319 CHB_PWR_CHINA_5DBM
= 0xE7, // China (780MHz)
320 CHB_PWR_CHINA_4DBM
= 0xE8,
321 CHB_PWR_CHINA_3DBM
= 0xE9,
322 CHB_PWR_CHINA_2DBM
= 0xEA,
323 CHB_PWR_CHINA_1DBM
= 0xCA,
324 CHB_PWR_CHINA_0DBM
= 0xAA
327 // define receive state based on promiscuous mode setting
328 #if (CFG_CHIBI_PROMISCUOUS == 1)
329 #define RX_STATE RX_ON
331 #define RX_STATE RX_AACK_ON
334 void chb_drvr_init();
337 U8
chb_reg_read(U8 addr
);
338 U16
chb_reg_read16(U8 addr
);
339 void chb_reg_write(U8 addr
, U8 val
);
340 void chb_reg_write16(U8 addr
, U16 val
);
341 void chb_reg_write64(U8 addr
, U8
*val
);
342 void chb_reg_read_mod_write(U8 addr
, U8 val
, U8 mask
);
343 void chb_frame_write(U8
*hdr
, U8 hdr_len
, U8
*data
, U8 data_len
);
345 // general configuration
346 void chb_set_mode(U8 mode
);
347 U8
chb_set_channel(U8 channel
);
348 void chb_set_pwr(U8 val
);
349 void chb_set_ieee_addr(U8
*addr
);
350 void chb_get_ieee_addr(U8
*addr
);
351 void chb_set_short_addr(U16 addr
);
352 U16
chb_get_short_addr();
353 U8
chb_set_state(U8 state
);
356 void chb_sleep(U8 enb
);
359 U8
chb_tx(U8
*hdr
, U8
*data
, U8 len
);
361 #if (CHB_CC1190_PRESENT)
362 void chb_set_hgm(U8 enb
);
367 void chb_sram_read(U8 addr
, U8 len
, U8
*data
);
368 void chb_sram_write(U8 addr
, U8 len
, U8
*data
);
371 void chb_ISR_Handler (void);