Error, handling, UART, QG8, Take actions on incoming string in assembly language

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Error, handling, UART, QG8, Take actions on incoming string in assembly language

3,051 Views
mnemonic
Contributor III
Hello Guys!
 
I wrote some code in assembly language to control a Siemens TC45 GSM Engine over AT commands. Thats working and I have no problems with it. Next what I want to do is take actions on the incoming OK and ERROR string for error handling. My thougt was to store all incoming digits to Ram and calculate these in a addition to get a specific value wich is allready stored in a predefined ram at the beginning of the processor init. If this value match to the calculated incoming then the programm goes further. I can do this if its only one digit. But I want to take action on these ERROR and OK string. In future I must to some actions on a specific word in a SMS.
 
How would do it for yours? Who has some experience in such a handling? How can I extract a special word from a complet string?
 
all inspiration is welcome,
 
nice evening from AUSTRIA
 
Ingo- Michael
Labels (1)
0 Kudos
9 Replies

789 Views
peg
Senior Contributor IV
Hello and welcome to the fora, mnemonic,

It is not clear to me where your actual problem is.
Presumably the communication with the GSM unit is over SCI?
Wouldn't you allocate a buffer in RAM then store the recieved string there (using indexed addressing).
Then when you know you have it all (?) you would start comparing the characters from the begining of the buffer to known possible responses and then act accordingly.

    lda BUF
    cmp #'O'
    bne NEXTTEST
    lda BUF+1
    cmp #'K'
    bne OTHERTEST
    lda BUF+2
    cmp #endofstring
    bne ERROR
    bset OKFLAG
    jmp AWAY

NEXTTEST:
    cmp #'E'
    etc

0 Kudos

789 Views
mnemonic
Contributor III
Hello Peg!
 
Thank you for your answer! Yes the communication is over SCI. I thought also a little like you. First I try to do this for a test:
 
mainLoop:    
           
            lda #$54                  ;calculated predefined value *=ascii 2A,   2A+2A=54
            sta RAM2                ;
            brclr 5,SCIS1,*        ;wait until rs232-receiver ful 
            lda SCID
            add #$2A               ;load akku with rs232-datareg.
            cmp RAM2
            beq next
            jmp mainLoop
next:           
            bclr 6,PTBD
            bclr 7,SCIC1
           
            bra mainLoop
This can be usefull to calculate a incoming string. I think it saves codespace and the incoming chars must not be on the same place. What do you think about it?
 
I also tryed to do
 
O:          DS.B   1
K:           DS.B   1
CR:        DS.B   1       ;Carriage return
LF:         DS.B   1        ;Linefeed
 
and compare the incoming string to my definitions. (like you do it.) But every action I take on the 2nd solution fails.
 
I am not sure that the GSM module sending ascii chars faster as I can ask the SCID. I think i should also implement the "receiver overrun flag" (or and) do Hardware handshake to be sure. Also a very fast subroutine would help in this case. Or trim Processor frequency to a higher value?
 
I would also know how you would extract a specific word from a string?
 
Thank you for your experience! Its a great input to me!
 
regards Ingo-Michael
0 Kudos

789 Views
alexod
Contributor I
Ah, the good old Hayes AT command set.

I've typically had the luxury of C, there are a couple of ways of doing this sort of thing, they are easier to read in C, but can be implemented in ASM.


RX ISR to FIFO
===========
First thing is get your receiver interrupt pushing the received data to a FIFO (circular software buffer), otherwise you may drop incoming bytes.  In the modem world you have plenty of time to respond to a string, but you have to catch every byte.  Have a look at your modems instruction book and see what the longest response string is, you will probably have started moving from your fifo to a buffer before you get to the end of the message, but what if you are busy elsewhere when the response comes in?

END OF STRING
=============
Now your main/match task will use your getbyte routine to poll the FIFO and build up a string for matching.  When you get to the <CR> or <CR><LF> pair you can then attempt to match.

For AT modems I usually treat CR and LF as the same character and throw away the spares, this comes from my earlier life when I was working between Apples, Acorns and PC's, they each had different usage of CR, CR/LF and LF.  Very painful.  Of course driving a VT100, CR and LF are significant.

MATCHING
========
When you have your received string you then try to match against every string, until you have a match, that is do a string comp  where you walk along the buffer and the string to match, aborting on first miss match.  Each match string has a function pointer associated with it, or an enuerated value to index into your jump table.

TABLE OF STRINGS
===============
Having the inline hard coded testing is a pain to add, if you can declare strings you will find life easier, especially adding strings or changing.


Another method is to have multiple match pointers, each points to the start of your target strings.  As you pop a byte from the buffer, if any of the strings match, you advance their pointer until you reach the end of the string.

e.g.

Target strings

OK
NO DIAL
NO SERVICE

t1ptr = (address of OK)
t2ptr = (address of NO DIAL)
t3ptr = (address of NO SERVICE)

when you get your first byte from the buffer, say an N you call a compare on each string, the OK fails to match, but the other two match first character, therefore advance t2ptr and t3ptr, you can probably see what's happening here... at the 4th character you can dismiss one of the two, but you must carry on to make sure the third string matches.  Here you have a match pointer per string, and don't need to buffer the incoming string.

TREES
======
Now you implied you may have even more messages to deal with than the AT responses, handling SMS message content too.  If you find you are having trouble managing a large number of strings you may want to build a tree structure for matching.  Also you may want to consider a state machine whereby only certain message responses are legal in each context.  I would not like to build a tree by hand.  We built a preprocessor for a project so we could define values, very much like a #define.  It built the tree for us.

TOKENS
=======
Your initial post implied you were going to sum your incoming bytes to make a token.  Is this right?

