uses pushing box to publish to google spreadsheets with a state machine instead of a while loop
Fork of GSM_Library by
GSMLibrary.cpp
00001 //Libraries 00002 #include "GSMLibrary.h" 00003 //#include "gsmqueue.h" 00004 #include <string.h> 00005 #include "GPRSInterface.h" 00006 #include "gsmqueue.h" 00007 //Global defines 00008 #define TIMEOUTLIMIT SECONDS_TIMEOUT/TIME_CONST //Defines how many "ticks" of the GSM will constitute "timeout" of our "watchdog timer" 00009 #define NUM_SIZE 250 00010 00011 //External variables 00012 extern Serial pc; //To print output to computer 00013 //extern Serial gsm; //To communicate with GSM 00014 extern uint8_t buffer[BUFFER_LENGTH]; //DMA queue 00015 /************************************************** 00016 ** GPRS ** 00017 **************************************************/ 00018 /** 00019 * D1 - TX pin (RX on the WiFi side) 00020 * D0 - RX pin (TX on the WiFi side) 00021 * 19200 - Baud rate 00022 * "apn" - APN name 00023 * "username" - APN username 00024 * "password" - APN passowrd 00025 */ 00026 GPRSInterface eth(D1,D0, 19200, "ndo","",""); 00027 00028 //Internal variables 00029 gsm_states gsm_current_state = GSM_INITIALIZE; 00030 int timeout_count = 0; 00031 char state_chars[] = "iSJICS"; //For debugging - 1 char to represent each state: init, ok, signalstrength, network, turn off notifications, messagemode, read, phone, writesms, del 00032 char* serverIP; 00033 TCPSocketConnection sock; 00034 00035 //Extras for transmitter 00036 char gsm_msg[250]; //String storing SMS message that will be sent (add 250 length to give leeway) 00037 char gsm_header[250]; //for the http header information 00038 char num[NUM_SIZE]; //Temporary string storage to help with concatenation of strings 00039 char send = false; //if true => we will send something (only if send_enable is true) 00040 char send_enable = false; //Sending start and stop commands to GSM via SMS changes this variable. If true, we will send SMS messages of our data received 00041 00042 00043 //"Tick" of the GSM (i.e. this is a state machine) 00044 void gsm_tick() 00045 { 00046 //Don't do anything, unless i) we received a response from the GSM, ii) the watchdog timer timed out, or iii) or we are initializing the GSM 00047 if (queueHasResponse() || gsm_timeOut() || gsm_current_state == GSM_INITIALIZE) 00048 { 00049 //gsm_printState(); //&debug 00050 //printQueue(); //&debug 00051 gsm_nextStateLogic(); //Next state 00052 //gsm_mealyOutputs(); //Mealy outputs. This state machine is a little different because Mealy outputs come after the next state logic 00053 } 00054 } 00055 00056 //Prints the current state. To save time printing, simply prints 1 character to indicate the current state. 00057 void gsm_printState() 00058 { 00059 pc.printf("S:%c;", state_chars[gsm_current_state]); 00060 } 00061 00062 //Advance timeout counter; if timeout, return true 00063 bool gsm_timeOut() 00064 { 00065 if(++timeout_count >= TIMEOUTLIMIT){ 00066 timeout_count = 0; 00067 gsm_reset(); 00068 return true; 00069 } 00070 else 00071 return false; 00072 } 00073 00074 //Have the GSM send data - L = long, S = short, hh/mm/ss for time, "lat ns" for latitute, "lon we" for longitude 00075 void gsm_send_data(float L, float Lref, int hh, int mm, int ss, float lat, char ns, float lon, char we) 00076 { 00077 //Concatenate data 00078 gsm_msg[0] = NULL; 00079 gsm_header[0] = NULL; 00080 int contentLength = 0; 00081 snprintf(num, NUM_SIZE, "&phone=%s", "3852368101"); 00082 contentLength += strlen(num); 00083 strcat(gsm_msg, num); 00084 snprintf(num, NUM_SIZE, "&data=%f", L); 00085 contentLength += strlen(num); 00086 strcat(gsm_msg, num); 00087 snprintf(num, NUM_SIZE, "&dataRef=%f", Lref); 00088 contentLength += strlen(num); 00089 strcat(gsm_msg, num); 00090 snprintf(num, NUM_SIZE, "&dataRatio=%f", (Lref ? (L/Lref) : 0)); 00091 contentLength += strlen(num); 00092 strcat(gsm_msg, num); 00093 snprintf(num, NUM_SIZE, "&time=%02d:%02d:%02d", hh, mm, ss); //If there is no data from GPS, the time will just be "00:00:00" (that is okay) 00094 contentLength += strlen(num); 00095 strcat(gsm_msg, num); 00096 if (ns != NULL) //If there is a gps fix (i.e. the gps has data on our location), ns will be set 00097 { 00098 snprintf(num, NUM_SIZE, "&latitude=%.4f&longitude=%.4f", (ns == 'N') ? lat : -lat, (we == 'E') ? lon : -lon); //Use + or - rather than N/S, E/W 00099 contentLength += strlen(num); 00100 strcat(gsm_msg, num); 00101 } 00102 else { 00103 snprintf(num, NUM_SIZE,"&latitude=0&longitude=0"); 00104 strcat(gsm_msg, num); //Otherwise just send 0's for latitude and longitude 00105 contentLength += strlen(num); 00106 } 00107 00108 00109 //header information 00110 snprintf(num, NUM_SIZE, "%s", "POST /pushingbox?devid=v941C443DE0C7B14"); 00111 strcat(gsm_header, num); 00112 strcat(gsm_header, gsm_msg); 00113 snprintf(num, NUM_SIZE, "%s"," HTTP/1.1\r\n"); 00114 strcat(gsm_header, num); 00115 snprintf(num, NUM_SIZE, "%s","Host: api.pushingbox.com\r\n"); 00116 strcat(gsm_header, num); 00117 snprintf(num, NUM_SIZE, "%s","Connection: close\r\n"); 00118 strcat(gsm_header, num); 00119 snprintf(num, NUM_SIZE, "%s","User-Agent: FRDM-KD64\r\n"); 00120 strcat(gsm_header, num); 00121 //must have two blank lines after so the server knows that this is the end of headers 00122 snprintf(num, NUM_SIZE, "Content-Length: %d\r\n\r\n", contentLength); 00123 strcat(gsm_header, num); 00124 send = true; //Mark that we are currently sending a message 00125 } 00126 00127 //Return true if gsm is ready to send via tcp 00128 //This only occurs if gsm received start sequence and responded appropriately 00129 bool gsm_ready() 00130 { 00131 return ((!send) && send_enable) ? true : false; 00132 } 00133 00134 //Reset the gsm. Currently this only resets the state, whether we are currently sending a message, and whether there are messages to delete. 00135 //It does not reset send_enable 00136 void gsm_reset() 00137 { 00138 gsm_current_state = GSM_INITIALIZE; 00139 send = false; 00140 } 00141 00142 //Next state logic ----------------------------------------------------- 00143 //Note how each state (except init) checks the response received to make sure 00144 //GSM has properly executed the command. If the response is correct, it changes 00145 //the state so that the next command will be sent in the gsm_mealyOutputs function 00146 //below. 00147 void gsm_nextStateLogic() 00148 { 00149 switch(gsm_current_state) 00150 { 00151 case GSM_INITIALIZE: 00152 timeout_count = 0; //No AT commands have been sent: this will send the first one 00153 printf(">>>INIT\r\n"); 00154 if (eth.init() != NULL) { 00155 printf(">>> Could not initialise. Halting!\n"); 00156 exit(0); 00157 } 00158 gsm_current_state = GSM_CHECK_SIM; 00159 break; 00160 case GSM_CHECK_SIM: 00161 printf(">>>CHECK SIM\r\n"); 00162 if (eth.preInit() == true){ 00163 gsm_current_state = GSM_JOIN; 00164 } 00165 break; 00166 case GSM_JOIN: 00167 printf(">>>JOIN\r\n"); 00168 int join = eth.connect(); 00169 if (join == false || join < 0){ 00170 //stay here 00171 } 00172 else{ 00173 //possibly send this sms to the main box at the lab 00174 //eth.send_SMS("17066311506", eth.getIPAddress()); 00175 gsm_current_state = GSM_SERVER_IP; 00176 } 00177 break; 00178 case GSM_SERVER_IP: 00179 printf(">>>SERVER IP\r\n"); 00180 serverIP = "api.pushingbox.com"; 00181 if(serverIP != NULL) 00182 { 00183 gsm_current_state = GSM_CONNECT; 00184 } 00185 else{ 00186 gsm_current_state = GSM_JOIN; 00187 } 00188 break; 00189 case GSM_CONNECT: 00190 printf("\r\n>>>CONNECT TO: %s\r\n", serverIP); 00191 //sock.set_blocking(true,5000); 00192 if (sock.connect(serverIP,80) == true){ 00193 gsm_current_state = GSM_SEND; 00194 } 00195 else{ 00196 gsm_current_state = GSM_CONNECT; 00197 } 00198 break; 00199 case GSM_SEND: 00200 printf(">>>READY TO SEND\r\n"); 00201 if(send){ 00202 if(sock.send_all(gsm_header, sizeof(gsm_header)-1)){ 00203 printf("Data succesfully sent to server\r\n"); 00204 //close the connection so others can send too 00205 //wait(2); 00206 //eth.disconnect(); 00207 } 00208 else{ 00209 printf("Reconnecting to Server...\r\n"); 00210 send = false; 00211 gsm_current_state = GSM_CONNECT; 00212 } 00213 } 00214 break; 00215 case GSM_WAIT: 00216 //check for text message from server asking for data 00217 gsm_current_state = GSM_SEND; 00218 break; 00219 default: 00220 pc.printf("This is a state error\r\n"); 00221 } 00222 } 00223 00224 //Initialize the GSM 00225 void gsm_initialize(){ 00226 wait(2.3); //Wait for the GSM to turn on properly before doing this initialization 00227 SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK; //enabling dmamux clock 00228 SIM_SCGC7 |= SIM_SCGC7_DMA_MASK; // enebaling dma clock 00229 //pc.printf("initializing DMA...\r\n"); 00230 // control register mux, enabling uart3 receive 00231 DMAMUX_CHCFG0 |= DMAMUX_CHCFG_ENBL_MASK|DMAMUX_CHCFG_SOURCE(8); 00232 00233 // Enable request signal for channel 0 00234 DMA_ERQ = DMA_ERQ_ERQ0_MASK; 00235 00236 // select round-robin arbitration priority 00237 DMA_CR |= DMA_CR_ERCA_MASK; 00238 00239 //enable error interrupt for DMA0 (commented out because we won't use interrupts for our implementation) 00240 //DMA_EEI = DMA_EEI_EEI0_MASK; 00241 00242 //Address for buffer 00243 DMA_TCD0_SADDR = (uint32_t) &UART_D_REG(UART3_BASE_PTR); 00244 DMA_TCD0_DADDR = (uint32_t) buffer; 00245 // Set an offset for source and destination address 00246 DMA_TCD0_SOFF = 0x00; 00247 DMA_TCD0_DOFF = 0x01; // Destination address offset of 1 byte per transaction 00248 00249 // Set source and destination data transfer size 00250 DMA_TCD0_ATTR = DMA_ATTR_SSIZE(0) | DMA_ATTR_DSIZE(0); 00251 00252 // Number of bytes to be transfered in each service request of the channel 00253 DMA_TCD0_NBYTES_MLNO = 0x01; 00254 // Current major iteration count 00255 DMA_TCD0_CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(BUFFER_LENGTH); 00256 DMA_TCD0_BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(BUFFER_LENGTH); 00257 // Adjustment value used to restore the source and destiny address to the initial value 00258 // After reading 'len' number of times, the DMA goes back to the beginning by subtracting len*2 from the address (going back to the original address) 00259 DMA_TCD0_SLAST = 0; // Source address adjustment 00260 DMA_TCD0_DLASTSGA = -BUFFER_LENGTH; // Destination address adjustment 00261 // Setup control and status register 00262 DMA_TCD0_CSR = 0; 00263 00264 // enable interrupt call at end of major loop 00265 DMA_TCD0_CSR |= DMA_CSR_INTMAJOR_MASK; 00266 00267 //Activate dma transfer rx interrupt 00268 UART_C2_REG(UART3) |= UART_C2_RIE_MASK; 00269 UART_C5_REG(UART3) |= UART_C5_RDMAS_MASK | UART_C5_ILDMAS_MASK | UART_C5_LBKDDMAS_MASK; 00270 //activate p fifo register 00271 UART_PFIFO_REG(UART3) |= UART_PFIFO_RXFE_MASK; //RXFE and buffer size of 1 word 00272 queueInit(); 00273 //pc.printf("done...\n\r"); 00274 } 00275 00276 //For debugging: print registers related to DMA and UART setup 00277 void print_registers() 00278 { 00279 pc.printf("\n\rDMA REGISTERS\n\r"); 00280 pc.printf("DMA_MUX: 0x%08x\r\n",DMAMUX_CHCFG0); 00281 pc.printf("SADDR0: 0x%08x\r\n",DMA_TCD0_SADDR); 00282 pc.printf("DADDR0: 0x%08x\r\n",DMA_TCD0_DADDR); 00283 pc.printf("CITER0: 0x%08x\r\n",DMA_TCD0_CITER_ELINKNO); 00284 pc.printf("BITER0: 0x%08x\r\n",DMA_TCD0_BITER_ELINKNO); 00285 pc.printf("DMA_CR: %08x\r\n", DMA_CR); 00286 pc.printf("DMA_ES: %08x\r\n", DMA_ES); 00287 pc.printf("DMA_ERQ: %08x\r\n", DMA_ERQ); 00288 pc.printf("DMA_EEI: %08x\r\n", DMA_EEI); 00289 pc.printf("DMA_CEEI: %02x\r\n", DMA_CEEI); 00290 pc.printf("DMA_SEEI: %02x\r\n", DMA_SEEI); 00291 pc.printf("DMA_CERQ: %02x\r\n", DMA_CERQ); 00292 pc.printf("DMA_SERQ: %02x\r\n", DMA_SERQ); 00293 pc.printf("DMA_CDNE: %02x\r\n", DMA_CDNE); 00294 pc.printf("DMA_SSRT: %02x\r\n", DMA_SSRT); 00295 pc.printf("DMA_CERR: %02x\r\n", DMA_CERR); 00296 pc.printf("DMA_CINT: %02x\r\n", DMA_CINT); 00297 pc.printf("DMA_INT: %08x\r\n", DMA_INT); 00298 pc.printf("DMA_ERR: %08x\r\n", DMA_ERR); 00299 pc.printf("DMA_HRS: %08x\r\n", DMA_HRS); 00300 pc.printf("DMA_TCD0_DOFF: %08x\r\n",DMA_TCD0_DOFF); 00301 pc.printf("\n\rUART REGISTERS\n\r"); 00302 pc.printf("UART_BDH_REG: %08x\r\n",UART_BDH_REG(UART3)); 00303 pc.printf("UART_C1_REG: %08x\r\n",UART_C1_REG(UART3)); 00304 pc.printf("UART_C2_REG: %08x\r\n",UART_C2_REG(UART3)); 00305 pc.printf("UART_S1_REG: %08x\r\n",UART_S1_REG(UART3)); 00306 pc.printf("UART_s2_REG: %08x\r\n",UART_S2_REG(UART3)); 00307 pc.printf("UART_C3_REG: %08x\r\n",UART_C3_REG(UART3)); 00308 pc.printf("UART_D_REG: %08x\r\n",UART_D_REG(UART3)); 00309 pc.printf("UART_MA1_REG: %08x\r\n",UART_MA1_REG(UART3)); 00310 pc.printf("UART_MA2_REG: %08x\r\n",UART_MA2_REG(UART3)); 00311 pc.printf("UART_C4_REG: %08x\r\n",UART_C4_REG(UART3)); 00312 pc.printf("UART_C5_REG: %08x\r\n",UART_C5_REG(UART3)); 00313 pc.printf("UART_ED_REG: %08x\r\n",UART_ED_REG(UART3)); 00314 pc.printf("UART_MODEM_REG: %08x\r\n",UART_MODEM_REG(UART3)); 00315 pc.printf("UART_IR_REG: %08x\r\n",UART_IR_REG(UART3)); 00316 pc.printf("UART_PFIFO_REG: %08x\r\n",UART_PFIFO_REG(UART3)); 00317 pc.printf("UART_CFIFO_REG: %08x\r\n",UART_CFIFO_REG(UART3)); 00318 pc.printf("UART_SFIFO_REG: %08x\r\n",UART_SFIFO_REG(UART3)); 00319 pc.printf("UART_TWFIFO_REG: %08x\r\n",UART_TWFIFO_REG(UART3)); 00320 pc.printf("UART_TCFIFO_REG: %08x\r\n",UART_TCFIFO_REG(UART3)); 00321 pc.printf("UART_RWFIFO_REG: %08x\r\n",UART_RWFIFO_REG(UART3)); 00322 pc.printf("UART_RCFIFO_REG: %08x\r\n",UART_RCFIFO_REG(UART3)); 00323 }
Generated on Tue Jul 26 2022 21:19:54 by
![doxygen](doxygen.png)