Engineers Garage

  • Electronic Projects & Tutorials
    • Electronic Projects
      • Arduino Projects
      • AVR
      • Raspberry pi
      • ESP8266
      • BeagleBone
      • 8051 Microcontroller
      • ARM
      • PIC Microcontroller
      • STM32
    • Tutorials
      • Audio Electronics
      • Battery Management
      • Brainwave
      • Electric Vehicles
      • EMI/EMC/RFI
      • Hardware Filters
      • IoT tutorials
      • Power Tutorials
      • Python
      • Sensors
      • USB
      • VHDL
    • Circuit Design
    • Project Videos
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • Electronic Product News
    • Business News
    • Company/Start-up News
    • DIY Reviews
    • Guest Post
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • DigiKey Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • Learn
    • eBooks/Tech Tips
    • Design Guides
    • Learning Center
    • Tech Toolboxes
    • Webinars & Digital Events
  • Resources
    • Digital Issues
    • EE Training Days
    • LEAP Awards
    • Podcasts
    • Webinars / Digital Events
    • White Papers
    • Engineering Diversity & Inclusion
    • DesignFast
  • Guest Post Guidelines
  • Advertise
  • Subscribe

How to Use SPM for Flash to Flash Programming – (Part 33/46)

By Ashutosh Bhatt June 14, 2013

The Self Programming Mode (SPM) is a feature which enables a microcontroller to program its own flash memory. Using the SPM a microcontroller can program itself with an SPM code. The SPM is commonly used with the microcontroller Boot-Loader codes which help to program the microcontroller serially. In AVR microcontroller the SPM is available only for the code running in the BLS of the flash memory. With the help of the SPM a code in BLS can rewrite the application flash memory entirely or a part of it. It can even rewrite its own code in the BLS section.

The SPM is a key factor of the Boot-Loader code since the major function of the Boot-Loader is to load an application code into the application flash section. The Boot-Loader may receive the code binary from other memory chips, SD-cards or through the serial port of the microcontroller in case of serial programming. It is then with the help of the SPM that the microcontroller write the binary code into the application flash section. In this project the operation of the SPM is demonstrated re-writing the code from one region of the flash memory to another region and then tries to execute the same code from that region. The hardware used in this project includes ATMEGA16 as microcontroller, USBASP as the programmer and the software used are AVR STUDIO 4 as IDE and AVR-BURNO-MAT as the burner software.


 

Self-Programming Mode (SPM) is a feature of the AVR microcontroller which enables the microcontroller to program its own flash memory. Only the code running on the BLS can make use of this SPM feature. The microcontroller can be made to start executing from the BLS from there the code can access the application flash area. The BLS can read or write the content of the entire flash including the BLS itself.

 

Block Diagram of SPM with BLS in AVR

Fig. 2: Block Diagram of SPM with BLS in AVR

The task of writing the BLS code with SPM has been made simple by the APIs available in the header file <avr/boot.h>. The following are the important APIs available in the header file which helps in the SPM.

 

FUNCTION

DESCRIPTION

PARAMETER

boot_is_spm_interrupt            ( )

Check if the SPM interrupt is enabled.

 

boot_lock_bits_set (lock_bits)

Set the Boot-Loader lock bits

A mask of which Boot Loader Lock Bits to set

boot_lock_bits_set_safe (lock_bits)

Waits for EEPROM and SPM operations to complete before setting lock bits

A mask of which Boot Loader Lock Bits to set

boot_lock_fuse_bits_get (address)

Read the lock or fuse bits at the given address. Returns 0 or 1 according to the fuse bit is programmed or not

The address to be read

boot_page_erase (address)

Erase the flash page that is referred by address

A byte address in flash

boot_page_erase_safe (address)            

waits for EEPROM and SPM operations to complete before erasing the page

A byte address in flash

boot_page_fill             (address, data)   

Fill the Boot-Loader temporary page buffer for flash address with data word

The address is a byte address. The data is a word

boot_page_fill_safe (address, data)

waits for EEPROM and SPM operations to complete before filling the page

The address is a byte address. The data is a word

boot_page_write (address)

Write the Boot-Loader temporary page buffer to flash page that contains address

Byte address in flash

boot_page_write_safe             (address)

waits for EEPROM and SPM operations to complete before writing the page

Byte address in flash

boot_rww_busy ( )

Check if the RWW section is busy

 

boot_rww_enable ( )  

Enable the Read-While-Write memory section.

 

boot_rww_enable_safe ( )     

waits for EEPROM and SPM operations to complete before enabling the RWW memory

 

boot_signature_byte_get (address)

Returns the Signature Row byte at the given address

Parameter address can be 0 to 0x1F

boot_spm_busy ( )

Check if the SPM instruction is busy

 

boot_spm_busy_wait ( )        

Wait while the SPM instruction is busy

 

boot_spm_interrupt_disable ( )

Disable the SPM interrupt

 

boot_spm_interrupt_enable ( )

Enable the SPM interrupt

 

Fig. 3: Important APIs in AVR’s header file for SPM 

