X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=Bootloader%2Fmain.c;h=aabaeebe502842c77922d49ded00763311bb6238;hb=7b7a55899f392ebb7f615fd1801aaaa3dcc3f738;hp=d1fbb862c81199b01f39a2553c5184f846e6fccd;hpb=41025125796f2f167d7f2a8c82aac712da1aa1b1;p=kiibohd-controller.git diff --git a/Bootloader/main.c b/Bootloader/main.c index d1fbb86..aabaeeb 100644 --- a/Bootloader/main.c +++ b/Bootloader/main.c @@ -1,5 +1,5 @@ /* Copyright (c) 2011,2012 Simon Schubert <2@0x2c.org>. - * Modifications by Jacob Alexander 2014 + * Modifications by Jacob Alexander 2014-2015 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,11 +15,14 @@ * along with this program. If not, see . */ -// ----- Local Includes ----- +// ----- Includes ----- +// Local Includes #include "mchck.h" #include "dfu.desc.h" +#include "debug.h" + // ----- Variables ----- @@ -27,46 +30,141 @@ /** * Unfortunately we can't DMA directly to FlexRAM, so we'll have to stage here. */ -static char staging[FLASH_SECTOR_SIZE]; +static char staging[ USB_DFU_TRANSFER_SIZE ]; // ----- Functions ----- -static enum dfu_status setup_write(size_t off, size_t len, void **buf) +int sector_print( void* buf, size_t sector, size_t chunks ) +{ + uint8_t* start = (uint8_t*)buf + sector * USB_DFU_TRANSFER_SIZE; + uint8_t* end = (uint8_t*)buf + (sector + 1) * USB_DFU_TRANSFER_SIZE; + uint8_t* pos = start; + + // Verify if sector erased + FTFL.fccob.read_1s_section.fcmd = FTFL_FCMD_READ_1s_SECTION; + FTFL.fccob.read_1s_section.addr = (uintptr_t)start; + FTFL.fccob.read_1s_section.margin = FTFL_MARGIN_NORMAL; + FTFL.fccob.read_1s_section.num_words = 250; // 2000 kB / 64 bits + int retval = ftfl_submit_cmd(); + +#ifdef FLASH_DEBUG + print( NL ); + print("Block "); + printHex( sector ); + print(" "); + printHex( (size_t)start ); + print(" -> "); + printHex( (size_t)end ); + print(" Erased: "); + printHex( retval ); + print( NL ); +#endif + + // Display sector + for ( size_t line = 0; pos < end - 24; line++ ) + { + // Each Line + printHex_op( (size_t)pos, 4 ); + print(": "); + + // Each 2 byte chunk + for ( size_t chunk = 0; chunk < chunks; chunk++ ) + { + // Print out the two bytes (second one first) + printHex_op( *(pos + 1), 2 ); + printHex_op( *pos, 2 ); + print(" "); + pos += 2; + } + + print( NL ); + } + + return retval; +} + +static enum dfu_status setup_read( size_t off, size_t *len, void **buf ) +{ + // Calculate starting address from offset + *buf = (void*)&_app_rom + (USB_DFU_TRANSFER_SIZE / 4) * off; + + // Calculate length of transfer + /* + *len = *buf > (void*)(&_app_rom_end) - USB_DFU_TRANSFER_SIZE + ? 0 : USB_DFU_TRANSFER_SIZE; + */ + + // Check for error + /* + if ( *buf > (void*)&_app_rom_end ) + return (DFU_STATUS_errADDRESS); + */ + + return (DFU_STATUS_OK); +} + +static enum dfu_status setup_write( size_t off, size_t len, void **buf ) { - static int last = 0; - - if (len > sizeof(staging)) - return (DFU_STATUS_errADDRESS); - - // We only allow the last write to be less than one sector size. - if (off == 0) - last = 0; - if (last && len != 0) - return (DFU_STATUS_errADDRESS); - if (len != FLASH_SECTOR_SIZE) { - last = 1; - memset(staging, 0xff, sizeof(staging)); - } - - *buf = staging; - return (DFU_STATUS_OK); + static int last = 0; + +#ifdef FLASH_DEBUG + // Debug + print("Setup Write: offset("); + printHex( off ); + print(") len("); + printHex( len ); + print(") last("); + printHex( last ); + printNL(")"); +#endif + + if ( len > sizeof(staging) ) + return (DFU_STATUS_errADDRESS); + + // We only allow the last write to be less than one sector size. + if ( off == 0 ) + last = 0; + if ( last && len != 0 ) + return (DFU_STATUS_errADDRESS); + if ( len != USB_DFU_TRANSFER_SIZE ) + { + last = 1; + memset( staging, 0xff, sizeof(staging) ); + } + + *buf = staging; + return (DFU_STATUS_OK); } static enum dfu_status finish_write( void *buf, size_t off, size_t len ) { - void *target; - if (len == 0) - return (DFU_STATUS_OK); - - target = flash_get_staging_area(off + (uintptr_t)&_app_rom, FLASH_SECTOR_SIZE); - if (!target) - return (DFU_STATUS_errADDRESS); - memcpy(target, buf, len); - if (flash_program_sector(off + (uintptr_t)&_app_rom, FLASH_SECTOR_SIZE) != 0) - return (DFU_STATUS_errADDRESS); - return (DFU_STATUS_OK); + void *target; + if ( len == 0 ) + return (DFU_STATUS_OK); + + target = flash_get_staging_area( off + (uintptr_t)&_app_rom, USB_DFU_TRANSFER_SIZE ); + if ( !target ) + return (DFU_STATUS_errADDRESS); + memcpy( target, buf, len ); + + // Depending on the error return a different status + switch ( flash_program_sector( off + (uintptr_t)&_app_rom, USB_DFU_TRANSFER_SIZE ) ) + { + /* + case FTFL_FSTAT_RDCOLERR: // Flash Read Collision Error + case FTFL_FSTAT_ACCERR: // Flash Access Error + case FTFL_FSTAT_FPVIOL: // Flash Protection Violation Error + return (DFU_STATUS_errADDRESS); + case FTFL_FSTAT_MGSTAT0: // Memory Controller Command Completion Error + return (DFU_STATUS_errADDRESS); + */ + + case 0: + default: // No error + return (DFU_STATUS_OK); + } } @@ -74,23 +172,61 @@ static struct dfu_ctx dfu_ctx; void init_usb_bootloader( int config ) { - dfu_init(setup_write, finish_write, &dfu_ctx); + dfu_init( setup_read, setup_write, finish_write, &dfu_ctx ); } void main() { +#if defined(_mk20dx128vlf5_) // Kiibohd-dfu / Infinity + // XXX McHCK uses B16 instead of A19 + // Enabling LED to indicate we are in the bootloader GPIOA_PDDR |= (1<<19); // Setup pin - A19 - See Lib/pin_map.mchck for more details on pins PORTA_PCR19 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); GPIOA_PSOR |= (1<<19); - flash_prepare_flashing(); - - usb_init( &dfu_device ); - for (;;) +#elif defined(_mk20dx256vlh7_) // Kiibohd-dfu + // Enabling LED to indicate we are in the bootloader + GPIOA_PDDR |= (1<<5); + // Setup pin - A5 - See Lib/pin_map.mchck for more details on pins + PORTA_PCR5 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); + GPIOA_PSOR |= (1<<5); + + // TODO Add CMake configuration for disabling + // Set LCD backlight on ICED to Red + GPIOC_PDDR |= (1<<1); + PORTC_PCR1 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); + GPIOC_PCOR |= (1<<1); +#else +#error "Incompatible chip for bootloader" +#endif + + uart_serial_setup(); + printNL( NL "Bootloader DFU-Mode" ); + + // Bootloader Enter Reasons + print(" RCM_SRS0 - "); + printHex( RCM_SRS0 & 0x60 ); + print( NL " RCM_SRS1 - "); + printHex( RCM_SRS1 & 0x02 ); + print( NL " _app_rom - "); + printHex( (uint32_t)_app_rom ); + print( NL " Soft Rst - " ); + printHex( memcmp( (uint8_t*)&VBAT, sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic) ) == 0 ); + print( NL ); + +#ifdef FLASH_DEBUG + for ( uint8_t sector = 0; sector < 3; sector++ ) + sector_print( &_app_rom, sector, 16 ); + print( NL ); +#endif + + flash_prepare_flashing(); + usb_init( &dfu_device ); + for (;;) { - usb_poll(); - } + usb_poll(); + } }