State machine for parsing responses from a modem?

Hi everyone, I am a relatively new firmware developer and am especially new to working with cellular modems in general and Quectel in particular. Based on the AT command manual, I learned that responses of the modem are always of the form:

<CR><LF><response><CR><LF>

based on which I create a state machine to parse the results of AT command lines (image below) based on the assumption (from the manual) that responses will ALWAYS come enclosed within <CR><LF>.

State S0 is start, state S2 is where the <response> gets buffered and S4 is where parsing is finished. Please do not be confused by the ~ and ! - they’re just symbols I had used to denote CR and LF respectively in this diagram.

This seems to work fine for some commands but for others there are <CR><LF> in between that throw off the above state machine. For example the response to the ATI command is as follows:

[00:00:15.704,193] <inf> sb_at_parser: new data
                                       0d 0a 51 75 65 63 74 65  6c 0d 0a 45 43 38 30 30 |..Quecte l..EC800
                                       4d 0d 0a 52 65 76 69 73  69 6f 6e 3a 20 45 43 38 |M..Revis ion: EC8
                                       30 30 4d 43 4e 47 42 52  30 36 41 30 34 4d 30 38 |00MCNGBR 06A04M08
                                       0d 0a 0d 0a 4f 4b 0d 0a                          |....OK..         
[00:00:15.704,223] <inf> sb_at_parser: Parse success.
[00:00:15.704,254] <inf> sb_at_parser: Payload
                                       51 75 65 63 74 65 6c                             |Quectel          
[00:00:15.704,254] <inf> sb_at_parser: Parse success.
[00:00:15.704,315] <inf> sb_at_parser: Payload
                                       52 65 76 69 73 69 6f 6e  3a 20 45 43 38 30 30 4d |Revision : EC800M
                                       43 4e 47 42 52 30 36 41  30 34 4d 30 38          |CNGBR06A 04M08   
[00:00:15.704,345] <inf> sb_at_parser: Parse success.
[00:00:15.704,376] <inf> sb_at_parser: Payload
                                       4f 4b                                            |OK  

As you can see a block of data, namely EC800M gets ignored by the state machine because it is not enclosed in <CR><LF> but the other sentences get captured by the state machine.

I have highlighted the parts that are captured by the state machine in { } brackets

0d 0a {51 75 65 63 74 65  6c} 0d 0a 45 43 38 30 30  |..{Quecte l}..EC800
4d 0d 0a {52 65 76 69 73  69 6f 6e 3a 20 45 43 38   |M..{Revis ion: EC8
30 30 4d 43 4e 47 42 52  30 36 41 30 34 4d 30 38}   |00MCNGBR 06A04M08}
0d 0a 0d 0a {4f 4b} 0d 0a                           |....{OK}..  

Clearly the bytes: 45 43 38 30 30 4d (correspoding to EC800M) are being ignored.

Am I doing something wrong? The state machine is clearly not capturing everything but I designed it based on the manual which says:

The AT or at prefix must be added at the beginning of each command line. Entering <CR> will terminate a command line. Commands are usually followed by a response that includes
<CR><LF><response><CR><LF>. Throughout this document, only the response will be presented, <CR><LF> are omitted intentionally.

Any help is highly appreciated! Thank you.

First, all the AT command will return “OK”.
Second, We should take the Quectel EC800M Revision: EC800MCNGBR06A04M08 as the response.

so basically I should wait until an “OK” is received to stop the state machine?

edit: will this be true for URCs as well?

Most AT commands will have a prefix such as +CREG: followed by the response we need. Some commands do not have a prefix, such as querying the version.

image

1 Like