RSS

Atmega: Reading and Writing to Flash Memory during Runtime

There may be a day when you are plodding along, doing stuff on your Atmega micro controller when suddenly, you realise that you suddenly are in need of a way to store some data persistently. EEPROM isn’t big enough, so what can you do? How about utilising left over flash/program memory?!

There exist tutorials already on how to utilise flash memory for static data structures (such as large static arrays), so I’ll just focus on reading and writing to flash on runtime. I’m also NOT writing a tutorial on writing a bootloader either.

So without further ado, I present a basic rundown on reading and writing to flash during runtime!

The functionality is based around the “boot.h” library FOUND HERE!
My example is based on the Atmega168, so all code will be tailored to that chip.
Code was developed in Atmel studio 6.

Once you have created your project for your particular micro controller and have successfully connected to the chip with your programmer (AVR ISP MKII, AVR Dragon etc…), we need to reprogram a few fuses on the Atmega.

Heading into the datasheet for your device, we need to find the boot loader parameters (the BOOTSZn bits).
For my Atmega168, the relevant information is on page 282, Table 27-9 (under the boot loader support section).

Page 282, datasheet.

Page 282, datasheet.

The code being stored in the bootloader section is less than 128 words, so we can go ahead and set the BOOTSZ fuses to 1 1.

Final fuse settings for device

Final fuse settings for device

However, that’s not all. We need to tell the compiler where the bootloader section starts so it knows where to place our flash memory writing function.

We can do this by right clicking your project in the “solution explorer” and clicking “properties”.

Opening Properties

Setting Compiler Flash Settings

  1. Select “All Configurations” from Configurations
  2. Click “Memory Settings” under AVR/GNU Linker
  3. Click the green plus for the FLASH segment
  4. Type “.bootloader=[start address of your bootloader section as defined by your fuse selection]”
  5. Hit OK
  6. Save

Cool! Now we are all ready for the code!

First up we have “FlashMem.h”. This is simply function definitions. Something to note is the “__attribute__” line is what tells the compiler that that particular function should be placed in the .bootloader section of memory.


#ifndef FLASHMEM_H_
#define FLASHMEM_H_

#include <avr/io.h>
#include <avr/boot.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

/* Main writing method for flash memory. Takes in an address and
a pointer to a buffer. Function stored in the bootloader section
of memory to enable proper functionality (NRWW mem section).
If the buffer is greater than SPM_PAGESIZE, the remainder data
is discarded.
Function is taken from: 
http://www.nongnu.org/avr-libc/user-manual/group__avr__boot.html */
void boot_program_page (uint32_t page, uint8_t *buf) \
__attribute__ ((section (".bootloader")));

/* Wrapper function for boot_program_page. Allows user to input a
page number instead of an address for simplicity of use. Requires
page number and a pointer to a buffer */
void flash_write_page (uint8_t page, uint8_t *buf);

/* Read a character from flash memory at the given address */
char flash_read_byte (uint32_t addr);

/* Reads a page of flash memory and stores it in the passed in buffer.
Functionality not defined if buffer is shorter than length
SPM_PAGESIZE */
void flash_read_page (uint8_t page, uint8_t *buf);


#endif /* FLASHMEM_H_ */

Next is “FlashMem.c”, the guts to code.

#include "FlashMem.h"

void boot_program_page (uint32_t page, uint8_t *buf)
{
    //This is copy paste from the boot.h GNU website
    uint16_t i;
    uint8_t sreg;

    sreg = SREG;
    
    cli(); // Disable interrupts.
    
    eeprom_busy_wait ();
    
    boot_page_erase (page);
    boot_spm_busy_wait ();      // Wait until the memory is erased.

    for (i=0; i<SPM_PAGESIZE; i+=2)
    {
        // Set up little-endian word.
        uint16_t w = *buf++;
        w += (*buf++) << 8;
        
        boot_page_fill (page + i, w);
    }
    
    boot_page_write (page);     // Store buffer in flash page.
    boot_spm_busy_wait();       // Wait until the memory is written.
    
    // Re-enable RWW-section again.
    boot_rww_enable ();

    // Re-enable interrupts
    sei();

    SREG = sreg;
}

void flash_write_page(uint8_t page, uint8_t *buf)
{
    uint32_t addr = page*SPM_PAGESIZE;
    boot_program_page(addr,buf);
}

char flash_read_byte (uint32_t addr)
{
    return pgm_read_byte(addr);
}

void flash_read_page (uint8_t page, uint8_t *buf)
{
    uint32_t addr = (page*SPM_PAGESIZE);
        
    for (int i = 0; i < 128; i++)
    {
        *buf = flash_read_byte(addr);
        boot_spm_busy_wait();
        buf++;
        addr++;
    }
}

And finally and example of its usage: (USART functionality not covered. There are plenty of guides on USART out there)

