Dependencies:   mbed PID

Committer:
narshu
Date:
Wed Feb 29 17:50:49 2012 +0000
Revision:
0:c8c04928d025
Primary Robot with Sonar function - needs PID tuning for motor control

Who changed what in which revision?

UserRevisionLine numberNew contents of line
narshu 0:c8c04928d025 1 #include "RF12B.h"
narshu 0:c8c04928d025 2
narshu 0:c8c04928d025 3 #include "RF_defs.h"
narshu 0:c8c04928d025 4 #include <algorithm>
narshu 0:c8c04928d025 5
narshu 0:c8c04928d025 6
narshu 0:c8c04928d025 7 RF12B::RF12B(PinName _SDI,
narshu 0:c8c04928d025 8 PinName _SDO,
narshu 0:c8c04928d025 9 PinName _SCK,
narshu 0:c8c04928d025 10 PinName _NCS,
narshu 0:c8c04928d025 11 PinName _NIRQ):spi(_SDI, _SDO, _SCK),
narshu 0:c8c04928d025 12 NCS(_NCS), NIRQ(_NIRQ), NIRQ_in(_NIRQ), rfled(LED3) {
narshu 0:c8c04928d025 13
narshu 0:c8c04928d025 14 /* SPI frequency, word lenght, polarity and phase */
narshu 0:c8c04928d025 15 spi.format(16,0);
narshu 0:c8c04928d025 16 spi.frequency(2000000);
narshu 0:c8c04928d025 17
narshu 0:c8c04928d025 18 /* Set ~CS high */
narshu 0:c8c04928d025 19 NCS = 1;
narshu 0:c8c04928d025 20
narshu 0:c8c04928d025 21 /* Initialise RF Module */
narshu 0:c8c04928d025 22 init();
narshu 0:c8c04928d025 23
narshu 0:c8c04928d025 24 /* Setup interrupt to happen on falling edge of NIRQ */
narshu 0:c8c04928d025 25 NIRQ.fall(this, &RF12B::rxISR);
narshu 0:c8c04928d025 26 }
narshu 0:c8c04928d025 27
narshu 0:c8c04928d025 28 /* Returns the packet length if data is available in the receive buffer, 0 otherwise*/
narshu 0:c8c04928d025 29 unsigned int RF12B::available() {
narshu 0:c8c04928d025 30 return fifo.size();
narshu 0:c8c04928d025 31 }
narshu 0:c8c04928d025 32
narshu 0:c8c04928d025 33 /* Reads a packet of data, with length "size" Returns false if read failed. TODO: make a metafifo to isolate packets*/
narshu 0:c8c04928d025 34 bool RF12B::read(unsigned char* data, unsigned int size) {
narshu 0:c8c04928d025 35 if (fifo.size() == 0) {
narshu 0:c8c04928d025 36 return false;
narshu 0:c8c04928d025 37 } else {
narshu 0:c8c04928d025 38 unsigned int i = 0;
narshu 0:c8c04928d025 39 while (fifo.size() > 0 && i < size) {
narshu 0:c8c04928d025 40 data[i++] = fifo.front();
narshu 0:c8c04928d025 41 fifo.pop();
narshu 0:c8c04928d025 42 }
narshu 0:c8c04928d025 43 return true;
narshu 0:c8c04928d025 44 }
narshu 0:c8c04928d025 45 }
narshu 0:c8c04928d025 46
narshu 0:c8c04928d025 47 /* Reads a byte of data from the receive buffer */
narshu 0:c8c04928d025 48 unsigned char RF12B::read() {
narshu 0:c8c04928d025 49 if (available()) {
narshu 0:c8c04928d025 50 unsigned char data = fifo.front();
narshu 0:c8c04928d025 51 fifo.pop();
narshu 0:c8c04928d025 52 return data;
narshu 0:c8c04928d025 53 } else {
narshu 0:c8c04928d025 54 return 0xFF; // Error val although could also be data...
narshu 0:c8c04928d025 55 }
narshu 0:c8c04928d025 56 }
narshu 0:c8c04928d025 57
narshu 0:c8c04928d025 58 /* Sends a packet of data to the RF module for transmission TODO: Make asych*/
narshu 0:c8c04928d025 59 void RF12B::write(unsigned char *data, unsigned char length) {
narshu 0:c8c04928d025 60 unsigned char crc = 0;
narshu 0:c8c04928d025 61
narshu 0:c8c04928d025 62 /* Transmitter mode */
narshu 0:c8c04928d025 63 changeMode(TX);
narshu 0:c8c04928d025 64
narshu 0:c8c04928d025 65 writeCmd(0x0000);
narshu 0:c8c04928d025 66 send(0xAA); // PREAMBLE
narshu 0:c8c04928d025 67 send(0xAA);
narshu 0:c8c04928d025 68 send(0xAA);
narshu 0:c8c04928d025 69 send(0x2D); // SYNC
narshu 0:c8c04928d025 70 send(0xD4);
narshu 0:c8c04928d025 71 /* Packet Length */
narshu 0:c8c04928d025 72 send(length);
narshu 0:c8c04928d025 73 crc = crc8(crc, length);
narshu 0:c8c04928d025 74 send(crc);
narshu 0:c8c04928d025 75 crc = crc8(crc, crc);
narshu 0:c8c04928d025 76 /* Packet Data */
narshu 0:c8c04928d025 77 for (unsigned char i=0; i<length; i++) {
narshu 0:c8c04928d025 78 send(data[i]);
narshu 0:c8c04928d025 79 crc = crc8(crc, data[i]);
narshu 0:c8c04928d025 80 }
narshu 0:c8c04928d025 81 send(crc);
narshu 0:c8c04928d025 82 send(0xAA); // DUMMY BYTES
narshu 0:c8c04928d025 83 send(0xAA);
narshu 0:c8c04928d025 84 send(0xAA);
narshu 0:c8c04928d025 85
narshu 0:c8c04928d025 86 /* Back to receiver mode */
narshu 0:c8c04928d025 87 changeMode(RX);
narshu 0:c8c04928d025 88 status();
narshu 0:c8c04928d025 89
narshu 0:c8c04928d025 90
narshu 0:c8c04928d025 91 }
narshu 0:c8c04928d025 92
narshu 0:c8c04928d025 93 /* Transmit a 1-byte data packet */
narshu 0:c8c04928d025 94 void RF12B::write(unsigned char data) {
narshu 0:c8c04928d025 95 write(&data, 1);
narshu 0:c8c04928d025 96 }
narshu 0:c8c04928d025 97
narshu 0:c8c04928d025 98 void RF12B::write(queue<char> &data, int length) {
narshu 0:c8c04928d025 99 char crc = 0;
narshu 0:c8c04928d025 100 char length_byte = 0;
narshu 0:c8c04928d025 101
narshu 0:c8c04928d025 102 /* -1 means try to transmit everything in the queue */
narshu 0:c8c04928d025 103 if(length == -1) {
narshu 0:c8c04928d025 104 length = data.size();
narshu 0:c8c04928d025 105 }
narshu 0:c8c04928d025 106
narshu 0:c8c04928d025 107 /* max length of packet is 255 */
narshu 0:c8c04928d025 108 length_byte = min(length, 255);
narshu 0:c8c04928d025 109
narshu 0:c8c04928d025 110 /* Transmitter mode */
narshu 0:c8c04928d025 111 changeMode(TX);
narshu 0:c8c04928d025 112
narshu 0:c8c04928d025 113 writeCmd(0x0000);
narshu 0:c8c04928d025 114 send(0xAA); // PREAMBLE
narshu 0:c8c04928d025 115 send(0xAA);
narshu 0:c8c04928d025 116 send(0xAA);
narshu 0:c8c04928d025 117 send(0x2D); // SYNC
narshu 0:c8c04928d025 118 send(0xD4);
narshu 0:c8c04928d025 119 /* Packet Length */
narshu 0:c8c04928d025 120 send(length_byte);
narshu 0:c8c04928d025 121 crc = crc8(crc, length_byte);
narshu 0:c8c04928d025 122 send(crc);
narshu 0:c8c04928d025 123 crc = crc8(crc, crc);
narshu 0:c8c04928d025 124 /* Packet Data */
narshu 0:c8c04928d025 125 for (char i=0; i<length_byte; i++) {
narshu 0:c8c04928d025 126 send(data.front());
narshu 0:c8c04928d025 127 crc = crc8(crc, data.front());
narshu 0:c8c04928d025 128 data.pop();
narshu 0:c8c04928d025 129 }
narshu 0:c8c04928d025 130 send(crc);
narshu 0:c8c04928d025 131 send(0xAA); // DUMMY BYTES
narshu 0:c8c04928d025 132 send(0xAA);
narshu 0:c8c04928d025 133 send(0xAA);
narshu 0:c8c04928d025 134
narshu 0:c8c04928d025 135 /* Back to receiver mode */
narshu 0:c8c04928d025 136 changeMode(RX);
narshu 0:c8c04928d025 137 status();
narshu 0:c8c04928d025 138 }
narshu 0:c8c04928d025 139
narshu 0:c8c04928d025 140 /**********************************************************************
narshu 0:c8c04928d025 141 * PRIVATE FUNCTIONS
narshu 0:c8c04928d025 142 *********************************************************************/
narshu 0:c8c04928d025 143
narshu 0:c8c04928d025 144 /* Initialises the RF12B module */
narshu 0:c8c04928d025 145 void RF12B::init() {
narshu 0:c8c04928d025 146 /* writeCmd(0x80E7); //EL,EF,868band,12.0pF
narshu 0:c8c04928d025 147 changeMode(RX);
narshu 0:c8c04928d025 148 writeCmd(0xA640); //frequency select
narshu 0:c8c04928d025 149 writeCmd(0xC647); //4.8kbps
narshu 0:c8c04928d025 150 writeCmd(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm
narshu 0:c8c04928d025 151 writeCmd(0xC2AC); //AL,!ml,DIG,DQD4
narshu 0:c8c04928d025 152 writeCmd(0xCA81); //FIFO8,SYNC,!ff,DR
narshu 0:c8c04928d025 153 writeCmd(0xCED4); //SYNC=2DD4
narshu 0:c8c04928d025 154 writeCmd(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN
narshu 0:c8c04928d025 155 writeCmd(0x9850); //!mp,90kHz,MAX OUT
narshu 0:c8c04928d025 156 writeCmd(0xCC17); //OB1, COB0, LPX, Iddy, CDDIT&#65533;CBW0
narshu 0:c8c04928d025 157 writeCmd(0xE000); //NOT USED
narshu 0:c8c04928d025 158 writeCmd(0xC800); //NOT USED
narshu 0:c8c04928d025 159 writeCmd(0xC040); //1.66MHz,2.2V */
narshu 0:c8c04928d025 160
narshu 0:c8c04928d025 161 writeCmd(
narshu 0:c8c04928d025 162 RFM_CONFIG_EL |
narshu 0:c8c04928d025 163 RFM_CONFIG_EF |
narshu 0:c8c04928d025 164 RFM_CONFIG_BAND_433 //|
narshu 0:c8c04928d025 165 //RFM_CONFIG_X_11_0pf // meh, using default
narshu 0:c8c04928d025 166 );
narshu 0:c8c04928d025 167
narshu 0:c8c04928d025 168 // 2. Power Management Command
narshu 0:c8c04928d025 169 // leave everything switched off for now
narshu 0:c8c04928d025 170 /*
narshu 0:c8c04928d025 171 writeCmd(
narshu 0:c8c04928d025 172 RFM_POWER_MANAGEMENT // switch all off
narshu 0:c8c04928d025 173 );
narshu 0:c8c04928d025 174 */
narshu 0:c8c04928d025 175
narshu 0:c8c04928d025 176 // 3. Frequency Setting Command
narshu 0:c8c04928d025 177 writeCmd(
narshu 0:c8c04928d025 178 RFM_FREQUENCY |
narshu 0:c8c04928d025 179 RFM_FREQ_433Band(435.7) //I totally made this value up... if someone knows where the sweetspots are in this band, tell me!
narshu 0:c8c04928d025 180 );
narshu 0:c8c04928d025 181
narshu 0:c8c04928d025 182
narshu 0:c8c04928d025 183 // 4. Data Rate Command
narshu 0:c8c04928d025 184 writeCmd(RFM_DATA_RATE_9600);
narshu 0:c8c04928d025 185
narshu 0:c8c04928d025 186
narshu 0:c8c04928d025 187 // 5. Receiver Control Command
narshu 0:c8c04928d025 188 writeCmd(
narshu 0:c8c04928d025 189 RFM_RX_CONTROL_P20_VDI |
narshu 0:c8c04928d025 190 RFM_RX_CONTROL_VDI_FAST |
narshu 0:c8c04928d025 191 //RFM_RX_CONTROL_BW(RFM_BAUD_RATE) |
narshu 0:c8c04928d025 192 RFM_RX_CONTROL_BW_134 | // CHANGE THIS TO 67 TO IMPROVE RANGE! (though the bitrate must then be below 8kbaud, and fsk modulation changed)
narshu 0:c8c04928d025 193 RFM_RX_CONTROL_GAIN_0 |
narshu 0:c8c04928d025 194 RFM_RX_CONTROL_RSSI_103 // Might need adjustment. Datasheet says around 10^-5 bit error rate at this level and baudrate.
narshu 0:c8c04928d025 195 );
narshu 0:c8c04928d025 196
narshu 0:c8c04928d025 197 // 6. Data Filter Command
narshu 0:c8c04928d025 198 writeCmd(
narshu 0:c8c04928d025 199 RFM_DATA_FILTER_AL |
narshu 0:c8c04928d025 200 RFM_DATA_FILTER_ML |
narshu 0:c8c04928d025 201 RFM_DATA_FILTER_DIG //|
narshu 0:c8c04928d025 202 //RFM_DATA_FILTER_DQD(4)
narshu 0:c8c04928d025 203 );
narshu 0:c8c04928d025 204
narshu 0:c8c04928d025 205 // 7. FIFO and Reset Mode Command
narshu 0:c8c04928d025 206 writeCmd(
narshu 0:c8c04928d025 207 RFM_FIFO_IT(8) |
narshu 0:c8c04928d025 208 RFM_FIFO_DR |
narshu 0:c8c04928d025 209 0x8 //turn on 16bit sync word
narshu 0:c8c04928d025 210 );
narshu 0:c8c04928d025 211
narshu 0:c8c04928d025 212 // 8. FIFO Syncword
narshu 0:c8c04928d025 213 // Leave as default: 0xD4
narshu 0:c8c04928d025 214
narshu 0:c8c04928d025 215 // 9. Receiver FIFO Read
narshu 0:c8c04928d025 216 // when the interupt goes high, (and if we can assume that it was a fifo fill interrupt) we can read a byte using:
narshu 0:c8c04928d025 217 // result = RFM_READ_FIFO();
narshu 0:c8c04928d025 218
narshu 0:c8c04928d025 219 // 10. AFC Command
narshu 0:c8c04928d025 220 writeCmd(
narshu 0:c8c04928d025 221 //RFM_AFC_AUTO_VDI | //Note this might be changed to improve range. Refer to datasheet.
narshu 0:c8c04928d025 222 RFM_AFC_AUTO_INDEPENDENT |
narshu 0:c8c04928d025 223 RFM_AFC_RANGE_LIMIT_7_8 |
narshu 0:c8c04928d025 224 RFM_AFC_EN |
narshu 0:c8c04928d025 225 RFM_AFC_OE |
narshu 0:c8c04928d025 226 RFM_AFC_FI
narshu 0:c8c04928d025 227 );
narshu 0:c8c04928d025 228
narshu 0:c8c04928d025 229 // 11. TX Configuration Control Command
narshu 0:c8c04928d025 230 writeCmd(
narshu 0:c8c04928d025 231 RFM_TX_CONTROL_MOD_60 |
narshu 0:c8c04928d025 232 RFM_TX_CONTROL_POW_0
narshu 0:c8c04928d025 233 );
narshu 0:c8c04928d025 234
narshu 0:c8c04928d025 235
narshu 0:c8c04928d025 236 // 12. PLL Setting Command
narshu 0:c8c04928d025 237 writeCmd(
narshu 0:c8c04928d025 238 0xCC77 & ~0x01 // Setting the PLL bandwith, less noise, but max bitrate capped at 86.2
narshu 0:c8c04928d025 239 // I think this will slow down the pll's reaction time. Not sure, check with someone!
narshu 0:c8c04928d025 240 );
narshu 0:c8c04928d025 241
narshu 0:c8c04928d025 242 changeMode(RX);
narshu 0:c8c04928d025 243 resetRX();
narshu 0:c8c04928d025 244 status();
narshu 0:c8c04928d025 245 }
narshu 0:c8c04928d025 246
narshu 0:c8c04928d025 247 /* Write a command to the RF Module */
narshu 0:c8c04928d025 248 unsigned int RF12B::writeCmd(unsigned int cmd) {
narshu 0:c8c04928d025 249 NCS = 0;
narshu 0:c8c04928d025 250 unsigned int recv = spi.write(cmd);
narshu 0:c8c04928d025 251 NCS = 1;
narshu 0:c8c04928d025 252 return recv;
narshu 0:c8c04928d025 253 }
narshu 0:c8c04928d025 254
narshu 0:c8c04928d025 255 /* Sends a byte of data across RF */
narshu 0:c8c04928d025 256 void RF12B::send(unsigned char data) {
narshu 0:c8c04928d025 257 while (NIRQ);
narshu 0:c8c04928d025 258 writeCmd(0xB800 + data);
narshu 0:c8c04928d025 259 }
narshu 0:c8c04928d025 260
narshu 0:c8c04928d025 261 /* Change the mode of the RF module to Transmitting or Receiving */
narshu 0:c8c04928d025 262 void RF12B::changeMode(rfmode_t _mode) {
narshu 0:c8c04928d025 263 mode = _mode;
narshu 0:c8c04928d025 264 if (_mode == TX) {
narshu 0:c8c04928d025 265 writeCmd(0x8239); //!er,!ebb,ET,ES,EX,!eb,!ew,DC
narshu 0:c8c04928d025 266 } else { /* mode == RX */
narshu 0:c8c04928d025 267 writeCmd(0x8299); //er,!ebb,ET,ES,EX,!eb,!ew,DC
narshu 0:c8c04928d025 268 }
narshu 0:c8c04928d025 269 }
narshu 0:c8c04928d025 270
narshu 0:c8c04928d025 271 /* Interrupt routine for data reception */
narshu 0:c8c04928d025 272 void RF12B::rxISR() {
narshu 0:c8c04928d025 273 unsigned int data = 0;
narshu 0:c8c04928d025 274 static int i = -2;
narshu 0:c8c04928d025 275 static unsigned char packet_length = 0;
narshu 0:c8c04928d025 276 static unsigned char crc = 0;
narshu 0:c8c04928d025 277 static queue<unsigned char> temp;
narshu 0:c8c04928d025 278
narshu 0:c8c04928d025 279 //Loop while interrupt is asserted
narshu 0:c8c04928d025 280 while (!NIRQ_in && mode == RX) {
narshu 0:c8c04928d025 281
narshu 0:c8c04928d025 282 /* Grab the packet's length byte */
narshu 0:c8c04928d025 283 if (i == -2) {
narshu 0:c8c04928d025 284 data = writeCmd(0x0000);
narshu 0:c8c04928d025 285 if ( (data&0x8000) ) {
narshu 0:c8c04928d025 286 data = writeCmd(0xB000);
narshu 0:c8c04928d025 287 packet_length = (data&0x00FF);
narshu 0:c8c04928d025 288 crc = crc8(crc, packet_length);
narshu 0:c8c04928d025 289 i++;
narshu 0:c8c04928d025 290 }
narshu 0:c8c04928d025 291 }
narshu 0:c8c04928d025 292
narshu 0:c8c04928d025 293 //If we exhaust the interrupt, exit
narshu 0:c8c04928d025 294 if (NIRQ_in)
narshu 0:c8c04928d025 295 break;
narshu 0:c8c04928d025 296
narshu 0:c8c04928d025 297 // Check that packet length was correct
narshu 0:c8c04928d025 298 if (i == -1) {
narshu 0:c8c04928d025 299 data = writeCmd(0x0000);
narshu 0:c8c04928d025 300 if ( (data&0x8000) ) {
narshu 0:c8c04928d025 301 data = writeCmd(0xB000);
narshu 0:c8c04928d025 302 unsigned char crcofsize = (data&0x00FF);
narshu 0:c8c04928d025 303 if (crcofsize != crc) {
narshu 0:c8c04928d025 304 //It was wrong, start over
narshu 0:c8c04928d025 305 i = -2;
narshu 0:c8c04928d025 306 packet_length = 0;
narshu 0:c8c04928d025 307 crc = 0;
narshu 0:c8c04928d025 308 temp = queue<unsigned char>();
narshu 0:c8c04928d025 309 resetRX();
narshu 0:c8c04928d025 310 } else {
narshu 0:c8c04928d025 311 crc = crc8(crc, crcofsize);
narshu 0:c8c04928d025 312 i++;
narshu 0:c8c04928d025 313 }
narshu 0:c8c04928d025 314 }
narshu 0:c8c04928d025 315 }
narshu 0:c8c04928d025 316
narshu 0:c8c04928d025 317 //If we exhaust the interrupt, exit
narshu 0:c8c04928d025 318 if (NIRQ_in)
narshu 0:c8c04928d025 319 break;
narshu 0:c8c04928d025 320
narshu 0:c8c04928d025 321 /* Grab the packet's data */
narshu 0:c8c04928d025 322 if (i >= 0 && i < packet_length) {
narshu 0:c8c04928d025 323 data = writeCmd(0x0000);
narshu 0:c8c04928d025 324 if ( (data&0x8000) ) {
narshu 0:c8c04928d025 325 data = writeCmd(0xB000);
narshu 0:c8c04928d025 326 temp.push(data&0x00FF);
narshu 0:c8c04928d025 327 crc = crc8(crc, (unsigned char)(data&0x00FF));
narshu 0:c8c04928d025 328 i++;
narshu 0:c8c04928d025 329 }
narshu 0:c8c04928d025 330 }
narshu 0:c8c04928d025 331
narshu 0:c8c04928d025 332 //If we exhaust the interrupt, exit
narshu 0:c8c04928d025 333 if (NIRQ_in)
narshu 0:c8c04928d025 334 break;
narshu 0:c8c04928d025 335
narshu 0:c8c04928d025 336 if (i >= packet_length) {
narshu 0:c8c04928d025 337 data = writeCmd(0x0000);
narshu 0:c8c04928d025 338 if ( (data&0x8000) ) {
narshu 0:c8c04928d025 339 data = writeCmd(0xB000);
narshu 0:c8c04928d025 340 if ((unsigned char)(data & 0x00FF) == crc) {
narshu 0:c8c04928d025 341 //If the checksum is correct, add our data to the end of the output buffer
narshu 0:c8c04928d025 342 while (!temp.empty()) {
narshu 0:c8c04928d025 343 fifo.push(temp.front());
narshu 0:c8c04928d025 344 temp.pop();
narshu 0:c8c04928d025 345 }
narshu 0:c8c04928d025 346 }
narshu 0:c8c04928d025 347
narshu 0:c8c04928d025 348 /* Tell RF Module we are finished, and clean up */
narshu 0:c8c04928d025 349 i = -2;
narshu 0:c8c04928d025 350 packet_length = 0;
narshu 0:c8c04928d025 351 crc = 0;
narshu 0:c8c04928d025 352 temp = queue<unsigned char>();
narshu 0:c8c04928d025 353 resetRX();
narshu 0:c8c04928d025 354 }
narshu 0:c8c04928d025 355 }
narshu 0:c8c04928d025 356 }
narshu 0:c8c04928d025 357 }
narshu 0:c8c04928d025 358
narshu 0:c8c04928d025 359 unsigned int RF12B::status() {
narshu 0:c8c04928d025 360 return writeCmd(0x0000);
narshu 0:c8c04928d025 361 }
narshu 0:c8c04928d025 362
narshu 0:c8c04928d025 363 /* Tell the RF Module this packet is received and wait for the next */
narshu 0:c8c04928d025 364 void RF12B::resetRX() {
narshu 0:c8c04928d025 365 writeCmd(0xCA81);
narshu 0:c8c04928d025 366 writeCmd(0xCA83);
narshu 0:c8c04928d025 367 };
narshu 0:c8c04928d025 368
narshu 0:c8c04928d025 369 /* Calculate CRC8 */
narshu 0:c8c04928d025 370 unsigned char RF12B::crc8(unsigned char crc, unsigned char data) {
narshu 0:c8c04928d025 371 crc = crc ^ data;
narshu 0:c8c04928d025 372 for (int i = 0; i < 8; i++) {
narshu 0:c8c04928d025 373 if (crc & 0x01) {
narshu 0:c8c04928d025 374 crc = (crc >> 1) ^ 0x8C;
narshu 0:c8c04928d025 375 } else {
narshu 0:c8c04928d025 376 crc >>= 1;
narshu 0:c8c04928d025 377 }
narshu 0:c8c04928d025 378 }
narshu 0:c8c04928d025 379 return crc;
narshu 0:c8c04928d025 380 }