|
|
View previous topic :: View next topic |
Author |
Message |
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
Force a 16 pointer to struct |
Posted: Fri Oct 27, 2006 12:10 pm |
|
|
When the *=16 is commented out this works. but with the 16bit pointers
I thought the compiler would take care of the char* using 16bit.
The base pointer in init is only 8bit not the required 16bit.
Can I make this work? ((Force/typecast it))
I am using 3.249
Code: | #include <16F877A.h>
#device *=16
#fuses hs,nowdt,noprotect,nolvp,put
#use delay(clock=11059200)
#use rs232(baud=19200,xmit=PIN_E2,invert,stream=debug,disable_ints)
#case
#zero_ram
struct buf {
char *bas;
char *in;
char *out;
int8 len;
char ctl;
};
struct buf tbctl;
#define TBLEN 32
char txbuf[TBLEN];
void init_buf();
void init_buf_ctl(struct buf *ctl, char *base, int length);
signed int8 cbw(char data, struct buf *ctl);
signed int8 cbr(struct buf *ctl);
//=== MAIN ===//
void main(void)
{
fprintf(DEBUG,"Start\n\r");
txbuf[0]=0xAA;
fprintf(DEBUG,"set txbuf[0]=0x%X\n\r",txbuf[0]);
fprintf(DEBUG,"addr txbuf[0]=0x%lX\n\r",&txbuf[0]);
init_buf();
cbw(0xBB, &tbctl);
fprintf(DEBUG,"now txbuf[0]=0x%X\n\r",txbuf[0]);
while(1);
}
void init_buf()
{
init_buf_ctl(&tbctl, txbuf, sizeof(txbuf));
}
/* Initialize Buffer Control Block. */
void init_buf_ctl(struct buf *ctl, char *base, int length)
{
fprintf(DEBUG,"base here=0x%lX\n\r",base);
ctl->bas = base;
ctl->in = base;
ctl->out = base;
ctl->len = length;
ctl->ctl = 0;
}
/* Circular Buffer Write. */
signed int8 cbw(char data, struct buf *ctl)
{
*ctl->in++ = data;
return 1;
}
///* Circular Buffer Read. */
//signed int8 cbr(struct buf *ctl)
//{
// int data;
// data = *ctl->out++;
// return data;
//}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Oct 27, 2006 12:36 pm |
|
|
Can you post the results you expect to see, and post the results that
you're getting ? (The print out from the Debug stream). |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Fri Oct 27, 2006 12:59 pm |
|
|
First run is with the =*16 commented out
next is with it in. The base should be 0x2A29 in second run.
Quote: |
Start
set txbuf[0]=0xAA
addr txbuf[0]=0x26
base here=0x26
now txbuf[0]=0xBB
Start
set txbuf[0]=0xAA
addr txbuf[0]=0x2A29
base here=0x0029
now txbuf[0]=0xAA
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Oct 27, 2006 1:22 pm |
|
|
The highest available RAM address in a 16F877A is 0x1FF. That's at
the end of bank 3. Buts that's in the common ram area, which is not
normally used for user variables. The array is 32 bytes long, so the
highest base address the compiler would assign to it is 0x01D0.
It can't ever be 0x2A29. |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Fri Oct 27, 2006 1:33 pm |
|
|
Right, Right,Right,
So.... Is the printf STATEMENT wrong or the printf funtionality?
Printf functionality..
Code: | #include <16F877A.h>
#device *=16
#fuses hs,nowdt,noprotect,nolvp,put
#use delay(clock=11059200)
#use rs232(baud=19200,xmit=PIN_E2,invert,stream=debug,disable_ints)
#case
#zero_ram
#define TBLEN 90
char txbuf[TBLEN];
//=== MAIN ===//
void main(void)
{
int16 addr;
fprintf(DEBUG,"Start\n\r");
txbuf[0]=0xAA;
fprintf(DEBUG,"set txbuf[0]=0x%X\n\r",txbuf[0]);
fprintf(DEBUG,"addr txbuf[0]=0x%lX\n\r",&txbuf[0]);
addr=&txbuf[0];
fprintf(DEBUG,"addr =0x%lX\n\r",addr);
while(1);
}
|
Code: | Start
set txbuf[0]=0xAA
addr txbuf[0]=0x1110
addr =0x0110
|
|
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Fri Oct 27, 2006 1:44 pm |
|
|
So the fault in in the ++ increment and *=16
This works
Code: |
/* Circular Buffer Write. */
signed int8 cbw(char data, struct buf *ctl)
{
*ctl->in=data;
ctl->in++;
return 1;
}
|
This fails
Code: |
/* Circular Buffer Write. */
signed int8 cbw(char data, struct buf *ctl)
{
*ctl->in++=data;
return 1;
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Oct 27, 2006 1:49 pm |
|
|
It looks like a printf bug. It can't extract the address correctly.
Code: | printf("addr txbuf[0] = %lx \n\r", txbuf);
0072 3011 00438 MOVLW 11 // Bug -- MSB should be 01.
0073 00ED 00439 MOVWF 6D
0074 3057 00440 MOVLW 57
0075 00EE 00441 MOVWF 6E
0076 1303 00442 BCF 03.6
0077 201F 00443 CALL 01F
0078 3010 00444 MOVLW 10 // LSB is correct.
0079 1703 00445 BSF 03.6
007A 00ED 00446 MOVWF 6D
007B 3057 00447 MOVLW 57
007C 00EE 00448 MOVWF 6E
007D 1303 00449 BCF 03.6
007E 201F 00450 CALL 01F |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Oct 27, 2006 3:48 pm |
|
|
Quote: |
This fails:
/* Circular Buffer Write. */
signed int8 cbw(char data, struct buf *ctl)
{
*ctl->in++=data;
return 1;
}
|
I did some testing and it works in MSVC vs. 1.52, but it fails in CCS.
This was with PCM vs. 3.249.
I tried to come up with a fix by putting in parentheses, but
it didn't help. I think you have to split the code into two lines
as you have done, as a work-around. |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Mon Oct 30, 2006 9:52 am |
|
|
Cool
Thanks for your time. |
|
|
|
|
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
|