For robots and stuff
CC1101/CC1101-FreqScan.cpp@2:c42a035d71ed, 2014-12-31 (annotated)
- Committer:
- jjones646
- Date:
- Wed Dec 31 22:16:01 2014 +0000
- Revision:
- 2:c42a035d71ed
- Parent:
- 1:05a48c038381
adding dummy cc1101 support
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jjones646 | 0:c5afea7b9057 | 1 | #include "CC1101.h" |
jjones646 | 0:c5afea7b9057 | 2 | |
jjones646 | 0:c5afea7b9057 | 3 | #define CC_NUMBER_OF_SUB_BANDS 1 |
jjones646 | 0:c5afea7b9057 | 4 | |
jjones646 | 0:c5afea7b9057 | 5 | uint16_t CC1101::scan(void) |
jjones646 | 0:c5afea7b9057 | 6 | { |
jjones646 | 0:c5afea7b9057 | 7 | int8_t i; |
jjones646 | 0:c5afea7b9057 | 8 | int16_t channel; |
jjones646 | 0:c5afea7b9057 | 9 | |
jjones646 | 0:c5afea7b9057 | 10 | uint8_t rssi_offset = 74; |
jjones646 | 0:c5afea7b9057 | 11 | carrierSenseCounter = 0; |
jjones646 | 0:c5afea7b9057 | 12 | |
jjones646 | 0:c5afea7b9057 | 13 | uint8_t lastChannel = 10; |
jjones646 | 0:c5afea7b9057 | 14 | uint16_t limitTest0Reg = 0; |
jjones646 | 0:c5afea7b9057 | 15 | int16_t highRSSI = -150; |
jjones646 | 0:c5afea7b9057 | 16 | uint16_t selectedChannel = 25; |
jjones646 | 0:c5afea7b9057 | 17 | |
jjones646 | 0:c5afea7b9057 | 18 | |
jjones646 | 0:c5afea7b9057 | 19 | // Freq. Band Range Channel |
jjones646 | 0:c5afea7b9057 | 20 | // 0 779.009766 - 829.997314 0 - 255 All 0x0B |
jjones646 | 0:c5afea7b9057 | 21 | // 1 830.196869 - 881.184418 0 - 255 <- 154 = 0x0B, 155 -> = 0x09 |
jjones646 | 0:c5afea7b9057 | 22 | // 2 881.384369 - 927.972992 0 - 233 All 0x09 |
jjones646 | 0:c5afea7b9057 | 23 | /* |
jjones646 | 0:c5afea7b9057 | 24 | uint8_t freqSettings[CC_NUMBER_OF_SUB_BANDS][3] = {{0x1D, 0xF6, 0x40}, |
jjones646 | 0:c5afea7b9057 | 25 | {0x1F, 0xEE, 0x3F}, |
jjones646 | 0:c5afea7b9057 | 26 | {0x21, 0xE6, 0x3F} |
jjones646 | 0:c5afea7b9057 | 27 | }; |
jjones646 | 0:c5afea7b9057 | 28 | */ |
jjones646 | 0:c5afea7b9057 | 29 | |
jjones646 | 0:c5afea7b9057 | 30 | |
jjones646 | 0:c5afea7b9057 | 31 | // 1.1) Set the base freq. for the current sub band. The values for FREQ2, FREQ1, and FREQ0 can be found in |
jjones646 | 0:c5afea7b9057 | 32 | // freqSettings[subBand][n], where n = 0, 1, or 2 |
jjones646 | 0:c5afea7b9057 | 33 | /* |
jjones646 | 0:c5afea7b9057 | 34 | for (int n=0; n<3; n++) { |
jjones646 | 0:c5afea7b9057 | 35 | write_reg(CCxxx0_FREQ2 + n, freqSettings[subBand][n]); |
jjones646 | 0:c5afea7b9057 | 36 | } |
jjones646 | 0:c5afea7b9057 | 37 | */ |
jjones646 | 0:c5afea7b9057 | 38 | |
jjones646 | 0:c5afea7b9057 | 39 | uint8_t calCounter = 0; |
jjones646 | 0:c5afea7b9057 | 40 | |
jjones646 | 0:c5afea7b9057 | 41 | // 1.4.2.1) Set TEST0 register = 0x09 |
jjones646 | 0:c5afea7b9057 | 42 | write_reg(CCxxx0_TEST0, 0x09); |
jjones646 | 0:c5afea7b9057 | 43 | |
jjones646 | 0:c5afea7b9057 | 44 | // 1.4.2.2) Set FSCAL2 register = 0x2A |
jjones646 | 0:c5afea7b9057 | 45 | write_reg(CCxxx0_FSCAL2, 0x2A); |
jjones646 | 0:c5afea7b9057 | 46 | |
jjones646 | 0:c5afea7b9057 | 47 | |
jjones646 | 0:c5afea7b9057 | 48 | // 1.3) Loop through all channels |
jjones646 | 0:c5afea7b9057 | 49 | for (channel = 0; channel <= lastChannel; channel++ ) { |
jjones646 | 0:c5afea7b9057 | 50 | int8_t pktStatus; |
jjones646 | 0:c5afea7b9057 | 51 | |
jjones646 | 0:c5afea7b9057 | 52 | // 1.3.1) Set CHANNR register = channel |
jjones646 | 0:c5afea7b9057 | 53 | write_reg(CCxxx0_CHANNR, channel); |
jjones646 | 0:c5afea7b9057 | 54 | |
jjones646 | 0:c5afea7b9057 | 55 | // 1.4.3) Calibrate for every 4th ch. + at start of every sub band and every time the TEST0 reg. is changed |
jjones646 | 0:c5afea7b9057 | 56 | if (calCounter++ == 0) { |
jjones646 | 0:c5afea7b9057 | 57 | // 1.4.3.1) Perform a manual calibration by issuing an SCAL strobe command |
jjones646 | 0:c5afea7b9057 | 58 | calibrate(); |
jjones646 | 0:c5afea7b9057 | 59 | } |
jjones646 | 0:c5afea7b9057 | 60 | |
jjones646 | 0:c5afea7b9057 | 61 | |
jjones646 | 0:c5afea7b9057 | 62 | // 1.4.4)) Reset Calibration Counter (if calCounter = 5, we are 1 MHz away from the frequency where a |
jjones646 | 0:c5afea7b9057 | 63 | // calibration was performed) |
jjones646 | 0:c5afea7b9057 | 64 | if (calCounter == 4) { |
jjones646 | 0:c5afea7b9057 | 65 | // 1.4.4.1) Calibration is performed if calCounter = 0 |
jjones646 | 0:c5afea7b9057 | 66 | calCounter = 0; |
jjones646 | 0:c5afea7b9057 | 67 | } |
jjones646 | 0:c5afea7b9057 | 68 | |
jjones646 | 0:c5afea7b9057 | 69 | |
jjones646 | 0:c5afea7b9057 | 70 | // 1.3.3) Enter RX mode by issuing an SRX strobe command |
jjones646 | 0:c5afea7b9057 | 71 | rx_mode(); |
jjones646 | 0:c5afea7b9057 | 72 | |
jjones646 | 0:c5afea7b9057 | 73 | // 1.3.4) Wait for radio to enter RX state (can be done by polling the MARCSTATE register) |
jjones646 | 0:c5afea7b9057 | 74 | while(mode() != 0x0D); |
jjones646 | 0:c5afea7b9057 | 75 | |
jjones646 | 0:c5afea7b9057 | 76 | // 1.3.5) Wait for RSSI to be valid (See DN505 [7] on how long to wait) |
jjones646 | 0:c5afea7b9057 | 77 | wait(0.4); |
jjones646 | 0:c5afea7b9057 | 78 | |
jjones646 | 0:c5afea7b9057 | 79 | // 1.3.6) Read the PKTSTATUS register while the radio is in RX state (store it in pktStatus) |
jjones646 | 0:c5afea7b9057 | 80 | pktStatus = status(CCxxx0_PKTSTATUS); |
jjones646 | 0:c5afea7b9057 | 81 | |
jjones646 | 0:c5afea7b9057 | 82 | // 1.3.7) Enter IDLE state by issuing an SIDLE strobe command |
jjones646 | 0:c5afea7b9057 | 83 | strobe(CCxxx0_SIDLE); |
jjones646 | 0:c5afea7b9057 | 84 | |
jjones646 | 0:c5afea7b9057 | 85 | // 1.3.8) Check if CS is asserted (use the value obtained in 1.3.6) |
jjones646 | 0:c5afea7b9057 | 86 | if (pktStatus & 0x40) { // CS is asserted |
jjones646 | 0:c5afea7b9057 | 87 | |
jjones646 | 0:c5afea7b9057 | 88 | // 1.3.8.1) Read RSSI value and store it in rssi_dec |
jjones646 | 0:c5afea7b9057 | 89 | rssi_dec = status(CCxxx0_RSSI); |
jjones646 | 0:c5afea7b9057 | 90 | |
jjones646 | 0:c5afea7b9057 | 91 | // 1.3.8.2) Calculate RSSI in dBm (rssi_dBm)(offset value found in rssi_offset) |
jjones646 | 0:c5afea7b9057 | 92 | if (rssi_dec & 0x80) { |
jjones646 | 0:c5afea7b9057 | 93 | rssi_dBm = (rssi_dec - 256)>>1; // negate and divide by 2 |
jjones646 | 0:c5afea7b9057 | 94 | } else { |
jjones646 | 0:c5afea7b9057 | 95 | rssi_dBm = rssi_dec>>1; // divide by 2 |
jjones646 | 0:c5afea7b9057 | 96 | } |
jjones646 | 0:c5afea7b9057 | 97 | rssi_dBm -= rssi_offset; // offset adjustment |
jjones646 | 0:c5afea7b9057 | 98 | |
jjones646 | 0:c5afea7b9057 | 99 | |
jjones646 | 0:c5afea7b9057 | 100 | std::printf("RSSI: %d\r\n", rssi_dBm); |
jjones646 | 0:c5afea7b9057 | 101 | // 1.3.8.3) Store the RSSI value and the corresponding channel number |
jjones646 | 0:c5afea7b9057 | 102 | rssiTable[carrierSenseCounter] = rssi_dBm; |
jjones646 | 0:c5afea7b9057 | 103 | channelNumber[carrierSenseCounter] = channel; |
jjones646 | 0:c5afea7b9057 | 104 | carrierSenseCounter++; |
jjones646 | 0:c5afea7b9057 | 105 | } |
jjones646 | 0:c5afea7b9057 | 106 | } // End Channel Loop |
jjones646 | 0:c5afea7b9057 | 107 | |
jjones646 | 0:c5afea7b9057 | 108 | |
jjones646 | 0:c5afea7b9057 | 109 | // 1.4) Before moving on to the next sub band, scan through the rssiTable to find the highest RSSI value. Store |
jjones646 | 0:c5afea7b9057 | 110 | // the RSSI value in highRSSI and the corresponding channel number in selectedChannel |
jjones646 | 0:c5afea7b9057 | 111 | for (i = 0; i < carrierSenseCounter; i++) { |
jjones646 | 0:c5afea7b9057 | 112 | if (rssiTable[i] > highRSSI) { |
jjones646 | 0:c5afea7b9057 | 113 | highRSSI = rssiTable[i]; |
jjones646 | 0:c5afea7b9057 | 114 | selectedChannel = channelNumber[i]; |
jjones646 | 0:c5afea7b9057 | 115 | } |
jjones646 | 0:c5afea7b9057 | 116 | } |
jjones646 | 0:c5afea7b9057 | 117 | |
jjones646 | 0:c5afea7b9057 | 118 | |
jjones646 | 0:c5afea7b9057 | 119 | // 1.5) Reset carrierSenseCounter |
jjones646 | 0:c5afea7b9057 | 120 | // carrierSenseCounter = 0; |
jjones646 | 0:c5afea7b9057 | 121 | |
jjones646 | 0:c5afea7b9057 | 122 | // } // End Band Loop |
jjones646 | 0:c5afea7b9057 | 123 | |
jjones646 | 0:c5afea7b9057 | 124 | /* |
jjones646 | 0:c5afea7b9057 | 125 | |
jjones646 | 0:c5afea7b9057 | 126 | // 2) When all sub bands have been scanned, find which sub band has the highest RSSI (Scan the highRSSI[subBand] |
jjones646 | 0:c5afea7b9057 | 127 | // table). Store the subBand (0, 1, or 2) and the corresponding channel in the global variables activeBand and |
jjones646 | 0:c5afea7b9057 | 128 | // activeChannel respectively |
jjones646 | 0:c5afea7b9057 | 129 | int16_t tempRssi = -150; |
jjones646 | 0:c5afea7b9057 | 130 | // for (int subBand = 0; subBand < CC_NUMBER_OF_SUB_BANDS; subBand++) |
jjones646 | 0:c5afea7b9057 | 131 | // { |
jjones646 | 0:c5afea7b9057 | 132 | if (highRSSI >= tempRssi) { |
jjones646 | 0:c5afea7b9057 | 133 | tempRssi = highRSSI; |
jjones646 | 0:c5afea7b9057 | 134 | activeChannel = selectedChannel; |
jjones646 | 0:c5afea7b9057 | 135 | activeBand = subBand; |
jjones646 | 0:c5afea7b9057 | 136 | } |
jjones646 | 0:c5afea7b9057 | 137 | // } |
jjones646 | 0:c5afea7b9057 | 138 | |
jjones646 | 0:c5afea7b9057 | 139 | */ |
jjones646 | 0:c5afea7b9057 | 140 | |
jjones646 | 0:c5afea7b9057 | 141 | activeChannel = selectedChannel; |
jjones646 | 0:c5afea7b9057 | 142 | |
jjones646 | 0:c5afea7b9057 | 143 | std::printf("Active Channel: %u\r\nRSSI: %ddBm\r\n", activeChannel, highRSSI); |
jjones646 | 0:c5afea7b9057 | 144 | |
jjones646 | 0:c5afea7b9057 | 145 | return activeChannel; |
jjones646 | 0:c5afea7b9057 | 146 | |
jjones646 | 0:c5afea7b9057 | 147 | } |