Flash Memory Library

This library provides routines for accessing microcontroller's (internal) Flash memory.

On the dsPIC30/33 and PIC24, Flash memory is mapped to address space 3:2, which means that every 3 consecutive bytes of Flash have 2 consecutive address locations available. That is why mikroE's library allows data to be written to flash in two ways: "regular" and "compact". In the "regular" mode, which is used for word(16-bit) variables, the 3rd (un-addressable) flash memory byte remains unused. In the "compact" mode, which can be used for 1 byte-sized variables/arrays, all flash bytes are being used.

All dsPIC30/33 and PIC24 MCUs use the RTSP module to perform Read/Erase/Write operations on Flash memory. This, together with the internal structure of the Flash, imposes certain rules to be followed when working with Flash memory:

dsPIC30:

PIC24 and dsPIC33:

24F04KA201 and 24F16KA102 Family Specifics :

Library Routines

dsPIC30 Functions

PIC24 and dsPIC33 Functions

dsPIC30 Functions

FLASH_Erase32

Prototype

sub procedure FLASH_Erase32(dim flash_address as longint)

Description

Erases one block (32 instructions, 64 addresses, 96 bytes)from the program FLASH memory.

Parameters
  • address: starting address of the FLASH memory block
Returns

Nothing.

Requires

Nothing.

Example
' erase the 32-instruction block, starting from address 0x006000
FLASH_Erase32(0x006000)
Notes

The user should take care about the address alignment (see the explanation at the beginning of this page).

FLASH_Write_Block

Prototype

sub procedure FLASH_Write_Block(dim flash_address as longint, dim data_address as word)

Description

Fills one writeable block of Flash memory (4 instructions, 8 addresses, 12 bytes) in the "regular" mode. Addresses and data are being mapped 1-on-1. This also means that 3rd byte of each program location remains unused.

Parameters
  • flash_address: starting address of the FLASH memory block
  • data_address: data to be written
Returns

Nothing.

Requires

The block to be written to must be erased first, either from the user code (through the RTSP), or during the programming of MCU. Please note that block size that is to be erased is different from the one that can be written with this function!

Example
dim flash_address as longint
    cArr          as string[4]
    ptr_data      as word
...
flash_address = 0x006000
cArr = "ABCD"
ptr_data = @cArr
FLASH_Write_Block(flash_address, ptr_data)
Notes

The user should take care about the address alignment (see the explanation at the beginning of this page).

FLASH_Write_Compact

Prototype

sub procedure FLASH_Write_Compact(dim flash_address as longint, dim data_address as word, dim bytes as word)

Description

Fills a portion of Flash memory using the dsPIC30 RTSP module, in the "compact" manner. In this way, several blocks of RTSP's latch can be written in one pass. One latch block contains 4 instructions (8 addresses, 12 bytes). Up to 8 latch blocks can be written in one round, resulting in a total of 8*12 = 96 bytes. This method uses all available bytes of the program FLASH memory, including those that are not mapped to address space (every 3rd byte).

Parameters
  • flash_address: starting address of the FLASH memory block
  • data_address: data to be written
  • bytes: number of bytes to be written. The amount of bytes to be written must be a multiply of 12, since this is the size of the RTSP's write latch(es).
Returns

Nothing.

Requires

The block to be written to must be erased first, either from the user code FLASH_Erase32, or during the programming of MCU. Please note that block size that is to be erased is different from the one that can be written with this function!

Example
dim flash_address as longint
    cArr          as string[36]
    ptr_data      as word
...
flash_address = 0x006000
cArr = "mikroElektronika12mikroElektronika34"
ptr_data = @cArr
FLASH_Write_Compact(flash_address, ptr_data, 36)
Notes

The user should take care about the address alignment (see the explanation at the beginning of this page).

FLASH_Write_Init

Prototype

sub procedure FLASH_Write_Init(dim flash_address as longint, dim data_address as word)

Description

Initializes RTSP for write-to-FLASH operation.

Parameters
  • flash_address: starting address of the FLASH memory block
  • data_address: data to be written
Returns

Nothing.

Requires

The block to be written to must be erased first, either from the user code FLASH_Erase32, or during the programming of MCU. Please note that block size that is to be erased is different from the one that can be written with this function!

Example
const iArr as word[8] = ("m", "i", "k", "r", "o", "E", "l", "e")
dim ptr_data as word
  ...
  ptr_data = @iArr
  FLASH_Write_Init(0x006100, ptr_data)
  FLASH_Write_Loadlatch4()
  FLASH_Write_Loadlatch4()
  FLASH_Write_DoWrite()
