aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/ports/STM32/LLD
diff options
context:
space:
mode:
authorDiego Ismirlian <dismirlian@gmail.com>2019-08-24 17:45:41 -0300
committerDiego Ismirlian <dismirlian@gmail.com>2019-08-24 17:45:41 -0300
commit7b2c61a676e024163057ec5ccc508a29ab3b9ed4 (patch)
tree5d1f5423a4e720d657681794ac81dc2a2004cbb0 /os/hal/ports/STM32/LLD
parent81391097156ce2c9fc71c3350457522841e10095 (diff)
parente346e779339636f578536785014609e46866fb9c (diff)
downloadChibiOS-Contrib-7b2c61a676e024163057ec5ccc508a29ab3b9ed4.tar.gz
ChibiOS-Contrib-7b2c61a676e024163057ec5ccc508a29ab3b9ed4.tar.bz2
ChibiOS-Contrib-7b2c61a676e024163057ec5ccc508a29ab3b9ed4.zip
Merge branch 'master' of https://github.com/ChibiOS/ChibiOS-Contrib
Diffstat (limited to 'os/hal/ports/STM32/LLD')
-rw-r--r--os/hal/ports/STM32/LLD/COMPv1/driver.mk9
-rw-r--r--os/hal/ports/STM32/LLD/CRCv1/driver.mk9
-rwxr-xr-xos/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.c2
-rw-r--r--os/hal/ports/STM32/LLD/DMA2Dv1/driver.mk2
-rw-r--r--os/hal/ports/STM32/LLD/FSMCv1/driver.mk17
-rw-r--r--os/hal/ports/STM32/LLD/LTDCv1/driver.mk2
-rw-r--r--os/hal/ports/STM32/LLD/OPAMPv1/driver.mk9
-rw-r--r--os/hal/ports/STM32/LLD/OPAMPv1/hal_opamp_lld.c615
-rw-r--r--os/hal/ports/STM32/LLD/OPAMPv1/hal_opamp_lld.h336
-rw-r--r--os/hal/ports/STM32/LLD/TIMv1/driver.mk17
-rw-r--r--os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.h2
-rw-r--r--os/hal/ports/STM32/LLD/USBHv1/driver.mk9
-rw-r--r--os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c13
13 files changed, 1034 insertions, 8 deletions
diff --git a/os/hal/ports/STM32/LLD/COMPv1/driver.mk b/os/hal/ports/STM32/LLD/COMPv1/driver.mk
new file mode 100644
index 0000000..e819a32
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/COMPv1/driver.mk
@@ -0,0 +1,9 @@
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_COMP TRUE,$(HALCONF)),)
+PLATFORMSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/COMPv1/hal_comp_lld.c
+endif
+else
+PLATFORMSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/COMPv1/hal_comp_lld.c
+endif
+
+PLATFORMINC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/COMPv1
diff --git a/os/hal/ports/STM32/LLD/CRCv1/driver.mk b/os/hal/ports/STM32/LLD/CRCv1/driver.mk
new file mode 100644
index 0000000..b8c16d4
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/CRCv1/driver.mk
@@ -0,0 +1,9 @@
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_CRC TRUE,$(HALCONF)),)
+PLATFORMSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.c
+endif
+else
+PLATFORMSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.c
+endif
+
+PLATFORMINC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/CRCv1
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 180a383..882022b 100755
--- a/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.c
+++ b/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.c
@@ -160,7 +160,7 @@ void crc_lld_start(CRCDriver *crcp) {
if (crcp->config == NULL)
crcp->config = &default_config;
- rccEnableCRC();
+ rccEnableCRC( FALSE );
#if STM32_CRC_PROGRAMMABLE == TRUE
crcp->crc->INIT = crcp->config->initial_val;
diff --git a/os/hal/ports/STM32/LLD/DMA2Dv1/driver.mk b/os/hal/ports/STM32/LLD/DMA2Dv1/driver.mk
new file mode 100644
index 0000000..22be164
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/DMA2Dv1/driver.mk
@@ -0,0 +1,2 @@
+PLATFORMSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/DMA2Dv1/hal_stm32_dma2d.c
+PLATFORMINC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/DMA2Dv1
diff --git a/os/hal/ports/STM32/LLD/FSMCv1/driver.mk b/os/hal/ports/STM32/LLD/FSMCv1/driver.mk
new file mode 100644
index 0000000..d92230d
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/FSMCv1/driver.mk
@@ -0,0 +1,17 @@
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_FSMC TRUE,$(HALCONF)),)
+PLATFORMSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.c
+endif
+ifneq ($(findstring HAL_USE_NAND TRUE,$(HALCONF)),)
+PLATFORMSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/FSMCv1/hal_nand_lld.c
+endif
+else
+PLATFORMSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/FSMCv1/hal_nand_lld.c
+endif
+
+PLATFORMINC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/FSMCv1
diff --git a/os/hal/ports/STM32/LLD/LTDCv1/driver.mk b/os/hal/ports/STM32/LLD/LTDCv1/driver.mk
new file mode 100644
index 0000000..d6cabcd
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/LTDCv1/driver.mk
@@ -0,0 +1,2 @@
+PLATFORMSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/LTDCv1/hal_stm32_ltdc.c
+PLATFORMINC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/LTDCv1
diff --git a/os/hal/ports/STM32/LLD/OPAMPv1/driver.mk b/os/hal/ports/STM32/LLD/OPAMPv1/driver.mk
new file mode 100644
index 0000000..08dc0f4
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/OPAMPv1/driver.mk
@@ -0,0 +1,9 @@
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_OPAMP TRUE,$(HALCONF)),)
+PLATFORMSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/OPAMPv1/hal_opamp_lld.c
+endif
+else
+PLATFORMSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/OPAMPv1/hal_opamp_lld.c
+endif
+
+PLATFORMINC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/OPAMPv1
diff --git a/os/hal/ports/STM32/LLD/OPAMPv1/hal_opamp_lld.c b/os/hal/ports/STM32/LLD/OPAMPv1/hal_opamp_lld.c
new file mode 100644
index 0000000..db988aa
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/OPAMPv1/hal_opamp_lld.c
@@ -0,0 +1,615 @@
+/*
+ ChibiOS - Copyright (C) 2006..2019 Giovanni Di Sirio
+ Copyright (C) 2019 Fabien Poussin (fabien.poussin (at) google's mail)
+ Copyright (C) 2019 Alexandre Bustico
+
+ 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_opamp_lld.c
+ * @brief STM32 Operational Amplifier subsystem low level driver header.
+ *
+ * @addtogroup OPAMP
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_OPAMP || defined(__DOXYGEN__)
+
+#include "hal_opamp.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief OPAMPD1 driver identifier.
+ * @note The driver OPAMPD1 allocates the comparator OPAMP1 when enabled.
+ */
+#if STM32_OPAMP_USE_OPAMP1 || defined(__DOXYGEN__)
+OPAMPDriver OPAMPD1;
+#endif
+
+/**
+ * @brief OPAMPD2 driver identifier.
+ * @note The driver OPAMPD2 allocates the comparator OPAMP2 when enabled.
+ */
+#if STM32_OPAMP_USE_OPAMP2 || defined(__DOXYGEN__)
+OPAMPDriver OPAMPD2;
+#endif
+
+/**
+ * @brief OPAMPD3 driver identifier.
+ * @note The driver OPAMPD3 allocates the comparator OPAMP3 when enabled.
+ */
+#if STM32_OPAMP_USE_OPAMP3 || defined(__DOXYGEN__)
+OPAMPDriver OPAMPD3;
+#endif
+
+/**
+ * @brief OPAMPD4 driver identifier.
+ * @note The driver OPAMPD4 allocates the comparator OPAMP4 when enabled.
+ */
+#if STM32_OPAMP_USE_OPAMP4 || defined(__DOXYGEN__)
+OPAMPDriver OPAMPD4;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level OPAMP driver initialization.
+ *
+ * @notapi
+ */
+void opamp_lld_init(void) {
+
+#if STM32_OPAMP_USE_OPAMP1
+ /* Driver initialization.*/
+ opampObjectInit(&OPAMPD1);
+ OPAMPD1.opamp = OPAMP;
+ OPAMPD1.opamp->CSR = 0;
+#endif
+
+#if STM32_OPAMP_USE_OPAMP2
+ /* Driver initialization.*/
+ opampObjectInit(&OPAMPD2);
+ OPAMPD2.opamp = OPAMP2;
+ OPAMPD2.opamp->CSR = 0;
+#endif
+
+#if STM32_OPAMP_USE_OPAMP3
+ /* Driver initialization.*/
+ opampObjectInit(&OPAMPD3);
+ OPAMPD3.opamp = OPAMP3;
+ OPAMPD3.opamp->CSR = 0;
+#endif
+
+#if STM32_OPAMP_USE_OPAMP4
+ /* Driver initialization.*/
+ opampObjectInit(&OPAMPD4);
+ OPAMPD4.opamp = OPAMP4;
+ OPAMPD4.opamp->CSR = 0;
+#endif
+
+}
+
+/**
+ * @brief Configures and activates the OPAMP peripheral.
+ *
+ * @param[in] opampp pointer to the @p OPAMPDriver object
+ *
+ * @notapi
+ */
+void opamp_lld_start(OPAMPDriver *opampp) {
+
+ // Apply CSR Execpt the enable bit.
+ opampp->opamp->CSR = opampp->config->csr & ~OPAMP_CSR_OPAMPxEN;
+
+}
+
+/**
+ * @brief Deactivates the comp peripheral.
+ *
+ * @param[in] opampp pointer to the @p OPAMPDriver object
+ *
+ * @notapi
+ */
+void opamp_lld_stop(OPAMPDriver *opampp) {
+
+ if (opampp->state == OPAMP_ACTIVE) {
+
+ opampp->opamp->CSR = 0;
+ }
+
+}
+
+/**
+ * @brief Enables the output.
+ *
+ * @param[in] opampp pointer to the @p OPAMPDriver object
+ *
+ * @notapi
+ */
+void opamp_lld_enable(OPAMPDriver *opampp) {
+
+ opampp->opamp->CSR |= OPAMP_CSR_OPAMPxEN; /* Enable */
+}
+
+/**
+ * @brief Disables the output.
+ *
+ * @param[in] opampp pointer to the @p OPAMPDriver object
+ *
+ * @notapi
+ */
+void opamp_lld_disable(OPAMPDriver *opampp) {
+
+ opampp->opamp->CSR &= ~OPAMP_CSR_OPAMPxEN; /* Disable */
+}
+
+#if STM32_OPAMP_USER_TRIM_ENABLED
+
+void opamp_lld_calibrate_once(void)
+{
+#if STM32_OPAMP_USE_OPAMP1
+ uint32_t trimmingvaluen1 = 16U;
+ uint32_t trimmingvaluep1 = 16U;
+ OPAMPD1.state = OPAMP_CALIBRATING;
+#define CSRm OPAMPD1.opamp->CSR
+ /* Set Calibration mode */
+ /* Non-inverting input connected to calibration reference voltage. */
+ CSRm |= OPAMP_CSR_FORCEVP;
+ /* user trimming values are used for offset calibration */
+ CSRm |= OPAMP_CSR_USERTRIM;
+ /* Enable calibration */
+ CSRm |= OPAMP_CSR_CALON;
+ /* 1st calibration - N Select 90U% VREF */
+ MODIFY_REG(CSRm, OPAMP_CSR_CALSEL, OPAMPx_CSR_CALSEL_90P);
+ /* Enable the opamps */
+ CSRm |= OPAMP_CSR_OPAMPxEN;
+#undef CSRm
+#endif
+
+#if STM32_OPAMP_USE_OPAMP2
+ uint32_t trimmingvaluen2 = 16U;
+ uint32_t trimmingvaluep2 = 16U;
+ OPAMPD2.state = OPAMP_CALIBRATING;
+#define CSRm OPAMPD2.opamp->CSR
+ CSRm |= OPAMP_CSR_FORCEVP;
+ CSRm |= OPAMP_CSR_USERTRIM;
+ CSRm |= OPAMP_CSR_CALON;
+ MODIFY_REG(CSRm, OPAMP_CSR_CALSEL, OPAMPx_CSR_CALSEL_90P);
+ CSRm |= OPAMP_CSR_OPAMPxEN;
+#undef CSRm
+#endif
+
+#if STM32_OPAMP_USE_OPAMP3
+ uint32_t trimmingvaluen3 = 16U;
+ uint32_t trimmingvaluep3 = 16U;
+ OPAMPD3.state = OPAMP_CALIBRATING;
+#define CSRm OPAMPD3.opamp->CSR
+ CSRm |= OPAMP_CSR_FORCEVP;
+ CSRm |= OPAMP_CSR_USERTRIM;
+ CSRm |= OPAMP_CSR_CALON;
+ MODIFY_REG(CSRm, OPAMP_CSR_CALSEL, OPAMPx_CSR_CALSEL_90P);
+ CSRm |= OPAMP_CSR_OPAMPxEN;
+#undef CSRm
+#endif
+
+#if STM32_OPAMP_USE_OPAMP4
+ uint32_t trimmingvaluen4 = 16U;
+ uint32_t trimmingvaluep4 = 16U;
+ OPAMPD4.state = OPAMP_CALIBRATING;
+#define CSRm OPAMPD4.opamp->CSR
+ CSRm |= OPAMP_CSR_FORCEVP;
+ CSRm |= OPAMP_CSR_USERTRIM;
+ CSRm |= OPAMP_CSR_CALON;
+ MODIFY_REG(CSRm, OPAMP_CSR_CALSEL, OPAMPx_CSR_CALSEL_90P);
+ CSRm |= OPAMP_CSR_OPAMPxEN;
+#undef CSRm
+#endif
+
+ chSysPolledDelayX(MS2RTC(STM32_SYSCLK, 20));
+ uint32_t delta = 8U;
+
+ while (delta != 0U) {
+#if STM32_OPAMP_USE_OPAMP1
+ MODIFY_REG(OPAMPD1.opamp->CSR, OPAMP_CSR_TRIMOFFSETN,
+ trimmingvaluen1<<OPAMP_CSR_TRIMOFFSETN_Pos);
+#endif
+#if STM32_OPAMP_USE_OPAMP2
+ MODIFY_REG(OPAMPD2.opamp->CSR, OPAMP_CSR_TRIMOFFSETN,
+ trimmingvaluen2<<OPAMP_CSR_TRIMOFFSETN_Pos);
+#endif
+#if STM32_OPAMP_USE_OPAMP3
+ MODIFY_REG(OPAMPD3.opamp->CSR, OPAMP_CSR_TRIMOFFSETN,
+ trimmingvaluen3<<OPAMP_CSR_TRIMOFFSETN_Pos);
+#endif
+#if STM32_OPAMP_USE_OPAMP4
+ MODIFY_REG(OPAMPD4.opamp->CSR, OPAMP_CSR_TRIMOFFSETN,
+ trimmingvaluen4<<OPAMP_CSR_TRIMOFFSETN_Pos);
+#endif
+
+ /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */
+ /* Offset trim time: during calibration, minimum time needed between */
+ /* two steps to have 1 mV accuracy */
+ chSysPolledDelayX(MS2RTC(STM32_SYSCLK, 2));
+
+#if STM32_OPAMP_USE_OPAMP1
+ if (OPAMPD1.opamp->CSR & OPAMP_CSR_OUTCAL) {
+ /* OPAMP_CSR_OUTCAL is HIGH try higher trimming */
+ trimmingvaluen1 += delta;
+ } else {
+ /* OPAMP_CSR_OUTCAL is LOW try lower trimming */
+ trimmingvaluen1 -= delta;
+ }
+#endif
+
+#if STM32_OPAMP_USE_OPAMP2
+ if (OPAMPD2.opamp->CSR & OPAMP_CSR_OUTCAL) {
+ trimmingvaluen2 += delta;
+ } else {
+ trimmingvaluen2 -= delta;
+ }
+#endif
+
+#if STM32_OPAMP_USE_OPAMP3
+ if (OPAMPD3.opamp->CSR & OPAMP_CSR_OUTCAL) {
+ trimmingvaluen3 += delta;
+ } else {
+ trimmingvaluen3 -= delta;
+ }
+#endif
+
+#if STM32_OPAMP_USE_OPAMP4
+ if (OPAMPD4.opamp->CSR & OPAMP_CSR_OUTCAL) {
+ trimmingvaluen4 += delta;
+ } else {
+ trimmingvaluen4 -= delta;
+ }
+#endif
+
+ delta >>= 1U;
+
+ }
+
+ /* Still need to check if righ calibration is current value or un step below */
+ /* Indeed the first value that causes the OUTCAL bit to change from 1 to 0U */
+#if STM32_OPAMP_USE_OPAMP1
+ MODIFY_REG(OPAMPD1.opamp->CSR, OPAMP_CSR_TRIMOFFSETN,
+ trimmingvaluen1<<OPAMP_CSR_TRIMOFFSETN_Pos);
+#endif
+#if STM32_OPAMP_USE_OPAMP2
+ MODIFY_REG(OPAMPD2.opamp->CSR, OPAMP_CSR_TRIMOFFSETN,
+ trimmingvaluen2<<OPAMP_CSR_TRIMOFFSETN_Pos);
+#endif
+#if STM32_OPAMP_USE_OPAMP3
+ MODIFY_REG(OPAMPD3.opamp->CSR, OPAMP_CSR_TRIMOFFSETN,
+ trimmingvaluen3<<OPAMP_CSR_TRIMOFFSETN_Pos);
+#endif
+#if STM32_OPAMP_USE_OPAMP4
+ MODIFY_REG(OPAMPD4.opamp->CSR, OPAMP_CSR_TRIMOFFSETN,
+ trimmingvaluen4<<OPAMP_CSR_TRIMOFFSETN_Pos);
+#endif
+
+ /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */
+ /* Offset trim time: during calibration, minimum time needed between */
+ /* two steps to have 1 mV accuracy */
+ chSysPolledDelayX(MS2RTC(STM32_SYSCLK, 2));
+
+#if STM32_OPAMP_USE_OPAMP1
+ if (OPAMPD1.opamp->CSR & OPAMP_CSR_OUTCAL) {
+ /* OPAMP_CSR_OUTCAL is HIGH try higher trimming */
+ trimmingvaluen1 += (trimmingvaluen1 != 31);
+ MODIFY_REG(OPAMPD1.opamp->CSR, OPAMP_CSR_TRIMOFFSETN,
+ trimmingvaluen1<<OPAMP_CSR_TRIMOFFSETN_Pos);
+ }
+#endif
+
+#if STM32_OPAMP_USE_OPAMP2
+ if (OPAMPD2.opamp->CSR & OPAMP_CSR_OUTCAL) {
+ trimmingvaluen2 += (trimmingvaluen2 != 31);
+ MODIFY_REG(OPAMPD2.opamp->CSR, OPAMP_CSR_TRIMOFFSETN,
+ trimmingvaluen2<<OPAMP_CSR_TRIMOFFSETN_Pos);
+ }
+#endif
+
+#if STM32_OPAMP_USE_OPAMP3
+ if (OPAMPD3.opamp->CSR & OPAMP_CSR_OUTCAL) {
+ trimmingvaluen3 += (trimmingvaluen3 != 31);
+ MODIFY_REG(OPAMPD3.opamp->CSR, OPAMP_CSR_TRIMOFFSETN,
+ trimmingvaluen3<<OPAMP_CSR_TRIMOFFSETN_Pos);
+ }
+#endif
+
+#if STM32_OPAMP_USE_OPAMP4
+ if (OPAMPD4.opamp->CSR & OPAMP_CSR_OUTCAL) {
+ trimmingvaluen4 += (trimmingvaluen4 != 31);
+ MODIFY_REG(OPAMPD4.opamp->CSR, OPAMP_CSR_TRIMOFFSETN,
+ trimmingvaluen4<<OPAMP_CSR_TRIMOFFSETN_Pos);
+ }
+#endif
+
+ /* 2nd calibration - P */
+ /* Select 10U% VREF */
+#if STM32_OPAMP_USE_OPAMP1
+ MODIFY_REG(OPAMPD1.opamp->CSR, OPAMP_CSR_CALSEL, OPAMPx_CSR_CALSEL_10P);
+#endif
+#if STM32_OPAMP_USE_OPAMP2
+ MODIFY_REG(OPAMPD2.opamp->CSR, OPAMP_CSR_CALSEL, OPAMPx_CSR_CALSEL_10P);
+#endif
+#if STM32_OPAMP_USE_OPAMP3
+ MODIFY_REG(OPAMPD3.opamp->CSR, OPAMP_CSR_CALSEL, OPAMPx_CSR_CALSEL_10P);
+#endif
+#if STM32_OPAMP_USE_OPAMP4
+ MODIFY_REG(OPAMPD4.opamp->CSR, OPAMP_CSR_CALSEL, OPAMPx_CSR_CALSEL_10P);
+#endif
+
+ delta = 8U;
+
+ while (delta != 0U) {
+#if STM32_OPAMP_USE_OPAMP1
+ MODIFY_REG(OPAMPD1.opamp->CSR, OPAMP_CSR_TRIMOFFSETP,
+ trimmingvaluep1<<OPAMP_CSR_TRIMOFFSETP_Pos);
+#endif
+#if STM32_OPAMP_USE_OPAMP2
+ MODIFY_REG(OPAMPD2.opamp->CSR, OPAMP_CSR_TRIMOFFSETP,
+ trimmingvaluep2<<OPAMP_CSR_TRIMOFFSETP_Pos);
+#endif
+#if STM32_OPAMP_USE_OPAMP3
+ MODIFY_REG(OPAMPD3.opamp->CSR, OPAMP_CSR_TRIMOFFSETP,
+ trimmingvaluep3<<OPAMP_CSR_TRIMOFFSETP_Pos);
+#endif
+#if STM32_OPAMP_USE_OPAMP4
+ MODIFY_REG(OPAMPD4.opamp->CSR, OPAMP_CSR_TRIMOFFSETP,
+ trimmingvaluep4<<OPAMP_CSR_TRIMOFFSETP_Pos);
+#endif
+
+
+ /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */
+ /* Offset trim time: during calibration, minimum time needed between */
+ /* two steps to have 1 mV accuracy */
+ chSysPolledDelayX(MS2RTC(STM32_SYSCLK, 2));
+#if STM32_OPAMP_USE_OPAMP1
+ if (OPAMPD1.opamp->CSR & OPAMP_CSR_OUTCAL) {
+ /* OPAMP_CSR_OUTCAL is HIGH try higher trimming */
+ trimmingvaluep1 += delta;
+ } else {
+ /* OPAMP_CSR_OUTCAL is LOW try lower trimming */
+ trimmingvaluep1 -= delta;
+ }
+#endif
+
+#if STM32_OPAMP_USE_OPAMP2
+ if (OPAMPD2.opamp->CSR & OPAMP_CSR_OUTCAL) {
+ trimmingvaluep2 += delta;
+ } else {
+ trimmingvaluep2 -= delta;
+ }
+#endif
+
+#if STM32_OPAMP_USE_OPAMP3
+ if (OPAMPD3.opamp->CSR & OPAMP_CSR_OUTCAL) {
+ trimmingvaluep3 += delta;
+ } else {
+ trimmingvaluep3 -= delta;
+ }
+#endif
+
+#if STM32_OPAMP_USE_OPAMP4
+ if (OPAMPD4.opamp->CSR & OPAMP_CSR_OUTCAL) {
+ trimmingvaluep4 += delta;
+ } else {
+ trimmingvaluep4 -= delta;
+ }
+#endif
+
+ delta >>= 1U;
+ }
+
+ /* Still need to check if righ calibration is current value or un step below */
+ /* Indeed the first value that causes the OUTCAL bit to change from 1 to 0U */
+#if STM32_OPAMP_USE_OPAMP1
+ MODIFY_REG(OPAMPD1.opamp->CSR, OPAMP_CSR_TRIMOFFSETP,
+ trimmingvaluep1<<OPAMP_CSR_TRIMOFFSETP_Pos);
+#endif
+#if STM32_OPAMP_USE_OPAMP2
+ MODIFY_REG(OPAMPD2.opamp->CSR, OPAMP_CSR_TRIMOFFSETP,
+ trimmingvaluep2<<OPAMP_CSR_TRIMOFFSETP_Pos);
+#endif
+#if STM32_OPAMP_USE_OPAMP3
+ MODIFY_REG(OPAMPD3.opamp->CSR, OPAMP_CSR_TRIMOFFSETP,
+ trimmingvaluep3<<OPAMP_CSR_TRIMOFFSETP_Pos);
+#endif
+#if STM32_OPAMP_USE_OPAMP4
+ MODIFY_REG(OPAMPD4.opamp->CSR, OPAMP_CSR_TRIMOFFSETP,
+ trimmingvaluep4<<OPAMP_CSR_TRIMOFFSETP_Pos);
+#endif
+
+ /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */
+ /* Offset trim time: during calibration, minimum time needed between */
+ /* two steps to have 1 mV accuracy */
+ chSysPolledDelayX(MS2RTC(STM32_SYSCLK, 2));
+
+#if STM32_OPAMP_USE_OPAMP1
+ if (OPAMPD1.opamp->CSR & OPAMP_CSR_OUTCAL) {
+ /* OPAMP_CSR_OUTCAL is HIGH try higher trimming */
+ trimmingvaluep1 += (trimmingvaluep1 != 31);
+ MODIFY_REG(OPAMPD1.opamp->CSR, OPAMP_CSR_TRIMOFFSETP,
+ trimmingvaluep1<<OPAMP_CSR_TRIMOFFSETP_Pos);
+ }
+#endif
+
+#if STM32_OPAMP_USE_OPAMP2
+ if (OPAMPD2.opamp->CSR & OPAMP_CSR_OUTCAL) {
+ trimmingvaluep2 += (trimmingvaluep2 != 31);
+ MODIFY_REG(OPAMPD2.opamp->CSR, OPAMP_CSR_TRIMOFFSETP,
+ trimmingvaluep2<<OPAMP_CSR_TRIMOFFSETP_Pos);
+ }
+#endif
+
+#if STM32_OPAMP_USE_OPAMP3
+ if (OPAMPD3.opamp->CSR & OPAMP_CSR_OUTCAL) {
+ trimmingvaluep3 += (trimmingvaluep3 != 31);
+ MODIFY_REG(OPAMPD3.opamp->CSR, OPAMP_CSR_TRIMOFFSETP,
+ trimmingvaluep3<<OPAMP_CSR_TRIMOFFSETP_Pos);
+ }
+#endif
+
+#if STM32_OPAMP_USE_OPAMP4
+ if (OPAMPD4.opamp->CSR & OPAMP_CSR_OUTCAL) {
+ trimmingvaluep4 += (trimmingvaluep4 != 31);
+ MODIFY_REG(OPAMPD4.opamp->CSR, OPAMP_CSR_TRIMOFFSETP,
+ trimmingvaluep4<<OPAMP_CSR_TRIMOFFSETP_Pos);
+ }
+#endif
+
+#if STM32_OPAMP_USE_OPAMP1
+#define CSRm OPAMPD1.opamp->CSR
+ /* Disable calibration */
+ CSRm &= ~OPAMP_CSR_CALON;
+ /* Disable the OPAMPs */
+ CSRm &= ~OPAMP_CSR_OPAMPxEN;
+ /* Set normal operating mode back */
+ CSRm &= ~OPAMP_CSR_FORCEVP;
+ /* Write calibration result N */
+ OPAMPD1.trim_n = trimmingvaluen1;
+ /* Write calibration result P */
+ OPAMPD1.trim_p = trimmingvaluep1;
+ MODIFY_REG(CSRm, OPAMP_CSR_TRIMOFFSETN,
+ trimmingvaluen1<<OPAMP_CSR_TRIMOFFSETN_Pos);
+ MODIFY_REG(CSRm, OPAMP_CSR_TRIMOFFSETP,
+ trimmingvaluep1<<OPAMP_CSR_TRIMOFFSETP_Pos);
+ OPAMPD1.state = OPAMP_STOP;
+#undef CSRm
+#endif
+
+#if STM32_OPAMP_USE_OPAMP2
+#define CSRm OPAMPD2.opamp->CSR
+ /* Disable calibration */
+ CSRm &= ~OPAMP_CSR_CALON;
+ /* Disable the OPAMPs */
+ CSRm &= ~OPAMP_CSR_OPAMPxEN;
+ /* Set normal operating mode back */
+ CSRm &= ~OPAMP_CSR_FORCEVP;
+ /* Write calibration result N */
+ OPAMPD2.trim_n = trimmingvaluen2;
+ /* Write calibration result P */
+ OPAMPD2.trim_p = trimmingvaluep2;
+ MODIFY_REG(CSRm, OPAMP_CSR_TRIMOFFSETN,
+ trimmingvaluen2<<OPAMP_CSR_TRIMOFFSETN_Pos);
+ MODIFY_REG(CSRm, OPAMP_CSR_TRIMOFFSETP,
+ trimmingvaluep2<<OPAMP_CSR_TRIMOFFSETP_Pos);
+ OPAMPD2.state = OPAMP_STOP;
+#undef CSRm
+#endif
+
+#if STM32_OPAMP_USE_OPAMP3
+#define CSRm OPAMPD3.opamp->CSR
+ /* Disable calibration */
+ CSRm &= ~OPAMP_CSR_CALON;
+ /* Disable the OPAMPs */
+ CSRm &= ~OPAMP_CSR_OPAMPxEN;
+ /* Set normal operating mode back */
+ CSRm &= ~OPAMP_CSR_FORCEVP;
+ /* Write calibration result N */
+ OPAMPD3.trim_n = trimmingvaluen3;
+ /* Write calibration result P */
+ OPAMPD3.trim_p = trimmingvaluep3;
+ MODIFY_REG(CSRm, OPAMP_CSR_TRIMOFFSETN,
+ trimmingvaluen3<<OPAMP_CSR_TRIMOFFSETN_Pos);
+ MODIFY_REG(CSRm, OPAMP_CSR_TRIMOFFSETP,
+ trimmingvaluep3<<OPAMP_CSR_TRIMOFFSETP_Pos);
+ OPAMPD3.state = OPAMP_STOP;
+#undef CSRm
+#endif
+
+#if STM32_OPAMP_USE_OPAMP4
+#define CSRm OPAMPD4.opamp->CSR
+ /* Disable calibration */
+ CSRm &= ~OPAMP_CSR_CALON;
+ /* Disable the OPAMPs */
+ CSRm &= ~OPAMP_CSR_OPAMPxEN;
+ /* Set normal operating mode back */
+ CSRm &= ~OPAMP_CSR_FORCEVP;
+ /* Write calibration result N */
+ OPAMPD4.trim_n = trimmingvaluen4;
+ /* Write calibration result P */
+ OPAMPD4.trim_p = trimmingvaluep4;
+ MODIFY_REG(CSRm, OPAMP_CSR_TRIMOFFSETN,
+ trimmingvaluen4<<OPAMP_CSR_TRIMOFFSETN_Pos);
+ MODIFY_REG(CSRm, OPAMP_CSR_TRIMOFFSETP,
+ trimmingvaluep4<<OPAMP_CSR_TRIMOFFSETP_Pos);
+ OPAMPD4.state = OPAMP_STOP;
+#undef CSRm
+#endif
+}
+
+void opamp_lld_calibrate(void)
+{
+ uint8_t trim_n[4] = {255};
+ uint8_t trim_p[4] = {255};
+ bool done;
+ do {
+ done = true;
+ opamp_lld_calibrate_once();
+#if STM32_OPAMP_USE_OPAMP1
+ done = done && (OPAMPD1.trim_n == trim_n[0]) && (OPAMPD1.trim_p == trim_p[0]);
+ trim_n[0] = OPAMPD1.trim_n;
+ trim_p[0] = OPAMPD1.trim_p;
+#endif
+#if STM32_OPAMP_USE_OPAMP2
+ done = done && (OPAMPD2.trim_n == trim_n[1]) && (OPAMPD2.trim_p == trim_p[1]);
+ trim_n[1] = OPAMPD2.trim_n;
+ trim_p[1] = OPAMPD2.trim_p;
+#endif
+#if STM32_OPAMP_USE_OPAMP3
+ done = done && (OPAMPD3.trim_n == trim_n[2]) && (OPAMPD3.trim_p == trim_p[2]);
+ trim_n[2] = OPAMPD3.trim_n;
+ trim_p[2] = OPAMPD3.trim_p;
+#endif
+#if STM32_OPAMP_USE_OPAMP4
+ done = done && (OPAMPD4.trim_n == trim_n[3]) && (OPAMPD4.trim_p == trim_p[3]);
+ trim_n[3] = OPAMPD4.trim_n;
+ trim_p[3] = OPAMPD4.trim_p;
+#endif
+ } while (!done);
+
+}
+#endif // STM32_OPAMP_USER_TRIM_ENABLED
+#endif /* HAL_USE_OPAMP */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/OPAMPv1/hal_opamp_lld.h b/os/hal/ports/STM32/LLD/OPAMPv1/hal_opamp_lld.h
new file mode 100644
index 0000000..6a701b9
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/OPAMPv1/hal_opamp_lld.h
@@ -0,0 +1,336 @@
+/*
+ ChibiOS - Copyright (C) 2006..2019 Giovanni Di Sirio
+ Copyright (C) 2019 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/opamp_lld.h
+ * @brief STM32 Operational Amplifier subsystem low level driver header.
+ *
+ * @addtogroup OPAMP
+ * @{
+ */
+
+#ifndef HAL_OPAMP_LLD_H_
+#define HAL_OPAMP_LLD_H_
+
+#include "hal.h"
+
+#if HAL_USE_OPAMP || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+#define OPAMPx_CSR_PGAGAIN_x2 ((uint32_t)0x00000000)
+#define OPAMPx_CSR_PGAGAIN_x4 OPAMP_CSR_PGGAIN_0
+#define OPAMPx_CSR_PGAGAIN_x8 OPAMP_CSR_PGGAIN_1
+#define OPAMPx_CSR_PGAGAIN_x16 ((uint32_t)0x0000C000)
+#define OPAMPx_CSR_PGAGAIN_LESS_IFB_VM0 (0b10 << 16)
+#define OPAMPx_CSR_PGAGAIN_LESS_IFB_VM1 (0b11 << 16)
+
+#define OPAMPx_CSR_PGACONNECT_GROUND ((uint32_t)0x00000000)
+#define OPAMPx_CSR_PGACONNECT_IO1 OPAMP_CSR_PGGAIN_3
+#define OPAMPx_CSR_PGACONNECT_IO2 ((uint32_t)0x00030000)
+
+#define OPAMPx_CSR_CALSEL_3P3 ((uint32_t)0x00000000)
+#define OPAMPx_CSR_CALSEL_10P OPAMP_CSR_CALSEL_0
+#define OPAMPx_CSR_CALSEL_50P OPAMP_CSR_CALSEL_1
+#define OPAMPx_CSR_CALSEL_90P OPAMP_CSR_CALSEL
+
+#define OPAMPx_CSR_TRIM_FACTORY ((uint32_t)0x00000000)
+#define OPAMPx_CSR_TRIM_USER OPAMP_CSR_USERTRIM /*!< User trimming */
+
+#define OPAMPx_CSR_OUTPUT_NORMAL ((uint32_t)0x00000000)
+#define OPAMPx_CSR_OUTPUT_INVERTED OPAMP_CSR_OUTCAL
+
+#define OPAMPx_CSR_LOCK OPAMP_CSR_LOCK
+
+
+#if defined(STM32F302xB) || defined(STM32F302xC) || defined(STM32F302xD) \
+|| defined(STM32F302xE) || defined(STM32F302xc) || defined(STM32F302xe) \
+|| defined(STM32L1XX) || defined(STM32L4XX) || defined(STM32H7XX)
+#define STM32_HAS_OPAMP1 TRUE
+#define STM32_HAS_OPAMP2 TRUE
+#define STM32_HAS_OPAMP3 FALSE
+#define STM32_HAS_OPAMP4 FALSE
+
+#elif defined(STM32F303xB) || defined(STM32F303xC) || defined(STM32F303xE) \
+|| defined(STM32F358xx) || defined(STM32F398xx)
+#define STM32_HAS_OPAMP1 TRUE
+#define STM32_HAS_OPAMP2 TRUE
+#define STM32_HAS_OPAMP3 TRUE
+#define STM32_HAS_OPAMP4 TRUE
+
+#else
+#define STM32_HAS_OPAMP1 FALSE
+#define STM32_HAS_OPAMP2 FALSE
+#define STM32_HAS_OPAMP3 FALSE
+#define STM32_HAS_OPAMP4 FALSE
+#endif
+
+
+#if STM32_HAS_OPAMP1
+#define OPAMP1_CSR_VPSEL_PA07 ((uint32_t)0x00000000)
+#define OPAMP1_CSR_VPSEL_PA05 OPAMP_CSR_VPSEL_0
+#define OPAMP1_CSR_VPSEL_PA03 OPAMP_CSR_VPSEL_1
+#define OPAMP1_CSR_VPSEL_PA01 OPAMP_CSR_VPSEL
+
+#define OPAMP1_CSR_VMSEL_PC05 ((uint32_t)0x00000000)
+#define OPAMP1_CSR_VMSEL_PA03 OPAMP_CSR_VMSEL_0
+#define OPAMP1_CSR_VMSEL_PGA OPAMP_CSR_VMSEL_1
+#define OPAMP1_CSR_VMSEL_FOLWR OPAMP_CSR_VMSEL
+
+#define OPAMP1_CSR_VMSSEL_PC05 ((uint32_t)0x00000000)
+#define OPAMP1_CSR_VMSSEL_PA03 OPAMP_CSR_VMSSEL
+
+#define OPAMP1_CSR_VPSSEL_PA07 ((uint32_t)0x00000000)
+#define OPAMP1_CSR_VPSSEL_PA05 OPAMP_CSR_VPSSEL_0
+#define OPAMP1_CSR_VPSSEL_PA03 OPAMP_CSR_VPSSEL_1
+#define OPAMP1_CSR_VPSSEL_PA01 OPAMP_CSR_VPSSEL
+#endif
+
+#if STM32_HAS_OPAMP2
+#define OPAMP2_CSR_VPSEL_PD14 ((uint32_t)0x00000000)
+#define OPAMP2_CSR_VPSEL_PB14 OPAMP_CSR_VPSEL_0
+#define OPAMP2_CSR_VPSEL_PB00 OPAMP_CSR_VPSEL_1
+#define OPAMP2_CSR_VPSEL_PA07 OPAMP_CSR_VPSEL
+
+#define OPAMP2_CSR_VMSEL_PC05 ((uint32_t)0x00000000)
+#define OPAMP2_CSR_VMSEL_PA05 OPAMP_CSR_VMSEL_0
+#define OPAMP2_CSR_VMSEL_PGA OPAMP_CSR_VMSEL_1
+#define OPAMP2_CSR_VMSEL_FOLWR OPAMP_CSR_VMSEL
+
+#define OPAMP2_CSR_VMSSEL_PC05 ((uint32_t)0x00000000)
+#define OPAMP2_CSR_VMSSEL_PA05 OPAMP_CSR_VMSSEL
+
+#define OPAMP2_CSR_VPSSEL_PD14 ((uint32_t)0x00000000)
+#define OPAMP2_CSR_VPSSEL_PB14 OPAMP_CSR_VPSSEL_0
+#define OPAMP2_CSR_VPSSEL_PB00 OPAMP_CSR_VPSSEL_1
+#define OPAMP2_CSR_VPSSEL_PA07 OPAMP_CSR_VPSSEL
+#endif
+
+#if STM32_HAS_OPAMP3
+#define OPAMP3_CSR_VPSEL_PB13 ((uint32_t)0x00000000)
+#define OPAMP3_CSR_VPSEL_PA05 OPAMP_CSR_VPSEL_0
+#define OPAMP3_CSR_VPSEL_PA01 OPAMP_CSR_VPSEL_1
+#define OPAMP3_CSR_VPSEL_PB00 OPAMP_CSR_VPSEL
+
+#define OPAMP3_CSR_VMSEL_PB10 ((uint32_t)0x00000000)
+#define OPAMP3_CSR_VMSEL_PB02 OPAMP_CSR_VMSEL_0
+#define OPAMP3_CSR_VMSEL_PGA OPAMP_CSR_VMSEL_1
+#define OPAMP3_CSR_VMSEL_FOLWR OPAMP_CSR_VMSEL
+
+#define OPAMP3_CSR_VMSSEL_PB10 ((uint32_t)0x00000000)
+#define OPAMP3_CSR_VMSSEL_PB02 OPAMP_CSR_VMSSEL
+
+#define OPAMP3_CSR_VPSSEL_PB13 ((uint32_t)0x00000000)
+#define OPAMP3_CSR_VPSSEL_PA05 OPAMP_CSR_VPSSEL_0
+#define OPAMP3_CSR_VPSSEL_PA01 OPAMP_CSR_VPSSEL_1
+#define OPAMP3_CSR_VPSSEL_PB00 OPAMP_CSR_VPSSEL
+#endif
+
+#if STM32_HAS_OPAMP4
+#define OPAMP4_CSR_VPSEL_PD11 ((uint32_t)0x00000000)
+#define OPAMP4_CSR_VPSEL_PB11 OPAMP_CSR_VPSEL_0
+#define OPAMP4_CSR_VPSEL_PA04 OPAMP_CSR_VPSEL_1
+#define OPAMP4_CSR_VPSEL_PB13 OPAMP_CSR_VPSEL
+
+#define OPAMP4_CSR_VMSEL_PB10 ((uint32_t)0x00000000)
+#define OPAMP4_CSR_VMSEL_PD08 OPAMP_CSR_VMSEL_0
+#define OPAMP4_CSR_VMSEL_PGA OPAMP_CSR_VMSEL_1
+#define OPAMP4_CSR_VMSEL_FOLWR OPAMP_CSR_VMSEL
+
+#define OPAMP4_CSRVMSSEL_PB10 ((uint32_t)0x00000000)
+#define OPAMP4_CSR_VMSSEL_PD08 OPAMP_CSR_VMSSEL
+
+#define OPAMP4_CSR_VPSSEL_PD11 ((uint32_t)0x00000000)
+#define OPAMP4_CSR_VPSSEL_PB11 OPAMP_CSR_VPSSEL_0
+#define OPAMP4_CSR_VPSSEL_PA04 OPAMP_CSR_VPSSEL_1
+#define OPAMP4_CSR_VPSSEL_PB13 OPAMP_CSR_VPSSEL
+#endif
+
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+
+/**
+ * @brief OPAMPD1 driver enable switch.
+ * @details If set to @p TRUE the support for OPAMPD1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_OPAMP_USE_OPAMP1) || defined(__DOXYGEN__)
+#define STM32_OPAMP_USE_OPAMP1 FALSE
+#endif
+
+/**
+ * @brief OPAMPD2 driver enable switch.
+ * @details If set to @p TRUE the support for OPAMPD2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_OPAMP_USE_OPAMP2) || defined(__DOXYGEN__)
+#define STM32_OPAMP_USE_OPAMP2 FALSE
+#endif
+
+/**
+ * @brief OPAMPD3 driver enable switch.
+ * @details If set to @p TRUE the support for OPAMPD3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_OPAMP_USE_OPAMP3) || defined(__DOXYGEN__)
+#define STM32_OPAMP_USE_OPAMP3 FALSE
+#endif
+
+/**
+ * @brief OPAMPD4 driver enable switch.
+ * @details If set to @p TRUE the support for OPAMPD4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_OPAMP_USE_OPAMP4) || defined(__DOXYGEN__)
+#define STM32_OPAMP_USE_OPAMP4 FALSE
+#endif
+
+/**
+ * @brief OPAMPD TRIM and CALIBRATION enable switch.
+ * @details If set to @p TRUE the support for USER_TRIM is included and calibration is done @init
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_OPAMP_USER_TRIM_ENABLED) || defined(__DOXYGEN__)
+#define STM32_OPAMP_USER_TRIM_ENABLED TRUE
+#endif
+
+
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+
+#if STM32_OPAMP_USE_OPAMP1 && !STM32_HAS_OPAMP1
+#error "OPAMP1 not present in the selected device"
+#endif
+
+#if STM32_OPAMP_USE_OPAMP2 && !STM32_HAS_OPAMP2
+#error "OPAMP2 not present in the selected device"
+#endif
+
+#if STM32_OPAMP_USE_OPAMP3 && !STM32_HAS_OPAMP3
+#error "OPAMP3 not present in the selected device"
+#endif
+
+#if STM32_OPAMP_USE_OPAMP4 && !STM32_HAS_OPAMP4
+#error "OPAMP4 not present in the selected device"
+#endif
+
+#if !STM32_OPAMP_USE_OPAMP1 && !STM32_OPAMP_USE_OPAMP2 && \
+ !STM32_OPAMP_USE_OPAMP3 && !STM32_OPAMP_USE_OPAMP4
+#error "OPAMP driver activated but no OPAMP peripheral assigned"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief OPAMP CSR register initialization data.
+ * @note The value of this field should normally be equal to zero.
+ */
+ uint32_t csr;
+} OPAMPConfig;
+
+/**
+ * @brief Structure representing an OPAMP driver.
+ */
+struct OPAMPDriver {
+ /**
+ * @brief Driver state.
+ */
+ opampstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const OPAMPConfig *config;
+#if defined(OPAMP_DRIVER_EXT_FIELDS)
+ OPAMP_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the OPAMPx registers block.
+ */
+ OPAMP_TypeDef *opamp;
+
+#if STM32_OPAMP_USER_TRIM_ENABLED
+ uint16_t trim_p;
+ uint16_t trim_n;
+#endif
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_OPAMP_USE_OPAMP1 && !defined(__DOXYGEN__)
+extern OPAMPDriver OPAMPD1;
+#endif
+
+#if STM32_OPAMP_USE_OPAMP2 && !defined(__DOXYGEN__)
+extern OPAMPDriver OPAMPD2;
+#endif
+
+#if STM32_OPAMP_USE_OPAMP3 && !defined(__DOXYGEN__)
+extern OPAMPDriver OPAMPD3;
+#endif
+
+#if STM32_OPAMP_USE_OPAMP4 && !defined(__DOXYGEN__)
+extern OPAMPDriver OPAMPD4;
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void opamp_lld_init(void);
+ void opamp_lld_start(OPAMPDriver *compp);
+ void opamp_lld_stop(OPAMPDriver *compp);
+ void opamp_lld_enable(OPAMPDriver *compp);
+ void opamp_lld_disable(OPAMPDriver *compp);
+#if STM32_OPAMP_USER_TRIM_ENABLED
+ void opamp_lld_calibrate(void);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_OPAMP */
+
+#endif /* _opamp_lld_H_ */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/TIMv1/driver.mk b/os/hal/ports/STM32/LLD/TIMv1/driver.mk
new file mode 100644
index 0000000..86eb7c7
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/TIMv1/driver.mk
@@ -0,0 +1,17 @@
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_EICU TRUE,$(HALCONF)),)
+PLATFORMSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/TIMv1/hal_eicu_lld.c
+endif
+ifneq ($(findstring HAL_USE_QEI TRUE,$(HALCONF)),)
+PLATFORMSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c
+endif
+ifneq ($(findstring HAL_USE_TIMCAP TRUE,$(HALCONF)),)
+PLATFORMSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/TIMv1/hal_timcap_lld.c
+endif
+else
+PLATFORMSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/TIMv1/hal_eicu_lld.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/TIMv1/hal_timcap_lld.c
+endif
+
+PLATFORMINC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/TIMv1
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 73468f5..a9bdaf4 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.h
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.h
@@ -415,7 +415,7 @@ struct QEIDriver {
*
* @notapi
*/
-#define qei_lld_set_count(qeip, value)
+#define qei_lld_set_count(qeip, value) ((qeip)->tim->CNT = (value))
/*===========================================================================*/
/* External declarations. */
diff --git a/os/hal/ports/STM32/LLD/USBHv1/driver.mk b/os/hal/ports/STM32/LLD/USBHv1/driver.mk
new file mode 100644
index 0000000..b8f8988
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/USBHv1/driver.mk
@@ -0,0 +1,9 @@
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_USBH TRUE,$(HALCONF)),)
+PLATFORMSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c
+endif
+else
+PLATFORMSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c
+endif
+
+PLATFORMINC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/ports/STM32/LLD/USBHv1
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 226f1bb..192b008 100644
--- a/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c
+++ b/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c
@@ -594,9 +594,10 @@ void usbh_lld_ep_open(usbh_ep_t *ep) {
}
void usbh_lld_ep_close(usbh_ep_t *ep) {
- usbh_urb_t *urb, *tmp;
+ usbh_urb_t *urb;
uinfof("\t%s: Closing EP...", ep->name);
- list_for_each_entry_safe(urb, usbh_urb_t, tmp, &ep->urb_list, node) {
+ while (!list_empty(&ep->urb_list)) {
+ urb = list_first_entry(&ep->urb_list, usbh_urb_t, node);
uinfof("\t%s: Abort URB, USBH_URBSTATUS_DISCONNECTED", ep->name);
_usbh_urb_abort_and_waitS(urb, USBH_URBSTATUS_DISCONNECTED);
}
@@ -987,7 +988,7 @@ static inline void _hcint_int(USBHDriver *host) {
haint = host->otg->HAINT;
haint &= host->otg->HAINTMSK;
-#if USBH_LLD_DEBUG_ENABLE_ERRORS
+#if USBH_DEBUG_ENABLE && USBH_LLD_DEBUG_ENABLE_ERRORS
if (!haint) {
uint32_t a, b;
a = host->otg->HAINT;
@@ -1327,7 +1328,7 @@ static void usb_lld_serve_interrupt(USBHDriver *host) {
gintsts &= otg->GINTMSK;
if (!gintsts) {
-#if USBH_DEBUG_ENABLE_WARNINGS
+#if USBH_DEBUG_ENABLE && USBH_DEBUG_ENABLE_WARNINGS
uint32_t a, b;
a = otg->GINTSTS;
b = otg->GINTMSK;
@@ -1504,8 +1505,8 @@ static void _usbh_start(USBHDriver *usbh) {
#endif
{
/* OTG HS clock enable and reset.*/
- 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
+ rccEnableOTG_HS(FALSE); // Disable HS clock when cpu is in sleep mode
+ rccDisableOTG_HSULPI();
rccResetOTG_HS();
otgp->GINTMSK = 0;