Appiko
cc112x_drv.c
1 /******************************************************************************
2  * Filename: cc112x_drv.c
3  *
4  * Description: Radio driver abstraction layer, this uses the same concept
5  * as found in Contiki OS.
6  *
7  * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
8  *
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * Redistributions of source code must retain the above copyright
15  * notice, this list of conditions and the following disclaimer.
16  *
17  * Redistributions in binary form must reproduce the above copyright
18  * notice, this list of conditions and the following disclaimer in the
19  * documentation and/or other materials provided with the distribution.
20  *
21  * Neither the name of Texas Instruments Incorporated nor the names of
22  * its contributors may be used to endorse or promote products derived
23  * from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *
37  *******************************************************************************/
38 
39 /******************************************************************************
40  * INCLUDES
41  */
42 #include "stdlib.h"
43 #include "cc112x_def.h"
44 #include "radio_drv.h"
45 #include "hal_spi_rf.h"
46 #include "hal_nop_delay.h"
47 #include "log.h"
48 #include "hal_gpio.h"
49 //#include "cc112x_drv.h"
50 
51 #ifdef USE_CC112X
52 
53 /******************************************************************************
54  * DEFINES
55  */
56 #define RF_XTAL_FREQ RF_XTAL /* XTAL frequency, given in 1kHz steps */
57 #define RF_LO_DIVIDER 4 /* there is a hardware LO divider CC112x */
58 
59 /******************************************************************************
60  * GLOBALS - used by the driver
61  */
62 uint8_t rf_end_packet = 0;
63 
64 /******************************************************************************
65  * Configuration extracted from SmartRF Studio version 7 Release 2.0.0
66  */
67 // Address config = No address check
68 // Performance mode = High Performance
69 // Packet bit length = 0
70 // Symbol rate = 1.2
71 // Whitening = false
72 // Carrier frequency = 902.750000
73 // TX power = 15
74 // Manchester enable = false
75 // Packet length mode = Fixed
76 // Packet length = 20
77 // RX filter BW = 25.000000
78 // Deviation = 3.997803
79 // Device address = 0
80 // Bit rate = 1.2
81 // Modulation format = 2-FSK
82 // PA ramping = true
83 // Append packetinfo = false
84 
85 const registerSetting_t preferredSettings_1200bps[]=
86 {
87  {IOCFG3, 0xB0},
88  {IOCFG2, 0x06},
89  {IOCFG1, 0xB0},
90  {IOCFG0, 0x06},
91  {SYNC3, 0xD3},
92  {SYNC2, 0x91},
93  {SYNC1, 0xD3},
94  {SYNC0, 0x91},
95  {SYNC_CFG1, 0x0B},
96  {DCFILT_CFG, 0x1C},
97  {PREAMBLE_CFG1, 0x18},
98  {IQIC, 0xC6},
99  {CHAN_BW, 0x08},
100  {MDMCFG0, 0x05},
101  {SYMBOL_RATE2, 0x43},
102  {SYMBOL_RATE1, 0xA9},
103  {SYMBOL_RATE0, 0x2A},
104  {AGC_REF, 0x20},
105  {AGC_CS_THR, 0x19},
106  {AGC_CFG1, 0xA9},
107  {AGC_CFG0, 0xCF},
108  {FIFO_CFG, 0x00},
109  {SETTLING_CFG, 0x0B},
110  {FS_CFG, 0x12},
111  {PKT_CFG2, 0x04},
112  {PKT_CFG1, 0x04},
113  {PKT_CFG0, 0x00},
114  {PA_CFG2, 0x7F},
115  {PA_CFG1, 0x56},
116  {PA_CFG0, 0x7C},
117  {PKT_LEN, 0x14},
118  {IF_MIX_CFG, 0x00},
119  {FREQOFF_CFG, 0x22},
120  {FREQ2, 0x70},
121  {FREQ1, 0xD8},
122  {FS_DIG1, 0x00},
123  {FS_DIG0, 0x5F},
124  {FS_CAL1, 0x40},
125  {FS_CAL0, 0x0E},
126  {FS_DIVTWO, 0x03},
127  {FS_DSM0, 0x33},
128  {FS_DVC0, 0x17},
129  {FS_PFD, 0x50},
130  {FS_PRE, 0x6E},
131  {FS_REG_DIV_CML, 0x14},
132  {FS_SPARE, 0xAC},
133  {FS_VCO0, 0xB4},
134  {XOSC5, 0x0E},
135  {XOSC1, 0x03},
136 };
137 
138 // RX filter BW = 100.000000
139 // Packet bit length = 0
140 // Deviation = 20.019531
141 // Packet length mode = Variable
142 // Packet length = 255
143 // Carrier frequency = 902.750000
144 // Manchester enable = false
145 // TX power = 15
146 // PA ramping = true
147 // Device address = 0
148 // Symbol rate = 38.4
149 // Address config = No address check
150 // Bit rate = 38.4
151 // Modulation format = 2-GFSK
152 // Whitening = false
153 // Performance mode = High Performance
154 // Append packetinfo = false
155 
156 const registerSetting_t preferredSettings_38400bps[]=
157 {
158  {IOCFG3, 0xB0},
159  {IOCFG2, 0x06},
160  {IOCFG1, 0xB0},
161  {IOCFG0, 0x06},
162  {SYNC3, 0xD3},
163  {SYNC2, 0x91},
164  {SYNC1, 0xD3},
165  {SYNC0, 0x91},
166  {SYNC_CFG1, 0x08},
167  {DEVIATION_M, 0x48},
168  {MODCFG_DEV_E, 0x0D},
169  {DCFILT_CFG, 0x1C},
170  {PREAMBLE_CFG1, 0x18},
171  {IQIC, 0x00},
172  {CHAN_BW, 0x02},
173  {MDMCFG0, 0x05},
174  {SYMBOL_RATE2, 0x93},
175  {SYMBOL_RATE1, 0xA9},
176  {SYMBOL_RATE0, 0x2A},
177  {AGC_CS_THR, 0x19},
178  {AGC_CFG1, 0xA9},
179  {AGC_CFG0, 0xCF},
180  {FIFO_CFG, 0x00},
181  {SETTLING_CFG, 0x0B},
182  {FS_CFG, 0x12},
183  {PKT_CFG2, 0x04},
184  {PKT_CFG1, 0x04},
185  {PKT_CFG0, 0x20},
186  {PA_CFG2, 0x7F},
187  {PA_CFG1, 0x56},
188  {PA_CFG0, 0x7B},
189  {PKT_LEN, 0xFF},
190  {IF_MIX_CFG, 0x00},
191  {FREQOFF_CFG, 0x22},
192  {FREQOFF1, 0x00},
193  {FREQOFF0, 0x00},
194  {FREQ2, 0x70},
195  {FREQ1, 0xD8},
196  {FREQ0, 0x00},
197  {FS_DIG1, 0x00},
198  {FS_DIG0, 0x5F},
199  {FS_CAL1, 0x40},
200  {FS_CAL0, 0x0E},
201  {FS_DIVTWO, 0x03},
202  {FS_DSM0, 0x33},
203  {FS_DVC0, 0x17},
204  {FS_PFD, 0x50},
205  {FS_PRE, 0x6E},
206  {FS_REG_DIV_CML, 0x14},
207  {FS_SPARE, 0xAC},
208  {FS_VCO0, 0xB4},
209  {XOSC5, 0x0E},
210  {XOSC1, 0x03},
211 };
212 
213 // Device address = 0
214 // Performance mode = High Performance
215 // Symbol rate = 50
216 // RX filter BW = 100.000000
217 // TX power = 15
218 // Modulation format = 2-GFSK
219 // Whitening = false
220 // Address config = No address check
221 // Packet length = 255
222 // Deviation = 24.963379
223 // Bit rate = 50
224 // Packet bit length = 0
225 // PA ramping = true
226 // Carrier frequency = 902.750000
227 // Packet length mode = Variable
228 // Manchester enable = false
229 // Append packetinfo = false
230 
231 const registerSetting_t preferredSettings_50kbps[]=
232 {
233  {IOCFG3, 0xB0},
234  {IOCFG2, 0x06},
235  {IOCFG1, 0xB0},
236  {IOCFG0, 0x06},
237  {SYNC3, 0xD3},
238  {SYNC2, 0x91},
239  {SYNC1, 0xD3},
240  {SYNC0, 0x91},
241  {SYNC_CFG1, 0x08},
242  {SYNC_CFG0, 0x17},
243  {DEVIATION_M, 0x99},
244  {MODCFG_DEV_E, 0x0D},
245  {DCFILT_CFG, 0x15},
246  {PREAMBLE_CFG1, 0x18},
247  {PREAMBLE_CFG0, 0x2A},
248  {FREQ_IF_CFG, 0x3A},
249  {IQIC, 0x00},
250  {CHAN_BW, 0x02},
251  {MDMCFG1, 0x46},
252  {MDMCFG0, 0x05},
253  {SYMBOL_RATE2, 0x99},
254  {SYMBOL_RATE1, 0x99},
255  {SYMBOL_RATE0, 0x99},
256  {AGC_REF, 0x3C},
257  {AGC_CS_THR, 0xEF},
258  {AGC_CFG1, 0xA9},
259  {AGC_CFG0, 0xC0},
260  {FIFO_CFG, 0x00},
261  {SETTLING_CFG, 0x0B},
262  {FS_CFG, 0x12},
263  {PKT_CFG2, 0x04},
264  {PKT_CFG1, 0x04},
265  {PKT_CFG0, 0x20},
266  {PA_CFG2, 0x7F},
267  {PA_CFG1, 0x56},
268  {PA_CFG0, 0x79},
269  {PKT_LEN, 0xFF},
270  {IF_MIX_CFG, 0x00},
271  {FREQOFF_CFG, 0x20},
272  {TOC_CFG, 0x0A},
273  {FREQOFF1, 0x00},
274  {FREQOFF0, 0x00},
275  {FREQ2, 0x70},
276  {FREQ1, 0xD8},
277  {FREQ0, 0x00},
278  {FS_DIG1, 0x00},
279  {FS_DIG0, 0x5F},
280  {FS_CAL1, 0x40},
281  {FS_CAL0, 0x0E},
282  {FS_DIVTWO, 0x03},
283  {FS_DSM0, 0x33},
284  {FS_DVC0, 0x17},
285  {FS_PFD, 0x50},
286  {FS_PRE, 0x6E},
287  {FS_REG_DIV_CML, 0x14},
288  {FS_SPARE, 0xAC},
289  {FS_VCO0, 0xB4},
290  {XOSC5, 0x0E},
291  {XOSC1, 0x03},
292 };
293 
294 // Address Config = No address check
295 // Bit Rate = 1.2
296 // Carrier Frequency = 915.000000
297 // Deviation = 3.997803
298 // Device Address = 0
299 // Manchester Enable = false
300 // Modulation Format = 2-FSK
301 // PA Ramping = true
302 // Packet Bit Length = 0
303 // Packet Length = 2
304 // Packet Length Mode = Fixed
305 // Performance Mode = High Performance
306 // RX Filter BW = 10.000000
307 // Symbol rate = 1.2
308 // TX Power = 15
309 // Whitening = false
310 
311 const registerSetting_t trial_Settings[]=
312 {
313  {IOCFG3, 0xB0},
314  {IOCFG2, 0x06},
315  {IOCFG1, 0xB0},
316  {IOCFG0, 0x40},
317  {SYNC_CFG1, 0x0B},
318  {DCFILT_CFG, 0x1C},
319  {PREAMBLE_CFG1, 0x18},
320  {IQIC, 0xC6},
321  {MDMCFG0, 0x05},
322  {AGC_REF, 0x20},
323  {AGC_CS_THR, 0x19},
324  {AGC_CFG1, 0xA9},
325  {AGC_CFG0, 0xCF},
326  {FIFO_CFG, 0x00},
327  {PKT_CFG1, 0x04},
328  {PKT_CFG0, 0x00},
329  {FS_CFG, 0x12},
330  {PA_CFG2, 0x77},
331  {PA_CFG1, 0x56},
332  {PA_CFG0, 0x7C},
333  {PKT_LEN, 0x02},
334  {IF_MIX_CFG, 0x00},
335  {DCFILT_CFG, 0x0A},
336  {FREQOFF_CFG, 0x30},
337  {FREQ2, 0x72},
338  {FREQ1, 0x60},
339  {FS_DIG1, 0x00},
340  {FS_DIG0, 0x5F},
341  {FS_CAL1, 0x40},
342  {FS_CAL0, 0x0E},
343  {FS_DIVTWO, 0x03},
344  {FS_DSM0, 0x33},
345  {FS_DVC0, 0x17},
346  {FS_PFD, 0x50},
347  {FS_PRE, 0x6E},
348  {FS_REG_DIV_CML, 0x14},
349  {FS_SPARE, 0xAC},
350  {FS_VCO0, 0xB4},
351  {XOSC5, 0x0E},
352  {XOSC1, 0x03},
353 };
354 
355 /******************************************************************************
356  * @fn radio_init
357  *
358  * @brief Initialize the radio hardware
359  *
360  *
361  * input parameters
362  *
363  * @param void
364  *
365  * output parameters
366  *
367  * @return void
368  *
369  */
370 int radio_init(uint8_t config_select) {
371 
372  uint8_t i, writeByte, preferredSettings_length;
373  uint32_t bit_rate;
374  registerSetting_t *preferredSettings;
375 
376 
377  /* Instantiate transceiver RF SPI interface to SCLK ~ 4 MHz */
378  /* Input parameter is clockDivider */
379  /* SCLK frequency = SMCLK/clockDivider */
380  hal_gpio_cfg_output (RF_RESET_PIN, 1);
381  hal_gpio_pin_set (RF_RESET_PIN);
382  hal_nop_delay_ms (1);
383  hal_gpio_pin_clear (RF_RESET_PIN);
384  hal_nop_delay_ms (1);
385  hal_gpio_pin_set (RF_RESET_PIN);
386  trxRfSpiInterfaceInit();
387  log_printf("%s\n", __func__);
388 
389 // /* remove the reset from the rf device */
390 // RF_RESET_N_PORT_SEL &= ~RF_RESET_N_PIN;
391 // RF_RESET_N_PORT_DIR |= RF_RESET_N_PIN;
392 // RF_RESET_N_PORT_OUT |= RF_RESET_N_PIN;
393 //
394  /* Reset radio */
395  trxSpiCmdStrobe(SRES);
396 
397  /* give the tranciever time enough to complete reset cycle */
398  hal_nop_delay_us (16000);
399 
400  switch (config_select) {
401  case 1:
402  preferredSettings_length = sizeof(preferredSettings_1200bps)/sizeof(registerSetting_t);
403  preferredSettings = (registerSetting_t *)preferredSettings_1200bps;
404  bit_rate = 12;
405  break;
406  case 2:
407  preferredSettings_length = sizeof(preferredSettings_38400bps)/sizeof(registerSetting_t);
408  preferredSettings = (registerSetting_t *)preferredSettings_38400bps;
409  bit_rate = 384;
410  break;
411  case 3:
412  preferredSettings_length = sizeof(preferredSettings_50kbps)/sizeof(registerSetting_t);
413  preferredSettings = (registerSetting_t *)preferredSettings_50kbps;
414  bit_rate = 500;
415  break;
416  case 4:
417  preferredSettings_length = sizeof(trial_Settings)/sizeof(registerSetting_t);
418  preferredSettings = (registerSetting_t *)trial_Settings;
419  bit_rate = 02;
420  break;
421  default:
422  preferredSettings_length = sizeof(preferredSettings_1200bps)/sizeof(registerSetting_t);
423  preferredSettings = (registerSetting_t *)preferredSettings_1200bps;
424  bit_rate = 12;
425  break;
426  }
427 
428  /* Write registers to radio */
429  for(i = 0; i < preferredSettings_length; i++) {
430 
431  if(preferredSettings[i].addr < 0x2F) {
432  writeByte = preferredSettings[i].data;
433  trx8BitRegAccess(RADIO_WRITE_ACCESS, preferredSettings[i].addr, &writeByte, 1);
434  } else {
435  writeByte = preferredSettings[i].data;
436  trx16BitRegAccess(RADIO_WRITE_ACCESS, 0x2F , (0xFF & preferredSettings[i].addr),
437  &writeByte, 1);
438  }
439  }
440 
441  /* enable range extender */
442 #ifdef ENABLE_RANGE_EXTENDER
443  range_extender_init();
444 #endif
445 
446  return bit_rate;
447 }
448 
449 /******************************************************************************
450  * @fn radio_prepare
451  *
452  * @brief Prepare the radio with a packet to be sent, but do not send
453  *
454  * input parameters
455  *
456  * @param uint8_t *payload - pointer to payload
457  * uint16_t payload_len - payload length information
458  *
459  * output parameters
460  *
461  * @return 0
462  *
463  */
464 int radio_prepare(uint8_t *payload, uint16_t payload_len) {
465  trx8BitRegAccess(RADIO_WRITE_ACCESS+RADIO_BURST_ACCESS, TXFIFO, payload, payload_len);
466 
467  return 0;
468 }
469 
470 /******************************************************************************
471  * @fn radio_transmit
472  *
473  * @brief Send the packet that has previously been prepared (used for
474  * exact timing)
475  *
476  * input parameters
477  *
478  * @param uint8_t *payload - pointer to payload
479  * uint16_t payload_len - payload length information
480  *
481  * output parameters
482  *
483  * @return 0
484  *
485  */
486 int radio_transmit(void) {
487 
488  /* Range extender in TX mode */
489 #ifdef ENABLE_RANGE_EXTENDER
490  range_extender_txon();
491 #endif
492 
493  /* Change state to TX, initiating */
494  trxSpiCmdStrobe(STX);
495 
496  return(0);
497 }
498 
499 /******************************************************************************
500  * @fn radio_receive_on
501  *
502  * @brief Initiate the RX chain
503  *
504  * input parameters
505  *
506  * @param void
507  *
508  * output parameters
509  *
510  * @return void
511  *
512  */
513 int radio_receive_on(void) {
514 
515  trxSpiCmdStrobe(SFRX); // Flush RXFIFO
516  /* Range extender in RX mode */
517 #ifdef ENABLE_RANGE_EXTENDER
518  range_extender_rxon();
519 #endif
520 
521  /* Strobe RX to initiate the recieve chain */
522  trxSpiCmdStrobe(SRX);
523 
524  return 0;
525 }
526 
527 /******************************************************************************
528  * @fn radio_send
529  *
530  * @brief Prepare & transmit a packet in same call
531  *
532  *
533  * input parameters
534  *
535  * @param uint8_t *payload
536  * uint16_t payload_len
537  *
538  * output parameters
539  *
540  * @return void
541  *
542  *
543  */
544 int radio_send(uint8_t *payload, uint16_t payload_len) {
545 
546 
547  trxSpiCmdStrobe (SFTX);
548 
549  /* Write packet to TX FIFO */
550  trx8BitRegAccess(RADIO_WRITE_ACCESS|RADIO_BURST_ACCESS, TXFIFO, payload, payload_len);
551 
552  /* Read number of bytes in TX FIFO */
553  uint8_t pktLen;
554 
555  trx16BitRegAccess(RADIO_READ_ACCESS|RADIO_BURST_ACCESS, 0x2F, 0xff & NUM_TXBYTES, &pktLen, 1);
556 // log_printf("Pkt : %d, %d\n", payload_len, pktLen);
557 
558  /* Range extender in TX mode */
559 #ifdef ENABLE_RANGE_EXTENDER
560  range_extender_txon();
561 #endif
562 
563  /* Strobe TX to send packet */
564  trxSpiCmdStrobe(STX); // Change state to TX, initiating
565 
566  return 0;
567 }
568 
569 /******************************************************************************
570  * @fn radio_read
571  *
572  * @brief Read a received packet into a buffer
573  *
574  *
575  * input parameters
576  *
577  * @param uint8_t *buf
578  * uint16_t buf_len
579  *
580  * output parameters
581  *
582  * @return void
583  *
584  *
585  */
586 int radio_read(uint8_t *buf, uint8_t *buf_len) {
587  uint8_t status;
588  uint8_t pktLen;
589 
590  /* Read number of bytes in RX FIFO */
591  trx16BitRegAccess(RADIO_READ_ACCESS, 0x2F, 0xff & NUM_RXBYTES, &pktLen, 1);
592 // pktLen = pktLen & NUM_RXBYTES;
593 
594 // log_printf("Pkt :%d, %d\n",*buf_len, pktLen);
595  /* make sure the packet size is appropriate, that is 1 -> buffer_size */
596  if ((pktLen > 0) && (pktLen <= *buf_len)) {
597 
598  /* retrieve the FIFO content */
599  trx8BitRegAccess(RADIO_READ_ACCESS|RADIO_BURST_ACCESS, RXFIFO, buf, pktLen);
600 
601  /* return the actual length of the FIFO */
602  *buf_len = pktLen;
603 
604  /* retrieve the CRC status information */
605  trx16BitRegAccess(RADIO_READ_ACCESS, 0x2F, 0xff & LQI_VAL, &status, 1);
606 
607  /* Return CRC_OK bit */
608  status = status & CRC_OK;
609  trxSpiCmdStrobe(SFRX); // Flush RXFIFO
610 
611  } else {
612 
613  /* if the length returned by the transciever does not make sense, flush it */
614 
615  log_printf("Wrong..!!");
616  *buf_len = 0; // Return 0 indicating a failure
617  status = 0; // Return 0 indicating a failure
618  trxSpiCmdStrobe(SFRX); // Flush RXFIFO
619 
620  }
621 
622  /* return status information, CRC OK or NOT OK */
623  return (status);
624 }
625 
626 /******************************************************************************
627  * @fn radio_channel_clear
628  *
629  * @brief Perform a Clear-Channel Assessment (CCA) to find out if
630  * channel is clear
631  *
632  *
633  * input parameters
634  *
635  * @param void
636  *
637  * output parameters
638  *
639  * @return 0 - no carrier found
640  * >0 - carrier found
641  *
642  */
643 int radio_channel_clear(void) {
644  uint8_t status;
645 
646  /* get RSSI0, and return the carrier sense signal */
647  trx16BitRegAccess(RADIO_READ_ACCESS, 0x2F, 0xff & RSSI0, &status, 1);
648 
649  /* return the carrier sense signal */
650  return(status & 0x04);
651 }
652 
653 
654 /******************************************************************************
655  * @fn radio_channel_clear
656  *
657  * @brief Wait for end of packet interupt to happen
658  *
659  * Timeout is controlled by TimerA running at 8MHz
660  * 64000 = 128ms, 32000 = 64ms, 16000 = 32ms
661  * 0 = no timeout.
662  *
663  * input parameters
664  *
665  * @param max_hold : Watch dog timeout, no end of packet = 0;
666  *
667  * output parameters
668  *
669  * @return timer value: Interupt happened based on end_of_packet interupt
670  *
671  */
672 
673 //COMPLETELY BROKEN
674 int radio_wait_for_idle(uint16_t max_hold) {
675 
676  uint32_t status;
677  uint8_t reg_status;
678 
679  /* check that we are still in RX mode before entering wait for RX end */
680  trx16BitRegAccess(RADIO_READ_ACCESS, 0x2F, 0xff & MARCSTATE, &reg_status, 1);
681 
682  /* filter out only the status section of the register values */
683  reg_status = (reg_status & 0x1F);
684 
685  /* check for not idle mode */
686  if(!(reg_status == MARCSTATE_IDLE)) {
687 
688  rf_end_packet = 0; // initialize global variable for use in this function
689 
690 // /* setup the interrupt */
691 // RF_GDO_PxIES |= RF_GDO_PIN; // Int on falling edge (end of pkt)
692 // RF_GDO_PxIFG &= ~RF_GDO_PIN; // Clear flag
693 // RF_GDO_PxIE |= RF_GDO_PIN; // Enable int on end of packet
694 
695  /* enabled timeout if requested */
696  if(max_hold > 0) {
697 // status = hal_nop_delay_ms ((uint)max_hold); //CHECKOUT WHAT TO DO WITH THIS LINE // this will timeout either with GDO or timer
698  } else {
699  // wait for radio to interupt us to continue processing
700  status = 0;
701 // _BIS_SR(LPM0_bits + GIE); // Enter LPM0
702  }
703 
704  /******** Setup the GDO ports to not interupts ****************************/
705 // RF_GDO_PxIE &= ~RF_GDO_PIN; // Disable int on end of packet
706 
707  }
708  /* Get timer values, however if we did not get a packet in time use 0 */
709  if(rf_end_packet == 0) {
710  status = max_hold;
711  }
712 
713 #ifdef ENABLE_RANGE_EXTENDER
714  range_extender_idle();
715 #endif
716 
717  return status;
718 }
719 
720 /******************************************************************************
721  * @fn radio_is_busy
722  *
723  * @brief Wait for radio to become idle
724  *
725  * input parameters
726  *
727  * @param void
728  *
729  * output parameters
730  *
731  * @return void
732  *
733  */
734 int radio_is_busy(void) {
735 
736  // Wait GDO0 to go hi -> sync TX'ed
737 // while (!(RF_GDO_IN & RF_GDO_PIN));
738 
739  // Wait GDO0 to go low again -> sync TX'ed
740 // while (RF_GDO_IN & RF_GDO_PIN);
741 
742  // Wait GDO0 to clear -> end of pkt
743 // RF_GDO_PxIFG &= ~RF_GDO_PIN; // After pkt TX, this flag is set.
744 
745  return(0);
746 }
747 
748 /******************************************************************************
749  * @fn radio_pending_packet
750  *
751  * @brief Check if the radio driver has just received a packet
752  *
753  * input parameters
754  *
755  * @param void
756  *
757  * output parameters
758  *
759  * @return void
760  *
761  */
762 int radio_pending_packet(void) {
763 
764 // RF_GDO_PxIES |= RF_GDO_PIN; // Int on falling edge (end of pkt)
765 // RF_GDO_PxIE |= RF_GDO_PIN; // Enable int on end of packet
766 
767  return rf_end_packet;
768 }
769 
770 /******************************************************************************
771  * @fn radio_clear_pending_packet
772  *
773  * @brief Clear pending packet indicator
774  *
775  * input parameters
776  *
777  * @param void
778  *
779  * output parameters
780  *
781  * @return void
782  *
783  */
784 int radio_clear_pending_packet(void) {
785 
786 // RF_GDO_PxIES &= ~RF_GDO_PIN; // Int on falling edge (end of pkt)
787 // RF_GDO_PxIE &= ~RF_GDO_PIN; // Enable int on end of packet
788 
789  rf_end_packet = 0;
790 
791  return 0;
792 }
793 
794 
795 /******************************************************************************
796  * @fn radio_set_pwr
797  *
798  * @brief Set the output power of the CC112x by looking up in table
799  *
800  * input parameters
801  *
802  * @param int tx_pwr
803  *
804  * output parameters
805  *
806  * @return int tx_pwr
807  *
808  */
809 int radio_set_pwr(int tx_pwr) {
810 
811  return tx_pwr;
812 }
813 
814 
815 /******************************************************************************
816  * @fn radio_set_freq
817  *
818  * @brief Calculate the required frequency registers and send the using
819  * serial connection to the RF tranceiver.
820  *
821  * input parameters
822  *
823  * @param freq - frequency word provided in [kHz] resolution
824  *
825  * output parameters
826  *
827  * @return void
828  */
829 int radio_set_freq(uint64_t freq) {
830 
831  uint8_t freq_regs[3];
832  uint32_t freq_regs_uint32;
833  float f_vco;
834 
835  /* Radio frequency -> VCO frequency */
836  f_vco = freq * RF_LO_DIVIDER;
837 
838  /* Divide by oscillator frequency */
839  f_vco = f_vco * (1/(float)RF_XTAL_FREQ);
840 
841  /* Multiply by 2^16 */
842  f_vco = f_vco * 65536;
843 
844  /* Convert value into uint32_t from float */
845  freq_regs_uint32 = (uint32_t) f_vco;
846 
847  /* return the frequency word */
848  freq_regs[2] = ((uint8_t*)&freq_regs_uint32)[0];
849  freq_regs[1] = ((uint8_t*)&freq_regs_uint32)[1];
850  freq_regs[0] = ((uint8_t*)&freq_regs_uint32)[2];
851 
852  /* write the frequency word to the transciever */
853  trx16BitRegAccess(RADIO_WRITE_ACCESS | RADIO_BURST_ACCESS, 0x2F, (0xFF & FREQ2), freq_regs, 3);
854 
855  return 0;
856 }
857 
858 
859 /******************************************************************************
860  * @fn radio_idle
861  *
862  * @brief Idle the radio, used when leaving low power modes (below)
863  *
864  *
865  * input parameters
866  *
867  * @param void
868  *
869  * output parameters
870  *
871  * @return void
872  *
873  */
874 int radio_idle(void) {
875 
876 #ifdef ENABLE_RANGE_EXTENDER
877  range_extender_idle();
878 #endif
879 
880  /* Idle range extender */
881 // range_extender_idle();
882 
883  /* Force transciever idle state */
884  trxSpiCmdStrobe(SIDLE);
885 
886  /* Flush the FIFO's */
887  trxSpiCmdStrobe(SFRX);
888  trxSpiCmdStrobe(SFTX);
889 
890  return(0);
891 }
892 
893 /******************************************************************************
894  * @fn radio_sleep
895  *
896  * @brief Enter sleep mode
897  *
898  * input parameters
899  *
900  * @param void
901  *
902  * output parameters
903  *
904  * @return void
905  *
906  */
907 int radio_sleep(void) {
908 
909  /* Idle range extender */
910 #ifdef ENABLE_RANGE_EXTENDER
911  range_extender_idle();
912 #endif
913 
914  /* Force transciever idle state */
915  trxSpiCmdStrobe(SIDLE);
916 
917  /* Enter sleep state on exit */
918  trxSpiCmdStrobe(SPWD);
919 
920  return(0);
921 }
922 
923 /******************************************************************************
924  * @fn radio_wake
925  *
926  * @brief Exit sleep mode
927  *
928  * input parameters
929  *
930  * @param void
931  *
932  * output parameters
933  *
934  * @return void
935  *
936  */
937 int radio_wake(void) {
938 
939  /* Force transciever idle state */
940  trxSpiCmdStrobe(SIDLE);
941 
942  /* 1 ms delay for letting RX settle */
943  hal_nop_delay_us (1000);
944 
945  return(0);
946 }
947 
948 
949 /******************************************************************************
950  * @fn radio_freq_error
951  *
952  * @brief Estimate the frequency error from two complement coded
953  * data to frequency error in Hertz
954  *
955  * input parameters
956  *
957  * @param freq_reg_error - two complement formatted data from tranceiver
958  *
959  * output parameters
960  *
961  * @return freq_error - 32 bit signed integer value representing
962  * frequency error in Hertz
963  *
964  */
965 int radio_freq_error(void) {
966 
967  uint64_t freq_error_est;
968  long freq_error_est_int;
969  uint8_t sign, regState, regState1;
970  uint32_t freq_reg_error;
971 
972  /* Read marcstate to check for frequency error estimate */
973  trx16BitRegAccess(RADIO_READ_ACCESS, 0x2F, (0xFF & FREQOFF_EST0), &regState, 1);
974  trx16BitRegAccess(RADIO_READ_ACCESS, 0x2F, (0xFF & FREQOFF_EST1), &regState1, 1);
975 
976  /* Calculate the frequency error in Hz */
977  freq_reg_error = ((uint32_t)regState1 << 8) + regState;
978 
979  /* the incoming data is 16 bit two complement format, separate "sign" */
980  if (freq_reg_error > 32768) {
981  freq_error_est = -(freq_reg_error - 65535);
982  sign = 1;
983  } else {
984  freq_error_est = freq_reg_error;
985  sign = 0;
986  }
987 
988  /* convert the data to hertz format in two steps to avoid integer overuns */
989  freq_error_est = (freq_error_est * (RF_XTAL_FREQ/RF_LO_DIVIDER)) >> 8;
990  freq_error_est = (freq_error_est * 1000) >> 10;
991 
992  /* re-assign the "sign" */
993  if(sign == 1) {
994  freq_error_est_int = -freq_error_est;
995  } else {
996  freq_error_est_int = freq_error_est;
997  }
998 
999  return freq_error_est_int;
1000 }
1001 
1002 
1003 int radio_check_status_flag (uint8_t status_bits)
1004 {
1005  uint8_t marc_sts1 ;
1006  trx16BitRegAccess((RADIO_READ_ACCESS | RADIO_BURST_ACCESS), 0x2F,
1007  (0x00FF & MARC_STATUS1), &marc_sts1, 1);
1008 
1009  if((status_bits & marc_sts1) == status_bits)
1010  {
1011  return 1;
1012  }
1013  else
1014  {
1015  return 0;
1016  }
1017 
1018 }
1019 
1020 
1021 int radio_get_rssi_val (void)
1022 {
1023  uint8_t rssi_regs[2];
1024  uint8_t rssi_val;
1025  trx16BitRegAccess (RADIO_READ_ACCESS, 0x2F, (0xFF & RSSI1), rssi_regs,
1026  sizeof(rssi_regs));
1027  if(rssi_regs[1] & RSSI0_RSSI_VALID)
1028  {
1029 // rssi_val = ((rssi_regs[0]<<RSSI0_RSSI_3_0_POS) |
1030 // ((rssi_regs[1]&RSSI0_RSSI_3_0_MSK)>>RSSI0_RSSI_3_0_POS));
1031 // rssi_val--;
1032 // rssi_val = 0xFF - rssi_val;
1033  rssi_val = 0xFF - (rssi_regs[0] -1);
1034  }
1035  else
1036  {
1037  rssi_val = 0xFF;
1038  }
1039 // rssi_val = rssi_regs[0];
1040  return rssi_val;
1041 }
1042 /******************************************************************************
1043  * @fn radio_ISR
1044  *
1045  * @brief Interrupt service routine used by transciever
1046  *
1047  * input parameters
1048  *
1049  * @param void
1050  *
1051  * output parameters
1052  *
1053  * @return void
1054  *
1055  */
1056 //#pragma vector=RF_PORT_VECTOR
1057 //__interrupt void radio_isr(void) {
1058 //
1059 // if(RF_GDO_PxIFG & RF_GDO_PIN) {
1060 //
1061 // // Clear LPM0 bits from 0(SR)
1062 // __bic_SR_register_on_exit(LPM3_bits);
1063 //
1064 // // clear the interrupt flag
1065 // RF_GDO_PxIFG &= ~RF_GDO_PIN;
1066 //
1067 // // indicate that end of packet has been found
1068 // rf_end_packet = 1;
1069 // }
1070 //}
1071 
1072 #endif