cleanup main.c
- codingstyle - move functions to top (readable asm-listing) - pull lowlevel.c into main.c
This commit is contained in:
parent
ba471f01de
commit
51182dbccb
|
@ -1,9 +1,16 @@
|
|||
|
||||
#ifndef CHIPDEF_H
|
||||
#define CHIPDEF_H
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
#if defined (SPMCSR)
|
||||
#define SPM_REG SPMCSR
|
||||
#elif defined (SPMCR)
|
||||
#define SPM_REG SPMCR
|
||||
#else
|
||||
#error "AVR processor does not provide bootloader support!"
|
||||
#endif
|
||||
|
||||
// TODO: make use of RAMEND in the avr-libc io-files and
|
||||
// avoid a lot of by-device definitions here
|
||||
|
||||
|
|
27
lowlevel.c
27
lowlevel.c
|
@ -1,27 +0,0 @@
|
|||
//
|
||||
// Low-level routines to read lock and fuse-bytes
|
||||
//
|
||||
// Copyright (C) 2/2005 Martin Thomas, Kaiserslautern, Germany
|
||||
//
|
||||
|
||||
#include "lowlevel.h"
|
||||
|
||||
unsigned char read_fuse_lock(unsigned short addr, unsigned char mode)
|
||||
{
|
||||
unsigned char retval;
|
||||
|
||||
asm volatile
|
||||
(
|
||||
"movw r30, %3\n\t" /* Z to addr */ \
|
||||
"sts %0, %2\n\t" /* set mode in SPM_REG */ \
|
||||
"lpm\n\t" /* load fuse/lock value into r0 */ \
|
||||
"mov %1,r0\n\t" /* save return value */ \
|
||||
: "=m" (SPM_REG),
|
||||
"=r" (retval)
|
||||
: "r" (mode),
|
||||
"r" (addr)
|
||||
: "r30", "r31", "r0"
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
|
18
lowlevel.h
18
lowlevel.h
|
@ -1,18 +0,0 @@
|
|||
#ifndef LOWLEVEL_H
|
||||
#define LOWLEVEL_H
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
/* Check for SPM Control Register in processor. */
|
||||
#if defined (SPMCSR)
|
||||
# define SPM_REG SPMCSR
|
||||
#elif defined (SPMCR)
|
||||
# define SPM_REG SPMCR
|
||||
#else
|
||||
# error AVR processor does not provide bootloader support!
|
||||
#endif
|
||||
|
||||
unsigned char read_fuse_lock(unsigned short addr, unsigned char mode);
|
||||
|
||||
|
||||
#endif
|
491
main.c
491
main.c
|
@ -67,8 +67,6 @@
|
|||
#include <avr/wdt.h>
|
||||
#include <avr/boot.h>
|
||||
#include <avr/pgmspace.h>
|
||||
// function not found in boot.h to read lock/fuses
|
||||
#include "lowlevel.h"
|
||||
|
||||
#ifndef XTAL
|
||||
#warning "Set XTAL in Makefile"
|
||||
|
@ -108,12 +106,129 @@ unsigned char gBuffer[UART_RX_BUFFER_SIZE];
|
|||
#define eeprom_is_ready() bit_is_clear(EECR, EEWE)
|
||||
#define my_eeprom_busy_wait() do{}while(!eeprom_is_ready())
|
||||
|
||||
unsigned char BufferLoad(unsigned int , unsigned char ) ;
|
||||
void BlockRead(unsigned int , unsigned char ) ;
|
||||
|
||||
uint32_t address;
|
||||
unsigned char device;
|
||||
|
||||
unsigned char BufferLoad(unsigned int size, unsigned char mem)
|
||||
{
|
||||
unsigned int data, cnt;
|
||||
uint32_t tempaddress;
|
||||
|
||||
for (cnt = 0; cnt < UART_RX_BUFFER_SIZE; cnt++) {
|
||||
if (cnt < size)
|
||||
gBuffer[cnt] = recchar();
|
||||
else
|
||||
gBuffer[cnt] = 0xFF;
|
||||
}
|
||||
cnt = 0;
|
||||
|
||||
tempaddress = address; // Store address in page
|
||||
|
||||
my_eeprom_busy_wait();
|
||||
|
||||
if (device == devtype) {
|
||||
// Flash
|
||||
if (mem == 'F') {
|
||||
do {
|
||||
data = gBuffer[cnt++];
|
||||
data |= (gBuffer[cnt++] << 8);
|
||||
boot_page_fill(address, data); // call asm routine.
|
||||
|
||||
address = address +2; // Select next word in memory
|
||||
size -= 2; // Reduce number of bytes to write by two
|
||||
} while(size); // Loop until all bytes written
|
||||
|
||||
/* commented out since not compatible with mega8 -
|
||||
secondary benefit: saves memory
|
||||
tempaddress &= 0xFF80; // Ensure the address points to the first byte in the page
|
||||
*/
|
||||
|
||||
boot_page_write(tempaddress);
|
||||
boot_spm_busy_wait();
|
||||
boot_rww_enable(); // Re-enable the RWW section
|
||||
|
||||
/* commented out since not compatible with mega8
|
||||
if (address != (address & 0xFF80))
|
||||
{ // Ensure that the address points to the beginning of the next page
|
||||
address &= 0xFF80;
|
||||
address += SPM_PAGESIZE;
|
||||
}
|
||||
*/
|
||||
} // End FLASH
|
||||
|
||||
// Start EEPROM
|
||||
if (mem == 'E') {
|
||||
address >>= 1;
|
||||
do {
|
||||
EEARL = address; // Setup EEPROM address
|
||||
EEARH = (address >> 8);
|
||||
address++; // Select next byte
|
||||
EEDR = gBuffer[cnt++];
|
||||
|
||||
EECR |= (1<<EEMWE); // Write data into EEPROM
|
||||
EECR |= (1<<EEWE);
|
||||
|
||||
while (EECR & (1<<EEWE)); // Wait for EEPROM write to finish
|
||||
size--; // Decreas number of bytes to write
|
||||
} while(size); // Loop until all bytes written
|
||||
}
|
||||
return '\r'; // Report programming OK
|
||||
}
|
||||
return 0; // Report programming failed
|
||||
}
|
||||
|
||||
void BlockRead(unsigned int size, unsigned char mem)
|
||||
{
|
||||
unsigned int data;
|
||||
|
||||
my_eeprom_busy_wait();
|
||||
|
||||
// Read EEPROM
|
||||
if (mem == 'E') {
|
||||
// address>>=1; // not needed here - hmm, somehow inconsistant TODO
|
||||
do {
|
||||
EEARL = address; // Setup EEPROM address
|
||||
EEARH = (address >> 8);
|
||||
address++; // Select next EEPROM byte
|
||||
EECR |= (1<<EERE); // Read EEPROM
|
||||
sendchar(EEDR); // Transmit EEPROM data to PC
|
||||
size--; // Decrease number of bytes to read
|
||||
} while (size); // Repeat until all block has been read
|
||||
// Read Flash
|
||||
} else {
|
||||
do {
|
||||
#if defined(RAMPZ)
|
||||
data = pgm_read_word_far(address);
|
||||
#else
|
||||
data = pgm_read_word_near((uint16_t)address);
|
||||
#endif
|
||||
sendchar((unsigned char)data); //send LSB
|
||||
sendchar((unsigned char)(data >> 8)); //send MSB
|
||||
address += 2; // Select next word in memory
|
||||
size -= 2; // Subtract two bytes from number of bytes to read
|
||||
} while (size); // Repeat until all block has been read
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char read_fuse_lock(unsigned short addr, unsigned char mode)
|
||||
{
|
||||
unsigned char retval;
|
||||
|
||||
asm volatile
|
||||
(
|
||||
"movw r30, %3\n\t" /* Z to addr */ \
|
||||
"sts %0, %2\n\t" /* set mode in SPM_REG */ \
|
||||
"lpm\n\t" /* load fuse/lock value into r0 */ \
|
||||
"mov %1,r0\n\t" /* save return value */ \
|
||||
: "=m" (SPM_REG),
|
||||
"=r" (retval)
|
||||
: "r" (mode),
|
||||
"r" (addr)
|
||||
: "r30", "r31", "r0"
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void send_boot(void)
|
||||
{
|
||||
sendchar('A');
|
||||
|
@ -132,70 +247,66 @@ int main(void)
|
|||
unsigned tempi;
|
||||
char val;
|
||||
|
||||
#ifdef START_POWERSAVE
|
||||
#ifdef START_POWERSAVE
|
||||
char OK = 1;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
cli();
|
||||
|
||||
MCUCR = (1<<IVCE); // move interruptvectors to the Boot sector
|
||||
MCUCR = (1<<IVSEL); // device specific !
|
||||
MCUCR = (1<<IVCE); // move interruptvectors to the Boot sector
|
||||
MCUCR = (1<<IVSEL); // device specific !
|
||||
|
||||
BLDDR &= ~(1<<BLPNUM); // set as Input
|
||||
BLDDR &= ~(1<<BLPNUM); // set as Input
|
||||
BLPORT |= (1<<BLPNUM); // Enable pullup
|
||||
|
||||
USART_Init(UART_BAUD_SELECT(BAUDRATE,XTAL),UARTSINGLE); // single speed
|
||||
// USART_Init(UART_BAUD_SELECT(BAUDRATE/2,XTAL),UARTDOUBLE); // double speed
|
||||
USART_Init(UART_BAUD_SELECT(BAUDRATE,XTAL),UARTSINGLE); // single speed
|
||||
// USART_Init(UART_BAUD_SELECT(BAUDRATE/2,XTAL),UARTDOUBLE); // double speed
|
||||
|
||||
#ifdef START_POWERSAVE
|
||||
#ifdef START_POWERSAVE
|
||||
/*
|
||||
This is an adoption of the Butterfly Bootloader startup-sequence.
|
||||
It may look a little strange but separating the login-loop from
|
||||
the main parser-loop gives a lot a possibilities (timeout, sleep-modes
|
||||
etc.).
|
||||
*/
|
||||
for(;OK;)
|
||||
{
|
||||
if((BLPIN & (1<<BLPNUM)))
|
||||
{
|
||||
for(;OK;) {
|
||||
if ((BLPIN & (1<<BLPNUM))) {
|
||||
// jump to main app if pin is not grounded
|
||||
BLPORT &= ~(1<<BLPNUM); // set to default
|
||||
MCUCR = (1<<IVCE); // move interruptvectors to the Application sector
|
||||
MCUCR = (0<<IVSEL); // device specific !
|
||||
jump_to_app(); // Jump to application sector
|
||||
}
|
||||
else
|
||||
{
|
||||
val = recchar();
|
||||
BLPORT &= ~(1<<BLPNUM); // set to default
|
||||
MCUCR = (1<<IVCE); // move interruptvectors to the Application sector
|
||||
MCUCR = (0<<IVSEL); // device specific !
|
||||
jump_to_app(); // Jump to application sector
|
||||
|
||||
if( val == 0x1B ) /* ESC */
|
||||
{ // AVRPROG connection
|
||||
while (val != 'S') // Wait for signon
|
||||
{
|
||||
} else {
|
||||
val = recchar();
|
||||
/* ESC */
|
||||
if (val == 0x1B) {
|
||||
// AVRPROG connection
|
||||
// Wait for signon
|
||||
while (val != 'S')
|
||||
val = recchar();
|
||||
}
|
||||
send_boot(); // Report signon
|
||||
|
||||
send_boot(); // Report signon
|
||||
OK = 0;
|
||||
}
|
||||
else
|
||||
|
||||
} else {
|
||||
sendchar('?');
|
||||
}
|
||||
}
|
||||
// Power-Save code here
|
||||
}
|
||||
|
||||
#elif defined(START_SIMPLE)
|
||||
#elif defined(START_SIMPLE)
|
||||
|
||||
if((BLPIN & (1<<BLPNUM)))
|
||||
{
|
||||
// jump to main app if pin is not grounded
|
||||
BLPORT &= ~(1<<BLPNUM); // set to default
|
||||
if ((BLPIN & (1<<BLPNUM))) {
|
||||
// jump to main app if pin is not grounded
|
||||
BLPORT &= ~(1<<BLPNUM); // set to default
|
||||
MCUCR = (1<<IVCE);
|
||||
MCUCR = (0<<IVSEL); //move interruptvectors to the Application sector
|
||||
jump_to_app(); // Jump to application sector
|
||||
MCUCR = (0<<IVSEL); //move interruptvectors to the Application sector
|
||||
jump_to_app(); // Jump to application sector
|
||||
}
|
||||
|
||||
|
||||
#elif defined(START_WAIT)
|
||||
#elif defined(START_WAIT)
|
||||
|
||||
// Timer-Setup for ATmega8
|
||||
// - verify that the configuration is valid for the target AVR
|
||||
|
@ -225,80 +336,68 @@ int main(void)
|
|||
TCCR1B |= _BV(CS00) |_BV(CS02); //1024 prescaler
|
||||
#endif
|
||||
|
||||
while(1){
|
||||
if(UART0_STATUS & (1<<RXC)){
|
||||
while (1) {
|
||||
if (UART0_STATUS & (1<<RXC)) {
|
||||
if (UART0_DATA == 'S')
|
||||
break;
|
||||
}
|
||||
if (TCNT1 >= WAIT_VALUE){
|
||||
BLPORT &= ~(1<<BLPNUM); // set to default
|
||||
BLPORT &= ~(1<<BLPNUM); // set to default
|
||||
MCUCR = (1<<IVCE);
|
||||
MCUCR = (0<<IVSEL); //move interruptvectors to the Application sector
|
||||
TCCR1B = 0; // timer off
|
||||
jump_to_app(); // Jump to application sector
|
||||
MCUCR = (0<<IVSEL); // move interruptvectors to the Application sector
|
||||
TCCR1B = 0; // timer off
|
||||
jump_to_app(); // Jump to application sector
|
||||
}
|
||||
}
|
||||
TCCR1B = 0; // timer off
|
||||
send_boot();
|
||||
|
||||
#elif defined(START_BOOTICE)
|
||||
#warning "BOOTICE mode - no startup-condition"
|
||||
#elif defined(START_BOOTICE)
|
||||
#warning "BOOTICE mode - no startup-condition"
|
||||
|
||||
#else
|
||||
#error "Select START_ condition for bootloader in main.c"
|
||||
#endif
|
||||
#else
|
||||
#error "Select START_ condition for bootloader in main.c"
|
||||
#endif
|
||||
|
||||
for(;;)
|
||||
{
|
||||
val=recchar();
|
||||
for(;;) {
|
||||
val = recchar();
|
||||
// Autoincrement?
|
||||
if (val == 'a') {
|
||||
sendchar('Y'); // Autoincrement is quicker
|
||||
|
||||
if(val=='a') //Autoincrement?
|
||||
{
|
||||
sendchar('Y'); //Autoincrement is quicker
|
||||
}
|
||||
//write address
|
||||
} else if (val == 'A') {
|
||||
address = recchar(); //read address 8 MSB
|
||||
address = (address<<8) | recchar();
|
||||
|
||||
else if(val=='A') //write address
|
||||
{
|
||||
address=recchar(); //read address 8 MSB
|
||||
address=(address<<8)|recchar();
|
||||
|
||||
address=address<<1; // !! convert from word address to byte address
|
||||
address = address<<1; // !! convert from word address to byte address
|
||||
sendchar('\r');
|
||||
}
|
||||
|
||||
else if(val=='b')
|
||||
{ // Buffer load support
|
||||
// Buffer load support
|
||||
} else if (val == 'b') {
|
||||
sendchar('Y'); // Report buffer load supported
|
||||
sendchar((UART_RX_BUFFER_SIZE >> 8) & 0xFF);
|
||||
// Report buffer size in bytes
|
||||
sendchar((UART_RX_BUFFER_SIZE >> 8) & 0xFF); // Report buffer size in bytes
|
||||
sendchar(UART_RX_BUFFER_SIZE & 0xFF);
|
||||
}
|
||||
|
||||
else if(val=='B') // Start buffer load
|
||||
{
|
||||
tempi = recchar() << 8; // Load high byte of buffersize
|
||||
// Start buffer load
|
||||
} else if (val == 'B') {
|
||||
tempi = recchar() << 8; // Load high byte of buffersize
|
||||
tempi |= recchar(); // Load low byte of buffersize
|
||||
val = recchar(); // Load memory type ('E' or 'F')
|
||||
sendchar (BufferLoad(tempi,val));
|
||||
// Start downloading of buffer
|
||||
}
|
||||
sendchar (BufferLoad(tempi, val)); // Start downloading of buffer
|
||||
|
||||
else if(val == 'g') // Block read
|
||||
{
|
||||
// Block read
|
||||
} else if (val == 'g') {
|
||||
tempi = (recchar() << 8) | recchar();
|
||||
|
||||
val = recchar(); // Get memtype
|
||||
BlockRead(tempi,val); // Perform the block read
|
||||
}
|
||||
BlockRead(tempi, val); // Perform the block read
|
||||
|
||||
else if(val=='e') //Chip erase
|
||||
{
|
||||
if (device == devtype)
|
||||
{
|
||||
// Chip erase
|
||||
} else if (val == 'e') {
|
||||
if (device == devtype) {
|
||||
// erase only main section (bootloader protection)
|
||||
address = 0;
|
||||
while ( APP_END > address )
|
||||
{
|
||||
while (APP_END > address) {
|
||||
boot_page_erase(address); // Perform page erase
|
||||
boot_spm_busy_wait(); // Wait until the memory is erased.
|
||||
address += SPM_PAGESIZE;
|
||||
|
@ -306,215 +405,89 @@ int main(void)
|
|||
}
|
||||
boot_rww_enable();
|
||||
sendchar('\r');
|
||||
}
|
||||
|
||||
else if(val=='E') //Exit upgrade
|
||||
{
|
||||
// Exit upgrade
|
||||
} else if (val == 'E') {
|
||||
wdt_enable(WDTO_15MS); // Enable Watchdog Timer to give reset
|
||||
sendchar('\r');
|
||||
}
|
||||
|
||||
#ifdef WRITELOCKBITS
|
||||
#warning "Extension 'WriteLockBits' enabled"
|
||||
// TODO: does not work reliably
|
||||
else if(val=='l') // write lockbits
|
||||
{
|
||||
if (device == devtype)
|
||||
{
|
||||
#ifdef WRITELOCKBITS
|
||||
#warning "Extension 'WriteLockBits' enabled"
|
||||
// TODO: does not work reliably
|
||||
// write lockbits
|
||||
} else if (val == 'l') {
|
||||
if (device == devtype) {
|
||||
// write_lock_bits(recchar());
|
||||
boot_lock_bits_set(recchar()); // boot.h takes care of mask
|
||||
boot_spm_busy_wait();
|
||||
}
|
||||
sendchar('\r');
|
||||
}
|
||||
#endif
|
||||
|
||||
else if(val=='P') // Enter programming mode
|
||||
{
|
||||
#endif
|
||||
// Enter programming mode
|
||||
} else if (val == 'P') {
|
||||
sendchar('\r');
|
||||
}
|
||||
|
||||
else if(val=='L') // Leave programming mode
|
||||
{
|
||||
// Leave programming mode
|
||||
} else if (val == 'L') {
|
||||
sendchar('\r');
|
||||
}
|
||||
|
||||
else if (val=='p') // return programmer type
|
||||
{
|
||||
sendchar('S'); // always serial programmer
|
||||
}
|
||||
// return programmer type
|
||||
} else if (val == 'p') {
|
||||
sendchar('S'); // always serial programmer
|
||||
|
||||
#ifdef ENABLEREADFUSELOCK
|
||||
#warning "Extension 'ReadFuseLock' enabled"
|
||||
else if(val=='F') // read "low" fuse bits
|
||||
{
|
||||
sendchar( read_fuse_lock(0x0000, _BV(BLBSET)|_BV(SPMEN)) );
|
||||
}
|
||||
// read "low" fuse bits
|
||||
} else if (val == 'F') {
|
||||
sendchar(read_fuse_lock(0x0000, _BV(BLBSET) | _BV(SPMEN)));
|
||||
|
||||
else if(val=='r') // read lock bits
|
||||
{
|
||||
sendchar( read_fuse_lock(0x0001, _BV(BLBSET)|_BV(SPMEN)) );
|
||||
}
|
||||
// read lock bits
|
||||
} else if (val == 'r') {
|
||||
sendchar(read_fuse_lock(0x0001, _BV(BLBSET) | _BV(SPMEN)));
|
||||
|
||||
else if(val=='N') // read high fuse bits
|
||||
{
|
||||
sendchar( read_fuse_lock(0x0003,_BV(BLBSET)|_BV(SPMEN)) );
|
||||
}
|
||||
// read high fuse bits
|
||||
} else if (val == 'N') {
|
||||
sendchar(read_fuse_lock(0x0003, _BV(BLBSET) | _BV(SPMEN)));
|
||||
|
||||
else if(val=='Q') // read extended fuse bits
|
||||
{
|
||||
sendchar( read_fuse_lock(0x0002,_BV(BLBSET)|_BV(SPMEN)) );
|
||||
}
|
||||
// read extended fuse bits
|
||||
} else if (val == 'Q') {
|
||||
sendchar(read_fuse_lock(0x0002, _BV(BLBSET) | _BV(SPMEN)));
|
||||
#endif
|
||||
// end of ENABLEREADFUSELOCK section
|
||||
|
||||
else if(val=='t') // Return device type
|
||||
{
|
||||
// Return device type
|
||||
} else if (val == 't') {
|
||||
sendchar(devtype);
|
||||
sendchar(0);
|
||||
}
|
||||
|
||||
else if ((val=='x')||(val=='y')) // clear and set LED ignored
|
||||
{
|
||||
// clear and set LED ignored
|
||||
} else if ((val == 'x') || (val == 'y')) {
|
||||
recchar();
|
||||
sendchar('\r');
|
||||
}
|
||||
|
||||
else if (val=='T') // set device
|
||||
{
|
||||
// set device
|
||||
} else if (val == 'T') {
|
||||
device = recchar();
|
||||
sendchar('\r');
|
||||
}
|
||||
|
||||
else if (val=='S') // Return software identifier
|
||||
{
|
||||
// Return software identifier
|
||||
} else if (val == 'S') {
|
||||
send_boot();
|
||||
}
|
||||
|
||||
else if (val=='V') // Return Software Version
|
||||
{
|
||||
// Return Software Version
|
||||
} else if (val == 'V') {
|
||||
sendchar(VERSION_HIGH);
|
||||
sendchar(VERSION_LOW);
|
||||
}
|
||||
|
||||
else if (val=='s') // Return Signature Byte
|
||||
{
|
||||
// Return Signature Byte
|
||||
} else if (val == 's') {
|
||||
sendchar(sig_byte1);
|
||||
sendchar(sig_byte2);
|
||||
sendchar(sig_byte3);
|
||||
}
|
||||
|
||||
else if(val != 0x1b) /* ESC */
|
||||
{
|
||||
/* ESC */
|
||||
} else if(val != 0x1b) {
|
||||
sendchar('?');
|
||||
}
|
||||
} // end of "parser" for-loop
|
||||
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned char BufferLoad(unsigned int size, unsigned char mem)
|
||||
{
|
||||
unsigned int data, cnt;
|
||||
uint32_t tempaddress;
|
||||
|
||||
for (cnt=0; cnt<UART_RX_BUFFER_SIZE; cnt++) {
|
||||
if (cnt<size) gBuffer[cnt]=recchar();
|
||||
else gBuffer[cnt]=0xFF;
|
||||
}
|
||||
cnt=0;
|
||||
|
||||
tempaddress = address; // Store address in page
|
||||
|
||||
my_eeprom_busy_wait();
|
||||
|
||||
if (device == devtype)
|
||||
{
|
||||
if (mem == 'F') // Flash
|
||||
{
|
||||
do {
|
||||
data=gBuffer[cnt++];
|
||||
data|=(gBuffer[cnt++]<<8);
|
||||
boot_page_fill(address,data);
|
||||
//call asm routine.
|
||||
address=address+2; // Select next word in memory
|
||||
size -= 2; // Reduce number of bytes to write by two
|
||||
} while(size); // Loop until all bytes written
|
||||
|
||||
/* commented out since not compatible with mega8 -
|
||||
secondary benefit: saves memory
|
||||
tempaddress &= 0xFF80; // Ensure the address points to the first byte in the page
|
||||
*/
|
||||
|
||||
boot_page_write(tempaddress);
|
||||
boot_spm_busy_wait();
|
||||
boot_rww_enable(); //Re-enable the RWW section
|
||||
|
||||
/* commented out since not compatible with mega8
|
||||
if (address != (address & 0xFF80))
|
||||
{ // Ensure that the address points to the beginning of the next page
|
||||
address &= 0xFF80;
|
||||
address += SPM_PAGESIZE;
|
||||
}
|
||||
*/
|
||||
} // End FLASH
|
||||
|
||||
if (mem == 'E') // Start EEPROM
|
||||
{
|
||||
address>>=1;
|
||||
do {
|
||||
EEARL = address; // Setup EEPROM address
|
||||
EEARH = (address >> 8);
|
||||
address++; // Select next byte
|
||||
EEDR=gBuffer[cnt++];
|
||||
|
||||
EECR |= (1<<EEMWE); // Write data into EEPROM
|
||||
EECR |= (1<<EEWE);
|
||||
|
||||
while (EECR & (1<<EEWE)); // Wait for EEPROM write to finish
|
||||
size--; // Decreas number of bytes to write
|
||||
} while(size); // Loop until all bytes written
|
||||
|
||||
}
|
||||
|
||||
return '\r'; // Report programming OK
|
||||
|
||||
}
|
||||
|
||||
return 0; // Report programming failed
|
||||
}
|
||||
|
||||
void BlockRead(unsigned int size, unsigned char mem)
|
||||
{
|
||||
unsigned int data;
|
||||
|
||||
my_eeprom_busy_wait();
|
||||
|
||||
if (mem == 'E') // Read EEPROM
|
||||
{
|
||||
// address>>=1; // not needed here - hmm, somehow inconsistant TODO
|
||||
do {
|
||||
EEARL = address; // Setup EEPROM address
|
||||
EEARH = (address >> 8);
|
||||
address++; // Select next EEPROM byte
|
||||
EECR |= (1<<EERE); // Read EEPROM
|
||||
sendchar(EEDR); // Transmit EEPROM data to PC
|
||||
size--; // Decrease number of bytes to read
|
||||
} while (size); // Repeat until all block has been read
|
||||
}
|
||||
else // Read Flash
|
||||
{
|
||||
do {
|
||||
#if defined(RAMPZ)
|
||||
data = pgm_read_word_far(address);
|
||||
#else
|
||||
data = pgm_read_word_near((uint16_t)address);
|
||||
#endif
|
||||
sendchar((unsigned char)data); //send LSB
|
||||
sendchar((unsigned char)(data >> 8)); //send MSB
|
||||
address += 2; // Select next word in memory
|
||||
size -= 2; // Subtract two bytes from number of bytes to read
|
||||
} while (size); // Repeat until all block has been read
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue