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

write_configuration_memory() compilation error

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



Joined: 01 Jul 2016
Posts: 8

View user's profile Send private message

write_configuration_memory() compilation error
PostPosted: Tue Jul 12, 2016 6:49 am     Reply with quote

Hi,
I've have to write on user ID area a checksum code for bootloading reason. Normally in my previous PIC18 and PIC16 designs I use write_program_eeprom API and it works as expected. Now I'm approaching a project with PIC16F18325 and it doesn't works. I've seen documentation and I've found new APIs for accessing that area :
write_configuration_memory() and read_configuration_memory().
read_configuration_memory works as expected but with write_configuration_memory, compiler raise an error that I don't understand. Below the compiler's output with error and a simple example with the API.

ERROR ->
>>> Warning 240 "test_ccs.c" Line 19(35,36): Pointer types do not match
*** Error 102 "test_ccs.c" Line 19(35,36): Expect comma
1 Errors, 1 Warnings.
Build Failed.
<-

Code:

#include <16f18325.h>
void main(void){
   unsigned char buffer[8];
   int i = 0;
   
   buffer[0] = 0x08;
   buffer[1] = 0xF0;
   buffer[2] = 0x0D;
   buffer[3] = 0xF0;
   buffer[4] = 0x0D;
   buffer[5] = 0xF0;
   buffer[6] = 0x08;
   buffer[7] = 0xF0;
   
   write_configuration_memory(buffer,8);
   
   while (1) {
      i++;
   }
}

Thanks for any support
Fabio
Ttelmah



Joined: 11 Mar 2010
Posts: 19359

View user's profile Send private message

PostPosted: Tue Jul 12, 2016 7:04 am     Reply with quote

Look at the data sheet.

Look at table 10-3.

What does the column 'write access' say about the configuration words?....

Because it cannot work, the compiler is 'hiccuping', and thinking you mean to use an offset, and so should have the third parameter....
ftoffolon



Joined: 01 Jul 2016
Posts: 8

View user's profile Send private message

PostPosted: Tue Jul 12, 2016 8:36 am     Reply with quote

My device table says that I can also write on user id area (0x8000-0x8003).
I've also tried to put optional 1st parameter to zero, so no offset 'cause the user id area is on 1st address of configuration memory, but another error comes from compiler :
Code:

#include <16f18325.h>
void main(void){
   unsigned char buffer[8];
   int i = 0;
   
   buffer[0] = 0x08;
   buffer[1] = 0xF0;
   buffer[2] = 0x0D;
   buffer[3] = 0xF0;
   buffer[4] = 0x0D;
   buffer[5] = 0xF0;
   buffer[6] = 0x08;
   buffer[7] = 0xF0;
   
   write_configuration_memory(0,buffer,8);
   
   while (1) {
      i++;
   }
}

ERROR ->
>>> Warning 203 "test_ccs.c" Line 17(1,1): Condition always TRUE
*** Error 112 "test_ccs.c" Line 15(1,1): Function used but not defined: ... write_configuration_memory 893 SCR=1391
1 Errors, 1 Warnings.
Build Failed.
<-


I'm using CCS 5.061

Thanks
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Tue Jul 12, 2016 9:37 am     Reply with quote

The manual entry for write_configuration_memory() says:

Quote:
On all PIC18 Family of chips, the configuration memory is readable and writable. This functionality is not available on the PIC16 Family of devices.


Your device is a PIC16, therefore does not have writable configuration memory, and thus no write_configuration_memory() function is provided by CCS for that device.

Also, if your device was a PIC18, you must never write to 0x8007 and beyond as your code does, or tries to. This area is the fuses, and writing to them is not going to end well. Even bootloaders, which might try, generally don't, or should not under normal operation. Bootloaders should always have the same fuses as the code they are intended to load.
ftoffolon



Joined: 01 Jul 2016
Posts: 8

View user's profile Send private message

PostPosted: Tue Jul 12, 2016 10:34 am     Reply with quote

Sorry RF_Developer but on compiler (rel. 5.061) documentation of write_configuration_memory() says that, on Enhanced16, I can use it for User ID memory, and microcontroller datasheet says it's writable.

See CCS manual extract :

->

write_configuration_memory( )
Syntax:
write_configuration_memory ([offset], dataptr,count)

Parameters:
dataptr: pointer to one or more bytes
count: a 8 bit integer
offset is an optional parameter specifying the offset into configuration memory to start writing to, offset defaults to zero if not used.
Returns:
undefined
Function:
For PIC18 devices-Erases all fuses and writes count bytes from the dataptr to the configuration memory.
For Enhanced16 devices - erases and write User ID memory.

Availability:
All PIC18 Flash and Enhanced16 devices
<-


Regards
temtronic



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

View user's profile Send private message

PostPosted: Tue Jul 12, 2016 11:08 am     Reply with quote