#define F_CPU 8000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdbool.h>

#include "USART.h"
#include "FlashMem.h"

//Declare a buffer in RAM the size of a single page of flash memory
uint8_t flash_page_buffer[SPM_PAGESIZE]; 
//To keep track of how full the buffer is
uint8_t flash_buffer_index = 0;
//Flag which indicates if the flash page buffer is full
volatile bool flash_page_buffer_full = false; 

void Clear_Array(char *array)
{
    while (*array)
    {
        *array = 0;
        array++;
    }
}

int main(void)
{
    USART_Init((int)9600);
    
    sei(); //set enable interrupts
    
    USART_Transmit_String("Startup\r\n");
        
    while(1)
    {
        if (flash_page_buffer_full == true)
        {
            flash_page_buffer_full = false;
            flash_write_page(50,flash_page_buffer);
            
            USART_Transmit_String("\r\n<Page Received>:");
            USART_Transmit_String((char*)flash_page_buffer);
            USART_Transmit_String("\r\n");
            
            Clear_Array((char*)flash_page_buffer);
            
            flash_read_page(50, flash_page_buffer);
            
            USART_Transmit_String("\r\n<From Mem>:");
            USART_Transmit_String((char*)flash_page_buffer);
            USART_Transmit_String("\r\n");
            
            Clear_Array((char*)flash_page_buffer);
        }
    }
}

ISR(USART_RX_vect)
{
    uint8_t data;
    
    data = UDR0;
    
    //If user hits enter or inputs 128 characters, trigger flash write.
    if ((data == '\r') || (flash_buffer_index >= (SPM_PAGESIZE - 1)))
    {
        flash_page_buffer_full = true;
        flash_buffer_index = 0;
    }
    else
    {
        flash_page_buffer[flash_buffer_index++] = data;
        USART_Transmit_Char(data);
    }
}

Note: My use of page 50 is arbitrary. I would not recommend reading and writing to the same
page over and over again. Flash memory has limited read/write cycles. It’s better to keep
shifting the page you are storing too. An idea could be to use EEPROM to keep track of which
pages contain data between power cycles.

That’s all folks. Hope this helped in any way~!

 
Leave a comment

Posted by on November 15, 2014 in Programming

 

Tags: , , , , , , , , ,

[Complete] AAA PSU Parts List and Files

Here’s the promised list (Yes I source most of my parts from Element 14…)

5V SMPS
[IC] MAX1674 1*$8.24 = $8.24
[L] 22uH 1*$1.87 = $1.87
[C] 47uF Electrolytic 2*$0.21 = $0.42 (min reel of 10)
[C] 100nF Ceramic 2*$0.05 = $0.10 (min reel of 100)
[R] 200k SMD 1*$0.009 = $0.009
[R] 20k SMD 1*$0.06 = $0.06
[R] 100k SMD 1*$0.017 = $0.017 (min reel of 5)
[Subtotal] $10.716

3V3 Linear Reg
[IC] RT9198 1*$0.19 = $0.19
[C] 1uF Ceramic 2*$0.022 = $0.044 (min reel of 10)
[Subtotal] $0.234

Misc Parts
Right angle 2 header 1*$0.30 = $0.30
Header plug female 1*$0.50 = $0.50
AAA battery holder 1*$2.45 = $2.45
Solder + Power/Gas (est) = $1.00
[Subtotal] $4.25

PCB (From PCBCart)
Single board = $3.68
Tooling coast per board = $4.549
Postage per board = $2.213
[Subtotal] $10.442

TOTAL per Board = $25.642

Files:
Schematic
PCB Doc
Standard Footprint Lib
Inductor Footprint
Capactor Footprint

 
1 Comment

Posted by on April 14, 2014 in Electronics and Circuits, Projects

 

[Complete] AAA powered PSU

The final boards arrive this morning (woo~!).

Wasted no time in assembling one. Was not my best soldering work, but it was also the first time I had soldered something this dense.

It works well and the changes I made supress the ripples a heap better than the prototype board.

[Edit] Component Costs and Files

 
Leave a comment

Posted by on April 14, 2014 in Electronics and Circuits, Projects

 

Prototype PSU assembled and tested!

The PCB’s that I sent off about 2 weeks ago came in from PCBCART and they looked nice.

Without further ado, I went ahead and whacked all the components on there and gave it a test.

IT WORKED! :D

See the pictures… :D :D

 

 
Leave a comment

Posted by on March 28, 2014 in Electronics and Circuits, Projects

 

Tags: , , , , , ,

Chapters 1 to 5 rewrites

So as I’ve started chapter 6, I’ve changed my writing style a bit and… I like it much better. So much so that I’m seriously contemplating going back over all my previous work and reworking them in this new style. For me, it just flows better and it’s easier for me to convey the story across to you the readers.

