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:
- Erasing can be done only in 32-instructions (64 addresses, 96 bytes) memory
blocks. This means that the block start address should be a multiply of 64 (i.e.
have 6 lower bits set to zero).
- Data is read and written in 4-instructions (8 addresses, 12 bytes)
blocks.This means that the block start address should be a multiply of 8 (i.e.
have 3 lower bits set to zero).
- On the dsPIC30s, 2 address locations are assigned on every 3 bytes of
(flash) program memory. Due to this specific and non-one-to-one address mapping,
the mikroC PRO for dsPIC30/33 and PIC24 offers two sets of Flash handling
functions: "regular" and "compact".
Using the "regular" set, the user can
write one byte of data to a single address, which means that each byte of
written data has its own address, but on every 2 written bytes one byte of Flash
memory remains empty.
Using the "compact" set, every byte of Flash memory,
including those non-addressable, is filled with data; this method can only be
used for data organized in bytes.
The "compact" functions have
_Compact
as name suffix.
- For run-time FLASH read/write, the dsPIC30's RTSP module is being used. It
organizes data into rows and panels. Each row contains write latches that can
hold 4 instructions (12 bytes). The number of panels varies from one dsPIC30 MCU
model to another. Because of that, the flash write sequence has been split into
several operations (
_Write_Init(), _Write_LoadLatch4(),
_Write_DoWrite()
), in order to be usable on all dsPICs.
PIC24 and dsPIC33:
- Erasing can be done only in 512-instructions (1024 addresses, 1536 bytes)
memory blocks, which means that the block start address should be a multiply of
1024 (i.e. have 10 lower bits set to zero).
- Data is read and written in 64-instructions (128 addresses, 192 bytes)
blocks.This means that the block start address should be a multiply of 128 (i.e.
have 7 lower bits set to zero).
- On the dsPIC33 and PIC24s, 2 address locations are assigned on every 3 bytes
of (flash) program memory. Due to this specific and non-one-to-one address
mapping, the mikroC PRO for dsPIC30/33 and PIC24 offers two sets of Flash
handling functions: "regular" and "compact".
Using the "regular" set, the
user can write one byte of data to a single address, which means that each byte
of written data has its own address, but on every 2 written bytes one byte of
Flash memory remains empty.
Using the "compact" set, every byte of Flash
memory, including those non-addressable, is filled with data; this method can
only be used for data organized in bytes.
The "compact" functions have
_Compact
as name suffix.
24F04KA201 and 24F16KA102 Family Specifics :
- These MCU's have their Flash memory organized into memory blocks of 32
instructions (96 bytes), unlike other PIC24 devices.
- Erasing can be done only in 32-instructions (64 addresses, 96 bytes) memory
blocks, which means that the block start address should be a multiply of 64
(i.e. have 6 lower bits set to zero).
- Data is read and written in 32-instructions (64 addresses, 96 bytes) blocks.
This means that the block start address should be a multiply of 64 (i.e. have 6
lower bits set to zero).
- Unlike other PIC24 devices, writing or erasing one block of data (32
instructions), is followed by erasing the memory block of the same size (32
instructions).
Library Routines
dsPIC30 Functions
PIC24 and dsPIC33 Functions
dsPIC30 Functions
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_Block
Prototype |
void FLASH_Write_Block(unsigned long address, unsigned
int *data_); |
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 |
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 |
void FLASH_Write_Compact(unsigned long address, void
*data_, unsigned bytes); |
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 |
address: starting address of the FLASH memory block
data_: 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 |
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). |
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);
|
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 "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 |
//--- 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. |
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_Read4
Prototype |
unsigned int* FLASH_Read4(unsigned long address, unsigned
int *write_to); |
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 |
//--- 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. |
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). |
PIC24 and dsPIC33 Functions
FLASH_Erase
Prototype |
void FLASH_Erase(unsigned long address); |
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
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). |
FLASH_Write
Prototype |
void FLASH_Write(unsigned long address, unsigned int
*data_); |
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 |
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). |
FLASH_Write_Compact
Prototype |
void FLASH_Write_Compact(unsigned long address, char
*data_); |
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 |
char cArr[] = "supercalifragillisticexpialidotiousABCDEFGHIJKLMNOPRSTUVWXYZ1234";
void * pv1;
...
pv1 = cArr;
FLASH_Write_Compact(0x006400, pv1);
|
Notes |
The user should take care of the address alignment (see the explanation at
the beginning of this page). |
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 "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 |
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. |
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 |
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). |
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.
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();
}
No comments:
Post a Comment