nRF24L01 driver

Dependents:   Nucleo_IOT1 wireless

Committer:
ianmcc
Date:
Wed Sep 14 14:43:13 2016 +0000
Revision:
6:952996e3abdb
Parent:
5:bb28775120e7
bug fixes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ianmcc 0:7313e63394c3 1
ianmcc 0:7313e63394c3 2 #include "nRF24L01P_PTX.h"
ianmcc 0:7313e63394c3 3
ianmcc 0:7313e63394c3 4 // status
ianmcc 0:7313e63394c3 5 #define STATUS_UNDEFINED 0
ianmcc 0:7313e63394c3 6 #define STATUS_READY_INIT 1
ianmcc 0:7313e63394c3 7 #define STATUS_POWER_DOWN 2
ianmcc 0:7313e63394c3 8 #define STATUS_STARTUP_STANDBY 3
ianmcc 0:7313e63394c3 9 #define STATUS_STANDBY 4
ianmcc 0:7313e63394c3 10 #define STATUS_TRANSMITTING 5
ianmcc 0:7313e63394c3 11 #define STATUS_PACKET_OK 6
ianmcc 0:7313e63394c3 12 #define STATUS_PACKET_MAX_RT 7
ianmcc 0:7313e63394c3 13
ianmcc 0:7313e63394c3 14 nRF24L01P_PTX::nRF24L01P_PTX(nRF24L01P& Device_, PinName CE_, PinName Int_)
ianmcc 0:7313e63394c3 15 : Device(Device_),
ianmcc 0:7313e63394c3 16 CE(CE_),
ianmcc 0:7313e63394c3 17 Int(Int_)
ianmcc 0:7313e63394c3 18 {
ianmcc 0:7313e63394c3 19 CE = 0;
ianmcc 0:7313e63394c3 20 Status = STATUS_UNDEFINED;
ianmcc 0:7313e63394c3 21 Int.mode(PullNone);
ianmcc 0:7313e63394c3 22 Int.fall(NULL);
ianmcc 0:7313e63394c3 23 InitializeTimer.attach_us(this, &nRF24L01P_PTX::ReadyInitialize, Tundef2pd_us);
ianmcc 0:7313e63394c3 24 }
ianmcc 0:7313e63394c3 25
ianmcc 0:7313e63394c3 26 void
ianmcc 0:7313e63394c3 27 nRF24L01P_PTX::Initialize()
ianmcc 0:7313e63394c3 28 {
ianmcc 0:7313e63394c3 29 while (Status == STATUS_UNDEFINED)
ianmcc 0:7313e63394c3 30 {
ianmcc 0:7313e63394c3 31 wait_us(1);
ianmcc 0:7313e63394c3 32 }
ianmcc 0:7313e63394c3 33 PowerOnTimer.detach();
ianmcc 0:7313e63394c3 34 CE = 0;
ianmcc 0:7313e63394c3 35 Device.reset();
ianmcc 0:7313e63394c3 36 Device.set_ptx_mode();
ianmcc 0:7313e63394c3 37 Status = STATUS_POWER_DOWN;
ianmcc 5:bb28775120e7 38 Int.fall(NULL);
ianmcc 0:7313e63394c3 39 }
ianmcc 0:7313e63394c3 40
ianmcc 0:7313e63394c3 41 void
ianmcc 0:7313e63394c3 42 nRF24L01P_PTX::SetChannel(int Channel)
ianmcc 0:7313e63394c3 43 {
ianmcc 0:7313e63394c3 44 Device.set_channel(Channel);
ianmcc 0:7313e63394c3 45 }
ianmcc 0:7313e63394c3 46
ianmcc 0:7313e63394c3 47 void
ianmcc 0:7313e63394c3 48 nRF24L01P_PTX::SetDataRate(int Rate)
ianmcc 0:7313e63394c3 49 {
ianmcc 0:7313e63394c3 50 Device.set_air_data_rate(Rate);
ianmcc 0:7313e63394c3 51 }
ianmcc 0:7313e63394c3 52
ianmcc 0:7313e63394c3 53 void
ianmcc 0:7313e63394c3 54 nRF24L01P_PTX::SetTransmitPower(int Power)
ianmcc 0:7313e63394c3 55 {
ianmcc 0:7313e63394c3 56 Device.set_tx_power(Power);
ianmcc 0:7313e63394c3 57 }
ianmcc 0:7313e63394c3 58
ianmcc 0:7313e63394c3 59 void
ianmcc 0:7313e63394c3 60 nRF24L01P_PTX::SetDestinationAddress(uint64_t Address)
ianmcc 0:7313e63394c3 61 {
ianmcc 0:7313e63394c3 62 Device.set_tx_address(Address);
ianmcc 0:7313e63394c3 63 }
ianmcc 0:7313e63394c3 64
ianmcc 0:7313e63394c3 65 void
ianmcc 0:7313e63394c3 66 nRF24L01P_PTX::PowerUp()
ianmcc 0:7313e63394c3 67 {
ianmcc 0:7313e63394c3 68 if (Status != STATUS_POWER_DOWN)
ianmcc 0:7313e63394c3 69 {
ianmcc 0:7313e63394c3 70 error("nRF24L01P_PTX::PowerUp(): can only be called when device is powered down");
ianmcc 0:7313e63394c3 71 }
ianmcc 0:7313e63394c3 72 Status = STATUS_STARTUP_STANDBY;
ianmcc 0:7313e63394c3 73 Device.set_power_up();
ianmcc 0:7313e63394c3 74 PowerOnTimer.attach_us(this, &nRF24L01P_PTX::ReadyStandby, Tpd2stby_us);
ianmcc 0:7313e63394c3 75 }
ianmcc 0:7313e63394c3 76
ianmcc 0:7313e63394c3 77 void
ianmcc 0:7313e63394c3 78 nRF24L01P_PTX::PowerDown()
ianmcc 0:7313e63394c3 79 {
ianmcc 0:7313e63394c3 80 if (Status == STATUS_UNDEFINED || Status == STATUS_READY_INIT)
ianmcc 0:7313e63394c3 81 {
ianmcc 0:7313e63394c3 82 error("nRF24L01P_PTX::PowerDown(): error: device is not initialized!");
ianmcc 0:7313e63394c3 83 }
ianmcc 0:7313e63394c3 84 // Although it is technically possible to turn the power off at any time,
ianmcc 0:7313e63394c3 85 // if we're currently processing a packet, wait until we've finished
ianmcc 0:7313e63394c3 86 while (Status == STATUS_TRANSMITTING || Status == STATUS_PACKET_OK || Status == STATUS_PACKET_MAX_RT)
ianmcc 0:7313e63394c3 87 {
ianmcc 0:7313e63394c3 88 wait_us(1);
ianmcc 0:7313e63394c3 89 }
ianmcc 0:7313e63394c3 90 PowerOnTimer.detach();
ianmcc 0:7313e63394c3 91 Device.set_power_down();
ianmcc 0:7313e63394c3 92 Status = STATUS_POWER_DOWN;
ianmcc 0:7313e63394c3 93 }
ianmcc 0:7313e63394c3 94
ianmcc 0:7313e63394c3 95 bool
ianmcc 0:7313e63394c3 96 nRF24L01P_PTX::IsReadyTransmit()
ianmcc 0:7313e63394c3 97 {
ianmcc 0:7313e63394c3 98 return (Status == STATUS_STANDBY);
ianmcc 0:7313e63394c3 99 }
ianmcc 0:7313e63394c3 100
ianmcc 0:7313e63394c3 101 int
ianmcc 0:7313e63394c3 102 nRF24L01P_PTX::TransmitPacket(char* Buf, int Size)
ianmcc 0:7313e63394c3 103 {
ianmcc 0:7313e63394c3 104 // If the device isn't powered up then there is a logic error
ianmcc 0:7313e63394c3 105 if (Status == STATUS_UNDEFINED || Status == STATUS_READY_INIT || Status == STATUS_POWER_DOWN)
ianmcc 0:7313e63394c3 106 {
ianmcc 0:7313e63394c3 107 error("nRF24L01P_PTX::TransmitPacket(): error: device power must be on!");
ianmcc 0:7313e63394c3 108 }
ianmcc 5:bb28775120e7 109
ianmcc 5:bb28775120e7 110 // if we're not ready to send, then bug out
ianmcc 5:bb28775120e7 111 if (Status != STATUS_STANDBY)
ianmcc 0:7313e63394c3 112 {
ianmcc 5:bb28775120e7 113 return -1;
ianmcc 0:7313e63394c3 114 }
ianmcc 5:bb28775120e7 115
ianmcc 0:7313e63394c3 116 Device.write_tx_payload(Buf, Size);
ianmcc 0:7313e63394c3 117 Status = STATUS_TRANSMITTING;
ianmcc 0:7313e63394c3 118 CE = 1;
ianmcc 0:7313e63394c3 119 wait_us(Thce_us);
ianmcc 6:952996e3abdb 120 //CE = 0;
ianmcc 0:7313e63394c3 121 // wait until the packet is transmitted (or some error)
ianmcc 0:7313e63394c3 122 while (Status == STATUS_TRANSMITTING)
ianmcc 0:7313e63394c3 123 {
ianmcc 0:7313e63394c3 124 wait_us(1);
ianmcc 4:8f612189af31 125 if (Device.is_tx_sent())
ianmcc 4:8f612189af31 126 {
ianmcc 4:8f612189af31 127 // we successfully sent a packet
ianmcc 4:8f612189af31 128 Status = STATUS_PACKET_OK;
ianmcc 4:8f612189af31 129 Device.clear_tx_sent();
ianmcc 4:8f612189af31 130 }
ianmcc 4:8f612189af31 131 else if (Device.is_max_rt())
ianmcc 4:8f612189af31 132 {
ianmcc 4:8f612189af31 133 // we failed to send the packet
ianmcc 4:8f612189af31 134 Status = STATUS_PACKET_MAX_RT;
ianmcc 4:8f612189af31 135 Device.clear_max_rt();
ianmcc 4:8f612189af31 136 }
ianmcc 0:7313e63394c3 137 }
ianmcc 6:952996e3abdb 138 CE=0;
ianmcc 4:8f612189af31 139 if (Status == STATUS_PACKET_OK)
ianmcc 0:7313e63394c3 140 {
ianmcc 0:7313e63394c3 141 Status = STATUS_STANDBY;
ianmcc 0:7313e63394c3 142 return 0;
ianmcc 0:7313e63394c3 143 }
ianmcc 4:8f612189af31 144 else if (Status == STATUS_PACKET_MAX_RT)
ianmcc 0:7313e63394c3 145 {
ianmcc 0:7313e63394c3 146 Status = STATUS_STANDBY;
ianmcc 4:8f612189af31 147 Device.flush_tx_fifo();
ianmcc 0:7313e63394c3 148 return -1;
ianmcc 0:7313e63394c3 149 }
ianmcc 0:7313e63394c3 150 // else the Status isn't what we expected, which
ianmcc 0:7313e63394c3 151 // shouldn't happen in blocking mode. Some interrupt must have
ianmcc 0:7313e63394c3 152 // reset Status. Bug out with an error.
ianmcc 0:7313e63394c3 153 return -1;
ianmcc 0:7313e63394c3 154 }
ianmcc 0:7313e63394c3 155
ianmcc 5:bb28775120e7 156 int
ianmcc 5:bb28775120e7 157 nRF24L01P_PTX::TransmitPacketNonBlocking(char* Buf, int Size)
ianmcc 5:bb28775120e7 158 {
ianmcc 5:bb28775120e7 159 // If the device isn't powered up then there is a logic error
ianmcc 5:bb28775120e7 160 if (Status == STATUS_UNDEFINED || Status == STATUS_READY_INIT || Status == STATUS_POWER_DOWN)
ianmcc 5:bb28775120e7 161 {
ianmcc 5:bb28775120e7 162 error("nRF24L01P_PTX::TransmitPacketNonBlocking(): error: device power must be on!");
ianmcc 5:bb28775120e7 163 }
ianmcc 5:bb28775120e7 164
ianmcc 5:bb28775120e7 165 // if we're not ready to send, then bug out
ianmcc 5:bb28775120e7 166 if (Status != STATUS_STANDBY)
ianmcc 5:bb28775120e7 167 {
ianmcc 5:bb28775120e7 168 return -1;
ianmcc 5:bb28775120e7 169 }
ianmcc 5:bb28775120e7 170
ianmcc 5:bb28775120e7 171 // Set up the interrupt handler
ianmcc 5:bb28775120e7 172 Int.fall(this, &nRF24L01P_PTX::IntHandler);
ianmcc 5:bb28775120e7 173
ianmcc 5:bb28775120e7 174 // write the payload
ianmcc 5:bb28775120e7 175 Device.write_tx_payload(Buf, Size);
ianmcc 5:bb28775120e7 176 Status = STATUS_TRANSMITTING;
ianmcc 5:bb28775120e7 177 CE = 1;
ianmcc 5:bb28775120e7 178 wait_us(Thce_us);
ianmcc 5:bb28775120e7 179 CE = 0;
ianmcc 5:bb28775120e7 180
ianmcc 5:bb28775120e7 181 return 0;
ianmcc 5:bb28775120e7 182 }
ianmcc 5:bb28775120e7 183
ianmcc 5:bb28775120e7 184 bool
ianmcc 5:bb28775120e7 185 nRF24L01P_PTX::IsTransmitFinished()
ianmcc 5:bb28775120e7 186 {
ianmcc 5:bb28775120e7 187 return Status != STATUS_TRANSMITTING;
ianmcc 5:bb28775120e7 188 }
ianmcc 5:bb28775120e7 189
ianmcc 5:bb28775120e7 190 int
ianmcc 5:bb28775120e7 191 nRF24L01P_PTX::TransmitComplete()
ianmcc 5:bb28775120e7 192 {
ianmcc 5:bb28775120e7 193 // wait until the packet is transmitted (or some error)
ianmcc 5:bb28775120e7 194 while (Status == STATUS_TRANSMITTING)
ianmcc 5:bb28775120e7 195 {
ianmcc 5:bb28775120e7 196 wait_us(1);
ianmcc 5:bb28775120e7 197 }
ianmcc 5:bb28775120e7 198
ianmcc 5:bb28775120e7 199 if (Status == STATUS_PACKET_OK)
ianmcc 5:bb28775120e7 200 {
ianmcc 5:bb28775120e7 201 Status = STATUS_STANDBY;
ianmcc 5:bb28775120e7 202 return 0;
ianmcc 5:bb28775120e7 203 }
ianmcc 5:bb28775120e7 204 else if (Status == STATUS_PACKET_MAX_RT)
ianmcc 5:bb28775120e7 205 {
ianmcc 5:bb28775120e7 206 Status = STATUS_STANDBY;
ianmcc 5:bb28775120e7 207 Device.flush_tx_fifo();
ianmcc 5:bb28775120e7 208 return -1;
ianmcc 5:bb28775120e7 209 }
ianmcc 5:bb28775120e7 210 // this shouldn't happen
ianmcc 5:bb28775120e7 211 return -2;
ianmcc 5:bb28775120e7 212 }
ianmcc 5:bb28775120e7 213
ianmcc 0:7313e63394c3 214 void
ianmcc 0:7313e63394c3 215 nRF24L01P_PTX::IntHandler()
ianmcc 0:7313e63394c3 216 {
ianmcc 5:bb28775120e7 217 Int.fall(NULL);
ianmcc 5:bb28775120e7 218 if (Device.is_tx_sent())
ianmcc 5:bb28775120e7 219 {
ianmcc 5:bb28775120e7 220 // we successfully sent a packet
ianmcc 5:bb28775120e7 221 Status = STATUS_PACKET_OK;
ianmcc 5:bb28775120e7 222 Device.clear_tx_sent();
ianmcc 5:bb28775120e7 223 }
ianmcc 5:bb28775120e7 224 else if (Device.is_max_rt())
ianmcc 5:bb28775120e7 225 {
ianmcc 5:bb28775120e7 226 // we failed to send the packet
ianmcc 5:bb28775120e7 227 Status = STATUS_PACKET_MAX_RT;
ianmcc 5:bb28775120e7 228 Device.clear_max_rt();
ianmcc 5:bb28775120e7 229 }
ianmcc 0:7313e63394c3 230 }
ianmcc 0:7313e63394c3 231
ianmcc 0:7313e63394c3 232 void
ianmcc 0:7313e63394c3 233 nRF24L01P_PTX::ReadyInitialize()
ianmcc 0:7313e63394c3 234 {
ianmcc 0:7313e63394c3 235 Status = STATUS_READY_INIT;
ianmcc 0:7313e63394c3 236 }
ianmcc 0:7313e63394c3 237
ianmcc 0:7313e63394c3 238 void
ianmcc 0:7313e63394c3 239 nRF24L01P_PTX::ReadyStandby()
ianmcc 0:7313e63394c3 240 {
ianmcc 0:7313e63394c3 241 if (Status == STATUS_STARTUP_STANDBY)
ianmcc 0:7313e63394c3 242 Status = STATUS_STANDBY;
ianmcc 0:7313e63394c3 243 }