nRF24L01 driver
Dependents: Nucleo_IOT1 wireless
Diff: nRF24L01P_PTX.cpp
- Revision:
- 0:7313e63394c3
- Child:
- 4:8f612189af31
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nRF24L01P_PTX.cpp Sun Aug 11 11:58:05 2013 +0000 @@ -0,0 +1,169 @@ + +#include "nRF24L01P_PTX.h" + +// status +#define STATUS_UNDEFINED 0 +#define STATUS_READY_INIT 1 +#define STATUS_POWER_DOWN 2 +#define STATUS_STARTUP_STANDBY 3 +#define STATUS_STANDBY 4 +#define STATUS_TRANSMITTING 5 +#define STATUS_PACKET_OK 6 +#define STATUS_PACKET_MAX_RT 7 + +nRF24L01P_PTX::nRF24L01P_PTX(nRF24L01P& Device_, PinName CE_, PinName Int_) + : Device(Device_), + CE(CE_), + Int(Int_) +{ + CE = 0; + Status = STATUS_UNDEFINED; + Int.mode(PullNone); + Int.fall(NULL); + InitializeTimer.attach_us(this, &nRF24L01P_PTX::ReadyInitialize, Tundef2pd_us); +} + +void +nRF24L01P_PTX::Initialize() +{ + while (Status == STATUS_UNDEFINED) + { + wait_us(1); + } + PowerOnTimer.detach(); + CE = 0; + Device.reset(); + Device.set_ptx_mode(); + Status = STATUS_POWER_DOWN; + Int.fall(this, &nRF24L01P_PTX::IntHandler); +} + +void +nRF24L01P_PTX::SetChannel(int Channel) +{ + Device.set_channel(Channel); +} + +void +nRF24L01P_PTX::SetDataRate(int Rate) +{ + Device.set_air_data_rate(Rate); +} + +void +nRF24L01P_PTX::SetTransmitPower(int Power) +{ + Device.set_tx_power(Power); +} + +void +nRF24L01P_PTX::SetDestinationAddress(uint64_t Address) +{ + Device.set_tx_address(Address); +} + +void +nRF24L01P_PTX::PowerUp() +{ + if (Status != STATUS_POWER_DOWN) + { + error("nRF24L01P_PTX::PowerUp(): can only be called when device is powered down"); + } + Status = STATUS_STARTUP_STANDBY; + Device.set_power_up(); + PowerOnTimer.attach_us(this, &nRF24L01P_PTX::ReadyStandby, Tpd2stby_us); +} + +void +nRF24L01P_PTX::PowerDown() +{ + if (Status == STATUS_UNDEFINED || Status == STATUS_READY_INIT) + { + error("nRF24L01P_PTX::PowerDown(): error: device is not initialized!"); + } + // Although it is technically possible to turn the power off at any time, + // if we're currently processing a packet, wait until we've finished + while (Status == STATUS_TRANSMITTING || Status == STATUS_PACKET_OK || Status == STATUS_PACKET_MAX_RT) + { + wait_us(1); + } + PowerOnTimer.detach(); + Device.set_power_down(); + Status = STATUS_POWER_DOWN; +} + +bool +nRF24L01P_PTX::IsReadyTransmit() +{ + return (Status == STATUS_STANDBY); +} + +int +nRF24L01P_PTX::TransmitPacket(char* Buf, int Size) +{ + // If the device isn't powered up then there is a logic error + if (Status == STATUS_UNDEFINED || Status == STATUS_READY_INIT || Status == STATUS_POWER_DOWN) + { + error("nRF24L01P_PTX::TransmitPacket(): error: device power must be on!"); + } + // Wait until the device is ready to transmit + while (Status != STATUS_STANDBY) + { + wait_us(1); + } + Device.write_tx_payload(Buf, Size); + Status = STATUS_TRANSMITTING; + CE = 1; + wait_us(Thce_us); + CE = 0; + // wait until the packet is transmitted (or some error) + while (Status == STATUS_TRANSMITTING) + { + wait_us(1); + } + int OldStatus = Status; + if (OldStatus == STATUS_PACKET_OK) + { + Status = STATUS_STANDBY; + return 0; + } + else if (OldStatus == STATUS_PACKET_MAX_RT) + { + Status = STATUS_STANDBY; + return -1; + } + // else the Status isn't what we expected, which + // shouldn't happen in blocking mode. Some interrupt must have + // reset Status. Bug out with an error. + return -1; +} + +void +nRF24L01P_PTX::IntHandler() +{ + if (Device.is_tx_sent()) + { + // we successfully sent a packet + Status = STATUS_PACKET_OK; + Device.clear_tx_sent(); + } + else if (Device.is_max_rt()) + { + // we failed to send the packet + Status = STATUS_PACKET_MAX_RT; + Device.clear_max_rt(); + } +} + +void +nRF24L01P_PTX::ReadyInitialize() +{ + Status = STATUS_READY_INIT; +} + +void +nRF24L01P_PTX::ReadyStandby() +{ + if (Status == STATUS_STARTUP_STANDBY) + Status = STATUS_STANDBY; +}