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

16F1508 returns great address

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



Joined: 10 Dec 2011
Posts: 376
Location: Sofiq,Bulgariq

View user's profile Send private message

16F1508 returns great address
PostPosted: Sat Apr 05, 2014 2:19 pm     Reply with quote

Hello
I am just verifying the address of variable location.
Code:

void main()
{
int r;

while(1)
{
delay_ms(300);
printf("\r%lxh  %lud",&r,&r);
}
}


This is printed:
Quote:
2001h 8193d


Since I established that the last user RAM location is 16F I am confused.
How come I get such a great address?
_________________
A person who never made a mistake never tried anything new.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Sun Apr 06, 2014 12:17 am     Reply with quote

Are you using #device *=16?.

If not, then the maximum address is only an 8bit value, so when you treat the address as a 16bit value (with 'l'), the top byte means nothing.

Separately though CCS uses high address values for the ROM space now.

If you have:
Code:

#device *=16 //immediately after your processor definition

void main()
{
   int r;
   rom int p=16; //declare an addressable variable in rom
   int16 address;

   while(TRUE)
   {
      delay_ms(300);
      address=&r;
      //print this address how you want here
      address=&p;
      //then this one
   }
}   

You will see how CCS is using high addresses for the rom space.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Apr 06, 2014 12:29 am     Reply with quote

But in his code, 'r' is in ram and the .SYM shows that it's at address 0021.
If his program is compiled for a 16F886, it displays 0x21 correctly.
But for the 16F1508 or 16F1847, etc., it doesn't display 0x21 as it should.

If you modify the test program so that &r is loaded into a 16-bit variable,
and then you look at the .LST file, you see the compiler breaking up the
0021 address into two components of 01 and 20. Why does it do this
for 16F1508 etc. ? (Tested with vs. 5.023).
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Sun Apr 06, 2014 1:04 am     Reply with quote

Yes.
Adding the SYM data is of course vital.

Gets more interesting. This is wrong right back to 4.141. It is mishandling the split point for what is the 'bank' and what is the address in the bank. Addresses are allowed to be a 7bit value in each bank, instead it is behaving as if it is a 5bit value, so moves bit 5 up into the bank select area....
It's getting it wrong when used as well (doesn't sort it out at this point).

You can see it really clearly, if you move a variable up above address 0x30. In this case 'fred' at 0x39:
Code:

.................... address=&fred;
0032:  MOVLW  20
0033:  MOVWF  37
0034:  MOVLW  19
0035:  MOVWF  36

So 5 bits of the address are being retained (0x19), but the higher bits are being treated as the bank address.....
Ouch.

Worse it is not even putting the bank addresses in the right place (high nibble instead of low).
Double ouch.

Even more annoyingly, the ram page size doesn't seem to have a setting in the device editor, so it can't even be fixed that way.

Needs rapid reporting.

I must admit, on a couple of PIC16 chips, when I do use 'rom', I've seen extra bits appear at the top of the address (presumably the compiler is using these as flags), and assumed this was what was being seen.....
rikotech8



Joined: 10 Dec 2011
Posts: 376
Location: Sofiq,Bulgariq

View user's profile Send private message

PostPosted: Sun Apr 06, 2014 3:07 am     Reply with quote

Quote:

Are you using #device *=16?.
If not, then the maximum address is only an 8bit value


I am not using #device *=16.

Moreover, when I try to print the address as 8bit int (" %u",&r);, I get this error: Print format type is invalid.
of course I can assign the addres to an 8bit int, but then I lose some data for sure.
in this case:
Code:
void main()
{
int r;
unsigned int8 add;

add = &r;
printf(" %u",add);
}


Printed:
Quote:
1
Which is also not inside GPR boundaries.

Second thought, Why do I need BANK number (attached to the address), if the address of each variable stored in GPR or SFR is unique?

Thank you for replies!
_________________
A person who never made a mistake never tried anything new.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Sun Apr 06, 2014 4:28 am     Reply with quote

The point about *=16, is you need this to actually 'use' more than an 8bit address. The actual address 'type' remains as a 16bit value when printed/used though. So you need this to access the '0x16F' of RAM memory.

The key point is that the compiler (in all versions I've tried), is making a right (rude word at this point!), of the address, and as explained, is treating the memory pages as being only 32bytes in length (they are actually 128 bytes). So the address being used at 33, gets cut up into '1', and a bank address. It then gets this wrong as well....

Report it to CCS. It is surprising no-one had spotted it before....
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Apr 06, 2014 11:23 am     Reply with quote

I wrote up the bug in detail and emailed it to CCS support just now.
I would guess they'll fix it in the next release. I pointed them to
this thread and your comments, for more explanation of the exact
mechanism involved in the bug. I told them it apparently affects
all 16F-series "enhanced" PICs. (Based on my testing).
rikotech8



Joined: 10 Dec 2011
Posts: 376
Location: Sofiq,Bulgariq

View user's profile Send private message

PostPosted: Sun Apr 06, 2014 12:39 pm     Reply with quote

Quote:
So you need this to access the '0x16F' of RAM memory.


I see clealy, not using *=16 is all my bad. Thank you about that!

What still not clear to me is: Do I need the bank address in case it is right placed (high nibble). I mean, using pointers, the bank address is not relevant, isn't it?
Maybe this is a bit beyond the topic, but if each address in the RAM has its own unique address, why do I need information about the bank at all? Is it useful for me as a "programmer" to know in which bank is stored a certain register?

I repeat myself because I am not sure if you understand my issue?
Its my English teacher's fault! Mad Very Happy
_________________
A person who never made a mistake never tried anything new.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Sun Apr 06, 2014 12:47 pm     Reply with quote

That is how PIC16 memory is addressed.
The bank address is like the page number, and the rest is the word count in the page.
Every memory address has both a low part and a bank address (even if this is zero), and both parts are needed to actually address the byte.
What is going wrong is because the compiler is treating the 'bank' as if it is only 32 bytes long, it is getting a non zero bank address, for every usable address in memory. So 0x21 (which should have '21' in the count, and '0' in the bank address), ends up with '1' in the count, and an incorrect value in the bank address. Result it accesses the wrong byte, and the value returned as the address is 'insane'....
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 07, 2014 11:54 am     Reply with quote

Here is the response from CCS tech support:
Quote:

The Enhanced 16 parts have two addressing modes. The SYM file shows
the physical address but anytime we use the FSR the logical address is
used. The & operator returns the logical address because the result will
eventually end up in the FSR.

Physical 0x0021 is the same location as logical 0x2001.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Mon Apr 07, 2014 12:00 pm     Reply with quote

Interesting....

Doesn't appear to agree with the values the data sheet shows to write to the FSR registers, to access the location. Question is does it work?.
Somebody needs to try on a real chip, and 'walk through' an area of memory with the pointers and see what is returned.

Ah. Their 'terminology' disagrees with Microchips....

They are accessing it through the 'linear data memory' area. Starts at address 0x2000, and gives direct access to the RAM starting at address 0x20, _and omitting the shared areas_, so gives a single linear area of RAM starting at this point.
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