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

#ROM directive difference between 16F1503 & 18F24K40

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



Joined: 07 Dec 2016
Posts: 60
Location: Northeast USA

View user's profile Send private message

#ROM directive difference between 16F1503 & 18F24K40
PostPosted: Wed Sep 19, 2018 4:00 pm     Reply with quote

CCS Compiler Version 5.073
Windows 10

On my PIC18F24K40 target device, I am initializing some data in the EEPROM. The following code works correctly on the PIC18F24K40:

Code:

#define EEPROM_ADDR_START getenv("EEPROM_ADDRESS")
#define EEPROM_MYDATA0_ADDR EEPROM_ADDR_START
#define EEPROM_MYDATA1_ADDR EEPROM_ADDR_START + 1
#define EEPROM_MYDATA2_ADDR EEPROM_ADDR_START + 2
#define EEPROM_MYDATA3_ADDR EEPROM_ADDR_START + 3

#ROM EEPROM_ADDR_START = {10,20,30,40}                   


When I try to port this code over to my PIC16F1503 target device and compile, I am presented with the following compiler error:

Quote:
Error#126 Invalid ORG range


...and the error points to the last closing curly brace in the source code.
For the record, it is only the last line with the #ROM directive that causes this compiler error to pop up. Any ideas on why this does not function the same between these two PICs?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Sep 19, 2018 4:19 pm     Reply with quote

The 16F1503 doesn't have eeprom.

The datasheet says:
Quote:
3.2 High-Endurance Flash
This device has a 128 byte section of high-endurance
program Flash memory (PFM) in lieu of data EEPROM.
This area is especially well suited for nonvolatile data
storage that is expected to be updated frequently over
the life of the end product.
apakSeO



Joined: 07 Dec 2016
Posts: 60
Location: Northeast USA

View user's profile Send private message

PostPosted: Thu Sep 20, 2018 8:33 am     Reply with quote

Thanks PCM

Is there already a built in method with the CCS compiler to read/write and initialize this memory in the 16F1503?

Something like the write_eeprom() and read_eeprom() functions for PICs that do have EEPROM, but for PFM NV data that needs to be modified during run time?
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Thu Sep 20, 2018 10:25 am     Reply with quote

Yes, and no.

Initialisation, you just use #ROM. It is just that the data has to be put at the address where the PFM is, instead of the EEPROM. However big 'caveat', remember that the program memory has each word 14bits wide. So your data layout will have to change significantly.

In use, there is a library designed to use two pages of the program memory to emulate an EEPROM (there is a big problem in that program memory has to be erased in pages, so single byte writes need to be done my using a marker and changing single words from the erased state to a used value, and then when a page is full, copying this to a second page and erasing). The driver to do all this is 'virtual_eeprom.c'.

Honestly for most applications I'd say add an external EEPROM. Much easier. However for a limited amount of data, that does not change at all frequently this driver can be used.
alan



Joined: 12 Nov 2012
Posts: 357
Location: South Africa

View user's profile Send private message

PostPosted: Thu Sep 20, 2018 10:50 am     Reply with quote

Why not use a PIC16F1825 it is pin compatible with EEPROM. I moved from the 1503 to 1825 using same board as I wanted EEPROM.
apakSeO



Joined: 07 Dec 2016
Posts: 60
Location: Northeast USA

View user's profile Send private message

PostPosted: Thu Sep 20, 2018 12:18 pm     Reply with quote

Thanks Ttelmah & Alan

The first solution will get my prototypes out.
Alan's solution will make it easier in the future.

Must appreciated, yet again.
apakSeO



Joined: 07 Dec 2016
Posts: 60
Location: Northeast USA

View user's profile Send private message

PostPosted: Thu Sep 20, 2018 3:02 pm     Reply with quote

I'm having a bit of trouble understanding the virtual_eeprom.c driver. I need to initialize 4 calibration constants during program upload, and then during run time, be able to modify them. Calibration constants are all 8-bit unsigned ints. I know program memory is 14-bits, so I plan to use only the lower 8 bits and mask off the rest.

The PIC16F1503 datasheet tells me the last program memory address is 0x07FF. The High-endurance flash memory which I am interested in has an address range of 0x0780 - 0x07FF

Thus I want my 1st cal constant to be stored at 0x0780


Code:

#include <16F1503.h>
#device PIC16F1503
#fuses NOWDT,NOPROTECT,NOBROWNOUT,NOPUT                           
#fuses NOWRT                                    // No write protection for program memory

#use delay(INTERNAL=2MHZ)                                         // Set clock internally sourced, 2MHz
#use rs232(BAUD=9600,XMIT=PIN_C0,RCV=PIN_C2,TRANSMIT_BUFFER=16,BITS=8,PARITY=N,STOP=1,ERRORS,STREAM=uart1)

#include <virtual_eeprom.c>
#DEFINE VIRTUAL_EEPROM_16BIT_ADDY

#ROM 0x0780 = {0xAB}

void main(void)
{

    init_virtual_eeprom();
   
    int8 counter = 0x00;     // Just a counter to see something incrementing
                             // on serial uart for debug
    while(1)
    {
        int16 v_ee_data             = read_virtual_eeprom(0x0780);
        int8   v_ee_data_parsed = v_ee_data & 0xFF;

        fputc(counter, uart1);
        putc_send();
       
        fputc(v_ee_data_parsed, uart1);
        putc_send();
       
        if(counter<0xFF) counter++;
        else             counter = 0;
        delay_ms(500);       
    }   
}



