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: "common" and "compact". In the "common" 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:

Library Routines

FLASH_Erase

Prototype

void FLASH_Erase(unsigned long address);

Description

Erases one block (512/1024 instructions, 1024/2048 addresses, 1536/3072 bytes) or row (32 instructions, 64 addresses, 96 bytes) from the program FLASH memory.

Parameters
  • address: starting address of the FLASH memory block/row.
Returns

Nothing.

Requires

Nothing.

Example
//--- erase the flash memory block, starting from address 0x006400
unsigned long 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).
  • Depending on the chosen MCU, the block/row size may vary. Please refer to the appropriate datasheet.

FLASH_Erase32

Prototype

void FLASH_Erase32(unsigned long address);

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

Prototype

void FLASH_Write(unsigned long address, unsigned int * data_);

Description

Fills one writeable block of Flash memory in the "common" mode. Addresses and data are being mapped 1-on-1. This means that 3rd byte of each program location remains unaffected.

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
unsigned int iArr[64] = {'m', 'i', 'k', 'r', 'o', 'E', 'l', 'e', 'k', 't', 'r', 'o', 'n', 'i', 'k', 'a'};
void * pv1;
...
pv1 = iArr;
FLASH_Write(0x006500, pv1);
Notes
  • The user should take care about the address alignment (see the explanation at the beginning of this page).
  • Depending on the chosen MCU, the block/row size may vary. Please refer to the appropriate datasheet.

FLASH_Write_Block

Prototype

void FLASH_Write_Block(unsigned long flash_address, unsigned int *data_);

Description

Fills one writeable block of Flash memory (4 instructions, 8 addresses, 12 bytes) in the "common" 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_: 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
unsigned long flash_address = 0x006000;
unsigned int Buffer[4] = {'A', 'B', 'C', 'D'};
...
FLASH_Write_Block(flash_address, Buffer);
Notes

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

FLASH_Write_Compact

Prototype // dsPIC30 :

void FLASH_Write_Compact(unsigned long address, void * data_, unsigned bytes);

// dsPIC33 and PIC24 :

void FLASH_Write_Compact(unsigned long address, char * data_);

Description

dsPIC30

  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).

dsPIC33 and PIC24

  Fills one writeable block (32/64/128 instructions, 64/128/256 addresses, 96/192/384 bytes) or row (32 instructions, 64 addresses, 96 bytes) in "compact" mode.
  "Compact" means that all 3 bytes that exist on 2 consecutive addresses (1 even, 1 odd) are being used-up.

Parameters

dsPIC30

  • 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).

dsPIC33 and PIC24

  • 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

dsPIC30

char cArr[] = "supercalifragillisticexpialidotiousABCDEFGHIJKLMNOPRSTUVWXYZ1234";
void * pv1;
...
pv1 = cArr;
FLASH_Write_Compact(0x006400, pv1);

dsPIC33 and PIC24

unsigned long flash_address = 0x006000;
char Buffer[] = "supercalifragillisticexpialidotious";
...
FLASH_Write_Compact(flash_address, Buffer, 36);
Notes
  • The user should take care about the address alignment (see the explanation at the beginning of this page).
  • Depending on the chosen MCU, the block/row size may vary. Please refer to the appropriate datasheet.

FLASH_WriteDoubleWord

Prototype

void FLASH_WriteDoubleWord(unsigned long address, unsigned long * data_)

Description

Writes two instructions (6 bytes) of Flash memory in the "compact" mode. "Compact" means that all 3 bytes that exist on 2 consecutive addresses (1 even, 1 odd) are being used-up.

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

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

FLASH_Write_Init

Prototype

void FLASH_Write_Init(unsigned long address, void *data_);

Description

Initializes RTSP for write-to-FLASH operation.

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_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
//--- Initializes the Flash to be written, starting from address 0x006100, the data is located at *pv1
void *pv1;
...
FLASH_Write_Init(0x006100, pv1);
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

void FLASH_Write_Loadlatch4();

Description

Loads the current RTSP write latch with data (4 instructions, 8 addresses, 12 bytes). The data is filled in the "common" 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
//--- writes data from an array, in "regular" manner
unsigned int iArr[16] = {'m', 'i', 'k', 'r', 'o', 'E', 'l', 'e', 'k'};
void * pv1;
...
pv1 = iArr;
FLASH_Write_Init(0x006100, pv1);
FLASH_Write_Loadlatch4();
FLASH_Write_Loadlatch4();
FLASH_Write_DoWrite();
Notes

None.

FLASH_Write_Loadlatch4_Compact

Prototype