Notes

The user should take care about the address alignment (see the explanation at the beginning of this page).

FLASH_Write_Loadlatch4

Prototype

sub procedure FLASH_Write_Loadlatch4()

Description

Loads the current RTSP write latch with data (4 instructions, 8 addresses, 12 bytes). The data is filled in the "regular" mode.

Parameters

None.

Returns

Nothing.

Requires

The block to be written to must be erased first, either from the user code FLASH_Erase32, or during the programming of MCU. Please note that block size that is to be erased is different from the one that can be written with this function!

This function is used as a part of the Flash write sequence, therefore the FLASH_Write_Init function must be called before this one.

This function can be called several times before commiting the actual write-to-Flash operation FLASH_Write_DoWrite. This depends on the organization of the RTSP module for the certain dsPIC30. Please consult the Datasheet for particular dsPIC30 on this subject.

Example
const  iArr  as word[8] = ("m", "i", "k", "r", "o", "E", "l", "e")
dim ptr_data as word
  ...
  ptr_data = @iArr
  FLASH_Write_Init(0x006100, ptr_data)
  FLASH_Write_Loadlatch4()
  FLASH_Write_Loadlatch4()
  FLASH_Write_DoWrite()
Notes

None.

FLASH_Write_Loadlatch4_Compact

Prototype

sub procedure FLASH_Write_Loadlatch4_Compact()

Description

Loads the current RTSP write latch with data (4 instructions, 8 addresses, 12 bytes). The data is filled in the "compact" mode.

Parameters

None.

Returns

Nothing.

Requires

The block to be written to must be erased first, either from the user code FLASH_Erase32, or during the programming of MCU. Please note that block size that is to be erased is different from the one that can be written with this function!

This function is used as a part of the Flash write sequence, therefore the FLASH_Write_Init function must be called before this one.

This function can be called several times before committing actual write-to-Flash operation FLASH_Write_DoWrite. This depends on the organization of the RTSP module for the certain dsPIC30. Please consult the Datasheet for particular dsPIC30 on this subject.

Example
const  iArr  as word[8] = ("m", "i", "k", "r", "o", "E", "l", "e")
dim ptr_data as word
  ...
  ptr_data = @iArr
  FLASH_Write_Init(0x006100, ptr_data)
  FLASH_Write_Loadlatch4_Compact()
  FLASH_Write_Loadlatch4_Compact() 	
  FLASH_Write_DoWrite()
Notes

None.

FLASH_Write_DoWrite

Prototype

sub procedure FLASH_Write_DoWrite()

Description

Commits the FLASH write operation.

Parameters

None.

Returns

Nothing.

Requires

The block to be written to must be erased first, either from the user code FLASH_Erase32, or during the programming of MCU. Please note that block size that is to be erased is different from the one that can be written with this function!

This function is used as a part of the Flash write sequence, therefore FLASH_Write_Init and certain number of FLASH_Write_Loadlatch4 or FLASH_Write_Loadlatch4_Compact function calls must be made before this one.

This function is to be called once, at the and of the FLASH write sequence.

Example
const  iArr  as word[8] = ("m", "i", "k", "r", "o", "E", "l", "e")
dim ptr_data as word
  ...
  ptr_data = @iArr
  FLASH_Write_Init(0x006100, ptr_data)
  FLASH_Write_Loadlatch4()
  FLASH_Write_Loadlatch4()
  FLASH_Write_DoWrite()
Notes

None.

FLASH_Read4

Prototype

sub procedure FLASH_Read4(dim flash_address as longint, dim write_to as word)

Description

Reads one latch row (4 instructions, 8 addresses) in the "regular" mode.

Parameters
  • address: starting address of the FLASH memory block to be read
  • write_to: starting address of RAM buffer for storing read data
Returns

Starting address of RAM buffer for storing read data.

Requires

Nothing.

Example
dim flash_address as longint
    cArr          as word[4]
    ptr_data      as word
...
flash_address = 0x006000
ptr_data = @cArr
FLASH_Read4(flash_address, ptr_data)
Notes

The user should take care of the address alignment (see the explanation at the beginning of this page).

FLASH_Read4_Compact

Prototype

sub procedure FLASH_Read4_Compact(dim flash_address as longint, dim write_to as word)

Description

Reads one latch row (4 instructions, 8 addresses) in the "compact" mode.

Parameters
  • address: starting address of the FLASH memory block to be read
  • write_to: starting address of RAM buffer for storing read data
