From 9708a3c30ff4ce1d95b3333b6be4375138a89be5 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 24 Feb 2013 15:35:53 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5313 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/templates/adc_lld.c | 29 ++++++- os/hal/templates/adc_lld.h | 73 +++++++++++++----- os/hal/templates/ext_lld.c | 28 +++++-- os/hal/templates/ext_lld.h | 15 +++- os/hal/templates/hal_lld.c | 152 ++++++++++++++++++++++++++++++++++++- os/hal/templates/hal_lld.h | 32 +++++++- os/hal/templates/usb_lld.c | 77 ++++++++++--------- os/hal/templates/usb_lld.h | 146 +++++++++++++++++++++++------------ 8 files changed, 431 insertions(+), 121 deletions(-) diff --git a/os/hal/templates/adc_lld.c b/os/hal/templates/adc_lld.c index 44c29d023..1ea117d8a 100644 --- a/os/hal/templates/adc_lld.c +++ b/os/hal/templates/adc_lld.c @@ -39,6 +39,11 @@ /* Driver exported variables. */ /*===========================================================================*/ +/** @brief ADC1 driver identifier.*/ +#if PLATFORM_ADC_USE_ADC1 || defined(__DOXYGEN__) +ADCDriver ADCD1; +#endif + /*===========================================================================*/ /* Driver local variables. */ /*===========================================================================*/ @@ -62,6 +67,10 @@ */ void adc_lld_init(void) { +#if PLATFORM_ADC_USE_ADC1 + /* Driver initialization.*/ + adcObjectInit(&ADCD1); +#endif /* PLATFORM_ADC_USE_ADC1 */ } /** @@ -73,10 +82,16 @@ void adc_lld_init(void) { */ void adc_lld_start(ADCDriver *adcp) { - if (adcp->adc_state == ADC_STOP) { - /* Clock activation.*/ + if (adcp->state == ADC_STOP) { + /* Enables the pehipheral.*/ +#if PLATFORM_ADC_USE_ADC1 + if (&ADCD1 == adcp) { + + } +#endif /* PLATFORM_ADC_USE_ADC1 */ } - /* Configuration.*/ + /* Configures the peripheral.*/ + } /** @@ -89,8 +104,14 @@ void adc_lld_start(ADCDriver *adcp) { void adc_lld_stop(ADCDriver *adcp) { if (adcp->state == ADC_READY) { - /* Clock de-activation.*/ + /* Resets the peripheral.*/ + /* Disables the peripheral.*/ +#if PLATFORM_ADC_USE_ADC1 + if (&ADCD1 == adcp) { + + } +#endif /* PLATFORM_ADC_USE_ADC1 */ } } diff --git a/os/hal/templates/adc_lld.h b/os/hal/templates/adc_lld.h index 1a396c06d..582f4dbaa 100644 --- a/os/hal/templates/adc_lld.h +++ b/os/hal/templates/adc_lld.h @@ -39,14 +39,24 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ +/** + * @brief ADC1 driver enable switch. + * @details If set to @p TRUE the support for ADC1 is included. + * @note The default is @p FALSE. + */ +#if !defined(PLATFORM_ADC_USE_ADC1) || defined(__DOXYGEN__) +#define PLATFORM_ADC_USE_ADC1 FALSE +#endif +/** @} */ + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ -#if !CH_USE_SEMAPHORES -#error "the ADC driver requires CH_USE_SEMAPHORES" -#endif - /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ @@ -61,6 +71,16 @@ typedef uint16_t adcsample_t; */ typedef uint16_t adc_channels_num_t; +/** + * @brief Possible ADC failure causes. + * @note Error codes are architecture dependent and should not relied + * upon. + */ +typedef enum { + ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */ + ADC_ERR_OVERFLOW = 1 /**< ADC overflow condition. */ +} adcerror_t; + /** * @brief Type of a structure representing an ADC driver. */ @@ -76,6 +96,15 @@ typedef struct ADCDriver ADCDriver; */ typedef void (*adccallback_t)(ADCDriver *adcp, adcsample_t *buffer, size_t n); +/** + * @brief ADC error callback type. + * + * @param[in] adcp pointer to the @p ADCDriver object triggering the + * callback + * @param[in] err ADC error code + */ +typedef void (*adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err); + /** * @brief Conversion group configuration structure. * @details This implementation-dependent structure describes a conversion @@ -85,66 +114,66 @@ typedef void (*adccallback_t)(ADCDriver *adcp, adcsample_t *buffer, size_t n); */ typedef struct { /** - * @brief Enables the circular buffer mode for the group. + * @brief Enables the circular buffer mode for the group. */ bool_t circular; /** - * @brief Number of the analog channels belonging to the conversion group. + * @brief Number of the analog channels belonging to the conversion group. */ adc_channels_num_t num_channels; /** - * @brief Callback function associated to the group or @p NULL. + * @brief Callback function associated to the group or @p NULL. */ adccallback_t end_cb; + /** + * @brief Error callback or @p NULL. + */ + adcerrorcallback_t error_cb; /* End of the mandatory fields.*/ } ADCConversionGroup; /** * @brief Driver configuration structure. - * @note Implementations may extend this structure to contain more, - * architecture dependent, fields. * @note It could be empty on some architectures. */ typedef struct { - + uint32_t dummy; } ADCConfig; /** * @brief Structure representing an ADC driver. - * @note Implementations may extend this structure to contain more, - * architecture dependent, fields. */ struct ADCDriver { /** - * @brief Driver state. + * @brief Driver state. */ adcstate_t state; /** - * @brief Current configuration data. + * @brief Current configuration data. */ const ADCConfig *config; /** - * @brief Current samples buffer pointer or @p NULL. + * @brief Current samples buffer pointer or @p NULL. */ adcsample_t *samples; /** - * @brief Current samples buffer depth or @p 0. + * @brief Current samples buffer depth or @p 0. */ size_t depth; /** - * @brief Current conversion group pointer or @p NULL. + * @brief Current conversion group pointer or @p NULL. */ const ADCConversionGroup *grpp; #if ADC_USE_WAIT || defined(__DOXYGEN__) /** - * @brief Waiting thread. + * @brief Waiting thread. */ Thread *thread; -#endif /* SPI_USE_WAIT */ +#endif #if ADC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) #if CH_USE_MUTEXES || defined(__DOXYGEN__) /** - * @brief Mutex protecting the peripheral. + * @brief Mutex protecting the peripheral. */ Mutex mutex; #elif CH_USE_SEMAPHORES @@ -165,6 +194,10 @@ struct ADCDriver { /* External declarations. */ /*===========================================================================*/ +#if PLATFORM_ADC_USE_ADC1 && !defined(__DOXYGEN__) +extern ADCDriver ADCD1; +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/os/hal/templates/ext_lld.c b/os/hal/templates/ext_lld.c index 54a10b644..e0d7575fd 100644 --- a/os/hal/templates/ext_lld.c +++ b/os/hal/templates/ext_lld.c @@ -39,10 +39,10 @@ /* Driver exported variables. */ /*===========================================================================*/ -/** - * @brief EXTD1 driver identifier. - */ +/** @brief EXT1 driver identifier.*/ +#if PLATFORM_EXT_USE_EXT1 || defined(__DOXYGEN__) EXTDriver EXTD1; +#endif /*===========================================================================*/ /* Driver local variables. */ @@ -67,8 +67,10 @@ EXTDriver EXTD1; */ void ext_lld_init(void) { +#if PLATFORM_EXT_USE_EXT1 /* Driver initialization.*/ extObjectInit(&EXTD1); +#endif /* PLATFORM_EXT_USE_EXT1 */ } /** @@ -81,9 +83,15 @@ void ext_lld_init(void) { void ext_lld_start(EXTDriver *extp) { if (extp->state == EXT_STOP) { - /* Clock activation.*/ + /* Enables the pehipheral.*/ +#if PLATFORM_EXT_USE_EXT1 + if (&EXTD1 == extp) { + + } +#endif /* PLATFORM_EXT_USE_EXT1 */ } - /* Configuration.*/ + /* Configures the peripheral.*/ + } /** @@ -95,9 +103,15 @@ void ext_lld_start(EXTDriver *extp) { */ void ext_lld_stop(EXTDriver *extp) { - if (extp->state == EXT_ACTIVE) { - /* Clock deactivation.*/ + if (extp->state == EXT_READY) { + /* Resets the peripheral.*/ + /* Disables the peripheral.*/ +#if PLATFORM_EXT_USE_EXT1 + if (&EXTD1 == extp) { + + } +#endif /* PLATFORM_EXT_USE_EXT1 */ } } diff --git a/os/hal/templates/ext_lld.h b/os/hal/templates/ext_lld.h index 5c4c4398a..d1f971713 100644 --- a/os/hal/templates/ext_lld.h +++ b/os/hal/templates/ext_lld.h @@ -44,6 +44,19 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ +/** + * @brief EXT driver enable switch. + * @details If set to @p TRUE the support for EXT1 is included. + */ +#if !defined(PLATFORM_EXT_USE_EXT1) || defined(__DOXYGEN__) +#define PLATFORM_EXT_USE_EXT1 FALSE +#endif +/** @} */ + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ @@ -117,7 +130,7 @@ struct EXTDriver { /* External declarations. */ /*===========================================================================*/ -#if !defined(__DOXYGEN__) +#if PLATFORM_EXT_USE_EXT1 && !defined(__DOXYGEN__) extern EXTDriver EXTD1; #endif diff --git a/os/hal/templates/hal_lld.c b/os/hal/templates/hal_lld.c index 76244ebf4..c903069f9 100644 --- a/os/hal/templates/hal_lld.c +++ b/os/hal/templates/hal_lld.c @@ -19,8 +19,8 @@ */ /** - * @file templates/hal_lld.c - * @brief HAL Driver subsystem low level driver source template. + * @file STM32F30x/hal_lld.c + * @brief STM32F30x HAL subsystem low level driver source. * * @addtogroup HAL * @{ @@ -45,6 +45,49 @@ /* Driver local functions. */ /*===========================================================================*/ +/** + * @brief Initializes the backup domain. + * @note WARNING! Changing clock source impossible without resetting + * of the whole BKP domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Backup domain access enabled and left open.*/ + PWR->CR |= PWR_CR_DBP; + + /* Reset BKP domain if different clock source selected.*/ + if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL){ + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + } + + /* If enabled then the LSE is started.*/ +#if STM32_LSE_ENABLED +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR = STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR = STM32_LSEDRV | RCC_BDCR_LSEON; +#endif + while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; /* Waits until LSE is stable. */ +#endif + +#if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { + /* Selects clock source.*/ + RCC->BDCR |= STM32_RTCSEL; + + /* RTC clock enabled.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ +} + /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ @@ -60,6 +103,111 @@ */ void hal_lld_init(void) { + /* Reset of all peripherals.*/ + rccResetAPB1(0xFFFFFFFF); + rccResetAPB2(0xFFFFFFFF); + + /* SysTick initialization using the system clock.*/ + SysTick->LOAD = STM32_HCLK / CH_FREQUENCY - 1; + SysTick->VAL = 0; + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_ENABLE_Msk | + SysTick_CTRL_TICKINT_Msk; + + /* DWT cycle counter enable.*/ + SCS_DEMCR |= SCS_DEMCR_TRCENA; + DWT_CTRL |= DWT_CTRL_CYCCNTENA; + + /* PWR clock enabled.*/ + rccEnablePWRInterface(FALSE); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + +#if defined(STM32_DMA_REQUIRED) + dmaInit(); +#endif + + /* Programmable voltage detector enable.*/ +#if STM32_PVD_ENABLE + PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); +#endif /* STM32_PVD_ENABLE */ + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, TRUE); + + /* USB IRQ relocated to not conflict with CAN.*/ + SYSCFG->CFGR1 |= SYSCFG_CFGR1_USB_IT_RMP; +} + +/** + * @brief STM32 clocks and PLL initialization. + * @note All the involved constants come from the file @p board.h. + * @note This function should be invoked just after the system reset. + * + * @special + */ +void stm32_clock_init(void) { + +#if !STM32_NO_INIT + /* HSI setup, it enforces the reset situation in order to handle possible + problems with JTAG probes and re-initializations.*/ + RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ + while (!(RCC->CR & RCC_CR_HSIRDY)) + ; /* Wait until HSI is stable. */ + RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ + RCC->CFGR = 0; /* CFGR reset value. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) + ; /* Waits until HSI is selected. */ + +#if STM32_HSE_ENABLED + /* HSE activation.*/ +#if defined(STM32_HSE_BYPASS) + /* HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; +#else + /* No HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON; +#endif + while (!(RCC->CR & RCC_CR_HSERDY)) + ; /* Waits until HSE is stable. */ +#endif + +#if STM32_LSI_ENABLED + /* LSI activation.*/ + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Waits until LSI is stable. */ +#endif + + /* Clock settings.*/ + RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL | + STM32_PLLSRC | STM32_PPRE1 | STM32_PPRE2 | + STM32_HPRE; + RCC->CFGR2 = STM32_ADC34PRES | STM32_ADC12PRES | STM32_PREDIV; + RCC->CFGR3 = STM32_UART5SW | STM32_UART4SW | STM32_USART3SW | + STM32_USART2SW | STM32_TIM8SW | STM32_TIM1SW | + STM32_I2C2SW | STM32_I2C1SW | STM32_USART1SW; + +#if STM32_ACTIVATE_PLL + /* PLL activation.*/ + RCC->CR |= RCC_CR_PLLON; + while (!(RCC->CR & RCC_CR_PLLRDY)) + ; /* Waits until PLL is stable. */ +#endif + + /* Flash setup and final clock selection. */ + FLASH->ACR = STM32_FLASHBITS; + + /* Switching to the configured clock source if it is different from HSI.*/ +#if (STM32_SW != STM32_SW_HSI) + /* Switches clock source.*/ + RCC->CFGR |= STM32_SW; + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; /* Waits selection complete. */ +#endif +#endif /* !STM32_NO_INIT */ } /** @} */ diff --git a/os/hal/templates/hal_lld.h b/os/hal/templates/hal_lld.h index 957d40099..59f64b869 100644 --- a/os/hal/templates/hal_lld.h +++ b/os/hal/templates/hal_lld.h @@ -36,12 +36,14 @@ /** * @brief Defines the support for realtime counters in the HAL. */ -#define HAL_IMPLEMENTS_COUNTERS TRUE +#define HAL_IMPLEMENTS_COUNTERS TRUE /** - * @brief Platform name. + * @name Platform identification + * @{ */ -#define PLATFORM_NAME "" +#define PLATFORM_NAME "" +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ @@ -50,6 +52,7 @@ /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ + /* * Configuration-related checks. */ @@ -75,6 +78,29 @@ typedef uint32_t halrtcnt_t; /* Driver macros. */ /*===========================================================================*/ +/** + * @brief Returns the current value of the system free running counter. + * @note This service is implemented by returning the content of the + * DWT_CYCCNT register. + * + * @return The value of the system free running counter of + * type halrtcnt_t. + * + * @notapi + */ +#define hal_lld_get_counter_value() 0 + +/** + * @brief Realtime counter frequency. + * @note The DWT_CYCCNT register is incremented directly by the system + * clock so this function returns STM32_HCLK. + * + * @return The realtime counter frequency of type halclock_t. + * + * @notapi + */ +#define hal_lld_get_counter_frequency() 0 + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ diff --git a/os/hal/templates/usb_lld.c b/os/hal/templates/usb_lld.c index 75fc19783..7c6a25060 100644 --- a/os/hal/templates/usb_lld.c +++ b/os/hal/templates/usb_lld.c @@ -39,6 +39,15 @@ /* Driver exported variables. */ /*===========================================================================*/ +/** @brief OTG_FS driver identifier.*/ +#if PLATFORM_USB_USE_USB1 || defined(__DOXYGEN__) +USBDriver USBD1; +#endif + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + /** * @brief EP0 state. * @note It is an union because IN and OUT endpoints are never used at the @@ -55,17 +64,25 @@ static union { USBOutEndpointState out; } ep0_state; +/** + * @brief Buffer for the EP0 setup packets. + */ +static uint8_t ep0setup_buffer[8]; + /** * @brief EP0 initialization structure. */ static const USBEndpointConfig ep0config = { - USB_EP_MODE_TYPE_CTRL | USB_EP_MODE_TRANSACTION, + USB_EP_MODE_TYPE_CTRL, + _usb_ep0setup, _usb_ep0in, _usb_ep0out, 0x40, 0x40, &ep0_state.in, - &ep0_state.out + &ep0_state.out, + 1, + ep0setup_buffer }; /*===========================================================================*/ @@ -77,7 +94,7 @@ static const USBEndpointConfig ep0config = { /*===========================================================================*/ /*===========================================================================*/ -/* Driver interrupt handlers. */ +/* Driver interrupt handlers and threads. */ /*===========================================================================*/ /*===========================================================================*/ @@ -91,6 +108,10 @@ static const USBEndpointConfig ep0config = { */ void usb_lld_init(void) { + /* Driver initialization.*/ +#if PLATFORM_USB_USE_USB1 + usbObjectInit(&USBD1); +#endif } /** @@ -101,14 +122,16 @@ void usb_lld_init(void) { * @notapi */ void usb_lld_start(USBDriver *usbp) { + stm32_otg_t *otgp = usbp->otg; if (usbp->state == USB_STOP) { /* Clock activation.*/ +#if STM32_USB_USE_OTG1 + if (&USBD1 == usbp) { /* Reset procedure enforced on driver start.*/ _usb_reset(usbp); } - /* Configuration.*/ } /** @@ -121,7 +144,7 @@ void usb_lld_start(USBDriver *usbp) { void usb_lld_stop(USBDriver *usbp) { /* If in ready state then disables the USB clock.*/ - if (usbp->state == USB_STOP) { + if (usbp->state != USB_STOP) { } } @@ -227,43 +250,35 @@ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) { } /** - * @brief Reads a packet from the dedicated packet buffer. - * @pre In order to use this function he endpoint must have been - * initialized in packet mode. - * @post The endpoint is ready to accept another packet. + * @brief Prepares for a receive operation. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number - * @param[out] buf buffer where to copy the packet data - * @param[in] n maximum number of bytes to copy. This value must - * not exceed the maximum packet size for this endpoint. - * @return The received packet size regardless the specified - * @p n parameter. - * @retval 0 Zero size packet received. * * @notapi */ -size_t usb_lld_read_packet(USBDriver *usbp, usbep_t ep, - uint8_t *buf, size_t n) { +void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep) { + uint32_t pcnt; + USBOutEndpointState *osp = usbp->epc[ep]->out_state; + + /* Transfer initialization.*/ + pcnt = (osp->rxsize + usbp->epc[ep]->out_maxsize - 1) / + usbp->epc[ep]->out_maxsize; + usbp->otg->oe[ep].DOEPTSIZ = DOEPTSIZ_STUPCNT(3) | DOEPTSIZ_PKTCNT(pcnt) | + DOEPTSIZ_XFRSIZ(usbp->epc[ep]->out_maxsize); } /** - * @brief Writes a packet to the dedicated packet buffer. - * @pre In order to use this function he endpoint must have been - * initialized in packet mode. - * @post The endpoint is ready to transmit the packet. + * @brief Prepares for a transmit operation. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number - * @param[in] buf buffer where to fetch the packet data - * @param[in] n maximum number of bytes to copy. This value must - * not exceed the maximum packet size for this endpoint. * * @notapi */ -void usb_lld_write_packet(USBDriver *usbp, usbep_t ep, - const uint8_t *buf, size_t n) { +void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep) { + USBInEndpointState *isp = usbp->epc[ep]->in_state; } @@ -272,13 +287,10 @@ void usb_lld_write_packet(USBDriver *usbp, usbep_t ep, * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number - * @param[out] buf buffer where to copy the endpoint data - * @param[in] n maximum number of bytes to copy in the buffer * * @notapi */ -void usb_lld_start_out(USBDriver *usbp, usbep_t ep, - uint8_t *buf, size_t n) { +void usb_lld_start_out(USBDriver *usbp, usbep_t ep) { } @@ -287,13 +299,10 @@ void usb_lld_start_out(USBDriver *usbp, usbep_t ep, * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number - * @param[in] buf buffer where to fetch the endpoint data - * @param[in] n maximum number of bytes to copy * * @notapi */ -void usb_lld_start_in(USBDriver *usbp, usbep_t ep, - const uint8_t *buf, size_t n) { +void usb_lld_start_in(USBDriver *usbp, usbep_t ep) { } diff --git a/os/hal/templates/usb_lld.h b/os/hal/templates/usb_lld.h index df469aadd..479e6ba40 100644 --- a/os/hal/templates/usb_lld.h +++ b/os/hal/templates/usb_lld.h @@ -31,8 +31,6 @@ #if HAL_USE_USB || defined(__DOXYGEN__) -#include "stm32_usb.h" - /*===========================================================================*/ /* Driver constants. */ /*===========================================================================*/ @@ -43,14 +41,22 @@ #define USB_MAX_ENDPOINTS 4 /** - * @brief This device requires the address change after the status packet. + * @brief The address can be changed immediately upon packet reception. */ -#define USB_SET_ADDRESS_MODE USB_LATE_SET_ADDRESS +#define USB_SET_ADDRESS_MODE USB_EARLY_SET_ADDRESS /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @brief OTG1 driver enable switch. + * @details If set to @p TRUE the support for OTG_FS is included. + * @note The default is @p TRUE. + */ +#if !defined(PLATFORM_USB_USE_USB1) || defined(__DOXYGEN__) +#define PLATFORM_USB_USE_USB1 TRUE +#endif /*===========================================================================*/ /* Derived constants and error checks. */ @@ -64,14 +70,64 @@ * @brief Type of an IN endpoint state structure. */ typedef struct { - + /** + * @brief Buffer mode, queue or linear. + */ + bool_t txqueued; + /** + * @brief Requested transmit transfer size. + */ + size_t txsize; + /** + * @brief Transmitted bytes so far. + */ + size_t txcnt; + union { + struct { + /** + * @brief Pointer to the transmission linear buffer. + */ + const uint8_t *txbuf; + } linear; + struct { + /** + * @brief Pointer to the output queue. + */ + OutputQueue *txqueue; + } queue; + } mode; } USBInEndpointState; /** * @brief Type of an OUT endpoint state structure. */ typedef struct { - + /** + * @brief Buffer mode, queue or linear. + */ + bool_t rxqueued; + /** + * @brief Requested receive transfer size. + */ + size_t rxsize; + /** + * @brief Received bytes so far. + */ + size_t rxcnt; + union { + struct { + /** + * @brief Pointer to the receive linear buffer. + */ + uint8_t *rxbuf; + } linear; + struct { + /** + * @brief Pointer to the input queue. + */ + InputQueue *rxqueue; + } queue; + } mode; } USBOutEndpointState; /** @@ -83,6 +139,17 @@ typedef struct { * @brief Type and mode of the endpoint. */ uint32_t ep_mode; + /** + * @brief Setup packet notification callback. + * @details This callback is invoked when a setup packet has been + * received. + * @post The application must immediately call @p usbReadPacket() in + * order to access the received packet. + * @note This field is only valid for @p USB_EP_MODE_TYPE_CTRL + * endpoints, it should be set to @p NULL for other endpoint + * types. + */ + usbepcallback_t setup_cb; /** * @brief IN endpoint notification callback. * @details This field must be set to @p NULL if the IN endpoint is not @@ -109,16 +176,12 @@ typedef struct { uint16_t out_maxsize; /** * @brief @p USBEndpointState associated to the IN endpoint. - * @details This structure maintains the state of the IN endpoint when - * the endpoint is not in packet mode. Endpoints configured in - * packet mode must set this field to @p NULL. + * @details This structure maintains the state of the IN endpoint. */ USBInEndpointState *in_state; /** * @brief @p USBEndpointState associated to the OUT endpoint. - * @details This structure maintains the state of the OUT endpoint when - * the endpoint is not in packet mode. Endpoints configured in - * packet mode must set this field to @p NULL. + * @details This structure maintains the state of the OUT endpoint. */ USBOutEndpointState *out_state; /* End of the mandatory fields.*/ @@ -222,25 +285,6 @@ struct USBDriver { /* Driver macros. */ /*===========================================================================*/ -/** - * @brief Fetches a 16 bits word value from an USB message. - * - * @param[in] p pointer to the 16 bits word - * - * @notapi - */ -#define usb_lld_fetch_word(p) (*(uint16_t *)(p)) - -/** - * @brief Returns the current frame number. - * - * @param[in] usbp pointer to the @p USBDriver object - * @return The current frame number. - * - * @notapi - */ -#define usb_lld_get_frame_number(usbp) - /** * @brief Returns the exact size of a receive transaction. * @details The received size can be different from the size specified in @@ -255,25 +299,31 @@ struct USBDriver { * * @notapi */ -#define usb_lld_get_transaction_size(usbp, ep) +#define usb_lld_get_transaction_size(usbp, ep) \ + ((usbp)->epc[ep]->out_state->rxcnt) /** - * @brief Returns the exact size of a received packet. - * @pre The OUT endpoint must have been configured in packet mode - * in order to use this function. + * @brief Connects the USB device. * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @return Received data size. - * - * @notapi + * @api */ -#define usb_lld_get_packet_size(usbp, ep) +#define usb_lld_connect_bus(usbp) + +/** + * @brief Disconnect the USB device. + * + * @api + */ +#define usb_lld_disconnect_bus(usbp) /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ +#if PLATFORM_USB_USE_USB1 && !defined(__DOXYGEN__) +extern USBDriver USBD1; +#endif + #ifdef __cplusplus extern "C" { #endif @@ -287,16 +337,12 @@ extern "C" { usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep); usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep); void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf); - size_t usb_lld_read_packet(USBDriver *usbp, usbep_t ep, - uint8_t *buf, size_t n); - void usb_lld_write_packet(USBDriver *usbp, usbep_t ep, - const uint8_t *buf, size_t n); - void usb_lld_start_out(USBDriver *usbp, usbep_t ep, - uint8_t *buf, size_t n); - void usb_lld_start_in(USBDriver *usbp, usbep_t ep, - const uint8_t *buf, size_t n); - void usb_lld_stall_in(USBDriver *usbp, usbep_t ep); + void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep); + void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep); + void usb_lld_start_out(USBDriver *usbp, usbep_t ep); + void usb_lld_start_in(USBDriver *usbp, usbep_t ep); void usb_lld_stall_out(USBDriver *usbp, usbep_t ep); + void usb_lld_stall_in(USBDriver *usbp, usbep_t ep); void usb_lld_clear_out(USBDriver *usbp, usbep_t ep); void usb_lld_clear_in(USBDriver *usbp, usbep_t ep); #ifdef __cplusplus