uses pushing box to publish to google spreadsheets with a state machine instead of a while loop

Fork of GSM_Library by DCS_TEAM

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GSMLibrary.cpp Source File

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 }