1 #include <twr_cmwx1zzabz.h> 
   15 #define TWR_CMWX1ZZABZ_DELAY_RUN 100 
   16 #define TWR_CMWX1ZZABZ_DELAY_INITIALIZATION_RESET_H 100 
   17 #define TWR_CMWX1ZZABZ_DELAY_INITIALIZATION_AT_COMMAND 100  
   18 #define TWR_CMWX1ZZABZ_DELAY_CONFIG_SAVE 100 
   19 #define TWR_CMWX1ZZABZ_DELAY_INITIALIZATION_REBOOT 500 
   20 #define TWR_CMWX1ZZABZ_DELAY_INITIALIZATION_AT_RESPONSE 100 
   21 #define TWR_CMWX1ZZABZ_DELAY_SEND_MESSAGE_RESPONSE 1500 
   22 #define TWR_CMWX1ZZABZ_DELAY_JOIN_RESPONSE 500  
   23 #define TWR_CMWX1ZZABZ_DELAY_LINK_CHECK_RESPONSE 4000 
   24 #define TWR_CMWX1ZZABZ_DELAY_CUSTOM_COMMAND_RESPONSE 100 
   26 #define TWR_CMWX1ZZABZ_TIMEOUT_CUSTOM_COMMAND_RESPONSE 500 
   27 #define TWR_CMWX1ZZABZ_TIMEOUT_LNCHECK 20000 
   28 #define TWR_CMWX1ZZABZ_TIMEOUT_JOIN 120000 
   31 const char *_init_commands[] =
 
   59 static void _twr_cmwx1zzabz_task(
void *param);
 
   63 static void _twr_cmwx1zzabz_save_config(
twr_cmwx1zzabz_t *
self, twr_cmwx1zzabz_config_index_t config_index);
 
   69     memset(
self, 0, 
sizeof(*
self));
 
   71     self->_uart_channel = uart_channel;
 
   74     twr_fifo_init(&self->_tx_fifo, self->_tx_fifo_buffer, 
sizeof(self->_tx_fifo_buffer));
 
   75     twr_fifo_init(&self->_rx_fifo, self->_rx_fifo_buffer, 
sizeof(self->_rx_fifo_buffer));
 
   83     self->_state = TWR_CMWX1ZZABZ_STATE_INITIALIZE;
 
   99     self->_custom_command = 
false;
 
  100     self->_link_check_command = 
false;
 
  101     self->_join_command = 
false;
 
  104     self->_state = TWR_CMWX1ZZABZ_STATE_INITIALIZE;
 
  116         self->_state = TWR_CMWX1ZZABZ_STATE_RECEIVE;
 
  122     self->_event_handler = event_handler;
 
  123     self->_event_param = event_param;
 
  128     if (self->_state == TWR_CMWX1ZZABZ_STATE_IDLE)
 
  143     self->_message_length = length;
 
  145     memcpy(self->_message_buffer, buffer, self->_message_length);
 
  147     self->_state = TWR_CMWX1ZZABZ_STATE_SEND_MESSAGE_COMMAND;
 
  161     self->_message_length = length;
 
  163     memcpy(self->_message_buffer, buffer, self->_message_length);
 
  165     self->_state = TWR_CMWX1ZZABZ_STATE_SEND_MESSAGE_CONFIRMED_COMMAND;
 
  174     self->_debug = debug;
 
  177 static size_t _twr_cmwx1zzabz_async_write(
twr_cmwx1zzabz_t *
self, 
const void *buffer, 
size_t length)
 
  189 static size_t _twr_cmwx1zzabz_write(
twr_cmwx1zzabz_t *
self, 
const void *buffer, 
size_t length)
 
  201 static void _twr_cmwx1zzabz_task(
void *param)
 
  207         switch (self->_state)
 
  209             case TWR_CMWX1ZZABZ_STATE_READY:
 
  211                 self->_state = TWR_CMWX1ZZABZ_STATE_IDLE;
 
  213                 if (self->_event_handler != NULL)
 
  220             case TWR_CMWX1ZZABZ_STATE_IDLE:
 
  222                 if (self->_save_config_mask != 0)
 
  224                     self->_state = TWR_CMWX1ZZABZ_STATE_CONFIG_SAVE_SEND;
 
  228                 if(self->_join_command)
 
  230                     self->_state = TWR_CMWX1ZZABZ_STATE_JOIN_SEND;
 
  234                 if(self->_custom_command)
 
  236                     self->_state = TWR_CMWX1ZZABZ_STATE_CUSTOM_COMMAND_SEND;
 
  240                 if(self->_link_check_command)
 
  242                     self->_state = TWR_CMWX1ZZABZ_STATE_LINK_CHECK_SEND;
 
  248             case TWR_CMWX1ZZABZ_STATE_RECEIVE:
 
  250                 self->_state = TWR_CMWX1ZZABZ_STATE_IDLE;
 
  252                 while (_twr_cmwx1zzabz_read_response(
self))
 
  254                     if (memcmp(self->_response, 
"+RECV=", 5) == 0)
 
  256                         self->_message_port = atoi(&self->_response[6]);
 
  258                         char *comma_search = strchr(self->_response, 
',');
 
  265                         self->_message_length = atoi(++comma_search);
 
  276                         if (self->_message_length > 
sizeof(self->_message_buffer))
 
  282                         bytes = 
twr_uart_async_read(self->_uart_channel, self->_message_buffer, self->_message_length);
 
  283                         if (bytes != self->_message_length)
 
  288                         if (self->_event_handler != NULL)
 
  293                     else if (memcmp(self->_response, 
"+ACK", 4) == 0)
 
  295                         if (self->_event_handler != NULL)
 
  300                     else if (memcmp(self->_response, 
"+NOACK", 4) == 0)
 
  302                         if (self->_event_handler != NULL)
 
  307                     else if (memcmp(self->_response, 
"+EVENT=2,2", 10) == 0)
 
  309                         if (self->_event_handler != NULL)
 
  317                     else if (memcmp(self->_response, 
"+EVENT=0,1", 10) == 0 || memcmp(self->_response, 
"+EVENT=0,0", 10) == 0)
 
  319                         self->_state = TWR_CMWX1ZZABZ_STATE_INITIALIZE;
 
  320                         self->_save_config_mask = 0;
 
  322                         if (self->_event_handler != NULL)
 
  324                             self->_event_handler(
self, TWR_CMWX1ZZABZ_EVENT_MODEM_FACTORY_RESET, self->_event_param);
 
  331             case TWR_CMWX1ZZABZ_STATE_ERROR:
 
  333                 self->_save_config_mask = 0;
 
  335                 if (self->_event_handler != NULL)
 
  340                 self->_state = TWR_CMWX1ZZABZ_STATE_INITIALIZE;
 
  344             case TWR_CMWX1ZZABZ_STATE_INITIALIZE:
 
  346                 self->_state = TWR_CMWX1ZZABZ_STATE_ERROR;
 
  347                 self->_init_command_index = 0;
 
  353                 char cmd_at[] = 
