Writing to Flash Memory on a 16-bit PIC® MCU

Overview of Writing to Flash Memory

Flash memory panels on 16-bit PIC® Microcontrollers (MCUs) are divided into pages. Each page consists of a number of rows. Each row has a set of 24-bit program words. Page and row sizes differ among the MCUs. Consult the datasheet to determine the page and row sizes for the PIC MCU you are using.

The implementation details of flash pages and rows are invisible to the application program. Rows and pages have no effect on program control or where the linker places program objects. Pages and rows are only taken into consideration when the application writes to the flash memory at run-time.

Writing to flash consists of loading the data to be written into a holding latch (or series of latches) using Table Write instructions. The flash address to be written to is loaded in the NVM address register. Once the data and address are loaded, a specific sequence of register operations will initiate the writing process. The writing process transfers the data from the holding latches into the Flash memory. During the writing process, the MCU stalls, resuming once the write operation has been completed

All 16-bit PIC MCUs allow the application program to specify individual Flash memory words to be written. Using this word addressed write method, 24-bits of data are loaded into a write latch with a pair of Table Write instructions (TBLWTH andTBLWTL). After the latch is loaded, the applications load the destination address into the NVM address registers. After both sets of registers are loaded, the application sets the control bits, then executes the write sequence on the NVMKEY register. The write sequence causes the data in the latches to be written to the Flash address specified by the NVM address registers.

Some devices provide the ability to program an entire row at one time. To program an entire row, the application loads a series of holding latch registers with repeated Table Write instructions. The applications then load the first address of the row to be written into the NVM address registers. After both sets of registers are loaded, the application executes the write sequence. With row programming, an entire row is written to flash at one time.

Resources used in writing to Flash Memory

Instructions

Assembly Read Instructions
TBLRDLTable_Read_LowReads the lower 16-bits of a 24-bit flash memory word. The address to be read is designated by theTBLPAG register and a working register passed to this instruction.
TBLRDHTable_Read_HighReads the upper 8- bits of a 24-bit flash memory word. The address to be read is designated by theTBLPAG register and a working register passed to this instruction.

ReadRead Flash Memory for more details on table read instructions.

Assembly Write Instructions
TBLWTLTable_Write_LowLoads 16-bits of data into a holding latch. The address of the data latch to be written to is designated by the table pageTBLPAG register and a working register. The latch will be written to flash memory when the programming sequence is initiated
TBLWTHTable_Write_HighLoads 8-bits of data into a holding latch. The address of the data latch to be written to is designated by theTBLPAG register and a working register. The latch will be written to flash memory when the programming sequence is initiated.
C Language Macros
MacroDescription
__builtin_tblpageReturns the page number of the memory address received as a parameter. For table instructions the returned value is placed inTBLPAG
__builtin_tbloffsetReturns the "offset" from the base page address for a memory location whose address is passed as a parameter. The return value of this function is passed as a parameter to table read and table write instructions
__builtin_write_NVMPerforms the programming sequence onNVMKEY then immediately sets theWR.__builtin_NVM causes the contents of the data latch(es) to be written to flash memory. This macro does NOT disable interrupts.
__builtin_disiDisables interrupts for a set number of instructions. This macro is typically called immediately preceding__builtin_write_NVM
__builtin_tblrdhReturns the upper 8-bits of the memory address specified byTBLPAG and the offset parameter. (CallsTBLRDH instruction)
__builtin_tblrdlReturns the lower 16-bits of the memory address specified byTBLPAG and the offset parameter. (CallsTBLRDL instruction)
__builtin_tblwrthWrites 8-bits of data to a holding latch which will be programmed to flash when the program sequence is initiated. This function receives two parameters: the value to be written and a page offset. This function determines the latch to be programmed using the contents ofTBLPAG and the offset parameter. (CallsTBLWRTH instruction)
__builtin_tblwrtlWrites 16-bits of data to a holding latch which will be programmed to flash when the program sequence is initiated. This function receives two parameters: the value to be written and a page offset. This function determines the latch to be programmed using the contents ofTBLPAG and the offset parameter. (CallsTBLWRTL instruction)

Registers