Using the above APIs one can write a code for SPM in an AVR microcontroller provided that the code should follow certain steps in the order. In this project code which has been programmed from the beginning of the flash memory is re-programmed into another region of the flash memory as such. The task of programming one region of flash memory with the binary taken from the other region can be done in the following three major steps.

Step: 1 Erase the flash page which is about to write into

The first step is to erase the flash page which is about to be written with the new values. The API which helps in executing this step is;

Boot_page_erase (address)

This API can erase an entire page in the flash which the parameter addresses. In the code the address of the page erased is 256. The following image shows the status of the temporary page buffer and the flash memory at the step 1. The temporary page buffer is a buffer in which an entire page can be stored before it is flashed into a page in the flash memory.

Figure represents Status of temporary page buffer and flash memory in SPM of AVR

Fig. 4:  Figure represents Status of temporary page buffer and flash memory in SPM of AVR

Step: 2 Store the values in a temporary buffer before write into a flash page

This is the second step in which one should store the required binary in a temporary buffer, before writing to any of the flash memory page. The API that can be used for this purpose is;

boot_page_fill             (address, data)

This API fills the Boot-Loader temporary page buffer byte by byte before flashing the data in the temporary page buffer into a page as such. The parameter data represents each byte in the buffer and the parameter address represents the page address + offset of the buffer location where the data byte need to be stored.

The following figure represents the operation in which the temporary page buffer is filled byte by byte using the API boot_page_fill (address, data). 

Operation of Data Transfer to temporary page buffer using AVR's API boot_page_fill

Fig. 5: Operation of Data Transfer to temporary page buffer using AVR’s API boot_page_fill

The parameter data in the API boot_page_fill (address, data) is actually read from the first location of the flash memory itself with the help of another API which is available in the header file <avr/pgmspace.h>.

pgm_read_byte (address)

 

FUNCTION

DESCRIPTION

PARAMETER

pgm_read_byte (address)

This function returns the byte which it reads from the flash memory referred by the parameter ‘address’

Refers the location of the flash memory from which the byte need to be read

 

Step: 3 Program the filled temporary buffer into the already erased flash page

This is the final step in which the filled temporary buffer is flashed using an API into already erased page of the flash memory. The API which helps in this step is;

boot_page_write (address)

Temporary Buffer Data transferred in AVR's Flash Memory using API

Fig. 6: Temporary Buffer Data transferred in AVR’s Flash Memory using API

The code in this project which is written for the BLS can copy 300bytes from the flash memory into the temporary buffer starting from the address 0x0000. These bytes are then flashed into the flash memory page starting from the address 0x0100. After doing this the code from the BLS will make a jump to the address 0x0100 so that the re-written binary can be executed next. With this boot loader code, whatever program we flash into the address starting from 0x0000 will get rewritten at ox 0x0100 and executed. A simple LED blinking test application can be written into the flash memory starting from 0x0000 to test the working. Flash the code for the BLS first and then the LED application code using the steps explained in the previous project on LED blinking from BLS of AVR. When the led blinks, it means that the code has been re-written from one section of the flash memory to another and is executing from there.

LED Blinking using SPM of AVR circuit set up on breadboard

Fig. 7: LED Blinking using SPM of AVR circuit set up on breadboard

Project Source Code

###


#define F_CPU 8000000
#include
#include
#include
#include
#include
#include
#include
 