"AT\r";
 
  354                 size_t length = strlen(cmd_at);
 
  356                 _twr_cmwx1zzabz_write(
self, cmd_at, length);
 
  365                 if (_twr_cmwx1zzabz_async_write(
self, cmd_at, length) != length)
 
  370                 self->_state = TWR_CMWX1ZZABZ_STATE_INITIALIZE_AT_RESPONSE;
 
  376             case TWR_CMWX1ZZABZ_STATE_INITIALIZE_AT_RESPONSE:
 
  378                 _twr_cmwx1zzabz_read_response(
self);
 
  380                 if (strcmp(self->_response, 
"+OK\r") == 0)
 
  387                     self->_state = TWR_CMWX1ZZABZ_STATE_INITIALIZE_COMMAND_SEND;
 
  396                 self->_state = TWR_CMWX1ZZABZ_STATE_RECOVER_BAUDRATE_UART;
 
  400             case TWR_CMWX1ZZABZ_STATE_RECOVER_BAUDRATE_UART:
 
  402                 self->_state = TWR_CMWX1ZZABZ_STATE_ERROR;
 
  415                 char cmd_at[] = 
"AT\r";
 
  416                 _twr_cmwx1zzabz_write(
self, cmd_at, strlen(cmd_at));
 
  422                 char cmd_at_baud[] = 
"AT+UART=9600\r";
 
  423                 _twr_cmwx1zzabz_write(
self, cmd_at_baud, strlen(cmd_at_baud));
 
  429                 char cmd_at_reboot[] = 
"AT+REBOOT\r";
 
  430                 _twr_cmwx1zzabz_write(
self, cmd_at_reboot, strlen(cmd_at_reboot));
 
  440                 twr_fifo_init(&self->_tx_fifo, self->_tx_fifo_buffer, 
sizeof(self->_tx_fifo_buffer));
 
  441                 twr_fifo_init(&self->_rx_fifo, self->_rx_fifo_buffer, 
sizeof(self->_rx_fifo_buffer));
 
  447                 self->_state = TWR_CMWX1ZZABZ_STATE_INITIALIZE;
 
  453             case TWR_CMWX1ZZABZ_STATE_INITIALIZE_COMMAND_SEND:
 
  455                 self->_state = TWR_CMWX1ZZABZ_STATE_ERROR;
 
  460                 strcpy(self->_command, _init_commands[self->_init_command_index]);
 
  461                 size_t length = strlen(self->_command);
 
  463                 if (_twr_cmwx1zzabz_async_write(
self, self->_command, length) != length)
 
  468                 self->_state = TWR_CMWX1ZZABZ_STATE_INITIALIZE_COMMAND_RESPONSE;
 
  471                 if(strcmp(self->_command, 
"AT+REBOOT\r") == 0)
 
  483             case TWR_CMWX1ZZABZ_STATE_INITIALIZE_COMMAND_RESPONSE:
 
  485                 if (!_twr_cmwx1zzabz_read_response(
self))
 
  488                     if (
twr_tick_get() > (self->_timeout + TWR_CMWX1ZZABZ_TIMEOUT_CUSTOM_COMMAND_RESPONSE))
 
  490                         self->_state = TWR_CMWX1ZZABZ_STATE_ERROR;
 
  495                 self->_state = TWR_CMWX1ZZABZ_STATE_ERROR;
 
  496                 uint8_t response_handled = 0;
 
  499                 uint32_t response_valid = (memcmp(self->_response, 
"+OK=", 4) == 0);
 
  501                 const char *last_command = _init_commands[
self->_init_command_index];
 
  503                 char *response_string_value = &
self->_response[4];
 
  505                 if (strcmp(last_command, 
"AT+DEVADDR?\r") == 0 && response_valid)
 
  508                     if ((self->_save_config_mask & 1 << TWR_CMWX1ZZABZ_CONFIG_INDEX_DEVADDR) == 0)
 
  510                         memcpy(self->_config.devaddr, response_string_value, 8);
 
  511                         self->_config.devaddr[8] = 
'\0';
 
  513                     response_handled = 1;
 
  515                 else if (strcmp(last_command, 
"AT+DEVEUI?\r") == 0 && response_valid)
 
  517                     if ((self->_save_config_mask & 1 << TWR_CMWX1ZZABZ_CONFIG_INDEX_DEVEUI) == 0)
 
  519                         memcpy(self->_config.deveui, response_string_value, 16);
 
  520                         self->_config.deveui[16] = 
'\0';
 
  522                     response_handled = 1;
 
  524                 else if (strcmp(last_command, 
"AT+APPEUI?\r") == 0 && response_valid)
 
  526                     if ((self->_save_config_mask & 1 << TWR_CMWX1ZZABZ_CONFIG_INDEX_APPEUI) == 0)
 
  528                         memcpy(self->_config.appeui, response_string_value, 16);
 
  529                         self->_config.appeui[16] = 
'\0';
 
  531                     response_handled = 1;
 
  533                 else if (strcmp(last_command, 
"AT+NWKSKEY?\r") == 0 && response_valid)
 
  535                     if ((self->_save_config_mask & 1 << TWR_CMWX1ZZABZ_CONFIG_INDEX_NWKSKEY) == 0)
 
  537                         memcpy(self->_config.nwkskey, response_string_value, 32);
 
  538                         self->_config.nwkskey[32] = 
'\0';
 
  540                     response_handled = 1;
 
  542                 else if (strcmp(last_command, 
"AT+APPSKEY?\r") == 0 && response_valid)
 
  544                     if ((self->_save_config_mask & 1 << TWR_CMWX1ZZABZ_CONFIG_INDEX_APPSKEY) == 0)
 
  546                         memcpy(self->_config.appskey, response_string_value, 32);
 
  547                         self->_config.appskey[32] = 
'\0';
 
  549                     response_handled = 1;
 
  551                 else if (strcmp(last_command, 
"AT+APPKEY?\r") == 0 && response_valid)
 
  553                     if ((self->_save_config_mask & 1 << TWR_CMWX1ZZABZ_CONFIG_INDEX_APPKEY) == 0)
 
  555                         memcpy(self->_config.appkey, response_string_value, 32);
 
  556                         self->_config.appkey[32] = 
'\0';
 
  558                     response_handled = 1;
 
  560                 else if (strcmp(last_command, 
"AT+BAND?\r") == 0 && response_valid)
 
  562                     if ((self->_save_config_mask & 1 << TWR_CMWX1ZZABZ_CONFIG_INDEX_BAND) == 0)
 
  564                         self->_config.band = response_string_value[0] - 
