Specialized interface code for the nRF24L01P wireless transceiver.

Dependents:   WalkingRobot PcRadioBridge FzeroXcontroller WalkingRobot ... more

Revision:
0:fb0cf6209cd3
Child:
1:32635715529f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Radio.cpp	Sun Dec 23 04:48:16 2012 +0000
@@ -0,0 +1,207 @@
+#include "Radio.h"
+#include "nRF24L01P_defs.h"
+
+
+
+Radio::Radio(PinName mosi, PinName miso, PinName sck, PinName csn, PinName ce, PinName irq) 
+: _spi(mosi, miso, sck), _csn(csn), _ce(ce), _irq(irq)
+{
+    // Disable nRF24L01+
+    _ce = 0;
+    
+    // Disable chip select
+    _csn = 1;
+    
+    // Set up SPI
+    _spi.frequency(SPI_FREQUENCY);
+    _spi.format(8, 0);
+    
+    // Power up
+    int config = getRegister(CONFIG);
+    config |= CONFIG_PWR_UP;
+    setRegister(CONFIG, config);
+    wait_us(TIMING_Tpd2stby);
+    
+    // Set to use controller channel 0
+    controller = 0;
+    
+    // Set up IRQ
+    _irq.fall(this, &Radio::receive);
+}
+
+
+
+void Radio::reset()
+{
+    // Wait for power on reset
+    wait_us(TIMING_Tpor);
+
+    // Put into standby
+    _ce = 0;
+    
+    // Configure registers
+    setRegister(CONFIG, CONFIG_MASK_TX_DS | CONFIG_MASK_MAX_RT | CONFIG_EN_CRC | CONFIG_PWR_UP | CONFIG_PRIM_RX);
+    setRegister(EN_AA, 0x00);
+    setRegister(EN_RXADDR, ERX_P0 | ERX_P1);
+    setRegister(SETUP_AW, SETUP_AW_3BYTES);
+    setRegister(SETUP_RETR, 0x00);
+    setRegister(RF_CH, RF_CHANNEL);
+    setRegister(RF_SETUP, RF_SETUP_RF_DR_HIGH | RF_SETUP_RF_PWR_0);
+    setRegister(STATUS, STATUS_RX_DR | STATUS_TX_DS | STATUS_MAX_RT);
+    setRegister(RX_PW_P0, 4);
+    setRegister(RX_PW_P1, 4);
+    setRegister(DYNPD, 0x00);
+    setRegister(FEATURE, 0x00);
+    
+    // Set addresses
+    _csn = 0;
+    _spi.write(W_REGISTER | RX_ADDR_P0);
+    _spi.write(CTRL_BASE_ADDRESS_1 + (controller & 0xf));
+    _spi.write(CTRL_BASE_ADDRESS_2);
+    _spi.write(CTRL_BASE_ADDRESS_3);
+    _csn = 1;
+    _csn = 0;
+    _spi.write(W_REGISTER | RX_ADDR_P1);
+    _spi.write(ROBOT_ADDRESS_1);
+    _spi.write(ROBOT_ADDRESS_2);
+    _spi.write(ROBOT_ADDRESS_3);
+    _csn = 1;
+    _csn = 0;
+    _spi.write(W_REGISTER | TX_ADDR);
+    _spi.write(ROBOT_ADDRESS_1);
+    _spi.write(ROBOT_ADDRESS_2);
+    _spi.write(ROBOT_ADDRESS_3);
+    _csn = 1;
+    
+    // Put into PRX
+    _ce = 1;
+    wait_us(TIMING_Tstby2a);
+    
+    // Flush FIFOs
+    _csn = 0;
+    _spi.write(FLUSH_TX);
+    _csn = 1;
+    _csn = 0;
+    _spi.write(FLUSH_RX);
+    _csn = 1;
+}
+
+
+
+void Radio::transmit(uint32_t data)
+{
+    // Put into standby
+    _ce = 0;
+    
+    // Configure for PTX
+    int config = getRegister(CONFIG);
+    config &= ~CONFIG_PRIM_RX;
+    setRegister(CONFIG, config);
+    
+    // Write packet data
+    _csn = 0;
+    _spi.write(W_TX_PAYLOAD);
+    _spi.write( (data>>0) & 0xff );
+    _spi.write( (data>>8) & 0xff );
+    _spi.write( (data>>16) & 0xff );
+    _spi.write( (data>>24) & 0xff );
+    _csn = 1;
+    
+    // Put into PTX
+    _ce = 1;
+    wait_us(TIMING_Tstby2a);
+    _ce = 0;
+    
+    // Wait for message transmission and put into PRX
+    wait_us(TIMING_Toa);
+    config = getRegister(CONFIG);
+    config |= CONFIG_PRIM_RX;
+    setRegister(CONFIG, config);
+    setRegister(STATUS, STATUS_TX_DS);
+    _ce = 1;
+}
+
+
+
+void Radio::receive()
+{
+    uint32_t data = 0;
+    int pipe;
+    
+    // Reset IRQ pin
+    setRegister(STATUS, STATUS_RX_DR);
+    
+    // Check data pipe
+    wait_us(1000);
+    pipe = getStatus() & STATUS_RN_P_MASK;
+    
+    // Read data
+    _csn = 0;
+    _spi.write(R_RX_PAYLOAD);
+    data |= _spi.write(NOP)<<0;
+    data |= _spi.write(NOP)<<8;
+    data |= _spi.write(NOP)<<16;
+    data |= _spi.write(NOP)<<24;
+    _csn = 1;
+    
+    // Sort into recieve buffer
+    switch(pipe)
+    {
+    case STATUS_RN_P_NO_P0:
+        rx_controller = data;
+        break;
+        
+    case STATUS_RN_P_NO_P1:
+        rx_robot[rx_robot_pos++ % RX_BUFFER_SIZE] = data;
+        break;
+        
+    default:
+        break;
+    }
+}
+
+
+
+int Radio::getRegister(int address)
+{
+    _csn = 0;
+    int rc = R_REGISTER | (address & REGISTER_ADDRESS_MASK);
+    _spi.write(rc);
+    int data = _spi.write(NOP);
+    _csn = 1;
+    return data;
+}
+
+
+
+int Radio::getStatus()
+{
+    _csn = 0;
+    int status = _spi.write(NOP);
+    _csn = 1;
+    return status;
+}
+
+
+void Radio::setRegister(int address, int data)
+{
+    bool enabled = false;
+    if (_ce == 1)
+    {
+        enabled = true;
+        _ce = 0;
+    }
+    
+    _csn = 0;
+    int rc = W_REGISTER | (address & REGISTER_ADDRESS_MASK);
+    _spi.write(rc);
+    _spi.write(data & 0xff);
+    _csn = 1;
+    
+    if (enabled)
+    {
+        _ce = 1;
+        wait_us(TIMING_Tpece2csn);
+    }
+    
+}