TBLPAG Table Page Register -TBLPAG is used by the Table Read and Table Write instructions. This register specifies the upper 8-bits of the address to be accessed by the table instruction. The lower 16-bits of the address are passed to the instruction as a value in a working register. When aTable Read instruction is to be executed this register contains the page address of the word to be read. When aTable Write instruction is to be executed TBLPAG should be loaded with the base address of the holding latch(es) (#FA00 on many16-bit PIC® MCUs.)

NVMADR/NVMADDRU NVM Address Registers. Holds the address of the flash memory word (or row address) which will be written to when the program sequence is executed. After loading the holding latch(es) the application sets the destination address inNVMADR/NVMADRU before initiating the write sequence. The write sequence causes the data to be copied from the latches into the flash memory location specified byNVMADR/NVMADRU.

NVMCON Non-Volatile Memory Control Register - The register through which the application selects the function to be performed when the program sequence is executed. The options in this register include Erase Page, Write Word, and Write Row.NVMCON also contains the bit to be written to start the write process (WR).

NVMKEY Non-Volatile Memory KeyRegister - To reduce the potential for flash to be modified by a spurious write toNVMCONWR cannot be set unless a specific sequence of data values are written toNVMKEY. This sequence is commonly referred to as the program sequence. Once the sequence is executedWR becomes 'write-able' for 2 instruction cycles.

Program (Unlock) Sequence

The program sequence for a 16-bit PIC® Microcontroller (MCU) is performed by writing specific values, in successive order, toNVMKEY. Writing 0x55, immediately followed by 0xAA, will unlockWR for two instruction cycles. IfWR is set within two instruction cycles of the programming sequence, the MCU will perform the flash self-write process.

Interrupts should be disabled during the write program sequence to prevent servicing an interrupt between the two write instructions.

The unlock sequence can be written in C so long as the compiler places the two write instructions in sequential order. The MPLAB® XC16 compiler provides the functionbuiltin-write-NVM to perform this program sequence. After executing the program sequence,builtin-write-NVM setsWR which initiates a flash write.

Using MPLAB® XC16 C Compiler

Using Assembly Language

Algorithm to Self-Program Flash Memory on a 16-bit PIC® MCU

The 16-bit PIC® MCU reference manual advises that a row or word in Flash program memory should not be programmed twice before being erased. Given this erase-before-programming mandate, the following application flow is commonly used:

1

Copy the Page To Be Updated Into Data Memory

  • Load the base address of the Flash memory page intoTBLPAG.
  • Using successiveTBLRDH andTBLRDL instructions, copy the contents of the Flash page to data RAM. Care should be taken when copying 24-bit wide Flash memory into the 16-bit wide data memory. One word of Flash memory requires two read instructions (TBLRDH andTBLRDL). These two read instructions will return a total of 32 bits of data.

Example of Reading a Page of Flash Memory

2

Update the Page In Data Memory

Pages can only be erased in their entirety. This means that updating even a single word of Flash memory requires the entire page to be read into Random Access Memory (RAM), erased in Flash, then reprogrammed. Unlike most Electrically Erasable Programmable Read-Only Memory (EEPROM) implementations, Flash memory words cannot be individually updated.

3

Erase the Page In Flash Memory

  • Load the base address of the page to be erased into the NVM address registersNVMADR andNVMADDRU. The base address is a modulo of the page size. For MCU's with a page size of 1024, the lowest 10 bits of the address for all page addresses will be '0'. Ensure that the value placed into NVMADR has the correct base address by masking off the appropriate number of lower bits.
  • Set the bits inNVMCON to enable writes and erase the page. The MCU in this example requires the value 0x4003 to setWREN and to erase a page. Check the datasheet for the bits to set inNVMCON of the MCU being used.
  • Disable interrupts for the duration of the write sequence.
  • Perform the program sequence.
  • EnsureWR is set within two instruction cycles of the completion of the programming sequence.__builtin_write_NVM issues the program sequence, then setsWR.

4

Program the New Data Into the Flash Memory

To write Flash, you must first consult the datasheet for the part you are using to determine the base address of the write latches. This information is typically listed in the memory map section rather than the Flash memory section of the datasheet. In this example, 0xFA000 is the base address of the write latches.

Writing a Row of Flash Data

  • SetTBLPAG with bits <11:8> of the base address of the write latches.
  • Using multipleTBLWRTH andTBLWRTL instructions move data from ram into the data latches.
  • LoadNVMADR andNVNADDRU with the base address of the Flash row to be written to.
  • Set the Write Enable (WREN) and the bits needed to write a row intoNVMCON.
  • Perform the program sequence.
  • SetWR within two cycles of completing the program sequence.