# | # | ||||
set( SRCS | set( SRCS | ||||
main.c | main.c | ||||
debug.c # TODO only compile in if necessary | |||||
dfu.c | dfu.c | ||||
dfu.desc.c | dfu.desc.c | ||||
flash.c | flash.c | ||||
usb.c | usb.c | ||||
) | ) | ||||
# Only compile in if necessary | |||||
if( CHIP STREQUAL "mk20dx256vlh7" ) | |||||
set( SRCS ${SRCS} | |||||
debug.c | |||||
) | |||||
endif() | |||||
message( STATUS "Bootloader Source Files:" ) | message( STATUS "Bootloader Source Files:" ) | ||||
message( "${SRCS}" ) | message( "${SRCS}" ) | ||||
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 )); | |||||
#elif defined(_mk20dx256vlh7_) | |||||
if ( len != FLASH_SECTOR_SIZE ) | if ( len != FLASH_SECTOR_SIZE ) | ||||
return 1; | return 1; | ||||
#if defined(_mk20dx128vlf5_) | |||||
// Check if this is the beginning of a sector | |||||
// Only erase if necessary | |||||
if ( (addr & (FLASH_SECTOR_SIZE - 1)) == 0 | |||||
&& flash_read_1s_sector( addr, FLASH_SECTOR_SIZE / 4 ) | |||||
&& flash_erase_sector( addr ) ) | |||||
return 1; | |||||
// Program sector | |||||
return flash_program_section_longwords( addr, FLASH_SECTOR_SIZE / 4 ); | |||||
#elif defined(_mk20dx256vlh7_) | |||||
// Check if beginning of sector and erase if not empty | // 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 | // 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 | // We can only erase an entire sector at a time |
// ----- Functions ----- | // ----- Functions ----- | ||||
void sector_print( void* buf, size_t sector, size_t chunks ) | |||||
int sector_print( void* buf, size_t sector, size_t chunks ) | |||||
{ | { | ||||
uint8_t* start = (uint8_t*)buf + sector * USB_DFU_TRANSFER_SIZE; | 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* end = (uint8_t*)buf + (sector + 1) * USB_DFU_TRANSFER_SIZE; | ||||
print( NL ); | print( NL ); | ||||
} | } | ||||
return retval; | |||||
} | } | ||||
static enum dfu_status setup_read( size_t off, size_t *len, void **buf ) | static enum dfu_status setup_read( size_t off, size_t *len, void **buf ) | ||||
if ( !target ) | if ( !target ) | ||||
return (DFU_STATUS_errADDRESS); | return (DFU_STATUS_errADDRESS); | ||||
memcpy( target, buf, len ); | memcpy( target, buf, len ); | ||||
print("BUF: "); | |||||
printHex( off ); | |||||
sector_print( target, 0, 16 ); | |||||
// Depending on the error return a different status | // Depending on the error return a different status | ||||
switch ( flash_program_sector(off + (uintptr_t)&_app_rom, FLASH_SECTOR_SIZE) ) | switch ( flash_program_sector(off + (uintptr_t)&_app_rom, FLASH_SECTOR_SIZE) ) |