nRF24L01 driver

Dependents:   Nucleo_IOT1 wireless

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;
+}