nRF24L01 driver

Dependents:   Nucleo_IOT1 wireless

Committer:
ianmcc
Date:
Sun Aug 11 11:58:05 2013 +0000
Revision:
0:7313e63394c3
Child:
4:8f612189af31
Initial

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 0:7313e63394c3 123 }
ianmcc 0:7313e63394c3 124 int OldStatus = Status;
ianmcc 0:7313e63394c3 125 if (OldStatus == STATUS_PACKET_OK)
ianmcc 0:7313e63394c3 126 {
ianmcc 0:7313e63394c3 127 Status = STATUS_STANDBY;
ianmcc 0:7313e63394c3 128 return 0;
ianmcc 0:7313e63394c3 129 }
ianmcc 0:7313e63394c3 130 else if (OldStatus == STATUS_PACKET_MAX_RT)
ianmcc 0:7313e63394c3 131 {
ianmcc 0:7313e63394c3 132 Status = STATUS_STANDBY;
ianmcc 0:7313e63394c3 133 return -1;
ianmcc 0:7313e63394c3 134 }
ianmcc 0:7313e63394c3 135 // else the Status isn't what we expected, which
ianmcc 0:7313e63394c3 136 // shouldn't happen in blocking mode. Some interrupt must have
ianmcc 0:7313e63394c3 137 // reset Status. Bug out with an error.
ianmcc 0:7313e63394c3 138 return -1;
ianmcc 0:7313e63394c3 139 }
ianmcc 0:7313e63394c3 140
ianmcc 0:7313e63394c3 141 void
ianmcc 0:7313e63394c3 142 nRF24L01P_PTX::IntHandler()
ianmcc 0:7313e63394c3 143 {
ianmcc 0:7313e63394c3 144 if (Device.is_tx_sent())
ianmcc 0:7313e63394c3 145 {
ianmcc 0:7313e63394c3 146 // we successfully sent a packet
ianmcc 0:7313e63394c3 147 Status = STATUS_PACKET_OK;
ianmcc 0:7313e63394c3 148 Device.clear_tx_sent();
ianmcc 0:7313e63394c3 149 }
ianmcc 0:7313e63394c3 150 else if (Device.is_max_rt())
ianmcc 0:7313e63394c3 151 {
ianmcc 0:7313e63394c3 152 // we failed to send the packet
ianmcc 0:7313e63394c3 153 Status = STATUS_PACKET_MAX_RT;
ianmcc 0:7313e63394c3 154 Device.clear_max_rt();
ianmcc 0:7313e63394c3 155 }
ianmcc 0:7313e63394c3 156 }
ianmcc 0:7313e63394c3 157
ianmcc 0:7313e63394c3 158 void
ianmcc 0:7313e63394c3 159 nRF24L01P_PTX::ReadyInitialize()
ianmcc 0:7313e63394c3 160 {
ianmcc 0:7313e63394c3 161 Status = STATUS_READY_INIT;
ianmcc 0:7313e63394c3 162 }
ianmcc 0:7313e63394c3 163
ianmcc 0:7313e63394c3 164 void
ianmcc 0:7313e63394c3 165 nRF24L01P_PTX::ReadyStandby()
ianmcc 0:7313e63394c3 166 {
ianmcc 0:7313e63394c3 167 if (Status == STATUS_STARTUP_STANDBY)
ianmcc 0:7313e63394c3 168 Status = STATUS_STANDBY;
ianmcc 0:7313e63394c3 169 }