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
GSMLibrary.cpp@29:bc5f53f2922a, 2015-04-25 (annotated)
- Committer:
- es_marble
- Date:
- Sat Apr 25 15:39:00 2015 +0000
- Revision:
- 29:bc5f53f2922a
- Parent:
- 28:81f1c8bd3299
- Child:
- 30:421aae087064
Finish adding comments
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
es_marble | 24:7d2ff444d6d8 | 1 | //Libraries |
danilob | 0:41904adca656 | 2 | #include "GSMLibrary.h" |
danilob | 0:41904adca656 | 3 | #include "gsmqueue.h" |
danilob | 2:8352ad91f2ee | 4 | #include <string.h> |
danilob | 0:41904adca656 | 5 | |
es_marble | 24:7d2ff444d6d8 | 6 | //Global defines |
es_marble | 29:bc5f53f2922a | 7 | #define TIMEOUTLIMIT SECONDS_TIMEOUT/TIME_CONST //Defines how many "ticks" of the GSM will constitute "timeout" of our "watchdog timer" |
danilob | 0:41904adca656 | 8 | |
es_marble | 24:7d2ff444d6d8 | 9 | //Extra defines for transmitter |
es_marble | 24:7d2ff444d6d8 | 10 | #define START_SMS_TRANSMISSION "START" |
es_marble | 24:7d2ff444d6d8 | 11 | #define STOP_SMS_TRANSMISSION "STOP" |
es_marble | 24:7d2ff444d6d8 | 12 | #define GPS_SMS_TRANSMISSION "GPS" |
es_marble | 24:7d2ff444d6d8 | 13 | #define RECEIVER_PHONE_NUMBER "\"+13853357314\"" |
es_marble | 29:bc5f53f2922a | 14 | #define AT_CMGS "AT+CMGS=" RECEIVER_PHONE_NUMBER //Begin sending SMS with this send command and the phone number |
es_marble | 29:bc5f53f2922a | 15 | #define NUM_SIZE 25 //Size of a temporary variable to help with concatenation of strings |
es_marble | 29:bc5f53f2922a | 16 | #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 |
es_marble | 26:838a9d26e8e9 | 17 | #define END_SENSOR_DATA "%" |
es_marble | 24:7d2ff444d6d8 | 18 | |
es_marble | 29:bc5f53f2922a | 19 | //Define AT commands to send |
es_marble | 29:bc5f53f2922a | 20 | #define AT_OK "AT" //Ask GSM if everything is 'ok' |
es_marble | 29:bc5f53f2922a | 21 | #define AT_CSQ "AT+CSQ" //Check signal strength |
es_marble | 29:bc5f53f2922a | 22 | #define AT_CREG "AT+CREG?" //Check if GSM is registered on cellular network |
es_marble | 29:bc5f53f2922a | 23 | #define AT_CNMI "AT+CNMI=2,0,0,0,0" //Turn off the notification that is normally received when text messages are received |
es_marble | 29:bc5f53f2922a | 24 | #define AT_CMGF "AT+CMGF=1" //Turn on "text message mode" so we can characters (rather than PDU mode in which you send bytes) |
es_marble | 29:bc5f53f2922a | 25 | #define AT_READ_MSG "AT+CMGL=\"REC UNREAD\"" //Read received messages that have not yet been read |
es_marble | 29:bc5f53f2922a | 26 | #define AT_DEL_R_MSGS "AT+QMGDA=\"DEL READ\"" //Delete read messages |
danilob | 22:a5adf9331032 | 27 | |
es_marble | 29:bc5f53f2922a | 28 | //Define expected responses for AT commands |
danilob | 0:41904adca656 | 29 | //Please notice that after ":" the gsm will usually send aditional information |
danilob | 0:41904adca656 | 30 | #define AT_OK_RESPONSE "OK" //Response after sending "AT" message |
es_marble | 6:3ccc86304c2c | 31 | #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 |
danilob | 13:9ac5ff131214 | 32 | #define AT_CREG_RESPONSE "+CREG:"//+CREG: <arg1>,<arg2> where <arg1> = 0-2(see AT command descriptions), <arg2> = 0-5, 0 not registered to nework and not looking for one. 1 is conected to network, 2 is not conected but searching |
es_marble | 24:7d2ff444d6d8 | 33 | #define AT_CNMI_RESPONSE "OK" |
danilob | 0:41904adca656 | 34 | #define AT_CMGF_RESPONSE "OK" |
es_marble | 24:7d2ff444d6d8 | 35 | #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!) |
es_marble | 29:bc5f53f2922a | 36 | #define AT_SENDSMS_RESPONSE "+CMGS:" // +CMGS: <id> this will include the message id, or CMS ERROR for error. |
es_marble | 24:7d2ff444d6d8 | 37 | #define AT_DEL_R_MSGS_RESPONSE "OK" |
danilob | 0:41904adca656 | 38 | |
es_marble | 16:6807d437cd48 | 39 | //External variables |
es_marble | 29:bc5f53f2922a | 40 | extern Serial pc; //To print output to computer |
es_marble | 29:bc5f53f2922a | 41 | extern Serial gsm; //To communicate with GSM |
es_marble | 29:bc5f53f2922a | 42 | extern uint8_t buffer[BUFFER_LENGTH]; //DMA queue |
es_marble | 16:6807d437cd48 | 43 | |
es_marble | 16:6807d437cd48 | 44 | //Internal variables |
danilob | 0:41904adca656 | 45 | gsm_states gsm_current_state = GSM_INITIALIZE; |
danilob | 12:f3ccc43c4d3c | 46 | int timeout_count = 0; |
es_marble | 29:bc5f53f2922a | 47 | char state_chars[] = "iosntmRPWD"; //For debugging - 1 char to represent each state: init, ok, signalstrength, network, turn off notifications, messagemode, read, phone, writesms, del |
es_marble | 24:7d2ff444d6d8 | 48 | |
es_marble | 24:7d2ff444d6d8 | 49 | //Extras for transmitter |
es_marble | 24:7d2ff444d6d8 | 50 | char send = false; //if true => we will send something (only if send_enable is true) |
es_marble | 29:bc5f53f2922a | 51 | 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 |
es_marble | 24:7d2ff444d6d8 | 52 | char undeleted_msgs = true; //At the beginning assume we have undeleted messages |
es_marble | 29:bc5f53f2922a | 53 | char gsm_msg[MAX_SMS_LENGTH + 250]; //String storing SMS message that will be sent (add 250 length to give leeway) |
es_marble | 29:bc5f53f2922a | 54 | char num[NUM_SIZE]; //Temporary string storage to help with concatenation of strings |
danilob | 0:41904adca656 | 55 | |
es_marble | 29:bc5f53f2922a | 56 | //"Tick" of the GSM (i.e. this is a state machine) |
es_marble | 16:6807d437cd48 | 57 | void gsm_tick() |
es_marble | 16:6807d437cd48 | 58 | { |
es_marble | 29:bc5f53f2922a | 59 | //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 |
es_marble | 24:7d2ff444d6d8 | 60 | if (queueHasResponse() || gsm_timeOut() || gsm_current_state == GSM_INITIALIZE) |
es_marble | 16:6807d437cd48 | 61 | { |
es_marble | 27:fe1c7eaf5b88 | 62 | //gsm_printState(); //&debug |
es_marble | 27:fe1c7eaf5b88 | 63 | //printQueue(); //&debug |
es_marble | 16:6807d437cd48 | 64 | gsm_nextStateLogic(); //Next state |
es_marble | 29:bc5f53f2922a | 65 | gsm_mealyOutputs(); //Mealy outputs. This state machine is a little different because Mealy outputs come after the next state logic |
es_marble | 16:6807d437cd48 | 66 | } |
es_marble | 16:6807d437cd48 | 67 | } |
es_marble | 29:bc5f53f2922a | 68 | |
es_marble | 29:bc5f53f2922a | 69 | //Prints the current state. To save time printing, simply prints 1 character to indicate the current state. |
es_marble | 24:7d2ff444d6d8 | 70 | void gsm_printState() |
es_marble | 24:7d2ff444d6d8 | 71 | { |
es_marble | 24:7d2ff444d6d8 | 72 | pc.printf("S:%c;", state_chars[gsm_current_state]); |
es_marble | 24:7d2ff444d6d8 | 73 | } |
es_marble | 24:7d2ff444d6d8 | 74 | |
es_marble | 16:6807d437cd48 | 75 | //Advance timeout counter; if timeout, return true |
es_marble | 16:6807d437cd48 | 76 | bool gsm_timeOut() |
es_marble | 16:6807d437cd48 | 77 | { |
es_marble | 16:6807d437cd48 | 78 | if(++timeout_count >= TIMEOUTLIMIT){ |
es_marble | 24:7d2ff444d6d8 | 79 | timeout_count = 0; |
es_marble | 24:7d2ff444d6d8 | 80 | gsm_reset(); |
es_marble | 16:6807d437cd48 | 81 | return true; |
danilob | 15:19ae032e2e54 | 82 | } |
es_marble | 16:6807d437cd48 | 83 | else |
es_marble | 16:6807d437cd48 | 84 | return false; |
es_marble | 16:6807d437cd48 | 85 | } |
es_marble | 16:6807d437cd48 | 86 | |
es_marble | 24:7d2ff444d6d8 | 87 | //Have the GSM send data - L = long, S = short, hh/mm/ss for time, "lat ns" for latitute, "lon we" for longitude |
es_marble | 24:7d2ff444d6d8 | 88 | void gsm_send_data(float L, float Lref, float S, float Sref, int hh, int mm, int ss, float lat, char ns, float lon, char we) |
es_marble | 18:7642909bfcfc | 89 | { |
es_marble | 24:7d2ff444d6d8 | 90 | if (!gsm_ready()) //Don't send if gsm not ready |
es_marble | 24:7d2ff444d6d8 | 91 | return; |
es_marble | 24:7d2ff444d6d8 | 92 | |
es_marble | 26:838a9d26e8e9 | 93 | //Concatenate data |
es_marble | 24:7d2ff444d6d8 | 94 | gsm_msg[0] = NULL; |
es_marble | 26:838a9d26e8e9 | 95 | strcat(gsm_msg, BEGIN_SENSOR_DATA); |
es_marble | 24:7d2ff444d6d8 | 96 | snprintf(num, NUM_SIZE, "%f,", L); |
es_marble | 24:7d2ff444d6d8 | 97 | strcat(gsm_msg, num); |
es_marble | 24:7d2ff444d6d8 | 98 | snprintf(num, NUM_SIZE, "%f,", Lref); |
es_marble | 24:7d2ff444d6d8 | 99 | strcat(gsm_msg, num); |
es_marble | 24:7d2ff444d6d8 | 100 | snprintf(num, NUM_SIZE, "%f,", S); |
es_marble | 24:7d2ff444d6d8 | 101 | strcat(gsm_msg, num); |
es_marble | 26:838a9d26e8e9 | 102 | snprintf(num, NUM_SIZE, "%f,", Sref); |
es_marble | 24:7d2ff444d6d8 | 103 | strcat(gsm_msg, num); |
es_marble | 29:bc5f53f2922a | 104 | 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) |
es_marble | 26:838a9d26e8e9 | 105 | strcat(gsm_msg, num); |
es_marble | 29:bc5f53f2922a | 106 | if (ns != NULL) //If there is a gps fix (i.e. the gps has data on our location), ns will be set |
es_marble | 24:7d2ff444d6d8 | 107 | { |
es_marble | 29:bc5f53f2922a | 108 | snprintf(num, NUM_SIZE, "%.4f,%.4f", (ns == 'N') ? lat : -lat, (we == 'E') ? lon : -lon); //Use + or - rather than N/S, E/W |
es_marble | 24:7d2ff444d6d8 | 109 | strcat(gsm_msg, num); |
es_marble | 24:7d2ff444d6d8 | 110 | } |
es_marble | 29:bc5f53f2922a | 111 | else strcat(gsm_msg, "0,0"); //Otherwise just send 0's for latitude and longitude |
es_marble | 26:838a9d26e8e9 | 112 | strcat(gsm_msg, END_SENSOR_DATA); |
es_marble | 24:7d2ff444d6d8 | 113 | |
es_marble | 24:7d2ff444d6d8 | 114 | send = true; //Mark that we are currently sending a message |
es_marble | 24:7d2ff444d6d8 | 115 | strcat(gsm_msg, SMS_END_CHAR); //Add SMS end char |
es_marble | 18:7642909bfcfc | 116 | } |
es_marble | 24:7d2ff444d6d8 | 117 | |
es_marble | 24:7d2ff444d6d8 | 118 | //Return true if gsm is ready to send sms |
es_marble | 24:7d2ff444d6d8 | 119 | //This only occurs if send = false (not currently sending a message) AND gsm received start sequence |
es_marble | 18:7642909bfcfc | 120 | bool gsm_ready() |
es_marble | 18:7642909bfcfc | 121 | { |
es_marble | 24:7d2ff444d6d8 | 122 | return ((!send) && send_enable) ? true : false; |
es_marble | 18:7642909bfcfc | 123 | } |
es_marble | 24:7d2ff444d6d8 | 124 | |
es_marble | 29:bc5f53f2922a | 125 | //Reset the gsm. Currently this only resets the state, whether we are currently sending a message, and whether there are messages to delete. |
es_marble | 29:bc5f53f2922a | 126 | //It does not reset send_enable |
es_marble | 18:7642909bfcfc | 127 | void gsm_reset() |
es_marble | 18:7642909bfcfc | 128 | { |
es_marble | 29:bc5f53f2922a | 129 | //If we are in the middle of sending a text message, we need to "escape" out of this mode by sending the escape character |
es_marble | 24:7d2ff444d6d8 | 130 | if (gsm_current_state == GSM_AT_CMGS) |
es_marble | 24:7d2ff444d6d8 | 131 | sendCommand(SMS_ESCAPE_CHAR); |
es_marble | 24:7d2ff444d6d8 | 132 | |
es_marble | 18:7642909bfcfc | 133 | gsm_current_state = GSM_INITIALIZE; |
es_marble | 24:7d2ff444d6d8 | 134 | undeleted_msgs = true; |
es_marble | 24:7d2ff444d6d8 | 135 | send = false; |
es_marble | 18:7642909bfcfc | 136 | } |
es_marble | 24:7d2ff444d6d8 | 137 | |
es_marble | 16:6807d437cd48 | 138 | //Next state logic ----------------------------------------------------- |
es_marble | 29:bc5f53f2922a | 139 | //Note how each state (except init) checks the response received to make sure |
es_marble | 29:bc5f53f2922a | 140 | //GSM has properly executed the command. If the response is correct, it changes |
es_marble | 29:bc5f53f2922a | 141 | //the state so that the next command will be sent in the gsm_mealyOutputs function |
es_marble | 29:bc5f53f2922a | 142 | //below. |
es_marble | 16:6807d437cd48 | 143 | void gsm_nextStateLogic() |
es_marble | 16:6807d437cd48 | 144 | { |
es_marble | 16:6807d437cd48 | 145 | switch(gsm_current_state) |
es_marble | 16:6807d437cd48 | 146 | { |
danilob | 0:41904adca656 | 147 | case GSM_INITIALIZE: |
es_marble | 29:bc5f53f2922a | 148 | timeout_count = 0; //No AT commands have been sent: this will send the first one |
es_marble | 29:bc5f53f2922a | 149 | gsm_current_state = GSM_AT_OK; |
danilob | 0:41904adca656 | 150 | break; |
danilob | 0:41904adca656 | 151 | case GSM_AT_OK: |
es_marble | 24:7d2ff444d6d8 | 152 | if (findInQueue(AT_OK_RESPONSE, true)) |
es_marble | 16:6807d437cd48 | 153 | gsm_current_state = GSM_AT_CSQ; |
danilob | 12:f3ccc43c4d3c | 154 | break; |
danilob | 12:f3ccc43c4d3c | 155 | case GSM_AT_CSQ: |
es_marble | 24:7d2ff444d6d8 | 156 | if(findInQueue(AT_CSQ_RESPONSE, true)) |
es_marble | 16:6807d437cd48 | 157 | gsm_current_state = GSM_AT_CREG; |
danilob | 2:8352ad91f2ee | 158 | break; |
danilob | 0:41904adca656 | 159 | case GSM_AT_CREG: |
es_marble | 24:7d2ff444d6d8 | 160 | if(findInQueue(AT_CREG_RESPONSE, true)) |
es_marble | 16:6807d437cd48 | 161 | { |
es_marble | 29:bc5f53f2922a | 162 | parseInt(); //After the CREG response we receive two integers. The second should be '1' (see AT_CREG_RESPONSE #define) |
es_marble | 24:7d2ff444d6d8 | 163 | if(parseInt() == 1) |
es_marble | 24:7d2ff444d6d8 | 164 | gsm_current_state = GSM_AT_CNMI; |
danilob | 12:f3ccc43c4d3c | 165 | } |
danilob | 0:41904adca656 | 166 | break; |
es_marble | 24:7d2ff444d6d8 | 167 | case GSM_AT_CNMI: |
es_marble | 24:7d2ff444d6d8 | 168 | if(findInQueue(AT_CNMI_RESPONSE, true)) |
es_marble | 24:7d2ff444d6d8 | 169 | gsm_current_state = GSM_AT_CMGF; |
es_marble | 24:7d2ff444d6d8 | 170 | break; |
danilob | 0:41904adca656 | 171 | case GSM_AT_CMGF: |
es_marble | 24:7d2ff444d6d8 | 172 | if(findInQueue(AT_CMGF_RESPONSE, true)) |
es_marble | 24:7d2ff444d6d8 | 173 | gsm_current_state = GSM_READ_MSG; |
es_marble | 24:7d2ff444d6d8 | 174 | break; |
es_marble | 24:7d2ff444d6d8 | 175 | case GSM_READ_MSG: |
es_marble | 29:bc5f53f2922a | 176 | if(send_enable) //If we are currently sending SMS, check if we need to stop transmission of SMS |
es_marble | 24:7d2ff444d6d8 | 177 | { |
es_marble | 24:7d2ff444d6d8 | 178 | if(findInQueue(STOP_SMS_TRANSMISSION, true)) //Always stop sending if stop sequence received by SMS |
es_marble | 24:7d2ff444d6d8 | 179 | { |
es_marble | 24:7d2ff444d6d8 | 180 | undeleted_msgs = true; |
es_marble | 24:7d2ff444d6d8 | 181 | send_enable = false; //Set send_enable to indicate we will stop sending SMS |
es_marble | 24:7d2ff444d6d8 | 182 | } |
es_marble | 24:7d2ff444d6d8 | 183 | else if (send) //Only continue sending if we didn't find stop sequence AND user requested that we send sms |
es_marble | 24:7d2ff444d6d8 | 184 | gsm_current_state = GSM_AT_CMGS; //Continue sending SMS (change state accordingly) |
es_marble | 24:7d2ff444d6d8 | 185 | //Implicit: otherwise we will continue checking text messages in this state. |
es_marble | 24:7d2ff444d6d8 | 186 | } |
es_marble | 29:bc5f53f2922a | 187 | else //If we are not yet sending SMS, check if we need to start transmission of SMS |
es_marble | 24:7d2ff444d6d8 | 188 | { |
es_marble | 24:7d2ff444d6d8 | 189 | if(findInQueue(START_SMS_TRANSMISSION, true)) |
es_marble | 24:7d2ff444d6d8 | 190 | { |
es_marble | 24:7d2ff444d6d8 | 191 | undeleted_msgs = true; |
es_marble | 29:bc5f53f2922a | 192 | send_enable = true; //Now we are in send SMS mode: whenever 'send' variable is set to true we will send an SMS |
es_marble | 29:bc5f53f2922a | 193 | if (send) //Only begin sending a new SMS if user requested that we send SMS (i.e. there is data to send) |
es_marble | 24:7d2ff444d6d8 | 194 | gsm_current_state = GSM_AT_CMGS; //Start sending SMS (change state accordingly) |
es_marble | 24:7d2ff444d6d8 | 195 | } |
es_marble | 24:7d2ff444d6d8 | 196 | } |
danilob | 0:41904adca656 | 197 | break; |
danilob | 0:41904adca656 | 198 | case GSM_AT_CMGS: |
es_marble | 24:7d2ff444d6d8 | 199 | if(findInQueue(AT_CMGS_RESPONSE, true)) |
es_marble | 16:6807d437cd48 | 200 | gsm_current_state = GSM_AT_SENDSMS; |
danilob | 0:41904adca656 | 201 | break; |
danilob | 0:41904adca656 | 202 | case GSM_AT_SENDSMS: |
es_marble | 24:7d2ff444d6d8 | 203 | if(findInQueue(AT_SENDSMS_RESPONSE, true)) |
es_marble | 18:7642909bfcfc | 204 | { |
es_marble | 27:fe1c7eaf5b88 | 205 | //pc.printf("(Wid%i)",parseInt());//&debug |
es_marble | 24:7d2ff444d6d8 | 206 | timeout_count = 0; //Reset timeout count |
es_marble | 29:bc5f53f2922a | 207 | send = false; //Indicate we are done sending the text message |
es_marble | 24:7d2ff444d6d8 | 208 | if (undeleted_msgs) //Check if we need to delete read messages |
es_marble | 29:bc5f53f2922a | 209 | gsm_current_state = GSM_DEL_R_MSGS; //Only delete messages if there are unread messages |
es_marble | 24:7d2ff444d6d8 | 210 | else |
es_marble | 18:7642909bfcfc | 211 | { |
es_marble | 29:bc5f53f2922a | 212 | gsm_current_state = GSM_READ_MSG; //Otherwise skip the delete messages state; go read text messages again |
es_marble | 27:fe1c7eaf5b88 | 213 | //pc.printf("(Dnone)");//&debug |
es_marble | 18:7642909bfcfc | 214 | } |
es_marble | 18:7642909bfcfc | 215 | } |
es_marble | 16:6807d437cd48 | 216 | else |
es_marble | 24:7d2ff444d6d8 | 217 | { |
es_marble | 27:fe1c7eaf5b88 | 218 | //pc.printf("(Werr)"); //&debug |
es_marble | 24:7d2ff444d6d8 | 219 | gsm_current_state = GSM_AT_CMGS; //If failed, try resending the message (i.e. continue until timeout) |
es_marble | 24:7d2ff444d6d8 | 220 | } |
danilob | 0:41904adca656 | 221 | break; |
es_marble | 24:7d2ff444d6d8 | 222 | case GSM_DEL_R_MSGS: |
es_marble | 24:7d2ff444d6d8 | 223 | if (findInQueue(AT_DEL_R_MSGS_RESPONSE, true)) |
es_marble | 18:7642909bfcfc | 224 | { |
es_marble | 24:7d2ff444d6d8 | 225 | undeleted_msgs = false; |
es_marble | 27:fe1c7eaf5b88 | 226 | //pc.printf("(Dsucc)"); //&debug |
es_marble | 18:7642909bfcfc | 227 | } |
es_marble | 27:fe1c7eaf5b88 | 228 | //else |
es_marble | 27:fe1c7eaf5b88 | 229 | //pc.printf("(Derr)"); //&debug |
es_marble | 24:7d2ff444d6d8 | 230 | gsm_current_state = GSM_READ_MSG; |
danilob | 0:41904adca656 | 231 | break; |
danilob | 0:41904adca656 | 232 | default: |
es_marble | 27:fe1c7eaf5b88 | 233 | //pc.printf("This is a state error\r\n"); |
danilob | 0:41904adca656 | 234 | } |
danilob | 0:41904adca656 | 235 | } |
es_marble | 24:7d2ff444d6d8 | 236 | |
es_marble | 16:6807d437cd48 | 237 | //Mealy output logic ------------------------------------------------------ |
es_marble | 16:6807d437cd48 | 238 | void gsm_mealyOutputs() |
es_marble | 16:6807d437cd48 | 239 | { |
es_marble | 16:6807d437cd48 | 240 | switch(gsm_current_state) |
es_marble | 16:6807d437cd48 | 241 | { |
es_marble | 16:6807d437cd48 | 242 | case GSM_INITIALIZE: |
es_marble | 16:6807d437cd48 | 243 | break; |
es_marble | 16:6807d437cd48 | 244 | case GSM_AT_OK: |
es_marble | 24:7d2ff444d6d8 | 245 | sendCommand(AT_OK); |
es_marble | 16:6807d437cd48 | 246 | break; |
es_marble | 16:6807d437cd48 | 247 | case GSM_AT_CSQ: |
es_marble | 24:7d2ff444d6d8 | 248 | sendCommand(AT_CSQ); |
es_marble | 16:6807d437cd48 | 249 | break; |
es_marble | 16:6807d437cd48 | 250 | case GSM_AT_CREG: |
es_marble | 24:7d2ff444d6d8 | 251 | sendCommand(AT_CREG); |
es_marble | 16:6807d437cd48 | 252 | break; |
es_marble | 24:7d2ff444d6d8 | 253 | case GSM_AT_CNMI: |
es_marble | 24:7d2ff444d6d8 | 254 | sendCommand(AT_CNMI); |
es_marble | 24:7d2ff444d6d8 | 255 | break; |
es_marble | 24:7d2ff444d6d8 | 256 | case GSM_AT_CMGF: |
es_marble | 24:7d2ff444d6d8 | 257 | sendCommand(AT_CMGF); |
es_marble | 24:7d2ff444d6d8 | 258 | break; |
es_marble | 24:7d2ff444d6d8 | 259 | case GSM_READ_MSG: |
es_marble | 24:7d2ff444d6d8 | 260 | sendCommand(AT_READ_MSG); |
es_marble | 24:7d2ff444d6d8 | 261 | break; |
es_marble | 16:6807d437cd48 | 262 | case GSM_AT_CMGS: |
es_marble | 24:7d2ff444d6d8 | 263 | sendCommand(AT_CMGS); |
es_marble | 16:6807d437cd48 | 264 | break; |
es_marble | 16:6807d437cd48 | 265 | case GSM_AT_SENDSMS: |
es_marble | 24:7d2ff444d6d8 | 266 | sendCommand(gsm_msg); //end char included |
es_marble | 16:6807d437cd48 | 267 | break; |
es_marble | 24:7d2ff444d6d8 | 268 | case GSM_DEL_R_MSGS: |
es_marble | 24:7d2ff444d6d8 | 269 | sendCommand(AT_DEL_R_MSGS); |
danilob | 19:a442b5a0116f | 270 | break; |
es_marble | 16:6807d437cd48 | 271 | default: |
es_marble | 27:fe1c7eaf5b88 | 272 | //pc.printf("This is a state error\r\n"); |
es_marble | 16:6807d437cd48 | 273 | } |
es_marble | 16:6807d437cd48 | 274 | } |
es_marble | 29:bc5f53f2922a | 275 | |
es_marble | 18:7642909bfcfc | 276 | //Initialize the GSM |
es_marble | 28:81f1c8bd3299 | 277 | void gsm_initialize(){ |
es_marble | 29:bc5f53f2922a | 278 | wait(2.3); //Wait for the GSM to turn on properly before doing this initialization |
danilob | 7:6c0b6ab3cafe | 279 | SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK; //enabling dmamux clock |
danilob | 12:f3ccc43c4d3c | 280 | SIM_SCGC7 |= SIM_SCGC7_DMA_MASK; // enebaling dma clock |
es_marble | 27:fe1c7eaf5b88 | 281 | //pc.printf("initializing DMA...\r\n"); |
es_marble | 29:bc5f53f2922a | 282 | // control register mux, enabling uart3 receive |
danilob | 0:41904adca656 | 283 | DMAMUX_CHCFG0 |= DMAMUX_CHCFG_ENBL_MASK|DMAMUX_CHCFG_SOURCE(8); |
danilob | 0:41904adca656 | 284 | |
danilob | 0:41904adca656 | 285 | // Enable request signal for channel 0 |
danilob | 0:41904adca656 | 286 | DMA_ERQ = DMA_ERQ_ERQ0_MASK; |
danilob | 0:41904adca656 | 287 | |
danilob | 0:41904adca656 | 288 | // select round-robin arbitration priority |
danilob | 0:41904adca656 | 289 | DMA_CR |= DMA_CR_ERCA_MASK; |
danilob | 0:41904adca656 | 290 | |
es_marble | 29:bc5f53f2922a | 291 | //enable error interrupt for DMA0 (commented out because we won't use interrupts for our implementation) |
es_marble | 29:bc5f53f2922a | 292 | //DMA_EEI = DMA_EEI_EEI0_MASK; |
es_marble | 29:bc5f53f2922a | 293 | |
es_marble | 29:bc5f53f2922a | 294 | //Address for buffer |
danilob | 0:41904adca656 | 295 | DMA_TCD0_SADDR = (uint32_t) &UART_D_REG(UART3_BASE_PTR); |
danilob | 0:41904adca656 | 296 | DMA_TCD0_DADDR = (uint32_t) buffer; |
danilob | 0:41904adca656 | 297 | // Set an offset for source and destination address |
danilob | 0:41904adca656 | 298 | DMA_TCD0_SOFF = 0x00; |
danilob | 0:41904adca656 | 299 | DMA_TCD0_DOFF = 0x01; // Destination address offset of 1 byte per transaction |
danilob | 0:41904adca656 | 300 | |
danilob | 0:41904adca656 | 301 | // Set source and destination data transfer size |
danilob | 0:41904adca656 | 302 | DMA_TCD0_ATTR = DMA_ATTR_SSIZE(0) | DMA_ATTR_DSIZE(0); |
danilob | 0:41904adca656 | 303 | |
danilob | 0:41904adca656 | 304 | // Number of bytes to be transfered in each service request of the channel |
danilob | 0:41904adca656 | 305 | DMA_TCD0_NBYTES_MLNO = 0x01; |
danilob | 0:41904adca656 | 306 | // Current major iteration count |
danilob | 0:41904adca656 | 307 | DMA_TCD0_CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(BUFFER_LENGTH); |
danilob | 0:41904adca656 | 308 | DMA_TCD0_BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(BUFFER_LENGTH); |
danilob | 0:41904adca656 | 309 | // Adjustment value used to restore the source and destiny address to the initial value |
danilob | 0:41904adca656 | 310 | // 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) |
es_marble | 16:6807d437cd48 | 311 | DMA_TCD0_SLAST = 0; // Source address adjustment |
es_marble | 16:6807d437cd48 | 312 | DMA_TCD0_DLASTSGA = -BUFFER_LENGTH; // Destination address adjustment |
danilob | 0:41904adca656 | 313 | // Setup control and status register |
danilob | 0:41904adca656 | 314 | DMA_TCD0_CSR = 0; |
danilob | 0:41904adca656 | 315 | |
danilob | 0:41904adca656 | 316 | // enable interrupt call at end of major loop |
danilob | 0:41904adca656 | 317 | DMA_TCD0_CSR |= DMA_CSR_INTMAJOR_MASK; |
danilob | 0:41904adca656 | 318 | |
es_marble | 29:bc5f53f2922a | 319 | //Activate dma transfer rx interrupt |
danilob | 0:41904adca656 | 320 | UART_C2_REG(UART3) |= UART_C2_RIE_MASK; |
danilob | 0:41904adca656 | 321 | UART_C5_REG(UART3) |= UART_C5_RDMAS_MASK | UART_C5_ILDMAS_MASK | UART_C5_LBKDDMAS_MASK; |
es_marble | 29:bc5f53f2922a | 322 | //activate p fifo register |
danilob | 0:41904adca656 | 323 | UART_PFIFO_REG(UART3) |= UART_PFIFO_RXFE_MASK; //RXFE and buffer size of 1 word |
danilob | 7:6c0b6ab3cafe | 324 | queueInit(); |
es_marble | 27:fe1c7eaf5b88 | 325 | //pc.printf("done...\n\r"); |
danilob | 0:41904adca656 | 326 | } |
es_marble | 24:7d2ff444d6d8 | 327 | |
es_marble | 29:bc5f53f2922a | 328 | //For debugging: print registers related to DMA and UART setup |
es_marble | 29:bc5f53f2922a | 329 | void print_registers() |
es_marble | 29:bc5f53f2922a | 330 | { |
danilob | 0:41904adca656 | 331 | pc.printf("\n\rDMA REGISTERS\n\r"); |
danilob | 0:41904adca656 | 332 | pc.printf("DMA_MUX: 0x%08x\r\n",DMAMUX_CHCFG0); |
danilob | 0:41904adca656 | 333 | pc.printf("SADDR0: 0x%08x\r\n",DMA_TCD0_SADDR); |
danilob | 0:41904adca656 | 334 | pc.printf("DADDR0: 0x%08x\r\n",DMA_TCD0_DADDR); |
danilob | 0:41904adca656 | 335 | pc.printf("CITER0: 0x%08x\r\n",DMA_TCD0_CITER_ELINKNO); |
danilob | 0:41904adca656 | 336 | pc.printf("BITER0: 0x%08x\r\n",DMA_TCD0_BITER_ELINKNO); |
danilob | 0:41904adca656 | 337 | pc.printf("DMA_CR: %08x\r\n", DMA_CR); |
danilob | 0:41904adca656 | 338 | pc.printf("DMA_ES: %08x\r\n", DMA_ES); |
danilob | 0:41904adca656 | 339 | pc.printf("DMA_ERQ: %08x\r\n", DMA_ERQ); |
danilob | 0:41904adca656 | 340 | pc.printf("DMA_EEI: %08x\r\n", DMA_EEI); |
danilob | 0:41904adca656 | 341 | pc.printf("DMA_CEEI: %02x\r\n", DMA_CEEI); |
danilob | 0:41904adca656 | 342 | pc.printf("DMA_SEEI: %02x\r\n", DMA_SEEI); |
danilob | 0:41904adca656 | 343 | pc.printf("DMA_CERQ: %02x\r\n", DMA_CERQ); |
danilob | 0:41904adca656 | 344 | pc.printf("DMA_SERQ: %02x\r\n", DMA_SERQ); |
danilob | 0:41904adca656 | 345 | pc.printf("DMA_CDNE: %02x\r\n", DMA_CDNE); |
danilob | 0:41904adca656 | 346 | pc.printf("DMA_SSRT: %02x\r\n", DMA_SSRT); |
danilob | 0:41904adca656 | 347 | pc.printf("DMA_CERR: %02x\r\n", DMA_CERR); |
danilob | 0:41904adca656 | 348 | pc.printf("DMA_CINT: %02x\r\n", DMA_CINT); |
danilob | 0:41904adca656 | 349 | pc.printf("DMA_INT: %08x\r\n", DMA_INT); |
danilob | 0:41904adca656 | 350 | pc.printf("DMA_ERR: %08x\r\n", DMA_ERR); |
danilob | 0:41904adca656 | 351 | pc.printf("DMA_HRS: %08x\r\n", DMA_HRS); |
danilob | 0:41904adca656 | 352 | pc.printf("DMA_TCD0_DOFF: %08x\r\n",DMA_TCD0_DOFF); |
danilob | 0:41904adca656 | 353 | pc.printf("\n\rUART REGISTERS\n\r"); |
danilob | 0:41904adca656 | 354 | pc.printf("UART_BDH_REG: %08x\r\n",UART_BDH_REG(UART3)); |
danilob | 0:41904adca656 | 355 | pc.printf("UART_C1_REG: %08x\r\n",UART_C1_REG(UART3)); |
danilob | 0:41904adca656 | 356 | pc.printf("UART_C2_REG: %08x\r\n",UART_C2_REG(UART3)); |
danilob | 0:41904adca656 | 357 | pc.printf("UART_S1_REG: %08x\r\n",UART_S1_REG(UART3)); |
es_marble | 16:6807d437cd48 | 358 | pc.printf("UART_s2_REG: %08x\r\n",UART_S2_REG(UART3)); |
danilob | 0:41904adca656 | 359 | pc.printf("UART_C3_REG: %08x\r\n",UART_C3_REG(UART3)); |
danilob | 0:41904adca656 | 360 | pc.printf("UART_D_REG: %08x\r\n",UART_D_REG(UART3)); |
danilob | 0:41904adca656 | 361 | pc.printf("UART_MA1_REG: %08x\r\n",UART_MA1_REG(UART3)); |
danilob | 0:41904adca656 | 362 | pc.printf("UART_MA2_REG: %08x\r\n",UART_MA2_REG(UART3)); |
danilob | 0:41904adca656 | 363 | pc.printf("UART_C4_REG: %08x\r\n",UART_C4_REG(UART3)); |
danilob | 0:41904adca656 | 364 | pc.printf("UART_C5_REG: %08x\r\n",UART_C5_REG(UART3)); |
es_marble | 16:6807d437cd48 | 365 | pc.printf("UART_ED_REG: %08x\r\n",UART_ED_REG(UART3)); |
danilob | 0:41904adca656 | 366 | pc.printf("UART_MODEM_REG: %08x\r\n",UART_MODEM_REG(UART3)); |
danilob | 0:41904adca656 | 367 | pc.printf("UART_IR_REG: %08x\r\n",UART_IR_REG(UART3)); |
danilob | 0:41904adca656 | 368 | pc.printf("UART_PFIFO_REG: %08x\r\n",UART_PFIFO_REG(UART3)); |
danilob | 0:41904adca656 | 369 | pc.printf("UART_CFIFO_REG: %08x\r\n",UART_CFIFO_REG(UART3)); |
danilob | 0:41904adca656 | 370 | pc.printf("UART_SFIFO_REG: %08x\r\n",UART_SFIFO_REG(UART3)); |
danilob | 0:41904adca656 | 371 | pc.printf("UART_TWFIFO_REG: %08x\r\n",UART_TWFIFO_REG(UART3)); |
danilob | 0:41904adca656 | 372 | pc.printf("UART_TCFIFO_REG: %08x\r\n",UART_TCFIFO_REG(UART3)); |
danilob | 0:41904adca656 | 373 | pc.printf("UART_RWFIFO_REG: %08x\r\n",UART_RWFIFO_REG(UART3)); |
danilob | 0:41904adca656 | 374 | pc.printf("UART_RCFIFO_REG: %08x\r\n",UART_RCFIFO_REG(UART3)); |
es_marble | 29:bc5f53f2922a | 375 | } |