5 #include <avr/interrupt.h>
11 * B2: SPI ~SS/shiftreg ~OE
13 * B4: SPI MISO (unused)
15 * C0: programming mode PGM
29 #define PC_SYSRST 0x20
31 static void proc_cmd(char *input);
32 static void start_prog(void);
33 static void end_prog(void);
34 static void write_ram(uint16_t addr, uint8_t val);
35 static uint8_t read_ram(uint16_t addr);
36 static void set_data_bus(unsigned char val);
37 static void set_addr_bus(uint16_t addr);
38 static void sys_reset(void);
39 static inline void iodelay(void);
45 static char input[128];
46 static unsigned char inp_cidx;
51 /* SPI (SS/MOSI/SCK) are outputs, as are the low 2 data bus bits */
52 DDRB = PB_SS | PB_MOSI | PB_SCK | 3;
53 PORTB = PB_SS; /* drive SS high when not in programming mode */
54 DDRC = 0xff; /* control signals are all outputs */
55 PORTC = PC_CS | PC_WE | PC_OE | PC_SYSRST;
56 DDRD = 0xff; /* always drive the (high bits of the) data bus */
59 /* disable all pullups */
62 /* enable SPI (used to talk to the address bus shift registers)
63 * SPI master mode, clock / 16, CPOL=0/CPHA=0 because shiftreg clocks on the
64 * rising edge, and MSB first
66 SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);
68 /* init the serial port we use to talk to the host */
79 if(c == '\r' || c == '\n') {
83 } else if(inp_cidx < sizeof input - 1) {
84 input[inp_cidx++] = c;
91 static void proc_cmd(char *input)
98 echo = input[1] == '1' ? 1 : 0;
99 printf("OK echo %s\n", echo ? "on" : "off");
104 puts("ERR already in programming mode");
107 puts("OK programming mode");
121 addr = strtol(input + 1, &endp, 0);
122 printf("OK address: %x\n", (unsigned int)addr);
127 puts("ERR not in programming mode");
130 data = strtol(input + 1, &endp, 0);
131 write_ram(addr++, data);
137 puts("ERR not in programming mode");
140 data = read_ram(addr++);
141 printf("OK %d\n", (int)data);
145 puts("OK command help");
146 puts(" e 0|1: turn echo on/off");
147 puts(" p: enter programming mode");
148 puts(" b: exit programming mode and boot up");
149 puts(" a <addr>: set address counter (0-ffff)");
150 puts(" w <data>: store data byte and increment address (0-255)");
151 puts(" r: read data byte and increment address");
152 puts(" ?: print command help");
156 printf("ERR unknown command: '%c'\n", input[0]);
160 static void start_prog(void)
162 /* hold reset low, and take over the RAM */
169 static void end_prog(void)
171 /* PGM low and return reset high */
178 static void write_ram(uint16_t addr, uint8_t val)
183 PORTC &= ~(PC_WE | PC_CS);
189 static uint8_t read_ram(uint16_t addr)
194 PORTC &= ~(PC_CS | PC_OE);
196 val = (PORTD & 0xfe) | (PORTB & 3);
197 PORTC |= PC_CS | PC_OE;
201 static void set_data_bus(unsigned char val)
203 PORTB = (PORTB & 0xfe) | (val & 3);
207 static void set_addr_bus(uint16_t addr)
210 SPDR = (uint8_t)addr;
211 while(!(SPSR & (1 << SPIF)));
212 SPDR = (uint8_t)(addr >> 8);
213 while(!(SPSR & (1 << SPIF)));
217 PORTB &= ~PB_SS; /* SS must return low because the shiftreg OE is tied to it */
220 static void sys_reset(void)
227 static inline void iodelay(void)