'0';
 
  566                     response_handled = 1;
 
  568                 else if (strcmp(last_command, 
"AT+MODE?\r") == 0 && response_valid)
 
  570                     if ((self->_save_config_mask & 1 << TWR_CMWX1ZZABZ_CONFIG_INDEX_MODE) == 0)
 
  572                         self->_config.mode = response_string_value[0] - 
'0';
 
  574                     response_handled = 1;
 
  576                 else if (strcmp(last_command, 
"AT+CLASS?\r") == 0 && response_valid)
 
  578                     if ((self->_save_config_mask & 1 << TWR_CMWX1ZZABZ_CONFIG_INDEX_CLASS) == 0)
 
  580                         self->_config.class = response_string_value[0] - 
'0';
 
  582                     response_handled = 1;
 
  584                 else if (strcmp(last_command, 
"AT+RX2?\r") == 0 && response_valid)
 
  586                     if ((self->_save_config_mask & 1 << TWR_CMWX1ZZABZ_CONFIG_INDEX_RX2) == 0)
 
  588                         self->_config.rx2_frequency = atoi(response_string_value);
 
  590                         char *comma_search = strchr(response_string_value, 
',');
 
  596                         self->_config.rx2_datarate = atoi(++comma_search);
 
  598                     response_handled = 1;
 
  600                 else if (strcmp(last_command, 
"AT+NWK?\r") == 0 && response_valid)
 
  602                     if ((self->_save_config_mask & 1 << TWR_CMWX1ZZABZ_CONFIG_INDEX_NWK) == 0)
 
  604                         self->_config.nwk_public = response_string_value[0] - 
'0';
 
  606                     response_handled = 1;
 
  608                 else if (strcmp(last_command, 
"AT+ADR?\r") == 0 && response_valid)
 
  610                     if ((self->_save_config_mask & 1 << TWR_CMWX1ZZABZ_CONFIG_INDEX_ADAPTIVE_DATARATE) == 0)
 
  612                         self->_config.adaptive_datarate = response_string_value[0] == 
'1';
 
  614                     response_handled = 1;
 
  616                 else if (strcmp(last_command, 
"AT+DR?\r") == 0 && response_valid)
 
  618                     if ((self->_save_config_mask & 1 << TWR_CMWX1ZZABZ_CONFIG_INDEX_DATARATE) == 0)
 
  620                         self->_config.datarate = atoi(response_string_value);
 
  622                     response_handled = 1;
 
  624                 else if (strcmp(last_command, 
"AT+REP?\r") == 0 && response_valid)
 
  626                     if ((self->_save_config_mask & 1 << TWR_CMWX1ZZABZ_CONFIG_INDEX_REP) == 0)
 
  628                         self->_config.repetition_unconfirmed = atoi(response_string_value);
 
  630                     response_handled = 1;
 
  632                 else if (strcmp(last_command, 
"AT+RTYNUM?\r") == 0 && response_valid)
 
  634                     if ((self->_save_config_mask & 1 << TWR_CMWX1ZZABZ_CONFIG_INDEX_RTYNUM) == 0)
 
  636                         self->_config.repetition_confirmed = atoi(response_string_value);
 
  638                     response_handled = 1;
 
  640                 else if (strcmp(last_command, 
"AT+DUTYCYCLE=0\r") == 0 && strcmp(self->_response, 
"+ERR=-17\r") == 0)
 
  643                     response_handled = 1;
 
  645                 else if (strcmp(last_command, 
"AT+DWELL=0,0\r") == 0 && strcmp(self->_response, 
"+ERR=-17\r") == 0)
 
  648                     response_handled = 1;
 
  650                 else if (strcmp(last_command, 
"AT+JOINDC=0\r") == 0 && (strcmp(self->_response, 
"+ERR=-1\r") == 0 || strcmp(self->_response, 
"+ERR=-14\r") == 0 || strcmp(self->_response, 
"+ERR=-17\r") == 0))
 
  656                     response_handled = 1;
 
  658                 else if (strcmp(last_command, 
"AT+VER?\r") == 0 && memcmp(self->_response, 
"+OK=", 4) == 0)
 
  662                     char *comma = strchr(self->_response, 
',');
 
  665                         char *first_character = &
