Specialized interface code for the nRF24L01P wireless transceiver.

Dependents:   WalkingRobot PcRadioBridge FzeroXcontroller WalkingRobot ... more

Committer:
pclary
Date:
Sun Dec 23 04:48:16 2012 +0000
Revision:
0:fb0cf6209cd3
Child:
1:32635715529f
Working robot-to-robot communication along with a test program

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pclary 0:fb0cf6209cd3 1 #include "Radio.h"
pclary 0:fb0cf6209cd3 2 #include "nRF24L01P_defs.h"
pclary 0:fb0cf6209cd3 3
pclary 0:fb0cf6209cd3 4
pclary 0:fb0cf6209cd3 5
pclary 0:fb0cf6209cd3 6 Radio::Radio(PinName mosi, PinName miso, PinName sck, PinName csn, PinName ce, PinName irq)
pclary 0:fb0cf6209cd3 7 : _spi(mosi, miso, sck), _csn(csn), _ce(ce), _irq(irq)
pclary 0:fb0cf6209cd3 8 {
pclary 0:fb0cf6209cd3 9 // Disable nRF24L01+
pclary 0:fb0cf6209cd3 10 _ce = 0;
pclary 0:fb0cf6209cd3 11
pclary 0:fb0cf6209cd3 12 // Disable chip select
pclary 0:fb0cf6209cd3 13 _csn = 1;
pclary 0:fb0cf6209cd3 14
pclary 0:fb0cf6209cd3 15 // Set up SPI
pclary 0:fb0cf6209cd3 16 _spi.frequency(SPI_FREQUENCY);
pclary 0:fb0cf6209cd3 17 _spi.format(8, 0);
pclary 0:fb0cf6209cd3 18
pclary 0:fb0cf6209cd3 19 // Power up
pclary 0:fb0cf6209cd3 20 int config = getRegister(CONFIG);
pclary 0:fb0cf6209cd3 21 config |= CONFIG_PWR_UP;
pclary 0:fb0cf6209cd3 22 setRegister(CONFIG, config);
pclary 0:fb0cf6209cd3 23 wait_us(TIMING_Tpd2stby);
pclary 0:fb0cf6209cd3 24
pclary 0:fb0cf6209cd3 25 // Set to use controller channel 0
pclary 0:fb0cf6209cd3 26 controller = 0;
pclary 0:fb0cf6209cd3 27
pclary 0:fb0cf6209cd3 28 // Set up IRQ
pclary 0:fb0cf6209cd3 29 _irq.fall(this, &Radio::receive);
pclary 0:fb0cf6209cd3 30 }
pclary 0:fb0cf6209cd3 31
pclary 0:fb0cf6209cd3 32
pclary 0:fb0cf6209cd3 33
pclary 0:fb0cf6209cd3 34 void Radio::reset()
pclary 0:fb0cf6209cd3 35 {
pclary 0:fb0cf6209cd3 36 // Wait for power on reset
pclary 0:fb0cf6209cd3 37 wait_us(TIMING_Tpor);
pclary 0:fb0cf6209cd3 38
pclary 0:fb0cf6209cd3 39 // Put into standby
pclary 0:fb0cf6209cd3 40 _ce = 0;
pclary 0:fb0cf6209cd3 41
pclary 0:fb0cf6209cd3 42 // Configure registers
pclary 0:fb0cf6209cd3 43 setRegister(CONFIG, CONFIG_MASK_TX_DS | CONFIG_MASK_MAX_RT | CONFIG_EN_CRC | CONFIG_PWR_UP | CONFIG_PRIM_RX);
pclary 0:fb0cf6209cd3 44 setRegister(EN_AA, 0x00);
pclary 0:fb0cf6209cd3 45 setRegister(EN_RXADDR, ERX_P0 | ERX_P1);
pclary 0:fb0cf6209cd3 46 setRegister(SETUP_AW, SETUP_AW_3BYTES);
pclary 0:fb0cf6209cd3 47 setRegister(SETUP_RETR, 0x00);
pclary 0:fb0cf6209cd3 48 setRegister(RF_CH, RF_CHANNEL);
pclary 0:fb0cf6209cd3 49 setRegister(RF_SETUP, RF_SETUP_RF_DR_HIGH | RF_SETUP_RF_PWR_0);
pclary 0:fb0cf6209cd3 50 setRegister(STATUS, STATUS_RX_DR | STATUS_TX_DS | STATUS_MAX_RT);
pclary 0:fb0cf6209cd3 51 setRegister(RX_PW_P0, 4);
pclary 0:fb0cf6209cd3 52 setRegister(RX_PW_P1, 4);
pclary 0:fb0cf6209cd3 53 setRegister(DYNPD, 0x00);
pclary 0:fb0cf6209cd3 54 setRegister(FEATURE, 0x00);
pclary 0:fb0cf6209cd3 55
pclary 0:fb0cf6209cd3 56 // Set addresses
pclary 0:fb0cf6209cd3 57 _csn = 0;
pclary 0:fb0cf6209cd3 58 _spi.write(W_REGISTER | RX_ADDR_P0);
pclary 0:fb0cf6209cd3 59 _spi.write(CTRL_BASE_ADDRESS_1 + (controller & 0xf));
pclary 0:fb0cf6209cd3 60 _spi.write(CTRL_BASE_ADDRESS_2);
pclary 0:fb0cf6209cd3 61 _spi.write(CTRL_BASE_ADDRESS_3);
pclary 0:fb0cf6209cd3 62 _csn = 1;
pclary 0:fb0cf6209cd3 63 _csn = 0;
pclary 0:fb0cf6209cd3 64 _spi.write(W_REGISTER | RX_ADDR_P1);
pclary 0:fb0cf6209cd3 65 _spi.write(ROBOT_ADDRESS_1);
pclary 0:fb0cf6209cd3 66 _spi.write(ROBOT_ADDRESS_2);
pclary 0:fb0cf6209cd3 67 _spi.write(ROBOT_ADDRESS_3);
pclary 0:fb0cf6209cd3 68 _csn = 1;
pclary 0:fb0cf6209cd3 69 _csn = 0;
pclary 0:fb0cf6209cd3 70 _spi.write(W_REGISTER | TX_ADDR);
pclary 0:fb0cf6209cd3 71 _spi.write(ROBOT_ADDRESS_1);
pclary 0:fb0cf6209cd3 72 _spi.write(ROBOT_ADDRESS_2);
pclary 0:fb0cf6209cd3 73 _spi.write(ROBOT_ADDRESS_3);
pclary 0:fb0cf6209cd3 74 _csn = 1;
pclary 0:fb0cf6209cd3 75
pclary 0:fb0cf6209cd3 76 // Put into PRX
pclary 0:fb0cf6209cd3 77 _ce = 1;
pclary 0:fb0cf6209cd3 78 wait_us(TIMING_Tstby2a);
pclary 0:fb0cf6209cd3 79
pclary 0:fb0cf6209cd3 80 // Flush FIFOs
pclary 0:fb0cf6209cd3 81 _csn = 0;
pclary 0:fb0cf6209cd3 82 _spi.write(FLUSH_TX);
pclary 0:fb0cf6209cd3 83 _csn = 1;
pclary 0:fb0cf6209cd3 84 _csn = 0;
pclary 0:fb0cf6209cd3 85 _spi.write(FLUSH_RX);
pclary 0:fb0cf6209cd3 86 _csn = 1;
pclary 0:fb0cf6209cd3 87 }
pclary 0:fb0cf6209cd3 88
pclary 0:fb0cf6209cd3 89
pclary 0:fb0cf6209cd3 90
pclary 0:fb0cf6209cd3 91 void Radio::transmit(uint32_t data)
pclary 0:fb0cf6209cd3 92 {
pclary 0:fb0cf6209cd3 93 // Put into standby
pclary 0:fb0cf6209cd3 94 _ce = 0;
pclary 0:fb0cf6209cd3 95
pclary 0:fb0cf6209cd3 96 // Configure for PTX
pclary 0:fb0cf6209cd3 97 int config = getRegister(CONFIG);
pclary 0:fb0cf6209cd3 98 config &= ~CONFIG_PRIM_RX;
pclary 0:fb0cf6209cd3 99 setRegister(CONFIG, config);
pclary 0:fb0cf6209cd3 100
pclary 0:fb0cf6209cd3 101 // Write packet data
pclary 0:fb0cf6209cd3 102 _csn = 0;
pclary 0:fb0cf6209cd3 103 _spi.write(W_TX_PAYLOAD);
pclary 0:fb0cf6209cd3 104 _spi.write( (data>>0) & 0xff );
pclary 0:fb0cf6209cd3 105 _spi.write( (data>>8) & 0xff );
pclary 0:fb0cf6209cd3 106 _spi.write( (data>>16) & 0xff );
pclary 0:fb0cf6209cd3 107 _spi.write( (data>>24) & 0xff );
pclary 0:fb0cf6209cd3 108 _csn = 1;
pclary 0:fb0cf6209cd3 109
pclary 0:fb0cf6209cd3 110 // Put into PTX
pclary 0:fb0cf6209cd3 111 _ce = 1;
pclary 0:fb0cf6209cd3 112 wait_us(TIMING_Tstby2a);
pclary 0:fb0cf6209cd3 113 _ce = 0;
pclary 0:fb0cf6209cd3 114
pclary 0:fb0cf6209cd3 115 // Wait for message transmission and put into PRX
pclary 0:fb0cf6209cd3 116 wait_us(TIMING_Toa);
pclary 0:fb0cf6209cd3 117 config = getRegister(CONFIG);
pclary 0:fb0cf6209cd3 118 config |= CONFIG_PRIM_RX;
pclary 0:fb0cf6209cd3 119 setRegister(CONFIG, config);
pclary 0:fb0cf6209cd3 120 setRegister(STATUS, STATUS_TX_DS);
pclary 0:fb0cf6209cd3 121 _ce = 1;
pclary 0:fb0cf6209cd3 122 }
pclary 0:fb0cf6209cd3 123
pclary 0:fb0cf6209cd3 124
pclary 0:fb0cf6209cd3 125
pclary 0:fb0cf6209cd3 126 void Radio::receive()
pclary 0:fb0cf6209cd3 127 {
pclary 0:fb0cf6209cd3 128 uint32_t data = 0;
pclary 0:fb0cf6209cd3 129 int pipe;
pclary 0:fb0cf6209cd3 130
pclary 0:fb0cf6209cd3 131 // Reset IRQ pin
pclary 0:fb0cf6209cd3 132 setRegister(STATUS, STATUS_RX_DR);
pclary 0:fb0cf6209cd3 133
pclary 0:fb0cf6209cd3 134 // Check data pipe
pclary 0:fb0cf6209cd3 135 wait_us(1000);
pclary 0:fb0cf6209cd3 136 pipe = getStatus() & STATUS_RN_P_MASK;
pclary 0:fb0cf6209cd3 137
pclary 0:fb0cf6209cd3 138 // Read data
pclary 0:fb0cf6209cd3 139 _csn = 0;
pclary 0:fb0cf6209cd3 140 _spi.write(R_RX_PAYLOAD);
pclary 0:fb0cf6209cd3 141 data |= _spi.write(NOP)<<0;
pclary 0:fb0cf6209cd3 142 data |= _spi.write(NOP)<<8;
pclary 0:fb0cf6209cd3 143 data |= _spi.write(NOP)<<16;
pclary 0:fb0cf6209cd3 144 data |= _spi.write(NOP)<<24;
pclary 0:fb0cf6209cd3 145 _csn = 1;
pclary 0:fb0cf6209cd3 146
pclary 0:fb0cf6209cd3 147 // Sort into recieve buffer
pclary 0:fb0cf6209cd3 148 switch(pipe)
pclary 0:fb0cf6209cd3 149 {
pclary 0:fb0cf6209cd3 150 case STATUS_RN_P_NO_P0:
pclary 0:fb0cf6209cd3 151 rx_controller = data;
pclary 0:fb0cf6209cd3 152 break;
pclary 0:fb0cf6209cd3 153
pclary 0:fb0cf6209cd3 154 case STATUS_RN_P_NO_P1:
pclary 0:fb0cf6209cd3 155 rx_robot[rx_robot_pos++ % RX_BUFFER_SIZE] = data;
pclary 0:fb0cf6209cd3 156 break;
pclary 0:fb0cf6209cd3 157
pclary 0:fb0cf6209cd3 158 default:
pclary 0:fb0cf6209cd3 159 break;
pclary 0:fb0cf6209cd3 160 }
pclary 0:fb0cf6209cd3 161 }
pclary 0:fb0cf6209cd3 162
pclary 0:fb0cf6209cd3 163
pclary 0:fb0cf6209cd3 164
pclary 0:fb0cf6209cd3 165 int Radio::getRegister(int address)
pclary 0:fb0cf6209cd3 166 {
pclary 0:fb0cf6209cd3 167 _csn = 0;
pclary 0:fb0cf6209cd3 168 int rc = R_REGISTER | (address & REGISTER_ADDRESS_MASK);
pclary 0:fb0cf6209cd3 169 _spi.write(rc);
pclary 0:fb0cf6209cd3 170 int data = _spi.write(NOP);
pclary 0:fb0cf6209cd3 171 _csn = 1;
pclary 0:fb0cf6209cd3 172 return data;
pclary 0:fb0cf6209cd3 173 }
pclary 0:fb0cf6209cd3 174
pclary 0:fb0cf6209cd3 175
pclary 0:fb0cf6209cd3 176
pclary 0:fb0cf6209cd3 177 int Radio::getStatus()
pclary 0:fb0cf6209cd3 178 {
pclary 0:fb0cf6209cd3 179 _csn = 0;
pclary 0:fb0cf6209cd3 180 int status = _spi.write(NOP);
pclary 0:fb0cf6209cd3 181 _csn = 1;
pclary 0:fb0cf6209cd3 182 return status;
pclary 0:fb0cf6209cd3 183 }
pclary 0:fb0cf6209cd3 184
pclary 0:fb0cf6209cd3 185
pclary 0:fb0cf6209cd3 186 void Radio::setRegister(int address, int data)
pclary 0:fb0cf6209cd3 187 {
pclary 0:fb0cf6209cd3 188 bool enabled = false;
pclary 0:fb0cf6209cd3 189 if (_ce == 1)
pclary 0:fb0cf6209cd3 190 {
pclary 0:fb0cf6209cd3 191 enabled = true;
pclary 0:fb0cf6209cd3 192 _ce = 0;
pclary 0:fb0cf6209cd3 193 }
pclary 0:fb0cf6209cd3 194
pclary 0:fb0cf6209cd3 195 _csn = 0;
pclary 0:fb0cf6209cd3 196 int rc = W_REGISTER | (address & REGISTER_ADDRESS_MASK);
pclary 0:fb0cf6209cd3 197 _spi.write(rc);
pclary 0:fb0cf6209cd3 198 _spi.write(data & 0xff);
pclary 0:fb0cf6209cd3 199 _csn = 1;
pclary 0:fb0cf6209cd3 200
pclary 0:fb0cf6209cd3 201 if (enabled)
pclary 0:fb0cf6209cd3 202 {
pclary 0:fb0cf6209cd3 203 _ce = 1;
pclary 0:fb0cf6209cd3 204 wait_us(TIMING_Tpece2csn);
pclary 0:fb0cf6209cd3 205 }
pclary 0:fb0cf6209cd3 206
pclary 0:fb0cf6209cd3 207 }