Split TWI handling into read/write functions

This commit is contained in:
Olaf Rempel 2019-11-03 08:58:02 +01:00
parent 1418971648
commit eee017dedf
2 changed files with 152 additions and 139 deletions

View File

@ -10,10 +10,10 @@ Currently the following AVR MCUs are supported:
AVR MCU | Flash bytes used (.text + .data) | Bootloader region size AVR MCU | Flash bytes used (.text + .data) | Bootloader region size
--- | --- | --- --- | --- | ---
atmega8 | 900 (0x384) | 512 words atmega8 | 868 (0x364) | 512 words
atmega88 | 950 (0x3B6) | 512 words atmega88 | 920 (0x398) | 512 words
atmega168 | 1002 (0x3EA) | 512 words atmega168 | 972 (0x3CC) | 512 words
atmega328p | 1002 (0x3EA) | 512 words atmega328p | 972 (0x3CC) | 512 words
(Compiled on Ubuntu 18.04 LTS (gcc 5.4.0 / avr-libc 2.0.0) with EEPROM and LED support) (Compiled on Ubuntu 18.04 LTS (gcc 5.4.0 / avr-libc 2.0.0) with EEPROM and LED support)

109
main.c
View File

@ -210,26 +210,11 @@ static void write_eeprom_byte(uint8_t val)
/* ************************************************************************* /* *************************************************************************
* TWI_vect * TWI_data_write
* ************************************************************************* */ * ************************************************************************* */
ISR(TWI_vect) static uint8_t TWI_data_write(uint8_t bcnt, uint8_t data)
{ {
static uint8_t bcnt; uint8_t ack = 0x01;
uint8_t data;
uint8_t ack = (1<<TWEA);
switch (TWSR & 0xF8)
{
/* SLA+W received, ACK returned -> receive data and ACK */
case 0x60:
bcnt = 0;
LED_RT_ON();
TWCR |= (1<<TWINT) | (1<<TWEA);
break;
/* prev. SLA+W, data received, ACK returned -> receive data and ACK */
case 0x80:
data = TWDR;
switch (bcnt) switch (bcnt)
{ {
@ -238,7 +223,6 @@ ISR(TWI_vect)
{ {
case CMD_SWITCH_APPLICATION: case CMD_SWITCH_APPLICATION:
case CMD_WRITE_MEMORY: case CMD_WRITE_MEMORY:
bcnt++;
/* no break */ /* no break */
case CMD_WAIT: case CMD_WAIT:
@ -249,7 +233,7 @@ ISR(TWI_vect)
default: default:
/* boot app now */ /* boot app now */
cmd = CMD_BOOT_APPLICATION; cmd = CMD_BOOT_APPLICATION;
ack = (0<<TWEA); ack = 0x00;
break; break;
} }
@ -265,11 +249,10 @@ ISR(TWI_vect)
cmd = CMD_BOOT_APPLICATION; cmd = CMD_BOOT_APPLICATION;
} }
ack = (0<<TWEA); ack = 0x00;
break; break;
case CMD_WRITE_MEMORY: case CMD_WRITE_MEMORY:
bcnt++;
if (data == MEMTYPE_CHIPINFO) if (data == MEMTYPE_CHIPINFO)
{ {
cmd = CMD_WRITE_CHIPINFO; cmd = CMD_WRITE_CHIPINFO;
@ -286,12 +269,12 @@ ISR(TWI_vect)
#endif /* (EEPROM_SUPPORT) */ #endif /* (EEPROM_SUPPORT) */
else else
{ {
ack = (0<<TWEA); ack = 0x00;
} }
break; break;
default: default:
ack = (0<<TWEA); ack = 0x00;
break; break;
} }
break; break;
@ -300,7 +283,6 @@ ISR(TWI_vect)
case 3: case 3:
addr <<= 8; addr <<= 8;
addr |= data; addr |= data;
bcnt++;
break; break;
default: default:
@ -308,56 +290,47 @@ ISR(TWI_vect)
{ {
case CMD_WRITE_FLASH: case CMD_WRITE_FLASH:
buf[bcnt -4] = data; buf[bcnt -4] = data;
if (bcnt < sizeof(buf) +3) if (bcnt >= sizeof(buf) +3)
{
bcnt++;
}
else
{ {
write_flash_page(); write_flash_page();
ack = (0<<TWEA); ack = 0x00;
} }
break; break;
#if (EEPROM_SUPPORT) #if (EEPROM_SUPPORT)
case CMD_WRITE_EEPROM: case CMD_WRITE_EEPROM:
write_eeprom_byte(data); write_eeprom_byte(data);
bcnt++;
break; break;
#endif /* (EEPROM_SUPPORT) */ #endif /* (EEPROM_SUPPORT) */
default: default:
ack = (0<<TWEA); ack = 0x00;
break; break;
} }
break; break;
} }
if (ack == 0x00) return ack;
{ } /* TWI_data_write */
bcnt = 0;
}
TWCR |= (1<<TWINT) | ack;
break;
/* SLA+R received, ACK returned -> send data */ /* *************************************************************************
case 0xA8: * TWI_data_read
bcnt = 0; * ************************************************************************* */
LED_RT_ON(); static uint8_t TWI_data_read(uint8_t bcnt)
{
uint8_t data;
/* prev. SLA+R, data sent, ACK returned -> send data */
case 0xB8:
switch (cmd) switch (cmd)
{ {
case CMD_READ_VERSION: case CMD_READ_VERSION:
data = info[bcnt++];
bcnt %= sizeof(info); bcnt %= sizeof(info);
data = info[bcnt];
break; break;
case CMD_READ_CHIPINFO: case CMD_READ_CHIPINFO:
data = chipinfo[bcnt++];
bcnt %= sizeof(chipinfo); bcnt %= sizeof(chipinfo);
data = chipinfo[bcnt];
break; break;
case CMD_READ_FLASH: case CMD_READ_FLASH:
@ -375,7 +348,47 @@ ISR(TWI_vect)
break; break;
} }
TWDR = data; return data;
} /* TWI_data_read */
/* *************************************************************************
* TWI_vect
* ************************************************************************* */
ISR(TWI_vect)
{
static uint8_t bcnt;
switch (TWSR & 0xF8)
{
/* SLA+W received, ACK returned -> receive data and ACK */
case 0x60:
bcnt = 0;
LED_RT_ON();
TWCR |= (1<<TWINT) | (1<<TWEA);
break;
/* prev. SLA+W, data received, ACK returned -> receive data and ACK */
case 0x80:
if (TWI_data_write(bcnt++, TWDR))
{
TWCR |= (1<<TWINT) | (1<<TWEA);
}
else
{
TWCR |= (1<<TWINT);
bcnt = 0;
}
break;
/* SLA+R received, ACK returned -> send data */
case 0xA8:
bcnt = 0;
LED_RT_ON();
/* prev. SLA+R, data sent, ACK returned -> send data */
case 0xB8:
TWDR = TWI_data_read(bcnt++);
TWCR |= (1<<TWINT) | (1<<TWEA); TWCR |= (1<<TWINT) | (1<<TWEA);
break; break;