OM13076 + OM13082 usbd_rom_msc_sdmmc errors on eject

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

OM13076 + OM13082 usbd_rom_msc_sdmmc errors on eject

1,679 Views
jmccabe
Contributor II

Hi

I have an OM13076 + OM13082 combination that I've tried using the LPCOpen usbd_rom_msc_sdmmc example with (with MCUXPresso). On Windows it mounted fine but, when I right click on the removable drive in Windows Explorer and select "eject" Windows reports that an error occurred and the drive is still there.

Has anyone else seen this issue? 

I've also tried porting this example to the EA LPC1788 dev kit with the same outcome. 

Any help or suggestions would be much appreciated. 

John 

Labels (4)
Tags (1)
0 Kudos
7 Replies

1,209 Views
mukelarvin
Contributor IV

*edit. Maybe my issue isn't exactly the same. I'll make my own post in the IMXRT forum.

 

Hi we are having this problem with the IMXRT 1050. Has the USB stack been updated to handle this? I can't see where to enable it.

0 Kudos

1,396 Views
jeremyzhou
NXP Employee
NXP Employee

Hi  John McCabe,

Thank you for your interest in NXP Semiconductor products and 
the opportunity to serve you.
To replicate the issue, I was wondering if you can share the demo for EA LPC1788 dev kit, as I don't have the OM13082 at hand.
I'm looking forward to your reply.
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
0 Kudos

1,396 Views
jmccabe
Contributor II

Hi Jeremy,

I have a slight confession to make; it's the usb_rom_msc_ram version that I ported to the EA1788 DevKit. I started with that one as there were fewer dependencies (i.e. no need for the SD Card interface to be set up!), and that gave me the error, on Windows 7 (I'm not sure about other versions of Windows), when I eject from the File Explorer so I didn't go any further with trying to port the SD/MMC version of the project.

However, just to make sure I wasn't talking complete nonsense, I have just checked the SDMMC version on the OM13076/OM13082 combination again, and I get the same error with that so I've attached the code I used for the RAM version which you should be able to import into LPCXPresso. It's worth noting that, other than try to port across to the 1788, the only other modifications I made were to make is use the 32MByte external RAM on the EA DevKit rather than being limited to a tiny amount by having it in internal RAM.

HTH

John

0 Kudos

1,396 Views
jeremyzhou
NXP Employee
NXP Employee

Hi John,

Thanks for your reply.

I think I've figured the root cause of this issue.

If you want to eject the 'USB Disk', the host PC will send the STOP UNIT Command to USB device, however USB device can't response to this command, as there's no related command function in the USBD_MSC_INIT_PARAM_T struct which only includes the Read, Write, Verify, etc.

/** \ingroup Group_USBD
 *  @defgroup USBD_MSC Mass Storage Class (MSC) Function Driver
 *  \section Sec_MSCModDescription Module Description
 *  MSC Class Function Driver module. This module contains an internal implementation of the USB MSC Class.
 *  User applications can use this class driver instead of implementing the MSC class manually
 *  via the low-level USBD_HW and USBD_Core APIs.
 *
 *  This module is designed to simplify the user code by exposing only the required interface needed to interface with
 *  Devices using the USB MSC Class.
 */

/** \brief Mass Storage class function driver initialization parameter data structure.
 *  \ingroup USBD_MSC
 *
 *  \details  This data structure is used to pass initialization parameters to the 
 *  Mass Storage class function driver's init function.
 *
 */
