By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,961 Members | 1,320 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,961 IT Pros & Developers. It's quick & easy.

Programming GM862 in C

P: 14
Hello I'm having trouble, BIG trouble programing a GM862 from telit.
First of all I'm using pic18f45k20, using development kit pickit3.
I've been trying to communicate with the pickit to the GM862 using UART (connecting TX and RX), I read online that it is fairly simple etc.. but it doesn't work for me..
I think the problem is my UART, I'm not sure how it works and I dont get any thing....
Below is the code I'm using deriving from the sample given from the vendor...
If someone can really help me on that! This is my final project to graduate! thank youuu...

Expand|Select|Wrap|Line Numbers
  1. #include <p18f45k20.h>
  2. #include <usart.h>
  3. #include <delays.h>
  4. #include <string.h>
  5. #include <stdio.h>
  6. #define in usart.h
  7. #define in usart.h
  8.  
  9.  
  10. // set of AT commands
  11. const char atc1[] = "ATE0";                      // disable command echo
  12. const char atc2[] = "AT# CAP= 1";                // enables handsfree external mic/ear audio path
  13. const char atc3[] = "ATD19168214521;";             // place a call to phone number 123456789
  14.                                                  // instead of 123456789 insert your phone number
  15. const char atc4[] = "ATH";                       // hang up
  16. const char atc5[] = "ATA";                       // answer a call
  17. const char atc6[] = "AT#HFMICG=4";               // handsfree microphone gain
  18. const char atc7[] = "AT#SHFEC=1";                // handsfree echo canceller
  19. const char atc8[] = "AT+CLVL=12";                // loudspeaker volume level
  20. const char atc9[] = "AT#SRS= 3,0";               // select ringer sound
  21. const char atc10[] = "ATS0=0";                   // number of rings to auto answer (auto answer disabled)
  22.  
  23.  
  24.  
  25. int GSM_OK    = 0;
  26. int GSM_RING  = 1;
  27.  
  28. char gsm_state = 0;
  29. char response_rcvd = 0;
  30. short responseID = -1, response = -1;
  31.  
  32.  
  33. // copy const to ram string
  34. char * CopyConst2Ram(char * dest, const char * src){
  35. char * d ;
  36.  d = dest;
  37.  for(;*dest++ = *src++;)
  38.   ;
  39.  return d;
  40. }
  41.  
  42. void interrupt() {
  43. char tmp;
  44. if (PIR1bits.RCIF == 1) {
  45.  
  46. tmp = ReadUSART();
  47.     switch (gsm_state) {
  48.       case  0: {
  49.                 response = -1;                   // clear response
  50.                 if (tmp == 'O')                  // we have 'O', it could be "OK"
  51.                   gsm_state = 1;                 // expecting 'K'
  52.                 if (tmp == 'R')                  // we have 'R', it could be "RING"
  53.                   gsm_state = 10;                // expecting 'I'
  54.                 break;
  55.                }
  56.       case  1: {
  57.                 if (tmp == 'K') {                // we have 'K' ->
  58.                   response = GSM_OK;             // we have "OK" response
  59.                   gsm_state = 50;                // expecting CR+LF
  60.                 }
  61.                 else
  62.                   gsm_state = 0;                 // reset state machine
  63.                 break;
  64.                }
  65.       case 10: {
  66.                 if (tmp == 'I')                  // we have 'I', it could be "RING"
  67.                   gsm_state = 11;                // expecting 'N'
  68.                 else
  69.                   gsm_state = 0;                 // reset state machine
  70.                 break;
  71.                }
  72.       case 11: {
  73.                 if (tmp == 'N')                  // we have 'N', it could be "RING"
  74.                   gsm_state = 12;                // expecting 'G'
  75.                 else
  76.                   gsm_state = 0;                 // reset state machine
  77.                 break;
  78.                }
  79.       case 12: {
  80.                 if (tmp == 'G') {                // we have 'G' ->
  81.                   response = GSM_RING;           // we have "RING" response
  82.                   gsm_state = 50;                // expecting CR+LF
  83.                 }
  84.                 else
  85.                   gsm_state = 0;                 // reset state machine
  86.                 break;
  87.                }
  88.       case 50: {
  89.                 if (tmp == 13)                   // we have 13, it could be CR+LF
  90.                   gsm_state = 51;                // expecting LF
  91.                 else
  92.                   gsm_state = 0;                 // reset state machine
  93.                 break;
  94.                }
  95.       case 51: {
  96.                 if (tmp == 10) {                 // we have LF, response is complete
  97.                   response_rcvd = 1;             // set reception flag
  98.                   responseID = response;         // set response ID
  99.                 }
  100.                 gsm_state = 0;                   // reset state machine
  101.                 break;
  102.                }
  103.       default: {                                 // unwanted character
  104.                 gsm_state = 0;                   // reset state machine
  105.                 break;
  106.                }
  107.     }
  108.  
  109. }
  110. }
  111.  
  112. // send ATC command
  113.  
  114. void send_atc(const char *s)
  115. {
  116. // send command string
  117. while(*s) {
  118.     WriteUSART(*s++);
  119. // terminate command with CR
  120.    WriteUSART(0x0D);
  121. }
  122.  
  123. // get GSM response, if there is any
  124. short get_response() {
  125.   if (response_rcvd) {
  126.     response_rcvd = 0;
  127.     return responseID;
  128.   }
  129.   else
  130.     return -1;
  131. }
  132.  
  133. // wait for GSM response
  134. void wait_response(char rspns) {
  135.   while (get_response() != rspns)
  136.     ;
  137. }
  138.  
  139. // pause
  140. void wait() {
  141.    Delay1KTCYx(1000);
  142. }
  143.  
  144.  
  145. void main(){
  146. /*************199********************************************************************************************************************/
  147. // all pins as digital I/Os
  148.   ANSEL  = 0;
  149.   ANSELH = 0;
  150.  
  151. // set PORTD inputs
  152.   TRISDbits.TRISD0 = 1;                                // place a call input
  153.   TRISDbits.TRISD1 = 1;                                // hang up input
  154.   TRISDbits.TRISD2 = 1;                                // answer a call input
  155.   TRISDbits.TRISD3 = 1;                                // continue with PIC program
  156.  
  157. // set RTS pin to zero, we will use only RX i TX
  158.   TRISCbits.TRISC3 = 0;
  159.   PORTCbits.RC3 = 0;
  160.  
  161. // enable uart rx interrupt
  162.     PIE1bits.RCIE = 1;
  163.   INTCONbits.PEIE = 1;
  164.   INTCONbits.GIE  = 1;
  165. /*215********************************************************************************************************************************/
  166.  
  167.  
  168.                             // initialize USART module
  169. putrsUSART ((const far rom char *)"AT+IPR=19200\r");
  170.  
  171.  
  172.  
  173.   Delay1KTCYx(5000);                                // wait for the GSM module to initialize it self
  174.  
  175. // negotiate baud rate
  176.   while(1) {
  177.     send_atc("AT");                              // send "AT" string until gsm sets up its baud rade
  178.      Delay1KTCYx(100);                               // and gets it correctly
  179.     if (get_response() == GSM_OK)                // if gsm says "OK" on our baud rate we got it
  180.       break;
  181.   }
  182.  
  183.  
  184.  
  185.  
  186. // disable command echo
  187.   send_atc(atc1);
  188.   wait_response(GSM_OK);
  189.  
  190. send_atc(atc3);
  191. wait_response(GSM_OK);
  192.  
  193. // change audio path (enables handsfree external mic/ear audio path)
  194.   send_atc(atc2);
  195.   wait_response(GSM_OK);
  196.  
  197. // handsfree microphone gain
  198.    send_atc(atc6);
  199.    wait_response(GSM_OK);
  200.  
  201. // handsfree echo canceller
  202.    send_atc(atc7);
  203.    wait_response(GSM_OK);
  204.  
  205. // loudspeaker volume level
  206.    send_atc(atc8);
  207.    wait_response(GSM_OK);
  208.  
  209. // select ringer sound
  210.    send_atc(atc9);
  211.    wait_response(GSM_OK);
  212.  
  213. // number of rings to auto answer (auto answer disabled)
  214.    send_atc(atc10);
  215.    wait_response(GSM_OK);
  216.  
  217.  
  218.  
  219.       }
  220.  
  221.  
  222.  
  223.  
Nov 30 '10 #1
Share this Question
Share on Google+
10 Replies


Banfa
Expert Mod 5K+
P: 8,916
Firstly I would like to say I have used both these products without a problem. Admittedly not together I used a PIC with a Semiens GSM module and a Telit GSM module with a Cyan microprocessor.

You have a number of issues in you code that are not good. They may or may not be causing a problem.

Firstly I assume that you have actually connected the TX pin of the PIC to the RX pin of the Tellit and vice versa.


  • In the state machine use an enum to name your states, it will make reading the code a lot easier and eliminate magic numbers that are always a maintenance issue.
  • State 50 and 51 (at least), you are expecting a CR or LF but if it doesn't arrive you through the character away. What if there was a data error and the CR or LF was lost? What if the Telit is configured to not send either CR or LF (which is possible). That character you are throwing away could be the 'O' of OK or 'R' of RING. The state machine is not very resilient to the unexpected.
  • You have no error handling, most UARTS throw error interrupts.
  • You do not transmit a CR or CRLF at the end of any of your AT commands, the AT command protocol uses the CR or CRLF as the delimiter for the end of the command. Without the CR or CRLF you have not finished the command and the Telit command processor will not parse it and action it.
  • Line 176. Sending "AT" to auto baud. That is fine but you do not know the state of the Telits command processor when you send it. Better to clear it down with a few CR (or CRLF) first, something like
    1. Send CR
    2. Short Pause
    3. Send CR
    4. Short Pause
    5. Send CR
    6. Short Pause
    7. Send "AT\r"
    8. Long Pause
    9. If you don't get an OK then goto 1
    The Telit can auto baud off any character so hopefully the CR sequence will allow it to auto-baud and the first AT will work. It will also reset the Telits command processor so it will definitely be expecting an AT
  • Your program code has no resilience to commands not working.
Nov 30 '10 #2

P: 14
Thank you very much for your answer.
Yes I did connected TX to RX and vis versa.
I'm new at using MPLAB, when I compiled the program it builds it with no error.

I have a couple question, this code was taken from the vendor but was originally for another board but still using a pic.

@ line 46:
tmp = ReadUSART();

On the vendor example he was using Read1Usart() but when I try to compile with read1usart it doesn't work, so I changed it to readUSART.
Mplab tells me that I did not define it in the USART.H
Am I allow to do so? Or is it why I do not read anything? (since I'm using write1, purts1 etc.. but readUsart)

Thank you...
Nov 30 '10 #3

P: 14
Hello,
Ok so I think I got a little bit further
when testing my the program below my progam is stuck in the loop to find the baudrate.. Can you help me debug this?

I tried several method (forcing the baudrate to be 9600) but did not work either...

Also to try my pgm maybe I'm doing it wrong, I'm inserting a sim card and check the status led (pin 22 on GM862) but the led keeps blinking fast as it doesnt find a network.. so I know (or I think) my pgm is not working

Reading your post, you said something about handling error, but I'm pretty new to this and I dont know what to write. Would you have a code for it by any change? and where to implement it?



Expand|Select|Wrap|Line Numbers
  1.  
  2.  
  3. /** I N C L U D E S **************************************************/
  4.  
  5. #include <p18f45k20.h>
  6. #include <usart.h>
  7. #include <delays.h>
  8. #include <string.h>
  9. #include <stdio.h>
  10. #define in usart.h
  11. #define in usart.h
  12.  
  13. #pragma config FOSC = INTIO67
  14. #pragma config WDTEN = OFF, LVP = OFF, MCLRE = OFF
  15.  
  16.  
  17. // set of AT commands
  18. const char atc0[] = "AT\r";                      // disable command echo
  19. const char atc1[] = "ATE0\r";                      // disable command echo
  20. const char atc2[] = "AT# CAP= 1\r";                // enables handsfree external mic/ear audio path
  21. const char atc3[] = "ATD19168214521;\r";             // place a call to phone number 123456789
  22.                                                  // instead of 123456789 insert your phone number
  23. const char atc4[] = "ATH\r";                       // hang up
  24. const char atc5[] = "ATA\r";                       // answer a call
  25. const char atc6[] = "AT#HFMICG=4\r";               // handsfree microphone gain
  26. const char atc7[] = "AT#SHFEC=1\r";                // handsfree echo canceller
  27. const char atc8[] = "AT+CLVL=12\r";                // loudspeaker volume level
  28. const char atc9[] = "AT#SRS= 3,0\r";               // select ringer sound
  29. const char atc10[] = "ATS0=0\r";                   // number of rings to auto answer (auto answer disabled)
  30.  
  31.  
  32.  
  33.  
  34. short GSM_OK    = 0;
  35. short GSM_RING  = 1;
  36.  
  37. char gsm_state = 0;
  38. short response_rcvd = 0;
  39. short responseID = -1, response = -1;
  40.  
  41.  
  42. // copy const to ram string
  43. char * CopyConst2Ram(char * dest, const char * src){
  44. char * d ;
  45.  d = dest;
  46.  for(;*dest++ = *src++;)
  47.   ;
  48.  return d;
  49. }
  50.  
  51. void interrupt() {
  52. char tmp;
  53. if (PIR1bits.RCIF == 1) {
  54.  
  55. //State Machine, only parsing OK and RING machine
  56. tmp = ReadUSART();
  57.     switch (gsm_state) {
  58.       case  0: {
  59.                 response = -1;                   // clear response
  60.                 if (tmp == 'O')                  // we have 'O', it could be "OK"
  61.                   gsm_state = 1;                 // expecting 'K'
  62.                 if (tmp == 'R')                  // we have 'R', it could be "RING"
  63.                   gsm_state = 10;                // expecting 'I'
  64.                 break;
  65.                }
  66.       case  1: {
  67.                 if (tmp == 'K') {                // we have 'K' ->
  68.                   response = GSM_OK;             // we have "OK" response
  69.                   gsm_state = 50;                // expecting CR+LF
  70.                 }
  71.                 else
  72.                   gsm_state = 0;                 // reset state machine
  73.                 break;
  74.                }
  75.       case 10: {
  76.                 if (tmp == 'I')                  // we have 'I', it could be "RING"
  77.                   gsm_state = 11;                // expecting 'N'
  78.                 else
  79.                   gsm_state = 0;                 // reset state machine
  80.                 break;
  81.                }
  82.       case 11: {
  83.                 if (tmp == 'N')                  // we have 'N', it could be "RING"
  84.                   gsm_state = 12;                // expecting 'G'
  85.                 else
  86.                   gsm_state = 0;                 // reset state machine
  87.                 break;
  88.                }
  89.       case 12: {
  90.                 if (tmp == 'G') {                // we have 'G' ->
  91.                   response = GSM_RING;           // we have "RING" response
  92.                   gsm_state = 50;                // expecting CR+LF
  93.                 }
  94.                 else
  95.                   gsm_state = 0;                 // reset state machine
  96.                 break;
  97.                }
  98.       case 50: {
  99.                 if (tmp == 13)                   // we have 13, it could be CR+LF
  100.                   gsm_state = 51;                // expecting LF
  101.                 else
  102.                   gsm_state = 0;                 // reset state machine
  103.                 break;
  104.                }
  105.       case 51: {
  106.                 if (tmp == 10) {                 // we have LF, response is complete
  107.                   response_rcvd = 1;             // set reception flag
  108.                   responseID = response;         // set response ID
  109.                 }
  110.                 gsm_state = 0;                   // reset state machine
  111.                 break;
  112.                }
  113.       default: {                                 // unwanted character
  114.                 gsm_state = 0;                   // reset state machine
  115.                 break;
  116.                }
  117.     }
  118.  
  119. }
  120. }
  121.  
  122. // send ATC command
  123.  
  124. void send_atc(const char *s)
  125. {
  126. // send command string
  127. while(*s) {
  128.     WriteUSART(*s++);
  129. // terminate command with CR
  130.    WriteUSART(0x0D);
  131. }
  132.  
  133. // get GSM response, if there is any
  134. short get_response(void) {
  135.   if (response_rcvd) {
  136.     response_rcvd = 0;
  137.     return responseID;
  138.   }
  139.   else
  140.     return -1;
  141. }
  142.  
  143. // wait for GSM response
  144. void wait_response(char rspns) {
  145.   while (get_response() != rspns)
  146.     ;
  147. }
  148.  
  149. // pause
  150. void wait() {
  151.    Delay1KTCYx(1000);
  152. }
  153.  
  154.  
  155. void main(){
  156.  
  157. // all pins as digital I/Os
  158.   ANSEL  = 0;
  159.   ANSELH = 0;
  160.  
  161. // set PORTD inputs
  162.   TRISDbits.TRISD0 = 1;                                // place a call input
  163.   TRISDbits.TRISD1 = 1;                                // hang up input
  164.   TRISDbits.TRISD2 = 1;                                // answer a call input
  165.   TRISDbits.TRISD3 = 1;                                // continue with PIC program
  166.  
  167. TRISDbits.TRISD7 = 0; // led test
  168.  
  169. // set RTS pin to zero, we will use only RX i TX
  170.  TRISCbits.TRISC3= 0;
  171.   PORTCbits.RC3 = 0;
  172.  
  173. // enable uart rx interrupt
  174. //PIE1bits.RCIE = 1;
  175.   //INTCONbits.PEIE = 1;
  176.   //INTCONbits.GIE  = 1;
  177.  
  178. TRISCbits.TRISC7=1;
  179. TRISCbits.TRISC6=1;
  180.  
  181. SPBRGH=0x00;
  182. SPBRG=0x19;
  183. RCSTAbits.SPEN=1;
  184. BAUDCONbits.BRG16=1;
  185. TXSTAbits.BRGH=1;
  186. TXSTAbits.SYNC=0;
  187. TXSTAbits.TXEN=1;
  188.  
  189. LATDbits.LATD7 = 0;
  190.  
  191. while(!PORTD){
  192. LATDbits.LATD7 = 1;
  193. Delay1KTCYx(1000);
  194. };
  195.  
  196. LATDbits.LATD7 = 0; // led stage test
  197.  
  198. Delay1KTCYx(5000);                                
  199. // wait for the GSM module to initialize it self
  200.  
  201.  
  202. // negotiate baud rate
  203.   while(1) {
  204. LATDbits.LATD7 = 1; // LED stage test
  205.  WriteUSART(0x0D); // send cr
  206. send_atc(atc0);                              // send "AT"
  207. /*I also tried putrsUSART ((const far rom char *)"AT+IPR=9600\r"); instead of send_atc(atc0)*/
  208.  string until gsm sets up its baud rade
  209.      Delay1KTCYx(1000);                             // and gets it correctly
  210.     if (get_response() == GSM_OK)                // if gsm says "OK" on our baud rate we got it
  211.       break;
  212.   }
  213.  
  214.  
  215.  
  216. LATDbits.LATD7 = 0; //led stage test
  217.  
  218.  
  219.  
  220. // disable command echo
  221.   send_atc(atc1);
  222.   Delay1KTCYx(100); 
  223.  WriteUSART(0x0D);
  224.  
  225.  
  226. send_atc(atc3);
  227.   Delay1KTCYx(100); 
  228.  WriteUSART(0x0D);
  229.  
  230. // change audio path (enables handsfree external mic/ear audio path)
  231.   send_atc(atc2);
  232.  
  233.  WriteUSART(0x0D);
  234.  
  235.  
  236.  
  237.       }
  238.  
  239.  
  240.  
  241.  
Thanks a lot for the help
Dec 1 '10 #4

Banfa
Expert Mod 5K+
P: 8,916
You need to sort out sending the AT and auto-bauding before anything else. The

AT
OK

is the biggest hurdle to get over.

Checking the LED for network status is a bad way to tell, there are AT commands you can send to get the current SIM state

I trust you have downloaded Telits "AT Commands Reference Guide" (doc number 80000ST10025a Rev. 2 - 16/03/07, there might be a newer revision by now).

See AT+CREG section 3.5.4.3.3 on page 77 and AT+CPIN is good for checkjing if the SIM requres a PIN.

Are you trying to do voice call control?

In the code we used went something like this

Expand|Select|Wrap|Line Numbers
  1. for 5 times
  2.    Send "AT/r"
  3.    Wait for up to 1 second for a reply
  4.    Is the reply OK? 
  5.    If Yes break loop
  6. endfor
  7.  
You are only waiting Delay1KTCYx(100); or 1000000 clock ticks. On a multi MHz processor that is a fraction of a second. Comms is slow, particularly setting it up.

If you are having trouble then you should output everything you are receiving and everything you are sending to some debug device (I typically use a second UART if there is one to transmit data to a PC).

At the very least store everything in a buffer so you can halt the debugger and look at what has been received.
Dec 1 '10 #5

P: 14
Hi,
Got it I will implement the CREG commands to the code.
This might seem like a stupid question, but in the manual on their example they always have an example of the run of commands.

How do I get a display of the run?

Thanks =)
Dec 1 '10 #6

P: 14
Hi Banfa!

My loop is still stuck I changed my loop to
Expand|Select|Wrap|Line Numbers
  1. while(1)
  2. {
  3. char tmp;
  4. WriteUSART(0x0D); // send CR
  5. Delay10KTCYx(100);
  6. Delay10KTCYx(100);
  7. Delay10KTCYx(100);
  8. WriteUSART(0x0D); // send CR
  9. Delay10KTCYx(100);
  10. Delay10KTCYx(100);
  11. Delay10KTCYx(100);
  12. putrsUSART ((const far rom char *)"AT\r"); // sim
  13. Delay10KTCYx(100);
  14. Delay10KTCYx(100);
  15. Delay10KTCYx(100);
  16. Delay10KTCYx(100);
  17. Delay10KTCYx(100);
  18. Delay10KTCYx(100);
  19. tmp = ReadUSART();
  20. Delay10KTCYx(100);
  21. Delay10KTCYx(100);
  22. Delay10KTCYx(100);
  23. Delay10KTCYx(100);
  24. Delay10KTCYx(100);
  25. if (ReadUSART())
  26.     break;
  27. }
  28.  
  29.  
  30.  
  31.  
I doesnt work yet... As for debuging Im using the output window UART I/O I can see my commands being sent out but no answer.

Can you please take a look at my diagram I suspect it might be a hardware issue?
Attached Images
File Type: jpg lydiagram.jpg (45.5 KB, 1048 views)
Dec 2 '10 #7

Banfa
Expert Mod 5K+
P: 8,916
Sorry I've been busy for a couple of days.

The manuals examples are almost certainly created either in theory (i.e. written by hand) or by connecting the Telit to a PC and using a terminal program to send commands and receive answers (like Hyperterminal on Windows or better still an other terminal program, I like TeraTerm). The terminal Window output can be copied.

Can you debug the program, try setting a breakpoint in you interrupt routine. Break points in interrupt routines often (always?) break the program entirely and stop it continuing but can provide instantaneous information on what is going on. For instance are you getting any interrupts at all.

The diagram you have posted does not have enough resolution for me to read it. Make it bigger please.
Dec 3 '10 #8

P: 14
Hey Banfa!
Please don't apologize I feel very thankful that you are helping me.
I will try the hyperterminal, I've never done it before.

As far as breakpoint, I don't know how to use it yet in MPLAB. I know double-clicking will place a breakpoint, but how do I watch (follow) where my program is like you were telling me?

Thank you
Dec 4 '10 #9

Banfa
Expert Mod 5K+
P: 8,916
Once you have set the break point you run the program in debugger. The program should stop when execution reaches the place where you set the break point.

Unfortunately it is too long since I used MPLAB for me to remember which menu item you need to select but looker for "Start Debugging" or "Run in Debugger" or something like that.
Dec 4 '10 #10

P: 14
Great! It works,
I added more delays and it found the network and I was able to make a call.
One problem I have right now though is I tried to send a SMS
and when I put back my sim card to my phone I can not send text anymore but only receive...

Did I do something wrong with the setting?

Delay10KTCYx(50);
putrsUSART ((const far rom char *)"AT+CMGF=1\r"); // txt msg
Delay10KTCYx(50);
putrsUSART ((const far rom char *)"AT+CSCA=19168214521,129"); // txt msg
Delay10KTCYx(100);
Dec 12 '10 #11

Post your reply

Sign in to post your reply or Sign up for a free account.