I downloaded the datasheet for that PIC and all I can find is ...
Program Flash memory consists of 8192 14-bit words
as user memory, with additional words for user ID
information, Configuration Words, and interrupt
vectors. Program Flash memory provides storage
locations for:
• User program instructions
• User defined data
Program Flash memory data can be read and/or written
to through:
• CPU instruction fetch (read-only)
• FSR/INDF indirect access (read-only)


Please note (read-only) !!

So I'm assuming that you cannot 'actively' write to memory, unlike other PICs.

Others will know for sure but usually Microchip will 'promote' any feature like R/W mem. Now there may be a 'family' memeber of that PIC that does have the feature.

You have to remmeber just because the compiler has a function that works on some PICS you need to confirm by reading read datasheet which these days is 400-500 pages long !

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19359

View user's profile Send private message

PostPosted: Tue Jul 12, 2016 1:51 pm     Reply with quote

If you look at the table I referred to, the main memory is writeable, but the configuration area isn't. The ID should be, but I'm not sure how.

I'd have to sit down and write a routine to do it. Problem is that the standard write will try to erase a page, and the configuration memory is in the same page, and not writeable!......
Duh.
Ttelmah



Joined: 11 Mar 2010
Posts: 19359

View user's profile Send private message

PostPosted: Wed Jul 13, 2016 1:03 am     Reply with quote

I have to ask. Why not put the checksum in the EEPROM?.

This is much easier memory to use. Byte wide, and can be written and erased byte by byte. Even if you are using the EEPROM for other things, you could reserve (say) the last four bytes of this for a checksum.

Alternatively, the standard way, is just to have the last couple of words in the main memory, containing a value to make the whole of memory 'sum' to a particular constant.

CCS have omitted the write_configuration_memory function, since there are only 4*14bits that can actually be written using it. If you must go this way, then ask them to add it, or write your own.
ftoffolon



Joined: 01 Jul 2016
Posts: 8

View user's profile Send private message

PostPosted: Wed Jul 13, 2016 1:55 am     Reply with quote

Hi,

to temtronic :

