Bladeren bron

Change flash settings to 3MB/1MB. Refactor to use radio factory

Chris Mullins 8 jaren geleden
bovenliggende
commit
d387f9abcc

+ 0 - 36
lib/MiLight/AbstractPL1167.h

@@ -1,36 +0,0 @@
-/*
- * AbstractPL1167.h
- *
- *  Created on: 29 May 2015
- *      Author: henryk
- */
-
-#ifdef ARDUINO
-#include "Arduino.h"
-#else
-#include <stdint.h>
-#include <stdlib.h>
-#endif
-
-#ifndef ABSTRACTPL1167_H_
-#define ABSTRACTPL1167_H_
-
-class AbstractPL1167 {
-  public:
-    virtual int open() = 0;
-
-    virtual int setPreambleLength(uint8_t preambleLength) = 0;
-    virtual int setSyncword(uint16_t syncword0, uint16_t syncword3) = 0;
-    virtual int setTrailerLength(uint8_t trailerLength) = 0;
-    virtual int setMaxPacketLength(uint8_t maxPacketLength) = 0;
-    virtual int setCRC(bool crc) = 0;
-    virtual int writeFIFO(const uint8_t data[], size_t data_length) = 0;
-    virtual int transmit(uint8_t channel) = 0;
-    virtual int receive(uint8_t channel) = 0;
-    virtual int readFIFO(uint8_t data[], size_t &data_length) = 0;
-};
-
-
-
-
-#endif /* ABSTRACTPL1167_H_ */

+ 34 - 31
lib/MiLight/MiLightRadioPL1197_LT8900.cpp

@@ -9,16 +9,15 @@
  *  https://bitbucket.org/robvanderveer/lt8900lib
  */
 
-#include "MiLightRadioPL1167_LT8900.h"
+#include "LT8900MiLightRadio.h"
 #include <SPI.h>
 
-#define DEBUG_PRINTF
-
 /**************************************************************************/
 // Constructor
 /**************************************************************************/
