171 #include "stm32l1xx.h"
181 #define DO_NOT_GO_STOP 0
185 #define ALWAYS_ENTER_SETUP 0
190 #define USE_OLD_MODULE_INIT 0
192 #ifndef __NO_SYSTEM_INIT
193 #error This firmware must be compiled with __NO_SYSTEM_INIT defined at project level.
210 #if USE_OLD_MODULE_INIT == 1
211 #warning Firmware compiled with the old module initialization method used
212 uint8_t
SARA_init(uint8_t use_NIDD,uint8_t *NIDD_APN)
216 uint32_t boot_start,boot_end;
220 uint8_t needs_reconfig;
224 printf(
"Starting SARA-R410M...\r\n");
226 printf(
"Waiting module to boot...\r\n");
239 printf(
"No startup message from the module, checking if it is already running.\r\n");
242 while ((resp_len==0) && (k<3))
244 printf(
"Attempt %d...\r\n",k+1);
252 printf(
"Module failed to start. Radio communication unavailable.\r\n");
256 printf(
"Module was already running, OK.\r\n");
263 printf(
"Module has booted in %d ms.\r\n",boot_end - boot_start);
277 printf(
"Unable to analyze and set profile, the RF module does not respond.\r\n");
284 if ((NIDD_APN==NULL) || (NIDD_APN[0]==
'\0'))
286 printf(
"NIDD APN value is wrong; the function will not be configured.\r\n");
291 if (strstr(buffer,
"+CGDCONT: 1,\"NONIP\"")==NULL)
293 printf(
"Current context is set for IP, but settings call for NIDD, fixing...\r\n");
294 snprintf(buffer,500,
"AT+CGDCONT=1,\"NONIP\",\"%s\"\r\n",NIDD_APN);
298 printf(
"NIDD mode used.\r\n");
305 if (strstr(buffer,
"+CGDCONT: 1,\"IPV4V6\"")==NULL)
307 printf(
"Current context is set for NIDD method, but settings call for IP, fixing...\r\n");
308 snprintf(buffer,500,
"AT+CGDCONT=1,\"IPV4V6\"\r\n");
312 printf(
"IP mode used.\r\n");
324 printf(
"Unable to configure module.\r\n");
329 printf(
"Applying settings (needs module reboot)...\r\n");
335 printf(
"Unable to reboot module.\r\n");
352 uint32_t boot_start,boot_end;
357 uint8_t needs_reconfig;
362 if (GPIOA->IDR &
PIN_MASK(NB_VINT_PA))
364 printf(
"V_INT is detected to be inactive, RF module is not switched on.\r\nStarting SARA-R410M...\r\n");
367 printf(
"Waiting module to boot...\r\n");
372 while ((GPIOA->IDR &
PIN_MASK(NB_VINT_PA)) && ((time - boot_start)<5000))
378 if ((time - boot_start)>7000)
380 printf(
"Unable to switch the RF module. This might be a hardware problem.\r\n");
386 printf(
"V_INT detected after %d ms.\r\n",time - boot_start);
398 printf(
"No startup message from the module.\r\n");
401 printf(
"The module has booted in %d second(s).\r\n",boot_end - boot_start);
405 printf(
"V_INT is present, the RF module is already powered ON.\r\n");
408 printf(
"Ensuring that the module responds to AT commands...\r\n");
412 while ((resp_len==0) && (k<3))
414 printf(
"Attempt %d...\r\n",k+1);
422 printf(
"The module does not respond.\r\n");
426 printf(
"Module OK.\r\n");
436 printf(
"Reading module configuration...\r\n");
442 printf(
"Attempt %d...\r\n",k);
451 while ((error != 0) && (k<3));
455 printf(
"Unable to analyze and set profile, try this later.\r\n");
462 if ((NIDD_APN==NULL) || (NIDD_APN[0]==
'\0'))
464 printf(
"NIDD APN value is wrong; the function will not be configured.\r\n");
469 if (strstr(buffer,
"+CGDCONT: 1,\"NONIP\"")==NULL)
471 printf(
"Current context is set for IP, but settings call for NIDD, fixing...\r\n");
472 snprintf(buffer,500,
"AT+CGDCONT=1,\"NONIP\",\"%s\"\r\n",NIDD_APN);
476 printf(
"NIDD mode used.\r\n");
483 if (strstr(buffer,
"+CGDCONT: 1,\"IPV4V6\"")==NULL)
485 printf(
"Current context is set for NIDD method, but settings call for IP, fixing...\r\n");
486 snprintf(buffer,500,
"AT+CGDCONT=1,\"IPV4V6\"\r\n");
490 printf(
"IP mode used.\r\n");
502 printf(
"Unable to configure module.\r\n");
507 printf(
"Applying settings (needs module reboot)...\r\n");
513 printf(
"Unable to reboot module.\r\n");
536 uint8_t
NMEA_to_LatLon(uint8_t *NMEA_string_in,
double *dd_lat_out,
double *dd_lon_out)
538 uint8_t *NMEA_pointers[10];
541 double lat_deg,lat_min;
542 double lon_deg,lon_min;
544 NMEA_pointers[0] = strtok(NMEA_string_in,
",");
546 if (NMEA_pointers[0]==NULL)
552 if (strcmp(NMEA_pointers[0],
"$GNGLL")!=0)
559 while ((NMEA_pointers[ptr_n]!=NULL) && (ptr_n<10))
562 NMEA_pointers[ptr_n] = strtok(NULL,
",");
564 if ((NMEA_pointers[ptr_n]==NULL) && (ptr_n<7))
577 if (NMEA_pointers[6][0]!=
'A')
583 if (strlen(NMEA_pointers[1])<4)
588 if (strlen(NMEA_pointers[3])<4)
596 tmp_str[0] = NMEA_pointers[1][0];
597 tmp_str[1] = NMEA_pointers[1][1];
599 lat_deg = atof(tmp_str);
601 lat_min = atof(&(NMEA_pointers[1][2]));
604 tmp_str[0] = NMEA_pointers[3][0];
605 tmp_str[1] = NMEA_pointers[3][1];
606 tmp_str[2] = NMEA_pointers[3][2];
608 lon_deg = atof(tmp_str);
610 lon_min = atof(&(NMEA_pointers[3][3]));
612 if (dd_lat_out!=NULL)
614 if (NMEA_pointers[2][0]==
'N')
616 (*dd_lat_out) = lat_deg + (lat_min/60.0);
620 (*dd_lat_out) = -(lat_deg + (lat_min/60.0));
624 if (dd_lon_out!=NULL)
626 if (NMEA_pointers[4][0]==
'E')
628 (*dd_lon_out) = lon_deg + (lon_min/60.0);
632 (*dd_lon_out) = -(lon_deg + (lon_min/60.0));
639 #define MAX_JSON_LENGTH 200
640 #define MAX_COAP_MSG_LEN (MAX_JSON_LENGTH + MAX_URI_LENGTH + 50)
662 uint8_t
transmit_telemetry(uint8_t *target_IP,uint8_t *target_url,uint16_t target_port,uint8_t *ICCID_string,uint8_t use_NIDD,uint8_t private_gnss)
665 int16_t accel_X,accel_Y,accel_Z;
667 static uint8_t json_string[MAX_JSON_LENGTH];
668 volatile uint16_t CoAP_msg_len;
669 static uint8_t CoAP_msg_buffer[MAX_COAP_MSG_LEN];
671 uint16_t rx_data_length;
672 uint8_t rx_socket_ID;
673 uint32_t wait_counter;
675 uint32_t resp_wait_start,resp_wait_end;
678 uint8_t gnss_data_conversion_result;
679 uint8_t gnss_string[80] = {
"No GNSS data"};
682 uint8_t GNSS_data_valid;
683 static uint8_t NIDD_response_data[520];
684 uint16_t NIDD_response_length;
687 latitude = 59.9397655;
688 longitude = 30.3132998;
692 printf(
"Using NIDD method.\r\n");
697 printf(
"Using IP method.\r\n");
699 if ((target_IP[0]==0) || (target_url[0]==0))
701 printf(
"Unable to transmit telemetry.\r\nPlease check that IP and URL are properly set and try again.\r\n");
706 printf(
"Sending data to %s:%d%s\r\n",target_IP,target_port,target_url);
711 gnss_data_conversion_result=0;
715 printf(
"Unable to read GNSS data, the shield is not fitted or does not function properly.\r\n");
720 gnss_data_conversion_result =
NMEA_to_LatLon(gnss_string,&latitude,&longitude);
722 if (gnss_data_conversion_result==0)
724 printf(
"Unable to convert GNSS data to decimal degrees format. GNSS shield is not fitted, GNSS fix is not completed or some other error occurred.\r\n");
730 printf(
"GNSS logging is set to private mode; actual data will not be transmitted to the server.\r\n");
731 printf(
"Actual GNSS location: latitude = %.6f, longitude = %.6f valid = %d\r\n",latitude,longitude,GNSS_data_valid);
732 latitude = 59.931839;
733 longitude = 30.243405;
734 printf(
"Location data will be replaced to: latitude = %.6f, longitude = %.6f\r\n",latitude,longitude);
746 snprintf(json_string,MAX_JSON_LENGTH,
747 "{'interface':'telemetry', 'ICCID':'%s', 'Tamb_degC':%d, 'aX':%d, 'aY':%d, 'aZ':%d, 'RSSI_dBm':%d, 'latitude':%.6f, 'longitude':%.6f, 'GNSS_data_valid':%d}",
758 printf(
"Telemetry:\r\n%s\r\n(%d bytes)\r\n",json_string,strlen(json_string));
764 printf(
"Message successfully sent.\r\n");
767 NIDD_response_length = 0;
774 if (NIDD_response_length != 0)
776 printf(
"NIDD response received: %s\r\n",NIDD_response_data);
780 printf(
"No NIDD response.\r\n");
785 printf(
"Failed to send message.\r\n");
790 CoAP_msg_len =
CoAP_assemble_request(COAP_METHOD_POST,CoAP_msg_buffer,MAX_COAP_MSG_LEN,target_url,json_string,strlen(json_string));
792 printf(
"Raw CoAP data (%d bytes):\r\n",CoAP_msg_len);
793 for (k=0; k<CoAP_msg_len; k++)
795 if (CoAP_msg_buffer[k]<0x10)
797 printf(
"0%X",CoAP_msg_buffer[k]);
801 printf(
"%X",CoAP_msg_buffer[k]);
810 printf(
"Unable to create UDP socket.\r\n");
817 printf(
"Failed to send data over IP.\r\n");
831 if ((rx_socket_ID!=socket_ID) || (rx_data_length==0))
833 printf(
"No answer from server.\r\n");
837 if (rx_data_length<MAX_COAP_MSG_LEN)
843 printf(
"Server response code: %d.%02d, response time = %d ms.\r\n",hdr_info.
code_class,hdr_info.
code_detail,resp_wait_end - resp_wait_start);
845 printf(
"Server response dump:\r\n");
846 for (k=0; k<rx_data_length; k++)
848 if (CoAP_msg_buffer[k]<0x10)
850 printf(
"0%X",CoAP_msg_buffer[k]);
854 printf(
"%X",CoAP_msg_buffer[k]);
861 printf(
"Server response is too large (%d bytes).\r\n",rx_data_length);
867 printf(
"Unable to close UDP socket.\r\n");
882 uint8_t user_input[80];
884 printf(
"\r\n*** Welcome to MTS NB-IoT Development Kit service menu ***\r\nFirmware version: %s\r\n\r\n",FIRMWARE_VERSION);
886 printf(
"Current settings found in EEPROM:\r\n\r\n");
892 printf(
"Warning: target server IP not set.\r\n");
903 printf(
"Warning: target URL not set.\r\n");
907 printf(
"Target URL:\t\t%s\r\n",settings.
target_URL);
912 printf(
"Warning: APN name not set.\r\n");
919 printf(
"Use NIDD for telemetry:\t%d\r\n",settings.
use_NIDD);
921 printf(
"Board mode on startup:\t");
925 printf(
"logger\r\n");
929 printf(
"service menu\r\n");
935 printf(
"\r\nType in a function number from a list below and press enter.\r\n\r\n");
938 while ((
menu_items[k].menu_item_handler!=NULL) && (
menu_items[k].item_string_description[0]!=
'\0'))
942 printf(
"Target server setup:\r\n");
946 printf(
"System functions:\r\n");
948 printf(
"\t%d\t- %s\r\n",k+1,
menu_items[k].item_string_description);
953 scanf(
"%s",user_input);
955 user_choice = atoi(user_input);
959 printf(
"\r\n--------------------------------------------------------------------------------\r\n");
963 printf(
"Unknown function - %d",user_input+1);
970 printf(
"\r\n--------------------------------------------------------------------------------\r\n");
972 printf(
"Press Enter to return to service menu.\r\n");
988 uint8_t ICCID_cache_string[100];
993 printf(
"Accelerometer initialized.\r\n");
997 printf(
"Temperature sensor initialized.\r\n");
999 printf(
"Temperature sensor always ready.\r\n");
1001 printf(
"Board initialization complete.\r\n");
1007 printf(
"The board is all-new or the settings in EEPROM are severely damaged or non-existent.\r\nPerforming factory setup.\r\n");
1013 printf(
"Saved telemetry interval is incorrect. Messages will be sent with 1000 ms timeout.\r\n");
1019 printf(
"(!) The device will enter service menu.\r\n");
1023 printf(
"Unable to initialize the RF module. Please check its configuration manually.\r\n");
1027 printf(
"Switching off the use of PSM...\r\n");
1031 printf(
"Could not disable the use of PSM;\r\ncheck that the module has started up and not in PSM mode already, and try to do this manually.\r\n");
1044 printf(
"Unable to initialize the RF module, rebooting in menu mode...\r\n");
1058 printf(
"Waiting for the module to register in a network...\r");
1066 #if DO_NOT_GO_STOP == 0
1071 printf(
"Enabling the use of PSM...");
1074 printf(
"Could not enable the use of PSM; something is wrong, the result will be unpredictable.\r\n");
1079 printf(
"Telemetry interval is lower than 6 sec, so the module will not be able to go into PSM; the use of PSM will be disabled.\r\n");
1082 printf(
"Could not disable PSM; something is wrong, the result will be unpredictable.\r\n");
1086 printf(
"(i) Notice: this firmware was compiled with power saving features disabled (debug mode).\r\n");
1092 #if DO_NOT_GO_STOP == 0
1109 #if DO_NOT_GO_STOP == 0
1113 #warning Firmware compiled without power-saving features.