Skip to content

Commit

Permalink
Add Flash library
Browse files Browse the repository at this point in the history
Closes #131
  • Loading branch information
MCUdude committed Sep 11, 2021
1 parent 9b640e7 commit 0fb2446
Show file tree
Hide file tree
Showing 8 changed files with 606 additions and 0 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ If you're looking for a great development board for the ATtiny13, and DIP-8 ATti
- [Working Arduino functions and libraries](#working-arduino-functions-and-libraries)
- [Arduino functions](#arduino-functions)
- [Arduino libraries](#arduino-libraries)
- [Other libraries](#other-libraries)
- [Acknowledgements](#acknowledgements)


Expand Down Expand Up @@ -278,6 +279,16 @@ Due to the limited hardware not all default Arduino functions and libraries is s
- [get()](https://www.arduino.cc/en/Reference/EEPROMGet)
- [put()](https://www.arduino.cc/en/Reference/EEPROMPut)

### Other libraries
* [Flash library, **Flash.h**](https://github.com/MCUdude/MicroCore/tree/master/avr/libraries/Flash)
- [erase_page()](https://github.com/MCUdude/MicroCore/tree/master/avr/libraries/Flash/README.md#erase_page)
- [fill_page()](https://github.com/MCUdude/MicroCore/tree/master/avr/libraries/Flash/README.md#fill_page)
- [write_page()](https://github.com/MCUdude/MicroCore/tree/master/avr/libraries/Flash/README.md#write_page)
- [read()](https://github.com/MCUdude/MicroCore/tree/master/avr/libraries/Flash/README.md#read)
- [get_address()](https://github.com/MCUdude/MicroCore/tree/master/avr/libraries/Flash/README.md#get_address)
- [put()](https://github.com/MCUdude/MicroCore/tree/master/avr/libraries/Flash/README.md#put)
- [get()](https://github.com/MCUdude/MicroCore/tree/master/avr/libraries/Flash/README.md#get)

## Acknowledgements
MicroCore is based Smeezekitty's [core13](https://sourceforge.net/projects/ard-core13/), which is an Arduino ATtiny13 hardware package for IDE 1.0.x.
Expand Down
155 changes: 155 additions & 0 deletions avr/libraries/Flash/README.md
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 avr/libraries/Flash/examples/Flash_iterate/Flash_iterate.ino
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()
{

}
Loading

0 comments on commit 0fb2446

Please sign in to comment.