uses pushing box to publish to google spreadsheets with a state machine instead of a while loop
Fork of GSM_PUSHING_BOX_STATE_MACHINE by
Diff: gsmqueue.cpp
- Revision:
- 34:5345174bfb30
- Parent:
- 33:2ae9a4eb6433
diff -r 2ae9a4eb6433 -r 5345174bfb30 gsmqueue.cpp --- a/gsmqueue.cpp Fri Nov 06 20:49:23 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,230 +0,0 @@ -#include "gsmqueue.h" -#include "GSMLibrary.h" -#include <string.h> - -/* gsmqueue.cpp - * Contains functions to read from the DMA buffer in a queue fashion - */ - -#define LAST_UNPRINTABLE_CHAR 31 - -//External variables -extern Serial pc; //Print data to serial connection with computer -//Serial gsm(D3,D2); //UART connection with GSM - -//Internal variables for a queue (wrap-around implementation) -//Note that the DMA (direct memory access) stores data in this queue. Therefore, QUEUETAIL is incremented -//by the DMA and we only read its value. Our queue's purpose is to read data communicated to us -//by the GSM without having to consume processor cycles. Unfortunately when we write data to the Serial -//port, the DMA will still write it to the buffer. For this reason, the sendCommand() function counts -//the number of characters we send over UART so we can ignore those characters in the queue. -char buffer[BUFFER_LENGTH]; //Stores the characters in the queue -char* queueHead; //Queue head - marks where to read from next -char* queueHeadExp; //Expected location of queueHead after gsm.puts() finishes executing - - -//Public functions ------------------------------------------------------------------------------ -//Initialize variables -void queueInit() -{ - //The buffer is initialized in GSMLibrary.cpp - queueHead = QUEUETAIL; - queueHeadExp = queueHead; -} - -//Send gsm a command (don't forget to flush queue and increment past QUEUETAIL -//by the number of characters send) -void sendCommand(char* sPtr) -{ - flushQueue(); //This "removes" any characters remaining in the queue - int size = strlen(sPtr); - if (size > 0 && size <= MAX_SMS_LENGTH) //Don't send if too long or negative size - { - //Send the command - //gsm.puts(sPtr); - //The increment part below: Effectively "removes" characters we just sent from the buffer - // by advancing queueHead by size - 1, or size + 2 - // size - 1 is because SMS_END_CHAR does not show up on the DMA. - // size + 2 is for "\n\r" that gets transmitted after we send the command - if (sPtr[size - 1] == SMS_END_CHAR[0]) - { - queueHeadExp = incrementIndex(queueHead, size - 1); - // Don't add "\n" because already included in string (this is when we are sending a message) - } - else - { - queueHeadExp = incrementIndex(queueHead, size + 2); - //gsm.puts("\n"); //make there be a \r\n in what we send (this is perfect.) - //Why not "\r\n"? Previously we had thought the extra \r was added due to \r\n coming - // through the command line: scanf only removed the \n as whitespace. However, upon - // further investigation we realized this behavior occurs because the gsm.puts function - // adds a "\r" at the end of your string, independent of whether it was already present - // in the string you sent to it. (Except if you only send "\n", in which case it does - // not follow it with a "\r".) Thus we need to simply add "\n" because the "\r" is - // already added by the gsm.puts command. - } - //pc.printf("C:%s\r\n", sPtr); //&debug - to know we have sent this message - } - else //Else: error message - { - //pc.printf("Error: AT command exceeded maximum length"); - gsm_reset(); - } -} - -//Return true if GSM has sent complete response already -//If GSM is idle and queue is not empty, return true -//If the last command was successfully sent, advance queueHead to queueHeadExp -bool queueHasResponse() -{ - if (getGSMIdleBit()) - { //If tail has advanced past the end of our last sent command, queue has new data - int dataReceived = queueSize(QUEUETAIL) - queueSize(queueHeadExp); - if (dataReceived >= 0) - queueHead = queueHeadExp; //Upon equality, last command was successfully sent - return (dataReceived > 0); //Data received only if characters present beyond "equality" point - } - else - return false; //Still busy; wait until transmission ended -} - -//Find an occurrence of the given string in the buffer. -//If advanceQueueHead is true, advance queueHead just until a matching string is found. -//The given string terminates in NULL (\0) -bool findInQueue(char* str, bool advanceQueueHead) -{ - //Check that string to find is not empty - if (*str == NULL) return false; - - char* head = queueHead; - while (head != QUEUETAIL) - { - //Does the character match the begin char? - if (*head == *str){ - //Check the remaining characters - char* sPos = str; - char* qPos = 0; - for (qPos = head; qPos != QUEUETAIL; qPos = incrementIndex(qPos)){ - //Compare the next char - if (*qPos == *sPos) - { - ++sPos; //Increment index (prefix incrementation). - if (*sPos == NULL) //If finished, update head, return true. - { - head = incrementIndex(qPos); - if (advanceQueueHead) - queueHead = head; - return true; - } - } - else //Not equal, so exit for loop and try again at a different location - break; - } - } - //Increment queue index for next iteration - head = incrementIndex(head); - } - //We never succeeded, so return false - if (advanceQueueHead) - queueHead = head; - return false; -} - -//Parse through characters until first integer is found -//Advance qHead until you reach the next non-numeric character -//Does not read negative integers; returns -1 if unsuccessful -int parseInt() -{ - //Check if queue is empty first - if (queueHead == QUEUETAIL) return -1; - - //Advance to first numeric character - while (!isNumeric(queueHead)) - { - queueHead = incrementIndex(queueHead); - if (queueHead == QUEUETAIL) return -1; - } - - //Continue until first non-numeric character - int val = 0; - while (queueHead != QUEUETAIL && isNumeric(queueHead)) - { - val *= 10; - val += (int)(*queueHead - '0'); - queueHead = incrementIndex(queueHead); - } - return val; -} - -//$debug - print queue elements -void printQueue() -{ - char* qPos = queueHead; - pc.printf("Q:"); - while (qPos != QUEUETAIL) - { - //Print the current character - if (*qPos <= LAST_UNPRINTABLE_CHAR) - { - if (*qPos == '\n') - pc.printf("\\n"); - else if (*qPos == '\r') - pc.printf("\\r"); - else - pc.printf("\0%x", *qPos); - } - else - pc.printf("%C",*qPos); - - - //Increment index - qPos = incrementIndex(qPos); - } -} - - -//Internal functions --------------------------------------------------------------------------------- - -//Get the GSM DMA idle bit (if 1, indicates we already received a response) -bool getGSMIdleBit() -{ - return (UART_S1_IDLE_MASK & UART_S1_REG(UART3)) >> UART_S1_IDLE_SHIFT; -} - -//Returns true if the character is numeric -bool isNumeric(char* qPos) -{ - return ('0' <= *qPos && *qPos <= '9'); -} - -//Increment queue position by 1 (Note: this function is only used by gsmqueue.cpp) -char* incrementIndex(char* pointerToIncrement) -{ - if((pointerToIncrement + 1) < (buffer + BUFFER_LENGTH)) - return (pointerToIncrement + 1); - else - return buffer; -} - -//Increment queue position by n (Note: this function is only used by gsmqueue.cpp) -char* incrementIndex(char* pointerToIncrement, int n) -{ - int initialIndex = pointerToIncrement - buffer; - int incrementedIndex = (initialIndex + n) % BUFFER_LENGTH; - return incrementedIndex + buffer; -} - -//Get size of the queue from reference point of tail parameter -int queueSize(char* tail) -{ - int headDiff = queueHead - buffer; - int tailDiff = tail - buffer; - return (tailDiff + BUFFER_LENGTH - headDiff) % BUFFER_LENGTH; -} - -//Clear queue (Note: this function is only used by gsmqueue.cpp) -void flushQueue() -{ - queueHead = QUEUETAIL; -} -