aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/ports/STM32/LLD
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal/ports/STM32/LLD')
-rw-r--r--os/hal/ports/STM32/LLD/COMPv1/hal_comp_lld.c520
-rw-r--r--os/hal/ports/STM32/LLD/COMPv1/hal_comp_lld.h482
-rwxr-xr-x[-rw-r--r--]os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.c18
-rw-r--r--os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.h8
-rw-r--r--os/hal/ports/STM32/LLD/DMA2Dv1/hal_stm32_dma2d.c3
-rw-r--r--os/hal/ports/STM32/LLD/DMA2Dv1/hal_stm32_dma2d.h8
-rw-r--r--os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.c16
-rw-r--r--os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.h56
-rw-r--r--os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.c8
-rw-r--r--os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.h14
-rw-r--r--os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.c15
-rw-r--r--os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.h8
-rw-r--r--os/hal/ports/STM32/LLD/FSMCv1/hal_nand_lld.c209
-rw-r--r--os/hal/ports/STM32/LLD/FSMCv1/hal_nand_lld.h62
-rw-r--r--os/hal/ports/STM32/LLD/LTDCv1/hal_stm32_ltdc.c3
-rw-r--r--os/hal/ports/STM32/LLD/LTDCv1/hal_stm32_ltdc.h8
-rw-r--r--os/hal/ports/STM32/LLD/TIMv1/hal_eicu_lld.c24
-rw-r--r--os/hal/ports/STM32/LLD/TIMv1/hal_eicu_lld.h6
-rw-r--r--os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c30
-rw-r--r--os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.h119
-rw-r--r--os/hal/ports/STM32/LLD/TIMv1/hal_timcap_lld.c17
-rw-r--r--os/hal/ports/STM32/LLD/TIMv1/hal_timcap_lld.h5
-rw-r--r--os/hal/ports/STM32/LLD/USBHv1/hal_stm32_otg.h929
-rw-r--r--os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c396
-rw-r--r--os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.h34
25 files changed, 1691 insertions, 1307 deletions
diff --git a/os/hal/ports/STM32/LLD/COMPv1/hal_comp_lld.c b/os/hal/ports/STM32/LLD/COMPv1/hal_comp_lld.c
new file mode 100644
index 0000000..62d9f14
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/COMPv1/hal_comp_lld.c
@@ -0,0 +1,520 @@
+/*
+ ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
+ Copyright (C) 2017 Fabien Poussin (fabien.poussin (at) google's mail)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+
+/**
+ * @file STM32/hal_comp_lld.c
+ * @brief STM32 Comp subsystem low level driver header.
+ *
+ * @addtogroup COMP
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_COMP || defined(__DOXYGEN__)
+
+#include "hal_comp.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief COMPD1 driver identifier.
+ * @note The driver COMPD1 allocates the comparator COMP1 when enabled.
+ */
+#if STM32_COMP_USE_COMP1 || defined(__DOXYGEN__)
+COMPDriver COMPD1;
+#endif
+
+/**
+ * @brief COMPD2 driver identifier.
+ * @note The driver COMPD2 allocates the comparator COMP2 when enabled.
+ */
+#if STM32_COMP_USE_COMP2 || defined(__DOXYGEN__)
+COMPDriver COMPD2;
+#endif
+
+/**
+ * @brief COMPD3 driver identifier.
+ * @note The driver COMPD3 allocates the comparator COMP3 when enabled.
+ */
+#if STM32_COMP_USE_COMP3 || defined(__DOXYGEN__)
+COMPDriver COMPD3;
+#endif
+
+/**
+ * @brief COMPD4 driver identifier.
+ * @note The driver COMPD4 allocates the comparator COMP4 when enabled.
+ */
+#if STM32_COMP_USE_COMP4 || defined(__DOXYGEN__)
+COMPDriver COMPD4;
+#endif
+
+/**
+ * @brief COMPD5 driver identifier.
+ * @note The driver COMPD5 allocates the comparator COMP5 when enabled.
+ */
+#if STM32_COMP_USE_COMP5 || defined(__DOXYGEN__)
+COMPDriver COMPD5;
+#endif
+
+/**
+ * @brief COMPD6 driver identifier.
+ * @note The driver COMPD6 allocates the comparator COMP6 when enabled.
+ */
+#if STM32_COMP_USE_COMP6 || defined(__DOXYGEN__)
+COMPDriver COMPD6;
+#endif
+
+/**
+ * @brief COMPD7 driver identifier.
+ * @note The driver COMPD7 allocates the comparator COMP7 when enabled.
+ */
+#if STM32_COMP_USE_COMP7 || defined(__DOXYGEN__)
+COMPDriver COMPD7;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level COMP driver initialization.
+ *
+ * @notapi
+ */
+void comp_lld_init(void) {
+
+#if STM32_COMP_USE_COMP1
+ /* Driver initialization.*/
+ compObjectInit(&COMPD1);
+ COMPD1.reg = COMP;
+ COMPD1.reg->CSR = 0;
+#if STM32_COMP_USE_INTERRUPTS
+ nvicEnableVector(COMP1_2_3_IRQn, STM32_COMP_1_2_3_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_COMP_USE_COMP2
+ /* Driver initialization.*/
+ compObjectInit(&COMPD2);
+ COMPD2.reg = COMP2;
+ COMPD2.reg->CSR = 0;
+#if STM32_COMP_USE_INTERRUPTS
+ nvicEnableVector(COMP1_2_3_IRQn, STM32_COMP_1_2_3_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_COMP_USE_COMP3
+ /* Driver initialization.*/
+ compObjectInit(&COMPD3);
+ COMPD3.reg = COMP3;
+ COMPD3.reg->CSR = 0;
+#if STM32_COMP_USE_INTERRUPTS
+ nvicEnableVector(COMP1_2_3_IRQn, STM32_COMP_1_2_3_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_COMP_USE_COMP4
+ /* Driver initialization.*/
+ compObjectInit(&COMPD4);
+ COMPD4.reg = COMP4;
+ COMPD4.reg->CSR = 0;
+#if STM32_COMP_USE_INTERRUPTS
+ nvicEnableVector(COMP4_5_6_IRQn, STM32_COMP_1_2_3_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_COMP_USE_COMP5
+ /* Driver initialization.*/
+ compObjectInit(&COMPD5);
+ COMPD5.reg = COMP5;
+ COMPD5.reg->CSR = 0;
+#if STM32_COMP_USE_INTERRUPTS
+ nvicEnableVector(COMP4_5_6_IRQn, STM32_COMP_1_2_3_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_COMP_USE_COMP6
+ /* Driver initialization.*/
+ compObjectInit(&COMPD6);
+ COMPD6.reg = COMP6;
+ COMPD6.reg->CSR = 0;
+#if STM32_COMP_USE_INTERRUPTS
+ nvicEnableVector(COMP4_5_6_IRQn, STM32_COMP_1_2_3_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_COMP_USE_COMP7
+ /* Driver initialization.*/
+ compObjectInit(&COMPD7);
+ COMPD7.reg = COMP7;
+ COMPD7.reg->CSR = 0;
+#if STM32_COMP_USE_INTERRUPTS
+ nvicEnableVector(COMP7_IRQn, STM32_COMP_7_IRQ_PRIORITY);
+#endif
+#endif
+
+}
+
+/**
+ * @brief COMP1, COMP2, COMP3 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(Vector140) {
+ uint32_t pr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ pr = EXTI->PR;
+ pr &= EXTI->IMR & ((1U << 21) | (1U << 22) | (1U << 29));
+ EXTI->PR = pr;
+#if STM32_COMP_USE_COMP1
+ if (pr & (1U << 21) && COMPD1.config->cb != NULL)
+ COMPD1.config->cb(&COMPD1);
+#endif
+#if STM32_COMP_USE_COMP2
+ if (pr & (1U << 22) && COMPD2.config->cb != NULL)
+ COMPD2.config->cb(&COMPD2);
+#endif
+#if STM32_COMP_USE_COMP3
+ if (pr & (1U << 29) && COMPD3.config->cb != NULL)
+ COMPD3.config->cb(&COMPD3);
+#endif
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief COMP4, COMP5, COMP6 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(Vector144) {
+ uint32_t pr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ pr = EXTI->PR;
+ pr &= EXTI->IMR & ((1U << 30) | (1U << 31));
+ EXTI->PR = pr;
+#if STM32_COMP_USE_COMP4
+ if (pr & (1U << 30) && COMPD4.config->cb != NULL)
+ COMPD4.config->cb(&COMPD4);
+#endif
+#if STM32_COMP_USE_COMP5
+ if (pr & (1U << 31) && COMPD5.config->cb != NULL)
+ COMPD5.config->cb(&COMPD5);
+#endif
+
+#if STM32_COMP_USE_COMP6
+ pr = EXTI->PR2 & EXTI->IMR2 & (1U << 0);
+ EXTI->PR2 = pr;
+ if (pr & (1U << 0) && COMPD6.config->cb != NULL)
+ COMPD6.config->cb(&COMPD6);
+#endif
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief COMP7 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(Vector148) {
+ uint32_t pr2;
+
+ OSAL_IRQ_PROLOGUE();
+
+ pr2 = EXTI->PR2;
+ pr2 = EXTI->IMR & (1U << 1);
+ EXTI->PR2 = pr2;
+#if STM32_COMP_USE_COMP7
+ if (pr2 & (1U << 1) && COMPD7.config->cb != NULL)
+ COMPD7.config->cb(&COMPD7);
+#endif
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief Configures and activates an EXT channel (used by comp)
+ *
+ * @param[in] compp pointer to the @p COMPDriver object
+ * @param[in] channel EXT channel
+ *
+ * @notapi
+ */
+void comp_ext_lld_channel_enable(COMPDriver *compp, uint32_t channel) {
+ uint32_t cmask = (1 << (channel & 0x1F));
+
+ /* Don't touch other channels */
+ if (channel < 21 || channel > 33) {
+ return;
+ }
+
+#if STM32_EXTI_NUM_LINES > 32
+ if (channel < 32) {
+#endif
+ /* Masked out lines must not be touched by this driver.*/
+ if ((cmask & STM32_EXTI_IMR_MASK) != 0U) {
+ return;
+ }
+
+ /* Programming edge registers.*/
+ if (compp->config->irq_mode == COMP_IRQ_RISING || compp->config->irq_mode == COMP_IRQ_BOTH)
+ EXTI->RTSR |= cmask;
+ else
+ EXTI->RTSR &= ~cmask;
+ if (compp->config->irq_mode == COMP_IRQ_FALLING || compp->config->irq_mode == COMP_IRQ_BOTH)
+ EXTI->FTSR |= cmask;
+ else
+ EXTI->FTSR &= ~cmask;
+
+ /* Programming interrupt and event registers.*/
+ EXTI->IMR |= cmask;
+ EXTI->EMR &= ~cmask;
+
+#if STM32_EXTI_NUM_LINES > 32
+ }
+ else {
+ /* Masked out lines must not be touched by this driver.*/
+ if ((cmask & STM32_EXTI_IMR2_MASK) != 0U) {
+ return;
+ }
+
+ /* Programming edge registers.*/
+ if (compp->config->irq_mode == COMP_IRQ_RISING || compp->config->irq_mode == COMP_IRQ_BOTH)
+ EXTI->RTSR2 |= cmask;
+ else
+ EXTI->RTSR2 &= ~cmask;
+ if (compp->config->irq_mode == COMP_IRQ_FALLING || compp->config->irq_mode == COMP_IRQ_BOTH)
+ EXTI->FTSR2 |= cmask;
+ else
+ EXTI->FTSR2 &= ~cmask;
+
+ /* Programming interrupt and event registers.*/
+ EXTI->IMR2 |= cmask;
+ EXTI->EMR2 &= ~cmask;
+ }
+#endif
+}
+
+/**
+ * @brief Deactivate an EXT channel (used by comp)
+ *
+ * @param[in] compp pointer to the @p COMPDriver object
+ * @param[in] channel EXT channel
+ *
+ * @notapi
+ */
+void comp_ext_lld_channel_disable(COMPDriver *compp, uint32_t channel) {
+
+ (void) compp;
+ uint32_t cmask = (1 << (channel & 0x1F));
+
+#if STM32_EXTI_NUM_LINES > 32
+ if (channel < 32) {
+#endif
+ EXTI->IMR &= ~cmask;
+ EXTI->EMR &= ~cmask;
+ EXTI->RTSR &= ~cmask;
+ EXTI->FTSR &= ~cmask;
+ EXTI->PR = cmask;
+#if STM32_EXTI_NUM_LINES > 32
+ }
+ else {
+ EXTI->IMR2 &= ~cmask;
+ EXTI->EMR2 &= ~cmask;
+ EXTI->RTSR2 &= ~cmask;
+ EXTI->FTSR2 &= ~cmask;
+ EXTI->PR2 = cmask;
+ }
+#endif
+}
+
+/**
+ * @brief Configures and activates the COMP peripheral.
+ *
+ * @param[in] compp pointer to the @p COMPDriver object
+ *
+ * @notapi
+ */
+void comp_lld_start(COMPDriver *compp) {
+
+ // Apply CSR Execpt the enable bit.
+ compp->reg->CSR = compp->config->csr & ~COMP_CSR_COMPxEN;
+
+ // Inverted output
+ if (compp->config->output_mode == COMP_OUTPUT_INVERTED)
+ compp->reg->CSR |= COMP_CSR_COMPxPOL;
+
+#if STM32_COMP_USE_INTERRUPTS
+#if STM32_COMP_USE_COMP1
+ if (compp == &COMPD1) {
+ comp_ext_lld_channel_enable(compp, 21);
+ }
+#endif
+
+#if STM32_COMP_USE_COMP2
+ if (compp == &COMPD2) {
+ comp_ext_lld_channel_enable(compp, 22);
+ }
+#endif
+
+#if STM32_COMP_USE_COMP3
+ if (compp == &COMPD3) {
+ comp_ext_lld_channel_enable(compp, 29);
+ }
+#endif
+
+#if STM32_COMP_USE_COMP4
+ if (compp == &COMPD4) {
+ comp_ext_lld_channel_enable(compp, 30);
+ }
+#endif
+
+#if STM32_COMP_USE_COMP5
+ if (compp == &COMPD5) {
+ comp_ext_lld_channel_enable(compp, 31);
+ }
+#endif
+
+#if STM32_COMP_USE_COMP6
+ if (compp == &COMPD6) {
+ comp_ext_lld_channel_enable(compp, 32);
+ }
+#endif
+
+#if STM32_COMP_USE_COMP7
+ if (compp == &COMPD7) {
+ comp_ext_lld_channel_enable(compp, 33);
+ }
+#endif
+#endif
+
+}
+
+/**
+ * @brief Deactivates the comp peripheral.
+ *
+ * @param[in] compp pointer to the @p COMPDriver object
+ *
+ * @notapi
+ */
+void comp_lld_stop(COMPDriver *compp) {
+
+ if (compp->state == COMP_READY) {
+
+ compp->reg->CSR = 0;
+ }
+
+#if STM32_COMP_USE_INTERRUPTS
+#if STM32_COMP_USE_COMP1
+ if (compp == &COMPD1) {
+ comp_ext_lld_channel_disable(compp, 21);
+ }
+#endif
+
+#if STM32_COMP_USE_COMP2
+ if (compp == &COMPD2) {
+ comp_ext_lld_channel_disable(compp, 22);
+ }
+#endif
+
+#if STM32_COMP_USE_COMP3
+ if (compp == &COMPD3) {
+ comp_ext_lld_channel_disable(compp, 29);
+ }
+#endif
+
+#if STM32_COMP_USE_COMP4
+ if (compp == &COMPD4) {
+ comp_ext_lld_channel_disable(compp, 30);
+ }
+#endif
+
+#if STM32_COMP_USE_COMP5
+ if (compp == &COMPD5) {
+ comp_ext_lld_channel_disable(compp, 31);
+ }
+#endif
+
+#if STM32_COMP_USE_COMP6
+ if (compp == &COMPD6) {
+ comp_ext_lld_channel_disable(compp, 32);
+ }
+#endif
+
+#if STM32_COMP_USE_COMP7
+ if (compp == &COMPD7) {
+ comp_ext_lld_channel_disable(compp, 33);
+ }
+#endif
+#endif
+
+}
+
+/**
+ * @brief Enables the output.
+ *
+ * @param[in] compp pointer to the @p COMPDriver object
+ *
+ * @notapi
+ */
+void comp_lld_enable(COMPDriver *compp) {
+
+ compp->reg->CSR |= COMP_CSR_COMPxEN; /* Enable */
+}
+
+/**
+ * @brief Disables the output.
+ *
+ * @param[in] compp pointer to the @p COMPDriver object
+ *
+ * @notapi
+ */
+void comp_lld_disable(COMPDriver *compp) {
+
+ compp->reg->CSR &= ~COMP_CSR_COMPxEN; /* Disable */
+}
+
+#endif /* HAL_USE_COMP */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/COMPv1/hal_comp_lld.h b/os/hal/ports/STM32/LLD/COMPv1/hal_comp_lld.h
new file mode 100644
index 0000000..bb40327
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/COMPv1/hal_comp_lld.h
@@ -0,0 +1,482 @@
+/*
+ ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
+ Copyright (C) 2017 Fabien Poussin (fabien.poussin (at) google's mail)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file STM32/comp_lld.h
+ * @brief STM32 Comparator subsystem low level driver header.
+ *
+ * @addtogroup COMP
+ * @{
+ */
+
+#ifndef HAL_COMP_LLD_H_
+#define HAL_COMP_LLD_H_
+
+#include "hal.h"
+
+#if HAL_USE_COMP || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+
+#define STM32_COMP_InvertingInput_1_4VREFINT ((uint32_t)0x00000000) /*!< 1/4 VREFINT connected to comparator inverting input */
+#define STM32_COMP_InvertingInput_1_2VREFINT COMP_CSR_COMPxINSEL_0 /*!< 1/2 VREFINT connected to comparator inverting input */
+#define STM32_COMP_InvertingInput_3_4VREFINT COMP_CSR_COMPxINSEL_1 /*!< 3/4 VREFINT connected to comparator inverting input */
+#define STM32_COMP_InvertingInput_VREFINT ((uint32_t)0x00000030) /*!< VREFINT connected to comparator inverting input */
+#define STM32_COMP_InvertingInput_DAC1OUT1 COMP_CSR_COMPxINSEL_2 /*!< DAC1_OUT1 (PA4) connected to comparator inverting input */
+#define STM32_COMP_InvertingInput_DAC1OUT2 ((uint32_t)0x00000050) /*!< DAC1_OUT2 (PA5) connected to comparator inverting input */
+
+#define STM32_COMP_InvertingInput_IO1 ((uint32_t)0x00000060) /*!< I/O1 (PA0 for COMP1, PA2 for COMP2, PD15 for COMP3,
+ PE8 for COMP4, PD13 for COMP5, PD10 for COMP6,
+ PC0 for COMP7) connected to comparator inverting input */
+
+#define STM32_COMP_InvertingInput_IO2 COMP_CSR_COMPxINSEL /*!< I/O2 (PB12 for COMP3, PB2 for COMP4, PB10 for COMP5,
+ PB15 for COMP6) connected to comparator inverting input.
+ It is valid only for STM32F303xC devices */
+
+#define STM32_COMP_InvertingInput_DAC2OUT1 COMP_CSR_COMPxINSEL_3 /*!< DAC2_OUT1 (PA6) connected to comparator inverting input */
+
+
+#define STM32_COMP_NonInvertingInput_IO1 ((uint32_t)0x00000000) /*!< I/O1 (PA1 for COMP1, PA7 for COMP2, PB14 for COMP3,
+ PB0 for COMP4, PD12 for COMP5, PD11 for COMP6,
+ PA0 for COMP7) connected to comparator non inverting input */
+
+#define STM32_COMP_NonInvertingInput_IO2 COMP_CSR_COMPxNONINSEL /*!< I/O2 (PA3 for COMP2, PD14 for COMP3, PE7 for COMP4, PB13 for COMP5,
+ PB11 for COMP6, PC1 for COMP7) connected to comparator non inverting input */
+
+
+#define STM32_COMP_Output_None ((uint32_t)0x00000000) /*!< COMP output isn't connected to other peripherals */
+
+/* Output Redirection common for all comparators COMP1...COMP7 */
+#define STM32_COMP_Output_TIM1BKIN COMP_CSR_COMPxOUTSEL_0 /*!< COMP output connected to TIM1 Break Input (BKIN) */
+#define STM32_COMP_Output_TIM1BKIN2 ((uint32_t)0x00000800) /*!< COMP output connected to TIM1 Break Input 2 (BKIN2) */
+#define STM32_COMP_Output_TIM8BKIN ((uint32_t)0x00000C00) /*!< COMP output connected to TIM8 Break Input (BKIN) */
+#define STM32_COMP_Output_TIM8BKIN2 ((uint32_t)0x00001000) /*!< COMP output connected to TIM8 Break Input 2 (BKIN2) */
+#define STM32_COMP_Output_TIM1BKIN2_TIM8BKIN2 ((uint32_t)0x00001400) /*!< COMP output connected to TIM1 Break Input 2 and TIM8 Break Input 2 */
+#define STM32_COMP_Output_TIM20BKIN ((uint32_t)0x00003000) /*!< COMP output connected to TIM20 Break Input (BKIN) */
+#define STM32_COMP_Output_TIM20BKIN2 ((uint32_t)0x00003400) /*!< COMP output connected to TIM20 Break Input 2 (BKIN2) */
+#define STM32_COMP_Output_TIM1BKIN2_TIM8BKIN2_TIM20BKIN2 ((uint32_t)0x00001400) /*!< COMP output connected to TIM1 Break Input 2, TIM8 Break Input 2 and TIM20 Break Input2 */
+
+/* Output Redirection common for COMP1 and COMP2 */
+#define STM32_COMP_Output_TIM1OCREFCLR ((uint32_t)0x00001800) /*!< COMP output connected to TIM1 OCREF Clear */
+#define STM32_COMP_Output_TIM1IC1 ((uint32_t)0x00001C00) /*!< COMP output connected to TIM1 Input Capture 1 */
+#define STM32_COMP_Output_TIM2IC4 ((uint32_t)0x00002000) /*!< COMP output connected to TIM2 Input Capture 4 */
+#define STM32_COMP_Output_TIM2OCREFCLR ((uint32_t)0x00002400) /*!< COMP output connected to TIM2 OCREF Clear */
+#define STM32_COMP_Output_TIM3IC1 ((uint32_t)0x00002800) /*!< COMP output connected to TIM3 Input Capture 1 */
+#define STM32_COMP_Output_TIM3OCREFCLR ((uint32_t)0x00002C00) /*!< COMP output connected to TIM3 OCREF Clear */
+
+/* Output Redirection specific to COMP2 */
+#define STM32_COMP_Output_HRTIM1_FLT6 ((uint32_t)0x00003000) /*!< COMP output connected to HRTIM1 FLT6 */
+#define STM32_COMP_Output_HRTIM1_EE1_2 ((uint32_t)0x00003400) /*!< COMP output connected to HRTIM1 EE1_2*/
+#define STM32_COMP_Output_HRTIM1_EE6_2 ((uint32_t)0x00003800) /*!< COMP output connected to HRTIM1 EE6_2 */
+#define STM32_COMP_Output_TIM20OCREFCLR ((uint32_t)0x00003C00) /*!< COMP output connected to TIM20 OCREF Clear */
+
+/* Output Redirection specific to COMP3 */
+#define STM32_COMP_Output_TIM4IC1 ((uint32_t)0x00001C00) /*!< COMP output connected to TIM4 Input Capture 1 */
+#define STM32_COMP_Output_TIM3IC2 ((uint32_t)0x00002000) /*!< COMP output connected to TIM3 Input Capture 2 */
+#define STM32_COMP_Output_TIM15IC1 ((uint32_t)0x00002800) /*!< COMP output connected to TIM15 Input Capture 1 */
+#define STM32_COMP_Output_TIM15BKIN ((uint32_t)0x00002C00) /*!< COMP output connected to TIM15 Break Input (BKIN) */
+
+/* Output Redirection specific to COMP4 */
+#define STM32_COMP_Output_TIM3IC3 ((uint32_t)0x00001800) /*!< COMP output connected to TIM3 Input Capture 3 */
+#define STM32_COMP_Output_TIM8OCREFCLR ((uint32_t)0x00001C00) /*!< COMP output connected to TIM8 OCREF Clear */
+#define STM32_COMP_Output_TIM15IC2 ((uint32_t)0x00002000) /*!< COMP output connected to TIM15 Input Capture 2 */
+#define STM32_COMP_Output_TIM4IC2 ((uint32_t)0x00002400) /*!< COMP output connected to TIM4 Input Capture 2 */
+#define STM32_COMP_Output_TIM15OCREFCLR ((uint32_t)0x00002800) /*!< COMP output connected to TIM15 OCREF Clear */
+
+#define STM32_COMP_Output_HRTIM1_FLT7 ((uint32_t)0x00003000) /*!< COMP output connected to HRTIM1 FLT7 */
+#define STM32_COMP_Output_HRTIM1_EE2_2 ((uint32_t)0x00003400) /*!< COMP output connected to HRTIM1 EE2_2*/
+#define STM32_COMP_Output_HRTIM1_EE7_2 ((uint32_t)0x00003800) /*!< COMP output connected to HRTIM1 EE7_2 */
+
+/* Output Redirection specific to COMP5 */
+#define STM32_COMP_Output_TIM2IC1 ((uint32_t)0x00001800) /*!< COMP output connected to TIM2 Input Capture 1 */
+#define STM32_COMP_Output_TIM17IC1 ((uint32_t)0x00002000) /*!< COMP output connected to TIM17 Input Capture 1 */
+#define STM32_COMP_Output_TIM4IC3 ((uint32_t)0x00002400) /*!< COMP output connected to TIM4 Input Capture 3 */
+#define STM32_COMP_Output_TIM16BKIN ((uint32_t)0x00002800) /*!< COMP output connected to TIM16 Break Input (BKIN) */
+
+/* Output Redirection specific to COMP6 */
+#define STM32_COMP_Output_TIM2IC2 ((uint32_t)0x00001800) /*!< COMP output connected to TIM2 Input Capture 2 */
+#define STM32_COMP_Output_COMP6TIM2OCREFCLR ((uint32_t)0x00002000) /*!< COMP output connected to TIM2 OCREF Clear */
+#define STM32_COMP_Output_TIM16OCREFCLR ((uint32_t)0x00002400) /*!< COMP output connected to TIM16 OCREF Clear */
+#define STM32_COMP_Output_TIM16IC1 ((uint32_t)0x00002800) /*!< COMP output connected to TIM16 Input Capture 1 */
+#define STM32_COMP_Output_TIM4IC4 ((uint32_t)0x00002C00) /*!< COMP output connected to TIM4 Input Capture 4 */
+
+#define STM32_COMP_Output_HRTIM1_FLT8 ((uint32_t)0x00003000) /*!< COMP output connected to HRTIM1 FLT8 */
+#define STM32_COMP_Output_HRTIM1_EE3_2 ((uint32_t)0x00003400) /*!< COMP output connected to HRTIM1 EE3_2*/
+#define STM32_COMP_Output_HRTIM1_EE8_2 ((uint32_t)0x00003800) /*!< COMP output connected to HRTIM1 EE8_2 */
+
+/* Output Redirection specific to COMP7 */
+#define STM32_COMP_Output_TIM2IC3 ((uint32_t)0x00002000) /*!< COMP output connected to TIM2 Input Capture 3 */
+#define STM32_COMP_Output_TIM1IC2 ((uint32_t)0x00002400) /*!< COMP output connected to TIM1 Input Capture 2 */
+#define STM32_COMP_Output_TIM17OCREFCLR ((uint32_t)0x00002800) /*!< COMP output connected to TIM16 OCREF Clear */
+#define STM32_COMP_Output_TIM17BKIN ((uint32_t)0x00002C00) /*!< COMP output connected to TIM16 Break Input (BKIN) */
+
+/* No blanking source can be selected for all comparators */
+#define STM32_COMP_BlankingSrce_None ((uint32_t)0x00000000) /*!< No blanking source */
+
+/* Blanking source common for COMP1, COMP2, COMP3 and COMP7 */
+#define STM32_COMP_BlankingSrce_TIM1OC5 COMP_CSR_COMPxBLANKING_0 /*!< TIM1 OC5 selected as blanking source for compartor */
+
+/* Blanking source common for COMP1 and COMP2 */
+#define STM32_COMP_BlankingSrce_TIM2OC3 COMP_CSR_COMPxBLANKING_1 /*!< TIM2 OC5 selected as blanking source for compartor */
+
+/* Blanking source common for COMP1, COMP2 and COMP5 */
+#define STM32_COMP_BlankingSrce_TIM3OC3 ((uint32_t)0x000C0000) /*!< TIM2 OC3 selected as blanking source for compartor */
+
+/* Blanking source common for COMP3 and COMP6 */
+#define STM32_COMP_BlankingSrce_TIM2OC4 ((uint32_t)0x000C0000) /*!< TIM2 OC4 selected as blanking source for compartor */
+
+/* Blanking source common for COMP4, COMP5, COMP6 and COMP7 */
+#define STM32_COMP_BlankingSrce_TIM8OC5 COMP_CSR_COMPxBLANKING_1 /*!< TIM8 OC5 selected as blanking source for compartor */
+
+/* Blanking source for COMP4 */
+#define STM32_COMP_BlankingSrce_TIM3OC4 COMP_CSR_COMPxBLANKING_0 /*!< TIM3 OC4 selected as blanking source for compartor */
+#define STM32_COMP_BlankingSrce_TIM15OC1 ((uint32_t)0x000C0000) /*!< TIM15 OC1 selected as blanking source for compartor */
+
+/* Blanking source common for COMP6 and COMP7 */
+#define STM32_COMP_BlankingSrce_TIM15OC2 COMP_CSR_COMPxBLANKING_2 /*!< TIM15 OC2 selected as blanking source for compartor */
+
+#define STM32_COMP_OutputPol_NonInverted ((uint32_t)0x00000000) /*!< COMP output on GPIO isn't inverted */
+#define STM32_COMP_OutputPol_Inverted COMP_CSR_COMPxPOL /*!< COMP output on GPIO is inverted */
+
+#define STM32_COMP_Hysteresis_No 0x00000000 /*!< No hysteresis */
+#define STM32_COMP_Hysteresis_Low COMP_CSR_COMPxHYST_0 /*!< Hysteresis level low */
+#define STM32_COMP_Hysteresis_Medium COMP_CSR_COMPxHYST_1 /*!< Hysteresis level medium */
+#define STM32_COMP_Hysteresis_High COMP_CSR_COMPxHYST /*!< Hysteresis level high */
+
+#define STM32_COMP_Mode_HighSpeed 0x00000000 /*!< High Speed */
+#define STM32_COMP_Mode_MediumSpeed COMP_CSR_COMPxMODE_0 /*!< Medium Speed */
+#define STM32_COMP_Mode_LowPower COMP_CSR_COMPxMODE_1 /*!< Low power mode */
+#define STM32_COMP_Mode_UltraLowPower COMP_CSR_COMPxMODE /*!< Ultra-low power mode */
+
+/* When output polarity is not inverted, comparator output is high when
+ the non-inverting input is at a higher voltage than the inverting input */
+#define STM32_COMP_OutputLevel_High COMP_CSR_COMPxOUT
+/* When output polarity is not inverted, comparator output is low when
+ the non-inverting input is at a lower voltage than the inverting input*/
+#define STM32_COMP_OutputLevel_Low ((uint32_t)0x00000000)
+
+
+#if defined(STM32F301x8) || defined(STM32F302x8) || defined(STM32F303x8) \
+|| defined(STM32F318xx) || defined(STM32F328xx) || defined(STM32F334x8)
+#define STM32_HAS_COMP1 FALSE
+#define STM32_HAS_COMP2 TRUE
+#define STM32_HAS_COMP3 FALSE
+#define STM32_HAS_COMP4 TRUE
+#define STM32_HAS_COMP5 FALSE
+#define STM32_HAS_COMP6 TRUE
+#define STM32_HAS_COMP7 FALSE
+
+#elif defined(STM32F302xc) || defined(STM32F302xe)
+#define STM32_HAS_COMP1 TRUE
+#define STM32_HAS_COMP2 TRUE
+#define STM32_HAS_COMP3 FALSE
+#define STM32_HAS_COMP4 TRUE
+#define STM32_HAS_COMP5 FALSE
+#define STM32_HAS_COMP6 TRUE
+#define STM32_HAS_COMP7 FALSE
+
+#elif defined(STM32F303xC) || defined(STM32F303xE) || defined(STM32F358xx) || defined(STM32F398xx)
+#define STM32_HAS_COMP1 TRUE
+#define STM32_HAS_COMP2 TRUE
+#define STM32_HAS_COMP3 TRUE
+#define STM32_HAS_COMP4 TRUE
+#define STM32_HAS_COMP5 TRUE
+#define STM32_HAS_COMP6 TRUE
+#define STM32_HAS_COMP7 TRUE
+
+#elif defined(STM32F373xx) || defined(STM32F378xx) || defined(STM32L0XX) || defined(STM32L1XX) \
+ || defined(STM32F051x8) || defined(STM32F048xx) || defined(STM32F058xx) || defined(STM32F078xx) \
+ || defined(STM32F072xb) || defined(STM32F071xb)
+#define STM32_HAS_COMP1 TRUE
+#define STM32_HAS_COMP2 TRUE
+#define STM32_HAS_COMP3 FALSE
+#define STM32_HAS_COMP4 FALSE
+#define STM32_HAS_COMP5 FALSE
+#define STM32_HAS_COMP6 FALSE
+#define STM32_HAS_COMP7 FALSE
+
+#else
+#define STM32_HAS_COMP1 FALSE
+#define STM32_HAS_COMP2 FALSE
+#define STM32_HAS_COMP3 FALSE
+#define STM32_HAS_COMP4 FALSE
+#define STM32_HAS_COMP5 FALSE
+#define STM32_HAS_COMP6 FALSE
+#define STM32_HAS_COMP7 FALSE
+
+#endif
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+
+/**
+ * @brief COMP INTERRUPTS.
+ * @details If set to @p TRUE the support for COMPD1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_COMP_USE_INTERRUPTS) || defined(__DOXYGEN__)
+#define STM32_COMP_USE_INTERRUPTS FALSE
+#endif
+
+/**
+ * @brief COMPD1 driver enable switch.
+ * @details If set to @p TRUE the support for COMPD1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_COMP_USE_COMP1) || defined(__DOXYGEN__)
+#define STM32_COMP_USE_COMP1 FALSE
+#endif
+
+/**
+ * @brief COMPD2 driver enable switch.
+ * @details If set to @p TRUE the support for COMPD2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_COMP_USE_COMP2) || defined(__DOXYGEN__)
+#define STM32_COMP_USE_COMP2 FALSE
+#endif
+
+/**
+ * @brief COMPD3 driver enable switch.
+ * @details If set to @p TRUE the support for COMPD3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_COMP_USE_COMP3) || defined(__DOXYGEN__)
+#define STM32_COMP_USE_COMP3 FALSE
+#endif
+
+/**
+ * @brief COMPD4 driver enable switch.
+ * @details If set to @p TRUE the support for COMPD4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_COMP_USE_COMP4) || defined(__DOXYGEN__)
+#define STM32_COMP_USE_COMP4 FALSE
+#endif
+
+/**
+ * @brief COMPD5 driver enable switch.
+ * @details If set to @p TRUE the support for COMPD4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_COMP_USE_COMP5) || defined(__DOXYGEN__)
+#define STM32_COMP_USE_COMP5 FALSE
+#endif
+
+/**
+ * @brief COMPD6 driver enable switch.
+ * @details If set to @p TRUE the support for COMPD4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_COMP_USE_COMP6) || defined(__DOXYGEN__)
+#define STM32_COMP_USE_COMP6 FALSE
+#endif
+
+/**
+ * @brief COMPD7 driver enable switch.
+ * @details If set to @p TRUE the support for COMPD4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_COMP_USE_COMP7) || defined(__DOXYGEN__)
+#define STM32_COMP_USE_COMP7 FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_COMP_USE_INTERRUPTS && defined(STM32F0XX)
+#error "Interrupts are shared with EXTI on F0s (lines 21-22)"
+#endif
+
+#if STM32_COMP_USE_INTERRUPTS
+#if !defined(STM32_DISABLE_EXTI21_22_29_HANDLER) || !defined(STM32_DISABLE_EXTI30_32_HANDLER) || !defined(STM32_DISABLE_EXTI33_HANDLER)
+#error "COMP needs these defines in mcuconf to use interrupts: STM32_DISABLE_EXTI21_22_29_HANDLER STM32_DISABLE_EXTI30_32_HANDLER STM32_DISABLE_EXTI33_HANDLER"
+#endif
+#endif
+
+#if STM32_COMP_USE_COMP1 && !STM32_HAS_COMP1
+#error "COMP1 not present in the selected device"
+#endif
+
+#if STM32_COMP_USE_COMP2 && !STM32_HAS_COMP2
+#error "COMP2 not present in the selected device"
+#endif
+
+#if STM32_COMP_USE_COMP3 && !STM32_HAS_COMP3
+#error "COMP3 not present in the selected device"
+#endif
+
+#if STM32_COMP_USE_COMP4 && !STM32_HAS_COMP4
+#error "COMP4 not present in the selected device"
+#endif
+
+#if STM32_COMP_USE_COMP5 && !STM32_HAS_COMP5
+#error "COMP5 not present in the selected device"
+#endif
+
+#if STM32_COMP_USE_COMP6 && !STM32_HAS_COMP6
+#error "COMP6 not present in the selected device"
+#endif
+
+#if STM32_COMP_USE_COMP7 && !STM32_HAS_COMP7
+#error "COMP7 not present in the selected device"
+#endif
+
+#if !STM32_COMP_USE_COMP1 && !STM32_COMP_USE_COMP2 && \
+ !STM32_COMP_USE_COMP3 && !STM32_COMP_USE_COMP4 && \
+ !STM32_COMP_USE_COMP6 && !STM32_COMP_USE_COMP6 && \
+ !STM32_COMP_USE_COMP7
+#error "COMP driver activated but no COMP peripheral assigned"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief COMP output mode.
+ */
+typedef enum {
+ COMP_OUTPUT_NORMAL = 0,
+ COMP_OUTPUT_INVERTED = 1
+} comp_output_mode_t;
+
+/**
+ * @brief COMP interrupt mode.
+ */
+typedef enum {
+ COMP_IRQ_RISING = 0,
+ COMP_IRQ_FALLING = 1,
+ COMP_IRQ_BOTH = 2
+} comp_irq_mode_t;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Ouput mode.
+ */
+ comp_output_mode_t output_mode;
+
+ /**
+ * @brief Ouput mode.
+ */
+ comp_irq_mode_t irq_mode;
+
+ /**
+ * @brief Callback.
+ */
+ compcallback_t cb;
+
+ /* End of the mandatory fields.*/
+
+ /**
+ * @brief COMP CSR register initialization data.
+ * @note The value of this field should normally be equal to zero.
+ */
+ uint32_t csr;
+} COMPConfig;
+
+/**
+ * @brief Structure representing an COMP driver.
+ */
+struct COMPDriver {
+ /**
+ * @brief Driver state.
+ */
+ compstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const COMPConfig *config;
+#if defined(COMP_DRIVER_EXT_FIELDS)
+ COMP_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the COMPx registers block.
+ */
+ COMP_TypeDef *reg;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_COMP_USE_COMP1 && !defined(__DOXYGEN__)
+extern COMPDriver COMPD1;
+#endif
+
+#if STM32_COMP_USE_COMP2 && !defined(__DOXYGEN__)
+extern COMPDriver COMPD2;
+#endif
+
+#if STM32_COMP_USE_COMP3 && !defined(__DOXYGEN__)
+extern COMPDriver COMPD3;
+#endif
+
+#if STM32_COMP_USE_COMP4 && !defined(__DOXYGEN__)
+extern COMPDriver COMPD4;
+#endif
+
+#if STM32_COMP_USE_COMP5 && !defined(__DOXYGEN__)
+extern COMPDriver COMPD5;
+#endif
+
+#if STM32_COMP_USE_COMP6 && !defined(__DOXYGEN__)
+extern COMPDriver COMPD6;
+#endif
+
+#if STM32_COMP_USE_COMP7 && !defined(__DOXYGEN__)
+extern COMPDriver COMPD7;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void comp_lld_init(void);
+ void comp_lld_start(COMPDriver *compp);
+ void comp_lld_stop(COMPDriver *compp);
+ void comp_lld_enable(COMPDriver *compp);
+ void comp_lld_disable(COMPDriver *compp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_COMP */
+
+#endif /* _comp_lld_H_ */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.c b/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.c
index 601deca..701b87d 100644..100755
--- a/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.c
+++ b/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.c
@@ -15,7 +15,7 @@
*/
/**
- * @file STM32/CRCv1/crc_lld.c
+ * @file STM32/CRCv1/hal_crc_lld.c
* @brief STM32 CRC subsystem low level driver source.
*
* @addtogroup CRC
@@ -155,7 +155,7 @@ void crc_lld_start(CRCDriver *crcp) {
if (crcp->config == NULL)
crcp->config = &default_config;
- rccEnableCRC(FALSE);
+ rccEnableCRC();
#if STM32_CRC_PROGRAMMABLE == TRUE
crcp->crc->INIT = crcp->config->initial_val;
@@ -185,15 +185,15 @@ void crc_lld_start(CRCDriver *crcp) {
crcp->crc->CR |= CRC_CR_REV_OUT;
}
#else
- osalDbgAssert(crcp->config->initial_val != default_config.initial_val,
+ osalDbgAssert(crcp->config->initial_val == default_config.initial_val,
"hardware doesn't support programmable initial value");
- osalDbgAssert(crcp->config->poly_size != default_config.poly_size,
+ osalDbgAssert(crcp->config->poly_size == default_config.poly_size,
"hardware doesn't support programmable polynomial size");
- osalDbgAssert(crcp->config->poly != default_config.poly,
+ osalDbgAssert(crcp->config->poly == default_config.poly,
"hardware doesn't support programmable polynomial");
- osalDbgAssert(crcp->config->reflect_data != default_config.reflect_data,
+ osalDbgAssert(crcp->config->reflect_data == default_config.reflect_data,
"hardware doesn't support reflect of input data");
- osalDbgAssert(crcp->config->reflect_remainder != default_config.reflect_remainder,
+ osalDbgAssert(crcp->config->reflect_remainder == default_config.reflect_remainder,
"hardware doesn't support reflect of output remainder");
#endif
@@ -234,7 +234,7 @@ void crc_lld_stop(CRCDriver *crcp) {
#else
(void)crcp;
#endif
- rccDisableCRC(FALSE);
+ rccDisableCRC();
}
/**
@@ -299,7 +299,7 @@ uint32_t crc_lld_calc(CRCDriver *crcp, size_t n, const void *buf) {
n--;
}
#else
- osalDbgAssert(n != 0, "STM32 CRC Unit only supports WORD accesses");
+ osalDbgAssert(n == 0, "STM32 CRC Unit only supports WORD accesses");
#endif
#endif
diff --git a/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.h b/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.h
index ecdaf81..213d346 100644
--- a/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.h
+++ b/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.h
@@ -15,15 +15,15 @@
*/
/**
- * @file STM32/CRCv1/crc_lld.h
+ * @file STM32/CRCv1/hal_crc_lld.h
* @brief STM32 CRC subsystem low level driver header.
*
* @addtogroup CRC
* @{
*/
-#ifndef _CRC_LLD_H_
-#define _CRC_LLD_H_
+#ifndef HAL_CRC_LLD_H_
+#define HAL_CRC_LLD_H_
#if (HAL_USE_CRC == TRUE) || defined(__DOXYGEN__)
@@ -244,6 +244,6 @@ extern "C" {
#endif /* HAL_USE_CRC */
-#endif /* _CRC_LLD_H_ */
+#endif /* HAL_CRC_LLD_H_ */
/** @} */
diff --git a/os/hal/ports/STM32/LLD/DMA2Dv1/hal_stm32_dma2d.c b/os/hal/ports/STM32/LLD/DMA2Dv1/hal_stm32_dma2d.c
index aba029f..b7c9b49 100644
--- a/os/hal/ports/STM32/LLD/DMA2Dv1/hal_stm32_dma2d.c
+++ b/os/hal/ports/STM32/LLD/DMA2Dv1/hal_stm32_dma2d.c
@@ -15,11 +15,10 @@
*/
/**
- * @file stm32_dma2d.c
+ * @file hal_stm32_dma2d.c
* @brief DMA2D/Chrom-ART driver.
*/
-#include "ch.h"
#include "hal.h"
#include "hal_stm32_dma2d.h"
diff --git a/os/hal/ports/STM32/LLD/DMA2Dv1/hal_stm32_dma2d.h b/os/hal/ports/STM32/LLD/DMA2Dv1/hal_stm32_dma2d.h
index 01f0941..c06ab62 100644
--- a/os/hal/ports/STM32/LLD/DMA2Dv1/hal_stm32_dma2d.h
+++ b/os/hal/ports/STM32/LLD/DMA2Dv1/hal_stm32_dma2d.h
@@ -15,15 +15,15 @@
*/
/**
- * @file stm32_dma2d.h
+ * @file hal_stm32_dma2d.h
* @brief DMA2D/Chrom-ART driver.
*
* @addtogroup dma2d
* @{
*/
-#ifndef _STM32_DMA2D_H_
-#define _STM32_DMA2D_H_
+#ifndef HAL_STM32_DMA2D_H_
+#define HAL_STM32_DMA2D_H_
/**
* @brief Using the DMA2D driver.
@@ -659,6 +659,6 @@ extern "C" {
#endif /* STM32_DMA2D_USE_DMA2D */
-#endif /* _STM32_DMA2D_H_ */
+#endif /* HAL_STM32_DMA2D_H_ */
/** @} */
diff --git a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.c b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.c
index 8b1082c..71c6ada 100644
--- a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.c
+++ b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.c
@@ -15,7 +15,7 @@
*/
/**
- * @file fsmc.c
+ * @file hal_fsmc.c
* @brief FSMC Driver subsystem low level driver source template.
*
* @addtogroup FSMC
@@ -96,7 +96,11 @@ void fsmc_init(void) {
#endif
#if (defined(STM32F427xx) || defined(STM32F437xx) || \
- defined(STM32F429xx) || defined(STM32F439xx))
+ defined(STM32F429xx) || defined(STM32F439xx) || \
+ defined(STM32F745xx) || defined(STM32F746xx) || \
+ defined(STM32F756xx) || defined(STM32F767xx) || \
+ defined(STM32F769xx) || defined(STM32F777xx) || \
+ defined(STM32F779xx))
#if STM32_USE_FSMC_SDRAM
FSMCD1.sdram = (FSMC_SDRAM_TypeDef *)FSMC_Bank5_6_R_BASE;
#endif
@@ -124,7 +128,7 @@ void fsmc_start(FSMCDriver *fsmcp) {
rccResetFSMC();
#endif
rccEnableFSMC(FALSE);
-#if (!STM32_NAND_USE_EXT_INT && HAL_USE_NAND)
+#if HAL_USE_NAND
nvicEnableVector(STM32_FSMC_NUMBER, STM32_FSMC_FSMC1_IRQ_PRIORITY);
#endif
}
@@ -152,10 +156,10 @@ void fsmc_stop(FSMCDriver *fsmcp) {
/* Disables the peripheral.*/
#if STM32_FSMC_USE_FSMC1
if (&FSMCD1 == fsmcp) {
-#if (!STM32_NAND_USE_EXT_INT && HAL_USE_NAND)
+#if HAL_USE_NAND
nvicDisableVector(STM32_FSMC_NUMBER);
#endif
- rccDisableFSMC(FALSE);
+ rccDisableFSMC();
}
#endif /* STM32_FSMC_USE_FSMC1 */
@@ -163,7 +167,6 @@ void fsmc_stop(FSMCDriver *fsmcp) {
}
}
-#if !STM32_NAND_USE_EXT_INT
/**
* @brief FSMC shared interrupt handler.
*
@@ -184,7 +187,6 @@ CH_IRQ_HANDLER(STM32_FSMC_HANDLER) {
#endif
CH_IRQ_EPILOGUE();
}
-#endif /* !STM32_NAND_USE_EXT_INT */
#endif /* HAL_USE_FSMC */
diff --git a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.h b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.h
index 7889b01..80c5d26 100644
--- a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.h
+++ b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.h
@@ -15,15 +15,15 @@
*/
/**
- * @file fsmc.h
+ * @file hal_fsmc.h
* @brief FSMC Driver subsystem low level driver header.
*
* @addtogroup FSMC
* @{
*/
-#ifndef _FSMC_H_
-#define _FSMC_H_
+#ifndef HAL_FSMC_H_
+#define HAL_FSMC_H_
#if (HAL_USE_FSMC == TRUE) || defined(__DOXYGEN__)
@@ -35,7 +35,11 @@
* (Re)define if needed base address constants supplied in ST's CMSIS
*/
#if (defined(STM32F427xx) || defined(STM32F437xx) || \
- defined(STM32F429xx) || defined(STM32F439xx))
+ defined(STM32F429xx) || defined(STM32F439xx) || \
+ defined(STM32F745xx) || defined(STM32F746xx) || \
+ defined(STM32F756xx) || defined(STM32F767xx) || \
+ defined(STM32F769xx) || defined(STM32F777xx) || \
+ defined(STM32F779xx))
#if !defined(FSMC_Bank1_R_BASE)
#define FSMC_Bank1_R_BASE (FMC_R_BASE + 0x0000)
#endif
@@ -80,7 +84,8 @@
#define FSMC_Bank3_MAP_BASE ((uint32_t) 0x80000000)
#define FSMC_Bank4_MAP_BASE ((uint32_t) 0x90000000)
#if (defined(STM32F427xx) || defined(STM32F437xx) || \
- defined(STM32F429xx) || defined(STM32F439xx))
+ defined(STM32F429xx) || defined(STM32F439xx) || \
+ defined(STM32F7))
#define FSMC_Bank5_MAP_BASE ((uint32_t) 0xC0000000)
#define FSMC_Bank6_MAP_BASE ((uint32_t) 0xD0000000)
#endif
@@ -157,7 +162,8 @@ typedef struct {
} FSMC_SRAM_NOR_TypeDef;
#if (defined(STM32F427xx) || defined(STM32F437xx) || \
- defined(STM32F429xx) || defined(STM32F439xx))
+ defined(STM32F429xx) || defined(STM32F439xx) || \
+ defined(STM32F7))
typedef struct {
__IO uint32_t SDCR1; /**< SDRAM control register (bank 1) */
@@ -174,10 +180,15 @@ typedef struct {
/**
* @brief PCR register
*/
-#define FSMC_PCR_PWAITEN ((uint32_t)0x00000002)
-#define FSMC_PCR_PBKEN ((uint32_t)0x00000004)
-#define FSMC_PCR_PTYP ((uint32_t)0x00000008)
-#define FSMC_PCR_ECCEN ((uint32_t)0x00000040)
+#define FSMC_PCR_PWAITEN ((uint32_t)1 << 1)
+#define FSMC_PCR_PBKEN ((uint32_t)1 << 2)
+#define FSMC_PCR_PTYP ((uint32_t)1 << 3)
+#define FSMC_PCR_PWID_8 ((uint32_t)0 << 4)
+#define FSMC_PCR_PWID_16 ((uint32_t)1 << 4)
+#define FSMC_PCR_PWID_RESERVED1 ((uint32_t)2 << 4)
+#define FSMC_PCR_PWID_RESERVED2 ((uint32_t)3 << 4)
+#define FSMC_PCR_PWID_MASK ((uint32_t)3 << 4)
+#define FSMC_PCR_ECCEN ((uint32_t)1 << 6)
#define FSMC_PCR_PTYP_PCCARD 0
#define FSMC_PCR_PTYP_NAND FSMC_PCR_PTYP
@@ -205,7 +216,8 @@ typedef struct {
#define FSMC_BCR_MWID_8 ((uint32_t)0 << 4)
#define FSMC_BCR_MWID_16 ((uint32_t)1 << 4)
#if (defined(STM32F427xx) || defined(STM32F437xx) || \
- defined(STM32F429xx) || defined(STM32F439xx))
+ defined(STM32F429xx) || defined(STM32F439xx) || \
+ defined(STM32F7))
#define FSMC_BCR_MWID_32 ((uint32_t)2 << 4)
#else
#define FSMC_BCR_MWID_RESERVED1 ((uint32_t)2 << 4)
@@ -221,6 +233,14 @@ typedef struct {
#define FSMC_BCR_EXTMOD ((uint32_t)1 << 14)
#define FSMC_BCR_ASYNCWAIT ((uint32_t)1 << 15)
#define FSMC_BCR_CBURSTRW ((uint32_t)1 << 19)
+#if (defined(STM32F427xx) || defined(STM32F437xx) || \
+ defined(STM32F429xx) || defined(STM32F439xx) || \
+ defined(STM32F7))
+#define FSMC_BCR_CCLKEN ((uint32_t)1 << 20)
+#endif
+#if (defined(STM32F7))
+#define FSMC_BCR_WFDIS ((uint32_t)1 << 21)
+#endif
/*===========================================================================*/
/* Driver pre-compile time settings. */
@@ -238,15 +258,6 @@ typedef struct {
#define STM32_FSMC_USE_FSMC1 FALSE
#endif
-/**
- * @brief Internal FSMC interrupt enable switch
- * @details MCUs in 100-pin package has no dedicated interrupt pin for FSMC.
- * You have to use EXTI module instead to workaround this issue.
- */
-#if !defined(STM32_NAND_USE_EXT_INT) || defined(__DOXYGEN__)
-#define STM32_NAND_USE_EXT_INT FALSE
-#endif
-
/** @} */
/*===========================================================================*/
@@ -303,7 +314,8 @@ struct FSMCDriver {
FSMC_NAND_TypeDef *nand2;
#endif
#if (defined(STM32F427xx) || defined(STM32F437xx) || \
- defined(STM32F429xx) || defined(STM32F439xx))
+ defined(STM32F429xx) || defined(STM32F439xx) || \
+ defined(STM32F7))
#if STM32_USE_FSMC_SDRAM
FSMC_SDRAM_TypeDef *sdram;
#endif
@@ -334,6 +346,6 @@ extern "C" {
#endif /* HAL_USE_FSMC */
-#endif /* _FSMC_H_ */
+#endif /* HAL_FSMC_H_ */
/** @} */
diff --git a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.c b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.c
index 95f47d5..6d727c8 100644
--- a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.c
+++ b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.c
@@ -18,7 +18,7 @@
*/
/**
- * @file fsmc_sdram.c
+ * @file hal_fsmc_sdram.c
* @brief SDRAM Driver subsystem low level driver source.
*
* @addtogroup SDRAM
@@ -28,7 +28,11 @@
#include "hal.h"
#if (defined(STM32F427xx) || defined(STM32F437xx) || \
- defined(STM32F429xx) || defined(STM32F439xx))
+ defined(STM32F429xx) || defined(STM32F439xx) || \
+ defined(STM32F745xx) || defined(STM32F746xx) || \
+ defined(STM32F756xx) || defined(STM32F767xx) || \
+ defined(STM32F769xx) || defined(STM32F777xx) || \
+ defined(STM32F779xx))
#if (STM32_USE_FSMC_SDRAM == TRUE) || defined(__DOXYGEN__)
diff --git a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.h b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.h
index cef6772..c9f9de0 100644
--- a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.h
+++ b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.h
@@ -18,18 +18,22 @@
*/
/**
- * @file fsmc_sdram.h
+ * @file hal_fsmc_sdram.h
* @brief SDRAM Driver subsystem low level driver header.
*
* @addtogroup SDRAM
* @{
*/
-#ifndef _FMC_SDRAM_H_
-#define _FMC_SDRAM_H_
+#ifndef HAL_FMC_SDRAM_H_
+#define HAL_FMC_SDRAM_H_
#if (defined(STM32F427xx) || defined(STM32F437xx) || \
- defined(STM32F429xx) || defined(STM32F439xx))
+ defined(STM32F429xx) || defined(STM32F439xx) || \
+ defined(STM32F745xx) || defined(STM32F746xx) || \
+ defined(STM32F756xx) || defined(STM32F767xx) || \
+ defined(STM32F769xx) || defined(STM32F777xx) || \
+ defined(STM32F779xx))
#include "hal_fsmc.h"
@@ -166,6 +170,6 @@ extern "C" {
#endif /* STM32F427xx / STM32F429xx / STM32F437xx / STM32F439xx */
-#endif /* _FMC_SDRAM_H_ */
+#endif /* HAL_FMC_SDRAM_H_ */
/** @} */
diff --git a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.c b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.c
index 6f710d4..da13ca5 100644
--- a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.c
+++ b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.c
@@ -15,7 +15,7 @@
*/
/**
- * @file fsmc_sram.c
+ * @file hal_fsmc_sram.c
* @brief SRAM Driver subsystem low level driver source.
*
* @addtogroup SRAM
@@ -128,9 +128,9 @@ void fsmcSramStart(SRAMDriver *sramp, const SRAMConfig *cfgp) {
"invalid state");
if (sramp->state == SRAM_STOP) {
- sramp->sram->BCR = cfgp->bcr | FSMC_BCR_MBKEN;
sramp->sram->BTR = cfgp->btr;
sramp->sram->BWTR = cfgp->bwtr;
+ sramp->sram->BCR = cfgp->bcr | FSMC_BCR_MBKEN;
sramp->state = SRAM_READY;
}
}
@@ -145,7 +145,16 @@ void fsmcSramStart(SRAMDriver *sramp, const SRAMConfig *cfgp) {
void fsmcSramStop(SRAMDriver *sramp) {
if (sramp->state == SRAM_READY) {
- sramp->sram->BCR &= ~FSMC_BCR_MBKEN;
+ uint32_t mask = FSMC_BCR_MBKEN;
+#if (defined(STM32F427xx) || defined(STM32F437xx) || \
+ defined(STM32F429xx) || defined(STM32F439xx) || \
+ defined(STM32F745xx) || defined(STM32F746xx) || \
+ defined(STM32F756xx) || defined(STM32F767xx) || \
+ defined(STM32F769xx) || defined(STM32F777xx) || \
+ defined(STM32F779xx))
+ mask |= FSMC_BCR_CCLKEN;
+#endif
+ sramp->sram->BCR &= ~mask;
sramp->state = SRAM_STOP;
}
}
diff --git a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.h b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.h
index 529bdc7..5e749a8 100644
--- a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.h
+++ b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.h
@@ -15,15 +15,15 @@
*/
/**
- * @file fsmc_sram.h
+ * @file hal_fsmc_sram.h
* @brief SRAM Driver subsystem low level driver header.
*
* @addtogroup SRAM
* @{
*/
-#ifndef _FSMC_SRAM_H_
-#define _FSMC_SRAM_H_
+#ifndef HAL_FSMC_SRAM_H_
+#define HAL_FSMC_SRAM_H_
#include "hal_fsmc.h"
@@ -167,6 +167,6 @@ extern "C" {
#endif /* STM32_USE_FSMC_SRAM */
-#endif /* _FSMC_SRAM_H_ */
+#endif /* HAL_FSMC_SRAM_H_ */
/** @} */
diff --git a/os/hal/ports/STM32/LLD/FSMCv1/hal_nand_lld.c b/os/hal/ports/STM32/LLD/FSMCv1/hal_nand_lld.c
index b37c026..5729f92 100644
--- a/os/hal/ports/STM32/LLD/FSMCv1/hal_nand_lld.c
+++ b/os/hal/ports/STM32/LLD/FSMCv1/hal_nand_lld.c
@@ -15,7 +15,7 @@
*/
/**
- * @file nand_lld.c
+ * @file hal_nand_lld.c
* @brief NAND Driver subsystem low level driver source.
*
* @addtogroup NAND
@@ -33,6 +33,19 @@
STM32_DMA_GETCHANNEL(STM32_NAND_DMA_STREAM, \
STM32_FSMC_DMA_CHN)
+/**
+ * @brief Bus width of NAND IC.
+ * @details Must be 8 or 16
+ */
+#if ! defined(STM32_NAND_BUS_WIDTH) || defined(__DOXYGEN__)
+#define STM32_NAND_BUS_WIDTH 8
+#endif
+
+/**
+ * @brief DMA transaction width on AHB bus in bytes
+ */
+#define AHB_TRANSACTION_WIDTH 2
+
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@@ -62,6 +75,47 @@ NANDDriver NANDD2;
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
+
+/**
+ * @brief Helper function.
+ *
+ * @notapi
+ */
+static void align_check(const void *ptr, uint32_t len) {
+ osalDbgCheck((((uint32_t)ptr % AHB_TRANSACTION_WIDTH) == 0) &&
+ ((len % AHB_TRANSACTION_WIDTH) == 0) &&
+ (len >= AHB_TRANSACTION_WIDTH));
+ (void)ptr;
+ (void)len;
+}
+
+/**
+ * @brief Work around errata in STM32's FSMC core.
+ * @details Constant output clock (if enabled) disappears when CLKDIV value
+ * sets to 1 (FMC_CLK period = 2 × HCLK periods) AND 8-bit async
+ * transaction generated on AHB. This workaround eliminates 8-bit
+ * transactions on bus when you use 8-bit memory. It suitable only
+ * for 8-bit memory (i.e. PWID bits in PCR register must be set
+ * to 8-bit mode).
+ *
+ * @notapi
+ */
+static void set_16bit_bus(NANDDriver *nandp) {
+#if STM32_NAND_BUS_WIDTH
+ nandp->nand->PCR |= FSMC_PCR_PWID_16;
+#else
+ (void)nandp;
+#endif
+}
+
+static void set_8bit_bus(NANDDriver *nandp) {
+#if STM32_NAND_BUS_WIDTH
+ nandp->nand->PCR &= ~FSMC_PCR_PWID_16;
+#else
+ (void)nandp;
+#endif
+}
+
/**
* @brief Wakes up the waiting thread.
*
@@ -117,13 +171,10 @@ static uint32_t calc_eccps(NANDDriver *nandp) {
* @notapi
*/
static void nand_ready_isr_enable(NANDDriver *nandp) {
-#if STM32_NAND_USE_EXT_INT
- nandp->config->ext_nand_isr_enable();
-#else
+
nandp->nand->SR &= ~(FSMC_SR_IRS | FSMC_SR_ILS | FSMC_SR_IFS |
- FSMC_SR_ILEN | FSMC_SR_IFEN);
+ FSMC_SR_ILEN | FSMC_SR_IFEN);
nandp->nand->SR |= FSMC_SR_IREN;
-#endif
}
/**
@@ -134,11 +185,8 @@ static void nand_ready_isr_enable(NANDDriver *nandp) {
* @notapi
*/
static void nand_ready_isr_disable(NANDDriver *nandp) {
-#if STM32_NAND_USE_EXT_INT
- nandp->config->ext_nand_isr_disable();
-#else
+
nandp->nand->SR &= ~FSMC_SR_IREN;
-#endif
}
/**
@@ -148,31 +196,24 @@ static void nand_ready_isr_disable(NANDDriver *nandp) {
*
* @notapi
*/
-static void nand_isr_handler (NANDDriver *nandp) {
+static void nand_isr_handler(NANDDriver *nandp) {
osalSysLockFromISR();
-#if !STM32_NAND_USE_EXT_INT
osalDbgCheck(nandp->nand->SR & FSMC_SR_IRS); /* spurious interrupt happened */
nandp->nand->SR &= ~FSMC_SR_IRS;
-#endif
switch (nandp->state){
case NAND_READ:
nandp->state = NAND_DMA_RX;
- dmaStartMemCopy(nandp->dma, nandp->dmamode,
- nandp->map_data, nandp->rxdata, nandp->datalen);
+ dmaStartMemCopy(nandp->dma, nandp->dmamode, nandp->map_data, nandp->rxdata,
+ nandp->datalen/AHB_TRANSACTION_WIDTH);
/* thread will be waked up from DMA ISR */
break;
- case NAND_ERASE:
- /* NAND reports about erase finish */
- nandp->state = NAND_READY;
- wakeup_isr(nandp);
- break;
-
- case NAND_PROGRAM:
- /* NAND reports about page programming finish */
+ case NAND_ERASE: /* NAND reports about erase finish */
+ case NAND_PROGRAM: /* NAND reports about page programming finish */
+ case NAND_RESET: /* NAND reports about finished reset recover */
nandp->state = NAND_READY;
wakeup_isr(nandp);
break;
@@ -210,7 +251,7 @@ static void nand_lld_serve_transfer_end_irq(NANDDriver *nandp, uint32_t flags) {
case NAND_DMA_TX:
nandp->state = NAND_PROGRAM;
nandp->map_cmd[0] = NAND_CMD_PAGEPROG;
- /* thread will be woken from ready_isr() */
+ /* thread will be woken up from ready_isr() */
break;
case NAND_DMA_RX:
@@ -249,9 +290,9 @@ void nand_lld_init(void) {
NANDD1.thread = NULL;
NANDD1.dma = STM32_DMA_STREAM(STM32_NAND_DMA_STREAM);
NANDD1.nand = FSMCD1.nand1;
- NANDD1.map_data = (uint8_t*)FSMC_Bank2_MAP_COMMON_DATA;
- NANDD1.map_cmd = (uint8_t*)FSMC_Bank2_MAP_COMMON_CMD;
- NANDD1.map_addr = (uint8_t*)FSMC_Bank2_MAP_COMMON_ADDR;
+ NANDD1.map_data = (void *)FSMC_Bank2_MAP_COMMON_DATA;
+ NANDD1.map_cmd = (uint16_t *)FSMC_Bank2_MAP_COMMON_CMD;
+ NANDD1.map_addr = (uint16_t *)FSMC_Bank2_MAP_COMMON_ADDR;
NANDD1.bb_map = NULL;
#endif /* STM32_NAND_USE_FSMC_NAND1 */
@@ -263,9 +304,9 @@ void nand_lld_init(void) {
NANDD2.thread = NULL;
NANDD2.dma = STM32_DMA_STREAM(STM32_NAND_DMA_STREAM);
NANDD2.nand = FSMCD1.nand2;
- NANDD2.map_data = (uint8_t*)FSMC_Bank3_MAP_COMMON_DATA;
- NANDD2.map_cmd = (uint8_t*)FSMC_Bank3_MAP_COMMON_CMD;
- NANDD2.map_addr = (uint8_t*)FSMC_Bank3_MAP_COMMON_ADDR;
+ NANDD2.map_data = (void *)FSMC_Bank3_MAP_COMMON_DATA;
+ NANDD2.map_cmd = (uint16_t *)FSMC_Bank3_MAP_COMMON_CMD;
+ NANDD2.map_addr = (uint16_t *)FSMC_Bank3_MAP_COMMON_ADDR;
NANDD2.bb_map = NULL;
#endif /* STM32_NAND_USE_FSMC_NAND2 */
}
@@ -280,6 +321,8 @@ void nand_lld_init(void) {
void nand_lld_start(NANDDriver *nandp) {
bool b;
+ uint32_t dmasize;
+ uint32_t pcr_bus_width;
if (FSMCD1.state == FSMC_STOP)
fsmc_start(&FSMCD1);
@@ -290,16 +333,33 @@ void nand_lld_start(NANDDriver *nandp) {
(stm32_dmaisr_t)nand_lld_serve_transfer_end_irq,
(void *)nandp);
osalDbgAssert(!b, "stream already allocated");
+
+#if AHB_TRANSACTION_WIDTH == 4
+ dmasize = STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD;
+#elif AHB_TRANSACTION_WIDTH == 2
+ dmasize = STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
+#elif AHB_TRANSACTION_WIDTH == 1
+ dmasize = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
+#else
+#error "Incorrect AHB_TRANSACTION_WIDTH"
+#endif
+
nandp->dmamode = STM32_DMA_CR_CHSEL(NAND_DMA_CHANNEL) |
STM32_DMA_CR_PL(STM32_NAND_NAND1_DMA_PRIORITY) |
- STM32_DMA_CR_PSIZE_BYTE |
- STM32_DMA_CR_MSIZE_BYTE |
+ dmasize |
STM32_DMA_CR_DMEIE |
STM32_DMA_CR_TEIE |
STM32_DMA_CR_TCIE;
- /* dmaStreamSetFIFO(nandp->dma,
- STM32_DMA_FCR_DMDIS | NAND_STM32_DMA_FCR_FTH_LVL); */
- nandp->nand->PCR = calc_eccps(nandp) | FSMC_PCR_PTYP | FSMC_PCR_PBKEN;
+
+#if STM32_NAND_BUS_WIDTH == 8
+ pcr_bus_width = FSMC_PCR_PWID_8;
+#elif STM32_NAND_BUS_WIDTH == 16
+ pcr_bus_width = FSMC_PCR_PWID_16;
+#else
+#error "Bus width must be 8 or 16 bits"
+#endif
+ nandp->nand->PCR = pcr_bus_width | calc_eccps(nandp) |
+ FSMC_PCR_PTYP_NAND | FSMC_PCR_PBKEN;
nandp->nand->PMEM = nandp->config->pmem;
nandp->nand->PATT = nandp->config->pmem;
nandp->isr_handler = nand_isr_handler;
@@ -329,24 +389,28 @@ void nand_lld_stop(NANDDriver *nandp) {
*
* @param[in] nandp pointer to the @p NANDDriver object
* @param[out] data pointer to data buffer
- * @param[in] datalen size of data buffer
+ * @param[in] datalen size of data buffer in bytes
* @param[in] addr pointer to address buffer
* @param[in] addrlen length of address
* @param[out] ecc pointer to store computed ECC. Ignored when NULL.
*
* @notapi
*/
-void nand_lld_read_data(NANDDriver *nandp, uint8_t *data, size_t datalen,
+void nand_lld_read_data(NANDDriver *nandp, uint16_t *data, size_t datalen,
uint8_t *addr, size_t addrlen, uint32_t *ecc){
+ align_check(data, datalen);
+
nandp->state = NAND_READ;
nandp->rxdata = data;
nandp->datalen = datalen;
- nand_lld_write_cmd (nandp, NAND_CMD_READ0);
+ set_16bit_bus(nandp);
+ nand_lld_write_cmd(nandp, NAND_CMD_READ0);
nand_lld_write_addr(nandp, addr, addrlen);
osalSysLock();
- nand_lld_write_cmd (nandp, NAND_CMD_READ0_CONFIRM);
+ nand_lld_write_cmd(nandp, NAND_CMD_READ0_CONFIRM);
+ set_8bit_bus(nandp);
/* Here NAND asserts busy signal and starts transferring from memory
array to page buffer. After the end of transmission ready_isr functions
@@ -375,7 +439,7 @@ void nand_lld_read_data(NANDDriver *nandp, uint8_t *data, size_t datalen,
*
* @param[in] nandp pointer to the @p NANDDriver object
* @param[in] data buffer with data to be written
- * @param[in] datalen size of data buffer
+ * @param[in] datalen size of data buffer in bytes
* @param[in] addr pointer to address buffer
* @param[in] addrlen length of address
* @param[out] ecc pointer to store computed ECC. Ignored when NULL.
@@ -384,14 +448,18 @@ void nand_lld_read_data(NANDDriver *nandp, uint8_t *data, size_t datalen,
*
* @notapi
*/
-uint8_t nand_lld_write_data(NANDDriver *nandp, const uint8_t *data,
+uint8_t nand_lld_write_data(NANDDriver *nandp, const uint16_t *data,
size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc) {
+ align_check(data, datalen);
+
nandp->state = NAND_WRITE;
- nand_lld_write_cmd (nandp, NAND_CMD_WRITE);
+ set_16bit_bus(nandp);
+ nand_lld_write_cmd(nandp, NAND_CMD_WRITE);
osalSysLock();
nand_lld_write_addr(nandp, addr, addrlen);
+ set_8bit_bus(nandp);
/* Now start DMA transfer to NAND buffer and put thread in sleep state.
Tread will be woken up from ready ISR. */
@@ -403,7 +471,8 @@ uint8_t nand_lld_write_data(NANDDriver *nandp, const uint8_t *data,
nandp->nand->PCR |= FSMC_PCR_ECCEN;
}
- dmaStartMemCopy(nandp->dma, nandp->dmamode, data, nandp->map_data, datalen);
+ dmaStartMemCopy(nandp->dma, nandp->dmamode, data, nandp->map_data,
+ datalen/AHB_TRANSACTION_WIDTH);
nand_lld_suspend_thread(nandp);
osalSysUnlock();
@@ -419,6 +488,26 @@ uint8_t nand_lld_write_data(NANDDriver *nandp, const uint8_t *data,
}
/**
+ * @brief Soft reset NAND device.
+ *
+ * @param[in] nandp pointer to the @p NANDDriver object
+ *
+ * @notapi
+ */
+void nand_lld_reset(NANDDriver *nandp) {
+
+ nandp->state = NAND_RESET;
+
+ set_16bit_bus(nandp);
+ nand_lld_write_cmd(nandp, NAND_CMD_RESET);
+ set_8bit_bus(nandp);
+
+ osalSysLock();
+ nand_lld_suspend_thread(nandp);
+ osalSysUnlock();
+}
+
+/**
* @brief Erase block.
*
* @param[in] nandp pointer to the @p NANDDriver object
@@ -433,10 +522,13 @@ uint8_t nand_lld_erase(NANDDriver *nandp, uint8_t *addr, size_t addrlen) {
nandp->state = NAND_ERASE;
- nand_lld_write_cmd (nandp, NAND_CMD_ERASE);
+ set_16bit_bus(nandp);
+ nand_lld_write_cmd(nandp, NAND_CMD_ERASE);
nand_lld_write_addr(nandp, addr, addrlen);
osalSysLock();
- nand_lld_write_cmd (nandp, NAND_CMD_ERASE_CONFIRM);
+ nand_lld_write_cmd(nandp, NAND_CMD_ERASE_CONFIRM);
+ set_8bit_bus(nandp);
+
nand_lld_suspend_thread(nandp);
osalSysUnlock();
@@ -444,25 +536,6 @@ uint8_t nand_lld_erase(NANDDriver *nandp, uint8_t *addr, size_t addrlen) {
}
/**
- * @brief Read data from NAND using polling approach.
- *
- * @detatils Use this function to read data when no waiting expected. For
- * Example read status word after 0x70 command
- *
- * @param[in] nandp pointer to the @p NANDDriver object
- * @param[out] data pointer to output buffer
- * @param[in] len length of data to be read
- *
- * @notapi
- */
-void nand_lld_polled_read_data(NANDDriver *nandp, uint8_t *data, size_t len) {
- size_t i = 0;
-
- for (i=0; i<len; i++)
- data[i] = nandp->map_data[i];
-}
-
-/**
* @brief Send addres to NAND.
*
* @param[in] nandp pointer to the @p NANDDriver object
@@ -501,12 +574,14 @@ void nand_lld_write_cmd(NANDDriver *nandp, uint8_t cmd) {
*/
uint8_t nand_lld_read_status(NANDDriver *nandp) {
- uint8_t status[1] = {0x01}; /* presume worse */
+ uint16_t status;
+ set_16bit_bus(nandp);
nand_lld_write_cmd(nandp, NAND_CMD_STATUS);
- nand_lld_polled_read_data(nandp, status, 1);
+ set_8bit_bus(nandp);
+ status = nandp->map_data[0];
- return status[0];
+ return status & 0xFF;
}
#endif /* HAL_USE_NAND */
diff --git a/os/hal/ports/STM32/LLD/FSMCv1/hal_nand_lld.h b/os/hal/ports/STM32/LLD/FSMCv1/hal_nand_lld.h
index 8dca42f..5266138 100644
--- a/os/hal/ports/STM32/LLD/FSMCv1/hal_nand_lld.h
+++ b/os/hal/ports/STM32/LLD/FSMCv1/hal_nand_lld.h
@@ -15,15 +15,15 @@
*/
/**
- * @file nand_lld.h
+ * @file hal_nand_lld.h
* @brief NAND Driver subsystem low level driver header.
*
* @addtogroup NAND
* @{
*/
-#ifndef _NAND_LLD_H_
-#define _NAND_LLD_H_
+#ifndef HAL_NAND_LLD_H_
+#define HAL_NAND_LLD_H_
#include "hal_fsmc.h"
#include "bitmap.h"
@@ -120,10 +120,6 @@
#error "FSMC not present in the selected device"
#endif
-#if STM32_NAND_USE_EXT_INT && !HAL_USE_EXT
-#error "External interrupt controller must be enabled to use this feature"
-#endif
-
#if !defined(STM32_DMA_REQUIRED)
#define STM32_DMA_REQUIRED
#endif
@@ -133,37 +129,21 @@
/*===========================================================================*/
/**
- * @brief NAND driver condition flags type.
- */
-typedef uint32_t nandflags_t;
-
-/**
* @brief Type of a structure representing an NAND driver.
*/
typedef struct NANDDriver NANDDriver;
/**
- * @brief Type of interrupt handler function
+ * @brief Type of interrupt handler function.
*/
typedef void (*nandisrhandler_t)(NANDDriver *nandp);
-#if STM32_NAND_USE_EXT_INT
-/**
- * @brief Type of function switching external interrupts on and off.
- */
-typedef void (*nandisrswitch_t)(void);
-#endif /* STM32_NAND_USE_EXT_INT */
-
/**
* @brief Driver configuration structure.
* @note It could be empty on some architectures.
*/
typedef struct {
/**
- * @brief Pointer to lower level driver.
- */
- //const FSMCDriver *fsmcp;
- /**
* @brief Number of erase blocks in NAND device.
*/
uint32_t blocks;
@@ -197,16 +177,6 @@ typedef struct {
* from STMicroelectronics.
*/
uint32_t pmem;
-#if STM32_NAND_USE_EXT_INT
- /**
- * @brief Function enabling interrupts from EXTI
- */
- nandisrswitch_t ext_nand_isr_enable;
- /**
- * @brief Function disabling interrupts from EXTI
- */
- nandisrswitch_t ext_nand_isr_disable;
-#endif /* STM32_NAND_USE_EXT_INT */
} NANDConfig;
/**
@@ -236,15 +206,15 @@ struct NANDDriver {
#endif /* NAND_USE_MUTUAL_EXCLUSION */
/* End of the mandatory fields.*/
/**
- * @brief Function enabling interrupts from FSMC
+ * @brief Function enabling interrupts from FSMC.
*/
nandisrhandler_t isr_handler;
/**
- * @brief Pointer to current transaction buffer
+ * @brief Pointer to current transaction buffer.
*/
- uint8_t *rxdata;
+ void *rxdata;
/**
- * @brief Current transaction length
+ * @brief Current transaction length in bytes.
*/
size_t datalen;
/**
@@ -266,15 +236,15 @@ struct NANDDriver {
/**
* @brief Memory mapping for data.
*/
- uint8_t *map_data;
+ uint16_t *map_data;
/**
* @brief Memory mapping for commands.
*/
- uint8_t *map_cmd;
+ uint16_t *map_cmd;
/**
* @brief Memory mapping for addresses.
*/
- uint8_t *map_addr;
+ uint16_t *map_addr;
/**
* @brief Pointer to bad block map.
* @details One bit per block. All memory allocation is user's responsibility.
@@ -304,21 +274,21 @@ extern "C" {
void nand_lld_init(void);
void nand_lld_start(NANDDriver *nandp);
void nand_lld_stop(NANDDriver *nandp);
- void nand_lld_read_data(NANDDriver *nandp, uint8_t *data,
+ uint8_t nand_lld_erase(NANDDriver *nandp, uint8_t *addr, size_t addrlen);
+ void nand_lld_read_data(NANDDriver *nandp, uint16_t *data,
size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc);
- void nand_lld_polled_read_data(NANDDriver *nandp, uint8_t *data, size_t len);
void nand_lld_write_addr(NANDDriver *nandp, const uint8_t *addr, size_t len);
void nand_lld_write_cmd(NANDDriver *nandp, uint8_t cmd);
- uint8_t nand_lld_erase(NANDDriver *nandp, uint8_t *addr, size_t addrlen);
- uint8_t nand_lld_write_data(NANDDriver *nandp, const uint8_t *data,
+ uint8_t nand_lld_write_data(NANDDriver *nandp, const uint16_t *data,
size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc);
uint8_t nand_lld_read_status(NANDDriver *nandp);
+ void nand_lld_reset(NANDDriver *nandp);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_NAND */
-#endif /* _NAND_LLD_H_ */
+#endif /* HAL_NAND_LLD_H_ */
/** @} */
diff --git a/os/hal/ports/STM32/LLD/LTDCv1/hal_stm32_ltdc.c b/os/hal/ports/STM32/LLD/LTDCv1/hal_stm32_ltdc.c
index e5f9a09..bffa472 100644
--- a/os/hal/ports/STM32/LLD/LTDCv1/hal_stm32_ltdc.c
+++ b/os/hal/ports/STM32/LLD/LTDCv1/hal_stm32_ltdc.c
@@ -15,11 +15,10 @@
*/
/**
- * @file stm32_ltdc.c
+ * @file hal_stm32_ltdc.c
* @brief LCD-TFT Controller Driver.
*/
-#include "ch.h"
#include "hal.h"
#include "hal_stm32_ltdc.h"
diff --git a/os/hal/ports/STM32/LLD/LTDCv1/hal_stm32_ltdc.h b/os/hal/ports/STM32/LLD/LTDCv1/hal_stm32_ltdc.h
index 16b38ca..5db89e2 100644
--- a/os/hal/ports/STM32/LLD/LTDCv1/hal_stm32_ltdc.h
+++ b/os/hal/ports/STM32/LLD/LTDCv1/hal_stm32_ltdc.h
@@ -15,15 +15,15 @@
*/
/**
- * @file stm32_ltdc.h
+ * @file hal_stm32_ltdc.h
* @brief LCD-TFT Controller Driver.
*
* @addtogroup ltdc
* @{
*/
-#ifndef _STM32_LTDC_H_
-#define _STM32_LTDC_H_
+#ifndef HAL_STM32_LTDC_H_
+#define HAL_STM32_LTDC_H_
/**
* @brief Using the LTDC driver.
@@ -731,6 +731,6 @@ extern "C" {
#endif /* STM32_LTDC_USE_LTDC */
-#endif /* _STM32_LTDC_H_ */
+#endif /* HAL_STM32_LTDC_H_ */
/** @} */
diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_eicu_lld.c b/os/hal/ports/STM32/LLD/TIMv1/hal_eicu_lld.c
index c04278e..ed4c5b8 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/hal_eicu_lld.c
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_eicu_lld.c
@@ -1057,75 +1057,75 @@ void eicu_lld_stop(EICUDriver *eicup) {
if (&EICUD1 == eicup) {
nvicDisableVector(STM32_TIM1_UP_NUMBER);
nvicDisableVector(STM32_TIM1_CC_NUMBER);
- rccDisableTIM1(FALSE);
+ rccDisableTIM1();
}
#endif
#if STM32_EICU_USE_TIM2
if (&EICUD2 == eicup) {
nvicDisableVector(STM32_TIM2_NUMBER);
- rccDisableTIM2(FALSE);
+ rccDisableTIM2();
}
#endif
#if STM32_EICU_USE_TIM3
if (&EICUD3 == eicup) {
nvicDisableVector(STM32_TIM3_NUMBER);
- rccDisableTIM3(FALSE);
+ rccDisableTIM3();
}
#endif
#if STM32_EICU_USE_TIM4
if (&EICUD4 == eicup) {
nvicDisableVector(STM32_TIM4_NUMBER);
- rccDisableTIM4(FALSE);
+ rccDisableTIM4();
}
#endif
#if STM32_EICU_USE_TIM5
if (&EICUD5 == eicup) {
nvicDisableVector(STM32_TIM5_NUMBER);
- rccDisableTIM5(FALSE);
+ rccDisableTIM5();
}
#endif
#if STM32_EICU_USE_TIM8
if (&EICUD8 == eicup) {
nvicDisableVector(STM32_TIM8_UP_NUMBER);
nvicDisableVector(STM32_TIM8_CC_NUMBER);
- rccDisableTIM8(FALSE);
+ rccDisableTIM8();
}
#endif
#if STM32_EICU_USE_TIM9
if (&EICUD9 == eicup) {
nvicDisableVector(STM32_TIM9_NUMBER);
- rccDisableTIM9(FALSE);
+ rccDisableTIM9();
}
#endif
#if STM32_EICU_USE_TIM12
if (&EICUD12 == eicup) {
nvicDisableVector(STM32_TIM12_NUMBER);
- rccDisableTIM12(FALSE);
+ rccDisableTIM12();
}
#endif
}
#if STM32_EICU_USE_TIM10
if (&EICUD10 == eicup) {
nvicDisableVector(STM32_TIM10_NUMBER);
- rccDisableTIM10(FALSE);
+ rccDisableTIM10();
}
#endif
#if STM32_EICU_USE_TIM11
if (&EICUD11 == eicup) {
nvicDisableVector(STM32_TIM11_NUMBER);
- rccDisableTIM11(FALSE);
+ rccDisableTIM11();
}
#endif
#if STM32_EICU_USE_TIM13
if (&EICUD13 == eicup) {
nvicDisableVector(STM32_TIM13_NUMBER);
- rccDisableTIM13(FALSE);
+ rccDisableTIM13();
}
#endif
#if STM32_EICU_USE_TIM14
if (&EICUD14 == eicup) {
nvicDisableVector(STM32_TIM14_NUMBER);
- rccDisableTIM14(FALSE);
+ rccDisableTIM14();
}
#endif
}
diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_eicu_lld.h b/os/hal/ports/STM32/LLD/TIMv1/hal_eicu_lld.h
index 927eb6f..e72098e 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/hal_eicu_lld.h
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_eicu_lld.h
@@ -22,8 +22,8 @@
32-bit timers and timers with single capture/compare channels.
*/
-#ifndef __EICU_LLD_H
-#define __EICU_LLD_H
+#ifndef HAL_EICU_LLD_H
+#define HAL_EICU_LLD_H
#include "stm32_tim.h"
@@ -551,4 +551,4 @@ extern "C" {
#endif /* HAL_USE_EICU */
-#endif /* __EICU_LLD_H */
+#endif /* HAL_EICU_LLD_H */
diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c b/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c
index ea051f7..e07b946 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c
@@ -150,6 +150,8 @@ void qei_lld_init(void) {
* @notapi
*/
void qei_lld_start(QEIDriver *qeip) {
+ osalDbgAssert((qeip->config->min == 0) || (qeip->config->max == 0),
+ "only min/max set to 0 is supported");
if (qeip->state == QEI_STOP) {
/* Clock activation and timer reset.*/
@@ -192,24 +194,24 @@ void qei_lld_start(QEIDriver *qeip) {
#endif
}
/* Timer configuration.*/
- qeip->tim->CR1 = 0; /* Initially stopped. */
+ qeip->tim->CR1 = 0; /* Initially stopped. */
qeip->tim->CR2 = 0;
qeip->tim->PSC = 0;
qeip->tim->DIER = 0;
- qeip->tim->ARR = 0xFFFF;
+ qeip->tim->ARR = 0xFFFF;
/* Set Capture Compare 1 and Capture Compare 2 as input. */
qeip->tim->CCMR1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
if (qeip->config->mode == QEI_MODE_QUADRATURE) {
if (qeip->config->resolution == QEI_BOTH_EDGES)
- qeip->tim->SMCR = TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0;
+ qeip->tim->SMCR = TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0;
else
- qeip->tim->SMCR = TIM_SMCR_SMS_0;
+ qeip->tim->SMCR = TIM_SMCR_SMS_0;
} else {
/* Direction/Clock mode.
* Direction input on TI1, Clock input on TI2. */
- qeip->tim->SMCR = TIM_SMCR_SMS_0;
+ qeip->tim->SMCR = TIM_SMCR_SMS_0;
}
if (qeip->config->dirinv == QEI_DIRINV_TRUE)
@@ -228,38 +230,38 @@ void qei_lld_start(QEIDriver *qeip) {
void qei_lld_stop(QEIDriver *qeip) {
if (qeip->state == QEI_READY) {
- qeip->tim->CR1 = 0; /* Timer disabled. */
+ qeip->tim->CR1 = 0; /* Timer disabled. */
/* Clock deactivation.*/
#if STM32_QEI_USE_TIM1
if (&QEID1 == qeip) {
- rccDisableTIM1(FALSE);
+ rccDisableTIM1();
}
#endif
#if STM32_QEI_USE_TIM2
if (&QEID2 == qeip) {
- rccDisableTIM2(FALSE);
+ rccDisableTIM2();
}
#endif
#if STM32_QEI_USE_TIM3
if (&QEID3 == qeip) {
- rccDisableTIM3(FALSE);
+ rccDisableTIM3();
}
#endif
#if STM32_QEI_USE_TIM4
if (&QEID4 == qeip) {
- rccDisableTIM4(FALSE);
+ rccDisableTIM4();
}
#endif
#if STM32_QEI_USE_TIM5
if (&QEID5 == qeip) {
- rccDisableTIM5(FALSE);
+ rccDisableTIM5();
}
#endif
}
#if STM32_QEI_USE_TIM8
if (&QEID8 == qeip) {
- rccDisableTIM8(FALSE);
+ rccDisableTIM8();
}
#endif
}
@@ -273,7 +275,7 @@ void qei_lld_stop(QEIDriver *qeip) {
*/
void qei_lld_enable(QEIDriver *qeip) {
- qeip->tim->CR1 = TIM_CR1_CEN; /* Timer enabled. */
+ qeip->tim->CR1 = TIM_CR1_CEN; /* Timer enabled. */
}
/**
@@ -285,7 +287,7 @@ void qei_lld_enable(QEIDriver *qeip) {
*/
void qei_lld_disable(QEIDriver *qeip) {
- qeip->tim->CR1 = 0; /* Timer disabled. */
+ qeip->tim->CR1 = 0; /* Timer disabled. */
}
#endif /* HAL_USE_QEI */
diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.h b/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.h
index d0cb683..73468f5 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.h
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.h
@@ -33,6 +33,16 @@
/* Driver constants. */
/*===========================================================================*/
+/**
+ * @brief Mininum usable value for defining counter underflow
+ */
+#define QEI_COUNT_MIN (0)
+
+/**
+ * @brief Maximum usable value for defining counter overflow
+ */
+#define QEI_COUNT_MAX (65535)
+
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@@ -172,6 +182,56 @@
#error "QEI driver activated but no TIM peripheral assigned"
#endif
+/* Checks on allocation of TIMx units.*/
+#if STM32_QEI_USE_TIM1
+#if defined(STM32_TIM1_IS_USED)
+#error "QEID1 requires TIM1 but the timer is already used"
+#else
+#define STM32_TIM1_IS_USED
+#endif
+#endif
+
+#if STM32_QEI_USE_TIM2
+#if defined(STM32_TIM2_IS_USED)
+#error "QEID2 requires TIM2 but the timer is already used"
+#else
+#define STM32_TIM2_IS_USED
+#endif
+#endif
+
+#if STM32_QEI_USE_TIM3
+#if defined(STM32_TIM3_IS_USED)
+#error "QEID3 requires TIM3 but the timer is already used"
+#else
+#define STM32_TIM3_IS_USED
+#endif
+#endif
+
+#if STM32_QEI_USE_TIM4
+#if defined(STM32_TIM4_IS_USED)
+#error "QEID4 requires TIM4 but the timer is already used"
+#else
+#define STM32_TIM4_IS_USED
+#endif
+#endif
+
+#if STM32_QEI_USE_TIM5
+#if defined(STM32_TIM5_IS_USED)
+#error "QEID5 requires TIM5 but the timer is already used"
+#else
+#define STM32_TIM5_IS_USED
+#endif
+#endif
+
+#if STM32_QEI_USE_TIM8
+#if defined(STM32_TIM8_IS_USED)
+#error "QEID8 requires TIM8 but the timer is already used"
+#else
+#define STM32_TIM8_IS_USED
+#endif
+#endif
+
+/* IRQ priority checks.*/
#if STM32_QEI_USE_TIM1 && \
!OSAL_IRQ_IS_VALID_PRIORITY(STM32_QEI_TIM1_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM1"
@@ -202,6 +262,14 @@
#error "Invalid IRQ priority assigned to TIM8"
#endif
+#if QEI_USE_OVERFLOW_DISCARD
+#error "QEI_USE_OVERFLOW_DISCARD not supported by this driver"
+#endif
+
+#if QEI_USE_OVERFLOW_MINMAX
+#error "QEI_USE_OVERFLOW_MINMAX not supported by this driver"
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@@ -233,7 +301,7 @@ typedef enum {
/**
* @brief QEI counter type.
*/
-typedef uint16_t qeicnt_t;
+typedef int16_t qeicnt_t;
/**
* @brief QEI delta type.
@@ -257,6 +325,45 @@ typedef struct {
* @brief Direction inversion.
*/
qeidirinv_t dirinv;
+ /**
+ * @brief Handling of counter overflow/underflow
+ *
+ * @details When overflow occurs, the counter value is updated
+ * according to:
+ * - QEI_OVERFLOW_DISCARD:
+ * discard the update value, counter doesn't change
+ */
+ qeioverflow_t overflow;
+ /**
+ * @brief Min count value.
+ *
+ * @note If min == max, then QEI_COUNT_MIN is used.
+ *
+ * @note Only min set to 0 / QEI_COUNT_MIN is supported.
+ */
+ qeicnt_t min;
+ /**
+ * @brief Max count value.
+ *
+ * @note If min == max, then QEI_COUNT_MAX is used.
+ *
+ * @note Only max set to 0 / QEI_COUNT_MAX is supported.
+ */
+ qeicnt_t max;
+ /**
+ * @brief Notify of value change
+ *
+ * @note Called from ISR context.
+ */
+ qeicallback_t notify_cb;
+ /**
+ * @brief Notify of overflow
+ *
+ * @note Overflow notification is performed after
+ * value changed notification.
+ * @note Called from ISR context.
+ */
+ void (*overflow_cb)(QEIDriver *qeip, qeidelta_t delta);
/* End of the mandatory fields.*/
} QEIConfig;
@@ -300,6 +407,16 @@ struct QEIDriver {
*/
#define qei_lld_get_count(qeip) ((qeip)->tim->CNT)
+/**
+ * @brief Set the counter value.
+ *
+ * @param[in] qeip pointer to the @p QEIDriver object
+ * @param[in] qeip counter value
+ *
+ * @notapi
+ */
+#define qei_lld_set_count(qeip, value)
+
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_timcap_lld.c b/os/hal/ports/STM32/LLD/TIMv1/hal_timcap_lld.c
index 8ab6176..d95c6a3 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/hal_timcap_lld.c
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_timcap_lld.c
@@ -24,14 +24,13 @@
/**
- * @file STM32/timcap_lld.c
+ * @file STM32/hal_timcap_lld.c
* @brief STM32 TIMCAP subsystem low level driver header.
*
* @addtogroup TIMCAP
* @{
*/
-#include "ch.h"
#include "hal.h"
#if HAL_USE_TIMCAP || defined(__DOXYGEN__)
@@ -714,44 +713,44 @@ void timcap_lld_stop(TIMCAPDriver *timcapp) {
if (&TIMCAPD1 == timcapp) {
nvicDisableVector(STM32_TIM1_UP_NUMBER);
nvicDisableVector(STM32_TIM1_CC_NUMBER);
- rccDisableTIM1(FALSE);
+ rccDisableTIM1();
}
#endif
#if STM32_TIMCAP_USE_TIM2
if (&TIMCAPD2 == timcapp) {
nvicDisableVector(STM32_TIM2_NUMBER);
- rccDisableTIM2(FALSE);
+ rccDisableTIM2();
}
#endif
#if STM32_TIMCAP_USE_TIM3
if (&TIMCAPD3 == timcapp) {
nvicDisableVector(STM32_TIM3_NUMBER);
- rccDisableTIM3(FALSE);
+ rccDisableTIM3();
}
#endif
#if STM32_TIMCAP_USE_TIM4
if (&TIMCAPD4 == timcapp) {
nvicDisableVector(STM32_TIM4_NUMBER);
- rccDisableTIM4(FALSE);
+ rccDisableTIM4();
}
#endif
#if STM32_TIMCAP_USE_TIM5
if (&TIMCAPD5 == timcapp) {
nvicDisableVector(STM32_TIM5_NUMBER);
- rccDisableTIM5(FALSE);
+ rccDisableTIM5();
}
#endif
#if STM32_TIMCAP_USE_TIM8
if (&TIMCAPD8 == timcapp) {
nvicDisableVector(STM32_TIM8_UP_NUMBER);
nvicDisableVector(STM32_TIM8_CC_NUMBER);
- rccDisableTIM8(FALSE);
+ rccDisableTIM8();
}
#endif
#if STM32_TIMCAP_USE_TIM9
if (&TIMCAPD9 == timcapp) {
nvicDisableVector(STM32_TIM9_NUMBER);
- rccDisableTIM9(FALSE);
+ rccDisableTIM9();
}
#endif
}
diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_timcap_lld.h b/os/hal/ports/STM32/LLD/TIMv1/hal_timcap_lld.h
index d39c438..621313a 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/hal_timcap_lld.h
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_timcap_lld.h
@@ -22,10 +22,9 @@
* @{
*/
-#ifndef _TIMCAP_LLD_H_
-#define _TIMCAP_LLD_H_
+#ifndef HAL_TIMCAP_LLD_H_
+#define HAL_TIMCAP_LLD_H_
-#include "ch.h"
#include "hal.h"
#include "stm32_tim.h"
diff --git a/os/hal/ports/STM32/LLD/USBHv1/hal_stm32_otg.h b/os/hal/ports/STM32/LLD/USBHv1/hal_stm32_otg.h
deleted file mode 100644
index ca2dc49..0000000
--- a/os/hal/ports/STM32/LLD/USBHv1/hal_stm32_otg.h
+++ /dev/null
@@ -1,929 +0,0 @@
-/*
- ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-/**
- * @file stm32_otg.h
- * @brief STM32 OTG registers layout header.
- *
- * @addtogroup USB
- * @{
- */
-
-
-#ifndef _STM32_OTG_H_
-#define _STM32_OTG_H_
-
-/**
- * @brief Number of the implemented endpoints in OTG_FS.
- * @details This value does not include the endpoint 0 that is always present.
- */
-#define STM32_OTG1_ENDOPOINTS_NUMBER 3
-
-/**
- * @brief Number of the implemented endpoints in OTG_HS.
- * @details This value does not include the endpoint 0 that is always present.
- */
-#define STM32_OTG2_ENDOPOINTS_NUMBER 5
-
-/**
- * @brief OTG_FS FIFO memory size in words.
- */
-#define STM32_OTG1_FIFO_MEM_SIZE 320
-
-/**
- * @brief OTG_HS FIFO memory size in words.
- */
-#define STM32_OTG2_FIFO_MEM_SIZE 1024
-
-/**
- * @brief Host channel registers group.
- */
-typedef struct {
- volatile uint32_t HCCHAR; /**< @brief Host channel characteristics
- register. */
- volatile uint32_t resvd8;
- volatile uint32_t HCINT; /**< @brief Host channel interrupt register.*/
- volatile uint32_t HCINTMSK; /**< @brief Host channel interrupt mask
- register. */
- volatile uint32_t HCTSIZ; /**< @brief Host channel transfer size
- register. */
- volatile uint32_t resvd14;
- volatile uint32_t resvd18;
- volatile uint32_t resvd1c;
-} stm32_otg_host_chn_t;
-
-/**
- * @brief Device input endpoint registers group.
- */
-typedef struct {
- volatile uint32_t DIEPCTL; /**< @brief Device control IN endpoint
- control register. */
- volatile uint32_t resvd4;
- volatile uint32_t DIEPINT; /**< @brief Device IN endpoint interrupt
- register. */
- volatile uint32_t resvdC;
- volatile uint32_t DIEPTSIZ; /**< @brief Device IN endpoint transfer size
- register. */
- volatile uint32_t resvd14;
- volatile uint32_t DTXFSTS; /**< @brief Device IN endpoint transmit FIFO
- status register. */
- volatile uint32_t resvd1C;
-} stm32_otg_in_ep_t;
-
-/**
- * @brief Device output endpoint registers group.
- */
-typedef struct {
- volatile uint32_t DOEPCTL; /**< @brief Device control OUT endpoint
- control register. */
- volatile uint32_t resvd4;
- volatile uint32_t DOEPINT; /**< @brief Device OUT endpoint interrupt
- register. */
- volatile uint32_t resvdC;
- volatile uint32_t DOEPTSIZ; /**< @brief Device OUT endpoint transfer
- size register. */
- volatile uint32_t resvd14;
- volatile uint32_t resvd18;
- volatile uint32_t resvd1C;
-} stm32_otg_out_ep_t;
-
-/**
- * @brief USB registers memory map.
- */
-typedef struct {
- volatile uint32_t GOTGCTL; /**< @brief OTG control and status register.*/
- volatile uint32_t GOTGINT; /**< @brief OTG interrupt register. */
- volatile uint32_t GAHBCFG; /**< @brief AHB configuration register. */
- volatile uint32_t GUSBCFG; /**< @brief USB configuration register. */
- volatile uint32_t GRSTCTL; /**< @brief Reset register size. */
- volatile uint32_t GINTSTS; /**< @brief Interrupt register. */
- volatile uint32_t GINTMSK; /**< @brief Interrupt mask register. */
- volatile uint32_t GRXSTSR; /**< @brief Receive status debug read
- register. */
- volatile uint32_t GRXSTSP; /**< @brief Receive status read/pop
- register. */
- volatile uint32_t GRXFSIZ; /**< @brief Receive FIFO size register. */
- volatile uint32_t DIEPTXF0; /**< @brief Endpoint 0 transmit FIFO size
- register. */
- volatile uint32_t HNPTXSTS; /**< @brief Non-periodic transmit FIFO/queue
- status register. */
- volatile uint32_t resvd30;
- volatile uint32_t resvd34;
- volatile uint32_t GCCFG; /**< @brief General core configuration. */
- volatile uint32_t CID; /**< @brief Core ID register. */
- volatile uint32_t resvd58[48];
- volatile uint32_t HPTXFSIZ; /**< @brief Host periodic transmit FIFO size
- register. */
- volatile uint32_t DIEPTXF[15];/**< @brief Device IN endpoint transmit FIFO
- size registers. */
- volatile uint32_t resvd140[176];
- volatile uint32_t HCFG; /**< @brief Host configuration register. */
- volatile uint32_t HFIR; /**< @brief Host frame interval register. */
- volatile uint32_t HFNUM; /**< @brief Host frame number/frame time
- Remaining register. */
- volatile uint32_t resvd40C;
- volatile uint32_t HPTXSTS; /**< @brief Host periodic transmit FIFO/queue
- status register. */
- volatile uint32_t HAINT; /**< @brief Host all channels interrupt
- register. */
- volatile uint32_t HAINTMSK; /**< @brief Host all channels interrupt mask
- register. */
- volatile uint32_t resvd41C[9];
- volatile uint32_t HPRT; /**< @brief Host port control and status
- register. */
- volatile uint32_t resvd444[47];
- stm32_otg_host_chn_t hc[16]; /**< @brief Host channels array. */
- volatile uint32_t resvd700[64];
- volatile uint32_t DCFG; /**< @brief Device configuration register. */
- volatile uint32_t DCTL; /**< @brief Device control register. */
- volatile uint32_t DSTS; /**< @brief Device status register. */
- volatile uint32_t resvd80C;
- volatile uint32_t DIEPMSK; /**< @brief Device IN endpoint common
- interrupt mask register. */
- volatile uint32_t DOEPMSK; /**< @brief Device OUT endpoint common
- interrupt mask register. */
- volatile uint32_t DAINT; /**< @brief Device all endpoints interrupt
- register. */
- volatile uint32_t DAINTMSK; /**< @brief Device all endpoints interrupt
- mask register. */
- volatile uint32_t resvd820;
- volatile uint32_t resvd824;
- volatile uint32_t DVBUSDIS; /**< @brief Device VBUS discharge time
- register. */
- volatile uint32_t DVBUSPULSE; /**< @brief Device VBUS pulsing time
- register. */
- volatile uint32_t resvd830;
- volatile uint32_t DIEPEMPMSK; /**< @brief Device IN endpoint FIFO empty
- interrupt mask register. */
- volatile uint32_t resvd838;
- volatile uint32_t resvd83C;
- volatile uint32_t resvd840[16];
- volatile uint32_t resvd880[16];
- volatile uint32_t resvd8C0[16];
- stm32_otg_in_ep_t ie[16]; /**< @brief Input endpoints. */
- stm32_otg_out_ep_t oe[16]; /**< @brief Output endpoints. */
- volatile uint32_t resvdD00[64];
- volatile uint32_t PCGCCTL; /**< @brief Power and clock gating control
- register. */
- volatile uint32_t resvdE04[127];
- volatile uint32_t FIFO[16][1024];
-} stm32_otg_t;
-
-/**
- * @name GOTGCTL register bit definitions
- * @{
- */
-#define GOTGCTL_BSVLD (1U<<19) /**< B-Session Valid. */
-#define GOTGCTL_ASVLD (1U<<18) /**< A-Session Valid. */
-#define GOTGCTL_DBCT (1U<<17) /**< Long/Short debounce time. */
-#define GOTGCTL_CIDSTS (1U<<16) /**< Connector ID status. */
-#define GOTGCTL_EHEN (1U<<12)
-#define GOTGCTL_DHNPEN (1U<<11) /**< Device HNP enabled. */
-#define GOTGCTL_HSHNPEN (1U<<10) /**< Host Set HNP enable. */
-#define GOTGCTL_HNPRQ (1U<<9) /**< HNP request. */
-#define GOTGCTL_HNGSCS (1U<<8) /**< Host negotiation success. */
-#define GOTGCTL_BVALOVAL (1U<<7)
-#define GOTGCTL_BVALOEN (1U<<6)
-#define GOTGCTL_AVALOVAL (1U<<5)
-#define GOTGCTL_AVALOEN (1U<<4)
-#define GOTGCTL_VBVALOVAL (1U<<3)
-#define GOTGCTL_VBVALOEN (1U<<2)
-#define GOTGCTL_SRQ (1U<<1) /**< Session request. */
-#define GOTGCTL_SRQSCS (1U<<0) /**< Session request success. */
-/** @} */
-
-/**
- * @name GOTGINT register bit definitions
- * @{
- */
-#define GOTGINT_DBCDNE (1U<<19) /**< Debounce done. */
-#define GOTGINT_ADTOCHG (1U<<18) /**< A-Device timeout change. */
-#define GOTGINT_HNGDET (1U<<17) /**< Host negotiation detected. */
-#define GOTGINT_HNSSCHG (1U<<9) /**< Host negotiation success
- status change. */
-#define GOTGINT_SRSSCHG (1U<<8) /**< Session request success
- status change. */
-#define GOTGINT_SEDET (1U<<2) /**< Session end detected. */
-/** @} */
-
-/**
- * @name GAHBCFG register bit definitions
- * @{
- */
-#define GAHBCFG_PTXFELVL (1U<<8) /**< Periodic TxFIFO empty
- level. */
-#define GAHBCFG_TXFELVL (1U<<7) /**< Non-periodic TxFIFO empty
- level. */
-#define GAHBCFG_DMAEN (1U<<5) /**< DMA enable (HS only). */
-#define GAHBCFG_HBSTLEN_MASK (15U<<1) /**< Burst length/type mask (HS
- only). */
-#define GAHBCFG_HBSTLEN(n) ((n)<<1) /**< Burst length/type (HS
- only). */
-#define GAHBCFG_GINTMSK (1U<<0) /**< Global interrupt mask. */
-/** @} */
-
-/**
- * @name GUSBCFG register bit definitions
- * @{
- */
-#define GUSBCFG_CTXPKT (1U<<31) /**< Corrupt Tx packet. */
-#define GUSBCFG_FDMOD (1U<<30) /**< Force Device Mode. */
-#define GUSBCFG_FHMOD (1U<<29) /**< Force Host Mode. */
-#define GUSBCFG_TRDT_MASK (15U<<10) /**< USB Turnaround time field
- mask. */
-#define GUSBCFG_TRDT(n) ((n)<<10) /**< USB Turnaround time field
- value. */
-#define GUSBCFG_HNPCAP (1U<<9) /**< HNP-Capable. */
-#define GUSBCFG_SRPCAP (1U<<8) /**< SRP-Capable. */
-#define GUSBCFG_PHYSEL (1U<<6) /**< USB 2.0 High-Speed PHY or
- USB 1.1 Full-Speed serial
- transceiver Select. */
-#define GUSBCFG_TOCAL_MASK (7U<<0) /**< HS/FS timeout calibration
- field mask. */
-#define GUSBCFG_TOCAL(n) ((n)<<0) /**< HS/FS timeout calibration
- field value. */
-/** @} */
-
-/**
- * @name GRSTCTL register bit definitions
- * @{
- */
-#define GRSTCTL_AHBIDL (1U<<31) /**< AHB Master Idle. */
-#define GRSTCTL_TXFNUM_MASK (31U<<6) /**< TxFIFO number field mask. */
-#define GRSTCTL_TXFNUM(n) ((n)<<6) /**< TxFIFO number field value. */
-#define GRSTCTL_TXFFLSH (1U<<5) /**< TxFIFO flush. */
-#define GRSTCTL_RXFFLSH (1U<<4) /**< RxFIFO flush. */
-#define GRSTCTL_FCRST (1U<<2) /**< Host frame counter reset. */
-#define GRSTCTL_HSRST (1U<<1) /**< HClk soft reset. */
-#define GRSTCTL_CSRST (1U<<0) /**< Core soft reset. */
-/** @} */
-
-/**
- * @name GINTSTS register bit definitions
- * @{
- */
-#define GINTSTS_WKUPINT (1U<<31) /**< Resume/Remote wakeup
- detected interrupt. */
-#define GINTSTS_SRQINT (1U<<30) /**< Session request/New session
- detected interrupt. */
-#define GINTSTS_DISCINT (1U<<29) /**< Disconnect detected
- interrupt. */
-#define GINTSTS_CIDSCHG (1U<<28) /**< Connector ID status change.*/
-#define GINTSTS_PTXFE (1U<<26) /**< Periodic TxFIFO empty. */
-#define GINTSTS_HCINT (1U<<25) /**< Host channels interrupt. */
-#define GINTSTS_HPRTINT (1U<<24) /**< Host port interrupt. */
-#define GINTSTS_IPXFR (1U<<21) /**< Incomplete periodic
- transfer. */
-#define GINTSTS_IISOOXFR (1U<<21) /**< Incomplete isochronous OUT
- transfer. */
-#define GINTSTS_IISOIXFR (1U<<20) /**< Incomplete isochronous IN
- transfer. */
-#define GINTSTS_OEPINT (1U<<19) /**< OUT endpoints interrupt. */
-#define GINTSTS_IEPINT (1U<<18) /**< IN endpoints interrupt. */
-#define GINTSTS_EOPF (1U<<15) /**< End of periodic frame
- interrupt. */
-#define GINTSTS_ISOODRP (1U<<14) /**< Isochronous OUT packet
- dropped interrupt. */
-#define GINTSTS_ENUMDNE (1U<<13) /**< Enumeration done. */
-#define GINTSTS_USBRST (1U<<12) /**< USB reset. */
-#define GINTSTS_USBSUSP (1U<<11) /**< USB suspend. */
-#define GINTSTS_ESUSP (1U<<10) /**< Early suspend. */
-#define GINTSTS_GONAKEFF (1U<<7) /**< Global OUT NAK effective. */
-#define GINTSTS_GINAKEFF (1U<<6) /**< Global IN non-periodic NAK
- effective. */
-#define GINTSTS_NPTXFE (1U<<5) /**< Non-periodic TxFIFO empty. */
-#define GINTSTS_RXFLVL (1U<<4) /**< RxFIFO non-empty. */
-#define GINTSTS_SOF (1U<<3) /**< Start of frame. */
-#define GINTSTS_OTGINT (1U<<2) /**< OTG interrupt. */
-#define GINTSTS_MMIS (1U<<1) /**< Mode Mismatch interrupt. */
-#define GINTSTS_CMOD (1U<<0) /**< Current mode of operation. */
-/** @} */
-
-/**
- * @name GINTMSK register bit definitions
- * @{
- */
-#define GINTMSK_WKUM (1U<<31) /**< Resume/remote wakeup
- detected interrupt mask. */
-#define GINTMSK_SRQM (1U<<30) /**< Session request/New session
- detected interrupt mask. */
-#define GINTMSK_DISCM (1U<<29) /**< Disconnect detected
- interrupt mask. */
-#define GINTMSK_CIDSCHGM (1U<<28) /**< Connector ID status change
- mask. */
-#define GINTMSK_PTXFEM (1U<<26) /**< Periodic TxFIFO empty mask.*/
-#define GINTMSK_HCM (1U<<25) /**< Host channels interrupt
- mask. */
-#define GINTMSK_HPRTM (1U<<24) /**< Host port interrupt mask. */
-#define GINTMSK_IPXFRM (1U<<21) /**< Incomplete periodic
- transfer mask. */
-#define GINTMSK_IISOOXFRM (1U<<21) /**< Incomplete isochronous OUT
- transfer mask. */
-#define GINTMSK_IISOIXFRM (1U<<20) /**< Incomplete isochronous IN
- transfer mask. */
-#define GINTMSK_OEPM (1U<<19) /**< OUT endpoints interrupt
- mask. */
-#define GINTMSK_IEPM (1U<<18) /**< IN endpoints interrupt
- mask. */
-#define GINTMSK_EOPFM (1U<<15) /**< End of periodic frame
- interrupt mask. */
-#define GINTMSK_ISOODRPM (1U<<14) /**< Isochronous OUT packet
- dropped interrupt mask. */
-#define GINTMSK_ENUMDNEM (1U<<13) /**< Enumeration done mask. */
-#define GINTMSK_USBRSTM (1U<<12) /**< USB reset mask. */
-#define GINTMSK_USBSUSPM (1U<<11) /**< USB suspend mask. */
-#define GINTMSK_ESUSPM (1U<<10) /**< Early suspend mask. */
-#define GINTMSK_GONAKEFFM (1U<<7) /**< Global OUT NAK effective
- mask. */
-#define GINTMSK_GINAKEFFM (1U<<6) /**< Global non-periodic IN NAK
- effective mask. */
-#define GINTMSK_NPTXFEM (1U<<5) /**< Non-periodic TxFIFO empty
- mask. */
-#define GINTMSK_RXFLVLM (1U<<4) /**< Receive FIFO non-empty
- mask. */
-#define GINTMSK_SOFM (1U<<3) /**< Start of (micro)frame mask.*/
-#define GINTMSK_OTGM (1U<<2) /**< OTG interrupt mask. */
-#define GINTMSK_MMISM (1U<<1) /**< Mode Mismatch interrupt
- mask. */
-/** @} */
-
-/**
- * @name GRXSTSR register bit definitions
- * @{
- */
-#define GRXSTSR_PKTSTS_MASK (15U<<17) /**< Packet status mask. */
-#define GRXSTSR_PKTSTS(n) ((n)<<17) /**< Packet status value. */
-#define GRXSTSR_OUT_GLOBAL_NAK GRXSTSR_PKTSTS(1)
-#define GRXSTSR_OUT_DATA GRXSTSR_PKTSTS(2)
-#define GRXSTSR_OUT_COMP GRXSTSR_PKTSTS(3)
-#define GRXSTSR_SETUP_COMP GRXSTSR_PKTSTS(4)
-#define GRXSTSR_SETUP_DATA GRXSTSR_PKTSTS(6)
-#define GRXSTSR_DPID_MASK (3U<<15) /**< Data PID mask. */
-#define GRXSTSR_DPID(n) ((n)<<15) /**< Data PID value. */
-#define GRXSTSR_BCNT_MASK (0x7FF<<4) /**< Byte count mask. */
-#define GRXSTSR_BCNT(n) ((n)<<4) /**< Byte count value. */
-#define GRXSTSR_CHNUM_MASK (15U<<0) /**< Channel number mask. */
-#define GRXSTSR_CHNUM(n) ((n)<<0) /**< Channel number value. */
-#define GRXSTSR_EPNUM_MASK (15U<<0) /**< Endpoint number mask. */
-#define GRXSTSR_EPNUM(n) ((n)<<0) /**< Endpoint number value. */
-/** @} */
-
-/**
- * @name GRXSTSP register bit definitions
- * @{
- */
-#define GRXSTSP_PKTSTS_MASK (15<<17) /**< Packet status mask. */
-#define GRXSTSP_PKTSTS(n) ((n)<<17) /**< Packet status value. */
-#define GRXSTSP_OUT_GLOBAL_NAK GRXSTSP_PKTSTS(1)
-#define GRXSTSP_OUT_DATA GRXSTSP_PKTSTS(2)
-#define GRXSTSP_OUT_COMP GRXSTSP_PKTSTS(3)
-#define GRXSTSP_SETUP_COMP GRXSTSP_PKTSTS(4)
-#define GRXSTSP_SETUP_DATA GRXSTSP_PKTSTS(6)
-#define GRXSTSP_DPID_MASK (3U<<15) /**< Data PID mask. */
-#define GRXSTSP_DPID(n) ((n)<<15) /**< Data PID value. */
-#define GRXSTSP_BCNT_MASK (0x7FF<<4) /**< Byte count mask. */
-#define GRXSTSP_BCNT_OFF 4 /**< Byte count offset. */
-#define GRXSTSP_BCNT(n) ((n)<<4) /**< Byte count value. */
-#define GRXSTSP_CHNUM_MASK (15U<<0) /**< Channel number mask. */
-#define GRXSTSP_CHNUM(n) ((n)<<0) /**< Channel number value. */
-#define GRXSTSP_EPNUM_MASK (15U<<0) /**< Endpoint number mask. */
-#define GRXSTSP_EPNUM_OFF 0 /**< Endpoint number offset. */
-#define GRXSTSP_EPNUM(n) ((n)<<0) /**< Endpoint number value. */
-/** @} */
-
-/**
- * @name GRXFSIZ register bit definitions
- * @{
- */
-#define GRXFSIZ_RXFD_MASK (0xFFFF<<0) /**< RxFIFO depth mask. */
-#define GRXFSIZ_RXFD(n) ((n)<<0) /**< RxFIFO depth value. */
-/** @} */
-
-/**
- * @name DIEPTXFx register bit definitions
- * @{
- */
-#define DIEPTXF_INEPTXFD_MASK (0xFFFFU<<16)/**< IN endpoint TxFIFO depth
- mask. */
-#define DIEPTXF_INEPTXFD(n) ((n)<<16) /**< IN endpoint TxFIFO depth
- value. */
-#define DIEPTXF_INEPTXSA_MASK (0xFFFF<<0) /**< IN endpoint FIFOx transmit
- RAM start address mask. */
-#define DIEPTXF_INEPTXSA(n) ((n)<<0) /**< IN endpoint FIFOx transmit
- RAM start address value. */
-/** @} */
-
-/**
- * @name GCCFG register bit definitions
- * @{
- */
-#define GCCFG_NOVBUSSENS (1U<<21) /**< VBUS sensing disable. */
-#define GCCFG_SOFOUTEN (1U<<20) /**< SOF output enable. */
-#define GCCFG_VBUSBSEN (1U<<19) /**< Enable the VBUS sensing "B"
- device. */
-#define GCCFG_VBUSASEN (1U<<18) /**< Enable the VBUS sensing "A"
- device. */
-#define GCCFG_PWRDWN (1U<<16) /**< Power down. */
-/** @} */
-
-/**
- * @name HPTXFSIZ register bit definitions
- * @{
- */
-#define HPTXFSIZ_PTXFD_MASK (0xFFFFU<<16)/**< Host periodic TxFIFO
- depth mask. */
-#define HPTXFSIZ_PTXFD(n) ((n)<<16) /**< Host periodic TxFIFO
- depth value. */
-#define HPTXFSIZ_PTXSA_MASK (0xFFFFU<<0)/**< Host periodic TxFIFO
- Start address mask. */
-#define HPTXFSIZ_PTXSA(n) ((n)<<0) /**< Host periodic TxFIFO
- start address value. */
-/** @} */
-
-/**
- * @name HCFG register bit definitions
- * @{
- */
-#define HCFG_FSLSS (1U<<2) /**< FS- and LS-only support. */
-#define HCFG_FSLSPCS_MASK (3U<<0) /**< FS/LS PHY clock select
- mask. */
-#define HCFG_FSLSPCS_48 (1U<<0) /**< PHY clock is running at
- 48 MHz. */
-#define HCFG_FSLSPCS_6 (2U<<0) /**< PHY clock is running at
- 6 MHz. */
-/** @} */
-
-/**
- * @name HFIR register bit definitions
- * @{
- */
-#define HFIR_FRIVL_MASK (0xFFFFU<<0)/**< Frame interval mask. */
-#define HFIR_FRIVL(n) ((n)<<0) /**< Frame interval value. */
-/** @} */
-
-/**
- * @name HFNUM register bit definitions
- * @{
- */
-#define HFNUM_FTREM_MASK (0xFFFFU<<16)/**< Frame time Remaining mask.*/
-#define HFNUM_FTREM(n) ((n)<<16) /**< Frame time Remaining value.*/
-#define HFNUM_FRNUM_MASK (0xFFFFU<<0)/**< Frame number mask. */
-#define HFNUM_FRNUM(n) ((n)<<0) /**< Frame number value. */
-/** @} */
-
-/**
- * @name HPTXSTS register bit definitions
- * @{
- */
-#define HPTXSTS_PTXQTOP_MASK (0xFFU<<24) /**< Top of the periodic
- transmit request queue
- mask. */
-#define HPTXSTS_PTXQTOP(n) ((n)<<24) /**< Top of the periodic
- transmit request queue
- value. */
-#define HPTXSTS_PTXQSAV_MASK (0xFF<<16) /**< Periodic transmit request
- queue Space Available
- mask. */
-#define HPTXSTS_PTXQSAV(n) ((n)<<16) /**< Periodic transmit request
- queue Space Available
- value. */
-#define HPTXSTS_PTXFSAVL_MASK (0xFFFF<<0) /**< Periodic transmit Data
- FIFO Space Available
- mask. */
-#define HPTXSTS_PTXFSAVL(n) ((n)<<0) /**< Periodic transmit Data
- FIFO Space Available
- value. */
-/** @} */
-
-/**
- * @name HAINT register bit definitions
- * @{
- */
-#define HAINT_HAINT_MASK (0xFFFFU<<0)/**< Channel interrupts mask. */
-#define HAINT_HAINT(n) ((n)<<0) /**< Channel interrupts value. */
-/** @} */
-
-/**
- * @name HAINTMSK register bit definitions
- * @{
- */
-#define HAINTMSK_HAINTM_MASK (0xFFFFU<<0)/**< Channel interrupt mask
- mask. */
-#define HAINTMSK_HAINTM(n) ((n)<<0) /**< Channel interrupt mask
- value. */
-/** @} */
-
-/**
- * @name HPRT register bit definitions
- * @{
- */
-#define HPRT_PSPD_MASK (3U<<17) /**< Port speed mask. */
-#define HPRT_PSPD_FS (1U<<17) /**< Full speed value. */
-#define HPRT_PSPD_LS (2U<<17) /**< Low speed value. */
-#define HPRT_PTCTL_MASK (15<<13) /**< Port Test control mask. */
-#define HPRT_PTCTL(n) ((n)<<13) /**< Port Test control value. */
-#define HPRT_PPWR (1U<<12) /**< Port power. */
-#define HPRT_PLSTS_MASK (3U<<11) /**< Port Line status mask. */
-#define HPRT_PLSTS_DM (1U<<11) /**< Logic level of D-. */
-#define HPRT_PLSTS_DP (1U<<10) /**< Logic level of D+. */
-#define HPRT_PRST (1U<<8) /**< Port reset. */
-#define HPRT_PSUSP (1U<<7) /**< Port suspend. */
-#define HPRT_PRES (1U<<6) /**< Port Resume. */
-#define HPRT_POCCHNG (1U<<5) /**< Port overcurrent change. */
-#define HPRT_POCA (1U<<4) /**< Port overcurrent active. */
-#define HPRT_PENCHNG (1U<<3) /**< Port enable/disable change.*/
-#define HPRT_PENA (1U<<2) /**< Port enable. */
-#define HPRT_PCDET (1U<<1) /**< Port Connect detected. */
-#define HPRT_PCSTS (1U<<0) /**< Port connect status. */
-/** @} */
-
-/**
- * @name HCCHAR register bit definitions
- * @{
- */
-#define HCCHAR_CHENA (1U<<31) /**< Channel enable. */
-#define HCCHAR_CHDIS (1U<<30) /**< Channel Disable. */
-#define HCCHAR_ODDFRM (1U<<29) /**< Odd frame. */
-#define HCCHAR_DAD_MASK (0x7FU<<22) /**< Device Address mask. */
-#define HCCHAR_DAD(n) ((n)<<22) /**< Device Address value. */
-#define HCCHAR_MCNT_MASK (3U<<20) /**< Multicount mask. */
-#define HCCHAR_MCNT(n) ((n)<<20) /**< Multicount value. */
-#define HCCHAR_EPTYP_MASK (3U<<18) /**< Endpoint type mask. */
-#define HCCHAR_EPTYP(n) ((n)<<18) /**< Endpoint type value. */
-#define HCCHAR_EPTYP_CTL (0U<<18) /**< Control endpoint value. */
-#define HCCHAR_EPTYP_ISO (1U<<18) /**< Isochronous endpoint value.*/
-#define HCCHAR_EPTYP_BULK (2U<<18) /**< Bulk endpoint value. */
-#define HCCHAR_EPTYP_INTR (3U<<18) /**< Interrupt endpoint value. */
-#define HCCHAR_LSDEV (1U<<17) /**< Low-Speed device. */
-#define HCCHAR_EPDIR (1U<<15) /**< Endpoint direction. */
-#define HCCHAR_EPNUM_MASK (15U<<11) /**< Endpoint number mask. */
-#define HCCHAR_EPNUM(n) ((n)<<11) /**< Endpoint number value. */
-#define HCCHAR_MPS_MASK (0x7FFU<<0) /**< Maximum packet size mask. */
-#define HCCHAR_MPS(n) ((n)<<0) /**< Maximum packet size value. */
-/** @} */
-
-/**
- * @name HCINT register bit definitions
- * @{
- */
-#define HCINT_DTERR (1U<<10) /**< Data toggle error. */
-#define HCINT_FRMOR (1U<<9) /**< Frame overrun. */
-#define HCINT_BBERR (1U<<8) /**< Babble error. */
-#define HCINT_TRERR (1U<<7) /**< Transaction Error. */
-#define HCINT_ACK (1U<<5) /**< ACK response
- received/transmitted
- interrupt. */
-#define HCINT_NAK (1U<<4) /**< NAK response received
- interrupt. */
-#define HCINT_STALL (1U<<3) /**< STALL response received
- interrupt. */
-#define HCINT_CHH (1U<<1) /**< Channel halted. */
-#define HCINT_XFRC (1U<<0) /**< Transfer completed. */
-/** @} */
-
-/**
- * @name HCINTMSK register bit definitions
- * @{
- */
-#define HCINTMSK_DTERRM (1U<<10) /**< Data toggle error mask. */
-#define HCINTMSK_FRMORM (1U<<9) /**< Frame overrun mask. */
-#define HCINTMSK_BBERRM (1U<<8) /**< Babble error mask. */
-#define HCINTMSK_TRERRM (1U<<7) /**< Transaction error mask. */
-#define HCINTMSK_NYET (1U<<6) /**< NYET response received
- interrupt mask. */
-#define HCINTMSK_ACKM (1U<<5) /**< ACK Response
- received/transmitted
- interrupt mask. */
-#define HCINTMSK_NAKM (1U<<4) /**< NAK response received
- interrupt mask. */
-#define HCINTMSK_STALLM (1U<<3) /**< STALL response received
- interrupt mask. */
-#define HCINTMSK_AHBERRM (1U<<2)
-#define HCINTMSK_CHHM (1U<<1) /**< Channel halted mask. */
-#define HCINTMSK_XFRCM (1U<<0) /**< Transfer completed mask. */
-/** @} */
-
-/**
- * @name HCTSIZ register bit definitions
- * @{
- */
-#define HCTSIZ_DPID_MASK (3U<<29) /**< PID mask. */
-#define HCTSIZ_DPID_DATA0 (0U<<29) /**< DATA0. */
-#define HCTSIZ_DPID_DATA2 (1U<<29) /**< DATA2. */
-#define HCTSIZ_DPID_DATA1 (2U<<29) /**< DATA1. */
-#define HCTSIZ_DPID_MDATA (3U<<29) /**< MDATA. */
-#define HCTSIZ_DPID_SETUP (3U<<29) /**< SETUP. */
-#define HCTSIZ_PKTCNT_MASK (0x3FFU<<19)/**< Packet count mask. */
-#define HCTSIZ_PKTCNT(n) ((n)<<19) /**< Packet count value. */
-#define HCTSIZ_XFRSIZ_MASK (0x7FFFF<<0)/**< Transfer size mask. */
-#define HCTSIZ_XFRSIZ(n) ((n)<<0) /**< Transfer size value. */
-/** @} */
-
-/**
- * @name DCFG register bit definitions
- * @{
- */
-#define DCFG_PFIVL_MASK (3U<<11) /**< Periodic frame interval
- mask. */
-#define DCFG_PFIVL(n) ((n)<<11) /**< Periodic frame interval
- value. */
-#define DCFG_DAD_MASK (0x7FU<<4) /**< Device address mask. */
-#define DCFG_DAD(n) ((n)<<4) /**< Device address value. */
-#define DCFG_NZLSOHSK (1U<<2) /**< Non-Zero-Length status
- OUT handshake. */
-#define DCFG_DSPD_MASK (3U<<0) /**< Device speed mask. */
-#define DCFG_DSPD_HS (0U<<0) /**< High speed (USB 2.0). */
-#define DCFG_DSPD_HS_FS (1U<<0) /**< High speed (USB 2.0) in FS
- mode. */
-#define DCFG_DSPD_FS11 (3U<<0) /**< Full speed (USB 1.1
- transceiver clock is 48
- MHz). */
-/** @} */
-
-/**
- * @name DCTL register bit definitions
- * @{
- */
-#define DCTL_POPRGDNE (1U<<11) /**< Power-on programming done. */
-#define DCTL_CGONAK (1U<<10) /**< Clear global OUT NAK. */
-#define DCTL_SGONAK (1U<<9) /**< Set global OUT NAK. */
-#define DCTL_CGINAK (1U<<8) /**< Clear global non-periodic
- IN NAK. */
-#define DCTL_SGINAK (1U<<7) /**< Set global non-periodic
- IN NAK. */
-#define DCTL_TCTL_MASK (7U<<4) /**< Test control mask. */
-#define DCTL_TCTL(n) ((n)<<4 /**< Test control value. */
-#define DCTL_GONSTS (1U<<3) /**< Global OUT NAK status. */
-#define DCTL_GINSTS (1U<<2) /**< Global non-periodic IN
- NAK status. */
-#define DCTL_SDIS (1U<<1) /**< Soft disconnect. */
-#define DCTL_RWUSIG (1U<<0) /**< Remote wakeup signaling. */
-/** @} */
-
-/**
- * @name DSTS register bit definitions
- * @{
- */
-#define DSTS_FNSOF_MASK (0x3FFU<<8) /**< Frame number of the received
- SOF mask. */
-#define DSTS_FNSOF(n) ((n)<<8) /**< Frame number of the received
- SOF value. */
-#define DSTS_FNSOF_ODD (1U<<8) /**< Frame parity of the received
- SOF value. */
-#define DSTS_EERR (1U<<3) /**< Erratic error. */
-#define DSTS_ENUMSPD_MASK (3U<<1) /**< Enumerated speed mask. */
-#define DSTS_ENUMSPD_FS_48 (3U<<1) /**< Full speed (PHY clock is
- running at 48 MHz). */
-#define DSTS_ENUMSPD_HS_480 (0U<<1) /**< High speed. */
-#define DSTS_SUSPSTS (1U<<0) /**< Suspend status. */
-/** @} */
-
-/**
- * @name DIEPMSK register bit definitions
- * @{
- */
-#define DIEPMSK_TXFEM (1U<<6) /**< Transmit FIFO empty mask. */
-#define DIEPMSK_INEPNEM (1U<<6) /**< IN endpoint NAK effective
- mask. */
-#define DIEPMSK_ITTXFEMSK (1U<<4) /**< IN token received when
- TxFIFO empty mask. */
-#define DIEPMSK_TOCM (1U<<3) /**< Timeout condition mask. */
-#define DIEPMSK_EPDM (1U<<1) /**< Endpoint disabled
- interrupt mask. */
-#define DIEPMSK_XFRCM (1U<<0) /**< Transfer completed
- interrupt mask. */
-/** @} */
-
-/**
- * @name DOEPMSK register bit definitions
- * @{
- */
-#define DOEPMSK_OTEPDM (1U<<4) /**< OUT token received when
- endpoint disabled mask. */
-#define DOEPMSK_STUPM (1U<<3) /**< SETUP phase done mask. */
-#define DOEPMSK_EPDM (1U<<1) /**< Endpoint disabled
- interrupt mask. */
-#define DOEPMSK_XFRCM (1U<<0) /**< Transfer completed
- interrupt mask. */
-/** @} */
-
-/**
- * @name DAINT register bit definitions
- * @{
- */
-#define DAINT_OEPINT_MASK (0xFFFFU<<16)/**< OUT endpoint interrupt
- bits mask. */
-#define DAINT_OEPINT(n) ((n)<<16) /**< OUT endpoint interrupt
- bits value. */
-#define DAINT_IEPINT_MASK (0xFFFFU<<0)/**< IN endpoint interrupt
- bits mask. */
-#define DAINT_IEPINT(n) ((n)<<0) /**< IN endpoint interrupt
- bits value. */
-/** @} */
-
-/**
- * @name DAINTMSK register bit definitions
- * @{
- */
-#define DAINTMSK_OEPM_MASK (0xFFFFU<<16)/**< OUT EP interrupt mask
- bits mask. */
-#define DAINTMSK_OEPM(n) (1U<<(16+(n)))/**< OUT EP interrupt mask
- bits value. */
-#define DAINTMSK_IEPM_MASK (0xFFFFU<<0)/**< IN EP interrupt mask
- bits mask. */
-#define DAINTMSK_IEPM(n) (1U<<(n)) /**< IN EP interrupt mask
- bits value. */
-/** @} */
-
-/**
- * @name DVBUSDIS register bit definitions
- * @{
- */
-#define DVBUSDIS_VBUSDT_MASK (0xFFFFU<<0)/**< Device VBUS discharge
- time mask. */
-#define DVBUSDIS_VBUSDT(n) ((n)<<0) /**< Device VBUS discharge
- time value. */
-/** @} */
-
-/**
- * @name DVBUSPULSE register bit definitions
- * @{
- */
-#define DVBUSPULSE_DVBUSP_MASK (0xFFFU<<0) /**< Device VBUSpulsing time
- mask. */
-#define DVBUSPULSE_DVBUSP(n) ((n)<<0) /**< Device VBUS pulsing time
- value. */
-/** @} */
-
-/**
- * @name DIEPEMPMSK register bit definitions
- * @{
- */
-#define DIEPEMPMSK_INEPTXFEM(n) (1U<<(n)) /**< IN EP Tx FIFO empty
- interrupt mask bit. */
-/** @} */
-
-/**
- * @name DIEPCTL register bit definitions
- * @{
- */
-#define DIEPCTL_EPENA (1U<<31) /**< Endpoint enable. */
-#define DIEPCTL_EPDIS (1U<<30) /**< Endpoint disable. */
-#define DIEPCTL_SD1PID (1U<<29) /**< Set DATA1 PID. */
-#define DIEPCTL_SODDFRM (1U<<29) /**< Set odd frame. */
-#define DIEPCTL_SD0PID (1U<<28) /**< Set DATA0 PID. */
-#define DIEPCTL_SEVNFRM (1U<<28) /**< Set even frame. */
-#define DIEPCTL_SNAK (1U<<27) /**< Set NAK. */
-#define DIEPCTL_CNAK (1U<<26) /**< Clear NAK. */
-#define DIEPCTL_TXFNUM_MASK (15U<<22) /**< TxFIFO number mask. */
-#define DIEPCTL_TXFNUM(n) ((n)<<22) /**< TxFIFO number value. */
-#define DIEPCTL_STALL (1U<<21) /**< STALL handshake. */
-#define DIEPCTL_SNPM (1U<<20) /**< Snoop mode. */
-#define DIEPCTL_EPTYP_MASK (3<<18) /**< Endpoint type mask. */
-#define DIEPCTL_EPTYP_CTRL (0U<<18) /**< Control. */
-#define DIEPCTL_EPTYP_ISO (1U<<18) /**< Isochronous. */
-#define DIEPCTL_EPTYP_BULK (2U<<18) /**< Bulk. */
-#define DIEPCTL_EPTYP_INTR (3U<<18) /**< Interrupt. */
-#define DIEPCTL_NAKSTS (1U<<17) /**< NAK status. */
-#define DIEPCTL_EONUM (1U<<16) /**< Even/odd frame. */
-#define DIEPCTL_DPID (1U<<16) /**< Endpoint data PID. */
-#define DIEPCTL_USBAEP (1U<<15) /**< USB active endpoint. */
-#define DIEPCTL_MPSIZ_MASK (0x3FFU<<0) /**< Maximum Packet size mask. */
-#define DIEPCTL_MPSIZ(n) ((n)<<0) /**< Maximum Packet size value. */
-/** @} */
-
-/**
- * @name DIEPINT register bit definitions
- * @{
- */
-#define DIEPINT_TXFE (1U<<7) /**< Transmit FIFO empty. */
-#define DIEPINT_INEPNE (1U<<6) /**< IN endpoint NAK effective. */
-#define DIEPINT_ITTXFE (1U<<4) /**< IN Token received when
- TxFIFO is empty. */
-#define DIEPINT_TOC (1U<<3) /**< Timeout condition. */
-#define DIEPINT_EPDISD (1U<<1) /**< Endpoint disabled
- interrupt. */
-#define DIEPINT_XFRC (1U<<0) /**< Transfer completed. */
-/** @} */
-
-/**
- * @name DIEPTSIZ register bit definitions
- * @{
- */
-#define DIEPTSIZ_MCNT_MASK (3U<<29) /**< Multi count mask. */
-#define DIEPTSIZ_MCNT(n) ((n)<<29) /**< Multi count value. */
-#define DIEPTSIZ_PKTCNT_MASK (0x3FF<<19) /**< Packet count mask. */
-#define DIEPTSIZ_PKTCNT(n) ((n)<<19) /**< Packet count value. */
-#define DIEPTSIZ_XFRSIZ_MASK (0x7FFFFU<<0)/**< Transfer size mask. */
-#define DIEPTSIZ_XFRSIZ(n) ((n)<<0) /**< Transfer size value. */
-/** @} */
-
-/**
- * @name DTXFSTS register bit definitions.
- * @{
- */
-#define DTXFSTS_INEPTFSAV_MASK (0xFFFF<<0) /**< IN endpoint TxFIFO space
- available. */
-/** @} */
-
-/**
- * @name DOEPCTL register bit definitions.
- * @{
- */
-#define DOEPCTL_EPENA (1U<<31) /**< Endpoint enable. */
-#define DOEPCTL_EPDIS (1U<<30) /**< Endpoint disable. */
-#define DOEPCTL_SD1PID (1U<<29) /**< Set DATA1 PID. */
-#define DOEPCTL_SODDFRM (1U<<29) /**< Set odd frame. */
-#define DOEPCTL_SD0PID (1U<<28) /**< Set DATA0 PID. */
-#define DOEPCTL_SEVNFRM (1U<<28) /**< Set even frame. */
-#define DOEPCTL_SNAK (1U<<27) /**< Set NAK. */
-#define DOEPCTL_CNAK (1U<<26) /**< Clear NAK. */
-#define DOEPCTL_STALL (1U<<21) /**< STALL handshake. */
-#define DOEPCTL_SNPM (1U<<20) /**< Snoop mode. */
-#define DOEPCTL_EPTYP_MASK (3U<<18) /**< Endpoint type mask. */
-#define DOEPCTL_EPTYP_CTRL (0U<<18) /**< Control. */
-#define DOEPCTL_EPTYP_ISO (1U<<18) /**< Isochronous. */
-#define DOEPCTL_EPTYP_BULK (2U<<18) /**< Bulk. */
-#define DOEPCTL_EPTYP_INTR (3U<<18) /**< Interrupt. */
-#define DOEPCTL_NAKSTS (1U<<17) /**< NAK status. */
-#define DOEPCTL_EONUM (1U<<16) /**< Even/odd frame. */
-#define DOEPCTL_DPID (1U<<16) /**< Endpoint data PID. */
-#define DOEPCTL_USBAEP (1U<<15) /**< USB active endpoint. */
-#define DOEPCTL_MPSIZ_MASK (0x3FFU<<0) /**< Maximum Packet size mask. */
-#define DOEPCTL_MPSIZ(n) ((n)<<0) /**< Maximum Packet size value. */
-/** @} */
-
-/**
- * @name DOEPINT register bit definitions
- * @{
- */
-#define DOEPINT_B2BSTUP (1U<<6) /**< Back-to-back SETUP packets
- received. */
-#define DOEPINT_OTEPDIS (1U<<4) /**< OUT token received when
- endpoint disabled. */
-#define DOEPINT_STUP (1U<<3) /**< SETUP phase done. */
-#define DOEPINT_EPDISD (1U<<1) /**< Endpoint disabled
- interrupt. */
-#define DOEPINT_XFRC (1U<<0) /**< Transfer completed
- interrupt. */
-/** @} */
-
-/**
- * @name DOEPTSIZ register bit definitions
- * @{
- */
-#define DOEPTSIZ_RXDPID_MASK (3U<<29) /**< Received data PID mask. */
-#define DOEPTSIZ_RXDPID(n) ((n)<<29) /**< Received data PID value. */
-#define DOEPTSIZ_STUPCNT_MASK (3U<<29) /**< SETUP packet count mask. */
-#define DOEPTSIZ_STUPCNT(n) ((n)<<29) /**< SETUP packet count value. */
-#define DOEPTSIZ_PKTCNT_MASK (0x3FFU<<19)/**< Packet count mask. */
-#define DOEPTSIZ_PKTCNT(n) ((n)<<19) /**< Packet count value. */
-#define DOEPTSIZ_XFRSIZ_MASK (0x7FFFFU<<0)/**< Transfer size mask. */
-#define DOEPTSIZ_XFRSIZ(n) ((n)<<0) /**< Transfer size value. */
-/** @} */
-
-/**
- * @name PCGCCTL register bit definitions
- * @{
- */
-#define PCGCCTL_PHYSUSP (1U<<4) /**< PHY Suspended. */
-#define PCGCCTL_GATEHCLK (1U<<1) /**< Gate HCLK. */
-#define PCGCCTL_STPPCLK (1U<<0) /**< Stop PCLK. */
-/** @} */
-
-/**
- * @brief OTG_FS registers block memory address.
- */
-#define OTG_FS_ADDR 0x50000000
-
-/**
- * @brief OTG_HS registers block memory address.
- */
-#define OTG_HS_ADDR 0x40040000
-
-/**
- * @brief Accesses to the OTG_FS registers block.
- */
-#define OTG_FS ((stm32_otg_t *)OTG_FS_ADDR)
-
-/**
- * @brief Accesses to the OTG_HS registers block.
- */
-#define OTG_HS ((stm32_otg_t *)OTG_HS_ADDR)
-
-#endif /* _STM32_OTG_H_ */
-
-/** @} */
diff --git a/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c b/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c
index 3abab1c..2894907 100644
--- a/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c
+++ b/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c
@@ -1,6 +1,6 @@
/*
- ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
- Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail)
+ ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
+ Copyright (C) 2015..2017 Diego Ismirlian, (dismirlian (at) google's mail)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -21,6 +21,53 @@
#include "usbh/internal.h"
#include <string.h>
+#if STM32_USBH_USE_OTG1
+#if !defined(STM32_OTG1_CHANNELS_NUMBER)
+#error "STM32_OTG1_CHANNELS_NUMBER must be defined"
+#endif
+#if !defined(STM32_OTG1_RXFIFO_SIZE)
+#define STM32_OTG1_RXFIFO_SIZE 1024
+#endif
+#if !defined(STM32_OTG1_PTXFIFO_SIZE)
+#define STM32_OTG1_PTXFIFO_SIZE 128
+#endif
+#if !defined(STM32_OTG1_NPTXFIFO_SIZE)
+#define STM32_OTG1_NPTXFIFO_SIZE 128
+#endif
+#if (STM32_OTG1_RXFIFO_SIZE + STM32_OTG1_PTXFIFO_SIZE + STM32_OTG1_NPTXFIFO_SIZE) > (STM32_OTG1_FIFO_MEM_SIZE * 4)
+#error "Not enough memory in OTG1 implementation"
+#elif (STM32_OTG1_RXFIFO_SIZE + STM32_OTG1_PTXFIFO_SIZE + STM32_OTG1_NPTXFIFO_SIZE) < (STM32_OTG1_FIFO_MEM_SIZE * 4)
+#warning "Spare memory in OTG1; could enlarge RX, PTX or NPTX FIFO sizes"
+#endif
+#if (STM32_OTG1_RXFIFO_SIZE % 4) || (STM32_OTG1_PTXFIFO_SIZE % 4) || (STM32_OTG1_NPTXFIFO_SIZE % 4)
+#error "FIFO sizes must be a multiple of 32-bit words"
+#endif
+#endif
+
+#if STM32_USBH_USE_OTG2
+#if !defined(STM32_OTG2_CHANNELS_NUMBER)
+#error "STM32_OTG2_CHANNELS_NUMBER must be defined"
+#endif
+#if !defined(STM32_OTG2_RXFIFO_SIZE)
+#define STM32_OTG2_RXFIFO_SIZE 2048
+#endif
+#if !defined(STM32_OTG2_PTXFIFO_SIZE)
+#define STM32_OTG2_PTXFIFO_SIZE 1024
+#endif
+#if !defined(STM32_OTG2_NPTXFIFO_SIZE)
+#define STM32_OTG2_NPTXFIFO_SIZE 1024
+#endif
+#if (STM32_OTG2_RXFIFO_SIZE + STM32_OTG2_PTXFIFO_SIZE + STM32_OTG2_NPTXFIFO_SIZE) > (STM32_OTG2_FIFO_MEM_SIZE * 4)
+#error "Not enough memory in OTG2 implementation"
+#elif (STM32_OTG2_RXFIFO_SIZE + STM32_OTG2_PTXFIFO_SIZE + STM32_OTG2_NPTXFIFO_SIZE) < (STM32_OTG2_FIFO_MEM_SIZE * 4)
+#warning "Spare memory in OTG2; could enlarge RX, PTX or NPTX FIFO sizes"
+#endif
+#if (STM32_OTG2_RXFIFO_SIZE % 4) || (STM32_OTG2_PTXFIFO_SIZE % 4) || (STM32_OTG2_NPTXFIFO_SIZE % 4)
+#error "FIFO sizes must be a multiple of 32-bit words"
+#endif
+#endif
+
+
#if USBH_LLD_DEBUG_ENABLE_TRACE
#define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
#define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
@@ -58,8 +105,15 @@ static void _try_commit_np(USBHDriver *host);
static void otg_rxfifo_flush(USBHDriver *usbp);
static void otg_txfifo_flush(USBHDriver *usbp, uint32_t fifo);
+#if STM32_USBH_USE_OTG1
+USBHDriver USBHD1;
+#endif
+#if STM32_USBH_USE_OTG2
+USBHDriver USBHD2;
+#endif
+
/*===========================================================================*/
-/* Little helper functions. */
+/* Little helper functions. */
/*===========================================================================*/
static inline void _move_to_pending_queue(usbh_ep_t *ep) {
list_move_tail(&ep->node, ep->pending_list);
@@ -73,18 +127,8 @@ static inline void _save_dt_mask(usbh_ep_t *ep, uint32_t hctsiz) {
ep->dt_mask = hctsiz & HCTSIZ_DPID_MASK;
}
-#if 1
-#define _transfer_completed _transfer_completedI
-#else
-static inline void _transfer_completed(usbh_ep_t *ep, usbh_urb_t *urb, usbh_urbstatus_t status) {
- osalSysLockFromISR();
- _transfer_completedI(ep, urb, status);
- osalSysUnlockFromISR();
-}
-#endif
-
/*===========================================================================*/
-/* Functions called from many places. */
+/* Functions called from many places. */
/*===========================================================================*/
static void _transfer_completedI(usbh_ep_t *ep, usbh_urb_t *urb, usbh_urbstatus_t status) {
osalDbgCheckClassI();
@@ -200,7 +244,6 @@ static bool _activate_ep(USBHDriver *host, usbh_ep_t *ep) {
ep->xfer.buf = urb->buff;
}
ep->xfer.error_count = 0;
- //urb->status = USBH_URBSTATUS_QUEUED;
} else {
osalDbgCheck(urb->requestedLength >= urb->actualLength);
@@ -340,7 +383,7 @@ static bool _update_urb(usbh_ep_t *ep, uint32_t hctsiz, usbh_urb_t *urb, bool co
osalDbgCheck(len == ep->xfer.partial); //TODO: if len == ep->xfer.partial, use this instead of the above code
}
-#if 1
+#if 0
osalDbgAssert(urb->actualLength + len <= urb->requestedLength, "what happened?");
#else
if (urb->actualLength + len > urb->requestedLength) {
@@ -412,7 +455,7 @@ static void _purge_queue(USBHDriver *host, struct list_head *list) {
_release_channel(host, hcm);
_update_urb(ep, hcm->hc->HCTSIZ, urb, FALSE);
}
- _transfer_completed(ep, urb, USBH_URBSTATUS_DISCONNECTED);
+ _transfer_completedI(ep, urb, USBH_URBSTATUS_DISCONNECTED);
}
}
@@ -487,12 +530,12 @@ static uint32_t _write_packet(struct list_head *list, uint32_t space_available)
/*===========================================================================*/
-/* API. */
+/* API. */
/*===========================================================================*/
void usbh_lld_ep_object_init(usbh_ep_t *ep) {
/* CTRL(IN) CTRL(OUT) INT(IN) INT(OUT) BULK(IN) BULK(OUT) ISO(IN) ISO(OUT)
- * STALL si sólo DAT/STAT si si si si no no ep->type != ISO && (ep->type != CTRL || ctrlphase != SETUP)
+ * STALL si solo DAT/STAT si si si si no no ep->type != ISO && (ep->type != CTRL || ctrlphase != SETUP)
* ACK si si si si si si no no ep->type != ISO
* NAK si si si si si si no no ep->type != ISO
* BBERR si no si no si no si no ep->in
@@ -548,7 +591,6 @@ void usbh_lld_ep_object_init(usbh_ep_t *ep) {
void usbh_lld_ep_open(usbh_ep_t *ep) {
uinfof("\t%s: Open EP", ep->name);
ep->status = USBH_EPSTATUS_OPEN;
- osalOsRescheduleS();
}
void usbh_lld_ep_close(usbh_ep_t *ep) {
@@ -560,11 +602,22 @@ void usbh_lld_ep_close(usbh_ep_t *ep) {
}
uinfof("\t%s: Closed", ep->name);
ep->status = USBH_EPSTATUS_CLOSED;
- osalOsRescheduleS();
+}
+
+bool usbh_lld_ep_reset(usbh_ep_t *ep) {
+ ep->dt_mask = HCTSIZ_DPID_DATA0;
+ return TRUE;
}
void usbh_lld_urb_submit(usbh_urb_t *urb) {
usbh_ep_t *const ep = urb->ep;
+ USBHDriver *const host = ep->device->host;
+
+ if (!(host->otg->HPRT & HPRT_PENA)) {
+ uwarnf("\t%s: Can't submit URB, port disabled", ep->name);
+ _usbh_urb_completeI(urb, USBH_URBSTATUS_DISCONNECTED);
+ return;
+ }
/* add the URB to the EP's queue */
list_add_tail(&urb->node, &ep->urb_list);
@@ -576,7 +629,7 @@ void usbh_lld_urb_submit(usbh_urb_t *urb) {
_move_to_pending_queue(ep);
if (usbhEPIsPeriodic(ep)) {
- ep->device->host->otg->GINTMSK |= GINTMSK_SOFM;
+ host->otg->GINTMSK |= GINTMSK_SOFM;
} else {
/* try to queue non-periodic transfers */
_try_commit_np(ep->device->host);
@@ -584,6 +637,7 @@ void usbh_lld_urb_submit(usbh_urb_t *urb) {
}
}
+/* usbh_lld_urb_abort may require a reschedule if called from a S-locked state */
bool usbh_lld_urb_abort(usbh_urb_t *urb, usbh_urbstatus_t status) {
osalDbgCheck(usbhURBIsBusy(urb));
@@ -596,17 +650,20 @@ bool usbh_lld_urb_abort(usbh_urb_t *urb, usbh_urbstatus_t status) {
if (hcm->halt_reason == USBH_LLD_HALTREASON_NONE) {
/* The channel is not being halted */
+ uinfof("\t%s: usbh_lld_urb_abort: channel is not being halted", hcm->ep->name);
urb->status = status;
_halt_channel(ep->device->host, hcm, USBH_LLD_HALTREASON_ABORT);
} else {
/* The channel is being halted, so we can't re-halt it. The CHH interrupt will
* be in charge of completing the transfer, but the URB will not have the specified status.
*/
+ uinfof("\t%s: usbh_lld_urb_abort: channel is being halted", hcm->ep->name);
}
return FALSE;
}
- /* This URB is active, we can cancel it now */
+ /* This URB is inactive, we can cancel it now */
+ uinfof("\t%s: usbh_lld_urb_abort: URB is not active", ep->name);
_transfer_completedI(ep, urb, status);
return TRUE;
@@ -614,7 +671,7 @@ bool usbh_lld_urb_abort(usbh_urb_t *urb, usbh_urbstatus_t status) {
/*===========================================================================*/
-/* Channel Interrupts. */
+/* Channel Interrupts. */
/*===========================================================================*/
//CTRL(IN) CTRL(OUT) INT(IN) INT(OUT) BULK(IN) BULK(OUT) ISO(IN) ISO(OUT)
@@ -705,7 +762,7 @@ static void _complete_bulk_int(USBHDriver *host, stm32_hc_management_t *hcm, usb
_save_dt_mask(ep, hctsiz);
if (_update_urb(ep, hctsiz, urb, TRUE)) {
udbgf("\t%s: done", ep->name);
- _transfer_completed(ep, urb, USBH_URBSTATUS_OK);
+ _transfer_completedI(ep, urb, USBH_URBSTATUS_OK);
} else {
osalDbgCheck(urb->requestedLength > 0x7FFFF);
uwarnf("\t%s: incomplete", ep->name);
@@ -736,7 +793,7 @@ static void _complete_control(USBHDriver *host, stm32_hc_management_t *hcm, usbh
} else {
osalDbgCheck(ep->xfer.u.ctrl_phase == USBH_LLD_CTRLPHASE_STATUS);
udbgf("\t%s: STATUS done", ep->name);
- _transfer_completed(ep, urb, USBH_URBSTATUS_OK);
+ _transfer_completedI(ep, urb, USBH_URBSTATUS_OK);
}
_try_commit_np(host);
}
@@ -762,7 +819,7 @@ static void _complete_iso(USBHDriver *host, stm32_hc_management_t *hcm, usbh_ep_
udbgf("\t%s: done", hcm->ep->name);
_release_channel(host, hcm);
_update_urb(ep, hctsiz, urb, TRUE);
- _transfer_completed(ep, urb, USBH_URBSTATUS_OK);
+ _transfer_completedI(ep, urb, USBH_URBSTATUS_OK);
_try_commit_p(host, FALSE);
}
@@ -847,7 +904,7 @@ static inline void _chh_int(USBHDriver *host, stm32_hc_management_t *hcm, stm32_
switch (reason) {
case USBH_LLD_HALTREASON_NAK:
if ((ep->type == USBH_EPTYPE_INT) && ep->in) {
- _transfer_completed(ep, urb, USBH_URBSTATUS_TIMEOUT);
+ _transfer_completedI(ep, urb, USBH_URBSTATUS_TIMEOUT);
} else {
ep->xfer.error_count = 0;
_move_to_pending_queue(ep);
@@ -855,15 +912,19 @@ static inline void _chh_int(USBHDriver *host, stm32_hc_management_t *hcm, stm32_
break;
case USBH_LLD_HALTREASON_STALL:
- if ((ep->type == USBH_EPTYPE_CTRL) && (ep->xfer.u.ctrl_phase == USBH_LLD_CTRLPHASE_SETUP)) {
- uerrf("\t%s: Faulty device: STALLed SETUP phase", ep->name);
+ if (ep->type == USBH_EPTYPE_CTRL) {
+ if (ep->xfer.u.ctrl_phase == USBH_LLD_CTRLPHASE_SETUP) {
+ uerrf("\t%s: Faulty device: STALLed SETUP phase", ep->name);
+ }
+ } else {
+ ep->status = USBH_EPSTATUS_HALTED;
}
- _transfer_completed(ep, urb, USBH_URBSTATUS_STALL);
+ _transfer_completedI(ep, urb, USBH_URBSTATUS_STALL);
break;
case USBH_LLD_HALTREASON_ERROR:
if ((ep->type == USBH_EPTYPE_ISO) || done || (ep->xfer.error_count >= 3)) {
- _transfer_completed(ep, urb, USBH_URBSTATUS_ERROR);
+ _transfer_completedI(ep, urb, USBH_URBSTATUS_ERROR);
} else {
uerrf("\t%s: err=%d, done=%d, retry", ep->name, ep->xfer.error_count, done);
_move_to_pending_queue(ep);
@@ -872,7 +933,7 @@ static inline void _chh_int(USBHDriver *host, stm32_hc_management_t *hcm, stm32_
case USBH_LLD_HALTREASON_ABORT:
uwarnf("\t%s: Abort", ep->name);
- _transfer_completed(ep, urb, urb->status);
+ _transfer_completedI(ep, urb, urb->status);
break;
default:
@@ -926,10 +987,15 @@ static inline void _hcint_int(USBHDriver *host) {
haint = host->otg->HAINT;
haint &= host->otg->HAINTMSK;
+#if USBH_LLD_DEBUG_ENABLE_ERRORS
if (!haint) {
- uerrf("HAINT=%08x, HAINTMSK=%08x", host->otg->HAINT, host->otg->HAINTMSK);
+ uint32_t a, b;
+ a = host->otg->HAINT;
+ b = host->otg->HAINTMSK;
+ uerrf("HAINT=%08x, HAINTMSK=%08x", a, b);
return;
}
+#endif
#if 1 //channel lookup loop
uint8_t i;
@@ -951,9 +1017,50 @@ static inline void _hcint_int(USBHDriver *host) {
/*===========================================================================*/
-/* Host interrupts. */
+/* Host interrupts. */
/*===========================================================================*/
static inline void _sof_int(USBHDriver *host) {
+
+ /* this is part of the workaround to the LS bug in the OTG core */
+#undef HPRT_PLSTS_MASK
+#define HPRT_PLSTS_MASK (3U<<10)
+ if (host->check_ls_activity) {
+ stm32_otg_t *const otg = host->otg;
+ uint16_t remaining = otg->HFNUM >> 16;
+ if (remaining < 5975) {
+ uwarnf("LS: ISR called too late (time=%d)", 6000 - remaining);
+ return;
+ }
+ /* 15us loop during which we check if the core generates an actual keep-alive
+ * (or activity other than idle) on the DP/DM lines. After 15us, we abort
+ * the loop and wait for the next SOF. If no activity is detected, the upper
+ * layer will time-out waiting for the reset to happen, and the port will remain
+ * enabled (though in a dumb state). This will be detected on the next port reset
+ * request and the OTG core will be reset. */
+ for (;;) {
+ uint32_t line_status = otg->HPRT & HPRT_PLSTS_MASK;
+ remaining = otg->HFNUM >> 16;
+ if (!(otg->HPRT & HPRT_PENA)) {
+ uwarn("LS: Port disabled");
+ return;
+ }
+ if (line_status != HPRT_PLSTS_DM) {
+ /* success; report that the port is enabled */
+ uinfof("LS: activity detected, line=%d, time=%d", line_status >> 10, 6000 - remaining);
+ host->check_ls_activity = FALSE;
+ otg->GINTMSK = (otg->GINTMSK & ~GINTMSK_SOFM) | (GINTMSK_HCM | GINTMSK_RXFLVLM);
+ host->rootport.lld_status |= USBH_PORTSTATUS_ENABLE;
+ host->rootport.lld_c_status |= USBH_PORTSTATUS_C_ENABLE;
+ return;
+ }
+ if (remaining < 5910) {
+ udbg("LS: No activity detected");
+ return;
+ }
+ }
+ }
+
+ /* real SOF interrupt */
udbg("SOF");
_try_commit_p(host, TRUE);
}
@@ -1059,9 +1166,6 @@ static inline void _nptxfe_int(USBHDriver *host) {
rem += _write_packet(&host->ep_active_lists[USBH_EPTYPE_BULK],
otg->HNPTXSTS & HPTXSTS_PTXFSAVL_MASK);
-// if (rem)
-// otg->GINTMSK |= GINTMSK_NPTXFEM;
-
if (!rem)
otg->GINTMSK &= ~GINTMSK_NPTXFEM;
@@ -1073,17 +1177,19 @@ static inline void _ptxfe_int(USBHDriver *host) {
uinfo("PTXFE");
}
-static inline void _discint_int(USBHDriver *host) {
- uint32_t hprt = host->otg->HPRT;
-
- uwarn("\tDISCINT");
+static void _disable(USBHDriver *host) {
+ host->rootport.lld_status &= ~(USBH_PORTSTATUS_CONNECTION | USBH_PORTSTATUS_ENABLE);
+ host->rootport.lld_c_status |= USBH_PORTSTATUS_C_CONNECTION | USBH_PORTSTATUS_C_ENABLE;
- if (!(hprt & HPRT_PCSTS)) {
- host->rootport.lld_status &= ~(USBH_PORTSTATUS_CONNECTION | USBH_PORTSTATUS_ENABLE);
- host->rootport.lld_c_status |= USBH_PORTSTATUS_C_CONNECTION | USBH_PORTSTATUS_C_ENABLE;
- }
_purge_active(host);
_purge_pending(host);
+
+ host->otg->GINTMSK &= ~(GINTMSK_HCM | GINTMSK_RXFLVLM);
+}
+
+static inline void _discint_int(USBHDriver *host) {
+ uinfo("DISCINT: Port disconnection detected");
+ _disable(host);
}
static inline void _hprtint_int(USBHDriver *host) {
@@ -1099,8 +1205,6 @@ static inline void _hprtint_int(USBHDriver *host) {
uinfo("\tHPRT: Port connection detected");
host->rootport.lld_status |= USBH_PORTSTATUS_CONNECTION;
host->rootport.lld_c_status |= USBH_PORTSTATUS_C_CONNECTION;
- } else {
- uinfo("\tHPRT: Port disconnection detected");
}
}
@@ -1108,9 +1212,32 @@ static inline void _hprtint_int(USBHDriver *host) {
hprt_clr |= HPRT_PENCHNG;
if (hprt & HPRT_PENA) {
uinfo("\tHPRT: Port enabled");
- host->rootport.lld_status |= USBH_PORTSTATUS_ENABLE;
host->rootport.lld_status &= ~(USBH_PORTSTATUS_HIGH_SPEED | USBH_PORTSTATUS_LOW_SPEED);
+ /* configure FIFOs */
+#define HNPTXFSIZ DIEPTXF0
+#if STM32_USBH_USE_OTG1
+#if STM32_USBH_USE_OTG2
+ if (&USBHD1 == host)
+#endif
+ {
+ otg->GRXFSIZ = GRXFSIZ_RXFD(STM32_OTG1_RXFIFO_SIZE / 4);
+ otg->HNPTXFSIZ = HPTXFSIZ_PTXSA(STM32_OTG1_RXFIFO_SIZE / 4) | HPTXFSIZ_PTXFD(STM32_OTG1_NPTXFIFO_SIZE / 4);
+ otg->HPTXFSIZ = HPTXFSIZ_PTXSA((STM32_OTG1_RXFIFO_SIZE / 4) + (STM32_OTG1_NPTXFIFO_SIZE / 4)) | HPTXFSIZ_PTXFD(STM32_OTG1_PTXFIFO_SIZE / 4);
+ }
+#endif
+#if STM32_USBH_USE_OTG2
+#if STM32_USBH_USE_OTG1
+ if (&USBHD2 == host)
+#endif
+ {
+ otg->GRXFSIZ = GRXFSIZ_RXFD(STM32_OTG2_RXFIFO_SIZE / 4);
+ otg->HNPTXFSIZ = HPTXFSIZ_PTXSA(STM32_OTG2_RXFIFO_SIZE / 4) | HPTXFSIZ_PTXFD(STM32_OTG2_NPTXFIFO_SIZE / 4);
+ otg->HPTXFSIZ = HPTXFSIZ_PTXSA((STM32_OTG2_RXFIFO_SIZE / 4) + (STM32_OTG2_NPTXFIFO_SIZE / 4)) | HPTXFSIZ_PTXFD(STM32_OTG2_PTXFIFO_SIZE / 4);
+ }
+#endif
+#undef HNPTXFSIZ
+
/* Make sure the FIFOs are flushed. */
otg_txfifo_flush(host, 0x10);
otg_rxfifo_flush(host);
@@ -1127,9 +1254,23 @@ static inline void _hprtint_int(USBHDriver *host) {
host->rootport.lld_status |= USBH_PORTSTATUS_LOW_SPEED;
otg->HFIR = 6000;
otg->HCFG = (otg->HCFG & ~HCFG_FSLSPCS_MASK) | HCFG_FSLSPCS_6;
+
+ /* Low speed devices connected to the STM32's internal transceiver sometimes
+ * don't behave correctly. Although HPRT reports a port enable, really
+ * no traffic is generated, and the core is non-functional. To avoid
+ * this we won't report the port enable until we are sure that the
+ * port is working. */
+ host->check_ls_activity = TRUE;
+ otg->GINTMSK |= GINTMSK_SOFM;
} else {
otg->HFIR = 48000;
otg->HCFG = (otg->HCFG & ~HCFG_FSLSPCS_MASK) | HCFG_FSLSPCS_48;
+ host->check_ls_activity = FALSE;
+
+ /* enable channel and rx interrupts */
+ otg->GINTMSK |= GINTMSK_HCM | GINTMSK_RXFLVLM;
+ host->rootport.lld_status |= USBH_PORTSTATUS_ENABLE;
+ host->rootport.lld_c_status |= USBH_PORTSTATUS_C_ENABLE;
}
} else {
if (hprt & HPRT_PCSTS) {
@@ -1141,13 +1282,8 @@ static inline void _hprtint_int(USBHDriver *host) {
} else {
uerr("\tHPRT: Port disabled due to disconnect");
}
-
- _purge_active(host);
- _purge_pending(host);
-
- host->rootport.lld_status &= ~USBH_PORTSTATUS_ENABLE;
+ _disable(host);
}
- host->rootport.lld_c_status |= USBH_PORTSTATUS_C_ENABLE;
}
if (hprt & HPRT_POCCHNG) {
@@ -1179,18 +1315,19 @@ static void usb_lld_serve_interrupt(USBHDriver *host) {
}
/* check mismatch */
- if (gintsts & GINTSTS_MMIS) {
- uerr("Mode Mismatch");
- otg->GINTSTS = gintsts;
- return;
- }
+ osalDbgAssert((gintsts & GINTSTS_MMIS) == 0, "mode mismatch");
gintsts &= otg->GINTMSK;
if (!gintsts) {
- uwarnf("GINTSTS=%08x, GINTMSK=%08x", otg->GINTSTS, otg->GINTMSK);
+#if USBH_DEBUG_ENABLE_WARNINGS
+ uint32_t a, b;
+ a = otg->GINTSTS;
+ b = otg->GINTMSK;
+ uwarnf("Masked bits caused an ISR: GINTSTS=%08x, GINTMSK=%08x (unhandled bits=%08x)", a, b, a & ~b);
+#endif
return;
}
-// otg->GINTMSK &= ~(GINTMSK_NPTXFEM | GINTMSK_PTXFEM);
+
otg->GINTSTS = gintsts;
if (gintsts & GINTSTS_SOF)
@@ -1214,7 +1351,7 @@ static void usb_lld_serve_interrupt(USBHDriver *host) {
/*===========================================================================*/
-/* Interrupt handlers. */
+/* Interrupt handlers. */
/*===========================================================================*/
#if STM32_USBH_USE_OTG1
@@ -1239,7 +1376,7 @@ OSAL_IRQ_HANDLER(STM32_OTG2_HANDLER) {
/*===========================================================================*/
-/* Initialization functions. */
+/* Initialization functions. */
/*===========================================================================*/
static void otg_core_reset(USBHDriver *usbp) {
stm32_otg_t *const otgp = usbp->otg;
@@ -1289,25 +1426,23 @@ static void _init(USBHDriver *host) {
#if STM32_USBH_USE_OTG1
#if STM32_USBH_USE_OTG2
- if (&USBHD1 == host) {
+ if (&USBHD1 == host)
#endif
+ {
host->otg = OTG_FS;
host->channels_number = STM32_OTG1_CHANNELS_NUMBER;
-#if STM32_USBH_USE_OTG2
}
#endif
-#endif
#if STM32_USBH_USE_OTG2
#if STM32_USBH_USE_OTG1
- if (&USBHD2 == host) {
+ if (&USBHD2 == host)
#endif
+ {
host->otg = OTG_HS;
host->channels_number = STM32_OTG2_CHANNELS_NUMBER;
-#if STM32_USBH_USE_OTG1
}
#endif
-#endif
INIT_LIST_HEAD(&host->ch_free[0]);
INIT_LIST_HEAD(&host->ch_free[1]);
for (i = 0; i < host->channels_number; i++) {
@@ -1341,8 +1476,9 @@ static void _usbh_start(USBHDriver *usbh) {
/* Clock activation.*/
#if STM32_USBH_USE_OTG1
#if STM32_USBH_USE_OTG2
- if (&USBHD1 == usbh) {
+ if (&USBHD1 == usbh)
#endif
+ {
/* OTG FS clock enable and reset.*/
rccEnableOTG_FS(FALSE);
rccResetOTG_FS();
@@ -1351,27 +1487,25 @@ static void _usbh_start(USBHDriver *usbh) {
/* Enables IRQ vector.*/
nvicEnableVector(STM32_OTG1_NUMBER, STM32_USB_OTG1_IRQ_PRIORITY);
-#if STM32_USBH_USE_OTG2
}
#endif
-#endif
#if STM32_USBH_USE_OTG2
#if STM32_USBH_USE_OTG1
- if (&USBHD2 == usbh) {
+ if (&USBHD2 == usbh)
#endif
+ {
/* OTG HS clock enable and reset.*/
- rccEnableOTG_HS(FALSE);
+ rccEnableOTG_HS(TRUE); // Enable HS clock when cpu is in sleep mode
+ rccDisableOTG_HSULPI(TRUE); // Disable HS ULPI clock when cpu is in sleep mode
rccResetOTG_HS();
otgp->GINTMSK = 0;
/* Enables IRQ vector.*/
nvicEnableVector(STM32_OTG2_NUMBER, STM32_USB_OTG2_IRQ_PRIORITY);
-#if STM32_USBH_USE_OTG1
}
#endif
-#endif
otgp->GUSBCFG = GUSBCFG_PHYSEL | GUSBCFG_TRDT(5);
@@ -1386,12 +1520,20 @@ static void _usbh_start(USBHDriver *usbh) {
otgp->PCGCCTL = 0;
/* Internal FS PHY activation.*/
+#if STM32_OTG_STEPPING == 1
#if defined(BOARD_OTG_NOVBUSSENS)
otgp->GCCFG = GCCFG_NOVBUSSENS | GCCFG_PWRDWN;
#else
otgp->GCCFG = GCCFG_PWRDWN;
#endif
+#elif STM32_OTG_STEPPING == 2
+#if defined(BOARD_OTG_NOVBUSSENS)
+ otgp->GCCFG = GCCFG_PWRDWN;
+#else
+ otgp->GCCFG = (GCCFG_VBDEN | GCCFG_PWRDWN);
+#endif
+#endif
/* 48MHz 1.1 PHY.*/
otgp->HCFG = HCFG_FSLSS | HCFG_FSLSPCS_48;
@@ -1402,40 +1544,11 @@ static void _usbh_start(USBHDriver *usbh) {
otgp->HPRT |= HPRT_PPWR;
- /* without this delay, the FIFO sizes are set INcorrectly */
- osalThreadSleepS(MS2ST(200));
-
-#define HNPTXFSIZ DIEPTXF0
-#if STM32_USBH_USE_OTG1
-#if STM32_USBH_USE_OTG2
- if (&USBHD1 == usbh) {
-#endif
- otgp->GRXFSIZ = GRXFSIZ_RXFD(STM32_OTG1_RXFIFO_SIZE / 4);
- otgp->HNPTXFSIZ = HPTXFSIZ_PTXSA((STM32_OTG1_RXFIFO_SIZE / 4)) | HPTXFSIZ_PTXFD(STM32_OTG1_NPTXFIFO_SIZE / 4);
- otgp->HPTXFSIZ = HPTXFSIZ_PTXSA((STM32_OTG1_RXFIFO_SIZE / 4) + (STM32_OTG1_NPTXFIFO_SIZE / 4)) | HPTXFSIZ_PTXFD(STM32_OTG1_PTXFIFO_SIZE / 4);
-#if STM32_USBH_USE_OTG2
- }
-#endif
-#endif
-#if STM32_USBH_USE_OTG2
-#if STM32_USBH_USE_OTG1
- if (&USBHD2 == usbh) {
-#endif
- otgp->GRXFSIZ = GRXFSIZ_RXFD(STM32_OTG2_RXFIFO_SIZE / 4);
- otgp->HNPTXFSIZ = HPTXFSIZ_PTXSA((STM32_OTG2_RXFIFO_SIZE / 4)) | HPTXFSIZ_PTXFD(STM32_OTG2_NPTXFIFO_SIZE / 4);
- otgp->HPTXFSIZ = HPTXFSIZ_PTXSA((STM32_OTG2_RXFIFO_SIZE / 4) + (STM32_OTG2_NPTXFIFO_SIZE / 4)) | HPTXFSIZ_PTXFD(STM32_OTG2_PTXFIFO_SIZE / 4);
-#if STM32_USBH_USE_OTG1
- }
-#endif
-#endif
-
otg_txfifo_flush(usbh, 0x10);
otg_rxfifo_flush(usbh);
otgp->GINTSTS = 0xffffffff;
- otgp->GINTMSK = GINTMSK_DISCM /*| GINTMSK_PTXFEM*/ | GINTMSK_HCM | GINTMSK_HPRTM
- /*| GINTMSK_IPXFRM | GINTMSK_NPTXFEM*/ | GINTMSK_RXFLVLM
- /*| GINTMSK_SOFM */ | GINTMSK_MMISM;
+ otgp->GINTMSK = GINTMSK_DISCM | GINTMSK_HPRTM | GINTMSK_MMISM;
usbh->rootport.lld_status = USBH_PORTSTATUS_POWER;
usbh->rootport.lld_c_status = 0;
@@ -1450,7 +1563,7 @@ void usbh_lld_start(USBHDriver *usbh) {
}
/*===========================================================================*/
-/* Root Hub request handler. */
+/* Root Hub request handler. */
/*===========================================================================*/
usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestType, uint8_t bRequest,
uint16_t wvalue, uint16_t windex, uint16_t wlength, uint8_t *buf) {
@@ -1469,18 +1582,18 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy
break;
case ClearPortFeature:
- chDbgAssert(windex == 1, "invalid windex");
+ osalDbgAssert(windex == 1, "invalid windex");
osalSysLock();
switch (wvalue) {
case USBH_PORT_FEAT_ENABLE:
case USBH_PORT_FEAT_SUSPEND:
case USBH_PORT_FEAT_POWER:
- chDbgAssert(0, "unimplemented"); /* TODO */
+ osalDbgAssert(0, "unimplemented"); /* TODO */
break;
case USBH_PORT_FEAT_INDICATOR:
- chDbgAssert(0, "unsupported");
+ osalDbgAssert(0, "unsupported");
break;
case USBH_PORT_FEAT_C_CONNECTION:
@@ -1500,30 +1613,18 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy
break;
case USBH_PORT_FEAT_C_OVERCURRENT:
- usbh->rootport.lld_c_status &= USBH_PORTSTATUS_C_OVERCURRENT;
+ usbh->rootport.lld_c_status &= ~USBH_PORTSTATUS_C_OVERCURRENT;
break;
default:
osalDbgAssert(0, "invalid wvalue");
break;
}
- osalOsRescheduleS();
osalSysUnlock();
break;
case GetHubDescriptor:
- /*dev_dbg(hsotg->dev, "GetHubDescriptor\n");
- hub_desc = (struct usb_hub_descriptor *)buf;
- hub_desc->bDescLength = 9;
- hub_desc->bDescriptorType = USB_DT_HUB;
- hub_desc->bNbrPorts = 1;
- hub_desc->wHubCharacteristics =
- cpu_to_le16(HUB_CHAR_COMMON_LPSM |
- HUB_CHAR_INDV_PORT_OCPM);
- hub_desc->bPwrOn2PwrGood = 1;
- hub_desc->bHubContrCurrent = 0;
- hub_desc->u.hs.DeviceRemovable[0] = 0;
- hub_desc->u.hs.DeviceRemovable[1] = 0xff;*/
+ osalDbgAssert(0, "unsupported");
break;
case GetHubStatus:
@@ -1532,26 +1633,25 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy
break;
case GetPortStatus:
- chDbgAssert(windex == 1, "invalid windex");
+ osalDbgAssert(windex == 1, "invalid windex");
osalDbgCheck(wlength >= 4);
osalSysLock();
*(uint32_t *)buf = usbh->rootport.lld_status | (usbh->rootport.lld_c_status << 16);
- osalOsRescheduleS();
osalSysUnlock();
break;
case SetHubFeature:
- chDbgAssert(0, "unsupported");
+ osalDbgAssert(0, "unsupported");
break;
case SetPortFeature:
- chDbgAssert(windex == 1, "invalid windex");
+ osalDbgAssert(windex == 1, "invalid windex");
switch (wvalue) {
case USBH_PORT_FEAT_TEST:
case USBH_PORT_FEAT_SUSPEND:
case USBH_PORT_FEAT_POWER:
- chDbgAssert(0, "unimplemented"); /* TODO */
+ osalDbgAssert(0, "unimplemented"); /* TODO */
break;
case USBH_PORT_FEAT_RESET: {
@@ -1560,18 +1660,35 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy
uint32_t hprt;
otg->PCGCCTL = 0;
hprt = otg->HPRT;
+ if (hprt & HPRT_PENA) {
+ /* This can occur when the OTG core doesn't generate traffic
+ * despite reporting a successful por enable. */
+ uerr("Detected enabled port; resetting OTG core");
+ otg->GAHBCFG = 0;
+ osalThreadSleepS(OSAL_MS2I(20));
+ _usbh_start(usbh); /* this effectively resets the core */
+ osalThreadSleepS(OSAL_MS2I(100)); /* during this delay, the core generates connect ISR */
+ uinfo("OTG reset ended");
+ if (otg->HPRT & HPRT_PCSTS) {
+ /* if the device is still connected, don't report a C_CONNECTION flag, which would cause
+ * the upper layer to abort enumeration */
+ uinfo("Clear connection change flag");
+ usbh->rootport.lld_c_status &= ~USBH_PORTSTATUS_C_CONNECTION;
+ }
+ }
/* note: writing PENA = 1 actually disables the port */
- hprt &= ~(HPRT_PSUSP | HPRT_PENA | HPRT_PCDET | HPRT_PENCHNG | HPRT_POCCHNG );
+ hprt &= ~(HPRT_PSUSP | HPRT_PENA | HPRT_PCDET | HPRT_PENCHNG | HPRT_POCCHNG);
+ while ((otg->GRSTCTL & GRSTCTL_AHBIDL) == 0);
otg->HPRT = hprt | HPRT_PRST;
- osalThreadSleepS(MS2ST(60));
+ osalThreadSleepS(OSAL_MS2I(15));
otg->HPRT = hprt;
+ osalThreadSleepS(OSAL_MS2I(10));
usbh->rootport.lld_c_status |= USBH_PORTSTATUS_C_RESET;
- osalOsRescheduleS();
osalSysUnlock();
} break;
case USBH_PORT_FEAT_INDICATOR:
- chDbgAssert(0, "unsupported");
+ osalDbgAssert(0, "unsupported");
break;
default:
@@ -1589,16 +1706,7 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy
}
uint8_t usbh_lld_roothub_get_statuschange_bitmap(USBHDriver *usbh) {
- osalSysLock();
- if (usbh->rootport.lld_c_status) {
- osalOsRescheduleS();
- osalSysUnlock();
- return 1 << 1;
- }
- osalOsRescheduleS();
- osalSysUnlock();
- return 0;
+ return usbh->rootport.lld_c_status ? (1 << 1) : 0;
}
-
#endif
diff --git a/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.h b/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.h
index e8df749..fd7f4e0 100644
--- a/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.h
+++ b/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.h
@@ -1,6 +1,6 @@
/*
- ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
- Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail)
+ ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
+ Copyright (C) 2015..2017 Diego Ismirlian, (dismirlian (at) google's mail)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -15,8 +15,8 @@
limitations under the License.
*/
-#ifndef USBH_LLD_H_
-#define USBH_LLD_H_
+#ifndef HAL_USBH_LLD_H
+#define HAL_USBH_LLD_H
#include "hal.h"
@@ -63,6 +63,8 @@ typedef struct stm32_hc_management {
#define _usbhdriver_ll_data \
stm32_otg_t *otg; \
+ /* low-speed port reset bug */ \
+ bool check_ls_activity; \
/* channels */ \
uint8_t channels_number; \
stm32_hc_management_t channels[STM32_OTG2_CHANNELS_NUMBER]; \
@@ -127,27 +129,37 @@ typedef struct stm32_hc_management {
"use USBH_DEFINE_BUFFER() to declare the IO buffers"); \
} while (0)
-
-
void usbh_lld_init(void);
void usbh_lld_start(USBHDriver *usbh);
void usbh_lld_ep_object_init(usbh_ep_t *ep);
void usbh_lld_ep_open(usbh_ep_t *ep);
void usbh_lld_ep_close(usbh_ep_t *ep);
+bool usbh_lld_ep_reset(usbh_ep_t *ep);
void usbh_lld_urb_submit(usbh_urb_t *urb);
bool usbh_lld_urb_abort(usbh_urb_t *urb, usbh_urbstatus_t status);
usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestType, uint8_t bRequest,
uint16_t wvalue, uint16_t windex, uint16_t wlength, uint8_t *buf);
uint8_t usbh_lld_roothub_get_statuschange_bitmap(USBHDriver *usbh);
-#define usbh_lld_epreset(ep) do {(ep)->dt_mask = HCTSIZ_DPID_DATA0;} while (0);
-
#ifdef __IAR_SYSTEMS_ICC__
-#define USBH_LLD_DEFINE_BUFFER(type, name) type name
+#define USBH_LLD_DEFINE_BUFFER(var) _Pragma("data_alignment=4") var
+#define USBH_LLD_DECLARE_STRUCT_MEMBER_H1(x, y) x ## y
+#define USBH_LLD_DECLARE_STRUCT_MEMBER_H2(x, y) USBH_LLD_DECLARE_STRUCT_MEMBER_H1(x, y)
+#define USBH_LLD_DECLARE_STRUCT_MEMBER(member) unsigned int USBH_LLD_DECLARE_STRUCT_MEMBER_H2(dummy_align_, __COUNTER__); member
#else
-#define USBH_LLD_DEFINE_BUFFER(type, name) type name __attribute__((aligned(4)))
+#define USBH_LLD_DEFINE_BUFFER(var) var __attribute__((aligned(4)))
+#define USBH_LLD_DECLARE_STRUCT_MEMBER(member) member __attribute__((aligned(4)))
+#endif
+
+
+#if STM32_USBH_USE_OTG1
+extern USBHDriver USBHD1;
+#endif
+
+#if STM32_USBH_USE_OTG2
+extern USBHDriver USBHD2;
#endif
#endif
-#endif /* USBH_LLD_H_ */
+#endif /* HAL_USBH_LLD_H */