ChibiOS/RT
2.5.1
usb_lld.h
Go to the documentation of this file.
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 /** @} */