OSDN Git Service

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