When this code is run and I check the serial stream on my scope, I always first receive the counter byte, incrementing on each loop as expected, but the following byte, v_ee_data_parsed, is always = 0xFF

What have I missed in the code above?
Is there more setup to do in virtual_eeprom.c?
apakSeO



Joined: 07 Dec 2016
Posts: 60
Location: Northeast USA

View user's profile Send private message

PostPosted: Thu Sep 20, 2018 3:39 pm     Reply with quote

I believe that the values stored in program memory need to be read as 16-bit ints ( because that's the next highest up standard type in CCS ) and then masked into 8-bit values, for what I want. I made the following changes to code, and when I browse the program memory space, I see the values initialized correctly as such:

Code:

#include <16F1503.h>
#device PIC16F1503
#fuses NOWDT,NOPROTECT,NOBROWNOUT,NOPUT                           
#fuses NOWRT

#use delay(INTERNAL=2MHZ)                                         // Set clock internally sourced, 2MHz
#use rs232(BAUD=9600,XMIT=PIN_C0,RCV=PIN_C2,TRANSMIT_BUFFER=16,BITS=8,PARITY=N,STOP=1,ERRORS,STREAM=uart1)

#include <virtual_eeprom.c>
#define VIRTUAL_EEPROM_16BIT_ADDY

#ROM 0x0780  = {0xAB}             
#ROM 0x0781  = {0xCD}
#ROM 0x0782  = {0xEF}             

void main(void)
{

    init_virtual_eeprom();
   
    int8 counter = 0x00;     // Just a counter to see something incrementing
                             // on serial uart for debug
   
    while(1)
    {

        int16 v_ee_data16  = read_virtual_eeprom(0x0780);
        int8  v_ee_data8   = v_ee_data16 & 0xFF;
             
        fputc(counter, uart1);
        putc_send();
       
        fputc(v_ee_data8, uart1);       
        putc_send();
       
        if(counter<0xFF) counter++;
        else             counter = 0;
        delay_ms(500);       
    }   
}






However, I'm still getting back a value of 0xFF for v_ee_data8, every time.
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Fri Sep 21, 2018 3:01 am     Reply with quote

Wrong in quite a few ways...

When setting defines to control a loaded driver, the values need to be defined _before_ you load the driver.
On your chip you have a total of 128bytes of the PFM. No point in using 16bit addresses, to talk to this.
You do not talk to a memory address, but to a virtual EEPROM address. Just as if your chip had an EEPROM.
Data stored has to be formatted ready for this virtual driver.
Also in order to give a reasonable number of values, you may need to increase the number pf pages used.

So:
Code:

#include <16F1503.h>
#device PIC16F1503
#fuses NOWDT,NOPROTECT,NOBROWNOUT,NOPUT                           
#fuses NOWRT

#use delay(INTERNAL=2MHZ)                                         // Set clock internally sourced, 2MHz
#use rs232(BAUD=9600,XMIT=PIN_C0,RCV=PIN_C2,TRANSMIT_BUFFER=16,BITS=8,PARITY=N,STOP=1,ERRORS,STREAM=uart1)

//Rom has to be loaded _before_ the driver. Otherwise it reserves the page

#rom int16 0x7C0 = { 0,0xFF, 1,0xAA, 2,0x55, 3,0x11, 4,0x22, 5,0x33, 6, 0x44, 7,0x66 }
//8 secords setup in the virtual EEPROM, numbered 0 to 7
//note you store address, value, address, value etc..
//Load this before the VE driver
//Note the first page used is in the middle of the used range

#define VIRTUAL_EEPROM_8BIT_ADDY
//defines controlling the virtual EEPROM driver must be set _before_ loading
//the driver...
//Your chip only has a small area of PFM. Pointless using 16bit addressing
#define VIRTUAL_EEPROM_NUM_PAGES 4
#include "virtual_eeprom.c"
//Use " so loads the local copy of this driver
         

void main(void)
{
    int8 v_ee_data8;
    int16 test;
   
    int8 counter;     // Just a counter to see something incrementing
                             // on serial uart for debug 
    test=_VE_PAGE0_START;
    test=_VE_PAGE1_START;
    test=_VE_PAGE1_END;

    init_virtual_eeprom();

   
    for (counter=0; counter<0x8;counter++)
    {

        v_ee_data8 = read_virtual_eeprom(counter); //you read bytes from a virtual _eeprom_ address
        //not the memory address. The driver returns _bytes_.
             
        fprintf(uart1, "Count: %d\n", counter);
        putc_send();
       
        fprintf(uart1, "Val: %02x\n\r",v_ee_data8);       
        putc_send();
       
        delay_ms(500);
    }   
}


This correctly displays

Count:0
Val:FF
Count:1
Val: AA

etc..

The only change, is that I have edited the virtual_eeprom driver, 'remming' out the following two lines:

//#org _VE_PAGE0_START,(_VE_PAGE0_END-1) {}
//#org _VE_PAGE1_START,(_VE_PAGE1_END-1) {}

If you don't do this, you can't #ROM data into the area reserved by the driver (it expects you to write the data using it).

Consider the option of having a predefined set of config values in a variable, and if reading address 0 (say) does not return a suitable flag, writing this to the 'EEPROM' using the driver itself.
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