diff --git a/src/bootldr/Makefile b/src/bootldr/Makefile index 4e0666b..c421d46 100644 --- a/src/bootldr/Makefile +++ b/src/bootldr/Makefile @@ -55,7 +55,7 @@ TARGET = $(OBJDIR)/sd2snes_bootldr # List C source files here. (C dependencies are automatically generated.) -SRC = timer.c main.c ff.c clock.c uart.c power.c led.c printf.c faulthandler.c crc32.c sdnative.c fileops.c iap.c +SRC = timer.c main.c ff.c clock.c uart.c power.c led.c faulthandler.c crc32.c sdnative.c fileops.c iap.c printf.c # usbcontrol.c usb_hid.c usbhw_lpc.c usbinit.c usbstdreq.c @@ -73,7 +73,6 @@ ASRC = startup.S crc.S # Optimization level, can be [0, 1, 2, 3, s]. # 0 = turn off optimization. s = optimize for size. # (Note: 3 is not always the best optimization level. See avr-libc FAQ.) -# Use s -mcall-prologues when you really need size... #OPT = 2 OPT = s diff --git a/src/bootldr/config.h b/src/bootldr/config.h index 971815d..19841ee 100644 --- a/src/bootldr/config.h +++ b/src/bootldr/config.h @@ -5,7 +5,15 @@ // #define DEBUG_IRQ // #define DEBUG_MSU1 -#define FW_START (0x00004000L) +//#define DEBUG_BL +#ifdef DEBUG_BL +#define DBG_BL +#else +#define DBG_BL while(0) +#endif + + +#define FW_START (0x00002000L) #define FLASH_SECTORS (17) #define VER "0.0.1(NSFW)" diff --git a/src/bootldr/crc32.c b/src/bootldr/crc32.c index 7928cf2..42ece34 100644 --- a/src/bootldr/crc32.c +++ b/src/bootldr/crc32.c @@ -2,7 +2,7 @@ * \file crc32.c * Functions and types for CRC checks. * - * Generated on Sat Sep 25 18:06:34 2010, + * Generated on Mon Feb 21 23:02:07 2011, * by pycrc v0.7.1, http://www.tty1.net/pycrc/ * using the configuration: * Width = 32 @@ -11,83 +11,35 @@ * ReflectIn = True * XorOut = 0xffffffff * ReflectOut = True - * Algorithm = table-driven + * Algorithm = bit-by-bit-fast * Direct = True *****************************************************************************/ #include "crc32.h" -#include "config.h" -#include +#include #include +#include /** - * Static table used for the table_driven implementation. - *****************************************************************************/ -static const uint32_t crc32_table[256] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, - 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, - 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, - 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, - 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, - 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, - 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, - 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, - 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, - 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, - 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, - 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, - 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, - 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, - 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, - 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, - 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, - 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; + * Reflect all bits of a \a data word of \a data_len bytes. + * + * \param data The data word to be reflected. + * \param data_len The width of \a data expressed in number of bits. + * \return The reflected data. +******************************************************************************/ +uint32_t crc_reflect(uint32_t data, size_t data_len) +{ + unsigned int i; + uint32_t ret; + + ret = data & 0x01; + for (i = 1; i < data_len; i++) + { + data >>= 1; + ret = (ret << 1) | (data & 0x01); + } + return ret; +} + /** * Update the crc value with new data. @@ -99,12 +51,22 @@ static const uint32_t crc32_table[256] = { *****************************************************************************/ uint32_t crc32_update(uint32_t crc, const unsigned char data) { - unsigned int tbl_idx; + unsigned int i; + uint32_t bit; + unsigned char c; - tbl_idx = (crc ^ data) & 0xff; - crc = (crc32_table[tbl_idx] ^ (crc >> 8)) & 0xffffffff; - - return crc & 0xffffffff; + c = data; + for (i = 0x01; i & 0xff; i <<= 1) { + bit = crc & 0x80000000; + if (c & i) { + bit = !bit; + } + crc <<= 1; + if (bit) { + crc ^= 0x04c11db7; + } + } + return crc & 0xffffffff; } diff --git a/src/bootldr/crc32.h b/src/bootldr/crc32.h index 9da3054..fbc5e55 100644 --- a/src/bootldr/crc32.h +++ b/src/bootldr/crc32.h @@ -2,7 +2,7 @@ * \file crc32.h * Functions and types for CRC checks. * - * Generated on Sat Sep 25 18:06:37 2010, + * Generated on Mon Feb 21 23:03:39 2011, * by pycrc v0.7.1, http://www.tty1.net/pycrc/ * using the configuration: * Width = 32 @@ -11,13 +11,13 @@ * ReflectIn = True * XorOut = 0xffffffff * ReflectOut = True - * Algorithm = table-driven + * Algorithm = bit-by-bit-fast * Direct = True *****************************************************************************/ #ifndef __CRC___H__ #define __CRC___H__ -#include +#include #include #ifdef __cplusplus @@ -27,7 +27,22 @@ extern "C" { /** * The definition of the used algorithm. *****************************************************************************/ -#define CRC_ALGO_TABLE_DRIVEN 1 +#define CRC_ALGO_BIT_BY_BIT_FAST 1 + +/** + * The type of the CRC values. + * + * This type must be big enough to contain at least 32 bits. + *****************************************************************************/ + +/** + * Reflect all bits of a \a data word of \a data_len bytes. + * + * \param data The data word to be reflected. + * \param data_len The width of \a data expressed in number of bits. + * \return The reflected data. + *****************************************************************************/ +uint32_t crc_reflect(uint32_t data, size_t data_len); /** * Calculate the initial crc value. @@ -36,7 +51,7 @@ extern "C" { *****************************************************************************/ static inline uint32_t crc_init(void) { - return 0xffffffff; + return 0xffffffff; } /** @@ -55,9 +70,9 @@ uint32_t crc32_update(uint32_t crc, const unsigned char data); * \param crc The current crc value. * \return The final crc value. *****************************************************************************/ -static inline uint32_t crc32_finalize(uint32_t crc) +static inline uint32_t crc_finalize(uint32_t crc) { - return crc ^ 0xffffffff; + return crc_reflect(crc, 32) ^ 0xffffffff; } diff --git a/src/bootldr/faulthandler.c b/src/bootldr/faulthandler.c index 47d595f..54bb803 100644 --- a/src/bootldr/faulthandler.c +++ b/src/bootldr/faulthandler.c @@ -1,20 +1,22 @@ #include +#include "config.h" #include "uart.h" void HardFault_Handler(void) { - printf("HFSR: %lx\n", SCB->HFSR); + DBG_BL printf("HFSR: %lx\n", SCB->HFSR); + uart_putc('H'); while (1) ; } void MemManage_Handler(void) { - printf("MemManage - CFSR: %lx; MMFAR: %lx\n", SCB->CFSR, SCB->MMFAR); + DBG_BL printf("MemManage - CFSR: %lx; MMFAR: %lx\n", SCB->CFSR, SCB->MMFAR); } void BusFault_Handler(void) { - printf("BusFault - CFSR: %lx; BFAR: %lx\n", SCB->CFSR, SCB->BFAR); + DBG_BL printf("BusFault - CFSR: %lx; BFAR: %lx\n", SCB->CFSR, SCB->BFAR); } void UsageFault_Handler(void) { - printf("UsageFault - CFSR: %lx; BFAR: %lx\n", SCB->CFSR, SCB->BFAR); + DBG_BL printf("UsageFault - CFSR: %lx; BFAR: %lx\n", SCB->CFSR, SCB->BFAR); } diff --git a/src/bootldr/ff.c b/src/bootldr/ff.c index e8cac79..2d4bdbd 100644 --- a/src/bootldr/ff.c +++ b/src/bootldr/ff.c @@ -2145,7 +2145,6 @@ FRESULT f_read ( UINT rcnt, cc; BYTE csect, *rbuff = buff; - if(btr>512) printf("WARNING: read >512 bytes!!\n"); *br = 0; /* Initialize byte counter */ diff --git a/src/bootldr/ffconf.h b/src/bootldr/ffconf.h index 31f8de9..c61e99d 100644 --- a/src/bootldr/ffconf.h +++ b/src/bootldr/ffconf.h @@ -20,13 +20,13 @@ / data transfer. This reduces memory consumption 512 bytes each file object. */ -#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */ +#define _FS_READONLY 1 /* 0:Read/Write or 1:Read only */ /* Setting _FS_READONLY to 1 defines read only configuration. This removes / writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename, / f_truncate and useless f_getfree. */ -#define _FS_MINIMIZE 2 /* 0 to 3 */ +#define _FS_MINIMIZE 3 /* 0 to 3 */ /* The _FS_MINIMIZE option defines minimization level to remove some functions. / / 0: Full function. diff --git a/src/bootldr/fileops.c b/src/bootldr/fileops.c index 3dd6d10..0bbcd88 100644 --- a/src/bootldr/fileops.c +++ b/src/bootldr/fileops.c @@ -72,14 +72,14 @@ UINT file_read() { return bytes_read; } -UINT file_write() { +/*UINT file_write() { UINT bytes_written; file_res = f_write(&file_handle, file_buf, sizeof(file_buf), &bytes_written); if(bytes_written < sizeof(file_buf)) { printf("wrote less than expected - card full?\n"); } return bytes_written; -} +}*/ UINT file_readblock(void* buf, uint32_t addr, uint16_t size) { UINT bytes_read; @@ -91,13 +91,13 @@ UINT file_readblock(void* buf, uint32_t addr, uint16_t size) { return bytes_read; } -UINT file_writeblock(void* buf, uint32_t addr, uint16_t size) { +/*UINT file_writeblock(void* buf, uint32_t addr, uint16_t size) { UINT bytes_written; file_res = f_lseek(&file_handle, addr); if(file_res) return 0; file_res = f_write(&file_handle, buf, size, &bytes_written); return bytes_written; -} +}*/ uint8_t file_getc() { if(file_block_off == file_block_max) { diff --git a/src/bootldr/iap.c b/src/bootldr/iap.c index 81b6e26..d0835c0 100644 --- a/src/bootldr/iap.c +++ b/src/bootldr/iap.c @@ -6,6 +6,7 @@ #include "uart.h" #include "fileops.h" #include "crc32.h" +#include "led.h" uint32_t iap_cmd[5]; uint32_t iap_res[5]; @@ -14,7 +15,7 @@ uint32_t flash_sig[4]; IAP iap_entry = (IAP) IAP_LOCATION; uint32_t calc_flash_crc(uint32_t start, uint32_t len) { - printf("calc_flash_crc(%08lx, %08lx) {\n", start, len); + DBG_BL printf("calc_flash_crc(%08lx, %08lx) {\n", start, len); uint32_t end = start + len; if(end > 0x20000) { len = 0x1ffff - start; @@ -26,20 +27,20 @@ uint32_t calc_flash_crc(uint32_t start, uint32_t len) { crc = crc32_update(crc, *(const unsigned char*)(s)); s++; } - crc ^= 0xffffffff; - printf(" crc generated. result=%08lx\n", crc); - printf("} //calc_flash_crc\n"); + crc = crc_finalize(crc); + DBG_BL printf(" crc generated. result=%08lx\n", crc); + DBG_BL printf("} //calc_flash_crc\n"); return crc; } void test_iap() { iap_cmd[0]=54; iap_entry(iap_cmd, iap_res); - printf("Part ID=%08lx\n", iap_res[1]); + DBG_BL printf("Part ID=%08lx\n", iap_res[1]); } void print_header(sd2snes_fw_header *header) { - printf(" magic = %08lx\n version = %08lx\n size = %08lx\n crc = %08lx\n ~crc = %08lx\n", + DBG_BL printf(" magic = %08lx\n version = %08lx\n size = %08lx\n crc = %08lx\n ~crc = %08lx\n", header->magic, header->version, header->size, header->crc, header->crcc); } @@ -61,11 +62,11 @@ FLASH_RES check_flash() { sd2snes_fw_header *fw_header = (sd2snes_fw_header*) FW_START; uint32_t flash_addr = FW_START; if(flash_addr != FW_START) { - printf("address sanity check failed. expected 0x%08lx, got 0x%08lx.\nSomething is terribly wrong.\nBailing out to avoid bootldr self-corruption.\n", FW_START, flash_addr); + DBG_BL printf("address sanity check failed. expected 0x%08lx, got 0x%08lx.\nSomething is terribly wrong.\nBailing out to avoid bootldr self-corruption.\n", FW_START, flash_addr); return ERR_HW; } - printf("Current flash contents:\n"); - print_header(fw_header); + DBG_BL printf("Current flash contents:\n"); + DBG_BL print_header(fw_header); uint32_t crc = calc_flash_crc(flash_addr + 0x100, (fw_header->size & 0x1ffff)); return check_header(fw_header, crc); } @@ -74,7 +75,6 @@ IAP_RES iap_wrap(uint32_t *iap_cmd, uint32_t *iap_res) { NVIC_DisableIRQ(RIT_IRQn); NVIC_DisableIRQ(UART_IRQ); iap_entry(iap_cmd, iap_res); - NVIC_EnableIRQ(RIT_IRQn); NVIC_EnableIRQ(UART_IRQ); return iap_res[0]; } @@ -116,20 +116,21 @@ FLASH_RES flash_file(uint8_t *filename) { sd2snes_fw_header file_header; UINT bytes_read; if(flash_addr != FW_START) { - printf("address sanity check failed. expected 0x%08lx, got 0x%08lx.\nSomething is terribly wrong.\nBailing out to avoid bootldr self-corruption.\n", FW_START, flash_addr); + DBG_BL printf("address sanity check failed. expected 0x%08lx, got 0x%08lx.\nSomething is terribly wrong.\nBailing out to avoid bootldr self-corruption.\n", FW_START, flash_addr); return ERR_HW; } file_open(filename, FA_READ); if(file_res) { - printf("file_open: error %d\n", file_res); + DBG_BL printf("file_open: error %d\n", file_res); return ERR_FS; } - printf("firmware image found. file size: %ld\n", file_handle.fsize); - printf("reading header...\n"); + DBG_BL printf("firmware image found. file size: %ld\n", file_handle.fsize); + DBG_BL printf("reading header...\n"); f_read(&file_handle, &file_header, 32, &bytes_read); print_header(&file_header); if(check_flash() || file_header.version != fw_header->version || file_header.version == FW_MAGIC || fw_header->version == FW_MAGIC) { - f_lseek(&file_handle, 0x100); + uart_putc('F'); + f_read(&file_handle, file_buf, 0xe0, &bytes_read); for(;;) { bytes_read = file_read(); if(file_res || !bytes_read) break; @@ -137,48 +138,59 @@ FLASH_RES flash_file(uint8_t *filename) { file_crc = crc32_update(file_crc, file_buf[count]); } } - file_crc ^= 0xffffffff; - printf("file crc=%08lx\n", file_crc); + file_crc = crc_finalize(file_crc); + DBG_BL printf("file crc=%08lx\n", file_crc); if(check_header(&file_header, file_header.crc) != ERR_OK) { - printf("Invalid firmware file (header corrupted).\n"); + DBG_BL printf("Invalid firmware file (header corrupted).\n"); return ERR_FILEHD; } if(file_header.crc != file_crc) { - printf("Firmware file checksum error.\n"); + DBG_BL printf("Firmware file checksum error.\n"); return ERR_FILECHK; } uint32_t res; - printf("erasing flash...\n"); + DBG_BL printf("erasing flash...\n"); if((res = iap_prepare_for_write(FW_START / 0x1000, FLASH_SECTORS)) != CMD_SUCCESS) { - printf("error %ld while preparing for erase\n", res); + DBG_BL printf("error %ld while preparing for erase\n", res); return ERR_FLASHPREP; }; if((res = iap_erase(FW_START / 0x1000, FLASH_SECTORS)) != CMD_SUCCESS) { - printf("error %ld while erasing\n", res); + DBG_BL printf("error %ld while erasing\n", res); return ERR_FLASHERASE; } - printf("writing... @%08lx\n", flash_addr); - f_lseek(&file_handle, 0); + DBG_BL printf("writing... @%08lx\n", flash_addr); + file_close(); + file_open(filename, FA_READ); uint8_t current_sec; - + uint32_t total_read = 0; for(flash_addr = FW_START; flash_addr < 0x00020000; flash_addr += 0x200) { - bytes_read = file_read(); + total_read += (bytes_read = file_read()); if(file_res || !bytes_read) break; current_sec = flash_addr & 0x10000 ? (16 + ((flash_addr >> 15) & 1)) : (flash_addr >> 12); - printf("current_sec=%d flash_addr=%08lx\n", current_sec, flash_addr); + DBG_BL printf("current_sec=%d flash_addr=%08lx\n", current_sec, flash_addr); + uart_putc('.'); + toggle_rdy_led(); if(current_sec < (FW_START / 0x1000)) return ERR_FLASH; if((res = iap_prepare_for_write(current_sec, current_sec)) != CMD_SUCCESS) { - printf("error %ld while preparing sector %d for write\n", res, current_sec); + DBG_BL printf("error %ld while preparing sector %d for write\n", res, current_sec); + return ERR_FLASH; } if((res = iap_ram2flash(flash_addr, file_buf, 512)) != CMD_SUCCESS) { - printf("error %ld while writing to address %08lx (sector %d)\n", res, flash_addr, current_sec); + DBG_BL printf("error %ld while writing to address %08lx (sector %d)\n", res, flash_addr, current_sec); + return ERR_FLASH; } } + if(total_read != file_header.size) { + DBG_BL printf("wrote less data than expected! (%08lx vs. %08lx)\n", total_read, file_header.size); + uart_putc('X'); + return ERR_FILECHK; + } } else { - printf("flash content is ok, no version mismatch, no forced upgrade. No need to flash\n"); + uart_putc('n'); + DBG_BL printf("flash content is ok, no version mismatch, no forced upgrade. No need to flash\n"); } return ERR_OK; } diff --git a/src/bootldr/led.c b/src/bootldr/led.c index 103dc25..ef537ea 100644 --- a/src/bootldr/led.c +++ b/src/bootldr/led.c @@ -5,53 +5,25 @@ #include "timer.h" #include "led.h" -static uint8_t led_bright[16]={255,253,252,251,249,247,244,239,232,223,210,191,165,127,74,0}; - int led_rdyledstate = 0; int led_readledstate = 0; int led_writeledstate = 0; -int led_pwmstate = 0; void rdyled(unsigned int state) { - if(led_pwmstate) { - rdybright(state?15:0); - } else { - BITBAND(LPC_GPIO2->FIODIR, 0) = state; - } + BITBAND(LPC_GPIO2->FIODIR, 0) = state; led_rdyledstate = state; } void readled(unsigned int state) { - if(led_pwmstate) { - readbright(state?15:0); - } else { - BITBAND(LPC_GPIO2->FIODIR, 1) = state; - } + BITBAND(LPC_GPIO2->FIODIR, 1) = state; led_readledstate = state; } void writeled(unsigned int state) { - if(led_pwmstate) { - writebright(state?15:0); - } else { - BITBAND(LPC_GPIO2->FIODIR, 2) = state; - } + BITBAND(LPC_GPIO2->FIODIR, 2) = state; led_writeledstate = state; } -void rdybright(uint8_t bright) { - LPC_PWM1->MR1 = led_bright[(bright & 15)]; - BITBAND(LPC_PWM1->LER, 1) = 1; -} -void readbright(uint8_t bright) { - LPC_PWM1->MR2 = led_bright[(bright & 15)]; - BITBAND(LPC_PWM1->LER, 2) = 1; -} -void writebright(uint8_t bright) { - LPC_PWM1->MR3 = led_bright[(bright & 15)]; - BITBAND(LPC_PWM1->LER, 3) = 1; -} - void led_clkout32(uint32_t val) { while(1) { rdyled(1); @@ -64,7 +36,7 @@ void led_clkout32(uint32_t val) { } void toggle_rdy_led() { - rdyled(~led_rdyledstate); + rdyled(!led_rdyledstate); } void toggle_read_led() { @@ -84,24 +56,6 @@ void led_panic() { } } -void led_pwm() { -/* connect PWM to P2.0 - P2.2 */ -/* XXX Rev.B P2.???? */ - BITBAND(LPC_PINCON->PINSEL4, 1) = 0; - BITBAND(LPC_PINCON->PINSEL4, 3) = 0; - BITBAND(LPC_PINCON->PINSEL4, 5) = 0; - - BITBAND(LPC_PINCON->PINSEL4, 0) = 1; - BITBAND(LPC_PINCON->PINSEL4, 2) = 1; - BITBAND(LPC_PINCON->PINSEL4, 4) = 1; - - BITBAND(LPC_PWM1->PCR, 9) = 1; - BITBAND(LPC_PWM1->PCR, 10) = 1; - BITBAND(LPC_PWM1->PCR, 11) = 1; - - led_pwmstate = 1; -} - void led_std() { BITBAND(LPC_PINCON->PINSEL4, 1) = 0; BITBAND(LPC_PINCON->PINSEL4, 3) = 0; @@ -110,12 +64,6 @@ void led_std() { BITBAND(LPC_PINCON->PINSEL4, 0) = 0; BITBAND(LPC_PINCON->PINSEL4, 2) = 0; BITBAND(LPC_PINCON->PINSEL4, 4) = 0; - - BITBAND(LPC_PWM1->PCR, 9) = 0; - BITBAND(LPC_PWM1->PCR, 10) = 0; - BITBAND(LPC_PWM1->PCR, 11) = 0; - - led_pwmstate = 0; } void led_init() { @@ -123,9 +71,4 @@ void led_init() { /* set PCLK divider to 8 */ BITBAND(LPC_SC->PCLKSEL1, 21) = 1; BITBAND(LPC_SC->PCLKSEL1, 20) = 1; - LPC_PWM1->MR0 = 255; - BITBAND(LPC_PWM1->LER, 0) = 1; - BITBAND(LPC_PWM1->TCR, 0) = 1; - BITBAND(LPC_PWM1->TCR, 3) = 1; - BITBAND(LPC_PWM1->MCR, 1) = 1; } diff --git a/src/bootldr/led.h b/src/bootldr/led.h index bb45b1a..ce97426 100644 --- a/src/bootldr/led.h +++ b/src/bootldr/led.h @@ -3,9 +3,6 @@ #ifndef _LED_H #define _LED_H -void readbright(uint8_t bright); -void writebright(uint8_t bright); -void rdybright(uint8_t bright); void readled(unsigned int state); void writeled(unsigned int state); void rdyled(unsigned int state); @@ -14,7 +11,6 @@ void toggle_rdy_led(void); void toggle_read_led(void); void toggle_write_led(void); void led_panic(void); -void led_pwm(void); void led_std(void); void led_init(void); diff --git a/src/bootldr/lpc1754boot.ld b/src/bootldr/lpc1754boot.ld index 954e49d..e0d8512 100644 --- a/src/bootldr/lpc1754boot.ld +++ b/src/bootldr/lpc1754boot.ld @@ -10,7 +10,7 @@ ENTRY(_start) MEMORY { - flash (rx) : ORIGIN = 0x00000000, LENGTH = 0x05000 + flash (rx) : ORIGIN = 0x00000000, LENGTH = 0x03000 ram (rwx) : ORIGIN = 0x10000000, LENGTH = 0x03fe0 /* leave room for IAP */ ahbram (rwx) : ORIGIN = 0x2007C000, LENGTH = 0x04000 } diff --git a/src/bootldr/main.c b/src/bootldr/main.c index 6f84e06..7765fbc 100644 --- a/src/bootldr/main.c +++ b/src/bootldr/main.c @@ -44,14 +44,16 @@ int main(void) { timer_init(); uart_init(); led_init(); + readled(0); + rdyled(0); + writeled(0); /* do this last because the peripheral init()s change PCLK dividers */ clock_init(); LPC_PINCON->PINSEL0 |= BV(20) | BV(21); /* MAT3.0 (FPGA clock) */ -led_pwm(); sdn_init(); - printf("chksum=%08lx\n", *(uint32_t*)28); - printf("\n\nsd2snes mk.2 bootloader\nver.: " VER "\ncpu clock: %ld Hz\n", CONFIG_CPU_FREQUENCY); -printf("PCONP=%lx\n", LPC_SC->PCONP); + DBG_BL printf("chksum=%08lx\n", *(uint32_t*)28); + DBG_BL printf("\n\nsd2snes mk.2 bootloader\nver.: " VER "\ncpu clock: %ld Hz\n", CONFIG_CPU_FREQUENCY); +DBG_BL printf("PCONP=%lx\n", LPC_SC->PCONP); /* setup timer (fpga clk) */ LPC_TIM3->CTCR=0; LPC_TIM3->EMR=EMC0TOGGLE; @@ -59,13 +61,21 @@ printf("PCONP=%lx\n", LPC_SC->PCONP); LPC_TIM3->MR0=1; LPC_TIM3->TCR=1; - test_iap(); FLASH_RES res = flash_file((uint8_t*)"/sd2snes/firmware.img"); - printf("flash result = %d\n", res); + if(res == ERR_FLASHPREP || res == ERR_FLASHERASE || res == ERR_FLASH) { + writeled(1); + } + if(res == ERR_FILEHD || res == ERR_FILECHK) { + readled(1); + } + DBG_BL printf("flash result = %d\n", res); if(res != ERR_OK) { if((res = check_flash()) != ERR_OK) { - printf("check_flash() failed with error %d, not booting.\n", res); - while(1); + DBG_BL printf("check_flash() failed with error %d, not booting.\n", res); + while(1) { + toggle_rdy_led(); + delay_ms(500); + } } } NVIC_DisableIRQ(RIT_IRQn); diff --git a/src/bootldr/printf.c b/src/bootldr/printf.c index 861c03d..a8988c9 100644 --- a/src/bootldr/printf.c +++ b/src/bootldr/printf.c @@ -47,6 +47,7 @@ #define FLAG_UNSIGNED 64 #define FLAG_NEGATIVE 128 +#ifdef DEBUG_BL /* Digits used for conversion */ static const char hexdigits[] = "0123456789abcdef"; @@ -289,3 +290,11 @@ int putchar(int c) { uart_putc(c); return 0; } + +#else +int printf(const char *format, ...) { return 0; } +int snprintf(char *str, size_t size, const char *format, ...) { return 0; } +int puts(const char *str) { return 0; } +#undef putchar +int putchar(int c) { return 0; } +#endif diff --git a/src/bootldr/sdnative.c b/src/bootldr/sdnative.c index 943932d..1621781 100644 --- a/src/bootldr/sdnative.c +++ b/src/bootldr/sdnative.c @@ -152,24 +152,6 @@ static uint32_t getbits(void *buffer, uint16_t start, int8_t bits) { return result; } -static inline void wiggle_slow_pos(uint16_t times) { - while(times--) { - delay_us(2); - BITBAND(SD_CLKREG->FIOSET, SD_CLKPIN) = 1; - delay_us(2); - BITBAND(SD_CLKREG->FIOCLR, SD_CLKPIN) = 1; - } -} - -static inline void wiggle_slow_neg(uint16_t times) { - while(times--) { - delay_us(2); - BITBAND(SD_CLKREG->FIOCLR, SD_CLKPIN) = 1; - delay_us(2); - BITBAND(SD_CLKREG->FIOSET, SD_CLKPIN) = 1; - } -} - static inline void wiggle_fast_pos(uint16_t times) { while(times--) { BITBAND(SD_CLKREG->FIOSET, SD_CLKPIN) = 1; @@ -201,77 +183,6 @@ static inline void wait_busy(void) { wiggle_fast_neg(4); } -/* - send_command_slow - send SD command and put response in rsp. - returns length of response or 0 if there was no response -*/ -int send_command_slow(uint8_t* cmd, uint8_t* rsp){ - uint8_t shift, i=6; - int rsplen; - uint8_t cmdno = *cmd & 0x3f; - wiggle_slow_pos(5); - switch(*cmd & 0x3f) { - case 0: - rsplen = 0; - break; - case 2: - case 9: - case 10: - rsplen = 17; - break; - default: - rsplen = 6; - } - /* send command */ - BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 1; - - while(i--) { - shift = 8; - do { - shift--; - uint8_t data = *cmd; - *cmd<<=1; - if(data&0x80) { - BITBAND(SD_CMDREG->FIOSET, SD_CMDPIN) = 1; - } else { - BITBAND(SD_CMDREG->FIOCLR, SD_CMDPIN) = 1; - } - wiggle_slow_pos(1); - } while (shift); - cmd++; - } - - wiggle_slow_pos(1); - BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 0; - - if(rsplen) { - uint16_t timeout=1000; - while((BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) && --timeout) { - wiggle_slow_neg(1); - } - if(!timeout) { - printf("CMD%d timed out\n", cmdno); - return 0; /* no response within timeout */ - } - - i=rsplen; - while(i--) { - shift = 8; - uint8_t data=0; - do { - shift--; - data |= (BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) << shift; - wiggle_slow_neg(1); - } while (shift); - *rsp=data; - rsp++; - } - } - return rsplen; -} - - /* send_command_fast send SD command and put response in rsp. @@ -305,7 +216,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){ rsplen = 6; } if(dat && (buf==NULL)) { - printf("send_command_fast error: buf is null but data transfer expected.\n"); + DBG_SD printf("send_command_fast error: buf is null but data transfer expected.\n"); return 0; } /* send command */ @@ -337,7 +248,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){ wiggle_fast_neg1(); } if(!timeout) { - printf("CMD%d timed out\n", cmdno); + DBG_SD printf("CMD%d timed out\n", cmdno); return 0; /* no response within timeout */ } @@ -348,7 +259,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){ do { if(dat) { if(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) { - printf("data start during response\n"); + DBG_SD printf("data start during response\n"); j=datcnt; state=CMD_RSPDAT; break; @@ -470,28 +381,6 @@ static inline void make_crc7(uint8_t* cmd) { cmd[5]=(cmd[5] << 1) | 1; } -int cmd_slow(uint8_t cmd, uint32_t param, uint8_t crc, uint8_t* dat, uint8_t* rsp) { - uint8_t cmdbuf[6]; - cmdbuf[0] = 0x40 | cmd; - cmdbuf[1] = param >> 24; - cmdbuf[2] = param >> 16; - cmdbuf[3] = param >> 8; - cmdbuf[4] = param; - if(!crc) { - make_crc7(cmdbuf); - } else { - cmdbuf[5] = crc; - } - return send_command_slow(cmdbuf, rsp); -} - -int acmd_slow(uint8_t cmd, uint32_t param, uint8_t crc, uint8_t* dat, uint8_t* rsp) { - if(!(cmd_slow(APP_CMD, rca, 0, NULL, rsp))) { - return 0; - } - return cmd_slow(cmd, param, crc, dat, rsp); -} - int cmd_fast(uint8_t cmd, uint32_t param, uint8_t crc, uint8_t* dat, uint8_t* rsp) { uint8_t cmdbuf[6]; cmdbuf[0] = 0x40 | cmd; @@ -652,11 +541,11 @@ void send_datablock(uint8_t *buf) { } while (datshift); DBG_SD printf("crc %02x\n", dat0); if((dat0 & 7) != 2) { - printf("crc error! %02x\n", dat0); + DBG_SD printf("crc error! %02x\n", dat0); while(1); } if(dat0 & 8) { - printf("missing start bit in CRC status response...\n"); + DBG_SD printf("missing start bit in CRC status response...\n"); } wiggle_fast_neg(2); wait_busy(); @@ -743,57 +632,57 @@ DRESULT sdn_initialize(BYTE drv) { prior to initialization */ for(rsplen=0; rsplen<2042; rsplen++) { if(!(BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN))) { - printf("card seems to be sending data, attempting deselect\n"); - cmd_slow(SELECT_CARD, 0, 0, NULL, rsp); + DBG_SD printf("card seems to be sending data, attempting deselect\n"); + cmd_fast(SELECT_CARD, 0, 0, NULL, rsp); } - wiggle_slow_neg(1); + wiggle_fast_neg(1); } - printf("sd_init start\n"); - cmd_slow(GO_IDLE_STATE, 0, 0x95, NULL, rsp); + DBG_SD printf("sd_init start\n"); + cmd_fast(GO_IDLE_STATE, 0, 0x95, NULL, rsp); - if((rsplen=cmd_slow(SEND_IF_COND, 0x000001aa, 0x87, NULL, rsp))) { + if((rsplen=cmd_fast(SEND_IF_COND, 0x000001aa, 0x87, NULL, rsp))) { DBG_SD printf("CMD8 response:\n"); DBG_SD uart_trace(rsp, 0, rsplen); hcs=1; } while(1) { - if(!(acmd_slow(SD_SEND_OP_COND, (hcs << 30) | 0xfc0000, 0, NULL, rsp))) { - printf("ACMD41 no response!\n"); + if(!(acmd_fast(SD_SEND_OP_COND, (hcs << 30) | 0xfc0000, 0, NULL, rsp))) { + DBG_SD printf("ACMD41 no response!\n"); } if(rsp[1]&0x80) break; } ccs = (rsp[1]>>6) & 1; /* SDHC/XC */ - cmd_slow(ALL_SEND_CID, 0, 0x4d, NULL, rsp); - if(cmd_slow(SEND_RELATIVE_ADDR, 0, 0x21, NULL, rsp)) { + cmd_fast(ALL_SEND_CID, 0, 0x4d, NULL, rsp); + if(cmd_fast(SEND_RELATIVE_ADDR, 0, 0x21, NULL, rsp)) { rca=(rsp[1]<<24) | (rsp[2]<<16); - printf("RCA: %04lx\n", rca>>16); + DBG_SD printf("RCA: %04lx\n", rca>>16); } else { - printf("CMD3 no response!\n"); + DBG_SD printf("CMD3 no response!\n"); rca=0; } /* record CSD for getinfo */ - cmd_slow(SEND_CSD, rca, 0, NULL, rsp); + cmd_fast(SEND_CSD, rca, 0, NULL, rsp); /* select the card */ - if(cmd_slow(SELECT_CARD, rca, 0, NULL, rsp)) { - printf("card selected!\n"); + if(cmd_fast(SELECT_CARD, rca, 0, NULL, rsp)) { + DBG_SD printf("card selected!\n"); } else { - printf("CMD7 no response!\n"); + DBG_SD printf("CMD7 no response!\n"); } /* get card status */ - cmd_slow(SEND_STATUS, rca, 0, NULL, rsp); + cmd_fast(SEND_STATUS, rca, 0, NULL, rsp); /* set bus width */ - acmd_slow(SD_SET_BUS_WIDTH, 0x2, 0, NULL, rsp); + acmd_fast(SD_SET_BUS_WIDTH, 0x2, 0, NULL, rsp); /* set block length */ - cmd_slow(SET_BLOCKLEN, 0x200, 0, NULL, rsp); + cmd_fast(SET_BLOCKLEN, 0x200, 0, NULL, rsp); - printf("SD init complete. SDHC/XC=%d\n", ccs); + DBG_SD printf("SD init complete. SDHC/XC=%d\n", ccs); disk_state = DISK_OK; during_blocktrans = TRANS_NONE; return sdn_status(drv); @@ -861,7 +750,7 @@ DRESULT sdn_getinfo(BYTE drv, BYTE page, void *buffer) { di->sectorsize = 2; di->sectorcount = capacity; - printf("card capacity: %lu sectors\n", capacity); + DBG_SD printf("card capacity: %lu sectors\n", capacity); return RES_OK; } DRESULT disk_getinfo(BYTE drv, BYTE page, void *buffer) __attribute__ ((weak, alias("sdn_getinfo"))); @@ -889,7 +778,7 @@ DRESULT disk_write(BYTE drv, const BYTE *buffer, DWORD sector, BYTE count) __att /* Detect changes of SD card 0 */ void sdn_changed() { if (sd_changed) { - printf("ch "); + DBG_SD printf("ch "); if(SDCARD_DETECT) { disk_state = DISK_CHANGED; } else { diff --git a/src/bootldr/uart.h b/src/bootldr/uart.h index f884313..93f4ed3 100644 --- a/src/bootldr/uart.h +++ b/src/bootldr/uart.h @@ -7,8 +7,8 @@ #ifndef UART_H #define UART_H -#include #include +#include #include "config.h" //#ifdef CONFIG_UART_DEBUG