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
- Committer:
- es_marble
- Date:
- 2015-03-07
- Revision:
- 18:7642909bfcfc
- Parent:
- 17:360afa1e6809
- Child:
- 19:a442b5a0116f
File content as of revision 18:7642909bfcfc:
#include "GSMLibrary.h" #include "gsmqueue.h" #include <string.h> #define TIME_CONST .3 #define SECONDS_TIMEOUT 40 #define TIMEOUTLIMIT SECONDS_TIMEOUT/TIME_CONST //$change check with main code this will set up condition fior timeout. //definition for AT comands #define AT_OK "AT" #define AT_CSQ "AT+CSQ" #define AT_CREG "AT+CREG?" #define AT_CMGF "AT+CMGF=1" #define RECEIVER_PHONE_NUMBER "\"+18014722842\"" #define AT_CMGS "AT+CMGS=" RECEIVER_PHONE_NUMBER #define MESSAGE_BODY "stress test\32\32" #define MSG_SIZE 200 //Definition for AT repsonses //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 #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 #define AT_CMGF_RESPONSE "OK" #define AT_CMGS_RESPONSE ">" //Message is written aftersymbol #define AT_SENDSMS_RESPONSE ">" // +CMGS: <id> this will include the message id. CMGS ERROR for error and #define AT_SUCCESS_RESPONSE "+CMGS:" //External variables extern Serial pc; extern Serial gsm; extern uint8_t buffer[BUFFER_LENGTH];//buffer storing char //Internal variables gsm_states gsm_current_state = GSM_INITIALIZE; char send = 0; int timeout_count = 0; char gsm_msg[MSG_SIZE + 1]; //1 extra for Ctrl+Z void gsm_tick() { if (getGSMIdleBit() || gsm_timeOut() || (send && gsm_current_state == GSM_INITIALIZE)) //question with send... { resetGSMIdleBit(); //reset GSM idle bit gsm_nextStateLogic(); //Next state gsm_mealyOutputs(); //Mealy outputs flushQueue(); //Flush the queue } } //Advance timeout counter; if timeout, return true bool gsm_timeOut() { if(++timeout_count >= TIMEOUTLIMIT){ timeout_count=0; gsm_current_state = GSM_INITIALIZE; return true; } else return false; } //Have the GSM send a message void gsm_send_sms(char msg[]) { send = 1; strcpy(gsm_msg,msg); //If we need to optimize later we can do that, but this is more robust strcat(gsm_msg,"\x1A"); } //Return true if gsm is ready bool gsm_ready() { return (send == 1) ? true : false; } //Reset the gsm void gsm_reset() { gsm_current_state = GSM_INITIALIZE; } //Next state logic ----------------------------------------------------- void gsm_nextStateLogic() { printQueue(); //$debug switch(gsm_current_state) { case GSM_INITIALIZE: pc.printf("gsm_initialize state\r\n");//&debug timeout_count = 0; if (send) gsm_current_state = GSM_AT_OK; //unconditional (check it) break; case GSM_AT_OK: pc.printf("inside AT_OK state\r\n");//&debug if (findInQueue(AT_OK_RESPONSE)) gsm_current_state = GSM_AT_CSQ; break; case GSM_AT_CSQ: pc.printf("inside AT_CSQ state \r\n");//&debug if(findInQueue(AT_CSQ_RESPONSE)) gsm_current_state = GSM_AT_CREG; break; case GSM_AT_CREG: pc.printf("gsm_creg state\r\n");//&debug if(findInQueue(AT_CREG_RESPONSE)) { pc.printf("creg parse Int1: %d\r\n",parseInt());//&debug int q = parseInt(); pc.printf("creg parse Int2: %d\r\n",q);//&debug if(q == 1) gsm_current_state = GSM_AT_CMGF; } break; case GSM_AT_CMGF: pc.printf("gsm_cmgf state\r\n");//&debug if(findInQueue(AT_CMGF_RESPONSE)) gsm_current_state = GSM_AT_CMGS; break; case GSM_AT_CMGS: pc.printf("gsm_cmgs state\r\n");//&debug if(findInQueue(AT_CMGS_RESPONSE)) gsm_current_state = GSM_AT_SENDSMS; break; case GSM_AT_SENDSMS: pc.printf("gsm_send_sms state\r\n");//&debug if(findInQueue(AT_SENDSMS_RESPONSE)) //> { //Check if the "successfully sent" has also already been received (most likely //this won't be the case, but if it has been >500 ms there's a possibility //we've received both the messages during the same call to our state machine.) if(findInQueue(AT_SUCCESS_RESPONSE)) { pc.printf("Message SENT! msgID: %iY\r\n",parseInt());//&debug send = 0; gsm_current_state = GSM_INITIALIZE; //Skip success state (we've received both) } else gsm_current_state = GSM_SUCCESS; //Go to success state } else gsm_current_state = GSM_AT_CMGS; //Try resending the message (until timeout) break; case GSM_SUCCESS: pc.printf("gsm_success state\r\n");//&debug if(findInQueue(AT_SUCCESS_RESPONSE)) { pc.printf("Message SENT! msgID: %iY\r\n",parseInt());//&debug } send = 0; gsm_current_state = GSM_INITIALIZE; //We will restart regardless of whether it worked break; default: pc.printf("This is a state error"); } } //Mealy output logic ------------------------------------------------------ void gsm_mealyOutputs() { switch(gsm_current_state) { case GSM_INITIALIZE: pc.printf("No Mealy initialize state output\r\n");//&debug break; case GSM_AT_OK: pc.printf("sending AT_OK\r\n");//&debug gsm.puts(AT_OK); gsm.puts("\r\n"); break; case GSM_AT_CSQ: pc.printf("sending AT_CSQ\r\n");//&debug gsm.puts(AT_CSQ); gsm.puts("\r\n"); break; case GSM_AT_CREG: pc.printf("sending AT_CREG\r\n");//&debug gsm.puts(AT_CREG); gsm.puts("\r\n"); break; case GSM_AT_CMGF: pc.printf("sending AT_CMGF\r\n");//&debug gsm.puts(AT_CMGF); gsm.puts("\r\n"); break; case GSM_AT_CMGS: pc.printf("sending AT_CMGS\r\n");//&debug gsm.puts(AT_CMGS); gsm.puts("\r\n"); break; case GSM_AT_SENDSMS: pc.printf("sending message\r\n");//&debug gsm.puts(gsm_msg); //substitute char included gsm.puts("\r\n"); break; case GSM_SUCCESS: pc.printf("No Mealy success state output\r\n");//&debug default: pc.printf("This is a state error"); } } //Initialize the GSM void gsm_initialize(){ SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK; //enabling dmamux clock SIM_SCGC7 |= SIM_SCGC7_DMA_MASK; // enebaling dma clock pc.printf("initializing tregisters...!\r\n"); // control register mux, enabling uart3 receive DMAMUX_CHCFG0 |= DMAMUX_CHCFG_ENBL_MASK|DMAMUX_CHCFG_SOURCE(8); // Enable request signal for channel 0 DMA_ERQ = DMA_ERQ_ERQ0_MASK; // 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 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 DMA_TCD0_SOFF = 0x00; DMA_TCD0_DOFF = 0x01; // Destination address offset of 1 byte per transaction // Set source and destination data transfer size DMA_TCD0_ATTR = DMA_ATTR_SSIZE(0) | DMA_ATTR_DSIZE(0); // Number of bytes to be transfered in each service request of the channel DMA_TCD0_NBYTES_MLNO = 0x01; // Current major iteration count DMA_TCD0_CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(BUFFER_LENGTH); DMA_TCD0_BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(BUFFER_LENGTH); // Adjustment value used to restore the source and destiny address to the initial value // 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) DMA_TCD0_SLAST = 0; // Source address adjustment DMA_TCD0_DLASTSGA = -BUFFER_LENGTH; // Destination address adjustment // Setup control and status register DMA_TCD0_CSR = 0; // enable interrupt call at end of major loop DMA_TCD0_CSR |= DMA_CSR_INTMAJOR_MASK; //Activate dma trasnfer 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 UART_PFIFO_REG(UART3) |= UART_PFIFO_RXFE_MASK; //RXFE and buffer size of 1 word queueInit(); pc.printf("Initialization done...\n\r"); } //initialization debuging purposes 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); pc.printf("DADDR0: 0x%08x\r\n",DMA_TCD0_DADDR); pc.printf("CITER0: 0x%08x\r\n",DMA_TCD0_CITER_ELINKNO); pc.printf("BITER0: 0x%08x\r\n",DMA_TCD0_BITER_ELINKNO); pc.printf("DMA_CR: %08x\r\n", DMA_CR); pc.printf("DMA_ES: %08x\r\n", DMA_ES); pc.printf("DMA_ERQ: %08x\r\n", DMA_ERQ); pc.printf("DMA_EEI: %08x\r\n", DMA_EEI); pc.printf("DMA_CEEI: %02x\r\n", DMA_CEEI); pc.printf("DMA_SEEI: %02x\r\n", DMA_SEEI); pc.printf("DMA_CERQ: %02x\r\n", DMA_CERQ); pc.printf("DMA_SERQ: %02x\r\n", DMA_SERQ); pc.printf("DMA_CDNE: %02x\r\n", DMA_CDNE); pc.printf("DMA_SSRT: %02x\r\n", DMA_SSRT); pc.printf("DMA_CERR: %02x\r\n", DMA_CERR); pc.printf("DMA_CINT: %02x\r\n", DMA_CINT); pc.printf("DMA_INT: %08x\r\n", DMA_INT); pc.printf("DMA_ERR: %08x\r\n", DMA_ERR); pc.printf("DMA_HRS: %08x\r\n", DMA_HRS); pc.printf("DMA_TCD0_DOFF: %08x\r\n",DMA_TCD0_DOFF); pc.printf("\n\rUART REGISTERS\n\r"); pc.printf("UART_BDH_REG: %08x\r\n",UART_BDH_REG(UART3)); pc.printf("UART_C1_REG: %08x\r\n",UART_C1_REG(UART3)); pc.printf("UART_C2_REG: %08x\r\n",UART_C2_REG(UART3)); pc.printf("UART_S1_REG: %08x\r\n",UART_S1_REG(UART3)); pc.printf("UART_s2_REG: %08x\r\n",UART_S2_REG(UART3)); pc.printf("UART_C3_REG: %08x\r\n",UART_C3_REG(UART3)); pc.printf("UART_D_REG: %08x\r\n",UART_D_REG(UART3)); pc.printf("UART_MA1_REG: %08x\r\n",UART_MA1_REG(UART3)); pc.printf("UART_MA2_REG: %08x\r\n",UART_MA2_REG(UART3)); pc.printf("UART_C4_REG: %08x\r\n",UART_C4_REG(UART3)); pc.printf("UART_C5_REG: %08x\r\n",UART_C5_REG(UART3)); pc.printf("UART_ED_REG: %08x\r\n",UART_ED_REG(UART3)); pc.printf("UART_MODEM_REG: %08x\r\n",UART_MODEM_REG(UART3)); pc.printf("UART_IR_REG: %08x\r\n",UART_IR_REG(UART3)); pc.printf("UART_PFIFO_REG: %08x\r\n",UART_PFIFO_REG(UART3)); pc.printf("UART_CFIFO_REG: %08x\r\n",UART_CFIFO_REG(UART3)); pc.printf("UART_SFIFO_REG: %08x\r\n",UART_SFIFO_REG(UART3)); pc.printf("UART_TWFIFO_REG: %08x\r\n",UART_TWFIFO_REG(UART3)); 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)); }