• AVR Freaks

Hot!Reading / writing from flash on PIC24H

Author
LGOR
New Member
  • Total Posts : 11
  • Reward points : 0
  • Joined: 2012/11/11 03:06:04
  • Location: 0
  • Status: offline
2019/11/11 08:07:39 (permalink)
0

Reading / writing from flash on PIC24H

Hi
I would like to read / write some configuration data in flash memory of a PIC24H.
To be able to use the builtin NVM fuctions I switched from the C30 compiler to the XC16 compiler and started testing the harmony example concerning flash read/erase/ write: https://microchipdeveloper.com/16bit:flash-write
However I am unable to compile the example code because the used NVMADRU & NVMADR variables (macro's ?) seems to be undefined. Am I missing some includes, defines ... the application note only shows some code snippets which makes it hard to find out (is there some more complete sample available ?).
 
Any help appreciated
Luc
 
 
My code ...
 
#include <xc.h>
#include <stdint.h> /* Includes uint16_t definition */
#include <stdbool.h> /* Includes true/false definition */
__prog__ int __attribute__ ((space(prog),address (0x6000))) PROG_ADDR = 0xFFFF;
int ramLoc;
 
void executeNVM()
{
__builtin_disi(6);
__builtin_write_NVM();
while (NVMCONbits.WR)
Nop();
}
void readFlash()
{
TBLPAG = __builtin_tblpage(&PROG_ADDR);
int addrOffset = __builtin_tbloffset(&PROG_ADDR);
ramLoc = __builtin_tblrdl(addrOffset);
}
void eraseFlashPage()
{
NVMADRU = __builtin_tblpage(&PROG_ADDR); // NVMADRU & NVMADR undefined !!!!!!!!!!!!!!!!
NVMADR = __builtin_tbloffset(&PROG_ADDR);
NVMCON = 0x4001;
executeNVM();
}
void writeFlashRow()
{
int offset;
TBLPAG = 0xFA; // write latches
for (offset = 0 ; offset < 64 ; offset++)
{
__builtin_tblwtl(offset, 0);
__builtin_tblwth(offset, 0);
}
NVMADRU = __builtin_tblpage(&PROG_ADDR);
NVMADR = __builtin_tbloffset(&PROG_ADDR);
NVMCON = 0x4001;
executeNVM();
}

int main ( void )
{
RCONbits.SWDTEN=0;
readFlash();
writeFlashRow();
readFlash();
while (1)
Nop();
return 0;
}
#1

6 Replies Related Threads

    NorthGuy
    Super Member
    • Total Posts : 5817
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: offline
    Re: Reading / writing from flash on PIC24H 2019/11/11 08:24:54 (permalink)
    0
    There are lots of different PIC24/dsPIC33 devices and they all have different methods of writing flash. The code you post is for a different PIC (which has NVMADRU/NVMADR registers). The easiest way is to read the RTSP section of the datasheet and act accordingly.
     
    post edited by NorthGuy - 2019/11/11 08:51:34
    #2
    Pusb
    Senior Member
    • Total Posts : 106
    • Reward points : 0
    • Joined: 2004/02/09 09:47:27
    • Status: offline
    Re: Reading / writing from flash on PIC24H 2019/11/11 10:39:31 (permalink)
    0
    For devices supported in MCC, there's a 'flash' support in the MCC PIC24/dsPIC device library.
     
    Unfortunately, PIC24H is not a supported family in MCC.
     
    Alternatively, XC16 compiler has flash library routines. The MCC flash supersedes the XC16 flash for devices supported in MCC. 
     
    #3
    LGOR
    New Member
    • Total Posts : 11
    • Reward points : 0
    • Joined: 2012/11/11 03:06:04
    • Location: 0
    • Status: offline
    Re: Reading / writing from flash on PIC24H 2019/11/12 11:45:18 (permalink)
    0
    I did some more reading on the PIC24H RTSP programming and found out I can write a full row (64 * 3bytes) by writing to the latches and then start the programming sequence. However every example for writing the latches is assembler code and I can't figure out how to translate the TBLWTL and TBLWTH instructions to the __builtin_tblwtl and __builtin_tblwth funtions. I tried to translate the assembler code for erasing a page and writing a row to C but I desperately need help ... or some C sample code.
     
    Thanks for any help!
     
    __prog__ int __attribute__ ((space(prog),address (0x6000))) PROG_ADDR; 
     
    void eraseFlashPage()
    {
       //Perform dummy table write to the Page to be erased.
       //MOV #tblpage(PROG_ADDR),W0
       //MOV W0,TBLPAG
       TBLPAG = __builtin_tblpage(&PROG_ADDR);
     
       // ******* DON'T KNOW HOW TO TRANSLATE FOLLOWING INSTRUCTIONS 
      //MOV #tbloffset(PROG_ADDR),W0
       //TBLWTL w0,[w0]
       __builtin_tblwtl(__builtin_tbloffset(&PROG_ADDR), ??);
       __builtin_tblwth(__builtin_tbloffset(&PROG_ADDR), ??);
       /// ***********************************************************
       NVMCON = 0x4042; // request page erase
       executeNVM();
    }
     
    void writeFlashRow()
    {
       //Setup pointer to first program location to be written
       //MOV #tblpage(PROG_ADDR),W0
       //MOV W0,TBLPAG
       TBLPAG = __builtin_tblpage(&PROG_ADDR);
     
       // Perform the TBLWT instruction to write the latches
       for (int offset = 0 ; offset < 128 ; offset += 2 )
       {
           // ******* DON'T KNOW HOW TO TRANSLATE FOLLOWING INSTRUCTIONS  
           //MOV #ram_image,W1
           //TBLWTL [W1++],[W0]
           //TBLWTH [W1++],[W0++]
           __builtin_tblwtl(??, ??);
           __builtin_tblwth(??, ??);
           // **********************************************************
        }
        NVMCON = 0x4001; // request row write
        executeNVM();
    }
     
    void executeNVM()
    {
       __builtin_disi(6); // disable interrupts
       __builtin_write_NVM(); // write sequence 0x55 - 0xAA to NVMKEY to unblock + set WR
        while (NVMCONbits.WR) // wait for completion
           Nop();
    }
     
    #4
    DuaneH
    New Member
    • Total Posts : 13
    • Reward points : 0
    • Joined: 2009/10/15 11:49:22
    • Location: Sandy, UT
    • Status: offline
    Re: Reading / writing from flash on PIC24H 2019/11/12 14:03:42 (permalink)
    0
    Here is some code that I have used:

    //save_values:
    void save_values (void)
    {
    int SAV_TBLPAG, SAV_SR;
    uint *up, psvsave, wh, we, c1, c2, c3, c4;
    SAV_TBLPAG = TBLPAG;
    SAV_SR = SR;
    psvsave = PSVPAG;
    PSVPAG = 1;
    up = (uint*) CFG1;
    c1 = *up;
    up = (uint*) CFG2;
    c2 = *up;
    SRbits.IPL = 0x7; //Disable Interrupts
    NVMCON = FLASH_ROW_ERASE_CODE; //Erase code command
    TBLPAG = 0;
    __builtin_tblwtl(WHL_ADDR & 0xfc00, 0xFFFF);
    __builtin_write_NVM(); //Unlock NVMCON and initiate erase
    while(NVMCONbits.WR); //Wait for operation complete
    __builtin_tblwtl(WHL_ADDR, wheel_center);
    __builtin_tblwth(WHL_ADDR, 0);
    __builtin_tblwtl(WEIGHT_ADDR, weight_set);
    __builtin_tblwth(WEIGHT_ADDR, 0);
    __builtin_tblwtl(BACKOFF_ADDR, back_time);
    __builtin_tblwth(BACKOFF_ADDR, 0);
    __builtin_tblwtl(INCLINE_ADDR, incline_zero);
    __builtin_tblwth(INCLINE_ADDR, 0);
    __builtin_tblwtl(PERCENT_ADDR, percentage);
    __builtin_tblwth(PERCENT_ADDR, 0);
    NVMCON = FLASH_ROW_WR_CODE; //Flash ROW write command
    __builtin_write_NVM(); //Unlock NVMCON and initiate write
    while(NVMCONbits.WR); //Wait for operation complete
    up = (uint*)WHL_ADDR;
    wh = *up++;
    we = *up;
    up = (uint*) CFG1;
    c3 = *up;
    up = (uint*) CFG2;
    c4 = *up;
    PSVPAG = psvsave;
    TBLPAG = SAV_TBLPAG;
    SR = SAV_SR;
    }

    duaneh
    #5
    LGOR
    New Member
    • Total Posts : 11
    • Reward points : 0
    • Joined: 2012/11/11 03:06:04
    • Location: 0
    • Status: offline
    Re: Reading / writing from flash on PIC24H 2019/11/13 11:49:48 (permalink)
    0
    Hi Duaneh
     
    Thanks for sharing code, but I am missing some import parts to understand:
       - what is the definition of WHL_ADDR, WEIGHT, BACKOFF_ADDR, ...
       - for the erasing code:
            - what page are you erasing?
            - What is the goal of the AND function with & 0xfc00? Has it something to do with the address of the write latches?
            - what is the exact PIC24 device (looks very important to check absolute addresses)
       - for the writing code:
            - what is the definition of wheel center, weight_set? Are those just values or addresses in ram?
     
    Thx
    Luc
     
     
     
     
    #6
    LGOR
    New Member
    • Total Posts : 11
    • Reward points : 0
    • Joined: 2012/11/11 03:06:04
    • Location: 0
    • Status: offline
    SOLVED: Reading / writing from flash on PIC24H 2019/11/15 04:19:26 (permalink)
    0
    I finally found out how to use to read / write / erase flash memory.
    Thanks to NorthGuy and Duanah for pointing me in the right direction!
     
    I wrote some functions to exchange arbitrary structured data between ram and flash dealing with the 24 bits data in program space and multiple rows in page. Because it seems hard to find some C examples I am sharing the code in attached file. See usage below ...
     
    struct TestStruct
    {
       char aChar;
       int aInt;
       long longs[300];
    };

    int main ( void )
    {
       int i;
       struct TestStruct testWrite, testRead;
       // Write some arbitrary data to the structure
       testWrite.aChar = 'A';
       testWrite.aInt = 1234;
       for (i = 0 ; i < sizeof(testWrite.longs) / sizeof(testWrite.longs[0]) ; i++ )
          testWrite.longs = 100000 + i;
     
       writeNVM(&testWrite, sizeof(testWrite)); // Write test data to flash
       readNVM(&testRead, sizeof(testRead)); // Read back flash data in other instance
    ...
    }
     
    #7
    Jump to:
    © 2019 APG vNext Commercial Version 4.5