-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Closes #131
- Loading branch information
Showing
8 changed files
with
606 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
# Flash | ||
A light-weight library that lets you read and write to the internal flash memory without using a RAM buffer. | ||
Developed by [MCUdude](https://github.com/MCUdude/). | ||
|
||
The flash library is a semi high level library that utilizes AVR Libc's [boot.h](https://www.nongnu.org/avr-libc/user-manual/group__avr__boot.html). It is page oriented, which means that you'll have to write an entire page to flash at once. The ATtiny13 's flash pages is 32 bytes large. | ||
|
||
## flash_space | ||
Static constant pointer that has to point to the allocated flash space in the user program. | ||
This tells the library where the allocated flash space is. | ||
|
||
### Usage | ||
```c++ | ||
// Number of flash pages to allocated for read/write | ||
#define NUMBER_OF_PAGES 2 | ||
|
||
// Allocated flash space | ||
const uint8_t flashSpace[SPM_PAGESIZE * NUMBER_OF_PAGES] __attribute__((aligned(SPM_PAGESIZE))) PROGMEM = {}; | ||
|
||
// Pass allocated space pointer to Flash library | ||
const uint8_t *Flash::flash_space = flashSpace; | ||
``` | ||
|
||
|
||
## erase_page() | ||
Static function that erases a flash page. | ||
|
||
### Declaration | ||
```c++ | ||
static void erase_page(uint8_t page_number); | ||
``` | ||
### Returns | ||
`void` | ||
### Usage | ||
```c++ | ||
// Erase allocated flash page 0 | ||
flash.erase_page(0); | ||
``` | ||
|
||
|
||
## fill_page() | ||
Static function that is used to fill the flash page buffer. This buffer "lives" within the flash controller itself, and does not accupy any RAM. this buffer can only be written to, and the function handles the address increments automatically. Note that the buffer doesn't have to be full to write it to flash. | ||
|
||
### Declaration | ||
```c++ | ||
static bool fill_page(uint8_t page_number, uint8_t data); | ||
``` | ||
### Returns | ||
`true` if the buffer is full (32 bytes written).</br> | ||
`false` if buffer is not full. | ||
### Usage | ||
```c++ | ||
// Write 0x55 to the next byte in the buffer on page 0 | ||
flash.fill_page(0, 0x55); | ||
``` | ||
|
||
|
||
## write_page() | ||
Writes the flash buffer content to a flash page. | ||
|
||
### Declaration | ||
```c++ | ||
static void write_page(uint8_t page_number); | ||
``` | ||
### Returns | ||
`void` | ||
### Usage | ||
```c++ | ||
// Write to flash page 0 | ||
flash.write_page(0); | ||
``` | ||
|
||
|
||
## read() | ||
Reads a byte from flash. | ||
|
||
### Declaration | ||
```c++ | ||
static uint8_t read(uint8_t page_number, uint8_t address); | ||
``` | ||
### Returns | ||
`uint8_t` byte stored in flash. | ||
### Usage | ||
```c++ | ||
// Read a byte from flash page 0, address 1 | ||
uint8_t byte_from_flash = flash.read(0, 1); | ||
``` | ||
|
||
|
||
## get_address() | ||
Returns the physical flash memory address for a particular byte in flash | ||
|
||
### Declaration | ||
```c++ | ||
static uint16_t get_address(uint8_t page_number, uint8_t address); | ||
``` | ||
### Returns | ||
`uint16_t` 16-bit memory address. | ||
### Usage | ||
```c++ | ||
// Get the physical flash memory address from data located at page 0, address 1 | ||
uint16_t flash_memory_address = flash.get_address(0, 1); | ||
``` | ||
|
||
|
||
## put() | ||
Write any data type or object to flash. This template function is a wrapper around fill_page(), and handles address increments automatically. | ||
|
||
### Declaration | ||
```c++ | ||
template <typename T> static const uint8_t &put(uint8_t page_number, const T &t); | ||
``` | ||
### Returns | ||
`const uint8_t` number of bytes currently in the flash buffer. | ||
### Usage | ||
```c++ | ||
// Write a string starting flash page 0, and then write the number to the same page | ||
char my_str[] = "Hello World!"; | ||
uint16_t number = 12345; | ||
flash.put(0, my_str); | ||
flash.put(0, data); | ||
``` | ||
|
||
|
||
## get() | ||
Read any data type or object from flash. | ||
|
||
### Declaration | ||
```c++ | ||
template <typename T> static T &get(uint8_t page_number, uint8_t page_address, T &t) | ||
``` | ||
### Returns | ||
`T` value stored to passed variable. | ||
### Usage | ||
```c++ | ||
// Read a string from flash page 0 starting from address 0, and read the number afterwards | ||
char my_str[13]; | ||
uint16_t number; | ||
flash.get(0, 0, my_str); | ||
flash.get(0, sizeof(my_str), number); | ||
``` |
103 changes: 103 additions & 0 deletions
103
avr/libraries/Flash/examples/Flash_iterate/Flash_iterate.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/***********************************************************************| | ||
| Flash read/write library for ATtiny13 | | ||
| | | ||
| Flash_iterate.ino | | ||
| | | ||
| A light-weight library that lets you read and write to the internal | | ||
| flash memory without using a RAM buffer. | | ||
| Developed by MCUdude, based on the AVR Libc boot.h | | ||
| https://github.com/MCUdude/MicroCore | | ||
| | | ||
| In this example we fill a flash page with 16-bit and read it back | | ||
| togeher with its physical flash address after a reboot. | | ||
| | | ||
| SERIAL REMINDER | | ||
| The baud rate is ignored on the ATtiny13 due to using a simplified | | ||
| serial. The baud rate used is dependent on the processor speed. | | ||
| Note that you can specify a custom baud rate if the following ones | | ||
| does not fit your application. | | ||
| | | ||
| THESE CLOCKS USES 115200 BAUD: THIS CLOCK USES 57600 BAUD: | | ||
| 20 MHz, 16 MHz, 9.6 MHz, 8 MHz 4.8 MHz | | ||
| THESE CLOCKS USES 19200 BAUD: THIS CLOCK USES 9600 BAUD: | | ||
| 1.2 MHz, 1 MHz 600 KHz | | ||
| | | ||
| If you get garbage output: | | ||
| 1. Check baud rate as above | | ||
| 2. Check if you have anything else connected to TX/RX like an LED | | ||
| 3. Check OSCCAL (see MicroCore OSCCAL tuner example) | | ||
|***********************************************************************/ | ||
|
||
#include <Flash.h> | ||
|
||
// Number of flash pages to allocated for read/write | ||
#define NUMBER_OF_PAGES 1 | ||
|
||
// Allocated flash space | ||
const uint8_t flashSpace[SPM_PAGESIZE * NUMBER_OF_PAGES] __attribute__((aligned(SPM_PAGESIZE))) PROGMEM = {}; | ||
|
||
// Pass allocated space pointer to Flash library | ||
const uint8_t *Flash::flash_space = flashSpace; | ||
|
||
void write_data() | ||
{ | ||
Serial.print(F("Writing...\n")); | ||
|
||
// Erase page 0 | ||
flash.erase_page(0); | ||
|
||
// Fill the page buffer with the alfabet | ||
for(uint16_t i = 0xF000; i < 0xF100; i+= 0x10) | ||
{ | ||
flash.put(0, i); | ||
|
||
// Alternatively, fill_page can be used instead | ||
//flash.fill_page(0, (uint8_t)i & 0xFF); | ||
//flash.fill_page(0, (uint8_t)(i >> 8)); | ||
} | ||
|
||
// Write the page buffer to flash | ||
flash.write_page(0); | ||
|
||
// Reset the microcontroller to check for new content in flash | ||
Serial.print(F("Done! Please reset...")); | ||
} | ||
|
||
void read_data() | ||
{ | ||
Serial.print(F("Reading...\n")); | ||
|
||
|
||
for(uint8_t i = 0; i < SPM_PAGESIZE; i+=2) | ||
{ | ||
uint16_t data; | ||
flash.get(0, i, data); | ||
Serial.print(F("Flash addr: 0x")); | ||
Serial.print(flash.get_address(0, i), HEX); | ||
Serial.print(F(", data = 0x")); | ||
Serial.print(data, HEX); | ||
Serial.print(F("\n")); | ||
} | ||
} | ||
|
||
void setup() | ||
{ | ||
Serial.begin(); | ||
|
||
// Check for content by reading the first byte on page 0 | ||
uint16_t data_present; | ||
flash.get(0, 0, data_present); | ||
|
||
// No data present - write new data | ||
if(data_present != 0xF000) | ||
write_data(); | ||
|
||
// Data present - read from flash | ||
else | ||
read_data(); | ||
} | ||
|
||
void loop() | ||
{ | ||
|
||
} |
Oops, something went wrong.