It works ... jesus FUCKING christ, I just had been feeding the address bus shift...
[romdev] / fw / src / main.c
index c07b34e..0711dbc 100644 (file)
@@ -3,6 +3,7 @@
 #include <stdint.h>
 #include <avr/io.h>
 #include <avr/interrupt.h>
+#include <util/delay.h>
 #include "serial.h"
 
 /* pin assignments
@@ -33,7 +34,9 @@ static void start_prog(void);
 static void end_prog(void);
 static void write_ram(uint16_t addr, uint8_t val);
 static uint8_t read_ram(uint16_t addr);
+static void dbg_setup_read(uint16_t addr);
 static void set_data_bus(unsigned char val);
+static void release_data_bus(void);
 static void set_addr_bus(uint16_t addr);
 static void sys_reset(void);
 static inline void iodelay(void);
@@ -48,12 +51,12 @@ static unsigned char inp_cidx;
 
 int main(void)
 {
-       /* SPI (SS/MOSI/SCK) are outputs, as are the low 2 data bus bits */
-       DDRB = PB_SS | PB_MOSI | PB_SCK | 3;
+       /* SPI (SS/MOSI/SCK) are outputs */
+       DDRB = PB_SS | PB_MOSI | PB_SCK;
        PORTB = PB_SS;  /* drive SS high when not in programming mode */
        DDRC = 0xff;    /* control signals are all outputs */
        PORTC = PC_CS | PC_WE | PC_OE | PC_SYSRST;
-       DDRD = 0xff;    /* always drive the (high bits of the) data bus */
+       DDRD = 0;       /* tri-state the data bus by default (high 6 bits, low 2 are in DDRB) */
        PORTD = 0;
 
        /* disable all pullups */
@@ -141,6 +144,25 @@ static void proc_cmd(char *input)
                printf("OK %d\n", (int)data);
                break;
 
+       case 'R':
+               if(!progmode) {
+                       puts("ERR not in programming mode");
+                       break;
+               }
+               dbg_setup_read(addr);
+               printf("OK set up read from %x\n", (unsigned int)addr);
+               break;
+
+       case 'A':
+               if(!progmode) {
+                       puts("ERR not in programming mode");
+                       break;
+               }
+               addr = strtol(input + 1, &endp, 0);
+               set_addr_bus(addr);
+               printf("OK DBG address %x\n", (unsigned int)addr);
+               break;
+
        case '?':
                puts("OK command help");
                puts(" e 0|1: turn echo on/off");
@@ -150,6 +172,7 @@ static void proc_cmd(char *input)
                puts(" w <data>: store data byte and increment address (0-255)");
                puts(" r: read data byte and increment address");
                puts(" ?: print command help");
+               printf("Currently in %s mode\n", progmode ? "programming" : "boot");
                break;
 
        default:
@@ -168,9 +191,13 @@ static void start_prog(void)
 
 static void end_prog(void)
 {
-       /* PGM low and return reset high */
+       /* make extra sure we don't drive the data bus */
+       release_data_bus();
+
+       /* PGM low and return reset and SS high */
+       PORTB |= PB_SS;
        PORTC &= ~PC_PGM;
-       PORTC |= PC_SYSRST;
+       PORTC |= PC_SYSRST | PC_CS | PC_OE;
 
        progmode = 0;
 }
@@ -184,6 +211,7 @@ static void write_ram(uint16_t addr, uint8_t val)
        iodelay();
        PORTC |= PC_CS;
        PORTC |= PC_WE;
+       release_data_bus();
 }
 
 static uint8_t read_ram(uint16_t addr)
@@ -193,24 +221,44 @@ static uint8_t read_ram(uint16_t addr)
        PORTC |= PC_WE;
        PORTC &= ~(PC_CS | PC_OE);
        iodelay();
-       val = (PORTD & 0xfe) | (PORTB & 3);
+       val = (PIND & 0xfc) | (PINB & 3);
        PORTC |= PC_CS | PC_OE;
        return val;
 }
 
+static void dbg_setup_read(uint16_t addr)
+{
+       set_addr_bus(addr);
+       PORTC |= PC_WE;
+       PORTC &= ~(PC_CS | PC_OE);
+}
+
+
 static void set_data_bus(unsigned char val)
 {
-       PORTB = (PORTB & 0xfe) | (val & 3);
-       PORTC = val;
+       /* drive the data bus */
+       DDRD = 0xff;
+       DDRB |= 3;
+       PORTB = (PORTB & 0xfc) | (val & 3);
+       PORTD = val;
+}
+
+static void release_data_bus(void)
+{
+       DDRD = 0;
+       DDRB &= 0xfc;
+
+       PORTD = 0;
+       PORTB &= 0xfc;
 }
 
 static void set_addr_bus(uint16_t addr)
 {
        PORTB &= ~PB_SS;
-       SPDR = (uint8_t)addr;
-       while(!(SPSR & (1 << SPIF)));
        SPDR = (uint8_t)(addr >> 8);
        while(!(SPSR & (1 << SPIF)));
+       SPDR = (uint8_t)addr;
+       while(!(SPSR & (1 << SPIF)));
 
        PORTB |= PB_SS;
        iodelay();
@@ -220,7 +268,7 @@ static void set_addr_bus(uint16_t addr)
 static void sys_reset(void)
 {
        PORTC &= ~PC_SYSRST;
-       iodelay();
+       _delay_ms(500);
        PORTC |= PC_SYSRST;
 }