@@ -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 |
@@ -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, |
@@ -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 \ |
@@ -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); | |||
} |
@@ -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(); | |||
@@ -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" |
@@ -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; |
@@ -43,6 +43,7 @@ SECTIONS | |||
. = 0; | |||
KEEP(* (.vectors)) | |||
*(.startup*) | |||
. = 0x400; KEEP(* (.flashconfig)) /* MUST BE AT 0x400 */ | |||
*(.text*) | |||
*(.rodata*) | |||
. = ALIGN(4); |