OSDN Git Service

bootloader の実装完了、version 情報を特定アドレスに固定
authornaruko <naruko@24ea1065-a21e-4ca1-99c9-f5125deb0858>
Thu, 31 Dec 2009 22:38:35 +0000 (22:38 +0000)
committernaruko <naruko@24ea1065-a21e-4ca1-99c9-f5125deb0858>
Thu, 31 Dec 2009 22:38:35 +0000 (22:38 +0000)
git-svn-id: svn+ssh://svn.osdn.net/svnroot/unagi@342 24ea1065-a21e-4ca1-99c9-f5125deb0858

kazzo/trunk/firmware/avr_main.c
kazzo/trunk/firmware/bus_access.c
kazzo/trunk/firmware/firmware.mak
kazzo/trunk/firmware/kazzo_request.h
kazzo/trunk/firmware/mcu_program.c
kazzo/trunk/firmware/mcu_program.h
kazzo/trunk/hostecho/Makefile
kazzo/trunk/hostecho/hostecho.c
kazzo/trunk/hostecho/usbdevice.c
kazzo/trunk/hostecho/usbdevice.h
kazzo/trunk/readme.txt

index f2a1aa4..757e52e 100644 (file)
@@ -211,14 +211,16 @@ usbMsgLen_t usbFunctionSetup(uchar d[8])
                usbMsgPtr = status;
                return 1;
        case REQUEST_FIRMWARE_VERSION:{
-               //static const PROGMEM char date[VERSION_STRING_SIZE] = "kazzo16 0.1.1 " __DATE__;
-               static const PROGMEM char date[VERSION_STRING_SIZE] = "kazzo16 0.1.1 " __TIME__;
+               __attribute__ ((section(".firmware.version")))
+               static const /*PROGMEM*/ char date[VERSION_STRING_SIZE] = "kazzo16 0.1.1 " __TIME__;
                memcpy_P(readbuffer, date, rq->wLength.word);
                goto xxx_read;}
