1 /***********************************************************************
2 * $Id:: mw_usbd_dfuuser.h 331 2012-08-09 18:54:34Z usb10131                   $
3 *
4 * Project: USB device ROM Stack
5 *
6 * Description:
7 *     Device Firmware Upgrade 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 
25 #ifndef __DFUUSER_H__
26 #define __DFUUSER_H__
27 
28 #include "usbd.h"
29 #include "usbd_dfu.h"
30 #include "usbd_core.h"
31 
32 /** \file
33  *  \brief Device Firmware Upgrade (DFU) API structures and function prototypes.
34  *
35  *  Definition of functions exported by ROM based DFU function driver.
36  *
37  */
38 
39 
40 /** \ingroup Group_USBD
41  *  @defgroup USBD_DFU Device Firmware Upgrade (DFU) Class Function Driver
42  *  \section Sec_MSCModDescription Module Description
43  *  DFU Class Function Driver module. This module contains an internal implementation of the USB DFU Class.
44  *  User applications can use this class driver instead of implementing the DFU 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 DFU Class.
49  */
50 
51 /** \brief USB descriptors data structure.
52  *  \ingroup USBD_DFU
53  *
54  *  \details  This module exposes functions which interact directly with USB device stack's core layer.
55  *  The application layer uses this component when it has to implement custom class function driver or
56  *  standard class function driver which is not part of the current USB device stack.
57  *  The functions exposed by this interface are to register class specific EP0 handlers and corresponding
58  *  utility functions to manipulate EP0 state machine of the stack. This interface also exposes
59  *  function to register custom endpoint interrupt handler.
60  *
61  */
62 typedef struct USBD_DFU_INIT_PARAM
63 {
64   /* memory allocation params */
65   uint32_t mem_base;  /**< Base memory location from where the stack can allocate
66                       data and buffers. \note The memory address set in this field
67                       should be accessible by USB DMA controller. Also this value
68                       should be aligned on 4 byte boundary.
69                       */
70   uint32_t mem_size;  /**< The size of memory buffer which stack can use.
71                       \note The \em mem_size should be greater than the size
72                       returned by USBD_DFU_API::GetMemSize() routine.*/
73   /* DFU paramas */
74   uint16_t wTransferSize; /**< DFU transfer block size in number of bytes.
75                           This value should match the value set in DFU descriptor
76                           provided as part of the descriptor array
77                           (\em high_speed_desc) passed to Init() through
78                           \ref USB_CORE_DESCS_T structure.  */
79 
80   uint16_t pad;
81   /** Pointer to the DFU interface descriptor within the descriptor
82   * array (\em high_speed_desc) passed to Init() through \ref USB_CORE_DESCS_T
83   * structure.
84   */
85   uint8_t* intf_desc;
86   /* user defined functions */
87   /**
88   *  DFU Write callback function.
89   *
90   *  This function is provided by the application software. This function gets called
91   *  when host sends a write command. For application using zero-copy buffer scheme
92   *  this function is called for the first time with \em length parameter set to 0.
93   *  The application code should update the buffer pointer.
94   *
95   *  \param[in] block_num Destination start address.
96   *  \param[in, out] src  Pointer to a pointer to the source of data. Pointer-to-pointer
97   *                     is used to implement zero-copy buffers. See \ref USBD_ZeroCopy
98   *                     for more details on zero-copy concept.
99   *  \param[out] bwPollTimeout  Pointer to a 3 byte buffer which the callback implementer
100   *                     should fill with the amount of minimum time, in milliseconds,
101   *                     that the host should wait before sending a subsequent
102   *                     DFU_GETSTATUS request.
103   *  \param[in] length  Number of bytes to be written.
104   *  \return Returns DFU_STATUS_ values defined in mw_usbd_dfu.h.
105   *
106   */
107   uint8_t (*DFU_Write)( uint32_t block_num, uint8_t** src, uint32_t length, uint8_t* bwPollTimeout);
108 
109   /**
110   *  DFU Read callback function.
111   *
112   *  This function is provided by the application software. This function gets called
113   *  when host sends a read command.
114   *
115   *  \param[in] block_num Destination start address.
116   *  \param[in, out] dst  Pointer to a pointer to the source of data. Pointer-to-pointer
117   *                       is used to implement zero-copy buffers. See \ref USBD_ZeroCopy
118   *                       for more details on zero-copy concept.
119   *  \param[in] length  Amount of data copied to destination buffer.
120   *  \return Returns
121   *                 - DFU_STATUS_ values defined in mw_usbd_dfu.h to return error conditions.
122   *                 - 0 if there is no more data to be read. Stack will send EOF frame and set
123   *                     DFU state-machine to dfuIdle state.
124   *                 - length of the data copied, should be greater than or equal to 16. If the data copied
125   *                   is less than DFU \em wTransferSize the stack will send EOF frame and
126   *                   goes to dfuIdle state.
127   *
128   */
129   uint32_t (*DFU_Read)( uint32_t block_num, uint8_t** dst, uint32_t length);
130 
131   /**
132   *  DFU done callback function.
133   *
134   *  This function is provided by the application software. This function gets called
135   *  after firmware download completes.
136   *
137   *  \return Nothing.
138   *
139   */
140   void (*DFU_Done)(void);
141 
142   /**
143   *  DFU detach callback function.
144   *
145   *  This function is provided by the application software. This function gets called
146   *  after USB_REQ_DFU_DETACH is received. Applications which set USB_DFU_WILL_DETACH
147   *  bit in DFU descriptor should define this function. As part of this function
148   *  application can call Connect() routine to disconnect and then connect back with
149   *  host. For application which rely on WinUSB based host application should use this
150   *  feature since USB reset can be invoked only by kernel drivers on Windows host.
151   *  By implementing this feature host doen't have to issue reset instead the device
152   *  has to do it automatically by disconnect and connect procedure.
153   *
154   *  \param[in] hUsb Handle DFU control structure.
155   *  \return Nothing.
156   *
157   */
158   void (*DFU_Detach)(USBD_HANDLE_T hUsb);
159 
160   /**
161   *  Optional user override-able function to replace the default DFU class handler.
162   *
163   *  The application software could override the default EP0 class handler with their
164   *  own by providing the handler function address as this data member of the parameter
165   *  structure. Application which like the default handler should set this data member
166   *  to zero before calling the USBD_DFU_API::Init().
167   *  \n
168   *  \note
169   *
170   *  \param[in] hUsb Handle to the USB device stack.
171   *  \param[in] data Pointer to the data which will be passed when callback function is called by the stack.
172   *  \param[in] event  Type of endpoint event. See \ref USBD_EVENT_T for more details.
173   *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
174   *          \retval LPC_OK On success.
175   *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line.
176   *          \retval ERR_USBD_xxx  For other error conditions.
177   *
178   */
179   ErrorCode_t (*DFU_Ep0_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event);
180 
181 } USBD_DFU_INIT_PARAM_T;
182 
183 
184 /** \brief DFU class API functions structure.
185  *  \ingroup USBD_DFU
186  *
187  *  This module exposes functions which interact directly with USB device controller hardware.
188  *
189  */
190 typedef struct USBD_DFU_API
191 {
192   /** \fn uint32_t GetMemSize(USBD_DFU_INIT_PARAM_T* param)
193    *  Function to determine the memory required by the DFU function driver module.
194    *
195    *  This function is called by application layer before calling pUsbApi->dfu->Init(), to allocate memory used
196    *  by DFU function driver module. The application should allocate the memory which is accessible by USB
197    *  controller/DMA controller.
198    *  \note Some memory areas are not accessible by all bus masters.
199    *
200    *  \param[in] param Structure containing DFU function driver module initialization parameters.
201    *  \return Returns the required memory size in bytes.
202    */
203   uint32_t (*GetMemSize)(USBD_DFU_INIT_PARAM_T* param);
204 
205   /** \fn ErrorCode_t init(USBD_HANDLE_T hUsb, USBD_DFU_INIT_PARAM_T* param)
206    *  Function to initialize DFU function driver module.
207    *
208    *  This function is called by application layer to initialize DFU function driver module.
209    *
210    *  \param[in] hUsb Handle to the USB device stack.
211    *  \param[in, out] param Structure containing DFU function driver module initialization parameters.
212    *  \return Returns \ref ErrorCode_t type to indicate success or error condition.
213    *          \retval LPC_OK On success
214    *          \retval ERR_USBD_BAD_MEM_BUF  Memory buffer passed is not 4-byte aligned or smaller than required.
215    *          \retval ERR_API_INVALID_PARAM2 Either DFU_Write() or DFU_Done() or DFU_Read() call-backs are not defined.
216    *          \retval ERR_USBD_BAD_DESC
217    *            - USB_DFU_DESCRIPTOR_TYPE is not defined immediately after
218    *              interface descriptor.
219    *            - wTransferSize in descriptor doesn't match the value passed
220    *              in param->wTransferSize.
221    *            - DFU_Detach() is not defined while USB_DFU_WILL_DETACH is set
222    *              in DFU descriptor.
223    *          \retval ERR_USBD_BAD_INTF_DESC  Wrong interface descriptor is passed.
224    */
225   ErrorCode_t (*init)(USBD_HANDLE_T hUsb, USBD_DFU_INIT_PARAM_T* param, uint32_t init_state);
226 
227 } USBD_DFU_API_T;
228 
229 /*-----------------------------------------------------------------------------
230  *  Private functions & structures prototypes
231  *-----------------------------------------------------------------------------*/
232 /** @cond  ADVANCED_API */
233 
234 typedef struct _USBD_DFU_CTRL_T
235 {
236   /*ALIGNED(4)*/ DFU_STATUS_T dfu_req_get_status;
237   uint16_t pad;
238   uint8_t dfu_state;
239   uint8_t dfu_status;
240   uint8_t download_done;
241   uint8_t if_num;                  /* interface number */
242 
243   uint8_t* xfr_buf;
244   USB_DFU_FUNC_DESCRIPTOR* dfu_desc;
245 
246   USB_CORE_CTRL_T*  pUsbCtrl;
247   /* user defined functions */
248   /* return DFU_STATUS_ values defined in mw_usbd_dfu.h */
249   uint8_t (*DFU_Write)( uint32_t block_num, uint8_t** src, uint32_t length, uint8_t* bwPollTimeout);
250   /* return
251   * DFU_STATUS_ : values defined in mw_usbd_dfu.h in case of errors
252   * 0 : If end of memory reached
253   * length : Amount of data copied to destination buffer
254   */
255   uint32_t (*DFU_Read)( uint32_t block_num, uint8_t** dst, uint32_t length);
256   /* callback called after download is finished */
257   void (*DFU_Done)(void);
258   /* callback called after USB_REQ_DFU_DETACH is recived */
259   void (*DFU_Detach)(USBD_HANDLE_T hUsb);
260 
261 } USBD_DFU_CTRL_T;
262 
263 /** @cond  DIRECT_API */
264 uint32_t mwDFU_GetMemSize(USBD_DFU_INIT_PARAM_T* param);
265 extern ErrorCode_t mwDFU_init(USBD_HANDLE_T hUsb, USBD_DFU_INIT_PARAM_T* param, uint32_t init_state);
266 /** @endcond */
267 
268 /** @endcond */
269 
270 #endif  /* __DFUUSER_H__ */
271