Having said all that… I’m a lazy slob and haven’t touched the story for a few weeks now… :(

*I’ll get there eventually…*

 
Leave a comment

Posted by on March 3, 2014 in Story

 

Tags: ,

Chapter 5

“Father!!” she screamed, reaching out towards the chaotic scene, which was receding into void. She was on her hands and knees, frozen still like a statue, still reeling from the feelings inflicted upon her in that vision. She was awash with sadness, confusion and anger. It took her a moment to realise that she wasn’t breathing before she gasped in a lungful of air. After settling down a bit, she stood up to stretch out her cramped up legs. Blood rushed down from her head causing her to feel light headed and unbalanced.

She was back in this dull, expansive world of lifeless water and endless dirty red sky.

“Was that me?” Yoora quietly asked, almost whispering.

A thick black smoke started drifting across the water, swirling up in front of her. The smoke started to take shape, forming legs, then body, arms and head. Then the smoke started to dissipate, revealing a girl with almost the exact likeness her. This new figure however was wearing a beautiful dark green silk hanbok with intricate blue and white decals embroidered across the dress. Her blouse was bright red, with golden embroidery around the hems of the sleeves depicting a phoenix and dragon flying about each other. Her hair was glossy and perfectly plaited, which was wrapped around the top of her head like a crown. A gold and enamel hair pin in the shape of a butterfly held the plaited hair in place. Her eyes though were bright red with a piercing, almost paralysing gaze.

“That was us” the apparition replied, a hint of sadness in her voice. “That was our 12th birthday”.

“By us you mean…” Yoora replied, and then paused, unsure how to continue.

Her other self walked up to her and took hold of both her hands. “Have you ever wondered why the spirits of hundred souls haunt you at night? Do you want to know why you feel the weight of all their deaths? I am all the answers to your questions. I am the other side of you. Together we are one.”

Surprising Yoora, tears started to well up in her eyes and her throat tightened. An overwhelming feeling of acceptance and relief washed over her. She was still confused, but she felt as if this image in front of her was the missing piece of the puzzle she had been searching for.

“How did we become like this?” Yoora croaked.

The figure turned away slightly. “There’s a part of us which is almost uncontrollable. We lost it, and as a result, the monk supressed most of those traits into me and split us apart. I don’t know what it is inside of us, but I think we can control it now, especially if we are together.”

“Can we become one again?” Yoora asked .

“Yes. Only we both truly wish for it. I do, do you?”

“Yes.”

Stepping closer, the figure leaned forward and pressed its forehead against Yoora’s.

“Are you sure? Do you really want to know the past? Are you willing to accept the darkness sealed away inside me?”

“You said that together, we can control the unknown inside of us. I want to do this. I need to know who I am, what I am. I feel so hollow as I am.”

She closed her eyes. All she could feel was the warmth in her hands and forehead. There was no sound, and she started to lose track of time. Then suddenly, she felt the floor she was standing on give way, but she wasn’t falling. Feint voices started echoing around her head. Vague images started creeping into her consciousness. Smells and tastes encroached on her senses. All these sensations started to form scenes.

She recognised them as scenes from her past. Bit by bit, years of memories, experiences and feelings flowed into her, engulfing her and changing her.

She opened her eyes to find herself back at the wondumak, facing at two very alarmed men. She looked down at her hands and clenched her fists.
I’m back
She looked back towards Jumong and gave him a cheeky smile.

“That was interesting” she remarked.

Both men were still on their feet and almost in a fighting stance, as if they were expecting to get attacked.

“What happened to you?!” exclaimed Ahn.

“Oh nothing much really.” She replied with a grin on her face.

Her awakening made her realise that she was completely out of tune with the energy around her. Having been desensitised to the natural magic permeating around her for so long, she had forgotten what it had felt like. She took a deep breath and let her senses reach out past her body. The sensation of the raw mana flowing around her sent her into a state of elation. She felt alive again.

“I met someone I knew a long time ago.” She said calmly, thinly veiling the fact that she was feeling increasingly euphoric as the border between her own energy and the energy about her started to blur.
“I remember what happened back then. I remember the blood, the rage, the pain and sadness.” She locked eyes with Jumong, sensing fear from her master and confusion from the head master.
“I took it all back” she said.

Jumong swiftly stepped back, raising his arms in preparation to strike, either physically or magically. Yoona was quicker however, collecting up the mana around her as soon as he started to move and send a controlled blast of energy towards the men, pushing them back slightly and knocking them off balance. Without giving them time to recuperate, she changed the direction of the mana, slamming them onto the floor. She then suddenly reversed the flow of mana, causing the men to be thrown into the air. She held the energy in that state, suspending them helplessly in mid-air.

The whole scene on the top of the mountain looked as if gravity had ceased to exist. Dust and small rocks were floating in the air, and the drooping branches of the cherry blossom now swung about aimlessly in the air. She walked over to the table which had nearly been pushed off the wondumak during the commotion and picked it up. She placed it back in the center, and picked up the boxes and tea set which had been scattered and knocked around. Amazingly, nothing was broken.

After setting everything back to how it was before the test, she sat down in front of the table and slowly released the spell keeping her master and the headmaster suspended in the air.

“I’m sorry masters.” She said calmly. “I did what I had to do to give me enough time to explain myself.”

She paused for a moment, motioning to the men to sit.

“I realise that I might have been… difficult when I first came here. Frankly my memory of that time is still a little vague, though I remember the faces of all those who died at my hands, and a soul wrenching fear which controlled me.”

She paused again, letting the words sink in.

“I’m not like I was back then.”

She shuffled across from the table in front of Jumong then bowed to him.

“Thank you for support and guidance.” She said.

She then shuffled across to Ahn and bowed to him.

“Please guide me in my future. I have a lot to learn about the world and myself. Please help me to trust myself and protect those around me.”

She remained bowed until she felt the large, warm hand of Ahn pat her head.

“I will to the best of my ability guide you to become someone you truly want to be” Ahn said reassuringly.

She sat back up, facing the 2 men.

“The spell on the box was no test” she said, aiming the remark at the headmaster.

“I know” he replied then paused, his face giving signs of an internal struggle of thoughts. “Being honest here, it’s designed to make high risk students face their inner fears and overcome them. Having a high concentration of emotionally unstable teenage sorcerers and sorceresses is a recipe for disaster. The problem is only made worse when they all suffer from insecurities, mostly inflicted upon them by stupid stories passed down through their families.”

“What would my case be then? I have no known family to pass down freaky stories and misguided thoughts. Why make me face my demons?” Yoona replied in an attempt to see if the headmaster knew anything about her past.

“That’s the problem, we know nothing of your past. Also the fact that you were found half dead and covered in blood in a village in the middle of nowhere doesn’t lend you a credible background” he replied.

A wry smile crept onto her face for a moment before she reverted to her expressionless face.

“Why don’t you just tell people the truth about those boxes?” Yoona asked.

“The truth scares people. It’s easier to let them think it’s a test.” He replied. “I don’t do this will all students though. Only the ones who have the power to influence others, in one way or another”

The headmaster reached over and opened her box and took out one of the small vials of liquid. He popped off the lid and held it out to her.  A sweet but foul smell filled the air around her. She took the opened vial and held it.

“What does this do?” she asked.

“Supress’ bloodlust” the headmaster replied calmly.

She eyed the blackish liquid swirling around in the vile before tipping it down her throat as quickly as possible.

The liquid hit her stomach like a punch to the gut. Her first reaction was to throw up, but the feeling passed before she could, only to be replaced with a paralysing chill spreading through her veins. The cold was stabbing her mind with knives, her vision fading in and out. The feelings subsided and she found herself staring at the floor of the wondumak. Her body ached and she was out of breath.

“That was horrible” she said wryly.

Sitting back up, she felt a change inside of her. She was more relaxed; as if the lid of a pressure cooker had been open slightly, gently letting out the violent and angry steam within.
She noticed that the lid covering the top compartment of the ‘test’ box was sitting slightly askew. She set down the now empty vial with the others and removed the lid. Below was a gold banded ring inscribed with the words ‘Wish to be hidden and let the darkness drown you’ in the old imperial language.

As she picked up the ring, she could feel it drawing in some of her energy. She realised that the ring was meant to supress or hide her power, but the feeling of having her mana drained was uncomfortable.

“Is this ring necessary” she asked the headmaster.

“You don’t have to wear it now, but as we get closer to civilisation, there are people and machines sensitive to a walking mass of concentrated energy. Also you’ll intimidate the other students less” he replied.

Yoona wondered for a moment as to how the headmaster knew that she, according to Jumong, was more powerful than the average person, but that chain of thought answered itself. Jumong had to have told him.

“When do we leave?” she asked.

“As soon as you’re packed!” the headmaster replied.

 
Leave a comment

Posted by on March 3, 2014 in Story

 

Tags: , , , ,

[Update] 2 AAA battery 5v and 3.3v PSU

I decided it would be wise to create a simpler PCB for the first iteration to make sure everything works. I used the same schematic, just re-did the board layout to put most things on the top layer and also broke out all the pins on the SMPS.

I ordered the parts earlier this afternoon from Element14! Just need to get the boards sent off soon.

Hope this all works out!

[New Layout]

BoardTopProto1

 
Leave a comment

Posted by on March 3, 2014 in Electronics and Circuits, Projects

 
 
Follow

Get every new post delivered to your Inbox.