goto out_no_status;
}
case USB_CTRL_REQ_DFU_UPLOAD: {
+ /*
void *buf;
size_t len = 0;
}
goto out_no_status;
+ */
+ return 0;
}
case USB_CTRL_REQ_DFU_GETSTATUS: {
struct dfu_status_t st;
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
},
.will_detach = 1,
.manifestation_tolerant = 0,
- .can_upload = 1,
+ .can_upload = 0,
.can_download = 1,
.wDetachTimeOut = 0,
.wTransferSize = USB_DFU_TRANSFER_SIZE,
#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 \
/* 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,
//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());
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;
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;
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);
}
/**
* 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 ];
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 );
printHex( (size_t)start );
print(" -> ");
printHex( (size_t)end );
+ print(" Erased: ");
+ printHex( retval );
print( NL );
// Display sector
{
// Each Line
printHex_op( (size_t)pos, 4 );
- print(" ");
+ print(": ");
// Each 2 byte chunk
for ( size_t chunk = 0; chunk < chunks; chunk++ )
*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);
}
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);
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);
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();
#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"
{
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;
. = 0;
KEEP(* (.vectors))
*(.startup*)
+ . = 0x400; KEEP(* (.flashconfig)) /* MUST BE AT 0x400 */
*(.text*)
*(.rodata*)
. = ALIGN(4);