OSDN Git Service

kazzo 0.1.1 release
[unagi/old-svn-converted.git] / kazzo / tag / 0.1.1 / firmware / avr_main.c
1 #include <avr/wdt.h>
2 #include <avr/interrupt.h>
3 #include <util/delay.h>
4 #include <string.h>
5 #include <avr/pgmspace.h>
6 #include "usbdrv.h"
7 #include "bus_access.h"
8 #include "disk_access.h"
9 #include "flashmemory.h"
10 #include "mcu_program.h"
11 #include "kazzo_request.h"
12
13 //---- global variable ----
14 #define REQUEST_NOP (0xee)
15 static struct write_command{
16         enum request request;
17         uint16_t address, length, offset;
18 }request_both_write, request_cpu_program, request_ppu_program;
19
20 //---- function start ----
21 static void flash_config_set(const uint8_t *t, void (*set)(uint16_t, uint16_t, uint16_t, uint16_t))
22 {
23         uint16_t c000x, c2aaa, c5555, unit;
24         c000x = t[0];
25         c000x |= t[1] << 8;
26         c2aaa = t[2];
27         c2aaa |= t[3] << 8;
28         c5555 = t[4];
29         c5555 |= t[5] << 8;
30         unit = t[6];
31         unit |= t[7] << 8;
32         (*set)(c000x, c2aaa, c5555, unit);
33 }
34 /*static uint8_t cpu_buffer[FLASH_PACKET_SIZE];
35 static uint8_t ppu_buffer[FLASH_PACKET_SIZE];*/
36 uchar usbFunctionWrite(uchar *data, uchar len)
37 {
38         static uint8_t cpu_buffer[FLASH_PACKET_SIZE];
39         static uint8_t ppu_buffer[FLASH_PACKET_SIZE];
40         const uint16_t length = (uint16_t) len;
41         uchar i;
42         //decode masked data
43         for(i = 0; i < len; i++){
44                 data[i] ^= 0xa5;
45         }
46         switch(request_both_write.request){
47         case REQUEST_CPU_WRITE_6502:
48                 cpu_write_6502(request_both_write.address + request_both_write.offset, length, data);
49                 goto BOTH_NEXT;
50         case REQUEST_CPU_WRITE_FLASH:
51                 cpu_write_flash(request_both_write.address + request_both_write.offset, length, data);
52                 goto BOTH_NEXT;
53         case REQUEST_PPU_WRITE:
54                 ppu_write(request_both_write.address + request_both_write.offset, length, data);
55                 goto BOTH_NEXT;
56         BOTH_NEXT:{
57                 request_both_write.offset += length;
58                 int ret = request_both_write.offset == request_both_write.length;
59                 if(ret){
60                         request_both_write.request = REQUEST_NOP;
61                 }
62                 return ret;
63                 }
64         default:
65                 break;
66         }
67         switch(request_cpu_program.request){
68         case REQUEST_FLASH_PROGRAM:
69         case REQUEST_FLASH_CONFIG_SET:{
70                 static uint8_t *w = cpu_buffer; //this is static pointer! be careful.
71                 if(request_cpu_program.offset == 0){
72                         w = cpu_buffer;
73                 }
74                 memcpy(w, data, length);
75                 w += length;
76                 request_cpu_program.offset += length;
77                 int ret = request_cpu_program.offset == request_cpu_program.length;
78                 if(ret){
79                         if(request_cpu_program.request == REQUEST_FLASH_CONFIG_SET){
80                                 flash_config_set(cpu_buffer, flash_cpu_config);
81                         }else{
82                                 flash_cpu_program(request_cpu_program.address, request_cpu_program.length, cpu_buffer);
83                         }
84                         request_cpu_program.request = REQUEST_NOP;
85                 }
86                 return ret;}
87         default:
88                 break;
89         }
90         switch(request_ppu_program.request){
91         case REQUEST_FLASH_PROGRAM:
92         case REQUEST_FLASH_CONFIG_SET:{
93                 static uint8_t *w = ppu_buffer; //static pointer
94                 if(request_ppu_program.offset == 0){
95                         w = ppu_buffer;
96                 }
97                 memcpy(w, data, length);
98                 w += length;
99                 request_ppu_program.offset += length;
100                 int ret = request_ppu_program.offset == request_ppu_program.length;
101                 if(ret){
102                         if(request_ppu_program.request == REQUEST_FLASH_CONFIG_SET){
103                                 flash_config_set(ppu_buffer, flash_ppu_config);
104                         }else{
105                                 flash_ppu_program(request_ppu_program.address, request_ppu_program.length, ppu_buffer);
106                         }
107                         request_ppu_program.request = REQUEST_NOP;
108                 }
109                 return ret;}
110         default:
111                 break;
112         }
113         return 1;
114 }
115
116 //static uint8_t readbuffer[READ_PACKET_SIZE];
117 usbMsgLen_t usbFunctionSetup(uchar d[8])
118 {
119         static uint8_t readbuffer[READ_PACKET_SIZE];
120         static uint8_t status[2];
121         usbRequest_t *rq = (void *)d;
122         struct write_command *write_command;
123
124         switch((enum request) rq->bRequest){
125         case REQUEST_ECHO:
126                 readbuffer[0] = rq->wValue.bytes[0];
127                 readbuffer[1] = rq->wValue.bytes[1];
128                 readbuffer[2] = rq->wIndex.bytes[0];
129                 readbuffer[3] = rq->wIndex.bytes[1];
130                 usbMsgPtr = readbuffer;
131                 return 4;
132         case REQUEST_PHI2_INIT:
133                 flash_both_idle();
134                 phi2_init();
135                 return 0;
136         case REQUEST_CPU_READ:
137                 cpu_read(rq->wValue.word, rq->wLength.word, readbuffer);
138                 goto xxx_read;
139         case REQUEST_CPU_READ_6502:
140                 cpu_read_6502(rq->wValue.word, rq->wLength.word, readbuffer);
141                 goto xxx_read;
142         case REQUEST_PPU_READ:
143                 ppu_read(rq->wValue.word, rq->wLength.word, readbuffer);
144                 goto xxx_read;
145         case REQUEST_CPU_WRITE_6502: case REQUEST_CPU_WRITE_FLASH:
146         case REQUEST_PPU_WRITE:
147                 write_command = &request_both_write;
148                 goto xxx_write;
149         case REQUEST_FLASH_PROGRAM:
150         case REQUEST_FLASH_CONFIG_SET:
151                 if(rq->wIndex.word == INDEX_CPU){
152                         write_command = &request_cpu_program;
153                 }else{
154                         write_command = &request_ppu_program;
155                 }
156                 goto xxx_write;
157         xxx_write:
158                 write_command->request = rq->bRequest;
159                 write_command->length = rq->wLength.word;
160                 write_command->address = rq->wValue.word;
161                 write_command->offset = 0;
162                 return USB_NO_MSG; //goto usbFunctionWrite
163 /*      case REQUEST_FLASH_BUFFER_GET:
164                 if(rq->wIndex.word == INDEX_CPU){
165                         usbMsgPtr = cpu_buffer;
166                 }else{
167                         usbMsgPtr = ppu_buffer;
168                 }
169                 return FLASH_PACKET_SIZE;*/
170         case REQUEST_DISK_STATUS_GET:
171                 //usbMsgPtr = status;
172                 return 0; //disk_status_get(status);
173         case REQUEST_DISK_READ: 
174                 disk_init(DISK_READ);
175                 return 0;
176         case REQUEST_DISK_WRITE:
177                 disk_init(DISK_WRITE);
178                 return 0;
179         case REQUEST_FLASH_STATUS:
180                 usbMsgPtr = status;
181                 switch((enum index) rq->wIndex.word){
182                 case INDEX_CPU:
183                         status[0] = flash_cpu_status();
184                         return 1;
185                 case INDEX_PPU:
186                         status[0] = flash_ppu_status();
187                         return 1;
188                 default:
189                         status[0] = flash_cpu_status();
190                         status[1] = flash_ppu_status();
191                         return 2;
192                 }
193                 return 1;
194         case REQUEST_FLASH_DEVICE:
195                 if(rq->wIndex.word == INDEX_CPU){
196                         flash_cpu_device_get(status);
197                 }else{
198                         flash_ppu_device_get(status);
199                 }
200                 usbMsgPtr = status;
201                 return 2;
202         case REQUEST_FLASH_ERASE:
203                 if(rq->wIndex.word == INDEX_CPU){
204                         flash_cpu_erase(rq->wValue.word);
205                 }else{
206                         flash_ppu_erase(rq->wValue.word);
207                 }
208                 return 0;
209         case REQUEST_VRAM_CONNECTION:
210                 status[0] = vram_connection_get();
211                 usbMsgPtr = status;
212                 return 1;
213         case REQUEST_FIRMWARE_VERSION:{
214                 __attribute__ ((section(".firmware.version")))
215                 static const /*PROGMEM*/ char date[VERSION_STRING_SIZE] = "kazzo16 0.1.1 " __DATE__;
216                 memcpy_P(readbuffer, date, rq->wLength.word);
217                 goto xxx_read;}
218         case REQUEST_FIRMWARE_PROGRAM:{
219                 void (*t)(uint8_t *buf, uint16_t address, uint16_t length);
220                 usbDeviceDisconnect();
221                 memcpy_P(&t, &BOOTLOADER_ASSIGN.programmer, sizeof(BOOTLOADER_ASSIGN.programmer));
222                 (*t)(readbuffer, rq->wValue.word, rq->wIndex.word);
223                 }return 0;
224         case REQUEST_FIRMWARE_DOWNLOAD:{
225                 const /*PROGMEM*/ uint8_t *firm = (const /*PROGMEM*/ uint8_t *) rq->wValue.word;
226                 memcpy_P(readbuffer, firm, rq->wLength.word);
227                 }
228                 goto xxx_read;
229         xxx_read:
230                 usbMsgPtr = readbuffer;
231                 return rq->wLength.word;
232         }
233         return 0;
234 }
235
236 int main(void)
237 {
238         static const struct write_command wc_init = {
239                 .request = REQUEST_NOP, .length = 0, .offset = 0
240         };
241         request_both_write = wc_init;
242         request_cpu_program = wc_init;
243         request_ppu_program = wc_init;
244
245         bus_init();
246         usbInit();
247         usbDeviceDisconnect();
248         {
249                 uchar   i;
250                 i = 0;
251                 while(--i){
252                         wdt_reset();
253                         _delay_ms(1);
254                 }
255         }
256         usbDeviceConnect();
257         wdt_enable(WDTO_500MS);
258         sei();
259         for(;;){
260                 wdt_reset();
261                 usbPoll();
262                 //disk_process();
263                 flash_process();
264         }
265         return 0;
266 }