Table controller for piswarm-office
Fork of PiSwarmTableController by
alpha433.cpp
- Committer:
- jah128
- Date:
- 2014-05-22
- Revision:
- 2:c81f4ef63132
- Child:
- 5:68a1ce96bfeb
File content as of revision 2:c81f4ef63132:
/* 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); }