errVal = asc('E')+asc('R')+asc('R')+asc('O')+asc('R') etc?

This can be dangerous as ERROR and EQSOT will evaluate to the same value.  Even an XOR check sum would not help.  I hear CRC can do this sort of uniqueness but is not fast to perform either.  Sorry,  character by character matching is more reliable and less prone to programming error.

WORD EXTRACTION or PARSING
==========================
If you are trying to pull a word out of a message you need to know how words are delimeted, and make sure that your word is properly formed.  If I was looking for "BE" I would match it in "BETWEEN" and "AMBER" if I didn't look for space characters.  I won't go into parsing here and now (as it's lunch time and I've waffled too much) but Parsing is the keyword you're looking for.
0 Kudos

789 Views
mnemonic
Contributor III
Hello alexod!
 
Thank you very much for spending time on my questions. I will take some time to translate your answer to my language and do some tests with your input. Yesterday I was at a friend and start a discussion about the most basically question. How to do a secure transmission to get all chars without lost data from the GSM Cellular Engine? We worked out that Hardware handshake (RTS/CTS) could be the best solution. I will start to write first a sub wich secures that all digits are receipt. Then I will come back to here and post what I worked out.
 
merry chrismas to all here
 
all the best
 
Ingo-Michael
 
 
0 Kudos

789 Views
peg
Senior Contributor IV
Hello again Michael,

Even if you implement hardware handshaking I still would recommend, as alexod does, that you use interrupts for your SCI receive. Hardware handshaking won't fix all your problems on its own. This is a basic decision you want to make early (and correctly) before you start building on top of it. Other than that I agree with all of Alex's detailed information he provided.

Merry Christmas!

0 Kudos

789 Views
alexod
Contributor I
Hardware flow control is quite important.  There is one thing to remember, it's not an instant stop to transmission.  Things are a lot better than they were once, now, you can pretty much assume that the sending unit has one byte being shifted out, and another in the hardware buffer immediately before the shifter, you really need to assert the flow control ( Set CTS to not clear state) before you get to the end of your software FIFO.  I've worked on older systems where four or five bytes escaped the transmit end.

For this purpose you want a "HIGH WATER MARK" and and "LOW WATER MARK" for you receiving FIFO.  The HWM is the point at which you stop the far end sending, it will be 3-10 bytes short of the full FIFO depth.  The LWM is the point where you enable the far end sending again, this is 8-16 bytes less than the full FIFO depth.

It's been so long since I handled serial comms directly I almost forgot that.

Anyway, hope this has been of help again.

Happy Chirstmas

Alex

0 Kudos

789 Views
mnemonic
Contributor III
Hello Alexod!
 
Thank you once more for your input to me last year! I was searching for some Informations about software buffers. I bought the HCS08 Unleashed book from Fábio Pereira and found a application note AN1752. Can this Application note be a good base to me for start writing a software buffer?
 
best regards,
 
Ingo-Michael
 
 
0 Kudos

789 Views
alexod
Contributor I
Ingo-Michael,

looking at the apnote I see that they have a reasonable Queue algorithm.

I have one slight reservation about it.  In a system where you can consume from the queue faster than the serial port can provide the data, then this will work fine. 

In a lot of cases I've dealt with you cannot consume the data as it comes, that's why you buffer it.  If you have hardware flow control you need to send the "STOP" to the transmitter before your buffer is full.  I typically go for a worst case scenario assuming that the hardware on both sides is limited to a TX Buffer, Shifter and RX buffer.

In this situation when you get a data ready interrupt, there is already data in your RX Buffer, and you can bet the next byte is moving between the shift registers, and there is a third byte in the far end TX Buf.  If you are only using buffer full for your flow control, then you will drop a couple of bytes here.

My general policy is to have a High water mark QHW which is equivalent of QMAX-4.  When Qcount >=QHW then it is time to shut off the data but making clear to send false.  I never use XON/XOFF, this may need a lower HWM.

Now, QHW is not the only level, you will want to clear some space before you let the far end start sending again.  The low water mark is several bytes below QHW.  You modify the DeQ to assert Clear to Send when Qcount <= QLW.

Of course, if you have no flow control, then the example is fine.  Scale the buffer so it can hold sufficient that you never get over-run.

=====================

As for book resources.  There are two very powerful books out there, both by Jean Labrosse.  One is uC/OS, the old version was a full OS whose license cost was covered by purchase of the book.  The newer version has a different license agreement, but the concepts are very good, and you can learn a lot.

A companion volume is "Embedded Building Blocks".  These are driver functions, and they cover all the basics, LCD, Keypad, etc and provide good hardware abstraction layer concepts.

Both books are in C, but if you take C as a psuedo code, you will see how to start moving it to assembly lang.

Another excellent resource for introducing concepts is Embedded magazine.  They have their last 12 years online at http://www.embedded.com/archive/index.html.

Their site changed in the last 10 months, but their search engine should bring up their "beginner corner" articles, they deal with the basics.  Other articles deal with emerging ideas.

Hope this all gets you going in the right direction.

Alex
0 Kudos

789 Views
peg
Senior Contributor IV
Hello,

It seems you are trying to interpret the string as you read it in by polling. I would suggest against this method.
I would suggest instead that you use interrupts on the receive side and write the string to a buffer.
When you know that you have all the string (a CR or something, you would check for this in the ISR) you would then do the code I showed before (interpret the buffer contents, note the live data). This avoids most speed issues while recieving the data. You only need to interpret the data before the next string arrives, not in between characters.

Also I am still unclear what you are trying to do by adding to $2A etc

Good evening from AUSTR(al)IA!



Message Edited by peg on 2008-12-23 10:56 PM
0 Kudos