Returns

Starting address of RAM buffer for storing read data.

Requires

Nothing.

Example
dim flash_address as longint
    cArr          as word[8]
    ptr_data      as word
...
flash_address = 0x006000
ptr_data = @cArr
FLASH_Read4_Compact(flash_address, ptr_data)
Notes

The user should take care of the address alignment (see the explanation at the beginning of this page).

PIC24 and dsPIC33 Functions

FLASH_Erase

Prototype

sub procedure FLASH_Erase(dim address as longint)

Description

Erases one block (512 instructions, 1024 addresses, 1536 bytes) from the program FLASH memory.

Parameters
  • address: starting address of the FLASH memory block
Returns

Nothing.

Requires

Nothing.

Example
'--- erase the flash memory block, starting from address 0x006400
dim flash_address as longint
...
flash_address = 0x006400
FLASH_Erase(flash_address)
Notes

The user should take care about the address alignment (see the explanation at the beginning of this page).

FLASH_Write

Prototype

sub procedure FLASH_Write(dim address as longint, dim byref data_ as word[64])

Description

Fills one writeable block of Flash memory (64 instructions, 128 addresses, 192 bytes) in the "regular" mode. Addresses and data are being mapped 1-on-1. This also means that 3rd byte of each program location remains unused.

Parameters
  • address: starting address of the FLASH memory block
  • data_: data to be written
Returns

Nothing.

Requires

The block to be written to must be erased first, either from the user code (through the RTSP), or during the programming of MCU. Please note that block size that is to be erased is different from the one that can be written with this function!

Example
dim data_ as word[64] = {"m", "i", "k", "r", "o", "E", "l", "e", "k", "t", "r", "o", "n", "i", "k", "a"}
...

FLASH_Write(0x006500, data_)
Notes

The user should take care about the address alignment (see the explanation at the beginning of this page).

FLASH_Write_Compact

Prototype

sub procedure FLASH_Write_Compact(dim address as longint, dim byref data_ as byte[192])

Description

Fills a portion of Flash memory (64 instructions, 128 addresses, 192 bytes) using the dsPIC33 and PIC24s RTSP (Run Time Self Programming) module, in the "compact" manner. This method uses all available bytes of the program FLASH memory, including those that are not mapped to address space (every 3rd byte).

Parameters
  • address: starting address of the FLASH memory block
  • data_: data to be written
Returns

Nothing.

Requires

The block to be written to must be erased first, either from the user code (FLASH_Erase), or during the programming of MCU. Please note that block size that is to be erased is different from the one that can be written with this function!

Example
dim data_ as string[192]
...
data_ = "supercalifragillisticexpialidotiousABCDEFGHIJKLMNOPRSTUVWXYZ1234"

FLASH_Write_Compact(0x006400, data_)
Notes

The user should take care of the address alignment (see the explanation at the beginning of this page).

FLASH_Read

Prototype

sub procedure FLASH_Read(dim address as longint, dim byref write_to as word[100], dim NoWords as word)

Description

Reads required number of words from the flash memory in the "regular" mode.

Parameters
  • address: starting address of the FLASH memory block to be read
  • write_to: starting address of RAM buffer for storing read data
  • NoWords: number of words to be read
Returns

Address of RAM buffer for storing read data.

Requires
Example
dim Buffer as word[10]
    start_address as longint
...
FLASH_Write(0x006500, data)
start_address = 0x6500
FLASH_Read(start_address, Buffer, 10)
Notes

The user should take care of the address alignment (see the explanation at the beginning of this page).

FLASH_Read_Compact

Prototype

sub procedure FLASH_Read_Compact(dim address as longint, dim byref write_to as byte[100], dim NoBytes as word)

Description

Reads required number of bytes from the flash memory in the "compact" mode.

Parameters
  • address: starting address of the FLASH memory block to be read
  • write_to: starting address of RAM buffer for storing read data
  • NoBytes: number of bytes to be read
Returns

Address of RAM buffer for storing read data.

Requires
Example
dim Buffer as byte[10]
    start_address as longint
...
FLASH_Write(0x006500, data)
start_address = 0x6500
FLASH_Read(start_address, Buffer, 10)
Notes

The user should take care of the address alignment (see the explanation at the beginning of this page).

Library Example

