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

Dependents:   DCS_FINAL_CODE

Fork of GSM_PUSHING_BOX_STATE_MACHINE by DCS_TEAM

Revision:
29:bc5f53f2922a
Parent:
28:81f1c8bd3299
Child:
30:421aae087064
diff -r 81f1c8bd3299 -r bc5f53f2922a GSMLibrary.cpp
--- a/GSMLibrary.cpp	Thu Apr 23 02:06:55 2015 +0000
+++ b/GSMLibrary.cpp	Sat Apr 25 15:39:00 2015 +0000
@@ -4,28 +4,28 @@
 #include <string.h>
 
 //Global defines
-#define TIMEOUTLIMIT SECONDS_TIMEOUT/TIME_CONST //$change check with main code this will set up condition fior timeout.
+#define TIMEOUTLIMIT SECONDS_TIMEOUT/TIME_CONST  //Defines how many "ticks" of the GSM will constitute "timeout" of our "watchdog timer"
 
 //Extra defines for transmitter
 #define START_SMS_TRANSMISSION "START"
 #define STOP_SMS_TRANSMISSION "STOP"
 #define GPS_SMS_TRANSMISSION "GPS"
 #define RECEIVER_PHONE_NUMBER "\"+13853357314\""
-#define AT_CMGS "AT+CMGS=" RECEIVER_PHONE_NUMBER
-#define NUM_SIZE 25
-#define BEGIN_SENSOR_DATA "$"
+#define AT_CMGS "AT+CMGS=" RECEIVER_PHONE_NUMBER    //Begin sending SMS with this send command and the phone number
+#define NUM_SIZE 25 //Size of a temporary variable to help with concatenation of strings
+#define BEGIN_SENSOR_DATA "$"   //$ and % are parsed by using regex by the GUI for the receiver and indicate the start and end of data received
 #define END_SENSOR_DATA  "%"
 
-//definition for AT comands to send
-#define AT_OK "AT"
-#define AT_CSQ "AT+CSQ" 
-#define AT_CREG "AT+CREG?"
-#define AT_CNMI "AT+CNMI=2,0,0,0,0"
-#define AT_CMGF "AT+CMGF=1"
-#define AT_READ_MSG "AT+CMGL=\"REC UNREAD\"" //make sure device is in txt mode.
-#define AT_DEL_R_MSGS "AT+QMGDA=\"DEL READ\""
+//Define AT commands to send
+#define AT_OK "AT"                  //Ask GSM if everything is 'ok'
+#define AT_CSQ "AT+CSQ"             //Check signal strength
+#define AT_CREG "AT+CREG?"          //Check if GSM is registered on cellular network
+#define AT_CNMI "AT+CNMI=2,0,0,0,0" //Turn off the notification that is normally received when text messages are received
+#define AT_CMGF "AT+CMGF=1"         //Turn on "text message mode" so we can characters (rather than PDU mode in which you send bytes)
+#define AT_READ_MSG "AT+CMGL=\"REC UNREAD\"" //Read received messages that have not yet been read
+#define AT_DEL_R_MSGS "AT+QMGDA=\"DEL READ\""   //Delete read messages
 
-//Definition for AT responses
+//Define expected responses for AT commands
 //Please notice that after ":" the gsm will usually send aditional information
 #define AT_OK_RESPONSE "OK" //Response after sending "AT" message
 #define AT_CSQ_RESPONSE "+CSQ:" //+CSQ: <arg1>,<arg2> where <arg1> is signal strength arg1 = 0-30 where a number below 10 means low signal strength and 99 is not knwn or detectable signal and arg2 is bit error rate form 0-7, 99 will represent error 
@@ -33,38 +33,40 @@
 #define AT_CNMI_RESPONSE "OK"
 #define AT_CMGF_RESPONSE "OK"
 #define AT_CMGS_RESPONSE ">"  //Received after you give the GSM the phone number. (We mistakenly thought it was received a second time after SMS was sent... this is not true!)
-#define AT_SENDSMS_RESPONSE "+CMGS:" // +CMGS: <id> this will include the message id. CMS ERROR for error.
+#define AT_SENDSMS_RESPONSE "+CMGS:" // +CMGS: <id> this will include the message id, or CMS ERROR for error.
 #define AT_DEL_R_MSGS_RESPONSE "OK"
 
 //External variables
-extern Serial pc;
-extern Serial gsm;
-extern uint8_t buffer[BUFFER_LENGTH];//buffer storing char
+extern Serial pc;   //To print output to computer
+extern Serial gsm;  //To communicate with GSM
+extern uint8_t buffer[BUFFER_LENGTH];   //DMA queue
 
 //Internal variables
 gsm_states gsm_current_state = GSM_INITIALIZE;
 int timeout_count = 0;
-char state_chars[] = "iosntmRPWD";  //init, ok, signalstrength, network, turn off notifications, messagemode, read, phone, writesms, del
+char state_chars[] = "iosntmRPWD";  //For debugging - 1 char to represent each state: init, ok, signalstrength, network, turn off notifications, messagemode, read, phone, writesms, del
 
 //Extras for transmitter
 char send = false;  //if true => we will send something (only if send_enable is true)
