-MCU_164P = MCU=atmega164p TARGET=kazzo_mega164p
-MCU_16 = MCU=atmega16 TARGET=kazzo_mega16
+MCU_164P = MCU=atmega164p TARGET=kazzo_mega164p PCB_REVISION=1
+MCU_16 = MCU=atmega16 TARGET=kazzo_mega16 PCB_REVISION=1
+MCU_88 = MCU=atmega88 TARGET=kazzo_mega88 PCB_REVISION=2
SOURCE_ROOT = Makefile COPYING kazzo_test.exe kazzo_schematics.png readme.txt usbrequest.txt kazzo_mega16.hex kazzo_mega164p.hex
SOURCE_FIRMWARE = \
avr_main.c bus_access.c disk_access.c flashmemory.c \
all:
(cd firmware;make -f firmware.mak $(MCU_164P))
(cd firmware;make -f firmware.mak $(MCU_16))
+ #(cd firmware;make -f firmware.mak $(MCU_88))
(cd hostecho;make)
clean:
(cd firmware;make -f firmware.mak $(MCU_164P) clean)
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>
+#include <avr/pgmspace.h>
#include "usbdrv.h"
#include "bus_access.h"
#include "disk_access.h"
#include "flashmemory.h"
+#include "mcu_program.h"
#include "kazzo_request.h"
//---- global variable ----
return 1; //when returns 0, sometime occours USB commnunication Error
}
+//static uint8_t readbuffer[READ_PACKET_SIZE];
usbMsgLen_t usbFunctionSetup(uchar d[8])
{
static uint8_t readbuffer[READ_PACKET_SIZE];
}
return FLASH_PACKET_SIZE;*/
case REQUEST_DISK_STATUS_GET:
- usbMsgPtr = status;
- return disk_status_get(status);
+ //usbMsgPtr = status;
+ return 0; //disk_status_get(status);
case REQUEST_DISK_READ:
disk_init(DISK_READ);
return 0;
status[0] = vram_connection_get();
usbMsgPtr = status;
return 1;
+ case REQUEST_FIRMWARE_VERSION:{
+ static const PROGMEM char date[VERSION_STRING_SIZE] = "kazzo16 0.1.1 " __DATE__;// " " __TIME__;
+ memcpy_P(readbuffer, date, VERSION_STRING_SIZE);
+ usbMsgPtr = (uint8_t *) readbuffer;
+/* static const char date[VERSION_STRING_SIZE] = "kazzo16 0.1.1 " __DATE__;
+ usbMsgPtr = (uint8_t *) date;*/
+ return VERSION_STRING_SIZE;}
+ case REQUEST_FIRMWARE_PROGRAM:
+ wdt_disable();
+ usbDeviceDisconnect();
+ mcu_data_program(readbuffer, READ_PACKET_SIZE);
+ return 0;
}
return 0;
}
request_both_write = wc_init;
request_cpu_program = wc_init;
request_ppu_program = wc_init;
- uchar i;
bus_init();
usbInit();
usbDeviceDisconnect();
- i = 0;
- while(--i){
- wdt_reset();
- _delay_ms(1);
+ {
+ uchar i;
+ i = 0;
+ while(--i){
+ wdt_reset();
+ _delay_ms(1);
+ }
}
usbDeviceConnect();
sei();
+ wdt_enable(WDTO_500MS);
for(;;){
wdt_reset();
usbPoll();
return ret;
}
+
+__attribute__ ((section(".bootloader.bus")))
+static void boot_address_set(uint16_t address)
+{
+ ADDRESSBUS_A0_A7_OUT = address & 0xff;
+ uint8_t high = (address & 0x7fff) >> 8; //mask A0-A14
+ if((address & (1 << 13)) == 0){ //if A13 == 0
+ high |= 0x80; //set /A13
+ }
+ DATABUS_OUT = high;
+ BUS_CONTROL_OUT = bit_get_negative(ADDRESS_HIGH_LATCH);
+ BUS_CONTROL_OUT = BUS_CLOSE;
+}
+
+__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);
+ direction_read();
+ *data = DATABUS_IN;
+ data += 1;
+ BUS_CONTROL_OUT = BUS_CLOSE;
+ address += 1;
+ length--;
+ }
+ direction_write();
+}
void ppu_write_order(const struct flash_order *t);
uint8_t vram_connection_get(void);
+void mcu_programdata_read(uint16_t address, uint16_t length, uint8_t *data);
+
#include <util/delay.h>
static inline void clock_wait(double clock)
{
F_CPU = 16000000
#FORMAT = srec
-FORMAT = ihex
+#FORMAT = ihex
+FORMAT = binary
# Target file name (without extension).
OBJDIR = ./$(TARGET)
USBDRIVER = ./usbdrv
-SRC = avr_main.c bus_access.c disk_access.c flashmemory.c $(addprefix $(USBDRIVER)/,usbdrv.c oddebug.c)
+SRC = avr_main.c bus_access.c flashmemory.c disk_access.c mcu_program.c $(addprefix $(USBDRIVER)/,usbdrv.c oddebug.c)
ASRC = $(USBDRIVER)/usbdrvasm.S
EXTRAINCDIRS = $(USBDRIVER)
CSTANDARD = -std=gnu99
-CDEFS = -DF_CPU=$(F_CPU)UL -DDEBUG_LEVEL=0
+CDEFS = -DF_CPU=$(F_CPU)UL -DDEBUG_LEVEL=0 -DPCB_REVISION=$(PCB_REVISION)
ADEFS = -DF_CPU=$(F_CPU) -DDEBUG_LEVEL=0
CPPDEFS = -DF_CPU=$(F_CPU)UL
SCANF_LIB =
#SCANF_LIB = $(SCANF_LIB_MIN)
#SCANF_LIB = $(SCANF_LIB_FLOAT)
-
-
MATH_LIB = -lm
-
# List any extra directories to look for libraries here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRALIBDIRS =
-
#---------------- External Memory Options ----------------
-
-# 64 KB of external RAM, starting after internal RAM (ATmega128!),
-# used for variables (.data/.bss) and heap (malloc()).
-#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
-
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# only used for heap (malloc()).
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
-EXTMEMOPTS =
+EXTMEMOPTS = -Wl,--section-start,.bootloader.bus=0x003d80,--section-start,.bootloader=0x003e00
#---------------- Linker Options ----------------
# -Wl,...: tell GCC to pass this to linker.
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
#LDFLAGS += -T linker_script.x
-
-
#---------------- Programming Options (avrdude) ----------------
# Programming hardware
# Type: avrdude -c ?
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
#---------------- Debugging Options ----------------
-
# For simulavr only - target MCU frequency.
DEBUG_MFREQ = $(F_CPU)
# avarice is running on a different computer.
DEBUG_HOST = localhost
-
-
#============================================================================
-
-
# Define programs and commands.
SHELL = sh
CC = avr-gcc
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
2>/dev/null; echo; fi
-
-
# Display compiler version information.
gccversion :
@$(CC) --version
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
- $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
+ $(OBJCOPY) -O $(FORMAT) -R .eeprom --gap-fill=0xff $< $@
%.eep: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
$(NM) -n $< > $@
-
-
# Create library from object files.
.SECONDARY : $(TARGET).a
.PRECIOUS : $(OBJ)
$(REMOVE) $(SRC:.c=.i)
$(REMOVEDIR) .dep
-
# Create object files directory
$(shell mkdir -p $(OBJDIR)/usbdrv 2>/dev/null)
-
# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
-
# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion \
build elf hex eep lss sym coff extcoff \
REQUEST_VRAM_CONNECTION,
//future expanstion
- REQUEST_DISK_STATUS_GET, REQUEST_DISK_READ, REQUEST_DISK_WRITE
+ REQUEST_DISK_STATUS_GET, REQUEST_DISK_READ, REQUEST_DISK_WRITE,
+
+ //bootloader control
+ REQUEST_FIRMWARE_VERSION = 0x80, REQUEST_FIRMWARE_PROGRAM
};
enum index{
INDEX_IMPLIED = 0, INDEX_CPU, INDEX_PPU, INDEX_BOTH
};
enum {
+ VERSION_STRING_SIZE = 0x24,
READ_PACKET_SIZE = 0x0100,
FLASH_PACKET_SIZE = 0x0100
};
--- /dev/null
+#include <stdint.h>
+#include <avr/boot.h>
+#include <avr/interrupt.h>
+#include <avr/pgmspace.h>
+#include <avr/wdt.h>
+#include "bus_access.h"
+/*
+firmware bootloader sequence
+- User insert a cartrige which has charcter RAM. eg. UNROM or SGROM
+- Host send new firmware image with REQUEST_PPU_WRITE.
+- Firmware calc charcter RAM checksum, firmware send result.
+- Firmware reprogram by REQUEST_MCU_DATA_PROGRAM.
+*/
+enum{
+ PROGRAM_MEMORYSIZE = 0x1c00,
+ PROGRAM_PAGESIZE = PROGRAM_MEMORYSIZE / SPM_PAGESIZE
+};
+
+BOOTLOADER_SECTION
+uint8_t mcu_data_check(uint16_t checksum, uint8_t *buf, const uint16_t bufsize)
+{
+ uint16_t sum = 0, address = 0;
+ for(address = 0; address < PROGRAM_MEMORYSIZE; address += bufsize){
+ int i;
+ uint8_t sum8 = 0;
+ mcu_programdata_read(address, bufsize, buf);
+ for(i = 0; i < bufsize; i += 4){
+ sum8 += buf[i + 0];
+ sum8 += buf[i + 1];
+ sum8 += buf[i + 2];
+ sum8 += buf[i + 3];
+ }
+ sum += (uint16_t) sum8;
+ }
+ return checksum == sum;
+}
+
+__attribute__((noreturn))
+BOOTLOADER_SECTION
+void mcu_data_program(uint8_t *buf, const uint16_t bufsize)
+{
+ int page;
+ uint16_t address = 0;
+ cli();
+ eeprom_busy_wait();
+ for(page = 0; page < PROGRAM_PAGESIZE; page++){
+ int i;
+ mcu_programdata_read(address, SPM_PAGESIZE, buf);
+// eeprom_busy_wait();
+ boot_page_erase(address);
+ boot_spm_busy_wait();
+ for(i = 0; i < SPM_PAGESIZE; i += 2){
+ //Set up little-endian word
+ uint16_t w = buf[i+0];
+ w |= buf[i+1] << 8;
+ boot_page_fill(i, w);
+ }
+ boot_page_write(address);
+ boot_spm_busy_wait();
+ address += SPM_PAGESIZE;
+ }
+ boot_rww_enable();
+ sei();
+ wdt_enable(WDTO_500MS);
+endless: //wait watchdog interrupt reset
+ goto endless;
+}
--- /dev/null
+#ifndef _MCU_PROGRAM_H_
+#define _MCU_PROGRAM_H_
+__attribute__((noreturn))
+void mcu_data_program(uint8_t *buf, const uint16_t bufsize);
+#endif
#ifndef __usbconfig_h_included__
#define __usbconfig_h_included__
-#define USB_CFG_IOPORTNAME D
-#define USB_CFG_DMINUS_BIT 4
-#define USB_CFG_DPLUS_BIT 2
-#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
-#define USB_CFG_CHECK_CRC 0
+#if PCB_REVISION == 1
+ #define USB_CFG_IOPORTNAME D
+ #define USB_CFG_DMINUS_BIT 4
+ #define USB_CFG_DPLUS_BIT 2
+ #define USB_CFG_CLOCK_KHZ (F_CPU/1000)
+ #define USB_CFG_CHECK_CRC 0
+#endif
+#if PCB_REVISION == 2
+ #define USB_CFG_IOPORTNAME B
+ #define USB_CFG_DMINUS_BIT 0
+ #define USB_CFG_DPLUS_BIT 1
+ #define USB_CFG_CLOCK_KHZ (F_CPU/1000)
+ #define USB_CFG_CHECK_CRC 0
+#endif
#define USB_CFG_HAVE_INTRIN_ENDPOINT 0
#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0
/* #define USB_INTR_ENABLE GIMSK */
/* #define USB_INTR_ENABLE_BIT INT0 */
/* #define USB_INTR_PENDING GIFR */
-#define USB_INTR_PENDING_BIT INTF0
-#define USB_INTR_CFG_SET ((1 << ISC01) | (1 << ISC00) | (1 << ISC11)| (0 << ISC10))
-/* #define USB_INTR_VECTOR SIG_INTERRUPT0 */
-
-#if 0//def atmega164p
-#define USB_INTR_CFG EICRA
-#define USB_INTR_PENDING EIFR
-#define USB_INTR_ENABLE EIMSK
+#if PCB_REVISION == 1
+ #define USB_INTR_PENDING_BIT INTF0
+ #define USB_INTR_CFG_SET ((1 << ISC01) | (1 << ISC00) | (1 << ISC11)| (0 << ISC10))
+#endif
+#if PCB_REVISION == 2
+ #define USB_INTR_CFG PCICR
+ #define USB_INTR_CFG_SET (1 << PCIE0)
+ #define USB_INTR_ENABLE PCMSK0
+ #define USB_INTR_ENABLE_BIT PCINT0
+ #define USB_INTR_PENDING PCIFR
+ #define USB_INTR_PENDING_BIT PCIF0
+ #define USB_INTR_VECTOR SIG_PIN_CHANGE0
#endif
#endif /* __usbconfig_h_included__ */