Specialized interface code for the nRF24L01P wireless transceiver.
Dependents: WalkingRobot PcRadioBridge FzeroXcontroller WalkingRobot ... more
Radio.cpp
- Committer:
- pclary
- Date:
- 2013-01-17
- Revision:
- 4:7953b5fa8aae
- Parent:
- 3:245faa365852
File content as of revision 4:7953b5fa8aae:
#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); // 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; while (!(getRegister(FIFO_STATUS) & FIFO_STATUS_RX_EMPTY)) { // 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; clearTimeout.attach(this, &Radio::clear, 0.5f); break; case STATUS_RN_P_NO_P1: rx_robot[rx_robot_pos++ % RX_BUFFER_SIZE] = data; break; default: break; } } // Reset IRQ pin setRegister(STATUS, STATUS_RX_DR); } void Radio::clear() { rx_controller = 0; } 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); } } /************************************************************************/ RadioController::RadioController(PinName mosi, PinName miso, PinName sck, PinName csn, PinName ce) : _spi(mosi, miso, sck), _csn(csn), _ce(ce) { // Disable nRF24L01+ _ce = 0; // Disable chip select _csn = 1; // Set up SPI _spi.frequency(SPI_FREQUENCY); _spi.format(8, 0); // Set to use controller channel 0 controller = 0; } void RadioController::reset() { // Wait for power on reset wait_us(TIMING_Tpor); // Put into standby _ce = 0; // Configure registers setRegister(CONFIG, CONFIG_MASK_RX_DR | CONFIG_MASK_TX_DS | CONFIG_MASK_MAX_RT | CONFIG_EN_CRC | CONFIG_PWR_UP); setRegister(EN_AA, 0x00); setRegister(EN_RXADDR, 0x00); 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(DYNPD, 0x00); setRegister(FEATURE, 0x00); // Set transmit address _csn = 0; _spi.write(W_REGISTER | TX_ADDR); _spi.write(CTRL_BASE_ADDRESS_1 + (controller & 0xf)); _spi.write(CTRL_BASE_ADDRESS_2); _spi.write(CTRL_BASE_ADDRESS_3); _csn = 1; // Flush TX FIFO _csn = 0; _spi.write(FLUSH_TX); _csn = 1; } void RadioController::transmit(uint32_t data) { // 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 and transmit packet _ce = 1; wait_us(TIMING_Tstby2a); // Go back into standby _ce = 0; } void RadioController::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); } }