-char send_enable = false;   //Sending start and stop commands to GSM via SMS changes this variable
+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
 char undeleted_msgs = true; //At the beginning assume we have undeleted messages
-char gsm_msg[MAX_SMS_LENGTH + 250]; //String storing SMS message to send to GSMMaximum (add 250 length to give leeway)
-char num[NUM_SIZE];   //Temporary string storage to convert numbers
+char gsm_msg[MAX_SMS_LENGTH + 250]; //String storing SMS message that will be sent (add 250 length to give leeway)
+char num[NUM_SIZE];   //Temporary string storage to help with concatenation of strings
 
+//"Tick" of the GSM (i.e. this is a state machine)
 void gsm_tick()
 {
-
+    //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
     if (queueHasResponse() || gsm_timeOut() || gsm_current_state == GSM_INITIALIZE)
     {
         //gsm_printState();   //&debug
         //printQueue();   //&debug
         gsm_nextStateLogic();   //Next state
-        gsm_mealyOutputs(); //Mealy outputs
+        gsm_mealyOutputs(); //Mealy outputs. This state machine is a little different because Mealy outputs come after the next state logic
     }
 }
- 
+
+//Prints the current state. To save time printing, simply prints 1 character to indicate the current state.
 void gsm_printState()
 {
     pc.printf("S:%c;", state_chars[gsm_current_state]);
@@ -99,14 +101,14 @@
     strcat(gsm_msg, num);
     snprintf(num, NUM_SIZE, "%f,", Sref);
     strcat(gsm_msg, num);
-    snprintf(num, NUM_SIZE, "%d:%d:%d,", hh, mm, ss);
+    snprintf(num, NUM_SIZE, "%d:%d:%d,", hh, mm, ss);   //If there is no data from GPS, the time will just be "0:0:0" (that is okay)
     strcat(gsm_msg, num);
-    if (ns != NULL) //If there is a gps fix, ns will be set
+    if (ns != NULL) //If there is a gps fix (i.e. the gps has data on our location), ns will be set
     { 
-        snprintf(num, NUM_SIZE, "%.4f,%.4f", (ns == 'N') ? lat : -lat, (we == 'E') ? lon : -lon);
+        snprintf(num, NUM_SIZE, "%.4f,%.4f", (ns == 'N') ? lat : -lat, (we == 'E') ? lon : -lon);   //Use + or - rather than N/S, E/W
         strcat(gsm_msg, num);
     }
-        else strcat(gsm_msg, "0,0");
+        else strcat(gsm_msg, "0,0");    //Otherwise just send 0's for latitude and longitude
     strcat(gsm_msg, END_SENSOR_DATA);
     
     send = true;    //Mark that we are currently sending a message
@@ -120,11 +122,11 @@
     return ((!send) && send_enable) ? true : false;
 }
  
-//Reset the gsm. Currently this only resets the state and whether we are currently sending a message
-//It does not reset send_enable or undeleted_msgs
+//Reset the gsm. Currently this only resets the state, whether we are currently sending a message, and whether there are messages to delete.
+//It does not reset send_enable
 void gsm_reset()
 {
-    //If we are in the middle of sending a text message, exit this loop
+    //If we are in the middle of sending a text message, we need to "escape" out of this mode by sending the escape character
     if (gsm_current_state == GSM_AT_CMGS)
         sendCommand(SMS_ESCAPE_CHAR);
     
@@ -134,13 +136,17 @@
 }
  
 //Next state logic -----------------------------------------------------
