From 2821d1665fffdc56761cdab9f99e9cd6d31256fb Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 18 Sep 2022 07:58:24 +0000 Subject: [PATCH 01/53] Fixed bug #1235. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@15787 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/rt/src/chvt.c | 4 ++++ readme.txt | 1 + 2 files changed, 5 insertions(+) diff --git a/os/rt/src/chvt.c b/os/rt/src/chvt.c index d28b3d9396..c1d32d08fe 100644 --- a/os/rt/src/chvt.c +++ b/os/rt/src/chvt.c @@ -338,6 +338,10 @@ static void vt_insert_first(virtual_timers_list_t *vtlp, /* Setting up the alarm on the next deadline.*/ port_timer_set_alarm(chTimeAddX(now, currdelta)); + + /* Current time becomes the new "base" time.*/ + now = newnow; + delay = currdelta; } chDbgAssert(currdelta <= CH_CFG_ST_TIMEDELTA, "insufficient delta"); diff --git a/readme.txt b/readme.txt index 75fffad915..b591de5ddd 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Virtual timers lockup uder rare conditions (bug #1235). - FIX: Some MISRA-related fixes. - FIX: Re-opened and fixed bug #1100. - FIX: Fixed wrong buffers toggling in STM32 USBv1 isochronous mode (bug #1232). From de39418378e330b0595d50e0ff389d263d171f17 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 18 Sep 2022 08:04:39 +0000 Subject: [PATCH 02/53] Fixed bug #1234. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@15788 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c | 1699 ++++++++++---------- readme.txt | 1 + 2 files changed, 851 insertions(+), 849 deletions(-) diff --git a/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c b/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c index ebd10ddbe8..56110cde95 100644 --- a/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c +++ b/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c @@ -1,849 +1,850 @@ -/* - ChibiOS - Copyright (C) 2006..2018 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. -*/ -/* - Concepts and parts of this file have been contributed by Uladzimir Pylinsky - aka barthess. - */ - -/** - * @file RTCv2/hal_rtc_lld.c - * @brief STM32 RTC low level driver. - * - * @addtogroup RTC - * @{ - */ - -#include "hal.h" - -#if HAL_USE_RTC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -#define RTC_TR_PM_OFFSET 22 -#define RTC_TR_HT_OFFSET 20 -#define RTC_TR_HU_OFFSET 16 -#define RTC_TR_MNT_OFFSET 12 -#define RTC_TR_MNU_OFFSET 8 -#define RTC_TR_ST_OFFSET 4 -#define RTC_TR_SU_OFFSET 0 - -#define RTC_DR_YT_OFFSET 20 -#define RTC_DR_YU_OFFSET 16 -#define RTC_DR_WDU_OFFSET 13 -#define RTC_DR_MT_OFFSET 12 -#define RTC_DR_MU_OFFSET 8 -#define RTC_DR_DT_OFFSET 4 -#define RTC_DR_DU_OFFSET 0 - -#define RTC_CR_BKP_OFFSET 18 - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief RTC driver identifier. - */ -RTCDriver RTCD1; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Beginning of configuration procedure. - * - * @notapi - */ -static void rtc_enter_init(void) { - - RTCD1.rtc->ISR |= RTC_ISR_INIT; - while ((RTCD1.rtc->ISR & RTC_ISR_INITF) == 0) - ; -} - -/** - * @brief Finalizing of configuration procedure. - * - * @notapi - */ -static inline void rtc_exit_init(void) { - - RTCD1.rtc->ISR &= ~RTC_ISR_INIT; -} - -/** - * @brief Converts time from TR register encoding to timespec. - * - * @param[in] tr TR register value - * @param[out] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -static void rtc_decode_time(uint32_t tr, RTCDateTime *timespec) { - uint32_t n; - - n = ((tr >> RTC_TR_HT_OFFSET) & 3) * 36000000; - n += ((tr >> RTC_TR_HU_OFFSET) & 15) * 3600000; - n += ((tr >> RTC_TR_MNT_OFFSET) & 7) * 600000; - n += ((tr >> RTC_TR_MNU_OFFSET) & 15) * 60000; - n += ((tr >> RTC_TR_ST_OFFSET) & 7) * 10000; - n += ((tr >> RTC_TR_SU_OFFSET) & 15) * 1000; - timespec->millisecond = n; -} - -/** - * @brief Converts date from DR register encoding to timespec. - * - * @param[in] dr DR register value - * @param[out] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -static void rtc_decode_date(uint32_t dr, RTCDateTime *timespec) { - - timespec->year = (((dr >> RTC_DR_YT_OFFSET) & 15) * 10) + - ((dr >> RTC_DR_YU_OFFSET) & 15); - timespec->month = (((dr >> RTC_TR_MNT_OFFSET) & 1) * 10) + - ((dr >> RTC_TR_MNU_OFFSET) & 15); - timespec->day = (((dr >> RTC_DR_DT_OFFSET) & 3) * 10) + - ((dr >> RTC_DR_DU_OFFSET) & 15); - timespec->dayofweek = (dr >> RTC_DR_WDU_OFFSET) & 7; -} - -/** - * @brief Converts time from timespec to TR register encoding. - * - * @param[in] timespec pointer to a @p RTCDateTime structure - * @return the TR register encoding. - * - * @notapi - */ -static uint32_t rtc_encode_time(const RTCDateTime *timespec) { - uint32_t n, tr = 0; - - /* Subseconds cannot be set.*/ - n = timespec->millisecond / 1000; - - /* Seconds conversion.*/ - tr = tr | ((n % 10) << RTC_TR_SU_OFFSET); - n /= 10; - tr = tr | ((n % 6) << RTC_TR_ST_OFFSET); - n /= 6; - - /* Minutes conversion.*/ - tr = tr | ((n % 10) << RTC_TR_MNU_OFFSET); - n /= 10; - tr = tr | ((n % 6) << RTC_TR_MNT_OFFSET); - n /= 6; - - /* Hours conversion.*/ - tr = tr | ((n % 10) << RTC_TR_HU_OFFSET); - n /= 10; - tr = tr | (n << RTC_TR_HT_OFFSET); - - return tr; -} - -/** - * @brief Converts a date from timespec to DR register encoding. - * - * @param[in] timespec pointer to a @p RTCDateTime structure - * @return the DR register encoding. - * - * @notapi - */ -static uint32_t rtc_encode_date(const RTCDateTime *timespec) { - uint32_t n, dr = 0; - - /* Year conversion. Note, only years last two digits are considered.*/ - n = timespec->year; - dr = dr | ((n % 10) << RTC_DR_YU_OFFSET); - n /= 10; - dr = dr | ((n % 10) << RTC_DR_YT_OFFSET); - - /* Months conversion.*/ - n = timespec->month; - dr = dr | ((n % 10) << RTC_DR_MU_OFFSET); - n /= 10; - dr = dr | ((n % 10) << RTC_DR_MT_OFFSET); - - /* Days conversion.*/ - n = timespec->day; - dr = dr | ((n % 10) << RTC_DR_DU_OFFSET); - n /= 10; - dr = dr | ((n % 10) << RTC_DR_DT_OFFSET); - - /* Days of week conversion.*/ - dr = dr | (timespec->dayofweek << RTC_DR_WDU_OFFSET); - - return dr; -} - -#if RTC_HAS_STORAGE == TRUE -static size_t _getsize(void *instance) { - - (void)instance; - - return (size_t)STM32_RTC_STORAGE_SIZE; -} - -static ps_error_t _read(void *instance, ps_offset_t offset, - size_t n, uint8_t *rp) { - volatile uint32_t *bkpr = &((RTCDriver *)instance)->rtc->BKP0R; - unsigned i; - - osalDbgCheck((instance != NULL) && (rp != NULL)); - osalDbgCheck((n > 0U) && (n <= STM32_RTC_STORAGE_SIZE)); - osalDbgCheck((offset < STM32_RTC_STORAGE_SIZE) && - (offset + n <= STM32_RTC_STORAGE_SIZE)); - - for (i = 0; i < (unsigned)n; i++) { - unsigned index = ((unsigned)offset + i) / sizeof (uint32_t); - unsigned shift = ((unsigned)offset + i) % sizeof (uint32_t); - *rp++ = (uint8_t)(bkpr[index] >> (shift * 8U)); - } - - return PS_NO_ERROR; -} - -static ps_error_t _write(void *instance, ps_offset_t offset, - size_t n, const uint8_t *wp) { - volatile uint32_t *bkpr = &((RTCDriver *)instance)->rtc->BKP0R; - unsigned i; - - osalDbgCheck((instance != NULL) && (wp != NULL)); - osalDbgCheck((n > 0U) && (n <= STM32_RTC_STORAGE_SIZE)); - osalDbgCheck((offset < STM32_RTC_STORAGE_SIZE) && - (offset + n <= STM32_RTC_STORAGE_SIZE)); - - for (i = 0; i < (unsigned)n; i++) { - unsigned index = ((unsigned)offset + i) / sizeof (uint32_t); - unsigned shift = ((unsigned)offset + i) % sizeof (uint32_t); - uint32_t regval = bkpr[index]; - regval &= ~(0xFFU << (shift * 8U)); - regval |= (uint32_t)*wp++ << (shift * 8U); - bkpr[index] = regval; - } - - return PS_NO_ERROR; -} - -/** - * @brief VMT for the RTC storage file interface. - */ -struct RTCDriverVMT _rtc_lld_vmt = { - (size_t)0, - _getsize, _read, _write -}; -#endif /* RTC_HAS_STORAGE == TRUE */ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if defined(STM32_RTC_COMMON_HANDLER) -#if !defined(STM32_RTC_SUPPRESS_COMMON_ISR) -/** - * @brief RTC common interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_RTC_COMMON_HANDLER) { - uint32_t isr, clear; - - OSAL_IRQ_PROLOGUE(); - - clear = (0U - | RTC_ISR_TSF - | RTC_ISR_TSOVF -#if defined(RTC_ISR_TAMP1F) - | RTC_ISR_TAMP1F -#endif -#if defined(RTC_ISR_TAMP2F) - | RTC_ISR_TAMP2F -#endif -#if defined(RTC_ISR_TAMP3F) - | RTC_ISR_TAMP3F -#endif -#if defined(RTC_ISR_WUTF) - | RTC_ISR_WUTF -#endif -#if defined(RTC_ISR_ALRAF) - | RTC_ISR_ALRAF -#endif -#if defined(RTC_ISR_ALRBF) - | RTC_ISR_ALRBF -#endif - ); - - isr = RTCD1.rtc->ISR; - RTCD1.rtc->ISR = isr & ~clear; - - extiClearGroup1(EXTI_MASK1(STM32_RTC_ALARM_EXTI) | - EXTI_MASK1(STM32_RTC_TAMP_STAMP_EXTI) | - EXTI_MASK1(STM32_RTC_WKUP_EXTI)); - - if (RTCD1.callback != NULL) { - uint32_t cr = RTCD1.rtc->CR; - uint32_t tcr; - -#if defined(RTC_ISR_WUTF) - if (((cr & RTC_CR_WUTIE) != 0U) && ((isr & RTC_ISR_WUTF) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_WAKEUP); - } -#endif - -#if defined(RTC_ISR_ALRAF) - if (((cr & RTC_CR_ALRAIE) != 0U) && ((isr & RTC_ISR_ALRAF) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_A); - } -#endif -#if defined(RTC_ISR_ALRBF) - if (((cr & RTC_CR_ALRBIE) != 0U) && ((isr & RTC_ISR_ALRBF) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_B); - } -#endif - - if ((cr & RTC_CR_TSIE) != 0U) { - if ((isr & RTC_ISR_TSF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TS); - } - if ((isr & RTC_ISR_TSOVF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TS_OVF); - } - } - - /* This part is different depending on if the RTC has a TAMPCR or TAFCR - register.*/ -#if defined(RTC_TAFCR_TAMP1E) - tcr = RTCD1.rtc->TAFCR; - if ((tcr & RTC_TAFCR_TAMPIE) != 0U) { -#if defined(RTC_ISR_TAMP1F) - if ((isr & RTC_ISR_TAMP1F) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); - } -#endif -#if defined(RTC_ISR_TAMP2F) - if ((isr & RTC_ISR_TAMP2F) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); - } -#endif - } - -#else /* !defined(RTC_TAFCR_TAMP1E) */ - tcr = RTCD1.rtc->TAMPCR; -#if defined(RTC_ISR_TAMP1F) - if (((tcr & RTC_TAMPCR_TAMP1IE) != 0U) && - ((isr & RTC_ISR_TAMP1F) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); - } -#endif -#if defined(RTC_ISR_TAMP2F) - if (((tcr & RTC_TAMPCR_TAMP2IE) != 0U) && - ((isr & RTC_ISR_TAMP2F) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); - } -#endif -#if defined(RTC_ISR_TAMP3F) - if (((tcr & RTC_TAMPCR_TAMP3IE) != 0U) && - ((isr & RTC_ISR_TAMP3F) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP3); - } -#endif -#endif /* !defined(RTC_TAFCR_TAMP1E) */ - } - - OSAL_IRQ_EPILOGUE(); -} -#endif /* !defined(STM32_RTC_SUPPRESS_COMMON_ISR) */ - -#elif defined(STM32_RTC_TAMP_STAMP_HANDLER) && \ - defined(STM32_RTC_WKUP_HANDLER) && \ - defined(STM32_RTC_ALARM_HANDLER) -/** - * @brief RTC TAMP/STAMP interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_RTC_TAMP_STAMP_HANDLER) { - uint32_t isr, clear; - - OSAL_IRQ_PROLOGUE(); - - clear = (0U - | RTC_ISR_TSF - | RTC_ISR_TSOVF -#if defined(RTC_ISR_TAMP1F) - | RTC_ISR_TAMP1F -#endif -#if defined(RTC_ISR_TAMP2F) - | RTC_ISR_TAMP2F -#endif -#if defined(RTC_ISR_TAMP3F) - | RTC_ISR_TAMP3F -#endif - ); - - isr = RTCD1.rtc->ISR; - RTCD1.rtc->ISR = isr & ~clear; - - extiClearGroup1(EXTI_MASK1(STM32_RTC_TAMP_STAMP_EXTI)); - - if (RTCD1.callback != NULL) { - uint32_t cr, tcr; - - cr = RTCD1.rtc->CR; - if ((cr & RTC_CR_TSIE) != 0U) { - if ((isr & RTC_ISR_TSF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TS); - } - if ((isr & RTC_ISR_TSOVF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TS_OVF); - } - } - - /* This part is different depending on if the RTC has a TAMPCR or TAFCR - register.*/ -#if defined(RTC_TAFCR_TAMP1E) - tcr = RTCD1.rtc->TAFCR; - if ((tcr & RTC_TAFCR_TAMPIE) != 0U) { -#if defined(RTC_ISR_TAMP1F) - if ((isr & RTC_ISR_TAMP1F) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); - } -#endif -#if defined(RTC_ISR_TAMP2F) - if ((isr & RTC_ISR_TAMP2F) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); - } -#endif - } - -#else /* !defined(RTC_TAFCR_TAMP1E) */ - tcr = RTCD1.rtc->TAMPCR; -#if defined(RTC_ISR_TAMP1F) - if (((tcr & RTC_TAMPCR_TAMP1IE) != 0U) && - ((isr & RTC_ISR_TAMP1F) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); - } -#endif -#if defined(RTC_ISR_TAMP2F) - if (((tcr & RTC_TAMPCR_TAMP2IE) != 0U) && - ((isr & RTC_ISR_TAMP2F) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); - } -#endif -#if defined(RTC_ISR_TAMP3F) - if (((tcr & RTC_TAMPCR_TAMP3IE) != 0U) && - ((isr & RTC_ISR_TAMP3F) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP3); - } -#endif -#endif /* !defined(RTC_TAFCR_TAMP1E) */ - } - - OSAL_IRQ_EPILOGUE(); -} -/** - * @brief RTC wakeup interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_RTC_WKUP_HANDLER) { - uint32_t isr; - - OSAL_IRQ_PROLOGUE(); - - isr = RTCD1.rtc->ISR; - RTCD1.rtc->ISR = isr & ~RTC_ISR_WUTF; - - extiClearGroup1(EXTI_MASK1(STM32_RTC_WKUP_EXTI)); - - if (RTCD1.callback != NULL) { - uint32_t cr = RTCD1.rtc->CR; - - if (((cr & RTC_CR_WUTIE) != 0U) && ((isr & RTC_ISR_WUTF) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_WAKEUP); - } - } - - OSAL_IRQ_EPILOGUE(); -} - -/** - * @brief RTC alarm interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_RTC_ALARM_HANDLER) { - uint32_t isr, clear; - - OSAL_IRQ_PROLOGUE(); - - clear = (0U -#if defined(RTC_ISR_ALRAF) - | RTC_ISR_ALRAF -#endif -#if defined(RTC_ISR_ALRBF) - | RTC_ISR_ALRBF -#endif - ); - - isr = RTCD1.rtc->ISR; - RTCD1.rtc->ISR = isr & ~clear; - - extiClearGroup1(EXTI_MASK1(STM32_RTC_ALARM_EXTI)); - - if (RTCD1.callback != NULL) { - uint32_t cr = RTCD1.rtc->CR; -#if defined(RTC_ISR_ALRAF) - if (((cr & RTC_CR_ALRAIE) != 0U) && ((isr & RTC_ISR_ALRAF) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_A); - } -#endif -#if defined(RTC_ISR_ALRBF) - if (((cr & RTC_CR_ALRBIE) != 0U) && ((isr & RTC_ISR_ALRBF) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_B); - } -#endif - } - - OSAL_IRQ_EPILOGUE(); -} - -#else -#error "missing required RTC handlers definitions in registry" -#endif - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Enable access to registers. - * - * @notapi - */ -void rtc_lld_init(void) { - - /* RTC object initialization.*/ - rtcObjectInit(&RTCD1); - - /* RTC pointer initialization.*/ - RTCD1.rtc = RTC; - - /* Disable write protection. */ - RTCD1.rtc->WPR = 0xCA; - RTCD1.rtc->WPR = 0x53; - - /* If calendar has not been initialized yet then proceed with the - initial setup.*/ - if (!(RTCD1.rtc->ISR & RTC_ISR_INITS)) { - - rtc_enter_init(); - - RTCD1.rtc->CR = STM32_RTC_CR_INIT; -#if defined(RTC_TAFCR_TAMP1E) - RTCD1.rtc->TAFCR = STM32_RTC_TAMPCR_INIT; -#else - RTCD1.rtc->TAMPCR = STM32_RTC_TAMPCR_INIT; -#endif - RTCD1.rtc->ISR = RTC_ISR_INIT; /* Clearing all but RTC_ISR_INIT. */ - RTCD1.rtc->PRER = STM32_RTC_PRER_BITS; - RTCD1.rtc->PRER = STM32_RTC_PRER_BITS; - - rtc_exit_init(); - } - else { - RTCD1.rtc->ISR &= ~RTC_ISR_RSF; - } - - /* Callback initially disabled.*/ - RTCD1.callback = NULL; - - /* Enabling RTC-related EXTI lines.*/ - extiEnableGroup1(EXTI_MASK1(STM32_RTC_ALARM_EXTI) | - EXTI_MASK1(STM32_RTC_TAMP_STAMP_EXTI) | - EXTI_MASK1(STM32_RTC_WKUP_EXTI), - EXTI_MODE_RISING_EDGE | EXTI_MODE_ACTION_INTERRUPT); - - /* IRQ vectors permanently assigned to this driver.*/ - STM32_RTC_IRQ_ENABLE(); -} - -/** - * @brief Set current time. - * @note Fractional part will be silently ignored. There is no possibility - * to set it on STM32 platform. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec) { - uint32_t dr, tr; - syssts_t sts; - - tr = rtc_encode_time(timespec); - dr = rtc_encode_date(timespec); - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - /* Writing the registers.*/ - rtc_enter_init(); - rtcp->rtc->TR = tr; - rtcp->rtc->DR = dr; - rtcp->rtc->CR = (rtcp->rtc->CR & ~(1U << RTC_CR_BKP_OFFSET)) | - (timespec->dstflag << RTC_CR_BKP_OFFSET); - rtc_exit_init(); - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} - -/** - * @brief Get current time. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[out] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec) { - uint32_t dr, tr, cr; - uint32_t subs; -#if STM32_RTC_HAS_SUBSECONDS - uint32_t oldssr, ssr; -#endif /* STM32_RTC_HAS_SUBSECONDS */ - syssts_t sts; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - /* Synchronization with the RTC and reading the registers, note - DR must be read last.*/ - while ((rtcp->rtc->ISR & RTC_ISR_RSF) == 0) - ; -#if STM32_RTC_HAS_SUBSECONDS - oldssr = rtcp->rtc->SSR; - do -#endif /* STM32_RTC_HAS_SUBSECONDS */ - { - tr = rtcp->rtc->TR; - dr = rtcp->rtc->DR; - cr = rtcp->rtc->CR; - } -#if STM32_RTC_HAS_SUBSECONDS - while (oldssr != (ssr = rtcp->rtc->SSR)); -#endif /* STM32_RTC_HAS_SUBSECONDS */ - rtcp->rtc->ISR &= ~RTC_ISR_RSF; - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); - - /* Decoding day time, this starts the atomic read sequence, see "Reading - the calendar" in the RTC documentation.*/ - rtc_decode_time(tr, timespec); - - /* If the RTC is capable of sub-second counting then the value is - normalized in milliseconds and added to the time.*/ -#if STM32_RTC_HAS_SUBSECONDS - subs = (((STM32_RTC_PRESS_VALUE - 1U) - ssr) * 1000U) / STM32_RTC_PRESS_VALUE; -#else - subs = 0; -#endif /* STM32_RTC_HAS_SUBSECONDS */ - timespec->millisecond += subs; - - /* Decoding date, this concludes the atomic read sequence.*/ - rtc_decode_date(dr, timespec); - - /* Retrieving the DST bit.*/ - timespec->dstflag = (cr >> RTC_CR_BKP_OFFSET) & 1; -} - -#if (RTC_ALARMS > 0) || defined(__DOXYGEN__) -/** - * @brief Set alarm time. - * @note Default value after BKP domain reset for both comparators is 0. - * @note Function does not performs any checks of alarm time validity. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure. - * @param[in] alarm alarm identifier. Can be 0 or 1. - * @param[in] alarmspec pointer to a @p RTCAlarm structure. - * - * @notapi - */ -void rtc_lld_set_alarm(RTCDriver *rtcp, - rtcalarm_t alarm, - const RTCAlarm *alarmspec) { - syssts_t sts; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - if (alarm == 0) { - if (alarmspec != NULL) { - rtcp->rtc->CR &= ~RTC_CR_ALRAE; - while (!(rtcp->rtc->ISR & RTC_ISR_ALRAWF)) - ; - rtcp->rtc->ALRMAR = alarmspec->alrmr; - rtcp->rtc->CR |= RTC_CR_ALRAE; - rtcp->rtc->CR |= RTC_CR_ALRAIE; - } - else { - rtcp->rtc->CR &= ~RTC_CR_ALRAIE; - rtcp->rtc->CR &= ~RTC_CR_ALRAE; - } - } -#if RTC_ALARMS > 1 - else { - if (alarmspec != NULL) { - rtcp->rtc->CR &= ~RTC_CR_ALRBE; - while (!(rtcp->rtc->ISR & RTC_ISR_ALRBWF)) - ; - rtcp->rtc->ALRMBR = alarmspec->alrmr; - rtcp->rtc->CR |= RTC_CR_ALRBE; - rtcp->rtc->CR |= RTC_CR_ALRBIE; - } - else { - rtcp->rtc->CR &= ~RTC_CR_ALRBIE; - rtcp->rtc->CR &= ~RTC_CR_ALRBE; - } - } -#endif /* RTC_ALARMS > 1 */ - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} - -/** - * @brief Get alarm time. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] alarm alarm identifier. Can be 0 or 1. - * @param[out] alarmspec pointer to a @p RTCAlarm structure - * - * @notapi - */ -void rtc_lld_get_alarm(RTCDriver *rtcp, - rtcalarm_t alarm, - RTCAlarm *alarmspec) { - - if (alarm == 0) - alarmspec->alrmr = rtcp->rtc->ALRMAR; -#if RTC_ALARMS > 1 - else - alarmspec->alrmr = rtcp->rtc->ALRMBR; -#endif /* RTC_ALARMS > 1 */ -} -#endif /* RTC_ALARMS > 0 */ - -/** - * @brief Enables or disables RTC callbacks. - * @details This function enables or disables callbacks, use a @p NULL pointer - * in order to disable a callback. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] callback callback function pointer or @p NULL - * - * @notapi - */ -void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) { - - rtcp->callback = callback; -} - -#if STM32_RTC_HAS_PERIODIC_WAKEUPS || defined(__DOXYGEN__) -/** - * @brief Sets time of periodic wakeup. - * @note Default value after BKP domain reset is 0x0000FFFF - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] wakeupspec pointer to a @p RTCWakeup structure - * - * @api - */ -void rtcSTM32SetPeriodicWakeup(RTCDriver *rtcp, const RTCWakeup *wakeupspec) { - syssts_t sts; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - if (wakeupspec != NULL) { - osalDbgCheck(wakeupspec->wutr != 0x30000); - - rtcp->rtc->CR &= ~RTC_CR_WUTE; - rtcp->rtc->CR &= ~RTC_CR_WUTIE; - while (!(rtcp->rtc->ISR & RTC_ISR_WUTWF)) - ; - rtcp->rtc->WUTR = wakeupspec->wutr & 0xFFFF; - rtcp->rtc->CR &= ~RTC_CR_WUCKSEL; - rtcp->rtc->CR |= (wakeupspec->wutr >> 16) & RTC_CR_WUCKSEL; - rtcp->rtc->CR |= RTC_CR_WUTIE; - rtcp->rtc->CR |= RTC_CR_WUTE; - } - else { - rtcp->rtc->CR &= ~RTC_CR_WUTE; - rtcp->rtc->CR &= ~RTC_CR_WUTIE; - } - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} - -/** - * @brief Gets time of periodic wakeup. - * @note Default value after BKP domain reset is 0x0000FFFF - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[out] wakeupspec pointer to a @p RTCWakeup structure - * - * @api - */ -void rtcSTM32GetPeriodicWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec) { - syssts_t sts; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - wakeupspec->wutr = 0; - wakeupspec->wutr |= rtcp->rtc->WUTR; - wakeupspec->wutr |= (((uint32_t)rtcp->rtc->CR) & 0x7) << 16; - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} -#endif /* STM32_RTC_HAS_PERIODIC_WAKEUPS */ - -#endif /* HAL_USE_RTC */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file RTCv2/hal_rtc_lld.c + * @brief STM32 RTC low level driver. + * + * @addtogroup RTC + * @{ + */ + +#include "hal.h" + +#if HAL_USE_RTC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define RTC_TR_PM_OFFSET 22 +#define RTC_TR_HT_OFFSET 20 +#define RTC_TR_HU_OFFSET 16 +#define RTC_TR_MNT_OFFSET 12 +#define RTC_TR_MNU_OFFSET 8 +#define RTC_TR_ST_OFFSET 4 +#define RTC_TR_SU_OFFSET 0 + +#define RTC_DR_YT_OFFSET 20 +#define RTC_DR_YU_OFFSET 16 +#define RTC_DR_WDU_OFFSET 13 +#define RTC_DR_MT_OFFSET 12 +#define RTC_DR_MU_OFFSET 8 +#define RTC_DR_DT_OFFSET 4 +#define RTC_DR_DU_OFFSET 0 + +#define RTC_CR_BKP_OFFSET 18 + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief RTC driver identifier. + */ +RTCDriver RTCD1; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Beginning of configuration procedure. + * + * @notapi + */ +static void rtc_enter_init(void) { + + RTCD1.rtc->ISR |= RTC_ISR_INIT; + while ((RTCD1.rtc->ISR & RTC_ISR_INITF) == 0) + ; +} + +/** + * @brief Finalizing of configuration procedure. + * + * @notapi + */ +static inline void rtc_exit_init(void) { + + RTCD1.rtc->ISR &= ~RTC_ISR_INIT; +} + +/** + * @brief Converts time from TR register encoding to timespec. + * + * @param[in] tr TR register value + * @param[out] timespec pointer to a @p RTCDateTime structure + * + * @notapi + */ +static void rtc_decode_time(uint32_t tr, RTCDateTime *timespec) { + uint32_t n; + + n = ((tr >> RTC_TR_HT_OFFSET) & 3) * 36000000; + n += ((tr >> RTC_TR_HU_OFFSET) & 15) * 3600000; + n += ((tr >> RTC_TR_MNT_OFFSET) & 7) * 600000; + n += ((tr >> RTC_TR_MNU_OFFSET) & 15) * 60000; + n += ((tr >> RTC_TR_ST_OFFSET) & 7) * 10000; + n += ((tr >> RTC_TR_SU_OFFSET) & 15) * 1000; + timespec->millisecond = n; +} + +/** + * @brief Converts date from DR register encoding to timespec. + * + * @param[in] dr DR register value + * @param[out] timespec pointer to a @p RTCDateTime structure + * + * @notapi + */ +static void rtc_decode_date(uint32_t dr, RTCDateTime *timespec) { + + timespec->year = (((dr >> RTC_DR_YT_OFFSET) & 15) * 10) + + ((dr >> RTC_DR_YU_OFFSET) & 15); + timespec->month = (((dr >> RTC_TR_MNT_OFFSET) & 1) * 10) + + ((dr >> RTC_TR_MNU_OFFSET) & 15); + timespec->day = (((dr >> RTC_DR_DT_OFFSET) & 3) * 10) + + ((dr >> RTC_DR_DU_OFFSET) & 15); + timespec->dayofweek = (dr >> RTC_DR_WDU_OFFSET) & 7; +} + +/** + * @brief Converts time from timespec to TR register encoding. + * + * @param[in] timespec pointer to a @p RTCDateTime structure + * @return the TR register encoding. + * + * @notapi + */ +static uint32_t rtc_encode_time(const RTCDateTime *timespec) { + uint32_t n, tr = 0; + + /* Subseconds cannot be set.*/ + n = timespec->millisecond / 1000; + + /* Seconds conversion.*/ + tr = tr | ((n % 10) << RTC_TR_SU_OFFSET); + n /= 10; + tr = tr | ((n % 6) << RTC_TR_ST_OFFSET); + n /= 6; + + /* Minutes conversion.*/ + tr = tr | ((n % 10) << RTC_TR_MNU_OFFSET); + n /= 10; + tr = tr | ((n % 6) << RTC_TR_MNT_OFFSET); + n /= 6; + + /* Hours conversion.*/ + tr = tr | ((n % 10) << RTC_TR_HU_OFFSET); + n /= 10; + tr = tr | (n << RTC_TR_HT_OFFSET); + + return tr; +} + +/** + * @brief Converts a date from timespec to DR register encoding. + * + * @param[in] timespec pointer to a @p RTCDateTime structure + * @return the DR register encoding. + * + * @notapi + */ +static uint32_t rtc_encode_date(const RTCDateTime *timespec) { + uint32_t n, dr = 0; + + /* Year conversion. Note, only years last two digits are considered.*/ + n = timespec->year; + dr = dr | ((n % 10) << RTC_DR_YU_OFFSET); + n /= 10; + dr = dr | ((n % 10) << RTC_DR_YT_OFFSET); + + /* Months conversion.*/ + n = timespec->month; + dr = dr | ((n % 10) << RTC_DR_MU_OFFSET); + n /= 10; + dr = dr | ((n % 10) << RTC_DR_MT_OFFSET); + + /* Days conversion.*/ + n = timespec->day; + dr = dr | ((n % 10) << RTC_DR_DU_OFFSET); + n /= 10; + dr = dr | ((n % 10) << RTC_DR_DT_OFFSET); + + /* Days of week conversion.*/ + dr = dr | (timespec->dayofweek << RTC_DR_WDU_OFFSET); + + return dr; +} + +#if RTC_HAS_STORAGE == TRUE +static size_t _getsize(void *instance) { + + (void)instance; + + return (size_t)STM32_RTC_STORAGE_SIZE; +} + +static ps_error_t _read(void *instance, ps_offset_t offset, + size_t n, uint8_t *rp) { + volatile uint32_t *bkpr = &((RTCDriver *)instance)->rtc->BKP0R; + unsigned i; + + osalDbgCheck((instance != NULL) && (rp != NULL)); + osalDbgCheck((n > 0U) && (n <= STM32_RTC_STORAGE_SIZE)); + osalDbgCheck((offset < STM32_RTC_STORAGE_SIZE) && + (offset + n <= STM32_RTC_STORAGE_SIZE)); + + for (i = 0; i < (unsigned)n; i++) { + unsigned index = ((unsigned)offset + i) / sizeof (uint32_t); + unsigned shift = ((unsigned)offset + i) % sizeof (uint32_t); + *rp++ = (uint8_t)(bkpr[index] >> (shift * 8U)); + } + + return PS_NO_ERROR; +} + +static ps_error_t _write(void *instance, ps_offset_t offset, + size_t n, const uint8_t *wp) { + volatile uint32_t *bkpr = &((RTCDriver *)instance)->rtc->BKP0R; + unsigned i; + + osalDbgCheck((instance != NULL) && (wp != NULL)); + osalDbgCheck((n > 0U) && (n <= STM32_RTC_STORAGE_SIZE)); + osalDbgCheck((offset < STM32_RTC_STORAGE_SIZE) && + (offset + n <= STM32_RTC_STORAGE_SIZE)); + + for (i = 0; i < (unsigned)n; i++) { + unsigned index = ((unsigned)offset + i) / sizeof (uint32_t); + unsigned shift = ((unsigned)offset + i) % sizeof (uint32_t); + uint32_t regval = bkpr[index]; + regval &= ~(0xFFU << (shift * 8U)); + regval |= (uint32_t)*wp++ << (shift * 8U); + bkpr[index] = regval; + } + + return PS_NO_ERROR; +} + +/** + * @brief VMT for the RTC storage file interface. + */ +struct RTCDriverVMT _rtc_lld_vmt = { + (size_t)0, + _getsize, _read, _write +}; +#endif /* RTC_HAS_STORAGE == TRUE */ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(STM32_RTC_COMMON_HANDLER) +#if !defined(STM32_RTC_SUPPRESS_COMMON_ISR) +/** + * @brief RTC common interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_RTC_COMMON_HANDLER) { + uint32_t isr, clear; + + OSAL_IRQ_PROLOGUE(); + + clear = (0U + | RTC_ISR_TSF + | RTC_ISR_TSOVF +#if defined(RTC_ISR_TAMP1F) + | RTC_ISR_TAMP1F +#endif +#if defined(RTC_ISR_TAMP2F) + | RTC_ISR_TAMP2F +#endif +#if defined(RTC_ISR_TAMP3F) + | RTC_ISR_TAMP3F +#endif +#if defined(RTC_ISR_WUTF) + | RTC_ISR_WUTF +#endif +#if defined(RTC_ISR_ALRAF) + | RTC_ISR_ALRAF +#endif +#if defined(RTC_ISR_ALRBF) + | RTC_ISR_ALRBF +#endif + ); + + isr = RTCD1.rtc->ISR; + RTCD1.rtc->ISR = isr & ~clear; + + extiClearGroup1(EXTI_MASK1(STM32_RTC_ALARM_EXTI) | + EXTI_MASK1(STM32_RTC_TAMP_STAMP_EXTI) | + EXTI_MASK1(STM32_RTC_WKUP_EXTI)); + + if (RTCD1.callback != NULL) { + uint32_t cr = RTCD1.rtc->CR; + uint32_t tcr; + +#if defined(RTC_ISR_WUTF) + if (((cr & RTC_CR_WUTIE) != 0U) && ((isr & RTC_ISR_WUTF) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_WAKEUP); + } +#endif + +#if defined(RTC_ISR_ALRAF) + if (((cr & RTC_CR_ALRAIE) != 0U) && ((isr & RTC_ISR_ALRAF) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_A); + } +#endif +#if defined(RTC_ISR_ALRBF) + if (((cr & RTC_CR_ALRBIE) != 0U) && ((isr & RTC_ISR_ALRBF) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_B); + } +#endif + + if ((cr & RTC_CR_TSIE) != 0U) { + if ((isr & RTC_ISR_TSF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TS); + } + if ((isr & RTC_ISR_TSOVF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TS_OVF); + } + } + + /* This part is different depending on if the RTC has a TAMPCR or TAFCR + register.*/ +#if defined(RTC_TAFCR_TAMP1E) + tcr = RTCD1.rtc->TAFCR; + if ((tcr & RTC_TAFCR_TAMPIE) != 0U) { +#if defined(RTC_ISR_TAMP1F) + if ((isr & RTC_ISR_TAMP1F) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); + } +#endif +#if defined(RTC_ISR_TAMP2F) + if ((isr & RTC_ISR_TAMP2F) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); + } +#endif + } + +#else /* !defined(RTC_TAFCR_TAMP1E) */ + tcr = RTCD1.rtc->TAMPCR; +#if defined(RTC_ISR_TAMP1F) + if (((tcr & RTC_TAMPCR_TAMP1IE) != 0U) && + ((isr & RTC_ISR_TAMP1F) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); + } +#endif +#if defined(RTC_ISR_TAMP2F) + if (((tcr & RTC_TAMPCR_TAMP2IE) != 0U) && + ((isr & RTC_ISR_TAMP2F) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); + } +#endif +#if defined(RTC_ISR_TAMP3F) + if (((tcr & RTC_TAMPCR_TAMP3IE) != 0U) && + ((isr & RTC_ISR_TAMP3F) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP3); + } +#endif +#endif /* !defined(RTC_TAFCR_TAMP1E) */ + } + + OSAL_IRQ_EPILOGUE(); +} +#endif /* !defined(STM32_RTC_SUPPRESS_COMMON_ISR) */ + +#elif defined(STM32_RTC_TAMP_STAMP_HANDLER) && \ + defined(STM32_RTC_WKUP_HANDLER) && \ + defined(STM32_RTC_ALARM_HANDLER) +/** + * @brief RTC TAMP/STAMP interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_RTC_TAMP_STAMP_HANDLER) { + uint32_t isr, clear; + + OSAL_IRQ_PROLOGUE(); + + clear = (0U + | RTC_ISR_TSF + | RTC_ISR_TSOVF +#if defined(RTC_ISR_TAMP1F) + | RTC_ISR_TAMP1F +#endif +#if defined(RTC_ISR_TAMP2F) + | RTC_ISR_TAMP2F +#endif +#if defined(RTC_ISR_TAMP3F) + | RTC_ISR_TAMP3F +#endif + ); + + isr = RTCD1.rtc->ISR; + RTCD1.rtc->ISR = isr & ~clear; + + extiClearGroup1(EXTI_MASK1(STM32_RTC_TAMP_STAMP_EXTI)); + + if (RTCD1.callback != NULL) { + uint32_t cr, tcr; + + cr = RTCD1.rtc->CR; + if ((cr & RTC_CR_TSIE) != 0U) { + if ((isr & RTC_ISR_TSF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TS); + } + if ((isr & RTC_ISR_TSOVF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TS_OVF); + } + } + + /* This part is different depending on if the RTC has a TAMPCR or TAFCR + register.*/ +#if defined(RTC_TAFCR_TAMP1E) + tcr = RTCD1.rtc->TAFCR; + if ((tcr & RTC_TAFCR_TAMPIE) != 0U) { +#if defined(RTC_ISR_TAMP1F) + if ((isr & RTC_ISR_TAMP1F) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); + } +#endif +#if defined(RTC_ISR_TAMP2F) + if ((isr & RTC_ISR_TAMP2F) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); + } +#endif + } + +#else /* !defined(RTC_TAFCR_TAMP1E) */ + tcr = RTCD1.rtc->TAMPCR; +#if defined(RTC_ISR_TAMP1F) + if (((tcr & RTC_TAMPCR_TAMP1IE) != 0U) && + ((isr & RTC_ISR_TAMP1F) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); + } +#endif +#if defined(RTC_ISR_TAMP2F) + if (((tcr & RTC_TAMPCR_TAMP2IE) != 0U) && + ((isr & RTC_ISR_TAMP2F) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); + } +#endif +#if defined(RTC_ISR_TAMP3F) + if (((tcr & RTC_TAMPCR_TAMP3IE) != 0U) && + ((isr & RTC_ISR_TAMP3F) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP3); + } +#endif +#endif /* !defined(RTC_TAFCR_TAMP1E) */ + } + + OSAL_IRQ_EPILOGUE(); +} +/** + * @brief RTC wakeup interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_RTC_WKUP_HANDLER) { + uint32_t isr; + + OSAL_IRQ_PROLOGUE(); + + isr = RTCD1.rtc->ISR; + RTCD1.rtc->ISR = isr & ~RTC_ISR_WUTF; + + extiClearGroup1(EXTI_MASK1(STM32_RTC_WKUP_EXTI)); + + if (RTCD1.callback != NULL) { + uint32_t cr = RTCD1.rtc->CR; + + if (((cr & RTC_CR_WUTIE) != 0U) && ((isr & RTC_ISR_WUTF) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_WAKEUP); + } + } + + OSAL_IRQ_EPILOGUE(); +} + +/** + * @brief RTC alarm interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_RTC_ALARM_HANDLER) { + uint32_t isr, clear; + + OSAL_IRQ_PROLOGUE(); + + clear = (0U +#if defined(RTC_ISR_ALRAF) + | RTC_ISR_ALRAF +#endif +#if defined(RTC_ISR_ALRBF) + | RTC_ISR_ALRBF +#endif + ); + + isr = RTCD1.rtc->ISR; + RTCD1.rtc->ISR = isr & ~clear; + + extiClearGroup1(EXTI_MASK1(STM32_RTC_ALARM_EXTI)); + + if (RTCD1.callback != NULL) { + uint32_t cr = RTCD1.rtc->CR; +#if defined(RTC_ISR_ALRAF) + if (((cr & RTC_CR_ALRAIE) != 0U) && ((isr & RTC_ISR_ALRAF) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_A); + } +#endif +#if defined(RTC_ISR_ALRBF) + if (((cr & RTC_CR_ALRBIE) != 0U) && ((isr & RTC_ISR_ALRBF) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_B); + } +#endif + } + + OSAL_IRQ_EPILOGUE(); +} + +#else +#error "missing required RTC handlers definitions in registry" +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Enable access to registers. + * + * @notapi + */ +void rtc_lld_init(void) { + + /* RTC object initialization.*/ + rtcObjectInit(&RTCD1); + + /* RTC pointer initialization.*/ + RTCD1.rtc = RTC; + + /* Disable write protection. */ + RTCD1.rtc->WPR = 0xCA; + RTCD1.rtc->WPR = 0x53; + + /* If calendar has not been initialized yet then proceed with the + initial setup.*/ + if (!(RTCD1.rtc->ISR & RTC_ISR_INITS)) { + + rtc_enter_init(); + + RTCD1.rtc->CR = STM32_RTC_CR_INIT; +#if defined(RTC_TAFCR_TAMP1E) + RTCD1.rtc->TAFCR = STM32_RTC_TAMPCR_INIT; +#else + RTCD1.rtc->TAMPCR = STM32_RTC_TAMPCR_INIT; +#endif + RTCD1.rtc->ISR = RTC_ISR_INIT; /* Clearing all but RTC_ISR_INIT. */ + RTCD1.rtc->PRER = STM32_RTC_PRER_BITS; + RTCD1.rtc->PRER = STM32_RTC_PRER_BITS; + + rtc_exit_init(); + } + else { + RTCD1.rtc->ISR &= ~RTC_ISR_RSF; + } + + /* Callback initially disabled.*/ + RTCD1.callback = NULL; + + /* Enabling RTC-related EXTI lines.*/ + extiEnableGroup1(EXTI_MASK1(STM32_RTC_ALARM_EXTI) | + EXTI_MASK1(STM32_RTC_TAMP_STAMP_EXTI) | + EXTI_MASK1(STM32_RTC_WKUP_EXTI), + EXTI_MODE_RISING_EDGE | EXTI_MODE_ACTION_INTERRUPT); + + /* IRQ vectors permanently assigned to this driver.*/ + STM32_RTC_IRQ_ENABLE(); +} + +/** + * @brief Set current time. + * @note Fractional part will be silently ignored. There is no possibility + * to set it on STM32 platform. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] timespec pointer to a @p RTCDateTime structure + * + * @notapi + */ +void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec) { + uint32_t dr, tr; + syssts_t sts; + + tr = rtc_encode_time(timespec); + dr = rtc_encode_date(timespec); + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + /* Writing the registers.*/ + rtc_enter_init(); + rtcp->rtc->TR = tr; + rtcp->rtc->DR = dr; + rtcp->rtc->CR = (rtcp->rtc->CR & ~(1U << RTC_CR_BKP_OFFSET)) | + (timespec->dstflag << RTC_CR_BKP_OFFSET); + rtc_exit_init(); + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); +} + +/** + * @brief Get current time. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[out] timespec pointer to a @p RTCDateTime structure + * + * @notapi + */ +void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec) { + uint32_t dr, tr, cr; + uint32_t subs; +#if STM32_RTC_HAS_SUBSECONDS + uint32_t oldssr, ssr; +#endif /* STM32_RTC_HAS_SUBSECONDS */ + syssts_t sts; + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + /* Synchronization with the RTC and reading the registers, note + DR must be read last.*/ + while ((rtcp->rtc->ISR & RTC_ISR_RSF) == 0) + ; +#if STM32_RTC_HAS_SUBSECONDS + do +#endif /* STM32_RTC_HAS_SUBSECONDS */ + { + oldssr = rtcp->rtc->SSR; + tr = rtcp->rtc->TR; + dr = rtcp->rtc->DR; + } +#if STM32_RTC_HAS_SUBSECONDS + while (oldssr != (ssr = rtcp->rtc->SSR)); + (void) rtcp->rtc->DR; +#endif /* STM32_RTC_HAS_SUBSECONDS */ + cr = rtcp->rtc->CR; + rtcp->rtc->ISR &= ~RTC_ISR_RSF; + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); + + /* Decoding day time, this starts the atomic read sequence, see "Reading + the calendar" in the RTC documentation.*/ + rtc_decode_time(tr, timespec); + + /* If the RTC is capable of sub-second counting then the value is + normalized in milliseconds and added to the time.*/ +#if STM32_RTC_HAS_SUBSECONDS + subs = (((STM32_RTC_PRESS_VALUE - 1U) - ssr) * 1000U) / STM32_RTC_PRESS_VALUE; +#else + subs = 0; +#endif /* STM32_RTC_HAS_SUBSECONDS */ + timespec->millisecond += subs; + + /* Decoding date, this concludes the atomic read sequence.*/ + rtc_decode_date(dr, timespec); + + /* Retrieving the DST bit.*/ + timespec->dstflag = (cr >> RTC_CR_BKP_OFFSET) & 1; +} + +#if (RTC_ALARMS > 0) || defined(__DOXYGEN__) +/** + * @brief Set alarm time. + * @note Default value after BKP domain reset for both comparators is 0. + * @note Function does not performs any checks of alarm time validity. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure. + * @param[in] alarm alarm identifier. Can be 0 or 1. + * @param[in] alarmspec pointer to a @p RTCAlarm structure. + * + * @notapi + */ +void rtc_lld_set_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + const RTCAlarm *alarmspec) { + syssts_t sts; + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + if (alarm == 0) { + if (alarmspec != NULL) { + rtcp->rtc->CR &= ~RTC_CR_ALRAE; + while (!(rtcp->rtc->ISR & RTC_ISR_ALRAWF)) + ; + rtcp->rtc->ALRMAR = alarmspec->alrmr; + rtcp->rtc->CR |= RTC_CR_ALRAE; + rtcp->rtc->CR |= RTC_CR_ALRAIE; + } + else { + rtcp->rtc->CR &= ~RTC_CR_ALRAIE; + rtcp->rtc->CR &= ~RTC_CR_ALRAE; + } + } +#if RTC_ALARMS > 1 + else { + if (alarmspec != NULL) { + rtcp->rtc->CR &= ~RTC_CR_ALRBE; + while (!(rtcp->rtc->ISR & RTC_ISR_ALRBWF)) + ; + rtcp->rtc->ALRMBR = alarmspec->alrmr; + rtcp->rtc->CR |= RTC_CR_ALRBE; + rtcp->rtc->CR |= RTC_CR_ALRBIE; + } + else { + rtcp->rtc->CR &= ~RTC_CR_ALRBIE; + rtcp->rtc->CR &= ~RTC_CR_ALRBE; + } + } +#endif /* RTC_ALARMS > 1 */ + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); +} + +/** + * @brief Get alarm time. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] alarm alarm identifier. Can be 0 or 1. + * @param[out] alarmspec pointer to a @p RTCAlarm structure + * + * @notapi + */ +void rtc_lld_get_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + RTCAlarm *alarmspec) { + + if (alarm == 0) + alarmspec->alrmr = rtcp->rtc->ALRMAR; +#if RTC_ALARMS > 1 + else + alarmspec->alrmr = rtcp->rtc->ALRMBR; +#endif /* RTC_ALARMS > 1 */ +} +#endif /* RTC_ALARMS > 0 */ + +/** + * @brief Enables or disables RTC callbacks. + * @details This function enables or disables callbacks, use a @p NULL pointer + * in order to disable a callback. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] callback callback function pointer or @p NULL + * + * @notapi + */ +void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) { + + rtcp->callback = callback; +} + +#if STM32_RTC_HAS_PERIODIC_WAKEUPS || defined(__DOXYGEN__) +/** + * @brief Sets time of periodic wakeup. + * @note Default value after BKP domain reset is 0x0000FFFF + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] wakeupspec pointer to a @p RTCWakeup structure + * + * @api + */ +void rtcSTM32SetPeriodicWakeup(RTCDriver *rtcp, const RTCWakeup *wakeupspec) { + syssts_t sts; + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + if (wakeupspec != NULL) { + osalDbgCheck(wakeupspec->wutr != 0x30000); + + rtcp->rtc->CR &= ~RTC_CR_WUTE; + rtcp->rtc->CR &= ~RTC_CR_WUTIE; + while (!(rtcp->rtc->ISR & RTC_ISR_WUTWF)) + ; + rtcp->rtc->WUTR = wakeupspec->wutr & 0xFFFF; + rtcp->rtc->CR &= ~RTC_CR_WUCKSEL; + rtcp->rtc->CR |= (wakeupspec->wutr >> 16) & RTC_CR_WUCKSEL; + rtcp->rtc->CR |= RTC_CR_WUTIE; + rtcp->rtc->CR |= RTC_CR_WUTE; + } + else { + rtcp->rtc->CR &= ~RTC_CR_WUTE; + rtcp->rtc->CR &= ~RTC_CR_WUTIE; + } + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); +} + +/** + * @brief Gets time of periodic wakeup. + * @note Default value after BKP domain reset is 0x0000FFFF + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[out] wakeupspec pointer to a @p RTCWakeup structure + * + * @api + */ +void rtcSTM32GetPeriodicWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec) { + syssts_t sts; + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + wakeupspec->wutr = 0; + wakeupspec->wutr |= rtcp->rtc->WUTR; + wakeupspec->wutr |= (((uint32_t)rtcp->rtc->CR) & 0x7) << 16; + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); +} +#endif /* STM32_RTC_HAS_PERIODIC_WAKEUPS */ + +#endif /* HAL_USE_RTC */ + +/** @} */ diff --git a/readme.txt b/readme.txt index b591de5ddd..2b67cf921f 100644 --- a/readme.txt +++ b/readme.txt @@ -75,6 +75,7 @@ *** 20.3.5 *** - FIX: Virtual timers lockup uder rare conditions (bug #1235). +- FIX: STM32 RTCv2 locks for a second (bug #1234). - FIX: Some MISRA-related fixes. - FIX: Re-opened and fixed bug #1100. - FIX: Fixed wrong buffers toggling in STM32 USBv1 isochronous mode (bug #1232). From d17179f29acfe9e51427fc07799b921ece65a455 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 18 Sep 2022 09:48:47 +0000 Subject: [PATCH 03/53] Fixed bug #1236. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@15789 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/include/hal_serial.h | 6 +++--- readme.txt | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/os/hal/include/hal_serial.h b/os/hal/include/hal_serial.h index d4309c2dea..48d6affadb 100644 --- a/os/hal/include/hal_serial.h +++ b/os/hal/include/hal_serial.h @@ -195,7 +195,7 @@ struct SerialDriver { #define sdGetTimeout(sdp, t) iqGetTimeout(&(sdp)->iqueue, t) /** - * @brief Direct blocking write to a @p SerialDriver. + * @brief Direct non-blocking write to a @p SerialDriver. * @note This function bypasses the indirect access to the channel and * writes directly to the output queue. This is faster but cannot * be used to write from different channels implementations. @@ -238,14 +238,14 @@ struct SerialDriver { oqWriteTimeout(&(sdp)->oqueue, b, n, TIME_IMMEDIATE) /** - * @brief Direct blocking read from a @p SerialDriver. + * @brief Direct non-blocking read from a @p SerialDriver. * @note This function bypasses the indirect access to the channel and * reads directly from the input queue. This is faster but cannot * be used to read from different channels implementations. * * @iclass */ -#define sdReadI(sdp, b, n) iqReadI(&(sdp)->iqueue, b, n, TIME_INFINITE) +#define sdReadI(sdp, b, n) iqReadI(&(sdp)->iqueue, b, n) /** * @brief Direct blocking read from a @p SerialDriver. diff --git a/readme.txt b/readme.txt index 2b67cf921f..4de64c609b 100644 --- a/readme.txt +++ b/readme.txt @@ -74,8 +74,9 @@ ***************************************************************************** *** 20.3.5 *** -- FIX: Virtual timers lockup uder rare conditions (bug #1235). -- FIX: STM32 RTCv2 locks for a second (bug #1234). +- FIX: Fixed old bugs in serial driver header (bug #1236). +- FIX: Fixed virtual timers lockup uder rare conditions (bug #1235). +- FIX: Fixed STM32 RTCv2 locks for a second (bug #1234). - FIX: Some MISRA-related fixes. - FIX: Re-opened and fixed bug #1100. - FIX: Fixed wrong buffers toggling in STM32 USBv1 isochronous mode (bug #1232). From 6b5ae2ab856362dc6813b6f8eec2d2b7f73f2311 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 18 Sep 2022 10:01:17 +0000 Subject: [PATCH 04/53] Fixed bug #1237. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@15790 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/STM32L4xx/stm32_registry.h | 3 ++- readme.txt | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/os/hal/ports/STM32/STM32L4xx/stm32_registry.h b/os/hal/ports/STM32/STM32L4xx/stm32_registry.h index f8ba636424..22a4dc1e7a 100644 --- a/os/hal/ports/STM32/STM32L4xx/stm32_registry.h +++ b/os/hal/ports/STM32/STM32L4xx/stm32_registry.h @@ -1150,7 +1150,8 @@ RCC_AHB2ENR_GPIOEEN | \ RCC_AHB2ENR_GPIOFEN | \ RCC_AHB2ENR_GPIOGEN | \ - RCC_AHB2ENR_GPIOHEN) + RCC_AHB2ENR_GPIOHEN | \ + RCC_AHB2ENR_GPIOIEN) /* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE diff --git a/readme.txt b/readme.txt index 4de64c609b..47e1689068 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed missing clock enables for some GPIOS on some STM32L4s (bug #1237). - FIX: Fixed old bugs in serial driver header (bug #1236). - FIX: Fixed virtual timers lockup uder rare conditions (bug #1235). - FIX: Fixed STM32 RTCv2 locks for a second (bug #1234). From 93176a57393f9053f4c7dc0979ac92d58f6be054 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 22 Oct 2022 07:52:45 +0000 Subject: [PATCH 05/53] Fixed bug #1240. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@15825 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/LLD/ADCv5/hal_adc_lld.c | 2 +- readme.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/os/hal/ports/STM32/LLD/ADCv5/hal_adc_lld.c b/os/hal/ports/STM32/LLD/ADCv5/hal_adc_lld.c index 30636094e7..dcbbecc8c3 100644 --- a/os/hal/ports/STM32/LLD/ADCv5/hal_adc_lld.c +++ b/os/hal/ports/STM32/LLD/ADCv5/hal_adc_lld.c @@ -61,7 +61,7 @@ NOINLINE static void adc_lld_vreg_on(ADC_TypeDef *adc) { #if defined(ADC_CR_ADVREGEN) adc->CR = ADC_CR_ADVREGEN; - volatile uint32_t loop = (STM32_HCLK >> 20) << 4; + volatile uint32_t loop = STM32_HCLK >> 16; do { loop--; } while (loop > 0); diff --git a/readme.txt b/readme.txt index 47e1689068..5d6e72cd93 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed invalid delay loop in STM32G0/WL ADCv5 driver (bug #1240). - FIX: Fixed missing clock enables for some GPIOS on some STM32L4s (bug #1237). - FIX: Fixed old bugs in serial driver header (bug #1236). - FIX: Fixed virtual timers lockup uder rare conditions (bug #1235). From 2f56f67ca8063e7e6d6246ed9905cb64a84a2017 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 20 Nov 2022 08:51:07 +0000 Subject: [PATCH 06/53] Fixed bug #1241. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@15842 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.c | 2307 ++++++++++---------- readme.txt | 1 + 2 files changed, 1155 insertions(+), 1153 deletions(-) diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.c b/os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.c index f7c449edb8..aede303d81 100644 --- a/os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.c +++ b/os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.c @@ -1,1153 +1,1154 @@ -/* - ChibiOS - Copyright (C) 2006..2018 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 TIMv1/hal_gpt_lld.c - * @brief STM32 GPT subsystem low level driver source. - * - * @addtogroup GPT - * @{ - */ - -#include "hal.h" - -#if HAL_USE_GPT || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief GPTD1 driver identifier. - * @note The driver GPTD1 allocates the complex timer TIM1 when enabled. - */ -#if STM32_GPT_USE_TIM1 || defined(__DOXYGEN__) -GPTDriver GPTD1; -#endif - -/** - * @brief GPTD2 driver identifier. - * @note The driver GPTD2 allocates the timer TIM2 when enabled. - */ -#if STM32_GPT_USE_TIM2 || defined(__DOXYGEN__) -GPTDriver GPTD2; -#endif - -/** - * @brief GPTD3 driver identifier. - * @note The driver GPTD3 allocates the timer TIM3 when enabled. - */ -#if STM32_GPT_USE_TIM3 || defined(__DOXYGEN__) -GPTDriver GPTD3; -#endif - -/** - * @brief GPTD4 driver identifier. - * @note The driver GPTD4 allocates the timer TIM4 when enabled. - */ -#if STM32_GPT_USE_TIM4 || defined(__DOXYGEN__) -GPTDriver GPTD4; -#endif - -/** - * @brief GPTD5 driver identifier. - * @note The driver GPTD5 allocates the timer TIM5 when enabled. - */ -#if STM32_GPT_USE_TIM5 || defined(__DOXYGEN__) -GPTDriver GPTD5; -#endif - -/** - * @brief GPTD6 driver identifier. - * @note The driver GPTD6 allocates the timer TIM6 when enabled. - */ -#if STM32_GPT_USE_TIM6 || defined(__DOXYGEN__) -GPTDriver GPTD6; -#endif - -/** - * @brief GPTD7 driver identifier. - * @note The driver GPTD7 allocates the timer TIM7 when enabled. - */ -#if STM32_GPT_USE_TIM7 || defined(__DOXYGEN__) -GPTDriver GPTD7; -#endif - -/** - * @brief GPTD8 driver identifier. - * @note The driver GPTD8 allocates the timer TIM8 when enabled. - */ -#if STM32_GPT_USE_TIM8 || defined(__DOXYGEN__) -GPTDriver GPTD8; -#endif - -/** - * @brief GPTD9 driver identifier. - * @note The driver GPTD9 allocates the timer TIM9 when enabled. - */ -#if STM32_GPT_USE_TIM9 || defined(__DOXYGEN__) -GPTDriver GPTD9; -#endif - -/** - * @brief GPTD10 driver identifier. - * @note The driver GPTD10 allocates the timer TIM10 when enabled. - */ -#if STM32_GPT_USE_TIM10 || defined(__DOXYGEN__) -GPTDriver GPTD10; -#endif - -/** - * @brief GPTD11 driver identifier. - * @note The driver GPTD11 allocates the timer TIM11 when enabled. - */ -#if STM32_GPT_USE_TIM11 || defined(__DOXYGEN__) -GPTDriver GPTD11; -#endif - -/** - * @brief GPTD12 driver identifier. - * @note The driver GPTD12 allocates the timer TIM12 when enabled. - */ -#if STM32_GPT_USE_TIM12 || defined(__DOXYGEN__) -GPTDriver GPTD12; -#endif - -/** - * @brief GPTD13 driver identifier. - * @note The driver GPTD13 allocates the timer TIM13 when enabled. - */ -#if STM32_GPT_USE_TIM13 || defined(__DOXYGEN__) -GPTDriver GPTD13; -#endif - -/** - * @brief GPTD14 driver identifier. - * @note The driver GPTD14 allocates the timer TIM14 when enabled. - */ -#if STM32_GPT_USE_TIM14 || defined(__DOXYGEN__) -GPTDriver GPTD14; -#endif - -/** - * @brief GPTD15 driver identifier. - * @note The driver GPTD14 allocates the timer TIM14 when enabled. - */ -#if STM32_GPT_USE_TIM15 || defined(__DOXYGEN__) -GPTDriver GPTD15; -#endif - -/** - * @brief GPTD16 driver identifier. - * @note The driver GPTD14 allocates the timer TIM14 when enabled. - */ -#if STM32_GPT_USE_TIM16 || defined(__DOXYGEN__) -GPTDriver GPTD16; -#endif - -/** - * @brief GPTD17 driver identifier. - * @note The driver GPTD14 allocates the timer TIM14 when enabled. - */ -#if STM32_GPT_USE_TIM17 || defined(__DOXYGEN__) -GPTDriver GPTD17; -#endif - -/** - * @brief GPTD21 driver identifier. - * @note The driver GPTD21 allocates the timer TIM21 when enabled. - */ -#if STM32_GPT_USE_TIM21 || defined(__DOXYGEN__) -GPTDriver GPTD21; -#endif - -/** - * @brief GPTD22 driver identifier. - * @note The driver GPTD22 allocates the timer TIM22 when enabled. - */ -#if STM32_GPT_USE_TIM22 || defined(__DOXYGEN__) -GPTDriver GPTD22; -#endif - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if STM32_GPT_USE_TIM1 || defined(__DOXYGEN__) -#if !defined(STM32_TIM1_SUPPRESS_ISR) -#if !defined(STM32_TIM1_UP_HANDLER) -#error "STM32_TIM1_UP_HANDLER not defined" -#endif -/** - * @brief TIM1 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_TIM1_UP_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - gpt_lld_serve_interrupt(&GPTD1); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* !defined(STM32_TIM1_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM1 */ - -#if STM32_GPT_USE_TIM2 || defined(__DOXYGEN__) -#if !defined(STM32_TIM2_SUPPRESS_ISR) -#if !defined(STM32_TIM2_HANDLER) -#error "STM32_TIM2_HANDLER not defined" -#endif -/** - * @brief TIM2 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_TIM2_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - gpt_lld_serve_interrupt(&GPTD2); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* !defined(STM32_TIM2_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM2 */ - -#if STM32_GPT_USE_TIM3 || defined(__DOXYGEN__) -#if !defined(STM32_TIM3_SUPPRESS_ISR) -#if !defined(STM32_TIM3_HANDLER) -#error "STM32_TIM3_HANDLER not defined" -#endif -/** - * @brief TIM3 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_TIM3_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - gpt_lld_serve_interrupt(&GPTD3); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* !defined(STM32_TIM3_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM3 */ - -#if STM32_GPT_USE_TIM4 || defined(__DOXYGEN__) -#if !defined(STM32_TIM4_SUPPRESS_ISR) -#if !defined(STM32_TIM4_HANDLER) -#error "STM32_TIM4_HANDLER not defined" -#endif -/** - * @brief TIM4 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_TIM4_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - gpt_lld_serve_interrupt(&GPTD4); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* !defined(STM32_TIM4_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM4 */ - -#if STM32_GPT_USE_TIM5 || defined(__DOXYGEN__) -#if !defined(STM32_TIM5_SUPPRESS_ISR) -#if !defined(STM32_TIM5_HANDLER) -#error "STM32_TIM5_HANDLER not defined" -#endif -/** - * @brief TIM5 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_TIM5_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - gpt_lld_serve_interrupt(&GPTD5); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* !defined(STM32_TIM5_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM5 */ - -#if STM32_GPT_USE_TIM6 || defined(__DOXYGEN__) -#if !defined(STM32_TIM6_SUPPRESS_ISR) -#if !defined(STM32_TIM6_HANDLER) -#error "STM32_TIM6_HANDLER not defined" -#endif -/** - * @brief TIM6 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_TIM6_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - gpt_lld_serve_interrupt(&GPTD6); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* !defined(STM32_TIM6_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM6 */ - -#if STM32_GPT_USE_TIM7 || defined(__DOXYGEN__) -#if !defined(STM32_TIM7_SUPPRESS_ISR) -#if !defined(STM32_TIM7_HANDLER) -#error "STM32_TIM7_HANDLER not defined" -#endif -/** - * @brief TIM7 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_TIM7_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - gpt_lld_serve_interrupt(&GPTD7); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* !defined(STM32_TIM7_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM7 */ - -#if STM32_GPT_USE_TIM8 || defined(__DOXYGEN__) -#if !defined(STM32_TIM8_SUPPRESS_ISR) -#if !defined(STM32_TIM8_UP_HANDLER) -#error "STM32_TIM8_UP_HANDLER not defined" -#endif -/** - * @brief TIM8 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_TIM8_UP_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - gpt_lld_serve_interrupt(&GPTD8); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* !defined(STM32_TIM8_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM8 */ - -#if STM32_GPT_USE_TIM9 || defined(__DOXYGEN__) -#if !defined(STM32_TIM9_SUPPRESS_ISR) -#error "TIM9 ISR not defined by platform" -#endif /* !defined(STM32_TIM9_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM9 */ - -#if STM32_GPT_USE_TIM10 || defined(__DOXYGEN__) -#if !defined(STM32_TIM10_SUPPRESS_ISR) -#error "TIM10 ISR not defined by platform" -#endif /* !defined(STM32_TIM10_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM10 */ - -#if STM32_GPT_USE_TIM11 || defined(__DOXYGEN__) -#if !defined(STM32_TIM11_SUPPRESS_ISR) -#error "TIM11 ISR not defined by platform" -#endif /* !defined(STM32_TIM11_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM11 */ - -#if STM32_GPT_USE_TIM12 || defined(__DOXYGEN__) -#if !defined(STM32_TIM12_SUPPRESS_ISR) -#error "TIM12 ISR not defined by platform" -#endif /* !defined(STM32_TIM12_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM12 */ - -#if STM32_GPT_USE_TIM13 || defined(__DOXYGEN__) -#if !defined(STM32_TIM13_SUPPRESS_ISR) -#error "TIM13 ISR not defined by platform" -#endif /* !defined(STM32_TIM13_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM13 */ - -#if STM32_GPT_USE_TIM14 || defined(__DOXYGEN__) -#if !defined(STM32_TIM14_SUPPRESS_ISR) -#error "TIM14 ISR not defined by platform" -#endif /* !defined(STM32_TIM14_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM14 */ - -#if STM32_GPT_USE_TIM15 || defined(__DOXYGEN__) -#if !defined(STM32_TIM15_SUPPRESS_ISR) -#error "TIM15 ISR not defined by platform" -#endif /* !defined(STM32_TIM15_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM15 */ - -#if STM32_GPT_USE_TIM16 || defined(__DOXYGEN__) -#if !defined(STM32_TIM16_SUPPRESS_ISR) -#error "TIM16 ISR not defined by platform" -#endif /* !defined(STM32_TIM16_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM16 */ - -#if STM32_GPT_USE_TIM17 || defined(__DOXYGEN__) -#if !defined(STM32_TIM17_SUPPRESS_ISR) -#error "TIM17 ISR not defined by platform" -#endif /* !defined(STM32_TIM17_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM17 */ - -#if STM32_GPT_USE_TIM21 || defined(__DOXYGEN__) -#if !defined(STM32_TIM21_SUPPRESS_ISR) -#if !defined(STM32_TIM21_HANDLER) -#error "STM32_TIM21_HANDLER not defined" -#endif -/** - * @brief TIM21 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_TIM21_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - gpt_lld_serve_interrupt(&GPTD21); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* !defined(STM32_TIM21_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM21 */ - -#if STM32_GPT_USE_TIM22 || defined(__DOXYGEN__) -#if !defined(STM32_TIM22_SUPPRESS_ISR) -#if !defined(STM32_TIM22_HANDLER) -#error "STM32_TIM22_HANDLER not defined" -#endif -/** - * @brief TIM22 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_TIM22_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - gpt_lld_serve_interrupt(&GPTD22); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* !defined(STM32_TIM22_SUPPRESS_ISR) */ -#endif /* STM32_GPT_USE_TIM22 */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level GPT driver initialization. - * - * @notapi - */ -void gpt_lld_init(void) { - -#if STM32_GPT_USE_TIM1 - /* Driver initialization.*/ - GPTD1.tim = STM32_TIM1; - gptObjectInit(&GPTD1); -#endif - -#if STM32_GPT_USE_TIM2 - /* Driver initialization.*/ - GPTD2.tim = STM32_TIM2; - gptObjectInit(&GPTD2); -#endif - -#if STM32_GPT_USE_TIM3 - /* Driver initialization.*/ - GPTD3.tim = STM32_TIM3; - gptObjectInit(&GPTD3); -#endif - -#if STM32_GPT_USE_TIM4 - /* Driver initialization.*/ - GPTD4.tim = STM32_TIM4; - gptObjectInit(&GPTD4); -#endif - -#if STM32_GPT_USE_TIM5 - /* Driver initialization.*/ - GPTD5.tim = STM32_TIM5; - gptObjectInit(&GPTD5); -#endif - -#if STM32_GPT_USE_TIM6 - /* Driver initialization.*/ - GPTD6.tim = STM32_TIM6; - gptObjectInit(&GPTD6); -#endif - -#if STM32_GPT_USE_TIM7 - /* Driver initialization.*/ - GPTD7.tim = STM32_TIM7; - gptObjectInit(&GPTD7); -#endif - -#if STM32_GPT_USE_TIM8 - /* Driver initialization.*/ - GPTD8.tim = STM32_TIM8; - gptObjectInit(&GPTD8); -#endif - -#if STM32_GPT_USE_TIM9 - /* Driver initialization.*/ - GPTD9.tim = STM32_TIM9; - gptObjectInit(&GPTD9); -#endif - -#if STM32_GPT_USE_TIM10 - /* Driver initialization.*/ - GPTD10.tim = STM32_TIM10; - gptObjectInit(&GPTD10); -#endif - -#if STM32_GPT_USE_TIM11 - /* Driver initialization.*/ - GPTD11.tim = STM32_TIM11; - gptObjectInit(&GPTD11); -#endif - -#if STM32_GPT_USE_TIM12 - /* Driver initialization.*/ - GPTD12.tim = STM32_TIM12; - gptObjectInit(&GPTD12); -#endif - -#if STM32_GPT_USE_TIM13 - /* Driver initialization.*/ - GPTD13.tim = STM32_TIM13; - gptObjectInit(&GPTD13); -#endif - -#if STM32_GPT_USE_TIM14 - /* Driver initialization.*/ - GPTD14.tim = STM32_TIM14; - gptObjectInit(&GPTD14); -#endif - -#if STM32_GPT_USE_TIM15 - /* Driver initialization.*/ - GPTD15.tim = STM32_TIM15; - gptObjectInit(&GPTD15); -#endif - -#if STM32_GPT_USE_TIM16 - /* Driver initialization.*/ - GPTD16.tim = STM32_TIM16; - gptObjectInit(&GPTD16); -#endif - -#if STM32_GPT_USE_TIM17 - /* Driver initialization.*/ - GPTD17.tim = STM32_TIM17; - gptObjectInit(&GPTD17); -#endif - -#if STM32_GPT_USE_TIM21 - /* Driver initialization.*/ - GPTD21.tim = STM32_TIM21; - gptObjectInit(&GPTD21); -#endif - -#if STM32_GPT_USE_TIM22 - /* Driver initialization.*/ - GPTD22.tim = STM32_TIM22; - gptObjectInit(&GPTD22); -#endif -} - -/** - * @brief Configures and activates the GPT peripheral. - * - * @param[in] gptp pointer to the @p GPTDriver object - * - * @notapi - */ -void gpt_lld_start(GPTDriver *gptp) { - uint16_t psc; - - if (gptp->state == GPT_STOP) { - /* Clock activation.*/ -#if STM32_GPT_USE_TIM1 - if (&GPTD1 == gptp) { - rccEnableTIM1(true); - rccResetTIM1(); -#if !defined(STM32_TIM1_SUPPRESS_ISR) - nvicEnableVector(STM32_TIM1_UP_NUMBER, STM32_GPT_TIM1_IRQ_PRIORITY); -#endif -#if defined(STM32_TIM1CLK) - gptp->clock = STM32_TIM1CLK; -#else - gptp->clock = STM32_TIMCLK2; -#endif - } -#endif - -#if STM32_GPT_USE_TIM2 - if (&GPTD2 == gptp) { - rccEnableTIM2(true); - rccResetTIM2(); -#if !defined(STM32_TIM2_SUPPRESS_ISR) - nvicEnableVector(STM32_TIM2_NUMBER, STM32_GPT_TIM2_IRQ_PRIORITY); -#endif -#if defined(STM32_TIM2CLK) - gptp->clock = STM32_TIM2CLK; -#else - gptp->clock = STM32_TIMCLK1; -#endif - } -#endif - -#if STM32_GPT_USE_TIM3 - if (&GPTD3 == gptp) { - rccEnableTIM3(true); - rccResetTIM3(); -#if !defined(STM32_TIM3_SUPPRESS_ISR) - nvicEnableVector(STM32_TIM3_NUMBER, STM32_GPT_TIM3_IRQ_PRIORITY); -#endif -#if defined(STM32_TIM3CLK) - gptp->clock = STM32_TIM3CLK; -#else - gptp->clock = STM32_TIMCLK1; -#endif - } -#endif - -#if STM32_GPT_USE_TIM4 - if (&GPTD4 == gptp) { - rccEnableTIM4(true); - rccResetTIM4(); -#if !defined(STM32_TIM4_SUPPRESS_ISR) - nvicEnableVector(STM32_TIM4_NUMBER, STM32_GPT_TIM4_IRQ_PRIORITY); -#endif -#if defined(STM32_TIM4CLK) - gptp->clock = STM32_TIM4CLK; -#else - gptp->clock = STM32_TIMCLK1; -#endif - } -#endif - -#if STM32_GPT_USE_TIM5 - if (&GPTD5 == gptp) { - rccEnableTIM5(true); - rccResetTIM5(); -#if !defined(STM32_TIM5_SUPPRESS_ISR) - nvicEnableVector(STM32_TIM5_NUMBER, STM32_GPT_TIM5_IRQ_PRIORITY); -#endif -#if defined(STM32_TIM5CLK) - gptp->clock = STM32_TIM5CLK; -#else - gptp->clock = STM32_TIMCLK1; -#endif - } -#endif - -#if STM32_GPT_USE_TIM6 - if (&GPTD6 == gptp) { - rccEnableTIM6(true); - rccResetTIM6(); -#if !defined(STM32_TIM6_SUPPRESS_ISR) - nvicEnableVector(STM32_TIM6_NUMBER, STM32_GPT_TIM6_IRQ_PRIORITY); -#endif -#if defined(STM32_TIM6CLK) - gptp->clock = STM32_TIM6CLK; -#else - gptp->clock = STM32_TIMCLK1; -#endif - } -#endif - -#if STM32_GPT_USE_TIM7 - if (&GPTD7 == gptp) { - rccEnableTIM7(true); - rccResetTIM7(); -#if !defined(STM32_TIM7_SUPPRESS_ISR) - nvicEnableVector(STM32_TIM7_NUMBER, STM32_GPT_TIM7_IRQ_PRIORITY); -#endif -#if defined(STM32_TIM7CLK) - gptp->clock = STM32_TIM7CLK; -#else - gptp->clock = STM32_TIMCLK1; -#endif - } -#endif - -#if STM32_GPT_USE_TIM8 - if (&GPTD8 == gptp) { - rccEnableTIM8(true); - rccResetTIM8(); -#if !defined(STM32_TIM8_SUPPRESS_ISR) - nvicEnableVector(STM32_TIM8_UP_NUMBER, STM32_GPT_TIM8_IRQ_PRIORITY); -#endif -#if defined(STM32_TIM8CLK) - gptp->clock = STM32_TIM8CLK; -#else - gptp->clock = STM32_TIMCLK2; -#endif - } -#endif - -#if STM32_GPT_USE_TIM9 - if (&GPTD9 == gptp) { - rccEnableTIM9(true); - rccResetTIM9(); -#if !defined(STM32_TIM9_SUPPRESS_ISR) - nvicEnableVector(STM32_TIM9_NUMBER, STM32_GPT_TIM9_IRQ_PRIORITY); -#endif -#if defined(STM32_TIM9CLK) - gptp->clock = STM32_TIM9CLK; -#else - gptp->clock = STM32_TIMCLK2; -#endif - } -#endif - -#if STM32_GPT_USE_TIM10 - if (&GPTD10 == gptp) { - rccEnableTIM10(true); - rccResetTIM10(); -#if !defined(STM32_TIM10_SUPPRESS_ISR) - nvicEnableVector(STM32_TIM10_NUMBER, STM32_GPT_TIM10_IRQ_PRIORITY); -#endif -#if defined(STM32_TIM10CLK) - gptp->clock = STM32_TIM10CLK; -#else - gptp->clock = STM32_TIMCLK2; -#endif - } -#endif - -#if STM32_GPT_USE_TIM11 - if (&GPTD11 == gptp) { - rccEnableTIM11(true); - rccResetTIM11(); -#if !defined(STM32_TIM11_SUPPRESS_ISR) - nvicEnableVector(STM32_TIM11_NUMBER, STM32_GPT_TIM11_IRQ_PRIORITY); -#endif -#if defined(STM32_TIM11CLK) - gptp->clock = STM32_TIM11CLK; -#else - gptp->clock = STM32_TIMCLK2; -#endif - } -#endif - -#if STM32_GPT_USE_TIM12 - if (&GPTD12 == gptp) { - rccEnableTIM12(true); - rccResetTIM12(); -#if !defined(STM32_TIM12_SUPPRESS_ISR) - nvicEnableVector(STM32_TIM12_NUMBER, STM32_GPT_TIM12_IRQ_PRIORITY); -#endif -#if defined(STM32_TIM12CLK) - gptp->clock = STM32_TIM12CLK; -#else - gptp->clock = STM32_TIMCLK1; -#endif - } -#endif - -#if STM32_GPT_USE_TIM13 - if (&GPTD13 == gptp) { - rccEnableTIM13(true); - rccResetTIM13(); -#if !defined(STM32_TIM13_SUPPRESS_ISR) - nvicEnableVector(STM32_TIM13_NUMBER, STM32_GPT_TIM13_IRQ_PRIORITY); -#endif -#if defined(STM32_TIM13CLK) - gptp->clock = STM32_TIM13CLK; -#else - gptp->clock = STM32_TIMCLK1; -#endif - } -#endif - -#if STM32_GPT_USE_TIM14 - if (&GPTD14 == gptp) { - rccEnableTIM14(true); - rccResetTIM14(); -#if !defined(STM32_TIM14_SUPPRESS_ISR) - nvicEnableVector(STM32_TIM14_NUMBER, STM32_GPT_TIM14_IRQ_PRIORITY); -#endif -#if defined(STM32_TIM14CLK) - gptp->clock = STM32_TIM14CLK; -#else - gptp->clock = STM32_TIMCLK1; -#endif - } -#endif - -#if STM32_GPT_USE_TIM15 - if (&GPTD15 == gptp) { - rccEnableTIM15(true); - rccResetTIM15(); -#if defined(STM32_TIM15CLK) - gptp->clock = STM32_TIM15CLK; -#else - gptp->clock = STM32_TIMCLK2; -#endif - } -#endif - -#if STM32_GPT_USE_TIM16 - if (&GPTD16 == gptp) { - rccEnableTIM16(true); - rccResetTIM16(); -#if defined(STM32_TIM16CLK) - gptp->clock = STM32_TIM16CLK; -#else - gptp->clock = STM32_TIMCLK2; -#endif - } -#endif - -#if STM32_GPT_USE_TIM17 - if (&GPTD17 == gptp) { - rccEnableTIM17(true); - rccResetTIM17(); -#if defined(STM32_TIM17CLK) - gptp->clock = STM32_TIM17CLK; -#else - gptp->clock = STM32_TIMCLK2; -#endif - } -#endif - -#if STM32_GPT_USE_TIM21 - if (&GPTD21 == gptp) { - rccEnableTIM21(true); - rccResetTIM21(); -#if !defined(STM32_TIM21_SUPPRESS_ISR) - nvicEnableVector(STM32_TIM21_NUMBER, STM32_GPT_TIM21_IRQ_PRIORITY); -#endif -#if defined(STM32_TIM21CLK) - gptp->clock = STM32_TIM21CLK; -#else - gptp->clock = STM32_TIMCLK1; -#endif - } -#endif - -#if STM32_GPT_USE_TIM22 - if (&GPTD22 == gptp) { - rccEnableTIM22(true); - rccResetTIM22(); -#if !defined(STM32_TIM22_SUPPRESS_ISR) - nvicEnableVector(STM32_TIM22_NUMBER, STM32_GPT_TIM22_IRQ_PRIORITY); -#endif -#if defined(STM32_TIM22CLK) - gptp->clock = STM32_TIM22CLK; -#else - gptp->clock = STM32_TIMCLK1; -#endif - } -#endif - } - - /* Prescaler value calculation.*/ - psc = (uint16_t)((gptp->clock / gptp->config->frequency) - 1); - osalDbgAssert(((uint32_t)(psc + 1) * gptp->config->frequency) == gptp->clock, - "invalid frequency"); - - /* Timer configuration.*/ - gptp->tim->CR1 = 0; /* Initially stopped. */ - gptp->tim->CR2 = gptp->config->cr2; - gptp->tim->PSC = psc; /* Prescaler value. */ - gptp->tim->SR = 0; /* Clear pending IRQs. */ - gptp->tim->DIER = gptp->config->dier & /* DMA-related DIER bits. */ - ~STM32_TIM_DIER_IRQ_MASK; -} - -/** - * @brief Deactivates the GPT peripheral. - * - * @param[in] gptp pointer to the @p GPTDriver object - * - * @notapi - */ -void gpt_lld_stop(GPTDriver *gptp) { - - if (gptp->state == GPT_READY) { - gptp->tim->CR1 = 0; /* Timer disabled. */ - gptp->tim->DIER = 0; /* All IRQs disabled. */ - gptp->tim->SR = 0; /* Clear pending IRQs. */ - -#if STM32_GPT_USE_TIM1 - if (&GPTD1 == gptp) { -#if !defined(STM32_TIM1_SUPPRESS_ISR) - nvicDisableVector(STM32_TIM1_UP_NUMBER); -#endif - rccDisableTIM1(); - } -#endif - -#if STM32_GPT_USE_TIM2 - if (&GPTD2 == gptp) { -#if !defined(STM32_TIM2_SUPPRESS_ISR) - nvicDisableVector(STM32_TIM2_NUMBER); -#endif - rccDisableTIM2(); - } -#endif - -#if STM32_GPT_USE_TIM3 - if (&GPTD3 == gptp) { -#if !defined(STM32_TIM3_SUPPRESS_ISR) - nvicDisableVector(STM32_TIM3_NUMBER); -#endif - rccDisableTIM3(); - } -#endif - -#if STM32_GPT_USE_TIM4 - if (&GPTD4 == gptp) { -#if !defined(STM32_TIM4_SUPPRESS_ISR) - nvicDisableVector(STM32_TIM4_NUMBER); -#endif - rccDisableTIM4(); - } -#endif - -#if STM32_GPT_USE_TIM5 - if (&GPTD5 == gptp) { -#if !defined(STM32_TIM5_SUPPRESS_ISR) - nvicDisableVector(STM32_TIM5_NUMBER); -#endif - rccDisableTIM5(); - } -#endif - -#if STM32_GPT_USE_TIM6 - if (&GPTD6 == gptp) { -#if !defined(STM32_TIM6_SUPPRESS_ISR) - nvicDisableVector(STM32_TIM6_NUMBER); -#endif - rccDisableTIM6(); - } -#endif - -#if STM32_GPT_USE_TIM7 - if (&GPTD7 == gptp) { -#if !defined(STM32_TIM7_SUPPRESS_ISR) - nvicDisableVector(STM32_TIM7_NUMBER); -#endif - rccDisableTIM7(); - } -#endif - -#if STM32_GPT_USE_TIM8 - if (&GPTD8 == gptp) { -#if !defined(STM32_TIM8_SUPPRESS_ISR) - nvicDisableVector(STM32_TIM8_UP_NUMBER); -#endif - rccDisableTIM8(); - } -#endif - -#if STM32_GPT_USE_TIM9 - if (&GPTD9 == gptp) { -#if !defined(STM32_TIM9_SUPPRESS_ISR) - nvicDisableVector(STM32_TIM9_NUMBER); -#endif - rccDisableTIM9(); - } -#endif - -#if STM32_GPT_USE_TIM10 - if (&GPTD10 == gptp) { -#if !defined(STM32_TIM10_SUPPRESS_ISR) - nvicDisableVector(STM32_TIM10_NUMBER); -#endif - rccDisableTIM10(); - } -#endif - -#if STM32_GPT_USE_TIM11 - if (&GPTD11 == gptp) { -#if !defined(STM32_TIM11_SUPPRESS_ISR) - nvicDisableVector(STM32_TIM11_NUMBER); -#endif - rccDisableTIM11(); - } -#endif - -#if STM32_GPT_USE_TIM12 - if (&GPTD12 == gptp) { -#if !defined(STM32_TIM12_SUPPRESS_ISR) - nvicDisableVector(STM32_TIM12_NUMBER); -#endif - rccDisableTIM12(); - } -#endif - -#if STM32_GPT_USE_TIM13 - if (&GPTD13 == gptp) { -#if !defined(STM32_TIM13_SUPPRESS_ISR) - nvicDisableVector(STM32_TIM13_NUMBER); -#endif - rccDisableTIM13(); - } -#endif - -#if STM32_GPT_USE_TIM14 - if (&GPTD14 == gptp) { -#if !defined(STM32_TIM14_SUPPRESS_ISR) - nvicDisableVector(STM32_TIM14_NUMBER); -#endif - rccDisableTIM14(); - } -#endif - -#if STM32_GPT_USE_TIM15 - if (&GPTD15 == gptp) { - rccDisableTIM15(); - } -#endif - -#if STM32_GPT_USE_TIM16 - if (&GPTD16 == gptp) { - rccDisableTIM16(); - } -#endif - -#if STM32_GPT_USE_TIM17 - if (&GPTD17 == gptp) { - rccDisableTIM17(); - } -#endif - -#if STM32_GPT_USE_TIM21 - if (&GPTD21 == gptp) { -#if !defined(STM32_TIM21_SUPPRESS_ISR) - nvicDisableVector(STM32_TIM21_NUMBER); -#endif - rccDisableTIM21(); - } -#endif - -#if STM32_GPT_USE_TIM22 - if (&GPTD22 == gptp) { -#if !defined(STM32_TIM22_SUPPRESS_ISR) - nvicDisableVector(STM32_TIM22_NUMBER); -#endif - rccDisableTIM22(); - } -#endif - } -} - -/** - * @brief Starts the timer in continuous mode. - * - * @param[in] gptp pointer to the @p GPTDriver object - * @param[in] interval period in ticks - * - * @notapi - */ -void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) { - - gptp->tim->ARR = (uint32_t)(interval - 1U); /* Time constant. */ - gptp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */ - gptp->tim->CNT = 0; /* Reset counter. */ - - /* NOTE: After generating the UG event it takes several clock cycles before - SR bit 0 goes to 1. This is why the clearing of CNT has been inserted - before the clearing of SR, to give it some time.*/ - gptp->tim->SR = 0; /* Clear pending IRQs. */ - if (NULL != gptp->config->callback) - gptp->tim->DIER |= STM32_TIM_DIER_UIE; /* Update Event IRQ enabled.*/ - gptp->tim->CR1 = STM32_TIM_CR1_ARPE | STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN; -} - -/** - * @brief Stops the timer. - * - * @param[in] gptp pointer to the @p GPTDriver object - * - * @notapi - */ -void gpt_lld_stop_timer(GPTDriver *gptp) { - - gptp->tim->CR1 = 0; /* Initially stopped. */ - gptp->tim->SR = 0; /* Clear pending IRQs. */ - - /* All interrupts disabled.*/ - gptp->tim->DIER &= ~STM32_TIM_DIER_IRQ_MASK; -} - -/** - * @brief Starts the timer in one shot mode and waits for completion. - * @details This function specifically polls the timer waiting for completion - * in order to not have extra delays caused by interrupt servicing, - * this function is only recommended for short delays. - * - * @param[in] gptp pointer to the @p GPTDriver object - * @param[in] interval time interval in ticks - * - * @notapi - */ -void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) { - - gptp->tim->ARR = (uint32_t)(interval - 1U); /* Time constant. */ - gptp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */ - gptp->tim->SR = 0; /* Clear pending IRQs. */ - gptp->tim->CR1 = STM32_TIM_CR1_OPM | STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN; - while (!(gptp->tim->SR & STM32_TIM_SR_UIF)) - ; - gptp->tim->SR = 0; /* Clear pending IRQs. */ -} - -/** - * @brief Shared IRQ handler. - * - * @param[in] gptp pointer to a @p GPTDriver object - * - * @notapi - */ -void gpt_lld_serve_interrupt(GPTDriver *gptp) { - uint32_t sr; - - sr = gptp->tim->SR; - sr &= gptp->tim->DIER & STM32_TIM_DIER_IRQ_MASK; - gptp->tim->SR = ~sr; - if ((sr & STM32_TIM_SR_UIF) != 0) { - _gpt_isr_invoke_cb(gptp); - } -} - -#endif /* HAL_USE_GPT */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 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 TIMv1/hal_gpt_lld.c + * @brief STM32 GPT subsystem low level driver source. + * + * @addtogroup GPT + * @{ + */ + +#include "hal.h" + +#if HAL_USE_GPT || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief GPTD1 driver identifier. + * @note The driver GPTD1 allocates the complex timer TIM1 when enabled. + */ +#if STM32_GPT_USE_TIM1 || defined(__DOXYGEN__) +GPTDriver GPTD1; +#endif + +/** + * @brief GPTD2 driver identifier. + * @note The driver GPTD2 allocates the timer TIM2 when enabled. + */ +#if STM32_GPT_USE_TIM2 || defined(__DOXYGEN__) +GPTDriver GPTD2; +#endif + +/** + * @brief GPTD3 driver identifier. + * @note The driver GPTD3 allocates the timer TIM3 when enabled. + */ +#if STM32_GPT_USE_TIM3 || defined(__DOXYGEN__) +GPTDriver GPTD3; +#endif + +/** + * @brief GPTD4 driver identifier. + * @note The driver GPTD4 allocates the timer TIM4 when enabled. + */ +#if STM32_GPT_USE_TIM4 || defined(__DOXYGEN__) +GPTDriver GPTD4; +#endif + +/** + * @brief GPTD5 driver identifier. + * @note The driver GPTD5 allocates the timer TIM5 when enabled. + */ +#if STM32_GPT_USE_TIM5 || defined(__DOXYGEN__) +GPTDriver GPTD5; +#endif + +/** + * @brief GPTD6 driver identifier. + * @note The driver GPTD6 allocates the timer TIM6 when enabled. + */ +#if STM32_GPT_USE_TIM6 || defined(__DOXYGEN__) +GPTDriver GPTD6; +#endif + +/** + * @brief GPTD7 driver identifier. + * @note The driver GPTD7 allocates the timer TIM7 when enabled. + */ +#if STM32_GPT_USE_TIM7 || defined(__DOXYGEN__) +GPTDriver GPTD7; +#endif + +/** + * @brief GPTD8 driver identifier. + * @note The driver GPTD8 allocates the timer TIM8 when enabled. + */ +#if STM32_GPT_USE_TIM8 || defined(__DOXYGEN__) +GPTDriver GPTD8; +#endif + +/** + * @brief GPTD9 driver identifier. + * @note The driver GPTD9 allocates the timer TIM9 when enabled. + */ +#if STM32_GPT_USE_TIM9 || defined(__DOXYGEN__) +GPTDriver GPTD9; +#endif + +/** + * @brief GPTD10 driver identifier. + * @note The driver GPTD10 allocates the timer TIM10 when enabled. + */ +#if STM32_GPT_USE_TIM10 || defined(__DOXYGEN__) +GPTDriver GPTD10; +#endif + +/** + * @brief GPTD11 driver identifier. + * @note The driver GPTD11 allocates the timer TIM11 when enabled. + */ +#if STM32_GPT_USE_TIM11 || defined(__DOXYGEN__) +GPTDriver GPTD11; +#endif + +/** + * @brief GPTD12 driver identifier. + * @note The driver GPTD12 allocates the timer TIM12 when enabled. + */ +#if STM32_GPT_USE_TIM12 || defined(__DOXYGEN__) +GPTDriver GPTD12; +#endif + +/** + * @brief GPTD13 driver identifier. + * @note The driver GPTD13 allocates the timer TIM13 when enabled. + */ +#if STM32_GPT_USE_TIM13 || defined(__DOXYGEN__) +GPTDriver GPTD13; +#endif + +/** + * @brief GPTD14 driver identifier. + * @note The driver GPTD14 allocates the timer TIM14 when enabled. + */ +#if STM32_GPT_USE_TIM14 || defined(__DOXYGEN__) +GPTDriver GPTD14; +#endif + +/** + * @brief GPTD15 driver identifier. + * @note The driver GPTD14 allocates the timer TIM14 when enabled. + */ +#if STM32_GPT_USE_TIM15 || defined(__DOXYGEN__) +GPTDriver GPTD15; +#endif + +/** + * @brief GPTD16 driver identifier. + * @note The driver GPTD14 allocates the timer TIM14 when enabled. + */ +#if STM32_GPT_USE_TIM16 || defined(__DOXYGEN__) +GPTDriver GPTD16; +#endif + +/** + * @brief GPTD17 driver identifier. + * @note The driver GPTD14 allocates the timer TIM14 when enabled. + */ +#if STM32_GPT_USE_TIM17 || defined(__DOXYGEN__) +GPTDriver GPTD17; +#endif + +/** + * @brief GPTD21 driver identifier. + * @note The driver GPTD21 allocates the timer TIM21 when enabled. + */ +#if STM32_GPT_USE_TIM21 || defined(__DOXYGEN__) +GPTDriver GPTD21; +#endif + +/** + * @brief GPTD22 driver identifier. + * @note The driver GPTD22 allocates the timer TIM22 when enabled. + */ +#if STM32_GPT_USE_TIM22 || defined(__DOXYGEN__) +GPTDriver GPTD22; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if STM32_GPT_USE_TIM1 || defined(__DOXYGEN__) +#if !defined(STM32_TIM1_SUPPRESS_ISR) +#if !defined(STM32_TIM1_UP_HANDLER) +#error "STM32_TIM1_UP_HANDLER not defined" +#endif +/** + * @brief TIM1 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_TIM1_UP_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + gpt_lld_serve_interrupt(&GPTD1); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* !defined(STM32_TIM1_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM1 */ + +#if STM32_GPT_USE_TIM2 || defined(__DOXYGEN__) +#if !defined(STM32_TIM2_SUPPRESS_ISR) +#if !defined(STM32_TIM2_HANDLER) +#error "STM32_TIM2_HANDLER not defined" +#endif +/** + * @brief TIM2 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_TIM2_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + gpt_lld_serve_interrupt(&GPTD2); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* !defined(STM32_TIM2_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM2 */ + +#if STM32_GPT_USE_TIM3 || defined(__DOXYGEN__) +#if !defined(STM32_TIM3_SUPPRESS_ISR) +#if !defined(STM32_TIM3_HANDLER) +#error "STM32_TIM3_HANDLER not defined" +#endif +/** + * @brief TIM3 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_TIM3_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + gpt_lld_serve_interrupt(&GPTD3); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* !defined(STM32_TIM3_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM3 */ + +#if STM32_GPT_USE_TIM4 || defined(__DOXYGEN__) +#if !defined(STM32_TIM4_SUPPRESS_ISR) +#if !defined(STM32_TIM4_HANDLER) +#error "STM32_TIM4_HANDLER not defined" +#endif +/** + * @brief TIM4 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_TIM4_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + gpt_lld_serve_interrupt(&GPTD4); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* !defined(STM32_TIM4_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM4 */ + +#if STM32_GPT_USE_TIM5 || defined(__DOXYGEN__) +#if !defined(STM32_TIM5_SUPPRESS_ISR) +#if !defined(STM32_TIM5_HANDLER) +#error "STM32_TIM5_HANDLER not defined" +#endif +/** + * @brief TIM5 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_TIM5_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + gpt_lld_serve_interrupt(&GPTD5); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* !defined(STM32_TIM5_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM5 */ + +#if STM32_GPT_USE_TIM6 || defined(__DOXYGEN__) +#if !defined(STM32_TIM6_SUPPRESS_ISR) +#if !defined(STM32_TIM6_HANDLER) +#error "STM32_TIM6_HANDLER not defined" +#endif +/** + * @brief TIM6 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_TIM6_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + gpt_lld_serve_interrupt(&GPTD6); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* !defined(STM32_TIM6_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM6 */ + +#if STM32_GPT_USE_TIM7 || defined(__DOXYGEN__) +#if !defined(STM32_TIM7_SUPPRESS_ISR) +#if !defined(STM32_TIM7_HANDLER) +#error "STM32_TIM7_HANDLER not defined" +#endif +/** + * @brief TIM7 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_TIM7_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + gpt_lld_serve_interrupt(&GPTD7); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* !defined(STM32_TIM7_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM7 */ + +#if STM32_GPT_USE_TIM8 || defined(__DOXYGEN__) +#if !defined(STM32_TIM8_SUPPRESS_ISR) +#if !defined(STM32_TIM8_UP_HANDLER) +#error "STM32_TIM8_UP_HANDLER not defined" +#endif +/** + * @brief TIM8 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_TIM8_UP_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + gpt_lld_serve_interrupt(&GPTD8); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* !defined(STM32_TIM8_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM8 */ + +#if STM32_GPT_USE_TIM9 || defined(__DOXYGEN__) +#if !defined(STM32_TIM9_SUPPRESS_ISR) +#error "TIM9 ISR not defined by platform" +#endif /* !defined(STM32_TIM9_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM9 */ + +#if STM32_GPT_USE_TIM10 || defined(__DOXYGEN__) +#if !defined(STM32_TIM10_SUPPRESS_ISR) +#error "TIM10 ISR not defined by platform" +#endif /* !defined(STM32_TIM10_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM10 */ + +#if STM32_GPT_USE_TIM11 || defined(__DOXYGEN__) +#if !defined(STM32_TIM11_SUPPRESS_ISR) +#error "TIM11 ISR not defined by platform" +#endif /* !defined(STM32_TIM11_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM11 */ + +#if STM32_GPT_USE_TIM12 || defined(__DOXYGEN__) +#if !defined(STM32_TIM12_SUPPRESS_ISR) +#error "TIM12 ISR not defined by platform" +#endif /* !defined(STM32_TIM12_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM12 */ + +#if STM32_GPT_USE_TIM13 || defined(__DOXYGEN__) +#if !defined(STM32_TIM13_SUPPRESS_ISR) +#error "TIM13 ISR not defined by platform" +#endif /* !defined(STM32_TIM13_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM13 */ + +#if STM32_GPT_USE_TIM14 || defined(__DOXYGEN__) +#if !defined(STM32_TIM14_SUPPRESS_ISR) +#error "TIM14 ISR not defined by platform" +#endif /* !defined(STM32_TIM14_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM14 */ + +#if STM32_GPT_USE_TIM15 || defined(__DOXYGEN__) +#if !defined(STM32_TIM15_SUPPRESS_ISR) +#error "TIM15 ISR not defined by platform" +#endif /* !defined(STM32_TIM15_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM15 */ + +#if STM32_GPT_USE_TIM16 || defined(__DOXYGEN__) +#if !defined(STM32_TIM16_SUPPRESS_ISR) +#error "TIM16 ISR not defined by platform" +#endif /* !defined(STM32_TIM16_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM16 */ + +#if STM32_GPT_USE_TIM17 || defined(__DOXYGEN__) +#if !defined(STM32_TIM17_SUPPRESS_ISR) +#error "TIM17 ISR not defined by platform" +#endif /* !defined(STM32_TIM17_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM17 */ + +#if STM32_GPT_USE_TIM21 || defined(__DOXYGEN__) +#if !defined(STM32_TIM21_SUPPRESS_ISR) +#if !defined(STM32_TIM21_HANDLER) +#error "STM32_TIM21_HANDLER not defined" +#endif +/** + * @brief TIM21 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_TIM21_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + gpt_lld_serve_interrupt(&GPTD21); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* !defined(STM32_TIM21_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM21 */ + +#if STM32_GPT_USE_TIM22 || defined(__DOXYGEN__) +#if !defined(STM32_TIM22_SUPPRESS_ISR) +#if !defined(STM32_TIM22_HANDLER) +#error "STM32_TIM22_HANDLER not defined" +#endif +/** + * @brief TIM22 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_TIM22_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + gpt_lld_serve_interrupt(&GPTD22); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* !defined(STM32_TIM22_SUPPRESS_ISR) */ +#endif /* STM32_GPT_USE_TIM22 */ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level GPT driver initialization. + * + * @notapi + */ +void gpt_lld_init(void) { + +#if STM32_GPT_USE_TIM1 + /* Driver initialization.*/ + GPTD1.tim = STM32_TIM1; + gptObjectInit(&GPTD1); +#endif + +#if STM32_GPT_USE_TIM2 + /* Driver initialization.*/ + GPTD2.tim = STM32_TIM2; + gptObjectInit(&GPTD2); +#endif + +#if STM32_GPT_USE_TIM3 + /* Driver initialization.*/ + GPTD3.tim = STM32_TIM3; + gptObjectInit(&GPTD3); +#endif + +#if STM32_GPT_USE_TIM4 + /* Driver initialization.*/ + GPTD4.tim = STM32_TIM4; + gptObjectInit(&GPTD4); +#endif + +#if STM32_GPT_USE_TIM5 + /* Driver initialization.*/ + GPTD5.tim = STM32_TIM5; + gptObjectInit(&GPTD5); +#endif + +#if STM32_GPT_USE_TIM6 + /* Driver initialization.*/ + GPTD6.tim = STM32_TIM6; + gptObjectInit(&GPTD6); +#endif + +#if STM32_GPT_USE_TIM7 + /* Driver initialization.*/ + GPTD7.tim = STM32_TIM7; + gptObjectInit(&GPTD7); +#endif + +#if STM32_GPT_USE_TIM8 + /* Driver initialization.*/ + GPTD8.tim = STM32_TIM8; + gptObjectInit(&GPTD8); +#endif + +#if STM32_GPT_USE_TIM9 + /* Driver initialization.*/ + GPTD9.tim = STM32_TIM9; + gptObjectInit(&GPTD9); +#endif + +#if STM32_GPT_USE_TIM10 + /* Driver initialization.*/ + GPTD10.tim = STM32_TIM10; + gptObjectInit(&GPTD10); +#endif + +#if STM32_GPT_USE_TIM11 + /* Driver initialization.*/ + GPTD11.tim = STM32_TIM11; + gptObjectInit(&GPTD11); +#endif + +#if STM32_GPT_USE_TIM12 + /* Driver initialization.*/ + GPTD12.tim = STM32_TIM12; + gptObjectInit(&GPTD12); +#endif + +#if STM32_GPT_USE_TIM13 + /* Driver initialization.*/ + GPTD13.tim = STM32_TIM13; + gptObjectInit(&GPTD13); +#endif + +#if STM32_GPT_USE_TIM14 + /* Driver initialization.*/ + GPTD14.tim = STM32_TIM14; + gptObjectInit(&GPTD14); +#endif + +#if STM32_GPT_USE_TIM15 + /* Driver initialization.*/ + GPTD15.tim = STM32_TIM15; + gptObjectInit(&GPTD15); +#endif + +#if STM32_GPT_USE_TIM16 + /* Driver initialization.*/ + GPTD16.tim = STM32_TIM16; + gptObjectInit(&GPTD16); +#endif + +#if STM32_GPT_USE_TIM17 + /* Driver initialization.*/ + GPTD17.tim = STM32_TIM17; + gptObjectInit(&GPTD17); +#endif + +#if STM32_GPT_USE_TIM21 + /* Driver initialization.*/ + GPTD21.tim = STM32_TIM21; + gptObjectInit(&GPTD21); +#endif + +#if STM32_GPT_USE_TIM22 + /* Driver initialization.*/ + GPTD22.tim = STM32_TIM22; + gptObjectInit(&GPTD22); +#endif +} + +/** + * @brief Configures and activates the GPT peripheral. + * + * @param[in] gptp pointer to the @p GPTDriver object + * + * @notapi + */ +void gpt_lld_start(GPTDriver *gptp) { + uint16_t psc; + + if (gptp->state == GPT_STOP) { + /* Clock activation.*/ +#if STM32_GPT_USE_TIM1 + if (&GPTD1 == gptp) { + rccEnableTIM1(true); + rccResetTIM1(); +#if !defined(STM32_TIM1_SUPPRESS_ISR) + nvicEnableVector(STM32_TIM1_UP_NUMBER, STM32_GPT_TIM1_IRQ_PRIORITY); +#endif +#if defined(STM32_TIM1CLK) + gptp->clock = STM32_TIM1CLK; +#else + gptp->clock = STM32_TIMCLK2; +#endif + } +#endif + +#if STM32_GPT_USE_TIM2 + if (&GPTD2 == gptp) { + rccEnableTIM2(true); + rccResetTIM2(); +#if !defined(STM32_TIM2_SUPPRESS_ISR) + nvicEnableVector(STM32_TIM2_NUMBER, STM32_GPT_TIM2_IRQ_PRIORITY); +#endif +#if defined(STM32_TIM2CLK) + gptp->clock = STM32_TIM2CLK; +#else + gptp->clock = STM32_TIMCLK1; +#endif + } +#endif + +#if STM32_GPT_USE_TIM3 + if (&GPTD3 == gptp) { + rccEnableTIM3(true); + rccResetTIM3(); +#if !defined(STM32_TIM3_SUPPRESS_ISR) + nvicEnableVector(STM32_TIM3_NUMBER, STM32_GPT_TIM3_IRQ_PRIORITY); +#endif +#if defined(STM32_TIM3CLK) + gptp->clock = STM32_TIM3CLK; +#else + gptp->clock = STM32_TIMCLK1; +#endif + } +#endif + +#if STM32_GPT_USE_TIM4 + if (&GPTD4 == gptp) { + rccEnableTIM4(true); + rccResetTIM4(); +#if !defined(STM32_TIM4_SUPPRESS_ISR) + nvicEnableVector(STM32_TIM4_NUMBER, STM32_GPT_TIM4_IRQ_PRIORITY); +#endif +#if defined(STM32_TIM4CLK) + gptp->clock = STM32_TIM4CLK; +#else + gptp->clock = STM32_TIMCLK1; +#endif + } +#endif + +#if STM32_GPT_USE_TIM5 + if (&GPTD5 == gptp) { + rccEnableTIM5(true); + rccResetTIM5(); +#if !defined(STM32_TIM5_SUPPRESS_ISR) + nvicEnableVector(STM32_TIM5_NUMBER, STM32_GPT_TIM5_IRQ_PRIORITY); +#endif +#if defined(STM32_TIM5CLK) + gptp->clock = STM32_TIM5CLK; +#else + gptp->clock = STM32_TIMCLK1; +#endif + } +#endif + +#if STM32_GPT_USE_TIM6 + if (&GPTD6 == gptp) { + rccEnableTIM6(true); + rccResetTIM6(); +#if !defined(STM32_TIM6_SUPPRESS_ISR) + nvicEnableVector(STM32_TIM6_NUMBER, STM32_GPT_TIM6_IRQ_PRIORITY); +#endif +#if defined(STM32_TIM6CLK) + gptp->clock = STM32_TIM6CLK; +#else + gptp->clock = STM32_TIMCLK1; +#endif + } +#endif + +#if STM32_GPT_USE_TIM7 + if (&GPTD7 == gptp) { + rccEnableTIM7(true); + rccResetTIM7(); +#if !defined(STM32_TIM7_SUPPRESS_ISR) + nvicEnableVector(STM32_TIM7_NUMBER, STM32_GPT_TIM7_IRQ_PRIORITY); +#endif +#if defined(STM32_TIM7CLK) + gptp->clock = STM32_TIM7CLK; +#else + gptp->clock = STM32_TIMCLK1; +#endif + } +#endif + +#if STM32_GPT_USE_TIM8 + if (&GPTD8 == gptp) { + rccEnableTIM8(true); + rccResetTIM8(); +#if !defined(STM32_TIM8_SUPPRESS_ISR) + nvicEnableVector(STM32_TIM8_UP_NUMBER, STM32_GPT_TIM8_IRQ_PRIORITY); +#endif +#if defined(STM32_TIM8CLK) + gptp->clock = STM32_TIM8CLK; +#else + gptp->clock = STM32_TIMCLK2; +#endif + } +#endif + +#if STM32_GPT_USE_TIM9 + if (&GPTD9 == gptp) { + rccEnableTIM9(true); + rccResetTIM9(); +#if !defined(STM32_TIM9_SUPPRESS_ISR) + nvicEnableVector(STM32_TIM9_NUMBER, STM32_GPT_TIM9_IRQ_PRIORITY); +#endif +#if defined(STM32_TIM9CLK) + gptp->clock = STM32_TIM9CLK; +#else + gptp->clock = STM32_TIMCLK2; +#endif + } +#endif + +#if STM32_GPT_USE_TIM10 + if (&GPTD10 == gptp) { + rccEnableTIM10(true); + rccResetTIM10(); +#if !defined(STM32_TIM10_SUPPRESS_ISR) + nvicEnableVector(STM32_TIM10_NUMBER, STM32_GPT_TIM10_IRQ_PRIORITY); +#endif +#if defined(STM32_TIM10CLK) + gptp->clock = STM32_TIM10CLK; +#else + gptp->clock = STM32_TIMCLK2; +#endif + } +#endif + +#if STM32_GPT_USE_TIM11 + if (&GPTD11 == gptp) { + rccEnableTIM11(true); + rccResetTIM11(); +#if !defined(STM32_TIM11_SUPPRESS_ISR) + nvicEnableVector(STM32_TIM11_NUMBER, STM32_GPT_TIM11_IRQ_PRIORITY); +#endif +#if defined(STM32_TIM11CLK) + gptp->clock = STM32_TIM11CLK; +#else + gptp->clock = STM32_TIMCLK2; +#endif + } +#endif + +#if STM32_GPT_USE_TIM12 + if (&GPTD12 == gptp) { + rccEnableTIM12(true); + rccResetTIM12(); +#if !defined(STM32_TIM12_SUPPRESS_ISR) + nvicEnableVector(STM32_TIM12_NUMBER, STM32_GPT_TIM12_IRQ_PRIORITY); +#endif +#if defined(STM32_TIM12CLK) + gptp->clock = STM32_TIM12CLK; +#else + gptp->clock = STM32_TIMCLK1; +#endif + } +#endif + +#if STM32_GPT_USE_TIM13 + if (&GPTD13 == gptp) { + rccEnableTIM13(true); + rccResetTIM13(); +#if !defined(STM32_TIM13_SUPPRESS_ISR) + nvicEnableVector(STM32_TIM13_NUMBER, STM32_GPT_TIM13_IRQ_PRIORITY); +#endif +#if defined(STM32_TIM13CLK) + gptp->clock = STM32_TIM13CLK; +#else + gptp->clock = STM32_TIMCLK1; +#endif + } +#endif + +#if STM32_GPT_USE_TIM14 + if (&GPTD14 == gptp) { + rccEnableTIM14(true); + rccResetTIM14(); +#if !defined(STM32_TIM14_SUPPRESS_ISR) + nvicEnableVector(STM32_TIM14_NUMBER, STM32_GPT_TIM14_IRQ_PRIORITY); +#endif +#if defined(STM32_TIM14CLK) + gptp->clock = STM32_TIM14CLK; +#else + gptp->clock = STM32_TIMCLK1; +#endif + } +#endif + +#if STM32_GPT_USE_TIM15 + if (&GPTD15 == gptp) { + rccEnableTIM15(true); + rccResetTIM15(); +#if defined(STM32_TIM15CLK) + gptp->clock = STM32_TIM15CLK; +#else + gptp->clock = STM32_TIMCLK2; +#endif + } +#endif + +#if STM32_GPT_USE_TIM16 + if (&GPTD16 == gptp) { + rccEnableTIM16(true); + rccResetTIM16(); +#if defined(STM32_TIM16CLK) + gptp->clock = STM32_TIM16CLK; +#else + gptp->clock = STM32_TIMCLK2; +#endif + } +#endif + +#if STM32_GPT_USE_TIM17 + if (&GPTD17 == gptp) { + rccEnableTIM17(true); + rccResetTIM17(); +#if defined(STM32_TIM17CLK) + gptp->clock = STM32_TIM17CLK; +#else + gptp->clock = STM32_TIMCLK2; +#endif + } +#endif + +#if STM32_GPT_USE_TIM21 + if (&GPTD21 == gptp) { + rccEnableTIM21(true); + rccResetTIM21(); +#if !defined(STM32_TIM21_SUPPRESS_ISR) + nvicEnableVector(STM32_TIM21_NUMBER, STM32_GPT_TIM21_IRQ_PRIORITY); +#endif +#if defined(STM32_TIM21CLK) + gptp->clock = STM32_TIM21CLK; +#else + gptp->clock = STM32_TIMCLK1; +#endif + } +#endif + +#if STM32_GPT_USE_TIM22 + if (&GPTD22 == gptp) { + rccEnableTIM22(true); + rccResetTIM22(); +#if !defined(STM32_TIM22_SUPPRESS_ISR) + nvicEnableVector(STM32_TIM22_NUMBER, STM32_GPT_TIM22_IRQ_PRIORITY); +#endif +#if defined(STM32_TIM22CLK) + gptp->clock = STM32_TIM22CLK; +#else + gptp->clock = STM32_TIMCLK1; +#endif + } +#endif + } + + /* Prescaler value calculation.*/ + psc = (uint16_t)((gptp->clock / gptp->config->frequency) - 1); + osalDbgAssert(((uint32_t)(psc + 1) * gptp->config->frequency) == gptp->clock, + "invalid frequency"); + + /* Timer configuration.*/ + gptp->tim->CR1 = 0U; /* Initially stopped. */ + gptp->tim->CR2 = gptp->config->cr2; + gptp->tim->PSC = psc; /* Prescaler value. */ + gptp->tim->SR = 0U; /* Clear pending IRQs. */ + gptp->tim->DIER = gptp->config->dier & /* DMA-related DIER bits. */ + ~STM32_TIM_DIER_IRQ_MASK; +} + +/** + * @brief Deactivates the GPT peripheral. + * + * @param[in] gptp pointer to the @p GPTDriver object + * + * @notapi + */ +void gpt_lld_stop(GPTDriver *gptp) { + + if (gptp->state == GPT_READY) { + gptp->tim->CR1 = 0U; /* Timer disabled. */ + gptp->tim->DIER = 0U; /* All IRQs disabled. */ + gptp->tim->SR = 0U; /* Clear pending IRQs. */ + +#if STM32_GPT_USE_TIM1 + if (&GPTD1 == gptp) { +#if !defined(STM32_TIM1_SUPPRESS_ISR) + nvicDisableVector(STM32_TIM1_UP_NUMBER); +#endif + rccDisableTIM1(); + } +#endif + +#if STM32_GPT_USE_TIM2 + if (&GPTD2 == gptp) { +#if !defined(STM32_TIM2_SUPPRESS_ISR) + nvicDisableVector(STM32_TIM2_NUMBER); +#endif + rccDisableTIM2(); + } +#endif + +#if STM32_GPT_USE_TIM3 + if (&GPTD3 == gptp) { +#if !defined(STM32_TIM3_SUPPRESS_ISR) + nvicDisableVector(STM32_TIM3_NUMBER); +#endif + rccDisableTIM3(); + } +#endif + +#if STM32_GPT_USE_TIM4 + if (&GPTD4 == gptp) { +#if !defined(STM32_TIM4_SUPPRESS_ISR) + nvicDisableVector(STM32_TIM4_NUMBER); +#endif + rccDisableTIM4(); + } +#endif + +#if STM32_GPT_USE_TIM5 + if (&GPTD5 == gptp) { +#if !defined(STM32_TIM5_SUPPRESS_ISR) + nvicDisableVector(STM32_TIM5_NUMBER); +#endif + rccDisableTIM5(); + } +#endif + +#if STM32_GPT_USE_TIM6 + if (&GPTD6 == gptp) { +#if !defined(STM32_TIM6_SUPPRESS_ISR) + nvicDisableVector(STM32_TIM6_NUMBER); +#endif + rccDisableTIM6(); + } +#endif + +#if STM32_GPT_USE_TIM7 + if (&GPTD7 == gptp) { +#if !defined(STM32_TIM7_SUPPRESS_ISR) + nvicDisableVector(STM32_TIM7_NUMBER); +#endif + rccDisableTIM7(); + } +#endif + +#if STM32_GPT_USE_TIM8 + if (&GPTD8 == gptp) { +#if !defined(STM32_TIM8_SUPPRESS_ISR) + nvicDisableVector(STM32_TIM8_UP_NUMBER); +#endif + rccDisableTIM8(); + } +#endif + +#if STM32_GPT_USE_TIM9 + if (&GPTD9 == gptp) { +#if !defined(STM32_TIM9_SUPPRESS_ISR) + nvicDisableVector(STM32_TIM9_NUMBER); +#endif + rccDisableTIM9(); + } +#endif + +#if STM32_GPT_USE_TIM10 + if (&GPTD10 == gptp) { +#if !defined(STM32_TIM10_SUPPRESS_ISR) + nvicDisableVector(STM32_TIM10_NUMBER); +#endif + rccDisableTIM10(); + } +#endif + +#if STM32_GPT_USE_TIM11 + if (&GPTD11 == gptp) { +#if !defined(STM32_TIM11_SUPPRESS_ISR) + nvicDisableVector(STM32_TIM11_NUMBER); +#endif + rccDisableTIM11(); + } +#endif + +#if STM32_GPT_USE_TIM12 + if (&GPTD12 == gptp) { +#if !defined(STM32_TIM12_SUPPRESS_ISR) + nvicDisableVector(STM32_TIM12_NUMBER); +#endif + rccDisableTIM12(); + } +#endif + +#if STM32_GPT_USE_TIM13 + if (&GPTD13 == gptp) { +#if !defined(STM32_TIM13_SUPPRESS_ISR) + nvicDisableVector(STM32_TIM13_NUMBER); +#endif + rccDisableTIM13(); + } +#endif + +#if STM32_GPT_USE_TIM14 + if (&GPTD14 == gptp) { +#if !defined(STM32_TIM14_SUPPRESS_ISR) + nvicDisableVector(STM32_TIM14_NUMBER); +#endif + rccDisableTIM14(); + } +#endif + +#if STM32_GPT_USE_TIM15 + if (&GPTD15 == gptp) { + rccDisableTIM15(); + } +#endif + +#if STM32_GPT_USE_TIM16 + if (&GPTD16 == gptp) { + rccDisableTIM16(); + } +#endif + +#if STM32_GPT_USE_TIM17 + if (&GPTD17 == gptp) { + rccDisableTIM17(); + } +#endif + +#if STM32_GPT_USE_TIM21 + if (&GPTD21 == gptp) { +#if !defined(STM32_TIM21_SUPPRESS_ISR) + nvicDisableVector(STM32_TIM21_NUMBER); +#endif + rccDisableTIM21(); + } +#endif + +#if STM32_GPT_USE_TIM22 + if (&GPTD22 == gptp) { +#if !defined(STM32_TIM22_SUPPRESS_ISR) + nvicDisableVector(STM32_TIM22_NUMBER); +#endif + rccDisableTIM22(); + } +#endif + } +} + +/** + * @brief Starts the timer in continuous mode. + * + * @param[in] gptp pointer to the @p GPTDriver object + * @param[in] interval period in ticks + * + * @notapi + */ +void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) { + + gptp->tim->ARR = (uint32_t)(interval - 1U); /* Time constant. */ + gptp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */ + gptp->tim->CNT = 0U; /* Reset counter. */ + + /* NOTE: After generating the UG event it takes several clock cycles before + SR bit 0 goes to 1. This is why the clearing of CNT has been inserted + before the clearing of SR, to give it some time.*/ + gptp->tim->SR = 0U; /* Clear pending IRQs. */ + if (NULL != gptp->config->callback) + gptp->tim->DIER |= STM32_TIM_DIER_UIE; /* Update Event IRQ enabled.*/ + gptp->tim->CR1 = STM32_TIM_CR1_ARPE | STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN; +} + +/** + * @brief Stops the timer. + * + * @param[in] gptp pointer to the @p GPTDriver object + * + * @notapi + */ +void gpt_lld_stop_timer(GPTDriver *gptp) { + + gptp->tim->CR1 = 0U; /* Initially stopped. */ + gptp->tim->SR = 0U; /* Clear pending IRQs. */ + + /* All interrupts disabled.*/ + gptp->tim->DIER &= ~STM32_TIM_DIER_IRQ_MASK; +} + +/** + * @brief Starts the timer in one shot mode and waits for completion. + * @details This function specifically polls the timer waiting for completion + * in order to not have extra delays caused by interrupt servicing, + * this function is only recommended for short delays. + * + * @param[in] gptp pointer to the @p GPTDriver object + * @param[in] interval time interval in ticks + * + * @notapi + */ +void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) { + + gptp->tim->CR1 = STM32_TIM_CR1_UDIS; /* Immediate update. */ + gptp->tim->ARR = (uint32_t)(interval - 1U); /* Time constant. */ + gptp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */ + gptp->tim->SR = 0U; /* Clear pending IRQs. */ + gptp->tim->CR1 = STM32_TIM_CR1_OPM | STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN; + while (!(gptp->tim->SR & STM32_TIM_SR_UIF)) + ; + gptp->tim->SR = 0U; /* Clear pending IRQs. */ +} + +/** + * @brief Shared IRQ handler. + * + * @param[in] gptp pointer to a @p GPTDriver object + * + * @notapi + */ +void gpt_lld_serve_interrupt(GPTDriver *gptp) { + uint32_t sr; + + sr = gptp->tim->SR; + sr &= gptp->tim->DIER & STM32_TIM_DIER_IRQ_MASK; + gptp->tim->SR = ~sr; + if ((sr & STM32_TIM_SR_UIF) != 0) { + _gpt_isr_invoke_cb(gptp); + } +} + +#endif /* HAL_USE_GPT */ + +/** @} */ diff --git a/readme.txt b/readme.txt index 5d6e72cd93..a7fdc73c50 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed problem in STM32 gpt_lld_polled_delay() implementation (bug #1241). - FIX: Fixed invalid delay loop in STM32G0/WL ADCv5 driver (bug #1240). - FIX: Fixed missing clock enables for some GPIOS on some STM32L4s (bug #1237). - FIX: Fixed old bugs in serial driver header (bug #1236). From 4a52632ed133800d05cffa1a811cd8fa48d8a6ef Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 20 Nov 2022 08:57:40 +0000 Subject: [PATCH 07/53] Fixed bug #1242. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@15843 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/STM32L4xx/stm32_registry.h | 2 +- readme.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/os/hal/ports/STM32/STM32L4xx/stm32_registry.h b/os/hal/ports/STM32/STM32L4xx/stm32_registry.h index 22a4dc1e7a..feddac2c87 100644 --- a/os/hal/ports/STM32/STM32L4xx/stm32_registry.h +++ b/os/hal/ports/STM32/STM32L4xx/stm32_registry.h @@ -1070,7 +1070,7 @@ #if defined(STM32L496xx) || defined(STM32L4A6xx) /* Clock attributes.*/ -#define STM32_CLOCK_HAS_HSI48 FALSE +#define STM32_CLOCK_HAS_HSI48 TRUE /* ADC attributes.*/ #define STM32_HAS_ADC1 TRUE diff --git a/readme.txt b/readme.txt index a7fdc73c50..f8580183fc 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed HSI48 not enabled for STM32L496/​4A6 (bug #1242). - FIX: Fixed problem in STM32 gpt_lld_polled_delay() implementation (bug #1241). - FIX: Fixed invalid delay loop in STM32G0/WL ADCv5 driver (bug #1240). - FIX: Fixed missing clock enables for some GPIOS on some STM32L4s (bug #1237). From 7cc8f15f52385ed15f9d3934d2cce4c19fd0ab76 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 20 Nov 2022 09:02:49 +0000 Subject: [PATCH 08/53] Fixed bug #1243. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@15844 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c | 2 +- readme.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c index 76f7c320b8..43ad6ddce7 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c +++ b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c @@ -897,7 +897,7 @@ void usb_lld_stop(USBDriver *usbp) { nvicDisableVector(STM32_OTG2_NUMBER); rccDisableOTG_HS(); #if defined(BOARD_OTG2_USES_ULPI) - rccDisableOTG_HSULPI() + rccDisableOTG_HSULPI(); #endif } #endif diff --git a/readme.txt b/readme.txt index f8580183fc..4c077d0cbc 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed missing semicolon in STM32 OTGv1 driver (bug #1243). - FIX: Fixed HSI48 not enabled for STM32L496/​4A6 (bug #1242). - FIX: Fixed problem in STM32 gpt_lld_polled_delay() implementation (bug #1241). - FIX: Fixed invalid delay loop in STM32G0/WL ADCv5 driver (bug #1240). From 9765a0c27580deefb46dd7785fb22b4c3115581e Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Fri, 25 Nov 2022 16:27:07 +0000 Subject: [PATCH 09/53] Improved WolfSSL bindings. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@15852 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/various/wolfssl_bindings/wolfssl_chibios.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/os/various/wolfssl_bindings/wolfssl_chibios.c b/os/various/wolfssl_bindings/wolfssl_chibios.c index 4b6cff314a..ee982bb63e 100644 --- a/os/various/wolfssl_bindings/wolfssl_chibios.c +++ b/os/various/wolfssl_bindings/wolfssl_chibios.c @@ -123,8 +123,16 @@ int wolfssl_send_cb(WOLFSSL* ssl, char *buf, int sz, void *ctx) err = netconn_write(sk->conn, buf, sz, NETCONN_COPY); if (err == ERR_OK) return sz; + else if (err == ERR_CLSD || err == ERR_ABRT || err == ERR_CONN) + return WOLFSSL_CBIO_ERR_CONN_CLOSE; + else if (err == ERR_RST) + return WOLFSSL_CBIO_ERR_CONN_RST; + else if (err == ERR_MEM) + return WOLFSSL_CBIO_ERR_GENERAL; + else if (err == ERR_TIMEOUT) + return WOLFSSL_CBIO_ERR_TIMEOUT; else - return -2; + return WOLFSSL_CBIO_ERR_WANT_WRITE; } @@ -174,6 +182,14 @@ int wolfssl_recv_cb(WOLFSSL *ssl, char *buf, int sz, void *ctx) netbuf_delete(inbuf); return sz; } + else if (err == ERR_CLSD || err == ERR_ABRT || err == ERR_CONN) + return WOLFSSL_CBIO_ERR_CONN_CLOSE; + else if (err == ERR_RST) + return WOLFSSL_CBIO_ERR_CONN_RST; + else if (err == ERR_MEM) + return WOLFSSL_CBIO_ERR_GENERAL; + else if (err == ERR_TIMEOUT) + return WOLFSSL_CBIO_ERR_TIMEOUT; else return 0; //return WOLFSSL_CBIO_ERR_WANT_READ; From 6cc1119cc2026250af864f42f57794220d78cbe8 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Thu, 8 Dec 2022 09:06:27 +0000 Subject: [PATCH 10/53] Fixed bug #1244. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@15857 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- readme.txt | 1 + testhal/STM32/multi/ADC/make/stm32l053r8_nucleo64.make | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/readme.txt b/readme.txt index 4c077d0cbc..6918531eb2 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed wrong path in STM32L053 ADC demo makefile (bug #1244). - FIX: Fixed missing semicolon in STM32 OTGv1 driver (bug #1243). - FIX: Fixed HSI48 not enabled for STM32L496/​4A6 (bug #1242). - FIX: Fixed problem in STM32 gpt_lld_polled_delay() implementation (bug #1241). diff --git a/testhal/STM32/multi/ADC/make/stm32l053r8_nucleo64.make b/testhal/STM32/multi/ADC/make/stm32l053r8_nucleo64.make index e340c4126a..353039098f 100644 --- a/testhal/STM32/multi/ADC/make/stm32l053r8_nucleo64.make +++ b/testhal/STM32/multi/ADC/make/stm32l053r8_nucleo64.make @@ -91,7 +91,7 @@ MCU = cortex-m0 # Imported source files and paths. CHIBIOS := ../../../.. CONFDIR := ./cfg/stm32l053r8_nucleo64 -BUILDDIR := ./build/stm32l063r8_nucleo64 +BUILDDIR := ./build/stm32l053r8_nucleo64 DEPDIR := ./.dep/stm32l053r8_nucleo64 # Licensing files. From 956e949522702a0ab2875070f815f11a98901f91 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Thu, 8 Dec 2022 09:56:12 +0000 Subject: [PATCH 11/53] Fixed bug #1245. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@15858 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- .../STM32/RT-STM32L053-DISCOVERY/cfg/mcuconf.h | 5 +++++ .../STM32/RT-STM32L053R8-NUCLEO64/cfg/mcuconf.h | 5 +++++ os/hal/ports/STM32/STM32L0xx/stm32_registry.h | 17 ++++++++--------- readme.txt | 1 + testhal/STM32/STM32L0xx/SPI/mcuconf.h | 5 +++++ .../ADC/cfg/stm32l053r8_nucleo64/mcuconf.h | 5 +++++ .../multi/PAL/cfg/stm32l053_discovery/mcuconf.h | 5 +++++ .../multi/RTC/cfg/stm32l053_discovery/mcuconf.h | 5 +++++ .../conf/mcuconf_stm32l05xxx/mcuconf.h.ftl | 7 ++++++- .../conf/mcuconf_stm32l07xxx/mcuconf.h.ftl | 4 ++-- 10 files changed, 47 insertions(+), 12 deletions(-) diff --git a/demos/STM32/RT-STM32L053-DISCOVERY/cfg/mcuconf.h b/demos/STM32/RT-STM32L053-DISCOVERY/cfg/mcuconf.h index c479fd8566..72708ae446 100644 --- a/demos/STM32/RT-STM32L053-DISCOVERY/cfg/mcuconf.h +++ b/demos/STM32/RT-STM32L053-DISCOVERY/cfg/mcuconf.h @@ -125,16 +125,21 @@ */ #define STM32_I2C_USE_I2C1 FALSE #define STM32_I2C_USE_I2C2 FALSE +#define STM32_I2C_USE_I2C3 FALSE #define STM32_I2C_BUSY_TIMEOUT 50 #define STM32_I2C_I2C1_IRQ_PRIORITY 3 #define STM32_I2C_I2C2_IRQ_PRIORITY 3 +#define STM32_I2C_I2C3_IRQ_PRIORITY 3 #define STM32_I2C_USE_DMA TRUE #define STM32_I2C_I2C1_DMA_PRIORITY 1 #define STM32_I2C_I2C2_DMA_PRIORITY 1 +#define STM32_I2C_I2C3_DMA_PRIORITY 1 #define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) #define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) #define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) #define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) #define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") /* diff --git a/demos/STM32/RT-STM32L053R8-NUCLEO64/cfg/mcuconf.h b/demos/STM32/RT-STM32L053R8-NUCLEO64/cfg/mcuconf.h index 20ec824ae6..ecbaf0c6b9 100644 --- a/demos/STM32/RT-STM32L053R8-NUCLEO64/cfg/mcuconf.h +++ b/demos/STM32/RT-STM32L053R8-NUCLEO64/cfg/mcuconf.h @@ -125,16 +125,21 @@ */ #define STM32_I2C_USE_I2C1 FALSE #define STM32_I2C_USE_I2C2 FALSE +#define STM32_I2C_USE_I2C3 FALSE #define STM32_I2C_BUSY_TIMEOUT 50 #define STM32_I2C_I2C1_IRQ_PRIORITY 3 #define STM32_I2C_I2C2_IRQ_PRIORITY 3 +#define STM32_I2C_I2C3_IRQ_PRIORITY 3 #define STM32_I2C_USE_DMA TRUE #define STM32_I2C_I2C1_DMA_PRIORITY 1 #define STM32_I2C_I2C2_DMA_PRIORITY 1 +#define STM32_I2C_I2C3_DMA_PRIORITY 1 #define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) #define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) #define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) #define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) #define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") /* diff --git a/os/hal/ports/STM32/STM32L0xx/stm32_registry.h b/os/hal/ports/STM32/STM32L0xx/stm32_registry.h index 7784ffc4c4..1dc62b2d54 100644 --- a/os/hal/ports/STM32/STM32L0xx/stm32_registry.h +++ b/os/hal/ports/STM32/STM32L0xx/stm32_registry.h @@ -574,7 +574,6 @@ #define STM32_HAS_CRC TRUE #define STM32_CRC_PROGRAMMABLE TRUE - /*===========================================================================*/ /* STM32L052xx, STM32L062xx, STM32L053xx, STM32L063xx. */ /*===========================================================================*/ @@ -853,10 +852,10 @@ #define STM32_HAS_I2C3 TRUE #define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\ STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_I2C3_RX_DMA_CHN 0x00E0E000 -#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\ - STM32_DMA_STREAM_ID_MSK(1, 6)) -#define STM32_I2C3_TX_DMA_CHN 0x0E0E0000 +#define STM32_I2C3_RX_DMA_CHN 0x000E0E00 +#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ + STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_I2C3_TX_DMA_CHN 0x0000E0E0 /* SDIO attributes.*/ #define STM32_HAS_SDIO FALSE @@ -1071,10 +1070,10 @@ #define STM32_HAS_I2C3 TRUE #define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\ STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_I2C3_RX_DMA_CHN 0x00E0E000 -#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\ - STM32_DMA_STREAM_ID_MSK(1, 6)) -#define STM32_I2C3_TX_DMA_CHN 0x0E0E0000 +#define STM32_I2C3_RX_DMA_CHN 0x000E0E00 +#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ + STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_I2C3_TX_DMA_CHN 0x0000E0E0 /* SDIO attributes.*/ #define STM32_HAS_SDIO FALSE diff --git a/readme.txt b/readme.txt index 6918531eb2..5a1e6dfc8a 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed wrong DMA definitions for STM32L0xx I2C3 peripheral (bug #1245). - FIX: Fixed wrong path in STM32L053 ADC demo makefile (bug #1244). - FIX: Fixed missing semicolon in STM32 OTGv1 driver (bug #1243). - FIX: Fixed HSI48 not enabled for STM32L496/​4A6 (bug #1242). diff --git a/testhal/STM32/STM32L0xx/SPI/mcuconf.h b/testhal/STM32/STM32L0xx/SPI/mcuconf.h index 3ab05cad1f..8ffd458d43 100644 --- a/testhal/STM32/STM32L0xx/SPI/mcuconf.h +++ b/testhal/STM32/STM32L0xx/SPI/mcuconf.h @@ -125,16 +125,21 @@ */ #define STM32_I2C_USE_I2C1 FALSE #define STM32_I2C_USE_I2C2 FALSE +#define STM32_I2C_USE_I2C3 FALSE #define STM32_I2C_BUSY_TIMEOUT 50 #define STM32_I2C_I2C1_IRQ_PRIORITY 3 #define STM32_I2C_I2C2_IRQ_PRIORITY 3 +#define STM32_I2C_I2C3_IRQ_PRIORITY 3 #define STM32_I2C_USE_DMA TRUE #define STM32_I2C_I2C1_DMA_PRIORITY 1 #define STM32_I2C_I2C2_DMA_PRIORITY 1 +#define STM32_I2C_I2C3_DMA_PRIORITY 1 #define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) #define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) #define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) #define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) #define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") /* diff --git a/testhal/STM32/multi/ADC/cfg/stm32l053r8_nucleo64/mcuconf.h b/testhal/STM32/multi/ADC/cfg/stm32l053r8_nucleo64/mcuconf.h index 8c9ca352e1..c13f90bb36 100644 --- a/testhal/STM32/multi/ADC/cfg/stm32l053r8_nucleo64/mcuconf.h +++ b/testhal/STM32/multi/ADC/cfg/stm32l053r8_nucleo64/mcuconf.h @@ -125,16 +125,21 @@ */ #define STM32_I2C_USE_I2C1 FALSE #define STM32_I2C_USE_I2C2 FALSE +#define STM32_I2C_USE_I2C3 FALSE #define STM32_I2C_BUSY_TIMEOUT 50 #define STM32_I2C_I2C1_IRQ_PRIORITY 3 #define STM32_I2C_I2C2_IRQ_PRIORITY 3 +#define STM32_I2C_I2C3_IRQ_PRIORITY 3 #define STM32_I2C_USE_DMA TRUE #define STM32_I2C_I2C1_DMA_PRIORITY 1 #define STM32_I2C_I2C2_DMA_PRIORITY 1 +#define STM32_I2C_I2C3_DMA_PRIORITY 1 #define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) #define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) #define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) #define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) #define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") /* diff --git a/testhal/STM32/multi/PAL/cfg/stm32l053_discovery/mcuconf.h b/testhal/STM32/multi/PAL/cfg/stm32l053_discovery/mcuconf.h index e0a250745c..90e6953fb8 100644 --- a/testhal/STM32/multi/PAL/cfg/stm32l053_discovery/mcuconf.h +++ b/testhal/STM32/multi/PAL/cfg/stm32l053_discovery/mcuconf.h @@ -125,16 +125,21 @@ */ #define STM32_I2C_USE_I2C1 FALSE #define STM32_I2C_USE_I2C2 FALSE +#define STM32_I2C_USE_I2C3 FALSE #define STM32_I2C_BUSY_TIMEOUT 50 #define STM32_I2C_I2C1_IRQ_PRIORITY 3 #define STM32_I2C_I2C2_IRQ_PRIORITY 3 +#define STM32_I2C_I2C3_IRQ_PRIORITY 3 #define STM32_I2C_USE_DMA TRUE #define STM32_I2C_I2C1_DMA_PRIORITY 1 #define STM32_I2C_I2C2_DMA_PRIORITY 1 +#define STM32_I2C_I2C3_DMA_PRIORITY 1 #define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) #define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) #define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) #define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) #define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") /* diff --git a/testhal/STM32/multi/RTC/cfg/stm32l053_discovery/mcuconf.h b/testhal/STM32/multi/RTC/cfg/stm32l053_discovery/mcuconf.h index e0a250745c..90e6953fb8 100644 --- a/testhal/STM32/multi/RTC/cfg/stm32l053_discovery/mcuconf.h +++ b/testhal/STM32/multi/RTC/cfg/stm32l053_discovery/mcuconf.h @@ -125,16 +125,21 @@ */ #define STM32_I2C_USE_I2C1 FALSE #define STM32_I2C_USE_I2C2 FALSE +#define STM32_I2C_USE_I2C3 FALSE #define STM32_I2C_BUSY_TIMEOUT 50 #define STM32_I2C_I2C1_IRQ_PRIORITY 3 #define STM32_I2C_I2C2_IRQ_PRIORITY 3 +#define STM32_I2C_I2C3_IRQ_PRIORITY 3 #define STM32_I2C_USE_DMA TRUE #define STM32_I2C_I2C1_DMA_PRIORITY 1 #define STM32_I2C_I2C2_DMA_PRIORITY 1 +#define STM32_I2C_I2C3_DMA_PRIORITY 1 #define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) #define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) #define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) #define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) #define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") /* diff --git a/tools/ftl/processors/conf/mcuconf_stm32l05xxx/mcuconf.h.ftl b/tools/ftl/processors/conf/mcuconf_stm32l05xxx/mcuconf.h.ftl index 673dbced0b..dca8718bcb 100644 --- a/tools/ftl/processors/conf/mcuconf_stm32l05xxx/mcuconf.h.ftl +++ b/tools/ftl/processors/conf/mcuconf_stm32l05xxx/mcuconf.h.ftl @@ -136,16 +136,21 @@ */ #define STM32_I2C_USE_I2C1 ${doc.STM32_I2C_USE_I2C1!"FALSE"} #define STM32_I2C_USE_I2C2 ${doc.STM32_I2C_USE_I2C2!"FALSE"} +#define STM32_I2C_USE_I2C3 ${doc.STM32_I2C_USE_I2C3!"FALSE"} #define STM32_I2C_BUSY_TIMEOUT ${doc.STM32_I2C_BUSY_TIMEOUT!"50"} #define STM32_I2C_I2C1_IRQ_PRIORITY ${doc.STM32_I2C_I2C1_IRQ_PRIORITY!"3"} #define STM32_I2C_I2C2_IRQ_PRIORITY ${doc.STM32_I2C_I2C2_IRQ_PRIORITY!"3"} +#define STM32_I2C_I2C3_IRQ_PRIORITY ${doc.STM32_I2C_I2C3_IRQ_PRIORITY!"3"} #define STM32_I2C_USE_DMA ${doc.STM32_I2C_USE_DMA!"TRUE"} #define STM32_I2C_I2C1_DMA_PRIORITY ${doc.STM32_I2C_I2C1_DMA_PRIORITY!"1"} #define STM32_I2C_I2C2_DMA_PRIORITY ${doc.STM32_I2C_I2C2_DMA_PRIORITY!"1"} +#define STM32_I2C_I2C3_DMA_PRIORITY ${doc.STM32_I2C_I2C3_DMA_PRIORITY!"1"} #define STM32_I2C_I2C1_RX_DMA_STREAM ${doc.STM32_I2C_I2C1_RX_DMA_STREAM!"STM32_DMA_STREAM_ID(1, 7)"} -#define STM32_I2C_I2C1_TX_DMA_STREAM ${doc.STM32_I2C_I2C1_TX_DMA_STREAM!"STM32_DMA_STREAM_ID(1, 2)"} +#define STM32_I2C_I2C1_TX_DMA_STREAM ${doc.STM32_I2C_I2C1_TX_DMA_STREAM!"STM32_DMA_STREAM_ID(1, 6)"} #define STM32_I2C_I2C2_RX_DMA_STREAM ${doc.STM32_I2C_I2C2_RX_DMA_STREAM!"STM32_DMA_STREAM_ID(1, 5)"} #define STM32_I2C_I2C2_TX_DMA_STREAM ${doc.STM32_I2C_I2C2_TX_DMA_STREAM!"STM32_DMA_STREAM_ID(1, 4)"} +#define STM32_I2C_I2C3_RX_DMA_STREAM ${doc.STM32_I2C_I2C3_RX_DMA_STREAM!"STM32_DMA_STREAM_ID(1, 3)"} +#define STM32_I2C_I2C3_TX_DMA_STREAM ${doc.STM32_I2C_I2C3_TX_DMA_STREAM!"STM32_DMA_STREAM_ID(1, 2)"} #define STM32_I2C_DMA_ERROR_HOOK(i2cp) ${doc.STM32_I2C_DMA_ERROR_HOOK!"osalSysHalt(\"DMA failure\")"} /* diff --git a/tools/ftl/processors/conf/mcuconf_stm32l07xxx/mcuconf.h.ftl b/tools/ftl/processors/conf/mcuconf_stm32l07xxx/mcuconf.h.ftl index 1d60a7611a..d470224432 100644 --- a/tools/ftl/processors/conf/mcuconf_stm32l07xxx/mcuconf.h.ftl +++ b/tools/ftl/processors/conf/mcuconf_stm32l07xxx/mcuconf.h.ftl @@ -155,11 +155,11 @@ #define STM32_I2C_I2C2_DMA_PRIORITY ${doc.STM32_I2C_I2C2_DMA_PRIORITY!"1"} #define STM32_I2C_I2C3_DMA_PRIORITY ${doc.STM32_I2C_I2C3_DMA_PRIORITY!"1"} #define STM32_I2C_I2C1_RX_DMA_STREAM ${doc.STM32_I2C_I2C1_RX_DMA_STREAM!"STM32_DMA_STREAM_ID(1, 7)"} -#define STM32_I2C_I2C1_TX_DMA_STREAM ${doc.STM32_I2C_I2C1_TX_DMA_STREAM!"STM32_DMA_STREAM_ID(1, 2)"} +#define STM32_I2C_I2C1_TX_DMA_STREAM ${doc.STM32_I2C_I2C1_TX_DMA_STREAM!"STM32_DMA_STREAM_ID(1, 6)"} #define STM32_I2C_I2C2_RX_DMA_STREAM ${doc.STM32_I2C_I2C2_RX_DMA_STREAM!"STM32_DMA_STREAM_ID(1, 5)"} #define STM32_I2C_I2C2_TX_DMA_STREAM ${doc.STM32_I2C_I2C2_TX_DMA_STREAM!"STM32_DMA_STREAM_ID(1, 4)"} #define STM32_I2C_I2C3_RX_DMA_STREAM ${doc.STM32_I2C_I2C3_RX_DMA_STREAM!"STM32_DMA_STREAM_ID(1, 3)"} -#define STM32_I2C_I2C3_TX_DMA_STREAM ${doc.STM32_I2C_I2C3_TX_DMA_STREAM!"STM32_DMA_STREAM_ID(1, 6)"} +#define STM32_I2C_I2C3_TX_DMA_STREAM ${doc.STM32_I2C_I2C3_TX_DMA_STREAM!"STM32_DMA_STREAM_ID(1, 2)"} #define STM32_I2C_DMA_ERROR_HOOK(i2cp) ${doc.STM32_I2C_DMA_ERROR_HOOK!"osalSysHalt(\"DMA failure\")"} /* From b4ccd4ff5c69331b71f4bcdf5ab1d51a4e896717 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Thu, 8 Dec 2022 10:08:22 +0000 Subject: [PATCH 12/53] Fixed bug #1246. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@15859 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/STM32L0xx/hal_lld.c | 2 +- readme.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/os/hal/ports/STM32/STM32L0xx/hal_lld.c b/os/hal/ports/STM32/STM32L0xx/hal_lld.c index 14b09e169b..64cd2ba35c 100644 --- a/os/hal/ports/STM32/STM32L0xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32L0xx/hal_lld.c @@ -99,7 +99,7 @@ void hal_lld_init(void) { /* Reset of all peripherals except those on IOP.*/ rccResetAHB(~RCC_AHBRSTR_MIFRST); rccResetAPB1(~RCC_APB1RSTR_PWRRST); - rccResetAPB2(~0); + rccResetAPB2(~RCC_APB2RSTR_SYSCFGRST); /* PWR clock enabled.*/ rccEnablePWRInterface(true); diff --git a/readme.txt b/readme.txt index 5a1e6dfc8a..b34f4f7034 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed wrong HSI48 support on STM32L0xx (bug #1246). - FIX: Fixed wrong DMA definitions for STM32L0xx I2C3 peripheral (bug #1245). - FIX: Fixed wrong path in STM32L053 ADC demo makefile (bug #1244). - FIX: Fixed missing semicolon in STM32 OTGv1 driver (bug #1243). From 03f0bd885125360a9033e7ea9d95e13c44a74f5d Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Fri, 9 Dec 2022 10:12:15 +0000 Subject: [PATCH 13/53] Fixed bug #1247. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@15868 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/STM32L1xx/hal_adc_lld.c | 588 ++++++++++----------- readme.txt | 1 + 2 files changed, 295 insertions(+), 294 deletions(-) diff --git a/os/hal/ports/STM32/STM32L1xx/hal_adc_lld.c b/os/hal/ports/STM32/STM32L1xx/hal_adc_lld.c index 913f974f19..78c0001867 100644 --- a/os/hal/ports/STM32/STM32L1xx/hal_adc_lld.c +++ b/os/hal/ports/STM32/STM32L1xx/hal_adc_lld.c @@ -1,294 +1,294 @@ -/* - ChibiOS - Copyright (C) 2006..2018 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 STM32L1xx/hal_adc_lld.c - * @brief STM32L1xx ADC subsystem low level driver source. - * - * @addtogroup ADC - * @{ - */ - -#include "hal.h" - -#if HAL_USE_ADC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** @brief ADC1 driver identifier.*/ -#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__) -ADCDriver ADCD1; -#endif - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief ADC DMA ISR service routine. - * - * @param[in] adcp pointer to the @p ADCDriver object - * @param[in] flags pre-shifted content of the ISR register - */ -static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { - - /* DMA errors handling.*/ - if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { - /* DMA, this could help only if the DMA tries to access an unmapped - address space or violates alignment rules.*/ - _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE); - } - else { - /* It is possible that the conversion group has already be reset by the - ADC error handler, in this case this interrupt is spurious.*/ - if (adcp->grpp != NULL) { - if ((flags & STM32_DMA_ISR_TCIF) != 0) { - /* Transfer complete processing.*/ - _adc_isr_full_code(adcp); - } - else if ((flags & STM32_DMA_ISR_HTIF) != 0) { - /* Half transfer processing.*/ - _adc_isr_half_code(adcp); - } - } - } -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__) -/** - * @brief ADC interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(Vector88) { - uint32_t sr; - - OSAL_IRQ_PROLOGUE(); - - sr = ADC1->SR; - ADC1->SR = 0; - /* Note, an overflow may occur after the conversion ended before the driver - is able to stop the ADC, this is why the DMA channel is checked too.*/ - if ((sr & ADC_SR_OVR) && (dmaStreamGetTransactionSize(ADCD1.dmastp) > 0)) { - /* ADC overflow condition, this could happen only if the DMA is unable - to read data fast enough.*/ - if (ADCD1.grpp != NULL) - _adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW); - } - /* CHTODO: Add here analog watchdog handling.*/ - - OSAL_IRQ_EPILOGUE(); -} -#endif - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level ADC driver initialization. - * - * @notapi - */ -void adc_lld_init(void) { - -#if STM32_ADC_USE_ADC1 - /* Driver initialization.*/ - adcObjectInit(&ADCD1); - ADCD1.adc = ADC1; - ADCD1.dmastp = NULL; - ADCD1.dmamode = STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) | - STM32_DMA_CR_DIR_P2M | - STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | - STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | - STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; -#endif - - /* The shared vector is initialized on driver initialization and never - disabled.*/ - nvicEnableVector(ADC1_IRQn, STM32_ADC_IRQ_PRIORITY); -} - -/** - * @brief Configures and activates the ADC peripheral. - * - * @param[in] adcp pointer to the @p ADCDriver object - * - * @notapi - */ -void adc_lld_start(ADCDriver *adcp) { - - /* If in stopped state then enables the ADC and DMA clocks.*/ - if (adcp->state == ADC_STOP) { -#if STM32_ADC_USE_ADC1 - if (&ADCD1 == adcp) { - adcp->dmastp = dmaStreamAllocI(STM32_DMA_STREAM_ID(1, 1), - STM32_ADC_ADC1_DMA_IRQ_PRIORITY, - (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, - (void *)adcp); - osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream"); - - dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR); - rccEnableADC1(true); - } -#endif /* STM32_ADC_USE_ADC1 */ - - ADC->CCR = (ADC->CCR & ADC_CCR_TSVREFE) | (STM32_ADC_ADCPRE << 16); - - /* ADC initial setup, starting the analog part here in order to reduce - the latency when starting a conversion.*/ - adcp->adc->CR1 = 0; - adcp->adc->CR2 = 0; - adcp->adc->CR2 = ADC_CR2_ADON; - } -} - -/** - * @brief Deactivates the ADC peripheral. - * - * @param[in] adcp pointer to the @p ADCDriver object - * - * @notapi - */ -void adc_lld_stop(ADCDriver *adcp) { - - /* If in ready state then disables the ADC clock and analog part.*/ - if (adcp->state == ADC_READY) { - dmaStreamFreeI(adcp->dmastp); - adcp->dmastp = NULL; - - adcp->adc->CR1 = 0; - adcp->adc->CR2 = 0; - -#if STM32_ADC_USE_ADC1 - if (&ADCD1 == adcp) - rccDisableADC1(); -#endif - } -} - -/** - * @brief Starts an ADC conversion. - * - * @param[in] adcp pointer to the @p ADCDriver object - * - * @notapi - */ -void adc_lld_start_conversion(ADCDriver *adcp) { - uint32_t mode; - uint32_t cr2; - const ADCConversionGroup *grpp = adcp->grpp; - - /* DMA setup.*/ - mode = adcp->dmamode; - if (grpp->circular) { - mode |= STM32_DMA_CR_CIRC; - if (adcp->depth > 1) { - /* If circular buffer depth > 1, then the half transfer interrupt - is enabled in order to allow streaming processing.*/ - mode |= STM32_DMA_CR_HTIE; - } - } - dmaStreamSetMemory0(adcp->dmastp, adcp->samples); - dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels * - (uint32_t)adcp->depth); - dmaStreamSetMode(adcp->dmastp, mode); - dmaStreamEnable(adcp->dmastp); - - /* ADC setup.*/ - adcp->adc->SR = 0; - adcp->adc->SMPR1 = grpp->smpr1; - adcp->adc->SMPR2 = grpp->smpr2; - adcp->adc->SMPR3 = grpp->smpr3; - adcp->adc->SQR1 = grpp->sqr1; - adcp->adc->SQR2 = grpp->sqr2; - adcp->adc->SQR3 = grpp->sqr3; - adcp->adc->SQR4 = grpp->sqr4; - adcp->adc->SQR5 = grpp->sqr5; - - /* ADC configuration and start.*/ - adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN; - - /* Enforcing the mandatory bits in CR2.*/ - cr2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON; - - /* The start method is different dependign if HW or SW triggered, the - start is performed using the method specified in the CR2 configuration.*/ - if ((cr2 & ADC_CR2_SWSTART) != 0) { - /* Initializing CR2 while keeping ADC_CR2_SWSTART at zero.*/ - adcp->adc->CR2 = (cr2 | ADC_CR2_CONT) & ~ADC_CR2_SWSTART; - - /* Finally enabling ADC_CR2_SWSTART.*/ - adcp->adc->CR2 = (cr2 | ADC_CR2_CONT); - } - else - adcp->adc->CR2 = cr2; -} - -/** - * @brief Stops an ongoing conversion. - * - * @param[in] adcp pointer to the @p ADCDriver object - * - * @notapi - */ -void adc_lld_stop_conversion(ADCDriver *adcp) { - - dmaStreamDisable(adcp->dmastp); - adcp->adc->CR1 = 0; - adcp->adc->CR2 = 0; - adcp->adc->CR2 = ADC_CR2_ADON; -} - -/** - * @brief Enables the TSVREFE bit. - * @details The TSVREFE bit is required in order to sample the internal - * temperature sensor and internal reference voltage. - * @note This is an STM32-only functionality. - */ -void adcSTM32EnableTSVREFE(void) { - - ADC->CCR |= ADC_CCR_TSVREFE; -} - -/** - * @brief Disables the TSVREFE bit. - * @details The TSVREFE bit is required in order to sample the internal - * temperature sensor and internal reference voltage. - * @note This is an STM32-only functionality. - */ -void adcSTM32DisableTSVREFE(void) { - - ADC->CCR &= ~ADC_CCR_TSVREFE; -} - -#endif /* HAL_USE_ADC */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 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 STM32L1xx/hal_adc_lld.c + * @brief STM32L1xx ADC subsystem low level driver source. + * + * @addtogroup ADC + * @{ + */ + +#include "hal.h" + +#if HAL_USE_ADC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief ADC1 driver identifier.*/ +#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__) +ADCDriver ADCD1; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief ADC DMA ISR service routine. + * + * @param[in] adcp pointer to the @p ADCDriver object + * @param[in] flags pre-shifted content of the ISR register + */ +static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { + + /* DMA errors handling.*/ + if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { + /* DMA, this could help only if the DMA tries to access an unmapped + address space or violates alignment rules.*/ + _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE); + } + else { + /* It is possible that the conversion group has already be reset by the + ADC error handler, in this case this interrupt is spurious.*/ + if (adcp->grpp != NULL) { + if ((flags & STM32_DMA_ISR_TCIF) != 0) { + /* Transfer complete processing.*/ + _adc_isr_full_code(adcp); + } + else if ((flags & STM32_DMA_ISR_HTIF) != 0) { + /* Half transfer processing.*/ + _adc_isr_half_code(adcp); + } + } + } +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__) +/** + * @brief ADC interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(Vector88) { + uint32_t sr; + + OSAL_IRQ_PROLOGUE(); + + sr = ADC1->SR; + ADC1->SR = 0; + /* Note, an overflow may occur after the conversion ended before the driver + is able to stop the ADC, this is why the DMA channel is checked too.*/ + if ((sr & ADC_SR_OVR) && (dmaStreamGetTransactionSize(ADCD1.dmastp) > 0)) { + /* ADC overflow condition, this could happen only if the DMA is unable + to read data fast enough.*/ + if (ADCD1.grpp != NULL) + _adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW); + } + /* CHTODO: Add here analog watchdog handling.*/ + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level ADC driver initialization. + * + * @notapi + */ +void adc_lld_init(void) { + +#if STM32_ADC_USE_ADC1 + /* Driver initialization.*/ + adcObjectInit(&ADCD1); + ADCD1.adc = ADC1; + ADCD1.dmastp = NULL; + ADCD1.dmamode = STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) | + STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | + STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | + STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; +#endif + + /* The shared vector is initialized on driver initialization and never + disabled.*/ + nvicEnableVector(ADC1_IRQn, STM32_ADC_IRQ_PRIORITY); +} + +/** + * @brief Configures and activates the ADC peripheral. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +void adc_lld_start(ADCDriver *adcp) { + + /* If in stopped state then enables the ADC and DMA clocks.*/ + if (adcp->state == ADC_STOP) { +#if STM32_ADC_USE_ADC1 + if (&ADCD1 == adcp) { + adcp->dmastp = dmaStreamAllocI(STM32_DMA_STREAM_ID(1, 1), + STM32_ADC_ADC1_DMA_IRQ_PRIORITY, + (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, + (void *)adcp); + osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream"); + + dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR); + rccEnableADC1(true); + } +#endif /* STM32_ADC_USE_ADC1 */ + + ADC->CCR = (ADC->CCR & ADC_CCR_TSVREFE) | (STM32_ADC_ADCPRE << 16); + + /* ADC initial setup, starting the analog part here in order to reduce + the latency when starting a conversion.*/ + adcp->adc->CR1 = 0; + adcp->adc->CR2 = 0; + adcp->adc->CR2 = ADC_CR2_ADON; + } +} + +/** + * @brief Deactivates the ADC peripheral. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +void adc_lld_stop(ADCDriver *adcp) { + + /* If in ready state then disables the ADC clock and analog part.*/ + if (adcp->state == ADC_READY) { + dmaStreamFreeI(adcp->dmastp); + adcp->dmastp = NULL; + + adcp->adc->CR1 = 0; + adcp->adc->CR2 = 0; + +#if STM32_ADC_USE_ADC1 + if (&ADCD1 == adcp) + rccDisableADC1(); +#endif + } +} + +/** + * @brief Starts an ADC conversion. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +void adc_lld_start_conversion(ADCDriver *adcp) { + uint32_t mode; + uint32_t cr2; + const ADCConversionGroup *grpp = adcp->grpp; + + /* DMA setup.*/ + mode = adcp->dmamode; + if (grpp->circular) { + mode |= STM32_DMA_CR_CIRC; + if (adcp->depth > 1) { + /* If circular buffer depth > 1, then the half transfer interrupt + is enabled in order to allow streaming processing.*/ + mode |= STM32_DMA_CR_HTIE; + } + } + dmaStreamSetMemory0(adcp->dmastp, adcp->samples); + dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels * + (uint32_t)adcp->depth); + dmaStreamSetMode(adcp->dmastp, mode); + dmaStreamEnable(adcp->dmastp); + + /* ADC setup.*/ + adcp->adc->SR = 0; + adcp->adc->SMPR1 = grpp->smpr1 | ADC_SQR1_NUM_CH(grpp->num_channels); + adcp->adc->SMPR2 = grpp->smpr2; + adcp->adc->SMPR3 = grpp->smpr3; + adcp->adc->SQR1 = grpp->sqr1; + adcp->adc->SQR2 = grpp->sqr2; + adcp->adc->SQR3 = grpp->sqr3; + adcp->adc->SQR4 = grpp->sqr4; + adcp->adc->SQR5 = grpp->sqr5; + + /* ADC configuration and start.*/ + adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN; + + /* Enforcing the mandatory bits in CR2.*/ + cr2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON; + + /* The start method is different dependign if HW or SW triggered, the + start is performed using the method specified in the CR2 configuration.*/ + if ((cr2 & ADC_CR2_SWSTART) != 0) { + /* Initializing CR2 while keeping ADC_CR2_SWSTART at zero.*/ + adcp->adc->CR2 = (cr2 | ADC_CR2_CONT) & ~ADC_CR2_SWSTART; + + /* Finally enabling ADC_CR2_SWSTART.*/ + adcp->adc->CR2 = (cr2 | ADC_CR2_CONT); + } + else + adcp->adc->CR2 = cr2; +} + +/** + * @brief Stops an ongoing conversion. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +void adc_lld_stop_conversion(ADCDriver *adcp) { + + dmaStreamDisable(adcp->dmastp); + adcp->adc->CR1 = 0; + adcp->adc->CR2 = 0; + adcp->adc->CR2 = ADC_CR2_ADON; +} + +/** + * @brief Enables the TSVREFE bit. + * @details The TSVREFE bit is required in order to sample the internal + * temperature sensor and internal reference voltage. + * @note This is an STM32-only functionality. + */ +void adcSTM32EnableTSVREFE(void) { + + ADC->CCR |= ADC_CCR_TSVREFE; +} + +/** + * @brief Disables the TSVREFE bit. + * @details The TSVREFE bit is required in order to sample the internal + * temperature sensor and internal reference voltage. + * @note This is an STM32-only functionality. + */ +void adcSTM32DisableTSVREFE(void) { + + ADC->CCR &= ~ADC_CCR_TSVREFE; +} + +#endif /* HAL_USE_ADC */ + +/** @} */ diff --git a/readme.txt b/readme.txt index b34f4f7034..155297f71e 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed wrong initialization in STM32L1xx ADC driver (bug #1247). - FIX: Fixed wrong HSI48 support on STM32L0xx (bug #1246). - FIX: Fixed wrong DMA definitions for STM32L0xx I2C3 peripheral (bug #1245). - FIX: Fixed wrong path in STM32L053 ADC demo makefile (bug #1244). From 28bd6db05fdf768279bcc5da44e012cc21ab4495 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 18 Dec 2022 09:12:16 +0000 Subject: [PATCH 14/53] Small fix to the shell. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@15879 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/various/shell/shell.c | 1209 +++++++++++++++++++------------------- 1 file changed, 605 insertions(+), 604 deletions(-) diff --git a/os/various/shell/shell.c b/os/various/shell/shell.c index 19db9aae38..35578e6ab6 100644 --- a/os/various/shell/shell.c +++ b/os/various/shell/shell.c @@ -1,604 +1,605 @@ -/* - ChibiOS - Copyright (C) 2006..2018 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 shell.c - * @brief Simple CLI shell code. - * - * @addtogroup SHELL - * @{ - */ - -#include - -#include "ch.h" -#include "hal.h" -#include "shell.h" -#include "shell_cmd.h" -#include "chprintf.h" - -/*===========================================================================*/ -/* Module local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module exported variables. */ -/*===========================================================================*/ - -#if !defined(_CHIBIOS_NIL_) || defined(__DOXYGEN__) -/** - * @brief Shell termination event source. - */ -event_source_t shell_terminated; -#endif - -/*===========================================================================*/ -/* Module local types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module local variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module local functions. */ -/*===========================================================================*/ - -static char *parse_arguments(char *str, char **saveptr) { - char *p; - - if (str != NULL) - *saveptr = str; - - p = *saveptr; - if (!p) { - return NULL; - } - - /* Skipping white space.*/ - p += strspn(p, " \t"); - - if (*p == '"') { - /* If an argument starts with a double quote then its delimiter is another - quote.*/ - p++; - *saveptr = strpbrk(p, "\""); - } - else { - /* The delimiter is white space.*/ - *saveptr = strpbrk(p, " \t"); - } - - /* Replacing the delimiter with a zero.*/ - if (*saveptr != NULL) { - *(*saveptr)++ = '\0'; - } - - return *p != '\0' ? p : NULL; -} - -static void list_commands(BaseSequentialStream *chp, const ShellCommand *scp) { - - while (scp->sc_name != NULL) { - chprintf(chp, "%s ", scp->sc_name); - scp++; - } -} - -static bool cmdexec(const ShellCommand *scp, BaseSequentialStream *chp, - char *name, int argc, char *argv[]) { - - while (scp->sc_name != NULL) { - if (strcmp(scp->sc_name, name) == 0) { - scp->sc_function(chp, argc, argv); - return false; - } - scp++; - } - return true; -} - -#if (SHELL_USE_HISTORY == TRUE) || defined(__DOXYGEN__) -static void del_histbuff_entry(ShellHistory *shp) { - int pos = shp->sh_beg + *(shp->sh_buffer + shp->sh_beg) + 1; - - if (pos >= shp->sh_size) - pos -= shp->sh_size; - - shp->sh_beg = pos; -} - -static bool is_histbuff_space(ShellHistory *shp, int length) { - - if (shp->sh_end >= shp->sh_beg) { - if (length < (shp->sh_size - (shp->sh_end - shp->sh_beg + 1))) - return true; - } - else { - if (length < (shp->sh_beg - shp->sh_end - 1)) - return true; - } - - return false; -} - -static void save_history(ShellHistory *shp, char *line, int length) { - - if (shp == NULL) - return; - - if (length > shp->sh_size - 2) - return; - - while ((*(line + length -1) == ' ') && (length > 0)) - length--; - - if (length <= 0) - return; - - while (!is_histbuff_space(shp, length)) - del_histbuff_entry(shp); - - if (length < shp->sh_size - shp->sh_end - 1) - memcpy(shp->sh_buffer + shp->sh_end + 1, line, length); - else { - /* - * Since there isn't enough room left at the end of the buffer, - * split the line to save up to the end of the buffer and then - * wrap back to the beginning of the buffer. - */ - int part_len = shp->sh_size - shp->sh_end - 1; - memcpy(shp->sh_buffer + shp->sh_end + 1, line, part_len); - memcpy(shp->sh_buffer, line + part_len, length - part_len); - } - - /* Save the length of the current line and move the buffer end pointer */ - *(shp->sh_buffer + shp->sh_end) = (char)length; - shp->sh_end += length + 1; - if (shp->sh_end >= shp->sh_size) - shp->sh_end -= shp->sh_size; - *(shp->sh_buffer + shp->sh_end) = 0; - shp->sh_cur = 0; -} - -static int get_history(ShellHistory *shp, char *line, int dir) { - int count=0; - - if (shp == NULL) - return -1; - - /* Count the number of lines saved in the buffer */ - int idx = shp->sh_beg; - while (idx != shp->sh_end) { - idx += *(shp->sh_buffer + idx) + 1; - if (idx >= shp->sh_size) - idx -= shp->sh_size; - count++; - } - - if (dir == SHELL_HIST_DIR_FW) { - if (shp->sh_cur > 0) - shp->sh_cur -= 2; - else - return 0; - } - - if (count >= shp->sh_cur) { - idx = shp->sh_beg; - int i = 0; - while (idx != shp->sh_end && shp->sh_cur != (count - i - 1)) { - idx += *(shp->sh_buffer + idx) + 1; - if (idx >= shp->sh_size) - idx -= shp->sh_size; - i++; - } - - int length = *(shp->sh_buffer + idx); - - if (length > 0) { - shp->sh_cur++; - - memset(line, 0, SHELL_MAX_LINE_LENGTH); - if ((idx + length) < shp->sh_size) { - memcpy(line, (shp->sh_buffer + idx + 1), length); - } - else { - /* - * Since the saved line was split at the end of the buffer, - * get the line in two parts. - */ - int part_len = shp->sh_size - idx - 1; - memcpy(line, shp->sh_buffer + idx + 1, part_len); - memcpy(line + part_len, shp->sh_buffer, length - part_len); - } - return length; - } - else if (dir == SHELL_HIST_DIR_FW) { - shp->sh_cur++; - return 0; - } - } - return -1; -} -#endif - -#if (SHELL_USE_COMPLETION == TRUE) || defined(__DOXYGEN__) -static void get_completions(ShellConfig *scfg, char *line) { - const ShellCommand *lcp = shell_local_commands; - const ShellCommand *scp = scfg->sc_commands; - char **scmp = scfg->sc_completion; - char help_cmp[] = "help"; - - if (strstr(help_cmp, line) == help_cmp) { - *scmp++ = help_cmp; - } - while (lcp->sc_name != NULL) { - if (strstr(lcp->sc_name, line) == lcp->sc_name) { - *scmp++ = (char *)lcp->sc_name; - } - lcp++; - } - if (scp != NULL) { - while (scp->sc_name != NULL) { - if (strstr(scp->sc_name, line) == scp->sc_name) { - *scmp++ = (char *)scp->sc_name; - } - scp++; - } - } - - *scmp = NULL; -} - -static int process_completions(ShellConfig *scfg, char *line, int length, unsigned size) { - char **scmp = scfg->sc_completion; - char **cmp = scmp + 1; - char *c = line + length; - int clen = 0; - - if (*scmp != NULL) { - if (*cmp == NULL) { - clen = strlen(*scmp); - int i = length; - while ((c < line + clen) && (c < line + size - 1)) - *c++ = *(*scmp + i++); - if (c < line + size -1) { - *c = ' '; - clen++; - } - } - else { - while (*(*scmp + clen) != 0) { - while ((*(*scmp + clen) == *(*cmp + clen)) && - (*(*cmp + clen) != 0) && (*cmp != NULL)) { - cmp++; - } - if (*cmp == NULL) { - if ((c < line + size - 1) && (clen >= length)) - *c++ = *(*scmp + clen); - cmp = scmp + 1; - clen++; - } - else { - break; - } - } - } - - *(line + clen) = 0; - } - - return clen; -} - -static void write_completions(ShellConfig *scfg, char *line, int pos) { - BaseSequentialStream *chp = scfg->sc_channel; - char **scmp = scfg->sc_completion; - - if (*(scmp + 1) != NULL) { - chprintf(chp, SHELL_NEWLINE_STR); - while (*scmp != NULL) - chprintf(chp, " %s", *scmp++); - chprintf(chp, SHELL_NEWLINE_STR); - - chprintf(chp, SHELL_PROMPT_STR); - chprintf(chp, "%s", line); - } - else { - chprintf(chp, "%s", line + pos); - } -} -#endif - -/*===========================================================================*/ -/* Module exported functions. */ -/*===========================================================================*/ - -/** - * @brief Shell thread function. - * - * @param[in] p pointer to a @p BaseSequentialStream object - */ -THD_FUNCTION(shellThread, p) { - int n; - ShellConfig *scfg = p; - BaseSequentialStream *chp = scfg->sc_channel; - const ShellCommand *scp = scfg->sc_commands; - char *lp, *cmd, *tokp, line[SHELL_MAX_LINE_LENGTH]; - char *args[SHELL_MAX_ARGUMENTS + 1]; - -#if !defined(_CHIBIOS_NIL_) - chRegSetThreadName(SHELL_THREAD_NAME); -#endif - -#if SHELL_USE_HISTORY == TRUE - *(scfg->sc_histbuf) = 0; - ShellHistory hist = { - scfg->sc_histbuf, - scfg->sc_histsize, - 0, - 0, - 0 - }; - ShellHistory *shp = &hist; -#else - ShellHistory *shp = NULL; -#endif - - chprintf(chp, SHELL_NEWLINE_STR); - chprintf(chp, "ChibiOS/RT Shell" SHELL_NEWLINE_STR); -#if !defined(_CHIBIOS_NIL_) - while (!chThdShouldTerminateX()) { -#else - while (true) { -#endif - chprintf(chp, SHELL_PROMPT_STR); - if (shellGetLine(scfg, line, sizeof(line), shp)) { -#if (SHELL_CMD_EXIT_ENABLED == TRUE) && !defined(_CHIBIOS_NIL_) - chprintf(chp, SHELL_NEWLINE_STR); - chprintf(chp, "logout"); - break; -#else - /* Putting a delay in order to avoid an endless loop trying to read - an unavailable stream.*/ - osalThreadSleepMilliseconds(100); -#endif - } - lp = parse_arguments(line, &tokp); - cmd = lp; - n = 0; - while ((lp = parse_arguments(NULL, &tokp)) != NULL) { - if (n >= SHELL_MAX_ARGUMENTS) { - chprintf(chp, "too many arguments" SHELL_NEWLINE_STR); - cmd = NULL; - break; - } - args[n++] = lp; - } - args[n] = NULL; - if (cmd != NULL) { - if (strcmp(cmd, "help") == 0) { - if (n > 0) { - shellUsage(chp, "help"); - continue; - } - chprintf(chp, "Commands: help "); - list_commands(chp, shell_local_commands); - if (scp != NULL) - list_commands(chp, scp); - chprintf(chp, SHELL_NEWLINE_STR); - } - else if (cmdexec(shell_local_commands, chp, cmd, n, args) && - ((scp == NULL) || cmdexec(scp, chp, cmd, n, args))) { - chprintf(chp, "%s", cmd); - chprintf(chp, " ?" SHELL_NEWLINE_STR); - } - } - } -#if !defined(_CHIBIOS_NIL_) - shellExit(MSG_OK); -#endif -} - -/** - * @brief Shell manager initialization. - * - * @api - */ -void shellInit(void) { - -#if !defined(_CHIBIOS_NIL_) - chEvtObjectInit(&shell_terminated); -#endif -} - -#if !defined(_CHIBIOS_NIL_) || defined(__DOXYGEN__) -/** - * @brief Terminates the shell. - * @note Must be invoked from the command handlers. - * @note Does not return. - * - * @param[in] msg shell exit code - * - * @api - */ -void shellExit(msg_t msg) { - - /* Atomically broadcasting the event source and terminating the thread, - there is not a chSysUnlock() because the thread terminates upon return.*/ - chSysLock(); - chEvtBroadcastI(&shell_terminated); - chThdExitS(msg); -} -#endif - -/** - * @brief Reads a whole line from the input channel. - * @note Input chars are echoed on the same stream object with the - * following exceptions: - * - DEL and BS are echoed as BS-SPACE-BS. - * - CR is echoed as CR-LF. - * - 0x4 is echoed as "^D". - * - Other values below 0x20 are not echoed. - * . - * - * @param[in] scfg pointer to a @p ShellConfig object - * @param[in] line pointer to the line buffer - * @param[in] size buffer maximum length - * @param[in] shp pointer to a @p ShellHistory object or NULL - * @return The operation status. - * @retval true the channel was reset or CTRL-D pressed. - * @retval false operation successful. - * - * @api - */ -bool shellGetLine(ShellConfig *scfg, char *line, unsigned size, ShellHistory *shp) { - char *p = line; - BaseSequentialStream *chp = scfg->sc_channel; -#if SHELL_USE_ESC_SEQ == TRUE - bool escape = false; - bool bracket = false; -#endif - -#if SHELL_USE_HISTORY != TRUE - (void) shp; -#endif - - while (true) { - char c; - - if (streamRead(chp, (uint8_t *)&c, 1) == 0) - return true; -#if SHELL_USE_ESC_SEQ == TRUE - if (c == 27) { - escape = true; - continue; - } - if (escape) { - escape = false; - if (c == '[') { - escape = true; - bracket = true; - continue; - } - if (bracket) { - bracket = false; -#if SHELL_USE_HISTORY == TRUE - if (c == 'A') { - int len = get_history(shp, line, SHELL_HIST_DIR_BK); - - if (len > 0) { - _shell_reset_cur(chp); - _shell_clr_line(chp); - chprintf(chp, "%s", line); - p = line + len; - } - continue; - } - if (c == 'B') { - int len = get_history(shp, line, SHELL_HIST_DIR_FW); - - if (len == 0) - *line = 0; - - if (len >= 0) { - _shell_reset_cur(chp); - _shell_clr_line(chp); - chprintf(chp, "%s", line); - p = line + len; - } - continue; - } -#endif - } - continue; - } -#endif -#if (SHELL_CMD_EXIT_ENABLED == TRUE) && !defined(_CHIBIOS_NIL_) - if (c == 4) { - chprintf(chp, "^D"); - return true; - } -#endif - if ((c == 8) || (c == 127)) { - if (p != line) { - streamPut(chp, 0x08); - streamPut(chp, 0x20); - streamPut(chp, 0x08); - p--; - } - continue; - } - if (c == '\r') { - chprintf(chp, SHELL_NEWLINE_STR); -#if SHELL_USE_HISTORY == TRUE - save_history(shp, line, p - line); -#endif - *p = 0; - return false; - } -#if SHELL_USE_COMPLETION == TRUE - if (c == '\t') { - if (p < line + size - 1) { - *p = 0; - - get_completions(scfg, line); - int len = process_completions(scfg, line, p - line, size); - if (len > 0) { - write_completions(scfg, line, p - line); - p = line + len; - } - } - continue; - } -#endif -#if SHELL_USE_HISTORY == TRUE - if (c == 14) { - int len = get_history(shp, line, SHELL_HIST_DIR_FW); - - if (len == 0) - *line = 0; - - if (len >= 0) { - _shell_reset_cur(chp); - _shell_clr_line(chp); - chprintf(chp, "%s", line); - p = line + len; - } - continue; - } - if (c == 16) { - int len = get_history(shp, line, SHELL_HIST_DIR_BK); - - if (len > 0) { - _shell_reset_cur(chp); - _shell_clr_line(chp); - chprintf(chp, "%s", line); - p = line + len; - } - continue; - } -#endif - if (c < 0x20) - continue; - if (p < line + size - 1) { - streamPut(chp, c); - *p++ = (char)c; - } - } -} - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 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 shell.c + * @brief Simple CLI shell code. + * + * @addtogroup SHELL + * @{ + */ + +#include + +#include "ch.h" +#include "hal.h" +#include "shell.h" +#include "shell_cmd.h" +#include "chprintf.h" + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +#if !defined(_CHIBIOS_NIL_) || defined(__DOXYGEN__) +/** + * @brief Shell termination event source. + */ +event_source_t shell_terminated; +#endif + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +static char *parse_arguments(char *str, char **saveptr) { + char *p; + + if (str != NULL) + *saveptr = str; + + p = *saveptr; + if (!p) { + return NULL; + } + + /* Skipping white space.*/ + p += strspn(p, " \t"); + + if (*p == '"') { + /* If an argument starts with a double quote then its delimiter is another + quote.*/ + p++; + *saveptr = strpbrk(p, "\""); + } + else { + /* The delimiter is white space.*/ + *saveptr = strpbrk(p, " \t"); + } + + /* Replacing the delimiter with a zero.*/ + if (*saveptr != NULL) { + *(*saveptr)++ = '\0'; + } + + return *p != '\0' ? p : NULL; +} + +static void list_commands(BaseSequentialStream *chp, const ShellCommand *scp) { + + while (scp->sc_name != NULL) { + chprintf(chp, "%s ", scp->sc_name); + scp++; + } +} + +static bool cmdexec(const ShellCommand *scp, BaseSequentialStream *chp, + char *name, int argc, char *argv[]) { + + while (scp->sc_name != NULL) { + if (strcmp(scp->sc_name, name) == 0) { + scp->sc_function(chp, argc, argv); + return false; + } + scp++; + } + return true; +} + +#if (SHELL_USE_HISTORY == TRUE) || defined(__DOXYGEN__) +static void del_histbuff_entry(ShellHistory *shp) { + int pos = shp->sh_beg + *(shp->sh_buffer + shp->sh_beg) + 1; + + if (pos >= shp->sh_size) + pos -= shp->sh_size; + + shp->sh_beg = pos; +} + +static bool is_histbuff_space(ShellHistory *shp, int length) { + + if (shp->sh_end >= shp->sh_beg) { + if (length < (shp->sh_size - (shp->sh_end - shp->sh_beg + 1))) + return true; + } + else { + if (length < (shp->sh_beg - shp->sh_end - 1)) + return true; + } + + return false; +} + +static void save_history(ShellHistory *shp, char *line, int length) { + + if (shp == NULL) + return; + + if (length > shp->sh_size - 2) + return; + + while ((*(line + length -1) == ' ') && (length > 0)) + length--; + + if (length <= 0) + return; + + while (!is_histbuff_space(shp, length)) + del_histbuff_entry(shp); + + if (length < shp->sh_size - shp->sh_end - 1) + memcpy(shp->sh_buffer + shp->sh_end + 1, line, length); + else { + /* + * Since there isn't enough room left at the end of the buffer, + * split the line to save up to the end of the buffer and then + * wrap back to the beginning of the buffer. + */ + int part_len = shp->sh_size - shp->sh_end - 1; + memcpy(shp->sh_buffer + shp->sh_end + 1, line, part_len); + memcpy(shp->sh_buffer, line + part_len, length - part_len); + } + + /* Save the length of the current line and move the buffer end pointer */ + *(shp->sh_buffer + shp->sh_end) = (char)length; + shp->sh_end += length + 1; + if (shp->sh_end >= shp->sh_size) + shp->sh_end -= shp->sh_size; + *(shp->sh_buffer + shp->sh_end) = 0; + shp->sh_cur = 0; +} + +static int get_history(ShellHistory *shp, char *line, int dir) { + int count=0; + + if (shp == NULL) + return -1; + + /* Count the number of lines saved in the buffer */ + int idx = shp->sh_beg; + while (idx != shp->sh_end) { + idx += *(shp->sh_buffer + idx) + 1; + if (idx >= shp->sh_size) + idx -= shp->sh_size; + count++; + } + + if (dir == SHELL_HIST_DIR_FW) { + if (shp->sh_cur > 0) + shp->sh_cur -= 2; + else + return 0; + } + + if (count >= shp->sh_cur) { + idx = shp->sh_beg; + int i = 0; + while (idx != shp->sh_end && shp->sh_cur != (count - i - 1)) { + idx += *(shp->sh_buffer + idx) + 1; + if (idx >= shp->sh_size) + idx -= shp->sh_size; + i++; + } + + int length = *(shp->sh_buffer + idx); + + if (length > 0) { + shp->sh_cur++; + + memset(line, 0, SHELL_MAX_LINE_LENGTH); + if ((idx + length) < shp->sh_size) { + memcpy(line, (shp->sh_buffer + idx + 1), length); + } + else { + /* + * Since the saved line was split at the end of the buffer, + * get the line in two parts. + */ + int part_len = shp->sh_size - idx - 1; + memcpy(line, shp->sh_buffer + idx + 1, part_len); + memcpy(line + part_len, shp->sh_buffer, length - part_len); + } + return length; + } + else if (dir == SHELL_HIST_DIR_FW) { + shp->sh_cur++; + return 0; + } + } + return -1; +} +#endif + +#if (SHELL_USE_COMPLETION == TRUE) || defined(__DOXYGEN__) +static void get_completions(ShellConfig *scfg, char *line) { + const ShellCommand *lcp = shell_local_commands; + const ShellCommand *scp = scfg->sc_commands; + char **scmp = scfg->sc_completion; + char help_cmp[] = "help"; + + if (strstr(help_cmp, line) == help_cmp) { + *scmp++ = help_cmp; + } + while (lcp->sc_name != NULL) { + if (strstr(lcp->sc_name, line) == lcp->sc_name) { + *scmp++ = (char *)lcp->sc_name; + } + lcp++; + } + if (scp != NULL) { + while (scp->sc_name != NULL) { + if (strstr(scp->sc_name, line) == scp->sc_name) { + *scmp++ = (char *)scp->sc_name; + } + scp++; + } + } + + *scmp = NULL; +} + +static int process_completions(ShellConfig *scfg, char *line, int length, unsigned size) { + char **scmp = scfg->sc_completion; + char **cmp = scmp + 1; + char *c = line + length; + int clen = 0; + + if (*scmp != NULL) { + if (*cmp == NULL) { + clen = strlen(*scmp); + int i = length; + while ((c < line + clen) && (c < line + size - 1)) + *c++ = *(*scmp + i++); + if (c < line + size -1) { + *c = ' '; + clen++; + } + } + else { + while (*(*scmp + clen) != 0) { + while ((*(*scmp + clen) == *(*cmp + clen)) && + (*(*cmp + clen) != 0) && (*cmp != NULL)) { + cmp++; + } + if (*cmp == NULL) { + if ((c < line + size - 1) && (clen >= length)) + *c++ = *(*scmp + clen); + cmp = scmp + 1; + clen++; + } + else { + break; + } + } + } + + *(line + clen) = 0; + } + + return clen; +} + +static void write_completions(ShellConfig *scfg, char *line, int pos) { + BaseSequentialStream *chp = scfg->sc_channel; + char **scmp = scfg->sc_completion; + + if (*(scmp + 1) != NULL) { + chprintf(chp, SHELL_NEWLINE_STR); + while (*scmp != NULL) + chprintf(chp, " %s", *scmp++); + chprintf(chp, SHELL_NEWLINE_STR); + + chprintf(chp, SHELL_PROMPT_STR); + chprintf(chp, "%s", line); + } + else { + chprintf(chp, "%s", line + pos); + } +} +#endif + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Shell thread function. + * + * @param[in] p pointer to a @p BaseSequentialStream object + */ +THD_FUNCTION(shellThread, p) { + int n; + ShellConfig *scfg = p; + BaseSequentialStream *chp = scfg->sc_channel; + const ShellCommand *scp = scfg->sc_commands; + char *lp, *cmd, *tokp, line[SHELL_MAX_LINE_LENGTH]; + char *args[SHELL_MAX_ARGUMENTS + 1]; + +#if !defined(_CHIBIOS_NIL_) + chRegSetThreadName(SHELL_THREAD_NAME); +#endif + +#if SHELL_USE_HISTORY == TRUE + *(scfg->sc_histbuf) = 0; + ShellHistory hist = { + scfg->sc_histbuf, + scfg->sc_histsize, + 0, + 0, + 0 + }; + ShellHistory *shp = &hist; +#else + ShellHistory *shp = NULL; +#endif + + chprintf(chp, SHELL_NEWLINE_STR); + chprintf(chp, "ChibiOS/RT Shell" SHELL_NEWLINE_STR); +#if !defined(_CHIBIOS_NIL_) + while (!chThdShouldTerminateX()) { +#else + while (true) { +#endif + chprintf(chp, SHELL_PROMPT_STR); + if (shellGetLine(scfg, line, sizeof(line), shp)) { +#if (SHELL_CMD_EXIT_ENABLED == TRUE) && !defined(_CHIBIOS_NIL_) + chprintf(chp, SHELL_NEWLINE_STR); + chprintf(chp, "logout"); + break; +#else + /* Putting a delay in order to avoid an endless loop trying to read + an unavailable stream.*/ + osalThreadSleepMilliseconds(100); + continue; +#endif + } + lp = parse_arguments(line, &tokp); + cmd = lp; + n = 0; + while ((lp = parse_arguments(NULL, &tokp)) != NULL) { + if (n >= SHELL_MAX_ARGUMENTS) { + chprintf(chp, "too many arguments" SHELL_NEWLINE_STR); + cmd = NULL; + break; + } + args[n++] = lp; + } + args[n] = NULL; + if (cmd != NULL) { + if (strcmp(cmd, "help") == 0) { + if (n > 0) { + shellUsage(chp, "help"); + continue; + } + chprintf(chp, "Commands: help "); + list_commands(chp, shell_local_commands); + if (scp != NULL) + list_commands(chp, scp); + chprintf(chp, SHELL_NEWLINE_STR); + } + else if (cmdexec(shell_local_commands, chp, cmd, n, args) && + ((scp == NULL) || cmdexec(scp, chp, cmd, n, args))) { + chprintf(chp, "%s", cmd); + chprintf(chp, " ?" SHELL_NEWLINE_STR); + } + } + } +#if !defined(_CHIBIOS_NIL_) + shellExit(MSG_OK); +#endif +} + +/** + * @brief Shell manager initialization. + * + * @api + */ +void shellInit(void) { + +#if !defined(_CHIBIOS_NIL_) + chEvtObjectInit(&shell_terminated); +#endif +} + +#if !defined(_CHIBIOS_NIL_) || defined(__DOXYGEN__) +/** + * @brief Terminates the shell. + * @note Must be invoked from the command handlers. + * @note Does not return. + * + * @param[in] msg shell exit code + * + * @api + */ +void shellExit(msg_t msg) { + + /* Atomically broadcasting the event source and terminating the thread, + there is not a chSysUnlock() because the thread terminates upon return.*/ + chSysLock(); + chEvtBroadcastI(&shell_terminated); + chThdExitS(msg); +} +#endif + +/** + * @brief Reads a whole line from the input channel. + * @note Input chars are echoed on the same stream object with the + * following exceptions: + * - DEL and BS are echoed as BS-SPACE-BS. + * - CR is echoed as CR-LF. + * - 0x4 is echoed as "^D". + * - Other values below 0x20 are not echoed. + * . + * + * @param[in] scfg pointer to a @p ShellConfig object + * @param[in] line pointer to the line buffer + * @param[in] size buffer maximum length + * @param[in] shp pointer to a @p ShellHistory object or NULL + * @return The operation status. + * @retval true the channel was reset or CTRL-D pressed. + * @retval false operation successful. + * + * @api + */ +bool shellGetLine(ShellConfig *scfg, char *line, unsigned size, ShellHistory *shp) { + char *p = line; + BaseSequentialStream *chp = scfg->sc_channel; +#if SHELL_USE_ESC_SEQ == TRUE + bool escape = false; + bool bracket = false; +#endif + +#if SHELL_USE_HISTORY != TRUE + (void) shp; +#endif + + while (true) { + char c; + + if (streamRead(chp, (uint8_t *)&c, 1) == 0) + return true; +#if SHELL_USE_ESC_SEQ == TRUE + if (c == 27) { + escape = true; + continue; + } + if (escape) { + escape = false; + if (c == '[') { + escape = true; + bracket = true; + continue; + } + if (bracket) { + bracket = false; +#if SHELL_USE_HISTORY == TRUE + if (c == 'A') { + int len = get_history(shp, line, SHELL_HIST_DIR_BK); + + if (len > 0) { + _shell_reset_cur(chp); + _shell_clr_line(chp); + chprintf(chp, "%s", line); + p = line + len; + } + continue; + } + if (c == 'B') { + int len = get_history(shp, line, SHELL_HIST_DIR_FW); + + if (len == 0) + *line = 0; + + if (len >= 0) { + _shell_reset_cur(chp); + _shell_clr_line(chp); + chprintf(chp, "%s", line); + p = line + len; + } + continue; + } +#endif + } + continue; + } +#endif +#if (SHELL_CMD_EXIT_ENABLED == TRUE) && !defined(_CHIBIOS_NIL_) + if (c == 4) { + chprintf(chp, "^D"); + return true; + } +#endif + if ((c == 8) || (c == 127)) { + if (p != line) { + streamPut(chp, 0x08); + streamPut(chp, 0x20); + streamPut(chp, 0x08); + p--; + } + continue; + } + if (c == '\r') { + chprintf(chp, SHELL_NEWLINE_STR); +#if SHELL_USE_HISTORY == TRUE + save_history(shp, line, p - line); +#endif + *p = 0; + return false; + } +#if SHELL_USE_COMPLETION == TRUE + if (c == '\t') { + if (p < line + size - 1) { + *p = 0; + + get_completions(scfg, line); + int len = process_completions(scfg, line, p - line, size); + if (len > 0) { + write_completions(scfg, line, p - line); + p = line + len; + } + } + continue; + } +#endif +#if SHELL_USE_HISTORY == TRUE + if (c == 14) { + int len = get_history(shp, line, SHELL_HIST_DIR_FW); + + if (len == 0) + *line = 0; + + if (len >= 0) { + _shell_reset_cur(chp); + _shell_clr_line(chp); + chprintf(chp, "%s", line); + p = line + len; + } + continue; + } + if (c == 16) { + int len = get_history(shp, line, SHELL_HIST_DIR_BK); + + if (len > 0) { + _shell_reset_cur(chp); + _shell_clr_line(chp); + chprintf(chp, "%s", line); + p = line + len; + } + continue; + } +#endif + if (c < 0x20) + continue; + if (p < line + size - 1) { + streamPut(chp, c); + *p++ = (char)c; + } + } +} + +/** @} */ From 66d5a0c658db72fdb8788ccb7e8b4965cb919c47 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Thu, 2 Mar 2023 09:09:22 +0000 Subject: [PATCH 15/53] Fixed bug #1251. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16122 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/nil/src/ch.c | 2160 +++++++++++++++++++++++------------------------ readme.txt | 1 + 2 files changed, 1081 insertions(+), 1080 deletions(-) diff --git a/os/nil/src/ch.c b/os/nil/src/ch.c index efcca07f52..2aa05427fd 100644 --- a/os/nil/src/ch.c +++ b/os/nil/src/ch.c @@ -1,1080 +1,1080 @@ -/* - ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014, - 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio. - - This file is part of ChibiOS. - - ChibiOS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation version 3 of the License. - - ChibiOS is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file nil/src/ch.c - * @brief Nil RTOS main source file. - * - * @addtogroup NIL_KERNEL - * @{ - */ - -#include "ch.h" - -/*===========================================================================*/ -/* Module local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module exported variables. */ -/*===========================================================================*/ - -/** - * @brief System data structures. - */ -nil_system_t nil; - -/*===========================================================================*/ -/* Module local variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module exported functions. */ -/*===========================================================================*/ - -/** - * @brief Retrieves the highest priority thread in the specified state and - * associated to the specified object. - * - * @param[in] state thread state - * @param[in] p object pointer - * @return The pointer to the found thread. - * @retval NULL if the thread is not found. - * - * @notapi - */ -thread_t *nil_find_thread(tstate_t state, void *p) { - thread_t *tp = nil.threads; - - while (tp < &nil.threads[CH_CFG_MAX_THREADS]) { - /* Is this thread matching?*/ - if ((tp->state == state) && (tp->u1.p == p)) { - return tp; - } - tp++; - } - return NULL; -} - -/** - * @brief Puts in ready state all thread matching the specified status and - * associated object. - * - * @param[in] p object pointer - * @param[in] cnt number of threads to be readied as a negative number, - * non negative numbers are ignored - * @param[in] msg the wakeup message - * @return The number of readied threads. - * - * @notapi - */ -cnt_t nil_ready_all(void *p, cnt_t cnt, msg_t msg) { - thread_t *tp = nil.threads;; - - while (cnt < (cnt_t)0) { - - chDbgAssert(tp < &nil.threads[CH_CFG_MAX_THREADS], - "pointer out of range"); - - /* Is this thread waiting on this queue?*/ - if ((tp->state == NIL_STATE_WTQUEUE) && (tp->u1.p == p)) { - cnt++; - (void) chSchReadyI(tp, msg); - } - tp++; - } - - return cnt; -} - -#if (CH_DBG_SYSTEM_STATE_CHECK == TRUE) || defined(__DOXYGEN__) -/** - * @brief Guard code for @p chSysDisable(). - * - * @notapi - */ -void _dbg_check_disable(void) { - - if ((nil.isr_cnt != (cnt_t)0) || (nil.lock_cnt != (cnt_t)0)) { - chSysHalt("SV#1"); - } -} - -/** - * @brief Guard code for @p chSysSuspend(). - * - * @notapi - */ -void _dbg_check_suspend(void) { - - if ((nil.isr_cnt != (cnt_t)0) || (nil.lock_cnt != (cnt_t)0)) { - chSysHalt("SV#2"); - } -} - -/** - * @brief Guard code for @p chSysEnable(). - * - * @notapi - */ -void _dbg_check_enable(void) { - - if ((nil.isr_cnt != (cnt_t)0) || (nil.lock_cnt != (cnt_t)0)) { - chSysHalt("SV#3"); - } -} - -/** - * @brief Guard code for @p chSysLock(). - * - * @notapi - */ -void _dbg_check_lock(void) { - - if ((nil.isr_cnt != (cnt_t)0) || (nil.lock_cnt != (cnt_t)0)) { - chSysHalt("SV#4"); - } - _dbg_enter_lock(); -} - -/** - * @brief Guard code for @p chSysUnlock(). - * - * @notapi - */ -void _dbg_check_unlock(void) { - - if ((nil.isr_cnt != (cnt_t)0) || (nil.lock_cnt <= (cnt_t)0)) { - chSysHalt("SV#5"); - } - _dbg_leave_lock(); -} - -/** - * @brief Guard code for @p chSysLockFromIsr(). - * - * @notapi - */ -void _dbg_check_lock_from_isr(void) { - - if ((nil.isr_cnt <= (cnt_t)0) || (nil.lock_cnt != (cnt_t)0)) { - chSysHalt("SV#6"); - } - _dbg_enter_lock(); -} - -/** - * @brief Guard code for @p chSysUnlockFromIsr(). - * - * @notapi - */ -void _dbg_check_unlock_from_isr(void) { - - if ((nil.isr_cnt <= (cnt_t)0) || (nil.lock_cnt <= (cnt_t)0)) { - chSysHalt("SV#7"); - } - _dbg_leave_lock(); -} - -/** - * @brief Guard code for @p CH_IRQ_PROLOGUE(). - * - * @notapi - */ -void _dbg_check_enter_isr(void) { - - port_lock_from_isr(); - if ((nil.isr_cnt < (cnt_t)0) || (nil.lock_cnt != (cnt_t)0)) { - chSysHalt("SV#8"); - } - nil.isr_cnt++; - port_unlock_from_isr(); -} - -/** - * @brief Guard code for @p CH_IRQ_EPILOGUE(). - * - * @notapi - */ -void _dbg_check_leave_isr(void) { - - port_lock_from_isr(); - if ((nil.isr_cnt <= (cnt_t)0) || (nil.lock_cnt != (cnt_t)0)) { - chSysHalt("SV#9"); - } - nil.isr_cnt--; - port_unlock_from_isr(); -} - -/** - * @brief I-class functions context check. - * @details Verifies that the system is in an appropriate state for invoking - * an I-class API function. A panic is generated if the state is - * not compatible. - * - * @api - */ -void chDbgCheckClassI(void) { - - if ((nil.isr_cnt < (cnt_t)0) || (nil.lock_cnt <= (cnt_t)0)) { - chSysHalt("SV#10"); - } -} - -/** - * @brief S-class functions context check. - * @details Verifies that the system is in an appropriate state for invoking - * an S-class API function. A panic is generated if the state is - * not compatible. - * - * @api - */ -void chDbgCheckClassS(void) { - - if ((nil.isr_cnt != (cnt_t)0) || (nil.lock_cnt <= (cnt_t)0)) { - chSysHalt("SV#11"); - } -} -#endif /* CH_DBG_SYSTEM_STATE_CHECK == TRUE */ - -/** - * @brief Initializes the kernel. - * @details Initializes the kernel structures, the current instructions flow - * becomes the idle thread upon return. The idle thread must not - * invoke any kernel primitive able to change state to not runnable. - * @note This function assumes that the @p nil global variable has been - * zeroed by the runtime environment. If this is not the case then - * make sure to clear it before calling this function. - * - * @special - */ -void chSysInit(void) { - const thread_descriptor_t *tdp; - - /* Optional library modules.*/ - _oslib_init(); - - /* Architecture layer initialization.*/ - port_init(); - - /* System initialization hook.*/ - CH_CFG_SYSTEM_INIT_HOOK(); - - /* Making idle the current thread, this may change after rescheduling.*/ - nil.next = nil.current = &nil.threads[CH_CFG_MAX_THREADS]; - nil.current->state = NIL_STATE_READY; - -#if CH_DBG_ENABLE_STACK_CHECK == TRUE - /* The idle thread is a special case because its stack is set up by the - runtime environment.*/ - nil.threads[CH_CFG_MAX_THREADS].wabase = THD_IDLE_BASE; -#endif - - /* Interrupts partially enabled. It is equivalent to entering the - kernel critical zone.*/ - chSysSuspend(); -#if CH_DBG_SYSTEM_STATE_CHECK == TRUE - nil.lock_cnt = (cnt_t)1; -#endif - -#if CH_CFG_AUTOSTART_THREADS == TRUE - /* Iterates through the list of threads to be auto-started.*/ - tdp = nil_thd_configs; - do { - (void) chThdCreateI(tdp); - tdp++; - } while (tdp->funcp != NULL); -#endif - - /* Starting the dance.*/ - chSchRescheduleS(); - chSysUnlock(); -} - -/** - * @brief Halts the system. - * @details This function is invoked by the operating system when an - * unrecoverable error is detected, for example because a programming - * error in the application code that triggers an assertion while - * in debug mode. - * @note Can be invoked from any system state. - * - * @param[in] reason pointer to an error string - * - * @special - */ -void chSysHalt(const char *reason) { - - port_disable(); - -#if NIL_DBG_ENABLED - nil.dbg_panic_msg = reason; -#else - (void)reason; -#endif - - /* Halt hook code, usually empty.*/ - CH_CFG_SYSTEM_HALT_HOOK(reason); - - /* Harmless infinite loop.*/ - while (true) { - } -} - -/** - * @brief Time management handler. - * @note This handler has to be invoked by a periodic ISR in order to - * reschedule the waiting threads. - * - * @iclass - */ -void chSysTimerHandlerI(void) { - - chDbgCheckClassI(); - -#if CH_CFG_ST_TIMEDELTA == 0 - thread_t *tp = &nil.threads[0]; - nil.systime++; - do { - /* Is the thread in a wait state with timeout?.*/ - if (tp->timeout > (sysinterval_t)0) { - - chDbgAssert(!NIL_THD_IS_READY(tp), "is ready"); - - /* Did the timer reach zero?*/ - if (--tp->timeout == (sysinterval_t)0) { - /* Timeout on queues/semaphores requires a special handling because - the counter must be incremented.*/ - /*lint -save -e9013 [15.7] There is no else because it is not needed.*/ -#if CH_CFG_USE_SEMAPHORES == TRUE - if (NIL_THD_IS_WTQUEUE(tp)) { - tp->u1.semp->cnt++; - } - else -#endif - if (NIL_THD_IS_SUSPENDED(tp)) { - *tp->u1.trp = NULL; - } - /*lint -restore*/ - (void) chSchReadyI(tp, MSG_TIMEOUT); - } - } - /* Lock released in order to give a preemption chance on those - architectures supporting IRQ preemption.*/ - chSysUnlockFromISR(); - tp++; - chSysLockFromISR(); - } while (tp < &nil.threads[CH_CFG_MAX_THREADS]); -#else - thread_t *tp = &nil.threads[0]; - sysinterval_t next = (sysinterval_t)0; - - chDbgAssert(nil.nexttime == port_timer_get_alarm(), "time mismatch"); - - do { - sysinterval_t timeout = tp->timeout; - - /* Is the thread in a wait state with timeout?.*/ - if (timeout > (sysinterval_t)0) { - - chDbgAssert(!NIL_THD_IS_READY(tp), "is ready"); - chDbgAssert(timeout >= chTimeDiffX(nil.lasttime, nil.nexttime), - "skipped one"); - - /* The volatile field is updated once, here.*/ - timeout -= chTimeDiffX(nil.lasttime, nil.nexttime); - tp->timeout = timeout; - - if (timeout == (sysinterval_t)0) { - /* Timeout on thread queues requires a special handling because the - counter must be incremented.*/ - if (NIL_THD_IS_WTQUEUE(tp)) { - tp->u1.tqp->cnt++; - } - else { - if (NIL_THD_IS_SUSPENDED(tp)) { - *tp->u1.trp = NULL; - } - } - (void) chSchReadyI(tp, MSG_TIMEOUT); - } - else { - if (timeout <= (sysinterval_t)(next - (sysinterval_t)1)) { - next = timeout; - } - } - } - - /* Lock released in order to give a preemption chance on those - architectures supporting IRQ preemption.*/ - chSysUnlockFromISR(); - tp++; - chSysLockFromISR(); - } while (tp < &nil.threads[CH_CFG_MAX_THREADS]); - - nil.lasttime = nil.nexttime; - if (next > (sysinterval_t)0) { - nil.nexttime = chTimeAddX(nil.nexttime, next); - port_timer_set_alarm(nil.nexttime); - } - else { - /* No tick event needed.*/ - port_timer_stop_alarm(); - } -#endif -} - -/** - * @brief Unconditionally enters the kernel lock state. - * @note Can be called without previous knowledge of the current lock state. - * The final state is "s-locked". - * - * @special - */ -void chSysUnconditionalLock(void) { - - if (port_irq_enabled(port_get_irq_status())) { - chSysLock(); - } -} - -/** - * @brief Unconditionally leaves the kernel lock state. - * @note Can be called without previous knowledge of the current lock state. - * The final state is "normal". - * - * @special - */ -void chSysUnconditionalUnlock(void) { - - if (!port_irq_enabled(port_get_irq_status())) { - chSysUnlock(); - } -} - -/** - * @brief Returns the execution status and enters a critical zone. - * @details This functions enters into a critical zone and can be called - * from any context. Because its flexibility it is less efficient - * than @p chSysLock() which is preferable when the calling context - * is known. - * @post The system is in a critical zone. - * - * @return The previous system status, the encoding of this - * status word is architecture-dependent and opaque. - * - * @xclass - */ -syssts_t chSysGetStatusAndLockX(void) { - - syssts_t sts = port_get_irq_status(); - if (port_irq_enabled(sts)) { - if (port_is_isr_context()) { - chSysLockFromISR(); - } - else { - chSysLock(); - } - } - return sts; -} - -/** - * @brief Restores the specified execution status and leaves a critical zone. - * @note A call to @p chSchRescheduleS() is automatically performed - * if exiting the critical zone and if not in ISR context. - * - * @param[in] sts the system status to be restored. - * - * @xclass - */ -void chSysRestoreStatusX(syssts_t sts) { - - if (port_irq_enabled(sts)) { - if (port_is_isr_context()) { - chSysUnlockFromISR(); - } - else { - chSchRescheduleS(); - chSysUnlock(); - } - } -} - -#if (PORT_SUPPORTS_RT == TRUE) || defined(__DOXYGEN__) -/** - * @brief Realtime window test. - * @details This function verifies if the current realtime counter value - * lies within the specified range or not. The test takes care - * of the realtime counter wrapping to zero on overflow. - * @note When start==end then the function returns always false because a - * null time range is specified. - * @note This function is only available if the port layer supports the - * option @p PORT_SUPPORTS_RT. - * - * @param[in] cnt the counter value to be tested - * @param[in] start the start of the time window (inclusive) - * @param[in] end the end of the time window (non inclusive) - * @retval true current time within the specified time window. - * @retval false current time not within the specified time window. - * - * @xclass - */ -bool chSysIsCounterWithinX(rtcnt_t cnt, rtcnt_t start, rtcnt_t end) { - - return (bool)(((rtcnt_t)cnt - (rtcnt_t)start) < - ((rtcnt_t)end - (rtcnt_t)start)); -} - -/** - * @brief Polled delay. - * @note The real delay is always few cycles in excess of the specified - * value. - * @note This function is only available if the port layer supports the - * option @p PORT_SUPPORTS_RT. - * - * @param[in] cycles number of cycles - * - * @xclass - */ -void chSysPolledDelayX(rtcnt_t cycles) { - rtcnt_t start = chSysGetRealtimeCounterX(); - rtcnt_t end = start + cycles; - - while (chSysIsCounterWithinX(chSysGetRealtimeCounterX(), start, end)) { - } -} -#endif /* PORT_SUPPORTS_RT == TRUE */ - -/** - * @brief Makes the specified thread ready for execution. - * - * @param[in] tp pointer to the @p thread_t object - * @param[in] msg the wakeup message - * - * @return The same reference passed as parameter. - */ -thread_t *chSchReadyI(thread_t *tp, msg_t msg) { - - chDbgCheckClassI(); - chDbgCheck((tp >= nil.threads) && (tp < &nil.threads[CH_CFG_MAX_THREADS])); - chDbgAssert(!NIL_THD_IS_READY(tp), "already ready"); - chDbgAssert(nil.next <= nil.current, "priority ordering"); - - tp->u1.msg = msg; - tp->state = NIL_STATE_READY; - tp->timeout = (sysinterval_t)0; - if (tp < nil.next) { - nil.next = tp; - } - return tp; -} - -/** - * @brief Evaluates if preemption is required. - * @details The decision is taken by comparing the relative priorities and - * depending on the state of the round robin timeout counter. - * @note Not a user function, it is meant to be invoked by the scheduler - * itself or from within the port layer. - * - * @retval true if there is a thread that must go in running state - * immediately. - * @retval false if preemption is not required. - * - * @special - */ -bool chSchIsPreemptionRequired(void) { - - return chSchIsRescRequiredI(); -} - -/** - * @brief Switches to the first thread on the runnable queue. - * @note Not a user function, it is meant to be invoked by the scheduler - * itself or from within the port layer. - * - * @special - */ -void chSchDoReschedule(void) { - thread_t *otp = nil.current; - - nil.current = nil.next; - if (otp == &nil.threads[CH_CFG_MAX_THREADS]) { - CH_CFG_IDLE_LEAVE_HOOK(); - } - port_switch(nil.next, otp); -} - -/** - * @brief Reschedules if needed. - * - * @sclass - */ -void chSchRescheduleS(void) { - - chDbgCheckClassS(); - - if (chSchIsRescRequiredI()) { - chSchDoReschedule(); - } -} - -/** - * @brief Puts the current thread to sleep into the specified state with - * timeout specification. - * @details The thread goes into a sleeping state, if it is not awakened - * explicitly within the specified system time then it is forcibly - * awakened with a @p MSG_TIMEOUT low level message. - * - * @param[in] newstate the new thread state or a semaphore pointer - * @param[in] timeout the number of ticks before the operation timeouts. - * the following special values are allowed: - * - @a TIME_INFINITE no timeout. - * . - * @return The wakeup message. - * @retval MSG_TIMEOUT if a timeout occurred. - * - * @sclass - */ -msg_t chSchGoSleepTimeoutS(tstate_t newstate, sysinterval_t timeout) { - thread_t *ntp, *otp = nil.current; - - chDbgCheckClassS(); - - chDbgAssert(otp != &nil.threads[CH_CFG_MAX_THREADS], - "idle cannot sleep"); - - /* Storing the wait object for the current thread.*/ - otp->state = newstate; - -#if CH_CFG_ST_TIMEDELTA > 0 - if (timeout != TIME_INFINITE) { - systime_t abstime; - - /* TIMEDELTA makes sure to have enough time to reprogram the timer - before the free-running timer counter reaches the selected timeout.*/ - if (timeout < (sysinterval_t)CH_CFG_ST_TIMEDELTA) { - timeout = (sysinterval_t)CH_CFG_ST_TIMEDELTA; - } - - /* Absolute time of the timeout event.*/ - abstime = chTimeAddX(chVTGetSystemTimeX(), timeout); - - if (nil.lasttime == nil.nexttime) { - /* Special case, first thread asking for a timeout.*/ - port_timer_start_alarm(abstime); - nil.nexttime = abstime; - } - else { - /* Special case, there are already other threads with a timeout - activated, evaluating the order.*/ - if (chTimeIsInRangeX(abstime, nil.lasttime, nil.nexttime)) { - port_timer_set_alarm(abstime); - nil.nexttime = abstime; - } - } - - /* Timeout settings.*/ - otp->timeout = abstime - nil.lasttime; - } -#else - - /* Timeout settings.*/ - otp->timeout = timeout; -#endif - - /* Scanning the whole threads array.*/ - ntp = nil.threads; - while (true) { - /* Is this thread ready to execute?*/ - if (NIL_THD_IS_READY(ntp)) { - nil.current = nil.next = ntp; - if (ntp == &nil.threads[CH_CFG_MAX_THREADS]) { - CH_CFG_IDLE_ENTER_HOOK(); - } - port_switch(ntp, otp); - return nil.current->u1.msg; - } - - /* Points to the next thread in lowering priority order.*/ - ntp++; - chDbgAssert(ntp <= &nil.threads[CH_CFG_MAX_THREADS], - "pointer out of range"); - } -} - -/** - * @brief Checks if the specified time is within the specified time range. - * @note When start==end then the function returns always false because the - * time window has zero size. - * - * @param[in] time the time to be verified - * @param[in] start the start of the time window (inclusive) - * @param[in] end the end of the time window (non inclusive) - * @retval true current time within the specified time window. - * @retval false current time not within the specified time window. - * - * @xclass - */ -bool chTimeIsInRangeX(systime_t time, systime_t start, systime_t end) { - - return (bool)((systime_t)((systime_t)(time) - (systime_t)(start)) < - (systime_t)((systime_t)(end) - (systime_t)(start))); -} - -/** - * @brief Creates a new thread into a static memory area. - * @details The new thread is initialized and make ready to execute. - * @note A thread can terminate by calling @p chThdExit() or by simply - * returning from its main function. - * - * @param[out] tdp pointer to the thread descriptor structure - * @return The pointer to the @p thread_t structure allocated for - * the thread. - * - * @iclass - */ -thread_t *chThdCreateI(const thread_descriptor_t *tdp) { - thread_t *tp; - - chDbgCheck((tdp->prio < (tprio_t)CH_CFG_MAX_THREADS) && - (tdp->wbase != NULL) && - MEM_IS_ALIGNED(tdp->wbase, PORT_WORKING_AREA_ALIGN) && - (tdp->wend > tdp->wbase) && - MEM_IS_ALIGNED(tdp->wbase, PORT_STACK_ALIGN) && - (tdp->funcp != NULL)); - - chDbgCheckClassI(); - - /* Pointer to the thread slot to be used.*/ - tp = &nil.threads[tdp->prio]; - chDbgAssert(NIL_THD_IS_WTSTART(tp) || NIL_THD_IS_FINAL(tp), - "priority slot taken"); - -#if CH_CFG_USE_EVENTS == TRUE - tp->epmask = (eventmask_t)0; -#endif -#if CH_DBG_ENABLE_STACK_CHECK == TRUE - tp->wabase = (stkalign_t *)tdp->wbase; -#endif - - /* Port dependent thread initialization.*/ - PORT_SETUP_CONTEXT(tp, tdp->wbase, tdp->wend, tdp->funcp, tdp->arg); - - /* Initialization hook.*/ - CH_CFG_THREAD_EXT_INIT_HOOK(tp); - - /* Readying up thread.*/ - return chSchReadyI(tp, MSG_OK); -} - -/** - * @brief Creates a new thread into a static memory area. - * @details The new thread is initialized and make ready to execute. - * @note A thread can terminate by calling @p chThdExit() or by simply - * returning from its main function. - * - * @param[out] tdp pointer to the thread descriptor structure - * @return The pointer to the @p thread_t structure allocated for - * the thread. - * - * @api - */ -thread_t *chThdCreate(const thread_descriptor_t *tdp) { - thread_t *tp; - - chSysLock(); - tp = chThdCreateI(tdp); - chSchRescheduleS(); - chSysUnlock(); - - return tp; -} - -/** - * @brief Terminates the current thread. - * @details The thread goes in the @p CH_STATE_FINAL state holding the - * specified exit status code, other threads can retrieve the - * exit status code by invoking the function @p chThdWait(). - * @post Exiting a non-static thread that does not have references - * (detached) causes the thread to remain in the registry. - * It can only be removed by performing a registry scan operation. - * @post Eventual code after this function will never be executed, - * this function never returns. The compiler has no way to - * know this so do not assume that the compiler would remove - * the dead code. - * - * @param[in] msg thread exit code - * - * @api - */ -void chThdExit(msg_t msg) { - - chSysLock(); - - /* Exit handler hook.*/ - CH_CFG_THREAD_EXIT_HOOK(tp); - -#if CH_CFG_USE_WAITEXIT == TRUE - { - /* Waking up any waiting thread.*/ - thread_t *tp = nil.threads; - while (tp < &nil.threads[CH_CFG_MAX_THREADS]) { - /* Is this thread waiting for current thread termination?*/ - if ((tp->state == NIL_STATE_WTEXIT) && (tp->u1.tp == nil.current)) { - (void) chSchReadyI(tp, msg); - } - tp++; - } - } -#endif - - /* Going into final state with exit message stored.*/ - nil.current->u1.msg = msg; - (void) chSchGoSleepTimeoutS(NIL_STATE_FINAL, TIME_INFINITE); - - /* The thread never returns here.*/ - chDbgAssert(false, "zombies apocalypse"); -} - -/** - * @brief Blocks the execution of the invoking thread until the specified - * thread terminates then the exit code is returned. - * - * @param[in] tp pointer to the thread - * @return The exit code from the terminated thread. - * - * @api - */ -msg_t chThdWait(thread_t *tp) { - msg_t msg; - - chSysLock(); - if (NIL_THD_IS_FINAL(tp)) { - msg = tp->u1.msg; - } - else { - nil.current->u1.tp = tp; - msg = chSchGoSleepTimeoutS(NIL_STATE_WTEXIT, TIME_INFINITE); - } - chSysUnlock(); - - return msg; -} - -/** - * @brief Sends the current thread sleeping and sets a reference variable. - * @note This function must reschedule, it can only be called from thread - * context. - * - * @param[in] trp a pointer to a thread reference object - * @param[in] timeout the number of ticks before the operation timeouts, - * the following special values are allowed: - * - @a TIME_IMMEDIATE immediate timeout. - * - @a TIME_INFINITE no timeout. - * . - * @return The wake up message. - * - * @sclass - */ -msg_t chThdSuspendTimeoutS(thread_reference_t *trp, sysinterval_t timeout) { - - chDbgAssert(*trp == NULL, "not NULL"); - - if (TIME_IMMEDIATE == timeout) { - return MSG_TIMEOUT; - } - - *trp = nil.current; - nil.current->u1.trp = trp; - return chSchGoSleepTimeoutS(NIL_STATE_SUSPENDED, timeout); -} - -/** - * @brief Wakes up a thread waiting on a thread reference object. - * @note This function must not reschedule because it can be called from - * ISR context. - * - * @param[in] trp a pointer to a thread reference object - * @param[in] msg the message code - * - * @iclass - */ -void chThdResumeI(thread_reference_t *trp, msg_t msg) { - - if (*trp != NULL) { - thread_reference_t tr = *trp; - - chDbgAssert(NIL_THD_IS_SUSPENDED(tr), "not suspended"); - - *trp = NULL; - (void) chSchReadyI(tr, msg); - } -} - -/** - * @brief Wakes up a thread waiting on a thread reference object. - * @note This function must reschedule, it can only be called from thread - * context. - * - * @param[in] trp a pointer to a thread reference object - * @param[in] msg the message code - * - * @api - */ -void chThdResume(thread_reference_t *trp, msg_t msg) { - - chSysLock(); - chThdResumeS(trp, msg); - chSysUnlock(); -} - -/** - * @brief Suspends the invoking thread for the specified time. - * - * @param[in] timeout the delay in system ticks - * - * @api - */ -void chThdSleep(sysinterval_t timeout) { - - chSysLock(); - chThdSleepS(timeout); - chSysUnlock(); -} - -/** - * @brief Suspends the invoking thread until the system time arrives to the - * specified value. - * - * @param[in] abstime absolute system time - * - * @api - */ -void chThdSleepUntil(systime_t abstime) { - - chSysLock(); - chThdSleepUntilS(abstime); - chSysUnlock(); -} - -/** - * @brief Enqueues the caller thread on a threads queue object. - * @details The caller thread is enqueued and put to sleep until it is - * dequeued or the specified timeouts expires. - * - * @param[in] tqp pointer to the threads queue object - * @param[in] timeout the timeout in system ticks, the special values are - * handled as follow: - * - @a TIME_IMMEDIATE immediate timeout. - * - @a TIME_INFINITE no timeout. - * . - * @return The message from @p osalQueueWakeupOneI() or - * @p osalQueueWakeupAllI() functions. - * @retval MSG_TIMEOUT if the thread has not been dequeued within the - * specified timeout or if the function has been - * invoked with @p TIME_IMMEDIATE as timeout - * specification. - * - * @sclass - */ -msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout) { - - chDbgCheckClassS(); - chDbgCheck(tqp != NULL); - - chDbgAssert(tqp->cnt <= (cnt_t)0, "invalid counter"); - - if (TIME_IMMEDIATE == timeout) { - return MSG_TIMEOUT; - } - - tqp->cnt--; - nil.current->u1.tqp = tqp; - return chSchGoSleepTimeoutS(NIL_STATE_WTQUEUE, timeout); -} - -/** - * @brief Dequeues and wakes up one thread from the threads queue object. - * @details Dequeues one thread from the queue without checking if the queue - * is empty. - * @pre The queue must contain at least an object. - * - * @param[in] tqp pointer to the threads queue object - * @param[in] msg the message code - * - * @iclass - */ -void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg) { - thread_t *tp; - - chDbgAssert(tqp->cnt < (cnt_t)0, "empty queue"); - - tqp->cnt++; - tp = nil_find_thread(NIL_STATE_WTQUEUE, (void *)tqp); - - chDbgAssert(tp != NULL, "thread not found"); - - (void) chSchReadyI(tp, msg); -} - -/** - * @brief Dequeues and wakes up one thread from the threads queue object, - * if any. - * - * @param[in] tqp pointer to the threads queue object - * @param[in] msg the message code - * - * @iclass - */ -void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg) { - - chDbgCheckClassI(); - chDbgCheck(tqp != NULL); - - if (tqp->cnt < (cnt_t)0) { - chThdDoDequeueNextI(tqp, msg); - } -} - -/** - * @brief Dequeues and wakes up all threads from the threads queue object. - * - * @param[in] tqp pointer to the threads queue object - * @param[in] msg the message code - * - * @iclass - */ -void chThdDequeueAllI(threads_queue_t *tqp, msg_t msg) { - - chDbgCheckClassI(); - chDbgCheck(tqp != NULL); - - tqp->cnt = nil_ready_all((void *)tqp, tqp->cnt, msg); -} - -/** @} */ +/* + ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014, + 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 3 of the License. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file nil/src/ch.c + * @brief Nil RTOS main source file. + * + * @addtogroup NIL_KERNEL + * @{ + */ + +#include "ch.h" + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/** + * @brief System data structures. + */ +nil_system_t nil; + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Retrieves the highest priority thread in the specified state and + * associated to the specified object. + * + * @param[in] state thread state + * @param[in] p object pointer + * @return The pointer to the found thread. + * @retval NULL if the thread is not found. + * + * @notapi + */ +thread_t *nil_find_thread(tstate_t state, void *p) { + thread_t *tp = nil.threads; + + while (tp < &nil.threads[CH_CFG_MAX_THREADS]) { + /* Is this thread matching?*/ + if ((tp->state == state) && (tp->u1.p == p)) { + return tp; + } + tp++; + } + return NULL; +} + +/** + * @brief Puts in ready state all thread matching the specified status and + * associated object. + * + * @param[in] p object pointer + * @param[in] cnt number of threads to be readied as a negative number, + * non negative numbers are ignored + * @param[in] msg the wakeup message + * @return The number of readied threads. + * + * @notapi + */ +cnt_t nil_ready_all(void *p, cnt_t cnt, msg_t msg) { + thread_t *tp = nil.threads;; + + while (cnt < (cnt_t)0) { + + chDbgAssert(tp < &nil.threads[CH_CFG_MAX_THREADS], + "pointer out of range"); + + /* Is this thread waiting on this queue?*/ + if ((tp->state == NIL_STATE_WTQUEUE) && (tp->u1.p == p)) { + cnt++; + (void) chSchReadyI(tp, msg); + } + tp++; + } + + return cnt; +} + +#if (CH_DBG_SYSTEM_STATE_CHECK == TRUE) || defined(__DOXYGEN__) +/** + * @brief Guard code for @p chSysDisable(). + * + * @notapi + */ +void _dbg_check_disable(void) { + + if ((nil.isr_cnt != (cnt_t)0) || (nil.lock_cnt != (cnt_t)0)) { + chSysHalt("SV#1"); + } +} + +/** + * @brief Guard code for @p chSysSuspend(). + * + * @notapi + */ +void _dbg_check_suspend(void) { + + if ((nil.isr_cnt != (cnt_t)0) || (nil.lock_cnt != (cnt_t)0)) { + chSysHalt("SV#2"); + } +} + +/** + * @brief Guard code for @p chSysEnable(). + * + * @notapi + */ +void _dbg_check_enable(void) { + + if ((nil.isr_cnt != (cnt_t)0) || (nil.lock_cnt != (cnt_t)0)) { + chSysHalt("SV#3"); + } +} + +/** + * @brief Guard code for @p chSysLock(). + * + * @notapi + */ +void _dbg_check_lock(void) { + + if ((nil.isr_cnt != (cnt_t)0) || (nil.lock_cnt != (cnt_t)0)) { + chSysHalt("SV#4"); + } + _dbg_enter_lock(); +} + +/** + * @brief Guard code for @p chSysUnlock(). + * + * @notapi + */ +void _dbg_check_unlock(void) { + + if ((nil.isr_cnt != (cnt_t)0) || (nil.lock_cnt <= (cnt_t)0)) { + chSysHalt("SV#5"); + } + _dbg_leave_lock(); +} + +/** + * @brief Guard code for @p chSysLockFromIsr(). + * + * @notapi + */ +void _dbg_check_lock_from_isr(void) { + + if ((nil.isr_cnt <= (cnt_t)0) || (nil.lock_cnt != (cnt_t)0)) { + chSysHalt("SV#6"); + } + _dbg_enter_lock(); +} + +/** + * @brief Guard code for @p chSysUnlockFromIsr(). + * + * @notapi + */ +void _dbg_check_unlock_from_isr(void) { + + if ((nil.isr_cnt <= (cnt_t)0) || (nil.lock_cnt <= (cnt_t)0)) { + chSysHalt("SV#7"); + } + _dbg_leave_lock(); +} + +/** + * @brief Guard code for @p CH_IRQ_PROLOGUE(). + * + * @notapi + */ +void _dbg_check_enter_isr(void) { + + port_lock_from_isr(); + if ((nil.isr_cnt < (cnt_t)0) || (nil.lock_cnt != (cnt_t)0)) { + chSysHalt("SV#8"); + } + nil.isr_cnt++; + port_unlock_from_isr(); +} + +/** + * @brief Guard code for @p CH_IRQ_EPILOGUE(). + * + * @notapi + */ +void _dbg_check_leave_isr(void) { + + port_lock_from_isr(); + if ((nil.isr_cnt <= (cnt_t)0) || (nil.lock_cnt != (cnt_t)0)) { + chSysHalt("SV#9"); + } + nil.isr_cnt--; + port_unlock_from_isr(); +} + +/** + * @brief I-class functions context check. + * @details Verifies that the system is in an appropriate state for invoking + * an I-class API function. A panic is generated if the state is + * not compatible. + * + * @api + */ +void chDbgCheckClassI(void) { + + if ((nil.isr_cnt < (cnt_t)0) || (nil.lock_cnt <= (cnt_t)0)) { + chSysHalt("SV#10"); + } +} + +/** + * @brief S-class functions context check. + * @details Verifies that the system is in an appropriate state for invoking + * an S-class API function. A panic is generated if the state is + * not compatible. + * + * @api + */ +void chDbgCheckClassS(void) { + + if ((nil.isr_cnt != (cnt_t)0) || (nil.lock_cnt <= (cnt_t)0)) { + chSysHalt("SV#11"); + } +} +#endif /* CH_DBG_SYSTEM_STATE_CHECK == TRUE */ + +/** + * @brief Initializes the kernel. + * @details Initializes the kernel structures, the current instructions flow + * becomes the idle thread upon return. The idle thread must not + * invoke any kernel primitive able to change state to not runnable. + * @note This function assumes that the @p nil global variable has been + * zeroed by the runtime environment. If this is not the case then + * make sure to clear it before calling this function. + * + * @special + */ +void chSysInit(void) { + const thread_descriptor_t *tdp; + + /* Optional library modules.*/ + _oslib_init(); + + /* Architecture layer initialization.*/ + port_init(); + + /* System initialization hook.*/ + CH_CFG_SYSTEM_INIT_HOOK(); + + /* Making idle the current thread, this may change after rescheduling.*/ + nil.next = nil.current = &nil.threads[CH_CFG_MAX_THREADS]; + nil.current->state = NIL_STATE_READY; + +#if CH_DBG_ENABLE_STACK_CHECK == TRUE + /* The idle thread is a special case because its stack is set up by the + runtime environment.*/ + nil.threads[CH_CFG_MAX_THREADS].wabase = THD_IDLE_BASE; +#endif + + /* Interrupts partially enabled. It is equivalent to entering the + kernel critical zone.*/ + chSysSuspend(); +#if CH_DBG_SYSTEM_STATE_CHECK == TRUE + nil.lock_cnt = (cnt_t)1; +#endif + +#if CH_CFG_AUTOSTART_THREADS == TRUE + /* Iterates through the list of threads to be auto-started.*/ + tdp = nil_thd_configs; + do { + (void) chThdCreateI(tdp); + tdp++; + } while (tdp->funcp != NULL); +#endif + + /* Starting the dance.*/ + chSchRescheduleS(); + chSysUnlock(); +} + +/** + * @brief Halts the system. + * @details This function is invoked by the operating system when an + * unrecoverable error is detected, for example because a programming + * error in the application code that triggers an assertion while + * in debug mode. + * @note Can be invoked from any system state. + * + * @param[in] reason pointer to an error string + * + * @special + */ +void chSysHalt(const char *reason) { + + port_disable(); + +#if NIL_DBG_ENABLED + nil.dbg_panic_msg = reason; +#else + (void)reason; +#endif + + /* Halt hook code, usually empty.*/ + CH_CFG_SYSTEM_HALT_HOOK(reason); + + /* Harmless infinite loop.*/ + while (true) { + } +} + +/** + * @brief Time management handler. + * @note This handler has to be invoked by a periodic ISR in order to + * reschedule the waiting threads. + * + * @iclass + */ +void chSysTimerHandlerI(void) { + + chDbgCheckClassI(); + +#if CH_CFG_ST_TIMEDELTA == 0 + thread_t *tp = &nil.threads[0]; + nil.systime++; + do { + /* Is the thread in a wait state with timeout?.*/ + if (tp->timeout > (sysinterval_t)0) { + + chDbgAssert(!NIL_THD_IS_READY(tp), "is ready"); + + /* Did the timer reach zero?*/ + if (--tp->timeout == (sysinterval_t)0) { + /* Timeout on queues/semaphores requires a special handling because + the counter must be incremented.*/ + /*lint -save -e9013 [15.7] There is no else because it is not needed.*/ +#if CH_CFG_USE_SEMAPHORES == TRUE + if (NIL_THD_IS_WTQUEUE(tp)) { + tp->u1.semp->cnt++; + } + else +#endif + if (NIL_THD_IS_SUSPENDED(tp)) { + *tp->u1.trp = NULL; + } + /*lint -restore*/ + (void) chSchReadyI(tp, MSG_TIMEOUT); + } + } + /* Lock released in order to give a preemption chance on those + architectures supporting IRQ preemption.*/ + chSysUnlockFromISR(); + tp++; + chSysLockFromISR(); + } while (tp < &nil.threads[CH_CFG_MAX_THREADS]); +#else + thread_t *tp = &nil.threads[0]; + sysinterval_t next = (sysinterval_t)0; + + chDbgAssert(nil.nexttime == port_timer_get_alarm(), "time mismatch"); + + do { + sysinterval_t timeout = tp->timeout; + + /* Is the thread in a wait state with timeout?.*/ + if (timeout > (sysinterval_t)0) { + + chDbgAssert(!NIL_THD_IS_READY(tp), "is ready"); + chDbgAssert(timeout >= chTimeDiffX(nil.lasttime, nil.nexttime), + "skipped one"); + + /* The volatile field is updated once, here.*/ + timeout -= chTimeDiffX(nil.lasttime, nil.nexttime); + tp->timeout = timeout; + + if (timeout == (sysinterval_t)0) { + /* Timeout on thread queues requires a special handling because the + counter must be incremented.*/ + if (NIL_THD_IS_WTQUEUE(tp)) { + tp->u1.tqp->cnt++; + } + else { + if (NIL_THD_IS_SUSPENDED(tp)) { + *tp->u1.trp = NULL; + } + } + (void) chSchReadyI(tp, MSG_TIMEOUT); + } + else { + if (timeout <= (sysinterval_t)(next - (sysinterval_t)1)) { + next = timeout; + } + } + } + + /* Lock released in order to give a preemption chance on those + architectures supporting IRQ preemption.*/ + chSysUnlockFromISR(); + tp++; + chSysLockFromISR(); + } while (tp < &nil.threads[CH_CFG_MAX_THREADS]); + + nil.lasttime = nil.nexttime; + if (next > (sysinterval_t)0) { + nil.nexttime = chTimeAddX(nil.nexttime, next); + port_timer_set_alarm(nil.nexttime); + } + else { + /* No tick event needed.*/ + port_timer_stop_alarm(); + } +#endif +} + +/** + * @brief Unconditionally enters the kernel lock state. + * @note Can be called without previous knowledge of the current lock state. + * The final state is "s-locked". + * + * @special + */ +void chSysUnconditionalLock(void) { + + if (port_irq_enabled(port_get_irq_status())) { + chSysLock(); + } +} + +/** + * @brief Unconditionally leaves the kernel lock state. + * @note Can be called without previous knowledge of the current lock state. + * The final state is "normal". + * + * @special + */ +void chSysUnconditionalUnlock(void) { + + if (!port_irq_enabled(port_get_irq_status())) { + chSysUnlock(); + } +} + +/** + * @brief Returns the execution status and enters a critical zone. + * @details This functions enters into a critical zone and can be called + * from any context. Because its flexibility it is less efficient + * than @p chSysLock() which is preferable when the calling context + * is known. + * @post The system is in a critical zone. + * + * @return The previous system status, the encoding of this + * status word is architecture-dependent and opaque. + * + * @xclass + */ +syssts_t chSysGetStatusAndLockX(void) { + + syssts_t sts = port_get_irq_status(); + if (port_irq_enabled(sts)) { + if (port_is_isr_context()) { + chSysLockFromISR(); + } + else { + chSysLock(); + } + } + return sts; +} + +/** + * @brief Restores the specified execution status and leaves a critical zone. + * @note A call to @p chSchRescheduleS() is automatically performed + * if exiting the critical zone and if not in ISR context. + * + * @param[in] sts the system status to be restored. + * + * @xclass + */ +void chSysRestoreStatusX(syssts_t sts) { + + if (port_irq_enabled(sts)) { + if (port_is_isr_context()) { + chSysUnlockFromISR(); + } + else { + chSchRescheduleS(); + chSysUnlock(); + } + } +} + +#if (PORT_SUPPORTS_RT == TRUE) || defined(__DOXYGEN__) +/** + * @brief Realtime window test. + * @details This function verifies if the current realtime counter value + * lies within the specified range or not. The test takes care + * of the realtime counter wrapping to zero on overflow. + * @note When start==end then the function returns always false because a + * null time range is specified. + * @note This function is only available if the port layer supports the + * option @p PORT_SUPPORTS_RT. + * + * @param[in] cnt the counter value to be tested + * @param[in] start the start of the time window (inclusive) + * @param[in] end the end of the time window (non inclusive) + * @retval true current time within the specified time window. + * @retval false current time not within the specified time window. + * + * @xclass + */ +bool chSysIsCounterWithinX(rtcnt_t cnt, rtcnt_t start, rtcnt_t end) { + + return (bool)(((rtcnt_t)cnt - (rtcnt_t)start) < + ((rtcnt_t)end - (rtcnt_t)start)); +} + +/** + * @brief Polled delay. + * @note The real delay is always few cycles in excess of the specified + * value. + * @note This function is only available if the port layer supports the + * option @p PORT_SUPPORTS_RT. + * + * @param[in] cycles number of cycles + * + * @xclass + */ +void chSysPolledDelayX(rtcnt_t cycles) { + rtcnt_t start = chSysGetRealtimeCounterX(); + rtcnt_t end = start + cycles; + + while (chSysIsCounterWithinX(chSysGetRealtimeCounterX(), start, end)) { + } +} +#endif /* PORT_SUPPORTS_RT == TRUE */ + +/** + * @brief Makes the specified thread ready for execution. + * + * @param[in] tp pointer to the @p thread_t object + * @param[in] msg the wakeup message + * + * @return The same reference passed as parameter. + */ +thread_t *chSchReadyI(thread_t *tp, msg_t msg) { + + chDbgCheckClassI(); + chDbgCheck((tp >= nil.threads) && (tp < &nil.threads[CH_CFG_MAX_THREADS])); + chDbgAssert(!NIL_THD_IS_READY(tp), "already ready"); + chDbgAssert(nil.next <= nil.current, "priority ordering"); + + tp->u1.msg = msg; + tp->state = NIL_STATE_READY; + tp->timeout = (sysinterval_t)0; + if (tp < nil.next) { + nil.next = tp; + } + return tp; +} + +/** + * @brief Evaluates if preemption is required. + * @details The decision is taken by comparing the relative priorities and + * depending on the state of the round robin timeout counter. + * @note Not a user function, it is meant to be invoked by the scheduler + * itself or from within the port layer. + * + * @retval true if there is a thread that must go in running state + * immediately. + * @retval false if preemption is not required. + * + * @special + */ +bool chSchIsPreemptionRequired(void) { + + return chSchIsRescRequiredI(); +} + +/** + * @brief Switches to the first thread on the runnable queue. + * @note Not a user function, it is meant to be invoked by the scheduler + * itself or from within the port layer. + * + * @special + */ +void chSchDoReschedule(void) { + thread_t *otp = nil.current; + + nil.current = nil.next; + if (otp == &nil.threads[CH_CFG_MAX_THREADS]) { + CH_CFG_IDLE_LEAVE_HOOK(); + } + port_switch(nil.next, otp); +} + +/** + * @brief Reschedules if needed. + * + * @sclass + */ +void chSchRescheduleS(void) { + + chDbgCheckClassS(); + + if (chSchIsRescRequiredI()) { + chSchDoReschedule(); + } +} + +/** + * @brief Puts the current thread to sleep into the specified state with + * timeout specification. + * @details The thread goes into a sleeping state, if it is not awakened + * explicitly within the specified system time then it is forcibly + * awakened with a @p MSG_TIMEOUT low level message. + * + * @param[in] newstate the new thread state or a semaphore pointer + * @param[in] timeout the number of ticks before the operation timeouts. + * the following special values are allowed: + * - @a TIME_INFINITE no timeout. + * . + * @return The wakeup message. + * @retval MSG_TIMEOUT if a timeout occurred. + * + * @sclass + */ +msg_t chSchGoSleepTimeoutS(tstate_t newstate, sysinterval_t timeout) { + thread_t *ntp, *otp = nil.current; + + chDbgCheckClassS(); + + chDbgAssert(otp != &nil.threads[CH_CFG_MAX_THREADS], + "idle cannot sleep"); + + /* Storing the wait object for the current thread.*/ + otp->state = newstate; + +#if CH_CFG_ST_TIMEDELTA > 0 + if (timeout != TIME_INFINITE) { + systime_t abstime; + + /* TIMEDELTA makes sure to have enough time to reprogram the timer + before the free-running timer counter reaches the selected timeout.*/ + if (timeout < (sysinterval_t)CH_CFG_ST_TIMEDELTA) { + timeout = (sysinterval_t)CH_CFG_ST_TIMEDELTA; + } + + /* Absolute time of the timeout event.*/ + abstime = chTimeAddX(chVTGetSystemTimeX(), timeout); + + if (nil.lasttime == nil.nexttime) { + /* Special case, first thread asking for a timeout.*/ + port_timer_start_alarm(abstime); + nil.nexttime = abstime; + } + else { + /* Special case, there are already other threads with a timeout + activated, evaluating the order.*/ + if (chTimeIsInRangeX(abstime, nil.lasttime, nil.nexttime)) { + port_timer_set_alarm(abstime); + nil.nexttime = abstime; + } + } + + /* Timeout settings.*/ + otp->timeout = abstime - nil.lasttime; + } +#else + + /* Timeout settings.*/ + otp->timeout = timeout; +#endif + + /* Scanning the whole threads array.*/ + ntp = nil.threads; + while (true) { + /* Is this thread ready to execute?*/ + if (NIL_THD_IS_READY(ntp)) { + nil.current = nil.next = ntp; + if (ntp == &nil.threads[CH_CFG_MAX_THREADS]) { + CH_CFG_IDLE_ENTER_HOOK(); + } + port_switch(ntp, otp); + return nil.current->u1.msg; + } + + /* Points to the next thread in lowering priority order.*/ + ntp++; + chDbgAssert(ntp <= &nil.threads[CH_CFG_MAX_THREADS], + "pointer out of range"); + } +} + +/** + * @brief Checks if the specified time is within the specified time range. + * @note When start==end then the function returns always false because the + * time window has zero size. + * + * @param[in] time the time to be verified + * @param[in] start the start of the time window (inclusive) + * @param[in] end the end of the time window (non inclusive) + * @retval true current time within the specified time window. + * @retval false current time not within the specified time window. + * + * @xclass + */ +bool chTimeIsInRangeX(systime_t time, systime_t start, systime_t end) { + + return (bool)((systime_t)((systime_t)(time) - (systime_t)(start)) < + (systime_t)((systime_t)(end) - (systime_t)(start))); +} + +/** + * @brief Creates a new thread into a static memory area. + * @details The new thread is initialized and make ready to execute. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. + * + * @param[out] tdp pointer to the thread descriptor structure + * @return The pointer to the @p thread_t structure allocated for + * the thread. + * + * @iclass + */ +thread_t *chThdCreateI(const thread_descriptor_t *tdp) { + thread_t *tp; + + chDbgCheck((tdp->prio < (tprio_t)CH_CFG_MAX_THREADS) && + (tdp->wbase != NULL) && + MEM_IS_ALIGNED(tdp->wbase, PORT_WORKING_AREA_ALIGN) && + (tdp->wend > tdp->wbase) && + MEM_IS_ALIGNED(tdp->wbase, PORT_STACK_ALIGN) && + (tdp->funcp != NULL)); + + chDbgCheckClassI(); + + /* Pointer to the thread slot to be used.*/ + tp = &nil.threads[tdp->prio]; + chDbgAssert(NIL_THD_IS_WTSTART(tp) || NIL_THD_IS_FINAL(tp), + "priority slot taken"); + +#if CH_CFG_USE_EVENTS == TRUE + tp->epmask = (eventmask_t)0; +#endif +#if CH_DBG_ENABLE_STACK_CHECK == TRUE + tp->wabase = (stkalign_t *)tdp->wbase; +#endif + + /* Port dependent thread initialization.*/ + PORT_SETUP_CONTEXT(tp, tdp->wbase, tdp->wend, tdp->funcp, tdp->arg); + + /* Initialization hook.*/ + CH_CFG_THREAD_EXT_INIT_HOOK(tp); + + /* Readying up thread.*/ + return chSchReadyI(tp, MSG_OK); +} + +/** + * @brief Creates a new thread into a static memory area. + * @details The new thread is initialized and make ready to execute. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. + * + * @param[out] tdp pointer to the thread descriptor structure + * @return The pointer to the @p thread_t structure allocated for + * the thread. + * + * @api + */ +thread_t *chThdCreate(const thread_descriptor_t *tdp) { + thread_t *tp; + + chSysLock(); + tp = chThdCreateI(tdp); + chSchRescheduleS(); + chSysUnlock(); + + return tp; +} + +/** + * @brief Terminates the current thread. + * @details The thread goes in the @p CH_STATE_FINAL state holding the + * specified exit status code, other threads can retrieve the + * exit status code by invoking the function @p chThdWait(). + * @post Exiting a non-static thread that does not have references + * (detached) causes the thread to remain in the registry. + * It can only be removed by performing a registry scan operation. + * @post Eventual code after this function will never be executed, + * this function never returns. The compiler has no way to + * know this so do not assume that the compiler would remove + * the dead code. + * + * @param[in] msg thread exit code + * + * @api + */ +void chThdExit(msg_t msg) { + + chSysLock(); + + /* Exit handler hook.*/ + CH_CFG_THREAD_EXIT_HOOK(nil.current); + +#if CH_CFG_USE_WAITEXIT == TRUE + { + /* Waking up any waiting thread.*/ + thread_t *tp = nil.threads; + while (tp < &nil.threads[CH_CFG_MAX_THREADS]) { + /* Is this thread waiting for current thread termination?*/ + if ((tp->state == NIL_STATE_WTEXIT) && (tp->u1.tp == nil.current)) { + (void) chSchReadyI(tp, msg); + } + tp++; + } + } +#endif + + /* Going into final state with exit message stored.*/ + nil.current->u1.msg = msg; + (void) chSchGoSleepTimeoutS(NIL_STATE_FINAL, TIME_INFINITE); + + /* The thread never returns here.*/ + chDbgAssert(false, "zombies apocalypse"); +} + +/** + * @brief Blocks the execution of the invoking thread until the specified + * thread terminates then the exit code is returned. + * + * @param[in] tp pointer to the thread + * @return The exit code from the terminated thread. + * + * @api + */ +msg_t chThdWait(thread_t *tp) { + msg_t msg; + + chSysLock(); + if (NIL_THD_IS_FINAL(tp)) { + msg = tp->u1.msg; + } + else { + nil.current->u1.tp = tp; + msg = chSchGoSleepTimeoutS(NIL_STATE_WTEXIT, TIME_INFINITE); + } + chSysUnlock(); + + return msg; +} + +/** + * @brief Sends the current thread sleeping and sets a reference variable. + * @note This function must reschedule, it can only be called from thread + * context. + * + * @param[in] trp a pointer to a thread reference object + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The wake up message. + * + * @sclass + */ +msg_t chThdSuspendTimeoutS(thread_reference_t *trp, sysinterval_t timeout) { + + chDbgAssert(*trp == NULL, "not NULL"); + + if (TIME_IMMEDIATE == timeout) { + return MSG_TIMEOUT; + } + + *trp = nil.current; + nil.current->u1.trp = trp; + return chSchGoSleepTimeoutS(NIL_STATE_SUSPENDED, timeout); +} + +/** + * @brief Wakes up a thread waiting on a thread reference object. + * @note This function must not reschedule because it can be called from + * ISR context. + * + * @param[in] trp a pointer to a thread reference object + * @param[in] msg the message code + * + * @iclass + */ +void chThdResumeI(thread_reference_t *trp, msg_t msg) { + + if (*trp != NULL) { + thread_reference_t tr = *trp; + + chDbgAssert(NIL_THD_IS_SUSPENDED(tr), "not suspended"); + + *trp = NULL; + (void) chSchReadyI(tr, msg); + } +} + +/** + * @brief Wakes up a thread waiting on a thread reference object. + * @note This function must reschedule, it can only be called from thread + * context. + * + * @param[in] trp a pointer to a thread reference object + * @param[in] msg the message code + * + * @api + */ +void chThdResume(thread_reference_t *trp, msg_t msg) { + + chSysLock(); + chThdResumeS(trp, msg); + chSysUnlock(); +} + +/** + * @brief Suspends the invoking thread for the specified time. + * + * @param[in] timeout the delay in system ticks + * + * @api + */ +void chThdSleep(sysinterval_t timeout) { + + chSysLock(); + chThdSleepS(timeout); + chSysUnlock(); +} + +/** + * @brief Suspends the invoking thread until the system time arrives to the + * specified value. + * + * @param[in] abstime absolute system time + * + * @api + */ +void chThdSleepUntil(systime_t abstime) { + + chSysLock(); + chThdSleepUntilS(abstime); + chSysUnlock(); +} + +/** + * @brief Enqueues the caller thread on a threads queue object. + * @details The caller thread is enqueued and put to sleep until it is + * dequeued or the specified timeouts expires. + * + * @param[in] tqp pointer to the threads queue object + * @param[in] timeout the timeout in system ticks, the special values are + * handled as follow: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The message from @p osalQueueWakeupOneI() or + * @p osalQueueWakeupAllI() functions. + * @retval MSG_TIMEOUT if the thread has not been dequeued within the + * specified timeout or if the function has been + * invoked with @p TIME_IMMEDIATE as timeout + * specification. + * + * @sclass + */ +msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout) { + + chDbgCheckClassS(); + chDbgCheck(tqp != NULL); + + chDbgAssert(tqp->cnt <= (cnt_t)0, "invalid counter"); + + if (TIME_IMMEDIATE == timeout) { + return MSG_TIMEOUT; + } + + tqp->cnt--; + nil.current->u1.tqp = tqp; + return chSchGoSleepTimeoutS(NIL_STATE_WTQUEUE, timeout); +} + +/** + * @brief Dequeues and wakes up one thread from the threads queue object. + * @details Dequeues one thread from the queue without checking if the queue + * is empty. + * @pre The queue must contain at least an object. + * + * @param[in] tqp pointer to the threads queue object + * @param[in] msg the message code + * + * @iclass + */ +void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg) { + thread_t *tp; + + chDbgAssert(tqp->cnt < (cnt_t)0, "empty queue"); + + tqp->cnt++; + tp = nil_find_thread(NIL_STATE_WTQUEUE, (void *)tqp); + + chDbgAssert(tp != NULL, "thread not found"); + + (void) chSchReadyI(tp, msg); +} + +/** + * @brief Dequeues and wakes up one thread from the threads queue object, + * if any. + * + * @param[in] tqp pointer to the threads queue object + * @param[in] msg the message code + * + * @iclass + */ +void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg) { + + chDbgCheckClassI(); + chDbgCheck(tqp != NULL); + + if (tqp->cnt < (cnt_t)0) { + chThdDoDequeueNextI(tqp, msg); + } +} + +/** + * @brief Dequeues and wakes up all threads from the threads queue object. + * + * @param[in] tqp pointer to the threads queue object + * @param[in] msg the message code + * + * @iclass + */ +void chThdDequeueAllI(threads_queue_t *tqp, msg_t msg) { + + chDbgCheckClassI(); + chDbgCheck(tqp != NULL); + + tqp->cnt = nil_ready_all((void *)tqp, tqp->cnt, msg); +} + +/** @} */ diff --git a/readme.txt b/readme.txt index 155297f71e..46f03c0084 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed wrong use of hooks in RT/NIL (bug #1251). - FIX: Fixed wrong initialization in STM32L1xx ADC driver (bug #1247). - FIX: Fixed wrong HSI48 support on STM32L0xx (bug #1246). - FIX: Fixed wrong DMA definitions for STM32L0xx I2C3 peripheral (bug #1245). From ca2dfc51247f492f1220a25d1ad8f59871068cc9 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Fri, 3 Mar 2023 07:34:57 +0000 Subject: [PATCH 16/53] Fixed harmless warning with GCC 12. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16123 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/src/hal_buffers.c | 1 + 1 file changed, 1 insertion(+) diff --git a/os/hal/src/hal_buffers.c b/os/hal/src/hal_buffers.c index 6020df41a9..80e70e3bb0 100644 --- a/os/hal/src/hal_buffers.c +++ b/os/hal/src/hal_buffers.c @@ -489,6 +489,7 @@ uint8_t *obqGetFullBufferI(output_buffers_queue_t *obqp, osalDbgCheckClassI(); if (obqIsEmptyI(obqp)) { + *sizep = 0U; return NULL; } From f6fe09b921956dea8527686e1a7acec3a226fe40 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Fri, 3 Mar 2023 10:10:20 +0000 Subject: [PATCH 17/53] Fixed bug #1252. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16124 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c | 2543 ++++++++++---------- os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h | 1212 +++++----- os/hal/ports/STM32/LLD/OTGv1/stm32_otg.h | 1858 +++++++------- readme.txt | 1 + 4 files changed, 2819 insertions(+), 2795 deletions(-) diff --git a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c index 43ad6ddce7..0a2e674696 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c +++ b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c @@ -1,1264 +1,1279 @@ -/* - ChibiOS - Copyright (C) 2006..2018 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 OTGv1/hal_usb_lld.c - * @brief STM32 USB subsystem low level driver source. - * - * @addtogroup USB - * @{ - */ - -#include - -#include "hal.h" - -#if HAL_USE_USB || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -#define TRDT_VALUE_FS 5 -#define TRDT_VALUE_HS 9 - -#define EP0_MAX_INSIZE 64 -#define EP0_MAX_OUTSIZE 64 - -#if STM32_OTG_STEPPING == 1 -#if defined(BOARD_OTG_NOVBUSSENS) -#define GCCFG_INIT_VALUE (GCCFG_NOVBUSSENS | GCCFG_VBUSASEN | \ - GCCFG_VBUSBSEN | GCCFG_PWRDWN) -#else -#define GCCFG_INIT_VALUE (GCCFG_VBUSASEN | GCCFG_VBUSBSEN | \ - GCCFG_PWRDWN) -#endif - -#elif STM32_OTG_STEPPING == 2 -#if defined(BOARD_OTG_NOVBUSSENS) -#define GCCFG_INIT_VALUE GCCFG_PWRDWN -#else -#define GCCFG_INIT_VALUE (GCCFG_VBDEN | GCCFG_PWRDWN) -#endif - -#endif - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** @brief OTG_FS driver identifier.*/ -#if STM32_USB_USE_OTG1 || defined(__DOXYGEN__) -USBDriver USBD1; -#endif - -/** @brief OTG_HS driver identifier.*/ -#if STM32_USB_USE_OTG2 || defined(__DOXYGEN__) -USBDriver USBD2; -#endif - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/** - * @brief EP0 state. - * @note It is an union because IN and OUT endpoints are never used at the - * same time for EP0. - */ -static union { - /** - * @brief IN EP0 state. - */ - USBInEndpointState in; - /** - * @brief OUT EP0 state. - */ - USBOutEndpointState out; -} ep0_state; - -/** - * @brief Buffer for the EP0 setup packets. - */ -static uint8_t ep0setup_buffer[8]; - -/** - * @brief EP0 initialization structure. - */ -static const USBEndpointConfig ep0config = { - USB_EP_MODE_TYPE_CTRL, - _usb_ep0setup, - _usb_ep0in, - _usb_ep0out, - 0x40, - 0x40, - &ep0_state.in, - &ep0_state.out, - 1, - ep0setup_buffer -}; - -#if STM32_USB_USE_OTG1 -static const stm32_otg_params_t fsparams = { - STM32_USB_OTG1_RX_FIFO_SIZE / 4, - STM32_OTG1_FIFO_MEM_SIZE, - STM32_OTG1_ENDPOINTS -}; -#endif - -#if STM32_USB_USE_OTG2 -static const stm32_otg_params_t hsparams = { - STM32_USB_OTG2_RX_FIFO_SIZE / 4, - STM32_OTG2_FIFO_MEM_SIZE, - STM32_OTG2_ENDPOINTS -}; -#endif - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -static void otg_core_reset(USBDriver *usbp) { - stm32_otg_t *otgp = usbp->otg; - - /* Wait AHB idle condition.*/ - while ((otgp->GRSTCTL & GRSTCTL_AHBIDL) == 0) - ; - - /* Core reset and delay of at least 3 PHY cycles.*/ - otgp->GRSTCTL = GRSTCTL_CSRST; - osalSysPolledDelayX(12); - while ((otgp->GRSTCTL & GRSTCTL_CSRST) != 0) - ; - - osalSysPolledDelayX(18); - - /* Wait AHB idle condition again.*/ - while ((otgp->GRSTCTL & GRSTCTL_AHBIDL) == 0) - ; -} - -static void otg_disable_ep(USBDriver *usbp) { - stm32_otg_t *otgp = usbp->otg; - unsigned i; - - for (i = 0; i <= usbp->otgparams->num_endpoints; i++) { - - if ((otgp->ie[i].DIEPCTL & DIEPCTL_EPENA) != 0U) { - otgp->ie[i].DIEPCTL |= DIEPCTL_EPDIS; - } - - if ((otgp->oe[i].DOEPCTL & DIEPCTL_EPENA) != 0U) { - otgp->oe[i].DOEPCTL |= DIEPCTL_EPDIS; - } - - otgp->ie[i].DIEPINT = 0xFFFFFFFF; - otgp->oe[i].DOEPINT = 0xFFFFFFFF; - } - otgp->DAINTMSK = DAINTMSK_OEPM(0) | DAINTMSK_IEPM(0); -} - -static void otg_rxfifo_flush(USBDriver *usbp) { - stm32_otg_t *otgp = usbp->otg; - - otgp->GRSTCTL = GRSTCTL_RXFFLSH; - while ((otgp->GRSTCTL & GRSTCTL_RXFFLSH) != 0) - ; - /* Wait for 3 PHY Clocks.*/ - osalSysPolledDelayX(18); -} - -static void otg_txfifo_flush(USBDriver *usbp, uint32_t fifo) { - stm32_otg_t *otgp = usbp->otg; - - otgp->GRSTCTL = GRSTCTL_TXFNUM(fifo) | GRSTCTL_TXFFLSH; - while ((otgp->GRSTCTL & GRSTCTL_TXFFLSH) != 0) - ; - /* Wait for 3 PHY Clocks.*/ - osalSysPolledDelayX(18); -} - -/** - * @brief Resets the FIFO RAM memory allocator. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -static void otg_ram_reset(USBDriver *usbp) { - - usbp->pmnext = usbp->otgparams->rx_fifo_size; -} - -/** - * @brief Allocates a block from the FIFO RAM memory. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] size size of the packet buffer to allocate in words - * - * @notapi - */ -static uint32_t otg_ram_alloc(USBDriver *usbp, size_t size) { - uint32_t next; - - next = usbp->pmnext; - usbp->pmnext += size; - osalDbgAssert(usbp->pmnext <= usbp->otgparams->otg_ram_size, - "OTG FIFO memory overflow"); - return next; -} - -/** - * @brief Writes to a TX FIFO. - * - * @param[in] fifop pointer to the FIFO register - * @param[in] buf buffer where to copy the endpoint data - * @param[in] n maximum number of bytes to copy - * - * @notapi - */ -static void otg_fifo_write_from_buffer(volatile uint32_t *fifop, - const uint8_t *buf, - size_t n) { - - osalDbgAssert(n > 0, "is zero"); - - while (true) { - *fifop = *((uint32_t *)buf); - if (n <= 4) { - break; - } - n -= 4; - buf += 4; - } -} - -/** - * @brief Reads a packet from the RXFIFO. - * - * @param[in] fifop pointer to the FIFO register - * @param[out] buf buffer where to copy the endpoint data - * @param[in] n number of bytes to pull from the FIFO - * @param[in] max number of bytes to copy into the buffer - * - * @notapi - */ -static void otg_fifo_read_to_buffer(volatile uint32_t *fifop, - uint8_t *buf, - size_t n, - size_t max) { - uint32_t w = 0; - size_t i = 0; - - while (i < n) { - if ((i & 3) == 0) { - w = *fifop; - } - if (i < max) { - *buf++ = (uint8_t)w; - w >>= 8; - } - i++; - } -} - -/** - * @brief Incoming packets handler. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -static void otg_rxfifo_handler(USBDriver *usbp) { - uint32_t sts, cnt, ep; - - /* Popping the event word out of the RX FIFO.*/ - sts = usbp->otg->GRXSTSP; - - /* Event details.*/ - cnt = (sts & GRXSTSP_BCNT_MASK) >> GRXSTSP_BCNT_OFF; - ep = (sts & GRXSTSP_EPNUM_MASK) >> GRXSTSP_EPNUM_OFF; - - switch (sts & GRXSTSP_PKTSTS_MASK) { - case GRXSTSP_SETUP_DATA: - otg_fifo_read_to_buffer(usbp->otg->FIFO[0], usbp->epc[ep]->setup_buf, - cnt, 8); - break; - case GRXSTSP_SETUP_COMP: - break; - case GRXSTSP_OUT_DATA: - otg_fifo_read_to_buffer(usbp->otg->FIFO[0], - usbp->epc[ep]->out_state->rxbuf, - cnt, - usbp->epc[ep]->out_state->rxsize - - usbp->epc[ep]->out_state->rxcnt); - usbp->epc[ep]->out_state->rxbuf += cnt; - usbp->epc[ep]->out_state->rxcnt += cnt; - break; - case GRXSTSP_OUT_COMP: - break; - case GRXSTSP_OUT_GLOBAL_NAK: - break; - default: - break; - } -} - -/** - * @brief Outgoing packets handler. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -static bool otg_txfifo_handler(USBDriver *usbp, usbep_t ep) { - - /* The TXFIFO is filled until there is space and data to be transmitted.*/ - while (true) { - uint32_t n; - - /* Transaction end condition.*/ - if (usbp->epc[ep]->in_state->txcnt >= usbp->epc[ep]->in_state->txsize) { -#if 1 - usbp->otg->DIEPEMPMSK &= ~DIEPEMPMSK_INEPTXFEM(ep); -#endif - return true; - } - - /* Number of bytes remaining in current transaction.*/ - n = usbp->epc[ep]->in_state->txsize - usbp->epc[ep]->in_state->txcnt; - if (n > usbp->epc[ep]->in_maxsize) - n = usbp->epc[ep]->in_maxsize; - - /* Checks if in the TXFIFO there is enough space to accommodate the - next packet.*/ - if (((usbp->otg->ie[ep].DTXFSTS & DTXFSTS_INEPTFSAV_MASK) * 4) < n) - return false; - -#if STM32_USB_OTGFIFO_FILL_BASEPRI - __set_BASEPRI(CORTEX_PRIO_MASK(STM32_USB_OTGFIFO_FILL_BASEPRI)); -#endif - otg_fifo_write_from_buffer(usbp->otg->FIFO[ep], - usbp->epc[ep]->in_state->txbuf, - n); - usbp->epc[ep]->in_state->txbuf += n; - usbp->epc[ep]->in_state->txcnt += n; -#if STM32_USB_OTGFIFO_FILL_BASEPRI - __set_BASEPRI(0); -#endif - } -} - -/** - * @brief Generic endpoint IN handler. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -static void otg_epin_handler(USBDriver *usbp, usbep_t ep) { - stm32_otg_t *otgp = usbp->otg; - uint32_t epint = otgp->ie[ep].DIEPINT; - - otgp->ie[ep].DIEPINT = epint; - - if (epint & DIEPINT_TOC) { - /* Timeouts not handled yet, not sure how to handle.*/ - } - if ((epint & DIEPINT_XFRC) && (otgp->DIEPMSK & DIEPMSK_XFRCM)) { - /* Transmit transfer complete.*/ - USBInEndpointState *isp = usbp->epc[ep]->in_state; - - if (isp->txsize < isp->totsize) { - /* In case the transaction covered only part of the total transfer - then another transaction is immediately started in order to - cover the remaining.*/ - isp->txsize = isp->totsize - isp->txsize; - isp->txcnt = 0; - osalSysLockFromISR(); - usb_lld_start_in(usbp, ep); - osalSysUnlockFromISR(); - } - else { - /* End on IN transfer.*/ - _usb_isr_invoke_in_cb(usbp, ep); - } - } - if ((epint & DIEPINT_TXFE) && - (otgp->DIEPEMPMSK & DIEPEMPMSK_INEPTXFEM(ep))) { - /* TX FIFO empty or emptying.*/ - otg_txfifo_handler(usbp, ep); - } -} - -/** - * @brief Generic endpoint OUT handler. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -static void otg_epout_handler(USBDriver *usbp, usbep_t ep) { - stm32_otg_t *otgp = usbp->otg; - uint32_t epint = otgp->oe[ep].DOEPINT; - - /* Resets all EP IRQ sources.*/ - otgp->oe[ep].DOEPINT = epint; - - if ((epint & DOEPINT_STUP) && (otgp->DOEPMSK & DOEPMSK_STUPM)) { - /* Setup packets handling, setup packets are handled using a - specific callback.*/ - _usb_isr_invoke_setup_cb(usbp, ep); - } - - if ((epint & DOEPINT_XFRC) && (otgp->DOEPMSK & DOEPMSK_XFRCM)) { - USBOutEndpointState *osp; - - /* OUT state structure pointer for this endpoint.*/ - osp = usbp->epc[ep]->out_state; - - /* EP0 requires special handling.*/ - if (ep == 0) { - -#if defined(STM32_OTG_SEQUENCE_WORKAROUND) - /* If an OUT transaction end interrupt is processed while the state - machine is not in an OUT state then it is ignored, this is caused - on some devices (L4) apparently injecting spurious data complete - words in the RX FIFO.*/ - if ((usbp->ep0state & USB_OUT_STATE) == 0) - return; -#endif - - /* In case the transaction covered only part of the total transfer - then another transaction is immediately started in order to - cover the remaining.*/ - if (((osp->rxcnt % usbp->epc[ep]->out_maxsize) == 0) && - (osp->rxsize < osp->totsize)) { - osp->rxsize = osp->totsize - osp->rxsize; - osp->rxcnt = 0; - osalSysLockFromISR(); - usb_lld_start_out(usbp, ep); - osalSysUnlockFromISR(); - return; - } - } - - /* End on OUT transfer.*/ - _usb_isr_invoke_out_cb(usbp, ep); - } -} - -/** - * @brief Isochronous IN transfer failed handler. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -static void otg_isoc_in_failed_handler(USBDriver *usbp) { - usbep_t ep; - stm32_otg_t *otgp = usbp->otg; - - for (ep = 0; ep <= usbp->otgparams->num_endpoints; ep++) { - if (((otgp->ie[ep].DIEPCTL & DIEPCTL_EPTYP_MASK) == DIEPCTL_EPTYP_ISO) && - ((otgp->ie[ep].DIEPCTL & DIEPCTL_EPENA) != 0)) { - /* Endpoint enabled -> ISOC IN transfer failed.*/ - /* Disable endpoint.*/ - otgp->ie[ep].DIEPCTL |= (DIEPCTL_EPDIS | DIEPCTL_SNAK); - while (otgp->ie[ep].DIEPCTL & DIEPCTL_EPENA) - ; - - /* Flush FIFO.*/ - otg_txfifo_flush(usbp, ep); - - /* Prepare data for next frame.*/ - _usb_isr_invoke_in_cb(usbp, ep); - } - } -} - -/** - * @brief Isochronous OUT transfer failed handler. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -static void otg_isoc_out_failed_handler(USBDriver *usbp) { - usbep_t ep; - stm32_otg_t *otgp = usbp->otg; - - for (ep = 0; ep <= usbp->otgparams->num_endpoints; ep++) { - if (((otgp->oe[ep].DOEPCTL & DOEPCTL_EPTYP_MASK) == DOEPCTL_EPTYP_ISO) && - ((otgp->oe[ep].DOEPCTL & DOEPCTL_EPENA) != 0)) { -#if 0 - /* Endpoint enabled -> ISOC OUT transfer failed.*/ - /* Disable endpoint.*/ - /* CHTODO:: Core stucks here */ - otgp->oe[ep].DOEPCTL |= (DOEPCTL_EPDIS | DOEPCTL_SNAK); - while (otgp->oe[ep].DOEPCTL & DOEPCTL_EPENA) - ; -#endif - /* Prepare transfer for next frame.*/ - _usb_isr_invoke_out_cb(usbp, ep); - } - } -} - -/** - * @brief OTG shared ISR. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -static void usb_lld_serve_interrupt(USBDriver *usbp) { - stm32_otg_t *otgp = usbp->otg; - uint32_t sts, src; - - sts = otgp->GINTSTS; - sts &= otgp->GINTMSK; - otgp->GINTSTS = sts; - - /* Reset interrupt handling.*/ - if (sts & GINTSTS_USBRST) { - /* Default reset action.*/ - _usb_reset(usbp); - - /* Preventing execution of more handlers, the core has been reset.*/ - return; - } - - /* Wake-up handling.*/ - if (sts & GINTSTS_WKUPINT) { - /* If clocks are gated off, turn them back on (may be the case if - coming out of suspend mode).*/ - if (otgp->PCGCCTL & (PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK)) { - /* Set to zero to un-gate the USB core clocks.*/ - otgp->PCGCCTL &= ~(PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK); - } - - /* Clear the Remote Wake-up Signaling.*/ - otgp->DCTL &= ~DCTL_RWUSIG; - - _usb_wakeup(usbp); - } - - /* Suspend handling.*/ - if (sts & GINTSTS_USBSUSP) { - /* Stopping all ongoing transfers.*/ - otg_disable_ep(usbp); - - /* Default suspend action.*/ - _usb_suspend(usbp); - } - - /* Enumeration done.*/ - if (sts & GINTSTS_ENUMDNE) { - /* Full or High speed timing selection.*/ - if ((otgp->DSTS & DSTS_ENUMSPD_MASK) == DSTS_ENUMSPD_HS_480) { - otgp->GUSBCFG = (otgp->GUSBCFG & ~(GUSBCFG_TRDT_MASK)) | - GUSBCFG_TRDT(TRDT_VALUE_HS); - } - else { - otgp->GUSBCFG = (otgp->GUSBCFG & ~(GUSBCFG_TRDT_MASK)) | - GUSBCFG_TRDT(TRDT_VALUE_FS); - } - } - - /* SOF interrupt handling.*/ - if (sts & GINTSTS_SOF) { - _usb_isr_invoke_sof_cb(usbp); - } - - /* Isochronous IN failed handling */ - if (sts & GINTSTS_IISOIXFR) { - otg_isoc_in_failed_handler(usbp); - } - - /* Isochronous OUT failed handling */ - if (sts & GINTSTS_IISOOXFR) { - otg_isoc_out_failed_handler(usbp); - } - - /* Performing the whole FIFO emptying in the ISR, it is advised to keep - this IRQ at a very low priority level.*/ - if ((sts & GINTSTS_RXFLVL) != 0U) { - otg_rxfifo_handler(usbp); - } - - /* IN/OUT endpoints event handling.*/ - src = otgp->DAINT; - if (sts & GINTSTS_OEPINT) { - if (src & (1 << 16)) - otg_epout_handler(usbp, 0); - if (src & (1 << 17)) - otg_epout_handler(usbp, 1); - if (src & (1 << 18)) - otg_epout_handler(usbp, 2); - if (src & (1 << 19)) - otg_epout_handler(usbp, 3); -#if USB_MAX_ENDPOINTS >= 4 - if (src & (1 << 20)) - otg_epout_handler(usbp, 4); -#endif -#if USB_MAX_ENDPOINTS >= 5 - if (src & (1 << 21)) - otg_epout_handler(usbp, 5); -#endif -#if USB_MAX_ENDPOINTS >= 6 - if (src & (1 << 22)) - otg_epout_handler(usbp, 6); -#endif -#if USB_MAX_ENDPOINTS >= 7 - if (src & (1 << 23)) - otg_epout_handler(usbp, 7); -#endif -#if USB_MAX_ENDPOINTS >= 8 - if (src & (1 << 24)) - otg_epout_handler(usbp, 8); -#endif - } - if (sts & GINTSTS_IEPINT) { - if (src & (1 << 0)) - otg_epin_handler(usbp, 0); - if (src & (1 << 1)) - otg_epin_handler(usbp, 1); - if (src & (1 << 2)) - otg_epin_handler(usbp, 2); - if (src & (1 << 3)) - otg_epin_handler(usbp, 3); -#if USB_MAX_ENDPOINTS >= 4 - if (src & (1 << 4)) - otg_epin_handler(usbp, 4); -#endif -#if USB_MAX_ENDPOINTS >= 5 - if (src & (1 << 5)) - otg_epin_handler(usbp, 5); -#endif -#if USB_MAX_ENDPOINTS >= 6 - if (src & (1 << 6)) - otg_epin_handler(usbp, 6); -#endif -#if USB_MAX_ENDPOINTS >= 7 - if (src & (1 << 7)) - otg_epin_handler(usbp, 7); -#endif -#if USB_MAX_ENDPOINTS >= 8 - if (src & (1 << 8)) - otg_epin_handler(usbp, 8); -#endif - } -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if STM32_USB_USE_OTG1 || defined(__DOXYGEN__) -/** - * @brief OTG1 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_OTG1_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - usb_lld_serve_interrupt(&USBD1); - - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if STM32_USB_USE_OTG2 || defined(__DOXYGEN__) -/** - * @brief OTG2 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_OTG2_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - usb_lld_serve_interrupt(&USBD2); - - OSAL_IRQ_EPILOGUE(); -} -#endif - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level USB driver initialization. - * - * @notapi - */ -void usb_lld_init(void) { - - /* Driver initialization.*/ -#if STM32_USB_USE_OTG1 - usbObjectInit(&USBD1); - USBD1.otg = OTG_FS; - USBD1.otgparams = &fsparams; - -#endif - -#if STM32_USB_USE_OTG2 - usbObjectInit(&USBD2); - USBD2.otg = OTG_HS; - USBD2.otgparams = &hsparams; -#endif -} - -/** - * @brief Configures and activates the USB peripheral. - * @note Starting the OTG cell can be a slow operation carried out with - * interrupts disabled, perform it before starting time-critical - * operations. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void usb_lld_start(USBDriver *usbp) { - stm32_otg_t *otgp = usbp->otg; - - if (usbp->state == USB_STOP) { - /* Clock activation.*/ - -#if STM32_USB_USE_OTG1 - if (&USBD1 == usbp) { - /* OTG FS clock enable and reset.*/ - rccEnableOTG_FS(true); - rccResetOTG_FS(); - - /* Enables IRQ vector.*/ - nvicEnableVector(STM32_OTG1_NUMBER, STM32_USB_OTG1_IRQ_PRIORITY); - - /* - Forced device mode. - - USB turn-around time = TRDT_VALUE_FS. - - Full Speed 1.1 PHY.*/ - otgp->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE_FS) | - GUSBCFG_PHYSEL; - - /* 48MHz 1.1 PHY.*/ - otgp->DCFG = 0x02200000 | DCFG_DSPD_FS11; - } -#endif - -#if STM32_USB_USE_OTG2 - if (&USBD2 == usbp) { - /* OTG HS clock enable and reset.*/ - rccEnableOTG_HS(true); - rccResetOTG_HS(); - - /* ULPI clock is managed depending on the presence of an external - PHY.*/ -#if defined(BOARD_OTG2_USES_ULPI) - rccEnableOTG_HSULPI(true); -#else - /* Workaround for the problem described here: - http://forum.chibios.org/phpbb/viewtopic.php?f=16&t=1798.*/ - rccDisableOTG_HSULPI(); -#endif - - /* Enables IRQ vector.*/ - nvicEnableVector(STM32_OTG2_NUMBER, STM32_USB_OTG2_IRQ_PRIORITY); - - /* - Forced device mode. - - USB turn-around time = TRDT_VALUE_HS or TRDT_VALUE_FS.*/ -#if defined(BOARD_OTG2_USES_ULPI) - /* High speed ULPI PHY.*/ - otgp->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE_HS) | - GUSBCFG_SRPCAP | GUSBCFG_HNPCAP; -#else - otgp->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE_FS) | - GUSBCFG_PHYSEL; -#endif - -#if defined(BOARD_OTG2_USES_ULPI) -#if STM32_USE_USB_OTG2_HS - /* USB 2.0 High Speed PHY in HS mode.*/ - otgp->DCFG = 0x02200000 | DCFG_DSPD_HS; -#else - /* USB 2.0 High Speed PHY in FS mode.*/ - otgp->DCFG = 0x02200000 | DCFG_DSPD_HS_FS; -#endif -#else - /* 48MHz 1.1 PHY.*/ - otgp->DCFG = 0x02200000 | DCFG_DSPD_FS11; -#endif - } -#endif - - /* PHY enabled.*/ - otgp->PCGCCTL = 0; - - /* VBUS sensing and transceiver enabled.*/ - otgp->GOTGCTL = GOTGCTL_BVALOEN | GOTGCTL_BVALOVAL; - -#if defined(BOARD_OTG2_USES_ULPI) -#if STM32_USB_USE_OTG1 - if (&USBD1 == usbp) { - otgp->GCCFG = GCCFG_INIT_VALUE; - } -#endif - -#if STM32_USB_USE_OTG2 - if (&USBD2 == usbp) { - otgp->GCCFG = 0; - } -#endif -#else - otgp->GCCFG = GCCFG_INIT_VALUE; -#endif - - /* Soft core reset.*/ - otg_core_reset(usbp); - - /* Interrupts on TXFIFOs half empty.*/ - otgp->GAHBCFG = 0; - - /* Endpoints re-initialization.*/ - otg_disable_ep(usbp); - - /* Clear all pending Device Interrupts, only the USB Reset interrupt - is required initially.*/ - otgp->DIEPMSK = 0; - otgp->DOEPMSK = 0; - otgp->DAINTMSK = 0; - if (usbp->config->sof_cb == NULL) - otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM | GINTMSK_USBSUSPM | - GINTMSK_ESUSPM | GINTMSK_SRQM | GINTMSK_WKUM | - GINTMSK_IISOIXFRM | GINTMSK_IISOOXFRM; - else - otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM | GINTMSK_USBSUSPM | - GINTMSK_ESUSPM | GINTMSK_SRQM | GINTMSK_WKUM | - GINTMSK_IISOIXFRM | GINTMSK_IISOOXFRM | - GINTMSK_SOFM; - - /* Clears all pending IRQs, if any. */ - otgp->GINTSTS = 0xFFFFFFFF; - - /* Global interrupts enable.*/ - otgp->GAHBCFG |= GAHBCFG_GINTMSK; - } -} - -/** - * @brief Deactivates the USB peripheral. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void usb_lld_stop(USBDriver *usbp) { - stm32_otg_t *otgp = usbp->otg; - - /* If in ready state then disables the USB clock.*/ - if (usbp->state != USB_STOP) { - - /* Disabling all endpoints in case the driver has been stopped while - active.*/ - otg_disable_ep(usbp); - - otgp->DAINTMSK = 0; - otgp->GAHBCFG = 0; - otgp->GCCFG = 0; - -#if STM32_USB_USE_OTG1 - if (&USBD1 == usbp) { - nvicDisableVector(STM32_OTG1_NUMBER); - rccDisableOTG_FS(); - } -#endif - -#if STM32_USB_USE_OTG2 - if (&USBD2 == usbp) { - nvicDisableVector(STM32_OTG2_NUMBER); - rccDisableOTG_HS(); -#if defined(BOARD_OTG2_USES_ULPI) - rccDisableOTG_HSULPI(); -#endif - } -#endif - } -} - -/** - * @brief USB low level reset routine. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void usb_lld_reset(USBDriver *usbp) { - unsigned i; - stm32_otg_t *otgp = usbp->otg; - - /* Flush the Tx FIFO.*/ - otg_txfifo_flush(usbp, 0); - - /* Endpoint interrupts all disabled and cleared.*/ - otgp->DIEPEMPMSK = 0; - otgp->DAINTMSK = DAINTMSK_OEPM(0) | DAINTMSK_IEPM(0); - - /* All endpoints in NAK mode, interrupts cleared.*/ - for (i = 0; i <= usbp->otgparams->num_endpoints; i++) { - otgp->ie[i].DIEPCTL = DIEPCTL_SNAK; - otgp->oe[i].DOEPCTL = DOEPCTL_SNAK; - otgp->ie[i].DIEPINT = 0xFFFFFFFF; - otgp->oe[i].DOEPINT = 0xFFFFFFFF; - } - - /* Resets the FIFO memory allocator.*/ - otg_ram_reset(usbp); - - /* Receive FIFO size initialization, the address is always zero.*/ - otgp->GRXFSIZ = usbp->otgparams->rx_fifo_size; - otg_rxfifo_flush(usbp); - - /* Resets the device address to zero.*/ - otgp->DCFG = (otgp->DCFG & ~DCFG_DAD_MASK) | DCFG_DAD(0); - - /* Enables also EP-related interrupt sources.*/ - otgp->GINTMSK |= GINTMSK_RXFLVLM | GINTMSK_OEPM | GINTMSK_IEPM; - otgp->DIEPMSK = DIEPMSK_TOCM | DIEPMSK_XFRCM; - otgp->DOEPMSK = DOEPMSK_STUPM | DOEPMSK_XFRCM; - - /* EP0 initialization, it is a special case.*/ - usbp->epc[0] = &ep0config; - otgp->oe[0].DOEPTSIZ = DOEPTSIZ_STUPCNT(3); - otgp->oe[0].DOEPCTL = DOEPCTL_SD0PID | DOEPCTL_USBAEP | DOEPCTL_EPTYP_CTRL | - DOEPCTL_MPSIZ(ep0config.out_maxsize); - otgp->ie[0].DIEPTSIZ = 0; - otgp->ie[0].DIEPCTL = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_CTRL | - DIEPCTL_TXFNUM(0) | DIEPCTL_MPSIZ(ep0config.in_maxsize); - otgp->DIEPTXF0 = DIEPTXF_INEPTXFD(ep0config.in_maxsize / 4) | - DIEPTXF_INEPTXSA(otg_ram_alloc(usbp, - ep0config.in_maxsize / 4)); -} - -/** - * @brief Sets the USB address. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void usb_lld_set_address(USBDriver *usbp) { - stm32_otg_t *otgp = usbp->otg; - - otgp->DCFG = (otgp->DCFG & ~DCFG_DAD_MASK) | DCFG_DAD(usbp->address); -} - -/** - * @brief Enables an endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) { - uint32_t ctl, fsize; - stm32_otg_t *otgp = usbp->otg; - - /* IN and OUT common parameters.*/ - switch (usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) { - case USB_EP_MODE_TYPE_CTRL: - ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_CTRL; - break; - case USB_EP_MODE_TYPE_ISOC: - ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_ISO; - break; - case USB_EP_MODE_TYPE_BULK: - ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_BULK; - break; - case USB_EP_MODE_TYPE_INTR: - ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_INTR; - break; - default: - return; - } - - /* OUT endpoint activation or deactivation.*/ - otgp->oe[ep].DOEPTSIZ = 0; - if (usbp->epc[ep]->out_state != NULL) { - otgp->oe[ep].DOEPCTL = ctl | DOEPCTL_MPSIZ(usbp->epc[ep]->out_maxsize); - otgp->DAINTMSK |= DAINTMSK_OEPM(ep); - } - else { - otgp->oe[ep].DOEPCTL &= ~DOEPCTL_USBAEP; - otgp->DAINTMSK &= ~DAINTMSK_OEPM(ep); - } - - /* IN endpoint activation or deactivation.*/ - otgp->ie[ep].DIEPTSIZ = 0; - if (usbp->epc[ep]->in_state != NULL) { - /* FIFO allocation for the IN endpoint.*/ - fsize = usbp->epc[ep]->in_maxsize / 4; - if (usbp->epc[ep]->in_multiplier > 1) - fsize *= usbp->epc[ep]->in_multiplier; - otgp->DIEPTXF[ep - 1] = DIEPTXF_INEPTXFD(fsize) | - DIEPTXF_INEPTXSA(otg_ram_alloc(usbp, fsize)); - otg_txfifo_flush(usbp, ep); - - otgp->ie[ep].DIEPCTL = ctl | - DIEPCTL_TXFNUM(ep) | - DIEPCTL_MPSIZ(usbp->epc[ep]->in_maxsize); - otgp->DAINTMSK |= DAINTMSK_IEPM(ep); - } - else { - otgp->DIEPTXF[ep - 1] = 0x02000400; /* Reset value.*/ - otg_txfifo_flush(usbp, ep); - otgp->ie[ep].DIEPCTL &= ~DIEPCTL_USBAEP; - otgp->DAINTMSK &= ~DAINTMSK_IEPM(ep); - } -} - -/** - * @brief Disables all the active endpoints except the endpoint zero. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void usb_lld_disable_endpoints(USBDriver *usbp) { - - /* Resets the FIFO memory allocator.*/ - otg_ram_reset(usbp); - - /* Disabling all endpoints.*/ - otg_disable_ep(usbp); -} - -/** - * @brief Returns the status of an OUT endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @return The endpoint status. - * @retval EP_STATUS_DISABLED The endpoint is not active. - * @retval EP_STATUS_STALLED The endpoint is stalled. - * @retval EP_STATUS_ACTIVE The endpoint is active. - * - * @notapi - */ -usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) { - uint32_t ctl; - - (void)usbp; - - ctl = usbp->otg->oe[ep].DOEPCTL; - if (!(ctl & DOEPCTL_USBAEP)) - return EP_STATUS_DISABLED; - if (ctl & DOEPCTL_STALL) - return EP_STATUS_STALLED; - return EP_STATUS_ACTIVE; -} - -/** - * @brief Returns the status of an IN endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @return The endpoint status. - * @retval EP_STATUS_DISABLED The endpoint is not active. - * @retval EP_STATUS_STALLED The endpoint is stalled. - * @retval EP_STATUS_ACTIVE The endpoint is active. - * - * @notapi - */ -usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) { - uint32_t ctl; - - (void)usbp; - - ctl = usbp->otg->ie[ep].DIEPCTL; - if (!(ctl & DIEPCTL_USBAEP)) - return EP_STATUS_DISABLED; - if (ctl & DIEPCTL_STALL) - return EP_STATUS_STALLED; - return EP_STATUS_ACTIVE; -} - -/** - * @brief Reads a setup packet from the dedicated packet buffer. - * @details This function must be invoked in the context of the @p setup_cb - * callback in order to read the received setup packet. - * @pre In order to use this function the endpoint must have been - * initialized as a control endpoint. - * @post The endpoint is ready to accept another packet. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @param[out] buf buffer where to copy the packet data - * - * @notapi - */ -void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) { - - memcpy(buf, usbp->epc[ep]->setup_buf, 8); -} - -/** - * @brief Starts a receive operation on an OUT endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_start_out(USBDriver *usbp, usbep_t ep) { - uint32_t pcnt, rxsize; - USBOutEndpointState *osp = usbp->epc[ep]->out_state; - - /* Transfer initialization.*/ - osp->totsize = osp->rxsize; - if ((ep == 0) && (osp->rxsize > EP0_MAX_OUTSIZE)) - osp->rxsize = EP0_MAX_OUTSIZE; - - /* Transaction size is rounded to a multiple of packet size because the - following requirement in the RM: - "For OUT transfers, the transfer size field in the endpoint's transfer - size register must be a multiple of the maximum packet size of the - endpoint, adjusted to the Word boundary".*/ - pcnt = (osp->rxsize + usbp->epc[ep]->out_maxsize - 1U) / - usbp->epc[ep]->out_maxsize; - rxsize = (pcnt * usbp->epc[ep]->out_maxsize + 3U) & 0xFFFFFFFCU; - - /*Setting up transaction parameters in DOEPTSIZ.*/ - usbp->otg->oe[ep].DOEPTSIZ = DOEPTSIZ_STUPCNT(3) | DOEPTSIZ_PKTCNT(pcnt) | - DOEPTSIZ_XFRSIZ(rxsize); - - /* Special case of isochronous endpoint.*/ - if ((usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) == USB_EP_MODE_TYPE_ISOC) { - /* Odd/even bit toggling for isochronous endpoint.*/ - if (usbp->otg->DSTS & DSTS_FNSOF_ODD) - usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_SEVNFRM; - else - usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_SODDFRM; - } - - /* Starting operation.*/ - usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_EPENA | DOEPCTL_CNAK; -} - -/** - * @brief Starts a transmit operation on an IN endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_start_in(USBDriver *usbp, usbep_t ep) { - USBInEndpointState *isp = usbp->epc[ep]->in_state; - - /* Transfer initialization.*/ - isp->totsize = isp->txsize; - if (isp->txsize == 0) { - /* Special case, sending zero size packet.*/ - usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_PKTCNT(1) | DIEPTSIZ_XFRSIZ(0); - } - else { - if ((ep == 0) && (isp->txsize > EP0_MAX_INSIZE)) - isp->txsize = EP0_MAX_INSIZE; - - /* Normal case.*/ - uint32_t pcnt = (isp->txsize + usbp->epc[ep]->in_maxsize - 1) / - usbp->epc[ep]->in_maxsize; - /* CHTODO: Support more than one packet per frame for isochronous transfers.*/ - usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_MCNT(1) | DIEPTSIZ_PKTCNT(pcnt) | - DIEPTSIZ_XFRSIZ(isp->txsize); - } - - /* Special case of isochronous endpoint.*/ - if ((usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) == USB_EP_MODE_TYPE_ISOC) { - /* Odd/even bit toggling.*/ - if (usbp->otg->DSTS & DSTS_FNSOF_ODD) - usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_SEVNFRM; - else - usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_SODDFRM; - } - - /* Starting operation.*/ - usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_EPENA | DIEPCTL_CNAK; - usbp->otg->DIEPEMPMSK |= DIEPEMPMSK_INEPTXFEM(ep); -} - -/** - * @brief Brings an OUT endpoint in the stalled state. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) { - - usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_STALL; -} - -/** - * @brief Brings an IN endpoint in the stalled state. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) { - - usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_STALL; -} - -/** - * @brief Brings an OUT endpoint in the active state. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) { - - usbp->otg->oe[ep].DOEPCTL &= ~DOEPCTL_STALL; -} - -/** - * @brief Brings an IN endpoint in the active state. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) { - - usbp->otg->ie[ep].DIEPCTL &= ~DIEPCTL_STALL; -} - -#endif /* HAL_USE_USB */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 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 OTGv1/hal_usb_lld.c + * @brief STM32 USB subsystem low level driver source. + * + * @addtogroup USB + * @{ + */ + +#include + +#include "hal.h" + +#if HAL_USE_USB || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define TRDT_VALUE_FS 5 +#define TRDT_VALUE_HS 9 + +#define EP0_MAX_INSIZE 64 +#define EP0_MAX_OUTSIZE 64 + +#if STM32_OTG_STEPPING == 1 +#if defined(BOARD_OTG_NOVBUSSENS) +#define GCCFG_INIT_VALUE (GCCFG_NOVBUSSENS | GCCFG_VBUSASEN | \ + GCCFG_VBUSBSEN | GCCFG_PWRDWN) +#else +#define GCCFG_INIT_VALUE (GCCFG_VBUSASEN | GCCFG_VBUSBSEN | \ + GCCFG_PWRDWN) +#endif + +#elif STM32_OTG_STEPPING == 2 +#if defined(BOARD_OTG_NOVBUSSENS) +#define GCCFG_INIT_VALUE GCCFG_PWRDWN +#else +#define GCCFG_INIT_VALUE (GCCFG_VBDEN | GCCFG_PWRDWN) +#endif + +#endif + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief OTG_FS driver identifier.*/ +#if STM32_USB_USE_OTG1 || defined(__DOXYGEN__) +USBDriver USBD1; +#endif + +/** @brief OTG_HS driver identifier.*/ +#if STM32_USB_USE_OTG2 || defined(__DOXYGEN__) +USBDriver USBD2; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/** + * @brief EP0 state. + * @note It is an union because IN and OUT endpoints are never used at the + * same time for EP0. + */ +static union { + /** + * @brief IN EP0 state. + */ + USBInEndpointState in; + /** + * @brief OUT EP0 state. + */ + USBOutEndpointState out; +} ep0_state; + +/** + * @brief Buffer for the EP0 setup packets. + */ +static uint8_t ep0setup_buffer[8]; + +/** + * @brief EP0 initialization structure. + */ +static const USBEndpointConfig ep0config = { + USB_EP_MODE_TYPE_CTRL, + _usb_ep0setup, + _usb_ep0in, + _usb_ep0out, + 0x40, + 0x40, + &ep0_state.in, + &ep0_state.out, + 1, + ep0setup_buffer +}; + +#if STM32_USB_USE_OTG1 +static const stm32_otg_params_t fsparams = { + STM32_USB_OTG1_RX_FIFO_SIZE / 4, + STM32_OTG1_FIFO_MEM_SIZE, + STM32_OTG1_ENDPOINTS +}; +#endif + +#if STM32_USB_USE_OTG2 +static const stm32_otg_params_t hsparams = { + STM32_USB_OTG2_RX_FIFO_SIZE / 4, + STM32_OTG2_FIFO_MEM_SIZE, + STM32_OTG2_ENDPOINTS +}; +#endif + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static void otg_core_reset(USBDriver *usbp) { + stm32_otg_t *otgp = usbp->otg; + + /* Wait AHB idle condition.*/ + while ((otgp->GRSTCTL & GRSTCTL_AHBIDL) == 0) + ; + + /* Core reset and delay of at least 3 PHY cycles.*/ + otgp->GRSTCTL = GRSTCTL_CSRST; + osalSysPolledDelayX(12); + while ((otgp->GRSTCTL & GRSTCTL_CSRST) != 0) + ; + + osalSysPolledDelayX(18); + + /* Wait AHB idle condition again.*/ + while ((otgp->GRSTCTL & GRSTCTL_AHBIDL) == 0) + ; +} + +static void otg_disable_ep(USBDriver *usbp) { + stm32_otg_t *otgp = usbp->otg; + unsigned i; + + for (i = 0; i <= usbp->otgparams->num_endpoints; i++) { + + if ((otgp->ie[i].DIEPCTL & DIEPCTL_EPENA) != 0U) { + otgp->ie[i].DIEPCTL |= DIEPCTL_EPDIS; + } + + if ((otgp->oe[i].DOEPCTL & DIEPCTL_EPENA) != 0U) { + otgp->oe[i].DOEPCTL |= DIEPCTL_EPDIS; + } + + otgp->ie[i].DIEPINT = 0xFFFFFFFF; + otgp->oe[i].DOEPINT = 0xFFFFFFFF; + } + otgp->DAINTMSK = DAINTMSK_OEPM(0) | DAINTMSK_IEPM(0); +} + +static void otg_rxfifo_flush(USBDriver *usbp) { + stm32_otg_t *otgp = usbp->otg; + + otgp->GRSTCTL = GRSTCTL_RXFFLSH; + while ((otgp->GRSTCTL & GRSTCTL_RXFFLSH) != 0) + ; + /* Wait for 3 PHY Clocks.*/ + osalSysPolledDelayX(18); +} + +static void otg_txfifo_flush(USBDriver *usbp, uint32_t fifo) { + stm32_otg_t *otgp = usbp->otg; + + otgp->GRSTCTL = GRSTCTL_TXFNUM(fifo) | GRSTCTL_TXFFLSH; + while ((otgp->GRSTCTL & GRSTCTL_TXFFLSH) != 0) + ; + /* Wait for 3 PHY Clocks.*/ + osalSysPolledDelayX(18); +} + +/** + * @brief Resets the FIFO RAM memory allocator. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +static void otg_ram_reset(USBDriver *usbp) { + + usbp->pmnext = usbp->otgparams->rx_fifo_size; +} + +/** + * @brief Allocates a block from the FIFO RAM memory. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] size size of the packet buffer to allocate in words + * + * @notapi + */ +static uint32_t otg_ram_alloc(USBDriver *usbp, size_t size) { + uint32_t next; + + next = usbp->pmnext; + usbp->pmnext += size; + osalDbgAssert(usbp->pmnext <= usbp->otgparams->otg_ram_size, + "OTG FIFO memory overflow"); + return next; +} + +/** + * @brief Writes to a TX FIFO. + * + * @param[in] fifop pointer to the FIFO register + * @param[in] buf buffer where to copy the endpoint data + * @param[in] n maximum number of bytes to copy + * + * @notapi + */ +static void otg_fifo_write_from_buffer(volatile uint32_t *fifop, + const uint8_t *buf, + size_t n) { + + osalDbgAssert(n > 0, "is zero"); + + while (true) { + *fifop = *((uint32_t *)buf); + if (n <= 4) { + break; + } + n -= 4; + buf += 4; + } +} + +/** + * @brief Reads a packet from the RXFIFO. + * + * @param[in] fifop pointer to the FIFO register + * @param[out] buf buffer where to copy the endpoint data + * @param[in] n number of bytes to pull from the FIFO + * @param[in] max number of bytes to copy into the buffer + * + * @notapi + */ +static void otg_fifo_read_to_buffer(volatile uint32_t *fifop, + uint8_t *buf, + size_t n, + size_t max) { + uint32_t w = 0; + size_t i = 0; + + while (i < n) { + if ((i & 3) == 0) { + w = *fifop; + } + if (i < max) { + *buf++ = (uint8_t)w; + w >>= 8; + } + i++; + } +} + +/** + * @brief Incoming packets handler. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +static void otg_rxfifo_handler(USBDriver *usbp) { + uint32_t sts, cnt, ep; + + /* Popping the event word out of the RX FIFO.*/ + sts = usbp->otg->GRXSTSP; + + /* Event details.*/ + cnt = (sts & GRXSTSP_BCNT_MASK) >> GRXSTSP_BCNT_OFF; + ep = (sts & GRXSTSP_EPNUM_MASK) >> GRXSTSP_EPNUM_OFF; + + switch (sts & GRXSTSP_PKTSTS_MASK) { + case GRXSTSP_SETUP_DATA: + otg_fifo_read_to_buffer(usbp->otg->FIFO[0], usbp->epc[ep]->setup_buf, + cnt, 8); + break; + case GRXSTSP_SETUP_COMP: + break; + case GRXSTSP_OUT_DATA: + otg_fifo_read_to_buffer(usbp->otg->FIFO[0], + usbp->epc[ep]->out_state->rxbuf, + cnt, + usbp->epc[ep]->out_state->rxsize - + usbp->epc[ep]->out_state->rxcnt); + usbp->epc[ep]->out_state->rxbuf += cnt; + usbp->epc[ep]->out_state->rxcnt += cnt; + break; + case GRXSTSP_OUT_COMP: + break; + case GRXSTSP_OUT_GLOBAL_NAK: + break; + default: + break; + } +} + +/** + * @brief Outgoing packets handler. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +static bool otg_txfifo_handler(USBDriver *usbp, usbep_t ep) { + + /* The TXFIFO is filled until there is space and data to be transmitted.*/ + while (true) { + uint32_t n; + + /* Transaction end condition.*/ + if (usbp->epc[ep]->in_state->txcnt >= usbp->epc[ep]->in_state->txsize) { +#if 1 + usbp->otg->DIEPEMPMSK &= ~DIEPEMPMSK_INEPTXFEM(ep); +#endif + return true; + } + + /* Number of bytes remaining in current transaction.*/ + n = usbp->epc[ep]->in_state->txsize - usbp->epc[ep]->in_state->txcnt; + if (n > usbp->epc[ep]->in_maxsize) + n = usbp->epc[ep]->in_maxsize; + + /* Checks if in the TXFIFO there is enough space to accommodate the + next packet.*/ + if (((usbp->otg->ie[ep].DTXFSTS & DTXFSTS_INEPTFSAV_MASK) * 4) < n) + return false; + +#if STM32_USB_OTGFIFO_FILL_BASEPRI + __set_BASEPRI(CORTEX_PRIO_MASK(STM32_USB_OTGFIFO_FILL_BASEPRI)); +#endif + otg_fifo_write_from_buffer(usbp->otg->FIFO[ep], + usbp->epc[ep]->in_state->txbuf, + n); + usbp->epc[ep]->in_state->txbuf += n; + usbp->epc[ep]->in_state->txcnt += n; +#if STM32_USB_OTGFIFO_FILL_BASEPRI + __set_BASEPRI(0); +#endif + } +} + +/** + * @brief Generic endpoint IN handler. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +static void otg_epin_handler(USBDriver *usbp, usbep_t ep) { + stm32_otg_t *otgp = usbp->otg; + uint32_t epint = otgp->ie[ep].DIEPINT; + + otgp->ie[ep].DIEPINT = epint; + + if (epint & DIEPINT_TOC) { + /* Timeouts not handled yet, not sure how to handle.*/ + } + if ((epint & DIEPINT_XFRC) && (otgp->DIEPMSK & DIEPMSK_XFRCM)) { + /* Transmit transfer complete.*/ + USBInEndpointState *isp = usbp->epc[ep]->in_state; + + if (isp->txsize < isp->totsize) { + /* In case the transaction covered only part of the total transfer + then another transaction is immediately started in order to + cover the remaining.*/ + isp->txsize = isp->totsize - isp->txsize; + isp->txcnt = 0; + osalSysLockFromISR(); + usb_lld_start_in(usbp, ep); + osalSysUnlockFromISR(); + } + else { + /* End on IN transfer.*/ + _usb_isr_invoke_in_cb(usbp, ep); + } + } + if ((epint & DIEPINT_TXFE) && + (otgp->DIEPEMPMSK & DIEPEMPMSK_INEPTXFEM(ep))) { + /* TX FIFO empty or emptying.*/ + otg_txfifo_handler(usbp, ep); + } +} + +/** + * @brief Generic endpoint OUT handler. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +static void otg_epout_handler(USBDriver *usbp, usbep_t ep) { + stm32_otg_t *otgp = usbp->otg; + uint32_t epint = otgp->oe[ep].DOEPINT; + + /* Resets all EP IRQ sources.*/ + otgp->oe[ep].DOEPINT = epint; + + if ((epint & DOEPINT_STUP) && (otgp->DOEPMSK & DOEPMSK_STUPM)) { + /* Setup packets handling, setup packets are handled using a + specific callback.*/ + _usb_isr_invoke_setup_cb(usbp, ep); + } + + if ((epint & DOEPINT_XFRC) && (otgp->DOEPMSK & DOEPMSK_XFRCM)) { + USBOutEndpointState *osp; + + /* OUT state structure pointer for this endpoint.*/ + osp = usbp->epc[ep]->out_state; + + /* EP0 requires special handling.*/ + if (ep == 0) { + +#if defined(STM32_OTG_SEQUENCE_WORKAROUND) + /* If an OUT transaction end interrupt is processed while the state + machine is not in an OUT state then it is ignored, this is caused + on some devices (L4) apparently injecting spurious data complete + words in the RX FIFO.*/ + if ((usbp->ep0state & USB_OUT_STATE) == 0) + return; +#endif + + /* In case the transaction covered only part of the total transfer + then another transaction is immediately started in order to + cover the remaining.*/ + if (((osp->rxcnt % usbp->epc[ep]->out_maxsize) == 0) && + (osp->rxsize < osp->totsize)) { + osp->rxsize = osp->totsize - osp->rxsize; + osp->rxcnt = 0; + osalSysLockFromISR(); + usb_lld_start_out(usbp, ep); + osalSysUnlockFromISR(); + return; + } + } + + /* End on OUT transfer.*/ + _usb_isr_invoke_out_cb(usbp, ep); + } +} + +/** + * @brief Isochronous IN transfer failed handler. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +static void otg_isoc_in_failed_handler(USBDriver *usbp) { + usbep_t ep; + stm32_otg_t *otgp = usbp->otg; + + for (ep = 0; ep <= usbp->otgparams->num_endpoints; ep++) { + if (((otgp->ie[ep].DIEPCTL & DIEPCTL_EPTYP_MASK) == DIEPCTL_EPTYP_ISO) && + ((otgp->ie[ep].DIEPCTL & DIEPCTL_EPENA) != 0)) { + /* Endpoint enabled -> ISOC IN transfer failed.*/ + /* Disable endpoint.*/ + otgp->ie[ep].DIEPCTL |= (DIEPCTL_EPDIS | DIEPCTL_SNAK); + while (otgp->ie[ep].DIEPCTL & DIEPCTL_EPENA) + ; + + /* Flush FIFO.*/ + otg_txfifo_flush(usbp, ep); + + /* Prepare data for next frame.*/ + _usb_isr_invoke_in_cb(usbp, ep); + } + } +} + +/** + * @brief Isochronous OUT transfer failed handler. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +static void otg_isoc_out_failed_handler(USBDriver *usbp) { + usbep_t ep; + stm32_otg_t *otgp = usbp->otg; + + for (ep = 0; ep <= usbp->otgparams->num_endpoints; ep++) { + if (((otgp->oe[ep].DOEPCTL & DOEPCTL_EPTYP_MASK) == DOEPCTL_EPTYP_ISO) && + ((otgp->oe[ep].DOEPCTL & DOEPCTL_EPENA) != 0)) { +#if 0 + /* Endpoint enabled -> ISOC OUT transfer failed.*/ + /* Disable endpoint.*/ + /* CHTODO:: Core stucks here */ + otgp->oe[ep].DOEPCTL |= (DOEPCTL_EPDIS | DOEPCTL_SNAK); + while (otgp->oe[ep].DOEPCTL & DOEPCTL_EPENA) + ; +#endif + /* Prepare transfer for next frame.*/ + _usb_isr_invoke_out_cb(usbp, ep); + } + } +} + +/** + * @brief OTG shared ISR. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +static void usb_lld_serve_interrupt(USBDriver *usbp) { + stm32_otg_t *otgp = usbp->otg; + uint32_t sts, src; + + sts = otgp->GINTSTS; + sts &= otgp->GINTMSK; + otgp->GINTSTS = sts; + + /* Reset interrupt handling.*/ + if (sts & GINTSTS_USBRST) { + /* Default reset action.*/ + _usb_reset(usbp); + + /* Preventing execution of more handlers, the core has been reset.*/ + return; + } + + /* Wake-up handling.*/ + if (sts & GINTSTS_WKUPINT) { + /* If clocks are gated off, turn them back on (may be the case if + coming out of suspend mode).*/ + if (otgp->PCGCCTL & (PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK)) { + /* Set to zero to un-gate the USB core clocks.*/ + otgp->PCGCCTL &= ~(PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK); + } + + /* Clear the Remote Wake-up Signaling.*/ + otgp->DCTL &= ~DCTL_RWUSIG; + + _usb_wakeup(usbp); + } + + /* Suspend handling.*/ + if (sts & GINTSTS_USBSUSP) { + /* Stopping all ongoing transfers.*/ + otg_disable_ep(usbp); + + /* Default suspend action.*/ + _usb_suspend(usbp); + } + + /* Enumeration done.*/ + if (sts & GINTSTS_ENUMDNE) { + /* Full or High speed timing selection.*/ + if ((otgp->DSTS & DSTS_ENUMSPD_MASK) == DSTS_ENUMSPD_HS_480) { + otgp->GUSBCFG = (otgp->GUSBCFG & ~(GUSBCFG_TRDT_MASK)) | + GUSBCFG_TRDT(TRDT_VALUE_HS); + } + else { + otgp->GUSBCFG = (otgp->GUSBCFG & ~(GUSBCFG_TRDT_MASK)) | + GUSBCFG_TRDT(TRDT_VALUE_FS); + } + } + + /* SOF interrupt handling.*/ + if (sts & GINTSTS_SOF) { + /* SOF interrupt was used to detect resume of the USB bus after issuing a + remote wake up of the host, therefore we disable it again.*/ + if (usbp->config->sof_cb == NULL) { + otgp->GINTMSK &= ~GINTMSK_SOFM; + } + if (usbp->state == USB_SUSPENDED) { + /* If clocks are gated off, turn them back on (may be the case if + coming out of suspend mode).*/ + if (otgp->PCGCCTL & (PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK)) { + /* Set to zero to un-gate the USB core clocks.*/ + otgp->PCGCCTL &= ~(PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK); + } + _usb_wakeup(usbp); + } + + _usb_isr_invoke_sof_cb(usbp); + } + + /* Isochronous IN failed handling */ + if (sts & GINTSTS_IISOIXFR) { + otg_isoc_in_failed_handler(usbp); + } + + /* Isochronous OUT failed handling */ + if (sts & GINTSTS_IISOOXFR) { + otg_isoc_out_failed_handler(usbp); + } + + /* Performing the whole FIFO emptying in the ISR, it is advised to keep + this IRQ at a very low priority level.*/ + if ((sts & GINTSTS_RXFLVL) != 0U) { + otg_rxfifo_handler(usbp); + } + + /* IN/OUT endpoints event handling.*/ + src = otgp->DAINT; + if (sts & GINTSTS_OEPINT) { + if (src & (1 << 16)) + otg_epout_handler(usbp, 0); + if (src & (1 << 17)) + otg_epout_handler(usbp, 1); + if (src & (1 << 18)) + otg_epout_handler(usbp, 2); + if (src & (1 << 19)) + otg_epout_handler(usbp, 3); +#if USB_MAX_ENDPOINTS >= 4 + if (src & (1 << 20)) + otg_epout_handler(usbp, 4); +#endif +#if USB_MAX_ENDPOINTS >= 5 + if (src & (1 << 21)) + otg_epout_handler(usbp, 5); +#endif +#if USB_MAX_ENDPOINTS >= 6 + if (src & (1 << 22)) + otg_epout_handler(usbp, 6); +#endif +#if USB_MAX_ENDPOINTS >= 7 + if (src & (1 << 23)) + otg_epout_handler(usbp, 7); +#endif +#if USB_MAX_ENDPOINTS >= 8 + if (src & (1 << 24)) + otg_epout_handler(usbp, 8); +#endif + } + if (sts & GINTSTS_IEPINT) { + if (src & (1 << 0)) + otg_epin_handler(usbp, 0); + if (src & (1 << 1)) + otg_epin_handler(usbp, 1); + if (src & (1 << 2)) + otg_epin_handler(usbp, 2); + if (src & (1 << 3)) + otg_epin_handler(usbp, 3); +#if USB_MAX_ENDPOINTS >= 4 + if (src & (1 << 4)) + otg_epin_handler(usbp, 4); +#endif +#if USB_MAX_ENDPOINTS >= 5 + if (src & (1 << 5)) + otg_epin_handler(usbp, 5); +#endif +#if USB_MAX_ENDPOINTS >= 6 + if (src & (1 << 6)) + otg_epin_handler(usbp, 6); +#endif +#if USB_MAX_ENDPOINTS >= 7 + if (src & (1 << 7)) + otg_epin_handler(usbp, 7); +#endif +#if USB_MAX_ENDPOINTS >= 8 + if (src & (1 << 8)) + otg_epin_handler(usbp, 8); +#endif + } +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if STM32_USB_USE_OTG1 || defined(__DOXYGEN__) +/** + * @brief OTG1 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_OTG1_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + usb_lld_serve_interrupt(&USBD1); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if STM32_USB_USE_OTG2 || defined(__DOXYGEN__) +/** + * @brief OTG2 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_OTG2_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + usb_lld_serve_interrupt(&USBD2); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level USB driver initialization. + * + * @notapi + */ +void usb_lld_init(void) { + + /* Driver initialization.*/ +#if STM32_USB_USE_OTG1 + usbObjectInit(&USBD1); + USBD1.otg = OTG_FS; + USBD1.otgparams = &fsparams; + +#endif + +#if STM32_USB_USE_OTG2 + usbObjectInit(&USBD2); + USBD2.otg = OTG_HS; + USBD2.otgparams = &hsparams; +#endif +} + +/** + * @brief Configures and activates the USB peripheral. + * @note Starting the OTG cell can be a slow operation carried out with + * interrupts disabled, perform it before starting time-critical + * operations. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void usb_lld_start(USBDriver *usbp) { + stm32_otg_t *otgp = usbp->otg; + + if (usbp->state == USB_STOP) { + /* Clock activation.*/ + +#if STM32_USB_USE_OTG1 + if (&USBD1 == usbp) { + /* OTG FS clock enable and reset.*/ + rccEnableOTG_FS(true); + rccResetOTG_FS(); + + /* Enables IRQ vector.*/ + nvicEnableVector(STM32_OTG1_NUMBER, STM32_USB_OTG1_IRQ_PRIORITY); + + /* - Forced device mode. + - USB turn-around time = TRDT_VALUE_FS. + - Full Speed 1.1 PHY.*/ + otgp->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE_FS) | + GUSBCFG_PHYSEL; + + /* 48MHz 1.1 PHY.*/ + otgp->DCFG = 0x02200000 | DCFG_DSPD_FS11; + } +#endif + +#if STM32_USB_USE_OTG2 + if (&USBD2 == usbp) { + /* OTG HS clock enable and reset.*/ + rccEnableOTG_HS(true); + rccResetOTG_HS(); + + /* ULPI clock is managed depending on the presence of an external + PHY.*/ +#if defined(BOARD_OTG2_USES_ULPI) + rccEnableOTG_HSULPI(true); +#else + /* Workaround for the problem described here: + http://forum.chibios.org/phpbb/viewtopic.php?f=16&t=1798.*/ + rccDisableOTG_HSULPI(); +#endif + + /* Enables IRQ vector.*/ + nvicEnableVector(STM32_OTG2_NUMBER, STM32_USB_OTG2_IRQ_PRIORITY); + + /* - Forced device mode. + - USB turn-around time = TRDT_VALUE_HS or TRDT_VALUE_FS.*/ +#if defined(BOARD_OTG2_USES_ULPI) + /* High speed ULPI PHY.*/ + otgp->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE_HS) | + GUSBCFG_SRPCAP | GUSBCFG_HNPCAP; +#else + otgp->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE_FS) | + GUSBCFG_PHYSEL; +#endif + +#if defined(BOARD_OTG2_USES_ULPI) +#if STM32_USE_USB_OTG2_HS + /* USB 2.0 High Speed PHY in HS mode.*/ + otgp->DCFG = 0x02200000 | DCFG_DSPD_HS; +#else + /* USB 2.0 High Speed PHY in FS mode.*/ + otgp->DCFG = 0x02200000 | DCFG_DSPD_HS_FS; +#endif +#else + /* 48MHz 1.1 PHY.*/ + otgp->DCFG = 0x02200000 | DCFG_DSPD_FS11; +#endif + } +#endif + + /* PHY enabled.*/ + otgp->PCGCCTL = 0; + + /* VBUS sensing and transceiver enabled.*/ + otgp->GOTGCTL = GOTGCTL_BVALOEN | GOTGCTL_BVALOVAL; + +#if defined(BOARD_OTG2_USES_ULPI) +#if STM32_USB_USE_OTG1 + if (&USBD1 == usbp) { + otgp->GCCFG = GCCFG_INIT_VALUE; + } +#endif + +#if STM32_USB_USE_OTG2 + if (&USBD2 == usbp) { + otgp->GCCFG = 0; + } +#endif +#else + otgp->GCCFG = GCCFG_INIT_VALUE; +#endif + + /* Soft core reset.*/ + otg_core_reset(usbp); + + /* Interrupts on TXFIFOs half empty.*/ + otgp->GAHBCFG = 0; + + /* Endpoints re-initialization.*/ + otg_disable_ep(usbp); + + /* Clear all pending Device Interrupts, only the USB Reset interrupt + is required initially.*/ + otgp->DIEPMSK = 0; + otgp->DOEPMSK = 0; + otgp->DAINTMSK = 0; + if (usbp->config->sof_cb == NULL) + otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM | GINTMSK_USBSUSPM | + GINTMSK_ESUSPM | GINTMSK_SRQM | GINTMSK_WKUM | + GINTMSK_IISOIXFRM | GINTMSK_IISOOXFRM; + else + otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM | GINTMSK_USBSUSPM | + GINTMSK_ESUSPM | GINTMSK_SRQM | GINTMSK_WKUM | + GINTMSK_IISOIXFRM | GINTMSK_IISOOXFRM | + GINTMSK_SOFM; + + /* Clears all pending IRQs, if any. */ + otgp->GINTSTS = 0xFFFFFFFF; + + /* Global interrupts enable.*/ + otgp->GAHBCFG |= GAHBCFG_GINTMSK; + } +} + +/** + * @brief Deactivates the USB peripheral. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void usb_lld_stop(USBDriver *usbp) { + stm32_otg_t *otgp = usbp->otg; + + /* If in ready state then disables the USB clock.*/ + if (usbp->state != USB_STOP) { + + /* Disabling all endpoints in case the driver has been stopped while + active.*/ + otg_disable_ep(usbp); + + otgp->DAINTMSK = 0; + otgp->GAHBCFG = 0; + otgp->GCCFG = 0; + +#if STM32_USB_USE_OTG1 + if (&USBD1 == usbp) { + nvicDisableVector(STM32_OTG1_NUMBER); + rccDisableOTG_FS(); + } +#endif + +#if STM32_USB_USE_OTG2 + if (&USBD2 == usbp) { + nvicDisableVector(STM32_OTG2_NUMBER); + rccDisableOTG_HS(); +#if defined(BOARD_OTG2_USES_ULPI) + rccDisableOTG_HSULPI(); +#endif + } +#endif + } +} + +/** + * @brief USB low level reset routine. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void usb_lld_reset(USBDriver *usbp) { + unsigned i; + stm32_otg_t *otgp = usbp->otg; + + /* Flush the Tx FIFO.*/ + otg_txfifo_flush(usbp, 0); + + /* Endpoint interrupts all disabled and cleared.*/ + otgp->DIEPEMPMSK = 0; + otgp->DAINTMSK = DAINTMSK_OEPM(0) | DAINTMSK_IEPM(0); + + /* All endpoints in NAK mode, interrupts cleared.*/ + for (i = 0; i <= usbp->otgparams->num_endpoints; i++) { + otgp->ie[i].DIEPCTL = DIEPCTL_SNAK; + otgp->oe[i].DOEPCTL = DOEPCTL_SNAK; + otgp->ie[i].DIEPINT = 0xFFFFFFFF; + otgp->oe[i].DOEPINT = 0xFFFFFFFF; + } + + /* Resets the FIFO memory allocator.*/ + otg_ram_reset(usbp); + + /* Receive FIFO size initialization, the address is always zero.*/ + otgp->GRXFSIZ = usbp->otgparams->rx_fifo_size; + otg_rxfifo_flush(usbp); + + /* Resets the device address to zero.*/ + otgp->DCFG = (otgp->DCFG & ~DCFG_DAD_MASK) | DCFG_DAD(0); + + /* Enables also EP-related interrupt sources.*/ + otgp->GINTMSK |= GINTMSK_RXFLVLM | GINTMSK_OEPM | GINTMSK_IEPM; + otgp->DIEPMSK = DIEPMSK_TOCM | DIEPMSK_XFRCM; + otgp->DOEPMSK = DOEPMSK_STUPM | DOEPMSK_XFRCM; + + /* EP0 initialization, it is a special case.*/ + usbp->epc[0] = &ep0config; + otgp->oe[0].DOEPTSIZ = DOEPTSIZ_STUPCNT(3); + otgp->oe[0].DOEPCTL = DOEPCTL_SD0PID | DOEPCTL_USBAEP | DOEPCTL_EPTYP_CTRL | + DOEPCTL_MPSIZ(ep0config.out_maxsize); + otgp->ie[0].DIEPTSIZ = 0; + otgp->ie[0].DIEPCTL = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_CTRL | + DIEPCTL_TXFNUM(0) | DIEPCTL_MPSIZ(ep0config.in_maxsize); + otgp->DIEPTXF0 = DIEPTXF_INEPTXFD(ep0config.in_maxsize / 4) | + DIEPTXF_INEPTXSA(otg_ram_alloc(usbp, + ep0config.in_maxsize / 4)); +} + +/** + * @brief Sets the USB address. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void usb_lld_set_address(USBDriver *usbp) { + stm32_otg_t *otgp = usbp->otg; + + otgp->DCFG = (otgp->DCFG & ~DCFG_DAD_MASK) | DCFG_DAD(usbp->address); +} + +/** + * @brief Enables an endpoint. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) { + uint32_t ctl, fsize; + stm32_otg_t *otgp = usbp->otg; + + /* IN and OUT common parameters.*/ + switch (usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) { + case USB_EP_MODE_TYPE_CTRL: + ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_CTRL; + break; + case USB_EP_MODE_TYPE_ISOC: + ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_ISO; + break; + case USB_EP_MODE_TYPE_BULK: + ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_BULK; + break; + case USB_EP_MODE_TYPE_INTR: + ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_INTR; + break; + default: + return; + } + + /* OUT endpoint activation or deactivation.*/ + otgp->oe[ep].DOEPTSIZ = 0; + if (usbp->epc[ep]->out_state != NULL) { + otgp->oe[ep].DOEPCTL = ctl | DOEPCTL_MPSIZ(usbp->epc[ep]->out_maxsize); + otgp->DAINTMSK |= DAINTMSK_OEPM(ep); + } + else { + otgp->oe[ep].DOEPCTL &= ~DOEPCTL_USBAEP; + otgp->DAINTMSK &= ~DAINTMSK_OEPM(ep); + } + + /* IN endpoint activation or deactivation.*/ + otgp->ie[ep].DIEPTSIZ = 0; + if (usbp->epc[ep]->in_state != NULL) { + /* FIFO allocation for the IN endpoint.*/ + fsize = usbp->epc[ep]->in_maxsize / 4; + if (usbp->epc[ep]->in_multiplier > 1) + fsize *= usbp->epc[ep]->in_multiplier; + otgp->DIEPTXF[ep - 1] = DIEPTXF_INEPTXFD(fsize) | + DIEPTXF_INEPTXSA(otg_ram_alloc(usbp, fsize)); + otg_txfifo_flush(usbp, ep); + + otgp->ie[ep].DIEPCTL = ctl | + DIEPCTL_TXFNUM(ep) | + DIEPCTL_MPSIZ(usbp->epc[ep]->in_maxsize); + otgp->DAINTMSK |= DAINTMSK_IEPM(ep); + } + else { + otgp->DIEPTXF[ep - 1] = 0x02000400; /* Reset value.*/ + otg_txfifo_flush(usbp, ep); + otgp->ie[ep].DIEPCTL &= ~DIEPCTL_USBAEP; + otgp->DAINTMSK &= ~DAINTMSK_IEPM(ep); + } +} + +/** + * @brief Disables all the active endpoints except the endpoint zero. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void usb_lld_disable_endpoints(USBDriver *usbp) { + + /* Resets the FIFO memory allocator.*/ + otg_ram_reset(usbp); + + /* Disabling all endpoints.*/ + otg_disable_ep(usbp); +} + +/** + * @brief Returns the status of an OUT endpoint. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * @return The endpoint status. + * @retval EP_STATUS_DISABLED The endpoint is not active. + * @retval EP_STATUS_STALLED The endpoint is stalled. + * @retval EP_STATUS_ACTIVE The endpoint is active. + * + * @notapi + */ +usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) { + uint32_t ctl; + + (void)usbp; + + ctl = usbp->otg->oe[ep].DOEPCTL; + if (!(ctl & DOEPCTL_USBAEP)) + return EP_STATUS_DISABLED; + if (ctl & DOEPCTL_STALL) + return EP_STATUS_STALLED; + return EP_STATUS_ACTIVE; +} + +/** + * @brief Returns the status of an IN endpoint. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * @return The endpoint status. + * @retval EP_STATUS_DISABLED The endpoint is not active. + * @retval EP_STATUS_STALLED The endpoint is stalled. + * @retval EP_STATUS_ACTIVE The endpoint is active. + * + * @notapi + */ +usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) { + uint32_t ctl; + + (void)usbp; + + ctl = usbp->otg->ie[ep].DIEPCTL; + if (!(ctl & DIEPCTL_USBAEP)) + return EP_STATUS_DISABLED; + if (ctl & DIEPCTL_STALL) + return EP_STATUS_STALLED; + return EP_STATUS_ACTIVE; +} + +/** + * @brief Reads a setup packet from the dedicated packet buffer. + * @details This function must be invoked in the context of the @p setup_cb + * callback in order to read the received setup packet. + * @pre In order to use this function the endpoint must have been + * initialized as a control endpoint. + * @post The endpoint is ready to accept another packet. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * @param[out] buf buffer where to copy the packet data + * + * @notapi + */ +void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) { + + memcpy(buf, usbp->epc[ep]->setup_buf, 8); +} + +/** + * @brief Starts a receive operation on an OUT endpoint. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +void usb_lld_start_out(USBDriver *usbp, usbep_t ep) { + uint32_t pcnt, rxsize; + USBOutEndpointState *osp = usbp->epc[ep]->out_state; + + /* Transfer initialization.*/ + osp->totsize = osp->rxsize; + if ((ep == 0) && (osp->rxsize > EP0_MAX_OUTSIZE)) + osp->rxsize = EP0_MAX_OUTSIZE; + + /* Transaction size is rounded to a multiple of packet size because the + following requirement in the RM: + "For OUT transfers, the transfer size field in the endpoint's transfer + size register must be a multiple of the maximum packet size of the + endpoint, adjusted to the Word boundary".*/ + pcnt = (osp->rxsize + usbp->epc[ep]->out_maxsize - 1U) / + usbp->epc[ep]->out_maxsize; + rxsize = (pcnt * usbp->epc[ep]->out_maxsize + 3U) & 0xFFFFFFFCU; + + /* Setting up transaction parameters in DOEPTSIZ.*/ + usbp->otg->oe[ep].DOEPTSIZ = DOEPTSIZ_STUPCNT(3) | DOEPTSIZ_PKTCNT(pcnt) | + DOEPTSIZ_XFRSIZ(rxsize); + + /* Special case of isochronous endpoint.*/ + if ((usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) == USB_EP_MODE_TYPE_ISOC) { + /* Odd/even bit toggling for isochronous endpoint.*/ + if (usbp->otg->DSTS & DSTS_FNSOF_ODD) + usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_SEVNFRM; + else + usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_SODDFRM; + } + + /* Starting operation.*/ + usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_EPENA | DOEPCTL_CNAK; +} + +/** + * @brief Starts a transmit operation on an IN endpoint. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +void usb_lld_start_in(USBDriver *usbp, usbep_t ep) { + USBInEndpointState *isp = usbp->epc[ep]->in_state; + + /* Transfer initialization.*/ + isp->totsize = isp->txsize; + if (isp->txsize == 0) { + /* Special case, sending zero size packet.*/ + usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_PKTCNT(1) | DIEPTSIZ_XFRSIZ(0); + } + else { + if ((ep == 0) && (isp->txsize > EP0_MAX_INSIZE)) + isp->txsize = EP0_MAX_INSIZE; + + /* Normal case.*/ + uint32_t pcnt = (isp->txsize + usbp->epc[ep]->in_maxsize - 1) / + usbp->epc[ep]->in_maxsize; + /* CHTODO: Support more than one packet per frame for isochronous transfers.*/ + usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_MCNT(1) | DIEPTSIZ_PKTCNT(pcnt) | + DIEPTSIZ_XFRSIZ(isp->txsize); + } + + /* Special case of isochronous endpoint.*/ + if ((usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) == USB_EP_MODE_TYPE_ISOC) { + /* Odd/even bit toggling.*/ + if (usbp->otg->DSTS & DSTS_FNSOF_ODD) + usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_SEVNFRM; + else + usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_SODDFRM; + } + + /* Starting operation.*/ + usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_EPENA | DIEPCTL_CNAK; + usbp->otg->DIEPEMPMSK |= DIEPEMPMSK_INEPTXFEM(ep); +} + +/** + * @brief Brings an OUT endpoint in the stalled state. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) { + + usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_STALL; +} + +/** + * @brief Brings an IN endpoint in the stalled state. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) { + + usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_STALL; +} + +/** + * @brief Brings an OUT endpoint in the active state. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) { + + usbp->otg->oe[ep].DOEPCTL &= ~DOEPCTL_STALL; +} + +/** + * @brief Brings an IN endpoint in the active state. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) { + + usbp->otg->ie[ep].DIEPCTL &= ~DIEPCTL_STALL; +} + +#endif /* HAL_USE_USB */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h index 4d7ae15935..c9d2be1649 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h +++ b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h @@ -1,604 +1,608 @@ -/* - ChibiOS - Copyright (C) 2006..2018 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 OTGv1/hal_usb_lld.h - * @brief STM32 USB subsystem low level driver header. - * - * @addtogroup USB - * @{ - */ - -#ifndef HAL_USB_LLD_H -#define HAL_USB_LLD_H - -#if HAL_USE_USB || defined(__DOXYGEN__) - -#include "stm32_otg.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @brief Status stage handling method. - */ -#define USB_EP0_STATUS_STAGE USB_EP0_STATUS_STAGE_SW - -/** - * @brief The address can be changed immediately upon packet reception. - */ -#define USB_SET_ADDRESS_MODE USB_EARLY_SET_ADDRESS - -/** - * @brief Method for set address acknowledge. - */ -#define USB_SET_ADDRESS_ACK_HANDLING USB_SET_ADDRESS_ACK_SW - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @brief OTG1 driver enable switch. - * @details If set to @p TRUE the support for OTG_FS is included. - * @note The default is @p FALSE - */ -#if !defined(STM32_USB_USE_OTG1) || defined(__DOXYGEN__) -#define STM32_USB_USE_OTG1 FALSE -#endif - -/** - * @brief OTG2 driver enable switch. - * @details If set to @p TRUE the support for OTG_HS is included. - * @note The default is @p FALSE. - */ -#if !defined(STM32_USB_USE_OTG2) || defined(__DOXYGEN__) -#define STM32_USB_USE_OTG2 FALSE -#endif - -/** - * @brief OTG1 interrupt priority level setting. - */ -#if !defined(STM32_USB_OTG1_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_USB_OTG1_IRQ_PRIORITY 14 -#endif - -/** - * @brief OTG2 interrupt priority level setting. - */ -#if !defined(STM32_USB_OTG2_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_USB_OTG2_IRQ_PRIORITY 14 -#endif - -/** - * @brief OTG1 RX shared FIFO size. - * @note Must be a multiple of 4. - */ -#if !defined(STM32_USB_OTG1_RX_FIFO_SIZE) || defined(__DOXYGEN__) -#define STM32_USB_OTG1_RX_FIFO_SIZE 512 -#endif - -/** - * @brief OTG2 RX shared FIFO size. - * @note Must be a multiple of 4. - */ -#if !defined(STM32_USB_OTG2_RX_FIFO_SIZE) || defined(__DOXYGEN__) -#define STM32_USB_OTG2_RX_FIFO_SIZE 1024 -#endif - -/** - * @brief Enables HS mode on OTG2 else FS mode. - * @note The default is @p TRUE. - * @note Has effect only if @p BOARD_OTG2_USES_ULPI is defined. - */ -#if !defined(STM32_USE_USB_OTG2_HS) || defined(__DOXYGEN__) -#define STM32_USE_USB_OTG2_HS TRUE -#endif - -/** - * @brief Exception priority level during TXFIFOs operations. - * @note Because an undocumented silicon behavior the operation of - * copying a packet into a TXFIFO must not be interrupted by - * any other operation on the OTG peripheral. - * This parameter represents the priority mask during copy - * operations. The default value only allows to call USB - * functions from callbacks invoked from USB ISR handlers. - * If you need to invoke USB functions from other handlers - * then raise this priority mast to the same level of the - * handler you need to use. - * @note The value zero means disabled, when disabled calling USB - * functions is only safe from thread level or from USB - * callbacks. - */ -#if !defined(STM32_USB_OTGFIFO_FILL_BASEPRI) || defined(__DOXYGEN__) -#define STM32_USB_OTGFIFO_FILL_BASEPRI 0 -#endif - -/** - * @brief Host wake-up procedure duration. - */ -#if !defined(STM32_USB_HOST_WAKEUP_DURATION) || defined(__DOXYGEN__) -#define STM32_USB_HOST_WAKEUP_DURATION 2 -#endif - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* Registry checks.*/ -#if !defined(STM32_OTG_STEPPING) -#error "STM32_OTG_STEPPING not defined in registry" -#endif - -#if (STM32_OTG_STEPPING < 1) || (STM32_OTG_STEPPING > 2) -#error "unsupported STM32_OTG_STEPPING" -#endif - -#if !defined(STM32_HAS_OTG1) || !defined(STM32_HAS_OTG2) -#error "STM32_HAS_OTGx not defined in registry" -#endif - -#if STM32_HAS_OTG1 && !defined(STM32_OTG1_ENDPOINTS) -#error "STM32_OTG1_ENDPOINTS not defined in registry" -#endif - -#if STM32_HAS_OTG2 && !defined(STM32_OTG2_ENDPOINTS) -#error "STM32_OTG2_ENDPOINTS not defined in registry" -#endif - -#if STM32_HAS_OTG1 && !defined(STM32_OTG1_FIFO_MEM_SIZE) -#error "STM32_OTG1_FIFO_MEM_SIZE not defined in registry" -#endif - -#if STM32_HAS_OTG2 && !defined(STM32_OTG2_FIFO_MEM_SIZE) -#error "STM32_OTG2_FIFO_MEM_SIZE not defined in registry" -#endif - -#if (STM32_USB_USE_OTG1 && !defined(STM32_OTG1_HANDLER)) || \ - (STM32_USB_USE_OTG2 && !defined(STM32_OTG2_HANDLER)) -#error "STM32_OTGx_HANDLER not defined in registry" -#endif - -#if (STM32_USB_USE_OTG1 && !defined(STM32_OTG1_NUMBER)) || \ - (STM32_USB_USE_OTG2 && !defined(STM32_OTG2_NUMBER)) -#error "STM32_OTGx_NUMBER not defined in registry" -#endif - -/** - * @brief Maximum endpoint address. - */ -#if (STM32_HAS_OTG2 && STM32_USB_USE_OTG2) || defined(__DOXYGEN__) -#if (STM32_OTG1_ENDPOINTS < STM32_OTG2_ENDPOINTS) || defined(__DOXYGEN__) -#define USB_MAX_ENDPOINTS STM32_OTG2_ENDPOINTS -#else -#define USB_MAX_ENDPOINTS STM32_OTG1_ENDPOINTS -#endif -#else -#define USB_MAX_ENDPOINTS STM32_OTG1_ENDPOINTS -#endif - -#if STM32_USB_USE_OTG1 && !STM32_HAS_OTG1 -#error "OTG1 not present in the selected device" -#endif - -#if STM32_USB_USE_OTG2 && !STM32_HAS_OTG2 -#error "OTG2 not present in the selected device" -#endif - -#if !STM32_USB_USE_OTG1 && !STM32_USB_USE_OTG2 -#error "USB driver activated but no USB peripheral assigned" -#endif - -#if STM32_USB_USE_OTG1 && \ - !OSAL_IRQ_IS_VALID_PRIORITY(STM32_USB_OTG1_IRQ_PRIORITY) -#error "Invalid IRQ priority assigned to OTG1" -#endif - -#if STM32_USB_USE_OTG2 && \ - !OSAL_IRQ_IS_VALID_PRIORITY(STM32_USB_OTG2_IRQ_PRIORITY) -#error "Invalid IRQ priority assigned to OTG2" -#endif - -#if (STM32_USB_OTG1_RX_FIFO_SIZE & 3) != 0 -#error "OTG1 RX FIFO size must be a multiple of 4" -#endif - -#if (STM32_USB_OTG2_RX_FIFO_SIZE & 3) != 0 -#error "OTG2 RX FIFO size must be a multiple of 4" -#endif - -#if defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32F7XX) -#define STM32_USBCLK STM32_PLL48CLK -#elif defined(STM32F10X_CL) -#define STM32_USBCLK STM32_OTGFSCLK -#elif defined(STM32L4XX) || defined(STM32L4XXP) -#define STM32_USBCLK STM32_48CLK -#elif defined(STM32H7XX) -/* Defines directly STM32_USBCLK.*/ -#define rccEnableOTG_FS rccEnableUSB2_OTG_FS -#define rccDisableOTG_FS rccDisableUSB2_OTG_FS -#define rccResetOTG_FS rccResetUSB2_OTG_FS -#define rccEnableOTG_HS rccEnableUSB1_OTG_HS -#define rccDisableOTG_HS rccDisableUSB1_OTG_HS -#define rccResetOTG_HS rccResetUSB1_OTG_HS -#define rccEnableOTG_HSULPI rccEnableUSB1_HSULPI -#define rccDisableOTG_HSULPI rccDisableUSB1_HSULPI -#else -#error "unsupported STM32 platform for OTG functionality" -#endif - -/* Allowing for a small tolerance.*/ -#if STM32_USBCLK < 47880000 || STM32_USBCLK > 48120000 -#error "the USB OTG driver requires a 48MHz clock" -#endif - -#if (STM32_USB_HOST_WAKEUP_DURATION < 2) || (STM32_USB_HOST_WAKEUP_DURATION > 15) -#error "invalid STM32_USB_HOST_WAKEUP_DURATION setting, it must be between 2 and 15" -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Peripheral-specific parameters block. - */ -typedef struct { - uint32_t rx_fifo_size; - uint32_t otg_ram_size; - uint32_t num_endpoints; -} stm32_otg_params_t; - -/** - * @brief Type of an IN endpoint state structure. - */ -typedef struct { - /** - * @brief Requested transmit transfer size. - */ - size_t txsize; - /** - * @brief Transmitted bytes so far. - */ - size_t txcnt; - /** - * @brief Pointer to the transmission linear buffer. - */ - const uint8_t *txbuf; -#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__) - /** - * @brief Waiting thread. - */ - thread_reference_t thread; -#endif - /* End of the mandatory fields.*/ - /** - * @brief Total transmit transfer size. - */ - size_t totsize; -} USBInEndpointState; - -/** - * @brief Type of an OUT endpoint state structure. - */ -typedef struct { - /** - * @brief Requested receive transfer size. - */ - size_t rxsize; - /** - * @brief Received bytes so far. - */ - size_t rxcnt; - /** - * @brief Pointer to the receive linear buffer. - */ - uint8_t *rxbuf; -#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__) - /** - * @brief Waiting thread. - */ - thread_reference_t thread; -#endif - /* End of the mandatory fields.*/ - /** - * @brief Total receive transfer size. - */ - size_t totsize; -} USBOutEndpointState; - -/** - * @brief Type of an USB endpoint configuration structure. - * @note Platform specific restrictions may apply to endpoints. - */ -typedef struct { - /** - * @brief Type and mode of the endpoint. - */ - uint32_t ep_mode; - /** - * @brief Setup packet notification callback. - * @details This callback is invoked when a setup packet has been - * received. - * @post The application must immediately call @p usbReadPacket() in - * order to access the received packet. - * @note This field is only valid for @p USB_EP_MODE_TYPE_CTRL - * endpoints, it should be set to @p NULL for other endpoint - * types. - */ - usbepcallback_t setup_cb; - /** - * @brief IN endpoint notification callback. - * @details This field must be set to @p NULL if callback is not required. - */ - usbepcallback_t in_cb; - /** - * @brief OUT endpoint notification callback. - * @details This field must be set to @p NULL if callback is not required. - */ - usbepcallback_t out_cb; - /** - * @brief IN endpoint maximum packet size. - * @details This field must be set to zero if the IN endpoint is not used. - */ - uint16_t in_maxsize; - /** - * @brief OUT endpoint maximum packet size. - * @details This field must be set to zero if the OUT endpoint is not used. - */ - uint16_t out_maxsize; - /** - * @brief @p USBEndpointState associated to the IN endpoint. - * @details This field must be set to @p NULL if the IN endpoint is not - * used. - */ - USBInEndpointState *in_state; - /** - * @brief @p USBEndpointState associated to the OUT endpoint. - * @details This field must be set to @p NULL if the OUT endpoint is not - * used. - */ - USBOutEndpointState *out_state; - /* End of the mandatory fields.*/ - /** - * @brief Determines the space allocated for the TXFIFO as multiples of - * the packet size (@p in_maxsize). Note that zero is interpreted - * as one for simplicity and robustness. - */ - uint16_t in_multiplier; - /** - * @brief Pointer to a buffer for setup packets. - * @details Setup packets require a dedicated 8-bytes buffer, set this - * field to @p NULL for non-control endpoints. - */ - uint8_t *setup_buf; -} USBEndpointConfig; - -/** - * @brief Type of an USB driver configuration structure. - */ -typedef struct { - /** - * @brief USB events callback. - * @details This callback is invoked when an USB driver event is registered. - */ - usbeventcb_t event_cb; - /** - * @brief Device GET_DESCRIPTOR request callback. - * @note This callback is mandatory and cannot be set to @p NULL. - */ - usbgetdescriptor_t get_descriptor_cb; - /** - * @brief Requests hook callback. - * @details This hook allows to be notified of standard requests or to - * handle non standard requests. - */ - usbreqhandler_t requests_hook_cb; - /** - * @brief Start Of Frame callback. - */ - usbcallback_t sof_cb; - /* End of the mandatory fields.*/ -} USBConfig; - -/** - * @brief Structure representing an USB driver. - */ -struct USBDriver { - /** - * @brief Driver state. - */ - usbstate_t state; - /** - * @brief Current configuration data. - */ - const USBConfig *config; - /** - * @brief Bit map of the transmitting IN endpoints. - */ - uint16_t transmitting; - /** - * @brief Bit map of the receiving OUT endpoints. - */ - uint16_t receiving; - /** - * @brief Active endpoints configurations. - */ - const USBEndpointConfig *epc[USB_MAX_ENDPOINTS + 1]; - /** - * @brief Fields available to user, it can be used to associate an - * application-defined handler to an IN endpoint. - * @note The base index is one, the endpoint zero does not have a - * reserved element in this array. - */ - void *in_params[USB_MAX_ENDPOINTS]; - /** - * @brief Fields available to user, it can be used to associate an - * application-defined handler to an OUT endpoint. - * @note The base index is one, the endpoint zero does not have a - * reserved element in this array. - */ - void *out_params[USB_MAX_ENDPOINTS]; - /** - * @brief Endpoint 0 state. - */ - usbep0state_t ep0state; - /** - * @brief Next position in the buffer to be transferred through endpoint 0. - */ - uint8_t *ep0next; - /** - * @brief Number of bytes yet to be transferred through endpoint 0. - */ - size_t ep0n; - /** - * @brief Endpoint 0 end transaction callback. - */ - usbcallback_t ep0endcb; - /** - * @brief Setup packet buffer. - */ - uint8_t setup[8]; - /** - * @brief Current USB device status. - */ - uint16_t status; - /** - * @brief Assigned USB address. - */ - uint8_t address; - /** - * @brief Current USB device configuration. - */ - uint8_t configuration; - /** - * @brief State of the driver when a suspend happened. - */ - usbstate_t saved_state; -#if defined(USB_DRIVER_EXT_FIELDS) - USB_DRIVER_EXT_FIELDS -#endif - /* End of the mandatory fields.*/ - /** - * @brief Pointer to the OTG peripheral associated to this driver. - */ - stm32_otg_t *otg; - /** - * @brief Peripheral-specific parameters. - */ - const stm32_otg_params_t *otgparams; - /** - * @brief Pointer to the next address in the packet memory. - */ - uint32_t pmnext; -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/** - * @brief Returns the exact size of a receive transaction. - * @details The received size can be different from the size specified in - * @p usbStartReceiveI() because the last packet could have a size - * different from the expected one. - * @pre The OUT endpoint must have been configured in transaction mode - * in order to use this function. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @return Received data size. - * - * @notapi - */ -#define usb_lld_get_transaction_size(usbp, ep) \ - ((usbp)->epc[ep]->out_state->rxcnt) - -/** - * @brief Connects the USB device. - * - * @notapi - */ -#if (STM32_OTG_STEPPING == 1) || defined(__DOXYGEN__) -#define usb_lld_connect_bus(usbp) ((usbp)->otg->GCCFG |= GCCFG_VBUSBSEN) -#else -#define usb_lld_connect_bus(usbp) ((usbp)->otg->DCTL &= ~DCTL_SDIS) -#endif - -/** - * @brief Disconnect the USB device. - * - * @notapi - */ -#if (STM32_OTG_STEPPING == 1) || defined(__DOXYGEN__) -#define usb_lld_disconnect_bus(usbp) ((usbp)->otg->GCCFG &= ~GCCFG_VBUSBSEN) -#else -#define usb_lld_disconnect_bus(usbp) ((usbp)->otg->DCTL |= DCTL_SDIS) -#endif - -/** - * @brief Start of host wake-up procedure. - * - * @notapi - */ -#define usb_lld_wakeup_host(usbp) \ - do { \ - (usbp)->otg->DCTL |= DCTL_RWUSIG; \ - osalThreadSleepMilliseconds(STM32_USB_HOST_WAKEUP_DURATION); \ - (usbp)->otg->DCTL &= ~DCTL_RWUSIG; \ - } while (false) - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if STM32_USB_USE_OTG1 && !defined(__DOXYGEN__) -extern USBDriver USBD1; -#endif - -#if STM32_USB_USE_OTG2 && !defined(__DOXYGEN__) -extern USBDriver USBD2; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void usb_lld_init(void); - void usb_lld_start(USBDriver *usbp); - void usb_lld_stop(USBDriver *usbp); - void usb_lld_reset(USBDriver *usbp); - void usb_lld_set_address(USBDriver *usbp); - void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep); - void usb_lld_disable_endpoints(USBDriver *usbp); - usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep); - usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep); - void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf); - void usb_lld_start_out(USBDriver *usbp, usbep_t ep); - void usb_lld_start_in(USBDriver *usbp, usbep_t ep); - void usb_lld_stall_out(USBDriver *usbp, usbep_t ep); - void usb_lld_stall_in(USBDriver *usbp, usbep_t ep); - void usb_lld_clear_out(USBDriver *usbp, usbep_t ep); - void usb_lld_clear_in(USBDriver *usbp, usbep_t ep); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_USB */ - -#endif /* HAL_USB_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 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 OTGv1/hal_usb_lld.h + * @brief STM32 USB subsystem low level driver header. + * + * @addtogroup USB + * @{ + */ + +#ifndef HAL_USB_LLD_H +#define HAL_USB_LLD_H + +#if HAL_USE_USB || defined(__DOXYGEN__) + +#include "stm32_otg.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Status stage handling method. + */ +#define USB_EP0_STATUS_STAGE USB_EP0_STATUS_STAGE_SW + +/** + * @brief The address can be changed immediately upon packet reception. + */ +#define USB_SET_ADDRESS_MODE USB_EARLY_SET_ADDRESS + +/** + * @brief Method for set address acknowledge. + */ +#define USB_SET_ADDRESS_ACK_HANDLING USB_SET_ADDRESS_ACK_SW + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @brief OTG1 driver enable switch. + * @details If set to @p TRUE the support for OTG_FS is included. + * @note The default is @p FALSE + */ +#if !defined(STM32_USB_USE_OTG1) || defined(__DOXYGEN__) +#define STM32_USB_USE_OTG1 FALSE +#endif + +/** + * @brief OTG2 driver enable switch. + * @details If set to @p TRUE the support for OTG_HS is included. + * @note The default is @p FALSE. + */ +#if !defined(STM32_USB_USE_OTG2) || defined(__DOXYGEN__) +#define STM32_USB_USE_OTG2 FALSE +#endif + +/** + * @brief OTG1 interrupt priority level setting. + */ +#if !defined(STM32_USB_OTG1_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_USB_OTG1_IRQ_PRIORITY 14 +#endif + +/** + * @brief OTG2 interrupt priority level setting. + */ +#if !defined(STM32_USB_OTG2_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_USB_OTG2_IRQ_PRIORITY 14 +#endif + +/** + * @brief OTG1 RX shared FIFO size. + * @note Must be a multiple of 4. + */ +#if !defined(STM32_USB_OTG1_RX_FIFO_SIZE) || defined(__DOXYGEN__) +#define STM32_USB_OTG1_RX_FIFO_SIZE 512 +#endif + +/** + * @brief OTG2 RX shared FIFO size. + * @note Must be a multiple of 4. + */ +#if !defined(STM32_USB_OTG2_RX_FIFO_SIZE) || defined(__DOXYGEN__) +#define STM32_USB_OTG2_RX_FIFO_SIZE 1024 +#endif + +/** + * @brief Enables HS mode on OTG2 else FS mode. + * @note The default is @p TRUE. + * @note Has effect only if @p BOARD_OTG2_USES_ULPI is defined. + */ +#if !defined(STM32_USE_USB_OTG2_HS) || defined(__DOXYGEN__) +#define STM32_USE_USB_OTG2_HS TRUE +#endif + +/** + * @brief Exception priority level during TXFIFOs operations. + * @note Because an undocumented silicon behavior the operation of + * copying a packet into a TXFIFO must not be interrupted by + * any other operation on the OTG peripheral. + * This parameter represents the priority mask during copy + * operations. The default value only allows to call USB + * functions from callbacks invoked from USB ISR handlers. + * If you need to invoke USB functions from other handlers + * then raise this priority mast to the same level of the + * handler you need to use. + * @note The value zero means disabled, when disabled calling USB + * functions is only safe from thread level or from USB + * callbacks. + */ +#if !defined(STM32_USB_OTGFIFO_FILL_BASEPRI) || defined(__DOXYGEN__) +#define STM32_USB_OTGFIFO_FILL_BASEPRI 0 +#endif + +/** + * @brief Host wake-up procedure duration. + */ +#if !defined(STM32_USB_HOST_WAKEUP_DURATION) || defined(__DOXYGEN__) +#define STM32_USB_HOST_WAKEUP_DURATION 2 +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* Registry checks.*/ +#if !defined(STM32_OTG_STEPPING) +#error "STM32_OTG_STEPPING not defined in registry" +#endif + +#if (STM32_OTG_STEPPING < 1) || (STM32_OTG_STEPPING > 2) +#error "unsupported STM32_OTG_STEPPING" +#endif + +#if !defined(STM32_HAS_OTG1) || !defined(STM32_HAS_OTG2) +#error "STM32_HAS_OTGx not defined in registry" +#endif + +#if STM32_HAS_OTG1 && !defined(STM32_OTG1_ENDPOINTS) +#error "STM32_OTG1_ENDPOINTS not defined in registry" +#endif + +#if STM32_HAS_OTG2 && !defined(STM32_OTG2_ENDPOINTS) +#error "STM32_OTG2_ENDPOINTS not defined in registry" +#endif + +#if STM32_HAS_OTG1 && !defined(STM32_OTG1_FIFO_MEM_SIZE) +#error "STM32_OTG1_FIFO_MEM_SIZE not defined in registry" +#endif + +#if STM32_HAS_OTG2 && !defined(STM32_OTG2_FIFO_MEM_SIZE) +#error "STM32_OTG2_FIFO_MEM_SIZE not defined in registry" +#endif + +#if (STM32_USB_USE_OTG1 && !defined(STM32_OTG1_HANDLER)) || \ + (STM32_USB_USE_OTG2 && !defined(STM32_OTG2_HANDLER)) +#error "STM32_OTGx_HANDLER not defined in registry" +#endif + +#if (STM32_USB_USE_OTG1 && !defined(STM32_OTG1_NUMBER)) || \ + (STM32_USB_USE_OTG2 && !defined(STM32_OTG2_NUMBER)) +#error "STM32_OTGx_NUMBER not defined in registry" +#endif + +#if STM32_USB_USE_OTG1 && !STM32_HAS_OTG1 +#error "OTG1 not present in the selected device" +#endif + +#if STM32_USB_USE_OTG2 && !STM32_HAS_OTG2 +#error "OTG2 not present in the selected device" +#endif + +#if !STM32_USB_USE_OTG1 && !STM32_USB_USE_OTG2 +#error "USB driver activated but no USB peripheral assigned" +#endif + +/* Maximum endpoint address.*/ +#if STM32_HAS_OTG1 && STM32_USB_USE_OTG1 && STM32_HAS_OTG2 && STM32_USB_USE_OTG2 + #if STM32_OTG1_ENDPOINTS < STM32_OTG2_ENDPOINTS + #define USB_MAX_ENDPOINTS STM32_OTG2_ENDPOINTS + #else + #define USB_MAX_ENDPOINTS STM32_OTG1_ENDPOINTS + #endif +#elif STM32_HAS_OTG1 && STM32_USB_USE_OTG1 + #define USB_MAX_ENDPOINTS STM32_OTG1_ENDPOINTS +#elif STM32_HAS_OTG2 && STM32_USB_USE_OTG2 + #define USB_MAX_ENDPOINTS STM32_OTG2_ENDPOINTS +#endif + +#if STM32_USB_USE_OTG1 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(STM32_USB_OTG1_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to OTG1" +#endif + +#if STM32_USB_USE_OTG2 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(STM32_USB_OTG2_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to OTG2" +#endif + +#if (STM32_USB_OTG1_RX_FIFO_SIZE & 3) != 0 +#error "OTG1 RX FIFO size must be a multiple of 4" +#endif + +#if (STM32_USB_OTG2_RX_FIFO_SIZE & 3) != 0 +#error "OTG2 RX FIFO size must be a multiple of 4" +#endif + +#if defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32F7XX) +#define STM32_USBCLK STM32_PLL48CLK +#elif defined(STM32F10X_CL) +#define STM32_USBCLK STM32_OTGFSCLK +#elif defined(STM32L4XX) || defined(STM32L4XXP) +#define STM32_USBCLK STM32_48CLK +#elif defined(STM32H7XX) +/* Defines directly STM32_USBCLK.*/ +#define rccEnableOTG_FS rccEnableUSB2_OTG_FS +#define rccDisableOTG_FS rccDisableUSB2_OTG_FS +#define rccResetOTG_FS rccResetUSB2_OTG_FS +#define rccEnableOTG_HS rccEnableUSB1_OTG_HS +#define rccDisableOTG_HS rccDisableUSB1_OTG_HS +#define rccResetOTG_HS rccResetUSB1_OTG_HS +#define rccEnableOTG_HSULPI rccEnableUSB1_HSULPI +#define rccDisableOTG_HSULPI rccDisableUSB1_HSULPI +#else +#error "unsupported STM32 platform for OTG functionality" +#endif + +/* Allowing for a small tolerance.*/ +#if STM32_USBCLK < 47880000 || STM32_USBCLK > 48120000 +#error "the USB OTG driver requires a 48MHz clock" +#endif + +#if (STM32_USB_HOST_WAKEUP_DURATION < 2) || (STM32_USB_HOST_WAKEUP_DURATION > 15) +#error "invalid STM32_USB_HOST_WAKEUP_DURATION setting, it must be between 2 and 15" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Peripheral-specific parameters block. + */ +typedef struct { + uint32_t rx_fifo_size; + uint32_t otg_ram_size; + uint32_t num_endpoints; +} stm32_otg_params_t; + +/** + * @brief Type of an IN endpoint state structure. + */ +typedef struct { + /** + * @brief Requested transmit transfer size. + */ + size_t txsize; + /** + * @brief Transmitted bytes so far. + */ + size_t txcnt; + /** + * @brief Pointer to the transmission linear buffer. + */ + const uint8_t *txbuf; +#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__) + /** + * @brief Waiting thread. + */ + thread_reference_t thread; +#endif + /* End of the mandatory fields.*/ + /** + * @brief Total transmit transfer size. + */ + size_t totsize; +} USBInEndpointState; + +/** + * @brief Type of an OUT endpoint state structure. + */ +typedef struct { + /** + * @brief Requested receive transfer size. + */ + size_t rxsize; + /** + * @brief Received bytes so far. + */ + size_t rxcnt; + /** + * @brief Pointer to the receive linear buffer. + */ + uint8_t *rxbuf; +#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__) + /** + * @brief Waiting thread. + */ + thread_reference_t thread; +#endif + /* End of the mandatory fields.*/ + /** + * @brief Total receive transfer size. + */ + size_t totsize; +} USBOutEndpointState; + +/** + * @brief Type of an USB endpoint configuration structure. + * @note Platform specific restrictions may apply to endpoints. + */ +typedef struct { + /** + * @brief Type and mode of the endpoint. + */ + uint32_t ep_mode; + /** + * @brief Setup packet notification callback. + * @details This callback is invoked when a setup packet has been + * received. + * @post The application must immediately call @p usbReadPacket() in + * order to access the received packet. + * @note This field is only valid for @p USB_EP_MODE_TYPE_CTRL + * endpoints, it should be set to @p NULL for other endpoint + * types. + */ + usbepcallback_t setup_cb; + /** + * @brief IN endpoint notification callback. + * @details This field must be set to @p NULL if callback is not required. + */ + usbepcallback_t in_cb; + /** + * @brief OUT endpoint notification callback. + * @details This field must be set to @p NULL if callback is not required. + */ + usbepcallback_t out_cb; + /** + * @brief IN endpoint maximum packet size. + * @details This field must be set to zero if the IN endpoint is not used. + */ + uint16_t in_maxsize; + /** + * @brief OUT endpoint maximum packet size. + * @details This field must be set to zero if the OUT endpoint is not used. + */ + uint16_t out_maxsize; + /** + * @brief @p USBEndpointState associated to the IN endpoint. + * @details This field must be set to @p NULL if the IN endpoint is not + * used. + */ + USBInEndpointState *in_state; + /** + * @brief @p USBEndpointState associated to the OUT endpoint. + * @details This field must be set to @p NULL if the OUT endpoint is not + * used. + */ + USBOutEndpointState *out_state; + /* End of the mandatory fields.*/ + /** + * @brief Determines the space allocated for the TXFIFO as multiples of + * the packet size (@p in_maxsize). Note that zero is interpreted + * as one for simplicity and robustness. + */ + uint16_t in_multiplier; + /** + * @brief Pointer to a buffer for setup packets. + * @details Setup packets require a dedicated 8-bytes buffer, set this + * field to @p NULL for non-control endpoints. + */ + uint8_t *setup_buf; +} USBEndpointConfig; + +/** + * @brief Type of an USB driver configuration structure. + */ +typedef struct { + /** + * @brief USB events callback. + * @details This callback is invoked when an USB driver event is registered. + */ + usbeventcb_t event_cb; + /** + * @brief Device GET_DESCRIPTOR request callback. + * @note This callback is mandatory and cannot be set to @p NULL. + */ + usbgetdescriptor_t get_descriptor_cb; + /** + * @brief Requests hook callback. + * @details This hook allows to be notified of standard requests or to + * handle non standard requests. + */ + usbreqhandler_t requests_hook_cb; + /** + * @brief Start Of Frame callback. + */ + usbcallback_t sof_cb; + /* End of the mandatory fields.*/ +} USBConfig; + +/** + * @brief Structure representing an USB driver. + */ +struct USBDriver { + /** + * @brief Driver state. + */ + usbstate_t state; + /** + * @brief Current configuration data. + */ + const USBConfig *config; + /** + * @brief Bit map of the transmitting IN endpoints. + */ + uint16_t transmitting; + /** + * @brief Bit map of the receiving OUT endpoints. + */ + uint16_t receiving; + /** + * @brief Active endpoints configurations. + */ + const USBEndpointConfig *epc[USB_MAX_ENDPOINTS + 1]; + /** + * @brief Fields available to user, it can be used to associate an + * application-defined handler to an IN endpoint. + * @note The base index is one, the endpoint zero does not have a + * reserved element in this array. + */ + void *in_params[USB_MAX_ENDPOINTS]; + /** + * @brief Fields available to user, it can be used to associate an + * application-defined handler to an OUT endpoint. + * @note The base index is one, the endpoint zero does not have a + * reserved element in this array. + */ + void *out_params[USB_MAX_ENDPOINTS]; + /** + * @brief Endpoint 0 state. + */ + usbep0state_t ep0state; + /** + * @brief Next position in the buffer to be transferred through endpoint 0. + */ + uint8_t *ep0next; + /** + * @brief Number of bytes yet to be transferred through endpoint 0. + */ + size_t ep0n; + /** + * @brief Endpoint 0 end transaction callback. + */ + usbcallback_t ep0endcb; + /** + * @brief Setup packet buffer. + */ + uint8_t setup[8]; + /** + * @brief Current USB device status. + */ + uint16_t status; + /** + * @brief Assigned USB address. + */ + uint8_t address; + /** + * @brief Current USB device configuration. + */ + uint8_t configuration; + /** + * @brief State of the driver when a suspend happened. + */ + usbstate_t saved_state; +#if defined(USB_DRIVER_EXT_FIELDS) + USB_DRIVER_EXT_FIELDS +#endif + /* End of the mandatory fields.*/ + /** + * @brief Pointer to the OTG peripheral associated to this driver. + */ + stm32_otg_t *otg; + /** + * @brief Peripheral-specific parameters. + */ + const stm32_otg_params_t *otgparams; + /** + * @brief Pointer to the next address in the packet memory. + */ + uint32_t pmnext; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Returns the exact size of a receive transaction. + * @details The received size can be different from the size specified in + * @p usbStartReceiveI() because the last packet could have a size + * different from the expected one. + * @pre The OUT endpoint must have been configured in transaction mode + * in order to use this function. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * @return Received data size. + * + * @notapi + */ +#define usb_lld_get_transaction_size(usbp, ep) \ + ((usbp)->epc[ep]->out_state->rxcnt) + +/** + * @brief Connects the USB device. + * + * @notapi + */ +#if (STM32_OTG_STEPPING == 1) || defined(__DOXYGEN__) +#define usb_lld_connect_bus(usbp) ((usbp)->otg->GCCFG |= GCCFG_VBUSBSEN) +#else +#define usb_lld_connect_bus(usbp) ((usbp)->otg->DCTL &= ~DCTL_SDIS) +#endif + +/** + * @brief Disconnect the USB device. + * + * @notapi + */ +#if (STM32_OTG_STEPPING == 1) || defined(__DOXYGEN__) +#define usb_lld_disconnect_bus(usbp) ((usbp)->otg->GCCFG &= ~GCCFG_VBUSBSEN) +#else +#define usb_lld_disconnect_bus(usbp) ((usbp)->otg->DCTL |= DCTL_SDIS) +#endif + +/** + * @brief Start of host wake-up procedure. + * + * @notapi + */ +#define usb_lld_wakeup_host(usbp) \ + do { \ + (usbp)->otg->DCTL |= DCTL_RWUSIG; \ + /* remote wakeup doesn't trigger the wakeup interrupt, therefore + we use the SOF interrupt to detect resume of the bus.*/ \ + (usbp)->otg->GINTSTS |= GINTSTS_SOF; \ + (usbp)->otg->GINTMSK |= GINTMSK_SOFM; \ + osalThreadSleepMilliseconds(STM32_USB_HOST_WAKEUP_DURATION); \ + (usbp)->otg->DCTL &= ~DCTL_RWUSIG; \ + } while (false) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if STM32_USB_USE_OTG1 && !defined(__DOXYGEN__) +extern USBDriver USBD1; +#endif + +#if STM32_USB_USE_OTG2 && !defined(__DOXYGEN__) +extern USBDriver USBD2; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void usb_lld_init(void); + void usb_lld_start(USBDriver *usbp); + void usb_lld_stop(USBDriver *usbp); + void usb_lld_reset(USBDriver *usbp); + void usb_lld_set_address(USBDriver *usbp); + void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep); + void usb_lld_disable_endpoints(USBDriver *usbp); + usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep); + usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep); + void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf); + void usb_lld_start_out(USBDriver *usbp, usbep_t ep); + void usb_lld_start_in(USBDriver *usbp, usbep_t ep); + void usb_lld_stall_out(USBDriver *usbp, usbep_t ep); + void usb_lld_stall_in(USBDriver *usbp, usbep_t ep); + void usb_lld_clear_out(USBDriver *usbp, usbep_t ep); + void usb_lld_clear_in(USBDriver *usbp, usbep_t ep); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_USB */ + +#endif /* HAL_USB_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/OTGv1/stm32_otg.h b/os/hal/ports/STM32/LLD/OTGv1/stm32_otg.h index 0ea7314053..b47df3c296 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/stm32_otg.h +++ b/os/hal/ports/STM32/LLD/OTGv1/stm32_otg.h @@ -1,927 +1,931 @@ -/* - ChibiOS - Copyright (C) 2006..2018 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 OTGv1/stm32_otg.h - * @brief STM32 OTG registers layout header. - * - * @addtogroup USB - * @{ - */ - -#ifndef STM32_OTG_H -#define STM32_OTG_H - -/** - * @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 - * @{ - */ -/* Definitions for stepping 1.*/ -#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. */ - -/* Definitions for stepping 2.*/ -#define GCCFG_VBDEN (1U<<21) /**< VBUS sensing enable. */ -#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_AHBERR (1U<<2) /**< AHB error 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) /**< AHB error interrupt mask. */ -#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_SETUP_RCVD (1U<<15) /**< SETUP packet received. */ -#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. */ -/** @} */ - -#if defined(STM32H7XX) || defined(__DOXYGEN__) -/** - * @brief OTG_FS registers block memory address. - */ -#define OTG_FS_ADDR 0x40080000 - -/** - * @brief OTG_HS registers block memory address. - */ -#define OTG_HS_ADDR 0x40040000 -#else -#define OTG_FS_ADDR 0x50000000 -#define OTG_HS_ADDR 0x40040000 -#endif - -/** - * @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 */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 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 OTGv1/stm32_otg.h + * @brief STM32 OTG registers layout header. + * + * @addtogroup USB + * @{ + */ + +#ifndef STM32_OTG_H +#define STM32_OTG_H + +/** + * @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 (0x7FFU << 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 (15U << 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 (0x7FFU << 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 (0xFFFFU << 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 (0xFFFFU << 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 + * @{ + */ +/* Definitions for stepping 1.*/ +#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. */ + +/* Definitions for stepping 2.*/ +#define GCCFG_VBDEN (1U << 21) /**< VBUS sensing enable. */ +#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 (15U << 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_AHBERR (1U << 2) /**< AHB error 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) /**< AHB error interrupt mask. */ +#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 (0x7FFFFU << 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 (3U << 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 (0xFFFFU << 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_SETUP_RCVD (1U << 15) /**< SETUP packet received. */ +#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. */ +/** @} */ + +#if defined(STM32H7XX) || defined(__DOXYGEN__) +/** + * @brief OTG_FS registers block memory address. + */ +#define OTG_FS_ADDR 0x40080000 + +/** + * @brief OTG_HS registers block memory address. + */ +#define OTG_HS_ADDR 0x40040000 +#else +#define OTG_FS_ADDR 0x50000000 +#define OTG_HS_ADDR 0x40040000 +#endif + +/** + * @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/readme.txt b/readme.txt index 46f03c0084..e02a21ac5e 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed remote wakeup failure in STM32 OTGv1 driver (bug #1252). - FIX: Fixed wrong use of hooks in RT/NIL (bug #1251). - FIX: Fixed wrong initialization in STM32L1xx ADC driver (bug #1247). - FIX: Fixed wrong HSI48 support on STM32L0xx (bug #1246). From 44ee205c5b68c7b0c17917616654c0c1a8d156a8 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 4 Mar 2023 08:54:54 +0000 Subject: [PATCH 18/53] Fixed bug #1253. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16126 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/STM32H7xx/hal_lld.h | 9 ++++----- readme.txt | 1 + 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/os/hal/ports/STM32/STM32H7xx/hal_lld.h b/os/hal/ports/STM32/STM32H7xx/hal_lld.h index b640fa246c..ad99c07002 100644 --- a/os/hal/ports/STM32/STM32H7xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32H7xx/hal_lld.h @@ -1753,9 +1753,8 @@ /** * @brief PLL1 DIVP field. */ -#if ((STM32_PLL1_DIVP_VALUE >= 2) && (STM32_PLL1_DIVP_VALUE <= 128) && \ - ((STM32_PLL1_DIVP_VALUE & 1U) == 0U)) || \ - defined(__DOXYGEN__) +#if ((STM32_PLL1_DIVP_VALUE >= 1) && (STM32_PLL1_DIVP_VALUE <= 128)) && \ + ((STM32_PLL1_DIVP_VALUE == 1) || ((STM32_PLL1_DIVP_VALUE & 1) == 0)) #define STM32_PLL1_DIVP ((STM32_PLL1_DIVP_VALUE - 1U) << 9U) #else #error "invalid STM32_PLL1_DIVP_VALUE value specified" @@ -1764,7 +1763,7 @@ /** * @brief PLL2 DIVP field. */ -#if ((STM32_PLL2_DIVP_VALUE >= 2) && (STM32_PLL2_DIVP_VALUE <= 128)) || \ +#if ((STM32_PLL2_DIVP_VALUE >= 1) && (STM32_PLL2_DIVP_VALUE <= 128)) || \ defined(__DOXYGEN__) #define STM32_PLL2_DIVP ((STM32_PLL2_DIVP_VALUE - 1U) << 9U) #else @@ -1774,7 +1773,7 @@ /** * @brief PLL3 DIVP field. */ -#if ((STM32_PLL3_DIVP_VALUE >= 2) && (STM32_PLL3_DIVP_VALUE <= 128)) || \ +#if ((STM32_PLL3_DIVP_VALUE >= 1) && (STM32_PLL3_DIVP_VALUE <= 128)) || \ defined(__DOXYGEN__) #define STM32_PLL3_DIVP ((STM32_PLL3_DIVP_VALUE - 1U) << 9U) #else diff --git a/readme.txt b/readme.txt index e02a21ac5e..e3266bf86e 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed invalid checks on PLLP/R/Q dividers on STM32H7 (bug #1253). - FIX: Fixed remote wakeup failure in STM32 OTGv1 driver (bug #1252). - FIX: Fixed wrong use of hooks in RT/NIL (bug #1251). - FIX: Fixed wrong initialization in STM32L1xx ADC driver (bug #1247). From 987b26f3f003b46ba118d4946896c5806015df38 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 4 Mar 2023 09:12:46 +0000 Subject: [PATCH 19/53] More bug #1252. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16127 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/src/hal_usb.c | 2011 +++++++++++++++++++++--------------------- 1 file changed, 1009 insertions(+), 1002 deletions(-) diff --git a/os/hal/src/hal_usb.c b/os/hal/src/hal_usb.c index caa8d6dcc3..73df1300ed 100644 --- a/os/hal/src/hal_usb.c +++ b/os/hal/src/hal_usb.c @@ -1,1002 +1,1009 @@ -/* - ChibiOS - Copyright (C) 2006..2018 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 hal_usb.c - * @brief USB Driver code. - * - * @addtogroup USB - * @{ - */ - -#include - -#include "hal.h" - -#if (HAL_USE_USB == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -static const uint8_t zero_status[] = {0x00, 0x00}; -static const uint8_t active_status[] = {0x00, 0x00}; -static const uint8_t halted_status[] = {0x01, 0x00}; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -static uint16_t get_hword(uint8_t *p) { - uint16_t hw; - - hw = (uint16_t)*p++; - hw |= (uint16_t)*p << 8U; - return hw; -} - -/** - * @brief SET ADDRESS transaction callback. - * - * @param[in] usbp pointer to the @p USBDriver object - */ -static void set_address(USBDriver *usbp) { - - usbp->address = usbp->setup[2]; - usb_lld_set_address(usbp); - _usb_isr_invoke_event_cb(usbp, USB_EVENT_ADDRESS); - usbp->state = USB_SELECTED; -} - -/** - * @brief Standard requests handler. - * @details This is the standard requests default handler, most standard - * requests are handled here, the user can override the standard - * handling using the @p requests_hook_cb hook in the - * @p USBConfig structure. - * - * @param[in] usbp pointer to the @p USBDriver object - * @return The request handling exit code. - * @retval false Request not recognized by the handler or error. - * @retval true Request handled. - */ -static bool default_handler(USBDriver *usbp) { - const USBDescriptor *dp; - - /* Decoding the request.*/ - switch ((((uint32_t)usbp->setup[0] & (USB_RTYPE_RECIPIENT_MASK | - USB_RTYPE_TYPE_MASK)) | - ((uint32_t)usbp->setup[1] << 8U))) { - case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_GET_STATUS << 8): - /* Just returns the current status word.*/ - usbSetupTransfer(usbp, (uint8_t *)&usbp->status, 2, NULL); - return true; - case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_CLEAR_FEATURE << 8): - /* Only the DEVICE_REMOTE_WAKEUP is handled here, any other feature - number is handled as an error.*/ - if (usbp->setup[2] == USB_FEATURE_DEVICE_REMOTE_WAKEUP) { - usbp->status &= ~2U; - usbSetupTransfer(usbp, NULL, 0, NULL); - return true; - } - return false; - case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_SET_FEATURE << 8): - /* Only the DEVICE_REMOTE_WAKEUP is handled here, any other feature - number is handled as an error.*/ - if (usbp->setup[2] == USB_FEATURE_DEVICE_REMOTE_WAKEUP) { - usbp->status |= 2U; - usbSetupTransfer(usbp, NULL, 0, NULL); - return true; - } - return false; - case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_SET_ADDRESS << 8): - /* The SET_ADDRESS handling can be performed here or postponed after - the status packed depending on the USB_SET_ADDRESS_MODE low - driver setting.*/ -#if USB_SET_ADDRESS_MODE == USB_EARLY_SET_ADDRESS - if ((usbp->setup[0] == USB_RTYPE_RECIPIENT_DEVICE) && - (usbp->setup[1] == USB_REQ_SET_ADDRESS)) { - set_address(usbp); - } - usbSetupTransfer(usbp, NULL, 0, NULL); -#else - usbSetupTransfer(usbp, NULL, 0, set_address); -#endif - return true; - case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_GET_DESCRIPTOR << 8): - case (uint32_t)USB_RTYPE_RECIPIENT_INTERFACE | ((uint32_t)USB_REQ_GET_DESCRIPTOR << 8): - /* Handling descriptor requests from the host.*/ - dp = usbp->config->get_descriptor_cb(usbp, usbp->setup[3], - usbp->setup[2], - get_hword(&usbp->setup[4])); - if (dp == NULL) { - return false; - } - /*lint -save -e9005 [11.8] Removing const is fine.*/ - usbSetupTransfer(usbp, (uint8_t *)dp->ud_string, dp->ud_size, NULL); - /*lint -restore*/ - return true; - case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_GET_CONFIGURATION << 8): - /* Returning the last selected configuration.*/ - usbSetupTransfer(usbp, &usbp->configuration, 1, NULL); - return true; - case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_SET_CONFIGURATION << 8): -#if defined(USB_SET_CONFIGURATION_OLD_BEHAVIOR) - /* Handling configuration selection from the host only if it is different - from the current configuration.*/ - if (usbp->configuration != usbp->setup[2]) -#endif - { - /* If the USB device is already active then we have to perform the clear - procedure on the current configuration.*/ - if (usbp->state == USB_ACTIVE) { - /* Current configuration cleared.*/ - osalSysLockFromISR (); - usbDisableEndpointsI(usbp); - osalSysUnlockFromISR (); - usbp->configuration = 0U; - usbp->state = USB_SELECTED; - _usb_isr_invoke_event_cb(usbp, USB_EVENT_UNCONFIGURED); - } - if (usbp->setup[2] != 0U) { - /* New configuration.*/ - usbp->configuration = usbp->setup[2]; - usbp->state = USB_ACTIVE; - _usb_isr_invoke_event_cb(usbp, USB_EVENT_CONFIGURED); - } - } - usbSetupTransfer(usbp, NULL, 0, NULL); - return true; - case (uint32_t)USB_RTYPE_RECIPIENT_INTERFACE | ((uint32_t)USB_REQ_GET_STATUS << 8): - case (uint32_t)USB_RTYPE_RECIPIENT_ENDPOINT | ((uint32_t)USB_REQ_SYNCH_FRAME << 8): - /* Just sending two zero bytes, the application can change the behavior - using a hook..*/ - /*lint -save -e9005 [11.8] Removing const is fine.*/ - usbSetupTransfer(usbp, (uint8_t *)zero_status, 2, NULL); - /*lint -restore*/ - return true; - case (uint32_t)USB_RTYPE_RECIPIENT_ENDPOINT | ((uint32_t)USB_REQ_GET_STATUS << 8): - /* Sending the EP status.*/ - if ((usbp->setup[4] & 0x80U) != 0U) { - switch (usb_lld_get_status_in(usbp, usbp->setup[4] & 0x0FU)) { - case EP_STATUS_STALLED: - /*lint -save -e9005 [11.8] Removing const is fine.*/ - usbSetupTransfer(usbp, (uint8_t *)halted_status, 2, NULL); - /*lint -restore*/ - return true; - case EP_STATUS_ACTIVE: - /*lint -save -e9005 [11.8] Removing const is fine.*/ - usbSetupTransfer(usbp, (uint8_t *)active_status, 2, NULL); - /*lint -restore*/ - return true; - case EP_STATUS_DISABLED: - default: - return false; - } - } - else { - switch (usb_lld_get_status_out(usbp, usbp->setup[4] & 0x0FU)) { - case EP_STATUS_STALLED: - /*lint -save -e9005 [11.8] Removing const is fine.*/ - usbSetupTransfer(usbp, (uint8_t *)halted_status, 2, NULL); - /*lint -restore*/ - return true; - case EP_STATUS_ACTIVE: - /*lint -save -e9005 [11.8] Removing const is fine.*/ - usbSetupTransfer(usbp, (uint8_t *)active_status, 2, NULL); - /*lint -restore*/ - return true; - case EP_STATUS_DISABLED: - default: - return false; - } - } - case (uint32_t)USB_RTYPE_RECIPIENT_ENDPOINT | ((uint32_t)USB_REQ_CLEAR_FEATURE << 8): - /* Only ENDPOINT_HALT is handled as feature.*/ - if (usbp->setup[2] != USB_FEATURE_ENDPOINT_HALT) { - return false; - } - /* Clearing the EP status, not valid for EP0, it is ignored in that case.*/ - if ((usbp->setup[4] & 0x0FU) != 0U) { - if ((usbp->setup[4] & 0x80U) != 0U) { - usb_lld_clear_in(usbp, usbp->setup[4] & 0x0FU); - } - else { - usb_lld_clear_out(usbp, usbp->setup[4] & 0x0FU); - } - } - usbSetupTransfer(usbp, NULL, 0, NULL); - return true; - case (uint32_t)USB_RTYPE_RECIPIENT_ENDPOINT | ((uint32_t)USB_REQ_SET_FEATURE << 8): - /* Only ENDPOINT_HALT is handled as feature.*/ - if (usbp->setup[2] != USB_FEATURE_ENDPOINT_HALT) { - return false; - } - /* Stalling the EP, not valid for EP0, it is ignored in that case.*/ - if ((usbp->setup[4] & 0x0FU) != 0U) { - if ((usbp->setup[4] & 0x80U) != 0U) { - usb_lld_stall_in(usbp, usbp->setup[4] & 0x0FU); - } - else { - usb_lld_stall_out(usbp, usbp->setup[4] & 0x0FU); - } - } - usbSetupTransfer(usbp, NULL, 0, NULL); - return true; - case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_SET_DESCRIPTOR << 8): - case (uint32_t)USB_RTYPE_RECIPIENT_INTERFACE | ((uint32_t)USB_REQ_CLEAR_FEATURE << 8): - case (uint32_t)USB_RTYPE_RECIPIENT_INTERFACE | ((uint32_t)USB_REQ_SET_FEATURE << 8): - case (uint32_t)USB_RTYPE_RECIPIENT_INTERFACE | ((uint32_t)USB_REQ_GET_INTERFACE << 8): - case (uint32_t)USB_RTYPE_RECIPIENT_INTERFACE | ((uint32_t)USB_REQ_SET_INTERFACE << 8): - /* All the above requests are not handled here, if you need them then - use the hook mechanism and provide handling.*/ - default: - return false; - } -} - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief USB Driver initialization. - * @note This function is implicitly invoked by @p halInit(), there is - * no need to explicitly initialize the driver. - * - * @init - */ -void usbInit(void) { - - usb_lld_init(); -} - -/** - * @brief Initializes the standard part of a @p USBDriver structure. - * - * @param[out] usbp pointer to the @p USBDriver object - * - * @init - */ -void usbObjectInit(USBDriver *usbp) { - unsigned i; - - usbp->state = USB_STOP; - usbp->config = NULL; - for (i = 0; i < (unsigned)USB_MAX_ENDPOINTS; i++) { - usbp->in_params[i] = NULL; - usbp->out_params[i] = NULL; - } - usbp->transmitting = 0; - usbp->receiving = 0; -} - -/** - * @brief Configures and activates the USB peripheral. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] config pointer to the @p USBConfig object - * - * @api - */ -void usbStart(USBDriver *usbp, const USBConfig *config) { - unsigned i; - - osalDbgCheck((usbp != NULL) && (config != NULL)); - - osalSysLock(); - osalDbgAssert((usbp->state == USB_STOP) || (usbp->state == USB_READY), - "invalid state"); - usbp->config = config; - for (i = 0; i <= (unsigned)USB_MAX_ENDPOINTS; i++) { - usbp->epc[i] = NULL; - } - usb_lld_start(usbp); - usbp->state = USB_READY; - osalSysUnlock(); -} - -/** - * @brief Deactivates the USB peripheral. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @api - */ -void usbStop(USBDriver *usbp) { - unsigned i; - - osalDbgCheck(usbp != NULL); - - osalSysLock(); - - osalDbgAssert((usbp->state == USB_STOP) || (usbp->state == USB_READY) || - (usbp->state == USB_SELECTED) || (usbp->state == USB_ACTIVE) || - (usbp->state == USB_SUSPENDED), - "invalid state"); - - usb_lld_stop(usbp); - usbp->config = NULL; - usbp->state = USB_STOP; - - /* Resetting all ongoing synchronous operations.*/ - for (i = 0; i <= (unsigned)USB_MAX_ENDPOINTS; i++) { -#if USB_USE_WAIT == TRUE - if (usbp->epc[i] != NULL) { - if (usbp->epc[i]->in_state != NULL) { - osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_RESET); - } - if (usbp->epc[i]->out_state != NULL) { - osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_RESET); - } - } -#endif - usbp->epc[i] = NULL; - } - osalOsRescheduleS(); - - osalSysUnlock(); -} - -/** - * @brief Enables an endpoint. - * @details This function enables an endpoint, both IN and/or OUT directions - * depending on the configuration structure. - * @note This function must be invoked in response of a SET_CONFIGURATION - * or SET_INTERFACE message. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @param[in] epcp the endpoint configuration - * - * @iclass - */ -void usbInitEndpointI(USBDriver *usbp, usbep_t ep, - const USBEndpointConfig *epcp) { - - osalDbgCheckClassI(); - osalDbgCheck((usbp != NULL) && (epcp != NULL)); - osalDbgAssert(usbp->state == USB_ACTIVE, - "invalid state"); - osalDbgAssert(usbp->epc[ep] == NULL, "already initialized"); - - /* Logically enabling the endpoint in the USBDriver structure.*/ - usbp->epc[ep] = epcp; - - /* Clearing the state structures, custom fields as well.*/ - if (epcp->in_state != NULL) { - memset(epcp->in_state, 0, sizeof(USBInEndpointState)); - } - if (epcp->out_state != NULL) { - memset(epcp->out_state, 0, sizeof(USBOutEndpointState)); - } - - /* Low level endpoint activation.*/ - usb_lld_init_endpoint(usbp, ep); -} - -/** - * @brief Disables all the active endpoints. - * @details This function disables all the active endpoints except the - * endpoint zero. - * @note This function must be invoked in response of a SET_CONFIGURATION - * message with configuration number zero. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @iclass - */ -void usbDisableEndpointsI(USBDriver *usbp) { - unsigned i; - - osalDbgCheckClassI(); - osalDbgCheck(usbp != NULL); - osalDbgAssert(usbp->state == USB_ACTIVE, "invalid state"); - - usbp->transmitting &= 1U; - usbp->receiving &= 1U; - - for (i = 1; i <= (unsigned)USB_MAX_ENDPOINTS; i++) { -#if USB_USE_WAIT == TRUE - /* Signaling the event to threads waiting on endpoints.*/ - if (usbp->epc[i] != NULL) { - if (usbp->epc[i]->in_state != NULL) { - osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_RESET); - } - if (usbp->epc[i]->out_state != NULL) { - osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_RESET); - } - } -#endif - usbp->epc[i] = NULL; - } - - /* Low level endpoints deactivation.*/ - usb_lld_disable_endpoints(usbp); -} - -/** - * @brief Starts a receive transaction on an OUT endpoint. - * @note This function is meant to be called from ISR context outside - * critical zones because there is a potentially slow operation - * inside. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @param[out] buf buffer where to copy the received data - * @param[in] n transaction size. It is recommended a multiple of - * the packet size because the excess is discarded. - * - * @iclass - */ -void usbStartReceiveI(USBDriver *usbp, usbep_t ep, - uint8_t *buf, size_t n) { - USBOutEndpointState *osp; - - osalDbgCheckClassI(); - osalDbgCheck((usbp != NULL) && (ep <= (usbep_t)USB_MAX_ENDPOINTS)); - osalDbgAssert(!usbGetReceiveStatusI(usbp, ep), "already receiving"); - - /* Marking the endpoint as active.*/ - usbp->receiving |= (uint16_t)((unsigned)1U << (unsigned)ep); - - /* Setting up the transfer.*/ - /*lint -save -e661 [18.1] pclint is confused by the check on ep.*/ - osp = usbp->epc[ep]->out_state; - /*lint -restore*/ - osp->rxbuf = buf; - osp->rxsize = n; - osp->rxcnt = 0; -#if USB_USE_WAIT == TRUE - osp->thread = NULL; -#endif - - /* Starting transfer.*/ - usb_lld_start_out(usbp, ep); -} - -/** - * @brief Starts a transmit transaction on an IN endpoint. - * @note This function is meant to be called from ISR context outside - * critical zones because there is a potentially slow operation - * inside. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @param[in] buf buffer where to fetch the data to be transmitted - * @param[in] n transaction size - * - * @iclass - */ -void usbStartTransmitI(USBDriver *usbp, usbep_t ep, - const uint8_t *buf, size_t n) { - USBInEndpointState *isp; - - osalDbgCheckClassI(); - osalDbgCheck((usbp != NULL) && (ep <= (usbep_t)USB_MAX_ENDPOINTS)); - osalDbgAssert(!usbGetTransmitStatusI(usbp, ep), "already transmitting"); - - /* Marking the endpoint as active.*/ - usbp->transmitting |= (uint16_t)((unsigned)1U << (unsigned)ep); - - /* Setting up the transfer.*/ - /*lint -save -e661 [18.1] pclint is confused by the check on ep.*/ - isp = usbp->epc[ep]->in_state; - /*lint -restore*/ - isp->txbuf = buf; - isp->txsize = n; - isp->txcnt = 0; -#if USB_USE_WAIT == TRUE - isp->thread = NULL; -#endif - - /* Starting transfer.*/ - usb_lld_start_in(usbp, ep); -} - -#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__) -/** - * @brief Performs a receive transaction on an OUT endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @param[out] buf buffer where to copy the received data - * @param[in] n transaction size. It is recommended a multiple of - * the packet size because the excess is discarded. - * - * @return The received effective data size, it can be less than - * the amount specified. - * @retval MSG_RESET driver not in @p USB_ACTIVE state or the operation - * has been aborted by an USB reset or a transition to - * the @p USB_SUSPENDED state. - * - * @api - */ -msg_t usbReceive(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) { - msg_t msg; - - osalSysLock(); - - if (usbGetDriverStateI(usbp) != USB_ACTIVE) { - osalSysUnlock(); - return MSG_RESET; - } - - usbStartReceiveI(usbp, ep, buf, n); - msg = osalThreadSuspendS(&usbp->epc[ep]->out_state->thread); - osalSysUnlock(); - - return msg; -} - -/** - * @brief Performs a transmit transaction on an IN endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @param[in] buf buffer where to fetch the data to be transmitted - * @param[in] n transaction size - * - * @return The operation status. - * @retval MSG_OK operation performed successfully. - * @retval MSG_RESET driver not in @p USB_ACTIVE state or the operation - * has been aborted by an USB reset or a transition to - * the @p USB_SUSPENDED state. - * - * @api - */ -msg_t usbTransmit(USBDriver *usbp, usbep_t ep, const uint8_t *buf, size_t n) { - msg_t msg; - - osalSysLock(); - - if (usbGetDriverStateI(usbp) != USB_ACTIVE) { - osalSysUnlock(); - return MSG_RESET; - } - - usbStartTransmitI(usbp, ep, buf, n); - msg = osalThreadSuspendS(&usbp->epc[ep]->in_state->thread); - osalSysUnlock(); - - return msg; -} -#endif /* USB_USE_WAIT == TRUE */ - -/** - * @brief Stalls an OUT endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @return The operation status. - * @retval false Endpoint stalled. - * @retval true Endpoint busy, not stalled. - * - * @iclass - */ -bool usbStallReceiveI(USBDriver *usbp, usbep_t ep) { - - osalDbgCheckClassI(); - osalDbgCheck(usbp != NULL); - - if (usbGetReceiveStatusI(usbp, ep)) { - return true; - } - - usb_lld_stall_out(usbp, ep); - return false; -} - -/** - * @brief Stalls an IN endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @return The operation status. - * @retval false Endpoint stalled. - * @retval true Endpoint busy, not stalled. - * - * @iclass - */ -bool usbStallTransmitI(USBDriver *usbp, usbep_t ep) { - - osalDbgCheckClassI(); - osalDbgCheck(usbp != NULL); - - if (usbGetTransmitStatusI(usbp, ep)) { - return true; - } - - usb_lld_stall_in(usbp, ep); - return false; -} - -/** - * @brief Host wake-up procedure. - * @note It is silently ignored if the USB device is not in the - * @p USB_SUSPENDED state. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @api - */ -void usbWakeupHost(USBDriver *usbp) { - - if (usbp->state == USB_SUSPENDED) { - /* Starting host wakeup procedure.*/ - usb_lld_wakeup_host(usbp); - } -} - -/** - * @brief USB reset routine. - * @details This function must be invoked when an USB bus reset condition is - * detected. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void _usb_reset(USBDriver *usbp) { - unsigned i; - - /* State transition.*/ - usbp->state = USB_READY; - - /* Resetting internal state.*/ - usbp->status = 0; - usbp->address = 0; - usbp->configuration = 0; - usbp->transmitting = 0; - usbp->receiving = 0; - - /* Invalidates all endpoints into the USBDriver structure.*/ - for (i = 0; i <= (unsigned)USB_MAX_ENDPOINTS; i++) { -#if USB_USE_WAIT == TRUE - /* Signaling the event to threads waiting on endpoints.*/ - if (usbp->epc[i] != NULL) { - osalSysLockFromISR(); - if (usbp->epc[i]->in_state != NULL) { - osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_RESET); - } - if (usbp->epc[i]->out_state != NULL) { - osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_RESET); - } - osalSysUnlockFromISR(); - } -#endif - usbp->epc[i] = NULL; - } - - /* EP0 state machine initialization.*/ - usbp->ep0state = USB_EP0_STP_WAITING; - - /* Low level reset.*/ - usb_lld_reset(usbp); - - /* Notification of reset event.*/ - _usb_isr_invoke_event_cb(usbp, USB_EVENT_RESET); -} - -/** - * @brief USB suspend routine. - * @details This function must be invoked when an USB bus suspend condition is - * detected. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void _usb_suspend(USBDriver *usbp) { - /* No state change, suspend always returns to previous state. */ - - /* State transition.*/ - usbp->saved_state = usbp->state; - usbp->state = USB_SUSPENDED; - - /* Notification of suspend event.*/ - _usb_isr_invoke_event_cb(usbp, USB_EVENT_SUSPEND); - - /* Terminating all pending transactions.*/ - usbp->transmitting = 0; - usbp->receiving = 0; - - /* Signaling the event to threads waiting on endpoints.*/ -#if USB_USE_WAIT == TRUE - { - unsigned i; - - for (i = 0; i <= (unsigned)USB_MAX_ENDPOINTS; i++) { - if (usbp->epc[i] != NULL) { - osalSysLockFromISR(); - if (usbp->epc[i]->in_state != NULL) { - osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_RESET); - } - if (usbp->epc[i]->out_state != NULL) { - osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_RESET); - } - osalSysUnlockFromISR(); - } - } - } -#endif -} - -/** - * @brief USB wake-up routine. - * @details This function must be invoked when an USB bus wake-up condition is - * detected. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void _usb_wakeup(USBDriver *usbp) { - - /* State transition, returning to the previous state.*/ - usbp->state = usbp->saved_state; - - /* Notification of suspend event.*/ - _usb_isr_invoke_event_cb(usbp, USB_EVENT_WAKEUP); -} - -/** - * @brief Default EP0 SETUP callback. - * @details This function is used by the low level driver as default handler - * for EP0 SETUP events. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number, always zero - * - * @notapi - */ -void _usb_ep0setup(USBDriver *usbp, usbep_t ep) { - size_t max; - - /* Is the EP0 state machine in the correct state for handling setup - packets?*/ - if (usbp->ep0state != USB_EP0_STP_WAITING) { - /* This is unexpected could require handling with a warning event.*/ - /* CHTODO: handling here.*/ - - /* Resetting the EP0 state machine and going ahead.*/ - usbp->ep0state = USB_EP0_STP_WAITING; - } - - /* Reading the setup data into the driver buffer.*/ - usbReadSetup(usbp, ep, usbp->setup); - - /* First verify if the application has an handler installed for this - request.*/ - /*lint -save -e9007 [13.5] No side effects, it is intentional.*/ - if ((usbp->config->requests_hook_cb == NULL) || - !(usbp->config->requests_hook_cb(usbp))) { - /*lint -restore*/ - /* Invoking the default handler, if this fails then stalls the - endpoint zero as error.*/ - /*lint -save -e9007 [13.5] No side effects, it is intentional.*/ - if (((usbp->setup[0] & USB_RTYPE_TYPE_MASK) != USB_RTYPE_TYPE_STD) || - !default_handler(usbp)) { - /*lint -restore*/ - /* Error response, the state machine goes into an error state, the low - level layer will have to reset it to USB_EP0_WAITING_SETUP after - receiving a SETUP packet.*/ - usb_lld_stall_in(usbp, 0); - usb_lld_stall_out(usbp, 0); - _usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED); - usbp->ep0state = USB_EP0_ERROR; - return; - } - } -#if (USB_SET_ADDRESS_ACK_HANDLING == USB_SET_ADDRESS_ACK_HW) - if (usbp->setup[1] == USB_REQ_SET_ADDRESS) { - /* Zero-length packet sent by hardware */ - return; - } -#endif - /* Transfer preparation. The request handler must have populated - correctly the fields ep0next, ep0n and ep0endcb using the macro - usbSetupTransfer().*/ - max = (size_t)get_hword(&usbp->setup[6]); - /* The transfer size cannot exceed the specified amount.*/ - if (usbp->ep0n > max) { - usbp->ep0n = max; - } - if ((usbp->setup[0] & USB_RTYPE_DIR_MASK) == USB_RTYPE_DIR_DEV2HOST) { - /* IN phase.*/ - if (usbp->ep0n != 0U) { - /* Starts the transmit phase.*/ - usbp->ep0state = USB_EP0_IN_TX; - osalSysLockFromISR(); - usbStartTransmitI(usbp, 0, usbp->ep0next, usbp->ep0n); - osalSysUnlockFromISR(); - } - else { - /* No transmission phase, directly receiving the zero sized status - packet.*/ - usbp->ep0state = USB_EP0_OUT_WAITING_STS; -#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) - osalSysLockFromISR(); - usbStartReceiveI(usbp, 0, NULL, 0); - osalSysUnlockFromISR(); -#else - usb_lld_end_setup(usbp, ep); -#endif - } - } - else { - /* OUT phase.*/ - if (usbp->ep0n != 0U) { - /* Starts the receive phase.*/ - usbp->ep0state = USB_EP0_OUT_RX; - osalSysLockFromISR(); - usbStartReceiveI(usbp, 0, (uint8_t *)usbp->ep0next, usbp->ep0n); - osalSysUnlockFromISR(); - } - else { - /* No receive phase, directly sending the zero sized status - packet.*/ - usbp->ep0state = USB_EP0_IN_SENDING_STS; -#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) - osalSysLockFromISR(); - usbStartTransmitI(usbp, 0, NULL, 0); - osalSysUnlockFromISR(); -#else - usb_lld_end_setup(usbp, ep); -#endif - } - } -} - -/** - * @brief Default EP0 IN callback. - * @details This function is used by the low level driver as default handler - * for EP0 IN events. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number, always zero - * - * @notapi - */ -void _usb_ep0in(USBDriver *usbp, usbep_t ep) { - size_t max; - - (void)ep; - switch (usbp->ep0state) { - case USB_EP0_IN_TX: - max = (size_t)get_hword(&usbp->setup[6]); - /* If the transmitted size is less than the requested size and it is a - multiple of the maximum packet size then a zero size packet must be - transmitted.*/ - if ((usbp->ep0n < max) && - ((usbp->ep0n % usbp->epc[0]->in_maxsize) == 0U)) { - osalSysLockFromISR(); - usbStartTransmitI(usbp, 0, NULL, 0); - osalSysUnlockFromISR(); - usbp->ep0state = USB_EP0_IN_WAITING_TX0; - return; - } - /* Falls through.*/ - case USB_EP0_IN_WAITING_TX0: - /* Transmit phase over, receiving the zero sized status packet.*/ - usbp->ep0state = USB_EP0_OUT_WAITING_STS; -#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) - osalSysLockFromISR(); - usbStartReceiveI(usbp, 0, NULL, 0); - osalSysUnlockFromISR(); -#else - usb_lld_end_setup(usbp, ep); -#endif - return; - case USB_EP0_IN_SENDING_STS: - /* Status packet sent, invoking the callback if defined.*/ - if (usbp->ep0endcb != NULL) { - usbp->ep0endcb(usbp); - } - usbp->ep0state = USB_EP0_STP_WAITING; - return; - case USB_EP0_STP_WAITING: - case USB_EP0_OUT_WAITING_STS: - case USB_EP0_OUT_RX: - /* All the above are invalid states in the IN phase.*/ - osalDbgAssert(false, "EP0 state machine error"); - /* Falls through.*/ - case USB_EP0_ERROR: - /* Error response, the state machine goes into an error state, the low - level layer will have to reset it to USB_EP0_WAITING_SETUP after - receiving a SETUP packet.*/ - usb_lld_stall_in(usbp, 0); - usb_lld_stall_out(usbp, 0); - _usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED); - usbp->ep0state = USB_EP0_ERROR; - return; - default: - osalDbgAssert(false, "EP0 state machine invalid state"); - } -} - -/** - * @brief Default EP0 OUT callback. - * @details This function is used by the low level driver as default handler - * for EP0 OUT events. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number, always zero - * - * @notapi - */ -void _usb_ep0out(USBDriver *usbp, usbep_t ep) { - - (void)ep; - switch (usbp->ep0state) { - case USB_EP0_OUT_RX: - /* Receive phase over, sending the zero sized status packet.*/ - usbp->ep0state = USB_EP0_IN_SENDING_STS; -#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) - osalSysLockFromISR(); - usbStartTransmitI(usbp, 0, NULL, 0); - osalSysUnlockFromISR(); -#else - usb_lld_end_setup(usbp, ep); -#endif - return; - case USB_EP0_OUT_WAITING_STS: - /* Status packet received, it must be zero sized, invoking the callback - if defined.*/ -#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) - if (usbGetReceiveTransactionSizeX(usbp, 0) != 0U) { - break; - } -#endif - if (usbp->ep0endcb != NULL) { - usbp->ep0endcb(usbp); - } - usbp->ep0state = USB_EP0_STP_WAITING; - return; - case USB_EP0_STP_WAITING: - case USB_EP0_IN_TX: - case USB_EP0_IN_WAITING_TX0: - case USB_EP0_IN_SENDING_STS: - /* All the above are invalid states in the IN phase.*/ - osalDbgAssert(false, "EP0 state machine error"); - /* Falls through.*/ - case USB_EP0_ERROR: - /* Error response, the state machine goes into an error state, the low - level layer will have to reset it to USB_EP0_WAITING_SETUP after - receiving a SETUP packet.*/ - usb_lld_stall_in(usbp, 0); - usb_lld_stall_out(usbp, 0); - _usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED); - usbp->ep0state = USB_EP0_ERROR; - return; - default: - osalDbgAssert(false, "EP0 state machine invalid state"); - } -} - -#endif /* HAL_USE_USB == TRUE */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 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 hal_usb.c + * @brief USB Driver code. + * + * @addtogroup USB + * @{ + */ + +#include + +#include "hal.h" + +#if (HAL_USE_USB == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +static const uint8_t zero_status[] = {0x00, 0x00}; +static const uint8_t active_status[] = {0x00, 0x00}; +static const uint8_t halted_status[] = {0x01, 0x00}; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static uint16_t get_hword(uint8_t *p) { + uint16_t hw; + + hw = (uint16_t)*p++; + hw |= (uint16_t)*p << 8U; + return hw; +} + +/** + * @brief SET ADDRESS transaction callback. + * + * @param[in] usbp pointer to the @p USBDriver object + */ +static void set_address(USBDriver *usbp) { + + usbp->address = usbp->setup[2]; + usb_lld_set_address(usbp); + _usb_isr_invoke_event_cb(usbp, USB_EVENT_ADDRESS); + usbp->state = USB_SELECTED; +} + +/** + * @brief Standard requests handler. + * @details This is the standard requests default handler, most standard + * requests are handled here, the user can override the standard + * handling using the @p requests_hook_cb hook in the + * @p USBConfig structure. + * + * @param[in] usbp pointer to the @p USBDriver object + * @return The request handling exit code. + * @retval false Request not recognized by the handler or error. + * @retval true Request handled. + */ +static bool default_handler(USBDriver *usbp) { + const USBDescriptor *dp; + + /* Decoding the request.*/ + switch ((((uint32_t)usbp->setup[0] & (USB_RTYPE_RECIPIENT_MASK | + USB_RTYPE_TYPE_MASK)) | + ((uint32_t)usbp->setup[1] << 8U))) { + case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_GET_STATUS << 8): + /* Just returns the current status word.*/ + usbSetupTransfer(usbp, (uint8_t *)&usbp->status, 2, NULL); + return true; + case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_CLEAR_FEATURE << 8): + /* Only the DEVICE_REMOTE_WAKEUP is handled here, any other feature + number is handled as an error.*/ + if (usbp->setup[2] == USB_FEATURE_DEVICE_REMOTE_WAKEUP) { + usbp->status &= ~2U; + usbSetupTransfer(usbp, NULL, 0, NULL); + return true; + } + return false; + case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_SET_FEATURE << 8): + /* Only the DEVICE_REMOTE_WAKEUP is handled here, any other feature + number is handled as an error.*/ + if (usbp->setup[2] == USB_FEATURE_DEVICE_REMOTE_WAKEUP) { + usbp->status |= 2U; + usbSetupTransfer(usbp, NULL, 0, NULL); + return true; + } + return false; + case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_SET_ADDRESS << 8): + /* The SET_ADDRESS handling can be performed here or postponed after + the status packed depending on the USB_SET_ADDRESS_MODE low + driver setting.*/ +#if USB_SET_ADDRESS_MODE == USB_EARLY_SET_ADDRESS + if ((usbp->setup[0] == USB_RTYPE_RECIPIENT_DEVICE) && + (usbp->setup[1] == USB_REQ_SET_ADDRESS)) { + set_address(usbp); + } + usbSetupTransfer(usbp, NULL, 0, NULL); +#else + usbSetupTransfer(usbp, NULL, 0, set_address); +#endif + return true; + case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_GET_DESCRIPTOR << 8): + case (uint32_t)USB_RTYPE_RECIPIENT_INTERFACE | ((uint32_t)USB_REQ_GET_DESCRIPTOR << 8): + /* Handling descriptor requests from the host.*/ + dp = usbp->config->get_descriptor_cb(usbp, usbp->setup[3], + usbp->setup[2], + get_hword(&usbp->setup[4])); + if (dp == NULL) { + return false; + } + /*lint -save -e9005 [11.8] Removing const is fine.*/ + usbSetupTransfer(usbp, (uint8_t *)dp->ud_string, dp->ud_size, NULL); + /*lint -restore*/ + return true; + case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_GET_CONFIGURATION << 8): + /* Returning the last selected configuration.*/ + usbSetupTransfer(usbp, &usbp->configuration, 1, NULL); + return true; + case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_SET_CONFIGURATION << 8): +#if defined(USB_SET_CONFIGURATION_OLD_BEHAVIOR) + /* Handling configuration selection from the host only if it is different + from the current configuration.*/ + if (usbp->configuration != usbp->setup[2]) +#endif + { + /* If the USB device is already active then we have to perform the clear + procedure on the current configuration.*/ + if (usbp->state == USB_ACTIVE) { + /* Current configuration cleared.*/ + osalSysLockFromISR (); + usbDisableEndpointsI(usbp); + osalSysUnlockFromISR (); + usbp->configuration = 0U; + usbp->state = USB_SELECTED; + _usb_isr_invoke_event_cb(usbp, USB_EVENT_UNCONFIGURED); + } + if (usbp->setup[2] != 0U) { + /* New configuration.*/ + usbp->configuration = usbp->setup[2]; + usbp->state = USB_ACTIVE; + _usb_isr_invoke_event_cb(usbp, USB_EVENT_CONFIGURED); + } + } + usbSetupTransfer(usbp, NULL, 0, NULL); + return true; + case (uint32_t)USB_RTYPE_RECIPIENT_INTERFACE | ((uint32_t)USB_REQ_GET_STATUS << 8): + case (uint32_t)USB_RTYPE_RECIPIENT_ENDPOINT | ((uint32_t)USB_REQ_SYNCH_FRAME << 8): + /* Just sending two zero bytes, the application can change the behavior + using a hook..*/ + /*lint -save -e9005 [11.8] Removing const is fine.*/ + usbSetupTransfer(usbp, (uint8_t *)zero_status, 2, NULL); + /*lint -restore*/ + return true; + case (uint32_t)USB_RTYPE_RECIPIENT_ENDPOINT | ((uint32_t)USB_REQ_GET_STATUS << 8): + /* Sending the EP status.*/ + if ((usbp->setup[4] & 0x80U) != 0U) { + switch (usb_lld_get_status_in(usbp, usbp->setup[4] & 0x0FU)) { + case EP_STATUS_STALLED: + /*lint -save -e9005 [11.8] Removing const is fine.*/ + usbSetupTransfer(usbp, (uint8_t *)halted_status, 2, NULL); + /*lint -restore*/ + return true; + case EP_STATUS_ACTIVE: + /*lint -save -e9005 [11.8] Removing const is fine.*/ + usbSetupTransfer(usbp, (uint8_t *)active_status, 2, NULL); + /*lint -restore*/ + return true; + case EP_STATUS_DISABLED: + default: + return false; + } + } + else { + switch (usb_lld_get_status_out(usbp, usbp->setup[4] & 0x0FU)) { + case EP_STATUS_STALLED: + /*lint -save -e9005 [11.8] Removing const is fine.*/ + usbSetupTransfer(usbp, (uint8_t *)halted_status, 2, NULL); + /*lint -restore*/ + return true; + case EP_STATUS_ACTIVE: + /*lint -save -e9005 [11.8] Removing const is fine.*/ + usbSetupTransfer(usbp, (uint8_t *)active_status, 2, NULL); + /*lint -restore*/ + return true; + case EP_STATUS_DISABLED: + default: + return false; + } + } + case (uint32_t)USB_RTYPE_RECIPIENT_ENDPOINT | ((uint32_t)USB_REQ_CLEAR_FEATURE << 8): + /* Only ENDPOINT_HALT is handled as feature.*/ + if (usbp->setup[2] != USB_FEATURE_ENDPOINT_HALT) { + return false; + } + /* Clearing the EP status, not valid for EP0, it is ignored in that case.*/ + if ((usbp->setup[4] & 0x0FU) != 0U) { + if ((usbp->setup[4] & 0x80U) != 0U) { + usb_lld_clear_in(usbp, usbp->setup[4] & 0x0FU); + } + else { + usb_lld_clear_out(usbp, usbp->setup[4] & 0x0FU); + } + } + usbSetupTransfer(usbp, NULL, 0, NULL); + return true; + case (uint32_t)USB_RTYPE_RECIPIENT_ENDPOINT | ((uint32_t)USB_REQ_SET_FEATURE << 8): + /* Only ENDPOINT_HALT is handled as feature.*/ + if (usbp->setup[2] != USB_FEATURE_ENDPOINT_HALT) { + return false; + } + /* Stalling the EP, not valid for EP0, it is ignored in that case.*/ + if ((usbp->setup[4] & 0x0FU) != 0U) { + if ((usbp->setup[4] & 0x80U) != 0U) { + usb_lld_stall_in(usbp, usbp->setup[4] & 0x0FU); + } + else { + usb_lld_stall_out(usbp, usbp->setup[4] & 0x0FU); + } + } + usbSetupTransfer(usbp, NULL, 0, NULL); + return true; + case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_SET_DESCRIPTOR << 8): + case (uint32_t)USB_RTYPE_RECIPIENT_INTERFACE | ((uint32_t)USB_REQ_CLEAR_FEATURE << 8): + case (uint32_t)USB_RTYPE_RECIPIENT_INTERFACE | ((uint32_t)USB_REQ_SET_FEATURE << 8): + case (uint32_t)USB_RTYPE_RECIPIENT_INTERFACE | ((uint32_t)USB_REQ_GET_INTERFACE << 8): + case (uint32_t)USB_RTYPE_RECIPIENT_INTERFACE | ((uint32_t)USB_REQ_SET_INTERFACE << 8): + /* All the above requests are not handled here, if you need them then + use the hook mechanism and provide handling.*/ + default: + return false; + } +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief USB Driver initialization. + * @note This function is implicitly invoked by @p halInit(), there is + * no need to explicitly initialize the driver. + * + * @init + */ +void usbInit(void) { + + usb_lld_init(); +} + +/** + * @brief Initializes the standard part of a @p USBDriver structure. + * + * @param[out] usbp pointer to the @p USBDriver object + * + * @init + */ +void usbObjectInit(USBDriver *usbp) { + unsigned i; + + usbp->state = USB_STOP; + usbp->config = NULL; + for (i = 0; i < (unsigned)USB_MAX_ENDPOINTS; i++) { + usbp->in_params[i] = NULL; + usbp->out_params[i] = NULL; + } + usbp->transmitting = 0; + usbp->receiving = 0; +} + +/** + * @brief Configures and activates the USB peripheral. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] config pointer to the @p USBConfig object + * + * @api + */ +void usbStart(USBDriver *usbp, const USBConfig *config) { + unsigned i; + + osalDbgCheck((usbp != NULL) && (config != NULL)); + + osalSysLock(); + osalDbgAssert((usbp->state == USB_STOP) || (usbp->state == USB_READY), + "invalid state"); + usbp->config = config; + for (i = 0; i <= (unsigned)USB_MAX_ENDPOINTS; i++) { + usbp->epc[i] = NULL; + } + usb_lld_start(usbp); + usbp->state = USB_READY; + osalSysUnlock(); +} + +/** + * @brief Deactivates the USB peripheral. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @api + */ +void usbStop(USBDriver *usbp) { + unsigned i; + + osalDbgCheck(usbp != NULL); + + osalSysLock(); + + osalDbgAssert((usbp->state == USB_STOP) || (usbp->state == USB_READY) || + (usbp->state == USB_SELECTED) || (usbp->state == USB_ACTIVE) || + (usbp->state == USB_SUSPENDED), + "invalid state"); + + usb_lld_stop(usbp); + usbp->config = NULL; + usbp->state = USB_STOP; + + /* Resetting all ongoing synchronous operations.*/ + for (i = 0; i <= (unsigned)USB_MAX_ENDPOINTS; i++) { +#if USB_USE_WAIT == TRUE + if (usbp->epc[i] != NULL) { + if (usbp->epc[i]->in_state != NULL) { + osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_RESET); + } + if (usbp->epc[i]->out_state != NULL) { + osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_RESET); + } + } +#endif + usbp->epc[i] = NULL; + } + osalOsRescheduleS(); + + osalSysUnlock(); +} + +/** + * @brief Enables an endpoint. + * @details This function enables an endpoint, both IN and/or OUT directions + * depending on the configuration structure. + * @note This function must be invoked in response of a SET_CONFIGURATION + * or SET_INTERFACE message. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * @param[in] epcp the endpoint configuration + * + * @iclass + */ +void usbInitEndpointI(USBDriver *usbp, usbep_t ep, + const USBEndpointConfig *epcp) { + + osalDbgCheckClassI(); + osalDbgCheck((usbp != NULL) && (epcp != NULL)); + osalDbgAssert(usbp->state == USB_ACTIVE, + "invalid state"); + osalDbgAssert(usbp->epc[ep] == NULL, "already initialized"); + + /* Logically enabling the endpoint in the USBDriver structure.*/ + usbp->epc[ep] = epcp; + + /* Clearing the state structures, custom fields as well.*/ + if (epcp->in_state != NULL) { + memset(epcp->in_state, 0, sizeof(USBInEndpointState)); + } + if (epcp->out_state != NULL) { + memset(epcp->out_state, 0, sizeof(USBOutEndpointState)); + } + + /* Low level endpoint activation.*/ + usb_lld_init_endpoint(usbp, ep); +} + +/** + * @brief Disables all the active endpoints. + * @details This function disables all the active endpoints except the + * endpoint zero. + * @note This function must be invoked in response of a SET_CONFIGURATION + * message with configuration number zero. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @iclass + */ +void usbDisableEndpointsI(USBDriver *usbp) { + unsigned i; + + osalDbgCheckClassI(); + osalDbgCheck(usbp != NULL); + osalDbgAssert(usbp->state == USB_ACTIVE, "invalid state"); + + usbp->transmitting &= 1U; + usbp->receiving &= 1U; + + for (i = 1; i <= (unsigned)USB_MAX_ENDPOINTS; i++) { +#if USB_USE_WAIT == TRUE + /* Signaling the event to threads waiting on endpoints.*/ + if (usbp->epc[i] != NULL) { + if (usbp->epc[i]->in_state != NULL) { + osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_RESET); + } + if (usbp->epc[i]->out_state != NULL) { + osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_RESET); + } + } +#endif + usbp->epc[i] = NULL; + } + + /* Low level endpoints deactivation.*/ + usb_lld_disable_endpoints(usbp); +} + +/** + * @brief Starts a receive transaction on an OUT endpoint. + * @note This function is meant to be called from ISR context outside + * critical zones because there is a potentially slow operation + * inside. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * @param[out] buf buffer where to copy the received data + * @param[in] n transaction size. It is recommended a multiple of + * the packet size because the excess is discarded. + * + * @iclass + */ +void usbStartReceiveI(USBDriver *usbp, usbep_t ep, + uint8_t *buf, size_t n) { + USBOutEndpointState *osp; + + osalDbgCheckClassI(); + osalDbgCheck((usbp != NULL) && (ep <= (usbep_t)USB_MAX_ENDPOINTS)); + osalDbgAssert(!usbGetReceiveStatusI(usbp, ep), "already receiving"); + + /* Marking the endpoint as active.*/ + usbp->receiving |= (uint16_t)((unsigned)1U << (unsigned)ep); + + /* Setting up the transfer.*/ + /*lint -save -e661 [18.1] pclint is confused by the check on ep.*/ + osp = usbp->epc[ep]->out_state; + /*lint -restore*/ + osp->rxbuf = buf; + osp->rxsize = n; + osp->rxcnt = 0; +#if USB_USE_WAIT == TRUE + osp->thread = NULL; +#endif + + /* Starting transfer.*/ + usb_lld_start_out(usbp, ep); +} + +/** + * @brief Starts a transmit transaction on an IN endpoint. + * @note This function is meant to be called from ISR context outside + * critical zones because there is a potentially slow operation + * inside. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * @param[in] buf buffer where to fetch the data to be transmitted + * @param[in] n transaction size + * + * @iclass + */ +void usbStartTransmitI(USBDriver *usbp, usbep_t ep, + const uint8_t *buf, size_t n) { + USBInEndpointState *isp; + + osalDbgCheckClassI(); + osalDbgCheck((usbp != NULL) && (ep <= (usbep_t)USB_MAX_ENDPOINTS)); + osalDbgAssert(!usbGetTransmitStatusI(usbp, ep), "already transmitting"); + + /* Marking the endpoint as active.*/ + usbp->transmitting |= (uint16_t)((unsigned)1U << (unsigned)ep); + + /* Setting up the transfer.*/ + /*lint -save -e661 [18.1] pclint is confused by the check on ep.*/ + isp = usbp->epc[ep]->in_state; + /*lint -restore*/ + isp->txbuf = buf; + isp->txsize = n; + isp->txcnt = 0; +#if USB_USE_WAIT == TRUE + isp->thread = NULL; +#endif + + /* Starting transfer.*/ + usb_lld_start_in(usbp, ep); +} + +#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__) +/** + * @brief Performs a receive transaction on an OUT endpoint. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * @param[out] buf buffer where to copy the received data + * @param[in] n transaction size. It is recommended a multiple of + * the packet size because the excess is discarded. + * + * @return The received effective data size, it can be less than + * the amount specified. + * @retval MSG_RESET driver not in @p USB_ACTIVE state or the operation + * has been aborted by an USB reset or a transition to + * the @p USB_SUSPENDED state. + * + * @api + */ +msg_t usbReceive(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) { + msg_t msg; + + osalSysLock(); + + if (usbGetDriverStateI(usbp) != USB_ACTIVE) { + osalSysUnlock(); + return MSG_RESET; + } + + usbStartReceiveI(usbp, ep, buf, n); + msg = osalThreadSuspendS(&usbp->epc[ep]->out_state->thread); + osalSysUnlock(); + + return msg; +} + +/** + * @brief Performs a transmit transaction on an IN endpoint. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * @param[in] buf buffer where to fetch the data to be transmitted + * @param[in] n transaction size + * + * @return The operation status. + * @retval MSG_OK operation performed successfully. + * @retval MSG_RESET driver not in @p USB_ACTIVE state or the operation + * has been aborted by an USB reset or a transition to + * the @p USB_SUSPENDED state. + * + * @api + */ +msg_t usbTransmit(USBDriver *usbp, usbep_t ep, const uint8_t *buf, size_t n) { + msg_t msg; + + osalSysLock(); + + if (usbGetDriverStateI(usbp) != USB_ACTIVE) { + osalSysUnlock(); + return MSG_RESET; + } + + usbStartTransmitI(usbp, ep, buf, n); + msg = osalThreadSuspendS(&usbp->epc[ep]->in_state->thread); + osalSysUnlock(); + + return msg; +} +#endif /* USB_USE_WAIT == TRUE */ + +/** + * @brief Stalls an OUT endpoint. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @return The operation status. + * @retval false Endpoint stalled. + * @retval true Endpoint busy, not stalled. + * + * @iclass + */ +bool usbStallReceiveI(USBDriver *usbp, usbep_t ep) { + + osalDbgCheckClassI(); + osalDbgCheck(usbp != NULL); + + if (usbGetReceiveStatusI(usbp, ep)) { + return true; + } + + usb_lld_stall_out(usbp, ep); + return false; +} + +/** + * @brief Stalls an IN endpoint. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @return The operation status. + * @retval false Endpoint stalled. + * @retval true Endpoint busy, not stalled. + * + * @iclass + */ +bool usbStallTransmitI(USBDriver *usbp, usbep_t ep) { + + osalDbgCheckClassI(); + osalDbgCheck(usbp != NULL); + + if (usbGetTransmitStatusI(usbp, ep)) { + return true; + } + + usb_lld_stall_in(usbp, ep); + return false; +} + +/** + * @brief Host wake-up procedure. + * @note It is silently ignored if the USB device is not in the + * @p USB_SUSPENDED state. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @api + */ +void usbWakeupHost(USBDriver *usbp) { + + if (usbp->state == USB_SUSPENDED) { + /* Starting host wakeup procedure.*/ + usb_lld_wakeup_host(usbp); + } +} + +/** + * @brief USB reset routine. + * @details This function must be invoked when an USB bus reset condition is + * detected. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void _usb_reset(USBDriver *usbp) { + unsigned i; + + /* State transition.*/ + usbp->state = USB_READY; + + /* Resetting internal state.*/ + usbp->status = 0; + usbp->address = 0; + usbp->configuration = 0; + usbp->transmitting = 0; + usbp->receiving = 0; + + /* Invalidates all endpoints into the USBDriver structure.*/ + for (i = 0; i <= (unsigned)USB_MAX_ENDPOINTS; i++) { +#if USB_USE_WAIT == TRUE + /* Signaling the event to threads waiting on endpoints.*/ + if (usbp->epc[i] != NULL) { + osalSysLockFromISR(); + if (usbp->epc[i]->in_state != NULL) { + osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_RESET); + } + if (usbp->epc[i]->out_state != NULL) { + osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_RESET); + } + osalSysUnlockFromISR(); + } +#endif + usbp->epc[i] = NULL; + } + + /* EP0 state machine initialization.*/ + usbp->ep0state = USB_EP0_STP_WAITING; + + /* Low level reset.*/ + usb_lld_reset(usbp); + + /* Notification of reset event.*/ + _usb_isr_invoke_event_cb(usbp, USB_EVENT_RESET); +} + +/** + * @brief USB suspend routine. + * @details This function must be invoked when an USB bus suspend condition is + * detected. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void _usb_suspend(USBDriver *usbp) { + + /* It could happen that multiple suspend events are triggered.*/ + if (usbp->state != USB_SUSPENDED) { + + /* State transition, saving the current state.*/ + usbp->saved_state = usbp->state; + usbp->state = USB_SUSPENDED; + + /* Notification of suspend event.*/ + _usb_isr_invoke_event_cb(usbp, USB_EVENT_SUSPEND); + + /* Terminating all pending transactions.*/ + usbp->transmitting = 0; + usbp->receiving = 0; + + /* Signaling the event to threads waiting on endpoints.*/ + #if USB_USE_WAIT == TRUE + { + unsigned i; + + for (i = 0; i <= (unsigned)USB_MAX_ENDPOINTS; i++) { + if (usbp->epc[i] != NULL) { + osalSysLockFromISR(); + if (usbp->epc[i]->in_state != NULL) { + osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_RESET); + } + if (usbp->epc[i]->out_state != NULL) { + osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_RESET); + } + osalSysUnlockFromISR(); + } + } + } + #endif + } +} + +/** + * @brief USB wake-up routine. + * @details This function must be invoked when an USB bus wake-up condition is + * detected. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void _usb_wakeup(USBDriver *usbp) { + + /* It could happen that multiple waakeup events are triggered.*/ + if (usbp->state == USB_SUSPENDED) { + + /* State transition, returning to the previous state.*/ + usbp->state = usbp->saved_state; + + /* Notification of suspend event.*/ + _usb_isr_invoke_event_cb(usbp, USB_EVENT_WAKEUP); + } +} + +/** + * @brief Default EP0 SETUP callback. + * @details This function is used by the low level driver as default handler + * for EP0 SETUP events. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number, always zero + * + * @notapi + */ +void _usb_ep0setup(USBDriver *usbp, usbep_t ep) { + size_t max; + + /* Is the EP0 state machine in the correct state for handling setup + packets?*/ + if (usbp->ep0state != USB_EP0_STP_WAITING) { + /* This is unexpected could require handling with a warning event.*/ + /* CHTODO: handling here.*/ + + /* Resetting the EP0 state machine and going ahead.*/ + usbp->ep0state = USB_EP0_STP_WAITING; + } + + /* Reading the setup data into the driver buffer.*/ + usbReadSetup(usbp, ep, usbp->setup); + + /* First verify if the application has an handler installed for this + request.*/ + /*lint -save -e9007 [13.5] No side effects, it is intentional.*/ + if ((usbp->config->requests_hook_cb == NULL) || + !(usbp->config->requests_hook_cb(usbp))) { + /*lint -restore*/ + /* Invoking the default handler, if this fails then stalls the + endpoint zero as error.*/ + /*lint -save -e9007 [13.5] No side effects, it is intentional.*/ + if (((usbp->setup[0] & USB_RTYPE_TYPE_MASK) != USB_RTYPE_TYPE_STD) || + !default_handler(usbp)) { + /*lint -restore*/ + /* Error response, the state machine goes into an error state, the low + level layer will have to reset it to USB_EP0_WAITING_SETUP after + receiving a SETUP packet.*/ + usb_lld_stall_in(usbp, 0); + usb_lld_stall_out(usbp, 0); + _usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED); + usbp->ep0state = USB_EP0_ERROR; + return; + } + } +#if (USB_SET_ADDRESS_ACK_HANDLING == USB_SET_ADDRESS_ACK_HW) + if (usbp->setup[1] == USB_REQ_SET_ADDRESS) { + /* Zero-length packet sent by hardware */ + return; + } +#endif + /* Transfer preparation. The request handler must have populated + correctly the fields ep0next, ep0n and ep0endcb using the macro + usbSetupTransfer().*/ + max = (size_t)get_hword(&usbp->setup[6]); + /* The transfer size cannot exceed the specified amount.*/ + if (usbp->ep0n > max) { + usbp->ep0n = max; + } + if ((usbp->setup[0] & USB_RTYPE_DIR_MASK) == USB_RTYPE_DIR_DEV2HOST) { + /* IN phase.*/ + if (usbp->ep0n != 0U) { + /* Starts the transmit phase.*/ + usbp->ep0state = USB_EP0_IN_TX; + osalSysLockFromISR(); + usbStartTransmitI(usbp, 0, usbp->ep0next, usbp->ep0n); + osalSysUnlockFromISR(); + } + else { + /* No transmission phase, directly receiving the zero sized status + packet.*/ + usbp->ep0state = USB_EP0_OUT_WAITING_STS; +#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) + osalSysLockFromISR(); + usbStartReceiveI(usbp, 0, NULL, 0); + osalSysUnlockFromISR(); +#else + usb_lld_end_setup(usbp, ep); +#endif + } + } + else { + /* OUT phase.*/ + if (usbp->ep0n != 0U) { + /* Starts the receive phase.*/ + usbp->ep0state = USB_EP0_OUT_RX; + osalSysLockFromISR(); + usbStartReceiveI(usbp, 0, (uint8_t *)usbp->ep0next, usbp->ep0n); + osalSysUnlockFromISR(); + } + else { + /* No receive phase, directly sending the zero sized status + packet.*/ + usbp->ep0state = USB_EP0_IN_SENDING_STS; +#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) + osalSysLockFromISR(); + usbStartTransmitI(usbp, 0, NULL, 0); + osalSysUnlockFromISR(); +#else + usb_lld_end_setup(usbp, ep); +#endif + } + } +} + +/** + * @brief Default EP0 IN callback. + * @details This function is used by the low level driver as default handler + * for EP0 IN events. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number, always zero + * + * @notapi + */ +void _usb_ep0in(USBDriver *usbp, usbep_t ep) { + size_t max; + + (void)ep; + switch (usbp->ep0state) { + case USB_EP0_IN_TX: + max = (size_t)get_hword(&usbp->setup[6]); + /* If the transmitted size is less than the requested size and it is a + multiple of the maximum packet size then a zero size packet must be + transmitted.*/ + if ((usbp->ep0n < max) && + ((usbp->ep0n % usbp->epc[0]->in_maxsize) == 0U)) { + osalSysLockFromISR(); + usbStartTransmitI(usbp, 0, NULL, 0); + osalSysUnlockFromISR(); + usbp->ep0state = USB_EP0_IN_WAITING_TX0; + return; + } + /* Falls through.*/ + case USB_EP0_IN_WAITING_TX0: + /* Transmit phase over, receiving the zero sized status packet.*/ + usbp->ep0state = USB_EP0_OUT_WAITING_STS; +#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) + osalSysLockFromISR(); + usbStartReceiveI(usbp, 0, NULL, 0); + osalSysUnlockFromISR(); +#else + usb_lld_end_setup(usbp, ep); +#endif + return; + case USB_EP0_IN_SENDING_STS: + /* Status packet sent, invoking the callback if defined.*/ + if (usbp->ep0endcb != NULL) { + usbp->ep0endcb(usbp); + } + usbp->ep0state = USB_EP0_STP_WAITING; + return; + case USB_EP0_STP_WAITING: + case USB_EP0_OUT_WAITING_STS: + case USB_EP0_OUT_RX: + /* All the above are invalid states in the IN phase.*/ + osalDbgAssert(false, "EP0 state machine error"); + /* Falls through.*/ + case USB_EP0_ERROR: + /* Error response, the state machine goes into an error state, the low + level layer will have to reset it to USB_EP0_WAITING_SETUP after + receiving a SETUP packet.*/ + usb_lld_stall_in(usbp, 0); + usb_lld_stall_out(usbp, 0); + _usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED); + usbp->ep0state = USB_EP0_ERROR; + return; + default: + osalDbgAssert(false, "EP0 state machine invalid state"); + } +} + +/** + * @brief Default EP0 OUT callback. + * @details This function is used by the low level driver as default handler + * for EP0 OUT events. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number, always zero + * + * @notapi + */ +void _usb_ep0out(USBDriver *usbp, usbep_t ep) { + + (void)ep; + switch (usbp->ep0state) { + case USB_EP0_OUT_RX: + /* Receive phase over, sending the zero sized status packet.*/ + usbp->ep0state = USB_EP0_IN_SENDING_STS; +#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) + osalSysLockFromISR(); + usbStartTransmitI(usbp, 0, NULL, 0); + osalSysUnlockFromISR(); +#else + usb_lld_end_setup(usbp, ep); +#endif + return; + case USB_EP0_OUT_WAITING_STS: + /* Status packet received, it must be zero sized, invoking the callback + if defined.*/ +#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) + if (usbGetReceiveTransactionSizeX(usbp, 0) != 0U) { + break; + } +#endif + if (usbp->ep0endcb != NULL) { + usbp->ep0endcb(usbp); + } + usbp->ep0state = USB_EP0_STP_WAITING; + return; + case USB_EP0_STP_WAITING: + case USB_EP0_IN_TX: + case USB_EP0_IN_WAITING_TX0: + case USB_EP0_IN_SENDING_STS: + /* All the above are invalid states in the IN phase.*/ + osalDbgAssert(false, "EP0 state machine error"); + /* Falls through.*/ + case USB_EP0_ERROR: + /* Error response, the state machine goes into an error state, the low + level layer will have to reset it to USB_EP0_WAITING_SETUP after + receiving a SETUP packet.*/ + usb_lld_stall_in(usbp, 0); + usb_lld_stall_out(usbp, 0); + _usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED); + usbp->ep0state = USB_EP0_ERROR; + return; + default: + osalDbgAssert(false, "EP0 state machine invalid state"); + } +} + +#endif /* HAL_USE_USB == TRUE */ + +/** @} */ From 2561fd623d018cb7ee1cd63bf00d0897412777bc Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 4 Mar 2023 11:49:39 +0000 Subject: [PATCH 20/53] Fixed bug #1256. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16130 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/STM32G4xx/hal_lld.c | 2 +- readme.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/os/hal/ports/STM32/STM32G4xx/hal_lld.c b/os/hal/ports/STM32/STM32G4xx/hal_lld.c index 25ad7a1975..a9c07760d5 100644 --- a/os/hal/ports/STM32/STM32G4xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32G4xx/hal_lld.c @@ -141,7 +141,7 @@ void stm32_clock_init(void) { rccResetAPB2(~0); /* PWR clock enable.*/ -#if (HAL_USE_RTC == TRUE) && defined(RCC_APBENR1_RTCAPBEN) +#if (HAL_USE_RTC == TRUE) && defined(RCC_APB1ENR1_RTCAPBEN) rccEnableAPB1R1(RCC_APB1ENR1_PWREN | RCC_APB1ENR1_RTCAPBEN, false) #else rccEnableAPB1R1(RCC_APB1ENR1_PWREN, false) diff --git a/readme.txt b/readme.txt index e3266bf86e..d975e5d965 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed incorrect RTC initialization on STM32G4 (bug #1256). - FIX: Fixed invalid checks on PLLP/R/Q dividers on STM32H7 (bug #1253). - FIX: Fixed remote wakeup failure in STM32 OTGv1 driver (bug #1252). - FIX: Fixed wrong use of hooks in RT/NIL (bug #1251). From e7e78a5f497f029b36fa85a78fb116c9133846f6 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 2 Apr 2023 09:46:03 +0000 Subject: [PATCH 21/53] Fixed bug #1258. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16198 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/STM32H7xx/hal_lld.c | 868 +++++++++++++------------ readme.txt | 1 + 2 files changed, 437 insertions(+), 432 deletions(-) diff --git a/os/hal/ports/STM32/STM32H7xx/hal_lld.c b/os/hal/ports/STM32/STM32H7xx/hal_lld.c index c5c2060e8c..20f4c1357d 100644 --- a/os/hal/ports/STM32/STM32H7xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32H7xx/hal_lld.c @@ -1,432 +1,436 @@ -/* - ChibiOS - Copyright (C) 2006..2018 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 STM32H7xx/hal_lld.c - * @brief STM32H7xx HAL subsystem low level driver source. - * - * @addtogroup HAL - * @{ - */ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief CMSIS system core clock variable. - * @note It is declared in system_stm32f7xx.h. - */ -uint32_t SystemCoreClock = STM32_CORE_CK; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Initializes the backup domain. - * @note WARNING! Changing clock source impossible without resetting - * of the whole BKP domain. - */ -static inline void init_bkp_domain(void) { - - /* Backup domain access enabled and left open.*/ - PWR->CR1 |= PWR_CR1_DBP; - - /* Reset BKP domain if different clock source selected.*/ - if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { - /* Backup domain reset.*/ - RCC->BDCR = RCC_BDCR_BDRST; - RCC->BDCR = 0; - } - -#if STM32_LSE_ENABLED -#if defined(STM32_LSE_BYPASS) - /* LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; -#else - /* No LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; -#endif - while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; /* Waits until LSE is stable. */ -#endif - -#if HAL_USE_RTC - /* If the backup domain hasn't been initialized yet then proceed with - initialization.*/ - if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { - /* Selects clock source.*/ - RCC->BDCR |= STM32_RTCSEL; - - /* RTC clock enabled.*/ - RCC->BDCR |= RCC_BDCR_RTCEN; - } -#endif /* HAL_USE_RTC */ -} - -/** - * @brief Initializes the PWR unit. - */ -static inline void init_pwr(void) { -#if 0 - PWR_TypeDef *pwr = PWR; /* For inspection.*/ - (void)pwr; -#endif - - /* Lower C3 byte, it must be programmed at very first, then waiting for - power supply to stabilize.*/ - PWR->CR3 = STM32_PWR_CR3 & 0x000000FFU; - while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0) - ; /* CHTODO timeout handling.*/ - - PWR->CR1 = STM32_PWR_CR1 | 0xF0000000U; - PWR->CR2 = STM32_PWR_CR2; - PWR->CR3 = STM32_PWR_CR3; /* Other bits, lower byte is not changed. */ - PWR->CPUCR = STM32_PWR_CPUCR; - PWR->D3CR = STM32_VOS; -#if !defined(STM32_ENFORCE_H7_REV_XY) - SYSCFG->PWRCR = STM32_ODEN; -#endif - while ((PWR->D3CR & PWR_D3CR_VOSRDY) == 0) - ; /* CHTODO timeout handling.*/ -#if STM32_PWR_CR2 & PWR_CR2_BREN -// while ((PWR->CR2 & PWR_CR2_BRRDY) == 0) -// ; -// rccEnableBKPRAM(true); -#endif -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level HAL driver initialization. - * - * @notapi - */ -void hal_lld_init(void) { - -#if STM32_NO_INIT == FALSE - /* Reset of all peripherals. AHB3 is not reset entirely because FMC could - have been initialized in the board initialization file (board.c). - Note, GPIOs are not reset because initialized before this point in - board files.*/ - rccResetAHB1(~0); - rccResetAHB2(~0); - rccResetAHB3(~(RCC_AHB3RSTR_FMCRST | - 0x80000000U)); /* Was RCC_AHB3RSTR_CPURST in Rev-V.*/ - rccResetAHB4(~(RCC_APB4RSTR_SYSCFGRST | STM32_GPIO_EN_MASK)); - rccResetAPB1L(~0); - rccResetAPB1H(~0); - rccResetAPB2(~0); - rccResetAPB3(~0); - rccResetAPB4(~0); -#endif /* STM32_NO_INIT == FALSE */ - - /* DMA subsystems initialization.*/ -#if defined(STM32_BDMA_REQUIRED) - bdmaInit(); -#endif -#if defined(STM32_DMA_REQUIRED) - dmaInit(); -#endif -#if defined(STM32_MDMA_REQUIRED) - mdmaInit(); -#endif - - /* IRQ subsystem initialization.*/ - irqInit(); - - /* MPU initialization.*/ -#if (STM32_NOCACHE_SRAM1_SRAM2 == TRUE) || (STM32_NOCACHE_SRAM3 == TRUE) - { - uint32_t base, size; - -#if (STM32_NOCACHE_SRAM1_SRAM2 == TRUE) && (STM32_NOCACHE_SRAM3 == TRUE) - base = 0x30000000U; - size = MPU_RASR_SIZE_512K; -#elif (STM32_NOCACHE_SRAM1_SRAM2 == TRUE) && (STM32_NOCACHE_SRAM3 == FALSE) - base = 0x30000000U; - size = MPU_RASR_SIZE_256K; -#elif (STM32_NOCACHE_SRAM1_SRAM2 == FALSE) && (STM32_NOCACHE_SRAM3 == TRUE) - base = 0x30040000U; - size = MPU_RASR_SIZE_16K; -#else -#error "invalid constants used in mcuconf.h" -#endif - - /* The SRAM2 bank can optionally made a non cache-able area for use by - DMA engines.*/ - mpuConfigureRegion(STM32_NOCACHE_MPU_REGION, - base, - MPU_RASR_ATTR_AP_RW_RW | - MPU_RASR_ATTR_NON_CACHEABLE | - MPU_RASR_ATTR_S | - size | - MPU_RASR_ENABLE); - mpuEnable(MPU_CTRL_PRIVDEFENA); - - /* Invalidating data cache to make sure that the MPU settings are taken - immediately.*/ - SCB_CleanInvalidateDCache(); - } -#endif -} - -/** - * @brief STM32H7xx clocks and PLL initialization. - * @note All the involved constants come from the file @p board.h. - * @note This function should be invoked just after the system reset. - * - * @special - */ -void stm32_clock_init(void) { -#if STM32_NO_INIT == FALSE - uint32_t cfgr; - -#if 0 - RCC_TypeDef *rcc = RCC; /* For inspection.*/ - (void)rcc; -#endif - -#if defined(STM32_ENFORCE_H7_REV_XY) - /* Fix for errata 2.2.15: Reading from AXI SRAM might lead to data - read corruption. - AXI->TARG7_FN_MOD.*/ - *((volatile uint32_t *)(0x51000000 + 0x1108 + 0x7000)) = 0x00000001U; -#endif - - /* SYSCFG clock enabled here because it is a multi-functional unit shared - among multiple drivers.*/ - rccEnableAPB4(RCC_APB4ENR_SYSCFGEN, true); - - /* PWR initialization.*/ - init_pwr(); - - /* Backup domain initialization.*/ - init_bkp_domain(); - - /* HSI setup, it enforces the reset situation in order to handle possible - problems with JTAG probes and re-initializations.*/ - RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ - while (!(RCC->CR & RCC_CR_HSIRDY)) - ; /* Wait until HSI is stable. */ - - /* HSI is selected as new source without touching the other fields in - CFGR. This is only required when using a debugger than can cause - restarts.*/ - RCC->CFGR = 0x00000000U; /* Reset SW to HSI. */ - while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) - ; /* Wait until HSI is selected. */ - - /* Registers cleared to reset values.*/ - RCC->CR = RCC_CR_HSION; /* CR Reset value. */ - RCC->HSICFGR = 0x40000000U; /* HSICFGR Reset value. */ -#if !defined(STM32_ENFORCE_H7_REV_XY) - RCC->CSICFGR = 0x20000000U; /* CSICFGR Reset value. */ -#endif - RCC->CSR = 0x00000000U; /* CSR reset value. */ - RCC->PLLCFGR = 0x01FF0000U; /* PLLCFGR reset value. */ - - /* Other clock-related settings, done before other things because - recommended in the RM.*/ - cfgr = STM32_MCO2SEL | RCC_CFGR_MCO2PRE_VALUE(STM32_MCO2PRE_VALUE) | - STM32_MCO1SEL | RCC_CFGR_MCO1PRE_VALUE(STM32_MCO1PRE_VALUE) | - RCC_CFGR_RTCPRE_VALUE(STM32_RTCPRE_VALUE) | - STM32_HRTIMSEL | STM32_STOPKERWUCK | STM32_STOPWUCK; -#if STM32_TIMPRE_ENABLE == TRUE - cfgr |= RCC_CFGR_TIMPRE; -#endif - RCC->CFGR = cfgr; - - /* HSE activation with optional bypass.*/ -#if STM32_HSE_ENABLED == TRUE -#if defined(STM32_HSE_BYPASS) - RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; -#else - RCC->CR |= RCC_CR_HSEON; -#endif - while ((RCC->CR & RCC_CR_HSERDY) == 0) - ; /* Waits until HSE is stable. */ -#endif /* STM32_HSE_ENABLED == TRUE */ - - /* HSI48 activation.*/ -#if STM32_HSI48_ENABLED == TRUE - RCC->CR |= RCC_CR_HSI48ON; - while ((RCC->CR & RCC_CR_HSI48RDY) == 0) - ; /* Waits until HSI48 is stable. */ - -#endif /* STM32_HSI48_ENABLED == TRUE */ - - /* CSI activation.*/ -#if STM32_CSI_ENABLED == TRUE - RCC->CR |= RCC_CR_CSION; - while ((RCC->CR & RCC_CR_CSIRDY) == 0) - ; /* Waits until CSI is stable. */ -#endif /* STM32_CSI_ENABLED == TRUE */ - - /* LSI activation.*/ -#if STM32_LSI_ENABLED == TRUE - RCC->CSR |= RCC_CSR_LSION; - while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) - ; /* Waits until LSI is stable. */ -#endif /* STM32_LSI_ENABLED == TRUE */ - - /* PLLs activation, it happens in parallel in order to - reduce boot time.*/ -#if (STM32_PLL1_ENABLED == TRUE) || \ - (STM32_PLL2_ENABLED == TRUE) || \ - (STM32_PLL3_ENABLED == TRUE) - { - uint32_t onmask = 0; - uint32_t rdymask = 0; - uint32_t cfgmask = 0; - - RCC->PLLCKSELR = RCC_PLLCKSELR_DIVM3_VALUE(STM32_PLL3_DIVM_VALUE) | - RCC_PLLCKSELR_DIVM2_VALUE(STM32_PLL2_DIVM_VALUE) | - RCC_PLLCKSELR_DIVM1_VALUE(STM32_PLL1_DIVM_VALUE) | - RCC_PLLCKSELR_PLLSRC_VALUE(STM32_PLLSRC); - - cfgmask = STM32_PLLCFGR_PLL3RGE | STM32_PLLCFGR_PLL3VCOSEL | RCC_PLLCFGR_PLL3FRACEN | - STM32_PLLCFGR_PLL2RGE | STM32_PLLCFGR_PLL2VCOSEL | RCC_PLLCFGR_PLL2FRACEN | - STM32_PLLCFGR_PLL1RGE | STM32_PLLCFGR_PLL1VCOSEL | RCC_PLLCFGR_PLL1FRACEN; - -#if STM32_PLL1_ENABLED == TRUE - RCC->PLL1FRACR = STM32_PLL1_FRACN; - RCC->PLL1DIVR = STM32_PLL1_DIVR | STM32_PLL1_DIVQ | - STM32_PLL1_DIVP | STM32_PLL1_DIVN; - onmask |= RCC_CR_PLL1ON; - rdymask |= RCC_CR_PLL1RDY; -#if STM32_PLL1_P_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVP1EN; -#endif -#if STM32_PLL1_Q_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVQ1EN; -#endif -#if STM32_PLL1_R_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVR1EN; -#endif -#endif /* STM32_PLL1_ENABLED == TRUE */ - -#if STM32_PLL2_ENABLED == TRUE - RCC->PLL2FRACR = STM32_PLL2_FRACN; - RCC->PLL2DIVR = STM32_PLL2_DIVR | STM32_PLL2_DIVQ | - STM32_PLL2_DIVP | STM32_PLL2_DIVN; - onmask |= RCC_CR_PLL2ON; - rdymask |= RCC_CR_PLL2RDY; -#if STM32_PLL2_P_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVP2EN; -#endif -#if STM32_PLL2_Q_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVQ2EN; -#endif -#if STM32_PLL2_R_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVR2EN; -#endif -#endif /* STM32_PLL2_ENABLED == TRUE */ - -#if STM32_PLL3_ENABLED == TRUE - RCC->PLL3FRACR = STM32_PLL3_FRACN; - RCC->PLL3DIVR = STM32_PLL3_DIVR | STM32_PLL3_DIVQ | - STM32_PLL3_DIVP | STM32_PLL3_DIVN; - onmask |= RCC_CR_PLL3ON; - rdymask |= RCC_CR_PLL3RDY; -#if STM32_PLL3_P_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVP3EN; -#endif -#if STM32_PLL3_Q_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVQ3EN; -#endif -#if STM32_PLL3_R_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVR3EN; -#endif -#endif /* STM32_PLL3_ENABLED == TRUE */ - - /* Activating enabled PLLs and waiting for all of them to become ready.*/ - RCC->PLLCFGR = cfgmask & STM32_PLLCFGR_MASK; - RCC->CR |= onmask; - while ((RCC->CR & rdymask) != rdymask) - ; - } -#endif /* STM32_PLL1_ENABLED || STM32_PLL2_ENABLED || STM32_PLL3_ENABLED */ - - /* AHB and APB dividers.*/ - RCC->D1CFGR = STM32_D1CPRE | STM32_D1PPRE3 | STM32_D1HPRE; - RCC->D2CFGR = STM32_D2PPRE2 | STM32_D2PPRE1; - RCC->D3CFGR = STM32_D3PPRE4; - - /* Peripherals clocks.*/ - RCC->D1CCIPR = STM32_CKPERSEL | STM32_SDMMCSEL | STM32_QSPISEL | - STM32_FMCSEL; - RCC->D2CCIP1R = STM32_SWPSEL | STM32_FDCANSEL | STM32_DFSDM1SEL | - STM32_SPDIFSEL | STM32_SPDIFSEL | STM32_SPI45SEL | - STM32_SPI123SEL | STM32_SAI23SEL | STM32_SAI1SEL; - RCC->D2CCIP2R = STM32_LPTIM1SEL | STM32_CECSEL | STM32_USBSEL | - STM32_I2C123SEL | STM32_RNGSEL | STM32_USART16SEL | - STM32_USART234578SEL; - RCC->D3CCIPR = STM32_SPI6SEL | STM32_SAI4BSEL | STM32_SAI4ASEL | - STM32_ADCSEL | STM32_LPTIM345SEL | STM32_LPTIM2SEL | - STM32_I2C4SEL | STM32_LPUART1SEL; - - /* Flash setup.*/ - FLASH->ACR = FLASH_ACR_WRHIGHFREQ_1 | FLASH_ACR_WRHIGHFREQ_0 | - STM32_FLASHBITS; - while ((FLASH->ACR & FLASH_ACR_LATENCY) != - (STM32_FLASHBITS & FLASH_ACR_LATENCY)) { - } - - /* Switching to the configured clock source if it is different - from HSI.*/ -#if STM32_SW != STM32_SW_HSI_CK - RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ - while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 3U)) - ; -#endif - -#if 0 - /* Peripheral clock sources.*/ - RCC->DCKCFGR2 = STM32_SDMMCSEL | STM32_CK48MSEL | STM32_CECSEL | - STM32_LPTIM1SEL | STM32_I2C4SEL | STM32_I2C3SEL | - STM32_I2C2SEL | STM32_I2C1SEL | STM32_UART8SEL | - STM32_UART7SEL | STM32_USART6SEL | STM32_UART5SEL | - STM32_UART4SEL | STM32_USART3SEL | STM32_USART2SEL | - STM32_USART1SEL; -#endif - - /* RAM1 2 and 3 clocks enabled.*/ - rccEnableSRAM1(true); - rccEnableSRAM2(true); - rccEnableSRAM3(true); -#endif /* STM32_NO_INIT */ -} - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 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 STM32H7xx/hal_lld.c + * @brief STM32H7xx HAL subsystem low level driver source. + * + * @addtogroup HAL + * @{ + */ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define RCC_AHB1RSTR_DONOTTOUCH_Pos (31U) +#define RCC_AHB1RSTR_DONOTTOUCH_Msk (0x1UL << RCC_AHB1RSTR_DONOTTOUCH_Pos) +#define RCC_AHB1RSTR_DONOTTOUCH RCC_AHB1RSTR_DONOTTOUCH_Msk + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief CMSIS system core clock variable. + * @note It is declared in system_stm32f7xx.h. + */ +uint32_t SystemCoreClock = STM32_CORE_CK; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the backup domain. + * @note WARNING! Changing clock source impossible without resetting + * of the whole BKP domain. + */ +static inline void init_bkp_domain(void) { + + /* Backup domain access enabled and left open.*/ + PWR->CR1 |= PWR_CR1_DBP; + + /* Reset BKP domain if different clock source selected.*/ + if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + } + +#if STM32_LSE_ENABLED +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; +#endif + while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; /* Waits until LSE is stable. */ +#endif + +#if HAL_USE_RTC + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { + /* Selects clock source.*/ + RCC->BDCR |= STM32_RTCSEL; + + /* RTC clock enabled.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* HAL_USE_RTC */ +} + +/** + * @brief Initializes the PWR unit. + */ +static inline void init_pwr(void) { +#if 0 + PWR_TypeDef *pwr = PWR; /* For inspection.*/ + (void)pwr; +#endif + + /* Lower C3 byte, it must be programmed at very first, then waiting for + power supply to stabilize.*/ + PWR->CR3 = STM32_PWR_CR3 & 0x000000FFU; + while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0) + ; /* CHTODO timeout handling.*/ + + PWR->CR1 = STM32_PWR_CR1 | 0xF0000000U; + PWR->CR2 = STM32_PWR_CR2; + PWR->CR3 = STM32_PWR_CR3; /* Other bits, lower byte is not changed. */ + PWR->CPUCR = STM32_PWR_CPUCR; + PWR->D3CR = STM32_VOS; +#if !defined(STM32_ENFORCE_H7_REV_XY) + SYSCFG->PWRCR = STM32_ODEN; +#endif + while ((PWR->D3CR & PWR_D3CR_VOSRDY) == 0) + ; /* CHTODO timeout handling.*/ +#if STM32_PWR_CR2 & PWR_CR2_BREN +// while ((PWR->CR2 & PWR_CR2_BRRDY) == 0) +// ; +// rccEnableBKPRAM(true); +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level HAL driver initialization. + * + * @notapi + */ +void hal_lld_init(void) { + +#if STM32_NO_INIT == FALSE + /* Reset of all peripherals. AHB3 is not reset entirely because FMC could + have been initialized in the board initialization file (board.c). + Note, GPIOs are not reset because initialized before this point in + board files.*/ + rccResetAHB1(~RCC_AHB1RSTR_DONOTTOUCH); + rccResetAHB2(~0); + rccResetAHB3(~(RCC_AHB3RSTR_FMCRST | + 0x80000000U)); /* Was RCC_AHB3RSTR_CPURST in Rev-V.*/ + rccResetAHB4(~(RCC_APB4RSTR_SYSCFGRST | STM32_GPIO_EN_MASK)); + rccResetAPB1L(~0); + rccResetAPB1H(~0); + rccResetAPB2(~0); + rccResetAPB3(~0); + rccResetAPB4(~0); +#endif /* STM32_NO_INIT == FALSE */ + + /* DMA subsystems initialization.*/ +#if defined(STM32_BDMA_REQUIRED) + bdmaInit(); +#endif +#if defined(STM32_DMA_REQUIRED) + dmaInit(); +#endif +#if defined(STM32_MDMA_REQUIRED) + mdmaInit(); +#endif + + /* IRQ subsystem initialization.*/ + irqInit(); + + /* MPU initialization.*/ +#if (STM32_NOCACHE_SRAM1_SRAM2 == TRUE) || (STM32_NOCACHE_SRAM3 == TRUE) + { + uint32_t base, size; + +#if (STM32_NOCACHE_SRAM1_SRAM2 == TRUE) && (STM32_NOCACHE_SRAM3 == TRUE) + base = 0x30000000U; + size = MPU_RASR_SIZE_512K; +#elif (STM32_NOCACHE_SRAM1_SRAM2 == TRUE) && (STM32_NOCACHE_SRAM3 == FALSE) + base = 0x30000000U; + size = MPU_RASR_SIZE_256K; +#elif (STM32_NOCACHE_SRAM1_SRAM2 == FALSE) && (STM32_NOCACHE_SRAM3 == TRUE) + base = 0x30040000U; + size = MPU_RASR_SIZE_16K; +#else +#error "invalid constants used in mcuconf.h" +#endif + + /* The SRAM2 bank can optionally made a non cache-able area for use by + DMA engines.*/ + mpuConfigureRegion(STM32_NOCACHE_MPU_REGION, + base, + MPU_RASR_ATTR_AP_RW_RW | + MPU_RASR_ATTR_NON_CACHEABLE | + MPU_RASR_ATTR_S | + size | + MPU_RASR_ENABLE); + mpuEnable(MPU_CTRL_PRIVDEFENA); + + /* Invalidating data cache to make sure that the MPU settings are taken + immediately.*/ + SCB_CleanInvalidateDCache(); + } +#endif +} + +/** + * @brief STM32H7xx clocks and PLL initialization. + * @note All the involved constants come from the file @p board.h. + * @note This function should be invoked just after the system reset. + * + * @special + */ +void stm32_clock_init(void) { +#if STM32_NO_INIT == FALSE + uint32_t cfgr; + +#if 0 + RCC_TypeDef *rcc = RCC; /* For inspection.*/ + (void)rcc; +#endif + +#if defined(STM32_ENFORCE_H7_REV_XY) + /* Fix for errata 2.2.15: Reading from AXI SRAM might lead to data + read corruption. + AXI->TARG7_FN_MOD.*/ + *((volatile uint32_t *)(0x51000000 + 0x1108 + 0x7000)) = 0x00000001U; +#endif + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + rccEnableAPB4(RCC_APB4ENR_SYSCFGEN, true); + + /* PWR initialization.*/ + init_pwr(); + + /* Backup domain initialization.*/ + init_bkp_domain(); + + /* HSI setup, it enforces the reset situation in order to handle possible + problems with JTAG probes and re-initializations.*/ + RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ + while (!(RCC->CR & RCC_CR_HSIRDY)) + ; /* Wait until HSI is stable. */ + + /* HSI is selected as new source without touching the other fields in + CFGR. This is only required when using a debugger than can cause + restarts.*/ + RCC->CFGR = 0x00000000U; /* Reset SW to HSI. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) + ; /* Wait until HSI is selected. */ + + /* Registers cleared to reset values.*/ + RCC->CR = RCC_CR_HSION; /* CR Reset value. */ + RCC->HSICFGR = 0x40000000U; /* HSICFGR Reset value. */ +#if !defined(STM32_ENFORCE_H7_REV_XY) + RCC->CSICFGR = 0x20000000U; /* CSICFGR Reset value. */ +#endif + RCC->CSR = 0x00000000U; /* CSR reset value. */ + RCC->PLLCFGR = 0x01FF0000U; /* PLLCFGR reset value. */ + + /* Other clock-related settings, done before other things because + recommended in the RM.*/ + cfgr = STM32_MCO2SEL | RCC_CFGR_MCO2PRE_VALUE(STM32_MCO2PRE_VALUE) | + STM32_MCO1SEL | RCC_CFGR_MCO1PRE_VALUE(STM32_MCO1PRE_VALUE) | + RCC_CFGR_RTCPRE_VALUE(STM32_RTCPRE_VALUE) | + STM32_HRTIMSEL | STM32_STOPKERWUCK | STM32_STOPWUCK; +#if STM32_TIMPRE_ENABLE == TRUE + cfgr |= RCC_CFGR_TIMPRE; +#endif + RCC->CFGR = cfgr; + + /* HSE activation with optional bypass.*/ +#if STM32_HSE_ENABLED == TRUE +#if defined(STM32_HSE_BYPASS) + RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; +#else + RCC->CR |= RCC_CR_HSEON; +#endif + while ((RCC->CR & RCC_CR_HSERDY) == 0) + ; /* Waits until HSE is stable. */ +#endif /* STM32_HSE_ENABLED == TRUE */ + + /* HSI48 activation.*/ +#if STM32_HSI48_ENABLED == TRUE + RCC->CR |= RCC_CR_HSI48ON; + while ((RCC->CR & RCC_CR_HSI48RDY) == 0) + ; /* Waits until HSI48 is stable. */ + +#endif /* STM32_HSI48_ENABLED == TRUE */ + + /* CSI activation.*/ +#if STM32_CSI_ENABLED == TRUE + RCC->CR |= RCC_CR_CSION; + while ((RCC->CR & RCC_CR_CSIRDY) == 0) + ; /* Waits until CSI is stable. */ +#endif /* STM32_CSI_ENABLED == TRUE */ + + /* LSI activation.*/ +#if STM32_LSI_ENABLED == TRUE + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Waits until LSI is stable. */ +#endif /* STM32_LSI_ENABLED == TRUE */ + + /* PLLs activation, it happens in parallel in order to + reduce boot time.*/ +#if (STM32_PLL1_ENABLED == TRUE) || \ + (STM32_PLL2_ENABLED == TRUE) || \ + (STM32_PLL3_ENABLED == TRUE) + { + uint32_t onmask = 0; + uint32_t rdymask = 0; + uint32_t cfgmask = 0; + + RCC->PLLCKSELR = RCC_PLLCKSELR_DIVM3_VALUE(STM32_PLL3_DIVM_VALUE) | + RCC_PLLCKSELR_DIVM2_VALUE(STM32_PLL2_DIVM_VALUE) | + RCC_PLLCKSELR_DIVM1_VALUE(STM32_PLL1_DIVM_VALUE) | + RCC_PLLCKSELR_PLLSRC_VALUE(STM32_PLLSRC); + + cfgmask = STM32_PLLCFGR_PLL3RGE | STM32_PLLCFGR_PLL3VCOSEL | RCC_PLLCFGR_PLL3FRACEN | + STM32_PLLCFGR_PLL2RGE | STM32_PLLCFGR_PLL2VCOSEL | RCC_PLLCFGR_PLL2FRACEN | + STM32_PLLCFGR_PLL1RGE | STM32_PLLCFGR_PLL1VCOSEL | RCC_PLLCFGR_PLL1FRACEN; + +#if STM32_PLL1_ENABLED == TRUE + RCC->PLL1FRACR = STM32_PLL1_FRACN; + RCC->PLL1DIVR = STM32_PLL1_DIVR | STM32_PLL1_DIVQ | + STM32_PLL1_DIVP | STM32_PLL1_DIVN; + onmask |= RCC_CR_PLL1ON; + rdymask |= RCC_CR_PLL1RDY; +#if STM32_PLL1_P_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVP1EN; +#endif +#if STM32_PLL1_Q_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVQ1EN; +#endif +#if STM32_PLL1_R_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVR1EN; +#endif +#endif /* STM32_PLL1_ENABLED == TRUE */ + +#if STM32_PLL2_ENABLED == TRUE + RCC->PLL2FRACR = STM32_PLL2_FRACN; + RCC->PLL2DIVR = STM32_PLL2_DIVR | STM32_PLL2_DIVQ | + STM32_PLL2_DIVP | STM32_PLL2_DIVN; + onmask |= RCC_CR_PLL2ON; + rdymask |= RCC_CR_PLL2RDY; +#if STM32_PLL2_P_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVP2EN; +#endif +#if STM32_PLL2_Q_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVQ2EN; +#endif +#if STM32_PLL2_R_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVR2EN; +#endif +#endif /* STM32_PLL2_ENABLED == TRUE */ + +#if STM32_PLL3_ENABLED == TRUE + RCC->PLL3FRACR = STM32_PLL3_FRACN; + RCC->PLL3DIVR = STM32_PLL3_DIVR | STM32_PLL3_DIVQ | + STM32_PLL3_DIVP | STM32_PLL3_DIVN; + onmask |= RCC_CR_PLL3ON; + rdymask |= RCC_CR_PLL3RDY; +#if STM32_PLL3_P_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVP3EN; +#endif +#if STM32_PLL3_Q_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVQ3EN; +#endif +#if STM32_PLL3_R_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVR3EN; +#endif +#endif /* STM32_PLL3_ENABLED == TRUE */ + + /* Activating enabled PLLs and waiting for all of them to become ready.*/ + RCC->PLLCFGR = cfgmask & STM32_PLLCFGR_MASK; + RCC->CR |= onmask; + while ((RCC->CR & rdymask) != rdymask) + ; + } +#endif /* STM32_PLL1_ENABLED || STM32_PLL2_ENABLED || STM32_PLL3_ENABLED */ + + /* AHB and APB dividers.*/ + RCC->D1CFGR = STM32_D1CPRE | STM32_D1PPRE3 | STM32_D1HPRE; + RCC->D2CFGR = STM32_D2PPRE2 | STM32_D2PPRE1; + RCC->D3CFGR = STM32_D3PPRE4; + + /* Peripherals clocks.*/ + RCC->D1CCIPR = STM32_CKPERSEL | STM32_SDMMCSEL | STM32_QSPISEL | + STM32_FMCSEL; + RCC->D2CCIP1R = STM32_SWPSEL | STM32_FDCANSEL | STM32_DFSDM1SEL | + STM32_SPDIFSEL | STM32_SPDIFSEL | STM32_SPI45SEL | + STM32_SPI123SEL | STM32_SAI23SEL | STM32_SAI1SEL; + RCC->D2CCIP2R = STM32_LPTIM1SEL | STM32_CECSEL | STM32_USBSEL | + STM32_I2C123SEL | STM32_RNGSEL | STM32_USART16SEL | + STM32_USART234578SEL; + RCC->D3CCIPR = STM32_SPI6SEL | STM32_SAI4BSEL | STM32_SAI4ASEL | + STM32_ADCSEL | STM32_LPTIM345SEL | STM32_LPTIM2SEL | + STM32_I2C4SEL | STM32_LPUART1SEL; + + /* Flash setup.*/ + FLASH->ACR = FLASH_ACR_WRHIGHFREQ_1 | FLASH_ACR_WRHIGHFREQ_0 | + STM32_FLASHBITS; + while ((FLASH->ACR & FLASH_ACR_LATENCY) != + (STM32_FLASHBITS & FLASH_ACR_LATENCY)) { + } + + /* Switching to the configured clock source if it is different + from HSI.*/ +#if STM32_SW != STM32_SW_HSI_CK + RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 3U)) + ; +#endif + +#if 0 + /* Peripheral clock sources.*/ + RCC->DCKCFGR2 = STM32_SDMMCSEL | STM32_CK48MSEL | STM32_CECSEL | + STM32_LPTIM1SEL | STM32_I2C4SEL | STM32_I2C3SEL | + STM32_I2C2SEL | STM32_I2C1SEL | STM32_UART8SEL | + STM32_UART7SEL | STM32_USART6SEL | STM32_UART5SEL | + STM32_UART4SEL | STM32_USART3SEL | STM32_USART2SEL | + STM32_USART1SEL; +#endif + + /* RAM1 2 and 3 clocks enabled.*/ + rccEnableSRAM1(true); + rccEnableSRAM2(true); + rccEnableSRAM3(true); +#endif /* STM32_NO_INIT */ +} + +/** @} */ diff --git a/readme.txt b/readme.txt index d975e5d965..e200de17dd 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed unwanted reset of cache on STM32H7xx (bug #1258). - FIX: Fixed incorrect RTC initialization on STM32G4 (bug #1256). - FIX: Fixed invalid checks on PLLP/R/Q dividers on STM32H7 (bug #1253). - FIX: Fixed remote wakeup failure in STM32 OTGv1 driver (bug #1252). From 360cc0cdde0a7a6e5eb935cfb77105c459893e0d Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 4 Apr 2023 09:37:42 +0000 Subject: [PATCH 22/53] Tentative fix for F401 I2S PLL. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16204 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/STM32F4xx/stm32_registry.h | 6351 +++++++++-------- 1 file changed, 3177 insertions(+), 3174 deletions(-) diff --git a/os/hal/ports/STM32/STM32F4xx/stm32_registry.h b/os/hal/ports/STM32/STM32F4xx/stm32_registry.h index 5072ce7443..3c100e0738 100644 --- a/os/hal/ports/STM32/STM32F4xx/stm32_registry.h +++ b/os/hal/ports/STM32/STM32F4xx/stm32_registry.h @@ -1,3174 +1,3177 @@ -/* - ChibiOS - Copyright (C) 2006..2018 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 STM32F4xx/stm32_registry.h - * @brief STM32F4xx capabilities registry. - * - * @addtogroup HAL - * @{ - */ - -#ifndef STM32_REGISTRY_H -#define STM32_REGISTRY_H - -#if defined(STM32F469xx) || defined(STM32F479xx) -#define STM32F469_479xx -#define STM32F4XX - -#elif defined(STM32F446xx) -#define STM32F4XX - -#elif defined(STM32F439xx) || defined(STM32F429xx) -#define STM32F429_439xx -#define STM32F4XX - -#elif defined(STM32F437xx) || defined(STM32F427xx) -#define STM32F427_437xx -#define STM32F4XX - -#elif defined(STM32F413xx) -#define STM32F413xx -#define STM32F4XX - -#elif defined(STM32F412Cx) || defined(STM32F412Rx) || \ - defined(STM32F412Vx) || defined(STM32F412Zx) -#define STM32F412xx -#define STM32F4XX - -#elif defined(STM32F411xE) -#define STM32F411xx -#define STM32F4XX - -#elif defined(STM32F410Cx) || defined(STM32F410Rx) || \ - defined(STM32F410Tx) -#define STM32F410xx -#define STM32F4XX - -#elif defined(STM32F405xx) || defined(STM32F415xx) || \ - defined(STM32F407xx) || defined(STM32F417xx) -#define STM32F40_41xxx -#define STM32F4XX - -#elif defined(STM32F401xC) || defined(STM32F401xE) -#define STM32F401xx -#define STM32F4XX - -#elif defined(STM32F205xx) || defined(STM32F215xx) || \ - defined(STM32F207xx) || defined(STM32F217xx) -#define STM32F2XX - -#else -#error "STM32F2xx/F4xx device not specified" -#endif - -/*===========================================================================*/ -/* Platform capabilities. */ -/*===========================================================================*/ - -/** - * @name STM32F4xx/STM32F2xx capabilities - * @{ - */ - -/*===========================================================================*/ -/* Common. */ -/*===========================================================================*/ - -/* RNG attributes.*/ -#define STM32_HAS_RNG1 TRUE - -/* RTC attributes.*/ -#define STM32_HAS_RTC TRUE -#if !defined(STM32F2XX) -#define STM32_RTC_HAS_SUBSECONDS TRUE -#else -#define STM32_RTC_HAS_SUBSECONDS FALSE -#endif -#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE -#define STM32_RTC_NUM_ALARMS 2 -#define STM32_RTC_STORAGE_SIZE 80 -#define STM32_RTC_TAMP_STAMP_HANDLER Vector48 -#define STM32_RTC_WKUP_HANDLER Vector4C -#define STM32_RTC_ALARM_HANDLER VectorE4 -#define STM32_RTC_TAMP_STAMP_NUMBER 2 -#define STM32_RTC_WKUP_NUMBER 3 -#define STM32_RTC_ALARM_NUMBER 41 -#define STM32_RTC_ALARM_EXTI 17 -#define STM32_RTC_TAMP_STAMP_EXTI 21 -#define STM32_RTC_WKUP_EXTI 22 -#define STM32_RTC_IRQ_ENABLE() do { \ - nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI21_PRIORITY); \ - nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI22_PRIORITY); \ - nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \ -} while (false) - -/*===========================================================================*/ -/* STM32F469xx, STM32F479xx. */ -/*===========================================================================*/ - -#if defined(STM32F469_479xx) || defined(__DOXYGEN__) - -/* Clock tree attributes.*/ -#define STM32_HAS_RCC_PLLSAI TRUE -#define STM32_HAS_RCC_PLLI2S TRUE -#define STM32_HAS_RCC_DCKCFGR TRUE -#define STM32_HAS_RCC_DCKCFGR2 FALSE -#define STM32_HAS_RCC_I2SSRC TRUE -#define STM32_HAS_RCC_I2SPLLSRC FALSE -#define STM32_HAS_RCC_CK48MSEL TRUE -#define STM32_RCC_CK48MSEL_USES_I2S FALSE -#define STM32_PLL48CLK_ALTSRC STM32_PLLSAI_Q_CLKOUT -#define STM32_TIMPRE_PRESCALE4 TRUE - -/* ADC attributes.*/ -#define STM32_ADC_HANDLER Vector88 -#define STM32_ADC_NUMBER 18 - -#define STM32_HAS_ADC1 TRUE -#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_ADC1_DMA_CHN 0x00000000 - -#define STM32_HAS_ADC2 TRUE -#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ - STM32_DMA_STREAM_ID_MSK(2, 3)) -#define STM32_ADC2_DMA_CHN 0x00001100 - -#define STM32_HAS_ADC3 TRUE -#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 1)) -#define STM32_ADC3_DMA_CHN 0x00000022 - -#define STM32_HAS_ADC4 FALSE - -#define STM32_HAS_SDADC1 FALSE -#define STM32_HAS_SDADC2 FALSE -#define STM32_HAS_SDADC3 FALSE - -/* CAN attributes.*/ -#define STM32_HAS_CAN1 TRUE -#define STM32_HAS_CAN2 TRUE -#define STM32_HAS_CAN3 FALSE -#define STM32_CAN_MAX_FILTERS 28 - -/* DAC attributes.*/ -#define STM32_HAS_DAC1_CH1 TRUE -#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_DAC1_CH1_DMA_CHN 0x00700000 - -#define STM32_HAS_DAC1_CH2 TRUE -#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) -#define STM32_DAC1_CH2_DMA_CHN 0x07000000 - -#define STM32_HAS_DAC2_CH1 FALSE -#define STM32_HAS_DAC2_CH2 FALSE - -/* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING FALSE -#define STM32_DMA_SUPPORTS_DMAMUX FALSE - -#define STM32_HAS_DMA1 TRUE -#define STM32_DMA1_CH0_HANDLER Vector6C -#define STM32_DMA1_CH1_HANDLER Vector70 -#define STM32_DMA1_CH2_HANDLER Vector74 -#define STM32_DMA1_CH3_HANDLER Vector78 -#define STM32_DMA1_CH4_HANDLER Vector7C -#define STM32_DMA1_CH5_HANDLER Vector80 -#define STM32_DMA1_CH6_HANDLER Vector84 -#define STM32_DMA1_CH7_HANDLER VectorFC -#define STM32_DMA1_CH0_NUMBER 11 -#define STM32_DMA1_CH1_NUMBER 12 -#define STM32_DMA1_CH2_NUMBER 13 -#define STM32_DMA1_CH3_NUMBER 14 -#define STM32_DMA1_CH4_NUMBER 15 -#define STM32_DMA1_CH5_NUMBER 16 -#define STM32_DMA1_CH6_NUMBER 17 -#define STM32_DMA1_CH7_NUMBER 47 - -#define STM32_HAS_DMA2 TRUE -#define STM32_DMA2_CH0_HANDLER Vector120 -#define STM32_DMA2_CH1_HANDLER Vector124 -#define STM32_DMA2_CH2_HANDLER Vector128 -#define STM32_DMA2_CH3_HANDLER Vector12C -#define STM32_DMA2_CH4_HANDLER Vector130 -#define STM32_DMA2_CH5_HANDLER Vector150 -#define STM32_DMA2_CH6_HANDLER Vector154 -#define STM32_DMA2_CH7_HANDLER Vector158 -#define STM32_DMA2_CH0_NUMBER 56 -#define STM32_DMA2_CH1_NUMBER 57 -#define STM32_DMA2_CH2_NUMBER 58 -#define STM32_DMA2_CH3_NUMBER 59 -#define STM32_DMA2_CH4_NUMBER 60 -#define STM32_DMA2_CH5_NUMBER 68 -#define STM32_DMA2_CH6_NUMBER 69 -#define STM32_DMA2_CH7_NUMBER 70 - -/* ETH attributes.*/ -#define STM32_HAS_ETH TRUE -#define STM32_ETH_HANDLER Vector134 -#define STM32_ETH_NUMBER 61 - -/* EXTI attributes.*/ -#define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR1_MASK 0x00000000U - -/* GPIO attributes.*/ -#define STM32_HAS_GPIOA TRUE -#define STM32_HAS_GPIOB TRUE -#define STM32_HAS_GPIOC TRUE -#define STM32_HAS_GPIOD TRUE -#define STM32_HAS_GPIOE TRUE -#define STM32_HAS_GPIOH TRUE -#define STM32_HAS_GPIOF TRUE -#define STM32_HAS_GPIOG TRUE -#define STM32_HAS_GPIOI TRUE -#define STM32_HAS_GPIOJ TRUE -#define STM32_HAS_GPIOK TRUE - -#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ - RCC_AHB1ENR_GPIOBEN | \ - RCC_AHB1ENR_GPIOCEN | \ - RCC_AHB1ENR_GPIODEN | \ - RCC_AHB1ENR_GPIOEEN | \ - RCC_AHB1ENR_GPIOFEN | \ - RCC_AHB1ENR_GPIOGEN | \ - RCC_AHB1ENR_GPIOHEN | \ - RCC_AHB1ENR_GPIOIEN | \ - RCC_AHB1ENR_GPIOJEN | \ - RCC_AHB1ENR_GPIOKEN) - -/* I2C attributes.*/ -#define STM32_HAS_I2C1 TRUE -#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ - STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_I2C1_RX_DMA_CHN 0x00100001 -#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ - STM32_DMA_STREAM_ID_MSK(1, 6)) -#define STM32_I2C1_TX_DMA_CHN 0x11000000 - -#define STM32_HAS_I2C2 TRUE -#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ - STM32_DMA_STREAM_ID_MSK(1, 3)) -#define STM32_I2C2_RX_DMA_CHN 0x00007700 -#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) -#define STM32_I2C2_TX_DMA_CHN 0x70000000 - -#define STM32_HAS_I2C3 TRUE -#define STM32_I2C3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) -#define STM32_I2C3_RX_DMA_CHN 0x00000300 -#define STM32_I2C3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_I2C3_TX_DMA_CHN 0x00030000 - -#define STM32_HAS_I2C4 FALSE - -/* QUADSPI attributes.*/ -#define STM32_HAS_QUADSPI1 TRUE -#define STM32_QUADSPI1_HANDLER Vector1AC -#define STM32_QUADSPI1_NUMBER 91 -#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) -#define STM32_QUADSPI1_DMA_CHN 0x30000000 - -/* SDIO attributes.*/ -#define STM32_HAS_SDIO TRUE -#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 6)) -#define STM32_SDC_SDIO_DMA_CHN 0x04004000 - -/* SPI attributes.*/ -#define STM32_HAS_SPI1 TRUE -#define STM32_SPI1_SUPPORTS_I2S TRUE -#define STM32_SPI1_I2S_FULLDUPLEX TRUE -#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_SPI1_RX_DMA_CHN 0x00000303 -#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_SPI1_TX_DMA_CHN 0x00303000 - -#define STM32_HAS_SPI2 TRUE -#define STM32_SPI2_SUPPORTS_I2S TRUE -#define STM32_SPI2_I2S_FULLDUPLEX TRUE -#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) -#define STM32_SPI2_RX_DMA_CHN 0x00000000 -#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_SPI2_TX_DMA_CHN 0x00000000 - -#define STM32_HAS_SPI3 TRUE -#define STM32_SPI3_SUPPORTS_I2S TRUE -#define STM32_SPI3_I2S_FULLDUPLEX TRUE -#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ - STM32_DMA_STREAM_ID_MSK(1, 2)) -#define STM32_SPI3_RX_DMA_CHN 0x00000000 -#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ - STM32_DMA_STREAM_ID_MSK(1, 7)) -#define STM32_SPI3_TX_DMA_CHN 0x00000000 - -#define STM32_HAS_SPI4 TRUE -#define STM32_SPI4_SUPPORTS_I2S FALSE -#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 3)) -#define STM32_SPI4_RX_DMA_CHN 0x00005004 -#define STM32_SPI4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_SPI4_TX_DMA_CHN 0x00050040 - -#define STM32_HAS_SPI5 TRUE -#define STM32_SPI5_SUPPORTS_I2S FALSE -#define STM32_SPI5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_SPI5_RX_DMA_CHN 0x00702000 -#define STM32_SPI5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\ - STM32_DMA_STREAM_ID_MSK(2, 6)) -#define STM32_SPI5_TX_DMA_CHN 0x07020000 - -#define STM32_HAS_SPI6 TRUE -#define STM32_SPI6_SUPPORTS_I2S FALSE -#define STM32_SPI6_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 6) -#define STM32_SPI6_RX_DMA_CHN 0x01000000 -#define STM32_SPI6_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 5) -#define STM32_SPI6_TX_DMA_CHN 0x00100000 - -/* TIM attributes.*/ -#define STM32_TIM_MAX_CHANNELS 4 - -#define STM32_HAS_TIM1 TRUE -#define STM32_TIM1_IS_32BITS FALSE -#define STM32_TIM1_CHANNELS 4 - -#define STM32_HAS_TIM2 TRUE -#define STM32_TIM2_IS_32BITS TRUE -#define STM32_TIM2_CHANNELS 4 - -#define STM32_HAS_TIM3 TRUE -#define STM32_TIM3_IS_32BITS FALSE -#define STM32_TIM3_CHANNELS 4 - -#define STM32_HAS_TIM4 TRUE -#define STM32_TIM4_IS_32BITS FALSE -#define STM32_TIM4_CHANNELS 4 - -#define STM32_HAS_TIM5 TRUE -#define STM32_TIM5_IS_32BITS TRUE -#define STM32_TIM5_CHANNELS 4 - -#define STM32_HAS_TIM6 TRUE -#define STM32_TIM6_IS_32BITS FALSE -#define STM32_TIM6_CHANNELS 0 - -#define STM32_HAS_TIM7 TRUE -#define STM32_TIM7_IS_32BITS FALSE -#define STM32_TIM7_CHANNELS 0 - -#define STM32_HAS_TIM8 TRUE -#define STM32_TIM8_IS_32BITS FALSE -#define STM32_TIM8_CHANNELS 4 - -#define STM32_HAS_TIM9 TRUE -#define STM32_TIM9_IS_32BITS FALSE -#define STM32_TIM9_CHANNELS 2 - -#define STM32_HAS_TIM10 TRUE -#define STM32_TIM10_IS_32BITS FALSE -#define STM32_TIM10_CHANNELS 1 - -#define STM32_HAS_TIM11 TRUE -#define STM32_TIM11_IS_32BITS FALSE -#define STM32_TIM11_CHANNELS 1 - -#define STM32_HAS_TIM12 TRUE -#define STM32_TIM12_IS_32BITS FALSE -#define STM32_TIM12_CHANNELS 2 - -#define STM32_HAS_TIM13 TRUE -#define STM32_TIM13_IS_32BITS FALSE -#define STM32_TIM13_CHANNELS 1 - -#define STM32_HAS_TIM14 TRUE -#define STM32_TIM14_IS_32BITS FALSE -#define STM32_TIM14_CHANNELS 1 - -#define STM32_HAS_TIM15 FALSE -#define STM32_HAS_TIM16 FALSE -#define STM32_HAS_TIM17 FALSE -#define STM32_HAS_TIM18 FALSE -#define STM32_HAS_TIM19 FALSE -#define STM32_HAS_TIM20 FALSE -#define STM32_HAS_TIM21 FALSE -#define STM32_HAS_TIM22 FALSE - -/* USART attributes.*/ -#define STM32_HAS_USART1 TRUE -#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_USART1_RX_DMA_CHN 0x00400400 -#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) -#define STM32_USART1_TX_DMA_CHN 0x40000000 - -#define STM32_HAS_USART2 TRUE -#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) -#define STM32_USART2_RX_DMA_CHN 0x00400000 -#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) -#define STM32_USART2_TX_DMA_CHN 0x04000000 - -#define STM32_HAS_USART3 TRUE -#define STM32_USART3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) -#define STM32_USART3_RX_DMA_CHN 0x00000040 -#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\ - STM32_DMA_STREAM_ID_MSK(1, 4)) -#define STM32_USART3_TX_DMA_CHN 0x00074000 - -#define STM32_HAS_UART4 TRUE -#define STM32_UART4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) -#define STM32_UART4_RX_DMA_CHN 0x00000400 -#define STM32_UART4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_UART4_TX_DMA_CHN 0x00040000 - -#define STM32_HAS_UART5 TRUE -#define STM32_UART5_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) -#define STM32_UART5_RX_DMA_CHN 0x00000004 -#define STM32_UART5_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) -#define STM32_UART5_TX_DMA_CHN 0x40000000 - -#define STM32_HAS_USART6 TRUE -#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_USART6_RX_DMA_CHN 0x00000550 -#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ - STM32_DMA_STREAM_ID_MSK(2, 7)) -#define STM32_USART6_TX_DMA_CHN 0x55000000 - -#define STM32_HAS_UART7 TRUE -#define STM32_UART7_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) -#define STM32_UART7_RX_DMA_CHN 0x00005000 -#define STM32_UART7_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) -#define STM32_UART7_TX_DMA_CHN 0x00000050 - -#define STM32_HAS_UART8 TRUE -#define STM32_UART8_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) -#define STM32_UART8_RX_DMA_CHN 0x05000000 -#define STM32_UART8_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) -#define STM32_UART8_TX_DMA_CHN 0x00000005 -#define STM32_HAS_LPUART1 FALSE - -/* USB attributes.*/ -#define STM32_OTG_STEPPING 2 -#define STM32_HAS_OTG1 TRUE -#define STM32_OTG1_ENDPOINTS 5 -#define STM32_HAS_OTG2 TRUE -#define STM32_OTG2_ENDPOINTS 7 - -#define STM32_HAS_USB FALSE - -/* IWDG attributes.*/ -#define STM32_HAS_IWDG TRUE -#define STM32_IWDG_IS_WINDOWED FALSE - -/* LTDC attributes.*/ -#define STM32_HAS_LTDC TRUE - -/* DMA2D attributes.*/ -#define STM32_HAS_DMA2D TRUE - -/* FSMC attributes.*/ -#define STM32_HAS_FSMC TRUE -#define STM32_FSMC_IS_FMC TRUE -#define STM32_FSMC_HANDLER Vector100 -#define STM32_FSMC_NUMBER 48 - -/* CRC attributes.*/ -#define STM32_HAS_CRC TRUE -#define STM32_CRC_PROGRAMMABLE FALSE - -#endif /* defined(STM32F469_479xx) */ - -/*===========================================================================*/ -/* STM32F446xx. */ -/*===========================================================================*/ - -#if defined(STM32F446xx) - -/* Clock tree attributes.*/ -#define STM32_HAS_RCC_PLLSAI TRUE -#define STM32_HAS_RCC_PLLI2S TRUE -#define STM32_HAS_RCC_DCKCFGR TRUE -#define STM32_HAS_RCC_DCKCFGR2 TRUE -#define STM32_HAS_RCC_I2SSRC FALSE -#define STM32_HAS_RCC_I2SPLLSRC FALSE -#define STM32_HAS_RCC_CK48MSEL TRUE -#define STM32_RCC_CK48MSEL_USES_I2S FALSE -#define STM32_PLL48CLK_ALTSRC STM32_PLLSAI_P_CLKOUT -#define STM32_TIMPRE_PRESCALE4 TRUE - -/* ADC attributes.*/ -#define STM32_ADC_HANDLER Vector88 -#define STM32_ADC_NUMBER 18 - -#define STM32_HAS_ADC1 TRUE -#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_ADC1_DMA_CHN 0x00000000 - -#define STM32_HAS_ADC2 TRUE -#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ - STM32_DMA_STREAM_ID_MSK(2, 3)) -#define STM32_ADC2_DMA_CHN 0x00001100 - -#define STM32_HAS_ADC3 TRUE -#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 1)) -#define STM32_ADC3_DMA_CHN 0x00000022 - -#define STM32_HAS_ADC4 FALSE - -#define STM32_HAS_SDADC1 FALSE -#define STM32_HAS_SDADC2 FALSE -#define STM32_HAS_SDADC3 FALSE - -/* CAN attributes.*/ -#define STM32_HAS_CAN1 TRUE -#define STM32_HAS_CAN2 TRUE -#define STM32_HAS_CAN3 FALSE -#define STM32_CAN_MAX_FILTERS 28 - -/* DAC attributes.*/ -#define STM32_HAS_DAC1_CH1 TRUE -#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_DAC1_CH1_DMA_CHN 0x00700000 - -#define STM32_HAS_DAC1_CH2 TRUE -#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) -#define STM32_DAC1_CH2_DMA_CHN 0x07000000 - -#define STM32_HAS_DAC2_CH1 FALSE -#define STM32_HAS_DAC2_CH2 FALSE - -/* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING FALSE -#define STM32_DMA_SUPPORTS_DMAMUX FALSE - -#define STM32_HAS_DMA1 TRUE -#define STM32_DMA1_CH0_HANDLER Vector6C -#define STM32_DMA1_CH1_HANDLER Vector70 -#define STM32_DMA1_CH2_HANDLER Vector74 -#define STM32_DMA1_CH3_HANDLER Vector78 -#define STM32_DMA1_CH4_HANDLER Vector7C -#define STM32_DMA1_CH5_HANDLER Vector80 -#define STM32_DMA1_CH6_HANDLER Vector84 -#define STM32_DMA1_CH7_HANDLER VectorFC -#define STM32_DMA1_CH0_NUMBER 11 -#define STM32_DMA1_CH1_NUMBER 12 -#define STM32_DMA1_CH2_NUMBER 13 -#define STM32_DMA1_CH3_NUMBER 14 -#define STM32_DMA1_CH4_NUMBER 15 -#define STM32_DMA1_CH5_NUMBER 16 -#define STM32_DMA1_CH6_NUMBER 17 -#define STM32_DMA1_CH7_NUMBER 47 - -#define STM32_HAS_DMA2 TRUE -#define STM32_DMA2_CH0_HANDLER Vector120 -#define STM32_DMA2_CH1_HANDLER Vector124 -#define STM32_DMA2_CH2_HANDLER Vector128 -#define STM32_DMA2_CH3_HANDLER Vector12C -#define STM32_DMA2_CH4_HANDLER Vector130 -#define STM32_DMA2_CH5_HANDLER Vector150 -#define STM32_DMA2_CH6_HANDLER Vector154 -#define STM32_DMA2_CH7_HANDLER Vector158 -#define STM32_DMA2_CH0_NUMBER 56 -#define STM32_DMA2_CH1_NUMBER 57 -#define STM32_DMA2_CH2_NUMBER 58 -#define STM32_DMA2_CH3_NUMBER 59 -#define STM32_DMA2_CH4_NUMBER 60 -#define STM32_DMA2_CH5_NUMBER 68 -#define STM32_DMA2_CH6_NUMBER 69 -#define STM32_DMA2_CH7_NUMBER 70 - -/* ETH attributes.*/ -#define STM32_HAS_ETH FALSE - -/* EXTI attributes.*/ -#define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR1_MASK 0x00000000U - -/* GPIO attributes.*/ -#define STM32_HAS_GPIOA TRUE -#define STM32_HAS_GPIOB TRUE -#define STM32_HAS_GPIOC TRUE -#define STM32_HAS_GPIOD TRUE -#define STM32_HAS_GPIOE TRUE -#define STM32_HAS_GPIOF TRUE -#define STM32_HAS_GPIOG TRUE -#define STM32_HAS_GPIOH TRUE -#define STM32_HAS_GPIOI FALSE -#define STM32_HAS_GPIOJ FALSE -#define STM32_HAS_GPIOK FALSE - -#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ - RCC_AHB1ENR_GPIOBEN | \ - RCC_AHB1ENR_GPIOCEN | \ - RCC_AHB1ENR_GPIODEN | \ - RCC_AHB1ENR_GPIOEEN | \ - RCC_AHB1ENR_GPIOFEN | \ - RCC_AHB1ENR_GPIOGEN | \ - RCC_AHB1ENR_GPIOHEN) - -/* I2C attributes.*/ -#define STM32_HAS_I2C1 TRUE -#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ - STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_I2C1_RX_DMA_CHN 0x00100001 -#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ - STM32_DMA_STREAM_ID_MSK(1, 6)) -#define STM32_I2C1_TX_DMA_CHN 0x11000000 - -#define STM32_HAS_I2C2 TRUE -#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ - STM32_DMA_STREAM_ID_MSK(1, 3)) -#define STM32_I2C2_RX_DMA_CHN 0x00007700 -#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) -#define STM32_I2C2_TX_DMA_CHN 0x70000000 - -#define STM32_HAS_I2C3 TRUE -#define STM32_I2C3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) -#define STM32_I2C3_RX_DMA_CHN 0x00000300 -#define STM32_I2C3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_I2C3_TX_DMA_CHN 0x00030000 - -#define STM32_HAS_I2C4 FALSE - -/* QUADSPI attributes.*/ -#define STM32_HAS_QUADSPI1 TRUE -#define STM32_QUADSPI1_HANDLER Vector1B0 -#define STM32_QUADSPI1_NUMBER 92 -#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) -#define STM32_QUADSPI1_DMA_CHN 0x30000000 - -/* SDIO attributes.*/ -#define STM32_HAS_SDIO TRUE -#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 6)) -#define STM32_SDC_SDIO_DMA_CHN 0x04004000 - -/* SPI attributes.*/ -#define STM32_HAS_SPI1 TRUE -#define STM32_SPI1_SUPPORTS_I2S TRUE -#define STM32_SPI1_I2S_FULLDUPLEX FALSE -#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_SPI1_RX_DMA_CHN 0x00000303 -#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_SPI1_TX_DMA_CHN 0x00303000 - -#define STM32_HAS_SPI2 TRUE -#define STM32_SPI2_SUPPORTS_I2S TRUE -#define STM32_SPI2_I2S_FULLDUPLEX FALSE -#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) -#define STM32_SPI2_RX_DMA_CHN 0x00000000 -#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_SPI2_TX_DMA_CHN 0x00000000 - -#define STM32_HAS_SPI3 TRUE -#define STM32_SPI3_SUPPORTS_I2S TRUE -#define STM32_SPI3_I2S_FULLDUPLEX FALSE -#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ - STM32_DMA_STREAM_ID_MSK(1, 2)) -#define STM32_SPI3_RX_DMA_CHN 0x00000000 -#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ - STM32_DMA_STREAM_ID_MSK(1, 7)) -#define STM32_SPI3_TX_DMA_CHN 0x00000000 - -#define STM32_HAS_SPI4 TRUE -#define STM32_SPI4_SUPPORTS_I2S FALSE -#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 3)) -#define STM32_SPI4_RX_DMA_CHN 0x00005004 -#define STM32_SPI4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_SPI4_TX_DMA_CHN 0x00050040 - -#define STM32_HAS_SPI5 FALSE -#define STM32_HAS_SPI6 FALSE - -/* TIM attributes.*/ -#define STM32_TIM_MAX_CHANNELS 4 - -#define STM32_HAS_TIM1 TRUE -#define STM32_TIM1_IS_32BITS FALSE -#define STM32_TIM1_CHANNELS 4 - -#define STM32_HAS_TIM2 TRUE -#define STM32_TIM2_IS_32BITS TRUE -#define STM32_TIM2_CHANNELS 4 - -#define STM32_HAS_TIM3 TRUE -#define STM32_TIM3_IS_32BITS FALSE -#define STM32_TIM3_CHANNELS 4 - -#define STM32_HAS_TIM4 TRUE -#define STM32_TIM4_IS_32BITS FALSE -#define STM32_TIM4_CHANNELS 4 - -#define STM32_HAS_TIM5 TRUE -#define STM32_TIM5_IS_32BITS TRUE -#define STM32_TIM5_CHANNELS 4 - -#define STM32_HAS_TIM6 TRUE -#define STM32_TIM6_IS_32BITS FALSE -#define STM32_TIM6_CHANNELS 0 - -#define STM32_HAS_TIM7 TRUE -#define STM32_TIM7_IS_32BITS FALSE -#define STM32_TIM7_CHANNELS 0 - -#define STM32_HAS_TIM8 TRUE -#define STM32_TIM8_IS_32BITS FALSE -#define STM32_TIM8_CHANNELS 4 - -#define STM32_HAS_TIM9 TRUE -#define STM32_TIM9_IS_32BITS FALSE -#define STM32_TIM9_CHANNELS 2 - -#define STM32_HAS_TIM10 TRUE -#define STM32_TIM10_IS_32BITS FALSE -#define STM32_TIM10_CHANNELS 1 - -#define STM32_HAS_TIM11 TRUE -#define STM32_TIM11_IS_32BITS FALSE -#define STM32_TIM11_CHANNELS 1 - -#define STM32_HAS_TIM12 TRUE -#define STM32_TIM12_IS_32BITS FALSE -#define STM32_TIM12_CHANNELS 2 - -#define STM32_HAS_TIM13 TRUE -#define STM32_TIM13_IS_32BITS FALSE -#define STM32_TIM13_CHANNELS 1 - -#define STM32_HAS_TIM14 TRUE -#define STM32_TIM14_IS_32BITS FALSE -#define STM32_TIM14_CHANNELS 1 - -#define STM32_HAS_TIM15 FALSE -#define STM32_HAS_TIM16 FALSE -#define STM32_HAS_TIM17 FALSE -#define STM32_HAS_TIM18 FALSE -#define STM32_HAS_TIM19 FALSE -#define STM32_HAS_TIM20 FALSE -#define STM32_HAS_TIM21 FALSE -#define STM32_HAS_TIM22 FALSE - -/* USART attributes.*/ -#define STM32_HAS_USART1 TRUE -#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_USART1_RX_DMA_CHN 0x00400400 -#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) -#define STM32_USART1_TX_DMA_CHN 0x40000000 - -#define STM32_HAS_USART2 TRUE -#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) -#define STM32_USART2_RX_DMA_CHN 0x00400000 -#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) -#define STM32_USART2_TX_DMA_CHN 0x04000000 - -#define STM32_HAS_USART3 TRUE -#define STM32_USART3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) -#define STM32_USART3_RX_DMA_CHN 0x00000040 -#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\ - STM32_DMA_STREAM_ID_MSK(1, 4)) -#define STM32_USART3_TX_DMA_CHN 0x00074000 - -#define STM32_HAS_UART4 TRUE -#define STM32_UART4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) -#define STM32_UART4_RX_DMA_CHN 0x00000400 -#define STM32_UART4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_UART4_TX_DMA_CHN 0x00040000 - -#define STM32_HAS_UART5 TRUE -#define STM32_UART5_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) -#define STM32_UART5_RX_DMA_CHN 0x00000004 -#define STM32_UART5_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) -#define STM32_UART5_TX_DMA_CHN 0x40000000 - -#define STM32_HAS_USART6 TRUE -#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_USART6_RX_DMA_CHN 0x00000550 -#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ - STM32_DMA_STREAM_ID_MSK(2, 7)) -#define STM32_USART6_TX_DMA_CHN 0x55000000 - -#define STM32_HAS_UART7 FALSE -#define STM32_HAS_UART8 FALSE -#define STM32_HAS_LPUART1 FALSE - -/* USB attributes.*/ -#define STM32_OTG_STEPPING 2 -#define STM32_HAS_OTG1 TRUE -#define STM32_OTG1_ENDPOINTS 5 -#define STM32_HAS_OTG2 TRUE -#define STM32_OTG2_ENDPOINTS 7 - -#define STM32_HAS_USB FALSE - -/* IWDG attributes.*/ -#define STM32_HAS_IWDG TRUE -#define STM32_IWDG_IS_WINDOWED FALSE - -/* LTDC attributes.*/ -#define STM32_HAS_LTDC TRUE - -/* DMA2D attributes.*/ -#define STM32_HAS_DMA2D TRUE - -/* FSMC attributes.*/ -#define STM32_HAS_FSMC TRUE -#define STM32_FSMC_IS_FMC TRUE -#define STM32_FSMC_HANDLER Vector100 -#define STM32_FSMC_NUMBER 48 - -/* CRC attributes.*/ -#define STM32_HAS_CRC TRUE -#define STM32_CRC_PROGRAMMABLE FALSE - -#endif /* defined(STM32F446xx) */ - -/*===========================================================================*/ -/* STM32F439xx, STM32F429xx, STM32F437xx, STM32F427xx. */ -/*===========================================================================*/ - -#if defined(STM32F429_439xx) || defined(STM32F427_437xx) - -/* Clock tree attributes.*/ -#define STM32_HAS_RCC_PLLSAI TRUE -#define STM32_HAS_RCC_PLLI2S TRUE -#define STM32_HAS_RCC_DCKCFGR TRUE -#define STM32_HAS_RCC_DCKCFGR2 FALSE -#define STM32_HAS_RCC_I2SSRC TRUE -#define STM32_HAS_RCC_I2SPLLSRC FALSE -#define STM32_HAS_RCC_CK48MSEL FALSE -#define STM32_RCC_CK48MSEL_USES_I2S FALSE -#define STM32_TIMPRE_PRESCALE4 TRUE - -/* ADC attributes.*/ -#define STM32_ADC_HANDLER Vector88 -#define STM32_ADC_NUMBER 18 - -#define STM32_HAS_ADC1 TRUE -#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_ADC1_DMA_CHN 0x00000000 - -#define STM32_HAS_ADC2 TRUE -#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ - STM32_DMA_STREAM_ID_MSK(2, 3)) -#define STM32_ADC2_DMA_CHN 0x00001100 - -#define STM32_HAS_ADC3 TRUE -#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 1)) -#define STM32_ADC3_DMA_CHN 0x00000022 - -#define STM32_HAS_ADC4 FALSE - -#define STM32_HAS_SDADC1 FALSE -#define STM32_HAS_SDADC2 FALSE -#define STM32_HAS_SDADC3 FALSE - -/* CAN attributes.*/ -#define STM32_HAS_CAN1 TRUE -#define STM32_HAS_CAN2 TRUE -#define STM32_HAS_CAN3 FALSE -#define STM32_CAN_MAX_FILTERS 28 - -/* DAC attributes.*/ -#define STM32_HAS_DAC1_CH1 TRUE -#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_DAC1_CH1_DMA_CHN 0x00700000 - -#define STM32_HAS_DAC1_CH2 TRUE -#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) -#define STM32_DAC1_CH2_DMA_CHN 0x07000000 - -#define STM32_HAS_DAC2_CH1 FALSE -#define STM32_HAS_DAC2_CH2 FALSE - -/* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING FALSE -#define STM32_DMA_SUPPORTS_DMAMUX FALSE - -#define STM32_HAS_DMA1 TRUE -#define STM32_DMA1_CH0_HANDLER Vector6C -#define STM32_DMA1_CH1_HANDLER Vector70 -#define STM32_DMA1_CH2_HANDLER Vector74 -#define STM32_DMA1_CH3_HANDLER Vector78 -#define STM32_DMA1_CH4_HANDLER Vector7C -#define STM32_DMA1_CH5_HANDLER Vector80 -#define STM32_DMA1_CH6_HANDLER Vector84 -#define STM32_DMA1_CH7_HANDLER VectorFC -#define STM32_DMA1_CH0_NUMBER 11 -#define STM32_DMA1_CH1_NUMBER 12 -#define STM32_DMA1_CH2_NUMBER 13 -#define STM32_DMA1_CH3_NUMBER 14 -#define STM32_DMA1_CH4_NUMBER 15 -#define STM32_DMA1_CH5_NUMBER 16 -#define STM32_DMA1_CH6_NUMBER 17 -#define STM32_DMA1_CH7_NUMBER 47 - -#define STM32_HAS_DMA2 TRUE -#define STM32_DMA2_CH0_HANDLER Vector120 -#define STM32_DMA2_CH1_HANDLER Vector124 -#define STM32_DMA2_CH2_HANDLER Vector128 -#define STM32_DMA2_CH3_HANDLER Vector12C -#define STM32_DMA2_CH4_HANDLER Vector130 -#define STM32_DMA2_CH5_HANDLER Vector150 -#define STM32_DMA2_CH6_HANDLER Vector154 -#define STM32_DMA2_CH7_HANDLER Vector158 -#define STM32_DMA2_CH0_NUMBER 56 -#define STM32_DMA2_CH1_NUMBER 57 -#define STM32_DMA2_CH2_NUMBER 58 -#define STM32_DMA2_CH3_NUMBER 59 -#define STM32_DMA2_CH4_NUMBER 60 -#define STM32_DMA2_CH5_NUMBER 68 -#define STM32_DMA2_CH6_NUMBER 69 -#define STM32_DMA2_CH7_NUMBER 70 - -/* ETH attributes.*/ -#define STM32_HAS_ETH TRUE -#define STM32_ETH_HANDLER Vector134 -#define STM32_ETH_NUMBER 61 - -/* EXTI attributes.*/ -#define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR1_MASK 0x00000000U - -/* GPIO attributes.*/ -#define STM32_HAS_GPIOA TRUE -#define STM32_HAS_GPIOB TRUE -#define STM32_HAS_GPIOC TRUE -#define STM32_HAS_GPIOD TRUE -#define STM32_HAS_GPIOE TRUE -#define STM32_HAS_GPIOH TRUE -#define STM32_HAS_GPIOF TRUE -#define STM32_HAS_GPIOG TRUE -#define STM32_HAS_GPIOI TRUE -#define STM32_HAS_GPIOJ FALSE -#define STM32_HAS_GPIOK FALSE -#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ - RCC_AHB1ENR_GPIOBEN | \ - RCC_AHB1ENR_GPIOCEN | \ - RCC_AHB1ENR_GPIODEN | \ - RCC_AHB1ENR_GPIOEEN | \ - RCC_AHB1ENR_GPIOFEN | \ - RCC_AHB1ENR_GPIOGEN | \ - RCC_AHB1ENR_GPIOHEN | \ - RCC_AHB1ENR_GPIOIEN) - -/* I2C attributes.*/ -#define STM32_HAS_I2C1 TRUE -#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ - STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_I2C1_RX_DMA_CHN 0x00100001 -#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ - STM32_DMA_STREAM_ID_MSK(1, 6)) -#define STM32_I2C1_TX_DMA_CHN 0x11000000 - -#define STM32_HAS_I2C2 TRUE -#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ - STM32_DMA_STREAM_ID_MSK(1, 3)) -#define STM32_I2C2_RX_DMA_CHN 0x00007700 -#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) -#define STM32_I2C2_TX_DMA_CHN 0x70000000 - -#define STM32_HAS_I2C3 TRUE -#define STM32_I2C3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) -#define STM32_I2C3_RX_DMA_CHN 0x00000300 -#define STM32_I2C3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_I2C3_TX_DMA_CHN 0x00030000 - -#define STM32_HAS_I2C4 FALSE - -/* QUADSPI attributes.*/ -#define STM32_HAS_QUADSPI1 FALSE - -/* SDIO attributes.*/ -#define STM32_HAS_SDIO TRUE -#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 6)) -#define STM32_SDC_SDIO_DMA_CHN 0x04004000 - -/* SPI attributes.*/ -#define STM32_HAS_SPI1 TRUE -#define STM32_SPI1_SUPPORTS_I2S FALSE -#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_SPI1_RX_DMA_CHN 0x00000303 -#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_SPI1_TX_DMA_CHN 0x00303000 - -#define STM32_HAS_SPI2 TRUE -#define STM32_SPI2_SUPPORTS_I2S TRUE -#define STM32_SPI2_I2S_FULLDUPLEX TRUE -#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) -#define STM32_SPI2_RX_DMA_CHN 0x00000000 -#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_SPI2_TX_DMA_CHN 0x00000000 - -#define STM32_HAS_SPI3 TRUE -#define STM32_SPI3_SUPPORTS_I2S TRUE -#define STM32_SPI3_I2S_FULLDUPLEX TRUE -#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ - STM32_DMA_STREAM_ID_MSK(1, 2)) -#define STM32_SPI3_RX_DMA_CHN 0x00000000 -#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ - STM32_DMA_STREAM_ID_MSK(1, 7)) -#define STM32_SPI3_TX_DMA_CHN 0x00000000 - -#define STM32_HAS_SPI4 TRUE -#define STM32_SPI4_SUPPORTS_I2S FALSE -#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 3)) -#define STM32_SPI4_RX_DMA_CHN 0x00005004 -#define STM32_SPI4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_SPI4_TX_DMA_CHN 0x00050040 - -#define STM32_HAS_SPI5 TRUE -#define STM32_SPI5_SUPPORTS_I2S FALSE -#define STM32_SPI5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) | \ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_SPI5_RX_DMA_CHN 0x00702000 -#define STM32_SPI5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) | \ - STM32_DMA_STREAM_ID_MSK(2, 6)) -#define STM32_SPI5_TX_DMA_CHN 0x07020000 - -#define STM32_HAS_SPI6 TRUE -#define STM32_SPI6_SUPPORTS_I2S FALSE -#define STM32_SPI6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6)) -#define STM32_SPI6_RX_DMA_CHN 0x01000000 -#define STM32_SPI6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_SPI6_TX_DMA_CHN 0x00100000 - -/* TIM attributes.*/ -#define STM32_TIM_MAX_CHANNELS 4 - -#define STM32_HAS_TIM1 TRUE -#define STM32_TIM1_IS_32BITS FALSE -#define STM32_TIM1_CHANNELS 4 - -#define STM32_HAS_TIM2 TRUE -#define STM32_TIM2_IS_32BITS TRUE -#define STM32_TIM2_CHANNELS 4 - -#define STM32_HAS_TIM3 TRUE -#define STM32_TIM3_IS_32BITS FALSE -#define STM32_TIM3_CHANNELS 4 - -#define STM32_HAS_TIM4 TRUE -#define STM32_TIM4_IS_32BITS FALSE -#define STM32_TIM4_CHANNELS 4 - -#define STM32_HAS_TIM5 TRUE -#define STM32_TIM5_IS_32BITS TRUE -#define STM32_TIM5_CHANNELS 4 - -#define STM32_HAS_TIM6 TRUE -#define STM32_TIM6_IS_32BITS FALSE -#define STM32_TIM6_CHANNELS 0 - -#define STM32_HAS_TIM7 TRUE -#define STM32_TIM7_IS_32BITS FALSE -#define STM32_TIM7_CHANNELS 0 - -#define STM32_HAS_TIM8 TRUE -#define STM32_TIM8_IS_32BITS FALSE -#define STM32_TIM8_CHANNELS 4 - -#define STM32_HAS_TIM9 TRUE -#define STM32_TIM9_IS_32BITS FALSE -#define STM32_TIM9_CHANNELS 2 - -#define STM32_HAS_TIM10 TRUE -#define STM32_TIM10_IS_32BITS FALSE -#define STM32_TIM10_CHANNELS 1 - -#define STM32_HAS_TIM11 TRUE -#define STM32_TIM11_IS_32BITS FALSE -#define STM32_TIM11_CHANNELS 1 - -#define STM32_HAS_TIM12 TRUE -#define STM32_TIM12_IS_32BITS FALSE -#define STM32_TIM12_CHANNELS 2 - -#define STM32_HAS_TIM13 TRUE -#define STM32_TIM13_IS_32BITS FALSE -#define STM32_TIM13_CHANNELS 1 - -#define STM32_HAS_TIM14 TRUE -#define STM32_TIM14_IS_32BITS FALSE -#define STM32_TIM14_CHANNELS 1 - -#define STM32_HAS_TIM15 FALSE -#define STM32_HAS_TIM16 FALSE -#define STM32_HAS_TIM17 FALSE -#define STM32_HAS_TIM18 FALSE -#define STM32_HAS_TIM19 FALSE -#define STM32_HAS_TIM20 FALSE -#define STM32_HAS_TIM21 FALSE -#define STM32_HAS_TIM22 FALSE - -/* USART attributes.*/ -#define STM32_HAS_USART1 TRUE -#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_USART1_RX_DMA_CHN 0x00400400 -#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) -#define STM32_USART1_TX_DMA_CHN 0x40000000 - -#define STM32_HAS_USART2 TRUE -#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) -#define STM32_USART2_RX_DMA_CHN 0x00400000 -#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) -#define STM32_USART2_TX_DMA_CHN 0x04000000 - -#define STM32_HAS_USART3 TRUE -#define STM32_USART3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) -#define STM32_USART3_RX_DMA_CHN 0x00000040 -#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\ - STM32_DMA_STREAM_ID_MSK(1, 4)) -#define STM32_USART3_TX_DMA_CHN 0x00074000 - -#define STM32_HAS_UART4 TRUE -#define STM32_UART4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) -#define STM32_UART4_RX_DMA_CHN 0x00000400 -#define STM32_UART4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_UART4_TX_DMA_CHN 0x00040000 - -#define STM32_HAS_UART5 TRUE -#define STM32_UART5_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) -#define STM32_UART5_RX_DMA_CHN 0x00000004 -#define STM32_UART5_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) -#define STM32_UART5_TX_DMA_CHN 0x40000000 - -#define STM32_HAS_USART6 TRUE -#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_USART6_RX_DMA_CHN 0x00000550 -#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ - STM32_DMA_STREAM_ID_MSK(2, 7)) -#define STM32_USART6_TX_DMA_CHN 0x55000000 - -#define STM32_HAS_UART7 TRUE -#define STM32_UART7_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) -#define STM32_UART7_RX_DMA_CHN 0x00005000 -#define STM32_UART7_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) -#define STM32_UART7_TX_DMA_CHN 0x00000050 - -#define STM32_HAS_UART8 TRUE -#define STM32_UART8_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) -#define STM32_UART8_RX_DMA_CHN 0x05000000 -#define STM32_UART8_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) -#define STM32_UART8_TX_DMA_CHN 0x00000005 - -#define STM32_HAS_LPUART1 FALSE - -/* USB attributes.*/ -#define STM32_OTG_STEPPING 1 -#define STM32_HAS_OTG1 TRUE -#define STM32_OTG1_ENDPOINTS 3 -#define STM32_HAS_OTG2 TRUE -#define STM32_OTG2_ENDPOINTS 5 - -#define STM32_HAS_USB FALSE - -/* IWDG attributes.*/ -#define STM32_HAS_IWDG TRUE -#define STM32_IWDG_IS_WINDOWED FALSE - -/* LTDC attributes.*/ -#define STM32_HAS_LTDC TRUE - -/* DMA2D attributes.*/ -#define STM32_HAS_DMA2D TRUE - -/* FSMC attributes.*/ -#define STM32_HAS_FSMC TRUE -#define STM32_FSMC_IS_FMC TRUE -#define STM32_FSMC_HANDLER Vector100 -#define STM32_FSMC_NUMBER 48 - -/* CRC attributes.*/ -#define STM32_HAS_CRC TRUE -#define STM32_CRC_PROGRAMMABLE FALSE - -#endif /* defined(STM32F429_439xx) || defined(STM32F427_437xx) */ - -/*===========================================================================*/ -/* STM32F413xx. */ -/*===========================================================================*/ - -#if defined(STM32F413xx) - -/* Clock tree attributes.*/ -#define STM32_HAS_RCC_PLLSAI FALSE -#define STM32_HAS_RCC_PLLI2S TRUE -#define STM32_HAS_RCC_DCKCFGR TRUE -#define STM32_HAS_RCC_DCKCFGR2 TRUE -#define STM32_HAS_RCC_I2SSRC FALSE -#define STM32_HAS_RCC_I2SPLLSRC TRUE -#define STM32_HAS_RCC_CK48MSEL TRUE -#define STM32_RCC_CK48MSEL_USES_I2S TRUE -#define STM32_PLL48CLK_ALTSRC STM32_PLLI2S_Q_CLKOUT -#define STM32_TIMPRE_PRESCALE4 FALSE - -/* ADC attributes.*/ -#define STM32_ADC_HANDLER Vector88 -#define STM32_ADC_NUMBER 18 - -#define STM32_HAS_ADC1 TRUE -#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_ADC1_DMA_CHN 0x00000000 - -#define STM32_HAS_ADC2 FALSE -#define STM32_HAS_ADC3 FALSE -#define STM32_HAS_ADC4 FALSE - -#define STM32_HAS_SDADC1 FALSE -#define STM32_HAS_SDADC2 FALSE -#define STM32_HAS_SDADC3 FALSE - -/* CAN attributes.*/ -#define STM32_HAS_CAN1 TRUE -#define STM32_HAS_CAN2 TRUE -#define STM32_HAS_CAN3 TRUE -#define STM32_CAN_MAX_FILTERS 28 - -/* DAC attributes.*/ -#define STM32_HAS_DAC1_CH1 TRUE -#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_DAC1_CH1_DMA_CHN 0x00700000 - -#define STM32_HAS_DAC1_CH2 TRUE -#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) -#define STM32_DAC1_CH2_DMA_CHN 0x07000000 - -#define STM32_HAS_DAC2_CH1 FALSE -#define STM32_HAS_DAC2_CH2 FALSE - -/* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING FALSE -#define STM32_DMA_SUPPORTS_DMAMUX FALSE - -#define STM32_HAS_DMA1 TRUE -#define STM32_DMA1_CH0_HANDLER Vector6C -#define STM32_DMA1_CH1_HANDLER Vector70 -#define STM32_DMA1_CH2_HANDLER Vector74 -#define STM32_DMA1_CH3_HANDLER Vector78 -#define STM32_DMA1_CH4_HANDLER Vector7C -#define STM32_DMA1_CH5_HANDLER Vector80 -#define STM32_DMA1_CH6_HANDLER Vector84 -#define STM32_DMA1_CH7_HANDLER VectorFC -#define STM32_DMA1_CH0_NUMBER 11 -#define STM32_DMA1_CH1_NUMBER 12 -#define STM32_DMA1_CH2_NUMBER 13 -#define STM32_DMA1_CH3_NUMBER 14 -#define STM32_DMA1_CH4_NUMBER 15 -#define STM32_DMA1_CH5_NUMBER 16 -#define STM32_DMA1_CH6_NUMBER 17 -#define STM32_DMA1_CH7_NUMBER 47 - -#define STM32_HAS_DMA2 TRUE -#define STM32_DMA2_CH0_HANDLER Vector120 -#define STM32_DMA2_CH1_HANDLER Vector124 -#define STM32_DMA2_CH2_HANDLER Vector128 -#define STM32_DMA2_CH3_HANDLER Vector12C -#define STM32_DMA2_CH4_HANDLER Vector130 -#define STM32_DMA2_CH5_HANDLER Vector150 -#define STM32_DMA2_CH6_HANDLER Vector154 -#define STM32_DMA2_CH7_HANDLER Vector158 -#define STM32_DMA2_CH0_NUMBER 56 -#define STM32_DMA2_CH1_NUMBER 57 -#define STM32_DMA2_CH2_NUMBER 58 -#define STM32_DMA2_CH3_NUMBER 59 -#define STM32_DMA2_CH4_NUMBER 60 -#define STM32_DMA2_CH5_NUMBER 68 -#define STM32_DMA2_CH6_NUMBER 69 -#define STM32_DMA2_CH7_NUMBER 70 - -/* ETH attributes.*/ -#define STM32_HAS_ETH FALSE - -/* EXTI attributes.*/ -#define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR1_MASK 0x00000000U - -/* GPIO attributes.*/ -#define STM32_HAS_GPIOA TRUE -#define STM32_HAS_GPIOB TRUE -#define STM32_HAS_GPIOC TRUE -#define STM32_HAS_GPIOD TRUE -#define STM32_HAS_GPIOE TRUE -#define STM32_HAS_GPIOH TRUE -#define STM32_HAS_GPIOF TRUE -#define STM32_HAS_GPIOG TRUE -#define STM32_HAS_GPIOI FALSE -#define STM32_HAS_GPIOJ FALSE -#define STM32_HAS_GPIOK FALSE -#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ - RCC_AHB1ENR_GPIOBEN | \ - RCC_AHB1ENR_GPIOCEN | \ - RCC_AHB1ENR_GPIODEN | \ - RCC_AHB1ENR_GPIOEEN | \ - RCC_AHB1ENR_GPIOFEN | \ - RCC_AHB1ENR_GPIOGEN | \ - RCC_AHB1ENR_GPIOHEN) - -/* I2C attributes.*/ -#define STM32_HAS_I2C1 TRUE -#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ - STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_I2C1_RX_DMA_CHN 0x00100001 -#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ - STM32_DMA_STREAM_ID_MSK(1, 6)) -#define STM32_I2C1_TX_DMA_CHN 0x11000000 - -#define STM32_HAS_I2C2 TRUE -#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ - STM32_DMA_STREAM_ID_MSK(1, 3)) -#define STM32_I2C2_RX_DMA_CHN 0x00007700 -#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) -#define STM32_I2C2_TX_DMA_CHN 0x70000000 - -#define STM32_HAS_I2C3 TRUE -#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\ - STM32_DMA_STREAM_ID_MSK(1, 2)) -#define STM32_I2C3_RX_DMA_CHN 0x00000310 -#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\ - STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_I2C3_TX_DMA_CHN 0x00630000 - -#define STM32_HAS_I2C4 TRUE -#define STM32_I2C4_SUPPORTS_FMP TRUE -#define STM32_HAS_I2C4 TRUE -#define STM32_I2C4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) -#define STM32_I2C4_RX_DMA_CHN 0x00001000 -#define STM32_I2C4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) -#define STM32_I2C4_TX_DMA_CHN 0x00000020 - -/* QUADSPI attributes.*/ -#define STM32_HAS_QUADSPI1 TRUE -#define STM32_QUADSPI1_HANDLER Vector1B0 -#define STM32_QUADSPI1_NUMBER 92 -#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) -#define STM32_QUADSPI1_DMA_CHN 0x30000000 - -/* SDIO attributes.*/ -#define STM32_HAS_SDIO TRUE -#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 6)) -#define STM32_SDC_SDIO_DMA_CHN 0x04004000 - -/* SPI attributes.*/ -#define STM32_HAS_SPI1 TRUE -#define STM32_SPI1_SUPPORTS_I2S TRUE -#define STM32_SPI1_I2S_FULLDUPLEX TRUE -#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_SPI1_RX_DMA_CHN 0x00000303 -#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ - STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_SPI1_TX_DMA_CHN 0x00303200 - -#define STM32_HAS_SPI2 TRUE -#define STM32_SPI2_SUPPORTS_I2S TRUE -#define STM32_SPI2_I2S_FULLDUPLEX TRUE -#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) -#define STM32_SPI2_RX_DMA_CHN 0x00000000 -#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_SPI2_TX_DMA_CHN 0x00000000 - -#define STM32_HAS_SPI3 TRUE -#define STM32_SPI3_SUPPORTS_I2S TRUE -#define STM32_SPI3_I2S_FULLDUPLEX TRUE -#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ - STM32_DMA_STREAM_ID_MSK(1, 2)) -#define STM32_SPI3_RX_DMA_CHN 0x00000000 -#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ - STM32_DMA_STREAM_ID_MSK(1, 7)) -#define STM32_SPI3_TX_DMA_CHN 0x00000000 - -#define STM32_HAS_SPI4 TRUE -#define STM32_SPI4_SUPPORTS_I2S TRUE -#define STM32_SPI4_I2S_FULLDUPLEX TRUE -#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_SPI4_RX_DMA_CHN 0x00045004 -#define STM32_SPI4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_SPI4_TX_DMA_CHN 0x00050040 - -#define STM32_HAS_SPI5 TRUE -#define STM32_SPI5_SUPPORTS_I2S TRUE -#define STM32_SPI5_I2S_FULLDUPLEX TRUE -#define STM32_SPI5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_SPI5_RX_DMA_CHN 0x00702000 -#define STM32_SPI5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\ - STM32_DMA_STREAM_ID_MSK(2, 5) |\ - STM32_DMA_STREAM_ID_MSK(2, 6)) -#define STM32_SPI5_TX_DMA_CHN 0x07520000 - -#define STM32_HAS_SPI6 FALSE - -/* TIM attributes.*/ -#define STM32_TIM_MAX_CHANNELS 4 - -#define STM32_HAS_TIM1 TRUE -#define STM32_TIM1_IS_32BITS FALSE -#define STM32_TIM1_CHANNELS 4 - -#define STM32_HAS_TIM2 TRUE -#define STM32_TIM2_IS_32BITS TRUE -#define STM32_TIM2_CHANNELS 4 - -#define STM32_HAS_TIM3 TRUE -#define STM32_TIM3_IS_32BITS FALSE -#define STM32_TIM3_CHANNELS 4 - -#define STM32_HAS_TIM4 TRUE -#define STM32_TIM4_IS_32BITS FALSE -#define STM32_TIM4_CHANNELS 4 - -#define STM32_HAS_TIM5 TRUE -#define STM32_TIM5_IS_32BITS TRUE -#define STM32_TIM5_CHANNELS 4 - -#define STM32_HAS_TIM6 TRUE -#define STM32_TIM6_IS_32BITS FALSE -#define STM32_TIM6_CHANNELS 0 - -#define STM32_HAS_TIM7 TRUE -#define STM32_TIM7_IS_32BITS FALSE -#define STM32_TIM7_CHANNELS 0 - -#define STM32_HAS_TIM8 TRUE -#define STM32_TIM8_IS_32BITS FALSE -#define STM32_TIM8_CHANNELS 4 - -#define STM32_HAS_TIM9 TRUE -#define STM32_TIM9_IS_32BITS FALSE -#define STM32_TIM9_CHANNELS 2 - -#define STM32_HAS_TIM10 TRUE -#define STM32_TIM10_IS_32BITS FALSE -#define STM32_TIM10_CHANNELS 1 - -#define STM32_HAS_TIM11 TRUE -#define STM32_TIM11_IS_32BITS FALSE -#define STM32_TIM11_CHANNELS 1 - -#define STM32_HAS_TIM12 TRUE -#define STM32_TIM12_IS_32BITS FALSE -#define STM32_TIM12_CHANNELS 2 - -#define STM32_HAS_TIM13 TRUE -#define STM32_TIM13_IS_32BITS FALSE -#define STM32_TIM13_CHANNELS 1 - -#define STM32_HAS_TIM14 TRUE -#define STM32_TIM14_IS_32BITS FALSE -#define STM32_TIM14_CHANNELS 1 - -#define STM32_HAS_TIM15 FALSE -#define STM32_HAS_TIM16 FALSE -#define STM32_HAS_TIM17 FALSE -#define STM32_HAS_TIM18 FALSE -#define STM32_HAS_TIM19 FALSE -#define STM32_HAS_TIM20 FALSE -#define STM32_HAS_TIM21 FALSE -#define STM32_HAS_TIM22 FALSE - -#define STM32_HAS_LPTIM1 TRUE - -/* USART attributes.*/ -#define STM32_HAS_USART1 TRUE -#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_USART1_RX_DMA_CHN 0x00400400 -#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) -#define STM32_USART1_TX_DMA_CHN 0x40000000 - -#define STM32_HAS_USART2 TRUE -#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) -#define STM32_USART2_RX_DMA_CHN 0x00400000 -#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) -#define STM32_USART2_TX_DMA_CHN 0x04000000 - -#define STM32_HAS_USART3 TRUE -#define STM32_USART3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) -#define STM32_USART3_RX_DMA_CHN 0x00000040 -#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\ - STM32_DMA_STREAM_ID_MSK(1, 4)) -#define STM32_USART3_TX_DMA_CHN 0x00074000 - -#define STM32_HAS_UART4 TRUE -#define STM32_UART4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) -#define STM32_UART4_RX_DMA_CHN 0x00000400 -#define STM32_UART4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_UART4_TX_DMA_CHN 0x00040000 - -#define STM32_HAS_UART5 TRUE -#define STM32_UART5_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) -#define STM32_UART5_RX_DMA_CHN 0x00000004 -#define STM32_UART5_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) -#define STM32_UART5_TX_DMA_CHN 0x80000000 - -#define STM32_HAS_USART6 TRUE -#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_USART6_RX_DMA_CHN 0x00000550 -#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ - STM32_DMA_STREAM_ID_MSK(2, 7)) -#define STM32_USART6_TX_DMA_CHN 0x55000000 - -#define STM32_HAS_UART7 TRUE -#define STM32_UART7_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) -#define STM32_UART7_RX_DMA_CHN 0x00005000 -#define STM32_UART7_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) -#define STM32_UART7_TX_DMA_CHN 0x00000050 - -#define STM32_HAS_UART8 TRUE -#define STM32_UART8_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) -#define STM32_UART8_RX_DMA_CHN 0x05000000 -#define STM32_UART8_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) -#define STM32_UART8_TX_DMA_CHN 0x00000005 - -#define STM32_HAS_UART9 TRUE -#define STM32_UART9_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) -#define STM32_UART9_RX_DMA_CHN 0x00000000 -#define STM32_UART9_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 0) -#define STM32_UART9_TX_DMA_CHN 0x00000001 - -#define STM32_HAS_UART10 TRUE -#define STM32_UART10_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 0) -#define STM32_UART10_RX_DMA_CHN 0x00000005 -#define STM32_UART10_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) -#define STM32_UART10_TX_DMA_CHN 0x60000000 - -#define STM32_HAS_LPUART1 FALSE - -/* USB attributes.*/ -#define STM32_OTG_STEPPING 2 -#define STM32_HAS_OTG1 TRUE -#define STM32_OTG1_ENDPOINTS 5 - -#define STM32_HAS_OTG2 FALSE -#define STM32_HAS_USB FALSE - -/* IWDG attributes.*/ -#define STM32_HAS_IWDG TRUE -#define STM32_IWDG_IS_WINDOWED FALSE - -/* LTDC attributes.*/ -#define STM32_HAS_LTDC FALSE - -/* DMA2D attributes.*/ -#define STM32_HAS_DMA2D FALSE - -/* FSMC attributes.*/ -#define STM32_HAS_FSMC FALSE - -/* CRC attributes.*/ -#define STM32_HAS_CRC TRUE -#define STM32_CRC_PROGRAMMABLE FALSE - -#endif /* defined(STM32F413xx) */ - -/*===========================================================================*/ -/* STM32F412xx. */ -/*===========================================================================*/ - -#if defined(STM32F412xx) - -/* Clock tree attributes.*/ -#define STM32_HAS_RCC_PLLSAI FALSE -#define STM32_HAS_RCC_PLLI2S TRUE -#define STM32_HAS_RCC_DCKCFGR TRUE -#define STM32_HAS_RCC_DCKCFGR2 TRUE -#define STM32_HAS_RCC_I2SSRC FALSE -#define STM32_HAS_RCC_I2SPLLSRC TRUE -#define STM32_HAS_RCC_CK48MSEL TRUE -#define STM32_RCC_CK48MSEL_USES_I2S TRUE -#define STM32_PLL48CLK_ALTSRC STM32_PLLI2S_Q_CLKOUT -#define STM32_TIMPRE_PRESCALE4 FALSE - -/* ADC attributes.*/ -#define STM32_ADC_HANDLER Vector88 -#define STM32_ADC_NUMBER 18 - -#define STM32_HAS_ADC1 TRUE -#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_ADC1_DMA_CHN 0x00000000 - -#define STM32_HAS_ADC2 FALSE -#define STM32_HAS_ADC3 FALSE -#define STM32_HAS_ADC4 FALSE - -#define STM32_HAS_SDADC1 FALSE -#define STM32_HAS_SDADC2 FALSE -#define STM32_HAS_SDADC3 FALSE - -/* CAN attributes.*/ -#define STM32_HAS_CAN1 TRUE -#define STM32_HAS_CAN2 TRUE -#define STM32_HAS_CAN3 FALSE -#define STM32_CAN_MAX_FILTERS 28 - -/* DAC attributes.*/ -#define STM32_HAS_DAC1_CH1 FALSE -#define STM32_HAS_DAC1_CH2 FALSE -#define STM32_HAS_DAC2_CH1 FALSE -#define STM32_HAS_DAC2_CH2 FALSE - -/* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING FALSE -#define STM32_DMA_SUPPORTS_DMAMUX FALSE - -#define STM32_HAS_DMA1 TRUE -#define STM32_DMA1_CH0_HANDLER Vector6C -#define STM32_DMA1_CH1_HANDLER Vector70 -#define STM32_DMA1_CH2_HANDLER Vector74 -#define STM32_DMA1_CH3_HANDLER Vector78 -#define STM32_DMA1_CH4_HANDLER Vector7C -#define STM32_DMA1_CH5_HANDLER Vector80 -#define STM32_DMA1_CH6_HANDLER Vector84 -#define STM32_DMA1_CH7_HANDLER VectorFC -#define STM32_DMA1_CH0_NUMBER 11 -#define STM32_DMA1_CH1_NUMBER 12 -#define STM32_DMA1_CH2_NUMBER 13 -#define STM32_DMA1_CH3_NUMBER 14 -#define STM32_DMA1_CH4_NUMBER 15 -#define STM32_DMA1_CH5_NUMBER 16 -#define STM32_DMA1_CH6_NUMBER 17 -#define STM32_DMA1_CH7_NUMBER 47 - -#define STM32_HAS_DMA2 TRUE -#define STM32_DMA2_CH0_HANDLER Vector120 -#define STM32_DMA2_CH1_HANDLER Vector124 -#define STM32_DMA2_CH2_HANDLER Vector128 -#define STM32_DMA2_CH3_HANDLER Vector12C -#define STM32_DMA2_CH4_HANDLER Vector130 -#define STM32_DMA2_CH5_HANDLER Vector150 -#define STM32_DMA2_CH6_HANDLER Vector154 -#define STM32_DMA2_CH7_HANDLER Vector158 -#define STM32_DMA2_CH0_NUMBER 56 -#define STM32_DMA2_CH1_NUMBER 57 -#define STM32_DMA2_CH2_NUMBER 58 -#define STM32_DMA2_CH3_NUMBER 59 -#define STM32_DMA2_CH4_NUMBER 60 -#define STM32_DMA2_CH5_NUMBER 68 -#define STM32_DMA2_CH6_NUMBER 69 -#define STM32_DMA2_CH7_NUMBER 70 - -/* ETH attributes.*/ -#define STM32_HAS_ETH FALSE - -/* EXTI attributes.*/ -#define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR1_MASK 0x00000000U - -/* GPIO attributes.*/ -#define STM32_HAS_GPIOA TRUE -#define STM32_HAS_GPIOB TRUE -#define STM32_HAS_GPIOC TRUE -#define STM32_HAS_GPIOD TRUE -#define STM32_HAS_GPIOE TRUE -#define STM32_HAS_GPIOH TRUE -#define STM32_HAS_GPIOF TRUE -#define STM32_HAS_GPIOG TRUE -#define STM32_HAS_GPIOI FALSE -#define STM32_HAS_GPIOJ FALSE -#define STM32_HAS_GPIOK FALSE -#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ - RCC_AHB1ENR_GPIOBEN | \ - RCC_AHB1ENR_GPIOCEN | \ - RCC_AHB1ENR_GPIODEN | \ - RCC_AHB1ENR_GPIOEEN | \ - RCC_AHB1ENR_GPIOFEN | \ - RCC_AHB1ENR_GPIOGEN | \ - RCC_AHB1ENR_GPIOHEN) - -/* I2C attributes.*/ -#define STM32_HAS_I2C1 TRUE -#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ - STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_I2C1_RX_DMA_CHN 0x00100001 -#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ - STM32_DMA_STREAM_ID_MSK(1, 6)) -#define STM32_I2C1_TX_DMA_CHN 0x11000000 - -#define STM32_HAS_I2C2 TRUE -#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ - STM32_DMA_STREAM_ID_MSK(1, 3)) -#define STM32_I2C2_RX_DMA_CHN 0x00007700 -#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) -#define STM32_I2C2_TX_DMA_CHN 0x70000000 - -#define STM32_HAS_I2C3 TRUE -#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\ - STM32_DMA_STREAM_ID_MSK(1, 2)) -#define STM32_I2C3_RX_DMA_CHN 0x00000310 -#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\ - STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_I2C3_TX_DMA_CHN 0x00630000 - -#define STM32_HAS_I2C4 FALSE - -/* QUADSPI attributes.*/ -#define STM32_HAS_QUADSPI1 TRUE -#define STM32_QUADSPI1_HANDLER Vector1B0 -#define STM32_QUADSPI1_NUMBER 92 -#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) -#define STM32_QUADSPI1_DMA_CHN 0x30000000 - -/* SDIO attributes.*/ -#define STM32_HAS_SDIO TRUE -#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 6)) -#define STM32_SDC_SDIO_DMA_CHN 0x04004000 - -/* SPI attributes.*/ -#define STM32_HAS_SPI1 TRUE -#define STM32_SPI1_SUPPORTS_I2S TRUE -#define STM32_SPI1_I2S_FULLDUPLEX TRUE -#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_SPI1_RX_DMA_CHN 0x00000303 -#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_SPI1_TX_DMA_CHN 0x00303000 - -#define STM32_HAS_SPI2 TRUE -#define STM32_SPI2_SUPPORTS_I2S TRUE -#define STM32_SPI2_I2S_FULLDUPLEX TRUE -#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) -#define STM32_SPI2_RX_DMA_CHN 0x00000000 -#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_SPI2_TX_DMA_CHN 0x00000000 - -#define STM32_HAS_SPI3 TRUE -#define STM32_SPI3_SUPPORTS_I2S TRUE -#define STM32_SPI3_I2S_FULLDUPLEX TRUE -#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ - STM32_DMA_STREAM_ID_MSK(1, 2)) -#define STM32_SPI3_RX_DMA_CHN 0x00000000 -#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ - STM32_DMA_STREAM_ID_MSK(1, 7)) -#define STM32_SPI3_TX_DMA_CHN 0x00000000 - -#define STM32_HAS_SPI4 TRUE -#define STM32_SPI4_SUPPORTS_I2S TRUE -#define STM32_SPI4_I2S_FULLDUPLEX TRUE -#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_SPI4_RX_DMA_CHN 0x00045004 -#define STM32_SPI4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_SPI4_TX_DMA_CHN 0x00050040 - -#define STM32_HAS_SPI5 TRUE -#define STM32_SPI5_SUPPORTS_I2S TRUE -#define STM32_SPI5_I2S_FULLDUPLEX TRUE -#define STM32_SPI5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_SPI5_RX_DMA_CHN 0x00702000 -#define STM32_SPI5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\ - STM32_DMA_STREAM_ID_MSK(2, 5) |\ - STM32_DMA_STREAM_ID_MSK(2, 6)) -#define STM32_SPI5_TX_DMA_CHN 0x07520000 - -#define STM32_HAS_SPI6 FALSE - -/* TIM attributes.*/ -#define STM32_TIM_MAX_CHANNELS 4 - -#define STM32_HAS_TIM1 TRUE -#define STM32_TIM1_IS_32BITS FALSE -#define STM32_TIM1_CHANNELS 4 - -#define STM32_HAS_TIM2 TRUE -#define STM32_TIM2_IS_32BITS TRUE -#define STM32_TIM2_CHANNELS 4 - -#define STM32_HAS_TIM3 TRUE -#define STM32_TIM3_IS_32BITS FALSE -#define STM32_TIM3_CHANNELS 4 - -#define STM32_HAS_TIM4 TRUE -#define STM32_TIM4_IS_32BITS FALSE -#define STM32_TIM4_CHANNELS 4 - -#define STM32_HAS_TIM5 TRUE -#define STM32_TIM5_IS_32BITS TRUE -#define STM32_TIM5_CHANNELS 4 - -#define STM32_HAS_TIM6 TRUE -#define STM32_TIM6_IS_32BITS FALSE -#define STM32_TIM6_CHANNELS 0 - -#define STM32_HAS_TIM7 TRUE -#define STM32_TIM7_IS_32BITS FALSE -#define STM32_TIM7_CHANNELS 0 - -#define STM32_HAS_TIM9 TRUE -#define STM32_TIM9_IS_32BITS FALSE -#define STM32_TIM9_CHANNELS 2 - -#define STM32_HAS_TIM10 TRUE -#define STM32_TIM10_IS_32BITS FALSE -#define STM32_TIM10_CHANNELS 1 - -#define STM32_HAS_TIM11 TRUE -#define STM32_TIM11_IS_32BITS FALSE -#define STM32_TIM11_CHANNELS 1 - -#define STM32_HAS_TIM12 TRUE -#define STM32_TIM12_IS_32BITS FALSE -#define STM32_TIM12_CHANNELS 2 - -#define STM32_HAS_TIM13 TRUE -#define STM32_TIM13_IS_32BITS FALSE -#define STM32_TIM13_CHANNELS 1 - -#define STM32_HAS_TIM14 TRUE -#define STM32_TIM14_IS_32BITS FALSE -#define STM32_TIM14_CHANNELS 1 - -#define STM32_HAS_TIM8 FALSE -#define STM32_HAS_TIM15 FALSE -#define STM32_HAS_TIM16 FALSE -#define STM32_HAS_TIM17 FALSE -#define STM32_HAS_TIM18 FALSE -#define STM32_HAS_TIM19 FALSE -#define STM32_HAS_TIM20 FALSE -#define STM32_HAS_TIM21 FALSE -#define STM32_HAS_TIM22 FALSE - -/* USART attributes.*/ -#define STM32_HAS_USART1 TRUE -#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_USART1_RX_DMA_CHN 0x00400400 -#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) -#define STM32_USART1_TX_DMA_CHN 0x40000000 - -#define STM32_HAS_USART2 TRUE -#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) -#define STM32_USART2_RX_DMA_CHN 0x00400000 -#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) -#define STM32_USART2_TX_DMA_CHN 0x04000000 - -#define STM32_HAS_USART3 TRUE -#define STM32_USART3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) -#define STM32_USART3_RX_DMA_CHN 0x00000040 -#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\ - STM32_DMA_STREAM_ID_MSK(1, 4)) -#define STM32_USART3_TX_DMA_CHN 0x00074000 - -#define STM32_HAS_USART6 TRUE -#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_USART6_RX_DMA_CHN 0x00000550 -#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ - STM32_DMA_STREAM_ID_MSK(2, 7)) -#define STM32_USART6_TX_DMA_CHN 0x55000000 - -#define STM32_HAS_UART4 FALSE -#define STM32_HAS_UART5 FALSE -#define STM32_HAS_UART7 FALSE -#define STM32_HAS_UART8 FALSE -#define STM32_HAS_LPUART1 FALSE - -/* USB attributes.*/ -#define STM32_OTG_STEPPING 2 -#define STM32_HAS_OTG1 TRUE -#define STM32_OTG1_ENDPOINTS 5 - -#define STM32_HAS_OTG2 FALSE -#define STM32_HAS_USB FALSE - -/* IWDG attributes.*/ -#define STM32_HAS_IWDG TRUE -#define STM32_IWDG_IS_WINDOWED FALSE - -/* LTDC attributes.*/ -#define STM32_HAS_LTDC FALSE - -/* DMA2D attributes.*/ -#define STM32_HAS_DMA2D FALSE - -/* FSMC attributes.*/ -#define STM32_HAS_FSMC FALSE - -/* CRC attributes.*/ -#define STM32_HAS_CRC TRUE -#define STM32_CRC_PROGRAMMABLE FALSE - -#endif /* defined(STM32F412xx) */ - -/*===========================================================================*/ -/* STM32F411xx. */ -/*===========================================================================*/ - -#if defined(STM32F411xx) - -/* Clock tree attributes.*/ -#define STM32_HAS_RCC_PLLSAI FALSE -#define STM32_HAS_RCC_PLLI2S TRUE -#define STM32_HAS_RCC_DCKCFGR TRUE -#define STM32_HAS_RCC_DCKCFGR2 FALSE -#define STM32_HAS_RCC_I2SSRC TRUE -#define STM32_HAS_RCC_I2SPLLSRC FALSE -#define STM32_HAS_RCC_CK48MSEL FALSE -#define STM32_RCC_CK48MSEL_USES_I2S FALSE -#define STM32_PLL48CLK_ALTSRC STM32_PLLSAI_Q_CLKOUT -#define STM32_TIMPRE_PRESCALE4 FALSE - -/* ADC attributes.*/ -#define STM32_ADC_HANDLER Vector88 -#define STM32_ADC_NUMBER 18 - -#define STM32_HAS_ADC1 TRUE -#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_ADC1_DMA_CHN 0x00000000 - -#define STM32_HAS_ADC2 FALSE -#define STM32_HAS_ADC3 FALSE -#define STM32_HAS_ADC4 FALSE - -#define STM32_HAS_SDADC1 FALSE -#define STM32_HAS_SDADC2 FALSE -#define STM32_HAS_SDADC3 FALSE - -/* CAN attributes.*/ -#define STM32_HAS_CAN1 FALSE -#define STM32_HAS_CAN2 FALSE -#define STM32_HAS_CAN3 FALSE - -/* DAC attributes.*/ -#define STM32_HAS_DAC1_CH1 FALSE -#define STM32_HAS_DAC1_CH2 FALSE -#define STM32_HAS_DAC2_CH1 FALSE -#define STM32_HAS_DAC2_CH2 FALSE - -/* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING FALSE -#define STM32_DMA_SUPPORTS_DMAMUX FALSE - -#define STM32_HAS_DMA1 TRUE -#define STM32_DMA1_CH0_HANDLER Vector6C -#define STM32_DMA1_CH1_HANDLER Vector70 -#define STM32_DMA1_CH2_HANDLER Vector74 -#define STM32_DMA1_CH3_HANDLER Vector78 -#define STM32_DMA1_CH4_HANDLER Vector7C -#define STM32_DMA1_CH5_HANDLER Vector80 -#define STM32_DMA1_CH6_HANDLER Vector84 -#define STM32_DMA1_CH7_HANDLER VectorFC -#define STM32_DMA1_CH0_NUMBER 11 -#define STM32_DMA1_CH1_NUMBER 12 -#define STM32_DMA1_CH2_NUMBER 13 -#define STM32_DMA1_CH3_NUMBER 14 -#define STM32_DMA1_CH4_NUMBER 15 -#define STM32_DMA1_CH5_NUMBER 16 -#define STM32_DMA1_CH6_NUMBER 17 -#define STM32_DMA1_CH7_NUMBER 47 - -#define STM32_HAS_DMA2 TRUE -#define STM32_DMA2_CH0_HANDLER Vector120 -#define STM32_DMA2_CH1_HANDLER Vector124 -#define STM32_DMA2_CH2_HANDLER Vector128 -#define STM32_DMA2_CH3_HANDLER Vector12C -#define STM32_DMA2_CH4_HANDLER Vector130 -#define STM32_DMA2_CH5_HANDLER Vector150 -#define STM32_DMA2_CH6_HANDLER Vector154 -#define STM32_DMA2_CH7_HANDLER Vector158 -#define STM32_DMA2_CH0_NUMBER 56 -#define STM32_DMA2_CH1_NUMBER 57 -#define STM32_DMA2_CH2_NUMBER 58 -#define STM32_DMA2_CH3_NUMBER 59 -#define STM32_DMA2_CH4_NUMBER 60 -#define STM32_DMA2_CH5_NUMBER 68 -#define STM32_DMA2_CH6_NUMBER 69 -#define STM32_DMA2_CH7_NUMBER 70 - -/* ETH attributes.*/ -#define STM32_HAS_ETH FALSE - -/* EXTI attributes.*/ -#define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR1_MASK 0x00000000U - -/* GPIO attributes.*/ -#define STM32_HAS_GPIOA TRUE -#define STM32_HAS_GPIOB TRUE -#define STM32_HAS_GPIOC TRUE -#define STM32_HAS_GPIOD TRUE -#define STM32_HAS_GPIOE TRUE -#define STM32_HAS_GPIOH TRUE -#define STM32_HAS_GPIOF FALSE -#define STM32_HAS_GPIOG FALSE -#define STM32_HAS_GPIOI FALSE -#define STM32_HAS_GPIOJ FALSE -#define STM32_HAS_GPIOK FALSE -#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ - RCC_AHB1ENR_GPIOBEN | \ - RCC_AHB1ENR_GPIOCEN | \ - RCC_AHB1ENR_GPIODEN | \ - RCC_AHB1ENR_GPIOEEN | \ - RCC_AHB1ENR_GPIOHEN) - -/* I2C attributes.*/ -#define STM32_HAS_I2C1 TRUE -#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ - STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_I2C1_RX_DMA_CHN 0x00100001 -#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ - STM32_DMA_STREAM_ID_MSK(1, 6) |\ - STM32_DMA_STREAM_ID_MSK(1, 1)) -#define STM32_I2C1_TX_DMA_CHN 0x11000000 - -#define STM32_HAS_I2C2 TRUE -#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ - STM32_DMA_STREAM_ID_MSK(1, 3)) -#define STM32_I2C2_RX_DMA_CHN 0x00007700 -#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) -#define STM32_I2C2_TX_DMA_CHN 0x70000000 - -#define STM32_HAS_I2C3 TRUE -#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\ -+ STM32_DMA_STREAM_ID_MSK(1, 2)) -#define STM32_I2C3_RX_DMA_CHN 0x00000310 -#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\ -+ STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_I2C3_TX_DMA_CHN 0x00630000 - -#define STM32_HAS_I2C4 FALSE - -/* QUADSPI attributes.*/ -#define STM32_HAS_QUADSPI1 FALSE - -/* SDIO attributes.*/ -#define STM32_HAS_SDIO TRUE -#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 6)) -#define STM32_SDC_SDIO_DMA_CHN 0x04004000 - -/* SPI attributes.*/ -#define STM32_HAS_SPI1 TRUE -#define STM32_SPI1_SUPPORTS_I2S TRUE -#define STM32_SPI1_I2S_FULLDUPLEX TRUE -#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_SPI1_RX_DMA_CHN 0x00000303 -#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_SPI1_TX_DMA_CHN 0x00303000 - -#define STM32_HAS_SPI2 TRUE -#define STM32_SPI2_SUPPORTS_I2S TRUE -#define STM32_SPI2_I2S_FULLDUPLEX TRUE -#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) -#define STM32_SPI2_RX_DMA_CHN 0x00000000 -#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_SPI2_TX_DMA_CHN 0x00000000 - -#define STM32_HAS_SPI3 TRUE -#define STM32_SPI3_SUPPORTS_I2S TRUE -#define STM32_SPI3_I2S_FULLDUPLEX TRUE -#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ - STM32_DMA_STREAM_ID_MSK(1, 2)) -#define STM32_SPI3_RX_DMA_CHN 0x00000000 -#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ - STM32_DMA_STREAM_ID_MSK(1, 7)) -#define STM32_SPI3_TX_DMA_CHN 0x00000000 - -#define STM32_HAS_SPI4 TRUE -#define STM32_SPI4_SUPPORTS_I2S TRUE -#define STM32_SPI4_I2S_FULLDUPLEX TRUE -#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 3)) -#define STM32_SPI4_RX_DMA_CHN 0x00005004 -#define STM32_SPI4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_SPI4_TX_DMA_CHN 0x00050040 - -#define STM32_HAS_SPI5 TRUE -#define STM32_SPI5_SUPPORTS_I2S TRUE -#define STM32_SPI5_I2S_FULLDUPLEX TRUE -#define STM32_SPI5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_SPI5_RX_DMA_CHN 0x00702000 -#define STM32_SPI5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\ - STM32_DMA_STREAM_ID_MSK(2, 6)) -#define STM32_SPI5_TX_DMA_CHN 0x07020000 - -#define STM32_HAS_SPI6 FALSE - -/* TIM attributes.*/ -#define STM32_TIM_MAX_CHANNELS 4 - -#define STM32_HAS_TIM1 TRUE -#define STM32_TIM1_IS_32BITS FALSE -#define STM32_TIM1_CHANNELS 4 - -#define STM32_HAS_TIM2 TRUE -#define STM32_TIM2_IS_32BITS TRUE -#define STM32_TIM2_CHANNELS 4 - -#define STM32_HAS_TIM3 TRUE -#define STM32_TIM3_IS_32BITS FALSE -#define STM32_TIM3_CHANNELS 4 - -#define STM32_HAS_TIM4 TRUE -#define STM32_TIM4_IS_32BITS FALSE -#define STM32_TIM4_CHANNELS 4 - -#define STM32_HAS_TIM5 TRUE -#define STM32_TIM5_IS_32BITS TRUE -#define STM32_TIM5_CHANNELS 4 - -#define STM32_HAS_TIM9 TRUE -#define STM32_TIM9_IS_32BITS FALSE -#define STM32_TIM9_CHANNELS 2 - -#define STM32_HAS_TIM10 TRUE -#define STM32_TIM10_IS_32BITS FALSE -#define STM32_TIM10_CHANNELS 1 - -#define STM32_HAS_TIM11 TRUE -#define STM32_TIM11_IS_32BITS FALSE -#define STM32_TIM11_CHANNELS 1 - -#define STM32_HAS_TIM6 FALSE -#define STM32_HAS_TIM7 FALSE -#define STM32_HAS_TIM8 FALSE -#define STM32_HAS_TIM12 FALSE -#define STM32_HAS_TIM13 FALSE -#define STM32_HAS_TIM14 FALSE -#define STM32_HAS_TIM15 FALSE -#define STM32_HAS_TIM16 FALSE -#define STM32_HAS_TIM17 FALSE -#define STM32_HAS_TIM18 FALSE -#define STM32_HAS_TIM19 FALSE -#define STM32_HAS_TIM20 FALSE -#define STM32_HAS_TIM21 FALSE -#define STM32_HAS_TIM22 FALSE - -/* USART attributes.*/ -#define STM32_HAS_USART1 TRUE -#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_USART1_RX_DMA_CHN 0x00400400 -#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) -#define STM32_USART1_TX_DMA_CHN 0x40000000 - -#define STM32_HAS_USART2 TRUE -#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) -#define STM32_USART2_RX_DMA_CHN 0x00400000 -#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) -#define STM32_USART2_TX_DMA_CHN 0x04000000 - -#define STM32_HAS_USART3 FALSE -#define STM32_HAS_UART4 FALSE -#define STM32_HAS_UART5 FALSE - -#define STM32_HAS_USART6 TRUE -#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_USART6_RX_DMA_CHN 0x00000550 -#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ - STM32_DMA_STREAM_ID_MSK(2, 7)) -#define STM32_USART6_TX_DMA_CHN 0x55000000 - -#define STM32_HAS_UART7 FALSE -#define STM32_HAS_UART8 FALSE -#define STM32_HAS_LPUART1 FALSE - -/* USB attributes.*/ -#define STM32_OTG_STEPPING 1 -#define STM32_HAS_OTG1 TRUE -#define STM32_OTG1_ENDPOINTS 3 - -#define STM32_HAS_OTG2 FALSE -#define STM32_HAS_USB FALSE - -/* IWDG attributes.*/ -#define STM32_HAS_IWDG TRUE -#define STM32_IWDG_IS_WINDOWED FALSE - -/* LTDC attributes.*/ -#define STM32_HAS_LTDC FALSE - -/* DMA2D attributes.*/ -#define STM32_HAS_DMA2D FALSE - -/* FSMC attributes.*/ -#define STM32_HAS_FSMC FALSE - -/* CRC attributes.*/ -#define STM32_HAS_CRC TRUE -#define STM32_CRC_PROGRAMMABLE FALSE - -#endif /* defined(STM32F411xx) */ - -/*===========================================================================*/ -/* STM32F410xx. */ -/*===========================================================================*/ - -#if defined(STM32F410xx) - -/* Clock tree attributes.*/ -#define STM32_HAS_RCC_PLLSAI FALSE -#define STM32_HAS_RCC_PLLI2S FALSE -#define STM32_HAS_RCC_DCKCFGR TRUE -#define STM32_HAS_RCC_DCKCFGR2 TRUE -#define STM32_HAS_RCC_I2SSRC FALSE -#define STM32_HAS_RCC_I2SPLLSRC FALSE -#define STM32_HAS_RCC_CK48MSEL FALSE -#define STM32_RCC_CK48MSEL_USES_I2S FALSE -#define STM32_PLL48CLK_ALTSRC STM32_PLLSAI_Q_CLKOUT -#define STM32_TIMPRE_PRESCALE4 FALSE - -/* ADC attributes.*/ -#define STM32_ADC_HANDLER Vector88 -#define STM32_ADC_NUMBER 18 - -#define STM32_HAS_ADC1 TRUE -#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_ADC1_DMA_CHN 0x00000000 - -#define STM32_HAS_ADC2 FALSE -#define STM32_HAS_ADC3 FALSE -#define STM32_HAS_ADC4 FALSE - -#define STM32_HAS_SDADC1 FALSE -#define STM32_HAS_SDADC2 FALSE -#define STM32_HAS_SDADC3 FALSE - -/* CAN attributes.*/ -#define STM32_HAS_CAN1 FALSE -#define STM32_HAS_CAN2 FALSE -#define STM32_HAS_CAN3 FALSE - -/* DAC attributes.*/ -#define STM32_HAS_DAC1_CH1 TRUE -#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_DAC1_CH1_DMA_CHN 0x00700000 - -#define STM32_HAS_DAC1_CH2 FALSE -#define STM32_HAS_DAC2_CH1 FALSE -#define STM32_HAS_DAC2_CH2 FALSE - -/* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING FALSE -#define STM32_DMA_SUPPORTS_DMAMUX FALSE - -#define STM32_HAS_DMA1 TRUE -#define STM32_DMA1_CH0_HANDLER Vector6C -#define STM32_DMA1_CH1_HANDLER Vector70 -#define STM32_DMA1_CH2_HANDLER Vector74 -#define STM32_DMA1_CH3_HANDLER Vector78 -#define STM32_DMA1_CH4_HANDLER Vector7C -#define STM32_DMA1_CH5_HANDLER Vector80 -#define STM32_DMA1_CH6_HANDLER Vector84 -#define STM32_DMA1_CH7_HANDLER VectorFC -#define STM32_DMA1_CH0_NUMBER 11 -#define STM32_DMA1_CH1_NUMBER 12 -#define STM32_DMA1_CH2_NUMBER 13 -#define STM32_DMA1_CH3_NUMBER 14 -#define STM32_DMA1_CH4_NUMBER 15 -#define STM32_DMA1_CH5_NUMBER 16 -#define STM32_DMA1_CH6_NUMBER 17 -#define STM32_DMA1_CH7_NUMBER 47 - -#define STM32_HAS_DMA2 TRUE -#define STM32_DMA2_CH0_HANDLER Vector120 -#define STM32_DMA2_CH1_HANDLER Vector124 -#define STM32_DMA2_CH2_HANDLER Vector128 -#define STM32_DMA2_CH3_HANDLER Vector12C -#define STM32_DMA2_CH4_HANDLER Vector130 -#define STM32_DMA2_CH5_HANDLER Vector150 -#define STM32_DMA2_CH6_HANDLER Vector154 -#define STM32_DMA2_CH7_HANDLER Vector158 -#define STM32_DMA2_CH0_NUMBER 56 -#define STM32_DMA2_CH1_NUMBER 57 -#define STM32_DMA2_CH2_NUMBER 58 -#define STM32_DMA2_CH3_NUMBER 59 -#define STM32_DMA2_CH4_NUMBER 60 -#define STM32_DMA2_CH5_NUMBER 68 -#define STM32_DMA2_CH6_NUMBER 69 -#define STM32_DMA2_CH7_NUMBER 70 - -/* ETH attributes.*/ -#define STM32_HAS_ETH FALSE - -/* EXTI attributes.*/ -#define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR1_MASK 0x00000000U - -/* GPIO attributes.*/ -#define STM32_HAS_GPIOA TRUE -#define STM32_HAS_GPIOB TRUE -#define STM32_HAS_GPIOC TRUE -#define STM32_HAS_GPIOD FALSE -#define STM32_HAS_GPIOE FALSE -#define STM32_HAS_GPIOH TRUE -#define STM32_HAS_GPIOF FALSE -#define STM32_HAS_GPIOG FALSE -#define STM32_HAS_GPIOI FALSE -#define STM32_HAS_GPIOJ FALSE -#define STM32_HAS_GPIOK FALSE -#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ - RCC_AHB1ENR_GPIOBEN | \ - RCC_AHB1ENR_GPIOCEN | \ - RCC_AHB1ENR_GPIOHEN) - -/* I2C attributes.*/ -#define STM32_HAS_I2C1 TRUE -#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ - STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_I2C1_RX_DMA_CHN 0x00100001 -#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ - STM32_DMA_STREAM_ID_MSK(1, 6)) -#define STM32_I2C1_TX_DMA_CHN 0x11000000 - -#define STM32_HAS_I2C2 TRUE -#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ - STM32_DMA_STREAM_ID_MSK(1, 3)) -#define STM32_I2C2_RX_DMA_CHN 0x00007700 -#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) -#define STM32_I2C2_TX_DMA_CHN 0x70000000 - -#define STM32_HAS_I2C3 FALSE - -#define STM32_HAS_I2C4 TRUE -#define STM32_I2C4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0)) |\ - STM32_DMA_STREAM_ID_MSK(1, 3)) -#define STM32_I2C4_RX_DMA_CHN 0x00002007 -#define STM32_I2C4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) |\ - STM32_DMA_STREAM_ID_MSK(1, 1)) -#define STM32_I2C4_TX_DMA_CHN 0x00040020 - -/* QUADSPI attributes.*/ -#define STM32_HAS_QUADSPI1 FALSE - -/* SDIO attributes.*/ -#define STM32_HAS_SDIO FALSE - -/* SPI attributes.*/ -#define STM32_HAS_SPI1 TRUE -#define STM32_SPI1_SUPPORTS_I2S TRUE -#define STM32_SPI1_I2S_FULLDUPLEX TRUE -#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_SPI1_RX_DMA_CHN 0x00000303 -#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ - STM32_DMA_STREAM_ID_MSK(2, 3)) -#define STM32_SPI1_TX_DMA_CHN 0x00003200 - -#define STM32_HAS_SPI2 TRUE -#define STM32_SPI2_SUPPORTS_I2S TRUE -#define STM32_SPI2_I2S_FULLDUPLEX TRUE -#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) -#define STM32_SPI2_RX_DMA_CHN 0x00000000 -#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_SPI2_TX_DMA_CHN 0x00000000 - -#define STM32_HAS_SPI5 TRUE -#define STM32_SPI5_SUPPORTS_I2S TRUE -#define STM32_SPI5_I2S_FULLDUPLEX TRUE -#define STM32_SPI5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_SPI5_RX_DMA_CHN 0x00702000 -#define STM32_SPI5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\ - STM32_DMA_STREAM_ID_MSK(2, 6)) -#define STM32_SPI5_TX_DMA_CHN 0x07020000 - -#define STM32_HAS_SPI3 FALSE -#define STM32_HAS_SPI4 FALSE -#define STM32_HAS_SPI6 FALSE - -/* TIM attributes.*/ -#define STM32_TIM_MAX_CHANNELS 4 - -#define STM32_HAS_TIM1 TRUE -#define STM32_TIM1_IS_32BITS FALSE -#define STM32_TIM1_CHANNELS 4 - -#define STM32_HAS_TIM5 TRUE -#define STM32_TIM5_IS_32BITS TRUE -#define STM32_TIM5_CHANNELS 4 - -#define STM32_HAS_TIM6 TRUE -#define STM32_TIM6_IS_32BITS FALSE -#define STM32_TIM6_CHANNELS 0 - -#define STM32_HAS_TIM9 TRUE -#define STM32_TIM9_IS_32BITS FALSE -#define STM32_TIM9_CHANNELS 2 - -#define STM32_HAS_TIM11 TRUE -#define STM32_TIM11_IS_32BITS FALSE -#define STM32_TIM11_CHANNELS 1 - -#define STM32_HAS_TIM2 FALSE -#define STM32_HAS_TIM3 FALSE -#define STM32_HAS_TIM4 FALSE -#define STM32_HAS_TIM7 FALSE -#define STM32_HAS_TIM8 FALSE -#define STM32_HAS_TIM10 FALSE -#define STM32_HAS_TIM12 FALSE -#define STM32_HAS_TIM13 FALSE -#define STM32_HAS_TIM14 FALSE -#define STM32_HAS_TIM15 FALSE -#define STM32_HAS_TIM16 FALSE -#define STM32_HAS_TIM17 FALSE -#define STM32_HAS_TIM18 FALSE -#define STM32_HAS_TIM19 FALSE -#define STM32_HAS_TIM20 FALSE -#define STM32_HAS_TIM21 FALSE -#define STM32_HAS_TIM22 FALSE - -/* USART attributes.*/ -#define STM32_HAS_USART1 TRUE -#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_USART1_RX_DMA_CHN 0x00400400 -#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) -#define STM32_USART1_TX_DMA_CHN 0x40000000 - -#define STM32_HAS_USART2 TRUE -#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ - STM32_DMA_STREAM_ID_MSK(1, 7)) -#define STM32_USART2_RX_DMA_CHN 0x60400000 -#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) -#define STM32_USART2_TX_DMA_CHN 0x04000000 - -#define STM32_HAS_USART3 FALSE -#define STM32_HAS_UART4 FALSE -#define STM32_HAS_UART5 FALSE - -#define STM32_HAS_USART6 TRUE -#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_USART6_RX_DMA_CHN 0x00000550 -#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ - STM32_DMA_STREAM_ID_MSK(2, 7)) -#define STM32_USART6_TX_DMA_CHN 0x55000000 - -#define STM32_HAS_UART7 FALSE -#define STM32_HAS_UART8 FALSE -#define STM32_HAS_LPUART1 FALSE - -/* USB attributes.*/ -#define STM32_HAS_USB FALSE -#define STM32_HAS_OTG1 FALSE -#define STM32_HAS_OTG2 FALSE - -/* IWDG attributes.*/ -#define STM32_HAS_IWDG TRUE -#define STM32_IWDG_IS_WINDOWED FALSE - -/* LTDC attributes.*/ -#define STM32_HAS_LTDC FALSE - -/* DMA2D attributes.*/ -#define STM32_HAS_DMA2D FALSE - -/* FSMC attributes.*/ -#define STM32_HAS_FSMC FALSE - -/* CRC attributes.*/ -#define STM32_HAS_CRC TRUE -#define STM32_CRC_PROGRAMMABLE FALSE - -#endif /* defined(STM32F410xx) */ - -/*===========================================================================*/ -/* STM32F405xx, STM32F415xx, STM32F407xx, STM32F417xx, STM32F205xx, */ -/* STM32F215xx, STM32F207xx, STM32F217xx. */ -/*===========================================================================*/ - -#if defined(STM32F40_41xxx) || defined(STM32F2XX) - -/* Clock tree attributes.*/ -#define STM32_HAS_RCC_PLLSAI FALSE -#define STM32_HAS_RCC_PLLI2S TRUE -#define STM32_HAS_RCC_DCKCFGR FALSE -#define STM32_HAS_RCC_DCKCFGR2 FALSE -#define STM32_HAS_RCC_I2SSRC TRUE -#define STM32_HAS_RCC_I2SPLLSRC FALSE -#define STM32_HAS_RCC_CK48MSEL FALSE -#define STM32_RCC_CK48MSEL_USES_I2S FALSE -#define STM32_TIMPRE_PRESCALE4 TRUE - -/* ADC attributes.*/ -#define STM32_ADC_HANDLER Vector88 -#define STM32_ADC_NUMBER 18 - -#define STM32_HAS_ADC1 TRUE -#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_ADC1_DMA_CHN 0x00000000 - -#define STM32_HAS_ADC2 TRUE -#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ - STM32_DMA_STREAM_ID_MSK(2, 3)) -#define STM32_ADC2_DMA_CHN 0x00001100 - -#define STM32_HAS_ADC3 TRUE -#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 1)) -#define STM32_ADC3_DMA_CHN 0x00000022 - -#define STM32_HAS_ADC4 FALSE - -#define STM32_HAS_SDADC1 FALSE -#define STM32_HAS_SDADC2 FALSE -#define STM32_HAS_SDADC3 FALSE - -/* CAN attributes.*/ -#define STM32_HAS_CAN1 TRUE -#define STM32_HAS_CAN2 TRUE -#define STM32_HAS_CAN3 FALSE -#define STM32_CAN_MAX_FILTERS 28 - -/* DAC attributes.*/ -#define STM32_HAS_DAC1_CH1 TRUE -#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_DAC1_CH1_DMA_CHN 0x00700000 - -#define STM32_HAS_DAC1_CH2 TRUE -#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) -#define STM32_DAC1_CH2_DMA_CHN 0x07000000 - -#define STM32_HAS_DAC2_CH1 FALSE -#define STM32_HAS_DAC2_CH2 FALSE - -/* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING FALSE -#define STM32_DMA_SUPPORTS_DMAMUX FALSE - -#define STM32_HAS_DMA1 TRUE -#define STM32_DMA1_CH0_HANDLER Vector6C -#define STM32_DMA1_CH1_HANDLER Vector70 -#define STM32_DMA1_CH2_HANDLER Vector74 -#define STM32_DMA1_CH3_HANDLER Vector78 -#define STM32_DMA1_CH4_HANDLER Vector7C -#define STM32_DMA1_CH5_HANDLER Vector80 -#define STM32_DMA1_CH6_HANDLER Vector84 -#define STM32_DMA1_CH7_HANDLER VectorFC -#define STM32_DMA1_CH0_NUMBER 11 -#define STM32_DMA1_CH1_NUMBER 12 -#define STM32_DMA1_CH2_NUMBER 13 -#define STM32_DMA1_CH3_NUMBER 14 -#define STM32_DMA1_CH4_NUMBER 15 -#define STM32_DMA1_CH5_NUMBER 16 -#define STM32_DMA1_CH6_NUMBER 17 -#define STM32_DMA1_CH7_NUMBER 47 - -#define STM32_HAS_DMA2 TRUE -#define STM32_DMA2_CH0_HANDLER Vector120 -#define STM32_DMA2_CH1_HANDLER Vector124 -#define STM32_DMA2_CH2_HANDLER Vector128 -#define STM32_DMA2_CH3_HANDLER Vector12C -#define STM32_DMA2_CH4_HANDLER Vector130 -#define STM32_DMA2_CH5_HANDLER Vector150 -#define STM32_DMA2_CH6_HANDLER Vector154 -#define STM32_DMA2_CH7_HANDLER Vector158 -#define STM32_DMA2_CH0_NUMBER 56 -#define STM32_DMA2_CH1_NUMBER 57 -#define STM32_DMA2_CH2_NUMBER 58 -#define STM32_DMA2_CH3_NUMBER 59 -#define STM32_DMA2_CH4_NUMBER 60 -#define STM32_DMA2_CH5_NUMBER 68 -#define STM32_DMA2_CH6_NUMBER 69 -#define STM32_DMA2_CH7_NUMBER 70 - -/* ETH attributes.*/ -#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F205xx) || \ - defined(STM32F215xx) -#define STM32_HAS_ETH FALSE -#else -#define STM32_HAS_ETH TRUE -#define STM32_ETH_HANDLER Vector134 -#define STM32_ETH_NUMBER 61 -#endif - -/* EXTI attributes.*/ -#define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR1_MASK 0x00000000U - -/* GPIO attributes.*/ -#define STM32_HAS_GPIOA TRUE -#define STM32_HAS_GPIOB TRUE -#define STM32_HAS_GPIOC TRUE -#define STM32_HAS_GPIOD TRUE -#define STM32_HAS_GPIOE TRUE -#define STM32_HAS_GPIOH TRUE -#define STM32_HAS_GPIOF TRUE -#define STM32_HAS_GPIOG TRUE -#define STM32_HAS_GPIOI TRUE -#define STM32_HAS_GPIOJ FALSE -#define STM32_HAS_GPIOK FALSE -#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ - RCC_AHB1ENR_GPIOBEN | \ - RCC_AHB1ENR_GPIOCEN | \ - RCC_AHB1ENR_GPIODEN | \ - RCC_AHB1ENR_GPIOEEN | \ - RCC_AHB1ENR_GPIOFEN | \ - RCC_AHB1ENR_GPIOGEN | \ - RCC_AHB1ENR_GPIOHEN | \ - RCC_AHB1ENR_GPIOIEN) - -/* I2C attributes.*/ -#define STM32_HAS_I2C1 TRUE -#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ - STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_I2C1_RX_DMA_CHN 0x00100001 -#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ - STM32_DMA_STREAM_ID_MSK(1, 6)) -#define STM32_I2C1_TX_DMA_CHN 0x11000000 - -#define STM32_HAS_I2C2 TRUE -#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ - STM32_DMA_STREAM_ID_MSK(1, 3)) -#define STM32_I2C2_RX_DMA_CHN 0x00007700 -#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) -#define STM32_I2C2_TX_DMA_CHN 0x70000000 - -#define STM32_HAS_I2C3 TRUE -#define STM32_I2C3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) -#define STM32_I2C3_RX_DMA_CHN 0x00000300 -#define STM32_I2C3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_I2C3_TX_DMA_CHN 0x00030000 - -#define STM32_HAS_I2C4 FALSE - -/* QUADSPI attributes.*/ -#define STM32_HAS_QUADSPI1 FALSE - -/* SDIO attributes.*/ -#define STM32_HAS_SDIO TRUE -#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 6)) -#define STM32_SDC_SDIO_DMA_CHN 0x04004000 - -/* SPI attributes.*/ -#define STM32_HAS_SPI1 TRUE -#define STM32_SPI1_SUPPORTS_I2S FALSE -#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_SPI1_RX_DMA_CHN 0x00000303 -#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_SPI1_TX_DMA_CHN 0x00303000 - -#define STM32_HAS_SPI2 TRUE -#define STM32_SPI2_SUPPORTS_I2S TRUE -#define STM32_SPI2_I2S_FULLDUPLEX TRUE -#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) -#define STM32_SPI2_RX_DMA_CHN 0x00000000 -#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_SPI2_TX_DMA_CHN 0x00000000 - -#define STM32_HAS_SPI3 TRUE -#define STM32_SPI3_SUPPORTS_I2S TRUE -#define STM32_SPI3_I2S_FULLDUPLEX TRUE -#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ - STM32_DMA_STREAM_ID_MSK(1, 2)) -#define STM32_SPI3_RX_DMA_CHN 0x00000000 -#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ - STM32_DMA_STREAM_ID_MSK(1, 7)) -#define STM32_SPI3_TX_DMA_CHN 0x00000000 - -#define STM32_HAS_SPI4 FALSE -#define STM32_HAS_SPI5 FALSE -#define STM32_HAS_SPI6 FALSE - -/* TIM attributes.*/ -#define STM32_TIM_MAX_CHANNELS 4 - -#define STM32_HAS_TIM1 TRUE -#define STM32_TIM1_IS_32BITS FALSE -#define STM32_TIM1_CHANNELS 4 - -#define STM32_HAS_TIM2 TRUE -#define STM32_TIM2_IS_32BITS TRUE -#define STM32_TIM2_CHANNELS 4 - -#define STM32_HAS_TIM3 TRUE -#define STM32_TIM3_IS_32BITS FALSE -#define STM32_TIM3_CHANNELS 4 - -#define STM32_HAS_TIM4 TRUE -#define STM32_TIM4_IS_32BITS FALSE -#define STM32_TIM4_CHANNELS 4 - -#define STM32_HAS_TIM5 TRUE -#define STM32_TIM5_IS_32BITS TRUE -#define STM32_TIM5_CHANNELS 4 - -#define STM32_HAS_TIM6 TRUE -#define STM32_TIM6_IS_32BITS FALSE -#define STM32_TIM6_CHANNELS 0 - -#define STM32_HAS_TIM7 TRUE -#define STM32_TIM7_IS_32BITS FALSE -#define STM32_TIM7_CHANNELS 0 - -#define STM32_HAS_TIM8 TRUE -#define STM32_TIM8_IS_32BITS FALSE -#define STM32_TIM8_CHANNELS 6 - -#define STM32_HAS_TIM9 TRUE -#define STM32_TIM9_IS_32BITS FALSE -#define STM32_TIM9_CHANNELS 2 - -#define STM32_HAS_TIM10 TRUE -#define STM32_TIM10_IS_32BITS FALSE -#define STM32_TIM10_CHANNELS 1 - -#define STM32_HAS_TIM11 TRUE -#define STM32_TIM11_IS_32BITS FALSE -#define STM32_TIM11_CHANNELS 1 - -#define STM32_HAS_TIM12 TRUE -#define STM32_TIM12_IS_32BITS FALSE -#define STM32_TIM12_CHANNELS 2 - -#define STM32_HAS_TIM13 TRUE -#define STM32_TIM13_IS_32BITS FALSE -#define STM32_TIM13_CHANNELS 1 - -#define STM32_HAS_TIM14 TRUE -#define STM32_TIM14_IS_32BITS FALSE -#define STM32_TIM14_CHANNELS 1 - -#define STM32_HAS_TIM15 FALSE -#define STM32_HAS_TIM16 FALSE -#define STM32_HAS_TIM17 FALSE -#define STM32_HAS_TIM18 FALSE -#define STM32_HAS_TIM19 FALSE -#define STM32_HAS_TIM20 FALSE -#define STM32_HAS_TIM21 FALSE -#define STM32_HAS_TIM22 FALSE - -/* USART attributes.*/ -#define STM32_HAS_USART1 TRUE -#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_USART1_RX_DMA_CHN 0x00400400 -#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) -#define STM32_USART1_TX_DMA_CHN 0x40000000 - -#define STM32_HAS_USART2 TRUE -#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) -#define STM32_USART2_RX_DMA_CHN 0x00400000 -#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) -#define STM32_USART2_TX_DMA_CHN 0x04000000 - -#define STM32_HAS_USART3 TRUE -#define STM32_USART3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) -#define STM32_USART3_RX_DMA_CHN 0x00000040 -#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\ - STM32_DMA_STREAM_ID_MSK(1, 4)) -#define STM32_USART3_TX_DMA_CHN 0x00074000 - -#define STM32_HAS_UART4 TRUE -#define STM32_UART4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) -#define STM32_UART4_RX_DMA_CHN 0x00000400 -#define STM32_UART4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_UART4_TX_DMA_CHN 0x00040000 - -#define STM32_HAS_UART5 TRUE -#define STM32_UART5_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) -#define STM32_UART5_RX_DMA_CHN 0x00000004 -#define STM32_UART5_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) -#define STM32_UART5_TX_DMA_CHN 0x40000000 - -#define STM32_HAS_USART6 TRUE -#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_USART6_RX_DMA_CHN 0x00000550 -#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ - STM32_DMA_STREAM_ID_MSK(2, 7)) -#define STM32_USART6_TX_DMA_CHN 0x55000000 - -#define STM32_HAS_UART7 FALSE -#define STM32_HAS_UART8 FALSE -#define STM32_HAS_LPUART1 FALSE - -/* USB attributes.*/ -#define STM32_OTG_STEPPING 1 -#define STM32_HAS_OTG1 TRUE -#define STM32_OTG1_ENDPOINTS 3 -#define STM32_HAS_OTG2 TRUE -#define STM32_OTG2_ENDPOINTS 5 - -#define STM32_HAS_USB FALSE - -/* IWDG attributes.*/ -#define STM32_HAS_IWDG TRUE -#define STM32_IWDG_IS_WINDOWED FALSE - -/* LTDC attributes.*/ -#define STM32_HAS_LTDC FALSE - -/* DMA2D attributes.*/ -#define STM32_HAS_DMA2D FALSE - -/* FSMC attributes.*/ -#define STM32_HAS_FSMC TRUE -#define STM32_FSMC_IS_FMC FALSE - -/* CRC attributes.*/ -#define STM32_HAS_CRC TRUE -#define STM32_CRC_PROGRAMMABLE FALSE - -#endif /* defined(STM32F40_41xxx) || defined(STM32F2XX) */ - -/*===========================================================================*/ -/* STM32F401xx. */ -/*===========================================================================*/ - -#if defined(STM32F401xx) - -/* Clock tree attributes.*/ -#define STM32_HAS_RCC_PLLSAI FALSE -#define STM32_HAS_RCC_PLLI2S FALSE -#define STM32_HAS_RCC_DCKCFGR TRUE -#define STM32_HAS_RCC_DCKCFGR2 FALSE -#define STM32_HAS_RCC_I2SSRC FALSE -#define STM32_HAS_RCC_I2SPLLSRC FALSE -#define STM32_HAS_RCC_CK48MSEL FALSE -#define STM32_RCC_CK48MSEL_USES_I2S FALSE -#define STM32_TIMPRE_PRESCALE4 FALSE - -/* ADC attributes.*/ -#define STM32_ADC_HANDLER Vector88 -#define STM32_ADC_NUMBER 18 - -#define STM32_HAS_ADC1 TRUE -#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_ADC1_DMA_CHN 0x00000000 - -#define STM32_HAS_ADC2 TRUE -#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ - STM32_DMA_STREAM_ID_MSK(2, 3)) -#define STM32_ADC2_DMA_CHN 0x00001100 - -#define STM32_HAS_ADC3 TRUE -#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 1)) -#define STM32_ADC3_DMA_CHN 0x00000022 - -#define STM32_HAS_ADC4 FALSE - -#define STM32_HAS_SDADC1 FALSE -#define STM32_HAS_SDADC2 FALSE -#define STM32_HAS_SDADC3 FALSE - -/* CAN attributes.*/ -#define STM32_HAS_CAN1 TRUE -#define STM32_HAS_CAN2 TRUE -#define STM32_HAS_CAN3 FALSE -#define STM32_CAN_MAX_FILTERS 28 - -/* DAC attributes.*/ -#define STM32_HAS_DAC1_CH1 FALSE -#define STM32_HAS_DAC1_CH2 FALSE -#define STM32_HAS_DAC2_CH1 FALSE -#define STM32_HAS_DAC2_CH2 FALSE - -/* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING FALSE -#define STM32_DMA_SUPPORTS_DMAMUX FALSE - -#define STM32_HAS_DMA1 TRUE -#define STM32_DMA1_CH0_HANDLER Vector6C -#define STM32_DMA1_CH1_HANDLER Vector70 -#define STM32_DMA1_CH2_HANDLER Vector74 -#define STM32_DMA1_CH3_HANDLER Vector78 -#define STM32_DMA1_CH4_HANDLER Vector7C -#define STM32_DMA1_CH5_HANDLER Vector80 -#define STM32_DMA1_CH6_HANDLER Vector84 -#define STM32_DMA1_CH7_HANDLER VectorFC -#define STM32_DMA1_CH0_NUMBER 11 -#define STM32_DMA1_CH1_NUMBER 12 -#define STM32_DMA1_CH2_NUMBER 13 -#define STM32_DMA1_CH3_NUMBER 14 -#define STM32_DMA1_CH4_NUMBER 15 -#define STM32_DMA1_CH5_NUMBER 16 -#define STM32_DMA1_CH6_NUMBER 17 -#define STM32_DMA1_CH7_NUMBER 47 - -#define STM32_HAS_DMA2 TRUE -#define STM32_DMA2_CH0_HANDLER Vector120 -#define STM32_DMA2_CH1_HANDLER Vector124 -#define STM32_DMA2_CH2_HANDLER Vector128 -#define STM32_DMA2_CH3_HANDLER Vector12C -#define STM32_DMA2_CH4_HANDLER Vector130 -#define STM32_DMA2_CH5_HANDLER Vector150 -#define STM32_DMA2_CH6_HANDLER Vector154 -#define STM32_DMA2_CH7_HANDLER Vector158 -#define STM32_DMA2_CH0_NUMBER 56 -#define STM32_DMA2_CH1_NUMBER 57 -#define STM32_DMA2_CH2_NUMBER 58 -#define STM32_DMA2_CH3_NUMBER 59 -#define STM32_DMA2_CH4_NUMBER 60 -#define STM32_DMA2_CH5_NUMBER 68 -#define STM32_DMA2_CH6_NUMBER 69 -#define STM32_DMA2_CH7_NUMBER 70 - -/* ETH attributes.*/ -#define STM32_HAS_ETH FALSE - -/* EXTI attributes.*/ -#define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR1_MASK 0x00000000U - -/* GPIO attributes.*/ -#define STM32_HAS_GPIOA TRUE -#define STM32_HAS_GPIOB TRUE -#define STM32_HAS_GPIOC TRUE -#define STM32_HAS_GPIOD TRUE -#define STM32_HAS_GPIOE TRUE -#define STM32_HAS_GPIOH TRUE -#define STM32_HAS_GPIOF FALSE -#define STM32_HAS_GPIOG FALSE -#define STM32_HAS_GPIOI FALSE -#define STM32_HAS_GPIOJ FALSE -#define STM32_HAS_GPIOK FALSE -#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ - RCC_AHB1ENR_GPIOBEN | \ - RCC_AHB1ENR_GPIOCEN | \ - RCC_AHB1ENR_GPIODEN | \ - RCC_AHB1ENR_GPIOEEN) - -/* I2C attributes.*/ -#define STM32_HAS_I2C1 TRUE -#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ - STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_I2C1_RX_DMA_CHN 0x00100001 -#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ - STM32_DMA_STREAM_ID_MSK(1, 6)) -#define STM32_I2C1_TX_DMA_CHN 0x11000000 - -#define STM32_HAS_I2C2 TRUE -#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ - STM32_DMA_STREAM_ID_MSK(1, 3)) -#define STM32_I2C2_RX_DMA_CHN 0x00007700 -#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) -#define STM32_I2C2_TX_DMA_CHN 0x70000000 - -#define STM32_HAS_I2C3 TRUE -#define STM32_I2C3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) -#define STM32_I2C3_RX_DMA_CHN 0x00000300 -#define STM32_I2C3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_I2C3_TX_DMA_CHN 0x00030000 - -#define STM32_HAS_I2C4 FALSE - -/* QUADSPI attributes.*/ -#define STM32_HAS_QUADSPI1 FALSE - -/* SDIO attributes.*/ -#define STM32_HAS_SDIO TRUE -#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 6)) -#define STM32_SDC_SDIO_DMA_CHN 0x04004000 - -/* SPI attributes.*/ -#define STM32_HAS_SPI1 TRUE -#define STM32_SPI1_SUPPORTS_I2S FALSE -#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_SPI1_RX_DMA_CHN 0x00000303 -#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_SPI1_TX_DMA_CHN 0x00303000 - -#define STM32_HAS_SPI2 TRUE -#define STM32_SPI2_SUPPORTS_I2S TRUE -#define STM32_SPI2_I2S_FULLDUPLEX TRUE -#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) -#define STM32_SPI2_RX_DMA_CHN 0x00000000 -#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_SPI2_TX_DMA_CHN 0x00000000 - -#define STM32_HAS_SPI3 TRUE -#define STM32_SPI3_SUPPORTS_I2S TRUE -#define STM32_SPI3_I2S_FULLDUPLEX TRUE -#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ - STM32_DMA_STREAM_ID_MSK(1, 2)) -#define STM32_SPI3_RX_DMA_CHN 0x00000000 -#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ - STM32_DMA_STREAM_ID_MSK(1, 7)) -#define STM32_SPI3_TX_DMA_CHN 0x00000000 - -#define STM32_HAS_SPI4 TRUE -#define STM32_SPI4_SUPPORTS_I2S FALSE -#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ - STM32_DMA_STREAM_ID_MSK(2, 3)) -#define STM32_SPI4_RX_DMA_CHN 0x00005004 -#define STM32_SPI4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_SPI4_TX_DMA_CHN 0x00050040 - -#define STM32_HAS_SPI5 FALSE -#define STM32_HAS_SPI6 FALSE - -/* TIM attributes.*/ -#define STM32_TIM_MAX_CHANNELS 4 - -#define STM32_HAS_TIM1 TRUE -#define STM32_TIM1_IS_32BITS FALSE -#define STM32_TIM1_CHANNELS 4 - -#define STM32_HAS_TIM2 TRUE -#define STM32_TIM2_IS_32BITS TRUE -#define STM32_TIM2_CHANNELS 4 - -#define STM32_HAS_TIM3 TRUE -#define STM32_TIM3_IS_32BITS FALSE -#define STM32_TIM3_CHANNELS 4 - -#define STM32_HAS_TIM4 TRUE -#define STM32_TIM4_IS_32BITS FALSE -#define STM32_TIM4_CHANNELS 4 - -#define STM32_HAS_TIM5 TRUE -#define STM32_TIM5_IS_32BITS TRUE -#define STM32_TIM5_CHANNELS 4 - -#define STM32_HAS_TIM9 TRUE -#define STM32_TIM9_IS_32BITS FALSE -#define STM32_TIM9_CHANNELS 2 - -#define STM32_HAS_TIM10 TRUE -#define STM32_TIM10_IS_32BITS FALSE -#define STM32_TIM10_CHANNELS 1 - -#define STM32_HAS_TIM11 TRUE -#define STM32_TIM11_IS_32BITS FALSE -#define STM32_TIM11_CHANNELS 1 - -#define STM32_HAS_TIM6 FALSE -#define STM32_HAS_TIM7 FALSE -#define STM32_HAS_TIM8 FALSE -#define STM32_HAS_TIM12 FALSE -#define STM32_HAS_TIM13 FALSE -#define STM32_HAS_TIM14 FALSE -#define STM32_HAS_TIM15 FALSE -#define STM32_HAS_TIM16 FALSE -#define STM32_HAS_TIM17 FALSE -#define STM32_HAS_TIM18 FALSE -#define STM32_HAS_TIM19 FALSE -#define STM32_HAS_TIM20 FALSE -#define STM32_HAS_TIM21 FALSE -#define STM32_HAS_TIM22 FALSE - -/* USART attributes.*/ -#define STM32_HAS_USART1 TRUE -#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ - STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_USART1_RX_DMA_CHN 0x00400400 -#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) -#define STM32_USART1_TX_DMA_CHN 0x40000000 - -#define STM32_HAS_USART2 TRUE -#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) -#define STM32_USART2_RX_DMA_CHN 0x00400000 -#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) -#define STM32_USART2_TX_DMA_CHN 0x04000000 - -#define STM32_HAS_USART3 FALSE -#define STM32_HAS_UART4 FALSE -#define STM32_HAS_UART5 FALSE - -#define STM32_HAS_USART6 TRUE -#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ - STM32_DMA_STREAM_ID_MSK(2, 2)) -#define STM32_USART6_RX_DMA_CHN 0x00000550 -#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ - STM32_DMA_STREAM_ID_MSK(2, 7)) -#define STM32_USART6_TX_DMA_CHN 0x55000000 - -#define STM32_HAS_UART7 FALSE -#define STM32_HAS_UART8 FALSE -#define STM32_HAS_LPUART1 FALSE - -/* USB attributes.*/ -#define STM32_OTG_STEPPING 1 -#define STM32_HAS_OTG1 TRUE -#define STM32_OTG1_ENDPOINTS 3 -#define STM32_HAS_OTG2 FALSE - -#define STM32_HAS_USB FALSE - -/* IWDG attributes.*/ -#define STM32_HAS_IWDG TRUE -#define STM32_IWDG_IS_WINDOWED FALSE - -/* LTDC attributes.*/ -#define STM32_HAS_LTDC FALSE - -/* DMA2D attributes.*/ -#define STM32_HAS_DMA2D FALSE - -/* FSMC attributes.*/ -#define STM32_HAS_FSMC FALSE - -/* CRC attributes.*/ -#define STM32_HAS_CRC TRUE -#define STM32_CRC_PROGRAMMABLE FALSE - -#endif /* defined(STM32F401xx) */ -/** @} */ - -#endif /* STM32_REGISTRY_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 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 STM32F4xx/stm32_registry.h + * @brief STM32F4xx capabilities registry. + * + * @addtogroup HAL + * @{ + */ + +#ifndef STM32_REGISTRY_H +#define STM32_REGISTRY_H + +#if defined(STM32F469xx) || defined(STM32F479xx) +#define STM32F469_479xx +#define STM32F4XX + +#elif defined(STM32F446xx) +#define STM32F4XX + +#elif defined(STM32F439xx) || defined(STM32F429xx) +#define STM32F429_439xx +#define STM32F4XX + +#elif defined(STM32F437xx) || defined(STM32F427xx) +#define STM32F427_437xx +#define STM32F4XX + +#elif defined(STM32F413xx) +#define STM32F413xx +#define STM32F4XX + +#elif defined(STM32F412Cx) || defined(STM32F412Rx) || \ + defined(STM32F412Vx) || defined(STM32F412Zx) +#define STM32F412xx +#define STM32F4XX + +#elif defined(STM32F411xE) +#define STM32F411xx +#define STM32F4XX + +#elif defined(STM32F410Cx) || defined(STM32F410Rx) || \ + defined(STM32F410Tx) +#define STM32F410xx +#define STM32F4XX + +#elif defined(STM32F405xx) || defined(STM32F415xx) || \ + defined(STM32F407xx) || defined(STM32F417xx) +#define STM32F40_41xxx +#define STM32F4XX + +#elif defined(STM32F401xC) || defined(STM32F401xE) +#define STM32F401xx +#define STM32F4XX + +#elif defined(STM32F205xx) || defined(STM32F215xx) || \ + defined(STM32F207xx) || defined(STM32F217xx) +#define STM32F2XX + +#else +#error "STM32F2xx/F4xx device not specified" +#endif + +/*===========================================================================*/ +/* Platform capabilities. */ +/*===========================================================================*/ + +/** + * @name STM32F4xx/STM32F2xx capabilities + * @{ + */ + +/*===========================================================================*/ +/* Common. */ +/*===========================================================================*/ + +/* RNG attributes.*/ +#define STM32_HAS_RNG1 TRUE + +/* RTC attributes.*/ +#define STM32_HAS_RTC TRUE +#if !defined(STM32F2XX) +#define STM32_RTC_HAS_SUBSECONDS TRUE +#else +#define STM32_RTC_HAS_SUBSECONDS FALSE +#endif +#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE +#define STM32_RTC_NUM_ALARMS 2 +#define STM32_RTC_STORAGE_SIZE 80 +#define STM32_RTC_TAMP_STAMP_HANDLER Vector48 +#define STM32_RTC_WKUP_HANDLER Vector4C +#define STM32_RTC_ALARM_HANDLER VectorE4 +#define STM32_RTC_TAMP_STAMP_NUMBER 2 +#define STM32_RTC_WKUP_NUMBER 3 +#define STM32_RTC_ALARM_NUMBER 41 +#define STM32_RTC_ALARM_EXTI 17 +#define STM32_RTC_TAMP_STAMP_EXTI 21 +#define STM32_RTC_WKUP_EXTI 22 +#define STM32_RTC_IRQ_ENABLE() do { \ + nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI21_PRIORITY); \ + nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI22_PRIORITY); \ + nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \ +} while (false) + +/*===========================================================================*/ +/* STM32F469xx, STM32F479xx. */ +/*===========================================================================*/ + +#if defined(STM32F469_479xx) || defined(__DOXYGEN__) + +/* Clock tree attributes.*/ +#define STM32_HAS_RCC_PLLSAI TRUE +#define STM32_HAS_RCC_PLLI2S TRUE +#define STM32_HAS_RCC_DCKCFGR TRUE +#define STM32_HAS_RCC_DCKCFGR2 FALSE +#define STM32_HAS_RCC_I2SSRC TRUE +#define STM32_HAS_RCC_I2SPLLSRC FALSE +#define STM32_HAS_RCC_CK48MSEL TRUE +#define STM32_RCC_CK48MSEL_USES_I2S FALSE +#define STM32_PLL48CLK_ALTSRC STM32_PLLSAI_Q_CLKOUT +#define STM32_TIMPRE_PRESCALE4 TRUE + +/* ADC attributes.*/ +#define STM32_ADC_HANDLER Vector88 +#define STM32_ADC_NUMBER 18 + +#define STM32_HAS_ADC1 TRUE +#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_ADC1_DMA_CHN 0x00000000 + +#define STM32_HAS_ADC2 TRUE +#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 3)) +#define STM32_ADC2_DMA_CHN 0x00001100 + +#define STM32_HAS_ADC3 TRUE +#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 1)) +#define STM32_ADC3_DMA_CHN 0x00000022 + +#define STM32_HAS_ADC4 FALSE + +#define STM32_HAS_SDADC1 FALSE +#define STM32_HAS_SDADC2 FALSE +#define STM32_HAS_SDADC3 FALSE + +/* CAN attributes.*/ +#define STM32_HAS_CAN1 TRUE +#define STM32_HAS_CAN2 TRUE +#define STM32_HAS_CAN3 FALSE +#define STM32_CAN_MAX_FILTERS 28 + +/* DAC attributes.*/ +#define STM32_HAS_DAC1_CH1 TRUE +#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_DAC1_CH1_DMA_CHN 0x00700000 + +#define STM32_HAS_DAC1_CH2 TRUE +#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_DAC1_CH2_DMA_CHN 0x07000000 + +#define STM32_HAS_DAC2_CH1 FALSE +#define STM32_HAS_DAC2_CH2 FALSE + +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA TRUE +#define STM32_DMA_CACHE_HANDLING FALSE +#define STM32_DMA_SUPPORTS_DMAMUX FALSE + +#define STM32_HAS_DMA1 TRUE +#define STM32_DMA1_CH0_HANDLER Vector6C +#define STM32_DMA1_CH1_HANDLER Vector70 +#define STM32_DMA1_CH2_HANDLER Vector74 +#define STM32_DMA1_CH3_HANDLER Vector78 +#define STM32_DMA1_CH4_HANDLER Vector7C +#define STM32_DMA1_CH5_HANDLER Vector80 +#define STM32_DMA1_CH6_HANDLER Vector84 +#define STM32_DMA1_CH7_HANDLER VectorFC +#define STM32_DMA1_CH0_NUMBER 11 +#define STM32_DMA1_CH1_NUMBER 12 +#define STM32_DMA1_CH2_NUMBER 13 +#define STM32_DMA1_CH3_NUMBER 14 +#define STM32_DMA1_CH4_NUMBER 15 +#define STM32_DMA1_CH5_NUMBER 16 +#define STM32_DMA1_CH6_NUMBER 17 +#define STM32_DMA1_CH7_NUMBER 47 + +#define STM32_HAS_DMA2 TRUE +#define STM32_DMA2_CH0_HANDLER Vector120 +#define STM32_DMA2_CH1_HANDLER Vector124 +#define STM32_DMA2_CH2_HANDLER Vector128 +#define STM32_DMA2_CH3_HANDLER Vector12C +#define STM32_DMA2_CH4_HANDLER Vector130 +#define STM32_DMA2_CH5_HANDLER Vector150 +#define STM32_DMA2_CH6_HANDLER Vector154 +#define STM32_DMA2_CH7_HANDLER Vector158 +#define STM32_DMA2_CH0_NUMBER 56 +#define STM32_DMA2_CH1_NUMBER 57 +#define STM32_DMA2_CH2_NUMBER 58 +#define STM32_DMA2_CH3_NUMBER 59 +#define STM32_DMA2_CH4_NUMBER 60 +#define STM32_DMA2_CH5_NUMBER 68 +#define STM32_DMA2_CH6_NUMBER 69 +#define STM32_DMA2_CH7_NUMBER 70 + +/* ETH attributes.*/ +#define STM32_HAS_ETH TRUE +#define STM32_ETH_HANDLER Vector134 +#define STM32_ETH_NUMBER 61 + +/* EXTI attributes.*/ +#define STM32_EXTI_NUM_LINES 23 +#define STM32_EXTI_IMR1_MASK 0x00000000U + +/* GPIO attributes.*/ +#define STM32_HAS_GPIOA TRUE +#define STM32_HAS_GPIOB TRUE +#define STM32_HAS_GPIOC TRUE +#define STM32_HAS_GPIOD TRUE +#define STM32_HAS_GPIOE TRUE +#define STM32_HAS_GPIOH TRUE +#define STM32_HAS_GPIOF TRUE +#define STM32_HAS_GPIOG TRUE +#define STM32_HAS_GPIOI TRUE +#define STM32_HAS_GPIOJ TRUE +#define STM32_HAS_GPIOK TRUE + +#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ + RCC_AHB1ENR_GPIOBEN | \ + RCC_AHB1ENR_GPIOCEN | \ + RCC_AHB1ENR_GPIODEN | \ + RCC_AHB1ENR_GPIOEEN | \ + RCC_AHB1ENR_GPIOFEN | \ + RCC_AHB1ENR_GPIOGEN | \ + RCC_AHB1ENR_GPIOHEN | \ + RCC_AHB1ENR_GPIOIEN | \ + RCC_AHB1ENR_GPIOJEN | \ + RCC_AHB1ENR_GPIOKEN) + +/* I2C attributes.*/ +#define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C1_RX_DMA_CHN 0x00100001 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ + STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_I2C1_TX_DMA_CHN 0x11000000 + +#define STM32_HAS_I2C2 TRUE +#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ + STM32_DMA_STREAM_ID_MSK(1, 3)) +#define STM32_I2C2_RX_DMA_CHN 0x00007700 +#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) +#define STM32_I2C2_TX_DMA_CHN 0x70000000 + +#define STM32_HAS_I2C3 TRUE +#define STM32_I2C3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_I2C3_RX_DMA_CHN 0x00000300 +#define STM32_I2C3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_I2C3_TX_DMA_CHN 0x00030000 + +#define STM32_HAS_I2C4 FALSE + +/* QUADSPI attributes.*/ +#define STM32_HAS_QUADSPI1 TRUE +#define STM32_QUADSPI1_HANDLER Vector1AC +#define STM32_QUADSPI1_NUMBER 91 +#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) +#define STM32_QUADSPI1_DMA_CHN 0x30000000 + +/* SDIO attributes.*/ +#define STM32_HAS_SDIO TRUE +#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SDC_SDIO_DMA_CHN 0x04004000 + +/* SPI attributes.*/ +#define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_SUPPORTS_I2S TRUE +#define STM32_SPI1_I2S_FULLDUPLEX TRUE +#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_SPI1_RX_DMA_CHN 0x00000303 +#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI1_TX_DMA_CHN 0x00303000 + +#define STM32_HAS_SPI2 TRUE +#define STM32_SPI2_SUPPORTS_I2S TRUE +#define STM32_SPI2_I2S_FULLDUPLEX TRUE +#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI3 TRUE +#define STM32_SPI3_SUPPORTS_I2S TRUE +#define STM32_SPI3_I2S_FULLDUPLEX TRUE +#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ + STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_SPI3_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI4 TRUE +#define STM32_SPI4_SUPPORTS_I2S FALSE +#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 3)) +#define STM32_SPI4_RX_DMA_CHN 0x00005004 +#define STM32_SPI4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_SPI4_TX_DMA_CHN 0x00050040 + +#define STM32_HAS_SPI5 TRUE +#define STM32_SPI5_SUPPORTS_I2S FALSE +#define STM32_SPI5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI5_RX_DMA_CHN 0x00702000 +#define STM32_SPI5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\ + STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SPI5_TX_DMA_CHN 0x07020000 + +#define STM32_HAS_SPI6 TRUE +#define STM32_SPI6_SUPPORTS_I2S FALSE +#define STM32_SPI6_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 6) +#define STM32_SPI6_RX_DMA_CHN 0x01000000 +#define STM32_SPI6_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 5) +#define STM32_SPI6_TX_DMA_CHN 0x00100000 + +/* TIM attributes.*/ +#define STM32_TIM_MAX_CHANNELS 4 + +#define STM32_HAS_TIM1 TRUE +#define STM32_TIM1_IS_32BITS FALSE +#define STM32_TIM1_CHANNELS 4 + +#define STM32_HAS_TIM2 TRUE +#define STM32_TIM2_IS_32BITS TRUE +#define STM32_TIM2_CHANNELS 4 + +#define STM32_HAS_TIM3 TRUE +#define STM32_TIM3_IS_32BITS FALSE +#define STM32_TIM3_CHANNELS 4 + +#define STM32_HAS_TIM4 TRUE +#define STM32_TIM4_IS_32BITS FALSE +#define STM32_TIM4_CHANNELS 4 + +#define STM32_HAS_TIM5 TRUE +#define STM32_TIM5_IS_32BITS TRUE +#define STM32_TIM5_CHANNELS 4 + +#define STM32_HAS_TIM6 TRUE +#define STM32_TIM6_IS_32BITS FALSE +#define STM32_TIM6_CHANNELS 0 + +#define STM32_HAS_TIM7 TRUE +#define STM32_TIM7_IS_32BITS FALSE +#define STM32_TIM7_CHANNELS 0 + +#define STM32_HAS_TIM8 TRUE +#define STM32_TIM8_IS_32BITS FALSE +#define STM32_TIM8_CHANNELS 4 + +#define STM32_HAS_TIM9 TRUE +#define STM32_TIM9_IS_32BITS FALSE +#define STM32_TIM9_CHANNELS 2 + +#define STM32_HAS_TIM10 TRUE +#define STM32_TIM10_IS_32BITS FALSE +#define STM32_TIM10_CHANNELS 1 + +#define STM32_HAS_TIM11 TRUE +#define STM32_TIM11_IS_32BITS FALSE +#define STM32_TIM11_CHANNELS 1 + +#define STM32_HAS_TIM12 TRUE +#define STM32_TIM12_IS_32BITS FALSE +#define STM32_TIM12_CHANNELS 2 + +#define STM32_HAS_TIM13 TRUE +#define STM32_TIM13_IS_32BITS FALSE +#define STM32_TIM13_CHANNELS 1 + +#define STM32_HAS_TIM14 TRUE +#define STM32_TIM14_IS_32BITS FALSE +#define STM32_TIM14_CHANNELS 1 + +#define STM32_HAS_TIM15 FALSE +#define STM32_HAS_TIM16 FALSE +#define STM32_HAS_TIM17 FALSE +#define STM32_HAS_TIM18 FALSE +#define STM32_HAS_TIM19 FALSE +#define STM32_HAS_TIM20 FALSE +#define STM32_HAS_TIM21 FALSE +#define STM32_HAS_TIM22 FALSE + +/* USART attributes.*/ +#define STM32_HAS_USART1 TRUE +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_USART1_RX_DMA_CHN 0x00400400 +#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) +#define STM32_USART1_TX_DMA_CHN 0x40000000 + +#define STM32_HAS_USART2 TRUE +#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) +#define STM32_USART2_RX_DMA_CHN 0x00400000 +#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) +#define STM32_USART2_TX_DMA_CHN 0x04000000 + +#define STM32_HAS_USART3 TRUE +#define STM32_USART3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) +#define STM32_USART3_RX_DMA_CHN 0x00000040 +#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\ + STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_USART3_TX_DMA_CHN 0x00074000 + +#define STM32_HAS_UART4 TRUE +#define STM32_UART4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_UART4_RX_DMA_CHN 0x00000400 +#define STM32_UART4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_UART4_TX_DMA_CHN 0x00040000 + +#define STM32_HAS_UART5 TRUE +#define STM32_UART5_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) +#define STM32_UART5_RX_DMA_CHN 0x00000004 +#define STM32_UART5_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) +#define STM32_UART5_TX_DMA_CHN 0x40000000 + +#define STM32_HAS_USART6 TRUE +#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_USART6_RX_DMA_CHN 0x00000550 +#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ + STM32_DMA_STREAM_ID_MSK(2, 7)) +#define STM32_USART6_TX_DMA_CHN 0x55000000 + +#define STM32_HAS_UART7 TRUE +#define STM32_UART7_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_UART7_RX_DMA_CHN 0x00005000 +#define STM32_UART7_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) +#define STM32_UART7_TX_DMA_CHN 0x00000050 + +#define STM32_HAS_UART8 TRUE +#define STM32_UART8_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) +#define STM32_UART8_RX_DMA_CHN 0x05000000 +#define STM32_UART8_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) +#define STM32_UART8_TX_DMA_CHN 0x00000005 +#define STM32_HAS_LPUART1 FALSE + +/* USB attributes.*/ +#define STM32_OTG_STEPPING 2 +#define STM32_HAS_OTG1 TRUE +#define STM32_OTG1_ENDPOINTS 5 +#define STM32_HAS_OTG2 TRUE +#define STM32_OTG2_ENDPOINTS 7 + +#define STM32_HAS_USB FALSE + +/* IWDG attributes.*/ +#define STM32_HAS_IWDG TRUE +#define STM32_IWDG_IS_WINDOWED FALSE + +/* LTDC attributes.*/ +#define STM32_HAS_LTDC TRUE + +/* DMA2D attributes.*/ +#define STM32_HAS_DMA2D TRUE + +/* FSMC attributes.*/ +#define STM32_HAS_FSMC TRUE +#define STM32_FSMC_IS_FMC TRUE +#define STM32_FSMC_HANDLER Vector100 +#define STM32_FSMC_NUMBER 48 + +/* CRC attributes.*/ +#define STM32_HAS_CRC TRUE +#define STM32_CRC_PROGRAMMABLE FALSE + +#endif /* defined(STM32F469_479xx) */ + +/*===========================================================================*/ +/* STM32F446xx. */ +/*===========================================================================*/ + +#if defined(STM32F446xx) + +/* Clock tree attributes.*/ +#define STM32_HAS_RCC_PLLSAI TRUE +#define STM32_HAS_RCC_PLLI2S TRUE +#define STM32_HAS_RCC_DCKCFGR TRUE +#define STM32_HAS_RCC_DCKCFGR2 TRUE +#define STM32_HAS_RCC_I2SSRC FALSE +#define STM32_HAS_RCC_I2SPLLSRC FALSE +#define STM32_HAS_RCC_CK48MSEL TRUE +#define STM32_RCC_CK48MSEL_USES_I2S FALSE +#define STM32_PLL48CLK_ALTSRC STM32_PLLSAI_P_CLKOUT +#define STM32_TIMPRE_PRESCALE4 TRUE + +/* ADC attributes.*/ +#define STM32_ADC_HANDLER Vector88 +#define STM32_ADC_NUMBER 18 + +#define STM32_HAS_ADC1 TRUE +#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_ADC1_DMA_CHN 0x00000000 + +#define STM32_HAS_ADC2 TRUE +#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 3)) +#define STM32_ADC2_DMA_CHN 0x00001100 + +#define STM32_HAS_ADC3 TRUE +#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 1)) +#define STM32_ADC3_DMA_CHN 0x00000022 + +#define STM32_HAS_ADC4 FALSE + +#define STM32_HAS_SDADC1 FALSE +#define STM32_HAS_SDADC2 FALSE +#define STM32_HAS_SDADC3 FALSE + +/* CAN attributes.*/ +#define STM32_HAS_CAN1 TRUE +#define STM32_HAS_CAN2 TRUE +#define STM32_HAS_CAN3 FALSE +#define STM32_CAN_MAX_FILTERS 28 + +/* DAC attributes.*/ +#define STM32_HAS_DAC1_CH1 TRUE +#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_DAC1_CH1_DMA_CHN 0x00700000 + +#define STM32_HAS_DAC1_CH2 TRUE +#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_DAC1_CH2_DMA_CHN 0x07000000 + +#define STM32_HAS_DAC2_CH1 FALSE +#define STM32_HAS_DAC2_CH2 FALSE + +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA TRUE +#define STM32_DMA_CACHE_HANDLING FALSE +#define STM32_DMA_SUPPORTS_DMAMUX FALSE + +#define STM32_HAS_DMA1 TRUE +#define STM32_DMA1_CH0_HANDLER Vector6C +#define STM32_DMA1_CH1_HANDLER Vector70 +#define STM32_DMA1_CH2_HANDLER Vector74 +#define STM32_DMA1_CH3_HANDLER Vector78 +#define STM32_DMA1_CH4_HANDLER Vector7C +#define STM32_DMA1_CH5_HANDLER Vector80 +#define STM32_DMA1_CH6_HANDLER Vector84 +#define STM32_DMA1_CH7_HANDLER VectorFC +#define STM32_DMA1_CH0_NUMBER 11 +#define STM32_DMA1_CH1_NUMBER 12 +#define STM32_DMA1_CH2_NUMBER 13 +#define STM32_DMA1_CH3_NUMBER 14 +#define STM32_DMA1_CH4_NUMBER 15 +#define STM32_DMA1_CH5_NUMBER 16 +#define STM32_DMA1_CH6_NUMBER 17 +#define STM32_DMA1_CH7_NUMBER 47 + +#define STM32_HAS_DMA2 TRUE +#define STM32_DMA2_CH0_HANDLER Vector120 +#define STM32_DMA2_CH1_HANDLER Vector124 +#define STM32_DMA2_CH2_HANDLER Vector128 +#define STM32_DMA2_CH3_HANDLER Vector12C +#define STM32_DMA2_CH4_HANDLER Vector130 +#define STM32_DMA2_CH5_HANDLER Vector150 +#define STM32_DMA2_CH6_HANDLER Vector154 +#define STM32_DMA2_CH7_HANDLER Vector158 +#define STM32_DMA2_CH0_NUMBER 56 +#define STM32_DMA2_CH1_NUMBER 57 +#define STM32_DMA2_CH2_NUMBER 58 +#define STM32_DMA2_CH3_NUMBER 59 +#define STM32_DMA2_CH4_NUMBER 60 +#define STM32_DMA2_CH5_NUMBER 68 +#define STM32_DMA2_CH6_NUMBER 69 +#define STM32_DMA2_CH7_NUMBER 70 + +/* ETH attributes.*/ +#define STM32_HAS_ETH FALSE + +/* EXTI attributes.*/ +#define STM32_EXTI_NUM_LINES 23 +#define STM32_EXTI_IMR1_MASK 0x00000000U + +/* GPIO attributes.*/ +#define STM32_HAS_GPIOA TRUE +#define STM32_HAS_GPIOB TRUE +#define STM32_HAS_GPIOC TRUE +#define STM32_HAS_GPIOD TRUE +#define STM32_HAS_GPIOE TRUE +#define STM32_HAS_GPIOF TRUE +#define STM32_HAS_GPIOG TRUE +#define STM32_HAS_GPIOH TRUE +#define STM32_HAS_GPIOI FALSE +#define STM32_HAS_GPIOJ FALSE +#define STM32_HAS_GPIOK FALSE + +#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ + RCC_AHB1ENR_GPIOBEN | \ + RCC_AHB1ENR_GPIOCEN | \ + RCC_AHB1ENR_GPIODEN | \ + RCC_AHB1ENR_GPIOEEN | \ + RCC_AHB1ENR_GPIOFEN | \ + RCC_AHB1ENR_GPIOGEN | \ + RCC_AHB1ENR_GPIOHEN) + +/* I2C attributes.*/ +#define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C1_RX_DMA_CHN 0x00100001 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ + STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_I2C1_TX_DMA_CHN 0x11000000 + +#define STM32_HAS_I2C2 TRUE +#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ + STM32_DMA_STREAM_ID_MSK(1, 3)) +#define STM32_I2C2_RX_DMA_CHN 0x00007700 +#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) +#define STM32_I2C2_TX_DMA_CHN 0x70000000 + +#define STM32_HAS_I2C3 TRUE +#define STM32_I2C3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_I2C3_RX_DMA_CHN 0x00000300 +#define STM32_I2C3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_I2C3_TX_DMA_CHN 0x00030000 + +#define STM32_HAS_I2C4 FALSE + +/* QUADSPI attributes.*/ +#define STM32_HAS_QUADSPI1 TRUE +#define STM32_QUADSPI1_HANDLER Vector1B0 +#define STM32_QUADSPI1_NUMBER 92 +#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) +#define STM32_QUADSPI1_DMA_CHN 0x30000000 + +/* SDIO attributes.*/ +#define STM32_HAS_SDIO TRUE +#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SDC_SDIO_DMA_CHN 0x04004000 + +/* SPI attributes.*/ +#define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_SUPPORTS_I2S TRUE +#define STM32_SPI1_I2S_FULLDUPLEX FALSE +#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_SPI1_RX_DMA_CHN 0x00000303 +#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI1_TX_DMA_CHN 0x00303000 + +#define STM32_HAS_SPI2 TRUE +#define STM32_SPI2_SUPPORTS_I2S TRUE +#define STM32_SPI2_I2S_FULLDUPLEX FALSE +#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI3 TRUE +#define STM32_SPI3_SUPPORTS_I2S TRUE +#define STM32_SPI3_I2S_FULLDUPLEX FALSE +#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ + STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_SPI3_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI4 TRUE +#define STM32_SPI4_SUPPORTS_I2S FALSE +#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 3)) +#define STM32_SPI4_RX_DMA_CHN 0x00005004 +#define STM32_SPI4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_SPI4_TX_DMA_CHN 0x00050040 + +#define STM32_HAS_SPI5 FALSE +#define STM32_HAS_SPI6 FALSE + +/* TIM attributes.*/ +#define STM32_TIM_MAX_CHANNELS 4 + +#define STM32_HAS_TIM1 TRUE +#define STM32_TIM1_IS_32BITS FALSE +#define STM32_TIM1_CHANNELS 4 + +#define STM32_HAS_TIM2 TRUE +#define STM32_TIM2_IS_32BITS TRUE +#define STM32_TIM2_CHANNELS 4 + +#define STM32_HAS_TIM3 TRUE +#define STM32_TIM3_IS_32BITS FALSE +#define STM32_TIM3_CHANNELS 4 + +#define STM32_HAS_TIM4 TRUE +#define STM32_TIM4_IS_32BITS FALSE +#define STM32_TIM4_CHANNELS 4 + +#define STM32_HAS_TIM5 TRUE +#define STM32_TIM5_IS_32BITS TRUE +#define STM32_TIM5_CHANNELS 4 + +#define STM32_HAS_TIM6 TRUE +#define STM32_TIM6_IS_32BITS FALSE +#define STM32_TIM6_CHANNELS 0 + +#define STM32_HAS_TIM7 TRUE +#define STM32_TIM7_IS_32BITS FALSE +#define STM32_TIM7_CHANNELS 0 + +#define STM32_HAS_TIM8 TRUE +#define STM32_TIM8_IS_32BITS FALSE +#define STM32_TIM8_CHANNELS 4 + +#define STM32_HAS_TIM9 TRUE +#define STM32_TIM9_IS_32BITS FALSE +#define STM32_TIM9_CHANNELS 2 + +#define STM32_HAS_TIM10 TRUE +#define STM32_TIM10_IS_32BITS FALSE +#define STM32_TIM10_CHANNELS 1 + +#define STM32_HAS_TIM11 TRUE +#define STM32_TIM11_IS_32BITS FALSE +#define STM32_TIM11_CHANNELS 1 + +#define STM32_HAS_TIM12 TRUE +#define STM32_TIM12_IS_32BITS FALSE +#define STM32_TIM12_CHANNELS 2 + +#define STM32_HAS_TIM13 TRUE +#define STM32_TIM13_IS_32BITS FALSE +#define STM32_TIM13_CHANNELS 1 + +#define STM32_HAS_TIM14 TRUE +#define STM32_TIM14_IS_32BITS FALSE +#define STM32_TIM14_CHANNELS 1 + +#define STM32_HAS_TIM15 FALSE +#define STM32_HAS_TIM16 FALSE +#define STM32_HAS_TIM17 FALSE +#define STM32_HAS_TIM18 FALSE +#define STM32_HAS_TIM19 FALSE +#define STM32_HAS_TIM20 FALSE +#define STM32_HAS_TIM21 FALSE +#define STM32_HAS_TIM22 FALSE + +/* USART attributes.*/ +#define STM32_HAS_USART1 TRUE +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_USART1_RX_DMA_CHN 0x00400400 +#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) +#define STM32_USART1_TX_DMA_CHN 0x40000000 + +#define STM32_HAS_USART2 TRUE +#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) +#define STM32_USART2_RX_DMA_CHN 0x00400000 +#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) +#define STM32_USART2_TX_DMA_CHN 0x04000000 + +#define STM32_HAS_USART3 TRUE +#define STM32_USART3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) +#define STM32_USART3_RX_DMA_CHN 0x00000040 +#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\ + STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_USART3_TX_DMA_CHN 0x00074000 + +#define STM32_HAS_UART4 TRUE +#define STM32_UART4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_UART4_RX_DMA_CHN 0x00000400 +#define STM32_UART4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_UART4_TX_DMA_CHN 0x00040000 + +#define STM32_HAS_UART5 TRUE +#define STM32_UART5_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) +#define STM32_UART5_RX_DMA_CHN 0x00000004 +#define STM32_UART5_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) +#define STM32_UART5_TX_DMA_CHN 0x40000000 + +#define STM32_HAS_USART6 TRUE +#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_USART6_RX_DMA_CHN 0x00000550 +#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ + STM32_DMA_STREAM_ID_MSK(2, 7)) +#define STM32_USART6_TX_DMA_CHN 0x55000000 + +#define STM32_HAS_UART7 FALSE +#define STM32_HAS_UART8 FALSE +#define STM32_HAS_LPUART1 FALSE + +/* USB attributes.*/ +#define STM32_OTG_STEPPING 2 +#define STM32_HAS_OTG1 TRUE +#define STM32_OTG1_ENDPOINTS 5 +#define STM32_HAS_OTG2 TRUE +#define STM32_OTG2_ENDPOINTS 7 + +#define STM32_HAS_USB FALSE + +/* IWDG attributes.*/ +#define STM32_HAS_IWDG TRUE +#define STM32_IWDG_IS_WINDOWED FALSE + +/* LTDC attributes.*/ +#define STM32_HAS_LTDC TRUE + +/* DMA2D attributes.*/ +#define STM32_HAS_DMA2D TRUE + +/* FSMC attributes.*/ +#define STM32_HAS_FSMC TRUE +#define STM32_FSMC_IS_FMC TRUE +#define STM32_FSMC_HANDLER Vector100 +#define STM32_FSMC_NUMBER 48 + +/* CRC attributes.*/ +#define STM32_HAS_CRC TRUE +#define STM32_CRC_PROGRAMMABLE FALSE + +#endif /* defined(STM32F446xx) */ + +/*===========================================================================*/ +/* STM32F439xx, STM32F429xx, STM32F437xx, STM32F427xx. */ +/*===========================================================================*/ + +#if defined(STM32F429_439xx) || defined(STM32F427_437xx) + +/* Clock tree attributes.*/ +#define STM32_HAS_RCC_PLLSAI TRUE +#define STM32_HAS_RCC_PLLI2S TRUE +#define STM32_HAS_RCC_DCKCFGR TRUE +#define STM32_HAS_RCC_DCKCFGR2 FALSE +#define STM32_HAS_RCC_I2SSRC TRUE +#define STM32_HAS_RCC_I2SPLLSRC FALSE +#define STM32_HAS_RCC_CK48MSEL FALSE +#define STM32_RCC_CK48MSEL_USES_I2S FALSE +#define STM32_TIMPRE_PRESCALE4 TRUE + +/* ADC attributes.*/ +#define STM32_ADC_HANDLER Vector88 +#define STM32_ADC_NUMBER 18 + +#define STM32_HAS_ADC1 TRUE +#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_ADC1_DMA_CHN 0x00000000 + +#define STM32_HAS_ADC2 TRUE +#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 3)) +#define STM32_ADC2_DMA_CHN 0x00001100 + +#define STM32_HAS_ADC3 TRUE +#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 1)) +#define STM32_ADC3_DMA_CHN 0x00000022 + +#define STM32_HAS_ADC4 FALSE + +#define STM32_HAS_SDADC1 FALSE +#define STM32_HAS_SDADC2 FALSE +#define STM32_HAS_SDADC3 FALSE + +/* CAN attributes.*/ +#define STM32_HAS_CAN1 TRUE +#define STM32_HAS_CAN2 TRUE +#define STM32_HAS_CAN3 FALSE +#define STM32_CAN_MAX_FILTERS 28 + +/* DAC attributes.*/ +#define STM32_HAS_DAC1_CH1 TRUE +#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_DAC1_CH1_DMA_CHN 0x00700000 + +#define STM32_HAS_DAC1_CH2 TRUE +#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_DAC1_CH2_DMA_CHN 0x07000000 + +#define STM32_HAS_DAC2_CH1 FALSE +#define STM32_HAS_DAC2_CH2 FALSE + +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA TRUE +#define STM32_DMA_CACHE_HANDLING FALSE +#define STM32_DMA_SUPPORTS_DMAMUX FALSE + +#define STM32_HAS_DMA1 TRUE +#define STM32_DMA1_CH0_HANDLER Vector6C +#define STM32_DMA1_CH1_HANDLER Vector70 +#define STM32_DMA1_CH2_HANDLER Vector74 +#define STM32_DMA1_CH3_HANDLER Vector78 +#define STM32_DMA1_CH4_HANDLER Vector7C +#define STM32_DMA1_CH5_HANDLER Vector80 +#define STM32_DMA1_CH6_HANDLER Vector84 +#define STM32_DMA1_CH7_HANDLER VectorFC +#define STM32_DMA1_CH0_NUMBER 11 +#define STM32_DMA1_CH1_NUMBER 12 +#define STM32_DMA1_CH2_NUMBER 13 +#define STM32_DMA1_CH3_NUMBER 14 +#define STM32_DMA1_CH4_NUMBER 15 +#define STM32_DMA1_CH5_NUMBER 16 +#define STM32_DMA1_CH6_NUMBER 17 +#define STM32_DMA1_CH7_NUMBER 47 + +#define STM32_HAS_DMA2 TRUE +#define STM32_DMA2_CH0_HANDLER Vector120 +#define STM32_DMA2_CH1_HANDLER Vector124 +#define STM32_DMA2_CH2_HANDLER Vector128 +#define STM32_DMA2_CH3_HANDLER Vector12C +#define STM32_DMA2_CH4_HANDLER Vector130 +#define STM32_DMA2_CH5_HANDLER Vector150 +#define STM32_DMA2_CH6_HANDLER Vector154 +#define STM32_DMA2_CH7_HANDLER Vector158 +#define STM32_DMA2_CH0_NUMBER 56 +#define STM32_DMA2_CH1_NUMBER 57 +#define STM32_DMA2_CH2_NUMBER 58 +#define STM32_DMA2_CH3_NUMBER 59 +#define STM32_DMA2_CH4_NUMBER 60 +#define STM32_DMA2_CH5_NUMBER 68 +#define STM32_DMA2_CH6_NUMBER 69 +#define STM32_DMA2_CH7_NUMBER 70 + +/* ETH attributes.*/ +#define STM32_HAS_ETH TRUE +#define STM32_ETH_HANDLER Vector134 +#define STM32_ETH_NUMBER 61 + +/* EXTI attributes.*/ +#define STM32_EXTI_NUM_LINES 23 +#define STM32_EXTI_IMR1_MASK 0x00000000U + +/* GPIO attributes.*/ +#define STM32_HAS_GPIOA TRUE +#define STM32_HAS_GPIOB TRUE +#define STM32_HAS_GPIOC TRUE +#define STM32_HAS_GPIOD TRUE +#define STM32_HAS_GPIOE TRUE +#define STM32_HAS_GPIOH TRUE +#define STM32_HAS_GPIOF TRUE +#define STM32_HAS_GPIOG TRUE +#define STM32_HAS_GPIOI TRUE +#define STM32_HAS_GPIOJ FALSE +#define STM32_HAS_GPIOK FALSE +#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ + RCC_AHB1ENR_GPIOBEN | \ + RCC_AHB1ENR_GPIOCEN | \ + RCC_AHB1ENR_GPIODEN | \ + RCC_AHB1ENR_GPIOEEN | \ + RCC_AHB1ENR_GPIOFEN | \ + RCC_AHB1ENR_GPIOGEN | \ + RCC_AHB1ENR_GPIOHEN | \ + RCC_AHB1ENR_GPIOIEN) + +/* I2C attributes.*/ +#define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C1_RX_DMA_CHN 0x00100001 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ + STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_I2C1_TX_DMA_CHN 0x11000000 + +#define STM32_HAS_I2C2 TRUE +#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ + STM32_DMA_STREAM_ID_MSK(1, 3)) +#define STM32_I2C2_RX_DMA_CHN 0x00007700 +#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) +#define STM32_I2C2_TX_DMA_CHN 0x70000000 + +#define STM32_HAS_I2C3 TRUE +#define STM32_I2C3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_I2C3_RX_DMA_CHN 0x00000300 +#define STM32_I2C3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_I2C3_TX_DMA_CHN 0x00030000 + +#define STM32_HAS_I2C4 FALSE + +/* QUADSPI attributes.*/ +#define STM32_HAS_QUADSPI1 FALSE + +/* SDIO attributes.*/ +#define STM32_HAS_SDIO TRUE +#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SDC_SDIO_DMA_CHN 0x04004000 + +/* SPI attributes.*/ +#define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_SUPPORTS_I2S FALSE +#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_SPI1_RX_DMA_CHN 0x00000303 +#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI1_TX_DMA_CHN 0x00303000 + +#define STM32_HAS_SPI2 TRUE +#define STM32_SPI2_SUPPORTS_I2S TRUE +#define STM32_SPI2_I2S_FULLDUPLEX TRUE +#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI3 TRUE +#define STM32_SPI3_SUPPORTS_I2S TRUE +#define STM32_SPI3_I2S_FULLDUPLEX TRUE +#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ + STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_SPI3_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI4 TRUE +#define STM32_SPI4_SUPPORTS_I2S FALSE +#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 3)) +#define STM32_SPI4_RX_DMA_CHN 0x00005004 +#define STM32_SPI4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_SPI4_TX_DMA_CHN 0x00050040 + +#define STM32_HAS_SPI5 TRUE +#define STM32_SPI5_SUPPORTS_I2S FALSE +#define STM32_SPI5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) | \ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI5_RX_DMA_CHN 0x00702000 +#define STM32_SPI5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) | \ + STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SPI5_TX_DMA_CHN 0x07020000 + +#define STM32_HAS_SPI6 TRUE +#define STM32_SPI6_SUPPORTS_I2S FALSE +#define STM32_SPI6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SPI6_RX_DMA_CHN 0x01000000 +#define STM32_SPI6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI6_TX_DMA_CHN 0x00100000 + +/* TIM attributes.*/ +#define STM32_TIM_MAX_CHANNELS 4 + +#define STM32_HAS_TIM1 TRUE +#define STM32_TIM1_IS_32BITS FALSE +#define STM32_TIM1_CHANNELS 4 + +#define STM32_HAS_TIM2 TRUE +#define STM32_TIM2_IS_32BITS TRUE +#define STM32_TIM2_CHANNELS 4 + +#define STM32_HAS_TIM3 TRUE +#define STM32_TIM3_IS_32BITS FALSE +#define STM32_TIM3_CHANNELS 4 + +#define STM32_HAS_TIM4 TRUE +#define STM32_TIM4_IS_32BITS FALSE +#define STM32_TIM4_CHANNELS 4 + +#define STM32_HAS_TIM5 TRUE +#define STM32_TIM5_IS_32BITS TRUE +#define STM32_TIM5_CHANNELS 4 + +#define STM32_HAS_TIM6 TRUE +#define STM32_TIM6_IS_32BITS FALSE +#define STM32_TIM6_CHANNELS 0 + +#define STM32_HAS_TIM7 TRUE +#define STM32_TIM7_IS_32BITS FALSE +#define STM32_TIM7_CHANNELS 0 + +#define STM32_HAS_TIM8 TRUE +#define STM32_TIM8_IS_32BITS FALSE +#define STM32_TIM8_CHANNELS 4 + +#define STM32_HAS_TIM9 TRUE +#define STM32_TIM9_IS_32BITS FALSE +#define STM32_TIM9_CHANNELS 2 + +#define STM32_HAS_TIM10 TRUE +#define STM32_TIM10_IS_32BITS FALSE +#define STM32_TIM10_CHANNELS 1 + +#define STM32_HAS_TIM11 TRUE +#define STM32_TIM11_IS_32BITS FALSE +#define STM32_TIM11_CHANNELS 1 + +#define STM32_HAS_TIM12 TRUE +#define STM32_TIM12_IS_32BITS FALSE +#define STM32_TIM12_CHANNELS 2 + +#define STM32_HAS_TIM13 TRUE +#define STM32_TIM13_IS_32BITS FALSE +#define STM32_TIM13_CHANNELS 1 + +#define STM32_HAS_TIM14 TRUE +#define STM32_TIM14_IS_32BITS FALSE +#define STM32_TIM14_CHANNELS 1 + +#define STM32_HAS_TIM15 FALSE +#define STM32_HAS_TIM16 FALSE +#define STM32_HAS_TIM17 FALSE +#define STM32_HAS_TIM18 FALSE +#define STM32_HAS_TIM19 FALSE +#define STM32_HAS_TIM20 FALSE +#define STM32_HAS_TIM21 FALSE +#define STM32_HAS_TIM22 FALSE + +/* USART attributes.*/ +#define STM32_HAS_USART1 TRUE +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_USART1_RX_DMA_CHN 0x00400400 +#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) +#define STM32_USART1_TX_DMA_CHN 0x40000000 + +#define STM32_HAS_USART2 TRUE +#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) +#define STM32_USART2_RX_DMA_CHN 0x00400000 +#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) +#define STM32_USART2_TX_DMA_CHN 0x04000000 + +#define STM32_HAS_USART3 TRUE +#define STM32_USART3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) +#define STM32_USART3_RX_DMA_CHN 0x00000040 +#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\ + STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_USART3_TX_DMA_CHN 0x00074000 + +#define STM32_HAS_UART4 TRUE +#define STM32_UART4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_UART4_RX_DMA_CHN 0x00000400 +#define STM32_UART4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_UART4_TX_DMA_CHN 0x00040000 + +#define STM32_HAS_UART5 TRUE +#define STM32_UART5_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) +#define STM32_UART5_RX_DMA_CHN 0x00000004 +#define STM32_UART5_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) +#define STM32_UART5_TX_DMA_CHN 0x40000000 + +#define STM32_HAS_USART6 TRUE +#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_USART6_RX_DMA_CHN 0x00000550 +#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ + STM32_DMA_STREAM_ID_MSK(2, 7)) +#define STM32_USART6_TX_DMA_CHN 0x55000000 + +#define STM32_HAS_UART7 TRUE +#define STM32_UART7_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_UART7_RX_DMA_CHN 0x00005000 +#define STM32_UART7_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) +#define STM32_UART7_TX_DMA_CHN 0x00000050 + +#define STM32_HAS_UART8 TRUE +#define STM32_UART8_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) +#define STM32_UART8_RX_DMA_CHN 0x05000000 +#define STM32_UART8_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) +#define STM32_UART8_TX_DMA_CHN 0x00000005 + +#define STM32_HAS_LPUART1 FALSE + +/* USB attributes.*/ +#define STM32_OTG_STEPPING 1 +#define STM32_HAS_OTG1 TRUE +#define STM32_OTG1_ENDPOINTS 3 +#define STM32_HAS_OTG2 TRUE +#define STM32_OTG2_ENDPOINTS 5 + +#define STM32_HAS_USB FALSE + +/* IWDG attributes.*/ +#define STM32_HAS_IWDG TRUE +#define STM32_IWDG_IS_WINDOWED FALSE + +/* LTDC attributes.*/ +#define STM32_HAS_LTDC TRUE + +/* DMA2D attributes.*/ +#define STM32_HAS_DMA2D TRUE + +/* FSMC attributes.*/ +#define STM32_HAS_FSMC TRUE +#define STM32_FSMC_IS_FMC TRUE +#define STM32_FSMC_HANDLER Vector100 +#define STM32_FSMC_NUMBER 48 + +/* CRC attributes.*/ +#define STM32_HAS_CRC TRUE +#define STM32_CRC_PROGRAMMABLE FALSE + +#endif /* defined(STM32F429_439xx) || defined(STM32F427_437xx) */ + +/*===========================================================================*/ +/* STM32F413xx. */ +/*===========================================================================*/ + +#if defined(STM32F413xx) + +/* Clock tree attributes.*/ +#define STM32_HAS_RCC_PLLSAI FALSE +#define STM32_HAS_RCC_PLLI2S TRUE +#define STM32_HAS_RCC_DCKCFGR TRUE +#define STM32_HAS_RCC_DCKCFGR2 TRUE +#define STM32_HAS_RCC_I2SSRC FALSE +#define STM32_HAS_RCC_I2SPLLSRC TRUE +#define STM32_HAS_RCC_CK48MSEL TRUE +#define STM32_RCC_CK48MSEL_USES_I2S TRUE +#define STM32_PLL48CLK_ALTSRC STM32_PLLI2S_Q_CLKOUT +#define STM32_TIMPRE_PRESCALE4 FALSE + +/* ADC attributes.*/ +#define STM32_ADC_HANDLER Vector88 +#define STM32_ADC_NUMBER 18 + +#define STM32_HAS_ADC1 TRUE +#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_ADC1_DMA_CHN 0x00000000 + +#define STM32_HAS_ADC2 FALSE +#define STM32_HAS_ADC3 FALSE +#define STM32_HAS_ADC4 FALSE + +#define STM32_HAS_SDADC1 FALSE +#define STM32_HAS_SDADC2 FALSE +#define STM32_HAS_SDADC3 FALSE + +/* CAN attributes.*/ +#define STM32_HAS_CAN1 TRUE +#define STM32_HAS_CAN2 TRUE +#define STM32_HAS_CAN3 TRUE +#define STM32_CAN_MAX_FILTERS 28 +#define STM32_CAN3_MAX_FILTERS 14 + +/* DAC attributes.*/ +#define STM32_HAS_DAC1_CH1 TRUE +#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_DAC1_CH1_DMA_CHN 0x00700000 + +#define STM32_HAS_DAC1_CH2 TRUE +#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_DAC1_CH2_DMA_CHN 0x07000000 + +#define STM32_HAS_DAC2_CH1 FALSE +#define STM32_HAS_DAC2_CH2 FALSE + +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA TRUE +#define STM32_DMA_CACHE_HANDLING FALSE +#define STM32_DMA_SUPPORTS_DMAMUX FALSE + +#define STM32_HAS_DMA1 TRUE +#define STM32_DMA1_CH0_HANDLER Vector6C +#define STM32_DMA1_CH1_HANDLER Vector70 +#define STM32_DMA1_CH2_HANDLER Vector74 +#define STM32_DMA1_CH3_HANDLER Vector78 +#define STM32_DMA1_CH4_HANDLER Vector7C +#define STM32_DMA1_CH5_HANDLER Vector80 +#define STM32_DMA1_CH6_HANDLER Vector84 +#define STM32_DMA1_CH7_HANDLER VectorFC +#define STM32_DMA1_CH0_NUMBER 11 +#define STM32_DMA1_CH1_NUMBER 12 +#define STM32_DMA1_CH2_NUMBER 13 +#define STM32_DMA1_CH3_NUMBER 14 +#define STM32_DMA1_CH4_NUMBER 15 +#define STM32_DMA1_CH5_NUMBER 16 +#define STM32_DMA1_CH6_NUMBER 17 +#define STM32_DMA1_CH7_NUMBER 47 + +#define STM32_HAS_DMA2 TRUE +#define STM32_DMA2_CH0_HANDLER Vector120 +#define STM32_DMA2_CH1_HANDLER Vector124 +#define STM32_DMA2_CH2_HANDLER Vector128 +#define STM32_DMA2_CH3_HANDLER Vector12C +#define STM32_DMA2_CH4_HANDLER Vector130 +#define STM32_DMA2_CH5_HANDLER Vector150 +#define STM32_DMA2_CH6_HANDLER Vector154 +#define STM32_DMA2_CH7_HANDLER Vector158 +#define STM32_DMA2_CH0_NUMBER 56 +#define STM32_DMA2_CH1_NUMBER 57 +#define STM32_DMA2_CH2_NUMBER 58 +#define STM32_DMA2_CH3_NUMBER 59 +#define STM32_DMA2_CH4_NUMBER 60 +#define STM32_DMA2_CH5_NUMBER 68 +#define STM32_DMA2_CH6_NUMBER 69 +#define STM32_DMA2_CH7_NUMBER 70 + +/* ETH attributes.*/ +#define STM32_HAS_ETH FALSE + +/* EXTI attributes.*/ +#define STM32_EXTI_NUM_LINES 23 +#define STM32_EXTI_IMR1_MASK 0x00000000U + +/* GPIO attributes.*/ +#define STM32_HAS_GPIOA TRUE +#define STM32_HAS_GPIOB TRUE +#define STM32_HAS_GPIOC TRUE +#define STM32_HAS_GPIOD TRUE +#define STM32_HAS_GPIOE TRUE +#define STM32_HAS_GPIOH TRUE +#define STM32_HAS_GPIOF TRUE +#define STM32_HAS_GPIOG TRUE +#define STM32_HAS_GPIOI FALSE +#define STM32_HAS_GPIOJ FALSE +#define STM32_HAS_GPIOK FALSE +#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ + RCC_AHB1ENR_GPIOBEN | \ + RCC_AHB1ENR_GPIOCEN | \ + RCC_AHB1ENR_GPIODEN | \ + RCC_AHB1ENR_GPIOEEN | \ + RCC_AHB1ENR_GPIOFEN | \ + RCC_AHB1ENR_GPIOGEN | \ + RCC_AHB1ENR_GPIOHEN) + +/* I2C attributes.*/ +#define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C1_RX_DMA_CHN 0x00100001 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ + STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_I2C1_TX_DMA_CHN 0x11000000 + +#define STM32_HAS_I2C2 TRUE +#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ + STM32_DMA_STREAM_ID_MSK(1, 3)) +#define STM32_I2C2_RX_DMA_CHN 0x00007700 +#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) +#define STM32_I2C2_TX_DMA_CHN 0x70000000 + +#define STM32_HAS_I2C3 TRUE +#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\ + STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_I2C3_RX_DMA_CHN 0x00000310 +#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\ + STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C3_TX_DMA_CHN 0x00630000 + +#define STM32_HAS_I2C4 TRUE +#define STM32_I2C4_SUPPORTS_FMP TRUE +#define STM32_HAS_I2C4 TRUE +#define STM32_I2C4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_I2C4_RX_DMA_CHN 0x00001000 +#define STM32_I2C4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) +#define STM32_I2C4_TX_DMA_CHN 0x00000020 + +/* QUADSPI attributes.*/ +#define STM32_HAS_QUADSPI1 TRUE +#define STM32_QUADSPI1_HANDLER Vector1B0 +#define STM32_QUADSPI1_NUMBER 92 +#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) +#define STM32_QUADSPI1_DMA_CHN 0x30000000 + +/* SDIO attributes.*/ +#define STM32_HAS_SDIO TRUE +#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SDC_SDIO_DMA_CHN 0x04004000 + +/* SPI attributes.*/ +#define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_SUPPORTS_I2S TRUE +#define STM32_SPI1_I2S_FULLDUPLEX TRUE +#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_SPI1_RX_DMA_CHN 0x00000303 +#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI1_TX_DMA_CHN 0x00303200 + +#define STM32_HAS_SPI2 TRUE +#define STM32_SPI2_SUPPORTS_I2S TRUE +#define STM32_SPI2_I2S_FULLDUPLEX TRUE +#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI3 TRUE +#define STM32_SPI3_SUPPORTS_I2S TRUE +#define STM32_SPI3_I2S_FULLDUPLEX TRUE +#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ + STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_SPI3_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI4 TRUE +#define STM32_SPI4_SUPPORTS_I2S TRUE +#define STM32_SPI4_I2S_FULLDUPLEX TRUE +#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_SPI4_RX_DMA_CHN 0x00045004 +#define STM32_SPI4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_SPI4_TX_DMA_CHN 0x00050040 + +#define STM32_HAS_SPI5 TRUE +#define STM32_SPI5_SUPPORTS_I2S TRUE +#define STM32_SPI5_I2S_FULLDUPLEX TRUE +#define STM32_SPI5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI5_RX_DMA_CHN 0x00702000 +#define STM32_SPI5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\ + STM32_DMA_STREAM_ID_MSK(2, 5) |\ + STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SPI5_TX_DMA_CHN 0x07520000 + +#define STM32_HAS_SPI6 FALSE + +/* TIM attributes.*/ +#define STM32_TIM_MAX_CHANNELS 4 + +#define STM32_HAS_TIM1 TRUE +#define STM32_TIM1_IS_32BITS FALSE +#define STM32_TIM1_CHANNELS 4 + +#define STM32_HAS_TIM2 TRUE +#define STM32_TIM2_IS_32BITS TRUE +#define STM32_TIM2_CHANNELS 4 + +#define STM32_HAS_TIM3 TRUE +#define STM32_TIM3_IS_32BITS FALSE +#define STM32_TIM3_CHANNELS 4 + +#define STM32_HAS_TIM4 TRUE +#define STM32_TIM4_IS_32BITS FALSE +#define STM32_TIM4_CHANNELS 4 + +#define STM32_HAS_TIM5 TRUE +#define STM32_TIM5_IS_32BITS TRUE +#define STM32_TIM5_CHANNELS 4 + +#define STM32_HAS_TIM6 TRUE +#define STM32_TIM6_IS_32BITS FALSE +#define STM32_TIM6_CHANNELS 0 + +#define STM32_HAS_TIM7 TRUE +#define STM32_TIM7_IS_32BITS FALSE +#define STM32_TIM7_CHANNELS 0 + +#define STM32_HAS_TIM8 TRUE +#define STM32_TIM8_IS_32BITS FALSE +#define STM32_TIM8_CHANNELS 4 + +#define STM32_HAS_TIM9 TRUE +#define STM32_TIM9_IS_32BITS FALSE +#define STM32_TIM9_CHANNELS 2 + +#define STM32_HAS_TIM10 TRUE +#define STM32_TIM10_IS_32BITS FALSE +#define STM32_TIM10_CHANNELS 1 + +#define STM32_HAS_TIM11 TRUE +#define STM32_TIM11_IS_32BITS FALSE +#define STM32_TIM11_CHANNELS 1 + +#define STM32_HAS_TIM12 TRUE +#define STM32_TIM12_IS_32BITS FALSE +#define STM32_TIM12_CHANNELS 2 + +#define STM32_HAS_TIM13 TRUE +#define STM32_TIM13_IS_32BITS FALSE +#define STM32_TIM13_CHANNELS 1 + +#define STM32_HAS_TIM14 TRUE +#define STM32_TIM14_IS_32BITS FALSE +#define STM32_TIM14_CHANNELS 1 + +#define STM32_HAS_TIM15 FALSE +#define STM32_HAS_TIM16 FALSE +#define STM32_HAS_TIM17 FALSE +#define STM32_HAS_TIM18 FALSE +#define STM32_HAS_TIM19 FALSE +#define STM32_HAS_TIM20 FALSE +#define STM32_HAS_TIM21 FALSE +#define STM32_HAS_TIM22 FALSE + +#define STM32_HAS_LPTIM1 TRUE + +/* USART attributes.*/ +#define STM32_HAS_USART1 TRUE +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_USART1_RX_DMA_CHN 0x00400400 +#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) +#define STM32_USART1_TX_DMA_CHN 0x40000000 + +#define STM32_HAS_USART2 TRUE +#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) +#define STM32_USART2_RX_DMA_CHN 0x00400000 +#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) +#define STM32_USART2_TX_DMA_CHN 0x04000000 + +#define STM32_HAS_USART3 TRUE +#define STM32_USART3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) +#define STM32_USART3_RX_DMA_CHN 0x00000040 +#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\ + STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_USART3_TX_DMA_CHN 0x00074000 + +#define STM32_HAS_UART4 TRUE +#define STM32_UART4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_UART4_RX_DMA_CHN 0x00000400 +#define STM32_UART4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_UART4_TX_DMA_CHN 0x00040000 + +#define STM32_HAS_UART5 TRUE +#define STM32_UART5_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) +#define STM32_UART5_RX_DMA_CHN 0x00000004 +#define STM32_UART5_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) +#define STM32_UART5_TX_DMA_CHN 0x80000000 + +#define STM32_HAS_USART6 TRUE +#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_USART6_RX_DMA_CHN 0x00000550 +#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ + STM32_DMA_STREAM_ID_MSK(2, 7)) +#define STM32_USART6_TX_DMA_CHN 0x55000000 + +#define STM32_HAS_UART7 TRUE +#define STM32_UART7_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_UART7_RX_DMA_CHN 0x00005000 +#define STM32_UART7_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) +#define STM32_UART7_TX_DMA_CHN 0x00000050 + +#define STM32_HAS_UART8 TRUE +#define STM32_UART8_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) +#define STM32_UART8_RX_DMA_CHN 0x05000000 +#define STM32_UART8_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) +#define STM32_UART8_TX_DMA_CHN 0x00000005 + +#define STM32_HAS_UART9 TRUE +#define STM32_UART9_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) +#define STM32_UART9_RX_DMA_CHN 0x00000000 +#define STM32_UART9_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 0) +#define STM32_UART9_TX_DMA_CHN 0x00000001 + +#define STM32_HAS_UART10 TRUE +#define STM32_UART10_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 0) +#define STM32_UART10_RX_DMA_CHN 0x00000005 +#define STM32_UART10_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) +#define STM32_UART10_TX_DMA_CHN 0x60000000 + +#define STM32_HAS_LPUART1 FALSE + +/* USB attributes.*/ +#define STM32_OTG_STEPPING 2 +#define STM32_HAS_OTG1 TRUE +#define STM32_OTG1_ENDPOINTS 5 + +#define STM32_HAS_OTG2 FALSE +#define STM32_HAS_USB FALSE + +/* IWDG attributes.*/ +#define STM32_HAS_IWDG TRUE +#define STM32_IWDG_IS_WINDOWED FALSE + +/* LTDC attributes.*/ +#define STM32_HAS_LTDC FALSE + +/* DMA2D attributes.*/ +#define STM32_HAS_DMA2D FALSE + +/* FSMC attributes.*/ +#define STM32_HAS_FSMC FALSE + +/* CRC attributes.*/ +#define STM32_HAS_CRC TRUE +#define STM32_CRC_PROGRAMMABLE FALSE + +#endif /* defined(STM32F413xx) */ + +/*===========================================================================*/ +/* STM32F412xx. */ +/*===========================================================================*/ + +#if defined(STM32F412xx) + +/* Clock tree attributes.*/ +#define STM32_HAS_RCC_PLLSAI FALSE +#define STM32_HAS_RCC_PLLI2S TRUE +#define STM32_HAS_RCC_DCKCFGR TRUE +#define STM32_HAS_RCC_DCKCFGR2 TRUE +#define STM32_HAS_RCC_I2SSRC FALSE +#define STM32_HAS_RCC_I2SPLLSRC TRUE +#define STM32_HAS_RCC_CK48MSEL TRUE +#define STM32_RCC_CK48MSEL_USES_I2S TRUE +#define STM32_PLL48CLK_ALTSRC STM32_PLLI2S_Q_CLKOUT +#define STM32_TIMPRE_PRESCALE4 FALSE + +/* ADC attributes.*/ +#define STM32_ADC_HANDLER Vector88 +#define STM32_ADC_NUMBER 18 + +#define STM32_HAS_ADC1 TRUE +#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_ADC1_DMA_CHN 0x00000000 + +#define STM32_HAS_ADC2 FALSE +#define STM32_HAS_ADC3 FALSE +#define STM32_HAS_ADC4 FALSE + +#define STM32_HAS_SDADC1 FALSE +#define STM32_HAS_SDADC2 FALSE +#define STM32_HAS_SDADC3 FALSE + +/* CAN attributes.*/ +#define STM32_HAS_CAN1 TRUE +#define STM32_HAS_CAN2 TRUE +#define STM32_HAS_CAN3 FALSE +#define STM32_CAN_MAX_FILTERS 28 + +/* DAC attributes.*/ +#define STM32_HAS_DAC1_CH1 FALSE +#define STM32_HAS_DAC1_CH2 FALSE +#define STM32_HAS_DAC2_CH1 FALSE +#define STM32_HAS_DAC2_CH2 FALSE + +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA TRUE +#define STM32_DMA_CACHE_HANDLING FALSE +#define STM32_DMA_SUPPORTS_DMAMUX FALSE + +#define STM32_HAS_DMA1 TRUE +#define STM32_DMA1_CH0_HANDLER Vector6C +#define STM32_DMA1_CH1_HANDLER Vector70 +#define STM32_DMA1_CH2_HANDLER Vector74 +#define STM32_DMA1_CH3_HANDLER Vector78 +#define STM32_DMA1_CH4_HANDLER Vector7C +#define STM32_DMA1_CH5_HANDLER Vector80 +#define STM32_DMA1_CH6_HANDLER Vector84 +#define STM32_DMA1_CH7_HANDLER VectorFC +#define STM32_DMA1_CH0_NUMBER 11 +#define STM32_DMA1_CH1_NUMBER 12 +#define STM32_DMA1_CH2_NUMBER 13 +#define STM32_DMA1_CH3_NUMBER 14 +#define STM32_DMA1_CH4_NUMBER 15 +#define STM32_DMA1_CH5_NUMBER 16 +#define STM32_DMA1_CH6_NUMBER 17 +#define STM32_DMA1_CH7_NUMBER 47 + +#define STM32_HAS_DMA2 TRUE +#define STM32_DMA2_CH0_HANDLER Vector120 +#define STM32_DMA2_CH1_HANDLER Vector124 +#define STM32_DMA2_CH2_HANDLER Vector128 +#define STM32_DMA2_CH3_HANDLER Vector12C +#define STM32_DMA2_CH4_HANDLER Vector130 +#define STM32_DMA2_CH5_HANDLER Vector150 +#define STM32_DMA2_CH6_HANDLER Vector154 +#define STM32_DMA2_CH7_HANDLER Vector158 +#define STM32_DMA2_CH0_NUMBER 56 +#define STM32_DMA2_CH1_NUMBER 57 +#define STM32_DMA2_CH2_NUMBER 58 +#define STM32_DMA2_CH3_NUMBER 59 +#define STM32_DMA2_CH4_NUMBER 60 +#define STM32_DMA2_CH5_NUMBER 68 +#define STM32_DMA2_CH6_NUMBER 69 +#define STM32_DMA2_CH7_NUMBER 70 + +/* ETH attributes.*/ +#define STM32_HAS_ETH FALSE + +/* EXTI attributes.*/ +#define STM32_EXTI_NUM_LINES 23 +#define STM32_EXTI_IMR1_MASK 0x00000000U + +/* GPIO attributes.*/ +#define STM32_HAS_GPIOA TRUE +#define STM32_HAS_GPIOB TRUE +#define STM32_HAS_GPIOC TRUE +#define STM32_HAS_GPIOD TRUE +#define STM32_HAS_GPIOE TRUE +#define STM32_HAS_GPIOH TRUE +#define STM32_HAS_GPIOF TRUE +#define STM32_HAS_GPIOG TRUE +#define STM32_HAS_GPIOI FALSE +#define STM32_HAS_GPIOJ FALSE +#define STM32_HAS_GPIOK FALSE +#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ + RCC_AHB1ENR_GPIOBEN | \ + RCC_AHB1ENR_GPIOCEN | \ + RCC_AHB1ENR_GPIODEN | \ + RCC_AHB1ENR_GPIOEEN | \ + RCC_AHB1ENR_GPIOFEN | \ + RCC_AHB1ENR_GPIOGEN | \ + RCC_AHB1ENR_GPIOHEN) + +/* I2C attributes.*/ +#define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C1_RX_DMA_CHN 0x00100001 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\ + STM32_DMA_STREAM_ID_MSK(1, 7) |\ + STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_I2C1_TX_DMA_CHN 0x11000000 + +#define STM32_HAS_I2C2 TRUE +#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ + STM32_DMA_STREAM_ID_MSK(1, 3)) +#define STM32_I2C2_RX_DMA_CHN 0x00007700 +#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) +#define STM32_I2C2_TX_DMA_CHN 0x70000000 + +#define STM32_HAS_I2C3 TRUE +#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\ + STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_I2C3_RX_DMA_CHN 0x00000310 +#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\ + STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C3_TX_DMA_CHN 0x00630000 + +#define STM32_HAS_I2C4 FALSE + +/* QUADSPI attributes.*/ +#define STM32_HAS_QUADSPI1 TRUE +#define STM32_QUADSPI1_HANDLER Vector1B0 +#define STM32_QUADSPI1_NUMBER 92 +#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) +#define STM32_QUADSPI1_DMA_CHN 0x30000000 + +/* SDIO attributes.*/ +#define STM32_HAS_SDIO TRUE +#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SDC_SDIO_DMA_CHN 0x04004000 + +/* SPI attributes.*/ +#define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_SUPPORTS_I2S TRUE +#define STM32_SPI1_I2S_FULLDUPLEX TRUE +#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_SPI1_RX_DMA_CHN 0x00000303 +#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI1_TX_DMA_CHN 0x00303000 + +#define STM32_HAS_SPI2 TRUE +#define STM32_SPI2_SUPPORTS_I2S TRUE +#define STM32_SPI2_I2S_FULLDUPLEX TRUE +#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI3 TRUE +#define STM32_SPI3_SUPPORTS_I2S TRUE +#define STM32_SPI3_I2S_FULLDUPLEX TRUE +#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ + STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_SPI3_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI4 TRUE +#define STM32_SPI4_SUPPORTS_I2S TRUE +#define STM32_SPI4_I2S_FULLDUPLEX TRUE +#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_SPI4_RX_DMA_CHN 0x00045004 +#define STM32_SPI4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_SPI4_TX_DMA_CHN 0x00050040 + +#define STM32_HAS_SPI5 TRUE +#define STM32_SPI5_SUPPORTS_I2S TRUE +#define STM32_SPI5_I2S_FULLDUPLEX TRUE +#define STM32_SPI5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI5_RX_DMA_CHN 0x00702000 +#define STM32_SPI5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\ + STM32_DMA_STREAM_ID_MSK(2, 5) |\ + STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SPI5_TX_DMA_CHN 0x07520000 + +#define STM32_HAS_SPI6 FALSE + +/* TIM attributes.*/ +#define STM32_TIM_MAX_CHANNELS 4 + +#define STM32_HAS_TIM1 TRUE +#define STM32_TIM1_IS_32BITS FALSE +#define STM32_TIM1_CHANNELS 4 + +#define STM32_HAS_TIM2 TRUE +#define STM32_TIM2_IS_32BITS TRUE +#define STM32_TIM2_CHANNELS 4 + +#define STM32_HAS_TIM3 TRUE +#define STM32_TIM3_IS_32BITS FALSE +#define STM32_TIM3_CHANNELS 4 + +#define STM32_HAS_TIM4 TRUE +#define STM32_TIM4_IS_32BITS FALSE +#define STM32_TIM4_CHANNELS 4 + +#define STM32_HAS_TIM5 TRUE +#define STM32_TIM5_IS_32BITS TRUE +#define STM32_TIM5_CHANNELS 4 + +#define STM32_HAS_TIM6 TRUE +#define STM32_TIM6_IS_32BITS FALSE +#define STM32_TIM6_CHANNELS 0 + +#define STM32_HAS_TIM7 TRUE +#define STM32_TIM7_IS_32BITS FALSE +#define STM32_TIM7_CHANNELS 0 + +#define STM32_HAS_TIM9 TRUE +#define STM32_TIM9_IS_32BITS FALSE +#define STM32_TIM9_CHANNELS 2 + +#define STM32_HAS_TIM10 TRUE +#define STM32_TIM10_IS_32BITS FALSE +#define STM32_TIM10_CHANNELS 1 + +#define STM32_HAS_TIM11 TRUE +#define STM32_TIM11_IS_32BITS FALSE +#define STM32_TIM11_CHANNELS 1 + +#define STM32_HAS_TIM12 TRUE +#define STM32_TIM12_IS_32BITS FALSE +#define STM32_TIM12_CHANNELS 2 + +#define STM32_HAS_TIM13 TRUE +#define STM32_TIM13_IS_32BITS FALSE +#define STM32_TIM13_CHANNELS 1 + +#define STM32_HAS_TIM14 TRUE +#define STM32_TIM14_IS_32BITS FALSE +#define STM32_TIM14_CHANNELS 1 + +#define STM32_HAS_TIM8 FALSE +#define STM32_HAS_TIM15 FALSE +#define STM32_HAS_TIM16 FALSE +#define STM32_HAS_TIM17 FALSE +#define STM32_HAS_TIM18 FALSE +#define STM32_HAS_TIM19 FALSE +#define STM32_HAS_TIM20 FALSE +#define STM32_HAS_TIM21 FALSE +#define STM32_HAS_TIM22 FALSE + +/* USART attributes.*/ +#define STM32_HAS_USART1 TRUE +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_USART1_RX_DMA_CHN 0x00400400 +#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) +#define STM32_USART1_TX_DMA_CHN 0x40000000 + +#define STM32_HAS_USART2 TRUE +#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) +#define STM32_USART2_RX_DMA_CHN 0x00400000 +#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) +#define STM32_USART2_TX_DMA_CHN 0x04000000 + +#define STM32_HAS_USART3 TRUE +#define STM32_USART3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) +#define STM32_USART3_RX_DMA_CHN 0x00000040 +#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\ + STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_USART3_TX_DMA_CHN 0x00074000 + +#define STM32_HAS_USART6 TRUE +#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_USART6_RX_DMA_CHN 0x00000550 +#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ + STM32_DMA_STREAM_ID_MSK(2, 7)) +#define STM32_USART6_TX_DMA_CHN 0x55000000 + +#define STM32_HAS_UART4 FALSE +#define STM32_HAS_UART5 FALSE +#define STM32_HAS_UART7 FALSE +#define STM32_HAS_UART8 FALSE +#define STM32_HAS_LPUART1 FALSE + +/* USB attributes.*/ +#define STM32_OTG_STEPPING 2 +#define STM32_HAS_OTG1 TRUE +#define STM32_OTG1_ENDPOINTS 5 + +#define STM32_HAS_OTG2 FALSE +#define STM32_HAS_USB FALSE + +/* IWDG attributes.*/ +#define STM32_HAS_IWDG TRUE +#define STM32_IWDG_IS_WINDOWED FALSE + +/* LTDC attributes.*/ +#define STM32_HAS_LTDC FALSE + +/* DMA2D attributes.*/ +#define STM32_HAS_DMA2D FALSE + +/* FSMC attributes.*/ +#define STM32_HAS_FSMC FALSE + +/* CRC attributes.*/ +#define STM32_HAS_CRC TRUE +#define STM32_CRC_PROGRAMMABLE FALSE + +#endif /* defined(STM32F412xx) */ + +/*===========================================================================*/ +/* STM32F411xx. */ +/*===========================================================================*/ + +#if defined(STM32F411xx) + +/* Clock tree attributes.*/ +#define STM32_HAS_RCC_PLLSAI FALSE +#define STM32_HAS_RCC_PLLI2S TRUE +#define STM32_HAS_RCC_DCKCFGR TRUE +#define STM32_HAS_RCC_DCKCFGR2 FALSE +#define STM32_HAS_RCC_I2SSRC TRUE +#define STM32_HAS_RCC_I2SPLLSRC FALSE +#define STM32_HAS_RCC_CK48MSEL FALSE +#define STM32_RCC_CK48MSEL_USES_I2S FALSE +#define STM32_PLL48CLK_ALTSRC STM32_PLLSAI_Q_CLKOUT +#define STM32_TIMPRE_PRESCALE4 FALSE + +/* ADC attributes.*/ +#define STM32_ADC_HANDLER Vector88 +#define STM32_ADC_NUMBER 18 + +#define STM32_HAS_ADC1 TRUE +#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_ADC1_DMA_CHN 0x00000000 + +#define STM32_HAS_ADC2 FALSE +#define STM32_HAS_ADC3 FALSE +#define STM32_HAS_ADC4 FALSE + +#define STM32_HAS_SDADC1 FALSE +#define STM32_HAS_SDADC2 FALSE +#define STM32_HAS_SDADC3 FALSE + +/* CAN attributes.*/ +#define STM32_HAS_CAN1 FALSE +#define STM32_HAS_CAN2 FALSE +#define STM32_HAS_CAN3 FALSE + +/* DAC attributes.*/ +#define STM32_HAS_DAC1_CH1 FALSE +#define STM32_HAS_DAC1_CH2 FALSE +#define STM32_HAS_DAC2_CH1 FALSE +#define STM32_HAS_DAC2_CH2 FALSE + +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA TRUE +#define STM32_DMA_CACHE_HANDLING FALSE +#define STM32_DMA_SUPPORTS_DMAMUX FALSE + +#define STM32_HAS_DMA1 TRUE +#define STM32_DMA1_CH0_HANDLER Vector6C +#define STM32_DMA1_CH1_HANDLER Vector70 +#define STM32_DMA1_CH2_HANDLER Vector74 +#define STM32_DMA1_CH3_HANDLER Vector78 +#define STM32_DMA1_CH4_HANDLER Vector7C +#define STM32_DMA1_CH5_HANDLER Vector80 +#define STM32_DMA1_CH6_HANDLER Vector84 +#define STM32_DMA1_CH7_HANDLER VectorFC +#define STM32_DMA1_CH0_NUMBER 11 +#define STM32_DMA1_CH1_NUMBER 12 +#define STM32_DMA1_CH2_NUMBER 13 +#define STM32_DMA1_CH3_NUMBER 14 +#define STM32_DMA1_CH4_NUMBER 15 +#define STM32_DMA1_CH5_NUMBER 16 +#define STM32_DMA1_CH6_NUMBER 17 +#define STM32_DMA1_CH7_NUMBER 47 + +#define STM32_HAS_DMA2 TRUE +#define STM32_DMA2_CH0_HANDLER Vector120 +#define STM32_DMA2_CH1_HANDLER Vector124 +#define STM32_DMA2_CH2_HANDLER Vector128 +#define STM32_DMA2_CH3_HANDLER Vector12C +#define STM32_DMA2_CH4_HANDLER Vector130 +#define STM32_DMA2_CH5_HANDLER Vector150 +#define STM32_DMA2_CH6_HANDLER Vector154 +#define STM32_DMA2_CH7_HANDLER Vector158 +#define STM32_DMA2_CH0_NUMBER 56 +#define STM32_DMA2_CH1_NUMBER 57 +#define STM32_DMA2_CH2_NUMBER 58 +#define STM32_DMA2_CH3_NUMBER 59 +#define STM32_DMA2_CH4_NUMBER 60 +#define STM32_DMA2_CH5_NUMBER 68 +#define STM32_DMA2_CH6_NUMBER 69 +#define STM32_DMA2_CH7_NUMBER 70 + +/* ETH attributes.*/ +#define STM32_HAS_ETH FALSE + +/* EXTI attributes.*/ +#define STM32_EXTI_NUM_LINES 23 +#define STM32_EXTI_IMR1_MASK 0x00000000U + +/* GPIO attributes.*/ +#define STM32_HAS_GPIOA TRUE +#define STM32_HAS_GPIOB TRUE +#define STM32_HAS_GPIOC TRUE +#define STM32_HAS_GPIOD TRUE +#define STM32_HAS_GPIOE TRUE +#define STM32_HAS_GPIOH TRUE +#define STM32_HAS_GPIOF FALSE +#define STM32_HAS_GPIOG FALSE +#define STM32_HAS_GPIOI FALSE +#define STM32_HAS_GPIOJ FALSE +#define STM32_HAS_GPIOK FALSE +#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ + RCC_AHB1ENR_GPIOBEN | \ + RCC_AHB1ENR_GPIOCEN | \ + RCC_AHB1ENR_GPIODEN | \ + RCC_AHB1ENR_GPIOEEN | \ + RCC_AHB1ENR_GPIOHEN) + +/* I2C attributes.*/ +#define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C1_RX_DMA_CHN 0x00100001 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ + STM32_DMA_STREAM_ID_MSK(1, 6) |\ + STM32_DMA_STREAM_ID_MSK(1, 1)) +#define STM32_I2C1_TX_DMA_CHN 0x11000000 + +#define STM32_HAS_I2C2 TRUE +#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ + STM32_DMA_STREAM_ID_MSK(1, 3)) +#define STM32_I2C2_RX_DMA_CHN 0x00007700 +#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) +#define STM32_I2C2_TX_DMA_CHN 0x70000000 + +#define STM32_HAS_I2C3 TRUE +#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\ ++ STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_I2C3_RX_DMA_CHN 0x00000310 +#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\ ++ STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C3_TX_DMA_CHN 0x00630000 + +#define STM32_HAS_I2C4 FALSE + +/* QUADSPI attributes.*/ +#define STM32_HAS_QUADSPI1 FALSE + +/* SDIO attributes.*/ +#define STM32_HAS_SDIO TRUE +#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SDC_SDIO_DMA_CHN 0x04004000 + +/* SPI attributes.*/ +#define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_SUPPORTS_I2S TRUE +#define STM32_SPI1_I2S_FULLDUPLEX TRUE +#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_SPI1_RX_DMA_CHN 0x00000303 +#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI1_TX_DMA_CHN 0x00303000 + +#define STM32_HAS_SPI2 TRUE +#define STM32_SPI2_SUPPORTS_I2S TRUE +#define STM32_SPI2_I2S_FULLDUPLEX TRUE +#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI3 TRUE +#define STM32_SPI3_SUPPORTS_I2S TRUE +#define STM32_SPI3_I2S_FULLDUPLEX TRUE +#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ + STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_SPI3_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI4 TRUE +#define STM32_SPI4_SUPPORTS_I2S TRUE +#define STM32_SPI4_I2S_FULLDUPLEX TRUE +#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 3)) +#define STM32_SPI4_RX_DMA_CHN 0x00005004 +#define STM32_SPI4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_SPI4_TX_DMA_CHN 0x00050040 + +#define STM32_HAS_SPI5 TRUE +#define STM32_SPI5_SUPPORTS_I2S TRUE +#define STM32_SPI5_I2S_FULLDUPLEX TRUE +#define STM32_SPI5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI5_RX_DMA_CHN 0x00702000 +#define STM32_SPI5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\ + STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SPI5_TX_DMA_CHN 0x07020000 + +#define STM32_HAS_SPI6 FALSE + +/* TIM attributes.*/ +#define STM32_TIM_MAX_CHANNELS 4 + +#define STM32_HAS_TIM1 TRUE +#define STM32_TIM1_IS_32BITS FALSE +#define STM32_TIM1_CHANNELS 4 + +#define STM32_HAS_TIM2 TRUE +#define STM32_TIM2_IS_32BITS TRUE +#define STM32_TIM2_CHANNELS 4 + +#define STM32_HAS_TIM3 TRUE +#define STM32_TIM3_IS_32BITS FALSE +#define STM32_TIM3_CHANNELS 4 + +#define STM32_HAS_TIM4 TRUE +#define STM32_TIM4_IS_32BITS FALSE +#define STM32_TIM4_CHANNELS 4 + +#define STM32_HAS_TIM5 TRUE +#define STM32_TIM5_IS_32BITS TRUE +#define STM32_TIM5_CHANNELS 4 + +#define STM32_HAS_TIM9 TRUE +#define STM32_TIM9_IS_32BITS FALSE +#define STM32_TIM9_CHANNELS 2 + +#define STM32_HAS_TIM10 TRUE +#define STM32_TIM10_IS_32BITS FALSE +#define STM32_TIM10_CHANNELS 1 + +#define STM32_HAS_TIM11 TRUE +#define STM32_TIM11_IS_32BITS FALSE +#define STM32_TIM11_CHANNELS 1 + +#define STM32_HAS_TIM6 FALSE +#define STM32_HAS_TIM7 FALSE +#define STM32_HAS_TIM8 FALSE +#define STM32_HAS_TIM12 FALSE +#define STM32_HAS_TIM13 FALSE +#define STM32_HAS_TIM14 FALSE +#define STM32_HAS_TIM15 FALSE +#define STM32_HAS_TIM16 FALSE +#define STM32_HAS_TIM17 FALSE +#define STM32_HAS_TIM18 FALSE +#define STM32_HAS_TIM19 FALSE +#define STM32_HAS_TIM20 FALSE +#define STM32_HAS_TIM21 FALSE +#define STM32_HAS_TIM22 FALSE + +/* USART attributes.*/ +#define STM32_HAS_USART1 TRUE +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_USART1_RX_DMA_CHN 0x00400400 +#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) +#define STM32_USART1_TX_DMA_CHN 0x40000000 + +#define STM32_HAS_USART2 TRUE +#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) +#define STM32_USART2_RX_DMA_CHN 0x00400000 +#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) +#define STM32_USART2_TX_DMA_CHN 0x04000000 + +#define STM32_HAS_USART3 FALSE +#define STM32_HAS_UART4 FALSE +#define STM32_HAS_UART5 FALSE + +#define STM32_HAS_USART6 TRUE +#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_USART6_RX_DMA_CHN 0x00000550 +#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ + STM32_DMA_STREAM_ID_MSK(2, 7)) +#define STM32_USART6_TX_DMA_CHN 0x55000000 + +#define STM32_HAS_UART7 FALSE +#define STM32_HAS_UART8 FALSE +#define STM32_HAS_LPUART1 FALSE + +/* USB attributes.*/ +#define STM32_OTG_STEPPING 1 +#define STM32_HAS_OTG1 TRUE +#define STM32_OTG1_ENDPOINTS 3 + +#define STM32_HAS_OTG2 FALSE +#define STM32_HAS_USB FALSE + +/* IWDG attributes.*/ +#define STM32_HAS_IWDG TRUE +#define STM32_IWDG_IS_WINDOWED FALSE + +/* LTDC attributes.*/ +#define STM32_HAS_LTDC FALSE + +/* DMA2D attributes.*/ +#define STM32_HAS_DMA2D FALSE + +/* FSMC attributes.*/ +#define STM32_HAS_FSMC FALSE + +/* CRC attributes.*/ +#define STM32_HAS_CRC TRUE +#define STM32_CRC_PROGRAMMABLE FALSE + +#endif /* defined(STM32F411xx) */ + +/*===========================================================================*/ +/* STM32F410xx. */ +/*===========================================================================*/ + +#if defined(STM32F410xx) + +/* Clock tree attributes.*/ +#define STM32_HAS_RCC_PLLSAI FALSE +#define STM32_HAS_RCC_PLLI2S FALSE +#define STM32_HAS_RCC_DCKCFGR TRUE +#define STM32_HAS_RCC_DCKCFGR2 TRUE +#define STM32_HAS_RCC_I2SSRC FALSE +#define STM32_HAS_RCC_I2SPLLSRC FALSE +#define STM32_HAS_RCC_CK48MSEL FALSE +#define STM32_RCC_CK48MSEL_USES_I2S FALSE +#define STM32_PLL48CLK_ALTSRC STM32_PLLSAI_Q_CLKOUT +#define STM32_TIMPRE_PRESCALE4 FALSE + +/* ADC attributes.*/ +#define STM32_ADC_HANDLER Vector88 +#define STM32_ADC_NUMBER 18 + +#define STM32_HAS_ADC1 TRUE +#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_ADC1_DMA_CHN 0x00000000 + +#define STM32_HAS_ADC2 FALSE +#define STM32_HAS_ADC3 FALSE +#define STM32_HAS_ADC4 FALSE + +#define STM32_HAS_SDADC1 FALSE +#define STM32_HAS_SDADC2 FALSE +#define STM32_HAS_SDADC3 FALSE + +/* CAN attributes.*/ +#define STM32_HAS_CAN1 FALSE +#define STM32_HAS_CAN2 FALSE +#define STM32_HAS_CAN3 FALSE + +/* DAC attributes.*/ +#define STM32_HAS_DAC1_CH1 TRUE +#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_DAC1_CH1_DMA_CHN 0x00700000 + +#define STM32_HAS_DAC1_CH2 FALSE +#define STM32_HAS_DAC2_CH1 FALSE +#define STM32_HAS_DAC2_CH2 FALSE + +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA TRUE +#define STM32_DMA_CACHE_HANDLING FALSE +#define STM32_DMA_SUPPORTS_DMAMUX FALSE + +#define STM32_HAS_DMA1 TRUE +#define STM32_DMA1_CH0_HANDLER Vector6C +#define STM32_DMA1_CH1_HANDLER Vector70 +#define STM32_DMA1_CH2_HANDLER Vector74 +#define STM32_DMA1_CH3_HANDLER Vector78 +#define STM32_DMA1_CH4_HANDLER Vector7C +#define STM32_DMA1_CH5_HANDLER Vector80 +#define STM32_DMA1_CH6_HANDLER Vector84 +#define STM32_DMA1_CH7_HANDLER VectorFC +#define STM32_DMA1_CH0_NUMBER 11 +#define STM32_DMA1_CH1_NUMBER 12 +#define STM32_DMA1_CH2_NUMBER 13 +#define STM32_DMA1_CH3_NUMBER 14 +#define STM32_DMA1_CH4_NUMBER 15 +#define STM32_DMA1_CH5_NUMBER 16 +#define STM32_DMA1_CH6_NUMBER 17 +#define STM32_DMA1_CH7_NUMBER 47 + +#define STM32_HAS_DMA2 TRUE +#define STM32_DMA2_CH0_HANDLER Vector120 +#define STM32_DMA2_CH1_HANDLER Vector124 +#define STM32_DMA2_CH2_HANDLER Vector128 +#define STM32_DMA2_CH3_HANDLER Vector12C +#define STM32_DMA2_CH4_HANDLER Vector130 +#define STM32_DMA2_CH5_HANDLER Vector150 +#define STM32_DMA2_CH6_HANDLER Vector154 +#define STM32_DMA2_CH7_HANDLER Vector158 +#define STM32_DMA2_CH0_NUMBER 56 +#define STM32_DMA2_CH1_NUMBER 57 +#define STM32_DMA2_CH2_NUMBER 58 +#define STM32_DMA2_CH3_NUMBER 59 +#define STM32_DMA2_CH4_NUMBER 60 +#define STM32_DMA2_CH5_NUMBER 68 +#define STM32_DMA2_CH6_NUMBER 69 +#define STM32_DMA2_CH7_NUMBER 70 + +/* ETH attributes.*/ +#define STM32_HAS_ETH FALSE + +/* EXTI attributes.*/ +#define STM32_EXTI_NUM_LINES 23 +#define STM32_EXTI_IMR1_MASK 0x00000000U + +/* GPIO attributes.*/ +#define STM32_HAS_GPIOA TRUE +#define STM32_HAS_GPIOB TRUE +#define STM32_HAS_GPIOC TRUE +#define STM32_HAS_GPIOD FALSE +#define STM32_HAS_GPIOE FALSE +#define STM32_HAS_GPIOH TRUE +#define STM32_HAS_GPIOF FALSE +#define STM32_HAS_GPIOG FALSE +#define STM32_HAS_GPIOI FALSE +#define STM32_HAS_GPIOJ FALSE +#define STM32_HAS_GPIOK FALSE +#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ + RCC_AHB1ENR_GPIOBEN | \ + RCC_AHB1ENR_GPIOCEN | \ + RCC_AHB1ENR_GPIOHEN) + +/* I2C attributes.*/ +#define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C1_RX_DMA_CHN 0x00100001 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ + STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_I2C1_TX_DMA_CHN 0x11000000 + +#define STM32_HAS_I2C2 TRUE +#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ + STM32_DMA_STREAM_ID_MSK(1, 3)) +#define STM32_I2C2_RX_DMA_CHN 0x00007700 +#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) +#define STM32_I2C2_TX_DMA_CHN 0x70000000 + +#define STM32_HAS_I2C3 FALSE + +#define STM32_HAS_I2C4 TRUE +#define STM32_I2C4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0)) |\ + STM32_DMA_STREAM_ID_MSK(1, 3)) +#define STM32_I2C4_RX_DMA_CHN 0x00002007 +#define STM32_I2C4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) |\ + STM32_DMA_STREAM_ID_MSK(1, 1)) +#define STM32_I2C4_TX_DMA_CHN 0x00040020 + +/* QUADSPI attributes.*/ +#define STM32_HAS_QUADSPI1 FALSE + +/* SDIO attributes.*/ +#define STM32_HAS_SDIO FALSE + +/* SPI attributes.*/ +#define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_SUPPORTS_I2S TRUE +#define STM32_SPI1_I2S_FULLDUPLEX TRUE +#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_SPI1_RX_DMA_CHN 0x00000303 +#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 3)) +#define STM32_SPI1_TX_DMA_CHN 0x00003200 + +#define STM32_HAS_SPI2 TRUE +#define STM32_SPI2_SUPPORTS_I2S TRUE +#define STM32_SPI2_I2S_FULLDUPLEX TRUE +#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI5 TRUE +#define STM32_SPI5_SUPPORTS_I2S TRUE +#define STM32_SPI5_I2S_FULLDUPLEX TRUE +#define STM32_SPI5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI5_RX_DMA_CHN 0x00702000 +#define STM32_SPI5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\ + STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SPI5_TX_DMA_CHN 0x07020000 + +#define STM32_HAS_SPI3 FALSE +#define STM32_HAS_SPI4 FALSE +#define STM32_HAS_SPI6 FALSE + +/* TIM attributes.*/ +#define STM32_TIM_MAX_CHANNELS 4 + +#define STM32_HAS_TIM1 TRUE +#define STM32_TIM1_IS_32BITS FALSE +#define STM32_TIM1_CHANNELS 4 + +#define STM32_HAS_TIM5 TRUE +#define STM32_TIM5_IS_32BITS TRUE +#define STM32_TIM5_CHANNELS 4 + +#define STM32_HAS_TIM6 TRUE +#define STM32_TIM6_IS_32BITS FALSE +#define STM32_TIM6_CHANNELS 0 + +#define STM32_HAS_TIM9 TRUE +#define STM32_TIM9_IS_32BITS FALSE +#define STM32_TIM9_CHANNELS 2 + +#define STM32_HAS_TIM11 TRUE +#define STM32_TIM11_IS_32BITS FALSE +#define STM32_TIM11_CHANNELS 1 + +#define STM32_HAS_TIM2 FALSE +#define STM32_HAS_TIM3 FALSE +#define STM32_HAS_TIM4 FALSE +#define STM32_HAS_TIM7 FALSE +#define STM32_HAS_TIM8 FALSE +#define STM32_HAS_TIM10 FALSE +#define STM32_HAS_TIM12 FALSE +#define STM32_HAS_TIM13 FALSE +#define STM32_HAS_TIM14 FALSE +#define STM32_HAS_TIM15 FALSE +#define STM32_HAS_TIM16 FALSE +#define STM32_HAS_TIM17 FALSE +#define STM32_HAS_TIM18 FALSE +#define STM32_HAS_TIM19 FALSE +#define STM32_HAS_TIM20 FALSE +#define STM32_HAS_TIM21 FALSE +#define STM32_HAS_TIM22 FALSE + +/* USART attributes.*/ +#define STM32_HAS_USART1 TRUE +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_USART1_RX_DMA_CHN 0x00400400 +#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) +#define STM32_USART1_TX_DMA_CHN 0x40000000 + +#define STM32_HAS_USART2 TRUE +#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ + STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_USART2_RX_DMA_CHN 0x60400000 +#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) +#define STM32_USART2_TX_DMA_CHN 0x04000000 + +#define STM32_HAS_USART3 FALSE +#define STM32_HAS_UART4 FALSE +#define STM32_HAS_UART5 FALSE + +#define STM32_HAS_USART6 TRUE +#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_USART6_RX_DMA_CHN 0x00000550 +#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ + STM32_DMA_STREAM_ID_MSK(2, 7)) +#define STM32_USART6_TX_DMA_CHN 0x55000000 + +#define STM32_HAS_UART7 FALSE +#define STM32_HAS_UART8 FALSE +#define STM32_HAS_LPUART1 FALSE + +/* USB attributes.*/ +#define STM32_HAS_USB FALSE +#define STM32_HAS_OTG1 FALSE +#define STM32_HAS_OTG2 FALSE + +/* IWDG attributes.*/ +#define STM32_HAS_IWDG TRUE +#define STM32_IWDG_IS_WINDOWED FALSE + +/* LTDC attributes.*/ +#define STM32_HAS_LTDC FALSE + +/* DMA2D attributes.*/ +#define STM32_HAS_DMA2D FALSE + +/* FSMC attributes.*/ +#define STM32_HAS_FSMC FALSE + +/* CRC attributes.*/ +#define STM32_HAS_CRC TRUE +#define STM32_CRC_PROGRAMMABLE FALSE + +#endif /* defined(STM32F410xx) */ + +/*===========================================================================*/ +/* STM32F405xx, STM32F415xx, STM32F407xx, STM32F417xx, STM32F205xx, */ +/* STM32F215xx, STM32F207xx, STM32F217xx. */ +/*===========================================================================*/ + +#if defined(STM32F40_41xxx) || defined(STM32F2XX) + +/* Clock tree attributes.*/ +#define STM32_HAS_RCC_PLLSAI FALSE +#define STM32_HAS_RCC_PLLI2S TRUE +#define STM32_HAS_RCC_DCKCFGR FALSE +#define STM32_HAS_RCC_DCKCFGR2 FALSE +#define STM32_HAS_RCC_I2SSRC TRUE +#define STM32_HAS_RCC_I2SPLLSRC FALSE +#define STM32_HAS_RCC_CK48MSEL FALSE +#define STM32_RCC_CK48MSEL_USES_I2S FALSE +#define STM32_TIMPRE_PRESCALE4 TRUE + +/* ADC attributes.*/ +#define STM32_ADC_HANDLER Vector88 +#define STM32_ADC_NUMBER 18 + +#define STM32_HAS_ADC1 TRUE +#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_ADC1_DMA_CHN 0x00000000 + +#define STM32_HAS_ADC2 TRUE +#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 3)) +#define STM32_ADC2_DMA_CHN 0x00001100 + +#define STM32_HAS_ADC3 TRUE +#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 1)) +#define STM32_ADC3_DMA_CHN 0x00000022 + +#define STM32_HAS_ADC4 FALSE + +#define STM32_HAS_SDADC1 FALSE +#define STM32_HAS_SDADC2 FALSE +#define STM32_HAS_SDADC3 FALSE + +/* CAN attributes.*/ +#define STM32_HAS_CAN1 TRUE +#define STM32_HAS_CAN2 TRUE +#define STM32_HAS_CAN3 FALSE +#define STM32_CAN_MAX_FILTERS 28 + +/* DAC attributes.*/ +#define STM32_HAS_DAC1_CH1 TRUE +#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_DAC1_CH1_DMA_CHN 0x00700000 + +#define STM32_HAS_DAC1_CH2 TRUE +#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_DAC1_CH2_DMA_CHN 0x07000000 + +#define STM32_HAS_DAC2_CH1 FALSE +#define STM32_HAS_DAC2_CH2 FALSE + +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA TRUE +#define STM32_DMA_CACHE_HANDLING FALSE +#define STM32_DMA_SUPPORTS_DMAMUX FALSE + +#define STM32_HAS_DMA1 TRUE +#define STM32_DMA1_CH0_HANDLER Vector6C +#define STM32_DMA1_CH1_HANDLER Vector70 +#define STM32_DMA1_CH2_HANDLER Vector74 +#define STM32_DMA1_CH3_HANDLER Vector78 +#define STM32_DMA1_CH4_HANDLER Vector7C +#define STM32_DMA1_CH5_HANDLER Vector80 +#define STM32_DMA1_CH6_HANDLER Vector84 +#define STM32_DMA1_CH7_HANDLER VectorFC +#define STM32_DMA1_CH0_NUMBER 11 +#define STM32_DMA1_CH1_NUMBER 12 +#define STM32_DMA1_CH2_NUMBER 13 +#define STM32_DMA1_CH3_NUMBER 14 +#define STM32_DMA1_CH4_NUMBER 15 +#define STM32_DMA1_CH5_NUMBER 16 +#define STM32_DMA1_CH6_NUMBER 17 +#define STM32_DMA1_CH7_NUMBER 47 + +#define STM32_HAS_DMA2 TRUE +#define STM32_DMA2_CH0_HANDLER Vector120 +#define STM32_DMA2_CH1_HANDLER Vector124 +#define STM32_DMA2_CH2_HANDLER Vector128 +#define STM32_DMA2_CH3_HANDLER Vector12C +#define STM32_DMA2_CH4_HANDLER Vector130 +#define STM32_DMA2_CH5_HANDLER Vector150 +#define STM32_DMA2_CH6_HANDLER Vector154 +#define STM32_DMA2_CH7_HANDLER Vector158 +#define STM32_DMA2_CH0_NUMBER 56 +#define STM32_DMA2_CH1_NUMBER 57 +#define STM32_DMA2_CH2_NUMBER 58 +#define STM32_DMA2_CH3_NUMBER 59 +#define STM32_DMA2_CH4_NUMBER 60 +#define STM32_DMA2_CH5_NUMBER 68 +#define STM32_DMA2_CH6_NUMBER 69 +#define STM32_DMA2_CH7_NUMBER 70 + +/* ETH attributes.*/ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F205xx) || \ + defined(STM32F215xx) +#define STM32_HAS_ETH FALSE +#else +#define STM32_HAS_ETH TRUE +#define STM32_ETH_HANDLER Vector134 +#define STM32_ETH_NUMBER 61 +#endif + +/* EXTI attributes.*/ +#define STM32_EXTI_NUM_LINES 23 +#define STM32_EXTI_IMR1_MASK 0x00000000U + +/* GPIO attributes.*/ +#define STM32_HAS_GPIOA TRUE +#define STM32_HAS_GPIOB TRUE +#define STM32_HAS_GPIOC TRUE +#define STM32_HAS_GPIOD TRUE +#define STM32_HAS_GPIOE TRUE +#define STM32_HAS_GPIOH TRUE +#define STM32_HAS_GPIOF TRUE +#define STM32_HAS_GPIOG TRUE +#define STM32_HAS_GPIOI TRUE +#define STM32_HAS_GPIOJ FALSE +#define STM32_HAS_GPIOK FALSE +#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ + RCC_AHB1ENR_GPIOBEN | \ + RCC_AHB1ENR_GPIOCEN | \ + RCC_AHB1ENR_GPIODEN | \ + RCC_AHB1ENR_GPIOEEN | \ + RCC_AHB1ENR_GPIOFEN | \ + RCC_AHB1ENR_GPIOGEN | \ + RCC_AHB1ENR_GPIOHEN | \ + RCC_AHB1ENR_GPIOIEN) + +/* I2C attributes.*/ +#define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C1_RX_DMA_CHN 0x00100001 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ + STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_I2C1_TX_DMA_CHN 0x11000000 + +#define STM32_HAS_I2C2 TRUE +#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ + STM32_DMA_STREAM_ID_MSK(1, 3)) +#define STM32_I2C2_RX_DMA_CHN 0x00007700 +#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) +#define STM32_I2C2_TX_DMA_CHN 0x70000000 + +#define STM32_HAS_I2C3 TRUE +#define STM32_I2C3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_I2C3_RX_DMA_CHN 0x00000300 +#define STM32_I2C3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_I2C3_TX_DMA_CHN 0x00030000 + +#define STM32_HAS_I2C4 FALSE + +/* QUADSPI attributes.*/ +#define STM32_HAS_QUADSPI1 FALSE + +/* SDIO attributes.*/ +#define STM32_HAS_SDIO TRUE +#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SDC_SDIO_DMA_CHN 0x04004000 + +/* SPI attributes.*/ +#define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_SUPPORTS_I2S FALSE +#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_SPI1_RX_DMA_CHN 0x00000303 +#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI1_TX_DMA_CHN 0x00303000 + +#define STM32_HAS_SPI2 TRUE +#define STM32_SPI2_SUPPORTS_I2S TRUE +#define STM32_SPI2_I2S_FULLDUPLEX TRUE +#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI3 TRUE +#define STM32_SPI3_SUPPORTS_I2S TRUE +#define STM32_SPI3_I2S_FULLDUPLEX TRUE +#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ + STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_SPI3_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI4 FALSE +#define STM32_HAS_SPI5 FALSE +#define STM32_HAS_SPI6 FALSE + +/* TIM attributes.*/ +#define STM32_TIM_MAX_CHANNELS 4 + +#define STM32_HAS_TIM1 TRUE +#define STM32_TIM1_IS_32BITS FALSE +#define STM32_TIM1_CHANNELS 4 + +#define STM32_HAS_TIM2 TRUE +#define STM32_TIM2_IS_32BITS TRUE +#define STM32_TIM2_CHANNELS 4 + +#define STM32_HAS_TIM3 TRUE +#define STM32_TIM3_IS_32BITS FALSE +#define STM32_TIM3_CHANNELS 4 + +#define STM32_HAS_TIM4 TRUE +#define STM32_TIM4_IS_32BITS FALSE +#define STM32_TIM4_CHANNELS 4 + +#define STM32_HAS_TIM5 TRUE +#define STM32_TIM5_IS_32BITS TRUE +#define STM32_TIM5_CHANNELS 4 + +#define STM32_HAS_TIM6 TRUE +#define STM32_TIM6_IS_32BITS FALSE +#define STM32_TIM6_CHANNELS 0 + +#define STM32_HAS_TIM7 TRUE +#define STM32_TIM7_IS_32BITS FALSE +#define STM32_TIM7_CHANNELS 0 + +#define STM32_HAS_TIM8 TRUE +#define STM32_TIM8_IS_32BITS FALSE +#define STM32_TIM8_CHANNELS 6 + +#define STM32_HAS_TIM9 TRUE +#define STM32_TIM9_IS_32BITS FALSE +#define STM32_TIM9_CHANNELS 2 + +#define STM32_HAS_TIM10 TRUE +#define STM32_TIM10_IS_32BITS FALSE +#define STM32_TIM10_CHANNELS 1 + +#define STM32_HAS_TIM11 TRUE +#define STM32_TIM11_IS_32BITS FALSE +#define STM32_TIM11_CHANNELS 1 + +#define STM32_HAS_TIM12 TRUE +#define STM32_TIM12_IS_32BITS FALSE +#define STM32_TIM12_CHANNELS 2 + +#define STM32_HAS_TIM13 TRUE +#define STM32_TIM13_IS_32BITS FALSE +#define STM32_TIM13_CHANNELS 1 + +#define STM32_HAS_TIM14 TRUE +#define STM32_TIM14_IS_32BITS FALSE +#define STM32_TIM14_CHANNELS 1 + +#define STM32_HAS_TIM15 FALSE +#define STM32_HAS_TIM16 FALSE +#define STM32_HAS_TIM17 FALSE +#define STM32_HAS_TIM18 FALSE +#define STM32_HAS_TIM19 FALSE +#define STM32_HAS_TIM20 FALSE +#define STM32_HAS_TIM21 FALSE +#define STM32_HAS_TIM22 FALSE + +/* USART attributes.*/ +#define STM32_HAS_USART1 TRUE +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_USART1_RX_DMA_CHN 0x00400400 +#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) +#define STM32_USART1_TX_DMA_CHN 0x40000000 + +#define STM32_HAS_USART2 TRUE +#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) +#define STM32_USART2_RX_DMA_CHN 0x00400000 +#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) +#define STM32_USART2_TX_DMA_CHN 0x04000000 + +#define STM32_HAS_USART3 TRUE +#define STM32_USART3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) +#define STM32_USART3_RX_DMA_CHN 0x00000040 +#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\ + STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_USART3_TX_DMA_CHN 0x00074000 + +#define STM32_HAS_UART4 TRUE +#define STM32_UART4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_UART4_RX_DMA_CHN 0x00000400 +#define STM32_UART4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_UART4_TX_DMA_CHN 0x00040000 + +#define STM32_HAS_UART5 TRUE +#define STM32_UART5_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) +#define STM32_UART5_RX_DMA_CHN 0x00000004 +#define STM32_UART5_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) +#define STM32_UART5_TX_DMA_CHN 0x40000000 + +#define STM32_HAS_USART6 TRUE +#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_USART6_RX_DMA_CHN 0x00000550 +#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ + STM32_DMA_STREAM_ID_MSK(2, 7)) +#define STM32_USART6_TX_DMA_CHN 0x55000000 + +#define STM32_HAS_UART7 FALSE +#define STM32_HAS_UART8 FALSE +#define STM32_HAS_LPUART1 FALSE + +/* USB attributes.*/ +#define STM32_OTG_STEPPING 1 +#define STM32_HAS_OTG1 TRUE +#define STM32_OTG1_ENDPOINTS 3 +#define STM32_HAS_OTG2 TRUE +#define STM32_OTG2_ENDPOINTS 5 + +#define STM32_HAS_USB FALSE + +/* IWDG attributes.*/ +#define STM32_HAS_IWDG TRUE +#define STM32_IWDG_IS_WINDOWED FALSE + +/* LTDC attributes.*/ +#define STM32_HAS_LTDC FALSE + +/* DMA2D attributes.*/ +#define STM32_HAS_DMA2D FALSE + +/* FSMC attributes.*/ +#define STM32_HAS_FSMC TRUE +#define STM32_FSMC_IS_FMC FALSE + +/* CRC attributes.*/ +#define STM32_HAS_CRC TRUE +#define STM32_CRC_PROGRAMMABLE FALSE + +#endif /* defined(STM32F40_41xxx) || defined(STM32F2XX) */ + +/*===========================================================================*/ +/* STM32F401xx. */ +/*===========================================================================*/ + +#if defined(STM32F401xx) + +/* Clock tree attributes.*/ +#define STM32_HAS_RCC_PLLSAI FALSE +#define STM32_HAS_RCC_PLLI2S TRUE +#define STM32_HAS_RCC_DCKCFGR TRUE +#define STM32_HAS_RCC_DCKCFGR2 FALSE +#define STM32_HAS_RCC_I2SSRC TRUE +#define STM32_HAS_RCC_I2SPLLSRC FALSE +#define STM32_HAS_RCC_CK48MSEL FALSE +#define STM32_RCC_CK48MSEL_USES_I2S FALSE +#define STM32_TIMPRE_PRESCALE4 FALSE + +/* ADC attributes.*/ +#define STM32_ADC_HANDLER Vector88 +#define STM32_ADC_NUMBER 18 + +#define STM32_HAS_ADC1 TRUE +#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_ADC1_DMA_CHN 0x00000000 + +#define STM32_HAS_ADC2 TRUE +#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 3)) +#define STM32_ADC2_DMA_CHN 0x00001100 + +#define STM32_HAS_ADC3 TRUE +#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 1)) +#define STM32_ADC3_DMA_CHN 0x00000022 + +#define STM32_HAS_ADC4 FALSE + +#define STM32_HAS_SDADC1 FALSE +#define STM32_HAS_SDADC2 FALSE +#define STM32_HAS_SDADC3 FALSE + +/* CAN attributes.*/ +#define STM32_HAS_CAN1 TRUE +#define STM32_HAS_CAN2 TRUE +#define STM32_HAS_CAN3 FALSE +#define STM32_CAN_MAX_FILTERS 28 + +/* DAC attributes.*/ +#define STM32_HAS_DAC1_CH1 FALSE +#define STM32_HAS_DAC1_CH2 FALSE +#define STM32_HAS_DAC2_CH1 FALSE +#define STM32_HAS_DAC2_CH2 FALSE + +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA TRUE +#define STM32_DMA_CACHE_HANDLING FALSE +#define STM32_DMA_SUPPORTS_DMAMUX FALSE + +#define STM32_HAS_DMA1 TRUE +#define STM32_DMA1_CH0_HANDLER Vector6C +#define STM32_DMA1_CH1_HANDLER Vector70 +#define STM32_DMA1_CH2_HANDLER Vector74 +#define STM32_DMA1_CH3_HANDLER Vector78 +#define STM32_DMA1_CH4_HANDLER Vector7C +#define STM32_DMA1_CH5_HANDLER Vector80 +#define STM32_DMA1_CH6_HANDLER Vector84 +#define STM32_DMA1_CH7_HANDLER VectorFC +#define STM32_DMA1_CH0_NUMBER 11 +#define STM32_DMA1_CH1_NUMBER 12 +#define STM32_DMA1_CH2_NUMBER 13 +#define STM32_DMA1_CH3_NUMBER 14 +#define STM32_DMA1_CH4_NUMBER 15 +#define STM32_DMA1_CH5_NUMBER 16 +#define STM32_DMA1_CH6_NUMBER 17 +#define STM32_DMA1_CH7_NUMBER 47 + +#define STM32_HAS_DMA2 TRUE +#define STM32_DMA2_CH0_HANDLER Vector120 +#define STM32_DMA2_CH1_HANDLER Vector124 +#define STM32_DMA2_CH2_HANDLER Vector128 +#define STM32_DMA2_CH3_HANDLER Vector12C +#define STM32_DMA2_CH4_HANDLER Vector130 +#define STM32_DMA2_CH5_HANDLER Vector150 +#define STM32_DMA2_CH6_HANDLER Vector154 +#define STM32_DMA2_CH7_HANDLER Vector158 +#define STM32_DMA2_CH0_NUMBER 56 +#define STM32_DMA2_CH1_NUMBER 57 +#define STM32_DMA2_CH2_NUMBER 58 +#define STM32_DMA2_CH3_NUMBER 59 +#define STM32_DMA2_CH4_NUMBER 60 +#define STM32_DMA2_CH5_NUMBER 68 +#define STM32_DMA2_CH6_NUMBER 69 +#define STM32_DMA2_CH7_NUMBER 70 + +/* ETH attributes.*/ +#define STM32_HAS_ETH FALSE + +/* EXTI attributes.*/ +#define STM32_EXTI_NUM_LINES 23 +#define STM32_EXTI_IMR1_MASK 0x00000000U + +/* GPIO attributes.*/ +#define STM32_HAS_GPIOA TRUE +#define STM32_HAS_GPIOB TRUE +#define STM32_HAS_GPIOC TRUE +#define STM32_HAS_GPIOD TRUE +#define STM32_HAS_GPIOE TRUE +#define STM32_HAS_GPIOH TRUE +#define STM32_HAS_GPIOF FALSE +#define STM32_HAS_GPIOG FALSE +#define STM32_HAS_GPIOI FALSE +#define STM32_HAS_GPIOJ FALSE +#define STM32_HAS_GPIOK FALSE +#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ + RCC_AHB1ENR_GPIOBEN | \ + RCC_AHB1ENR_GPIOCEN | \ + RCC_AHB1ENR_GPIODEN | \ + RCC_AHB1ENR_GPIOEEN) + +/* I2C attributes.*/ +#define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C1_RX_DMA_CHN 0x00100001 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ + STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_I2C1_TX_DMA_CHN 0x11000000 + +#define STM32_HAS_I2C2 TRUE +#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ + STM32_DMA_STREAM_ID_MSK(1, 3)) +#define STM32_I2C2_RX_DMA_CHN 0x00007700 +#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) +#define STM32_I2C2_TX_DMA_CHN 0x70000000 + +#define STM32_HAS_I2C3 TRUE +#define STM32_I2C3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_I2C3_RX_DMA_CHN 0x00000300 +#define STM32_I2C3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_I2C3_TX_DMA_CHN 0x00030000 + +#define STM32_HAS_I2C4 FALSE + +/* QUADSPI attributes.*/ +#define STM32_HAS_QUADSPI1 FALSE + +/* SDIO attributes.*/ +#define STM32_HAS_SDIO TRUE +#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SDC_SDIO_DMA_CHN 0x04004000 + +/* SPI attributes.*/ +#define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_SUPPORTS_I2S FALSE +#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_SPI1_RX_DMA_CHN 0x00000303 +#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI1_TX_DMA_CHN 0x00303000 + +#define STM32_HAS_SPI2 TRUE +#define STM32_SPI2_SUPPORTS_I2S TRUE +#define STM32_SPI2_I2S_FULLDUPLEX TRUE +#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI3 TRUE +#define STM32_SPI3_SUPPORTS_I2S TRUE +#define STM32_SPI3_I2S_FULLDUPLEX TRUE +#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ + STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_SPI3_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI4 TRUE +#define STM32_SPI4_SUPPORTS_I2S FALSE +#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 3)) +#define STM32_SPI4_RX_DMA_CHN 0x00005004 +#define STM32_SPI4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_SPI4_TX_DMA_CHN 0x00050040 + +#define STM32_HAS_SPI5 FALSE +#define STM32_HAS_SPI6 FALSE + +/* TIM attributes.*/ +#define STM32_TIM_MAX_CHANNELS 4 + +#define STM32_HAS_TIM1 TRUE +#define STM32_TIM1_IS_32BITS FALSE +#define STM32_TIM1_CHANNELS 4 + +#define STM32_HAS_TIM2 TRUE +#define STM32_TIM2_IS_32BITS TRUE +#define STM32_TIM2_CHANNELS 4 + +#define STM32_HAS_TIM3 TRUE +#define STM32_TIM3_IS_32BITS FALSE +#define STM32_TIM3_CHANNELS 4 + +#define STM32_HAS_TIM4 TRUE +#define STM32_TIM4_IS_32BITS FALSE +#define STM32_TIM4_CHANNELS 4 + +#define STM32_HAS_TIM5 TRUE +#define STM32_TIM5_IS_32BITS TRUE +#define STM32_TIM5_CHANNELS 4 + +#define STM32_HAS_TIM9 TRUE +#define STM32_TIM9_IS_32BITS FALSE +#define STM32_TIM9_CHANNELS 2 + +#define STM32_HAS_TIM10 TRUE +#define STM32_TIM10_IS_32BITS FALSE +#define STM32_TIM10_CHANNELS 1 + +#define STM32_HAS_TIM11 TRUE +#define STM32_TIM11_IS_32BITS FALSE +#define STM32_TIM11_CHANNELS 1 + +#define STM32_HAS_TIM6 FALSE +#define STM32_HAS_TIM7 FALSE +#define STM32_HAS_TIM8 FALSE +#define STM32_HAS_TIM12 FALSE +#define STM32_HAS_TIM13 FALSE +#define STM32_HAS_TIM14 FALSE +#define STM32_HAS_TIM15 FALSE +#define STM32_HAS_TIM16 FALSE +#define STM32_HAS_TIM17 FALSE +#define STM32_HAS_TIM18 FALSE +#define STM32_HAS_TIM19 FALSE +#define STM32_HAS_TIM20 FALSE +#define STM32_HAS_TIM21 FALSE +#define STM32_HAS_TIM22 FALSE + +/* USART attributes.*/ +#define STM32_HAS_USART1 TRUE +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_USART1_RX_DMA_CHN 0x00400400 +#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) +#define STM32_USART1_TX_DMA_CHN 0x40000000 + +#define STM32_HAS_USART2 TRUE +#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) +#define STM32_USART2_RX_DMA_CHN 0x00400000 +#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) +#define STM32_USART2_TX_DMA_CHN 0x04000000 + +#define STM32_HAS_USART3 FALSE +#define STM32_HAS_UART4 FALSE +#define STM32_HAS_UART5 FALSE + +#define STM32_HAS_USART6 TRUE +#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_USART6_RX_DMA_CHN 0x00000550 +#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ + STM32_DMA_STREAM_ID_MSK(2, 7)) +#define STM32_USART6_TX_DMA_CHN 0x55000000 + +#define STM32_HAS_UART7 FALSE +#define STM32_HAS_UART8 FALSE +#define STM32_HAS_LPUART1 FALSE + +/* USB attributes.*/ +#define STM32_OTG_STEPPING 1 +#define STM32_HAS_OTG1 TRUE +#define STM32_OTG1_ENDPOINTS 3 +#define STM32_HAS_OTG2 FALSE + +#define STM32_HAS_USB FALSE + +/* IWDG attributes.*/ +#define STM32_HAS_IWDG TRUE +#define STM32_IWDG_IS_WINDOWED FALSE + +/* LTDC attributes.*/ +#define STM32_HAS_LTDC FALSE + +/* DMA2D attributes.*/ +#define STM32_HAS_DMA2D FALSE + +/* FSMC attributes.*/ +#define STM32_HAS_FSMC FALSE + +/* CRC attributes.*/ +#define STM32_HAS_CRC TRUE +#define STM32_CRC_PROGRAMMABLE FALSE + +#endif /* defined(STM32F401xx) */ +/** @} */ + +#endif /* STM32_REGISTRY_H */ + +/** @} */ From 14fb62efdcc9a1a3c11d4adb1b105b3e6d1b163c Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 11 Apr 2023 08:23:33 +0000 Subject: [PATCH 23/53] Small fix to STM32F4xx EFL driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16213 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/STM32F4xx/hal_efl_lld.c | 288 ++++++++++++++++++++- os/hal/ports/STM32/STM32F4xx/hal_efl_lld.h | 49 +++- 2 files changed, 325 insertions(+), 12 deletions(-) diff --git a/os/hal/ports/STM32/STM32F4xx/hal_efl_lld.c b/os/hal/ports/STM32/STM32F4xx/hal_efl_lld.c index bfaf5dff08..e03ecee1ba 100644 --- a/os/hal/ports/STM32/STM32F4xx/hal_efl_lld.c +++ b/os/hal/ports/STM32/STM32F4xx/hal_efl_lld.c @@ -48,6 +48,10 @@ #define FLASH_SR_OPERR FLASH_SR_SOP #endif +#if !defined(STM32_FLASH_DUAL_BANK_PERMANENT) +#define STM32_FLASH_DUAL_BANK_PERMANENT FALSE +#endif + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -61,8 +65,8 @@ EFlashDriver EFLD1; /* Driver local variables and types. */ /*===========================================================================*/ -#if defined(STM32F413xx) || defined(STM32F412xx) || defined(STM32F40_41xxx) \ - || defined(__DOXYGEN__) +#if defined(STM32F413xx) || defined(STM32F412xx) || \ + defined(STM32F40_41xxx) || defined(__DOXYGEN__) /* Sector table for 1.5M device. */ static const flash_sector_descriptor_t efl_lld_sect1[STM32_FLASH1_SECTORS_TOTAL] = { @@ -137,6 +141,250 @@ static const efl_lld_size_t efl_lld_flash_sizes[] = { .desc = efl_lld_size2 } }; +#elif defined(STM32F401xx) || defined(STM32F411xx) || \ + defined(__DOXYGEN__) + +/* Sector table for 128k device. */ +static const flash_sector_descriptor_t efl_lld_sect1[STM32_FLASH1_SECTORS_TOTAL] = { + { 0, 16384}, /* Sector 0. */ + { 1 * 16384, 16384}, /* Sector 1. */ + { 2 * 16384, 16384}, /* Sector 2. */ + { 3 * 16384, 16384}, /* Sector 3. */ + { 4 * 16384, 65536}, /* Sector 4. */ +}; + +/* Sector table for 256k device. */ +static const flash_sector_descriptor_t efl_lld_sect2[STM32_FLASH2_SECTORS_TOTAL] = { + { 0, 16384}, /* Sector 0. */ + { 1 * 16384, 16384}, /* Sector 1. */ + { 2 * 16384, 16384}, /* Sector 2. */ + { 3 * 16384, 16384}, /* Sector 3. */ + { 4 * 16384, 65536}, /* Sector 4. */ + { 4 * 16384 + 65536, 131072}, /* Sector 5. */ +}; + +/* Sector table for 384k device. */ +static const flash_sector_descriptor_t efl_lld_sect3[STM32_FLASH3_SECTORS_TOTAL] = { + { 0, 16384}, /* Sector 0. */ + { 1 * 16384, 16384}, /* Sector 1. */ + { 2 * 16384, 16384}, /* Sector 2. */ + { 3 * 16384, 16384}, /* Sector 3. */ + { 4 * 16384, 65536}, /* Sector 4. */ + { 4 * 16384 + 65536, 131072}, /* Sector 5. */ + { 4 * 16384 + 65536 + 1 * 131072, 131072}, /* Sector 6. */ +}; + +/* Sector table for 512k device. */ +static const flash_sector_descriptor_t efl_lld_sect4[STM32_FLASH4_SECTORS_TOTAL] = { + { 0, 16384}, /* Sector 0. */ + { 1 * 16384, 16384}, /* Sector 1. */ + { 2 * 16384, 16384}, /* Sector 2. */ + { 3 * 16384, 16384}, /* Sector 3. */ + { 4 * 16384, 65536}, /* Sector 4. */ + { 4 * 16384 + 65536, 131072}, /* Sector 5. */ + { 4 * 16384 + 65536 + 1 * 131072, 131072}, /* Sector 6. */ + { 4 * 16384 + 65536 + 2 * 131072, 131072}, /* Sector 7. */ +}; + +/* The descriptors for 128k device. */ +static const flash_descriptor_t efl_lld_size1[STM32_FLASH_NUMBER_OF_BANKS] = { + { /* Single bank organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH1_SECTORS_TOTAL, + .sectors = efl_lld_sect1, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH1_SIZE * STM32_FLASH_SIZE_SCALE + } +}; + +/* The descriptors for 256k device. */ +static const flash_descriptor_t efl_lld_size2[STM32_FLASH_NUMBER_OF_BANKS] = { + { /* Single bank organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH2_SECTORS_TOTAL, + .sectors = efl_lld_sect2, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH2_SIZE * STM32_FLASH_SIZE_SCALE + } +}; + +/* The descriptors for 384k device. */ +static const flash_descriptor_t efl_lld_size3[STM32_FLASH_NUMBER_OF_BANKS] = { + { /* Single bank organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH3_SECTORS_TOTAL, + .sectors = efl_lld_sect3, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH3_SIZE * STM32_FLASH_SIZE_SCALE + } +}; + +/* The descriptors for 512k device. */ +static const flash_descriptor_t efl_lld_size4[STM32_FLASH_NUMBER_OF_BANKS] = { + { /* Single bank organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH4_SECTORS_TOTAL, + .sectors = efl_lld_sect4, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH4_SIZE * STM32_FLASH_SIZE_SCALE + } +}; + +/* Table describing possible flash sizes and descriptors for this device. */ +static const efl_lld_size_t efl_lld_flash_sizes[] = { + { + .desc = efl_lld_size1 + }, + { + .desc = efl_lld_size2 + }, + { + .desc = efl_lld_size3 + }, + { + .desc = efl_lld_size4 + } +}; +#elif defined(STM32F429_439xx) || defined(STM32F427_437xx) || \ + defined(__DOXYGEN__) + +/* Sector table for 1M device in SBM. */ +static const flash_sector_descriptor_t efl_lld_sect_1m_sbm[STM32_FLASH_SECTORS_TOTAL_1M_SBM] = { + { 0, 16384}, /* Sector 0. */ + { 1 * 16384, 16384}, /* Sector 1. */ + { 2 * 16384, 16384}, /* Sector 2. */ + { 3 * 16384, 16384}, /* Sector 3. */ + { 4 * 16384, 65536}, /* Sector 4. */ + { 4 * 16384 + 1 * 65536, 131072}, /* Sector 5. */ + { 4 * 16384 + 1 * 65536 + 1 * 131072, 131072}, /* Sector 6. */ + { 4 * 16384 + 1 * 65536 + 2 * 131072, 131072}, /* Sector 7. */ + { 4 * 16384 + 1 * 65536 + 3 * 131072, 131072}, /* Sector 8. */ + { 4 * 16384 + 1 * 65536 + 4 * 131072, 131072}, /* Sector 9. */ + { 4 * 16384 + 1 * 65536 + 5 * 131072, 131072}, /* Sector 10. */ + { 4 * 16384 + 1 * 65536 + 6 * 131072, 131072} /* Sector 11. */ +}; + +/* Sector table for 1M device in DBM. */ +static const flash_sector_descriptor_t efl_lld_sect_1m_dbm[STM32_FLASH_SECTORS_TOTAL_1M_DBM] = { + { 0, 16384}, /* Sector 0. */ + { 1 * 16384, 16384}, /* Sector 1. */ + { 2 * 16384, 16384}, /* Sector 2. */ + { 3 * 16384, 16384}, /* Sector 3. */ + { 4 * 16384, 65536}, /* Sector 4. */ + { 4 * 16384 + 1 * 65536, 131072}, /* Sector 5. */ + { 4 * 16384 + 1 * 65536 + 1 * 131072, 131072}, /* Sector 6. */ + { 4 * 16384 + 1 * 65536 + 2 * 131072, 131072}, /* Sector 7. */ + { 4 * 16384 + 1 * 65536 + 3 * 131072, 0}, /* Invalid. */ + { 4 * 16384 + 1 * 65536 + 3 * 131072, 0}, /* Invalid. */ + { 4 * 16384 + 1 * 65536 + 3 * 131072, 0}, /* Invalid. */ + { 4 * 16384 + 1 * 65536 + 3 * 131072, 0}, /* Invalid. */ + { 4 * 16384 + 1 * 65536 + 3 * 131072, 16384}, /* Sector 12. */ + { 5 * 16384 + 1 * 65536 + 3 * 131072, 16384}, /* Sector 13. */ + { 6 * 16384 + 1 * 65536 + 3 * 131072, 16384}, /* Sector 14. */ + { 7 * 16384 + 1 * 65536 + 3 * 131072, 16384}, /* Sector 15. */ + { 8 * 16384 + 1 * 65536 + 3 * 131072, 65536}, /* Sector 16. */ + { 8 * 16384 + 2 * 65536 + 3 * 131072, 131072}, /* Sector 17. */ + { 8 * 16384 + 2 * 65536 + 4 * 131072, 131072}, /* Sector 18. */ + { 8 * 16384 + 2 * 65536 + 5 * 131072, 131072} /* Sector 19. */ +}; + +/* Sector table for 2M device banks. */ +static const flash_sector_descriptor_t efl_lld_sect_2m[STM32_FLASH_SECTORS_TOTAL_2M] = { + { 0, 16384}, /* Sector 0. */ + { 1 * 16384, 16384}, /* Sector 1. */ + { 2 * 16384, 16384}, /* Sector 2. */ + { 3 * 16384, 16384}, /* Sector 3. */ + { 4 * 16384, 65536}, /* Sector 4. */ + { 4 * 16384 + 1 * 65536, 131072}, /* Sector 5. */ + { 4 * 16384 + 1 * 65536 + 1 * 131072, 131072}, /* Sector 6. */ + { 4 * 16384 + 1 * 65536 + 2 * 131072, 131072}, /* Sector 7. */ + { 4 * 16384 + 1 * 65536 + 3 * 131072, 131072}, /* Sector 8. */ + { 4 * 16384 + 1 * 65536 + 4 * 131072, 131072}, /* Sector 9. */ + { 4 * 16384 + 1 * 65536 + 5 * 131072, 131072}, /* Sector 10. */ + { 4 * 16384 + 1 * 65536 + 6 * 131072, 131072}, /* Sector 11. */ + { 4 * 16384 + 1 * 65536 + 7 * 131072, 16384}, /* Sector 12. */ + { 5 * 16384 + 1 * 65536 + 7 * 131072, 16384}, /* Sector 13. */ + { 6 * 16384 + 1 * 65536 + 7 * 131072, 16384}, /* Sector 14. */ + { 7 * 16384 + 1 * 65536 + 7 * 131072, 16384}, /* Sector 15. */ + { 8 * 16384 + 1 * 65536 + 7 * 131072, 65536}, /* Sector 16. */ + { 8 * 16384 + 2 * 65536 + 7 * 131072, 131072}, /* Sector 17. */ + { 8 * 16384 + 2 * 65536 + 8 * 131072, 131072}, /* Sector 18. */ + { 8 * 16384 + 2 * 65536 + 9 * 131072, 131072}, /* Sector 19. */ + { 8 * 16384 + 2 * 65536 + 10 * 131072, 131072}, /* Sector 20. */ + { 8 * 16384 + 2 * 65536 + 11 * 131072, 131072}, /* Sector 21. */ + { 8 * 16384 + 2 * 65536 + 12 * 131072, 131072}, /* Sector 22. */ + { 8 * 16384 + 2 * 65536 + 13 * 131072, 131072} /* Sector 23. */ +}; + +/* The descriptors for 1M device. */ +static const flash_descriptor_t efl_lld_size_1m[STM32_FLASH_NUMBER_OF_BANKS] = { + { /* Bank 1 (SBM) organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH_SECTORS_TOTAL_1M_SBM, + .sectors = efl_lld_sect_1m_sbm, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH_SIZE_1M * STM32_FLASH_SIZE_SCALE + }, + { /* Bank 1 & 2 (DBM) organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH_SECTORS_TOTAL_1M_DBM, + .sectors = efl_lld_sect_1m_dbm, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH_SIZE_1M * STM32_FLASH_SIZE_SCALE + } +}; + +/* The descriptors for 2M device. */ +static const flash_descriptor_t efl_lld_size_2m[STM32_FLASH_NUMBER_OF_BANKS] = { + { /* Dual bank organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH_SECTORS_TOTAL_2M, + .sectors = efl_lld_sect_2m, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH_SIZE_2M * STM32_FLASH_SIZE_SCALE + }, + { /* Dual bank organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH_SECTORS_TOTAL_2M, + .sectors = efl_lld_sect_2m, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH_SIZE_2M * STM32_FLASH_SIZE_SCALE + } +}; + +/* Table describing possible flash sizes and descriptors for this device. */ +static const efl_lld_size_t efl_lld_flash_sizes[] = { + { + .desc = efl_lld_size_1m + }, + { + .desc = efl_lld_size_2m + } +}; #else #error "This EFL driver does not support the selected device" #endif @@ -190,7 +438,7 @@ static inline size_t stm32_flash_get_size(void) { static inline bool stm32_flash_dual_bank(EFlashDriver *eflp) { #if STM32_FLASH_NUMBER_OF_BANKS > 1 - return ((eflp->flash->OPTCR & FLASH_OPTCR_DB1M) != 0U); + return ((eflp->flash->OPTCR & FLASH_OPTCR_DB1M) != 0U || STM32_FLASH_DUAL_BANK_PERMANENT); #endif (void)eflp; return false; @@ -460,9 +708,10 @@ flash_error_t efl_lld_program(void *instance, flash_offset_t offset, /** * @brief Starts a whole-device erase operation. - * @note This function only erases bank 2 if it is present. Bank 1 is not - * allowed since it is normally where the primary program is located. - * Sectors on bank 1 can be individually erased. + * @note This function only erases the unused bank if in dual bank mode. The + * currently in use bank is not allowed since it is normally where the + * currently running program is executing from. + * Sectors on the in-use bank can be individually erased. * * @param[in] ip pointer to a @p EFlashDriver instance * @return An error code. @@ -484,7 +733,7 @@ flash_error_t efl_lld_start_erase_all(void *instance) { return FLASH_BUSY_ERASING; } -#if defined(FLASH_CR_MER1) +#if defined(FLASH_CR_MER2) /* If dual bank is active then mass erase bank2. */ if (stm32_flash_dual_bank(devp)) { @@ -494,7 +743,15 @@ flash_error_t efl_lld_start_erase_all(void *instance) { /* Clearing error status bits.*/ stm32_flash_clear_status(devp); - devp->flash->CR |= FLASH_CR_MER1; + /* Erase the currently unused bank, based on Flash Bank Mode */ + if ((SYSCFG->MEMRMP & SYSCFG_MEMRMP_UFB_MODE) != 0U) { + /* Bank 2 in use, erase Bank 1 */ + devp->flash->CR |= FLASH_CR_MER; + } + else { + /* Bank 1 in use, erase Bank 2 */ + devp->flash->CR |= FLASH_CR_MER2; + } devp->flash->CR |= FLASH_CR_STRT; return FLASH_NO_ERROR; } @@ -545,6 +802,17 @@ flash_error_t efl_lld_start_erase_sector(void *instance, devp->flash->CR &= ~FLASH_CR_SNB; devp->flash->CR &= ~FLASH_CR_PSIZE; +#if defined(FLASH_CR_MER2) + /* Adjust sector value for dual-bank devices + * For STM32F42x_43x devices (dual-bank), FLASH_CR_SNB values jump to 0b10000 + * for sectors 12 and up. + */ + if (sector >= 12) { + sector -= 12; + sector |= 0x10U; + } +#endif + /* Set sector and parallelism. */ devp->flash->CR |= (sector << FLASH_CR_SNB_Pos) | (STM32_FLASH_PSIZE << FLASH_CR_PSIZE_Pos); @@ -582,8 +850,8 @@ flash_error_t efl_lld_query_erase(void *instance, uint32_t *msec) { /* Disabling the various erase control bits.*/ devp->flash->CR &= ~(FLASH_CR_MER | -#if defined(FLASH_CR_MER1) - FLASH_CR_MER1 | +#if defined(FLASH_CR_MER2) + FLASH_CR_MER2 | #endif FLASH_CR_SER); diff --git a/os/hal/ports/STM32/STM32F4xx/hal_efl_lld.h b/os/hal/ports/STM32/STM32F4xx/hal_efl_lld.h index 21614b4614..73eae8e660 100644 --- a/os/hal/ports/STM32/STM32F4xx/hal_efl_lld.h +++ b/os/hal/ports/STM32/STM32F4xx/hal_efl_lld.h @@ -51,8 +51,8 @@ /* Derived constants and error checks. */ /*===========================================================================*/ -#if defined(STM32F413xx) || defined(STM32F412xx) || defined(STM32F40_41xxx) \ - || defined(__DOXYGEN__) +#if defined(STM32F413xx) || defined(STM32F412xx) || \ + defined(STM32F40_41xxx) || defined(__DOXYGEN__) /* Flash size register. */ #define STM32_FLASH_SIZE_REGISTER 0x1FFF7A22 @@ -67,6 +67,51 @@ #define STM32_FLASH2_SIZE 1024U #define STM32_FLASH1_SECTORS_TOTAL 16 #define STM32_FLASH2_SECTORS_TOTAL 12 + +#elif defined(STM32F401xx) || defined(STM32F411xx) || \ + defined(__DOXYGEN__) + +/* Flash size register. */ +#define STM32_FLASH_SIZE_REGISTER 0x1FFF7A22 +#define STM32_FLASH_SIZE_SCALE 1024U + +/* + * Device flash size... + * + */ +#define STM32_FLASH_NUMBER_OF_BANKS 1 +#define STM32_FLASH1_SIZE 128U +#define STM32_FLASH2_SIZE 256U +#define STM32_FLASH3_SIZE 384U +#define STM32_FLASH4_SIZE 512U +#define STM32_FLASH1_SECTORS_TOTAL 5 +#define STM32_FLASH2_SECTORS_TOTAL 6 +#define STM32_FLASH3_SECTORS_TOTAL 7 +#define STM32_FLASH4_SECTORS_TOTAL 8 + +#elif defined(STM32F429_439xx) || defined(STM32F427_437xx) || \ + defined(__DOXYGEN__) + +/* Flash size register. */ +#define STM32_FLASH_SIZE_REGISTER 0x1FFF7A22 +#define STM32_FLASH_SIZE_SCALE 1024U + +/* + * Device flash size is: + * 1M for STM32F4x7/4x9 suffix G devices + * 2M for STM32F4x7/4x9 suffix I devices. + * + * For 1M devices SBM is organised as 16K x 4 + 64K + 128K x 7 sectors. + * For 1M devices DBM is organised as 16K x 4 + 64K + 128K x 3 sectors per bank. + * + * For 2M devices are organised as 16K x 4 + 64K + 128K x 7 sectors per bank. + */ +#define STM32_FLASH_NUMBER_OF_BANKS 2 +#define STM32_FLASH_SIZE_1M 1024U +#define STM32_FLASH_SIZE_2M 2048U +#define STM32_FLASH_SECTORS_TOTAL_1M_SBM 12 +#define STM32_FLASH_SECTORS_TOTAL_1M_DBM 20 +#define STM32_FLASH_SECTORS_TOTAL_2M 24 #else #error "This EFL driver does not support the selected device" #endif From 011ea8754f3318225d8577f078e51c1571e6083f Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 11 Apr 2023 11:45:28 +0000 Subject: [PATCH 24/53] Tentative USBv1 and USBv2 fix about wrong size of PMA buffers larger than 62. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16214 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.c | 1750 ++++++++++---------- 1 file changed, 876 insertions(+), 874 deletions(-) diff --git a/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.c b/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.c index 9ca5c6a53a..6ac8d38b44 100644 --- a/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.c +++ b/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.c @@ -1,874 +1,876 @@ -/* - ChibiOS - Copyright (C) 2006..2018 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 USBv1/hal_usb_lld.c - * @brief STM32 USB subsystem low level driver source. - * - * @addtogroup USB - * @{ - */ - -#include - -#include "hal.h" - -#if HAL_USE_USB || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -#define BTABLE_ADDR 0x0000 - -#define EPR_EP_TYPE_IS_ISO(bits) ((bits & EPR_EP_TYPE_MASK) == EPR_EP_TYPE_ISO) - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** @brief USB1 driver identifier.*/ -#if STM32_USB_USE_USB1 || defined(__DOXYGEN__) -USBDriver USBD1; -#endif - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/** - * @brief EP0 state. - * @note It is an union because IN and OUT endpoints are never used at the - * same time for EP0. - */ -static union { - /** - * @brief IN EP0 state. - */ - USBInEndpointState in; - /** - * @brief OUT EP0 state. - */ - USBOutEndpointState out; -} ep0_state; - -/** - * @brief Buffer for the EP0 setup packets. - */ -static uint8_t ep0setup_buffer[8]; - -/** - * @brief EP0 initialization structure. - */ -static const USBEndpointConfig ep0config = { - USB_EP_MODE_TYPE_CTRL, - _usb_ep0setup, - _usb_ep0in, - _usb_ep0out, - 0x40, - 0x40, - &ep0_state.in, - &ep0_state.out, - 1, - ep0setup_buffer -}; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Resets the packet memory allocator. - * - * @param[in] usbp pointer to the @p USBDriver object - */ -static void usb_pm_reset(USBDriver *usbp) { - - /* The first 64 bytes are reserved for the descriptors table. The effective - available RAM for endpoint buffers is just 448 bytes.*/ - usbp->pmnext = 64; -} - -/** - * @brief Resets the packet memory allocator. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] size size of the packet buffer to allocate - * @return The packet buffer address. - */ -static uint32_t usb_pm_alloc(USBDriver *usbp, size_t size) { - uint32_t next; - - next = usbp->pmnext; - usbp->pmnext += (size + 1) & ~1; - osalDbgAssert(usbp->pmnext <= STM32_USB_PMA_SIZE, "PMA overflow"); - return next; -} - -/** - * @brief Reads from a dedicated packet buffer. - * - * @param[in] ep endpoint number - * @param[out] buf buffer where to copy the packet data - * @return The size of the receivee packet. - * - * @notapi - */ -static size_t usb_packet_read_to_buffer(usbep_t ep, uint8_t *buf) { - size_t i, n; - stm32_usb_descriptor_t *udp = USB_GET_DESCRIPTOR(ep); - stm32_usb_pma_t *pmap = USB_ADDR2PTR(udp->RXADDR0); -#if STM32_USB_USE_ISOCHRONOUS - uint32_t epr = STM32_USB->EPR[ep]; - - /* Double buffering is always enabled for isochronous endpoints, and - although we overlap the two buffers for simplicity, we still need - to read from the right counter. The DTOG_RX bit indicates the buffer - that is currently in use by the USB peripheral, that is, the buffer - in which the next received packet will be stored, so we need to - read the counter of the OTHER buffer, which is where the last - received packet was stored.*/ - if (EPR_EP_TYPE_IS_ISO(epr) && ((epr & EPR_DTOG_RX) != 0U)) - n = (size_t)udp->RXCOUNT1 & RXCOUNT_COUNT_MASK; - else - n = (size_t)udp->RXCOUNT0 & RXCOUNT_COUNT_MASK; -#else - n = (size_t)udp->RXCOUNT0 & RXCOUNT_COUNT_MASK; -#endif - - i = n; - -#if STM32_USB_USE_FAST_COPY - while (i >= 16) { - uint32_t w; - - w = *(pmap + 0); - *(buf + 0) = (uint8_t)w; - *(buf + 1) = (uint8_t)(w >> 8); - w = *(pmap + 1); - *(buf + 2) = (uint8_t)w; - *(buf + 3) = (uint8_t)(w >> 8); - w = *(pmap + 2); - *(buf + 4) = (uint8_t)w; - *(buf + 5) = (uint8_t)(w >> 8); - w = *(pmap + 3); - *(buf + 6) = (uint8_t)w; - *(buf + 7) = (uint8_t)(w >> 8); - w = *(pmap + 4); - *(buf + 8) = (uint8_t)w; - *(buf + 9) = (uint8_t)(w >> 8); - w = *(pmap + 5); - *(buf + 10) = (uint8_t)w; - *(buf + 11) = (uint8_t)(w >> 8); - w = *(pmap + 6); - *(buf + 12) = (uint8_t)w; - *(buf + 13) = (uint8_t)(w >> 8); - w = *(pmap + 7); - *(buf + 14) = (uint8_t)w; - *(buf + 15) = (uint8_t)(w >> 8); - - i -= 16; - buf += 16; - pmap += 8; - } -#endif /* STM32_USB_USE_FAST_COPY */ - - while (i >= 2) { - uint32_t w = *pmap++; - *buf++ = (uint8_t)w; - *buf++ = (uint8_t)(w >> 8); - i -= 2; - } - - if (i >= 1) { - *buf = (uint8_t)*pmap; - } - - return n; -} - -/** - * @brief Writes to a dedicated packet buffer. - * - * @param[in] ep endpoint number - * @param[in] buf buffer where to fetch the packet data - * @param[in] n maximum number of bytes to copy. This value must - * not exceed the maximum packet size for this endpoint. - * - * @notapi - */ -static void usb_packet_write_from_buffer(usbep_t ep, - const uint8_t *buf, - size_t n) { - stm32_usb_descriptor_t *udp = USB_GET_DESCRIPTOR(ep); - stm32_usb_pma_t *pmap = USB_ADDR2PTR(udp->TXADDR0); - int i = (int)n; - -#if STM32_USB_USE_ISOCHRONOUS - uint32_t epr = STM32_USB->EPR[ep]; - - /* Double buffering is always enabled for isochronous endpoints, and - although we overlap the two buffers for simplicity, we still need - to write to the right counter. The DTOG_TX bit indicates the buffer - that is currently in use by the USB peripheral, that is, the buffer - from which the next packet will be sent, so we need to write the - counter of that buffer.*/ - if (EPR_EP_TYPE_IS_ISO(epr) && (epr & EPR_DTOG_TX)) - udp->TXCOUNT1 = (stm32_usb_pma_t)n; - else - udp->TXCOUNT0 = (stm32_usb_pma_t)n; -#else - udp->TXCOUNT0 = (stm32_usb_pma_t)n; -#endif - -#if STM32_USB_USE_FAST_COPY - while (i >= 16) { - uint32_t w; - - w = *(buf + 0); - w |= *(buf + 1) << 8; - *(pmap + 0) = (stm32_usb_pma_t)w; - w = *(buf + 2); - w |= *(buf + 3) << 8; - *(pmap + 1) = (stm32_usb_pma_t)w; - w = *(buf + 4); - w |= *(buf + 5) << 8; - *(pmap + 2) = (stm32_usb_pma_t)w; - w = *(buf + 6); - w |= *(buf + 7) << 8; - *(pmap + 3) = (stm32_usb_pma_t)w; - w = *(buf + 8); - w |= *(buf + 9) << 8; - *(pmap + 4) = (stm32_usb_pma_t)w; - w = *(buf + 10); - w |= *(buf + 11) << 8; - *(pmap + 5) = (stm32_usb_pma_t)w; - w = *(buf + 12); - w |= *(buf + 13) << 8; - *(pmap + 6) = (stm32_usb_pma_t)w; - w = *(buf + 14); - w |= *(buf + 15) << 8; - *(pmap + 7) = (stm32_usb_pma_t)w; - - i -= 16; - buf += 16; - pmap += 8; - } -#endif /* STM32_USB_USE_FAST_COPY */ - - while (i > 0) { - uint32_t w; - - w = *buf++; - w |= *buf++ << 8; - *pmap++ = (stm32_usb_pma_t)w; - i -= 2; - } -} - -/** - * @brief Common ISR code, serves the EP-related interrupts. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -static void usb_serve_endpoints(USBDriver *usbp, uint32_t ep) { - size_t n; - uint32_t epr = STM32_USB->EPR[ep]; - const USBEndpointConfig *epcp = usbp->epc[ep]; - - if (epr & EPR_CTR_TX) { - /* IN endpoint, transmission.*/ - USBInEndpointState *isp = epcp->in_state; - - EPR_CLEAR_CTR_TX(ep); - - isp->txcnt += isp->txlast; - n = isp->txsize - isp->txcnt; - if (n > 0) { - /* Transfer not completed, there are more packets to send.*/ - if (n > epcp->in_maxsize) - n = epcp->in_maxsize; - - /* Writes the packet from the defined buffer.*/ - isp->txbuf += isp->txlast; - isp->txlast = n; - usb_packet_write_from_buffer(ep, isp->txbuf, n); - - /* Starting IN operation.*/ - EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID); - } - else { - /* Transfer completed, invokes the callback.*/ - _usb_isr_invoke_in_cb(usbp, ep); - } - } - if (epr & EPR_CTR_RX) { - /* OUT endpoint, receive.*/ - - EPR_CLEAR_CTR_RX(ep); - - if (epr & EPR_SETUP) { - /* Setup packets handling, setup packets are handled using a - specific callback.*/ - _usb_isr_invoke_setup_cb(usbp, ep); - } - else { - USBOutEndpointState *osp = epcp->out_state; - - /* Reads the packet into the defined buffer.*/ - n = usb_packet_read_to_buffer(ep, osp->rxbuf); - osp->rxbuf += n; - - /* Transaction data updated.*/ - osp->rxcnt += n; - osp->rxsize -= n; - osp->rxpkts -= 1; - - /* The transaction is completed if the specified number of packets - has been received or the current packet is a short packet.*/ - if ((n < epcp->out_maxsize) || (osp->rxpkts == 0)) { - /* Transfer complete, invokes the callback.*/ - _usb_isr_invoke_out_cb(usbp, ep); - } - else { - /* Transfer not complete, there are more packets to receive.*/ - EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID); - } - } - } -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if STM32_USB_USE_USB1 || defined(__DOXYGEN__) -#if STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER -#if STM32_USB_USE_ISOCHRONOUS -/** - * @brief USB high priority interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_USB1_HP_HANDLER) { - uint32_t istr; - USBDriver *usbp = &USBD1; - - OSAL_IRQ_PROLOGUE(); - - /* Endpoint events handling.*/ - istr = STM32_USB->ISTR; - while (istr & ISTR_CTR) { - usb_serve_endpoints(usbp, istr & ISTR_EP_ID_MASK); - istr = STM32_USB->ISTR; - } - - OSAL_IRQ_EPILOGUE(); -} -#endif /* STM32_USB_USE_ISOCHRONOUS */ -#endif /* STM32_USB1_LP_NUMBER != STM32_USB1_HP_NUMBER */ - -/** - * @brief USB low priority interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_USB1_LP_HANDLER) { - uint32_t istr; - USBDriver *usbp = &USBD1; - - OSAL_IRQ_PROLOGUE(); - - istr = STM32_USB->ISTR; - - /* USB bus reset condition handling.*/ - if (istr & ISTR_RESET) { - STM32_USB->ISTR = ~ISTR_RESET; - - _usb_reset(usbp); - } - - /* USB bus SUSPEND condition handling.*/ - if (istr & ISTR_SUSP) { - STM32_USB->CNTR |= CNTR_FSUSP; -#if STM32_USB_LOW_POWER_ON_SUSPEND - STM32_USB->CNTR |= CNTR_LP_MODE; -#endif - STM32_USB->ISTR = ~ISTR_SUSP; - - _usb_suspend(usbp); - } - - /* USB bus WAKEUP condition handling.*/ - if (istr & ISTR_WKUP) { - uint32_t fnr = STM32_USB->FNR; - if (!(fnr & FNR_RXDP)) { - STM32_USB->CNTR &= ~CNTR_FSUSP; - - _usb_wakeup(usbp); - } -#if STM32_USB_LOW_POWER_ON_SUSPEND - else { - /* Just noise, going back in SUSPEND mode, reference manual 22.4.5, - table 169.*/ - STM32_USB->CNTR |= CNTR_LP_MODE; - } -#endif - STM32_USB->ISTR = ~ISTR_WKUP; - } - - /* SOF handling.*/ - if (istr & ISTR_SOF) { - _usb_isr_invoke_sof_cb(usbp); - STM32_USB->ISTR = ~ISTR_SOF; - } - - /* Endpoint events handling.*/ - while (istr & ISTR_CTR) { - usb_serve_endpoints(usbp, istr & ISTR_EP_ID_MASK); - istr = STM32_USB->ISTR; - } - - OSAL_IRQ_EPILOGUE(); -} -#endif /* STM32_USB_USE_USB1 */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level USB driver initialization. - * - * @notapi - */ -void usb_lld_init(void) { - - /* Driver initialization.*/ - usbObjectInit(&USBD1); -} - -/** - * @brief Configures and activates the USB peripheral. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void usb_lld_start(USBDriver *usbp) { - - if (usbp->state == USB_STOP) { - /* Clock activation.*/ -#if STM32_USB_USE_USB1 - if (&USBD1 == usbp) { - /* USB clock enabled.*/ - rccEnableUSB(true); - /* Powers up the transceiver while holding the USB in reset state.*/ - STM32_USB->CNTR = CNTR_FRES; - /* Enabling the USB IRQ vectors, this also gives enough time to allow - the transceiver power up (1uS).*/ -#if STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER - nvicEnableVector(STM32_USB1_HP_NUMBER, STM32_USB_USB1_HP_IRQ_PRIORITY); -#endif - nvicEnableVector(STM32_USB1_LP_NUMBER, STM32_USB_USB1_LP_IRQ_PRIORITY); - /* Releases the USB reset.*/ - STM32_USB->CNTR = 0; - } -#endif - /* Reset procedure enforced on driver start.*/ - usb_lld_reset(usbp); - } -} - -/** - * @brief Deactivates the USB peripheral. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void usb_lld_stop(USBDriver *usbp) { - - /* If in ready state then disables the USB clock.*/ - if (usbp->state != USB_STOP) { -#if STM32_USB_USE_USB1 - if (&USBD1 == usbp) { -#if STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER - nvicDisableVector(STM32_USB1_HP_NUMBER); -#endif - nvicDisableVector(STM32_USB1_LP_NUMBER); - STM32_USB->CNTR = CNTR_PDWN | CNTR_FRES; - rccDisableUSB(); - } -#endif - } -} - -/** - * @brief USB low level reset routine. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void usb_lld_reset(USBDriver *usbp) { - uint32_t cntr; - - /* Post reset initialization.*/ - STM32_USB->BTABLE = BTABLE_ADDR; - STM32_USB->ISTR = 0; - STM32_USB->DADDR = DADDR_EF; - cntr = /*CNTR_ESOFM | */ CNTR_RESETM | CNTR_SUSPM | - CNTR_WKUPM | /*CNTR_ERRM | CNTR_PMAOVRM |*/ CNTR_CTRM; - /* The SOF interrupt is only enabled if a callback is defined for - this service because it is an high rate source.*/ - if (usbp->config->sof_cb != NULL) - cntr |= CNTR_SOFM; - STM32_USB->CNTR = cntr; - - /* Resets the packet memory allocator.*/ - usb_pm_reset(usbp); - - /* EP0 initialization.*/ - usbp->epc[0] = &ep0config; - usb_lld_init_endpoint(usbp, 0); -} - -/** - * @brief Sets the USB address. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void usb_lld_set_address(USBDriver *usbp) { - - STM32_USB->DADDR = (uint32_t)(usbp->address) | DADDR_EF; -} - -/** - * @brief Enables an endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) { - uint16_t epr; - stm32_usb_descriptor_t *dp; - const USBEndpointConfig *epcp = usbp->epc[ep]; - - /* Setting the endpoint type. Note that isochronous endpoints cannot be - bidirectional because it uses double buffering and both transmit and - receive descriptor fields are used for either direction.*/ - switch (epcp->ep_mode & USB_EP_MODE_TYPE) { - case USB_EP_MODE_TYPE_ISOC: -#if STM32_USB_USE_ISOCHRONOUS - osalDbgAssert((epcp->in_state == NULL) || (epcp->out_state == NULL), - "isochronous EP cannot be IN and OUT"); - epr = EPR_EP_TYPE_ISO; - break; -#else - osalDbgAssert(false, "isochronous support disabled"); -#endif - /* Falls through.*/ - case USB_EP_MODE_TYPE_BULK: - epr = EPR_EP_TYPE_BULK; - break; - case USB_EP_MODE_TYPE_INTR: - epr = EPR_EP_TYPE_INTERRUPT; - break; - default: - epr = EPR_EP_TYPE_CONTROL; - } - - dp = USB_GET_DESCRIPTOR(ep); - - /* IN endpoint handling.*/ - if (epcp->in_state != NULL) { - dp->TXCOUNT0 = 0; - dp->TXADDR0 = usb_pm_alloc(usbp, epcp->in_maxsize); - -#if STM32_USB_USE_ISOCHRONOUS - if (epr == EPR_EP_TYPE_ISO) { - epr |= EPR_STAT_TX_VALID; - dp->TXCOUNT1 = dp->TXCOUNT0; - dp->TXADDR1 = dp->TXADDR0; /* Both buffers overlapped.*/ - } - else { - epr |= EPR_STAT_TX_NAK; - } -#else - epr |= EPR_STAT_TX_NAK; -#endif - } - - /* OUT endpoint handling.*/ - if (epcp->out_state != NULL) { - uint16_t nblocks; - - /* Endpoint size and address initialization.*/ - if (epcp->out_maxsize > 62) - nblocks = (((((epcp->out_maxsize - 1) | 0x1f) + 1) / 32) << 10) | - 0x8000; - else - nblocks = ((((epcp->out_maxsize - 1) | 1) + 1) / 2) << 10; - dp->RXCOUNT0 = nblocks; - dp->RXADDR0 = usb_pm_alloc(usbp, epcp->out_maxsize); - -#if STM32_USB_USE_ISOCHRONOUS - if (epr == EPR_EP_TYPE_ISO) { - epr |= EPR_STAT_RX_VALID; - dp->RXCOUNT1 = dp->RXCOUNT0; - dp->RXADDR1 = dp->RXADDR0; /* Both buffers overlapped.*/ - } - else { - epr |= EPR_STAT_RX_NAK; - } -#else - epr |= EPR_STAT_RX_NAK; -#endif - } - - /* Resetting the data toggling bits for this endpoint.*/ - if (STM32_USB->EPR[ep] & EPR_DTOG_RX) { - epr |= EPR_DTOG_RX; - } - - if (STM32_USB->EPR[ep] & EPR_DTOG_TX) { - epr |= EPR_DTOG_TX; - } - - /* EPxR register setup.*/ - EPR_SET(ep, epr | ep); - EPR_TOGGLE(ep, epr); -} - -/** - * @brief Disables all the active endpoints except the endpoint zero. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void usb_lld_disable_endpoints(USBDriver *usbp) { - unsigned i; - - /* Resets the packet memory allocator.*/ - usb_pm_reset(usbp); - - /* Disabling all endpoints.*/ - for (i = 1; i <= USB_ENDOPOINTS_NUMBER; i++) { - EPR_TOGGLE(i, 0); - EPR_SET(i, 0); - } -} - -/** - * @brief Returns the status of an OUT endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @return The endpoint status. - * @retval EP_STATUS_DISABLED The endpoint is not active. - * @retval EP_STATUS_STALLED The endpoint is stalled. - * @retval EP_STATUS_ACTIVE The endpoint is active. - * - * @notapi - */ -usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) { - - (void)usbp; - switch (STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) { - case EPR_STAT_RX_DIS: - return EP_STATUS_DISABLED; - case EPR_STAT_RX_STALL: - return EP_STATUS_STALLED; - default: - return EP_STATUS_ACTIVE; - } -} - -/** - * @brief Returns the status of an IN endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @return The endpoint status. - * @retval EP_STATUS_DISABLED The endpoint is not active. - * @retval EP_STATUS_STALLED The endpoint is stalled. - * @retval EP_STATUS_ACTIVE The endpoint is active. - * - * @notapi - */ -usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) { - - (void)usbp; - switch (STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) { - case EPR_STAT_TX_DIS: - return EP_STATUS_DISABLED; - case EPR_STAT_TX_STALL: - return EP_STATUS_STALLED; - default: - return EP_STATUS_ACTIVE; - } -} - -/** - * @brief Reads a setup packet from the dedicated packet buffer. - * @details This function must be invoked in the context of the @p setup_cb - * callback in order to read the received setup packet. - * @pre In order to use this function the endpoint must have been - * initialized as a control endpoint. - * @post The endpoint is ready to accept another packet. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @param[out] buf buffer where to copy the packet data - * - * @notapi - */ -void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) { - stm32_usb_pma_t *pmap; - stm32_usb_descriptor_t *udp; - uint32_t n; - - (void)usbp; - udp = USB_GET_DESCRIPTOR(ep); - pmap = USB_ADDR2PTR(udp->RXADDR0); - for (n = 0; n < 4; n++) { - *(uint16_t *)buf = (uint16_t)*pmap++; - buf += 2; - } -} - -/** - * @brief Starts a receive operation on an OUT endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_start_out(USBDriver *usbp, usbep_t ep) { - USBOutEndpointState *osp = usbp->epc[ep]->out_state; - - /* Transfer initialization.*/ - if (osp->rxsize == 0) /* Special case for zero sized packets.*/ - osp->rxpkts = 1; - else - osp->rxpkts = (uint16_t)((osp->rxsize + usbp->epc[ep]->out_maxsize - 1) / - usbp->epc[ep]->out_maxsize); - - EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID); -} - -/** - * @brief Starts a transmit operation on an IN endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_start_in(USBDriver *usbp, usbep_t ep) { - size_t n; - USBInEndpointState *isp = usbp->epc[ep]->in_state; - - /* Transfer initialization.*/ - n = isp->txsize; - if (n > (size_t)usbp->epc[ep]->in_maxsize) - n = (size_t)usbp->epc[ep]->in_maxsize; - - isp->txlast = n; - usb_packet_write_from_buffer(ep, isp->txbuf, n); - - EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID); -} - -/** - * @brief Brings an OUT endpoint in the stalled state. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) { - - (void)usbp; - - EPR_SET_STAT_RX(ep, EPR_STAT_RX_STALL); -} - -/** - * @brief Brings an IN endpoint in the stalled state. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) { - - (void)usbp; - - EPR_SET_STAT_TX(ep, EPR_STAT_TX_STALL); -} - -/** - * @brief Brings an OUT endpoint in the active state. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) { - - (void)usbp; - - /* Makes sure to not put to NAK an endpoint that is already - transferring.*/ - if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_VALID) - EPR_SET_STAT_TX(ep, EPR_STAT_RX_NAK); -} - -/** - * @brief Brings an IN endpoint in the active state. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) { - - (void)usbp; - - /* Makes sure to not put to NAK an endpoint that is already - transferring.*/ - if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_VALID) - EPR_SET_STAT_TX(ep, EPR_STAT_TX_NAK); -} - -#endif /* HAL_USE_USB */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 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 USBv1/hal_usb_lld.c + * @brief STM32 USB subsystem low level driver source. + * + * @addtogroup USB + * @{ + */ + +#include + +#include "hal.h" + +#if HAL_USE_USB || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define BTABLE_ADDR 0x0000 + +#define EPR_EP_TYPE_IS_ISO(bits) ((bits & EPR_EP_TYPE_MASK) == EPR_EP_TYPE_ISO) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief USB1 driver identifier.*/ +#if STM32_USB_USE_USB1 || defined(__DOXYGEN__) +USBDriver USBD1; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/** + * @brief EP0 state. + * @note It is an union because IN and OUT endpoints are never used at the + * same time for EP0. + */ +static union { + /** + * @brief IN EP0 state. + */ + USBInEndpointState in; + /** + * @brief OUT EP0 state. + */ + USBOutEndpointState out; +} ep0_state; + +/** + * @brief Buffer for the EP0 setup packets. + */ +static uint8_t ep0setup_buffer[8]; + +/** + * @brief EP0 initialization structure. + */ +static const USBEndpointConfig ep0config = { + USB_EP_MODE_TYPE_CTRL, + _usb_ep0setup, + _usb_ep0in, + _usb_ep0out, + 0x40, + 0x40, + &ep0_state.in, + &ep0_state.out, + 1, + ep0setup_buffer +}; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Resets the packet memory allocator. + * + * @param[in] usbp pointer to the @p USBDriver object + */ +static void usb_pm_reset(USBDriver *usbp) { + + /* The first 64 bytes are reserved for the descriptors table. The effective + available RAM for endpoint buffers is just 448 bytes.*/ + usbp->pmnext = 64; +} + +/** + * @brief Resets the packet memory allocator. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] size size of the packet buffer to allocate + * @return The packet buffer address. + */ +static uint32_t usb_pm_alloc(USBDriver *usbp, size_t size) { + uint32_t next; + + next = usbp->pmnext; + usbp->pmnext += (size + 1) & ~1; + osalDbgAssert(usbp->pmnext <= STM32_USB_PMA_SIZE, "PMA overflow"); + return next; +} + +/** + * @brief Reads from a dedicated packet buffer. + * + * @param[in] ep endpoint number + * @param[out] buf buffer where to copy the packet data + * @return The size of the receivee packet. + * + * @notapi + */ +static size_t usb_packet_read_to_buffer(usbep_t ep, uint8_t *buf) { + size_t i, n; + stm32_usb_descriptor_t *udp = USB_GET_DESCRIPTOR(ep); + stm32_usb_pma_t *pmap = USB_ADDR2PTR(udp->RXADDR0); +#if STM32_USB_USE_ISOCHRONOUS + uint32_t epr = STM32_USB->EPR[ep]; + + /* Double buffering is always enabled for isochronous endpoints, and + although we overlap the two buffers for simplicity, we still need + to read from the right counter. The DTOG_RX bit indicates the buffer + that is currently in use by the USB peripheral, that is, the buffer + in which the next received packet will be stored, so we need to + read the counter of the OTHER buffer, which is where the last + received packet was stored.*/ + if (EPR_EP_TYPE_IS_ISO(epr) && ((epr & EPR_DTOG_RX) != 0U)) + n = (size_t)udp->RXCOUNT1 & RXCOUNT_COUNT_MASK; + else + n = (size_t)udp->RXCOUNT0 & RXCOUNT_COUNT_MASK; +#else + n = (size_t)udp->RXCOUNT0 & RXCOUNT_COUNT_MASK; +#endif + + i = n; + +#if STM32_USB_USE_FAST_COPY + while (i >= 16) { + uint32_t w; + + w = *(pmap + 0); + *(buf + 0) = (uint8_t)w; + *(buf + 1) = (uint8_t)(w >> 8); + w = *(pmap + 1); + *(buf + 2) = (uint8_t)w; + *(buf + 3) = (uint8_t)(w >> 8); + w = *(pmap + 2); + *(buf + 4) = (uint8_t)w; + *(buf + 5) = (uint8_t)(w >> 8); + w = *(pmap + 3); + *(buf + 6) = (uint8_t)w; + *(buf + 7) = (uint8_t)(w >> 8); + w = *(pmap + 4); + *(buf + 8) = (uint8_t)w; + *(buf + 9) = (uint8_t)(w >> 8); + w = *(pmap + 5); + *(buf + 10) = (uint8_t)w; + *(buf + 11) = (uint8_t)(w >> 8); + w = *(pmap + 6); + *(buf + 12) = (uint8_t)w; + *(buf + 13) = (uint8_t)(w >> 8); + w = *(pmap + 7); + *(buf + 14) = (uint8_t)w; + *(buf + 15) = (uint8_t)(w >> 8); + + i -= 16; + buf += 16; + pmap += 8; + } +#endif /* STM32_USB_USE_FAST_COPY */ + + while (i >= 2) { + uint32_t w = *pmap++; + *buf++ = (uint8_t)w; + *buf++ = (uint8_t)(w >> 8); + i -= 2; + } + + if (i >= 1) { + *buf = (uint8_t)*pmap; + } + + return n; +} + +/** + * @brief Writes to a dedicated packet buffer. + * + * @param[in] ep endpoint number + * @param[in] buf buffer where to fetch the packet data + * @param[in] n maximum number of bytes to copy. This value must + * not exceed the maximum packet size for this endpoint. + * + * @notapi + */ +static void usb_packet_write_from_buffer(usbep_t ep, + const uint8_t *buf, + size_t n) { + stm32_usb_descriptor_t *udp = USB_GET_DESCRIPTOR(ep); + stm32_usb_pma_t *pmap = USB_ADDR2PTR(udp->TXADDR0); + int i = (int)n; + +#if STM32_USB_USE_ISOCHRONOUS + uint32_t epr = STM32_USB->EPR[ep]; + + /* Double buffering is always enabled for isochronous endpoints, and + although we overlap the two buffers for simplicity, we still need + to write to the right counter. The DTOG_TX bit indicates the buffer + that is currently in use by the USB peripheral, that is, the buffer + from which the next packet will be sent, so we need to write the + counter of that buffer.*/ + if (EPR_EP_TYPE_IS_ISO(epr) && (epr & EPR_DTOG_TX)) + udp->TXCOUNT1 = (stm32_usb_pma_t)n; + else + udp->TXCOUNT0 = (stm32_usb_pma_t)n; +#else + udp->TXCOUNT0 = (stm32_usb_pma_t)n; +#endif + +#if STM32_USB_USE_FAST_COPY + while (i >= 16) { + uint32_t w; + + w = *(buf + 0); + w |= *(buf + 1) << 8; + *(pmap + 0) = (stm32_usb_pma_t)w; + w = *(buf + 2); + w |= *(buf + 3) << 8; + *(pmap + 1) = (stm32_usb_pma_t)w; + w = *(buf + 4); + w |= *(buf + 5) << 8; + *(pmap + 2) = (stm32_usb_pma_t)w; + w = *(buf + 6); + w |= *(buf + 7) << 8; + *(pmap + 3) = (stm32_usb_pma_t)w; + w = *(buf + 8); + w |= *(buf + 9) << 8; + *(pmap + 4) = (stm32_usb_pma_t)w; + w = *(buf + 10); + w |= *(buf + 11) << 8; + *(pmap + 5) = (stm32_usb_pma_t)w; + w = *(buf + 12); + w |= *(buf + 13) << 8; + *(pmap + 6) = (stm32_usb_pma_t)w; + w = *(buf + 14); + w |= *(buf + 15) << 8; + *(pmap + 7) = (stm32_usb_pma_t)w; + + i -= 16; + buf += 16; + pmap += 8; + } +#endif /* STM32_USB_USE_FAST_COPY */ + + while (i > 0) { + uint32_t w; + + w = *buf++; + w |= *buf++ << 8; + *pmap++ = (stm32_usb_pma_t)w; + i -= 2; + } +} + +/** + * @brief Common ISR code, serves the EP-related interrupts. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +static void usb_serve_endpoints(USBDriver *usbp, uint32_t ep) { + size_t n; + uint32_t epr = STM32_USB->EPR[ep]; + const USBEndpointConfig *epcp = usbp->epc[ep]; + + if (epr & EPR_CTR_TX) { + /* IN endpoint, transmission.*/ + USBInEndpointState *isp = epcp->in_state; + + EPR_CLEAR_CTR_TX(ep); + + isp->txcnt += isp->txlast; + n = isp->txsize - isp->txcnt; + if (n > 0) { + /* Transfer not completed, there are more packets to send.*/ + if (n > epcp->in_maxsize) + n = epcp->in_maxsize; + + /* Writes the packet from the defined buffer.*/ + isp->txbuf += isp->txlast; + isp->txlast = n; + usb_packet_write_from_buffer(ep, isp->txbuf, n); + + /* Starting IN operation.*/ + EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID); + } + else { + /* Transfer completed, invokes the callback.*/ + _usb_isr_invoke_in_cb(usbp, ep); + } + } + if (epr & EPR_CTR_RX) { + /* OUT endpoint, receive.*/ + + EPR_CLEAR_CTR_RX(ep); + + if (epr & EPR_SETUP) { + /* Setup packets handling, setup packets are handled using a + specific callback.*/ + _usb_isr_invoke_setup_cb(usbp, ep); + } + else { + USBOutEndpointState *osp = epcp->out_state; + + /* Reads the packet into the defined buffer.*/ + n = usb_packet_read_to_buffer(ep, osp->rxbuf); + osp->rxbuf += n; + + /* Transaction data updated.*/ + osp->rxcnt += n; + osp->rxsize -= n; + osp->rxpkts -= 1; + + /* The transaction is completed if the specified number of packets + has been received or the current packet is a short packet.*/ + if ((n < epcp->out_maxsize) || (osp->rxpkts == 0)) { + /* Transfer complete, invokes the callback.*/ + _usb_isr_invoke_out_cb(usbp, ep); + } + else { + /* Transfer not complete, there are more packets to receive.*/ + EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID); + } + } + } +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if STM32_USB_USE_USB1 || defined(__DOXYGEN__) +#if STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER +#if STM32_USB_USE_ISOCHRONOUS +/** + * @brief USB high priority interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_USB1_HP_HANDLER) { + uint32_t istr; + USBDriver *usbp = &USBD1; + + OSAL_IRQ_PROLOGUE(); + + /* Endpoint events handling.*/ + istr = STM32_USB->ISTR; + while (istr & ISTR_CTR) { + usb_serve_endpoints(usbp, istr & ISTR_EP_ID_MASK); + istr = STM32_USB->ISTR; + } + + OSAL_IRQ_EPILOGUE(); +} +#endif /* STM32_USB_USE_ISOCHRONOUS */ +#endif /* STM32_USB1_LP_NUMBER != STM32_USB1_HP_NUMBER */ + +/** + * @brief USB low priority interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_USB1_LP_HANDLER) { + uint32_t istr; + USBDriver *usbp = &USBD1; + + OSAL_IRQ_PROLOGUE(); + + istr = STM32_USB->ISTR; + + /* USB bus reset condition handling.*/ + if (istr & ISTR_RESET) { + STM32_USB->ISTR = ~ISTR_RESET; + + _usb_reset(usbp); + } + + /* USB bus SUSPEND condition handling.*/ + if (istr & ISTR_SUSP) { + STM32_USB->CNTR |= CNTR_FSUSP; +#if STM32_USB_LOW_POWER_ON_SUSPEND + STM32_USB->CNTR |= CNTR_LP_MODE; +#endif + STM32_USB->ISTR = ~ISTR_SUSP; + + _usb_suspend(usbp); + } + + /* USB bus WAKEUP condition handling.*/ + if (istr & ISTR_WKUP) { + uint32_t fnr = STM32_USB->FNR; + if (!(fnr & FNR_RXDP)) { + STM32_USB->CNTR &= ~CNTR_FSUSP; + + _usb_wakeup(usbp); + } +#if STM32_USB_LOW_POWER_ON_SUSPEND + else { + /* Just noise, going back in SUSPEND mode, reference manual 22.4.5, + table 169.*/ + STM32_USB->CNTR |= CNTR_LP_MODE; + } +#endif + STM32_USB->ISTR = ~ISTR_WKUP; + } + + /* SOF handling.*/ + if (istr & ISTR_SOF) { + _usb_isr_invoke_sof_cb(usbp); + STM32_USB->ISTR = ~ISTR_SOF; + } + + /* Endpoint events handling.*/ + while (istr & ISTR_CTR) { + usb_serve_endpoints(usbp, istr & ISTR_EP_ID_MASK); + istr = STM32_USB->ISTR; + } + + OSAL_IRQ_EPILOGUE(); +} +#endif /* STM32_USB_USE_USB1 */ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level USB driver initialization. + * + * @notapi + */ +void usb_lld_init(void) { + + /* Driver initialization.*/ + usbObjectInit(&USBD1); +} + +/** + * @brief Configures and activates the USB peripheral. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void usb_lld_start(USBDriver *usbp) { + + if (usbp->state == USB_STOP) { + /* Clock activation.*/ +#if STM32_USB_USE_USB1 + if (&USBD1 == usbp) { + /* USB clock enabled.*/ + rccEnableUSB(true); + /* Powers up the transceiver while holding the USB in reset state.*/ + STM32_USB->CNTR = CNTR_FRES; + /* Enabling the USB IRQ vectors, this also gives enough time to allow + the transceiver power up (1uS).*/ +#if STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER + nvicEnableVector(STM32_USB1_HP_NUMBER, STM32_USB_USB1_HP_IRQ_PRIORITY); +#endif + nvicEnableVector(STM32_USB1_LP_NUMBER, STM32_USB_USB1_LP_IRQ_PRIORITY); + /* Releases the USB reset.*/ + STM32_USB->CNTR = 0; + } +#endif + /* Reset procedure enforced on driver start.*/ + usb_lld_reset(usbp); + } +} + +/** + * @brief Deactivates the USB peripheral. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void usb_lld_stop(USBDriver *usbp) { + + /* If in ready state then disables the USB clock.*/ + if (usbp->state != USB_STOP) { +#if STM32_USB_USE_USB1 + if (&USBD1 == usbp) { +#if STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER + nvicDisableVector(STM32_USB1_HP_NUMBER); +#endif + nvicDisableVector(STM32_USB1_LP_NUMBER); + STM32_USB->CNTR = CNTR_PDWN | CNTR_FRES; + rccDisableUSB(); + } +#endif + } +} + +/** + * @brief USB low level reset routine. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void usb_lld_reset(USBDriver *usbp) { + uint32_t cntr; + + /* Post reset initialization.*/ + STM32_USB->BTABLE = BTABLE_ADDR; + STM32_USB->ISTR = 0; + STM32_USB->DADDR = DADDR_EF; + cntr = /*CNTR_ESOFM | */ CNTR_RESETM | CNTR_SUSPM | + CNTR_WKUPM | /*CNTR_ERRM | CNTR_PMAOVRM |*/ CNTR_CTRM; + /* The SOF interrupt is only enabled if a callback is defined for + this service because it is an high rate source.*/ + if (usbp->config->sof_cb != NULL) + cntr |= CNTR_SOFM; + STM32_USB->CNTR = cntr; + + /* Resets the packet memory allocator.*/ + usb_pm_reset(usbp); + + /* EP0 initialization.*/ + usbp->epc[0] = &ep0config; + usb_lld_init_endpoint(usbp, 0); +} + +/** + * @brief Sets the USB address. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void usb_lld_set_address(USBDriver *usbp) { + + STM32_USB->DADDR = (uint32_t)(usbp->address) | DADDR_EF; +} + +/** + * @brief Enables an endpoint. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) { + uint16_t epr; + stm32_usb_descriptor_t *dp; + const USBEndpointConfig *epcp = usbp->epc[ep]; + + /* Setting the endpoint type. Note that isochronous endpoints cannot be + bidirectional because it uses double buffering and both transmit and + receive descriptor fields are used for either direction.*/ + switch (epcp->ep_mode & USB_EP_MODE_TYPE) { + case USB_EP_MODE_TYPE_ISOC: +#if STM32_USB_USE_ISOCHRONOUS + osalDbgAssert((epcp->in_state == NULL) || (epcp->out_state == NULL), + "isochronous EP cannot be IN and OUT"); + epr = EPR_EP_TYPE_ISO; + break; +#else + osalDbgAssert(false, "isochronous support disabled"); +#endif + /* Falls through.*/ + case USB_EP_MODE_TYPE_BULK: + epr = EPR_EP_TYPE_BULK; + break; + case USB_EP_MODE_TYPE_INTR: + epr = EPR_EP_TYPE_INTERRUPT; + break; + default: + epr = EPR_EP_TYPE_CONTROL; + } + + dp = USB_GET_DESCRIPTOR(ep); + + /* IN endpoint handling.*/ + if (epcp->in_state != NULL) { + dp->TXCOUNT0 = 0; + dp->TXADDR0 = usb_pm_alloc(usbp, epcp->in_maxsize); + +#if STM32_USB_USE_ISOCHRONOUS + if (epr == EPR_EP_TYPE_ISO) { + epr |= EPR_STAT_TX_VALID; + dp->TXCOUNT1 = dp->TXCOUNT0; + dp->TXADDR1 = dp->TXADDR0; /* Both buffers overlapped.*/ + } + else { + epr |= EPR_STAT_TX_NAK; + } +#else + epr |= EPR_STAT_TX_NAK; +#endif + } + + /* OUT endpoint handling.*/ + if (epcp->out_state != NULL) { + uint16_t nblocks; + + /* Endpoint size and address initialization.*/ + if (epcp->out_maxsize > 62) { + nblocks = (((((uint32_t)epcp->out_maxsize - 1U) | 0x1FU) / 32U) << 10) | + 0x8000U; + } + else { + nblocks = ((((uint32_t)(epcp->out_maxsize - 1U) | 1U) + 1U) / 2U) << 10; + } + dp->RXCOUNT0 = nblocks; + dp->RXADDR0 = usb_pm_alloc(usbp, epcp->out_maxsize); + +#if STM32_USB_USE_ISOCHRONOUS + if (epr == EPR_EP_TYPE_ISO) { + epr |= EPR_STAT_RX_VALID; + dp->RXCOUNT1 = dp->RXCOUNT0; + dp->RXADDR1 = dp->RXADDR0; /* Both buffers overlapped.*/ + } + else { + epr |= EPR_STAT_RX_NAK; + } +#else + epr |= EPR_STAT_RX_NAK; +#endif + } + + /* Resetting the data toggling bits for this endpoint.*/ + if (STM32_USB->EPR[ep] & EPR_DTOG_RX) { + epr |= EPR_DTOG_RX; + } + + if (STM32_USB->EPR[ep] & EPR_DTOG_TX) { + epr |= EPR_DTOG_TX; + } + + /* EPxR register setup.*/ + EPR_SET(ep, epr | ep); + EPR_TOGGLE(ep, epr); +} + +/** + * @brief Disables all the active endpoints except the endpoint zero. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void usb_lld_disable_endpoints(USBDriver *usbp) { + unsigned i; + + /* Resets the packet memory allocator.*/ + usb_pm_reset(usbp); + + /* Disabling all endpoints.*/ + for (i = 1; i <= USB_ENDOPOINTS_NUMBER; i++) { + EPR_TOGGLE(i, 0); + EPR_SET(i, 0); + } +} + +/** + * @brief Returns the status of an OUT endpoint. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * @return The endpoint status. + * @retval EP_STATUS_DISABLED The endpoint is not active. + * @retval EP_STATUS_STALLED The endpoint is stalled. + * @retval EP_STATUS_ACTIVE The endpoint is active. + * + * @notapi + */ +usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) { + + (void)usbp; + switch (STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) { + case EPR_STAT_RX_DIS: + return EP_STATUS_DISABLED; + case EPR_STAT_RX_STALL: + return EP_STATUS_STALLED; + default: + return EP_STATUS_ACTIVE; + } +} + +/** + * @brief Returns the status of an IN endpoint. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * @return The endpoint status. + * @retval EP_STATUS_DISABLED The endpoint is not active. + * @retval EP_STATUS_STALLED The endpoint is stalled. + * @retval EP_STATUS_ACTIVE The endpoint is active. + * + * @notapi + */ +usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) { + + (void)usbp; + switch (STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) { + case EPR_STAT_TX_DIS: + return EP_STATUS_DISABLED; + case EPR_STAT_TX_STALL: + return EP_STATUS_STALLED; + default: + return EP_STATUS_ACTIVE; + } +} + +/** + * @brief Reads a setup packet from the dedicated packet buffer. + * @details This function must be invoked in the context of the @p setup_cb + * callback in order to read the received setup packet. + * @pre In order to use this function the endpoint must have been + * initialized as a control endpoint. + * @post The endpoint is ready to accept another packet. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * @param[out] buf buffer where to copy the packet data + * + * @notapi + */ +void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) { + stm32_usb_pma_t *pmap; + stm32_usb_descriptor_t *udp; + uint32_t n; + + (void)usbp; + udp = USB_GET_DESCRIPTOR(ep); + pmap = USB_ADDR2PTR(udp->RXADDR0); + for (n = 0; n < 4; n++) { + *(uint16_t *)buf = (uint16_t)*pmap++; + buf += 2; + } +} + +/** + * @brief Starts a receive operation on an OUT endpoint. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +void usb_lld_start_out(USBDriver *usbp, usbep_t ep) { + USBOutEndpointState *osp = usbp->epc[ep]->out_state; + + /* Transfer initialization.*/ + if (osp->rxsize == 0) /* Special case for zero sized packets.*/ + osp->rxpkts = 1; + else + osp->rxpkts = (uint16_t)((osp->rxsize + usbp->epc[ep]->out_maxsize - 1) / + usbp->epc[ep]->out_maxsize); + + EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID); +} + +/** + * @brief Starts a transmit operation on an IN endpoint. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +void usb_lld_start_in(USBDriver *usbp, usbep_t ep) { + size_t n; + USBInEndpointState *isp = usbp->epc[ep]->in_state; + + /* Transfer initialization.*/ + n = isp->txsize; + if (n > (size_t)usbp->epc[ep]->in_maxsize) + n = (size_t)usbp->epc[ep]->in_maxsize; + + isp->txlast = n; + usb_packet_write_from_buffer(ep, isp->txbuf, n); + + EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID); +} + +/** + * @brief Brings an OUT endpoint in the stalled state. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) { + + (void)usbp; + + EPR_SET_STAT_RX(ep, EPR_STAT_RX_STALL); +} + +/** + * @brief Brings an IN endpoint in the stalled state. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) { + + (void)usbp; + + EPR_SET_STAT_TX(ep, EPR_STAT_TX_STALL); +} + +/** + * @brief Brings an OUT endpoint in the active state. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) { + + (void)usbp; + + /* Makes sure to not put to NAK an endpoint that is already + transferring.*/ + if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_VALID) + EPR_SET_STAT_TX(ep, EPR_STAT_RX_NAK); +} + +/** + * @brief Brings an IN endpoint in the active state. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * + * @notapi + */ +void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) { + + (void)usbp; + + /* Makes sure to not put to NAK an endpoint that is already + transferring.*/ + if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_VALID) + EPR_SET_STAT_TX(ep, EPR_STAT_TX_NAK); +} + +#endif /* HAL_USE_USB */ + +/** @} */ From 7fcf0f5184a721f1bbffe21235ead41b04fa7f9a Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Fri, 14 Apr 2023 09:00:14 +0000 Subject: [PATCH 25/53] Tentative BOARD_OTG_NOVBUSSENS fix for STM32 OTGv1 driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16219 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c index 0a2e674696..c52ba5c5dc 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c +++ b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c @@ -40,8 +40,7 @@ #if STM32_OTG_STEPPING == 1 #if defined(BOARD_OTG_NOVBUSSENS) -#define GCCFG_INIT_VALUE (GCCFG_NOVBUSSENS | GCCFG_VBUSASEN | \ - GCCFG_VBUSBSEN | GCCFG_PWRDWN) +#define GCCFG_INIT_VALUE (GCCFG_NOVBUSSENS | GCCFG_PWRDWN) #else #define GCCFG_INIT_VALUE (GCCFG_VBUSASEN | GCCFG_VBUSBSEN | \ GCCFG_PWRDWN) From 6fb6e2f24d67f09929a9521852be298c9a832ea0 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 25 Apr 2023 07:40:50 +0000 Subject: [PATCH 26/53] Fixed bug #1261. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16230 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/common/startup/ARMCMx/compilers/GCC/crt1.c | 444 +++++++++--------- readme.txt | 2 + 2 files changed, 227 insertions(+), 219 deletions(-) diff --git a/os/common/startup/ARMCMx/compilers/GCC/crt1.c b/os/common/startup/ARMCMx/compilers/GCC/crt1.c index 87179c4ab0..961a76d4d5 100644 --- a/os/common/startup/ARMCMx/compilers/GCC/crt1.c +++ b/os/common/startup/ARMCMx/compilers/GCC/crt1.c @@ -1,219 +1,225 @@ -/* - ChibiOS - Copyright (C) 2006..2018 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 ARMCMx/compilers/GCC/crt1.c - * @brief Startup stub functions. - * - * @addtogroup ARMCMx_GCC_STARTUP - * @{ - */ - -#include -#include - -#include "cmparams.h" - -/*===========================================================================*/ -/* Module local definitions. */ -/*===========================================================================*/ - -#if !defined(CRT1_AREAS_NUMBER) || defined(__DOXYGEN__) -#define CRT1_AREAS_NUMBER 8 -#endif - -#if (CRT1_AREAS_NUMBER < 0) || (CRT1_AREAS_NUMBER > 8) -#error "CRT1_AREAS_NUMBER must be within 0 and 8" -#endif - -/*===========================================================================*/ -/* Module exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module local types. */ -/*===========================================================================*/ - -/** - * @brief Type of an area to be initialized. - */ -typedef struct { - uint32_t *init_text_area; - uint32_t *init_area; - uint32_t *clear_area; - uint32_t *no_init_area; -} ram_init_area_t; - -/*===========================================================================*/ -/* Module local variables. */ -/*===========================================================================*/ - -#if (CRT1_AREAS_NUMBER > 0) || defined(__DOXYGEN__) -extern uint32_t __ram0_init_text__, __ram0_init__, __ram0_clear__, __ram0_noinit__; -#endif -#if (CRT1_AREAS_NUMBER > 1) || defined(__DOXYGEN__) -extern uint32_t __ram1_init_text__, __ram1_init__, __ram1_clear__, __ram1_noinit__; -#endif -#if (CRT1_AREAS_NUMBER > 2) || defined(__DOXYGEN__) -extern uint32_t __ram2_init_text__, __ram2_init__, __ram2_clear__, __ram2_noinit__; -#endif -#if (CRT1_AREAS_NUMBER > 3) || defined(__DOXYGEN__) -extern uint32_t __ram3_init_text__, __ram3_init__, __ram3_clear__, __ram3_noinit__; -#endif -#if (CRT1_AREAS_NUMBER > 4) || defined(__DOXYGEN__) -extern uint32_t __ram4_init_text__, __ram4_init__, __ram4_clear__, __ram4_noinit__; -#endif -#if (CRT1_AREAS_NUMBER > 5) || defined(__DOXYGEN__) -extern uint32_t __ram5_init_text__, __ram5_init__, __ram5_clear__, __ram5_noinit__; -#endif -#if (CRT1_AREAS_NUMBER > 6) || defined(__DOXYGEN__) -extern uint32_t __ram6_init_text__, __ram6_init__, __ram6_clear__, __ram6_noinit__; -#endif -#if (CRT1_AREAS_NUMBER > 7) || defined(__DOXYGEN__) -extern uint32_t __ram7_init_text__, __ram7_init__, __ram7_clear__, __ram7_noinit__; -#endif - -/** - * @brief Static table of areas to be initialized. - */ -#if (CRT1_AREAS_NUMBER > 0) || defined(__DOXYGEN__) -static const ram_init_area_t ram_areas[CRT1_AREAS_NUMBER] = { - {&__ram0_init_text__, &__ram0_init__, &__ram0_clear__, &__ram0_noinit__}, -#if (CRT1_AREAS_NUMBER > 1) || defined(__DOXYGEN__) - {&__ram1_init_text__, &__ram1_init__, &__ram1_clear__, &__ram1_noinit__}, -#endif -#if (CRT1_AREAS_NUMBER > 2) || defined(__DOXYGEN__) - {&__ram2_init_text__, &__ram2_init__, &__ram2_clear__, &__ram2_noinit__}, -#endif -#if (CRT1_AREAS_NUMBER > 3) || defined(__DOXYGEN__) - {&__ram3_init_text__, &__ram3_init__, &__ram3_clear__, &__ram3_noinit__}, -#endif -#if (CRT1_AREAS_NUMBER > 4) || defined(__DOXYGEN__) - {&__ram4_init_text__, &__ram4_init__, &__ram4_clear__, &__ram4_noinit__}, -#endif -#if (CRT1_AREAS_NUMBER > 5) || defined(__DOXYGEN__) - {&__ram5_init_text__, &__ram5_init__, &__ram5_clear__, &__ram5_noinit__}, -#endif -#if (CRT1_AREAS_NUMBER > 6) || defined(__DOXYGEN__) - {&__ram6_init_text__, &__ram6_init__, &__ram6_clear__, &__ram6_noinit__}, -#endif -#if (CRT1_AREAS_NUMBER > 7) || defined(__DOXYGEN__) - {&__ram7_init_text__, &__ram7_init__, &__ram7_clear__, &__ram7_noinit__}, -#endif -}; -#endif - -/*===========================================================================*/ -/* Module local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module exported functions. */ -/*===========================================================================*/ - -/** - * @brief Architecture-dependent core initialization. - * @details This hook is invoked immediately after the stack initialization - * and before the DATA and BSS segments initialization. - * @note This function is a weak symbol. - */ -#if !defined(__DOXYGEN__) -__attribute__((weak)) -#endif -/*lint -save -e9075 [8.4] All symbols are invoked from asm context.*/ -void __core_init(void) { - -#if CORTEX_MODEL == 7 - SCB_EnableICache(); - SCB_EnableDCache(); -#endif -} - -/** - * @brief Early initialization. - * @details This hook is invoked immediately after the stack and core - * initialization and before the DATA and BSS segments - * initialization. - * @note This function is a weak symbol. - */ -#if !defined(__DOXYGEN__) -__attribute__((weak)) -#endif -/*lint -save -e9075 [8.4] All symbols are invoked from asm context.*/ -void __early_init(void) {} -/*lint -restore*/ - -/** - * @brief Late initialization. - * @details This hook is invoked after the DATA and BSS segments - * initialization and before any static constructor. The - * default behavior is to do nothing. - * @note This function is a weak symbol. - */ -#if !defined(__DOXYGEN__) -__attribute__((weak)) -#endif -/*lint -save -e9075 [8.4] All symbols are invoked from asm context.*/ -void __late_init(void) {} -/*lint -restore*/ - -/** - * @brief Default @p main() function exit handler. - * @details This handler is invoked or the @p main() function exit. The - * default behavior is to enter an infinite loop. - * @note This function is a weak symbol. - */ -#if !defined(__DOXYGEN__) -__attribute__((noreturn, weak)) -#endif -/*lint -save -e9075 [8.4] All symbols are invoked from asm context.*/ -void __default_exit(void) { -/*lint -restore*/ - - while (true) { - } -} - -/** - * @brief Performs the initialization of the various RAM areas. - */ -void __init_ram_areas(void) { -#if CRT1_AREAS_NUMBER > 0 - const ram_init_area_t *rap = ram_areas; - - do { - uint32_t *tp = rap->init_text_area; - uint32_t *p = rap->init_area; - - /* Copying initialization data.*/ - while (p < rap->clear_area) { - *p = *tp; - p++; - tp++; - } - - /* Zeroing clear area.*/ - while (p < rap->no_init_area) { - *p = 0; - p++; - } - rap++; - } - while (rap < &ram_areas[CRT1_AREAS_NUMBER]); -#endif -} - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 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 ARMCMx/compilers/GCC/crt1.c + * @brief Startup stub functions. + * + * @addtogroup ARMCMx_GCC_STARTUP + * @{ + */ + +#include +#include + +#include "cmparams.h" + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +#if !defined(CRT1_AREAS_NUMBER) || defined(__DOXYGEN__) +#define CRT1_AREAS_NUMBER 8 +#endif + +#if (CRT1_AREAS_NUMBER < 0) || (CRT1_AREAS_NUMBER > 8) +#error "CRT1_AREAS_NUMBER must be within 0 and 8" +#endif + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/** + * @brief Type of an area to be initialized. + */ +typedef struct { + uint32_t *init_text_area; + uint32_t *init_area; + uint32_t *clear_area; + uint32_t *no_init_area; +} ram_init_area_t; + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +#if (CRT1_AREAS_NUMBER > 0) || defined(__DOXYGEN__) +extern uint32_t __ram0_init_text__, __ram0_init__, __ram0_clear__, __ram0_noinit__; +#endif +#if (CRT1_AREAS_NUMBER > 1) || defined(__DOXYGEN__) +extern uint32_t __ram1_init_text__, __ram1_init__, __ram1_clear__, __ram1_noinit__; +#endif +#if (CRT1_AREAS_NUMBER > 2) || defined(__DOXYGEN__) +extern uint32_t __ram2_init_text__, __ram2_init__, __ram2_clear__, __ram2_noinit__; +#endif +#if (CRT1_AREAS_NUMBER > 3) || defined(__DOXYGEN__) +extern uint32_t __ram3_init_text__, __ram3_init__, __ram3_clear__, __ram3_noinit__; +#endif +#if (CRT1_AREAS_NUMBER > 4) || defined(__DOXYGEN__) +extern uint32_t __ram4_init_text__, __ram4_init__, __ram4_clear__, __ram4_noinit__; +#endif +#if (CRT1_AREAS_NUMBER > 5) || defined(__DOXYGEN__) +extern uint32_t __ram5_init_text__, __ram5_init__, __ram5_clear__, __ram5_noinit__; +#endif +#if (CRT1_AREAS_NUMBER > 6) || defined(__DOXYGEN__) +extern uint32_t __ram6_init_text__, __ram6_init__, __ram6_clear__, __ram6_noinit__; +#endif +#if (CRT1_AREAS_NUMBER > 7) || defined(__DOXYGEN__) +extern uint32_t __ram7_init_text__, __ram7_init__, __ram7_clear__, __ram7_noinit__; +#endif + +/** + * @brief Static table of areas to be initialized. + */ +#if (CRT1_AREAS_NUMBER > 0) || defined(__DOXYGEN__) +static const ram_init_area_t ram_areas[CRT1_AREAS_NUMBER] = { + {&__ram0_init_text__, &__ram0_init__, &__ram0_clear__, &__ram0_noinit__}, +#if (CRT1_AREAS_NUMBER > 1) || defined(__DOXYGEN__) + {&__ram1_init_text__, &__ram1_init__, &__ram1_clear__, &__ram1_noinit__}, +#endif +#if (CRT1_AREAS_NUMBER > 2) || defined(__DOXYGEN__) + {&__ram2_init_text__, &__ram2_init__, &__ram2_clear__, &__ram2_noinit__}, +#endif +#if (CRT1_AREAS_NUMBER > 3) || defined(__DOXYGEN__) + {&__ram3_init_text__, &__ram3_init__, &__ram3_clear__, &__ram3_noinit__}, +#endif +#if (CRT1_AREAS_NUMBER > 4) || defined(__DOXYGEN__) + {&__ram4_init_text__, &__ram4_init__, &__ram4_clear__, &__ram4_noinit__}, +#endif +#if (CRT1_AREAS_NUMBER > 5) || defined(__DOXYGEN__) + {&__ram5_init_text__, &__ram5_init__, &__ram5_clear__, &__ram5_noinit__}, +#endif +#if (CRT1_AREAS_NUMBER > 6) || defined(__DOXYGEN__) + {&__ram6_init_text__, &__ram6_init__, &__ram6_clear__, &__ram6_noinit__}, +#endif +#if (CRT1_AREAS_NUMBER > 7) || defined(__DOXYGEN__) + {&__ram7_init_text__, &__ram7_init__, &__ram7_clear__, &__ram7_noinit__}, +#endif +}; +#endif + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Architecture-dependent core initialization. + * @details This hook is invoked immediately after the stack initialization + * and before the DATA and BSS segments initialization. + * @note This function is a weak symbol. + */ +#if !defined(__DOXYGEN__) +__attribute__((weak)) +#endif +/*lint -save -e9075 [8.4] All symbols are invoked from asm context.*/ +void __core_init(void) { + +#if CORTEX_MODEL == 7 + SCB_EnableICache(); + SCB_EnableDCache(); +#endif +} + +/** + * @brief Early initialization. + * @details This hook is invoked immediately after the stack and core + * initialization and before the DATA and BSS segments + * initialization. + * @note This function is a weak symbol. + */ +#if !defined(__DOXYGEN__) +__attribute__((weak)) +#endif +/*lint -save -e9075 [8.4] All symbols are invoked from asm context.*/ +void __early_init(void) {} +/*lint -restore*/ + +/** + * @brief Late initialization. + * @details This hook is invoked after the DATA and BSS segments + * initialization and before any static constructor. The + * default behavior is to do nothing. + * @note This function is a weak symbol. + */ +#if !defined(__DOXYGEN__) +__attribute__((weak)) +#endif +/*lint -save -e9075 [8.4] All symbols are invoked from asm context.*/ +void __late_init(void) {} +/*lint -restore*/ + +/** + * @brief Default @p main() function exit handler. + * @details This handler is invoked or the @p main() function exit. The + * default behavior is to enter an infinite loop. + * @note This function is a weak symbol. + */ +#if !defined(__DOXYGEN__) +__attribute__((noreturn, weak)) +#endif +/*lint -save -e9075 [8.4] All symbols are invoked from asm context.*/ +void __default_exit(void) { +/*lint -restore*/ + + while (true) { + } +} + +/** + * @brief Performs the initialization of the various RAM areas. + */ +void __init_ram_areas(void) { +#if CRT1_AREAS_NUMBER > 0 + const ram_init_area_t *rap = ram_areas; + + do { + uint32_t *tp = rap->init_text_area; + uint32_t *p = rap->init_area; + + /* Copying initialization data.*/ + while (p < rap->clear_area) { + *p = *tp; + p++; + tp++; + } + + /* Zeroing clear area.*/ + while (p < rap->no_init_area) { + *p = 0; + p++; + } + rap++; + } + while (rap < &ram_areas[CRT1_AREAS_NUMBER]); +#if CORTEX_MODEL == 7 + /* PM0253 - 4.8.7 Cache maintenance design hints and tips - required + for self-modifying code.*/ + SCB_CleanDCache(); + SCB_InvalidateICache(); +#endif +#endif +} + +/** @} */ diff --git a/readme.txt b/readme.txt index e200de17dd..b2c321e620 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,8 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed missing cache management during Cortex-M RAM initializations + (bug #1261)(backported to 20.3.5)(backported to 21.11.4). - FIX: Fixed unwanted reset of cache on STM32H7xx (bug #1258). - FIX: Fixed incorrect RTC initialization on STM32G4 (bug #1256). - FIX: Fixed invalid checks on PLLP/R/Q dividers on STM32H7 (bug #1253). From 5aec7c2dad215a6304357bd858fe0103293ab9cf Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 25 Apr 2023 09:41:00 +0000 Subject: [PATCH 27/53] Fixed bug #1263. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16232 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.c | 910 ++++++++++----------- readme.txt | 1 + 2 files changed, 456 insertions(+), 455 deletions(-) diff --git a/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.c b/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.c index 4ca2e417bb..feadcaeb5e 100644 --- a/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.c +++ b/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.c @@ -1,455 +1,455 @@ -/* - ChibiOS - Copyright (C) 2006..2018 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 BDMAv1/stm32_bdma.c - * @brief BDMA helper driver code. - * - * @addtogroup STM32_BDMA - * @details BDMA sharing helper driver. In the STM32 the BDMA streams are a - * shared resource, this driver allows to allocate and free BDMA - * streams at runtime in order to allow all the other device - * drivers to coordinate the access to the resource. - * @note The BDMA ISR handlers are all declared into this module because - * sharing, the various device drivers can associate a callback to - * ISRs when allocating streams. - * @{ - */ - -#include "hal.h" - -/* The following macro is only defined if some driver requiring BDMA services - has been enabled.*/ -#if defined(STM32_BDMA_REQUIRED) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/** - * @brief Mask of the BDMA streams in @p bdma_allocated_mask. - */ -#define STM32_BDMA_STREAMS_MASK 0x000000FFU - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief BDMA streams descriptors. - * @details This table keeps the association between an unique stream - * identifier and the involved physical registers. - * @note Don't use this array directly, use the appropriate wrapper macros - * instead: @p STM32_BDMA1_STREAM1, @p STM32_BDMA1_STREAM2 etc. - */ -const stm32_bdma_stream_t _stm32_bdma_streams[STM32_BDMA_STREAMS] = { - {BDMA, BDMA_Channel0, 0, DMAMUX2_Channel0, 0, STM32_BDMA1_CH0_NUMBER}, - {BDMA, BDMA_Channel1, 4, DMAMUX2_Channel1, 1, STM32_BDMA1_CH1_NUMBER}, - {BDMA, BDMA_Channel2, 8, DMAMUX2_Channel2, 2, STM32_BDMA1_CH2_NUMBER}, - {BDMA, BDMA_Channel3, 12, DMAMUX2_Channel3, 3, STM32_BDMA1_CH3_NUMBER}, - {BDMA, BDMA_Channel4, 16, DMAMUX2_Channel4, 4, STM32_BDMA1_CH4_NUMBER}, - {BDMA, BDMA_Channel5, 20, DMAMUX2_Channel5, 5, STM32_BDMA1_CH5_NUMBER}, - {BDMA, BDMA_Channel6, 24, DMAMUX2_Channel6, 6, STM32_BDMA1_CH6_NUMBER}, - {BDMA, BDMA_Channel7, 28, DMAMUX2_Channel7, 7, STM32_BDMA1_CH7_NUMBER} -}; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/** - * @brief BDMA ISR redirector type. - */ -typedef struct { - stm32_bdmaisr_t func; /**< @brief BDMA callback function. */ - void *param; /**< @brief BDMA callback parameter.*/ -} bdma_isr_redir_t; - -/** - * @brief BDMA driver base structure. - */ -static struct { - /** - * @brief Mask of the allocated streams. - */ - uint32_t allocated_mask; - /** - * @brief DMA IRQ redirectors. - */ - struct { - /** - * @brief DMA callback function. - */ - stm32_bdmaisr_t func; - /** - * @brief DMA callback parameter. - */ - void *param; - } streams[STM32_BDMA_STREAMS]; -} bdma; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/** - * @brief BDMA1 stream 0 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_BDMA1_CH0_HANDLER) { - uint32_t flags; - - OSAL_IRQ_PROLOGUE(); - - flags = (BDMA->ISR >> 0U) & STM32_BDMA_ISR_MASK; - BDMA->IFCR = flags << 0U; - if (bdma.streams[0].func) - bdma.streams[0].func(bdma.streams[0].param, flags); - - OSAL_IRQ_EPILOGUE(); -} - -/** - * @brief BDMA1 stream 1 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_BDMA1_CH1_HANDLER) { - uint32_t flags; - - OSAL_IRQ_PROLOGUE(); - - flags = (BDMA->ISR >> 4U) & STM32_BDMA_ISR_MASK; - BDMA->IFCR = flags << 4U; - if (bdma.streams[1].func) - bdma.streams[1].func(bdma.streams[1].param, flags); - - OSAL_IRQ_EPILOGUE(); -} - -/** - * @brief BDMA1 stream 2 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_BDMA1_CH2_HANDLER) { - uint32_t flags; - - OSAL_IRQ_PROLOGUE(); - - flags = (BDMA->ISR >> 8U) & STM32_BDMA_ISR_MASK; - BDMA->IFCR = flags << 8U; - if (bdma.streams[2].func) - bdma.streams[2].func(bdma.streams[2].param, flags); - - OSAL_IRQ_EPILOGUE(); -} - -/** - * @brief BDMA1 stream 3 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_BDMA1_CH3_HANDLER) { - uint32_t flags; - - OSAL_IRQ_PROLOGUE(); - - flags = (BDMA->ISR >> 12U) & STM32_BDMA_ISR_MASK; - BDMA->IFCR = flags << 12U; - if (bdma.streams[3].func) - bdma.streams[3].func(bdma.streams[3].param, flags); - - OSAL_IRQ_EPILOGUE(); -} - -/** - * @brief BDMA1 stream 4 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_BDMA1_CH4_HANDLER) { - uint32_t flags; - - OSAL_IRQ_PROLOGUE(); - - flags = (BDMA->ISR >> 16U) & STM32_BDMA_ISR_MASK; - BDMA->IFCR = flags << 16U; - if (bdma.streams[4].func) - bdma.streams[4].func(bdma.streams[4].param, flags); - - OSAL_IRQ_EPILOGUE(); -} - -/** - * @brief BDMA1 stream 5 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_BDMA1_CH5_HANDLER) { - uint32_t flags; - - OSAL_IRQ_PROLOGUE(); - - flags = (BDMA->ISR >> 20U) & STM32_BDMA_ISR_MASK; - BDMA->IFCR = flags << 20U; - if (bdma.streams[5].func) - bdma.streams[5].func(bdma.streams[5].param, flags); - - OSAL_IRQ_EPILOGUE(); -} - -/** - * @brief BDMA1 stream 6 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_BDMA1_CH6_HANDLER) { - uint32_t flags; - - OSAL_IRQ_PROLOGUE(); - - flags = (BDMA->ISR >> 24U) & STM32_BDMA_ISR_MASK; - BDMA->IFCR = flags << 24U; - if (bdma.streams[6].func) - bdma.streams[6].func(bdma.streams[6].param, flags); - - OSAL_IRQ_EPILOGUE(); -} - -/** - * @brief BDMA1 stream 7 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_BDMA1_CH7_HANDLER) { - uint32_t flags; - - OSAL_IRQ_PROLOGUE(); - - flags = (BDMA->ISR >> 28U) & STM32_BDMA_ISR_MASK; - BDMA->IFCR = flags << 28U; - if (bdma.streams[7].func) - bdma.streams[7].func(bdma.streams[7].param, flags); - - OSAL_IRQ_EPILOGUE(); -} - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief STM32 BDMA helper initialization. - * - * @init - */ -void bdmaInit(void) { - unsigned i; - - bdma.allocated_mask = 0U; - for (i = 0; i < STM32_BDMA_STREAMS; i++) { - _stm32_bdma_streams[i].channel->CCR = 0U; - bdma.streams[i].func = NULL; - bdma.streams[i].param = NULL; - } - BDMA->IFCR = 0xFFFFFFFFU; -} - -/** - * @brief Allocates a BDMA stream. - * @details The stream is allocated and, if required, the BDMA clock enabled. - * The function also enables the IRQ vector associated to the stream - * and initializes its priority. - * - * @param[in] id numeric identifiers of a specific stream or: - * - @p STM32_BDMA_STREAM_ID_ANY for any stream. - * . - * @param[in] priority IRQ priority for the BDMA stream - * @param[in] func handling function pointer, can be @p NULL - * @param[in] param a parameter to be passed to the handling function - * @return Pointer to the allocated @p stm32_bdma_stream_t - * structure. - * @retval NULL if a/the stream is not available. - * - * @iclass - */ -const stm32_bdma_stream_t *bdmaStreamAllocI(uint32_t id, - uint32_t priority, - stm32_bdmaisr_t func, - void *param) { - uint32_t i, startid, endid; - - osalDbgCheckClassI(); - - if (id < STM32_BDMA_STREAMS) { - startid = id; - endid = id; - } - else if (id == STM32_BDMA_STREAM_ID_ANY) { - startid = 0U; - endid = STM32_BDMA_STREAMS - 1U; - } - else { - osalDbgCheck(false); - return NULL; - } - - for (i = startid; i <= endid; i++) { - uint32_t mask = (1U << i); - if ((bdma.allocated_mask & mask) == 0U) { - const stm32_bdma_stream_t *stp = STM32_BDMA_STREAM(i); - - /* Installs the DMA handler.*/ - bdma.streams[i].func = func; - bdma.streams[i].param = param; - bdma.allocated_mask |= mask; - - /* Enabling DMA clocks required by the current streams set.*/ - if ((STM32_BDMA_STREAMS_MASK & mask) != 0U) { - rccEnableBDMA1(true); - } - -#if defined(rccEnableDMAMUX) - /* Enabling DMAMUX if present.*/ - if (bdma.allocated_mask != 0U) { - rccEnableDMAMUX(true); - } -#endif - - /* Enables the associated IRQ vector if not already enabled and if a - callback is defined.*/ - if (func != NULL) { - nvicEnableVector(stp->vector, priority); - } - - /* Putting the stream in a known state.*/ - bdmaStreamDisable(stp); - stp->channel->CCR = STM32_BDMA_CR_RESET_VALUE; - - return stp; - } - } - - return NULL; -} - -/** - * @brief Allocates a BDMA stream. - * @details The stream is allocated and, if required, the BDMA clock enabled. - * The function also enables the IRQ vector associated to the stream - * and initializes its priority. - * - * @param[in] id numeric identifiers of a specific stream or: - * - @p STM32_BDMA_STREAM_ID_ANY for any stream. - * . - * @param[in] priority IRQ priority for the BDMA stream - * @param[in] func handling function pointer, can be @p NULL - * @param[in] param a parameter to be passed to the handling function - * @return Pointer to the allocated @p stm32_bdma_stream_t - * structure. - * @retval NULL if a/the stream is not available. - * - * @api - */ -const stm32_bdma_stream_t *bdmaStreamAlloc(uint32_t id, - uint32_t priority, - stm32_bdmaisr_t func, - void *param) { - const stm32_bdma_stream_t *stp; - - osalSysLock(); - stp = bdmaStreamAllocI(id, priority, func, param); - osalSysUnlock(); - - return stp; -} - -/** - * @brief Releases a BDMA stream. - * @details The stream is freed and, if required, the BDMA clock disabled. - * Trying to release a unallocated stream is an illegal operation - * and is trapped if assertions are enabled. - * - * @param[in] stp pointer to an @p stm32_bdma_stream_t structure - * - * @iclass - */ -void bdmaStreamFreeI(const stm32_bdma_stream_t *stp) { - - osalDbgCheck(stp != NULL); - - /* Check if the streams is not taken.*/ - osalDbgAssert((bdma.allocated_mask & (1U << stp->selfindex)) != 0U, - "not allocated"); - - /* Disables the associated IRQ vector.*/ - nvicDisableVector(stp->vector); - - /* Marks the stream as not allocated.*/ - bdma.allocated_mask &= ~(1U << stp->selfindex); - - /* Clearing associated handler and parameter.*/ - bdma.streams->func = NULL; - bdma.streams->param = NULL; - - /* Shutting down clocks that are no more required, if any.*/ - if ((bdma.allocated_mask & STM32_BDMA_STREAMS_MASK) == 0U) { - rccDisableBDMA1(); - } -} - -/** - * @brief Releases a BDMA stream. - * @details The stream is freed and, if required, the BDMA clock disabled. - * Trying to release a unallocated stream is an illegal operation - * and is trapped if assertions are enabled. - * - * @param[in] stp pointer to an @p stm32_bdma_stream_t structure - * - * @api - */ -void bdmaStreamFree(const stm32_bdma_stream_t *stp) { - - osalSysLock(); - bdmaStreamFreeI(stp); - osalSysUnlock(); -} - -/** - * @brief Associates a peripheral request to a BDMA stream. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] stp pointer to a @p stm32_bdma_stream_t structure - * @param[in] per peripheral identifier - * - * @special - */ -void bdmaSetRequestSource(const stm32_bdma_stream_t *stp, uint32_t per) { - - osalDbgCheck(per < 256U); - - stp->mux->CCR = per; -} - -#endif /* STM32_BDMA_REQUIRED */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 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 BDMAv1/stm32_bdma.c + * @brief BDMA helper driver code. + * + * @addtogroup STM32_BDMA + * @details BDMA sharing helper driver. In the STM32 the BDMA streams are a + * shared resource, this driver allows to allocate and free BDMA + * streams at runtime in order to allow all the other device + * drivers to coordinate the access to the resource. + * @note The BDMA ISR handlers are all declared into this module because + * sharing, the various device drivers can associate a callback to + * ISRs when allocating streams. + * @{ + */ + +#include "hal.h" + +/* The following macro is only defined if some driver requiring BDMA services + has been enabled.*/ +#if defined(STM32_BDMA_REQUIRED) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/** + * @brief Mask of the BDMA streams in @p bdma_allocated_mask. + */ +#define STM32_BDMA_STREAMS_MASK 0x000000FFU + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief BDMA streams descriptors. + * @details This table keeps the association between an unique stream + * identifier and the involved physical registers. + * @note Don't use this array directly, use the appropriate wrapper macros + * instead: @p STM32_BDMA1_STREAM1, @p STM32_BDMA1_STREAM2 etc. + */ +const stm32_bdma_stream_t _stm32_bdma_streams[STM32_BDMA_STREAMS] = { + {BDMA, BDMA_Channel0, 0, DMAMUX2_Channel0, 0, STM32_BDMA1_CH0_NUMBER}, + {BDMA, BDMA_Channel1, 4, DMAMUX2_Channel1, 1, STM32_BDMA1_CH1_NUMBER}, + {BDMA, BDMA_Channel2, 8, DMAMUX2_Channel2, 2, STM32_BDMA1_CH2_NUMBER}, + {BDMA, BDMA_Channel3, 12, DMAMUX2_Channel3, 3, STM32_BDMA1_CH3_NUMBER}, + {BDMA, BDMA_Channel4, 16, DMAMUX2_Channel4, 4, STM32_BDMA1_CH4_NUMBER}, + {BDMA, BDMA_Channel5, 20, DMAMUX2_Channel5, 5, STM32_BDMA1_CH5_NUMBER}, + {BDMA, BDMA_Channel6, 24, DMAMUX2_Channel6, 6, STM32_BDMA1_CH6_NUMBER}, + {BDMA, BDMA_Channel7, 28, DMAMUX2_Channel7, 7, STM32_BDMA1_CH7_NUMBER} +}; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/** + * @brief BDMA ISR redirector type. + */ +typedef struct { + stm32_bdmaisr_t func; /**< @brief BDMA callback function. */ + void *param; /**< @brief BDMA callback parameter.*/ +} bdma_isr_redir_t; + +/** + * @brief BDMA driver base structure. + */ +static struct { + /** + * @brief Mask of the allocated streams. + */ + uint32_t allocated_mask; + /** + * @brief DMA IRQ redirectors. + */ + struct { + /** + * @brief DMA callback function. + */ + stm32_bdmaisr_t func; + /** + * @brief DMA callback parameter. + */ + void *param; + } streams[STM32_BDMA_STREAMS]; +} bdma; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/** + * @brief BDMA1 stream 0 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_BDMA1_CH0_HANDLER) { + uint32_t flags; + + OSAL_IRQ_PROLOGUE(); + + flags = (BDMA->ISR >> 0U) & STM32_BDMA_ISR_MASK; + BDMA->IFCR = flags << 0U; + if (bdma.streams[0].func) + bdma.streams[0].func(bdma.streams[0].param, flags); + + OSAL_IRQ_EPILOGUE(); +} + +/** + * @brief BDMA1 stream 1 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_BDMA1_CH1_HANDLER) { + uint32_t flags; + + OSAL_IRQ_PROLOGUE(); + + flags = (BDMA->ISR >> 4U) & STM32_BDMA_ISR_MASK; + BDMA->IFCR = flags << 4U; + if (bdma.streams[1].func) + bdma.streams[1].func(bdma.streams[1].param, flags); + + OSAL_IRQ_EPILOGUE(); +} + +/** + * @brief BDMA1 stream 2 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_BDMA1_CH2_HANDLER) { + uint32_t flags; + + OSAL_IRQ_PROLOGUE(); + + flags = (BDMA->ISR >> 8U) & STM32_BDMA_ISR_MASK; + BDMA->IFCR = flags << 8U; + if (bdma.streams[2].func) + bdma.streams[2].func(bdma.streams[2].param, flags); + + OSAL_IRQ_EPILOGUE(); +} + +/** + * @brief BDMA1 stream 3 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_BDMA1_CH3_HANDLER) { + uint32_t flags; + + OSAL_IRQ_PROLOGUE(); + + flags = (BDMA->ISR >> 12U) & STM32_BDMA_ISR_MASK; + BDMA->IFCR = flags << 12U; + if (bdma.streams[3].func) + bdma.streams[3].func(bdma.streams[3].param, flags); + + OSAL_IRQ_EPILOGUE(); +} + +/** + * @brief BDMA1 stream 4 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_BDMA1_CH4_HANDLER) { + uint32_t flags; + + OSAL_IRQ_PROLOGUE(); + + flags = (BDMA->ISR >> 16U) & STM32_BDMA_ISR_MASK; + BDMA->IFCR = flags << 16U; + if (bdma.streams[4].func) + bdma.streams[4].func(bdma.streams[4].param, flags); + + OSAL_IRQ_EPILOGUE(); +} + +/** + * @brief BDMA1 stream 5 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_BDMA1_CH5_HANDLER) { + uint32_t flags; + + OSAL_IRQ_PROLOGUE(); + + flags = (BDMA->ISR >> 20U) & STM32_BDMA_ISR_MASK; + BDMA->IFCR = flags << 20U; + if (bdma.streams[5].func) + bdma.streams[5].func(bdma.streams[5].param, flags); + + OSAL_IRQ_EPILOGUE(); +} + +/** + * @brief BDMA1 stream 6 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_BDMA1_CH6_HANDLER) { + uint32_t flags; + + OSAL_IRQ_PROLOGUE(); + + flags = (BDMA->ISR >> 24U) & STM32_BDMA_ISR_MASK; + BDMA->IFCR = flags << 24U; + if (bdma.streams[6].func) + bdma.streams[6].func(bdma.streams[6].param, flags); + + OSAL_IRQ_EPILOGUE(); +} + +/** + * @brief BDMA1 stream 7 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_BDMA1_CH7_HANDLER) { + uint32_t flags; + + OSAL_IRQ_PROLOGUE(); + + flags = (BDMA->ISR >> 28U) & STM32_BDMA_ISR_MASK; + BDMA->IFCR = flags << 28U; + if (bdma.streams[7].func) + bdma.streams[7].func(bdma.streams[7].param, flags); + + OSAL_IRQ_EPILOGUE(); +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief STM32 BDMA helper initialization. + * + * @init + */ +void bdmaInit(void) { + unsigned i; + + bdma.allocated_mask = 0U; + for (i = 0; i < STM32_BDMA_STREAMS; i++) { + _stm32_bdma_streams[i].channel->CCR = 0U; + bdma.streams[i].func = NULL; + bdma.streams[i].param = NULL; + } + BDMA->IFCR = 0xFFFFFFFFU; +} + +/** + * @brief Allocates a BDMA stream. + * @details The stream is allocated and, if required, the BDMA clock enabled. + * The function also enables the IRQ vector associated to the stream + * and initializes its priority. + * + * @param[in] id numeric identifiers of a specific stream or: + * - @p STM32_BDMA_STREAM_ID_ANY for any stream. + * . + * @param[in] priority IRQ priority for the BDMA stream + * @param[in] func handling function pointer, can be @p NULL + * @param[in] param a parameter to be passed to the handling function + * @return Pointer to the allocated @p stm32_bdma_stream_t + * structure. + * @retval NULL if a/the stream is not available. + * + * @iclass + */ +const stm32_bdma_stream_t *bdmaStreamAllocI(uint32_t id, + uint32_t priority, + stm32_bdmaisr_t func, + void *param) { + uint32_t i, startid, endid; + + osalDbgCheckClassI(); + + if (id < STM32_BDMA_STREAMS) { + startid = id; + endid = id; + } + else if (id == STM32_BDMA_STREAM_ID_ANY) { + startid = 0U; + endid = STM32_BDMA_STREAMS - 1U; + } + else { + osalDbgCheck(false); + return NULL; + } + + for (i = startid; i <= endid; i++) { + uint32_t mask = (1U << i); + if ((bdma.allocated_mask & mask) == 0U) { + const stm32_bdma_stream_t *stp = STM32_BDMA_STREAM(i); + + /* Installs the DMA handler.*/ + bdma.streams[i].func = func; + bdma.streams[i].param = param; + bdma.allocated_mask |= mask; + + /* Enabling DMA clocks required by the current streams set.*/ + if ((STM32_BDMA_STREAMS_MASK & mask) != 0U) { + rccEnableBDMA1(true); + } + +#if defined(rccEnableDMAMUX) + /* Enabling DMAMUX if present.*/ + if (bdma.allocated_mask != 0U) { + rccEnableDMAMUX(true); + } +#endif + + /* Enables the associated IRQ vector if not already enabled and if a + callback is defined.*/ + if (func != NULL) { + nvicEnableVector(stp->vector, priority); + } + + /* Putting the stream in a known state.*/ + bdmaStreamDisable(stp); + stp->channel->CCR = STM32_BDMA_CR_RESET_VALUE; + + return stp; + } + } + + return NULL; +} + +/** + * @brief Allocates a BDMA stream. + * @details The stream is allocated and, if required, the BDMA clock enabled. + * The function also enables the IRQ vector associated to the stream + * and initializes its priority. + * + * @param[in] id numeric identifiers of a specific stream or: + * - @p STM32_BDMA_STREAM_ID_ANY for any stream. + * . + * @param[in] priority IRQ priority for the BDMA stream + * @param[in] func handling function pointer, can be @p NULL + * @param[in] param a parameter to be passed to the handling function + * @return Pointer to the allocated @p stm32_bdma_stream_t + * structure. + * @retval NULL if a/the stream is not available. + * + * @api + */ +const stm32_bdma_stream_t *bdmaStreamAlloc(uint32_t id, + uint32_t priority, + stm32_bdmaisr_t func, + void *param) { + const stm32_bdma_stream_t *stp; + + osalSysLock(); + stp = bdmaStreamAllocI(id, priority, func, param); + osalSysUnlock(); + + return stp; +} + +/** + * @brief Releases a BDMA stream. + * @details The stream is freed and, if required, the BDMA clock disabled. + * Trying to release a unallocated stream is an illegal operation + * and is trapped if assertions are enabled. + * + * @param[in] stp pointer to an @p stm32_bdma_stream_t structure + * + * @iclass + */ +void bdmaStreamFreeI(const stm32_bdma_stream_t *stp) { + + osalDbgCheck(stp != NULL); + + /* Check if the streams is not taken.*/ + osalDbgAssert((bdma.allocated_mask & (1U << stp->selfindex)) != 0U, + "not allocated"); + + /* Disables the associated IRQ vector.*/ + nvicDisableVector(stp->vector); + + /* Marks the stream as not allocated.*/ + bdma.allocated_mask &= ~(1U << stp->selfindex); + + /* Clearing associated handler and parameter.*/ + bdma.streams[stp->selfindex]->func = NULL; + bdma.streams[stp->selfindex]->param = NULL; + + /* Shutting down clocks that are no more required, if any.*/ + if ((bdma.allocated_mask & STM32_BDMA_STREAMS_MASK) == 0U) { + rccDisableBDMA1(); + } +} + +/** + * @brief Releases a BDMA stream. + * @details The stream is freed and, if required, the BDMA clock disabled. + * Trying to release a unallocated stream is an illegal operation + * and is trapped if assertions are enabled. + * + * @param[in] stp pointer to an @p stm32_bdma_stream_t structure + * + * @api + */ +void bdmaStreamFree(const stm32_bdma_stream_t *stp) { + + osalSysLock(); + bdmaStreamFreeI(stp); + osalSysUnlock(); +} + +/** + * @brief Associates a peripheral request to a BDMA stream. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] stp pointer to a @p stm32_bdma_stream_t structure + * @param[in] per peripheral identifier + * + * @special + */ +void bdmaSetRequestSource(const stm32_bdma_stream_t *stp, uint32_t per) { + + osalDbgCheck(per < 256U); + + stp->mux->CCR = per; +} + +#endif /* STM32_BDMA_REQUIRED */ + +/** @} */ diff --git a/readme.txt b/readme.txt index b2c321e620..85c03e84e0 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed channel 0 corruption on STM32 BDMAv1 (bug #1263). - FIX: Fixed missing cache management during Cortex-M RAM initializations (bug #1261)(backported to 20.3.5)(backported to 21.11.4). - FIX: Fixed unwanted reset of cache on STM32H7xx (bug #1258). From 778d38ef866bc4c59fd09e7c9b47b55dfaddd6e9 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Wed, 26 Apr 2023 14:12:52 +0000 Subject: [PATCH 28/53] Wrong patch. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16235 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.c b/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.c index feadcaeb5e..25e65363f6 100644 --- a/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.c +++ b/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.c @@ -408,8 +408,8 @@ void bdmaStreamFreeI(const stm32_bdma_stream_t *stp) { bdma.allocated_mask &= ~(1U << stp->selfindex); /* Clearing associated handler and parameter.*/ - bdma.streams[stp->selfindex]->func = NULL; - bdma.streams[stp->selfindex]->param = NULL; + bdma.streams[stp->selfindex].func = NULL; + bdma.streams[stp->selfindex].param = NULL; /* Shutting down clocks that are no more required, if any.*/ if ((bdma.allocated_mask & STM32_BDMA_STREAMS_MASK) == 0U) { From 38460fa46bebc98d5839f834c2c98cf013e69f11 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 27 May 2023 09:18:44 +0000 Subject: [PATCH 29/53] Fixed bug #1265. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16267 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- .../serial_nor/devices/macronix_mx25/hal_flash_device.c | 3 --- .../complex/serial_nor/devices/micron_n25q/hal_flash_device.c | 3 --- readme.txt | 1 + 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/os/hal/lib/complex/serial_nor/devices/macronix_mx25/hal_flash_device.c b/os/hal/lib/complex/serial_nor/devices/macronix_mx25/hal_flash_device.c index 39a7475ae9..923c4bd354 100644 --- a/os/hal/lib/complex/serial_nor/devices/macronix_mx25/hal_flash_device.c +++ b/os/hal/lib/complex/serial_nor/devices/macronix_mx25/hal_flash_device.c @@ -589,9 +589,6 @@ flash_error_t snor_device_verify_erase(SNORDriver *devp, /* Checking for erased state of current buffer.*/ for (p = cmpbuf; p < &cmpbuf[MX25_COMPARE_BUFFER_SIZE]; p++) { if (*p != 0xFFU) { - /* Ready state again.*/ - devp->state = FLASH_READY; - return FLASH_ERROR_VERIFY; } } diff --git a/os/hal/lib/complex/serial_nor/devices/micron_n25q/hal_flash_device.c b/os/hal/lib/complex/serial_nor/devices/micron_n25q/hal_flash_device.c index f314c54cc9..3b19423bc2 100644 --- a/os/hal/lib/complex/serial_nor/devices/micron_n25q/hal_flash_device.c +++ b/os/hal/lib/complex/serial_nor/devices/micron_n25q/hal_flash_device.c @@ -472,9 +472,6 @@ flash_error_t snor_device_verify_erase(SNORDriver *devp, /* Checking for erased state of current buffer.*/ for (p = cmpbuf; p < &cmpbuf[N25Q_COMPARE_BUFFER_SIZE]; p++) { if (*p != 0xFFU) { - /* Ready state again.*/ - devp->state = FLASH_READY; - return FLASH_ERROR_VERIFY; } } diff --git a/readme.txt b/readme.txt index 85c03e84e0..478116604a 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed unnecessary code in SNOR device drivers (bug #1265). - FIX: Fixed channel 0 corruption on STM32 BDMAv1 (bug #1263). - FIX: Fixed missing cache management during Cortex-M RAM initializations (bug #1261)(backported to 20.3.5)(backported to 21.11.4). From c8f9175d947c1fb87dba817057ab35e4a91f0004 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 27 May 2023 13:02:14 +0000 Subject: [PATCH 30/53] Documentation improvement. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16269 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/oslib/include/chobjfifos.h | 860 +++++++++++++++++----------------- 1 file changed, 430 insertions(+), 430 deletions(-) diff --git a/os/oslib/include/chobjfifos.h b/os/oslib/include/chobjfifos.h index 0e45be9a63..b85ca2b131 100644 --- a/os/oslib/include/chobjfifos.h +++ b/os/oslib/include/chobjfifos.h @@ -1,430 +1,430 @@ -/* - ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014, - 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio. - - This file is part of ChibiOS. - - ChibiOS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation version 3 of the License. - - ChibiOS is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file oslib/include/chobjfifos.h - * @brief Objects FIFO structures and macros. - * @details This module implements a generic FIFO queue of objects by - * coupling a Guarded Memory Pool (for objects storage) and - * a MailBox.
- * On the sender side free objects are taken from the pool, filled - * and then sent to the receiver, on the receiver side objects are - * fetched, used and then returned to the pool. - * Operations defined for object FIFOs: - * - Take: An object is taken from the pool of the free - * objects, can be blocking. - * - Return: An object is returned to the pool of the - * free objects, it is guaranteed to be non-blocking. - * - Send: An object is sent through the mailbox, it is - * guaranteed to be non-blocking - * - Receive: An object is received from the mailbox, - * can be blocking. - * . - * - * @addtogroup oslib_objects_fifos - * @{ - */ - -#ifndef CHOBJFIFOS_H -#define CHOBJFIFOS_H - -#if (CH_CFG_USE_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Module constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if CH_CFG_USE_MEMPOOLS == FALSE -#error "CH_CFG_USE_OBJ_FIFOS requires CH_CFG_USE_MEMPOOLS" -#endif - -#if CH_CFG_USE_SEMAPHORES == FALSE -#error "CH_CFG_USE_OBJ_FIFOS requires CH_CFG_USE_SEMAPHORES" -#endif - -#if CH_CFG_USE_MAILBOXES == FALSE -#error "CH_CFG_USE_OBJ_FIFOS requires CH_CFG_USE_MAILBOXES" -#endif - -/*===========================================================================*/ -/* Module data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Type of an objects FIFO. - */ -typedef struct ch_objects_fifo { - /** - * @brief Pool of the free objects. - */ - guarded_memory_pool_t free; - /** - * @brief Mailbox of the sent objects. - */ - mailbox_t mbx; -} objects_fifo_t; - -/*===========================================================================*/ -/* Module macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -/*===========================================================================*/ -/* Module inline functions. */ -/*===========================================================================*/ - -/** - * @brief Initializes a FIFO object. - * @pre The messages size must be a multiple of the alignment - * requirement. - * - * @param[out] ofp pointer to a @p objects_fifo_t structure - * @param[in] objsize size of objects - * @param[in] objn number of objects available - * @param[in] objalign required objects alignment - * @param[in] objbuf pointer to the buffer of objects, it must be able - * to hold @p objn objects of @p objsize size with - * @p objalign alignment - * @param[in] msgbuf pointer to the buffer of messages, it must be able - * to hold @p objn messages - * - * @init - */ -static inline void chFifoObjectInitAligned(objects_fifo_t *ofp, size_t objsize, - size_t objn, unsigned objalign, - void *objbuf, msg_t *msgbuf) { - - chDbgCheck((objsize >= objalign) && ((objsize % objalign) == 0U)); - - chGuardedPoolObjectInitAligned(&ofp->free, objsize, objalign); - chGuardedPoolLoadArray(&ofp->free, objbuf, objn); - chMBObjectInit(&ofp->mbx, msgbuf, objn); -} - -/** - * @brief Initializes a FIFO object. - * @pre The messages size must be a multiple of the alignment - * requirement. - * - * @param[out] ofp pointer to a @p objects_fifo_t structure - * @param[in] objsize size of objects - * @param[in] objn number of objects available - * @param[in] objbuf pointer to the buffer of objects, it must be able - * to hold @p objn objects of @p objsize size - * @param[in] msgbuf pointer to the buffer of messages, it must be able - * to hold @p objn messages - * - * @init - */ -static inline void chFifoObjectInit(objects_fifo_t *ofp, size_t objsize, - size_t objn, void *objbuf, - msg_t *msgbuf) { - - chFifoObjectInitAligned(ofp, objsize, objn, - PORT_NATURAL_ALIGN, - objbuf, msgbuf); -} - -/** - * @brief Allocates a free object. - * - * @param[in] ofp pointer to a @p objects_fifo_t structure - * @return The pointer to the allocated object. - * @retval NULL if an object is not immediately available. - * - * @iclass - */ -static inline void *chFifoTakeObjectI(objects_fifo_t *ofp) { - - return chGuardedPoolAllocI(&ofp->free); -} - -/** - * @brief Allocates a free object. - * - * @param[in] ofp pointer to a @p objects_fifo_t structure - * @param[in] timeout the number of ticks before the operation timeouts, - * the following special values are allowed: - * - @a TIME_IMMEDIATE immediate timeout. - * - @a TIME_INFINITE no timeout. - * . - * @return The pointer to the allocated object. - * @retval NULL if an object is not available within the specified - * timeout. - * - * @sclass - */ -static inline void *chFifoTakeObjectTimeoutS(objects_fifo_t *ofp, - sysinterval_t timeout) { - - return chGuardedPoolAllocTimeoutS(&ofp->free, timeout); -} - -/** - * @brief Allocates a free object. - * - * @param[in] ofp pointer to a @p objects_fifo_t structure - * @param[in] timeout the number of ticks before the operation timeouts, - * the following special values are allowed: - * - @a TIME_IMMEDIATE immediate timeout. - * - @a TIME_INFINITE no timeout. - * . - * @return The pointer to the allocated object. - * @retval NULL if an object is not available within the specified - * timeout. - * - * @api - */ -static inline void *chFifoTakeObjectTimeout(objects_fifo_t *ofp, - sysinterval_t timeout) { - - return chGuardedPoolAllocTimeout(&ofp->free, timeout); -} - -/** - * @brief Releases a fetched object. - * - * @param[in] ofp pointer to a @p objects_fifo_t structure - * @param[in] objp pointer to the object to be released - * - * @iclass - */ -static inline void chFifoReturnObjectI(objects_fifo_t *ofp, - void *objp) { - - chGuardedPoolFreeI(&ofp->free, objp); -} - -/** - * @brief Releases a fetched object. - * - * @param[in] ofp pointer to a @p objects_fifo_t structure - * @param[in] objp pointer to the object to be released - * - * @sclass - */ -static inline void chFifoReturnObjectS(objects_fifo_t *ofp, - void *objp) { - - chGuardedPoolFreeS(&ofp->free, objp); -} - -/** - * @brief Releases a fetched object. - * - * @param[in] ofp pointer to a @p objects_fifo_t structure - * @param[in] objp pointer to the object to be released - * - * @api - */ -static inline void chFifoReturnObject(objects_fifo_t *ofp, - void *objp) { - - chGuardedPoolFree(&ofp->free, objp); -} - -/** - * @brief Posts an object. - * @note By design the object can be always immediately posted. - * - * @param[in] ofp pointer to a @p objects_fifo_t structure - * @param[in] objp pointer to the object to be posted - * - * @iclass - */ -static inline void chFifoSendObjectI(objects_fifo_t *ofp, - void *objp) { - msg_t msg; - - msg = chMBPostI(&ofp->mbx, (msg_t)objp); - chDbgAssert(msg == MSG_OK, "post failed"); -} - -/** - * @brief Posts an object. - * @note By design the object can be always immediately posted. - * - * @param[in] ofp pointer to a @p objects_fifo_t structure - * @param[in] objp pointer to the object to be posted - * - * @sclass - */ -static inline void chFifoSendObjectS(objects_fifo_t *ofp, - void *objp) { - msg_t msg; - - msg = chMBPostTimeoutS(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE); - chDbgAssert(msg == MSG_OK, "post failed"); -} - -/** - * @brief Posts an object. - * @note By design the object can be always immediately posted. - * - * @param[in] ofp pointer to a @p objects_fifo_t structure - * @param[in] objp pointer to the object to be released - * - * @api - */ -static inline void chFifoSendObject(objects_fifo_t *ofp, void *objp) { - - msg_t msg; - - msg = chMBPostTimeout(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE); - chDbgAssert(msg == MSG_OK, "post failed"); -} - -/** - * @brief Posts an high priority object. - * @note By design the object can be always immediately posted. - * - * @param[in] ofp pointer to a @p objects_fifo_t structure - * @param[in] objp pointer to the object to be posted - * - * @iclass - */ -static inline void chFifoSendObjectAheadI(objects_fifo_t *ofp, - void *objp) { - msg_t msg; - - msg = chMBPostAheadI(&ofp->mbx, (msg_t)objp); - chDbgAssert(msg == MSG_OK, "post failed"); -} - -/** - * @brief Posts an high priority object. - * @note By design the object can be always immediately posted. - * - * @param[in] ofp pointer to a @p objects_fifo_t structure - * @param[in] objp pointer to the object to be posted - * - * @sclass - */ -static inline void chFifoSendObjectAheadS(objects_fifo_t *ofp, - void *objp) { - msg_t msg; - - msg = chMBPostAheadTimeoutS(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE); - chDbgAssert(msg == MSG_OK, "post failed"); -} - -/** - * @brief Posts an high priority object. - * @note By design the object can be always immediately posted. - * - * @param[in] ofp pointer to a @p objects_fifo_t structure - * @param[in] objp pointer to the object to be released - * - * @api - */ -static inline void chFifoSendObjectAhead(objects_fifo_t *ofp, void *objp) { - - msg_t msg; - - msg = chMBPostAheadTimeout(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE); - chDbgAssert(msg == MSG_OK, "post failed"); -} - -/** - * @brief Fetches an object. - * - * @param[in] ofp pointer to a @p objects_fifo_t structure - * @param[in] objpp pointer to the fetched object reference - * @return The operation status. - * @retval MSG_OK if an object has been correctly fetched. - * @retval MSG_TIMEOUT if the FIFO is empty and a message cannot be fetched. - * - * @iclass - */ -static inline msg_t chFifoReceiveObjectI(objects_fifo_t *ofp, - void **objpp) { - - return chMBFetchI(&ofp->mbx, (msg_t *)objpp); -} - -/** - * @brief Fetches an object. - * - * @param[in] ofp pointer to a @p objects_fifo_t structure - * @param[in] objpp pointer to the fetched object reference - * @param[in] timeout the number of ticks before the operation timeouts, - * the following special values are allowed: - * - @a TIME_IMMEDIATE immediate timeout. - * - @a TIME_INFINITE no timeout. - * . - * @return The operation status. - * @retval MSG_OK if an object has been correctly fetched. - * @retval MSG_TIMEOUT if the operation has timed out. - * - * @sclass - */ -static inline msg_t chFifoReceiveObjectTimeoutS(objects_fifo_t *ofp, - void **objpp, - sysinterval_t timeout) { - - return chMBFetchTimeoutS(&ofp->mbx, (msg_t *)objpp, timeout); -} - -/** - * @brief Fetches an object. - * - * @param[in] ofp pointer to a @p objects_fifo_t structure - * @param[in] objpp pointer to the fetched object reference - * @param[in] timeout the number of ticks before the operation timeouts, - * the following special values are allowed: - * - @a TIME_IMMEDIATE immediate timeout. - * - @a TIME_INFINITE no timeout. - * . - * @return The operation status. - * @retval MSG_OK if an object has been correctly fetched. - * @retval MSG_TIMEOUT if the operation has timed out. - * - * @api - */ -static inline msg_t chFifoReceiveObjectTimeout(objects_fifo_t *ofp, - void **objpp, - sysinterval_t timeout) { - - return chMBFetchTimeout(&ofp->mbx, (msg_t *)objpp, timeout); -} - -#endif /* CH_CFG_USE_OBJ_FIFOS == TRUE */ - -#endif /* CHOBJFIFOS_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014, + 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 3 of the License. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file oslib/include/chobjfifos.h + * @brief Objects FIFO structures and macros. + * @details This module implements a generic FIFO queue of objects by + * coupling a Guarded Memory Pool (for objects storage) and + * a MailBox.
+ * On the sender side free objects are taken from the pool, filled + * and then sent to the receiver, on the receiver side objects are + * fetched, used and then returned to the pool. + * Operations defined for object FIFOs: + * - Take: An object is taken from the pool of the free + * objects, can be blocking. + * - Return: An object is returned to the pool of the + * free objects, it is guaranteed to be non-blocking. + * - Send: An object is sent through the mailbox, it is + * guaranteed to be non-blocking + * - Receive: An object is received from the mailbox, + * can be blocking. + * . + * + * @addtogroup oslib_objects_fifos + * @{ + */ + +#ifndef CHOBJFIFOS_H +#define CHOBJFIFOS_H + +#if (CH_CFG_USE_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if CH_CFG_USE_MEMPOOLS == FALSE +#error "CH_CFG_USE_OBJ_FIFOS requires CH_CFG_USE_MEMPOOLS" +#endif + +#if CH_CFG_USE_SEMAPHORES == FALSE +#error "CH_CFG_USE_OBJ_FIFOS requires CH_CFG_USE_SEMAPHORES" +#endif + +#if CH_CFG_USE_MAILBOXES == FALSE +#error "CH_CFG_USE_OBJ_FIFOS requires CH_CFG_USE_MAILBOXES" +#endif + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of an objects FIFO. + */ +typedef struct ch_objects_fifo { + /** + * @brief Pool of the free objects. + */ + guarded_memory_pool_t free; + /** + * @brief Mailbox of the sent objects. + */ + mailbox_t mbx; +} objects_fifo_t; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes a FIFO object. + * @pre The messages size must be a multiple of the alignment + * requirement. + * + * @param[out] ofp pointer to a @p objects_fifo_t structure + * @param[in] objsize object size + * @param[in] objn number of objects available + * @param[in] objalign required objects alignment + * @param[in] objbuf pointer to the buffer of objects, it must be able + * to hold @p objn objects of @p objsize size with + * @p objalign alignment + * @param[in] msgbuf pointer to the buffer of messages, it must be able + * to hold @p objn messages + * + * @init + */ +static inline void chFifoObjectInitAligned(objects_fifo_t *ofp, size_t objsize, + size_t objn, unsigned objalign, + void *objbuf, msg_t *msgbuf) { + + chDbgCheck((objsize >= objalign) && ((objsize % objalign) == 0U)); + + chGuardedPoolObjectInitAligned(&ofp->free, objsize, objalign); + chGuardedPoolLoadArray(&ofp->free, objbuf, objn); + chMBObjectInit(&ofp->mbx, msgbuf, objn); +} + +/** + * @brief Initializes a FIFO object. + * @pre The messages size must be a multiple of the alignment + * requirement. + * + * @param[out] ofp pointer to a @p objects_fifo_t structure + * @param[in] objsize object size + * @param[in] objn number of objects available + * @param[in] objbuf pointer to the buffer of objects, it must be able + * to hold @p objn objects of @p objsize size + * @param[in] msgbuf pointer to the buffer of messages, it must be able + * to hold @p objn messages + * + * @init + */ +static inline void chFifoObjectInit(objects_fifo_t *ofp, size_t objsize, + size_t objn, void *objbuf, + msg_t *msgbuf) { + + chFifoObjectInitAligned(ofp, objsize, objn, + PORT_NATURAL_ALIGN, + objbuf, msgbuf); +} + +/** + * @brief Allocates a free object. + * + * @param[in] ofp pointer to a @p objects_fifo_t structure + * @return The pointer to the allocated object. + * @retval NULL if an object is not immediately available. + * + * @iclass + */ +static inline void *chFifoTakeObjectI(objects_fifo_t *ofp) { + + return chGuardedPoolAllocI(&ofp->free); +} + +/** + * @brief Allocates a free object. + * + * @param[in] ofp pointer to a @p objects_fifo_t structure + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The pointer to the allocated object. + * @retval NULL if an object is not available within the specified + * timeout. + * + * @sclass + */ +static inline void *chFifoTakeObjectTimeoutS(objects_fifo_t *ofp, + sysinterval_t timeout) { + + return chGuardedPoolAllocTimeoutS(&ofp->free, timeout); +} + +/** + * @brief Allocates a free object. + * + * @param[in] ofp pointer to a @p objects_fifo_t structure + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The pointer to the allocated object. + * @retval NULL if an object is not available within the specified + * timeout. + * + * @api + */ +static inline void *chFifoTakeObjectTimeout(objects_fifo_t *ofp, + sysinterval_t timeout) { + + return chGuardedPoolAllocTimeout(&ofp->free, timeout); +} + +/** + * @brief Releases a fetched object. + * + * @param[in] ofp pointer to a @p objects_fifo_t structure + * @param[in] objp pointer to the object to be released + * + * @iclass + */ +static inline void chFifoReturnObjectI(objects_fifo_t *ofp, + void *objp) { + + chGuardedPoolFreeI(&ofp->free, objp); +} + +/** + * @brief Releases a fetched object. + * + * @param[in] ofp pointer to a @p objects_fifo_t structure + * @param[in] objp pointer to the object to be released + * + * @sclass + */ +static inline void chFifoReturnObjectS(objects_fifo_t *ofp, + void *objp) { + + chGuardedPoolFreeS(&ofp->free, objp); +} + +/** + * @brief Releases a fetched object. + * + * @param[in] ofp pointer to a @p objects_fifo_t structure + * @param[in] objp pointer to the object to be released + * + * @api + */ +static inline void chFifoReturnObject(objects_fifo_t *ofp, + void *objp) { + + chGuardedPoolFree(&ofp->free, objp); +} + +/** + * @brief Posts an object. + * @note By design the object can be always immediately posted. + * + * @param[in] ofp pointer to a @p objects_fifo_t structure + * @param[in] objp pointer to the object to be posted + * + * @iclass + */ +static inline void chFifoSendObjectI(objects_fifo_t *ofp, + void *objp) { + msg_t msg; + + msg = chMBPostI(&ofp->mbx, (msg_t)objp); + chDbgAssert(msg == MSG_OK, "post failed"); +} + +/** + * @brief Posts an object. + * @note By design the object can be always immediately posted. + * + * @param[in] ofp pointer to a @p objects_fifo_t structure + * @param[in] objp pointer to the object to be posted + * + * @sclass + */ +static inline void chFifoSendObjectS(objects_fifo_t *ofp, + void *objp) { + msg_t msg; + + msg = chMBPostTimeoutS(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE); + chDbgAssert(msg == MSG_OK, "post failed"); +} + +/** + * @brief Posts an object. + * @note By design the object can be always immediately posted. + * + * @param[in] ofp pointer to a @p objects_fifo_t structure + * @param[in] objp pointer to the object to be released + * + * @api + */ +static inline void chFifoSendObject(objects_fifo_t *ofp, void *objp) { + + msg_t msg; + + msg = chMBPostTimeout(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE); + chDbgAssert(msg == MSG_OK, "post failed"); +} + +/** + * @brief Posts an high priority object. + * @note By design the object can be always immediately posted. + * + * @param[in] ofp pointer to a @p objects_fifo_t structure + * @param[in] objp pointer to the object to be posted + * + * @iclass + */ +static inline void chFifoSendObjectAheadI(objects_fifo_t *ofp, + void *objp) { + msg_t msg; + + msg = chMBPostAheadI(&ofp->mbx, (msg_t)objp); + chDbgAssert(msg == MSG_OK, "post failed"); +} + +/** + * @brief Posts an high priority object. + * @note By design the object can be always immediately posted. + * + * @param[in] ofp pointer to a @p objects_fifo_t structure + * @param[in] objp pointer to the object to be posted + * + * @sclass + */ +static inline void chFifoSendObjectAheadS(objects_fifo_t *ofp, + void *objp) { + msg_t msg; + + msg = chMBPostAheadTimeoutS(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE); + chDbgAssert(msg == MSG_OK, "post failed"); +} + +/** + * @brief Posts an high priority object. + * @note By design the object can be always immediately posted. + * + * @param[in] ofp pointer to a @p objects_fifo_t structure + * @param[in] objp pointer to the object to be released + * + * @api + */ +static inline void chFifoSendObjectAhead(objects_fifo_t *ofp, void *objp) { + + msg_t msg; + + msg = chMBPostAheadTimeout(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE); + chDbgAssert(msg == MSG_OK, "post failed"); +} + +/** + * @brief Fetches an object. + * + * @param[in] ofp pointer to a @p objects_fifo_t structure + * @param[in] objpp pointer to the fetched object reference + * @return The operation status. + * @retval MSG_OK if an object has been correctly fetched. + * @retval MSG_TIMEOUT if the FIFO is empty and a message cannot be fetched. + * + * @iclass + */ +static inline msg_t chFifoReceiveObjectI(objects_fifo_t *ofp, + void **objpp) { + + return chMBFetchI(&ofp->mbx, (msg_t *)objpp); +} + +/** + * @brief Fetches an object. + * + * @param[in] ofp pointer to a @p objects_fifo_t structure + * @param[in] objpp pointer to the fetched object reference + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The operation status. + * @retval MSG_OK if an object has been correctly fetched. + * @retval MSG_TIMEOUT if the operation has timed out. + * + * @sclass + */ +static inline msg_t chFifoReceiveObjectTimeoutS(objects_fifo_t *ofp, + void **objpp, + sysinterval_t timeout) { + + return chMBFetchTimeoutS(&ofp->mbx, (msg_t *)objpp, timeout); +} + +/** + * @brief Fetches an object. + * + * @param[in] ofp pointer to a @p objects_fifo_t structure + * @param[in] objpp pointer to the fetched object reference + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The operation status. + * @retval MSG_OK if an object has been correctly fetched. + * @retval MSG_TIMEOUT if the operation has timed out. + * + * @api + */ +static inline msg_t chFifoReceiveObjectTimeout(objects_fifo_t *ofp, + void **objpp, + sysinterval_t timeout) { + + return chMBFetchTimeout(&ofp->mbx, (msg_t *)objpp, timeout); +} + +#endif /* CH_CFG_USE_OBJ_FIFOS == TRUE */ + +#endif /* CHOBJFIFOS_H */ + +/** @} */ From 5470978e3d66cb9a6646fc6b500c0922ecf5a4c7 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 28 May 2023 07:41:19 +0000 Subject: [PATCH 31/53] Fixed some device description strings. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16271 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/STM32F7xx/hal_lld.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/os/hal/ports/STM32/STM32F7xx/hal_lld.h b/os/hal/ports/STM32/STM32F7xx/hal_lld.h index 877eabf3d7..e3d8d82405 100644 --- a/os/hal/ports/STM32/STM32F7xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32F7xx/hal_lld.h @@ -57,16 +57,16 @@ * @{ */ #if defined(STM32F722xx) || defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32F745 Very High Performance with DSP and FPU" +#define PLATFORM_NAME "STM32F722 Very High Performance with DSP and FPU" #elif defined(STM32F723xx) -#define PLATFORM_NAME "STM32F745 Very High Performance with DSP and FPU" +#define PLATFORM_NAME "STM32F723 Very High Performance with DSP and FPU" #elif defined(STM32F732xx) -#define PLATFORM_NAME "STM32F745 Very High Performance with DSP and FPU" +#define PLATFORM_NAME "STM32F732 Very High Performance with DSP and FPU" #elif defined(STM32F733xx) -#define PLATFORM_NAME "STM32F745 Very High Performance with DSP and FPU" +#define PLATFORM_NAME "STM32F733 Very High Performance with DSP and FPU" #elif defined(STM32F745xx) #define PLATFORM_NAME "STM32F745 Very High Performance with DSP and FPU" From f9c5e95db966d465cfc6ec6ef5063a986a89bdd8 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Mon, 19 Jun 2023 17:29:16 +0000 Subject: [PATCH 32/53] Fixed a possible name conflict in oslib.mk. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16296 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/oslib/oslib.mk | 114 +++++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/os/oslib/oslib.mk b/os/oslib/oslib.mk index c0b95a8ba0..a264e60abf 100644 --- a/os/oslib/oslib.mk +++ b/os/oslib/oslib.mk @@ -1,57 +1,57 @@ -# List of all the ChibiOS/LIB files, there is no need to remove the files -# from this list, you can disable parts of the kernel by editing chlibconf.h. -ifeq ($(USE_SMART_BUILD),yes) - -# Configuration files directory -ifeq ($(CHCONFDIR),) - ifeq ($(CONFDIR),) - CHCONFDIR = . - else - CHCONFDIR := $(CONFDIR) - endif -endif - -CHLIBCONF := $(strip $(shell cat $(CHCONFDIR)/chconf.h | egrep -e "\#define")) - -LIBSRC := -ifneq ($(findstring CH_CFG_USE_MAILBOXES TRUE,$(CHLIBCONF)),) -LIBSRC += $(CHIBIOS)/os/oslib/src/chmboxes.c -endif -ifneq ($(findstring CH_CFG_USE_MEMCORE TRUE,$(CHLIBCONF)),) -LIBSRC += $(CHIBIOS)/os/oslib/src/chmemcore.c -endif -ifneq ($(findstring CH_CFG_USE_HEAP TRUE,$(CHLIBCONF)),) -LIBSRC += $(CHIBIOS)/os/oslib/src/chmemheaps.c -endif -ifneq ($(findstring CH_CFG_USE_MEMPOOLS TRUE,$(CHLIBCONF)),) -LIBSRC += $(CHIBIOS)/os/oslib/src/chmempools.c -endif -ifneq ($(findstring CH_CFG_USE_PIPES TRUE,$(CHLIBCONF)),) -LIBSRC += $(CHIBIOS)/os/oslib/src/chpipes.c -endif -ifneq ($(findstring CH_CFG_USE_OBJ_CACHES TRUE,$(CHLIBCONF)),) -LIBSRC += $(CHIBIOS)/os/oslib/src/chobjcaches.c -endif -ifneq ($(findstring CH_CFG_USE_DELEGATES TRUE,$(CHLIBCONF)),) -LIBSRC += $(CHIBIOS)/os/oslib/src/chdelegates.c -endif -ifneq ($(findstring CH_CFG_USE_FACTORY TRUE,$(CHLIBCONF)),) -LIBSRC += $(CHIBIOS)/os/oslib/src/chfactory.c -endif -else -LIBSRC := $(CHIBIOS)/os/oslib/src/chmboxes.c \ - $(CHIBIOS)/os/oslib/src/chmemcore.c \ - $(CHIBIOS)/os/oslib/src/chmemheaps.c \ - $(CHIBIOS)/os/oslib/src/chmempools.c \ - $(CHIBIOS)/os/oslib/src/chpipes.c \ - $(CHIBIOS)/os/oslib/src/chobjcaches.c \ - $(CHIBIOS)/os/oslib/src/chdelegates.c \ - $(CHIBIOS)/os/oslib/src/chfactory.c -endif - -# Required include directories -LIBINC := $(CHIBIOS)/os/oslib/include - -# Shared variables -ALLCSRC += $(LIBSRC) -ALLINC += $(LIBINC) +# List of all the ChibiOS/LIB files. +ifeq ($(USE_SMART_BUILD),yes) + +# Configuration files directory +ifeq ($(CHCONFDIR),) + ifeq ($(CONFDIR),) + CHCONFDIR = . + else + CHCONFDIR := $(CONFDIR) + endif +endif + +CHLIBCONF := $(strip $(shell cat $(CHCONFDIR)/chconf.h | egrep -e "\#define")) + +OSLIBSRC := $(CHIBIOS)/os/oslib/src/chmemchecks.c +ifneq ($(findstring CH_CFG_USE_MAILBOXES TRUE,$(CHLIBCONF)),) +OSLIBSRC += $(CHIBIOS)/os/oslib/src/chmboxes.c +endif +ifneq ($(findstring CH_CFG_USE_MEMCORE TRUE,$(CHLIBCONF)),) +OSLIBSRC += $(CHIBIOS)/os/oslib/src/chmemcore.c +endif +ifneq ($(findstring CH_CFG_USE_HEAP TRUE,$(CHLIBCONF)),) +OSLIBSRC += $(CHIBIOS)/os/oslib/src/chmemheaps.c +endif +ifneq ($(findstring CH_CFG_USE_MEMPOOLS TRUE,$(CHLIBCONF)),) +OSLIBSRC += $(CHIBIOS)/os/oslib/src/chmempools.c +endif +ifneq ($(findstring CH_CFG_USE_PIPES TRUE,$(CHLIBCONF)),) +OSLIBSRC += $(CHIBIOS)/os/oslib/src/chpipes.c +endif +ifneq ($(findstring CH_CFG_USE_OBJ_CACHES TRUE,$(CHLIBCONF)),) +OSLIBSRC += $(CHIBIOS)/os/oslib/src/chobjcaches.c +endif +ifneq ($(findstring CH_CFG_USE_DELEGATES TRUE,$(CHLIBCONF)),) +OSLIBSRC += $(CHIBIOS)/os/oslib/src/chdelegates.c +endif +ifneq ($(findstring CH_CFG_USE_FACTORY TRUE,$(CHLIBCONF)),) +OSLIBSRC += $(CHIBIOS)/os/oslib/src/chfactory.c +endif +else +OSLIBSRC := $(CHIBIOS)/os/oslib/src/chmemchecks.c \ + $(CHIBIOS)/os/oslib/src/chmboxes.c \ + $(CHIBIOS)/os/oslib/src/chmemcore.c \ + $(CHIBIOS)/os/oslib/src/chmemheaps.c \ + $(CHIBIOS)/os/oslib/src/chmempools.c \ + $(CHIBIOS)/os/oslib/src/chpipes.c \ + $(CHIBIOS)/os/oslib/src/chobjcaches.c \ + $(CHIBIOS)/os/oslib/src/chdelegates.c \ + $(CHIBIOS)/os/oslib/src/chfactory.c +endif + +# Required include directories +OSLIBINC := $(CHIBIOS)/os/oslib/include + +# Shared variables +ALLCSRC += $(OSLIBSRC) +ALLINC += $(OSLIBINC) From 7e34aeaa98e601d59f0f0a27fa713a2b4db9c30a Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 2 Jul 2023 08:34:38 +0000 Subject: [PATCH 33/53] Explicit LTO mode. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16309 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/common/startup/ARM/compilers/GCC/rules.mk | 2 +- os/common/startup/ARMCMx/compilers/GCC/mk/rules.mk | 2 +- os/common/startup/SIMIA32/compilers/GCC/rules.mk | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/os/common/startup/ARM/compilers/GCC/rules.mk b/os/common/startup/ARM/compilers/GCC/rules.mk index a7c78835a5..5af2b6a61f 100644 --- a/os/common/startup/ARM/compilers/GCC/rules.mk +++ b/os/common/startup/ARM/compilers/GCC/rules.mk @@ -24,7 +24,7 @@ endif # Link time optimizations ifeq ($(USE_LTO),yes) - OPT += -flto + OPT += -flto=auto endif # Undefined state stack size diff --git a/os/common/startup/ARMCMx/compilers/GCC/mk/rules.mk b/os/common/startup/ARMCMx/compilers/GCC/mk/rules.mk index 4f7178de5a..a65d8cdff6 100644 --- a/os/common/startup/ARMCMx/compilers/GCC/mk/rules.mk +++ b/os/common/startup/ARMCMx/compilers/GCC/mk/rules.mk @@ -24,7 +24,7 @@ endif # Link time optimizations ifeq ($(USE_LTO),yes) - OPT += -flto + OPT += -flto=auto endif # FPU options default (Cortex-M4 and Cortex-M7 single precision). diff --git a/os/common/startup/SIMIA32/compilers/GCC/rules.mk b/os/common/startup/SIMIA32/compilers/GCC/rules.mk index 73a6d14f89..4bf6b993a4 100644 --- a/os/common/startup/SIMIA32/compilers/GCC/rules.mk +++ b/os/common/startup/SIMIA32/compilers/GCC/rules.mk @@ -24,7 +24,7 @@ endif # Link time optimizations ifeq ($(USE_LTO),yes) - OPT += -flto + OPT += -flto=auto endif # Output directory and files From deaa86b8f1db94eaf24ae18b0e387e5e57f12946 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 2 Jul 2023 08:52:49 +0000 Subject: [PATCH 34/53] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16310 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/STM32L4xx+/stm32_registry.h | 4 ++-- os/hal/ports/STM32/STM32L4xx/stm32_registry.h | 12 +++++++----- os/hal/ports/STM32/STM32L5xx/stm32_registry.h | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/os/hal/ports/STM32/STM32L4xx+/stm32_registry.h b/os/hal/ports/STM32/STM32L4xx+/stm32_registry.h index 88673699c7..dd3373c4d9 100644 --- a/os/hal/ports/STM32/STM32L4xx+/stm32_registry.h +++ b/os/hal/ports/STM32/STM32L4xx+/stm32_registry.h @@ -213,11 +213,11 @@ #define STM32_HAS_TIM16 TRUE #define STM32_TIM16_IS_32BITS FALSE -#define STM32_TIM16_CHANNELS 2 +#define STM32_TIM16_CHANNELS 1 #define STM32_HAS_TIM17 TRUE #define STM32_TIM17_IS_32BITS FALSE -#define STM32_TIM17_CHANNELS 2 +#define STM32_TIM17_CHANNELS 1 #define STM32_HAS_TIM9 FALSE #define STM32_HAS_TIM10 FALSE diff --git a/os/hal/ports/STM32/STM32L4xx/stm32_registry.h b/os/hal/ports/STM32/STM32L4xx/stm32_registry.h index feddac2c87..da1a4819e8 100644 --- a/os/hal/ports/STM32/STM32L4xx/stm32_registry.h +++ b/os/hal/ports/STM32/STM32L4xx/stm32_registry.h @@ -223,7 +223,7 @@ #define STM32_HAS_TIM16 TRUE #define STM32_TIM16_IS_32BITS FALSE -#define STM32_TIM16_CHANNELS 2 +#define STM32_TIM16_CHANNELS 1 #define STM32_HAS_TIM3 FALSE #define STM32_HAS_TIM4 FALSE @@ -463,7 +463,7 @@ #define STM32_HAS_TIM16 TRUE #define STM32_TIM16_IS_32BITS FALSE -#define STM32_TIM16_CHANNELS 2 +#define STM32_TIM16_CHANNELS 1 #define STM32_HAS_TIM3 FALSE #define STM32_HAS_TIM4 FALSE @@ -702,7 +702,7 @@ #define STM32_HAS_TIM16 TRUE #define STM32_TIM16_IS_32BITS FALSE -#define STM32_TIM16_CHANNELS 2 +#define STM32_TIM16_CHANNELS 1 #define STM32_HAS_TIM4 FALSE #define STM32_HAS_TIM5 FALSE @@ -978,11 +978,11 @@ #define STM32_HAS_TIM16 TRUE #define STM32_TIM16_IS_32BITS FALSE -#define STM32_TIM16_CHANNELS 2 +#define STM32_TIM16_CHANNELS 1 #define STM32_HAS_TIM17 TRUE #define STM32_TIM17_IS_32BITS FALSE -#define STM32_TIM17_CHANNELS 2 +#define STM32_TIM17_CHANNELS 1 #define STM32_HAS_TIM9 FALSE #define STM32_HAS_TIM10 FALSE @@ -1262,9 +1262,11 @@ #define STM32_HAS_TIM16 TRUE #define STM32_TIM16_IS_32BITS FALSE +#define STM32_TIM16_CHANNELS 1 #define STM32_HAS_TIM17 TRUE #define STM32_TIM17_IS_32BITS FALSE +#define STM32_TIM17_CHANNELS 1 #define STM32_HAS_TIM9 FALSE #define STM32_HAS_TIM10 FALSE diff --git a/os/hal/ports/STM32/STM32L5xx/stm32_registry.h b/os/hal/ports/STM32/STM32L5xx/stm32_registry.h index 1b0b0246ed..8c1aabc77a 100644 --- a/os/hal/ports/STM32/STM32L5xx/stm32_registry.h +++ b/os/hal/ports/STM32/STM32L5xx/stm32_registry.h @@ -207,11 +207,11 @@ #define STM32_HAS_TIM16 TRUE #define STM32_TIM16_IS_32BITS FALSE -#define STM32_TIM16_CHANNELS 2 +#define STM32_TIM16_CHANNELS 1 #define STM32_HAS_TIM17 TRUE #define STM32_TIM17_IS_32BITS FALSE -#define STM32_TIM17_CHANNELS 2 +#define STM32_TIM17_CHANNELS 1 #define STM32_HAS_TIM9 FALSE #define STM32_HAS_TIM10 FALSE From 214fede5aa2809c55b7bb3f0414da7da90cb9065 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 8 Jul 2023 06:39:28 +0000 Subject: [PATCH 35/53] Fixed OSLIB makefile regression. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16312 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/oslib/oslib.mk | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/os/oslib/oslib.mk b/os/oslib/oslib.mk index a264e60abf..bdfba1864a 100644 --- a/os/oslib/oslib.mk +++ b/os/oslib/oslib.mk @@ -12,7 +12,6 @@ endif CHLIBCONF := $(strip $(shell cat $(CHCONFDIR)/chconf.h | egrep -e "\#define")) -OSLIBSRC := $(CHIBIOS)/os/oslib/src/chmemchecks.c ifneq ($(findstring CH_CFG_USE_MAILBOXES TRUE,$(CHLIBCONF)),) OSLIBSRC += $(CHIBIOS)/os/oslib/src/chmboxes.c endif @@ -38,8 +37,7 @@ ifneq ($(findstring CH_CFG_USE_FACTORY TRUE,$(CHLIBCONF)),) OSLIBSRC += $(CHIBIOS)/os/oslib/src/chfactory.c endif else -OSLIBSRC := $(CHIBIOS)/os/oslib/src/chmemchecks.c \ - $(CHIBIOS)/os/oslib/src/chmboxes.c \ +OSLIBSRC := $(CHIBIOS)/os/oslib/src/chmboxes.c \ $(CHIBIOS)/os/oslib/src/chmemcore.c \ $(CHIBIOS)/os/oslib/src/chmemheaps.c \ $(CHIBIOS)/os/oslib/src/chmempools.c \ From 755714606bb5a62a5e31ec3a7ef8d5a37193fc61 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 8 Jul 2023 06:54:31 +0000 Subject: [PATCH 36/53] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16313 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/boards/ST_NUCLEO144_L496ZG/board.c | 562 +-- os/hal/boards/ST_NUCLEO144_L496ZG/board.h | 3122 +++++++++-------- os/hal/boards/ST_NUCLEO144_L496ZG/board.mk | 18 +- .../ST_NUCLEO144_L496ZG/cfg/board.chcfg | 890 ++--- 4 files changed, 2404 insertions(+), 2188 deletions(-) diff --git a/os/hal/boards/ST_NUCLEO144_L496ZG/board.c b/os/hal/boards/ST_NUCLEO144_L496ZG/board.c index cd16e432e6..74e05f3a48 100644 --- a/os/hal/boards/ST_NUCLEO144_L496ZG/board.c +++ b/os/hal/boards/ST_NUCLEO144_L496ZG/board.c @@ -1,281 +1,281 @@ -/* - ChibiOS - Copyright (C) 2006..2018 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. -*/ - -/* - * This file has been automatically generated using ChibiStudio board - * generator plugin. Do not edit manually. - */ - -#include "hal.h" -#include "stm32_gpio.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/** - * @brief Type of STM32 GPIO port setup. - */ -typedef struct { - uint32_t moder; - uint32_t otyper; - uint32_t ospeedr; - uint32_t pupdr; - uint32_t odr; - uint32_t afrl; - uint32_t afrh; - uint32_t ascr; - uint32_t lockr; -} gpio_setup_t; - -/** - * @brief Type of STM32 GPIO initialization data. - */ -typedef struct { -#if STM32_HAS_GPIOA || defined(__DOXYGEN__) - gpio_setup_t PAData; -#endif -#if STM32_HAS_GPIOB || defined(__DOXYGEN__) - gpio_setup_t PBData; -#endif -#if STM32_HAS_GPIOC || defined(__DOXYGEN__) - gpio_setup_t PCData; -#endif -#if STM32_HAS_GPIOD || defined(__DOXYGEN__) - gpio_setup_t PDData; -#endif -#if STM32_HAS_GPIOE || defined(__DOXYGEN__) - gpio_setup_t PEData; -#endif -#if STM32_HAS_GPIOF || defined(__DOXYGEN__) - gpio_setup_t PFData; -#endif -#if STM32_HAS_GPIOG || defined(__DOXYGEN__) - gpio_setup_t PGData; -#endif -#if STM32_HAS_GPIOH || defined(__DOXYGEN__) - gpio_setup_t PHData; -#endif -#if STM32_HAS_GPIOI || defined(__DOXYGEN__) - gpio_setup_t PIData; -#endif -#if STM32_HAS_GPIOJ || defined(__DOXYGEN__) - gpio_setup_t PJData; -#endif -#if STM32_HAS_GPIOK || defined(__DOXYGEN__) - gpio_setup_t PKData; -#endif -} gpio_config_t; - -/** - * @brief STM32 GPIO static initialization data. - */ -static const gpio_config_t gpio_default_config = { -#if STM32_HAS_GPIOA - {VAL_GPIOA_MODER, VAL_GPIOA_OTYPER, VAL_GPIOA_OSPEEDR, VAL_GPIOA_PUPDR, - VAL_GPIOA_ODR, VAL_GPIOA_AFRL, VAL_GPIOA_AFRH, VAL_GPIOA_ASCR, - VAL_GPIOA_LOCKR}, -#endif -#if STM32_HAS_GPIOB - {VAL_GPIOB_MODER, VAL_GPIOB_OTYPER, VAL_GPIOB_OSPEEDR, VAL_GPIOB_PUPDR, - VAL_GPIOB_ODR, VAL_GPIOB_AFRL, VAL_GPIOB_AFRH, VAL_GPIOB_ASCR, - VAL_GPIOB_LOCKR}, -#endif -#if STM32_HAS_GPIOC - {VAL_GPIOC_MODER, VAL_GPIOC_OTYPER, VAL_GPIOC_OSPEEDR, VAL_GPIOC_PUPDR, - VAL_GPIOC_ODR, VAL_GPIOC_AFRL, VAL_GPIOC_AFRH, VAL_GPIOC_ASCR, - VAL_GPIOC_LOCKR}, -#endif -#if STM32_HAS_GPIOD - {VAL_GPIOD_MODER, VAL_GPIOD_OTYPER, VAL_GPIOD_OSPEEDR, VAL_GPIOD_PUPDR, - VAL_GPIOD_ODR, VAL_GPIOD_AFRL, VAL_GPIOD_AFRH, VAL_GPIOD_ASCR, - VAL_GPIOD_LOCKR}, -#endif -#if STM32_HAS_GPIOE - {VAL_GPIOE_MODER, VAL_GPIOE_OTYPER, VAL_GPIOE_OSPEEDR, VAL_GPIOE_PUPDR, - VAL_GPIOE_ODR, VAL_GPIOE_AFRL, VAL_GPIOE_AFRH, VAL_GPIOE_ASCR, - VAL_GPIOE_LOCKR}, -#endif -#if STM32_HAS_GPIOF - {VAL_GPIOF_MODER, VAL_GPIOF_OTYPER, VAL_GPIOF_OSPEEDR, VAL_GPIOF_PUPDR, - VAL_GPIOF_ODR, VAL_GPIOF_AFRL, VAL_GPIOF_AFRH, VAL_GPIOF_ASCR, - VAL_GPIOF_LOCKR}, -#endif -#if STM32_HAS_GPIOG - {VAL_GPIOG_MODER, VAL_GPIOG_OTYPER, VAL_GPIOG_OSPEEDR, VAL_GPIOG_PUPDR, - VAL_GPIOG_ODR, VAL_GPIOG_AFRL, VAL_GPIOG_AFRH, VAL_GPIOG_ASCR, - VAL_GPIOG_LOCKR}, -#endif -#if STM32_HAS_GPIOH - {VAL_GPIOH_MODER, VAL_GPIOH_OTYPER, VAL_GPIOH_OSPEEDR, VAL_GPIOH_PUPDR, - VAL_GPIOH_ODR, VAL_GPIOH_AFRL, VAL_GPIOH_AFRH, VAL_GPIOH_ASCR, - VAL_GPIOH_LOCKR}, -#endif -#if STM32_HAS_GPIOI - {VAL_GPIOI_MODER, VAL_GPIOI_OTYPER, VAL_GPIOI_OSPEEDR, VAL_GPIOI_PUPDR, - VAL_GPIOI_ODR, VAL_GPIOI_AFRL, VAL_GPIOI_AFRH, VAL_GPIOI_ASCR, - VAL_GPIOI_LOCKR}, -#endif -#if STM32_HAS_GPIOJ - {VAL_GPIOJ_MODER, VAL_GPIOJ_OTYPER, VAL_GPIOJ_OSPEEDR, VAL_GPIOJ_PUPDR, - VAL_GPIOJ_ODR, VAL_GPIOJ_AFRL, VAL_GPIOJ_AFRH, VAL_GPIOJ_ASCR, - VAL_GPIOJ_LOCKR}, -#endif -#if STM32_HAS_GPIOK - {VAL_GPIOK_MODER, VAL_GPIOK_OTYPER, VAL_GPIOK_OSPEEDR, VAL_GPIOK_PUPDR, - VAL_GPIOK_ODR, VAL_GPIOK_AFRL, VAL_GPIOK_AFRH, VAL_GPIOK_ASCR, - VAL_GPIOK_LOCKR} -#endif -}; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -static void gpio_init(stm32_gpio_t *gpiop, const gpio_setup_t *config) { - - gpiop->OTYPER = config->otyper; - gpiop->ASCR = config->ascr; - gpiop->OSPEEDR = config->ospeedr; - gpiop->PUPDR = config->pupdr; - gpiop->ODR = config->odr; - gpiop->AFRL = config->afrl; - gpiop->AFRH = config->afrh; - gpiop->MODER = config->moder; - gpiop->LOCKR = config->lockr; -} - -static void stm32_gpio_init(void) { - - /* Enabling GPIO-related clocks, the mask comes from the - registry header file.*/ - rccResetAHB2(STM32_GPIO_EN_MASK); - rccEnableAHB2(STM32_GPIO_EN_MASK, true); - - /* Initializing all the defined GPIO ports.*/ -#if STM32_HAS_GPIOA - gpio_init(GPIOA, &gpio_default_config.PAData); -#endif -#if STM32_HAS_GPIOB - gpio_init(GPIOB, &gpio_default_config.PBData); -#endif -#if STM32_HAS_GPIOC - gpio_init(GPIOC, &gpio_default_config.PCData); -#endif -#if STM32_HAS_GPIOD - gpio_init(GPIOD, &gpio_default_config.PDData); -#endif -#if STM32_HAS_GPIOE - gpio_init(GPIOE, &gpio_default_config.PEData); -#endif -#if STM32_HAS_GPIOF - gpio_init(GPIOF, &gpio_default_config.PFData); -#endif -#if STM32_HAS_GPIOG - gpio_init(GPIOG, &gpio_default_config.PGData); -#endif -#if STM32_HAS_GPIOH - gpio_init(GPIOH, &gpio_default_config.PHData); -#endif -#if STM32_HAS_GPIOI - gpio_init(GPIOI, &gpio_default_config.PIData); -#endif -#if STM32_HAS_GPIOJ - gpio_init(GPIOJ, &gpio_default_config.PJData); -#endif -#if STM32_HAS_GPIOK - gpio_init(GPIOK, &gpio_default_config.PKData); -#endif -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Early initialization code. - * @details GPIO ports and system clocks are initialized before everything - * else. - */ -void __early_init(void) { - - stm32_gpio_init(); - stm32_clock_init(); -} - -#if HAL_USE_SDC || defined(__DOXYGEN__) -/** - * @brief SDC card detection. - */ -bool sdc_lld_is_card_inserted(SDCDriver *sdcp) { - - (void)sdcp; - /* CHTODO: Fill the implementation.*/ - return true; -} - -/** - * @brief SDC card write protection detection. - */ -bool sdc_lld_is_write_protected(SDCDriver *sdcp) { - - (void)sdcp; - /* CHTODO: Fill the implementation.*/ - return false; -} -#endif /* HAL_USE_SDC */ - -#if HAL_USE_MMC_SPI || defined(__DOXYGEN__) -/** - * @brief MMC_SPI card detection. - */ -bool mmc_lld_is_card_inserted(MMCDriver *mmcp) { - - (void)mmcp; - /* CHTODO: Fill the implementation.*/ - return true; -} - -/** - * @brief MMC_SPI card write protection detection. - */ -bool mmc_lld_is_write_protected(MMCDriver *mmcp) { - - (void)mmcp; - /* CHTODO: Fill the implementation.*/ - return false; -} -#endif - -/** - * @brief Board-specific initialization code. - * @note You can add your board-specific code here. - */ -void boardInit(void) { - -} +/* + ChibiOS - Copyright (C) 2006..2020 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. +*/ + +/* + * This file has been automatically generated using ChibiStudio board + * generator plugin. Do not edit manually. + */ + +#include "hal.h" +#include "stm32_gpio.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/** + * @brief Type of STM32 GPIO port setup. + */ +typedef struct { + uint32_t moder; + uint32_t otyper; + uint32_t ospeedr; + uint32_t pupdr; + uint32_t odr; + uint32_t afrl; + uint32_t afrh; + uint32_t ascr; + uint32_t lockr; +} gpio_setup_t; + +/** + * @brief Type of STM32 GPIO initialization data. + */ +typedef struct { +#if STM32_HAS_GPIOA || defined(__DOXYGEN__) + gpio_setup_t PAData; +#endif +#if STM32_HAS_GPIOB || defined(__DOXYGEN__) + gpio_setup_t PBData; +#endif +#if STM32_HAS_GPIOC || defined(__DOXYGEN__) + gpio_setup_t PCData; +#endif +#if STM32_HAS_GPIOD || defined(__DOXYGEN__) + gpio_setup_t PDData; +#endif +#if STM32_HAS_GPIOE || defined(__DOXYGEN__) + gpio_setup_t PEData; +#endif +#if STM32_HAS_GPIOF || defined(__DOXYGEN__) + gpio_setup_t PFData; +#endif +#if STM32_HAS_GPIOG || defined(__DOXYGEN__) + gpio_setup_t PGData; +#endif +#if STM32_HAS_GPIOH || defined(__DOXYGEN__) + gpio_setup_t PHData; +#endif +#if STM32_HAS_GPIOI || defined(__DOXYGEN__) + gpio_setup_t PIData; +#endif +#if STM32_HAS_GPIOJ || defined(__DOXYGEN__) + gpio_setup_t PJData; +#endif +#if STM32_HAS_GPIOK || defined(__DOXYGEN__) + gpio_setup_t PKData; +#endif +} gpio_config_t; + +/** + * @brief STM32 GPIO static initialization data. + */ +static const gpio_config_t gpio_default_config = { +#if STM32_HAS_GPIOA + {VAL_GPIOA_MODER, VAL_GPIOA_OTYPER, VAL_GPIOA_OSPEEDR, VAL_GPIOA_PUPDR, + VAL_GPIOA_ODR, VAL_GPIOA_AFRL, VAL_GPIOA_AFRH, VAL_GPIOA_ASCR, + VAL_GPIOA_LOCKR}, +#endif +#if STM32_HAS_GPIOB + {VAL_GPIOB_MODER, VAL_GPIOB_OTYPER, VAL_GPIOB_OSPEEDR, VAL_GPIOB_PUPDR, + VAL_GPIOB_ODR, VAL_GPIOB_AFRL, VAL_GPIOB_AFRH, VAL_GPIOB_ASCR, + VAL_GPIOB_LOCKR}, +#endif +#if STM32_HAS_GPIOC + {VAL_GPIOC_MODER, VAL_GPIOC_OTYPER, VAL_GPIOC_OSPEEDR, VAL_GPIOC_PUPDR, + VAL_GPIOC_ODR, VAL_GPIOC_AFRL, VAL_GPIOC_AFRH, VAL_GPIOC_ASCR, + VAL_GPIOC_LOCKR}, +#endif +#if STM32_HAS_GPIOD + {VAL_GPIOD_MODER, VAL_GPIOD_OTYPER, VAL_GPIOD_OSPEEDR, VAL_GPIOD_PUPDR, + VAL_GPIOD_ODR, VAL_GPIOD_AFRL, VAL_GPIOD_AFRH, VAL_GPIOD_ASCR, + VAL_GPIOD_LOCKR}, +#endif +#if STM32_HAS_GPIOE + {VAL_GPIOE_MODER, VAL_GPIOE_OTYPER, VAL_GPIOE_OSPEEDR, VAL_GPIOE_PUPDR, + VAL_GPIOE_ODR, VAL_GPIOE_AFRL, VAL_GPIOE_AFRH, VAL_GPIOE_ASCR, + VAL_GPIOE_LOCKR}, +#endif +#if STM32_HAS_GPIOF + {VAL_GPIOF_MODER, VAL_GPIOF_OTYPER, VAL_GPIOF_OSPEEDR, VAL_GPIOF_PUPDR, + VAL_GPIOF_ODR, VAL_GPIOF_AFRL, VAL_GPIOF_AFRH, VAL_GPIOF_ASCR, + VAL_GPIOF_LOCKR}, +#endif +#if STM32_HAS_GPIOG + {VAL_GPIOG_MODER, VAL_GPIOG_OTYPER, VAL_GPIOG_OSPEEDR, VAL_GPIOG_PUPDR, + VAL_GPIOG_ODR, VAL_GPIOG_AFRL, VAL_GPIOG_AFRH, VAL_GPIOG_ASCR, + VAL_GPIOG_LOCKR}, +#endif +#if STM32_HAS_GPIOH + {VAL_GPIOH_MODER, VAL_GPIOH_OTYPER, VAL_GPIOH_OSPEEDR, VAL_GPIOH_PUPDR, + VAL_GPIOH_ODR, VAL_GPIOH_AFRL, VAL_GPIOH_AFRH, VAL_GPIOH_ASCR, + VAL_GPIOH_LOCKR}, +#endif +#if STM32_HAS_GPIOI + {VAL_GPIOI_MODER, VAL_GPIOI_OTYPER, VAL_GPIOI_OSPEEDR, VAL_GPIOI_PUPDR, + VAL_GPIOI_ODR, VAL_GPIOI_AFRL, VAL_GPIOI_AFRH, VAL_GPIOI_ASCR, + VAL_GPIOI_LOCKR}, +#endif +#if STM32_HAS_GPIOJ + {VAL_GPIOJ_MODER, VAL_GPIOJ_OTYPER, VAL_GPIOJ_OSPEEDR, VAL_GPIOJ_PUPDR, + VAL_GPIOJ_ODR, VAL_GPIOJ_AFRL, VAL_GPIOJ_AFRH, VAL_GPIOJ_ASCR, + VAL_GPIOJ_LOCKR}, +#endif +#if STM32_HAS_GPIOK + {VAL_GPIOK_MODER, VAL_GPIOK_OTYPER, VAL_GPIOK_OSPEEDR, VAL_GPIOK_PUPDR, + VAL_GPIOK_ODR, VAL_GPIOK_AFRL, VAL_GPIOK_AFRH, VAL_GPIOK_ASCR, + VAL_GPIOK_LOCKR} +#endif +}; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static void gpio_init(stm32_gpio_t *gpiop, const gpio_setup_t *config) { + + gpiop->OTYPER = config->otyper; + gpiop->ASCR = config->ascr; + gpiop->OSPEEDR = config->ospeedr; + gpiop->PUPDR = config->pupdr; + gpiop->ODR = config->odr; + gpiop->AFRL = config->afrl; + gpiop->AFRH = config->afrh; + gpiop->MODER = config->moder; + gpiop->LOCKR = config->lockr; +} + +static void stm32_gpio_init(void) { + + /* Enabling GPIO-related clocks, the mask comes from the + registry header file.*/ + rccResetAHB2(STM32_GPIO_EN_MASK); + rccEnableAHB2(STM32_GPIO_EN_MASK, true); + + /* Initializing all the defined GPIO ports.*/ +#if STM32_HAS_GPIOA + gpio_init(GPIOA, &gpio_default_config.PAData); +#endif +#if STM32_HAS_GPIOB + gpio_init(GPIOB, &gpio_default_config.PBData); +#endif +#if STM32_HAS_GPIOC + gpio_init(GPIOC, &gpio_default_config.PCData); +#endif +#if STM32_HAS_GPIOD + gpio_init(GPIOD, &gpio_default_config.PDData); +#endif +#if STM32_HAS_GPIOE + gpio_init(GPIOE, &gpio_default_config.PEData); +#endif +#if STM32_HAS_GPIOF + gpio_init(GPIOF, &gpio_default_config.PFData); +#endif +#if STM32_HAS_GPIOG + gpio_init(GPIOG, &gpio_default_config.PGData); +#endif +#if STM32_HAS_GPIOH + gpio_init(GPIOH, &gpio_default_config.PHData); +#endif +#if STM32_HAS_GPIOI + gpio_init(GPIOI, &gpio_default_config.PIData); +#endif +#if STM32_HAS_GPIOJ + gpio_init(GPIOJ, &gpio_default_config.PJData); +#endif +#if STM32_HAS_GPIOK + gpio_init(GPIOK, &gpio_default_config.PKData); +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Early initialization code. + * @details GPIO ports and system clocks are initialized before everything + * else. + */ +void __early_init(void) { + + stm32_gpio_init(); + stm32_clock_init(); +} + +#if HAL_USE_SDC || defined(__DOXYGEN__) +/** + * @brief SDC card detection. + */ +bool sdc_lld_is_card_inserted(SDCDriver *sdcp) { + + (void)sdcp; + /* CHTODO: Fill the implementation.*/ + return true; +} + +/** + * @brief SDC card write protection detection. + */ +bool sdc_lld_is_write_protected(SDCDriver *sdcp) { + + (void)sdcp; + /* CHTODO: Fill the implementation.*/ + return false; +} +#endif /* HAL_USE_SDC */ + +#if HAL_USE_MMC_SPI || defined(__DOXYGEN__) +/** + * @brief MMC_SPI card detection. + */ +bool mmc_lld_is_card_inserted(MMCDriver *mmcp) { + + (void)mmcp; + /* CHTODO: Fill the implementation.*/ + return true; +} + +/** + * @brief MMC_SPI card write protection detection. + */ +bool mmc_lld_is_write_protected(MMCDriver *mmcp) { + + (void)mmcp; + /* CHTODO: Fill the implementation.*/ + return false; +} +#endif + +/** + * @brief Board-specific initialization code. + * @note You can add your board-specific code here. + */ +void boardInit(void) { + +} diff --git a/os/hal/boards/ST_NUCLEO144_L496ZG/board.h b/os/hal/boards/ST_NUCLEO144_L496ZG/board.h index 180733fd7d..a15a016649 100644 --- a/os/hal/boards/ST_NUCLEO144_L496ZG/board.h +++ b/os/hal/boards/ST_NUCLEO144_L496ZG/board.h @@ -1,1478 +1,1644 @@ -/* - ChibiOS - Copyright (C) 2006..2018 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. -*/ - -/* - * This file has been automatically generated using ChibiStudio board - * generator plugin. Do not edit manually. - */ - -#ifndef BOARD_H -#define BOARD_H - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/* - * Setup for STMicroelectronics STM32 Nucleo144-L496ZG board. - */ - -/* - * Board identifier. - */ -#define BOARD_ST_NUCLEO144_L496ZG -#define BOARD_NAME "STMicroelectronics STM32 Nucleo144-L496ZG" - -/* - * Board oscillators-related settings. - * NOTE: LSE not fitted. - * NOTE: HSE not fitted. - */ -#if !defined(STM32_LSECLK) -#define STM32_LSECLK 0U -#endif - -#define STM32_LSEDRV (3U << 3U) - -#if !defined(STM32_HSECLK) -#define STM32_HSECLK 0U -#endif - -/* - * Board voltages. - * Required for performance limits calculation. - */ -#define STM32_VDD 300U - -/* - * MCU type as defined in the ST header. - */ -#define STM32L496xx - -/* - * IO pins assignments. - */ -#define GPIOA_PIN0 0U -#define GPIOA_PIN1 1U -#define GPIOA_PIN2 2U -#define GPIOA_PIN3 3U -#define GPIOA_PIN4 4U -#define GPIOA_PIN5 5U -#define GPIOA_PIN6 6U -#define GPIOA_PIN7 7U -#define GPIOA_USB_SOF 8U -#define GPIOA_USB_VBUS 9U -#define GPIOA_USB_ID 10U -#define GPIOA_USB_DM 11U -#define GPIOA_USB_DP 12U -#define GPIOA_SWDIO 13U -#define GPIOA_SWCLK 14U -#define GPIOA_PIN15 15U - -#define GPIOB_PIN0 0U -#define GPIOB_PIN1 1U -#define GPIOB_PIN2 2U -#define GPIOB_SWO 3U -#define GPIOB_PIN4 4U -#define GPIOB_PIN5 5U -#define GPIOB_PIN6 6U -#define GPIOB_LED2 7U -#define GPIOB_LED_BLUE 7U -#define GPIOB_PIN8 8U -#define GPIOB_PIN9 9U -#define GPIOB_PIN10 10U -#define GPIOB_PIN11 11U -#define GPIOB_PIN12 12U -#define GPIOB_PIN13 13U -#define GPIOB_LED3 14U -#define GPIOB_LED_RED 14U -#define GPIOB_PIN15 15U - -#define GPIOC_PIN0 0U -#define GPIOC_PIN1 1U -#define GPIOC_PIN2 2U -#define GPIOC_PIN3 3U -#define GPIOC_PIN4 4U -#define GPIOC_PIN5 5U -#define GPIOC_PIN6 6U -#define GPIOC_LED1 7U -#define GPIOC_LED_GREEN 7U -#define GPIOC_PIN8 8U -#define GPIOC_PIN9 9U -#define GPIOC_PIN10 10U -#define GPIOC_PIN11 11U -#define GPIOC_PIN12 12U -#define GPIOC_BUTTON 13U -#define GPIOC_PIN14 14U -#define GPIOC_PIN15 15U - -#define GPIOD_PIN0 0U -#define GPIOD_PIN1 1U -#define GPIOD_PIN2 2U -#define GPIOD_PIN3 3U -#define GPIOD_PIN4 4U -#define GPIOD_PIN5 5U -#define GPIOD_PIN6 6U -#define GPIOD_PIN7 7U -#define GPIOD_PIN8 8U -#define GPIOD_PIN9 9U -#define GPIOD_PIN10 10U -#define GPIOD_PIN11 11U -#define GPIOD_PIN12 12U -#define GPIOD_PIN13 13U -#define GPIOD_PIN14 14U -#define GPIOD_PIN15 15U - -#define GPIOE_PIN0 0U -#define GPIOE_PIN1 1U -#define GPIOE_PIN2 2U -#define GPIOE_PIN3 3U -#define GPIOE_PIN4 4U -#define GPIOE_PIN5 5U -#define GPIOE_PIN6 6U -#define GPIOE_PIN7 7U -#define GPIOE_PIN8 8U -#define GPIOE_PIN9 9U -#define GPIOE_PIN10 10U -#define GPIOE_PIN11 11U -#define GPIOE_PIN12 12U -#define GPIOE_PIN13 13U -#define GPIOE_PIN14 14U -#define GPIOE_PIN15 15U - -#define GPIOF_PIN0 0U -#define GPIOF_PIN1 1U -#define GPIOF_PIN2 2U -#define GPIOF_PIN3 3U -#define GPIOF_PIN4 4U -#define GPIOF_PIN5 5U -#define GPIOF_PIN6 6U -#define GPIOF_PIN7 7U -#define GPIOF_PIN8 8U -#define GPIOF_PIN9 9U -#define GPIOF_PIN10 10U -#define GPIOF_PIN11 11U -#define GPIOF_PIN12 12U -#define GPIOF_PIN13 13U -#define GPIOF_PIN14 14U -#define GPIOF_PIN15 15U - -#define GPIOG_PIN0 0U -#define GPIOG_PIN1 1U -#define GPIOG_PIN2 2U -#define GPIOG_PIN3 3U -#define GPIOG_PIN4 4U -#define GPIOG_USB_OVER_CURRENT 5U -#define GPIOG_USB_POWER_SWITCH_ON 6U -#define GPIOG_LPUART1_TX 7U -#define GPIOG_LPUART1_RX 8U -#define GPIOG_PIN9 9U -#define GPIOG_PIN10 10U -#define GPIOG_PIN11 11U -#define GPIOG_PIN12 12U -#define GPIOG_PIN13 13U -#define GPIOG_PIN14 14U -#define GPIOG_PIN15 15U - -#define GPIOH_PIN0 0U -#define GPIOH_PIN1 1U -#define GPIOH_PIN2 2U -#define GPIOH_PIN3 3U -#define GPIOH_PIN4 4U -#define GPIOH_PIN5 5U -#define GPIOH_PIN6 6U -#define GPIOH_PIN7 7U -#define GPIOH_PIN8 8U -#define GPIOH_PIN9 9U -#define GPIOH_PIN10 10U -#define GPIOH_PIN11 11U -#define GPIOH_PIN12 12U -#define GPIOH_PIN13 13U -#define GPIOH_PIN14 14U -#define GPIOH_PIN15 15U - -/* - * IO lines assignments. - */ -#define LINE_USB_SOF PAL_LINE(GPIOA, 8U) -#define LINE_USB_VBUS PAL_LINE(GPIOA, 9U) -#define LINE_USB_ID PAL_LINE(GPIOA, 10U) -#define LINE_USB_DM PAL_LINE(GPIOA, 11U) -#define LINE_USB_DP PAL_LINE(GPIOA, 12U) -#define LINE_SWDIO PAL_LINE(GPIOA, 13U) -#define LINE_SWCLK PAL_LINE(GPIOA, 14U) -#define LINE_SWO PAL_LINE(GPIOB, 3U) -#define LINE_LED2 PAL_LINE(GPIOB, 7U) -#define LINE_LED_BLUE PAL_LINE(GPIOB, 7U) -#define LINE_LED3 PAL_LINE(GPIOB, 14U) -#define LINE_LED_RED PAL_LINE(GPIOB, 14U) -#define LINE_LED1 PAL_LINE(GPIOC, 7U) -#define LINE_LED_GREEN PAL_LINE(GPIOC, 7U) -#define LINE_BUTTON PAL_LINE(GPIOC, 13U) -#define LINE_USB_OVER_CURRENT PAL_LINE(GPIOG, 5U) -#define LINE_USB_POWER_SWITCH_ON PAL_LINE(GPIOG, 6U) -#define LINE_LPUART1_TX PAL_LINE(GPIOG, 7U) -#define LINE_LPUART1_RX PAL_LINE(GPIOG, 8U) - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/* - * I/O ports initial setup, this configuration is established soon after reset - * in the initialization code. - * Please refer to the STM32 Reference Manual for details. - */ -#define PIN_MODE_INPUT(n) (0U << ((n) * 2U)) -#define PIN_MODE_OUTPUT(n) (1U << ((n) * 2U)) -#define PIN_MODE_ALTERNATE(n) (2U << ((n) * 2U)) -#define PIN_MODE_ANALOG(n) (3U << ((n) * 2U)) -#define PIN_ODR_LOW(n) (0U << (n)) -#define PIN_ODR_HIGH(n) (1U << (n)) -#define PIN_OTYPE_PUSHPULL(n) (0U << (n)) -#define PIN_OTYPE_OPENDRAIN(n) (1U << (n)) -#define PIN_OSPEED_VERYLOW(n) (0U << ((n) * 2U)) -#define PIN_OSPEED_LOW(n) (1U << ((n) * 2U)) -#define PIN_OSPEED_MEDIUM(n) (2U << ((n) * 2U)) -#define PIN_OSPEED_HIGH(n) (3U << ((n) * 2U)) -#define PIN_PUPDR_FLOATING(n) (0U << ((n) * 2U)) -#define PIN_PUPDR_PULLUP(n) (1U << ((n) * 2U)) -#define PIN_PUPDR_PULLDOWN(n) (2U << ((n) * 2U)) -#define PIN_AFIO_AF(n, v) ((v) << (((n) % 8U) * 4U)) -#define PIN_ASCR_DISABLED(n) (0U << (n)) -#define PIN_ASCR_ENABLED(n) (1U << (n)) -#define PIN_LOCKR_DISABLED(n) (0U << (n)) -#define PIN_LOCKR_ENABLED(n) (1U << (n)) - -/* - * GPIOA setup: - * - * PA0 - PIN0 (analog). - * PA1 - PIN1 (analog). - * PA2 - PIN2 (analog). - * PA3 - PIN3 (analog). - * PA4 - PIN4 (analog). - * PA5 - PIN5 (analog). - * PA6 - PIN6 (analog). - * PA7 - PIN7 (analog). - * PA8 - USB_SOF (alternate 10). - * PA9 - USB_VBUS (analog). - * PA10 - USB_ID (alternate 10). - * PA11 - USB_DM (alternate 10). - * PA12 - USB_DP (alternate 10). - * PA13 - SWDIO (alternate 0). - * PA14 - SWCLK (alternate 0). - * PA15 - PIN15 (analog). - */ -#define VAL_GPIOA_MODER (PIN_MODE_ANALOG(GPIOA_PIN0) | \ - PIN_MODE_ANALOG(GPIOA_PIN1) | \ - PIN_MODE_ANALOG(GPIOA_PIN2) | \ - PIN_MODE_ANALOG(GPIOA_PIN3) | \ - PIN_MODE_ANALOG(GPIOA_PIN4) | \ - PIN_MODE_ANALOG(GPIOA_PIN5) | \ - PIN_MODE_ANALOG(GPIOA_PIN6) | \ - PIN_MODE_ANALOG(GPIOA_PIN7) | \ - PIN_MODE_ALTERNATE(GPIOA_USB_SOF) | \ - PIN_MODE_ANALOG(GPIOA_USB_VBUS) | \ - PIN_MODE_ALTERNATE(GPIOA_USB_ID) | \ - PIN_MODE_ALTERNATE(GPIOA_USB_DM) | \ - PIN_MODE_ALTERNATE(GPIOA_USB_DP) | \ - PIN_MODE_ALTERNATE(GPIOA_SWDIO) | \ - PIN_MODE_ALTERNATE(GPIOA_SWCLK) | \ - PIN_MODE_ANALOG(GPIOA_PIN15)) -#define VAL_GPIOA_OTYPER (PIN_OTYPE_PUSHPULL(GPIOA_PIN0) | \ - PIN_OTYPE_PUSHPULL(GPIOA_PIN1) | \ - PIN_OTYPE_PUSHPULL(GPIOA_PIN2) | \ - PIN_OTYPE_PUSHPULL(GPIOA_PIN3) | \ - PIN_OTYPE_PUSHPULL(GPIOA_PIN4) | \ - PIN_OTYPE_PUSHPULL(GPIOA_PIN5) | \ - PIN_OTYPE_PUSHPULL(GPIOA_PIN6) | \ - PIN_OTYPE_PUSHPULL(GPIOA_PIN7) | \ - PIN_OTYPE_PUSHPULL(GPIOA_USB_SOF) | \ - PIN_OTYPE_PUSHPULL(GPIOA_USB_VBUS) | \ - PIN_OTYPE_PUSHPULL(GPIOA_USB_ID) | \ - PIN_OTYPE_PUSHPULL(GPIOA_USB_DM) | \ - PIN_OTYPE_PUSHPULL(GPIOA_USB_DP) | \ - PIN_OTYPE_PUSHPULL(GPIOA_SWDIO) | \ - PIN_OTYPE_PUSHPULL(GPIOA_SWCLK) | \ - PIN_OTYPE_PUSHPULL(GPIOA_PIN15)) -#define VAL_GPIOA_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOA_PIN0) | \ - PIN_OSPEED_VERYLOW(GPIOA_PIN1) | \ - PIN_OSPEED_VERYLOW(GPIOA_PIN2) | \ - PIN_OSPEED_VERYLOW(GPIOA_PIN3) | \ - PIN_OSPEED_VERYLOW(GPIOA_PIN4) | \ - PIN_OSPEED_VERYLOW(GPIOA_PIN5) | \ - PIN_OSPEED_VERYLOW(GPIOA_PIN6) | \ - PIN_OSPEED_VERYLOW(GPIOA_PIN7) | \ - PIN_OSPEED_HIGH(GPIOA_USB_SOF) | \ - PIN_OSPEED_VERYLOW(GPIOA_USB_VBUS) | \ - PIN_OSPEED_HIGH(GPIOA_USB_ID) | \ - PIN_OSPEED_HIGH(GPIOA_USB_DM) | \ - PIN_OSPEED_HIGH(GPIOA_USB_DP) | \ - PIN_OSPEED_HIGH(GPIOA_SWDIO) | \ - PIN_OSPEED_HIGH(GPIOA_SWCLK) | \ - PIN_OSPEED_VERYLOW(GPIOA_PIN15)) -#define VAL_GPIOA_PUPDR (PIN_PUPDR_FLOATING(GPIOA_PIN0) | \ - PIN_PUPDR_FLOATING(GPIOA_PIN1) | \ - PIN_PUPDR_FLOATING(GPIOA_PIN2) | \ - PIN_PUPDR_FLOATING(GPIOA_PIN3) | \ - PIN_PUPDR_FLOATING(GPIOA_PIN4) | \ - PIN_PUPDR_FLOATING(GPIOA_PIN5) | \ - PIN_PUPDR_FLOATING(GPIOA_PIN6) | \ - PIN_PUPDR_FLOATING(GPIOA_PIN7) | \ - PIN_PUPDR_FLOATING(GPIOA_USB_SOF) | \ - PIN_PUPDR_FLOATING(GPIOA_USB_VBUS) | \ - PIN_PUPDR_FLOATING(GPIOA_USB_ID) | \ - PIN_PUPDR_FLOATING(GPIOA_USB_DM) | \ - PIN_PUPDR_FLOATING(GPIOA_USB_DP) | \ - PIN_PUPDR_PULLDOWN(GPIOA_SWDIO) | \ - PIN_PUPDR_PULLUP(GPIOA_SWCLK) | \ - PIN_PUPDR_FLOATING(GPIOA_PIN15)) -#define VAL_GPIOA_ODR (PIN_ODR_LOW(GPIOA_PIN0) | \ - PIN_ODR_LOW(GPIOA_PIN1) | \ - PIN_ODR_LOW(GPIOA_PIN2) | \ - PIN_ODR_LOW(GPIOA_PIN3) | \ - PIN_ODR_LOW(GPIOA_PIN4) | \ - PIN_ODR_LOW(GPIOA_PIN5) | \ - PIN_ODR_LOW(GPIOA_PIN6) | \ - PIN_ODR_LOW(GPIOA_PIN7) | \ - PIN_ODR_LOW(GPIOA_USB_SOF) | \ - PIN_ODR_LOW(GPIOA_USB_VBUS) | \ - PIN_ODR_LOW(GPIOA_USB_ID) | \ - PIN_ODR_LOW(GPIOA_USB_DM) | \ - PIN_ODR_LOW(GPIOA_USB_DP) | \ - PIN_ODR_LOW(GPIOA_SWDIO) | \ - PIN_ODR_LOW(GPIOA_SWCLK) | \ - PIN_ODR_LOW(GPIOA_PIN15)) -#define VAL_GPIOA_AFRL (PIN_AFIO_AF(GPIOA_PIN0, 0U) | \ - PIN_AFIO_AF(GPIOA_PIN1, 0U) | \ - PIN_AFIO_AF(GPIOA_PIN2, 0U) | \ - PIN_AFIO_AF(GPIOA_PIN3, 0U) | \ - PIN_AFIO_AF(GPIOA_PIN4, 0U) | \ - PIN_AFIO_AF(GPIOA_PIN5, 0U) | \ - PIN_AFIO_AF(GPIOA_PIN6, 0U) | \ - PIN_AFIO_AF(GPIOA_PIN7, 0U)) -#define VAL_GPIOA_AFRH (PIN_AFIO_AF(GPIOA_USB_SOF, 10U) | \ - PIN_AFIO_AF(GPIOA_USB_VBUS, 0U) | \ - PIN_AFIO_AF(GPIOA_USB_ID, 10U) | \ - PIN_AFIO_AF(GPIOA_USB_DM, 10U) | \ - PIN_AFIO_AF(GPIOA_USB_DP, 10U) | \ - PIN_AFIO_AF(GPIOA_SWDIO, 0U) | \ - PIN_AFIO_AF(GPIOA_SWCLK, 0U) | \ - PIN_AFIO_AF(GPIOA_PIN15, 0U)) -#define VAL_GPIOA_ASCR (PIN_ASCR_DISABLED(GPIOA_PIN0) | \ - PIN_ASCR_DISABLED(GPIOA_PIN1) | \ - PIN_ASCR_DISABLED(GPIOA_PIN2) | \ - PIN_ASCR_DISABLED(GPIOA_PIN3) | \ - PIN_ASCR_DISABLED(GPIOA_PIN4) | \ - PIN_ASCR_DISABLED(GPIOA_PIN5) | \ - PIN_ASCR_DISABLED(GPIOA_PIN6) | \ - PIN_ASCR_DISABLED(GPIOA_PIN7) | \ - PIN_ASCR_DISABLED(GPIOA_USB_SOF) | \ - PIN_ASCR_DISABLED(GPIOA_USB_VBUS) | \ - PIN_ASCR_DISABLED(GPIOA_USB_ID) | \ - PIN_ASCR_DISABLED(GPIOA_USB_DM) | \ - PIN_ASCR_DISABLED(GPIOA_USB_DP) | \ - PIN_ASCR_DISABLED(GPIOA_SWDIO) | \ - PIN_ASCR_DISABLED(GPIOA_SWCLK) | \ - PIN_ASCR_DISABLED(GPIOA_PIN15)) -#define VAL_GPIOA_LOCKR (PIN_LOCKR_DISABLED(GPIOA_PIN0) | \ - PIN_LOCKR_DISABLED(GPIOA_PIN1) | \ - PIN_LOCKR_DISABLED(GPIOA_PIN2) | \ - PIN_LOCKR_DISABLED(GPIOA_PIN3) | \ - PIN_LOCKR_DISABLED(GPIOA_PIN4) | \ - PIN_LOCKR_DISABLED(GPIOA_PIN5) | \ - PIN_LOCKR_DISABLED(GPIOA_PIN6) | \ - PIN_LOCKR_DISABLED(GPIOA_PIN7) | \ - PIN_LOCKR_DISABLED(GPIOA_USB_SOF) | \ - PIN_LOCKR_DISABLED(GPIOA_USB_VBUS) | \ - PIN_LOCKR_DISABLED(GPIOA_USB_ID) | \ - PIN_LOCKR_DISABLED(GPIOA_USB_DM) | \ - PIN_LOCKR_DISABLED(GPIOA_USB_DP) | \ - PIN_LOCKR_DISABLED(GPIOA_SWDIO) | \ - PIN_LOCKR_DISABLED(GPIOA_SWCLK) | \ - PIN_LOCKR_DISABLED(GPIOA_PIN15)) - -/* - * GPIOB setup: - * - * PB0 - PIN0 (analog). - * PB1 - PIN1 (analog). - * PB2 - PIN2 (analog). - * PB3 - SWO (alternate 0). - * PB4 - PIN4 (analog). - * PB5 - PIN5 (analog). - * PB6 - PIN6 (analog). - * PB7 - LED2 LED_BLUE (output pushpull maximum). - * PB8 - PIN8 (analog). - * PB9 - PIN9 (analog). - * PB10 - PIN10 (analog). - * PB11 - PIN11 (analog). - * PB12 - PIN12 (analog). - * PB13 - PIN13 (analog). - * PB14 - LED3 LED_RED (output pushpull maximum). - * PB15 - PIN15 (analog). - */ -#define VAL_GPIOB_MODER (PIN_MODE_ANALOG(GPIOB_PIN0) | \ - PIN_MODE_ANALOG(GPIOB_PIN1) | \ - PIN_MODE_ANALOG(GPIOB_PIN2) | \ - PIN_MODE_ALTERNATE(GPIOB_SWO) | \ - PIN_MODE_ANALOG(GPIOB_PIN4) | \ - PIN_MODE_ANALOG(GPIOB_PIN5) | \ - PIN_MODE_ANALOG(GPIOB_PIN6) | \ - PIN_MODE_OUTPUT(GPIOB_LED2) | \ - PIN_MODE_ANALOG(GPIOB_PIN8) | \ - PIN_MODE_ANALOG(GPIOB_PIN9) | \ - PIN_MODE_ANALOG(GPIOB_PIN10) | \ - PIN_MODE_ANALOG(GPIOB_PIN11) | \ - PIN_MODE_ANALOG(GPIOB_PIN12) | \ - PIN_MODE_ANALOG(GPIOB_PIN13) | \ - PIN_MODE_OUTPUT(GPIOB_LED3) | \ - PIN_MODE_ANALOG(GPIOB_PIN15)) -#define VAL_GPIOB_OTYPER (PIN_OTYPE_PUSHPULL(GPIOB_PIN0) | \ - PIN_OTYPE_PUSHPULL(GPIOB_PIN1) | \ - PIN_OTYPE_PUSHPULL(GPIOB_PIN2) | \ - PIN_OTYPE_PUSHPULL(GPIOB_SWO) | \ - PIN_OTYPE_PUSHPULL(GPIOB_PIN4) | \ - PIN_OTYPE_PUSHPULL(GPIOB_PIN5) | \ - PIN_OTYPE_PUSHPULL(GPIOB_PIN6) | \ - PIN_OTYPE_PUSHPULL(GPIOB_LED2) | \ - PIN_OTYPE_PUSHPULL(GPIOB_PIN8) | \ - PIN_OTYPE_PUSHPULL(GPIOB_PIN9) | \ - PIN_OTYPE_PUSHPULL(GPIOB_PIN10) | \ - PIN_OTYPE_PUSHPULL(GPIOB_PIN11) | \ - PIN_OTYPE_PUSHPULL(GPIOB_PIN12) | \ - PIN_OTYPE_PUSHPULL(GPIOB_PIN13) | \ - PIN_OTYPE_PUSHPULL(GPIOB_LED3) | \ - PIN_OTYPE_PUSHPULL(GPIOB_PIN15)) -#define VAL_GPIOB_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOB_PIN0) | \ - PIN_OSPEED_VERYLOW(GPIOB_PIN1) | \ - PIN_OSPEED_VERYLOW(GPIOB_PIN2) | \ - PIN_OSPEED_HIGH(GPIOB_SWO) | \ - PIN_OSPEED_VERYLOW(GPIOB_PIN4) | \ - PIN_OSPEED_VERYLOW(GPIOB_PIN5) | \ - PIN_OSPEED_VERYLOW(GPIOB_PIN6) | \ - PIN_OSPEED_HIGH(GPIOB_LED2) | \ - PIN_OSPEED_VERYLOW(GPIOB_PIN8) | \ - PIN_OSPEED_VERYLOW(GPIOB_PIN9) | \ - PIN_OSPEED_VERYLOW(GPIOB_PIN10) | \ - PIN_OSPEED_VERYLOW(GPIOB_PIN11) | \ - PIN_OSPEED_VERYLOW(GPIOB_PIN12) | \ - PIN_OSPEED_VERYLOW(GPIOB_PIN13) | \ - PIN_OSPEED_HIGH(GPIOB_LED3) | \ - PIN_OSPEED_VERYLOW(GPIOB_PIN15)) -#define VAL_GPIOB_PUPDR (PIN_PUPDR_FLOATING(GPIOB_PIN0) | \ - PIN_PUPDR_FLOATING(GPIOB_PIN1) | \ - PIN_PUPDR_FLOATING(GPIOB_PIN2) | \ - PIN_PUPDR_FLOATING(GPIOB_SWO) | \ - PIN_PUPDR_FLOATING(GPIOB_PIN4) | \ - PIN_PUPDR_FLOATING(GPIOB_PIN5) | \ - PIN_PUPDR_FLOATING(GPIOB_PIN6) | \ - PIN_PUPDR_FLOATING(GPIOB_LED2) | \ - PIN_PUPDR_FLOATING(GPIOB_PIN8) | \ - PIN_PUPDR_FLOATING(GPIOB_PIN9) | \ - PIN_PUPDR_FLOATING(GPIOB_PIN10) | \ - PIN_PUPDR_FLOATING(GPIOB_PIN11) | \ - PIN_PUPDR_FLOATING(GPIOB_PIN12) | \ - PIN_PUPDR_FLOATING(GPIOB_PIN13) | \ - PIN_PUPDR_FLOATING(GPIOB_LED3) | \ - PIN_PUPDR_FLOATING(GPIOB_PIN15)) -#define VAL_GPIOB_ODR (PIN_ODR_LOW(GPIOB_PIN0) | \ - PIN_ODR_LOW(GPIOB_PIN1) | \ - PIN_ODR_LOW(GPIOB_PIN2) | \ - PIN_ODR_LOW(GPIOB_SWO) | \ - PIN_ODR_LOW(GPIOB_PIN4) | \ - PIN_ODR_LOW(GPIOB_PIN5) | \ - PIN_ODR_LOW(GPIOB_PIN6) | \ - PIN_ODR_LOW(GPIOB_LED2) | \ - PIN_ODR_LOW(GPIOB_PIN8) | \ - PIN_ODR_LOW(GPIOB_PIN9) | \ - PIN_ODR_LOW(GPIOB_PIN10) | \ - PIN_ODR_LOW(GPIOB_PIN11) | \ - PIN_ODR_LOW(GPIOB_PIN12) | \ - PIN_ODR_LOW(GPIOB_PIN13) | \ - PIN_ODR_LOW(GPIOB_LED3) | \ - PIN_ODR_LOW(GPIOB_PIN15)) -#define VAL_GPIOB_AFRL (PIN_AFIO_AF(GPIOB_PIN0, 0U) | \ - PIN_AFIO_AF(GPIOB_PIN1, 0U) | \ - PIN_AFIO_AF(GPIOB_PIN2, 0U) | \ - PIN_AFIO_AF(GPIOB_SWO, 0U) | \ - PIN_AFIO_AF(GPIOB_PIN4, 0U) | \ - PIN_AFIO_AF(GPIOB_PIN5, 0U) | \ - PIN_AFIO_AF(GPIOB_PIN6, 0U) | \ - PIN_AFIO_AF(GPIOB_LED2, 0U)) -#define VAL_GPIOB_AFRH (PIN_AFIO_AF(GPIOB_PIN8, 0U) | \ - PIN_AFIO_AF(GPIOB_PIN9, 0U) | \ - PIN_AFIO_AF(GPIOB_PIN10, 0U) | \ - PIN_AFIO_AF(GPIOB_PIN11, 0U) | \ - PIN_AFIO_AF(GPIOB_PIN12, 0U) | \ - PIN_AFIO_AF(GPIOB_PIN13, 0U) | \ - PIN_AFIO_AF(GPIOB_LED3, 0U) | \ - PIN_AFIO_AF(GPIOB_PIN15, 0U)) -#define VAL_GPIOB_ASCR (PIN_ASCR_DISABLED(GPIOB_PIN0) | \ - PIN_ASCR_DISABLED(GPIOB_PIN1) | \ - PIN_ASCR_DISABLED(GPIOB_PIN2) | \ - PIN_ASCR_DISABLED(GPIOB_SWO) | \ - PIN_ASCR_DISABLED(GPIOB_PIN4) | \ - PIN_ASCR_DISABLED(GPIOB_PIN5) | \ - PIN_ASCR_DISABLED(GPIOB_PIN6) | \ - PIN_ASCR_DISABLED(GPIOB_LED2) | \ - PIN_ASCR_DISABLED(GPIOB_PIN8) | \ - PIN_ASCR_DISABLED(GPIOB_PIN9) | \ - PIN_ASCR_DISABLED(GPIOB_PIN10) | \ - PIN_ASCR_DISABLED(GPIOB_PIN11) | \ - PIN_ASCR_DISABLED(GPIOB_PIN12) | \ - PIN_ASCR_DISABLED(GPIOB_PIN13) | \ - PIN_ASCR_DISABLED(GPIOB_LED3) | \ - PIN_ASCR_DISABLED(GPIOB_PIN15)) -#define VAL_GPIOB_LOCKR (PIN_LOCKR_DISABLED(GPIOB_PIN0) | \ - PIN_LOCKR_DISABLED(GPIOB_PIN1) | \ - PIN_LOCKR_DISABLED(GPIOB_PIN2) | \ - PIN_LOCKR_DISABLED(GPIOB_SWO) | \ - PIN_LOCKR_DISABLED(GPIOB_PIN4) | \ - PIN_LOCKR_DISABLED(GPIOB_PIN5) | \ - PIN_LOCKR_DISABLED(GPIOB_PIN6) | \ - PIN_LOCKR_DISABLED(GPIOB_LED2) | \ - PIN_LOCKR_DISABLED(GPIOB_PIN8) | \ - PIN_LOCKR_DISABLED(GPIOB_PIN9) | \ - PIN_LOCKR_DISABLED(GPIOB_PIN10) | \ - PIN_LOCKR_DISABLED(GPIOB_PIN11) | \ - PIN_LOCKR_DISABLED(GPIOB_PIN12) | \ - PIN_LOCKR_DISABLED(GPIOB_PIN13) | \ - PIN_LOCKR_DISABLED(GPIOB_LED3) | \ - PIN_LOCKR_DISABLED(GPIOB_PIN15)) - -/* - * GPIOC setup: - * - * PC0 - PIN0 (analog). - * PC1 - PIN1 (analog). - * PC2 - PIN2 (analog). - * PC3 - PIN3 (analog). - * PC4 - PIN4 (analog). - * PC5 - PIN5 (analog). - * PC6 - PIN6 (analog). - * PC7 - LED1 LED_GREEN (output pushpull maximum). - * PC8 - PIN8 (analog). - * PC9 - PIN9 (analog). - * PC10 - PIN10 (analog). - * PC11 - PIN11 (analog). - * PC12 - PIN12 (analog). - * PC13 - BUTTON (input floating). - * PC14 - PIN14 (analog). - * PC15 - PIN15 (analog). - */ -#define VAL_GPIOC_MODER (PIN_MODE_ANALOG(GPIOC_PIN0) | \ - PIN_MODE_ANALOG(GPIOC_PIN1) | \ - PIN_MODE_ANALOG(GPIOC_PIN2) | \ - PIN_MODE_ANALOG(GPIOC_PIN3) | \ - PIN_MODE_ANALOG(GPIOC_PIN4) | \ - PIN_MODE_ANALOG(GPIOC_PIN5) | \ - PIN_MODE_ANALOG(GPIOC_PIN6) | \ - PIN_MODE_OUTPUT(GPIOC_LED1) | \ - PIN_MODE_ANALOG(GPIOC_PIN8) | \ - PIN_MODE_ANALOG(GPIOC_PIN9) | \ - PIN_MODE_ANALOG(GPIOC_PIN10) | \ - PIN_MODE_ANALOG(GPIOC_PIN11) | \ - PIN_MODE_ANALOG(GPIOC_PIN12) | \ - PIN_MODE_INPUT(GPIOC_BUTTON) | \ - PIN_MODE_ANALOG(GPIOC_PIN14) | \ - PIN_MODE_ANALOG(GPIOC_PIN15)) -#define VAL_GPIOC_OTYPER (PIN_OTYPE_PUSHPULL(GPIOC_PIN0) | \ - PIN_OTYPE_PUSHPULL(GPIOC_PIN1) | \ - PIN_OTYPE_PUSHPULL(GPIOC_PIN2) | \ - PIN_OTYPE_PUSHPULL(GPIOC_PIN3) | \ - PIN_OTYPE_PUSHPULL(GPIOC_PIN4) | \ - PIN_OTYPE_PUSHPULL(GPIOC_PIN5) | \ - PIN_OTYPE_PUSHPULL(GPIOC_PIN6) | \ - PIN_OTYPE_PUSHPULL(GPIOC_LED1) | \ - PIN_OTYPE_PUSHPULL(GPIOC_PIN8) | \ - PIN_OTYPE_PUSHPULL(GPIOC_PIN9) | \ - PIN_OTYPE_PUSHPULL(GPIOC_PIN10) | \ - PIN_OTYPE_PUSHPULL(GPIOC_PIN11) | \ - PIN_OTYPE_PUSHPULL(GPIOC_PIN12) | \ - PIN_OTYPE_PUSHPULL(GPIOC_BUTTON) | \ - PIN_OTYPE_PUSHPULL(GPIOC_PIN14) | \ - PIN_OTYPE_PUSHPULL(GPIOC_PIN15)) -#define VAL_GPIOC_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOC_PIN0) | \ - PIN_OSPEED_VERYLOW(GPIOC_PIN1) | \ - PIN_OSPEED_VERYLOW(GPIOC_PIN2) | \ - PIN_OSPEED_VERYLOW(GPIOC_PIN3) | \ - PIN_OSPEED_VERYLOW(GPIOC_PIN4) | \ - PIN_OSPEED_VERYLOW(GPIOC_PIN5) | \ - PIN_OSPEED_VERYLOW(GPIOC_PIN6) | \ - PIN_OSPEED_HIGH(GPIOC_LED1) | \ - PIN_OSPEED_VERYLOW(GPIOC_PIN8) | \ - PIN_OSPEED_VERYLOW(GPIOC_PIN9) | \ - PIN_OSPEED_VERYLOW(GPIOC_PIN10) | \ - PIN_OSPEED_VERYLOW(GPIOC_PIN11) | \ - PIN_OSPEED_VERYLOW(GPIOC_PIN12) | \ - PIN_OSPEED_VERYLOW(GPIOC_BUTTON) | \ - PIN_OSPEED_VERYLOW(GPIOC_PIN14) | \ - PIN_OSPEED_VERYLOW(GPIOC_PIN15)) -#define VAL_GPIOC_PUPDR (PIN_PUPDR_FLOATING(GPIOC_PIN0) | \ - PIN_PUPDR_FLOATING(GPIOC_PIN1) | \ - PIN_PUPDR_FLOATING(GPIOC_PIN2) | \ - PIN_PUPDR_FLOATING(GPIOC_PIN3) | \ - PIN_PUPDR_FLOATING(GPIOC_PIN4) | \ - PIN_PUPDR_FLOATING(GPIOC_PIN5) | \ - PIN_PUPDR_FLOATING(GPIOC_PIN6) | \ - PIN_PUPDR_FLOATING(GPIOC_LED1) | \ - PIN_PUPDR_FLOATING(GPIOC_PIN8) | \ - PIN_PUPDR_FLOATING(GPIOC_PIN9) | \ - PIN_PUPDR_FLOATING(GPIOC_PIN10) | \ - PIN_PUPDR_FLOATING(GPIOC_PIN11) | \ - PIN_PUPDR_FLOATING(GPIOC_PIN12) | \ - PIN_PUPDR_FLOATING(GPIOC_BUTTON) | \ - PIN_PUPDR_FLOATING(GPIOC_PIN14) | \ - PIN_PUPDR_FLOATING(GPIOC_PIN15)) -#define VAL_GPIOC_ODR (PIN_ODR_LOW(GPIOC_PIN0) | \ - PIN_ODR_LOW(GPIOC_PIN1) | \ - PIN_ODR_LOW(GPIOC_PIN2) | \ - PIN_ODR_LOW(GPIOC_PIN3) | \ - PIN_ODR_LOW(GPIOC_PIN4) | \ - PIN_ODR_LOW(GPIOC_PIN5) | \ - PIN_ODR_LOW(GPIOC_PIN6) | \ - PIN_ODR_LOW(GPIOC_LED1) | \ - PIN_ODR_LOW(GPIOC_PIN8) | \ - PIN_ODR_LOW(GPIOC_PIN9) | \ - PIN_ODR_LOW(GPIOC_PIN10) | \ - PIN_ODR_LOW(GPIOC_PIN11) | \ - PIN_ODR_LOW(GPIOC_PIN12) | \ - PIN_ODR_LOW(GPIOC_BUTTON) | \ - PIN_ODR_LOW(GPIOC_PIN14) | \ - PIN_ODR_LOW(GPIOC_PIN15)) -#define VAL_GPIOC_AFRL (PIN_AFIO_AF(GPIOC_PIN0, 0U) | \ - PIN_AFIO_AF(GPIOC_PIN1, 0U) | \ - PIN_AFIO_AF(GPIOC_PIN2, 0U) | \ - PIN_AFIO_AF(GPIOC_PIN3, 0U) | \ - PIN_AFIO_AF(GPIOC_PIN4, 0U) | \ - PIN_AFIO_AF(GPIOC_PIN5, 0U) | \ - PIN_AFIO_AF(GPIOC_PIN6, 0U) | \ - PIN_AFIO_AF(GPIOC_LED1, 0U)) -#define VAL_GPIOC_AFRH (PIN_AFIO_AF(GPIOC_PIN8, 0U) | \ - PIN_AFIO_AF(GPIOC_PIN9, 0U) | \ - PIN_AFIO_AF(GPIOC_PIN10, 0U) | \ - PIN_AFIO_AF(GPIOC_PIN11, 0U) | \ - PIN_AFIO_AF(GPIOC_PIN12, 0U) | \ - PIN_AFIO_AF(GPIOC_BUTTON, 0U) | \ - PIN_AFIO_AF(GPIOC_PIN14, 0U) | \ - PIN_AFIO_AF(GPIOC_PIN15, 0U)) -#define VAL_GPIOC_ASCR (PIN_ASCR_DISABLED(GPIOC_PIN0) | \ - PIN_ASCR_DISABLED(GPIOC_PIN1) | \ - PIN_ASCR_DISABLED(GPIOC_PIN2) | \ - PIN_ASCR_DISABLED(GPIOC_PIN3) | \ - PIN_ASCR_DISABLED(GPIOC_PIN4) | \ - PIN_ASCR_DISABLED(GPIOC_PIN5) | \ - PIN_ASCR_DISABLED(GPIOC_PIN6) | \ - PIN_ASCR_DISABLED(GPIOC_LED1) | \ - PIN_ASCR_DISABLED(GPIOC_PIN8) | \ - PIN_ASCR_DISABLED(GPIOC_PIN9) | \ - PIN_ASCR_DISABLED(GPIOC_PIN10) | \ - PIN_ASCR_DISABLED(GPIOC_PIN11) | \ - PIN_ASCR_DISABLED(GPIOC_PIN12) | \ - PIN_ASCR_DISABLED(GPIOC_BUTTON) | \ - PIN_ASCR_DISABLED(GPIOC_PIN14) | \ - PIN_ASCR_DISABLED(GPIOC_PIN15)) -#define VAL_GPIOC_LOCKR (PIN_LOCKR_DISABLED(GPIOC_PIN0) | \ - PIN_LOCKR_DISABLED(GPIOC_PIN1) | \ - PIN_LOCKR_DISABLED(GPIOC_PIN2) | \ - PIN_LOCKR_DISABLED(GPIOC_PIN3) | \ - PIN_LOCKR_DISABLED(GPIOC_PIN4) | \ - PIN_LOCKR_DISABLED(GPIOC_PIN5) | \ - PIN_LOCKR_DISABLED(GPIOC_PIN6) | \ - PIN_LOCKR_DISABLED(GPIOC_LED1) | \ - PIN_LOCKR_DISABLED(GPIOC_PIN8) | \ - PIN_LOCKR_DISABLED(GPIOC_PIN9) | \ - PIN_LOCKR_DISABLED(GPIOC_PIN10) | \ - PIN_LOCKR_DISABLED(GPIOC_PIN11) | \ - PIN_LOCKR_DISABLED(GPIOC_PIN12) | \ - PIN_LOCKR_DISABLED(GPIOC_BUTTON) | \ - PIN_LOCKR_DISABLED(GPIOC_PIN14) | \ - PIN_LOCKR_DISABLED(GPIOC_PIN15)) - -/* - * GPIOD setup: - * - * PD0 - PIN0 (analog). - * PD1 - PIN1 (analog). - * PD2 - PIN2 (analog). - * PD3 - PIN3 (analog). - * PD4 - PIN4 (analog). - * PD5 - PIN5 (analog). - * PD6 - PIN6 (analog). - * PD7 - PIN7 (analog). - * PD8 - PIN8 (analog). - * PD9 - PIN9 (analog). - * PD10 - PIN10 (analog). - * PD11 - PIN11 (analog). - * PD12 - PIN12 (analog). - * PD13 - PIN13 (analog). - * PD14 - PIN14 (analog). - * PD15 - PIN15 (analog). - */ -#define VAL_GPIOD_MODER (PIN_MODE_ANALOG(GPIOD_PIN0) | \ - PIN_MODE_ANALOG(GPIOD_PIN1) | \ - PIN_MODE_ANALOG(GPIOD_PIN2) | \ - PIN_MODE_ANALOG(GPIOD_PIN3) | \ - PIN_MODE_ANALOG(GPIOD_PIN4) | \ - PIN_MODE_ANALOG(GPIOD_PIN5) | \ - PIN_MODE_ANALOG(GPIOD_PIN6) | \ - PIN_MODE_ANALOG(GPIOD_PIN7) | \ - PIN_MODE_ANALOG(GPIOD_PIN8) | \ - PIN_MODE_ANALOG(GPIOD_PIN9) | \ - PIN_MODE_ANALOG(GPIOD_PIN10) | \ - PIN_MODE_ANALOG(GPIOD_PIN11) | \ - PIN_MODE_ANALOG(GPIOD_PIN12) | \ - PIN_MODE_ANALOG(GPIOD_PIN13) | \ - PIN_MODE_ANALOG(GPIOD_PIN14) | \ - PIN_MODE_ANALOG(GPIOD_PIN15)) -#define VAL_GPIOD_OTYPER (PIN_OTYPE_PUSHPULL(GPIOD_PIN0) | \ - PIN_OTYPE_PUSHPULL(GPIOD_PIN1) | \ - PIN_OTYPE_PUSHPULL(GPIOD_PIN2) | \ - PIN_OTYPE_PUSHPULL(GPIOD_PIN3) | \ - PIN_OTYPE_PUSHPULL(GPIOD_PIN4) | \ - PIN_OTYPE_PUSHPULL(GPIOD_PIN5) | \ - PIN_OTYPE_PUSHPULL(GPIOD_PIN6) | \ - PIN_OTYPE_PUSHPULL(GPIOD_PIN7) | \ - PIN_OTYPE_PUSHPULL(GPIOD_PIN8) | \ - PIN_OTYPE_PUSHPULL(GPIOD_PIN9) | \ - PIN_OTYPE_PUSHPULL(GPIOD_PIN10) | \ - PIN_OTYPE_PUSHPULL(GPIOD_PIN11) | \ - PIN_OTYPE_PUSHPULL(GPIOD_PIN12) | \ - PIN_OTYPE_PUSHPULL(GPIOD_PIN13) | \ - PIN_OTYPE_PUSHPULL(GPIOD_PIN14) | \ - PIN_OTYPE_PUSHPULL(GPIOD_PIN15)) -#define VAL_GPIOD_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOD_PIN0) | \ - PIN_OSPEED_VERYLOW(GPIOD_PIN1) | \ - PIN_OSPEED_VERYLOW(GPIOD_PIN2) | \ - PIN_OSPEED_VERYLOW(GPIOD_PIN3) | \ - PIN_OSPEED_VERYLOW(GPIOD_PIN4) | \ - PIN_OSPEED_VERYLOW(GPIOD_PIN5) | \ - PIN_OSPEED_VERYLOW(GPIOD_PIN6) | \ - PIN_OSPEED_VERYLOW(GPIOD_PIN7) | \ - PIN_OSPEED_VERYLOW(GPIOD_PIN8) | \ - PIN_OSPEED_VERYLOW(GPIOD_PIN9) | \ - PIN_OSPEED_VERYLOW(GPIOD_PIN10) | \ - PIN_OSPEED_VERYLOW(GPIOD_PIN11) | \ - PIN_OSPEED_VERYLOW(GPIOD_PIN12) | \ - PIN_OSPEED_VERYLOW(GPIOD_PIN13) | \ - PIN_OSPEED_VERYLOW(GPIOD_PIN14) | \ - PIN_OSPEED_VERYLOW(GPIOD_PIN15)) -#define VAL_GPIOD_PUPDR (PIN_PUPDR_FLOATING(GPIOD_PIN0) | \ - PIN_PUPDR_FLOATING(GPIOD_PIN1) | \ - PIN_PUPDR_FLOATING(GPIOD_PIN2) | \ - PIN_PUPDR_FLOATING(GPIOD_PIN3) | \ - PIN_PUPDR_FLOATING(GPIOD_PIN4) | \ - PIN_PUPDR_FLOATING(GPIOD_PIN5) | \ - PIN_PUPDR_FLOATING(GPIOD_PIN6) | \ - PIN_PUPDR_FLOATING(GPIOD_PIN7) | \ - PIN_PUPDR_FLOATING(GPIOD_PIN8) | \ - PIN_PUPDR_FLOATING(GPIOD_PIN9) | \ - PIN_PUPDR_FLOATING(GPIOD_PIN10) | \ - PIN_PUPDR_FLOATING(GPIOD_PIN11) | \ - PIN_PUPDR_FLOATING(GPIOD_PIN12) | \ - PIN_PUPDR_FLOATING(GPIOD_PIN13) | \ - PIN_PUPDR_FLOATING(GPIOD_PIN14) | \ - PIN_PUPDR_FLOATING(GPIOD_PIN15)) -#define VAL_GPIOD_ODR (PIN_ODR_LOW(GPIOD_PIN0) | \ - PIN_ODR_LOW(GPIOD_PIN1) | \ - PIN_ODR_LOW(GPIOD_PIN2) | \ - PIN_ODR_LOW(GPIOD_PIN3) | \ - PIN_ODR_LOW(GPIOD_PIN4) | \ - PIN_ODR_LOW(GPIOD_PIN5) | \ - PIN_ODR_LOW(GPIOD_PIN6) | \ - PIN_ODR_LOW(GPIOD_PIN7) | \ - PIN_ODR_LOW(GPIOD_PIN8) | \ - PIN_ODR_LOW(GPIOD_PIN9) | \ - PIN_ODR_LOW(GPIOD_PIN10) | \ - PIN_ODR_LOW(GPIOD_PIN11) | \ - PIN_ODR_LOW(GPIOD_PIN12) | \ - PIN_ODR_LOW(GPIOD_PIN13) | \ - PIN_ODR_LOW(GPIOD_PIN14) | \ - PIN_ODR_LOW(GPIOD_PIN15)) -#define VAL_GPIOD_AFRL (PIN_AFIO_AF(GPIOD_PIN0, 0U) | \ - PIN_AFIO_AF(GPIOD_PIN1, 0U) | \ - PIN_AFIO_AF(GPIOD_PIN2, 0U) | \ - PIN_AFIO_AF(GPIOD_PIN3, 0U) | \ - PIN_AFIO_AF(GPIOD_PIN4, 0U) | \ - PIN_AFIO_AF(GPIOD_PIN5, 0U) | \ - PIN_AFIO_AF(GPIOD_PIN6, 0U) | \ - PIN_AFIO_AF(GPIOD_PIN7, 0U)) -#define VAL_GPIOD_AFRH (PIN_AFIO_AF(GPIOD_PIN8, 0U) | \ - PIN_AFIO_AF(GPIOD_PIN9, 0U) | \ - PIN_AFIO_AF(GPIOD_PIN10, 0U) | \ - PIN_AFIO_AF(GPIOD_PIN11, 0U) | \ - PIN_AFIO_AF(GPIOD_PIN12, 0U) | \ - PIN_AFIO_AF(GPIOD_PIN13, 0U) | \ - PIN_AFIO_AF(GPIOD_PIN14, 0U) | \ - PIN_AFIO_AF(GPIOD_PIN15, 0U)) -#define VAL_GPIOD_ASCR (PIN_ASCR_DISABLED(GPIOD_PIN0) | \ - PIN_ASCR_DISABLED(GPIOD_PIN1) | \ - PIN_ASCR_DISABLED(GPIOD_PIN2) | \ - PIN_ASCR_DISABLED(GPIOD_PIN3) | \ - PIN_ASCR_DISABLED(GPIOD_PIN4) | \ - PIN_ASCR_DISABLED(GPIOD_PIN5) | \ - PIN_ASCR_DISABLED(GPIOD_PIN6) | \ - PIN_ASCR_DISABLED(GPIOD_PIN7) | \ - PIN_ASCR_DISABLED(GPIOD_PIN8) | \ - PIN_ASCR_DISABLED(GPIOD_PIN9) | \ - PIN_ASCR_DISABLED(GPIOD_PIN10) | \ - PIN_ASCR_DISABLED(GPIOD_PIN11) | \ - PIN_ASCR_DISABLED(GPIOD_PIN12) | \ - PIN_ASCR_DISABLED(GPIOD_PIN13) | \ - PIN_ASCR_DISABLED(GPIOD_PIN14) | \ - PIN_ASCR_DISABLED(GPIOD_PIN15)) -#define VAL_GPIOD_LOCKR (PIN_LOCKR_DISABLED(GPIOD_PIN0) | \ - PIN_LOCKR_DISABLED(GPIOD_PIN1) | \ - PIN_LOCKR_DISABLED(GPIOD_PIN2) | \ - PIN_LOCKR_DISABLED(GPIOD_PIN3) | \ - PIN_LOCKR_DISABLED(GPIOD_PIN4) | \ - PIN_LOCKR_DISABLED(GPIOD_PIN5) | \ - PIN_LOCKR_DISABLED(GPIOD_PIN6) | \ - PIN_LOCKR_DISABLED(GPIOD_PIN7) | \ - PIN_LOCKR_DISABLED(GPIOD_PIN8) | \ - PIN_LOCKR_DISABLED(GPIOD_PIN9) | \ - PIN_LOCKR_DISABLED(GPIOD_PIN10) | \ - PIN_LOCKR_DISABLED(GPIOD_PIN11) | \ - PIN_LOCKR_DISABLED(GPIOD_PIN12) | \ - PIN_LOCKR_DISABLED(GPIOD_PIN13) | \ - PIN_LOCKR_DISABLED(GPIOD_PIN14) | \ - PIN_LOCKR_DISABLED(GPIOD_PIN15)) - -/* - * GPIOE setup: - * - * PE0 - PIN0 (analog). - * PE1 - PIN1 (analog). - * PE2 - PIN2 (analog). - * PE3 - PIN3 (analog). - * PE4 - PIN4 (analog). - * PE5 - PIN5 (analog). - * PE6 - PIN6 (analog). - * PE7 - PIN7 (analog). - * PE8 - PIN8 (analog). - * PE9 - PIN9 (analog). - * PE10 - PIN10 (analog). - * PE11 - PIN11 (analog). - * PE12 - PIN12 (analog). - * PE13 - PIN13 (analog). - * PE14 - PIN14 (analog). - * PE15 - PIN15 (analog). - */ -#define VAL_GPIOE_MODER (PIN_MODE_ANALOG(GPIOE_PIN0) | \ - PIN_MODE_ANALOG(GPIOE_PIN1) | \ - PIN_MODE_ANALOG(GPIOE_PIN2) | \ - PIN_MODE_ANALOG(GPIOE_PIN3) | \ - PIN_MODE_ANALOG(GPIOE_PIN4) | \ - PIN_MODE_ANALOG(GPIOE_PIN5) | \ - PIN_MODE_ANALOG(GPIOE_PIN6) | \ - PIN_MODE_ANALOG(GPIOE_PIN7) | \ - PIN_MODE_ANALOG(GPIOE_PIN8) | \ - PIN_MODE_ANALOG(GPIOE_PIN9) | \ - PIN_MODE_ANALOG(GPIOE_PIN10) | \ - PIN_MODE_ANALOG(GPIOE_PIN11) | \ - PIN_MODE_ANALOG(GPIOE_PIN12) | \ - PIN_MODE_ANALOG(GPIOE_PIN13) | \ - PIN_MODE_ANALOG(GPIOE_PIN14) | \ - PIN_MODE_ANALOG(GPIOE_PIN15)) -#define VAL_GPIOE_OTYPER (PIN_OTYPE_PUSHPULL(GPIOE_PIN0) | \ - PIN_OTYPE_PUSHPULL(GPIOE_PIN1) | \ - PIN_OTYPE_PUSHPULL(GPIOE_PIN2) | \ - PIN_OTYPE_PUSHPULL(GPIOE_PIN3) | \ - PIN_OTYPE_PUSHPULL(GPIOE_PIN4) | \ - PIN_OTYPE_PUSHPULL(GPIOE_PIN5) | \ - PIN_OTYPE_PUSHPULL(GPIOE_PIN6) | \ - PIN_OTYPE_PUSHPULL(GPIOE_PIN7) | \ - PIN_OTYPE_PUSHPULL(GPIOE_PIN8) | \ - PIN_OTYPE_PUSHPULL(GPIOE_PIN9) | \ - PIN_OTYPE_PUSHPULL(GPIOE_PIN10) | \ - PIN_OTYPE_PUSHPULL(GPIOE_PIN11) | \ - PIN_OTYPE_PUSHPULL(GPIOE_PIN12) | \ - PIN_OTYPE_PUSHPULL(GPIOE_PIN13) | \ - PIN_OTYPE_PUSHPULL(GPIOE_PIN14) | \ - PIN_OTYPE_PUSHPULL(GPIOE_PIN15)) -#define VAL_GPIOE_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOE_PIN0) | \ - PIN_OSPEED_VERYLOW(GPIOE_PIN1) | \ - PIN_OSPEED_VERYLOW(GPIOE_PIN2) | \ - PIN_OSPEED_VERYLOW(GPIOE_PIN3) | \ - PIN_OSPEED_VERYLOW(GPIOE_PIN4) | \ - PIN_OSPEED_VERYLOW(GPIOE_PIN5) | \ - PIN_OSPEED_VERYLOW(GPIOE_PIN6) | \ - PIN_OSPEED_VERYLOW(GPIOE_PIN7) | \ - PIN_OSPEED_VERYLOW(GPIOE_PIN8) | \ - PIN_OSPEED_VERYLOW(GPIOE_PIN9) | \ - PIN_OSPEED_VERYLOW(GPIOE_PIN10) | \ - PIN_OSPEED_VERYLOW(GPIOE_PIN11) | \ - PIN_OSPEED_VERYLOW(GPIOE_PIN12) | \ - PIN_OSPEED_VERYLOW(GPIOE_PIN13) | \ - PIN_OSPEED_VERYLOW(GPIOE_PIN14) | \ - PIN_OSPEED_VERYLOW(GPIOE_PIN15)) -#define VAL_GPIOE_PUPDR (PIN_PUPDR_FLOATING(GPIOE_PIN0) | \ - PIN_PUPDR_FLOATING(GPIOE_PIN1) | \ - PIN_PUPDR_FLOATING(GPIOE_PIN2) | \ - PIN_PUPDR_FLOATING(GPIOE_PIN3) | \ - PIN_PUPDR_FLOATING(GPIOE_PIN4) | \ - PIN_PUPDR_FLOATING(GPIOE_PIN5) | \ - PIN_PUPDR_FLOATING(GPIOE_PIN6) | \ - PIN_PUPDR_FLOATING(GPIOE_PIN7) | \ - PIN_PUPDR_FLOATING(GPIOE_PIN8) | \ - PIN_PUPDR_FLOATING(GPIOE_PIN9) | \ - PIN_PUPDR_FLOATING(GPIOE_PIN10) | \ - PIN_PUPDR_FLOATING(GPIOE_PIN11) | \ - PIN_PUPDR_FLOATING(GPIOE_PIN12) | \ - PIN_PUPDR_FLOATING(GPIOE_PIN13) | \ - PIN_PUPDR_FLOATING(GPIOE_PIN14) | \ - PIN_PUPDR_FLOATING(GPIOE_PIN15)) -#define VAL_GPIOE_ODR (PIN_ODR_LOW(GPIOE_PIN0) | \ - PIN_ODR_LOW(GPIOE_PIN1) | \ - PIN_ODR_LOW(GPIOE_PIN2) | \ - PIN_ODR_LOW(GPIOE_PIN3) | \ - PIN_ODR_LOW(GPIOE_PIN4) | \ - PIN_ODR_LOW(GPIOE_PIN5) | \ - PIN_ODR_LOW(GPIOE_PIN6) | \ - PIN_ODR_LOW(GPIOE_PIN7) | \ - PIN_ODR_LOW(GPIOE_PIN8) | \ - PIN_ODR_LOW(GPIOE_PIN9) | \ - PIN_ODR_LOW(GPIOE_PIN10) | \ - PIN_ODR_LOW(GPIOE_PIN11) | \ - PIN_ODR_LOW(GPIOE_PIN12) | \ - PIN_ODR_LOW(GPIOE_PIN13) | \ - PIN_ODR_LOW(GPIOE_PIN14) | \ - PIN_ODR_LOW(GPIOE_PIN15)) -#define VAL_GPIOE_AFRL (PIN_AFIO_AF(GPIOE_PIN0, 0U) | \ - PIN_AFIO_AF(GPIOE_PIN1, 0U) | \ - PIN_AFIO_AF(GPIOE_PIN2, 0U) | \ - PIN_AFIO_AF(GPIOE_PIN3, 0U) | \ - PIN_AFIO_AF(GPIOE_PIN4, 0U) | \ - PIN_AFIO_AF(GPIOE_PIN5, 0U) | \ - PIN_AFIO_AF(GPIOE_PIN6, 0U) | \ - PIN_AFIO_AF(GPIOE_PIN7, 0U)) -#define VAL_GPIOE_AFRH (PIN_AFIO_AF(GPIOE_PIN8, 0U) | \ - PIN_AFIO_AF(GPIOE_PIN9, 0U) | \ - PIN_AFIO_AF(GPIOE_PIN10, 0U) | \ - PIN_AFIO_AF(GPIOE_PIN11, 0U) | \ - PIN_AFIO_AF(GPIOE_PIN12, 0U) | \ - PIN_AFIO_AF(GPIOE_PIN13, 0U) | \ - PIN_AFIO_AF(GPIOE_PIN14, 0U) | \ - PIN_AFIO_AF(GPIOE_PIN15, 0U)) -#define VAL_GPIOE_ASCR (PIN_ASCR_DISABLED(GPIOE_PIN0) | \ - PIN_ASCR_DISABLED(GPIOE_PIN1) | \ - PIN_ASCR_DISABLED(GPIOE_PIN2) | \ - PIN_ASCR_DISABLED(GPIOE_PIN3) | \ - PIN_ASCR_DISABLED(GPIOE_PIN4) | \ - PIN_ASCR_DISABLED(GPIOE_PIN5) | \ - PIN_ASCR_DISABLED(GPIOE_PIN6) | \ - PIN_ASCR_DISABLED(GPIOE_PIN7) | \ - PIN_ASCR_DISABLED(GPIOE_PIN8) | \ - PIN_ASCR_DISABLED(GPIOE_PIN9) | \ - PIN_ASCR_DISABLED(GPIOE_PIN10) | \ - PIN_ASCR_DISABLED(GPIOE_PIN11) | \ - PIN_ASCR_DISABLED(GPIOE_PIN12) | \ - PIN_ASCR_DISABLED(GPIOE_PIN13) | \ - PIN_ASCR_DISABLED(GPIOE_PIN14) | \ - PIN_ASCR_DISABLED(GPIOE_PIN15)) -#define VAL_GPIOE_LOCKR (PIN_LOCKR_DISABLED(GPIOE_PIN0) | \ - PIN_LOCKR_DISABLED(GPIOE_PIN1) | \ - PIN_LOCKR_DISABLED(GPIOE_PIN2) | \ - PIN_LOCKR_DISABLED(GPIOE_PIN3) | \ - PIN_LOCKR_DISABLED(GPIOE_PIN4) | \ - PIN_LOCKR_DISABLED(GPIOE_PIN5) | \ - PIN_LOCKR_DISABLED(GPIOE_PIN6) | \ - PIN_LOCKR_DISABLED(GPIOE_PIN7) | \ - PIN_LOCKR_DISABLED(GPIOE_PIN8) | \ - PIN_LOCKR_DISABLED(GPIOE_PIN9) | \ - PIN_LOCKR_DISABLED(GPIOE_PIN10) | \ - PIN_LOCKR_DISABLED(GPIOE_PIN11) | \ - PIN_LOCKR_DISABLED(GPIOE_PIN12) | \ - PIN_LOCKR_DISABLED(GPIOE_PIN13) | \ - PIN_LOCKR_DISABLED(GPIOE_PIN14) | \ - PIN_LOCKR_DISABLED(GPIOE_PIN15)) - -/* - * GPIOF setup: - * - * PF0 - PIN0 (analog). - * PF1 - PIN1 (analog). - * PF2 - PIN2 (analog). - * PF3 - PIN3 (analog). - * PF4 - PIN4 (analog). - * PF5 - PIN5 (analog). - * PF6 - PIN6 (analog). - * PF7 - PIN7 (analog). - * PF8 - PIN8 (analog). - * PF9 - PIN9 (analog). - * PF10 - PIN10 (analog). - * PF11 - PIN11 (analog). - * PF12 - PIN12 (analog). - * PF13 - PIN13 (analog). - * PF14 - PIN14 (analog). - * PF15 - PIN15 (analog). - */ -#define VAL_GPIOF_MODER (PIN_MODE_ANALOG(GPIOF_PIN0) | \ - PIN_MODE_ANALOG(GPIOF_PIN1) | \ - PIN_MODE_ANALOG(GPIOF_PIN2) | \ - PIN_MODE_ANALOG(GPIOF_PIN3) | \ - PIN_MODE_ANALOG(GPIOF_PIN4) | \ - PIN_MODE_ANALOG(GPIOF_PIN5) | \ - PIN_MODE_ANALOG(GPIOF_PIN6) | \ - PIN_MODE_ANALOG(GPIOF_PIN7) | \ - PIN_MODE_ANALOG(GPIOF_PIN8) | \ - PIN_MODE_ANALOG(GPIOF_PIN9) | \ - PIN_MODE_ANALOG(GPIOF_PIN10) | \ - PIN_MODE_ANALOG(GPIOF_PIN11) | \ - PIN_MODE_ANALOG(GPIOF_PIN12) | \ - PIN_MODE_ANALOG(GPIOF_PIN13) | \ - PIN_MODE_ANALOG(GPIOF_PIN14) | \ - PIN_MODE_ANALOG(GPIOF_PIN15)) -#define VAL_GPIOF_OTYPER (PIN_OTYPE_PUSHPULL(GPIOF_PIN0) | \ - PIN_OTYPE_PUSHPULL(GPIOF_PIN1) | \ - PIN_OTYPE_PUSHPULL(GPIOF_PIN2) | \ - PIN_OTYPE_PUSHPULL(GPIOF_PIN3) | \ - PIN_OTYPE_PUSHPULL(GPIOF_PIN4) | \ - PIN_OTYPE_PUSHPULL(GPIOF_PIN5) | \ - PIN_OTYPE_PUSHPULL(GPIOF_PIN6) | \ - PIN_OTYPE_PUSHPULL(GPIOF_PIN7) | \ - PIN_OTYPE_PUSHPULL(GPIOF_PIN8) | \ - PIN_OTYPE_PUSHPULL(GPIOF_PIN9) | \ - PIN_OTYPE_PUSHPULL(GPIOF_PIN10) | \ - PIN_OTYPE_PUSHPULL(GPIOF_PIN11) | \ - PIN_OTYPE_PUSHPULL(GPIOF_PIN12) | \ - PIN_OTYPE_PUSHPULL(GPIOF_PIN13) | \ - PIN_OTYPE_PUSHPULL(GPIOF_PIN14) | \ - PIN_OTYPE_PUSHPULL(GPIOF_PIN15)) -#define VAL_GPIOF_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOF_PIN0) | \ - PIN_OSPEED_VERYLOW(GPIOF_PIN1) | \ - PIN_OSPEED_VERYLOW(GPIOF_PIN2) | \ - PIN_OSPEED_VERYLOW(GPIOF_PIN3) | \ - PIN_OSPEED_VERYLOW(GPIOF_PIN4) | \ - PIN_OSPEED_VERYLOW(GPIOF_PIN5) | \ - PIN_OSPEED_VERYLOW(GPIOF_PIN6) | \ - PIN_OSPEED_VERYLOW(GPIOF_PIN7) | \ - PIN_OSPEED_VERYLOW(GPIOF_PIN8) | \ - PIN_OSPEED_VERYLOW(GPIOF_PIN9) | \ - PIN_OSPEED_VERYLOW(GPIOF_PIN10) | \ - PIN_OSPEED_VERYLOW(GPIOF_PIN11) | \ - PIN_OSPEED_VERYLOW(GPIOF_PIN12) | \ - PIN_OSPEED_VERYLOW(GPIOF_PIN13) | \ - PIN_OSPEED_VERYLOW(GPIOF_PIN14) | \ - PIN_OSPEED_VERYLOW(GPIOF_PIN15)) -#define VAL_GPIOF_PUPDR (PIN_PUPDR_FLOATING(GPIOF_PIN0) | \ - PIN_PUPDR_FLOATING(GPIOF_PIN1) | \ - PIN_PUPDR_FLOATING(GPIOF_PIN2) | \ - PIN_PUPDR_FLOATING(GPIOF_PIN3) | \ - PIN_PUPDR_FLOATING(GPIOF_PIN4) | \ - PIN_PUPDR_FLOATING(GPIOF_PIN5) | \ - PIN_PUPDR_FLOATING(GPIOF_PIN6) | \ - PIN_PUPDR_FLOATING(GPIOF_PIN7) | \ - PIN_PUPDR_FLOATING(GPIOF_PIN8) | \ - PIN_PUPDR_FLOATING(GPIOF_PIN9) | \ - PIN_PUPDR_FLOATING(GPIOF_PIN10) | \ - PIN_PUPDR_FLOATING(GPIOF_PIN11) | \ - PIN_PUPDR_FLOATING(GPIOF_PIN12) | \ - PIN_PUPDR_FLOATING(GPIOF_PIN13) | \ - PIN_PUPDR_FLOATING(GPIOF_PIN14) | \ - PIN_PUPDR_FLOATING(GPIOF_PIN15)) -#define VAL_GPIOF_ODR (PIN_ODR_LOW(GPIOF_PIN0) | \ - PIN_ODR_LOW(GPIOF_PIN1) | \ - PIN_ODR_LOW(GPIOF_PIN2) | \ - PIN_ODR_LOW(GPIOF_PIN3) | \ - PIN_ODR_LOW(GPIOF_PIN4) | \ - PIN_ODR_LOW(GPIOF_PIN5) | \ - PIN_ODR_LOW(GPIOF_PIN6) | \ - PIN_ODR_LOW(GPIOF_PIN7) | \ - PIN_ODR_LOW(GPIOF_PIN8) | \ - PIN_ODR_LOW(GPIOF_PIN9) | \ - PIN_ODR_LOW(GPIOF_PIN10) | \ - PIN_ODR_LOW(GPIOF_PIN11) | \ - PIN_ODR_LOW(GPIOF_PIN12) | \ - PIN_ODR_LOW(GPIOF_PIN13) | \ - PIN_ODR_LOW(GPIOF_PIN14) | \ - PIN_ODR_LOW(GPIOF_PIN15)) -#define VAL_GPIOF_AFRL (PIN_AFIO_AF(GPIOF_PIN0, 0U) | \ - PIN_AFIO_AF(GPIOF_PIN1, 0U) | \ - PIN_AFIO_AF(GPIOF_PIN2, 0U) | \ - PIN_AFIO_AF(GPIOF_PIN3, 0U) | \ - PIN_AFIO_AF(GPIOF_PIN4, 0U) | \ - PIN_AFIO_AF(GPIOF_PIN5, 0U) | \ - PIN_AFIO_AF(GPIOF_PIN6, 0U) | \ - PIN_AFIO_AF(GPIOF_PIN7, 0U)) -#define VAL_GPIOF_AFRH (PIN_AFIO_AF(GPIOF_PIN8, 0U) | \ - PIN_AFIO_AF(GPIOF_PIN9, 0U) | \ - PIN_AFIO_AF(GPIOF_PIN10, 0U) | \ - PIN_AFIO_AF(GPIOF_PIN11, 0U) | \ - PIN_AFIO_AF(GPIOF_PIN12, 0U) | \ - PIN_AFIO_AF(GPIOF_PIN13, 0U) | \ - PIN_AFIO_AF(GPIOF_PIN14, 0U) | \ - PIN_AFIO_AF(GPIOF_PIN15, 0U)) -#define VAL_GPIOF_ASCR (PIN_ASCR_DISABLED(GPIOF_PIN0) | \ - PIN_ASCR_DISABLED(GPIOF_PIN1) | \ - PIN_ASCR_DISABLED(GPIOF_PIN2) | \ - PIN_ASCR_DISABLED(GPIOF_PIN3) | \ - PIN_ASCR_DISABLED(GPIOF_PIN4) | \ - PIN_ASCR_DISABLED(GPIOF_PIN5) | \ - PIN_ASCR_DISABLED(GPIOF_PIN6) | \ - PIN_ASCR_DISABLED(GPIOF_PIN7) | \ - PIN_ASCR_DISABLED(GPIOF_PIN8) | \ - PIN_ASCR_DISABLED(GPIOF_PIN9) | \ - PIN_ASCR_DISABLED(GPIOF_PIN10) | \ - PIN_ASCR_DISABLED(GPIOF_PIN11) | \ - PIN_ASCR_DISABLED(GPIOF_PIN12) | \ - PIN_ASCR_DISABLED(GPIOF_PIN13) | \ - PIN_ASCR_DISABLED(GPIOF_PIN14) | \ - PIN_ASCR_DISABLED(GPIOF_PIN15)) -#define VAL_GPIOF_LOCKR (PIN_LOCKR_DISABLED(GPIOF_PIN0) | \ - PIN_LOCKR_DISABLED(GPIOF_PIN1) | \ - PIN_LOCKR_DISABLED(GPIOF_PIN2) | \ - PIN_LOCKR_DISABLED(GPIOF_PIN3) | \ - PIN_LOCKR_DISABLED(GPIOF_PIN4) | \ - PIN_LOCKR_DISABLED(GPIOF_PIN5) | \ - PIN_LOCKR_DISABLED(GPIOF_PIN6) | \ - PIN_LOCKR_DISABLED(GPIOF_PIN7) | \ - PIN_LOCKR_DISABLED(GPIOF_PIN8) | \ - PIN_LOCKR_DISABLED(GPIOF_PIN9) | \ - PIN_LOCKR_DISABLED(GPIOF_PIN10) | \ - PIN_LOCKR_DISABLED(GPIOF_PIN11) | \ - PIN_LOCKR_DISABLED(GPIOF_PIN12) | \ - PIN_LOCKR_DISABLED(GPIOF_PIN13) | \ - PIN_LOCKR_DISABLED(GPIOF_PIN14) | \ - PIN_LOCKR_DISABLED(GPIOF_PIN15)) - -/* - * GPIOG setup: - * - * PG0 - PIN0 (analog). - * PG1 - PIN1 (analog). - * PG2 - PIN2 (analog). - * PG3 - PIN3 (analog). - * PG4 - PIN4 (analog). - * PG5 - USB_OVER_CURRENT (input floating). - * PG6 - USB_POWER_SWITCH_ON (output pushpull maximum). - * PG7 - LPUART1_TX (alternate 8). - * PG8 - LPUART1_RX (alternate 8). - * PG9 - PIN9 (analog). - * PG10 - PIN10 (analog). - * PG11 - PIN11 (analog). - * PG12 - PIN12 (analog). - * PG13 - PIN13 (analog). - * PG14 - PIN14 (analog). - * PG15 - PIN15 (analog). - */ -#define VAL_GPIOG_MODER (PIN_MODE_ANALOG(GPIOG_PIN0) | \ - PIN_MODE_ANALOG(GPIOG_PIN1) | \ - PIN_MODE_ANALOG(GPIOG_PIN2) | \ - PIN_MODE_ANALOG(GPIOG_PIN3) | \ - PIN_MODE_ANALOG(GPIOG_PIN4) | \ - PIN_MODE_INPUT(GPIOG_USB_OVER_CURRENT) |\ - PIN_MODE_OUTPUT(GPIOG_USB_POWER_SWITCH_ON) |\ - PIN_MODE_ALTERNATE(GPIOG_LPUART1_TX) | \ - PIN_MODE_ALTERNATE(GPIOG_LPUART1_RX) | \ - PIN_MODE_ANALOG(GPIOG_PIN9) | \ - PIN_MODE_ANALOG(GPIOG_PIN10) | \ - PIN_MODE_ANALOG(GPIOG_PIN11) | \ - PIN_MODE_ANALOG(GPIOG_PIN12) | \ - PIN_MODE_ANALOG(GPIOG_PIN13) | \ - PIN_MODE_ANALOG(GPIOG_PIN14) | \ - PIN_MODE_ANALOG(GPIOG_PIN15)) -#define VAL_GPIOG_OTYPER (PIN_OTYPE_PUSHPULL(GPIOG_PIN0) | \ - PIN_OTYPE_PUSHPULL(GPIOG_PIN1) | \ - PIN_OTYPE_PUSHPULL(GPIOG_PIN2) | \ - PIN_OTYPE_PUSHPULL(GPIOG_PIN3) | \ - PIN_OTYPE_PUSHPULL(GPIOG_PIN4) | \ - PIN_OTYPE_PUSHPULL(GPIOG_USB_OVER_CURRENT) |\ - PIN_OTYPE_PUSHPULL(GPIOG_USB_POWER_SWITCH_ON) |\ - PIN_OTYPE_PUSHPULL(GPIOG_LPUART1_TX) | \ - PIN_OTYPE_PUSHPULL(GPIOG_LPUART1_RX) | \ - PIN_OTYPE_PUSHPULL(GPIOG_PIN9) | \ - PIN_OTYPE_PUSHPULL(GPIOG_PIN10) | \ - PIN_OTYPE_PUSHPULL(GPIOG_PIN11) | \ - PIN_OTYPE_PUSHPULL(GPIOG_PIN12) | \ - PIN_OTYPE_PUSHPULL(GPIOG_PIN13) | \ - PIN_OTYPE_PUSHPULL(GPIOG_PIN14) | \ - PIN_OTYPE_PUSHPULL(GPIOG_PIN15)) -#define VAL_GPIOG_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOG_PIN0) | \ - PIN_OSPEED_VERYLOW(GPIOG_PIN1) | \ - PIN_OSPEED_VERYLOW(GPIOG_PIN2) | \ - PIN_OSPEED_VERYLOW(GPIOG_PIN3) | \ - PIN_OSPEED_VERYLOW(GPIOG_PIN4) | \ - PIN_OSPEED_VERYLOW(GPIOG_USB_OVER_CURRENT) |\ - PIN_OSPEED_HIGH(GPIOG_USB_POWER_SWITCH_ON) |\ - PIN_OSPEED_VERYLOW(GPIOG_LPUART1_TX) | \ - PIN_OSPEED_VERYLOW(GPIOG_LPUART1_RX) | \ - PIN_OSPEED_VERYLOW(GPIOG_PIN9) | \ - PIN_OSPEED_VERYLOW(GPIOG_PIN10) | \ - PIN_OSPEED_VERYLOW(GPIOG_PIN11) | \ - PIN_OSPEED_VERYLOW(GPIOG_PIN12) | \ - PIN_OSPEED_VERYLOW(GPIOG_PIN13) | \ - PIN_OSPEED_VERYLOW(GPIOG_PIN14) | \ - PIN_OSPEED_VERYLOW(GPIOG_PIN15)) -#define VAL_GPIOG_PUPDR (PIN_PUPDR_FLOATING(GPIOG_PIN0) | \ - PIN_PUPDR_FLOATING(GPIOG_PIN1) | \ - PIN_PUPDR_FLOATING(GPIOG_PIN2) | \ - PIN_PUPDR_FLOATING(GPIOG_PIN3) | \ - PIN_PUPDR_FLOATING(GPIOG_PIN4) | \ - PIN_PUPDR_FLOATING(GPIOG_USB_OVER_CURRENT) |\ - PIN_PUPDR_FLOATING(GPIOG_USB_POWER_SWITCH_ON) |\ - PIN_PUPDR_FLOATING(GPIOG_LPUART1_TX) | \ - PIN_PUPDR_FLOATING(GPIOG_LPUART1_RX) | \ - PIN_PUPDR_FLOATING(GPIOG_PIN9) | \ - PIN_PUPDR_FLOATING(GPIOG_PIN10) | \ - PIN_PUPDR_FLOATING(GPIOG_PIN11) | \ - PIN_PUPDR_FLOATING(GPIOG_PIN12) | \ - PIN_PUPDR_FLOATING(GPIOG_PIN13) | \ - PIN_PUPDR_FLOATING(GPIOG_PIN14) | \ - PIN_PUPDR_FLOATING(GPIOG_PIN15)) -#define VAL_GPIOG_ODR (PIN_ODR_LOW(GPIOG_PIN0) | \ - PIN_ODR_LOW(GPIOG_PIN1) | \ - PIN_ODR_LOW(GPIOG_PIN2) | \ - PIN_ODR_LOW(GPIOG_PIN3) | \ - PIN_ODR_LOW(GPIOG_PIN4) | \ - PIN_ODR_LOW(GPIOG_USB_OVER_CURRENT) | \ - PIN_ODR_LOW(GPIOG_USB_POWER_SWITCH_ON) |\ - PIN_ODR_LOW(GPIOG_LPUART1_TX) | \ - PIN_ODR_LOW(GPIOG_LPUART1_RX) | \ - PIN_ODR_LOW(GPIOG_PIN9) | \ - PIN_ODR_LOW(GPIOG_PIN10) | \ - PIN_ODR_LOW(GPIOG_PIN11) | \ - PIN_ODR_LOW(GPIOG_PIN12) | \ - PIN_ODR_LOW(GPIOG_PIN13) | \ - PIN_ODR_LOW(GPIOG_PIN14) | \ - PIN_ODR_LOW(GPIOG_PIN15)) -#define VAL_GPIOG_AFRL (PIN_AFIO_AF(GPIOG_PIN0, 0U) | \ - PIN_AFIO_AF(GPIOG_PIN1, 0U) | \ - PIN_AFIO_AF(GPIOG_PIN2, 0U) | \ - PIN_AFIO_AF(GPIOG_PIN3, 0U) | \ - PIN_AFIO_AF(GPIOG_PIN4, 0U) | \ - PIN_AFIO_AF(GPIOG_USB_OVER_CURRENT, 0U) |\ - PIN_AFIO_AF(GPIOG_USB_POWER_SWITCH_ON, 0U) |\ - PIN_AFIO_AF(GPIOG_LPUART1_TX, 8U)) -#define VAL_GPIOG_AFRH (PIN_AFIO_AF(GPIOG_LPUART1_RX, 8U) | \ - PIN_AFIO_AF(GPIOG_PIN9, 0U) | \ - PIN_AFIO_AF(GPIOG_PIN10, 0U) | \ - PIN_AFIO_AF(GPIOG_PIN11, 0U) | \ - PIN_AFIO_AF(GPIOG_PIN12, 0U) | \ - PIN_AFIO_AF(GPIOG_PIN13, 0U) | \ - PIN_AFIO_AF(GPIOG_PIN14, 0U) | \ - PIN_AFIO_AF(GPIOG_PIN15, 0U)) -#define VAL_GPIOG_ASCR (PIN_ASCR_DISABLED(GPIOG_PIN0) | \ - PIN_ASCR_DISABLED(GPIOG_PIN1) | \ - PIN_ASCR_DISABLED(GPIOG_PIN2) | \ - PIN_ASCR_DISABLED(GPIOG_PIN3) | \ - PIN_ASCR_DISABLED(GPIOG_PIN4) | \ - PIN_ASCR_DISABLED(GPIOG_USB_OVER_CURRENT) |\ - PIN_ASCR_DISABLED(GPIOG_USB_POWER_SWITCH_ON) |\ - PIN_ASCR_DISABLED(GPIOG_LPUART1_TX) | \ - PIN_ASCR_DISABLED(GPIOG_LPUART1_RX) | \ - PIN_ASCR_DISABLED(GPIOG_PIN9) | \ - PIN_ASCR_DISABLED(GPIOG_PIN10) | \ - PIN_ASCR_DISABLED(GPIOG_PIN11) | \ - PIN_ASCR_DISABLED(GPIOG_PIN12) | \ - PIN_ASCR_DISABLED(GPIOG_PIN13) | \ - PIN_ASCR_DISABLED(GPIOG_PIN14) | \ - PIN_ASCR_DISABLED(GPIOG_PIN15)) -#define VAL_GPIOG_LOCKR (PIN_LOCKR_DISABLED(GPIOG_PIN0) | \ - PIN_LOCKR_DISABLED(GPIOG_PIN1) | \ - PIN_LOCKR_DISABLED(GPIOG_PIN2) | \ - PIN_LOCKR_DISABLED(GPIOG_PIN3) | \ - PIN_LOCKR_DISABLED(GPIOG_PIN4) | \ - PIN_LOCKR_DISABLED(GPIOG_USB_OVER_CURRENT) |\ - PIN_LOCKR_DISABLED(GPIOG_USB_POWER_SWITCH_ON) |\ - PIN_LOCKR_DISABLED(GPIOG_LPUART1_TX) | \ - PIN_LOCKR_DISABLED(GPIOG_LPUART1_RX) | \ - PIN_LOCKR_DISABLED(GPIOG_PIN9) | \ - PIN_LOCKR_DISABLED(GPIOG_PIN10) | \ - PIN_LOCKR_DISABLED(GPIOG_PIN11) | \ - PIN_LOCKR_DISABLED(GPIOG_PIN12) | \ - PIN_LOCKR_DISABLED(GPIOG_PIN13) | \ - PIN_LOCKR_DISABLED(GPIOG_PIN14) | \ - PIN_LOCKR_DISABLED(GPIOG_PIN15)) - -/* - * GPIOH setup: - * - * PH0 - PIN0 (analog). - * PH1 - PIN1 (analog). - * PH2 - PIN2 (input floating). - * PH3 - PIN3 (input floating). - * PH4 - PIN4 (input floating). - * PH5 - PIN5 (input floating). - * PH6 - PIN6 (input floating). - * PH7 - PIN7 (input floating). - * PH8 - PIN8 (input floating). - * PH9 - PIN9 (input floating). - * PH10 - PIN10 (input floating). - * PH11 - PIN11 (input floating). - * PH12 - PIN12 (input floating). - * PH13 - PIN13 (input floating). - * PH14 - PIN14 (input floating). - * PH15 - PIN15 (input floating). - */ -#define VAL_GPIOH_MODER (PIN_MODE_ANALOG(GPIOH_PIN0) | \ - PIN_MODE_ANALOG(GPIOH_PIN1) | \ - PIN_MODE_INPUT(GPIOH_PIN2) | \ - PIN_MODE_INPUT(GPIOH_PIN3) | \ - PIN_MODE_INPUT(GPIOH_PIN4) | \ - PIN_MODE_INPUT(GPIOH_PIN5) | \ - PIN_MODE_INPUT(GPIOH_PIN6) | \ - PIN_MODE_INPUT(GPIOH_PIN7) | \ - PIN_MODE_INPUT(GPIOH_PIN8) | \ - PIN_MODE_INPUT(GPIOH_PIN9) | \ - PIN_MODE_INPUT(GPIOH_PIN10) | \ - PIN_MODE_INPUT(GPIOH_PIN11) | \ - PIN_MODE_INPUT(GPIOH_PIN12) | \ - PIN_MODE_INPUT(GPIOH_PIN13) | \ - PIN_MODE_INPUT(GPIOH_PIN14) | \ - PIN_MODE_INPUT(GPIOH_PIN15)) -#define VAL_GPIOH_OTYPER (PIN_OTYPE_PUSHPULL(GPIOH_PIN0) | \ - PIN_OTYPE_PUSHPULL(GPIOH_PIN1) | \ - PIN_OTYPE_PUSHPULL(GPIOH_PIN2) | \ - PIN_OTYPE_PUSHPULL(GPIOH_PIN3) | \ - PIN_OTYPE_PUSHPULL(GPIOH_PIN4) | \ - PIN_OTYPE_PUSHPULL(GPIOH_PIN5) | \ - PIN_OTYPE_PUSHPULL(GPIOH_PIN6) | \ - PIN_OTYPE_PUSHPULL(GPIOH_PIN7) | \ - PIN_OTYPE_PUSHPULL(GPIOH_PIN8) | \ - PIN_OTYPE_PUSHPULL(GPIOH_PIN9) | \ - PIN_OTYPE_PUSHPULL(GPIOH_PIN10) | \ - PIN_OTYPE_PUSHPULL(GPIOH_PIN11) | \ - PIN_OTYPE_PUSHPULL(GPIOH_PIN12) | \ - PIN_OTYPE_PUSHPULL(GPIOH_PIN13) | \ - PIN_OTYPE_PUSHPULL(GPIOH_PIN14) | \ - PIN_OTYPE_PUSHPULL(GPIOH_PIN15)) -#define VAL_GPIOH_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOH_PIN0) | \ - PIN_OSPEED_VERYLOW(GPIOH_PIN1) | \ - PIN_OSPEED_VERYLOW(GPIOH_PIN2) | \ - PIN_OSPEED_VERYLOW(GPIOH_PIN3) | \ - PIN_OSPEED_VERYLOW(GPIOH_PIN4) | \ - PIN_OSPEED_VERYLOW(GPIOH_PIN5) | \ - PIN_OSPEED_VERYLOW(GPIOH_PIN6) | \ - PIN_OSPEED_VERYLOW(GPIOH_PIN7) | \ - PIN_OSPEED_VERYLOW(GPIOH_PIN8) | \ - PIN_OSPEED_VERYLOW(GPIOH_PIN9) | \ - PIN_OSPEED_VERYLOW(GPIOH_PIN10) | \ - PIN_OSPEED_VERYLOW(GPIOH_PIN11) | \ - PIN_OSPEED_VERYLOW(GPIOH_PIN12) | \ - PIN_OSPEED_VERYLOW(GPIOH_PIN13) | \ - PIN_OSPEED_VERYLOW(GPIOH_PIN14) | \ - PIN_OSPEED_VERYLOW(GPIOH_PIN15)) -#define VAL_GPIOH_PUPDR (PIN_PUPDR_FLOATING(GPIOH_PIN0) | \ - PIN_PUPDR_FLOATING(GPIOH_PIN1) | \ - PIN_PUPDR_FLOATING(GPIOH_PIN2) | \ - PIN_PUPDR_FLOATING(GPIOH_PIN3) | \ - PIN_PUPDR_FLOATING(GPIOH_PIN4) | \ - PIN_PUPDR_FLOATING(GPIOH_PIN5) | \ - PIN_PUPDR_FLOATING(GPIOH_PIN6) | \ - PIN_PUPDR_FLOATING(GPIOH_PIN7) | \ - PIN_PUPDR_FLOATING(GPIOH_PIN8) | \ - PIN_PUPDR_FLOATING(GPIOH_PIN9) | \ - PIN_PUPDR_FLOATING(GPIOH_PIN10) | \ - PIN_PUPDR_FLOATING(GPIOH_PIN11) | \ - PIN_PUPDR_FLOATING(GPIOH_PIN12) | \ - PIN_PUPDR_FLOATING(GPIOH_PIN13) | \ - PIN_PUPDR_FLOATING(GPIOH_PIN14) | \ - PIN_PUPDR_FLOATING(GPIOH_PIN15)) -#define VAL_GPIOH_ODR (PIN_ODR_LOW(GPIOH_PIN0) | \ - PIN_ODR_LOW(GPIOH_PIN1) | \ - PIN_ODR_LOW(GPIOH_PIN2) | \ - PIN_ODR_LOW(GPIOH_PIN3) | \ - PIN_ODR_LOW(GPIOH_PIN4) | \ - PIN_ODR_LOW(GPIOH_PIN5) | \ - PIN_ODR_LOW(GPIOH_PIN6) | \ - PIN_ODR_LOW(GPIOH_PIN7) | \ - PIN_ODR_LOW(GPIOH_PIN8) | \ - PIN_ODR_LOW(GPIOH_PIN9) | \ - PIN_ODR_LOW(GPIOH_PIN10) | \ - PIN_ODR_LOW(GPIOH_PIN11) | \ - PIN_ODR_LOW(GPIOH_PIN12) | \ - PIN_ODR_LOW(GPIOH_PIN13) | \ - PIN_ODR_LOW(GPIOH_PIN14) | \ - PIN_ODR_LOW(GPIOH_PIN15)) -#define VAL_GPIOH_AFRL (PIN_AFIO_AF(GPIOH_PIN0, 0U) | \ - PIN_AFIO_AF(GPIOH_PIN1, 0U) | \ - PIN_AFIO_AF(GPIOH_PIN2, 0U) | \ - PIN_AFIO_AF(GPIOH_PIN3, 0U) | \ - PIN_AFIO_AF(GPIOH_PIN4, 0U) | \ - PIN_AFIO_AF(GPIOH_PIN5, 0U) | \ - PIN_AFIO_AF(GPIOH_PIN6, 0U) | \ - PIN_AFIO_AF(GPIOH_PIN7, 0U)) -#define VAL_GPIOH_AFRH (PIN_AFIO_AF(GPIOH_PIN8, 0U) | \ - PIN_AFIO_AF(GPIOH_PIN9, 0U) | \ - PIN_AFIO_AF(GPIOH_PIN10, 0U) | \ - PIN_AFIO_AF(GPIOH_PIN11, 0U) | \ - PIN_AFIO_AF(GPIOH_PIN12, 0U) | \ - PIN_AFIO_AF(GPIOH_PIN13, 0U) | \ - PIN_AFIO_AF(GPIOH_PIN14, 0U) | \ - PIN_AFIO_AF(GPIOH_PIN15, 0U)) -#define VAL_GPIOH_ASCR (PIN_ASCR_DISABLED(GPIOH_PIN0) | \ - PIN_ASCR_DISABLED(GPIOH_PIN1) | \ - PIN_ASCR_DISABLED(GPIOH_PIN2) | \ - PIN_ASCR_DISABLED(GPIOH_PIN3) | \ - PIN_ASCR_DISABLED(GPIOH_PIN4) | \ - PIN_ASCR_DISABLED(GPIOH_PIN5) | \ - PIN_ASCR_DISABLED(GPIOH_PIN6) | \ - PIN_ASCR_DISABLED(GPIOH_PIN7) | \ - PIN_ASCR_DISABLED(GPIOH_PIN8) | \ - PIN_ASCR_DISABLED(GPIOH_PIN9) | \ - PIN_ASCR_DISABLED(GPIOH_PIN10) | \ - PIN_ASCR_DISABLED(GPIOH_PIN11) | \ - PIN_ASCR_DISABLED(GPIOH_PIN12) | \ - PIN_ASCR_DISABLED(GPIOH_PIN13) | \ - PIN_ASCR_DISABLED(GPIOH_PIN14) | \ - PIN_ASCR_DISABLED(GPIOH_PIN15)) -#define VAL_GPIOH_LOCKR (PIN_LOCKR_DISABLED(GPIOH_PIN0) | \ - PIN_LOCKR_DISABLED(GPIOH_PIN1) | \ - PIN_LOCKR_DISABLED(GPIOH_PIN2) | \ - PIN_LOCKR_DISABLED(GPIOH_PIN3) | \ - PIN_LOCKR_DISABLED(GPIOH_PIN4) | \ - PIN_LOCKR_DISABLED(GPIOH_PIN5) | \ - PIN_LOCKR_DISABLED(GPIOH_PIN6) | \ - PIN_LOCKR_DISABLED(GPIOH_PIN7) | \ - PIN_LOCKR_DISABLED(GPIOH_PIN8) | \ - PIN_LOCKR_DISABLED(GPIOH_PIN9) | \ - PIN_LOCKR_DISABLED(GPIOH_PIN10) | \ - PIN_LOCKR_DISABLED(GPIOH_PIN11) | \ - PIN_LOCKR_DISABLED(GPIOH_PIN12) | \ - PIN_LOCKR_DISABLED(GPIOH_PIN13) | \ - PIN_LOCKR_DISABLED(GPIOH_PIN14) | \ - PIN_LOCKR_DISABLED(GPIOH_PIN15)) - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if !defined(_FROM_ASM_) -#ifdef __cplusplus -extern "C" { -#endif - void boardInit(void); -#ifdef __cplusplus -} -#endif -#endif /* _FROM_ASM_ */ - -#endif /* BOARD_H */ +/* + ChibiOS - Copyright (C) 2006..2020 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. +*/ + +/* + * This file has been automatically generated using ChibiStudio board + * generator plugin. Do not edit manually. + */ + +#ifndef BOARD_H +#define BOARD_H + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/* + * Setup for STMicroelectronics STM32 Nucleo144-L496ZG board. + */ + +/* + * Board identifier. + */ +#define BOARD_ST_NUCLEO144_L496ZG +#define BOARD_NAME "STMicroelectronics STM32 Nucleo144-L496ZG" + +/* + * Board oscillators-related settings. + * NOTE: LSE not fitted. + * NOTE: HSE not fitted. + */ +#if !defined(STM32_LSECLK) +#define STM32_LSECLK 0U +#endif + +#define STM32_LSEDRV (3U << 3U) + +#if !defined(STM32_HSECLK) +#define STM32_HSECLK 0U +#endif + +/* + * Board voltages. + * Required for performance limits calculation. + */ +#define STM32_VDD 300U + +/* + * MCU type as defined in the ST header. + */ +#define STM32L496xx + +/* + * IO pins assignments. + */ +#define GPIOA_PIN0 0U +#define GPIOA_PIN1 1U +#define GPIOA_PIN2 2U +#define GPIOA_PIN3 3U +#define GPIOA_PIN4 4U +#define GPIOA_PIN5 5U +#define GPIOA_PIN6 6U +#define GPIOA_PIN7 7U +#define GPIOA_USB_SOF 8U +#define GPIOA_USB_VBUS 9U +#define GPIOA_USB_ID 10U +#define GPIOA_USB_DM 11U +#define GPIOA_USB_DP 12U +#define GPIOA_SWDIO 13U +#define GPIOA_SWCLK 14U +#define GPIOA_PIN15 15U + +#define GPIOB_PIN0 0U +#define GPIOB_PIN1 1U +#define GPIOB_PIN2 2U +#define GPIOB_SWO 3U +#define GPIOB_PIN4 4U +#define GPIOB_PIN5 5U +#define GPIOB_PIN6 6U +#define GPIOB_LED2 7U +#define GPIOB_LED_BLUE 7U +#define GPIOB_PIN8 8U +#define GPIOB_PIN9 9U +#define GPIOB_PIN10 10U +#define GPIOB_PIN11 11U +#define GPIOB_PIN12 12U +#define GPIOB_PIN13 13U +#define GPIOB_LED3 14U +#define GPIOB_LED_RED 14U +#define GPIOB_PIN15 15U + +#define GPIOC_PIN0 0U +#define GPIOC_PIN1 1U +#define GPIOC_PIN2 2U +#define GPIOC_PIN3 3U +#define GPIOC_PIN4 4U +#define GPIOC_PIN5 5U +#define GPIOC_PIN6 6U +#define GPIOC_LED1 7U +#define GPIOC_LED_GREEN 7U +#define GPIOC_PIN8 8U +#define GPIOC_PIN9 9U +#define GPIOC_PIN10 10U +#define GPIOC_PIN11 11U +#define GPIOC_PIN12 12U +#define GPIOC_BUTTON 13U +#define GPIOC_PIN14 14U +#define GPIOC_PIN15 15U + +#define GPIOD_PIN0 0U +#define GPIOD_PIN1 1U +#define GPIOD_PIN2 2U +#define GPIOD_PIN3 3U +#define GPIOD_PIN4 4U +#define GPIOD_PIN5 5U +#define GPIOD_PIN6 6U +#define GPIOD_PIN7 7U +#define GPIOD_PIN8 8U +#define GPIOD_PIN9 9U +#define GPIOD_PIN10 10U +#define GPIOD_PIN11 11U +#define GPIOD_PIN12 12U +#define GPIOD_PIN13 13U +#define GPIOD_PIN14 14U +#define GPIOD_PIN15 15U + +#define GPIOE_PIN0 0U +#define GPIOE_PIN1 1U +#define GPIOE_PIN2 2U +#define GPIOE_PIN3 3U +#define GPIOE_PIN4 4U +#define GPIOE_PIN5 5U +#define GPIOE_PIN6 6U +#define GPIOE_PIN7 7U +#define GPIOE_PIN8 8U +#define GPIOE_PIN9 9U +#define GPIOE_PIN10 10U +#define GPIOE_PIN11 11U +#define GPIOE_PIN12 12U +#define GPIOE_PIN13 13U +#define GPIOE_PIN14 14U +#define GPIOE_PIN15 15U + +#define GPIOF_PIN0 0U +#define GPIOF_PIN1 1U +#define GPIOF_PIN2 2U +#define GPIOF_PIN3 3U +#define GPIOF_PIN4 4U +#define GPIOF_PIN5 5U +#define GPIOF_PIN6 6U +#define GPIOF_PIN7 7U +#define GPIOF_PIN8 8U +#define GPIOF_PIN9 9U +#define GPIOF_PIN10 10U +#define GPIOF_PIN11 11U +#define GPIOF_PIN12 12U +#define GPIOF_PIN13 13U +#define GPIOF_PIN14 14U +#define GPIOF_PIN15 15U + +#define GPIOG_PIN0 0U +#define GPIOG_PIN1 1U +#define GPIOG_PIN2 2U +#define GPIOG_PIN3 3U +#define GPIOG_PIN4 4U +#define GPIOG_USB_OVER_CURRENT 5U +#define GPIOG_USB_POWER_SWITCH_ON 6U +#define GPIOG_LPUART1_TX 7U +#define GPIOG_LPUART1_RX 8U +#define GPIOG_PIN9 9U +#define GPIOG_PIN10 10U +#define GPIOG_PIN11 11U +#define GPIOG_PIN12 12U +#define GPIOG_PIN13 13U +#define GPIOG_PIN14 14U +#define GPIOG_PIN15 15U + +#define GPIOH_PIN0 0U +#define GPIOH_PIN1 1U +#define GPIOH_PIN2 2U +#define GPIOH_PIN3 3U +#define GPIOH_PIN4 4U +#define GPIOH_PIN5 5U +#define GPIOH_PIN6 6U +#define GPIOH_PIN7 7U +#define GPIOH_PIN8 8U +#define GPIOH_PIN9 9U +#define GPIOH_PIN10 10U +#define GPIOH_PIN11 11U +#define GPIOH_PIN12 12U +#define GPIOH_PIN13 13U +#define GPIOH_PIN14 14U +#define GPIOH_PIN15 15U + +#define GPIOI_PIN0 0U +#define GPIOI_PIN1 1U +#define GPIOI_PIN2 2U +#define GPIOI_PIN3 3U +#define GPIOI_PIN4 4U +#define GPIOI_PIN5 5U +#define GPIOI_PIN6 6U +#define GPIOI_PIN7 7U +#define GPIOI_PIN8 8U +#define GPIOI_PIN9 9U +#define GPIOI_PIN10 10U +#define GPIOI_PIN11 11U +#define GPIOI_PIN12 12U +#define GPIOI_PIN13 13U +#define GPIOI_PIN14 14U +#define GPIOI_PIN15 15U + +/* + * IO lines assignments. + */ +#define LINE_USB_SOF PAL_LINE(GPIOA, 8U) +#define LINE_USB_VBUS PAL_LINE(GPIOA, 9U) +#define LINE_USB_ID PAL_LINE(GPIOA, 10U) +#define LINE_USB_DM PAL_LINE(GPIOA, 11U) +#define LINE_USB_DP PAL_LINE(GPIOA, 12U) +#define LINE_SWDIO PAL_LINE(GPIOA, 13U) +#define LINE_SWCLK PAL_LINE(GPIOA, 14U) +#define LINE_SWO PAL_LINE(GPIOB, 3U) +#define LINE_LED2 PAL_LINE(GPIOB, 7U) +#define LINE_LED_BLUE PAL_LINE(GPIOB, 7U) +#define LINE_LED3 PAL_LINE(GPIOB, 14U) +#define LINE_LED_RED PAL_LINE(GPIOB, 14U) +#define LINE_LED1 PAL_LINE(GPIOC, 7U) +#define LINE_LED_GREEN PAL_LINE(GPIOC, 7U) +#define LINE_BUTTON PAL_LINE(GPIOC, 13U) +#define LINE_USB_OVER_CURRENT PAL_LINE(GPIOG, 5U) +#define LINE_USB_POWER_SWITCH_ON PAL_LINE(GPIOG, 6U) +#define LINE_LPUART1_TX PAL_LINE(GPIOG, 7U) +#define LINE_LPUART1_RX PAL_LINE(GPIOG, 8U) + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/* + * I/O ports initial setup, this configuration is established soon after reset + * in the initialization code. + * Please refer to the STM32 Reference Manual for details. + */ +#define PIN_MODE_INPUT(n) (0U << ((n) * 2U)) +#define PIN_MODE_OUTPUT(n) (1U << ((n) * 2U)) +#define PIN_MODE_ALTERNATE(n) (2U << ((n) * 2U)) +#define PIN_MODE_ANALOG(n) (3U << ((n) * 2U)) +#define PIN_ODR_LOW(n) (0U << (n)) +#define PIN_ODR_HIGH(n) (1U << (n)) +#define PIN_OTYPE_PUSHPULL(n) (0U << (n)) +#define PIN_OTYPE_OPENDRAIN(n) (1U << (n)) +#define PIN_OSPEED_VERYLOW(n) (0U << ((n) * 2U)) +#define PIN_OSPEED_LOW(n) (1U << ((n) * 2U)) +#define PIN_OSPEED_MEDIUM(n) (2U << ((n) * 2U)) +#define PIN_OSPEED_HIGH(n) (3U << ((n) * 2U)) +#define PIN_PUPDR_FLOATING(n) (0U << ((n) * 2U)) +#define PIN_PUPDR_PULLUP(n) (1U << ((n) * 2U)) +#define PIN_PUPDR_PULLDOWN(n) (2U << ((n) * 2U)) +#define PIN_AFIO_AF(n, v) ((v) << (((n) % 8U) * 4U)) +#define PIN_ASCR_DISABLED(n) (0U << (n)) +#define PIN_ASCR_ENABLED(n) (1U << (n)) +#define PIN_LOCKR_DISABLED(n) (0U << (n)) +#define PIN_LOCKR_ENABLED(n) (1U << (n)) + +/* + * GPIOA setup: + * + * PA0 - PIN0 (analog). + * PA1 - PIN1 (analog). + * PA2 - PIN2 (analog). + * PA3 - PIN3 (analog). + * PA4 - PIN4 (analog). + * PA5 - PIN5 (analog). + * PA6 - PIN6 (analog). + * PA7 - PIN7 (analog). + * PA8 - USB_SOF (alternate 10). + * PA9 - USB_VBUS (analog). + * PA10 - USB_ID (alternate 10). + * PA11 - USB_DM (alternate 10). + * PA12 - USB_DP (alternate 10). + * PA13 - SWDIO (alternate 0). + * PA14 - SWCLK (alternate 0). + * PA15 - PIN15 (analog). + */ +#define VAL_GPIOA_MODER (PIN_MODE_ANALOG(GPIOA_PIN0) | \ + PIN_MODE_ANALOG(GPIOA_PIN1) | \ + PIN_MODE_ANALOG(GPIOA_PIN2) | \ + PIN_MODE_ANALOG(GPIOA_PIN3) | \ + PIN_MODE_ANALOG(GPIOA_PIN4) | \ + PIN_MODE_ANALOG(GPIOA_PIN5) | \ + PIN_MODE_ANALOG(GPIOA_PIN6) | \ + PIN_MODE_ANALOG(GPIOA_PIN7) | \ + PIN_MODE_ALTERNATE(GPIOA_USB_SOF) | \ + PIN_MODE_ANALOG(GPIOA_USB_VBUS) | \ + PIN_MODE_ALTERNATE(GPIOA_USB_ID) | \ + PIN_MODE_ALTERNATE(GPIOA_USB_DM) | \ + PIN_MODE_ALTERNATE(GPIOA_USB_DP) | \ + PIN_MODE_ALTERNATE(GPIOA_SWDIO) | \ + PIN_MODE_ALTERNATE(GPIOA_SWCLK) | \ + PIN_MODE_ANALOG(GPIOA_PIN15)) +#define VAL_GPIOA_OTYPER (PIN_OTYPE_PUSHPULL(GPIOA_PIN0) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN1) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN7) | \ + PIN_OTYPE_PUSHPULL(GPIOA_USB_SOF) | \ + PIN_OTYPE_PUSHPULL(GPIOA_USB_VBUS) | \ + PIN_OTYPE_PUSHPULL(GPIOA_USB_ID) | \ + PIN_OTYPE_PUSHPULL(GPIOA_USB_DM) | \ + PIN_OTYPE_PUSHPULL(GPIOA_USB_DP) | \ + PIN_OTYPE_PUSHPULL(GPIOA_SWDIO) | \ + PIN_OTYPE_PUSHPULL(GPIOA_SWCLK) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN15)) +#define VAL_GPIOA_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOA_PIN0) | \ + PIN_OSPEED_VERYLOW(GPIOA_PIN1) | \ + PIN_OSPEED_VERYLOW(GPIOA_PIN2) | \ + PIN_OSPEED_VERYLOW(GPIOA_PIN3) | \ + PIN_OSPEED_VERYLOW(GPIOA_PIN4) | \ + PIN_OSPEED_VERYLOW(GPIOA_PIN5) | \ + PIN_OSPEED_VERYLOW(GPIOA_PIN6) | \ + PIN_OSPEED_VERYLOW(GPIOA_PIN7) | \ + PIN_OSPEED_HIGH(GPIOA_USB_SOF) | \ + PIN_OSPEED_VERYLOW(GPIOA_USB_VBUS) | \ + PIN_OSPEED_HIGH(GPIOA_USB_ID) | \ + PIN_OSPEED_HIGH(GPIOA_USB_DM) | \ + PIN_OSPEED_HIGH(GPIOA_USB_DP) | \ + PIN_OSPEED_HIGH(GPIOA_SWDIO) | \ + PIN_OSPEED_HIGH(GPIOA_SWCLK) | \ + PIN_OSPEED_VERYLOW(GPIOA_PIN15)) +#define VAL_GPIOA_PUPDR (PIN_PUPDR_FLOATING(GPIOA_PIN0) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN1) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN2) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN3) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN4) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN5) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN6) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN7) | \ + PIN_PUPDR_FLOATING(GPIOA_USB_SOF) | \ + PIN_PUPDR_FLOATING(GPIOA_USB_VBUS) | \ + PIN_PUPDR_FLOATING(GPIOA_USB_ID) | \ + PIN_PUPDR_FLOATING(GPIOA_USB_DM) | \ + PIN_PUPDR_FLOATING(GPIOA_USB_DP) | \ + PIN_PUPDR_PULLDOWN(GPIOA_SWDIO) | \ + PIN_PUPDR_PULLUP(GPIOA_SWCLK) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN15)) +#define VAL_GPIOA_ODR (PIN_ODR_LOW(GPIOA_PIN0) | \ + PIN_ODR_LOW(GPIOA_PIN1) | \ + PIN_ODR_LOW(GPIOA_PIN2) | \ + PIN_ODR_LOW(GPIOA_PIN3) | \ + PIN_ODR_LOW(GPIOA_PIN4) | \ + PIN_ODR_LOW(GPIOA_PIN5) | \ + PIN_ODR_LOW(GPIOA_PIN6) | \ + PIN_ODR_LOW(GPIOA_PIN7) | \ + PIN_ODR_LOW(GPIOA_USB_SOF) | \ + PIN_ODR_LOW(GPIOA_USB_VBUS) | \ + PIN_ODR_LOW(GPIOA_USB_ID) | \ + PIN_ODR_LOW(GPIOA_USB_DM) | \ + PIN_ODR_LOW(GPIOA_USB_DP) | \ + PIN_ODR_LOW(GPIOA_SWDIO) | \ + PIN_ODR_LOW(GPIOA_SWCLK) | \ + PIN_ODR_LOW(GPIOA_PIN15)) +#define VAL_GPIOA_AFRL (PIN_AFIO_AF(GPIOA_PIN0, 0U) | \ + PIN_AFIO_AF(GPIOA_PIN1, 0U) | \ + PIN_AFIO_AF(GPIOA_PIN2, 0U) | \ + PIN_AFIO_AF(GPIOA_PIN3, 0U) | \ + PIN_AFIO_AF(GPIOA_PIN4, 0U) | \ + PIN_AFIO_AF(GPIOA_PIN5, 0U) | \ + PIN_AFIO_AF(GPIOA_PIN6, 0U) | \ + PIN_AFIO_AF(GPIOA_PIN7, 0U)) +#define VAL_GPIOA_AFRH (PIN_AFIO_AF(GPIOA_USB_SOF, 10U) | \ + PIN_AFIO_AF(GPIOA_USB_VBUS, 0U) | \ + PIN_AFIO_AF(GPIOA_USB_ID, 10U) | \ + PIN_AFIO_AF(GPIOA_USB_DM, 10U) | \ + PIN_AFIO_AF(GPIOA_USB_DP, 10U) | \ + PIN_AFIO_AF(GPIOA_SWDIO, 0U) | \ + PIN_AFIO_AF(GPIOA_SWCLK, 0U) | \ + PIN_AFIO_AF(GPIOA_PIN15, 0U)) +#define VAL_GPIOA_ASCR (PIN_ASCR_DISABLED(GPIOA_PIN0) | \ + PIN_ASCR_DISABLED(GPIOA_PIN1) | \ + PIN_ASCR_DISABLED(GPIOA_PIN2) | \ + PIN_ASCR_DISABLED(GPIOA_PIN3) | \ + PIN_ASCR_DISABLED(GPIOA_PIN4) | \ + PIN_ASCR_DISABLED(GPIOA_PIN5) | \ + PIN_ASCR_DISABLED(GPIOA_PIN6) | \ + PIN_ASCR_DISABLED(GPIOA_PIN7) | \ + PIN_ASCR_DISABLED(GPIOA_USB_SOF) | \ + PIN_ASCR_DISABLED(GPIOA_USB_VBUS) | \ + PIN_ASCR_DISABLED(GPIOA_USB_ID) | \ + PIN_ASCR_DISABLED(GPIOA_USB_DM) | \ + PIN_ASCR_DISABLED(GPIOA_USB_DP) | \ + PIN_ASCR_DISABLED(GPIOA_SWDIO) | \ + PIN_ASCR_DISABLED(GPIOA_SWCLK) | \ + PIN_ASCR_DISABLED(GPIOA_PIN15)) +#define VAL_GPIOA_LOCKR (PIN_LOCKR_DISABLED(GPIOA_PIN0) | \ + PIN_LOCKR_DISABLED(GPIOA_PIN1) | \ + PIN_LOCKR_DISABLED(GPIOA_PIN2) | \ + PIN_LOCKR_DISABLED(GPIOA_PIN3) | \ + PIN_LOCKR_DISABLED(GPIOA_PIN4) | \ + PIN_LOCKR_DISABLED(GPIOA_PIN5) | \ + PIN_LOCKR_DISABLED(GPIOA_PIN6) | \ + PIN_LOCKR_DISABLED(GPIOA_PIN7) | \ + PIN_LOCKR_DISABLED(GPIOA_USB_SOF) | \ + PIN_LOCKR_DISABLED(GPIOA_USB_VBUS) | \ + PIN_LOCKR_DISABLED(GPIOA_USB_ID) | \ + PIN_LOCKR_DISABLED(GPIOA_USB_DM) | \ + PIN_LOCKR_DISABLED(GPIOA_USB_DP) | \ + PIN_LOCKR_DISABLED(GPIOA_SWDIO) | \ + PIN_LOCKR_DISABLED(GPIOA_SWCLK) | \ + PIN_LOCKR_DISABLED(GPIOA_PIN15)) + +/* + * GPIOB setup: + * + * PB0 - PIN0 (analog). + * PB1 - PIN1 (analog). + * PB2 - PIN2 (analog). + * PB3 - SWO (alternate 0). + * PB4 - PIN4 (analog). + * PB5 - PIN5 (analog). + * PB6 - PIN6 (analog). + * PB7 - LED2 LED_BLUE (output pushpull maximum). + * PB8 - PIN8 (analog). + * PB9 - PIN9 (analog). + * PB10 - PIN10 (analog). + * PB11 - PIN11 (analog). + * PB12 - PIN12 (analog). + * PB13 - PIN13 (analog). + * PB14 - LED3 LED_RED (output pushpull maximum). + * PB15 - PIN15 (analog). + */ +#define VAL_GPIOB_MODER (PIN_MODE_ANALOG(GPIOB_PIN0) | \ + PIN_MODE_ANALOG(GPIOB_PIN1) | \ + PIN_MODE_ANALOG(GPIOB_PIN2) | \ + PIN_MODE_ALTERNATE(GPIOB_SWO) | \ + PIN_MODE_ANALOG(GPIOB_PIN4) | \ + PIN_MODE_ANALOG(GPIOB_PIN5) | \ + PIN_MODE_ANALOG(GPIOB_PIN6) | \ + PIN_MODE_OUTPUT(GPIOB_LED2) | \ + PIN_MODE_ANALOG(GPIOB_PIN8) | \ + PIN_MODE_ANALOG(GPIOB_PIN9) | \ + PIN_MODE_ANALOG(GPIOB_PIN10) | \ + PIN_MODE_ANALOG(GPIOB_PIN11) | \ + PIN_MODE_ANALOG(GPIOB_PIN12) | \ + PIN_MODE_ANALOG(GPIOB_PIN13) | \ + PIN_MODE_OUTPUT(GPIOB_LED3) | \ + PIN_MODE_ANALOG(GPIOB_PIN15)) +#define VAL_GPIOB_OTYPER (PIN_OTYPE_PUSHPULL(GPIOB_PIN0) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN1) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOB_SWO) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOB_LED2) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN13) | \ + PIN_OTYPE_PUSHPULL(GPIOB_LED3) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN15)) +#define VAL_GPIOB_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOB_PIN0) | \ + PIN_OSPEED_VERYLOW(GPIOB_PIN1) | \ + PIN_OSPEED_VERYLOW(GPIOB_PIN2) | \ + PIN_OSPEED_HIGH(GPIOB_SWO) | \ + PIN_OSPEED_VERYLOW(GPIOB_PIN4) | \ + PIN_OSPEED_VERYLOW(GPIOB_PIN5) | \ + PIN_OSPEED_VERYLOW(GPIOB_PIN6) | \ + PIN_OSPEED_HIGH(GPIOB_LED2) | \ + PIN_OSPEED_VERYLOW(GPIOB_PIN8) | \ + PIN_OSPEED_VERYLOW(GPIOB_PIN9) | \ + PIN_OSPEED_VERYLOW(GPIOB_PIN10) | \ + PIN_OSPEED_VERYLOW(GPIOB_PIN11) | \ + PIN_OSPEED_VERYLOW(GPIOB_PIN12) | \ + PIN_OSPEED_VERYLOW(GPIOB_PIN13) | \ + PIN_OSPEED_HIGH(GPIOB_LED3) | \ + PIN_OSPEED_VERYLOW(GPIOB_PIN15)) +#define VAL_GPIOB_PUPDR (PIN_PUPDR_FLOATING(GPIOB_PIN0) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN1) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN2) | \ + PIN_PUPDR_FLOATING(GPIOB_SWO) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN4) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN5) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN6) | \ + PIN_PUPDR_FLOATING(GPIOB_LED2) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN8) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN9) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN10) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN11) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN12) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN13) | \ + PIN_PUPDR_FLOATING(GPIOB_LED3) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN15)) +#define VAL_GPIOB_ODR (PIN_ODR_LOW(GPIOB_PIN0) | \ + PIN_ODR_LOW(GPIOB_PIN1) | \ + PIN_ODR_LOW(GPIOB_PIN2) | \ + PIN_ODR_LOW(GPIOB_SWO) | \ + PIN_ODR_LOW(GPIOB_PIN4) | \ + PIN_ODR_LOW(GPIOB_PIN5) | \ + PIN_ODR_LOW(GPIOB_PIN6) | \ + PIN_ODR_LOW(GPIOB_LED2) | \ + PIN_ODR_LOW(GPIOB_PIN8) | \ + PIN_ODR_LOW(GPIOB_PIN9) | \ + PIN_ODR_LOW(GPIOB_PIN10) | \ + PIN_ODR_LOW(GPIOB_PIN11) | \ + PIN_ODR_LOW(GPIOB_PIN12) | \ + PIN_ODR_LOW(GPIOB_PIN13) | \ + PIN_ODR_LOW(GPIOB_LED3) | \ + PIN_ODR_LOW(GPIOB_PIN15)) +#define VAL_GPIOB_AFRL (PIN_AFIO_AF(GPIOB_PIN0, 0U) | \ + PIN_AFIO_AF(GPIOB_PIN1, 0U) | \ + PIN_AFIO_AF(GPIOB_PIN2, 0U) | \ + PIN_AFIO_AF(GPIOB_SWO, 0U) | \ + PIN_AFIO_AF(GPIOB_PIN4, 0U) | \ + PIN_AFIO_AF(GPIOB_PIN5, 0U) | \ + PIN_AFIO_AF(GPIOB_PIN6, 0U) | \ + PIN_AFIO_AF(GPIOB_LED2, 0U)) +#define VAL_GPIOB_AFRH (PIN_AFIO_AF(GPIOB_PIN8, 0U) | \ + PIN_AFIO_AF(GPIOB_PIN9, 0U) | \ + PIN_AFIO_AF(GPIOB_PIN10, 0U) | \ + PIN_AFIO_AF(GPIOB_PIN11, 0U) | \ + PIN_AFIO_AF(GPIOB_PIN12, 0U) | \ + PIN_AFIO_AF(GPIOB_PIN13, 0U) | \ + PIN_AFIO_AF(GPIOB_LED3, 0U) | \ + PIN_AFIO_AF(GPIOB_PIN15, 0U)) +#define VAL_GPIOB_ASCR (PIN_ASCR_DISABLED(GPIOB_PIN0) | \ + PIN_ASCR_DISABLED(GPIOB_PIN1) | \ + PIN_ASCR_DISABLED(GPIOB_PIN2) | \ + PIN_ASCR_DISABLED(GPIOB_SWO) | \ + PIN_ASCR_DISABLED(GPIOB_PIN4) | \ + PIN_ASCR_DISABLED(GPIOB_PIN5) | \ + PIN_ASCR_DISABLED(GPIOB_PIN6) | \ + PIN_ASCR_DISABLED(GPIOB_LED2) | \ + PIN_ASCR_DISABLED(GPIOB_PIN8) | \ + PIN_ASCR_DISABLED(GPIOB_PIN9) | \ + PIN_ASCR_DISABLED(GPIOB_PIN10) | \ + PIN_ASCR_DISABLED(GPIOB_PIN11) | \ + PIN_ASCR_DISABLED(GPIOB_PIN12) | \ + PIN_ASCR_DISABLED(GPIOB_PIN13) | \ + PIN_ASCR_DISABLED(GPIOB_LED3) | \ + PIN_ASCR_DISABLED(GPIOB_PIN15)) +#define VAL_GPIOB_LOCKR (PIN_LOCKR_DISABLED(GPIOB_PIN0) | \ + PIN_LOCKR_DISABLED(GPIOB_PIN1) | \ + PIN_LOCKR_DISABLED(GPIOB_PIN2) | \ + PIN_LOCKR_DISABLED(GPIOB_SWO) | \ + PIN_LOCKR_DISABLED(GPIOB_PIN4) | \ + PIN_LOCKR_DISABLED(GPIOB_PIN5) | \ + PIN_LOCKR_DISABLED(GPIOB_PIN6) | \ + PIN_LOCKR_DISABLED(GPIOB_LED2) | \ + PIN_LOCKR_DISABLED(GPIOB_PIN8) | \ + PIN_LOCKR_DISABLED(GPIOB_PIN9) | \ + PIN_LOCKR_DISABLED(GPIOB_PIN10) | \ + PIN_LOCKR_DISABLED(GPIOB_PIN11) | \ + PIN_LOCKR_DISABLED(GPIOB_PIN12) | \ + PIN_LOCKR_DISABLED(GPIOB_PIN13) | \ + PIN_LOCKR_DISABLED(GPIOB_LED3) | \ + PIN_LOCKR_DISABLED(GPIOB_PIN15)) + +/* + * GPIOC setup: + * + * PC0 - PIN0 (analog). + * PC1 - PIN1 (analog). + * PC2 - PIN2 (analog). + * PC3 - PIN3 (analog). + * PC4 - PIN4 (analog). + * PC5 - PIN5 (analog). + * PC6 - PIN6 (analog). + * PC7 - LED1 LED_GREEN (output pushpull maximum). + * PC8 - PIN8 (analog). + * PC9 - PIN9 (analog). + * PC10 - PIN10 (analog). + * PC11 - PIN11 (analog). + * PC12 - PIN12 (analog). + * PC13 - BUTTON (input floating). + * PC14 - PIN14 (analog). + * PC15 - PIN15 (analog). + */ +#define VAL_GPIOC_MODER (PIN_MODE_ANALOG(GPIOC_PIN0) | \ + PIN_MODE_ANALOG(GPIOC_PIN1) | \ + PIN_MODE_ANALOG(GPIOC_PIN2) | \ + PIN_MODE_ANALOG(GPIOC_PIN3) | \ + PIN_MODE_ANALOG(GPIOC_PIN4) | \ + PIN_MODE_ANALOG(GPIOC_PIN5) | \ + PIN_MODE_ANALOG(GPIOC_PIN6) | \ + PIN_MODE_OUTPUT(GPIOC_LED1) | \ + PIN_MODE_ANALOG(GPIOC_PIN8) | \ + PIN_MODE_ANALOG(GPIOC_PIN9) | \ + PIN_MODE_ANALOG(GPIOC_PIN10) | \ + PIN_MODE_ANALOG(GPIOC_PIN11) | \ + PIN_MODE_ANALOG(GPIOC_PIN12) | \ + PIN_MODE_INPUT(GPIOC_BUTTON) | \ + PIN_MODE_ANALOG(GPIOC_PIN14) | \ + PIN_MODE_ANALOG(GPIOC_PIN15)) +#define VAL_GPIOC_OTYPER (PIN_OTYPE_PUSHPULL(GPIOC_PIN0) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN1) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOC_LED1) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOC_BUTTON) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN14) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN15)) +#define VAL_GPIOC_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOC_PIN0) | \ + PIN_OSPEED_VERYLOW(GPIOC_PIN1) | \ + PIN_OSPEED_VERYLOW(GPIOC_PIN2) | \ + PIN_OSPEED_VERYLOW(GPIOC_PIN3) | \ + PIN_OSPEED_VERYLOW(GPIOC_PIN4) | \ + PIN_OSPEED_VERYLOW(GPIOC_PIN5) | \ + PIN_OSPEED_VERYLOW(GPIOC_PIN6) | \ + PIN_OSPEED_HIGH(GPIOC_LED1) | \ + PIN_OSPEED_VERYLOW(GPIOC_PIN8) | \ + PIN_OSPEED_VERYLOW(GPIOC_PIN9) | \ + PIN_OSPEED_VERYLOW(GPIOC_PIN10) | \ + PIN_OSPEED_VERYLOW(GPIOC_PIN11) | \ + PIN_OSPEED_VERYLOW(GPIOC_PIN12) | \ + PIN_OSPEED_VERYLOW(GPIOC_BUTTON) | \ + PIN_OSPEED_VERYLOW(GPIOC_PIN14) | \ + PIN_OSPEED_VERYLOW(GPIOC_PIN15)) +#define VAL_GPIOC_PUPDR (PIN_PUPDR_FLOATING(GPIOC_PIN0) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN1) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN2) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN3) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN4) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN5) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN6) | \ + PIN_PUPDR_FLOATING(GPIOC_LED1) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN8) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN9) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN10) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN11) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN12) | \ + PIN_PUPDR_FLOATING(GPIOC_BUTTON) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN14) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN15)) +#define VAL_GPIOC_ODR (PIN_ODR_LOW(GPIOC_PIN0) | \ + PIN_ODR_LOW(GPIOC_PIN1) | \ + PIN_ODR_LOW(GPIOC_PIN2) | \ + PIN_ODR_LOW(GPIOC_PIN3) | \ + PIN_ODR_LOW(GPIOC_PIN4) | \ + PIN_ODR_LOW(GPIOC_PIN5) | \ + PIN_ODR_LOW(GPIOC_PIN6) | \ + PIN_ODR_LOW(GPIOC_LED1) | \ + PIN_ODR_LOW(GPIOC_PIN8) | \ + PIN_ODR_LOW(GPIOC_PIN9) | \ + PIN_ODR_LOW(GPIOC_PIN10) | \ + PIN_ODR_LOW(GPIOC_PIN11) | \ + PIN_ODR_LOW(GPIOC_PIN12) | \ + PIN_ODR_LOW(GPIOC_BUTTON) | \ + PIN_ODR_LOW(GPIOC_PIN14) | \ + PIN_ODR_LOW(GPIOC_PIN15)) +#define VAL_GPIOC_AFRL (PIN_AFIO_AF(GPIOC_PIN0, 0U) | \ + PIN_AFIO_AF(GPIOC_PIN1, 0U) | \ + PIN_AFIO_AF(GPIOC_PIN2, 0U) | \ + PIN_AFIO_AF(GPIOC_PIN3, 0U) | \ + PIN_AFIO_AF(GPIOC_PIN4, 0U) | \ + PIN_AFIO_AF(GPIOC_PIN5, 0U) | \ + PIN_AFIO_AF(GPIOC_PIN6, 0U) | \ + PIN_AFIO_AF(GPIOC_LED1, 0U)) +#define VAL_GPIOC_AFRH (PIN_AFIO_AF(GPIOC_PIN8, 0U) | \ + PIN_AFIO_AF(GPIOC_PIN9, 0U) | \ + PIN_AFIO_AF(GPIOC_PIN10, 0U) | \ + PIN_AFIO_AF(GPIOC_PIN11, 0U) | \ + PIN_AFIO_AF(GPIOC_PIN12, 0U) | \ + PIN_AFIO_AF(GPIOC_BUTTON, 0U) | \ + PIN_AFIO_AF(GPIOC_PIN14, 0U) | \ + PIN_AFIO_AF(GPIOC_PIN15, 0U)) +#define VAL_GPIOC_ASCR (PIN_ASCR_DISABLED(GPIOC_PIN0) | \ + PIN_ASCR_DISABLED(GPIOC_PIN1) | \ + PIN_ASCR_DISABLED(GPIOC_PIN2) | \ + PIN_ASCR_DISABLED(GPIOC_PIN3) | \ + PIN_ASCR_DISABLED(GPIOC_PIN4) | \ + PIN_ASCR_DISABLED(GPIOC_PIN5) | \ + PIN_ASCR_DISABLED(GPIOC_PIN6) | \ + PIN_ASCR_DISABLED(GPIOC_LED1) | \ + PIN_ASCR_DISABLED(GPIOC_PIN8) | \ + PIN_ASCR_DISABLED(GPIOC_PIN9) | \ + PIN_ASCR_DISABLED(GPIOC_PIN10) | \ + PIN_ASCR_DISABLED(GPIOC_PIN11) | \ + PIN_ASCR_DISABLED(GPIOC_PIN12) | \ + PIN_ASCR_DISABLED(GPIOC_BUTTON) | \ + PIN_ASCR_DISABLED(GPIOC_PIN14) | \ + PIN_ASCR_DISABLED(GPIOC_PIN15)) +#define VAL_GPIOC_LOCKR (PIN_LOCKR_DISABLED(GPIOC_PIN0) | \ + PIN_LOCKR_DISABLED(GPIOC_PIN1) | \ + PIN_LOCKR_DISABLED(GPIOC_PIN2) | \ + PIN_LOCKR_DISABLED(GPIOC_PIN3) | \ + PIN_LOCKR_DISABLED(GPIOC_PIN4) | \ + PIN_LOCKR_DISABLED(GPIOC_PIN5) | \ + PIN_LOCKR_DISABLED(GPIOC_PIN6) | \ + PIN_LOCKR_DISABLED(GPIOC_LED1) | \ + PIN_LOCKR_DISABLED(GPIOC_PIN8) | \ + PIN_LOCKR_DISABLED(GPIOC_PIN9) | \ + PIN_LOCKR_DISABLED(GPIOC_PIN10) | \ + PIN_LOCKR_DISABLED(GPIOC_PIN11) | \ + PIN_LOCKR_DISABLED(GPIOC_PIN12) | \ + PIN_LOCKR_DISABLED(GPIOC_BUTTON) | \ + PIN_LOCKR_DISABLED(GPIOC_PIN14) | \ + PIN_LOCKR_DISABLED(GPIOC_PIN15)) + +/* + * GPIOD setup: + * + * PD0 - PIN0 (analog). + * PD1 - PIN1 (analog). + * PD2 - PIN2 (analog). + * PD3 - PIN3 (analog). + * PD4 - PIN4 (analog). + * PD5 - PIN5 (analog). + * PD6 - PIN6 (analog). + * PD7 - PIN7 (analog). + * PD8 - PIN8 (analog). + * PD9 - PIN9 (analog). + * PD10 - PIN10 (analog). + * PD11 - PIN11 (analog). + * PD12 - PIN12 (analog). + * PD13 - PIN13 (analog). + * PD14 - PIN14 (analog). + * PD15 - PIN15 (analog). + */ +#define VAL_GPIOD_MODER (PIN_MODE_ANALOG(GPIOD_PIN0) | \ + PIN_MODE_ANALOG(GPIOD_PIN1) | \ + PIN_MODE_ANALOG(GPIOD_PIN2) | \ + PIN_MODE_ANALOG(GPIOD_PIN3) | \ + PIN_MODE_ANALOG(GPIOD_PIN4) | \ + PIN_MODE_ANALOG(GPIOD_PIN5) | \ + PIN_MODE_ANALOG(GPIOD_PIN6) | \ + PIN_MODE_ANALOG(GPIOD_PIN7) | \ + PIN_MODE_ANALOG(GPIOD_PIN8) | \ + PIN_MODE_ANALOG(GPIOD_PIN9) | \ + PIN_MODE_ANALOG(GPIOD_PIN10) | \ + PIN_MODE_ANALOG(GPIOD_PIN11) | \ + PIN_MODE_ANALOG(GPIOD_PIN12) | \ + PIN_MODE_ANALOG(GPIOD_PIN13) | \ + PIN_MODE_ANALOG(GPIOD_PIN14) | \ + PIN_MODE_ANALOG(GPIOD_PIN15)) +#define VAL_GPIOD_OTYPER (PIN_OTYPE_PUSHPULL(GPIOD_PIN0) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN1) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN7) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN13) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN14) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN15)) +#define VAL_GPIOD_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOD_PIN0) | \ + PIN_OSPEED_VERYLOW(GPIOD_PIN1) | \ + PIN_OSPEED_VERYLOW(GPIOD_PIN2) | \ + PIN_OSPEED_VERYLOW(GPIOD_PIN3) | \ + PIN_OSPEED_VERYLOW(GPIOD_PIN4) | \ + PIN_OSPEED_VERYLOW(GPIOD_PIN5) | \ + PIN_OSPEED_VERYLOW(GPIOD_PIN6) | \ + PIN_OSPEED_VERYLOW(GPIOD_PIN7) | \ + PIN_OSPEED_VERYLOW(GPIOD_PIN8) | \ + PIN_OSPEED_VERYLOW(GPIOD_PIN9) | \ + PIN_OSPEED_VERYLOW(GPIOD_PIN10) | \ + PIN_OSPEED_VERYLOW(GPIOD_PIN11) | \ + PIN_OSPEED_VERYLOW(GPIOD_PIN12) | \ + PIN_OSPEED_VERYLOW(GPIOD_PIN13) | \ + PIN_OSPEED_VERYLOW(GPIOD_PIN14) | \ + PIN_OSPEED_VERYLOW(GPIOD_PIN15)) +#define VAL_GPIOD_PUPDR (PIN_PUPDR_FLOATING(GPIOD_PIN0) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN1) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN2) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN3) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN4) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN5) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN6) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN7) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN8) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN9) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN10) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN11) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN12) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN13) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN14) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN15)) +#define VAL_GPIOD_ODR (PIN_ODR_LOW(GPIOD_PIN0) | \ + PIN_ODR_LOW(GPIOD_PIN1) | \ + PIN_ODR_LOW(GPIOD_PIN2) | \ + PIN_ODR_LOW(GPIOD_PIN3) | \ + PIN_ODR_LOW(GPIOD_PIN4) | \ + PIN_ODR_LOW(GPIOD_PIN5) | \ + PIN_ODR_LOW(GPIOD_PIN6) | \ + PIN_ODR_LOW(GPIOD_PIN7) | \ + PIN_ODR_LOW(GPIOD_PIN8) | \ + PIN_ODR_LOW(GPIOD_PIN9) | \ + PIN_ODR_LOW(GPIOD_PIN10) | \ + PIN_ODR_LOW(GPIOD_PIN11) | \ + PIN_ODR_LOW(GPIOD_PIN12) | \ + PIN_ODR_LOW(GPIOD_PIN13) | \ + PIN_ODR_LOW(GPIOD_PIN14) | \ + PIN_ODR_LOW(GPIOD_PIN15)) +#define VAL_GPIOD_AFRL (PIN_AFIO_AF(GPIOD_PIN0, 0U) | \ + PIN_AFIO_AF(GPIOD_PIN1, 0U) | \ + PIN_AFIO_AF(GPIOD_PIN2, 0U) | \ + PIN_AFIO_AF(GPIOD_PIN3, 0U) | \ + PIN_AFIO_AF(GPIOD_PIN4, 0U) | \ + PIN_AFIO_AF(GPIOD_PIN5, 0U) | \ + PIN_AFIO_AF(GPIOD_PIN6, 0U) | \ + PIN_AFIO_AF(GPIOD_PIN7, 0U)) +#define VAL_GPIOD_AFRH (PIN_AFIO_AF(GPIOD_PIN8, 0U) | \ + PIN_AFIO_AF(GPIOD_PIN9, 0U) | \ + PIN_AFIO_AF(GPIOD_PIN10, 0U) | \ + PIN_AFIO_AF(GPIOD_PIN11, 0U) | \ + PIN_AFIO_AF(GPIOD_PIN12, 0U) | \ + PIN_AFIO_AF(GPIOD_PIN13, 0U) | \ + PIN_AFIO_AF(GPIOD_PIN14, 0U) | \ + PIN_AFIO_AF(GPIOD_PIN15, 0U)) +#define VAL_GPIOD_ASCR (PIN_ASCR_DISABLED(GPIOD_PIN0) | \ + PIN_ASCR_DISABLED(GPIOD_PIN1) | \ + PIN_ASCR_DISABLED(GPIOD_PIN2) | \ + PIN_ASCR_DISABLED(GPIOD_PIN3) | \ + PIN_ASCR_DISABLED(GPIOD_PIN4) | \ + PIN_ASCR_DISABLED(GPIOD_PIN5) | \ + PIN_ASCR_DISABLED(GPIOD_PIN6) | \ + PIN_ASCR_DISABLED(GPIOD_PIN7) | \ + PIN_ASCR_DISABLED(GPIOD_PIN8) | \ + PIN_ASCR_DISABLED(GPIOD_PIN9) | \ + PIN_ASCR_DISABLED(GPIOD_PIN10) | \ + PIN_ASCR_DISABLED(GPIOD_PIN11) | \ + PIN_ASCR_DISABLED(GPIOD_PIN12) | \ + PIN_ASCR_DISABLED(GPIOD_PIN13) | \ + PIN_ASCR_DISABLED(GPIOD_PIN14) | \ + PIN_ASCR_DISABLED(GPIOD_PIN15)) +#define VAL_GPIOD_LOCKR (PIN_LOCKR_DISABLED(GPIOD_PIN0) | \ + PIN_LOCKR_DISABLED(GPIOD_PIN1) | \ + PIN_LOCKR_DISABLED(GPIOD_PIN2) | \ + PIN_LOCKR_DISABLED(GPIOD_PIN3) | \ + PIN_LOCKR_DISABLED(GPIOD_PIN4) | \ + PIN_LOCKR_DISABLED(GPIOD_PIN5) | \ + PIN_LOCKR_DISABLED(GPIOD_PIN6) | \ + PIN_LOCKR_DISABLED(GPIOD_PIN7) | \ + PIN_LOCKR_DISABLED(GPIOD_PIN8) | \ + PIN_LOCKR_DISABLED(GPIOD_PIN9) | \ + PIN_LOCKR_DISABLED(GPIOD_PIN10) | \ + PIN_LOCKR_DISABLED(GPIOD_PIN11) | \ + PIN_LOCKR_DISABLED(GPIOD_PIN12) | \ + PIN_LOCKR_DISABLED(GPIOD_PIN13) | \ + PIN_LOCKR_DISABLED(GPIOD_PIN14) | \ + PIN_LOCKR_DISABLED(GPIOD_PIN15)) + +/* + * GPIOE setup: + * + * PE0 - PIN0 (analog). + * PE1 - PIN1 (analog). + * PE2 - PIN2 (analog). + * PE3 - PIN3 (analog). + * PE4 - PIN4 (analog). + * PE5 - PIN5 (analog). + * PE6 - PIN6 (analog). + * PE7 - PIN7 (analog). + * PE8 - PIN8 (analog). + * PE9 - PIN9 (analog). + * PE10 - PIN10 (analog). + * PE11 - PIN11 (analog). + * PE12 - PIN12 (analog). + * PE13 - PIN13 (analog). + * PE14 - PIN14 (analog). + * PE15 - PIN15 (analog). + */ +#define VAL_GPIOE_MODER (PIN_MODE_ANALOG(GPIOE_PIN0) | \ + PIN_MODE_ANALOG(GPIOE_PIN1) | \ + PIN_MODE_ANALOG(GPIOE_PIN2) | \ + PIN_MODE_ANALOG(GPIOE_PIN3) | \ + PIN_MODE_ANALOG(GPIOE_PIN4) | \ + PIN_MODE_ANALOG(GPIOE_PIN5) | \ + PIN_MODE_ANALOG(GPIOE_PIN6) | \ + PIN_MODE_ANALOG(GPIOE_PIN7) | \ + PIN_MODE_ANALOG(GPIOE_PIN8) | \ + PIN_MODE_ANALOG(GPIOE_PIN9) | \ + PIN_MODE_ANALOG(GPIOE_PIN10) | \ + PIN_MODE_ANALOG(GPIOE_PIN11) | \ + PIN_MODE_ANALOG(GPIOE_PIN12) | \ + PIN_MODE_ANALOG(GPIOE_PIN13) | \ + PIN_MODE_ANALOG(GPIOE_PIN14) | \ + PIN_MODE_ANALOG(GPIOE_PIN15)) +#define VAL_GPIOE_OTYPER (PIN_OTYPE_PUSHPULL(GPIOE_PIN0) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN1) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN7) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN13) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN14) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN15)) +#define VAL_GPIOE_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOE_PIN0) | \ + PIN_OSPEED_VERYLOW(GPIOE_PIN1) | \ + PIN_OSPEED_VERYLOW(GPIOE_PIN2) | \ + PIN_OSPEED_VERYLOW(GPIOE_PIN3) | \ + PIN_OSPEED_VERYLOW(GPIOE_PIN4) | \ + PIN_OSPEED_VERYLOW(GPIOE_PIN5) | \ + PIN_OSPEED_VERYLOW(GPIOE_PIN6) | \ + PIN_OSPEED_VERYLOW(GPIOE_PIN7) | \ + PIN_OSPEED_VERYLOW(GPIOE_PIN8) | \ + PIN_OSPEED_VERYLOW(GPIOE_PIN9) | \ + PIN_OSPEED_VERYLOW(GPIOE_PIN10) | \ + PIN_OSPEED_VERYLOW(GPIOE_PIN11) | \ + PIN_OSPEED_VERYLOW(GPIOE_PIN12) | \ + PIN_OSPEED_VERYLOW(GPIOE_PIN13) | \ + PIN_OSPEED_VERYLOW(GPIOE_PIN14) | \ + PIN_OSPEED_VERYLOW(GPIOE_PIN15)) +#define VAL_GPIOE_PUPDR (PIN_PUPDR_FLOATING(GPIOE_PIN0) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN1) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN2) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN3) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN4) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN5) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN6) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN7) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN8) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN9) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN10) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN11) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN12) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN13) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN14) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN15)) +#define VAL_GPIOE_ODR (PIN_ODR_LOW(GPIOE_PIN0) | \ + PIN_ODR_LOW(GPIOE_PIN1) | \ + PIN_ODR_LOW(GPIOE_PIN2) | \ + PIN_ODR_LOW(GPIOE_PIN3) | \ + PIN_ODR_LOW(GPIOE_PIN4) | \ + PIN_ODR_LOW(GPIOE_PIN5) | \ + PIN_ODR_LOW(GPIOE_PIN6) | \ + PIN_ODR_LOW(GPIOE_PIN7) | \ + PIN_ODR_LOW(GPIOE_PIN8) | \ + PIN_ODR_LOW(GPIOE_PIN9) | \ + PIN_ODR_LOW(GPIOE_PIN10) | \ + PIN_ODR_LOW(GPIOE_PIN11) | \ + PIN_ODR_LOW(GPIOE_PIN12) | \ + PIN_ODR_LOW(GPIOE_PIN13) | \ + PIN_ODR_LOW(GPIOE_PIN14) | \ + PIN_ODR_LOW(GPIOE_PIN15)) +#define VAL_GPIOE_AFRL (PIN_AFIO_AF(GPIOE_PIN0, 0U) | \ + PIN_AFIO_AF(GPIOE_PIN1, 0U) | \ + PIN_AFIO_AF(GPIOE_PIN2, 0U) | \ + PIN_AFIO_AF(GPIOE_PIN3, 0U) | \ + PIN_AFIO_AF(GPIOE_PIN4, 0U) | \ + PIN_AFIO_AF(GPIOE_PIN5, 0U) | \ + PIN_AFIO_AF(GPIOE_PIN6, 0U) | \ + PIN_AFIO_AF(GPIOE_PIN7, 0U)) +#define VAL_GPIOE_AFRH (PIN_AFIO_AF(GPIOE_PIN8, 0U) | \ + PIN_AFIO_AF(GPIOE_PIN9, 0U) | \ + PIN_AFIO_AF(GPIOE_PIN10, 0U) | \ + PIN_AFIO_AF(GPIOE_PIN11, 0U) | \ + PIN_AFIO_AF(GPIOE_PIN12, 0U) | \ + PIN_AFIO_AF(GPIOE_PIN13, 0U) | \ + PIN_AFIO_AF(GPIOE_PIN14, 0U) | \ + PIN_AFIO_AF(GPIOE_PIN15, 0U)) +#define VAL_GPIOE_ASCR (PIN_ASCR_DISABLED(GPIOE_PIN0) | \ + PIN_ASCR_DISABLED(GPIOE_PIN1) | \ + PIN_ASCR_DISABLED(GPIOE_PIN2) | \ + PIN_ASCR_DISABLED(GPIOE_PIN3) | \ + PIN_ASCR_DISABLED(GPIOE_PIN4) | \ + PIN_ASCR_DISABLED(GPIOE_PIN5) | \ + PIN_ASCR_DISABLED(GPIOE_PIN6) | \ + PIN_ASCR_DISABLED(GPIOE_PIN7) | \ + PIN_ASCR_DISABLED(GPIOE_PIN8) | \ + PIN_ASCR_DISABLED(GPIOE_PIN9) | \ + PIN_ASCR_DISABLED(GPIOE_PIN10) | \ + PIN_ASCR_DISABLED(GPIOE_PIN11) | \ + PIN_ASCR_DISABLED(GPIOE_PIN12) | \ + PIN_ASCR_DISABLED(GPIOE_PIN13) | \ + PIN_ASCR_DISABLED(GPIOE_PIN14) | \ + PIN_ASCR_DISABLED(GPIOE_PIN15)) +#define VAL_GPIOE_LOCKR (PIN_LOCKR_DISABLED(GPIOE_PIN0) | \ + PIN_LOCKR_DISABLED(GPIOE_PIN1) | \ + PIN_LOCKR_DISABLED(GPIOE_PIN2) | \ + PIN_LOCKR_DISABLED(GPIOE_PIN3) | \ + PIN_LOCKR_DISABLED(GPIOE_PIN4) | \ + PIN_LOCKR_DISABLED(GPIOE_PIN5) | \ + PIN_LOCKR_DISABLED(GPIOE_PIN6) | \ + PIN_LOCKR_DISABLED(GPIOE_PIN7) | \ + PIN_LOCKR_DISABLED(GPIOE_PIN8) | \ + PIN_LOCKR_DISABLED(GPIOE_PIN9) | \ + PIN_LOCKR_DISABLED(GPIOE_PIN10) | \ + PIN_LOCKR_DISABLED(GPIOE_PIN11) | \ + PIN_LOCKR_DISABLED(GPIOE_PIN12) | \ + PIN_LOCKR_DISABLED(GPIOE_PIN13) | \ + PIN_LOCKR_DISABLED(GPIOE_PIN14) | \ + PIN_LOCKR_DISABLED(GPIOE_PIN15)) + +/* + * GPIOF setup: + * + * PF0 - PIN0 (analog). + * PF1 - PIN1 (analog). + * PF2 - PIN2 (analog). + * PF3 - PIN3 (analog). + * PF4 - PIN4 (analog). + * PF5 - PIN5 (analog). + * PF6 - PIN6 (analog). + * PF7 - PIN7 (analog). + * PF8 - PIN8 (analog). + * PF9 - PIN9 (analog). + * PF10 - PIN10 (analog). + * PF11 - PIN11 (analog). + * PF12 - PIN12 (analog). + * PF13 - PIN13 (analog). + * PF14 - PIN14 (analog). + * PF15 - PIN15 (analog). + */ +#define VAL_GPIOF_MODER (PIN_MODE_ANALOG(GPIOF_PIN0) | \ + PIN_MODE_ANALOG(GPIOF_PIN1) | \ + PIN_MODE_ANALOG(GPIOF_PIN2) | \ + PIN_MODE_ANALOG(GPIOF_PIN3) | \ + PIN_MODE_ANALOG(GPIOF_PIN4) | \ + PIN_MODE_ANALOG(GPIOF_PIN5) | \ + PIN_MODE_ANALOG(GPIOF_PIN6) | \ + PIN_MODE_ANALOG(GPIOF_PIN7) | \ + PIN_MODE_ANALOG(GPIOF_PIN8) | \ + PIN_MODE_ANALOG(GPIOF_PIN9) | \ + PIN_MODE_ANALOG(GPIOF_PIN10) | \ + PIN_MODE_ANALOG(GPIOF_PIN11) | \ + PIN_MODE_ANALOG(GPIOF_PIN12) | \ + PIN_MODE_ANALOG(GPIOF_PIN13) | \ + PIN_MODE_ANALOG(GPIOF_PIN14) | \ + PIN_MODE_ANALOG(GPIOF_PIN15)) +#define VAL_GPIOF_OTYPER (PIN_OTYPE_PUSHPULL(GPIOF_PIN0) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN1) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN7) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN13) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN14) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN15)) +#define VAL_GPIOF_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOF_PIN0) | \ + PIN_OSPEED_VERYLOW(GPIOF_PIN1) | \ + PIN_OSPEED_VERYLOW(GPIOF_PIN2) | \ + PIN_OSPEED_VERYLOW(GPIOF_PIN3) | \ + PIN_OSPEED_VERYLOW(GPIOF_PIN4) | \ + PIN_OSPEED_VERYLOW(GPIOF_PIN5) | \ + PIN_OSPEED_VERYLOW(GPIOF_PIN6) | \ + PIN_OSPEED_VERYLOW(GPIOF_PIN7) | \ + PIN_OSPEED_VERYLOW(GPIOF_PIN8) | \ + PIN_OSPEED_VERYLOW(GPIOF_PIN9) | \ + PIN_OSPEED_VERYLOW(GPIOF_PIN10) | \ + PIN_OSPEED_VERYLOW(GPIOF_PIN11) | \ + PIN_OSPEED_VERYLOW(GPIOF_PIN12) | \ + PIN_OSPEED_VERYLOW(GPIOF_PIN13) | \ + PIN_OSPEED_VERYLOW(GPIOF_PIN14) | \ + PIN_OSPEED_VERYLOW(GPIOF_PIN15)) +#define VAL_GPIOF_PUPDR (PIN_PUPDR_FLOATING(GPIOF_PIN0) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN1) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN2) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN3) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN4) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN5) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN6) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN7) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN8) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN9) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN10) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN11) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN12) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN13) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN14) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN15)) +#define VAL_GPIOF_ODR (PIN_ODR_LOW(GPIOF_PIN0) | \ + PIN_ODR_LOW(GPIOF_PIN1) | \ + PIN_ODR_LOW(GPIOF_PIN2) | \ + PIN_ODR_LOW(GPIOF_PIN3) | \ + PIN_ODR_LOW(GPIOF_PIN4) | \ + PIN_ODR_LOW(GPIOF_PIN5) | \ + PIN_ODR_LOW(GPIOF_PIN6) | \ + PIN_ODR_LOW(GPIOF_PIN7) | \ + PIN_ODR_LOW(GPIOF_PIN8) | \ + PIN_ODR_LOW(GPIOF_PIN9) | \ + PIN_ODR_LOW(GPIOF_PIN10) | \ + PIN_ODR_LOW(GPIOF_PIN11) | \ + PIN_ODR_LOW(GPIOF_PIN12) | \ + PIN_ODR_LOW(GPIOF_PIN13) | \ + PIN_ODR_LOW(GPIOF_PIN14) | \ + PIN_ODR_LOW(GPIOF_PIN15)) +#define VAL_GPIOF_AFRL (PIN_AFIO_AF(GPIOF_PIN0, 0U) | \ + PIN_AFIO_AF(GPIOF_PIN1, 0U) | \ + PIN_AFIO_AF(GPIOF_PIN2, 0U) | \ + PIN_AFIO_AF(GPIOF_PIN3, 0U) | \ + PIN_AFIO_AF(GPIOF_PIN4, 0U) | \ + PIN_AFIO_AF(GPIOF_PIN5, 0U) | \ + PIN_AFIO_AF(GPIOF_PIN6, 0U) | \ + PIN_AFIO_AF(GPIOF_PIN7, 0U)) +#define VAL_GPIOF_AFRH (PIN_AFIO_AF(GPIOF_PIN8, 0U) | \ + PIN_AFIO_AF(GPIOF_PIN9, 0U) | \ + PIN_AFIO_AF(GPIOF_PIN10, 0U) | \ + PIN_AFIO_AF(GPIOF_PIN11, 0U) | \ + PIN_AFIO_AF(GPIOF_PIN12, 0U) | \ + PIN_AFIO_AF(GPIOF_PIN13, 0U) | \ + PIN_AFIO_AF(GPIOF_PIN14, 0U) | \ + PIN_AFIO_AF(GPIOF_PIN15, 0U)) +#define VAL_GPIOF_ASCR (PIN_ASCR_DISABLED(GPIOF_PIN0) | \ + PIN_ASCR_DISABLED(GPIOF_PIN1) | \ + PIN_ASCR_DISABLED(GPIOF_PIN2) | \ + PIN_ASCR_DISABLED(GPIOF_PIN3) | \ + PIN_ASCR_DISABLED(GPIOF_PIN4) | \ + PIN_ASCR_DISABLED(GPIOF_PIN5) | \ + PIN_ASCR_DISABLED(GPIOF_PIN6) | \ + PIN_ASCR_DISABLED(GPIOF_PIN7) | \ + PIN_ASCR_DISABLED(GPIOF_PIN8) | \ + PIN_ASCR_DISABLED(GPIOF_PIN9) | \ + PIN_ASCR_DISABLED(GPIOF_PIN10) | \ + PIN_ASCR_DISABLED(GPIOF_PIN11) | \ + PIN_ASCR_DISABLED(GPIOF_PIN12) | \ + PIN_ASCR_DISABLED(GPIOF_PIN13) | \ + PIN_ASCR_DISABLED(GPIOF_PIN14) | \ + PIN_ASCR_DISABLED(GPIOF_PIN15)) +#define VAL_GPIOF_LOCKR (PIN_LOCKR_DISABLED(GPIOF_PIN0) | \ + PIN_LOCKR_DISABLED(GPIOF_PIN1) | \ + PIN_LOCKR_DISABLED(GPIOF_PIN2) | \ + PIN_LOCKR_DISABLED(GPIOF_PIN3) | \ + PIN_LOCKR_DISABLED(GPIOF_PIN4) | \ + PIN_LOCKR_DISABLED(GPIOF_PIN5) | \ + PIN_LOCKR_DISABLED(GPIOF_PIN6) | \ + PIN_LOCKR_DISABLED(GPIOF_PIN7) | \ + PIN_LOCKR_DISABLED(GPIOF_PIN8) | \ + PIN_LOCKR_DISABLED(GPIOF_PIN9) | \ + PIN_LOCKR_DISABLED(GPIOF_PIN10) | \ + PIN_LOCKR_DISABLED(GPIOF_PIN11) | \ + PIN_LOCKR_DISABLED(GPIOF_PIN12) | \ + PIN_LOCKR_DISABLED(GPIOF_PIN13) | \ + PIN_LOCKR_DISABLED(GPIOF_PIN14) | \ + PIN_LOCKR_DISABLED(GPIOF_PIN15)) + +/* + * GPIOG setup: + * + * PG0 - PIN0 (analog). + * PG1 - PIN1 (analog). + * PG2 - PIN2 (analog). + * PG3 - PIN3 (analog). + * PG4 - PIN4 (analog). + * PG5 - USB_OVER_CURRENT (input floating). + * PG6 - USB_POWER_SWITCH_ON (output pushpull maximum). + * PG7 - LPUART1_TX (alternate 8). + * PG8 - LPUART1_RX (alternate 8). + * PG9 - PIN9 (analog). + * PG10 - PIN10 (analog). + * PG11 - PIN11 (analog). + * PG12 - PIN12 (analog). + * PG13 - PIN13 (analog). + * PG14 - PIN14 (analog). + * PG15 - PIN15 (analog). + */ +#define VAL_GPIOG_MODER (PIN_MODE_ANALOG(GPIOG_PIN0) | \ + PIN_MODE_ANALOG(GPIOG_PIN1) | \ + PIN_MODE_ANALOG(GPIOG_PIN2) | \ + PIN_MODE_ANALOG(GPIOG_PIN3) | \ + PIN_MODE_ANALOG(GPIOG_PIN4) | \ + PIN_MODE_INPUT(GPIOG_USB_OVER_CURRENT) |\ + PIN_MODE_OUTPUT(GPIOG_USB_POWER_SWITCH_ON) |\ + PIN_MODE_ALTERNATE(GPIOG_LPUART1_TX) | \ + PIN_MODE_ALTERNATE(GPIOG_LPUART1_RX) | \ + PIN_MODE_ANALOG(GPIOG_PIN9) | \ + PIN_MODE_ANALOG(GPIOG_PIN10) | \ + PIN_MODE_ANALOG(GPIOG_PIN11) | \ + PIN_MODE_ANALOG(GPIOG_PIN12) | \ + PIN_MODE_ANALOG(GPIOG_PIN13) | \ + PIN_MODE_ANALOG(GPIOG_PIN14) | \ + PIN_MODE_ANALOG(GPIOG_PIN15)) +#define VAL_GPIOG_OTYPER (PIN_OTYPE_PUSHPULL(GPIOG_PIN0) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN1) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOG_USB_OVER_CURRENT) |\ + PIN_OTYPE_PUSHPULL(GPIOG_USB_POWER_SWITCH_ON) |\ + PIN_OTYPE_PUSHPULL(GPIOG_LPUART1_TX) | \ + PIN_OTYPE_PUSHPULL(GPIOG_LPUART1_RX) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN13) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN14) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN15)) +#define VAL_GPIOG_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOG_PIN0) | \ + PIN_OSPEED_VERYLOW(GPIOG_PIN1) | \ + PIN_OSPEED_VERYLOW(GPIOG_PIN2) | \ + PIN_OSPEED_VERYLOW(GPIOG_PIN3) | \ + PIN_OSPEED_VERYLOW(GPIOG_PIN4) | \ + PIN_OSPEED_VERYLOW(GPIOG_USB_OVER_CURRENT) |\ + PIN_OSPEED_HIGH(GPIOG_USB_POWER_SWITCH_ON) |\ + PIN_OSPEED_VERYLOW(GPIOG_LPUART1_TX) | \ + PIN_OSPEED_VERYLOW(GPIOG_LPUART1_RX) | \ + PIN_OSPEED_VERYLOW(GPIOG_PIN9) | \ + PIN_OSPEED_VERYLOW(GPIOG_PIN10) | \ + PIN_OSPEED_VERYLOW(GPIOG_PIN11) | \ + PIN_OSPEED_VERYLOW(GPIOG_PIN12) | \ + PIN_OSPEED_VERYLOW(GPIOG_PIN13) | \ + PIN_OSPEED_VERYLOW(GPIOG_PIN14) | \ + PIN_OSPEED_VERYLOW(GPIOG_PIN15)) +#define VAL_GPIOG_PUPDR (PIN_PUPDR_FLOATING(GPIOG_PIN0) | \ + PIN_PUPDR_FLOATING(GPIOG_PIN1) | \ + PIN_PUPDR_FLOATING(GPIOG_PIN2) | \ + PIN_PUPDR_FLOATING(GPIOG_PIN3) | \ + PIN_PUPDR_FLOATING(GPIOG_PIN4) | \ + PIN_PUPDR_FLOATING(GPIOG_USB_OVER_CURRENT) |\ + PIN_PUPDR_FLOATING(GPIOG_USB_POWER_SWITCH_ON) |\ + PIN_PUPDR_FLOATING(GPIOG_LPUART1_TX) | \ + PIN_PUPDR_FLOATING(GPIOG_LPUART1_RX) | \ + PIN_PUPDR_FLOATING(GPIOG_PIN9) | \ + PIN_PUPDR_FLOATING(GPIOG_PIN10) | \ + PIN_PUPDR_FLOATING(GPIOG_PIN11) | \ + PIN_PUPDR_FLOATING(GPIOG_PIN12) | \ + PIN_PUPDR_FLOATING(GPIOG_PIN13) | \ + PIN_PUPDR_FLOATING(GPIOG_PIN14) | \ + PIN_PUPDR_FLOATING(GPIOG_PIN15)) +#define VAL_GPIOG_ODR (PIN_ODR_LOW(GPIOG_PIN0) | \ + PIN_ODR_LOW(GPIOG_PIN1) | \ + PIN_ODR_LOW(GPIOG_PIN2) | \ + PIN_ODR_LOW(GPIOG_PIN3) | \ + PIN_ODR_LOW(GPIOG_PIN4) | \ + PIN_ODR_LOW(GPIOG_USB_OVER_CURRENT) | \ + PIN_ODR_LOW(GPIOG_USB_POWER_SWITCH_ON) |\ + PIN_ODR_LOW(GPIOG_LPUART1_TX) | \ + PIN_ODR_LOW(GPIOG_LPUART1_RX) | \ + PIN_ODR_LOW(GPIOG_PIN9) | \ + PIN_ODR_LOW(GPIOG_PIN10) | \ + PIN_ODR_LOW(GPIOG_PIN11) | \ + PIN_ODR_LOW(GPIOG_PIN12) | \ + PIN_ODR_LOW(GPIOG_PIN13) | \ + PIN_ODR_LOW(GPIOG_PIN14) | \ + PIN_ODR_LOW(GPIOG_PIN15)) +#define VAL_GPIOG_AFRL (PIN_AFIO_AF(GPIOG_PIN0, 0U) | \ + PIN_AFIO_AF(GPIOG_PIN1, 0U) | \ + PIN_AFIO_AF(GPIOG_PIN2, 0U) | \ + PIN_AFIO_AF(GPIOG_PIN3, 0U) | \ + PIN_AFIO_AF(GPIOG_PIN4, 0U) | \ + PIN_AFIO_AF(GPIOG_USB_OVER_CURRENT, 0U) |\ + PIN_AFIO_AF(GPIOG_USB_POWER_SWITCH_ON, 0U) |\ + PIN_AFIO_AF(GPIOG_LPUART1_TX, 8U)) +#define VAL_GPIOG_AFRH (PIN_AFIO_AF(GPIOG_LPUART1_RX, 8U) | \ + PIN_AFIO_AF(GPIOG_PIN9, 0U) | \ + PIN_AFIO_AF(GPIOG_PIN10, 0U) | \ + PIN_AFIO_AF(GPIOG_PIN11, 0U) | \ + PIN_AFIO_AF(GPIOG_PIN12, 0U) | \ + PIN_AFIO_AF(GPIOG_PIN13, 0U) | \ + PIN_AFIO_AF(GPIOG_PIN14, 0U) | \ + PIN_AFIO_AF(GPIOG_PIN15, 0U)) +#define VAL_GPIOG_ASCR (PIN_ASCR_DISABLED(GPIOG_PIN0) | \ + PIN_ASCR_DISABLED(GPIOG_PIN1) | \ + PIN_ASCR_DISABLED(GPIOG_PIN2) | \ + PIN_ASCR_DISABLED(GPIOG_PIN3) | \ + PIN_ASCR_DISABLED(GPIOG_PIN4) | \ + PIN_ASCR_DISABLED(GPIOG_USB_OVER_CURRENT) |\ + PIN_ASCR_DISABLED(GPIOG_USB_POWER_SWITCH_ON) |\ + PIN_ASCR_DISABLED(GPIOG_LPUART1_TX) | \ + PIN_ASCR_DISABLED(GPIOG_LPUART1_RX) | \ + PIN_ASCR_DISABLED(GPIOG_PIN9) | \ + PIN_ASCR_DISABLED(GPIOG_PIN10) | \ + PIN_ASCR_DISABLED(GPIOG_PIN11) | \ + PIN_ASCR_DISABLED(GPIOG_PIN12) | \ + PIN_ASCR_DISABLED(GPIOG_PIN13) | \ + PIN_ASCR_DISABLED(GPIOG_PIN14) | \ + PIN_ASCR_DISABLED(GPIOG_PIN15)) +#define VAL_GPIOG_LOCKR (PIN_LOCKR_DISABLED(GPIOG_PIN0) | \ + PIN_LOCKR_DISABLED(GPIOG_PIN1) | \ + PIN_LOCKR_DISABLED(GPIOG_PIN2) | \ + PIN_LOCKR_DISABLED(GPIOG_PIN3) | \ + PIN_LOCKR_DISABLED(GPIOG_PIN4) | \ + PIN_LOCKR_DISABLED(GPIOG_USB_OVER_CURRENT) |\ + PIN_LOCKR_DISABLED(GPIOG_USB_POWER_SWITCH_ON) |\ + PIN_LOCKR_DISABLED(GPIOG_LPUART1_TX) | \ + PIN_LOCKR_DISABLED(GPIOG_LPUART1_RX) | \ + PIN_LOCKR_DISABLED(GPIOG_PIN9) | \ + PIN_LOCKR_DISABLED(GPIOG_PIN10) | \ + PIN_LOCKR_DISABLED(GPIOG_PIN11) | \ + PIN_LOCKR_DISABLED(GPIOG_PIN12) | \ + PIN_LOCKR_DISABLED(GPIOG_PIN13) | \ + PIN_LOCKR_DISABLED(GPIOG_PIN14) | \ + PIN_LOCKR_DISABLED(GPIOG_PIN15)) + +/* + * GPIOH setup: + * + * PH0 - PIN0 (analog). + * PH1 - PIN1 (analog). + * PH2 - PIN2 (input floating). + * PH3 - PIN3 (input floating). + * PH4 - PIN4 (input floating). + * PH5 - PIN5 (input floating). + * PH6 - PIN6 (input floating). + * PH7 - PIN7 (input floating). + * PH8 - PIN8 (input floating). + * PH9 - PIN9 (input floating). + * PH10 - PIN10 (input floating). + * PH11 - PIN11 (input floating). + * PH12 - PIN12 (input floating). + * PH13 - PIN13 (input floating). + * PH14 - PIN14 (input floating). + * PH15 - PIN15 (input floating). + */ +#define VAL_GPIOH_MODER (PIN_MODE_ANALOG(GPIOH_PIN0) | \ + PIN_MODE_ANALOG(GPIOH_PIN1) | \ + PIN_MODE_INPUT(GPIOH_PIN2) | \ + PIN_MODE_INPUT(GPIOH_PIN3) | \ + PIN_MODE_INPUT(GPIOH_PIN4) | \ + PIN_MODE_INPUT(GPIOH_PIN5) | \ + PIN_MODE_INPUT(GPIOH_PIN6) | \ + PIN_MODE_INPUT(GPIOH_PIN7) | \ + PIN_MODE_INPUT(GPIOH_PIN8) | \ + PIN_MODE_INPUT(GPIOH_PIN9) | \ + PIN_MODE_INPUT(GPIOH_PIN10) | \ + PIN_MODE_INPUT(GPIOH_PIN11) | \ + PIN_MODE_INPUT(GPIOH_PIN12) | \ + PIN_MODE_INPUT(GPIOH_PIN13) | \ + PIN_MODE_INPUT(GPIOH_PIN14) | \ + PIN_MODE_INPUT(GPIOH_PIN15)) +#define VAL_GPIOH_OTYPER (PIN_OTYPE_PUSHPULL(GPIOH_PIN0) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN1) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN7) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN13) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN14) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN15)) +#define VAL_GPIOH_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOH_PIN0) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN1) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN2) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN3) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN4) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN5) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN6) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN7) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN8) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN9) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN10) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN11) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN12) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN13) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN14) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN15)) +#define VAL_GPIOH_PUPDR (PIN_PUPDR_FLOATING(GPIOH_PIN0) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN1) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN2) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN3) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN4) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN5) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN6) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN7) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN8) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN9) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN10) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN11) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN12) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN13) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN14) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN15)) +#define VAL_GPIOH_ODR (PIN_ODR_LOW(GPIOH_PIN0) | \ + PIN_ODR_LOW(GPIOH_PIN1) | \ + PIN_ODR_LOW(GPIOH_PIN2) | \ + PIN_ODR_LOW(GPIOH_PIN3) | \ + PIN_ODR_LOW(GPIOH_PIN4) | \ + PIN_ODR_LOW(GPIOH_PIN5) | \ + PIN_ODR_LOW(GPIOH_PIN6) | \ + PIN_ODR_LOW(GPIOH_PIN7) | \ + PIN_ODR_LOW(GPIOH_PIN8) | \ + PIN_ODR_LOW(GPIOH_PIN9) | \ + PIN_ODR_LOW(GPIOH_PIN10) | \ + PIN_ODR_LOW(GPIOH_PIN11) | \ + PIN_ODR_LOW(GPIOH_PIN12) | \ + PIN_ODR_LOW(GPIOH_PIN13) | \ + PIN_ODR_LOW(GPIOH_PIN14) | \ + PIN_ODR_LOW(GPIOH_PIN15)) +#define VAL_GPIOH_AFRL (PIN_AFIO_AF(GPIOH_PIN0, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN1, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN2, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN3, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN4, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN5, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN6, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN7, 0U)) +#define VAL_GPIOH_AFRH (PIN_AFIO_AF(GPIOH_PIN8, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN9, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN10, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN11, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN12, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN13, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN14, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN15, 0U)) +#define VAL_GPIOH_ASCR (PIN_ASCR_DISABLED(GPIOH_PIN0) | \ + PIN_ASCR_DISABLED(GPIOH_PIN1) | \ + PIN_ASCR_DISABLED(GPIOH_PIN2) | \ + PIN_ASCR_DISABLED(GPIOH_PIN3) | \ + PIN_ASCR_DISABLED(GPIOH_PIN4) | \ + PIN_ASCR_DISABLED(GPIOH_PIN5) | \ + PIN_ASCR_DISABLED(GPIOH_PIN6) | \ + PIN_ASCR_DISABLED(GPIOH_PIN7) | \ + PIN_ASCR_DISABLED(GPIOH_PIN8) | \ + PIN_ASCR_DISABLED(GPIOH_PIN9) | \ + PIN_ASCR_DISABLED(GPIOH_PIN10) | \ + PIN_ASCR_DISABLED(GPIOH_PIN11) | \ + PIN_ASCR_DISABLED(GPIOH_PIN12) | \ + PIN_ASCR_DISABLED(GPIOH_PIN13) | \ + PIN_ASCR_DISABLED(GPIOH_PIN14) | \ + PIN_ASCR_DISABLED(GPIOH_PIN15)) +#define VAL_GPIOH_LOCKR (PIN_LOCKR_DISABLED(GPIOH_PIN0) | \ + PIN_LOCKR_DISABLED(GPIOH_PIN1) | \ + PIN_LOCKR_DISABLED(GPIOH_PIN2) | \ + PIN_LOCKR_DISABLED(GPIOH_PIN3) | \ + PIN_LOCKR_DISABLED(GPIOH_PIN4) | \ + PIN_LOCKR_DISABLED(GPIOH_PIN5) | \ + PIN_LOCKR_DISABLED(GPIOH_PIN6) | \ + PIN_LOCKR_DISABLED(GPIOH_PIN7) | \ + PIN_LOCKR_DISABLED(GPIOH_PIN8) | \ + PIN_LOCKR_DISABLED(GPIOH_PIN9) | \ + PIN_LOCKR_DISABLED(GPIOH_PIN10) | \ + PIN_LOCKR_DISABLED(GPIOH_PIN11) | \ + PIN_LOCKR_DISABLED(GPIOH_PIN12) | \ + PIN_LOCKR_DISABLED(GPIOH_PIN13) | \ + PIN_LOCKR_DISABLED(GPIOH_PIN14) | \ + PIN_LOCKR_DISABLED(GPIOH_PIN15)) + +/* + * GPIOI setup: + * + * PI0 - PIN0 (analog). + * PI1 - PIN1 (analog). + * PI2 - PIN2 (input floating). + * PI3 - PIN3 (input floating). + * PI4 - PIN4 (input floating). + * PI5 - PIN5 (input floating). + * PI6 - PIN6 (input floating). + * PI7 - PIN7 (input floating). + * PI8 - PIN8 (input floating). + * PI9 - PIN9 (input floating). + * PI10 - PIN10 (input floating). + * PI11 - PIN11 (input floating). + * PI12 - PIN12 (input floating). + * PI13 - PIN13 (input floating). + * PI14 - PIN14 (input floating). + * PI15 - PIN15 (input floating). + */ +#define VAL_GPIOI_MODER (PIN_MODE_ANALOG(GPIOI_PIN0) | \ + PIN_MODE_ANALOG(GPIOI_PIN1) | \ + PIN_MODE_INPUT(GPIOI_PIN2) | \ + PIN_MODE_INPUT(GPIOI_PIN3) | \ + PIN_MODE_INPUT(GPIOI_PIN4) | \ + PIN_MODE_INPUT(GPIOI_PIN5) | \ + PIN_MODE_INPUT(GPIOI_PIN6) | \ + PIN_MODE_INPUT(GPIOI_PIN7) | \ + PIN_MODE_INPUT(GPIOI_PIN8) | \ + PIN_MODE_INPUT(GPIOI_PIN9) | \ + PIN_MODE_INPUT(GPIOI_PIN10) | \ + PIN_MODE_INPUT(GPIOI_PIN11) | \ + PIN_MODE_INPUT(GPIOI_PIN12) | \ + PIN_MODE_INPUT(GPIOI_PIN13) | \ + PIN_MODE_INPUT(GPIOI_PIN14) | \ + PIN_MODE_INPUT(GPIOI_PIN15)) +#define VAL_GPIOI_OTYPER (PIN_OTYPE_PUSHPULL(GPIOI_PIN0) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN1) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN7) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN13) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN14) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN15)) +#define VAL_GPIOI_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOI_PIN0) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN1) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN2) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN3) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN4) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN5) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN6) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN7) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN8) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN9) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN10) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN11) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN12) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN13) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN14) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN15)) +#define VAL_GPIOI_PUPDR (PIN_PUPDR_FLOATING(GPIOI_PIN0) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN1) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN2) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN3) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN4) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN5) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN6) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN7) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN8) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN9) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN10) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN11) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN12) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN13) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN14) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN15)) +#define VAL_GPIOI_ODR (PIN_ODR_LOW(GPIOI_PIN0) | \ + PIN_ODR_LOW(GPIOI_PIN1) | \ + PIN_ODR_LOW(GPIOI_PIN2) | \ + PIN_ODR_LOW(GPIOI_PIN3) | \ + PIN_ODR_LOW(GPIOI_PIN4) | \ + PIN_ODR_LOW(GPIOI_PIN5) | \ + PIN_ODR_LOW(GPIOI_PIN6) | \ + PIN_ODR_LOW(GPIOI_PIN7) | \ + PIN_ODR_LOW(GPIOI_PIN8) | \ + PIN_ODR_LOW(GPIOI_PIN9) | \ + PIN_ODR_LOW(GPIOI_PIN10) | \ + PIN_ODR_LOW(GPIOI_PIN11) | \ + PIN_ODR_LOW(GPIOI_PIN12) | \ + PIN_ODR_LOW(GPIOI_PIN13) | \ + PIN_ODR_LOW(GPIOI_PIN14) | \ + PIN_ODR_LOW(GPIOI_PIN15)) +#define VAL_GPIOI_AFRL (PIN_AFIO_AF(GPIOI_PIN0, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN1, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN2, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN3, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN4, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN5, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN6, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN7, 0U)) +#define VAL_GPIOI_AFRH (PIN_AFIO_AF(GPIOI_PIN8, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN9, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN10, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN11, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN12, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN13, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN14, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN15, 0U)) +#define VAL_GPIOI_ASCR (PIN_ASCR_DISABLED(GPIOI_PIN0) | \ + PIN_ASCR_DISABLED(GPIOI_PIN1) | \ + PIN_ASCR_DISABLED(GPIOI_PIN2) | \ + PIN_ASCR_DISABLED(GPIOI_PIN3) | \ + PIN_ASCR_DISABLED(GPIOI_PIN4) | \ + PIN_ASCR_DISABLED(GPIOI_PIN5) | \ + PIN_ASCR_DISABLED(GPIOI_PIN6) | \ + PIN_ASCR_DISABLED(GPIOI_PIN7) | \ + PIN_ASCR_DISABLED(GPIOI_PIN8) | \ + PIN_ASCR_DISABLED(GPIOI_PIN9) | \ + PIN_ASCR_DISABLED(GPIOI_PIN10) | \ + PIN_ASCR_DISABLED(GPIOI_PIN11) | \ + PIN_ASCR_DISABLED(GPIOI_PIN12) | \ + PIN_ASCR_DISABLED(GPIOI_PIN13) | \ + PIN_ASCR_DISABLED(GPIOI_PIN14) | \ + PIN_ASCR_DISABLED(GPIOI_PIN15)) +#define VAL_GPIOI_LOCKR (PIN_LOCKR_DISABLED(GPIOI_PIN0) | \ + PIN_LOCKR_DISABLED(GPIOI_PIN1) | \ + PIN_LOCKR_DISABLED(GPIOI_PIN2) | \ + PIN_LOCKR_DISABLED(GPIOI_PIN3) | \ + PIN_LOCKR_DISABLED(GPIOI_PIN4) | \ + PIN_LOCKR_DISABLED(GPIOI_PIN5) | \ + PIN_LOCKR_DISABLED(GPIOI_PIN6) | \ + PIN_LOCKR_DISABLED(GPIOI_PIN7) | \ + PIN_LOCKR_DISABLED(GPIOI_PIN8) | \ + PIN_LOCKR_DISABLED(GPIOI_PIN9) | \ + PIN_LOCKR_DISABLED(GPIOI_PIN10) | \ + PIN_LOCKR_DISABLED(GPIOI_PIN11) | \ + PIN_LOCKR_DISABLED(GPIOI_PIN12) | \ + PIN_LOCKR_DISABLED(GPIOI_PIN13) | \ + PIN_LOCKR_DISABLED(GPIOI_PIN14) | \ + PIN_LOCKR_DISABLED(GPIOI_PIN15)) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(_FROM_ASM_) +#ifdef __cplusplus +extern "C" { +#endif + void boardInit(void); +#ifdef __cplusplus +} +#endif +#endif /* _FROM_ASM_ */ + +#endif /* BOARD_H */ diff --git a/os/hal/boards/ST_NUCLEO144_L496ZG/board.mk b/os/hal/boards/ST_NUCLEO144_L496ZG/board.mk index 68cc5d5803..8c2d7074a7 100644 --- a/os/hal/boards/ST_NUCLEO144_L496ZG/board.mk +++ b/os/hal/boards/ST_NUCLEO144_L496ZG/board.mk @@ -1,9 +1,9 @@ -# List of all the board related files. -BOARDSRC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO144_L496ZG/board.c - -# Required include directories -BOARDINC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO144_L496ZG - -# Shared variables -ALLCSRC += $(BOARDSRC) -ALLINC += $(BOARDINC) +# List of all the board related files. +BOARDSRC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO144_L496ZG/board.c + +# Required include directories +BOARDINC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO144_L496ZG + +# Shared variables +ALLCSRC += $(BOARDSRC) +ALLINC += $(BOARDINC) diff --git a/os/hal/boards/ST_NUCLEO144_L496ZG/cfg/board.chcfg b/os/hal/boards/ST_NUCLEO144_L496ZG/cfg/board.chcfg index 1415660961..12ef83b402 100644 --- a/os/hal/boards/ST_NUCLEO144_L496ZG/cfg/board.chcfg +++ b/os/hal/boards/ST_NUCLEO144_L496ZG/cfg/board.chcfg @@ -1,420 +1,470 @@ - - - - - resources/gencfg/processors/boards/stm32l4xx/templates - .. - 5.0.x - - STMicroelectronics STM32 Nucleo144-L496ZG - ST_NUCLEO144_L496ZG - - - STM32L496xx - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + resources/gencfg/processors/boards/stm32l4xx/templates + .. + 5.0.x + + STMicroelectronics STM32 Nucleo144-L496ZG + ST_NUCLEO144_L496ZG + + + STM32L496xx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From f15055fa94a688c1d37a65f8ac323917290d1abc Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 8 Jul 2023 07:01:00 +0000 Subject: [PATCH 37/53] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16314 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- demos/STM32/RT-STM32F042K6-NUCLEO32/Makefile | 2 +- demos/STM32/RT-STM32L031K6-NUCLEO32/Makefile | 2 +- os/sb/various/syscalls.c | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/demos/STM32/RT-STM32F042K6-NUCLEO32/Makefile b/demos/STM32/RT-STM32F042K6-NUCLEO32/Makefile index b877ef4631..963e07dc5f 100644 --- a/demos/STM32/RT-STM32F042K6-NUCLEO32/Makefile +++ b/demos/STM32/RT-STM32F042K6-NUCLEO32/Makefile @@ -5,7 +5,7 @@ # Compiler options here. ifeq ($(USE_OPT),) - USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16 + USE_OPT = -Os -ggdb -fomit-frame-pointer -falign-functions=16 endif # C specific options here (added to USE_OPT). diff --git a/demos/STM32/RT-STM32L031K6-NUCLEO32/Makefile b/demos/STM32/RT-STM32L031K6-NUCLEO32/Makefile index af1f391dcd..4e86cc971e 100644 --- a/demos/STM32/RT-STM32L031K6-NUCLEO32/Makefile +++ b/demos/STM32/RT-STM32L031K6-NUCLEO32/Makefile @@ -5,7 +5,7 @@ # Compiler options here. ifeq ($(USE_OPT),) - USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16 + USE_OPT = -Os -ggdb -fomit-frame-pointer -falign-functions=16 endif # C specific options here (added to USE_OPT). diff --git a/os/sb/various/syscalls.c b/os/sb/various/syscalls.c index 1af2d0292c..00872554ef 100644 --- a/os/sb/various/syscalls.c +++ b/os/sb/various/syscalls.c @@ -115,11 +115,10 @@ caddr_t _sbrk_r(struct _reent *r, int incr) { } __attribute__((used)) -int _getpid_r(struct _reent *r) { - - (void)r; +int _getpid(void) { return 1; + abort(); } __attribute__((used)) From 6049000cc4ec3b3ff09d819a799383d6e5a03c0e Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 25 Jul 2023 14:03:09 +0000 Subject: [PATCH 38/53] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16341 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/STM32G0xx/hal_lld.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/os/hal/ports/STM32/STM32G0xx/hal_lld.h b/os/hal/ports/STM32/STM32G0xx/hal_lld.h index d7a2403cc9..1c14314542 100644 --- a/os/hal/ports/STM32/STM32G0xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32G0xx/hal_lld.h @@ -705,7 +705,7 @@ /** * @brief Maximum ADC clock frequency. */ -#define STM32_ADCCLK_MAX 350000000 +#define STM32_ADCCLK_MAX 35000000 /** @} */ /** From dd0783ca6f450486a96deadb98b6df01d6bb6e85 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Wed, 26 Jul 2023 09:33:27 +0000 Subject: [PATCH 39/53] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16342 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/STM32G0xx/hal_lld.h | 1 + 1 file changed, 1 insertion(+) diff --git a/os/hal/ports/STM32/STM32G0xx/hal_lld.h b/os/hal/ports/STM32/STM32G0xx/hal_lld.h index 1c14314542..69ac7ac519 100644 --- a/os/hal/ports/STM32/STM32G0xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32G0xx/hal_lld.h @@ -794,6 +794,7 @@ #if (STM32_I2C1SEL == STM32_I2C1SEL_HSI16) #error "HSI16 not enabled, required by STM32_I2C1SEL" #endif + #if (STM32_I2S1SEL == STM32_I2S1SEL_HSI16) #error "HSI16 not enabled, required by STM32_I2S1SEL" #endif From fed7a8212485f2c939f999e2c105c3e718b73ced Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 2 Dec 2023 16:22:55 +0000 Subject: [PATCH 40/53] Fixed extra parameter in some RCC macros. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16428 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/STM32F4xx/stm32_rcc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/os/hal/ports/STM32/STM32F4xx/stm32_rcc.h b/os/hal/ports/STM32/STM32F4xx/stm32_rcc.h index cc401ce059..69dbd37a36 100644 --- a/os/hal/ports/STM32/STM32F4xx/stm32_rcc.h +++ b/os/hal/ports/STM32/STM32F4xx/stm32_rcc.h @@ -1478,7 +1478,7 @@ * * @api */ -#define rccDisableUART9() rccDisableAPB2(RCC_APB2ENR_UART9EN, lp) +#define rccDisableUART9() rccDisableAPB2(RCC_APB2ENR_UART9EN) /** * @brief Resets the UART9 peripheral. @@ -1503,7 +1503,7 @@ * * @api */ -#define rccDisableUART10(lp) rccDisableAPB2(RCC_APB2ENR_UART10EN, lp) +#define rccDisableUART10(lp) rccDisableAPB2(RCC_APB2ENR_UART10EN) /** * @brief Resets the UART10 peripheral. From 1977b8c3e4dda99a65fd86b142600218683fa37e Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 5 Dec 2023 11:36:54 +0000 Subject: [PATCH 41/53] External removed. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16430 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 From f944e2d111d7a712c014a4b4a06c633c669eb946 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 24 Dec 2023 07:31:22 +0000 Subject: [PATCH 42/53] Fixed bug #1277. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16436 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/oslib/include/chmempools.h | 11 +++++++---- readme.txt | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/os/oslib/include/chmempools.h b/os/oslib/include/chmempools.h index 6fad2ebfc6..f4fdcf6349 100644 --- a/os/oslib/include/chmempools.h +++ b/os/oslib/include/chmempools.h @@ -275,12 +275,15 @@ static inline cnt_t chGuardedPoolGetCounterI(guarded_memory_pool_t *gmp) { static inline void *chGuardedPoolAllocI(guarded_memory_pool_t *gmp) { void *p; - p = chPoolAllocI(&gmp->pool); - if (p != NULL) { + if (chSemGetCounterI(&gmp->sem) > (cnt_t)0) { + chSemFastWaitI(&gmp->sem); - chDbgAssert(chSemGetCounterI(&gmp->sem) >= (cnt_t)0, - "semaphore out of sync"); + p = chPoolAllocI(&gmp->pool); + } + else { + p = NULL; } + return p; } diff --git a/readme.txt b/readme.txt index 478116604a..7602b98ceb 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed ace condition caused by chGuardedPoolAllocI() (bug #1277). - FIX: Fixed unnecessary code in SNOR device drivers (bug #1265). - FIX: Fixed channel 0 corruption on STM32 BDMAv1 (bug #1263). - FIX: Fixed missing cache management during Cortex-M RAM initializations From 6ffc244fa5798511b51726c59b3ddd1396d00767 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 24 Dec 2023 07:53:48 +0000 Subject: [PATCH 43/53] Fixed bug #1269. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16437 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c | 2 ++ readme.txt | 2 ++ testhal/STM32/multi/RTC/.cproject | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c b/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c index 56110cde95..f6a27d8516 100644 --- a/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c +++ b/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c @@ -652,7 +652,9 @@ void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec) { do #endif /* STM32_RTC_HAS_SUBSECONDS */ { +#if STM32_RTC_HAS_SUBSECONDS oldssr = rtcp->rtc->SSR; +#endif /* STM32_RTC_HAS_SUBSECONDS */ tr = rtcp->rtc->TR; dr = rtcp->rtc->DR; } diff --git a/readme.txt b/readme.txt index 7602b98ceb..1f79fbb561 100644 --- a/readme.txt +++ b/readme.txt @@ -75,6 +75,8 @@ *** 20.3.5 *** - FIX: Fixed ace condition caused by chGuardedPoolAllocI() (bug #1277). +- FIX: Fixed STM32/LLD/RTCv2/hal_rtc_lld.c does not compile with + STM32_RTC_HAS_SUBSECONDS = FALSE (bug #1269). - FIX: Fixed unnecessary code in SNOR device drivers (bug #1265). - FIX: Fixed channel 0 corruption on STM32 BDMAv1 (bug #1263). - FIX: Fixed missing cache management during Cortex-M RAM initializations diff --git a/testhal/STM32/multi/RTC/.cproject b/testhal/STM32/multi/RTC/.cproject index 68a8220070..4a551972c8 100644 --- a/testhal/STM32/multi/RTC/.cproject +++ b/testhal/STM32/multi/RTC/.cproject @@ -326,4 +326,5 @@ - + + \ No newline at end of file From 09eb5c262a9be2099e7b312d34d9ddcc5d14ff2c Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 24 Dec 2023 08:16:26 +0000 Subject: [PATCH 44/53] Fixed bug #1274. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16439 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/lib/streams/chprintf.c | 9 ++++----- readme.txt | 4 +++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/os/hal/lib/streams/chprintf.c b/os/hal/lib/streams/chprintf.c index 4ecec7bcff..3196b3d205 100644 --- a/os/hal/lib/streams/chprintf.c +++ b/os/hal/lib/streams/chprintf.c @@ -75,17 +75,16 @@ static char *ch_ltoa(char *p, long num, unsigned radix) { } #if CHPRINTF_USE_FLOAT -static const long pow10[FLOAT_PRECISION] = { - 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 -}; - static char *ftoa(char *p, double num, unsigned long precision) { + static const long chpow10[FLOAT_PRECISION] = { + 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 + }; long l; if ((precision == 0) || (precision > FLOAT_PRECISION)) { precision = FLOAT_PRECISION; } - precision = pow10[precision - 1]; + precision = chpow10[precision - 1]; l = (long)num; p = long_to_string_with_divisor(p, l, 10, 0); diff --git a/readme.txt b/readme.txt index 1f79fbb561..3c7ce16eb5 100644 --- a/readme.txt +++ b/readme.txt @@ -74,7 +74,9 @@ ***************************************************************************** *** 20.3.5 *** -- FIX: Fixed ace condition caused by chGuardedPoolAllocI() (bug #1277). +- FIX: Fixed race condition caused by chGuardedPoolAllocI() (bug #1277). +- FIX: Fixed avoid shadowing with build-in pow10 function in chprintf.c + (bug #1274). - FIX: Fixed STM32/LLD/RTCv2/hal_rtc_lld.c does not compile with STM32_RTC_HAS_SUBSECONDS = FALSE (bug #1269). - FIX: Fixed unnecessary code in SNOR device drivers (bug #1265). From 49af7fd235cf571b5303a61b0124a527fbce1404 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Wed, 14 Aug 2024 09:31:32 +0000 Subject: [PATCH 45/53] Fixed bug #1288. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16533 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/common/ports/ARMCMx/chcore_v6m.h | 21 ++++++++++++-- os/common/ports/ARMCMx/chcore_v7m.h | 21 ++++++++++++-- os/common/ports/templates/chcore.h | 43 ++++++++++++----------------- os/nil/include/ch.h | 2 +- os/nil/src/ch.c | 18 ++++++++---- os/rt/include/chsys.h | 10 +++++-- os/rt/src/chsys.c | 12 ++++++-- readme.txt | 1 + 8 files changed, 86 insertions(+), 42 deletions(-) diff --git a/os/common/ports/ARMCMx/chcore_v6m.h b/os/common/ports/ARMCMx/chcore_v6m.h index 6313dc4bac..257abe6d20 100644 --- a/os/common/ports/ARMCMx/chcore_v6m.h +++ b/os/common/ports/ARMCMx/chcore_v6m.h @@ -325,6 +325,23 @@ struct port_context { } #endif +/** + * @brief Returns a word representing a critical section status. + * + * @return The critical section status. + */ +#define port_get_lock_status() __port_get_irq_status() + +/** + * @brief Determines if in a critical section. + * + * @param[in] sts status word returned by @p port_get_lock_status() + * @return The current status. + * @retval false if running outside a critical section. + * @retval true if running within a critical section. + */ +#define port_is_locked(sts) !__port_irq_enabled(sts) + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ @@ -351,7 +368,7 @@ extern "C" { * * @return The interrupts status. */ -static inline syssts_t port_get_irq_status(void) { +static inline syssts_t __port_get_irq_status(void) { return (syssts_t)__get_PRIMASK(); } @@ -365,7 +382,7 @@ static inline syssts_t port_get_irq_status(void) { * @retval false the word specified a disabled interrupts status. * @retval true the word specified an enabled interrupts status. */ -static inline bool port_irq_enabled(syssts_t sts) { +static inline bool __port_irq_enabled(syssts_t sts) { return (sts & (syssts_t)1) == (syssts_t)0; } diff --git a/os/common/ports/ARMCMx/chcore_v7m.h b/os/common/ports/ARMCMx/chcore_v7m.h index d7b3f0985f..a01d16b7f0 100644 --- a/os/common/ports/ARMCMx/chcore_v7m.h +++ b/os/common/ports/ARMCMx/chcore_v7m.h @@ -591,6 +591,23 @@ struct port_context { #endif #endif +/** + * @brief Returns a word representing a critical section status. + * + * @return The critical section status. + */ +#define port_get_lock_status() __port_get_irq_status() + +/** + * @brief Determines if in a critical section. + * + * @param[in] sts status word returned by @p port_get_lock_status() + * @return The current status. + * @retval false if running outside a critical section. + * @retval true if running within a critical section. + */ +#define port_is_locked(sts) !__port_irq_enabled(sts) + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ @@ -620,7 +637,7 @@ extern "C" { * * @return The interrupts status. */ -__STATIC_FORCEINLINE syssts_t port_get_irq_status(void) { +__STATIC_FORCEINLINE syssts_t __port_get_irq_status(void) { syssts_t sts; #if CORTEX_SIMPLIFIED_PRIORITY == FALSE @@ -640,7 +657,7 @@ __STATIC_FORCEINLINE syssts_t port_get_irq_status(void) { * @retval false the word specified a disabled interrupts status. * @retval true the word specified an enabled interrupts status. */ -__STATIC_FORCEINLINE bool port_irq_enabled(syssts_t sts) { +__STATIC_FORCEINLINE bool __port_irq_enabled(syssts_t sts) { #if CORTEX_SIMPLIFIED_PRIORITY == FALSE return sts == (syssts_t)CORTEX_BASEPRI_DISABLED; diff --git a/os/common/ports/templates/chcore.h b/os/common/ports/templates/chcore.h index f62fd1b595..a4fd0d8416 100644 --- a/os/common/ports/templates/chcore.h +++ b/os/common/ports/templates/chcore.h @@ -286,6 +286,23 @@ struct port_context { } #endif +/** + * @brief Returns a word representing a critical section status. + * + * @return The critical section status. + */ +#define port_get_lock_status() 0U + +/** + * @brief Determines if in a critical section. + * + * @param[in] sts status word returned by @p port_get_lock_status() + * @return The current status. + * @retval false if running outside a critical section. + * @retval true if running within a critical section. + */ +#define port_is_locked(sts) ((sts) != 0U) + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ @@ -313,32 +330,6 @@ extern "C" { asm module.*/ #if !defined(_FROM_ASM_) -/** - * @brief Returns a word encoding the current interrupts status. - * - * @return The interrupts status. - */ -static inline syssts_t port_get_irq_status(void) { - - return 0; -} - -/** - * @brief Checks the interrupt status. - * - * @param[in] sts the interrupt status word - * - * @return The interrupt status. - * @retval false the word specified a disabled interrupts status. - * @retval true the word specified an enabled interrupts status. - */ -static inline bool port_irq_enabled(syssts_t sts) { - - (void)sts; - - return false; -} - /** * @brief Determines the current execution context. * diff --git a/os/nil/include/ch.h b/os/nil/include/ch.h index d20144671b..995ab447ad 100644 --- a/os/nil/include/ch.h +++ b/os/nil/include/ch.h @@ -53,7 +53,7 @@ /** * @brief Kernel version string. */ -#define CH_KERNEL_VERSION "4.0.2" +#define CH_KERNEL_VERSION "4.0.3" /** * @brief Kernel version major number. diff --git a/os/nil/src/ch.c b/os/nil/src/ch.c index 2aa05427fd..501f353951 100644 --- a/os/nil/src/ch.c +++ b/os/nil/src/ch.c @@ -448,6 +448,7 @@ void chSysTimerHandlerI(void) { #endif } +#if defined(port_get_lock_status) || defined(__DOXYGEN__) /** * @brief Unconditionally enters the kernel lock state. * @note Can be called without previous knowledge of the current lock state. @@ -457,7 +458,7 @@ void chSysTimerHandlerI(void) { */ void chSysUnconditionalLock(void) { - if (port_irq_enabled(port_get_irq_status())) { + if (!port_is_locked(port_get_lock_status())) { chSysLock(); } } @@ -471,7 +472,7 @@ void chSysUnconditionalLock(void) { */ void chSysUnconditionalUnlock(void) { - if (!port_irq_enabled(port_get_irq_status())) { + if (port_is_locked(port_get_lock_status())) { chSysUnlock(); } } @@ -483,16 +484,18 @@ void chSysUnconditionalUnlock(void) { * than @p chSysLock() which is preferable when the calling context * is known. * @post The system is in a critical zone. + * @note This function is only available if the underlying port supports + * @p port_get_lock_status() and @p port_is_locked(). * * @return The previous system status, the encoding of this * status word is architecture-dependent and opaque. * * @xclass */ -syssts_t chSysGetStatusAndLockX(void) { +syssts_t chSysGetStatusAndLockX(void) { - syssts_t sts = port_get_irq_status(); - if (port_irq_enabled(sts)) { + syssts_t sts = port_get_lock_status(); + if (!port_is_locked(sts)) { if (port_is_isr_context()) { chSysLockFromISR(); } @@ -507,6 +510,8 @@ syssts_t chSysGetStatusAndLockX(void) { * @brief Restores the specified execution status and leaves a critical zone. * @note A call to @p chSchRescheduleS() is automatically performed * if exiting the critical zone and if not in ISR context. + * @note This function is only available if the underlying port supports + * @p port_get_lock_status() and @p port_is_locked(). * * @param[in] sts the system status to be restored. * @@ -514,7 +519,7 @@ syssts_t chSysGetStatusAndLockX(void) { */ void chSysRestoreStatusX(syssts_t sts) { - if (port_irq_enabled(sts)) { + if (!port_is_locked(sts)) { if (port_is_isr_context()) { chSysUnlockFromISR(); } @@ -524,6 +529,7 @@ void chSysRestoreStatusX(syssts_t sts) { } } } +#endif /* defined(port_get_lock_status) */ #if (PORT_SUPPORTS_RT == TRUE) || defined(__DOXYGEN__) /** diff --git a/os/rt/include/chsys.h b/os/rt/include/chsys.h index c2e81fb48e..28fb3c4966 100644 --- a/os/rt/include/chsys.h +++ b/os/rt/include/chsys.h @@ -419,16 +419,19 @@ static inline void chSysUnlockFromISR(void) { port_unlock_from_isr(); } +#if defined(port_get_lock_status) || defined(__DOXYGEN__) /** * @brief Unconditionally enters the kernel lock state. * @note Can be called without previous knowledge of the current lock state. * The final state is "s-locked". + * @note This function is only available if the underlying port supports + * @p port_get_lock_status() and @p port_is_locked(). * * @special */ static inline void chSysUnconditionalLock(void) { - if (port_irq_enabled(port_get_irq_status())) { + if (!port_is_locked(port_get_lock_status())) { chSysLock(); } } @@ -437,15 +440,18 @@ static inline void chSysUnconditionalLock(void) { * @brief Unconditionally leaves the kernel lock state. * @note Can be called without previous knowledge of the current lock state. * The final state is "normal". + * @note This function is only available if the underlying port supports + * @p port_get_lock_status() and @p port_is_locked(). * * @special */ static inline void chSysUnconditionalUnlock(void) { - if (!port_irq_enabled(port_get_irq_status())) { + if (port_is_locked(port_get_lock_status())) { chSysUnlock(); } } +#endif /* defined(port_get_lock_status) */ #if (CH_CFG_NO_IDLE_THREAD == FALSE) || defined(__DOXYGEN__) /** diff --git a/os/rt/src/chsys.c b/os/rt/src/chsys.c index cdab59d703..27c1b65516 100644 --- a/os/rt/src/chsys.c +++ b/os/rt/src/chsys.c @@ -348,6 +348,7 @@ void chSysTimerHandlerI(void) { CH_CFG_SYSTEM_TICK_HOOK(); } +#if defined(port_get_lock_status) || defined(__DOXYGEN__) /** * @brief Returns the execution status and enters a critical zone. * @details This functions enters into a critical zone and can be called @@ -355,6 +356,8 @@ void chSysTimerHandlerI(void) { * than @p chSysLock() which is preferable when the calling context * is known. * @post The system is in a critical zone. + * @note This function is only available if the underlying port supports + * @p port_get_lock_status() and @p port_is_locked(). * * @return The previous system status, the encoding of this * status word is architecture-dependent and opaque. @@ -363,8 +366,8 @@ void chSysTimerHandlerI(void) { */ syssts_t chSysGetStatusAndLockX(void) { - syssts_t sts = port_get_irq_status(); - if (port_irq_enabled(sts)) { + syssts_t sts = port_get_lock_status(); + if (!port_is_locked(sts)) { if (port_is_isr_context()) { chSysLockFromISR(); } @@ -379,6 +382,8 @@ syssts_t chSysGetStatusAndLockX(void) { * @brief Restores the specified execution status and leaves a critical zone. * @note A call to @p chSchRescheduleS() is automatically performed * if exiting the critical zone and if not in ISR context. + * @note This function is only available if the underlying port supports + * @p port_get_lock_status() and @p port_is_locked(). * * @param[in] sts the system status to be restored. * @@ -386,7 +391,7 @@ syssts_t chSysGetStatusAndLockX(void) { */ void chSysRestoreStatusX(syssts_t sts) { - if (port_irq_enabled(sts)) { + if (!port_is_locked(sts)) { if (port_is_isr_context()) { chSysUnlockFromISR(); } @@ -396,6 +401,7 @@ void chSysRestoreStatusX(syssts_t sts) { } } } +#endif /* defined(port_get_lock_status) */ #if (PORT_SUPPORTS_RT == TRUE) || defined(__DOXYGEN__) /** diff --git a/readme.txt b/readme.txt index 3c7ce16eb5..71d017b664 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 20.3.5 *** +- FIX: Fixed problem in recursive locks functions (bug #1288). - FIX: Fixed race condition caused by chGuardedPoolAllocI() (bug #1277). - FIX: Fixed avoid shadowing with build-in pow10 function in chprintf.c (bug #1274). From f66b3dce34680288603b041edb446ddb7fd5390a Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Fri, 16 Aug 2024 09:29:19 +0000 Subject: [PATCH 46/53] Recursive locks in RT and NIL made optional, only enabled if the underlying port supports the capability. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16538 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/nil/include/ch.h | 7 +++++++ os/nil/src/ch.c | 4 ++-- os/rt/include/chsys.h | 11 +++++++++-- os/rt/src/chsys.c | 4 ++-- readme.txt | 2 ++ test/rt/configuration.xml | 2 +- test/rt/source/test/rt_test_sequence_002.c | 10 ++++++++++ 7 files changed, 33 insertions(+), 7 deletions(-) diff --git a/os/nil/include/ch.h b/os/nil/include/ch.h index 995ab447ad..306f42844c 100644 --- a/os/nil/include/ch.h +++ b/os/nil/include/ch.h @@ -367,6 +367,13 @@ #define THD_IDLE_END NULL #endif +/* Recursive locks port capability assessed.*/ +#if defined(port_get_lock_status) && defined(port_is_locked) +#define CH_PORT_SUPPORTS_RECURSIVE_LOCKS TRUE +#else +#define CH_PORT_SUPPORTS_RECURSIVE_LOCKS FALSE +#endif + /*===========================================================================*/ /* Module data structures and types. */ /*===========================================================================*/ diff --git a/os/nil/src/ch.c b/os/nil/src/ch.c index 501f353951..2b750acab4 100644 --- a/os/nil/src/ch.c +++ b/os/nil/src/ch.c @@ -448,7 +448,7 @@ void chSysTimerHandlerI(void) { #endif } -#if defined(port_get_lock_status) || defined(__DOXYGEN__) +#if (CH_PORT_SUPPORTS_RECURSIVE_LOCKS == TRUE) || defined(__DOXYGEN__) /** * @brief Unconditionally enters the kernel lock state. * @note Can be called without previous knowledge of the current lock state. @@ -529,7 +529,7 @@ void chSysRestoreStatusX(syssts_t sts) { } } } -#endif /* defined(port_get_lock_status) */ +#endif /* CH_PORT_SUPPORTS_RECURSIVE_LOCKS == TRUE */ #if (PORT_SUPPORTS_RT == TRUE) || defined(__DOXYGEN__) /** diff --git a/os/rt/include/chsys.h b/os/rt/include/chsys.h index 28fb3c4966..36389f5915 100644 --- a/os/rt/include/chsys.h +++ b/os/rt/include/chsys.h @@ -52,6 +52,13 @@ /* Derived constants and error checks. */ /*===========================================================================*/ +/* Recursive locks port capability assessed.*/ +#if defined(port_get_lock_status) && defined(port_is_locked) +#define CH_PORT_SUPPORTS_RECURSIVE_LOCKS TRUE +#else +#define CH_PORT_SUPPORTS_RECURSIVE_LOCKS FALSE +#endif + /*===========================================================================*/ /* Module data structures and types. */ /*===========================================================================*/ @@ -419,7 +426,7 @@ static inline void chSysUnlockFromISR(void) { port_unlock_from_isr(); } -#if defined(port_get_lock_status) || defined(__DOXYGEN__) +#if (CH_PORT_SUPPORTS_RECURSIVE_LOCKS == TRUE) || defined(__DOXYGEN__) /** * @brief Unconditionally enters the kernel lock state. * @note Can be called without previous knowledge of the current lock state. @@ -451,7 +458,7 @@ static inline void chSysUnconditionalUnlock(void) { chSysUnlock(); } } -#endif /* defined(port_get_lock_status) */ +#endif /* CH_PORT_SUPPORTS_RECURSIVE_LOCKS == TRUE */ #if (CH_CFG_NO_IDLE_THREAD == FALSE) || defined(__DOXYGEN__) /** diff --git a/os/rt/src/chsys.c b/os/rt/src/chsys.c index 27c1b65516..12cdfeed4f 100644 --- a/os/rt/src/chsys.c +++ b/os/rt/src/chsys.c @@ -348,7 +348,7 @@ void chSysTimerHandlerI(void) { CH_CFG_SYSTEM_TICK_HOOK(); } -#if defined(port_get_lock_status) || defined(__DOXYGEN__) +#if (CH_PORT_SUPPORTS_RECURSIVE_LOCKS == TRUE) || defined(__DOXYGEN__) /** * @brief Returns the execution status and enters a critical zone. * @details This functions enters into a critical zone and can be called @@ -401,7 +401,7 @@ void chSysRestoreStatusX(syssts_t sts) { } } } -#endif /* defined(port_get_lock_status) */ +#endif /* CH_PORT_SUPPORTS_RECURSIVE_LOCKS == TRUE */ #if (PORT_SUPPORTS_RT == TRUE) || defined(__DOXYGEN__) /** diff --git a/readme.txt b/readme.txt index 71d017b664..1878944a8b 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,8 @@ ***************************************************************************** *** 20.3.5 *** +- NEW: Recursive locks in RT and NIL made optional, only enabled if the + underlying port supports the capability. - FIX: Fixed problem in recursive locks functions (bug #1288). - FIX: Fixed race condition caused by chGuardedPoolAllocI() (bug #1277). - FIX: Fixed avoid shadowing with build-in pow10 function in chprintf.c diff --git a/test/rt/configuration.xml b/test/rt/configuration.xml index 92aa8c8df2..e82b6c3688 100644 --- a/test/rt/configuration.xml +++ b/test/rt/configuration.xml @@ -515,7 +515,7 @@ test_assert(result == false, "port layer check failed");]]> The critical zones API is invoked for coverage. - + CH_PORT_SUPPORTS_RECURSIVE_LOCKS == TRUE diff --git a/test/rt/source/test/rt_test_sequence_002.c b/test/rt/source/test/rt_test_sequence_002.c index 51542002cb..b991202266 100644 --- a/test/rt/source/test/rt_test_sequence_002.c +++ b/test/rt/source/test/rt_test_sequence_002.c @@ -130,12 +130,19 @@ static const testcase_t rt_test_002_001 = { rt_test_002_001_execute }; +#if (CH_PORT_SUPPORTS_RECURSIVE_LOCKS == TRUE) || defined(__DOXYGEN__) /** * @page rt_test_002_002 [2.2] Critical zones functionality * *

Description

* The critical zones API is invoked for coverage. * + *

Conditions

+ * This test is only executed if the following preprocessor condition + * evaluates to true: + * - CH_PORT_SUPPORTS_RECURSIVE_LOCKS == TRUE + * . + * *

Test Steps

* - [2.2.1] Testing chSysGetStatusAndLockX() and * chSysRestoreStatusX(), non reentrant case. @@ -207,6 +214,7 @@ static const testcase_t rt_test_002_002 = { NULL, rt_test_002_002_execute }; +#endif /* CH_PORT_SUPPORTS_RECURSIVE_LOCKS == TRUE */ /** * @page rt_test_002_003 [2.3] Interrupts handling functionality @@ -249,7 +257,9 @@ static const testcase_t rt_test_002_003 = { */ const testcase_t * const rt_test_sequence_002_array[] = { &rt_test_002_001, +#if (CH_PORT_SUPPORTS_RECURSIVE_LOCKS == TRUE) || defined(__DOXYGEN__) &rt_test_002_002, +#endif &rt_test_002_003, NULL }; From 70eec9d02867d6e30abb2ef7cfdbf85e6c7188e5 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Wed, 28 Aug 2024 11:19:49 +0000 Subject: [PATCH 47/53] LWIP fix related to possible systick frequencies. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16554 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/various/lwip_bindings/arch/sys_arch.c | 37 ++++++++++++++++++------ 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/os/various/lwip_bindings/arch/sys_arch.c b/os/various/lwip_bindings/arch/sys_arch.c index 7a7d5ea606..c169d2732e 100644 --- a/os/various/lwip_bindings/arch/sys_arch.c +++ b/os/various/lwip_bindings/arch/sys_arch.c @@ -225,15 +225,34 @@ void sys_arch_unprotect(sys_prot_t pval) { chSysRestoreStatusX((syssts_t)pval); } -u32_t sys_now(void) { +#if (OSAL_ST_FREQUENCY < 1000) || ((OSAL_ST_FREQUENCY % 1000) != 0) +#error "LWIP requires a systick frequency that is a multiple of 1000" +#endif + +#if (OSAL_ST_RESOLUTION >= 32) && (OSAL_ST_FREQUENCY == 1000) +u32_t sys_now(void) {return (u32_t)osalOsGetSystemTimeX();} -#if OSAL_ST_FREQUENCY == 1000 - return (u32_t)chVTGetSystemTimeX(); -#elif (OSAL_ST_FREQUENCY / 1000) >= 1 && (OSAL_ST_FREQUENCY % 1000) == 0 - return ((u32_t)chVTGetSystemTimeX() - 1) / (OSAL_ST_FREQUENCY / 1000) + 1; -#elif (1000 / OSAL_ST_FREQUENCY) >= 1 && (1000 % OSAL_ST_FREQUENCY) == 0 - return ((u32_t)chVTGetSystemTimeX() - 1) * (1000 / OSAL_ST_FREQUENCY) + 1; #else - return (u32_t)(((u64_t)(chVTGetSystemTimeX() - 1) * 1000) / OSAL_ST_FREQUENCY) + 1; -#endif +u32_t sys_now(void) { + static struct { + systime_t last_system_time; + u32_t last_ms; + u32_t last_unprocessed; + } persistent = {0, 0, 0}; + u32_t delta; + systime_t now_time; + + /* Calculating delta, in ticks, from the last acquired system time.*/ + now_time = osalOsGetSystemTimeX(); + delta = (u32_t)osalTimeDiffX(persistent.last_system_time, now_time) + + persistent.last_unprocessed; + persistent.last_system_time = now_time; + + /* Storing this milliseconds time and eventual remainder.*/ + persistent.last_ms += delta / (OSAL_ST_FREQUENCY / 1000U); + persistent.last_unprocessed = delta % (OSAL_ST_FREQUENCY / 1000U); + + return persistent.last_ms; } +#endif + From b66949344af400549c96dfed072729de32b522a7 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Fri, 11 Oct 2024 07:45:05 +0000 Subject: [PATCH 48/53] Fixed bug 1292. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16633 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/oslib/src/chfactory.c | 60 ++++++++++++++++++++++++++++------------ readme.txt | 1 + 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/os/oslib/src/chfactory.c b/os/oslib/src/chfactory.c index dccf0c12a4..26a67f9b18 100644 --- a/os/oslib/src/chfactory.c +++ b/os/oslib/src/chfactory.c @@ -113,16 +113,14 @@ static dyn_element_t *dyn_list_find(const char *name, dyn_list_t *dlp) { return NULL; } -static dyn_element_t *dyn_list_unlink(dyn_element_t *element, +static dyn_element_t *dyn_list_find_prev(dyn_element_t *element, dyn_list_t *dlp) { dyn_element_t *prev = (dyn_element_t *)dlp; /* Scanning the list.*/ while (prev->next != (dyn_element_t *)dlp) { if (prev->next == element) { - /* Found.*/ - prev->next = element->next; - return element; + return prev; } /* Next element in the list.*/ @@ -132,6 +130,14 @@ static dyn_element_t *dyn_list_unlink(dyn_element_t *element, return NULL; } +static dyn_element_t *dyn_list_unlink(dyn_element_t *prev) { + dyn_element_t *element = prev->next; + + prev->next = element->next; + + return element; +} + #if CH_FACTORY_REQUIRES_HEAP || defined(__DOXYGEN__) static dyn_element_t *dyn_create_object_heap(const char *name, dyn_list_t *dlp, @@ -165,15 +171,25 @@ static dyn_element_t *dyn_create_object_heap(const char *name, } static void dyn_release_object_heap(dyn_element_t *dep, - dyn_list_t *dlp) { + dyn_list_t *dlp) { + dyn_element_t *prev; + ucnt_t refs; chDbgCheck(dep != NULL); - chDbgAssert(dep->refs > (ucnt_t)0, "invalid references number"); - dep->refs--; - if (dep->refs == (ucnt_t)0) { - dep = dyn_list_unlink(dep, dlp); - chHeapFree((void *)dep); + /* Checking 1st if the object is in the list.*/ + prev = dyn_list_find_prev(dep, dlp); + if (prev != NULL) { + + chDbgAssert(dep->refs > (ucnt_t)0, "invalid references number"); + + refs = --dep->refs; + if (refs == (ucnt_t)0) { + chHeapFree((void *)dyn_list_unlink(prev)); + } + } + else { + chDbgAssert(false, "unknown object"); } } #endif /* CH_FACTORY_REQUIRES_HEAP */ @@ -210,16 +226,26 @@ static dyn_element_t *dyn_create_object_pool(const char *name, } static void dyn_release_object_pool(dyn_element_t *dep, - dyn_list_t *dlp, - memory_pool_t *mp) { + dyn_list_t *dlp, + memory_pool_t *mp) { + dyn_element_t *prev; + ucnt_t refs; chDbgCheck(dep != NULL); - chDbgAssert(dep->refs > (ucnt_t)0, "invalid references number"); - dep->refs--; - if (dep->refs == (ucnt_t)0) { - dep = dyn_list_unlink(dep, dlp); - chPoolFree(mp, (void *)dep); + /* Checking 1st if the object is in the list.*/ + prev = dyn_list_find_prev(dep, dlp); + if (prev != NULL) { + + chDbgAssert(dep->refs > (ucnt_t)0, "invalid references number"); + + refs = --dep->refs; + if (refs == (ucnt_t)0) { + chPoolFree(mp, (void *)dyn_list_unlink(prev)); + } + } + else { + chDbgAssert(false, "unknown object"); } } #endif /* CH_FACTORY_REQUIRES_POOLS */ diff --git a/readme.txt b/readme.txt index 1878944a8b..e60fc5f54d 100644 --- a/readme.txt +++ b/readme.txt @@ -76,6 +76,7 @@ *** 20.3.5 *** - NEW: Recursive locks in RT and NIL made optional, only enabled if the underlying port supports the capability. +- FIX: Fixed missing assertion in OSLIB factory module (bug 1292). - FIX: Fixed problem in recursive locks functions (bug #1288). - FIX: Fixed race condition caused by chGuardedPoolAllocI() (bug #1277). - FIX: Fixed avoid shadowing with build-in pow10 function in chprintf.c From bdf7bf1458fdf8be7cb04c780948731084fbe2f2 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Mon, 14 Oct 2024 08:08:50 +0000 Subject: [PATCH 49/53] Fixed wrong condition in sdcErase(). git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16635 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/src/hal_sdc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/os/hal/src/hal_sdc.c b/os/hal/src/hal_sdc.c index 17995e4154..dcd5b35f6f 100644 --- a/os/hal/src/hal_sdc.c +++ b/os/hal/src/hal_sdc.c @@ -950,7 +950,7 @@ bool sdcErase(SDCDriver *sdcp, uint32_t startblk, uint32_t endblk) { sdcp->state = BLK_WRITING; /* Handling command differences between HC and normal cards.*/ - if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) != 0U) { + if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0U) { startblk *= MMCSD_BLOCK_SIZE; endblk *= MMCSD_BLOCK_SIZE; } From d3666fb96080f7ea424d99922d0abc179b33f25b Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Mon, 14 Oct 2024 08:13:50 +0000 Subject: [PATCH 50/53] Small registry fix for STM32F7xx CRC. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16636 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/STM32F7xx/stm32_registry.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/os/hal/ports/STM32/STM32F7xx/stm32_registry.h b/os/hal/ports/STM32/STM32F7xx/stm32_registry.h index 5a5e4b036d..e67e7372fb 100644 --- a/os/hal/ports/STM32/STM32F7xx/stm32_registry.h +++ b/os/hal/ports/STM32/STM32F7xx/stm32_registry.h @@ -745,7 +745,7 @@ /* CRC attributes.*/ #define STM32_HAS_CRC TRUE -#define STM32_CRC_PROGRAMMABLE FALSE +#define STM32_CRC_PROGRAMMABLE TRUE #endif /* defined(STM32F745xx) || defined(STM32F746xx) || defined(STM32F756xx) */ @@ -1096,7 +1096,7 @@ /* CRC attributes.*/ #define STM32_HAS_CRC TRUE -#define STM32_CRC_PROGRAMMABLE FALSE +#define STM32_CRC_PROGRAMMABLE TRUE #endif /* defined(STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx) */ From 85424e7fd72b983bdb7703e81e46bc894893c17b Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Mon, 14 Oct 2024 08:23:37 +0000 Subject: [PATCH 51/53] STM32 OTGv1 ULPI fix. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16637 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c index c52ba5c5dc..6658d6af12 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c +++ b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c @@ -38,6 +38,19 @@ #define EP0_MAX_INSIZE 64 #define EP0_MAX_OUTSIZE 64 +/** @brief Enables delay in ULPI timing during device chirp.*/ +#define USB_OTG_DCFG_XCVRDLY (1U << 14) + +/** + * @brief some ULPI chip need additional delay for initial handshake, + * namely microchip 334x series. + */ +#if defined(BOARD_OTG2_ULPI_ACTIVATE_CHIRP_DELAY) +#define BOARD_OTG2_ULPI_CHIRP_DELAY_MASK USB_OTG_DCFG_XCVRDLY +#else +#define BOARD_OTG2_ULPI_CHIRP_DELAY_MASK 0 +#endif + #if STM32_OTG_STEPPING == 1 #if defined(BOARD_OTG_NOVBUSSENS) #define GCCFG_INIT_VALUE (GCCFG_NOVBUSSENS | GCCFG_PWRDWN) @@ -812,7 +825,7 @@ void usb_lld_start(USBDriver *usbp) { #if defined(BOARD_OTG2_USES_ULPI) #if STM32_USE_USB_OTG2_HS /* USB 2.0 High Speed PHY in HS mode.*/ - otgp->DCFG = 0x02200000 | DCFG_DSPD_HS; + otgp->DCFG = 0x02200000 | DCFG_DSPD_HS | BOARD_OTG2_ULPI_CHIRP_DELAY_MASK; #else /* USB 2.0 High Speed PHY in FS mode.*/ otgp->DCFG = 0x02200000 | DCFG_DSPD_HS_FS; @@ -952,7 +965,7 @@ void usb_lld_reset(USBDriver *usbp) { otg_rxfifo_flush(usbp); /* Resets the device address to zero.*/ - otgp->DCFG = (otgp->DCFG & ~DCFG_DAD_MASK) | DCFG_DAD(0); + otgp->DCFG = (otgp->DCFG & ~DCFG_DAD_MASK) | DCFG_DAD(0) | BOARD_OTG2_ULPI_CHIRP_DELAY_MASK; /* Enables also EP-related interrupt sources.*/ otgp->GINTMSK |= GINTMSK_RXFLVLM | GINTMSK_OEPM | GINTMSK_IEPM; From 071bdc02e6f318e14c3c3673bf38185244018517 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 30 Nov 2024 09:37:48 +0000 Subject: [PATCH 52/53] Fixed bug 1293. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16761 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c | 39 ++++++++++++++++++---- os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h | 3 ++ readme.txt | 2 ++ 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c index 6658d6af12..35f21849ee 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c +++ b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c @@ -68,6 +68,8 @@ #endif +#define IRQ_RETRY_MASK (GINTSTS_NPTXFE | GINTSTS_PTXFE | GINTSTS_RXFLVL) + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -183,6 +185,20 @@ static void otg_disable_ep(USBDriver *usbp) { otgp->DAINTMSK = DAINTMSK_OEPM(0) | DAINTMSK_IEPM(0); } +static void otg_enable_ep(USBDriver *usbp) { + stm32_otg_t *otgp = usbp->otg; + unsigned i; + + for (i = 0; i <= usbp->otgparams->num_endpoints; i++) { + if (usbp->epc[i]->out_state != NULL) { + otgp->DAINTMSK |= DAINTMSK_OEPM(i); + } + if (usbp->epc[i]->in_state != NULL) { + otgp->DAINTMSK |= DAINTMSK_IEPM(i); + } + } +} + static void otg_rxfifo_flush(USBDriver *usbp) { stm32_otg_t *otgp = usbp->otg; @@ -543,6 +559,9 @@ static void otg_isoc_out_failed_handler(USBDriver *usbp) { static void usb_lld_serve_interrupt(USBDriver *usbp) { stm32_otg_t *otgp = usbp->otg; uint32_t sts, src; + unsigned retry = 64U; + +irq_retry: sts = otgp->GINTSTS; sts &= otgp->GINTMSK; @@ -566,6 +585,9 @@ static void usb_lld_serve_interrupt(USBDriver *usbp) { otgp->PCGCCTL &= ~(PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK); } + /* Re-enable endpoint IRQs if they have been disabled by suspend before.*/ + otg_enable_ep(usbp); + /* Clear the Remote Wake-up Signaling.*/ otgp->DCTL &= ~DCTL_RWUSIG; @@ -624,12 +646,6 @@ static void usb_lld_serve_interrupt(USBDriver *usbp) { otg_isoc_out_failed_handler(usbp); } - /* Performing the whole FIFO emptying in the ISR, it is advised to keep - this IRQ at a very low priority level.*/ - if ((sts & GINTSTS_RXFLVL) != 0U) { - otg_rxfifo_handler(usbp); - } - /* IN/OUT endpoints event handling.*/ src = otgp->DAINT; if (sts & GINTSTS_OEPINT) { @@ -692,6 +708,15 @@ static void usb_lld_serve_interrupt(USBDriver *usbp) { otg_epin_handler(usbp, 8); #endif } + + /* Performing the whole FIFO emptying in the ISR, it is advised to keep + this IRQ at a very low priority level.*/ + if ((sts & GINTSTS_RXFLVL) != 0U) { + otg_rxfifo_handler(usbp); + } + + if ((sts & IRQ_RETRY_MASK) && (--retry > 0U)) + goto irq_retry; } /*===========================================================================*/ @@ -1163,7 +1188,7 @@ void usb_lld_start_out(USBDriver *usbp, usbep_t ep) { /* Transfer initialization.*/ osp->totsize = osp->rxsize; if ((ep == 0) && (osp->rxsize > EP0_MAX_OUTSIZE)) - osp->rxsize = EP0_MAX_OUTSIZE; + osp->rxsize = EP0_MAX_OUTSIZE; /* Transaction size is rounded to a multiple of packet size because the following requirement in the RM: diff --git a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h index c9d2be1649..e46c03f9f2 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h +++ b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h @@ -557,6 +557,9 @@ struct USBDriver { */ #define usb_lld_wakeup_host(usbp) \ do { \ + /* Turnings clocks back on (may be required if coming out of suspend + mode).*/ \ + (usbp)->otg->PCGCCTL &= ~(PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK); \ (usbp)->otg->DCTL |= DCTL_RWUSIG; \ /* remote wakeup doesn't trigger the wakeup interrupt, therefore we use the SOF interrupt to detect resume of the bus.*/ \ diff --git a/readme.txt b/readme.txt index e60fc5f54d..470fa96664 100644 --- a/readme.txt +++ b/readme.txt @@ -76,6 +76,8 @@ *** 20.3.5 *** - NEW: Recursive locks in RT and NIL made optional, only enabled if the underlying port supports the capability. +- FIX: Fixed STM32 OTGv1 driver does not re-enables endpoints on wakeup + (bug 1293). - FIX: Fixed missing assertion in OSLIB factory module (bug 1292). - FIX: Fixed problem in recursive locks functions (bug #1288). - FIX: Fixed race condition caused by chGuardedPoolAllocI() (bug #1277). From eb0d0fb26c00f4aefc7f92b9a6a1f0d8cf68f278 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 15 Dec 2024 07:44:56 +0000 Subject: [PATCH 53/53] Fixed partial patch, removed an extra check. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@16812 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c | 35 ++++++++++++---------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c index 35f21849ee..1d2611af30 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c +++ b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c @@ -311,30 +311,36 @@ static void otg_fifo_read_to_buffer(volatile uint32_t *fifop, * @notapi */ static void otg_rxfifo_handler(USBDriver *usbp) { - uint32_t sts, cnt, ep; + uint32_t sts, ep; + size_t n, max; /* Popping the event word out of the RX FIFO.*/ sts = usbp->otg->GRXSTSP; /* Event details.*/ - cnt = (sts & GRXSTSP_BCNT_MASK) >> GRXSTSP_BCNT_OFF; - ep = (sts & GRXSTSP_EPNUM_MASK) >> GRXSTSP_EPNUM_OFF; + n = (size_t)((sts & GRXSTSP_BCNT_MASK) >> GRXSTSP_BCNT_OFF); + ep = (sts & GRXSTSP_EPNUM_MASK) >> GRXSTSP_EPNUM_OFF; switch (sts & GRXSTSP_PKTSTS_MASK) { case GRXSTSP_SETUP_DATA: otg_fifo_read_to_buffer(usbp->otg->FIFO[0], usbp->epc[ep]->setup_buf, - cnt, 8); + n, 8); break; case GRXSTSP_SETUP_COMP: break; case GRXSTSP_OUT_DATA: + max = usbp->epc[ep]->out_state->rxsize - usbp->epc[ep]->out_state->rxcnt; otg_fifo_read_to_buffer(usbp->otg->FIFO[0], usbp->epc[ep]->out_state->rxbuf, - cnt, - usbp->epc[ep]->out_state->rxsize - - usbp->epc[ep]->out_state->rxcnt); - usbp->epc[ep]->out_state->rxbuf += cnt; - usbp->epc[ep]->out_state->rxcnt += cnt; + n, max); + if (n < max) { + usbp->epc[ep]->out_state->rxbuf += n; + usbp->epc[ep]->out_state->rxcnt += n; + } + else { + usbp->epc[ep]->out_state->rxbuf += max; + usbp->epc[ep]->out_state->rxcnt += max; + } break; case GRXSTSP_OUT_COMP: break; @@ -624,15 +630,14 @@ static void usb_lld_serve_interrupt(USBDriver *usbp) { otgp->GINTMSK &= ~GINTMSK_SOFM; } if (usbp->state == USB_SUSPENDED) { - /* If clocks are gated off, turn them back on (may be the case if - coming out of suspend mode).*/ - if (otgp->PCGCCTL & (PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK)) { - /* Set to zero to un-gate the USB core clocks.*/ - otgp->PCGCCTL &= ~(PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK); - } + /* Set to zero to un-gate the USB core clocks.*/ + otgp->PCGCCTL &= ~(PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK); _usb_wakeup(usbp); } + /* Re-enable endpoint irqs if they have been disabled by suspend before.*/ + otg_enable_ep(usbp); + _usb_isr_invoke_sof_cb(usbp); }