2023-02-13 22:59:42 +01:00
/*
* EBYTE LoRa E2200 Series
* https : //www.mischianti.org/category/my-libraries/lora-e220-devices/
*
* The MIT License ( MIT )
*
* Copyright ( c ) 2019 Renzo Mischianti www . mischianti . org All right reserved .
*
* You may copy , alter and reuse this code in any way you like , but please leave
* reference to www . mischianti . org in your comments if you redistribute this code .
*
*
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the " Software " ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
*/
# include "LoRa_E220.h"
# ifdef ACTIVATE_SOFTWARE_SERIAL
LoRa_E220 : : LoRa_E220 ( byte txE220pin , byte rxE220pin , UART_BPS_RATE bpsRate ) {
this - > txE220pin = txE220pin ;
this - > rxE220pin = rxE220pin ;
SoftwareSerial * mySerial = new SoftwareSerial ( ( uint8_t ) this - > txE220pin , ( uint8_t ) this - > rxE220pin ) ; // "RX TX" // @suppress("Abstract class cannot be instantiated")
this - > ss = mySerial ;
this - > hs = NULL ;
this - > bpsRate = bpsRate ;
}
LoRa_E220 : : LoRa_E220 ( byte txE220pin , byte rxE220pin , byte auxPin , UART_BPS_RATE bpsRate ) {
this - > txE220pin = txE220pin ;
this - > rxE220pin = rxE220pin ;
this - > auxPin = auxPin ;
SoftwareSerial * mySerial = new SoftwareSerial ( ( uint8_t ) this - > txE220pin , ( uint8_t ) this - > rxE220pin ) ; // "RX TX" // @suppress("Abstract class cannot be instantiated")
this - > ss = mySerial ;
this - > hs = NULL ;
this - > bpsRate = bpsRate ;
}
LoRa_E220 : : LoRa_E220 ( byte txE220pin , byte rxE220pin , byte auxPin , byte m0Pin , byte m1Pin , UART_BPS_RATE bpsRate ) {
this - > txE220pin = txE220pin ;
this - > rxE220pin = rxE220pin ;
this - > auxPin = auxPin ;
this - > m0Pin = m0Pin ;
this - > m1Pin = m1Pin ;
SoftwareSerial * mySerial = new SoftwareSerial ( ( uint8_t ) this - > txE220pin , ( uint8_t ) this - > rxE220pin ) ; // "RX TX" // @suppress("Abstract class cannot be instantiated")
this - > ss = mySerial ;
this - > hs = NULL ;
this - > bpsRate = bpsRate ;
}
# endif
LoRa_E220 : : LoRa_E220 ( HardwareSerial * serial , UART_BPS_RATE bpsRate ) { //, uint32_t serialConfig
this - > txE220pin = txE220pin ;
this - > rxE220pin = rxE220pin ;
# ifdef ACTIVATE_SOFTWARE_SERIAL
this - > ss = NULL ;
# endif
this - > hs = serial ;
// this->serialConfig = serialConfig;
this - > bpsRate = bpsRate ;
}
LoRa_E220 : : LoRa_E220 ( HardwareSerial * serial , byte auxPin , UART_BPS_RATE bpsRate ) { // , uint32_t serialConfig
this - > txE220pin = txE220pin ;
this - > rxE220pin = rxE220pin ;
this - > auxPin = auxPin ;
# ifdef ACTIVATE_SOFTWARE_SERIAL
this - > ss = NULL ;
# endif
this - > hs = serial ;
// this->serialConfig = serialConfig;
this - > bpsRate = bpsRate ;
}
LoRa_E220 : : LoRa_E220 ( HardwareSerial * serial , byte auxPin , byte m0Pin , byte m1Pin , UART_BPS_RATE bpsRate ) { //, uint32_t serialConfig
this - > txE220pin = txE220pin ;
this - > rxE220pin = rxE220pin ;
this - > auxPin = auxPin ;
this - > m0Pin = m0Pin ;
this - > m1Pin = m1Pin ;
# ifdef ACTIVATE_SOFTWARE_SERIAL
this - > ss = NULL ;
# endif
this - > hs = serial ;
// this->serialConfig = serialConfig;
this - > bpsRate = bpsRate ;
}
# ifdef HARDWARE_SERIAL_SELECTABLE_PIN
LoRa_E220 : : LoRa_E220 ( byte txE220pin , byte rxE220pin , HardwareSerial * serial , UART_BPS_RATE bpsRate , uint32_t serialConfig ) {
this - > txE220pin = txE220pin ;
this - > rxE220pin = rxE220pin ;
# ifdef ACTIVATE_SOFTWARE_SERIAL
this - > ss = NULL ;
# endif
this - > serialConfig = serialConfig ;
this - > hs = serial ;
this - > bpsRate = bpsRate ;
}
LoRa_E220 : : LoRa_E220 ( byte txE220pin , byte rxE220pin , HardwareSerial * serial , byte auxPin , UART_BPS_RATE bpsRate , uint32_t serialConfig ) {
this - > txE220pin = txE220pin ;
this - > rxE220pin = rxE220pin ;
this - > auxPin = auxPin ;
# ifdef ACTIVATE_SOFTWARE_SERIAL
this - > ss = NULL ;
# endif
this - > serialConfig = serialConfig ;
this - > hs = serial ;
this - > bpsRate = bpsRate ;
}
LoRa_E220 : : LoRa_E220 ( byte txE220pin , byte rxE220pin , HardwareSerial * serial , byte auxPin , byte m0Pin , byte m1Pin , UART_BPS_RATE bpsRate , uint32_t serialConfig ) {
this - > txE220pin = txE220pin ;
this - > rxE220pin = rxE220pin ;
this - > auxPin = auxPin ;
this - > m0Pin = m0Pin ;
this - > m1Pin = m1Pin ;
# ifdef ACTIVATE_SOFTWARE_SERIAL
this - > ss = NULL ;
# endif
this - > serialConfig = serialConfig ;
this - > hs = serial ;
this - > bpsRate = bpsRate ;
}
# endif
# ifdef ACTIVATE_SOFTWARE_SERIAL
LoRa_E220 : : LoRa_E220 ( SoftwareSerial * serial , UART_BPS_RATE bpsRate ) {
this - > txE220pin = txE220pin ;
this - > rxE220pin = rxE220pin ;
this - > ss = serial ;
this - > hs = NULL ;
this - > bpsRate = bpsRate ;
}
LoRa_E220 : : LoRa_E220 ( SoftwareSerial * serial , byte auxPin , UART_BPS_RATE bpsRate ) {
this - > txE220pin = txE220pin ;
this - > rxE220pin = rxE220pin ;
this - > auxPin = auxPin ;
this - > ss = serial ;
this - > hs = NULL ;
this - > bpsRate = bpsRate ;
}
LoRa_E220 : : LoRa_E220 ( SoftwareSerial * serial , byte auxPin , byte m0Pin , byte m1Pin , UART_BPS_RATE bpsRate ) {
this - > txE220pin = txE220pin ;
this - > rxE220pin = rxE220pin ;
this - > auxPin = auxPin ;
this - > m0Pin = m0Pin ;
this - > m1Pin = m1Pin ;
this - > ss = serial ;
this - > hs = NULL ;
this - > bpsRate = bpsRate ;
}
# endif
bool LoRa_E220 : : begin ( ) {
DEBUG_PRINT ( " RX MIC ---> " ) ;
DEBUG_PRINTLN ( this - > txE220pin ) ;
DEBUG_PRINT ( " TX MIC ---> " ) ;
DEBUG_PRINTLN ( this - > rxE220pin ) ;
DEBUG_PRINT ( " AUX ---> " ) ;
DEBUG_PRINTLN ( this - > auxPin ) ;
DEBUG_PRINT ( " M0 ---> " ) ;
DEBUG_PRINTLN ( this - > m0Pin ) ;
DEBUG_PRINT ( " M1 ---> " ) ;
DEBUG_PRINTLN ( this - > m1Pin ) ;
if ( this - > auxPin ! = - 1 ) {
pinMode ( this - > auxPin , INPUT ) ;
DEBUG_PRINTLN ( " Init AUX pin! " ) ;
}
if ( this - > m0Pin ! = - 1 ) {
// pinMode(this->m0Pin, OUTPUT);
DEBUG_PRINTLN ( " Init M0 pin! " ) ;
setMPins ( this - > m0Pin , HIGH ) ;
}
if ( this - > m1Pin ! = - 1 ) {
pinMode ( this - > m1Pin , OUTPUT ) ;
DEBUG_PRINTLN ( " Init M1 pin! " ) ;
setMPins ( this - > m1Pin , HIGH ) ;
}
DEBUG_PRINTLN ( " Begin ex " ) ;
if ( this - > hs ) {
DEBUG_PRINTLN ( " Begin Hardware Serial " ) ;
# ifdef HARDWARE_SERIAL_SELECTABLE_PIN
if ( this - > txE220pin ! = - 1 & & this - > rxE220pin ! = - 1 ) {
DEBUG_PRINTLN ( " PIN SELECTED!! " ) ;
this - > serialDef . begin ( * this - > hs , this - > bpsRate , this - > serialConfig , this - > txE220pin , this - > rxE220pin ) ;
} else {
this - > serialDef . begin ( * this - > hs , this - > bpsRate , this - > serialConfig ) ;
}
# endif
# ifndef HARDWARE_SERIAL_SELECTABLE_PIN
this - > serialDef . begin ( * this - > hs , this - > bpsRate ) ;
# endif
while ( ! this - > hs ) {
; // wait for serial port to connect. Needed for native USB
}
# ifdef ACTIVATE_SOFTWARE_SERIAL
} else if ( this - > ss ) {
DEBUG_PRINTLN ( " Begin Software Serial " ) ;
this - > serialDef . begin ( * this - > ss , this - > bpsRate ) ;
} else {
DEBUG_PRINTLN ( " Begin Software Serial Pin " ) ;
SoftwareSerial * mySerial = new SoftwareSerial ( ( int ) this - > txE220pin , ( int ) this - > rxE220pin ) ; // "RX TX" // @suppress("Abstract class cannot be instantiated")
this - > ss = mySerial ;
// SoftwareSerial mySerial(this->txE220pin, this->rxE220pin);
DEBUG_PRINT ( " RX Pin: " ) ;
DEBUG_PRINT ( ( int ) this - > txE220pin ) ;
DEBUG_PRINT ( " TX Pin: " ) ;
DEBUG_PRINTLN ( ( int ) this - > rxE220pin ) ;
this - > serialDef . begin ( * this - > ss , this - > bpsRate ) ;
# endif
}
this - > serialDef . stream - > setTimeout ( 100 ) ;
Status status = setMode ( MODE_0_NORMAL ) ;
2023-04-12 22:47:17 +02:00
return status ;
2023-02-13 22:59:42 +01:00
}
/*
Utility method to wait until module is doen tranmitting
a timeout is provided to avoid an infinite loop
*/
Status LoRa_E220 : : waitCompleteResponse ( unsigned long timeout , unsigned int waitNoAux ) {
Status result = E220_SUCCESS ;
unsigned long t = millis ( ) ;
// make darn sure millis() is not about to reach max data type limit and start over
if ( ( ( unsigned long ) ( t + timeout ) ) = = 0 ) {
t = 0 ;
}
// if AUX pin was supplied and look for HIGH state
// note you can omit using AUX if no pins are available, but you will have to use delay() to let module finish
if ( this - > auxPin ! = - 1 ) {
while ( digitalRead ( this - > auxPin ) = = LOW ) {
if ( ( millis ( ) - t ) > timeout ) {
result = ERR_E220_TIMEOUT ;
DEBUG_PRINTLN ( " Timeout error! " ) ;
return result ;
}
}
DEBUG_PRINTLN ( " AUX HIGH! " ) ;
}
else {
// if you can't use aux pin, use 4K7 pullup with Arduino
// you may need to adjust this value if transmissions fail
this - > managedDelay ( waitNoAux ) ;
DEBUG_PRINTLN ( F ( " Wait no AUX pin! " ) ) ;
}
// per data sheet control after aux goes high is 2ms so delay for at least that long)
this - > managedDelay ( 20 ) ;
DEBUG_PRINTLN ( F ( " Complete! " ) ) ;
return result ;
}
/*
delay ( ) in a library is not a good idea as it can stop interrupts
just poll internal time until timeout is reached
*/
void LoRa_E220 : : managedDelay ( unsigned long timeout ) {
unsigned long t = millis ( ) ;
// make darn sure millis() is not about to reach max data type limit and start over
if ( ( ( unsigned long ) ( t + timeout ) ) = = 0 ) {
t = 0 ;
}
while ( ( millis ( ) - t ) < timeout ) { }
}
/*
Method to indicate availability
*/
//int LoRa_E220::available(unsigned long timeout) {
int LoRa_E220 : : available ( ) {
// unsigned long t = millis();
//
// // make darn sure millis() is not about to reach max data type limit and start over
// if (((unsigned long) (t + timeout)) == 0){
// t = 0;
// }
//
// if (this->auxPin != -1) {
// if (digitalRead(this->auxPin) == HIGH){
// return 0;
// }else{
// while (digitalRead(this->auxPin) == LOW) {
// if ((millis() - t) > timeout){
// DEBUG_PRINTLN("Timeout error!");
// return 0;
// }
// }
// DEBUG_PRINTLN("AUX HIGH!");
// return 2;
// }
// }else{
return this - > serialDef . stream - > available ( ) ;
// }
}
/*
Method to indicate availability
*/
void LoRa_E220 : : flush ( ) {
this - > serialDef . stream - > flush ( ) ;
}
void LoRa_E220 : : cleanUARTBuffer ( )
{
// bool IsNull = true;
while ( this - > available ( ) )
{
// IsNull = false;
this - > serialDef . stream - > read ( ) ;
}
}
/*
Method to send a chunk of data provided data is in a struct - - my personal favorite as you
need not parse or worry about sprintf ( ) inability to handle floats
TTP : put your structure definition into a . h file and include in both the sender and reciever
sketches
NOTE : of your sender and receiver MCU ' s are different ( Teensy and Arduino ) caution on the data
types each handle ints floats differently
*/
Status LoRa_E220 : : sendStruct ( void * structureManaged , uint16_t size_ ) {
if ( size_ > MAX_SIZE_TX_PACKET + 2 ) {
return ERR_E220_PACKET_TOO_BIG ;
}
Status result = E220_SUCCESS ;
uint8_t len = this - > serialDef . stream - > write ( ( uint8_t * ) structureManaged , size_ ) ;
if ( len ! = size_ ) {
DEBUG_PRINT ( F ( " Send... len: " ) )
DEBUG_PRINT ( len ) ;
DEBUG_PRINT ( F ( " size: " ) )
DEBUG_PRINT ( size_ ) ;
if ( len = = 0 ) {
result = ERR_E220_NO_RESPONSE_FROM_DEVICE ;
} else {
result = ERR_E220_DATA_SIZE_NOT_MATCH ;
}
}
if ( result ! = E220_SUCCESS ) return result ;
result = this - > waitCompleteResponse ( 5000 , 5000 ) ;
if ( result ! = E220_SUCCESS ) return result ;
DEBUG_PRINT ( F ( " Clear buffer... " ) )
this - > cleanUARTBuffer ( ) ;
DEBUG_PRINTLN ( F ( " ok! " ) )
return result ;
}
/*
Method to get a chunk of data provided data is in a struct - - my personal favorite as you
need not parse or worry about sprintf ( ) inability to handle floats
TTP : put your structure definition into a . h file and include in both the sender and reciever
sketches
NOTE : of your sender and receiver MCU ' s are different ( Teensy and Arduino ) caution on the data
types each handle ints floats differently
*/
Status LoRa_E220 : : receiveStruct ( void * structureManaged , uint16_t size_ ) {
Status result = E220_SUCCESS ;
uint8_t len = this - > serialDef . stream - > readBytes ( ( uint8_t * ) structureManaged , size_ ) ;
DEBUG_PRINT ( " Available buffer: " ) ;
DEBUG_PRINT ( len ) ;
DEBUG_PRINT ( " structure size: " ) ;
DEBUG_PRINTLN ( size_ ) ;
if ( len ! = size_ ) {
if ( len = = 0 ) {
result = ERR_E220_NO_RESPONSE_FROM_DEVICE ;
} else {
result = ERR_E220_DATA_SIZE_NOT_MATCH ;
}
}
if ( result ! = E220_SUCCESS ) return result ;
result = this - > waitCompleteResponse ( 1000 ) ;
if ( result ! = E220_SUCCESS ) return result ;
return result ;
}
/*
method to set the mode ( program , normal , etc . )
*/
Status LoRa_E220 : : setMode ( MODE_TYPE mode ) {
// data sheet claims module needs some extra time after mode setting (2ms)
// most of my projects uses 10 ms, but 40ms is safer
this - > managedDelay ( 40 ) ;
if ( this - > m0Pin = = - 1 & & this - > m1Pin = = - 1 ) {
DEBUG_PRINTLN ( F ( " The M0 and M1 pins is not set, this mean that you are connect directly the pins as you need! " ) )
} else {
switch ( mode )
{
case MODE_0_NORMAL :
// Mode 0 | normal operation
setMPins ( this - > m0Pin , LOW ) ;
setMPins ( this - > m1Pin , LOW ) ;
DEBUG_PRINTLN ( " MODE NORMAL! " ) ;
break ;
case MODE_1_WOR_TRANSMITTER :
setMPins ( this - > m0Pin , HIGH ) ;
setMPins ( this - > m1Pin , LOW ) ;
DEBUG_PRINTLN ( " MODE WOR! " ) ;
break ;
case MODE_2_WOR_RECEIVER :
// case MODE_2_PROGRAM:
setMPins ( this - > m0Pin , LOW ) ;
setMPins ( this - > m1Pin , HIGH ) ;
DEBUG_PRINTLN ( " MODE RECEIVING! " ) ;
break ;
case MODE_3_CONFIGURATION :
// Mode 3 | Setting operation
setMPins ( this - > m0Pin , HIGH ) ;
setMPins ( this - > m1Pin , HIGH ) ;
DEBUG_PRINTLN ( " MODE SLEEP CONFIG! " ) ;
break ;
default :
return ERR_E220_INVALID_PARAM ;
}
}
// data sheet says 2ms later control is returned, let's give just a bit more time
// these modules can take time to activate pins
this - > managedDelay ( 40 ) ;
// wait until aux pin goes back low
Status res = this - > waitCompleteResponse ( 1000 ) ;
if ( res = = E220_SUCCESS ) {
this - > mode = mode ;
}
return res ;
}
MODE_TYPE LoRa_E220 : : getMode ( ) {
return this - > mode ;
}
void LoRa_E220 : : writeProgramCommand ( PROGRAM_COMMAND cmd , REGISTER_ADDRESS addr , PACKET_LENGHT pl ) {
uint8_t CMD [ 3 ] = { cmd , addr , pl } ;
uint8_t size = this - > serialDef . stream - > write ( CMD , 3 ) ;
DEBUG_PRINTLN ( size ) ;
this - > managedDelay ( 50 ) ; //need ti check
}
ResponseStructContainer LoRa_E220 : : getConfiguration ( ) {
ResponseStructContainer rc ;
rc . status . code = checkUARTConfiguration ( MODE_3_PROGRAM ) ;
if ( rc . status . code ! = E220_SUCCESS ) return rc ;
MODE_TYPE prevMode = this - > mode ;
rc . status . code = this - > setMode ( MODE_3_PROGRAM ) ;
if ( rc . status . code ! = E220_SUCCESS ) return rc ;
this - > writeProgramCommand ( READ_CONFIGURATION , REG_ADDRESS_CFG , PL_CONFIGURATION ) ;
rc . data = malloc ( sizeof ( Configuration ) ) ;
rc . status . code = this - > receiveStruct ( ( uint8_t * ) rc . data , sizeof ( Configuration ) ) ;
# ifdef LoRa_E220_DEBUG
this - > printParameters ( ( Configuration * ) rc . data ) ;
# endif
if ( rc . status . code ! = E220_SUCCESS ) {
this - > setMode ( prevMode ) ;
return rc ;
}
rc . status . code = this - > setMode ( prevMode ) ;
if ( rc . status . code ! = E220_SUCCESS ) return rc ;
if ( WRONG_FORMAT = = ( ( Configuration * ) rc . data ) - > COMMAND ) {
rc . status . code = ERR_E220_WRONG_FORMAT ;
}
if ( RETURNED_COMMAND ! = ( ( Configuration * ) rc . data ) - > COMMAND | | REG_ADDRESS_CFG ! = ( ( Configuration * ) rc . data ) - > STARTING_ADDRESS | | PL_CONFIGURATION ! = ( ( Configuration * ) rc . data ) - > LENGHT ) {
rc . status . code = ERR_E220_HEAD_NOT_RECOGNIZED ;
}
return rc ;
}
RESPONSE_STATUS LoRa_E220 : : checkUARTConfiguration ( MODE_TYPE mode ) {
if ( mode = = MODE_3_PROGRAM & & this - > bpsRate ! = UART_BPS_RATE_9600 ) {
return ERR_E220_WRONG_UART_CONFIG ;
}
return E220_SUCCESS ;
}
ResponseStatus LoRa_E220 : : setConfiguration ( Configuration configuration , PROGRAM_COMMAND saveType ) {
ResponseStatus rc ;
rc . code = checkUARTConfiguration ( MODE_3_PROGRAM ) ;
if ( rc . code ! = E220_SUCCESS ) return rc ;
MODE_TYPE prevMode = this - > mode ;
rc . code = this - > setMode ( MODE_3_PROGRAM ) ;
if ( rc . code ! = E220_SUCCESS ) return rc ;
// this->writeProgramCommand(saveType, REG_ADDRESS_CFG);
// configuration.HEAD = saveType;
configuration . COMMAND = saveType ;
configuration . STARTING_ADDRESS = REG_ADDRESS_CFG ;
configuration . LENGHT = PL_CONFIGURATION ;
rc . code = this - > sendStruct ( ( uint8_t * ) & configuration , sizeof ( Configuration ) ) ;
if ( rc . code ! = E220_SUCCESS ) {
this - > setMode ( prevMode ) ;
return rc ;
}
rc . code = this - > receiveStruct ( ( uint8_t * ) & configuration , sizeof ( Configuration ) ) ;
# ifdef LoRa_E220_DEBUG
this - > printParameters ( ( Configuration * ) & configuration ) ;
# endif
rc . code = this - > setMode ( prevMode ) ;
if ( rc . code ! = E220_SUCCESS ) return rc ;
if ( WRONG_FORMAT = = ( ( Configuration * ) & configuration ) - > COMMAND ) {
rc . code = ERR_E220_WRONG_FORMAT ;
}
if ( RETURNED_COMMAND ! = ( ( Configuration * ) & configuration ) - > COMMAND | | REG_ADDRESS_CFG ! = ( ( Configuration * ) & configuration ) - > STARTING_ADDRESS | | PL_CONFIGURATION ! = ( ( Configuration * ) & configuration ) - > LENGHT ) {
rc . code = ERR_E220_HEAD_NOT_RECOGNIZED ;
}
return rc ;
}
ResponseStructContainer LoRa_E220 : : getModuleInformation ( ) {
ResponseStructContainer rc ;
rc . status . code = checkUARTConfiguration ( MODE_3_PROGRAM ) ;
if ( rc . status . code ! = E220_SUCCESS ) return rc ;
MODE_TYPE prevMode = this - > mode ;
rc . status . code = this - > setMode ( MODE_3_PROGRAM ) ;
if ( rc . status . code ! = E220_SUCCESS ) return rc ;
this - > writeProgramCommand ( READ_CONFIGURATION , REG_ADDRESS_PID , PL_PID ) ;
rc . data = malloc ( sizeof ( ModuleInformation ) ) ;
// struct ModuleInformation *moduleInformation = (ModuleInformation *)malloc(sizeof(ModuleInformation));
rc . status . code = this - > receiveStruct ( ( uint8_t * ) rc . data , sizeof ( ModuleInformation ) ) ;
if ( rc . status . code ! = E220_SUCCESS ) {
this - > setMode ( prevMode ) ;
return rc ;
}
rc . status . code = this - > setMode ( prevMode ) ;
if ( rc . status . code ! = E220_SUCCESS ) return rc ;
// this->printParameters(*configuration);
if ( WRONG_FORMAT = = ( ( ModuleInformation * ) rc . data ) - > COMMAND ) {
rc . status . code = ERR_E220_WRONG_FORMAT ;
}
if ( RETURNED_COMMAND ! = ( ( ModuleInformation * ) rc . data ) - > COMMAND | | REG_ADDRESS_PID ! = ( ( ModuleInformation * ) rc . data ) - > STARTING_ADDRESS | | PL_PID ! = ( ( ModuleInformation * ) rc . data ) - > LENGHT ) {
rc . status . code = ERR_E220_HEAD_NOT_RECOGNIZED ;
}
DEBUG_PRINTLN ( " ---------------------------------------- " ) ;
DEBUG_PRINT ( F ( " HEAD: " ) ) ; DEBUG_PRINT ( ( ( ModuleInformation * ) rc . data ) - > COMMAND , BIN ) ; DEBUG_PRINT ( " " ) ; DEBUG_PRINT ( ( ( ModuleInformation * ) rc . data ) - > STARTING_ADDRESS , DEC ) ; DEBUG_PRINT ( " " ) ; DEBUG_PRINTLN ( ( ( ModuleInformation * ) rc . data ) - > LENGHT , HEX ) ;
DEBUG_PRINT ( F ( " Model no.: " ) ) ; DEBUG_PRINTLN ( ( ( ModuleInformation * ) rc . data ) - > model , HEX ) ;
DEBUG_PRINT ( F ( " Version : " ) ) ; DEBUG_PRINTLN ( ( ( ModuleInformation * ) rc . data ) - > version , HEX ) ;
DEBUG_PRINT ( F ( " Features : " ) ) ; DEBUG_PRINTLN ( ( ( ModuleInformation * ) rc . data ) - > features , HEX ) ;
DEBUG_PRINT ( F ( " Status : " ) ) ; DEBUG_PRINTLN ( rc . status . getResponseDescription ( ) ) ;
DEBUG_PRINTLN ( " ---------------------------------------- " ) ;
// if (rc.status.code!=E220_SUCCESS) return rc;
// rc.data = moduleInformation; // malloc(sizeof (moduleInformation));
return rc ;
}
ResponseStatus LoRa_E220 : : resetModule ( ) {
// ResponseStatus status;
//
// status.code = checkUARTConfiguration(MODE_2_PROGRAM);
// if (status.code!=E220_SUCCESS) return status;
//
// MODE_TYPE prevMode = this->mode;
//
// status.code = this->setMode(MODE_2_PROGRAM);
// if (status.code!=E220_SUCCESS) return status;
//
// this->writeProgramCommand(WRITE_RESET_MODULE);
//
// status.code = this->waitCompleteResponse(1000);
// if (status.code!=E220_SUCCESS) {
// this->setMode(prevMode);
// return status;
// }
//
//
// status.code = this->setMode(prevMode);
// if (status.code!=E220_SUCCESS) return status;
//
// return status;
DEBUG_PRINT ( F ( " No information to reset module! " ) ) ;
ResponseStatus status ;
status . code = ERR_E220_NOT_IMPLEMENT ;
return status ;
}
ResponseContainer LoRa_E220 : : receiveMessage ( ) {
return LoRa_E220 : : receiveMessageComplete ( false ) ;
}
ResponseContainer LoRa_E220 : : receiveMessageRSSI ( ) {
return LoRa_E220 : : receiveMessageComplete ( true ) ;
}
ResponseContainer LoRa_E220 : : receiveMessageComplete ( bool rssiEnabled ) {
ResponseContainer rc ;
rc . status . code = E220_SUCCESS ;
String tmpData = this - > serialDef . stream - > readString ( ) ;
DEBUG_PRINTLN ( tmpData ) ;
if ( rssiEnabled ) {
rc . rssi = tmpData . charAt ( tmpData . length ( ) - 1 ) ;
rc . data = tmpData . substring ( 0 , tmpData . length ( ) - 1 ) ;
} else {
rc . data = tmpData ;
}
this - > cleanUARTBuffer ( ) ;
if ( rc . status . code ! = E220_SUCCESS ) {
return rc ;
}
// rc.data = message; // malloc(sizeof (moduleInformation));
return rc ;
}
ResponseContainer LoRa_E220 : : receiveMessageUntil ( char delimiter ) {
ResponseContainer rc ;
rc . status . code = E220_SUCCESS ;
rc . data = this - > serialDef . stream - > readStringUntil ( delimiter ) ;
// this->cleanUARTBuffer();
if ( rc . status . code ! = E220_SUCCESS ) {
return rc ;
}
// rc.data = message; // malloc(sizeof (moduleInformation));
return rc ;
}
ResponseContainer LoRa_E220 : : receiveInitialMessage ( uint8_t size ) {
ResponseContainer rc ;
rc . status . code = E220_SUCCESS ;
char buff [ size ] ;
uint8_t len = this - > serialDef . stream - > readBytes ( buff , size ) ;
if ( len ! = size ) {
if ( len = = 0 ) {
rc . status . code = ERR_E220_NO_RESPONSE_FROM_DEVICE ;
} else {
rc . status . code = ERR_E220_DATA_SIZE_NOT_MATCH ;
}
return rc ;
}
rc . data = buff ; // malloc(sizeof (moduleInformation));
return rc ;
}
ResponseStructContainer LoRa_E220 : : receiveMessage ( const uint8_t size ) {
return LoRa_E220 : : receiveMessageComplete ( size , false ) ;
}
ResponseStructContainer LoRa_E220 : : receiveMessageRSSI ( const uint8_t size ) {
return LoRa_E220 : : receiveMessageComplete ( size , true ) ;
}
ResponseStructContainer LoRa_E220 : : receiveMessageComplete ( const uint8_t size , bool rssiEnabled ) {
ResponseStructContainer rc ;
rc . data = malloc ( size ) ;
rc . status . code = this - > receiveStruct ( ( uint8_t * ) rc . data , size ) ;
if ( rc . status . code ! = E220_SUCCESS ) {
return rc ;
}
if ( rssiEnabled ) {
char rssi [ 1 ] ;
this - > serialDef . stream - > readBytes ( rssi , 1 ) ;
rc . rssi = rssi [ 0 ] ;
}
this - > cleanUARTBuffer ( ) ;
return rc ;
}
ResponseStatus LoRa_E220 : : sendMessage ( const void * message , const uint8_t size ) {
ResponseStatus status ;
status . code = this - > sendStruct ( ( uint8_t * ) message , size ) ;
if ( status . code ! = E220_SUCCESS ) return status ;
return status ;
}
ResponseStatus LoRa_E220 : : sendMessage ( const String message ) {
DEBUG_PRINT ( F ( " Send message: " ) ) ;
DEBUG_PRINT ( message ) ;
byte size = message . length ( ) ; // sizeof(message.c_str())+1;
DEBUG_PRINT ( F ( " size: " ) ) ;
DEBUG_PRINTLN ( size ) ;
char messageFixed [ size ] ;
memcpy ( messageFixed , message . c_str ( ) , size ) ;
DEBUG_PRINTLN ( F ( " memcpy " ) ) ;
ResponseStatus status ;
status . code = this - > sendStruct ( ( uint8_t * ) & messageFixed , size ) ;
if ( status . code ! = E220_SUCCESS ) return status ;
// free(messageFixed);
return status ;
}
ResponseStatus LoRa_E220 : : sendFixedMessage ( byte ADDH , byte ADDL , byte CHAN , const String message ) {
// DEBUG_PRINT("String/size: ");
// DEBUG_PRINT(message);
// DEBUG_PRINT("/");
byte size = message . length ( ) ; // sizeof(message.c_str())+1;
// DEBUG_PRINTLN(size);
//
// #pragma pack(push, 1)
// struct FixedStransmissionString {
// byte ADDH = 0;
// byte ADDL = 0;
// byte CHAN = 0;
// char message[];
// } fixedStransmission;
// #pragma pack(pop)
//
// fixedStransmission.ADDH = ADDH;
// fixedStransmission.ADDL = ADDL;
// fixedStransmission.CHAN = CHAN;
// char* msg = (char*)message.c_str();
// memcpy(fixedStransmission.message, (char*)msg, size);
//// fixedStransmission.message = message;
//
// DEBUG_PRINT("Message: ");
// DEBUG_PRINTLN(fixedStransmission.message);
//
// ResponseStatus status;
// status.code = this->sendStruct((uint8_t *)&fixedStransmission, sizeof(fixedStransmission));
// if (status.code!=E220_SUCCESS) return status;
//
// return status;
char messageFixed [ size ] ;
memcpy ( messageFixed , message . c_str ( ) , size ) ;
return this - > sendFixedMessage ( ADDH , ADDL , CHAN , ( uint8_t * ) messageFixed , size ) ;
}
ResponseStatus LoRa_E220 : : sendBroadcastFixedMessage ( byte CHAN , const String message ) {
return this - > sendFixedMessage ( BROADCAST_ADDRESS , BROADCAST_ADDRESS , CHAN , message ) ;
}
typedef struct fixedStransmission
{
byte ADDH = 0 ;
byte ADDL = 0 ;
byte CHAN = 0 ;
unsigned char message [ ] ;
} FixedStransmission ;
FixedStransmission * init_stack ( int m ) {
FixedStransmission * st = ( FixedStransmission * ) malloc ( sizeof ( FixedStransmission ) + m * sizeof ( int ) ) ;
return st ;
}
ResponseStatus LoRa_E220 : : sendFixedMessage ( byte ADDH , byte ADDL , byte CHAN , const void * message , const uint8_t size ) {
// #pragma pack(push, 1)
// struct FixedStransmission {
// byte ADDH = 0;
// byte ADDL = 0;
// byte CHAN = 0;
// unsigned char message[];
// } fixedStransmission;
// #pragma pack(pop)
DEBUG_PRINT ( ADDH ) ;
FixedStransmission * fixedStransmission = init_stack ( size ) ;
// STACK *resize_stack(STACK *st, int m){
// if (m<=st->max){
// return st; /* Take sure do not kill old values */
// }
// STACK *st = (STACK *)realloc(sizeof(STACK)+m*sizeof(int));
// st->max = m;
// return st;
// }
fixedStransmission - > ADDH = ADDH ;
fixedStransmission - > ADDL = ADDL ;
fixedStransmission - > CHAN = CHAN ;
// fixedStransmission.message = &message;
memcpy ( fixedStransmission - > message , ( unsigned char * ) message , size ) ;
ResponseStatus status ;
status . code = this - > sendStruct ( ( uint8_t * ) fixedStransmission , size + 3 ) ;
free ( fixedStransmission ) ;
if ( status . code ! = E220_SUCCESS ) return status ;
return status ;
}
ConfigurationMessage * init_stack_conf ( int m ) {
ConfigurationMessage * st = ( ConfigurationMessage * ) malloc ( sizeof ( ConfigurationMessage ) + m * sizeof ( int ) ) ;
return st ;
}
ResponseStatus LoRa_E220 : : sendConfigurationMessage ( byte ADDH , byte ADDL , byte CHAN , Configuration * configuration , PROGRAM_COMMAND programCommand ) {
ResponseStatus rc ;
// rc.code = this->setMode(MODE_2_PROGRAM);
// if (rc.code!=E220_SUCCESS) return rc;
configuration - > COMMAND = programCommand ;
configuration - > STARTING_ADDRESS = REG_ADDRESS_CFG ;
configuration - > LENGHT = PL_CONFIGURATION ;
ConfigurationMessage * fixedStransmission = init_stack_conf ( sizeof ( Configuration ) ) ;
// fixedStransmission.message = &message;
memcpy ( fixedStransmission - > message , ( unsigned char * ) configuration , sizeof ( Configuration ) ) ;
fixedStransmission - > specialCommand1 = SPECIAL_WIFI_CONF_COMMAND ;
fixedStransmission - > specialCommand2 = SPECIAL_WIFI_CONF_COMMAND ;
DEBUG_PRINTLN ( sizeof ( Configuration ) + 2 ) ;
rc = sendFixedMessage ( ADDH , ADDL , CHAN , fixedStransmission , sizeof ( Configuration ) + 2 ) ;
//
// ResponseStatus status;
// status.code = this->sendStruct((uint8_t *)fixedStransmission, sizeof(Configuration)+5);
// if (status.code!=E220_SUCCESS) return status;
// free(fixedStransmission);
return rc ;
}
ResponseStatus LoRa_E220 : : sendBroadcastFixedMessage ( byte CHAN , const void * message , const uint8_t size ) {
return this - > sendFixedMessage ( 0xFF , 0xFF , CHAN , message , size ) ;
}
# define KeeLoq_NLF 0x3A5C742E
unsigned long LoRa_E220 : : encrypt ( unsigned long data )
{
unsigned long x = data ;
unsigned long r ;
int keyBitNo , index ;
unsigned long keyBitVal , bitVal ;
for ( r = 0 ; r < 528 ; r + + )
{
keyBitNo = r & 63 ;
if ( keyBitNo < 32 )
keyBitVal = bitRead ( this - > halfKeyloqKey , keyBitNo ) ; // key low
else
keyBitVal = bitRead ( this - > halfKeyloqKey , keyBitNo - 32 ) ; // key hight
index = 1 * bitRead ( x , 1 ) + 2 * bitRead ( x , 9 ) + 4 * bitRead ( x , 20 ) + 8 * bitRead ( x , 26 ) + 16 * bitRead ( x , 31 ) ;
bitVal = bitRead ( x , 0 ) ^ bitRead ( x , 16 ) ^ bitRead ( KeeLoq_NLF , index ) ^ keyBitVal ;
x = ( x > > 1 ) ^ bitVal < < 31 ;
}
return x ;
}
unsigned long LoRa_E220 : : decrypt ( unsigned long data )
{
unsigned long x = data ;
unsigned long r ;
int keyBitNo , index ;
unsigned long keyBitVal , bitVal ;
for ( r = 0 ; r < 528 ; r + + )
{
keyBitNo = ( 15 - r ) & 63 ;
if ( keyBitNo < 32 )
keyBitVal = bitRead ( this - > halfKeyloqKey , keyBitNo ) ; // key low
else
keyBitVal = bitRead ( this - > halfKeyloqKey , keyBitNo - 32 ) ; // key hight
index = 1 * bitRead ( x , 0 ) + 2 * bitRead ( x , 8 ) + 4 * bitRead ( x , 19 ) + 8 * bitRead ( x , 25 ) + 16 * bitRead ( x , 30 ) ;
bitVal = bitRead ( x , 31 ) ^ bitRead ( x , 15 ) ^ bitRead ( KeeLoq_NLF , index ) ^ keyBitVal ;
x = ( x < < 1 ) ^ bitVal ;
}
return x ;
}
# ifdef LoRa_E220_DEBUG
void LoRa_E220 : : printParameters ( struct Configuration * configuration ) {
DEBUG_PRINTLN ( " ---------------------------------------- " ) ;
DEBUG_PRINT ( F ( " HEAD : " ) ) ; DEBUG_PRINT ( configuration - > COMMAND , HEX ) ; DEBUG_PRINT ( " " ) ; DEBUG_PRINT ( configuration - > STARTING_ADDRESS , HEX ) ; DEBUG_PRINT ( " " ) ; DEBUG_PRINTLN ( configuration - > LENGHT , HEX ) ;
DEBUG_PRINTLN ( F ( " " ) ) ;
DEBUG_PRINT ( F ( " AddH : " ) ) ; DEBUG_PRINTLN ( configuration - > ADDH , HEX ) ;
DEBUG_PRINT ( F ( " AddL : " ) ) ; DEBUG_PRINTLN ( configuration - > ADDL , HEX ) ;
DEBUG_PRINTLN ( F ( " " ) ) ;
DEBUG_PRINT ( F ( " Chan : " ) ) ; DEBUG_PRINT ( configuration - > CHAN , DEC ) ; DEBUG_PRINT ( " -> " ) ; DEBUG_PRINTLN ( configuration - > getChannelDescription ( ) ) ;
DEBUG_PRINTLN ( F ( " " ) ) ;
DEBUG_PRINT ( F ( " SpeedParityBit : " ) ) ; DEBUG_PRINT ( configuration - > SPED . uartParity , BIN ) ; DEBUG_PRINT ( " -> " ) ; DEBUG_PRINTLN ( configuration - > SPED . getUARTParityDescription ( ) ) ;
DEBUG_PRINT ( F ( " SpeedUARTDatte : " ) ) ; DEBUG_PRINT ( configuration - > SPED . uartBaudRate , BIN ) ; DEBUG_PRINT ( " -> " ) ; DEBUG_PRINTLN ( configuration - > SPED . getUARTBaudRateDescription ( ) ) ;
DEBUG_PRINT ( F ( " SpeedAirDataRate : " ) ) ; DEBUG_PRINT ( configuration - > SPED . airDataRate , BIN ) ; DEBUG_PRINT ( " -> " ) ; DEBUG_PRINTLN ( configuration - > SPED . getAirDataRateDescription ( ) ) ;
DEBUG_PRINTLN ( F ( " " ) ) ;
DEBUG_PRINT ( F ( " OptionSubPacketSett: " ) ) ; DEBUG_PRINT ( configuration - > OPTION . subPacketSetting , BIN ) ; DEBUG_PRINT ( " -> " ) ; DEBUG_PRINTLN ( configuration - > OPTION . getSubPacketSetting ( ) ) ;
DEBUG_PRINT ( F ( " OptionTranPower : " ) ) ; DEBUG_PRINT ( configuration - > OPTION . transmissionPower , BIN ) ; DEBUG_PRINT ( " -> " ) ; DEBUG_PRINTLN ( configuration - > OPTION . getTransmissionPowerDescription ( ) ) ;
DEBUG_PRINT ( F ( " OptionRSSIAmbientNo: " ) ) ; DEBUG_PRINT ( configuration - > OPTION . RSSIAmbientNoise , BIN ) ; DEBUG_PRINT ( " -> " ) ; DEBUG_PRINTLN ( configuration - > OPTION . getRSSIAmbientNoiseEnable ( ) ) ;
DEBUG_PRINTLN ( F ( " " ) ) ;
DEBUG_PRINT ( F ( " TransModeWORPeriod : " ) ) ; DEBUG_PRINT ( configuration - > TRANSMISSION_MODE . WORPeriod , BIN ) ; DEBUG_PRINT ( " -> " ) ; DEBUG_PRINTLN ( configuration - > TRANSMISSION_MODE . getWORPeriodByParamsDescription ( ) ) ;
DEBUG_PRINT ( F ( " TransModeEnableLBT : " ) ) ; DEBUG_PRINT ( configuration - > TRANSMISSION_MODE . enableLBT , BIN ) ; DEBUG_PRINT ( " -> " ) ; DEBUG_PRINTLN ( configuration - > TRANSMISSION_MODE . getLBTEnableByteDescription ( ) ) ;
DEBUG_PRINT ( F ( " TransModeEnableRSSI: " ) ) ; DEBUG_PRINT ( configuration - > TRANSMISSION_MODE . enableRSSI , BIN ) ; DEBUG_PRINT ( " -> " ) ; DEBUG_PRINTLN ( configuration - > TRANSMISSION_MODE . getRSSIEnableByteDescription ( ) ) ;
DEBUG_PRINT ( F ( " TransModeFixedTrans: " ) ) ; DEBUG_PRINT ( configuration - > TRANSMISSION_MODE . fixedTransmission , BIN ) ; DEBUG_PRINT ( " -> " ) ; DEBUG_PRINTLN ( configuration - > TRANSMISSION_MODE . getFixedTransmissionDescription ( ) ) ;
DEBUG_PRINTLN ( " ---------------------------------------- " ) ;
}
# endif