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

Committer:
es_marble
Date:
Sat Apr 11 23:21:46 2015 +0000
Revision:
24:7d2ff444d6d8
Parent:
13:9ac5ff131214
Child:
27:fe1c7eaf5b88
added final GSM_Library code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
danilob 0:41904adca656 1 #include "gsmqueue.h"
es_marble 24:7d2ff444d6d8 2 #include "GSMLibrary.h"
es_marble 24:7d2ff444d6d8 3 #include <string.h>
es_marble 24:7d2ff444d6d8 4
es_marble 24:7d2ff444d6d8 5 /* gsmqueue.cpp
danilob 0:41904adca656 6 * Contains functions to read from the DMA buffer in a queue fashion
danilob 0:41904adca656 7 */
es_marble 24:7d2ff444d6d8 8
es_marble 24:7d2ff444d6d8 9 #define LAST_UNPRINTABLE_CHAR 31
es_marble 24:7d2ff444d6d8 10
es_marble 3:dac922a18af6 11 extern Serial pc;
es_marble 24:7d2ff444d6d8 12 extern Serial gsm;
danilob 0:41904adca656 13
danilob 0:41904adca656 14 char buffer[BUFFER_LENGTH];
danilob 0:41904adca656 15 char* queueHead;
es_marble 24:7d2ff444d6d8 16 char* queueHeadExp; //Expected location of queueHead after gsm.puts() finishes executing
danilob 0:41904adca656 17
danilob 0:41904adca656 18
es_marble 24:7d2ff444d6d8 19 //Public functions ------------------------------------------------------------------------------
es_marble 24:7d2ff444d6d8 20 //Initialize variables
danilob 0:41904adca656 21 void queueInit()
danilob 0:41904adca656 22 {
es_marble 24:7d2ff444d6d8 23 //The buffer is initialized in GSMLibrary.cpp
danilob 0:41904adca656 24 queueHead = QUEUETAIL;
es_marble 24:7d2ff444d6d8 25 queueHeadExp = queueHead;
es_marble 24:7d2ff444d6d8 26 }
es_marble 24:7d2ff444d6d8 27
es_marble 24:7d2ff444d6d8 28 //Send gsm a command (don't forget to flush queue and increment past QUEUETAIL
es_marble 24:7d2ff444d6d8 29 //by the number of characters send)
es_marble 24:7d2ff444d6d8 30 void sendCommand(char* sPtr)
es_marble 24:7d2ff444d6d8 31 {
es_marble 24:7d2ff444d6d8 32 flushQueue(); //This "removes" any characters remaining in the queue
es_marble 24:7d2ff444d6d8 33 int size = strlen(sPtr);
es_marble 24:7d2ff444d6d8 34 if (size > 0 && size <= MAX_SMS_LENGTH) //Don't send if too long or negative size
es_marble 24:7d2ff444d6d8 35 {
es_marble 24:7d2ff444d6d8 36 //Send the command
es_marble 24:7d2ff444d6d8 37 gsm.puts(sPtr);
es_marble 24:7d2ff444d6d8 38 //The increment part below: Effectively "removes" characters we just sent from the buffer
es_marble 24:7d2ff444d6d8 39 // by advancing queueHead by size - 1, or size + 2
es_marble 24:7d2ff444d6d8 40 // size - 1 is because SMS_END_CHAR does not show up on the DMA.
es_marble 24:7d2ff444d6d8 41 // size + 2 is for "\n\r" that gets transmitted after we send the command
es_marble 24:7d2ff444d6d8 42 if (sPtr[size - 1] == SMS_END_CHAR[0])
es_marble 24:7d2ff444d6d8 43 {
es_marble 24:7d2ff444d6d8 44 queueHeadExp = incrementIndex(queueHead, size - 1);
es_marble 24:7d2ff444d6d8 45 // Don't add "\n" because already included in string (this is when we are sending a message)
es_marble 24:7d2ff444d6d8 46 }
es_marble 24:7d2ff444d6d8 47 else
es_marble 24:7d2ff444d6d8 48 {
es_marble 24:7d2ff444d6d8 49 queueHeadExp = incrementIndex(queueHead, size + 2);
es_marble 24:7d2ff444d6d8 50 gsm.puts("\n"); //make there be a \r\n in what we send (this is perfect.)
es_marble 24:7d2ff444d6d8 51 //Why not "\r\n"? Previously we had thought the extra \r was added due to \r\n coming
es_marble 24:7d2ff444d6d8 52 // through the command line: scanf only removed the \n as whitespace. However, upon
es_marble 24:7d2ff444d6d8 53 // further investigation we realized this behavior occurs because the gsm.puts function
es_marble 24:7d2ff444d6d8 54 // adds a "\r" at the end of your string, independent of whether it was already present
es_marble 24:7d2ff444d6d8 55 // in the string you sent to it. (Except if you only send "\n", in which case it does
es_marble 24:7d2ff444d6d8 56 // not follow it with a "\r".) Thus we need to simply add "\n" because the "\r" is
es_marble 24:7d2ff444d6d8 57 // already added by the gsm.puts command.
es_marble 24:7d2ff444d6d8 58 }
es_marble 24:7d2ff444d6d8 59 pc.printf("C:%s\r\n", sPtr); //&debug - to know we have sent this message
es_marble 24:7d2ff444d6d8 60 }
es_marble 24:7d2ff444d6d8 61 else //Else: error message
es_marble 24:7d2ff444d6d8 62 {
es_marble 24:7d2ff444d6d8 63 pc.printf("Error: AT command exceeded maximum length");
es_marble 24:7d2ff444d6d8 64 gsm_reset();
es_marble 24:7d2ff444d6d8 65 }
es_marble 24:7d2ff444d6d8 66 }
es_marble 24:7d2ff444d6d8 67
es_marble 24:7d2ff444d6d8 68 //Return true if GSM has sent complete response already
es_marble 24:7d2ff444d6d8 69 //If GSM is idle and queue is not empty, return true
es_marble 24:7d2ff444d6d8 70 //If the last command was successfully sent, advance queueHead to queueHeadExp
es_marble 24:7d2ff444d6d8 71 bool queueHasResponse()
es_marble 24:7d2ff444d6d8 72 {
es_marble 24:7d2ff444d6d8 73 if (getGSMIdleBit())
es_marble 24:7d2ff444d6d8 74 { //If tail has advanced past the end of our last sent command, queue has new data
es_marble 24:7d2ff444d6d8 75 int dataReceived = queueSize(QUEUETAIL) - queueSize(queueHeadExp);
es_marble 24:7d2ff444d6d8 76 if (dataReceived >= 0)
es_marble 24:7d2ff444d6d8 77 queueHead = queueHeadExp; //Upon equality, last command was successfully sent
es_marble 24:7d2ff444d6d8 78 return (dataReceived > 0); //Data received only if characters present beyond "equality" point
es_marble 24:7d2ff444d6d8 79 }
es_marble 24:7d2ff444d6d8 80 else
es_marble 24:7d2ff444d6d8 81 return false; //Still busy; wait until transmission ended
danilob 0:41904adca656 82 }
danilob 0:41904adca656 83
danilob 0:41904adca656 84 //Find an occurrence of the given string in the buffer.
es_marble 24:7d2ff444d6d8 85 //If advanceQueueHead is true, advance queueHead just until a matching string is found.
es_marble 3:dac922a18af6 86 //The given string terminates in NULL (\0)
es_marble 24:7d2ff444d6d8 87 bool findInQueue(char* str, bool advanceQueueHead)
danilob 0:41904adca656 88 {
es_marble 3:dac922a18af6 89 //Check that string to find is not empty
es_marble 3:dac922a18af6 90 if (*str == NULL) return false;
es_marble 3:dac922a18af6 91
es_marble 24:7d2ff444d6d8 92 char* head = queueHead;
es_marble 24:7d2ff444d6d8 93 while (head != QUEUETAIL)
danilob 0:41904adca656 94 {
danilob 0:41904adca656 95 //Does the character match the begin char?
es_marble 24:7d2ff444d6d8 96 if (*head == *str){
danilob 0:41904adca656 97 //Check the remaining characters
danilob 13:9ac5ff131214 98 char* sPos = str;
es_marble 3:dac922a18af6 99 char* qPos = 0;
es_marble 24:7d2ff444d6d8 100 for (qPos = head; qPos != QUEUETAIL; qPos = incrementIndex(qPos)){
danilob 0:41904adca656 101 //Compare the next char
danilob 0:41904adca656 102 if (*qPos == *sPos)
danilob 0:41904adca656 103 {
es_marble 3:dac922a18af6 104 ++sPos; //Increment index (prefix incrementation).
es_marble 24:7d2ff444d6d8 105 if (*sPos == NULL) //If finished, update head, return true.
es_marble 8:1d8623e25fa6 106 {
es_marble 24:7d2ff444d6d8 107 head = incrementIndex(qPos);
es_marble 24:7d2ff444d6d8 108 if (advanceQueueHead)
es_marble 24:7d2ff444d6d8 109 queueHead = head;
danilob 0:41904adca656 110 return true;
es_marble 8:1d8623e25fa6 111 }
danilob 0:41904adca656 112 }
danilob 0:41904adca656 113 else //Not equal, so exit for loop and try again at a different location
danilob 0:41904adca656 114 break;
danilob 0:41904adca656 115 }
danilob 0:41904adca656 116 }
danilob 0:41904adca656 117 //Increment queue index for next iteration
es_marble 24:7d2ff444d6d8 118 head = incrementIndex(head);
danilob 0:41904adca656 119 }
es_marble 24:7d2ff444d6d8 120 //We never succeeded, so return false
es_marble 24:7d2ff444d6d8 121 if (advanceQueueHead)
es_marble 24:7d2ff444d6d8 122 queueHead = head;
danilob 0:41904adca656 123 return false;
danilob 0:41904adca656 124 }
danilob 0:41904adca656 125
danilob 0:41904adca656 126 //Parse through characters until first integer is found
es_marble 1:c1458b739eb6 127 //Advance qHead until you reach the next non-numeric character
es_marble 3:dac922a18af6 128 //Does not read negative integers; returns -1 if unsuccessful
danilob 0:41904adca656 129 int parseInt()
danilob 0:41904adca656 130 {
danilob 13:9ac5ff131214 131 //Check if queue is empty first
danilob 13:9ac5ff131214 132 if (queueHead == QUEUETAIL) return -1;
danilob 13:9ac5ff131214 133
es_marble 3:dac922a18af6 134 //Advance to first numeric character
danilob 13:9ac5ff131214 135 while (!isNumeric(queueHead))
danilob 0:41904adca656 136 {
danilob 13:9ac5ff131214 137 queueHead = incrementIndex(queueHead);
danilob 13:9ac5ff131214 138 if (queueHead == QUEUETAIL) return -1;
es_marble 3:dac922a18af6 139 }
es_marble 3:dac922a18af6 140
es_marble 3:dac922a18af6 141 //Continue until first non-numeric character
es_marble 3:dac922a18af6 142 int val = 0;
danilob 13:9ac5ff131214 143 while (queueHead != QUEUETAIL && isNumeric(queueHead))
es_marble 3:dac922a18af6 144 {
es_marble 3:dac922a18af6 145 val *= 10;
danilob 13:9ac5ff131214 146 val += (int)(*queueHead - '0');
danilob 13:9ac5ff131214 147 queueHead = incrementIndex(queueHead);
danilob 0:41904adca656 148 }
es_marble 3:dac922a18af6 149 return val;
es_marble 1:c1458b739eb6 150 }
es_marble 1:c1458b739eb6 151
es_marble 24:7d2ff444d6d8 152 //$debug - print queue elements
es_marble 24:7d2ff444d6d8 153 void printQueue()
es_marble 24:7d2ff444d6d8 154 {
es_marble 24:7d2ff444d6d8 155 char* qPos = queueHead;
es_marble 24:7d2ff444d6d8 156 pc.printf("Q:");
es_marble 24:7d2ff444d6d8 157 while (qPos != QUEUETAIL)
es_marble 24:7d2ff444d6d8 158 {
es_marble 24:7d2ff444d6d8 159 //Print the current character
es_marble 24:7d2ff444d6d8 160 if (*qPos <= LAST_UNPRINTABLE_CHAR)
es_marble 24:7d2ff444d6d8 161 {
es_marble 24:7d2ff444d6d8 162 if (*qPos == '\n')
es_marble 24:7d2ff444d6d8 163 pc.printf("\\n");
es_marble 24:7d2ff444d6d8 164 else if (*qPos == '\r')
es_marble 24:7d2ff444d6d8 165 pc.printf("\\r");
es_marble 24:7d2ff444d6d8 166 else
es_marble 24:7d2ff444d6d8 167 pc.printf("\0%x", *qPos);
es_marble 24:7d2ff444d6d8 168 }
es_marble 24:7d2ff444d6d8 169 else
es_marble 24:7d2ff444d6d8 170 pc.printf("%C",*qPos);
es_marble 24:7d2ff444d6d8 171
es_marble 24:7d2ff444d6d8 172
es_marble 24:7d2ff444d6d8 173 //Increment index
es_marble 24:7d2ff444d6d8 174 qPos = incrementIndex(qPos);
es_marble 24:7d2ff444d6d8 175 }
es_marble 24:7d2ff444d6d8 176 }
es_marble 24:7d2ff444d6d8 177
es_marble 24:7d2ff444d6d8 178
es_marble 24:7d2ff444d6d8 179 //Internal functions ---------------------------------------------------------------------------------
es_marble 24:7d2ff444d6d8 180
es_marble 24:7d2ff444d6d8 181 //Get the GSM DMA idle bit (if 1, indicates we already received a response)
es_marble 24:7d2ff444d6d8 182 bool getGSMIdleBit()
es_marble 24:7d2ff444d6d8 183 {
es_marble 24:7d2ff444d6d8 184 return (UART_S1_IDLE_MASK & UART_S1_REG(UART3)) >> UART_S1_IDLE_SHIFT;
es_marble 24:7d2ff444d6d8 185 }
es_marble 24:7d2ff444d6d8 186
es_marble 3:dac922a18af6 187 //Returns true if the character is numeric
es_marble 3:dac922a18af6 188 bool isNumeric(char* qPos)
es_marble 3:dac922a18af6 189 {
danilob 13:9ac5ff131214 190 return ('0' <= *qPos && *qPos <= '9');
es_marble 3:dac922a18af6 191 }
es_marble 24:7d2ff444d6d8 192
es_marble 24:7d2ff444d6d8 193 //Increment queue position by 1 (Note: this function is only used by gsmqueue.cpp)
es_marble 24:7d2ff444d6d8 194 char* incrementIndex(char* pointerToIncrement)
es_marble 24:7d2ff444d6d8 195 {
es_marble 24:7d2ff444d6d8 196 if((pointerToIncrement + 1) < (buffer + BUFFER_LENGTH))
es_marble 24:7d2ff444d6d8 197 return (pointerToIncrement + 1);
es_marble 24:7d2ff444d6d8 198 else
es_marble 24:7d2ff444d6d8 199 return buffer;
es_marble 24:7d2ff444d6d8 200 }
es_marble 24:7d2ff444d6d8 201
es_marble 24:7d2ff444d6d8 202 //Increment queue position by n (Note: this function is only used by gsmqueue.cpp)
es_marble 24:7d2ff444d6d8 203 char* incrementIndex(char* pointerToIncrement, int n)
es_marble 24:7d2ff444d6d8 204 {
es_marble 24:7d2ff444d6d8 205 int initialIndex = pointerToIncrement - buffer;
es_marble 24:7d2ff444d6d8 206 int incrementedIndex = (initialIndex + n) % BUFFER_LENGTH;
es_marble 24:7d2ff444d6d8 207 return incrementedIndex + buffer;
es_marble 24:7d2ff444d6d8 208 }
es_marble 24:7d2ff444d6d8 209
es_marble 24:7d2ff444d6d8 210 //Get size of the queue from reference point of tail parameter
es_marble 24:7d2ff444d6d8 211 int queueSize(char* tail)
es_marble 24:7d2ff444d6d8 212 {
es_marble 24:7d2ff444d6d8 213 int headDiff = queueHead - buffer;
es_marble 24:7d2ff444d6d8 214 int tailDiff = tail - buffer;
es_marble 24:7d2ff444d6d8 215 return (tailDiff + BUFFER_LENGTH - headDiff) % BUFFER_LENGTH;
es_marble 24:7d2ff444d6d8 216 }
es_marble 24:7d2ff444d6d8 217
es_marble 24:7d2ff444d6d8 218 //Clear queue (Note: this function is only used by gsmqueue.cpp)
es_marble 24:7d2ff444d6d8 219 void flushQueue()
es_marble 24:7d2ff444d6d8 220 {
es_marble 24:7d2ff444d6d8 221 queueHead = QUEUETAIL;
es_marble 24:7d2ff444d6d8 222 }
es_marble 3:dac922a18af6 223
es_marble 1:c1458b739eb6 224 //Reset the GSM DMA idle bit to 0
es_marble 1:c1458b739eb6 225 void resetGSMIdleBit()
es_marble 1:c1458b739eb6 226 {
es_marble 1:c1458b739eb6 227 UART_S1_REG(UART3) &= ~UART_S1_IDLE_MASK;
es_marble 1:c1458b739eb6 228 }
es_marble 1:c1458b739eb6 229