on PIC16F18325 datasheet (last release), after row FSR/INDF indirect access (read-only) you find :
. NVMREG access (Section 10.4 “NVMREG Access")
that explain how to write to flash and also to user id area.
And on table 10-3 it's explicitly indicate that user id area (0x8000-0x8003) is writtable. I know that datasheet has a lot of pages but I'm tring to read all of these, at least all of these involved on my program.



to Ttelmah:

of course write access to eeprom is easy but I've chosen, as in many PIC16 and PIC18 project (also PIC16F1825, very similar to PIC16F18325) to use user id, to storage my bootloadable program checksum, for safety reason, to put on a region not involved to my normal program. On PIC16F1825, where I've used CCS 4.132 at that time, I've seen that write_program_memory() api doesn't works (unlike on PIC16F19xx) and write_configuration_memory() was available only for PIC18, so I've written a procedure on my own, following datasheet assembly indication, to do the job and it works, so it's possible to write on user id. On CCS 5.061 I've noticed that write_configuration_memory() is availabe also for Enhanced16 and I hoped that CCS has covered that gap on there apis. Maybe there is some jobs to do on CCS side?

Regards and thanks for your response on my issue
Fabio
Ttelmah



Joined: 11 Mar 2010
Posts: 19359

View user's profile Send private message

PostPosted: Wed Jul 13, 2016 2:27 am     Reply with quote

Just worth adding, that the code example MicroChip, gives for writing to the User ID on this chip, doesn't work....

Probably explains why CCS have omitted it.

Then Table 10-2, disagrees with MicroChip's own comment in Table 10-3. If you look this shows for NVM access, for the User ID, config etc., 'READ', not 'READ WRITE'.....

Nothing listed yet in the errata about this.
Ttelmah



Joined: 11 Mar 2010
Posts: 19359

View user's profile Send private message

PostPosted: Wed Jul 13, 2016 3:31 am     Reply with quote

OK. Looking at the data sheet, the code given to supposedly access the ID, is the code to access program memory, not the ID....
Copying from a couple of other chips with the ID access, it looks as if this should be close to what is needed:
Code:

#BYTE NVMADRL = getenv("SFR:NVMADRL")
#BYTE NVMADRH = getenv("SFR:NVMADRH")
#BYTE NVMDATL = getenv("SFR:NVMDATL")
#BYTE NVMDATH = getenv("SFR:NVMDATH")
#BYTE NVMCON1 = getenv("SFR:NVMCON1")
#BYTE NVMCON2 = getenv("SFR:NVMCON2")
#bit NVRD=NVMCON1.0
#bit NVWR=NVMCON1.1
#bit WREN=NVMCON1.2
#bit FREE=NVMCON1.4
#bit LWLO=NVMCON1.5
#bit NVMREGS=NVMCON1.6

void write_ID(int8 * buffer)
{
   int1 GIE;
   int8 ctr;
   //designed just to write the 8 bytes of the User ID
   //sequence needs to begin with GIE disabled, and UNLOCK
   GIE=interrupt_enabled(GLOBAL); //remember if interrupts are enabled
   disable_interrupts(GLOBAL);
   NVMREGS=TRUE; //access the special registers
   LWLO=1; //latch data
   WREN=TRUE;
   NVMADRL=0;
   NVMADRH=0; //User ID is at address 0..3
   for (ctr=0;ctr<4;ctr++)
   {
      NVMDATL=*(buffer++);
      NVMDATH=*(buffer++); //latch the 14bits of data
   
      NVMCON2=0x55;
      NVMCON2=0xAA; //unlock
      NVWR=TRUE; //set write bit
      //delays supposedly not needed
      if (ctr==2)
         LWLO=0; //write will trigger on the next pass
      NVMADRL++; //next address
   }
   NVWR=FALSE;
   NVMREGS=FALSE;
   if (GIE)
      enable_interrupts(GLOBAL); 
}


Can't test this today, but it looks close, if the chip does allow access....
ftoffolon



Joined: 01 Jul 2016
Posts: 8

View user's profile Send private message

PostPosted: Thu Jul 14, 2016 3:45 am     Reply with quote

Thank you very much Ttelmah,

this week I'm fully involved into other project but next one I'll try your example.

Regards
ftoffolon



Joined: 01 Jul 2016
Posts: 8

View user's profile Send private message

PostPosted: Fri Jul 22, 2016 5:29 am     Reply with quote

Hi Ttelmah,

Finally I've found time to test your procedure. Unfortunately has no success. I've checked an old porject I've done with PIC16F1825, where I've implemented my proceudre to write User ID area. I've translated it with new registry names of PIC16F18325 (they are almost the same, only with different names) and it works !
Now I can write to user ID area.

Here's the procedure:
Code:

#pragma byte EECON1 = getenv("SFR:NVMCON1")
#pragma byte EECON2 = getenv("SFR:NVMCON2")

#pragma byte EEDATL = getenv("SFR:NVMDATL")
#pragma byte EEDATH = getenv("SFR:NVMDATH")

#pragma byte EEADRL = getenv("SFR:NVMADRL")
#pragma byte EEADRH = getenv("SFR:NVMADRH")


#define EEPG      0x80
#define CFGS      0x40
#define LWLO      0x20
#define FREE      0x10
#define WRERR      0x08
#define WREN      0x04
#define WR      0x02
#define RD      0x01


#define __Nop()      \
   #asm nop #endasm

void write_user_id(uint_16 u16data)
{
   uint_16 u16_tmp;
    uint_8 i;

    // erase
   EEADRH = 0x80;
    EEADRL = 0x00;
   EECON1 |= CFGS;
    EECON1 |= EEPG;
   EECON1 |= FREE;
    EECON1 |= WREN;
   EECON2 = 0x55;
    EECON2 = 0xAA;
   EECON1 |= WR;
    __Nop();
   __Nop();
    EECON1 &= ~WREN;

   // write
    EEADRH = 0x80;
    EEADRL = 0x00;

   EECON1 |= CFGS;
    EECON1 |= EEPG;
   EECON1 &= ~FREE;
   EECON1 |= WREN;
    EECON1 |= LWLO;

    for (i = 0;i <= 3;i++)
   {
       u16_tmp = (u16data & (0xF000 >> (i*4)));

      u16_tmp >>= (12 - (i*4));
       u16_tmp <<= 8;
      u16_tmp &= 0x0F00;
       u16_tmp |= 0x00F0;

       EEDATL =  make8(u16_tmp,1);
      EEDATH =  make8(u16_tmp,0);

      if (i == 3)
       {
         EECON1 &= ~LWLO;
       }

      EECON2 = 0x55;
      EECON2 = 0xAA;

      EECON1 |= WR;

       __Nop();
      __Nop();

      EEADRL++;
   }
   EECON1 &= ~WREN;
}


Best regards
Ttelmah



Joined: 11 Mar 2010
Posts: 19359

View user's profile Send private message

PostPosted: Fri Jul 22, 2016 5:59 am     Reply with quote

Well done.

You can do the nop with:
Code:

#define __Nop() delay_cycles(1)


The data sheet says that you have to use address 0, with NVMREGS set to true (which is what I coded). However you are using address 0x8000.

It suggests the whole data sheet about this bit is wrong (look at the other errors we already found), so instead use the sheet/routine for a similar chip, to get it working....

Ouch...

Even more annoying, this means the standard CCS code to write to the program memory would work, if it allowed you to use address 0x8000 (which it won't).
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