void usbd_msc_write_sect(uint32_t block, uint8_t *buf, uint32_t num_of_blocks) { FatDirectoryEntry_t tmp_file = {0}; extension_t start_type_identified = UNKNOWN; target_flash_status_t status = TARGET_OK; uint32_t i = 0; if (!USBD_MSC_MediaReady) { return; } debug_msg("block: %d\r\n", block); // indicate msd activity main_blink_msd_led(0); // this is the key for starting a file write - we dont care what file types are sent // just look for something unique (NVIC table, hex, srec, etc) until root dir is updated if (0 == file_transfer_state.transfer_started) { // look for file types we can program start_type_identified = identify_start_sequence(buf); if (start_type_identified != UNKNOWN) { debug_msg("%s", "FLASH INIT\r\n"); // binary file transfer - reset parsing file_transfer_state.start_block = block; file_transfer_state.amt_to_write = 0xffffffff; file_transfer_state.amt_written = USBD_MSC_BlockSize; file_transfer_state.last_block_written = block; file_transfer_state.transfer_started = 1; file_transfer_state.file_type = start_type_identified; // prepare the target device status = target_flash_init(file_transfer_state.file_type); if (status != TARGET_OK) { goto msc_fail_exit; } // writing in 2 places less than ideal but manageable for the time being debug_msg("%d: %s", __LINE__, "FLASH WRITE - "); //debug_data(buf, USBD_MSC_BlockSize); status = target_flash_program_page((block-file_transfer_state.start_block)*USBD_MSC_BlockSize, buf, USBD_MSC_BlockSize*num_of_blocks); debug_msg("%d\r\n", status); if ((status != TARGET_OK) && (status != TARGET_HEX_FILE_EOF)) { goto msc_fail_exit; } goto msc_complete; } } // if the root dir comes we should look at it and parse for info that can end a transfer else if ((block == ((mbr.num_fats * mbr.logical_sectors_per_fat) + 1)) || (block == ((mbr.num_fats * mbr.logical_sectors_per_fat) + 2))) { // start looking for a known file and some info about it for( ; i < USBD_MSC_BlockSize/sizeof(tmp_file); i++) { memcpy(&tmp_file, &buf[i*sizeof(tmp_file)], sizeof(tmp_file)); debug_msg("na:%.11s\tatrb:%8d\tsz:%8d\tst:%8d\tcr:%8d\tmod:%8d\taccd:%8d\r\n" , tmp_file.filename, tmp_file.attributes, tmp_file.filesize, tmp_file.first_cluster_low_16 , tmp_file.creation_time_ms, tmp_file.modification_time, tmp_file.accessed_date); // test for a known dir entry file type and also that the filesize is greater than 0 if (1 == wanted_dir_entry(tmp_file)) { file_transfer_state.amt_to_write = tmp_file.filesize; } } } // write data to media if ((block >= file_transfer_state.start_block) && (file_transfer_state.transfer_started == 1)) { if (block >= file_transfer_state.start_block) { // check for contiguous transfer if (block != (file_transfer_state.last_block_written+1)) { // this is non-contigous transfer. need to wait for then next proper block debug_msg("%s", "BLOCK OUT OF ORDER\r\n"); } else { debug_msg("%d: %s", __LINE__, "FLASH WRITE - "); //debug_data(buf, USBD_MSC_BlockSize); status = target_flash_program_page((block-file_transfer_state.start_block)*USBD_MSC_BlockSize, buf, USBD_MSC_BlockSize*num_of_blocks); debug_msg("%d\r\n", status); if ((status != TARGET_OK) && (status != TARGET_HEX_FILE_EOF)) { goto msc_fail_exit; } // and do the housekeeping file_transfer_state.amt_written += USBD_MSC_BlockSize; file_transfer_state.last_block_written = block; } } } msc_complete: // see if a complete transfer occured by knowing it started and comparing filesize expectations (BIN) // finding an EOF from hex file (HEX) if (((file_transfer_state.amt_written >= file_transfer_state.amt_to_write) && (file_transfer_state.transfer_started == 1 )) || (TARGET_HEX_FILE_EOF == status)) { // hex file complete exit needs to look like binary file complete exit status = TARGET_OK; // do the disconnect - maybe write some programming stats to the file debug_msg("%s", "FLASH END\r\n"); // we know the contents have been reveived. Time to eject file_transfer_state.transfer_started = 0; configure_fail_txt(status); main_msc_disconnect_event(); return; } // There is one more known state where the root dir is updated with the amount of data transfered but not the whole file transfer was complete // To handle this we need a state to kick off a timer for a fixed amount of time where we can receive more continous sectors and assume // they are valid file data. This is only the case for bin files since the only known end is the filesize from the root dir entry. return; msc_fail_exit: file_transfer_state.transfer_started = 0; configure_fail_txt(status); //main_force_msc_disconnect_event(); main_msc_disconnect_event(); USBD_MSC_MediaReady = 0; return; }
int main(void) { uint32_t i, err; DelayInit(); GPIO_QuickInit(HW_GPIOC, 10, kGPIO_Mode_OPP); #ifdef MK22F25612 UART_QuickInit(UART0_RX_PB16_TX_PB17, 115200); #elif MK20D5 UART_QuickInit(UART1_RX_PC03_TX_PC04, 115200); #endif printf("program for Manley\r\n"); swd_io_init(); SWJ_InitDebug(); SWJ_SetTargetState(RESET_HOLD); ShowID(); for(i=0;i<sizeof(buf);i++) { buf[i] = i & 0xFF; } SWJ_WriteMem(0x20000000, buf, sizeof(buf)); memset(buf, 0, sizeof(buf)); SWJ_ReadMem(0x20000000, buf, sizeof(buf)); for(i=0;i<sizeof(buf);i++) { if(buf[i] != (i & 0xFF)) { printf("error buf[%d]:%d should be:%d\r\n", i, buf[i], i); } } printf("mem teset complete\r\n"); SWJ_SetTargetState(RESET_PROGRAM); err = TFlash_UnlockSequence(); printf("TFlash_UnlockSequence %d\r\n", err); SWJ_SetTargetState(RESET_PROGRAM); err = TFlash_Init(&flash); printf("TFlash_Init %d\r\n", err); err = target_flash_program_page(&flash, 0x00000200, (uint8_t*)flash.image, 512); printf("target_flash_program_page %d\r\n", err); while(1) { GPIO_ToggleBit(HW_GPIOC, 10); DelayMs(500); } }