typedef struct USBD_MSC_INIT_PARAM
{
  /* memory allocation params */
  uint32_t mem_base;  /**< Base memory location from where the stack can allocate
                      data and buffers. \note The memory address set in this field
                      should be accessible by USB DMA controller. Also this value
                      should be aligned on 4 byte boundary.
                      */
  uint32_t mem_size;  /**< The size of memory buffer which stack can use. 
                      \note The \em mem_size should be greater than the size 
                      returned by USBD_MSC_API::GetMemSize() routine.*/
  /* mass storage params */
  uint8_t*  InquiryStr; /**< Pointer to the 28 character string. This string is 
                        sent in response to the SCSI Inquiry command. \note The data 
                        pointed by the pointer should be of global scope. 
                        */
  uint32_t  BlockCount; /**< Number of blocks present in the mass storage device */
  uint32_t  BlockSize; /**< Block size in number of bytes */
  uint32_t  MemorySize; /**< Memory size in number of bytes */
  /** Pointer to the interface descriptor within the descriptor
  * array (\em high_speed_desc) passed to Init() through \ref USB_CORE_DESCS_T 
  * structure. The stack assumes both HS and FS use same BULK endpoints. 
  */

  uint8_t* intf_desc;
  /* user defined functions */

 /** 
  *  MSC Write callback function.
  *
  *  This function is provided by the application software. This function gets called 
  *  when host sends a write command.
  *  
  *  \param[in] offset Destination start address. 
  *  \param[in, out] src  Pointer to a pointer to the source of data. Pointer-to-pointer
  *                       is used to implement zero-copy buffers. See \ref USBD_ZeroCopy
  *                       for more details on zero-copy concept.
  *  \param[in] length  Number of bytes to be written.
  *  \return Nothing. 
  *                                             
  */
  void (*MSC_Write)( uint32_t offset, uint8_t** src, uint32_t length, uint32_t high_offset); 
 /** 
  *  MSC Read callback function.
  *
  *  This function is provided by the application software. This function gets called 
  *  when host sends a read command.
  *  
  *  \param[in] offset Source start address. 
  *  \param[in, out] dst  Pointer to a pointer to the source of data. The MSC function drivers 
  *         implemented in stack are written with zero-copy model. Meaning the stack doesn't make an 
  *          extra copy of buffer before writing/reading data from USB hardware FIFO. Hence the 
  *          parameter is pointer to a pointer containing address buffer (<em>uint8_t** dst</em>). 
  *          So that the user application can update the buffer pointer instead of copying data to 
  *          address pointed by the parameter. /note The updated buffer address should be accessible
  *          by USB DMA master. If user doesn't want to use zero-copy model, then the user should copy
  *          data to the address pointed by the passed buffer pointer parameter and shouldn't change 
  *          the address value. See \ref USBD_ZeroCopy for more details on zero-copy concept.
  *  \param[in] length  Number of bytes to be read.
  *  \return Nothing. 
  *                                             
  */
  void (*MSC_Read)( uint32_t offset, uint8_t** dst, uint32_t length, uint32_t high_offset);
 /** 
  *  MSC Verify callback function.
  *
  *  This function is provided by the application software. This function gets called 
  *  when host sends a verify command. The callback function should compare the buffer
  *  with the destination memory at the requested offset and 
  *  
  *  \param[in] offset Destination start address. 
  *  \param[in] buf  Buffer containing the data sent by the host.
  *  \param[in] length  Number of bytes to verify.
  *  \return Returns \ref ErrorCode_t type to indicate success or error condition.
  *          \retval LPC_OK If data in the buffer matches the data at destination
  *          \retval ERR_FAILED  At least one byte is different.
  *                                             
  */
  ErrorCode_t (*MSC_Verify)( uint32_t offset, uint8_t buf[], uint32_t length, uint32_t high_offset);
  /** 
  *  Optional callback function to optimize MSC_Write buffer transfer.
  *
  *  This function is provided by the application software. This function gets called 
  *  when host sends SCSI_WRITE10/SCSI_WRITE12 command. The callback function should 
  *  update the \em buff_adr pointer so that the stack transfers the data directly
  *  to the target buffer. /note The updated buffer address should be accessible
  *  by USB DMA master. If user doesn't want to use zero-copy model, then the user 
  *  should not update the buffer pointer. See \ref USBD_ZeroCopy for more details
  *  on zero-copy concept.
  *  
  *  \param[in] offset Destination start address. 
  *  \param[in,out] buf  Buffer containing the data sent by the host.
  *  \param[in] length  Number of bytes to write.
  *  \return Nothing. 
  *                                             
  */
  void (*MSC_GetWriteBuf)( uint32_t offset, uint8_t** buff_adr, uint32_t length, uint32_t high_offset); 

  /** 
  *  Optional user override-able function to replace the default MSC class handler.
  *
  *  The application software could override the default EP0 class handler with their
  *  own by providing the handler function address as this data member of the parameter
  *  structure. Application which like the default handler should set this data member
  *  to zero before calling the USBD_MSC_API::Init().
  *  \n
  *  \note 
  *  
  *  \param[in] hUsb Handle to the USB device stack. 
  *  \param[in] data Pointer to the data which will be passed when callback function is called by the stack. 
  *  \param[in] event  Type of endpoint event. See \ref USBD_EVENT_T for more details.
  *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
  *          \retval LPC_OK On success.
  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
  *          \retval ERR_USBD_xxx  For other error conditions. 
  *                                             
  */
  ErrorCode_t (*MSC_Ep0_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event);

  uint64_t  MemorySize64;
  
} USBD_MSC_INIT_PARAM_T;
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
0 Kudos

1,396 Views
jmccabe
Contributor II

Hi Jeremy,

Thanks for taking the time to look into this; that's exactly what I was thinking though so, unfortunately, doesn't get me any further (see Handling of SCSI PREVENT ALLOW MEDIUM REMOVAL/START STOP in usbdlib/usbdrom). In that question I asked if that is something I'd need to handle by adding my own handler into the MSC_Ep0_hdlr array, but I wasn't sure the best way to do that, if that was, indeed, how it should be done.

Do you have any thoughts on that?

As an aside, I noticed that LUFA (the origin of NXP's nxpUsbLib) is missing handlers for a couple of those SCSI commands, at least around the time nxpUsbLib was created, although they have been added as default "success" responses in the latest version.

John

0 Kudos

1,398 Views
jeremyzhou
NXP Employee
NXP Employee

Hi John McCabe,

Thanks for your reply.

Firstly, I don't think you can add the function pointer in the USBD_MSC_INIT_PARAM_T struct, as the libusbd_40XX_lib.a is invisible for the user, in another word, you can'd change it.

There's a USB MSD demo in below library, and it support to handle STOP UNIT Command, however the user need to code the related handling function.

lpc407x_8x_177x_8x.zip - Google Drive 

Hope it hleps.

Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
0 Kudos

1,398 Views
jmccabe
Contributor II

Jeremy,

Correct; you can't change USBD_MSC_INIT_PARAM_T as it's in the usbdlib but, also, it's the same structure as is defined for the USBD ROM built into multiple MCUs.

Thanks for that demo zip though; I don't think I've seen that specific one before. It's a struggle to build with LPCXPresso, but I'll take a look at it to see if it gives me any hints (so far it does look like it may be an MSC_Ep0_hdlr thing, but I haven't found many useful examples about how to use that very well...

Thanks

John

0 Kudos