new protocol
This commit is contained in:
parent
b39087eb8e
commit
e013aea33c
260
main.c
260
main.c
@ -1,5 +1,5 @@
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 09/2007 by Olaf Rempel *
|
* Copyright (C) 07/2010 by Olaf Rempel *
|
||||||
* razzor@kopf-tisch.de *
|
* razzor@kopf-tisch.de *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
@ -24,66 +24,102 @@
|
|||||||
#define F_CPU 8000000
|
#define F_CPU 8000000
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* atmega88:
|
||||||
|
* Fuse E: 0xfa (512 words bootloader)
|
||||||
|
* Fuse H: 0xdd (2.7V BOD)
|
||||||
|
* Fuse L: 0xc2 (8Mhz internal RC-Osz.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 25ms @8MHz */
|
||||||
|
#define TIMER_RELOAD (0xFF - 195)
|
||||||
|
|
||||||
|
/* 40 * 25ms */
|
||||||
|
#define TIMEOUT 40
|
||||||
|
|
||||||
#define LED_RT (1<<PORTB4)
|
#define LED_RT (1<<PORTB4)
|
||||||
#define LED_GN (1<<PORTB5)
|
#define LED_GN (1<<PORTB5)
|
||||||
|
|
||||||
#define TWI_ADDRESS 0x21
|
#define TWI_ADDRESS 0x21
|
||||||
|
|
||||||
#define COOKIE 0x4711
|
|
||||||
#define APP_END 0x1C00
|
#define APP_END 0x1C00
|
||||||
|
|
||||||
|
#define VERSION_STRING "TWIBOOT m88-v20"
|
||||||
|
#define SIGNATURE_BYTES { 0x1E, 0x93, 0x0A, 0x00 }
|
||||||
|
|
||||||
|
/* SLA+R */
|
||||||
#define CMD_WAIT 0x00
|
#define CMD_WAIT 0x00
|
||||||
#define CMD_GET_INFO 0x10
|
#define CMD_READ_VERSION 0x01
|
||||||
#define CMD_GET_SIGNATURE 0x11
|
#define CMD_READ_MEMORY 0x02
|
||||||
#define CMD_WRITE_FLASH 0x12
|
/* internal mappings */
|
||||||
#define CMD_READ_FLASH 0x13
|
#define CMD_READ_SIGNATURE (0x10 | CMD_READ_MEMORY)
|
||||||
#define CMD_WRITE_EEPROM 0x14
|
#define CMD_READ_FLASH (0x20 | CMD_READ_MEMORY)
|
||||||
#define CMD_READ_EEPROM 0x15
|
#define CMD_READ_EEPROM (0x30 | CMD_READ_MEMORY)
|
||||||
#define CMD_BOOT_APPLICATION 0x1F
|
#define CMD_READ_PARAMETERS (0x40 | CMD_READ_MEMORY) /* only in APP */
|
||||||
|
|
||||||
|
/* SLA+W */
|
||||||
|
#define CMD_SWITCH_APPLICATION CMD_READ_VERSION
|
||||||
|
#define CMD_WRITE_MEMORY CMD_READ_MEMORY
|
||||||
|
/* internal mappings */
|
||||||
|
#define CMD_BOOT_BOOTLOADER (0x10 | CMD_SWITCH_APPLICATION) /* only in APP */
|
||||||
|
#define CMD_BOOT_APPLICATION (0x20 | CMD_SWITCH_APPLICATION)
|
||||||
|
#define CMD_WRITE_SIGNATURE (0x10 | CMD_WRITE_MEMORY)
|
||||||
|
#define CMD_WRITE_FLASH (0x20 | CMD_WRITE_MEMORY)
|
||||||
|
#define CMD_WRITE_EEPROM (0x30 | CMD_WRITE_MEMORY)
|
||||||
|
#define CMD_WRITE_PARAMETERS (0x40 | CMD_WRITE_MEMORY) /* only in APP */
|
||||||
|
|
||||||
|
/* CMD_SWITCH_APPLICATION parameter */
|
||||||
|
#define BOOTTYPE_BOOTLOADER 0x00 /* only in APP */
|
||||||
|
#define BOOTTYPE_APPLICATION 0x80
|
||||||
|
|
||||||
|
/* CMD_{READ|WRITE}_* parameter */
|
||||||
|
#define MEMTYPE_SIGNATURE 0x00
|
||||||
|
#define MEMTYPE_FLASH 0x01
|
||||||
|
#define MEMTYPE_EEPROM 0x02
|
||||||
|
#define MEMTYPE_PARAMETERS 0x03 /* only in APP */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LED on PORTB4 blinks with 20Hz (while bootloader is running)
|
* LED_GN blinks with 20Hz (while bootloader is running)
|
||||||
* LED on PORTB5 blinks on TWI activity
|
* LED_RT blinks on TWI activity
|
||||||
*
|
|
||||||
* Fuse E: 0xfa (512 words bootloader)
|
|
||||||
* Fuse H: 0xdd (2.7V BOD)
|
|
||||||
* Fuse L: 0xc2 (8Mhz internal RC-Osz.)
|
|
||||||
*
|
*
|
||||||
* bootloader twi-protocol:
|
* bootloader twi-protocol:
|
||||||
* - get info about bootloader:
|
* - abort boot timeout:
|
||||||
* SLA+W, 0x10, SLA+R, {16 bytes}, STO
|
* SLA+W, 0x00, STO
|
||||||
*
|
*
|
||||||
* - get signature bytes:
|
* - show bootloader version
|
||||||
* SLA+W, 0x11, SLA+R, {4 bytes}, STO
|
* SLA+W, 0x01, SLA+R, {16 bytes}, STO
|
||||||
*
|
*
|
||||||
* - write one flash page (64bytes on mega8)
|
* - start application
|
||||||
* SLA+W, 0x12, addrh, addrl, 0x47, 0x11, {64 bytes}, STO
|
* SLA+W, 0x01, 0x80, STO
|
||||||
|
*
|
||||||
|
* - read signature bytes
|
||||||
|
* SLA+W, 0x02, 0x00, SLA+R, {4 bytes}, STO
|
||||||
*
|
*
|
||||||
* - read one (or more) flash bytes
|
* - read one (or more) flash bytes
|
||||||
* SLA+W, 0x13, addrh, addrl, SLA+R, {* bytes}, STO
|
* SLA+W, 0x02, 0x01, addrh, addrl, SLA+R, {* bytes}, STO
|
||||||
*
|
|
||||||
* - write one (or more) eeprom bytes
|
|
||||||
* SLA+W, 0x14, addrh, addrl, 0x47, 0x11, {* bytes}, STO
|
|
||||||
*
|
*
|
||||||
* - read one (or more) eeprom bytes
|
* - read one (or more) eeprom bytes
|
||||||
* SLA+W, 0x15, addrh, addrl, SLA+R, {* bytes}, STO
|
* SLA+W, 0x02, 0x02, addrh, addrl, SLA+R, {* bytes}, STO
|
||||||
*
|
*
|
||||||
* - boot application
|
* - write one flash page (64bytes on mega8)
|
||||||
* SLA+W, 0x1F, STO
|
* SLA+W, 0x02, 0x01, addrh, addrl, {64 bytes}, STO
|
||||||
|
*
|
||||||
|
* - write one (or more) eeprom bytes
|
||||||
|
* SLA+W, 0x02, 0x02, addrh, addrl, {* bytes}, STO
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const static uint8_t info[16] = "TWIBOOT m88-v12";
|
const static uint8_t info[16] = VERSION_STRING;
|
||||||
const static uint8_t signature[4] = { 0x1E, 0x93, 0x0A, 0x00 };
|
const static uint8_t signature[4] = SIGNATURE_BYTES;
|
||||||
|
|
||||||
/* wait 40 * 25ms = 1s */
|
/* wait 40 * 25ms = 1s */
|
||||||
static uint8_t boot_timeout = 40;
|
static uint8_t boot_timeout = TIMEOUT;
|
||||||
volatile static uint8_t cmd = CMD_WAIT;
|
volatile static uint8_t cmd = CMD_WAIT;
|
||||||
|
|
||||||
/* flash buffer */
|
/* flash buffer */
|
||||||
static uint8_t buf[SPM_PAGESIZE];
|
static uint8_t buf[SPM_PAGESIZE];
|
||||||
static uint16_t addr;
|
static uint16_t addr;
|
||||||
|
|
||||||
void write_flash_page(void)
|
static void write_flash_page(void)
|
||||||
{
|
{
|
||||||
uint16_t pagestart = addr;
|
uint16_t pagestart = addr;
|
||||||
uint8_t size = SPM_PAGESIZE;
|
uint8_t size = SPM_PAGESIZE;
|
||||||
@ -109,7 +145,16 @@ void write_flash_page(void)
|
|||||||
boot_rww_enable();
|
boot_rww_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_eeprom_byte(uint8_t val)
|
static uint8_t read_eeprom_byte(void)
|
||||||
|
{
|
||||||
|
EEARL = addr;
|
||||||
|
EEARH = (addr >> 8);
|
||||||
|
EECR |= (1<<EERE);
|
||||||
|
addr++;
|
||||||
|
return EEDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_eeprom_byte(uint8_t val)
|
||||||
{
|
{
|
||||||
EEARL = addr;
|
EEARL = addr;
|
||||||
EEARH = (addr >> 8);
|
EEARH = (addr >> 8);
|
||||||
@ -123,7 +168,9 @@ void write_eeprom_byte(uint8_t val)
|
|||||||
|
|
||||||
ISR(TWI_vect)
|
ISR(TWI_vect)
|
||||||
{
|
{
|
||||||
static uint8_t bcnt = 0;
|
static uint8_t bcnt;
|
||||||
|
uint8_t data;
|
||||||
|
uint8_t ack = (1<<TWEA);
|
||||||
|
|
||||||
switch (TWSR & 0xF8) {
|
switch (TWSR & 0xF8) {
|
||||||
/* SLA+W received, ACK returned -> receive data and ACK */
|
/* SLA+W received, ACK returned -> receive data and ACK */
|
||||||
@ -135,64 +182,87 @@ ISR(TWI_vect)
|
|||||||
|
|
||||||
/* prev. SLA+W, data received, ACK returned -> receive data and ACK */
|
/* prev. SLA+W, data received, ACK returned -> receive data and ACK */
|
||||||
case 0x80:
|
case 0x80:
|
||||||
if (bcnt == 0) {
|
data = TWDR;
|
||||||
cmd = TWDR;
|
switch (bcnt) {
|
||||||
switch (cmd) {
|
case 0:
|
||||||
case CMD_GET_INFO:
|
switch (data) {
|
||||||
case CMD_GET_SIGNATURE:
|
case CMD_SWITCH_APPLICATION:
|
||||||
case CMD_WRITE_FLASH:
|
case CMD_WRITE_MEMORY:
|
||||||
case CMD_READ_FLASH:
|
bcnt++;
|
||||||
case CMD_WRITE_EEPROM:
|
/* no break */
|
||||||
case CMD_READ_EEPROM:
|
|
||||||
|
case CMD_WAIT:
|
||||||
/* abort countdown */
|
/* abort countdown */
|
||||||
boot_timeout = 0;
|
boot_timeout = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
case CMD_BOOT_APPLICATION:
|
default:
|
||||||
|
/* boot app now */
|
||||||
|
data = CMD_BOOT_APPLICATION;
|
||||||
|
ack = (0<<TWEA);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cmd = data;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
switch (cmd) {
|
||||||
|
case CMD_SWITCH_APPLICATION:
|
||||||
|
if (data == BOOTTYPE_APPLICATION) {
|
||||||
|
cmd = CMD_BOOT_APPLICATION;
|
||||||
|
}
|
||||||
|
ack = (0<<TWEA);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CMD_WRITE_MEMORY:
|
||||||
|
bcnt++;
|
||||||
|
if (data == MEMTYPE_SIGNATURE) {
|
||||||
|
cmd = CMD_WRITE_SIGNATURE;
|
||||||
|
|
||||||
|
} else if (data == MEMTYPE_FLASH) {
|
||||||
|
cmd = CMD_WRITE_FLASH;
|
||||||
|
|
||||||
|
} else if (data == MEMTYPE_EEPROM) {
|
||||||
|
cmd = CMD_WRITE_EEPROM;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ack = (0<<TWEA);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
addr <<= 8;
|
||||||
|
addr |= data;
|
||||||
bcnt++;
|
bcnt++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
cmd = CMD_WAIT;
|
switch (cmd) {
|
||||||
bcnt = 0;
|
case CMD_WRITE_FLASH:
|
||||||
|
buf[bcnt -4] = data;
|
||||||
|
if (bcnt < sizeof(buf) +3) {
|
||||||
|
bcnt++;
|
||||||
|
} else {
|
||||||
|
write_flash_page();
|
||||||
|
ack = (0<<TWEA);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CMD_WRITE_EEPROM:
|
||||||
|
write_eeprom_byte(data);
|
||||||
|
bcnt++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (bcnt == 1) {
|
if (ack == 0x00)
|
||||||
addr = (TWDR << 8);
|
|
||||||
bcnt++;
|
|
||||||
|
|
||||||
} else if (bcnt == 2) {
|
|
||||||
addr |= TWDR;
|
|
||||||
bcnt++;
|
|
||||||
|
|
||||||
} else if (bcnt == 3) {
|
|
||||||
if (TWDR == (COOKIE >> 8))
|
|
||||||
bcnt++;
|
|
||||||
else
|
|
||||||
bcnt = 0;
|
bcnt = 0;
|
||||||
|
|
||||||
} else if (bcnt == 4) {
|
TWCR |= (1<<TWINT) | ack;
|
||||||
if (TWDR == (COOKIE & 0xFF))
|
|
||||||
bcnt++;
|
|
||||||
else
|
|
||||||
bcnt = 0;
|
|
||||||
|
|
||||||
} else if (bcnt >= 5 && cmd == CMD_WRITE_FLASH) {
|
|
||||||
buf[bcnt -5] = TWDR;
|
|
||||||
if (bcnt < sizeof(buf) +4) {
|
|
||||||
bcnt++;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
write_flash_page();
|
|
||||||
bcnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (bcnt >= 5 && cmd == CMD_WRITE_EEPROM) {
|
|
||||||
write_eeprom_byte(TWDR);
|
|
||||||
bcnt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
TWCR |= (1<<TWINT) | (1<<TWEA);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* SLA+R received, ACK returned -> send data */
|
/* SLA+R received, ACK returned -> send data */
|
||||||
@ -203,33 +273,30 @@ ISR(TWI_vect)
|
|||||||
/* prev. SLA+R, data sent, ACK returned -> send data */
|
/* prev. SLA+R, data sent, ACK returned -> send data */
|
||||||
case 0xB8:
|
case 0xB8:
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case CMD_GET_INFO:
|
case CMD_READ_VERSION:
|
||||||
TWDR = info[bcnt++];
|
data = info[bcnt++];
|
||||||
bcnt %= sizeof(info);
|
bcnt %= sizeof(info);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_GET_SIGNATURE:
|
case CMD_READ_SIGNATURE:
|
||||||
TWDR = signature[bcnt++];
|
data = signature[bcnt++];
|
||||||
bcnt %= sizeof(signature);
|
bcnt %= sizeof(signature);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_READ_FLASH:
|
case CMD_READ_FLASH:
|
||||||
TWDR = pgm_read_byte_near(addr++);
|
data = pgm_read_byte_near(addr++);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_READ_EEPROM:
|
case CMD_READ_EEPROM:
|
||||||
EEARL = addr;
|
data = read_eeprom_byte();
|
||||||
EEARH = (addr >> 8);
|
|
||||||
EECR |= (1<<EERE);
|
|
||||||
addr++;
|
|
||||||
TWDR = EEDR;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
TWDR = 0xFF;
|
data = 0xFF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TWDR = data;
|
||||||
TWCR |= (1<<TWINT) | (1<<TWEA);
|
TWCR |= (1<<TWINT) | (1<<TWEA);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -250,8 +317,8 @@ ISR(TWI_vect)
|
|||||||
|
|
||||||
ISR(TIMER0_OVF_vect)
|
ISR(TIMER0_OVF_vect)
|
||||||
{
|
{
|
||||||
/* come back in 25ms (@8MHz) */
|
/* restart timer */
|
||||||
TCNT0 = 0xFF - 195;
|
TCNT0 = TIMER_RELOAD;
|
||||||
|
|
||||||
/* blink LED while running */
|
/* blink LED while running */
|
||||||
PORTB ^= LED_GN;
|
PORTB ^= LED_GN;
|
||||||
@ -316,10 +383,9 @@ int main(void)
|
|||||||
|
|
||||||
PORTB = 0x00;
|
PORTB = 0x00;
|
||||||
|
|
||||||
_delay_ms(25);
|
uint8_t i;
|
||||||
_delay_ms(25);
|
for (i = 0; i < 10; i++)
|
||||||
_delay_ms(25);
|
_delay_ms(10);
|
||||||
_delay_ms(25);
|
|
||||||
|
|
||||||
jump_to_app();
|
jump_to_app();
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user