@@ -25,8 +25,11 @@ const char mac_tx_ok[] PROGMEM = "mac_tx_ok";
2525const char mac_rx[] PROGMEM = " mac_rx" ;
2626const char mac_err[] PROGMEM = " mac_err" ;
2727const char rn2483[] PROGMEM = " RN2483" ;
28+ const char rn2483a[] PROGMEM = " RN2483A" ;
29+ const char rn2903[] PROGMEM = " RN2903" ;
30+ const char rn2903as[] PROGMEM = " RN2903AS" ;
2831
29- const char *const compare_table[] PROGMEM = {ok, on, off, accepted, mac_tx_ok, mac_rx, mac_err, rn2483};
32+ const char *const compare_table[] PROGMEM = {ok, on, off, accepted, mac_tx_ok, mac_rx, mac_err, rn2483, rn2483a, rn2903, rn2903as };
3033
3134#define CMP_OK 0
3235#define CMP_ON 1
@@ -36,6 +39,9 @@ const char *const compare_table[] PROGMEM = {ok, on, off, accepted, mac_tx_ok, m
3639#define CMP_MAC_RX 5
3740#define CMP_MAC_ERR 6
3841#define CMP_RN2483 7
42+ #define CMP_RN2483A 8
43+ #define CMP_RN2903 9
44+ #define CMP_RN2903AS 10
3945
4046// CMP OK
4147const char busy[] PROGMEM = " busy" ;
@@ -109,8 +115,9 @@ const char response_is_not_ok[] PROGMEM = "Response is not OK: ";
109115const char error_key_length[] PROGMEM = " One or more keys are of invalid length." ;
110116const char check_configuration[] PROGMEM = " Check your coverage, keys and backend status." ;
111117const char no_response[] PROGMEM = " No response from RN module." ;
118+ const char invalid_module[] PROGMEM = " Invalid module (must be RN2xx3[xx])." ;
112119
113- const char *const error_msg[] PROGMEM = {invalid_sf, invalid_fp, unexpected_response, send_command_failed, join_failed, join_not_accepted, personalize_not_accepted, response_is_not_ok, error_key_length, check_configuration, no_response};
120+ const char *const error_msg[] PROGMEM = {invalid_sf, invalid_fp, unexpected_response, send_command_failed, join_failed, join_not_accepted, personalize_not_accepted, response_is_not_ok, error_key_length, check_configuration, no_response, invalid_module };
114121
115122#define ERR_INVALID_SF 0
116123#define ERR_INVALID_FP 1
@@ -123,18 +130,21 @@ const char *const error_msg[] PROGMEM = {invalid_sf, invalid_fp, unexpected_resp
123130#define ERR_KEY_LENGTH 8
124131#define ERR_CHECK_CONFIGURATION 9
125132#define ERR_NO_RESPONSE 10
133+ #define ERR_INVALID_MODULE 11
126134
127135const char personalize_accepted[] PROGMEM = " Personalize accepted. Status: " ;
128136const char join_accepted[] PROGMEM = " Join accepted. Status: " ;
129137const char successful_transmission[] PROGMEM = " Successful transmission" ;
130138const char successful_transmission_received[] PROGMEM = " Successful transmission. Received " ;
139+ const char valid_module[] PROGMEM = " Valid module connected." ;
131140
132- const char *const success_msg[] PROGMEM = {personalize_accepted, join_accepted, successful_transmission, successful_transmission_received};
141+ const char *const success_msg[] PROGMEM = {personalize_accepted, join_accepted, successful_transmission, successful_transmission_received, valid_module };
133142
134143#define SCS_PERSONALIZE_ACCEPTED 0
135144#define SCS_JOIN_ACCEPTED 1
136145#define SCS_SUCCESSFUL_TRANSMISSION 2
137146#define SCS_SUCCESSFUL_TRANSMISSION_RECEIVED 3
147+ #define SCS_VALID_MODULE 4
138148
139149const char radio_prefix[] PROGMEM = " radio" ;
140150const char radio_set[] PROGMEM = " set" ;
@@ -381,6 +391,11 @@ size_t TheThingsNetwork::getHardwareEui(char *buffer, size_t size)
381391 return readResponse (SYS_TABLE, SYS_TABLE, SYS_GET_HWEUI, buffer, size);
382392}
383393
394+ size_t TheThingsNetwork::getVersion (char *buffer, size_t size)
395+ {
396+ return readResponse (SYS_TABLE, SYS_TABLE, SYS_GET_VER, buffer, size);
397+ }
398+
384399uint16_t TheThingsNetwork::getVDD ()
385400{
386401 if (readResponse (SYS_TABLE, SYS_TABLE, SYS_GET_VDD, buffer, sizeof (buffer)) > 0 ) {
@@ -632,22 +647,25 @@ void TheThingsNetwork::autoBaud()
632647
633648void TheThingsNetwork::reset (bool adr)
634649{
650+ // autobaud and send "sys reset"
635651 autoBaud ();
636652 readResponse (SYS_TABLE, SYS_RESET, buffer, sizeof (buffer));
637653
654+ // autobaud (again, because baudrate was reset with "sys reset") and get HW model and SW version
638655 autoBaud ();
639- readResponse (SYS_TABLE, SYS_TABLE, SYS_GET_VER, buffer, sizeof (buffer));
656+ getVersion ( buffer, sizeof (buffer));
640657
641658 // buffer contains "RN2xx3[xx] x.x.x ...", splitting model from version
642659 char *model = strtok (buffer, " " );
643660 debugPrintIndex (SHOW_MODEL, model);
644661 char *version = strtok (NULL , " " );
645662 debugPrintIndex (SHOW_VERSION, version);
646663
664+ // set DEVEUI as HWEUI
647665 readResponse (SYS_TABLE, SYS_TABLE, SYS_GET_HWEUI, buffer, sizeof (buffer));
648666 sendMacSet (MAC_DEVEUI, buffer);
667+ // set ADR
649668 setADR (adr);
650- this ->needsHardReset = false ;
651669}
652670
653671void TheThingsNetwork::resetHard (uint8_t resetPin){
@@ -671,9 +689,11 @@ void TheThingsNetwork::onMessage(void (*cb)(const uint8_t *payload, size_t size,
671689 messageCallback = cb;
672690}
673691
674- bool TheThingsNetwork::personalize (const char *devAddr, const char *nwkSKey, const char *appSKey)
692+ bool TheThingsNetwork::personalize (const char *devAddr, const char *nwkSKey, const char *appSKey, bool resetFirst )
675693{
676- reset (adr);
694+ if (resetFirst) {
695+ reset (adr);
696+ }
677697 if (strlen (devAddr) != 8 || strlen (appSKey) != 32 || strlen (nwkSKey) != 32 )
678698 {
679699 debugPrintMessage (ERR_MESSAGE, ERR_KEY_LENGTH);
@@ -703,9 +723,11 @@ bool TheThingsNetwork::personalize()
703723 return true ;
704724}
705725
706- bool TheThingsNetwork::provision (const char *appEui, const char *appKey)
726+ bool TheThingsNetwork::provision (const char *appEui, const char *appKey, bool resetFirst )
707727{
708- reset (adr);
728+ if (resetFirst) {
729+ reset (adr);
730+ }
709731 if (strlen (appEui) != 16 || strlen (appKey) != 32 )
710732 {
711733 debugPrintMessage (ERR_MESSAGE, ERR_KEY_LENGTH);
@@ -917,6 +939,34 @@ void TheThingsNetwork::showStatus()
917939 debugPrintIndex (SHOW_RX_DELAY_2, buffer);
918940}
919941
942+ bool TheThingsNetwork::checkValidModuleConnected (bool autoBaudFirst)
943+ {
944+ // check if we want to autobaud first
945+ if (autoBaudFirst)
946+ {
947+ autoBaud ();
948+ }
949+ // send "sys get ver" to check if (and what) module is connected
950+ getVersion (buffer, sizeof (buffer));
951+ // check if we got a response (whatever it might be)
952+ // needsHardReset flag is set by readLine() (called at some point down the line by getVersion())
953+ if (this ->needsHardReset )
954+ {
955+ return false ; // no response
956+ }
957+ // buffer contains "RN2xx3[xx] x.x.x ...", getting only model (RN2xx3[xx])
958+ char *model = strtok (buffer, " " );
959+ debugPrintIndex (SHOW_MODEL, model);
960+ // check if module is valid (must be RN2483, RN2483A, RN2903 or RN2903AS)
961+ if (pgmstrcmp (model, CMP_RN2483) == 0 || pgmstrcmp (model, CMP_RN2483A) == 0 || pgmstrcmp (model, CMP_RN2903) == 0 || pgmstrcmp (model, CMP_RN2903AS) == 0 )
962+ {
963+ debugPrintMessage (SUCCESS_MESSAGE, SCS_VALID_MODULE);
964+ return true ; // module responded and is valid (recognized/supported)
965+ }
966+ debugPrintMessage (ERR_MESSAGE, ERR_INVALID_MODULE);
967+ return false ; // module responded but is invalid (unrecognized/unsupported)
968+ }
969+
920970void TheThingsNetwork::configureEU868 ()
921971{
922972 sendMacSet (MAC_RX2, 3 , 869525000 );
0 commit comments