self->_response[4];
 
  666                         memset(self->_fw_version, 
'\0', 
sizeof(self->_fw_version));
 
  667                         int len = comma - first_character;
 
  668                         memcpy(self->_fw_version, first_character, len);
 
  670                     response_handled = 1;
 
  672                 else if (   strcmp(last_command, 
"AT\r") == 0 &&
 
  673                             strcmp(self->_response, 
"+OK\r") == 0
 
  676                     response_handled = 1;
 
  679                 else if (memcmp(self->_response, 
"+OK", 3) == 0)
 
  681                     response_handled = 1;
 
  684                 if (!response_handled)
 
  689                 self->_init_command_index++;
 
  691                 if (_init_commands[self->_init_command_index] == NULL)
 
  694                     if (self->_save_config_mask)
 
  696                         self->_state = TWR_CMWX1ZZABZ_STATE_CONFIG_SAVE_SEND;
 
  697                         self->_save_command_index = 0;
 
  701                         self->_state = TWR_CMWX1ZZABZ_STATE_READY;
 
  706                     self->_state = TWR_CMWX1ZZABZ_STATE_INITIALIZE_COMMAND_SEND;
 
  711             case TWR_CMWX1ZZABZ_STATE_SEND_MESSAGE_COMMAND:
 
  712             case TWR_CMWX1ZZABZ_STATE_SEND_MESSAGE_CONFIRMED_COMMAND:
 
  714                 if (self->_state == TWR_CMWX1ZZABZ_STATE_SEND_MESSAGE_CONFIRMED_COMMAND)
 
  716                     snprintf(self->_command, TWR_CMWX1ZZABZ_TX_FIFO_BUFFER_SIZE, 
"AT+PCTX %d,%d\r", self->_tx_port, self->_message_length);
 
  720                     snprintf(self->_command, TWR_CMWX1ZZABZ_TX_FIFO_BUFFER_SIZE, 
"AT+PUTX %d,%d\r", self->_tx_port, self->_message_length);
 
  723                 self->_state = TWR_CMWX1ZZABZ_STATE_ERROR;
 
  725                 uint8_t command_length = strlen(self->_command);
 
  727                 for (
size_t i = 0; i < 
self->_message_length; i++)
 
  730                     self->_command[command_length + i] = 
self->_message_buffer[i];
 
  733                 self->_command[command_length + 
self->_message_length] = 
'\r';
 
  735                 size_t length = command_length + 
self->_message_length + 1; 
 
  737                 if (_twr_cmwx1zzabz_async_write(
self, self->_command, length) != length)
 
  742                 self->_state = TWR_CMWX1ZZABZ_STATE_SEND_MESSAGE_RESPONSE;
 
  744                 if (self->_event_handler != NULL)
 
  753             case TWR_CMWX1ZZABZ_STATE_SEND_MESSAGE_RESPONSE:
 
  755                 self->_state = TWR_CMWX1ZZABZ_STATE_ERROR;
 
  757                 if (!_twr_cmwx1zzabz_read_response(
self))
 
  762                 if (strcmp(self->_response, 
"+OK\r") != 0)
 
  767                 self->_state = TWR_CMWX1ZZABZ_STATE_IDLE;
 
  769                 if (self->_event_handler != NULL)
 
  776             case TWR_CMWX1ZZABZ_STATE_CONFIG_SAVE_SEND:
 
  778                 self->_state = TWR_CMWX1ZZABZ_STATE_ERROR;
 
  781                 if (self->_save_config_mask == 0)
 
  783                     if (self->_event_handler != NULL)
 
  788                     self->_state = TWR_CMWX1ZZABZ_STATE_READY;
 
  793                 for (uint8_t i = 0; i < TWR_CMWX1ZZABZ_CONFIG_INDEX_LAST_ITEM; i++)
 
  795                     if (self->_save_config_mask & 1 << i)
 
  797                         self->_save_command_index = i;
 
  805                 switch (self->_save_command_index)
 
  807                     case TWR_CMWX1ZZABZ_CONFIG_INDEX_DEVADDR:
 
  809                         snprintf(self->_command, TWR_CMWX1ZZABZ_TX_FIFO_BUFFER_SIZE, 
"AT+DEVADDR=%s\r", self->_config.devaddr);
 
  812                     case TWR_CMWX1ZZABZ_CONFIG_INDEX_DEVEUI:
 
  814                         snprintf(self->_command, TWR_CMWX1ZZABZ_TX_FIFO_BUFFER_SIZE, 
"AT+DEVEUI=%s\r", self->_config.deveui);
 
  817                     case TWR_CMWX1ZZABZ_CONFIG_INDEX_APPEUI:
 
  819                         snprintf(self->_command, TWR_CMWX1ZZABZ_TX_FIFO_BUFFER_SIZE, 
"AT+APPEUI=%s\r", self->_config.appeui);
 
  822                     case TWR_CMWX1ZZABZ_CONFIG_INDEX_NWKSKEY:
 
  824                         snprintf(self->_command, TWR_CMWX1ZZABZ_TX_FIFO_BUFFER_SIZE, 
"AT+NWKSKEY=%s\r", self->_config.nwkskey);
 
  827                     case TWR_CMWX1ZZABZ_CONFIG_INDEX_APPSKEY:
 
  829                         snprintf(self->_command, TWR_CMWX1ZZABZ_TX_FIFO_BUFFER_SIZE, 
"AT+APPSKEY=%s\r", self->_config.appskey);
 
  832                     case TWR_CMWX1ZZABZ_CONFIG_INDEX_APPKEY:
 
  834                         snprintf(self->_command, TWR_CMWX1ZZABZ_TX_FIFO_BUFFER_SIZE, 
"AT+APPKEY=%s\r", self->_config.appkey);
 
  837                     case TWR_CMWX1ZZABZ_CONFIG_INDEX_BAND:
 
  839                         snprintf(self->_command, TWR_CMWX1ZZABZ_TX_FIFO_BUFFER_SIZE, 
"AT+BAND=%d\r", self->_config.band);
 
  842                     case TWR_CMWX1ZZABZ_CONFIG_INDEX_MODE:
 
  844                         snprintf(self->_command, TWR_CMWX1ZZABZ_TX_FIFO_BUFFER_SIZE, 
"AT+MODE=%d\r", self->_config.mode);
 
  847                     case TWR_CMWX1ZZABZ_CONFIG_INDEX_CLASS:
 
  849                         snprintf(self->_command, TWR_CMWX1ZZABZ_TX_FIFO_BUFFER_SIZE, 
"AT+CLASS=%d\r", self->_config.class);
 
  852                     case TWR_CMWX1ZZABZ_CONFIG_INDEX_RX2:
 
  854                         snprintf(self->_command, TWR_CMWX1ZZABZ_TX_FIFO_BUFFER_SIZE, 
"AT+RX2=%d,%d\r", (
int) self->_config.rx2_frequency, self->_config.rx2_datarate);
 
  857                     case TWR_CMWX1ZZABZ_CONFIG_INDEX_NWK:
 
  859                         snprintf(self->_command, TWR_CMWX1ZZABZ_TX_FIFO_BUFFER_SIZE, 
"AT+NWK=%d\r", (
int) self->_config.nwk_public);
 
  862                     case TWR_CMWX1ZZABZ_CONFIG_INDEX_ADAPTIVE_DATARATE:
 
  864                         snprintf(self->_command, TWR_CMWX1ZZABZ_TX_FIFO_BUFFER_SIZE, 
"AT+ADR=%d\r", self->_config.adaptive_datarate ? 1 : 0);
 
  867                     case TWR_CMWX1ZZABZ_CONFIG_INDEX_DATARATE:
 
  869                         snprintf(self->_command, TWR_CMWX1ZZABZ_TX_FIFO_BUFFER_SIZE, 
"AT+DR=%d\r", (
int) self->_config.datarate);
 
  872                     case TWR_CMWX1ZZABZ_CONFIG_INDEX_REP:
 
  874                         snprintf(self->_command, TWR_CMWX1ZZABZ_TX_FIFO_BUFFER_SIZE, 
"AT+REP=%d\r", (
int) self->_config.repetition_unconfirmed);
 
  877                     case TWR_CMWX1ZZABZ_CONFIG_INDEX_RTYNUM:
 
  879                         snprintf(self->_command, TWR_CMWX1ZZABZ_TX_FIFO_BUFFER_SIZE, 
"AT+RTYNUM=%d\r", (
int) self->_config.repetition_confirmed);
 
  889                 size_t length = strlen(self->_command);
 
  891                 if (_twr_cmwx1zzabz_async_write(
self, self->_command, length) != length)
 
  896                 self->_state = TWR_CMWX1ZZABZ_STATE_CONFIG_SAVE_RESPONSE;
 
  901             case TWR_CMWX1ZZABZ_STATE_CONFIG_SAVE_RESPONSE:
 
  903                 self->_state = TWR_CMWX1ZZABZ_STATE_ERROR;
 
  905                 if (!_twr_cmwx1zzabz_read_response(
self))
 
  911                 if (memcmp(self->_response, 
"+OK", 3) != 0)
 
  917                 self->_save_config_mask &= ~(1 << 
self->_save_command_index);
 
  919                 self->_state = TWR_CMWX1ZZABZ_STATE_CONFIG_SAVE_SEND;
 
  924             case TWR_CMWX1ZZABZ_STATE_JOIN_SEND:
 
  926                 self->_state = TWR_CMWX1ZZABZ_STATE_ERROR;
 
  931                 strcpy(self->_command, 
"AT+JOIN\r");
 
  933                 size_t length = strlen(self->_command);
 
  934                 if (_twr_cmwx1zzabz_async_write(
self, self->_command, length) != length)
 
  940                 self->_join_command = 
false;
 
  942                 self->_state = TWR_CMWX1ZZABZ_STATE_JOIN_RESPONSE;
 
  948             case TWR_CMWX1ZZABZ_STATE_JOIN_RESPONSE:
 
  950                 bool join_successful = 
false;
 
  952                 if (!_twr_cmwx1zzabz_read_response(
self))
 
  955                     if (
twr_tick_get() > (self->_timeout + TWR_CMWX1ZZABZ_TIMEOUT_JOIN))
 
  957                         self->_state = TWR_CMWX1ZZABZ_STATE_ERROR;
 
  962                 if (memcmp(self->_response, 
"+OK", 3) == 0)
 
  969                 if (memcmp(self->_response, 
"+ERR=-7", 7) == 0)
 
  971                     self->_state = TWR_CMWX1ZZABZ_STATE_ERROR;
 
  976                 if (memcmp(self->_response, 
"+EVENT=1,1", 10) == 0)
 
  978                     join_successful = 
true;
 
  983                     if (self->_event_handler != NULL)
 
  990                     if (self->_event_handler != NULL)
 
  996                 self->_state = TWR_CMWX1ZZABZ_STATE_IDLE;
 
 1000             case TWR_CMWX1ZZABZ_STATE_LINK_CHECK_SEND:
 
 1002                 self->_state = TWR_CMWX1ZZABZ_STATE_ERROR;
 
 1007                 strcpy(self->_command, 
"AT+LNCHECK\r");
 
 1009                 size_t length = strlen(self->_command);
 
 1010                 if (_twr_cmwx1zzabz_async_write(
self, self->_command, length) != length)
 
 1015                 self->_link_check_command = 
false;
 
 1017                 self->_state = TWR_CMWX1ZZABZ_STATE_LINK_CHECK_RESPONSE;
 
 1023             case TWR_CMWX1ZZABZ_STATE_LINK_CHECK_RESPONSE:
 
 1025                 if (!_twr_cmwx1zzabz_read_response(
self))
 
 1028                     if (
twr_tick_get() > (self->_timeout + TWR_CMWX1ZZABZ_TIMEOUT_LNCHECK))
 
 1030                         self->_state = TWR_CMWX1ZZABZ_STATE_ERROR;
 
 1035                 if (memcmp(self->_response, 
"+OK", 3) == 0)
 
 1042                 if (strstr(self->_response, 
"+EVENT=2,") > (
char *)0)
 
 1045                     char *event_str = strchr(self->_response, 
',');
 
 1048                     uint8_t link_check_event = atoi(event_str);
 
 1051                     self->_cmd_link_check_gwcnt = 0;
 
 1052                     self->_cmd_link_check_margin = 0;
 
 1054                     if (link_check_event == 1)
 
 1056                         self->_state = TWR_CMWX1ZZABZ_STATE_LINK_CHECK_RESPONSE_ANS;
 
 1064                     self->_state = TWR_CMWX1ZZABZ_STATE_ERROR;
 
 1068                 self->_state = TWR_CMWX1ZZABZ_STATE_IDLE;
 
 1070                 if (self->_event_handler != NULL)
 
 1072                     self->_event_handler(
self, TWR_CMWX1ZZABZ_EVENT_LINK_CHECK_NOK, self->_event_param);
 
 1079             case TWR_CMWX1ZZABZ_STATE_LINK_CHECK_RESPONSE_ANS:
 
 1082                 if (_twr_cmwx1zzabz_read_response(
self))
 
 1085                     char *ans = strstr(self->_response, 
"+ANS=2,");
 
 1090                         self->_cmd_link_check_margin = atoi(ans);
 
 1093                         char *gwcnt_str = strchr(ans, 
',');
 
 1096                         self->_cmd_link_check_gwcnt = atoi(gwcnt_str);
 
 1100                 self->_state = TWR_CMWX1ZZABZ_STATE_IDLE;
 
 1102                 if (self->_event_handler != NULL)
 
 1104                     self->_event_handler(
self, TWR_CMWX1ZZABZ_EVENT_LINK_CHECK_OK, self->_event_param);
 
 1111             case TWR_CMWX1ZZABZ_STATE_CUSTOM_COMMAND_SEND:
 
 1113                 self->_state = TWR_CMWX1ZZABZ_STATE_ERROR;
 
 1118                 strcpy(self->_command, self->_custom_command_buf);
 
 1120                 size_t length = strlen(self->_command);
 
 1121                 if (_twr_cmwx1zzabz_async_write(
self, self->_command, length) != length)
 
 1126                 self->_state = TWR_CMWX1ZZABZ_STATE_CUSTOM_COMMAND_RESPONSE;
 
 1132             case TWR_CMWX1ZZABZ_STATE_CUSTOM_COMMAND_RESPONSE:
 
 1134                 if (!_twr_cmwx1zzabz_read_response(
self))
 
 1137                     if (
twr_tick_get() > (self->_timeout + TWR_CMWX1ZZABZ_TIMEOUT_CUSTOM_COMMAND_RESPONSE))
 
 1139                         self->_custom_command = 
false;
 
 1140                         self->_state = TWR_CMWX1ZZABZ_STATE_ERROR;
 
 1142                         if (strcmp(self->_command, 
"AT+FACNEW\r") == 0)
 
 1145                             self->_state = TWR_CMWX1ZZABZ_STATE_INITIALIZE;
 
 1152                 self->_state = TWR_CMWX1ZZABZ_STATE_IDLE; 
 
 1153                 self->_custom_command = 
false;
 
 1157                 if (memcmp(self->_response, 
"+ERR=-1", 7) == 0)
 
 1159                     self->_state = TWR_CMWX1ZZABZ_STATE_IDLE;
 
 1160                     self->_cmd_frmcnt_uplink = 0;
 
 1161                     self->_cmd_frmcnt_downlink = 0;
 
 1165                 if (memcmp(self->_response, 
"+OK=", 4) == 0)
 
 1172                     if (strcmp(self->_custom_command_buf, 
"AT+RFQ?\r") == 0)
 
 1175                         char *rssi_str = strchr(self->_response, 
'=');
 
 1178                         char *snr_str = strchr(self->_response, 
',');
 
 1181                         self->_cmd_rfq_rssi = atoi(rssi_str);
 
 1182                         self->_cmd_rfq_snr = atoi(snr_str);
 
 1186                     if (strcmp(self->_custom_command_buf, 
"AT+FRMCNT?\r") == 0)
 
 1189                         char *uplink_str = strchr(self->_response, 
'=');
 
 1192                         char *downlink_str = strchr(self->_response, 
',');
 
 1195                         self->_cmd_frmcnt_uplink = atoi(uplink_str);
 
 1196                         self->_cmd_frmcnt_downlink = atoi(downlink_str);
 
 1200                     self->_state = TWR_CMWX1ZZABZ_STATE_IDLE;
 
 1202                     if (self->_event_handler != NULL)
 
 1204                         self->_event_handler(
self, event, self->_event_param);
 
 1212             case TWR_CMWX1ZZABZ_STATE_RECOVER_BAUDRATE_REBOOT:
 
 1228     self->_join_command = 
true;
 
 1234     self->_tx_port = port;
 
 1239     return self->_tx_port;
 
 1244     strncpy(self->_config.devaddr, devaddr, 8+1);
 
 1246     _twr_cmwx1zzabz_save_config(
self, TWR_CMWX1ZZABZ_CONFIG_INDEX_DEVADDR);
 
 1251     strncpy(devaddr, self->_config.devaddr, 8+1);
 
 1256     strncpy(self->_config.deveui, deveui, 16+1);
 
 1258     _twr_cmwx1zzabz_save_config(
self, TWR_CMWX1ZZABZ_CONFIG_INDEX_DEVEUI);
 
 1263     strncpy(deveui, self->_config.deveui, 16+1);
 
 1268     strncpy(self->_config.appeui, appeui, 16+1);
 
 1270     _twr_cmwx1zzabz_save_config(
self, TWR_CMWX1ZZABZ_CONFIG_INDEX_APPEUI);
 
 1275     strncpy(appeui, self->_config.appeui, 16+1);
 
 1280     strncpy(self->_config.nwkskey, nwkskey, 32);
 
 1282     _twr_cmwx1zzabz_save_config(
self, TWR_CMWX1ZZABZ_CONFIG_INDEX_NWKSKEY);
 
 1287     strncpy(nwkskey, self->_config.nwkskey, 32+1);
 
 1292     strncpy(self->_config.appskey, appskey, 32);
 
 1294     _twr_cmwx1zzabz_save_config(
self, TWR_CMWX1ZZABZ_CONFIG_INDEX_APPSKEY);
 
 1299     strncpy(appskey, self->_config.appskey, 32+1);
 
 1304     strncpy(self->_config.appkey, appkey, 32+1);
 
 1306     _twr_cmwx1zzabz_save_config(
self, TWR_CMWX1ZZABZ_CONFIG_INDEX_APPKEY);
 
 1311     strncpy(appkey, self->_config.appkey, 32+1);
 
 1316     self->_config.band = band;
 
 1318     _twr_cmwx1zzabz_save_config(
self, TWR_CMWX1ZZABZ_CONFIG_INDEX_BAND);
 
 1323     return self->_config.band;
 
 1328     self->_config.mode = mode;
 
 1330     _twr_cmwx1zzabz_save_config(
self, TWR_CMWX1ZZABZ_CONFIG_INDEX_MODE);
 
 1335     return self->_config.mode;
 
 1340     self->_config.class = 
class;
 
 1342     _twr_cmwx1zzabz_save_config(
self, TWR_CMWX1ZZABZ_CONFIG_INDEX_CLASS);
 
 1347     return self->_config.class;
 
 1352     return self->_message_port;
 
 1357     return self->_message_length;
 
 1362     if (self->_message_length > buffer_size)
 
 1367     memcpy(buffer, self->_message_buffer, self->_message_length);
 
 1369     return self->_message_length;
 
 1374     self->_config.rx2_frequency = frequency;
 
 1376     self->_config.rx2_datarate = datarate;
 
 1378     _twr_cmwx1zzabz_save_config(
self, TWR_CMWX1ZZABZ_CONFIG_INDEX_RX2);
 
 1383     *frequency = 
self->_config.rx2_frequency;
 
 1384     *datarate = 
self->_config.rx2_datarate;
 
 1389     self->_config.nwk_public = 
public;
 
 1391     _twr_cmwx1zzabz_save_config(
self, TWR_CMWX1ZZABZ_CONFIG_INDEX_NWK);
 
 1396     return self->_config.nwk_public;
 
 1401     self->_config.adaptive_datarate = enable;
 
 1403     _twr_cmwx1zzabz_save_config(
self, TWR_CMWX1ZZABZ_CONFIG_INDEX_ADAPTIVE_DATARATE);
 
 1408     return self->_config.adaptive_datarate;
 
 1413     self->_config.datarate = datarate;
 
 1415     _twr_cmwx1zzabz_save_config(
self, TWR_CMWX1ZZABZ_CONFIG_INDEX_DATARATE);
 
 1420     return self->_config.datarate;
 
 1425     self->_config.repetition_unconfirmed = repeat;
 
 1427     _twr_cmwx1zzabz_save_config(
self, TWR_CMWX1ZZABZ_CONFIG_INDEX_REP);
 
 1432     return self->_config.repetition_unconfirmed;
 
 1437     self->_config.repetition_confirmed = repeat;
 
 1439     _twr_cmwx1zzabz_save_config(
self, TWR_CMWX1ZZABZ_CONFIG_INDEX_RTYNUM);
 
 1444     return self->_config.repetition_confirmed;
 
 1449     return self->_command;
 
 1454     return self->_response;
 
 1459     if (self->_custom_command)
 
 1464     self->_custom_command = 
true;
 
 1465     snprintf(self->_custom_command_buf, 
sizeof(self->_custom_command_buf), 
"%s\r", at_command);
 
 1474     if (self->_custom_command)
 
 1479     self->_custom_command = 
true;
 
 1480     strcpy(self->_custom_command_buf, 
"AT+RFQ?\r");
 
 1489     *rssi = 
self->_cmd_rfq_rssi;
 
 1490     *snr = 
self->_cmd_rfq_snr;
 
 1497     if (self->_custom_command)
 
 1502     self->_custom_command = 
true;
 
 1503     strcpy(self->_custom_command_buf, 
"AT+FRMCNT?\r");
 
 1512     *uplink = 
self->_cmd_frmcnt_uplink;
 
 1513     *downlink = 
self->_cmd_frmcnt_downlink;
 
 1520     if (self->_custom_command)
 
 1525     self->_custom_command = 
true;
 
 1526     strcpy(self->_custom_command_buf, 
"AT+FACNEW\r");
 
 1535     return self->_fw_version;
 
 1540     if (self->_state != TWR_CMWX1ZZABZ_STATE_IDLE)
 
 1545     self->_link_check_command = 
true;
 
 1554     *margin = 
self->_cmd_link_check_margin;
 
 1555     *gateway_count = 
self->_cmd_link_check_gwcnt;
 
 1571         if (rx_character == 
'\n')
 
 1576         self->_response[
self->_response_length++] = rx_character;
 
 1578         if (rx_character == 
'\r')
 
 1580             if (self->_response_length == 1)
 
 1582                 self->_response_length = 0;
 
 1587             self->_response[
self->_response_length] = 
'\0';
 
 1592         if (self->_response_length == 
sizeof(self->_response) - 1)
 
 1603     self->_response_length = 0;
 
 1608 static void _twr_cmwx1zzabz_save_config(
twr_cmwx1zzabz_t *
self, twr_cmwx1zzabz_config_index_t config_index)
 
 1610     self->_save_config_mask |= 1 << config_index;
 
 1612     if (self->_state == TWR_CMWX1ZZABZ_STATE_IDLE)
 
void twr_cmwx1zzabz_set_adaptive_datarate(twr_cmwx1zzabz_t *self, bool enable)
Set the configuration adaptive data rate.
bool twr_cmwx1zzabz_link_check(twr_cmwx1zzabz_t *self)
Request send of link check packet.
void twr_cmwx1zzabz_set_appeui(twr_cmwx1zzabz_t *self, char *appeui)
Set APPEUI.
void twr_cmwx1zzabz_get_deveui(twr_cmwx1zzabz_t *self, char *deveui)
Get DEVEUI.
void twr_cmwx1zzabz_init(twr_cmwx1zzabz_t *self, twr_uart_channel_t uart_channel)
Initialize CMWX1ZZABZ.
char * twr_cmwx1zzabz_get_error_command(twr_cmwx1zzabz_t *self)
Get pointer to string containg last sent command.
uint8_t twr_cmwx1zzabz_get_nwk_public(twr_cmwx1zzabz_t *self)
Get the configuration if public networks are enabled.
void twr_cmwx1zzabz_set_rx2(twr_cmwx1zzabz_t *self, uint32_t frequency, uint8_t datarate)
Set the frequency and datarate for RX2 receive window.
void twr_cmwx1zzabz_set_nwkskey(twr_cmwx1zzabz_t *self, char *nwkskey)
Set NWKSKEY.
void twr_cmwx1zzabz_get_appkey(twr_cmwx1zzabz_t *self, char *appkey)
Get APPKEY.
uint8_t twr_cmwx1zzabz_get_datarate(twr_cmwx1zzabz_t *self)
Get the configuration of datarate.
bool twr_cmwx1zzabz_send_message(twr_cmwx1zzabz_t *self, const void *buffer, size_t length)
Send LoRa message.
void twr_cmwx1zzabz_set_debug(twr_cmwx1zzabz_t *self, bool debug)
Set debugging flag which prints modem communication to twr_log.
void twr_cmwx1zzabz_get_nwkskey(twr_cmwx1zzabz_t *self, char *nwkskey)
Set NWKSKEY.
void twr_cmwx1zzabz_set_event_handler(twr_cmwx1zzabz_t *self, void(*event_handler)(twr_cmwx1zzabz_t *, twr_cmwx1zzabz_event_t, void *), void *event_param)
Set callback function.
bool twr_cmwx1zzabz_is_ready(twr_cmwx1zzabz_t *self)
Check if modem is ready for commands.
bool twr_cmwx1zzabz_get_rfq(twr_cmwx1zzabz_t *self, int32_t *rssi, int32_t *snr)
Get RF quality values in callback.
void twr_cmwx1zzabz_set_band(twr_cmwx1zzabz_t *self, twr_cmwx1zzabz_config_band_t band)
Set BAND.
void twr_cmwx1zzabz_set_repeat_unconfirmed(twr_cmwx1zzabz_t *self, uint8_t repeat)
Set number of transmissions of unconfirmed message.
bool twr_cmwx1zzabz_frame_counter(twr_cmwx1zzabz_t *self)
Request frame counter value.
twr_cmwx1zzabz_config_mode_t
LoRa mode ABP/OTAA.
bool twr_cmwx1zzabz_get_link_check(twr_cmwx1zzabz_t *self, uint8_t *margin, uint8_t *gateway_count)
Get link check values.
void twr_cmwx1zzabz_set_devaddr(twr_cmwx1zzabz_t *self, char *devaddr)
Set DEVADDR.
void twr_cmwx1zzabz_join(twr_cmwx1zzabz_t *self)
Start LoRa OTAA join procedure.
char * twr_cmwx1zzabz_get_fw_version(twr_cmwx1zzabz_t *self)
Get firmware version string.
twr_cmwx1zzabz_config_band_t twr_cmwx1zzabz_get_band(twr_cmwx1zzabz_t *self)
Get BAND.
void twr_cmwx1zzabz_set_port(twr_cmwx1zzabz_t *self, uint8_t port)
Set the port for the transmission of the messages.
void twr_cmwx1zzabz_get_devaddr(twr_cmwx1zzabz_t *self, char *devaddr)
Get DEVADDR.
bool twr_cmwx1zzabz_rfq(twr_cmwx1zzabz_t *self)
Request RF quality of the last received packet (JOIN, LNPARAM, confirmed message)
void twr_cmwx1zzabz_set_class(twr_cmwx1zzabz_t *self, twr_cmwx1zzabz_config_class_t class)
Set device class.
uint32_t twr_cmwx1zzabz_get_received_message_data(twr_cmwx1zzabz_t *self, uint8_t *buffer, uint32_t buffer_size)
Get received message data.
twr_cmwx1zzabz_config_class_t
LoRa device class A or C.
void twr_cmwx1zzabz_reboot(twr_cmwx1zzabz_t *self)
Reboot and initialize CMWX1ZZABZ.
void twr_cmwx1zzabz_get_appskey(twr_cmwx1zzabz_t *self, char *appskey)
Get APPSKEY.
uint32_t twr_cmwx1zzabz_get_received_message_length(twr_cmwx1zzabz_t *self)
Get length of the received message.
void twr_cmwx1zzabz_set_nwk_public(twr_cmwx1zzabz_t *self, uint8_t public)
Set the configuration enabling public networks.
void twr_cmwx1zzabz_set_deveui(twr_cmwx1zzabz_t *self, char *deveui)
Set DEVEUI.
twr_cmwx1zzabz_config_band_t
Frequency modes and standards.
uint8_t twr_cmwx1zzabz_get_port(twr_cmwx1zzabz_t *self)
Get the port for the transmission of the messages.
uint8_t twr_cmwx1zzabz_get_repeat_confirmed(twr_cmwx1zzabz_t *self)
Get number of transmissions of confirmed message.
bool twr_cmwx1zzabz_custom_at(twr_cmwx1zzabz_t *self, char *at_command)
Send custom AT command to LoRa Module.
void twr_cmwx1zzabz_deinit(twr_cmwx1zzabz_t *self)
Deinitialize CMWX1ZZABZ.
uint8_t twr_cmwx1zzabz_get_repeat_unconfirmed(twr_cmwx1zzabz_t *self)
Get number of transmissions of unconfirmed message.
void twr_cmwx1zzabz_set_datarate(twr_cmwx1zzabz_t *self, uint8_t datarate)
Set the configuration of datarate.
void twr_cmwx1zzabz_set_appkey(twr_cmwx1zzabz_t *self, char *appkey)
Set APPKEY.
void twr_cmwx1zzabz_set_appskey(twr_cmwx1zzabz_t *self, char *appskey)
Set APPSKEY.
twr_cmwx1zzabz_config_mode_t twr_cmwx1zzabz_get_mode(twr_cmwx1zzabz_t *self)
Get ABP/OTAA mode.
void twr_cmwx1zzabz_get_appeui(twr_cmwx1zzabz_t *self, char *appeui)
Get APPEUI.
bool twr_cmwx1zzabz_get_adaptive_datarate(twr_cmwx1zzabz_t *self)
Get the configuration if adaptive data rate are enabled.
twr_cmwx1zzabz_config_class_t twr_cmwx1zzabz_get_class(twr_cmwx1zzabz_t *self)
Get device class.
bool twr_cmwx1zzabz_factory_reset(twr_cmwx1zzabz_t *self)
Send factory reset command to LoRa Module.
struct twr_cmwx1zzabz_t twr_cmwx1zzabz_t
CMWX1ZZABZ instance.
bool twr_cmwx1zzabz_get_frame_counter(twr_cmwx1zzabz_t *self, uint32_t *uplink, uint32_t *downlink)
Get frame counter value.
void twr_cmwx1zzabz_get_rx2(twr_cmwx1zzabz_t *self, uint32_t *frequency, uint8_t *datarate)
Get the frequency and datarate for RX2 receive window.
bool twr_cmwx1zzabz_send_message_confirmed(twr_cmwx1zzabz_t *self, const void *buffer, size_t length)
Send LoRa confirmed message.
void twr_cmwx1zzabz_set_mode(twr_cmwx1zzabz_t *self, twr_cmwx1zzabz_config_mode_t mode)
Set ABP/OTAA mode.
char * twr_cmwx1zzabz_get_error_response(twr_cmwx1zzabz_t *self)
Get pointer to string containg response on last sent command.
uint8_t twr_cmwx1zzabz_get_received_message_port(twr_cmwx1zzabz_t *self)
Get port of the received message.
twr_cmwx1zzabz_event_t
Callback events.
void twr_cmwx1zzabz_set_repeat_confirmed(twr_cmwx1zzabz_t *self, uint8_t repeat)
Set number of transmissions of confirmed message.
@ TWR_CMWX1ZZABZ_EVENT_ERROR
Error event.
@ TWR_CMWX1ZZABZ_EVENT_CONFIG_SAVE_DONE
Configuration save done.
@ TWR_CMWX1ZZABZ_EVENT_MESSAGE_RECEIVED
Received message.
@ TWR_CMWX1ZZABZ_EVENT_FRAME_COUNTER
Frame counter response.
@ TWR_CMWX1ZZABZ_EVENT_SEND_MESSAGE_DONE
RF frame transmission finished event.
@ TWR_CMWX1ZZABZ_EVENT_READY
Ready event.
@ TWR_CMWX1ZZABZ_EVENT_MESSAGE_NOT_CONFIRMED
Sent message not confirmed.
@ TWR_CMWX1ZZABZ_EVENT_MESSAGE_CONFIRMED
Sent message confirmed.
@ TWR_CMWX1ZZABZ_EVENT_JOIN_ERROR
OTAA join error.
@ TWR_CMWX1ZZABZ_EVENT_SEND_MESSAGE_START
RF frame transmission started event.
@ TWR_CMWX1ZZABZ_EVENT_JOIN_SUCCESS
OTAA join success.
@ TWR_CMWX1ZZABZ_EVENT_RFQ
RF quality response.
@ TWR_CMWX1ZZABZ_EVENT_MESSAGE_RETRANSMISSION
Retransmission of the confirmed message.
void twr_fifo_purge(twr_fifo_t *fifo)
Purge FIFO buffer.
void twr_fifo_init(twr_fifo_t *fifo, void *buffer, size_t size)
Initialize FIFO buffer.
void void twr_log_debug(const char *format,...) __attribute__((format(printf
Log DEBUG message (annotated in log as <D>)
void twr_scheduler_plan_current_from_now(twr_tick_t tick)
Schedule current task to tick relative from now.
void twr_scheduler_unregister(twr_scheduler_task_id_t task_id)
Unregister specified task.
void twr_scheduler_plan_now(twr_scheduler_task_id_t task_id)
Schedule specified task for immediate execution.
void twr_scheduler_plan_current_now(void)
Schedule current task for immediate execution.
void twr_scheduler_plan_relative(twr_scheduler_task_id_t task_id, twr_tick_t tick)
Schedule specified task to tick relative from current spin.
twr_scheduler_task_id_t twr_scheduler_register(void(*task)(void *), void *param, twr_tick_t tick)
Register task in scheduler.
#define TWR_TICK_INFINITY
Maximum timestamp value.
twr_tick_t twr_tick_get(void)
Get absolute timestamp since start of program.
void twr_timer_init(void)
Initialize timer.
void twr_timer_delay(uint16_t microseconds)
Relative delay.
void twr_timer_stop(void)
Stop timer.
void twr_timer_start(void)
Start timer.
twr_uart_channel_t
UART channels.
void twr_uart_init(twr_uart_channel_t channel, twr_uart_baudrate_t baudrate, twr_uart_setting_t setting)
Initialize UART channel.
size_t twr_uart_async_write(twr_uart_channel_t channel, const void *buffer, size_t length)
Add data to be transmited in async mode.
void twr_uart_set_async_fifo(twr_uart_channel_t channel, twr_fifo_t *write_fifo, twr_fifo_t *read_fifo)
Set buffers for async transfers.
size_t twr_uart_write(twr_uart_channel_t channel, const void *buffer, size_t length)
Write data to UART channel (blocking call)
bool twr_uart_async_read_start(twr_uart_channel_t channel, twr_tick_t timeout)
Start async reading.
twr_uart_event_t
Callback events.
void twr_uart_set_event_handler(twr_uart_channel_t channel, void(*event_handler)(twr_uart_channel_t, twr_uart_event_t, void *), void *event_param)
Set callback function.
size_t twr_uart_async_read(twr_uart_channel_t channel, void *buffer, size_t length)
Get data that has been received in async mode.
void twr_uart_deinit(twr_uart_channel_t channel)
Deinitialize UART channel.
@ TWR_UART_EVENT_ASYNC_READ_DATA
Event is reading done.
@ TWR_UART_BAUDRATE_19200
UART baudrat 19200 bps.
@ TWR_UART_BAUDRATE_9600
UART baudrat 9600 bps.
@ TWR_UART_SETTING_8N1
8N1: 8 data bits, none parity bit, 1 stop bit