LPC43xx USBD_ROM Versus USBD_LIB?

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

LPC43xx USBD_ROM Versus USBD_LIB?

1,665 Views
definium
Contributor II

Hi There,

We are using LPC4337 MCUs in multiple projects. Two of which require a USB port to enumerate as a USB Mass Storage Device with and SD/MMC card as the backing store.

We have it working using the ROM drivers however writing large files fails consistently at the 3G boundary. Specifically at 3040.3MB. The SD card is formatted with FAT32 however the failure also occurs when the card is formatted with ExFAT as well.

Looking at the Linux logs at the time of the failure we see the following:

sd 8:0:0:0: [sdc] tag#0 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE cmd_age=0s
sd 8:0:0:0: [sdc] tag#0 Sense Key : Not Ready [current] 
sd 8:0:0:0: [sdc] tag#0 Add. Sense: Cannot read medium - unknown format
sd 8:0:0:0: [sdc] tag#0 CDB: Read(10) 28 00 00 5a cb ff 00 00 08 00
print_req_error: 4119 callbacks suppressed
blk_update_request: I/O error, dev sdc, sector 5950463 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0

This appears to be an issue with the NXP USB stack. Sure enough, digging through the code reveals the following obscure comment:

if (USBD_API->version > 0x01111101) {
    /* New ROM stack version */
    msc_param.MemorySize64 = sdcardinfo.card_info.device_size;
    msc_param.MemorySize = 0;
} else {
    /* Old ROM stack version - cannot support more than 4GB of memory card */
    msc_param.MemorySize = sdcardinfo.card_info.device_size;
}

The Old ROM stack path is the code that gets executed.

The state of NXP LPC USB support is confusing to say the least. 

  • LPCUSBLib device is no longer supported (Yet host is ?)
  • Apparently there is a library version of USBD. Is this correct?
  • Are USBD_LIB libraries available for the LPC43xx?
  • Where can the library files be downloaded?
  • What is the latest version?
  • Why is there a 4G limit?
  • Is the 4G limitation still present?
  • Where is the documentation?
  • Is there a suggested workaround for the old rom 4G limit?

Any answers to the questions above would be welcomed. Especially if there is a link to a USBD library archive that is a later version than 0x01111101.

Regards,

Mike

Labels (3)
0 Kudos
Reply
2 Replies

1,577 Views
bernhardfink
NXP Employee
NXP Employee

Hi Mike,

I found a few things in an older thread, so that's just a quick info shot. But maybe it answers already some of your questions. I have some legacy knowledge on this platform, that's why I jumped in.

###############
The USB ROM code for the mass storage class in devices with bootcode version older than 11.3 does indeed limit the size of partitions to 4 GiB. This is due to the 32-bit MemorySize field as you have pointed out. Also callback functions use 32-bit offsets only.

The "USBD" code has been updated to support larger partitions, and the 64-bit MemorySize64 replaces the old 32-bit MemorySize. The header file in LPCOpen reflects this.

The MemorySize parameter should be defined as 0 and then the MemorySize64 must be set to the actual size

Note that callback functions will take an additional parameter "high_offset" for the upper 32-bit of the 64-bit offset.

Unfortunately, devices with older ROM code don't support MemorySize64. This affects all flash based LPC1800 and LPC4300 devices, and older flashless devices in these two series. Only the latest flashless LPC18x0 and LPC43x0 have 64-bit support in the mass storage class implementation from boot code version 11.3 onwards.

Devices for which USBD exists as a library in LPCOpen (e.g. LPC17xx) support large disk sizes. However, a USBD library for LPC1800/LPC4300 is not available.

################

Regards,

Bernhard.

0 Kudos
Reply

1,577 Views
definium
Contributor II

Hi Bernhard,

Thanks for your reply. I had figured out most of those details and I also found the USBD source (including the original ROM USBD source) in https://www.nxp.com/docs/en/application-note/TN00041.zip

This is indeed the USBD code for the LPC18xx/43xx MCU.

I managed to piece all that together and rework my code to use that stack and got it up and running. 

The version identifier (from mw_usbd_rom_api.c) of the the code in TN00041.zip is 0x02233405. Much later than the version of the ROM stack it appears.

It does indeed have the changes for 64 bit byte offset value in the control structure but I don't think anyone ever tested this code by writing more than 4G of data to a device. Mainly because it fails with the file system being corrupted.

There is a bug in this version as well and as soon as you reach the 4G boundary the offset wraps back to zero destroying the FAT first followed by critical structures at the beginning of the cluster heap. This destroys the filesystem (exfat in my case) and the partition cannot be mounted after that. The parameter high_offset is always passed in as zero.  

After spending a few hours wandering through code with a little bit of wiresharking and debugging I found the issue and fixed it. While the offset in the USB control structure is a uint64_t, the variable that is used to extract the LBA value from the USB packet is a uint32_t which causes 32 bit arithmetic to be used erroneously.

The function mwMSC_RWSetup in mw_usbd_mscuser.c contains the following line that converts the LBA address to the 64 bit offset:

pMscCtrl->Offset = n * pMscCtrl->BlockSize;

This line needs a cast to make sure that 64 bit arithmetic is used and should read:

pMscCtrl->Offset = (uint64_t)n * pMscCtrl->BlockSize;

With that fix in place I was able to write multiple 7GB files to the sd card with out any problem.

Hopefully this post helps 2^32+1 people.

Best regards,

Mike

0 Kudos
Reply