M H / Mbed 2 deprecated prijimac-final

Dependencies:   mbed FATFileSystem

Fork of KL46Z-USBHostMSD_HelloWorld by Norimasa Okamoto

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RF22.cpp Source File

RF22.cpp

00001 // RF22.cpp
00002 
00003 #include "mbed.h"
00004 #include "RF22.h"
00005 
00006 Serial pc1(USBTX, USBRX);  
00007 
00008 // These are indexed by the values of ModemConfigChoic
00009 // Stored in flash (program) memory to save SRAM
00010 /*PROGMEM */ static const RF22::ModemConfig MODEM_CONFIG_TABLE[] = {
00011     { 0x2b, 0x03, 0xf4, 0x20, 0x41, 0x89, 0x00, 0x36, 0x40, 0x0a, 0x1d, 0x80, 0x60, 0x10, 0x62, 0x2c, 0x00, 0x08 }, // Unmodulated carrier
00012     { 0x2b, 0x03, 0xf4, 0x20, 0x41, 0x89, 0x00, 0x36, 0x40, 0x0a, 0x1d, 0x80, 0x60, 0x10, 0x62, 0x2c, 0x33, 0x08 }, // FSK, PN9 random modulation, 2, 5
00013 
00014     // All the following enable FIFO with reg 71
00015     //  1c,   1f,   20,   21,   22,   23,   24,   25,   2c,   2d,   2e,   58,   69,   6e,   6f,   70,   71,   72
00016     // FSK, No Manchester, Max Rb err <1%, Xtal Tol 20ppm
00017     { 0x2b, 0x03, 0xf4, 0x20, 0x41, 0x89, 0x00, 0x36, 0x40, 0x0a, 0x1d, 0x80, 0x60, 0x10, 0x62, 0x2c, 0x22, 0x08 }, // 2, 5
00018     { 0x1b, 0x03, 0x41, 0x60, 0x27, 0x52, 0x00, 0x07, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x13, 0xa9, 0x2c, 0x22, 0x3a }, // 2.4, 36
00019     { 0x1d, 0x03, 0xa1, 0x20, 0x4e, 0xa5, 0x00, 0x13, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x27, 0x52, 0x2c, 0x22, 0x48 }, // 4.8, 45
00020     { 0x1e, 0x03, 0xd0, 0x00, 0x9d, 0x49, 0x00, 0x45, 0x40, 0x0a, 0x20, 0x80, 0x60, 0x4e, 0xa5, 0x2c, 0x22, 0x48 }, // 9.6, 45
00021     { 0x2b, 0x03, 0x34, 0x02, 0x75, 0x25, 0x07, 0xff, 0x40, 0x0a, 0x1b, 0x80, 0x60, 0x9d, 0x49, 0x2c, 0x22, 0x0f }, // 19.2, 9.6
00022     { 0x02, 0x03, 0x68, 0x01, 0x3a, 0x93, 0x04, 0xd5, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x09, 0xd5, 0x0c, 0x22, 0x1f }, // 38.4, 19.6
00023     { 0x06, 0x03, 0x45, 0x01, 0xd7, 0xdc, 0x07, 0x6e, 0x40, 0x0a, 0x2d, 0x80, 0x60, 0x0e, 0xbf, 0x0c, 0x22, 0x2e }, // 57.6. 28.8
00024     { 0x8a, 0x03, 0x60, 0x01, 0x55, 0x55, 0x02, 0xad, 0x40, 0x0a, 0x50, 0x80, 0x60, 0x20, 0x00, 0x0c, 0x22, 0xc8 }, // 125, 125
00025 
00026     // GFSK, No Manchester, Max Rb err <1%, Xtal Tol 20ppm
00027     // These differ from FSK only in register 71, for the modulation type
00028     { 0x2b, 0x03, 0xf4, 0x20, 0x41, 0x89, 0x00, 0x36, 0x40, 0x0a, 0x1d, 0x80, 0x60, 0x10, 0x62, 0x2c, 0x23, 0x08 }, // 2, 5
00029     { 0x1b, 0x03, 0x41, 0x60, 0x27, 0x52, 0x00, 0x07, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x13, 0xa9, 0x2c, 0x23, 0x3a }, // 2.4, 36
00030     { 0x1d, 0x03, 0xa1, 0x20, 0x4e, 0xa5, 0x00, 0x13, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x27, 0x52, 0x2c, 0x23, 0x48 }, // 4.8, 45
00031     { 0x1e, 0x03, 0xd0, 0x00, 0x9d, 0x49, 0x00, 0x45, 0x40, 0x0a, 0x20, 0x80, 0x60, 0x4e, 0xa5, 0x2c, 0x23, 0x48 }, // 9.6, 45
00032     { 0x2b, 0x03, 0x34, 0x02, 0x75, 0x25, 0x07, 0xff, 0x40, 0x0a, 0x1b, 0x80, 0x60, 0x9d, 0x49, 0x2c, 0x23, 0x0f }, // 19.2, 9.6
00033     { 0x02, 0x03, 0x68, 0x01, 0x3a, 0x93, 0x04, 0xd5, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x09, 0xd5, 0x0c, 0x23, 0x1f }, // 38.4, 19.6
00034     { 0x06, 0x03, 0x45, 0x01, 0xd7, 0xdc, 0x07, 0x6e, 0x40, 0x0a, 0x2d, 0x80, 0x60, 0x0e, 0xbf, 0x0c, 0x23, 0x2e }, // 57.6. 28.8
00035     { 0x8a, 0x03, 0x60, 0x01, 0x55, 0x55, 0x02, 0xad, 0x40, 0x0a, 0x50, 0x80, 0x60, 0x20, 0x00, 0x0c, 0x23, 0xc8 }, // 125, 125
00036 
00037     // OOK, No Manchester, Max Rb err <1%, Xtal Tol 20ppm
00038     { 0x51, 0x03, 0x68, 0x00, 0x3a, 0x93, 0x01, 0x3d, 0x2c, 0x11, 0x28, 0x80, 0x60, 0x09, 0xd5, 0x2c, 0x21, 0x08 }, // 1.2, 75
00039     { 0xc8, 0x03, 0x39, 0x20, 0x68, 0xdc, 0x00, 0x6b, 0x2a, 0x08, 0x2a, 0x80, 0x60, 0x13, 0xa9, 0x2c, 0x21, 0x08 }, // 2.4, 335
00040     { 0xc8, 0x03, 0x9c, 0x00, 0xd1, 0xb7, 0x00, 0xd4, 0x29, 0x04, 0x29, 0x80, 0x60, 0x27, 0x52, 0x2c, 0x21, 0x08 }, // 4.8, 335
00041     { 0xb8, 0x03, 0x9c, 0x00, 0xd1, 0xb7, 0x00, 0xd4, 0x28, 0x82, 0x29, 0x80, 0x60, 0x4e, 0xa5, 0x2c, 0x21, 0x08 }, // 9.6, 335
00042     { 0xa8, 0x03, 0x9c, 0x00, 0xd1, 0xb7, 0x00, 0xd4, 0x28, 0x41, 0x29, 0x80, 0x60, 0x9d, 0x49, 0x2c, 0x21, 0x08 }, // 19.2, 335
00043     { 0x98, 0x03, 0x9c, 0x00, 0xd1, 0xb7, 0x00, 0xd4, 0x28, 0x20, 0x29, 0x80, 0x60, 0x09, 0xd5, 0x0c, 0x21, 0x08 }, // 38.4, 335
00044     { 0x98, 0x03, 0x96, 0x00, 0xda, 0x74, 0x00, 0xdc, 0x28, 0x1f, 0x29, 0x80, 0x60, 0x0a, 0x3d, 0x0c, 0x21, 0x08 }, // 40, 335
00045 
00046 };
00047 
00048 RF22::RF22(PinName slaveSelectPin, PinName mosi, PinName miso, PinName sclk, PinName interrupt)
00049     : _slaveSelectPin(slaveSelectPin),  _spi(mosi, miso, sclk), _interrupt(interrupt) /*, led1(LED1), led2(LED2), led3(LED3), led4(LED4) */
00050 {
00051 
00052 
00053     _idleMode = RF22_XTON; // Default idle state is READY mode
00054     _mode = RF22_MODE_IDLE; // We start up in idle mode
00055     _rxGood = 0;
00056     _rxBad = 0;
00057     _txGood = 0;
00058 
00059 
00060 }
00061 
00062 //moje dopsane metody
00063 
00064     void RF22::obsluhapreruseni()
00065     {
00066         handleInterrupt();
00067     }
00068     
00069    /* void RF22::vypisfifo()
00070     {
00071         _slaveSelectPin = 0;
00072         _spi.write(RF22_REG_7F_FIFO_ACCESS);
00073         pc1.printf("\n\r Obsah FIFA je:");
00074         for(int a = 0; a<10; a++)
00075         {
00076            uint8_t x = _spi.write(RF22_REG_7F_FIFO_ACCESS); 
00077            pc1.printf("\t %i", x);
00078         }
00079        _slaveSelectPin = 1; 
00080     }*/
00081 
00082 boolean RF22::init()
00083 {
00084     wait_ms(16);
00085     
00086     _slaveSelectPin = 1;    // cip select
00087 
00088     wait_ms(100);
00089 
00090     _spi.format(8,0);       //konfigurace SPI
00091     _spi.frequency(10000000);
00092 
00093     // Software reset the device
00094     reset();
00095 
00096     // Get the device type and check it
00097     // This also tests whether we are really connected to a device
00098     _deviceType = spiRead(RF22_REG_00_DEVICE_TYPE);
00099     
00100     if (   _deviceType != RF22_DEVICE_TYPE_RX_TRX
00101             && _deviceType != RF22_DEVICE_TYPE_TX)
00102         return false;
00103 
00104     _interrupt.fall(this, &RF22::isr0);
00105     
00106     clearTxBuf();
00107     clearRxBuf();
00108 
00109     // Most of these are the POR default
00110     spiWrite(RF22_REG_7D_TX_FIFO_CONTROL2, RF22_TXFFAEM_THRESHOLD);
00111     spiWrite(RF22_REG_7E_RX_FIFO_CONTROL,  RF22_RXFFAFULL_THRESHOLD);
00112     spiWrite(RF22_REG_30_DATA_ACCESS_CONTROL, RF22_ENPACRX | RF22_ENPACTX | RF22_ENCRC | RF22_CRC_CRC_16_IBM);
00113     // Configure the message headers
00114     // Here we set up the standard packet format for use by the RF22 library
00115     // 8 nibbles preamble
00116     // 2 SYNC words 2d, d4
00117     // Header length 4 (to, from, id, flags)
00118     // 1 octet of data length (0 to 255)
00119     // 0 to 255 octets data
00120     // 2 CRC octets as CRC16(IBM), computed on the header, length and data
00121     // On reception the to address is check for validity against RF22_REG_3F_CHECK_HEADER3
00122     // or the broadcast address of 0xff
00123     // If no changes are made after this, the transmitted
00124     // to address will be 0xff, the from address will be 0xff
00125     // and all such messages will be accepted. This permits the out-of the box
00126     // RF22 config to act as an unaddresed, unreliable datagram service
00127     spiWrite(RF22_REG_32_HEADER_CONTROL1, RF22_BCEN_HEADER3 | RF22_HDCH_HEADER3);
00128     spiWrite(RF22_REG_33_HEADER_CONTROL2, RF22_HDLEN_4 | RF22_SYNCLEN_2);
00129     setPreambleLength(8);   //delka preambule
00130     uint8_t syncwords[] = { 0x2d, 0xd4 };
00131     setSyncWords(syncwords, sizeof(syncwords));
00132     setPromiscuous(false);
00133     // Check the TO header against RF22_DEFAULT_NODE_ADDRESS
00134     spiWrite(RF22_REG_3F_CHECK_HEADER3, RF22_DEFAULT_NODE_ADDRESS);
00135     // Set the default transmit header values
00136     setHeaderTo(RF22_DEFAULT_NODE_ADDRESS);
00137     setHeaderFrom(RF22_DEFAULT_NODE_ADDRESS);
00138     setHeaderId(0);
00139     setHeaderFlags(0);
00140 
00141     // Ensure the antenna can be switched automatically according to transmit and receive
00142     // This assumes GPIO0(out) is connected to TX_ANT(in) to enable tx antenna during transmit
00143     // This assumes GPIO1(out) is connected to RX_ANT(in) to enable rx antenna during receive
00144     spiWrite (RF22_REG_0B_GPIO_CONFIGURATION0, 0x12) ; // TX state
00145     spiWrite (RF22_REG_0C_GPIO_CONFIGURATION1, 0x15) ; // RX state
00146 
00147     // Enable interrupts
00148     
00149     spiWrite(RF22_REG_05_INTERRUPT_ENABLE1, RF22_ENTXFFAEM |RF22_ENRXFFAFULL | RF22_ENPKSENT |RF22_ENPKVALID| RF22_ENCRCERROR);
00150     spiWrite(RF22_REG_06_INTERRUPT_ENABLE2, RF22_ENPREAVAL);
00151 
00152     // Set some defaults. An innocuous ISM frequency, and reasonable pull-in
00153     setFrequency(434.0, 0.05);
00154 //    setFrequency(900.0);
00155     // Some slow, reliable default speed and modulation
00156     setModemConfig(FSK_Rb2_4Fd36);
00157 //    setModemConfig(FSK_Rb125Fd125);
00158     // Minimum power
00159     setTxPower(RF22_TXPOW_8DBM);
00160 //    setTxPower(RF22_TXPOW_17DBM);
00161 
00162 
00163 
00164     return true;
00165 }
00166 
00167 // C++ level interrupt handler for this instance
00168 void RF22::handleInterrupt()
00169 {
00170     uint8_t _lastInterruptFlags[2];
00171 
00172     //led1 = 1;
00173 
00174     // Read the interrupt flags which clears the interrupt
00175     spiBurstRead(RF22_REG_03_INTERRUPT_STATUS1, _lastInterruptFlags, 2);
00176 
00177 #if 0
00178     // Caution: Serial printing in this interrupt routine can cause mysterious crashes
00179     Serial.print("interrupt ");
00180     Serial.print(_lastInterruptFlags[0], HEX);
00181     Serial.print(" ");
00182     Serial.println(_lastInterruptFlags[1], HEX);
00183     if (_lastInterruptFlags[0] == 0 && _lastInterruptFlags[1] == 0)
00184         Serial.println("FUNNY: no interrupt!");
00185 #endif
00186 
00187 #if 0
00188     // TESTING: fake an RF22_IFFERROR
00189     static int counter = 0;
00190     if (_lastInterruptFlags[0] & RF22_IPKSENT && counter++ == 10) {
00191         _lastInterruptFlags[0] = RF22_IFFERROR;
00192         counter = 0;
00193     }
00194 #endif
00195 
00196 
00197     if (_lastInterruptFlags[0] & RF22_IFFERROR) {
00198 //    Serial.println("IFFERROR");
00199         //led4 = !led4;
00200         resetFifos(); // Clears the interrupt
00201         if (_mode == RF22_MODE_TX)
00202             restartTransmit();
00203         else if (_mode == RF22_MODE_RX){
00204             clearRxBuf();
00205             //stop and start Rx
00206             setModeIdle();
00207             setModeRx();
00208         }
00209         // stop handling the remaining interruppts as something went wrong here
00210         return;
00211     } 
00212     
00213     // Caution, any delay here may cause a FF underflow or overflow
00214     if (_lastInterruptFlags[0] & RF22_ITXFFAEM) {
00215         // See if more data has to be loaded into the Tx FIFO
00216         //led2 = !led2;
00217         sendNextFragment();
00218 //  Serial.println("ITXFFAEM");
00219     }
00220   
00221     if (_lastInterruptFlags[0] & RF22_IRXFFAFULL) {
00222         // Caution, any delay here may cause a FF overflow
00223         // Read some data from the Rx FIFO
00224         //led4 = !led4;
00225         readNextFragment();
00226 //    Serial.println("IRXFFAFULL");
00227     }   
00228     if (_lastInterruptFlags[0] & RF22_IEXT) {
00229         // This is not enabled by the base code, but users may want to enable it
00230         //led2 = !led2;
00231         handleExternalInterrupt();
00232 //    Serial.println("IEXT");
00233     }
00234     if (_lastInterruptFlags[1] & RF22_IWUT) {
00235         // This is not enabled by the base code, but users may want to enable it
00236         //led2 = !led2;
00237         handleWakeupTimerInterrupt();
00238 //    Serial.println("IWUT");
00239     }    
00240     if (_lastInterruptFlags[0] & RF22_IPKSENT) {
00241 //  Serial.println("IPKSENT");
00242         _txGood++;
00243         //led4 = !led4;
00244         // Transmission does not automatically clear the tx buffer.
00245         // Could retransmit if we wanted
00246         // RF22 transitions automatically to Idle
00247         _mode = RF22_MODE_IDLE;
00248     }
00249    
00250     if (_lastInterruptFlags[0] & RF22_IPKVALID) {
00251         uint8_t len = spiRead(RF22_REG_4B_RECEIVED_PACKET_LENGTH);
00252 //  Serial.println("IPKVALID");
00253 //  Serial.println(len);
00254 //  Serial.println(_bufLen);
00255 
00256         // May have already read one or more fragments
00257         // Get any remaining unread octets, based on the expected length
00258         // First make sure we dont overflow the buffer in the case of a stupid length
00259         // or partial bad receives
00260 
00261         if (   len >  RF22_MAX_MESSAGE_LEN || len < _bufLen) //pokud je delka zpravy delsi nez FIFO
00262         {
00263             _rxBad++;
00264             _mode = RF22_MODE_IDLE;
00265             clearRxBuf();
00266             return; // Hmmm receiver buffer overflow.
00267         }
00268 
00269         spiBurstRead(RF22_REG_7F_FIFO_ACCESS, _buf + _bufLen, len - _bufLen);
00270         __disable_irq();    // Disable Interrupts
00271         _rxGood++;
00272         _bufLen = len;
00273         _mode = RF22_MODE_IDLE;
00274         _rxBufValid = true;
00275         // reset the fifo for next packet??
00276         //resetRxFifo();
00277         __enable_irq();     // Enable Interrupts
00278 
00279         //led3 = !led3;
00280 
00281     }
00282     
00283     if (_lastInterruptFlags[0] & RF22_ICRCERROR) {
00284 //    Serial.println("ICRCERR");
00285         _rxBad++;
00286         //led2 = !led2;
00287         clearRxBuf();
00288         resetRxFifo();
00289         _mode = RF22_MODE_IDLE;
00290         setModeRx(); // Keep trying
00291     }
00292     
00293     if (_lastInterruptFlags[1] & RF22_IPREAVAL) {
00294 //  Serial.println("IPREAVAL");
00295         
00296         _lastRssi = spiRead(RF22_REG_26_RSSI);
00297 
00298 
00299         // why clear the rx-buf here? charly
00300         clearRxBuf();
00301 
00302 
00303     }
00304     //led1 = 0;
00305 }
00306 
00307 // These are low level functions that call the interrupt handler for the correct
00308 // instance of RF22.
00309 // 2 interrupts allows us to have 2 different devices
00310 
00311 void RF22::isr0()
00312 {
00313     //handleInterrupt();
00314     obsluhapreruseni();
00315     
00316 }
00317 
00318 
00319 void RF22::reset()
00320 {
00321     spiWrite(RF22_REG_07_OPERATING_MODE1, RF22_SWRES);      //soft reset
00322     wait_ms(1);
00323 }
00324 
00325 uint8_t RF22::spiRead(uint8_t reg)
00326 {
00327     __disable_irq();    // Disable Interrupts
00328 
00329     _slaveSelectPin=0;
00330     
00331     _spi.write(reg & ~RF22_SPI_WRITE_MASK); // Send the address with the write mask off
00332     uint8_t val = _spi.write(0); // The written value is ignored, reg value is read  ??????
00333     
00334     _slaveSelectPin = 1;
00335     __enable_irq();     // Enable Interrupts
00336     return val;
00337 }
00338 
00339 void RF22::spiWrite(uint8_t reg, uint8_t val)       //zapis hodnot z define
00340 {
00341     __disable_irq();    // Disable Interrupts
00342    
00343     _slaveSelectPin = 0;
00344     _spi.write(reg | RF22_SPI_WRITE_MASK); // Send the address with the write mask on
00345     _spi.write(val); // New value follows
00346     
00347     _slaveSelectPin = 1;
00348     __enable_irq();     // Enable Interrupts
00349 }
00350 
00351 void RF22::spiBurstRead(uint8_t reg, uint8_t* dest, uint8_t len)        //tady se vycitaji data
00352 {
00353     _slaveSelectPin = 0;
00354     _spi.write(reg & ~RF22_SPI_WRITE_MASK); // Send the start address with the write mask off
00355     if(reg == RF22_REG_7F_FIFO_ACCESS) pc1.printf("\n\r Data primo z bufferu:");
00356     while (len--)
00357     {
00358         *dest++ = _spi.write(0);
00359         if(reg == RF22_REG_7F_FIFO_ACCESS) pc1.printf(" %i", *dest);
00360     }   
00361     _slaveSelectPin = 1;
00362 }
00363 
00364 void RF22::spiBurstWrite(uint8_t reg, const uint8_t* src, uint8_t len)
00365 {
00366     _slaveSelectPin = 0;
00367     _spi.write(reg | RF22_SPI_WRITE_MASK); // Send the start address with the write mask on
00368     while (len--)
00369         _spi.write(*src++);
00370     _slaveSelectPin = 1;
00371 }
00372 
00373 uint8_t RF22::statusRead()
00374 {
00375     return spiRead(RF22_REG_02_DEVICE_STATUS);
00376 }
00377 
00378 uint8_t RF22::adcRead(uint8_t adcsel,
00379                       uint8_t adcref ,
00380                       uint8_t adcgain,
00381                       uint8_t adcoffs)
00382 {
00383     uint8_t configuration = adcsel | adcref | (adcgain & RF22_ADCGAIN);
00384     spiWrite(RF22_REG_0F_ADC_CONFIGURATION, configuration | RF22_ADCSTART);
00385     spiWrite(RF22_REG_10_ADC_SENSOR_AMP_OFFSET, adcoffs);
00386 
00387     // Conversion time is nominally 305usec
00388     // Wait for the DONE bit
00389     while (!(spiRead(RF22_REG_0F_ADC_CONFIGURATION) & RF22_ADCDONE))
00390         ;
00391     // Return the value
00392     return spiRead(RF22_REG_11_ADC_VALUE);
00393 }
00394 
00395 
00396 uint16_t RF22::wutRead()
00397 {
00398     uint8_t buf[2];
00399     spiBurstRead(RF22_REG_17_WAKEUP_TIMER_VALUE1, buf, 2);
00400     return ((uint16_t)buf[0] << 8) | buf[1]; // Dont rely on byte order
00401 }
00402 
00403 // RFM-22 doc appears to be wrong: WUT for wtm = 10000, r, = 0, d = 0 is about 1 sec
00404 void RF22::setWutPeriod(uint16_t wtm, uint8_t wtr, uint8_t wtd)
00405 {
00406     uint8_t period[3];
00407 
00408     period[0] = ((wtr & 0xf) << 2) | (wtd & 0x3);
00409     period[1] = wtm >> 8;
00410     period[2] = wtm & 0xff;
00411     spiBurstWrite(RF22_REG_14_WAKEUP_TIMER_PERIOD1, period, sizeof(period));
00412 }
00413 
00414 // Returns true if centre + (fhch * fhs) is within limits
00415 // Caution, different versions of the RF22 support different max freq
00416 // so YMMV
00417 boolean RF22::setFrequency(float centre, float afcPullInRange)
00418 {
00419     uint8_t fbsel = RF22_SBSEL;
00420     uint8_t afclimiter;
00421     if (centre < 240.0 || centre > 960.0) // 930.0 for early silicon
00422         return false;
00423     if (centre >= 480.0) {
00424         if (afcPullInRange < 0.0 || afcPullInRange > 0.318750)
00425             return false;
00426         centre /= 2;
00427         fbsel |= RF22_HBSEL;
00428         afclimiter = afcPullInRange * 1000000.0 / 1250.0;
00429     } else {
00430         if (afcPullInRange < 0.0 || afcPullInRange > 0.159375)
00431             return false;
00432         afclimiter = afcPullInRange * 1000000.0 / 625.0;
00433     }
00434     centre /= 10.0;
00435     float integerPart = floor(centre);
00436     float fractionalPart = centre - integerPart;
00437 
00438     uint8_t fb = (uint8_t)integerPart - 24; // Range 0 to 23
00439     fbsel |= fb;
00440     uint16_t fc = fractionalPart * 64000;
00441     spiWrite(RF22_REG_73_FREQUENCY_OFFSET1, 0);  // REVISIT
00442     spiWrite(RF22_REG_74_FREQUENCY_OFFSET2, 0);
00443     spiWrite(RF22_REG_75_FREQUENCY_BAND_SELECT, fbsel);
00444     spiWrite(RF22_REG_76_NOMINAL_CARRIER_FREQUENCY1, fc >> 8);
00445     spiWrite(RF22_REG_77_NOMINAL_CARRIER_FREQUENCY0, fc & 0xff);
00446     spiWrite(RF22_REG_2A_AFC_LIMITER, afclimiter);
00447     return !(statusRead() & RF22_FREQERR);
00448 }
00449 
00450 // Step size in 10kHz increments
00451 // Returns true if centre + (fhch * fhs) is within limits
00452 boolean RF22::setFHStepSize(uint8_t fhs)
00453 {
00454     spiWrite(RF22_REG_7A_FREQUENCY_HOPPING_STEP_SIZE, fhs);
00455     return !(statusRead() & RF22_FREQERR);
00456 }
00457 
00458 // Adds fhch * fhs to centre frequency
00459 // Returns true if centre + (fhch * fhs) is within limits
00460 boolean RF22::setFHChannel(uint8_t fhch)
00461 {
00462     spiWrite(RF22_REG_79_FREQUENCY_HOPPING_CHANNEL_SELECT, fhch);
00463     return !(statusRead() & RF22_FREQERR);
00464 }
00465 
00466 uint8_t RF22::rssiRead()
00467 {
00468     return spiRead(RF22_REG_26_RSSI);
00469 }
00470 
00471 uint8_t RF22::ezmacStatusRead()
00472 {
00473     return spiRead(RF22_REG_31_EZMAC_STATUS);
00474 }
00475 
00476 void RF22::setMode(uint8_t mode)
00477 {
00478     spiWrite(RF22_REG_07_OPERATING_MODE1, mode);
00479 }
00480 
00481 void RF22::setModeIdle()
00482 {
00483     if (_mode != RF22_MODE_IDLE) {
00484         setMode(_idleMode);
00485         _mode = RF22_MODE_IDLE;
00486     
00487     }
00488 }
00489 
00490 void RF22::setModeRx()
00491 {
00492     if (_mode != RF22_MODE_RX) {
00493         setMode(_idleMode | RF22_RXON);
00494         _mode = RF22_MODE_RX;
00495     }
00496 }
00497 
00498 void RF22::setModeTx()
00499 {
00500     if (_mode != RF22_MODE_TX) {
00501         setMode(_idleMode | RF22_TXON);
00502         _mode = RF22_MODE_TX;
00503         // Hmmm, if you dont clear the RX FIFO here, then it appears that going
00504         // to transmit mode in the middle of a receive can corrupt the
00505         // RX FIFO
00506         resetRxFifo();
00507 
00508     }
00509 }
00510 
00511 uint8_t  RF22::mode()
00512 {
00513     return _mode;
00514 }
00515 
00516 void RF22::setTxPower(uint8_t power)
00517 {
00518     spiWrite(RF22_REG_6D_TX_POWER, power);
00519 }
00520 
00521 // Sets registers from a canned modem configuration structure
00522 void RF22::setModemRegisters(const ModemConfig* config)
00523 {
00524     spiWrite(RF22_REG_1C_IF_FILTER_BANDWIDTH,                    config->reg_1c);
00525     spiWrite(RF22_REG_1F_CLOCK_RECOVERY_GEARSHIFT_OVERRIDE,      config->reg_1f);
00526     spiBurstWrite(RF22_REG_20_CLOCK_RECOVERY_OVERSAMPLING_RATE, &config->reg_20, 6);
00527     spiBurstWrite(RF22_REG_2C_OOK_COUNTER_VALUE_1,              &config->reg_2c, 3);
00528     spiWrite(RF22_REG_58_CHARGE_PUMP_CURRENT_TRIMMING,           config->reg_58);
00529     spiWrite(RF22_REG_69_AGC_OVERRIDE1,                          config->reg_69);
00530     spiBurstWrite(RF22_REG_6E_TX_DATA_RATE1,                    &config->reg_6e, 5);
00531 }
00532 
00533 // Set one of the canned FSK Modem configs
00534 // Returns true if its a valid choice
00535 boolean RF22::setModemConfig(ModemConfigChoice index)
00536 {
00537     if (index > (sizeof(MODEM_CONFIG_TABLE) / sizeof(ModemConfig)))
00538         return false;
00539 
00540     RF22::ModemConfig cfg;
00541     memcpy(&cfg, &MODEM_CONFIG_TABLE[index], sizeof(RF22::ModemConfig));
00542     setModemRegisters(&cfg);
00543 
00544     return true;
00545 }
00546 
00547 // REVISIT: top bit is in Header Control 2 0x33
00548 void RF22::setPreambleLength(uint8_t nibbles)
00549 {
00550     spiWrite(RF22_REG_34_PREAMBLE_LENGTH, nibbles);
00551 }
00552 
00553 // Caution doesnt set sync word len in Header Control 2 0x33
00554 void RF22::setSyncWords(const uint8_t* syncWords, uint8_t len)
00555 {
00556     spiBurstWrite(RF22_REG_36_SYNC_WORD3, syncWords, len);
00557 }
00558 
00559 void RF22::clearRxBuf()
00560 {
00561     __disable_irq();    // Disable Interrupts
00562     _bufLen = 0;
00563     _rxBufValid = false;
00564     __enable_irq();     // Enable Interrupts
00565 }
00566 
00567 boolean RF22::available()
00568 {
00569     if (!_rxBufValid)
00570         setModeRx(); // Make sure we are receiving
00571     return _rxBufValid;
00572 }
00573 
00574 // Blocks until a valid message is received
00575 void RF22::waitAvailable()
00576 {
00577     while (!available())
00578         ;
00579 }
00580 
00581 // Blocks until a valid message is received or timeout expires
00582 // Return true if there is a message available
00583 bool RF22::waitAvailableTimeout(uint16_t timeout)
00584 {
00585     Timer t;
00586     t.start();
00587     unsigned long endtime = t.read_ms() + timeout;
00588     while (t.read_ms() < endtime)
00589         if (available())
00590             return true;
00591     return false;
00592 }
00593 
00594 void RF22::waitPacketSent()
00595 {
00596     while (_mode == RF22_MODE_TX)
00597         ; // Wait for any previous transmit to finish
00598 }
00599 
00600 // Diagnostic help
00601 void RF22::printBuffer(const uint8_t *buf, uint8_t len)
00602 {
00603 
00604     uint8_t i;
00605 
00606     pc1.printf("\n\rObsah Bufferu ");
00607     for (i = 0; i < len; i++) {
00608         if (i % 16 == 15)
00609             pc1.printf("%d", buf[i]);
00610         else {
00611             pc1.printf("%d", buf[i]);
00612             pc1.printf("  ");
00613         }
00614     }
00615     pc1.printf("  ");
00616 
00617 }
00618 
00619 boolean RF22::recv(uint8_t* buf, uint8_t* len)
00620 {
00621     if (!available())
00622         return false;
00623     __disable_irq();    // Disable Interrupts
00624     if (*len > _bufLen)
00625         *len = _bufLen;
00626     memcpy(buf, _buf, *len); 
00627     printBuffer(_buf, *len);   
00628     clearRxBuf();
00629     __enable_irq();     // Enable Interrupts
00630     printBuffer( buf, *len);
00631 
00632     return true;
00633 }
00634 
00635 void RF22::clearTxBuf()
00636 {
00637     __disable_irq();    // Disable Interrupts
00638     _bufLen = 0;
00639     _txBufSentIndex = 0;
00640     _txPacketSent = false;
00641     __enable_irq();     // Enable Interrupts
00642 }
00643 
00644 void RF22::startTransmit()
00645 {
00646     sendNextFragment(); // Actually the first fragment
00647     spiWrite(RF22_REG_3E_PACKET_LENGTH, _bufLen); // Total length that will be sent
00648     setModeTx(); // Start the transmitter, turns off the receiver
00649 }
00650 
00651 // Restart the transmission of a packet that had a problem
00652 void RF22::restartTransmit()
00653 {
00654     _mode = RF22_MODE_IDLE;
00655     _txBufSentIndex = 0;
00656 //        Serial.println("Restart");
00657     startTransmit();
00658 }
00659 
00660 boolean RF22::send(const uint8_t* data, uint8_t len)       //pocka, nez se odesle paket a potom odesle data
00661 {
00662     waitPacketSent();
00663     {
00664         if (!fillTxBuf(data, len))
00665             return false;
00666         startTransmit();
00667     }
00668 //    printBuffer("send:", data, len);
00669     return true;
00670 }
00671 
00672 boolean RF22::fillTxBuf(const uint8_t* data, uint8_t len)
00673 {
00674     clearTxBuf();
00675     if (!len)
00676         return false;
00677     return appendTxBuf(data, len);
00678 }
00679 
00680 boolean RF22::appendTxBuf(const uint8_t* data, uint8_t len)
00681 {
00682     if (((uint16_t)_bufLen + len) > RF22_MAX_MESSAGE_LEN)
00683         return false;
00684     __disable_irq();    // Disable Interrupts
00685     memcpy(_buf + _bufLen, data, len);
00686     _bufLen += len;
00687     __enable_irq();     // Enable Interrupts
00688 
00689 //    printBuffer("txbuf:", _buf, _bufLen);
00690     return true;
00691 }
00692 
00693 // Assumption: there is currently <= RF22_TXFFAEM_THRESHOLD bytes in the Tx FIFO
00694 void RF22::sendNextFragment()
00695 {
00696     if (_txBufSentIndex < _bufLen) {
00697         // Some left to send?
00698         uint8_t len = _bufLen - _txBufSentIndex;
00699         // But dont send too much
00700         if (len > (RF22_FIFO_SIZE - RF22_TXFFAEM_THRESHOLD - 1))
00701             len = (RF22_FIFO_SIZE - RF22_TXFFAEM_THRESHOLD - 1);
00702         spiBurstWrite(RF22_REG_7F_FIFO_ACCESS, _buf + _txBufSentIndex, len);
00703         _txBufSentIndex += len;
00704     }
00705 }
00706 
00707 // Assumption: there are at least RF22_RXFFAFULL_THRESHOLD in the RX FIFO
00708 // That means it should only be called after a RXFFAFULL interrupt
00709 void RF22::readNextFragment()
00710 {
00711     if (((uint16_t)_bufLen + RF22_RXFFAFULL_THRESHOLD) > RF22_MAX_MESSAGE_LEN)
00712         return; // Hmmm receiver overflow. Should never occur
00713 
00714     // Read the RF22_RXFFAFULL_THRESHOLD octets that should be there
00715     spiBurstRead(RF22_REG_7F_FIFO_ACCESS, _buf + _bufLen, RF22_RXFFAFULL_THRESHOLD);
00716     _bufLen += RF22_RXFFAFULL_THRESHOLD;
00717 }
00718 
00719 // Clear the FIFOs
00720 void RF22::resetFifos()
00721 {
00722     spiWrite(RF22_REG_08_OPERATING_MODE2, RF22_FFCLRRX | RF22_FFCLRTX);
00723     spiWrite(RF22_REG_08_OPERATING_MODE2, 0);
00724 }
00725 
00726 // Clear the Rx FIFO
00727 void RF22::resetRxFifo()
00728 {
00729     spiWrite(RF22_REG_08_OPERATING_MODE2, RF22_FFCLRRX);
00730     spiWrite(RF22_REG_08_OPERATING_MODE2, 0);
00731 }
00732 
00733 // CLear the TX FIFO
00734 void RF22::resetTxFifo()
00735 {
00736     spiWrite(RF22_REG_08_OPERATING_MODE2, RF22_FFCLRTX);
00737     spiWrite(RF22_REG_08_OPERATING_MODE2, 0);
00738 }
00739 
00740 // Default implmentation does nothing. Override if you wish
00741 void RF22::handleExternalInterrupt()
00742 {
00743 }
00744 
00745 // Default implmentation does nothing. Override if you wish
00746 void RF22::handleWakeupTimerInterrupt()
00747 {
00748 }
00749 
00750 void RF22::setHeaderTo(uint8_t to)
00751 {
00752     spiWrite(RF22_REG_3A_TRANSMIT_HEADER3, to);
00753 }
00754 
00755 void RF22::setHeaderFrom(uint8_t from)
00756 {
00757     spiWrite(RF22_REG_3B_TRANSMIT_HEADER2, from);
00758 }
00759 
00760 void RF22::setHeaderId(uint8_t id)
00761 {
00762     spiWrite(RF22_REG_3C_TRANSMIT_HEADER1, id);
00763 }
00764 
00765 void RF22::setHeaderFlags(uint8_t flags)
00766 {
00767     spiWrite(RF22_REG_3D_TRANSMIT_HEADER0, flags);
00768 }
00769 
00770 uint8_t RF22::headerTo()
00771 {
00772     return spiRead(RF22_REG_47_RECEIVED_HEADER3);
00773 }
00774 
00775 uint8_t RF22::headerFrom()
00776 {
00777     return spiRead(RF22_REG_48_RECEIVED_HEADER2);
00778 }
00779 
00780 uint8_t RF22::headerId()
00781 {
00782     return spiRead(RF22_REG_49_RECEIVED_HEADER1);
00783 }
00784 
00785 uint8_t RF22::headerFlags()
00786 {
00787     return spiRead(RF22_REG_4A_RECEIVED_HEADER0);
00788 }
00789 
00790 uint8_t RF22::lastRssi()
00791 {
00792     return _lastRssi;
00793 }
00794 
00795 void RF22::setPromiscuous(boolean promiscuous)
00796 {
00797     spiWrite(RF22_REG_43_HEADER_ENABLE3, promiscuous ? 0x00 : 0xff);
00798 }