CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Serial Strategies.....

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
John Morley



Joined: 09 Aug 2004
Posts: 97

View user's profile Send private message

Serial Strategies.....
PostPosted: Fri Sep 01, 2006 9:33 pm     Reply with quote

Hi All,

I'm writing some code for the 16F628A to communicate with an Aerocomm AC4490 wireless module. Most of the time I will be receiving data from another AC4490 that is programmed to send data using predefined 'Start' (#) and 'End' (CR) characters. In this situation, the code for the ISR is no problem. The problem is that sometimes I will be also be receiving configuration messages from the AC4490 itself, and these messages will be variable length and not terminated with a consistent character. How should I handle this situation? I always know which serial 'mode' I'm in, so I could set a flag and then switch receive methods inside the ISR, but this method seems clumsy?

Any suggestions on how to code a more universal serial ISR?

Thanks!
_________________
John Morley
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 01, 2006 11:31 pm     Reply with quote

Quote:

Most of the time I will be receiving data from another AC4490 that is
programmed to send data using predefined 'Start' (#) and 'End' (CR)
characters.
The problem is that sometimes I will be also be receiving configuration
messages from the AC4490 itself, and these messages will be variable
length and not terminated with a consistent character. How should I
handle this situation ?

Are the config messages given in response to commands that you send ?

Can you give two examples of each message type, as described
in the manual below ?
http://www.aerocomm.com/docs/User_Manual_AC4490.pdf
John Morley



Joined: 09 Aug 2004
Posts: 97

View user's profile Send private message

PostPosted: Tue Sep 05, 2006 7:23 pm     Reply with quote

Hi PCM,

Maybe I wasn't quite clear. The AC4490 has one serial port that is used to send and receive wireless data, as well as to configure the module. The serial data format for each is quite different, so I'm wondering how best to design my serial interrupt routine.

For example, the "wireless data" I am receiving always looks like this:

#N01:01:0<CR>

This data always begins with a '#' and ends with a 'CR', so it's very easy to detect both the 1st and last characters and know when the transmission has ended. I have examples of that working just fine.

The challenge is that the "config data" is totally different. It doesn't always start with the same character each time, it doesn't have a termination character, and the number of bytes returned can be different.

For example, the "config data" I am receiving might be the following:

Enter AT Mode Repsonse: 0xCC, 0x43, 0x4F, 0x4D
Enter Config Mode Response: 0x65

I have a routine working now that receives the config. data by using getc() until a preset # of bytes has been received, and that works just fine. What I need to do now is combine the two serial reception modes into one routine.

Maybe the solution is to have separate programs for configuring the AC4490 module, and communicating through it? Another possibility is to have separate routines for the two "modes". For example, enable Int_RDA when receiving wireless data, and disable it when receiving config data, and call a separate routine to receive the proper number of characters. A third method would be to have some sort of a "Mode" flag and a "Receive Characters" flag, and switch between the two reception modes inside the ISR.

I'm just wondering how this is normally handled?

Thanks,

John
_________________
John Morley
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Sep 05, 2006 10:50 pm     Reply with quote

I would always use #int_rda. I would use an interrupt driven receive
fifo, similar to the one shown CCS example file, EX_SISR.C, with
a suitably large buffer.

You know when you're going to be in Configuration mode.
At the start of your program, you would call a configure_modem()
function. In that function, you enter config mode, by the method(s)
given in the manual. Then let's say you send a command that
that is supposed to return 3 bytes. You could modify the EX_SISR
code to add a global variable that holds the number of bytes that are
in the receive buffer. You could then poll that 'byte_count' value and
wait until it's equal to 3 or more. You would also want to have a
timeout feature, so you don't sit in the polling loop forever. This
could be done with a hardware timer. You also want to make sure
that no previous command was in progress and that the receive
buffer is empty, before you send the command.

Once you're done with configuration, you would exit from the
configure_modem() function and return to main(). In main(), you
would presumably have a while() loop, in which you handle your
normal communications. Again, you call the bkbhit() function or
look at the global 'count' variable to find out if you have any bytes
available in the receive buffer.

This is just a general explanation of how I believe I would do it.
If you want specific code from someone who has already used a
modem like this, then someone else will have to answer.
Ken Johnson



Joined: 23 Mar 2006
Posts: 197
Location: Lewisburg, WV

View user's profile Send private message

PostPosted: Wed Sep 06, 2006 11:11 am     Reply with quote

What you've described is a fairly common problem: how does a serial-recieve ISR know when to notify the main program to "process this stuff"?

Having a known end-of-message character is a good way, as you've already mentioned (Unless something goes wrong and the end-of-message never arrives). Motorola's 68HC11 family had a very nice "Idle Line" interrupt which occurred when a reception-in-progress ceased. I usually implement something like this with a timer: With each byte received, I reset the timer to timeout after 2 more byte-times. Then when the timer interrupts, I notify the main program to process the message(s) in the buffer. There is of course a slight delay between end-of-message and notification, but that's usually ok if considered in your design (You may also want to insist on 2-3 byte times between messages)

Hope this is helpful.
Ken
kd5uzz



Joined: 28 May 2006
Posts: 56

View user's profile Send private message

PostPosted: Sun Sep 10, 2006 11:52 pm     Reply with quote

How about a received message buffer? I did this:
Code:

   void SerIn() {
      char Inp;
      int i;

      Inp = getc();

      // we've got new char, now lets shift the buffer
      for (i=0;i<=5;++i) { // once for each byte
         Buffer[i] = Buffer[i+1];
      }

      Buffer[6] = Inp;  //stuff the last byte into the buffer

      // shifted, now lets see if its a packet:
      if ((Buffer[0] == 0x08) && (Buffer[6] == 0x0D)) {
         //its a packet! lets do something with it...
         DoParsePacket = TRUE;
      }
   }


With something like this you'll never get stuck inside a loop waiting for a packet, and if a packet gets mangled it will fail gracefully.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group