5 #include <avr/interrupt.h>
6 #include <util/delay.h>
12 * B2: SPI ~SS/shiftreg ~OE
14 * B4: SPI MISO (unused)
16 * C0: programming mode PGM
30 #define PC_SYSRST 0x20
32 static void proc_cmd(char *input);
33 static void start_prog(void);
34 static void end_prog(void);
35 static void write_ram(uint16_t addr, uint8_t val);
36 static uint8_t read_ram(uint16_t addr);
37 static void dbg_setup_read(uint16_t addr);
38 static void set_data_bus(unsigned char val);
39 static void release_data_bus(void);
40 static void set_addr_bus(uint16_t addr);
41 static void sys_reset(void);
42 static inline void iodelay(void);
48 static char input[128];
49 static unsigned char inp_cidx;
54 /* SPI (SS/MOSI/SCK) are outputs */
55 DDRB = PB_SS | PB_MOSI | PB_SCK;
56 PORTB = PB_SS; /* drive SS high when not in programming mode */
57 DDRC = 0xff; /* control signals are all outputs */
58 PORTC = PC_CS | PC_WE | PC_OE | PC_SYSRST;
59 DDRD = 0; /* tri-state the data bus by default (high 6 bits, low 2 are in DDRB) */
62 /* disable all pullups */
65 /* enable SPI (used to talk to the address bus shift registers)
66 * SPI master mode, clock / 16, CPOL=0/CPHA=0 because shiftreg clocks on the
67 * rising edge, and MSB first
69 SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);
71 /* init the serial port we use to talk to the host */
82 if(c == '\r' || c == '\n') {
86 } else if(inp_cidx < sizeof input - 1) {
87 input[inp_cidx++] = c;
94 static void proc_cmd(char *input)
101 echo = input[1] == '1' ? 1 : 0;
102 printf("OK echo %s\n", echo ? "on" : "off");
107 puts("ERR already in programming mode");
110 puts("OK programming mode");
124 addr = strtol(input + 1, &endp, 0);
125 printf("OK address: %x\n", (unsigned int)addr);
130 puts("ERR not in programming mode");
133 data = strtol(input + 1, &endp, 0);
134 write_ram(addr++, data);
140 puts("ERR not in programming mode");
143 data = read_ram(addr++);
144 printf("OK %d\n", (int)data);
149 puts("ERR not in programming mode");
152 dbg_setup_read(addr);
153 printf("OK set up read from %x\n", (unsigned int)addr);
158 puts("ERR not in programming mode");
161 addr = strtol(input + 1, &endp, 0);
163 printf("OK DBG address %x\n", (unsigned int)addr);
167 puts("OK command help");
168 puts(" e 0|1: turn echo on/off");
169 puts(" p: enter programming mode");
170 puts(" b: exit programming mode and boot up");
171 puts(" a <addr>: set address counter (0-ffff)");
172 puts(" w <data>: store data byte and increment address (0-255)");
173 puts(" r: read data byte and increment address");
174 puts(" ?: print command help");
175 printf("Currently in %s mode\n", progmode ? "programming" : "boot");
179 printf("ERR unknown command: '%c'\n", input[0]);
183 static void start_prog(void)
185 /* hold reset low, and take over the RAM */
192 static void end_prog(void)
194 /* make extra sure we don't drive the data bus */
197 /* PGM low and return reset and SS high */
200 PORTC |= PC_SYSRST | PC_CS | PC_OE;
205 static void write_ram(uint16_t addr, uint8_t val)
210 PORTC &= ~(PC_WE | PC_CS);
217 static uint8_t read_ram(uint16_t addr)
222 PORTC &= ~(PC_CS | PC_OE);
224 val = (PIND & 0xfc) | (PINB & 3);
225 PORTC |= PC_CS | PC_OE;
229 static void dbg_setup_read(uint16_t addr)
233 PORTC &= ~(PC_CS | PC_OE);
237 static void set_data_bus(unsigned char val)
239 /* drive the data bus */
242 PORTB = (PORTB & 0xfc) | (val & 3);
246 static void release_data_bus(void)
255 static void set_addr_bus(uint16_t addr)
258 SPDR = (uint8_t)(addr >> 8);
259 while(!(SPSR & (1 << SPIF)));
260 SPDR = (uint8_t)addr;
261 while(!(SPSR & (1 << SPIF)));
265 PORTB &= ~PB_SS; /* SS must return low because the shiftreg OE is tied to it */
268 static void sys_reset(void)
275 static inline void iodelay(void)