HWA
Bare metal programming with style
hwa/atmel/avr/examples/08-1-swuart-flash-read-write/main.c
Process read/write commands on the Flash memory.

Algorithm:

Synchronize the software UART.
Send the application '$' prompt
Infinite loop:
  Wait for: c + al + ah + n + '\n'
  IF c=='f' THEN read n bytes from Flash address al:ah
  IF c=='F' THEN write n at Flash address al:ah
Test application
 ./main.py --help
 ./main.py read 0 1024
 ./main.py write 0x800 0x55 # BE CAREFULL OF NOT OVERWRITING THE APPLICATION OR THE BOOTLOADER!
Note: if you have Diabolo installed, writing into the Flash memory below Diabolo will corrupt the application CRC and Diabolo will not start the application anymore after RESET. Oonly a few 0xFF bytes above Diabolo can be modified without changing the CRC. If the application does not start, you can still dump the Flash content with:
diabolo.py --read-flash --hexdump

FIXME: the Diabolo host application should help repairing the CRC.

config.h
#ifndef CONFIG_H
#define CONFIG_H
#include BOARD_H
#define UART HW_SWUARTA( txd, DIABOLO_PIN_TX, \
rxd, DIABOLO_PIN_RX, \
startirq, (DIABOLO_PIN_RX,port,pcic,irq), \
counter, counter1, \
compare, compare0, \
clkdiv, 1, \
autosync, 51, \
fastreg, (shared,gpior0) )
HW_DECLARE(UART);
#endif
main.c
/* This file is part of the HWA project.
* Copyright (c) 2012,2015 Christophe Duparquet.
* All rights reserved. Read LICENSE.TXT for details.
*/
#include "config.h"
uint8_t uart_getbyte ( )
{
while ( !hw(stat,UART).rxc )
hw( wait, irq );
return hw( read, UART );
}
void uart_putbyte ( uint8_t byte )
{
while ( !hw(stat,UART).txc )
hw( wait, irq );
hw( write, UART, byte );
}
/* Process received bytes. Valid sequences are:
*
* 'f'+al+ah+n+'\n' Read n bytes of Flash from address al:ah
* 'F'+al+ah+v+'\n' Write v in Flash at address al:ah
*/
static void process ( uint8_t byte )
{
static uint8_t bcount = 0 ;
static union {
uint8_t buf[4] ;
struct {
uint8_t cmd ;
// intptr_t addr ;
uint16_t addr ;
uint8_t n ;
} ;
} buf ;
/* Buffer for one Flash page
*/
static uint8_t page[HW_DEVICE_FLASH_PAGE_SIZE] ;
if ( bcount == 0 ) {
buf.cmd = byte ;
bcount++ ;
} else if ( bcount < 4 )
buf.buf[bcount++] = byte ;
else {
bcount = 0 ;
if ( byte == '\n'
&& buf.addr < HW_DEVICE_FLASH_SIZE ) {
if ( buf.cmd == 'F' ) {
/*
* Write data
*/
uint8_t zbyte = buf.addr & (HW_DEVICE_FLASH_PAGE_SIZE-1) ;
intptr_t zpage = buf.addr & ~(HW_DEVICE_FLASH_PAGE_SIZE-1) ;
/* Get the content of the page to be modified and make the required
* change
*/
hw( read_bytes, flash0, page, zpage, sizeof(page) );
page[ zbyte ] = buf.n ;
/* Process the reprogramming of the page. Some more checkings could be
* done in order to not erase or program blank pages.
*/
hw( load_buffer, flash0, page );
hw( erase_page, flash0, zpage );
hw( write_page, flash0, zpage );
uart_putbyte( '$');
return ;
}
else if ( buf.cmd == 'f' ) {
/*
* Read data
*/
while ( buf.n-- ) {
uint8_t byte = hw( read, flash0, buf.addr++ );
uart_putbyte( byte );
}
uart_putbyte( '$');
return ;
}
}
uart_putbyte( '!');
return ;
}
}
int
main ( )
{
/* Create a HWA context to collect the hardware configuration
* Preload this context with RESET values
*/
hwa( begin, reset );
/* Configure the software UART
*/
hwa( configure, UART );
/* Have the CPU enter idle mode when the 'sleep' instruction is executed.
*/
hwa( configure, core0,
sleep, enabled,
sleep_mode, idle );
/* Write this configuration into the hardware
*/
hwa( commit );
hw( enable, interrupts );
/* Wait for UART synchronization, then send the prompt
*/
while ( !hw(stat,UART).sync )
hw( wait, irq );
uart_putbyte( '$');
for(;;) {
/*
* Main loop:
* put the MCU into sleep mode, an interrupt will awake it
*/
hw( wait, irq );
if ( hw(stat,UART).rxc ) {
/*
* MCU awakened by SWUART that has received a stop bit
* Get the received byte (clears rxc flag)
*/
process( uart_getbyte() );
}
}
}
hwa
#define hwa(...)
hwa( action, object [,...] ) stores an action for an object into a HWA context.
Definition: hwa_macros.h:552
HW_DEVICE_FLASH_SIZE
#define HW_DEVICE_FLASH_SIZE
Definition: atmega168x.h:32
HW_DECLARE
#define HW_DECLARE(...)
Declares the functions that implement an object.
Definition: hwa_1.h:521
swuarta.h
Software-emulated UART.
HW_DEVICE_FLASH_PAGE_SIZE
#define HW_DEVICE_FLASH_PAGE_SIZE
Definition: atmega168x.h:37
hw
#define hw(...)
hw( action, object [,...] ) executes an action immediately on an object.
Definition: hwa_macros.h:523