From 02b919a4cb1bed022b5a09e9e03e29cda2b5a660 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Mon, 25 May 2015 17:23:18 -0700 Subject: [PATCH] Basic code for mk20dx256vlh7 flashing --- Bootloader/dfu.c | 40 +----------- Bootloader/dfu.desc.c | 2 +- Bootloader/dfu.h | 10 ++- Bootloader/flash.c | 83 +++++++++++++------------ Bootloader/main.c | 107 +++++++++++++++++++++++++++++--- Bootloader/mchck.h | 2 +- Lib/mk20dx256vlh7.bootloader.ld | 3 +- Lib/mk20dx256vlh7.ld | 1 + 8 files changed, 158 insertions(+), 90 deletions(-) diff --git a/Bootloader/dfu.c b/Bootloader/dfu.c index e238ac3..e5509fa 100644 --- a/Bootloader/dfu.c +++ b/Bootloader/dfu.c @@ -101,6 +101,7 @@ static int dfu_handle_control( struct usb_ctrl_req_t *req, void *data ) goto out_no_status; } case USB_CTRL_REQ_DFU_UPLOAD: { + /* void *buf; size_t len = 0; @@ -141,6 +142,8 @@ static int dfu_handle_control( struct usb_ctrl_req_t *req, void *data ) } goto out_no_status; + */ + return 0; } case USB_CTRL_REQ_DFU_GETSTATUS: { struct dfu_status_t st; @@ -149,43 +152,6 @@ static int dfu_handle_control( struct usb_ctrl_req_t *req, void *data ) st.bStatus = ctx->status; st.bwPollTimeout = 1000; /* XXX */ - // XXX FAKE WRITE - if ( ctx->state == DFU_STATE_dfuMANIFEST ) - { - uint8_t data[] = { 0x10, 0x20, 0x30, 0x40 }; - flash_program_longword((uintptr_t)&_app_rom, data); - } - /* - - uint32_t *position = &_app_rom + 0x100; - for ( ; position < &_app_rom + 0x200; position++ ) - //for ( ; position < &_app_rom + 0x800; position++ ) - { - if ( *position != 0xFFFFFFFF ) - { - while( 1 ) - { - GPIOA_PTOR |= (1<<5); - for (uint32_t d = 0; d < 7200000; d++ ); - } - } - }*/ - - // Check to see if vector table was flashed correctly - // Return a flash error if it was not - if (_app_rom == 0xffffffff && ctx->state == DFU_STATE_dfuMANIFEST) - st.bStatus = DFU_STATUS_errPROG; - //} - /* - if (ctx->state == DFU_STATE_dfuMANIFEST) - { - uint8_t *addr = (uint8_t*)_app_rom; - //while (*(addr++) != 0x80); - //st.bStatus = DFU_STATUS_errPROG; - st.bStatus = (uint8_t)((uint32_t)(&_app_rom) >> 16); - } - */ - /** * If we're in DFU_STATE_dfuMANIFEST, we just finished * the download, and we're just about to send our last diff --git a/Bootloader/dfu.desc.c b/Bootloader/dfu.desc.c index c705300..dc11fef 100644 --- a/Bootloader/dfu.desc.c +++ b/Bootloader/dfu.desc.c @@ -61,7 +61,7 @@ static const struct usb_config_1 usb_config_1 = { }, .will_detach = 1, .manifestation_tolerant = 0, - .can_upload = 1, + .can_upload = 0, .can_download = 1, .wDetachTimeOut = 0, .wTransferSize = USB_DFU_TRANSFER_SIZE, diff --git a/Bootloader/dfu.h b/Bootloader/dfu.h index 83d5d2b..1462746 100644 --- a/Bootloader/dfu.h +++ b/Bootloader/dfu.h @@ -30,7 +30,15 @@ #ifndef USB_DFU_TRANSFER_SIZE -#define USB_DFU_TRANSFER_SIZE FLASH_SECTOR_SIZE +// Sector size is the same as the program flash size +#if defined(_mk20dx128vlf5_) +#define USB_DFU_TRANSFER_SIZE FLASH_SECTOR_SIZE + +// Sector size is double the program flash size +#elif defined(_mk20dx256vlh7_ ) +#define USB_DFU_TRANSFER_SIZE FLASH_SECTOR_SIZE / 2 + +#endif #endif #define USB_FUNCTION_DESC_DFU_DECL \ diff --git a/Bootloader/flash.c b/Bootloader/flash.c index 57edc16..349a44e 100644 --- a/Bootloader/flash.c +++ b/Bootloader/flash.c @@ -31,7 +31,7 @@ uint32_t flash_ALLOW_BRICKABLE_ADDRESSES; /* This will have to live in SRAM. */ __attribute__((section(".ramtext.ftfl_submit_cmd"), long_call)) -int ftfl_submit_cmd(void) +int ftfl_submit_cmd() { FTFL.fstat.raw = ((struct FTFL_FSTAT_t){ .ccif = 1, @@ -49,10 +49,11 @@ int ftfl_submit_cmd(void) //return (!!stat.mgstat0); } -int flash_prepare_flashing(void) +int flash_prepare_flashing() { /* switch to FlexRAM */ - if (!FTFL.fcnfg.ramrdy) { + if ( !FTFL.fcnfg.ramrdy ) + { FTFL.fccob.set_flexram.fcmd = FTFL_FCMD_SET_FLEXRAM; FTFL.fccob.set_flexram.flexram_function = FTFL_FLEXRAM_RAM; return (ftfl_submit_cmd()); @@ -60,17 +61,27 @@ int flash_prepare_flashing(void) return (0); } -int flash_erase_sector(uintptr_t addr) +int flash_read_1s_sector( uintptr_t addr, size_t num ) { - if (addr < (uintptr_t)&_app_rom && - flash_ALLOW_BRICKABLE_ADDRESSES != 0x00023420) + FTFL.fccob.read_1s_section.fcmd = FTFL_FCMD_READ_1s_SECTION; + FTFL.fccob.read_1s_section.addr = addr; + FTFL.fccob.read_1s_section.margin = FTFL_MARGIN_NORMAL; + FTFL.fccob.read_1s_section.num_words = num; + + return ftfl_submit_cmd(); +} + +int flash_erase_sector( uintptr_t addr ) +{ + if ( addr < (uintptr_t)&_app_rom && flash_ALLOW_BRICKABLE_ADDRESSES != 0x00023420 ) return (-1); FTFL.fccob.erase.fcmd = FTFL_FCMD_ERASE_SECTOR; FTFL.fccob.erase.addr = addr; - return (ftfl_submit_cmd()); + + return ftfl_submit_cmd(); } -int flash_program_section_longwords(uintptr_t addr, size_t num_words) +int flash_program_section_longwords( uintptr_t addr, size_t num_words ) { FTFL.fccob.program_section.fcmd = FTFL_FCMD_PROGRAM_SECTION; FTFL.fccob.program_section.addr = addr; @@ -79,7 +90,7 @@ int flash_program_section_longwords(uintptr_t addr, size_t num_words) return ftfl_submit_cmd(); } -int flash_program_section_phrases(uintptr_t addr, size_t num_phrases) +int flash_program_section_phrases( uintptr_t addr, size_t num_phrases ) { FTFL.fccob.program_section.fcmd = FTFL_FCMD_PROGRAM_SECTION; FTFL.fccob.program_section.addr = addr; @@ -88,53 +99,43 @@ int flash_program_section_phrases(uintptr_t addr, size_t num_phrases) return ftfl_submit_cmd(); } -int flash_program_longword(uintptr_t addr, uint8_t *data) -{ - FTFL.fccob.program_longword.fcmd = FTFL_FCMD_PROGRAM_LONGWORD; - FTFL.fccob.program_longword.addr = addr; - FTFL.fccob.program_longword.data_be[0] = data[0]; - FTFL.fccob.program_longword.data_be[1] = data[1]; - FTFL.fccob.program_longword.data_be[2] = data[2]; - FTFL.fccob.program_longword.data_be[3] = data[3]; - - return ftfl_submit_cmd(); -} - -int flash_program_sector(uintptr_t addr, size_t len) +int flash_program_sector( uintptr_t addr, size_t len ) { #if defined(_mk20dx128vlf5_) - return (len != FLASH_SECTOR_SIZE || - (addr & (FLASH_SECTOR_SIZE - 1)) != 0 || - flash_erase_sector(addr) || - flash_program_section_longwords(addr, FLASH_SECTOR_SIZE / 4)); + return (len != FLASH_SECTOR_SIZE + || (addr & (FLASH_SECTOR_SIZE - 1)) != 0 + || flash_erase_sector( addr ) + || flash_program_section_longwords( addr, FLASH_SECTOR_SIZE / 4 )); #elif defined(_mk20dx256vlh7_) - /* - return (len != FLASH_SECTOR_SIZE || - (addr & (FLASH_SECTOR_SIZE - 1)) != 0 || - flash_erase_sector(addr) || - flash_program_section_phrases(addr, FLASH_SECTOR_SIZE / 8)); - */ - return (len != FLASH_SECTOR_SIZE || - (addr & (FLASH_SECTOR_SIZE - 1)) != 0 || - flash_erase_sector(addr) || - flash_program_section_phrases(addr, FLASH_SECTOR_SIZE / 8)); + if ( len != FLASH_SECTOR_SIZE ) + return 1; + + // Check if beginning of sector and erase if not empty + // Each sector is 2 kB in length, but we can only write to half a sector at a time + // We can only erase an entire sector at a time + if ( (addr & (FLASH_SECTOR_SIZE - 1)) == 0 + && flash_read_1s_sector( addr, FLASH_SECTOR_SIZE / 8 ) + && flash_erase_sector( addr ) ) + return 1; + + // Program half-sector + return flash_program_section_phrases( addr, FLASH_SECTOR_SIZE / 16 ); #endif } -int flash_prepare_reading(void) +int flash_prepare_reading() { return (0); } -int flash_read_sector(uintptr_t addr, size_t len) +int flash_read_sector( uintptr_t addr, size_t len ) { return (0); } -void *flash_get_staging_area(uintptr_t addr, size_t len) +void *flash_get_staging_area( uintptr_t addr, size_t len ) { - if ((addr & (FLASH_SECTOR_SIZE - 1)) != 0 || - len != FLASH_SECTOR_SIZE) + if ( (addr & (FLASH_SECTOR_SIZE - 1)) != 0 || len != FLASH_SECTOR_SIZE ) return (NULL); return (FlexRAM); } diff --git a/Bootloader/main.c b/Bootloader/main.c index 639e8b2..303ea35 100644 --- a/Bootloader/main.c +++ b/Bootloader/main.c @@ -30,7 +30,7 @@ /** * 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 ]; @@ -42,6 +42,13 @@ void sector_print( void* buf, size_t sector, size_t chunks ) 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(); + print( NL ); print("Block "); printHex( sector ); @@ -49,6 +56,8 @@ void sector_print( void* buf, size_t sector, size_t chunks ) printHex( (size_t)start ); print(" -> "); printHex( (size_t)end ); + print(" Erased: "); + printHex( retval ); print( NL ); // Display sector @@ -56,7 +65,7 @@ void sector_print( void* buf, size_t sector, size_t chunks ) { // Each Line printHex_op( (size_t)pos, 4 ); - print(" "); + print(": "); // Each 2 byte chunk for ( size_t chunk = 0; chunk < chunks; chunk++ ) @@ -78,12 +87,16 @@ static enum dfu_status setup_read( size_t off, size_t *len, void **buf ) *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); } @@ -174,11 +187,6 @@ void main() uart_serial_setup(); printNL( NL "Bootloader DFU-Mode" ); - // TODO REMOVEME - for ( uint8_t sector = 0; sector < 3; sector++ ) - sector_print( &_app_rom, sector, 16 ); - print( NL ); - // XXX REMOVEME /* GPIOB_PDDR |= (1<<16); @@ -196,6 +204,7 @@ void main() GPIOC_PCOR |= (1<<4); */ // Backlight + /* GPIOC_PDDR |= (1<<1); PORTC_PCR1 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); GPIOC_PCOR |= (1<<1); @@ -205,6 +214,90 @@ void main() GPIOC_PDDR |= (1<<3); PORTC_PCR3 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); GPIOC_PCOR |= (1<<3); + */ + + /* + // Read Firmware 1 Status + FTFL.fccob.read_1s_block.fcmd = FTFL_FCMD_READ_1s_BLOCK; + FTFL.fccob.read_1s_block.addr = (uintptr_t)&_app_rom; + FTFL.fccob.read_1s_block.margin = FTFL_MARGIN_NORMAL; + + int retval = ftfl_submit_cmd(); + print("Firmware Erase Status: "); + printHex( retval ); + print( NL ); + + + // Read Bootloader 1 Status + FTFL.fccob.read_1s_block.fcmd = FTFL_FCMD_READ_1s_BLOCK; + FTFL.fccob.read_1s_block.addr = (uintptr_t)&_bootloader; + FTFL.fccob.read_1s_block.margin = FTFL_MARGIN_NORMAL; + + retval = ftfl_submit_cmd(); + print("Bootloader Erase Status: "); + printHex( retval ); + print( NL ); + */ + + /* + // Program First Longword of firmware + FTFL.fccob.program_longword.fcmd = FTFL_FCMD_PROGRAM_LONGWORD; + FTFL.fccob.program_longword.addr = (uintptr_t)&_app_rom; + FTFL.fccob.program_longword.data_be[0] = 0x1; + FTFL.fccob.program_longword.data_be[1] = 0x2; + FTFL.fccob.program_longword.data_be[2] = 0x4; + FTFL.fccob.program_longword.data_be[3] = 0x8; + int retval = ftfl_submit_cmd(); + print("Write Longword Status: "); + printHex( retval ); + print( NL ); + */ + + /* + // Erase Sector + FTFL.fccob.erase.fcmd = FTFL_FCMD_ERASE_SECTOR; + FTFL.fccob.erase.addr = (uintptr_t)&_app_rom; + int retval = ftfl_submit_cmd(); + print("Erase Status: "); + printHex( retval ); + print( NL ); + + // Prepare FlexRAM + FTFL.fccob.set_flexram.fcmd = FTFL_FCMD_SET_FLEXRAM; + FTFL.fccob.set_flexram.flexram_function = FTFL_FLEXRAM_RAM; + retval = ftfl_submit_cmd(); + print("Set FlexRAM Status: "); + printHex( retval ); + print( NL ); + + // Write to FlexRAM + memset( FlexRAM, 0xB4, 1000 ); + memset( &FlexRAM[1000], 0xE3, 1000 ); + + // Program Sector + FTFL.fccob.program_section.fcmd = FTFL_FCMD_PROGRAM_SECTION; + FTFL.fccob.program_section.addr = (uintptr_t)&_app_rom; + FTFL.fccob.program_section.num_words = 128; + //FTFL.fccob.program_section.num_words = 250; // 2000 kb / 64 bits + retval = ftfl_submit_cmd(); + print("Program Sector1 Status: "); + printHex( retval ); + print( NL ); + + FTFL.fccob.program_section.fcmd = FTFL_FCMD_PROGRAM_SECTION; + FTFL.fccob.program_section.addr = (uintptr_t)&_app_rom + 0x400; + FTFL.fccob.program_section.num_words = 128; + //FTFL.fccob.program_section.num_words = 250; // 2000 kb / 64 bits + retval = ftfl_submit_cmd(); + print("Program Sector2 Status: "); + printHex( retval ); + print( NL ); + + for ( uint8_t sector = 0; sector < 1; sector++ ) + //sector_print( &_bootloader, sector, 16 ); + sector_print( &_app_rom, sector, 16 ); + print( NL ); + */ flash_prepare_flashing(); diff --git a/Bootloader/mchck.h b/Bootloader/mchck.h index 807f3a0..13bc392 100644 --- a/Bootloader/mchck.h +++ b/Bootloader/mchck.h @@ -37,7 +37,7 @@ #include "mchck-cdefs.h" -extern uint32_t _sidata, _sdata, _edata, _sbss, _ebss, _app_rom, _app_rom_end; +extern uint32_t _sidata, _sdata, _edata, _sbss, _ebss, _app_rom, _app_rom_end, _bootloader; #include "ftfl.h" #include "usbotg.h" diff --git a/Lib/mk20dx256vlh7.bootloader.ld b/Lib/mk20dx256vlh7.bootloader.ld index cff6090..ade94ea 100644 --- a/Lib/mk20dx256vlh7.bootloader.ld +++ b/Lib/mk20dx256vlh7.bootloader.ld @@ -33,13 +33,12 @@ MEMORY { FLASH (rx) : ORIGIN = 0x0, LENGTH = 256K FLASH_APP (rx) : ORIGIN = 8K, LENGTH = 256K-8K - FLASH_END (r) : ORIGIN = 256K, LENGTH = 32 RAM (rwx) : ORIGIN = 0x20000000 - 64K / 2, LENGTH = 64K } /* Starting Address of the application ROM */ +_bootloader = ORIGIN( FLASH ); _app_rom = ORIGIN( FLASH_APP ); -_app_rom_end = ORIGIN( FLASH_END ); FlexRAM = 0x14000000; FTFL = 0x40020000; diff --git a/Lib/mk20dx256vlh7.ld b/Lib/mk20dx256vlh7.ld index a1be3ac..7bc0292 100644 --- a/Lib/mk20dx256vlh7.ld +++ b/Lib/mk20dx256vlh7.ld @@ -43,6 +43,7 @@ SECTIONS . = 0; KEEP(* (.vectors)) *(.startup*) + . = 0x400; KEEP(* (.flashconfig)) /* MUST BE AT 0x400 */ *(.text*) *(.rodata*) . = ALIGN(4);