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

Reading program memory using inline assembler

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



Joined: 17 Nov 2016
Posts: 12

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

Reading program memory using inline assembler
PostPosted: Sun Nov 27, 2016 5:00 pm     Reply with quote

The MCU is PIC18F25K22

I have some tables in my code and those tables are in program memory.
For example the default settings for the application and the LCD initialization instructions and GUI state engine states - to name a few.

I would like to have a function like this:
Code:

#define   PGM_P   __ADDRESS__
typedef unsigned int8   uint8_t;

uint8_t   ReadProgMem   (PGM_P aAdr) {
#asm
   <the assembler code goes here>
#endasm
}


I know how to read the flash using TBLRD and associated SFRs.
What I do not know is:
- Assigning the address to the TBLPTRL, TBLPTRH and TBLPTRU SFRs
- Returning the value from the TABLAT register

In this case the __ADDRESS__ is declared as an 32 bit unsigned integer so the values go directly into the TBLPTR* registers.

I also would like to know whether the rest of the code will get tainted if I manipulate those SFRs. I WILL block interrupts during that operation and I will NOT use the function inside an interrupt.

Are there any other considerations with this - the code protection for example is set up in a way that this is possible.
temtronic



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

View user's profile Send private message

PostPosted: Sun Nov 27, 2016 5:14 pm     Reply with quote

obvious question
WHY not use the CCS C functions they provide??

Jay
esko



Joined: 17 Nov 2016
Posts: 12

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

PostPosted: Sun Nov 27, 2016 6:00 pm     Reply with quote

Yes - it IS a VERY obvious question. And it does nothing to help me Smile

I have already tried out the ONLY fucntion I could find for this purpose:
Code:

_bif void goto_address(__ADDRESS__ address);
_bif __ADDRESS__ label_address(__ADDRESS__ label);

// Program Memory Prototypes:
_bif void read_program_memory(__ADDRESS__ address, unsigned int8* dataptr, unsigned int16 count);


Alhough THAT might do what I want to do there is a lot of overhead in it.
Code:

#define   PGM_P   __ADDRESS__
typedef unsigned int8   uint8_t;

uint8_t   ReadProgMem   (PGM_P aAdr) {
   uint8_t   pbyte;
   read_program_memory( aAdr, &pbyte, 1 );
   return   pbyte;
}


I do not want THAT.

Sure someone has made a C function that takes a 32 bit argument and returns a byte. This is all the information I need - how does the compiler pass arguments to funcrtions and how it returns them.
temtronic



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

View user's profile Send private message

PostPosted: Sun Nov 27, 2016 6:08 pm     Reply with quote

from the ccs manual..

read_program_eeprom( )
Syntax:
value = read_program_eeprom (address)
Parameters:
address is 16 bits on PCM parts and 32 bits on PCH parts
Returns:
16 bits
Function:
Reads data from the program memory.

Availability:
Only devices that allow reads from program memory.



Requires:
Nothing



Examples:
checksum = 0;

for(i=0;i<8196;i++)

checksum^=read_program_eeprom(i);

printf("Checksum is %2X\r\n",checksum);



Example Files:
None



Also See:
write_program_eeprom(), write_eeprom(), read_eeprom(), Program Eeprom Overview

....

so am I missing 'something' here. This function does return what's in the PICs internal EEPROM...

If you really want assembler, then simply cut a small program using the function and dump the listing! CCS does not 'hide' anything,never has for the past 2 decades that I'm aware of.


Jay
esko



Joined: 17 Nov 2016
Posts: 12

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

PostPosted: Sun Nov 27, 2016 6:23 pm     Reply with quote

Actually ..... You are missing nothing Smile I quess I have to go back to elementary school and learn how to read Smile

There is one glitch though. This one returns a word (not a byte) and probably also wants the address to be aligned on word boundary.

Actually.... I will implement this one and then see what it does Smile
temtronic



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

View user's profile Send private message

PostPosted: Sun Nov 27, 2016 7:42 pm     Reply with quote

If you press F11 while your project is open, The CCS manual 'magically' appears.....
There are 4 different 'read-eeprom' functions, which one you use depends on the PIC you have as well as compiler. Some will return a byte, others a word, etc.
I just randomly PICked one to show you that sometimes reading the manual is kinda useful !!
It's always open when I work,can't remember syntax, or names and no nerves in left ring finger....so lots of typos...

Jay
esko



Joined: 17 Nov 2016
Posts: 12

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

PostPosted: Sun Nov 27, 2016 11:04 pm     Reply with quote

If I press ALT-CTL-F4 I get a new terminal.... out of 7 predefined.

This is a real Old School developing environment - no GUI - just the terminal Smile

Sorry about that.

As I said - I have to do more reading and less editing.
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Mon Nov 28, 2016 2:17 am     Reply with quote

Note that the code example in the data sheet also reads a word as well though. The address used to talk to the program memory, is a 'word address', so it is not easy to read on a byte basis.
You actually have to read a word, and then select the upper or lower byte.

To show how to do the assembler, if you did want to go that way:
Code:

//table read needs to access TBLPTR, TABLAT. Define these
#byte TBLPTRL=getenv("SFR:TBLPTRL")
#byte TBLPTRH=getenv("SFR:TBLPTRH")
#byte TBLPTRU=getenv("SFR:TBLPTRU")
#byte TABLAT=getenv("SFR:TABLAT")
//Up to this point answers your question about how to add register
//definitions for the assembler. These will now work


Now the function to read a single _word_ from the program memory, is 'read_program_eeprom'. The 'read_program_memory' function is designed to read a block.

If you look at the code generated for 'read_program_eeprom':
Code:

....................       value=read_program_eeprom(0x1000);
0016:  MOVFF  INTCON,@@0B
001A:  BCF    INTCON.GIEH
001C:  CLRF   TBLPTRU
001E:  MOVLW  10
0020:  MOVWF  TBLPTRH
0022:  CLRF   TBLPTRL
0024:  TBLRD*+
0026:  MOVF   TABLAT,W
0028:  TBLRD*
002A:  MOVFF  TABLAT,03
002E:  CLRF   TBLPTRU
0030:  BTFSC  @@0B.7
0032:  BSF    INTCON.GIEH
0034:  MOVWF  value
0036:  MOVFF  03,value+1


This is exactly the same as the code in the data sheet to read the program memory. Now much point in going DIY!....
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