Engineers Garage

  • Projects and Tutorials
    • Circuit Design
    • Electronic Projects
      • 8051
      • Arduino
      • ARM
      • AVR
      • PIC
      • Raspberry pi
      • STM32
    • Tutorials
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • EE Design News
    • DIY Reviews
    • Guest Post
    • Sponsored Content
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • Digi-Key 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
  • EE Resources
    • DesignFast
    • LEAP Awards
    • Oscilloscope Product Finder
    • Video
    • White Papers
    • Webinars
  • EE Learning Center
  • Women in Engineering

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

June 14, 2013 By Ashutosh Bhatt

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 <avr/io.h>
#include <util/delay.h>
#include <avr/boot.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdio.h>
 
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<SPM_PAGESIZE; i+=2)
        {
            //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 <avr/io.h>
#include <util/delay.h>
 
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

Related Articles Read More >

Atmega162 UAR serial communication using Arduino IDE
Controlling a BLDC Motor with an ESC
LED chaser using AVR ATMega16
Satellite dish antenna angle controller using ATmega16

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!


Featured Tutorials

  • Getting Started with the ESPlorer IDE
  • SENDING TEXT MESSAGE USING ESP8266
  • CONNECTION BETWEEN TWO ESP8266
  • ESP8266 WIFI HOTSPOT
  • HOME AUTOMATION USING ESP8266
  • Open WiFi Scanner using Esp8266

Stay Up To Date

Newsletter Signup

EE Training Center Classrooms

“ee

“ee

“ee

“ee

“ee

Recent Articles

  • What are the different types of fingerprint scanners?
  • TV remote hack using Arduino and IR sensor
  • Gesture sensor using Arduino
  • Diodes adds to its family of voltage-level shifters
  • Xilinx expands UltraScale+ portfolio to include compact, intelligent edge solutions

RSS EDABOARD.com Discussions

  • WiringPi SPI without Chip Select/Enable?
  • Need help in optimizing RF antenna balun on two port network analyzer
  • Different types of screened cable, which is best?
  • Radiated immunity testing for product that has an antenna and receiver?
  • ealtek RTL8722DM_mini Arduino Compatible WiFi + BLE IoT development board

RSS Electro-Tech-Online.com Discussions

  • Help with circuit design
  • Adjustable 0-5v ground switch
  • Multiple UART Hub to USB?
  • Need to add a question to a thread.
  • Weird switching transformer noise, Audio attached
Engineers Garage
  • Analog IC TIps
  • Connector Tips
  • DesignFast
  • EDABoard Forums
  • EE World Online
  • Electro-Tech-Online Forums
  • Microcontroller Tips
  • Power Electronic Tips
  • Sensor Tips
  • Test and Measurement Tips
  • 5G Technology World
  • About Us
  • Contact Us
  • Advertise

Copyright © 2021 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 | Advertising | About Us

Search Engineers Garage

  • Projects and Tutorials
    • Circuit Design
    • Electronic Projects
      • 8051
      • Arduino
      • ARM
      • AVR
      • PIC
      • Raspberry pi
      • STM32
    • Tutorials
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • EE Design News
    • DIY Reviews
    • Guest Post
    • Sponsored Content
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • Digi-Key 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
  • EE Resources
    • DesignFast
    • LEAP Awards
    • Oscilloscope Product Finder
    • Video
    • White Papers
    • Webinars
  • EE Learning Center
  • Women in Engineering