From b8335062ae7d19bd27e6131fadcd7d3a116c4992 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Fri, 11 Mar 2011 01:28:00 +0000 Subject: DimOS RT --- firmware/firmware.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 firmware/firmware.c (limited to 'firmware/firmware.c') diff --git a/firmware/firmware.c b/firmware/firmware.c new file mode 100644 index 0000000..a0a649b --- /dev/null +++ b/firmware/firmware.c @@ -0,0 +1,104 @@ +/* $Id$ */ +/* + * Copyright (c) 2011 Dimitri Sokolyuk + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include /* depends on BAUD & F_CPU env vars */ +#include + +#define TIMEOUT (F_CPU >> 3) /* ca. 2 sec */ + +union { + uint16_t word; + uint8_t byte[2]; +} data; + +void +reboot() +{ + boot_rww_enable(); + ((void(*)(void))0)(); /* jump to app */ +} + +void +putch(char c) +{ + if (c == '\n') + putch('\r'); /* be unix polite */ + + loop_until_bit_is_set(UCSRA, UDRE); + + UDR = c; +} + +uint8_t +getch(void) +{ + uint32_t counter = 0; + + do { + if (++counter > TIMEOUT) + reboot(); + } while (bit_is_clear(UCSRA, RXC)); + + return UDR; +} + +int +main(void) +{ + uint8_t i; + uint16_t off; + + UCSRB = _BV(RXEN) | _BV(TXEN); + UBRRH = UBRRH_VALUE; + UBRRL = UBRRL_VALUE; + UCSRA &= ~_BV(U2X); + + putch('+'); /* say hallo */ + + if (getch() != 'P') /* wait a while for program request */ + reboot(); + putch('p'); /* confirm */ + + for (;;) { + switch (getch()) { + case 'D': /* data request */ + off = (uint16_t)getch() * SPM_PAGESIZE; + for (i = 0; i < SPM_PAGESIZE; i += 2) { + data.byte[0] = getch(); + data.byte[1] = getch(); + boot_page_fill(off + i, data.word); + } + + boot_page_erase(off); + boot_spm_busy_wait(); + + boot_page_write(off); + boot_spm_busy_wait(); + + putch('d'); /* confirm */ + break; + case 'R': /* reboot request */ + reboot(); + break; + default: + break; + } + } + + return 0; +} -- cgit v1.2.3