From 2e14fe9090a9bced63f75f20d1ff5b8e5c5f06cb Mon Sep 17 00:00:00 2001 From: Olaf Rempel Date: Sun, 11 Aug 2019 11:10:18 +0200 Subject: [PATCH] working version --- main.c | 395 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 272 insertions(+), 123 deletions(-) diff --git a/main.c b/main.c index edfa054..855be47 100644 --- a/main.c +++ b/main.c @@ -21,8 +21,6 @@ #define F_CPU 8000000 #include -#define USE_HEX 0 - /* * attiny2313 * lfuse: 0xe4 (int rc osc, max startup time) @@ -50,15 +48,65 @@ #define nWRITE PORTD5 #define nREAD PORTD6 -#define PAGE_SIZE 64 - #define BAUDRATE 115200 #define UART_CALC_BAUDRATE(baudRate) (((uint32_t)F_CPU) / (((uint32_t)baudRate)*16) -1) #define NOP asm volatile ("nop") -static uint16_t g_address; +/* ************************************************************************* */ + +#define MSGTYPE_VERSION_REQ 0x01 /* no payload */ +#define MSGTYPE_PAGESIZE_REQ 0x02 /* no payload */ +#define MSGTYPE_CONFIG_REQ 0x03 /* eprom_type(1), pagesize(1), reset_polarity(1) */ +#define MSGTYPE_PROGMODE_REQ 0x04 /* progmode(1) */ +#define MSGTYPE_SETADDRESS_REQ 0x05 /* address(3) msb first */ +#define MSGTYPE_WRITE_REQ 0x06 /* data(0-pagesize) */ +#define MSGTYPE_READ_REQ 0x07 /* length(1) */ + +#define MSGTYPE_ERROR_RSP 0x80 /* error_code(1) */ +#define MSGTYPE_VERSION_RSP 0x81 /* version(?) */ +#define MSGTYPE_PAGESIZE_RSP 0x82 /* pagesize(1) */ +#define MSGTYPE_CONFIG_RSP 0x83 /* no payload */ +#define MSGTYPE_PROGMODE_RSP 0x84 /* no payload */ +#define MSGTYPE_SETADDRESS_RSP 0x85 /* no payload */ +#define MSGTYPE_WRITE_RSP 0x86 /* no payload */ +#define MSGTYPE_READ_RSP 0x87 /* data(0-pagesize) */ + +#define SUCCESS 0x00 +#define ERROR_UNKNOWN_COMMAND 0x01 /* unknown message type */ +#define ERROR_NOT_SUPPORTED 0x02 /* command not supported */ +#define ERROR_INVALID_MODE 0x03 /* invalid progmode */ +#define ERROR_INVALID_PARAMETER 0x04 /* invalid parameter in request */ +#define ERROR_INVALID_ADDRESS 0x05 /* write outside of configured region */ + +#define RESET_POLARITY_LOW 0x00 /* low active reset */ +#define RESET_POLARITY_HIGH 0x01 /* high active reset */ + +#define EPROM_TYPE_2K 0x02 /* 2716 */ +#define EPROM_TYPE_4K 0x04 /* 2732 */ +#define EPROM_TYPE_8K 0x08 /* 2764 */ +#define EPROM_TYPE_16K 0x10 /* 27128 */ +#define EPROM_TYPE_32K 0x20 /* 27256 */ +#define EPROM_TYPE_64K 0x40 /* 27512 */ +#define EPROM_TYPE_128K 0x80 /* 27010 */ + +#define PROGMODE_DISABLED 0x00 /* target running, no write access to RAM */ +#define PROGMODE_ENABLED 0x01 /* target reset, write access to RAM */ + +#define PAGESIZE_MAX 64 + +/* ************************************************************************* */ + +struct _globdata { + uint32_t address_max; + uint32_t address; + uint8_t progmode; + uint8_t pagesize; +}; + +static const uint8_t version_str[] = "e2prog v1.00"; +static struct _globdata gdata = { 0 }; /* ************************************************************************* * send one byte to UART @@ -80,71 +128,6 @@ static uint8_t ser_recv(void) } /* ser_recv */ -#if (USE_HEX) -/* ************************************************************************* - * - * ************************************************************************* */ -static void ser_send_hexnibble(uint8_t value) -{ - value += (value < 0x0A) ? '0' : ('A' - 0x0A); - - ser_send(value); -} /* ser_send_hexnibble */ - - -/* ************************************************************************* - * - * ************************************************************************* */ -static void ser_send_hex(uint8_t value) -{ - ser_send_hexnibble(value >> 4); - ser_send_hexnibble(value & 0x0F); -} /* ser_send_hex */ - - -/* ************************************************************************* - * - * ************************************************************************* */ -static uint8_t ascii2hexnibble(uint8_t value) -{ - if (value >= '0' && value <= '9') - { - return (value - '0'); - } - else - { - value &= ~(0x20); - if (value >= 'A' && value <= 'F') - { - return (value - 'A' + 0x0A); - } - } - - return 0; -} /* ascii2hexnibble */ - - -/* ************************************************************************* - * - * ************************************************************************* */ -static uint8_t ser_recv_hex(void) -{ - uint8_t result; - - result = ascii2hexnibble(ser_recv()) << 4; - result |= ascii2hexnibble(ser_recv()); - - return result; -} /* ser_recv_hex */ - -#define ser_send_comm(x) ser_send_hex(x) -#define ser_recv_comm() ser_recv_hex() -#else -#define ser_send_comm(x) ser_send(x) -#define ser_recv_comm() ser_recv() -#endif /* (USE_HEX) */ - - /* ************************************************************************* * * ************************************************************************* */ @@ -160,23 +143,19 @@ static void address_clear(void) NOP; PORTD &= ~(1< address) + if (gdata.address > address) { /* reset address counter */ PORTA &= ~(1<> 8); -// ser_send_hex(address & 0xFF); + gdata.address = address; } /* address_set */ @@ -225,25 +201,61 @@ static void address_inc(void) NOP; PORTD &= ~(1< PAGE_SIZE) + for (i = 0; i < length; i++) { - count = PAGE_SIZE; - } - - for (i = 0; i < count; i++) - { - buffer[i] = ser_recv_comm(); + buffer[i] = ser_recv(); } DDRB = 0xFF; - for (i = 0; i < count; i++) + for (i = 0; i < length; i++) { PORTB = buffer[i]; @@ -309,7 +313,7 @@ static void data_write(void) PORTD |= (1< start polling */ - if ((g_address & (sizeof(buffer) -1)) == (sizeof(buffer) -1)) + if ((gdata.address & (gdata.pagesize -1)) == (gdata.pagesize -1)) { data_poll(buffer[i]); DDRB = 0xFF; @@ -318,6 +322,8 @@ static void data_write(void) address_inc(); } + data_poll(buffer[length -1]); + DDRB = 0x00; PORTB = 0x00; } /* data_write */ @@ -351,37 +357,180 @@ int main(void) while (1) { - switch (ser_recv()) + uint8_t msgtype = ser_recv(); + uint8_t length = ser_recv(); + uint8_t error_code = ERROR_INVALID_PARAMETER; + + switch (msgtype) { - case 'a': - address_set(); - ser_send('\r'); - ser_send('\n'); + case MSGTYPE_VERSION_REQ: + if (length == 0x00) + { + ser_send(MSGTYPE_VERSION_RSP); + ser_send(sizeof(version_str) -1); + + const uint8_t * p_data = version_str; + while (*p_data) + { + ser_send(*p_data++); + } + + error_code = SUCCESS; + } break; - case 'b': - ser_send_comm(PAGE_SIZE); - ser_send('\r'); - ser_send('\n'); + case MSGTYPE_PAGESIZE_REQ: + if (length == 0x00) + { + ser_send(MSGTYPE_PAGESIZE_RSP); + ser_send(0x01); + ser_send(PAGESIZE_MAX); + + error_code = SUCCESS; + } break; - case 'r': - data_read(); - ser_send('\r'); - ser_send('\n'); + case MSGTYPE_CONFIG_REQ: + if (length == 0x03) + { + uint8_t eprom_type = ser_recv(); + uint8_t pagesize = ser_recv(); + + /* reset polarity not used on this target */ + ser_recv(); + + if (gdata.progmode == PROGMODE_ENABLED) + { + error_code = ERROR_INVALID_MODE; + } + else if ((pagesize <= PAGESIZE_MAX) && + (set_eprom_type(eprom_type) == SUCCESS) + ) + { + gdata.pagesize = pagesize; + + ser_send(MSGTYPE_CONFIG_RSP); + ser_send(0x00); + error_code = SUCCESS; + } + } break; - case 'w': - data_write(); - ser_send('\r'); - ser_send('\n'); + case MSGTYPE_PROGMODE_REQ: + if (length == 0x01) + { + uint8_t progmode = ser_recv(); + + if (progmode <= PROGMODE_ENABLED) + { + gdata.progmode = progmode; + + ser_send(MSGTYPE_PROGMODE_RSP); + ser_send(0x00); + error_code = SUCCESS; + } + } + break; + + case MSGTYPE_SETADDRESS_REQ: + if (length == 0x03) + { + uint32_t address; + + address = ser_recv(); + address = (address<<8) | ser_recv(); + address = (address<<8) | ser_recv(); + + if (address < gdata.address_max) + { + if (gdata.progmode == PROGMODE_DISABLED) + { + error_code = ERROR_INVALID_MODE; + } + else + { + address_set(address); + + ser_send(MSGTYPE_SETADDRESS_RSP); + ser_send(0x00); + error_code = SUCCESS; + } + } + } + break; + + case MSGTYPE_WRITE_REQ: + if ((length > 0) && + (length <= gdata.pagesize) + ) + { + if ((gdata.address >= gdata.address_max) || + ((gdata.address + length) > gdata.address_max) + ) + { + error_code = ERROR_INVALID_ADDRESS; + } + else if (gdata.progmode == PROGMODE_DISABLED) + { + error_code = ERROR_INVALID_MODE; + } + else + { + data_write(length); + + ser_send(MSGTYPE_WRITE_RSP); + ser_send(0x00); + error_code = SUCCESS; + } + } + break; + + case MSGTYPE_READ_REQ: + if (length == 0x01) + { + uint8_t size = ser_recv(); + + if (size <= PAGESIZE_MAX) + { + if ((gdata.address >= gdata.address_max) || + ((gdata.address + size) > gdata.address_max) + ) + { + error_code = ERROR_INVALID_ADDRESS; + } + else if (gdata.progmode == PROGMODE_DISABLED) + { + error_code = ERROR_INVALID_MODE; + } + else + { + ser_send(MSGTYPE_READ_RSP); + ser_send(size); + + data_read(size); + + error_code = SUCCESS; + } + } + } break; default: - ser_send('?'); - ser_send('\r'); - ser_send('\n'); + error_code = ERROR_UNKNOWN_COMMAND; break; } + + if (error_code != SUCCESS) + { + /* read remaining request */ + while (length--) + { + (void)ser_recv(); + } + + ser_send(MSGTYPE_ERROR_RSP); + ser_send(0x01); + ser_send(error_code); + } } } /* main */