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

Using rom as constant
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
freeman3020



Joined: 23 Oct 2015
Posts: 7

View user's profile Send private message

Using rom as constant
PostPosted: Tue Nov 03, 2015 7:56 am     Reply with quote

Hi again,

I have test this code

Code:
#include <16F628.h>


#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOPUT                    //No Power Up Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES PROTECT                  //Code protected from reads


#define use_portb_lcd TRUE

#use delay(clock=20000000,RESTART_WDT)
#use rs232(baud=115200,parity=N,bits=8,UART1,errors, stream = sms)


char rom version[] = "PRODUCT ID V1.01";
 char rom *ptr;

 void display_string(rom *str)
 {
 printf("%s \r", str);
 }

 //=====================
 void main()
 {
 ptr = version;

 printf("ptr = %lx \r", ptr);

 display_string(version);
 display_string(ptr);
     
 while(1);
 }


I got reference from here :
https://www.ccsinfo.com/forum/viewtopic.php?p=146223&sid=04f081ae04230eea19c3fa20dd731174#146223


but I got error on proteus : Program or eprom data has invalid address

??
temtronic



Joined: 01 Jul 2010
Posts: 9096
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Nov 03, 2015 9:01 am     Reply with quote

"but I got error on proteus "


well what makes you think proteus is 100% perfect program ???

Please see PIC101 sticky...

Jay
freeman3020



Joined: 23 Oct 2015
Posts: 7

View user's profile Send private message

PostPosted: Tue Nov 03, 2015 9:29 am     Reply with quote

temtronic wrote:
"but I got error on proteus "


well what makes you think proteus is 100% perfect program ???

Please see PIC101 sticky...

Jay



sorry , but I test also in real hardware , no output?
it's not proteus problem
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Tue Nov 03, 2015 12:22 pm     Reply with quote

If you just want to use pointers to ROM based strings, then don't use rom. Just declare them as 'const', and add the header line near the fuses "#DEVICE PASS_STRINGS=IN_RAM". This tells the compiler to automatically 'virtualise' strings stored in ROM, and pass them as if they were in RAM. Easier and more reliable in general. The use of rom pointers requires _functions_ declared to use rom pointers. You can't use them 'interchangeably' with RAM pointers.

Critical question also is 'what compiler version'. This ability works to different amounts in different compilers.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Nov 03, 2015 2:40 pm     Reply with quote

The example in his link uses the 16F1824, but he has changed it to a 16F628.

Looking at the .LST file, I can see that for the 16F1824, CCS sets the
EEPGD bit, to read from program memory.

When the program is compiled for the 16F628, CCS attempts to do this
but there is no EEPGD bit in the 16F628, so it just puts a '-' in the .LST file.
The 16F628 has no ability to read its own program memory.
Quote:

0048: MOVF @READ_PROGRAM_MEMORY8.P2,W
0049: MOVWF @77
004A: BCF STATUS.C
004B: BSF STATUS.RP0
004C: BSF EECON1.-
004D: BSF EECON1.RD
004E: NOP
004F: NOP
0050: MOVF EEDATA,W
0051: MOVWF INDF
0052: INCF FSR,F
0053: INCF EEADR,F
0054: BTFSC STATUS.Z
0055: INCF TXSTA,F
0056: DECFSZ @77,F
0057: GOTO 04D

This test was done with CCS compiler vs. 5.051.
freeman3020



Joined: 23 Oct 2015
Posts: 7

View user's profile Send private message

PostPosted: Tue Nov 03, 2015 2:59 pm     Reply with quote

Ttelmah wrote:
If you just want to use pointers to ROM based strings, then don't use rom. Just declare them as 'const', and add the header line near the fuses "#DEVICE PASS_STRINGS=IN_RAM". This tells the compiler to automatically 'virtualise' strings stored in ROM, and pass them as if they were in RAM. Easier and more reliable in general. The use of rom pointers requires _functions_ declared to use rom pointers. You can't use them 'interchangeably' with RAM pointers.

Critical question also is 'what compiler version'. This ability works to different amounts in different compilers.


I tried as you said, I got strange string ..
Is this mean rom and pass in ram require special chip? regarding PCM programmer post
freeman3020



Joined: 23 Oct 2015
Posts: 7

View user's profile Send private message

PostPosted: Tue Nov 03, 2015 3:06 pm     Reply with quote

PCM programmer wrote:
The example in his link uses the 16F1824, but he has changed it to a 16F628.

Looking at the .LST file, I can see that for the 16F1824, CCS sets the
EEPGD bit, to read from program memory.

When the program is compiled for the 16F628, CCS attempts to do this
but there is no EEPGD bit in the 16F628, so it just puts a '-' in the .LST file.
The 16F628 has no ability to read its own program memory.
Quote:

0048: MOVF @READ_PROGRAM_MEMORY8.P2,W
0049: MOVWF @77
004A: BCF STATUS.C
004B: BSF STATUS.RP0
004C: BSF EECON1.-
004D: BSF EECON1.RD
004E: NOP
004F: NOP
0050: MOVF EEDATA,W
0051: MOVWF INDF
0052: INCF FSR,F
0053: INCF EEADR,F
0054: BTFSC STATUS.Z
0055: INCF TXSTA,F
0056: DECFSZ @77,F
0057: GOTO 04D

This test was done with CCS compiler vs. 5.051.


if 16f628 can't read from program memory , how compiler copy from rom to ram using

memcpy(tmpMsg,msg5,sizeof(msg5));

where msg5 is char const array?
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Tue Nov 03, 2015 3:19 pm     Reply with quote

This gets a little complex.

