1 /*********************************************************************** 2 * $Id:: mw_usbd_mscuser.h 577 2012-11-20 01:42:04Z usb10131 $ 3 * 4 * Project: USB device ROM Stack 5 * 6 * Description: 7 * Mass Storage Class Custom User Module definitions. 8 * 9 *********************************************************************** 10 * Copyright(C) 2011, NXP Semiconductor 11 * All rights reserved. 12 * 13 * Software that is described herein is for illustrative purposes only 14 * which provides customers with programming information regarding the 15 * products. This software is supplied "AS IS" without any warranties. 16 * NXP Semiconductors assumes no responsibility or liability for the 17 * use of the software, conveys no license or title under any patent, 18 * copyright, or mask work right to the product. NXP Semiconductors 19 * reserves the right to make changes in the software without 20 * notification. NXP Semiconductors also make no representation or 21 * warranty that such application will be suitable for the specified 22 * use without further testing or modification. 23 **********************************************************************/ 24 #ifndef __MSCUSER_H__ 25 #define __MSCUSER_H__ 26 27 #include "error.h" 28 #include "usbd.h" 29 #include "usbd_msc.h" 30 #include "usbd_core.h" 31 #include "app_usbd_cfg.h" 32 33 /** \file 34 * \brief Mass Storage Class (MSC) API structures and function prototypes. 35 * 36 * Definition of functions exported by ROM based MSC function driver. 37 * 38 */ 39 40 /** \ingroup Group_USBD 41 * @defgroup USBD_MSC Mass Storage Class (MSC) Function Driver 42 * \section Sec_MSCModDescription Module Description 43 * MSC Class Function Driver module. This module contains an internal implementation of the USB MSC Class. 44 * User applications can use this class driver instead of implementing the MSC class manually 45 * via the low-level USBD_HW and USBD_Core APIs. 46 * 47 * This module is designed to simplify the user code by exposing only the required interface needed to interface with 48 * Devices using the USB MSC Class. 49 */ 50 51 /** \brief Mass Storage class function driver initialization parameter data structure. 52 * \ingroup USBD_MSC 53 * 54 * \details This data structure is used to pass initialization parameters to the 55 * Mass Storage class function driver's init function. 56 * 57 */ 58 typedef struct USBD_MSC_INIT_PARAM 59 { 60 /* memory allocation params */ 61 uint32_t mem_base; /**< Base memory location from where the stack can allocate 62 data and buffers. \note The memory address set in this field 63 should be accessible by USB DMA controller. Also this value 64 should be aligned on 4 byte boundary. 65 */ 66 uint32_t mem_size; /**< The size of memory buffer which stack can use. 67 \note The \em mem_size should be greater than the size 68 returned by USBD_MSC_API::GetMemSize() routine.*/ 69 /* mass storage params */ 70 uint8_t* InquiryStr; /**< Pointer to the 28 character string. This string is 71 sent in response to the SCSI Inquiry command. \note The data 72 pointed by the pointer should be of global scope. 73 */ 74 uint32_t BlockCount; /**< Number of blocks present in the mass storage device */ 75 uint32_t BlockSize; /**< Block size in number of bytes */ 76 uint32_t MemorySize; /**< Memory size in number of bytes */ 77 /** Pointer to the interface descriptor within the descriptor 78 * array (\em high_speed_desc) passed to Init() through \ref USB_CORE_DESCS_T 79 * structure. The stack assumes both HS and FS use same BULK endpoints. 80 */ 81 82 uint8_t* intf_desc; 83 /* user defined functions */ 84 85 /** 86 * MSC Write callback function. 87 * 88 * This function is provided by the application software. This function gets called 89 * when host sends a write command. 90 * 91 * \param[in] offset Destination start address. 92 * \param[in, out] src Pointer to a pointer to the source of data. Pointer-to-pointer 93 * is used to implement zero-copy buffers. See \ref USBD_ZeroCopy 94 * for more details on zero-copy concept. 95 * \param[in] length Number of bytes to be written. 96 * \return Nothing. 97 * 98 */ 99 void (*MSC_Write)( uint32_t offset, uint8_t** src, uint32_t length, uint32_t high_offset); 100 /** 101 * MSC Read callback function. 102 * 103 * This function is provided by the application software. This function gets called 104 * when host sends a read command. 105 * 106 * \param[in] offset Source start address. 107 * \param[in, out] dst Pointer to a pointer to the source of data. The MSC function drivers 108 * implemented in stack are written with zero-copy model. Meaning the stack doesn't make an 109 * extra copy of buffer before writing/reading data from USB hardware FIFO. Hence the 110 * parameter is pointer to a pointer containing address buffer (<em>uint8_t** dst</em>). 111 * So that the user application can update the buffer pointer instead of copying data to 112 * address pointed by the parameter. /note The updated buffer address should be accessible 113 * by USB DMA master. If user doesn't want to use zero-copy model, then the user should copy 114 * data to the address pointed by the passed buffer pointer parameter and shouldn't change 115 * the address value. See \ref USBD_ZeroCopy for more details on zero-copy concept. 116 * \param[in] length Number of bytes to be read. 117 * \return Nothing. 118 * 119 */ 120 void (*MSC_Read)( uint32_t offset, uint8_t** dst, uint32_t length, uint32_t high_offset); 121 /** 122 * MSC Verify callback function. 123 * 124 * This function is provided by the application software. This function gets called 125 * when host sends a verify command. The callback function should compare the buffer 126 * with the destination memory at the requested offset and 127 * 128 * \param[in] offset Destination start address. 129 * \param[in] buf Buffer containing the data sent by the host. 130 * \param[in] length Number of bytes to verify. 131 * \return Returns \ref ErrorCode_t type to indicate success or error condition. 132 * \retval LPC_OK If data in the buffer matches the data at destination 133 * \retval ERR_FAILED At least one byte is different. 134 * 135 */ 136 ErrorCode_t (*MSC_Verify)( uint32_t offset, uint8_t buf[], uint32_t length, uint32_t high_offset); 137 /** 138 * Optional callback function to optimize MSC_Write buffer transfer. 139 * 140 * This function is provided by the application software. This function gets called 141 * when host sends SCSI_WRITE10/SCSI_WRITE12 command. The callback function should 142 * update the \em buff_adr pointer so that the stack transfers the data directly 143 * to the target buffer. /note The updated buffer address should be accessible 144 * by USB DMA master. If user doesn't want to use zero-copy model, then the user 145 * should not update the buffer pointer. See \ref USBD_ZeroCopy for more details 146 * on zero-copy concept. 147 * 148 * \param[in] offset Destination start address. 149 * \param[in,out] buf Buffer containing the data sent by the host. 150 * \param[in] length Number of bytes to write. 151 * \return Nothing. 152 * 153 */ 154 void (*MSC_GetWriteBuf)( uint32_t offset, uint8_t** buff_adr, uint32_t length, uint32_t high_offset); 155 156 /** 157 * Optional user override-able function to replace the default MSC class handler. 158 * 159 * The application software could override the default EP0 class handler with their 160 * own by providing the handler function address as this data member of the parameter 161 * structure. Application which like the default handler should set this data member 162 * to zero before calling the USBD_MSC_API::Init(). 163 * \n 164 * \note 165 * 166 * \param[in] hUsb Handle to the USB device stack. 167 * \param[in] data Pointer to the data which will be passed when callback function is called by the stack. 168 * \param[in] event Type of endpoint event. See \ref USBD_EVENT_T for more details. 169 * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. 170 * \retval LPC_OK On success. 171 * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. 172 * \retval ERR_USBD_xxx For other error conditions. 173 * 174 */ 175 ErrorCode_t (*MSC_Ep0_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event); 176 177 uint64_t MemorySize64; 178 179 } USBD_MSC_INIT_PARAM_T; 180 181 /** \brief MSC class API functions structure. 182 * \ingroup USBD_MSC 183 * 184 * This module exposes functions which interact directly with USB device controller hardware. 185 * 186 */ 187 typedef struct USBD_MSC_API 188 { 189 /** \fn uint32_t GetMemSize(USBD_MSC_INIT_PARAM_T* param) 190 * Function to determine the memory required by the MSC function driver module. 191 * 192 * This function is called by application layer before calling pUsbApi->msc->Init(), to allocate memory used 193 * by MSC function driver module. The application should allocate the memory which is accessible by USB 194 * controller/DMA controller. 195 * \note Some memory areas are not accessible by all bus masters. 196 * 197 * \param[in] param Structure containing MSC function driver module initialization parameters. 198 * \return Returns the required memory size in bytes. 199 */ 200 uint32_t (*GetMemSize)(USBD_MSC_INIT_PARAM_T* param); 201 202 /** \fn ErrorCode_t init(USBD_HANDLE_T hUsb, USBD_MSC_INIT_PARAM_T* param) 203 * Function to initialize MSC function driver module. 204 * 205 * This function is called by application layer to initialize MSC function driver module. 206 * 207 * \param[in] hUsb Handle to the USB device stack. 208 * \param[in, out] param Structure containing MSC function driver module initialization parameters. 209 * \return Returns \ref ErrorCode_t type to indicate success or error condition. 210 * \retval LPC_OK On success 211 * \retval ERR_USBD_BAD_MEM_BUF Memory buffer passed is not 4-byte 212 * aligned or smaller than required. 213 * \retval ERR_API_INVALID_PARAM2 Either MSC_Write() or MSC_Read() or 214 * MSC_Verify() callbacks are not defined. 215 * \retval ERR_USBD_BAD_INTF_DESC Wrong interface descriptor is passed. 216 * \retval ERR_USBD_BAD_EP_DESC Wrong endpoint descriptor is passed. 217 */ 218 ErrorCode_t (*init)(USBD_HANDLE_T hUsb, USBD_MSC_INIT_PARAM_T* param); 219 220 } USBD_MSC_API_T; 221 222 /*----------------------------------------------------------------------------- 223 * Private functions & structures prototypes 224 *-----------------------------------------------------------------------------*/ 225 /** @cond ADVANCED_API */ 226 227 typedef struct _MSC_CTRL_T 228 { 229 /* If it's a USB HS, the max packet is 512, if it's USB FS, 230 the max packet is 64. Use 512 for both HS and FS. */ 231 /*ALIGNED(4)*/ uint8_t BulkBuf[USB_HS_MAX_BULK_PACKET]; /* Bulk In/Out Buffer */ 232 /*ALIGNED(4)*/MSC_CBW CBW; /* Command Block Wrapper */ 233 /*ALIGNED(4)*/MSC_CSW CSW; /* Command Status Wrapper */ 234 235 USB_CORE_CTRL_T* pUsbCtrl; 236 237 uint64_t Offset; /* R/W Offset */ 238 uint32_t Length; /* R/W Length */ 239 uint32_t BulkLen; /* Bulk In/Out Length */ 240 uint8_t* rx_buf; 241 242 uint8_t BulkStage; /* Bulk Stage */ 243 uint8_t if_num; /* interface number */ 244 uint8_t epin_num; /* BULK IN endpoint number */ 245 uint8_t epout_num; /* BULK OUT endpoint number */ 246 uint32_t MemOK; /* Memory OK */ 247 248 uint8_t* InquiryStr; 249 uint32_t BlockCount; 250 uint32_t BlockSize; 251 uint64_t MemorySize; 252 /* user defined functions */ 253 void (*MSC_Write)( uint32_t offset, uint8_t** src, uint32_t length, uint32_t high_offset); 254 void (*MSC_Read)( uint32_t offset, uint8_t** dst, uint32_t length, uint32_t high_offset); 255 ErrorCode_t (*MSC_Verify)( uint32_t offset, uint8_t src[], uint32_t length, uint32_t high_offset); 256 /* optional call back for MSC_Write optimization */ 257 void (*MSC_GetWriteBuf)( uint32_t offset, uint8_t** buff_adr, uint32_t length, uint32_t high_offset); 258 259 260 }USB_MSC_CTRL_T; 261 262 /** @cond DIRECT_API */ 263 extern uint32_t mwMSC_GetMemSize(USBD_MSC_INIT_PARAM_T* param); 264 extern ErrorCode_t mwMSC_init(USBD_HANDLE_T hUsb, USBD_MSC_INIT_PARAM_T* param); 265 /** @endcond */ 266 267 /** @endcond */ 268 269 270 #endif /* __MSCUSER_H__ */ 271