summaryrefslogtreecommitdiffstats
path: root/sw/programmer/avr/main.c
diff options
context:
space:
mode:
authorNao Pross <naopross@thearcway.org>2017-08-07 19:27:05 +0200
committerNao Pross <naopross@thearcway.org>2017-08-07 19:27:05 +0200
commitd0801b36b47d8f3da610597160fde92059fd7e62 (patch)
treef9f0e348145c3548433e60adbf459e784b909f96 /sw/programmer/avr/main.c
parentfilesystem structure intro and docs (diff)
downloadz80uPC-d0801b36b47d8f3da610597160fde92059fd7e62.tar.gz
z80uPC-d0801b36b47d8f3da610597160fde92059fd7e62.zip
implementation for avr programmer
the programmer will receive the binary in blocks of defined size by a program under sw/programmer/linux (moved from sw/linux).
Diffstat (limited to 'sw/programmer/avr/main.c')
-rw-r--r--sw/programmer/avr/main.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/sw/programmer/avr/main.c b/sw/programmer/avr/main.c
new file mode 100644
index 0000000..90d05fa
--- /dev/null
+++ b/sw/programmer/avr/main.c
@@ -0,0 +1,109 @@
+#include "fileinfo.h"
+#include "usart.h"
+#include <util/delay.h>
+
+#define EEPROM_TICK_MS 10
+
+#define ADDRCR PORTB
+#define EEPROMCR PORTC
+#define EEPROMDR PORTD
+
+#define ADDR_BIT 0
+#define ADDR_EL 3
+#define ADDR_EH 4
+#define ADDR_DL 5
+#define ADDR_DH 6
+
+#define EEPROM_WR 0
+#define EEPROM_RD 1
+#define EEPROM_CLK 2
+
+
+void eeprom_write(uint16_t addr, uint8_t byte);
+void eeprom_tick();
+
+int main(void)
+{
+ uint8_t *buffer, i;
+ uint16_t addr;
+ size_t read;
+
+ struct file_info *finfo = malloc(sizeof(struct file_info));
+
+ DDRB = 0x7F;
+ DDRC = 0x83;
+ DDRD = 0xFC;
+
+ /* get configuration */
+ usart_init(1200);
+
+ usart_print("EEPROM Programmer\n\r");
+
+ do {
+ usart_print("Waiting for configuration\n\r");
+ read = usart_read((uint8_t *) finfo, sizeof(struct file_info));
+ } while (read != sizeof(struct file_info));
+
+ usart_print("Programmer Ready\n<waiting for binary>\n\r");
+
+ buffer = malloc(finfo->blklen);
+ addr = finfo->start_addr;
+
+ /* read file */
+ while ((read = usart_read(buffer, finfo->blklen))) {
+ for (i = 0; i < read; i++) {
+ eeprom_write(addr + i, *(buffer++));
+ }
+
+ addr += finfo->blklen;
+ }
+
+ return 0;
+}
+
+
+void eeprom_write(uint16_t addr, uint8_t byte)
+{
+ int bit;
+
+ /* set address */
+ for (bit = 0; bit < 8; bit++) {
+ // clear bit
+ ADDRCR &= ~0x07;
+ // select the bit
+ ADDRCR |= bit;
+
+ // write bit for lower byte
+ if (addr & _BV(bit))
+ ADDRCR |= _BV(ADDR_DL);
+ else
+ ADDRCR &= ~_BV(ADDR_DL);
+
+ // write bit for higher byte
+ if ((addr>>8) & _BV(bit))
+ ADDRCR |= _BV(ADDR_DH);
+ else
+ ADDRCR &= ~_BV(ADDR_DH);
+ }
+
+ /* set data */
+ EEPROMDR = byte;
+ EEPROMCR &= ~(_BV(ADDR_EH) | _BV(ADDR_EL));
+
+ /* write eeprom */
+ EEPROMCR &= ~_BV(EEPROM_WR);
+ eeprom_tick();
+
+ EEPROMCR |= _BV(EEPROM_WR);
+ EEPROMCR |= _BV(ADDR_EH) | _BV(ADDR_EL);
+}
+
+/* pulse the clock line for the eeprom */
+void eeprom_tick()
+{
+ EEPROMCR |= _BV(EEPROM_CLK);
+ _delay_ms(EEPROM_TICK_MS);
+ EEPROMCR &= ~_BV(EEPROM_CLK);
+ _delay_ms(EEPROM_TICK_MS);
+}
+