Hi all,
i'm using the new SDK library with le MSD library. My problem is in the function:
uint8_t msd1_class_specific_callback(uint8_t event_type, uint16_t value, uint8_t ** data, uint32_t * size, void * arg)
{
...................................................
/* Prepare the storage device buffer for USB transfer */
case USB_MSC_DEVICE_WRITE_REQUEST:
#ifdef msd1_RAM_DISK_DEMO /* USB RAM disk PEx demo project (This code is possible to enable by 'USB RAM disk demo' property). */
lba_data_ptr = (lba_app_struct_t *)size;
if(data != NULL) {
*data = (uint8_t *)&msd1_StorageDisk[lba_data_ptr->offset];
}
#else
/* copy data from USb buffer to Storage device
(Called before after recv_data on BULK OUT endpoints)*/
lba_data_ptr = (lba_app_struct_t*) size;
*data = (uint8_t *) &buffer_out;
//printf("offset=0x%08X,offset>>9=0x%08X\r\n",lba_data_ptr->offset,lba_data_ptr->offset>>9);
if ((lba_data_ptr->offset >> 9) == FATTable0Sec0) { /* write new file */
new_file = TRUE;
printf("new_file=TRUE\r\n");
} /* EndIf */
if (((lba_data_ptr->offset >> 9) == FATRootDirSec0)
&& (new_file == TRUE)) {
/* read file size of the file was received */
/* search for the file entry was received */
/* each file entry contain 32 bytes */
for (i = lba_data_ptr->size - 32; i > 0; i -= 32) {
if (*(lba_data_ptr->buff_ptr + i) != 0) {
break;
} /* EndIf */
} /* Endfor */
/* the file size field is offet 28 of file entry */
#if (defined MCU_MK60N512VMD100)
file_size = *(uint_32*)( lba_data_ptr->buff_ptr + i + 28);
#else
file_size = BYTESWAP32( *(uint_32* )(lba_data_ptr->buff_ptr + i + 28));
printf("file_size=0x%08X\r\n", file_size);
#endif
new_file = FALSE;
} /* EndIf */
if ((lba_data_ptr->offset >> 9) == FATDataSec0) {
erase_flash();
filetype = UNKNOWN;
printf("\n\tOpen Image File");
} /* EndIf */
if ((lba_data_ptr->offset >> 9) >= FATDataSec0) {
/* parse and flash an array to flash memory */
if (FLASH_IMAGE_SUCCESS == error) {
printf("\r\nbufsize=%d\r\n", lba_data_ptr->size);
printf("bufaddr=0x%08X\r\n", lba_data_ptr->buff_ptr);
//dumpBuf(lba_data_ptr->buff_ptr, lba_data_ptr->size, 16);
error = FlashApplication(lba_data_ptr->buff_ptr, lba_data_ptr->size);
}
} /* EndIf */
/* rest of file */
//printf("Rest of file\r\n");
if (((lba_data_ptr->offset >> 9) - FATDataSec0)
== ((file_size - 1) / 512)) {
boot_complete = TRUE; //tranfer file done
if (BootloaderStatus == BootloaderReady) {
BootloaderStatus = BootloaderSuccess;
}
/* print flashing status */
if (BootloaderStatus != BootloaderSuccess) {
printf("\nFlash image file fail!");
} else {
printf("\nFlash image file complete!");
printf("\nPress RESET button to enter application mode.");
} /* EndIf */
} /* EndIf */
#endif
break;
.................................................
}
where the USB_MSC_DEVICE_WRITE_REQUEST is called. This call is done by the :
function in usb_msc.c. As visible the call is different and in USB_Service_Bulk_Out the parameter of size and offset are declare as NULL. Why this? my problem is than that i can't write correctly the data.
Thanks
Daniele
Hi nobody can help me? My problem is that i have to write data to memory,
i have the file msd1_msc where i have the function msd1_class_specific_callback, here there is the :
case USB_MSC_DEVICE_WRITE_REQUEST:
lba_data_ptr = (lba_app_struct_t*) size;
if (n = strstr(g_msc_bulk_out_buff, "S0160000426C696E6B204669726D776172652E73726563C1")) {
flag_srec = TRUE;
}
*data = g_msc_bulk_out_buff;
if (n = strstr(g_msc_bulk_out_buff, "S0160000426C696E6B204669726D776172652E73726563C1")) {
flag_srec = TRUE;
}
used to prepare the buffer where write the data, and the :
case USB_DEV_EVENT_DATA_RECEIVED:
lba_data_ptr = (lba_app_struct_t*) size;
if (n = strstr(g_msc_bulk_out_buff, "S0160000426C696E6B204669726D776172652E73726563C1")) {
flag_srec = TRUE;
}
where i have to write the buffer to the memory. In usb_msc.c i have this code:
//#ifdef MUTILE_BUFFER
#if ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK) && (!USE_RTOS)) || (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM)
lba_app_struct_t lba_data2;
if (msc_obj_ptr->transfer_remaining)
{
msc_obj_ptr->class_specific_callback.callback(USB_MSC_DEVICE_WRITE_REQUEST,
USB_REQ_VAL_INVALID,&msc_obj_ptr->msd_buff.msc_bulk_out_ptr, NULL, msc_obj_ptr->class_specific_callback.arg);
if (msc_obj_ptr->msd_buff.msc_bulk_out_ptr != NULL)
{
have_transfer = 1;
msc_obj_ptr->current_offset += event->len;
lba_data2.offset = msc_obj_ptr->current_offset;
lba_data2.size = (msc_obj_ptr->msd_buff.msc_bulk_out_size > MSD_RECV_MAX_TRANS_LENGTH) ?
MSD_RECV_MAX_TRANS_LENGTH : msc_obj_ptr->msd_buff.msc_bulk_out_size; /* whichever is smaller */
lba_data2.size = (msc_obj_ptr->transfer_remaining > lba_data2.size) ?
lba_data2.size : msc_obj_ptr->transfer_remaining; /* whichever is smaller */
lba_data2.buff_ptr = msc_obj_ptr->msd_buff.msc_bulk_out_ptr;
if(msc_obj_ptr->current_offset < (msc_obj_ptr->device_info.total_lba_device_supports * msc_obj_ptr->device_info.length_of_each_lab_of_device))
{
(void)USB_MSC_Bulk_Recv_Data(msc_obj_ptr->controller_handle,
lba_data2.buff_ptr,lba_data2.size);
}
else
{
msc_obj_ptr->need_out_stall_flag = FALSE; /* clear the flag */
msc_obj_ptr->out_stall_flag = TRUE; /* clear the flag */
msc_obj_ptr->out_flag = FALSE; /* clear send flag */
msc_obj_ptr->stall_status = (uint8_t)STALL_IN_DATA_PHASE;
usb_device_stall_endpoint(msc_obj_ptr->controller_handle,msc_obj_ptr->bulk_out_endpoint,USB_RECV);
}
}
}
#endif
msc_obj_ptr->class_specific_callback.callback(USB_DEV_EVENT_DATA_RECEIVED,
USB_REQ_VAL_INVALID,NULL,(uint32_t *)&lba_data1, msc_obj_ptr->class_specific_callback.arg);
}
in USB_MSC_DEVICE_WRITE_REQUEST i can see the string S0160000426C696E6B204669726D776172652E73726563C1 before do the *data = g_msc_bulk_out_buff; so the data arrived before prepare the buffer to save this, the problem is that they didn't arrive in USB_DEV_EVENT_DATA_RECEIVED because the function USB_MSC_Bulk_Recv_Data is called so is changed the content of the buffer .... What i have to do? I have contact the Freescale support but it didn't help me .... He said is not an expert about this code .... HELP PLEASE!
Hi Daniele
The SDK USB code is very difficult to follow and maintain and I don't think there will be any support unless Freescale has a team working on it that can help you directly.
Generally it is difficult to say what parts are operational for productive use and which are base examples for further work, which will need to be developed before fully operational.
However what I can say is that USB-MSD is in fact quite simple and in case you find that the investment is too high, or your projects are delayed too long due to the need to debug or correct or extend the present references do remember that there are supported sources that are designed to allow easy use and are proven in industrial applications. The follow code is the USB-MSD implementation in the uTasker project as reference which shows that the application/class in fact needs only a fairly small amount of code and can be written in a way that the USB details themselves are almost completely hidden. This code also allows operation of multiple USB-MSD LUMs (eg. on SD card, in internal Flash and or external SPI Flash). It is HW independent and runs on any KL, K or Coldfire V2 with USB.
The uTasker project allows the USB operation to be simulated using VisualStudio, including USB enumeration, USB interrupts, memory usage by USB etc. and so also enables easy understanding of the operations or aids in developing, testing and debuging additional code without HW complications. Problems can be analysed remotely and problem cases played back as scripts.
If your developments are for hobby or as a student assignment you may find that it will be an interesting excercise to analse the USB base that you have and rework it once you fully undertand it. If you are programming professionally I would look at proven and supported sources so that you don't need to invest time in solving fundamental problems and can complete your actual application/product development. If you don't think the uTasker project is suitable you can contact various USB stack manufacturers who can supply professional quality code with personal support so that you don't lose any time: See Micrium, Segger, MQX (USB stacks with or without File System support).
Regards
Mark
while (fnMsgs(USBPortID_MSD) != 0) { // handle USB-MSD host receptions if (ulWriteBlock != 0) { // write data expected static unsigned char ucBuffer[512]; // intermediate buffer to collect each sector content Length = fnRead(USBPortID_MSD, &ucBuffer[iContent], (QUEUE_TRANSFER)(512 - iContent)); // read the content directly to the intermediate buffer ulWriteBlock -= Length; iContent += Length; if (iContent >= 512) { // input buffer is complete fnWriteSector(ucActiveLUN, ucBuffer, ulLogicalBlockAdr++); // commit the buffer content to the media iContent = 0; // reset intermediate buffer if (ulWriteBlock != 0) { // block not complete uTaskerStateChange(OWN_TASK, UTASKER_ACTIVATE); // {17} yield after a write when further data is expected but schedule again immediately to read any remaining queue content return; } } if (ulWriteBlock != 0) { // more data expected continue; } // allow CSW to be sent after a complete transfer has completed } else { USB_MASS_STORAGE_CBW *ptrCBW; Length = fnRead(USBPortID_MSD, ucInputMessage, LARGE_MESSAGE); // read the content ptrCBW = (USB_MASS_STORAGE_CBW *)ucInputMessage; uMemcpy(&csw.dCBWTag, ptrCBW->dCBWTag, sizeof(csw.dCBWTag)); // save the tag csw.dCSWDataResidue[0] = 0; csw.dCSWDataResidue[1] = 0; csw.dCSWDataResidue[2] = 0; csw.dCSWDataResidue[3] = 0; csw.bCSWStatus = CSW_STATUS_COMMAND_PASSED; // set for success fnFlush(USBPortID_MSD, FLUSH_TX); // always flush the tx buffer to ensure message alignment in buffer before responding ucActiveLUN = ptrCBW->dCBWLUN; // the logical unit number to use if (ptrCBW->dmCBWFlags & CBW_IN_FLAG) { switch (ptrCBW->CBWCB[CBW_OperationCode]) { case UFI_FORMAT_UNIT: break; case UFI_INQUIRY: { CBW_INQUIRY_COMMAND *ptrInquiry = (CBW_INQUIRY_COMMAND *)ptrCBW->CBWCB; unsigned char ucLogicalUnitNumber = (ptrInquiry->ucLogicalUnitNumber_EVPD >> 5); // the logical unit number being requested QUEUE_TRANSFER inquiry_length; unsigned char *ptrInquiryData = fnGetPartition(ucLogicalUnitNumber, &inquiry_length); if (ptrInquiryData == 0) { // partition doesn't exist csw.bCSWStatus = CSW_STATUS_COMMAND_FAILED; } else { fnWrite(USBPortID_MSD, ptrInquiryData, inquiry_length); // respond to the request and then return } } break; case UFI_MODE_SENSE_6: // {15} { MODE_PARAMETER_6 SelectDataWP; uMemcpy(&SelectDataWP, &SelectData, sizeof(SelectData)); if (ptrDiskInfo[ucActiveLUN]->usDiskFlags & WRITE_PROTECTED_SD_CARD) { SelectDataWP.ucWP_DPOFUA = PAR6_WRITE_PROTECTED; // the medium is write protected } fnWrite(USBPortID_MSD, (unsigned char *)&SelectDataWP, sizeof(SelectData)); // respond to the request and then return } break; case UFI_START_STOP: case UFI_MODE_SELECT: case UFI_PRE_ALLOW_REMOVAL: break; case UFI_READ_10: case UFI_READ_12: { CBW_READ_10 *ptrRead = (CBW_READ_10 *)ptrCBW->CBWCB; if (ptrRead->ucOperationCode == UFI_READ_12) { CBW_READ_12 *ptrRead = (CBW_READ_12 *)ptrCBW->CBWCB; ulReadBlock = ((ptrRead->ucTransferLength[0] << 24) | (ptrRead->ucTransferLength[1] << 16) | (ptrRead->ucTransferLength[2] << 8) | ptrRead->ucTransferLength[3]); } else { ulReadBlock = ((ptrRead->ucTransferLength[0] << 8) | ptrRead->ucTransferLength[1]); // the total number of blocks to be returned } fnContinueMedia(); continue; // the transfer has not completed so don't send termination stage yet } break; case UFI_READ_CAPACITY: { CBW_READ_CAPACITY_DATA formatData; unsigned long ulLastSector = (ptrDiskInfo[ucActiveLUN]->ulSD_sectors - 1); formatData.ucBlockLengthInBytes[0] = 0; formatData.ucBlockLengthInBytes[1] = 0; formatData.ucBlockLengthInBytes[2] = (unsigned char)(ptrDiskInfo[ucActiveLUN]->utFAT.usBytesPerSector >> 8); formatData.ucBlockLengthInBytes[3] = (unsigned char)(ptrDiskInfo[ucActiveLUN]->utFAT.usBytesPerSector); formatData.ucLastLogicalBlockAddress[0] = (unsigned char)(ulLastSector >> 24); formatData.ucLastLogicalBlockAddress[1] = (unsigned char)(ulLastSector >> 16); formatData.ucLastLogicalBlockAddress[2] = (unsigned char)(ulLastSector >> 8); formatData.ucLastLogicalBlockAddress[3] = (unsigned char)(ulLastSector); fnWrite(USBPortID_MSD, (unsigned char *)&formatData, sizeof(formatData)); } break; case UFI_READ_FORMAT_CAPACITY: { CBW_FORMAT_CAPACITIES *ptrCapacities = (CBW_FORMAT_CAPACITIES *)ptrCBW->CBWCB; unsigned short usLengthAccepted = ((ptrCapacities->ucAllocationLength[0] << 8) | (ptrCapacities->ucAllocationLength[1])); CBW_CAPACITY_LIST mediaCapacity; uMemcpy(&mediaCapacity, &formatCapacityNoMedia, sizeof(CBW_CAPACITY_LIST)); // assume no disk if (ptrDiskInfo[ucActiveLUN]->usDiskFlags & (DISK_MOUNTED | DISK_UNFORMATTED)) { // {16} if (ptrDiskInfo[ucActiveLUN]->usDiskFlags & DISK_FORMATTED) { mediaCapacity.capacityDescriptor.ucDescriptorCode = DESC_CODE_FORMATTED_MEDIA; } else { mediaCapacity.capacityDescriptor.ucDescriptorCode = DESC_CODE_UNFORMATTED_MEDIA; } mediaCapacity.capacityDescriptor.ucNumberOfBlocks[3] = (unsigned char)ptrDiskInfo[ucActiveLUN]->ulSD_sectors; mediaCapacity.capacityDescriptor.ucNumberOfBlocks[2] = (unsigned char)(ptrDiskInfo[ucActiveLUN]->ulSD_sectors >> 8); mediaCapacity.capacityDescriptor.ucNumberOfBlocks[1] = (unsigned char)(ptrDiskInfo[ucActiveLUN]->ulSD_sectors >> 16); mediaCapacity.capacityDescriptor.ucNumberOfBlocks[0] = (unsigned char)(ptrDiskInfo[ucActiveLUN]->ulSD_sectors >> 24); } if (usLengthAccepted > sizeof(CBW_CAPACITY_LIST)) { usLengthAccepted = sizeof(CBW_CAPACITY_LIST); } fnWrite(USBPortID_MSD, (unsigned char *)&mediaCapacity, usLengthAccepted); } break; case UFI_REQUEST_SENSE: { CBW_RETURN_SENSE_DATA present_sense_data; uMemcpy(&present_sense_data, &sense_data_OK, sizeof(sense_data_OK)); if ((ptrDiskInfo[ucActiveLUN]->usDiskFlags & (DISK_MOUNTED | DISK_UNFORMATTED)) == 0) { present_sense_data.ucValid_ErrorCode = (CURRENT_ERRORS); // set that the disk is presently in a non-useable state present_sense_data.ucSenseKey = SENSE_NOT_READY; present_sense_data.ucAdditionalSenseCode = DESC_MEDIUM_NOT_PRESENT; } fnWrite(USBPortID_MSD, (unsigned char *)&present_sense_data, sizeof(present_sense_data)); } break; case UFI_REZERO_UNIT: case UFI_SEEK_10: case UFI_SEND_DIAGNOSTIC: case UFI_VERIFY: case UFI_WRITE_AND_VERIFY: default: break; } } else { // OUT types switch (ptrCBW->CBWCB[CBW_OperationCode]) { case UFI_TEST_UNIT_READY: if ((ptrDiskInfo[ucActiveLUN]->usDiskFlags & (DISK_MOUNTED | DISK_UNFORMATTED)) == 0) { // if the partition is not ready csw.bCSWStatus = CSW_STATUS_COMMAND_FAILED; } break; case UFI_WRITE_10: case UFI_WRITE_12: { CBW_WRITE_10 *ptrWrite = (CBW_WRITE_10 *)ptrCBW->CBWCB; if (ptrWrite->ucOperationCode == UFI_WRITE_12) { CBW_WRITE_12 *ptrWrite = (CBW_WRITE_12 *)ptrCBW->CBWCB; ulWriteBlock = ((ptrWrite->ucTransferLength[0] << 24) | (ptrWrite->ucTransferLength[1] << 16) | (ptrWrite->ucTransferLength[2] << 8) | ptrWrite->ucTransferLength[3]); } else { ulWriteBlock = ((ptrWrite->ucTransferLength[0] << 8) | ptrWrite->ucTransferLength[1]); // the total number of blocks to be returned } ulWriteBlock *= 512; // convert to byte count } continue; // data will follow so don't reply with CSW stage yet } } } fnWrite(USBPortID_MSD, (unsigned char *)&csw, sizeof(csw)); // close with CSW stage }