void 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. "Compact" means that all 3 bytes that exist on 2 consecutive addresses (1 even, 1 odd) are being used-up.

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
//--- writes data from an array of char, in "compact" manner
char cArr[] = "supercalifragillisticexpialidotious"; //35+1 bytes
void * pv1;
...
pv1 = cArr;
FLASH_Write_Init(0x006000, pv1);                     //init
FLASH_Write_Loadlatch4_Compact();                    //12 bytes
FLASH_Write_Loadlatch4_Compact();                    //12 bytes
FLASH_Write_Loadlatch4_Compact();                    //12 bytes
FLASH_Write_DoWrite();                               //commit write
	
Notes

None.

FLASH_Write_DoWrite

Prototype

void 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
//--- writes data from an array, in "regular" manner
unsigned int iArr[16] = {'m', 'i', 'k', 'r', 'o', 'E', 'l', 'e', 'k'};
void * pv1;
...
pv1 = iArr;
FLASH_Write_Init(0x006100, pv1);
FLASH_Write_Loadlatch4();
FLASH_Write_Loadlatch4();
FLASH_Write_DoWrite();
Notes

None.

FLASH_Read

Prototype

unsigned int* FLASH_Read(unsigned long address, unsigned int *write_to, unsigned NoWords);

Description

Reads required number of words from the Flash memory in the "common" 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
unsigned Buffer[64];
unsigned long 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

void *FLASH_Read_Compact(unsigned long address, void *write_to, unsigned NoBytes);

Description

Reads required number of bytes from the flash memory in the "compact" mode. "Compact" means that all 3 bytes that exist on 2 consecutive addresses (1 even, 1 odd) are being used-up.

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

Nothing.

Example
char Buffer[64];
unsigned long start_address = 0x6500;
...
FLASH_Read_Compact(start_address, Buffer, 10);
Notes

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

FLASH_ReadDoubleWord

Prototype

unsigned long * FLASH_ReadDoubleWord(unsigned long address, unsigned long * write_to);

Description

Reads two instructions (6 bytes) from Flash memory in the "compact" mode. "Compact" means that all 3 bytes that exist on 2 consecutive addresses (1 even, 1 odd) are being used-up.

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
Example

Notes

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

FLASH_Read4

Prototype

unsigned int* FLASH_Read4(unsigned long address, unsigned int *write_to);

Description

Reads one latch row (4 instructions, 8 addresses) in the "common" 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
//--- reads 8 bytes (4 words) from location 0x006000 and stores it to *pv1;
unsigned int *pv1;
...
FLASH_Read4(0x006000, pv1);
Notes

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

FLASH_Read4_Compact

Prototype

void* FLASH_Read4_Compact(unsigned long address, void *write_to);

Description

Reads one latch row (4 instructions, 8 addresses) in the "compact" mode. "Compact" means that all 3 bytes that exist on 2 consecutive addresses (1 even, 1 odd) are being used-up.

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
//--- reads 12 bytes (4 words) from location 0x006000 and stores it to *pv1;
unsigned int *pv1;
...
FLASH_Read4_Compact(0x006000, pv1);
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
unsigned int iArr[8] = {'m', 'i', 'k', 'r', 'o', 'E', 'l', 'e'};
char cArr[] = "mikroElektronika Flash example";
char cArr2[40];

void * pv1;
unsigned bb;

void main() {
  unsigned i;

  pv1 = cArr;

/*
  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();
 */

  //--- erase the block first
  FLASH_Erase32(0x006000);

  //--- write compact format to flash
  FLASH_Write_Compact(0x006000, pv1, 36);

  //--- read compact format
  pv1 = cArr2;
  FLASH_Read4_Compact(0x006000, pv1);
  pv1 += 12;
  FLASH_Read4_Compact(0x006008, pv1);
  pv1 += 12;
  FLASH_Read4_Compact(0x006010, pv1);
  pv1 += 12;
  *pv1 = 0;  //termination
  
  //--- show what has been written
  i = 0;
  UART1_Init(9600);
//  UART1_Write_Text("Start");
  UART1_Write(10);
  UART1_Write(13);
  while(cArr2[i]) {
    bb = cArr2[i++];
    UART1_Write(bb);
  }

  //--- now for some non-compact flash-write
  pv1 = iArr;
  //--- erase the block first
  FLASH_Erase32(0x006100);
  FLASH_Write_Init(0x006100, pv1);
  FLASH_Write_Loadlatch4();
  FLASH_Write_Loadlatch4();
  FLASH_Write_DoWrite();
}
Copyright (c) 2002-2018 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