int main ( void )
{
uint16_t i;
uint8_t A [ 300 ];
uint8_t sreg;
uint32_t page = 256;
unsigned char *buf = A;
 
 
//-------------------------------------------------------------------------------
DDRD |= 0x80;
PORTD |= 0x7F; //led on. bootloader ok.
_delay_ms ( 2000 );
PORTD |= 0x80; //turn off led now. We hope the application will turn on the LED again
_delay_ms ( 2000 );
//--------------------------------------------------------------------------------
 
// storing the bytes from ith location of flash memory to ith variable of array A//
for ( i = 0; i < 300; i ++ )
A [ i ] = pgm_read_byte ( i );
// storing the bytes from ith location of flash memory to ith variable of array A//
 
//================================= SPM ==========================================//
        sreg = SREG; // store the current interrupt status in sreg
        cli(); // clear interrupts
        eeprom_busy_wait (); // wait till the eeprom is free.
        boot_page_erase (page); // erase the page in the flash which we are about to write into
        boot_spm_busy_wait ();      // Wait until the memory is erased.
 
//---- fill the bytes of the page into temperory page buffer before wriying into flash ----//
        for (i=0; i
        {
            //convert the bytes to little-endian word//
            uint16_t w = *buf++;
            w += (*buf++) << 8;
      //convert the bytes to little-endian word//
 
            boot_page_fill (page + i, w); // fill the temperory page buffer byte by byte
        }
//---- fill the bytes of the page into temperory page buffer before wriying into flash ----//
 
//--------------------------------------------------------------------//
        boot_page_write (page);     // Store buffer in flash page.
//--------------------------------------------------------------------//
 
        boot_spm_busy_wait();       // Wait until the memory is written.
        boot_rww_enable (); // Reenable RWW-section again
        SREG = sreg; // Re-enable interrupts
//================================= SPM ==========================================//
 
asm ( "jmp 0x0100" ); // jump to application programmed at 0x0100
 
}
 

###

 


Project Source Code

###


#define F_CPU 8000000
#include
#include
 
int main ( void )
{
DDRD |= 0x80;
 
while(1)
{
PORTD &= 0x7F;
_delay_ms ( 2000 );
PORTD |= 0x80;
_delay_ms ( 2000 );
}
 
}
 

###

 


Circuit Diagrams

Circuit-Diagram-of-How-to-Use-SPM-for-Flash-to-Flash-Programming

Project Components

  • ATmega16
  • LCD
  • LED
  • Resistor

Project Video


Filed Under: AVR, Electronic Projects
Tagged With: avr microcontroller, circuit, Flash Programming, project, SPM
 

Next Article

← Previous Article
Next Article →

Questions related to this article?
👉Ask and discuss on EDAboard.com and Electro-Tech-Online.com forums.



Tell Us What You Think!! Cancel reply

You must be logged in to post a comment.

EE TECH TOOLBOX

“ee
Tech Toolbox: Internet of Things
Explore practical strategies for minimizing attack surfaces, managing memory efficiently, and securing firmware. Download now to ensure your IoT implementations remain secure, efficient, and future-ready.

EE Learning Center

EE Learning Center
“engineers
EXPAND YOUR KNOWLEDGE AND STAY CONNECTED
Get the latest info on technologies, tools and strategies for EE professionals.

HAVE A QUESTION?

Have a technical question about an article or other engineering questions? Check out our engineering forums EDABoard.com and Electro-Tech-Online.com where you can get those questions asked and answered by your peers!


RSS EDABOARD.com Discussions

  • Reducing "shoot-through" in offline Full Bridge SMPS?
  • High Side current sensing
  • How to simulate power electronics converter in PSpice?
  • Voltage mode pushpull is a nonsense SMPS?
  • Layout IRN reduction in Comparator

RSS Electro-Tech-Online.com Discussions

  • Back to the old BASIC days
  • Parts required for a personal project
  • PIC KIT 3 not able to program dsPIC
  • Failure of polypropylene motor-run capacitors
  • Siemens large industrial PLC parts

Featured – RPi Python Programming (27 Part)

  • RPi Python Programming 21: The SIM900A AT commands
  • RPi Python Programming 22: Calls & SMS using a SIM900A GSM-GPRS modem
  • RPi Python Programming 23: Interfacing a NEO-6MV2 GPS module with Raspberry Pi
  • RPi Python Programming 24: I2C explained
  • RPi Python Programming 25 – Synchronous serial communication in Raspberry Pi using I2C protocol
  • RPi Python Programming 26 – Interfacing ADXL345 accelerometer sensor with Raspberry Pi

Recent Articles

  • What is AWS IoT Core and when should you use it?
  • AC-DC power supply extends voltage range to 800 V DC
  • Infineon’s inductive sensor integrates coil system driver, signal conditioning circuits and DSP
  • Arm Cortex-M23 MCU delivers 87.5 µA/MHz active mode
  • STMicroelectronics releases automotive amplifiers with in-play open-load detection

EE ENGINEERING TRAINING DAYS

engineering

Submit a Guest Post

submit a guest post
Engineers Garage
  • Analog IC TIps
  • Connector Tips
  • Battery Power Tips
  • DesignFast
  • EDABoard Forums
  • EE World Online
  • Electro-Tech-Online Forums
  • EV Engineering
  • Microcontroller Tips
  • Power Electronic Tips
  • Sensor Tips
  • Test and Measurement Tips
  • 5G Technology World
  • Subscribe to our newsletter
  • About Us
  • Contact Us
  • Advertise

Copyright © 2025 WTWH Media LLC. All Rights Reserved. The material on this site may not be reproduced, distributed, transmitted, cached or otherwise used, except with the prior written permission of WTWH Media
Privacy Policy

Search Engineers Garage

  • Electronic Projects & Tutorials
    • Electronic Projects
      • Arduino Projects
      • AVR
      • Raspberry pi
      • ESP8266
      • BeagleBone
      • 8051 Microcontroller
      • ARM
      • PIC Microcontroller
      • STM32
    • Tutorials
      • Audio Electronics
      • Battery Management
      • Brainwave
      • Electric Vehicles
      • EMI/EMC/RFI
      • Hardware Filters
      • IoT tutorials
      • Power Tutorials
      • Python
      • Sensors
      • USB
      • VHDL
    • Circuit Design
    • Project Videos
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • Electronic Product News
    • Business News
    • Company/Start-up News
    • DIY Reviews
    • Guest Post
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • DigiKey Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • Learn
    • eBooks/Tech Tips
    • Design Guides
    • Learning Center
    • Tech Toolboxes
    • Webinars & Digital Events
  • Resources
    • Digital Issues
    • EE Training Days
    • LEAP Awards
    • Podcasts
    • Webinars / Digital Events
    • White Papers
    • Engineering Diversity & Inclusion
    • DesignFast
  • Guest Post Guidelines
  • Advertise
  • Subscribe