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 support@ccsinfo.com

RS232 Stream with data of 0x00 - this ones for Ttelmah
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
MikeW



Joined: 15 Sep 2003
Posts: 184
Location: Warrington UK

View user's profile Send private message

RS232 Stream with data of 0x00 - this ones for Ttelmah
PostPosted: Sun Aug 20, 2006 6:34 am     Reply with quote

I little while ago, you were very helpul on answering questions on streams. - see "help on custom Send_string_RS232 function" below

http://www.ccsinfo.com/forum/viewtopic.php?t=27883

you pointed out having a define to send out strings.

I implemented your thoughts, but am still having problems.

I think its because any putc or fputc sees a 0x00 as the end of string terminator.

here is what I constructed, but it quits early when the data is 0x00.

any ideas to overcome this.

char const command_Cam_OFF[] = {0x81,0x01,0x04,0x00,0x03,0xFF};



#define Send_command(String) putcint(String);

void putcint( int c)

{
fputc (c,Streamname);// WHERE STREAMNAME IS DEFINED IN THE USE RS232 ETC
}

void main()
{

Send_Command(command_Cam_OFF);
etc
etc
}


i know i can probably use

fputc (Streamname,%c%c%c%c%c,0x81,0x01,0x04,0x00,0x03,0xFF);

but it is nowhere near as elegant as having the command defined as a string constant


any help will result in beer tokens of your choice :-)
Mike
Sherpa Doug
Guest







PostPosted: Sun Aug 20, 2006 6:58 am     Reply with quote

Putc() deals in bytes. It doesn't know stings or care about string terminataors. 0x00 is just another byte.
Is it possible that you are sending this stream to a PC and the PC is throwing out nulls? Some PC comm software does that by default. I think Hyperterminal does that which is another reason it should be vigorously expunged from every Windows PC on the planet. (Oddly Hyperterminal for OS/2 was a fine program, a completely different animal)

SherpaDoug
Ttelmah
Guest







PostPosted: Sun Aug 20, 2006 7:14 am     Reply with quote

The problem is nothing to do with putc, but that C, sees an ascii '0' as an end of string, so never calls putc with this value.
There are a number of possible routes. The normal 'workround', is to use another character as an escape. So in C itself, the '\' is used this way.
So, for this one value:
Code:

char const command_Cam_OFF[] = {0x81,0x01,0x04,0x5C0x30,0x03,0xFF};

#define Send_command(String) putcint(String);

void putcint( int c) {
   static int1 esc_flag=false;
   if (c=='\') {
     esc_flag=true;
     return;
   }
   if (esc_flag) {
     if (c=='0') c=0;
     esc_flag=false;
   }
   fputc (c,Streamname);
   // WHERE STREAMNAME IS DEFINED IN THE USE RS232 ETC
}

void main() {
   Send_Command(command_Cam_OFF);
   etc
   etc
}

Then the '\' character, if required, has to be sent as '\\', and the ascii '0', is sent as '\0'.

Best Wishes
MikeW



Joined: 15 Sep 2003
Posts: 184
Location: Warrington UK

View user's profile Send private message

PostPosted: Sun Aug 20, 2006 7:18 am     Reply with quote

Sherpa,

i am single stepping through the code using ICDU-40

the listing shows


................ fputc (c,streamname);
*
007D: MOVF 22,W
007E: BTFSS 0C.4
007F: GOTO 07E
0080: MOVWF 19 // mike - this is putting the byte in TxD register
....................
.................... } // end of function
0081: RETLW 00
....................

so that part seems sound


i think the problem is here :-


.................... Send_Command(command_Cam_IF_Clear);
00BD: CLRF 21
00BE: MOVF 21,W
00BF: CALL 00D
00C0: IORLW 00 // mike- i think it got the byte, INCOR it with zero
00C1: BTFSC 03.2 // mike - the data byte was zero, so exit
00C2: GOTO 0C7 // mike - exit the routine
00C3: INCF 21,F
00C4: MOVWF 22
00C5: CALL 07D
00C6: GOTO 0BE


00C7 is the next part of main code

so the #define has inserted the code above as putcint(string)
MikeW



Joined: 15 Sep 2003
Posts: 184
Location: Warrington UK

View user's profile Send private message

PostPosted: Sun Aug 20, 2006 8:03 am     Reply with quote

Ttelmah

I dont like using the "\" as a flag to signify an escape sequence.

I really want to leave the char const string as its raw data, otherwise supportability and readabilty in the future is compromised.



Mike
Ttelmah
Guest







PostPosted: Sun Aug 20, 2006 10:15 am     Reply with quote

Unless you use some form of indicator, I'm afraid you cannot use the 'shortcut'. The shortcut is designed to deal with strings, and in C, '0' is the string terminator character. You can use any character you want as an indicator. If (for instance), you never use the backspace character, or a 'high' character like 0xff, then you can simply use these, and output a zero when these are encountered.

Best Wishes
Sherpa Doug
Guest







PostPosted: Sun Aug 20, 2006 11:05 am     Reply with quote

On closer inspection Ttelmah is right. You are using an odd extension of CCS C that allows passing strings to putc(). In K&R C this would be forbidden so the whole point would be moot.
To solve your problem you need some way to tell the printing function how long the string is. Escape sequences work and are commonly used but I don't like the asthetics any more than you. Another less common option is to use the first byte to hold the string length in binary. Or if all your strings can be padded to the same length, then make a printing function that just prints that length.

SherpaDoug
MikeW



Joined: 15 Sep 2003
Posts: 184
Location: Warrington UK

View user's profile Send private message

PostPosted: Sun Aug 20, 2006 11:41 am     Reply with quote

