nRF24L01 driver

Dependents:   Nucleo_IOT1 wireless

Committer:
ianmcc
Date:
Sat Sep 03 12:24:04 2016 +0000
Revision:
4:8f612189af31
Parent:
0:7313e63394c3
Child:
5:bb28775120e7
Fix handling of blocking transmit, no need to use the interrupt handler

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 0:7313e63394c3 38 Int.fall(this, &nRF24L01P_PTX::IntHandler);
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 0:7313e63394c3 109 // Wait until the device is ready to transmit
ianmcc 0:7313e63394c3 110 while (Status != STATUS_STANDBY)
ianmcc 0:7313e63394c3 111 {
ianmcc 0:7313e63394c3 112 wait_us(1);
ianmcc 0:7313e63394c3 113 }
ianmcc 0:7313e63394c3 114 Device.write_tx_payload(Buf, Size);
ianmcc 0:7313e63394c3 115 Status = STATUS_TRANSMITTING;
ianmcc 0:7313e63394c3 116 CE = 1;
ianmcc 0:7313e63394c3 117 wait_us(Thce_us);
ianmcc 0:7313e63394c3 118 CE = 0;
ianmcc 0:7313e63394c3 119 // wait until the packet is transmitted (or some error)
ianmcc 0:7313e63394c3 120 while (Status == STATUS_TRANSMITTING)
ianmcc 0:7313e63394c3 121 {
ianmcc 0:7313e63394c3 122 wait_us(1);
ianmcc 4:8f612189af31 123 if (Device.is_tx_sent())
ianmcc 4:8f612189af31 124 {
ianmcc 4:8f612189af31 125 // we successfully sent a packet
ianmcc 4:8f612189af31 126 Status = STATUS_PACKET_OK;
ianmcc 4:8f612189af31 127 Device.clear_tx_sent();
ianmcc 4:8f612189af31 128 }
ianmcc 4:8f612189af31 129 else if (Device.is_max_rt())
ianmcc 4:8f612189af31 130 {
ianmcc 4:8f612189af31 131 // we failed to send the packet
ianmcc 4:8f612189af31 132 Status = STATUS_PACKET_MAX_RT;
ianmcc 4:8f612189af31 133 Device.clear_max_rt();
ianmcc 4:8f612189af31 134 }
ianmcc 0:7313e63394c3 135 }
ianmcc 4:8f612189af31 136
ianmcc 4:8f612189af31 137 if (Status == STATUS_PACKET_OK)
ianmcc 0:7313e63394c3 138 {
ianmcc 0:7313e63394c3 139 Status = STATUS_STANDBY;
ianmcc 0:7313e63394c3 140 return 0;
ianmcc 0:7313e63394c3 141 }
ianmcc 4:8f612189af31 142 else if (Status == STATUS_PACKET_MAX_RT)
ianmcc 0:7313e63394c3 143 {
ianmcc 0:7313e63394c3 144 Status = STATUS_STANDBY;
ianmcc 4:8f612189af31 145 Device.flush_tx_fifo();
ianmcc 0:7313e63394c3 146 return -1;
ianmcc 0:7313e63394c3 147 }
ianmcc 0:7313e63394c3 148 // else the Status isn't what we expected, which
ianmcc 0:7313e63394c3 149 // shouldn't happen in blocking mode. Some interrupt must have
ianmcc 0:7313e63394c3 150 // reset Status. Bug out with an error.
ianmcc 0:7313e63394c3 151 return -1;
ianmcc 0:7313e63394c3 152 }
ianmcc 0:7313e63394c3 153
ianmcc 0:7313e63394c3 154 void
ianmcc 0:7313e63394c3 155 nRF24L01P_PTX::IntHandler()
ianmcc 0:7313e63394c3 156 {
ianmcc 0:7313e63394c3 157 }
ianmcc 0:7313e63394c3 158
ianmcc 0:7313e63394c3 159 void
ianmcc 0:7313e63394c3 160 nRF24L01P_PTX::ReadyInitialize()
ianmcc 0:7313e63394c3 161 {
ianmcc 0:7313e63394c3 162 Status = STATUS_READY_INIT;
ianmcc 0:7313e63394c3 163 }
ianmcc 0:7313e63394c3 164
ianmcc 0:7313e63394c3 165 void
ianmcc 0:7313e63394c3 166 nRF24L01P_PTX::ReadyStandby()
ianmcc 0:7313e63394c3 167 {
ianmcc 0:7313e63394c3 168 if (Status == STATUS_STARTUP_STANDBY)
ianmcc 0:7313e63394c3 169 Status = STATUS_STANDBY;
ianmcc 0:7313e63394c3 170 }