-MiLightRadioPL1167_LT8900::MiLightRadioPL1167_LT8900(byte byCSPin, byte byResetPin, byte byPktFlag, const MiLightRadioConfig& config)
-  :  config(config)
+LT8900MiLightRadio::LT8900MiLightRadio(byte byCSPin, byte byResetPin, byte byPktFlag, const MiLightRadioConfig& config)
+  : _config(config),
+    _channel(0)
 {
   _csPin = byCSPin;
 	_pin_pktflag = byPktFlag;
@@ -63,7 +62,7 @@ MiLightRadioPL1167_LT8900::MiLightRadioPL1167_LT8900(byte byCSPin, byte byResetP
 /**************************************************************************/
 // Checks the connection to the radio module by verifying a register setting
 /**************************************************************************/
-bool MiLightRadioPL1167_LT8900::bCheckRadioConnection(void)
+bool LT8900MiLightRadio::bCheckRadioConnection(void)
 {
 	int iRetValue = 0;
 	uint16_t value_0 = uiReadRegister(0);
@@ -89,7 +88,7 @@ bool MiLightRadioPL1167_LT8900::bCheckRadioConnection(void)
 /**************************************************************************/
 // Initialize radio module
 /**************************************************************************/
-void MiLightRadioPL1167_LT8900::vInitRadioModule(MiLightRadioType type)
+void LT8900MiLightRadio::vInitRadioModule(MiLightRadioType type)
 {
 	if (type == RGB_CCT)
 	{
@@ -201,7 +200,7 @@ void MiLightRadioPL1167_LT8900::vInitRadioModule(MiLightRadioType type)
 /**************************************************************************/
 // Set sync word
 /**************************************************************************/
-void MiLightRadioPL1167_LT8900::vSetSyncWord(uint16_t syncWord3, uint16_t syncWord2, uint16_t syncWord1, uint16_t syncWord0)
+void LT8900MiLightRadio::vSetSyncWord(uint16_t syncWord3, uint16_t syncWord2, uint16_t syncWord1, uint16_t syncWord0)
 {
 	uiWriteRegister(R_SYNCWORD1, syncWord0);
 	uiWriteRegister(R_SYNCWORD2, syncWord1);
@@ -212,7 +211,7 @@ void MiLightRadioPL1167_LT8900::vSetSyncWord(uint16_t syncWord3, uint16_t syncWo
 /**************************************************************************/
 // Low level register write with delay
 /**************************************************************************/
-void MiLightRadioPL1167_LT8900::regWrite16(byte ADDR, byte V1, byte V2, byte WAIT)
+void LT8900MiLightRadio::regWrite16(byte ADDR, byte V1, byte V2, byte WAIT)
 {
 	digitalWrite(_csPin, LOW);
 	SPI.transfer(ADDR);
@@ -226,7 +225,7 @@ void MiLightRadioPL1167_LT8900::regWrite16(byte ADDR, byte V1, byte V2, byte WAI
 /**************************************************************************/
 // Low level register read
 /**************************************************************************/
-uint16_t MiLightRadioPL1167_LT8900::uiReadRegister(uint8_t reg)
+uint16_t LT8900MiLightRadio::uiReadRegister(uint8_t reg)
 {
 	SPI.setDataMode(SPI_MODE1);
 	digitalWrite(_csPin, LOW);
@@ -244,7 +243,7 @@ uint16_t MiLightRadioPL1167_LT8900::uiReadRegister(uint8_t reg)
 /**************************************************************************/
 // Low level 16bit register write
 /**************************************************************************/
-uint8_t MiLightRadioPL1167_LT8900::uiWriteRegister(uint8_t reg, uint16_t data)
+uint8_t LT8900MiLightRadio::uiWriteRegister(uint8_t reg, uint16_t data)
 {
 	uint8_t high = data >> 8;
 	uint8_t low = data & 0xFF;
@@ -263,10 +262,10 @@ uint8_t MiLightRadioPL1167_LT8900::uiWriteRegister(uint8_t reg, uint16_t data)
 /**************************************************************************/
 // Start listening on specified channel and syncword
 /**************************************************************************/
-void MiLightRadioPL1167_LT8900::vStartListening(uint uiChannelToListenTo)
+void LT8900MiLightRadio::vStartListening(uint uiChannelToListenTo)
 {
   _dupes_received = 0;
-  vSetSyncWord(config.syncword3, 0,0,config.syncword0);
+  vSetSyncWord(_config.syncword3, 0,0,_config.syncword0);
 	//vSetChannel(uiChannelToListenTo);
 
   _channel = uiChannelToListenTo;
@@ -281,7 +280,7 @@ void MiLightRadioPL1167_LT8900::vStartListening(uint uiChannelToListenTo)
 /**************************************************************************/
 // Resume listening - without changing the channel and syncword
 /**************************************************************************/
-void MiLightRadioPL1167_LT8900::vResumeRX(void)
+void LT8900MiLightRadio::vResumeRX(void)
 {
   _dupes_received = 0;
 	uiWriteRegister(R_CHANNEL, _channel & CHANNEL_MASK);   //turn off rx/tx
@@ -293,7 +292,7 @@ void MiLightRadioPL1167_LT8900::vResumeRX(void)
 /**************************************************************************/
 // Check if data is available using the hardware pin PKT_FLAG
 /**************************************************************************/
-bool MiLightRadioPL1167_LT8900::bAvailablePin()
+bool LT8900MiLightRadio::bAvailablePin()
 {
 	//read the PKT_FLAG pin.
 	if (digitalRead(_pin_pktflag) != 0)
@@ -307,7 +306,7 @@ bool MiLightRadioPL1167_LT8900::bAvailablePin()
 /**************************************************************************/
 // Check if data is available using the PKT_FLAG state in the status register
 /**************************************************************************/
-bool MiLightRadioPL1167_LT8900::bAvailableRegister()
+bool LT8900MiLightRadio::bAvailableRegister()
 {
 	//read the PKT_FLAG state; this can also be done with a hard wire.
 	uint16_t value = uiReadRegister(R_STATUS);
@@ -323,7 +322,7 @@ bool MiLightRadioPL1167_LT8900::bAvailableRegister()
 /**************************************************************************/
 // Read the RX buffer
 /**************************************************************************/
-int MiLightRadioPL1167_LT8900::iReadRXBuffer(uint8_t *buffer, size_t maxBuffer)
+int LT8900MiLightRadio::iReadRXBuffer(uint8_t *buffer, size_t maxBuffer)
 {
 	uint16_t value = uiReadRegister(R_STATUS);
 	if (bitRead(value, STATUS_CRC_BIT) == 0)
@@ -358,7 +357,7 @@ int MiLightRadioPL1167_LT8900::iReadRXBuffer(uint8_t *buffer, size_t maxBuffer)
 /**************************************************************************/
 // Set the active channel for the radio module
 /**************************************************************************/
-void MiLightRadioPL1167_LT8900::vSetChannel(uint8_t channel)
+void LT8900MiLightRadio::vSetChannel(uint8_t channel)
 {
 	_channel = channel;
 	uiWriteRegister(R_CHANNEL, (_channel & CHANNEL_MASK));
@@ -367,9 +366,9 @@ void MiLightRadioPL1167_LT8900::vSetChannel(uint8_t channel)
 /**************************************************************************/
 // Startup
 /**************************************************************************/
-int MiLightRadioPL1167_LT8900::begin()
+int LT8900MiLightRadio::begin()
 {
-  vSetChannel(config.channels[0]);
+  vSetChannel(_config.channels[0]);
   configure();
   available();
   return 0;
@@ -378,18 +377,18 @@ int MiLightRadioPL1167_LT8900::begin()
 /**************************************************************************/
 // Configure the module according to type, and start listening
 /**************************************************************************/
-int MiLightRadioPL1167_LT8900::configure()
+int LT8900MiLightRadio::configure()
 {
-  vInitRadioModule(config.type);
-  vSetSyncWord(config.syncword3, 0,0,config.syncword0);
-  vStartListening(config.channels[0]);
+  vInitRadioModule(_config.type);
+  vSetSyncWord(_config.syncword3, 0,0,_config.syncword0);
+  vStartListening(_config.channels[0]);
   return 0;
 }
 
 /**************************************************************************/
 // Check if data is available
 /**************************************************************************/
-bool MiLightRadioPL1167_LT8900::available()
+bool LT8900MiLightRadio::available()
 {
   _waiting = false;
 
@@ -519,7 +518,7 @@ bool MiLightRadioPL1167_LT8900::available()
   return _waiting;
 }
 
-int MiLightRadioPL1167_LT8900::dupesReceived()
+int LT8900MiLightRadio::dupesReceived()
 {
   return _dupes_received;
 }
@@ -527,7 +526,7 @@ int MiLightRadioPL1167_LT8900::dupesReceived()
 /**************************************************************************/
 // Read received data from buffer to upper layer
 /**************************************************************************/
-int MiLightRadioPL1167_LT8900::read(uint8_t frame[], size_t &frame_length)
+int LT8900MiLightRadio::read(uint8_t frame[], size_t &frame_length)
 {
   if (!_waiting)
   {
@@ -557,7 +556,7 @@ int MiLightRadioPL1167_LT8900::read(uint8_t frame[], size_t &frame_length)
 /**************************************************************************/
 // Write data
 /**************************************************************************/
-int MiLightRadioPL1167_LT8900::write(uint8_t frame[], size_t frame_length)
+int LT8900MiLightRadio::write(uint8_t frame[], size_t frame_length)
 {
   if (frame_length > sizeof(_out_packet) - 1) {
     return -1;
@@ -582,13 +581,13 @@ int MiLightRadioPL1167_LT8900::write(uint8_t frame[], size_t frame_length)
 /**************************************************************************/
 // Handle the transmission to regarding to freq diversity and repeats
 /**************************************************************************/
-int MiLightRadioPL1167_LT8900::resend()
+int LT8900MiLightRadio::resend()
 {
   byte Length =  _out_packet[0];
 
   for (size_t i = 0; i < MiLightRadioConfig::NUM_CHANNELS; i++)
   {
-    sendPacket(_out_packet, Length, config.channels[i]);
+    sendPacket(_out_packet, Length, _config.channels[i]);
     delayMicroseconds(DEFAULT_TIME_BETWEEN_RETRANSMISSIONS_uS);
   }
 
@@ -598,7 +597,7 @@ int MiLightRadioPL1167_LT8900::resend()
 /**************************************************************************/
 // The actual transmit happens here
 /**************************************************************************/
-bool MiLightRadioPL1167_LT8900::sendPacket(uint8_t *data, size_t packetSize, byte byChannel)
+bool LT8900MiLightRadio::sendPacket(uint8_t *data, size_t packetSize, byte byChannel)
 {
   if (packetSize < 1 || packetSize > 255)
   {
@@ -629,3 +628,7 @@ bool MiLightRadioPL1167_LT8900::sendPacket(uint8_t *data, size_t packetSize, byt
 
   return true;
 }
+
+const MiLightRadioConfig& LT8900MiLightRadio::config() {
+  return _config;
+}

+ 26 - 28
lib/MiLight/MiLightRadioPL1167_LT8900.h

@@ -15,8 +15,7 @@
 
 #include <MiLightRadioConfig.h>
 #include <MiLightButtons.h>
-#include <MiLightRadioInterface.h>
-
+#include <MiLightRadio.h>
 
 // Register defines
 #define REGISTER_READ       0b10000000  //bin
@@ -43,13 +42,12 @@
 
 #define DEFAULT_TIME_BETWEEN_RETRANSMISSIONS_uS	350
 
-
 #ifndef MILIGHTRADIOPL1167_LT8900_H_
 #define MILIGHTRADIOPL1167_LT8900_H_
 
-class MiLightRadioPL1167_LT8900 : public MiLightRadioInterface{
+class LT8900MiLightRadio : public MiLightRadio {
   public:
-    MiLightRadioPL1167_LT8900(byte byCSPin, byte byResetPin, byte byPktFlag, const MiLightRadioConfig& config);
+    LT8900MiLightRadio(byte byCSPin, byte byResetPin, byte byPktFlag, const MiLightRadioConfig& config);
 
     virtual int begin();
     virtual bool available();
@@ -58,32 +56,32 @@ class MiLightRadioPL1167_LT8900 : public MiLightRadioInterface{
     virtual int write(uint8_t frame[], size_t frame_length);
     virtual int resend();
     virtual int configure();
+    virtual const MiLightRadioConfig& config();
 
   private:
 
-
-        void vInitRadioModule(MiLightRadioType type);
-        void vSetSyncWord(uint16_t syncWord3, uint16_t syncWord2, uint16_t syncWord1, uint16_t syncWord0);
-        uint16_t uiReadRegister(uint8_t reg);
-        void regWrite16(byte ADDR, byte V1, byte V2, byte WAIT);
-        uint8_t uiWriteRegister(uint8_t reg, uint16_t data);
-
-        bool bAvailablePin(void);
-        bool bAvailableRegister(void);
-        void vStartListening(uint uiChannelToListenTo);
-        void vResumeRX(void);
-        int iReadRXBuffer(uint8_t *buffer, size_t maxBuffer);
-        void vSetChannel(uint8_t channel);
-        void vGenericSendPacket(int iMode, int iLength, byte *pbyFrame, byte byChannel );
-        bool bCheckRadioConnection(void);
-        bool sendPacket(uint8_t *data, size_t packetSize,byte byChannel);
-
-        byte _pin_pktflag;
-      	byte _csPin;
-
-    const MiLightRadioConfig& config;
+    void vInitRadioModule(MiLightRadioType type);
+    void vSetSyncWord(uint16_t syncWord3, uint16_t syncWord2, uint16_t syncWord1, uint16_t syncWord0);
+    uint16_t uiReadRegister(uint8_t reg);
+    void regWrite16(byte ADDR, byte V1, byte V2, byte WAIT);
+    uint8_t uiWriteRegister(uint8_t reg, uint16_t data);
+
+    bool bAvailablePin(void);
+    bool bAvailableRegister(void);
+    void vStartListening(uint uiChannelToListenTo);
+    void vResumeRX(void);
+    int iReadRXBuffer(uint8_t *buffer, size_t maxBuffer);
+    void vSetChannel(uint8_t channel);
+    void vGenericSendPacket(int iMode, int iLength, byte *pbyFrame, byte byChannel );
+    bool bCheckRadioConnection(void);
+    bool sendPacket(uint8_t *data, size_t packetSize,byte byChannel);
+
+    byte _pin_pktflag;
+    byte _csPin;
+
+    const MiLightRadioConfig& _config;
     //uint32_t _prev_packet_id;
-    uint8_t _channel = 0;
+    uint8_t _channel;
     uint8_t _packet[10];
     uint8_t _out_packet[10];
     bool _waiting;
@@ -92,4 +90,4 @@ class MiLightRadioPL1167_LT8900 : public MiLightRadioInterface{
 
 
 
-#endif /* MILIGHTRADIO_H_ */
+#endif

+ 40 - 17
lib/MiLight/MiLightClient.cpp

@@ -2,29 +2,48 @@
 #include <MiLightRadioConfig.h>
 #include <Arduino.h>
 
+MiLightClient::MiLightClient(MiLightRadioFactory* radioFactory)
+  : resendCount(MILIGHT_DEFAULT_RESEND_COUNT),
+    currentRadio(NULL),
+    numRadios(MiLightRadioConfig::NUM_CONFIGS)
+{
+  radios = new MiLightRadio*[numRadios];
+
+  for (size_t i = 0; i < numRadios; i++) {
+    radios[i] = radioFactory->create(*MiLightRadioConfig::ALL_CONFIGS[i]);
+  }
 
-MiLightRadioInterface* MiLightClient::switchRadio(const MiLightRadioType type) {
-  RadioStack* stack = NULL;
+  this->currentRadio = radios[0];
+  this->currentRadio->configure();
+}
+
+void MiLightClient::begin() {
+  for (size_t i = 0; i < numRadios; i++) {
+    radios[i]->begin();
+  }
+}
+
+MiLightRadio* MiLightClient::switchRadio(const MiLightRadioType type) {
+  MiLightRadio* radio = NULL;
 
   for (int i = 0; i < numRadios; i++) {
-    if (radios[i]->config.type == type) {
-      stack = radios[i];
+    if (this->radios[i]->config().type == type) {
+      radio = radios[i];
       break;
     }
   }
 
-  if (stack != NULL) {
-    MiLightRadioInterface *radio = stack->getRadioInterface();
-
-    if (currentRadio->config.type != stack->config.type) {
+  if (radio != NULL) {
+    if (currentRadio != radio) {
       radio->configure();
     }
 
-    currentRadio = stack;
-    formatter = stack->config.packetFormatter;
+    this->currentRadio = radio;
+    this->formatter = radio->config().packetFormatter;
+
     return radio;
   } else {
-    Serial.print("MiLightClient - tried to get radio for unknown type: ");
+    Serial.print(F("MiLightClient - tried to get radio for unknown type: "));
     Serial.println(type);
   }
 
@@ -53,16 +72,16 @@ bool MiLightClient::available() {
     return false;
   }
 
-  return currentRadio->getRadioInterface()->available();
+  return currentRadio->available();
 }
 void MiLightClient::read(uint8_t packet[]) {
   if (currentRadio == NULL) {
     return;
   }
 
-  size_t length = currentRadio->config.getPacketLength();
+  size_t length = currentRadio->config().getPacketLength();
 
-  currentRadio->getRadioInterface()->read(packet, length);
+  currentRadio->read(packet, length);
 }
 
 void MiLightClient::write(uint8_t packet[]) {
@@ -72,18 +91,22 @@ void MiLightClient::write(uint8_t packet[]) {
 
 #ifdef DEBUG_PRINTF
   printf("Sending packet: ");
-  for (int i = 0; i < currentRadio->config.getPacketLength(); i++) {
+  for (int i = 0; i < currentRadio->config().getPacketLength(); i++) {
     printf("%02X", packet[i]);
   }
   printf("\n");
-#endif
   int iStart = millis();
+#endif
+
   for (int i = 0; i < this->resendCount; i++) {
-        currentRadio->getRadioInterface()->write(packet, currentRadio->config.getPacketLength());
+    currentRadio->write(packet, currentRadio->config().getPacketLength());
   }
+
+#ifdef DEBUG_PRINTF
   int iElapsed = millis() - iStart;
   Serial.print("Elapsed: ");
   Serial.println(iElapsed);
+#endif
 }
 
 void MiLightClient::updateColorRaw(const uint8_t color) {

+ 44 - 81
lib/MiLight/MiLightClient.h

@@ -1,10 +1,7 @@
 #include <Arduino.h>
 #include <MiLightRadio.h>
-#include <MiLightRadioPL1167_LT8900.h>
-#include <PL1167_nRF24.h>
-#include <RF24.h>
+#include <MiLightRadioFactory.h>
 #include <MiLightButtons.h>
-#include <RadioStack.h>
 #include <Settings.h>
 
 #ifndef _MILIGHTCLIENT_H
@@ -15,97 +12,63 @@
 #define MILIGHT_DEFAULT_RESEND_COUNT 10
 
 class MiLightClient {
-  public:
-  MiLightClient(byte byCSPin, byte byResetPin, byte byPktFlag, eRadioInterfaceType InterfaceType)
-  :
-  resendCount(MILIGHT_DEFAULT_RESEND_COUNT),
-  currentRadio(NULL),
-  numRadios(MiLightRadioConfig::NUM_CONFIGS)
-
-  {
-    radios = new RadioStack*[numRadios];
-
-    for (size_t i = 0; i < numRadios; i++)
-    {
-      if(InterfaceType == PL1167_LT8900)
-      {
-        radios[i] = new RadioStack(byCSPin, byResetPin, byPktFlag, *MiLightRadioConfig::ALL_CONFIGS[i]);
-      }
-      else if(InterfaceType == nRF24)
-      {
-        pRF = new RF24(byCSPin, byPktFlag);
-        radios[i] = new RadioStack(*pRF, *MiLightRadioConfig::ALL_CONFIGS[i]);
-      }
-    }
-
-    currentRadio = radios[0];
-
-    currentRadio->getRadioInterface()->configure();
-  }
-
-
-    ~MiLightClient() {
-      delete pRF;
-      delete[] radios;
-    }
-
-    void begin() {
-      for (size_t i = 0; i < numRadios; i++) {
-        radios[i]->getRadioInterface()->begin();
-      }
-    }
+public:
+  MiLightClient(MiLightRadioFactory* radioFactory);
 
+  ~MiLightClient() {
+    delete[] radios;
+  }
 
-    void prepare(MiLightRadioConfig& config, const uint16_t deviceId = -1, const uint8_t groupId = -1);
+  void begin();
+  void prepare(MiLightRadioConfig& config, const uint16_t deviceId = -1, const uint8_t groupId = -1);
 
-    void setResendCount(const unsigned int resendCount);
-    bool available();
-    void read(uint8_t packet[]);
-    void write(uint8_t packet[]);
+  void setResendCount(const unsigned int resendCount);
+  bool available();
+  void read(uint8_t packet[]);
+  void write(uint8_t packet[]);
 
-    // Common methods
-    void updateStatus(MiLightStatus status);
-    void updateStatus(MiLightStatus status, uint8_t groupId);
-    void pair();
-    void unpair();
-    void command(uint8_t command, uint8_t arg);
-    void updateMode(uint8_t mode);
-    void nextMode();
-    void previousMode();
-    void modeSpeedDown();
-    void modeSpeedUp();
+  // Common methods
+  void updateStatus(MiLightStatus status);
+  void updateStatus(MiLightStatus status, uint8_t groupId);
+  void pair();
+  void unpair();
+  void command(uint8_t command, uint8_t arg);
+  void updateMode(uint8_t mode);
+  void nextMode();
+  void previousMode();
+  void modeSpeedDown();
+  void modeSpeedUp();
 
-    // RGBW methods
-    void updateHue(const uint16_t hue);
-    void updateBrightness(const uint8_t brightness);
-    void updateColorWhite();
-    void updateColorRaw(const uint8_t color);
+  // RGBW methods
+  void updateHue(const uint16_t hue);
+  void updateBrightness(const uint8_t brightness);
+  void updateColorWhite();
+  void updateColorRaw(const uint8_t color);
 
-    // CCT methods
-    void updateTemperature(const uint8_t colorTemperature);
-    void decreaseTemperature();
-    void increaseTemperature();
-    void increaseBrightness();
-    void decreaseBrightness();
+  // CCT methods
+  void updateTemperature(const uint8_t colorTemperature);
+  void decreaseTemperature();
+  void increaseTemperature();
+  void increaseBrightness();
+  void decreaseBrightness();
 
-    void updateSaturation(const uint8_t saturation);
+  void updateSaturation(const uint8_t saturation);
 
-    void formatPacket(uint8_t* packet, char* buffer);
+  void formatPacket(uint8_t* packet, char* buffer);
 
 
-  protected:
+protected:
 
-    RF24 *pRF;
-    RadioStack** radios;
-    RadioStack* currentRadio;
-    PacketFormatter* formatter;
-    const size_t numRadios;
+  MiLightRadio** radios;
+  MiLightRadio* currentRadio;
+  PacketFormatter* formatter;
+  const size_t numRadios;
 
-    unsigned int resendCount;
+  unsigned int resendCount;
 
-    MiLightRadioInterface* switchRadio(const MiLightRadioType type);
+  MiLightRadio* switchRadio(const MiLightRadioType type);
 
-    void flushPacket();
+  void flushPacket();
 };
 
 #endif

+ 15 - 34
lib/MiLight/MiLightRadio.h

@@ -1,50 +1,31 @@
-/*
- * MiLightRadio.h
- *
- *  Created on: 29 May 2015
- *      Author: henryk
- */
 
 #ifdef ARDUINO
 #include "Arduino.h"
 #else
 #include <stdint.h>
 #include <stdlib.h>
-#include <string.h>
 #endif
 
-#include "AbstractPL1167.h"
 #include <MiLightRadioConfig.h>
-#include <MiLightRadioInterface.h>
 
-// #define DEBUG_PRINTF
+#ifndef _MILIGHT_RADIO_H_
+#define _MILIGHT_RADIO_H_
 
-#ifndef MILIGHTRADIO_H_
-#define MILIGHTRADIO_H_
-
-class MiLightRadio : public MiLightRadioInterface{
+class MiLightRadio {
   public:
-    MiLightRadio(AbstractPL1167 &pl1167, const MiLightRadioConfig& config);
-
-    int begin();
-    bool available();
-    int read(uint8_t frame[], size_t &frame_length);
-    int dupesReceived();
-    int write(uint8_t frame[], size_t frame_length);
-    int resend();
-    int configure();
-
-  private:
-    AbstractPL1167 &_pl1167;
-    const MiLightRadioConfig& config;
-    uint32_t _prev_packet_id;
-
-    uint8_t _packet[10];
-    uint8_t _out_packet[10];
-    bool _waiting;
-    int _dupes_received;
+
+    virtual int begin();
+    virtual bool available();
+    virtual int read(uint8_t frame[], size_t &frame_length);
+    virtual int dupesReceived();
+    virtual int write(uint8_t frame[], size_t frame_length);
+    virtual int resend();
+    virtual int configure();
+    virtual const MiLightRadioConfig& config();
+
 };
 
 
 
-#endif /* MILIGHTRADIO_H_ */
+
+#endif

+ 32 - 0
lib/MiLight/MiLightRadioFactory.cpp

@@ -0,0 +1,32 @@
+#include <MiLightRadioFactory.h>
+
+MiLightRadioFactory* MiLightRadioFactory::fromSettings(const Settings& settings) {
+  switch (settings.radioInterfaceType) {
+    case nRF24:
+      return new NRF24Factory(settings.csnPin, settings.cePin);
+
+    case LT8900:
+      return new LT8900Factory(settings.csnPin, settings.resetPin, settings.cePin);
+
+    default:
+      return NULL;
+  }
+}
+
+NRF24Factory::NRF24Factory(uint8_t csnPin, uint8_t cePin)
+  : rf24(RF24(cePin, csnPin))
+{ }
+
+MiLightRadio* NRF24Factory::create(const MiLightRadioConfig &config) {
+  return new NRF24MiLightRadio(rf24, config);
+}
+
+LT8900Factory::LT8900Factory(uint8_t csPin, uint8_t resetPin, uint8_t pktFlag)
+  : _csPin(csPin),
+    _resetPin(resetPin),
+    _pktFlag(pktFlag)
+{ }
+
+MiLightRadio* LT8900Factory::create(const MiLightRadioConfig& config) {
+  return new LT8900MiLightRadio(_csPin, _resetPin, _pktFlag, config);
+}

+ 49 - 0
lib/MiLight/MiLightRadioFactory.h

@@ -0,0 +1,49 @@
+#include <RF24.h>
+#include <PL1167_nRF24.h>
+#include <MiLightRadioConfig.h>
+#include <MiLightRadio.h>
+#include <NRF24MiLightRadio.h>
+#include <LT8900MiLightRadio.h>
+#include <Settings.h>
+
+#ifndef _MILIGHT_RADIO_FACTORY_H
+#define _MILIGHT_RADIO_FACTORY_H
+
+class MiLightRadioFactory {
+public:
+
+  virtual MiLightRadio* create(const MiLightRadioConfig& config) = 0;
+
+  static MiLightRadioFactory* fromSettings(const Settings& settings);
+  
+};
+
+class NRF24Factory : public MiLightRadioFactory {
+public:
+
+  NRF24Factory(uint8_t cePin, uint8_t csnPin);
+
+  virtual MiLightRadio* create(const MiLightRadioConfig& config);
+
+protected:
+
+  RF24 rf24;
+
+};
+
+class LT8900Factory : public MiLightRadioFactory {
+public:
+
+  LT8900Factory(uint8_t csPin, uint8_t resetPin, uint8_t pktFlag);
+
+  virtual MiLightRadio* create(const MiLightRadioConfig& config);
+
+protected:
+
+  uint8_t _csPin;
+  uint8_t _resetPin;
+  uint8_t _pktFlag;
+
+};
+
+#endif

+ 0 - 29
lib/MiLight/MiLightRadioInterface.h

@@ -1,29 +0,0 @@
-
-#ifdef ARDUINO
-#include "Arduino.h"
-#else
-#include <stdint.h>
-#include <stdlib.h>
-#endif
-
-#ifndef MILIGHTRADIOINTERFACE_H_
-#define MILIGHTRADIOINTERFACE_H_
-
-class MiLightRadioInterface
-{
-  public:
-
-    virtual int begin();
-    virtual bool available();
-    virtual int read(uint8_t frame[], size_t &frame_length);
-    virtual int dupesReceived();
-    virtual int write(uint8_t frame[], size_t frame_length);
-    virtual int resend();
-    virtual int configure();
-
-};
-
-
-
-
-#endif /* MILIGHTRADIOINTERFACE_H_ */

+ 29 - 31
lib/MiLight/MiLightRadio.cpp

@@ -1,26 +1,22 @@
-/*
- * MiLightRadio.cpp
- *
- *  Created on: 29 May 2015
- *      Author: henryk
- */
+// Adapated from code from henryk
 
-#include "MiLightRadio.h"
+#include <PL1167_nRF24.h>
+#include <NRF24MiLightRadio.h>
 
 #define PACKET_ID(packet, packet_length) ( (packet[1] << 8) | packet[packet_length - 1] )
 
-MiLightRadio::MiLightRadio(AbstractPL1167 &pl1167, const MiLightRadioConfig& config)
-  : _pl1167(pl1167), config(config) {
-  _waiting = false;
-}
+NRF24MiLightRadio::NRF24MiLightRadio(RF24& rf24, const MiLightRadioConfig& config)
+  : _pl1167(PL1167_nRF24(rf24)),
+    _waiting(false),
+    _config(config)
+{ }
 
-int MiLightRadio::begin()
-{
+int NRF24MiLightRadio::begin() {
   int retval = _pl1167.open();
   if (retval < 0) {
     return retval;
   }
-  
+
   retval = configure();
   if (retval < 0) {
     return retval;
@@ -31,7 +27,7 @@ int MiLightRadio::begin()
   return 0;
 }
 
-int MiLightRadio::configure() {
+int NRF24MiLightRadio::configure() {
   int retval = _pl1167.setCRC(true);
   if (retval < 0) {
     return retval;
@@ -47,38 +43,38 @@ int MiLightRadio::configure() {
     return retval;
   }
 
-  retval = _pl1167.setSyncword(config.syncword0, config.syncword3);
+  retval = _pl1167.setSyncword(_config.syncword0, _config.syncword3);
   if (retval < 0) {
     return retval;
   }
 
-  // +1 to be able to buffer the length 
-  retval = _pl1167.setMaxPacketLength(config.getPacketLength() + 1);
+  // +1 to be able to buffer the length
+  retval = _pl1167.setMaxPacketLength(_config.getPacketLength() + 1);
   if (retval < 0) {
     return retval;
   }
-  
+
   return 0;
 }
 
-bool MiLightRadio::available() {
+bool NRF24MiLightRadio::available() {
   if (_waiting) {
 #ifdef DEBUG_PRINTF
   printf("_waiting\n");
 #endif
     return true;
   }
-  
-  if (_pl1167.receive(config.channels[0]) > 0) {
+
+  if (_pl1167.receive(_config.channels[0]) > 0) {
 #ifdef DEBUG_PRINTF
-  printf("MiLightRadio - received packet!\n");
+  printf("NRF24MiLightRadio - received packet!\n");
 #endif
     size_t packet_length = sizeof(_packet);
     if (_pl1167.readFIFO(_packet, packet_length) < 0) {
       return false;
     }
 #ifdef DEBUG_PRINTF
-  printf("MiLightRadio - Checking packet length (expecting %d, is %d)\n", _packet[0] + 1U, packet_length);
+  printf("NRF24MiLightRadio - Checking packet length (expecting %d, is %d)\n", _packet[0] + 1U, packet_length);
 #endif
     if (packet_length == 0 || packet_length != _packet[0] + 1U) {
       return false;
@@ -98,13 +94,13 @@ bool MiLightRadio::available() {
   return _waiting;
 }
 
-int MiLightRadio::dupesReceived()
+int NRF24MiLightRadio::dupesReceived()
 {
   return _dupes_received;
 }
 
 
-int MiLightRadio::read(uint8_t frame[], size_t &frame_length)
+int NRF24MiLightRadio::read(uint8_t frame[], size_t &frame_length)
 {
   if (!_waiting) {
     frame_length = 0;
@@ -125,8 +121,7 @@ int MiLightRadio::read(uint8_t frame[], size_t &frame_length)
   return _packet[0];
 }
 
-int MiLightRadio::write(uint8_t frame[], size_t frame_length)
-{
+int NRF24MiLightRadio::write(uint8_t frame[], size_t frame_length) {
   if (frame_length > sizeof(_out_packet) - 1) {
     return -1;
   }
@@ -141,11 +136,14 @@ int MiLightRadio::write(uint8_t frame[], size_t frame_length)
   return frame_length;
 }
 
-int MiLightRadio::resend()
-{
+int NRF24MiLightRadio::resend() {
   for (size_t i = 0; i < MiLightRadioConfig::NUM_CHANNELS; i++) {
     _pl1167.writeFIFO(_out_packet, _out_packet[0] + 1);
-    _pl1167.transmit(config.channels[i]);
+    _pl1167.transmit(_config.channels[i]);
   }
   return 0;
 }
+
+const MiLightRadioConfig& NRF24MiLightRadio::config() {
+  return _config;
+}

+ 43 - 0
lib/MiLight/NRF24MiLightRadio.h

@@ -0,0 +1,43 @@
+#ifdef ARDUINO
+#include "Arduino.h"
+#else
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#include <RF24.h>
+#include <PL1167_nRF24.h>
+#include <MiLightRadioConfig.h>
+#include <MiLightRadio.h>
+
+#ifndef _NRF24_MILIGHT_RADIO_H_
+#define _NRF24_MILIGHT_RADIO_H_
+
+class NRF24MiLightRadio : public MiLightRadio {
+  public:
+    NRF24MiLightRadio(RF24& rf, const MiLightRadioConfig& config);
+
+    int begin();
+    bool available();
+    int read(uint8_t frame[], size_t &frame_length);
+    int dupesReceived();
+    int write(uint8_t frame[], size_t frame_length);
+    int resend();
+    int configure();
+    const MiLightRadioConfig& config();
+
+  private:
+    PL1167_nRF24 _pl1167;
+    const MiLightRadioConfig& _config;
+    uint32_t _prev_packet_id;
+
+    uint8_t _packet[10];
+    uint8_t _out_packet[10];
+    bool _waiting;
+    int _dupes_received;
+};
+
+
+
+#endif

+ 6 - 5
lib/MiLight/PL1167_nRF24.cpp

@@ -12,7 +12,8 @@ static uint8_t reverse_bits(uint8_t data);
 static void demangle_packet(uint8_t *in, uint8_t *out) ;
 
 PL1167_nRF24::PL1167_nRF24(RF24 &radio)
-  : _radio(radio) { }
+  : _radio(radio)
+{ }
 
 static const uint8_t pipe[] = {0xd1, 0x28, 0x5e, 0x55, 0x55};
 
@@ -266,7 +267,7 @@ int PL1167_nRF24::transmit(uint8_t channel)
       buffer_fill -= 8;
     }
   }
-  
+
   yield();
 
   _radio.write(tmp, outp);
@@ -374,14 +375,14 @@ int PL1167_nRF24::internal_receive()
   }
 
   memcpy(_packet, tmp, outp);
-  
+
   _packet_length = outp;
   _received = true;
-  
+
 #ifdef DEBUG_PRINTF
   printf("Successfully parsed packet of length %d\n", _packet_length);
 #endif
-  
+
   return outp;
 }
 

+ 2 - 3
lib/MiLight/PL1167_nRF24.h

@@ -9,7 +9,6 @@
 #include "Arduino.h"
 #endif
 
-#include "AbstractPL1167.h"
 #include "RF24.h"
 
 // #define DEBUG_PRINTF
@@ -17,9 +16,9 @@
 #ifndef PL1167_NRF24_H_
 #define PL1167_NRF24_H_
 
-class PL1167_nRF24 : public AbstractPL1167 {
+class PL1167_nRF24 {
   public:
-    PL1167_nRF24(RF24 &radio);
+    PL1167_nRF24(RF24& radio);
     int open();
     int setPreambleLength(uint8_t preambleLength);
     int setSyncword(uint16_t syncword0, uint16_t syncword3);

+ 0 - 56
lib/MiLight/RadioStack.h

@@ -1,56 +0,0 @@
-#include <RF24.h>
-#include <PL1167_nRF24.h>
-#include <MiLightRadioConfig.h>
-#include <MiLightRadio.h>
-#include <MiLightRadioPL1167_LT8900.h>
-#include <MiLightRadioInterface.h>
-#include <Settings.h>
-
-#ifndef _RADIO_STACK_H
-#define _RADIO_STACK_H
-
-class RadioStack {
-public:
-  RadioStack(RF24& rf, const MiLightRadioConfig& config)
-    : config(config),UsedInterfaceType(nRF24)
-  {
-    nrf = new PL1167_nRF24(rf);
-    radio = new MiLightRadio(*nrf, config);
-  }
-
-  RadioStack(byte byCSPin, byte byResetPin, byte byPktFlag, const MiLightRadioConfig& config)
-      : config(config),UsedInterfaceType(PL1167_LT8900)
-    {
-      radioPL1167_LT8900 = new MiLightRadioPL1167_LT8900(byCSPin, byResetPin, byPktFlag, config);
-    }
-
-  ~RadioStack() {
-    delete radio;
-    delete nrf;
-    delete radioPL1167_LT8900;
-
-  }
-
-  inline MiLightRadioInterface* getRadioInterface()
-  {
-    if(UsedInterfaceType == nRF24)
-    {
-      return this->radio;
-    }
-    else if(UsedInterfaceType == PL1167_LT8900)
-    {
-      return this->radioPL1167_LT8900;
-    }
-  }
-
-  const MiLightRadioConfig& config;
-
-private:
-  PL1167_nRF24 *nrf;
-  MiLightRadio *radio;
-  MiLightRadioPL1167_LT8900 *radioPL1167_LT8900;
-  eRadioInterfaceType UsedInterfaceType;
-
-};
-
-#endif

+ 24 - 35
lib/Settings/Settings.cpp

@@ -48,17 +48,8 @@ void Settings::deserialize(Settings& settings, JsonObject& parsedSettings) {
       settings.resetPin = parsedSettings["reset_pin"];
     }
 
-    if (parsedSettings.containsKey("radio_interface_type"))
-    {
-      String InterfaceType = parsedSettings["radio_interface_type"];
-      if(InterfaceType == "nRF24")
-      {
-        settings.radioInterfaceType =  nRF24;
-      }
-      else if(InterfaceType == "PL1167/LT8900/8910/8920")
-      {
-        settings.radioInterfaceType =  PL1167_LT8900;
-      }
+    if (parsedSettings.containsKey("radio_interface_type")) {
+      settings.radioInterfaceType = typeFromString(parsedSettings["radio_interface_type"]);
     }
 
     if (parsedSettings.containsKey("packet_repeats")) {
@@ -129,24 +120,12 @@ void Settings::patch(JsonObject& parsedSettings) {
     if (parsedSettings.containsKey("csn_pin")) {
       this->csnPin = parsedSettings["csn_pin"];
     }
-
     if (parsedSettings.containsKey("reset_pin")) {
       this->resetPin = parsedSettings["reset_pin"];
     }
-
-    if (parsedSettings.containsKey("radio_interface_type"))
-    {
-      String InterfaceType = parsedSettings["radio_interface_type"];
-      if(InterfaceType == "nRF24")
-      {
-        this->radioInterfaceType =  nRF24;
-      }
-      else if(InterfaceType == "PL1167/LT8900/8910/8920")
-      {
-        this->radioInterfaceType =  PL1167_LT8900;
-      }
+    if (parsedSettings.containsKey("radio_interface_type")) {
+      this->radioInterfaceType = typeFromString(parsedSettings["radio_interface_type"]);
     }
-
     if (parsedSettings.containsKey("packet_repeats")) {
       this->packetRepeats = parsedSettings["packet_repeats"];
     }
@@ -206,16 +185,7 @@ void Settings::serialize(Stream& stream, const bool prettyPrint) {
   root["ce_pin"] = this->cePin;
   root["csn_pin"] = this->csnPin;
   root["reset_pin"] = this->resetPin;
-
-  if(this->radioInterfaceType == nRF24)
-  {
-    root["radio_interface_type"] = "nRF24";
-  }
-  else if(this->radioInterfaceType == PL1167_LT8900)
-  {
-    root["radio_interface_type"] = "PL1167/LT8900/8910/8920";
-  }
-
+  root["radio_interface_type"] = typeToString(this->radioInterfaceType);
   root["packet_repeats"] = this->packetRepeats;
   root["http_repeat_factor"] = this->httpRepeatFactor;
   root["auto_restart_period"] = this->_autoRestartPeriod;
@@ -245,3 +215,22 @@ void Settings::serialize(Stream& stream, const bool prettyPrint) {
     root.printTo(stream);
   }
 }
+
+RadioInterfaceType Settings::typeFromString(const String& s) {
+  if (s.equalsIgnoreCase("lt8900")) {
+    return LT8900;
+  } else {
+    return nRF24;
+  }
+}
+
+String Settings::typeToString(RadioInterfaceType type) {
+  switch (type) {
+    case LT8900:
+      return "LT8900";
+
+    case nRF24:
+    default:
+      return "nRF24";
+  }
+}

+ 7 - 5
lib/Settings/Settings.h

@@ -24,10 +24,9 @@
 
 #define MINIMUM_RESTART_PERIOD 1
 
-enum eRadioInterfaceType
-{
+enum RadioInterfaceType {
   nRF24 = 0,
-  PL1167_LT8900 =1,
+  LT8900 = 1,
 };
 
 class GatewayConfig {
@@ -52,7 +51,7 @@ public:
     cePin(D0),
     csnPin(D8),
     resetPin(0),
-    radioInterfaceType(PL1167_LT8900),
+    radioInterfaceType(nRF24),
     deviceIds(NULL),
     gatewayConfigs(NULL),
     numDeviceIds(0),
@@ -76,6 +75,9 @@ public:
   static void deserialize(Settings& settings, JsonObject& json);
   static void load(Settings& settings);
 
+  static RadioInterfaceType typeFromString(const String& s);
+  static String typeToString(RadioInterfaceType type);
+
   void save();
   String toJson(const bool prettyPrint = true);
   void serialize(Stream& stream, const bool prettyPrint = false);
@@ -88,7 +90,7 @@ public:
   uint8_t cePin;
   uint8_t csnPin;
   uint8_t resetPin;
-  eRadioInterfaceType radioInterfaceType;
+  RadioInterfaceType radioInterfaceType;
   uint16_t *deviceIds;
   GatewayConfig **gatewayConfigs;
   size_t numGatewayConfigs;

+ 2 - 2
platformio.ini

@@ -27,7 +27,7 @@ board = nodemcuv2
 lib_deps =
   ${common.lib_deps_builtin}
   ${common.lib_deps_external}
-build_flags = ${common.build_flags} -D FIRMWARE_VARIANT=\\\"nodemcuv2\\\"
+build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.4m1m.ld -D FIRMWARE_VARIANT=\\\"nodemcuv2\\\"
 
 [env:d1_mini]
 platform = espressif8266
@@ -36,7 +36,7 @@ board = d1_mini
 lib_deps =
   ${common.lib_deps_builtin}
   ${common.lib_deps_external}
-build_flags = ${common.build_flags} -D FIRMWARE_VARIANT=\\\"d1_mini\\\"
+build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.4m1m.ld -D FIRMWARE_VARIANT=\\\"d1_mini\\\"
 
 [env:esp12]
 platform = espressif8266

+ 13 - 13
src/main.cpp

@@ -17,6 +17,7 @@ WiFiManager wifiManager;
 Settings settings;
 
 MiLightClient* milightClient;
+MiLightRadioFactory* radioFactory;
 MiLightHttpServer *httpServer;
 
 int numUdpServers = 0;
@@ -56,24 +57,23 @@ void initMilightUdpServers() {
 }
 
 
-void applySettings() 
-{
+void applySettings() {
   if (milightClient) {
     delete milightClient;
   }
-
-  if(settings.radioInterfaceType == nRF24)
-  {
-      Serial.println("Starting using 'nRF24' interface...");
-      milightClient = new MiLightClient(settings.cePin, settings.resetPin, settings.csnPin, nRF24);
-      milightClient->begin();
+  if (radioFactory) {
+    delete radioFactory;
   }
-  else if(settings.radioInterfaceType == PL1167_LT8900)
-  {
-      Serial.println("Starting using 'PL1167_LT8900' interface...");
-      milightClient = new MiLightClient(settings.cePin, settings.resetPin, settings.csnPin, PL1167_LT8900);
-      milightClient->begin();
+
+  radioFactory = MiLightRadioFactory::fromSettings(settings);
+
+  if (radioFactory == NULL) {
+    Serial.println(F("ERROR: unable to construct radio factory"));
   }
+
+  milightClient = new MiLightClient(radioFactory);
+  milightClient->begin();
+
   initMilightUdpServers();
 }