I am coming to the conclusion ( after several beers) , that the solution is to directly manipulate the bytes, stuffing them into a buffer, which the serial isr just pumps out.

Mike
newguy



Joined: 24 Jun 2004
Posts: 1903

View user's profile Send private message

PostPosted: Sun Aug 20, 2006 12:05 pm     Reply with quote

MikeW wrote:
I am coming to the conclusion ( after several beers) , that the solution is to directly manipulate the bytes, stuffing them into a buffer, which the serial isr just pumps out.

Mike


Mike,

Look at the CCS example EX_STISR.C in the \examples folder. It's an example of an interrupt driven transmit routine. I use this routine (slightly modified) all the time. And I send 0x00 all the time - no issues.

Have a look at it - I hope it helps.
sjbaxter



Joined: 26 Jan 2006
Posts: 141
Location: Cheshire, UK

View user's profile Send private message Visit poster's website

PostPosted: Sun Aug 20, 2006 12:34 pm     Reply with quote

How about this method....

I think the term 'string' should be avoided for this problem. This is a stream of bytes, NOT characters, and as such should be treated as a byte stream.

You can use fputc to send an individual byte (or char 0 to 255). It's the string parser that calls this that, as has been mentioned, will cause the headache. So replace this with a helper function/macro that sends a number os bytes instead. i.e

Code:
char const command_Cam_OFF[] = { 0x81, 0x01, 0x04, 0x00, 0x03, 0xFF };   

#define SendCommand(x) {int8 i; for(i=0; i<sizeof((x));i++) { fputc((x)[i], PC_STREAM); }}

void main()
{
    SendCommand(command_Cam_OFF);
    ...
}


Only drawback is that it gets inlined, but it does look more elegent (if you have the FLASH space !!)
_________________
Regards,
Simon.
Ttelmah
Guest







PostPosted: Sun Aug 20, 2006 2:20 pm     Reply with quote

The term 'string', does apply, but is also the cause of the problem....
A 'string' in C, is a linear array of characters, terminated by a 0. The 'const' shortcut, handles strings _only_. For anything else (which if you want to have a '0' in the definition, you are dealing with), then you need to go DIY.
Not exactly a major problem.

Best Wishes
MikeW



Joined: 15 Sep 2003
Posts: 184
Location: Warrington UK

View user's profile Send private message

PostPosted: Mon Aug 21, 2006 2:39 am     Reply with quote

Telmah,

yes, I know its not exactly a major problem, but pointers and strings and char consts are not my strengths.

I tried mr Baxters solution, and it doesnt work. it doesnt get to the strings at all.

sorry to be a pain, but i was hoping for a quick solution that i could just pop in, and get on with hte rest of the project


below is what is compiled from me Baxters suggestion

char const command_Cam_OFF[] = {0x81,0x01,0x04,0x00,0x03,0xFF};


.................... Send_Command(command_Cam_OFF);
0079: CLRF 22
007A: MOVF 22,W
007B: SUBLW 03
007C: BTFSS 03.0
007D: GOTO 088
007E: ADDWF 22,W
007F: MOVWF 04
0080: MOVF 00,W
0081: MOVWF 27
0082: MOVF 27,W
0083: BTFSS 0C.4
0084: GOTO 083
0085: MOVWF 19 // mike - this is loading the TxD reg with totally wrong values
0086: INCF 22,F
0087: GOTO 07A
sjbaxter



Joined: 26 Jan 2006
Posts: 141
Location: Cheshire, UK

View user's profile Send private message Visit poster's website

PostPosted: Mon Aug 21, 2006 4:09 am     Reply with quote

Mike,

It was a typo in my code !! if you remove the brackets around the x in the body of the macro definition then the macro is correctly expanded by the compiler and it does the right thing. i.e.

Code:
char const command_Cam_OFF[] = { 0x81, 0x01, 0x04, 0x00, 0x03, 0xFF };   

#define SendCommand(x) {int8 i; for(i=0; i<sizeof(x);i++) { fputc(x[i], PC_STREAM); }}

void main()
{
    SendCommand(command_Cam_OFF);
    ...
}


you also may want to put

Code:
int8 i;


as a global as the compiler may get a bit upset with that if the macro isn't the first call in a function or main.
_________________
Regards,
Simon.
Ttelmah
Guest







PostPosted: Mon Aug 21, 2006 4:22 am     Reply with quote

What is proposed by Mr Baxter, will work, but just needs a little 'tweak' or two to make it work. There are a couple of 'potential' problems (which may cause problems).
The first 'potential' problem, is with the use of the local counter 'i'. Normally in C, this would be fine, but CCS, distinguishes 'local' variables, by adding the name of the subroutine to the declaration. I have seen too many problems appear in CCS C, when variables are declared inside an unnamed function, to 'trust' this. Hence I'd use a single global variable for the counter. Then the use of brackets round 'x' in the fputc, will cause problems with the expansion. This should work:
Code:

int8 send_ctr;
#define SendCommand(x) {for(send_ctr=0;\
send_ctr<sizeof(x);send_ctr++)\
{fputc(x[send_ctr],PC_STREAM);}}

const int command_Cam_OFF[] = {0x81, 0x01, 0x04, 0x00, 0x03, 0xFF};

With this 'SendCommand(command_Cam_OFF);', does generate the required sequence.

Best Wishes
sjbaxter



Joined: 26 Jan 2006
Posts: 141
Location: Cheshire, UK

View user's profile Send private message Visit poster's website

PostPosted: Mon Aug 21, 2006 4:26 am     Reply with quote

Ttelmah,

Just what I said in my previous post !!!

BTW : You can call me Simon. No need to be so formal Smile
_________________
Regards,
Simon.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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