James Hilder / Pi_Swarm_Library
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers alpha433.cpp Source File

alpha433.cpp

00001 /*******************************************************************************************
00002  *
00003  * University of York Robot Lab Pi Swarm Library: 433MHz Alpha Transceiver Driver
00004  *
00005  * (C) Dr James Hilder, Dept. Electronics & Computer Science, University of York
00006  *
00007  * Version 0.5  February 2014
00008  *
00009  * Designed for use with the Pi Swarm Board (enhanced MBED sensor board) v1.2
00010  *
00011  ******************************************************************************************/ 
00012 
00013 #include "main.h"
00014 #include "communications.h"
00015 
00016 // Variables
00017 
00018 Timeout reset_timeout;
00019 
00020 char cRFStatus = 0;
00021 
00022 signed short ssTransmitCount = 0;
00023 signed short ssTransmitPointer = 0;
00024 char cTXBuffer[64];
00025 
00026 signed short ssReceiveCount = 0;
00027 signed short ssReceivePointer = 0;
00028 char cRXBuffer[64];
00029 
00030 char cDataAvailable = 0;
00031 
00032 Alpha433::Alpha433(PinName mosi, PinName miso, PinName sck, PinName fss, PinName nirq) :  Stream("Alpha433"), _spi(mosi,miso,sck), _fss(fss), _nirq_test(nirq), _nirq(nirq)
00033 {
00034 
00035 }
00036 
00037 Alpha433::Alpha433() :  Stream("Alpha433"), _spi(p5,p6,p7), _fss(p8), _nirq_test(p11), _nirq(p11)
00038 {
00039 
00040 }
00041 
00042 // Send data on the Alpha 433 transceiver, cCount = string length, cBuffer = data string
00043 unsigned long Alpha433::sendString(char cCount, char* cBuffer)
00044 {
00045     unsigned char i = 0;
00046     if(cRFStatus == ALPHA433_MODE_TRANSMITTING) {
00047         // RF already transmitting
00048         if(RF_VERBOSE == 1)pc.printf("RF Error: Already transmitting\n");
00049         return 1; // Error
00050 
00051     }
00052 
00053     if(cCount > 62) {
00054         // Amount of data to high
00055         if(RF_VERBOSE == 1)pc.printf("RF Error: Too much tx data\n");
00056         return 2; // Error
00057 
00058     }
00059     if(cCount == 0) {
00060         // No Data
00061         if(RF_VERBOSE == 1)pc.printf("RF Error: No tx data\n");
00062         return 3; // Error
00063     }
00064     cTXBuffer[i] = cCount;
00065     unsigned char checksum_byte = 0;
00066     for(i=0; i<cCount; i++)   {
00067         // make a copy
00068         cTXBuffer[i+1] = cBuffer[i];
00069         checksum_byte ^= cBuffer[i];
00070     }
00071     cTXBuffer[cCount+1] = checksum_byte;
00072     if(RF_VERBOSE == 1)pc.printf("RF Message: \"%s\" Checksum: %2X\n",cBuffer,checksum_byte);
00073     ssTransmitCount = cCount+3; 
00074     // add count and checksum
00075     ssTransmitPointer = -6;
00076     cRFStatus = ALPHA433_MODE_SWITCHING;
00077     disableReceiver();
00078     enableTransmitter();
00079     cRFStatus = ALPHA433_MODE_TRANSMITTING;
00080 
00081     if(RF_VERBOSE == 1)pc.printf("RF Transmitting");
00082 
00083     while(ssTransmitPointer <= ssTransmitCount) {
00084         while(_nirq_test);
00085         if(ssTransmitPointer < -2) _write(0xB8AA);  // send sync
00086         else if(ssTransmitPointer == -2) _write(0xB82D);  // send first part of the fifo pattern;
00087         else if(ssTransmitPointer == -1) _write(0xB8D4);  // send second part of the fifo pattern;
00088         else if(ssTransmitPointer == ssTransmitCount) _write(0xB800);   // send dummy byte
00089         else _write(0xB800 | cTXBuffer[ssTransmitPointer]);   // send data
00090         ssTransmitPointer++;
00091     }
00092 
00093     _write(0xB800);   // send dummy byte, maybe redundant
00094     disableTransmitter();
00095     enableReceiver();
00096     ssReceivePointer = 0;
00097     cRFStatus = ALPHA433_MODE_RECEIVING;
00098     return 0;
00099 }
00100 
00101 // Handle new RF Data
00102 void Alpha433::dataAvailable(char cCount, char* cBuffer)
00103 {
00104     char rstring [cCount+1];
00105     char checksum = 0;
00106     int i;
00107     for(i=0; i<cCount; i++) {
00108         rstring[i]=cBuffer[i];
00109         checksum ^= rstring[i];
00110     }
00111     rstring[cCount]=0;
00112     if (cBuffer[cCount] != checksum) {
00113         if(RF_VERBOSE == 1)pc.printf("RF Received [%d] \"%s\" (checksum failed: expected %02X, received %02X)%02X %02X\n",cCount,rstring,checksum,cBuffer[cCount],cBuffer[cCount-1],cBuffer[cCount+1]);
00114     } else {
00115         if(RF_VERBOSE == 1)pc.printf("RF Received [%d] \"%s\" (checksum passed)\n",cCount,rstring);
00116         if(USE_COMMUNICATION_STACK == 1) {
00117             processRadioData(rstring, cCount);
00118         } else {
00119             processRawRFData(rstring, cCount);
00120         }
00121     }
00122 }
00123 
00124 
00125 // Enable RF Transmitter
00126 void Alpha433::enableTransmitter(void)
00127 {
00128     if(RF_VERBOSE == 1)pc.printf("RF Enable TX\n");
00129     //RFCommand(0x8229);
00130     _write(0x8229);
00131 }
00132 
00133 // Disable RF Transmitter
00134 void Alpha433::disableTransmitter(void)
00135 {
00136     if(RF_VERBOSE == 1)pc.printf("RF Disable TX\n");
00137     //RFCommand(0x8209);
00138     _write(0x8209);
00139 }
00140 
00141 
00142 // Enable RF Receiver
00143 void Alpha433::enableReceiver(void)
00144 {
00145     if(RF_VERBOSE == 1)pc.printf("RF Enable RX\n");
00146     //RFCommand(0x8288);
00147     _write(0x8288);
00148     enableFifoFill();
00149 }
00150 
00151 // Disable RF Receiver
00152 void Alpha433::disableReceiver(void)
00153 {
00154     if(RF_VERBOSE == 1)pc.printf("RF Disable RX\n");
00155     //RFCommand(0x8208);
00156     _write(0x8208);
00157     //rx_led = 0;
00158     disableFifoFill();
00159 }
00160 
00161 // SSI FiFo Clear
00162 void Alpha433::clearBuffer(void)
00163 {
00164     while(_read(0xB000) != 0);
00165 }
00166 
00167 // Reset RF
00168 void Alpha433::rf_reset(void)
00169 {
00170     // Chip must be deselected
00171     _fss = 1;
00172 
00173     // Setup the spi for 16 bit data, high steady state clock, second edge capture, with a 1MHz clock rate
00174     _spi.format(16,0);  //Was 16,3
00175     _spi.frequency(2000000);
00176     _nirq.mode(PullUp);
00177     _nirq.fall(this,&Alpha433::interrupt);
00178     // Select the device by seting chip select low
00179     _fss = 0;
00180     //int_out=0;
00181 
00182 }
00183 
00184 // Timeout interrupt routine - reset chip
00185 void Alpha433::timeout(void)
00186 {
00187     if(RF_VERBOSE == 1)pc.printf("RF Error on read; resetting chip\n");
00188     rf_init();
00189 }
00190 
00191 // Initialise RF
00192 void Alpha433::rf_init(void)
00193 {
00194 
00195     if(RF_VERBOSE == 1)pc.printf("RF Init start\n");
00196     rf_reset(); // RF Hardware Reset
00197     _write(0x0000);    // read status to cancel prior interrupt
00198     _write(0x8000 | ALPHA433_FREQUENCY | ALPHA433_CRYSTAL_LOAD | ALPHA433_USE_FIFO);
00199     _write(0x9000 | ALPHA433_PIN20 | ALPHA433_VDI_RESPONSE | ALPHA433_BANDWIDTH | ALPHA433_LNA_GAIN | ALPHA433_RSSI);
00200     _write(0xC228 | ALPHA433_CLOCK_RECOVERY | ALPHA433_FILTER | ALPHA433_DQD);
00201     _write(0xCA00 | ALPHA433_FIFO_LEVEL | ALPHA433_FIFO_FILL | ALPHA433_HI_SENS_RESET);
00202     _write(0xC400 | ALPHA433_AFC_MODE | ALPHA433_AFC_RANGE | ALPHA433_AFC_FINE_MODE | ALPHA433_AFC);
00203     _write(0x9800 | ALPHA433_MOD_POLARITY | ALPHA433_MOD_FREQUENCY | ALPHA433_TX_POWER);
00204     _write(0xC000 | ALPHA433_CLK_OUT | ALPHA433_LOW_BAT);
00205     enableReceiver();
00206     ssReceivePointer = 0;
00207     reset_timeout.attach(this,&Alpha433::timeout,TIMEOUT);
00208     if(RF_VERBOSE == 1)pc.printf("RF Init end\n");
00209     cRFStatus = ALPHA433_MODE_RECEIVING;
00210 }
00211 
00212 
00213 // RF Interrupt Called - handle received data
00214 void Alpha433::interrupt(void)
00215 {
00216     if(cRFStatus == ALPHA433_MODE_RECEIVING) {
00217         //Add reset timeout
00218         reset_timeout.detach();
00219         reset_timeout.attach(this,&Alpha433::timeout,0.5);
00220         //pc.printf("Rec. ISR\n");
00221         int res = _read(0x0000);
00222         if(res==0) res = _read(0x0000);
00223         char read_failure = 0;
00224 
00225         if (res & (ALPHA433_STATUS_TX_NEXT_BYTE | ALPHA433_STATUS_FIFO_LIMIT_REACHED)) { // RF: waiting for next Byte OR FIFO full
00226             //pc.printf("Receiving");
00227             cRXBuffer[ssReceivePointer] = _read(0xB000) & 0xFF; // get data
00228             if(ssReceivePointer == 0) {
00229                 ssReceiveCount = cRXBuffer[0];
00230 
00231                 if((ssReceiveCount == 0) || (ssReceiveCount > 62)) { // error amount of data
00232                     read_failure=1;
00233                     pc.printf("Error amount of RX data: %d\n",ssReceiveCount);
00234                     reset_timeout.detach();
00235                     reset_timeout.attach(this,&Alpha433::timeout,TIMEOUT);
00236                 } else {
00237                     ssReceiveCount += 2;   // add count + checksum
00238                     //pc.printf("\nBytes to receive: %d\n",ssReceiveCount);
00239                 }
00240 
00241             }
00242             if(!read_failure) {
00243                 ssReceivePointer++;
00244                 if (ssReceivePointer >= ssReceiveCount) { // End transmission
00245                     disableFifoFill();
00246                     enableFifoFill();
00247                     //irqled=0;
00248                     reset_timeout.detach();
00249                     reset_timeout.attach(this,&Alpha433::timeout,TIMEOUT);
00250                     ssReceivePointer = 0;
00251                     dataAvailable(cRXBuffer[0], &cRXBuffer[1]);
00252                 }
00253             } else {
00254                 disableFifoFill();
00255                 enableFifoFill();
00256                 ssReceivePointer = 0;
00257                 reset_timeout.detach();
00258                 reset_timeout.attach(this,&Alpha433::timeout,TIMEOUT);
00259             }
00260         }
00261     }
00262 }
00263 
00264 // RF Set Datarate
00265 void Alpha433::setDatarate(unsigned long ulValue)
00266 {
00267     unsigned long ulRateCmd;
00268     if(ulValue < 3000) ulRateCmd = 0x0080 | (10000000 / 29 / 8 / ulValue) - 1;
00269     else ulRateCmd = 0x0000 | (10000000 / 29 / 1 / ulValue) - 1;
00270     _write(0xC600 | ulRateCmd);
00271 }
00272 
00273 // RF Set Frequency
00274 void Alpha433::setFrequency(unsigned long ulValue)
00275 {
00276     unsigned long ulRateCmd;
00277 
00278 #if (ALPHA433_FREQUENCY  == ALPHA433_FREQUENCY_315)
00279     ulRateCmd = (ulValue - 10000000 * 1 * 31) * 4 / 10000;
00280 
00281 #elif (ALPHA433_FREQUENCY == ALPHA433_FREQUENCY_433)
00282     ulRateCmd = (ulValue - 10000000 * 1 * 43) * 4 / 10000;
00283 
00284 #elif (ALPHA433_FREQUENCY == ALPHA433_FREQUENCY_868)
00285     ulRateCmd = (ulValue - 10000000 * 2 * 43) * 4 / 10000;
00286 
00287 #elif (ALPHA433_FREQUENCY == ALPHA433_FREQUENCY_915)
00288     ulRateCmd = (ulValue - 10000000 * 3 * 30) * 4 / 10000;
00289 #endif
00290 
00291     _write(0xA000 | ulRateCmd);
00292 }
00293 
00294 // Enable RF Receiver FiFo fill
00295 void Alpha433::enableFifoFill(void)
00296 {
00297     _write(0xCA00 | ALPHA433_FIFO_LEVEL | ALPHA433_FIFO_FILL | ALPHA433_HI_SENS_RESET | 0x0002);
00298     while((_read(0x0000) & ALPHA433_STATUS_FIFO_EMPTY) == 0);
00299 }
00300 
00301 // Disable RF Receiver FiFo fill
00302 void Alpha433::disableFifoFill(void)
00303 {
00304     _write(0xCA00 | ALPHA433_FIFO_LEVEL | ALPHA433_FIFO_FILL | ALPHA433_HI_SENS_RESET);
00305 }
00306 
00307 
00308 int Alpha433::readStatusByte()
00309 {
00310     if(RF_VERBOSE == 1)pc.printf("RF Reading status byte\n");
00311     return _read(0x0000);
00312 }
00313 
00314 //-----PRIVATE FUNCTIONS-----
00315 
00316 void Alpha433::_write(int address)
00317 {
00318     _fss=0;                 //select the deivce
00319     _spi.write(address);    //write the address of where the data is to be written first
00320     //pc.printf("Write data: %04X\n",address);
00321     _fss=1;                 //deselect the device
00322 }
00323 
00324 int Alpha433::_read(int address)
00325 {
00326     int _data;
00327     _fss=0;                  //select the device
00328     _data = _spi.write(address);     //select the register
00329     //pc.printf("Read data: %04X\n",_data);
00330     _fss=1;                  //deselect the device
00331     return _data;            //return the data
00332 
00333 }
00334 
00335 int Alpha433::_putc (int c)
00336 {
00337     return(c);
00338 }
00339 
00340 int Alpha433::_getc (void)
00341 {
00342     char r = 0;
00343     return(r);
00344 }