The older PIC's can't read their own program memory.
On these CCS generates a const array, by generating a _program_ that stores the values as RETLW instructions, and then if you want (say) the 30th byte, the program is called with '29', and does a indexed jump forward by 29 to the 30th RETLW instruction, and returns the required byte (phew).
The strcpy/memcpy functions, are _overloaded_ (have two different versions), and if asked to copy a value from the ROM to RAM, instead of doing a direct copy, do the required repeated calls to the function, and write the resulting bytes back to RAM. Effectively hiding this extra complexity from you.
CCS are trying to give you the 'important parts' of the ability to store things in ROM, on chips that can't actually read such data.
In the manual for strcpy:
"src may be either a pointer to a RAM array of characters or it may be a constant string".

Use of pointers to ROM, requires a chip that can directly read it's own ROM. Problem is that the program approach only works if you call the program at the start!...

I must admit so few chips now don't allow this, that I failed to spot he was using one of the old ones that didn't.
tinley



Joined: 09 May 2006
Posts: 66

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

PostPosted: Thu Nov 19, 2015 5:07 am     Reply with quote

Ttelmah wrote:
If you just want to use pointers to ROM based strings, then don't use rom. Just declare them as 'const', and add the header line near the fuses "#DEVICE PASS_STRINGS=IN_RAM". This tells the compiler to automatically 'virtualise' strings stored in ROM, and pass them as if they were in RAM. Easier and more reliable in general. The use of rom pointers requires _functions_ declared to use rom pointers. You can't use them 'interchangeably' with RAM pointers.

Critical question also is 'what compiler version'. This ability works to different amounts in different compilers.


I am trying to copy constant tables in ROM into ram using pointers.
PCD V5.051 PIC24FJ256DA206

This works:

const char arial_8pt[1111]={0,1,2,3,4,5,etc........};

memcpy (FONT_IN_RAM, arial_8pt, TABLE_SIZE);

This doesn't:

char *FONT_TABLE = arial_8pt;

memcpy (FONT_IN_RAM, FONT_TABLE, TABLE_SIZE);

Is there a way of doing this please?

I tried "#DEVICE PASS_STRINGS=IN_RAM" amongst much else and pulling hair out!

Cheers
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Thu Nov 19, 2015 5:22 am     Reply with quote

You need to use rom, not const.

The point is that const is not designed to have pointers constructed to it. The memcpy ability to use const, relies on memcpy 'knowing' that it is talking to a const. By trying to use an actual pointer variable, you are destroying this overload. Your variable says it is a pointer to RAM, and it isn't....

Code:

rom char arial_8pt[1111]={0,1,2,3,4,5,etc........};

rom char *FONT_TABLE = arial_8pt;

memcpy (FONT_IN_RAM, FONT_TABLE, TABLE_SIZE);


'rom' constructs a constant, designed to have rom pointers constructed to it.
Your pointer then needs to be a rom pointer.

memcpy, then knows what it is dealing with.
tinley



Joined: 09 May 2006
Posts: 66

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

PostPosted: Thu Nov 19, 2015 7:38 am     Reply with quote

Hi Ttelmah, Thank you very much for your reply.

Unfortunately it compiles but doesn't work!

Without an #ORG, it changes the location of the table to the end of ROM instead of near the beginning and it does alter the structure of the table...

But *FONT_TABLE is still not returning the table?
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Thu Nov 19, 2015 9:06 am     Reply with quote

It will alter the structure of the table, the rom table is built so it can be accessed using pointers, while the const table has the extra code added so it can be accessed as a program. and rom declarations normally are put near the end of the memory.

As a question, why do you actually want to copy it to RAM?.
Given that you can access it with rom pointers, it can be used from ROM just as easily.

Problem is that memcpy as written for the PIC24, is explicitly written to _only_ access RAM. It uses the direct RAM to RAM transfer ability, and this is why the manual says it only copies to/from RAM. strcpy, is overloaded to handle ROM pointers.

Just do your own version of memcpy, to handle ROM data. Something like:
Code:

void rommemcpy(unsigned int8 * dest,rom char * source, unsigned int16 count)
{
   if (count==0 return;
   do {
   *dest++=*source++;
   } while (--count);
}


With this, and the rom font (in my case, just called 'font'), if merrily works with:
Code:

   char buffer[256];
   rom char * fontptr;

   fontptr=font;
   rommemcpy (buffer, fontptr, sizeof(font));
tinley



Joined: 09 May 2006
Posts: 66

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

PostPosted: Fri Nov 20, 2015 7:20 am     Reply with quote

The built in display controller can only access font tables in RAM on the PIC24FJxxxDAxxx chips.

Whilst there is plenty of ROM to store fonts, the ram can only store a couple at a time, so I need to transfer font tables on the fly.

Thanks for the code. Ironically I was using a loop to copy before changing it to memcpy, but your code looks more elegant than mine, so I shall use it!

Thank you!
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Fri Nov 20, 2015 8:09 am     Reply with quote

A good reason. Smile

Annoyingly, the overload ability, on the current releases doesn't seem to be able to tell between a rom pointer, and a normal pointer. I'm sure it did a while ago, when I was doing something similar. I was going to write an overloaded version, that would automatically switch between memcpy, and the rom version, depending on the types of the pointer passed, but the overload doesn't want to work...
tinley



Joined: 09 May 2006
Posts: 66

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

PostPosted: Fri Nov 20, 2015 8:47 am     Reply with quote

Thanks Ttelmah,

I can confirm that works when the typo is fixed!!!

Code:

if (count==0) return;


Thank you very much for your help.
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