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