Table controller for piswarm-office

Dependencies:   mbed

Fork of PiSwarmTableController by piswarm

Revision:
2:c81f4ef63132
Child:
5:68a1ce96bfeb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/alpha433.cpp	Thu May 22 14:25:10 2014 +0000
@@ -0,0 +1,379 @@
+/* University of York Robot Lab m3pi Library: 433MHz Alpha Transceiver
+ *
+ * (C) Dr James Hilder, Dept. Electronics & Computer Science, University of York
+ * 
+ * October 2013
+ *
+ * Designed for use with the enhanced MBED sensor board
+ *
+ * Based on code developed by Tobias Dipper, University of Stuttgart
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+ 
+#include "mbed.h"
+#include "alpha433.h"
+#include "main.h"
+
+// Variables
+
+//Serial pc(USBTX, USBRX);
+//DigitalOut tx_led(LED2);
+//DigitalOut rx_led(LED3);
+DigitalOut irqled(LED4);
+Timeout reset_timeout;
+
+
+char cRFStatus = 0;
+
+signed short ssTransmitCount = 0;
+signed short ssTransmitPointer = 0;
+char cTXBuffer[64];
+
+signed short ssReceiveCount = 0;
+signed short ssReceivePointer = 0;
+char cRXBuffer[64];
+
+char cDataAvailable = 0;
+
+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) {
+  
+}
+
+Alpha433::Alpha433() :  Stream("alpha433"), _spi(p5,p6,p7), _fss(p8), _nirq_test(p11), _nirq(p11)  {
+  
+}
+
+
+
+
+// RF Send Data
+//
+//  Eg:
+//  unsigned char message[32];
+//  unsigned char count;
+//  count = snprintf(message, 32, "Hello: %i", 42);
+//  sendString(count, message);
+unsigned long Alpha433::sendString(char cCount, char* cBuffer)
+{
+    //pc.printf("SendString called");
+    char i = 0;
+    if(cRFStatus == ALPHA433_MODE_TRANSMITTING) {// RF already transmitting
+            pc.printf("Error: Already transmitting\n");
+
+        return 1; // Error
+        
+        }
+  
+    if(cCount > 62) {// Amount of data to high
+               pc.printf("Error: Too much tx data\n");
+
+        return 2; // Error
+  
+    }
+    if(cCount == 0) {// No Data
+               pc.printf("Error: No tx data\n");
+        return 3; // Error
+    }
+    cTXBuffer[i] = cCount;
+
+    unsigned char checksum_byte = 0;  
+    for(i=0; i<cCount; i++)   {// make a copy
+        cTXBuffer[i+1] = cBuffer[i];
+        checksum_byte ^= cBuffer[i];
+    }    
+    cTXBuffer[cCount+1] = checksum_byte;
+    //pc.printf("Message: \"%s\" Checksum: %2X\n",cBuffer,checksum_byte);
+    ssTransmitCount = cCount+3; // add count and checksum
+    ssTransmitPointer = -6;
+    cRFStatus = ALPHA433_MODE_SWITCHING;
+    disableReceiver();
+    enableTransmitter();
+    cRFStatus = ALPHA433_MODE_TRANSMITTING; 
+    
+    //pc.printf("Transmitting %d bytes\n",ssTransmitCount);
+
+    while(ssTransmitPointer <= ssTransmitCount){
+       while(_nirq_test);
+       
+       if(ssTransmitPointer < -2)
+                    _write(0xB8AA);  // send sync
+                else if(ssTransmitPointer == -2)
+                    _write(0xB82D);  // send first part of the fifo pattern;
+                else if(ssTransmitPointer == -1)
+                    _write(0xB8D4);  // send second part of the fifo pattern;
+                else if(ssTransmitPointer == ssTransmitCount)
+                    _write(0xB800);   // send dummy byte
+                else 
+                     _write(0xB800 | cTXBuffer[ssTransmitPointer]);   // send data
+      ssTransmitPointer++; 
+    }
+                              
+    _write(0xB800);   // send dummy byte, maybe redundant
+    disableTransmitter();
+    enableReceiver();
+    ssReceivePointer = 0;
+    cRFStatus = ALPHA433_MODE_RECEIVING;
+    return 0;
+}
+
+// Enable RF Transmitter
+void Alpha433::enableTransmitter(void)
+{
+    //pc.printf("Enable TX\n");
+    //RFCommand(0x8229);
+    _write(0x8229);
+    //tx_led = 1;
+}
+
+// Disable RF Transmitter
+void Alpha433::disableTransmitter(void)
+{
+    //pc.printf("Disable TX\n");
+    //RFCommand(0x8209);
+    _write(0x8209);
+   // tx_led = 0;
+
+}
+
+
+// Enable RF Receiver
+void Alpha433::enableReceiver(void)
+{
+    //pc.printf("Enable RX\n");
+    //RFCommand(0x8288);
+    _write(0x8288);
+   // rx_led = 1;
+    enableFifoFill();
+}
+
+// Disable RF Receiver
+void Alpha433::disableReceiver(void)
+{    
+   //pc.printf("Disable RX\n");
+    //RFCommand(0x8208);
+    _write(0x8208);
+   // rx_led = 0;
+    disableFifoFill();
+}
+
+// SSI FiFo Clear
+void Alpha433::clearBuffer(void)
+{
+    while(_read(0xB000) != 0); 
+}
+
+// Reset RF
+void Alpha433::rf_reset(void)
+{
+    // Chip must be deselected
+    _fss = 1;
+
+    // Setup the spi for 16 bit data, high steady state clock, second edge capture, with a 1MHz clock rate
+    _spi.format(16,0);  //Was 16,3
+    _spi.frequency(2000000);
+    _nirq.mode(PullUp);
+    _nirq.fall(this,&Alpha433::interrupt);
+    // Select the device by seting chip select low
+    _fss = 0;
+    //pc.printf("End reset\n");
+
+}
+
+void Alpha433::timeout(void)
+{
+    pc.printf("Error on read; resetting chip\n");
+    rf_init();
+}
+
+// Initialise RF
+void Alpha433::rf_init(void)
+{
+    
+    pc.printf("Init start\n");
+
+    rf_reset(); // RF Hardware Reset
+    _write(0x0000);    // read status to cancel prior interrupt           
+    pc.printf("Start setup\n");
+
+    _write(0x8000 | ALPHA433_FREQUENCY | ALPHA433_CRYSTAL_LOAD | ALPHA433_USE_FIFO);
+    _write(0x9000 | ALPHA433_PIN20 | ALPHA433_VDI_RESPONSE | ALPHA433_BANDWIDTH | ALPHA433_LNA_GAIN | ALPHA433_RSSI);
+    _write(0xC228 | ALPHA433_CLOCK_RECOVERY | ALPHA433_FILTER | ALPHA433_DQD);
+    _write(0xCA00 | ALPHA433_FIFO_LEVEL | ALPHA433_FIFO_FILL | ALPHA433_HI_SENS_RESET);
+    _write(0xC400 | ALPHA433_AFC_MODE | ALPHA433_AFC_RANGE | ALPHA433_AFC_FINE_MODE | ALPHA433_AFC);
+    _write(0x9800 | ALPHA433_MOD_POLARITY | ALPHA433_MOD_FREQUENCY | ALPHA433_TX_POWER);
+    _write(0xC000 | ALPHA433_CLK_OUT | ALPHA433_LOW_BAT);
+
+    enableReceiver();
+    //pc.printf("End setup\n");
+
+    ssReceivePointer = 0;
+    reset_timeout.attach(this,&Alpha433::timeout,TIMEOUT);
+    pc.printf("Init end\n");
+    cRFStatus = ALPHA433_MODE_RECEIVING;
+   
+}
+    
+  
+// RF Interrupt
+void Alpha433::interrupt(void)
+{
+   if(cRFStatus == ALPHA433_MODE_RECEIVING){
+      irqled=1;
+      //Add reset timeout
+      reset_timeout.detach(); 
+      reset_timeout.attach(this,&Alpha433::timeout,0.5);
+      pc.printf("Rec. ISR\n");
+      int res = _read(0x0000);
+      if(res==0) res = _read(0x0000);
+      char read_failure = 0;
+
+      if (res & (ALPHA433_STATUS_TX_NEXT_BYTE | ALPHA433_STATUS_FIFO_LIMIT_REACHED)) { // RF: waiting for next Byte OR FIFO full
+        pc.printf("Receiving");
+        cRXBuffer[ssReceivePointer] = _read(0xB000) & 0xFF; // get data
+        if(ssReceivePointer == 0) {
+           ssReceiveCount = cRXBuffer[0];
+       
+           if((ssReceiveCount == 0) || (ssReceiveCount > 62)) { // error amount of data
+             read_failure=1;
+             pc.printf("Error amount of RX data: %d\n",ssReceiveCount);
+             reset_timeout.detach();
+             reset_timeout.attach(this,&Alpha433::timeout,TIMEOUT);
+           } else ssReceiveCount += 2;   // add count + checksum
+        }
+        if(!read_failure){
+          ssReceivePointer++;
+          if (ssReceivePointer > ssReceiveCount) { // End transmission
+             disableFifoFill();
+             enableFifoFill();
+             irqled=0;      
+             reset_timeout.detach(); 
+             reset_timeout.attach(this,&Alpha433::timeout,TIMEOUT);
+             ssReceivePointer = 0;
+             dataAvailable(cRXBuffer[0], &cRXBuffer[1]);
+          }
+        }else{
+             disableFifoFill();
+             enableFifoFill();
+             ssReceivePointer = 0;
+             reset_timeout.detach();
+             reset_timeout.attach(this,&Alpha433::timeout,TIMEOUT);
+        }
+     }
+   }
+}
+
+// RF Set Datarate
+void Alpha433::setDatarate(unsigned long ulValue)
+{
+    unsigned long ulRateCmd;
+    if(ulValue < 3000) ulRateCmd = 0x0080 | (10000000 / 29 / 8 / ulValue) - 1;
+    else ulRateCmd = 0x0000 | (10000000 / 29 / 1 / ulValue) - 1;
+    _write(0xC600 | ulRateCmd);
+}
+
+// RF Set Frequency
+void Alpha433::setFrequency(unsigned long ulValue)
+{
+    unsigned long ulRateCmd;
+
+#if (ALPHA433_FREQUENCY  == ALPHA433_FREQUENCY_315)
+    ulRateCmd = (ulValue - 10000000 * 1 * 31) * 4 / 10000;
+
+#elif (ALPHA433_FREQUENCY == ALPHA433_FREQUENCY_433)
+    ulRateCmd = (ulValue - 10000000 * 1 * 43) * 4 / 10000;
+
+#elif (ALPHA433_FREQUENCY == ALPHA433_FREQUENCY_868)
+    ulRateCmd = (ulValue - 10000000 * 2 * 43) * 4 / 10000;
+
+#elif (ALPHA433_FREQUENCY == ALPHA433_FREQUENCY_915)
+    ulRateCmd = (ulValue - 10000000 * 3 * 30) * 4 / 10000;
+#endif
+
+    _write(0xA000 | ulRateCmd);
+}
+
+
+
+// Enable RF Receiver FiFo fill
+void Alpha433::enableFifoFill(void)
+{
+    _write(0xCA00 | ALPHA433_FIFO_LEVEL | ALPHA433_FIFO_FILL | ALPHA433_HI_SENS_RESET | 0x0002);
+    while((_read(0x0000) & ALPHA433_STATUS_FIFO_EMPTY) == 0);
+}
+
+// Disable RF Receiver FiFo fill
+void Alpha433::disableFifoFill(void)
+{
+    _write(0xCA00 | ALPHA433_FIFO_LEVEL | ALPHA433_FIFO_FILL | ALPHA433_HI_SENS_RESET);
+}
+
+// Handle new RF Data
+void Alpha433::dataAvailable(char cCount, char* cBuffer)
+{
+   char rstring [cCount+1];
+   char checksum = 0;
+   int i;
+   for(i=0;i<cCount;i++){
+    rstring[i]=cBuffer[i];
+    checksum ^= rstring[i];
+   }
+   rstring[cCount]=0;
+   if (cBuffer[cCount] != checksum){
+        pc.printf("Received [%d] \"%s\" (checksum failed: expected %02X, received %02X)%02X %02X\n",cCount,rstring,checksum,cBuffer[cCount],cBuffer[cCount-1],cBuffer[cCount+1]);
+   }else {
+   pc.printf("Received [%d] \"%s\" (checksum passed)\n",cCount,rstring);
+   handleData(rstring, cCount);
+   }
+}
+
+
+int Alpha433::readStatusByte()
+{
+   pc.printf("Reading status byte\n");
+   return _read(0x0000); 
+}
+
+//-----PRIVATE FUNCTIONS-----
+
+void Alpha433::_write(int address) {
+    _fss=0;                 //select the deivce
+    _spi.write(address);    //write the address of where the data is to be written first
+    //pc.printf("Write data: %04X\n",address);
+    _fss=1;                 //deselect the device
+}
+
+int Alpha433::_read(int address) {
+    int _data;
+    _fss=0;                  //select the device
+    _data = _spi.write(address);     //select the register
+    //pc.printf("Read data: %04X\n",_data);
+    _fss=1;                  //deselect the device
+    return _data;            //return the data
+
+}
+
+int Alpha433::_putc (int c) {
+    return(c);
+}
+
+int Alpha433::_getc (void) {
+    char r = 0;
+    return(r);
+}
\ No newline at end of file