lpcware

Using LPC1830 USBD ROM stack for MSC device

Discussion created by lpcware Employee on Jun 15, 2016
Content originally posted in LPCWare by ironss_eaton on Sun May 10 21:15:18 MST 2015
Hello

We are in the processing of developing a product that has to appear as a USB MSC device when plugged into a PC. The USBD ROM stack seems to be just what we need. However, the example (storing data in RAM) is note very enlightening, and the documentation for the ROM stack is very poor:

[list]
  [*]Most disk software operates in terms of sectors. In prior example code, both FatFS and LPCUSBlib/lpcusblib_MassStorageDevice operated on sectors. I assume that the ROM stack thinks of the disk simply as a huge sequence of bytes?
  [*]The description of the callback functions in the user manual (UM10430 LPC18xx User Manual 17 February2015) is different from the functions actually provided in the example code -- there is an extra parameter high_offset in the example code. The example code does, however, agree with the LPCOpen #include files.
  [*]Both the user manual and the LPCOpen #include files refer to Zero-Copy Data Transfer Model. I found an old, incomplete description at http://docs.lpcware.com/usbromlib/v1.0/index.html
[/list]

This is how I think the USBD ROM stack things work.

[list=1]
  [*]The ROM stack calls the MSC_Read function when it is about to send (to the remote host) data read from disk. The user code calculates the sector number from the offset, allocates a buffer, reads the data from disk into the buffer, and writes a pointer to the buffer into *buff_adr. The ROM stack then transfers the data from the buffer to the remote host.
  [*]The ROM stack calls the MSC_GetWriteBuf function when it is about to receive (from the remote host) data that will be written to disk. The user code calculates the sector number from the offset, allocates a buffer to receive the data, and writes a pointer to the buffer into *buff_adr. The ROM stack then transfers the data from the remote host into the buffer.
  [*]The ROM stack calls the MSC_Write function when is has received (from the remote host) data that must now be written to disk. The user code calculates the sector number, then writes the data from the buffer to the disk. The user code can allocate a new buffer and write a pointer to the new buffer in buf_addr before returning. This will allow the user function to trigger a long-running process to write the data in the old buffer to disk while the ROM stack can continue to receive more data in the new buffer.
  [*]It is safe to provide only two buffers, one for reading, the other for writing, and to re-use these two buffers for all read and write operations, provided that the operation has completed before returning to the ROM stack.
  [*]Although the ROM stack tells the user code how big the buffer should be, there is no way for the user code to tell the ROM stack that it could not allocate that size buffer. We had better hope that the ROM stack does not try to write too much at once. Perhaps the ROM stack plays nicely and only transfers one sector's worth of data (BlockSize) at a time?
  [*]It is not clear how the user code knows when the ROM stack has finished using the read buffer, so that the user code can free the buffer. Perhaps the next call to the MSC_Read function tells the user code that the previous buffer is now free?
  [*]It is not clear how the user code knows which sector to write to. Assuming that the ROM stack thinks of the disk as a linear sequence of up to 2^64 bytes, perhaps the user code can calculate the sector number as:
offset64 = (offset_high << 32) | offset
sector = offset / BlockSize

[/list]
with appropriate type_casts, rounding and so on.

[list]
  [*]Please will someone confirm whether this description is close to the mark, or completely wrong.
  [*]Please make corrections, and feel free to use this description as a basis for the next version of the User Manual and online documentation.
  [*]Please consider including a non-trivial example (using SD card or SPIFI flash) in a new release of LPCOpen.
[/list]

Thank you
Stephen Irons

Outcomes