aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2013-02-24 15:35:53 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2013-02-24 15:35:53 +0000
commit9708a3c30ff4ce1d95b3333b6be4375138a89be5 (patch)
treea8b3422730ceaa58c1b4edf54b3a1f66d505310d /os/hal
parent9a1b57db6d7da73e6a1ae070de1835caaf276341 (diff)
downloadChibiOS-9708a3c30ff4ce1d95b3333b6be4375138a89be5.tar.gz
ChibiOS-9708a3c30ff4ce1d95b3333b6be4375138a89be5.tar.bz2
ChibiOS-9708a3c30ff4ce1d95b3333b6be4375138a89be5.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5313 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/templates/adc_lld.c29
-rw-r--r--os/hal/templates/adc_lld.h73
-rw-r--r--os/hal/templates/ext_lld.c28
-rw-r--r--os/hal/templates/ext_lld.h15
-rw-r--r--os/hal/templates/hal_lld.c152
-rw-r--r--os/hal/templates/hal_lld.h32
-rw-r--r--os/hal/templates/usb_lld.c77
-rw-r--r--os/hal/templates/usb_lld.h144
8 files changed, 430 insertions, 120 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. */
/*===========================================================================*/
@@ -62,6 +72,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.
*/
typedef struct ADCDriver ADCDriver;
@@ -77,6 +97,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
* operation.
@@ -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
@@ -56,16 +65,24 @@ static union {
} 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;
/**
@@ -84,6 +140,17 @@ typedef struct {
*/
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
* used.
@@ -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.*/
@@ -223,25 +286,6 @@ struct USBDriver {
/*===========================================================================*/
/**
- * @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
* @p usbStartReceiveI() because the last packet could have a size
@@ -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.
+ * @api
+ */
+#define usb_lld_connect_bus(usbp)
+
+/**
+ * @brief Disconnect the USB device.
*
- * @notapi
+ * @api
*/
-#define usb_lld_get_packet_size(usbp, ep)
+#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