In this example written for dsPIC30F4013, various read/write tecniques to/from the on-chip FLASH memory are shown. Flash memory is mapped to address space 3:2, meaning every 3 consecutive bytes of Flash have 2 consecutive address locations available.
That is why mikroE's library allows data to be written to Flash in two ways: 'regular' and 'compact'. In 'regular' mode, which is used for variables that are size of 2 bytes and more, the 3rd (un-addressable) byte remains unused.
In 'compact' mode, which can be used for 1 byte-sized variables/arrays, all bytes of flash are being used.

Copy Code To ClipboardCopy Code To Clipboard
program Flash_Test
dim WriteWordArr  as word[8]
    WriteByteArr  as byte[32]
    ReadByteArr as byte[40]
    RealongwordArr as word[20]

    pw as ^word
    pb as ^byte
    i as word
    temp_byte as byte
main:
  ' Initialize arrays
  WriteWordArr[0] = "*"  WriteWordArr[1] = "m"  WriteWordArr[2] = "i"  WriteWordArr[3] = "k"
  WriteWordArr[4] = "r"  WriteWordArr[5] = "o"  WriteWordArr[6] = "E"  WriteWordArr[7] = "*"

  WriteByteArr[0]  = "m"  WriteByteArr[1]  = "i"  WriteByteArr[2]  = "k"  WriteByteArr[3] = "r"
  WriteByteArr[4]  = "o"  WriteByteArr[5]  = "E"  WriteByteArr[6]  = "l"  WriteByteArr[7] = "e"
  WriteByteArr[8]  = "k"  WriteByteArr[9]  = "t"  WriteByteArr[10] = "r"  WriteByteArr[11] = "o"
  WriteByteArr[12] = "n"  WriteByteArr[13] = "i"  WriteByteArr[14] = "k"  WriteByteArr[15] = "a"
  WriteByteArr[16] = " "  WriteByteArr[17] = "F"  WriteByteArr[18] = "l"  WriteByteArr[19] = "a"
  WriteByteArr[20] = "s"  WriteByteArr[21] = "h"  WriteByteArr[22] = " "  WriteByteArr[23] = "e"
  WriteByteArr[24] = "x"  WriteByteArr[25] = "a"  WriteByteArr[26] = "m"  WriteByteArr[27] = "p"
  WriteByteArr[28] = "l"  WriteByteArr[29] = "e"  WriteByteArr[30] = "."  WriteByteArr[31] = 0


  pb = @WriteByteArr
  '--- erase the block first
  FLASH_Erase32(0x006000)

  pb = @WriteByteArr[0]
  FLASH_Write_Compact(0x006000, pb, 36)
  (*
  This is what FLASH_Write_Compact() does "beneath the hood"
  *
  FLASH_Write_Init(0x006000, pv1)
  FLASH_Write_Loadlatch4_Compact()
  FLASH_Write_Loadlatch4_Compact()
  FLASH_Write_Loadlatch4_Compact()
  FLASH_Write_DoWrite()
  *)


  '--- read compact format
  pb = @ReadByteArr
  FLASH_Read4_Compact(0x006000, pb)
  pb = pb + 12
  FLASH_Read4_Compact(0x006008, pb)
  pb = pb + 12
  FLASH_Read4_Compact(0x006010, pb)
  pb = pb + 12
  pb^ = 0   'termination

  UART1_Init(9600)
  UART1_Write(10)
  UART1_Write(13)
  UART1_Write_Text("Start")
  UART1_Write(10)
  UART1_Write(13)
  i = 0
  while(ReadByteArr[i])
    temp_byte = ReadByteArr[i]
    UART1_Write(temp_byte)
    Inc(i)
  wend

  '--- now for some non-compact flash-write
  pw = @WriteWordArr
  '--- erase the block first
  FLASH_Erase32(0x006100)
  FLASH_Write_Init(0x006100, pw)
  FLASH_Write_Loadlatch4()
  FLASH_Write_Loadlatch4()
  FLASH_Write_DoWrite()

  '--- read non-compact format
  pw = @RealongwordArr[0]
  FLASH_Read4(0x006100, pw)
  pw = pw + 4
  FLASH_Read4(0x006108, pw)
  pw = pw + 4
  pw^ = 0   'termination

  '--- show what has been written
  UART1_Write(10)
  UART1_Write(13)
  i = 0
  while(RealongwordArr[i]<>0)
    temp_byte = RealongwordArr[i]
    UART1_Write(temp_byte)
    i = i + 1
  wend

end.
Copyright (c) 2002-2012 mikroElektronika. All rights reserved.
What do you think about this topic ? Send us feedback!
Want more examples and libraries? 
Find them on LibStock - A place for the code