-       case REQUEST_FIRMWARE_PROGRAM:
+       case REQUEST_FIRMWARE_PROGRAM:{
+               void (*t)(uint8_t *buf, uint16_t address, uint16_t length);
                usbDeviceDisconnect();
-               mcu_data_program(readbuffer, READ_PACKET_SIZE, rq->wValue.word, rq->wIndex.word);
-               return 0;
+               memcpy_P(&t, &BOOTLOADER_ASSIGN.programmer, sizeof(BOOTLOADER_ASSIGN.programmer));
+               (*t)(readbuffer, rq->wValue.word, rq->wIndex.word);
+               }return 0;
        case REQUEST_FIRMWARE_DOWNLOAD:{
                const /*PROGMEM*/ uint8_t *firm = (const /*PROGMEM*/ uint8_t *) rq->wValue.word;
                memcpy_P(readbuffer, firm, rq->wLength.word);
index 14857b5..4873f4c 100644 (file)
@@ -452,11 +452,19 @@ static void boot_address_set(uint16_t address)
 __attribute__ ((section(".bootloader.bus")))
 void mcu_programdata_read(uint16_t address, uint16_t length, uint8_t *data)
 {
-       //BUS_CONTROL_OUT = BUS_CLOSE;
        while(length != 0){
                direction_write();
-               boot_address_set(address);
-               BUS_CONTROL_OUT = bit_get_negative(PPU_RD);
+               if(address < 0x2000){ //PPU CHR-RAM
+                       boot_address_set(address);
+                       BUS_CONTROL_OUT = bit_get_negative(PPU_RD);
+               }else{ //CPU W-RAM
+                       address &= 0x1fff;
+                       address |= 0x6000;
+                       boot_address_set(address);
+/*                     if((address & 0x8000) != 0){
+                               BUS_CONTROL_OUT = bit_get_negative(CPU_ROMCS);
+                       }*/
+               }
                direction_read();
                *data = DATABUS_IN;
                data += 1;
index 47148b9..53af7c4 100644 (file)
@@ -1,7 +1,7 @@
 F_CPU = 16000000
 #FORMAT = srec
-#FORMAT = ihex
-FORMAT = binary
+FORMAT = ihex
+#FORMAT = binary
 
 # Target file name (without extension).
 OBJDIR = ./$(TARGET)
@@ -13,7 +13,7 @@ ASRC = $(USBDRIVER)/usbdrvasm.S
 
 
 # Optimization level, can be [0, 1, 2, 3, s]. 
-OPT = s
+OPT = 2
 
 # Debugging format.
 #     Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
@@ -105,7 +105,10 @@ EXTRALIBDIRS =
 # only used for heap (malloc()).
 #EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
 
-EXTMEMOPTS = -Wl,--section-start,.bootloader.bus=0x003d80,--section-start,.bootloader=0x003e00
+EXTMEMOPTS = -Wl,--section-start,.firmware.version=0x003780
+EXTMEMOPTS += -Wl,--section-start,.bootloader.version=0x003d00
+EXTMEMOPTS += -Wl,--section-start,.bootloader.bus=0x003d80
+EXTMEMOPTS += -Wl,--section-start,.bootloader.programmer=0x003e00
 
 #---------------- Linker Options ----------------
 #  -Wl,...:     tell GCC to pass this to linker.
index b4c3544..689f063 100644 (file)
@@ -30,8 +30,9 @@ enum index{
        INDEX_IMPLIED = 0, INDEX_CPU, INDEX_PPU, INDEX_BOTH
 };
 enum {
-       VERSION_STRING_SIZE = 0x24,
-       READ_PACKET_SIZE = 0x0100,
+       VERSION_STRING_SIZE = 0x20,
+//     READ_PACKET_SIZE = 0x0100, //use macro to compare SPM_PAGESIZE
        FLASH_PACKET_SIZE = 0x0100
 };
+#define READ_PACKET_SIZE (0x100)
 #endif
index 448d0a1..30e35a2 100644 (file)
@@ -3,7 +3,13 @@
 #include <avr/interrupt.h>
 #include <avr/pgmspace.h> 
 #include <avr/wdt.h>
+#include "kazzo_request.h"
 #include "bus_access.h"
+#include "mcu_program.h"
+
+#if SPM_PAGESIZE > READ_PACKET_SIZE 
+ #error READ_PACKET_SIZE is few capacity
+#endif
 /*
 firmware bootloader sequence
 - User insert a cartrige which has charcter RAM. eg. UNROM or SGROM
@@ -11,13 +17,13 @@ firmware bootloader sequence
 - Host receive and compare charcter memory image.
 - Firmware reprogram by REQUEST_FIRMWARE_PROGRAM.
 
-compiler notice/ WinAVR 20080610
-compiler produces bad object with optimize option -O2
-use -Os
+MEGA164P-20[AP]U
+ISP programming -> REQUEST_FIRMWARE_PROGRAM -> flash memory is programmed 2 pages only...
+ISP programming -> power off->on -> REQUEST_FIRMWARE_PROGRAM -> flash memory is programmed all pages.
 */
 __attribute__((noreturn))
-BOOTLOADER_SECTION
-void mcu_data_program(uint8_t *buf, const uint16_t bufsize, uint16_t address, uint16_t length)
+__attribute__ ((section(".bootloader.programmer")))
+static void mcu_data_program(uint8_t *buf, uint16_t address, uint16_t length)
 {
        uint16_t offset = 0;
        int page;
@@ -41,9 +47,18 @@ void mcu_data_program(uint8_t *buf, const uint16_t bufsize, uint16_t address, ui
                offset += SPM_PAGESIZE;
                address += SPM_PAGESIZE;
        }
-       boot_rww_enable();
-       sei();
-       wdt_enable(WDTO_500MS);
+       if(0){ //force re-turn power on. keep watchdog disable
+               boot_rww_enable();
+               sei();
+               wdt_enable(WDTO_500MS);
+       }
 endless: //wait watchdog interruptting reset
        goto endless;
 }
+
+__attribute__ ((section(".bootloader.version")))
+const struct bootloader_assign BOOTLOADER_ASSIGN = {
+       .version = "bootlader 0.1.0",
+       .programmer = mcu_data_program
+};
+
index 4081fd5..f1e5a11 100644 (file)
@@ -1,5 +1,10 @@
 #ifndef _MCU_PROGRAM_H_
 #define _MCU_PROGRAM_H_
-__attribute__((noreturn))
-void mcu_data_program(uint8_t *buf, const uint16_t bufsize, uint16_t address, uint16_t length);
+struct bootloader_assign{
+       const char version[0x20];
+       __attribute__((noreturn))
+       void (*const programmer)(uint8_t *buf, uint16_t address, uint16_t length);
+};
+//__attribute__ ((section(".bootloader.version")))
+const struct bootloader_assign BOOTLOADER_ASSIGN;
 #endif
index a3a0094..d8c82a2 100644 (file)
@@ -1,7 +1,7 @@
 LIBUSB = d:/dev/LibUSB-Win32
 KAZZO = ../firmware
 
-OBJECT = opendevice.o hostecho.o usbdevice.o
+OBJECT = opendevice.o hostecho.o usbdevice.o ihex.o file.o
 
 CC = gcc
 CFLAG = -I$(LIBUSB)/include -I$(KAZZO) -Wall -Werror
index 4de3e57..d939b50 100644 (file)
@@ -7,6 +7,8 @@
 #include <time.h>
 #include <usb.h>
 #include <kazzo_request.h>
+#include "ihex.h"
+#include "file.h"
 #include "usbdevice.h"
 
 static void echo(usb_dev_handle *handle)
@@ -45,44 +47,118 @@ static void echo(usb_dev_handle *handle)
        printf("\nTest completed.\n");
 }
 
-static bool buf_load(uint8_t *buf, const char *file, int size)
+static bool hex_load(const char *file, long firmsize, uint8_t *image)
 {
-       FILE *fp;
-
-       fp = fopen(file, "rb");
-       if(fp == NULL){
+       FILE *f;
+       char s[0x80];
+       f = fopen(file, "r");
+       if(f == NULL){
                return false;
        }
-       fseek(fp, 0, SEEK_SET);
-       fread(buf, sizeof(uint8_t), size, fp);
-       fclose(fp);
-       return true;
+       fseek(f, 0, SEEK_SET);
+       
+       struct record *t = ihex_new();
+       bool ret = true;
+       while(fgets(s, 0x80, f) != NULL){
+               if(ihex_load(s, t) == false){
+                       ret = false;
+                       break;
+               }
+               ihex_write(t, firmsize, image);
+       }
+       ihex_destory(t);
+       return ret;
+}
+static void snrom_ramopen(usb_dev_handle *handle)
+{
+       uint8_t t[5];
+       t[0] = 0x80;
+       write_memory(handle, REQUEST_CPU_WRITE_6502, INDEX_IMPLIED, 0x8000, 1, t);
+       t[0] = 0, t[1] = 0, t[2] = 0, t[3] = 1, t[4] = 0;
+       write_memory(handle, REQUEST_CPU_WRITE_6502, INDEX_IMPLIED, 0x8000, 5, t);
+       t[0] = 0, t[1] = 0, t[2] = 0, t[3] = 0, t[4] = 0;
+       write_memory(handle, REQUEST_CPU_WRITE_6502, INDEX_IMPLIED, 0xe000, 5, t);
+       write_memory(handle, REQUEST_CPU_WRITE_6502, INDEX_IMPLIED, 0xa000, 5, t);
 }
 
+static int cartridge_ram_transform(usb_dev_handle *handle, const uint8_t *firmware, enum request w, enum request r, long address, long length)
+{
+       uint8_t *compare;
+       compare = malloc(length);
+       write_memory(handle, w, INDEX_IMPLIED, address, length, firmware);
+       read_memory(handle, r, INDEX_IMPLIED, address, length, compare);
+       int ret = memcmp(firmware, compare, length);
+       free(compare);
+       return ret;
+}
 static void firmware_update(usb_dev_handle *handle, const char *file)
 {
-       uint8_t *firmware, *compare;
-       const int firmsize = 0x1c00;
-       assert(firmsize <= 0x2000);
+       uint8_t *firmware;
+       const int firmsize = 0x3800;
+       assert(firmsize <= 0x3800);
        firmware = malloc(firmsize);
        memset(firmware, 0xff, firmsize);
+
+       if(hex_load(file, firmsize, firmware) == false){
+               puts("image open error!");
+               goto end;
+       }
+       snrom_ramopen(handle);
+
+       int ppu, cpu = 0;
+       ppu = cartridge_ram_transform(handle, firmware, REQUEST_PPU_WRITE, REQUEST_PPU_READ, 0x0000, 0x2000);
+       if(firmsize >= 0x2000){
+               cpu = cartridge_ram_transform(handle, firmware + 0x2000, REQUEST_CPU_WRITE_6502, REQUEST_CPU_READ, 0x6000, firmsize - 0x2000);
+       }
+       if((ppu == 0) && (cpu == 0)){
+//             write_memory(handle, REQUEST_FIRMWARE_PROGRAM, firmsize, 0x2000, 0, firmware);
+               write_memory(handle, REQUEST_FIRMWARE_PROGRAM, firmsize, 0x0000, 0, firmware);
+               puts("USB connection will be disconnteced. This is normally.");
+               puts("Re-turn on kazzo power.");
+       }else{
+               puts("firmware transform error!");
+       }
+end:
+       free(firmware);
+}
+enum{
+       FIRM_VERSION_OFFSET = 0x3780,
+       BOOTLOADER_VERSION_OFFSET = 0x3d00
+};
+static void firmware_verify(usb_dev_handle *handle, const char *file)
+{
+       uint8_t *firmware, *compare;
+       const int firmsize = 0x3800;
+       assert(firmsize <= 0x3800);
+       firmware = malloc(firmsize);
        compare = malloc(firmsize);
-       if(buf_load(firmware, file, firmsize) == false){
+       memset(compare, 0xff, firmsize);
+//     if(buf_load(compare, file, firmsize) == false){
+       if(hex_load(file, firmsize, compare) == false){
                puts("image open error!");
                goto end;
        }
-       write_memory(handle, REQUEST_PPU_WRITE, 0, firmsize, firmware);
-       read_memory(handle, REQUEST_PPU_READ, INDEX_IMPLIED, 0, firmsize, compare);
+       read_memory(handle, REQUEST_FIRMWARE_DOWNLOAD, INDEX_IMPLIED, 0, firmsize, firmware);
        if(memcmp(firmware, compare, firmsize) == 0){
-               write_memory(handle, REQUEST_FIRMWARE_PROGRAM, 0, 1, firmware);
-               //usb_close(handle);
+               puts("firmware compare ok!");
        }else{
-               puts("firmware transform error!");
+               puts("firmware compare ng!");
+               printf("hex: %s\n", compare + FIRM_VERSION_OFFSET);
+               printf("avr: %s\n", firmware + FIRM_VERSION_OFFSET);
        }
 end:
        free(firmware);
        free(compare);
 }
+static void firmware_download(usb_dev_handle *handle, const char *file)
+{
+       const int firmsize = 0x4000;
+       uint8_t *firmware = malloc(firmsize);
+       read_memory(handle, REQUEST_FIRMWARE_DOWNLOAD, INDEX_IMPLIED, 0, firmsize, firmware);
+       buf_save(firmware, file, firmsize);
+       puts(firmware + FIRM_VERSION_OFFSET);
+       free(firmware);
+}
 
 static void firmware_version(usb_dev_handle *handle)
 {
@@ -90,6 +166,7 @@ static void firmware_version(usb_dev_handle *handle)
        read_memory(handle, REQUEST_FIRMWARE_VERSION, INDEX_IMPLIED, 0, VERSION_STRING_SIZE, (uint8_t *) version);
        puts(version);
 }
+
 int main(int c, char **v)
 {
        usb_init();
@@ -109,7 +186,17 @@ int main(int c, char **v)
                firmware_version(handle);
                break;
        case 3:
-               firmware_update(handle, v[2]);
+               switch(v[1][0]){
+               case 'w':
+                       firmware_update(handle, v[2]);
+                       break;
+               case 'r':
+                       firmware_download(handle, v[2]);
+                       break;
+               case 'v':
+                       firmware_verify(handle, v[2]);
+                       break;
+               }
                break;
        }
        usb_close(handle);
index 7325d02..08bf5b5 100644 (file)
@@ -78,18 +78,19 @@ static void device_write(usb_dev_handle *handle, enum request w, enum index inde
        if(cnt != length){
                puts(__FUNCTION__);
                puts(usb_strerror());
-               exit(1);
+               //exit(1);
        }
        free(d);
 }
 
-void write_memory(usb_dev_handle *handle, enum request r, long address, long length, const uint8_t *data)
+void write_memory(usb_dev_handle *handle, enum request r, enum index index, long address, long length, const uint8_t *data)
 {
-       while(length != 0){
+       //To accept length == 0, use do-while loop
+       do{
                long l = length >= FLASH_PACKET_SIZE ? FLASH_PACKET_SIZE : length;
-               device_write(handle, r, INDEX_IMPLIED, address, l, data);
+               device_write(handle, r, index, address, l, data);
                address += l;
                data += l;
                length -= l;
-       }
+       }while(length != 0);
 }
index 9605751..4e2eaa3 100644 (file)
@@ -2,5 +2,5 @@
 #define _USBDEVICE_H_
 usb_dev_handle *device_open(void);
 void read_memory(usb_dev_handle *handle, const enum request r, enum index index, long address, long length, uint8_t *data);
-void write_memory(usb_dev_handle *handle, enum request r, long address, long length, const uint8_t *data);
+void write_memory(usb_dev_handle *handle, enum request r, enum index index, long address, long length, const uint8_t *data);
 #endif
index c4d3a24..9713ed7 100644 (file)
@@ -67,6 +67,10 @@ CP1  |10uF electric capacitor
 JP1  |toggle switch
 JP2  |push switch
 
+CN4  |
+Tyco Electronics  5530843-8 13.97mm
+Sullins Connector Solutions ECC36DJWN 15.49mm
+Sullins Connector Solutions ECC36DJBN 13.97mm
 ----pin assignment----
 See schematics for switch, register, diode and capacitor connection.