|
ChibiOS/RT
2.5.1 |
00001 /* 00002 ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, 00003 2011,2012 Giovanni Di Sirio. 00004 00005 This file is part of ChibiOS/RT. 00006 00007 ChibiOS/RT is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 ChibiOS/RT is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 /** 00022 * @file STM32/USBv1/usb_lld.h 00023 * @brief STM32 USB subsystem low level driver header. 00024 * 00025 * @addtogroup USB 00026 * @{ 00027 */ 00028 00029 #ifndef _USB_LLD_H_ 00030 #define _USB_LLD_H_ 00031 00032 #if HAL_USE_USB || defined(__DOXYGEN__) 00033 00034 #include "stm32_usb.h" 00035 00036 /*===========================================================================*/ 00037 /* Driver constants. */ 00038 /*===========================================================================*/ 00039 00040 /** 00041 * @brief Maximum endpoint address. 00042 */ 00043 #define USB_MAX_ENDPOINTS USB_ENDOPOINTS_NUMBER 00044 00045 /** 00046 * @brief This device requires the address change after the status packet. 00047 */ 00048 #define USB_SET_ADDRESS_MODE USB_LATE_SET_ADDRESS 00049 00050 /*===========================================================================*/ 00051 /* Driver pre-compile time settings. */ 00052 /*===========================================================================*/ 00053 00054 /** 00055 * @brief USB1 driver enable switch. 00056 * @details If set to @p TRUE the support for USB1 is included. 00057 * @note The default is @p TRUE. 00058 */ 00059 #if !defined(STM32_USB_USE_USB1) || defined(__DOXYGEN__) 00060 #define STM32_USB_USE_USB1 FALSE 00061 #endif 00062 00063 /** 00064 * @brief Enables the USB device low power mode on suspend. 00065 */ 00066 #if !defined(STM32_USB_LOW_POWER_ON_SUSPEND) || defined(__DOXYGEN__) 00067 #define STM32_USB_LOW_POWER_ON_SUSPEND FALSE 00068 #endif 00069 00070 /** 00071 * @brief USB1 interrupt priority level setting. 00072 */ 00073 #if !defined(STM32_USB_USB1_HP_IRQ_PRIORITY) || defined(__DOXYGEN__) 00074 #define STM32_USB_USB1_HP_IRQ_PRIORITY 13 00075 #endif 00076 00077 /** 00078 * @brief USB1 interrupt priority level setting. 00079 */ 00080 #if !defined(STM32_USB_USB1_LP_IRQ_PRIORITY) || defined(__DOXYGEN__) 00081 #define STM32_USB_USB1_LP_IRQ_PRIORITY 14 00082 #endif 00083 00084 /*===========================================================================*/ 00085 /* Derived constants and error checks. */ 00086 /*===========================================================================*/ 00087 00088 #if STM32_USB_USE_USB1 && !STM32_HAS_USB 00089 #error "USB not present in the selected device" 00090 #endif 00091 00092 #if !STM32_USB_USE_USB1 00093 #error "USB driver activated but no USB peripheral assigned" 00094 #endif 00095 00096 #if STM32_USB_USE_USB1 && \ 00097 !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_USB_USB1_HP_IRQ_PRIORITY) 00098 #error "Invalid IRQ priority assigned to USB HP" 00099 #endif 00100 00101 #if STM32_USB_USE_USB1 && \ 00102 !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_USB_USB1_LP_IRQ_PRIORITY) 00103 #error "Invalid IRQ priority assigned to USB LP" 00104 #endif 00105 00106 #if STM32_USBCLK != 48000000 00107 #error "the USB driver requires a 48MHz clock" 00108 #endif 00109 00110 /*===========================================================================*/ 00111 /* Driver data structures and types. */ 00112 /*===========================================================================*/ 00113 00114 /** 00115 * @brief Type of an IN endpoint state structure. 00116 */ 00117 typedef struct { 00118 /** 00119 * @brief Buffer mode, queue or linear. 00120 */ 00121 bool_t txqueued; 00122 /** 00123 * @brief Requested transmit transfer size. 00124 */ 00125 size_t txsize; 00126 /** 00127 * @brief Transmitted bytes so far. 00128 */ 00129 size_t txcnt; 00130 union { 00131 struct { 00132 /** 00133 * @brief Pointer to the transmission linear buffer. 00134 */ 00135 const uint8_t *txbuf; 00136 } linear; 00137 struct { 00138 /** 00139 * @brief Pointer to the output queue. 00140 */ 00141 OutputQueue *txqueue; 00142 } queue; 00143 /* End of the mandatory fields.*/ 00144 } mode; 00145 } USBInEndpointState; 00146 00147 /** 00148 * @brief Type of an OUT endpoint state structure. 00149 */ 00150 typedef struct { 00151 /** 00152 * @brief Buffer mode, queue or linear. 00153 */ 00154 bool_t rxqueued; 00155 /** 00156 * @brief Requested receive transfer size. 00157 */ 00158 size_t rxsize; 00159 /** 00160 * @brief Received bytes so far. 00161 */ 00162 size_t rxcnt; 00163 union { 00164 struct { 00165 /** 00166 * @brief Pointer to the receive linear buffer. 00167 */ 00168 uint8_t *rxbuf; 00169 } linear; 00170 struct { 00171 /** 00172 * @brief Pointer to the input queue. 00173 */ 00174 InputQueue *rxqueue; 00175 } queue; 00176 } mode; 00177 /* End of the mandatory fields.*/ 00178 /** 00179 * @brief Number of packets to receive. 00180 */ 00181 uint16_t rxpkts; 00182 } USBOutEndpointState; 00183 00184 /** 00185 * @brief Type of an USB endpoint configuration structure. 00186 * @note Platform specific restrictions may apply to endpoints. 00187 */ 00188 typedef struct { 00189 /** 00190 * @brief Type and mode of the endpoint. 00191 */ 00192 uint32_t ep_mode; 00193 /** 00194 * @brief Setup packet notification callback. 00195 * @details This callback is invoked when a setup packet has been 00196 * received. 00197 * @post The application must immediately call @p usbReadPacket() in 00198 * order to access the received packet. 00199 * @note This field is only valid for @p USB_EP_MODE_TYPE_CTRL 00200 * endpoints, it should be set to @p NULL for other endpoint 00201 * types. 00202 */ 00203 usbepcallback_t setup_cb; 00204 /** 00205 * @brief IN endpoint notification callback. 00206 * @details This field must be set to @p NULL if the IN endpoint is not 00207 * used. 00208 */ 00209 usbepcallback_t in_cb; 00210 /** 00211 * @brief OUT endpoint notification callback. 00212 * @details This field must be set to @p NULL if the OUT endpoint is not 00213 * used. 00214 */ 00215 usbepcallback_t out_cb; 00216 /** 00217 * @brief IN endpoint maximum packet size. 00218 * @details This field must be set to zero if the IN endpoint is not 00219 * used. 00220 */ 00221 uint16_t in_maxsize; 00222 /** 00223 * @brief OUT endpoint maximum packet size. 00224 * @details This field must be set to zero if the OUT endpoint is not 00225 * used. 00226 */ 00227 uint16_t out_maxsize; 00228 /** 00229 * @brief @p USBEndpointState associated to the IN endpoint. 00230 * @details This structure maintains the state of the IN endpoint. 00231 */ 00232 USBInEndpointState *in_state; 00233 /** 00234 * @brief @p USBEndpointState associated to the OUT endpoint. 00235 * @details This structure maintains the state of the OUT endpoint. 00236 */ 00237 USBOutEndpointState *out_state; 00238 /* End of the mandatory fields.*/ 00239 /** 00240 * @brief Reserved field, not currently used. 00241 * @note Initialize this field to 1 in order to be forward compatible. 00242 */ 00243 uint16_t ep_buffers; 00244 /** 00245 * @brief Pointer to a buffer for setup packets. 00246 * @details Setup packets require a dedicated 8-bytes buffer, set this 00247 * field to @p NULL for non-control endpoints. 00248 */ 00249 uint8_t *setup_buf; 00250 } USBEndpointConfig; 00251 00252 /** 00253 * @brief Type of an USB driver configuration structure. 00254 */ 00255 typedef struct { 00256 /** 00257 * @brief USB events callback. 00258 * @details This callback is invoked when an USB driver event is registered. 00259 */ 00260 usbeventcb_t event_cb; 00261 /** 00262 * @brief Device GET_DESCRIPTOR request callback. 00263 * @note This callback is mandatory and cannot be set to @p NULL. 00264 */ 00265 usbgetdescriptor_t get_descriptor_cb; 00266 /** 00267 * @brief Requests hook callback. 00268 * @details This hook allows to be notified of standard requests or to 00269 * handle non standard requests. 00270 */ 00271 usbreqhandler_t requests_hook_cb; 00272 /** 00273 * @brief Start Of Frame callback. 00274 */ 00275 usbcallback_t sof_cb; 00276 /* End of the mandatory fields.*/ 00277 } USBConfig; 00278 00279 /** 00280 * @brief Structure representing an USB driver. 00281 */ 00282 struct USBDriver { 00283 /** 00284 * @brief Driver state. 00285 */ 00286 usbstate_t state; 00287 /** 00288 * @brief Current configuration data. 00289 */ 00290 const USBConfig *config; 00291 /** 00292 * @brief Field available to user, it can be used to associate an 00293 * application-defined handler to the USB driver. 00294 */ 00295 void *param; 00296 /** 00297 * @brief Bit map of the transmitting IN endpoints. 00298 */ 00299 uint16_t transmitting; 00300 /** 00301 * @brief Bit map of the receiving OUT endpoints. 00302 */ 00303 uint16_t receiving; 00304 /** 00305 * @brief Active endpoints configurations. 00306 */ 00307 const USBEndpointConfig *epc[USB_MAX_ENDPOINTS + 1]; 00308 /** 00309 * @brief Endpoint 0 state. 00310 */ 00311 usbep0state_t ep0state; 00312 /** 00313 * @brief Next position in the buffer to be transferred through endpoint 0. 00314 */ 00315 uint8_t *ep0next; 00316 /** 00317 * @brief Number of bytes yet to be transferred through endpoint 0. 00318 */ 00319 size_t ep0n; 00320 /** 00321 * @brief Endpoint 0 end transaction callback. 00322 */ 00323 usbcallback_t ep0endcb; 00324 /** 00325 * @brief Setup packet buffer. 00326 */ 00327 uint8_t setup[8]; 00328 /** 00329 * @brief Current USB device status. 00330 */ 00331 uint16_t status; 00332 /** 00333 * @brief Assigned USB address. 00334 */ 00335 uint8_t address; 00336 /** 00337 * @brief Current USB device configuration. 00338 */ 00339 uint8_t configuration; 00340 #if defined(USB_DRIVER_EXT_FIELDS) 00341 USB_DRIVER_EXT_FIELDS 00342 #endif 00343 /* End of the mandatory fields.*/ 00344 /** 00345 * @brief Pointer to the next address in the packet memory. 00346 */ 00347 uint32_t pmnext; 00348 }; 00349 00350 /*===========================================================================*/ 00351 /* Driver macros. */ 00352 /*===========================================================================*/ 00353 00354 /** 00355 * @brief Returns the current frame number. 00356 * 00357 * @param[in] usbp pointer to the @p USBDriver object 00358 * @return The current frame number. 00359 * 00360 * @notapi 00361 */ 00362 #define usb_lld_get_frame_number(usbp) (STM32_USB->FNR & FNR_FN_MASK) 00363 00364 /** 00365 * @brief Returns the exact size of a receive transaction. 00366 * @details The received size can be different from the size specified in 00367 * @p usbStartReceiveI() because the last packet could have a size 00368 * different from the expected one. 00369 * @pre The OUT endpoint must have been configured in transaction mode 00370 * in order to use this function. 00371 * 00372 * @param[in] usbp pointer to the @p USBDriver object 00373 * @param[in] ep endpoint number 00374 * @return Received data size. 00375 * 00376 * @notapi 00377 */ 00378 #define usb_lld_get_transaction_size(usbp, ep) \ 00379 ((usbp)->epc[ep]->out_state->rxcnt) 00380 00381 /** 00382 * @brief Returns the exact size of a received packet. 00383 * @pre The OUT endpoint must have been configured in packet mode 00384 * in order to use this function. 00385 * 00386 * @param[in] usbp pointer to the @p USBDriver object 00387 * @param[in] ep endpoint number 00388 * @return Received data size. 00389 * 00390 * @notapi 00391 */ 00392 #define usb_lld_get_packet_size(usbp, ep) \ 00393 ((size_t)USB_GET_DESCRIPTOR(ep)->RXCOUNT & RXCOUNT_COUNT_MASK) 00394 00395 /*===========================================================================*/ 00396 /* External declarations. */ 00397 /*===========================================================================*/ 00398 00399 #if STM32_USB_USE_USB1 && !defined(__DOXYGEN__) 00400 extern USBDriver USBD1; 00401 #endif 00402 00403 #ifdef __cplusplus 00404 extern "C" { 00405 #endif 00406 void usb_lld_init(void); 00407 void usb_lld_start(USBDriver *usbp); 00408 void usb_lld_stop(USBDriver *usbp); 00409 void usb_lld_reset(USBDriver *usbp); 00410 void usb_lld_set_address(USBDriver *usbp); 00411 void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep); 00412 void usb_lld_disable_endpoints(USBDriver *usbp); 00413 usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep); 00414 usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep); 00415 void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf); 00416 void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep); 00417 void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep); 00418 void usb_lld_start_out(USBDriver *usbp, usbep_t ep); 00419 void usb_lld_start_in(USBDriver *usbp, usbep_t ep); 00420 void usb_lld_stall_out(USBDriver *usbp, usbep_t ep); 00421 void usb_lld_stall_in(USBDriver *usbp, usbep_t ep); 00422 void usb_lld_clear_out(USBDriver *usbp, usbep_t ep); 00423 void usb_lld_clear_in(USBDriver *usbp, usbep_t ep); 00424 #ifdef __cplusplus 00425 } 00426 #endif 00427 00428 #endif /* HAL_USE_USB */ 00429 00430 #endif /* _USB_LLD_H_ */ 00431 00432 /** @} */