+//Note how each state (except init) checks the response received to make sure
+//GSM has properly executed the command. If the response is correct, it changes
+//the state so that the next command will be sent in the gsm_mealyOutputs function
+//below.
 void gsm_nextStateLogic()
 {
     switch(gsm_current_state)
     {
         case GSM_INITIALIZE:
-            timeout_count = 0;
-            gsm_current_state = GSM_AT_OK;   //unconditional (check it)
+            timeout_count = 0;  //No AT commands have been sent: this will send the first one
+            gsm_current_state = GSM_AT_OK;
             break;
         case GSM_AT_OK:
             if (findInQueue(AT_OK_RESPONSE, true))
@@ -153,7 +159,7 @@
         case GSM_AT_CREG:
             if(findInQueue(AT_CREG_RESPONSE, true))
             {
-                parseInt();
+                parseInt(); //After the CREG response we receive two integers. The second should be '1' (see AT_CREG_RESPONSE #define)
                 if(parseInt() == 1)
                     gsm_current_state = GSM_AT_CNMI;
             } 
@@ -167,7 +173,7 @@
                 gsm_current_state = GSM_READ_MSG;
             break;
         case GSM_READ_MSG:
-            if(send_enable) //Check if we need to stop transmission of SMS
+            if(send_enable) //If we are currently sending SMS, check if we need to stop transmission of SMS
             {
                 if(findInQueue(STOP_SMS_TRANSMISSION, true))  //Always stop sending if stop sequence received by SMS
                 {
@@ -178,13 +184,13 @@
                     gsm_current_state = GSM_AT_CMGS;    //Continue sending SMS (change state accordingly)
                 //Implicit: otherwise we will continue checking text messages in this state.
             }
-            else
+            else    //If we are not yet sending SMS, check if we need to start transmission of SMS
             {
                 if(findInQueue(START_SMS_TRANSMISSION, true))
                 {
                     undeleted_msgs = true;
-                    send_enable = true;
-                    if (send) //Only continue sending if we found start sequence AND user requested that we send sms
+                    send_enable = true; //Now we are in send SMS mode: whenever 'send' variable is set to true we will send an SMS
+                    if (send) //Only begin sending a new SMS if user requested that we send SMS (i.e. there is data to send)
                         gsm_current_state = GSM_AT_CMGS;    //Start sending SMS (change state accordingly)
                 }
             }
@@ -198,12 +204,12 @@
             {
                 //pc.printf("(Wid%i)",parseInt());//&debug
                 timeout_count = 0;  //Reset timeout count
-                send = 0;   //Indicate we are done sending the text message
+                send = false;   //Indicate we are done sending the text message
                 if (undeleted_msgs) //Check if we need to delete read messages
-                    gsm_current_state = GSM_DEL_R_MSGS; //Only delete messages if there are no unread messages
+                    gsm_current_state = GSM_DEL_R_MSGS; //Only delete messages if there are unread messages
                 else
                 {
-                    gsm_current_state = GSM_READ_MSG;   //Otherwise read text messages again
+                    gsm_current_state = GSM_READ_MSG;   //Otherwise skip the delete messages state; go read text messages again
                     //pc.printf("(Dnone)");//&debug 
                 }
             }
@@ -266,13 +272,14 @@
             //pc.printf("This is a state error\r\n");
     }
 }
+
 //Initialize the GSM
 void gsm_initialize(){ 
-     wait(2.3);
+     wait(2.3); //Wait for the GSM to turn on properly before doing this initialization
       SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK; //enabling dmamux clock
       SIM_SCGC7 |= SIM_SCGC7_DMA_MASK;  // enebaling dma clock
       //pc.printf("initializing DMA...\r\n");
-     // control register mux, enabling uart3 receive        
+     // control register mux, enabling uart3 receive
      DMAMUX_CHCFG0 |= DMAMUX_CHCFG_ENBL_MASK|DMAMUX_CHCFG_SOURCE(8); 
      
      // Enable request signal for channel 0 
@@ -281,9 +288,10 @@
       // select round-robin arbitration priority
      DMA_CR |= DMA_CR_ERCA_MASK;
      
-     //enabled error interrupt for DMA0
-     //DMA_EEI = DMA_EEI_EEI0_MASK ;
-     //Addres for buffer
+     //enable error interrupt for DMA0 (commented out because we won't use interrupts for our implementation)
+     //DMA_EEI = DMA_EEI_EEI0_MASK;
+     
+     //Address for buffer
      DMA_TCD0_SADDR = (uint32_t) &UART_D_REG(UART3_BASE_PTR);
      DMA_TCD0_DADDR = (uint32_t) buffer;
      // Set an offset for source and destination address
@@ -308,21 +316,18 @@
     // enable interrupt call at end of major loop
     DMA_TCD0_CSR |= DMA_CSR_INTMAJOR_MASK;
     
-    //Activate dma trasnfer rx interrupt
+    //Activate dma transfer rx interrupt
     UART_C2_REG(UART3) |= UART_C2_RIE_MASK;
     UART_C5_REG(UART3) |= UART_C5_RDMAS_MASK | UART_C5_ILDMAS_MASK | UART_C5_LBKDDMAS_MASK;
-    //activate p fifo   
+    //activate p fifo register
     UART_PFIFO_REG(UART3) |= UART_PFIFO_RXFE_MASK; //RXFE and buffer size of 1 word
     queueInit();
     //pc.printf("done...\n\r");
 }
  
- 
- 
-//initialization debuging purposes
-void print_registers() {
-    
-   
+//For debugging: print registers related to DMA and UART setup
+void print_registers()
+{
     pc.printf("\n\rDMA REGISTERS\n\r");
     pc.printf("DMA_MUX: 0x%08x\r\n",DMAMUX_CHCFG0);
     pc.printf("SADDR0: 0x%08x\r\n",DMA_TCD0_SADDR);
@@ -367,5 +372,4 @@
     pc.printf("UART_TCFIFO_REG: %08x\r\n",UART_TCFIFO_REG(UART3)); 
     pc.printf("UART_RWFIFO_REG: %08x\r\n",UART_RWFIFO_REG(UART3)); 
     pc.printf("UART_RCFIFO_REG: %08x\r\n",UART_RCFIFO_REG(UART3));
-  
-}
\ No newline at end of file
+}