From 919b3e56419cfaf533030e45c536a7640a1e53e5 Mon Sep 17 00:00:00 2001 From: barthess Date: Fri, 2 Sep 2011 13:27:37 +0000 Subject: RTC. Doxy comments improvements. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3282 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/rtc_lld.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/rtc_lld.c b/os/hal/platforms/STM32/rtc_lld.c index 1ddbc0903..a6032e0a4 100644 --- a/os/hal/platforms/STM32/rtc_lld.c +++ b/os/hal/platforms/STM32/rtc_lld.c @@ -52,6 +52,8 @@ RTCDriver RTCD; * @brief Shared IRQ handler. * * @param[in] rtcp pointer to a @p RTCDriver object + * + * @notapi */ #if RTC_SUPPORTS_CALLBACKS @@ -106,6 +108,8 @@ CH_IRQ_HANDLER(RTC_IRQHandler) { /** * @brief Enable access to registers and initialize RTC if BKP domain * was previously reseted. + * + * @notapi */ void rtc_lld_init(void){ RCC->APB1ENR |= (RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN); /* enable clocking */ @@ -162,6 +166,8 @@ void rtc_lld_init(void){ * * @param[in] rtcp pointer to a @p RTCDriver object * @param[in] rtccfgp pointer to a @p RTCDriver config object + * + * @notapi */ void rtc_lld_start(RTCDriver *rtcp, const RTCConfig *rtccfgp){ uint16_t isr_flags = 0; @@ -186,6 +192,8 @@ void rtc_lld_start(RTCDriver *rtcp, const RTCConfig *rtccfgp){ /** * @brief Disable interrupt servicing routines. + * + * @notapi */ void rtc_lld_stop(void){ NVICDisableVector(RTC_IRQn); @@ -197,6 +205,8 @@ void rtc_lld_stop(void){ * @brief Set current time. * * @param[in] tv_sec time value in UNIX notation. + * + * @notapi */ void rtc_lld_set_time(uint32_t tv_sec){ @@ -214,6 +224,8 @@ void rtc_lld_set_time(uint32_t tv_sec){ /** * @brief Return current time in UNIX notation. + * + * @notapi */ inline uint32_t rtc_lld_get_sec(void){ return ((RTC->CNTH << 16) + RTC->CNTL); @@ -221,6 +233,8 @@ inline uint32_t rtc_lld_get_sec(void){ /** * @brief Return fractional part of current time (milliseconds). + * + * @notapi */ inline uint16_t rtc_lld_get_msec(void){ uint32_t time_frac = 0; @@ -230,6 +244,9 @@ inline uint16_t rtc_lld_get_msec(void){ /** * @brief Set alarm date in UNIX notation. + * @note Default value after BKP domain reset is 0xFFFFFFFF + * + * @notapi */ void rtc_lld_set_alarm(uint32_t tv_alarm){ @@ -252,7 +269,9 @@ void rtc_lld_set_alarm(uint32_t tv_alarm){ /** * @brief Get current alarm date in UNIX notation. - * @note Default value after reset is 0xFFFFFFFF + * @note Default value after BKP domain reset is 0xFFFFFFFF + * + * @notapi */ inline uint32_t rtc_lld_get_alarm(void){ return ((RTC->ALRH << 16) + RTC->ALRL); -- cgit v1.2.3 From 4e57582138fceee0792ef629715183f6647a5e93 Mon Sep 17 00:00:00 2001 From: barthess Date: Fri, 2 Sep 2011 13:32:19 +0000 Subject: I2C. Added forgotten copyrights. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3283 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/i2c_lld.c | 20 ++++++++++++++++++++ os/hal/platforms/STM32/i2c_lld.h | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index d10cb4031..48bdb3e4e 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -1,3 +1,23 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/i2c_lld.c * @brief STM32 I2C subsystem low level driver source. Slave mode not implemented. diff --git a/os/hal/platforms/STM32/i2c_lld.h b/os/hal/platforms/STM32/i2c_lld.h index 9bf56985c..548b5418e 100644 --- a/os/hal/platforms/STM32/i2c_lld.h +++ b/os/hal/platforms/STM32/i2c_lld.h @@ -1,3 +1,23 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/i2c_lld.h * @brief STM32 I2C subsystem low level driver header. -- cgit v1.2.3 From c57e9ca9981e20e50630ace1656431ad84d73852 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 3 Sep 2011 08:22:04 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3285 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/src/rtc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/src/rtc.c b/os/hal/src/rtc.c index 1341bb2dd..bd934b11b 100644 --- a/os/hal/src/rtc.c +++ b/os/hal/src/rtc.c @@ -29,8 +29,6 @@ #include "ch.h" #include "hal.h" -#include "rtc_lld.h" - #if HAL_USE_RTC || defined(__DOXYGEN__) /*===========================================================================*/ -- cgit v1.2.3 From 08dad7b1f54ff8eb6266e811533eecf53051249c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 3 Sep 2011 08:23:11 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3286 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/templates/meta/driver.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'os/hal') diff --git a/os/hal/templates/meta/driver.h b/os/hal/templates/meta/driver.h index b4b07170b..2af95b010 100644 --- a/os/hal/templates/meta/driver.h +++ b/os/hal/templates/meta/driver.h @@ -56,6 +56,11 @@ typedef enum { XXX_READY = 2, /**< Ready. */ } xxxstate_t; +/** + * @brief Type of a structure representing a XXX driver. + */ +typedef struct XXXDriver XXXDriver; + #include "xxx_lld.h" /*===========================================================================*/ -- cgit v1.2.3 From 792d85bcb5774e63100abef0125d5325312f916a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 3 Sep 2011 12:35:41 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3287 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/mac.h | 36 ++++++++++++++++- os/hal/platforms/AT91SAM7/mac_lld.c | 74 ++++++++++++++++++++++------------ os/hal/platforms/AT91SAM7/mac_lld.h | 80 +++++++++++++++++++++++++++++-------- os/hal/src/mac.c | 63 ++++++++++++++++++++++++----- 4 files changed, 198 insertions(+), 55 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/mac.h b/os/hal/include/mac.h index 37d6bbe9b..c716796f8 100644 --- a/os/hal/include/mac.h +++ b/os/hal/include/mac.h @@ -38,18 +38,48 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name MAC configuration options + * @{ + */ +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) +#define MAC_USE_EVENTS TRUE +#endif +/** @} */ + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ #if !CH_USE_SEMAPHORES || !CH_USE_EVENTS -#error "the MAC driver requires CH_USE_SEMAPHORES and CH_USE_EVENTS" +#error "the MAC driver requires CH_USE_SEMAPHORES" +#endif + +#if MAC_USE_EVENTS && !CH_USE_EVENTS +#error "the MAC driver requires CH_USE_EVENTS" #endif /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ +/** + * @brief Driver state machine possible states. + */ +typedef enum { + MAC_UNINIT = 0, /**< Not initialized. */ + MAC_STOP = 1, /**< Stopped. */ + MAC_ACTIVE = 2, /**< Active. */ +} macstate_t; + +/** + * @brief Type of a structure representing a MAC driver. + */ +typedef struct MACDriver MACDriver; + #include "mac_lld.h" /*===========================================================================*/ @@ -68,7 +98,7 @@ * * @api */ -#if CH_USE_EVENTS || defined(__DOXYGEN__) +#if MAC_USE_EVENTS || defined(__DOXYGEN__) #define macGetReceiveEventSource(macp) (&(macp)->rdevent) #endif @@ -113,6 +143,8 @@ extern "C" { #endif void macInit(void); void macObjectInit(MACDriver *macp); + void macStart(MACDriver *macp, const MACConfig *config); + void macStop(MACDriver *macp); void macSetAddress(MACDriver *macp, const uint8_t *p); msg_t macWaitTransmitDescriptor(MACDriver *macp, MACTransmitDescriptor *tdp, diff --git a/os/hal/platforms/AT91SAM7/mac_lld.c b/os/hal/platforms/AT91SAM7/mac_lld.c index 43055b94d..fc610fcc7 100644 --- a/os/hal/platforms/AT91SAM7/mac_lld.c +++ b/os/hal/platforms/AT91SAM7/mac_lld.c @@ -64,7 +64,6 @@ MACDriver ETH1; /*===========================================================================*/ #ifndef __DOXYGEN__ -static bool_t link_up; static uint8_t default_mac[] = {0xAA, 0x55, 0x13, 0x37, 0x01, 0x10}; @@ -102,7 +101,7 @@ static void serve_interrupt(void) { if (rsr & AT91C_EMAC_REC) { chSysLockFromIsr(); chSemResetI(Ð1.rdsem, 0); -#if CH_USE_EVENTS +#if MAC_USE_EVENTS chEvtBroadcastI(Ð1.rdevent); #endif chSysUnlockFromIsr(); @@ -135,6 +134,19 @@ static void cleanup(EMACDescriptor *from) { } } +/** + * @brief MAC address setup. + * + * @param[in] p pointer to a six bytes buffer containing the MAC + * address + */ +static void set_address(const uint8_t *p) { + + AT91C_BASE_EMAC->EMAC_SA1L = (AT91_REG)((p[3] << 24) | (p[2] << 16) | + (p[1] << 8) | p[0]); + AT91C_BASE_EMAC->EMAC_SA1H = (AT91_REG)((p[5] << 8) | p[4]); +} + /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ @@ -163,11 +175,34 @@ CH_IRQ_HANDLER(irq_handler) { * @notapi */ void mac_lld_init(void) { - unsigned i; miiInit(); macObjectInit(Ð1); + /* + * Associated PHY initialization. + */ + miiReset(Ð1); + + /* + * EMAC pins setup. Note, PB18 is not included because it is + * used as #PD control and not as EF100. + */ + AT91C_BASE_PIOB->PIO_ASR = EMAC_PIN_MASK; + AT91C_BASE_PIOB->PIO_PDR = EMAC_PIN_MASK; + AT91C_BASE_PIOB->PIO_PPUDR = EMAC_PIN_MASK; +} + +/** + * @brief Configures and activates the MAC peripheral. + * + * @param[in] macp pointer to the @p MACDriver object + * + * @notapi + */ +void mac_lld_start(MACDriver *macp) { + unsigned i; + /* * Buffers initialization. */ @@ -185,18 +220,9 @@ void mac_lld_init(void) { txptr = td; /* - * Associated PHY initialization. - */ - miiReset(Ð1); - - /* - * EMAC pins setup and clock enable. Note, PB18 is not included because it is - * used as #PD control and not as EF100. + * EMAC clock enable. */ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_EMAC; - AT91C_BASE_PIOB->PIO_ASR = EMAC_PIN_MASK; - AT91C_BASE_PIOB->PIO_PDR = EMAC_PIN_MASK; - AT91C_BASE_PIOB->PIO_PPUDR = EMAC_PIN_MASK; /* * EMAC Initial setup. @@ -213,7 +239,10 @@ void mac_lld_init(void) { AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TE | AT91C_EMAC_RE | AT91C_EMAC_CLRSTAT;/* Initial NCR settings.*/ - mac_lld_set_address(Ð1, default_mac); + if (macp->config->mac_address == NULL) + set_address(default_mac); + else + set_address(macp->config->mac_address); /* * PHY device identification. @@ -235,22 +264,15 @@ void mac_lld_init(void) { } /** - * @brief Low level MAC address setup. + * @brief Deactivates the MAC peripheral. * * @param[in] macp pointer to the @p MACDriver object - * @param[in] p pointer to a six bytes buffer containing the MAC - * address. If this parameter is set to @p NULL then - * a system default MAC is used. The MAC address must - * be aligned with the most significant byte first. * * @notapi */ -void mac_lld_set_address(MACDriver *macp, const uint8_t *p) { +void mac_lld_stop(MACDriver *macp) { (void)macp; - AT91C_BASE_EMAC->EMAC_SA1L = (AT91_REG)((p[3] << 24) | (p[2] << 16) | - (p[1] << 8) | p[0]); - AT91C_BASE_EMAC->EMAC_SA1H = (AT91_REG)((p[5] << 8) | p[4]); } /** @@ -272,7 +294,7 @@ msg_t max_lld_get_transmit_descriptor(MACDriver *macp, (void)macp; - if (!link_up) + if (!macp->link_up) return RDY_TIMEOUT; chSysLock(); @@ -505,7 +527,7 @@ bool_t mac_lld_poll_link_status(MACDriver *macp) { bmsr = miiGet(macp, MII_BMSR); if (!(bmsr & BMSR_LSTATUS)) { AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE; - return link_up = FALSE; + return macp->link_up = FALSE; } ncfgr = AT91C_BASE_EMAC->EMAC_NCFGR & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); @@ -525,7 +547,7 @@ bool_t mac_lld_poll_link_status(MACDriver *macp) { } AT91C_BASE_EMAC->EMAC_NCFGR = ncfgr; AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE; - return link_up = TRUE; + return macp->link_up = TRUE; } #endif /* HAL_USE_MAC */ diff --git a/os/hal/platforms/AT91SAM7/mac_lld.h b/os/hal/platforms/AT91SAM7/mac_lld.h index 9f30e0426..97a8ba2ae 100644 --- a/os/hal/platforms/AT91SAM7/mac_lld.h +++ b/os/hal/platforms/AT91SAM7/mac_lld.h @@ -128,38 +128,85 @@ typedef struct { } EMACDescriptor; /** - * @brief Structure representing a MAC driver. + * @brief Driver configuration structure. */ typedef struct { - Semaphore tdsem; /**< Transmit semaphore. */ - Semaphore rdsem; /**< Receive semaphore. */ -#if CH_USE_EVENTS - EventSource rdevent; /**< Receive event source. */ + /** + * @brief MAC address. + */ + uint8_t *mac_address; + /* End of the mandatory fields.*/ +} MACConfig; + +/** + * @brief Structure representing a MAC driver. + */ +struct MACDriver { + /** + * @brief Driver state. + */ + macstate_t state; + /** + * @brief Current configuration data. + */ + const MACConfig *config; + /** + * @brief Transmit semaphore. + */ + Semaphore tdsem; + /** + * @brief Receive semaphore. + */ + Semaphore rdsem; +#if MAC_USE_EVENTS || defined(__DOXYGEN__) + /** + * @brief Receive event. + */ + EventSource rdevent; #endif /* End of the mandatory fields.*/ -} MACDriver; + /** + * @brief Link status flag. + */ + bool_t link_up; +}; /** * @brief Structure representing a transmit descriptor. */ typedef struct { - size_t offset; /**< Current write offset. */ - size_t size; /**< Available space size. */ + /** + * @brief Current write offset. + */ + size_t offset; + /** + * @brief Available space size. + */ + size_t size; /* End of the mandatory fields.*/ - EMACDescriptor *physdesc; /**< Pointer to the physical - descriptor. */ + /** + * @brief Pointer to the physical descriptor. + */ + EMACDescriptor *physdesc; } MACTransmitDescriptor; /** * @brief Structure representing a receive descriptor. */ typedef struct { - size_t offset; /**< Current read offset. */ - size_t size; /**< Available data size. */ + /** + * @brief Current read offset. + */ + size_t offset; + /** + * @brief Available data size. + */ + size_t size; /* End of the mandatory fields.*/ - EMACDescriptor *physdesc; /**< Pointer to the first - descriptor of the buffers - chain. */ + /** + * @brief Pointer to the first descriptor of the buffers chain. + */ + EMACDescriptor *physdesc; } MACReceiveDescriptor; /*===========================================================================*/ @@ -178,7 +225,8 @@ extern MACDriver ETH1; extern "C" { #endif void mac_lld_init(void); - void mac_lld_set_address(MACDriver *macp, const uint8_t *p); + void mac_lld_start(MACDriver *macp); + void mac_lld_stop(MACDriver *macp); msg_t max_lld_get_transmit_descriptor(MACDriver *macp, MACTransmitDescriptor *tdp); size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp, diff --git a/os/hal/src/mac.c b/os/hal/src/mac.c index 0f1c47576..edd15d087 100644 --- a/os/hal/src/mac.c +++ b/os/hal/src/mac.c @@ -21,8 +21,6 @@ /** * @file mac.c * @brief MAC Driver code. - * @note This function is implicitly invoked by @p halInit(), there is - * no need to explicitly initialize the driver. * * @addtogroup MAC * @{ @@ -59,6 +57,8 @@ /** * @brief MAC Driver initialization. + * @note This function is implicitly invoked by @p halInit(), there is + * no need to explicitly initialize the driver. * * @init */ @@ -76,28 +76,53 @@ void macInit(void) { */ void macObjectInit(MACDriver *macp) { + macp->state = MAC_STOP; + macp->config = NULL; chSemInit(&macp->tdsem, 0); chSemInit(&macp->rdsem, 0); -#if CH_USE_EVENTS +#if MAC_USE_EVENTS chEvtInit(&macp->rdevent); #endif } /** - * @brief MAC address setup. - * @pre This function must be invoked with the driver in the stopped - * state. If invoked on an active interface then it is ignored. + * @brief Configures and activates the MAC peripheral. + * + * @param[in] macp pointer to the @p MACDriver object + * @param[in] config pointer to the @p MACConfig object + * + * @api + */ +void macStart(MACDriver *macp, const MACConfig *config) { + + chDbgCheck((macp != NULL) && (config != NULL), "macStart"); + + chSysLock(); + chDbgAssert(macp->state == MAC_STOP, + "macStart(), #1", "invalid state"); + macp->config = config; + mac_lld_start(macp); + macp->state = MAC_ACTIVE; + chSysUnlock(); +} + +/** + * @brief Deactivates the MAC peripheral. * * @param[in] macp pointer to the @p MACDriver object - * @param[in] p pointer to a six bytes buffer containing the MAC - * address. If this parameter is set to @p NULL then MAC - * a system default is used. * * @api */ -void macSetAddress(MACDriver *macp, const uint8_t *p) { +void macStop(MACDriver *macp) { + + chDbgCheck(macp != NULL, "macStop"); - mac_lld_set_address(macp, p); + chSysLock(); + chDbgAssert((macp->state == MAC_STOP) || (macp->state == MAC_ACTIVE), + "macStop(), #1", "invalid state"); + mac_lld_stop(macp); + macp->state = MAC_STOP; + chSysUnlock(); } /** @@ -124,6 +149,10 @@ msg_t macWaitTransmitDescriptor(MACDriver *macp, systime_t time) { msg_t msg; + chDbgCheck((macp != NULL) && (tdp != NULL), "macWaitTransmitDescriptor"); + chDbgAssert(macp->state == MAC_ACTIVE, "macWaitTransmitDescriptor(), #1", + "not active"); + while (((msg = max_lld_get_transmit_descriptor(macp, tdp)) != RDY_OK) && (time > 0)) { chSysLock(); @@ -149,6 +178,8 @@ msg_t macWaitTransmitDescriptor(MACDriver *macp, */ void macReleaseTransmitDescriptor(MACTransmitDescriptor *tdp) { + chDbgCheck((tdp != NULL), "macReleaseTransmitDescriptor"); + mac_lld_release_transmit_descriptor(tdp); } @@ -176,6 +207,10 @@ msg_t macWaitReceiveDescriptor(MACDriver *macp, systime_t time) { msg_t msg; + chDbgCheck((macp != NULL) && (rdp != NULL), "macWaitReceiveDescriptor"); + chDbgAssert(macp->state == MAC_ACTIVE, "macWaitReceiveDescriptor(), #1", + "not active"); + while (((msg = max_lld_get_receive_descriptor(macp, rdp)) != RDY_OK) && (time > 0)) { chSysLock(); @@ -202,6 +237,8 @@ msg_t macWaitReceiveDescriptor(MACDriver *macp, */ void macReleaseReceiveDescriptor(MACReceiveDescriptor *rdp) { + chDbgCheck((rdp != NULL), "macReleaseReceiveDescriptor"); + mac_lld_release_receive_descriptor(rdp); } @@ -217,6 +254,10 @@ void macReleaseReceiveDescriptor(MACReceiveDescriptor *rdp) { */ bool_t macPollLinkStatus(MACDriver *macp) { + chDbgCheck((macp != NULL), "macPollLinkStatus"); + chDbgAssert(macp->state == MAC_ACTIVE, "macPollLinkStatus(), #1", + "not active"); + return mac_lld_poll_link_status(macp); } -- cgit v1.2.3 From d15f612b861af72fffb8ee2e4f3b95e991bfcf10 Mon Sep 17 00:00:00 2001 From: barthess Date: Sat, 3 Sep 2011 18:25:04 +0000 Subject: RTC. Tiny improvement in documentation. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3288 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/src/rtc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'os/hal') diff --git a/os/hal/src/rtc.c b/os/hal/src/rtc.c index bd934b11b..8f9025364 100644 --- a/os/hal/src/rtc.c +++ b/os/hal/src/rtc.c @@ -53,6 +53,9 @@ /** * @brief Enable access to registers and initialize RTC if BKP doamin * was previously reseted. + * + * @note This function is implicitly invoked by @p halInit(), there is + * no need to explicitly initialize the driver. */ void rtcInit(void){ rtc_lld_init(); -- cgit v1.2.3 From c14c1959b1186bc79dd223f0a744a8220874bc5a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 5 Sep 2011 15:05:12 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3290 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/mac_lld.c | 260 +++++++++++++++++++++++++++++++++++++++ os/hal/platforms/STM32/mac_lld.h | 200 ++++++++++++++++++++++++++++++ os/hal/templates/mac_lld.c | 53 +++++--- os/hal/templates/mac_lld.h | 73 ++++++++--- 4 files changed, 549 insertions(+), 37 deletions(-) create mode 100644 os/hal/platforms/STM32/mac_lld.c create mode 100644 os/hal/platforms/STM32/mac_lld.h (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/mac_lld.c b/os/hal/platforms/STM32/mac_lld.c new file mode 100644 index 000000000..37ca9e106 --- /dev/null +++ b/os/hal/platforms/STM32/mac_lld.c @@ -0,0 +1,260 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/mac_lld.c + * @brief STM32 low level MAC driver code. + * + * @addtogroup MAC + * @{ + */ + +#include "ch.h" +#include "hal.h" +#include "mii.h" +# +#if HAL_USE_MAC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define BUFFER_SLICE ((((MAC_BUFFERS_SIZE - 1) | 3) + 1) / 4) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief Ethernet driver 1. + */ +MACDriver ETH1; + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +static stm32_eth_rx_descriptor_t *rxptr; +static stm32_eth_tx_descriptor_t *txptr; + +static stm32_eth_rx_descriptor_t rd[MAC_RECEIVE_BUFFERS]; +static stm32_eth_tx_descriptor_t td[MAC_TRANSMIT_BUFFERS]; + +static uint32_t rb[MAC_RECEIVE_BUFFERS * BUFFER_SLICE]; +static uint32_t tb[MAC_TRANSMIT_BUFFERS * BUFFER_SLICE]; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level MAC initialization. + * + * @notapi + */ +void mac_lld_init(void) { + unsigned i; + + macObjectInit(Ð1); + + /* Descriptor tables are initialized in linked mode, note that the first + word is not initialized here but in mac_lld_start().*/ + for (i = 0; i < MAC_RECEIVE_BUFFERS; i++) { + rd[i].rdes1 = RDES1_RCH | MAC_BUFFERS_SIZE; + rd[i].rdes2 = (uint32_t)&rb[i * BUFFER_SLICE]; + rd[i].rdes3 = (uint32_t)&rb[((i + 1) % MAC_RECEIVE_BUFFERS) * + BUFFER_SLICE]; + } + for (i = 0; i < MAC_TRANSMIT_BUFFERS; i++) { + td[i].tdes1 = 0; + td[i].tdes2 = (uint32_t)&tb[i * BUFFER_SLICE]; + td[i].tdes3 = (uint32_t)&tb[((i + 1) % MAC_TRANSMIT_BUFFERS) * + BUFFER_SLICE]; + } +} + +/** + * @brief Configures and activates the MAC peripheral. + * + * @param[in] macp pointer to the @p MACDriver object + * + * @notapi + */ +void mac_lld_start(MACDriver *macp) { + unsigned i; + + /* Resets the state of all descriptors.*/ + for (i = 0; i < MAC_RECEIVE_BUFFERS; i++) + rd[i].rdes0 = RDES0_OWN; + rxptr = (stm32_eth_rx_descriptor_t *)rd; + for (i = 0; i < MAC_TRANSMIT_BUFFERS; i++) + td[i].tdes0 = TDES0_TCH; + txptr = (stm32_eth_tx_descriptor_t *)td; + + /* Soft reset of the MAC core and wait until the reset is complete.*/ + ETH->DMABMR |= ETH_DMABMR_SR; + while (ETH->DMABMR & ETH_DMABMR_SR) + ; + + /* Descriptor chains pointers.*/ + ETH->DMARDLAR = (uint32_t)rd; + ETH->DMATDLAR = (uint32_t)rd; + + /* Clear DMA status.*/ +} + +/** + * @brief Deactivates the MAC peripheral. + * + * @param[in] macp pointer to the @p MACDriver object + * + * @notapi + */ +void mac_lld_stop(MACDriver *macp) { + +} + +/** + * @brief Returns a transmission descriptor. + * @details One of the available transmission descriptors is locked and + * returned. + * + * @param[in] macp pointer to the @p MACDriver object + * @param[out] tdp pointer to a @p MACTransmitDescriptor structure + * @return The operation status. + * @retval RDY_OK the descriptor has been obtained. + * @retval RDY_TIMEOUT descriptor not available. + * + * @notapi + */ +msg_t max_lld_get_transmit_descriptor(MACDriver *macp, + MACTransmitDescriptor *tdp) { + + return RDY_OK; +} + +/** + * @brief Writes to a transmit descriptor's stream. + * + * @param[in] tdp pointer to a @p MACTransmitDescriptor structure + * @param[in] buf pointer to the buffer cointaining the data to be + * written + * @param[in] size number of bytes to be written + * @return The number of bytes written into the descriptor's + * stream, this value can be less than the amount + * specified in the parameter @p size if the maximum + * frame size is reached. + * + * @notapi + */ +size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp, + uint8_t *buf, + size_t size) { + + return 0; +} + +/** + * @brief Releases a transmit descriptor and starts the transmission of the + * enqueued data as a single frame. + * + * @param[in] tdp the pointer to the @p MACTransmitDescriptor structure + * + * @notapi + */ +void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) { + +} + +/** + * @brief Returns a receive descriptor. + * + * @param[in] macp pointer to the @p MACDriver object + * @param[out] rdp pointer to a @p MACReceiveDescriptor structure + * @return The operation status. + * @retval RDY_OK the descriptor has been obtained. + * @retval RDY_TIMEOUT descriptor not available. + * + * @notapi + */ +msg_t max_lld_get_receive_descriptor(MACDriver *macp, + MACReceiveDescriptor *rdp) { + + return RDY_TIMEOUT; +} + +/** + * @brief Reads from a receive descriptor's stream. + * + * @param[in] rdp pointer to a @p MACReceiveDescriptor structure + * @param[in] buf pointer to the buffer that will receive the read data + * @param[in] size number of bytes to be read + * @return The number of bytes read from the descriptor's + * stream, this value can be less than the amount + * specified in the parameter @p size if there are + * no more bytes to read. + * + * @notapi + */ +size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp, + uint8_t *buf, + size_t size) { + + return 0; +} + +/** + * @brief Releases a receive descriptor. + * @details The descriptor and its buffer are made available for more incoming + * frames. + * + * @param[in] rdp the pointer to the @p MACReceiveDescriptor structure + * + * @notapi + */ +void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) { + +} + +/** + * @brief Updates and returns the link status. + * + * @param[in] macp pointer to the @p MACDriver object + * @return The link status. + * @retval TRUE if the link is active. + * @retval FALSE if the link is down. + * + * @notapi + */ +bool_t mac_lld_poll_link_status(MACDriver *macp) { + +} + +#endif /* HAL_USE_MAC */ + +/** @} */ diff --git a/os/hal/platforms/STM32/mac_lld.h b/os/hal/platforms/STM32/mac_lld.h new file mode 100644 index 000000000..8647bd296 --- /dev/null +++ b/os/hal/platforms/STM32/mac_lld.h @@ -0,0 +1,200 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/mac_lld.h + * @brief STM32 low level MAC driver header. + * + * @addtogroup MAC + * @{ + */ + +#ifndef _MAC_LLD_H_ +#define _MAC_LLD_H_ + +#if HAL_USE_MAC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @brief Number of available transmit buffers. + */ +#if !defined(MAC_TRANSMIT_BUFFERS) || defined(__DOXYGEN__) +#define MAC_TRANSMIT_BUFFERS 2 +#endif + +/** + * @brief Number of available receive buffers. + */ +#if !defined(MAC_RECEIVE_BUFFERS) || defined(__DOXYGEN__) +#define MAC_RECEIVE_BUFFERS 2 +#endif + +/** + * @brief Maximum supported frame size. + */ +#if !defined(MAC_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define MAC_BUFFERS_SIZE 1518 +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of an STM32 Ethernet receive descriptor. + */ +typedef struct { + volatile uint32_t rdes0; + volatile uint32_t rdes1; + volatile uint32_t rdes2; + volatile uint32_t rdes3; +} stm32_eth_rx_descriptor_t; + +/** + * @brief Type of an STM32 Ethernet transmit descriptor. + */ +typedef struct { + volatile uint32_t tdes0; + volatile uint32_t tdes1; + volatile uint32_t tdes2; + volatile uint32_t tdes3; +} stm32_eth_tx_descriptor_t; + +/** + * @brief Driver configuration structure. + */ +typedef struct { + /** + * @brief MAC address. + */ + uint8_t *mac_address; + /* End of the mandatory fields.*/ +} MACConfig; + +/** + * @brief Structure representing a MAC driver. + */ +struct MACDriver { + /** + * @brief Driver state. + */ + macstate_t state; + /** + * @brief Current configuration data. + */ + const MACConfig *config; + /** + * @brief Transmit semaphore. + */ + Semaphore tdsem; + /** + * @brief Receive semaphore. + */ + Semaphore rdsem; +#if MAC_USE_EVENTS || defined(__DOXYGEN__) + /** + * @brief Receive event. + */ + EventSource rdevent; +#endif + /* End of the mandatory fields.*/ +}; + +/** + * @brief Structure representing a transmit descriptor. + */ +typedef struct { + /** + * @brief Current write offset. + */ + size_t offset; + /** + * @brief Available space size. + */ + size_t size; + /* End of the mandatory fields.*/ +} MACTransmitDescriptor; + +/** + * @brief Structure representing a receive descriptor. + */ +typedef struct { + /** + * @brief Current read offset. + */ + size_t offset; + /** + * @brief Available data size. + */ + size_t size; + /* End of the mandatory fields.*/ +} MACReceiveDescriptor; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern MACDriver ETH1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void mac_lld_init(void); + void mac_lld_start(MACDriver *macp); + void mac_lld_stop(MACDriver *macp); + msg_t max_lld_get_transmit_descriptor(MACDriver *macp, + MACTransmitDescriptor *tdp); + size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp, + uint8_t *buf, + size_t size); + void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp); + msg_t max_lld_get_receive_descriptor(MACDriver *macp, + MACReceiveDescriptor *rdp); + size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp, + uint8_t *buf, + size_t size); + void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp); + bool_t mac_lld_poll_link_status(MACDriver *macp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_MAC */ + +#endif /* _MAC_LLD_H_ */ + +/** @} */ diff --git a/os/hal/templates/mac_lld.c b/os/hal/templates/mac_lld.c index 62b8765d0..ecd7f82bd 100644 --- a/os/hal/templates/mac_lld.c +++ b/os/hal/templates/mac_lld.c @@ -39,6 +39,11 @@ /* Driver exported variables. */ /*===========================================================================*/ +/** + * @brief Ethernet driver 1. + */ +MACDriver ETH1; + /*===========================================================================*/ /* Driver local variables. */ /*===========================================================================*/ @@ -65,16 +70,24 @@ void mac_lld_init(void) { } /** - * @brief Low level MAC address setup. + * @brief Configures and activates the MAC peripheral. * * @param[in] macp pointer to the @p MACDriver object - * @param[in] p pointer to a six bytes buffer containing the MAC - * address. If this parameter is set to @p NULL then - * a system default MAC is used. * * @notapi */ -void mac_lld_set_address(MACDriver *macp, const uint8_t *p) { +void mac_lld_start(MACDriver *macp) { + +} + +/** + * @brief Deactivates the MAC peripheral. + * + * @param[in] macp pointer to the @p MACDriver object + * + * @notapi + */ +void mac_lld_stop(MACDriver *macp) { } @@ -86,7 +99,7 @@ void mac_lld_set_address(MACDriver *macp, const uint8_t *p) { * @param[in] macp pointer to the @p MACDriver object * @param[out] tdp pointer to a @p MACTransmitDescriptor structure * @return The operation status. - * @retval RDY_OK a descriptor was obtained. + * @retval RDY_OK the descriptor has been obtained. * @retval RDY_TIMEOUT descriptor not available. * * @notapi @@ -101,7 +114,7 @@ msg_t max_lld_get_transmit_descriptor(MACDriver *macp, * @brief Writes to a transmit descriptor's stream. * * @param[in] tdp pointer to a @p MACTransmitDescriptor structure - * @param[in] buf pointer to the buffer containing the data to be + * @param[in] buf pointer to the buffer cointaining the data to be * written * @param[in] size number of bytes to be written * @return The number of bytes written into the descriptor's @@ -122,7 +135,7 @@ size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp, * @brief Releases a transmit descriptor and starts the transmission of the * enqueued data as a single frame. * - * @param[in] tdp pointer to a @p MACTransmitDescriptor structure + * @param[in] tdp the pointer to the @p MACTransmitDescriptor structure * * @notapi */ @@ -133,10 +146,10 @@ void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) { /** * @brief Returns a receive descriptor. * - * @param[in] macp pointer to a @p MACDriver object + * @param[in] macp pointer to the @p MACDriver object * @param[out] rdp pointer to a @p MACReceiveDescriptor structure * @return The operation status. - * @retval RDY_OK a descriptor was obtained. + * @retval RDY_OK the descriptor has been obtained. * @retval RDY_TIMEOUT descriptor not available. * * @notapi @@ -144,18 +157,19 @@ void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) { msg_t max_lld_get_receive_descriptor(MACDriver *macp, MACReceiveDescriptor *rdp) { - return RDY_OK; + return RDY_TIMEOUT; } /** * @brief Reads from a receive descriptor's stream. * - * @param[in] rdp pointer to a @p MACReceiveDescriptor structure - * @param[in] buf pointer to a buffer that will receive the read data - * @param[in] size number of bytes to be read - * @return The number of bytes read from the descriptor's stream, - * this value can be less than the amount specified in - * the parameter @p size if there are no more bytes to read. + * @param[in] rdp pointer to a @p MACReceiveDescriptor structure + * @param[in] buf pointer to the buffer that will receive the read data + * @param[in] size number of bytes to be read + * @return The number of bytes read from the descriptor's + * stream, this value can be less than the amount + * specified in the parameter @p size if there are + * no more bytes to read. * * @notapi */ @@ -171,7 +185,7 @@ size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp, * @details The descriptor and its buffer are made available for more incoming * frames. * - * @param[in] rdp pointer to a @p MACReceiveDescriptor structure + * @param[in] rdp the pointer to the @p MACReceiveDescriptor structure * * @notapi */ @@ -182,7 +196,7 @@ void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) { /** * @brief Updates and returns the link status. * - * @param[in] macp pointer to a @p MACDriver object + * @param[in] macp pointer to the @p MACDriver object * @return The link status. * @retval TRUE if the link is active. * @retval FALSE if the link is down. @@ -191,7 +205,6 @@ void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) { */ bool_t mac_lld_poll_link_status(MACDriver *macp) { - return FALSE; } #endif /* HAL_USE_MAC */ diff --git a/os/hal/templates/mac_lld.h b/os/hal/templates/mac_lld.h index e103128a9..765ac247e 100644 --- a/os/hal/templates/mac_lld.h +++ b/os/hal/templates/mac_lld.h @@ -48,38 +48,72 @@ /*===========================================================================*/ /** - * @brief Structure representing a MAC driver. - * @note Implementations may extend this structure to contain more, - * architecture dependent, fields. + * @brief Driver configuration structure. */ typedef struct { - Semaphore tdsem; /**< Transmit semaphore. */ - Semaphore rdsem; /**< Receive semaphore. */ -#if CH_USE_EVENTS - EventSource rdevent; /**< Receive event source. */ + /** + * @brief MAC address. + */ + uint8_t *mac_address; + /* End of the mandatory fields.*/ +} MACConfig; + +/** + * @brief Structure representing a MAC driver. + */ +struct MACDriver { + /** + * @brief Driver state. + */ + macstate_t state; + /** + * @brief Current configuration data. + */ + const MACConfig *config; + /** + * @brief Transmit semaphore. + */ + Semaphore tdsem; + /** + * @brief Receive semaphore. + */ + Semaphore rdsem; +#if MAC_USE_EVENTS || defined(__DOXYGEN__) + /** + * @brief Receive event. + */ + EventSource rdevent; #endif /* End of the mandatory fields.*/ -} MACDriver; +}; /** * @brief Structure representing a transmit descriptor. - * @note Implementations may extend this structure to contain more, - * architecture dependent, fields. */ typedef struct { - size_t offset; /**< Current write offset. */ - size_t size; /**< Available space size. */ + /** + * @brief Current write offset. + */ + size_t offset; + /** + * @brief Available space size. + */ + size_t size; /* End of the mandatory fields.*/ } MACTransmitDescriptor; /** * @brief Structure representing a receive descriptor. - * @note Implementations may extend this structure to contain more, - * architecture dependent, fields. */ typedef struct { - size_t offset; /**< Current read offset. */ - size_t size; /**< Available data size. */ + /** + * @brief Current read offset. + */ + size_t offset; + /** + * @brief Available data size. + */ + size_t size; /* End of the mandatory fields.*/ } MACReceiveDescriptor; @@ -91,11 +125,16 @@ typedef struct { /* External declarations. */ /*===========================================================================*/ +#if !defined(__DOXYGEN__) +extern MACDriver ETH1; +#endif + #ifdef __cplusplus extern "C" { #endif void mac_lld_init(void); - void mac_lld_set_address(MACDriver *macp, const uint8_t *p); + void mac_lld_start(MACDriver *macp); + void mac_lld_stop(MACDriver *macp); msg_t max_lld_get_transmit_descriptor(MACDriver *macp, MACTransmitDescriptor *tdp); size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp, -- cgit v1.2.3 From b8ad6dbae6914316f731c99324ccb5052018dfbf Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 6 Sep 2011 14:59:00 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3292 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/mii.h | 1 + os/hal/platforms/STM32/mac_lld.c | 68 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/include/mii.h b/os/hal/include/mii.h index 89ba69810..969f4a9d5 100644 --- a/os/hal/include/mii.h +++ b/os/hal/include/mii.h @@ -178,6 +178,7 @@ #define MII_DM9161_ID 0x0181b8a0 #define MII_AM79C875_ID 0x00225540 #define MII_KS8721_ID 0x00221610 +#define MII_STE101P_ID 0x00061C50 #endif /* _MII_H_ */ diff --git a/os/hal/platforms/STM32/mac_lld.c b/os/hal/platforms/STM32/mac_lld.c index 37ca9e106..01a28a8b4 100644 --- a/os/hal/platforms/STM32/mac_lld.c +++ b/os/hal/platforms/STM32/mac_lld.c @@ -29,7 +29,7 @@ #include "ch.h" #include "hal.h" #include "mii.h" -# + #if HAL_USE_MAC || defined(__DOXYGEN__) /*===========================================================================*/ @@ -38,6 +38,20 @@ #define BUFFER_SLICE ((((MAC_BUFFERS_SIZE - 1) | 3) + 1) / 4) +/* MII divider optimal value.*/ +#if (STM32_HCLK >= 60000000) +#define MACMIIDR_CR ETH_MACMIIAR_CR_Div42 +#elif (STM32_HCLK >= 35000000) +#define MACMIIDR_CR ETH_MACMIIAR_CR_Div26 +#elif (STM32_HCLK >= 20000000) +#define MACMIIDR_CR ETH_MACMIIAR_CR_Div16 +#else +#error "STM32_HCLK below minimum frequency for ETH operations (20MHz)" +#endif + +/* PHY address.*/ +#define MACMIIDR_PA (32 << 11) + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -64,6 +78,55 @@ static uint32_t tb[MAC_TRANSMIT_BUFFERS * BUFFER_SLICE]; /* Driver local functions. */ /*===========================================================================*/ +/** + * @brief Writes a PHY register. + * + * @param[in] reg register number + * @param[in] value new register value + */ +static void mii_write_phy(uint16_t reg, uint16_t value) { + uint32_t miiar; + + miiar = ETH->MACMIIAR | ETH_MACMIIAR_MW | ETH_MACMIIAR_MB; + miiar = (miiar & ~ETH_MACMIIAR_MR) | (reg << 6); + ETH->MACMIIDR = value; + ETH->MACMIIAR = miiar; + while ((ETH->MACMIIAR & ETH_MACMIIAR_MB) != 0) + ; +} + +/** + * @brief Reads a PHY register. + * + * @param[in] reg register number + */ +static uint16_t mii_read_phy(uint16_t reg) { + uint32_t miiar; + + miiar = ETH->MACMIIAR | ETH_MACMIIAR_MB; + miiar = (miiar & ~(ETH_MACMIIAR_MR | ETH_MACMIIAR_MW)) | (reg << 6); + ETH->MACMIIAR = miiar; + while ((ETH->MACMIIAR & ETH_MACMIIAR_MB) != 0) + ; + return (uint16_t)ETH->MACMIIDR; +} + +/** + * @brief MII/RMII interface initialization. + */ +static void mii_init(void) { + uint32_t i; + + for (i = 0; i < 31; i++) { + ETH->MACMIIDR = (i << 6) | MACMIIDR_CR; + if ((mii_read_phy(MII_PHYSID1) == (PHY_ID >> 16)) && + (mii_read_phy(MII_PHYSID2) == (PHY_ID & 0xFFF0))) + return; + } + /* Wrong or defective board.*/ + chSysHalt(); +} + /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ @@ -121,6 +184,9 @@ void mac_lld_start(MACDriver *macp) { while (ETH->DMABMR & ETH_DMABMR_SR) ; + /* MII initialization.*/ + mii_init(); + /* Descriptor chains pointers.*/ ETH->DMARDLAR = (uint32_t)rd; ETH->DMATDLAR = (uint32_t)rd; -- cgit v1.2.3 From d0771593893ef9f8a9ae4ab689c569b88e3631a9 Mon Sep 17 00:00:00 2001 From: barthess Date: Wed, 7 Sep 2011 12:53:27 +0000 Subject: RTC. rtcStart() and rtcStop() functions replaced by rtcSetCallback() git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3293 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/rtc.h | 7 +--- os/hal/platforms/STM32/rtc_lld.c | 87 +++++++++++++++++++++++++--------------- os/hal/platforms/STM32/rtc_lld.h | 22 ++++------ os/hal/src/rtc.c | 29 ++++++-------- 4 files changed, 77 insertions(+), 68 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/rtc.h b/os/hal/include/rtc.h index 0c545c3a6..e0a2c50c5 100644 --- a/os/hal/include/rtc.h +++ b/os/hal/include/rtc.h @@ -70,11 +70,8 @@ extern "C" { void rtcInit(void); #if RTC_SUPPORTS_CALLBACKS - void rtcStart(RTCDriver *rtcp, const RTCConfig *rtccfgp); - void rtcStop(void); - #else /* RTC_SUPPORTS_CALLBACKS */ - #define rtcStart(rtcp, rtccfgp) - #define rtcStop() + void rtcSetCallback(RTCDriver *rtcp, rtccb_t overflowcb, + rtccb_t secondcb, rtccb_t alarmcb); #endif /* RTC_SUPPORTS_CALLBACKS */ void rtcSetTime(uint32_t tv_sec); diff --git a/os/hal/platforms/STM32/rtc_lld.c b/os/hal/platforms/STM32/rtc_lld.c index a6032e0a4..4f404ab27 100644 --- a/os/hal/platforms/STM32/rtc_lld.c +++ b/os/hal/platforms/STM32/rtc_lld.c @@ -62,20 +62,20 @@ static void rtc_lld_serve_interrupt(RTCDriver *rtcp){ if ((RTC->CRH & RTC_CRH_SECIE) && \ (RTC->CRL & RTC_CRL_SECF) && \ - (rtcp->config->second_cb != NULL)){ - rtcp->config->second_cb(rtcp); + (rtcp->second_cb != NULL)){ + rtcp->second_cb(rtcp); RTC->CRL &= ~RTC_CRL_SECF; } if ((RTC->CRH & RTC_CRH_ALRIE) && \ (RTC->CRL & RTC_CRL_ALRF) && \ - (rtcp->config->alarm_cb != NULL)){ - rtcp->config->alarm_cb(rtcp); + (rtcp->alarm_cb != NULL)){ + rtcp->alarm_cb(rtcp); RTC->CRL &= ~RTC_CRL_ALRF; } if ((RTC->CRH & RTC_CRH_OWIE) && \ (RTC->CRL & RTC_CRL_OWF) && \ - (rtcp->config->overflow_cb != NULL)){ - rtcp->config->overflow_cb(rtcp); + (rtcp->overflow_cb != NULL)){ + rtcp->overflow_cb(rtcp); RTC->CRL &= ~RTC_CRL_OWF; } @@ -157,49 +157,72 @@ void rtc_lld_init(void){ RTC->CRH &= ~(RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE); RTC->CRL &= ~(RTC_CRL_SECF | RTC_CRL_ALRF | RTC_CRL_OWF); - RTCD.config = NULL; +#if RTC_SUPPORTS_CALLBACKS + RTCD.alarm_cb = NULL; + RTCD.overflow_cb = NULL; + RTCD.second_cb = NULL; +#endif /* RTC_SUPPORTS_CALLBACKS */ } /** - * @brief Configure and start interrupt servicing routines. - * This function do nothing if callbacks disabled. + * @brief Enables and disables callbacks on the fly. * - * @param[in] rtcp pointer to a @p RTCDriver object - * @param[in] rtccfgp pointer to a @p RTCDriver config object + * @details Pass callback function(s) in argument(s) to enable callback(s). + * Pass NULL to disable callback. + * + * @pre To use this function you must set @p RTC_SUPPORTS_CALLBACKS + * to @p TRUE. + * + * @param[in] rtcp pointer to RTC driver structure. + * @param[in] overflowcb overflow callback function. + * @param[in] secondcb every second callback function. + * @param[in] alarmcb alarm callback function. * * @notapi */ -void rtc_lld_start(RTCDriver *rtcp, const RTCConfig *rtccfgp){ - uint16_t isr_flags = 0; +#if RTC_SUPPORTS_CALLBACKS +void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t overflowcb, + rtccb_t secondcb, rtccb_t alarmcb){ - NVICEnableVector(RTC_IRQn, CORTEX_PRIORITY_MASK(STM32_RTC_IRQ_PRIORITY)); + uint16_t isr_flags = 0; - rtcp->config = rtccfgp; - if (rtcp->config->overflow_cb != NULL){ + if (overflowcb != NULL){ + rtcp->overflow_cb = *overflowcb; isr_flags |= RTC_CRH_OWIE; } - if (rtcp->config->alarm_cb != NULL){ + else{ + rtcp->overflow_cb = NULL; + isr_flags &= ~RTC_CRH_OWIE; + } + + if (alarmcb != NULL){ + rtcp->alarm_cb = *alarmcb; isr_flags |= RTC_CRH_ALRIE; } - if (rtcp->config->second_cb != NULL){ - isr_flags |= RTC_CRH_SECIE; + else{ + rtcp->alarm_cb = NULL; + isr_flags &= ~RTC_CRH_ALRIE; } - /* clear all event flags just to be safe */ - RTC->CRL &= ~(RTC_CRL_SECF | RTC_CRL_ALRF | RTC_CRL_OWF); - RTC->CRH |= isr_flags; -} + if (secondcb != NULL){ + rtcp->second_cb = *secondcb; + isr_flags |= RTC_CRH_SECIE; + } + else{ + rtcp->second_cb = NULL; + isr_flags &= ~RTC_CRH_SECIE; + } -/** - * @brief Disable interrupt servicing routines. - * - * @notapi - */ -void rtc_lld_stop(void){ - NVICDisableVector(RTC_IRQn); - RTC->CRH = 0; + if(isr_flags != 0){ + NVICEnableVector(RTC_IRQn, CORTEX_PRIORITY_MASK(STM32_RTC_IRQ_PRIORITY)); + RTC->CRH |= isr_flags; + } + else{ + NVICDisableVector(RTC_IRQn); + RTC->CRH = 0; + } } - +#endif /* RTC_SUPPORTS_CALLBACKS */ /** * @brief Set current time. diff --git a/os/hal/platforms/STM32/rtc_lld.h b/os/hal/platforms/STM32/rtc_lld.h index 3b4f69665..2ec4427d5 100644 --- a/os/hal/platforms/STM32/rtc_lld.h +++ b/os/hal/platforms/STM32/rtc_lld.h @@ -66,10 +66,12 @@ /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ + /** - * @brief Structure representing an RTC driver config. + * @brief Structure representing an RTC driver. */ -typedef struct { +struct RTCDriver{ +#if RTC_SUPPORTS_CALLBACKS /** * @brief Overflow callback. Set it to NULL if not used. */ @@ -84,17 +86,7 @@ typedef struct { * @brief Alarm callback. Set it to NULL if not used. */ rtccb_t alarm_cb; -}RTCConfig; - - -/** - * @brief Structure representing an RTC driver. - */ -struct RTCDriver{ - /** - * @brief Pointer to RCT config. - */ - const RTCConfig *config; +#endif /* RTC_SUPPORTS_CALLBACKS */ }; /*===========================================================================*/ @@ -112,8 +104,8 @@ extern RTCDriver RTCD; extern "C" { #endif void rtc_lld_init(void); - void rtc_lld_start(RTCDriver *rtcp, const RTCConfig *rtccfgp); - void rtc_lld_stop(void); + void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t overflow_cb, + rtccb_t second_cb, rtccb_t alarm_cb); void rtc_lld_set_time(uint32_t tv_sec); uint32_t rtc_lld_get_sec(void); uint16_t rtc_lld_get_msec(void); diff --git a/os/hal/src/rtc.c b/os/hal/src/rtc.c index 8f9025364..ab916cf52 100644 --- a/os/hal/src/rtc.c +++ b/os/hal/src/rtc.c @@ -61,26 +61,23 @@ void rtcInit(void){ rtc_lld_init(); } +#if RTC_SUPPORTS_CALLBACKS /** - * @brief Configure and start interrupt servicing routines. - * This function do nothing if callbacks disabled. + * @brief Enables and disables callbacks on the fly. + * @details Pass callback function(s) in argument(s) to enable callback(s). + * Pass NULL to disable callback. + * @pre To use this function you must set @p RTC_SUPPORTS_CALLBACKS + * to @p TRUE. * * @param[in] rtcp - pointer to RTC driver structure. - * @param[in] rtccfgp - pointer to RTC config structure. - */ -#if RTC_SUPPORTS_CALLBACKS -void rtcStartI(RTCDriver *rtcp, const RTCConfig *rtccfgp){ - chDbgCheckClassI(); - chDbgCheck(((rtcp != NULL) && (rtccfgp != NULL)), "rtcStart"); - rtc_lld_start(rtcp, rtccfgp); -} - -/** - * @brief Stop interrupt servicing routines. + * @param[in] overflowcb - overflow callback function. + * @param[in] secondcb - every second callback function. + * @param[in] alarmcb - alarm callback function. */ -void rtcStopI(void){ - chDbgCheckClassI(); - rtc_lld_stop(); +void rtcSetCallback(RTCDriver *rtcp, rtccb_t overflowcb, + rtccb_t secondcb, rtccb_t alarmcb){ + chDbgCheck((rtcp != NULL), "rtcStart"); + rtc_lld_set_callback(rtcp, overflowcb, secondcb, alarmcb); } #endif /* RTC_SUPPORTS_CALLBACKS */ -- cgit v1.2.3 From 9d91559dd2a9c79c061487b5d36c5b1665b597d7 Mon Sep 17 00:00:00 2001 From: barthess Date: Wed, 7 Sep 2011 12:58:34 +0000 Subject: RTC. Minor comments inprovement. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3295 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/rtc_lld.h | 1 + 1 file changed, 1 insertion(+) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/rtc_lld.h b/os/hal/platforms/STM32/rtc_lld.h index 2ec4427d5..c2c6f676b 100644 --- a/os/hal/platforms/STM32/rtc_lld.h +++ b/os/hal/platforms/STM32/rtc_lld.h @@ -69,6 +69,7 @@ /** * @brief Structure representing an RTC driver. + * @note This driver if dummy when callbacks disabled. */ struct RTCDriver{ #if RTC_SUPPORTS_CALLBACKS -- cgit v1.2.3 From ff11f4aa9a4815f3cf4d2a3becba0101cd684a6d Mon Sep 17 00:00:00 2001 From: barthess Date: Sun, 11 Sep 2011 18:19:03 +0000 Subject: I2C. Remove const qualifier from pointer to I2CSlaveConfig. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3306 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/i2c_lld.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/i2c_lld.h b/os/hal/platforms/STM32/i2c_lld.h index 548b5418e..aa11bb543 100644 --- a/os/hal/platforms/STM32/i2c_lld.h +++ b/os/hal/platforms/STM32/i2c_lld.h @@ -212,7 +212,7 @@ struct I2CDriver{ /** * @brief Current slave configuration data. */ - const I2CSlaveConfig *id_slave_config; + I2CSlaveConfig *id_slave_config; __IO size_t txbytes; /*!< @brief Number of bytes to be transmitted. */ __IO size_t rxbytes; /*!< @brief Number of bytes to be received. */ -- cgit v1.2.3 From a08f38d06c5dabf25751bac2deb4259e67fac530 Mon Sep 17 00:00:00 2001 From: barthess Date: Sun, 11 Sep 2011 18:30:56 +0000 Subject: I2C. Remove const qualifier from pointer to I2CSlaveConfig. Step 2. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3307 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/i2c.h | 4 ++-- os/hal/src/i2c.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h index acf09ec9c..96f85460d 100644 --- a/os/hal/include/i2c.h +++ b/os/hal/include/i2c.h @@ -256,11 +256,11 @@ extern "C" { void i2cObjectInit(I2CDriver *i2cp); void i2cStart(I2CDriver *i2cp, const I2CConfig *config); void i2cStop(I2CDriver *i2cp); - void i2cMasterTransmit(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg, + void i2cMasterTransmit(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg, uint16_t slave_addr, uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes); - void i2cMasterReceive(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg, + void i2cMasterReceive(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg, uint16_t slave_addr, uint8_t *rxbuf, size_t rxbytes); void i2cMasterStart(I2CDriver *i2cp); void i2cMasterStop(I2CDriver *i2cp); diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c index 9ce2cc76f..68735b037 100644 --- a/os/hal/src/i2c.c +++ b/os/hal/src/i2c.c @@ -166,7 +166,7 @@ void i2cStop(I2CDriver *i2cp) { * you want transmit only */ void i2cMasterTransmit(I2CDriver *i2cp, - const I2CSlaveConfig *i2cscfg, + I2CSlaveConfig *i2cscfg, uint16_t slave_addr, uint8_t *txbuf, size_t txbytes, @@ -210,7 +210,7 @@ void i2cMasterTransmit(I2CDriver *i2cp, * @param[in] rxbuf pointer to receive buffer */ void i2cMasterReceive(I2CDriver *i2cp, - const I2CSlaveConfig *i2cscfg, + I2CSlaveConfig *i2cscfg, uint16_t slave_addr, uint8_t *rxbuf, size_t rxbytes){ -- cgit v1.2.3 From cf7747f0407db08d59ecb0570dd66f867a07063e Mon Sep 17 00:00:00 2001 From: barthess Date: Sun, 11 Sep 2011 20:21:45 +0000 Subject: I2C. Remove const qualifier from pointer to I2CSlaveConfig. Step 3. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3308 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/i2c.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h index 96f85460d..95bbfa8b4 100644 --- a/os/hal/include/i2c.h +++ b/os/hal/include/i2c.h @@ -105,7 +105,7 @@ typedef enum { * @param[in] i2cscfg pointer to the @p I2CSlaveConfig object triggering the * callback */ -typedef void (*i2ccallback_t)(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg); +typedef void (*i2ccallback_t)(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg); /** @@ -116,8 +116,7 @@ typedef void (*i2ccallback_t)(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg); * @param[in] i2cscfg pointer to the @p I2CSlaveConfig object triggering the * callback */ -typedef void (*i2cerrorcallback_t)(I2CDriver *i2cp, - const I2CSlaveConfig *i2cscfg); +typedef void (*i2cerrorcallback_t)(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg); /** -- cgit v1.2.3 From 7148a664b5c73138a504cd61a1882cfb91ba3b7a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 12 Sep 2011 13:40:44 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3309 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/dox/ext.dox | 84 +++++++ os/hal/hal.mk | 1 + os/hal/include/ext.h | 101 +++++++++ os/hal/include/hal.h | 1 + os/hal/platforms/STM32/ext_lld.c | 390 +++++++++++++++++++++++++++++++++ os/hal/platforms/STM32/ext_lld.h | 265 ++++++++++++++++++++++ os/hal/platforms/STM32F1xx/platform.mk | 1 + os/hal/src/ext.c | 121 ++++++++++ os/hal/src/hal.c | 3 + os/hal/templates/ext_lld.c | 99 +++++++++ os/hal/templates/ext_lld.h | 125 +++++++++++ 11 files changed, 1191 insertions(+) create mode 100644 os/hal/dox/ext.dox create mode 100644 os/hal/include/ext.h create mode 100644 os/hal/platforms/STM32/ext_lld.c create mode 100644 os/hal/platforms/STM32/ext_lld.h create mode 100644 os/hal/src/ext.c create mode 100644 os/hal/templates/ext_lld.c create mode 100644 os/hal/templates/ext_lld.h (limited to 'os/hal') diff --git a/os/hal/dox/ext.dox b/os/hal/dox/ext.dox new file mode 100644 index 000000000..5a66830e9 --- /dev/null +++ b/os/hal/dox/ext.dox @@ -0,0 +1,84 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 . +*/ + +/** + * @defgroup EXT EXT Driver + * @brief Generic EXT Driver. + * @details This module implements a generic EXT (EXTernal) driver. + * @pre In order to use the EXT driver the @p HAL_USE_EXT option + * must be enabled in @p halconf.h. + * + * @section ext_1 Driver State Machine + * The driver implements a state machine internally, not all the driver + * functionalities can be used in any moment, any transition not explicitly + * shown in the following diagram has to be considered an error and shall + * be captured by an assertion (if enabled). + * @if LATEX_PDF + * @dot + digraph example { + size="5, 7"; + rankdir="LR"; + + node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"]; + edge [fontname=Sans, fontsize=8]; + + uninit [label="EXT_UNINIT", style="bold"]; + stop [label="EXT_STOP\nLow Power"]; + active [label="EXT_ACTIVE"]; + + uninit -> stop [label="extInit()"]; + stop -> stop [label="\nextStop()"]; + stop -> active [label="\nextStart()"]; + active -> stop [label="\nextStop()"]; + active -> active [label="\nextStart()"]; + } + * @enddot + * @else + * @dot + digraph example { + rankdir="LR"; + + node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"]; + edge [fontname=Sans, fontsize=8]; + + uninit [label="EXT_UNINIT", style="bold"]; + stop [label="EXT_STOP\nLow Power"]; + active [label="EXT_ACTIVE"]; + + uninit -> stop [label="extInit()"]; + stop -> stop [label="\nextStop()"]; + stop -> active [label="\nextStart()"]; + active -> stop [label="\nextStop()"]; + active -> active [label="\nextStart()"]; + } + * @enddot + * @endif + * + * @section ext_2 EXT Operations. + * This driver abstracts generic external interrupt sources, a callback + * is invoked when a programmable transition is detected on one of the + * configured channels. Several channel modes are possible. + * - EXT_CH_MODE_DISABLED, channel not used. + * - EXT_CH_MODE_RISING_EDGE, callback on a rising edge. + * - EXT_CH_MODE_FALLING_EDGE, callback on a falling edge. + * - EXT_CH_MODE_BOTH_EDGES, callback on a both edges. + * . + * @ingroup IO + */ diff --git a/os/hal/hal.mk b/os/hal/hal.mk index 87a3c6dc3..dddb73f85 100644 --- a/os/hal/hal.mk +++ b/os/hal/hal.mk @@ -3,6 +3,7 @@ HALSRC = ${CHIBIOS}/os/hal/src/hal.c \ ${CHIBIOS}/os/hal/src/adc.c \ ${CHIBIOS}/os/hal/src/can.c \ + ${CHIBIOS}/os/hal/src/ext.c \ ${CHIBIOS}/os/hal/src/gpt.c \ ${CHIBIOS}/os/hal/src/i2c.c \ ${CHIBIOS}/os/hal/src/icu.c \ diff --git a/os/hal/include/ext.h b/os/hal/include/ext.h new file mode 100644 index 000000000..83191b030 --- /dev/null +++ b/os/hal/include/ext.h @@ -0,0 +1,101 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 ext.h + * @brief EXT Driver macros and structures. + * + * @addtogroup EXT + * @{ + */ + +#ifndef _EXT_H_ +#define _EXT_H_ + +#if HAL_USE_EXT || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name EXT channels modes + * @{ + */ +#define EXT_CH_MODE_DISABLED 0 /**< @brief Channel disabled. */ +#define EXT_CH_MODE_RISING_EDGE 1 /**< @brief Rising edge callback. */ +#define EXT_CH_MODE_FALLING_EDGE 2 /**< @brief Falling edge callback. */ +/** @brief Both edges callback.*/ +#define EXT_CH_MODE_BOTH_EDGES (EXT_CH_MODE_RISING_EDGE | \ + EXT_CH_MODE_FALLING_EDGE) +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Driver state machine possible states. + */ +typedef enum { + EXT_UNINIT = 0, /**< Not initialized. */ + EXT_STOP = 1, /**< Stopped. */ + EXT_ACTIVE = 2, /**< Active. */ +} extstate_t; + +/** + * @brief Type of a structure representing a EXT driver. + */ +typedef struct EXTDriver EXTDriver; + +#include "ext_lld.h" + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void extInit(void); + void extObjectInit(EXTDriver *extp); + void extStart(EXTDriver *extp, const EXTConfig *config); + void extStop(EXTDriver *extp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_EXT */ + +#endif /* _EXT_H_ */ + +/** @} */ diff --git a/os/hal/include/hal.h b/os/hal/include/hal.h index b92789b02..8d7214325 100644 --- a/os/hal/include/hal.h +++ b/os/hal/include/hal.h @@ -37,6 +37,7 @@ #include "pal.h" #include "adc.h" #include "can.h" +#include "ext.h" #include "gpt.h" #include "i2c.h" #include "icu.h" diff --git a/os/hal/platforms/STM32/ext_lld.c b/os/hal/platforms/STM32/ext_lld.c new file mode 100644 index 000000000..fc203fa60 --- /dev/null +++ b/os/hal/platforms/STM32/ext_lld.c @@ -0,0 +1,390 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/ext_lld.c + * @brief STM32 EXT subsystem low level driver source. + * + * @addtogroup EXT + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_EXT || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief EXTD1 driver identifier. + */ +EXTDriver EXTD1; + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/** + * @brief EXTI[0] interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(EXTI0_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 0); + EXTD1.config->channels[0].cb(&EXTD1, 0); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief EXTI[1] interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(EXTI1_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 1); + EXTD1.config->channels[1].cb(&EXTD1, 1); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief EXTI[2] interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(EXTI2_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 2); + EXTD1.config->channels[2].cb(&EXTD1, 2); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief EXTI[3] interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(EXTI3_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 3); + EXTD1.config->channels[3].cb(&EXTD1, 3); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief EXTI[4] interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(EXTI4_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 4); + EXTD1.config->channels[4].cb(&EXTD1, 4); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief EXTI[5]...EXTI[9] interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(EXTI9_5_IRQHandler) { + uint32_t pr; + + CH_IRQ_PROLOGUE(); + + pr = EXTI->PR; + EXTI->PR = pr; + if (pr & (1 << 5)) + EXTD1.config->channels[5].cb(&EXTD1, 5); + if (pr & (1 << 6)) + EXTD1.config->channels[6].cb(&EXTD1, 6); + if (pr & (1 << 7)) + EXTD1.config->channels[7].cb(&EXTD1, 7); + if (pr & (1 << 8)) + EXTD1.config->channels[8].cb(&EXTD1, 8); + if (pr & (1 << 9)) + EXTD1.config->channels[9].cb(&EXTD1, 9); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief EXTI[10]...EXTI[15] interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(EXTI15_10_IRQHandler) { + uint32_t pr; + + CH_IRQ_PROLOGUE(); + + pr = EXTI->PR; + EXTI->PR = pr; + if (pr & (1 << 10)) + EXTD1.config->channels[10].cb(&EXTD1, 10); + if (pr & (1 << 11)) + EXTD1.config->channels[11].cb(&EXTD1, 11); + if (pr & (1 << 12)) + EXTD1.config->channels[12].cb(&EXTD1, 12); + if (pr & (1 << 13)) + EXTD1.config->channels[13].cb(&EXTD1, 13); + if (pr & (1 << 14)) + EXTD1.config->channels[14].cb(&EXTD1, 14); + if (pr & (1 << 15)) + EXTD1.config->channels[15].cb(&EXTD1, 15); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief EXTI[16] interrupt handler (PVD). + * + * @isr + */ +CH_IRQ_HANDLER(PVD_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 16); + EXTD1.config->channels[16].cb(&EXTD1, 16); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief EXTI[17] interrupt handler (RTC). + * + * @isr + */ +CH_IRQ_HANDLER(RTCAlarm_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 17); + EXTD1.config->channels[17].cb(&EXTD1, 17); + + CH_IRQ_EPILOGUE(); +} + +#if STM32_HAS_USB || defined(__DOXYGEN__) +/** + * @brief EXTI[18] interrupt handler (USB). + * + * @isr + */ +CH_IRQ_HANDLER(USBWakeUp_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 18); + EXTD1.config->channels[18].cb(&EXTD1, 18); + + CH_IRQ_EPILOGUE(); +} +#endif /* STM32_HAS_USB */ + +#if STM32_HAS_OTG1 || defined(__DOXYGEN__) +/** + * @brief EXTI[18] interrupt handler (OTG1). + * + * @isr + */ +CH_IRQ_HANDLER(OTG_FS_WKUP_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 18); + EXTD1.config->channels[18].cb(&EXTD1, 18); + + CH_IRQ_EPILOGUE(); +} +#endif /* STM32_HAS_OTG1 */ + +#if STM32_HAS_ETH || defined(__DOXYGEN__) +/** + * @brief EXTI[19] interrupt handler (ETH). + * + * @isr + */ +CH_IRQ_HANDLER(ETH_WKUP_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 19); + EXTD1.config->channels[19].cb(&EXTD1, 19); + + CH_IRQ_EPILOGUE(); +} +#endif /* STM32_HAS_ETH */ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level EXT driver initialization. + * + * @notapi + */ +void ext_lld_init(void) { + + /* Driver initialization.*/ + extObjectInit(&EXTD1); +} + +/** + * @brief Configures and activates the EXT peripheral. + * + * @param[in] extp pointer to the @p EXTDriver object + * + * @notapi + */ +void ext_lld_start(EXTDriver *extp) { + unsigned i; + uint32_t imr, emr, rtsr, ftsr; + + if (extp->state == EXT_STOP) { + /* Clock activation.*/ + NVICEnableVector(EXTI0_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI0_IRQ_PRIORITY)); + NVICEnableVector(EXTI1_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI1_IRQ_PRIORITY)); + NVICEnableVector(EXTI2_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI2_IRQ_PRIORITY)); + NVICEnableVector(EXTI3_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI3_IRQ_PRIORITY)); + NVICEnableVector(EXTI4_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI4_IRQ_PRIORITY)); + NVICEnableVector(EXTI9_5_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI5_9_IRQ_PRIORITY)); + NVICEnableVector(EXTI15_10_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI10_15_IRQ_PRIORITY)); + NVICEnableVector(PVD_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI16_IRQ_PRIORITY)); + NVICEnableVector(RTCAlarm_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI17_IRQ_PRIORITY)); +#if STM32_HAS_USB + NVICEnableVector(USBWakeUp_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI18_IRQ_PRIORITY)); +#endif +#if STM32_HAS_OTG1 + NVICEnableVector(OTG_FS_WKUP_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI18_IRQ_PRIORITY)); +#endif +#if STM32_HAS_ETH + NVICEnableVector(ETH_WKUP_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI19_IRQ_PRIORITY)); +#endif + } + /* Configuration.*/ + imr = emr = rtsr = ftsr = 0; + for (i = 0; i < EXT_MAX_CHANNELS; i++) { + if (extp->config->channels[i].mode != EXT_CH_MODE_DISABLED) { + if (extp->config->channels[i].cb != NULL) + imr |= (1 << i); + else + emr |= (1 << i); + if (extp->config->channels[i].mode & EXT_CH_MODE_RISING_EDGE) + rtsr |= (1 << i); + if (extp->config->channels[i].mode & EXT_CH_MODE_FALLING_EDGE) + ftsr |= (1 << i); + } + } + AFIO->EXTICR[0] = extp->config->exti[0]; + AFIO->EXTICR[1] = extp->config->exti[1]; + AFIO->EXTICR[2] = extp->config->exti[2]; + AFIO->EXTICR[3] = extp->config->exti[3]; + EXTI->SWIER = 0; + EXTI->RTSR = rtsr; + EXTI->FTSR = ftsr; + EXTI->PR = EXT_CHANNELS_MASK; + EXTI->EMR = emr; + EXTI->IMR = imr; +} + +/** + * @brief Deactivates the EXT peripheral. + * + * @param[in] extp pointer to the @p EXTDriver object + * + * @notapi + */ +void ext_lld_stop(EXTDriver *extp) { + + if (extp->state == EXT_ACTIVE) { + NVICDisableVector(EXTI0_IRQn); + NVICDisableVector(EXTI1_IRQn); + NVICDisableVector(EXTI2_IRQn); + NVICDisableVector(EXTI3_IRQn); + NVICDisableVector(EXTI4_IRQn); + NVICDisableVector(EXTI9_5_IRQn); + NVICDisableVector(EXTI15_10_IRQn); + NVICDisableVector(PVD_IRQn); + NVICDisableVector(RTCAlarm_IRQn); +#if STM32_HAS_USB + NVICDisableVector(USBWakeUp_IRQn); +#endif +#if STM32_HAS_OTG1 + NVICDisableVector(OTG_FS_WKUP_IRQn); +#endif +#if STM32_HAS_ETH + NVICDisableVector(ETH_WKUP_IRQn); +#endif + } + EXTI->EMR = 0; + EXTI->IMR = 0; + EXTI->PR = EXT_CHANNELS_MASK; +} + +#endif /* HAL_USE_EXT */ + +/** @} */ diff --git a/os/hal/platforms/STM32/ext_lld.h b/os/hal/platforms/STM32/ext_lld.h new file mode 100644 index 000000000..45e863d9c --- /dev/null +++ b/os/hal/platforms/STM32/ext_lld.h @@ -0,0 +1,265 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/ext_lld.h + * @brief STM32 EXT subsystem low level driver header. + * + * @addtogroup EXT + * @{ + */ + +#ifndef _EXT_LLD_H_ +#define _EXT_LLD_H_ + +#if HAL_USE_EXT || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Available number of EXT channels. + * @note The number of available channels varies depending on the STM32 + * subfamily: + * - STM32F10X_CL, 20 channels. + * - STM32F2XX, 23 channels. + * - STM32L1XX_MD, 23 channels. + * - All other STM32F10X_xx, 19 channels. + * . + */ +#if defined(STM32F10X_CL) || defined(__DOXYGEN__) +#define EXT_MAX_CHANNELS 20 +#elif defined(STM32F2XX) +#define EXT_MAX_CHANNELS 23 +#else +#define EXT_MAX_CHANNELS 19 +#endif + +/** + * @brief Mask of the available channels. + */ +#define EXT_CHANNELS_MASK (EXT_MAX_CHANNELS - 1) + +/** + * @name EXTI configuration helpers + * @{ + */ +/** + * @brief EXTI-GPIO association macro. + * @details Helper macro to associate a GPIO to each of the Mx EXTI inputs. + */ +#define EXT_MODE_EXTI(m0, m1, m2, m3, m4, m5, m6, m7, \ + m8, m9, m10, m11, m12, m13, m14, m15) \ + { \ + ((m0) << 0) | ((m1) << 4) | ((m2) << 8) | ((m3) << 12), \ + ((m4) << 0) | ((m5) << 4) | ((m6) << 8) | ((m7) << 12), \ + ((m8) << 0) | ((m9) << 4) | ((m10) << 8) | ((m11) << 12), \ + ((m12) << 0) | ((m13) << 4) | ((m14) << 8) | ((m15) << 12) \ + } + +#define EXT_MODE_GPIOA 0 /**< @brief GPIOA identifier. */ +#define EXT_MODE_GPIOB 1 /**< @brief GPIOB identifier. */ +#define EXT_MODE_GPIOC 2 /**< @brief GPIOC identifier. */ +#define EXT_MODE_GPIOD 3 /**< @brief GPIOD identifier. */ +#define EXT_MODE_GPIOE 4 /**< @brief GPIOE identifier. */ +#define EXT_MODE_GPIOF 5 /**< @brief GPIOF identifier. */ +#define EXT_MODE_GPIOG 6 /**< @brief GPIOG identifier. */ +#define EXT_MODE_GPIOH 7 /**< @brief GPIOH identifier. */ +#define EXT_MODE_GPIOI 8 /**< @brief GPIOI identifier. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @brief EXTI0 interrupt priority level setting. + */ +#if !defined(STM32_EXT_EXTI0_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_EXT_EXTI0_IRQ_PRIORITY 6 +#endif + +/** + * @brief EXTI1 interrupt priority level setting. + */ +#if !defined(STM32_EXT_EXTI1_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_EXT_EXTI1_IRQ_PRIORITY 6 +#endif + +/** + * @brief EXTI2 interrupt priority level setting. + */ +#if !defined(STM32_EXT_EXTI2_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_EXT_EXTI2_IRQ_PRIORITY 6 +#endif + +/** + * @brief EXTI3 interrupt priority level setting. + */ +#if !defined(STM32_EXT_EXTI3_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_EXT_EXTI3_IRQ_PRIORITY 6 +#endif + +/** + * @brief EXTI4 interrupt priority level setting. + */ +#if !defined(STM32_EXT_EXTI4_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_EXT_EXTI4_IRQ_PRIORITY 6 +#endif + +/** + * @brief EXTI9..5 interrupt priority level setting. + */ +#if !defined(STM32_EXT_EXTI5_9_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6 +#endif + +/** + * @brief EXTI15..10 interrupt priority level setting. + */ +#if !defined(STM32_EXT_EXTI10_15_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_EXT_EXTI10_15_IRQ_PRIORITY 6 +#endif + +/** + * @brief EXTI16 (PVD) interrupt priority level setting. + */ +#if !defined(STM32_EXT_EXTI16_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_EXT_EXTI16_IRQ_PRIORITY 6 +#endif + +/** + * @brief EXTI17 (RTC) interrupt priority level setting. + */ +#if !defined(STM32_EXT_EXTI17_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_EXT_EXTI17_IRQ_PRIORITY 6 +#endif + +/** + * @brief EXTI18 (USB) interrupt priority level setting. + */ +#if !defined(STM32_EXT_EXTI18_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_EXT_EXTI18_IRQ_PRIORITY 6 +#endif + +/** + * @brief EXTI19 (ETH) interrupt priority level setting. + */ +#if !defined(STM32_EXT_EXTI19_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_EXT_EXTI19_IRQ_PRIORITY 6 +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief EXT channel identifier. + */ +typedef uint32_t expchannel_t; + +/** + * @brief Type of an EXT generic notification callback. + * + * @param[in] extp pointer to the @p EXPDriver object triggering the + * callback + */ +typedef void (*extcallback_t)(EXTDriver *extp, expchannel_t channel); + +/** + * @brief Channel configuration structure. + */ +typedef struct { + /** + * @brief Channel mode. + */ + uint32_t mode; + /** + * @brief Channel callback. + * @details In the STM32 implementation a @p NULL callback pointer is + * valid and configures the channel as an event sources instead + * of an interrupt source. + */ + extcallback_t cb; +} EXTChannelConfig; + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + /** + * @brief Channel configurations. + */ + EXTChannelConfig channels[EXT_MAX_CHANNELS]; + /* End of the mandatory fields.*/ + /** + * @brief Initialization values for EXTICRx registers. + */ + uint16_t exti[4]; +} EXTConfig; + +/** + * @brief Structure representing an EXT driver. + */ +struct EXTDriver { + /** + * @brief Driver state. + */ + extstate_t state; + /** + * @brief Current configuration data. + */ + const EXTConfig *config; + /* End of the mandatory fields.*/ +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern EXTDriver EXTD1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void ext_lld_init(void); + void ext_lld_start(EXTDriver *extp); + void ext_lld_stop(EXTDriver *extp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_EXT */ + +#endif /* _EXT_LLD_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32F1xx/platform.mk b/os/hal/platforms/STM32F1xx/platform.mk index 26f13cd81..89179f65f 100644 --- a/os/hal/platforms/STM32F1xx/platform.mk +++ b/os/hal/platforms/STM32F1xx/platform.mk @@ -2,6 +2,7 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F1xx/hal_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32F1xx/adc_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/can_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/ext_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/gpt_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/icu_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/i2c_lld.c \ diff --git a/os/hal/src/ext.c b/os/hal/src/ext.c new file mode 100644 index 000000000..d68758684 --- /dev/null +++ b/os/hal/src/ext.c @@ -0,0 +1,121 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 ext.c + * @brief EXT Driver code. + * + * @addtogroup EXT + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_EXT || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief EXT Driver initialization. + * @note This function is implicitly invoked by @p halInit(), there is + * no need to explicitly initialize the driver. + * + * @init + */ +void extInit(void) { + + ext_lld_init(); +} + +/** + * @brief Initializes the standard part of a @p EXTDriver structure. + * + * @param[out] extp pointer to the @p EXTDriver object + * + * @init + */ +void extObjectInit(EXTDriver *extp) { + + extp->state = EXT_STOP; + extp->config = NULL; +} + +/** + * @brief Configures and activates the EXT peripheral. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] config pointer to the @p EXTConfig object + * + * @api + */ +void extStart(EXTDriver *extp, const EXTConfig *config) { + + chDbgCheck((extp != NULL) && (config != NULL), "extStart"); + + chSysLock(); + chDbgAssert((extp->state == EXT_STOP) || (extp->state == EXT_ACTIVE), + "extStart(), #1", "invalid state"); + extp->config = config; + ext_lld_start(extp); + extp->state = EXT_ACTIVE; + chSysUnlock(); +} + +/** + * @brief Deactivates the EXT peripheral. + * + * @param[in] extp pointer to the @p EXTDriver object + * + * @api + */ +void extStop(EXTDriver *extp) { + + chDbgCheck(extp != NULL, "extStop"); + + chSysLock(); + chDbgAssert((extp->state == EXT_STOP) || (extp->state == EXT_ACTIVE), + "extStop(), #1", "invalid state"); + ext_lld_stop(extp); + extp->state = EXT_STOP; + chSysUnlock(); +} + +#endif /* HAL_USE_EXT */ + +/** @} */ diff --git a/os/hal/src/hal.c b/os/hal/src/hal.c index 3c8fb2fe6..d5a8082e9 100644 --- a/os/hal/src/hal.c +++ b/os/hal/src/hal.c @@ -71,6 +71,9 @@ void halInit(void) { #if HAL_USE_CAN || defined(__DOXYGEN__) canInit(); #endif +#if HAL_USE_EXT || defined(__DOXYGEN__) + extInit(); +#endif #if HAL_USE_GPT || defined(__DOXYGEN__) gptInit(); #endif diff --git a/os/hal/templates/ext_lld.c b/os/hal/templates/ext_lld.c new file mode 100644 index 000000000..1aa9477a6 --- /dev/null +++ b/os/hal/templates/ext_lld.c @@ -0,0 +1,99 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 templates/ext_lld.c + * @brief EXT Driver subsystem low level driver source template. + * + * @addtogroup EXT + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_EXT || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level EXT driver initialization. + * + * @notapi + */ +void ext_lld_init(void) { + +} + +/** + * @brief Configures and activates the EXT peripheral. + * + * @param[in] extp pointer to the @p EXTDriver object + * + * @notapi + */ +void ext_lld_start(EXTDriver *extp) { + + if (extp->state == EXT_STOP) { + /* Clock activation.*/ + } + /* Configuration.*/ +} + +/** + * @brief Deactivates the EXT peripheral. + * + * @param[in] extp pointer to the @p EXTDriver object + * + * @notapi + */ +void ext_lld_stop(EXTDriver *extp) { + + if (extp->state == EXT_ACTIVE) { + /* Clock deactivation.*/ + + } +} + +#endif /* HAL_USE_EXT */ + +/** @} */ diff --git a/os/hal/templates/ext_lld.h b/os/hal/templates/ext_lld.h new file mode 100644 index 000000000..eb5a624a4 --- /dev/null +++ b/os/hal/templates/ext_lld.h @@ -0,0 +1,125 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 templates/ext_lld.h + * @brief EXT Driver subsystem low level driver header template. + * + * @addtogroup EXT + * @{ + */ + +#ifndef _EXT_LLD_H_ +#define _EXT_LLD_H_ + +#if HAL_USE_EXT || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Available number of EXT channels. + */ +#define EXT_MAX_CHANNELS 20 + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief EXT channel identifier. + */ +typedef uint32_t expchannel_t; + +/** + * @brief Type of an EXT generic notification callback. + * + * @param[in] extp pointer to the @p EXPDriver object triggering the + * callback + */ +typedef void (*extcallback_t)(EXTDriver *extp); + +/** + * @brief Channel configuration structure. + */ +typedef struct { + uint32_t mode; /**< @brief Channel mode. */ + extcallback_t cb; /**< @brief Channel callback. */ +} EXTChannelConfig; + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + /** + * @brief Channel configurations. + */ + EXTChannelConfig channels[EXT_MAX_CHANNELS]; + /* End of the mandatory fields.*/ +} EXTConfig; + +/** + * @brief Structure representing an EXT driver. + */ +struct EXTDriver { + /** + * @brief Driver state. + */ + extstate_t state; + /** + * @brief Current configuration data. + */ + const EXTConfig *config; + /* End of the mandatory fields.*/ +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void ext_lld_init(void); + void ext_lld_start(EXTDriver *extp); + void ext_lld_stop(EXTDriver *extp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_EXT */ + +#endif /* _EXT_LLD_H_ */ + +/** @} */ -- cgit v1.2.3 From d3e15bccfc41af4e4d3972003ff06b69de2225bc Mon Sep 17 00:00:00 2001 From: barthess Date: Mon, 12 Sep 2011 15:50:35 +0000 Subject: I2C. Revert const qualifier to the pointer to I2CSlaveConfig. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3310 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/i2c.h | 9 +++++---- os/hal/platforms/STM32/i2c_lld.c | 2 +- os/hal/platforms/STM32/i2c_lld.h | 2 +- os/hal/src/i2c.c | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h index 95bbfa8b4..acf09ec9c 100644 --- a/os/hal/include/i2c.h +++ b/os/hal/include/i2c.h @@ -105,7 +105,7 @@ typedef enum { * @param[in] i2cscfg pointer to the @p I2CSlaveConfig object triggering the * callback */ -typedef void (*i2ccallback_t)(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg); +typedef void (*i2ccallback_t)(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg); /** @@ -116,7 +116,8 @@ typedef void (*i2ccallback_t)(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg); * @param[in] i2cscfg pointer to the @p I2CSlaveConfig object triggering the * callback */ -typedef void (*i2cerrorcallback_t)(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg); +typedef void (*i2cerrorcallback_t)(I2CDriver *i2cp, + const I2CSlaveConfig *i2cscfg); /** @@ -255,11 +256,11 @@ extern "C" { void i2cObjectInit(I2CDriver *i2cp); void i2cStart(I2CDriver *i2cp, const I2CConfig *config); void i2cStop(I2CDriver *i2cp); - void i2cMasterTransmit(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg, + void i2cMasterTransmit(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg, uint16_t slave_addr, uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes); - void i2cMasterReceive(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg, + void i2cMasterReceive(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg, uint16_t slave_addr, uint8_t *rxbuf, size_t rxbytes); void i2cMasterStart(I2CDriver *i2cp); void i2cMasterStop(I2CDriver *i2cp); diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index 48bdb3e4e..202669f8e 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -40,7 +40,7 @@ * Note: * When the STOP, START or PEC bit is set, the software must NOT perform * any write access to I2C_CR1 before this bit is cleared by hardware. - * Otherwise there is a risk of setting a second STOP, START or PEC request. + * Otherwise there is a risk of setting a second STOP, START or PEC request. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/i2c_lld.h b/os/hal/platforms/STM32/i2c_lld.h index aa11bb543..548b5418e 100644 --- a/os/hal/platforms/STM32/i2c_lld.h +++ b/os/hal/platforms/STM32/i2c_lld.h @@ -212,7 +212,7 @@ struct I2CDriver{ /** * @brief Current slave configuration data. */ - I2CSlaveConfig *id_slave_config; + const I2CSlaveConfig *id_slave_config; __IO size_t txbytes; /*!< @brief Number of bytes to be transmitted. */ __IO size_t rxbytes; /*!< @brief Number of bytes to be received. */ diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c index 68735b037..9ce2cc76f 100644 --- a/os/hal/src/i2c.c +++ b/os/hal/src/i2c.c @@ -166,7 +166,7 @@ void i2cStop(I2CDriver *i2cp) { * you want transmit only */ void i2cMasterTransmit(I2CDriver *i2cp, - I2CSlaveConfig *i2cscfg, + const I2CSlaveConfig *i2cscfg, uint16_t slave_addr, uint8_t *txbuf, size_t txbytes, @@ -210,7 +210,7 @@ void i2cMasterTransmit(I2CDriver *i2cp, * @param[in] rxbuf pointer to receive buffer */ void i2cMasterReceive(I2CDriver *i2cp, - I2CSlaveConfig *i2cscfg, + const I2CSlaveConfig *i2cscfg, uint16_t slave_addr, uint8_t *rxbuf, size_t rxbytes){ -- cgit v1.2.3 From bc571ccd326886a8cbbde85de66b6fab91336193 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 12 Sep 2011 19:15:30 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3312 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/templates/halconf.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'os/hal') diff --git a/os/hal/templates/halconf.h b/os/hal/templates/halconf.h index 0e616d3d5..43bc0440f 100644 --- a/os/hal/templates/halconf.h +++ b/os/hal/templates/halconf.h @@ -59,6 +59,13 @@ #define HAL_USE_CAN TRUE #endif +/** + * @brief Enables the EXT subsystem. + */ +#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__) +#define HAL_USE_EXT FALSE +#endif + /** * @brief Enables the GPT subsystem. */ @@ -183,6 +190,22 @@ #endif /** @} */ +/*===========================================================================*/ +/** + * @name EXT driver related setting + * @{ + */ +/*===========================================================================*/ +/** @} */ + +/*===========================================================================*/ +/** + * @name GPT driver related setting + * @{ + */ +/*===========================================================================*/ +/** @} */ + /*===========================================================================*/ /** * @name I2C driver related setting @@ -204,6 +227,13 @@ * @{ */ /*===========================================================================*/ + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) +#define MAC_USE_EVENTS TRUE +#endif /** @} */ /*===========================================================================*/ -- cgit v1.2.3 From b86e5efeeb17af6937319d0fd874fc64b0c1ccb4 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 12 Sep 2011 19:27:05 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3313 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/templates/halconf.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/templates/halconf.h b/os/hal/templates/halconf.h index 43bc0440f..2e28bea73 100644 --- a/os/hal/templates/halconf.h +++ b/os/hal/templates/halconf.h @@ -221,6 +221,14 @@ #endif /** @} */ +/*===========================================================================*/ +/** + * @name ICU driver related setting + * @{ + */ +/*===========================================================================*/ +/** @} */ + /*===========================================================================*/ /** * @name MAC driver related setting @@ -311,6 +319,7 @@ * @{ */ /*===========================================================================*/ + /** * @brief Number of initialization attempts before rejecting the card. * @note Attempts are performed at 10mS intevals. @@ -367,13 +376,13 @@ #endif /** @} */ - /*===========================================================================*/ /** * @name SERIAL_USB driver related setting * @{ */ /*===========================================================================*/ + /** * @brief Serial over USB buffers size. * @details Configuration parameter, the buffer size must be a multiple of -- cgit v1.2.3 From fbac4d253d67cc5b1ec39166ce1abb8124b1e3a8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 13 Sep 2011 12:40:42 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3314 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/ext.h | 30 ++++++++++++++++++++--- os/hal/platforms/STM32/ext_lld.c | 51 +++++++++++++++++++++++++++++++++++----- os/hal/platforms/STM32/ext_lld.h | 2 ++ os/hal/src/ext.c | 46 ++++++++++++++++++++++++++++++++++++ os/hal/templates/ext_lld.c | 24 +++++++++++++++++++ os/hal/templates/ext_lld.h | 2 ++ 6 files changed, 146 insertions(+), 9 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/ext.h b/os/hal/include/ext.h index 83191b030..5d904cf4e 100644 --- a/os/hal/include/ext.h +++ b/os/hal/include/ext.h @@ -39,12 +39,14 @@ * @name EXT channels modes * @{ */ +#define EXT_CH_MODE_EDGES_MASK 3 /**< @brief Mask of edges field. */ #define EXT_CH_MODE_DISABLED 0 /**< @brief Channel disabled. */ #define EXT_CH_MODE_RISING_EDGE 1 /**< @brief Rising edge callback. */ #define EXT_CH_MODE_FALLING_EDGE 2 /**< @brief Falling edge callback. */ -/** @brief Both edges callback.*/ -#define EXT_CH_MODE_BOTH_EDGES (EXT_CH_MODE_RISING_EDGE | \ - EXT_CH_MODE_FALLING_EDGE) +#define EXT_CH_MODE_BOTH_EDGES 3 /**< @brief Both edges callback. */ + +#define EXT_CH_MODE_AUTOSTART 4 /**< @brief Channel started + automatically on driver start. */ /** @} */ /*===========================================================================*/ @@ -79,6 +81,26 @@ typedef struct EXTDriver EXTDriver; /* Driver macros. */ /*===========================================================================*/ +/** + * @brief Enables an EXT channel. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] channel channel to be enabled + * + * @iclass + */ +#define extChannelEnableI(extp, channel) ext_lld_channel_enable(extp, channel) + +/** + * @brief Disables an EXT channel. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] channel channel to be disabled + * + * @iclass + */ +#define extChannelDisableI(extp, channel) ext_lld_channel_disable(extp, channel) + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ @@ -90,6 +112,8 @@ extern "C" { void extObjectInit(EXTDriver *extp); void extStart(EXTDriver *extp, const EXTConfig *config); void extStop(EXTDriver *extp); + void extChannelEnable(EXTDriver *extp, expchannel_t channel); + void extChannelDisable(EXTDriver *extp, expchannel_t channel); #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32/ext_lld.c b/os/hal/platforms/STM32/ext_lld.c index fc203fa60..712ed5a39 100644 --- a/os/hal/platforms/STM32/ext_lld.c +++ b/os/hal/platforms/STM32/ext_lld.c @@ -328,7 +328,7 @@ void ext_lld_start(EXTDriver *extp) { /* Configuration.*/ imr = emr = rtsr = ftsr = 0; for (i = 0; i < EXT_MAX_CHANNELS; i++) { - if (extp->config->channels[i].mode != EXT_CH_MODE_DISABLED) { + if (extp->config->channels[i].mode & EXT_CH_MODE_AUTOSTART) { if (extp->config->channels[i].cb != NULL) imr |= (1 << i); else @@ -344,11 +344,11 @@ void ext_lld_start(EXTDriver *extp) { AFIO->EXTICR[2] = extp->config->exti[2]; AFIO->EXTICR[3] = extp->config->exti[3]; EXTI->SWIER = 0; - EXTI->RTSR = rtsr; - EXTI->FTSR = ftsr; - EXTI->PR = EXT_CHANNELS_MASK; - EXTI->EMR = emr; - EXTI->IMR = imr; + EXTI->RTSR = rtsr; + EXTI->FTSR = ftsr; + EXTI->PR = EXT_CHANNELS_MASK; + EXTI->EMR = emr; + EXTI->IMR = imr; } /** @@ -385,6 +385,45 @@ void ext_lld_stop(EXTDriver *extp) { EXTI->PR = EXT_CHANNELS_MASK; } +/** + * @brief Enables an EXT channel. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] channel channel to be enabled + * + * @notapi + */ +void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel) { + + if (extp->config->channels[channel].cb != NULL) + EXTI->IMR |= (1 << channel); + else + EXTI->EMR |= (1 << channel); + if (extp->config->channels[channel].mode & EXT_CH_MODE_RISING_EDGE) + EXTI->RTSR |= (1 << channel); + if (extp->config->channels[channel].mode & EXT_CH_MODE_FALLING_EDGE) + EXTI->FTSR |= (1 << channel); +} + +/** + * @brief Disables an EXT channel. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] channel channel to be disabled + * + * @notapi + */ +void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel) { + + (void)extp; + + EXTI->IMR &= ~(1 << channel); + EXTI->EMR &= ~(1 << channel); + EXTI->RTSR &= ~(1 << channel); + EXTI->FTSR &= ~(1 << channel); + EXTI->PR = (1 << channel); +} + #endif /* HAL_USE_EXT */ /** @} */ diff --git a/os/hal/platforms/STM32/ext_lld.h b/os/hal/platforms/STM32/ext_lld.h index 45e863d9c..17ea09fb8 100644 --- a/os/hal/platforms/STM32/ext_lld.h +++ b/os/hal/platforms/STM32/ext_lld.h @@ -254,6 +254,8 @@ extern "C" { void ext_lld_init(void); void ext_lld_start(EXTDriver *extp); void ext_lld_stop(EXTDriver *extp); + void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel); + void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel); #ifdef __cplusplus } #endif diff --git a/os/hal/src/ext.c b/os/hal/src/ext.c index d68758684..1c83cd2e6 100644 --- a/os/hal/src/ext.c +++ b/os/hal/src/ext.c @@ -78,6 +78,8 @@ void extObjectInit(EXTDriver *extp) { /** * @brief Configures and activates the EXT peripheral. + * @post After activation all EXT channels are in the disabled state, + * use @p extChannelEnable() in order to activate them. * * @param[in] extp pointer to the @p EXTDriver object * @param[in] config pointer to the @p EXTConfig object @@ -116,6 +118,50 @@ void extStop(EXTDriver *extp) { chSysUnlock(); } +/** + * @brief Enables an EXT channel. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] channel channel to be enabled + * + * @api + */ +void extChannelEnable(EXTDriver *extp, expchannel_t channel) { + + chDbgCheck((extp != NULL) && + (channel < EXT_MAX_CHANNELS) && + (extp->config->channels[channel].mode != EXT_CH_MODE_DISABLED), + "extChannelEnable"); + + chSysLock(); + chDbgAssert(extp->state == EXT_ACTIVE, + "extChannelEnable(), #1", "invalid state"); + extChannelEnableI(extp, channel); + chSysUnlock(); +} + +/** + * @brief Disables an EXT channel. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] channel channel to be disabled + * + * @api + */ +void extChannelDisable(EXTDriver *extp, expchannel_t channel) { + + chDbgCheck((extp != NULL) && + (channel < EXT_MAX_CHANNELS) && + (extp->config->channels[channel].mode != EXT_CH_MODE_DISABLED), + "extChannelDisable"); + + chSysLock(); + chDbgAssert(extp->state == EXT_ACTIVE, + "extChannelDisable(), #1", "invalid state"); + extChannelDisableI(extp, channel); + chSysUnlock(); +} + #endif /* HAL_USE_EXT */ /** @} */ diff --git a/os/hal/templates/ext_lld.c b/os/hal/templates/ext_lld.c index 1aa9477a6..45bc1c3dc 100644 --- a/os/hal/templates/ext_lld.c +++ b/os/hal/templates/ext_lld.c @@ -94,6 +94,30 @@ void ext_lld_stop(EXTDriver *extp) { } } +/** + * @brief Enables an EXT channel. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] channel channel to be enabled + * + * @notapi + */ +void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel) { + +} + +/** + * @brief Disables an EXT channel. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] channel channel to be disabled + * + * @notapi + */ +void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel) { + +} + #endif /* HAL_USE_EXT */ /** @} */ diff --git a/os/hal/templates/ext_lld.h b/os/hal/templates/ext_lld.h index eb5a624a4..494cef1b9 100644 --- a/os/hal/templates/ext_lld.h +++ b/os/hal/templates/ext_lld.h @@ -114,6 +114,8 @@ extern "C" { void ext_lld_init(void); void ext_lld_start(EXTDriver *extp); void ext_lld_stop(EXTDriver *extp); + void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel); + void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel); #ifdef __cplusplus } #endif -- cgit v1.2.3 From ff435ba9f475e9bb537dd912a71431a779543e24 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 14 Sep 2011 16:53:08 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3315 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/mac_lld.c | 36 ++++++++-------- os/hal/platforms/STM32/mac_lld.h | 77 +++++++++++++++++++++++++++++++++- os/hal/platforms/STM32F1xx/platform.mk | 1 + 3 files changed, 95 insertions(+), 19 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/mac_lld.c b/os/hal/platforms/STM32/mac_lld.c index 01a28a8b4..1bec4d879 100644 --- a/os/hal/platforms/STM32/mac_lld.c +++ b/os/hal/platforms/STM32/mac_lld.c @@ -49,9 +49,6 @@ #error "STM32_HCLK below minimum frequency for ETH operations (20MHz)" #endif -/* PHY address.*/ -#define MACMIIDR_PA (32 << 11) - /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -83,14 +80,14 @@ static uint32_t tb[MAC_TRANSMIT_BUFFERS * BUFFER_SLICE]; * * @param[in] reg register number * @param[in] value new register value + * + * @notapi */ -static void mii_write_phy(uint16_t reg, uint16_t value) { - uint32_t miiar; +void _stm32_eth_write_phy(uint32_t reg, uint32_t value) { - miiar = ETH->MACMIIAR | ETH_MACMIIAR_MW | ETH_MACMIIAR_MB; - miiar = (miiar & ~ETH_MACMIIAR_MR) | (reg << 6); ETH->MACMIIDR = value; - ETH->MACMIIAR = miiar; + ETH->MACMIIAR = BOARD_PHY_ADDR | (reg << 6) | MACMIIDR_CR | + ETH_MACMIIAR_MW | ETH_MACMIIAR_MB; while ((ETH->MACMIIAR & ETH_MACMIIAR_MB) != 0) ; } @@ -99,21 +96,23 @@ static void mii_write_phy(uint16_t reg, uint16_t value) { * @brief Reads a PHY register. * * @param[in] reg register number + * + * @notapi */ -static uint16_t mii_read_phy(uint16_t reg) { - uint32_t miiar; +static uint32_t _stm32_eth_read_phy(uint32_t reg) { - miiar = ETH->MACMIIAR | ETH_MACMIIAR_MB; - miiar = (miiar & ~(ETH_MACMIIAR_MR | ETH_MACMIIAR_MW)) | (reg << 6); - ETH->MACMIIAR = miiar; + ETH->MACMIIAR = BOARD_PHY_ADDR | (reg << 6) | MACMIIDR_CR | + ETH_MACMIIAR_MB; while ((ETH->MACMIIAR & ETH_MACMIIAR_MB) != 0) ; - return (uint16_t)ETH->MACMIIDR; + return ETH->MACMIIDR; } + /** * @brief MII/RMII interface initialization. */ +#if 0 static void mii_init(void) { uint32_t i; @@ -126,6 +125,7 @@ static void mii_init(void) { /* Wrong or defective board.*/ chSysHalt(); } +#endif /*===========================================================================*/ /* Driver interrupt handlers. */ @@ -148,7 +148,7 @@ void mac_lld_init(void) { /* Descriptor tables are initialized in linked mode, note that the first word is not initialized here but in mac_lld_start().*/ for (i = 0; i < MAC_RECEIVE_BUFFERS; i++) { - rd[i].rdes1 = RDES1_RCH | MAC_BUFFERS_SIZE; + rd[i].rdes1 = STM32_RDES1_RCH | MAC_BUFFERS_SIZE; rd[i].rdes2 = (uint32_t)&rb[i * BUFFER_SLICE]; rd[i].rdes3 = (uint32_t)&rb[((i + 1) % MAC_RECEIVE_BUFFERS) * BUFFER_SLICE]; @@ -173,10 +173,10 @@ void mac_lld_start(MACDriver *macp) { /* Resets the state of all descriptors.*/ for (i = 0; i < MAC_RECEIVE_BUFFERS; i++) - rd[i].rdes0 = RDES0_OWN; + rd[i].rdes0 = STM32_RDES0_OWN; rxptr = (stm32_eth_rx_descriptor_t *)rd; for (i = 0; i < MAC_TRANSMIT_BUFFERS; i++) - td[i].tdes0 = TDES0_TCH; + td[i].tdes0 = STM32_TDES0_TCH; txptr = (stm32_eth_tx_descriptor_t *)td; /* Soft reset of the MAC core and wait until the reset is complete.*/ @@ -185,7 +185,7 @@ void mac_lld_start(MACDriver *macp) { ; /* MII initialization.*/ - mii_init(); +// mii_init(); /* Descriptor chains pointers.*/ ETH->DMARDLAR = (uint32_t)rd; diff --git a/os/hal/platforms/STM32/mac_lld.h b/os/hal/platforms/STM32/mac_lld.h index 8647bd296..f21f4c129 100644 --- a/os/hal/platforms/STM32/mac_lld.h +++ b/os/hal/platforms/STM32/mac_lld.h @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. @@ -35,6 +35,81 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @name RDES0 constants + * @{ + */ +#define STM32_RDES0_OWN 0x80000000 +#define STM32_RDES0_AFM 0x40000000 +#define STM32_RDES0_FL_MASK 0x3FFF0000 +#define STM32_RDES0_ES 0x00008000 +#define STM32_RDES0_DESERR 0x00004000 +#define STM32_RDES0_SAF 0x00002000 +#define STM32_RDES0_LE 0x00001000 +#define STM32_RDES0_OE 0x00000800 +#define STM32_RDES0_VLAN 0x00000400 +#define STM32_RDES0_FS 0x00000200 +#define STM32_RDES0_LS 0x00000100 +#define STM32_RDES0_IPHCE 0x00000080 +#define STM32_RDES0_LCO 0x00000040 +#define STM32_RDES0_FT 0x00000020 +#define STM32_RDES0_RWT 0x00000010 +#define STM32_RDES0_RE 0x00000008 +#define STM32_RDES0_DE 0x00000004 +#define STM32_RDES0_CE 0x00000002 +#define STM32_RDES0_PCE 0x00000001 +/** @} */ + +/** + * @name RDES1 constants + * @{ + */ +#define STM32_RDES1_DIC 0x80000000 +#define STM32_RDES1_RBS2_MASK 0x1FFF0000 +#define STM32_RDES1_RER 0x00008000 +#define STM32_RDES1_RCH 0x00004000 +#define STM32_RDES1_RBS1_MASK 0x00001FFF +/** @} */ + +/** + * @name TDES0 constants + * @{ + */ +#define STM32_TDES0_OWN 0x80000000 +#define STM32_TDES0_IC 0x40000000 +#define STM32_TDES0_LS 0x20000000 +#define STM32_TDES0_FS 0x10000000 +#define STM32_TDES0_DC 0x08000000 +#define STM32_TDES0_DP 0x04000000 +#define STM32_TDES0_TTSE 0x02000000 +#define STM32_TDES0_CIC_MASK 0x00C00000 +#define STM32_TDES0_TER 0x00200000 +#define STM32_TDES0_TCH 0x00100000 +#define STM32_TDES0_TTSS 0x00020000 +#define STM32_TDES0_IHE 0x00010000 +#define STM32_TDES0_ES 0x00008000 +#define STM32_TDES0_JT 0x00004000 +#define STM32_TDES0_FF 0x00002000 +#define STM32_TDES0_IPE 0x00001000 +#define STM32_TDES0_LCA 0x00000800 +#define STM32_TDES0_NC 0x00000400 +#define STM32_TDES0_LCO 0x00000200 +#define STM32_TDES0_EC 0x00000100 +#define STM32_TDES0_VF 0x00000080 +#define STM32_TDES0_CC_MASK 0x00000078 +#define STM32_TDES0_ED 0x00000004 +#define STM32_TDES0_UF 0x00000002 +#define STM32_TDES0_DB 0x00000001 +/** @} */ + +/** + * @name TDES1 constants + * @{ + */ +#define STM32_TDES1_TBS2_MASK 0x1FFF0000 +#define STM32_TDES1_TBS1_MASK 0x00001FFF +/** @} */ + /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F1xx/platform.mk b/os/hal/platforms/STM32F1xx/platform.mk index 89179f65f..1a8c42bc7 100644 --- a/os/hal/platforms/STM32F1xx/platform.mk +++ b/os/hal/platforms/STM32F1xx/platform.mk @@ -6,6 +6,7 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F1xx/hal_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/gpt_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/icu_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/i2c_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/mac_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/pwm_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/serial_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv1/pal_lld.c \ -- cgit v1.2.3 From 061a1d4844a0eeffca59ae09b2799cc8ff24e05b Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 14 Sep 2011 18:35:47 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3317 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/sdc_lld.c | 730 -------------------------------- os/hal/platforms/STM32/DMAv1/sdc_lld.h | 203 --------- os/hal/platforms/STM32/DMAv1/spi_lld.c | 445 ------------------- os/hal/platforms/STM32/DMAv1/spi_lld.h | 285 ------------- os/hal/platforms/STM32/DMAv1/uart_lld.c | 557 ------------------------ os/hal/platforms/STM32/DMAv1/uart_lld.h | 318 -------------- os/hal/platforms/STM32/sdc_lld.c | 730 ++++++++++++++++++++++++++++++++ os/hal/platforms/STM32/sdc_lld.h | 203 +++++++++ os/hal/platforms/STM32/spi_lld.c | 445 +++++++++++++++++++ os/hal/platforms/STM32/spi_lld.h | 285 +++++++++++++ os/hal/platforms/STM32/uart_lld.c | 557 ++++++++++++++++++++++++ os/hal/platforms/STM32/uart_lld.h | 318 ++++++++++++++ 12 files changed, 2538 insertions(+), 2538 deletions(-) delete mode 100644 os/hal/platforms/STM32/DMAv1/sdc_lld.c delete mode 100644 os/hal/platforms/STM32/DMAv1/sdc_lld.h delete mode 100644 os/hal/platforms/STM32/DMAv1/spi_lld.c delete mode 100644 os/hal/platforms/STM32/DMAv1/spi_lld.h delete mode 100644 os/hal/platforms/STM32/DMAv1/uart_lld.c delete mode 100644 os/hal/platforms/STM32/DMAv1/uart_lld.h create mode 100644 os/hal/platforms/STM32/sdc_lld.c create mode 100644 os/hal/platforms/STM32/sdc_lld.h create mode 100644 os/hal/platforms/STM32/spi_lld.c create mode 100644 os/hal/platforms/STM32/spi_lld.h create mode 100644 os/hal/platforms/STM32/uart_lld.c create mode 100644 os/hal/platforms/STM32/uart_lld.h (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/DMAv1/sdc_lld.c b/os/hal/platforms/STM32/DMAv1/sdc_lld.c deleted file mode 100644 index b9e02a815..000000000 --- a/os/hal/platforms/STM32/DMAv1/sdc_lld.c +++ /dev/null @@ -1,730 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT 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 STM32/sdc_lld.c - * @brief STM32 SDC subsystem low level driver source. - * - * @addtogroup SDC - * @{ - */ - -#include - -#include "ch.h" -#include "hal.h" - -#if HAL_USE_SDC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** @brief SDCD1 driver identifier.*/ -SDCDriver SDCD1; - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ - -#if STM32_SDC_UNALIGNED_SUPPORT -/** - * @brief Buffer for temporary storage during unaligned transfers. - */ -static union { - uint32_t alignment; - uint8_t buf[SDC_BLOCK_SIZE]; -} u; -#endif - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Reads one or more blocks. - * - * @param[in] sdcp pointer to the @p SDCDriver object - * @param[in] startblk first block to read - * @param[out] buf pointer to the read buffer, it must be aligned to - * four bytes boundary - * @param[in] n number of blocks to read - * @return The operation status. - * @retval FALSE operation succeeded, the requested blocks have been - * read. - * @retval TRUE operation failed, the state of the buffer is uncertain. - * - * @notapi - */ -static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk, - uint8_t *buf, uint32_t n) { - uint32_t resp[1]; - - /* Checks for errors and waits for the card to be ready for reading.*/ - if (_sdc_wait_for_transfer_state(sdcp)) - return TRUE; - - /* Prepares the DMA channel for reading.*/ - dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); - dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, - (n * SDC_BLOCK_SIZE) / sizeof (uint32_t)); - dmaStreamSetMode(STM32_DMA2_STREAM4, - STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | - STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_PSIZE_WORD | - STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); - - /* Setting up data transfer. - Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/ - SDIO->ICR = 0xFFFFFFFF; - SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | - SDIO_MASK_DATAENDIE | SDIO_MASK_STBITERRIE; - SDIO->DLEN = n * SDC_BLOCK_SIZE; - SDIO->DCTRL = SDIO_DCTRL_DTDIR | - SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 | - SDIO_DCTRL_DMAEN | - SDIO_DCTRL_DTEN; - - /* DMA channel activation.*/ - dmaStreamEnable(STM32_DMA2_STREAM4); - - /* Read multiple blocks command.*/ - if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) - startblk *= SDC_BLOCK_SIZE; - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_MULTIPLE_BLOCK, - startblk, resp) || - SDC_R1_ERROR(resp[0])) - goto error; - - chSysLock(); - if (SDIO->MASK != 0) { - chDbgAssert(sdcp->thread == NULL, - "sdc_lld_read_multiple(), #1", "not NULL"); - sdcp->thread = chThdSelf(); - chSchGoSleepS(THD_STATE_SUSPENDED); - chDbgAssert(sdcp->thread == NULL, - "sdc_lld_read_multiple(), #2", "not NULL"); - } - if ((SDIO->STA & SDIO_STA_DATAEND) == 0) { - chSysUnlock(); - goto error; - } - dmaStreamDisable(STM32_DMA2_STREAM4); - SDIO->ICR = 0xFFFFFFFF; - SDIO->DCTRL = 0; - chSysUnlock(); - - return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); -error: - dmaStreamDisable(STM32_DMA2_STREAM4); - SDIO->ICR = 0xFFFFFFFF; - SDIO->MASK = 0; - SDIO->DCTRL = 0; - return TRUE; -} - -/** - * @brief Reads one block. - * - * @param[in] sdcp pointer to the @p SDCDriver object - * @param[in] startblk first block to read - * @param[out] buf pointer to the read buffer, it must be aligned to - * four bytes boundary - * @return The operation status. - * @retval FALSE operation succeeded, the requested blocks have been - * read. - * @retval TRUE operation failed, the state of the buffer is uncertain. - * - * @notapi - */ -static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk, - uint8_t *buf) { - uint32_t resp[1]; - - /* Checks for errors and waits for the card to be ready for reading.*/ - if (_sdc_wait_for_transfer_state(sdcp)) - return TRUE; - - /* Prepares the DMA channel for reading.*/ - dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); - dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, - SDC_BLOCK_SIZE / sizeof (uint32_t)); - dmaStreamSetMode(STM32_DMA2_STREAM4, - STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | - STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_PSIZE_WORD | - STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); - - /* Setting up data transfer. - Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/ - SDIO->ICR = 0xFFFFFFFF; - SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | - SDIO_MASK_DATAENDIE | SDIO_MASK_STBITERRIE; - SDIO->DLEN = SDC_BLOCK_SIZE; - SDIO->DCTRL = SDIO_DCTRL_DTDIR | - SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 | - SDIO_DCTRL_DMAEN | - SDIO_DCTRL_DTEN; - - /* DMA channel activation.*/ - dmaStreamEnable(STM32_DMA2_STREAM4); - - /* Read single block command.*/ - if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) - startblk *= SDC_BLOCK_SIZE; - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_SINGLE_BLOCK, - startblk, resp) || - SDC_R1_ERROR(resp[0])) - goto error; - - chSysLock(); - if (SDIO->MASK != 0) { - chDbgAssert(sdcp->thread == NULL, - "sdc_lld_read_single(), #1", "not NULL"); - sdcp->thread = chThdSelf(); - chSchGoSleepS(THD_STATE_SUSPENDED); - chDbgAssert(sdcp->thread == NULL, - "sdc_lld_read_single(), #2", "not NULL"); - } - if ((SDIO->STA & SDIO_STA_DATAEND) == 0) { - chSysUnlock(); - goto error; - } - dmaStreamDisable(STM32_DMA2_STREAM4); - SDIO->ICR = 0xFFFFFFFF; - SDIO->DCTRL = 0; - chSysUnlock(); - - return FALSE; -error: - dmaStreamDisable(STM32_DMA2_STREAM4); - SDIO->ICR = 0xFFFFFFFF; - SDIO->MASK = 0; - SDIO->DCTRL = 0; - return TRUE; -} - -/** - * @brief Writes one or more blocks. - * - * @param[in] sdcp pointer to the @p SDCDriver object - * @param[in] startblk first block to write - * @param[out] buf pointer to the write buffer, it must be aligned to - * four bytes boundary - * @param[in] n number of blocks to write - * @return The operation status. - * @retval FALSE operation succeeded, the requested blocks have been - * written. - * @retval TRUE operation failed. - * - * @notapi - */ -static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk, - const uint8_t *buf, uint32_t n) { - uint32_t resp[1]; - - /* Checks for errors and waits for the card to be ready for writing.*/ - if (_sdc_wait_for_transfer_state(sdcp)) - return TRUE; - - /* Prepares the DMA channel for writing.*/ - dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); - dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, - (n * SDC_BLOCK_SIZE) / sizeof (uint32_t)); - dmaStreamSetMode(STM32_DMA2_STREAM4, - STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | - STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | - STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); - - /* Write multiple blocks command.*/ - if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) - startblk *= SDC_BLOCK_SIZE; - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_MULTIPLE_BLOCK, - startblk, resp) || - SDC_R1_ERROR(resp[0])) - return TRUE; - - /* Setting up data transfer. - Options: Controller to Card, Block mode, DMA mode, 512 bytes blocks.*/ - SDIO->ICR = 0xFFFFFFFF; - SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | - SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE | - SDIO_MASK_STBITERRIE; - SDIO->DLEN = n * SDC_BLOCK_SIZE; - SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 | - SDIO_DCTRL_DMAEN | - SDIO_DCTRL_DTEN; - - /* DMA channel activation.*/ - dmaStreamEnable(STM32_DMA2_STREAM4); - - /* Note the mask is checked before going to sleep because the interrupt - may have occurred before reaching the critical zone.*/ - chSysLock(); - if (SDIO->MASK != 0) { - chDbgAssert(sdcp->thread == NULL, - "sdc_lld_write_multiple(), #1", "not NULL"); - sdcp->thread = chThdSelf(); - chSchGoSleepS(THD_STATE_SUSPENDED); - chDbgAssert(sdcp->thread == NULL, - "sdc_lld_write_multiple(), #2", "not NULL"); - } - if ((SDIO->STA & SDIO_STA_DATAEND) == 0) { - chSysUnlock(); - goto error; - } - dmaStreamDisable(STM32_DMA2_STREAM4); - SDIO->ICR = 0xFFFFFFFF; - SDIO->DCTRL = 0; - chSysUnlock(); - - return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); -error: - dmaStreamDisable(STM32_DMA2_STREAM4); - SDIO->ICR = 0xFFFFFFFF; - SDIO->MASK = 0; - SDIO->DCTRL = 0; - return TRUE; -} - -/** - * @brief Writes one block. - * - * @param[in] sdcp pointer to the @p SDCDriver object - * @param[in] startblk first block to write - * @param[out] buf pointer to the write buffer, it must be aligned to - * four bytes boundary - * @param[in] n number of blocks to write - * @return The operation status. - * @retval FALSE operation succeeded, the requested blocks have been - * written. - * @retval TRUE operation failed. - * - * @notapi - */ -static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk, - const uint8_t *buf) { - uint32_t resp[1]; - - /* Checks for errors and waits for the card to be ready for writing.*/ - if (_sdc_wait_for_transfer_state(sdcp)) - return TRUE; - - /* Prepares the DMA channel for writing.*/ - dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); - dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, - SDC_BLOCK_SIZE / sizeof (uint32_t)); - dmaStreamSetMode(STM32_DMA2_STREAM4, - STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | - STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | - STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); - - /* Write single block command.*/ - if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) - startblk *= SDC_BLOCK_SIZE; - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_BLOCK, - startblk, resp) || - SDC_R1_ERROR(resp[0])) - return TRUE; - - /* Setting up data transfer. - Options: Controller to Card, Block mode, DMA mode, 512 bytes blocks.*/ - SDIO->ICR = 0xFFFFFFFF; - SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | - SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE | - SDIO_MASK_STBITERRIE; - SDIO->DLEN = SDC_BLOCK_SIZE; - SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 | - SDIO_DCTRL_DMAEN | - SDIO_DCTRL_DTEN; - - /* DMA channel activation.*/ - dmaStreamEnable(STM32_DMA2_STREAM4); - - /* Note the mask is checked before going to sleep because the interrupt - may have occurred before reaching the critical zone.*/ - chSysLock(); - if (SDIO->MASK != 0) { - chDbgAssert(sdcp->thread == NULL, - "sdc_lld_write_single(), #1", "not NULL"); - sdcp->thread = chThdSelf(); - chSchGoSleepS(THD_STATE_SUSPENDED); - chDbgAssert(sdcp->thread == NULL, - "sdc_lld_write_single(), #2", "not NULL"); - } - if ((SDIO->STA & SDIO_STA_DATAEND) == 0) { - chSysUnlock(); - goto error; - } - dmaStreamDisable(STM32_DMA2_STREAM4); - SDIO->ICR = 0xFFFFFFFF; - SDIO->DCTRL = 0; - chSysUnlock(); - - return FALSE; -error: - dmaStreamDisable(STM32_DMA2_STREAM4); - SDIO->ICR = 0xFFFFFFFF; - SDIO->MASK = 0; - SDIO->DCTRL = 0; - return TRUE; -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/** - * @brief SDIO IRQ handler. - * - * @isr - */ -CH_IRQ_HANDLER(SDIO_IRQHandler) { - - CH_IRQ_PROLOGUE(); - - chSysLockFromIsr(); - if (SDCD1.thread != NULL) { - chSchReadyI(SDCD1.thread); - SDCD1.thread = NULL; - } - chSysUnlockFromIsr(); - - /* Disables the source but the status flags are not reset because the - read/write functions need to check them.*/ - SDIO->MASK = 0; - - CH_IRQ_EPILOGUE(); -} - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level SDC driver initialization. - * - * @notapi - */ -void sdc_lld_init(void) { - - sdcObjectInit(&SDCD1); - SDCD1.thread = NULL; -} - -/** - * @brief Configures and activates the SDC peripheral. - * - * @param[in] sdcp pointer to the @p SDCDriver object, must be @p NULL, - * this driver does not require any configuration - * - * @notapi - */ -void sdc_lld_start(SDCDriver *sdcp) { - - if (sdcp->state == SDC_STOP) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaStreamAllocate(STM32_DMA2_STREAM4, 0, NULL, NULL); - dmaStreamSetPeripheral(STM32_DMA2_STREAM4, &SDIO->FIFO); - NVICEnableVector(SDIO_IRQn, - CORTEX_PRIORITY_MASK(STM32_SDC_SDIO_IRQ_PRIORITY)); - RCC->AHBENR |= RCC_AHBENR_SDIOEN; - } - /* Configuration, card clock is initially stopped.*/ - SDIO->POWER = 0; - SDIO->CLKCR = 0; - SDIO->DCTRL = 0; - SDIO->DTIMER = STM32_SDC_DATATIMEOUT; -} - -/** - * @brief Deactivates the SDC peripheral. - * - * @param[in] sdcp pointer to the @p SDCDriver object - * - * @notapi - */ -void sdc_lld_stop(SDCDriver *sdcp) { - - if ((sdcp->state == SDC_READY) || (sdcp->state == SDC_ACTIVE)) { - SDIO->POWER = 0; - SDIO->CLKCR = 0; - SDIO->DCTRL = 0; - SDIO->DTIMER = 0; - - /* Clock deactivation.*/ - NVICDisableVector(SDIO_IRQn); - dmaStreamRelease(STM32_DMA2_STREAM4); - } -} - -/** - * @brief Starts the SDIO clock and sets it to init mode (400KHz or less). - * - * @param[in] sdcp pointer to the @p SDCDriver object - * - * @notapi - */ -void sdc_lld_start_clk(SDCDriver *sdcp) { - - (void)sdcp; - /* Initial clock setting: 400KHz, 1bit mode.*/ - SDIO->CLKCR = STM32_SDIO_DIV_LS; - SDIO->POWER |= SDIO_POWER_PWRCTRL_0 | SDIO_POWER_PWRCTRL_1; - SDIO->CLKCR |= SDIO_CLKCR_CLKEN; -} - -/** - * @brief Sets the SDIO clock to data mode (25MHz or less). - * - * @param[in] sdcp pointer to the @p SDCDriver object - * - * @notapi - */ -void sdc_lld_set_data_clk(SDCDriver *sdcp) { - - (void)sdcp; - SDIO->CLKCR = (SDIO->CLKCR & 0xFFFFFF00) | STM32_SDIO_DIV_HS; -} - -/** - * @brief Stops the SDIO clock. - * - * @param[in] sdcp pointer to the @p SDCDriver object - * - * @notapi - */ -void sdc_lld_stop_clk(SDCDriver *sdcp) { - - (void)sdcp; - SDIO->CLKCR = 0; - SDIO->POWER = 0; -} - -/** - * @brief Switches the bus to 4 bits mode. - * - * @param[in] sdcp pointer to the @p SDCDriver object - * @param[in] mode bus mode - * - * @notapi - */ -void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode) { - uint32_t clk = SDIO->CLKCR & ~SDIO_CLKCR_WIDBUS; - - (void)sdcp; - switch (mode) { - case SDC_MODE_1BIT: - SDIO->CLKCR = clk; - break; - case SDC_MODE_4BIT: - SDIO->CLKCR = clk | SDIO_CLKCR_WIDBUS_0; - break; - case SDC_MODE_8BIT: - SDIO->CLKCR = clk | SDIO_CLKCR_WIDBUS_1; - } -} - -/** - * @brief Sends an SDIO command with no response expected. - * - * @param[in] sdcp pointer to the @p SDCDriver object - * @param[in] cmd card command - * @param[in] arg command argument - * - * @notapi - */ -void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) { - - (void)sdcp; - SDIO->ARG = arg; - SDIO->CMD = (uint32_t)cmd | SDIO_CMD_CPSMEN; - while ((SDIO->STA & SDIO_STA_CMDSENT) == 0) - ; - SDIO->ICR = SDIO_ICR_CMDSENTC; -} - -/** - * @brief Sends an SDIO command with a short response expected. - * @note The CRC is not verified. - * - * @param[in] sdcp pointer to the @p SDCDriver object - * @param[in] cmd card command - * @param[in] arg command argument - * @param[out] resp pointer to the response buffer (one word) - * @return The operation status. - * @retval FALSE the operation succeeded. - * @retval TRUE the operation failed because timeout, CRC check or - * other errors. - * - * @notapi - */ -bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, - uint32_t *resp) { - uint32_t sta; - - (void)sdcp; - SDIO->ARG = arg; - SDIO->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_CPSMEN; - while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT | - SDIO_STA_CCRCFAIL)) == 0) - ; - SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC; - if ((sta & (SDIO_STA_CTIMEOUT)) != 0) - return TRUE; - *resp = SDIO->RESP1; - return FALSE; -} - -/** - * @brief Sends an SDIO command with a short response expected and CRC. - * - * @param[in] sdcp pointer to the @p SDCDriver object - * @param[in] cmd card command - * @param[in] arg command argument - * @param[out] resp pointer to the response buffer (one word) - * @return The operation status. - * @retval FALSE the operation succeeded. - * @retval TRUE the operation failed because timeout, CRC check or - * other errors. - * - * @notapi - */ -bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, - uint32_t *resp) { - uint32_t sta; - - (void)sdcp; - SDIO->ARG = arg; - SDIO->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_CPSMEN; - while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT | - SDIO_STA_CCRCFAIL)) == 0) - ; - SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC; - if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0) - return TRUE; - *resp = SDIO->RESP1; - return FALSE; -} - -/** - * @brief Sends an SDIO command with a long response expected and CRC. - * - * @param[in] sdcp pointer to the @p SDCDriver object - * @param[in] cmd card command - * @param[in] arg command argument - * @param[out] resp pointer to the response buffer (four words) - * @return The operation status. - * @retval FALSE the operation succeeded. - * @retval TRUE the operation failed because timeout, CRC check or - * other errors. - * - * @notapi - */ -bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, - uint32_t *resp) { - - uint32_t sta; - - (void)sdcp; - SDIO->ARG = arg; - SDIO->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_WAITRESP_1 | - SDIO_CMD_CPSMEN; - while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT | - SDIO_STA_CCRCFAIL)) == 0) - ; - SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC; - if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0) - return TRUE; - *resp = SDIO->RESP1; - return FALSE; -} - -/** - * @brief Reads one or more blocks. - * - * @param[in] sdcp pointer to the @p SDCDriver object - * @param[in] startblk first block to read - * @param[out] buf pointer to the read buffer - * @param[in] n number of blocks to read - * @return The operation status. - * @retval FALSE operation succeeded, the requested blocks have been - * read. - * @retval TRUE operation failed, the state of the buffer is uncertain. - * - * @notapi - */ -bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk, - uint8_t *buf, uint32_t n) { - -#if STM32_SDC_UNALIGNED_SUPPORT - if (((unsigned)buf & 3) != 0) { - uint32_t i; - for (i = 0; i < n; i++) { - if (sdc_lld_read_single(sdcp, startblk, u.buf)) - return TRUE; - memcpy(buf, u.buf, SDC_BLOCK_SIZE); - buf += SDC_BLOCK_SIZE; - startblk++; - } - return FALSE; - } -#endif - if (n == 1) - return sdc_lld_read_single(sdcp, startblk, buf); - return sdc_lld_read_multiple(sdcp, startblk, buf, n); -} - -/** - * @brief Writes one or more blocks. - * - * @param[in] sdcp pointer to the @p SDCDriver object - * @param[in] startblk first block to write - * @param[out] buf pointer to the write buffer - * @param[in] n number of blocks to write - * @return The operation status. - * @retval FALSE operation succeeded, the requested blocks have been - * written. - * @retval TRUE operation failed. - * - * @notapi - */ -bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk, - const uint8_t *buf, uint32_t n) { - - #if STM32_SDC_UNALIGNED_SUPPORT - if (((unsigned)buf & 3) != 0) { - uint32_t i; - for (i = 0; i < n; i++) { - memcpy(u.buf, buf, SDC_BLOCK_SIZE); - buf += SDC_BLOCK_SIZE; - if (sdc_lld_write_single(sdcp, startblk, u.buf)) - return TRUE; - startblk++; - } - return FALSE; - } -#endif - if (n == 1) - return sdc_lld_write_single(sdcp, startblk, buf); - return sdc_lld_write_multiple(sdcp, startblk, buf, n); -} - -#endif /* HAL_USE_SDC */ - -/** @} */ diff --git a/os/hal/platforms/STM32/DMAv1/sdc_lld.h b/os/hal/platforms/STM32/DMAv1/sdc_lld.h deleted file mode 100644 index eea76dadd..000000000 --- a/os/hal/platforms/STM32/DMAv1/sdc_lld.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT 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 STM32/sdc_lld.h - * @brief STM32 SDC subsystem low level driver header. - * - * @addtogroup SDC - * @{ - */ - -#ifndef _SDC_LLD_H_ -#define _SDC_LLD_H_ - -#if HAL_USE_SDC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @brief SDIO data timeout in SDIO clock cycles. - */ -#if !defined(STM32_SDC_DATATIMEOUT) || defined(__DOXYGEN__) -#define STM32_SDC_DATATIMEOUT 0x000FFFFF -#endif - -/** - * @brief SDIO DMA priority (0..3|lowest..highest). - */ -#if !defined(STM32_SDC_SDIO_DMA_PRIORITY) || defined(__DOXYGEN__) -#define STM32_SDC_SDIO_DMA_PRIORITY 3 -#endif - -/** - * @brief SDIO interrupt priority level setting. - */ -#if !defined(STM32_SDC_SDIO_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_SDC_SDIO_IRQ_PRIORITY 9 -#endif - -/** - * @brief SDIO support for unaligned transfers. - */ -#if !defined(STM32_SDC_UNALIGNED_SUPPORT) || defined(__DOXYGEN__) -#define STM32_SDC_UNALIGNED_SUPPORT TRUE -#endif - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if !STM32_HAS_SDIO -#error "SDIO not present in the selected device" -#endif - -#if !defined(STM32_DMA_REQUIRED) -#define STM32_DMA_REQUIRED -#endif - -/* - * SDIO clock divider. - */ -#if STM32_HCLK > 48000000 -#define STM32_SDIO_DIV_HS 0x01 -#define STM32_SDIO_DIV_LS 0xB2 -#else -#define STM32_SDIO_DIV_HS 0x00 -#define STM32_SDIO_DIV_LS 0x76 -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Type of SDIO bus mode. - */ -typedef enum { - SDC_MODE_1BIT = 0, - SDC_MODE_4BIT, - SDC_MODE_8BIT -} sdcbusmode_t; - -/** - * @brief Type of card flags. - */ -typedef uint32_t sdcmode_t; - -/** - * @brief Type of a structure representing an SDC driver. - */ -typedef struct SDCDriver SDCDriver; - -/** - * @brief Driver configuration structure. - * @note It could be empty on some architectures. - */ -typedef struct { - uint32_t dummy; -} SDCConfig; - -/** - * @brief Structure representing an SDC driver. - */ -struct SDCDriver { - /** - * @brief Driver state. - */ - sdcstate_t state; - /** - * @brief Current configuration data. - */ - const SDCConfig *config; - /** - * @brief Various flags regarding the mounted card. - */ - sdcmode_t cardmode; - /** - * @brief Card CID. - */ - uint32_t cid[4]; - /** - * @brief Card CSD. - */ - uint32_t csd[4]; - /** - * @brief Card RCA. - */ - uint32_t rca; - /* End of the mandatory fields.*/ - /** - * @brief Thread waiting for I/O completion IRQ. - */ - Thread *thread; -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if !defined(__DOXYGEN__) -extern SDCDriver SDCD1; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void sdc_lld_init(void); - void sdc_lld_start(SDCDriver *sdcp); - void sdc_lld_stop(SDCDriver *sdcp); - void sdc_lld_start_clk(SDCDriver *sdcp); - void sdc_lld_set_data_clk(SDCDriver *sdcp); - void sdc_lld_stop_clk(SDCDriver *sdcp); - void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode); - void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg); - bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, - uint32_t *resp); - bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, - uint32_t *resp); - bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, - uint32_t *resp); - bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk, - uint8_t *buf, uint32_t n); - bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk, - const uint8_t *buf, uint32_t n); - bool_t sdc_lld_is_card_inserted(SDCDriver *sdcp); - bool_t sdc_lld_is_write_protected(SDCDriver *sdcp); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_SDC */ - -#endif /* _SDC_LLD_H_ */ - -/** @} */ diff --git a/os/hal/platforms/STM32/DMAv1/spi_lld.c b/os/hal/platforms/STM32/DMAv1/spi_lld.c deleted file mode 100644 index 9302b0102..000000000 --- a/os/hal/platforms/STM32/DMAv1/spi_lld.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT 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 STM32/spi_lld.c - * @brief STM32 SPI subsystem low level driver source. - * - * @addtogroup SPI - * @{ - */ - -#include "ch.h" -#include "hal.h" - -#if HAL_USE_SPI || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** @brief SPI1 driver identifier.*/ -#if STM32_SPI_USE_SPI1 || defined(__DOXYGEN__) -SPIDriver SPID1; -#endif - -/** @brief SPI2 driver identifier.*/ -#if STM32_SPI_USE_SPI2 || defined(__DOXYGEN__) -SPIDriver SPID2; -#endif - -/** @brief SPI3 driver identifier.*/ -#if STM32_SPI_USE_SPI3 || defined(__DOXYGEN__) -SPIDriver SPID3; -#endif - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ - -static uint16_t dummytx; -static uint16_t dummyrx; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Stops the SPI DMA channels. - * - * @param[in] spip pointer to the @p SPIDriver object - */ -#define dma_stop(spip) { \ - dmaStreamDisable(spip->dmatx); \ - dmaStreamDisable(spip->dmarx); \ -} - -/** - * @brief Starts the SPI DMA channels. - * - * @param[in] spip pointer to the @p SPIDriver object - */ -#define dma_start(spip) { \ - dmaChannelEnable((spip)->dmarx); \ - dmaChannelEnable((spip)->dmatx); \ -} - -/** - * @brief Shared end-of-rx service routine. - * - * @param[in] spip pointer to the @p SPIDriver object - * @param[in] flags pre-shifted content of the ISR register - */ -static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { - - /* DMA errors handling.*/ -#if defined(STM32_SPI_DMA_ERROR_HOOK) - if ((flags & STM32_DMA_ISR_TEIF) != 0) { - STM32_SPI_DMA_ERROR_HOOK(spip); - } -#else - (void)flags; -#endif - - /* Stop everything.*/ - dma_stop(spip); - - /* Portable SPI ISR code defined in the high level driver, note, it is - a macro.*/ - _spi_isr_code(spip); -} - -/** - * @brief Shared end-of-tx service routine. - * - * @param[in] spip pointer to the @p SPIDriver object - * @param[in] flags pre-shifted content of the ISR register - */ -static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) { - - /* DMA errors handling.*/ -#if defined(STM32_SPI_DMA_ERROR_HOOK) - (void)spip; - if ((flags & STM32_DMA_ISR_TEIF) != 0) { - STM32_SPI_DMA_ERROR_HOOK(spip); - } -#else - (void)spip; - (void)flags; -#endif -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level SPI driver initialization. - * - * @notapi - */ -void spi_lld_init(void) { - - dummytx = 0xFFFF; - -#if STM32_SPI_USE_SPI1 - spiObjectInit(&SPID1); - SPID1.thread = NULL; - SPID1.spi = SPI1; - SPID1.dmarx = STM32_DMA1_STREAM2; - SPID1.dmatx = STM32_DMA1_STREAM3; -#endif - -#if STM32_SPI_USE_SPI2 - spiObjectInit(&SPID2); - SPID2.thread = NULL; - SPID2.spi = SPI2; - SPID2.dmarx = STM32_DMA1_STREAM4; - SPID2.dmatx = STM32_DMA1_STREAM5; -#endif - -#if STM32_SPI_USE_SPI3 - spiObjectInit(&SPID3); - SPID3.thread = NULL; - SPID3.spi = SPI3; - SPID3.dmarx = STM32_DMA2_STREAM1; - SPID3.dmatx = STM32_DMA2_STREAM2; -#endif -} - -/** - * @brief Configures and activates the SPI peripheral. - * - * @param[in] spip pointer to the @p SPIDriver object - * - * @notapi - */ -void spi_lld_start(SPIDriver *spip) { - - /* If in stopped state then enables the SPI and DMA clocks.*/ - if (spip->state == SPI_STOP) { -#if STM32_SPI_USE_SPI1 - if (&SPID1 == spip) { - bool_t b; - b = dmaStreamAllocate(STM32_DMA1_STREAM2, - STM32_SPI_SPI1_IRQ_PRIORITY, - (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, - (void *)spip); - chDbgAssert(!b, "spi_lld_start(), #1", "stream already allocated"); - b = dmaStreamAllocate(STM32_DMA1_STREAM3, - STM32_SPI_SPI1_IRQ_PRIORITY, - (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, - (void *)spip); - chDbgAssert(!b, "spi_lld_start(), #2", "stream already allocated"); - RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; - } -#endif -#if STM32_SPI_USE_SPI2 - if (&SPID2 == spip) { - bool_t b; - b = dmaStreamAllocate(STM32_DMA1_STREAM4, - STM32_SPI_SPI2_IRQ_PRIORITY, - (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, - (void *)spip); - chDbgAssert(!b, "spi_lld_start(), #3", "stream already allocated"); - b = dmaStreamAllocate(STM32_DMA1_STREAM5, - STM32_SPI_SPI2_IRQ_PRIORITY, - (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, - (void *)spip); - chDbgAssert(!b, "spi_lld_start(), #4", "stream already allocated"); - RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; - } -#endif -#if STM32_SPI_USE_SPI3 - if (&SPID3 == spip) { - bool_t b; - b = dmaStreamAllocate(STM32_DMA1_STREAM1, - STM32_SPI_SPI3_IRQ_PRIORITY, - (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, - (void *)spip); - chDbgAssert(!b, "spi_lld_start(), #5", "stream already allocated"); - b = dmaStreamAllocate(STM32_DMA1_STREAM2, - STM32_SPI_SPI3_IRQ_PRIORITY, - (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, - (void *)spip); - chDbgAssert(!b, "spi_lld_start(), #6", "stream already allocated"); - RCC->APB1ENR |= RCC_APB1ENR_SPI3EN; - } -#endif - - /* DMA setup.*/ - dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR); - dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR); - } - - /* More DMA setup.*/ - if ((spip->config->cr1 & SPI_CR1_DFF) == 0) - spip->dmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) | - STM32_DMA_CR_TEIE | - STM32_DMA_CR_PSIZE_BYTE | - STM32_DMA_CR_MSIZE_BYTE; /* 8 bits transfers. */ - else - spip->dmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) | - STM32_DMA_CR_TEIE | - STM32_DMA_CR_PSIZE_HWORD | - STM32_DMA_CR_MSIZE_HWORD; /* 16 bits transfers. */ - - /* SPI setup and enable.*/ - spip->spi->CR1 = 0; - spip->spi->CR1 = spip->config->cr1 | SPI_CR1_MSTR | SPI_CR1_SSM | - SPI_CR1_SSI; - spip->spi->CR2 = SPI_CR2_SSOE | SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN; - spip->spi->CR1 |= SPI_CR1_SPE; -} - -/** - * @brief Deactivates the SPI peripheral. - * - * @param[in] spip pointer to the @p SPIDriver object - * - * @notapi - */ -void spi_lld_stop(SPIDriver *spip) { - - /* If in ready state then disables the SPI clock.*/ - if (spip->state == SPI_READY) { - - /* SPI disable.*/ - spip->spi->CR1 = 0; - -#if STM32_SPI_USE_SPI1 - if (&SPID1 == spip) { - dmaStreamRelease(STM32_DMA1_STREAM2); - dmaStreamRelease(STM32_DMA1_STREAM3); - RCC->APB2ENR &= ~RCC_APB2ENR_SPI1EN; - } -#endif -#if STM32_SPI_USE_SPI2 - if (&SPID2 == spip) { - dmaStreamRelease(STM32_DMA1_STREAM4); - dmaStreamRelease(STM32_DMA1_STREAM5); - RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN; - } -#endif -#if STM32_SPI_USE_SPI3 - if (&SPID3 == spip) { - dmaStreamRelease(STM32_DMA1_STREAM1); - dmaStreamRelease(STM32_DMA1_STREAM2); - RCC->APB1ENR &= ~RCC_APB1ENR_SPI3EN; - } -#endif - } -} - -/** - * @brief Asserts the slave select signal and prepares for transfers. - * - * @param[in] spip pointer to the @p SPIDriver object - * - * @notapi - */ -void spi_lld_select(SPIDriver *spip) { - - palClearPad(spip->config->ssport, spip->config->sspad); -} - -/** - * @brief Deasserts the slave select signal. - * @details The previously selected peripheral is unselected. - * - * @param[in] spip pointer to the @p SPIDriver object - * - * @notapi - */ -void spi_lld_unselect(SPIDriver *spip) { - - palSetPad(spip->config->ssport, spip->config->sspad); -} - -/** - * @brief Ignores data on the SPI bus. - * @details This asynchronous function starts the transmission of a series of - * idle words on the SPI bus and ignores the received data. - * @post At the end of the operation the configured callback is invoked. - * - * @param[in] spip pointer to the @p SPIDriver object - * @param[in] n number of words to be ignored - * - * @notapi - */ -void spi_lld_ignore(SPIDriver *spip, size_t n) { - - dmaStreamSetMemory0(spip->dmarx, &dummyrx); - dmaStreamSetTransactionSize(spip->dmarx, n); - dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | - STM32_DMA_CR_TCIE | STM32_DMA_CR_EN); - dmaStreamSetMemory0(spip->dmatx, &dummytx); - dmaStreamSetTransactionSize(spip->dmatx, n); - dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | - STM32_DMA_CR_EN); -} - -/** - * @brief Exchanges data on the SPI bus. - * @details This asynchronous function starts a simultaneous transmit/receive - * operation. - * @post At the end of the operation the configured callback is invoked. - * @note The buffers are organized as uint8_t arrays for data sizes below or - * equal to 8 bits else it is organized as uint16_t arrays. - * - * @param[in] spip pointer to the @p SPIDriver object - * @param[in] n number of words to be exchanged - * @param[in] txbuf the pointer to the transmit buffer - * @param[out] rxbuf the pointer to the receive buffer - * - * @notapi - */ -void spi_lld_exchange(SPIDriver *spip, size_t n, - const void *txbuf, void *rxbuf) { - - dmaStreamSetMemory0(spip->dmarx, rxbuf); - dmaStreamSetTransactionSize(spip->dmarx, n); - dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | - STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC | - STM32_DMA_CR_EN); - dmaStreamSetMemory0(spip->dmatx, txbuf); - dmaStreamSetTransactionSize(spip->dmatx, n); - dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | - STM32_DMA_CR_MINC | STM32_DMA_CR_EN); -} - -/** - * @brief Sends data over the SPI bus. - * @details This asynchronous function starts a transmit operation. - * @post At the end of the operation the configured callback is invoked. - * @note The buffers are organized as uint8_t arrays for data sizes below or - * equal to 8 bits else it is organized as uint16_t arrays. - * - * @param[in] spip pointer to the @p SPIDriver object - * @param[in] n number of words to send - * @param[in] txbuf the pointer to the transmit buffer - * - * @notapi - */ -void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { - - dmaStreamSetMemory0(spip->dmarx, &dummyrx); - dmaStreamSetTransactionSize(spip->dmarx, n); - dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | - STM32_DMA_CR_TCIE | STM32_DMA_CR_EN); - dmaStreamSetMemory0(spip->dmatx, txbuf); - dmaStreamSetTransactionSize(spip->dmatx, n); - dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | - STM32_DMA_CR_MINC | STM32_DMA_CR_EN); -} - -/** - * @brief Receives data from the SPI bus. - * @details This asynchronous function starts a receive operation. - * @post At the end of the operation the configured callback is invoked. - * @note The buffers are organized as uint8_t arrays for data sizes below or - * equal to 8 bits else it is organized as uint16_t arrays. - * - * @param[in] spip pointer to the @p SPIDriver object - * @param[in] n number of words to receive - * @param[out] rxbuf the pointer to the receive buffer - * - * @notapi - */ -void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { - - dmaStreamSetMemory0(spip->dmarx, rxbuf); - dmaStreamSetTransactionSize(spip->dmarx, n); - dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | - STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC | - STM32_DMA_CR_EN); - dmaStreamSetMemory0(spip->dmatx, &dummytx); - dmaStreamSetTransactionSize(spip->dmatx, n); - dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | - STM32_DMA_CR_EN); -} - -/** - * @brief Exchanges one frame using a polled wait. - * @details This synchronous function exchanges one frame using a polled - * synchronization method. This function is useful when exchanging - * small amount of data on high speed channels, usually in this - * situation is much more efficient just wait for completion using - * polling than suspending the thread waiting for an interrupt. - * - * @param[in] spip pointer to the @p SPIDriver object - * @param[in] frame the data frame to send over the SPI bus - * @return The received data frame from the SPI bus. - */ -uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) { - - spip->spi->DR = frame; - while ((spip->spi->SR & SPI_SR_RXNE) == 0) - ; - return spip->spi->DR; -} - -#endif /* HAL_USE_SPI */ - -/** @} */ diff --git a/os/hal/platforms/STM32/DMAv1/spi_lld.h b/os/hal/platforms/STM32/DMAv1/spi_lld.h deleted file mode 100644 index c8c1e0661..000000000 --- a/os/hal/platforms/STM32/DMAv1/spi_lld.h +++ /dev/null @@ -1,285 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT 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 STM32/spi_lld.h - * @brief STM32 SPI subsystem low level driver header. - * - * @addtogroup SPI - * @{ - */ - -#ifndef _SPI_LLD_H_ -#define _SPI_LLD_H_ - -#if HAL_USE_SPI || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @brief SPI1 driver enable switch. - * @details If set to @p TRUE the support for SPI1 is included. - * @note The default is @p TRUE. - */ -#if !defined(STM32_SPI_USE_SPI1) || defined(__DOXYGEN__) -#define STM32_SPI_USE_SPI1 TRUE -#endif - -/** - * @brief SPI2 driver enable switch. - * @details If set to @p TRUE the support for SPI2 is included. - * @note The default is @p TRUE. - */ -#if !defined(STM32_SPI_USE_SPI2) || defined(__DOXYGEN__) -#define STM32_SPI_USE_SPI2 TRUE -#endif - -/** - * @brief SPI3 driver enable switch. - * @details If set to @p TRUE the support for SPI3 is included. - * @note The default is @p TRUE. - */ -#if !defined(STM32_SPI_USE_SPI3) || defined(__DOXYGEN__) -#define STM32_SPI_USE_SPI3 FALSE -#endif - -/** - * @brief SPI1 DMA priority (0..3|lowest..highest). - * @note The priority level is used for both the TX and RX DMA channels but - * because of the channels ordering the RX channel has always priority - * over the TX channel. - */ -#if !defined(STM32_SPI_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__) -#define STM32_SPI_SPI1_DMA_PRIORITY 1 -#endif - -/** - * @brief SPI2 DMA priority (0..3|lowest..highest). - * @note The priority level is used for both the TX and RX DMA channels but - * because of the channels ordering the RX channel has always priority - * over the TX channel. - */ -#if !defined(STM32_SPI_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__) -#define STM32_SPI_SPI2_DMA_PRIORITY 1 -#endif - -/** - * @brief SPI3 DMA priority (0..3|lowest..highest). - * @note The priority level is used for both the TX and RX DMA channels but - * because of the channels ordering the RX channel has always priority - * over the TX channel. - */ -#if !defined(STM32_SPI_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__) -#define STM32_SPI_SPI3_DMA_PRIORITY 1 -#endif - -/** - * @brief SPI1 interrupt priority level setting. - */ -#if !defined(STM32_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_SPI_SPI1_IRQ_PRIORITY 10 -#endif - -/** - * @brief SPI2 interrupt priority level setting. - */ -#if !defined(STM32_SPI_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_SPI_SPI2_IRQ_PRIORITY 10 -#endif - -/** - * @brief SPI3 interrupt priority level setting. - */ -#if !defined(STM32_SPI_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_SPI_SPI3_IRQ_PRIORITY 10 -#endif - -/** - * @brief SPI DMA error hook. - * @note The default action for DMA errors is a system halt because DMA - * error can only happen because programming errors. - */ -#if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__) -#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt() -#endif - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if STM32_SPI_USE_SPI1 && !STM32_HAS_SPI1 -#error "SPI1 not present in the selected device" -#endif - -#if STM32_SPI_USE_SPI2 && !STM32_HAS_SPI2 -#error "SPI2 not present in the selected device" -#endif - -#if STM32_SPI_USE_SPI3 && !STM32_HAS_SPI3 -#error "SPI3 not present in the selected device" -#endif - -#if !STM32_SPI_USE_SPI1 && !STM32_SPI_USE_SPI2 && !STM32_SPI_USE_SPI3 -#error "SPI driver activated but no SPI peripheral assigned" -#endif - -#if !defined(STM32_DMA_REQUIRED) -#define STM32_DMA_REQUIRED -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Type of a structure representing an SPI driver. - */ -typedef struct SPIDriver SPIDriver; - -/** - * @brief SPI notification callback type. - * - * @param[in] spip pointer to the @p SPIDriver object triggering the - * callback - */ -typedef void (*spicallback_t)(SPIDriver *spip); - -/** - * @brief Driver configuration structure. - */ -typedef struct { - /** - * @brief Operation complete callback or @p NULL. - */ - spicallback_t end_cb; - /* End of the mandatory fields.*/ - /** - * @brief The chip select line port. - */ - ioportid_t ssport; - /** - * @brief The chip select line pad number. - */ - uint16_t sspad; - /** - * @brief SPI initialization data. - */ - uint16_t cr1; -} SPIConfig; - -/** - * @brief Structure representing a SPI driver. - */ -struct SPIDriver{ - /** - * @brief Driver state. - */ - spistate_t state; - /** - * @brief Current configuration data. - */ - const SPIConfig *config; -#if SPI_USE_WAIT || defined(__DOXYGEN__) - /** - * @brief Waiting thread. - */ - Thread *thread; -#endif /* SPI_USE_WAIT */ -#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) -#if CH_USE_MUTEXES || defined(__DOXYGEN__) - /** - * @brief Mutex protecting the bus. - */ - Mutex mutex; -#elif CH_USE_SEMAPHORES - Semaphore semaphore; -#endif -#endif /* SPI_USE_MUTUAL_EXCLUSION */ -#if defined(SPI_DRIVER_EXT_FIELDS) - SPI_DRIVER_EXT_FIELDS -#endif - /* End of the mandatory fields.*/ - /** - * @brief Pointer to the SPIx registers block. - */ - SPI_TypeDef *spi; - /** - * @brief Receive DMA channel. - */ - const stm32_dma_stream_t *dmarx; - /** - * @brief Transmit DMA channel. - */ - const stm32_dma_stream_t *dmatx; - /** - * @brief DMA mode bit mask. - */ - uint32_t dmamode; -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if STM32_SPI_USE_SPI1 && !defined(__DOXYGEN__) -extern SPIDriver SPID1; -#endif - -#if STM32_SPI_USE_SPI2 && !defined(__DOXYGEN__) -extern SPIDriver SPID2; -#endif - -#if STM32_SPI_USE_SPI3 && !defined(__DOXYGEN__) -extern SPIDriver SPID3; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void spi_lld_init(void); - void spi_lld_start(SPIDriver *spip); - void spi_lld_stop(SPIDriver *spip); - void spi_lld_select(SPIDriver *spip); - void spi_lld_unselect(SPIDriver *spip); - void spi_lld_ignore(SPIDriver *spip, size_t n); - void spi_lld_exchange(SPIDriver *spip, size_t n, - const void *txbuf, void *rxbuf); - void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf); - void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf); - uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_SPI */ - -#endif /* _SPI_LLD_H_ */ - -/** @} */ diff --git a/os/hal/platforms/STM32/DMAv1/uart_lld.c b/os/hal/platforms/STM32/DMAv1/uart_lld.c deleted file mode 100644 index a9303744d..000000000 --- a/os/hal/platforms/STM32/DMAv1/uart_lld.c +++ /dev/null @@ -1,557 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT 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 STM32/uart_lld.c - * @brief STM32 low level UART driver code. - * - * @addtogroup UART - * @{ - */ - -#include "ch.h" -#include "hal.h" - -#if HAL_USE_UART || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** @brief USART1 UART driver identifier.*/ -#if STM32_UART_USE_USART1 || defined(__DOXYGEN__) -UARTDriver UARTD1; -#endif - -/** @brief USART2 UART driver identifier.*/ -#if STM32_UART_USE_USART2 || defined(__DOXYGEN__) -UARTDriver UARTD2; -#endif - -/** @brief USART3 UART driver identifier.*/ -#if STM32_UART_USE_USART3 || defined(__DOXYGEN__) -UARTDriver UARTD3; -#endif - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Status bits translation. - * - * @param[in] sr USART SR register value - * - * @return The error flags. - */ -static uartflags_t translate_errors(uint16_t sr) { - uartflags_t sts = 0; - - if (sr & USART_SR_ORE) - sts |= UART_OVERRUN_ERROR; - if (sr & USART_SR_PE) - sts |= UART_PARITY_ERROR; - if (sr & USART_SR_FE) - sts |= UART_FRAMING_ERROR; - if (sr & USART_SR_NE) - sts |= UART_NOISE_ERROR; - if (sr & USART_SR_LBD) - sts |= UART_BREAK_DETECTED; - return sts; -} - -/** - * @brief Puts the receiver in the UART_RX_IDLE state. - * - * @param[in] uartp pointer to the @p UARTDriver object - */ -static void set_rx_idle_loop(UARTDriver *uartp) { - uint32_t mode; - - /* RX DMA channel preparation, if the char callback is defined then the - TCIE interrupt is enabled too.*/ - if (uartp->config->rxchar_cb == NULL) - mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TEIE; - else - mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TEIE | - STM32_DMA_CR_TCIE; - dmaStreamSetMemory0(uartp->dmarx, &uartp->rxbuf); - dmaStreamSetTransactionSize(uartp->dmarx, 1); - dmaStreamSetMode(uartp->dmarx, uartp->dmamode | mode); - dmaStreamEnable(uartp->dmarx); -} - -/** - * @brief USART de-initialization. - * @details This function must be invoked with interrupts disabled. - * - * @param[in] uartp pointer to the @p UARTDriver object - */ -static void usart_stop(UARTDriver *uartp) { - - /* Stops RX and TX DMA channels.*/ - dmaStreamDisable(uartp->dmarx); - dmaStreamClearInterrupt(uartp->dmarx); - dmaStreamDisable(uartp->dmatx); - dmaStreamClearInterrupt(uartp->dmatx); - - /* Stops USART operations.*/ - uartp->usart->CR1 = 0; - uartp->usart->CR2 = 0; - uartp->usart->CR3 = 0; -} - -/** - * @brief USART initialization. - * @details This function must be invoked with interrupts disabled. - * - * @param[in] uartp pointer to the @p UARTDriver object - */ -static void usart_start(UARTDriver *uartp) { - uint16_t cr1; - USART_TypeDef *u = uartp->usart; - - /* Defensive programming, starting from a clean state.*/ - usart_stop(uartp); - - /* Baud rate setting.*/ - if (uartp->usart == USART1) - u->BRR = STM32_PCLK2 / uartp->config->speed; - else - u->BRR = STM32_PCLK1 / uartp->config->speed; - - /* Resetting eventual pending status flags.*/ - (void)u->SR; /* SR reset step 1.*/ - (void)u->DR; /* SR reset step 2.*/ - u->SR = 0; - - /* Note that some bits are enforced because required for correct driver - operations.*/ - if (uartp->config->txend2_cb == NULL) - cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE; - else - cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE | - USART_CR1_TCIE; - u->CR1 = uartp->config->cr1 | cr1; - u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE; - u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR | - USART_CR3_EIE; - - /* Starting the receiver idle loop.*/ - set_rx_idle_loop(uartp); -} - -/** - * @brief RX DMA common service routine. - * - * @param[in] uartp pointer to the @p UARTDriver object - * @param[in] flags pre-shifted content of the ISR register - */ -static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) { - - /* DMA errors handling.*/ -#if defined(STM32_UART_DMA_ERROR_HOOK) - if ((flags & STM32_DMA_ISR_TEIF) != 0) { - STM32_UART_DMA_ERROR_HOOK(uartp); - } -#else - (void)flags; -#endif - - if (uartp->rxstate == UART_RX_IDLE) { - /* Receiver in idle state, a callback is generated, if enabled, for each - received character and then the driver stays in the same state.*/ - if (uartp->config->rxchar_cb != NULL) - uartp->config->rxchar_cb(uartp, uartp->rxbuf); - } - else { - /* Receiver in active state, a callback is generated, if enabled, after - a completed transfer.*/ - dmaStreamDisable(uartp->dmarx); - uartp->rxstate = UART_RX_COMPLETE; - if (uartp->config->rxend_cb != NULL) - uartp->config->rxend_cb(uartp); - /* If the callback didn't explicitly change state then the receiver - automatically returns to the idle state.*/ - if (uartp->rxstate == UART_RX_COMPLETE) { - uartp->rxstate = UART_RX_IDLE; - set_rx_idle_loop(uartp); - } - } -} - -/** - * @brief TX DMA common service routine. - * - * @param[in] uartp pointer to the @p UARTDriver object - * @param[in] flags pre-shifted content of the ISR register - */ -static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) { - - /* DMA errors handling.*/ -#if defined(STM32_UART_DMA_ERROR_HOOK) - if ((flags & STM32_DMA_ISR_TEIF) != 0) { - STM32_UART_DMA_ERROR_HOOK(uartp); - } -#else - (void)flags; -#endif - - dmaStreamDisable(uartp->dmatx); - /* A callback is generated, if enabled, after a completed transfer.*/ - uartp->txstate = UART_TX_COMPLETE; - if (uartp->config->txend1_cb != NULL) - uartp->config->txend1_cb(uartp); - /* If the callback didn't explicitly change state then the transmitter - automatically returns to the idle state.*/ - if (uartp->txstate == UART_TX_COMPLETE) - uartp->txstate = UART_TX_IDLE; -} - -/** - * @brief USART common service routine. - * - * @param[in] uartp pointer to the @p UARTDriver object - */ -static void serve_usart_irq(UARTDriver *uartp) { - uint16_t sr; - USART_TypeDef *u = uartp->usart; - - sr = u->SR; /* SR reset step 1.*/ - (void)u->DR; /* SR reset step 2.*/ - if (sr & (USART_SR_LBD | USART_SR_ORE | USART_SR_NE | - USART_SR_FE | USART_SR_PE)) { - u->SR = ~USART_SR_LBD; - if (uartp->config->rxerr_cb != NULL) - uartp->config->rxerr_cb(uartp, translate_errors(sr)); - } - if (sr & USART_SR_TC) { - u->SR = ~USART_SR_TC; - /* End of transmission, a callback is generated.*/ - if (uartp->config->txend2_cb != NULL) - uartp->config->txend2_cb(uartp); - } -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if STM32_UART_USE_USART1 || defined(__DOXYGEN__) -/** - * @brief USART1 IRQ handler. - * - * @isr - */ -CH_IRQ_HANDLER(USART1_IRQHandler) { - - CH_IRQ_PROLOGUE(); - - serve_usart_irq(&UARTD1); - - CH_IRQ_EPILOGUE(); -} -#endif /* STM32_UART_USE_USART1 */ - -#if STM32_UART_USE_USART2 || defined(__DOXYGEN__) -/** - * @brief USART2 IRQ handler. - * - * @isr - */ -CH_IRQ_HANDLER(USART2_IRQHandler) { - - CH_IRQ_PROLOGUE(); - - serve_usart_irq(&UARTD2); - - CH_IRQ_EPILOGUE(); -} -#endif /* STM32_UART_USE_USART2 */ - -#if STM32_UART_USE_USART3 || defined(__DOXYGEN__) -/** - * @brief USART3 IRQ handler. - * - * @isr - */ -CH_IRQ_HANDLER(USART3_IRQHandler) { - - CH_IRQ_PROLOGUE(); - - serve_usart_irq(&UARTD3); - - CH_IRQ_EPILOGUE(); -} -#endif /* STM32_UART_USE_USART3 */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level UART driver initialization. - * - * @notapi - */ -void uart_lld_init(void) { - -#if STM32_UART_USE_USART1 - uartObjectInit(&UARTD1); - UARTD1.usart = USART1; - UARTD1.dmarx = STM32_DMA1_STREAM5; - UARTD1.dmatx = STM32_DMA1_STREAM4; -#endif - -#if STM32_UART_USE_USART2 - uartObjectInit(&UARTD2); - UARTD2.usart = USART2; - UARTD2.dmarx = STM32_DMA1_STREAM6; - UARTD2.dmatx = STM32_DMA1_STREAM7; -#endif - -#if STM32_UART_USE_USART3 - uartObjectInit(&UARTD3); - UARTD3.usart = USART3; - UARTD3.dmarx = STM32_DMA1_STREAM3; - UARTD3.dmatx = STM32_DMA1_STREAM2; -#endif -} - -/** - * @brief Configures and activates the UART peripheral. - * - * @param[in] uartp pointer to the @p UARTDriver object - * - * @notapi - */ -void uart_lld_start(UARTDriver *uartp) { - - if (uartp->state == UART_STOP) { -#if STM32_UART_USE_USART1 - if (&UARTD1 == uartp) { - bool_t b; - b = dmaStreamAllocate(STM32_DMA1_STREAM4, - STM32_UART_USART1_IRQ_PRIORITY, - (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, - (void *)uartp); - chDbgAssert(!b, "uart_lld_start(), #1", "stream already allocated"); - b = dmaStreamAllocate(STM32_DMA1_STREAM5, - STM32_UART_USART1_IRQ_PRIORITY, - (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, - (void *)uartp); - chDbgAssert(!b, "uart_lld_start(), #2", "stream already allocated"); - RCC->APB2ENR |= RCC_APB2ENR_USART1EN; - NVICEnableVector(USART1_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY)); - } -#endif - -#if STM32_UART_USE_USART2 - if (&UARTD2 == uartp) { - bool_t b; - b = dmaStreamAllocate(STM32_DMA1_STREAM6, - STM32_UART_USART2_IRQ_PRIORITY, - (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, - (void *)uartp); - chDbgAssert(!b, "uart_lld_start(), #3", "stream already allocated"); - b = dmaStreamAllocate(STM32_DMA1_STREAM7, - STM32_UART_USART2_IRQ_PRIORITY, - (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, - (void *)uartp); - chDbgAssert(!b, "uart_lld_start(), #4", "stream already allocated"); - RCC->APB1ENR |= RCC_APB1ENR_USART2EN; - NVICEnableVector(USART2_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); - } -#endif - -#if STM32_UART_USE_USART3 - if (&UARTD3 == uartp) { - bool_t b; - b = dmaStreamAllocate(STM32_DMA1_STREAM2, - STM32_UART_USART3_IRQ_PRIORITY, - (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, - (void *)uartp); - chDbgAssert(!b, "uart_lld_start(), #5", "stream already allocated"); - b = dmaStreamAllocate(STM32_DMA1_STREAM3, - STM32_UART_USART3_IRQ_PRIORITY, - (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, - (void *)uartp); - chDbgAssert(!b, "uart_lld_start(), #6", "stream already allocated"); - RCC->APB1ENR |= RCC_APB1ENR_USART3EN; - NVICEnableVector(USART3_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY)); - } -#endif - - /* Static DMA setup, the transfer size depends on the USART settings, - it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/ - uartp->dmamode = STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY); - if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M) - uartp->dmamode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; - dmaStreamSetPeripheral(uartp->dmarx, &uartp->usart->DR); - dmaStreamSetPeripheral(uartp->dmatx, &uartp->usart->DR); - uartp->rxbuf = 0; - } - - uartp->rxstate = UART_RX_IDLE; - uartp->txstate = UART_TX_IDLE; - usart_start(uartp); -} - -/** - * @brief Deactivates the UART peripheral. - * - * @param[in] uartp pointer to the @p UARTDriver object - * - * @notapi - */ -void uart_lld_stop(UARTDriver *uartp) { - - if (uartp->state == UART_READY) { - usart_stop(uartp); - -#if STM32_UART_USE_USART1 - if (&UARTD1 == uartp) { - dmaStreamRelease(STM32_DMA1_STREAM4); - dmaStreamRelease(STM32_DMA1_STREAM5); - NVICDisableVector(USART1_IRQn); - RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN; - return; - } -#endif - -#if STM32_UART_USE_USART2 - if (&UARTD2 == uartp) { - dmaStreamRelease(STM32_DMA1_STREAM6); - dmaStreamRelease(STM32_DMA1_STREAM7); - NVICDisableVector(USART2_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN; - return; - } -#endif - -#if STM32_UART_USE_USART3 - if (&UARTD3 == uartp) { - dmaStreamRelease(STM32_DMA1_STREAM2); - dmaStreamRelease(STM32_DMA1_STREAM3); - NVICDisableVector(USART3_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN; - return; - } -#endif - } -} - -/** - * @brief Starts a transmission on the UART peripheral. - * @note The buffers are organized as uint8_t arrays for data sizes below - * or equal to 8 bits else it is organized as uint16_t arrays. - * - * @param[in] uartp pointer to the @p UARTDriver object - * @param[in] n number of data frames to send - * @param[in] txbuf the pointer to the transmit buffer - * - * @notapi - */ -void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { - - /* TX DMA channel preparation and start.*/ - dmaStreamSetMemory0(uartp->dmatx, txbuf); - dmaStreamSetTransactionSize(uartp->dmatx, n); - dmaStreamSetMode(uartp->dmatx, uartp->dmamode | STM32_DMA_CR_DIR_M2P | - STM32_DMA_CR_MINC | STM32_DMA_CR_TEIE | - STM32_DMA_CR_TCIE); - dmaStreamEnable(uartp->dmatx); -} - -/** - * @brief Stops any ongoing transmission. - * @note Stopping a transmission also suppresses the transmission callbacks. - * - * @param[in] uartp pointer to the @p UARTDriver object - * - * @return The number of data frames not transmitted by the - * stopped transmit operation. - * - * @notapi - */ -size_t uart_lld_stop_send(UARTDriver *uartp) { - - dmaStreamDisable(uartp->dmatx); - dmaStreamClearInterrupt(uartp->dmatx); - return dmaStreamGetTransactionSize(uartp->dmatx); -} - -/** - * @brief Starts a receive operation on the UART peripheral. - * @note The buffers are organized as uint8_t arrays for data sizes below - * or equal to 8 bits else it is organized as uint16_t arrays. - * - * @param[in] uartp pointer to the @p UARTDriver object - * @param[in] n number of data frames to send - * @param[out] rxbuf the pointer to the receive buffer - * - * @notapi - */ -void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) { - - /* Stopping previous activity (idle state).*/ - dmaStreamDisable(uartp->dmarx); - dmaStreamClearInterrupt(uartp->dmarx); - - /* RX DMA channel preparation and start.*/ - dmaStreamSetMemory0(uartp->dmarx, rxbuf); - dmaStreamSetTransactionSize(uartp->dmarx, n); - dmaStreamSetMode(uartp->dmarx, uartp->dmamode | STM32_DMA_CR_DIR_P2M | - STM32_DMA_CR_MINC | STM32_DMA_CR_TEIE | - STM32_DMA_CR_TCIE); - dmaStreamEnable(uartp->dmarx); -} - -/** - * @brief Stops any ongoing receive operation. - * @note Stopping a receive operation also suppresses the receive callbacks. - * - * @param[in] uartp pointer to the @p UARTDriver object - * - * @return The number of data frames not received by the - * stopped receive operation. - * - * @notapi - */ -size_t uart_lld_stop_receive(UARTDriver *uartp) { - size_t n; - - dmaStreamDisable(uartp->dmarx); - dmaStreamClearInterrupt(uartp->dmarx); - n = dmaStreamGetTransactionSize(uartp->dmarx); - set_rx_idle_loop(uartp); - return n; -} - -#endif /* HAL_USE_UART */ - -/** @} */ diff --git a/os/hal/platforms/STM32/DMAv1/uart_lld.h b/os/hal/platforms/STM32/DMAv1/uart_lld.h deleted file mode 100644 index aff7f52ba..000000000 --- a/os/hal/platforms/STM32/DMAv1/uart_lld.h +++ /dev/null @@ -1,318 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT 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 STM32/uart_lld.h - * @brief STM32 low level UART driver header. - * - * @addtogroup UART - * @{ - */ - -#ifndef _UART_LLD_H_ -#define _UART_LLD_H_ - -#if HAL_USE_UART || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @brief UART driver on USART1 enable switch. - * @details If set to @p TRUE the support for USART1 is included. - * @note The default is @p FALSE. - */ -#if !defined(STM32_UART_USE_USART1) || defined(__DOXYGEN__) -#define STM32_UART_USE_USART1 TRUE -#endif - -/** - * @brief UART driver on USART2 enable switch. - * @details If set to @p TRUE the support for USART2 is included. - * @note The default is @p FALSE. - */ -#if !defined(STM32_UART_USE_USART2) || defined(__DOXYGEN__) -#define STM32_UART_USE_USART2 TRUE -#endif - -/** - * @brief UART driver on USART3 enable switch. - * @details If set to @p TRUE the support for USART3 is included. - * @note The default is @p FALSE. - */ -#if !defined(STM32_UART_USE_USART3) || defined(__DOXYGEN__) -#define STM32_UART_USE_USART3 TRUE -#endif - -/** - * @brief USART1 interrupt priority level setting. - */ -#if !defined(STM32_UART_USART1_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_UART_USART1_IRQ_PRIORITY 12 -#endif - -/** - * @brief USART2 interrupt priority level setting. - */ -#if !defined(STM32_UART_USART2_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_UART_USART2_IRQ_PRIORITY 12 -#endif - -/** - * @brief USART3 interrupt priority level setting. - */ -#if !defined(STM32_UART_USART3_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_UART_USART3_IRQ_PRIORITY 12 -#endif - -/** - * @brief USART1 DMA priority (0..3|lowest..highest). - * @note The priority level is used for both the TX and RX DMA channels but - * because of the channels ordering the RX channel has always priority - * over the TX channel. - */ -#if !defined(STM32_UART_USART1_DMA_PRIORITY) || defined(__DOXYGEN__) -#define STM32_UART_USART1_DMA_PRIORITY 0 -#endif - -/** - * @brief USART2 DMA priority (0..3|lowest..highest). - * @note The priority level is used for both the TX and RX DMA channels but - * because of the channels ordering the RX channel has always priority - * over the TX channel. - */ -#if !defined(STM32_UART_USART2_DMA_PRIORITY) || defined(__DOXYGEN__) -#define STM32_UART_USART2_DMA_PRIORITY 0 -#endif -/** - * @brief USART3 DMA priority (0..3|lowest..highest). - * @note The priority level is used for both the TX and RX DMA channels but - * because of the channels ordering the RX channel has always priority - * over the TX channel. - */ -#if !defined(STM32_UART_USART3_DMA_PRIORITY) || defined(__DOXYGEN__) -#define STM32_UART_USART3_DMA_PRIORITY 0 -#endif - -/** - * @brief USART1 DMA error hook. - * @note The default action for DMA errors is a system halt because DMA - * error can only happen because programming errors. - */ -#if !defined(STM32_UART_DMA_ERROR_HOOK) || defined(__DOXYGEN__) -#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt() -#endif - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if STM32_UART_USE_USART1 && !STM32_HAS_USART1 -#error "USART1 not present in the selected device" -#endif - -#if STM32_UART_USE_USART2 && !STM32_HAS_USART2 -#error "USART2 not present in the selected device" -#endif - -#if STM32_UART_USE_USART3 && !STM32_HAS_USART3 -#error "USART3 not present in the selected device" -#endif - -#if !STM32_UART_USE_USART1 && !STM32_UART_USE_USART2 && \ - !STM32_UART_USE_USART3 -#error "UART driver activated but no USART/UART peripheral assigned" -#endif - -#if !defined(STM32_DMA_REQUIRED) -#define STM32_DMA_REQUIRED -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief UART driver condition flags type. - */ -typedef uint32_t uartflags_t; - -/** - * @brief Structure representing an UART driver. - */ -typedef struct UARTDriver UARTDriver; - -/** - * @brief Generic UART notification callback type. - * - * @param[in] uartp pointer to the @p UARTDriver object - */ -typedef void (*uartcb_t)(UARTDriver *uartp); - -/** - * @brief Character received UART notification callback type. - * - * @param[in] uartp pointer to the @p UARTDriver object - * @param[in] c received character - */ -typedef void (*uartccb_t)(UARTDriver *uartp, uint16_t c); - -/** - * @brief Receive error UART notification callback type. - * - * @param[in] uartp pointer to the @p UARTDriver object - * @param[in] e receive error mask - */ -typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e); - -/** - * @brief Driver configuration structure. - * @note It could be empty on some architectures. - */ -typedef struct { - /** - * @brief End of transmission buffer callback. - */ - uartcb_t txend1_cb; - /** - * @brief Physical end of transmission callback. - */ - uartcb_t txend2_cb; - /** - * @brief Receive buffer filled callback. - */ - uartcb_t rxend_cb; - /** - * @brief Character received while out if the @p UART_RECEIVE state. - */ - uartccb_t rxchar_cb; - /** - * @brief Receive error callback. - */ - uartecb_t rxerr_cb; - /* End of the mandatory fields.*/ - /** - * @brief Bit rate. - */ - uint32_t speed; - /** - * @brief Initialization value for the CR1 register. - */ - uint16_t cr1; - /** - * @brief Initialization value for the CR2 register. - */ - uint16_t cr2; - /** - * @brief Initialization value for the CR3 register. - */ - uint16_t cr3; -} UARTConfig; - -/** - * @brief Structure representing an UART driver. - */ -struct UARTDriver { - /** - * @brief Driver state. - */ - uartstate_t state; - /** - * @brief Transmitter state. - */ - uarttxstate_t txstate; - /** - * @brief Receiver state. - */ - uartrxstate_t rxstate; - /** - * @brief Current configuration data. - */ - const UARTConfig *config; -#if defined(UART_DRIVER_EXT_FIELDS) - UART_DRIVER_EXT_FIELDS -#endif - /* End of the mandatory fields.*/ - /** - * @brief Pointer to the USART registers block. - */ - USART_TypeDef *usart; - /** - * @brief DMA mode bit mask. - */ - uint32_t dmamode; - /** - * @brief Receive DMA channel. - */ - const stm32_dma_stream_t *dmarx; - /** - * @brief Transmit DMA channel. - */ - const stm32_dma_stream_t *dmatx; - /** - * @brief Default receive buffer while into @p UART_RX_IDLE state. - */ - volatile uint16_t rxbuf; -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if STM32_UART_USE_USART1 && !defined(__DOXYGEN__) -extern UARTDriver UARTD1; -#endif - -#if STM32_UART_USE_USART2 && !defined(__DOXYGEN__) -extern UARTDriver UARTD2; -#endif - -#if STM32_UART_USE_USART3 && !defined(__DOXYGEN__) -extern UARTDriver UARTD3; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void uart_lld_init(void); - void uart_lld_start(UARTDriver *uartp); - void uart_lld_stop(UARTDriver *uartp); - void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf); - size_t uart_lld_stop_send(UARTDriver *uartp); - void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf); - size_t uart_lld_stop_receive(UARTDriver *uartp); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_UART */ - -#endif /* _UART_LLD_H_ */ - -/** @} */ diff --git a/os/hal/platforms/STM32/sdc_lld.c b/os/hal/platforms/STM32/sdc_lld.c new file mode 100644 index 000000000..b9e02a815 --- /dev/null +++ b/os/hal/platforms/STM32/sdc_lld.c @@ -0,0 +1,730 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/sdc_lld.c + * @brief STM32 SDC subsystem low level driver source. + * + * @addtogroup SDC + * @{ + */ + +#include + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_SDC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief SDCD1 driver identifier.*/ +SDCDriver SDCD1; + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +#if STM32_SDC_UNALIGNED_SUPPORT +/** + * @brief Buffer for temporary storage during unaligned transfers. + */ +static union { + uint32_t alignment; + uint8_t buf[SDC_BLOCK_SIZE]; +} u; +#endif + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Reads one or more blocks. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] startblk first block to read + * @param[out] buf pointer to the read buffer, it must be aligned to + * four bytes boundary + * @param[in] n number of blocks to read + * @return The operation status. + * @retval FALSE operation succeeded, the requested blocks have been + * read. + * @retval TRUE operation failed, the state of the buffer is uncertain. + * + * @notapi + */ +static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk, + uint8_t *buf, uint32_t n) { + uint32_t resp[1]; + + /* Checks for errors and waits for the card to be ready for reading.*/ + if (_sdc_wait_for_transfer_state(sdcp)) + return TRUE; + + /* Prepares the DMA channel for reading.*/ + dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); + dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, + (n * SDC_BLOCK_SIZE) / sizeof (uint32_t)); + dmaStreamSetMode(STM32_DMA2_STREAM4, + STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | + STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); + + /* Setting up data transfer. + Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/ + SDIO->ICR = 0xFFFFFFFF; + SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | + SDIO_MASK_DATAENDIE | SDIO_MASK_STBITERRIE; + SDIO->DLEN = n * SDC_BLOCK_SIZE; + SDIO->DCTRL = SDIO_DCTRL_DTDIR | + SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 | + SDIO_DCTRL_DMAEN | + SDIO_DCTRL_DTEN; + + /* DMA channel activation.*/ + dmaStreamEnable(STM32_DMA2_STREAM4); + + /* Read multiple blocks command.*/ + if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) + startblk *= SDC_BLOCK_SIZE; + if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_MULTIPLE_BLOCK, + startblk, resp) || + SDC_R1_ERROR(resp[0])) + goto error; + + chSysLock(); + if (SDIO->MASK != 0) { + chDbgAssert(sdcp->thread == NULL, + "sdc_lld_read_multiple(), #1", "not NULL"); + sdcp->thread = chThdSelf(); + chSchGoSleepS(THD_STATE_SUSPENDED); + chDbgAssert(sdcp->thread == NULL, + "sdc_lld_read_multiple(), #2", "not NULL"); + } + if ((SDIO->STA & SDIO_STA_DATAEND) == 0) { + chSysUnlock(); + goto error; + } + dmaStreamDisable(STM32_DMA2_STREAM4); + SDIO->ICR = 0xFFFFFFFF; + SDIO->DCTRL = 0; + chSysUnlock(); + + return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); +error: + dmaStreamDisable(STM32_DMA2_STREAM4); + SDIO->ICR = 0xFFFFFFFF; + SDIO->MASK = 0; + SDIO->DCTRL = 0; + return TRUE; +} + +/** + * @brief Reads one block. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] startblk first block to read + * @param[out] buf pointer to the read buffer, it must be aligned to + * four bytes boundary + * @return The operation status. + * @retval FALSE operation succeeded, the requested blocks have been + * read. + * @retval TRUE operation failed, the state of the buffer is uncertain. + * + * @notapi + */ +static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk, + uint8_t *buf) { + uint32_t resp[1]; + + /* Checks for errors and waits for the card to be ready for reading.*/ + if (_sdc_wait_for_transfer_state(sdcp)) + return TRUE; + + /* Prepares the DMA channel for reading.*/ + dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); + dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, + SDC_BLOCK_SIZE / sizeof (uint32_t)); + dmaStreamSetMode(STM32_DMA2_STREAM4, + STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | + STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); + + /* Setting up data transfer. + Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/ + SDIO->ICR = 0xFFFFFFFF; + SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | + SDIO_MASK_DATAENDIE | SDIO_MASK_STBITERRIE; + SDIO->DLEN = SDC_BLOCK_SIZE; + SDIO->DCTRL = SDIO_DCTRL_DTDIR | + SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 | + SDIO_DCTRL_DMAEN | + SDIO_DCTRL_DTEN; + + /* DMA channel activation.*/ + dmaStreamEnable(STM32_DMA2_STREAM4); + + /* Read single block command.*/ + if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) + startblk *= SDC_BLOCK_SIZE; + if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_SINGLE_BLOCK, + startblk, resp) || + SDC_R1_ERROR(resp[0])) + goto error; + + chSysLock(); + if (SDIO->MASK != 0) { + chDbgAssert(sdcp->thread == NULL, + "sdc_lld_read_single(), #1", "not NULL"); + sdcp->thread = chThdSelf(); + chSchGoSleepS(THD_STATE_SUSPENDED); + chDbgAssert(sdcp->thread == NULL, + "sdc_lld_read_single(), #2", "not NULL"); + } + if ((SDIO->STA & SDIO_STA_DATAEND) == 0) { + chSysUnlock(); + goto error; + } + dmaStreamDisable(STM32_DMA2_STREAM4); + SDIO->ICR = 0xFFFFFFFF; + SDIO->DCTRL = 0; + chSysUnlock(); + + return FALSE; +error: + dmaStreamDisable(STM32_DMA2_STREAM4); + SDIO->ICR = 0xFFFFFFFF; + SDIO->MASK = 0; + SDIO->DCTRL = 0; + return TRUE; +} + +/** + * @brief Writes one or more blocks. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] startblk first block to write + * @param[out] buf pointer to the write buffer, it must be aligned to + * four bytes boundary + * @param[in] n number of blocks to write + * @return The operation status. + * @retval FALSE operation succeeded, the requested blocks have been + * written. + * @retval TRUE operation failed. + * + * @notapi + */ +static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk, + const uint8_t *buf, uint32_t n) { + uint32_t resp[1]; + + /* Checks for errors and waits for the card to be ready for writing.*/ + if (_sdc_wait_for_transfer_state(sdcp)) + return TRUE; + + /* Prepares the DMA channel for writing.*/ + dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); + dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, + (n * SDC_BLOCK_SIZE) / sizeof (uint32_t)); + dmaStreamSetMode(STM32_DMA2_STREAM4, + STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | + STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); + + /* Write multiple blocks command.*/ + if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) + startblk *= SDC_BLOCK_SIZE; + if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_MULTIPLE_BLOCK, + startblk, resp) || + SDC_R1_ERROR(resp[0])) + return TRUE; + + /* Setting up data transfer. + Options: Controller to Card, Block mode, DMA mode, 512 bytes blocks.*/ + SDIO->ICR = 0xFFFFFFFF; + SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | + SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE | + SDIO_MASK_STBITERRIE; + SDIO->DLEN = n * SDC_BLOCK_SIZE; + SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 | + SDIO_DCTRL_DMAEN | + SDIO_DCTRL_DTEN; + + /* DMA channel activation.*/ + dmaStreamEnable(STM32_DMA2_STREAM4); + + /* Note the mask is checked before going to sleep because the interrupt + may have occurred before reaching the critical zone.*/ + chSysLock(); + if (SDIO->MASK != 0) { + chDbgAssert(sdcp->thread == NULL, + "sdc_lld_write_multiple(), #1", "not NULL"); + sdcp->thread = chThdSelf(); + chSchGoSleepS(THD_STATE_SUSPENDED); + chDbgAssert(sdcp->thread == NULL, + "sdc_lld_write_multiple(), #2", "not NULL"); + } + if ((SDIO->STA & SDIO_STA_DATAEND) == 0) { + chSysUnlock(); + goto error; + } + dmaStreamDisable(STM32_DMA2_STREAM4); + SDIO->ICR = 0xFFFFFFFF; + SDIO->DCTRL = 0; + chSysUnlock(); + + return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); +error: + dmaStreamDisable(STM32_DMA2_STREAM4); + SDIO->ICR = 0xFFFFFFFF; + SDIO->MASK = 0; + SDIO->DCTRL = 0; + return TRUE; +} + +/** + * @brief Writes one block. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] startblk first block to write + * @param[out] buf pointer to the write buffer, it must be aligned to + * four bytes boundary + * @param[in] n number of blocks to write + * @return The operation status. + * @retval FALSE operation succeeded, the requested blocks have been + * written. + * @retval TRUE operation failed. + * + * @notapi + */ +static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk, + const uint8_t *buf) { + uint32_t resp[1]; + + /* Checks for errors and waits for the card to be ready for writing.*/ + if (_sdc_wait_for_transfer_state(sdcp)) + return TRUE; + + /* Prepares the DMA channel for writing.*/ + dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); + dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, + SDC_BLOCK_SIZE / sizeof (uint32_t)); + dmaStreamSetMode(STM32_DMA2_STREAM4, + STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | + STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); + + /* Write single block command.*/ + if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) + startblk *= SDC_BLOCK_SIZE; + if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_BLOCK, + startblk, resp) || + SDC_R1_ERROR(resp[0])) + return TRUE; + + /* Setting up data transfer. + Options: Controller to Card, Block mode, DMA mode, 512 bytes blocks.*/ + SDIO->ICR = 0xFFFFFFFF; + SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | + SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE | + SDIO_MASK_STBITERRIE; + SDIO->DLEN = SDC_BLOCK_SIZE; + SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 | + SDIO_DCTRL_DMAEN | + SDIO_DCTRL_DTEN; + + /* DMA channel activation.*/ + dmaStreamEnable(STM32_DMA2_STREAM4); + + /* Note the mask is checked before going to sleep because the interrupt + may have occurred before reaching the critical zone.*/ + chSysLock(); + if (SDIO->MASK != 0) { + chDbgAssert(sdcp->thread == NULL, + "sdc_lld_write_single(), #1", "not NULL"); + sdcp->thread = chThdSelf(); + chSchGoSleepS(THD_STATE_SUSPENDED); + chDbgAssert(sdcp->thread == NULL, + "sdc_lld_write_single(), #2", "not NULL"); + } + if ((SDIO->STA & SDIO_STA_DATAEND) == 0) { + chSysUnlock(); + goto error; + } + dmaStreamDisable(STM32_DMA2_STREAM4); + SDIO->ICR = 0xFFFFFFFF; + SDIO->DCTRL = 0; + chSysUnlock(); + + return FALSE; +error: + dmaStreamDisable(STM32_DMA2_STREAM4); + SDIO->ICR = 0xFFFFFFFF; + SDIO->MASK = 0; + SDIO->DCTRL = 0; + return TRUE; +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/** + * @brief SDIO IRQ handler. + * + * @isr + */ +CH_IRQ_HANDLER(SDIO_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + chSysLockFromIsr(); + if (SDCD1.thread != NULL) { + chSchReadyI(SDCD1.thread); + SDCD1.thread = NULL; + } + chSysUnlockFromIsr(); + + /* Disables the source but the status flags are not reset because the + read/write functions need to check them.*/ + SDIO->MASK = 0; + + CH_IRQ_EPILOGUE(); +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level SDC driver initialization. + * + * @notapi + */ +void sdc_lld_init(void) { + + sdcObjectInit(&SDCD1); + SDCD1.thread = NULL; +} + +/** + * @brief Configures and activates the SDC peripheral. + * + * @param[in] sdcp pointer to the @p SDCDriver object, must be @p NULL, + * this driver does not require any configuration + * + * @notapi + */ +void sdc_lld_start(SDCDriver *sdcp) { + + if (sdcp->state == SDC_STOP) { + /* Note, the DMA must be enabled before the IRQs.*/ + dmaStreamAllocate(STM32_DMA2_STREAM4, 0, NULL, NULL); + dmaStreamSetPeripheral(STM32_DMA2_STREAM4, &SDIO->FIFO); + NVICEnableVector(SDIO_IRQn, + CORTEX_PRIORITY_MASK(STM32_SDC_SDIO_IRQ_PRIORITY)); + RCC->AHBENR |= RCC_AHBENR_SDIOEN; + } + /* Configuration, card clock is initially stopped.*/ + SDIO->POWER = 0; + SDIO->CLKCR = 0; + SDIO->DCTRL = 0; + SDIO->DTIMER = STM32_SDC_DATATIMEOUT; +} + +/** + * @brief Deactivates the SDC peripheral. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * + * @notapi + */ +void sdc_lld_stop(SDCDriver *sdcp) { + + if ((sdcp->state == SDC_READY) || (sdcp->state == SDC_ACTIVE)) { + SDIO->POWER = 0; + SDIO->CLKCR = 0; + SDIO->DCTRL = 0; + SDIO->DTIMER = 0; + + /* Clock deactivation.*/ + NVICDisableVector(SDIO_IRQn); + dmaStreamRelease(STM32_DMA2_STREAM4); + } +} + +/** + * @brief Starts the SDIO clock and sets it to init mode (400KHz or less). + * + * @param[in] sdcp pointer to the @p SDCDriver object + * + * @notapi + */ +void sdc_lld_start_clk(SDCDriver *sdcp) { + + (void)sdcp; + /* Initial clock setting: 400KHz, 1bit mode.*/ + SDIO->CLKCR = STM32_SDIO_DIV_LS; + SDIO->POWER |= SDIO_POWER_PWRCTRL_0 | SDIO_POWER_PWRCTRL_1; + SDIO->CLKCR |= SDIO_CLKCR_CLKEN; +} + +/** + * @brief Sets the SDIO clock to data mode (25MHz or less). + * + * @param[in] sdcp pointer to the @p SDCDriver object + * + * @notapi + */ +void sdc_lld_set_data_clk(SDCDriver *sdcp) { + + (void)sdcp; + SDIO->CLKCR = (SDIO->CLKCR & 0xFFFFFF00) | STM32_SDIO_DIV_HS; +} + +/** + * @brief Stops the SDIO clock. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * + * @notapi + */ +void sdc_lld_stop_clk(SDCDriver *sdcp) { + + (void)sdcp; + SDIO->CLKCR = 0; + SDIO->POWER = 0; +} + +/** + * @brief Switches the bus to 4 bits mode. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] mode bus mode + * + * @notapi + */ +void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode) { + uint32_t clk = SDIO->CLKCR & ~SDIO_CLKCR_WIDBUS; + + (void)sdcp; + switch (mode) { + case SDC_MODE_1BIT: + SDIO->CLKCR = clk; + break; + case SDC_MODE_4BIT: + SDIO->CLKCR = clk | SDIO_CLKCR_WIDBUS_0; + break; + case SDC_MODE_8BIT: + SDIO->CLKCR = clk | SDIO_CLKCR_WIDBUS_1; + } +} + +/** + * @brief Sends an SDIO command with no response expected. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] cmd card command + * @param[in] arg command argument + * + * @notapi + */ +void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) { + + (void)sdcp; + SDIO->ARG = arg; + SDIO->CMD = (uint32_t)cmd | SDIO_CMD_CPSMEN; + while ((SDIO->STA & SDIO_STA_CMDSENT) == 0) + ; + SDIO->ICR = SDIO_ICR_CMDSENTC; +} + +/** + * @brief Sends an SDIO command with a short response expected. + * @note The CRC is not verified. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] cmd card command + * @param[in] arg command argument + * @param[out] resp pointer to the response buffer (one word) + * @return The operation status. + * @retval FALSE the operation succeeded. + * @retval TRUE the operation failed because timeout, CRC check or + * other errors. + * + * @notapi + */ +bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, + uint32_t *resp) { + uint32_t sta; + + (void)sdcp; + SDIO->ARG = arg; + SDIO->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_CPSMEN; + while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT | + SDIO_STA_CCRCFAIL)) == 0) + ; + SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC; + if ((sta & (SDIO_STA_CTIMEOUT)) != 0) + return TRUE; + *resp = SDIO->RESP1; + return FALSE; +} + +/** + * @brief Sends an SDIO command with a short response expected and CRC. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] cmd card command + * @param[in] arg command argument + * @param[out] resp pointer to the response buffer (one word) + * @return The operation status. + * @retval FALSE the operation succeeded. + * @retval TRUE the operation failed because timeout, CRC check or + * other errors. + * + * @notapi + */ +bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, + uint32_t *resp) { + uint32_t sta; + + (void)sdcp; + SDIO->ARG = arg; + SDIO->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_CPSMEN; + while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT | + SDIO_STA_CCRCFAIL)) == 0) + ; + SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC; + if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0) + return TRUE; + *resp = SDIO->RESP1; + return FALSE; +} + +/** + * @brief Sends an SDIO command with a long response expected and CRC. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] cmd card command + * @param[in] arg command argument + * @param[out] resp pointer to the response buffer (four words) + * @return The operation status. + * @retval FALSE the operation succeeded. + * @retval TRUE the operation failed because timeout, CRC check or + * other errors. + * + * @notapi + */ +bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, + uint32_t *resp) { + + uint32_t sta; + + (void)sdcp; + SDIO->ARG = arg; + SDIO->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_WAITRESP_1 | + SDIO_CMD_CPSMEN; + while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT | + SDIO_STA_CCRCFAIL)) == 0) + ; + SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC; + if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0) + return TRUE; + *resp = SDIO->RESP1; + return FALSE; +} + +/** + * @brief Reads one or more blocks. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] startblk first block to read + * @param[out] buf pointer to the read buffer + * @param[in] n number of blocks to read + * @return The operation status. + * @retval FALSE operation succeeded, the requested blocks have been + * read. + * @retval TRUE operation failed, the state of the buffer is uncertain. + * + * @notapi + */ +bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk, + uint8_t *buf, uint32_t n) { + +#if STM32_SDC_UNALIGNED_SUPPORT + if (((unsigned)buf & 3) != 0) { + uint32_t i; + for (i = 0; i < n; i++) { + if (sdc_lld_read_single(sdcp, startblk, u.buf)) + return TRUE; + memcpy(buf, u.buf, SDC_BLOCK_SIZE); + buf += SDC_BLOCK_SIZE; + startblk++; + } + return FALSE; + } +#endif + if (n == 1) + return sdc_lld_read_single(sdcp, startblk, buf); + return sdc_lld_read_multiple(sdcp, startblk, buf, n); +} + +/** + * @brief Writes one or more blocks. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] startblk first block to write + * @param[out] buf pointer to the write buffer + * @param[in] n number of blocks to write + * @return The operation status. + * @retval FALSE operation succeeded, the requested blocks have been + * written. + * @retval TRUE operation failed. + * + * @notapi + */ +bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk, + const uint8_t *buf, uint32_t n) { + + #if STM32_SDC_UNALIGNED_SUPPORT + if (((unsigned)buf & 3) != 0) { + uint32_t i; + for (i = 0; i < n; i++) { + memcpy(u.buf, buf, SDC_BLOCK_SIZE); + buf += SDC_BLOCK_SIZE; + if (sdc_lld_write_single(sdcp, startblk, u.buf)) + return TRUE; + startblk++; + } + return FALSE; + } +#endif + if (n == 1) + return sdc_lld_write_single(sdcp, startblk, buf); + return sdc_lld_write_multiple(sdcp, startblk, buf, n); +} + +#endif /* HAL_USE_SDC */ + +/** @} */ diff --git a/os/hal/platforms/STM32/sdc_lld.h b/os/hal/platforms/STM32/sdc_lld.h new file mode 100644 index 000000000..eea76dadd --- /dev/null +++ b/os/hal/platforms/STM32/sdc_lld.h @@ -0,0 +1,203 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/sdc_lld.h + * @brief STM32 SDC subsystem low level driver header. + * + * @addtogroup SDC + * @{ + */ + +#ifndef _SDC_LLD_H_ +#define _SDC_LLD_H_ + +#if HAL_USE_SDC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @brief SDIO data timeout in SDIO clock cycles. + */ +#if !defined(STM32_SDC_DATATIMEOUT) || defined(__DOXYGEN__) +#define STM32_SDC_DATATIMEOUT 0x000FFFFF +#endif + +/** + * @brief SDIO DMA priority (0..3|lowest..highest). + */ +#if !defined(STM32_SDC_SDIO_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SDC_SDIO_DMA_PRIORITY 3 +#endif + +/** + * @brief SDIO interrupt priority level setting. + */ +#if !defined(STM32_SDC_SDIO_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SDC_SDIO_IRQ_PRIORITY 9 +#endif + +/** + * @brief SDIO support for unaligned transfers. + */ +#if !defined(STM32_SDC_UNALIGNED_SUPPORT) || defined(__DOXYGEN__) +#define STM32_SDC_UNALIGNED_SUPPORT TRUE +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if !STM32_HAS_SDIO +#error "SDIO not present in the selected device" +#endif + +#if !defined(STM32_DMA_REQUIRED) +#define STM32_DMA_REQUIRED +#endif + +/* + * SDIO clock divider. + */ +#if STM32_HCLK > 48000000 +#define STM32_SDIO_DIV_HS 0x01 +#define STM32_SDIO_DIV_LS 0xB2 +#else +#define STM32_SDIO_DIV_HS 0x00 +#define STM32_SDIO_DIV_LS 0x76 +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of SDIO bus mode. + */ +typedef enum { + SDC_MODE_1BIT = 0, + SDC_MODE_4BIT, + SDC_MODE_8BIT +} sdcbusmode_t; + +/** + * @brief Type of card flags. + */ +typedef uint32_t sdcmode_t; + +/** + * @brief Type of a structure representing an SDC driver. + */ +typedef struct SDCDriver SDCDriver; + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + uint32_t dummy; +} SDCConfig; + +/** + * @brief Structure representing an SDC driver. + */ +struct SDCDriver { + /** + * @brief Driver state. + */ + sdcstate_t state; + /** + * @brief Current configuration data. + */ + const SDCConfig *config; + /** + * @brief Various flags regarding the mounted card. + */ + sdcmode_t cardmode; + /** + * @brief Card CID. + */ + uint32_t cid[4]; + /** + * @brief Card CSD. + */ + uint32_t csd[4]; + /** + * @brief Card RCA. + */ + uint32_t rca; + /* End of the mandatory fields.*/ + /** + * @brief Thread waiting for I/O completion IRQ. + */ + Thread *thread; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern SDCDriver SDCD1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void sdc_lld_init(void); + void sdc_lld_start(SDCDriver *sdcp); + void sdc_lld_stop(SDCDriver *sdcp); + void sdc_lld_start_clk(SDCDriver *sdcp); + void sdc_lld_set_data_clk(SDCDriver *sdcp); + void sdc_lld_stop_clk(SDCDriver *sdcp); + void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode); + void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg); + bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, + uint32_t *resp); + bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, + uint32_t *resp); + bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, + uint32_t *resp); + bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk, + uint8_t *buf, uint32_t n); + bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk, + const uint8_t *buf, uint32_t n); + bool_t sdc_lld_is_card_inserted(SDCDriver *sdcp); + bool_t sdc_lld_is_write_protected(SDCDriver *sdcp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_SDC */ + +#endif /* _SDC_LLD_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32/spi_lld.c b/os/hal/platforms/STM32/spi_lld.c new file mode 100644 index 000000000..9302b0102 --- /dev/null +++ b/os/hal/platforms/STM32/spi_lld.c @@ -0,0 +1,445 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/spi_lld.c + * @brief STM32 SPI subsystem low level driver source. + * + * @addtogroup SPI + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_SPI || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief SPI1 driver identifier.*/ +#if STM32_SPI_USE_SPI1 || defined(__DOXYGEN__) +SPIDriver SPID1; +#endif + +/** @brief SPI2 driver identifier.*/ +#if STM32_SPI_USE_SPI2 || defined(__DOXYGEN__) +SPIDriver SPID2; +#endif + +/** @brief SPI3 driver identifier.*/ +#if STM32_SPI_USE_SPI3 || defined(__DOXYGEN__) +SPIDriver SPID3; +#endif + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +static uint16_t dummytx; +static uint16_t dummyrx; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Stops the SPI DMA channels. + * + * @param[in] spip pointer to the @p SPIDriver object + */ +#define dma_stop(spip) { \ + dmaStreamDisable(spip->dmatx); \ + dmaStreamDisable(spip->dmarx); \ +} + +/** + * @brief Starts the SPI DMA channels. + * + * @param[in] spip pointer to the @p SPIDriver object + */ +#define dma_start(spip) { \ + dmaChannelEnable((spip)->dmarx); \ + dmaChannelEnable((spip)->dmatx); \ +} + +/** + * @brief Shared end-of-rx service routine. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] flags pre-shifted content of the ISR register + */ +static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { + + /* DMA errors handling.*/ +#if defined(STM32_SPI_DMA_ERROR_HOOK) + if ((flags & STM32_DMA_ISR_TEIF) != 0) { + STM32_SPI_DMA_ERROR_HOOK(spip); + } +#else + (void)flags; +#endif + + /* Stop everything.*/ + dma_stop(spip); + + /* Portable SPI ISR code defined in the high level driver, note, it is + a macro.*/ + _spi_isr_code(spip); +} + +/** + * @brief Shared end-of-tx service routine. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] flags pre-shifted content of the ISR register + */ +static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) { + + /* DMA errors handling.*/ +#if defined(STM32_SPI_DMA_ERROR_HOOK) + (void)spip; + if ((flags & STM32_DMA_ISR_TEIF) != 0) { + STM32_SPI_DMA_ERROR_HOOK(spip); + } +#else + (void)spip; + (void)flags; +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level SPI driver initialization. + * + * @notapi + */ +void spi_lld_init(void) { + + dummytx = 0xFFFF; + +#if STM32_SPI_USE_SPI1 + spiObjectInit(&SPID1); + SPID1.thread = NULL; + SPID1.spi = SPI1; + SPID1.dmarx = STM32_DMA1_STREAM2; + SPID1.dmatx = STM32_DMA1_STREAM3; +#endif + +#if STM32_SPI_USE_SPI2 + spiObjectInit(&SPID2); + SPID2.thread = NULL; + SPID2.spi = SPI2; + SPID2.dmarx = STM32_DMA1_STREAM4; + SPID2.dmatx = STM32_DMA1_STREAM5; +#endif + +#if STM32_SPI_USE_SPI3 + spiObjectInit(&SPID3); + SPID3.thread = NULL; + SPID3.spi = SPI3; + SPID3.dmarx = STM32_DMA2_STREAM1; + SPID3.dmatx = STM32_DMA2_STREAM2; +#endif +} + +/** + * @brief Configures and activates the SPI peripheral. + * + * @param[in] spip pointer to the @p SPIDriver object + * + * @notapi + */ +void spi_lld_start(SPIDriver *spip) { + + /* If in stopped state then enables the SPI and DMA clocks.*/ + if (spip->state == SPI_STOP) { +#if STM32_SPI_USE_SPI1 + if (&SPID1 == spip) { + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM2, + STM32_SPI_SPI1_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #1", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM3, + STM32_SPI_SPI1_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #2", "stream already allocated"); + RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; + } +#endif +#if STM32_SPI_USE_SPI2 + if (&SPID2 == spip) { + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM4, + STM32_SPI_SPI2_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #3", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM5, + STM32_SPI_SPI2_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #4", "stream already allocated"); + RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; + } +#endif +#if STM32_SPI_USE_SPI3 + if (&SPID3 == spip) { + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM1, + STM32_SPI_SPI3_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #5", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM2, + STM32_SPI_SPI3_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #6", "stream already allocated"); + RCC->APB1ENR |= RCC_APB1ENR_SPI3EN; + } +#endif + + /* DMA setup.*/ + dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR); + dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR); + } + + /* More DMA setup.*/ + if ((spip->config->cr1 & SPI_CR1_DFF) == 0) + spip->dmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) | + STM32_DMA_CR_TEIE | + STM32_DMA_CR_PSIZE_BYTE | + STM32_DMA_CR_MSIZE_BYTE; /* 8 bits transfers. */ + else + spip->dmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) | + STM32_DMA_CR_TEIE | + STM32_DMA_CR_PSIZE_HWORD | + STM32_DMA_CR_MSIZE_HWORD; /* 16 bits transfers. */ + + /* SPI setup and enable.*/ + spip->spi->CR1 = 0; + spip->spi->CR1 = spip->config->cr1 | SPI_CR1_MSTR | SPI_CR1_SSM | + SPI_CR1_SSI; + spip->spi->CR2 = SPI_CR2_SSOE | SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN; + spip->spi->CR1 |= SPI_CR1_SPE; +} + +/** + * @brief Deactivates the SPI peripheral. + * + * @param[in] spip pointer to the @p SPIDriver object + * + * @notapi + */ +void spi_lld_stop(SPIDriver *spip) { + + /* If in ready state then disables the SPI clock.*/ + if (spip->state == SPI_READY) { + + /* SPI disable.*/ + spip->spi->CR1 = 0; + +#if STM32_SPI_USE_SPI1 + if (&SPID1 == spip) { + dmaStreamRelease(STM32_DMA1_STREAM2); + dmaStreamRelease(STM32_DMA1_STREAM3); + RCC->APB2ENR &= ~RCC_APB2ENR_SPI1EN; + } +#endif +#if STM32_SPI_USE_SPI2 + if (&SPID2 == spip) { + dmaStreamRelease(STM32_DMA1_STREAM4); + dmaStreamRelease(STM32_DMA1_STREAM5); + RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN; + } +#endif +#if STM32_SPI_USE_SPI3 + if (&SPID3 == spip) { + dmaStreamRelease(STM32_DMA1_STREAM1); + dmaStreamRelease(STM32_DMA1_STREAM2); + RCC->APB1ENR &= ~RCC_APB1ENR_SPI3EN; + } +#endif + } +} + +/** + * @brief Asserts the slave select signal and prepares for transfers. + * + * @param[in] spip pointer to the @p SPIDriver object + * + * @notapi + */ +void spi_lld_select(SPIDriver *spip) { + + palClearPad(spip->config->ssport, spip->config->sspad); +} + +/** + * @brief Deasserts the slave select signal. + * @details The previously selected peripheral is unselected. + * + * @param[in] spip pointer to the @p SPIDriver object + * + * @notapi + */ +void spi_lld_unselect(SPIDriver *spip) { + + palSetPad(spip->config->ssport, spip->config->sspad); +} + +/** + * @brief Ignores data on the SPI bus. + * @details This asynchronous function starts the transmission of a series of + * idle words on the SPI bus and ignores the received data. + * @post At the end of the operation the configured callback is invoked. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] n number of words to be ignored + * + * @notapi + */ +void spi_lld_ignore(SPIDriver *spip, size_t n) { + + dmaStreamSetMemory0(spip->dmarx, &dummyrx); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, &dummytx); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_EN); +} + +/** + * @brief Exchanges data on the SPI bus. + * @details This asynchronous function starts a simultaneous transmit/receive + * operation. + * @post At the end of the operation the configured callback is invoked. + * @note The buffers are organized as uint8_t arrays for data sizes below or + * equal to 8 bits else it is organized as uint16_t arrays. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] n number of words to be exchanged + * @param[in] txbuf the pointer to the transmit buffer + * @param[out] rxbuf the pointer to the receive buffer + * + * @notapi + */ +void spi_lld_exchange(SPIDriver *spip, size_t n, + const void *txbuf, void *rxbuf) { + + dmaStreamSetMemory0(spip->dmarx, rxbuf); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC | + STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, txbuf); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_MINC | STM32_DMA_CR_EN); +} + +/** + * @brief Sends data over the SPI bus. + * @details This asynchronous function starts a transmit operation. + * @post At the end of the operation the configured callback is invoked. + * @note The buffers are organized as uint8_t arrays for data sizes below or + * equal to 8 bits else it is organized as uint16_t arrays. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] n number of words to send + * @param[in] txbuf the pointer to the transmit buffer + * + * @notapi + */ +void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { + + dmaStreamSetMemory0(spip->dmarx, &dummyrx); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, txbuf); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_MINC | STM32_DMA_CR_EN); +} + +/** + * @brief Receives data from the SPI bus. + * @details This asynchronous function starts a receive operation. + * @post At the end of the operation the configured callback is invoked. + * @note The buffers are organized as uint8_t arrays for data sizes below or + * equal to 8 bits else it is organized as uint16_t arrays. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] n number of words to receive + * @param[out] rxbuf the pointer to the receive buffer + * + * @notapi + */ +void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { + + dmaStreamSetMemory0(spip->dmarx, rxbuf); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC | + STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, &dummytx); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_EN); +} + +/** + * @brief Exchanges one frame using a polled wait. + * @details This synchronous function exchanges one frame using a polled + * synchronization method. This function is useful when exchanging + * small amount of data on high speed channels, usually in this + * situation is much more efficient just wait for completion using + * polling than suspending the thread waiting for an interrupt. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] frame the data frame to send over the SPI bus + * @return The received data frame from the SPI bus. + */ +uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) { + + spip->spi->DR = frame; + while ((spip->spi->SR & SPI_SR_RXNE) == 0) + ; + return spip->spi->DR; +} + +#endif /* HAL_USE_SPI */ + +/** @} */ diff --git a/os/hal/platforms/STM32/spi_lld.h b/os/hal/platforms/STM32/spi_lld.h new file mode 100644 index 000000000..c8c1e0661 --- /dev/null +++ b/os/hal/platforms/STM32/spi_lld.h @@ -0,0 +1,285 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/spi_lld.h + * @brief STM32 SPI subsystem low level driver header. + * + * @addtogroup SPI + * @{ + */ + +#ifndef _SPI_LLD_H_ +#define _SPI_LLD_H_ + +#if HAL_USE_SPI || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @brief SPI1 driver enable switch. + * @details If set to @p TRUE the support for SPI1 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_SPI_USE_SPI1) || defined(__DOXYGEN__) +#define STM32_SPI_USE_SPI1 TRUE +#endif + +/** + * @brief SPI2 driver enable switch. + * @details If set to @p TRUE the support for SPI2 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_SPI_USE_SPI2) || defined(__DOXYGEN__) +#define STM32_SPI_USE_SPI2 TRUE +#endif + +/** + * @brief SPI3 driver enable switch. + * @details If set to @p TRUE the support for SPI3 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_SPI_USE_SPI3) || defined(__DOXYGEN__) +#define STM32_SPI_USE_SPI3 FALSE +#endif + +/** + * @brief SPI1 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA channels but + * because of the channels ordering the RX channel has always priority + * over the TX channel. + */ +#if !defined(STM32_SPI_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SPI_SPI1_DMA_PRIORITY 1 +#endif + +/** + * @brief SPI2 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA channels but + * because of the channels ordering the RX channel has always priority + * over the TX channel. + */ +#if !defined(STM32_SPI_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SPI_SPI2_DMA_PRIORITY 1 +#endif + +/** + * @brief SPI3 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA channels but + * because of the channels ordering the RX channel has always priority + * over the TX channel. + */ +#if !defined(STM32_SPI_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SPI_SPI3_DMA_PRIORITY 1 +#endif + +/** + * @brief SPI1 interrupt priority level setting. + */ +#if !defined(STM32_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SPI_SPI1_IRQ_PRIORITY 10 +#endif + +/** + * @brief SPI2 interrupt priority level setting. + */ +#if !defined(STM32_SPI_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SPI_SPI2_IRQ_PRIORITY 10 +#endif + +/** + * @brief SPI3 interrupt priority level setting. + */ +#if !defined(STM32_SPI_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SPI_SPI3_IRQ_PRIORITY 10 +#endif + +/** + * @brief SPI DMA error hook. + * @note The default action for DMA errors is a system halt because DMA + * error can only happen because programming errors. + */ +#if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__) +#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt() +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if STM32_SPI_USE_SPI1 && !STM32_HAS_SPI1 +#error "SPI1 not present in the selected device" +#endif + +#if STM32_SPI_USE_SPI2 && !STM32_HAS_SPI2 +#error "SPI2 not present in the selected device" +#endif + +#if STM32_SPI_USE_SPI3 && !STM32_HAS_SPI3 +#error "SPI3 not present in the selected device" +#endif + +#if !STM32_SPI_USE_SPI1 && !STM32_SPI_USE_SPI2 && !STM32_SPI_USE_SPI3 +#error "SPI driver activated but no SPI peripheral assigned" +#endif + +#if !defined(STM32_DMA_REQUIRED) +#define STM32_DMA_REQUIRED +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of a structure representing an SPI driver. + */ +typedef struct SPIDriver SPIDriver; + +/** + * @brief SPI notification callback type. + * + * @param[in] spip pointer to the @p SPIDriver object triggering the + * callback + */ +typedef void (*spicallback_t)(SPIDriver *spip); + +/** + * @brief Driver configuration structure. + */ +typedef struct { + /** + * @brief Operation complete callback or @p NULL. + */ + spicallback_t end_cb; + /* End of the mandatory fields.*/ + /** + * @brief The chip select line port. + */ + ioportid_t ssport; + /** + * @brief The chip select line pad number. + */ + uint16_t sspad; + /** + * @brief SPI initialization data. + */ + uint16_t cr1; +} SPIConfig; + +/** + * @brief Structure representing a SPI driver. + */ +struct SPIDriver{ + /** + * @brief Driver state. + */ + spistate_t state; + /** + * @brief Current configuration data. + */ + const SPIConfig *config; +#if SPI_USE_WAIT || defined(__DOXYGEN__) + /** + * @brief Waiting thread. + */ + Thread *thread; +#endif /* SPI_USE_WAIT */ +#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) +#if CH_USE_MUTEXES || defined(__DOXYGEN__) + /** + * @brief Mutex protecting the bus. + */ + Mutex mutex; +#elif CH_USE_SEMAPHORES + Semaphore semaphore; +#endif +#endif /* SPI_USE_MUTUAL_EXCLUSION */ +#if defined(SPI_DRIVER_EXT_FIELDS) + SPI_DRIVER_EXT_FIELDS +#endif + /* End of the mandatory fields.*/ + /** + * @brief Pointer to the SPIx registers block. + */ + SPI_TypeDef *spi; + /** + * @brief Receive DMA channel. + */ + const stm32_dma_stream_t *dmarx; + /** + * @brief Transmit DMA channel. + */ + const stm32_dma_stream_t *dmatx; + /** + * @brief DMA mode bit mask. + */ + uint32_t dmamode; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if STM32_SPI_USE_SPI1 && !defined(__DOXYGEN__) +extern SPIDriver SPID1; +#endif + +#if STM32_SPI_USE_SPI2 && !defined(__DOXYGEN__) +extern SPIDriver SPID2; +#endif + +#if STM32_SPI_USE_SPI3 && !defined(__DOXYGEN__) +extern SPIDriver SPID3; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void spi_lld_init(void); + void spi_lld_start(SPIDriver *spip); + void spi_lld_stop(SPIDriver *spip); + void spi_lld_select(SPIDriver *spip); + void spi_lld_unselect(SPIDriver *spip); + void spi_lld_ignore(SPIDriver *spip, size_t n); + void spi_lld_exchange(SPIDriver *spip, size_t n, + const void *txbuf, void *rxbuf); + void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf); + void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf); + uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_SPI */ + +#endif /* _SPI_LLD_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32/uart_lld.c b/os/hal/platforms/STM32/uart_lld.c new file mode 100644 index 000000000..a9303744d --- /dev/null +++ b/os/hal/platforms/STM32/uart_lld.c @@ -0,0 +1,557 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/uart_lld.c + * @brief STM32 low level UART driver code. + * + * @addtogroup UART + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_UART || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief USART1 UART driver identifier.*/ +#if STM32_UART_USE_USART1 || defined(__DOXYGEN__) +UARTDriver UARTD1; +#endif + +/** @brief USART2 UART driver identifier.*/ +#if STM32_UART_USE_USART2 || defined(__DOXYGEN__) +UARTDriver UARTD2; +#endif + +/** @brief USART3 UART driver identifier.*/ +#if STM32_UART_USE_USART3 || defined(__DOXYGEN__) +UARTDriver UARTD3; +#endif + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Status bits translation. + * + * @param[in] sr USART SR register value + * + * @return The error flags. + */ +static uartflags_t translate_errors(uint16_t sr) { + uartflags_t sts = 0; + + if (sr & USART_SR_ORE) + sts |= UART_OVERRUN_ERROR; + if (sr & USART_SR_PE) + sts |= UART_PARITY_ERROR; + if (sr & USART_SR_FE) + sts |= UART_FRAMING_ERROR; + if (sr & USART_SR_NE) + sts |= UART_NOISE_ERROR; + if (sr & USART_SR_LBD) + sts |= UART_BREAK_DETECTED; + return sts; +} + +/** + * @brief Puts the receiver in the UART_RX_IDLE state. + * + * @param[in] uartp pointer to the @p UARTDriver object + */ +static void set_rx_idle_loop(UARTDriver *uartp) { + uint32_t mode; + + /* RX DMA channel preparation, if the char callback is defined then the + TCIE interrupt is enabled too.*/ + if (uartp->config->rxchar_cb == NULL) + mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TEIE; + else + mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TEIE | + STM32_DMA_CR_TCIE; + dmaStreamSetMemory0(uartp->dmarx, &uartp->rxbuf); + dmaStreamSetTransactionSize(uartp->dmarx, 1); + dmaStreamSetMode(uartp->dmarx, uartp->dmamode | mode); + dmaStreamEnable(uartp->dmarx); +} + +/** + * @brief USART de-initialization. + * @details This function must be invoked with interrupts disabled. + * + * @param[in] uartp pointer to the @p UARTDriver object + */ +static void usart_stop(UARTDriver *uartp) { + + /* Stops RX and TX DMA channels.*/ + dmaStreamDisable(uartp->dmarx); + dmaStreamClearInterrupt(uartp->dmarx); + dmaStreamDisable(uartp->dmatx); + dmaStreamClearInterrupt(uartp->dmatx); + + /* Stops USART operations.*/ + uartp->usart->CR1 = 0; + uartp->usart->CR2 = 0; + uartp->usart->CR3 = 0; +} + +/** + * @brief USART initialization. + * @details This function must be invoked with interrupts disabled. + * + * @param[in] uartp pointer to the @p UARTDriver object + */ +static void usart_start(UARTDriver *uartp) { + uint16_t cr1; + USART_TypeDef *u = uartp->usart; + + /* Defensive programming, starting from a clean state.*/ + usart_stop(uartp); + + /* Baud rate setting.*/ + if (uartp->usart == USART1) + u->BRR = STM32_PCLK2 / uartp->config->speed; + else + u->BRR = STM32_PCLK1 / uartp->config->speed; + + /* Resetting eventual pending status flags.*/ + (void)u->SR; /* SR reset step 1.*/ + (void)u->DR; /* SR reset step 2.*/ + u->SR = 0; + + /* Note that some bits are enforced because required for correct driver + operations.*/ + if (uartp->config->txend2_cb == NULL) + cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE; + else + cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE | + USART_CR1_TCIE; + u->CR1 = uartp->config->cr1 | cr1; + u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE; + u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR | + USART_CR3_EIE; + + /* Starting the receiver idle loop.*/ + set_rx_idle_loop(uartp); +} + +/** + * @brief RX DMA common service routine. + * + * @param[in] uartp pointer to the @p UARTDriver object + * @param[in] flags pre-shifted content of the ISR register + */ +static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) { + + /* DMA errors handling.*/ +#if defined(STM32_UART_DMA_ERROR_HOOK) + if ((flags & STM32_DMA_ISR_TEIF) != 0) { + STM32_UART_DMA_ERROR_HOOK(uartp); + } +#else + (void)flags; +#endif + + if (uartp->rxstate == UART_RX_IDLE) { + /* Receiver in idle state, a callback is generated, if enabled, for each + received character and then the driver stays in the same state.*/ + if (uartp->config->rxchar_cb != NULL) + uartp->config->rxchar_cb(uartp, uartp->rxbuf); + } + else { + /* Receiver in active state, a callback is generated, if enabled, after + a completed transfer.*/ + dmaStreamDisable(uartp->dmarx); + uartp->rxstate = UART_RX_COMPLETE; + if (uartp->config->rxend_cb != NULL) + uartp->config->rxend_cb(uartp); + /* If the callback didn't explicitly change state then the receiver + automatically returns to the idle state.*/ + if (uartp->rxstate == UART_RX_COMPLETE) { + uartp->rxstate = UART_RX_IDLE; + set_rx_idle_loop(uartp); + } + } +} + +/** + * @brief TX DMA common service routine. + * + * @param[in] uartp pointer to the @p UARTDriver object + * @param[in] flags pre-shifted content of the ISR register + */ +static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) { + + /* DMA errors handling.*/ +#if defined(STM32_UART_DMA_ERROR_HOOK) + if ((flags & STM32_DMA_ISR_TEIF) != 0) { + STM32_UART_DMA_ERROR_HOOK(uartp); + } +#else + (void)flags; +#endif + + dmaStreamDisable(uartp->dmatx); + /* A callback is generated, if enabled, after a completed transfer.*/ + uartp->txstate = UART_TX_COMPLETE; + if (uartp->config->txend1_cb != NULL) + uartp->config->txend1_cb(uartp); + /* If the callback didn't explicitly change state then the transmitter + automatically returns to the idle state.*/ + if (uartp->txstate == UART_TX_COMPLETE) + uartp->txstate = UART_TX_IDLE; +} + +/** + * @brief USART common service routine. + * + * @param[in] uartp pointer to the @p UARTDriver object + */ +static void serve_usart_irq(UARTDriver *uartp) { + uint16_t sr; + USART_TypeDef *u = uartp->usart; + + sr = u->SR; /* SR reset step 1.*/ + (void)u->DR; /* SR reset step 2.*/ + if (sr & (USART_SR_LBD | USART_SR_ORE | USART_SR_NE | + USART_SR_FE | USART_SR_PE)) { + u->SR = ~USART_SR_LBD; + if (uartp->config->rxerr_cb != NULL) + uartp->config->rxerr_cb(uartp, translate_errors(sr)); + } + if (sr & USART_SR_TC) { + u->SR = ~USART_SR_TC; + /* End of transmission, a callback is generated.*/ + if (uartp->config->txend2_cb != NULL) + uartp->config->txend2_cb(uartp); + } +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if STM32_UART_USE_USART1 || defined(__DOXYGEN__) +/** + * @brief USART1 IRQ handler. + * + * @isr + */ +CH_IRQ_HANDLER(USART1_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + serve_usart_irq(&UARTD1); + + CH_IRQ_EPILOGUE(); +} +#endif /* STM32_UART_USE_USART1 */ + +#if STM32_UART_USE_USART2 || defined(__DOXYGEN__) +/** + * @brief USART2 IRQ handler. + * + * @isr + */ +CH_IRQ_HANDLER(USART2_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + serve_usart_irq(&UARTD2); + + CH_IRQ_EPILOGUE(); +} +#endif /* STM32_UART_USE_USART2 */ + +#if STM32_UART_USE_USART3 || defined(__DOXYGEN__) +/** + * @brief USART3 IRQ handler. + * + * @isr + */ +CH_IRQ_HANDLER(USART3_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + serve_usart_irq(&UARTD3); + + CH_IRQ_EPILOGUE(); +} +#endif /* STM32_UART_USE_USART3 */ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level UART driver initialization. + * + * @notapi + */ +void uart_lld_init(void) { + +#if STM32_UART_USE_USART1 + uartObjectInit(&UARTD1); + UARTD1.usart = USART1; + UARTD1.dmarx = STM32_DMA1_STREAM5; + UARTD1.dmatx = STM32_DMA1_STREAM4; +#endif + +#if STM32_UART_USE_USART2 + uartObjectInit(&UARTD2); + UARTD2.usart = USART2; + UARTD2.dmarx = STM32_DMA1_STREAM6; + UARTD2.dmatx = STM32_DMA1_STREAM7; +#endif + +#if STM32_UART_USE_USART3 + uartObjectInit(&UARTD3); + UARTD3.usart = USART3; + UARTD3.dmarx = STM32_DMA1_STREAM3; + UARTD3.dmatx = STM32_DMA1_STREAM2; +#endif +} + +/** + * @brief Configures and activates the UART peripheral. + * + * @param[in] uartp pointer to the @p UARTDriver object + * + * @notapi + */ +void uart_lld_start(UARTDriver *uartp) { + + if (uartp->state == UART_STOP) { +#if STM32_UART_USE_USART1 + if (&UARTD1 == uartp) { + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM4, + STM32_UART_USART1_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #1", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM5, + STM32_UART_USART1_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #2", "stream already allocated"); + RCC->APB2ENR |= RCC_APB2ENR_USART1EN; + NVICEnableVector(USART1_IRQn, + CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY)); + } +#endif + +#if STM32_UART_USE_USART2 + if (&UARTD2 == uartp) { + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM6, + STM32_UART_USART2_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #3", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM7, + STM32_UART_USART2_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #4", "stream already allocated"); + RCC->APB1ENR |= RCC_APB1ENR_USART2EN; + NVICEnableVector(USART2_IRQn, + CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); + } +#endif + +#if STM32_UART_USE_USART3 + if (&UARTD3 == uartp) { + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM2, + STM32_UART_USART3_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #5", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM3, + STM32_UART_USART3_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #6", "stream already allocated"); + RCC->APB1ENR |= RCC_APB1ENR_USART3EN; + NVICEnableVector(USART3_IRQn, + CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY)); + } +#endif + + /* Static DMA setup, the transfer size depends on the USART settings, + it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/ + uartp->dmamode = STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY); + if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M) + uartp->dmamode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; + dmaStreamSetPeripheral(uartp->dmarx, &uartp->usart->DR); + dmaStreamSetPeripheral(uartp->dmatx, &uartp->usart->DR); + uartp->rxbuf = 0; + } + + uartp->rxstate = UART_RX_IDLE; + uartp->txstate = UART_TX_IDLE; + usart_start(uartp); +} + +/** + * @brief Deactivates the UART peripheral. + * + * @param[in] uartp pointer to the @p UARTDriver object + * + * @notapi + */ +void uart_lld_stop(UARTDriver *uartp) { + + if (uartp->state == UART_READY) { + usart_stop(uartp); + +#if STM32_UART_USE_USART1 + if (&UARTD1 == uartp) { + dmaStreamRelease(STM32_DMA1_STREAM4); + dmaStreamRelease(STM32_DMA1_STREAM5); + NVICDisableVector(USART1_IRQn); + RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN; + return; + } +#endif + +#if STM32_UART_USE_USART2 + if (&UARTD2 == uartp) { + dmaStreamRelease(STM32_DMA1_STREAM6); + dmaStreamRelease(STM32_DMA1_STREAM7); + NVICDisableVector(USART2_IRQn); + RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN; + return; + } +#endif + +#if STM32_UART_USE_USART3 + if (&UARTD3 == uartp) { + dmaStreamRelease(STM32_DMA1_STREAM2); + dmaStreamRelease(STM32_DMA1_STREAM3); + NVICDisableVector(USART3_IRQn); + RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN; + return; + } +#endif + } +} + +/** + * @brief Starts a transmission on the UART peripheral. + * @note The buffers are organized as uint8_t arrays for data sizes below + * or equal to 8 bits else it is organized as uint16_t arrays. + * + * @param[in] uartp pointer to the @p UARTDriver object + * @param[in] n number of data frames to send + * @param[in] txbuf the pointer to the transmit buffer + * + * @notapi + */ +void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { + + /* TX DMA channel preparation and start.*/ + dmaStreamSetMemory0(uartp->dmatx, txbuf); + dmaStreamSetTransactionSize(uartp->dmatx, n); + dmaStreamSetMode(uartp->dmatx, uartp->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_MINC | STM32_DMA_CR_TEIE | + STM32_DMA_CR_TCIE); + dmaStreamEnable(uartp->dmatx); +} + +/** + * @brief Stops any ongoing transmission. + * @note Stopping a transmission also suppresses the transmission callbacks. + * + * @param[in] uartp pointer to the @p UARTDriver object + * + * @return The number of data frames not transmitted by the + * stopped transmit operation. + * + * @notapi + */ +size_t uart_lld_stop_send(UARTDriver *uartp) { + + dmaStreamDisable(uartp->dmatx); + dmaStreamClearInterrupt(uartp->dmatx); + return dmaStreamGetTransactionSize(uartp->dmatx); +} + +/** + * @brief Starts a receive operation on the UART peripheral. + * @note The buffers are organized as uint8_t arrays for data sizes below + * or equal to 8 bits else it is organized as uint16_t arrays. + * + * @param[in] uartp pointer to the @p UARTDriver object + * @param[in] n number of data frames to send + * @param[out] rxbuf the pointer to the receive buffer + * + * @notapi + */ +void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) { + + /* Stopping previous activity (idle state).*/ + dmaStreamDisable(uartp->dmarx); + dmaStreamClearInterrupt(uartp->dmarx); + + /* RX DMA channel preparation and start.*/ + dmaStreamSetMemory0(uartp->dmarx, rxbuf); + dmaStreamSetTransactionSize(uartp->dmarx, n); + dmaStreamSetMode(uartp->dmarx, uartp->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_MINC | STM32_DMA_CR_TEIE | + STM32_DMA_CR_TCIE); + dmaStreamEnable(uartp->dmarx); +} + +/** + * @brief Stops any ongoing receive operation. + * @note Stopping a receive operation also suppresses the receive callbacks. + * + * @param[in] uartp pointer to the @p UARTDriver object + * + * @return The number of data frames not received by the + * stopped receive operation. + * + * @notapi + */ +size_t uart_lld_stop_receive(UARTDriver *uartp) { + size_t n; + + dmaStreamDisable(uartp->dmarx); + dmaStreamClearInterrupt(uartp->dmarx); + n = dmaStreamGetTransactionSize(uartp->dmarx); + set_rx_idle_loop(uartp); + return n; +} + +#endif /* HAL_USE_UART */ + +/** @} */ diff --git a/os/hal/platforms/STM32/uart_lld.h b/os/hal/platforms/STM32/uart_lld.h new file mode 100644 index 000000000..aff7f52ba --- /dev/null +++ b/os/hal/platforms/STM32/uart_lld.h @@ -0,0 +1,318 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/uart_lld.h + * @brief STM32 low level UART driver header. + * + * @addtogroup UART + * @{ + */ + +#ifndef _UART_LLD_H_ +#define _UART_LLD_H_ + +#if HAL_USE_UART || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @brief UART driver on USART1 enable switch. + * @details If set to @p TRUE the support for USART1 is included. + * @note The default is @p FALSE. + */ +#if !defined(STM32_UART_USE_USART1) || defined(__DOXYGEN__) +#define STM32_UART_USE_USART1 TRUE +#endif + +/** + * @brief UART driver on USART2 enable switch. + * @details If set to @p TRUE the support for USART2 is included. + * @note The default is @p FALSE. + */ +#if !defined(STM32_UART_USE_USART2) || defined(__DOXYGEN__) +#define STM32_UART_USE_USART2 TRUE +#endif + +/** + * @brief UART driver on USART3 enable switch. + * @details If set to @p TRUE the support for USART3 is included. + * @note The default is @p FALSE. + */ +#if !defined(STM32_UART_USE_USART3) || defined(__DOXYGEN__) +#define STM32_UART_USE_USART3 TRUE +#endif + +/** + * @brief USART1 interrupt priority level setting. + */ +#if !defined(STM32_UART_USART1_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_UART_USART1_IRQ_PRIORITY 12 +#endif + +/** + * @brief USART2 interrupt priority level setting. + */ +#if !defined(STM32_UART_USART2_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_UART_USART2_IRQ_PRIORITY 12 +#endif + +/** + * @brief USART3 interrupt priority level setting. + */ +#if !defined(STM32_UART_USART3_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_UART_USART3_IRQ_PRIORITY 12 +#endif + +/** + * @brief USART1 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA channels but + * because of the channels ordering the RX channel has always priority + * over the TX channel. + */ +#if !defined(STM32_UART_USART1_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_UART_USART1_DMA_PRIORITY 0 +#endif + +/** + * @brief USART2 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA channels but + * because of the channels ordering the RX channel has always priority + * over the TX channel. + */ +#if !defined(STM32_UART_USART2_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_UART_USART2_DMA_PRIORITY 0 +#endif +/** + * @brief USART3 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA channels but + * because of the channels ordering the RX channel has always priority + * over the TX channel. + */ +#if !defined(STM32_UART_USART3_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_UART_USART3_DMA_PRIORITY 0 +#endif + +/** + * @brief USART1 DMA error hook. + * @note The default action for DMA errors is a system halt because DMA + * error can only happen because programming errors. + */ +#if !defined(STM32_UART_DMA_ERROR_HOOK) || defined(__DOXYGEN__) +#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt() +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if STM32_UART_USE_USART1 && !STM32_HAS_USART1 +#error "USART1 not present in the selected device" +#endif + +#if STM32_UART_USE_USART2 && !STM32_HAS_USART2 +#error "USART2 not present in the selected device" +#endif + +#if STM32_UART_USE_USART3 && !STM32_HAS_USART3 +#error "USART3 not present in the selected device" +#endif + +#if !STM32_UART_USE_USART1 && !STM32_UART_USE_USART2 && \ + !STM32_UART_USE_USART3 +#error "UART driver activated but no USART/UART peripheral assigned" +#endif + +#if !defined(STM32_DMA_REQUIRED) +#define STM32_DMA_REQUIRED +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief UART driver condition flags type. + */ +typedef uint32_t uartflags_t; + +/** + * @brief Structure representing an UART driver. + */ +typedef struct UARTDriver UARTDriver; + +/** + * @brief Generic UART notification callback type. + * + * @param[in] uartp pointer to the @p UARTDriver object + */ +typedef void (*uartcb_t)(UARTDriver *uartp); + +/** + * @brief Character received UART notification callback type. + * + * @param[in] uartp pointer to the @p UARTDriver object + * @param[in] c received character + */ +typedef void (*uartccb_t)(UARTDriver *uartp, uint16_t c); + +/** + * @brief Receive error UART notification callback type. + * + * @param[in] uartp pointer to the @p UARTDriver object + * @param[in] e receive error mask + */ +typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e); + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + /** + * @brief End of transmission buffer callback. + */ + uartcb_t txend1_cb; + /** + * @brief Physical end of transmission callback. + */ + uartcb_t txend2_cb; + /** + * @brief Receive buffer filled callback. + */ + uartcb_t rxend_cb; + /** + * @brief Character received while out if the @p UART_RECEIVE state. + */ + uartccb_t rxchar_cb; + /** + * @brief Receive error callback. + */ + uartecb_t rxerr_cb; + /* End of the mandatory fields.*/ + /** + * @brief Bit rate. + */ + uint32_t speed; + /** + * @brief Initialization value for the CR1 register. + */ + uint16_t cr1; + /** + * @brief Initialization value for the CR2 register. + */ + uint16_t cr2; + /** + * @brief Initialization value for the CR3 register. + */ + uint16_t cr3; +} UARTConfig; + +/** + * @brief Structure representing an UART driver. + */ +struct UARTDriver { + /** + * @brief Driver state. + */ + uartstate_t state; + /** + * @brief Transmitter state. + */ + uarttxstate_t txstate; + /** + * @brief Receiver state. + */ + uartrxstate_t rxstate; + /** + * @brief Current configuration data. + */ + const UARTConfig *config; +#if defined(UART_DRIVER_EXT_FIELDS) + UART_DRIVER_EXT_FIELDS +#endif + /* End of the mandatory fields.*/ + /** + * @brief Pointer to the USART registers block. + */ + USART_TypeDef *usart; + /** + * @brief DMA mode bit mask. + */ + uint32_t dmamode; + /** + * @brief Receive DMA channel. + */ + const stm32_dma_stream_t *dmarx; + /** + * @brief Transmit DMA channel. + */ + const stm32_dma_stream_t *dmatx; + /** + * @brief Default receive buffer while into @p UART_RX_IDLE state. + */ + volatile uint16_t rxbuf; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if STM32_UART_USE_USART1 && !defined(__DOXYGEN__) +extern UARTDriver UARTD1; +#endif + +#if STM32_UART_USE_USART2 && !defined(__DOXYGEN__) +extern UARTDriver UARTD2; +#endif + +#if STM32_UART_USE_USART3 && !defined(__DOXYGEN__) +extern UARTDriver UARTD3; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void uart_lld_init(void); + void uart_lld_start(UARTDriver *uartp); + void uart_lld_stop(UARTDriver *uartp); + void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf); + size_t uart_lld_stop_send(UARTDriver *uartp); + void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf); + size_t uart_lld_stop_receive(UARTDriver *uartp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_UART */ + +#endif /* _UART_LLD_H_ */ + +/** @} */ -- cgit v1.2.3 From adb989bc17a879e51dbd9aeb471089af1f9d73e2 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 14 Sep 2011 18:59:52 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3318 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/adc_lld.c | 4 ++-- os/hal/platforms/STM32F1xx/adc_lld.h | 4 ++-- os/hal/platforms/STM32F1xx/hal_lld.c | 4 ++-- os/hal/platforms/STM32F1xx/hal_lld.h | 4 ++-- os/hal/platforms/STM32F1xx/platform.mk | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/adc_lld.c b/os/hal/platforms/STM32F1xx/adc_lld.c index 52d43daa9..cc4d25ea1 100644 --- a/os/hal/platforms/STM32F1xx/adc_lld.c +++ b/os/hal/platforms/STM32F1xx/adc_lld.c @@ -19,8 +19,8 @@ */ /** - * @file STM32/adc_lld.c - * @brief STM32 ADC subsystem low level driver source. + * @file STM32F1xx/adc_lld.c + * @brief STM32F1xx ADC subsystem low level driver source. * * @addtogroup ADC * @{ diff --git a/os/hal/platforms/STM32F1xx/adc_lld.h b/os/hal/platforms/STM32F1xx/adc_lld.h index 43b16b738..7180c2b83 100644 --- a/os/hal/platforms/STM32F1xx/adc_lld.h +++ b/os/hal/platforms/STM32F1xx/adc_lld.h @@ -19,8 +19,8 @@ */ /** - * @file STM32/adc_lld.h - * @brief STM32 ADC subsystem low level driver header. + * @file STM32F1xx/adc_lld.h + * @brief STM32F1xx ADC subsystem low level driver header. * * @addtogroup ADC * @{ diff --git a/os/hal/platforms/STM32F1xx/hal_lld.c b/os/hal/platforms/STM32F1xx/hal_lld.c index 081499b83..ba13544f4 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld.c +++ b/os/hal/platforms/STM32F1xx/hal_lld.c @@ -19,8 +19,8 @@ */ /** - * @file STM32/hal_lld.c - * @brief STM32 HAL subsystem low level driver source. + * @file STM32F1xx/hal_lld.c + * @brief STM32F1xx HAL subsystem low level driver source. * * @addtogroup HAL * @{ diff --git a/os/hal/platforms/STM32F1xx/hal_lld.h b/os/hal/platforms/STM32F1xx/hal_lld.h index 44e179f49..77c954e9a 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld.h +++ b/os/hal/platforms/STM32F1xx/hal_lld.h @@ -19,8 +19,8 @@ */ /** - * @file STM32/hal_lld.h - * @brief STM32 HAL subsystem low level driver header. + * @file STM32F1xx/hal_lld.h + * @brief STM32F1xx HAL subsystem low level driver header. * @pre This module requires the following macros to be defined in the * @p board.h file: * - STM32_LSECLK. diff --git a/os/hal/platforms/STM32F1xx/platform.mk b/os/hal/platforms/STM32F1xx/platform.mk index 1a8c42bc7..51601731e 100644 --- a/os/hal/platforms/STM32F1xx/platform.mk +++ b/os/hal/platforms/STM32F1xx/platform.mk @@ -9,10 +9,10 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F1xx/hal_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/mac_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/pwm_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/serial_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/sdc_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/uart_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv1/pal_lld.c \ - ${CHIBIOS}/os/hal/platforms/STM32/DMAv1/sdc_lld.c \ - ${CHIBIOS}/os/hal/platforms/STM32/DMAv1/spi_lld.c \ - ${CHIBIOS}/os/hal/platforms/STM32/DMAv1/uart_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/DMAv1/stm32_dma.c \ ${CHIBIOS}/os/hal/platforms/STM32/USBv1/usb_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/rtc_lld.c -- cgit v1.2.3 From 46538d795be83d1d54b132e7d57213cb6d975c51 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 15 Sep 2011 14:43:36 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3319 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/mac_lld.c | 89 +++++++++++++++++++++++++++++----------- os/hal/platforms/STM32/mac_lld.h | 2 +- 2 files changed, 66 insertions(+), 25 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/mac_lld.c b/os/hal/platforms/STM32/mac_lld.c index 1bec4d879..98f1839c0 100644 --- a/os/hal/platforms/STM32/mac_lld.c +++ b/os/hal/platforms/STM32/mac_lld.c @@ -56,12 +56,14 @@ /** * @brief Ethernet driver 1. */ -MACDriver ETH1; +MACDriver ETHD1; /*===========================================================================*/ /* Driver local variables. */ /*===========================================================================*/ +static uint32_t phyaddr; + static stm32_eth_rx_descriptor_t *rxptr; static stm32_eth_tx_descriptor_t *txptr; @@ -80,13 +82,11 @@ static uint32_t tb[MAC_TRANSMIT_BUFFERS * BUFFER_SLICE]; * * @param[in] reg register number * @param[in] value new register value - * - * @notapi */ -void _stm32_eth_write_phy(uint32_t reg, uint32_t value) { +static void mii_write_phy(uint32_t reg, uint32_t value) { ETH->MACMIIDR = value; - ETH->MACMIIAR = BOARD_PHY_ADDR | (reg << 6) | MACMIIDR_CR | + ETH->MACMIIAR = phyaddr | (reg << 6) | MACMIIDR_CR | ETH_MACMIIAR_MW | ETH_MACMIIAR_MB; while ((ETH->MACMIIAR & ETH_MACMIIAR_MB) != 0) ; @@ -96,12 +96,10 @@ void _stm32_eth_write_phy(uint32_t reg, uint32_t value) { * @brief Reads a PHY register. * * @param[in] reg register number - * - * @notapi */ -static uint32_t _stm32_eth_read_phy(uint32_t reg) { +static uint32_t mii_read_phy(uint32_t reg) { - ETH->MACMIIAR = BOARD_PHY_ADDR | (reg << 6) | MACMIIDR_CR | + ETH->MACMIIAR = phyaddr | (reg << 6) | MACMIIDR_CR | ETH_MACMIIAR_MB; while ((ETH->MACMIIAR & ETH_MACMIIAR_MB) != 0) ; @@ -110,22 +108,22 @@ static uint32_t _stm32_eth_read_phy(uint32_t reg) { /** - * @brief MII/RMII interface initialization. + * @brief PHY address detection. */ -#if 0 -static void mii_init(void) { +static void mii_find_phy(void) { uint32_t i; for (i = 0; i < 31; i++) { ETH->MACMIIDR = (i << 6) | MACMIIDR_CR; - if ((mii_read_phy(MII_PHYSID1) == (PHY_ID >> 16)) && - (mii_read_phy(MII_PHYSID2) == (PHY_ID & 0xFFF0))) + if ((mii_read_phy(MII_PHYSID1) == (BOARD_PHY_ID >> 16)) && + (mii_read_phy(MII_PHYSID2) == (BOARD_PHY_ID & 0xFFF0))) { + phyaddr = i << 11; return; + } } /* Wrong or defective board.*/ chSysHalt(); } -#endif /*===========================================================================*/ /* Driver interrupt handlers. */ @@ -143,7 +141,7 @@ static void mii_init(void) { void mac_lld_init(void) { unsigned i; - macObjectInit(Ð1); + macObjectInit(ÐD1); /* Descriptor tables are initialized in linked mode, note that the first word is not initialized here but in mac_lld_start().*/ @@ -159,6 +157,36 @@ void mac_lld_init(void) { td[i].tdes3 = (uint32_t)&tb[((i + 1) % MAC_TRANSMIT_BUFFERS) * BUFFER_SLICE]; } + + /* MAC clocks activation.*/ + RCC->AHBENR |= RCC_AHBENR_ETHMACEN | + RCC_AHBENR_ETHMACTXEN | + RCC_AHBENR_ETHMACRXEN; + + /* Reset of the MAC core.*/ + RCC->AHBRSTR = RCC_AHBRSTR_ETHMACRST; + RCC->AHBRSTR = 0; + + /* Find PHY address.*/ + mii_find_phy(); + +#if defined(BOARD_PHY_RESET) + /* PHY board-specific reset procedure.*/ + BOARD_PHY_RESET(); +#else + /* PHY soft reset procedure.*/ + mii_write_phy(MII_BMCR, BMCR_RESET); + while (mii_read_phy(MII_BMCR) & BMCR_RESET) + ; +#endif + + /* PHY in power down mode until the driver will be started.*/ + mii_write_phy(MII_BMCR, BMCR_PDOWN); + + /* MAC clocks stopped again.*/ + RCC->AHBENR &= ~(RCC_AHBENR_ETHMACEN | + RCC_AHBENR_ETHMACTXEN | + RCC_AHBENR_ETHMACRXEN); } /** @@ -179,19 +207,28 @@ void mac_lld_start(MACDriver *macp) { td[i].tdes0 = STM32_TDES0_TCH; txptr = (stm32_eth_tx_descriptor_t *)td; - /* Soft reset of the MAC core and wait until the reset is complete.*/ - ETH->DMABMR |= ETH_DMABMR_SR; - while (ETH->DMABMR & ETH_DMABMR_SR) - ; - - /* MII initialization.*/ -// mii_init(); + /* MAC clocks activation.*/ + RCC->AHBENR |= RCC_AHBENR_ETHMACEN | + RCC_AHBENR_ETHMACTXEN | + RCC_AHBENR_ETHMACRXEN; /* Descriptor chains pointers.*/ ETH->DMARDLAR = (uint32_t)rd; ETH->DMATDLAR = (uint32_t)rd; - /* Clear DMA status.*/ + /* MAC configuration: + ETH_MACCR_TE - Transmitter enable. + ETH_MACCR_RE - Receiver enable. + Note that the complete setup of the MAC is performed when the link + status is detected.*/ + ETH->MACCR = ETH_MACCR_TE | ETH_MACCR_TE; + + ETH->MACFFR = 0; + ETH->MACHTHR = 0; + ETH->MACHTLR = 0; + ETH->MACHTLR = 0; + ETH->MACFCR = 0; + ETH->MACVLANTR = 0; } /** @@ -203,6 +240,10 @@ void mac_lld_start(MACDriver *macp) { */ void mac_lld_stop(MACDriver *macp) { + /* MAC clocks stopped.*/ + RCC->AHBENR &= ~(RCC_AHBENR_ETHMACEN | + RCC_AHBENR_ETHMACTXEN | + RCC_AHBENR_ETHMACRXEN); } /** diff --git a/os/hal/platforms/STM32/mac_lld.h b/os/hal/platforms/STM32/mac_lld.h index f21f4c129..3e00639cc 100644 --- a/os/hal/platforms/STM32/mac_lld.h +++ b/os/hal/platforms/STM32/mac_lld.h @@ -242,7 +242,7 @@ typedef struct { /*===========================================================================*/ #if !defined(__DOXYGEN__) -extern MACDriver ETH1; +extern MACDriver ETHD1; #endif #ifdef __cplusplus -- cgit v1.2.3 From 3a94137eb38857d9780a5ef65be30736804dea46 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 16 Sep 2011 17:38:22 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3320 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/stm32_dma.c | 8 +++--- os/hal/platforms/STM32/GPIOv1/pal_lld.c | 2 +- os/hal/platforms/STM32/GPIOv2/pal_lld.c | 16 ++++++------ os/hal/platforms/STM32/USBv1/usb_lld.c | 6 ++--- os/hal/platforms/STM32/can_lld.c | 4 +-- os/hal/platforms/STM32/gpt_lld.c | 42 ++++++++++++++------------------ os/hal/platforms/STM32/i2c_lld.c | 15 ++++-------- os/hal/platforms/STM32/icu_lld.c | 42 ++++++++++++++------------------ os/hal/platforms/STM32/mac_lld.c | 19 ++++----------- os/hal/platforms/STM32/pwm_lld.c | 42 ++++++++++++++------------------ os/hal/platforms/STM32/sdc_lld.c | 3 ++- os/hal/platforms/STM32/serial_lld.c | 20 +++++++-------- os/hal/platforms/STM32/spi_lld.c | 12 ++++----- os/hal/platforms/STM32/uart_lld.c | 12 ++++----- os/hal/platforms/STM32F1xx/adc_lld.c | 8 +++--- os/hal/platforms/STM32F1xx/hal_lld.c | 6 ++--- os/hal/platforms/STM32F1xx/hal_lld.h | 3 ++- os/hal/platforms/STM32L1xx/hal_lld.h | 3 ++- 18 files changed, 115 insertions(+), 148 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.c b/os/hal/platforms/STM32/DMAv1/stm32_dma.c index 1df93bb2f..29ee02360 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.c @@ -437,10 +437,10 @@ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, /* Enabling DMA clocks required by the current streams set.*/ if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) - RCC->AHBENR |= RCC_AHBENR_DMA1EN; + rccEnableDMA1(FALSE); #if STM32_HAS_DMA2 if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) - RCC->AHBENR |= RCC_AHBENR_DMA2EN; + rccEnableDMA2(FALSE); #endif /* Putting the stream in a safe state.*/ @@ -484,10 +484,10 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { /* Shutting down clocks that are no more required, if any.*/ if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) - RCC->AHBENR &= ~RCC_AHBENR_DMA1EN; + rccDisableDMA1(FALSE); #if STM32_HAS_DMA2 if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) - RCC->AHBENR &= ~RCC_AHBENR_DMA2EN; + rccDisableDMA2(FALSE); #endif } diff --git a/os/hal/platforms/STM32/GPIOv1/pal_lld.c b/os/hal/platforms/STM32/GPIOv1/pal_lld.c index 81846fa58..274d8b6c0 100644 --- a/os/hal/platforms/STM32/GPIOv1/pal_lld.c +++ b/os/hal/platforms/STM32/GPIOv1/pal_lld.c @@ -79,7 +79,7 @@ void _pal_lld_init(const PALConfig *config) { /* * Enables the GPIO related clocks. */ - RCC->APB2ENR |= APB2_EN_MASK; + rccEnableAPB2(APB2_EN_MASK, FALSE); /* * Initial GPIO setup. diff --git a/os/hal/platforms/STM32/GPIOv2/pal_lld.c b/os/hal/platforms/STM32/GPIOv2/pal_lld.c index c84df64f6..8f84f225e 100644 --- a/os/hal/platforms/STM32/GPIOv2/pal_lld.c +++ b/os/hal/platforms/STM32/GPIOv2/pal_lld.c @@ -32,15 +32,14 @@ #if HAL_USE_PAL || defined(__DOXYGEN__) #if defined(STM32L1XX_MD) -#define AHB_EN_MASK (RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | \ - RCC_AHBENR_GPIOCEN | RCC_AHBENR_GPIODEN | \ +#define AHB_EN_MASK (RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | \ + RCC_AHBENR_GPIOCEN | RCC_AHBENR_GPIODEN | \ RCC_AHBENR_GPIOEEN | RCC_AHBENR_GPIOHEN) -#define AHB_LPEN_MASK AHB_EN_MASK #elif defined(STM32F2XX) -#define AHB1_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 | \ +#define AHB1_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) #define AHB1_LPEN_MASK AHB1_EN_MASK #else @@ -92,8 +91,7 @@ void _pal_lld_init(const PALConfig *config) { * Enables the GPIO related clocks. */ #if defined(STM32L1XX_MD) - RCC->AHBENR |= AHB_EN_MASK; - RCC->AHBLPENR |= AHB_LPEN_MASK; + rccEnableAHB(AHB_EN_MASK, TRUE); #elif defined(STM32F2XX) RCC->AHB1ENR |= AHB1_EN_MASK; RCC->AHB1LPENR |= AHB1_LPEN_MASK; diff --git a/os/hal/platforms/STM32/USBv1/usb_lld.c b/os/hal/platforms/STM32/USBv1/usb_lld.c index 34b8d9bf0..b22f8f0da 100644 --- a/os/hal/platforms/STM32/USBv1/usb_lld.c +++ b/os/hal/platforms/STM32/USBv1/usb_lld.c @@ -330,7 +330,7 @@ void usb_lld_start(USBDriver *usbp) { #if STM32_USB_USE_USB1 if (&USBD1 == usbp) { /* USB clock enabled.*/ - RCC->APB1ENR |= RCC_APB1ENR_USBEN; + rccEnableUSB(FALSE); /* 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 @@ -360,12 +360,12 @@ void usb_lld_stop(USBDriver *usbp) { /* If in ready state then disables the USB clock.*/ if (usbp->state == USB_STOP) { -#if STM32_ADC_USE_ADC1 +#if STM32_USB_USE_USB1 if (&USBD1 == usbp) { NVICDisableVector(19); NVICDisableVector(20); STM32_USB->CNTR = CNTR_PDWN | CNTR_FRES; - RCC->APB1ENR &= ~RCC_APB1ENR_USBEN; + rccDisableUSB(FALSE); } #endif } diff --git a/os/hal/platforms/STM32/can_lld.c b/os/hal/platforms/STM32/can_lld.c index e180a87cb..64ccb3af3 100644 --- a/os/hal/platforms/STM32/can_lld.c +++ b/os/hal/platforms/STM32/can_lld.c @@ -192,7 +192,7 @@ void can_lld_start(CANDriver *canp) { CORTEX_PRIORITY_MASK(STM32_CAN_CAN1_IRQ_PRIORITY)); NVICEnableVector(CAN1_SCE_IRQn, CORTEX_PRIORITY_MASK(STM32_CAN_CAN1_IRQ_PRIORITY)); - RCC->APB1ENR |= RCC_APB1ENR_CAN1EN; + rccEnableCAN1(FALSE); } #endif @@ -276,7 +276,7 @@ void can_lld_stop(CANDriver *canp) { NVICDisableVector(USB_LP_CAN1_RX0_IRQn); NVICDisableVector(CAN1_RX1_IRQn); NVICDisableVector(CAN1_SCE_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_CAN1EN; + rccDisableCAN1(FALSE); } #endif } diff --git a/os/hal/platforms/STM32/gpt_lld.c b/os/hal/platforms/STM32/gpt_lld.c index f7a9226ad..0fd5dde73 100644 --- a/os/hal/platforms/STM32/gpt_lld.c +++ b/os/hal/platforms/STM32/gpt_lld.c @@ -268,9 +268,8 @@ void gpt_lld_start(GPTDriver *gptp) { /* Clock activation.*/ #if STM32_GPT_USE_TIM1 if (&GPTD1 == gptp) { - RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; - RCC->APB2RSTR = RCC_APB2RSTR_TIM1RST; - RCC->APB2RSTR = 0; + rccEnableTIM1(FALSE); + rccResetTIM1(); NVICEnableVector(TIM1_UP_IRQn, CORTEX_PRIORITY_MASK(STM32_GPT_TIM1_IRQ_PRIORITY)); gptp->clock = STM32_TIMCLK2; @@ -278,9 +277,8 @@ void gpt_lld_start(GPTDriver *gptp) { #endif #if STM32_GPT_USE_TIM2 if (&GPTD2 == gptp) { - RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; - RCC->APB1RSTR = RCC_APB1RSTR_TIM2RST; - RCC->APB1RSTR = 0; + rccEnableTIM2(FALSE); + rccResetTIM2(); NVICEnableVector(TIM2_IRQn, CORTEX_PRIORITY_MASK(STM32_GPT_TIM2_IRQ_PRIORITY)); gptp->clock = STM32_TIMCLK1; @@ -288,9 +286,8 @@ void gpt_lld_start(GPTDriver *gptp) { #endif #if STM32_GPT_USE_TIM3 if (&GPTD3 == gptp) { - RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; - RCC->APB1RSTR = RCC_APB1RSTR_TIM3RST; - RCC->APB1RSTR = 0; + rccEnableTIM3(FALSE); + rccResetTIM3(); NVICEnableVector(TIM3_IRQn, CORTEX_PRIORITY_MASK(STM32_GPT_TIM3_IRQ_PRIORITY)); gptp->clock = STM32_TIMCLK1; @@ -298,9 +295,8 @@ void gpt_lld_start(GPTDriver *gptp) { #endif #if STM32_GPT_USE_TIM4 if (&GPTD4 == gptp) { - RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; - RCC->APB1RSTR = RCC_APB1RSTR_TIM4RST; - RCC->APB1RSTR = 0; + rccEnableTIM4(FALSE); + rccResetTIM4(); NVICEnableVector(TIM4_IRQn, CORTEX_PRIORITY_MASK(STM32_GPT_TIM4_IRQ_PRIORITY)); gptp->clock = STM32_TIMCLK1; @@ -309,9 +305,8 @@ void gpt_lld_start(GPTDriver *gptp) { #if STM32_GPT_USE_TIM5 if (&GPTD5 == gptp) { - RCC->APB1ENR |= RCC_APB1ENR_TIM5EN; - RCC->APB1RSTR = RCC_APB1RSTR_TIM5RST; - RCC->APB1RSTR = 0; + rccEnableTIM5(FALSE); + rccResetTIM5(); NVICEnableVector(TIM5_IRQn, CORTEX_PRIORITY_MASK(STM32_GPT_TIM5_IRQ_PRIORITY)); gptp->clock = STM32_TIMCLK1; @@ -320,9 +315,8 @@ void gpt_lld_start(GPTDriver *gptp) { #if STM32_GPT_USE_TIM8 if (&GPTD8 == gptp) { - RCC->APB2ENR |= RCC_APB2ENR_TIM8EN; - RCC->APB2RSTR = RCC_APB2RSTR_TIM8RST; - RCC->APB2RSTR = 0; + rccEnableTIM8(FALSE); + rccResetTIM8(); NVICEnableVector(TIM8_UP_IRQn, CORTEX_PRIORITY_MASK(STM32_GPT_TIM8_IRQ_PRIORITY)); gptp->clock = STM32_TIMCLK2; @@ -359,37 +353,37 @@ void gpt_lld_stop(GPTDriver *gptp) { #if STM32_GPT_USE_TIM1 if (&GPTD1 == gptp) { NVICDisableVector(TIM1_UP_IRQn); - RCC->APB2ENR &= ~RCC_APB2ENR_TIM1EN; + rccDisableTIM1(FALSE); } #endif #if STM32_GPT_USE_TIM2 if (&GPTD2 == gptp) { NVICDisableVector(TIM2_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_TIM2EN; + rccDisableTIM2(FALSE); } #endif #if STM32_GPT_USE_TIM3 if (&GPTD3 == gptp) { NVICDisableVector(TIM3_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_TIM3EN; + rccDisableTIM3(FALSE); } #endif #if STM32_GPT_USE_TIM4 if (&GPTD4 == gptp) { NVICDisableVector(TIM4_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_TIM4EN; + rccDisableTIM4(FALSE); } #endif #if STM32_GPT_USE_TIM5 if (&GPTD5 == gptp) { NVICDisableVector(TIM5_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_TIM5EN; + rccDisableTIM5(FALSE); } #endif #if STM32_GPT_USE_TIM8 if (&GPTD8 == gptp) { NVICDisableVector(TIM8_UP_IRQn); - RCC->APB2ENR &= ~RCC_APB2ENR_TIM8EN; + rccDisableTIM8(FALSE); } #endif } diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index 202669f8e..317fc57dd 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -497,8 +497,6 @@ CH_IRQ_HANDLER(VectorC8) { void i2c_lld_init(void) { #if STM32_I2C_USE_I2C1 - RCC->APB1RSTR = RCC_APB1RSTR_I2C1RST; /* reset I2C 1 */ - RCC->APB1RSTR = 0; i2cObjectInit(&I2CD1); I2CD1.id_i2c = I2C1; @@ -512,8 +510,6 @@ void i2c_lld_init(void) { #endif /* STM32_I2C_USE_I2C */ #if STM32_I2C_USE_I2C2 - RCC->APB1RSTR = RCC_APB1RSTR_I2C2RST; /* reset I2C 2 */ - RCC->APB1RSTR = 0; i2cObjectInit(&I2CD2); I2CD2.id_i2c = I2C2; @@ -542,7 +538,7 @@ void i2c_lld_start(I2CDriver *i2cp) { #endif /* I2C_SUPPORTS_CALLBACKS */ NVICEnableVector(I2C1_ER_IRQn, CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); - RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; /* I2C 1 clock enable */ + rccEnableI2C1(FALSE); } #endif #if STM32_I2C_USE_I2C2 @@ -553,7 +549,7 @@ void i2c_lld_start(I2CDriver *i2cp) { #endif /* I2C_SUPPORTS_CALLBACKS */ NVICEnableVector(I2C2_ER_IRQn, CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); - RCC->APB1ENR |= RCC_APB1ENR_I2C2EN; /* I2C 2 clock enable */ + rccEnableI2C2(FALSE); } #endif } @@ -569,8 +565,7 @@ void i2c_lld_reset(I2CDriver *i2cp){ chDbgCheck((i2cp->id_state == I2C_STOP)||(i2cp->id_state == I2C_READY), "i2c_lld_reset: invalid state"); - RCC->APB1RSTR = RCC_APB1RSTR_I2C1RST; /* reset I2C 1 */ - RCC->APB1RSTR = 0; + rccResetI2C1(); } @@ -699,14 +694,14 @@ void i2c_lld_stop(I2CDriver *i2cp) { if (&I2CD1 == i2cp) { NVICDisableVector(I2C1_EV_IRQn); NVICDisableVector(I2C1_ER_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_I2C1EN; + rccDisableI2C1(FALSE); } #endif #if STM32_I2C_USE_I2C2 if (&I2CD2 == i2cp) { NVICDisableVector(I2C2_EV_IRQn); NVICDisableVector(I2C2_ER_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_I2C2EN; + rccDisableI2C2(FALSE); } #endif } diff --git a/os/hal/platforms/STM32/icu_lld.c b/os/hal/platforms/STM32/icu_lld.c index 054ce1e3d..eaf98ec12 100644 --- a/os/hal/platforms/STM32/icu_lld.c +++ b/os/hal/platforms/STM32/icu_lld.c @@ -287,9 +287,8 @@ void icu_lld_start(ICUDriver *icup) { /* Clock activation and timer reset.*/ #if STM32_ICU_USE_TIM1 if (&ICUD1 == icup) { - RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; - RCC->APB2RSTR = RCC_APB2RSTR_TIM1RST; - RCC->APB2RSTR = 0; + rccEnableTIM1(FALSE); + rccResetTIM1(); NVICEnableVector(TIM1_CC_IRQn, CORTEX_PRIORITY_MASK(STM32_ICU_TIM1_IRQ_PRIORITY)); clock = STM32_TIMCLK2; @@ -297,9 +296,8 @@ void icu_lld_start(ICUDriver *icup) { #endif #if STM32_ICU_USE_TIM2 if (&ICUD2 == icup) { - RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; - RCC->APB1RSTR = RCC_APB1RSTR_TIM2RST; - RCC->APB1RSTR = 0; + rccEnableTIM2(FALSE); + rccResetTIM2(); NVICEnableVector(TIM2_IRQn, CORTEX_PRIORITY_MASK(STM32_ICU_TIM2_IRQ_PRIORITY)); clock = STM32_TIMCLK1; @@ -307,9 +305,8 @@ void icu_lld_start(ICUDriver *icup) { #endif #if STM32_ICU_USE_TIM3 if (&ICUD3 == icup) { - RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; - RCC->APB1RSTR = RCC_APB1RSTR_TIM3RST; - RCC->APB1RSTR = 0; + rccEnableTIM3(FALSE); + rccResetTIM3(); NVICEnableVector(TIM3_IRQn, CORTEX_PRIORITY_MASK(STM32_ICU_TIM3_IRQ_PRIORITY)); clock = STM32_TIMCLK1; @@ -317,9 +314,8 @@ void icu_lld_start(ICUDriver *icup) { #endif #if STM32_ICU_USE_TIM4 if (&ICUD4 == icup) { - RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; - RCC->APB1RSTR = RCC_APB1RSTR_TIM4RST; - RCC->APB1RSTR = 0; + rccEnableTIM4(FALSE); + rccResetTIM4(); NVICEnableVector(TIM4_IRQn, CORTEX_PRIORITY_MASK(STM32_ICU_TIM4_IRQ_PRIORITY)); clock = STM32_TIMCLK1; @@ -328,9 +324,8 @@ void icu_lld_start(ICUDriver *icup) { #if STM32_ICU_USE_TIM5 if (&ICUD5 == icup) { - RCC->APB1ENR |= RCC_APB1ENR_TIM5EN; - RCC->APB1RSTR = RCC_APB1RSTR_TIM5RST; - RCC->APB1RSTR = 0; + rccEnableTIM5(FALSE); + rccResetTIM5(); NVICEnableVector(TIM5_IRQn, CORTEX_PRIORITY_MASK(STM32_ICU_TIM5_IRQ_PRIORITY)); clock = STM32_TIMCLK1; @@ -338,9 +333,8 @@ void icu_lld_start(ICUDriver *icup) { #endif #if STM32_ICU_USE_TIM8 if (&ICUD8 == icup) { - RCC->APB2ENR |= RCC_APB2ENR_TIM8EN; - RCC->APB2RSTR = RCC_APB2RSTR_TIM8RST; - RCC->APB2RSTR = 0; + rccEnableTIM5(FALSE); + rccResetTIM5(); NVICEnableVector(TIM8_CC_IRQn, CORTEX_PRIORITY_MASK(STM32_ICU_TIM8_IRQ_PRIORITY)); clock = STM32_TIMCLK2; @@ -402,38 +396,38 @@ void icu_lld_stop(ICUDriver *icup) { #if STM32_ICU_USE_TIM1 if (&ICUD1 == icup) { NVICDisableVector(TIM1_CC_IRQn); - RCC->APB2ENR &= ~RCC_APB2ENR_TIM1EN; + rccDisableTIM1(FALSE); } #endif #if STM32_ICU_USE_TIM2 if (&ICUD2 == icup) { NVICDisableVector(TIM2_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_TIM2EN; + rccDisableTIM2(FALSE); } #endif #if STM32_ICU_USE_TIM3 if (&ICUD3 == icup) { NVICDisableVector(TIM3_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_TIM3EN; + rccDisableTIM3(FALSE); } #endif #if STM32_ICU_USE_TIM4 if (&ICUD4 == icup) { NVICDisableVector(TIM4_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_TIM4EN; + rccDisableTIM4(FALSE); } #endif #if STM32_ICU_USE_TIM5 if (&ICUD5 == icup) { NVICDisableVector(TIM5_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_TIM5EN; + rccDisableTIM5(FALSE); } #endif } #if STM32_ICU_USE_TIM8 if (&ICUD8 == icup) { NVICDisableVector(TIM8_CC_IRQn); - RCC->APB2ENR &= ~RCC_APB2ENR_TIM8EN; + rccDisableTIM8(FALSE); } #endif } diff --git a/os/hal/platforms/STM32/mac_lld.c b/os/hal/platforms/STM32/mac_lld.c index 98f1839c0..99fba21ff 100644 --- a/os/hal/platforms/STM32/mac_lld.c +++ b/os/hal/platforms/STM32/mac_lld.c @@ -159,13 +159,10 @@ void mac_lld_init(void) { } /* MAC clocks activation.*/ - RCC->AHBENR |= RCC_AHBENR_ETHMACEN | - RCC_AHBENR_ETHMACTXEN | - RCC_AHBENR_ETHMACRXEN; + rccEnableETH(FALSE); /* Reset of the MAC core.*/ - RCC->AHBRSTR = RCC_AHBRSTR_ETHMACRST; - RCC->AHBRSTR = 0; + rccResetETH(); /* Find PHY address.*/ mii_find_phy(); @@ -184,9 +181,7 @@ void mac_lld_init(void) { mii_write_phy(MII_BMCR, BMCR_PDOWN); /* MAC clocks stopped again.*/ - RCC->AHBENR &= ~(RCC_AHBENR_ETHMACEN | - RCC_AHBENR_ETHMACTXEN | - RCC_AHBENR_ETHMACRXEN); + rccDisableETH(FALSE); } /** @@ -208,9 +203,7 @@ void mac_lld_start(MACDriver *macp) { txptr = (stm32_eth_tx_descriptor_t *)td; /* MAC clocks activation.*/ - RCC->AHBENR |= RCC_AHBENR_ETHMACEN | - RCC_AHBENR_ETHMACTXEN | - RCC_AHBENR_ETHMACRXEN; + rccEnableETH(FALSE); /* Descriptor chains pointers.*/ ETH->DMARDLAR = (uint32_t)rd; @@ -241,9 +234,7 @@ void mac_lld_start(MACDriver *macp) { void mac_lld_stop(MACDriver *macp) { /* MAC clocks stopped.*/ - RCC->AHBENR &= ~(RCC_AHBENR_ETHMACEN | - RCC_AHBENR_ETHMACTXEN | - RCC_AHBENR_ETHMACRXEN); + rccDisableETH(FALSE); } /** diff --git a/os/hal/platforms/STM32/pwm_lld.c b/os/hal/platforms/STM32/pwm_lld.c index efe215458..901474091 100644 --- a/os/hal/platforms/STM32/pwm_lld.c +++ b/os/hal/platforms/STM32/pwm_lld.c @@ -348,9 +348,8 @@ void pwm_lld_start(PWMDriver *pwmp) { /* Clock activation and timer reset.*/ #if STM32_PWM_USE_TIM1 if (&PWMD1 == pwmp) { - RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; - RCC->APB2RSTR = RCC_APB2RSTR_TIM1RST; - RCC->APB2RSTR = 0; + rccEnableTIM1(FALSE); + rccResetTIM1(); NVICEnableVector(TIM1_UP_IRQn, CORTEX_PRIORITY_MASK(STM32_PWM_TIM1_IRQ_PRIORITY)); NVICEnableVector(TIM1_CC_IRQn, @@ -360,9 +359,8 @@ void pwm_lld_start(PWMDriver *pwmp) { #endif #if STM32_PWM_USE_TIM2 if (&PWMD2 == pwmp) { - RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; - RCC->APB1RSTR = RCC_APB1RSTR_TIM2RST; - RCC->APB1RSTR = 0; + rccEnableTIM2(FALSE); + rccResetTIM2(); NVICEnableVector(TIM2_IRQn, CORTEX_PRIORITY_MASK(STM32_PWM_TIM2_IRQ_PRIORITY)); clock = STM32_TIMCLK1; @@ -370,9 +368,8 @@ void pwm_lld_start(PWMDriver *pwmp) { #endif #if STM32_PWM_USE_TIM3 if (&PWMD3 == pwmp) { - RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; - RCC->APB1RSTR = RCC_APB1RSTR_TIM3RST; - RCC->APB1RSTR = 0; + rccEnableTIM3(FALSE); + rccResetTIM3(); NVICEnableVector(TIM3_IRQn, CORTEX_PRIORITY_MASK(STM32_PWM_TIM3_IRQ_PRIORITY)); clock = STM32_TIMCLK1; @@ -380,9 +377,8 @@ void pwm_lld_start(PWMDriver *pwmp) { #endif #if STM32_PWM_USE_TIM4 if (&PWMD4 == pwmp) { - RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; - RCC->APB1RSTR = RCC_APB1RSTR_TIM4RST; - RCC->APB1RSTR = 0; + rccEnableTIM4(FALSE); + rccResetTIM4(); NVICEnableVector(TIM4_IRQn, CORTEX_PRIORITY_MASK(STM32_PWM_TIM4_IRQ_PRIORITY)); clock = STM32_TIMCLK1; @@ -391,9 +387,8 @@ void pwm_lld_start(PWMDriver *pwmp) { #if STM32_PWM_USE_TIM5 if (&PWMD5 == pwmp) { - RCC->APB1ENR |= RCC_APB1ENR_TIM5EN; - RCC->APB1RSTR = RCC_APB1RSTR_TIM5RST; - RCC->APB1RSTR = 0; + rccEnableTIM5(FALSE); + rccResetTIM5(); NVICEnableVector(TIM5_IRQn, CORTEX_PRIORITY_MASK(STM32_PWM_TIM5_IRQ_PRIORITY)); clock = STM32_TIMCLK1; @@ -401,9 +396,8 @@ void pwm_lld_start(PWMDriver *pwmp) { #endif #if STM32_PWM_USE_TIM8 if (&PWMD8 == pwmp) { - RCC->APB2ENR |= RCC_APB2ENR_TIM8EN; - RCC->APB2RSTR = RCC_APB2RSTR_TIM8RST; - RCC->APB2RSTR = 0; + rccEnableTIM8(FALSE); + rccResetTIM8(); NVICEnableVector(TIM8_UP_IRQn, CORTEX_PRIORITY_MASK(STM32_PWM_TIM8_IRQ_PRIORITY)); NVICEnableVector(TIM8_CC_IRQn, @@ -552,38 +546,38 @@ void pwm_lld_stop(PWMDriver *pwmp) { if (&PWMD1 == pwmp) { NVICDisableVector(TIM1_UP_IRQn); NVICDisableVector(TIM1_CC_IRQn); - RCC->APB2ENR &= ~RCC_APB2ENR_TIM1EN; + rccDisableTIM1(FALSE); } #endif #if STM32_PWM_USE_TIM2 if (&PWMD2 == pwmp) { NVICDisableVector(TIM2_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_TIM2EN; + rccDisableTIM2(FALSE); } #endif #if STM32_PWM_USE_TIM3 if (&PWMD3 == pwmp) { NVICDisableVector(TIM3_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_TIM3EN; + rccDisableTIM3(FALSE); } #endif #if STM32_PWM_USE_TIM4 if (&PWMD4 == pwmp) { NVICDisableVector(TIM4_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_TIM4EN; + rccDisableTIM4(FALSE); } #endif #if STM32_PWM_USE_TIM5 if (&PWMD5 == pwmp) { NVICDisableVector(TIM5_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_TIM5EN; + rccDisableTIM5(FALSE); } #endif #if STM32_PWM_USE_TIM8 if (&PWMD8 == pwmp) { NVICDisableVector(TIM8_UP_IRQn); NVICDisableVector(TIM8_CC_IRQn); - RCC->APB2ENR &= ~RCC_APB2ENR_TIM8EN; + rccDisableTIM8(FALSE); } #endif } diff --git a/os/hal/platforms/STM32/sdc_lld.c b/os/hal/platforms/STM32/sdc_lld.c index b9e02a815..2ce3cd0fb 100644 --- a/os/hal/platforms/STM32/sdc_lld.c +++ b/os/hal/platforms/STM32/sdc_lld.c @@ -443,7 +443,7 @@ void sdc_lld_start(SDCDriver *sdcp) { dmaStreamSetPeripheral(STM32_DMA2_STREAM4, &SDIO->FIFO); NVICEnableVector(SDIO_IRQn, CORTEX_PRIORITY_MASK(STM32_SDC_SDIO_IRQ_PRIORITY)); - RCC->AHBENR |= RCC_AHBENR_SDIOEN; + rccEnableSDIO(FALSE); } /* Configuration, card clock is initially stopped.*/ SDIO->POWER = 0; @@ -470,6 +470,7 @@ void sdc_lld_stop(SDCDriver *sdcp) { /* Clock deactivation.*/ NVICDisableVector(SDIO_IRQn); dmaStreamRelease(STM32_DMA2_STREAM4); + rccDisableSDIO(FALSE); } } diff --git a/os/hal/platforms/STM32/serial_lld.c b/os/hal/platforms/STM32/serial_lld.c index 5aaa60de9..ce412dedb 100644 --- a/os/hal/platforms/STM32/serial_lld.c +++ b/os/hal/platforms/STM32/serial_lld.c @@ -376,35 +376,35 @@ void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) { if (sdp->state == SD_STOP) { #if STM32_SERIAL_USE_USART1 if (&SD1 == sdp) { - RCC->APB2ENR |= RCC_APB2ENR_USART1EN; + rccEnableUSART1(FALSE); NVICEnableVector(USART1_IRQn, CORTEX_PRIORITY_MASK(STM32_SERIAL_USART1_PRIORITY)); } #endif #if STM32_SERIAL_USE_USART2 if (&SD2 == sdp) { - RCC->APB1ENR |= RCC_APB1ENR_USART2EN; + rccEnableUSART2(FALSE); NVICEnableVector(USART2_IRQn, CORTEX_PRIORITY_MASK(STM32_SERIAL_USART2_PRIORITY)); } #endif #if STM32_SERIAL_USE_USART3 if (&SD3 == sdp) { - RCC->APB1ENR |= RCC_APB1ENR_USART3EN; + rccEnableUSART3(FALSE); NVICEnableVector(USART3_IRQn, CORTEX_PRIORITY_MASK(STM32_SERIAL_USART3_PRIORITY)); } #endif #if STM32_SERIAL_USE_UART4 if (&SD4 == sdp) { - RCC->APB1ENR |= RCC_APB1ENR_UART4EN; + rccEnableUART4(FALSE); NVICEnableVector(UART4_IRQn, CORTEX_PRIORITY_MASK(STM32_SERIAL_UART4_PRIORITY)); } #endif #if STM32_SERIAL_USE_UART5 if (&SD5 == sdp) { - RCC->APB1ENR |= RCC_APB1ENR_UART5EN; + rccEnableUART5(FALSE); NVICEnableVector(UART5_IRQn, CORTEX_PRIORITY_MASK(STM32_SERIAL_UART5_PRIORITY)); } @@ -428,35 +428,35 @@ void sd_lld_stop(SerialDriver *sdp) { usart_deinit(sdp->usart); #if STM32_SERIAL_USE_USART1 if (&SD1 == sdp) { - RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN; + rccDisableUSART1(FALSE); NVICDisableVector(USART1_IRQn); return; } #endif #if STM32_SERIAL_USE_USART2 if (&SD2 == sdp) { - RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN; + rccDisableUSART2(FALSE); NVICDisableVector(USART2_IRQn); return; } #endif #if STM32_SERIAL_USE_USART3 if (&SD3 == sdp) { - RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN; + rccDisableUSART3(FALSE); NVICDisableVector(USART3_IRQn); return; } #endif #if STM32_SERIAL_USE_UART4 if (&SD4 == sdp) { - RCC->APB1ENR &= ~RCC_APB1ENR_UART4EN; + rccDisableUART4(FALSE); NVICDisableVector(UART4_IRQn); return; } #endif #if STM32_SERIAL_USE_UART5 if (&SD5 == sdp) { - RCC->APB1ENR &= ~RCC_APB1ENR_UART5EN; + rccDisableUART5(FALSE); NVICDisableVector(UART5_IRQn); return; } diff --git a/os/hal/platforms/STM32/spi_lld.c b/os/hal/platforms/STM32/spi_lld.c index 9302b0102..7041ef854 100644 --- a/os/hal/platforms/STM32/spi_lld.c +++ b/os/hal/platforms/STM32/spi_lld.c @@ -192,7 +192,7 @@ void spi_lld_start(SPIDriver *spip) { (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); chDbgAssert(!b, "spi_lld_start(), #2", "stream already allocated"); - RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; + rccEnableSPI1(FALSE); } #endif #if STM32_SPI_USE_SPI2 @@ -208,7 +208,7 @@ void spi_lld_start(SPIDriver *spip) { (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); chDbgAssert(!b, "spi_lld_start(), #4", "stream already allocated"); - RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; + rccEnableSPI2(FALSE); } #endif #if STM32_SPI_USE_SPI3 @@ -224,7 +224,7 @@ void spi_lld_start(SPIDriver *spip) { (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); chDbgAssert(!b, "spi_lld_start(), #6", "stream already allocated"); - RCC->APB1ENR |= RCC_APB1ENR_SPI3EN; + rccEnableSPI3(FALSE); } #endif @@ -272,21 +272,21 @@ void spi_lld_stop(SPIDriver *spip) { if (&SPID1 == spip) { dmaStreamRelease(STM32_DMA1_STREAM2); dmaStreamRelease(STM32_DMA1_STREAM3); - RCC->APB2ENR &= ~RCC_APB2ENR_SPI1EN; + rccDisableSPI1(FALSE); } #endif #if STM32_SPI_USE_SPI2 if (&SPID2 == spip) { dmaStreamRelease(STM32_DMA1_STREAM4); dmaStreamRelease(STM32_DMA1_STREAM5); - RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN; + rccDisableSPI2(FALSE); } #endif #if STM32_SPI_USE_SPI3 if (&SPID3 == spip) { dmaStreamRelease(STM32_DMA1_STREAM1); dmaStreamRelease(STM32_DMA1_STREAM2); - RCC->APB1ENR &= ~RCC_APB1ENR_SPI3EN; + rccDisableSPI3(FALSE); } #endif } diff --git a/os/hal/platforms/STM32/uart_lld.c b/os/hal/platforms/STM32/uart_lld.c index a9303744d..3841be8fa 100644 --- a/os/hal/platforms/STM32/uart_lld.c +++ b/os/hal/platforms/STM32/uart_lld.c @@ -362,7 +362,7 @@ void uart_lld_start(UARTDriver *uartp) { (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); chDbgAssert(!b, "uart_lld_start(), #2", "stream already allocated"); - RCC->APB2ENR |= RCC_APB2ENR_USART1EN; + rccEnableUSART1(FALSE); NVICEnableVector(USART1_IRQn, CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY)); } @@ -381,7 +381,7 @@ void uart_lld_start(UARTDriver *uartp) { (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); chDbgAssert(!b, "uart_lld_start(), #4", "stream already allocated"); - RCC->APB1ENR |= RCC_APB1ENR_USART2EN; + rccEnableUSART2(FALSE); NVICEnableVector(USART2_IRQn, CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); } @@ -400,7 +400,7 @@ void uart_lld_start(UARTDriver *uartp) { (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); chDbgAssert(!b, "uart_lld_start(), #6", "stream already allocated"); - RCC->APB1ENR |= RCC_APB1ENR_USART3EN; + rccEnableUSART3(FALSE); NVICEnableVector(USART3_IRQn, CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY)); } @@ -438,7 +438,7 @@ void uart_lld_stop(UARTDriver *uartp) { dmaStreamRelease(STM32_DMA1_STREAM4); dmaStreamRelease(STM32_DMA1_STREAM5); NVICDisableVector(USART1_IRQn); - RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN; + rccDisableUSART1(FALSE); return; } #endif @@ -448,7 +448,7 @@ void uart_lld_stop(UARTDriver *uartp) { dmaStreamRelease(STM32_DMA1_STREAM6); dmaStreamRelease(STM32_DMA1_STREAM7); NVICDisableVector(USART2_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN; + rccDisableUSART2(FALSE); return; } #endif @@ -458,7 +458,7 @@ void uart_lld_stop(UARTDriver *uartp) { dmaStreamRelease(STM32_DMA1_STREAM2); dmaStreamRelease(STM32_DMA1_STREAM3); NVICDisableVector(USART3_IRQn); - RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN; + rccDisableUSART3(FALSE); return; } #endif diff --git a/os/hal/platforms/STM32F1xx/adc_lld.c b/os/hal/platforms/STM32F1xx/adc_lld.c index cc4d25ea1..ac74251f8 100644 --- a/os/hal/platforms/STM32F1xx/adc_lld.c +++ b/os/hal/platforms/STM32F1xx/adc_lld.c @@ -100,7 +100,7 @@ void adc_lld_init(void) { STM32_DMA_CR_TEIE | STM32_DMA_CR_EN; /* Temporary activation.*/ - RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; + rccEnableADC1(FALSE); ADC1->CR1 = 0; ADC1->CR2 = ADC_CR2_ADON; @@ -116,7 +116,7 @@ void adc_lld_init(void) { /* Return the ADC in low power mode.*/ ADC1->CR2 = 0; - RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN; + rccDisableADC1(FALSE); #endif } @@ -140,7 +140,7 @@ void adc_lld_start(ADCDriver *adcp) { (void *)adcp); chDbgAssert(!b, "adc_lld_start(), #1", "stream already allocated"); dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR); - RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; + rccEnableADC1(FALSE); } #endif @@ -167,7 +167,7 @@ void adc_lld_stop(ADCDriver *adcp) { ADC1->CR1 = 0; ADC1->CR2 = 0; dmaStreamRelease(adcp->dmastp); - RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN; + rccDisableADC1(FALSE); } #endif } diff --git a/os/hal/platforms/STM32F1xx/hal_lld.c b/os/hal/platforms/STM32F1xx/hal_lld.c index ba13544f4..6b5cc1459 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld.c +++ b/os/hal/platforms/STM32F1xx/hal_lld.c @@ -59,10 +59,8 @@ void hal_lld_init(void) { /* Reset of all peripherals.*/ - RCC->APB1RSTR = 0xFFFFFFFF; - RCC->APB2RSTR = 0xFFFFFFFF; - RCC->APB1RSTR = 0; - RCC->APB2RSTR = 0; + rccResetAPB1(0xFFFFFFFF); + rccResetAPB2(0xFFFFFFFF); /* SysTick initialization using the system clock.*/ SysTick->LOAD = STM32_HCLK / CH_FREQUENCY - 1; diff --git a/os/hal/platforms/STM32F1xx/hal_lld.h b/os/hal/platforms/STM32F1xx/hal_lld.h index 77c954e9a..659fd3fb1 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld.h +++ b/os/hal/platforms/STM32F1xx/hal_lld.h @@ -578,8 +578,9 @@ #define FALSE 0 #define TRUE (!FALSE) -/* STM32 DMA support code.*/ +/* STM32 DMA and RCC helpers.*/ #include "stm32_dma.h" +#include "stm32_rcc.h" #ifdef __cplusplus extern "C" { diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index 97cfde0b7..e650be5d7 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -787,8 +787,9 @@ /* External declarations. */ /*===========================================================================*/ -/* STM32 DMA support code.*/ +/* STM32 DMA and RCC helpers.*/ #include "stm32_dma.h" +#include "stm32_rcc.h" #ifdef __cplusplus extern "C" { -- cgit v1.2.3 From 06d3e6325be3061cc281b3aa49fcb983998fc4cb Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 16 Sep 2011 17:56:55 +0000 Subject: STM32 RCC helper driver implemented. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3321 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/stm32_rcc.h | 864 +++++++++++++++++++++++++++++++++ os/hal/platforms/STM32L1xx/hal_lld.c | 7 +- os/hal/platforms/STM32L1xx/stm32_rcc.h | 552 +++++++++++++++++++++ 3 files changed, 1419 insertions(+), 4 deletions(-) create mode 100644 os/hal/platforms/STM32F1xx/stm32_rcc.h create mode 100644 os/hal/platforms/STM32L1xx/stm32_rcc.h (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/stm32_rcc.h b/os/hal/platforms/STM32F1xx/stm32_rcc.h new file mode 100644 index 000000000..56fa0905c --- /dev/null +++ b/os/hal/platforms/STM32F1xx/stm32_rcc.h @@ -0,0 +1,864 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32F1xx/stm32_rcc.h + * @brief RCC helper driver header. + * @note This file requires definitions from the ST header file + * @p stm32f10x.h. + * + * @addtogroup STM32_RCC + * @{ + */ + +#ifndef _STM32_RCC_ +#define _STM32_RCC_ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @name Generic RCC operations + * @{ + */ +/** + * @brief Enables the clock of one or more peripheral on the APB1 bus. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] mask APB1 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableAPB1(mask, lp) { \ + RCC->APB1ENR |= (mask); \ +} + +/** + * @brief Disables the clock of one or more peripheral on the APB1 bus. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] mask APB1 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableAPB1(mask, lp) { \ + RCC->APB1ENR &= ~(mask); \ +} + +/** + * @brief Resets one or more peripheral on the APB1 bus. + * + * @param[in] mask APB1 peripherals mask + * + * @api + */ +#define rccResetAPB1(mask) { \ + RCC->APB1RSTR |= (mask); \ + RCC->APB1RSTR = 0; \ +} + +/** + * @brief Enables the clock of one or more peripheral on the APB2 bus. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] mask APB2 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableAPB2(mask, lp) { \ + RCC->APB2ENR |= (mask); \ +} + +/** + * @brief Disables the clock of one or more peripheral on the APB2 bus. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] mask APB2 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableAPB2(mask, lp) { \ + RCC->APB2ENR &= ~(mask); \ +} + +/** + * @brief Resets one or more peripheral on the APB2 bus. + * + * @param[in] mask APB2 peripherals mask + * + * @api + */ +#define rccResetAPB2(mask) { \ + RCC->APB2RSTR |= (mask); \ + RCC->APB2RSTR = 0; \ +} + +/** + * @brief Enables the clock of one or more peripheral on the AHB bus. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] mask AHB peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableAHB(mask, lp) { \ + RCC->AHBENR |= (mask); \ +} + +/** + * @brief Disables the clock of one or more peripheral on the AHB bus. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] mask AHB peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableAHB(mask, lp) { \ + RCC->AHBENR &= ~(mask); \ +} + +/** + * @brief Resets one or more peripheral on the AHB bus. + * + * @param[in] mask AHB peripherals mask + * + * @api + */ +#define rccResetAHB(mask) { \ + RCC->AHBRSTR |= (mask); \ + RCC->AHBRSTR = 0; \ +} +/** @} */ + +/** + * @brief ADC peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the ADC1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableADC1(lp) rccEnableAPB2(RCC_APB2ENR_ADC1EN, lp) + +/** + * @brief Disables the ADC1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableADC1(lp) rccDisableAPB2(RCC_APB2ENR_ADC1EN, lp) + +/** + * @brief Resets the ADC1 peripheral. + * + * @api + */ +#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST) +/** @} */ + +/** + * @brief CAN peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the CAN1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableCAN1(lp) rccEnableAPB1(RCC_APB1ENR_CAN1EN, lp) + +/** + * @brief Disables the CAN1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableCAN1(lp) rccDisableAPB1(RCC_APB1ENR_CAN1EN, lp) + +/** + * @brief Resets the CAN1 peripheral. + * + * @api + */ +#define rccResetCAN1() rccResetAPB1(RCC_APB1RSTR_CAN1RST) +/** @} */ + +/** + * @brief DMA peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the DMA1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableDMA1(lp) rccEnableAHB(RCC_AHBENR_DMA1EN, lp) + +/** + * @brief Disables the DMA1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableDMA1(lp) rccDisableAHB(RCC_AHBENR_DMA1EN, lp) + +/** + * @brief Resets the DMA1 peripheral. + * @note Not supported in this family, does nothing. + * + * @api + */ +#define rccResetDMA1() + +/** + * @brief Enables the DMA2 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableDMA2(lp) rccEnableAHB(RCC_AHBENR_DMA2EN, lp) + +/** + * @brief Disables the DMA2 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableDMA2(lp) rccDisableAHB(RCC_AHBENR_DMA2EN, lp) + +/** + * @brief Resets the DMA1 peripheral. + * @note Not supported in this family, does nothing. + * + * @api + */ +#define rccResetDMA2() +/** @} */ + +/** + * @brief ETH peripheral specific RCC operations + * @{ + */ +/** + * @brief Enables the ETH peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableETH(lp) rccEnableAHB(RCC_AHBENR_ETHMACEN | \ + RCC_AHBENR_ETHMACTXEN | \ + RCC_AHBENR_ETHMACRXEN, lp) + +/** + * @brief Disables the ETH peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableETH(lp) rccDisableAHB(RCC_AHBENR_ETHMACEN | \ + RCC_AHBENR_ETHMACTXEN | \ + RCC_AHBENR_ETHMACRXEN, lp) + +/** + * @brief Resets the ETH peripheral. + * + * @api + */ +#define rccResetETH() rccResetAHB(RCC_AHBRSTR_ETHMACRST) +/** @} */ + +/** + * @brief I2c peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the I2C1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableI2C1(lp) rccEnableAPB1(RCC_APB1ENR_I2C1EN, lp) + +/** + * @brief Disables the I2C1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableI2C1(lp) rccDisableAPB1(RCC_APB1ENR_I2C1EN, lp) + +/** + * @brief Resets the I2C1 peripheral. + * + * @api + */ +#define rccResetI2C1() rccResetAPB1(RCC_APB1RSTR_I2C1RST) + +/** + * @brief Enables the I2C2 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableI2C2(lp) rccEnableAPB1(RCC_APB1ENR_I2C2EN, lp) + +/** + * @brief Disables the I2C2 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableI2C2(lp) rccDisableAPB1(RCC_APB1ENR_I2C2EN, lp) + +/** + * @brief Resets the I2C2 peripheral. + * + * @api + */ +#define rccResetI2C2() rccResetAPB1(RCC_APB1RSTR_I2C2RST) +/** @} */ + +/** + * @brief SDIO peripheral specific RCC operations + * @{ + */ +/** + * @brief Enables the SDIO peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableSDIO(lp) rccEnableAHB(RCC_AHBENR_SDIOEN, lp) + +/** + * @brief Disables the SDIO peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableSDIO(lp) rccDisableAHB(RCC_AHBENR_SDIOEN, lp) + +/** + * @brief Resets the SDIO peripheral. + * @note Not supported in this family, does nothing. + * + * @api + */ +#define rccResetSDIO() +/** @} */ + +/** + * @brief SPI peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the SPI1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableSPI1(lp) rccEnableAPB2(RCC_APB2ENR_SPI1EN, lp) + +/** + * @brief Disables the SPI1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableSPI1(lp) rccDisableAPB2(RCC_APB2ENR_SPI1EN, lp) + +/** + * @brief Resets the SPI1 peripheral. + * + * @api + */ +#define rccResetSPI1() rccResetAPB2(RCC_APB2RSTR_SPI1RST) + +/** + * @brief Enables the SPI2 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableSPI2(lp) rccEnableAPB1(RCC_APB1ENR_SPI2EN, lp) + +/** + * @brief Disables the SPI2 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableSPI2(lp) rccDisableAPB1(RCC_APB1ENR_SPI2EN, lp) + +/** + * @brief Resets the SPI2 peripheral. + * + * @api + */ +#define rccResetSPI2() rccResetAPB1(RCC_APB1RSTR_SPI2RST) + +/** + * @brief Enables the SPI3 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableSPI3(lp) rccEnableAPB1(RCC_APB1ENR_SPI3EN, lp) + +/** + * @brief Disables the SPI3 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableSPI3(lp) rccDisableAPB1(RCC_APB1ENR_SPI3EN, lp) + +/** + * @brief Resets the SPI3 peripheral. + * + * @api + */ +#define rccResetSPI3() rccResetAPB1(RCC_APB1RSTR_SPI3RST) +/** @} */ + +/** + * @brief TIM peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the TIM1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM1(lp) rccEnableAPB2(RCC_APB2ENR_TIM1EN, lp) + +/** + * @brief Disables the TIM1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableTIM1(lp) rccDisableAPB2(RCC_APB2ENR_TIM1EN, lp) + +/** + * @brief Resets the TIM1 peripheral. + * + * @api + */ +#define rccResetTIM1() rccResetAPB2(RCC_APB2RSTR_TIM1RST) + +/** + * @brief Enables the TIM2 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM2(lp) rccEnableAPB1(RCC_APB1ENR_TIM2EN, lp) + +/** + * @brief Disables the TIM2 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableTIM2(lp) rccDisableAPB1(RCC_APB1ENR_TIM2EN, lp) + +/** + * @brief Resets the TIM2 peripheral. + * + * @api + */ +#define rccResetTIM2() rccResetAPB1(RCC_APB1RSTR_TIM2RST) + +/** + * @brief Enables the TIM3 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM3(lp) rccEnableAPB1(RCC_APB1ENR_TIM3EN, lp) + +/** + * @brief Disables the TIM3 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableTIM3(lp) rccDisableAPB1(RCC_APB1ENR_TIM3EN, lp) + +/** + * @brief Resets the TIM3 peripheral. + * + * @api + */ +#define rccResetTIM3() rccResetAPB1(RCC_APB1RSTR_TIM3RST) + +/** + * @brief Enables the TIM4 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM4(lp) rccEnableAPB1(RCC_APB1ENR_TIM4EN, lp) + +/** + * @brief Disables the TIM4 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableTIM4(lp) rccDisableAPB1(RCC_APB1ENR_TIM4EN, lp) + +/** + * @brief Resets the TIM4 peripheral. + * + * @api + */ +#define rccResetTIM4() rccResetAPB1(RCC_APB1RSTR_TIM4RST) + +/** + * @brief Enables the TIM5 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM5(lp) rccEnableAPB1(RCC_APB1ENR_TIM5EN, lp) + +/** + * @brief Disables the TIM5 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableTIM5(lp) rccDisableAPB1(RCC_APB1ENR_TIM5EN, lp) + +/** + * @brief Resets the TIM5 peripheral. + * + * @api + */ +#define rccResetTIM5() rccResetAPB1(RCC_APB1RSTR_TIM5RST) + +/** + * @brief Enables the TIM8 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM8(lp) rccEnableAPB2(RCC_APB2ENR_TIM8EN, lp) + +/** + * @brief Disables the TIM8 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableTIM8(lp) rccDisableAPB2(RCC_APB2ENR_TIM8EN, lp) + +/** + * @brief Resets the TIM8 peripheral. + * + * @api + */ +#define rccResetTIM8() rccResetAPB2(RCC_APB2RSTR_TIM8RST) +/** @} */ + +/** + * @brief USART/UART peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the USART1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUSART1(lp) rccEnableAPB2(RCC_APB2ENR_USART1EN, lp) + +/** + * @brief Disables the USART1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUSART1(lp) rccDisableAPB2(RCC_APB2ENR_USART1EN, lp) + +/** + * @brief Resets the USART1 peripheral. + * + * @api + */ +#define rccResetUSART1() rccResetAPB2(RCC_APB2RSTR_USART1RST) + +/** + * @brief Enables the USART2 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUSART2(lp) rccEnableAPB1(RCC_APB1ENR_USART2EN, lp) + +/** + * @brief Disables the USART2 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUSART2(lp) rccDisableAPB1(RCC_APB1ENR_USART2EN, lp) + +/** + * @brief Resets the USART2 peripheral. + * + * @api + */ +#define rccResetUSART2() rccResetAPB1(RCC_APB1RSTR_USART2RST) + +/** + * @brief Enables the USART3 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUSART3(lp) rccEnableAPB1(RCC_APB1ENR_USART3EN, lp) + +/** + * @brief Disables the USART3 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUSART3(lp) rccDisableAPB1(RCC_APB1ENR_USART3EN, lp) + +/** + * @brief Resets the USART3 peripheral. + * + * @api + */ +#define rccResetUSART3() rccResetAPB1(RCC_APB1RSTR_USART3RST) + +/** + * @brief Enables the UART4 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUART4(lp) rccEnableAPB1(RCC_APB1ENR_UART4EN, lp) + +/** + * @brief Disables the UART4 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUART4(lp) rccDisableAPB1(RCC_APB1ENR_UART4EN, lp) + +/** + * @brief Resets the UART4 peripheral. + * + * @api + */ +#define rccResetUART4() rccResetAPB1(RCC_APB1RSTR_UART4RST) + +/** + * @brief Enables the UART5 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUART5(lp) rccEnableAPB1(RCC_APB1ENR_UART5EN, lp) + +/** + * @brief Disables the UART5 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUART5(lp) rccDisableAPB1(RCC_APB1ENR_UART5EN, lp) + +/** + * @brief Resets the UART5 peripheral. + * + * @api + */ +#define rccResetUART5() rccResetAPB1(RCC_APB1RSTR_UART5RST) +/** @} */ + +/** + * @brief USB peripheral specific RCC operations + * @{ + */ +/** + * @brief Enables the USB peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUSB(lp) rccEnableAPB1(RCC_APB1ENR_USBEN, lp) + +/** + * @brief Disables the USB peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUSB(lp) rccDisableAPB1(RCC_APB1ENR_USBEN, lp) + +/** + * @brief Resets the USB peripheral. + * + * @api + */ +#define rccResetUSB() rccResetAPB1(RCC_APB1RSTR_USBRST) +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif + +#endif /* _STM32_RCC_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32L1xx/hal_lld.c b/os/hal/platforms/STM32L1xx/hal_lld.c index 9a8265365..c59aa3f1c 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.c +++ b/os/hal/platforms/STM32L1xx/hal_lld.c @@ -59,10 +59,9 @@ void hal_lld_init(void) { /* Reset of all peripherals.*/ -// RCC->APB1RSTR = 0xFFFFFFFF; -// RCC->APB2RSTR = 0xFFFFFFFF; -// RCC->APB1RSTR = 0; -// RCC->APB2RSTR = 0; + rccResetAHB(!RCC_AHBRSTR_FLITFRST); + rccResetAPB1(!0); + rccResetAPB2(!RCC_APB2RSTR_SYSCFGRST); /* SysTick initialization using the system clock.*/ SysTick->LOAD = STM32_HCLK / CH_FREQUENCY - 1; diff --git a/os/hal/platforms/STM32L1xx/stm32_rcc.h b/os/hal/platforms/STM32L1xx/stm32_rcc.h new file mode 100644 index 000000000..abad4f96b --- /dev/null +++ b/os/hal/platforms/STM32L1xx/stm32_rcc.h @@ -0,0 +1,552 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32L1xx/stm32_rcc.h + * @brief RCC helper driver header. + * @note This file requires definitions from the ST header file + * @p stm32l1xx.h. + * + * @addtogroup STM32_RCC + * @{ + */ + +#ifndef _STM32_RCC_ +#define _STM32_RCC_ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @name Generic RCC operations + * @{ + */ +/** + * @brief Enables the clock of one or more peripheral on the APB1 bus. + * + * @param[in] mask APB1 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableAPB1(mask, lp) { \ + RCC->APB1ENR |= (mask); \ + if (lp) \ + RCC->APB1LPENR |= (mask); \ +} + +/** + * @brief Disables the clock of one or more peripheral on the APB1 bus. + * + * @param[in] mask APB1 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableAPB1(mask, lp) { \ + RCC->APB1ENR &= ~(mask); \ + if (lp) \ + RCC->APB1LPENR &= ~(mask); \ +} + +/** + * @brief Resets one or more peripheral on the APB1 bus. + * + * @param[in] mask APB1 peripherals mask + * + * @api + */ +#define rccResetAPB1(mask) { \ + RCC->APB1RSTR |= (mask); \ + RCC->APB1RSTR = 0; \ +} + +/** + * @brief Enables the clock of one or more peripheral on the APB2 bus. + * + * @param[in] mask APB2 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableAPB2(mask, lp) { \ + RCC->APB2ENR |= (mask); \ + if (lp) \ + RCC->APB2LPENR |= (mask); \ +} + +/** + * @brief Disables the clock of one or more peripheral on the APB2 bus. + * + * @param[in] mask APB2 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableAPB2(mask, lp) { \ + RCC->APB2ENR &= ~(mask); \ + if (lp) \ + RCC->APB2LPENR &= ~(mask); \ +} + +/** + * @brief Resets one or more peripheral on the APB2 bus. + * + * @param[in] mask APB2 peripherals mask + * + * @api + */ +#define rccResetAPB2(mask) { \ + RCC->APB2RSTR |= (mask); \ + RCC->APB2RSTR = 0; \ +} + +/** + * @brief Enables the clock of one or more peripheral on the AHB bus. + * + * @param[in] mask AHB peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableAHB(mask, lp) { \ + RCC->AHBENR |= (mask); \ + if (lp) \ + RCC->AHBLPENR |= (mask); \ +} + +/** + * @brief Disables the clock of one or more peripheral on the AHB bus. + * + * @param[in] mask AHB peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableAHB(mask, lp) { \ + RCC->AHBENR &= ~(mask); \ + if (lp) \ + RCC->AHBLPENR &= ~(mask); \ +} + +/** + * @brief Resets one or more peripheral on the AHB bus. + * + * @param[in] mask AHB peripherals mask + * + * @api + */ +#define rccResetAHB(mask) { \ + RCC->AHBRSTR |= (mask); \ + RCC->AHBRSTR = 0; \ +} +/** @} */ + +/** + * @brief ADC peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the ADC1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableADC1(lp) rccEnableAPB2(RCC_APB2ENR_ADC1EN, lp) + +/** + * @brief Disables the ADC1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableADC1(lp) rccDisableAPB2(RCC_APB2ENR_ADC1EN, lp) + +/** + * @brief Resets the ADC1 peripheral. + * + * @api + */ +#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST) +/** @} */ + +/** + * @brief DMA peripheral specific RCC operations + * @{ + */ +/** + * @brief Enables the DMA1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableDMA1(lp) rccEnableAHB(RCC_AHBENR_DMA1EN, lp) + +/** + * @brief Disables the DMA1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableDMA1(lp) rccDisableAHB(RCC_AHBENR_DMA1EN, lp) + +/** + * @brief Resets the DMA1 peripheral. + * + * @api + */ +#define rccResetDMA1() rccResetAHB(RCC_AHBRSTR_DMA1RST) +/** @} */ + +/** + * @brief I2c peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the I2C1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableI2C1(lp) rccEnableAPB1(RCC_APB1ENR_I2C1EN, lp) + +/** + * @brief Disables the I2C1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableI2C1(lp) rccDisableAPB1(RCC_APB1ENR_I2C1EN, lp) + +/** + * @brief Resets the I2C1 peripheral. + * + * @api + */ +#define rccResetI2C1() rccResetAPB1(RCC_APB1RSTR_I2C1RST) + +/** + * @brief Enables the I2C2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableI2C2(lp) rccEnableAPB1(RCC_APB1ENR_I2C2EN, lp) + +/** + * @brief Disables the I2C2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableI2C2(lp) rccDisableAPB1(RCC_APB1ENR_I2C2EN, lp) + +/** + * @brief Resets the I2C2 peripheral. + * + * @api + */ +#define rccResetI2C2() rccResetAPB1(RCC_APB1RSTR_I2C2RST) +/** @} */ + +/** + * @brief SPI peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the SPI1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableSPI1(lp) rccEnableAPB2(RCC_APB2ENR_SPI1EN, lp) + +/** + * @brief Disables the SPI1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableSPI1(lp) rccDisableAPB2(RCC_APB2ENR_SPI1EN, lp) + +/** + * @brief Resets the SPI1 peripheral. + * + * @api + */ +#define rccResetSPI1() rccResetAPB2(RCC_APB2RSTR_SPI1RST) + +/** + * @brief Enables the SPI2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableSPI2(lp) rccEnableAPB1(RCC_APB1ENR_SPI2EN, lp) + +/** + * @brief Disables the SPI2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableSPI2(lp) rccDisableAPB1(RCC_APB1ENR_SPI2EN, lp) + +/** + * @brief Resets the SPI2 peripheral. + * + * @api + */ +#define rccResetSPI2() rccResetAPB1(RCC_APB1RSTR_SPI2RST) +/** @} */ + +/** + * @brief TIM peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the TIM2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM2(lp) rccEnableAPB1(RCC_APB1ENR_TIM2EN, lp) + +/** + * @brief Disables the TIM2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableTIM2(lp) rccDisableAPB1(RCC_APB1ENR_TIM2EN, lp) + +/** + * @brief Resets the TIM2 peripheral. + * + * @api + */ +#define rccResetTIM2() rccResetAPB1(RCC_APB1RSTR_TIM2RST) + +/** + * @brief Enables the TIM3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM3(lp) rccEnableAPB1(RCC_APB1ENR_TIM3EN, lp) + +/** + * @brief Disables the TIM3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableTIM3(lp) rccDisableAPB1(RCC_APB1ENR_TIM3EN, lp) + +/** + * @brief Resets the TIM3 peripheral. + * + * @api + */ +#define rccResetTIM3() rccResetAPB1(RCC_APB1RSTR_TIM3RST) + +/** + * @brief Enables the TIM4 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM4(lp) rccEnableAPB1(RCC_APB1ENR_TIM4EN, lp) + +/** + * @brief Disables the TIM4 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableTIM4(lp) rccDisableAPB1(RCC_APB1ENR_TIM4EN, lp) + +/** + * @brief Resets the TIM4 peripheral. + * + * @api + */ +#define rccResetTIM4() rccResetAPB1(RCC_APB1RSTR_TIM4RST) +/** @} */ + +/** + * @brief USART/UART peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the USART1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUSART1(lp) rccEnableAPB2(RCC_APB2ENR_USART1EN, lp) + +/** + * @brief Disables the USART1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUSART1(lp) rccDisableAPB2(RCC_APB2ENR_USART1EN, lp) + +/** + * @brief Resets the USART1 peripheral. + * + * @api + */ +#define rccResetUSART1() rccResetAPB2(RCC_APB2RSTR_USART1RST) + +/** + * @brief Enables the USART2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUSART2(lp) rccEnableAPB1(RCC_APB1ENR_USART2EN, lp) + +/** + * @brief Disables the USART2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUSART2(lp) rccDisableAPB1(RCC_APB1ENR_USART2EN, lp) + +/** + * @brief Resets the USART2 peripheral. + * + * @api + */ +#define rccResetUSART2() rccResetAPB1(RCC_APB1RSTR_USART2RST) + +/** + * @brief Enables the USART3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUSART3(lp) rccEnableAPB1(RCC_APB1ENR_USART3EN, lp) + +/** + * @brief Disables the USART3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUSART3(lp) rccDisableAPB1(RCC_APB1ENR_USART3EN, lp) + +/** + * @brief Resets the USART3 peripheral. + * + * @api + */ +#define rccResetUSART3() rccResetAPB1(RCC_APB1RSTR_USART3RST) +/** @} */ + +/** + * @brief USB peripheral specific RCC operations + * @{ + */ +/** + * @brief Enables the USB peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUSB(lp) rccEnableAPB1(RCC_APB1ENR_USBEN, lp) + +/** + * @brief Disables the USB peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUSB(lp) rccDisableAPB1(RCC_APB1ENR_USBEN, lp) + +/** + * @brief Resets the USB peripheral. + * + * @api + */ +#define rccResetUSB() rccResetAPB1(RCC_APB1RSTR_USBRST) +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif + +#endif /* _STM32_RCC_ */ + +/** @} */ -- cgit v1.2.3 From 4ff96215eddade6e541f1a97af5364e754ccee7c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 17 Sep 2011 08:45:43 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3323 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/GPIOv2/pal_lld.h | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/GPIOv2/pal_lld.h b/os/hal/platforms/STM32/GPIOv2/pal_lld.h index 0f9f22441..aa8dc2d73 100644 --- a/os/hal/platforms/STM32/GPIOv2/pal_lld.h +++ b/os/hal/platforms/STM32/GPIOv2/pal_lld.h @@ -95,6 +95,32 @@ #define PAL_MODE_INPUT_PULLDOWN (PAL_STM32_MODE_INPUT | \ PAL_STM32_PUDR_PULLDOWN) +/** + * @brief Alternate input high-Z pad. + * + * @param[in] n alternate function selector + */ +#define PAL_MODE_ALT_INPUT(n) (PAL_STM32_MODE_INPUT | \ + PAL_STM32_ALTERNATE(n)) + +/** + * @brief Alternate input pad with weak pull up resistor. + * + * @param[in] n alternate function selector + */ +#define PAL_MODE_ALT_INPUT_PULLUP(n) (PAL_STM32_MODE_INPUT | \ + PAL_STM32_PUDR_PULLUP | \ + PAL_STM32_ALTERNATE(n)) + +/** + * @brief Alternate input pad with weak pull down resistor. + * + * @param[in] n alternate function selector + */ +#define PAL_MODE_ALT_INPUT_PULLDOWN(n) (PAL_STM32_MODE_INPUT | \ + PAL_STM32_PUDR_PULLDOWN | \ + PAL_STM32_ALTERNATE(n)) + /** * @brief Analog input mode. */ @@ -117,7 +143,7 @@ * * @param[in] n alternate function selector */ -#define PAL_MODE_ALTERNATE_PUSHPULL(n) (PAL_STM32_MODE_ALTERNATE | \ +#define PAL_MODE_ALT_OUTPUT_PUSHPULL(n) (PAL_STM32_MODE_ALTERNATE | \ PAL_STM32_OTYPE_PUSHPULL | \ PAL_STM32_ALTERNATE(n)) @@ -126,7 +152,7 @@ * * @param[in] n alternate function selector */ -#define PAL_MODE_ALTERNATE_OPENDRAIN(n) (PAL_STM32_MODE_ALTERNATE | \ +#define PAL_MODE_ALT_OUTPUT_OPENDRAIN(n) (PAL_STM32_MODE_ALTERNATE | \ PAL_STM32_OTYPE_OPENDRAIN | \ PAL_STM32_ALTERNATE(n)) -- cgit v1.2.3 From 93bea8080848c1526d302b577390e197ce030081 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 17 Sep 2011 09:06:19 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3324 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32L1xx/hal_lld.h | 51 ++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index e650be5d7..2815febb1 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -195,6 +195,57 @@ #define STM32_HAS_USB TRUE #define STM32_HAS_OTG1 FALSE +/** + * @name Platform specific friendly IRQ names + */ +#define WWDG_IRQHandler Vector40 /**< Window Watchdog. */ +#define PVD_IRQHandler Vector44 /**< PVD through EXTI Line + detect. */ +#define TAMPER_IRQHandler Vector48 /**< Tamper. */ +#define RTC_IRQHandler Vector4C /**< RTC. */ +#define FLASH_IRQHandler Vector50 /**< Flash. */ +#define RCC_IRQHandler Vector54 /**< RCC. */ +#define EXTI0_IRQHandler Vector58 /**< EXTI Line 0. */ +#define EXTI1_IRQHandler Vector5C /**< EXTI Line 1. */ +#define EXTI2_IRQHandler Vector60 /**< EXTI Line 2. */ +#define EXTI3_IRQHandler Vector64 /**< EXTI Line 3. */ +#define EXTI4_IRQHandler Vector68 /**< EXTI Line 4. */ +#define DMA1_Ch1_IRQHandler Vector6C /**< DMA1 Channel 1. */ +#define DMA1_Ch2_IRQHandler Vector70 /**< DMA1 Channel 2. */ +#define DMA1_Ch3_IRQHandler Vector74 /**< DMA1 Channel 3. */ +#define DMA1_Ch4_IRQHandler Vector78 /**< DMA1 Channel 4. */ +#define DMA1_Ch5_IRQHandler Vector7C /**< DMA1 Channel 5. */ +#define DMA1_Ch6_IRQHandler Vector80 /**< DMA1 Channel 6. */ +#define DMA1_Ch7_IRQHandler Vector84 /**< DMA1 Channel 7. */ +#define ADC1_IRQHandler Vector88 /**< ADC1. */ +#define USB_HP_IRQHandler Vector8C /**< USB High Priority. */ +#define USB_LP_IRQHandler Vector90 /**< USB Low Priority. */ +#define DAC_IRQHandler Vector94 /**< DAC. */ +#define COMP_IRQHandler Vector98 /**< COMP. */ +#define EXTI9_5_IRQHandler Vector9C /**< EXTI Line 9..5. */ +#define TIM9_IRQHandler VectorA0 /**< TIM9. */ +#define TIM10_IRQHandler VectorA4 /**< TIM10. */ +#define TIM11_IRQHandler VectorA8 /**< TIM11. */ +#define LCD_IRQHandler VectorAC /**< LCD. */ +#define TIM2_IRQHandler VectorB0 /**< TIM2. */ +#define TIM3_IRQHandler VectorB4 /**< TIM3. */ +#define TIM4_IRQHandler VectorB8 /**< TIM4. */ +#define I2C1_EV_IRQHandler VectorBC /**< I2C1 Event. */ +#define I2C1_ER_IRQHandler VectorC0 /**< I2C1 Error. */ +#define I2C2_EV_IRQHandler VectorC4 /**< I2C2 Event. */ +#define I2C2_ER_IRQHandler VectorC8 /**< I2C2 Error. */ +#define SPI1_IRQHandler VectorCC /**< SPI1. */ +#define SPI2_IRQHandler VectorD0 /**< SPI2. */ +#define USART1_IRQHandler VectorD4 /**< USART1. */ +#define USART2_IRQHandler VectorD8 /**< USART2. */ +#define USART3_IRQHandler VectorDC /**< USART3. */ +#define EXTI15_10_IRQHandler VectorE0 /**< EXTI Line 15..10. */ +#define RTCAlarm_IRQHandler VectorE4 /**< RTC Alarm through EXTI. */ +#define USBWakeUp_IRQHandler VectorE8 /**< USB Wakeup from suspend. */ +#define TIM6_IRQHandler VectorEC /**< TIM6. */ +#define TIM7_IRQHandler VectorF0 /**< TIM7. */ +/** @} */ + /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ -- cgit v1.2.3 From 17ab902203a60ac1c70aebf41facc0f278babfd5 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 17 Sep 2011 09:16:10 +0000 Subject: STM32L152 report added. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3325 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32L1xx/platform.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32L1xx/platform.mk b/os/hal/platforms/STM32L1xx/platform.mk index 348722671..e51234323 100644 --- a/os/hal/platforms/STM32L1xx/platform.mk +++ b/os/hal/platforms/STM32L1xx/platform.mk @@ -1,12 +1,12 @@ # List of all the STM32L1xx platform files. PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32L1xx/hal_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/gpt_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/icu_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/pwm_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/serial_lld.c \ - ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c \ - ${CHIBIOS}/os/hal/platforms/STM32/DMAv1/spi_lld.c \ - ${CHIBIOS}/os/hal/platforms/STM32/DMAv1/uart_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/uart_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/DMAv1/stm32_dma.c \ ${CHIBIOS}/os/hal/platforms/STM32/USBv1/usb_lld.c -- cgit v1.2.3 From f90db59d00378a4999389b75cb66a38db2eb9aa1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 17 Sep 2011 11:34:23 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3326 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/GPIOv2/pal_lld.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/GPIOv2/pal_lld.h b/os/hal/platforms/STM32/GPIOv2/pal_lld.h index aa8dc2d73..4c82141e3 100644 --- a/os/hal/platforms/STM32/GPIOv2/pal_lld.h +++ b/os/hal/platforms/STM32/GPIOv2/pal_lld.h @@ -55,10 +55,10 @@ #define PAL_STM32_OTYPE_OPENDRAIN (1 << 2) #define PAL_STM32_OSPEED_MASK (3 << 3) -#define PAL_STM32_OSPEED_400K (0 << 3) -#define PAL_STM32_OSPEED_2M (1 << 3) -#define PAL_STM32_OSPEED_10M (2 << 3) -#define PAL_STM32_OSPEED_40M (3 << 3) +#define PAL_STM32_OSPEED_LOWEST (0 << 3) +#define PAL_STM32_OSPEED_MID1 (1 << 3) +#define PAL_STM32_OSPEED_MID2 (2 << 3) +#define PAL_STM32_OSPEED_HIGHEST (3 << 3) #define PAL_STM32_PUDR_MASK (3 << 5) #define PAL_STM32_PUDR_FLOATING (0 << 5) -- cgit v1.2.3 From baabff16e61179d497fe986d63e325e83272d4ed Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 17 Sep 2011 16:56:44 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3329 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/stm32_dma.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.h b/os/hal/platforms/STM32/DMAv1/stm32_dma.h index 473bbe851..ca9c429f7 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.h @@ -63,11 +63,11 @@ #define STM32_DMA1_STREAM5 (&_stm32_dma_streams[4]) #define STM32_DMA1_STREAM6 (&_stm32_dma_streams[5]) #define STM32_DMA1_STREAM7 (&_stm32_dma_streams[6]) -#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[8]) -#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[9]) -#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[10]) -#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[11]) -#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[12]) +#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[7]) +#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[8]) +#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[9]) +#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[10]) +#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[11]) /** @} */ /** -- cgit v1.2.3 From 278fc39f993660a8d7ebf4df4a89f6beb10c7f7b Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 17 Sep 2011 17:53:57 +0000 Subject: UART driver tested with STM32L. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3330 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/GPIOv2/pal_lld.h | 40 ++------------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/GPIOv2/pal_lld.h b/os/hal/platforms/STM32/GPIOv2/pal_lld.h index 4c82141e3..6c799c14c 100644 --- a/os/hal/platforms/STM32/GPIOv2/pal_lld.h +++ b/os/hal/platforms/STM32/GPIOv2/pal_lld.h @@ -95,32 +95,6 @@ #define PAL_MODE_INPUT_PULLDOWN (PAL_STM32_MODE_INPUT | \ PAL_STM32_PUDR_PULLDOWN) -/** - * @brief Alternate input high-Z pad. - * - * @param[in] n alternate function selector - */ -#define PAL_MODE_ALT_INPUT(n) (PAL_STM32_MODE_INPUT | \ - PAL_STM32_ALTERNATE(n)) - -/** - * @brief Alternate input pad with weak pull up resistor. - * - * @param[in] n alternate function selector - */ -#define PAL_MODE_ALT_INPUT_PULLUP(n) (PAL_STM32_MODE_INPUT | \ - PAL_STM32_PUDR_PULLUP | \ - PAL_STM32_ALTERNATE(n)) - -/** - * @brief Alternate input pad with weak pull down resistor. - * - * @param[in] n alternate function selector - */ -#define PAL_MODE_ALT_INPUT_PULLDOWN(n) (PAL_STM32_MODE_INPUT | \ - PAL_STM32_PUDR_PULLDOWN | \ - PAL_STM32_ALTERNATE(n)) - /** * @brief Analog input mode. */ @@ -139,21 +113,11 @@ PAL_STM32_OTYPE_OPENDRAIN) /** - * @brief Alternate push-pull output. - * - * @param[in] n alternate function selector - */ -#define PAL_MODE_ALT_OUTPUT_PUSHPULL(n) (PAL_STM32_MODE_ALTERNATE | \ - PAL_STM32_OTYPE_PUSHPULL | \ - PAL_STM32_ALTERNATE(n)) - -/** - * @brief Alternate push-pull output. + * @brief Alternate function. * * @param[in] n alternate function selector */ -#define PAL_MODE_ALT_OUTPUT_OPENDRAIN(n) (PAL_STM32_MODE_ALTERNATE | \ - PAL_STM32_OTYPE_OPENDRAIN | \ +#define PAL_MODE_ALTERNATE(n) (PAL_STM32_MODE_ALTERNATE | \ PAL_STM32_ALTERNATE(n)) /*===========================================================================*/ -- cgit v1.2.3 From 07f868d3792cadd6377fdb5039c7cbf27f68bd92 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 18 Sep 2011 18:23:50 +0000 Subject: GPT driver tested on STM32L. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3341 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/GPIOv2/pal_lld.h | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/GPIOv2/pal_lld.h b/os/hal/platforms/STM32/GPIOv2/pal_lld.h index 6c799c14c..a73f80c7a 100644 --- a/os/hal/platforms/STM32/GPIOv2/pal_lld.h +++ b/os/hal/platforms/STM32/GPIOv2/pal_lld.h @@ -135,13 +135,7 @@ typedef struct { volatile uint32_t PUPDR; volatile uint32_t IDR; volatile uint32_t ODR; - volatile union { - uint32_t W; - struct { - uint16_t set; - uint16_t clear; - } H; - } BSRR; + volatile uint32_t BSRR; volatile uint32_t LCKR; volatile uint32_t AFRL; volatile uint32_t AFRH; @@ -375,7 +369,7 @@ typedef GPIO_TypeDef * ioportid_t; * * @notapi */ -#define pal_lld_setport(port, bits) ((port)->BSRR.H.set = (uint16_t)(bits)) +#define pal_lld_setport(port, bits) ((port)->BSRR = (uint32_t)(bits)) /** * @brief Clears a bits mask on a I/O port. @@ -392,7 +386,7 @@ typedef GPIO_TypeDef * ioportid_t; * * @notapi */ -#define pal_lld_clearport(port, bits) ((port)->BSRR.H.clear = (uint16_t)(bits)) +#define pal_lld_clearport(port, bits) ((port)->BSRR = (uint32_t)(bits) << 16) /** * @brief Writes a group of bits. @@ -413,8 +407,8 @@ typedef GPIO_TypeDef * ioportid_t; * @notapi */ #define pal_lld_writegroup(port, mask, offset, bits) \ - ((port)->BSRR.W = ((~(bits) & (mask)) << (16 + (offset))) | \ - (((bits) & (mask)) << (offset))) + ((port)->BSRR = ((~(bits) & (mask)) << (16 + (offset))) | \ + (((bits) & (mask)) << (offset))) /** * @brief Pads group mode setup. -- cgit v1.2.3 From e1afd2700be6c631f1e74766525724cf95588c3e Mon Sep 17 00:00:00 2001 From: barthess Date: Sun, 18 Sep 2011 21:08:42 +0000 Subject: Added RCC helper support to RTC driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3342 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/rtc_lld.c | 2 +- os/hal/platforms/STM32F1xx/stm32_rcc.h | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/rtc_lld.c b/os/hal/platforms/STM32/rtc_lld.c index 4f404ab27..62e114e66 100644 --- a/os/hal/platforms/STM32/rtc_lld.c +++ b/os/hal/platforms/STM32/rtc_lld.c @@ -112,7 +112,7 @@ CH_IRQ_HANDLER(RTC_IRQHandler) { * @notapi */ void rtc_lld_init(void){ - RCC->APB1ENR |= (RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN); /* enable clocking */ + rccEnableBKP(FALSE); /* enable interface clocking */ PWR->CR |= PWR_CR_DBP; /* enable access */ if (!(RCC->BDCR & (RCC_BDCR_RTCEN | RCC_BDCR_LSEON))){ /* BKP domain was reseted */ diff --git a/os/hal/platforms/STM32F1xx/stm32_rcc.h b/os/hal/platforms/STM32F1xx/stm32_rcc.h index 56fa0905c..7735b2034 100644 --- a/os/hal/platforms/STM32F1xx/stm32_rcc.h +++ b/os/hal/platforms/STM32F1xx/stm32_rcc.h @@ -202,6 +202,38 @@ #define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST) /** @} */ +/** + * @brief Bakup domain interface specific RCC operations + * @{ + */ +/** + * @brief Enables the BKP interface clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableBKP(lp) rccEnableAPB1(RCC_APB1ENR_BKPEN, lp); + +/** + * @brief Disables BKP interface clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableBKP(lp) rccDisableAPB1(RCC_APB1ENR_BKPEN, lp); + +/** + * @brief Resets the Backup Domain. + * + * @api + */ +#define rccResetBKP(lp) rccResetAPB1(RCC_APB1ENR_BKPRST); +/** @} */ + /** * @brief CAN peripherals specific RCC operations * @{ -- cgit v1.2.3 From c1a1893307e154fa295f2fbf1d873e0471c0fd81 Mon Sep 17 00:00:00 2001 From: barthess Date: Mon, 19 Sep 2011 11:47:12 +0000 Subject: small fix in RCC helper for RTC git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3347 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/stm32_rcc.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/stm32_rcc.h b/os/hal/platforms/STM32F1xx/stm32_rcc.h index 7735b2034..7f215a720 100644 --- a/os/hal/platforms/STM32F1xx/stm32_rcc.h +++ b/os/hal/platforms/STM32F1xx/stm32_rcc.h @@ -214,7 +214,8 @@ * * @api */ -#define rccEnableBKP(lp) rccEnableAPB1(RCC_APB1ENR_BKPEN, lp); +#define rccEnableBKP(lp) \ + rccEnableAPB1((RCC_APB1ENR_BKPEN | RCC_APB1ENR_PWREN), lp); /** * @brief Disables BKP interface clock. @@ -224,7 +225,8 @@ * * @api */ -#define rccDisableBKP(lp) rccDisableAPB1(RCC_APB1ENR_BKPEN, lp); +#define rccDisableBKP(lp) \ + rccDisableAPB1((RCC_APB1ENR_BKPEN | RCC_APB1ENR_PWREN), lp); /** * @brief Resets the Backup Domain. -- cgit v1.2.3 From 22d8fa4450d5563d3ff1134a9f007b73c977ff9a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 19 Sep 2011 12:04:02 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3348 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/GPIOv2/pal_lld.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/GPIOv2/pal_lld.h b/os/hal/platforms/STM32/GPIOv2/pal_lld.h index a73f80c7a..6c799c14c 100644 --- a/os/hal/platforms/STM32/GPIOv2/pal_lld.h +++ b/os/hal/platforms/STM32/GPIOv2/pal_lld.h @@ -135,7 +135,13 @@ typedef struct { volatile uint32_t PUPDR; volatile uint32_t IDR; volatile uint32_t ODR; - volatile uint32_t BSRR; + volatile union { + uint32_t W; + struct { + uint16_t set; + uint16_t clear; + } H; + } BSRR; volatile uint32_t LCKR; volatile uint32_t AFRL; volatile uint32_t AFRH; @@ -369,7 +375,7 @@ typedef GPIO_TypeDef * ioportid_t; * * @notapi */ -#define pal_lld_setport(port, bits) ((port)->BSRR = (uint32_t)(bits)) +#define pal_lld_setport(port, bits) ((port)->BSRR.H.set = (uint16_t)(bits)) /** * @brief Clears a bits mask on a I/O port. @@ -386,7 +392,7 @@ typedef GPIO_TypeDef * ioportid_t; * * @notapi */ -#define pal_lld_clearport(port, bits) ((port)->BSRR = (uint32_t)(bits) << 16) +#define pal_lld_clearport(port, bits) ((port)->BSRR.H.clear = (uint16_t)(bits)) /** * @brief Writes a group of bits. @@ -407,8 +413,8 @@ typedef GPIO_TypeDef * ioportid_t; * @notapi */ #define pal_lld_writegroup(port, mask, offset, bits) \ - ((port)->BSRR = ((~(bits) & (mask)) << (16 + (offset))) | \ - (((bits) & (mask)) << (offset))) + ((port)->BSRR.W = ((~(bits) & (mask)) << (16 + (offset))) | \ + (((bits) & (mask)) << (offset))) /** * @brief Pads group mode setup. -- cgit v1.2.3 From bae85ff69f0037ae22bb9bf1fada5762f7db4292 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 19 Sep 2011 12:54:13 +0000 Subject: Fixed problem in gptPolledDelay(). git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3350 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/src/gpt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'os/hal') diff --git a/os/hal/src/gpt.c b/os/hal/src/gpt.c index c677f5284..726936ca8 100644 --- a/os/hal/src/gpt.c +++ b/os/hal/src/gpt.c @@ -236,6 +236,7 @@ void gptPolledDelay(GPTDriver *gptp, gptcnt_t interval) { gptp->state = GPT_ONESHOT; gpt_lld_polled_delay(gptp, interval); + gptp->state = GPT_READY; } #endif /* HAL_USE_GPT */ -- cgit v1.2.3 From 31a099cb104ea4d7d957bb65bbdc7e8edbdbe636 Mon Sep 17 00:00:00 2001 From: barthess Date: Mon, 19 Sep 2011 13:54:07 +0000 Subject: RTC. Driver improvements git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3352 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/dox/rtc.dox | 9 ++++++++ os/hal/platforms/STM32/rtc_lld.c | 41 ++++++++++++++++++++-------------- os/hal/platforms/STM32F1xx/stm32_rcc.h | 17 +++++++++----- 3 files changed, 45 insertions(+), 22 deletions(-) (limited to 'os/hal') diff --git a/os/hal/dox/rtc.dox b/os/hal/dox/rtc.dox index 3572aca18..dc49c8bb0 100644 --- a/os/hal/dox/rtc.dox +++ b/os/hal/dox/rtc.dox @@ -30,5 +30,14 @@ * @pre In order to use the RTC driver the @p HAL_USE_RTC option * must be enabled in @p halconf.h. * + * @note STM32 Errata notes: + * Description + * When the LSIRDY flag is set, the clock may still be out of the + * specified frequency range (fLSI parameter, see LSI oscillator + * characteristics in the product datasheet). + * Workaround + * To have a fully stabilized clock in the specified range, a + * software temporization of 100 uS should be added. + * * @ingroup IO */ diff --git a/os/hal/platforms/STM32/rtc_lld.c b/os/hal/platforms/STM32/rtc_lld.c index 62e114e66..875dc464c 100644 --- a/os/hal/platforms/STM32/rtc_lld.c +++ b/os/hal/platforms/STM32/rtc_lld.c @@ -112,29 +112,42 @@ CH_IRQ_HANDLER(RTC_IRQHandler) { * @notapi */ void rtc_lld_init(void){ - rccEnableBKP(FALSE); /* enable interface clocking */ - PWR->CR |= PWR_CR_DBP; /* enable access */ + rccEnableBKPInterface(FALSE); - if (!(RCC->BDCR & (RCC_BDCR_RTCEN | RCC_BDCR_LSEON))){ /* BKP domain was reseted */ - RCC->BDCR |= RTC_CLOCK_SOURCE; /* select clocking from LSE */ - RCC->BDCR |= RCC_BDCR_LSEON; /* switch LSE on */ - while(!(RCC->BDCR & RCC_BDCR_LSEON)) /* wait for stabilization */ + /* Ensure that RTC_CNT and RTC_DIV contain actual values after enabling + * clocking on APB1, because these values only update when APB1 functioning.*/ + RTC->CRL &= ~(RTC_CRL_RSF); + while (!(RTC->CRL & RTC_CRL_RSF)) + ; + + /* enable access to BKP registers */ + PWR->CR |= PWR_CR_DBP; + + if (! ((RCC->BDCR & RCC_BDCR_RTCEN) || (RCC->BDCR & RCC_BDCR_LSEON))){ + RCC->BDCR |= RTC_CLOCK_SOURCE; + + /* for LSE source we must wait until source became stable */ + #if defined(RTC_CLOCK_SOURCE) == defined(RCC_BDCR_RTCSEL_LSE) + RCC->BDCR |= RCC_BDCR_LSEON; + while(!(RCC->BDCR & RCC_BDCR_LSERDY)) ; - RCC->BDCR |= RCC_BDCR_RTCEN; /* run clock */ + #endif + + RCC->BDCR |= RCC_BDCR_RTCEN; } #if defined(RTC_CLOCK_SOURCE) == defined(RCC_BDCR_RTCSEL_LSE) - uint32_t preload = STM32_LSECLK - 1UL; + uint32_t preload = STM32_LSECLK - 1; #elif defined(RTC_CLOCK_SOURCE) == defined(RCC_BDCR_RTCSEL_LSI) - uint32_t preload = STM32_LSICLK - 1UL; + uint32_t preload = STM32_LSICLK - 1; #elif defined(RTC_CLOCK_SOURCE) == defined(RCC_BDCR_RTCSEL_HSE) - uint32_t preload = (STM32_HSICLK / 128UL) - 1UL; + uint32_t preload = (STM32_HSICLK / 128) - 1; #else #error "RTC clock source not selected" #endif /* RTC_CLOCK_SOURCE == RCC_BDCR_RTCSEL_LSE */ /* Write preload register only if value changed */ - if (preload != (((uint32_t)(RTC->PRLH)) << 16) + RTC->PRLH){ + if (preload != ((((uint32_t)(RTC->PRLH)) << 16) + RTC->PRLL)){ while(!(RTC->CRL & RTC_CRL_RTOFF)) ; @@ -147,12 +160,6 @@ void rtc_lld_init(void){ ; } - /* Ensure that RTC_CNT and RTC_DIV contain actual values after enabling - * clocking on APB1, because these values only update when APB1 functioning.*/ - RTC->CRL &= ~(RTC_CRL_RSF); - while (!(RTC->CRL & RTC_CRL_RSF)) - ; - /* disable all interrupts and clear all even flags just to be safe */ RTC->CRH &= ~(RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE); RTC->CRL &= ~(RTC_CRL_SECF | RTC_CRL_ALRF | RTC_CRL_OWF); diff --git a/os/hal/platforms/STM32F1xx/stm32_rcc.h b/os/hal/platforms/STM32F1xx/stm32_rcc.h index 7f215a720..9ca1140e9 100644 --- a/os/hal/platforms/STM32F1xx/stm32_rcc.h +++ b/os/hal/platforms/STM32F1xx/stm32_rcc.h @@ -203,7 +203,7 @@ /** @} */ /** - * @brief Bakup domain interface specific RCC operations + * @brief Backup domain interface specific RCC operations * @{ */ /** @@ -214,7 +214,7 @@ * * @api */ -#define rccEnableBKP(lp) \ +#define rccEnableBKPInterface(lp) \ rccEnableAPB1((RCC_APB1ENR_BKPEN | RCC_APB1ENR_PWREN), lp); /** @@ -225,15 +225,22 @@ * * @api */ -#define rccDisableBKP(lp) \ +#define rccDisableBKPInterface(lp) \ rccDisableAPB1((RCC_APB1ENR_BKPEN | RCC_APB1ENR_PWREN), lp); /** - * @brief Resets the Backup Domain. + * @brief Resets the Backup Domain interface. * * @api */ -#define rccResetBKP(lp) rccResetAPB1(RCC_APB1ENR_BKPRST); +#define rccResetBKPInterface() rccResetAPB1(RCC_APB1ENR_BKPRST); + +/** + * @brief Resets the entire Backup Domain. + * + * @api + */ +#define rccResetBKP() (RCC->BDCR |= RCC_BDCR_BDRST); /** @} */ /** -- cgit v1.2.3 From f5c7e2f7cd4e43f272db4e9f053053eea9f92dde Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 19 Sep 2011 14:01:42 +0000 Subject: Fixed an STM32 GPT driver problem. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3353 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/gpt_lld.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/gpt_lld.c b/os/hal/platforms/STM32/gpt_lld.c index 0fd5dde73..af8737f04 100644 --- a/os/hal/platforms/STM32/gpt_lld.c +++ b/os/hal/platforms/STM32/gpt_lld.c @@ -401,6 +401,10 @@ void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) { gptp->tim->ARR = interval - 1; /* Time constant. */ gptp->tim->EGR = 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 because 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 any). */ gptp->tim->DIER = TIM_DIER_UIE; /* Update Event IRQ enabled. */ gptp->tim->CR1 = TIM_CR1_URS | TIM_CR1_CEN; -- cgit v1.2.3 From 353ee572ad1d55e06648e5ff911f421b140baea7 Mon Sep 17 00:00:00 2001 From: barthess Date: Mon, 19 Sep 2011 15:02:02 +0000 Subject: RTC. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3354 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/rtc_lld.c | 52 ++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 20 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/rtc_lld.c b/os/hal/platforms/STM32/rtc_lld.c index 875dc464c..941f2429f 100644 --- a/os/hal/platforms/STM32/rtc_lld.c +++ b/os/hal/platforms/STM32/rtc_lld.c @@ -112,6 +112,8 @@ CH_IRQ_HANDLER(RTC_IRQHandler) { * @notapi */ void rtc_lld_init(void){ + uint32_t preload = 0; + rccEnableBKPInterface(FALSE); /* Ensure that RTC_CNT and RTC_DIV contain actual values after enabling @@ -122,29 +124,39 @@ void rtc_lld_init(void){ /* enable access to BKP registers */ PWR->CR |= PWR_CR_DBP; - - if (! ((RCC->BDCR & RCC_BDCR_RTCEN) || (RCC->BDCR & RCC_BDCR_LSEON))){ - RCC->BDCR |= RTC_CLOCK_SOURCE; - - /* for LSE source we must wait until source became stable */ - #if defined(RTC_CLOCK_SOURCE) == defined(RCC_BDCR_RTCSEL_LSE) - RCC->BDCR |= RCC_BDCR_LSEON; - while(!(RCC->BDCR & RCC_BDCR_LSERDY)) + /* select clock source */ + RCC->BDCR |= RTC_CLOCK_SOURCE; + + chDbgCheck(((RTC_CLOCK_SOURCE == RCC_BDCR_RTCSEL_LSE) &&\ + (RTC_CLOCK_SOURCE == RCC_BDCR_RTCSEL_LSI) &&\ + (RTC_CLOCK_SOURCE == RCC_BDCR_RTCSEL_HSE)), "No clock source selected"); + + if (RTC_CLOCK_SOURCE == RCC_BDCR_RTCSEL_LSE){ + if (! ((RCC->BDCR & RCC_BDCR_RTCEN) || (RCC->BDCR & RCC_BDCR_LSEON))){ + RCC->BDCR |= RCC_BDCR_LSEON; + while(!(RCC->BDCR & RCC_BDCR_LSERDY)) + ; + RCC->BDCR |= RCC_BDCR_RTCEN; + } + preload = STM32_LSECLK - 1; + } + else if (RTC_CLOCK_SOURCE == RCC_BDCR_RTCSEL_LSI){ + RCC->CSR |= RCC_CSR_LSION; + while(!(RCC->CSR & RCC_CSR_LSIRDY)) + ; + /* According to errata notes we must wait additional 100 uS for stabilization */ + uint32_t tmo = (STM32_SYSCLK / 1000000 ) * 100; + while(tmo--) ; - #endif - RCC->BDCR |= RCC_BDCR_RTCEN; + preload = STM32_LSICLK - 1; + } + else if (RTC_CLOCK_SOURCE == RCC_BDCR_RTCSEL_HSE){ + preload = (STM32_HSICLK / 128) - 1; + } + else{ + chDbgPanic("Wrong"); } - - #if defined(RTC_CLOCK_SOURCE) == defined(RCC_BDCR_RTCSEL_LSE) - uint32_t preload = STM32_LSECLK - 1; - #elif defined(RTC_CLOCK_SOURCE) == defined(RCC_BDCR_RTCSEL_LSI) - uint32_t preload = STM32_LSICLK - 1; - #elif defined(RTC_CLOCK_SOURCE) == defined(RCC_BDCR_RTCSEL_HSE) - uint32_t preload = (STM32_HSICLK / 128) - 1; - #else - #error "RTC clock source not selected" - #endif /* RTC_CLOCK_SOURCE == RCC_BDCR_RTCSEL_LSE */ /* Write preload register only if value changed */ if (preload != ((((uint32_t)(RTC->PRLH)) << 16) + RTC->PRLL)){ -- cgit v1.2.3 From da3d1eae7b4035fb916e14ba853a5cf2aa0f70cd Mon Sep 17 00:00:00 2001 From: barthess Date: Tue, 20 Sep 2011 07:02:14 +0000 Subject: RTC. Code reorganization to correspond ChibiOS rules. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3356 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/rtc_lld.c | 43 ++++++++++++-------------- os/hal/platforms/STM32/rtc_lld.h | 8 ----- os/hal/platforms/STM32F1xx/hal_lld_f100.h | 7 +++++ os/hal/platforms/STM32F1xx/hal_lld_f103.h | 11 +++++++ os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h | 7 +++++ 5 files changed, 45 insertions(+), 31 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/rtc_lld.c b/os/hal/platforms/STM32/rtc_lld.c index 941f2429f..465f2f02e 100644 --- a/os/hal/platforms/STM32/rtc_lld.c +++ b/os/hal/platforms/STM32/rtc_lld.c @@ -115,23 +115,14 @@ void rtc_lld_init(void){ uint32_t preload = 0; rccEnableBKPInterface(FALSE); - - /* Ensure that RTC_CNT and RTC_DIV contain actual values after enabling - * clocking on APB1, because these values only update when APB1 functioning.*/ - RTC->CRL &= ~(RTC_CRL_RSF); - while (!(RTC->CRL & RTC_CRL_RSF)) - ; + //RCC->APB1ENR |= (RCC_APB1ENR_BKPEN | RCC_APB1ENR_PWREN); /* enable access to BKP registers */ PWR->CR |= PWR_CR_DBP; /* select clock source */ - RCC->BDCR |= RTC_CLOCK_SOURCE; + RCC->BDCR |= STM32_RTC; - chDbgCheck(((RTC_CLOCK_SOURCE == RCC_BDCR_RTCSEL_LSE) &&\ - (RTC_CLOCK_SOURCE == RCC_BDCR_RTCSEL_LSI) &&\ - (RTC_CLOCK_SOURCE == RCC_BDCR_RTCSEL_HSE)), "No clock source selected"); - - if (RTC_CLOCK_SOURCE == RCC_BDCR_RTCSEL_LSE){ +#if STM32_RTC == STM32_RTC_LSE if (! ((RCC->BDCR & RCC_BDCR_RTCEN) || (RCC->BDCR & RCC_BDCR_LSEON))){ RCC->BDCR |= RCC_BDCR_LSEON; while(!(RCC->BDCR & RCC_BDCR_LSERDY)) @@ -139,26 +130,32 @@ void rtc_lld_init(void){ RCC->BDCR |= RCC_BDCR_RTCEN; } preload = STM32_LSECLK - 1; - } - else if (RTC_CLOCK_SOURCE == RCC_BDCR_RTCSEL_LSI){ + +#elif STM32_RTC == STM32_RTC_LSI RCC->CSR |= RCC_CSR_LSION; while(!(RCC->CSR & RCC_CSR_LSIRDY)) ; - /* According to errata notes we must wait additional 100 uS for stabilization */ + /* According to errata sheet we must wait additional 100 uS for stabilization */ uint32_t tmo = (STM32_SYSCLK / 1000000 ) * 100; while(tmo--) ; RCC->BDCR |= RCC_BDCR_RTCEN; preload = STM32_LSICLK - 1; - } - else if (RTC_CLOCK_SOURCE == RCC_BDCR_RTCSEL_HSE){ + +#elif STM32_RTC == STM32_RTC_HSE preload = (STM32_HSICLK / 128) - 1; - } - else{ - chDbgPanic("Wrong"); - } - /* Write preload register only if value changed */ +#else +#error "RTC clock source not selected" +#endif + + /* Ensure that RTC_CNT and RTC_DIV contain actual values after enabling + * clocking on APB1, because these values only update when APB1 functioning.*/ + RTC->CRL &= ~(RTC_CRL_RSF); + while (!(RTC->CRL & RTC_CRL_RSF)) + ; + + /* Write preload register only if its value changed */ if (preload != ((((uint32_t)(RTC->PRLH)) << 16) + RTC->PRLL)){ while(!(RTC->CRL & RTC_CRL_RTOFF)) ; @@ -174,7 +171,7 @@ void rtc_lld_init(void){ /* disable all interrupts and clear all even flags just to be safe */ RTC->CRH &= ~(RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE); - RTC->CRL &= ~(RTC_CRL_SECF | RTC_CRL_ALRF | RTC_CRL_OWF); + RTC->CRL &= ~(RTC_CRL_SECF | RTC_CRL_ALRF | RTC_CRL_OWF); #if RTC_SUPPORTS_CALLBACKS RTCD.alarm_cb = NULL; diff --git a/os/hal/platforms/STM32/rtc_lld.h b/os/hal/platforms/STM32/rtc_lld.h index c2c6f676b..7d7d703f0 100644 --- a/os/hal/platforms/STM32/rtc_lld.h +++ b/os/hal/platforms/STM32/rtc_lld.h @@ -47,14 +47,6 @@ #define RTC_SUPPORTS_CALLBACKS TRUE #endif -/** - * @brief Clock source selecting. LSE by default. - */ -#if !defined(RTC_CLOCK_SOURCE) || defined(__DOXYGEN__) -#define RTC_CLOCK_SOURCE RCC_BDCR_RTCSEL_LSE -#endif - - /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f100.h b/os/hal/platforms/STM32F1xx/hal_lld_f100.h index aad199528..60e42ece4 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f100.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f100.h @@ -228,6 +228,13 @@ #define STM32_MCO STM32_MCO_NOCLOCK #endif +/** + * @brief Clock source selecting. LSI by default. + */ +#if !defined(STM32_RTC) || defined(__DOXYGEN__) +#define STM32_RTC STM32_RTC_LSI +#endif + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f103.h b/os/hal/platforms/STM32F1xx/hal_lld_f103.h index 4421663a0..f14ab5dc4 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f103.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f103.h @@ -90,6 +90,11 @@ #define STM32_MCO_HSE (6 << 24) /**< HSE clock on MCO pin. */ #define STM32_MCO_PLLDIV2 (7 << 24) /**< PLL/2 clock on MCO pin. */ +#define STM32_RTC_NOCLOCK (0 << 8) /**< No clock */ +#define STM32_RTC_LSE (1 << 8) /**< LSE used as RTC clock */ +#define STM32_RTC_LSI (2 << 8) /**< LSI used as RTC clock */ +#define STM32_RTC_HSE (3 << 8) /**< HSE divided by 128 used as RTC clock */ + /*===========================================================================*/ /* Platform specific friendly IRQ names. */ /*===========================================================================*/ @@ -251,6 +256,12 @@ #define STM32_MCO STM32_MCO_NOCLOCK #endif +/** + * @brief Clock source selecting. LSI by default. + */ +#if !defined(STM32_RTC) || defined(__DOXYGEN__) +#define STM32_RTC STM32_RTC_LSI +#endif /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h index 27a840ba8..52c124d2d 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h @@ -317,6 +317,13 @@ #define STM32_MCO STM32_MCO_NOCLOCK #endif +/** + * @brief Clock source selecting. LSI by default. + */ +#if !defined(STM32_RTC) || defined(__DOXYGEN__) +#define STM32_RTC STM32_RTC_LSI +#endif + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ -- cgit v1.2.3 From 3035afea9de7fbf89c5c3852abeaf47780df4613 Mon Sep 17 00:00:00 2001 From: barthess Date: Tue, 20 Sep 2011 07:18:29 +0000 Subject: RTC. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3357 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/hal_lld_f100.h | 5 +++++ os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f100.h b/os/hal/platforms/STM32F1xx/hal_lld_f100.h index 60e42ece4..5cabd9788 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f100.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f100.h @@ -87,6 +87,11 @@ #define STM32_MCO_HSE (6 << 24) /**< HSE clock on MCO pin. */ #define STM32_MCO_PLLDIV2 (7 << 24) /**< PLL/2 clock on MCO pin. */ +#define STM32_RTC_NOCLOCK (0 << 8) /**< No clock */ +#define STM32_RTC_LSE (1 << 8) /**< LSE used as RTC clock */ +#define STM32_RTC_LSI (2 << 8) /**< LSI used as RTC clock */ +#define STM32_RTC_HSE (3 << 8) /**< HSE divided by 128 used as RTC clock */ + /*===========================================================================*/ /* Platform specific friendly IRQ names. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h index 52c124d2d..caed49aca 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h @@ -92,6 +92,11 @@ #define STM32_MCO_XT1 (10 << 24) /**< XT1 clock on MCO pin. */ #define STM32_MCO_PLL3 (11 << 24) /**< PLL3 clock on MCO pin. */ +#define STM32_RTC_NOCLOCK (0 << 8) /**< No clock */ +#define STM32_RTC_LSE (1 << 8) /**< LSE used as RTC clock */ +#define STM32_RTC_LSI (2 << 8) /**< LSI used as RTC clock */ +#define STM32_RTC_HSE (3 << 8) /**< HSE divided by 128 used as RTC clock */ + /* RCC_CFGR2 register bits definitions.*/ #define STM32_PREDIV1SRC_HSE (0 << 16) /**< PREDIV1 source is HSE. */ #define STM32_PREDIV1SRC_PLL2 (1 << 16) /**< PREDIV1 source is PLL2. */ -- cgit v1.2.3 From 0886cac0499a65b3fd1d410fd0f29b7cbcd4b1ba Mon Sep 17 00:00:00 2001 From: barthess Date: Tue, 20 Sep 2011 08:37:12 +0000 Subject: RTC. Removed errata note from rtc.dox because workaround realized in driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3359 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/dox/rtc.dox | 9 --------- 1 file changed, 9 deletions(-) (limited to 'os/hal') diff --git a/os/hal/dox/rtc.dox b/os/hal/dox/rtc.dox index dc49c8bb0..b538f3a4a 100644 --- a/os/hal/dox/rtc.dox +++ b/os/hal/dox/rtc.dox @@ -29,15 +29,6 @@ * * @pre In order to use the RTC driver the @p HAL_USE_RTC option * must be enabled in @p halconf.h. - * - * @note STM32 Errata notes: - * Description - * When the LSIRDY flag is set, the clock may still be out of the - * specified frequency range (fLSI parameter, see LSI oscillator - * characteristics in the product datasheet). - * Workaround - * To have a fully stabilized clock in the specified range, a - * software temporization of 100 uS should be added. * * @ingroup IO */ -- cgit v1.2.3 From 01596d8b5e9399d2c4b3e3551cdd3396b4c787bc Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 20 Sep 2011 17:33:38 +0000 Subject: Fixed bug 3411774. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3367 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/hal_lld.h | 35 ++++++++++++++++++++----- os/hal/platforms/STM32F1xx/hal_lld_f100.h | 13 +++++----- os/hal/platforms/STM32F1xx/hal_lld_f103.h | 13 +++++----- os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h | 11 ++++---- os/hal/platforms/STM32F1xx/stm32f10x.h | 36 +++++++++++++++++--------- os/hal/platforms/STM32F2xx/hal_lld.h | 17 +++++++----- os/hal/platforms/STM32L1xx/hal_lld.h | 17 +++++++----- os/hal/platforms/STM32L1xx/platform.mk | 1 + 8 files changed, 94 insertions(+), 49 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/hal_lld.h b/os/hal/platforms/STM32F1xx/hal_lld.h index 659fd3fb1..da9e610fd 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld.h +++ b/os/hal/platforms/STM32F1xx/hal_lld.h @@ -82,6 +82,8 @@ #define STM32_HAS_ETH FALSE +#define STM32_EXTI_NUM_CHANNELS 19 + #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -123,8 +125,9 @@ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 FALSE -#define STM32_HAS_UART3 FALSE #define STM32_HAS_UART4 FALSE +#define STM32_HAS_UART5 FALSE +#define STM32_HAS_USART6 FALSE #define STM32_HAS_USB FALSE #define STM32_HAS_OTG1 FALSE @@ -150,6 +153,8 @@ #define STM32_HAS_ETH FALSE +#define STM32_EXTI_NUM_CHANNELS 19 + #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -191,8 +196,9 @@ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 TRUE -#define STM32_HAS_UART3 FALSE #define STM32_HAS_UART4 FALSE +#define STM32_HAS_UART5 FALSE +#define STM32_HAS_USART6 FALSE #define STM32_HAS_USB FALSE #define STM32_HAS_OTG1 FALSE @@ -218,6 +224,8 @@ #define STM32_HAS_ETH FALSE +#define STM32_EXTI_NUM_CHANNELS 19 + #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -259,8 +267,9 @@ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 FALSE -#define STM32_HAS_UART3 FALSE #define STM32_HAS_UART4 FALSE +#define STM32_HAS_UART5 FALSE +#define STM32_HAS_USART6 FALSE #define STM32_HAS_USB FALSE #define STM32_HAS_OTG1 FALSE @@ -286,6 +295,8 @@ #define STM32_HAS_ETH FALSE +#define STM32_EXTI_NUM_CHANNELS 19 + #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -327,8 +338,9 @@ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 TRUE -#define STM32_HAS_UART3 FALSE #define STM32_HAS_UART4 FALSE +#define STM32_HAS_UART5 FALSE +#define STM32_HAS_USART6 FALSE #define STM32_HAS_USB TRUE #define STM32_HAS_OTG1 FALSE @@ -354,6 +366,8 @@ #define STM32_HAS_ETH FALSE +#define STM32_EXTI_NUM_CHANNELS 19 + #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -395,8 +409,9 @@ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 TRUE -#define STM32_HAS_UART3 TRUE #define STM32_HAS_UART4 TRUE +#define STM32_HAS_UART5 TRUE +#define STM32_HAS_USART6 FALSE #define STM32_HAS_USB TRUE #define STM32_HAS_OTG1 FALSE @@ -422,6 +437,8 @@ #define STM32_HAS_ETH FALSE +#define STM32_EXTI_NUM_CHANNELS 19 + #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -463,8 +480,9 @@ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 TRUE -#define STM32_HAS_UART3 TRUE #define STM32_HAS_UART4 TRUE +#define STM32_HAS_UART5 TRUE +#define STM32_HAS_USART6 FALSE #define STM32_HAS_USB TRUE #define STM32_HAS_OTG1 FALSE @@ -490,6 +508,8 @@ #define STM32_HAS_ETH TRUE +#define STM32_EXTI_NUM_CHANNELS 20 + #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -531,8 +551,9 @@ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 TRUE -#define STM32_HAS_UART3 TRUE #define STM32_HAS_UART4 TRUE +#define STM32_HAS_UART5 TRUE +#define STM32_HAS_USART6 FALSE #define STM32_HAS_USB FALSE #define STM32_HAS_OTG1 TRUE diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f100.h b/os/hal/platforms/STM32F1xx/hal_lld_f100.h index 5cabd9788..51cdf97e3 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f100.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f100.h @@ -87,10 +87,11 @@ #define STM32_MCO_HSE (6 << 24) /**< HSE clock on MCO pin. */ #define STM32_MCO_PLLDIV2 (7 << 24) /**< PLL/2 clock on MCO pin. */ -#define STM32_RTC_NOCLOCK (0 << 8) /**< No clock */ -#define STM32_RTC_LSE (1 << 8) /**< LSE used as RTC clock */ -#define STM32_RTC_LSI (2 << 8) /**< LSI used as RTC clock */ -#define STM32_RTC_HSE (3 << 8) /**< HSE divided by 128 used as RTC clock */ +#define STM32_RTC_NOCLOCK (0 << 8) /**< No clock. */ +#define STM32_RTC_LSE (1 << 8) /**< LSE used as RTC clock. */ +#define STM32_RTC_LSI (2 << 8) /**< LSI used as RTC clock. */ +#define STM32_RTC_HSE (3 << 8) /**< HSE divided by 128 used as + RTC clock. */ /*===========================================================================*/ /* Platform specific friendly IRQ names. */ @@ -143,8 +144,8 @@ #define USART3_IRQHandler VectorDC /**< USART3. */ #endif #define EXTI15_10_IRQHandler VectorE0 /**< EXTI Line 15..10. */ -#define RTCAlarm_IRQHandler VectorE4 /**< RTC Alarm through EXTI. */ -#define CEC_IRQHandler VectorE8 /**< CEC. */ +#define RTC_Alarm_IRQHandler VectorE4 /**< RTC Alarm through EXTI. */ +#define CEC_IRQHandler VectorE8 /**< CEC. */ #define TIM12_IRQHandler VectorEC /**< TIM12. */ #define TIM13_IRQHandler VectorF0 /**< TIM13. */ #define TIM14_IRQHandler VectorF4 /**< TIM14. */ diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f103.h b/os/hal/platforms/STM32F1xx/hal_lld_f103.h index f14ab5dc4..9ba74d239 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f103.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f103.h @@ -90,10 +90,11 @@ #define STM32_MCO_HSE (6 << 24) /**< HSE clock on MCO pin. */ #define STM32_MCO_PLLDIV2 (7 << 24) /**< PLL/2 clock on MCO pin. */ -#define STM32_RTC_NOCLOCK (0 << 8) /**< No clock */ -#define STM32_RTC_LSE (1 << 8) /**< LSE used as RTC clock */ -#define STM32_RTC_LSI (2 << 8) /**< LSI used as RTC clock */ -#define STM32_RTC_HSE (3 << 8) /**< HSE divided by 128 used as RTC clock */ +#define STM32_RTC_NOCLOCK (0 << 8) /**< No clock. */ +#define STM32_RTC_LSE (1 << 8) /**< LSE used as RTC clock. */ +#define STM32_RTC_LSI (2 << 8) /**< LSI used as RTC clock. */ +#define STM32_RTC_HSE (3 << 8) /**< HSE divided by 128 used as + RTC clock. */ /*===========================================================================*/ /* Platform specific friendly IRQ names. */ @@ -144,8 +145,8 @@ #define USART2_IRQHandler VectorD8 /**< USART2. */ #define USART3_IRQHandler VectorDC /**< USART3. */ #define EXTI15_10_IRQHandler VectorE0 /**< EXTI Line 15..10. */ -#define RTCAlarm_IRQHandler VectorE4 /**< RTC Alarm through EXTI. */ -#define USBWakeUp_IRQHandler VectorE8 /**< USB Wakeup from suspend. */ +#define RTC_Alarm_IRQHandler VectorE4 /**< RTC Alarm through EXTI. */ +#define USB_FS_WKUP_IRQHandler VectorE8 /**< USB Wakeup from suspend. */ #define TIM8_BRK_IRQHandler VectorEC /**< TIM8 Break. */ #define TIM8_UP_IRQHandler VectorF0 /**< TIM8 Update. */ #define TIM8_TRG_COM_IRQHandler VectorF4 /**< TIM8 Trigger and diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h index caed49aca..974b59f34 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h @@ -92,10 +92,11 @@ #define STM32_MCO_XT1 (10 << 24) /**< XT1 clock on MCO pin. */ #define STM32_MCO_PLL3 (11 << 24) /**< PLL3 clock on MCO pin. */ -#define STM32_RTC_NOCLOCK (0 << 8) /**< No clock */ -#define STM32_RTC_LSE (1 << 8) /**< LSE used as RTC clock */ -#define STM32_RTC_LSI (2 << 8) /**< LSI used as RTC clock */ -#define STM32_RTC_HSE (3 << 8) /**< HSE divided by 128 used as RTC clock */ +#define STM32_RTC_NOCLOCK (0 << 8) /**< No clock. */ +#define STM32_RTC_LSE (1 << 8) /**< LSE used as RTC clock. */ +#define STM32_RTC_LSI (2 << 8) /**< LSI used as RTC clock. */ +#define STM32_RTC_HSE (3 << 8) /**< HSE divided by 128 used as + RTC clock. */ /* RCC_CFGR2 register bits definitions.*/ #define STM32_PREDIV1SRC_HSE (0 << 16) /**< PREDIV1 source is HSE. */ @@ -148,7 +149,7 @@ #define USART2_IRQHandler VectorD8 /**< USART2. */ #define USART3_IRQHandler VectorDC /**< USART3. */ #define EXTI15_10_IRQHandler VectorE0 /**< EXTI Line 15..10. */ -#define RTCAlarm_IRQHandler VectorE4 /**< RTC alarm through EXTI +#define RTC_Alarm_IRQHandler VectorE4 /**< RTC alarm through EXTI line. */ #define OTG_FS_WKUP_IRQHandler VectorE8 /**< USB OTG FS Wakeup through EXTI line. */ diff --git a/os/hal/platforms/STM32F1xx/stm32f10x.h b/os/hal/platforms/STM32F1xx/stm32f10x.h index c7f447d18..6697b9648 100644 --- a/os/hal/platforms/STM32F1xx/stm32f10x.h +++ b/os/hal/platforms/STM32F1xx/stm32f10x.h @@ -217,8 +217,10 @@ typedef enum IRQn USART1_IRQn = 37, /*!< USART1 global Interrupt */ USART2_IRQn = 38, /*!< USART2 global Interrupt */ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ - USBWakeUp_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ + /* CHIBIOS FIX (making it compatible with STM32L and STM32F2 headers).*/ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + /* CHIBIOS FIX (making it compatible with STM32L and STM32F2 headers).*/ + USB_FS_WKUP_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ #endif /* STM32F10X_LD */ #ifdef STM32F10X_LD_VL @@ -236,7 +238,8 @@ typedef enum IRQn USART1_IRQn = 37, /*!< USART1 global Interrupt */ USART2_IRQn = 38, /*!< USART2 global Interrupt */ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + /* CHIBIOS FIX (making it compatible with STM32L and STM32F2 headers).*/ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */ TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */ TIM7_IRQn = 55 /*!< TIM7 Interrupt */ @@ -266,8 +269,10 @@ typedef enum IRQn USART2_IRQn = 38, /*!< USART2 global Interrupt */ USART3_IRQn = 39, /*!< USART3 global Interrupt */ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ - USBWakeUp_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ + /* CHIBIOS FIX (making it compatible with STM32L and STM32F2 headers).*/ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + /* CHIBIOS FIX (making it compatible with STM32L and STM32F2 headers).*/ + USB_FS_WKUP_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ #endif /* STM32F10X_MD */ #ifdef STM32F10X_MD_VL @@ -290,7 +295,8 @@ typedef enum IRQn USART2_IRQn = 38, /*!< USART2 global Interrupt */ USART3_IRQn = 39, /*!< USART3 global Interrupt */ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + /* CHIBIOS FIX (making it compatible with STM32L and STM32F2 headers).*/ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */ TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */ TIM7_IRQn = 55 /*!< TIM7 Interrupt */ @@ -320,8 +326,10 @@ typedef enum IRQn USART2_IRQn = 38, /*!< USART2 global Interrupt */ USART3_IRQn = 39, /*!< USART3 global Interrupt */ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ - USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ + /* CHIBIOS FIX (making it compatible with STM32L and STM32F2 headers).*/ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + /* CHIBIOS FIX (making it compatible with STM32L and STM32F2 headers).*/ + USB_FS_WKUP_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ TIM8_BRK_IRQn = 43, /*!< TIM8 Break Interrupt */ TIM8_UP_IRQn = 44, /*!< TIM8 Update Interrupt */ TIM8_TRG_COM_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt */ @@ -361,7 +369,8 @@ typedef enum IRQn USART2_IRQn = 38, /*!< USART2 global Interrupt */ USART3_IRQn = 39, /*!< USART3 global Interrupt */ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + /* CHIBIOS FIX (making it compatible with STM32L and STM32F2 headers).*/ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */ TIM12_IRQn = 43, /*!< TIM12 global Interrupt */ TIM13_IRQn = 44, /*!< TIM13 global Interrupt */ @@ -405,8 +414,10 @@ typedef enum IRQn USART2_IRQn = 38, /*!< USART2 global Interrupt */ USART3_IRQn = 39, /*!< USART3 global Interrupt */ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ - USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ + /* CHIBIOS FIX (making it compatible with STM32L and STM32F2 headers).*/ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + /* CHIBIOS FIX (making it compatible with STM32L and STM32F2 headers).*/ + USB_FS_WKUP_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global Interrupt */ TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global Interrupt */ TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */ @@ -450,7 +461,8 @@ typedef enum IRQn USART2_IRQn = 38, /*!< USART2 global Interrupt */ USART3_IRQn = 39, /*!< USART3 global Interrupt */ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + /* CHIBIOS FIX (making it compatible with STM32L and STM32F2 headers).*/ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS WakeUp from suspend through EXTI Line Interrupt */ TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ diff --git a/os/hal/platforms/STM32F2xx/hal_lld.h b/os/hal/platforms/STM32F2xx/hal_lld.h index 764f58529..91135950f 100644 --- a/os/hal/platforms/STM32F2xx/hal_lld.h +++ b/os/hal/platforms/STM32F2xx/hal_lld.h @@ -133,7 +133,7 @@ /* STM32F2xx capabilities.*/ #define STM32_HAS_ADC1 TRUE #define STM32_HAS_ADC2 TRUE -#define STM32_HAS_ADC3 FALSE +#define STM32_HAS_ADC3 TRUE #define STM32_HAS_CAN1 TRUE #define STM32_HAS_CAN2 TRUE @@ -145,6 +145,8 @@ #define STM32_HAS_ETH TRUE +#define STM32_EXTI_NUM_CHANNELS 23 + #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -171,8 +173,8 @@ #define STM32_HAS_TIM3 TRUE #define STM32_HAS_TIM4 TRUE #define STM32_HAS_TIM5 TRUE -#define STM32_HAS_TIM6 TRUE -#define STM32_HAS_TIM7 TRUE +#define STM32_HAS_TIM6 FALSE +#define STM32_HAS_TIM7 FALSE #define STM32_HAS_TIM8 TRUE #define STM32_HAS_TIM9 TRUE #define STM32_HAS_TIM10 TRUE @@ -187,10 +189,11 @@ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 TRUE -#define STM32_HAS_UART3 FALSE -#define STM32_HAS_UART4 FALSE +#define STM32_HAS_UART4 TRUE +#define STM32_HAS_UART5 TRUE +#define STM32_HAS_USART6 TRUE -#define STM32_HAS_USB TRUE +#define STM32_HAS_USB FALSE #define STM32_HAS_OTG1 TRUE /*===========================================================================*/ @@ -240,7 +243,7 @@ #define USART2_IRQHandler VectorD8 /**< USART2. */ #define USART3_IRQHandler VectorDC /**< USART3. */ #define EXTI15_10_IRQHandler VectorE0 /**< EXTI Line 15..10. */ -#define RTCAlarm_IRQHandler VectorE4 /**< RTC alarm through EXTI +#define RTC_Alarm_IRQHandler VectorE4 /**< RTC alarm through EXTI line. */ #define OTG_FS_WKUP_IRQHandler VectorE8 /**< USB OTG FS Wakeup through EXTI line. */ diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index 2815febb1..2c3d05138 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -148,6 +148,8 @@ #define STM32_HAS_ETH FALSE +#define STM32_EXTI_NUM_CHANNELS 23 + #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -189,8 +191,9 @@ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 TRUE -#define STM32_HAS_UART3 FALSE #define STM32_HAS_UART4 FALSE +#define STM32_HAS_UART5 FALSE +#define STM32_HAS_USART6 FALSE #define STM32_HAS_USB TRUE #define STM32_HAS_OTG1 FALSE @@ -201,8 +204,10 @@ #define WWDG_IRQHandler Vector40 /**< Window Watchdog. */ #define PVD_IRQHandler Vector44 /**< PVD through EXTI Line detect. */ -#define TAMPER_IRQHandler Vector48 /**< Tamper. */ -#define RTC_IRQHandler Vector4C /**< RTC. */ +#define TAMPER_STAMP_IRQHandler Vector48 /**< Tamper and Time Stamp + through EXTI. */ +#define RTC_WKUP_IRQHandler Vector4C /**< RTC Wakeup Timer through + EXTI. */ #define FLASH_IRQHandler Vector50 /**< Flash. */ #define RCC_IRQHandler Vector54 /**< RCC. */ #define EXTI0_IRQHandler Vector58 /**< EXTI Line 0. */ @@ -221,7 +226,7 @@ #define USB_HP_IRQHandler Vector8C /**< USB High Priority. */ #define USB_LP_IRQHandler Vector90 /**< USB Low Priority. */ #define DAC_IRQHandler Vector94 /**< DAC. */ -#define COMP_IRQHandler Vector98 /**< COMP. */ +#define COMP_IRQHandler Vector98 /**< Comparator through EXTI. */ #define EXTI9_5_IRQHandler Vector9C /**< EXTI Line 9..5. */ #define TIM9_IRQHandler VectorA0 /**< TIM9. */ #define TIM10_IRQHandler VectorA4 /**< TIM10. */ @@ -240,8 +245,8 @@ #define USART2_IRQHandler VectorD8 /**< USART2. */ #define USART3_IRQHandler VectorDC /**< USART3. */ #define EXTI15_10_IRQHandler VectorE0 /**< EXTI Line 15..10. */ -#define RTCAlarm_IRQHandler VectorE4 /**< RTC Alarm through EXTI. */ -#define USBWakeUp_IRQHandler VectorE8 /**< USB Wakeup from suspend. */ +#define RTC_Alarm_IRQHandler VectorE4 /**< RTC Alarm through EXTI. */ +#define USB_FS_WKUP_IRQHandler VectorE8 /**< USB Wakeup from suspend. */ #define TIM6_IRQHandler VectorEC /**< TIM6. */ #define TIM7_IRQHandler VectorF0 /**< TIM7. */ /** @} */ diff --git a/os/hal/platforms/STM32L1xx/platform.mk b/os/hal/platforms/STM32L1xx/platform.mk index e51234323..047864a79 100644 --- a/os/hal/platforms/STM32L1xx/platform.mk +++ b/os/hal/platforms/STM32L1xx/platform.mk @@ -1,6 +1,7 @@ # List of all the STM32L1xx platform files. PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32L1xx/hal_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/ext_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/gpt_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/icu_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/pwm_lld.c \ -- cgit v1.2.3 From 450a8fe0c86102a685fa8accde3a9a0aa8a05ae7 Mon Sep 17 00:00:00 2001 From: barthess Date: Tue, 20 Sep 2011 19:35:20 +0000 Subject: EXT lld driver. Fixed according to new naming conventions in stm32f10x.h git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3372 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/ext_lld.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/ext_lld.c b/os/hal/platforms/STM32/ext_lld.c index 712ed5a39..ee00fb592 100644 --- a/os/hal/platforms/STM32/ext_lld.c +++ b/os/hal/platforms/STM32/ext_lld.c @@ -310,10 +310,10 @@ void ext_lld_start(EXTDriver *extp) { CORTEX_PRIORITY_MASK(STM32_EXT_EXTI10_15_IRQ_PRIORITY)); NVICEnableVector(PVD_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI16_IRQ_PRIORITY)); - NVICEnableVector(RTCAlarm_IRQn, + NVICEnableVector(RTC_Alarm_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI17_IRQ_PRIORITY)); #if STM32_HAS_USB - NVICEnableVector(USBWakeUp_IRQn, + NVICEnableVector(USB_FS_WKUP_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI18_IRQ_PRIORITY)); #endif #if STM32_HAS_OTG1 @@ -369,9 +369,9 @@ void ext_lld_stop(EXTDriver *extp) { NVICDisableVector(EXTI9_5_IRQn); NVICDisableVector(EXTI15_10_IRQn); NVICDisableVector(PVD_IRQn); - NVICDisableVector(RTCAlarm_IRQn); + NVICDisableVector(RTC_Alarm_IRQn ); #if STM32_HAS_USB - NVICDisableVector(USBWakeUp_IRQn); + NVICDisableVector(USB_FS_WKUP_IRQn); #endif #if STM32_HAS_OTG1 NVICDisableVector(OTG_FS_WKUP_IRQn); -- cgit v1.2.3 From f90273557f060f07b87c1c9e3765f74491910533 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 20 Sep 2011 19:44:18 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3373 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/ext_lld.c | 226 +++++++++++++++++++++++++++++++++++---- os/hal/platforms/STM32/ext_lld.h | 44 ++++---- 2 files changed, 229 insertions(+), 41 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/ext_lld.c b/os/hal/platforms/STM32/ext_lld.c index ee00fb592..13eca6f3b 100644 --- a/os/hal/platforms/STM32/ext_lld.c +++ b/os/hal/platforms/STM32/ext_lld.c @@ -141,7 +141,7 @@ CH_IRQ_HANDLER(EXTI9_5_IRQHandler) { CH_IRQ_PROLOGUE(); - pr = EXTI->PR; + pr = EXTI->PR & ((1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9)); EXTI->PR = pr; if (pr & (1 << 5)) EXTD1.config->channels[5].cb(&EXTD1, 5); @@ -167,7 +167,8 @@ CH_IRQ_HANDLER(EXTI15_10_IRQHandler) { CH_IRQ_PROLOGUE(); - pr = EXTI->PR; + pr = EXTI->PR & ((1 << 10) | (1 << 11) | (1 << 12) | (1 << 13) | (1 << 14) | + (1 << 15)); EXTI->PR = pr; if (pr & (1 << 10)) EXTD1.config->channels[10].cb(&EXTD1, 10); @@ -215,13 +216,13 @@ CH_IRQ_HANDLER(RTCAlarm_IRQHandler) { CH_IRQ_EPILOGUE(); } -#if STM32_HAS_USB || defined(__DOXYGEN__) +#if defined(STM32L1XX_MD) /** - * @brief EXTI[18] interrupt handler (USB). + * @brief EXTI[18] interrupt handler (USB_FS_WKUP). * * @isr */ -CH_IRQ_HANDLER(USBWakeUp_IRQHandler) { +CH_IRQ_HANDLER(USB_FS_WKUP_IRQHandler) { CH_IRQ_PROLOGUE(); @@ -230,11 +231,136 @@ CH_IRQ_HANDLER(USBWakeUp_IRQHandler) { CH_IRQ_EPILOGUE(); } -#endif /* STM32_HAS_USB */ -#if STM32_HAS_OTG1 || defined(__DOXYGEN__) /** - * @brief EXTI[18] interrupt handler (OTG1). + * @brief EXTI[19] interrupt handler (TAMPER_STAMP). + * + * @isr + */ +CH_IRQ_HANDLER(TAMPER_STAMP_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 19); + EXTD1.config->channels[19].cb(&EXTD1, 19); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief EXTI[20] interrupt handler (RTC_WKUP). + * + * @isr + */ +CH_IRQ_HANDLER(RTC_WKUP_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 20); + EXTD1.config->channels[20].cb(&EXTD1, 20); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief EXTI[21]...EXTI[22] interrupt handler (COMP). + * + * @isr + */ +CH_IRQ_HANDLER(COMP_IRQHandler) { + uint32_t pr; + + CH_IRQ_PROLOGUE(); + + pr = EXTI->PR & ((1 << 21) | (1 << 22)); + EXTI->PR = pr; + if (pr & (1 << 21)) + EXTD1.config->channels[21].cb(&EXTD1, 21); + if (pr & (1 << 22)) + EXTD1.config->channels[22].cb(&EXTD1, 22); + + CH_IRQ_EPILOGUE(); +} + +#elif defined(STM32F2XX) +/** + * @brief EXTI[18] interrupt handler (OTG_FS_WKUP). + * + * @isr + */ +CH_IRQ_HANDLER(OTG_FS_WKUP_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 18); + EXTD1.config->channels[18].cb(&EXTD1, 18); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief EXTI[19] interrupt handler (ETH_WKUP). + * + * @isr + */ +CH_IRQ_HANDLER(ETH_WKUP_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 19); + EXTD1.config->channels[19].cb(&EXTD1, 19); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief EXTI[20] interrupt handler (OTG_HS_WKUP). + * + * @isr + */ +CH_IRQ_HANDLER(OTG_HS_WKUP_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 20); + EXTD1.config->channels[20].cb(&EXTD1, 20); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief EXTI[21] interrupt handler (TAMPER_STAMP). + * + * @isr + */ +CH_IRQ_HANDLER(TAMPER_STAMP_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 21); + EXTD1.config->channels[21].cb(&EXTD1, 21); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief EXTI[22] interrupt handler (RTC_WKUP). + * + * @isr + */ +CH_IRQ_HANDLER(RTC_WKUP_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 22); + EXTD1.config->channels[22].cb(&EXTD1, 22); + + CH_IRQ_EPILOGUE(); +} + +#elif defined(STM32F10X_CL) +/** + * @brief EXTI[18] interrupt handler (OTG_FS_WKUP). * * @isr */ @@ -247,11 +373,9 @@ CH_IRQ_HANDLER(OTG_FS_WKUP_IRQHandler) { CH_IRQ_EPILOGUE(); } -#endif /* STM32_HAS_OTG1 */ -#if STM32_HAS_ETH || defined(__DOXYGEN__) /** - * @brief EXTI[19] interrupt handler (ETH). + * @brief EXTI[19] interrupt handler (ETH_WKUP). * * @isr */ @@ -264,7 +388,23 @@ CH_IRQ_HANDLER(ETH_WKUP_IRQHandler) { CH_IRQ_EPILOGUE(); } -#endif /* STM32_HAS_ETH */ + +#else +/** + * @brief EXTI[18] interrupt handler (USB_FS_WKUP). + * + * @isr + */ +CH_IRQ_HANDLER(USB_FS_WKUP_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + EXTI->PR = (1 << 18); + EXTD1.config->channels[18].cb(&EXTD1, 18); + + CH_IRQ_EPILOGUE(); +} +#endif /*===========================================================================*/ /* Driver exported functions. */ @@ -312,17 +452,38 @@ void ext_lld_start(EXTDriver *extp) { CORTEX_PRIORITY_MASK(STM32_EXT_EXTI16_IRQ_PRIORITY)); NVICEnableVector(RTC_Alarm_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI17_IRQ_PRIORITY)); -#if STM32_HAS_USB +#if defined(STM32L1XX_MD) + /* EXTI vectors specific to STM32L1xx.*/ NVICEnableVector(USB_FS_WKUP_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI18_IRQ_PRIORITY)); -#endif -#if STM32_HAS_OTG1 + NVICEnableVector(TAMPER_STAMP_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI19_IRQ_PRIORITY)); + NVICEnableVector(RTC_WKUP_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI20_IRQ_PRIORITY)); + NVICEnableVector(COMP_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI21_IRQ_PRIORITY)); +#elif defined(STM32F2XX) + /* EXTI vectors specific to STM32F2xx.*/ + NVICEnableVector(OTG_FS_WKUP_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI18_IRQ_PRIORITY)); + NVICEnableVector(ETH_WKUP_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI19_IRQ_PRIORITY)); + NVICEnableVector(OTG_HS_WKUP_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI20_IRQ_PRIORITY)); + NVICEnableVector(TAMPER_STAMP_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI21_IRQ_PRIORITY)); + NVICEnableVector(RTC_WKUP_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI22_IRQ_PRIORITY)); +#elif defined(STM32F10X_CL) + /* EXTI vectors specific to STM32F1xx Connectivity Line.*/ NVICEnableVector(OTG_FS_WKUP_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI18_IRQ_PRIORITY)); -#endif -#if STM32_HAS_ETH NVICEnableVector(ETH_WKUP_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI19_IRQ_PRIORITY)); +#else + /* EXTI vectors specific to STM32F1xx except Connectivity Line.*/ + NVICEnableVector(USB_FS_WKUP_IRQn, + CORTEX_PRIORITY_MASK(STM32_EXT_EXTI18_IRQ_PRIORITY)); #endif } /* Configuration.*/ @@ -339,10 +500,17 @@ void ext_lld_start(EXTDriver *extp) { ftsr |= (1 << i); } } +#if defined(STM32L1XX_MD) || defined(STM32F2XX) + SYSCFG->EXTICR[0] = extp->config->exti[0]; + SYSCFG->EXTICR[1] = extp->config->exti[1]; + SYSCFG->EXTICR[2] = extp->config->exti[2]; + SYSCFG->EXTICR[3] = extp->config->exti[3]; +#else /* STM32F1XX */ AFIO->EXTICR[0] = extp->config->exti[0]; AFIO->EXTICR[1] = extp->config->exti[1]; AFIO->EXTICR[2] = extp->config->exti[2]; AFIO->EXTICR[3] = extp->config->exti[3]; +#endif /* STM32F1XX */ EXTI->SWIER = 0; EXTI->RTSR = rtsr; EXTI->FTSR = ftsr; @@ -369,15 +537,27 @@ void ext_lld_stop(EXTDriver *extp) { NVICDisableVector(EXTI9_5_IRQn); NVICDisableVector(EXTI15_10_IRQn); NVICDisableVector(PVD_IRQn); - NVICDisableVector(RTC_Alarm_IRQn ); -#if STM32_HAS_USB + NVICDisableVector(RTC_Alarm_IRQn); +#if defined(STM32L1XX_MD) + /* EXTI vectors specific to STM32L1xx.*/ NVICDisableVector(USB_FS_WKUP_IRQn); -#endif -#if STM32_HAS_OTG1 + NVICDisableVector(TAMPER_STAMP_IRQn); + NVICDisableVector(RTC_WKUP_IRQn); + NVICDisableVector(COMP_IRQn); +#elif defined(STM32F2XX) + /* EXTI vectors specific to STM32F2xx.*/ NVICDisableVector(OTG_FS_WKUP_IRQn); -#endif -#if STM32_HAS_ETH NVICDisableVector(ETH_WKUP_IRQn); + NVICDisableVector(OTG_HS_WKUP_IRQn); + NVICDisableVector(TAMPER_STAMP_IRQn); + NVICDisableVector(RTC_WKUP_IRQn); +#elif defined(STM32F10X_CL) + /* EXTI vectors specific to STM32F1xx Connectivity Line.*/ + NVICDisableVector(OTG_FS_WKUP_IRQn); + NVICDisableVector(ETH_WKUP_IRQn); +#else + /* EXTI vectors specific to STM32F1xx except Connectivity Line.*/ + NVICDisableVector(USB_FS_WKUP_IRQn); #endif } EXTI->EMR = 0; diff --git a/os/hal/platforms/STM32/ext_lld.h b/os/hal/platforms/STM32/ext_lld.h index 17ea09fb8..753b12608 100644 --- a/os/hal/platforms/STM32/ext_lld.h +++ b/os/hal/platforms/STM32/ext_lld.h @@ -37,21 +37,8 @@ /** * @brief Available number of EXT channels. - * @note The number of available channels varies depending on the STM32 - * subfamily: - * - STM32F10X_CL, 20 channels. - * - STM32F2XX, 23 channels. - * - STM32L1XX_MD, 23 channels. - * - All other STM32F10X_xx, 19 channels. - * . */ -#if defined(STM32F10X_CL) || defined(__DOXYGEN__) -#define EXT_MAX_CHANNELS 20 -#elif defined(STM32F2XX) -#define EXT_MAX_CHANNELS 23 -#else -#define EXT_MAX_CHANNELS 19 -#endif +#define EXT_MAX_CHANNELS STM32_EXTI_NUM_CHANNELS /** * @brief Mask of the available channels. @@ -140,33 +127,54 @@ #endif /** - * @brief EXTI16 (PVD) interrupt priority level setting. + * @brief EXTI16 interrupt priority level setting. */ #if !defined(STM32_EXT_EXTI16_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_EXT_EXTI16_IRQ_PRIORITY 6 #endif /** - * @brief EXTI17 (RTC) interrupt priority level setting. + * @brief EXTI17 interrupt priority level setting. */ #if !defined(STM32_EXT_EXTI17_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_EXT_EXTI17_IRQ_PRIORITY 6 #endif /** - * @brief EXTI18 (USB) interrupt priority level setting. + * @brief EXTI18 interrupt priority level setting. */ #if !defined(STM32_EXT_EXTI18_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_EXT_EXTI18_IRQ_PRIORITY 6 #endif /** - * @brief EXTI19 (ETH) interrupt priority level setting. + * @brief EXTI19 interrupt priority level setting. */ #if !defined(STM32_EXT_EXTI19_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_EXT_EXTI19_IRQ_PRIORITY 6 #endif +/** + * @brief EXTI20 interrupt priority level setting. + */ +#if !defined(STM32_EXT_EXTI20_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_EXT_EXTI20_IRQ_PRIORITY 6 +#endif + +/** + * @brief EXTI21 interrupt priority level setting. + */ +#if !defined(STM32_EXT_EXTI21_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_EXT_EXTI21_IRQ_PRIORITY 6 +#endif + +/** + * @brief EXTI22 interrupt priority level setting. + */ +#if !defined(STM32_EXT_EXTI22_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_EXT_EXTI22_IRQ_PRIORITY 6 +#endif + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ -- cgit v1.2.3 From 95713cae20050dd58b41f52edead1b05c1c982a2 Mon Sep 17 00:00:00 2001 From: barthess Date: Wed, 21 Sep 2011 12:46:09 +0000 Subject: RTC. API cnahge. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3376 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/rtc.h | 3 +-- os/hal/platforms/STM32/rtc_lld.c | 22 ++++++++++------------ os/hal/platforms/STM32/rtc_lld.h | 3 +-- os/hal/src/rtc.c | 18 ++++++++---------- 4 files changed, 20 insertions(+), 26 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/rtc.h b/os/hal/include/rtc.h index e0a2c50c5..5adf9559c 100644 --- a/os/hal/include/rtc.h +++ b/os/hal/include/rtc.h @@ -75,8 +75,7 @@ extern "C" { #endif /* RTC_SUPPORTS_CALLBACKS */ void rtcSetTime(uint32_t tv_sec); - uint32_t rtcGetSec(void); - uint16_t rtcGetMsec(void); + uint32_t rtcGetTime(uint16_t *msec); void rtcSetAlarm(uint32_t tv_alarm); uint32_t rtcGetAlarm(void); #ifdef __cplusplus diff --git a/os/hal/platforms/STM32/rtc_lld.c b/os/hal/platforms/STM32/rtc_lld.c index 465f2f02e..6ae2a4aee 100644 --- a/os/hal/platforms/STM32/rtc_lld.c +++ b/os/hal/platforms/STM32/rtc_lld.c @@ -125,6 +125,7 @@ void rtc_lld_init(void){ #if STM32_RTC == STM32_RTC_LSE if (! ((RCC->BDCR & RCC_BDCR_RTCEN) || (RCC->BDCR & RCC_BDCR_LSEON))){ RCC->BDCR |= RCC_BDCR_LSEON; + /* Note: cold start time of LSE oscillator on STM32 is about 3 seconds. */ while(!(RCC->BDCR & RCC_BDCR_LSERDY)) ; RCC->BDCR |= RCC_BDCR_RTCEN; @@ -262,23 +263,20 @@ void rtc_lld_set_time(uint32_t tv_sec){ } /** - * @brief Return current time in UNIX notation. + * @brief Return return seconds since UNIX epoch. * - * @notapi - */ -inline uint32_t rtc_lld_get_sec(void){ - return ((RTC->CNTH << 16) + RTC->CNTL); -} - -/** - * @brief Return fractional part of current time (milliseconds). + * @param[in] msec pointer to variable for storing fractional part of + * time (milliseconds). * * @notapi */ -inline uint16_t rtc_lld_get_msec(void){ +inline uint32_t rtc_lld_get_time(uint16_t *msec){ uint32_t time_frac = 0; - time_frac = (((uint32_t)RTC->DIVH) << 16) + (RTC->DIVL); - return(((STM32_LSECLK - time_frac) * 1000) / STM32_LSECLK); + if(msec != NULL){ + time_frac = (((uint32_t)RTC->DIVH) << 16) + (RTC->DIVL); + *msec = (uint16_t)(((STM32_LSECLK - time_frac) * 1000) / STM32_LSECLK); + } + return ((RTC->CNTH << 16) + RTC->CNTL); } /** diff --git a/os/hal/platforms/STM32/rtc_lld.h b/os/hal/platforms/STM32/rtc_lld.h index 7d7d703f0..d73d35091 100644 --- a/os/hal/platforms/STM32/rtc_lld.h +++ b/os/hal/platforms/STM32/rtc_lld.h @@ -100,8 +100,7 @@ extern "C" { void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t overflow_cb, rtccb_t second_cb, rtccb_t alarm_cb); void rtc_lld_set_time(uint32_t tv_sec); - uint32_t rtc_lld_get_sec(void); - uint16_t rtc_lld_get_msec(void); + uint32_t rtc_lld_get_time(uint16_t *msec); uint32_t rtc_lld_get_alarm(void); void rtc_lld_set_alarm(uint32_t); #ifdef __cplusplus diff --git a/os/hal/src/rtc.c b/os/hal/src/rtc.c index ab916cf52..3b4b5824b 100644 --- a/os/hal/src/rtc.c +++ b/os/hal/src/rtc.c @@ -90,17 +90,15 @@ void rtcSetTime(uint32_t tv_sec){ } /** - * @brief Return current time in UNIX notation. - */ -inline uint32_t rtcGetSec(void){ - return rtc_lld_get_sec(); -} - -/** - * @brief Return fractional part of current time (milliseconds). + * @brief Return return seconds since UNIX epoch. + * + * @param[in] msec pointer to variable for storing fractional part of + * time (milliseconds). + * + * @notapi */ -inline uint16_t rtcGetMsec(void){ - return rtc_lld_get_msec(); +inline uint32_t rtcGetTime(uint16_t *msec){ + return rtc_lld_get_time(msec); } /** -- cgit v1.2.3 From ae42ff1857ee56d67feca50d379c5f4b66d7fe69 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 21 Sep 2011 17:10:15 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3377 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/adc_lld.h | 27 +- os/hal/platforms/STM32L1xx/adc_lld.c | 241 ++++++++++++++++++ os/hal/platforms/STM32L1xx/adc_lld.h | 447 +++++++++++++++++++++++++++++++++ os/hal/platforms/STM32L1xx/hal_lld.h | 2 +- os/hal/platforms/STM32L1xx/platform.mk | 1 + 5 files changed, 716 insertions(+), 2 deletions(-) create mode 100644 os/hal/platforms/STM32L1xx/adc_lld.c create mode 100644 os/hal/platforms/STM32L1xx/adc_lld.h (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/adc_lld.h b/os/hal/platforms/STM32F1xx/adc_lld.h index 7180c2b83..1d1052f50 100644 --- a/os/hal/platforms/STM32F1xx/adc_lld.h +++ b/os/hal/platforms/STM32F1xx/adc_lld.h @@ -35,9 +35,18 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @name Triggers selection + * @{ + */ #define ADC_CR2_EXTSEL_SRC(n) ((n) << 17) /**< @brief Trigger source. */ #define ADC_CR2_EXTSEL_SWSTART (7 << 17) /**< @brief Software trigger. */ +/** @} */ +/** + * @name Available analog channels + * @{ + */ #define ADC_CHANNEL_IN0 0 /**< @brief External analog input 0. */ #define ADC_CHANNEL_IN1 1 /**< @brief External analog input 1. */ #define ADC_CHANNEL_IN2 2 /**< @brief External analog input 2. */ @@ -56,7 +65,12 @@ #define ADC_CHANNEL_IN15 15 /**< @brief External analog input 15. */ #define ADC_CHANNEL_SENSOR 16 /**< @brief Internal temperature sensor.*/ #define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference. */ +/** @} */ +/** + * @name Sampling rates + * @{ + */ #define ADC_SAMPLE_1P5 0 /**< @brief 1.5 cycles sampling time. */ #define ADC_SAMPLE_7P5 1 /**< @brief 7.5 cycles sampling time. */ #define ADC_SAMPLE_13P5 2 /**< @brief 13.5 cycles sampling time. */ @@ -65,6 +79,7 @@ #define ADC_SAMPLE_55P5 5 /**< @brief 55.5 cycles sampling time. */ #define ADC_SAMPLE_71P5 6 /**< @brief 71.5 cycles sampling time. */ #define ADC_SAMPLE_239P5 7 /**< @brief 239.5 cycles sampling time. */ +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ @@ -206,7 +221,7 @@ typedef struct { uint32_t sqr2; /** * @brief ADC SQR3 register initialization data. - * @details Conversion group sequence 0...6. + * @details Conversion group sequence 1...6. */ uint32_t sqr3; } ADCConversionGroup; @@ -281,6 +296,10 @@ struct ADCDriver { /* Driver macros. */ /*===========================================================================*/ +/** + * @name Sequences building helper macros + * @{ + */ /** * @brief Number of channels in a conversion sequence. */ @@ -304,7 +323,12 @@ struct ADCDriver { #define ADC_SQR1_SQ14_N(n) ((n) << 5) /**< @brief 14th channel in seq.*/ #define ADC_SQR1_SQ15_N(n) ((n) << 10) /**< @brief 15th channel in seq.*/ #define ADC_SQR1_SQ16_N(n) ((n) << 15) /**< @brief 16th channel in seq.*/ +/** @} */ +/** + * @name Sampling rate settings helper macros + * @{ + */ #define ADC_SMPR2_SMP_AN0(n) ((n) << 0) /**< @brief AN0 sampling time. */ #define ADC_SMPR2_SMP_AN1(n) ((n) << 3) /**< @brief AN1 sampling time. */ #define ADC_SMPR2_SMP_AN2(n) ((n) << 6) /**< @brief AN2 sampling time. */ @@ -326,6 +350,7 @@ struct ADCDriver { sampling time. */ #define ADC_SMPR1_SMP_VREF(n) ((n) << 21) /**< @brief Voltage Reference sampling time. */ +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/platforms/STM32L1xx/adc_lld.c b/os/hal/platforms/STM32L1xx/adc_lld.c new file mode 100644 index 000000000..9ccb198e4 --- /dev/null +++ b/os/hal/platforms/STM32L1xx/adc_lld.c @@ -0,0 +1,241 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32L1xx/adc_lld.c + * @brief STM32L1xx ADC subsystem low level driver source. + * + * @addtogroup ADC + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_ADC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief ADC1 driver identifier.*/ +#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__) +ADCDriver ADCD1; +#endif + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* 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 defined(STM32_ADC_DMA_ERROR_HOOK) + if ((flags & STM32_DMA_ISR_TEIF) != 0) { + STM32_ADC_DMA_ERROR_HOOK(spip); + } +#else + (void)flags; +#endif + if ((flags & STM32_DMA_ISR_HTIF) != 0) { + /* Half transfer processing.*/ + _adc_isr_half_code(adcp); + } + if ((flags & STM32_DMA_ISR_TCIF) != 0) { + /* Transfer complete processing.*/ + _adc_isr_full_code(adcp); + } +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* 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 = STM32_DMA1_STREAM1; + ADCD1.dmamode = STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) | + STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | + STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | + STM32_DMA_CR_TEIE | STM32_DMA_CR_EN; + ADC->CCR = STM32_ADC_ADCPRE; +#endif +} + +/** + * @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) { + bool_t b; + b = dmaStreamAllocate(adcp->dmastp, + STM32_ADC_ADC1_IRQ_PRIORITY, + (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, + (void *)adcp); + chDbgAssert(!b, "adc_lld_start(), #1", "stream already allocated"); + dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR); + rccEnableADC1(FALSE); + } +#endif + + /* ADC initial setup, just resetting control registers in this case.*/ + adcp->adc->CR1 = 0; + adcp->adc->CR2 = 0; + } +} + +/** + * @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.*/ + if (adcp->state == ADC_READY) { +#if STM32_ADC_USE_ADC1 + if (&ADCD1 == adcp) { + ADC1->CR2 = 0; + dmaStreamRelease(adcp->dmastp); + rccDisableADC1(FALSE); + } +#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, n; + const ADCConversionGroup *grpp = adcp->grpp; + + /* DMA setup.*/ + mode = adcp->dmamode; + if (grpp->circular) + mode |= STM32_DMA_CR_CIRC; + if (adcp->depth > 1) { + /* If the buffer depth is greater than one then the half transfer interrupt + interrupt is enabled in order to allows streaming processing.*/ + mode |= STM32_DMA_CR_HTIE; + n = (uint32_t)grpp->num_channels * (uint32_t)adcp->depth; + } + else + n = (uint32_t)grpp->num_channels; + dmaStreamSetMemory0(adcp->dmastp, adcp->samples); + dmaStreamSetTransactionSize(adcp->dmastp, n); + dmaStreamSetMode(adcp->dmastp, mode); + + /* ADC setup.*/ + adcp->adc->SR = 0; + adcp->adc->CR1 = grpp->cr1 | ADC_CR1_SCAN; + adcp->adc->SMPR1 = grpp->smpr1; /* Writing SMPRx requires ADON=0. */ + adcp->adc->SMPR2 = grpp->smpr2; + adcp->adc->SMPR3 = grpp->smpr3; + adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON; + 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; + /* Must wait the ADC to be ready for conversion, see 9.3.6 "Timing diagram" + in the Reference Manual.*/ + while ((adcp->adc->SR & ADC_SR_ADONS) == 0) + ; + /* ADC start by raising ADC_CR2_SWSTART.*/ + adcp->adc->CR2 = grpp->cr2 | ADC_CR2_SWSTART | ADC_CR2_DMA | + ADC_CR2_CONT | ADC_CR2_ADON; +} + +/** + * @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->CR2 = 0; +} + +/** + * @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/os/hal/platforms/STM32L1xx/adc_lld.h b/os/hal/platforms/STM32L1xx/adc_lld.h new file mode 100644 index 000000000..2889387ab --- /dev/null +++ b/os/hal/platforms/STM32L1xx/adc_lld.h @@ -0,0 +1,447 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32L1xx/adc_lld.h + * @brief STM32L1xx ADC subsystem low level driver header. + * + * @addtogroup ADC + * @{ + */ + +#ifndef _ADC_LLD_H_ +#define _ADC_LLD_H_ + +#if HAL_USE_ADC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Triggers selection + * @{ + */ +#define ADC_CR2_EXTSEL_SRC(n) ((n) << 17) /**< @brief Trigger source. */ +#define ADC_CR2_EXTSEL_SWSTART (7 << 17) /**< @brief Software trigger. */ +/** @} */ + +/** + * @name ADC clock divider settings + * @{ + */ +#define ADC_CCR_ADCPRE_DIV1 0 +#define ADC_CCR_ADCPRE_DIV2 1 +#define ADC_CCR_ADCPRE_DIV4 2 +/** @} */ + +/** + * @name Available analog channels + * @{ + */ +#define ADC_CHANNEL_IN0 0 /**< @brief External analog input 0. */ +#define ADC_CHANNEL_IN1 1 /**< @brief External analog input 1. */ +#define ADC_CHANNEL_IN2 2 /**< @brief External analog input 2. */ +#define ADC_CHANNEL_IN3 3 /**< @brief External analog input 3. */ +#define ADC_CHANNEL_IN4 4 /**< @brief External analog input 4. */ +#define ADC_CHANNEL_IN5 5 /**< @brief External analog input 5. */ +#define ADC_CHANNEL_IN6 6 /**< @brief External analog input 6. */ +#define ADC_CHANNEL_IN7 7 /**< @brief External analog input 7. */ +#define ADC_CHANNEL_IN8 8 /**< @brief External analog input 8. */ +#define ADC_CHANNEL_IN9 9 /**< @brief External analog input 9. */ +#define ADC_CHANNEL_IN10 10 /**< @brief External analog input 10. */ +#define ADC_CHANNEL_IN11 11 /**< @brief External analog input 11. */ +#define ADC_CHANNEL_IN12 12 /**< @brief External analog input 12. */ +#define ADC_CHANNEL_IN13 13 /**< @brief External analog input 13. */ +#define ADC_CHANNEL_IN14 14 /**< @brief External analog input 14. */ +#define ADC_CHANNEL_IN15 15 /**< @brief External analog input 15. */ +#define ADC_CHANNEL_SENSOR 16 /**< @brief Internal temperature sensor.*/ +#define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference. */ +#define ADC_CHANNEL_IN18 18 /**< @brief External analog input 18. */ +#define ADC_CHANNEL_IN19 19 /**< @brief External analog input 19. */ +#define ADC_CHANNEL_IN20 20 /**< @brief External analog input 20. */ +#define ADC_CHANNEL_IN21 21 /**< @brief External analog input 21. */ +#define ADC_CHANNEL_IN22 22 /**< @brief External analog input 22. */ +#define ADC_CHANNEL_IN23 23 /**< @brief External analog input 23. */ +#define ADC_CHANNEL_IN24 24 /**< @brief External analog input 24. */ +#define ADC_CHANNEL_IN25 25 /**< @brief External analog input 25. */ +/** @} */ + +/** + * @name Sampling rates + * @{ + */ +#define ADC_SAMPLE_4 0 /**< @brief 4 cycles sampling time. */ +#define ADC_SAMPLE_9 1 /**< @brief 9 cycles sampling time. */ +#define ADC_SAMPLE_16 2 /**< @brief 16 cycles sampling time. */ +#define ADC_SAMPLE_24 3 /**< @brief 24 cycles sampling time. */ +#define ADC_SAMPLE_48 4 /**< @brief 48 cycles sampling time. */ +#define ADC_SAMPLE_96 5 /**< @brief 96 cycles sampling time. */ +#define ADC_SAMPLE_192 6 /**< @brief 192 cycles sampling time. */ +#define ADC_SAMPLE_384 7 /**< @brief 384 cycles sampling time. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @brief ADC1 driver enable switch. + * @details If set to @p TRUE the support for ADC1 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__) +#define STM32_ADC_USE_ADC1 TRUE +#endif + +/** + * @brief ADC common clock divider. + * @note This setting is influenced by the VDDA voltage and other + * external conditions, please refer to the STM32L15x datasheet + * for more info.
+ * See section 6.3.15 "12-bit ADC characteristics". + */ +#if !defined(STM32_ADC_ADCPRE) || defined(__DOXYGEN__) +#define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV1 +#endif + +/** + * @brief ADC1 DMA priority (0..3|lowest..highest). + */ +#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_ADC_ADC1_DMA_PRIORITY 2 +#endif + +/** + * @brief ADC1 interrupt priority level setting. + */ +#if !defined(STM32_ADC_ADC1_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_ADC_ADC1_IRQ_PRIORITY 5 +#endif + +/** + * @brief ADC DMA error hook. + * @note The default action for DMA errors is a system halt because DMA + * error can only happen because programming errors. + */ +#if !defined(STM32_ADC_DMA_ERROR_HOOK) || defined(__DOXYGEN__) +#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt() +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1 +#error "ADC1 not present in the selected device" +#endif + +#if !STM32_ADC_USE_ADC1 +#error "ADC driver activated but no ADC peripheral assigned" +#endif + +#if !defined(STM32_DMA_REQUIRED) +#define STM32_DMA_REQUIRED +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief ADC sample data type. + */ +typedef uint16_t adcsample_t; + +/** + * @brief Channels number in a conversion group. + */ +typedef uint16_t adc_channels_num_t; + +/** + * @brief Type of a structure representing an ADC driver. + */ +typedef struct ADCDriver ADCDriver; + +/** + * @brief ADC notification callback type. + * + * @param[in] adcp pointer to the @p ADCDriver object triggering the + * callback + * @param[in] buffer pointer to the most recent samples data + * @param[in] n number of buffer rows available starting from @p buffer + */ +typedef void (*adccallback_t)(ADCDriver *adcp, adcsample_t *buffer, size_t n); + +/** + * @brief Conversion group configuration structure. + * @details This implementation-dependent structure describes a conversion + * operation. + * @note The use of this configuration structure requires knowledge of + * STM32 ADC cell registers interface, please refer to the STM32 + * reference manual for details. + */ +typedef struct { + /** + * @brief Enables the circular buffer mode for the group. + */ + bool_t circular; + /** + * @brief Number of the analog channels belonging to the conversion group. + */ + adc_channels_num_t num_channels; + /** + * @brief Callback function associated to the group or @p NULL. + */ + adccallback_t end_cb; + /* End of the mandatory fields.*/ + /** + * @brief ADC CR1 register initialization data. + * @note All the required bits must be defined into this field except + * @p ADC_CR1_SCAN that is enforced inside the driver. + */ + uint32_t cr1; + /** + * @brief ADC CR2 register initialization data. + * @note All the required bits must be defined into this field except + * @p ADC_CR2_DMA, @p ADC_CR2_CONT and @p ADC_CR2_ADON that are + * enforced inside the driver. + */ + uint32_t cr2; + /** + * @brief ADC SMPR1 register initialization data. + * @details In this field must be specified the sample times for channels + * 20...25. + */ + uint32_t smpr1; + /** + * @brief ADC SMPR2 register initialization data. + * @details In this field must be specified the sample times for channels + * 10...19. + */ + uint32_t smpr2; + /** + * @brief ADC SMPR3 register initialization data. + * @details In this field must be specified the sample times for channels + * 0...9. + */ + uint32_t smpr3; + /** + * @brief ADC SQR1 register initialization data. + * @details Conversion group sequence 25...27 + sequence length. + */ + uint32_t sqr1; + /** + * @brief ADC SQR2 register initialization data. + * @details Conversion group sequence 19...24. + */ + uint32_t sqr2; + /** + * @brief ADC SQR3 register initialization data. + * @details Conversion group sequence 13...18. + */ + uint32_t sqr3; + /** + * @brief ADC SQR3 register initialization data. + * @details Conversion group sequence 7...12. + */ + uint32_t sqr4; + /** + * @brief ADC SQR3 register initialization data. + * @details Conversion group sequence 1...6. + */ + uint32_t sqr5; +} ADCConversionGroup; + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + uint32_t dummy; +} ADCConfig; + +/** + * @brief Structure representing an ADC driver. + */ +struct ADCDriver { + /** + * @brief Driver state. + */ + adcstate_t state; + /** + * @brief Current configuration data. + */ + const ADCConfig *config; + /** + * @brief Current samples buffer pointer or @p NULL. + */ + adcsample_t *samples; + /** + * @brief Current samples buffer depth or @p 0. + */ + size_t depth; + /** + * @brief Current conversion group pointer or @p NULL. + */ + const ADCConversionGroup *grpp; +#if ADC_USE_WAIT || defined(__DOXYGEN__) + /** + * @brief Waiting thread. + */ + Thread *thread; +#endif +#if ADC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) +#if CH_USE_MUTEXES || defined(__DOXYGEN__) + /** + * @brief Mutex protecting the peripheral. + */ + Mutex mutex; +#elif CH_USE_SEMAPHORES + Semaphore semaphore; +#endif +#endif /* ADC_USE_MUTUAL_EXCLUSION */ +#if defined(ADC_DRIVER_EXT_FIELDS) + ADC_DRIVER_EXT_FIELDS +#endif + /* End of the mandatory fields.*/ + /** + * @brief Pointer to the ADCx registers block. + */ + ADC_TypeDef *adc; + /** + * @brief Pointer to associated SMA channel. + */ + const stm32_dma_stream_t *dmastp; + /** + * @brief DMA mode bit mask. + */ + uint32_t dmamode; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @name Sequences building helper macros + * @{ + */ +/** + * @brief Number of channels in a conversion sequence. + */ +#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20) + +#define ADC_SQR5_SQ1_N(n) ((n) << 0) /**< @brief 1st channel in seq. */ +#define ADC_SQR5_SQ2_N(n) ((n) << 5) /**< @brief 2nd channel in seq. */ +#define ADC_SQR5_SQ3_N(n) ((n) << 10) /**< @brief 3rd channel in seq. */ +#define ADC_SQR5_SQ4_N(n) ((n) << 15) /**< @brief 4th channel in seq. */ +#define ADC_SQR5_SQ5_N(n) ((n) << 20) /**< @brief 5th channel in seq. */ +#define ADC_SQR5_SQ6_N(n) ((n) << 25) /**< @brief 6th channel in seq. */ + +#define ADC_SQR4_SQ7_N(n) ((n) << 0) /**< @brief 7th channel in seq. */ +#define ADC_SQR4_SQ8_N(n) ((n) << 5) /**< @brief 8th channel in seq. */ +#define ADC_SQR4_SQ9_N(n) ((n) << 10) /**< @brief 9th channel in seq. */ +#define ADC_SQR4_SQ10_N(n) ((n) << 15) /**< @brief 10th channel in seq.*/ +#define ADC_SQR4_SQ11_N(n) ((n) << 20) /**< @brief 11th channel in seq.*/ +#define ADC_SQR4_SQ12_N(n) ((n) << 25) /**< @brief 12th channel in seq.*/ + +#define ADC_SQR3_SQ13_N(n) ((n) << 0) /**< @brief 13th channel in seq.*/ +#define ADC_SQR3_SQ14_N(n) ((n) << 5) /**< @brief 14th channel in seq.*/ +#define ADC_SQR3_SQ15_N(n) ((n) << 10) /**< @brief 15th channel in seq.*/ +#define ADC_SQR3_SQ16_N(n) ((n) << 15) /**< @brief 16th channel in seq.*/ +#define ADC_SQR3_SQ17_N(n) ((n) << 20) /**< @brief 17th channel in seq.*/ +#define ADC_SQR3_SQ18_N(n) ((n) << 25) /**< @brief 18th channel in seq.*/ + +#define ADC_SQR2_SQ19_N(n) ((n) << 0) /**< @brief 19th channel in seq.*/ +#define ADC_SQR2_SQ20_N(n) ((n) << 5) /**< @brief 20th channel in seq.*/ +#define ADC_SQR2_SQ21_N(n) ((n) << 10) /**< @brief 21th channel in seq.*/ +#define ADC_SQR2_SQ22_N(n) ((n) << 15) /**< @brief 22th channel in seq.*/ +#define ADC_SQR2_SQ23_N(n) ((n) << 20) /**< @brief 23th channel in seq.*/ +#define ADC_SQR2_SQ24_N(n) ((n) << 25) /**< @brief 24th channel in seq.*/ + +#define ADC_SQR1_SQ25_N(n) ((n) << 0) /**< @brief 25th channel in seq.*/ +#define ADC_SQR1_SQ26_N(n) ((n) << 5) /**< @brief 26th channel in seq.*/ +#define ADC_SQR1_SQ27_N(n) ((n) << 10) /**< @brief 27th channel in seq.*/ +/** @} */ + +/** + * @name Sampling rate settings helper macros + * @{ + */ +#define ADC_SMPR3_SMP_AN0(n) ((n) << 0) /**< @brief AN0 sampling time. */ +#define ADC_SMPR3_SMP_AN1(n) ((n) << 3) /**< @brief AN1 sampling time. */ +#define ADC_SMPR3_SMP_AN2(n) ((n) << 6) /**< @brief AN2 sampling time. */ +#define ADC_SMPR3_SMP_AN3(n) ((n) << 9) /**< @brief AN3 sampling time. */ +#define ADC_SMPR3_SMP_AN4(n) ((n) << 12) /**< @brief AN4 sampling time. */ +#define ADC_SMPR3_SMP_AN5(n) ((n) << 15) /**< @brief AN5 sampling time. */ +#define ADC_SMPR3_SMP_AN6(n) ((n) << 18) /**< @brief AN6 sampling time. */ +#define ADC_SMPR3_SMP_AN7(n) ((n) << 21) /**< @brief AN7 sampling time. */ +#define ADC_SMPR3_SMP_AN8(n) ((n) << 24) /**< @brief AN8 sampling time. */ +#define ADC_SMPR3_SMP_AN9(n) ((n) << 27) /**< @brief AN9 sampling time. */ + +#define ADC_SMPR2_SMP_AN10(n) ((n) << 0) /**< @brief AN10 sampling time. */ +#define ADC_SMPR2_SMP_AN11(n) ((n) << 3) /**< @brief AN11 sampling time. */ +#define ADC_SMPR2_SMP_AN12(n) ((n) << 6) /**< @brief AN12 sampling time. */ +#define ADC_SMPR2_SMP_AN13(n) ((n) << 9) /**< @brief AN13 sampling time. */ +#define ADC_SMPR2_SMP_AN14(n) ((n) << 12) /**< @brief AN14 sampling time. */ +#define ADC_SMPR2_SMP_AN15(n) ((n) << 15) /**< @brief AN15 sampling time. */ +#define ADC_SMPR2_SMP_SENSOR(n) ((n) << 18) /**< @brief Temperature Sensor + sampling time. */ +#define ADC_SMPR2_SMP_VREF(n) ((n) << 21) /**< @brief Voltage Reference + sampling time. */ +#define ADC_SMPR2_SMP_AN18(n) ((n) << 24) /**< @brief AN18 sampling time. */ +#define ADC_SMPR2_SMP_AN19(n) ((n) << 27) /**< @brief AN19 sampling time. */ + +#define ADC_SMPR1_SMP_AN20(n) ((n) << 0) /**< @brief AN20 sampling time. */ +#define ADC_SMPR1_SMP_AN21(n) ((n) << 3) /**< @brief AN21 sampling time. */ +#define ADC_SMPR1_SMP_AN22(n) ((n) << 6) /**< @brief AN22 sampling time. */ +#define ADC_SMPR1_SMP_AN23(n) ((n) << 9) /**< @brief AN23 sampling time. */ +#define ADC_SMPR1_SMP_AN24(n) ((n) << 12) /**< @brief AN24 sampling time. */ +#define ADC_SMPR1_SMP_AN25(n) ((n) << 15) /**< @brief AN25 sampling time. */ +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__) +extern ADCDriver ADCD1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void adc_lld_init(void); + void adc_lld_start(ADCDriver *adcp); + void adc_lld_stop(ADCDriver *adcp); + void adc_lld_start_conversion(ADCDriver *adcp); + void adc_lld_stop_conversion(ADCDriver *adcp); + void adcSTM32EnableTSVREFE(void); + void adcSTM32DisableTSVREFE(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_ADC */ + +#endif /* _ADC_LLD_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index 2c3d05138..cf07e8036 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -423,7 +423,7 @@ /** * @brief Maximum HSECLK at current voltage setting. */ -#define STM32_HSECLK_MAX 32000000#if +#define STM32_HSECLK_MAX 32000000 /** * @brief Maximum SYSCLK at current voltage setting. diff --git a/os/hal/platforms/STM32L1xx/platform.mk b/os/hal/platforms/STM32L1xx/platform.mk index 047864a79..45e937ee5 100644 --- a/os/hal/platforms/STM32L1xx/platform.mk +++ b/os/hal/platforms/STM32L1xx/platform.mk @@ -1,5 +1,6 @@ # List of all the STM32L1xx platform files. PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32L1xx/hal_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32L1xx/adc_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/ext_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/gpt_lld.c \ -- cgit v1.2.3 From 8dfb19e4364eac8aea8f4fe1196cd0d0d6d4c266 Mon Sep 17 00:00:00 2001 From: barthess Date: Wed, 21 Sep 2011 17:42:30 +0000 Subject: RTC. Minor documentation improvements. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3378 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/rtc_lld.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/rtc_lld.c b/os/hal/platforms/STM32/rtc_lld.c index 6ae2a4aee..c1163d1a1 100644 --- a/os/hal/platforms/STM32/rtc_lld.c +++ b/os/hal/platforms/STM32/rtc_lld.c @@ -109,13 +109,15 @@ CH_IRQ_HANDLER(RTC_IRQHandler) { * @brief Enable access to registers and initialize RTC if BKP domain * was previously reseted. * + * @note: Cold start time of LSE oscillator on STM32 platform + * takes about 3 seconds. + * * @notapi */ void rtc_lld_init(void){ uint32_t preload = 0; rccEnableBKPInterface(FALSE); - //RCC->APB1ENR |= (RCC_APB1ENR_BKPEN | RCC_APB1ENR_PWREN); /* enable access to BKP registers */ PWR->CR |= PWR_CR_DBP; @@ -124,8 +126,7 @@ void rtc_lld_init(void){ #if STM32_RTC == STM32_RTC_LSE if (! ((RCC->BDCR & RCC_BDCR_RTCEN) || (RCC->BDCR & RCC_BDCR_LSEON))){ - RCC->BDCR |= RCC_BDCR_LSEON; - /* Note: cold start time of LSE oscillator on STM32 is about 3 seconds. */ + RCC->BDCR |= RCC_BDCR_LSEON; while(!(RCC->BDCR & RCC_BDCR_LSERDY)) ; RCC->BDCR |= RCC_BDCR_RTCEN; -- cgit v1.2.3 From 4ffade31534ae304e78c1992b65fc6f1cd1bddeb Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 21 Sep 2011 19:23:41 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3379 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/spi_lld.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/spi_lld.c b/os/hal/platforms/STM32/spi_lld.c index 7041ef854..194a386a7 100644 --- a/os/hal/platforms/STM32/spi_lld.c +++ b/os/hal/platforms/STM32/spi_lld.c @@ -214,12 +214,12 @@ void spi_lld_start(SPIDriver *spip) { #if STM32_SPI_USE_SPI3 if (&SPID3 == spip) { bool_t b; - b = dmaStreamAllocate(STM32_DMA1_STREAM1, + b = dmaStreamAllocate(STM32_DMA2_STREAM1, STM32_SPI_SPI3_IRQ_PRIORITY, (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); chDbgAssert(!b, "spi_lld_start(), #5", "stream already allocated"); - b = dmaStreamAllocate(STM32_DMA1_STREAM2, + b = dmaStreamAllocate(STM32_DMA2_STREAM2, STM32_SPI_SPI3_IRQ_PRIORITY, (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); -- cgit v1.2.3 From 40c7a8982aaef28d6ac7cbbd378708f237711ccf Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 21 Sep 2011 19:31:11 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3380 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/spi_lld.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/spi_lld.c b/os/hal/platforms/STM32/spi_lld.c index 194a386a7..f8ec8546c 100644 --- a/os/hal/platforms/STM32/spi_lld.c +++ b/os/hal/platforms/STM32/spi_lld.c @@ -284,8 +284,8 @@ void spi_lld_stop(SPIDriver *spip) { #endif #if STM32_SPI_USE_SPI3 if (&SPID3 == spip) { - dmaStreamRelease(STM32_DMA1_STREAM1); - dmaStreamRelease(STM32_DMA1_STREAM2); + dmaStreamRelease(STM32_DMA2_STREAM1); + dmaStreamRelease(STM32_DMA2_STREAM2); rccDisableSPI3(FALSE); } #endif -- cgit v1.2.3 From 4a3e3fc01ec6dfb4a710db771bee262d5dc9327e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 22 Sep 2011 14:53:42 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3381 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/dox/adc.dox | 16 ++++++++--- os/hal/include/adc.h | 49 +++++++++++++++++++++++++++++++++- os/hal/platforms/STM32F1xx/adc_lld.c | 26 +++++++++--------- os/hal/platforms/STM32F1xx/adc_lld.h | 30 ++++++++++++++------- os/hal/platforms/STM32L1xx/adc_lld.c | 51 +++++++++++++++++++++++++++--------- os/hal/platforms/STM32L1xx/adc_lld.h | 34 ++++++++++++++++-------- os/hal/src/adc.c | 7 ++++- 7 files changed, 162 insertions(+), 51 deletions(-) (limited to 'os/hal') diff --git a/os/hal/dox/adc.dox b/os/hal/dox/adc.dox index bb8ff014f..53bfb75d2 100644 --- a/os/hal/dox/adc.dox +++ b/os/hal/dox/adc.dox @@ -34,8 +34,9 @@ * @if LATEX_PDF * @dot digraph example { - size="5, 7"; rankdir="LR"; + size="5, 7"; + node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"]; edge [fontname=Helvetica, fontsize=8]; @@ -43,6 +44,7 @@ uninit [label="ADC_UNINIT", style="bold"]; ready [label="ADC_READY\nClock Enabled"]; active [label="ADC_ACTIVE\nConverting"]; + error [label="ADC_ERROR\nError"]; complete [label="ADC_COMPLETE\nComplete"]; uninit -> stop [label="\n adcInit()", constraint=false]; @@ -53,15 +55,19 @@ ready -> active [label="\nadcStartConversion() (async)\nadcConvert() (sync)"]; active -> ready [label="\nadcStopConversion()\nsync return"]; active -> active [label="\nasync callback (half buffer)\nasync callback (full buffer circular)\n>acg_endcb<"]; - active -> complete [label="\nasync callback (full buffer)\n>acg_endcb<"]; + active -> complete [label="\n\nasync callback (full buffer)\n>end_cb<"]; + active -> error [label="\n\nasync callback (error)\n>error_cb<"]; complete -> active [label="\nadcStartConversionI()\nthen\ncallback return"]; complete -> ready [label="\ncallback return"]; + error -> active [label="\nadcStartConversionI()\nthen\ncallback return"]; + error -> ready [label="\ncallback return"]; } * @enddot * @else * @dot digraph example { rankdir="LR"; + node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"]; edge [fontname=Helvetica, fontsize=8]; @@ -69,6 +75,7 @@ uninit [label="ADC_UNINIT", style="bold"]; ready [label="ADC_READY\nClock Enabled"]; active [label="ADC_ACTIVE\nConverting"]; + error [label="ADC_ERROR\nError"]; complete [label="ADC_COMPLETE\nComplete"]; uninit -> stop [label="\n adcInit()", constraint=false]; @@ -79,9 +86,12 @@ ready -> active [label="\nadcStartConversion() (async)\nadcConvert() (sync)"]; active -> ready [label="\nadcStopConversion()\nsync return"]; active -> active [label="\nasync callback (half buffer)\nasync callback (full buffer circular)\n>acg_endcb<"]; - active -> complete [label="\nasync callback (full buffer)\n>acg_endcb<"]; + active -> complete [label="\n\nasync callback (full buffer)\n>end_cb<"]; + active -> error [label="\n\nasync callback (error)\n>error_cb<"]; complete -> active [label="\nadcStartConversionI()\nthen\ncallback return"]; complete -> ready [label="\ncallback return"]; + error -> active [label="\nadcStartConversionI()\nthen\ncallback return"]; + error -> ready [label="\ncallback return"]; } * @enddot * @endif diff --git a/os/hal/include/adc.h b/os/hal/include/adc.h index 53c7c199a..cb392f4e2 100644 --- a/os/hal/include/adc.h +++ b/os/hal/include/adc.h @@ -80,7 +80,8 @@ typedef enum { ADC_STOP = 1, /**< Stopped. */ ADC_READY = 2, /**< Ready. */ ADC_ACTIVE = 3, /**< Converting. */ - ADC_COMPLETE = 4 /**< Conversion complete. */ + ADC_COMPLETE = 4, /**< Conversion complete. */ + ADC_ERROR = 5 /**< Conversion complete. */ } adcstate_t; #include "adc_lld.h" @@ -144,10 +145,30 @@ typedef enum { } \ } +/** + * @brief Wakes up the waiting thread with a timeout message. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +#define _adc_timeout_isr(adcp) { \ + if ((adcp)->thread != NULL) { \ + Thread *tp; \ + chSysLockFromIsr(); \ + tp = (adcp)->thread; \ + (adcp)->thread = NULL; \ + tp->p_u.rdymsg = RDY_TIMEOUT; \ + chSchReadyI(tp); \ + chSysUnlockFromIsr(); \ + } \ +} + #else /* !ADC_USE_WAIT */ #define _adc_reset_i(adcp) #define _adc_reset_s(adcp) #define _adc_wakeup_isr(adcp) +#define _adc_timeout_isr(adcp) #endif /* !ADC_USE_WAIT */ /** @@ -220,6 +241,32 @@ typedef enum { _adc_wakeup_isr(adcp); \ } \ } + +/** + * @brief Common ISR code, error event. + * @details This code handles the portable part of the ISR code: + * - Callback invocation. + * - Waiting thread timeout signaling, if any. + * - Driver state transitions. + * . + * @note This macro is meant to be used in the low level drivers + * implementation only. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +#define _adc_isr_error_code(adcp, err) { \ + adc_lld_stop_conversion(adcp); \ + if ((adcp)->grpp->error_cb != NULL) { \ + (adcp)->state = ADC_ERROR; \ + (adcp)->grpp->error_cb(adcp, err); \ + if ((adcp)->state == ADC_ERROR) \ + (adcp)->state = ADC_READY; \ + } \ + (adcp)->grpp = NULL; \ + _adc_timeout_isr(adcp); \ +} /** @} */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F1xx/adc_lld.c b/os/hal/platforms/STM32F1xx/adc_lld.c index ac74251f8..84b194c0f 100644 --- a/os/hal/platforms/STM32F1xx/adc_lld.c +++ b/os/hal/platforms/STM32F1xx/adc_lld.c @@ -57,20 +57,20 @@ ADCDriver ADCD1; static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { /* DMA errors handling.*/ -#if defined(STM32_ADC_DMA_ERROR_HOOK) if ((flags & STM32_DMA_ISR_TEIF) != 0) { - STM32_ADC_DMA_ERROR_HOOK(spip); + /* 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 - (void)flags; -#endif - if ((flags & STM32_DMA_ISR_HTIF) != 0) { - /* Half transfer processing.*/ - _adc_isr_half_code(adcp); - } - 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); + } + if ((flags & STM32_DMA_ISR_TCIF) != 0) { + /* Transfer complete processing.*/ + _adc_isr_full_code(adcp); + } } } @@ -146,7 +146,7 @@ void adc_lld_start(ADCDriver *adcp) { /* ADC setup, the calibration procedure has already been performed during initialization.*/ - adcp->adc->CR1 = ADC_CR1_SCAN; + adcp->adc->CR1 = 0; adcp->adc->CR2 = 0; } } diff --git a/os/hal/platforms/STM32F1xx/adc_lld.h b/os/hal/platforms/STM32F1xx/adc_lld.h index 1d1052f50..e3a327afa 100644 --- a/os/hal/platforms/STM32F1xx/adc_lld.h +++ b/os/hal/platforms/STM32F1xx/adc_lld.h @@ -108,15 +108,6 @@ #define STM32_ADC_ADC1_IRQ_PRIORITY 5 #endif -/** - * @brief ADC DMA error hook. - * @note The default action for DMA errors is a system halt because DMA - * error can only happen because programming errors. - */ -#if !defined(STM32_ADC_DMA_ERROR_HOOK) || defined(__DOXYGEN__) -#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt() -#endif - /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ @@ -147,6 +138,15 @@ typedef uint16_t adcsample_t; */ typedef uint16_t adc_channels_num_t; +/** + * @brief Possible ADC failure causes. + * @note Error codes are architecture dependent and should not relied + * upon. + */ +typedef enum { + ADC_ERR_DMAFAILURE = 0 /**< DMA operations failure. */ +} adcerror_t; + /** * @brief Type of a structure representing an ADC driver. */ @@ -162,6 +162,14 @@ typedef struct ADCDriver ADCDriver; */ typedef void (*adccallback_t)(ADCDriver *adcp, adcsample_t *buffer, size_t n); +/** + * @brief ADC error callback type. + * + * @param[in] adcp pointer to the @p ADCDriver object triggering the + * callback + */ +typedef void (*adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err); + /** * @brief Conversion group configuration structure. * @details This implementation-dependent structure describes a conversion @@ -183,6 +191,10 @@ typedef struct { * @brief Callback function associated to the group or @p NULL. */ adccallback_t end_cb; + /** + * @brief Error callback or @p NULL. + */ + adcerrorcallback_t error_cb; /* End of the mandatory fields.*/ /** * @brief ADC CR1 register initialization data. diff --git a/os/hal/platforms/STM32L1xx/adc_lld.c b/os/hal/platforms/STM32L1xx/adc_lld.c index 9ccb198e4..a2149b6ae 100644 --- a/os/hal/platforms/STM32L1xx/adc_lld.c +++ b/os/hal/platforms/STM32L1xx/adc_lld.c @@ -57,20 +57,20 @@ ADCDriver ADCD1; static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { /* DMA errors handling.*/ -#if defined(STM32_ADC_DMA_ERROR_HOOK) if ((flags & STM32_DMA_ISR_TEIF) != 0) { - STM32_ADC_DMA_ERROR_HOOK(spip); + /* 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 - (void)flags; -#endif - if ((flags & STM32_DMA_ISR_HTIF) != 0) { - /* Half transfer processing.*/ - _adc_isr_half_code(adcp); - } - 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); + } + if ((flags & STM32_DMA_ISR_TCIF) != 0) { + /* Transfer complete processing.*/ + _adc_isr_full_code(adcp); + } } } @@ -78,6 +78,29 @@ static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { /* Driver interrupt handlers. */ /*===========================================================================*/ +#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__) +/** + * @brief ADC1 interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(UART5_IRQHandler) { + uint32_t sr; + + CH_IRQ_PROLOGUE(); + + sr = ADC1->SR; + ADC1->SR = 0; + if (sr & ADC_SR_OVR) { + /* ADC overflow condition, this could happen only if the DMA is unable + to read data fast enough.*/ + _adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW); + } + + CH_IRQ_EPILOGUE(); +} +#endif + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -145,6 +168,7 @@ void adc_lld_stop(ADCDriver *adcp) { if (adcp->state == ADC_READY) { #if STM32_ADC_USE_ADC1 if (&ADCD1 == adcp) { + ADC1->CR1 = 0; ADC1->CR2 = 0; dmaStreamRelease(adcp->dmastp); rccDisableADC1(FALSE); @@ -182,7 +206,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) { /* ADC setup.*/ adcp->adc->SR = 0; - adcp->adc->CR1 = grpp->cr1 | ADC_CR1_SCAN; + adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN; adcp->adc->SMPR1 = grpp->smpr1; /* Writing SMPRx requires ADON=0. */ adcp->adc->SMPR2 = grpp->smpr2; adcp->adc->SMPR3 = grpp->smpr3; @@ -211,6 +235,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) { void adc_lld_stop_conversion(ADCDriver *adcp) { dmaStreamDisable(adcp->dmastp); + adcp->adc->CR1 = 0; adcp->adc->CR2 = 0; } diff --git a/os/hal/platforms/STM32L1xx/adc_lld.h b/os/hal/platforms/STM32L1xx/adc_lld.h index 2889387ab..0ca41c269 100644 --- a/os/hal/platforms/STM32L1xx/adc_lld.h +++ b/os/hal/platforms/STM32L1xx/adc_lld.h @@ -39,8 +39,7 @@ * @name Triggers selection * @{ */ -#define ADC_CR2_EXTSEL_SRC(n) ((n) << 17) /**< @brief Trigger source. */ -#define ADC_CR2_EXTSEL_SWSTART (7 << 17) /**< @brief Software trigger. */ +#define ADC_CR2_EXTSEL_SRC(n) ((n) << 24) /**< @brief Trigger source. */ /** @} */ /** @@ -136,15 +135,6 @@ #define STM32_ADC_ADC1_IRQ_PRIORITY 5 #endif -/** - * @brief ADC DMA error hook. - * @note The default action for DMA errors is a system halt because DMA - * error can only happen because programming errors. - */ -#if !defined(STM32_ADC_DMA_ERROR_HOOK) || defined(__DOXYGEN__) -#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt() -#endif - /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ @@ -175,6 +165,16 @@ typedef uint16_t adcsample_t; */ typedef uint16_t adc_channels_num_t; +/** + * @brief Possible ADC failure causes. + * @note Error codes are architecture dependent and should not relied + * upon. + */ +typedef enum { + ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */ + ADC_ERR_OVERFLOW = 1 /**< ADC overflow condition. */ +} adcerror_t; + /** * @brief Type of a structure representing an ADC driver. */ @@ -190,6 +190,14 @@ typedef struct ADCDriver ADCDriver; */ typedef void (*adccallback_t)(ADCDriver *adcp, adcsample_t *buffer, size_t n); +/** + * @brief ADC error callback type. + * + * @param[in] adcp pointer to the @p ADCDriver object triggering the + * callback + */ +typedef void (*adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err); + /** * @brief Conversion group configuration structure. * @details This implementation-dependent structure describes a conversion @@ -211,6 +219,10 @@ typedef struct { * @brief Callback function associated to the group or @p NULL. */ adccallback_t end_cb; + /** + * @brief Error callback or @p NULL. + */ + adcerrorcallback_t error_cb; /* End of the mandatory fields.*/ /** * @brief ADC CR1 register initialization data. diff --git a/os/hal/src/adc.c b/os/hal/src/adc.c index c375818a6..08aa830f0 100644 --- a/os/hal/src/adc.c +++ b/os/hal/src/adc.c @@ -162,6 +162,8 @@ void adcStartConversion(ADCDriver *adcp, /** * @brief Starts an ADC conversion. * @details Starts an asynchronous conversion operation. + * @post The callbacks associated to the conversion group will be invoked + * on buffer fill and error events. * @note The buffer is organized as a matrix of M*N elements where M is the * channels number configured into the conversion group and N is the * buffer depth. The samples are sequentially written into the buffer @@ -185,7 +187,8 @@ void adcStartConversionI(ADCDriver *adcp, ((depth == 1) || ((depth & 1) == 0)), "adcStartConversionI"); chDbgAssert((adcp->state == ADC_READY) || - (adcp->state == ADC_COMPLETE), + (adcp->state == ADC_COMPLETE) || + (adcp->state == ADC_ERROR), "adcStartConversionI(), #1", "not ready"); adcp->samples = samples; @@ -268,6 +271,8 @@ void adcStopConversionI(ADCDriver *adcp) { * @retval RDY_RESET The conversion has been stopped using * @p acdStopConversion() or @p acdStopConversionI(), * the result buffer may contain incorrect data. + * @retval RDY_TIMEOUT The conversion has been stopped because an hardware + * error. * * @api */ -- cgit v1.2.3 From c39d08fc2ae9c43f73114e24292520306bddde19 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 23 Sep 2011 15:48:55 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3384 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/adc.h | 1 + os/hal/platforms/STM32F1xx/platform.dox | 20 +++++++++++++++-- os/hal/platforms/STM32L1xx/adc_lld.c | 5 ++++- os/hal/platforms/STM32L1xx/platform.dox | 40 +++++++++++++++++++++++++++++++-- os/hal/templates/ext_lld.c | 7 ++++++ os/hal/templates/ext_lld.h | 19 +++++++++++++--- 6 files changed, 84 insertions(+), 8 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/adc.h b/os/hal/include/adc.h index cb392f4e2..ff9e6b18f 100644 --- a/os/hal/include/adc.h +++ b/os/hal/include/adc.h @@ -253,6 +253,7 @@ typedef enum { * implementation only. * * @param[in] adcp pointer to the @p ADCDriver object + * @param[in] err platform dependent error code * * @notapi */ diff --git a/os/hal/platforms/STM32F1xx/platform.dox b/os/hal/platforms/STM32F1xx/platform.dox index 83c33a868..de8d9a5d9 100644 --- a/os/hal/platforms/STM32F1xx/platform.dox +++ b/os/hal/platforms/STM32F1xx/platform.dox @@ -62,7 +62,7 @@ * - Programmable ADC interrupt priority level. * - Programmable DMA bus priority for each DMA channel. * - Programmable DMA interrupt priority for each DMA channel. - * - Programmable DMA error hook. + * - DMA errors detection. * . * @ingroup STM32F1xx_DRIVERS */ @@ -93,9 +93,25 @@ * - DMA2 (where present). * . * @section stm32f1xx_dma_2 STM32F1xx DMA driver implementation features - * - Automatic DMA clock stop when not in use by other drivers. * - Exports helper functions/macros to the other drivers that share the * DMA resource. + * - Automatic DMA clock stop when not in use by any driver. + * - DMA streams and interrupt vectors sharing among multiple drivers. + * . + * @ingroup STM32F1xx_DRIVERS + */ + +/** + * @defgroup STM32F1xx_EXT STM32F1xx EXT Support + * @details The STM32F1xx EXT driver uses the EXTI peripheral. + * + * @section stm32f1xx_ext_1 Supported HW resources + * - EXTI. + * . + * @section stm32f1xx_ext_2 STM32F1xx EXT driver implementation features + * - Each EXTI channel can be independently enabled and programmed. + * - Programmable EXTI interrupts priority level. + * - Capability to work as event sources (WFE) rather than interrupt sources. * . * @ingroup STM32F1xx_DRIVERS */ diff --git a/os/hal/platforms/STM32L1xx/adc_lld.c b/os/hal/platforms/STM32L1xx/adc_lld.c index a2149b6ae..74c9a6ee3 100644 --- a/os/hal/platforms/STM32L1xx/adc_lld.c +++ b/os/hal/platforms/STM32L1xx/adc_lld.c @@ -84,7 +84,7 @@ static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { * * @isr */ -CH_IRQ_HANDLER(UART5_IRQHandler) { +CH_IRQ_HANDLER(ADC1_IRQHandler) { uint32_t sr; CH_IRQ_PROLOGUE(); @@ -96,6 +96,7 @@ CH_IRQ_HANDLER(UART5_IRQHandler) { to read data fast enough.*/ _adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW); } + /* TODO: Add here analog watchdog handling.*/ CH_IRQ_EPILOGUE(); } @@ -146,6 +147,8 @@ void adc_lld_start(ADCDriver *adcp) { chDbgAssert(!b, "adc_lld_start(), #1", "stream already allocated"); dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR); rccEnableADC1(FALSE); + NVICEnableVector(ADC1_IRQn, + CORTEX_PRIORITY_MASK(STM32_ADC_ADC1_IRQ_PRIORITY)); } #endif diff --git a/os/hal/platforms/STM32L1xx/platform.dox b/os/hal/platforms/STM32L1xx/platform.dox index 7abe18e5e..910fdf7bd 100644 --- a/os/hal/platforms/STM32L1xx/platform.dox +++ b/os/hal/platforms/STM32L1xx/platform.dox @@ -20,7 +20,7 @@ /** * @defgroup STM32L1xx_DRIVERS STM32L1xx Drivers - * @details This section describes all the supported drivers on the STM32F1xx + * @details This section describes all the supported drivers on the STM32L1xx * platform and the implementation details of the single drivers. * * @ingroup platforms @@ -46,6 +46,26 @@ * @ingroup STM32L1xx_DRIVERS */ +/** + * @defgroup STM32L1xx_ADC STM32L1xx ADC Support + * @details The STM32L1xx ADC driver supports the ADC peripherals using DMA + * channels for maximum performance. + * + * @section stm32l1xx_adc_1 Supported HW resources + * - ADC1. + * - DMA1. + * . + * @section stm32l1xx_adc_2 STM32L1xx ADC driver implementation features + * - Clock stop for reduced power usage when the driver is in stop state. + * - Streaming conversion using DMA for maximum performance. + * - Programmable ADC interrupt priority level. + * - Programmable DMA bus priority for each DMA channel. + * - Programmable DMA interrupt priority for each DMA channel. + * - DMA and ADC errors detection. + * . + * @ingroup STM32L1xx_DRIVERS + */ + /** * @defgroup STM32L1xx_DMA STM32L1xx DMA Support * @details This DMA helper driver is used by the other drivers in order to @@ -56,9 +76,25 @@ * - DMA1. * . * @section stm32l1xx_dma_2 STM32L1xx DMA driver implementation features - * - Automatic DMA clock stop when not in use by other drivers. * - Exports helper functions/macros to the other drivers that share the * DMA resource. + * - Automatic DMA clock stop when not in use by any driver. + * - DMA streams and interrupt vectors sharing among multiple drivers. + * . + * @ingroup STM32L1xx_DRIVERS + */ + +/** + * @defgroup STM32L1xx_EXT STM32L1xx EXT Support + * @details The STM32L1xx EXT driver uses the EXTI peripheral. + * + * @section stm32l1xx_ext_1 Supported HW resources + * - EXTI. + * . + * @section stm32l1xx_ext_2 STM32L1xx EXT driver implementation features + * - Each EXTI channel can be independently enabled and programmed. + * - Programmable EXTI interrupts priority level. + * - Capability to work as event sources (WFE) rather than interrupt sources. * . * @ingroup STM32L1xx_DRIVERS */ diff --git a/os/hal/templates/ext_lld.c b/os/hal/templates/ext_lld.c index 45bc1c3dc..fc9c2181d 100644 --- a/os/hal/templates/ext_lld.c +++ b/os/hal/templates/ext_lld.c @@ -39,6 +39,11 @@ /* Driver exported variables. */ /*===========================================================================*/ +/** + * @brief EXTD1 driver identifier. + */ +EXTDriver EXTD1; + /*===========================================================================*/ /* Driver local variables. */ /*===========================================================================*/ @@ -62,6 +67,8 @@ */ void ext_lld_init(void) { + /* Driver initialization.*/ + extObjectInit(&EXTD1); } /** diff --git a/os/hal/templates/ext_lld.h b/os/hal/templates/ext_lld.h index 494cef1b9..f299a8914 100644 --- a/os/hal/templates/ext_lld.h +++ b/os/hal/templates/ext_lld.h @@ -63,14 +63,23 @@ typedef uint32_t expchannel_t; * @param[in] extp pointer to the @p EXPDriver object triggering the * callback */ -typedef void (*extcallback_t)(EXTDriver *extp); +typedef void (*extcallback_t)(EXTDriver *extp, expchannel_t channel); /** * @brief Channel configuration structure. */ typedef struct { - uint32_t mode; /**< @brief Channel mode. */ - extcallback_t cb; /**< @brief Channel callback. */ + /** + * @brief Channel mode. + */ + uint32_t mode; + /** + * @brief Channel callback. + * @details In the STM32 implementation a @p NULL callback pointer is + * valid and configures the channel as an event sources instead + * of an interrupt source. + */ + extcallback_t cb; } EXTChannelConfig; /** @@ -108,6 +117,10 @@ struct EXTDriver { /* External declarations. */ /*===========================================================================*/ +#if !defined(__DOXYGEN__) +extern EXTDriver EXTD1; +#endif + #ifdef __cplusplus extern "C" { #endif -- cgit v1.2.3 From 09d93604e7d02274f433d0854f9bfdfcab53cc9f Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 23 Sep 2011 20:38:42 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3386 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32L1xx/adc_lld.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32L1xx/adc_lld.c b/os/hal/platforms/STM32L1xx/adc_lld.c index 74c9a6ee3..dfd1883f0 100644 --- a/os/hal/platforms/STM32L1xx/adc_lld.c +++ b/os/hal/platforms/STM32L1xx/adc_lld.c @@ -213,7 +213,8 @@ void adc_lld_start_conversion(ADCDriver *adcp) { adcp->adc->SMPR1 = grpp->smpr1; /* Writing SMPRx requires ADON=0. */ adcp->adc->SMPR2 = grpp->smpr2; adcp->adc->SMPR3 = grpp->smpr3; - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON; + adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_CONT | + ADC_CR2_ADON; adcp->adc->SQR1 = grpp->sqr1; adcp->adc->SQR2 = grpp->sqr2; adcp->adc->SQR3 = grpp->sqr3; @@ -224,7 +225,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) { while ((adcp->adc->SR & ADC_SR_ADONS) == 0) ; /* ADC start by raising ADC_CR2_SWSTART.*/ - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_SWSTART | ADC_CR2_DMA | + adcp->adc->CR2 = grpp->cr2 | ADC_CR2_SWSTART | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_CONT | ADC_CR2_ADON; } -- cgit v1.2.3 From 5bf43b6500206391495dee6ea06c892dc450dcf2 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 24 Sep 2011 06:53:13 +0000 Subject: STM32L driver tested and working. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3387 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32L1xx/adc_lld.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32L1xx/adc_lld.c b/os/hal/platforms/STM32L1xx/adc_lld.c index dfd1883f0..eeae18f68 100644 --- a/os/hal/platforms/STM32L1xx/adc_lld.c +++ b/os/hal/platforms/STM32L1xx/adc_lld.c @@ -188,23 +188,24 @@ void adc_lld_stop(ADCDriver *adcp) { * @notapi */ void adc_lld_start_conversion(ADCDriver *adcp) { - uint32_t mode, n; + uint32_t mode, cr2; const ADCConversionGroup *grpp = adcp->grpp; /* DMA setup.*/ mode = adcp->dmamode; - if (grpp->circular) + cr2 = grpp->cr2; + if (grpp->circular) { mode |= STM32_DMA_CR_CIRC; + cr2 |= ADC_CR2_CONT; + } if (adcp->depth > 1) { /* If the buffer depth is greater than one then the half transfer interrupt interrupt is enabled in order to allows streaming processing.*/ mode |= STM32_DMA_CR_HTIE; - n = (uint32_t)grpp->num_channels * (uint32_t)adcp->depth; } - else - n = (uint32_t)grpp->num_channels; dmaStreamSetMemory0(adcp->dmastp, adcp->samples); - dmaStreamSetTransactionSize(adcp->dmastp, n); + dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels * + (uint32_t)adcp->depth); dmaStreamSetMode(adcp->dmastp, mode); /* ADC setup.*/ @@ -213,8 +214,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) { adcp->adc->SMPR1 = grpp->smpr1; /* Writing SMPRx requires ADON=0. */ adcp->adc->SMPR2 = grpp->smpr2; adcp->adc->SMPR3 = grpp->smpr3; - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_CONT | - ADC_CR2_ADON; + adcp->adc->CR2 = cr2 | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON; adcp->adc->SQR1 = grpp->sqr1; adcp->adc->SQR2 = grpp->sqr2; adcp->adc->SQR3 = grpp->sqr3; @@ -225,8 +225,8 @@ void adc_lld_start_conversion(ADCDriver *adcp) { while ((adcp->adc->SR & ADC_SR_ADONS) == 0) ; /* ADC start by raising ADC_CR2_SWSTART.*/ - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_SWSTART | ADC_CR2_DMA | ADC_CR2_DDS | - ADC_CR2_CONT | ADC_CR2_ADON; + adcp->adc->CR2 = cr2 | ADC_CR2_SWSTART | ADC_CR2_DMA | ADC_CR2_DDS | + ADC_CR2_ADON; } /** -- cgit v1.2.3 From da02a90b8cbe29a6304e7af0c1396c0274a4a9ce Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 24 Sep 2011 10:34:03 +0000 Subject: Fixed bug 3413558. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3396 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/icu_lld.c | 18 +++++++++--------- os/hal/platforms/STM32/icu_lld.h | 4 ++++ os/hal/platforms/STM32/pwm_lld.c | 18 +++++++++--------- os/hal/platforms/STM32/pwm_lld.h | 4 ++++ 4 files changed, 26 insertions(+), 18 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/icu_lld.c b/os/hal/platforms/STM32/icu_lld.c index eaf98ec12..33eff67d5 100644 --- a/os/hal/platforms/STM32/icu_lld.c +++ b/os/hal/platforms/STM32/icu_lld.c @@ -281,7 +281,7 @@ void icu_lld_init(void) { * @notapi */ void icu_lld_start(ICUDriver *icup) { - uint32_t clock, psc; + uint32_t psc; if (icup->state == ICU_STOP) { /* Clock activation and timer reset.*/ @@ -291,7 +291,7 @@ void icu_lld_start(ICUDriver *icup) { rccResetTIM1(); NVICEnableVector(TIM1_CC_IRQn, CORTEX_PRIORITY_MASK(STM32_ICU_TIM1_IRQ_PRIORITY)); - clock = STM32_TIMCLK2; + icup->clock = STM32_TIMCLK2; } #endif #if STM32_ICU_USE_TIM2 @@ -300,7 +300,7 @@ void icu_lld_start(ICUDriver *icup) { rccResetTIM2(); NVICEnableVector(TIM2_IRQn, CORTEX_PRIORITY_MASK(STM32_ICU_TIM2_IRQ_PRIORITY)); - clock = STM32_TIMCLK1; + icup->clock = STM32_TIMCLK1; } #endif #if STM32_ICU_USE_TIM3 @@ -309,7 +309,7 @@ void icu_lld_start(ICUDriver *icup) { rccResetTIM3(); NVICEnableVector(TIM3_IRQn, CORTEX_PRIORITY_MASK(STM32_ICU_TIM3_IRQ_PRIORITY)); - clock = STM32_TIMCLK1; + icup->clock = STM32_TIMCLK1; } #endif #if STM32_ICU_USE_TIM4 @@ -318,7 +318,7 @@ void icu_lld_start(ICUDriver *icup) { rccResetTIM4(); NVICEnableVector(TIM4_IRQn, CORTEX_PRIORITY_MASK(STM32_ICU_TIM4_IRQ_PRIORITY)); - clock = STM32_TIMCLK1; + icup->clock = STM32_TIMCLK1; } #endif @@ -328,7 +328,7 @@ void icu_lld_start(ICUDriver *icup) { rccResetTIM5(); NVICEnableVector(TIM5_IRQn, CORTEX_PRIORITY_MASK(STM32_ICU_TIM5_IRQ_PRIORITY)); - clock = STM32_TIMCLK1; + icup->clock = STM32_TIMCLK1; } #endif #if STM32_ICU_USE_TIM8 @@ -337,7 +337,7 @@ void icu_lld_start(ICUDriver *icup) { rccResetTIM5(); NVICEnableVector(TIM8_CC_IRQn, CORTEX_PRIORITY_MASK(STM32_ICU_TIM8_IRQ_PRIORITY)); - clock = STM32_TIMCLK2; + icup->clock = STM32_TIMCLK2; } #endif } @@ -352,9 +352,9 @@ void icu_lld_start(ICUDriver *icup) { } /* Timer configuration.*/ - psc = (clock / icup->config->frequency) - 1; + psc = (icup->clock / icup->config->frequency) - 1; chDbgAssert((psc <= 0xFFFF) && - ((psc + 1) * icup->config->frequency) == clock, + ((psc + 1) * icup->config->frequency) == icup->clock, "icu_lld_start(), #1", "invalid frequency"); icup->tim->PSC = (uint16_t)psc; icup->tim->ARR = 0xFFFF; diff --git a/os/hal/platforms/STM32/icu_lld.h b/os/hal/platforms/STM32/icu_lld.h index e7321e794..4c440b868 100644 --- a/os/hal/platforms/STM32/icu_lld.h +++ b/os/hal/platforms/STM32/icu_lld.h @@ -233,6 +233,10 @@ struct ICUDriver { ICU_DRIVER_EXT_FIELDS #endif /* End of the mandatory fields.*/ + /** + * @brief Timer base clock. + */ + uint32_t clock; /** * @brief Pointer to the TIMx registers block. */ diff --git a/os/hal/platforms/STM32/pwm_lld.c b/os/hal/platforms/STM32/pwm_lld.c index 901474091..d8f98a432 100644 --- a/os/hal/platforms/STM32/pwm_lld.c +++ b/os/hal/platforms/STM32/pwm_lld.c @@ -341,7 +341,7 @@ void pwm_lld_init(void) { * @notapi */ void pwm_lld_start(PWMDriver *pwmp) { - uint32_t clock, psc; + uint32_t psc; uint16_t ccer; if (pwmp->state == PWM_STOP) { @@ -354,7 +354,7 @@ void pwm_lld_start(PWMDriver *pwmp) { CORTEX_PRIORITY_MASK(STM32_PWM_TIM1_IRQ_PRIORITY)); NVICEnableVector(TIM1_CC_IRQn, CORTEX_PRIORITY_MASK(STM32_PWM_TIM1_IRQ_PRIORITY)); - clock = STM32_TIMCLK2; + pwmp->clock = STM32_TIMCLK2; } #endif #if STM32_PWM_USE_TIM2 @@ -363,7 +363,7 @@ void pwm_lld_start(PWMDriver *pwmp) { rccResetTIM2(); NVICEnableVector(TIM2_IRQn, CORTEX_PRIORITY_MASK(STM32_PWM_TIM2_IRQ_PRIORITY)); - clock = STM32_TIMCLK1; + pwmp->clock = STM32_TIMCLK1; } #endif #if STM32_PWM_USE_TIM3 @@ -372,7 +372,7 @@ void pwm_lld_start(PWMDriver *pwmp) { rccResetTIM3(); NVICEnableVector(TIM3_IRQn, CORTEX_PRIORITY_MASK(STM32_PWM_TIM3_IRQ_PRIORITY)); - clock = STM32_TIMCLK1; + pwmp->clock = STM32_TIMCLK1; } #endif #if STM32_PWM_USE_TIM4 @@ -381,7 +381,7 @@ void pwm_lld_start(PWMDriver *pwmp) { rccResetTIM4(); NVICEnableVector(TIM4_IRQn, CORTEX_PRIORITY_MASK(STM32_PWM_TIM4_IRQ_PRIORITY)); - clock = STM32_TIMCLK1; + pwmp->clock = STM32_TIMCLK1; } #endif @@ -391,7 +391,7 @@ void pwm_lld_start(PWMDriver *pwmp) { rccResetTIM5(); NVICEnableVector(TIM5_IRQn, CORTEX_PRIORITY_MASK(STM32_PWM_TIM5_IRQ_PRIORITY)); - clock = STM32_TIMCLK1; + pwmp->clock = STM32_TIMCLK1; } #endif #if STM32_PWM_USE_TIM8 @@ -402,7 +402,7 @@ void pwm_lld_start(PWMDriver *pwmp) { CORTEX_PRIORITY_MASK(STM32_PWM_TIM8_IRQ_PRIORITY)); NVICEnableVector(TIM8_CC_IRQn, CORTEX_PRIORITY_MASK(STM32_PWM_TIM8_IRQ_PRIORITY)); - clock = STM32_TIMCLK2; + pwmp->clock = STM32_TIMCLK2; } #endif @@ -430,9 +430,9 @@ void pwm_lld_start(PWMDriver *pwmp) { } /* Timer configuration.*/ - psc = (clock / pwmp->config->frequency) - 1; + psc = (pwmp->clock / pwmp->config->frequency) - 1; chDbgAssert((psc <= 0xFFFF) && - ((psc + 1) * pwmp->config->frequency) == clock, + ((psc + 1) * pwmp->config->frequency) == pwmp->clock, "pwm_lld_start(), #1", "invalid frequency"); pwmp->tim->PSC = (uint16_t)psc; pwmp->tim->ARR = (uint16_t)(pwmp->period - 1); diff --git a/os/hal/platforms/STM32/pwm_lld.h b/os/hal/platforms/STM32/pwm_lld.h index fb5a83790..d084b3dc7 100644 --- a/os/hal/platforms/STM32/pwm_lld.h +++ b/os/hal/platforms/STM32/pwm_lld.h @@ -315,6 +315,10 @@ struct PWMDriver { PWM_DRIVER_EXT_FIELDS #endif /* End of the mandatory fields.*/ + /** + * @brief Timer base clock. + */ + uint32_t clock; /** * @brief Pointer to the TIMx registers block. */ -- cgit v1.2.3 From 7d30f4c821023de001cd4459c83a1fdae2f8cb07 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 24 Sep 2011 15:04:39 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3399 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32L1xx/adc_lld.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32L1xx/adc_lld.c b/os/hal/platforms/STM32L1xx/adc_lld.c index eeae18f68..bc04df615 100644 --- a/os/hal/platforms/STM32L1xx/adc_lld.c +++ b/os/hal/platforms/STM32L1xx/adc_lld.c @@ -188,15 +188,13 @@ void adc_lld_stop(ADCDriver *adcp) { * @notapi */ void adc_lld_start_conversion(ADCDriver *adcp) { - uint32_t mode, cr2; + uint32_t mode; const ADCConversionGroup *grpp = adcp->grpp; /* DMA setup.*/ mode = adcp->dmamode; - cr2 = grpp->cr2; if (grpp->circular) { mode |= STM32_DMA_CR_CIRC; - cr2 |= ADC_CR2_CONT; } if (adcp->depth > 1) { /* If the buffer depth is greater than one then the half transfer interrupt @@ -214,7 +212,8 @@ void adc_lld_start_conversion(ADCDriver *adcp) { adcp->adc->SMPR1 = grpp->smpr1; /* Writing SMPRx requires ADON=0. */ adcp->adc->SMPR2 = grpp->smpr2; adcp->adc->SMPR3 = grpp->smpr3; - adcp->adc->CR2 = cr2 | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON; + adcp->adc->CR2 = grpp->cr2 | ADC_CR2_CONT | ADC_CR2_DMA | ADC_CR2_DDS | + ADC_CR2_ADON; adcp->adc->SQR1 = grpp->sqr1; adcp->adc->SQR2 = grpp->sqr2; adcp->adc->SQR3 = grpp->sqr3; @@ -225,8 +224,8 @@ void adc_lld_start_conversion(ADCDriver *adcp) { while ((adcp->adc->SR & ADC_SR_ADONS) == 0) ; /* ADC start by raising ADC_CR2_SWSTART.*/ - adcp->adc->CR2 = cr2 | ADC_CR2_SWSTART | ADC_CR2_DMA | ADC_CR2_DDS | - ADC_CR2_ADON; + adcp->adc->CR2 = grpp->cr2 | ADC_CR2_SWSTART | ADC_CR2_CONT | ADC_CR2_DMA | + ADC_CR2_DDS | ADC_CR2_ADON; } /** -- cgit v1.2.3 From 00278617267aba8d6483bc0cc1290d771b6c2f93 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 25 Sep 2011 09:31:19 +0000 Subject: Documentation related fixes. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3403 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/stm32_dma.c | 1 + os/hal/platforms/STM32/DMAv1/stm32_dma.h | 2 +- os/hal/platforms/STM32/DMAv2/stm32_dma.c | 1 + os/hal/platforms/STM32/USBv1/usb_lld.c | 2 +- os/hal/platforms/STM32/USBv1/usb_lld.h | 2 +- os/hal/platforms/STM32F1xx/hal_lld_f100.h | 2 +- os/hal/platforms/STM32F1xx/hal_lld_f103.h | 2 +- os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h | 2 +- os/hal/platforms/STM32F1xx/platform.dox | 114 ++++++++++++++++++------- 9 files changed, 91 insertions(+), 37 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.c b/os/hal/platforms/STM32/DMAv1/stm32_dma.c index 29ee02360..3fb1b2dc6 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.c @@ -411,6 +411,7 @@ void dmaInit(void) { * @note This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] priority IRQ priority mask for the DMA stream * @param[in] func handling function pointer, can be @p NULL * @param[in] param a parameter to be passed to the handling function * @return The operation status. diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.h b/os/hal/platforms/STM32/DMAv1/stm32_dma.h index ca9c429f7..22be4a67e 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.h @@ -217,7 +217,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @brief DMA stream enable. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmachp pointer to a stm32_dma_stream_t structure + * @param[in] dmastp pointer to a stm32_dma_stream_t structure * * @special */ diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.c b/os/hal/platforms/STM32/DMAv2/stm32_dma.c index 2b6851ad6..70f412083 100644 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.c @@ -450,6 +450,7 @@ void dmaInit(void) { * @note This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] priority IRQ priority mask for the DMA stream * @param[in] func handling function pointer, can be @p NULL * @param[in] param a parameter to be passed to the handling function * @return The operation status. diff --git a/os/hal/platforms/STM32/USBv1/usb_lld.c b/os/hal/platforms/STM32/USBv1/usb_lld.c index b22f8f0da..01bc50090 100644 --- a/os/hal/platforms/STM32/USBv1/usb_lld.c +++ b/os/hal/platforms/STM32/USBv1/usb_lld.c @@ -19,7 +19,7 @@ */ /** - * @file STM32/usb_lld.c + * @file STM32/USBv1/usb_lld.c * @brief STM32 USB subsystem low level driver source. * * @addtogroup USB diff --git a/os/hal/platforms/STM32/USBv1/usb_lld.h b/os/hal/platforms/STM32/USBv1/usb_lld.h index 9b5e9dad2..47160af56 100644 --- a/os/hal/platforms/STM32/USBv1/usb_lld.h +++ b/os/hal/platforms/STM32/USBv1/usb_lld.h @@ -19,7 +19,7 @@ */ /** - * @file STM32/usb_lld.h + * @file STM32/USBv1/usb_lld.h * @brief STM32 USB subsystem low level driver header. * * @addtogroup USB diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f100.h b/os/hal/platforms/STM32F1xx/hal_lld_f100.h index 51cdf97e3..012cf0c11 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f100.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f100.h @@ -26,7 +26,7 @@ */ /** - * @file STM32/hal_lld_f100.h + * @file STM32F1xx/hal_lld_f100.h * @brief STM32F100 Value Line HAL subsystem low level driver header. * * @addtogroup STM32F100_HAL diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f103.h b/os/hal/platforms/STM32F1xx/hal_lld_f103.h index 9ba74d239..7f493ee01 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f103.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f103.h @@ -26,7 +26,7 @@ */ /** - * @file STM32/hal_lld_f103.h + * @file STM32F1xx/hal_lld_f103.h * @brief STM32F103 Performance Line HAL subsystem low level driver header. * * @addtogroup STM32F103_HAL diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h index 974b59f34..25e28c62d 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h @@ -26,7 +26,7 @@ */ /** - * @file STM32/hal_lld_f105_f107.h + * @file STM32F1xx/hal_lld_f105_f107.h * @brief STM32F10x Connectivity Line HAL subsystem low level driver header. * * @addtogroup STM32F10X_CL_HAL diff --git a/os/hal/platforms/STM32F1xx/platform.dox b/os/hal/platforms/STM32F1xx/platform.dox index de8d9a5d9..89f7520c5 100644 --- a/os/hal/platforms/STM32F1xx/platform.dox +++ b/os/hal/platforms/STM32F1xx/platform.dox @@ -19,7 +19,7 @@ */ /** - * @defgroup STM32F1xx_DRIVERS STM32F1xx Drivers + * @defgroup STM32_DRIVERS STM32F1xx Drivers * @details This section describes all the supported drivers on the STM32F1xx * platform and the implementation details of the single drivers. * @@ -27,7 +27,7 @@ */ /** - * @defgroup STM32F1xx_HAL STM32F1xx Initialization Support + * @defgroup STM32_HAL STM32F1xx Initialization Support * @details The STM32F1xx HAL support is responsible for system initialization. * * @section stm32f1xx_hal_1 Supported HW resources @@ -44,11 +44,11 @@ * - SYSTICK initialization based on current clock and kernel required rate. * - DMA support initialization. * . - * @ingroup STM32F1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32F1xx_ADC STM32F1xx ADC Support + * @defgroup STM32_ADC STM32F1xx ADC Support * @details The STM32F1xx ADC driver supports the ADC peripherals using DMA * channels for maximum performance. * @@ -64,11 +64,11 @@ * - Programmable DMA interrupt priority for each DMA channel. * - DMA errors detection. * . - * @ingroup STM32F1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32F1xx_CAN STM32F1xx CAN Support + * @defgroup STM32_CAN STM32F1xx CAN Support * @details The STM32F1xx CAN driver uses the CAN peripherals. * * @section stm32f1xx_can_1 Supported HW resources @@ -79,11 +79,11 @@ * - Support for bxCAN sleep mode. * - Programmable bxCAN interrupts priority level. * . - * @ingroup STM32F1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32F1xx_DMA STM32F1xx DMA Support + * @defgroup STM32_DMA STM32F1xx DMA Support * @details This DMA helper driver is used by the other drivers in order to * access the shared DMA resources in a consistent way. * @@ -98,11 +98,11 @@ * - Automatic DMA clock stop when not in use by any driver. * - DMA streams and interrupt vectors sharing among multiple drivers. * . - * @ingroup STM32F1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32F1xx_EXT STM32F1xx EXT Support + * @defgroup STM32_EXT STM32F1xx EXT Support * @details The STM32F1xx EXT driver uses the EXTI peripheral. * * @section stm32f1xx_ext_1 Supported HW resources @@ -113,11 +113,11 @@ * - Programmable EXTI interrupts priority level. * - Capability to work as event sources (WFE) rather than interrupt sources. * . - * @ingroup STM32F1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32F1xx_GPT STM32F1xx GPT Support + * @defgroup STM32_GPT STM32F1xx GPT Support * @details The STM32F1xx GPT driver uses the TIMx peripherals. * * @section stm32f1xx_gpt_1 Supported HW resources @@ -132,11 +132,27 @@ * peripherals are left in low power mode. * - Programmable TIMx interrupts priority level. * . - * @ingroup STM32F1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32F1xx_ICU STM32F1xx ICU Support + * @defgroup STM32_I2C STM32F1xx I2C Support + * @details The STM32F1xx I2C driver uses the I2Cx peripherals. + * + * @section stm32f1xx_i2c_1 Supported HW resources + * - I2C1. + * - I2C2. + * . + * @section stm32f1xx_i2c_2 STM32F1xx I2C driver implementation features + * - Each I2C port can be independently enabled and programmed. Unused + * peripherals are left in low power mode. + * - Programmable I2Cx interrupts priority level. + * . + * @ingroup STM32_DRIVERS + */ + +/** + * @defgroup STM32_ICU STM32F1xx ICU Support * @details The STM32F1xx ICU driver uses the TIMx peripherals. * * @section stm32f1xx_icu_1 Supported HW resources @@ -151,11 +167,21 @@ * peripherals are left in low power mode. * - Programmable TIMx interrupts priority level. * . - * @ingroup STM32F1xx_DRIVERS + * @ingroup STM32_DRIVERS + */ + +/** + * @defgroup STM32_MAC STM32 MAC Support + * @details The STM32 MAC driver supports the ETH peripheral. + * + * @section at91sam7_mac_1 Supported HW resources + * - ETH. + * . + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32F1xx_PAL STM32F1xx PAL Support + * @defgroup STM32_PAL STM32F1xx PAL Support * @details The STM32F1xx PAL driver uses the GPIO peripherals. * * @section stm32f1xx_pal_1 Supported HW resources @@ -187,8 +213,8 @@ * - @p PAL_MODE_INPUT_ANALOG. * - @p PAL_MODE_OUTPUT_PUSHPULL. * - @p PAL_MODE_OUTPUT_OPENDRAIN. - * - @p PAL_MODE_STM32F1xx_ALTERNATE_PUSHPULL (non standard). - * - @p PAL_MODE_STM32F1xx_ALTERNATE_OPENDRAIN (non standard). + * - @p PAL_MODE_STM32_ALTERNATE_PUSHPULL (non standard). + * - @p PAL_MODE_STM32_ALTERNATE_OPENDRAIN (non standard). * . * Any attempt to setup an invalid mode is ignored. * @@ -201,11 +227,11 @@ * resistor can change the resistor setting because the output latch is * used for resistor selection. * . - * @ingroup STM32F1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32F1xx_PWM STM32F1xx PWM Support + * @defgroup STM32_PWM STM32F1xx PWM Support * @details The STM32F1xx PWM driver uses the TIMx peripherals. * * @section stm32f1xx_pwm_1 Supported HW resources @@ -221,11 +247,37 @@ * - Four independent PWM channels per timer. * - Programmable TIMx interrupts priority level. * . - * @ingroup STM32F1xx_DRIVERS + * @ingroup STM32_DRIVERS + */ + +/** + * @defgroup STM32_RCC STM32F1xx RCC Support + * @details This RCC helper driver is used by the other drivers in order to + * access the shared RCC resources in a consistent way. + * + * @section stm32f1xx_rcc_1 Supported HW resources + * - RCC. + * . + * @section stm32f1xx_rcc_2 STM32F1xx RCC driver implementation features + * - Peripherals reset. + * - Peripherals clock enable. + * - Periplerals clock disable. + * . + * @ingroup STM32_DRIVERS + */ + +/** + * @defgroup STM32_RTC STM32F1xx RTC Support + * @details The STM32F1xx RTC driver uses the RTC peripheral. + * + * @section stm32f1xx_rtc_1 Supported HW resources + * - RTC. + * . + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32F1xx_SDC STM32F1xx SDC Support + * @defgroup STM32_SDC STM32F1xx SDC Support * @details The STM32F1xx SDC driver uses the SDIO peripheral. * * @section stm32f1xx_sdc_1 Supported HW resources @@ -238,11 +290,11 @@ * - DMA is used for receiving and transmitting. * - Programmable DMA bus priority for each DMA channel. * . - * @ingroup STM32F1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32F1xx_SERIAL STM32F1xx Serial Support + * @defgroup STM32_SERIAL STM32F1xx Serial Support * @details The STM32F1xx Serial driver uses the USART/UART peripherals in a * buffered, interrupt driven, implementation. * @@ -261,11 +313,11 @@ * - Fully interrupt driven. * - Programmable priority levels for each UART/USART. * . - * @ingroup STM32F1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32F1xx_SPI STM32F1xx SPI Support + * @defgroup STM32_SPI STM32F1xx SPI Support * @details The SPI driver supports the STM32F1xx SPI peripherals using DMA * channels for maximum performance. * @@ -286,11 +338,11 @@ * - Programmable DMA interrupt priority for each DMA channel. * - Programmable DMA error hook. * . - * @ingroup STM32F1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32F1xx_UART STM32F1xx UART Support + * @defgroup STM32_UART STM32F1xx UART Support * @details The UART driver supports the STM32F1xx USART peripherals using DMA * channels for maximum performance. * @@ -313,11 +365,11 @@ * - Programmable DMA interrupt priority for each DMA channel. * - Programmable DMA error hook. * . - * @ingroup STM32F1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32F1xx_USB STM32F1xx USB Support + * @defgroup STM32_USB STM32F1xx USB Support * @details The USB driver supports the STM32F1xx USB peripheral. * * @section stm32f1xx_usb_1 Supported HW resources @@ -329,5 +381,5 @@ * - Programmable interrupt priority levels. * - Each endpoint programmable in Control, Bulk and Interrupt modes. * . - * @ingroup STM32F1xx_DRIVERS + * @ingroup STM32_DRIVERS */ -- cgit v1.2.3 From 5edc2c8b69cd60a1c53b565e529e099c36a243c4 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 25 Sep 2011 09:34:48 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3404 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/platform.dox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/platform.dox b/os/hal/platforms/STM32F1xx/platform.dox index 89f7520c5..624a5b12f 100644 --- a/os/hal/platforms/STM32F1xx/platform.dox +++ b/os/hal/platforms/STM32F1xx/platform.dox @@ -171,7 +171,7 @@ */ /** - * @defgroup STM32_MAC STM32 MAC Support + * @defgroup STM32_MAC STM32F1xx MAC Support * @details The STM32 MAC driver supports the ETH peripheral. * * @section at91sam7_mac_1 Supported HW resources -- cgit v1.2.3 From 41fd0fb5fb2d446605e7a99c11f46d7c28071500 Mon Sep 17 00:00:00 2001 From: barthess Date: Sun, 25 Sep 2011 10:03:59 +0000 Subject: RTC. API changes. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3405 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/rtc.h | 18 +- os/hal/platforms/STM32/RTCv1/rtc_lld.c | 334 +++++++++++++++++++++++++++++++++ os/hal/platforms/STM32/RTCv1/rtc_lld.h | 131 +++++++++++++ os/hal/platforms/STM32/rtc_lld.c | 321 ------------------------------- os/hal/platforms/STM32/rtc_lld.h | 114 ----------- os/hal/platforms/STM32F1xx/platform.mk | 5 +- os/hal/src/rtc.c | 38 ++-- 7 files changed, 504 insertions(+), 457 deletions(-) create mode 100644 os/hal/platforms/STM32/RTCv1/rtc_lld.c create mode 100644 os/hal/platforms/STM32/RTCv1/rtc_lld.h delete mode 100644 os/hal/platforms/STM32/rtc_lld.c delete mode 100644 os/hal/platforms/STM32/rtc_lld.h (limited to 'os/hal') diff --git a/os/hal/include/rtc.h b/os/hal/include/rtc.h index 5adf9559c..02aec2ceb 100644 --- a/os/hal/include/rtc.h +++ b/os/hal/include/rtc.h @@ -74,10 +74,20 @@ extern "C" { rtccb_t secondcb, rtccb_t alarmcb); #endif /* RTC_SUPPORTS_CALLBACKS */ - void rtcSetTime(uint32_t tv_sec); - uint32_t rtcGetTime(uint16_t *msec); - void rtcSetAlarm(uint32_t tv_alarm); - uint32_t rtcGetAlarm(void); + void rtcSetTime(RTCDateTime *timespec); + void rtcGetTime(RTCDateTime *timespec); + + + + + void rtcSetAlarm(RTCDateTime *timespec); + void rtcGetAlarm(RTCDateTime *timespec); + + + + + + #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.c b/os/hal/platforms/STM32/RTCv1/rtc_lld.c new file mode 100644 index 000000000..a3329544e --- /dev/null +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.c @@ -0,0 +1,334 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/rtc_lld.c + * @brief STM32 RTC subsystem low level driver header. + * + * @addtogroup RTC + * @{ + */ + +#include "ch.h" +#include "hal.h" + + +#if HAL_USE_RTC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief RTC driver identifier.*/ +RTCDriver RTCD; + + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Shared IRQ handler. + * + * @param[in] rtcp pointer to a @p RTCDriver object + * + * @notapi + */ +#if RTC_SUPPORTS_CALLBACKS + +static void rtc_lld_serve_interrupt(RTCDriver *rtcp){ + chSysLockFromIsr(); + + if ((RTC->CRH & RTC_CRH_SECIE) && \ + (RTC->CRL & RTC_CRL_SECF) && \ + (rtcp->second_cb != NULL)){ + rtcp->second_cb(rtcp); + RTC->CRL &= ~RTC_CRL_SECF; + } + if ((RTC->CRH & RTC_CRH_ALRIE) && \ + (RTC->CRL & RTC_CRL_ALRF) && \ + (rtcp->alarm_cb != NULL)){ + rtcp->alarm_cb(rtcp); + RTC->CRL &= ~RTC_CRL_ALRF; + } + if ((RTC->CRH & RTC_CRH_OWIE) && \ + (RTC->CRL & RTC_CRL_OWF) && \ + (rtcp->overflow_cb != NULL)){ + rtcp->overflow_cb(rtcp); + RTC->CRL &= ~RTC_CRL_OWF; + } + + chSysUnlockFromIsr(); +} +#endif /* RTC_SUPPORTS_CALLBACKS */ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/** + * @brief RTC interrupt handler. + * @isr + */ +#if RTC_SUPPORTS_CALLBACKS + +CH_IRQ_HANDLER(RTC_IRQHandler) { + CH_IRQ_PROLOGUE(); + rtc_lld_serve_interrupt(&RTCD); + CH_IRQ_EPILOGUE(); +} + +#endif /* RTC_SUPPORTS_CALLBACKS */ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Enable access to registers and initialize RTC if BKP domain + * was previously reseted. + * + * @note: Cold start time of LSE oscillator on STM32 platform + * takes about 3 seconds. + * + * @notapi + */ +void rtc_lld_init(void){ + uint32_t preload = 0; + + rccEnableBKPInterface(FALSE); + + /* enable access to BKP registers */ + PWR->CR |= PWR_CR_DBP; + /* select clock source */ + RCC->BDCR |= STM32_RTC; + +#if STM32_RTC == STM32_RTC_LSE + if (! ((RCC->BDCR & RCC_BDCR_RTCEN) || (RCC->BDCR & RCC_BDCR_LSEON))){ + RCC->BDCR |= RCC_BDCR_LSEON; + while(!(RCC->BDCR & RCC_BDCR_LSERDY)) + ; + RCC->BDCR |= RCC_BDCR_RTCEN; + } + preload = STM32_LSECLK - 1; + +#elif STM32_RTC == STM32_RTC_LSI + RCC->CSR |= RCC_CSR_LSION; + while(!(RCC->CSR & RCC_CSR_LSIRDY)) + ; + /* According to errata sheet we must wait additional 100 uS for stabilization */ + uint32_t tmo = (STM32_SYSCLK / 1000000 ) * 100; + while(tmo--) + ; + RCC->BDCR |= RCC_BDCR_RTCEN; + preload = STM32_LSICLK - 1; + +#elif STM32_RTC == STM32_RTC_HSE + preload = (STM32_HSICLK / 128) - 1; + +#else +#error "RTC clock source not selected" +#endif + + /* Ensure that RTC_CNT and RTC_DIV contain actual values after enabling + * clocking on APB1, because these values only update when APB1 functioning.*/ + RTC->CRL &= ~(RTC_CRL_RSF); + while (!(RTC->CRL & RTC_CRL_RSF)) + ; + + /* Write preload register only if its value changed */ + if (preload != ((((uint32_t)(RTC->PRLH)) << 16) + RTC->PRLL)){ + while(!(RTC->CRL & RTC_CRL_RTOFF)) + ; + + RTC->CRL |= RTC_CRL_CNF; /* switch on configure mode */ + RTC->PRLH = (uint16_t)((preload >> 16) & 0b1111); /* write preloader */ + RTC->PRLL = (uint16_t)(preload & 0xFFFF); + RTC->CRL &= ~RTC_CRL_CNF; /* switch off configure mode */ + + while(!(RTC->CRL & RTC_CRL_RTOFF)) /* wait for completion */ + ; + } + + /* disable all interrupts and clear all even flags just to be safe */ + RTC->CRH &= ~(RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE); + RTC->CRL &= ~(RTC_CRL_SECF | RTC_CRL_ALRF | RTC_CRL_OWF); + +#if RTC_SUPPORTS_CALLBACKS + RTCD.alarm_cb = NULL; + RTCD.overflow_cb = NULL; + RTCD.second_cb = NULL; +#endif /* RTC_SUPPORTS_CALLBACKS */ +} + +/** + * @brief Enables and disables callbacks on the fly. + * + * @details Pass callback function(s) in argument(s) to enable callback(s). + * Pass NULL to disable callback. + * + * @pre To use this function you must set @p RTC_SUPPORTS_CALLBACKS + * to @p TRUE. + * + * @param[in] rtcp pointer to RTC driver structure. + * @param[in] overflowcb overflow callback function. + * @param[in] secondcb every second callback function. + * @param[in] alarmcb alarm callback function. + * + * @notapi + */ +#if RTC_SUPPORTS_CALLBACKS +void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t overflowcb, + rtccb_t secondcb, rtccb_t alarmcb){ + + uint16_t isr_flags = 0; + + if (overflowcb != NULL){ + rtcp->overflow_cb = *overflowcb; + isr_flags |= RTC_CRH_OWIE; + } + else{ + rtcp->overflow_cb = NULL; + isr_flags &= ~RTC_CRH_OWIE; + } + + if (alarmcb != NULL){ + rtcp->alarm_cb = *alarmcb; + isr_flags |= RTC_CRH_ALRIE; + } + else{ + rtcp->alarm_cb = NULL; + isr_flags &= ~RTC_CRH_ALRIE; + } + + if (secondcb != NULL){ + rtcp->second_cb = *secondcb; + isr_flags |= RTC_CRH_SECIE; + } + else{ + rtcp->second_cb = NULL; + isr_flags &= ~RTC_CRH_SECIE; + } + + if(isr_flags != 0){ + NVICEnableVector(RTC_IRQn, CORTEX_PRIORITY_MASK(STM32_RTC_IRQ_PRIORITY)); + RTC->CRH |= isr_flags; + } + else{ + NVICDisableVector(RTC_IRQn); + RTC->CRH = 0; + } +} +#endif /* RTC_SUPPORTS_CALLBACKS */ + +/** + * @brief Set current time. + * + * @param[in] timespec pointer to variable storing time. + * + * @note Fractional part will be silently ignored. There is no possibility + * to change it on STM32F1xx platform. + * @notapi + */ +void rtc_lld_set_time(RTCDateTime *timespec){ + + while(!(RTC->CRL & RTC_CRL_RTOFF)) + ; + + RTC->CRL |= RTC_CRL_CNF; /* switch on configure mode */ + RTC->CNTH = (uint16_t)((timespec->tv_sec >> 16) & 0xFFFF); + RTC->CNTL = (uint16_t)(timespec->tv_sec & 0xFFFF); + RTC->CRL &= ~RTC_CRL_CNF; /* switch off configure mode */ + + while(!(RTC->CRL & RTC_CRL_RTOFF)) /* wait for completion */ + ; +} + +/** + * @brief Get current time. + * + * @param[in] msec pointer to variable for storing fractional part of + * time (milliseconds). + * + * @notapi + */ +inline void rtc_lld_get_time(RTCDateTime *timespec){ + uint32_t time_frac = 0; + time_frac = (((uint32_t)RTC->DIVH) << 16) + (RTC->DIVL); + + timespec->tv_msec = (uint16_t)(((STM32_LSECLK - time_frac) * 1000) / STM32_LSECLK); + timespec->tv_sec = (RTC->CNTH << 16) + RTC->CNTL; +} + +/** + * @brief Set alarm time. + * + * @param[in] timespec pointer to variable storing time of alarm. + * + * @note Fractional part will be silently ignored. There is no possibility + * to change it on STM32F1xx platform. + * + * @note Default value after BKP domain reset is 0xFFFFFFFF + * + * @notapi + */ +void rtc_lld_set_alarm(RTCDateTime *timespec){ + + while(!(RTC->CRL & RTC_CRL_RTOFF)) + ; + + RTC->CRL |= RTC_CRL_CNF; /* switch on configure mode */ + RTC->ALRH = (uint16_t)((timespec->tv_sec >> 16) & 0xFFFF); + RTC->ALRL = (uint16_t)(timespec->tv_sec & 0xFFFF); + RTC->CRL &= ~RTC_CRL_CNF; /* switch off configure mode */ + +#if !(RTC_SUPPORTS_CALLBACKS) + RTC->CRL &= ~RTC_CRL_ALRF; + RTC->CRH |= RTC_CRH_ALRIE; +#endif /* !(RTC_SUPPORTS_CALLBACKS) */ + + while(!(RTC->CRL & RTC_CRL_RTOFF)) /* wait for completion */ + ; +} + +/** + * @brief Get current alarm time. + * + * @param[in] timespec pointer to variable storing time of alarm. + * + * @note Fractional part will be silently ignored. There is no possibility + * to change it on STM32F1xx platform. + * + * @note Default value after BKP domain reset is 0xFFFFFFFF + * + * @notapi + */ +inline void rtc_lld_get_alarm(RTCDateTime *timespec){ + timespec->tv_sec = ((RTC->ALRH << 16) + RTC->ALRL); +} + + +#endif /* HAL_USE_RTC */ + +/** @} */ diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.h b/os/hal/platforms/STM32/RTCv1/rtc_lld.h new file mode 100644 index 000000000..125b6c11e --- /dev/null +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.h @@ -0,0 +1,131 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/rtc_lld.h + * @brief STM32 RTC subsystem low level driver header. + * + * @addtogroup RTC + * @{ + */ + +#ifndef _RTC_LLD_H_ +#define _RTC_LLD_H_ + +#if HAL_USE_RTC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ +/** + * @brief Switch to TRUE if you need callbacks from RTC. Switch to FALSE + * if you need only time keeping. + * @note Default is true. + */ +#if !defined(RTC_SUPPORTS_CALLBACKS) || defined(__DOXYGEN__) +#define RTC_SUPPORTS_CALLBACKS TRUE +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if HAL_USE_RTC && !STM32_HAS_RTC +#error "RTC not present in the selected device" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + + + + + +typedef struct { + uint32_t tv_sec; + uint32_t tv_msec; +}RTCDateTime; + + + + + + + +/** + * @brief Structure representing an RTC driver. + * @note This driver if dummy when callbacks disabled. + */ +struct RTCDriver{ +#if RTC_SUPPORTS_CALLBACKS + /** + * @brief Overflow callback. Set it to NULL if not used. + */ + rtccb_t overflow_cb; + + /** + * @brief Every second callback. Set it to NULL if not used. + */ + rtccb_t second_cb; + + /** + * @brief Alarm callback. Set it to NULL if not used. + */ + rtccb_t alarm_cb; +#endif /* RTC_SUPPORTS_CALLBACKS */ +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +extern RTCDriver RTCD; + + +#ifdef __cplusplus +extern "C" { +#endif + void rtc_lld_init(void); + void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t overflow_cb, + rtccb_t second_cb, rtccb_t alarm_cb); + + void rtc_lld_set_time(RTCDateTime *timespec); + void rtc_lld_get_time(RTCDateTime *timespec); + + void rtc_lld_get_alarm(RTCDateTime *timespec); + void rtc_lld_set_alarm(RTCDateTime *timespec); +#ifdef __cplusplus +} +#endif + + +#endif /* HAL_USE_RTC */ +#endif /* _RTC_LLD_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32/rtc_lld.c b/os/hal/platforms/STM32/rtc_lld.c deleted file mode 100644 index c1163d1a1..000000000 --- a/os/hal/platforms/STM32/rtc_lld.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT 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 STM32/rtc_lld.c - * @brief STM32 RTC subsystem low level driver header. - * - * @addtogroup RTC - * @{ - */ - -#include "ch.h" -#include "hal.h" - - -#if HAL_USE_RTC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** @brief RTC driver identifier.*/ -RTCDriver RTCD; - - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Shared IRQ handler. - * - * @param[in] rtcp pointer to a @p RTCDriver object - * - * @notapi - */ -#if RTC_SUPPORTS_CALLBACKS - -static void rtc_lld_serve_interrupt(RTCDriver *rtcp){ - chSysLockFromIsr(); - - if ((RTC->CRH & RTC_CRH_SECIE) && \ - (RTC->CRL & RTC_CRL_SECF) && \ - (rtcp->second_cb != NULL)){ - rtcp->second_cb(rtcp); - RTC->CRL &= ~RTC_CRL_SECF; - } - if ((RTC->CRH & RTC_CRH_ALRIE) && \ - (RTC->CRL & RTC_CRL_ALRF) && \ - (rtcp->alarm_cb != NULL)){ - rtcp->alarm_cb(rtcp); - RTC->CRL &= ~RTC_CRL_ALRF; - } - if ((RTC->CRH & RTC_CRH_OWIE) && \ - (RTC->CRL & RTC_CRL_OWF) && \ - (rtcp->overflow_cb != NULL)){ - rtcp->overflow_cb(rtcp); - RTC->CRL &= ~RTC_CRL_OWF; - } - - chSysUnlockFromIsr(); -} -#endif /* RTC_SUPPORTS_CALLBACKS */ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/** - * @brief RTC interrupt handler. - * @isr - */ -#if RTC_SUPPORTS_CALLBACKS - -CH_IRQ_HANDLER(RTC_IRQHandler) { - CH_IRQ_PROLOGUE(); - rtc_lld_serve_interrupt(&RTCD); - CH_IRQ_EPILOGUE(); -} - -#endif /* RTC_SUPPORTS_CALLBACKS */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Enable access to registers and initialize RTC if BKP domain - * was previously reseted. - * - * @note: Cold start time of LSE oscillator on STM32 platform - * takes about 3 seconds. - * - * @notapi - */ -void rtc_lld_init(void){ - uint32_t preload = 0; - - rccEnableBKPInterface(FALSE); - - /* enable access to BKP registers */ - PWR->CR |= PWR_CR_DBP; - /* select clock source */ - RCC->BDCR |= STM32_RTC; - -#if STM32_RTC == STM32_RTC_LSE - if (! ((RCC->BDCR & RCC_BDCR_RTCEN) || (RCC->BDCR & RCC_BDCR_LSEON))){ - RCC->BDCR |= RCC_BDCR_LSEON; - while(!(RCC->BDCR & RCC_BDCR_LSERDY)) - ; - RCC->BDCR |= RCC_BDCR_RTCEN; - } - preload = STM32_LSECLK - 1; - -#elif STM32_RTC == STM32_RTC_LSI - RCC->CSR |= RCC_CSR_LSION; - while(!(RCC->CSR & RCC_CSR_LSIRDY)) - ; - /* According to errata sheet we must wait additional 100 uS for stabilization */ - uint32_t tmo = (STM32_SYSCLK / 1000000 ) * 100; - while(tmo--) - ; - RCC->BDCR |= RCC_BDCR_RTCEN; - preload = STM32_LSICLK - 1; - -#elif STM32_RTC == STM32_RTC_HSE - preload = (STM32_HSICLK / 128) - 1; - -#else -#error "RTC clock source not selected" -#endif - - /* Ensure that RTC_CNT and RTC_DIV contain actual values after enabling - * clocking on APB1, because these values only update when APB1 functioning.*/ - RTC->CRL &= ~(RTC_CRL_RSF); - while (!(RTC->CRL & RTC_CRL_RSF)) - ; - - /* Write preload register only if its value changed */ - if (preload != ((((uint32_t)(RTC->PRLH)) << 16) + RTC->PRLL)){ - while(!(RTC->CRL & RTC_CRL_RTOFF)) - ; - - RTC->CRL |= RTC_CRL_CNF; /* switch on configure mode */ - RTC->PRLH = (uint16_t)((preload >> 16) & 0b1111); /* write preloader */ - RTC->PRLL = (uint16_t)(preload & 0xFFFF); - RTC->CRL &= ~RTC_CRL_CNF; /* switch off configure mode */ - - while(!(RTC->CRL & RTC_CRL_RTOFF)) /* wait for completion */ - ; - } - - /* disable all interrupts and clear all even flags just to be safe */ - RTC->CRH &= ~(RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE); - RTC->CRL &= ~(RTC_CRL_SECF | RTC_CRL_ALRF | RTC_CRL_OWF); - -#if RTC_SUPPORTS_CALLBACKS - RTCD.alarm_cb = NULL; - RTCD.overflow_cb = NULL; - RTCD.second_cb = NULL; -#endif /* RTC_SUPPORTS_CALLBACKS */ -} - -/** - * @brief Enables and disables callbacks on the fly. - * - * @details Pass callback function(s) in argument(s) to enable callback(s). - * Pass NULL to disable callback. - * - * @pre To use this function you must set @p RTC_SUPPORTS_CALLBACKS - * to @p TRUE. - * - * @param[in] rtcp pointer to RTC driver structure. - * @param[in] overflowcb overflow callback function. - * @param[in] secondcb every second callback function. - * @param[in] alarmcb alarm callback function. - * - * @notapi - */ -#if RTC_SUPPORTS_CALLBACKS -void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t overflowcb, - rtccb_t secondcb, rtccb_t alarmcb){ - - uint16_t isr_flags = 0; - - if (overflowcb != NULL){ - rtcp->overflow_cb = *overflowcb; - isr_flags |= RTC_CRH_OWIE; - } - else{ - rtcp->overflow_cb = NULL; - isr_flags &= ~RTC_CRH_OWIE; - } - - if (alarmcb != NULL){ - rtcp->alarm_cb = *alarmcb; - isr_flags |= RTC_CRH_ALRIE; - } - else{ - rtcp->alarm_cb = NULL; - isr_flags &= ~RTC_CRH_ALRIE; - } - - if (secondcb != NULL){ - rtcp->second_cb = *secondcb; - isr_flags |= RTC_CRH_SECIE; - } - else{ - rtcp->second_cb = NULL; - isr_flags &= ~RTC_CRH_SECIE; - } - - if(isr_flags != 0){ - NVICEnableVector(RTC_IRQn, CORTEX_PRIORITY_MASK(STM32_RTC_IRQ_PRIORITY)); - RTC->CRH |= isr_flags; - } - else{ - NVICDisableVector(RTC_IRQn); - RTC->CRH = 0; - } -} -#endif /* RTC_SUPPORTS_CALLBACKS */ - -/** - * @brief Set current time. - * - * @param[in] tv_sec time value in UNIX notation. - * - * @notapi - */ -void rtc_lld_set_time(uint32_t tv_sec){ - - while(!(RTC->CRL & RTC_CRL_RTOFF)) - ; - - RTC->CRL |= RTC_CRL_CNF; /* switch on configure mode */ - RTC->CNTH = (uint16_t)((tv_sec >> 16) & 0xFFFF); /* write time */ - RTC->CNTL = (uint16_t)(tv_sec & 0xFFFF); - RTC->CRL &= ~RTC_CRL_CNF; /* switch off configure mode */ - - while(!(RTC->CRL & RTC_CRL_RTOFF)) /* wait for completion */ - ; -} - -/** - * @brief Return return seconds since UNIX epoch. - * - * @param[in] msec pointer to variable for storing fractional part of - * time (milliseconds). - * - * @notapi - */ -inline uint32_t rtc_lld_get_time(uint16_t *msec){ - uint32_t time_frac = 0; - if(msec != NULL){ - time_frac = (((uint32_t)RTC->DIVH) << 16) + (RTC->DIVL); - *msec = (uint16_t)(((STM32_LSECLK - time_frac) * 1000) / STM32_LSECLK); - } - return ((RTC->CNTH << 16) + RTC->CNTL); -} - -/** - * @brief Set alarm date in UNIX notation. - * @note Default value after BKP domain reset is 0xFFFFFFFF - * - * @notapi - */ -void rtc_lld_set_alarm(uint32_t tv_alarm){ - - while(!(RTC->CRL & RTC_CRL_RTOFF)) - ; - - RTC->CRL |= RTC_CRL_CNF; /* switch on configure mode */ - RTC->ALRH = (uint16_t)((tv_alarm >> 16) & 0xFFFF); /* write time */ - RTC->ALRL = (uint16_t)(tv_alarm & 0xFFFF); - RTC->CRL &= ~RTC_CRL_CNF; /* switch off configure mode */ - -#if !(RTC_SUPPORTS_CALLBACKS) - RTC->CRL &= ~RTC_CRL_ALRF; - RTC->CRH |= RTC_CRH_ALRIE; -#endif /* !(RTC_SUPPORTS_CALLBACKS) */ - - while(!(RTC->CRL & RTC_CRL_RTOFF)) /* wait for completion */ - ; -} - -/** - * @brief Get current alarm date in UNIX notation. - * @note Default value after BKP domain reset is 0xFFFFFFFF - * - * @notapi - */ -inline uint32_t rtc_lld_get_alarm(void){ - return ((RTC->ALRH << 16) + RTC->ALRL); -} - - -#endif /* HAL_USE_RTC */ - -/** @} */ diff --git a/os/hal/platforms/STM32/rtc_lld.h b/os/hal/platforms/STM32/rtc_lld.h deleted file mode 100644 index d73d35091..000000000 --- a/os/hal/platforms/STM32/rtc_lld.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT 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 STM32/rtc_lld.h - * @brief STM32 RTC subsystem low level driver header. - * - * @addtogroup RTC - * @{ - */ - -#ifndef _RTC_LLD_H_ -#define _RTC_LLD_H_ - -#if HAL_USE_RTC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ -/** - * @brief Switch to TRUE if you need callbacks from RTC. Switch to FALSE - * if you need only time keeping. - * @note Default is true. - */ -#if !defined(RTC_SUPPORTS_CALLBACKS) || defined(__DOXYGEN__) -#define RTC_SUPPORTS_CALLBACKS TRUE -#endif - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if HAL_USE_RTC && !STM32_HAS_RTC -#error "RTC not present in the selected device" -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Structure representing an RTC driver. - * @note This driver if dummy when callbacks disabled. - */ -struct RTCDriver{ -#if RTC_SUPPORTS_CALLBACKS - /** - * @brief Overflow callback. Set it to NULL if not used. - */ - rtccb_t overflow_cb; - - /** - * @brief Every second callback. Set it to NULL if not used. - */ - rtccb_t second_cb; - - /** - * @brief Alarm callback. Set it to NULL if not used. - */ - rtccb_t alarm_cb; -#endif /* RTC_SUPPORTS_CALLBACKS */ -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -extern RTCDriver RTCD; - - -#ifdef __cplusplus -extern "C" { -#endif - void rtc_lld_init(void); - void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t overflow_cb, - rtccb_t second_cb, rtccb_t alarm_cb); - void rtc_lld_set_time(uint32_t tv_sec); - uint32_t rtc_lld_get_time(uint16_t *msec); - uint32_t rtc_lld_get_alarm(void); - void rtc_lld_set_alarm(uint32_t); -#ifdef __cplusplus -} -#endif - - -#endif /* HAL_USE_RTC */ -#endif /* _RTC_LLD_H_ */ - -/** @} */ diff --git a/os/hal/platforms/STM32F1xx/platform.mk b/os/hal/platforms/STM32F1xx/platform.mk index 51601731e..a73f1b4f3 100644 --- a/os/hal/platforms/STM32F1xx/platform.mk +++ b/os/hal/platforms/STM32F1xx/platform.mk @@ -15,11 +15,12 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F1xx/hal_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv1/pal_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/DMAv1/stm32_dma.c \ ${CHIBIOS}/os/hal/platforms/STM32/USBv1/usb_lld.c \ - ${CHIBIOS}/os/hal/platforms/STM32/rtc_lld.c + ${CHIBIOS}/os/hal/platforms/STM32/RTCv1/rtc_lld.c # Required include directories PLATFORMINC = ${CHIBIOS}/os/hal/platforms/STM32F1xx \ ${CHIBIOS}/os/hal/platforms/STM32 \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv1 \ ${CHIBIOS}/os/hal/platforms/STM32/DMAv1 \ - ${CHIBIOS}/os/hal/platforms/STM32/USBv1 + ${CHIBIOS}/os/hal/platforms/STM32/USBv1 \ + ${CHIBIOS}/os/hal/platforms/STM32/RTCv1 diff --git a/os/hal/src/rtc.c b/os/hal/src/rtc.c index 3b4b5824b..0c8959ea6 100644 --- a/os/hal/src/rtc.c +++ b/os/hal/src/rtc.c @@ -83,36 +83,42 @@ void rtcSetCallback(RTCDriver *rtcp, rtccb_t overflowcb, /** * @brief Set current time. - * @param[in] tv_sec - time value in UNIX notation. + * + * @param[in] timespec pointer to variable storing time. */ -void rtcSetTime(uint32_t tv_sec){ - rtc_lld_set_time(tv_sec); +void rtcSetTime(RTCDateTime *timespec){ + chDbgCheck((timespec != NULL), "rtcSetTime"); + rtc_lld_set_time(timespec); } /** - * @brief Return return seconds since UNIX epoch. - * - * @param[in] msec pointer to variable for storing fractional part of - * time (milliseconds). + * @brief Get current time. * - * @notapi + * @param[in] timespec pointer to variable storing time. */ -inline uint32_t rtcGetTime(uint16_t *msec){ - return rtc_lld_get_time(msec); +void rtcGetTime(RTCDateTime *timespec){ + chDbgCheck((timespec != NULL), "rtcGetTime"); + rtc_lld_get_time(timespec); } /** - * @brief Set alarm date in UNIX notation. + * @brief Set alarm time. + * + * @param[in] timespec pointer to variable storing time of alarm. */ -void rtcSetAlarm(uint32_t tv_alarm){ - rtc_lld_set_alarm(tv_alarm); +void rtcSetAlarm(RTCDateTime *timespec){ + chDbgCheck((timespec != NULL), "rtcSetAlarm"); + rtc_lld_set_alarm(timespec); } /** - * @brief Get current alarm date in UNIX notation. + * @brief Get current alarm. + * + * @param[in] timespec pointer to variable to store alarm time. */ -inline uint32_t rtcGetAlarm(void){ - return rtc_lld_get_alarm(); +void rtcGetAlarm(RTCDateTime *timespec){ + chDbgCheck((timespec != NULL), "rtcGetAlarm"); + rtc_lld_get_alarm(timespec); } #endif /* HAL_USE_RTC */ -- cgit v1.2.3 From 17a20fe36a9356f8d73088ad0411486710210e24 Mon Sep 17 00:00:00 2001 From: barthess Date: Sun, 25 Sep 2011 10:06:23 +0000 Subject: RTC. Documentation improvements. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3406 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/RTCv1/rtc_lld.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.h b/os/hal/platforms/STM32/RTCv1/rtc_lld.h index 125b6c11e..37f8e105e 100644 --- a/os/hal/platforms/STM32/RTCv1/rtc_lld.h +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.h @@ -59,24 +59,24 @@ /* Driver data structures and types. */ /*===========================================================================*/ - - - - +/** + * @brief Structure representing an RTC time value. + */ typedef struct { + /** + * @brief Seconds sins UNIX epoch. + */ uint32_t tv_sec; + /** + * @brief Fractional part. + */ uint32_t tv_msec; }RTCDateTime; - - - - - /** * @brief Structure representing an RTC driver. - * @note This driver if dummy when callbacks disabled. + * @note This driver is dummy when callbacks disabled. */ struct RTCDriver{ #if RTC_SUPPORTS_CALLBACKS -- cgit v1.2.3 From fa0a7f52dbe51185794b3fa5c0279738790ee131 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 25 Sep 2011 10:11:49 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3407 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/i2c.h | 105 ++++++++++++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 55 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h index acf09ec9c..cf4d47713 100644 --- a/os/hal/include/i2c.h +++ b/os/hal/include/i2c.h @@ -34,24 +34,27 @@ /*===========================================================================*/ /* Driver constants. */ /*===========================================================================*/ + /*===========================================================================*/ /* Driver constants. */ /*===========================================================================*/ -#define I2CD_NO_ERROR 0 -/** @brief Bus Error.*/ -#define I2CD_BUS_ERROR 0x01 -/** @brief Arbitration Lost (master mode).*/ -#define I2CD_ARBITRATION_LOST 0x02 -/** @brief Acknowledge Failure.*/ -#define I2CD_ACK_FAILURE 0x04 -/** @brief Overrun/Underrun.*/ -#define I2CD_OVERRUN 0x08 -/** @brief PEC Error in reception.*/ -#define I2CD_PEC_ERROR 0x10 -/** @brief Timeout or Tlow Error.*/ -#define I2CD_TIMEOUT 0x20 -/** @brief SMBus Alert.*/ -#define I2CD_SMB_ALERT 0x40 + +/** + * @name I2C bus error conditions + * @{ + */ +#define I2CD_NO_ERROR 0x00 /**< @brief No error. */ +#define I2CD_BUS_ERROR 0x01 /**< @brief Bus Error. */ +#define I2CD_ARBITRATION_LOST 0x02 /**< @brief Arbitration Lost + (master mode). */ +#define I2CD_ACK_FAILURE 0x04 /**< @brief Acknowledge Failure.*/ +#define I2CD_OVERRUN 0x08 /**< @brief Overrun/Underrun. */ +#define I2CD_PEC_ERROR 0x10 /**< @brief PEC Error in + reception. */ +#define I2CD_TIMEOUT 0x20 /**< @brief Timeout Error. */ +#define I2CD_SMB_ALERT 0x40 /**< @brief SMBus Alert. */ +/** @} */ + /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ @@ -66,6 +69,7 @@ /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ + #if I2C_USE_MUTUAL_EXCLUSION && !CH_USE_MUTEXES && !CH_USE_SEMAPHORES #error "I2C_USE_MUTUAL_EXCLUSION requires CH_USE_MUTEXES and/or CH_USE_SEMAPHORES" #endif @@ -78,27 +82,20 @@ * @brief Driver state machine possible states. */ typedef enum { - /* master part */ - I2C_UNINIT = 0, /**< @brief Not initialized. */ - I2C_STOP = 1, /**< @brief Stopped. */ - I2C_READY = 2, /**< @brief Ready. */ - I2C_ACTIVE_TRANSMIT = 3, /**< @brief Transmit in progress. */ - I2C_ACTIVE_RECEIVE = 4, /**< @brief Receive in progress. */ - I2C_ACTIVE_TRANSCEIVE = 5, /**< @brief Receive after transmit in progress. */ - - /* Slave part. Not realized. */ - I2C_SACTIVE = 10, - I2C_STRANSMIT = 11, - I2C_SRECEIVE = 12, + I2C_UNINIT = 0, /**< Not initialized. */ + I2C_STOP = 1, /**< Stopped. */ + I2C_READY = 2, /**< Ready. */ + I2C_ACTIVE_TRANSMIT = 3, /**< Transmitting. */ + I2C_ACTIVE_RECEIVE = 4, /**< Receiving. */ + I2C_ACTIVE_TRANSCEIVE = 5, /**< Receiving after transmit. */ } i2cstate_t; - #include "i2c_lld.h" /** * @brief I2C notification callback type. * @details This callback invoked when byte transfer finish event occurs, - * No matter sending or reading. + * no matter if sending or reading. * * @param[in] i2cp pointer to the @p I2CDriver object triggering the * callback @@ -107,7 +104,6 @@ typedef enum { */ typedef void (*i2ccallback_t)(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg); - /** * @brief I2C error notification callback type. * @@ -119,13 +115,11 @@ typedef void (*i2ccallback_t)(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg); typedef void (*i2cerrorcallback_t)(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg); - /** - * @brief I2C transmission data block size. + * @brief I2C transmission data block size. */ typedef uint8_t i2cblock_t; - /** * @brief Structure representing an I2C slave configuration. * @details Each slave device has its own config structure with input and @@ -138,7 +132,6 @@ struct I2CSlaveConfig{ * If set to @p NULL then the callback is disabled. */ i2ccallback_t id_callback; - /** * @brief Callback pointer. * @note This callback will be invoked when error condition occur. @@ -150,7 +143,6 @@ struct I2CSlaveConfig{ #endif }; - /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ @@ -209,17 +201,18 @@ struct I2CSlaveConfig{ * implementation only. * * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] i2cscfg pointer to the @p I2CSlaveConfig object * * @notapi */ -#define _i2c_isr_code(i2cp, i2cscfg) { \ - if(((i2cp)->id_slave_config)->id_callback) { \ - ((i2cp)->id_slave_config)->id_callback(i2cp, i2cscfg); \ - (i2cp)->id_state = I2C_READY; \ - } \ - else \ - (i2cp)->id_state = I2C_READY; \ - _i2c_wakeup_isr(i2cp); \ +#define _i2c_isr_code(i2cp, i2cscfg) { \ + if(((i2cp)->id_slave_config)->id_callback) { \ + ((i2cp)->id_slave_config)->id_callback(i2cp, i2cscfg); \ + (i2cp)->id_state = I2C_READY; \ + } \ + else \ + (i2cp)->id_state = I2C_READY; \ + _i2c_wakeup_isr(i2cp); \ } /** @@ -233,22 +226,24 @@ struct I2CSlaveConfig{ * implementation only. * * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] i2cscfg pointer to the @p I2CSlaveConfig object * * @notapi */ -#define _i2c_isr_err_code(i2cp, i2cscfg) { \ - if(((i2cp)->id_slave_config)->id_err_callback) { \ - ((i2cp)->id_slave_config)->id_err_callback(i2cp, i2cscfg); \ - (i2cp)->id_state = I2C_READY; \ - } \ - else \ - (i2cp)->id_state = I2C_READY; \ - _i2c_wakeup_isr(i2cp); \ +#define _i2c_isr_err_code(i2cp, i2cscfg) { \ + if(((i2cp)->id_slave_config)->id_err_callback) { \ + ((i2cp)->id_slave_config)->id_err_callback(i2cp, i2cscfg); \ + (i2cp)->id_state = I2C_READY; \ + } \ + else \ + (i2cp)->id_state = I2C_READY; \ + _i2c_wakeup_isr(i2cp); \ } /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ + #ifdef __cplusplus extern "C" { #endif @@ -257,11 +252,11 @@ extern "C" { void i2cStart(I2CDriver *i2cp, const I2CConfig *config); void i2cStop(I2CDriver *i2cp); void i2cMasterTransmit(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg, - uint16_t slave_addr, - uint8_t *txbuf, size_t txbytes, - uint8_t *rxbuf, size_t rxbytes); + uint16_t slave_addr, + uint8_t *txbuf, size_t txbytes, + uint8_t *rxbuf, size_t rxbytes); void i2cMasterReceive(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg, - uint16_t slave_addr, uint8_t *rxbuf, size_t rxbytes); + uint16_t slave_addr, uint8_t *rxbuf, size_t rxbytes); void i2cMasterStart(I2CDriver *i2cp); void i2cMasterStop(I2CDriver *i2cp); void i2cAddFlagsI(I2CDriver *i2cp, i2cflags_t mask); -- cgit v1.2.3 From 0af85bab42eda2d80ce6efd2a0c1f5a94bad5f34 Mon Sep 17 00:00:00 2001 From: barthess Date: Sun, 25 Sep 2011 10:32:39 +0000 Subject: RTC. Test updated. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3408 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/src/rtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/src/rtc.c b/os/hal/src/rtc.c index 0c8959ea6..17c83f4b3 100644 --- a/os/hal/src/rtc.c +++ b/os/hal/src/rtc.c @@ -76,7 +76,7 @@ void rtcInit(void){ */ void rtcSetCallback(RTCDriver *rtcp, rtccb_t overflowcb, rtccb_t secondcb, rtccb_t alarmcb){ - chDbgCheck((rtcp != NULL), "rtcStart"); + chDbgCheck((rtcp != NULL), "rtcSetCallback"); rtc_lld_set_callback(rtcp, overflowcb, secondcb, alarmcb); } #endif /* RTC_SUPPORTS_CALLBACKS */ -- cgit v1.2.3 From aba41323fcc5ac96be23e8e498527397c66b5a71 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 25 Sep 2011 10:56:39 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3409 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/RTCv1/rtc_lld.c | 2 +- os/hal/platforms/STM32/RTCv1/rtc_lld.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.c b/os/hal/platforms/STM32/RTCv1/rtc_lld.c index a3329544e..df90bcc11 100644 --- a/os/hal/platforms/STM32/RTCv1/rtc_lld.c +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.c @@ -19,7 +19,7 @@ */ /** - * @file STM32/rtc_lld.c + * @file STM32/RTCv1/rtc_lld.c * @brief STM32 RTC subsystem low level driver header. * * @addtogroup RTC diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.h b/os/hal/platforms/STM32/RTCv1/rtc_lld.h index 37f8e105e..f8256ae31 100644 --- a/os/hal/platforms/STM32/RTCv1/rtc_lld.h +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.h @@ -19,7 +19,7 @@ */ /** - * @file STM32/rtc_lld.h + * @file STM32/RTCv1/rtc_lld.h * @brief STM32 RTC subsystem low level driver header. * * @addtogroup RTC -- cgit v1.2.3 From bede8d6781661d679475d2b60d87fb7f43cc5e8e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 25 Sep 2011 15:18:18 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3410 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/AVR/pal_lld.c | 134 ++++++++++++++++ os/hal/platforms/AVR/pal_lld.h | 265 ++++++++++++++++++++++++++++++++ os/hal/platforms/AVR/platform.dox | 14 ++ os/hal/platforms/AVR/platform.mk | 1 + os/hal/platforms/LPC11xx/pal_lld.h | 20 --- os/hal/platforms/LPC13xx/pal_lld.h | 20 --- os/hal/platforms/Posix/pal_lld.h | 8 - os/hal/platforms/STM32/GPIOv1/pal_lld.c | 2 - os/hal/platforms/STM32/GPIOv1/pal_lld.h | 12 -- os/hal/platforms/STM32/GPIOv2/pal_lld.c | 2 - os/hal/platforms/STM32/GPIOv2/pal_lld.h | 12 -- os/hal/platforms/STM8L/pal_lld.c | 2 - os/hal/platforms/STM8L/pal_lld.h | 8 - os/hal/platforms/STM8S/pal_lld.c | 2 - os/hal/platforms/STM8S/pal_lld.h | 8 - os/hal/platforms/Win32/pal_lld.h | 8 - os/hal/templates/pal_lld.h | 28 ---- 17 files changed, 414 insertions(+), 132 deletions(-) create mode 100644 os/hal/platforms/AVR/pal_lld.c create mode 100644 os/hal/platforms/AVR/pal_lld.h (limited to 'os/hal') diff --git a/os/hal/platforms/AVR/pal_lld.c b/os/hal/platforms/AVR/pal_lld.c new file mode 100644 index 000000000..4bfd7bd04 --- /dev/null +++ b/os/hal/platforms/AVR/pal_lld.c @@ -0,0 +1,134 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 AVR/pal_lld.c + * @brief AVR GPIO low level driver code. + * + * @addtogroup PAL + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_PAL || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief AVR GPIO ports configuration. + * @details GPIO registers initialization. + * + * @param[in] config the AVR ports configuration + * + * @notapi + */ +void _pal_lld_init(const PALConfig *config) { + +#if defined(PORTA) || defined(__DOXYGEN__) + PORTA = config->porta.out; + DDRA = config->porta.dir; +#endif + +#if defined(PORTB) || defined(__DOXYGEN__) + PORTB = config->portb.out; + DDRB = config->portb.dir; +#endif + +#if defined(PORTC) || defined(__DOXYGEN__) + PORTC = config->portc.out; + DDRC = config->portc.dir; +#endif + +#if defined(PORTD) || defined(__DOXYGEN__) + PORTD = config->portd.out; + DDRD = config->portd.dir; +#endif + +#if defined(PORTE) || defined(__DOXYGEN__) + PORTE = config->porte.out; + DDRE = config->porte.dir; +#endif +} + +/** + * @brief Pads mode setup. + * @details This function programs a pads group belonging to the same port + * with the specified mode. + * + * @param[in] port the port identifier + * @param[in] mask the group mask + * @param[in] mode the mode + * + * @note This function is not meant to be invoked directly by the application + * code. + * @note @p PAL_MODE_UNCONNECTED is implemented as output as recommended by + * the AVR Family User's Guide. Unconnected pads are set to input + * with pull-up by default. + * + * @notapi + * + * TODO: check PAL_MODE_UNCONNECTED mode recommended for AVR + */ +void _pal_lld_setgroupmode(ioportid_t port, + ioportmask_t mask, + iomode_t mode) { + + switch (mode) { + case PAL_MODE_RESET: + case PAL_MODE_INPUT: + port->dir &= ~mask; + break; + case PAL_MODE_INPUT_ANALOG: + port->dir &= ~mask; + port->out &= ~mask; + break; + case PAL_MODE_UNCONNECTED: + case PAL_MODE_INPUT_PULLUP: + port->dir &= ~mask; + port->out |= mask; + case PAL_MODE_OUTPUT_PUSHPULL: + port->dir |= mask; + break; + } +} + +#endif /* HAL_USE_PAL */ + +/** @} */ diff --git a/os/hal/platforms/AVR/pal_lld.h b/os/hal/platforms/AVR/pal_lld.h new file mode 100644 index 000000000..a2d1f8714 --- /dev/null +++ b/os/hal/platforms/AVR/pal_lld.h @@ -0,0 +1,265 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 AVR/pal_lld.h + * @brief AVR GPIO low level driver header. + * + * @addtogroup PAL + * @{ + */ + +#ifndef _PAL_LLD_H_ +#define _PAL_LLD_H_ + +#if HAL_USE_PAL || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Unsupported modes and specific modes */ +/*===========================================================================*/ + +#undef PAL_MODE_INPUT_PULLDOWN +#undef PAL_MODE_OUTPUT_OPENDRAIN + +/*===========================================================================*/ +/* I/O Ports Types and constants. */ +/*===========================================================================*/ + +/** + * @brief Width, in bits, of an I/O port. + */ +#define PAL_IOPORTS_WIDTH 8 + +/** + * @brief Whole port mask. + * @brief This macro specifies all the valid bits into a port. + */ +#define PAL_WHOLE_PORT ((ioportmask_t)0xFF) + +/** + * @brief AVR setup registers. + */ +typedef struct { + uint8_t out; + uint8_t dir; +} avr_gpio_setup_t; + +typedef struct { + volatile uint8_t in; + volatile uint8_t dir; + volatile uint8_t out; +} avr_gpio_registers_t; + +/** + * @brief Generic I/O ports static initializer. + * @details An instance of this structure must be passed to @p palInit() at + * system startup time in order to initialized the digital I/O + * subsystem. This represents only the initial setup, specific pads + * or whole ports can be reprogrammed at later time. + */ +typedef struct { +#if defined(PORTA) || defined(__DOXYGEN__) + avr_gpio_setup_t porta; +#endif +#if defined(PORTB) || defined(__DOXYGEN__) + avr_gpio_setup_t portb; +#endif +#if defined(PORTC) || defined(__DOXYGEN__) + avr_gpio_setup_t portc; +#endif +#if defined(PORTD) || defined(__DOXYGEN__) + avr_gpio_setup_t portd; +#endif +#if defined(PORTE) || defined(__DOXYGEN__) + avr_gpio_setup_t porte; +#endif +} PALConfig; + +/** + * @brief Digital I/O port sized unsigned type. + */ +typedef uint8_t ioportmask_t; + +/** + * @brief Digital I/O modes. + */ +typedef uint8_t iomode_t; + +/** + * @brief Port Identifier. + * @details This type can be a scalar or some kind of pointer, do not make + * any assumption about it, use the provided macros when populating + * variables of this type. + */ +typedef avr_gpio_registers_t *ioportid_t; + +/*===========================================================================*/ +/* I/O Ports Identifiers. */ +/*===========================================================================*/ + +#if defined(PORTA) || defined(__DOXYGEN__) +/** + * @brief GPIO port A identifier. + */ +#define IOPORT1 ((volatile avr_gpio_registers_t *)&PINA) +#endif + +#if defined(PORTB) || defined(__DOXYGEN__) +/** + * @brief GPIO port B identifier. + */ +#define IOPORT2 ((volatile avr_gpio_registers_t *)&PINB) +#endif + +#if defined(PORTC) || defined(__DOXYGEN__) +/** + * @brief GPIO port C identifier. + */ +#define IOPORT3 ((volatile avr_gpio_registers_t *)&PINC) +#endif + +#if defined(PORTD) || defined(__DOXYGEN__) +/** + * @brief GPIO port D identifier. + */ +#define IOPORT4 ((volatile avr_gpio_registers_t *)&PIND) +#endif + +#if defined(PORTE) || defined(__DOXYGEN__) +/** + * @brief GPIO port E identifier. + */ +#define IOPORT5 ((volatile avr_gpio_registers_t *)&PINE) +#endif + +/*===========================================================================*/ +/* Implementation, some of the following macros could be implemented as */ +/* functions, if so please put them in pal_lld.c. */ +/*===========================================================================*/ + +/** + * @brief Low level PAL subsystem initialization. + * + * @param[in] config the architecture-dependent ports configuration + * + * @notapi + */ +#define pal_lld_init(config) _pal_lld_init(config) + +/** + * @brief Reads the physical I/O port states. + * + * @param[in] port the port identifier + * @return The port bits. + * + * @notapi + */ +#define pal_lld_readport(port) ((port)->in) + +/** + * @brief Reads the output latch. + * @details The purpose of this function is to read back the latched output + * value. + * + * @param[in] port the port identifier + * @return The latched logical states. + * + * @notapi + */ +#define pal_lld_readlatch(port) ((port)->out) + +/** + * @brief Writes a bits mask on a I/O port. + * + * @param[in] port the port identifier + * @param[in] bits the bits to be written on the specified port + * + * @notapi + */ +#define pal_lld_writeport(port, bits) ((port)->out = bits) + +/** + * @brief Pads group mode setup. + * @details This function programs a pads group belonging to the same port + * with the specified mode. + * @note Programming an unknown or unsupported mode is silently ignored. + * + * @param[in] port the port identifier + * @param[in] mask the group mask + * @param[in] mode the mode + * + * @notapi + */ +#define pal_lld_setgroupmode(port, mask, mode) _pal_lld_setgroupmode(port, mask, mode) + +/** + * @brief Sets a pad logical state to @p PAL_HIGH. + * + * @param[in] port the port identifier + * @param[in] pad the pad number within the port + * + * @notapi + */ +#define pal_lld_setpad(port, pad) \ +__asm__ __volatile__ \ +( \ + "sbi %0,%1\n\t" \ + : \ + : "I" (_SFR_IO_ADDR(port->out)), \ + "I" (pad) \ + \ +) + +/** + * @brief Clears a pad logical state to @p PAL_LOW. + * + * @param[in] port the port identifier + * @param[in] pad the pad number within the port + * + * @notapi + */ +#define pal_lld_clearpad(port, pad) \ +__asm__ __volatile__ \ +( \ + "cbi %0,%1\n\t" \ + : \ + : "I" (_SFR_IO_ADDR(port->out)), \ + "I" (pad) \ + \ +) + +extern ROMCONST PALConfig pal_default_config; + +#ifdef __cplusplus +extern "C" { +#endif + void _pal_lld_init(const PALConfig *config); + void _pal_lld_setgroupmode(ioportid_t port, + ioportmask_t mask, + iomode_t mode); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_PAL */ + +#endif /* _PAL_LLD_H_ */ + +/** @} */ diff --git a/os/hal/platforms/AVR/platform.dox b/os/hal/platforms/AVR/platform.dox index bc29954b6..2ac2256b9 100644 --- a/os/hal/platforms/AVR/platform.dox +++ b/os/hal/platforms/AVR/platform.dox @@ -35,6 +35,20 @@ * @ingroup AVR_DRIVERS */ +/** + * @defgroup AVR_PAL AVR PAL Support + * @details The AVR PAL driver uses the GPIO peripherals. + * + * @section avr_pal_1 Supported HW resources + * - GPIOA. + * - GPIOB. + * - GPIOC. + * - GPIOD. + * - GPIOE. + * . + * @ingroup AVR_DRIVERS + */ + /** * @defgroup AVR_SERIAL AVR Serial Support * @details The AVR Serial driver uses the USART peripherals in a diff --git a/os/hal/platforms/AVR/platform.mk b/os/hal/platforms/AVR/platform.mk index fdc5390bb..e31413c79 100644 --- a/os/hal/platforms/AVR/platform.mk +++ b/os/hal/platforms/AVR/platform.mk @@ -1,5 +1,6 @@ # List of all the AVR platform files. PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/AVR/hal_lld.c \ + ${CHIBIOS}/os/hal/platforms/AVR/pal_lld.c \ ${CHIBIOS}/os/hal/platforms/AVR/serial_lld.c # Required include directories diff --git a/os/hal/platforms/LPC11xx/pal_lld.h b/os/hal/platforms/LPC11xx/pal_lld.h index b46362aeb..2e99f0697 100644 --- a/os/hal/platforms/LPC11xx/pal_lld.h +++ b/os/hal/platforms/LPC11xx/pal_lld.h @@ -147,8 +147,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; /** * @brief Reads the physical I/O port states. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @return The port bits. @@ -161,8 +159,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; * @brief Reads the output latch. * @details The purpose of this function is to read back the latched output * value. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @return The latched logical states. @@ -173,8 +169,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; /** * @brief Writes a bits mask on a I/O port. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @param[in] bits bits to be written on the specified port @@ -185,8 +179,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; /** * @brief Sets a bits mask on a I/O port. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -200,8 +192,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; /** * @brief Clears a bits mask on a I/O port. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -215,8 +205,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; /** * @brief Reads a group of bits. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -233,8 +221,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; /** * @brief Writes a group of bits. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -254,8 +240,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; * @brief Pads group mode setup. * @details This function programs a pads group belonging to the same port * with the specified mode. - * @note This function is not meant to be invoked directly by the - * application code. * @note Programming an unknown or unsupported mode is silently ignored. * * @param[in] port port identifier @@ -287,8 +271,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; /** * @brief Sets a pad logical state to @p PAL_HIGH. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -303,8 +285,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; /** * @brief Clears a pad logical state to @p PAL_LOW. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. diff --git a/os/hal/platforms/LPC13xx/pal_lld.h b/os/hal/platforms/LPC13xx/pal_lld.h index 6e291dfc9..0673c11f1 100644 --- a/os/hal/platforms/LPC13xx/pal_lld.h +++ b/os/hal/platforms/LPC13xx/pal_lld.h @@ -147,8 +147,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; /** * @brief Reads the physical I/O port states. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @return The port bits. @@ -161,8 +159,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; * @brief Reads the output latch. * @details The purpose of this function is to read back the latched output * value. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @return The latched logical states. @@ -173,8 +169,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; /** * @brief Writes a bits mask on a I/O port. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @param[in] bits bits to be written on the specified port @@ -185,8 +179,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; /** * @brief Sets a bits mask on a I/O port. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -200,8 +192,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; /** * @brief Clears a bits mask on a I/O port. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -215,8 +205,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; /** * @brief Reads a group of bits. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -233,8 +221,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; /** * @brief Writes a group of bits. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -254,8 +240,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; * @brief Pads group mode setup. * @details This function programs a pads group belonging to the same port * with the specified mode. - * @note This function is not meant to be invoked directly by the - * application code. * @note Programming an unknown or unsupported mode is silently ignored. * * @param[in] port port identifier @@ -287,8 +271,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; /** * @brief Sets a pad logical state to @p PAL_HIGH. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -303,8 +285,6 @@ typedef LPC_GPIO_TypeDef *ioportid_t; /** * @brief Clears a pad logical state to @p PAL_LOW. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. diff --git a/os/hal/platforms/Posix/pal_lld.h b/os/hal/platforms/Posix/pal_lld.h index d76eacf25..f8e2a8702 100644 --- a/os/hal/platforms/Posix/pal_lld.h +++ b/os/hal/platforms/Posix/pal_lld.h @@ -140,8 +140,6 @@ typedef sim_vio_port_t *ioportid_t; /** * @brief Reads the physical I/O port states. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @return The port bits. @@ -152,8 +150,6 @@ typedef sim_vio_port_t *ioportid_t; * @brief Reads the output latch. * @details The purpose of this function is to read back the latched output * value. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @return The latched logical states. @@ -162,8 +158,6 @@ typedef sim_vio_port_t *ioportid_t; /** * @brief Writes a bits mask on a I/O port. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @param[in] bits bits to be written on the specified port @@ -174,8 +168,6 @@ typedef sim_vio_port_t *ioportid_t; * @brief Pads group mode setup. * @details This function programs a pads group belonging to the same port * with the specified mode. - * @note This function is not meant to be invoked directly by the - * application code. * @note Programming an unknown or unsupported mode is silently ignored. * * @param[in] port port identifier diff --git a/os/hal/platforms/STM32/GPIOv1/pal_lld.c b/os/hal/platforms/STM32/GPIOv1/pal_lld.c index 274d8b6c0..6b4b806b9 100644 --- a/os/hal/platforms/STM32/GPIOv1/pal_lld.c +++ b/os/hal/platforms/STM32/GPIOv1/pal_lld.c @@ -117,8 +117,6 @@ void _pal_lld_init(const PALConfig *config) { * @brief Pads mode setup. * @details This function programs a pads group belonging to the same port * with the specified mode. - * @note This function is not meant to be invoked directly by the - * application code. * @note @p PAL_MODE_UNCONNECTED is implemented as push pull output at 2MHz. * @note Writing on pads programmed as pull-up or pull-down has the side * effect to modify the resistor setting because the output latched diff --git a/os/hal/platforms/STM32/GPIOv1/pal_lld.h b/os/hal/platforms/STM32/GPIOv1/pal_lld.h index 65e660944..c9bb99de7 100644 --- a/os/hal/platforms/STM32/GPIOv1/pal_lld.h +++ b/os/hal/platforms/STM32/GPIOv1/pal_lld.h @@ -219,8 +219,6 @@ typedef GPIO_TypeDef * ioportid_t; * @brief Writes on a I/O port. * @details This function is implemented by writing the GPIO ODR register, the * implementation has no side effects. - * @note This function is not meant to be invoked directly by the - * application code. * @note Writing on pads programmed as pull-up or pull-down has the side * effect to modify the resistor setting because the output latched * data is used for the resistor selection. @@ -236,8 +234,6 @@ typedef GPIO_TypeDef * ioportid_t; * @brief Sets a bits mask on a I/O port. * @details This function is implemented by writing the GPIO BSRR register, the * implementation has no side effects. - * @note This function is not meant to be invoked directly by the - * application code. * @note Writing on pads programmed as pull-up or pull-down has the side * effect to modify the resistor setting because the output latched * data is used for the resistor selection. @@ -253,8 +249,6 @@ typedef GPIO_TypeDef * ioportid_t; * @brief Clears a bits mask on a I/O port. * @details This function is implemented by writing the GPIO BRR register, the * implementation has no side effects. - * @note This function is not meant to be invoked directly by the - * application code. * @note Writing on pads programmed as pull-up or pull-down has the side * effect to modify the resistor setting because the output latched * data is used for the resistor selection. @@ -270,8 +264,6 @@ typedef GPIO_TypeDef * ioportid_t; * @brief Writes a group of bits. * @details This function is implemented by writing the GPIO BSRR register, the * implementation has no side effects. - * @note This function is not meant to be invoked directly by the - * application code. * @note Writing on pads programmed as pull-up or pull-down has the side * effect to modify the resistor setting because the output latched * data is used for the resistor selection. @@ -292,8 +284,6 @@ typedef GPIO_TypeDef * ioportid_t; * @brief Pads group mode setup. * @details This function programs a pads group belonging to the same port * with the specified mode. - * @note This function is not meant to be invoked directly by the - * application code. * @note Writing on pads programmed as pull-up or pull-down has the side * effect to modify the resistor setting because the output latched * data is used for the resistor selection. @@ -309,8 +299,6 @@ typedef GPIO_TypeDef * ioportid_t; /** * @brief Writes a logical state on an output pad. - * @note This function is not meant to be invoked directly by the - * application code. * @note Writing on pads programmed as pull-up or pull-down has the side * effect to modify the resistor setting because the output latched * data is used for the resistor selection. diff --git a/os/hal/platforms/STM32/GPIOv2/pal_lld.c b/os/hal/platforms/STM32/GPIOv2/pal_lld.c index 8f84f225e..bde24db25 100644 --- a/os/hal/platforms/STM32/GPIOv2/pal_lld.c +++ b/os/hal/platforms/STM32/GPIOv2/pal_lld.c @@ -125,8 +125,6 @@ void _pal_lld_init(const PALConfig *config) { * @brief Pads mode setup. * @details This function programs a pads group belonging to the same port * with the specified mode. - * @note This function is not meant to be invoked directly by the - * application code. * @note @p PAL_MODE_UNCONNECTED is implemented as push pull at minimum * speed. * diff --git a/os/hal/platforms/STM32/GPIOv2/pal_lld.h b/os/hal/platforms/STM32/GPIOv2/pal_lld.h index 6c799c14c..7f8c2e17a 100644 --- a/os/hal/platforms/STM32/GPIOv2/pal_lld.h +++ b/os/hal/platforms/STM32/GPIOv2/pal_lld.h @@ -347,8 +347,6 @@ typedef GPIO_TypeDef * ioportid_t; * @brief Writes on a I/O port. * @details This function is implemented by writing the GPIO ODR register, the * implementation has no side effects. - * @note This function is not meant to be invoked directly by the - * application code. * @note Writing on pads programmed as pull-up or pull-down has the side * effect to modify the resistor setting because the output latched * data is used for the resistor selection. @@ -364,8 +362,6 @@ typedef GPIO_TypeDef * ioportid_t; * @brief Sets a bits mask on a I/O port. * @details This function is implemented by writing the GPIO BSRR register, the * implementation has no side effects. - * @note This function is not meant to be invoked directly by the - * application code. * @note Writing on pads programmed as pull-up or pull-down has the side * effect to modify the resistor setting because the output latched * data is used for the resistor selection. @@ -381,8 +377,6 @@ typedef GPIO_TypeDef * ioportid_t; * @brief Clears a bits mask on a I/O port. * @details This function is implemented by writing the GPIO BSRR register, the * implementation has no side effects. - * @note This function is not meant to be invoked directly by the - * application code. * @note Writing on pads programmed as pull-up or pull-down has the side * effect to modify the resistor setting because the output latched * data is used for the resistor selection. @@ -398,8 +392,6 @@ typedef GPIO_TypeDef * ioportid_t; * @brief Writes a group of bits. * @details This function is implemented by writing the GPIO BSRR register, the * implementation has no side effects. - * @note This function is not meant to be invoked directly by the - * application code. * @note Writing on pads programmed as pull-up or pull-down has the side * effect to modify the resistor setting because the output latched * data is used for the resistor selection. @@ -420,8 +412,6 @@ typedef GPIO_TypeDef * ioportid_t; * @brief Pads group mode setup. * @details This function programs a pads group belonging to the same port * with the specified mode. - * @note This function is not meant to be invoked directly by the - * application code. * @note Writing on pads programmed as pull-up or pull-down has the side * effect to modify the resistor setting because the output latched * data is used for the resistor selection. @@ -437,8 +427,6 @@ typedef GPIO_TypeDef * ioportid_t; /** * @brief Writes a logical state on an output pad. - * @note This function is not meant to be invoked directly by the - * application code. * @note Writing on pads programmed as pull-up or pull-down has the side * effect to modify the resistor setting because the output latched * data is used for the resistor selection. diff --git a/os/hal/platforms/STM8L/pal_lld.c b/os/hal/platforms/STM8L/pal_lld.c index 40dcdf8d2..aba1565cb 100644 --- a/os/hal/platforms/STM8L/pal_lld.c +++ b/os/hal/platforms/STM8L/pal_lld.c @@ -55,8 +55,6 @@ * @brief Pads mode setup. * @details This function programs a pads group belonging to the same port * with the specified mode. - * @note This function is not meant to be invoked directly by the - * application code. * @note @p PAL_MODE_UNCONNECTED is implemented as push pull output at 2MHz. * * @param[in] port the port identifier diff --git a/os/hal/platforms/STM8L/pal_lld.h b/os/hal/platforms/STM8L/pal_lld.h index 30fef0e82..22d048c74 100644 --- a/os/hal/platforms/STM8L/pal_lld.h +++ b/os/hal/platforms/STM8L/pal_lld.h @@ -184,8 +184,6 @@ typedef GPIO_TypeDef *ioportid_t; /** * @brief Reads the physical I/O port states. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @return The port bits. @@ -198,8 +196,6 @@ typedef GPIO_TypeDef *ioportid_t; * @brief Reads the output latch. * @details The purpose of this function is to read back the latched output * value. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @return The latched logical states. @@ -210,8 +206,6 @@ typedef GPIO_TypeDef *ioportid_t; /** * @brief Writes a bits mask on a I/O port. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @param[in] bits bits to be written on the specified port @@ -224,8 +218,6 @@ typedef GPIO_TypeDef *ioportid_t; * @brief Pads group mode setup. * @details This function programs a pads group belonging to the same port * with the specified mode. - * @note This function is not meant to be invoked directly by the - * application code. * @note Programming an unknown or unsupported mode is silently ignored. * * @param[in] port port identifier diff --git a/os/hal/platforms/STM8S/pal_lld.c b/os/hal/platforms/STM8S/pal_lld.c index cebf349aa..e1e6d919e 100644 --- a/os/hal/platforms/STM8S/pal_lld.c +++ b/os/hal/platforms/STM8S/pal_lld.c @@ -55,8 +55,6 @@ * @brief Pads mode setup. * @details This function programs a pads group belonging to the same port * with the specified mode. - * @note This function is not meant to be invoked directly by the - * application code. * @note @p PAL_MODE_UNCONNECTED is implemented as push pull output at 2MHz. * * @param[in] port the port identifier diff --git a/os/hal/platforms/STM8S/pal_lld.h b/os/hal/platforms/STM8S/pal_lld.h index 954a11361..d38406b2f 100644 --- a/os/hal/platforms/STM8S/pal_lld.h +++ b/os/hal/platforms/STM8S/pal_lld.h @@ -169,8 +169,6 @@ typedef GPIO_TypeDef *ioportid_t; /** * @brief Reads the physical I/O port states. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @return The port bits. @@ -183,8 +181,6 @@ typedef GPIO_TypeDef *ioportid_t; * @brief Reads the output latch. * @details The purpose of this function is to read back the latched output * value. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @return The latched logical states. @@ -195,8 +191,6 @@ typedef GPIO_TypeDef *ioportid_t; /** * @brief Writes a bits mask on a I/O port. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @param[in] bits bits to be written on the specified port @@ -209,8 +203,6 @@ typedef GPIO_TypeDef *ioportid_t; * @brief Pads group mode setup. * @details This function programs a pads group belonging to the same port * with the specified mode. - * @note This function is not meant to be invoked directly by the - * application code. * @note Programming an unknown or unsupported mode is silently ignored. * * @param[in] port port identifier diff --git a/os/hal/platforms/Win32/pal_lld.h b/os/hal/platforms/Win32/pal_lld.h index ad70eeebc..e0f03e135 100644 --- a/os/hal/platforms/Win32/pal_lld.h +++ b/os/hal/platforms/Win32/pal_lld.h @@ -140,8 +140,6 @@ typedef sim_vio_port_t *ioportid_t; /** * @brief Reads the physical I/O port states. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @return The port bits. @@ -152,8 +150,6 @@ typedef sim_vio_port_t *ioportid_t; * @brief Reads the output latch. * @details The purpose of this function is to read back the latched output * value. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @return The latched logical states. @@ -162,8 +158,6 @@ typedef sim_vio_port_t *ioportid_t; /** * @brief Writes a bits mask on a I/O port. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @param[in] bits bits to be written on the specified port @@ -174,8 +168,6 @@ typedef sim_vio_port_t *ioportid_t; * @brief Pads group mode setup. * @details This function programs a pads group belonging to the same port * with the specified mode. - * @note This function is not meant to be invoked directly by the - * application code. * @note Programming an unknown or unsupported mode is silently ignored. * * @param[in] port port identifier diff --git a/os/hal/templates/pal_lld.h b/os/hal/templates/pal_lld.h index 46f5a3d39..60bac5e5c 100644 --- a/os/hal/templates/pal_lld.h +++ b/os/hal/templates/pal_lld.h @@ -108,8 +108,6 @@ typedef uint32_t ioportid_t; /** * @brief Reads the physical I/O port states. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @return The port bits. @@ -122,8 +120,6 @@ typedef uint32_t ioportid_t; * @brief Reads the output latch. * @details The purpose of this function is to read back the latched output * value. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @return The latched logical states. @@ -134,8 +130,6 @@ typedef uint32_t ioportid_t; /** * @brief Writes a bits mask on a I/O port. - * @note This function is not meant to be invoked directly by the - * application code. * * @param[in] port port identifier * @param[in] bits bits to be written on the specified port @@ -146,8 +140,6 @@ typedef uint32_t ioportid_t; /** * @brief Sets a bits mask on a I/O port. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -161,8 +153,6 @@ typedef uint32_t ioportid_t; /** * @brief Clears a bits mask on a I/O port. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -176,8 +166,6 @@ typedef uint32_t ioportid_t; /** * @brief Toggles a bits mask on a I/O port. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -191,8 +179,6 @@ typedef uint32_t ioportid_t; /** * @brief Reads a group of bits. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -208,8 +194,6 @@ typedef uint32_t ioportid_t; /** * @brief Writes a group of bits. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -228,8 +212,6 @@ typedef uint32_t ioportid_t; * @brief Pads group mode setup. * @details This function programs a pads group belonging to the same port * with the specified mode. - * @note This function is not meant to be invoked directly by the - * application code. * @note Programming an unknown or unsupported mode is silently ignored. * * @param[in] port port identifier @@ -242,8 +224,6 @@ typedef uint32_t ioportid_t; /** * @brief Reads a logical state from an I/O pad. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -277,8 +257,6 @@ typedef uint32_t ioportid_t; /** * @brief Sets a pad logical state to @p PAL_HIGH. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -292,8 +270,6 @@ typedef uint32_t ioportid_t; /** * @brief Clears a pad logical state to @p PAL_LOW. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -307,8 +283,6 @@ typedef uint32_t ioportid_t; /** * @brief Toggles a pad logical state. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. @@ -323,8 +297,6 @@ typedef uint32_t ioportid_t; /** * @brief Pad mode setup. * @details This function programs a pad with the specified mode. - * @note This function is not meant to be invoked directly by the - * application code. * @note The @ref PAL provides a default software implementation of this * functionality, implement this function if can optimize it by using * special hardware functionalities or special coding. -- cgit v1.2.3 From d2fa0e3fdee679a6cdd5dd6616aca527eca3f080 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 26 Sep 2011 08:23:10 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3412 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/rtc.h | 29 ++++++++--------------- os/hal/src/rtc.c | 65 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 48 insertions(+), 46 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/rtc.h b/os/hal/include/rtc.h index 02aec2ceb..aa2562c69 100644 --- a/os/hal/include/rtc.h +++ b/os/hal/include/rtc.h @@ -26,12 +26,9 @@ * @{ */ - #ifndef _RTC_H_ #define _RTC_H_ - - #if HAL_USE_RTC || defined(__DOXYGEN__) /*===========================================================================*/ @@ -50,8 +47,14 @@ /* Driver data structures and types. */ /*===========================================================================*/ +/** + * @brief Type of a structure representing an RTC driver. + */ typedef struct RTCDriver RTCDriver; +/** + * @brief Type of an RTC callback. + */ typedef void (*rtccb_t)(RTCDriver *rtcp); #include "rtc_lld.h" @@ -68,26 +71,14 @@ typedef void (*rtccb_t)(RTCDriver *rtcp); extern "C" { #endif void rtcInit(void); - - #if RTC_SUPPORTS_CALLBACKS - void rtcSetCallback(RTCDriver *rtcp, rtccb_t overflowcb, - rtccb_t secondcb, rtccb_t alarmcb); - #endif /* RTC_SUPPORTS_CALLBACKS */ - +#if RTC_SUPPORTS_CALLBACKS + void rtcSetCallback(RTCDriver *rtcp, rtccb_t overflowcb, + rtccb_t secondcb, rtccb_t alarmcb); +#endif /* RTC_SUPPORTS_CALLBACKS */ void rtcSetTime(RTCDateTime *timespec); void rtcGetTime(RTCDateTime *timespec); - - - - void rtcSetAlarm(RTCDateTime *timespec); void rtcGetAlarm(RTCDateTime *timespec); - - - - - - #ifdef __cplusplus } #endif diff --git a/os/hal/src/rtc.c b/os/hal/src/rtc.c index 17c83f4b3..24ccce84e 100644 --- a/os/hal/src/rtc.c +++ b/os/hal/src/rtc.c @@ -20,7 +20,7 @@ /** * @file rtc.c - * @brief Real Time Clock Abstraction Layer code. + * @brief RTC Driver code. * * @addtogroup RTC * @{ @@ -50,74 +50,85 @@ /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ + /** - * @brief Enable access to registers and initialize RTC if BKP doamin - * was previously reseted. - * + * @brief Enable access to registers and initialize RTC if BKP domain + * was previously reset. * @note This function is implicitly invoked by @p halInit(), there is * no need to explicitly initialize the driver. + * + * @init */ -void rtcInit(void){ +void rtcInit(void) { rtc_lld_init(); } -#if RTC_SUPPORTS_CALLBACKS +#if RTC_SUPPORTS_CALLBACKS || defined(__DOXYGEN__) /** - * @brief Enables and disables callbacks on the fly. - * @details Pass callback function(s) in argument(s) to enable callback(s). - * Pass NULL to disable callback. - * @pre To use this function you must set @p RTC_SUPPORTS_CALLBACKS - * to @p TRUE. + * @brief Enables or disables callbacks. + * @details This function enables or disables callbacks, use a @p NULL pointer + * in order to disable a callback. + * @pre To use this function you must set @p RTC_SUPPORTS_CALLBACKS + * to @p TRUE. * - * @param[in] rtcp - pointer to RTC driver structure. - * @param[in] overflowcb - overflow callback function. - * @param[in] secondcb - every second callback function. - * @param[in] alarmcb - alarm callback function. + * @param[in] rtcp pointer to RTC driver structure + * @param[in] overflowcb overflow callback function + * @param[in] secondcb every second callback function + * @param[in] alarmcb alarm callback function */ void rtcSetCallback(RTCDriver *rtcp, rtccb_t overflowcb, - rtccb_t secondcb, rtccb_t alarmcb){ + rtccb_t secondcb, rtccb_t alarmcb) { + chDbgCheck((rtcp != NULL), "rtcSetCallback"); + rtc_lld_set_callback(rtcp, overflowcb, secondcb, alarmcb); } #endif /* RTC_SUPPORTS_CALLBACKS */ /** - * @brief Set current time. + * @brief Set current time. * - * @param[in] timespec pointer to variable storing time. + * @param[in] timespec pointer to a @p RTCDateTime structure */ -void rtcSetTime(RTCDateTime *timespec){ +void rtcSetTime(RTCDateTime *timespec) { + chDbgCheck((timespec != NULL), "rtcSetTime"); + rtc_lld_set_time(timespec); } /** - * @brief Get current time. + * @brief Get current time. * - * @param[in] timespec pointer to variable storing time. + * @param[in] timespec pointer to a @p RTCDateTime structure */ -void rtcGetTime(RTCDateTime *timespec){ +void rtcGetTime(RTCDateTime *timespec) { + chDbgCheck((timespec != NULL), "rtcGetTime"); rtc_lld_get_time(timespec); } /** - * @brief Set alarm time. + * @brief Set alarm time. * - * @param[in] timespec pointer to variable storing time of alarm. + * @param[in] timespec pointer to a @p RTCDateTime structure */ -void rtcSetAlarm(RTCDateTime *timespec){ +void rtcSetAlarm(RTCDateTime *timespec) { + chDbgCheck((timespec != NULL), "rtcSetAlarm"); + rtc_lld_set_alarm(timespec); } /** - * @brief Get current alarm. + * @brief Get current alarm. * - * @param[in] timespec pointer to variable to store alarm time. + * @param[in] timespec pointer to a @p RTCDateTime structure */ void rtcGetAlarm(RTCDateTime *timespec){ + chDbgCheck((timespec != NULL), "rtcGetAlarm"); + rtc_lld_get_alarm(timespec); } -- cgit v1.2.3 From 2950a0a7b8316a742a7a67b5acb4f224a98397ff Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 1 Oct 2011 08:04:14 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3413 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/rtc.h | 33 +++- os/hal/platforms/STM32/RTCv1/rtc_lld.c | 333 ++++++++++++++++----------------- os/hal/platforms/STM32/RTCv1/rtc_lld.h | 105 +++++++---- os/hal/platforms/STM32F1xx/stm32_rcc.h | 12 +- os/hal/platforms/STM32L1xx/hal_lld.h | 4 +- os/hal/src/rtc.c | 95 ++++++---- 6 files changed, 315 insertions(+), 267 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/rtc.h b/os/hal/include/rtc.h index aa2562c69..1264c5bd8 100644 --- a/os/hal/include/rtc.h +++ b/os/hal/include/rtc.h @@ -35,6 +35,18 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @name Date/Time bit masks + * @{ + */ +#define RTC_TIME_SECONDS_MASK 0x0000001F /* @brief Seconds mask. */ +#define RTC_TIME_MINUTES_MASK 0x000007E0 /* @brief Minutes mask. */ +#define RTC_TIME_HOURS_MASK 0x0000F800 /* @brief Hours mask. */ +#define RTC_DATE_DAYS_MASK 0x001F0000 /* @brief Days mask. */ +#define RTC_DATE_MONTHS_MASK 0x01E00000 /* @brief Months mask. */ +#define RTC_DATE_YEARS_MASK 0xFE000000 /* @brief Years mask. */ +/** @} */ + /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ @@ -53,9 +65,9 @@ typedef struct RTCDriver RTCDriver; /** - * @brief Type of an RTC callback. + * @brief Type of a structure representing an RTC time stamp. */ -typedef void (*rtccb_t)(RTCDriver *rtcp); +typedef struct RTCTime RTCTime; #include "rtc_lld.h" @@ -71,14 +83,17 @@ typedef void (*rtccb_t)(RTCDriver *rtcp); extern "C" { #endif void rtcInit(void); + void rtcSetTime(RTCDriver *rtcp, const RTCTime *timespec); + void rtcGetTime(RTCDriver *rtcp, RTCTime *timespec); +#if RTC_ALARMS > 0 + void rtcSetAlarm(RTCDriver *rtcp, + rtcalarm_t alarm, + const RTCAlarm *alarmspec); + void rtcGetAlarm(RTCDriver *rtcp, rtcalarm_t alarm, RTCAlarm *alarmspec); +#endif #if RTC_SUPPORTS_CALLBACKS - void rtcSetCallback(RTCDriver *rtcp, rtccb_t overflowcb, - rtccb_t secondcb, rtccb_t alarmcb); -#endif /* RTC_SUPPORTS_CALLBACKS */ - void rtcSetTime(RTCDateTime *timespec); - void rtcGetTime(RTCDateTime *timespec); - void rtcSetAlarm(RTCDateTime *timespec); - void rtcGetAlarm(RTCDateTime *timespec); + void rtcSetCallback(RTCDriver *rtcp, rtccb_t callback); +#endif #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.c b/os/hal/platforms/STM32/RTCv1/rtc_lld.c index df90bcc11..2876b990d 100644 --- a/os/hal/platforms/STM32/RTCv1/rtc_lld.c +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.c @@ -29,16 +29,16 @@ #include "ch.h" #include "hal.h" - #if HAL_USE_RTC || defined(__DOXYGEN__) /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ -/** @brief RTC driver identifier.*/ -RTCDriver RTCD; - +/** + * @brief RTC driver identifier. + */ +RTCDriver RTCD1; /*===========================================================================*/ /* Driver local variables. */ @@ -55,33 +55,37 @@ RTCDriver RTCD; * * @notapi */ -#if RTC_SUPPORTS_CALLBACKS +static void rtc_lld_serve_interrupt(RTCDriver *rtcp) { -static void rtc_lld_serve_interrupt(RTCDriver *rtcp){ chSysLockFromIsr(); - if ((RTC->CRH & RTC_CRH_SECIE) && \ - (RTC->CRL & RTC_CRL_SECF) && \ - (rtcp->second_cb != NULL)){ - rtcp->second_cb(rtcp); + if ((RTC->CRH & RTC_CRH_SECIE) && (RTC->CRL & RTC_CRL_SECF)) { + rtcp->rtc_cb(rtcp, RTC_EVENT_SECOND); RTC->CRL &= ~RTC_CRL_SECF; } - if ((RTC->CRH & RTC_CRH_ALRIE) && \ - (RTC->CRL & RTC_CRL_ALRF) && \ - (rtcp->alarm_cb != NULL)){ - rtcp->alarm_cb(rtcp); + if ((RTC->CRH & RTC_CRH_ALRIE) && (RTC->CRL & RTC_CRL_ALRF)) { + rtcp->rtc_cb(rtcp, RTC_EVENT_ALARM); RTC->CRL &= ~RTC_CRL_ALRF; } - if ((RTC->CRH & RTC_CRH_OWIE) && \ - (RTC->CRL & RTC_CRL_OWF) && \ - (rtcp->overflow_cb != NULL)){ - rtcp->overflow_cb(rtcp); + if ((RTC->CRH & RTC_CRH_OWIE) && (RTC->CRL & RTC_CRL_OWF)) { + rtcp->rtc_cb(rtcp, RTC_EVENT_OVERFLOW); RTC->CRL &= ~RTC_CRL_OWF; } chSysUnlockFromIsr(); } -#endif /* RTC_SUPPORTS_CALLBACKS */ + +/** + * @brief Waits for the previous registers write to finish. + * + * @notapi + */ +static void rtc_lld_wait_write(void) { + + /* Waits registers write completion.*/ + while (!(RTC->CRL & RTC_CRL_RTOFF)) + ; +} /*===========================================================================*/ /* Driver interrupt handlers. */ @@ -89,18 +93,18 @@ static void rtc_lld_serve_interrupt(RTCDriver *rtcp){ /** * @brief RTC interrupt handler. + * * @isr */ -#if RTC_SUPPORTS_CALLBACKS - CH_IRQ_HANDLER(RTC_IRQHandler) { + CH_IRQ_PROLOGUE(); - rtc_lld_serve_interrupt(&RTCD); + + rtc_lld_serve_interrupt(&RTCD1); + CH_IRQ_EPILOGUE(); } -#endif /* RTC_SUPPORTS_CALLBACKS */ - /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -108,226 +112,207 @@ CH_IRQ_HANDLER(RTC_IRQHandler) { /** * @brief Enable access to registers and initialize RTC if BKP domain * was previously reseted. - * * @note: Cold start time of LSE oscillator on STM32 platform * takes about 3 seconds. * * @notapi */ void rtc_lld_init(void){ - uint32_t preload = 0; + uint32_t preload; rccEnableBKPInterface(FALSE); - /* enable access to BKP registers */ + /* Enables access to BKP registers.*/ PWR->CR |= PWR_CR_DBP; - /* select clock source */ - RCC->BDCR |= STM32_RTC; -#if STM32_RTC == STM32_RTC_LSE - if (! ((RCC->BDCR & RCC_BDCR_RTCEN) || (RCC->BDCR & RCC_BDCR_LSEON))){ - RCC->BDCR |= RCC_BDCR_LSEON; - while(!(RCC->BDCR & RCC_BDCR_LSERDY)) - ; - RCC->BDCR |= RCC_BDCR_RTCEN; - } - preload = STM32_LSECLK - 1; + /* If the RTC is not enabled then performs a reset of the backup domain.*/ + if (!(RCC->BDCR & RCC_BDCR_RTCEN)) { + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + } -#elif STM32_RTC == STM32_RTC_LSI - RCC->CSR |= RCC_CSR_LSION; - while(!(RCC->CSR & RCC_CSR_LSIRDY)) - ; - /* According to errata sheet we must wait additional 100 uS for stabilization */ - uint32_t tmo = (STM32_SYSCLK / 1000000 ) * 100; - while(tmo--) +#if STM32_RTC == STM32_RTC_LSE + if (!(RCC->BDCR & RCC_BDCR_LSEON)) { + RCC->BDCR |= RCC_BDCR_LSEON; + while (!(RCC->BDCR & RCC_BDCR_LSERDY)) ; - RCC->BDCR |= RCC_BDCR_RTCEN; - preload = STM32_LSICLK - 1; - + } + preload = STM32_LSECLK - 1; +#elif STM32_RTC == STM32_RTC_LSI + /* TODO: Move the LSI clock initialization in the HAL low level driver.*/ + RCC->CSR |= RCC_CSR_LSION; + while (!(RCC->CSR & RCC_CSR_LSIRDY)) + ; + /* According to errata sheet we must wait additional 100 uS for + stabilization. + TODO: Change this code, software loops are not reliable.*/ + uint32_t tmo = (STM32_SYSCLK / 1000000) * 100; + while (tmo--) + ; + preload = STM32_LSICLK - 1; #elif STM32_RTC == STM32_RTC_HSE - preload = (STM32_HSICLK / 128) - 1; - -#else -#error "RTC clock source not selected" + preload = (STM32_HSICLK / 128) - 1; #endif + /* Selects clock source (previously enabled and stabilized.*/ + RCC->BDCR = (RCC->BDCR & ~RCC_BDCR_RTCSEL) | STM32_RTC; + + /* RTC enabled regardless its previous status.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + /* Ensure that RTC_CNT and RTC_DIV contain actual values after enabling - * clocking on APB1, because these values only update when APB1 functioning.*/ - RTC->CRL &= ~(RTC_CRL_RSF); + clocking on APB1, because these values only update when APB1 + functioning.*/ + RTC->CRL = 0; while (!(RTC->CRL & RTC_CRL_RSF)) ; - /* Write preload register only if its value changed */ - if (preload != ((((uint32_t)(RTC->PRLH)) << 16) + RTC->PRLL)){ - while(!(RTC->CRL & RTC_CRL_RTOFF)) - ; + /* Write preload register only if its value differs.*/ + if (preload != ((((uint32_t)(RTC->PRLH)) << 16) + (uint32_t)RTC->PRLL)) { - RTC->CRL |= RTC_CRL_CNF; /* switch on configure mode */ - RTC->PRLH = (uint16_t)((preload >> 16) & 0b1111); /* write preloader */ - RTC->PRLL = (uint16_t)(preload & 0xFFFF); - RTC->CRL &= ~RTC_CRL_CNF; /* switch off configure mode */ + rtc_lld_wait_write(); - while(!(RTC->CRL & RTC_CRL_RTOFF)) /* wait for completion */ - ; + /* Enters configuration mode and writes PRLx registers then leaves the + configuration mode.*/ + RTC->CRL |= RTC_CRL_CNF; + RTC->PRLH = (uint16_t)(preload >> 16); + RTC->PRLL = (uint16_t)(preload & 0xFFFF); + RTC->CRL &= ~RTC_CRL_CNF; } - /* disable all interrupts and clear all even flags just to be safe */ - RTC->CRH &= ~(RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE); - RTC->CRL &= ~(RTC_CRL_SECF | RTC_CRL_ALRF | RTC_CRL_OWF); + /* All interrupts initially disabled.*/ + RTC->CRH = 0; -#if RTC_SUPPORTS_CALLBACKS - RTCD.alarm_cb = NULL; - RTCD.overflow_cb = NULL; - RTCD.second_cb = NULL; -#endif /* RTC_SUPPORTS_CALLBACKS */ + /* Callback initially disabled.*/ + RTCD1.rtc_cb = NULL; } /** - * @brief Enables and disables callbacks on the fly. + * @brief Set current time. + * @note Fractional part will be silently ignored. There is no possibility + * to change it on STM32F1xx platform. * - * @details Pass callback function(s) in argument(s) to enable callback(s). - * Pass NULL to disable callback. - * - * @pre To use this function you must set @p RTC_SUPPORTS_CALLBACKS - * to @p TRUE. - * - * @param[in] rtcp pointer to RTC driver structure. - * @param[in] overflowcb overflow callback function. - * @param[in] secondcb every second callback function. - * @param[in] alarmcb alarm callback function. + * @param[in] rtcp pointer to RTC driver structure + * @param[in] timespec pointer to a @p RTCTime structure * * @notapi */ -#if RTC_SUPPORTS_CALLBACKS -void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t overflowcb, - rtccb_t secondcb, rtccb_t alarmcb){ +void rtc_lld_set_time(RTCDriver *rtcp, const RTCTime *timespec) { - uint16_t isr_flags = 0; + (void)rtcp; - if (overflowcb != NULL){ - rtcp->overflow_cb = *overflowcb; - isr_flags |= RTC_CRH_OWIE; - } - else{ - rtcp->overflow_cb = NULL; - isr_flags &= ~RTC_CRH_OWIE; - } + rtc_lld_wait_write(); - if (alarmcb != NULL){ - rtcp->alarm_cb = *alarmcb; - isr_flags |= RTC_CRH_ALRIE; - } - else{ - rtcp->alarm_cb = NULL; - isr_flags &= ~RTC_CRH_ALRIE; - } - - if (secondcb != NULL){ - rtcp->second_cb = *secondcb; - isr_flags |= RTC_CRH_SECIE; - } - else{ - rtcp->second_cb = NULL; - isr_flags &= ~RTC_CRH_SECIE; - } - - if(isr_flags != 0){ - NVICEnableVector(RTC_IRQn, CORTEX_PRIORITY_MASK(STM32_RTC_IRQ_PRIORITY)); - RTC->CRH |= isr_flags; - } - else{ - NVICDisableVector(RTC_IRQn); - RTC->CRH = 0; - } + RTC->CRL |= RTC_CRL_CNF; + RTC->CNTH = (uint16_t)(timespec->tv_sec >> 16); + RTC->CNTL = (uint16_t)(timespec->tv_sec & 0xFFFF); + RTC->CRL &= ~RTC_CRL_CNF; } -#endif /* RTC_SUPPORTS_CALLBACKS */ /** - * @brief Set current time. + * @brief Get current time. * - * @param[in] timespec pointer to variable storing time. + * @param[in] rtcp pointer to RTC driver structure + * @param[out] timespec pointer to a @p RTCTime structure * - * @note Fractional part will be silently ignored. There is no possibility - * to change it on STM32F1xx platform. * @notapi */ -void rtc_lld_set_time(RTCDateTime *timespec){ +void rtc_lld_get_time(RTCDriver *rtcp, RTCTime *timespec) { + uint32_t time_frac; - while(!(RTC->CRL & RTC_CRL_RTOFF)) - ; + (void)rtcp; - RTC->CRL |= RTC_CRL_CNF; /* switch on configure mode */ - RTC->CNTH = (uint16_t)((timespec->tv_sec >> 16) & 0xFFFF); - RTC->CNTL = (uint16_t)(timespec->tv_sec & 0xFFFF); - RTC->CRL &= ~RTC_CRL_CNF; /* switch off configure mode */ - - while(!(RTC->CRL & RTC_CRL_RTOFF)) /* wait for completion */ - ; + time_frac = (((uint32_t)RTC->DIVH) << 16) + (uint32_t)RTC->DIVL; + timespec->tv_msec = (uint16_t)(((STM32_LSECLK - time_frac) * 1000) / + STM32_LSECLK); + timespec->tv_sec = (RTC->CNTH << 16) + RTC->CNTL; } /** - * @brief Get current time. + * @brief Set alarm time. + * + * @note Default value after BKP domain reset is 0xFFFFFFFF * - * @param[in] msec pointer to variable for storing fractional part of - * time (milliseconds). + * @param[in] rtcp pointer to RTC driver structure + * @param[in] alarm alarm identifier + * @param[in] alarmspec pointer to a @p RTCAlarm structure * * @notapi */ -inline void rtc_lld_get_time(RTCDateTime *timespec){ - uint32_t time_frac = 0; - time_frac = (((uint32_t)RTC->DIVH) << 16) + (RTC->DIVL); +void rtc_lld_set_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + const RTCAlarm *alarmspec) { - timespec->tv_msec = (uint16_t)(((STM32_LSECLK - time_frac) * 1000) / STM32_LSECLK); - timespec->tv_sec = (RTC->CNTH << 16) + RTC->CNTL; + (void)rtcp; + (void)alarm; + + rtc_lld_wait_write(); + + /* Enters configuration mode and writes ALRHx registers then leaves the + configuration mode.*/ + RTC->CRL |= RTC_CRL_CNF; + if (alarmspec != NULL) { + RTC->ALRH = (uint16_t)(alarmspec->tv_sec >> 16); + RTC->ALRL = (uint16_t)(alarmspec->tv_sec & 0xFFFF); + } + else { + RTC->ALRH = 0; + RTC->ALRL = 0; + } + RTC->CRL &= ~RTC_CRL_CNF; } /** - * @brief Set alarm time. + * @brief Get current alarm. + * @note If an alarm has not been set then the returned alarm specification + * is not meaningful. * - * @param[in] timespec pointer to variable storing time of alarm. + * @note Default value after BKP domain reset is 0xFFFFFFFF. * - * @note Fractional part will be silently ignored. There is no possibility - * to change it on STM32F1xx platform. - * - * @note Default value after BKP domain reset is 0xFFFFFFFF + * @param[in] rtcp pointer to RTC driver structure + * @param[in] alarm alarm identifier + * @param[out] alarmspec pointer to a @p RTCAlarm structure * * @notapi */ -void rtc_lld_set_alarm(RTCDateTime *timespec){ +void rtc_lld_get_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + RTCAlarm *alarmspec) { - while(!(RTC->CRL & RTC_CRL_RTOFF)) - ; - - RTC->CRL |= RTC_CRL_CNF; /* switch on configure mode */ - RTC->ALRH = (uint16_t)((timespec->tv_sec >> 16) & 0xFFFF); - RTC->ALRL = (uint16_t)(timespec->tv_sec & 0xFFFF); - RTC->CRL &= ~RTC_CRL_CNF; /* switch off configure mode */ - -#if !(RTC_SUPPORTS_CALLBACKS) - RTC->CRL &= ~RTC_CRL_ALRF; - RTC->CRH |= RTC_CRH_ALRIE; -#endif /* !(RTC_SUPPORTS_CALLBACKS) */ + (void)rtcp; + (void)alarm; - while(!(RTC->CRL & RTC_CRL_RTOFF)) /* wait for completion */ - ; + alarmspec->tv_sec = ((RTC->ALRH << 16) + RTC->ALRL); } /** - * @brief Get current alarm time. - * - * @param[in] timespec pointer to variable storing time of alarm. + * @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 Fractional part will be silently ignored. There is no possibility - * to change it on STM32F1xx platform. - * - * @note Default value after BKP domain reset is 0xFFFFFFFF + * @param[in] rtcp pointer to RTC driver structure + * @param[in] callback callback function pointer or @p NULL * * @notapi */ -inline void rtc_lld_get_alarm(RTCDateTime *timespec){ - timespec->tv_sec = ((RTC->ALRH << 16) + RTC->ALRL); -} +void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) { + + if (callback != NULL) { + rtcp->rtc_cb = callback; + NVICEnableVector(RTC_IRQn, CORTEX_PRIORITY_MASK(STM32_RTC_IRQ_PRIORITY)); + /* Interrupts are enabled only after setting up the callback, this + way there is no need to check for the NULL callback pointer inside + the IRQ handler.*/ + RTC->CRL &= ~(RTC_CRL_OWF | RTC_CRL_ALRF | RTC_CRL_SECF); + RTC->CRH |= RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE; + } + else { + NVICDisableVector(RTC_IRQn); + RTC->CRL = 0; + RTC->CRH = 0; + } +} #endif /* HAL_USE_RTC */ diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.h b/os/hal/platforms/STM32/RTCv1/rtc_lld.h index f8256ae31..e3ce0e365 100644 --- a/os/hal/platforms/STM32/RTCv1/rtc_lld.h +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.h @@ -35,17 +35,19 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @brief This RTC implementation supports callbacks. + */ +#define RTC_SUPPORTS_CALLBACKS TRUE + +/** + * @brief One alarm comparator available. + */ +#define RTC_ALARMS 1 + /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ -/** - * @brief Switch to TRUE if you need callbacks from RTC. Switch to FALSE - * if you need only time keeping. - * @note Default is true. - */ -#if !defined(RTC_SUPPORTS_CALLBACKS) || defined(__DOXYGEN__) -#define RTC_SUPPORTS_CALLBACKS TRUE -#endif /*===========================================================================*/ /* Derived constants and error checks. */ @@ -55,46 +57,71 @@ #error "RTC not present in the selected device" #endif +#if !(STM32_RTC == STM32_RTC_LSE) && !(STM32_RTC == STM32_RTC_LSI) && \ + !(STM32_RTC == STM32_RTC_HSE) +#error "invalid source selected for RTC clock" +#endif + /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ /** - * @brief Structure representing an RTC time value. + * @brief Type of a structure representing an RTC alarm stamp. + */ +typedef struct RTCAlarm RTCAlarm; + +/** + * @brief Type of an RTC alarm. + */ +typedef uint32_t rtcalarm_t; + +/** + * @brief Type of an RTC event. + */ +typedef enum { + RTC_EVENT_SECOND = 0, /** Triggered every second. */ + RTC_EVENT_ALARM = 1, /** Triggered on alarm. */ + RTC_EVENT_OVERFLOW = 2 /** Triggered on counter overflow. */ +} rtcevent_t; + +/** + * @brief Type of a generic RTC callback. */ -typedef struct { +typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event); + +/** + * @brief Structure representing an RTC time stamp. + */ +struct RTCTime { /** - * @brief Seconds sins UNIX epoch. + * @brief Seconds since UNIX epoch. */ uint32_t tv_sec; /** * @brief Fractional part. */ uint32_t tv_msec; -}RTCDateTime; - +}; /** - * @brief Structure representing an RTC driver. - * @note This driver is dummy when callbacks disabled. + * @brief Structure representing an RTC alarm specification. */ -struct RTCDriver{ -#if RTC_SUPPORTS_CALLBACKS +struct RTCAlarm { /** - * @brief Overflow callback. Set it to NULL if not used. + * @brief Seconds since UNIX epoch. */ - rtccb_t overflow_cb; - - /** - * @brief Every second callback. Set it to NULL if not used. - */ - rtccb_t second_cb; + uint32_t tv_sec; +}; +/** + * @brief Structure representing an RTC driver. + */ +struct RTCDriver{ /** - * @brief Alarm callback. Set it to NULL if not used. + * @brief Callback pointer. */ - rtccb_t alarm_cb; -#endif /* RTC_SUPPORTS_CALLBACKS */ + rtccb_t rtc_cb; }; /*===========================================================================*/ @@ -105,27 +132,29 @@ struct RTCDriver{ /* External declarations. */ /*===========================================================================*/ -extern RTCDriver RTCD; - +#if !defined(__DOXYGEN__) +extern RTCDriver RTCD1; +#endif #ifdef __cplusplus extern "C" { #endif void rtc_lld_init(void); - void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t overflow_cb, - rtccb_t second_cb, rtccb_t alarm_cb); - - void rtc_lld_set_time(RTCDateTime *timespec); - void rtc_lld_get_time(RTCDateTime *timespec); - - void rtc_lld_get_alarm(RTCDateTime *timespec); - void rtc_lld_set_alarm(RTCDateTime *timespec); + void rtc_lld_set_time(RTCDriver *rtcp, const RTCTime *timespec); + void rtc_lld_get_time(RTCDriver *rtcp, RTCTime *timespec); + void rtc_lld_set_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + const RTCAlarm *alarmspec); + void rtc_lld_get_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + RTCAlarm *alarmspec); + void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback); #ifdef __cplusplus } #endif - #endif /* HAL_USE_RTC */ + #endif /* _RTC_LLD_H_ */ /** @} */ diff --git a/os/hal/platforms/STM32F1xx/stm32_rcc.h b/os/hal/platforms/STM32F1xx/stm32_rcc.h index 9ca1140e9..0f19f7b07 100644 --- a/os/hal/platforms/STM32F1xx/stm32_rcc.h +++ b/os/hal/platforms/STM32F1xx/stm32_rcc.h @@ -214,8 +214,8 @@ * * @api */ -#define rccEnableBKPInterface(lp) \ - rccEnableAPB1((RCC_APB1ENR_BKPEN | RCC_APB1ENR_PWREN), lp); +#define rccEnableBKPInterface(lp) \ + rccEnableAPB1((RCC_APB1ENR_BKPEN | RCC_APB1ENR_PWREN), lp) /** * @brief Disables BKP interface clock. @@ -225,22 +225,22 @@ * * @api */ -#define rccDisableBKPInterface(lp) \ - rccDisableAPB1((RCC_APB1ENR_BKPEN | RCC_APB1ENR_PWREN), lp); +#define rccDisableBKPInterface(lp) \ + rccDisableAPB1((RCC_APB1ENR_BKPEN | RCC_APB1ENR_PWREN), lp) /** * @brief Resets the Backup Domain interface. * * @api */ -#define rccResetBKPInterface() rccResetAPB1(RCC_APB1ENR_BKPRST); +#define rccResetBKPInterface() rccResetAPB1(RCC_APB1ENR_BKPRST) /** * @brief Resets the entire Backup Domain. * * @api */ -#define rccResetBKP() (RCC->BDCR |= RCC_BDCR_BDRST); +#define rccResetBKP() (RCC->BDCR |= RCC_BDCR_BDRST) /** @} */ /** diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index cf07e8036..6efee2ca7 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -514,11 +514,11 @@ #if (STM32_LSECLK < 1000) || (STM32_LSECLK > 1000000) #error "STM32_LSECLK outside acceptable range (1...1000KHz)" #endif -#else /* !#if STM32_LSE_ENABLED */ +#else /* !STM32_LSE_ENABLED */ #if STM_RTCCLK == STM32_LSECLK #error "required LSE clock is not enabled" #endif -#endif /* !#if STM32_LSE_ENABLED */ +#endif /* !STM32_LSE_ENABLED */ /* PLL related checks.*/ #if STM32_USB_CLOCK_ENABLED || \ diff --git a/os/hal/src/rtc.c b/os/hal/src/rtc.c index 24ccce84e..dda5a9c95 100644 --- a/os/hal/src/rtc.c +++ b/os/hal/src/rtc.c @@ -52,88 +52,107 @@ /*===========================================================================*/ /** - * @brief Enable access to registers and initialize RTC if BKP domain - * was previously reset. + * @brief RTC Driver initialization. * @note This function is implicitly invoked by @p halInit(), there is * no need to explicitly initialize the driver. * * @init */ void rtcInit(void) { + rtc_lld_init(); } -#if RTC_SUPPORTS_CALLBACKS || defined(__DOXYGEN__) /** - * @brief Enables or disables callbacks. - * @details This function enables or disables callbacks, use a @p NULL pointer - * in order to disable a callback. - * @pre To use this function you must set @p RTC_SUPPORTS_CALLBACKS - * to @p TRUE. + * @brief Set current time. * * @param[in] rtcp pointer to RTC driver structure - * @param[in] overflowcb overflow callback function - * @param[in] secondcb every second callback function - * @param[in] alarmcb alarm callback function + * @param[in] timespec pointer to a @p RTCTime structure + * + * @api */ -void rtcSetCallback(RTCDriver *rtcp, rtccb_t overflowcb, - rtccb_t secondcb, rtccb_t alarmcb) { +void rtcSetTime(RTCDriver *rtcp, const RTCTime *timespec) { - chDbgCheck((rtcp != NULL), "rtcSetCallback"); + chDbgCheck((rtcp != NULL) && (timespec != NULL), "rtcSetTime"); - rtc_lld_set_callback(rtcp, overflowcb, secondcb, alarmcb); + rtc_lld_set_time(rtcp, timespec); } -#endif /* RTC_SUPPORTS_CALLBACKS */ /** - * @brief Set current time. + * @brief Get current time. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[out] timespec pointer to a @p RTCTime structure * - * @param[in] timespec pointer to a @p RTCDateTime structure + * @api */ -void rtcSetTime(RTCDateTime *timespec) { +void rtcGetTime(RTCDriver *rtcp, RTCTime *timespec) { - chDbgCheck((timespec != NULL), "rtcSetTime"); + chDbgCheck((rtcp != NULL) && (timespec != NULL), "rtcGetTime"); - rtc_lld_set_time(timespec); + rtc_lld_get_time(rtcp, timespec); } +#if (RTC_ALARMS > 0) || defined(__DOXYGEN__) /** - * @brief Get current time. + * @brief Set alarm time. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] alarm alarm identifier + * @param[in] alarmspec pointer to a @p RTCAlarm structure or @p NULL * - * @param[in] timespec pointer to a @p RTCDateTime structure + * @api */ -void rtcGetTime(RTCDateTime *timespec) { +void rtcSetAlarm(RTCDriver *rtcp, + rtcalarm_t alarm, + const RTCAlarm *alarmspec) { - chDbgCheck((timespec != NULL), "rtcGetTime"); - rtc_lld_get_time(timespec); + chDbgCheck((rtcp != NULL) && (alarm < RTC_ALARMS), "rtcSetAlarm"); + + rtc_lld_set_alarm(rtcp, alarm, alarmspec); } /** - * @brief Set alarm time. + * @brief Get current alarm. + * @note If an alarm has not been set then the returned alarm specification + * is not meaningful. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] alarm alarm identifier + * @param[out] alarmspec pointer to a @p RTCAlarm structure * - * @param[in] timespec pointer to a @p RTCDateTime structure + * @api */ -void rtcSetAlarm(RTCDateTime *timespec) { +void rtcGetAlarm(RTCDriver *rtcp, + rtcalarm_t alarm, + RTCAlarm *alarmspec) { - chDbgCheck((timespec != NULL), "rtcSetAlarm"); + chDbgCheck((rtcp != NULL) && (alarm < RTC_ALARMS) && (alarmspec != NULL), + "rtcGetAlarm"); - rtc_lld_set_alarm(timespec); + rtc_lld_get_alarm(rtcp, alarm, alarmspec); } +#endif /* RTC_ALARMS > 0 */ +#if RTC_SUPPORTS_CALLBACKS || defined(__DOXYGEN__) /** - * @brief Get current alarm. + * @brief Enables or disables RTC callbacks. + * @details This function enables or disables callbacks, use a @p NULL pointer + * in order to disable a callback. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] callback callback function pointer or @p NULL * - * @param[in] timespec pointer to a @p RTCDateTime structure + * @api */ -void rtcGetAlarm(RTCDateTime *timespec){ +void rtcSetCallback(RTCDriver *rtcp, rtccb_t callback) { - chDbgCheck((timespec != NULL), "rtcGetAlarm"); + chDbgCheck((rtcp != NULL), "rtcSetCallback"); - rtc_lld_get_alarm(timespec); + rtc_lld_set_callback(rtcp, callback); } +#endif /* RTC_SUPPORTS_CALLBACKS */ #endif /* HAL_USE_RTC */ /** @} */ - - -- cgit v1.2.3 From 4ab87c6ded40d1797a8d2f8ddc22ee91f6392320 Mon Sep 17 00:00:00 2001 From: barthess Date: Sat, 1 Oct 2011 20:20:53 +0000 Subject: RTC. Insert forgotten closing brace in documentation. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3414 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/RTCv1/rtc_lld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.c b/os/hal/platforms/STM32/RTCv1/rtc_lld.c index 2876b990d..cae23525f 100644 --- a/os/hal/platforms/STM32/RTCv1/rtc_lld.c +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.c @@ -154,7 +154,7 @@ void rtc_lld_init(void){ preload = (STM32_HSICLK / 128) - 1; #endif - /* Selects clock source (previously enabled and stabilized.*/ + /* Selects clock source (previously enabled and stabilized).*/ RCC->BDCR = (RCC->BDCR & ~RCC_BDCR_RTCSEL) | STM32_RTC; /* RTC enabled regardless its previous status.*/ -- cgit v1.2.3 From 25fd95662814fd189c3616a804f234c19c6b6a58 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 2 Oct 2011 10:19:27 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3416 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/USBv1/stm32_usb.h | 6 ++-- os/hal/platforms/STM32L1xx/platform.dox | 54 ++++++++++++++++---------------- 2 files changed, 30 insertions(+), 30 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/USBv1/stm32_usb.h b/os/hal/platforms/STM32/USBv1/stm32_usb.h index 51e7510c4..7ba03350a 100644 --- a/os/hal/platforms/STM32/USBv1/stm32_usb.h +++ b/os/hal/platforms/STM32/USBv1/stm32_usb.h @@ -21,10 +21,10 @@ /** * @file stm32_usb.h * @brief STM32 USB registers layout header. - * @note This file requires definitions from the ST STM32 header file - * stm3232f10x.h. + * @note This file requires definitions from the ST STM32 header files + * stm32f10x.h or stm32l1xx.h. * - * @addtogroup STM32_USB + * @addtogroup USB * @{ */ diff --git a/os/hal/platforms/STM32L1xx/platform.dox b/os/hal/platforms/STM32L1xx/platform.dox index 910fdf7bd..dc7b26905 100644 --- a/os/hal/platforms/STM32L1xx/platform.dox +++ b/os/hal/platforms/STM32L1xx/platform.dox @@ -19,7 +19,7 @@ */ /** - * @defgroup STM32L1xx_DRIVERS STM32L1xx Drivers + * @defgroup STM32_DRIVERS STM32L1xx Drivers * @details This section describes all the supported drivers on the STM32L1xx * platform and the implementation details of the single drivers. * @@ -27,7 +27,7 @@ */ /** - * @defgroup STM32L1xx_HAL STM32L1xx Initialization Support + * @defgroup STM32_HAL STM32L1xx Initialization Support * @details The STM32L1xx HAL support is responsible for system initialization. * * @section stm32l1xx_hal_1 Supported HW resources @@ -43,11 +43,11 @@ * - SYSTICK initialization based on current clock and kernel required rate. * - DMA support initialization. * . - * @ingroup STM32L1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32L1xx_ADC STM32L1xx ADC Support + * @defgroup STM32_ADC STM32L1xx ADC Support * @details The STM32L1xx ADC driver supports the ADC peripherals using DMA * channels for maximum performance. * @@ -63,11 +63,11 @@ * - Programmable DMA interrupt priority for each DMA channel. * - DMA and ADC errors detection. * . - * @ingroup STM32L1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32L1xx_DMA STM32L1xx DMA Support + * @defgroup STM32_DMA STM32L1xx DMA Support * @details This DMA helper driver is used by the other drivers in order to * access the shared DMA resources in a consistent way. * @@ -81,11 +81,11 @@ * - Automatic DMA clock stop when not in use by any driver. * - DMA streams and interrupt vectors sharing among multiple drivers. * . - * @ingroup STM32L1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32L1xx_EXT STM32L1xx EXT Support + * @defgroup STM32_EXT STM32L1xx EXT Support * @details The STM32L1xx EXT driver uses the EXTI peripheral. * * @section stm32l1xx_ext_1 Supported HW resources @@ -96,11 +96,11 @@ * - Programmable EXTI interrupts priority level. * - Capability to work as event sources (WFE) rather than interrupt sources. * . - * @ingroup STM32L1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32L1xx_GPT STM32L1xx GPT Support + * @defgroup STM32_GPT STM32L1xx GPT Support * @details The STM32L1xx GPT driver uses the TIMx peripherals. * * @section stm32l1xx_gpt_1 Supported HW resources @@ -113,11 +113,11 @@ * peripherals are left in low power mode. * - Programmable TIMx interrupts priority level. * . - * @ingroup STM32L1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32L1xx_ICU STM32L1xx ICU Support + * @defgroup STM32_ICU STM32L1xx ICU Support * @details The STM32L1xx ICU driver uses the TIMx peripherals. * * @section stm32l1xx_icu_1 Supported HW resources @@ -130,11 +130,11 @@ * peripherals are left in low power mode. * - Programmable TIMx interrupts priority level. * . - * @ingroup STM32L1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32L1xx_PAL STM32L1xx PAL Support + * @defgroup STM32_PAL STM32L1xx PAL Support * @details The STM32L1xx PAL driver uses the GPIO peripherals. * * @section stm32l1xx_pal_1 Supported HW resources @@ -164,8 +164,8 @@ * - @p PAL_MODE_INPUT_ANALOG. * - @p PAL_MODE_OUTPUT_PUSHPULL. * - @p PAL_MODE_OUTPUT_OPENDRAIN. - * - @p PAL_MODE_STM32L1xx_ALTERNATE_PUSHPULL (non standard). - * - @p PAL_MODE_STM32L1xx_ALTERNATE_OPENDRAIN (non standard). + * - @p PAL_MODE_STM32_ALTERNATE_PUSHPULL (non standard). + * - @p PAL_MODE_STM32_ALTERNATE_OPENDRAIN (non standard). * . * Any attempt to setup an invalid mode is ignored. * @@ -175,11 +175,11 @@ * - Pad/port toggling operations are not atomic. * - Pad/group mode setup is not atomic. * . - * @ingroup STM32L1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32L1xx_PWM STM32L1xx PWM Support + * @defgroup STM32_PWM STM32L1xx PWM Support * @details The STM32L1xx PWM driver uses the TIMx peripherals. * * @section stm32l1xx_pwm_1 Supported HW resources @@ -195,11 +195,11 @@ * - Four independent PWM channels per timer. * - Programmable TIMx interrupts priority level. * . - * @ingroup STM32L1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32L1xx_SERIAL STM32L1xx Serial Support + * @defgroup STM32_SERIAL STM32L1xx Serial Support * @details The STM32L1xx Serial driver uses the USART/UART peripherals in a * buffered, interrupt driven, implementation. * @@ -218,11 +218,11 @@ * - Fully interrupt driven. * - Programmable priority levels for each UART/USART. * . - * @ingroup STM32L1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32L1xx_SPI STM32L1xx SPI Support + * @defgroup STM32_SPI STM32L1xx SPI Support * @details The SPI driver supports the STM32L1xx SPI peripherals using DMA * channels for maximum performance. * @@ -243,11 +243,11 @@ * - Programmable DMA interrupt priority for each DMA channel. * - Programmable DMA error hook. * . - * @ingroup STM32L1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32L1xx_UART STM32L1xx UART Support + * @defgroup STM32_UART STM32L1xx UART Support * @details The UART driver supports the STM32L1xx USART peripherals using DMA * channels for maximum performance. * @@ -270,11 +270,11 @@ * - Programmable DMA interrupt priority for each DMA channel. * - Programmable DMA error hook. * . - * @ingroup STM32L1xx_DRIVERS + * @ingroup STM32_DRIVERS */ /** - * @defgroup STM32L1xx_USB STM32L1xx USB Support + * @defgroup STM32_USB STM32L1xx USB Support * @details The USB driver supports the STM32L1xx USB peripheral. * * @section stm32l1xx_usb_1 Supported HW resources @@ -286,5 +286,5 @@ * - Programmable interrupt priority levels. * - Each endpoint programmable in Control, Bulk and Interrupt modes. * . - * @ingroup STM32L1xx_DRIVERS + * @ingroup STM32_DRIVERS */ -- cgit v1.2.3 From e3262e950c778403d9d8303e6f70cdb5912a5b5d Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 2 Oct 2011 10:21:17 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3417 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32L1xx/platform.dox | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32L1xx/platform.dox b/os/hal/platforms/STM32L1xx/platform.dox index dc7b26905..3737cc10d 100644 --- a/os/hal/platforms/STM32L1xx/platform.dox +++ b/os/hal/platforms/STM32L1xx/platform.dox @@ -164,8 +164,7 @@ * - @p PAL_MODE_INPUT_ANALOG. * - @p PAL_MODE_OUTPUT_PUSHPULL. * - @p PAL_MODE_OUTPUT_OPENDRAIN. - * - @p PAL_MODE_STM32_ALTERNATE_PUSHPULL (non standard). - * - @p PAL_MODE_STM32_ALTERNATE_OPENDRAIN (non standard). + * - @p PAL_MODE_ALTERNATE (non standard). * . * Any attempt to setup an invalid mode is ignored. * -- cgit v1.2.3 From 2913907698510dc37049990dff13da0a11140b6a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 2 Oct 2011 10:23:04 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3418 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32L1xx/platform.dox | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32L1xx/platform.dox b/os/hal/platforms/STM32L1xx/platform.dox index 3737cc10d..773785a5b 100644 --- a/os/hal/platforms/STM32L1xx/platform.dox +++ b/os/hal/platforms/STM32L1xx/platform.dox @@ -197,6 +197,22 @@ * @ingroup STM32_DRIVERS */ +/** + * @defgroup STM32_RCC STM32F1xx RCC Support + * @details This RCC helper driver is used by the other drivers in order to + * access the shared RCC resources in a consistent way. + * + * @section stm32f1xx_rcc_1 Supported HW resources + * - RCC. + * . + * @section stm32f1xx_rcc_2 STM32F1xx RCC driver implementation features + * - Peripherals reset. + * - Peripherals clock enable. + * - Periplerals clock disable. + * . + * @ingroup STM32_DRIVERS + */ + /** * @defgroup STM32_SERIAL STM32L1xx Serial Support * @details The STM32L1xx Serial driver uses the USART/UART peripherals in a -- cgit v1.2.3 From 9a25b3d92870112cfad854f7d146e9d607ead491 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 2 Oct 2011 10:59:38 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3419 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/platform.dox | 78 ++++++++++++++++----------------- os/hal/platforms/STM32L1xx/platform.dox | 56 +++++++++++------------ 2 files changed, 67 insertions(+), 67 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/platform.dox b/os/hal/platforms/STM32F1xx/platform.dox index 624a5b12f..2f282e4d5 100644 --- a/os/hal/platforms/STM32F1xx/platform.dox +++ b/os/hal/platforms/STM32F1xx/platform.dox @@ -19,7 +19,7 @@ */ /** - * @defgroup STM32_DRIVERS STM32F1xx Drivers + * @defgroup STM32F1xx_DRIVERS STM32F1xx Drivers * @details This section describes all the supported drivers on the STM32F1xx * platform and the implementation details of the single drivers. * @@ -27,7 +27,7 @@ */ /** - * @defgroup STM32_HAL STM32F1xx Initialization Support + * @defgroup STM32F1xx_HAL STM32F1xx Initialization Support * @details The STM32F1xx HAL support is responsible for system initialization. * * @section stm32f1xx_hal_1 Supported HW resources @@ -44,11 +44,11 @@ * - SYSTICK initialization based on current clock and kernel required rate. * - DMA support initialization. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ /** - * @defgroup STM32_ADC STM32F1xx ADC Support + * @defgroup STM32F1xx_ADC STM32F1xx ADC Support * @details The STM32F1xx ADC driver supports the ADC peripherals using DMA * channels for maximum performance. * @@ -64,11 +64,11 @@ * - Programmable DMA interrupt priority for each DMA channel. * - DMA errors detection. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ /** - * @defgroup STM32_CAN STM32F1xx CAN Support + * @defgroup STM32F1xx_CAN STM32F1xx CAN Support * @details The STM32F1xx CAN driver uses the CAN peripherals. * * @section stm32f1xx_can_1 Supported HW resources @@ -79,11 +79,11 @@ * - Support for bxCAN sleep mode. * - Programmable bxCAN interrupts priority level. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ /** - * @defgroup STM32_DMA STM32F1xx DMA Support + * @defgroup STM32F1xx_DMA STM32F1xx DMA Support * @details This DMA helper driver is used by the other drivers in order to * access the shared DMA resources in a consistent way. * @@ -98,11 +98,11 @@ * - Automatic DMA clock stop when not in use by any driver. * - DMA streams and interrupt vectors sharing among multiple drivers. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ /** - * @defgroup STM32_EXT STM32F1xx EXT Support + * @defgroup STM32F1xx_EXT STM32F1xx EXT Support * @details The STM32F1xx EXT driver uses the EXTI peripheral. * * @section stm32f1xx_ext_1 Supported HW resources @@ -113,11 +113,11 @@ * - Programmable EXTI interrupts priority level. * - Capability to work as event sources (WFE) rather than interrupt sources. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ /** - * @defgroup STM32_GPT STM32F1xx GPT Support + * @defgroup STM32F1xx_GPT STM32F1xx GPT Support * @details The STM32F1xx GPT driver uses the TIMx peripherals. * * @section stm32f1xx_gpt_1 Supported HW resources @@ -132,11 +132,11 @@ * peripherals are left in low power mode. * - Programmable TIMx interrupts priority level. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ /** - * @defgroup STM32_I2C STM32F1xx I2C Support + * @defgroup STM32F1xx_I2C STM32F1xx I2C Support * @details The STM32F1xx I2C driver uses the I2Cx peripherals. * * @section stm32f1xx_i2c_1 Supported HW resources @@ -148,11 +148,11 @@ * peripherals are left in low power mode. * - Programmable I2Cx interrupts priority level. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ /** - * @defgroup STM32_ICU STM32F1xx ICU Support + * @defgroup STM32F1xx_ICU STM32F1xx ICU Support * @details The STM32F1xx ICU driver uses the TIMx peripherals. * * @section stm32f1xx_icu_1 Supported HW resources @@ -167,21 +167,21 @@ * peripherals are left in low power mode. * - Programmable TIMx interrupts priority level. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ /** - * @defgroup STM32_MAC STM32F1xx MAC Support + * @defgroup STM32F1xx_MAC STM32F1xx MAC Support * @details The STM32 MAC driver supports the ETH peripheral. * * @section at91sam7_mac_1 Supported HW resources * - ETH. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ /** - * @defgroup STM32_PAL STM32F1xx PAL Support + * @defgroup STM32F1xx_PAL STM32F1xx PAL Support * @details The STM32F1xx PAL driver uses the GPIO peripherals. * * @section stm32f1xx_pal_1 Supported HW resources @@ -213,8 +213,8 @@ * - @p PAL_MODE_INPUT_ANALOG. * - @p PAL_MODE_OUTPUT_PUSHPULL. * - @p PAL_MODE_OUTPUT_OPENDRAIN. - * - @p PAL_MODE_STM32_ALTERNATE_PUSHPULL (non standard). - * - @p PAL_MODE_STM32_ALTERNATE_OPENDRAIN (non standard). + * - @p PAL_MODE_STM32F1xx_ALTERNATE_PUSHPULL (non standard). + * - @p PAL_MODE_STM32F1xx_ALTERNATE_OPENDRAIN (non standard). * . * Any attempt to setup an invalid mode is ignored. * @@ -227,11 +227,11 @@ * resistor can change the resistor setting because the output latch is * used for resistor selection. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ /** - * @defgroup STM32_PWM STM32F1xx PWM Support + * @defgroup STM32F1xx_PWM STM32F1xx PWM Support * @details The STM32F1xx PWM driver uses the TIMx peripherals. * * @section stm32f1xx_pwm_1 Supported HW resources @@ -247,11 +247,11 @@ * - Four independent PWM channels per timer. * - Programmable TIMx interrupts priority level. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ /** - * @defgroup STM32_RCC STM32F1xx RCC Support + * @defgroup STM32F1xx_RCC STM32F1xx RCC Support * @details This RCC helper driver is used by the other drivers in order to * access the shared RCC resources in a consistent way. * @@ -263,21 +263,21 @@ * - Peripherals clock enable. * - Periplerals clock disable. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ /** - * @defgroup STM32_RTC STM32F1xx RTC Support + * @defgroup STM32F1xx_RTC STM32F1xx RTC Support * @details The STM32F1xx RTC driver uses the RTC peripheral. * * @section stm32f1xx_rtc_1 Supported HW resources * - RTC. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ /** - * @defgroup STM32_SDC STM32F1xx SDC Support + * @defgroup STM32F1xx_SDC STM32F1xx SDC Support * @details The STM32F1xx SDC driver uses the SDIO peripheral. * * @section stm32f1xx_sdc_1 Supported HW resources @@ -290,11 +290,11 @@ * - DMA is used for receiving and transmitting. * - Programmable DMA bus priority for each DMA channel. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ /** - * @defgroup STM32_SERIAL STM32F1xx Serial Support + * @defgroup STM32F1xx_SERIAL STM32F1xx Serial Support * @details The STM32F1xx Serial driver uses the USART/UART peripherals in a * buffered, interrupt driven, implementation. * @@ -313,11 +313,11 @@ * - Fully interrupt driven. * - Programmable priority levels for each UART/USART. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ /** - * @defgroup STM32_SPI STM32F1xx SPI Support + * @defgroup STM32F1xx_SPI STM32F1xx SPI Support * @details The SPI driver supports the STM32F1xx SPI peripherals using DMA * channels for maximum performance. * @@ -338,11 +338,11 @@ * - Programmable DMA interrupt priority for each DMA channel. * - Programmable DMA error hook. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ /** - * @defgroup STM32_UART STM32F1xx UART Support + * @defgroup STM32F1xx_UART STM32F1xx UART Support * @details The UART driver supports the STM32F1xx USART peripherals using DMA * channels for maximum performance. * @@ -365,11 +365,11 @@ * - Programmable DMA interrupt priority for each DMA channel. * - Programmable DMA error hook. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ /** - * @defgroup STM32_USB STM32F1xx USB Support + * @defgroup STM32F1xx_USB STM32F1xx USB Support * @details The USB driver supports the STM32F1xx USB peripheral. * * @section stm32f1xx_usb_1 Supported HW resources @@ -381,5 +381,5 @@ * - Programmable interrupt priority levels. * - Each endpoint programmable in Control, Bulk and Interrupt modes. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32F1xx_DRIVERS */ diff --git a/os/hal/platforms/STM32L1xx/platform.dox b/os/hal/platforms/STM32L1xx/platform.dox index 773785a5b..18a788ed0 100644 --- a/os/hal/platforms/STM32L1xx/platform.dox +++ b/os/hal/platforms/STM32L1xx/platform.dox @@ -19,7 +19,7 @@ */ /** - * @defgroup STM32_DRIVERS STM32L1xx Drivers + * @defgroup STM32L1xx_DRIVERS STM32L1xx Drivers * @details This section describes all the supported drivers on the STM32L1xx * platform and the implementation details of the single drivers. * @@ -27,7 +27,7 @@ */ /** - * @defgroup STM32_HAL STM32L1xx Initialization Support + * @defgroup STM32L1xx_HAL STM32L1xx Initialization Support * @details The STM32L1xx HAL support is responsible for system initialization. * * @section stm32l1xx_hal_1 Supported HW resources @@ -43,11 +43,11 @@ * - SYSTICK initialization based on current clock and kernel required rate. * - DMA support initialization. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32L1xx_DRIVERS */ /** - * @defgroup STM32_ADC STM32L1xx ADC Support + * @defgroup STM32L1xx_ADC STM32L1xx ADC Support * @details The STM32L1xx ADC driver supports the ADC peripherals using DMA * channels for maximum performance. * @@ -63,11 +63,11 @@ * - Programmable DMA interrupt priority for each DMA channel. * - DMA and ADC errors detection. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32L1xx_DRIVERS */ /** - * @defgroup STM32_DMA STM32L1xx DMA Support + * @defgroup STM32L1xx_DMA STM32L1xx DMA Support * @details This DMA helper driver is used by the other drivers in order to * access the shared DMA resources in a consistent way. * @@ -81,11 +81,11 @@ * - Automatic DMA clock stop when not in use by any driver. * - DMA streams and interrupt vectors sharing among multiple drivers. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32L1xx_DRIVERS */ /** - * @defgroup STM32_EXT STM32L1xx EXT Support + * @defgroup STM32L1xx_EXT STM32L1xx EXT Support * @details The STM32L1xx EXT driver uses the EXTI peripheral. * * @section stm32l1xx_ext_1 Supported HW resources @@ -96,11 +96,11 @@ * - Programmable EXTI interrupts priority level. * - Capability to work as event sources (WFE) rather than interrupt sources. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32L1xx_DRIVERS */ /** - * @defgroup STM32_GPT STM32L1xx GPT Support + * @defgroup STM32L1xx_GPT STM32L1xx GPT Support * @details The STM32L1xx GPT driver uses the TIMx peripherals. * * @section stm32l1xx_gpt_1 Supported HW resources @@ -113,11 +113,11 @@ * peripherals are left in low power mode. * - Programmable TIMx interrupts priority level. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32L1xx_DRIVERS */ /** - * @defgroup STM32_ICU STM32L1xx ICU Support + * @defgroup STM32L1xx_ICU STM32L1xx ICU Support * @details The STM32L1xx ICU driver uses the TIMx peripherals. * * @section stm32l1xx_icu_1 Supported HW resources @@ -130,11 +130,11 @@ * peripherals are left in low power mode. * - Programmable TIMx interrupts priority level. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32L1xx_DRIVERS */ /** - * @defgroup STM32_PAL STM32L1xx PAL Support + * @defgroup STM32L1xx_PAL STM32L1xx PAL Support * @details The STM32L1xx PAL driver uses the GPIO peripherals. * * @section stm32l1xx_pal_1 Supported HW resources @@ -174,11 +174,11 @@ * - Pad/port toggling operations are not atomic. * - Pad/group mode setup is not atomic. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32L1xx_DRIVERS */ /** - * @defgroup STM32_PWM STM32L1xx PWM Support + * @defgroup STM32L1xx_PWM STM32L1xx PWM Support * @details The STM32L1xx PWM driver uses the TIMx peripherals. * * @section stm32l1xx_pwm_1 Supported HW resources @@ -194,27 +194,27 @@ * - Four independent PWM channels per timer. * - Programmable TIMx interrupts priority level. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32L1xx_DRIVERS */ /** - * @defgroup STM32_RCC STM32F1xx RCC Support + * @defgroup STM32L1xx_RCC STM32L1xx RCC Support * @details This RCC helper driver is used by the other drivers in order to * access the shared RCC resources in a consistent way. * * @section stm32f1xx_rcc_1 Supported HW resources * - RCC. * . - * @section stm32f1xx_rcc_2 STM32F1xx RCC driver implementation features + * @section stm32l1xx_rcc_2 STM32L1xx RCC driver implementation features * - Peripherals reset. * - Peripherals clock enable. * - Periplerals clock disable. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32L1xx_DRIVERS */ /** - * @defgroup STM32_SERIAL STM32L1xx Serial Support + * @defgroup STM32L1xx_SERIAL STM32L1xx Serial Support * @details The STM32L1xx Serial driver uses the USART/UART peripherals in a * buffered, interrupt driven, implementation. * @@ -233,11 +233,11 @@ * - Fully interrupt driven. * - Programmable priority levels for each UART/USART. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32L1xx_DRIVERS */ /** - * @defgroup STM32_SPI STM32L1xx SPI Support + * @defgroup STM32L1xx_SPI STM32L1xx SPI Support * @details The SPI driver supports the STM32L1xx SPI peripherals using DMA * channels for maximum performance. * @@ -258,11 +258,11 @@ * - Programmable DMA interrupt priority for each DMA channel. * - Programmable DMA error hook. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32L1xx_DRIVERS */ /** - * @defgroup STM32_UART STM32L1xx UART Support + * @defgroup STM32L1xx_UART STM32L1xx UART Support * @details The UART driver supports the STM32L1xx USART peripherals using DMA * channels for maximum performance. * @@ -285,11 +285,11 @@ * - Programmable DMA interrupt priority for each DMA channel. * - Programmable DMA error hook. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32L1xx_DRIVERS */ /** - * @defgroup STM32_USB STM32L1xx USB Support + * @defgroup STM32L1xx_USB STM32L1xx USB Support * @details The USB driver supports the STM32L1xx USB peripheral. * * @section stm32l1xx_usb_1 Supported HW resources @@ -301,5 +301,5 @@ * - Programmable interrupt priority levels. * - Each endpoint programmable in Control, Bulk and Interrupt modes. * . - * @ingroup STM32_DRIVERS + * @ingroup STM32L1xx_DRIVERS */ -- cgit v1.2.3 From 65d15d42c446b5f30e549fdeadfe88f963d2ee55 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 2 Oct 2011 11:20:09 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3420 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/platform.dox | 79 ++++++++++++++++++--------------- os/hal/platforms/STM32L1xx/platform.dox | 77 ++++++++++++++++++-------------- 2 files changed, 87 insertions(+), 69 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/platform.dox b/os/hal/platforms/STM32F1xx/platform.dox index 2f282e4d5..c9d43a80e 100644 --- a/os/hal/platforms/STM32F1xx/platform.dox +++ b/os/hal/platforms/STM32F1xx/platform.dox @@ -82,25 +82,6 @@ * @ingroup STM32F1xx_DRIVERS */ -/** - * @defgroup STM32F1xx_DMA STM32F1xx DMA Support - * @details This DMA helper driver is used by the other drivers in order to - * access the shared DMA resources in a consistent way. - * - * @section stm32f1xx_dma_1 Supported HW resources - * The DMA driver can support any of the following hardware resources: - * - DMA1. - * - DMA2 (where present). - * . - * @section stm32f1xx_dma_2 STM32F1xx DMA driver implementation features - * - Exports helper functions/macros to the other drivers that share the - * DMA resource. - * - Automatic DMA clock stop when not in use by any driver. - * - DMA streams and interrupt vectors sharing among multiple drivers. - * . - * @ingroup STM32F1xx_DRIVERS - */ - /** * @defgroup STM32F1xx_EXT STM32F1xx EXT Support * @details The STM32F1xx EXT driver uses the EXTI peripheral. @@ -250,22 +231,6 @@ * @ingroup STM32F1xx_DRIVERS */ -/** - * @defgroup STM32F1xx_RCC STM32F1xx RCC Support - * @details This RCC helper driver is used by the other drivers in order to - * access the shared RCC resources in a consistent way. - * - * @section stm32f1xx_rcc_1 Supported HW resources - * - RCC. - * . - * @section stm32f1xx_rcc_2 STM32F1xx RCC driver implementation features - * - Peripherals reset. - * - Peripherals clock enable. - * - Periplerals clock disable. - * . - * @ingroup STM32F1xx_DRIVERS - */ - /** * @defgroup STM32F1xx_RTC STM32F1xx RTC Support * @details The STM32F1xx RTC driver uses the RTC peripheral. @@ -383,3 +348,47 @@ * . * @ingroup STM32F1xx_DRIVERS */ + +/** + * @defgroup STM32F1xx_PLATFORM_DRIVERS STM32F1xx Platform Drivers + * @details Platform support drivers. Platform drivers do not implement HAL + * standard driver templates, their role is to support platform + * specific functionalities. + * + * @ingroup STM32F1xx_DRIVERS + */ + +/** + * @defgroup STM32F1xx_DMA STM32F1xx DMA Support + * @details This DMA helper driver is used by the other drivers in order to + * access the shared DMA resources in a consistent way. + * + * @section stm32f1xx_dma_1 Supported HW resources + * The DMA driver can support any of the following hardware resources: + * - DMA1. + * - DMA2 (where present). + * . + * @section stm32f1xx_dma_2 STM32F1xx DMA driver implementation features + * - Exports helper functions/macros to the other drivers that share the + * DMA resource. + * - Automatic DMA clock stop when not in use by any driver. + * - DMA streams and interrupt vectors sharing among multiple drivers. + * . + * @ingroup STM32F1xx_PLATFORM_DRIVERS + */ + +/** + * @defgroup STM32F1xx_RCC STM32F1xx RCC Support + * @details This RCC helper driver is used by the other drivers in order to + * access the shared RCC resources in a consistent way. + * + * @section stm32f1xx_rcc_1 Supported HW resources + * - RCC. + * . + * @section stm32f1xx_rcc_2 STM32F1xx RCC driver implementation features + * - Peripherals reset. + * - Peripherals clock enable. + * - Periplerals clock disable. + * . + * @ingroup STM32F1xx_PLATFORM_DRIVERS + */ diff --git a/os/hal/platforms/STM32L1xx/platform.dox b/os/hal/platforms/STM32L1xx/platform.dox index 18a788ed0..33bf706ab 100644 --- a/os/hal/platforms/STM32L1xx/platform.dox +++ b/os/hal/platforms/STM32L1xx/platform.dox @@ -66,24 +66,6 @@ * @ingroup STM32L1xx_DRIVERS */ -/** - * @defgroup STM32L1xx_DMA STM32L1xx DMA Support - * @details This DMA helper driver is used by the other drivers in order to - * access the shared DMA resources in a consistent way. - * - * @section stm32l1xx_dma_1 Supported HW resources - * The DMA driver can support any of the following hardware resources: - * - DMA1. - * . - * @section stm32l1xx_dma_2 STM32L1xx DMA driver implementation features - * - Exports helper functions/macros to the other drivers that share the - * DMA resource. - * - Automatic DMA clock stop when not in use by any driver. - * - DMA streams and interrupt vectors sharing among multiple drivers. - * . - * @ingroup STM32L1xx_DRIVERS - */ - /** * @defgroup STM32L1xx_EXT STM32L1xx EXT Support * @details The STM32L1xx EXT driver uses the EXTI peripheral. @@ -197,22 +179,6 @@ * @ingroup STM32L1xx_DRIVERS */ -/** - * @defgroup STM32L1xx_RCC STM32L1xx RCC Support - * @details This RCC helper driver is used by the other drivers in order to - * access the shared RCC resources in a consistent way. - * - * @section stm32f1xx_rcc_1 Supported HW resources - * - RCC. - * . - * @section stm32l1xx_rcc_2 STM32L1xx RCC driver implementation features - * - Peripherals reset. - * - Peripherals clock enable. - * - Periplerals clock disable. - * . - * @ingroup STM32L1xx_DRIVERS - */ - /** * @defgroup STM32L1xx_SERIAL STM32L1xx Serial Support * @details The STM32L1xx Serial driver uses the USART/UART peripherals in a @@ -303,3 +269,46 @@ * . * @ingroup STM32L1xx_DRIVERS */ + +/** + * @defgroup STM32L1xx_PLATFORM_DRIVERS STM32L1xx Platform Drivers + * @details Platform support drivers. Platform drivers do not implement HAL + * standard driver templates, their role is to support platform + * specific functionalities. + * + * @ingroup STM32L1xx_DRIVERS + */ + +/** + * @defgroup STM32L1xx_DMA STM32L1xx DMA Support + * @details This DMA helper driver is used by the other drivers in order to + * access the shared DMA resources in a consistent way. + * + * @section stm32l1xx_dma_1 Supported HW resources + * The DMA driver can support any of the following hardware resources: + * - DMA1. + * . + * @section stm32l1xx_dma_2 STM32L1xx DMA driver implementation features + * - Exports helper functions/macros to the other drivers that share the + * DMA resource. + * - Automatic DMA clock stop when not in use by any driver. + * - DMA streams and interrupt vectors sharing among multiple drivers. + * . + * @ingroup STM32L1xx_PLATFORM_DRIVERS + */ + +/** + * @defgroup STM32L1xx_RCC STM32L1xx RCC Support + * @details This RCC helper driver is used by the other drivers in order to + * access the shared RCC resources in a consistent way. + * + * @section stm32f1xx_rcc_1 Supported HW resources + * - RCC. + * . + * @section stm32l1xx_rcc_2 STM32L1xx RCC driver implementation features + * - Peripherals reset. + * - Peripherals clock enable. + * - Periplerals clock disable. + * . + * @ingroup STM32L1xx_PLATFORM_DRIVERS + */ -- cgit v1.2.3 From a2109bf01e8910ca1cc16a109cf6911fbd2323fa Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 2 Oct 2011 11:30:06 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3421 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/stm32_rcc.h | 2 +- os/hal/platforms/STM32L1xx/stm32_rcc.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/stm32_rcc.h b/os/hal/platforms/STM32F1xx/stm32_rcc.h index 0f19f7b07..2a5daaadd 100644 --- a/os/hal/platforms/STM32F1xx/stm32_rcc.h +++ b/os/hal/platforms/STM32F1xx/stm32_rcc.h @@ -24,7 +24,7 @@ * @note This file requires definitions from the ST header file * @p stm32f10x.h. * - * @addtogroup STM32_RCC + * @addtogroup STM32F1xx_RCC * @{ */ diff --git a/os/hal/platforms/STM32L1xx/stm32_rcc.h b/os/hal/platforms/STM32L1xx/stm32_rcc.h index abad4f96b..e2460a41f 100644 --- a/os/hal/platforms/STM32L1xx/stm32_rcc.h +++ b/os/hal/platforms/STM32L1xx/stm32_rcc.h @@ -24,7 +24,7 @@ * @note This file requires definitions from the ST header file * @p stm32l1xx.h. * - * @addtogroup STM32_RCC + * @addtogroup STM32L1xx_RCC * @{ */ -- cgit v1.2.3 From 9422ad779cb626290d92db6144bce33eaa5758f1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 4 Oct 2011 20:01:46 +0000 Subject: Fixed bug 3418620. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3424 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/pwm_lld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/pwm_lld.c b/os/hal/platforms/STM32/pwm_lld.c index d8f98a432..ab3c1c2bb 100644 --- a/os/hal/platforms/STM32/pwm_lld.c +++ b/os/hal/platforms/STM32/pwm_lld.c @@ -327,7 +327,7 @@ void pwm_lld_init(void) { #if STM32_PWM_USE_TIM8 /* Driver initialization.*/ pwmObjectInit(&PWMD8); - PWMD5.tim = TIM8; + PWMD8.tim = TIM8; #endif } -- cgit v1.2.3 From 1351fded5a9c460166637d276616a73be0b72392 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 5 Oct 2011 17:00:13 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3426 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/stm32_dma.c | 4 +-- os/hal/platforms/STM32/DMAv1/stm32_dma.h | 55 ++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.c b/os/hal/platforms/STM32/DMAv1/stm32_dma.c index 3fb1b2dc6..84e372c26 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.c @@ -100,8 +100,8 @@ const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { * @brief DMA ISR redirector type. */ typedef struct { - stm32_dmaisr_t dma_func; - void *dma_param; + stm32_dmaisr_t dma_func; /**< @brief DMA callback function. */ + void *dma_param; /**< @brief DMA callback parameter. */ } dma_isr_redir_t; /** diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.h b/os/hal/platforms/STM32/DMAv1/stm32_dma.h index 22be4a67e..f209898d4 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.h @@ -153,6 +153,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /** * @brief Associates a peripheral data register to a DMA stream. * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @param[in] addr value to be written in the CPAR register @@ -166,6 +168,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /** * @brief Associates a memory destination to a DMA stream. * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @param[in] addr value to be written in the CMAR register @@ -179,6 +183,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /** * @brief Sets the number of transfers to be performed. * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @param[in] size value to be written in the CNDTR register @@ -192,6 +198,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /** * @brief Returns the number of transfers to be performed. * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @return The number of transfers to be performed. @@ -203,6 +211,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /** * @brief Programs the stream mode settings. * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @param[in] mode value to be written in the CCR register @@ -216,6 +226,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /** * @brief DMA stream enable. * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @@ -228,6 +240,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /** * @brief DMA stream disable. * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @@ -240,6 +254,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /** * @brief DMA stream interrupt sources clear. * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @@ -249,6 +265,45 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \ } +/** + * @brief Starts a memory to memory operation using the specified stream. + * @note The default transfer data mode is "byte to byte" but it can be + * changed by specifying extra options in the @p mode parameter. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] mode value to be written in the CCR register, this value + * is implicitly ORed with: + * - @p STM32_DMA_CR_MINC + * - @p STM32_DMA_CR_PINC + * - @p STM32_DMA_CR_DIR_M2M + * - @p STM32_DMA_CR_EN + * . + * @param[in] src source address + * @param[in] dst destination address + * @param[in] n number of data units to copy + */ +#define dmaStartMemCopy(dmastp, mode, src, dst, n) { \ + dmaStreamSetPeripheral(dmastp, src); \ + dmaStreamSetMemory0(dmastp, dst); \ + dmaStreamGetTransactionSize(dmastp, n); \ + dmaStreamSetMode(dmastp, (mode) | \ + STM32_DMA_CR_MINC | STM32_DMA_CR_PINC | \ + STM32_DMA_CR_DIR_M2M | STM32_DMA_CR_EN); \ +} + +/** + * @brief Polled wait for DMA transfer end. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + */ +#define dmaWaitCompletion(dmastp) \ + while (((dmastp)->channel->CNDTR > 0) && \ + ((dmastp)->channel->CCR & STM32_DMA_CR_EN)) + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ -- cgit v1.2.3 From 7e567dedc7a496257a00660a14cf3dfbc571a59c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 8 Oct 2011 10:33:31 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3429 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/stm32_dma.c | 497 ------------------------------- os/hal/platforms/STM32/DMAv1/stm32_dma.h | 330 -------------------- os/hal/platforms/STM32F1xx/platform.mk | 4 +- os/hal/platforms/STM32F1xx/stm32_dma.c | 497 +++++++++++++++++++++++++++++++ os/hal/platforms/STM32F1xx/stm32_dma.h | 330 ++++++++++++++++++++ 5 files changed, 829 insertions(+), 829 deletions(-) delete mode 100644 os/hal/platforms/STM32/DMAv1/stm32_dma.c delete mode 100644 os/hal/platforms/STM32/DMAv1/stm32_dma.h create mode 100644 os/hal/platforms/STM32F1xx/stm32_dma.c create mode 100644 os/hal/platforms/STM32F1xx/stm32_dma.h (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.c b/os/hal/platforms/STM32/DMAv1/stm32_dma.c deleted file mode 100644 index 84e372c26..000000000 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.c +++ /dev/null @@ -1,497 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT 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 DMAv1/stm32_dma.c - * @brief DMA helper driver code. - * - * @addtogroup STM32_DMA - * @details DMA sharing helper driver. In the STM32 the DMA streams are a - * shared resource, this driver allows to allocate and free DMA - * streams at runtime in order to allow all the other device - * drivers to coordinate the access to the resource. - * @note The DMA ISR handlers are all declared into this module because - * sharing, the various device drivers can associate a callback to - * IRSs when allocating streams. - * @{ - */ - -#include "ch.h" -#include "hal.h" - -/* The following macro is only defined if some driver requiring DMA services - has been enabled.*/ -#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/** - * @brief Mask of the DMA1 streams in @p dma_streams_mask. - */ -#define STM32_DMA1_STREAMS_MASK 0x0000007F - -/** - * @brief Mask of the DMA2 streams in @p dma_streams_mask. - */ -#define STM32_DMA2_STREAMS_MASK 0x00000F80 - -/** - * @brief Post-reset value of the stream CCR register. - */ -#define STM32_DMA_CCR_RESET_VALUE 0x00000000 - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief DMA 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_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc. - */ -const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { - {DMA1_Channel1, &DMA1->IFCR, 0, 0, DMA1_Channel1_IRQn}, - {DMA1_Channel2, &DMA1->IFCR, 4, 1, DMA1_Channel2_IRQn}, - {DMA1_Channel3, &DMA1->IFCR, 8, 2, DMA1_Channel3_IRQn}, - {DMA1_Channel4, &DMA1->IFCR, 12, 3, DMA1_Channel4_IRQn}, - {DMA1_Channel5, &DMA1->IFCR, 16, 4, DMA1_Channel5_IRQn}, - {DMA1_Channel6, &DMA1->IFCR, 20, 5, DMA1_Channel6_IRQn}, - {DMA1_Channel7, &DMA1->IFCR, 24, 6, DMA1_Channel7_IRQn}, -#if STM32_HAS_DMA2 || defined(__DOXYGEN__) - {DMA2_Channel1, &DMA2->IFCR, 0, 7, DMA2_Channel1_IRQn}, - {DMA2_Channel2, &DMA2->IFCR, 4, 8, DMA2_Channel2_IRQn}, - {DMA2_Channel3, &DMA2->IFCR, 8, 9, DMA2_Channel3_IRQn}, -#if defined(STM32F10X_CL) || defined(__DOXYGEN__) - {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_IRQn}, - {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel5_IRQn}, -#else /* !STM32F10X_CL */ - {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_5_IRQn}, - {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel4_5_IRQn}, -#endif /* !STM32F10X_CL */ -#endif /* STM32_HAS_DMA2 */ -}; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/** - * @brief DMA ISR redirector type. - */ -typedef struct { - stm32_dmaisr_t dma_func; /**< @brief DMA callback function. */ - void *dma_param; /**< @brief DMA callback parameter. */ -} dma_isr_redir_t; - -/** - * @brief Mask of the allocated streams. - */ -static uint32_t dma_streams_mask; - -/** - * @brief DMA IRQ redirectors. - */ -static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS]; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/** - * @brief DMA1 stream 1 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 0) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 0; - if (dma_isr_redir[0].dma_func) - dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 2 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 4; - if (dma_isr_redir[1].dma_func) - dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 3 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 8; - if (dma_isr_redir[2].dma_func) - dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 4 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 12; - if (dma_isr_redir[3].dma_func) - dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 5 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 16; - if (dma_isr_redir[4].dma_func) - dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 6 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 20; - if (dma_isr_redir[5].dma_func) - dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 7 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 24; - if (dma_isr_redir[6].dma_func) - dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -#if STM32_HAS_DMA2 || defined(__DOXYGEN__) -/** - * @brief DMA2 stream 1 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->ISR >> 0) & STM32_DMA_ISR_MASK; - DMA2->IFCR = STM32_DMA_ISR_MASK << 0; - if (dma_isr_redir[7].dma_func) - dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA2 stream 2 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->ISR >> 4) & STM32_DMA_ISR_MASK; - DMA2->IFCR = STM32_DMA_ISR_MASK << 4; - if (dma_isr_redir[8].dma_func) - dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA2 stream 3 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch3_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->ISR >> 8) & STM32_DMA_ISR_MASK; - DMA2->IFCR = STM32_DMA_ISR_MASK << 8; - if (dma_isr_redir[9].dma_func) - dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -#if defined(STM32F10X_CL) || defined(__DOXYGEN__) -/** - * @brief DMA2 stream 4 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch4_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; - DMA2->IFCR = STM32_DMA_ISR_MASK << 12; - if (dma_isr_redir[10].dma_func) - dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA2 stream 5 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch5_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; - DMA2->IFCR = STM32_DMA_ISR_MASK << 16; - if (dma_isr_redir[11].dma_func) - dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} -#else /* !STM32F10X_CL */ -/** - * @brief DMA2 streams 4 and 5 shared interrupt handler. - * @note This IRQ is shared between DMA2 channels 4 and 5 so it is a - * bit less efficient because an extra check. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - /* Check on channel 4.*/ - flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; - if (flags & STM32_DMA_ISR_MASK) { - DMA2->IFCR = STM32_DMA_ISR_MASK << 12; - if (dma_isr_redir[10].dma_func) - dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); - } - - /* Check on channel 5.*/ - flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; - if (flags & STM32_DMA_ISR_MASK) { - DMA2->IFCR = STM32_DMA_ISR_MASK << 16; - if (dma_isr_redir[11].dma_func) - dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); - } - - CH_IRQ_EPILOGUE(); -} -#endif /* !STM32F10X_CL */ -#endif /* STM32_HAS_DMA2 */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief STM32 DMA helper initialization. - * - * @init - */ -void dmaInit(void) { - int i; - - dma_streams_mask = 0; - for (i = 0; i < STM32_DMA_STREAMS; i++) { - _stm32_dma_streams[i].channel->CCR = 0; - dma_isr_redir[i].dma_func = NULL; - } - DMA1->IFCR = 0xFFFFFFFF; -#if STM32_HAS_DMA2 - DMA2->IFCR = 0xFFFFFFFF; -#endif -} - -/** - * @brief Allocates a DMA stream. - * @details The stream is allocated and, if required, the DMA clock enabled. - * The function also enables the IRQ vector associated to the stream - * and initializes its priority. - * @pre The stream must not be already in use or an error is returned. - * @post The stream is allocated and the default ISR handler redirected - * to the specified function. - * @post The stream ISR vector is enabled and its priority configured. - * @post The stream must be freed using @p dmaStreamRelease() before it can - * be reused with another peripheral. - * @post The stream is in its post-reset state. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] priority IRQ priority mask for the DMA stream - * @param[in] func handling function pointer, can be @p NULL - * @param[in] param a parameter to be passed to the handling function - * @return The operation status. - * @retval FALSE no error, stream taken. - * @retval TRUE error, stream already taken. - * - * @special - */ -bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, - uint32_t priority, - stm32_dmaisr_t func, - void *param) { - - chDbgCheck(dmastp != NULL, "dmaAllocate"); - - /* Checks if the stream is already taken.*/ - if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0) - return TRUE; - - /* Marks the stream as allocated.*/ - dma_isr_redir[dmastp->selfindex].dma_func = func; - dma_isr_redir[dmastp->selfindex].dma_param = param; - dma_streams_mask |= (1 << dmastp->selfindex); - - /* Enabling DMA clocks required by the current streams set.*/ - if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) - rccEnableDMA1(FALSE); -#if STM32_HAS_DMA2 - if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) - rccEnableDMA2(FALSE); -#endif - - /* Putting the stream in a safe state.*/ - dmaStreamDisable(dmastp); - dmaStreamClearInterrupt(dmastp); - dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; - - /* Enables the associated IRQ vector if a callback is defined.*/ - if (func != NULL) - NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority)); - - return FALSE; -} - -/** - * @brief Releases a DMA stream. - * @details The stream is freed and, if required, the DMA clock disabled. - * Trying to release a unallocated stream is an illegal operation - * and is trapped if assertions are enabled. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post The stream is again available. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * - * @special - */ -void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { - - chDbgCheck(dmastp != NULL, "dmaRelease"); - - /* Check if the streams is not taken.*/ - chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0, - "dmaRelease(), #1", "not allocated"); - - /* Disables the associated IRQ vector.*/ - NVICDisableVector(dmastp->vector); - - /* Marks the stream as not allocated.*/ - dma_streams_mask &= ~(1 << dmastp->selfindex); - - /* Shutting down clocks that are no more required, if any.*/ - if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) - rccDisableDMA1(FALSE); -#if STM32_HAS_DMA2 - if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) - rccDisableDMA2(FALSE); -#endif -} - -#endif /* STM32_DMA_REQUIRED */ - -/** @} */ diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.h b/os/hal/platforms/STM32/DMAv1/stm32_dma.h deleted file mode 100644 index f209898d4..000000000 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.h +++ /dev/null @@ -1,330 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT 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 DMAv1/stm32_dma.h - * @brief DMA helper driver header. - * @note This file requires definitions from the ST header files - * stm32f10x.h or stm32l1xx.h. - * @note This driver uses the new naming convention used for the STM32F2xx - * so the "DMA channels" are referred as "DMA streams". - * - * @addtogroup STM32_DMA - * @{ - */ - -#ifndef _STM32_DMA_H_ -#define _STM32_DMA_H_ - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @brief Total number of DMA streams. - * @note This is the total number of streams among all the DMA units. - */ -#if STM32_HAS_DMA2 || defined(__DOXYGEN__) -#define STM32_DMA_STREAMS 12 -#else -#define STM32_DMA_STREAMS 7 -#endif - -/** - * @brief Mask of the ISR bits passed to the DMA callback functions. - */ -#define STM32_DMA_ISR_MASK 0x0F - -/** - * @name DMA streams identifiers - * @{ - */ -#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[0]) -#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[1]) -#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[2]) -#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[3]) -#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[4]) -#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[5]) -#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[6]) -#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[7]) -#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[8]) -#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[9]) -#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[10]) -#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[11]) -/** @} */ - -/** - * @name CR register constants common to all DMA types - */ -#define STM32_DMA_CR_EN DMA_CCR1_EN -#define STM32_DMA_CR_TEIE DMA_CCR1_TEIE -#define STM32_DMA_CR_HTIE DMA_CCR1_HTIE -#define STM32_DMA_CR_TCIE DMA_CCR1_TCIE -#define STM32_DMA_CR_DIR_MASK (DMA_CCR1_DIR | DMA_CCR1_MEM2MEM) -#define STM32_DMA_CR_DIR_P2M 0 -#define STM32_DMA_CR_DIR_M2P DMA_CCR1_DIR -#define STM32_DMA_CR_DIR_M2M DMA_CCR1_MEM2MEM -#define STM32_DMA_CR_CIRC DMA_CCR1_CIRC -#define STM32_DMA_CR_PINC DMA_CCR1_PINC -#define STM32_DMA_CR_MINC DMA_CCR1_MINC -#define STM32_DMA_CR_PSIZE_MASK DMA_CCR1_PSIZE -#define STM32_DMA_CR_PSIZE_BYTE 0 -#define STM32_DMA_CR_PSIZE_HWORD DMA_CCR1_PSIZE_0 -#define STM32_DMA_CR_PSIZE_WORD DMA_CCR1_PSIZE_1 -#define STM32_DMA_CR_MSIZE_MASK DMA_CCR1_MSIZE -#define STM32_DMA_CR_MSIZE_BYTE 0 -#define STM32_DMA_CR_MSIZE_HWORD DMA_CCR1_MSIZE_0 -#define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1 -#define STM32_DMA_CR_PL_MASK DMA_CCR1_PL -#define STM32_DMA_CR_PL(n) ((n) << 12) -/** @} */ - -/** - * @name CR register constants only found in enhanced DMA - */ -#define STM32_DMA_CR_CHSEL_MASK 0 /**< @brief Ignored by normal DMA. */ -#define STM32_DMA_CR_CHSEL(n) 0 /**< @brief Ignored by normal DMA. */ -/** @} */ - -/** - * @name Status flags passed to the ISR callbacks - */ -#define STM32_DMA_ISR_FEIF 0 -#define STM32_DMA_ISR_DMEIF 0 -#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1 -#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1 -#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1 -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief STM32 DMA stream descriptor structure. - */ -typedef struct { - DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ - volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */ - uint8_t ishift; /**< @brief Bits offset in xIFCR - register. */ - uint8_t selfindex; /**< @brief Index to self in array. */ - uint8_t vector; /**< @brief Associated IRQ vector. */ -} stm32_dma_stream_t; - -/** - * @brief STM32 DMA ISR function type. - * - * @param[in] p parameter for the registered function - * @param[in] flags pre-shifted content of the ISR register, the bits - * are aligned to bit zero - */ -typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/** - * @brief Associates a peripheral data register to a DMA stream. - * @note This function can be invoked in both ISR or thread context. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] addr value to be written in the CPAR register - * - * @special - */ -#define dmaStreamSetPeripheral(dmastp, addr) { \ - (dmastp)->channel->CPAR = (uint32_t)(addr); \ -} - -/** - * @brief Associates a memory destination to a DMA stream. - * @note This function can be invoked in both ISR or thread context. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] addr value to be written in the CMAR register - * - * @special - */ -#define dmaStreamSetMemory0(dmastp, addr) { \ - (dmastp)->channel->CMAR = (uint32_t)(addr); \ -} - -/** - * @brief Sets the number of transfers to be performed. - * @note This function can be invoked in both ISR or thread context. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] size value to be written in the CNDTR register - * - * @special - */ -#define dmaStreamSetTransactionSize(dmastp, size) { \ - (dmastp)->channel->CNDTR = (uint32_t)(size); \ -} - -/** - * @brief Returns the number of transfers to be performed. - * @note This function can be invoked in both ISR or thread context. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @return The number of transfers to be performed. - * - * @special - */ -#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->CNDTR)) - -/** - * @brief Programs the stream mode settings. - * @note This function can be invoked in both ISR or thread context. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] mode value to be written in the CCR register - * - * @special - */ -#define dmaStreamSetMode(dmastp, mode) { \ - (dmastp)->channel->CCR = (uint32_t)(mode); \ -} - -/** - * @brief DMA stream enable. - * @note This function can be invoked in both ISR or thread context. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * - * @special - */ -#define dmaStreamEnable(dmastp) { \ - (dmastp)->channel->CCR |= STM32_DMA_CR_EN; \ -} - -/** - * @brief DMA stream disable. - * @note This function can be invoked in both ISR or thread context. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * - * @special - */ -#define dmaStreamDisable(dmastp) { \ - (dmastp)->channel->CCR &= ~STM32_DMA_CR_EN; \ -} - -/** - * @brief DMA stream interrupt sources clear. - * @note This function can be invoked in both ISR or thread context. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * - * @special - */ -#define dmaStreamClearInterrupt(dmastp) { \ - *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \ -} - -/** - * @brief Starts a memory to memory operation using the specified stream. - * @note The default transfer data mode is "byte to byte" but it can be - * changed by specifying extra options in the @p mode parameter. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] mode value to be written in the CCR register, this value - * is implicitly ORed with: - * - @p STM32_DMA_CR_MINC - * - @p STM32_DMA_CR_PINC - * - @p STM32_DMA_CR_DIR_M2M - * - @p STM32_DMA_CR_EN - * . - * @param[in] src source address - * @param[in] dst destination address - * @param[in] n number of data units to copy - */ -#define dmaStartMemCopy(dmastp, mode, src, dst, n) { \ - dmaStreamSetPeripheral(dmastp, src); \ - dmaStreamSetMemory0(dmastp, dst); \ - dmaStreamGetTransactionSize(dmastp, n); \ - dmaStreamSetMode(dmastp, (mode) | \ - STM32_DMA_CR_MINC | STM32_DMA_CR_PINC | \ - STM32_DMA_CR_DIR_M2M | STM32_DMA_CR_EN); \ -} - -/** - * @brief Polled wait for DMA transfer end. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - */ -#define dmaWaitCompletion(dmastp) \ - while (((dmastp)->channel->CNDTR > 0) && \ - ((dmastp)->channel->CCR & STM32_DMA_CR_EN)) - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if !defined(__DOXYGEN__) -extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void dmaInit(void); - bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, - uint32_t priority, - stm32_dmaisr_t func, - void *param); - void dmaStreamRelease(const stm32_dma_stream_t *dmastp); -#ifdef __cplusplus -} -#endif - -#endif /* _STM32_DMA_H_ */ - -/** @} */ diff --git a/os/hal/platforms/STM32F1xx/platform.mk b/os/hal/platforms/STM32F1xx/platform.mk index a73f1b4f3..5e42d1335 100644 --- a/os/hal/platforms/STM32F1xx/platform.mk +++ b/os/hal/platforms/STM32F1xx/platform.mk @@ -1,5 +1,6 @@ # List of all the STM32F1xx platform files. -PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F1xx/hal_lld.c \ +PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F1xx/stm32_dma.c \ + ${CHIBIOS}/os/hal/platforms/STM32F1xx/hal_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32F1xx/adc_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/can_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/ext_lld.c \ @@ -13,7 +14,6 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F1xx/hal_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/uart_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv1/pal_lld.c \ - ${CHIBIOS}/os/hal/platforms/STM32/DMAv1/stm32_dma.c \ ${CHIBIOS}/os/hal/platforms/STM32/USBv1/usb_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/RTCv1/rtc_lld.c diff --git a/os/hal/platforms/STM32F1xx/stm32_dma.c b/os/hal/platforms/STM32F1xx/stm32_dma.c new file mode 100644 index 000000000..84e372c26 --- /dev/null +++ b/os/hal/platforms/STM32F1xx/stm32_dma.c @@ -0,0 +1,497 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 DMAv1/stm32_dma.c + * @brief DMA helper driver code. + * + * @addtogroup STM32_DMA + * @details DMA sharing helper driver. In the STM32 the DMA streams are a + * shared resource, this driver allows to allocate and free DMA + * streams at runtime in order to allow all the other device + * drivers to coordinate the access to the resource. + * @note The DMA ISR handlers are all declared into this module because + * sharing, the various device drivers can associate a callback to + * IRSs when allocating streams. + * @{ + */ + +#include "ch.h" +#include "hal.h" + +/* The following macro is only defined if some driver requiring DMA services + has been enabled.*/ +#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/** + * @brief Mask of the DMA1 streams in @p dma_streams_mask. + */ +#define STM32_DMA1_STREAMS_MASK 0x0000007F + +/** + * @brief Mask of the DMA2 streams in @p dma_streams_mask. + */ +#define STM32_DMA2_STREAMS_MASK 0x00000F80 + +/** + * @brief Post-reset value of the stream CCR register. + */ +#define STM32_DMA_CCR_RESET_VALUE 0x00000000 + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief DMA 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_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc. + */ +const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { + {DMA1_Channel1, &DMA1->IFCR, 0, 0, DMA1_Channel1_IRQn}, + {DMA1_Channel2, &DMA1->IFCR, 4, 1, DMA1_Channel2_IRQn}, + {DMA1_Channel3, &DMA1->IFCR, 8, 2, DMA1_Channel3_IRQn}, + {DMA1_Channel4, &DMA1->IFCR, 12, 3, DMA1_Channel4_IRQn}, + {DMA1_Channel5, &DMA1->IFCR, 16, 4, DMA1_Channel5_IRQn}, + {DMA1_Channel6, &DMA1->IFCR, 20, 5, DMA1_Channel6_IRQn}, + {DMA1_Channel7, &DMA1->IFCR, 24, 6, DMA1_Channel7_IRQn}, +#if STM32_HAS_DMA2 || defined(__DOXYGEN__) + {DMA2_Channel1, &DMA2->IFCR, 0, 7, DMA2_Channel1_IRQn}, + {DMA2_Channel2, &DMA2->IFCR, 4, 8, DMA2_Channel2_IRQn}, + {DMA2_Channel3, &DMA2->IFCR, 8, 9, DMA2_Channel3_IRQn}, +#if defined(STM32F10X_CL) || defined(__DOXYGEN__) + {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_IRQn}, + {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel5_IRQn}, +#else /* !STM32F10X_CL */ + {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_5_IRQn}, + {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel4_5_IRQn}, +#endif /* !STM32F10X_CL */ +#endif /* STM32_HAS_DMA2 */ +}; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/** + * @brief DMA ISR redirector type. + */ +typedef struct { + stm32_dmaisr_t dma_func; /**< @brief DMA callback function. */ + void *dma_param; /**< @brief DMA callback parameter. */ +} dma_isr_redir_t; + +/** + * @brief Mask of the allocated streams. + */ +static uint32_t dma_streams_mask; + +/** + * @brief DMA IRQ redirectors. + */ +static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS]; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/** + * @brief DMA1 stream 1 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 0) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[0].dma_func) + dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 2 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 4; + if (dma_isr_redir[1].dma_func) + dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 8; + if (dma_isr_redir[2].dma_func) + dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 4 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[3].dma_func) + dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[4].dma_func) + dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 6 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 20; + if (dma_isr_redir[5].dma_func) + dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 7 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 24; + if (dma_isr_redir[6].dma_func) + dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +#if STM32_HAS_DMA2 || defined(__DOXYGEN__) +/** + * @brief DMA2 stream 1 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 0) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[7].dma_func) + dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 2 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 4) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 4; + if (dma_isr_redir[8].dma_func) + dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 8) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 8; + if (dma_isr_redir[9].dma_func) + dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +#if defined(STM32F10X_CL) || defined(__DOXYGEN__) +/** + * @brief DMA2 stream 4 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch4_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[10].dma_func) + dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[11].dma_func) + dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} +#else /* !STM32F10X_CL */ +/** + * @brief DMA2 streams 4 and 5 shared interrupt handler. + * @note This IRQ is shared between DMA2 channels 4 and 5 so it is a + * bit less efficient because an extra check. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + /* Check on channel 4.*/ + flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA2->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[10].dma_func) + dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); + } + + /* Check on channel 5.*/ + flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA2->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[11].dma_func) + dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); + } + + CH_IRQ_EPILOGUE(); +} +#endif /* !STM32F10X_CL */ +#endif /* STM32_HAS_DMA2 */ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA helper initialization. + * + * @init + */ +void dmaInit(void) { + int i; + + dma_streams_mask = 0; + for (i = 0; i < STM32_DMA_STREAMS; i++) { + _stm32_dma_streams[i].channel->CCR = 0; + dma_isr_redir[i].dma_func = NULL; + } + DMA1->IFCR = 0xFFFFFFFF; +#if STM32_HAS_DMA2 + DMA2->IFCR = 0xFFFFFFFF; +#endif +} + +/** + * @brief Allocates a DMA stream. + * @details The stream is allocated and, if required, the DMA clock enabled. + * The function also enables the IRQ vector associated to the stream + * and initializes its priority. + * @pre The stream must not be already in use or an error is returned. + * @post The stream is allocated and the default ISR handler redirected + * to the specified function. + * @post The stream ISR vector is enabled and its priority configured. + * @post The stream must be freed using @p dmaStreamRelease() before it can + * be reused with another peripheral. + * @post The stream is in its post-reset state. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] priority IRQ priority mask for the DMA stream + * @param[in] func handling function pointer, can be @p NULL + * @param[in] param a parameter to be passed to the handling function + * @return The operation status. + * @retval FALSE no error, stream taken. + * @retval TRUE error, stream already taken. + * + * @special + */ +bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param) { + + chDbgCheck(dmastp != NULL, "dmaAllocate"); + + /* Checks if the stream is already taken.*/ + if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0) + return TRUE; + + /* Marks the stream as allocated.*/ + dma_isr_redir[dmastp->selfindex].dma_func = func; + dma_isr_redir[dmastp->selfindex].dma_param = param; + dma_streams_mask |= (1 << dmastp->selfindex); + + /* Enabling DMA clocks required by the current streams set.*/ + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) + rccEnableDMA1(FALSE); +#if STM32_HAS_DMA2 + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) + rccEnableDMA2(FALSE); +#endif + + /* Putting the stream in a safe state.*/ + dmaStreamDisable(dmastp); + dmaStreamClearInterrupt(dmastp); + dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; + + /* Enables the associated IRQ vector if a callback is defined.*/ + if (func != NULL) + NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority)); + + return FALSE; +} + +/** + * @brief Releases a DMA stream. + * @details The stream is freed and, if required, the DMA clock disabled. + * Trying to release a unallocated stream is an illegal operation + * and is trapped if assertions are enabled. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post The stream is again available. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { + + chDbgCheck(dmastp != NULL, "dmaRelease"); + + /* Check if the streams is not taken.*/ + chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0, + "dmaRelease(), #1", "not allocated"); + + /* Disables the associated IRQ vector.*/ + NVICDisableVector(dmastp->vector); + + /* Marks the stream as not allocated.*/ + dma_streams_mask &= ~(1 << dmastp->selfindex); + + /* Shutting down clocks that are no more required, if any.*/ + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) + rccDisableDMA1(FALSE); +#if STM32_HAS_DMA2 + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) + rccDisableDMA2(FALSE); +#endif +} + +#endif /* STM32_DMA_REQUIRED */ + +/** @} */ diff --git a/os/hal/platforms/STM32F1xx/stm32_dma.h b/os/hal/platforms/STM32F1xx/stm32_dma.h new file mode 100644 index 000000000..f209898d4 --- /dev/null +++ b/os/hal/platforms/STM32F1xx/stm32_dma.h @@ -0,0 +1,330 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 DMAv1/stm32_dma.h + * @brief DMA helper driver header. + * @note This file requires definitions from the ST header files + * stm32f10x.h or stm32l1xx.h. + * @note This driver uses the new naming convention used for the STM32F2xx + * so the "DMA channels" are referred as "DMA streams". + * + * @addtogroup STM32_DMA + * @{ + */ + +#ifndef _STM32_DMA_H_ +#define _STM32_DMA_H_ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Total number of DMA streams. + * @note This is the total number of streams among all the DMA units. + */ +#if STM32_HAS_DMA2 || defined(__DOXYGEN__) +#define STM32_DMA_STREAMS 12 +#else +#define STM32_DMA_STREAMS 7 +#endif + +/** + * @brief Mask of the ISR bits passed to the DMA callback functions. + */ +#define STM32_DMA_ISR_MASK 0x0F + +/** + * @name DMA streams identifiers + * @{ + */ +#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[0]) +#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[1]) +#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[2]) +#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[3]) +#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[4]) +#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[5]) +#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[6]) +#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[7]) +#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[8]) +#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[9]) +#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[10]) +#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[11]) +/** @} */ + +/** + * @name CR register constants common to all DMA types + */ +#define STM32_DMA_CR_EN DMA_CCR1_EN +#define STM32_DMA_CR_TEIE DMA_CCR1_TEIE +#define STM32_DMA_CR_HTIE DMA_CCR1_HTIE +#define STM32_DMA_CR_TCIE DMA_CCR1_TCIE +#define STM32_DMA_CR_DIR_MASK (DMA_CCR1_DIR | DMA_CCR1_MEM2MEM) +#define STM32_DMA_CR_DIR_P2M 0 +#define STM32_DMA_CR_DIR_M2P DMA_CCR1_DIR +#define STM32_DMA_CR_DIR_M2M DMA_CCR1_MEM2MEM +#define STM32_DMA_CR_CIRC DMA_CCR1_CIRC +#define STM32_DMA_CR_PINC DMA_CCR1_PINC +#define STM32_DMA_CR_MINC DMA_CCR1_MINC +#define STM32_DMA_CR_PSIZE_MASK DMA_CCR1_PSIZE +#define STM32_DMA_CR_PSIZE_BYTE 0 +#define STM32_DMA_CR_PSIZE_HWORD DMA_CCR1_PSIZE_0 +#define STM32_DMA_CR_PSIZE_WORD DMA_CCR1_PSIZE_1 +#define STM32_DMA_CR_MSIZE_MASK DMA_CCR1_MSIZE +#define STM32_DMA_CR_MSIZE_BYTE 0 +#define STM32_DMA_CR_MSIZE_HWORD DMA_CCR1_MSIZE_0 +#define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1 +#define STM32_DMA_CR_PL_MASK DMA_CCR1_PL +#define STM32_DMA_CR_PL(n) ((n) << 12) +/** @} */ + +/** + * @name CR register constants only found in enhanced DMA + */ +#define STM32_DMA_CR_CHSEL_MASK 0 /**< @brief Ignored by normal DMA. */ +#define STM32_DMA_CR_CHSEL(n) 0 /**< @brief Ignored by normal DMA. */ +/** @} */ + +/** + * @name Status flags passed to the ISR callbacks + */ +#define STM32_DMA_ISR_FEIF 0 +#define STM32_DMA_ISR_DMEIF 0 +#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1 +#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1 +#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1 +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA stream descriptor structure. + */ +typedef struct { + DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ + volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */ + uint8_t ishift; /**< @brief Bits offset in xIFCR + register. */ + uint8_t selfindex; /**< @brief Index to self in array. */ + uint8_t vector; /**< @brief Associated IRQ vector. */ +} stm32_dma_stream_t; + +/** + * @brief STM32 DMA ISR function type. + * + * @param[in] p parameter for the registered function + * @param[in] flags pre-shifted content of the ISR register, the bits + * are aligned to bit zero + */ +typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Associates a peripheral data register to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the CPAR register + * + * @special + */ +#define dmaStreamSetPeripheral(dmastp, addr) { \ + (dmastp)->channel->CPAR = (uint32_t)(addr); \ +} + +/** + * @brief Associates a memory destination to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the CMAR register + * + * @special + */ +#define dmaStreamSetMemory0(dmastp, addr) { \ + (dmastp)->channel->CMAR = (uint32_t)(addr); \ +} + +/** + * @brief Sets the number of transfers to be performed. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] size value to be written in the CNDTR register + * + * @special + */ +#define dmaStreamSetTransactionSize(dmastp, size) { \ + (dmastp)->channel->CNDTR = (uint32_t)(size); \ +} + +/** + * @brief Returns the number of transfers to be performed. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @return The number of transfers to be performed. + * + * @special + */ +#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->CNDTR)) + +/** + * @brief Programs the stream mode settings. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] mode value to be written in the CCR register + * + * @special + */ +#define dmaStreamSetMode(dmastp, mode) { \ + (dmastp)->channel->CCR = (uint32_t)(mode); \ +} + +/** + * @brief DMA stream enable. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamEnable(dmastp) { \ + (dmastp)->channel->CCR |= STM32_DMA_CR_EN; \ +} + +/** + * @brief DMA stream disable. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamDisable(dmastp) { \ + (dmastp)->channel->CCR &= ~STM32_DMA_CR_EN; \ +} + +/** + * @brief DMA stream interrupt sources clear. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamClearInterrupt(dmastp) { \ + *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \ +} + +/** + * @brief Starts a memory to memory operation using the specified stream. + * @note The default transfer data mode is "byte to byte" but it can be + * changed by specifying extra options in the @p mode parameter. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] mode value to be written in the CCR register, this value + * is implicitly ORed with: + * - @p STM32_DMA_CR_MINC + * - @p STM32_DMA_CR_PINC + * - @p STM32_DMA_CR_DIR_M2M + * - @p STM32_DMA_CR_EN + * . + * @param[in] src source address + * @param[in] dst destination address + * @param[in] n number of data units to copy + */ +#define dmaStartMemCopy(dmastp, mode, src, dst, n) { \ + dmaStreamSetPeripheral(dmastp, src); \ + dmaStreamSetMemory0(dmastp, dst); \ + dmaStreamGetTransactionSize(dmastp, n); \ + dmaStreamSetMode(dmastp, (mode) | \ + STM32_DMA_CR_MINC | STM32_DMA_CR_PINC | \ + STM32_DMA_CR_DIR_M2M | STM32_DMA_CR_EN); \ +} + +/** + * @brief Polled wait for DMA transfer end. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + */ +#define dmaWaitCompletion(dmastp) \ + while (((dmastp)->channel->CNDTR > 0) && \ + ((dmastp)->channel->CCR & STM32_DMA_CR_EN)) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void dmaInit(void); + bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param); + void dmaStreamRelease(const stm32_dma_stream_t *dmastp); +#ifdef __cplusplus +} +#endif + +#endif /* _STM32_DMA_H_ */ + +/** @} */ -- cgit v1.2.3 From c5086c0b0c99d87f9f8b3142b8e084c84123a23e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 8 Oct 2011 10:34:44 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3430 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv2/stm32_dma.c | 541 ------------------------------- os/hal/platforms/STM32/DMAv2/stm32_dma.h | 327 ------------------- os/hal/platforms/STM32F2xx/platform.mk | 3 +- os/hal/platforms/STM32F2xx/stm32_dma.c | 541 +++++++++++++++++++++++++++++++ os/hal/platforms/STM32F2xx/stm32_dma.h | 327 +++++++++++++++++++ 5 files changed, 869 insertions(+), 870 deletions(-) delete mode 100644 os/hal/platforms/STM32/DMAv2/stm32_dma.c delete mode 100644 os/hal/platforms/STM32/DMAv2/stm32_dma.h create mode 100644 os/hal/platforms/STM32F2xx/stm32_dma.c create mode 100644 os/hal/platforms/STM32F2xx/stm32_dma.h (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.c b/os/hal/platforms/STM32/DMAv2/stm32_dma.c deleted file mode 100644 index 70f412083..000000000 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.c +++ /dev/null @@ -1,541 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT 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 DMAv2/stm32_dma.c - * @brief Enhanced DMA helper driver code. - * - * @addtogroup STM32_DMA - * @details DMA sharing helper driver. In the STM32 the DMA streams are a - * shared resource, this driver allows to allocate and free DMA - * streams at runtime in order to allow all the other device - * drivers to coordinate the access to the resource. - * @note The DMA ISR handlers are all declared into this module because - * sharing, the various device drivers can associate a callback to - * IRSs when allocating streams. - * @{ - */ - -#include "ch.h" -#include "hal.h" - -/* The following macro is only defined if some driver requiring DMA services - has been enabled.*/ -#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/** - * @brief Mask of the DMA1 streams in @p dma_streams_mask. - */ -#define STM32_DMA1_STREAMS_MASK 0x000000FF - -/** - * @brief Mask of the DMA2 streams in @p dma_streams_mask. - */ -#define STM32_DMA2_STREAMS_MASK 0x0000FF00 - -/** - * @brief Post-reset value of the stream CR register. - */ -#define STM32_DMA_CR_RESET_VALUE 0x00000000 - -/** - * @brief Post-reset value of the stream FCR register. - */ -#define STM32_DMA_FCR_RESET_VALUE 0x00000021 - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief DMA 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_DMA1_STREAM0, @p STM32_DMA1_STREAM1 etc. - */ -const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { - {0, DMA1, DMA1_Stream0, &DMA1->LIFCR, 0}, - {1, DMA1, DMA1_Stream1, &DMA1->LIFCR, 6}, - {2, DMA1, DMA1_Stream2, &DMA1->LIFCR, 16}, - {3, DMA1, DMA1_Stream3, &DMA1->LIFCR, 22}, - {4, DMA1, DMA1_Stream4, &DMA1->HIFCR, 0}, - {5, DMA1, DMA1_Stream5, &DMA1->HIFCR, 6}, - {6, DMA1, DMA1_Stream6, &DMA1->HIFCR, 16}, - {7, DMA1, DMA1_Stream7, &DMA1->HIFCR, 22}, - {8, DMA2, DMA2_Stream0, &DMA2->LIFCR, 0}, - {9, DMA2, DMA2_Stream1, &DMA2->LIFCR, 6}, - {10, DMA2, DMA2_Stream2, &DMA2->LIFCR, 16}, - {11, DMA2, DMA2_Stream3, &DMA2->LIFCR, 22}, - {12, DMA2, DMA2_Stream4, &DMA2->HIFCR, 0}, - {13, DMA2, DMA2_Stream5, &DMA2->HIFCR, 6}, - {14, DMA2, DMA2_Stream6, &DMA2->HIFCR, 16}, - {15, DMA2, DMA2_Stream7, &DMA2->HIFCR, 22}, -}; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/** - * @brief DMA ISR redirector type. - */ -typedef struct { - stm32_dmaisr_t dma_func; - void *dma_param; -} dma_isr_redir_t; - -/** - * @brief Mask of the allocated streams. - */ -static uint32_t dma_streams_mask; - -/** - * @brief DMA IRQ redirectors. - */ -static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS]; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/** - * @brief DMA1 stream 0 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Stream0_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->LISR >> 0) & STM32_DMA_ISR_MASK; - DMA1->LIFCR = STM32_DMA_ISR_MASK << 0; - if (dma_isr_redir[0].dma_func) - dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 1 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Stream1_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->LISR >> 6) & STM32_DMA_ISR_MASK; - DMA1->LIFCR = STM32_DMA_ISR_MASK << 6; - if (dma_isr_redir[1].dma_func) - dma_isr_redir[1].dma_func(dma_isr_redir[0].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 2 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Stream2_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->LISR >> 16) & STM32_DMA_ISR_MASK; - DMA1->LIFCR = STM32_DMA_ISR_MASK << 16; - if (dma_isr_redir[2].dma_func) - dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 3 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Stream3_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->LISR >> 22) & STM32_DMA_ISR_MASK; - DMA1->LIFCR = STM32_DMA_ISR_MASK << 22; - if (dma_isr_redir[3].dma_func) - dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 4 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Stream4_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->HISR >> 0) & STM32_DMA_ISR_MASK; - DMA1->HIFCR = STM32_DMA_ISR_MASK << 0; - if (dma_isr_redir[4].dma_func) - dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 5 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Stream5_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->HISR >> 6) & STM32_DMA_ISR_MASK; - DMA1->HIFCR = STM32_DMA_ISR_MASK << 6; - if (dma_isr_redir[5].dma_func) - dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 6 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Stream6_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->HISR >> 16) & STM32_DMA_ISR_MASK; - DMA1->HIFCR = STM32_DMA_ISR_MASK << 16; - if (dma_isr_redir[6].dma_func) - dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 7 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Stream7_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->HISR >> 22) & STM32_DMA_ISR_MASK; - DMA1->HIFCR = STM32_DMA_ISR_MASK << 22; - if (dma_isr_redir[7].dma_func) - dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA2 stream 0 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Stream0_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->LISR >> 0) & STM32_DMA_ISR_MASK; - DMA2->LIFCR = STM32_DMA_ISR_MASK << 0; - if (dma_isr_redir[8].dma_func) - dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA2 stream 1 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Stream1_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->LISR >> 6) & STM32_DMA_ISR_MASK; - DMA2->LIFCR = STM32_DMA_ISR_MASK << 6; - if (dma_isr_redir[9].dma_func) - dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA2 stream 2 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Stream2_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->LISR >> 16) & STM32_DMA_ISR_MASK; - DMA2->LIFCR = STM32_DMA_ISR_MASK << 16; - if (dma_isr_redir[10].dma_func) - dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA2 stream 3 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Stream3_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->LISR >> 22) & STM32_DMA_ISR_MASK; - DMA2->LIFCR = STM32_DMA_ISR_MASK << 22; - if (dma_isr_redir[11].dma_func) - dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA2 stream 4 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Stream4_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->HISR >> 0) & STM32_DMA_ISR_MASK; - DMA2->HIFCR = STM32_DMA_ISR_MASK << 0; - if (dma_isr_redir[12].dma_func) - dma_isr_redir[12].dma_func(dma_isr_redir[12].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA2 stream 5 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Stream5_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->HISR >> 6) & STM32_DMA_ISR_MASK; - DMA2->HIFCR = STM32_DMA_ISR_MASK << 6; - if (dma_isr_redir[13].dma_func) - dma_isr_redir[13].dma_func(dma_isr_redir[13].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA2 stream 6 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Stream6_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->HISR >> 16) & STM32_DMA_ISR_MASK; - DMA2->HIFCR = STM32_DMA_ISR_MASK << 16; - if (dma_isr_redir[14].dma_func) - dma_isr_redir[14].dma_func(dma_isr_redir[14].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA2 stream 7 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Stream7_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->HISR >> 22) & STM32_DMA_ISR_MASK; - DMA2->HIFCR = STM32_DMA_ISR_MASK << 22; - if (dma_isr_redir[15].dma_func) - dma_isr_redir[15].dma_func(dma_isr_redir[15].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief STM32 DMA helper initialization. - * - * @init - */ -void dmaInit(void) { - int i; - - dma_streams_mask = 0; - for (i = 0; i < STM32_DMA_STREAMS; i++) { - _stm32_dma_streams[i].stream->CR = 0; - dma_isr_redir[i].dma_func = NULL; - } - DMA1->LIFCR = 0xFFFFFFFF; - DMA1->HIFCR = 0xFFFFFFFF; - DMA2->LIFCR = 0xFFFFFFFF; - DMA2->HIFCR = 0xFFFFFFFF; -} - -/** - * @brief Allocates a DMA stream. - * @details The stream is allocated and, if required, the DMA clock enabled. - * The function also enables the IRQ vector associated to the stream - * and initializes its priority. - * @pre The stream must not be already in use or an error is returned. - * @post The stream is allocated and the default ISR handler redirected - * to the specified function. - * @post The stream ISR vector is enabled and its priority configured. - * @post The stream must be freed using @p dmaStreamRelease() before it can - * be reused with another peripheral. - * @post The stream is in its post-reset state. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] priority IRQ priority mask for the DMA stream - * @param[in] func handling function pointer, can be @p NULL - * @param[in] param a parameter to be passed to the handling function - * @return The operation status. - * @retval FALSE no error, stream taken. - * @retval TRUE error, stream already taken. - * - * @special - */ -bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, - uint32_t priority, - stm32_dmaisr_t func, - void *param) { - - chDbgCheck(dmastp != NULL, "dmaAllocate"); - - /* Checks if the stream is already taken.*/ - if ((dma_streams_mask & dmastp->mask) != 0) - return TRUE; - - /* Marks the stream as allocated.*/ - dma_isr_redir[dmastp->selfindex].dma_func = func; - dma_isr_redir[dmastp->selfindex].dma_param = param; - dma_streams_mask |= (1 << dmastp->selfindex); - - /* Enabling DMA clocks required by the current streams set.*/ - if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) { - RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; - RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA1LPEN; - } - if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) { - RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; - RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA2LPEN; - } - - /* Putting the stream in a safe state.*/ - dmaStreamDisable(dmastp); - dmaStreamClearInterrupt(dmastp); - dmastp->channel->CR = STM32_DMA_CR_RESET_VALUE; - dmastp->channel->FCR = STM32_DMA_FCR_RESET_VALUE; - - /* Enables the associated IRQ vector if a callback is defined.*/ - if (func != NULL) - NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority)); - - return FALSE; -} - -/** - * @brief Releases a DMA stream. - * @details The stream is freed and, if required, the DMA clock disabled. - * Trying to release a unallocated stream is an illegal operation - * and is trapped if assertions are enabled. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post The stream is again available. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * - * @special - */ -void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { - - chDbgCheck(dmastp != NULL, "dmaRelease"); - - /* Check if the streams is not taken.*/ - chDbgAssert((dma_streams_mask & dmastp->mask) != 0, - "dmaRelease(), #1", "not allocated"); - - /* Disables the associated IRQ vector.*/ - NVICDisableVector(dmastp->vector); - - /* Marks the stream as not allocated.*/ - dma_streams_mask &= ~(1 << dmastp->selfindex); - - /* Shutting down clocks that are no more required, if any.*/ - if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) { - RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA1EN; - RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA1LPEN; - } - if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) { - RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA2EN; - RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA2LPEN; - } -} - -#endif /* STM32_DMA_REQUIRED */ - -/** @} */ diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.h b/os/hal/platforms/STM32/DMAv2/stm32_dma.h deleted file mode 100644 index af18497fc..000000000 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.h +++ /dev/null @@ -1,327 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT 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 DMAv2/stm32_dma.h - * @brief Enhanced-DMA helper driver header. - * @note This file requires definitions from the ST STM32F2xx header file - * stm32f2xx.h. - * - * @addtogroup STM32_DMA - * @{ - */ - -#ifndef _STM32_DMA_H_ -#define _STM32_DMA_H_ - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @brief Total number of DMA streams. - * @note This is the total number of streams among all the DMA units. - */ -#define STM32_DMA_STREAMS 16 - -/** - * @brief Mask of the ISR bits passed to the DMA callback functions. - */ -#define STM32_DMA_ISR_MASK 0x3D - -/** - * @name DMA streams identifiers - * @{ - */ -#define STM32_DMA1_STREAM0 (&_stm32_dma_streams[0]) -#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[1]) -#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[2]) -#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[3]) -#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[4]) -#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[5]) -#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[6]) -#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[7]) -#define STM32_DMA2_STREAM0 (&_stm32_dma_streams[8]) -#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[9]) -#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[10]) -#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[11]) -#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[12]) -#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[13]) -#define STM32_DMA2_STREAM6 (&_stm32_dma_streams[14]) -#define STM32_DMA2_STREAM7 (&_stm32_dma_streams[15]) -/** @} */ - -/** - * @name CR register constants common to all DMA types - */ -#define STM32_DMA_CR_EN DMA_SxCR_EN -#define STM32_DMA_CR_TEIE DMA_SxCR_TEIE -#define STM32_DMA_CR_HTIE DMA_SxCR_HTIE -#define STM32_DMA_CR_TCIE DMA_SxCR_TCIE -#define STM32_DMA_CR_DIR_MASK DMA_SxCR_DIR -#define STM32_DMA_CR_DIR_P2M 0 -#define STM32_DMA_CR_DIR_M2P DMA_SxCR_DIR_0 -#define STM32_DMA_CR_DIR_M2M DMA_SxCR_DIR_1 -#define STM32_DMA_CR_CIRC DMA_SxCR_CIRC -#define STM32_DMA_CR_PINC DMA_SxCR_PINC -#define STM32_DMA_CR_MINC DMA_SxCR_MINC -#define STM32_DMA_CR_PSIZE_MASK DMA_SxCR_PSIZE -#define STM32_DMA_CR_PSIZE_BYTE 0 -#define STM32_DMA_CR_PSIZE_HWORD DMA_SxCR_PSIZE_0 -#define STM32_DMA_CR_PSIZE_WORD DMA_SxCR_PSIZE_1 -#define STM32_DMA_CR_MSIZE_MASK DMA_SxCR_MSIZE -#define STM32_DMA_CR_MSIZE_BYTE 0 -#define STM32_DMA_CR_MSIZE_HWORD DMA_SxCR_MSIZE_0 -#define STM32_DMA_CR_MSIZE_WORD DMA_SxCR_MSIZE_1 -#define STM32_DMA_CR_PL_MASK DMA_SxCR_PL -#define STM32_DMA_CR_PL(n) ((n) << 16) -/** @} */ - -/** - * @name CR register constants only found in STM32F2xx - */ -#define STM32_DMA_CR_DMEIE DMA_SxCR_DMEIE -#define STM32_DMA_CR_PFCTRL DMA_SxCR_PFCTRL -#define STM32_DMA_CR_PINCOS DMA_SxCR_PINCOS -#define STM32_DMA_CR_DBM DMA_SxCR_DBM -#define STM32_DMA_CR_CT DMA_SxCR_CT -#define STM32_DMA_CR_PBURST_MASK DMA_SxCR_PBURST -#define STM32_DMA_CR_PBURST_SINGLE 0 -#define STM32_DMA_CR_PBURST_INCR4 DMA_SxCR_PBURST_0 -#define STM32_DMA_CR_PBURST_INCR8 DMA_SxCR_PBURST_1 -#define STM32_DMA_CR_PBURST_INCR16 (DMA_SxCR_PBURST_0 | DMA_SxCR_PBURST_1) -#define STM32_DMA_CR_MBURST_MASK DMA_SxCR_MBURST -#define STM32_DMA_CR_MBURST_SINGLE 0 -#define STM32_DMA_CR_MBURST_INCR4 DMA_SxCR_MBURST_0 -#define STM32_DMA_CR_MBURST_INCR8 DMA_SxCR_MBURST_1 -#define STM32_DMA_CR_MBURST_INCR16 (DMA_SxCR_MBURST_0 | DMA_SxCR_MBURST_1) -#define STM32_DMA_CR_CHSEL_MASK DMA_SxCR_CHSEL -#define STM32_DMA_CR_CHSEL(n) ((n) << 25) -/** @} */ - -/** - * @name FCR register constants only found in STM32F2xx - */ -#define STM32_DMA_FCR_FEIE DMA_SxFCR_FEIE -#define STM32_DMA_FCR_FS_MASK DMA_SxFCR_FS -#define STM32_DMA_FCR_DMDIS DMA_SxFCR_DMDIS -#define STM32_DMA_FCR_FTH_MASK DMA_SxFCR_FTH -#define STM32_DMA_FCR_FTH_1Q 0 -#define STM32_DMA_FCR_FTH_HALF DMA_SxFCR_FTH_0 -#define STM32_DMA_FCR_FTH_3Q DMA_SxFCR_FTH_1 -#define STM32_DMA_FCR_FTH_FULL (DMA_SxFCR_FTH_0 | DMA_SxFCR_FTH_1) -/** @} */ - -/** - * @name Status flags passed to the ISR callbacks - */ -#define STM32_DMA_ISR_FEIF DMA_LISR_FEIF0 -#define STM32_DMA_ISR_DMEIF DMA_LISR_DMEIF0 -#define STM32_DMA_ISR_TEIF DMA_LISR_TEIF0 -#define STM32_DMA_ISR_HTIF DMA_LISR_HTIF0 -#define STM32_DMA_ISR_TCIF DMA_LISR_TCIF0 -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief STM32 DMA stream descriptor structure. - */ -typedef struct { - DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ - volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */ - uint8_t ishift; /**< @brief Bits offset in xIFCR - register. */ - uint8_t selfindex; /**< @brief Index to self in array. */ - uint8_t vector; /**< @brief Associated IRQ vector. */ -} stm32_dma_stream_t; - -/** - * @brief STM32 DMA ISR function type. - * - * @param[in] p parameter for the registered function - * @param[in] flags pre-shifted content of the xISR register, the bits - * are aligned to bit zero - */ -typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/** - * @brief Associates a peripheral data register to a DMA stream. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] addr value to be written in the PAR register - * - * @special - */ -#define dmaStreamSetPeripheral(dmastp, addr) { \ - (dmastp)->stream->PAR = (uint32_t)(addr); \ -} - -/** - * @brief Associates a memory destination to a DMA stream. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] addr value to be written in the M0AR register - * - * @special - */ -#define dmaStreamSetMemory0(dmastp, addr) { \ - (dmastp)->stream->M0AR = (uint32_t)(addr); \ -} - -/** - * @brief Associates an alternate memory destination to a DMA stream. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] addr value to be written in the M1AR register - * - * @special - */ -#define dmaStreamSetMemory1(dmastp, addr) { \ - (dmastp)->stream->M1AR = (uint32_t)(addr); \ -} - -/** - * @brief Sets the number of transfers to be performed. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] size value to be written in the CNDTR register - * - * @special - */ -#define dmaStreamSetTransactionSize(dmastp, size) { \ - (dmastp)->stream->NDTR = (uint32_t)(size); \ -} - -/** - * @brief Returns the number of transfers to be performed. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @return The number of transfers to be performed. - * - * @special - */ -#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->stream->NDTR)) - -/** - * @brief Programs the stream mode settings. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] mode value to be written in the CR register - * - * @special - */ -#define dmaStreamSetMode(dmastp, mode) { \ - (dmastp)->stream->CR = (uint32_t)(mode); \ -} - -/** - * @brief Programs the stream FIFO settings. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] mode value to be written in the FCR register - * - * @special - */ -#define dmaStreamSetFIFO(dmastp, mode) { \ - (dmastp)->stream->FCR = (uint32_t)(mode); \ -} - -/** - * @brief DMA stream enable. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmachp pointer to a stm32_dma_stream_t structure - * - * @special - */ -#define dmaStreamEnable(dmachp) { \ - (dmastp)->stream->CR |= STM32_DMA_CR_EN; \ -} - -/** - * @brief DMA stream disable. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * - * @special - */ -#define dmaStreamDisable(dmastp) { \ - (dmastp)->stream->CR &= ~STM32_DMA_CR_EN; \ -} - -/** - * @brief DMA stream interrupt sources clear. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * - * @special - */ -#define dmaStreamClearInterrupt(dmastp) { \ - *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \ -} - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if !defined(__DOXYGEN__) -extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void dmaInit(void); - bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, - uint32_t priority, - stm32_dmaisr_t func, - void *param); - void dmaStreamRelease(const stm32_dma_stream_t *dmastp); -#ifdef __cplusplus -} -#endif - -#endif /* _STM32_DMA_H_ */ - -/** @} */ diff --git a/os/hal/platforms/STM32F2xx/platform.mk b/os/hal/platforms/STM32F2xx/platform.mk index c1502009f..64365e897 100644 --- a/os/hal/platforms/STM32F2xx/platform.mk +++ b/os/hal/platforms/STM32F2xx/platform.mk @@ -9,5 +9,4 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F2xx/hal_lld.c \ # Required include directories PLATFORMINC = ${CHIBIOS}/os/hal/platforms/STM32F2xx \ ${CHIBIOS}/os/hal/platforms/STM32 \ - ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2 \ - ${CHIBIOS}/os/hal/platforms/STM32/DMAv2 + ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2 diff --git a/os/hal/platforms/STM32F2xx/stm32_dma.c b/os/hal/platforms/STM32F2xx/stm32_dma.c new file mode 100644 index 000000000..70f412083 --- /dev/null +++ b/os/hal/platforms/STM32F2xx/stm32_dma.c @@ -0,0 +1,541 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 DMAv2/stm32_dma.c + * @brief Enhanced DMA helper driver code. + * + * @addtogroup STM32_DMA + * @details DMA sharing helper driver. In the STM32 the DMA streams are a + * shared resource, this driver allows to allocate and free DMA + * streams at runtime in order to allow all the other device + * drivers to coordinate the access to the resource. + * @note The DMA ISR handlers are all declared into this module because + * sharing, the various device drivers can associate a callback to + * IRSs when allocating streams. + * @{ + */ + +#include "ch.h" +#include "hal.h" + +/* The following macro is only defined if some driver requiring DMA services + has been enabled.*/ +#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/** + * @brief Mask of the DMA1 streams in @p dma_streams_mask. + */ +#define STM32_DMA1_STREAMS_MASK 0x000000FF + +/** + * @brief Mask of the DMA2 streams in @p dma_streams_mask. + */ +#define STM32_DMA2_STREAMS_MASK 0x0000FF00 + +/** + * @brief Post-reset value of the stream CR register. + */ +#define STM32_DMA_CR_RESET_VALUE 0x00000000 + +/** + * @brief Post-reset value of the stream FCR register. + */ +#define STM32_DMA_FCR_RESET_VALUE 0x00000021 + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief DMA 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_DMA1_STREAM0, @p STM32_DMA1_STREAM1 etc. + */ +const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { + {0, DMA1, DMA1_Stream0, &DMA1->LIFCR, 0}, + {1, DMA1, DMA1_Stream1, &DMA1->LIFCR, 6}, + {2, DMA1, DMA1_Stream2, &DMA1->LIFCR, 16}, + {3, DMA1, DMA1_Stream3, &DMA1->LIFCR, 22}, + {4, DMA1, DMA1_Stream4, &DMA1->HIFCR, 0}, + {5, DMA1, DMA1_Stream5, &DMA1->HIFCR, 6}, + {6, DMA1, DMA1_Stream6, &DMA1->HIFCR, 16}, + {7, DMA1, DMA1_Stream7, &DMA1->HIFCR, 22}, + {8, DMA2, DMA2_Stream0, &DMA2->LIFCR, 0}, + {9, DMA2, DMA2_Stream1, &DMA2->LIFCR, 6}, + {10, DMA2, DMA2_Stream2, &DMA2->LIFCR, 16}, + {11, DMA2, DMA2_Stream3, &DMA2->LIFCR, 22}, + {12, DMA2, DMA2_Stream4, &DMA2->HIFCR, 0}, + {13, DMA2, DMA2_Stream5, &DMA2->HIFCR, 6}, + {14, DMA2, DMA2_Stream6, &DMA2->HIFCR, 16}, + {15, DMA2, DMA2_Stream7, &DMA2->HIFCR, 22}, +}; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/** + * @brief DMA ISR redirector type. + */ +typedef struct { + stm32_dmaisr_t dma_func; + void *dma_param; +} dma_isr_redir_t; + +/** + * @brief Mask of the allocated streams. + */ +static uint32_t dma_streams_mask; + +/** + * @brief DMA IRQ redirectors. + */ +static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS]; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/** + * @brief DMA1 stream 0 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream0_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->LISR >> 0) & STM32_DMA_ISR_MASK; + DMA1->LIFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[0].dma_func) + dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 1 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream1_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->LISR >> 6) & STM32_DMA_ISR_MASK; + DMA1->LIFCR = STM32_DMA_ISR_MASK << 6; + if (dma_isr_redir[1].dma_func) + dma_isr_redir[1].dma_func(dma_isr_redir[0].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 2 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream2_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->LISR >> 16) & STM32_DMA_ISR_MASK; + DMA1->LIFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[2].dma_func) + dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->LISR >> 22) & STM32_DMA_ISR_MASK; + DMA1->LIFCR = STM32_DMA_ISR_MASK << 22; + if (dma_isr_redir[3].dma_func) + dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 4 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream4_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->HISR >> 0) & STM32_DMA_ISR_MASK; + DMA1->HIFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[4].dma_func) + dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->HISR >> 6) & STM32_DMA_ISR_MASK; + DMA1->HIFCR = STM32_DMA_ISR_MASK << 6; + if (dma_isr_redir[5].dma_func) + dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 6 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream6_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->HISR >> 16) & STM32_DMA_ISR_MASK; + DMA1->HIFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[6].dma_func) + dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 7 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream7_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->HISR >> 22) & STM32_DMA_ISR_MASK; + DMA1->HIFCR = STM32_DMA_ISR_MASK << 22; + if (dma_isr_redir[7].dma_func) + dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 0 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream0_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->LISR >> 0) & STM32_DMA_ISR_MASK; + DMA2->LIFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[8].dma_func) + dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 1 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream1_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->LISR >> 6) & STM32_DMA_ISR_MASK; + DMA2->LIFCR = STM32_DMA_ISR_MASK << 6; + if (dma_isr_redir[9].dma_func) + dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 2 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream2_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->LISR >> 16) & STM32_DMA_ISR_MASK; + DMA2->LIFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[10].dma_func) + dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->LISR >> 22) & STM32_DMA_ISR_MASK; + DMA2->LIFCR = STM32_DMA_ISR_MASK << 22; + if (dma_isr_redir[11].dma_func) + dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 4 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream4_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->HISR >> 0) & STM32_DMA_ISR_MASK; + DMA2->HIFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[12].dma_func) + dma_isr_redir[12].dma_func(dma_isr_redir[12].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->HISR >> 6) & STM32_DMA_ISR_MASK; + DMA2->HIFCR = STM32_DMA_ISR_MASK << 6; + if (dma_isr_redir[13].dma_func) + dma_isr_redir[13].dma_func(dma_isr_redir[13].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 6 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream6_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->HISR >> 16) & STM32_DMA_ISR_MASK; + DMA2->HIFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[14].dma_func) + dma_isr_redir[14].dma_func(dma_isr_redir[14].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 7 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream7_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->HISR >> 22) & STM32_DMA_ISR_MASK; + DMA2->HIFCR = STM32_DMA_ISR_MASK << 22; + if (dma_isr_redir[15].dma_func) + dma_isr_redir[15].dma_func(dma_isr_redir[15].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA helper initialization. + * + * @init + */ +void dmaInit(void) { + int i; + + dma_streams_mask = 0; + for (i = 0; i < STM32_DMA_STREAMS; i++) { + _stm32_dma_streams[i].stream->CR = 0; + dma_isr_redir[i].dma_func = NULL; + } + DMA1->LIFCR = 0xFFFFFFFF; + DMA1->HIFCR = 0xFFFFFFFF; + DMA2->LIFCR = 0xFFFFFFFF; + DMA2->HIFCR = 0xFFFFFFFF; +} + +/** + * @brief Allocates a DMA stream. + * @details The stream is allocated and, if required, the DMA clock enabled. + * The function also enables the IRQ vector associated to the stream + * and initializes its priority. + * @pre The stream must not be already in use or an error is returned. + * @post The stream is allocated and the default ISR handler redirected + * to the specified function. + * @post The stream ISR vector is enabled and its priority configured. + * @post The stream must be freed using @p dmaStreamRelease() before it can + * be reused with another peripheral. + * @post The stream is in its post-reset state. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] priority IRQ priority mask for the DMA stream + * @param[in] func handling function pointer, can be @p NULL + * @param[in] param a parameter to be passed to the handling function + * @return The operation status. + * @retval FALSE no error, stream taken. + * @retval TRUE error, stream already taken. + * + * @special + */ +bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param) { + + chDbgCheck(dmastp != NULL, "dmaAllocate"); + + /* Checks if the stream is already taken.*/ + if ((dma_streams_mask & dmastp->mask) != 0) + return TRUE; + + /* Marks the stream as allocated.*/ + dma_isr_redir[dmastp->selfindex].dma_func = func; + dma_isr_redir[dmastp->selfindex].dma_param = param; + dma_streams_mask |= (1 << dmastp->selfindex); + + /* Enabling DMA clocks required by the current streams set.*/ + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) { + RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; + RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA1LPEN; + } + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) { + RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; + RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA2LPEN; + } + + /* Putting the stream in a safe state.*/ + dmaStreamDisable(dmastp); + dmaStreamClearInterrupt(dmastp); + dmastp->channel->CR = STM32_DMA_CR_RESET_VALUE; + dmastp->channel->FCR = STM32_DMA_FCR_RESET_VALUE; + + /* Enables the associated IRQ vector if a callback is defined.*/ + if (func != NULL) + NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority)); + + return FALSE; +} + +/** + * @brief Releases a DMA stream. + * @details The stream is freed and, if required, the DMA clock disabled. + * Trying to release a unallocated stream is an illegal operation + * and is trapped if assertions are enabled. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post The stream is again available. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { + + chDbgCheck(dmastp != NULL, "dmaRelease"); + + /* Check if the streams is not taken.*/ + chDbgAssert((dma_streams_mask & dmastp->mask) != 0, + "dmaRelease(), #1", "not allocated"); + + /* Disables the associated IRQ vector.*/ + NVICDisableVector(dmastp->vector); + + /* Marks the stream as not allocated.*/ + dma_streams_mask &= ~(1 << dmastp->selfindex); + + /* Shutting down clocks that are no more required, if any.*/ + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) { + RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA1EN; + RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA1LPEN; + } + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) { + RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA2EN; + RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA2LPEN; + } +} + +#endif /* STM32_DMA_REQUIRED */ + +/** @} */ diff --git a/os/hal/platforms/STM32F2xx/stm32_dma.h b/os/hal/platforms/STM32F2xx/stm32_dma.h new file mode 100644 index 000000000..af18497fc --- /dev/null +++ b/os/hal/platforms/STM32F2xx/stm32_dma.h @@ -0,0 +1,327 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 DMAv2/stm32_dma.h + * @brief Enhanced-DMA helper driver header. + * @note This file requires definitions from the ST STM32F2xx header file + * stm32f2xx.h. + * + * @addtogroup STM32_DMA + * @{ + */ + +#ifndef _STM32_DMA_H_ +#define _STM32_DMA_H_ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Total number of DMA streams. + * @note This is the total number of streams among all the DMA units. + */ +#define STM32_DMA_STREAMS 16 + +/** + * @brief Mask of the ISR bits passed to the DMA callback functions. + */ +#define STM32_DMA_ISR_MASK 0x3D + +/** + * @name DMA streams identifiers + * @{ + */ +#define STM32_DMA1_STREAM0 (&_stm32_dma_streams[0]) +#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[1]) +#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[2]) +#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[3]) +#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[4]) +#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[5]) +#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[6]) +#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[7]) +#define STM32_DMA2_STREAM0 (&_stm32_dma_streams[8]) +#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[9]) +#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[10]) +#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[11]) +#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[12]) +#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[13]) +#define STM32_DMA2_STREAM6 (&_stm32_dma_streams[14]) +#define STM32_DMA2_STREAM7 (&_stm32_dma_streams[15]) +/** @} */ + +/** + * @name CR register constants common to all DMA types + */ +#define STM32_DMA_CR_EN DMA_SxCR_EN +#define STM32_DMA_CR_TEIE DMA_SxCR_TEIE +#define STM32_DMA_CR_HTIE DMA_SxCR_HTIE +#define STM32_DMA_CR_TCIE DMA_SxCR_TCIE +#define STM32_DMA_CR_DIR_MASK DMA_SxCR_DIR +#define STM32_DMA_CR_DIR_P2M 0 +#define STM32_DMA_CR_DIR_M2P DMA_SxCR_DIR_0 +#define STM32_DMA_CR_DIR_M2M DMA_SxCR_DIR_1 +#define STM32_DMA_CR_CIRC DMA_SxCR_CIRC +#define STM32_DMA_CR_PINC DMA_SxCR_PINC +#define STM32_DMA_CR_MINC DMA_SxCR_MINC +#define STM32_DMA_CR_PSIZE_MASK DMA_SxCR_PSIZE +#define STM32_DMA_CR_PSIZE_BYTE 0 +#define STM32_DMA_CR_PSIZE_HWORD DMA_SxCR_PSIZE_0 +#define STM32_DMA_CR_PSIZE_WORD DMA_SxCR_PSIZE_1 +#define STM32_DMA_CR_MSIZE_MASK DMA_SxCR_MSIZE +#define STM32_DMA_CR_MSIZE_BYTE 0 +#define STM32_DMA_CR_MSIZE_HWORD DMA_SxCR_MSIZE_0 +#define STM32_DMA_CR_MSIZE_WORD DMA_SxCR_MSIZE_1 +#define STM32_DMA_CR_PL_MASK DMA_SxCR_PL +#define STM32_DMA_CR_PL(n) ((n) << 16) +/** @} */ + +/** + * @name CR register constants only found in STM32F2xx + */ +#define STM32_DMA_CR_DMEIE DMA_SxCR_DMEIE +#define STM32_DMA_CR_PFCTRL DMA_SxCR_PFCTRL +#define STM32_DMA_CR_PINCOS DMA_SxCR_PINCOS +#define STM32_DMA_CR_DBM DMA_SxCR_DBM +#define STM32_DMA_CR_CT DMA_SxCR_CT +#define STM32_DMA_CR_PBURST_MASK DMA_SxCR_PBURST +#define STM32_DMA_CR_PBURST_SINGLE 0 +#define STM32_DMA_CR_PBURST_INCR4 DMA_SxCR_PBURST_0 +#define STM32_DMA_CR_PBURST_INCR8 DMA_SxCR_PBURST_1 +#define STM32_DMA_CR_PBURST_INCR16 (DMA_SxCR_PBURST_0 | DMA_SxCR_PBURST_1) +#define STM32_DMA_CR_MBURST_MASK DMA_SxCR_MBURST +#define STM32_DMA_CR_MBURST_SINGLE 0 +#define STM32_DMA_CR_MBURST_INCR4 DMA_SxCR_MBURST_0 +#define STM32_DMA_CR_MBURST_INCR8 DMA_SxCR_MBURST_1 +#define STM32_DMA_CR_MBURST_INCR16 (DMA_SxCR_MBURST_0 | DMA_SxCR_MBURST_1) +#define STM32_DMA_CR_CHSEL_MASK DMA_SxCR_CHSEL +#define STM32_DMA_CR_CHSEL(n) ((n) << 25) +/** @} */ + +/** + * @name FCR register constants only found in STM32F2xx + */ +#define STM32_DMA_FCR_FEIE DMA_SxFCR_FEIE +#define STM32_DMA_FCR_FS_MASK DMA_SxFCR_FS +#define STM32_DMA_FCR_DMDIS DMA_SxFCR_DMDIS +#define STM32_DMA_FCR_FTH_MASK DMA_SxFCR_FTH +#define STM32_DMA_FCR_FTH_1Q 0 +#define STM32_DMA_FCR_FTH_HALF DMA_SxFCR_FTH_0 +#define STM32_DMA_FCR_FTH_3Q DMA_SxFCR_FTH_1 +#define STM32_DMA_FCR_FTH_FULL (DMA_SxFCR_FTH_0 | DMA_SxFCR_FTH_1) +/** @} */ + +/** + * @name Status flags passed to the ISR callbacks + */ +#define STM32_DMA_ISR_FEIF DMA_LISR_FEIF0 +#define STM32_DMA_ISR_DMEIF DMA_LISR_DMEIF0 +#define STM32_DMA_ISR_TEIF DMA_LISR_TEIF0 +#define STM32_DMA_ISR_HTIF DMA_LISR_HTIF0 +#define STM32_DMA_ISR_TCIF DMA_LISR_TCIF0 +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA stream descriptor structure. + */ +typedef struct { + DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ + volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */ + uint8_t ishift; /**< @brief Bits offset in xIFCR + register. */ + uint8_t selfindex; /**< @brief Index to self in array. */ + uint8_t vector; /**< @brief Associated IRQ vector. */ +} stm32_dma_stream_t; + +/** + * @brief STM32 DMA ISR function type. + * + * @param[in] p parameter for the registered function + * @param[in] flags pre-shifted content of the xISR register, the bits + * are aligned to bit zero + */ +typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Associates a peripheral data register to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the PAR register + * + * @special + */ +#define dmaStreamSetPeripheral(dmastp, addr) { \ + (dmastp)->stream->PAR = (uint32_t)(addr); \ +} + +/** + * @brief Associates a memory destination to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the M0AR register + * + * @special + */ +#define dmaStreamSetMemory0(dmastp, addr) { \ + (dmastp)->stream->M0AR = (uint32_t)(addr); \ +} + +/** + * @brief Associates an alternate memory destination to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the M1AR register + * + * @special + */ +#define dmaStreamSetMemory1(dmastp, addr) { \ + (dmastp)->stream->M1AR = (uint32_t)(addr); \ +} + +/** + * @brief Sets the number of transfers to be performed. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] size value to be written in the CNDTR register + * + * @special + */ +#define dmaStreamSetTransactionSize(dmastp, size) { \ + (dmastp)->stream->NDTR = (uint32_t)(size); \ +} + +/** + * @brief Returns the number of transfers to be performed. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @return The number of transfers to be performed. + * + * @special + */ +#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->stream->NDTR)) + +/** + * @brief Programs the stream mode settings. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] mode value to be written in the CR register + * + * @special + */ +#define dmaStreamSetMode(dmastp, mode) { \ + (dmastp)->stream->CR = (uint32_t)(mode); \ +} + +/** + * @brief Programs the stream FIFO settings. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] mode value to be written in the FCR register + * + * @special + */ +#define dmaStreamSetFIFO(dmastp, mode) { \ + (dmastp)->stream->FCR = (uint32_t)(mode); \ +} + +/** + * @brief DMA stream enable. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmachp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamEnable(dmachp) { \ + (dmastp)->stream->CR |= STM32_DMA_CR_EN; \ +} + +/** + * @brief DMA stream disable. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamDisable(dmastp) { \ + (dmastp)->stream->CR &= ~STM32_DMA_CR_EN; \ +} + +/** + * @brief DMA stream interrupt sources clear. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamClearInterrupt(dmastp) { \ + *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \ +} + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void dmaInit(void); + bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param); + void dmaStreamRelease(const stm32_dma_stream_t *dmastp); +#ifdef __cplusplus +} +#endif + +#endif /* _STM32_DMA_H_ */ + +/** @} */ -- cgit v1.2.3 From 8cc4b7f2e82a9a498ad97fb3ba45626a5b745bf9 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 8 Oct 2011 10:48:52 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3432 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/platform.mk | 1 - os/hal/platforms/STM32F1xx/stm32_dma.c | 4 +- os/hal/platforms/STM32F1xx/stm32_dma.h | 7 +- os/hal/platforms/STM32L1xx/platform.mk | 4 +- os/hal/platforms/STM32L1xx/stm32_dma.c | 349 +++++++++++++++++++++++++++++++++ os/hal/platforms/STM32L1xx/stm32_dma.h | 320 ++++++++++++++++++++++++++++++ 6 files changed, 676 insertions(+), 9 deletions(-) create mode 100644 os/hal/platforms/STM32L1xx/stm32_dma.c create mode 100644 os/hal/platforms/STM32L1xx/stm32_dma.h (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/platform.mk b/os/hal/platforms/STM32F1xx/platform.mk index 5e42d1335..33579609c 100644 --- a/os/hal/platforms/STM32F1xx/platform.mk +++ b/os/hal/platforms/STM32F1xx/platform.mk @@ -21,6 +21,5 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F1xx/stm32_dma.c \ PLATFORMINC = ${CHIBIOS}/os/hal/platforms/STM32F1xx \ ${CHIBIOS}/os/hal/platforms/STM32 \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv1 \ - ${CHIBIOS}/os/hal/platforms/STM32/DMAv1 \ ${CHIBIOS}/os/hal/platforms/STM32/USBv1 \ ${CHIBIOS}/os/hal/platforms/STM32/RTCv1 diff --git a/os/hal/platforms/STM32F1xx/stm32_dma.c b/os/hal/platforms/STM32F1xx/stm32_dma.c index 84e372c26..7fd1e39ee 100644 --- a/os/hal/platforms/STM32F1xx/stm32_dma.c +++ b/os/hal/platforms/STM32F1xx/stm32_dma.c @@ -19,10 +19,10 @@ */ /** - * @file DMAv1/stm32_dma.c + * @file STM32F1xx/stm32_dma.c * @brief DMA helper driver code. * - * @addtogroup STM32_DMA + * @addtogroup STM32F1xx_DMA * @details DMA sharing helper driver. In the STM32 the DMA streams are a * shared resource, this driver allows to allocate and free DMA * streams at runtime in order to allow all the other device diff --git a/os/hal/platforms/STM32F1xx/stm32_dma.h b/os/hal/platforms/STM32F1xx/stm32_dma.h index f209898d4..bacd0a809 100644 --- a/os/hal/platforms/STM32F1xx/stm32_dma.h +++ b/os/hal/platforms/STM32F1xx/stm32_dma.h @@ -19,14 +19,13 @@ */ /** - * @file DMAv1/stm32_dma.h + * @file STM32F1xx/stm32_dma.h * @brief DMA helper driver header. - * @note This file requires definitions from the ST header files - * stm32f10x.h or stm32l1xx.h. + * @note This file requires definitions from the ST header file stm32f10x.h. * @note This driver uses the new naming convention used for the STM32F2xx * so the "DMA channels" are referred as "DMA streams". * - * @addtogroup STM32_DMA + * @addtogroup STM32F1xx_DMA * @{ */ diff --git a/os/hal/platforms/STM32L1xx/platform.mk b/os/hal/platforms/STM32L1xx/platform.mk index 45e937ee5..301187e71 100644 --- a/os/hal/platforms/STM32L1xx/platform.mk +++ b/os/hal/platforms/STM32L1xx/platform.mk @@ -1,5 +1,6 @@ # List of all the STM32L1xx platform files. -PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32L1xx/hal_lld.c \ +PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32L1xx/stm32_dma.c \ + ${CHIBIOS}/os/hal/platforms/STM32L1xx/hal_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32L1xx/adc_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/ext_lld.c \ @@ -9,7 +10,6 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32L1xx/hal_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/serial_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/uart_lld.c \ - ${CHIBIOS}/os/hal/platforms/STM32/DMAv1/stm32_dma.c \ ${CHIBIOS}/os/hal/platforms/STM32/USBv1/usb_lld.c # Required include directories diff --git a/os/hal/platforms/STM32L1xx/stm32_dma.c b/os/hal/platforms/STM32L1xx/stm32_dma.c new file mode 100644 index 000000000..e49c419d9 --- /dev/null +++ b/os/hal/platforms/STM32L1xx/stm32_dma.c @@ -0,0 +1,349 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32L1xx/stm32_dma.c + * @brief DMA helper driver code. + * + * @addtogroup STM32L1xx_DMA + * @details DMA sharing helper driver. In the STM32 the DMA streams are a + * shared resource, this driver allows to allocate and free DMA + * streams at runtime in order to allow all the other device + * drivers to coordinate the access to the resource. + * @note The DMA ISR handlers are all declared into this module because + * sharing, the various device drivers can associate a callback to + * IRSs when allocating streams. + * @{ + */ + +#include "ch.h" +#include "hal.h" + +/* The following macro is only defined if some driver requiring DMA services + has been enabled.*/ +#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/** + * @brief Mask of the DMA1 streams in @p dma_streams_mask. + */ +#define STM32_DMA1_STREAMS_MASK 0x0000007F + +/** + * @brief Mask of the DMA2 streams in @p dma_streams_mask. + */ +#define STM32_DMA2_STREAMS_MASK 0x00000F80 + +/** + * @brief Post-reset value of the stream CCR register. + */ +#define STM32_DMA_CCR_RESET_VALUE 0x00000000 + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief DMA 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_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc. + */ +const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { + {DMA1_Channel1, &DMA1->IFCR, 0, 0, DMA1_Channel1_IRQn}, + {DMA1_Channel2, &DMA1->IFCR, 4, 1, DMA1_Channel2_IRQn}, + {DMA1_Channel3, &DMA1->IFCR, 8, 2, DMA1_Channel3_IRQn}, + {DMA1_Channel4, &DMA1->IFCR, 12, 3, DMA1_Channel4_IRQn}, + {DMA1_Channel5, &DMA1->IFCR, 16, 4, DMA1_Channel5_IRQn}, + {DMA1_Channel6, &DMA1->IFCR, 20, 5, DMA1_Channel6_IRQn}, + {DMA1_Channel7, &DMA1->IFCR, 24, 6, DMA1_Channel7_IRQn} +}; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/** + * @brief DMA ISR redirector type. + */ +typedef struct { + stm32_dmaisr_t dma_func; /**< @brief DMA callback function. */ + void *dma_param; /**< @brief DMA callback parameter. */ +} dma_isr_redir_t; + +/** + * @brief Mask of the allocated streams. + */ +static uint32_t dma_streams_mask; + +/** + * @brief DMA IRQ redirectors. + */ +static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS]; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/** + * @brief DMA1 stream 1 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 0) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[0].dma_func) + dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 2 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 4; + if (dma_isr_redir[1].dma_func) + dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 8; + if (dma_isr_redir[2].dma_func) + dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 4 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[3].dma_func) + dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[4].dma_func) + dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 6 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 20; + if (dma_isr_redir[5].dma_func) + dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 7 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 24; + if (dma_isr_redir[6].dma_func) + dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA helper initialization. + * + * @init + */ +void dmaInit(void) { + int i; + + dma_streams_mask = 0; + for (i = 0; i < STM32_DMA_STREAMS; i++) { + _stm32_dma_streams[i].channel->CCR = 0; + dma_isr_redir[i].dma_func = NULL; + } + DMA1->IFCR = 0xFFFFFFFF; +} + +/** + * @brief Allocates a DMA stream. + * @details The stream is allocated and, if required, the DMA clock enabled. + * The function also enables the IRQ vector associated to the stream + * and initializes its priority. + * @pre The stream must not be already in use or an error is returned. + * @post The stream is allocated and the default ISR handler redirected + * to the specified function. + * @post The stream ISR vector is enabled and its priority configured. + * @post The stream must be freed using @p dmaStreamRelease() before it can + * be reused with another peripheral. + * @post The stream is in its post-reset state. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] priority IRQ priority mask for the DMA stream + * @param[in] func handling function pointer, can be @p NULL + * @param[in] param a parameter to be passed to the handling function + * @return The operation status. + * @retval FALSE no error, stream taken. + * @retval TRUE error, stream already taken. + * + * @special + */ +bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param) { + + chDbgCheck(dmastp != NULL, "dmaAllocate"); + + /* Checks if the stream is already taken.*/ + if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0) + return TRUE; + + /* Marks the stream as allocated.*/ + dma_isr_redir[dmastp->selfindex].dma_func = func; + dma_isr_redir[dmastp->selfindex].dma_param = param; + dma_streams_mask |= (1 << dmastp->selfindex); + + /* Enabling DMA clocks required by the current streams set.*/ + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) + rccEnableDMA1(FALSE); + + /* Putting the stream in a safe state.*/ + dmaStreamDisable(dmastp); + dmaStreamClearInterrupt(dmastp); + dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; + + /* Enables the associated IRQ vector if a callback is defined.*/ + if (func != NULL) + NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority)); + + return FALSE; +} + +/** + * @brief Releases a DMA stream. + * @details The stream is freed and, if required, the DMA clock disabled. + * Trying to release a unallocated stream is an illegal operation + * and is trapped if assertions are enabled. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post The stream is again available. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { + + chDbgCheck(dmastp != NULL, "dmaRelease"); + + /* Check if the streams is not taken.*/ + chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0, + "dmaRelease(), #1", "not allocated"); + + /* Disables the associated IRQ vector.*/ + NVICDisableVector(dmastp->vector); + + /* Marks the stream as not allocated.*/ + dma_streams_mask &= ~(1 << dmastp->selfindex); + + /* Shutting down clocks that are no more required, if any.*/ + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) + rccDisableDMA1(FALSE); +} + +#endif /* STM32_DMA_REQUIRED */ + +/** @} */ diff --git a/os/hal/platforms/STM32L1xx/stm32_dma.h b/os/hal/platforms/STM32L1xx/stm32_dma.h new file mode 100644 index 000000000..cada5de38 --- /dev/null +++ b/os/hal/platforms/STM32L1xx/stm32_dma.h @@ -0,0 +1,320 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32L1xx/stm32_dma.h + * @brief DMA helper driver header. + * @note This file requires definitions from the ST header file stm32f10x.h. + * @note This driver uses the new naming convention used for the STM32F2xx + * so the "DMA channels" are referred as "DMA streams". + * + * @addtogroup STM32L1xx_DMA + * @{ + */ + +#ifndef _STM32_DMA_H_ +#define _STM32_DMA_H_ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Total number of DMA streams. + * @note This is the total number of streams among all the DMA units. + */ +#define STM32_DMA_STREAMS 7 + +/** + * @brief Mask of the ISR bits passed to the DMA callback functions. + */ +#define STM32_DMA_ISR_MASK 0x0F + +/** + * @name DMA streams identifiers + * @{ + */ +#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[0]) +#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[1]) +#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[2]) +#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[3]) +#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[4]) +#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[5]) +#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[6]) +/** @} */ + +/** + * @name CR register constants common to all DMA types + */ +#define STM32_DMA_CR_EN DMA_CCR1_EN +#define STM32_DMA_CR_TEIE DMA_CCR1_TEIE +#define STM32_DMA_CR_HTIE DMA_CCR1_HTIE +#define STM32_DMA_CR_TCIE DMA_CCR1_TCIE +#define STM32_DMA_CR_DIR_MASK (DMA_CCR1_DIR | DMA_CCR1_MEM2MEM) +#define STM32_DMA_CR_DIR_P2M 0 +#define STM32_DMA_CR_DIR_M2P DMA_CCR1_DIR +#define STM32_DMA_CR_DIR_M2M DMA_CCR1_MEM2MEM +#define STM32_DMA_CR_CIRC DMA_CCR1_CIRC +#define STM32_DMA_CR_PINC DMA_CCR1_PINC +#define STM32_DMA_CR_MINC DMA_CCR1_MINC +#define STM32_DMA_CR_PSIZE_MASK DMA_CCR1_PSIZE +#define STM32_DMA_CR_PSIZE_BYTE 0 +#define STM32_DMA_CR_PSIZE_HWORD DMA_CCR1_PSIZE_0 +#define STM32_DMA_CR_PSIZE_WORD DMA_CCR1_PSIZE_1 +#define STM32_DMA_CR_MSIZE_MASK DMA_CCR1_MSIZE +#define STM32_DMA_CR_MSIZE_BYTE 0 +#define STM32_DMA_CR_MSIZE_HWORD DMA_CCR1_MSIZE_0 +#define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1 +#define STM32_DMA_CR_PL_MASK DMA_CCR1_PL +#define STM32_DMA_CR_PL(n) ((n) << 12) +/** @} */ + +/** + * @name CR register constants only found in enhanced DMA + */ +#define STM32_DMA_CR_CHSEL_MASK 0 /**< @brief Ignored by normal DMA. */ +#define STM32_DMA_CR_CHSEL(n) 0 /**< @brief Ignored by normal DMA. */ +/** @} */ + +/** + * @name Status flags passed to the ISR callbacks + */ +#define STM32_DMA_ISR_FEIF 0 +#define STM32_DMA_ISR_DMEIF 0 +#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1 +#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1 +#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1 +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA stream descriptor structure. + */ +typedef struct { + DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ + volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */ + uint8_t ishift; /**< @brief Bits offset in xIFCR + register. */ + uint8_t selfindex; /**< @brief Index to self in array. */ + uint8_t vector; /**< @brief Associated IRQ vector. */ +} stm32_dma_stream_t; + +/** + * @brief STM32 DMA ISR function type. + * + * @param[in] p parameter for the registered function + * @param[in] flags pre-shifted content of the ISR register, the bits + * are aligned to bit zero + */ +typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Associates a peripheral data register to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the CPAR register + * + * @special + */ +#define dmaStreamSetPeripheral(dmastp, addr) { \ + (dmastp)->channel->CPAR = (uint32_t)(addr); \ +} + +/** + * @brief Associates a memory destination to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the CMAR register + * + * @special + */ +#define dmaStreamSetMemory0(dmastp, addr) { \ + (dmastp)->channel->CMAR = (uint32_t)(addr); \ +} + +/** + * @brief Sets the number of transfers to be performed. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] size value to be written in the CNDTR register + * + * @special + */ +#define dmaStreamSetTransactionSize(dmastp, size) { \ + (dmastp)->channel->CNDTR = (uint32_t)(size); \ +} + +/** + * @brief Returns the number of transfers to be performed. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @return The number of transfers to be performed. + * + * @special + */ +#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->CNDTR)) + +/** + * @brief Programs the stream mode settings. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] mode value to be written in the CCR register + * + * @special + */ +#define dmaStreamSetMode(dmastp, mode) { \ + (dmastp)->channel->CCR = (uint32_t)(mode); \ +} + +/** + * @brief DMA stream enable. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamEnable(dmastp) { \ + (dmastp)->channel->CCR |= STM32_DMA_CR_EN; \ +} + +/** + * @brief DMA stream disable. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamDisable(dmastp) { \ + (dmastp)->channel->CCR &= ~STM32_DMA_CR_EN; \ +} + +/** + * @brief DMA stream interrupt sources clear. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamClearInterrupt(dmastp) { \ + *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \ +} + +/** + * @brief Starts a memory to memory operation using the specified stream. + * @note The default transfer data mode is "byte to byte" but it can be + * changed by specifying extra options in the @p mode parameter. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] mode value to be written in the CCR register, this value + * is implicitly ORed with: + * - @p STM32_DMA_CR_MINC + * - @p STM32_DMA_CR_PINC + * - @p STM32_DMA_CR_DIR_M2M + * - @p STM32_DMA_CR_EN + * . + * @param[in] src source address + * @param[in] dst destination address + * @param[in] n number of data units to copy + */ +#define dmaStartMemCopy(dmastp, mode, src, dst, n) { \ + dmaStreamSetPeripheral(dmastp, src); \ + dmaStreamSetMemory0(dmastp, dst); \ + dmaStreamGetTransactionSize(dmastp, n); \ + dmaStreamSetMode(dmastp, (mode) | \ + STM32_DMA_CR_MINC | STM32_DMA_CR_PINC | \ + STM32_DMA_CR_DIR_M2M | STM32_DMA_CR_EN); \ +} + +/** + * @brief Polled wait for DMA transfer end. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + */ +#define dmaWaitCompletion(dmastp) \ + while (((dmastp)->channel->CNDTR > 0) && \ + ((dmastp)->channel->CCR & STM32_DMA_CR_EN)) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void dmaInit(void); + bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param); + void dmaStreamRelease(const stm32_dma_stream_t *dmastp); +#ifdef __cplusplus +} +#endif + +#endif /* _STM32_DMA_H_ */ + +/** @} */ -- cgit v1.2.3 From 05f792e54ea17171380538bf95e062ad6f37196c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 8 Oct 2011 10:49:17 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3433 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32L1xx/stm32_dma.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32L1xx/stm32_dma.h b/os/hal/platforms/STM32L1xx/stm32_dma.h index cada5de38..e23980f9f 100644 --- a/os/hal/platforms/STM32L1xx/stm32_dma.h +++ b/os/hal/platforms/STM32L1xx/stm32_dma.h @@ -21,7 +21,7 @@ /** * @file STM32L1xx/stm32_dma.h * @brief DMA helper driver header. - * @note This file requires definitions from the ST header file stm32f10x.h. + * @note This file requires definitions from the ST header file stm32l1xx.h. * @note This driver uses the new naming convention used for the STM32F2xx * so the "DMA channels" are referred as "DMA streams". * -- cgit v1.2.3 From eea23b22826e76dba443a12c651d5490a0314471 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 8 Oct 2011 16:56:03 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3439 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/templates/halconf.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'os/hal') diff --git a/os/hal/templates/halconf.h b/os/hal/templates/halconf.h index 2e28bea73..9a0d3c7d7 100644 --- a/os/hal/templates/halconf.h +++ b/os/hal/templates/halconf.h @@ -108,6 +108,13 @@ #define HAL_USE_PWM TRUE #endif +/** + * @brief Enables the RTC subsystem. + */ +#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) +#define HAL_USE_RTC FALSE +#endif + /** * @brief Enables the SDC subsystem. */ -- cgit v1.2.3 From 36d1e0978ac7cce6074470ac5a09d14b9986f922 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 10 Oct 2011 18:08:37 +0000 Subject: Finalized AVR PAL driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3441 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/AVR/pal_lld.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/AVR/pal_lld.c b/os/hal/platforms/AVR/pal_lld.c index 4bfd7bd04..2f3174934 100644 --- a/os/hal/platforms/AVR/pal_lld.c +++ b/os/hal/platforms/AVR/pal_lld.c @@ -103,8 +103,6 @@ void _pal_lld_init(const PALConfig *config) { * with pull-up by default. * * @notapi - * - * TODO: check PAL_MODE_UNCONNECTED mode recommended for AVR */ void _pal_lld_setgroupmode(ioportid_t port, ioportmask_t mask, @@ -113,8 +111,6 @@ void _pal_lld_setgroupmode(ioportid_t port, switch (mode) { case PAL_MODE_RESET: case PAL_MODE_INPUT: - port->dir &= ~mask; - break; case PAL_MODE_INPUT_ANALOG: port->dir &= ~mask; port->out &= ~mask; -- cgit v1.2.3 From ade734b003ec8f45e365816c60a1689dd3454146 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 15 Oct 2011 07:10:47 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3443 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/AVR/pal_lld.c | 10 +++++++++ os/hal/platforms/AVR/pal_lld.h | 34 ++++++++++++++++++++++++---- os/hal/platforms/AVR/platform.dox | 47 ++++++++++++++++++++++++++++++++++----- 3 files changed, 81 insertions(+), 10 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/AVR/pal_lld.c b/os/hal/platforms/AVR/pal_lld.c index 2f3174934..0676047ac 100644 --- a/os/hal/platforms/AVR/pal_lld.c +++ b/os/hal/platforms/AVR/pal_lld.c @@ -85,6 +85,16 @@ void _pal_lld_init(const PALConfig *config) { PORTE = config->porte.out; DDRE = config->porte.dir; #endif + +#if defined(PORTF) || defined(__DOXYGEN__) + PORTF = config->portf.out; + DDRF = config->portf.dir; +#endif + +#if defined(PORTG) || defined(__DOXYGEN__) + PORTG = config->portg.out; + DDRG = config->portg.dir; +#endif } /** diff --git a/os/hal/platforms/AVR/pal_lld.h b/os/hal/platforms/AVR/pal_lld.h index a2d1f8714..fe64029d0 100644 --- a/os/hal/platforms/AVR/pal_lld.h +++ b/os/hal/platforms/AVR/pal_lld.h @@ -43,24 +43,30 @@ /*===========================================================================*/ /** - * @brief Width, in bits, of an I/O port. + * @brief Width, in bits, of an I/O port. */ #define PAL_IOPORTS_WIDTH 8 /** - * @brief Whole port mask. - * @brief This macro specifies all the valid bits into a port. + * @brief Whole port mask. + * @details This macro specifies all the valid bits into a port. */ #define PAL_WHOLE_PORT ((ioportmask_t)0xFF) /** - * @brief AVR setup registers. + * @brief AVR setup registers. */ typedef struct { uint8_t out; uint8_t dir; } avr_gpio_setup_t; +/** + * @brief AVR registers block. + * @note On some devices registers do not follow this layout on some + * ports, the ports with abnormal layout cannot be used through + * the PAL driver. Example: PORT F on Mega128. + */ typedef struct { volatile uint8_t in; volatile uint8_t dir; @@ -90,6 +96,12 @@ typedef struct { #if defined(PORTE) || defined(__DOXYGEN__) avr_gpio_setup_t porte; #endif +#if defined(PORTF) || defined(__DOXYGEN__) + avr_gpio_setup_t portf; +#endif +#if defined(PORTG) || defined(__DOXYGEN__) + avr_gpio_setup_t portg; +#endif } PALConfig; /** @@ -149,6 +161,20 @@ typedef avr_gpio_registers_t *ioportid_t; #define IOPORT5 ((volatile avr_gpio_registers_t *)&PINE) #endif +#if defined(PORTF) || defined(__DOXYGEN__) +/** + * @brief GPIO port F identifier. + */ +#define IOPORT6 ((volatile avr_gpio_registers_t *)&PINF) +#endif + +#if defined(PORTG) || defined(__DOXYGEN__) +/** + * @brief GPIO port G identifier. + */ +#define IOPORT7 ((volatile avr_gpio_registers_t *)&PING) +#endif + /*===========================================================================*/ /* Implementation, some of the following macros could be implemented as */ /* functions, if so please put them in pal_lld.c. */ diff --git a/os/hal/platforms/AVR/platform.dox b/os/hal/platforms/AVR/platform.dox index 2ac2256b9..a004113b0 100644 --- a/os/hal/platforms/AVR/platform.dox +++ b/os/hal/platforms/AVR/platform.dox @@ -37,14 +37,49 @@ /** * @defgroup AVR_PAL AVR PAL Support - * @details The AVR PAL driver uses the GPIO peripherals. + * @details The AVR PAL driver uses the PORT peripherals. * * @section avr_pal_1 Supported HW resources - * - GPIOA. - * - GPIOB. - * - GPIOC. - * - GPIOD. - * - GPIOE. + * - PORTA. + * - PORTB. + * - PORTC. + * - PORTD. + * - PORTE. + * - PORTF. + * - PORTG. + * . + * @section avr_pal_2 AVR PAL driver implementation features + * The AVR PAL driver implementation fully supports the following hardware + * capabilities: + * - 8 bits wide ports. + * - Atomic set/reset functions. + * - Output latched regardless of the pad setting. + * - Direct read of input pads regardless of the pad setting. + * . + * @section avr_pal_3 Supported PAL setup modes + * The AVR PAL driver supports the following I/O modes: + * - @p PAL_MODE_RESET. + * - @p PAL_MODE_UNCONNECTED. + * - @p PAL_MODE_INPUT. + * - @p PAL_MODE_INPUT_PULLUP. + * - @p PAL_MODE_INPUT_ANALOG. + * - @p PAL_MODE_OUTPUT_PUSHPULL. + * . + * Any attempt to setup an invalid mode is ignored. + * + * @section avr_pal_4 Suboptimal behavior + * The AVR PORT is less than optimal in several areas, the limitations + * should be taken in account while using the PAL driver: + * - Pad/port toggling operations are not atomic. + * - Pad/group mode setup is not atomic. + * - Group set+reset function is not atomic. + * - Writing on pads/groups/ports programmed as input with pull-up + * resistor changes the resistor setting because the output latch is + * used for resistor selection. + * - The PORT registers layout on some devices is not regular (it does + * not have contiguous PIN, DDR, PORT registers in this order), such + * ports cannot be accessed using the PAL driver. For example, PORT F + * on ATmega128. Verify the user manual of your device. * . * @ingroup AVR_DRIVERS */ -- cgit v1.2.3 From 309b1e411426e8d36d9a552ef2870da3db912a80 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 23 Oct 2011 11:39:45 +0000 Subject: Improvements to the USB driver, first phase. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3449 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/usb.h | 86 +++++++++++++++++---- os/hal/platforms/STM32/USBv1/usb_lld.c | 133 ++++++++++++++------------------- os/hal/platforms/STM32/USBv1/usb_lld.h | 20 ++--- os/hal/src/serial_usb.c | 91 +++++++++++++--------- os/hal/src/usb.c | 107 ++++++-------------------- 5 files changed, 218 insertions(+), 219 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/usb.h b/os/hal/include/usb.h index 884b11e8d..18842abd3 100644 --- a/os/hal/include/usb.h +++ b/os/hal/include/usb.h @@ -172,11 +172,6 @@ USB_DESC_BYTE(bInterval) /** @} */ -/** - * @brief Returned by some functions to report a busy endpoint. - */ -#define USB_ENDPOINT_BUSY ((size_t)0xFFFFFFFF) - /** * @name Endpoint types and settings * @{ @@ -362,6 +357,75 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp, */ #define usbGetReceiveStatusI(usbp, ep) ((usbp)->receiving & (1 << (ep))) +/** + * @brief Reads from a dedicated packet buffer. + * @pre In order to use this function he endpoint must have been + * initialized in packet mode. + * @note This function can be invoked both in thread and IRQ context. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * @param[out] buf buffer where to copy the packet data + * @param[in] n maximum number of bytes to copy. This value must + * not exceed the maximum packet size for this endpoint. + * @return The received packet size regardless the specified + * @p n parameter. + * @retval 0 Zero size packet received. + * + * @special + */ +#define usbReadPacketBuffer(usbp, ep, buf, n) \ + usb_lld_read_packet_buffer(usbp, ep, buf, n) + +/** + * @brief Writes to a dedicated packet buffer. + * @pre In order to use this function he endpoint must have been + * initialized in packet mode. + * @note This function can be invoked both in thread and IRQ context. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] ep endpoint number + * @param[in] buf buffer where to fetch the packet data + * @param[in] n maximum number of bytes to copy. This value must + * not exceed the maximum packet size for this endpoint. + * + * @special + */ +#define usbWritePacketBuffer(usbp, ep, buf, n) \ + usb_lld_write_packet_buffer(usbp, ep, buf, n) + +/** + * @brief Prepares for a receive transaction on an OUT endpoint. + * @pre In order to use this function he endpoint must have been + * initialized in transaction mode. + * @post The endpoint is ready for @p usbStartReceiveI(). + * + * @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 maximum number of bytes to copy + * + * @special + */ +#define usbPrepareReceive(usbp, ep, buf, n) \ + usb_lld_prepare_receive(usbp, ep, buf, n) + +/** + * @brief Prepares for a transmit transaction on an IN endpoint. + * @pre In order to use this function he endpoint must have been + * initialized in transaction mode. + * @post The endpoint is ready for @p usbStartTransmitI(). + * + * @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 maximum number of bytes to copy + * + * @special + */ +#define usbPrepareTransmit(usbp, ep, buf, n) \ + usb_lld_prepare_transmit(usbp, ep, buf, n) + /** * @brief Returns the exact size of a receive transaction. * @details The received size can be different from the size specified in @@ -417,7 +481,7 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp, * 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. + * @note This function can be invoked both in thread and IRQ context. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number @@ -511,14 +575,8 @@ extern "C" { const USBEndpointConfig *epcp); void usbDisableEndpointsI(USBDriver *usbp); void usbReadSetupI(USBDriver *usbp, usbep_t ep, uint8_t *buf); - size_t usbReadPacketI(USBDriver *usbp, usbep_t ep, - uint8_t *buf, size_t n); - size_t usbWritePacketI(USBDriver *usbp, usbep_t ep, - const uint8_t *buf, size_t n); - bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep, - uint8_t *buf, size_t n); - bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep, - const uint8_t *buf, size_t n); + bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep); + bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep); bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep); bool_t usbStallTransmitI(USBDriver *usbp, usbep_t ep); void _usb_reset(USBDriver *usbp); diff --git a/os/hal/platforms/STM32/USBv1/usb_lld.c b/os/hal/platforms/STM32/USBv1/usb_lld.c index 01bc50090..253f45197 100644 --- a/os/hal/platforms/STM32/USBv1/usb_lld.c +++ b/os/hal/platforms/STM32/USBv1/usb_lld.c @@ -109,58 +109,6 @@ static uint32_t pm_alloc(USBDriver *usbp, size_t size) { return next; } -/** - * @brief Copies a packet from memory into a packet buffer. - * - * @param[in] ep endpoint number - * @param[in] buf buffer where to fetch the endpoint data - * @param[in] n maximum number of bytes to copy - */ -static void write_packet(usbep_t ep, const uint8_t *buf, size_t n){ - uint32_t *pmap; - stm32_usb_descriptor_t *udp; - size_t count; - - udp = USB_GET_DESCRIPTOR(ep); - pmap = USB_ADDR2PTR(udp->TXADDR); - udp->TXCOUNT = n; - count = (n + 1) / 2; - while (count) { - *pmap++ = *(uint16_t *)buf; - buf += 2; - count--; - } - EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID); -} - -/** - * @brief Copies a packet from a packet buffer into memory. - * - * @param[in] ep endpoint number - * @param[in] buf buffer where to copy the endpoint data - * @param[in] n maximum number of bytes to copy - * @return The packet size. - * @retval 0 Special case, zero sized packet. - */ -static size_t read_packet(usbep_t ep, uint8_t *buf, size_t n){ - uint32_t *pmap; - stm32_usb_descriptor_t *udp; - size_t count; - - udp = USB_GET_DESCRIPTOR(ep); - pmap = USB_ADDR2PTR(udp->RXADDR); - count = udp->RXCOUNT & RXCOUNT_COUNT_MASK; - if (n > count) - n = count; - count = (n + 1) / 2; - while (count) { - *(uint16_t *)buf = (uint16_t)*pmap++; - buf += 2; - count--; - } - return n; -} - /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ @@ -257,7 +205,8 @@ CH_IRQ_HANDLER(Vector90) { n = epcp->in_maxsize; else n = epcp->in_state->txsize; - write_packet(ep, epcp->in_state->txbuf, n); + usb_lld_write_packet_buffer(usbp, ep, epcp->in_state->txbuf, n); + usb_lld_start_in(usbp, ep); } else { /* Transfer completed, invokes the callback.*/ @@ -279,7 +228,10 @@ CH_IRQ_HANDLER(Vector90) { } else { /* Transaction mode.*/ - n = read_packet(ep, epcp->out_state->rxbuf, epcp->out_state->rxsize); + n = usb_lld_read_packet_buffer(usbp, ep, + epcp->out_state->rxbuf, + epcp->out_state->rxsize); + usb_lld_start_out(usbp, ep); epcp->out_state->rxbuf += n; epcp->out_state->rxcnt += n; epcp->out_state->rxsize -= n; @@ -569,14 +521,13 @@ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) { *(uint16_t *)buf = (uint16_t)*pmap++; buf += 2; } - EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID); } /** - * @brief Reads a packet from the dedicated packet buffer. + * @brief Reads from a dedicated packet buffer. * @pre In order to use this function he endpoint must have been * initialized in packet mode. - * @post The endpoint is ready to accept another packet. + * @note This function can be invoked both in thread and IRQ context. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number @@ -589,8 +540,8 @@ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) { * * @notapi */ -size_t usb_lld_read_packet(USBDriver *usbp, usbep_t ep, - uint8_t *buf, size_t n) { +size_t usb_lld_read_packet_buffer(USBDriver *usbp, usbep_t ep, + uint8_t *buf, size_t n) { uint32_t *pmap; stm32_usb_descriptor_t *udp; size_t count; @@ -607,15 +558,14 @@ size_t usb_lld_read_packet(USBDriver *usbp, usbep_t ep, buf += 2; n--; } - EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID); return count; } /** - * @brief Writes a packet to the dedicated packet buffer. + * @brief Writes to a dedicated packet buffer. * @pre In order to use this function he endpoint must have been * initialized in packet mode. - * @post The endpoint is ready to transmit the packet. + * @note This function can be invoked both in thread and IRQ context. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number @@ -625,8 +575,8 @@ size_t usb_lld_read_packet(USBDriver *usbp, usbep_t ep, * * @notapi */ -void usb_lld_write_packet(USBDriver *usbp, usbep_t ep, - const uint8_t *buf, size_t n) { +void usb_lld_write_packet_buffer(USBDriver *usbp, usbep_t ep, + const uint8_t *buf, size_t n) { uint32_t *pmap; stm32_usb_descriptor_t *udp; @@ -640,21 +590,20 @@ void usb_lld_write_packet(USBDriver *usbp, usbep_t ep, buf += 2; n--; } - EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID); } /** - * @brief Starts a receive operation on an OUT endpoint. + * @brief Prepares for a receive operation. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number - * @param[out] buf buffer where to copy the endpoint data - * @param[in] n maximum number of bytes to copy in the buffer + * @param[out] buf buffer where to copy the received data + * @param[in] n maximum number of bytes to copy * * @notapi */ -void usb_lld_start_out(USBDriver *usbp, usbep_t ep, - uint8_t *buf, size_t n) { +void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep, + uint8_t *buf, size_t n) { USBOutEndpointState *osp = usbp->epc[ep]->out_state; osp->rxbuf = buf; @@ -665,21 +614,20 @@ void usb_lld_start_out(USBDriver *usbp, usbep_t ep, else osp->rxpkts = (uint16_t)((n + 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. + * @brief Prepares for a transmit operation. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number - * @param[in] buf buffer where to fetch the endpoint data + * @param[in] buf buffer where to fetch the data to be transmitted * @param[in] n maximum number of bytes to copy * * @notapi */ -void usb_lld_start_in(USBDriver *usbp, usbep_t ep, - const uint8_t *buf, size_t n) { +void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep, + const uint8_t *buf, size_t n) { USBInEndpointState *isp = usbp->epc[ep]->in_state; isp->txbuf = buf; @@ -687,7 +635,39 @@ void usb_lld_start_in(USBDriver *usbp, usbep_t ep, isp->txcnt = 0; if (n > (size_t)usbp->epc[ep]->in_maxsize) n = (size_t)usbp->epc[ep]->in_maxsize; - write_packet(ep, buf, n); + usb_lld_write_packet_buffer(usbp, ep, buf, n); +} + +/** + * @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) { + + (void)usbp; + + 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 + * @param[in] buf buffer where to fetch the endpoint data + * @param[in] n maximum number of bytes to copy + * + * @notapi + */ +void usb_lld_start_in(USBDriver *usbp, usbep_t ep) { + + (void)usbp; + + EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID); } /** @@ -701,6 +681,7 @@ void usb_lld_start_in(USBDriver *usbp, usbep_t ep, void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) { (void)usbp; + EPR_SET_STAT_RX(ep, EPR_STAT_RX_STALL); } diff --git a/os/hal/platforms/STM32/USBv1/usb_lld.h b/os/hal/platforms/STM32/USBv1/usb_lld.h index 47160af56..0ee9fd6c2 100644 --- a/os/hal/platforms/STM32/USBv1/usb_lld.h +++ b/os/hal/platforms/STM32/USBv1/usb_lld.h @@ -375,16 +375,18 @@ extern "C" { usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep); usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep); void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf); - size_t usb_lld_read_packet(USBDriver *usbp, usbep_t ep, - uint8_t *buf, size_t n); - void usb_lld_write_packet(USBDriver *usbp, usbep_t ep, - const uint8_t *buf, size_t n); - void usb_lld_start_out(USBDriver *usbp, usbep_t ep, - uint8_t *buf, size_t n); - void usb_lld_start_in(USBDriver *usbp, usbep_t ep, - const uint8_t *buf, size_t n); - void usb_lld_stall_in(USBDriver *usbp, usbep_t ep); + size_t usb_lld_read_packet_buffer(USBDriver *usbp, usbep_t ep, + uint8_t *buf, size_t n); + void usb_lld_write_packet_buffer(USBDriver *usbp, usbep_t ep, + const uint8_t *buf, size_t n); + void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep, + uint8_t *buf, size_t n); + void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep, + const uint8_t *buf, size_t n); + 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 diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c index 16822502a..ea434b197 100644 --- a/os/hal/src/serial_usb.c +++ b/os/hal/src/serial_usb.c @@ -118,21 +118,26 @@ static const struct SerialUSBDriverVMT vmt = { */ static void inotify(GenericQueue *qp) { SerialUSBDriver *sdup = (SerialUSBDriver *)qp->q_wrptr; - size_t n; /* Writes to the input queue can only happen when the queue has been emptied, then a whole packet is loaded in the queue.*/ - if (chIQIsEmptyI(&sdup->iqueue)) { - - n = usbReadPacketI(sdup->config->usbp, USB_CDC_DATA_AVAILABLE_EP, - sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE); - if (n != USB_ENDPOINT_BUSY) { - chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE); - sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer; - sdup->iqueue.q_counter = n; - while (notempty(&sdup->iqueue.q_waiting)) - chSchReadyI(fifo_remove(&sdup->iqueue.q_waiting))->p_u.rdymsg = Q_OK; - } + if (!usbGetReceiveStatusI(sdup->config->usbp, USB_CDC_DATA_AVAILABLE_EP) && + chIQIsEmptyI(&sdup->iqueue)) { + chSysUnlock(); + + /* Unlocked to make the potentially long read operation preemptable.*/ + size_t n = usbReadPacketBuffer(sdup->config->usbp, + USB_CDC_DATA_AVAILABLE_EP, + sdup->iqueue.q_buffer, + SERIAL_USB_BUFFERS_SIZE); + + chSysLock(); + usbStartReceiveI(sdup->config->usbp, USB_CDC_DATA_AVAILABLE_EP); + chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE); + sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer; + sdup->iqueue.q_counter = n; + while (notempty(&sdup->iqueue.q_waiting)) + chSchReadyI(fifo_remove(&sdup->iqueue.q_waiting))->p_u.rdymsg = Q_OK; } } @@ -141,14 +146,20 @@ static void inotify(GenericQueue *qp) { */ static void onotify(GenericQueue *qp) { SerialUSBDriver *sdup = (SerialUSBDriver *)qp->q_rdptr; - size_t w, n; + size_t n; /* If there is any data in the output queue then it is sent within a single packet and the queue is emptied.*/ n = chOQGetFullI(&sdup->oqueue); - w = usbWritePacketI(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP, - sdup->oqueue.q_buffer, n); - if (w != USB_ENDPOINT_BUSY) { + if (!usbGetTransmitStatusI(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP)) { + chSysUnlock(); + + /* Unlocked to make the potentially long write operation preemptable.*/ + usbWritePacketBuffer(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP, + sdup->oqueue.q_buffer, n); + + chSysLock(); + usbStartTransmitI(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP); chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY); sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer; sdup->oqueue.q_counter = chQSizeI(&sdup->oqueue); @@ -285,21 +296,27 @@ bool_t sduRequestsHook(USBDriver *usbp) { */ void sduDataTransmitted(USBDriver *usbp, usbep_t ep) { SerialUSBDriver *sdup = usbp->param; - size_t n, w; + size_t n; chSysLockFromIsr(); /* If there is any data in the output queue then it is sent within a single packet and the queue is emptied.*/ n = chOQGetFullI(&sdup->oqueue); if (n > 0) { - w = usbWritePacketI(usbp, ep, sdup->oqueue.q_buffer, n); - if (w != USB_ENDPOINT_BUSY) { - chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY); - sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer; - sdup->oqueue.q_counter = chQSizeI(&sdup->oqueue); - while (notempty(&sdup->oqueue.q_waiting)) - chSchReadyI(fifo_remove(&sdup->oqueue.q_waiting))->p_u.rdymsg = Q_OK; - } + /* The endpoint cannot be busy, we are in the context of the callback, + so it is safe to transmit without a check.*/ + chSysUnlockFromIsr(); + + /* Unlocked to make the potentially long write operation preemptable.*/ + usbWritePacketBuffer(usbp, ep, sdup->oqueue.q_buffer, n); + + chSysLockFromIsr(); + usbStartTransmitI(usbp, ep); + chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY); + sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer; + sdup->oqueue.q_counter = chQSizeI(&sdup->oqueue); + while (notempty(&sdup->oqueue.q_waiting)) + chSchReadyI(fifo_remove(&sdup->oqueue.q_waiting))->p_u.rdymsg = Q_OK; } chSysUnlockFromIsr(); } @@ -319,17 +336,23 @@ void sduDataReceived(USBDriver *usbp, usbep_t ep) { /* Writes to the input queue can only happen when the queue has been emptied, then a whole packet is loaded in the queue.*/ if (chIQIsEmptyI(&sdup->iqueue)) { + /* The endpoint cannot be busy, we are in the context of the callback, + so a packet is in the buffer for sure.*/ size_t n; - n = usbReadPacketI(usbp, ep, sdup->iqueue.q_buffer, - SERIAL_USB_BUFFERS_SIZE); - if (n != USB_ENDPOINT_BUSY) { - chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE); - sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer; - sdup->iqueue.q_counter = n; - while (notempty(&sdup->iqueue.q_waiting)) - chSchReadyI(fifo_remove(&sdup->iqueue.q_waiting))->p_u.rdymsg = Q_OK; - } + chSysUnlockFromIsr(); + + /* Unlocked to make the potentially long write operation preemptable.*/ + n = usbReadPacketBuffer(usbp, ep, sdup->iqueue.q_buffer, + SERIAL_USB_BUFFERS_SIZE); + + chSysLockFromIsr(); + usbStartReceiveI(usbp, ep); + chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE); + sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer; + sdup->iqueue.q_counter = n; + while (notempty(&sdup->iqueue.q_waiting)) + chSchReadyI(fifo_remove(&sdup->iqueue.q_waiting))->p_u.rdymsg = Q_OK; } chSysUnlockFromIsr(); } diff --git a/os/hal/src/usb.c b/os/hal/src/usb.c index 44a772ab1..30919580c 100644 --- a/os/hal/src/usb.c +++ b/os/hal/src/usb.c @@ -309,7 +309,7 @@ void usbInitEndpointI(USBDriver *usbp, usbep_t ep, chDbgCheck((usbp != NULL) && (epcp != NULL), "usbInitEndpointI"); chDbgAssert(usbp->state == USB_ACTIVE, "usbEnableEndpointI(), #1", "invalid state"); - chDbgAssert(usbp->epc[ep] != NULL, + chDbgAssert(usbp->epc[ep] == NULL, "usbEnableEndpointI(), #2", "already initialized"); /* Logically enabling the endpoint in the USBDriver structure.*/ @@ -351,127 +351,55 @@ void usbDisableEndpointsI(USBDriver *usbp) { usb_lld_disable_endpoints(usbp); } -/** - * @brief Reads a packet from the dedicated packet buffer. - * @pre In order to use this function he endpoint must have been - * initialized in packet mode. - * @post The endpoint is ready to accept another packet. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @param[out] buf buffer where to copy the packet data - * @param[in] n maximum number of bytes to copy. This value must - * not exceed the maximum packet size for this endpoint. - * @return The received packet size regardless the specified - * @p n parameter. - * @retval USB_ENDPOINT_BUSY Endpoint busy receiving. - * @retval 0 Zero size packet received. - * - * @iclass - */ -size_t usbReadPacketI(USBDriver *usbp, usbep_t ep, - uint8_t *buf, size_t n) { - - chDbgCheckClassI(); - chDbgCheck((usbp != NULL) && (buf != NULL), "usbReadPacketI"); - - if (usbGetReceiveStatusI(usbp, ep)) - return USB_ENDPOINT_BUSY; - - usbp->receiving |= (1 << ep); - return usb_lld_read_packet(usbp, ep, buf, n);; -} - -/** - * @brief Writes a packet to the dedicated packet buffer. - * @pre In order to use this function he endpoint must have been - * initialized in packet mode. - * @post The endpoint is ready to transmit the packet. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @param[in] buf buffer where to fetch the packet data - * @param[in] n maximum number of bytes to copy. This value must - * not exceed the maximum packet size for this endpoint. - * @return The operation status. - * @retval USB_ENDPOINT_BUSY Endpoint busy transmitting. - * @retval 0 Operation complete. - * - * @iclass - */ -size_t usbWritePacketI(USBDriver *usbp, usbep_t ep, - const uint8_t *buf, size_t n) { - - chDbgCheckClassI(); - chDbgCheck((usbp != NULL) && (buf != NULL), "usbWritePacketI"); - - if (usbGetTransmitStatusI(usbp, ep)) - return USB_ENDPOINT_BUSY; - - usbp->transmitting |= (1 << ep); - usb_lld_write_packet(usbp, ep, buf, n); - return 0; -} - /** * @brief Starts a receive transaction on an OUT endpoint. - * @pre In order to use this function he endpoint must have been - * initialized in transaction mode. * @post The endpoint callback is invoked when the transfer has been * completed. * * @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 maximum number of bytes to copy * @return The operation status. * @retval FALSE Operation started successfully. * @retval TRUE Endpoint busy, operation not started. * * @iclass */ -bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep, - uint8_t *buf, size_t n) { +bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep) { chDbgCheckClassI(); - chDbgCheck((usbp != NULL) && (buf != NULL), "usbStartReceiveI"); + chDbgCheck(usbp != NULL, "usbStartReceiveI"); if (usbGetReceiveStatusI(usbp, ep)) return TRUE; usbp->receiving |= (1 << ep); - usb_lld_start_out(usbp, ep, buf, n); + usb_lld_start_out(usbp, ep); return FALSE; } /** * @brief Starts a transmit transaction on an IN endpoint. - * @pre In order to use this function he endpoint must have been - * initialized in transaction mode. * @post The endpoint callback is invoked when the transfer has been * completed. * * @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 maximum number of bytes to copy * @return The operation status. * @retval FALSE Operation started successfully. * @retval TRUE Endpoint busy, operation not started. * * @iclass */ -bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep, - const uint8_t *buf, size_t n) { +bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep) { chDbgCheckClassI(); - chDbgCheck((usbp != NULL) && (buf != NULL), "usbStartTransmitI"); + chDbgCheck(usbp != NULL, "usbStartTransmitI"); if (usbGetTransmitStatusI(usbp, ep)) return TRUE; usbp->transmitting |= (1 << ep); - usb_lld_start_in(usbp, ep, buf, n); + usb_lld_start_in(usbp, ep); return FALSE; } @@ -597,13 +525,15 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) { if (usbp->ep0n > 0) { /* Starts the transmit phase.*/ usbp->ep0state = USB_EP0_TX; - usb_lld_start_in(usbp, 0, usbp->ep0next, usbp->ep0n); + usb_lld_prepare_transmit(usbp, 0, usbp->ep0next, usbp->ep0n); + usb_lld_start_in(usbp, 0); } else { /* No transmission phase, directly receiving the zero sized status packet.*/ usbp->ep0state = USB_EP0_WAITING_STS; - usb_lld_start_out(usbp, 0, NULL, 0); + usb_lld_prepare_receive(usbp, 0, NULL, 0); + usb_lld_start_out(usbp, 0); } } else { @@ -611,13 +541,15 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) { if (usbp->ep0n > 0) { /* Starts the receive phase.*/ usbp->ep0state = USB_EP0_RX; - usb_lld_start_out(usbp, 0, usbp->ep0next, usbp->ep0n); + usb_lld_prepare_receive(usbp, 0, usbp->ep0next, usbp->ep0n); + usb_lld_start_out(usbp, 0); } else { /* No receive phase, directly sending the zero sized status packet.*/ usbp->ep0state = USB_EP0_SENDING_STS; - usb_lld_start_in(usbp, 0, NULL, 0); + usb_lld_prepare_transmit(usbp, 0, NULL, 0); + usb_lld_start_in(usbp, 0); } } } @@ -644,13 +576,15 @@ void _usb_ep0in(USBDriver *usbp, usbep_t ep) { transmitted.*/ if ((usbp->ep0n < max) && ((usbp->ep0n % usbp->epc[0]->in_maxsize) == 0)) { - usb_lld_start_in(usbp, 0, NULL, 0); + usb_lld_prepare_transmit(usbp, 0, NULL, 0); + usb_lld_start_in(usbp, 0); return; } /* Transmit phase over, receiving the zero sized status packet.*/ usbp->ep0state = USB_EP0_WAITING_STS; - usb_lld_start_out(usbp, 0, NULL, 0); + usb_lld_prepare_receive(usbp, 0, NULL, 0); + usb_lld_start_out(usbp, 0); return; case USB_EP0_SENDING_STS: /* Status packet sent, invoking the callback if defined.*/ @@ -687,7 +621,8 @@ void _usb_ep0out(USBDriver *usbp, usbep_t ep) { case USB_EP0_RX: /* Receive phase over, sending the zero sized status packet.*/ usbp->ep0state = USB_EP0_SENDING_STS; - usb_lld_start_in(usbp, 0, NULL, 0); + usb_lld_prepare_transmit(usbp, 0, NULL, 0); + usb_lld_start_in(usbp, 0); return; case USB_EP0_WAITING_STS: /* Status packet received, it must be zero sized, invoking the callback -- cgit v1.2.3 From 53df7ed814f665ebeef75b379941f9c0cebcba55 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 23 Oct 2011 11:51:18 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3450 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/dox/usb.dox | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'os/hal') diff --git a/os/hal/dox/usb.dox b/os/hal/dox/usb.dox index 62b3aaf12..5778cc1a7 100644 --- a/os/hal/dox/usb.dox +++ b/os/hal/dox/usb.dox @@ -132,9 +132,9 @@ receiving [label="EP_BUSY\nReceiving Packet"]; idle [label="EP_IDLE\nPacket in Buffer"]; - disabled -> receiving [label="\usbInitEndpointI()"]; + disabled -> receiving [label="\nusbInitEndpointI()"]; receiving -> idle [label="\npacket received\n>out_cb<"]; - idle -> receiving [label="\nusbReadPacketI()"]; + idle -> receiving [label="\nusbReadPacketBuffer()\nusbStartReceiveI()"]; receiving -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"]; idle -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"]; } @@ -152,8 +152,8 @@ transmitting [label="EP_BUSY\nSending Packet"]; idle [label="EP_IDLE\nBuffer Empty"]; - disabled -> idle [label="\usbInitEndpointI()"]; - idle -> transmitting [label="\nusbWritePacketI()"]; + disabled -> idle [label="\nusbInitEndpointI()"]; + idle -> transmitting [label="\nusbWritePacketBuffer()\nusbStartTransmitI()"]; transmitting -> idle [label="\npacket sent\n>in_cb<"]; transmitting -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"]; idle -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"]; @@ -176,8 +176,8 @@ receiving [label="EP_BUSY\nReceiving"]; idle [label="EP_IDLE\nReady"]; - disabled -> idle [label="\usbInitEndpointI()"]; - idle -> receiving [label="\usbStartReceiveI()"]; + disabled -> idle [label="\nusbInitEndpointI()"]; + idle -> receiving [label="\nusbPrepareReceive()\nusbStartReceiveI()"]; receiving -> receiving [label="\nmore packets"]; receiving -> idle [label="\nreception end\n>out_cb<"]; receiving -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"]; @@ -198,7 +198,7 @@ idle [label="EP_IDLE\nReady"]; disabled -> idle [label="\usbInitEndpointI()"]; - idle -> transmitting [label="\nusbStartTransmitI()"]; + idle -> transmitting [label="\nusbPrepareTransmit()\nusbStartTransmitI()"]; transmitting -> transmitting [label="\nmore packets"]; transmitting -> idle [label="\ntransmission end\n>in_cb<"]; transmitting -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"]; -- cgit v1.2.3 From 2f572f109a463e7faa46ed544c91198e72e63343 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 23 Oct 2011 12:21:44 +0000 Subject: USB enhancements, phase two. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3451 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/usb.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'os/hal') diff --git a/os/hal/include/usb.h b/os/hal/include/usb.h index 18842abd3..bc4418f6b 100644 --- a/os/hal/include/usb.h +++ b/os/hal/include/usb.h @@ -321,6 +321,16 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp, * @name Macro Functions * @{ */ +/** + * @brief Connects the USB device. + */ +#define usbConnectBus(usbp) usb_lld_connect_bus(usbp) + +/** + * @brief Disconnect the USB device. + */ +#define usbDisconnectBus(usbp) usb_lld_disconnect_bus(usbp) + /** * @brief Returns the current frame number. * -- cgit v1.2.3 From 267e558ee47441126a6e54312a3529a8c4564f76 Mon Sep 17 00:00:00 2001 From: barthess Date: Wed, 26 Oct 2011 17:49:51 +0000 Subject: I2C. Fixed warning. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3453 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/i2c_lld.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index 317fc57dd..a0914e819 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -277,8 +277,9 @@ void _i2c_ev7_master_rec_byte_qued(I2CDriver *i2cp){ rxBuffp++; (i2cp->rxbytes)--; } - else + else{ _i2c_unhandled_case(i2cp); + } break; default: -- cgit v1.2.3 From 71ff7f78d21d33ad39ecbbe356adca26d86de87b Mon Sep 17 00:00:00 2001 From: barthess Date: Thu, 27 Oct 2011 08:00:32 +0000 Subject: I2C. Dead code removing. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3454 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/i2c_lld.h | 1 - 1 file changed, 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/i2c_lld.h b/os/hal/platforms/STM32/i2c_lld.h index 548b5418e..b66ba5d6a 100644 --- a/os/hal/platforms/STM32/i2c_lld.h +++ b/os/hal/platforms/STM32/i2c_lld.h @@ -164,7 +164,6 @@ typedef struct { i2cdutycycle_t duty_cycle; /**< @brief Specifies the I2C fast mode duty cycle */ uint8_t own_addr_7; /**< @brief Specifies the first device 7-bit own address. */ uint16_t own_addr_10; /**< @brief Specifies the second part of device own address in 10-bit mode. Set to NULL if not used. */ - uint16_t ack; /**< @brief Enables or disables the acknowledgment. */ uint8_t nbit_own_addr; /**< @brief Specifies if 7-bit or 10-bit address is acknowledged */ } I2CConfig; -- cgit v1.2.3 From 113f63e33f8a1ebd0e5d8689ee4183f1d3b2ba47 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 30 Oct 2011 07:45:46 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3455 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/USBv1/stm32_usb.h | 16 ++++++++++++---- os/hal/platforms/STM32/USBv1/usb_lld.c | 14 +++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/USBv1/stm32_usb.h b/os/hal/platforms/STM32/USBv1/stm32_usb.h index 7ba03350a..d5701c192 100644 --- a/os/hal/platforms/STM32/USBv1/stm32_usb.h +++ b/os/hal/platforms/STM32/USBv1/stm32_usb.h @@ -80,17 +80,25 @@ typedef struct { */ volatile uint32_t TXADDR; /** - * @brief TX counter register. + * @brief TX counter register 0. */ - volatile uint32_t TXCOUNT; + volatile uint16_t TXCOUNT0; + /** + * @brief TX counter register 1. + */ + volatile uint16_t TXCOUNT1; /** * @brief RX buffer offset register. */ volatile uint32_t RXADDR; /** - * @brief RX counter register. + * @brief RX counter register 0. + */ + volatile uint16_t RXCOUNT0; + /** + * @brief RX counter register 1. */ - volatile uint32_t RXCOUNT; + volatile uint16_t RXCOUNT1; } stm32_usb_descriptor_t; /** diff --git a/os/hal/platforms/STM32/USBv1/usb_lld.c b/os/hal/platforms/STM32/USBv1/usb_lld.c index 253f45197..b81766f6d 100644 --- a/os/hal/platforms/STM32/USBv1/usb_lld.c +++ b/os/hal/platforms/STM32/USBv1/usb_lld.c @@ -195,7 +195,7 @@ CH_IRQ_HANDLER(Vector90) { } else { /* Transaction mode.*/ - n = USB_GET_DESCRIPTOR(ep)->TXCOUNT; + n = (size_t)USB_GET_DESCRIPTOR(ep)->TXCOUNT0; epcp->in_state->txbuf += n; epcp->in_state->txcnt += n; epcp->in_state->txsize -= n; @@ -419,10 +419,10 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) { else nblocks = ((((epcp->out_maxsize - 1) | 1) + 1) / 2) << 10; dp = USB_GET_DESCRIPTOR(ep); - dp->TXCOUNT = 0; - dp->RXCOUNT = nblocks; - dp->TXADDR = pm_alloc(usbp, epcp->in_maxsize); - dp->RXADDR = pm_alloc(usbp, epcp->out_maxsize); + dp->TXCOUNT0 = 0; + dp->RXCOUNT0 = nblocks; + dp->TXADDR = pm_alloc(usbp, epcp->in_maxsize); + dp->RXADDR = pm_alloc(usbp, epcp->out_maxsize); } /** @@ -549,7 +549,7 @@ size_t usb_lld_read_packet_buffer(USBDriver *usbp, usbep_t ep, (void)usbp; udp = USB_GET_DESCRIPTOR(ep); pmap = USB_ADDR2PTR(udp->RXADDR); - count = udp->RXCOUNT & RXCOUNT_COUNT_MASK; + count = (size_t)udp->RXCOUNT0 & RXCOUNT_COUNT_MASK; if (n > count) n = count; n = (n + 1) / 2; @@ -583,7 +583,7 @@ void usb_lld_write_packet_buffer(USBDriver *usbp, usbep_t ep, (void)usbp; udp = USB_GET_DESCRIPTOR(ep); pmap = USB_ADDR2PTR(udp->TXADDR); - udp->TXCOUNT = n; + udp->TXCOUNT0 = (uint16_t)n; n = (n + 1) / 2; while (n > 0) { *pmap++ = *(uint16_t *)buf; -- cgit v1.2.3 From 2e4d6bc9abce18f10967536c2c2b2512593b6421 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 30 Oct 2011 08:03:49 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3456 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/USBv1/stm32_usb.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/USBv1/stm32_usb.h b/os/hal/platforms/STM32/USBv1/stm32_usb.h index d5701c192..b06e8d887 100644 --- a/os/hal/platforms/STM32/USBv1/stm32_usb.h +++ b/os/hal/platforms/STM32/USBv1/stm32_usb.h @@ -140,6 +140,7 @@ typedef struct { #define EPR_STAT_TX_NAK 0x0020 #define EPR_STAT_TX_VALID 0x0030 #define EPR_DTOG_TX 0x0040 +#define EPR_SWBUF_RX 0x0040 #define EPR_CTR_TX 0x0080 #define EPR_EP_KIND 0x0100 #define EPR_EP_TYPE_MASK 0x0600 @@ -154,6 +155,7 @@ typedef struct { #define EPR_STAT_RX_NAK 0x2000 #define EPR_STAT_RX_VALID 0x3000 #define EPR_DTOG_RX 0x4000 +#define EPR_SWBUF_TX 0x4000 #define EPR_CTR_RX 0x8000 #define CNTR_FRES 0x0001 -- cgit v1.2.3 From 8912d9fea23f516281c150fb5f3a101f4338a37d Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 30 Oct 2011 10:09:16 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3457 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/AT91SAM7/ext_lld.c | 238 ++++++++++++++++++++++++++++++++ os/hal/platforms/AT91SAM7/ext_lld.h | 249 ++++++++++++++++++++++++++++++++++ os/hal/platforms/AT91SAM7/platform.mk | 1 + 3 files changed, 488 insertions(+) create mode 100644 os/hal/platforms/AT91SAM7/ext_lld.c create mode 100644 os/hal/platforms/AT91SAM7/ext_lld.h (limited to 'os/hal') diff --git a/os/hal/platforms/AT91SAM7/ext_lld.c b/os/hal/platforms/AT91SAM7/ext_lld.c new file mode 100644 index 000000000..2dbfc1562 --- /dev/null +++ b/os/hal/platforms/AT91SAM7/ext_lld.c @@ -0,0 +1,238 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio, + 2011 Florian Goebe, Chair for Computer Science 11, + RWTH Aachen University + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/ext_lld.c + * @brief STM32 EXT subsystem low level driver source. + * + * @addtogroup EXT + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_EXT || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief EXTDA driver identifier. + */ +EXTDriver EXTDA; + +#if (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \ + (SAM7_PLATFORM == SAM7X512) +/** + * @brief EXTDB driver identifier. + */ +EXTDriver EXTDB; +#endif + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Handles external interrupts. + * + * @param[in] extp pointer to the driver that received the interrupt + */ +static void ext_lld_serveInterrupt(EXTDriver *extp) { + uint32_t irqFlags; + uint32_t ch; + + chSysLockFromIsr(); + + /* Read flags of pending PIO interrupts.*/ + irqFlags = extp->pio->PIO_ISR; + + /* Call callback function for any pending interrupt.*/ + for(ch = 0; ch < 32; ch++) { + + /* Check if the channel is activated and if its IRQ flag is set.*/ + if((extp->config->channels[ch].mode & + EXT_CH_MODE_ENABLED & EXT_CH_MODE_EDGES_MASK) + && ((1 << ch) & irqFlags)) { + (extp->config->channels[ch].cb)(extp, ch); + } + } + + chSysUnlockFromIsr(); + + AT91C_BASE_AIC->AIC_EOICR = 0; +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/** + * @brief EXTI[0] interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(EXTIA_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + ext_lld_serveInterrupt(&EXTDA); + + CH_IRQ_EPILOGUE(); +} + +#if (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \ + (SAM7_PLATFORM == SAM7X512) +/** + * @brief EXTI[1] interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(EXTIB_IRQHandler) { + CH_IRQ_PROLOGUE(); + + ext_lld_serveInterrupt(&EXTDB); + + CH_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level EXT driver initialization. + * + * @notapi + */ +void ext_lld_init(void) { + + /* Driver initialization.*/ + extObjectInit(&EXTDA); + + /* Set PIO base addresses.*/ + EXTDA.pio = AT91C_BASE_PIOA; + + /* Set peripheral IDs.*/ + EXTDA.pid = AT91C_ID_PIOA; + +#if (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \ + (SAM7_PLATFORM == SAM7X512) + /* Aame for PIOB.*/ + extObjectInit(&EXTDB); + EXTDB.pio = AT91C_BASE_PIOB; + EXTDB.pid = AT91C_ID_PIOB; +#endif +} + +/** + * @brief Configures and activates the EXT peripheral. + * + * @param[in] extp pointer to the @p EXTDriver object + * + * @notapi + */ +void ext_lld_start(EXTDriver *extp) { + uint16_t ch; + uint32_t ier = 0; + const EXTConfig *config = extp->config; + + switch(extp->pid) { + case AT91C_ID_PIOA: + AIC_ConfigureIT(AT91C_ID_PIOA, SAM7_computeSMR(config->mode, + config->priority), + EXTIA_IRQHandler); + break; +#if (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \ + (SAM7_PLATFORM == SAM7X512) + case AT91C_ID_PIOB: + AIC_ConfigureIT(AT91C_ID_PIOB, SAM7_computeSMR(config->mode, + config->priority), + EXTIB_IRQHandler); + break; +#endif + } + + /* Enable and Disable channels with respect to config.*/ + for(ch = 0; ch < EXT_MAX_CHANNELS; ch++) { + ier |= (config->channels[ch].mode & EXT_CH_MODE_EDGES_MASK & EXT_CH_MODE_ENABLED ? 1 : 0) << ch; + } + extp->pio->PIO_IER = ier; + extp->pio->PIO_IDR = ~ier; + + /* Enable interrupt on corresponding PIO port in AIC.*/ + AIC_EnableIT(extp->pid); +} + +/** + * @brief Deactivates the EXT peripheral. + * + * @param[in] extp pointer to the @p EXTDriver object + * + * @notapi + */ +void ext_lld_stop(EXTDriver *extp) { + + /* Disable interrupt on corresponding PIO port in AIC.*/ + AIC_DisableIT(extp->pid); +} + +/** + * @brief Enables an EXT channel. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] channel channel to be enabled + * + * @notapi + */ +void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel) { + + extp->pio->PIO_IER = (1 << channel); +} + +/** + * @brief Disables an EXT channel. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] channel channel to be disabled + * + * @notapi + */ +void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel) { + + extp->pio->PIO_IDR = (1 << channel); +} + +#endif /* HAL_USE_EXT */ + +/** @} */ diff --git a/os/hal/platforms/AT91SAM7/ext_lld.h b/os/hal/platforms/AT91SAM7/ext_lld.h new file mode 100644 index 000000000..4c8442481 --- /dev/null +++ b/os/hal/platforms/AT91SAM7/ext_lld.h @@ -0,0 +1,249 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio, + 2011 Florian Goebe, Chair for Computer Science 11, + RWTH Aachen University + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 AT91SAM7/ext_lld.h + * @brief AT91SAM7 EXT subsystem low level driver header. + * + * @addtogroup EXT + * @{ + */ + +#ifndef _EXT_LLD_H_ +#define _EXT_LLD_H_ + +#if HAL_USE_EXT || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Pointer to the SAM7 AIC register block. + */ +#define SAM7_EXT_AIC ((AT91PS_AIC *)AT91C_BASE_AIC) + +/** + * @brief Number of channels within one ext driver. + */ +#define EXT_MAX_CHANNELS 32 + +/** + * @brief Mask of priority bits in interrupt mode register. + */ +#define SAM7_EXT_PRIORITY_MASK 0x00000007 + +/** + * @brief Shifter for priority bits in interrupt mode register. + */ +#define SAM7_EXT_PRIORITY_SHIFTER 0 + +/** + * @brief Shifter for mode bits in interrupt mode register. + */ +#define SAM7_EXT_MODE_SHIFTER 5 + +/* + * On the SAM7 architecture, a single channel can only be enables or disabled + * Hence, undefine the other channel mode constants + */ +#ifdef EXT_CH_MODE_RISING_EDGE +#undef EXT_CH_MODE_RISING_EDGE +#endif + +#ifdef EXT_CH_MODE_FALLING_EDGE +#undef EXT_CH_MODE_FALLING_EDGE +#endif + +#ifdef EXT_CH_MODE_BOTH_EDGES +#undef EXT_CH_MODE_BOTH_EDGES +#endif + +/** + * @name EXT channels mode + * @{ + */ +#define EXT_CH_MODE_ENABLED 1 /**< @brief Channel is enabled. */ +/** @} */ + +/** + * @name EXT drivers mode + * @{ + */ +/** + * @brief Mask for modes. + */ +#define SAM7_EXT_MODE_MASK AT91C_AIC_SRCTYPE +/** + * @brief Falling edge callback. + */ +#define SAM7_EXT_MODE_FALLING_EDGE AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE +/** + * @brief Rising edge callback. + */ +#define SAM7_EXT_MODE_RISING_EDGE AT91C_AIC_SRCTYPE_POSITIVE_EDGE +/** + * @brief High-level callback. + */ +#define SAM7_EXT_MODE_HIGH_LEVEL AT91C_AIC_SRCTYPE_HIGH_LEVEL +/** + * @brief Low-level callback. + */ +#define SAM7_EXT_MODE_LOW_LEVEL AT91C_AIC_SRCTYPE_EXT_LOW_LEVEL +/** @} */ + +/** + * @name EXT drivers priorities + * @{ + */ +#define SAM7_EXT_PRIOR_HIGHEST AT91C_AIC_PRIOR_HIGHEST +#define SAM7_EXT_PRIOR_LOWEST AT91C_AIC_PRIOR_LOWEST +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief EXT channel identifier. + */ +typedef uint32_t expchannel_t; + +/** + * @brief Type of an EXT generic notification callback. + * + * @param[in] extp pointer to the @p EXPDriver object triggering the + * callback + */ +typedef void (*extcallback_t)(EXTDriver *extp, expchannel_t channel); + +/** + * @brief Channel configuration structure. + */ +typedef struct { + /** + * @brief Channel mode. + */ + uint32_t mode; + /** + * @brief Channel callback. + * @details In the STM32 implementation a @p NULL callback pointer is + * valid and configures the channel as an event sources instead + * of an interrupt source. + */ + extcallback_t cb; +} EXTChannelConfig; + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + /** + * @brief Channel configurations. + */ + EXTChannelConfig channels[EXT_MAX_CHANNELS]; + /* End of the mandatory fields.*/ + + /** + * @brief interrupt mode. + */ + uint32_t mode; + + /** + * @brief interrupt priority. + */ + uint32_t priority; +} EXTConfig; + +/** + * @brief Structure representing an EXT driver. + */ +struct EXTDriver { + /** + * @brief Driver state. + */ + extstate_t state; + /** + * @brief Current configuration data. + */ + const EXTConfig *config; + /* End of the mandatory fields.*/ + /** + * @brief Pointer to the corresponding PIO registers block. + */ + AT91PS_PIO pio; + /** + * @brief peripheral ID of the corresponding PIO block. + */ + uint32_t pid; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Computes the content for the interrupt source mode register. + */ +#define SAM7_computeSMR(mode, prio) ( \ + ((mode & SAM7_EXT_MODE_MASK) << SAM7_EXT_MODE_SHIFTER) | \ + ((prio & SAM7_EXT_PRIORITY_MASK) << SAM7_EXT_PRIORITY_SHIFTER) \ +) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern EXTDriver EXTDA; +#if (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \ + (SAM7_PLATFORM == SAM7X512) +extern EXTDriver EXTDB; +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void ext_lld_init(void); + void ext_lld_start(EXTDriver *extp); + void ext_lld_stop(EXTDriver *extp); + void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel); + void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_EXT */ + +#endif /* _EXT_LLD_H_ */ + +/** @} */ diff --git a/os/hal/platforms/AT91SAM7/platform.mk b/os/hal/platforms/AT91SAM7/platform.mk index 9a5bba436..83b53491a 100644 --- a/os/hal/platforms/AT91SAM7/platform.mk +++ b/os/hal/platforms/AT91SAM7/platform.mk @@ -1,6 +1,7 @@ # List of all the AT91SAM7 platform files. PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/AT91SAM7/hal_lld.c \ ${CHIBIOS}/os/hal/platforms/AT91SAM7/pal_lld.c \ + ${CHIBIOS}/os/hal/platforms/AT91SAM7/ext_lld.c \ ${CHIBIOS}/os/hal/platforms/AT91SAM7/serial_lld.c \ ${CHIBIOS}/os/hal/platforms/AT91SAM7/spi_lld.c \ ${CHIBIOS}/os/hal/platforms/AT91SAM7/mac_lld.c \ -- cgit v1.2.3 From a54d331c93e98f75a2784adf48e61dcd81b792bb Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 30 Oct 2011 20:57:37 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3458 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/USBv1/usb_lld.c | 1 + 1 file changed, 1 insertion(+) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/USBv1/usb_lld.c b/os/hal/platforms/STM32/USBv1/usb_lld.c index b81766f6d..e148a6fea 100644 --- a/os/hal/platforms/STM32/USBv1/usb_lld.c +++ b/os/hal/platforms/STM32/USBv1/usb_lld.c @@ -696,6 +696,7 @@ void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) { void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) { (void)usbp; + EPR_SET_STAT_TX(ep, EPR_STAT_TX_STALL); } -- cgit v1.2.3 From 656ec7b1fbd543c5c32a9eee3292cdf2f70701f8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 1 Nov 2011 10:16:13 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3459 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/USBv1/stm32_usb.h | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/USBv1/stm32_usb.h b/os/hal/platforms/STM32/USBv1/stm32_usb.h index b06e8d887..435224033 100644 --- a/os/hal/platforms/STM32/USBv1/stm32_usb.h +++ b/os/hal/platforms/STM32/USBv1/stm32_usb.h @@ -78,7 +78,7 @@ typedef struct { /** * @brief TX buffer offset register. */ - volatile uint32_t TXADDR; + volatile uint32_t TXADDR0; /** * @brief TX counter register 0. */ @@ -90,7 +90,7 @@ typedef struct { /** * @brief RX buffer offset register. */ - volatile uint32_t RXADDR; + volatile uint32_t RXADDR0; /** * @brief RX counter register 0. */ @@ -101,6 +101,14 @@ typedef struct { volatile uint16_t RXCOUNT1; } stm32_usb_descriptor_t; +/** + * @name Register aliases + * @{ + */ +#define RXADDR1 TXADDR0 +#define TXADDR1 RXADDR0 +/** @} */ + /** * @brief USB registers block numeric address. */ @@ -140,9 +148,11 @@ typedef struct { #define EPR_STAT_TX_NAK 0x0020 #define EPR_STAT_TX_VALID 0x0030 #define EPR_DTOG_TX 0x0040 -#define EPR_SWBUF_RX 0x0040 +#define EPR_SWBUF_RX EPR_DTOG_TX #define EPR_CTR_TX 0x0080 #define EPR_EP_KIND 0x0100 +#define EPR_EP_DBL_BUF EPR_EP_KIND +#define EPR_EP_STATUS_OUT EPR_EP_KIND #define EPR_EP_TYPE_MASK 0x0600 #define EPR_EP_TYPE_BULK 0x0000 #define EPR_EP_TYPE_CONTROL 0x0200 @@ -155,7 +165,7 @@ typedef struct { #define EPR_STAT_RX_NAK 0x2000 #define EPR_STAT_RX_VALID 0x3000 #define EPR_DTOG_RX 0x4000 -#define EPR_SWBUF_TX 0x4000 +#define EPR_SWBUF_TX EPR_DTOG_RX #define EPR_CTR_RX 0x8000 #define CNTR_FRES 0x0001 -- cgit v1.2.3 From dc71ea034dc35f6a394a71831c95a73cd2ae06e7 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 2 Nov 2011 17:36:00 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3460 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/hal_lld.c | 164 + os/hal/platforms/STM32F4xx/hal_lld.h | 955 +++++ os/hal/platforms/STM32F4xx/platform.mk | 9 + os/hal/platforms/STM32F4xx/stm32_dma.c | 541 +++ os/hal/platforms/STM32F4xx/stm32_dma.h | 327 ++ os/hal/platforms/STM32F4xx/stm32f4xx.h | 7000 ++++++++++++++++++++++++++++++++ 6 files changed, 8996 insertions(+) create mode 100644 os/hal/platforms/STM32F4xx/hal_lld.c create mode 100644 os/hal/platforms/STM32F4xx/hal_lld.h create mode 100644 os/hal/platforms/STM32F4xx/platform.mk create mode 100644 os/hal/platforms/STM32F4xx/stm32_dma.c create mode 100644 os/hal/platforms/STM32F4xx/stm32_dma.h create mode 100644 os/hal/platforms/STM32F4xx/stm32f4xx.h (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/hal_lld.c b/os/hal/platforms/STM32F4xx/hal_lld.c new file mode 100644 index 000000000..74afa4bdb --- /dev/null +++ b/os/hal/platforms/STM32F4xx/hal_lld.c @@ -0,0 +1,164 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32F4xx/hal_lld.c + * @brief STM32F4xx HAL subsystem low level driver source. + * + * @addtogroup HAL + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#define AIRCR_VECTKEY 0x05FA0000 + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level HAL driver initialization. + * + * @notapi + */ +void hal_lld_init(void) { + + /* Reset of all peripherals.*/ +// RCC->APB1RSTR = 0xFFFFFFFF; +// RCC->APB2RSTR = 0xFFFFFFFF; +// RCC->APB1RSTR = 0; +// RCC->APB2RSTR = 0; + + /* SysTick initialization using the system clock.*/ + SysTick->LOAD = STM32_HCLK / CH_FREQUENCY - 1; + SysTick->VAL = 0; + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_ENABLE_Msk | + SysTick_CTRL_TICKINT_Msk; + + + +#if defined(STM32_DMA_REQUIRED) + dmaInit(); +#endif +} + +/** + * @brief STM32F2xx 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 + */ +#if defined(STM32F2XX) || defined(__DOXYGEN__) +/** + * @brief Clocks and internal voltage initialization. + */ +void stm32_clock_init(void) { + +#if !STM32_NO_INIT + /* PWR clock enable.*/ + RCC->APB1ENR = RCC_APB1ENR_PWREN; + + /* Initial clocks setup and wait for HSI stabilization, the MSI clock is + always enabled because it is the fallback clock when PLL the fails.*/ + RCC->CR |= RCC_CR_HSION; + while ((RCC->CR & RCC_CR_HSIRDY) == 0) + ; /* Waits until HSI is stable. */ + +#if STM32_HSE_ENABLED + /* HSE activation.*/ + RCC->CR |= RCC_CR_HSEON; + while ((RCC->CR & RCC_CR_HSERDY) == 0) + ; /* Waits until HSE is stable. */ +#endif + +#if STM32_LSI_ENABLED + /* LSI activation.*/ + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Waits until LSI is stable. */ +#endif + +#if STM32_LSE_ENABLED + /* LSE activation, have to unlock the register.*/ + if ((RCC->BDCR & RCC_BDCR_LSEON) == 0) { + PWR->CR |= PWR_CR_DBP; + RCC->BDCR |= RCC_BDCR_LSEON; + PWR->CR &= ~PWR_CR_DBP; + } + while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; /* Waits until LSE is stable. */ +#endif + +#if STM32_ACTIVATE_PLL + /* PLL activation.*/ + RCC->PLLCFGR = STM32_PLLQ | STM32_PLLSRC | STM32_PLLP | STM32_PLLN | STM32_PLLM; + RCC->CR |= RCC_CR_PLLON; + while (!(RCC->CR & RCC_CR_PLLRDY)) + ; /* Waits until PLL is stable. */ +#endif + +#if STM32_ACTIVATE_PLLI2S + /* PLLI2S activation.*/ + RCC->PLLI2SCFGR = STM32_PLI2SR_VALUE | STM32_PLLI2SN_VALUE; + RCC->CR |= RCC_CR_PLLI2SON; + while (!(RCC->CR & RCC_CR_PLLI2SRDY)) + ; /* Waits until PLLI2S is stable. */ +#endif + + /* Other clock-related settings (dividers, MCO etc).*/ + RCC->CFGR |= STM32_MCO2PRE | STM32_MCO2SEL | STM32_MCO1PRE | STM32_MCO1SEL | + STM32_RTCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; + + /* Flash setup. */ + FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN | STM32_FLASHBITS; + + /* Switching to the configured clock source if it is different from MSI. */ +#if (STM32_SW != STM32_SW_HSI) + RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; +#endif +#endif /* STM32_NO_INIT */ +} +#else +void stm32_clock_init(void) {} +#endif + +/** @} */ diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h new file mode 100644 index 000000000..1371f0e8e --- /dev/null +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -0,0 +1,955 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32F4xx/hal_lld.h + * @brief STM32F4xx HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - STM32_LSECLK. + * - STM32_HSECLK. + * . + * One of the following macros must also be defined: + * - STM32F4XX for High-performance STM32 F-4 devices. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef _HAL_LLD_H_ +#define _HAL_LLD_H_ + +#include "stm32f4xx.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Platform name. + */ +#define PLATFORM_NAME "STM32F2 High performance" + +#define STM32_HSICLK 16000000 /**< High speed internal clock. */ +#define STM32_LSICLK 38000 /**< Low speed internal clock. */ + +/* RCC_PLLCFGR register bits definitions.*/ +#define STM32_PLLP_MASK (3 << 16) /**< PLLP mask. */ +#define STM32_PLLP_DIV2 (0 << 16) /**< PLL clock divided by 2. */ +#define STM32_PLLP_DIV4 (1 << 16) /**< PLL clock divided by 4. */ +#define STM32_PLLP_DIV6 (2 << 16) /**< PLL clock divided by 6. */ +#define STM32_PLLP_DIV8 (3 << 16) /**< PLL clock divided by 8. */ + +#define STM32_PLLSRC_HSI (0 << 22) /**< PLL clock source is HSI. */ +#define STM32_PLLSRC_HSE (1 << 22) /**< PLL clock source is HSE. */ + +/* RCC_CFGR register bits definitions.*/ +#define STM32_SW_MASK (3 << 0) /**< SW mask. */ +#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ +#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ + +#define STM32_HPRE_MASK (15 << 4) /**< HPRE mask. */ +#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ +#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ +#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ +#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ +#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ +#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ +#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ +#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ +#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ + +#define STM32_PPRE1_MASK (7 << 10) /**< PPRE1 mask. */ +#define STM32_PPRE1_DIV1 (0 << 10) /**< HCLK divided by 1. */ +#define STM32_PPRE1_DIV2 (4 << 10) /**< HCLK divided by 2. */ +#define STM32_PPRE1_DIV4 (5 << 10) /**< HCLK divided by 4. */ +#define STM32_PPRE1_DIV8 (6 << 10) /**< HCLK divided by 8. */ +#define STM32_PPRE1_DIV16 (7 << 10) /**< HCLK divided by 16. */ + +#define STM32_PPRE2_MASK (7 << 13) /**< PPRE2 mask. */ +#define STM32_PPRE2_DIV1 (0 << 13) /**< HCLK divided by 1. */ +#define STM32_PPRE2_DIV2 (4 << 13) /**< HCLK divided by 2. */ +#define STM32_PPRE2_DIV4 (5 << 13) /**< HCLK divided by 4. */ +#define STM32_PPRE2_DIV8 (6 << 13) /**< HCLK divided by 8. */ +#define STM32_PPRE2_DIV16 (7 << 13) /**< HCLK divided by 16. */ + +#define STM32_RTCPRE_MASK (31 << 16) /**< RTCPRE mask. */ + +#define STM32_MCO1SEL_MASK (3 << 21) /**< MCO1 mask. */ +#define STM32_MCO1SEL_HSI (0 << 21) /**< HSI clock on MCO1 pin. */ +#define STM32_MCO1SEL_LSE (1 << 21) /**< LSE clock on MCO1 pin. */ +#define STM32_MCO1SEL_HSE (2 << 21) /**< HSE clock on MCO1 pin. */ +#define STM32_MCO1SEL_PLL (3 << 21) /**< PLL clock on MCO1 pin. */ + +#define STM32_MCO1PRE_MASK (7 << 24) /**< MCO1PRE mask. */ +#define STM32_MCO1PRE_DIV1 (0 << 24) /**< MCO1 divided by 1. */ +#define STM32_MCO1PRE_DIV2 (1 << 24) /**< MCO1 divided by 2. */ +#define STM32_MCO1PRE_DIV3 (2 << 24) /**< MCO1 divided by 3. */ +#define STM32_MCO1PRE_DIV4 (3 << 24) /**< MCO1 divided by 4. */ +#define STM32_MCO1PRE_DIV5 (4 << 24) /**< MCO1 divided by 5. */ + +#define STM32_MCO2PRE_MASK (7 << 27) /**< MCO2PRE mask. */ +#define STM32_MCO2PRE_DIV1 (0 << 27) /**< MCO2 divided by 1. */ +#define STM32_MCO2PRE_DIV2 (4 << 27) /**< MCO2 divided by 2. */ +#define STM32_MCO2PRE_DIV3 (5 << 27) /**< MCO2 divided by 3. */ +#define STM32_MCO2PRE_DIV4 (6 << 27) /**< MCO2 divided by 4. */ +#define STM32_MCO2PRE_DIV5 (7 << 27) /**< MCO2 divided by 5. */ + +#define STM32_MCO2SEL_MASK (3 << 30) /**< MCO2 mask. */ +#define STM32_MCO2SEL_SYSCLK (0 << 30) /**< SYSCLK clock on MCO2 pin. */ +#define STM32_MCO2SEL_PLLI2S (1 << 30) /**< PLLI2S clock on MCO2 pin. */ +#define STM32_MCO2SEL_HSE (2 << 30) /**< HSE clock on MCO2 pin. */ +#define STM32_MCO2SEL_PLL (3 << 30) /**< PLL clock on MCO2 pin. */ + +/* RCC_PLLI2SCFGR register bits definitions.*/ +#define STM32_PLLI2SN_MASK (511 << 6) /**< PLLI2SN mask. */ +#define STM32_PLLI2SR_MASK (7 << 28) /**< PLLI2SR mask. */ + +/* STM32F2xx capabilities.*/ +#define STM32_HAS_ADC1 TRUE +#define STM32_HAS_ADC2 TRUE +#define STM32_HAS_ADC3 TRUE + +#define STM32_HAS_CAN1 TRUE +#define STM32_HAS_CAN2 TRUE + +#define STM32_HAS_DAC TRUE + +#define STM32_HAS_DMA1 TRUE +#define STM32_HAS_DMA2 TRUE + +#define STM32_HAS_ETH TRUE + +#define STM32_EXTI_NUM_CHANNELS 23 + +#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 TRUE + +#define STM32_HAS_I2C1 TRUE +#define STM32_HAS_I2C2 TRUE + +#define STM32_HAS_RTC TRUE + +#define STM32_HAS_SDIO TRUE + +#define STM32_HAS_SPI1 TRUE +#define STM32_HAS_SPI2 TRUE +#define STM32_HAS_SPI3 TRUE + +#define STM32_HAS_TIM1 TRUE +#define STM32_HAS_TIM2 TRUE +#define STM32_HAS_TIM3 TRUE +#define STM32_HAS_TIM4 TRUE +#define STM32_HAS_TIM5 TRUE +#define STM32_HAS_TIM6 FALSE +#define STM32_HAS_TIM7 FALSE +#define STM32_HAS_TIM8 TRUE +#define STM32_HAS_TIM9 TRUE +#define STM32_HAS_TIM10 TRUE +#define STM32_HAS_TIM11 TRUE +#define STM32_HAS_TIM12 TRUE +#define STM32_HAS_TIM13 TRUE +#define STM32_HAS_TIM14 TRUE +#define STM32_HAS_TIM15 FALSE +#define STM32_HAS_TIM16 FALSE +#define STM32_HAS_TIM17 FALSE + +#define STM32_HAS_USART1 TRUE +#define STM32_HAS_USART2 TRUE +#define STM32_HAS_USART3 TRUE +#define STM32_HAS_UART4 TRUE +#define STM32_HAS_UART5 TRUE +#define STM32_HAS_USART6 TRUE + +#define STM32_HAS_USB FALSE +#define STM32_HAS_OTG1 TRUE + +/*===========================================================================*/ +/* Platform specific friendly IRQ names. */ +/*===========================================================================*/ + +#define WWDG_IRQHandler Vector40 /**< Window Watchdog. */ +#define PVD_IRQHandler Vector44 /**< PVD through EXTI Line + detect. */ +#define TAMPER_IRQHandler Vector48 /**< Tamper. */ +#define RTC_IRQHandler Vector4C /**< RTC. */ +#define FLASH_IRQHandler Vector50 /**< Flash. */ +#define RCC_IRQHandler Vector54 /**< RCC. */ +#define EXTI0_IRQHandler Vector58 /**< EXTI Line 0. */ +#define EXTI1_IRQHandler Vector5C /**< EXTI Line 1. */ +#define EXTI2_IRQHandler Vector60 /**< EXTI Line 2. */ +#define EXTI3_IRQHandler Vector64 /**< EXTI Line 3. */ +#define EXTI4_IRQHandler Vector68 /**< EXTI Line 4. */ +#define DMA1_Stream0_IRQHandler Vector6C /**< DMA1 Stream 0. */ +#define DMA1_Stream1_IRQHandler Vector70 /**< DMA1 Stream 1. */ +#define DMA1_Stream2_IRQHandler Vector74 /**< DMA1 Stream 2. */ +#define DMA1_Stream3_IRQHandler Vector78 /**< DMA1 Stream 3. */ +#define DMA1_Stream4_IRQHandler Vector7C /**< DMA1 Stream 4. */ +#define DMA1_Stream5_IRQHandler Vector80 /**< DMA1 Stream 5. */ +#define DMA1_Stream6_IRQHandler Vector84 /**< DMA1 Stream 6. */ +#define ADC1_2_3_IRQHandler Vector88 /**< ADC1, ADC2 and ADC3. */ +#define CAN1_TX_IRQHandler Vector8C /**< CAN1 TX. */ +#define CAN1_RX0_IRQHandler Vector90 /**< CAN1 RX0. */ +#define CAN1_RX1_IRQHandler Vector94 /**< CAN1 RX1. */ +#define CAN1_SCE_IRQHandler Vector98 /**< CAN1 SCE. */ +#define EXTI9_5_IRQHandler Vector9C /**< EXTI Line 9..5. */ +#define TIM1_BRK_IRQHandler VectorA0 /**< TIM1 Break. */ +#define TIM1_UP_IRQHandler VectorA4 /**< TIM1 Update. */ +#define TIM1_TRG_COM_IRQHandler VectorA8 /**< TIM1 Trigger and + Commutation. */ +#define TIM1_CC_IRQHandler VectorAC /**< TIM1 Capture Compare. */ +#define TIM2_IRQHandler VectorB0 /**< TIM2. */ +#define TIM3_IRQHandler VectorB4 /**< TIM3. */ +#define TIM4_IRQHandler VectorB8 /**< TIM4. */ +#define I2C1_EV_IRQHandler VectorBC /**< I2C1 Event. */ +#define I2C1_ER_IRQHandler VectorC0 /**< I2C1 Error. */ +#define I2C2_EV_IRQHandler VectorC4 /**< I2C2 Event. */ +#define I2C2_ER_IRQHandler VectorC8 /**< I2C1 Error. */ +#define SPI1_IRQHandler VectorCC /**< SPI1. */ +#define SPI2_IRQHandler VectorD0 /**< SPI2. */ +#define USART1_IRQHandler VectorD4 /**< USART1. */ +#define USART2_IRQHandler VectorD8 /**< USART2. */ +#define USART3_IRQHandler VectorDC /**< USART3. */ +#define EXTI15_10_IRQHandler VectorE0 /**< EXTI Line 15..10. */ +#define RTC_Alarm_IRQHandler VectorE4 /**< RTC alarm through EXTI + line. */ +#define OTG_FS_WKUP_IRQHandler VectorE8 /**< USB OTG FS Wakeup through + EXTI line. */ +#define TIM8_BRK_IRQHandler VectorEC /**< TIM8 Break. */ +#define TIM8_UP_IRQHandler VectorF0 /**< TIM8 Update. */ +#define TIM8_TRG_COM_IRQHandler VectorF4 /**< TIM8 Trigger and + Commutation. */ +#define TIM8_CC_IRQHandler VectorF8 /**< TIM8 Capture Compare. */ +#define DMA1_Stream7_IRQHandler VectorFC /**< DMA1 Stream 7. */ +#define FSMC_IRQHandler Vector100 /**< FSMC. */ +#define TIM5_IRQHandler Vector108 /**< TIM5. */ +#define SPI3_IRQHandler Vector10C /**< SPI3. */ +#define UART4_IRQHandler Vector110 /**< UART4. */ +#define UART5_IRQHandler Vector114 /**< UART5. */ +#define TIM6_IRQHandler Vector118 /**< TIM6. */ +#define TIM7_IRQHandler Vector11C /**< TIM7. */ +#define DMA2_Stream0_IRQHandler Vector120 /**< DMA2 Stream0. */ +#define DMA2_Stream1_IRQHandler Vector124 /**< DMA2 Stream1. */ +#define DMA2_Stream2_IRQHandler Vector128 /**< DMA2 Stream2. */ +#define DMA2_Stream3_IRQHandler Vector12C /**< DMA2 Stream3. */ +#define DMA2_Stream4_IRQHandler Vector130 /**< DMA2 Stream4. */ +#define ETH_IRQHandler Vector134 /**< Ethernet. */ +#define ETH_WKUP_IRQHandler Vector138 /**< Ethernet Wakeup through + EXTI line. */ +#define CAN2_TX_IRQHandler Vector13C /**< CAN2 TX. */ +#define CAN2_RX0_IRQHandler Vector140 /**< CAN2 RX0. */ +#define CAN2_RX1_IRQHandler Vector144 /**< CAN2 RX1. */ +#define CAN2_SCE_IRQHandler Vector148 /**< CAN2 SCE. */ +#define OTG_FS_IRQHandler Vector14C /**< USB OTG FS. */ +#define DMA2_Stream5_IRQHandler Vector150 /**< DMA2 Stream5. */ +#define DMA2_Stream6_IRQHandler Vector154 /**< DMA2 Stream6. */ +#define DMA2_Stream7_IRQHandler Vector158 /**< DMA2 Stream7. */ +#define USART6_IRQHandler Vector15C /**< USART6. */ +#define I2C3_EV_IRQHandler Vector160 /**< I2C3 Event. */ +#define I2C3_ER_IRQHandler Vector164 /**< I2C3 Error. */ +#define OTG_HS_EP1_OUT_IRQHandler Vector168 /**< USB OTG HS End Point 1 Out.*/ +#define OTG_HS_EP1_IN_IRQHandler Vector16C /**< USB OTG HS End Point 1 In. */ +#define OTG_HS_WKUP_IRQHandler Vector170 /**< USB OTG HS Wakeup through + EXTI line. */ +#define OTG_HS_IRQHandler Vector174 /**< USB OTG HS. */ +#define DCMI_IRQHandler Vector178 /**< DCMI. */ +#define CRYP_IRQHandler Vector17C /**< CRYP. */ +#define HASH_RNG_IRQHandler Vector180 /**< Hash and Rng. */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @brief Disables the PWR/RCC initialization in the HAL. + */ +#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) +#define STM32_NO_INIT FALSE +#endif + +/** + * @brief Enables or disables the HSI clock source. + */ +#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSI_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the HSE clock source. + */ +#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSE_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSE clock source. + */ +#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSE_ENABLED FALSE +#endif + +/** + * @brief ADC clock setting. + */ +#if !defined(STM32_ADC_CLOCK_ENABLED) || defined(__DOXYGEN__) +#define STM32_ADC_CLOCK_ENABLED TRUE +#endif + +/** + * @brief USB clock setting. + */ +#if !defined(STM32_USB_CLOCK_ENABLED) || defined(__DOXYGEN__) +#define STM32_USB_CLOCK_ENABLED TRUE +#endif + +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 32MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLL +#endif + +/** + * @brief Clock source for the PLL. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 120MHz system clock from + * the external 25MHz HSE clock. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_HSE +#endif + +/** + * @brief PLLM divider value. + * @note The allowed values are 2..63. + * @note The default value is calculated for a 120MHz system clock from + * an external 25MHz HSE clock. + */ +#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLM_VALUE 25 +#endif + +/** + * @brief PLLN multiplier value. + * @note The allowed values are 192..432. + * @note The default value is calculated for a 120MHz system clock from + * an external 25MHz HSE clock. + */ +#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLN_VALUE 240 +#endif + +/** + * @brief PLLP multiplier value. + * @note The allowed values are DIV2, DIV4, DIV6, DIV8. + * @note The default value is calculated for a 120MHz system clock from + * an external 25MHz HSE clock. + */ +#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLP_VALUE 2 +#endif + +/** + * @brief PLLQ multiplier value. + * @note The allowed values are 4..15. + * @note The default value is calculated for a 120MHz system clock from + * an external 25MHz HSE clock. + */ +#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLQ_VALUE 5 +#endif + +/** + * @brief AHB prescaler value. + * @note The default value is calculated for a 120MHz system clock from + * an external 25MHz HSE clock. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) +#define STM32_PPRE1 STM32_PPRE1_DIV4 +#endif + +/** + * @brief APB2 prescaler value. + */ +#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) +#define STM32_PPRE2 STM32_PPRE2_DIV2 +#endif + +/** + * @brief RTC prescaler value. + */ +#if !defined(STM32_RTCPRE_VALUE) || defined(__DOXYGEN__) +#define STM32_RTCPRE_VALUE 25 +#endif + +/** + * @brief MC01 clock source value. + * @note The default value outputs HSI clock on MC01 pin. + */ +#if !defined(STM32_MCO1SEL) || defined(__DOXYGEN__) +#define STM32_MCO1SEL STM32_MCO1SEL_HSI +#endif + +/** + * @brief MC01 prescaler value. + * @note The default value outputs HSI clock on MC01 pin. + */ +#if !defined(STM32_MCO1PRE) || defined(__DOXYGEN__) +#define STM32_MCO1PRE STM32_MCO1PRE_DIV1 +#endif + +/** + * @brief MC02 clock source value. + * @note The default value outputs SYSCLK / 5 on MC02 pin. + */ +#if !defined(STM32_MCO2SEL) || defined(__DOXYGEN__) +#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK +#endif + +/** + * @brief MC02 prescaler value. + * @note The default value outputs SYSCLK / 5 on MC02 pin. + */ +#if !defined(STM32_MCO2PRE) || defined(__DOXYGEN__) +#define STM32_MCO2PRE STM32_MCO2PRE_DIV5 +#endif + +/** + * @brief PLLI2SN multiplier value. + * @note The allowed values are 192..432. + * @note The default value is calculated for a 48000 I2S clock with + * I2SDIV = 12 and I2SODD = 1. + */ +#if !defined(STM32_PLLI2SN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SN_VALUE 384 +#endif + +/** + * @brief PLLI2SR multiplier value. + * @note The allowed values are 2..7. + * @note The default value is calculated for a 48000 I2S clock with + * I2SDIV = 12 and I2SODD = 1. + */ +#if !defined(STM32_PLLI2SP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLI2SLP_VALUE 5 +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/** + * @brief Maximum HSECLK. + */ +#define STM32_HSECLK_MAX 32000000 + +/** + * @brief Maximum SYSCLK. + */ +#define STM32_SYSCLK_MAX 120000000 + +/** + * @brief Maximum frequency thresholds and wait states for flash access. + * @note The values are valid for 2.7V to 3.6V supply range. + */ +#define STM32_0WS_THRESHOLD 30000000 +#define STM32_1WS_THRESHOLD 60000000 +#define STM32_2WS_THRESHOLD 90000000 +#define STM32_3WS_THRESHOLD 0 +#define STM32_4WS_THRESHOLD 0 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 + +/* HSI related checks.*/ +#if STM32_HSI_ENABLED +#else /* !STM32_HSI_ENABLED */ +#if STM32_ADC_CLOCK_ENABLED || \ + (STM32_SW == STM32_SW_HSI) || \ + ((STM32_SW == STM32_SW_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI)) || \ + (STM32_MCO1SEL == STM32_MCO1SEL_HSI) || \ + ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI)) +#error "required HSI clock is not enabled" +#endif +#endif /* !STM32_HSI_ENABLED */ + +/* HSE related checks.*/ +#if STM32_HSE_ENABLED +#if STM32_HSECLK == 0 +#error "impossible to activate HSE" +#endif +#if (STM32_HSECLK < 1000000) || (STM32_HSECLK > STM32_HSECLK_MAX) +#error "STM32_HSECLK outside acceptable range (1MHz...STM32_HSECLK_MAX)" +#endif +#else /* !STM32_HSE_ENABLED */ +#if (STM32_SW == STM32_SW_HSE) || \ + ((STM32_SW == STM32_SW_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) || \ + (STM32_MCO1SEL == STM32_MCO1SEL_HSE) || \ + ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) || \ + (STM32_MCO2SEL == STM32_MCO2SEL_HSE) || \ + ((STM32_MCO2SEL == STM32_MCO2SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) || \ + (STM_RTC_SOURCE == STM32_RTCSEL_HSEDIV) +#error "required HSE clock is not enabled" +#endif +#endif /* !STM32_HSE_ENABLED */ + +/* LSI related checks.*/ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ +#if STM_RTCCLK == STM32_LSICLK +#error "required LSI clock is not enabled" +#endif +#endif /* !STM32_LSI_ENABLED */ + +/* LSE related checks.*/ +#if STM32_LSE_ENABLED +#if (STM32_LSECLK == 0) +#error "impossible to activate LSE" +#endif +#if (STM32_LSECLK < 1000) || (STM32_LSECLK > 1000000) +#error "STM32_LSECLK outside acceptable range (1...1000KHz)" +#endif +#else /* !#if STM32_LSE_ENABLED */ +#if STM_RTCCLK == STM32_LSECLK +#error "required LSE clock is not enabled" +#endif +#endif /* !#if STM32_LSE_ENABLED */ + +/* PLL related checks.*/ +#if STM32_USB_CLOCK_ENABLED || \ + (STM32_SW == STM32_SW_PLL) || \ + (STM32_MCO1SEL == STM32_MCO1SEL_PLL) || \ + (STM32_MCO2SEL == STM32_MCO2SEL_PLL) || \ + defined(__DOXYGEN__) +/** + * @brief PLL activation flag. + */ +#define STM32_ACTIVATE_PLL TRUE +#else +#define STM32_ACTIVATE_PLL FALSE +#endif + +/** + * @brief STM32_PLLM field. + */ +#if ((STM32_PLLM_VALUE >= 2) && (STM32_PLLM_VALUE <= 63)) || \ + defined(__DOXYGEN__) +#define STM32_PLLM STM32_PLLM_VALUE +#else +#error "invalid STM32_PLLM_VALUE value specified" +#endif + +/** + * @brief STM32_PLLN field. + */ +#if ((STM32_PLLN_VALUE >= 192) && (STM32_PLLN_VALUE <= 432)) || \ + defined(__DOXYGEN__) +#define STM32_PLLN (STM32_PLLN_VALUE << 6) +#else +#error "invalid STM32_PLLN_VALUE value specified" +#endif + +/** + * @brief STM32_PLLP field. + */ +#if (STM32_PLLP_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLP (0 << 16) +#elif STM32_PLLP_VALUE == 4 +#define STM32_PLLP (1 << 16) +#elif STM32_PLLP_VALUE == 6 +#define STM32_PLLP (2 << 16) +#elif STM32_PLLP_VALUE == 8 +#define STM32_PLLP (3 << 16) +#else +#error "invalid STM32_PLLP_VALUE value specified" +#endif + +/** + * @brief STM32_PLLQ field. + */ +#if ((STM32_PLLQ_VALUE >= 4) && (STM32_PLLQ_VALUE <= 15)) || \ + defined(__DOXYGEN__) +#define STM32_PLLQ (STM32_PLLQ_VALUE << 24) +#else +#error "invalid STM32_PLLQ_VALUE value specified" +#endif + +/** + * @brief PLL input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLCLKIN STM32_HSECLK +#elif STM32_PLLSRC == STM32_PLLSRC_HSI +#define STM32_PLLCLKIN STM32_HSICLK +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/* PLL input frequency range check.*/ +#if (STM32_PLLCLKIN < 4000000) || (STM32_PLLCLKIN > 26000000) +#error "STM32_PLLCLKIN outside acceptable range (4...26MHz)" +#endif + +/** + * @brief PLL VCO frequency. + */ +#define STM32_PLLVCO ((STM32_PLLCLKIN / STM32_PLLM_VALUE) * \ + STM32_PLLN_VALUE) + +/* PLL output frequency range check.*/ +#if (STM32_PLLVCO < 192000000) || (STM32_PLLVCO > 432000000) +#error STM32_PLLVCO +#error "STM32_PLLVCO outside acceptable range (192...432MHz)" +#endif + +/** + * @brief PLL output clock frequency. + */ +#define STM32_PLLCLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) + +/* PLL output frequency range check.*/ +#if (STM32_PLLCLKOUT < 24000000) || (STM32_PLLCLKOUT > 120000000) +#error "STM32_PLLCLKOUT outside acceptable range (24...120MHz)" +#endif + +/** + * @brief System clock source. + */ +#if STM32_NO_INIT || defined(__DOXYGEN__) +#define STM32_SYSCLK 96000000 +#elif (STM32_SW == STM32_SW_HSI) +#define STM32_SYSCLK STM32_HSICLK +#elif (STM32_SW == STM32_SW_HSE) +#define STM32_SYSCLK STM32_HSECLK +#elif (STM32_SW == STM32_SW_PLL) +#define STM32_SYSCLK STM32_PLLCLKOUT +#else +#error "invalid STM32_SW value specified" +#endif + +/* Check on the system clock.*/ +#if STM32_SYSCLK > STM32_SYSCLK_MAX +#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYSCLK / 1) +#elif STM32_HPRE == STM32_HPRE_DIV2 +#define STM32_HCLK (STM32_SYSCLK / 2) +#elif STM32_HPRE == STM32_HPRE_DIV4 +#define STM32_HCLK (STM32_SYSCLK / 4) +#elif STM32_HPRE == STM32_HPRE_DIV8 +#define STM32_HCLK (STM32_SYSCLK / 8) +#elif STM32_HPRE == STM32_HPRE_DIV16 +#define STM32_HCLK (STM32_SYSCLK / 16) +#elif STM32_HPRE == STM32_HPRE_DIV64 +#define STM32_HCLK (STM32_SYSCLK / 64) +#elif STM32_HPRE == STM32_HPRE_DIV128 +#define STM32_HCLK (STM32_SYSCLK / 128) +#elif STM32_HPRE == STM32_HPRE_DIV256 +#define STM32_HCLK (STM32_SYSCLK / 256) +#elif STM32_HPRE == STM32_HPRE_DIV512 +#define STM32_HCLK (STM32_SYSCLK / 512) +#else +#error "invalid STM32_HPRE value specified" +#endif + +/* AHB frequency check.*/ +#if STM32_HCLK > STM32_SYSCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB1 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK1 (STM32_HCLK / 1) +#elif STM32_PPRE1 == STM32_PPRE1_DIV2 +#define STM32_PCLK1 (STM32_HCLK / 2) +#elif STM32_PPRE1 == STM32_PPRE1_DIV4 +#define STM32_PCLK1 (STM32_HCLK / 4) +#elif STM32_PPRE1 == STM32_PPRE1_DIV8 +#define STM32_PCLK1 (STM32_HCLK / 8) +#elif STM32_PPRE1 == STM32_PPRE1_DIV16 +#define STM32_PCLK1 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE1 value specified" +#endif + +/* APB1 frequency check.*/ +#if STM32_PCLK2 > STM32_SYSCLK_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB2 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK2 (STM32_HCLK / 1) +#elif STM32_PPRE2 == STM32_PPRE2_DIV2 +#define STM32_PCLK2 (STM32_HCLK / 2) +#elif STM32_PPRE2 == STM32_PPRE2_DIV4 +#define STM32_PCLK2 (STM32_HCLK / 4) +#elif STM32_PPRE2 == STM32_PPRE2_DIV8 +#define STM32_PCLK2 (STM32_HCLK / 8) +#elif STM32_PPRE2 == STM32_PPRE2_DIV16 +#define STM32_PCLK2 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE2 value specified" +#endif + +/* APB2 frequency check.*/ +#if STM32_PCLK2 > STM32_SYSCLK_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief RTC frequency. + */ +#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_RTCPRE (STM32_RTCPRE_VALUE << 16) +#else +#error "invalid STM32_RTCPRE value specified" +#endif + +/** + * @brief MCO1 divider clock. + */ +#if (STM32_MCO1SEL == STM32_MCO1SEL_HSI) || defined(__DOXYGEN__) +#define STM_MCO1DIVCLK STM32_HSICLK +#elif STM32_MCO1SEL == STM32_MCO1SEL_LSE +#define STM_MCO1DIVCLK STM32_LSECLK +#elif STM32_MCO1SEL == STM32_MCO1SEL_HSE +#define STM_MCO1DIVCLK STM32_HSECLK +#elif STM32_MCO1SEL == STM32_MCO1SEL_PLL +#define STM_MCO1DIVCLK STM32_PLLCLKOUT +#else +#error "invalid STM32_MCO1SEL value specified" +#endif + +/** + * @brief MCO1 output pin clock. + */ +#if (STM32_MCO1PRE == STM32_MCO1PRE_DIV1) || defined(__DOXYGEN__) +#define STM_MCO1CLK STM_MCO1DIVCLK +#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV2 +#define STM_MCO1CLK (STM_MCO1DIVCLK / 2) +#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV3 +#define STM_MCO1CLK (STM_MCO1DIVCLK / 3) +#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV4 +#define STM_MCO1CLK (STM_MCO1DIVCLK / 4) +#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV5 +#define STM_MCO1CLK (STM_MCO1DIVCLK / 5) +#else +#error "invalid STM32_MCO1PRE value specified" +#endif + +/** + * @brief MCO2 divider clock. + */ +#if (STM32_MCO2SEL == STM32_MCO2SEL_HSE) || defined(__DOXYGEN__) +#define STM_MCO2DIVCLK STM32_HSECLK +#elif STM32_MCO2SEL == STM32_MCO2SEL_PLL +#define STM_MCO2DIVCLK STM32_PLLCLKOUT +#elif STM32_MCO2SEL == STM32_MCO2SEL_SYSCLK +#define STM_MCO2DIVCLK STM32_SYSCLK +#elif STM32_MCO2SEL == STM32_MCO2SEL_PLLI2S +#define STM_MCO2DIVCLK STM32_PLLI2S + +#else +#error "invalid STM32_MCO2SEL value specified" +#endif + +/** + * @brief MCO2 output pin clock. + */ +#if (STM32_MCO2PRE == STM32_MCO2PRE_DIV1) || defined(__DOXYGEN__) +#define STM_MCO2CLK STM_MCO2DIVCLK +#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV2 +#define STM_MCO2CLK (STM_MCO2DIVCLK / 2) +#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV3 +#define STM_MCO2CLK (STM_MCO2DIVCLK / 3) +#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV4 +#define STM_MCO2CLK (STM_MCO2DIVCLK / 4) +#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV5 +#define STM_MCO2CLK (STM_MCO2DIVCLK / 5) +#else +#error "invalid STM32_MCO2PRE value specified" +#endif + +/** + * @brief HSE divider toward RTC clock. + */ +#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_HSEDIVCLK (HSECLK / STM32_RTCPRE_VALUE) +#else +#error "invalid STM32_RTCPRE value specified" +#endif + +/** + * @brief RTC clock. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM_RTCCLK 0 +#elif STM32_RTCSEL == STM32_RTCSEL_LSE +#define STM_RTCCLK STM32_LSECLK +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM_RTCCLK STM32_LSICLK +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM_RTCCLK STM32_HSEDIVCLK +#else +#error "invalid STM32_RTCSEL value specified" +#endif + +/** + * @brief ADC frequency. + */ +#if (STM32_ADCPRE == STM32_ADCPRE_DIV2) || defined(__DOXYGEN__) +#define STM32_ADCCLK (STM32_PCLK2 / 2) +#elif STM32_ADCPRE == STM32_ADCPRE_DIV4 +#define STM32_ADCCLK (STM32_PCLK2 / 4) +#elif STM32_ADCPRE == STM32_ADCPRE_DIV6 +#define STM32_ADCCLK (STM32_PCLK2 / 6) +#elif STM32_ADCPRE == STM32_ADCPRE_DIV8 +#define STM32_ADCCLK (STM32_PCLK2 / 8) +#else +#error "invalid STM32_ADCPRE value specified" +#endif + +/* ADC frequency check.*/ +#if STM32_ADCCLK > 30000000 +#error "STM32_ADCCLK exceeding maximum frequency (30MHz)" +#endif + +/** + * @brief OTG frequency. + */ +#if (STM32_OTGFSPRE == STM32_OTGFSPRE_DIV3) || defined(__DOXYGEN__) +#define STM32_OTGFSCLK (STM32_PLLVCO / 3) +#elif (STM32_OTGFSPRE == STM32_OTGFSPRE_DIV2) +#define STM32_OTGFSCLK (STM32_PLLVCO / 2) +#else +#error "invalid STM32_OTGFSPRE value specified" +#endif + +/** + * @brief Timers 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14 clock. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK1 (STM32_PCLK1 * 1) +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 2) +#endif + +/** + * @brief Timers 1, 8 clock. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK2 (STM32_PCLK2 * 1) +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 2) +#endif + +/** + * @brief Flash settings. + */ +#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_FLASHBITS 0x00000000 +#elif STM32_HCLK <= STM32_1WS_THRESHOLD +#define STM32_FLASHBITS 0x00000001 +#elif STM32_HCLK <= STM32_2WS_THRESHOLD +#define STM32_FLASHBITS 0x00000002 +#elif STM32_HCLK <= STM32_3WS_THRESHOLD +#define STM32_FLASHBITS 0x00000003 +#elif STM32_HCLK <= STM32_4WS_THRESHOLD +#define STM32_FLASHBITS 0x00000004 +#elif STM32_HCLK <= STM32_5WS_THRESHOLD +#define STM32_FLASHBITS 0x00000005 +#elif STM32_HCLK <= STM32_6WS_THRESHOLD +#define STM32_FLASHBITS 0x00000006 +#else +#define STM32_FLASHBITS 0x00000007 +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* STM32 DMA support code.*/ +//#include "stm32_dma.h" + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void stm32_clock_init(void); +#ifdef __cplusplus +} +#endif + +#endif /* _HAL_LLD_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32F4xx/platform.mk b/os/hal/platforms/STM32F4xx/platform.mk new file mode 100644 index 000000000..36d555536 --- /dev/null +++ b/os/hal/platforms/STM32F4xx/platform.mk @@ -0,0 +1,9 @@ +# List of all the STM32L1xx platform files. +PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F4xx/hal_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/serial_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c + +# Required include directories +PLATFORMINC = ${CHIBIOS}/os/hal/platforms/STM32F4xx \ + ${CHIBIOS}/os/hal/platforms/STM32 \ + ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2 diff --git a/os/hal/platforms/STM32F4xx/stm32_dma.c b/os/hal/platforms/STM32F4xx/stm32_dma.c new file mode 100644 index 000000000..e35d93543 --- /dev/null +++ b/os/hal/platforms/STM32F4xx/stm32_dma.c @@ -0,0 +1,541 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32F4xx/stm32_dma.c + * @brief Enhanced DMA helper driver code. + * + * @addtogroup STM32_DMA + * @details DMA sharing helper driver. In the STM32 the DMA streams are a + * shared resource, this driver allows to allocate and free DMA + * streams at runtime in order to allow all the other device + * drivers to coordinate the access to the resource. + * @note The DMA ISR handlers are all declared into this module because + * sharing, the various device drivers can associate a callback to + * IRSs when allocating streams. + * @{ + */ + +#include "ch.h" +#include "hal.h" + +/* The following macro is only defined if some driver requiring DMA services + has been enabled.*/ +#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/** + * @brief Mask of the DMA1 streams in @p dma_streams_mask. + */ +#define STM32_DMA1_STREAMS_MASK 0x000000FF + +/** + * @brief Mask of the DMA2 streams in @p dma_streams_mask. + */ +#define STM32_DMA2_STREAMS_MASK 0x0000FF00 + +/** + * @brief Post-reset value of the stream CR register. + */ +#define STM32_DMA_CR_RESET_VALUE 0x00000000 + +/** + * @brief Post-reset value of the stream FCR register. + */ +#define STM32_DMA_FCR_RESET_VALUE 0x00000021 + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief DMA 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_DMA1_STREAM0, @p STM32_DMA1_STREAM1 etc. + */ +const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { + {0, DMA1, DMA1_Stream0, &DMA1->LIFCR, 0}, + {1, DMA1, DMA1_Stream1, &DMA1->LIFCR, 6}, + {2, DMA1, DMA1_Stream2, &DMA1->LIFCR, 16}, + {3, DMA1, DMA1_Stream3, &DMA1->LIFCR, 22}, + {4, DMA1, DMA1_Stream4, &DMA1->HIFCR, 0}, + {5, DMA1, DMA1_Stream5, &DMA1->HIFCR, 6}, + {6, DMA1, DMA1_Stream6, &DMA1->HIFCR, 16}, + {7, DMA1, DMA1_Stream7, &DMA1->HIFCR, 22}, + {8, DMA2, DMA2_Stream0, &DMA2->LIFCR, 0}, + {9, DMA2, DMA2_Stream1, &DMA2->LIFCR, 6}, + {10, DMA2, DMA2_Stream2, &DMA2->LIFCR, 16}, + {11, DMA2, DMA2_Stream3, &DMA2->LIFCR, 22}, + {12, DMA2, DMA2_Stream4, &DMA2->HIFCR, 0}, + {13, DMA2, DMA2_Stream5, &DMA2->HIFCR, 6}, + {14, DMA2, DMA2_Stream6, &DMA2->HIFCR, 16}, + {15, DMA2, DMA2_Stream7, &DMA2->HIFCR, 22}, +}; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/** + * @brief DMA ISR redirector type. + */ +typedef struct { + stm32_dmaisr_t dma_func; + void *dma_param; +} dma_isr_redir_t; + +/** + * @brief Mask of the allocated streams. + */ +static uint32_t dma_streams_mask; + +/** + * @brief DMA IRQ redirectors. + */ +static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS]; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/** + * @brief DMA1 stream 0 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream0_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->LISR >> 0) & STM32_DMA_ISR_MASK; + DMA1->LIFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[0].dma_func) + dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 1 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream1_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->LISR >> 6) & STM32_DMA_ISR_MASK; + DMA1->LIFCR = STM32_DMA_ISR_MASK << 6; + if (dma_isr_redir[1].dma_func) + dma_isr_redir[1].dma_func(dma_isr_redir[0].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 2 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream2_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->LISR >> 16) & STM32_DMA_ISR_MASK; + DMA1->LIFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[2].dma_func) + dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->LISR >> 22) & STM32_DMA_ISR_MASK; + DMA1->LIFCR = STM32_DMA_ISR_MASK << 22; + if (dma_isr_redir[3].dma_func) + dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 4 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream4_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->HISR >> 0) & STM32_DMA_ISR_MASK; + DMA1->HIFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[4].dma_func) + dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->HISR >> 6) & STM32_DMA_ISR_MASK; + DMA1->HIFCR = STM32_DMA_ISR_MASK << 6; + if (dma_isr_redir[5].dma_func) + dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 6 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream6_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->HISR >> 16) & STM32_DMA_ISR_MASK; + DMA1->HIFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[6].dma_func) + dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 7 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream7_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->HISR >> 22) & STM32_DMA_ISR_MASK; + DMA1->HIFCR = STM32_DMA_ISR_MASK << 22; + if (dma_isr_redir[7].dma_func) + dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 0 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream0_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->LISR >> 0) & STM32_DMA_ISR_MASK; + DMA2->LIFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[8].dma_func) + dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 1 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream1_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->LISR >> 6) & STM32_DMA_ISR_MASK; + DMA2->LIFCR = STM32_DMA_ISR_MASK << 6; + if (dma_isr_redir[9].dma_func) + dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 2 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream2_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->LISR >> 16) & STM32_DMA_ISR_MASK; + DMA2->LIFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[10].dma_func) + dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->LISR >> 22) & STM32_DMA_ISR_MASK; + DMA2->LIFCR = STM32_DMA_ISR_MASK << 22; + if (dma_isr_redir[11].dma_func) + dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 4 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream4_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->HISR >> 0) & STM32_DMA_ISR_MASK; + DMA2->HIFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[12].dma_func) + dma_isr_redir[12].dma_func(dma_isr_redir[12].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->HISR >> 6) & STM32_DMA_ISR_MASK; + DMA2->HIFCR = STM32_DMA_ISR_MASK << 6; + if (dma_isr_redir[13].dma_func) + dma_isr_redir[13].dma_func(dma_isr_redir[13].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 6 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream6_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->HISR >> 16) & STM32_DMA_ISR_MASK; + DMA2->HIFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[14].dma_func) + dma_isr_redir[14].dma_func(dma_isr_redir[14].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 7 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream7_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->HISR >> 22) & STM32_DMA_ISR_MASK; + DMA2->HIFCR = STM32_DMA_ISR_MASK << 22; + if (dma_isr_redir[15].dma_func) + dma_isr_redir[15].dma_func(dma_isr_redir[15].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA helper initialization. + * + * @init + */ +void dmaInit(void) { + int i; + + dma_streams_mask = 0; + for (i = 0; i < STM32_DMA_STREAMS; i++) { + _stm32_dma_streams[i].stream->CR = 0; + dma_isr_redir[i].dma_func = NULL; + } + DMA1->LIFCR = 0xFFFFFFFF; + DMA1->HIFCR = 0xFFFFFFFF; + DMA2->LIFCR = 0xFFFFFFFF; + DMA2->HIFCR = 0xFFFFFFFF; +} + +/** + * @brief Allocates a DMA stream. + * @details The stream is allocated and, if required, the DMA clock enabled. + * The function also enables the IRQ vector associated to the stream + * and initializes its priority. + * @pre The stream must not be already in use or an error is returned. + * @post The stream is allocated and the default ISR handler redirected + * to the specified function. + * @post The stream ISR vector is enabled and its priority configured. + * @post The stream must be freed using @p dmaStreamRelease() before it can + * be reused with another peripheral. + * @post The stream is in its post-reset state. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] priority IRQ priority mask for the DMA stream + * @param[in] func handling function pointer, can be @p NULL + * @param[in] param a parameter to be passed to the handling function + * @return The operation status. + * @retval FALSE no error, stream taken. + * @retval TRUE error, stream already taken. + * + * @special + */ +bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param) { + + chDbgCheck(dmastp != NULL, "dmaAllocate"); + + /* Checks if the stream is already taken.*/ + if ((dma_streams_mask & dmastp->mask) != 0) + return TRUE; + + /* Marks the stream as allocated.*/ + dma_isr_redir[dmastp->selfindex].dma_func = func; + dma_isr_redir[dmastp->selfindex].dma_param = param; + dma_streams_mask |= (1 << dmastp->selfindex); + + /* Enabling DMA clocks required by the current streams set.*/ + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) { + RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; + RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA1LPEN; + } + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) { + RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; + RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA2LPEN; + } + + /* Putting the stream in a safe state.*/ + dmaStreamDisable(dmastp); + dmaStreamClearInterrupt(dmastp); + dmastp->channel->CR = STM32_DMA_CR_RESET_VALUE; + dmastp->channel->FCR = STM32_DMA_FCR_RESET_VALUE; + + /* Enables the associated IRQ vector if a callback is defined.*/ + if (func != NULL) + NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority)); + + return FALSE; +} + +/** + * @brief Releases a DMA stream. + * @details The stream is freed and, if required, the DMA clock disabled. + * Trying to release a unallocated stream is an illegal operation + * and is trapped if assertions are enabled. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post The stream is again available. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { + + chDbgCheck(dmastp != NULL, "dmaRelease"); + + /* Check if the streams is not taken.*/ + chDbgAssert((dma_streams_mask & dmastp->mask) != 0, + "dmaRelease(), #1", "not allocated"); + + /* Disables the associated IRQ vector.*/ + NVICDisableVector(dmastp->vector); + + /* Marks the stream as not allocated.*/ + dma_streams_mask &= ~(1 << dmastp->selfindex); + + /* Shutting down clocks that are no more required, if any.*/ + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) { + RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA1EN; + RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA1LPEN; + } + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) { + RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA2EN; + RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA2LPEN; + } +} + +#endif /* STM32_DMA_REQUIRED */ + +/** @} */ diff --git a/os/hal/platforms/STM32F4xx/stm32_dma.h b/os/hal/platforms/STM32F4xx/stm32_dma.h new file mode 100644 index 000000000..a1266fec4 --- /dev/null +++ b/os/hal/platforms/STM32F4xx/stm32_dma.h @@ -0,0 +1,327 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32F4xx/stm32_dma.h + * @brief Enhanced-DMA helper driver header. + * @note This file requires definitions from the ST STM32F2xx header file + * stm32f2xx.h. + * + * @addtogroup STM32_DMA + * @{ + */ + +#ifndef _STM32_DMA_H_ +#define _STM32_DMA_H_ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Total number of DMA streams. + * @note This is the total number of streams among all the DMA units. + */ +#define STM32_DMA_STREAMS 16 + +/** + * @brief Mask of the ISR bits passed to the DMA callback functions. + */ +#define STM32_DMA_ISR_MASK 0x3D + +/** + * @name DMA streams identifiers + * @{ + */ +#define STM32_DMA1_STREAM0 (&_stm32_dma_streams[0]) +#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[1]) +#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[2]) +#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[3]) +#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[4]) +#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[5]) +#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[6]) +#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[7]) +#define STM32_DMA2_STREAM0 (&_stm32_dma_streams[8]) +#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[9]) +#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[10]) +#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[11]) +#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[12]) +#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[13]) +#define STM32_DMA2_STREAM6 (&_stm32_dma_streams[14]) +#define STM32_DMA2_STREAM7 (&_stm32_dma_streams[15]) +/** @} */ + +/** + * @name CR register constants common to all DMA types + */ +#define STM32_DMA_CR_EN DMA_SxCR_EN +#define STM32_DMA_CR_TEIE DMA_SxCR_TEIE +#define STM32_DMA_CR_HTIE DMA_SxCR_HTIE +#define STM32_DMA_CR_TCIE DMA_SxCR_TCIE +#define STM32_DMA_CR_DIR_MASK DMA_SxCR_DIR +#define STM32_DMA_CR_DIR_P2M 0 +#define STM32_DMA_CR_DIR_M2P DMA_SxCR_DIR_0 +#define STM32_DMA_CR_DIR_M2M DMA_SxCR_DIR_1 +#define STM32_DMA_CR_CIRC DMA_SxCR_CIRC +#define STM32_DMA_CR_PINC DMA_SxCR_PINC +#define STM32_DMA_CR_MINC DMA_SxCR_MINC +#define STM32_DMA_CR_PSIZE_MASK DMA_SxCR_PSIZE +#define STM32_DMA_CR_PSIZE_BYTE 0 +#define STM32_DMA_CR_PSIZE_HWORD DMA_SxCR_PSIZE_0 +#define STM32_DMA_CR_PSIZE_WORD DMA_SxCR_PSIZE_1 +#define STM32_DMA_CR_MSIZE_MASK DMA_SxCR_MSIZE +#define STM32_DMA_CR_MSIZE_BYTE 0 +#define STM32_DMA_CR_MSIZE_HWORD DMA_SxCR_MSIZE_0 +#define STM32_DMA_CR_MSIZE_WORD DMA_SxCR_MSIZE_1 +#define STM32_DMA_CR_PL_MASK DMA_SxCR_PL +#define STM32_DMA_CR_PL(n) ((n) << 16) +/** @} */ + +/** + * @name CR register constants only found in STM32F2xx + */ +#define STM32_DMA_CR_DMEIE DMA_SxCR_DMEIE +#define STM32_DMA_CR_PFCTRL DMA_SxCR_PFCTRL +#define STM32_DMA_CR_PINCOS DMA_SxCR_PINCOS +#define STM32_DMA_CR_DBM DMA_SxCR_DBM +#define STM32_DMA_CR_CT DMA_SxCR_CT +#define STM32_DMA_CR_PBURST_MASK DMA_SxCR_PBURST +#define STM32_DMA_CR_PBURST_SINGLE 0 +#define STM32_DMA_CR_PBURST_INCR4 DMA_SxCR_PBURST_0 +#define STM32_DMA_CR_PBURST_INCR8 DMA_SxCR_PBURST_1 +#define STM32_DMA_CR_PBURST_INCR16 (DMA_SxCR_PBURST_0 | DMA_SxCR_PBURST_1) +#define STM32_DMA_CR_MBURST_MASK DMA_SxCR_MBURST +#define STM32_DMA_CR_MBURST_SINGLE 0 +#define STM32_DMA_CR_MBURST_INCR4 DMA_SxCR_MBURST_0 +#define STM32_DMA_CR_MBURST_INCR8 DMA_SxCR_MBURST_1 +#define STM32_DMA_CR_MBURST_INCR16 (DMA_SxCR_MBURST_0 | DMA_SxCR_MBURST_1) +#define STM32_DMA_CR_CHSEL_MASK DMA_SxCR_CHSEL +#define STM32_DMA_CR_CHSEL(n) ((n) << 25) +/** @} */ + +/** + * @name FCR register constants only found in STM32F2xx + */ +#define STM32_DMA_FCR_FEIE DMA_SxFCR_FEIE +#define STM32_DMA_FCR_FS_MASK DMA_SxFCR_FS +#define STM32_DMA_FCR_DMDIS DMA_SxFCR_DMDIS +#define STM32_DMA_FCR_FTH_MASK DMA_SxFCR_FTH +#define STM32_DMA_FCR_FTH_1Q 0 +#define STM32_DMA_FCR_FTH_HALF DMA_SxFCR_FTH_0 +#define STM32_DMA_FCR_FTH_3Q DMA_SxFCR_FTH_1 +#define STM32_DMA_FCR_FTH_FULL (DMA_SxFCR_FTH_0 | DMA_SxFCR_FTH_1) +/** @} */ + +/** + * @name Status flags passed to the ISR callbacks + */ +#define STM32_DMA_ISR_FEIF DMA_LISR_FEIF0 +#define STM32_DMA_ISR_DMEIF DMA_LISR_DMEIF0 +#define STM32_DMA_ISR_TEIF DMA_LISR_TEIF0 +#define STM32_DMA_ISR_HTIF DMA_LISR_HTIF0 +#define STM32_DMA_ISR_TCIF DMA_LISR_TCIF0 +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA stream descriptor structure. + */ +typedef struct { + DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ + volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */ + uint8_t ishift; /**< @brief Bits offset in xIFCR + register. */ + uint8_t selfindex; /**< @brief Index to self in array. */ + uint8_t vector; /**< @brief Associated IRQ vector. */ +} stm32_dma_stream_t; + +/** + * @brief STM32 DMA ISR function type. + * + * @param[in] p parameter for the registered function + * @param[in] flags pre-shifted content of the xISR register, the bits + * are aligned to bit zero + */ +typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Associates a peripheral data register to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the PAR register + * + * @special + */ +#define dmaStreamSetPeripheral(dmastp, addr) { \ + (dmastp)->stream->PAR = (uint32_t)(addr); \ +} + +/** + * @brief Associates a memory destination to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the M0AR register + * + * @special + */ +#define dmaStreamSetMemory0(dmastp, addr) { \ + (dmastp)->stream->M0AR = (uint32_t)(addr); \ +} + +/** + * @brief Associates an alternate memory destination to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the M1AR register + * + * @special + */ +#define dmaStreamSetMemory1(dmastp, addr) { \ + (dmastp)->stream->M1AR = (uint32_t)(addr); \ +} + +/** + * @brief Sets the number of transfers to be performed. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] size value to be written in the CNDTR register + * + * @special + */ +#define dmaStreamSetTransactionSize(dmastp, size) { \ + (dmastp)->stream->NDTR = (uint32_t)(size); \ +} + +/** + * @brief Returns the number of transfers to be performed. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @return The number of transfers to be performed. + * + * @special + */ +#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->stream->NDTR)) + +/** + * @brief Programs the stream mode settings. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] mode value to be written in the CR register + * + * @special + */ +#define dmaStreamSetMode(dmastp, mode) { \ + (dmastp)->stream->CR = (uint32_t)(mode); \ +} + +/** + * @brief Programs the stream FIFO settings. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] mode value to be written in the FCR register + * + * @special + */ +#define dmaStreamSetFIFO(dmastp, mode) { \ + (dmastp)->stream->FCR = (uint32_t)(mode); \ +} + +/** + * @brief DMA stream enable. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmachp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamEnable(dmachp) { \ + (dmastp)->stream->CR |= STM32_DMA_CR_EN; \ +} + +/** + * @brief DMA stream disable. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamDisable(dmastp) { \ + (dmastp)->stream->CR &= ~STM32_DMA_CR_EN; \ +} + +/** + * @brief DMA stream interrupt sources clear. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamClearInterrupt(dmastp) { \ + *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \ +} + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void dmaInit(void); + bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param); + void dmaStreamRelease(const stm32_dma_stream_t *dmastp); +#ifdef __cplusplus +} +#endif + +#endif /* _STM32_DMA_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32F4xx/stm32f4xx.h b/os/hal/platforms/STM32F4xx/stm32f4xx.h new file mode 100644 index 000000000..60dc0622a --- /dev/null +++ b/os/hal/platforms/STM32F4xx/stm32f4xx.h @@ -0,0 +1,7000 @@ +/** + ****************************************************************************** + * @file stm32f4xx.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer Header File. + * This file contains all the peripheral register's definitions, bits + * definitions and memory mapping for STM32F4xx devices. + * + * The file is the unique include file that the application programmer + * is using in the C source code, usually in main.c. This file contains: + * - Configuration section that allows to select: + * - The device used in the target application + * - To use or not the peripheral’s drivers in application code(i.e. + * code will be based on direct access to peripheral’s registers + * rather than drivers API), this option is controlled by + * "#define USE_STDPERIPH_DRIVER" + * - To change few application-specific parameters such as the HSE + * crystal frequency + * - Data structures and the address mapping for all peripherals + * - Peripheral's registers declarations and bits definition + * - Macros to access peripheral’s registers hardware + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f4xx + * @{ + */ + +#ifndef __STM32F4xx_H +#define __STM32F4xx_H + +#ifdef __cplusplus + extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup Library_configuration_section + * @{ + */ + +/* Uncomment the line below according to the target STM32 device used in your + application + */ + +#if !defined (STM32F4XX) + #define STM32F4XX +#endif + +/* Tip: To avoid modifying this file each time you need to switch between these + devices, you can define the device in your toolchain compiler preprocessor. + */ + +#if !defined (STM32F4XX) + #error "Please select first the target STM32F4XX device used in your application (in stm32f4xx.h file)" +#endif + +#if !defined (USE_STDPERIPH_DRIVER) +/** + * @brief Comment the line below if you will not use the peripherals drivers. + In this case, these drivers will not be included and the application code will + be based on direct access to peripherals registers + */ + /*#define USE_STDPERIPH_DRIVER*/ +#endif /* USE_STDPERIPH_DRIVER */ + +/** + * @brief In the following line adjust the value of External High Speed oscillator (HSE) + used in your application + + Tip: To avoid modifying this file each time you need to use different HSE, you + can define the HSE value in your toolchain compiler preprocessor. + */ + +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +/** + * @brief In the following line adjust the External High Speed oscillator (HSE) Startup + Timeout value + */ +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSE start up */ +#endif /* HSE_STARTUP_TIMEOUT */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief STM32F4XX Standard Peripherals Library version number V1.0.0 + */ +#define __STM32F4XX_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */ +#define __STM32F4XX_STDPERIPH_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */ +#define __STM32F4XX_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __STM32F4XX_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __STM32F4XX_STDPERIPH_VERSION ((__STM32F4XX_STDPERIPH_VERSION_MAIN << 24)\ + |(__STM32F4XX_STDPERIPH_VERSION_SUB1 << 16)\ + |(__STM32F4XX_STDPERIPH_VERSION_SUB2 << 8)\ + |(__STM32F4XX_STDPERIPH_VERSION_RC)) + +/** + * @} + */ + +/** @addtogroup Configuration_section_for_CMSIS + * @{ + */ + +/** + * @brief Configuration of the Cortex-M4 Processor and Core Peripherals + */ +#define __CM4_REV 0x0001 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 1 /*!< STM32F4XX provides an MPU */ +#define __NVIC_PRIO_BITS 4 /*!< STM32F4XX uses 4 Bits for the Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1 /*!< FPU present */ + +/** + * @brief STM32F4XX Interrupt Number Definition, according to the selected device + * in @ref Library_configuration_section + */ +typedef enum IRQn +{ +/****** Cortex-M4 Processor Exceptions Numbers ****************************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M4 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M4 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M4 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M4 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M4 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M4 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M4 System Tick Interrupt */ +/****** STM32 specific Interrupt Numbers **********************************************************************/ + WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ + PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */ + TAMP_STAMP_IRQn = 2, /*!< Tamper and TimeStamp interrupts through the EXTI line */ + RTC_WKUP_IRQn = 3, /*!< RTC Wakeup interrupt through the EXTI line */ + FLASH_IRQn = 4, /*!< FLASH global Interrupt */ + RCC_IRQn = 5, /*!< RCC global Interrupt */ + EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */ + EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */ + EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */ + EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */ + EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */ + DMA1_Stream0_IRQn = 11, /*!< DMA1 Stream 0 global Interrupt */ + DMA1_Stream1_IRQn = 12, /*!< DMA1 Stream 1 global Interrupt */ + DMA1_Stream2_IRQn = 13, /*!< DMA1 Stream 2 global Interrupt */ + DMA1_Stream3_IRQn = 14, /*!< DMA1 Stream 3 global Interrupt */ + DMA1_Stream4_IRQn = 15, /*!< DMA1 Stream 4 global Interrupt */ + DMA1_Stream5_IRQn = 16, /*!< DMA1 Stream 5 global Interrupt */ + DMA1_Stream6_IRQn = 17, /*!< DMA1 Stream 6 global Interrupt */ + ADC_IRQn = 18, /*!< ADC1, ADC2 and ADC3 global Interrupts */ + CAN1_TX_IRQn = 19, /*!< CAN1 TX Interrupt */ + CAN1_RX0_IRQn = 20, /*!< CAN1 RX0 Interrupt */ + CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ + CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break interrupt and TIM9 global interrupt */ + TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global interrupt */ + TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + USART3_IRQn = 39, /*!< USART3 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm (A and B) through EXTI Line Interrupt */ + OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS Wakeup through EXTI line interrupt */ + TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global interrupt */ + TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global interrupt */ + TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */ + TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */ + DMA1_Stream7_IRQn = 47, /*!< DMA1 Stream7 Interrupt */ + FSMC_IRQn = 48, /*!< FSMC global Interrupt */ + SDIO_IRQn = 49, /*!< SDIO global Interrupt */ + TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ + SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ + UART4_IRQn = 52, /*!< UART4 global Interrupt */ + UART5_IRQn = 53, /*!< UART5 global Interrupt */ + TIM6_DAC_IRQn = 54, /*!< TIM6 global and DAC1&2 underrun error interrupts */ + TIM7_IRQn = 55, /*!< TIM7 global interrupt */ + DMA2_Stream0_IRQn = 56, /*!< DMA2 Stream 0 global Interrupt */ + DMA2_Stream1_IRQn = 57, /*!< DMA2 Stream 1 global Interrupt */ + DMA2_Stream2_IRQn = 58, /*!< DMA2 Stream 2 global Interrupt */ + DMA2_Stream3_IRQn = 59, /*!< DMA2 Stream 3 global Interrupt */ + DMA2_Stream4_IRQn = 60, /*!< DMA2 Stream 4 global Interrupt */ + ETH_IRQn = 61, /*!< Ethernet global Interrupt */ + ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */ + CAN2_TX_IRQn = 63, /*!< CAN2 TX Interrupt */ + CAN2_RX0_IRQn = 64, /*!< CAN2 RX0 Interrupt */ + CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */ + CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */ + OTG_FS_IRQn = 67, /*!< USB OTG FS global Interrupt */ + DMA2_Stream5_IRQn = 68, /*!< DMA2 Stream 5 global interrupt */ + DMA2_Stream6_IRQn = 69, /*!< DMA2 Stream 6 global interrupt */ + DMA2_Stream7_IRQn = 70, /*!< DMA2 Stream 7 global interrupt */ + USART6_IRQn = 71, /*!< USART6 global interrupt */ + I2C3_EV_IRQn = 72, /*!< I2C3 event interrupt */ + I2C3_ER_IRQn = 73, /*!< I2C3 error interrupt */ + OTG_HS_EP1_OUT_IRQn = 74, /*!< USB OTG HS End Point 1 Out global interrupt */ + OTG_HS_EP1_IN_IRQn = 75, /*!< USB OTG HS End Point 1 In global interrupt */ + OTG_HS_WKUP_IRQn = 76, /*!< USB OTG HS Wakeup through EXTI interrupt */ + OTG_HS_IRQn = 77, /*!< USB OTG HS global interrupt */ + DCMI_IRQn = 78, /*!< DCMI global interrupt */ + CRYP_IRQn = 79, /*!< CRYP crypto global interrupt */ + HASH_RNG_IRQn = 80, /*!< Hash and Rng global interrupt */ + FPU_IRQn = 81 /*!< FPU global interrupt */ +} IRQn_Type; + +/** + * @} + */ + + /* CHIBIOS FIX */ +#include "core_cm4.h" /* Cortex-M4 processor and core peripherals */ +/*#include "system_stm32f4xx.h"*/ +#include + +/** @addtogroup Exported_types + * @{ + */ +/*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */ +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; + +typedef const int32_t sc32; /*!< Read Only */ +typedef const int16_t sc16; /*!< Read Only */ +typedef const int8_t sc8; /*!< Read Only */ + +typedef __IO int32_t vs32; +typedef __IO int16_t vs16; +typedef __IO int8_t vs8; + +typedef __I int32_t vsc32; /*!< Read Only */ +typedef __I int16_t vsc16; /*!< Read Only */ +typedef __I int8_t vsc8; /*!< Read Only */ + +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +typedef const uint32_t uc32; /*!< Read Only */ +typedef const uint16_t uc16; /*!< Read Only */ +typedef const uint8_t uc8; /*!< Read Only */ + +typedef __IO uint32_t vu32; +typedef __IO uint16_t vu16; +typedef __IO uint8_t vu8; + +typedef __I uint32_t vuc32; /*!< Read Only */ +typedef __I uint16_t vuc16; /*!< Read Only */ +typedef __I uint8_t vuc8; /*!< Read Only */ + +typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; + +typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; +#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) + +typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; + +/** + * @} + */ + +/** @addtogroup Peripheral_registers_structures + * @{ + */ + +/** + * @brief Analog to Digital Converter + */ + +typedef struct +{ + __IO uint32_t SR; /*!< ADC status register, Address offset: 0x00 */ + __IO uint32_t CR1; /*!< ADC control register 1, Address offset: 0x04 */ + __IO uint32_t CR2; /*!< ADC control register 2, Address offset: 0x08 */ + __IO uint32_t SMPR1; /*!< ADC sample time register 1, Address offset: 0x0C */ + __IO uint32_t SMPR2; /*!< ADC sample time register 2, Address offset: 0x10 */ + __IO uint32_t JOFR1; /*!< ADC injected channel data offset register 1, Address offset: 0x14 */ + __IO uint32_t JOFR2; /*!< ADC injected channel data offset register 2, Address offset: 0x18 */ + __IO uint32_t JOFR3; /*!< ADC injected channel data offset register 3, Address offset: 0x1C */ + __IO uint32_t JOFR4; /*!< ADC injected channel data offset register 4, Address offset: 0x20 */ + __IO uint32_t HTR; /*!< ADC watchdog higher threshold register, Address offset: 0x24 */ + __IO uint32_t LTR; /*!< ADC watchdog lower threshold register, Address offset: 0x28 */ + __IO uint32_t SQR1; /*!< ADC regular sequence register 1, Address offset: 0x2C */ + __IO uint32_t SQR2; /*!< ADC regular sequence register 2, Address offset: 0x30 */ + __IO uint32_t SQR3; /*!< ADC regular sequence register 3, Address offset: 0x34 */ + __IO uint32_t JSQR; /*!< ADC injected sequence register, Address offset: 0x38*/ + __IO uint32_t JDR1; /*!< ADC injected data register 1, Address offset: 0x3C */ + __IO uint32_t JDR2; /*!< ADC injected data register 2, Address offset: 0x40 */ + __IO uint32_t JDR3; /*!< ADC injected data register 3, Address offset: 0x44 */ + __IO uint32_t JDR4; /*!< ADC injected data register 4, Address offset: 0x48 */ + __IO uint32_t DR; /*!< ADC regular data register, Address offset: 0x4C */ +} ADC_TypeDef; + +typedef struct +{ + __IO uint32_t CSR; /*!< ADC Common status register, Address offset: ADC1 base address + 0x300 */ + __IO uint32_t CCR; /*!< ADC common control register, Address offset: ADC1 base address + 0x304 */ + __IO uint32_t CDR; /*!< ADC common regular data register for dual + AND triple modes, Address offset: ADC1 base address + 0x308 */ +} ADC_Common_TypeDef; + + +/** + * @brief Controller Area Network TxMailBox + */ + +typedef struct +{ + __IO uint32_t TIR; /*!< CAN TX mailbox identifier register */ + __IO uint32_t TDTR; /*!< CAN mailbox data length control and time stamp register */ + __IO uint32_t TDLR; /*!< CAN mailbox data low register */ + __IO uint32_t TDHR; /*!< CAN mailbox data high register */ +} CAN_TxMailBox_TypeDef; + +/** + * @brief Controller Area Network FIFOMailBox + */ + +typedef struct +{ + __IO uint32_t RIR; /*!< CAN receive FIFO mailbox identifier register */ + __IO uint32_t RDTR; /*!< CAN receive FIFO mailbox data length control and time stamp register */ + __IO uint32_t RDLR; /*!< CAN receive FIFO mailbox data low register */ + __IO uint32_t RDHR; /*!< CAN receive FIFO mailbox data high register */ +} CAN_FIFOMailBox_TypeDef; + +/** + * @brief Controller Area Network FilterRegister + */ + +typedef struct +{ + __IO uint32_t FR1; /*!< CAN Filter bank register 1 */ + __IO uint32_t FR2; /*!< CAN Filter bank register 1 */ +} CAN_FilterRegister_TypeDef; + +/** + * @brief Controller Area Network + */ + +typedef struct +{ + __IO uint32_t MCR; /*!< CAN master control register, Address offset: 0x00 */ + __IO uint32_t MSR; /*!< CAN master status register, Address offset: 0x04 */ + __IO uint32_t TSR; /*!< CAN transmit status register, Address offset: 0x08 */ + __IO uint32_t RF0R; /*!< CAN receive FIFO 0 register, Address offset: 0x0C */ + __IO uint32_t RF1R; /*!< CAN receive FIFO 1 register, Address offset: 0x10 */ + __IO uint32_t IER; /*!< CAN interrupt enable register, Address offset: 0x14 */ + __IO uint32_t ESR; /*!< CAN error status register, Address offset: 0x18 */ + __IO uint32_t BTR; /*!< CAN bit timing register, Address offset: 0x1C */ + uint32_t RESERVED0[88]; /*!< Reserved, 0x020 - 0x17F */ + CAN_TxMailBox_TypeDef sTxMailBox[3]; /*!< CAN Tx MailBox, Address offset: 0x180 - 0x1AC */ + CAN_FIFOMailBox_TypeDef sFIFOMailBox[2]; /*!< CAN FIFO MailBox, Address offset: 0x1B0 - 0x1CC */ + uint32_t RESERVED1[12]; /*!< Reserved, 0x1D0 - 0x1FF */ + __IO uint32_t FMR; /*!< CAN filter master register, Address offset: 0x200 */ + __IO uint32_t FM1R; /*!< CAN filter mode register, Address offset: 0x204 */ + uint32_t RESERVED2; /*!< Reserved, 0x208 */ + __IO uint32_t FS1R; /*!< CAN filter scale register, Address offset: 0x20C */ + uint32_t RESERVED3; /*!< Reserved, 0x210 */ + __IO uint32_t FFA1R; /*!< CAN filter FIFO assignment register, Address offset: 0x214 */ + uint32_t RESERVED4; /*!< Reserved, 0x218 */ + __IO uint32_t FA1R; /*!< CAN filter activation register, Address offset: 0x21C */ + uint32_t RESERVED5[8]; /*!< Reserved, 0x220-0x23F */ + CAN_FilterRegister_TypeDef sFilterRegister[28]; /*!< CAN Filter Register, Address offset: 0x240-0x31C */ +} CAN_TypeDef; + +/** + * @brief CRC calculation unit + */ + +typedef struct +{ + __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */ + __IO uint8_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */ + uint8_t RESERVED0; /*!< Reserved, 0x05 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ +} CRC_TypeDef; + +/** + * @brief Digital to Analog Converter + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DAC control register, Address offset: 0x00 */ + __IO uint32_t SWTRIGR; /*!< DAC software trigger register, Address offset: 0x04 */ + __IO uint32_t DHR12R1; /*!< DAC channel1 12-bit right-aligned data holding register, Address offset: 0x08 */ + __IO uint32_t DHR12L1; /*!< DAC channel1 12-bit left aligned data holding register, Address offset: 0x0C */ + __IO uint32_t DHR8R1; /*!< DAC channel1 8-bit right aligned data holding register, Address offset: 0x10 */ + __IO uint32_t DHR12R2; /*!< DAC channel2 12-bit right aligned data holding register, Address offset: 0x14 */ + __IO uint32_t DHR12L2; /*!< DAC channel2 12-bit left aligned data holding register, Address offset: 0x18 */ + __IO uint32_t DHR8R2; /*!< DAC channel2 8-bit right-aligned data holding register, Address offset: 0x1C */ + __IO uint32_t DHR12RD; /*!< Dual DAC 12-bit right-aligned data holding register, Address offset: 0x20 */ + __IO uint32_t DHR12LD; /*!< DUAL DAC 12-bit left aligned data holding register, Address offset: 0x24 */ + __IO uint32_t DHR8RD; /*!< DUAL DAC 8-bit right aligned data holding register, Address offset: 0x28 */ + __IO uint32_t DOR1; /*!< DAC channel1 data output register, Address offset: 0x2C */ + __IO uint32_t DOR2; /*!< DAC channel2 data output register, Address offset: 0x30 */ + __IO uint32_t SR; /*!< DAC status register, Address offset: 0x34 */ +} DAC_TypeDef; + +/** + * @brief Debug MCU + */ + +typedef struct +{ + __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */ + __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */ + __IO uint32_t APB1FZ; /*!< Debug MCU APB1 freeze register, Address offset: 0x08 */ + __IO uint32_t APB2FZ; /*!< Debug MCU APB2 freeze register, Address offset: 0x0C */ +}DBGMCU_TypeDef; + +/** + * @brief DCMI + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DCMI control register 1, Address offset: 0x00 */ + __IO uint32_t SR; /*!< DCMI status register, Address offset: 0x04 */ + __IO uint32_t RISR; /*!< DCMI raw interrupt status register, Address offset: 0x08 */ + __IO uint32_t IER; /*!< DCMI interrupt enable register, Address offset: 0x0C */ + __IO uint32_t MISR; /*!< DCMI masked interrupt status register, Address offset: 0x10 */ + __IO uint32_t ICR; /*!< DCMI interrupt clear register, Address offset: 0x14 */ + __IO uint32_t ESCR; /*!< DCMI embedded synchronization code register, Address offset: 0x18 */ + __IO uint32_t ESUR; /*!< DCMI embedded synchronization unmask register, Address offset: 0x1C */ + __IO uint32_t CWSTRTR; /*!< DCMI crop window start, Address offset: 0x20 */ + __IO uint32_t CWSIZER; /*!< DCMI crop window size, Address offset: 0x24 */ + __IO uint32_t DR; /*!< DCMI data register, Address offset: 0x28 */ +} DCMI_TypeDef; + +/** + * @brief DMA Controller + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DMA stream x configuration register */ + __IO uint32_t NDTR; /*!< DMA stream x number of data register */ + __IO uint32_t PAR; /*!< DMA stream x peripheral address register */ + __IO uint32_t M0AR; /*!< DMA stream x memory 0 address register */ + __IO uint32_t M1AR; /*!< DMA stream x memory 1 address register */ + __IO uint32_t FCR; /*!< DMA stream x FIFO control register */ +} DMA_Stream_TypeDef; + +typedef struct +{ + __IO uint32_t LISR; /*!< DMA low interrupt status register, Address offset: 0x00 */ + __IO uint32_t HISR; /*!< DMA high interrupt status register, Address offset: 0x04 */ + __IO uint32_t LIFCR; /*!< DMA low interrupt flag clear register, Address offset: 0x08 */ + __IO uint32_t HIFCR; /*!< DMA high interrupt flag clear register, Address offset: 0x0C */ +} DMA_TypeDef; + +/** + * @brief Ethernet MAC + */ + +typedef struct +{ + __IO uint32_t MACCR; + __IO uint32_t MACFFR; + __IO uint32_t MACHTHR; + __IO uint32_t MACHTLR; + __IO uint32_t MACMIIAR; + __IO uint32_t MACMIIDR; + __IO uint32_t MACFCR; + __IO uint32_t MACVLANTR; /* 8 */ + uint32_t RESERVED0[2]; + __IO uint32_t MACRWUFFR; /* 11 */ + __IO uint32_t MACPMTCSR; + uint32_t RESERVED1[2]; + __IO uint32_t MACSR; /* 15 */ + __IO uint32_t MACIMR; + __IO uint32_t MACA0HR; + __IO uint32_t MACA0LR; + __IO uint32_t MACA1HR; + __IO uint32_t MACA1LR; + __IO uint32_t MACA2HR; + __IO uint32_t MACA2LR; + __IO uint32_t MACA3HR; + __IO uint32_t MACA3LR; /* 24 */ + uint32_t RESERVED2[40]; + __IO uint32_t MMCCR; /* 65 */ + __IO uint32_t MMCRIR; + __IO uint32_t MMCTIR; + __IO uint32_t MMCRIMR; + __IO uint32_t MMCTIMR; /* 69 */ + uint32_t RESERVED3[14]; + __IO uint32_t MMCTGFSCCR; /* 84 */ + __IO uint32_t MMCTGFMSCCR; + uint32_t RESERVED4[5]; + __IO uint32_t MMCTGFCR; + uint32_t RESERVED5[10]; + __IO uint32_t MMCRFCECR; + __IO uint32_t MMCRFAECR; + uint32_t RESERVED6[10]; + __IO uint32_t MMCRGUFCR; + uint32_t RESERVED7[334]; + __IO uint32_t PTPTSCR; + __IO uint32_t PTPSSIR; + __IO uint32_t PTPTSHR; + __IO uint32_t PTPTSLR; + __IO uint32_t PTPTSHUR; + __IO uint32_t PTPTSLUR; + __IO uint32_t PTPTSAR; + __IO uint32_t PTPTTHR; + __IO uint32_t PTPTTLR; + __IO uint32_t RESERVED8; + __IO uint32_t PTPTSSR; + uint32_t RESERVED9[565]; + __IO uint32_t DMABMR; + __IO uint32_t DMATPDR; + __IO uint32_t DMARPDR; + __IO uint32_t DMARDLAR; + __IO uint32_t DMATDLAR; + __IO uint32_t DMASR; + __IO uint32_t DMAOMR; + __IO uint32_t DMAIER; + __IO uint32_t DMAMFBOCR; + __IO uint32_t DMARSWTR; + uint32_t RESERVED10[8]; + __IO uint32_t DMACHTDR; + __IO uint32_t DMACHRDR; + __IO uint32_t DMACHTBAR; + __IO uint32_t DMACHRBAR; +} ETH_TypeDef; + +/** + * @brief External Interrupt/Event Controller + */ + +typedef struct +{ + __IO uint32_t IMR; /*!< EXTI Interrupt mask register, Address offset: 0x00 */ + __IO uint32_t EMR; /*!< EXTI Event mask register, Address offset: 0x04 */ + __IO uint32_t RTSR; /*!< EXTI Rising trigger selection register, Address offset: 0x08 */ + __IO uint32_t FTSR; /*!< EXTI Falling trigger selection register, Address offset: 0x0C */ + __IO uint32_t SWIER; /*!< EXTI Software interrupt event register, Address offset: 0x10 */ + __IO uint32_t PR; /*!< EXTI Pending register, Address offset: 0x14 */ +} EXTI_TypeDef; + +/** + * @brief FLASH Registers + */ + +typedef struct +{ + __IO uint32_t ACR; /*!< FLASH access control register, Address offset: 0x00 */ + __IO uint32_t KEYR; /*!< FLASH key register, Address offset: 0x04 */ + __IO uint32_t OPTKEYR; /*!< FLASH option key register, Address offset: 0x08 */ + __IO uint32_t SR; /*!< FLASH status register, Address offset: 0x0C */ + __IO uint32_t CR; /*!< FLASH control register, Address offset: 0x10 */ + __IO uint32_t OPTCR; /*!< FLASH option control register, Address offset: 0x14 */ +} FLASH_TypeDef; + +/** + * @brief Flexible Static Memory Controller + */ + +typedef struct +{ + __IO uint32_t BTCR[8]; /*!< NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR), Address offset: 0x00-1C */ +} FSMC_Bank1_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank1E + */ + +typedef struct +{ + __IO uint32_t BWTR[7]; /*!< NOR/PSRAM write timing registers, Address offset: 0x104-0x11C */ +} FSMC_Bank1E_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank2 + */ + +typedef struct +{ + __IO uint32_t PCR2; /*!< NAND Flash control register 2, Address offset: 0x60 */ + __IO uint32_t SR2; /*!< NAND Flash FIFO status and interrupt register 2, Address offset: 0x64 */ + __IO uint32_t PMEM2; /*!< NAND Flash Common memory space timing register 2, Address offset: 0x68 */ + __IO uint32_t PATT2; /*!< NAND Flash Attribute memory space timing register 2, Address offset: 0x6C */ + uint32_t RESERVED0; /*!< Reserved, 0x70 */ + __IO uint32_t ECCR2; /*!< NAND Flash ECC result registers 2, Address offset: 0x74 */ +} FSMC_Bank2_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank3 + */ + +typedef struct +{ + __IO uint32_t PCR3; /*!< NAND Flash control register 3, Address offset: 0x80 */ + __IO uint32_t SR3; /*!< NAND Flash FIFO status and interrupt register 3, Address offset: 0x84 */ + __IO uint32_t PMEM3; /*!< NAND Flash Common memory space timing register 3, Address offset: 0x88 */ + __IO uint32_t PATT3; /*!< NAND Flash Attribute memory space timing register 3, Address offset: 0x8C */ + uint32_t RESERVED0; /*!< Reserved, 0x90 */ + __IO uint32_t ECCR3; /*!< NAND Flash ECC result registers 3, Address offset: 0x94 */ +} FSMC_Bank3_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank4 + */ + +typedef struct +{ + __IO uint32_t PCR4; /*!< PC Card control register 4, Address offset: 0xA0 */ + __IO uint32_t SR4; /*!< PC Card FIFO status and interrupt register 4, Address offset: 0xA4 */ + __IO uint32_t PMEM4; /*!< PC Card Common memory space timing register 4, Address offset: 0xA8 */ + __IO uint32_t PATT4; /*!< PC Card Attribute memory space timing register 4, Address offset: 0xAC */ + __IO uint32_t PIO4; /*!< PC Card I/O space timing register 4, Address offset: 0xB0 */ +} FSMC_Bank4_TypeDef; + +/** + * @brief General Purpose I/O + */ + +typedef struct +{ + __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ + __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ + __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ + __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ + __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ + __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ + __IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */ + __IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */ + __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ + __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ +} GPIO_TypeDef; + +/** + * @brief System configuration controller + */ + +typedef struct +{ + __IO uint32_t MEMRMP; /*!< SYSCFG memory remap register, Address offset: 0x00 */ + __IO uint32_t PMC; /*!< SYSCFG peripheral mode configuration register, Address offset: 0x04 */ + __IO uint32_t EXTICR[4]; /*!< SYSCFG external interrupt configuration registers, Address offset: 0x08-0x14 */ + uint32_t RESERVED[2]; /*!< Reserved, 0x18-0x1C */ + __IO uint32_t CMPCR; /*!< SYSCFG Compensation cell control register, Address offset: 0x20 */ +} SYSCFG_TypeDef; + +/** + * @brief Inter-integrated Circuit Interface + */ + +typedef struct +{ + __IO uint16_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t OAR1; /*!< I2C Own address register 1, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t OAR2; /*!< I2C Own address register 2, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t DR; /*!< I2C Data register, Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t SR1; /*!< I2C Status register 1, Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t SR2; /*!< I2C Status register 2, Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ + __IO uint16_t CCR; /*!< I2C Clock control register, Address offset: 0x1C */ + uint16_t RESERVED7; /*!< Reserved, 0x1E */ + __IO uint16_t TRISE; /*!< I2C TRISE register, Address offset: 0x20 */ + uint16_t RESERVED8; /*!< Reserved, 0x22 */ +} I2C_TypeDef; + +/** + * @brief Independent WATCHDOG + */ + +typedef struct +{ + __IO uint32_t KR; /*!< IWDG Key register, Address offset: 0x00 */ + __IO uint32_t PR; /*!< IWDG Prescaler register, Address offset: 0x04 */ + __IO uint32_t RLR; /*!< IWDG Reload register, Address offset: 0x08 */ + __IO uint32_t SR; /*!< IWDG Status register, Address offset: 0x0C */ +} IWDG_TypeDef; + +/** + * @brief Power Control + */ + +typedef struct +{ + __IO uint32_t CR; /*!< PWR power control register, Address offset: 0x00 */ + __IO uint32_t CSR; /*!< PWR power control/status register, Address offset: 0x04 */ +} PWR_TypeDef; + +/** + * @brief Reset and Clock Control + */ + +typedef struct +{ + __IO uint32_t CR; /*!< RCC clock control register, Address offset: 0x00 */ + __IO uint32_t PLLCFGR; /*!< RCC PLL configuration register, Address offset: 0x04 */ + __IO uint32_t CFGR; /*!< RCC clock configuration register, Address offset: 0x08 */ + __IO uint32_t CIR; /*!< RCC clock interrupt register, Address offset: 0x0C */ + __IO uint32_t AHB1RSTR; /*!< RCC AHB1 peripheral reset register, Address offset: 0x10 */ + __IO uint32_t AHB2RSTR; /*!< RCC AHB2 peripheral reset register, Address offset: 0x14 */ + __IO uint32_t AHB3RSTR; /*!< RCC AHB3 peripheral reset register, Address offset: 0x18 */ + uint32_t RESERVED0; /*!< Reserved, 0x1C */ + __IO uint32_t APB1RSTR; /*!< RCC APB1 peripheral reset register, Address offset: 0x20 */ + __IO uint32_t APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x24 */ + uint32_t RESERVED1[2]; /*!< Reserved, 0x28-0x2C */ + __IO uint32_t AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0x30 */ + __IO uint32_t AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0x34 */ + __IO uint32_t AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0x38 */ + uint32_t RESERVED2; /*!< Reserved, 0x3C */ + __IO uint32_t APB1ENR; /*!< RCC APB1 peripheral clock enable register, Address offset: 0x40 */ + __IO uint32_t APB2ENR; /*!< RCC APB2 peripheral clock enable register, Address offset: 0x44 */ + uint32_t RESERVED3[2]; /*!< Reserved, 0x48-0x4C */ + __IO uint32_t AHB1LPENR; /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */ + __IO uint32_t AHB2LPENR; /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */ + __IO uint32_t AHB3LPENR; /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */ + uint32_t RESERVED4; /*!< Reserved, 0x5C */ + __IO uint32_t APB1LPENR; /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */ + __IO uint32_t APB2LPENR; /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */ + uint32_t RESERVED5[2]; /*!< Reserved, 0x68-0x6C */ + __IO uint32_t BDCR; /*!< RCC Backup domain control register, Address offset: 0x70 */ + __IO uint32_t CSR; /*!< RCC clock control & status register, Address offset: 0x74 */ + uint32_t RESERVED6[2]; /*!< Reserved, 0x78-0x7C */ + __IO uint32_t SSCGR; /*!< RCC spread spectrum clock generation register, Address offset: 0x80 */ + __IO uint32_t PLLI2SCFGR; /*!< RCC PLLI2S configuration register, Address offset: 0x84 */ +} RCC_TypeDef; + +/** + * @brief Real-Time Clock + */ + +typedef struct +{ + __IO uint32_t TR; /*!< RTC time register, Address offset: 0x00 */ + __IO uint32_t DR; /*!< RTC date register, Address offset: 0x04 */ + __IO uint32_t CR; /*!< RTC control register, Address offset: 0x08 */ + __IO uint32_t ISR; /*!< RTC initialization and status register, Address offset: 0x0C */ + __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ + __IO uint32_t WUTR; /*!< RTC wakeup timer register, Address offset: 0x14 */ + __IO uint32_t CALIBR; /*!< RTC calibration register, Address offset: 0x18 */ + __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x1C */ + __IO uint32_t ALRMBR; /*!< RTC alarm B register, Address offset: 0x20 */ + __IO uint32_t WPR; /*!< RTC write protection register, Address offset: 0x24 */ + __IO uint32_t SSR; /*!< RTC sub second register, Address offset: 0x28 */ + __IO uint32_t SHIFTR; /*!< RTC shift control register, Address offset: 0x2C */ + __IO uint32_t TSTR; /*!< RTC time stamp time register, Address offset: 0x30 */ + __IO uint32_t TSDR; /*!< RTC time stamp date register, Address offset: 0x34 */ + __IO uint32_t TSSSR; /*!< RTC time-stamp sub second register, Address offset: 0x38 */ + __IO uint32_t CALR; /*!< RTC calibration register, Address offset: 0x3C */ + __IO uint32_t TAFCR; /*!< RTC tamper and alternate function configuration register, Address offset: 0x40 */ + __IO uint32_t ALRMASSR;/*!< RTC alarm A sub second register, Address offset: 0x44 */ + __IO uint32_t ALRMBSSR;/*!< RTC alarm B sub second register, Address offset: 0x48 */ + uint32_t RESERVED7; /*!< Reserved, 0x4C */ + __IO uint32_t BKP0R; /*!< RTC backup register 1, Address offset: 0x50 */ + __IO uint32_t BKP1R; /*!< RTC backup register 1, Address offset: 0x54 */ + __IO uint32_t BKP2R; /*!< RTC backup register 2, Address offset: 0x58 */ + __IO uint32_t BKP3R; /*!< RTC backup register 3, Address offset: 0x5C */ + __IO uint32_t BKP4R; /*!< RTC backup register 4, Address offset: 0x60 */ + __IO uint32_t BKP5R; /*!< RTC backup register 5, Address offset: 0x64 */ + __IO uint32_t BKP6R; /*!< RTC backup register 6, Address offset: 0x68 */ + __IO uint32_t BKP7R; /*!< RTC backup register 7, Address offset: 0x6C */ + __IO uint32_t BKP8R; /*!< RTC backup register 8, Address offset: 0x70 */ + __IO uint32_t BKP9R; /*!< RTC backup register 9, Address offset: 0x74 */ + __IO uint32_t BKP10R; /*!< RTC backup register 10, Address offset: 0x78 */ + __IO uint32_t BKP11R; /*!< RTC backup register 11, Address offset: 0x7C */ + __IO uint32_t BKP12R; /*!< RTC backup register 12, Address offset: 0x80 */ + __IO uint32_t BKP13R; /*!< RTC backup register 13, Address offset: 0x84 */ + __IO uint32_t BKP14R; /*!< RTC backup register 14, Address offset: 0x88 */ + __IO uint32_t BKP15R; /*!< RTC backup register 15, Address offset: 0x8C */ + __IO uint32_t BKP16R; /*!< RTC backup register 16, Address offset: 0x90 */ + __IO uint32_t BKP17R; /*!< RTC backup register 17, Address offset: 0x94 */ + __IO uint32_t BKP18R; /*!< RTC backup register 18, Address offset: 0x98 */ + __IO uint32_t BKP19R; /*!< RTC backup register 19, Address offset: 0x9C */ +} RTC_TypeDef; + +/** + * @brief SD host Interface + */ + +typedef struct +{ + __IO uint32_t POWER; /*!< SDIO power control register, Address offset: 0x00 */ + __IO uint32_t CLKCR; /*!< SDI clock control register, Address offset: 0x04 */ + __IO uint32_t ARG; /*!< SDIO argument register, Address offset: 0x08 */ + __IO uint32_t CMD; /*!< SDIO command register, Address offset: 0x0C */ + __I uint32_t RESPCMD; /*!< SDIO command response register, Address offset: 0x10 */ + __I uint32_t RESP1; /*!< SDIO response 1 register, Address offset: 0x14 */ + __I uint32_t RESP2; /*!< SDIO response 2 register, Address offset: 0x18 */ + __I uint32_t RESP3; /*!< SDIO response 3 register, Address offset: 0x1C */ + __I uint32_t RESP4; /*!< SDIO response 4 register, Address offset: 0x20 */ + __IO uint32_t DTIMER; /*!< SDIO data timer register, Address offset: 0x24 */ + __IO uint32_t DLEN; /*!< SDIO data length register, Address offset: 0x28 */ + __IO uint32_t DCTRL; /*!< SDIO data control register, Address offset: 0x2C */ + __I uint32_t DCOUNT; /*!< SDIO data counter register, Address offset: 0x30 */ + __I uint32_t STA; /*!< SDIO status register, Address offset: 0x34 */ + __IO uint32_t ICR; /*!< SDIO interrupt clear register, Address offset: 0x38 */ + __IO uint32_t MASK; /*!< SDIO mask register, Address offset: 0x3C */ + uint32_t RESERVED0[2]; /*!< Reserved, 0x40-0x44 */ + __I uint32_t FIFOCNT; /*!< SDIO FIFO counter register, Address offset: 0x48 */ + uint32_t RESERVED1[13]; /*!< Reserved, 0x4C-0x7C */ + __IO uint32_t FIFO; /*!< SDIO data FIFO register, Address offset: 0x80 */ +} SDIO_TypeDef; + +/** + * @brief Serial Peripheral Interface + */ + +typedef struct +{ + __IO uint16_t CR1; /*!< SPI control register 1 (not used in I2S mode), Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t CR2; /*!< SPI control register 2, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t SR; /*!< SPI status register, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t DR; /*!< SPI data register, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t CRCPR; /*!< SPI CRC polynomial register (not used in I2S mode), Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t RXCRCR; /*!< SPI RX CRC register (not used in I2S mode), Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t TXCRCR; /*!< SPI TX CRC register (not used in I2S mode), Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ + __IO uint16_t I2SCFGR; /*!< SPI_I2S configuration register, Address offset: 0x1C */ + uint16_t RESERVED7; /*!< Reserved, 0x1E */ + __IO uint16_t I2SPR; /*!< SPI_I2S prescaler register, Address offset: 0x20 */ + uint16_t RESERVED8; /*!< Reserved, 0x22 */ +} SPI_TypeDef; + +/** + * @brief TIM + */ + +typedef struct +{ + __IO uint16_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t CR2; /*!< TIM control register 2, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t SR; /*!< TIM status register, Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t EGR; /*!< TIM event generation register, Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ + __IO uint16_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */ + uint16_t RESERVED7; /*!< Reserved, 0x1E */ + __IO uint16_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */ + uint16_t RESERVED8; /*!< Reserved, 0x22 */ + __IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */ + __IO uint16_t PSC; /*!< TIM prescaler, Address offset: 0x28 */ + uint16_t RESERVED9; /*!< Reserved, 0x2A */ + __IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */ + __IO uint16_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */ + uint16_t RESERVED10; /*!< Reserved, 0x32 */ + __IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */ + __IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */ + __IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */ + __IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */ + __IO uint16_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */ + uint16_t RESERVED11; /*!< Reserved, 0x46 */ + __IO uint16_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */ + uint16_t RESERVED12; /*!< Reserved, 0x4A */ + __IO uint16_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x4C */ + uint16_t RESERVED13; /*!< Reserved, 0x4E */ + __IO uint16_t OR; /*!< TIM option register, Address offset: 0x50 */ + uint16_t RESERVED14; /*!< Reserved, 0x52 */ +} TIM_TypeDef; + +/** + * @brief Universal Synchronous Asynchronous Receiver Transmitter + */ + +typedef struct +{ + __IO uint16_t SR; /*!< USART Status register, Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t DR; /*!< USART Data register, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t BRR; /*!< USART Baud rate register, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t CR1; /*!< USART Control register 1, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t CR2; /*!< USART Control register 2, Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t CR3; /*!< USART Control register 3, Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ +} USART_TypeDef; + +/** + * @brief Window WATCHDOG + */ + +typedef struct +{ + __IO uint32_t CR; /*!< WWDG Control register, Address offset: 0x00 */ + __IO uint32_t CFR; /*!< WWDG Configuration register, Address offset: 0x04 */ + __IO uint32_t SR; /*!< WWDG Status register, Address offset: 0x08 */ +} WWDG_TypeDef; + +/** + * @brief Crypto Processor + */ + +typedef struct +{ + __IO uint32_t CR; /*!< CRYP control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< CRYP status register, Address offset: 0x04 */ + __IO uint32_t DR; /*!< CRYP data input register, Address offset: 0x08 */ + __IO uint32_t DOUT; /*!< CRYP data output register, Address offset: 0x0C */ + __IO uint32_t DMACR; /*!< CRYP DMA control register, Address offset: 0x10 */ + __IO uint32_t IMSCR; /*!< CRYP interrupt mask set/clear register, Address offset: 0x14 */ + __IO uint32_t RISR; /*!< CRYP raw interrupt status register, Address offset: 0x18 */ + __IO uint32_t MISR; /*!< CRYP masked interrupt status register, Address offset: 0x1C */ + __IO uint32_t K0LR; /*!< CRYP key left register 0, Address offset: 0x20 */ + __IO uint32_t K0RR; /*!< CRYP key right register 0, Address offset: 0x24 */ + __IO uint32_t K1LR; /*!< CRYP key left register 1, Address offset: 0x28 */ + __IO uint32_t K1RR; /*!< CRYP key right register 1, Address offset: 0x2C */ + __IO uint32_t K2LR; /*!< CRYP key left register 2, Address offset: 0x30 */ + __IO uint32_t K2RR; /*!< CRYP key right register 2, Address offset: 0x34 */ + __IO uint32_t K3LR; /*!< CRYP key left register 3, Address offset: 0x38 */ + __IO uint32_t K3RR; /*!< CRYP key right register 3, Address offset: 0x3C */ + __IO uint32_t IV0LR; /*!< CRYP initialization vector left-word register 0, Address offset: 0x40 */ + __IO uint32_t IV0RR; /*!< CRYP initialization vector right-word register 0, Address offset: 0x44 */ + __IO uint32_t IV1LR; /*!< CRYP initialization vector left-word register 1, Address offset: 0x48 */ + __IO uint32_t IV1RR; /*!< CRYP initialization vector right-word register 1, Address offset: 0x4C */ +} CRYP_TypeDef; + +/** + * @brief HASH + */ + +typedef struct +{ + __IO uint32_t CR; /*!< HASH control register, Address offset: 0x00 */ + __IO uint32_t DIN; /*!< HASH data input register, Address offset: 0x04 */ + __IO uint32_t STR; /*!< HASH start register, Address offset: 0x08 */ + __IO uint32_t HR[5]; /*!< HASH digest registers, Address offset: 0x0C-0x1C */ + __IO uint32_t IMR; /*!< HASH interrupt enable register, Address offset: 0x20 */ + __IO uint32_t SR; /*!< HASH status register, Address offset: 0x24 */ + uint32_t RESERVED[52]; /*!< Reserved, 0x28-0xF4 */ + __IO uint32_t CSR[51]; /*!< HASH context swap registers, Address offset: 0x0F8-0x1C0 */ +} HASH_TypeDef; + +/** + * @brief HASH + */ + +typedef struct +{ + __IO uint32_t CR; /*!< RNG control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< RNG status register, Address offset: 0x04 */ + __IO uint32_t DR; /*!< RNG data register, Address offset: 0x08 */ +} RNG_TypeDef; + +/** + * @} + */ + +/** @addtogroup Peripheral_memory_map + * @{ + */ +#define FLASH_BASE ((uint32_t)0x08000000) /*!< FLASH(up to 1 MB) base address in the alias region */ +#define CCMDATARAM_BASE ((uint32_t)0x10000000) /*!< CCM(core coupled memory) data RAM(64 KB) base address in the alias region */ +#define SRAM1_BASE ((uint32_t)0x20000000) /*!< SRAM1(112 KB) base address in the alias region */ +#define SRAM2_BASE ((uint32_t)0x2001C000) /*!< SRAM2(16 KB) base address in the alias region */ +#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */ +#define BKPSRAM_BASE ((uint32_t)0x40024000) /*!< Backup SRAM(4 KB) base address in the alias region */ +#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address */ + +#define CCMDATARAM_BB_BASE ((uint32_t)0x12000000) /*!< CCM(core coupled memory) data RAM(64 KB) base address in the bit-band region */ +#define SRAM1_BB_BASE ((uint32_t)0x22000000) /*!< SRAM1(112 KB) base address in the bit-band region */ +#define SRAM2_BB_BASE ((uint32_t)0x2201C000) /*!< SRAM2(16 KB) base address in the bit-band region */ +#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the bit-band region */ +#define BKPSRAM_BB_BASE ((uint32_t)0x42024000) /*!< Backup SRAM(4 KB) base address in the bit-band region */ + +/* Legacy defines */ +#define SRAM_BASE SRAM1_BASE +#define SRAM_BB_BASE SRAM1_BB_BASE + + +/*!< Peripheral memory map */ +#define APB1PERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000) +#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000) +#define AHB2PERIPH_BASE (PERIPH_BASE + 0x10000000) + +/*!< APB1 peripherals */ +#define TIM2_BASE (APB1PERIPH_BASE + 0x0000) +#define TIM3_BASE (APB1PERIPH_BASE + 0x0400) +#define TIM4_BASE (APB1PERIPH_BASE + 0x0800) +#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00) +#define TIM6_BASE (APB1PERIPH_BASE + 0x1000) +#define TIM7_BASE (APB1PERIPH_BASE + 0x1400) +#define TIM12_BASE (APB1PERIPH_BASE + 0x1800) +#define TIM13_BASE (APB1PERIPH_BASE + 0x1C00) +#define TIM14_BASE (APB1PERIPH_BASE + 0x2000) +#define RTC_BASE (APB1PERIPH_BASE + 0x2800) +#define WWDG_BASE (APB1PERIPH_BASE + 0x2C00) +#define IWDG_BASE (APB1PERIPH_BASE + 0x3000) +#define I2S2ext_BASE (APB1PERIPH_BASE + 0x3400) +#define SPI2_BASE (APB1PERIPH_BASE + 0x3800) +#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00) +#define I2S3ext_BASE (APB1PERIPH_BASE + 0x4000) +#define USART2_BASE (APB1PERIPH_BASE + 0x4400) +#define USART3_BASE (APB1PERIPH_BASE + 0x4800) +#define UART4_BASE (APB1PERIPH_BASE + 0x4C00) +#define UART5_BASE (APB1PERIPH_BASE + 0x5000) +#define I2C1_BASE (APB1PERIPH_BASE + 0x5400) +#define I2C2_BASE (APB1PERIPH_BASE + 0x5800) +#define I2C3_BASE (APB1PERIPH_BASE + 0x5C00) +#define CAN1_BASE (APB1PERIPH_BASE + 0x6400) +#define CAN2_BASE (APB1PERIPH_BASE + 0x6800) +#define PWR_BASE (APB1PERIPH_BASE + 0x7000) +#define DAC_BASE (APB1PERIPH_BASE + 0x7400) + +/*!< APB2 peripherals */ +#define TIM1_BASE (APB2PERIPH_BASE + 0x0000) +#define TIM8_BASE (APB2PERIPH_BASE + 0x0400) +#define USART1_BASE (APB2PERIPH_BASE + 0x1000) +#define USART6_BASE (APB2PERIPH_BASE + 0x1400) +#define ADC1_BASE (APB2PERIPH_BASE + 0x2000) +#define ADC2_BASE (APB2PERIPH_BASE + 0x2100) +#define ADC3_BASE (APB2PERIPH_BASE + 0x2200) +#define ADC_BASE (APB2PERIPH_BASE + 0x2300) +#define SDIO_BASE (APB2PERIPH_BASE + 0x2C00) +#define SPI1_BASE (APB2PERIPH_BASE + 0x3000) +#define SYSCFG_BASE (APB2PERIPH_BASE + 0x3800) +#define EXTI_BASE (APB2PERIPH_BASE + 0x3C00) +#define TIM9_BASE (APB2PERIPH_BASE + 0x4000) +#define TIM10_BASE (APB2PERIPH_BASE + 0x4400) +#define TIM11_BASE (APB2PERIPH_BASE + 0x4800) + +/*!< AHB1 peripherals */ +#define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000) +#define GPIOB_BASE (AHB1PERIPH_BASE + 0x0400) +#define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800) +#define GPIOD_BASE (AHB1PERIPH_BASE + 0x0C00) +#define GPIOE_BASE (AHB1PERIPH_BASE + 0x1000) +#define GPIOF_BASE (AHB1PERIPH_BASE + 0x1400) +#define GPIOG_BASE (AHB1PERIPH_BASE + 0x1800) +#define GPIOH_BASE (AHB1PERIPH_BASE + 0x1C00) +#define GPIOI_BASE (AHB1PERIPH_BASE + 0x2000) +#define CRC_BASE (AHB1PERIPH_BASE + 0x3000) +#define RCC_BASE (AHB1PERIPH_BASE + 0x3800) +#define FLASH_R_BASE (AHB1PERIPH_BASE + 0x3C00) +#define DMA1_BASE (AHB1PERIPH_BASE + 0x6000) +#define DMA1_Stream0_BASE (DMA1_BASE + 0x010) +#define DMA1_Stream1_BASE (DMA1_BASE + 0x028) +#define DMA1_Stream2_BASE (DMA1_BASE + 0x040) +#define DMA1_Stream3_BASE (DMA1_BASE + 0x058) +#define DMA1_Stream4_BASE (DMA1_BASE + 0x070) +#define DMA1_Stream5_BASE (DMA1_BASE + 0x088) +#define DMA1_Stream6_BASE (DMA1_BASE + 0x0A0) +#define DMA1_Stream7_BASE (DMA1_BASE + 0x0B8) +#define DMA2_BASE (AHB1PERIPH_BASE + 0x6400) +#define DMA2_Stream0_BASE (DMA2_BASE + 0x010) +#define DMA2_Stream1_BASE (DMA2_BASE + 0x028) +#define DMA2_Stream2_BASE (DMA2_BASE + 0x040) +#define DMA2_Stream3_BASE (DMA2_BASE + 0x058) +#define DMA2_Stream4_BASE (DMA2_BASE + 0x070) +#define DMA2_Stream5_BASE (DMA2_BASE + 0x088) +#define DMA2_Stream6_BASE (DMA2_BASE + 0x0A0) +#define DMA2_Stream7_BASE (DMA2_BASE + 0x0B8) +#define ETH_BASE (AHB1PERIPH_BASE + 0x8000) +#define ETH_MAC_BASE (ETH_BASE) +#define ETH_MMC_BASE (ETH_BASE + 0x0100) +#define ETH_PTP_BASE (ETH_BASE + 0x0700) +#define ETH_DMA_BASE (ETH_BASE + 0x1000) + +/*!< AHB2 peripherals */ +#define DCMI_BASE (AHB2PERIPH_BASE + 0x50000) +#define CRYP_BASE (AHB2PERIPH_BASE + 0x60000) +#define HASH_BASE (AHB2PERIPH_BASE + 0x60400) +#define RNG_BASE (AHB2PERIPH_BASE + 0x60800) + +/*!< FSMC Bankx registers base address */ +#define FSMC_Bank1_R_BASE (FSMC_R_BASE + 0x0000) +#define FSMC_Bank1E_R_BASE (FSMC_R_BASE + 0x0104) +#define FSMC_Bank2_R_BASE (FSMC_R_BASE + 0x0060) +#define FSMC_Bank3_R_BASE (FSMC_R_BASE + 0x0080) +#define FSMC_Bank4_R_BASE (FSMC_R_BASE + 0x00A0) + +/* Debug MCU registers base address */ +#define DBGMCU_BASE ((uint32_t )0xE0042000) + +/** + * @} + */ + +/** @addtogroup Peripheral_declaration + * @{ + */ +#define TIM2 ((TIM_TypeDef *) TIM2_BASE) +#define TIM3 ((TIM_TypeDef *) TIM3_BASE) +#define TIM4 ((TIM_TypeDef *) TIM4_BASE) +#define TIM5 ((TIM_TypeDef *) TIM5_BASE) +#define TIM6 ((TIM_TypeDef *) TIM6_BASE) +#define TIM7 ((TIM_TypeDef *) TIM7_BASE) +#define TIM12 ((TIM_TypeDef *) TIM12_BASE) +#define TIM13 ((TIM_TypeDef *) TIM13_BASE) +#define TIM14 ((TIM_TypeDef *) TIM14_BASE) +#define RTC ((RTC_TypeDef *) RTC_BASE) +#define WWDG ((WWDG_TypeDef *) WWDG_BASE) +#define IWDG ((IWDG_TypeDef *) IWDG_BASE) +#define I2S2ext ((SPI_TypeDef *) I2S2ext_BASE) +#define SPI2 ((SPI_TypeDef *) SPI2_BASE) +#define SPI3 ((SPI_TypeDef *) SPI3_BASE) +#define I2S3ext ((SPI_TypeDef *) I2S3ext_BASE) +#define USART2 ((USART_TypeDef *) USART2_BASE) +#define USART3 ((USART_TypeDef *) USART3_BASE) +#define UART4 ((USART_TypeDef *) UART4_BASE) +#define UART5 ((USART_TypeDef *) UART5_BASE) +#define I2C1 ((I2C_TypeDef *) I2C1_BASE) +#define I2C2 ((I2C_TypeDef *) I2C2_BASE) +#define I2C3 ((I2C_TypeDef *) I2C3_BASE) +#define CAN1 ((CAN_TypeDef *) CAN1_BASE) +#define CAN2 ((CAN_TypeDef *) CAN2_BASE) +#define PWR ((PWR_TypeDef *) PWR_BASE) +#define DAC ((DAC_TypeDef *) DAC_BASE) +#define TIM1 ((TIM_TypeDef *) TIM1_BASE) +#define TIM8 ((TIM_TypeDef *) TIM8_BASE) +#define USART1 ((USART_TypeDef *) USART1_BASE) +#define USART6 ((USART_TypeDef *) USART6_BASE) +#define ADC ((ADC_Common_TypeDef *) ADC_BASE) +#define ADC1 ((ADC_TypeDef *) ADC1_BASE) +#define ADC2 ((ADC_TypeDef *) ADC2_BASE) +#define ADC3 ((ADC_TypeDef *) ADC3_BASE) +#define SDIO ((SDIO_TypeDef *) SDIO_BASE) +#define SPI1 ((SPI_TypeDef *) SPI1_BASE) +#define SYSCFG ((SYSCFG_TypeDef *) SYSCFG_BASE) +#define EXTI ((EXTI_TypeDef *) EXTI_BASE) +#define TIM9 ((TIM_TypeDef *) TIM9_BASE) +#define TIM10 ((TIM_TypeDef *) TIM10_BASE) +#define TIM11 ((TIM_TypeDef *) TIM11_BASE) +#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) +#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) +#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) +#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) +#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) +#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) +#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE) +#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE) +#define GPIOI ((GPIO_TypeDef *) GPIOI_BASE) +#define CRC ((CRC_TypeDef *) CRC_BASE) +#define RCC ((RCC_TypeDef *) RCC_BASE) +#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) +#define DMA1 ((DMA_TypeDef *) DMA1_BASE) +#define DMA1_Stream0 ((DMA_Stream_TypeDef *) DMA1_Stream0_BASE) +#define DMA1_Stream1 ((DMA_Stream_TypeDef *) DMA1_Stream1_BASE) +#define DMA1_Stream2 ((DMA_Stream_TypeDef *) DMA1_Stream2_BASE) +#define DMA1_Stream3 ((DMA_Stream_TypeDef *) DMA1_Stream3_BASE) +#define DMA1_Stream4 ((DMA_Stream_TypeDef *) DMA1_Stream4_BASE) +#define DMA1_Stream5 ((DMA_Stream_TypeDef *) DMA1_Stream5_BASE) +#define DMA1_Stream6 ((DMA_Stream_TypeDef *) DMA1_Stream6_BASE) +#define DMA1_Stream7 ((DMA_Stream_TypeDef *) DMA1_Stream7_BASE) +#define DMA2 ((DMA_TypeDef *) DMA2_BASE) +#define DMA2_Stream0 ((DMA_Stream_TypeDef *) DMA2_Stream0_BASE) +#define DMA2_Stream1 ((DMA_Stream_TypeDef *) DMA2_Stream1_BASE) +#define DMA2_Stream2 ((DMA_Stream_TypeDef *) DMA2_Stream2_BASE) +#define DMA2_Stream3 ((DMA_Stream_TypeDef *) DMA2_Stream3_BASE) +#define DMA2_Stream4 ((DMA_Stream_TypeDef *) DMA2_Stream4_BASE) +#define DMA2_Stream5 ((DMA_Stream_TypeDef *) DMA2_Stream5_BASE) +#define DMA2_Stream6 ((DMA_Stream_TypeDef *) DMA2_Stream6_BASE) +#define DMA2_Stream7 ((DMA_Stream_TypeDef *) DMA2_Stream7_BASE) +#define ETH ((ETH_TypeDef *) ETH_BASE) +#define DCMI ((DCMI_TypeDef *) DCMI_BASE) +#define CRYP ((CRYP_TypeDef *) CRYP_BASE) +#define HASH ((HASH_TypeDef *) HASH_BASE) +#define RNG ((RNG_TypeDef *) RNG_BASE) +#define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE) +#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE) +#define FSMC_Bank2 ((FSMC_Bank2_TypeDef *) FSMC_Bank2_R_BASE) +#define FSMC_Bank3 ((FSMC_Bank3_TypeDef *) FSMC_Bank3_R_BASE) +#define FSMC_Bank4 ((FSMC_Bank4_TypeDef *) FSMC_Bank4_R_BASE) +#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) + +/** + * @} + */ + +/** @addtogroup Exported_constants + * @{ + */ + + /** @addtogroup Peripheral_Registers_Bits_Definition + * @{ + */ + +/******************************************************************************/ +/* Peripheral Registers_Bits_Definition */ +/******************************************************************************/ + +/******************************************************************************/ +/* */ +/* Analog to Digital Converter */ +/* */ +/******************************************************************************/ +/******************** Bit definition for ADC_SR register ********************/ +#define ADC_SR_AWD ((uint8_t)0x01) /*! Date: Thu, 3 Nov 2011 18:02:48 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3462 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/hal_lld.h | 503 +------------------------ os/hal/platforms/STM32F1xx/hal_lld_f100.h | 185 ++++++++- os/hal/platforms/STM32F1xx/hal_lld_f103.h | 340 ++++++++++++++++- os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h | 107 +++++- os/hal/platforms/STM32F4xx/hal_lld.h | 86 +++-- os/hal/platforms/STM32L1xx/hal_lld.h | 59 ++- 6 files changed, 741 insertions(+), 539 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/hal_lld.h b/os/hal/platforms/STM32F1xx/hal_lld.h index da9e610fd..9b87b0a85 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld.h +++ b/os/hal/platforms/STM32F1xx/hal_lld.h @@ -55,509 +55,26 @@ /* Derived constants and error checks. */ /*===========================================================================*/ +#if defined(__DOXYGEN__) /** - * @brief Platform name. + * @name Platform identification + * @{ */ -#if defined(__DOXYGEN__) #define PLATFORM_NAME "STM32" +/** @} */ -#elif defined(STM32F10X_LD_VL) -/* - * Capability flags for Value Line Low Density devices. - */ -#define PLATFORM_NAME "STM32 Value Line Low Density" -#include "hal_lld_f100.h" - -#define STM32_HAS_ADC1 TRUE -#define STM32_HAS_ADC2 FALSE -#define STM32_HAS_ADC3 FALSE - -#define STM32_HAS_CAN1 FALSE -#define STM32_HAS_CAN2 FALSE - -#define STM32_HAS_DAC TRUE - -#define STM32_HAS_DMA1 TRUE -#define STM32_HAS_DMA2 FALSE - -#define STM32_HAS_ETH FALSE - -#define STM32_EXTI_NUM_CHANNELS 19 - -#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 FALSE -#define STM32_HAS_GPIOG FALSE -#define STM32_HAS_GPIOH FALSE - -#define STM32_HAS_I2C1 TRUE -#define STM32_HAS_I2C2 FALSE - -#define STM32_HAS_RTC TRUE - -#define STM32_HAS_SDIO FALSE - -#define STM32_HAS_SPI1 TRUE -#define STM32_HAS_SPI2 FALSE -#define STM32_HAS_SPI3 FALSE - -#define STM32_HAS_TIM1 TRUE -#define STM32_HAS_TIM2 TRUE -#define STM32_HAS_TIM3 TRUE -#define STM32_HAS_TIM4 FALSE -#define STM32_HAS_TIM5 FALSE -#define STM32_HAS_TIM6 TRUE -#define STM32_HAS_TIM7 TRUE -#define STM32_HAS_TIM8 FALSE -#define STM32_HAS_TIM9 FALSE -#define STM32_HAS_TIM10 FALSE -#define STM32_HAS_TIM11 FALSE -#define STM32_HAS_TIM12 FALSE -#define STM32_HAS_TIM13 FALSE -#define STM32_HAS_TIM14 FALSE -#define STM32_HAS_TIM15 TRUE -#define STM32_HAS_TIM16 TRUE -#define STM32_HAS_TIM17 TRUE - -#define STM32_HAS_USART1 TRUE -#define STM32_HAS_USART2 TRUE -#define STM32_HAS_USART3 FALSE -#define STM32_HAS_UART4 FALSE -#define STM32_HAS_UART5 FALSE -#define STM32_HAS_USART6 FALSE - -#define STM32_HAS_USB FALSE -#define STM32_HAS_OTG1 FALSE - -#elif defined(STM32F10X_MD_VL) -/* - * Capability flags for Value Line Medium Density devices. - */ -#define PLATFORM_NAME "STM32 Value Line Medium Density" +#elif defined(STM32F10X_LD_VL) || defined(STM32F10X_MD_VL) || \ + defined(STM32F10X_HD_VL) || defined(__DOXYGEN__) #include "hal_lld_f100.h" -#define STM32_HAS_ADC1 TRUE -#define STM32_HAS_ADC2 FALSE -#define STM32_HAS_ADC3 FALSE - -#define STM32_HAS_CAN1 FALSE -#define STM32_HAS_CAN2 FALSE - -#define STM32_HAS_DAC TRUE - -#define STM32_HAS_DMA1 TRUE -#define STM32_HAS_DMA2 FALSE - -#define STM32_HAS_ETH FALSE - -#define STM32_EXTI_NUM_CHANNELS 19 - -#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 FALSE -#define STM32_HAS_GPIOG FALSE -#define STM32_HAS_GPIOH FALSE - -#define STM32_HAS_I2C1 TRUE -#define STM32_HAS_I2C2 TRUE - -#define STM32_HAS_RTC TRUE - -#define STM32_HAS_SDIO FALSE - -#define STM32_HAS_SPI1 TRUE -#define STM32_HAS_SPI2 TRUE -#define STM32_HAS_SPI3 FALSE - -#define STM32_HAS_TIM1 TRUE -#define STM32_HAS_TIM2 TRUE -#define STM32_HAS_TIM3 TRUE -#define STM32_HAS_TIM4 TRUE -#define STM32_HAS_TIM5 FALSE -#define STM32_HAS_TIM6 TRUE -#define STM32_HAS_TIM7 TRUE -#define STM32_HAS_TIM8 FALSE -#define STM32_HAS_TIM9 FALSE -#define STM32_HAS_TIM10 FALSE -#define STM32_HAS_TIM11 FALSE -#define STM32_HAS_TIM12 FALSE -#define STM32_HAS_TIM13 FALSE -#define STM32_HAS_TIM14 FALSE -#define STM32_HAS_TIM15 TRUE -#define STM32_HAS_TIM16 TRUE -#define STM32_HAS_TIM17 TRUE - -#define STM32_HAS_USART1 TRUE -#define STM32_HAS_USART2 TRUE -#define STM32_HAS_USART3 TRUE -#define STM32_HAS_UART4 FALSE -#define STM32_HAS_UART5 FALSE -#define STM32_HAS_USART6 FALSE - -#define STM32_HAS_USB FALSE -#define STM32_HAS_OTG1 FALSE - -#elif defined(STM32F10X_LD) -/* - * Capability flags for Performance Line Low Density devices. - */ -#define PLATFORM_NAME "STM32 Performance Line Low Density" -#include "hal_lld_f103.h" - -#define STM32_HAS_ADC1 TRUE -#define STM32_HAS_ADC2 TRUE -#define STM32_HAS_ADC3 FALSE - -#define STM32_HAS_CAN1 TRUE -#define STM32_HAS_CAN2 FALSE - -#define STM32_HAS_DAC FALSE - -#define STM32_HAS_DMA1 TRUE -#define STM32_HAS_DMA2 FALSE - -#define STM32_HAS_ETH FALSE - -#define STM32_EXTI_NUM_CHANNELS 19 - -#define STM32_HAS_GPIOA TRUE -#define STM32_HAS_GPIOB TRUE -#define STM32_HAS_GPIOC TRUE -#define STM32_HAS_GPIOD TRUE -#define STM32_HAS_GPIOE FALSE -#define STM32_HAS_GPIOF FALSE -#define STM32_HAS_GPIOG FALSE -#define STM32_HAS_GPIOH FALSE - -#define STM32_HAS_I2C1 TRUE -#define STM32_HAS_I2C2 FALSE - -#define STM32_HAS_RTC TRUE - -#define STM32_HAS_SDIO FALSE - -#define STM32_HAS_SPI1 TRUE -#define STM32_HAS_SPI2 FALSE -#define STM32_HAS_SPI3 FALSE - -#define STM32_HAS_TIM1 TRUE -#define STM32_HAS_TIM2 TRUE -#define STM32_HAS_TIM3 TRUE -#define STM32_HAS_TIM4 FALSE -#define STM32_HAS_TIM5 FALSE -#define STM32_HAS_TIM6 FALSE -#define STM32_HAS_TIM7 FALSE -#define STM32_HAS_TIM8 FALSE -#define STM32_HAS_TIM9 FALSE -#define STM32_HAS_TIM10 FALSE -#define STM32_HAS_TIM11 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_USART1 TRUE -#define STM32_HAS_USART2 TRUE -#define STM32_HAS_USART3 FALSE -#define STM32_HAS_UART4 FALSE -#define STM32_HAS_UART5 FALSE -#define STM32_HAS_USART6 FALSE - -#define STM32_HAS_USB FALSE -#define STM32_HAS_OTG1 FALSE - -#elif defined(STM32F10X_MD) -/* - * Capability flags for Performance Line Medium Density devices. - */ -#define PLATFORM_NAME "STM32 Performance Line Medium Density" -#include "hal_lld_f103.h" - -#define STM32_HAS_ADC1 TRUE -#define STM32_HAS_ADC2 TRUE -#define STM32_HAS_ADC3 FALSE - -#define STM32_HAS_CAN1 TRUE -#define STM32_HAS_CAN2 FALSE - -#define STM32_HAS_DAC FALSE - -#define STM32_HAS_DMA1 TRUE -#define STM32_HAS_DMA2 FALSE - -#define STM32_HAS_ETH FALSE - -#define STM32_EXTI_NUM_CHANNELS 19 - -#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 FALSE -#define STM32_HAS_GPIOG FALSE -#define STM32_HAS_GPIOH FALSE - -#define STM32_HAS_I2C1 TRUE -#define STM32_HAS_I2C2 TRUE - -#define STM32_HAS_RTC TRUE - -#define STM32_HAS_SDIO FALSE - -#define STM32_HAS_SPI1 TRUE -#define STM32_HAS_SPI2 TRUE -#define STM32_HAS_SPI3 FALSE - -#define STM32_HAS_TIM1 TRUE -#define STM32_HAS_TIM2 TRUE -#define STM32_HAS_TIM3 TRUE -#define STM32_HAS_TIM4 TRUE -#define STM32_HAS_TIM5 FALSE -#define STM32_HAS_TIM6 FALSE -#define STM32_HAS_TIM7 FALSE -#define STM32_HAS_TIM8 FALSE -#define STM32_HAS_TIM9 FALSE -#define STM32_HAS_TIM10 FALSE -#define STM32_HAS_TIM11 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_USART1 TRUE -#define STM32_HAS_USART2 TRUE -#define STM32_HAS_USART3 TRUE -#define STM32_HAS_UART4 FALSE -#define STM32_HAS_UART5 FALSE -#define STM32_HAS_USART6 FALSE - -#define STM32_HAS_USB TRUE -#define STM32_HAS_OTG1 FALSE - -#elif defined(STM32F10X_HD) -/* - * Capability flags for Performance Line High Density devices. - */ -#define PLATFORM_NAME "STM32 Performance Line High Density" -#include "hal_lld_f103.h" - -#define STM32_HAS_ADC1 TRUE -#define STM32_HAS_ADC2 TRUE -#define STM32_HAS_ADC3 TRUE - -#define STM32_HAS_CAN1 TRUE -#define STM32_HAS_CAN2 FALSE - -#define STM32_HAS_DAC TRUE - -#define STM32_HAS_DMA1 TRUE -#define STM32_HAS_DMA2 TRUE - -#define STM32_HAS_ETH FALSE - -#define STM32_EXTI_NUM_CHANNELS 19 - -#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 FALSE - -#define STM32_HAS_I2C1 TRUE -#define STM32_HAS_I2C2 TRUE - -#define STM32_HAS_RTC TRUE - -#define STM32_HAS_SDIO TRUE - -#define STM32_HAS_SPI1 TRUE -#define STM32_HAS_SPI2 TRUE -#define STM32_HAS_SPI3 TRUE - -#define STM32_HAS_TIM1 TRUE -#define STM32_HAS_TIM2 TRUE -#define STM32_HAS_TIM3 TRUE -#define STM32_HAS_TIM4 TRUE -#define STM32_HAS_TIM5 TRUE -#define STM32_HAS_TIM6 TRUE -#define STM32_HAS_TIM7 TRUE -#define STM32_HAS_TIM8 TRUE -#define STM32_HAS_TIM9 TRUE -#define STM32_HAS_TIM10 TRUE -#define STM32_HAS_TIM11 TRUE -#define STM32_HAS_TIM12 TRUE -#define STM32_HAS_TIM13 TRUE -#define STM32_HAS_TIM14 TRUE -#define STM32_HAS_TIM15 FALSE -#define STM32_HAS_TIM16 FALSE -#define STM32_HAS_TIM17 FALSE - -#define STM32_HAS_USART1 TRUE -#define STM32_HAS_USART2 TRUE -#define STM32_HAS_USART3 TRUE -#define STM32_HAS_UART4 TRUE -#define STM32_HAS_UART5 TRUE -#define STM32_HAS_USART6 FALSE - -#define STM32_HAS_USB TRUE -#define STM32_HAS_OTG1 FALSE - -#elif defined(STM32F10X_XL) -/* - * Capability flags for Performance Line eXtra Density devices. - */ -#define PLATFORM_NAME "STM32 Performance Line eXtra Density" +#elif defined(STM32F10X_LD) || defined(STM32F10X_MD) || \ + defined(STM32F10X_HD) || defined(STM32F10X_XL) || \ + defined(__DOXYGEN__) #include "hal_lld_f103.h" -#define STM32_HAS_ADC1 TRUE -#define STM32_HAS_ADC2 TRUE -#define STM32_HAS_ADC3 TRUE - -#define STM32_HAS_CAN1 TRUE -#define STM32_HAS_CAN2 FALSE - -#define STM32_HAS_DAC TRUE - -#define STM32_HAS_DMA1 TRUE -#define STM32_HAS_DMA2 TRUE - -#define STM32_HAS_ETH FALSE - -#define STM32_EXTI_NUM_CHANNELS 19 - -#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 FALSE - -#define STM32_HAS_I2C1 TRUE -#define STM32_HAS_I2C2 TRUE - -#define STM32_HAS_RTC TRUE - -#define STM32_HAS_SDIO TRUE - -#define STM32_HAS_SPI1 TRUE -#define STM32_HAS_SPI2 TRUE -#define STM32_HAS_SPI3 TRUE - -#define STM32_HAS_TIM1 TRUE -#define STM32_HAS_TIM2 TRUE -#define STM32_HAS_TIM3 TRUE -#define STM32_HAS_TIM4 TRUE -#define STM32_HAS_TIM5 TRUE -#define STM32_HAS_TIM6 TRUE -#define STM32_HAS_TIM7 TRUE -#define STM32_HAS_TIM8 TRUE -#define STM32_HAS_TIM9 FALSE -#define STM32_HAS_TIM10 FALSE -#define STM32_HAS_TIM11 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_USART1 TRUE -#define STM32_HAS_USART2 TRUE -#define STM32_HAS_USART3 TRUE -#define STM32_HAS_UART4 TRUE -#define STM32_HAS_UART5 TRUE -#define STM32_HAS_USART6 FALSE - -#define STM32_HAS_USB TRUE -#define STM32_HAS_OTG1 FALSE - -#elif defined(STM32F10X_CL) -/* - * Capability flags for Connectivity Line devices. - */ -#define PLATFORM_NAME "STM32 Connectivity Line" +#elif defined(STM32F10X_CL) || defined(__DOXYGEN__) #include "hal_lld_f105_f107.h" -#define STM32_HAS_ADC1 TRUE -#define STM32_HAS_ADC2 TRUE -#define STM32_HAS_ADC3 FALSE - -#define STM32_HAS_CAN1 TRUE -#define STM32_HAS_CAN2 TRUE - -#define STM32_HAS_DAC TRUE - -#define STM32_HAS_DMA1 TRUE -#define STM32_HAS_DMA2 TRUE - -#define STM32_HAS_ETH TRUE - -#define STM32_EXTI_NUM_CHANNELS 20 - -#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 FALSE -#define STM32_HAS_GPIOG FALSE -#define STM32_HAS_GPIOH FALSE - -#define STM32_HAS_I2C1 TRUE -#define STM32_HAS_I2C2 TRUE - -#define STM32_HAS_RTC TRUE - -#define STM32_HAS_SDIO FALSE - -#define STM32_HAS_SPI1 TRUE -#define STM32_HAS_SPI2 TRUE -#define STM32_HAS_SPI3 TRUE - -#define STM32_HAS_TIM1 TRUE -#define STM32_HAS_TIM2 TRUE -#define STM32_HAS_TIM3 TRUE -#define STM32_HAS_TIM4 TRUE -#define STM32_HAS_TIM5 TRUE -#define STM32_HAS_TIM6 TRUE -#define STM32_HAS_TIM7 TRUE -#define STM32_HAS_TIM8 FALSE -#define STM32_HAS_TIM9 FALSE -#define STM32_HAS_TIM10 FALSE -#define STM32_HAS_TIM11 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_USART1 TRUE -#define STM32_HAS_USART2 TRUE -#define STM32_HAS_USART3 TRUE -#define STM32_HAS_UART4 TRUE -#define STM32_HAS_UART5 TRUE -#define STM32_HAS_USART6 FALSE - -#define STM32_HAS_USB FALSE -#define STM32_HAS_OTG1 TRUE - #else #error "unspecified, unsupported or invalid STM32 platform" #endif diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f100.h b/os/hal/platforms/STM32F1xx/hal_lld_f100.h index 012cf0c11..864be581e 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f100.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f100.h @@ -40,10 +40,35 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @name Platform identification + * @{ + */ +#if defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32 Value Line" + +#elif defined(STM32F10X_LD_VL) +#define PLATFORM_NAME "STM32 Value Line Low Density" + +#elif defined(STM32F10X_MD_VL) +#define PLATFORM_NAME "STM32 Value Line Medium Density" +#else +#error "unsupported STM32 Value Line member" +#endif +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ #define STM32_HSICLK 8000000 /**< High speed internal clock. */ #define STM32_LSICLK 40000 /**< Low speed internal clock. */ +/** @} */ -/* RCC_CFGR register bits definitions.*/ +/** + * @name RCC_CFGR register bits definitions + * @{ + */ #define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ #define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ #define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ @@ -92,11 +117,168 @@ #define STM32_RTC_LSI (2 << 8) /**< LSI used as RTC clock. */ #define STM32_RTC_HSE (3 << 8) /**< HSE divided by 128 used as RTC clock. */ +/** @} */ + +/*===========================================================================*/ +/* Platform capabilities. */ +/*===========================================================================*/ + +#if defined(STM32F10X_LD_VL) || defined(__DOXYGEN__) +/** + * @name STM32F100 LD capabilities + * @{ + */ +#define STM32_HAS_ADC1 TRUE +#define STM32_HAS_ADC2 FALSE +#define STM32_HAS_ADC3 FALSE + +#define STM32_HAS_CAN1 FALSE +#define STM32_HAS_CAN2 FALSE + +#define STM32_HAS_DAC TRUE + +#define STM32_HAS_DMA1 TRUE +#define STM32_HAS_DMA2 FALSE + +#define STM32_HAS_ETH FALSE + +#define STM32_EXTI_NUM_CHANNELS 19 + +#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 FALSE +#define STM32_HAS_GPIOG FALSE +#define STM32_HAS_GPIOH FALSE +#define STM32_HAS_GPIOI FALSE + +#define STM32_HAS_I2C1 TRUE +#define STM32_HAS_I2C2 FALSE +#define STM32_HAS_I2C3 FALSE + +#define STM32_HAS_RTC TRUE + +#define STM32_HAS_SDIO FALSE + +#define STM32_HAS_SPI1 TRUE +#define STM32_HAS_SPI2 FALSE +#define STM32_HAS_SPI3 FALSE + +#define STM32_HAS_TIM1 TRUE +#define STM32_HAS_TIM2 TRUE +#define STM32_HAS_TIM3 TRUE +#define STM32_HAS_TIM4 FALSE +#define STM32_HAS_TIM5 FALSE +#define STM32_HAS_TIM6 TRUE +#define STM32_HAS_TIM7 TRUE +#define STM32_HAS_TIM8 FALSE +#define STM32_HAS_TIM9 FALSE +#define STM32_HAS_TIM10 FALSE +#define STM32_HAS_TIM11 FALSE +#define STM32_HAS_TIM12 FALSE +#define STM32_HAS_TIM13 FALSE +#define STM32_HAS_TIM14 FALSE +#define STM32_HAS_TIM15 TRUE +#define STM32_HAS_TIM16 TRUE +#define STM32_HAS_TIM17 TRUE + +#define STM32_HAS_USART1 TRUE +#define STM32_HAS_USART2 TRUE +#define STM32_HAS_USART3 FALSE +#define STM32_HAS_UART4 FALSE +#define STM32_HAS_UART5 FALSE +#define STM32_HAS_USART6 FALSE + +#define STM32_HAS_USB FALSE +#define STM32_HAS_OTG1 FALSE +#define STM32_HAS_OTG2 FALSE +/** @} */ +#endif /* defined(STM32F10X_LD_VL) */ + +#if defined(STM32F10X_MD_VL) || defined(__DOXYGEN__) +/** + * @name STM32F100 MD capabilities + * @{ + */ +#define STM32_HAS_ADC1 TRUE +#define STM32_HAS_ADC2 FALSE +#define STM32_HAS_ADC3 FALSE + +#define STM32_HAS_CAN1 FALSE +#define STM32_HAS_CAN2 FALSE + +#define STM32_HAS_DAC TRUE + +#define STM32_HAS_DMA1 TRUE +#define STM32_HAS_DMA2 FALSE + +#define STM32_HAS_ETH FALSE + +#define STM32_EXTI_NUM_CHANNELS 19 + +#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 FALSE +#define STM32_HAS_GPIOG FALSE +#define STM32_HAS_GPIOH FALSE +#define STM32_HAS_GPIOI FALSE + +#define STM32_HAS_I2C1 TRUE +#define STM32_HAS_I2C2 TRUE +#define STM32_HAS_I2C3 FALSE + +#define STM32_HAS_RTC TRUE + +#define STM32_HAS_SDIO FALSE + +#define STM32_HAS_SPI1 TRUE +#define STM32_HAS_SPI2 TRUE +#define STM32_HAS_SPI3 FALSE + +#define STM32_HAS_TIM1 TRUE +#define STM32_HAS_TIM2 TRUE +#define STM32_HAS_TIM3 TRUE +#define STM32_HAS_TIM4 TRUE +#define STM32_HAS_TIM5 FALSE +#define STM32_HAS_TIM6 TRUE +#define STM32_HAS_TIM7 TRUE +#define STM32_HAS_TIM8 FALSE +#define STM32_HAS_TIM9 FALSE +#define STM32_HAS_TIM10 FALSE +#define STM32_HAS_TIM11 FALSE +#define STM32_HAS_TIM12 FALSE +#define STM32_HAS_TIM13 FALSE +#define STM32_HAS_TIM14 FALSE +#define STM32_HAS_TIM15 TRUE +#define STM32_HAS_TIM16 TRUE +#define STM32_HAS_TIM17 TRUE + +#define STM32_HAS_USART1 TRUE +#define STM32_HAS_USART2 TRUE +#define STM32_HAS_USART3 TRUE +#define STM32_HAS_UART4 FALSE +#define STM32_HAS_UART5 FALSE +#define STM32_HAS_USART6 FALSE + +#define STM32_HAS_USB FALSE +#define STM32_HAS_OTG1 FALSE +#define STM32_HAS_OTG2 FALSE +/** @} */ +#endif /* defined(STM32F10X_MD_VL) */ /*===========================================================================*/ /* Platform specific friendly IRQ names. */ /*===========================================================================*/ +/** + * @name IRQ VECTOR names + * @{ + */ #define WWDG_IRQHandler Vector40 /**< Window Watchdog. */ #define PVD_IRQHandler Vector44 /**< PVD through EXTI Line detect. */ @@ -149,6 +331,7 @@ #define TIM12_IRQHandler VectorEC /**< TIM12. */ #define TIM13_IRQHandler VectorF0 /**< TIM13. */ #define TIM14_IRQHandler VectorF4 /**< TIM14. */ +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f103.h b/os/hal/platforms/STM32F1xx/hal_lld_f103.h index 7f493ee01..7c04b7d38 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f103.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f103.h @@ -40,10 +40,42 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @name Platform identification + * @{ + */ +#if defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32 Performance Line" + +#elif defined(STM32F10X_LD) +#define PLATFORM_NAME "STM32 Performance Line Low Density" + +#elif defined(STM32F10X_MD) +#define PLATFORM_NAME "STM32 Performance Line Medium Density" + +#elif defined(STM32F10X_HD) +#define PLATFORM_NAME "STM32 Performance Line High Density" + +#elif defined(STM32F10X_XL) +#define PLATFORM_NAME "STM32 Performance Line eXtra Density" + +#else +#error "unsupported STM32 Performance Line member" +#endif +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ #define STM32_HSICLK 8000000 /**< High speed internal clock. */ #define STM32_LSICLK 40000 /**< Low speed internal clock. */ +/** @} */ -/* RCC_CFGR register bits definitions.*/ +/** + * @name RCC_CFGR register bits definitions + * @{ + */ #define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ #define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ #define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ @@ -95,11 +127,316 @@ #define STM32_RTC_LSI (2 << 8) /**< LSI used as RTC clock. */ #define STM32_RTC_HSE (3 << 8) /**< HSE divided by 128 used as RTC clock. */ +/** @} */ + +/*===========================================================================*/ +/* Platform capabilities. */ +/*===========================================================================*/ + +#if defined(STM32F10X_LD) || defined(__DOXYGEN__) +/** + * @name STM32F103 LD capabilities + * @{ + */ +#define STM32_HAS_ADC1 TRUE +#define STM32_HAS_ADC2 TRUE +#define STM32_HAS_ADC3 FALSE + +#define STM32_HAS_CAN1 TRUE +#define STM32_HAS_CAN2 FALSE + +#define STM32_HAS_DAC FALSE + +#define STM32_HAS_DMA1 TRUE +#define STM32_HAS_DMA2 FALSE + +#define STM32_HAS_ETH FALSE + +#define STM32_EXTI_NUM_CHANNELS 19 + +#define STM32_HAS_GPIOA TRUE +#define STM32_HAS_GPIOB TRUE +#define STM32_HAS_GPIOC TRUE +#define STM32_HAS_GPIOD TRUE +#define STM32_HAS_GPIOE FALSE +#define STM32_HAS_GPIOF FALSE +#define STM32_HAS_GPIOG FALSE +#define STM32_HAS_GPIOH FALSE +#define STM32_HAS_GPIOI FALSE + +#define STM32_HAS_I2C1 TRUE +#define STM32_HAS_I2C2 FALSE +#define STM32_HAS_I2C3 FALSE + +#define STM32_HAS_RTC TRUE + +#define STM32_HAS_SDIO FALSE + +#define STM32_HAS_SPI1 TRUE +#define STM32_HAS_SPI2 FALSE +#define STM32_HAS_SPI3 FALSE + +#define STM32_HAS_TIM1 TRUE +#define STM32_HAS_TIM2 TRUE +#define STM32_HAS_TIM3 TRUE +#define STM32_HAS_TIM4 FALSE +#define STM32_HAS_TIM5 FALSE +#define STM32_HAS_TIM6 FALSE +#define STM32_HAS_TIM7 FALSE +#define STM32_HAS_TIM8 FALSE +#define STM32_HAS_TIM9 FALSE +#define STM32_HAS_TIM10 FALSE +#define STM32_HAS_TIM11 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_USART1 TRUE +#define STM32_HAS_USART2 TRUE +#define STM32_HAS_USART3 FALSE +#define STM32_HAS_UART4 FALSE +#define STM32_HAS_UART5 FALSE +#define STM32_HAS_USART6 FALSE + +#define STM32_HAS_USB FALSE +#define STM32_HAS_OTG1 FALSE +#define STM32_HAS_OTG2 FALSE +/** @} */ +#endif /* defined(STM32F10X_LD) */ + +#if defined(STM32F10X_MD) || defined(__DOXYGEN__) +/** + * @name STM32F103 MD capabilities + * @{ + */ +#define STM32_HAS_ADC1 TRUE +#define STM32_HAS_ADC2 TRUE +#define STM32_HAS_ADC3 FALSE + +#define STM32_HAS_CAN1 TRUE +#define STM32_HAS_CAN2 FALSE + +#define STM32_HAS_DAC FALSE + +#define STM32_HAS_DMA1 TRUE +#define STM32_HAS_DMA2 FALSE + +#define STM32_HAS_ETH FALSE + +#define STM32_EXTI_NUM_CHANNELS 19 + +#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 FALSE +#define STM32_HAS_GPIOG FALSE +#define STM32_HAS_GPIOH FALSE +#define STM32_HAS_GPIOI FALSE + +#define STM32_HAS_I2C1 TRUE +#define STM32_HAS_I2C2 TRUE +#define STM32_HAS_I2C3 FALSE + +#define STM32_HAS_RTC TRUE + +#define STM32_HAS_SDIO FALSE + +#define STM32_HAS_SPI1 TRUE +#define STM32_HAS_SPI2 TRUE +#define STM32_HAS_SPI3 FALSE + +#define STM32_HAS_TIM1 TRUE +#define STM32_HAS_TIM2 TRUE +#define STM32_HAS_TIM3 TRUE +#define STM32_HAS_TIM4 TRUE +#define STM32_HAS_TIM5 FALSE +#define STM32_HAS_TIM6 FALSE +#define STM32_HAS_TIM7 FALSE +#define STM32_HAS_TIM8 FALSE +#define STM32_HAS_TIM9 FALSE +#define STM32_HAS_TIM10 FALSE +#define STM32_HAS_TIM11 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_USART1 TRUE +#define STM32_HAS_USART2 TRUE +#define STM32_HAS_USART3 TRUE +#define STM32_HAS_UART4 FALSE +#define STM32_HAS_UART5 FALSE +#define STM32_HAS_USART6 FALSE + +#define STM32_HAS_USB TRUE +#define STM32_HAS_OTG1 FALSE +#define STM32_HAS_OTG2 FALSE +/** @} */ +#endif /* defined(STM32F10X_MD) */ + +#if defined(STM32F10X_HD) || defined(__DOXYGEN__) +/** + * @name STM32F103 HD capabilities + * @{ + */ +#define STM32_HAS_ADC1 TRUE +#define STM32_HAS_ADC2 TRUE +#define STM32_HAS_ADC3 TRUE + +#define STM32_HAS_CAN1 TRUE +#define STM32_HAS_CAN2 FALSE + +#define STM32_HAS_DAC TRUE + +#define STM32_HAS_DMA1 TRUE +#define STM32_HAS_DMA2 TRUE + +#define STM32_HAS_ETH FALSE + +#define STM32_EXTI_NUM_CHANNELS 19 + +#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 FALSE +#define STM32_HAS_GPIOI FALSE + +#define STM32_HAS_I2C1 TRUE +#define STM32_HAS_I2C2 TRUE +#define STM32_HAS_I2C3 FALSE + +#define STM32_HAS_RTC TRUE + +#define STM32_HAS_SDIO TRUE + +#define STM32_HAS_SPI1 TRUE +#define STM32_HAS_SPI2 TRUE +#define STM32_HAS_SPI3 TRUE + +#define STM32_HAS_TIM1 TRUE +#define STM32_HAS_TIM2 TRUE +#define STM32_HAS_TIM3 TRUE +#define STM32_HAS_TIM4 TRUE +#define STM32_HAS_TIM5 TRUE +#define STM32_HAS_TIM6 TRUE +#define STM32_HAS_TIM7 TRUE +#define STM32_HAS_TIM8 TRUE +#define STM32_HAS_TIM9 TRUE +#define STM32_HAS_TIM10 TRUE +#define STM32_HAS_TIM11 TRUE +#define STM32_HAS_TIM12 TRUE +#define STM32_HAS_TIM13 TRUE +#define STM32_HAS_TIM14 TRUE +#define STM32_HAS_TIM15 FALSE +#define STM32_HAS_TIM16 FALSE +#define STM32_HAS_TIM17 FALSE + +#define STM32_HAS_USART1 TRUE +#define STM32_HAS_USART2 TRUE +#define STM32_HAS_USART3 TRUE +#define STM32_HAS_UART4 TRUE +#define STM32_HAS_UART5 TRUE +#define STM32_HAS_USART6 FALSE + +#define STM32_HAS_USB TRUE +#define STM32_HAS_OTG1 FALSE +#define STM32_HAS_OTG2 FALSE +/** @} */ +#endif /* defined(STM32F10X_HD) */ + +#if defined(STM32F10X_XL) || defined(__DOXYGEN__) +/** + * @name STM32F103 XL capabilities + * @{ + */ +#define STM32_HAS_ADC1 TRUE +#define STM32_HAS_ADC2 TRUE +#define STM32_HAS_ADC3 TRUE + +#define STM32_HAS_CAN1 TRUE +#define STM32_HAS_CAN2 FALSE + +#define STM32_HAS_DAC TRUE + +#define STM32_HAS_DMA1 TRUE +#define STM32_HAS_DMA2 TRUE + +#define STM32_HAS_ETH FALSE + +#define STM32_EXTI_NUM_CHANNELS 19 + +#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 FALSE +#define STM32_HAS_GPIOI FALSE + +#define STM32_HAS_I2C1 TRUE +#define STM32_HAS_I2C2 TRUE +#define STM32_HAS_I2C3 FALSE + +#define STM32_HAS_RTC TRUE + +#define STM32_HAS_SDIO TRUE + +#define STM32_HAS_SPI1 TRUE +#define STM32_HAS_SPI2 TRUE +#define STM32_HAS_SPI3 TRUE + +#define STM32_HAS_TIM1 TRUE +#define STM32_HAS_TIM2 TRUE +#define STM32_HAS_TIM3 TRUE +#define STM32_HAS_TIM4 TRUE +#define STM32_HAS_TIM5 TRUE +#define STM32_HAS_TIM6 TRUE +#define STM32_HAS_TIM7 TRUE +#define STM32_HAS_TIM8 TRUE +#define STM32_HAS_TIM9 FALSE +#define STM32_HAS_TIM10 FALSE +#define STM32_HAS_TIM11 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_USART1 TRUE +#define STM32_HAS_USART2 TRUE +#define STM32_HAS_USART3 TRUE +#define STM32_HAS_UART4 TRUE +#define STM32_HAS_UART5 TRUE +#define STM32_HAS_USART6 FALSE + +#define STM32_HAS_USB TRUE +#define STM32_HAS_OTG1 FALSE +#define STM32_HAS_OTG2 FALSE +/** @} */ +#endif /* defined(STM32F10X_XL) */ /*===========================================================================*/ /* Platform specific friendly IRQ names. */ /*===========================================================================*/ +/** + * @name IRQ VECTOR names + * @{ + */ #define WWDG_IRQHandler Vector40 /**< Window Watchdog. */ #define PVD_IRQHandler Vector44 /**< PVD through EXTI Line detect. */ @@ -165,6 +502,7 @@ #define DMA2_Ch2_IRQHandler Vector124 /**< DMA2 Channel2. */ #define DMA2_Ch3_IRQHandler Vector128 /**< DMA2 Channel3. */ #define DMA2_Ch4_5_IRQHandler Vector12C /**< DMA2 Channel4 & Channel5. */ +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h index 25e28c62d..e4361c77f 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h @@ -40,10 +40,25 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @name Platform identification + * @{ + */ +#define PLATFORM_NAME "STM32 Connectivity Line" +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ #define STM32_HSICLK 8000000 /**< High speed internal clock. */ #define STM32_LSICLK 40000 /**< Low speed internal clock. */ +/** @} */ -/* RCC_CFGR register bits definitions.*/ +/** + * @name RCC_CFGR register bits definitions + * @{ + */ #define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ #define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ #define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ @@ -97,15 +112,100 @@ #define STM32_RTC_LSI (2 << 8) /**< LSI used as RTC clock. */ #define STM32_RTC_HSE (3 << 8) /**< HSE divided by 128 used as RTC clock. */ +/** @} */ -/* RCC_CFGR2 register bits definitions.*/ +/** + * @name RCC_CFGR2 register bits definitions + * @{ + */ #define STM32_PREDIV1SRC_HSE (0 << 16) /**< PREDIV1 source is HSE. */ #define STM32_PREDIV1SRC_PLL2 (1 << 16) /**< PREDIV1 source is PLL2. */ +/** @} */ + +/*===========================================================================*/ +/* Platform capabilities. */ +/*===========================================================================*/ + +/** + * @name STM32F105/F107 CL capabilities + * @{ + */ +#define STM32_HAS_ADC1 TRUE +#define STM32_HAS_ADC2 TRUE +#define STM32_HAS_ADC3 FALSE + +#define STM32_HAS_CAN1 TRUE +#define STM32_HAS_CAN2 TRUE + +#define STM32_HAS_DAC TRUE + +#define STM32_HAS_DMA1 TRUE +#define STM32_HAS_DMA2 TRUE + +#define STM32_HAS_ETH TRUE + +#define STM32_EXTI_NUM_CHANNELS 20 + +#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 FALSE +#define STM32_HAS_GPIOG FALSE +#define STM32_HAS_GPIOH FALSE +#define STM32_HAS_GPIOI FALSE + +#define STM32_HAS_I2C1 TRUE +#define STM32_HAS_I2C2 TRUE +#define STM32_HAS_I2C3 FALSE + +#define STM32_HAS_RTC TRUE + +#define STM32_HAS_SDIO FALSE + +#define STM32_HAS_SPI1 TRUE +#define STM32_HAS_SPI2 TRUE +#define STM32_HAS_SPI3 TRUE + +#define STM32_HAS_TIM1 TRUE +#define STM32_HAS_TIM2 TRUE +#define STM32_HAS_TIM3 TRUE +#define STM32_HAS_TIM4 TRUE +#define STM32_HAS_TIM5 TRUE +#define STM32_HAS_TIM6 TRUE +#define STM32_HAS_TIM7 TRUE +#define STM32_HAS_TIM8 FALSE +#define STM32_HAS_TIM9 FALSE +#define STM32_HAS_TIM10 FALSE +#define STM32_HAS_TIM11 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_USART1 TRUE +#define STM32_HAS_USART2 TRUE +#define STM32_HAS_USART3 TRUE +#define STM32_HAS_UART4 TRUE +#define STM32_HAS_UART5 TRUE +#define STM32_HAS_USART6 FALSE + +#define STM32_HAS_USB FALSE +#define STM32_HAS_OTG1 TRUE +#define STM32_HAS_OTG2 FALSE +/** @} */ /*===========================================================================*/ /* Platform specific friendly IRQ names. */ /*===========================================================================*/ +/** + * @name IRQ VECTOR names + * @{ + */ #define WWDG_IRQHandler Vector40 /**< Window Watchdog. */ #define PVD_IRQHandler Vector44 /**< PVD through EXTI Line detect. */ @@ -172,7 +272,8 @@ #define CAN2_RX1_IRQHandler Vector144 /**< CAN2 RX1. */ #define CAN2_SCE_IRQHandler Vector148 /**< CAN2 SCE. */ #define OTG_FS_IRQHandler Vector14C /**< USB OTG FS. */ - +/** @} */ + /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index 1371f0e8e..1b6882511 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -44,14 +44,24 @@ /*===========================================================================*/ /** - * @brief Platform name. + * @name Platform identification + * @{ */ #define PLATFORM_NAME "STM32F2 High performance" +/** @} */ +/** + * @name Internal clock sources + * @{ + */ #define STM32_HSICLK 16000000 /**< High speed internal clock. */ #define STM32_LSICLK 38000 /**< Low speed internal clock. */ +/** @} */ -/* RCC_PLLCFGR register bits definitions.*/ +/** + * @name RCC_PLLCFGR register bits definitions + * @{ + */ #define STM32_PLLP_MASK (3 << 16) /**< PLLP mask. */ #define STM32_PLLP_DIV2 (0 << 16) /**< PLL clock divided by 2. */ #define STM32_PLLP_DIV4 (1 << 16) /**< PLL clock divided by 4. */ @@ -60,8 +70,12 @@ #define STM32_PLLSRC_HSI (0 << 22) /**< PLL clock source is HSI. */ #define STM32_PLLSRC_HSE (1 << 22) /**< PLL clock source is HSE. */ +/** @} */ -/* RCC_CFGR register bits definitions.*/ +/** + * @name RCC_CFGR register bits definitions + * @{ + */ #define STM32_SW_MASK (3 << 0) /**< SW mask. */ #define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ #define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ @@ -120,11 +134,22 @@ #define STM32_MCO2SEL_HSE (2 << 30) /**< HSE clock on MCO2 pin. */ #define STM32_MCO2SEL_PLL (3 << 30) /**< PLL clock on MCO2 pin. */ -/* RCC_PLLI2SCFGR register bits definitions.*/ +/** + * @name RCC_PLLI2SCFGR register bits definitions + * @{ + */ #define STM32_PLLI2SN_MASK (511 << 6) /**< PLLI2SN mask. */ #define STM32_PLLI2SR_MASK (7 << 28) /**< PLLI2SR mask. */ +/** @} */ + +/*===========================================================================*/ +/* Platform capabilities. */ +/*===========================================================================*/ -/* STM32F2xx capabilities.*/ +/** + * @name STM32F4xx capabilities + * @{ + */ #define STM32_HAS_ADC1 TRUE #define STM32_HAS_ADC2 TRUE #define STM32_HAS_ADC3 TRUE @@ -153,6 +178,7 @@ #define STM32_HAS_I2C1 TRUE #define STM32_HAS_I2C2 TRUE +#define STM32_HAS_I2C3 TRUE #define STM32_HAS_RTC TRUE @@ -189,11 +215,17 @@ #define STM32_HAS_USB FALSE #define STM32_HAS_OTG1 TRUE +#define STM32_HAS_OTG2 TRUE +/** @} */ /*===========================================================================*/ /* Platform specific friendly IRQ names. */ /*===========================================================================*/ +/** + * @name IRQ VECTOR names + * @{ + */ #define WWDG_IRQHandler Vector40 /**< Window Watchdog. */ #define PVD_IRQHandler Vector44 /**< PVD through EXTI Line detect. */ @@ -281,6 +313,8 @@ #define DCMI_IRQHandler Vector178 /**< DCMI. */ #define CRYP_IRQHandler Vector17C /**< CRYP. */ #define HASH_RNG_IRQHandler Vector180 /**< Hash and Rng. */ +#define FPU_IRQHandler Vector184 /**< Floating Point Unit. */ +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ @@ -321,26 +355,12 @@ #define STM32_LSE_ENABLED FALSE #endif -/** - * @brief ADC clock setting. - */ -#if !defined(STM32_ADC_CLOCK_ENABLED) || defined(__DOXYGEN__) -#define STM32_ADC_CLOCK_ENABLED TRUE -#endif - -/** - * @brief USB clock setting. - */ -#if !defined(STM32_USB_CLOCK_ENABLED) || defined(__DOXYGEN__) -#define STM32_USB_CLOCK_ENABLED TRUE -#endif - /** * @brief Main clock source selection. * @note If the selected clock source is not the PLL then the PLL is not * initialized and started. - * @note The default value is calculated for a 32MHz system clock from - * the internal 16MHz HSI clock. + * @note The default value is calculated for a 168MHz system clock from + * an external 8MHz HSE clock. */ #if !defined(STM32_SW) || defined(__DOXYGEN__) #define STM32_SW STM32_SW_PLL @@ -350,8 +370,8 @@ * @brief Clock source for the PLL. * @note This setting has only effect if the PLL is selected as the * system clock source. - * @note The default value is calculated for a 120MHz system clock from - * the external 25MHz HSE clock. + * @note The default value is calculated for a 168MHz system clock from + * an external 8MHz HSE clock. */ #if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) #define STM32_PLLSRC STM32_PLLSRC_HSE @@ -360,8 +380,8 @@ /** * @brief PLLM divider value. * @note The allowed values are 2..63. - * @note The default value is calculated for a 120MHz system clock from - * an external 25MHz HSE clock. + * @note The default value is calculated for a 168MHz system clock from + * an external 8MHz HSE clock. */ #if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) #define STM32_PLLM_VALUE 25 @@ -370,8 +390,8 @@ /** * @brief PLLN multiplier value. * @note The allowed values are 192..432. - * @note The default value is calculated for a 120MHz system clock from - * an external 25MHz HSE clock. + * @note The default value is calculated for a 168MHz system clock from + * an external 8MHz HSE clock. */ #if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) #define STM32_PLLN_VALUE 240 @@ -380,8 +400,8 @@ /** * @brief PLLP multiplier value. * @note The allowed values are DIV2, DIV4, DIV6, DIV8. - * @note The default value is calculated for a 120MHz system clock from - * an external 25MHz HSE clock. + * @note The default value is calculated for a 168MHz system clock from + * an external 8MHz HSE clock. */ #if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) #define STM32_PLLP_VALUE 2 @@ -390,8 +410,8 @@ /** * @brief PLLQ multiplier value. * @note The allowed values are 4..15. - * @note The default value is calculated for a 120MHz system clock from - * an external 25MHz HSE clock. + * @note The default value is calculated for a 168MHz system clock from + * an external 8MHz HSE clock. */ #if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) #define STM32_PLLQ_VALUE 5 @@ -399,8 +419,8 @@ /** * @brief AHB prescaler value. - * @note The default value is calculated for a 120MHz system clock from - * an external 25MHz HSE clock. + * @note The default value is calculated for a 168MHz system clock from + * an external 8MHz HSE clock. */ #if !defined(STM32_HPRE) || defined(__DOXYGEN__) #define STM32_HPRE STM32_HPRE_DIV1 diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index 6efee2ca7..7ad613b5f 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -50,27 +50,45 @@ /*===========================================================================*/ /** - * @brief Platform name. + * @name Platform identification + * @{ */ #define PLATFORM_NAME "STM32L Ultra Low Power Medium Density" +/** @} */ +/** + * @name Internal clock sources + * @{ + */ #define STM32_HSICLK 16000000 /**< High speed internal clock. */ #define STM32_LSICLK 38000 /**< Low speed internal clock. */ +/** @} */ -/* PWR_CR register bits definitions.*/ +/** + * @name PWR_CR register bits definitions + * @{ + */ #define STM32_VOS_MASK (3 << 11) /**< Core voltage mask. */ #define STM32_VOS_1P8 (1 << 11) /**< Core voltage 1.8 Volts. */ #define STM32_VOS_1P5 (2 << 11) /**< Core voltage 1.5 Volts. */ #define STM32_VOS_1P2 (3 << 11) /**< Core voltage 1.2 Volts. */ +/** @} */ -/* RCC_CR register bits definitions.*/ +/** + * @name RCC_CR register bits definitions + * @{ + */ #define STM32_RTCPRE_MASK (3 << 29) /**< RTCPRE mask. */ #define STM32_RTCPRE_DIV2 (0 << 29) /**< HSE divided by 2. */ #define STM32_RTCPRE_DIV4 (1 << 29) /**< HSE divided by 4. */ #define STM32_RTCPRE_DIV8 (2 << 29) /**< HSE divided by 2. */ #define STM32_RTCPRE_DIV16 (3 << 29) /**< HSE divided by 16. */ +/** @} */ -/* RCC_CFGR register bits definitions.*/ +/** + * @name RCC_CFGR register bits definitions + * @{ + */ #define STM32_SW_MSI (0 << 0) /**< SYSCLK source is MSI. */ #define STM32_SW_HSI (1 << 0) /**< SYSCLK source is HSI. */ #define STM32_SW_HSE (2 << 0) /**< SYSCLK source is HSE. */ @@ -115,8 +133,12 @@ #define STM32_MCOPRE_DIV4 (2 << 28) /**< MCO divided by 1. */ #define STM32_MCOPRE_DIV8 (3 << 28) /**< MCO divided by 1. */ #define STM32_MCOPRE_DIV16 (4 << 28) /**< MCO divided by 1. */ +/** @} */ -/* RCC_ICSCR register bits definitions.*/ +/** + * @name RCC_ICSCR register bits definitions + * @{ + */ #define STM32_MSIRANGE_MASK (7 << 13) /**< MSIRANGE field mask. */ #define STM32_MSIRANGE_64K (0 << 13) /**< 64KHz nominal. */ #define STM32_MSIRANGE_128K (1 << 13) /**< 128KHz nominal. */ @@ -125,15 +147,27 @@ #define STM32_MSIRANGE_1M (4 << 13) /**< 1MHz nominal. */ #define STM32_MSIRANGE_2M (5 << 13) /**< 2MHz nominal. */ #define STM32_MSIRANGE_4M (6 << 13) /**< 4MHz nominal */ +/** @} */ -/* RCC_CSR register bits definitions.*/ +/** + * @name RCC_CSR register bits definitions + * @{ + */ #define STM32_RTCSEL_MASK (3 << 16) /**< RTC source mask. */ #define STM32_RTCSEL_NOCLOCK (0 << 16) /**< No RTC source. */ #define STM32_RTCSEL_LSE (1 << 16) /**< RTC source is LSE. */ #define STM32_RTCSEL_LSI (2 << 16) /**< RTC source is LSI. */ #define STM32_RTCSEL_HSEDIV (3 << 16) /**< RTC source is HSE divided. */ +/** @} */ + +/*===========================================================================*/ +/* Platform capabilities. */ +/*===========================================================================*/ -/* STM32L1xx capabilities.*/ +/** + * @name STM32L1xx capabilities + * @{ + */ #define STM32_HAS_ADC1 TRUE #define STM32_HAS_ADC2 FALSE #define STM32_HAS_ADC3 FALSE @@ -158,9 +192,11 @@ #define STM32_HAS_GPIOF FALSE #define STM32_HAS_GPIOG FALSE #define STM32_HAS_GPIOH TRUE +#define STM32_HAS_GPIOI FALSE #define STM32_HAS_I2C1 TRUE #define STM32_HAS_I2C2 TRUE +#define STM32_HAS_I2C3 FALSE #define STM32_HAS_RTC TRUE @@ -197,9 +233,16 @@ #define STM32_HAS_USB TRUE #define STM32_HAS_OTG1 FALSE +#define STM32_HAS_OTG2 FALSE +/** @} */ + +/*===========================================================================*/ +/* Platform specific friendly IRQ names. */ +/*===========================================================================*/ /** - * @name Platform specific friendly IRQ names + * @name IRQ VECTOR names + * @{ */ #define WWDG_IRQHandler Vector40 /**< Window Watchdog. */ #define PVD_IRQHandler Vector44 /**< PVD through EXTI Line -- cgit v1.2.3 From c90189fc103322b3f2ea85bc59a50d92cc9f2913 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 3 Nov 2011 18:06:39 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3463 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/USBv1/usb_lld.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/USBv1/usb_lld.c b/os/hal/platforms/STM32/USBv1/usb_lld.c index e148a6fea..3ecf738da 100644 --- a/os/hal/platforms/STM32/USBv1/usb_lld.c +++ b/os/hal/platforms/STM32/USBv1/usb_lld.c @@ -421,8 +421,8 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) { dp = USB_GET_DESCRIPTOR(ep); dp->TXCOUNT0 = 0; dp->RXCOUNT0 = nblocks; - dp->TXADDR = pm_alloc(usbp, epcp->in_maxsize); - dp->RXADDR = pm_alloc(usbp, epcp->out_maxsize); + dp->TXADDR0 = pm_alloc(usbp, epcp->in_maxsize); + dp->RXADDR0 = pm_alloc(usbp, epcp->out_maxsize); } /** @@ -516,7 +516,7 @@ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) { (void)usbp; udp = USB_GET_DESCRIPTOR(ep); - pmap = USB_ADDR2PTR(udp->RXADDR); + pmap = USB_ADDR2PTR(udp->RXADDR0); for (n = 0; n < 4; n++) { *(uint16_t *)buf = (uint16_t)*pmap++; buf += 2; @@ -548,7 +548,7 @@ size_t usb_lld_read_packet_buffer(USBDriver *usbp, usbep_t ep, (void)usbp; udp = USB_GET_DESCRIPTOR(ep); - pmap = USB_ADDR2PTR(udp->RXADDR); + pmap = USB_ADDR2PTR(udp->RXADDR0); count = (size_t)udp->RXCOUNT0 & RXCOUNT_COUNT_MASK; if (n > count) n = count; @@ -582,7 +582,7 @@ void usb_lld_write_packet_buffer(USBDriver *usbp, usbep_t ep, (void)usbp; udp = USB_GET_DESCRIPTOR(ep); - pmap = USB_ADDR2PTR(udp->TXADDR); + pmap = USB_ADDR2PTR(udp->TXADDR0); udp->TXCOUNT0 = (uint16_t)n; n = (n + 1) / 2; while (n > 0) { -- cgit v1.2.3 From ba89f675a2affeaa66f06c31085ecc95b88e25df Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 4 Nov 2011 20:20:36 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3466 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/hal_lld_f100.h | 6 +- os/hal/platforms/STM32F1xx/hal_lld_f103.h | 10 +- os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h | 2 +- os/hal/platforms/STM32F4xx/hal_lld.h | 149 ++++++++++++++++++++----- os/hal/platforms/STM32L1xx/hal_lld.h | 2 +- 5 files changed, 129 insertions(+), 40 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f100.h b/os/hal/platforms/STM32F1xx/hal_lld_f100.h index 864be581e..cdad07bc5 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f100.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f100.h @@ -45,13 +45,13 @@ * @{ */ #if defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32 Value Line" +#define PLATFORM_NAME "STM32F1 Value Line" #elif defined(STM32F10X_LD_VL) -#define PLATFORM_NAME "STM32 Value Line Low Density" +#define PLATFORM_NAME "STM32F1 Value Line Low Density" #elif defined(STM32F10X_MD_VL) -#define PLATFORM_NAME "STM32 Value Line Medium Density" +#define PLATFORM_NAME "STM32F1 Value Line Medium Density" #else #error "unsupported STM32 Value Line member" #endif diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f103.h b/os/hal/platforms/STM32F1xx/hal_lld_f103.h index 7c04b7d38..92144b5dc 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f103.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f103.h @@ -45,19 +45,19 @@ * @{ */ #if defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32 Performance Line" +#define PLATFORM_NAME "STM32F1 Performance Line" #elif defined(STM32F10X_LD) -#define PLATFORM_NAME "STM32 Performance Line Low Density" +#define PLATFORM_NAME "STM32F1 Performance Line Low Density" #elif defined(STM32F10X_MD) -#define PLATFORM_NAME "STM32 Performance Line Medium Density" +#define PLATFORM_NAME "STM32F1 Performance Line Medium Density" #elif defined(STM32F10X_HD) -#define PLATFORM_NAME "STM32 Performance Line High Density" +#define PLATFORM_NAME "STM32F1 Performance Line High Density" #elif defined(STM32F10X_XL) -#define PLATFORM_NAME "STM32 Performance Line eXtra Density" +#define PLATFORM_NAME "STM32F1 Performance Line eXtra Density" #else #error "unsupported STM32 Performance Line member" diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h index e4361c77f..52de807d2 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h @@ -44,7 +44,7 @@ * @name Platform identification * @{ */ -#define PLATFORM_NAME "STM32 Connectivity Line" +#define PLATFORM_NAME "STM32F1 Connectivity Line" /** @} */ /** diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index 1b6882511..38581b6bd 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -25,6 +25,7 @@ * @p board.h file: * - STM32_LSECLK. * - STM32_HSECLK. + * - STM32_VDD (as hundredths of Volt). * . * One of the following macros must also be defined: * - STM32F4XX for High-performance STM32 F-4 devices. @@ -47,7 +48,7 @@ * @name Platform identification * @{ */ -#define PLATFORM_NAME "STM32F2 High performance" +#define PLATFORM_NAME "STM32F4 High Performance & DSP" /** @} */ /** @@ -58,6 +59,15 @@ #define STM32_LSICLK 38000 /**< Low speed internal clock. */ /** @} */ +/** + * @name PWR_CR register bits definitions + * @{ + */ +#define STM32_VOS_MASK (1 << 14) /**< Core voltage mask. */ +#define STM32_VOS_LOW (0 << 14) /**< Core voltage set to low. */ +#define STM32_VOS_HIGH (1 << 14) /**< Core voltage set to high. */ +/** @} */ + /** * @name RCC_PLLCFGR register bits definitions * @{ @@ -114,6 +124,10 @@ #define STM32_MCO1SEL_HSE (2 << 21) /**< HSE clock on MCO1 pin. */ #define STM32_MCO1SEL_PLL (3 << 21) /**< PLL clock on MCO1 pin. */ +#define STM32_I2CSRC_MASK (1 << 23) /**< I2CSRC mask. */ +#define STM32_I2CSRC_PLLI2S (0 << 23) /**< I2SSRC is PLLI2S. */ +#define STM32_I2CSRC_CKIN (1 << 23) /**< I2S_CKIN is PLLI2S. */ + #define STM32_MCO1PRE_MASK (7 << 24) /**< MCO1PRE mask. */ #define STM32_MCO1PRE_DIV1 (0 << 24) /**< MCO1 divided by 1. */ #define STM32_MCO1PRE_DIV2 (1 << 24) /**< MCO1 divided by 2. */ @@ -327,6 +341,16 @@ #define STM32_NO_INIT FALSE #endif +/** + * @brief Core voltage selection. + * @note This setting affects all the performance and clock related + * settings, the maximum performance is only obtainable selecting + * the maximum voltage. + */ +#if !defined(STM32_VOS) || defined(__DOXYGEN__) +#define STM32_VOS STM32_VOS_HIGH +#endif + /** * @brief Enables or disables the HSI clock source. */ @@ -367,7 +391,7 @@ #endif /** - * @brief Clock source for the PLL. + * @brief Clock source for the PLLs. * @note This setting has only effect if the PLL is selected as the * system clock source. * @note The default value is calculated for a 168MHz system clock from @@ -384,7 +408,7 @@ * an external 8MHz HSE clock. */ #if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLM_VALUE 25 +#define STM32_PLLM_VALUE 8 #endif /** @@ -394,17 +418,17 @@ * an external 8MHz HSE clock. */ #if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLN_VALUE 240 +#define STM32_PLLN_VALUE 336 #endif /** - * @brief PLLP multiplier value. - * @note The allowed values are DIV2, DIV4, DIV6, DIV8. + * @brief PLLP divider value. + * @note The allowed values are 2, 4, 6, 8. * @note The default value is calculated for a 168MHz system clock from * an external 8MHz HSE clock. */ #if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLP_VALUE 2 +#define STM32_PLLP_VALUE 2 #endif /** @@ -414,7 +438,7 @@ * an external 8MHz HSE clock. */ #if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLQ_VALUE 5 +#define STM32_PLLQ_VALUE 7 #endif /** @@ -444,7 +468,7 @@ * @brief RTC prescaler value. */ #if !defined(STM32_RTCPRE_VALUE) || defined(__DOXYGEN__) -#define STM32_RTCPRE_VALUE 25 +#define STM32_RTCPRE_VALUE 8 #endif /** @@ -479,24 +503,35 @@ #define STM32_MCO2PRE STM32_MCO2PRE_DIV5 #endif + +/** + * @brief Enables or disables the I2S clock source. + */ +#if !defined(STM32_I2S_ENABLED) || defined(__DOXYGEN__) +#define STM32_I2S_ENABLED FALSE +#endif + +/** + * @brief I2S clock source. + */ +#if !defined(STM32_I2SSRC) || defined(__DOXYGEN__) +#define STM32_I2SSRC STM32_I2CSRC_PLLI2S +#endif + /** * @brief PLLI2SN multiplier value. * @note The allowed values are 192..432. - * @note The default value is calculated for a 48000 I2S clock with - * I2SDIV = 12 and I2SODD = 1. */ #if !defined(STM32_PLLI2SN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SN_VALUE 384 +#define STM32_PLLI2SN_VALUE 192 #endif /** * @brief PLLI2SR multiplier value. * @note The allowed values are 2..7. - * @note The default value is calculated for a 48000 I2S clock with - * I2SDIV = 12 and I2SODD = 1. */ -#if !defined(STM32_PLLI2SP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLI2SLP_VALUE 5 +#if !defined(STM32_PLLI2SR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SR_VALUE 5 #endif /*===========================================================================*/ @@ -506,47 +541,101 @@ /** * @brief Maximum HSECLK. */ -#define STM32_HSECLK_MAX 32000000 +#define STM32_HSECLK_MAX 26000000 + +/** + * @brief Minimum HSECLK. + */ +#define STM32_HSECLK_MIN 1000000 /** * @brief Maximum SYSCLK. + * @note It is a function of the core voltage setting. */ -#define STM32_SYSCLK_MAX 120000000 +#if (STM32_VOS == STM32_VOS_HIGH) || defined(__DOXYGEN__) +#define STM32_SYSCLK_MAX 168000000 +#else +#define STM32_SYSCLK_MAX 144000000 +#endif /** * @brief Maximum frequency thresholds and wait states for flash access. * @note The values are valid for 2.7V to 3.6V supply range. */ +#if ((STM32_VDD >= 270) && (STM32_VDD <= 360)) || defined(__DOXYGEN__) #define STM32_0WS_THRESHOLD 30000000 #define STM32_1WS_THRESHOLD 60000000 #define STM32_2WS_THRESHOLD 90000000 -#define STM32_3WS_THRESHOLD 0 -#define STM32_4WS_THRESHOLD 0 -#define STM32_5WS_THRESHOLD 0 +#define STM32_3WS_THRESHOLD 120000000 +#define STM32_4WS_THRESHOLD 150000000 +#define STM32_5WS_THRESHOLD 168000000 #define STM32_6WS_THRESHOLD 0 #define STM32_7WS_THRESHOLD 0 +#elif (STM32_VDD >= 240) && (STM32_VDD < 270) +#define STM32_0WS_THRESHOLD 24000000 +#define STM32_1WS_THRESHOLD 48000000 +#define STM32_2WS_THRESHOLD 72000000 +#define STM32_3WS_THRESHOLD 96000000 +#define STM32_4WS_THRESHOLD 120000000 +#define STM32_5WS_THRESHOLD 144000000 +#define STM32_6WS_THRESHOLD 168000000 +#define STM32_7WS_THRESHOLD 0 +#elif (STM32_VDD >= 210) && (STM32_VDD < 240) +#define STM32_0WS_THRESHOLD 18000000 +#define STM32_1WS_THRESHOLD 36000000 +#define STM32_2WS_THRESHOLD 54000000 +#define STM32_3WS_THRESHOLD 72000000 +#define STM32_4WS_THRESHOLD 90000000 +#define STM32_5WS_THRESHOLD 108000000 +#define STM32_6WS_THRESHOLD 120000000 +#define STM32_7WS_THRESHOLD 138000000 +#elif (STM32_VDD >= 180) && (STM32_VDD < 210) +#define STM32_0WS_THRESHOLD 16000000 +#define STM32_1WS_THRESHOLD 32000000 +#define STM32_2WS_THRESHOLD 48000000 +#define STM32_3WS_THRESHOLD 64000000 +#define STM32_4WS_THRESHOLD 80000000 +#define STM32_5WS_THRESHOLD 96000000 +#define STM32_6WS_THRESHOLD 112000000 +#define STM32_7WS_THRESHOLD 128000000 +#else +#error "invalid VDD voltage specified" +#endif /* HSI related checks.*/ #if STM32_HSI_ENABLED #else /* !STM32_HSI_ENABLED */ -#if STM32_ADC_CLOCK_ENABLED || \ - (STM32_SW == STM32_SW_HSI) || \ - ((STM32_SW == STM32_SW_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI)) || \ - (STM32_MCO1SEL == STM32_MCO1SEL_HSI) || \ + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCO1SEL == STM32_MCO1SEL_HSI) || \ ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ (STM32_PLLSRC == STM32_PLLSRC_HSI)) -#error "required HSI clock is not enabled" +#error "HSI not enabled, required by STM32_MCO1SEL" +#endif + +#if (STM32_MCO2SEL == STM32_MCO2SEL_HSI) || \ + ((STM32_MCO2SEL == STM32_MCO2SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI)) +#error "HSI not enabled, required by STM32_MCO2SEL" #endif + +#if STM32_I2S_ENABLED && \ + (STM32_I2SSRC == STM32_I2CSRC_PLLI2S) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_I2S_ENABLED and STM32_I2SSRC" +#endif + #endif /* !STM32_HSI_ENABLED */ /* HSE related checks.*/ #if STM32_HSE_ENABLED #if STM32_HSECLK == 0 #error "impossible to activate HSE" -#endif -#if (STM32_HSECLK < 1000000) || (STM32_HSECLK > STM32_HSECLK_MAX) -#error "STM32_HSECLK outside acceptable range (1MHz...STM32_HSECLK_MAX)" +#elif (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" #endif #else /* !STM32_HSE_ENABLED */ #if (STM32_SW == STM32_SW_HSE) || \ diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index 7ad613b5f..09bd9bf78 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -53,7 +53,7 @@ * @name Platform identification * @{ */ -#define PLATFORM_NAME "STM32L Ultra Low Power Medium Density" +#define PLATFORM_NAME "STM32L1 Ultra Low Power Medium Density" /** @} */ /** -- cgit v1.2.3 From 5649691bf9e05cd64fa244de733497f7dbc4efae Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 5 Nov 2011 08:14:16 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3467 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/hal_lld.h | 284 ++++++++++++++++++++++++----------- os/hal/platforms/STM32L1xx/hal_lld.h | 53 +++++-- 2 files changed, 233 insertions(+), 104 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index 38581b6bd..6fc67e39e 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -51,6 +51,71 @@ #define PLATFORM_NAME "STM32F4 High Performance & DSP" /** @} */ +/** + * @name Absolute Maximum Ratings + * @{ + */ +/** + * @brief Maximum HSE clock frequency. + */ +#define STM32_HSECLK_MAX 26000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_MIN 1000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_MAX 1000000 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_MIN 1000 + +/** + * @brief Maximum PLL input clock frequency. + */ +#define STM32_PLLIN_MAX 2000000 + +/** + * @brief Maximum PLL input clock frequency. + */ +#define STM32_PLLIN_MIN 950000 + +/** + * @brief Maximum PLLCLKOUT clock frequency. + */ +#define STM32_PLLVCO_MAX 432000000 + +/** + * @brief Maximum PLLCLKOUT clock frequency. + */ +#define STM32_PLLVCO_MIN 192000000 + +/** + * @brief Maximum PLL output clock frequency. + */ +#define STM32_PLLOUT_MAX 168000000 + +/** + * @brief Maximum PLL output clock frequency. + */ +#define STM32_PLLOUT_MIN 24000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define STM32_PCLK1_MAX 42000000 + +/** + * @brief Maximum APB2 clock frequency. + */ +#define STM32_PCLK2_MAX 84000000 +/** @} */ + /** * @name Internal clock sources * @{ @@ -156,6 +221,17 @@ #define STM32_PLLI2SR_MASK (7 << 28) /**< PLLI2SR mask. */ /** @} */ +/** + * @name RCC_BDCR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3 << 8) /**< RTC source mask. */ +#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No RTC source. */ +#define STM32_RTCSEL_LSE (1 << 8) /**< RTC source is LSE. */ +#define STM32_RTCSEL_LSI (2 << 8) /**< RTC source is LSI. */ +#define STM32_RTCSEL_HSEDIV (3 << 8) /**< RTC source is HSE divided. */ +/** @} */ + /*===========================================================================*/ /* Platform capabilities. */ /*===========================================================================*/ @@ -379,6 +455,20 @@ #define STM32_LSE_ENABLED FALSE #endif +/** + * @brief USB clock setting. + */ +#if !defined(STM32_USB_CLOCK_ENABLED) || defined(__DOXYGEN__) +#define STM32_USB_CLOCK_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the I2S clock source. + */ +#if !defined(STM32_I2S_CLOCK_ENABLED) || defined(__DOXYGEN__) +#define STM32_I2S_CLOCK_ENABLED FALSE +#endif + /** * @brief Main clock source selection. * @note If the selected clock source is not the PLL then the PLL is not @@ -465,9 +555,16 @@ #endif /** - * @brief RTC prescaler value. + * @brief RTC source clock. */ -#if !defined(STM32_RTCPRE_VALUE) || defined(__DOXYGEN__) +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief RTC HSE prescaler value. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) #define STM32_RTCPRE_VALUE 8 #endif @@ -503,12 +600,11 @@ #define STM32_MCO2PRE STM32_MCO2PRE_DIV5 #endif - /** * @brief Enables or disables the I2S clock source. */ -#if !defined(STM32_I2S_ENABLED) || defined(__DOXYGEN__) -#define STM32_I2S_ENABLED FALSE +#if !defined(STM32_I2S_CLOCK_ENABLED) || defined(__DOXYGEN__) +#define STM32_I2S_CLOCK_ENABLED FALSE #endif /** @@ -538,16 +634,6 @@ /* Derived constants and error checks. */ /*===========================================================================*/ -/** - * @brief Maximum HSECLK. - */ -#define STM32_HSECLK_MAX 26000000 - -/** - * @brief Minimum HSECLK. - */ -#define STM32_HSECLK_MIN 1000000 - /** * @brief Maximum SYSCLK. * @note It is a function of the core voltage setting. @@ -602,10 +688,16 @@ #error "invalid VDD voltage specified" #endif -/* HSI related checks.*/ +/* + * HSI related checks. + */ #if STM32_HSI_ENABLED #else /* !STM32_HSI_ENABLED */ +#if STM32_SW == STM32_SW_HSI +#error "HSI not enabled, required by STM32_SW" +#endif + #if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) #error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" #endif @@ -622,59 +714,95 @@ #error "HSI not enabled, required by STM32_MCO2SEL" #endif -#if STM32_I2S_ENABLED && \ +#if STM32_I2S_CLOCK_ENABLED && \ (STM32_I2SSRC == STM32_I2CSRC_PLLI2S) && \ (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_I2S_ENABLED and STM32_I2SSRC" +#error "HSI not enabled, required by STM32_I2S_CLOCK_ENABLED and STM32_I2SSRC" #endif #endif /* !STM32_HSI_ENABLED */ -/* HSE related checks.*/ +/* + * HSE related checks. + */ #if STM32_HSE_ENABLED + #if STM32_HSECLK == 0 -#error "impossible to activate HSE" +#error "HSE frequency not defined" #elif (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) #error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" #endif + #else /* !STM32_HSE_ENABLED */ -#if (STM32_SW == STM32_SW_HSE) || \ - ((STM32_SW == STM32_SW_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) || \ - (STM32_MCO1SEL == STM32_MCO1SEL_HSE) || \ + +#if STM32_SW == STM32_SW_HSE +#error "HSE not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCO1SEL == STM32_MCO1SEL_HSE) || \ ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) || \ - (STM32_MCO2SEL == STM32_MCO2SEL_HSE) || \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) +#error "HSE not enabled, required by STM32_MCO1SEL" +#endif + +#if (STM32_MCO2SEL == STM32_MCO2SEL_HSE) || \ ((STM32_MCO2SEL == STM32_MCO2SEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) || \ - (STM_RTC_SOURCE == STM32_RTCSEL_HSEDIV) -#error "required HSE clock is not enabled" + (STM32_PLLSRC == STM32_PLLSRC_HSE)) +#error "HSE not enabled, required by STM32_MCO2SEL" #endif + +#if STM32_I2S_CLOCK_ENABLED && \ + (STM32_I2SSRC == STM32_I2CSRC_PLLI2S) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_I2S_CLOCK_ENABLED and STM32_I2SSRC" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#error "HSE not enabled, required by STM32_RTCSEL" +#endif + #endif /* !STM32_HSE_ENABLED */ -/* LSI related checks.*/ +/* + * LSI related checks. + */ #if STM32_LSI_ENABLED #else /* !STM32_LSI_ENABLED */ -#if STM_RTCCLK == STM32_LSICLK + +#if STM32_RTCSEL == STM32_RTCSEL_LSI #error "required LSI clock is not enabled" #endif + #endif /* !STM32_LSI_ENABLED */ -/* LSE related checks.*/ +/* + * LSE related checks. + */ #if STM32_LSE_ENABLED + #if (STM32_LSECLK == 0) -#error "impossible to activate LSE" +#error "LSE frequency not defined" #endif -#if (STM32_LSECLK < 1000) || (STM32_LSECLK > 1000000) -#error "STM32_LSECLK outside acceptable range (1...1000KHz)" + +#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) +#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" #endif + #else /* !#if STM32_LSE_ENABLED */ -#if STM_RTCCLK == STM32_LSECLK -#error "required LSE clock is not enabled" + +#if STM32_RTCSEL == STM32_RTCSEL_LSE +#error "LSE not enabled, required by STM32_RTCSEL" #endif + #endif /* !#if STM32_LSE_ENABLED */ -/* PLL related checks.*/ +/* + * PLL related checks. + */ #if STM32_USB_CLOCK_ENABLED || \ (STM32_SW == STM32_SW_PLL) || \ (STM32_MCO1SEL == STM32_MCO1SEL_PLL) || \ @@ -693,7 +821,7 @@ */ #if ((STM32_PLLM_VALUE >= 2) && (STM32_PLLM_VALUE <= 63)) || \ defined(__DOXYGEN__) -#define STM32_PLLM STM32_PLLM_VALUE +#define STM32_PLLM (STM32_PLLM_VALUE << 0) #else #error "invalid STM32_PLLM_VALUE value specified" #endif @@ -737,28 +865,29 @@ * @brief PLL input clock frequency. */ #if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLCLKIN STM32_HSECLK +#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PLLM_VALUE) #elif STM32_PLLSRC == STM32_PLLSRC_HSI -#define STM32_PLLCLKIN STM32_HSICLK +#define STM32_PLLCLKIN (STM32_HSICLK / STM32_PLLM_VALUE) #else #error "invalid STM32_PLLSRC value specified" #endif /* PLL input frequency range check.*/ -#if (STM32_PLLCLKIN < 4000000) || (STM32_PLLCLKIN > 26000000) -#error "STM32_PLLCLKIN outside acceptable range (4...26MHz)" +#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) +#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" #endif /** * @brief PLL VCO frequency. */ -#define STM32_PLLVCO ((STM32_PLLCLKIN / STM32_PLLM_VALUE) * \ - STM32_PLLN_VALUE) +#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) -/* PLL output frequency range check.*/ -#if (STM32_PLLVCO < 192000000) || (STM32_PLLVCO > 432000000) +/* + * PLL output frequency range check. + */ +#if (STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX) #error STM32_PLLVCO -#error "STM32_PLLVCO outside acceptable range (192...432MHz)" +#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" #endif /** @@ -767,15 +896,15 @@ #define STM32_PLLCLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) /* PLL output frequency range check.*/ -#if (STM32_PLLCLKOUT < 24000000) || (STM32_PLLCLKOUT > 120000000) -#error "STM32_PLLCLKOUT outside acceptable range (24...120MHz)" +#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) +#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" #endif /** * @brief System clock source. */ #if STM32_NO_INIT || defined(__DOXYGEN__) -#define STM32_SYSCLK 96000000 +#define STM32_SYSCLK STM32_HSICLK #elif (STM32_SW == STM32_SW_HSI) #define STM32_SYSCLK STM32_HSICLK #elif (STM32_SW == STM32_SW_HSE) @@ -816,7 +945,9 @@ #error "invalid STM32_HPRE value specified" #endif -/* AHB frequency check.*/ +/* + * AHB frequency check. + */ #if STM32_HCLK > STM32_SYSCLK_MAX #error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" #endif @@ -838,9 +969,11 @@ #error "invalid STM32_PPRE1 value specified" #endif -/* APB1 frequency check.*/ -#if STM32_PCLK2 > STM32_SYSCLK_MAX -#error "STM32_PCLK1 exceeding maximum frequency (STM32_SYSCLK_MAX)" +/* + * APB1 frequency check. + */ +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" #endif /** @@ -860,9 +993,11 @@ #error "invalid STM32_PPRE2 value specified" #endif -/* APB2 frequency check.*/ -#if STM32_PCLK2 > STM32_SYSCLK_MAX -#error "STM32_PCLK2 exceeding maximum frequency (STM32_SYSCLK_MAX)" +/* + * APB2 frequency check. + */ +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" #endif /** @@ -918,7 +1053,6 @@ #define STM_MCO2DIVCLK STM32_SYSCLK #elif STM32_MCO2SEL == STM32_MCO2SEL_PLLI2S #define STM_MCO2DIVCLK STM32_PLLI2S - #else #error "invalid STM32_MCO2SEL value specified" #endif @@ -943,9 +1077,9 @@ /** * @brief HSE divider toward RTC clock. */ -#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ +#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ defined(__DOXYGEN__) -#define STM32_HSEDIVCLK (HSECLK / STM32_RTCPRE_VALUE) +#define STM32_HSEDIVCLK (STM32_HSECLK / STM32_RTCPRE_VALUE) #else #error "invalid STM32_RTCPRE value specified" #endif @@ -965,36 +1099,10 @@ #error "invalid STM32_RTCSEL value specified" #endif -/** - * @brief ADC frequency. - */ -#if (STM32_ADCPRE == STM32_ADCPRE_DIV2) || defined(__DOXYGEN__) -#define STM32_ADCCLK (STM32_PCLK2 / 2) -#elif STM32_ADCPRE == STM32_ADCPRE_DIV4 -#define STM32_ADCCLK (STM32_PCLK2 / 4) -#elif STM32_ADCPRE == STM32_ADCPRE_DIV6 -#define STM32_ADCCLK (STM32_PCLK2 / 6) -#elif STM32_ADCPRE == STM32_ADCPRE_DIV8 -#define STM32_ADCCLK (STM32_PCLK2 / 8) -#else -#error "invalid STM32_ADCPRE value specified" -#endif - -/* ADC frequency check.*/ -#if STM32_ADCCLK > 30000000 -#error "STM32_ADCCLK exceeding maximum frequency (30MHz)" -#endif - /** * @brief OTG frequency. */ -#if (STM32_OTGFSPRE == STM32_OTGFSPRE_DIV3) || defined(__DOXYGEN__) -#define STM32_OTGFSCLK (STM32_PLLVCO / 3) -#elif (STM32_OTGFSPRE == STM32_OTGFSPRE_DIV2) -#define STM32_OTGFSCLK (STM32_PLLVCO / 2) -#else -#error "invalid STM32_OTGFSPRE value specified" -#endif +#define STM32_OTGFSCLK (STM32_PLLVCO / STM32_PLLQ_VALUE) /** * @brief Timers 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14 clock. diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index 09bd9bf78..9ca34fb7c 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -464,19 +464,34 @@ /* Voltage related limits.*/ #if (STM32_VOS == STM32_VOS_1P8) || defined(__DOXYGEN__) /** - * @brief Maximum HSECLK at current voltage setting. + * @brief Maximum HSE clock frequency at current voltage setting. */ #define STM32_HSECLK_MAX 32000000 /** - * @brief Maximum SYSCLK at current voltage setting. + * @brief Maximum SYSCLK clock frequency at current voltage setting. */ #define STM32_SYSCLK_MAX 32000000 /** - * @brief Maximum PLLCLKOUT at current voltage setting. + * @brief Maximum VCO clock frequency at current voltage setting. */ -#define STM32_PLLCLKOUT_MAX 96000000 +#define STM32_PLLVCO_MAX 96000000 + +/** + * @brief Minimum VCO clock frequency at current voltage setting. + */ +#define STM32_PLLVCO_MIN 6000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define STM32_PCLK1_MAX 32000000 + +/** + * @brief Maximum APB2 clock frequency. + */ +#define STM32_PCLK2_MAX 32000000 /** * @brief Maximum frequency not requiring a wait state for flash accesses. @@ -491,13 +506,19 @@ #elif STM32_VOS == STM32_VOS_1P5 #define STM32_HSECLK_MAX 16000000 #define STM32_SYSCLK_MAX 16000000 -#define STM32_PLLCLKOUT_MAX 48000000 +#define STM32_PLLVCO_MAX 48000000 +#define STM32_PLLVCO_MIN 6000000 +#define STM32_PCLK1_MAX 16000000 +#define STM32_PCLK2_MAX 16000000 #define STM32_0WS_THRESHOLD 8000000 #define STM32_HSI_AVAILABLE TRUE #elif STM32_VOS == STM32_VOS_1P2 #define STM32_HSECLK_MAX 4000000 #define STM32_SYSCLK_MAX 4000000 -#define STM32_PLLCLKOUT_MAX 24000000 +#define STM32_PLLVCO_MAX 24000000 +#define STM32_PLLVCO_MIN 6000000 +#define STM32_PCLK1_MAX 4000000 +#define STM32_PCLK2_MAX 4000000 #define STM32_0WS_THRESHOLD 2000000 #define STM32_HSI_AVAILABLE FALSE #else @@ -636,8 +657,8 @@ #define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) /* PLL output frequency range check.*/ -#if (STM32_PLLVCO < 6000000) || (STM32_PLLVCO > 96000000) -#error "STM32_PLLVCO outside acceptable range (6...96MHz)" +#if (STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX) +#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" #endif /** @@ -742,8 +763,8 @@ #endif /* APB1 frequency check.*/ -#if STM32_PCLK2 > STM32_SYSCLK_MAX -#error "STM32_PCLK1 exceeding maximum frequency (STM32_SYSCLK_MAX)" +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" #endif /** @@ -764,8 +785,8 @@ #endif /* APB2 frequency check.*/ -#if STM32_PCLK2 > STM32_SYSCLK_MAX -#error "STM32_PCLK2 exceeding maximum frequency (STM32_SYSCLK_MAX)" +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" #endif /** @@ -810,13 +831,13 @@ * @brief HSE divider toward RTC clock. */ #if (STM32_RTCPRE == STM32_RTCPRE_DIV2) || defined(__DOXYGEN__) -#define STM32_HSEDIVCLK (HSECLK / 2) +#define STM32_HSEDIVCLK (STM32_HSECLK / 2) #elif (STM32_RTCPRE == STM32_RTCPRE_DIV4) || defined(__DOXYGEN__) -#define STM32_HSEDIVCLK (HSECLK / 4) +#define STM32_HSEDIVCLK (STM32_HSECLK / 4) #elif (STM32_RTCPRE == STM32_RTCPRE_DIV8) || defined(__DOXYGEN__) -#define STM32_HSEDIVCLK (HSECLK / 8) +#define STM32_HSEDIVCLK (STM32_HSECLK / 8) #elif (STM32_RTCPRE == STM32_RTCPRE_DIV16) || defined(__DOXYGEN__) -#define STM32_HSEDIVCLK (HSECLK / 16) +#define STM32_HSEDIVCLK (STM32_HSECLK / 16) #else #error "invalid STM32_RTCPRE value specified" #endif -- cgit v1.2.3 From 1297070fa9afcb4895b459bf798822e72bb42ea1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 5 Nov 2011 09:53:04 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3468 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/hal_lld.h | 187 ++++++++++++++++++++++------------- 1 file changed, 120 insertions(+), 67 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index 6fc67e39e..337b67b55 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -76,22 +76,22 @@ #define STM32_LSECLK_MIN 1000 /** - * @brief Maximum PLL input clock frequency. + * @brief Maximum PLLs input clock frequency. */ #define STM32_PLLIN_MAX 2000000 /** - * @brief Maximum PLL input clock frequency. + * @brief Maximum PLLs input clock frequency. */ #define STM32_PLLIN_MIN 950000 /** - * @brief Maximum PLLCLKOUT clock frequency. + * @brief Maximum PLLs VCO clock frequency. */ #define STM32_PLLVCO_MAX 432000000 /** - * @brief Maximum PLLCLKOUT clock frequency. + * @brief Maximum PLLs VCO clock frequency. */ #define STM32_PLLVCO_MIN 192000000 @@ -114,6 +114,11 @@ * @brief Maximum APB2 clock frequency. */ #define STM32_PCLK2_MAX 84000000 + +/** + * @brief Maximum SPI/I2S clock frequency. + */ +#define STM32_SPII2S_MAX 37500000 /** @} */ /** @@ -458,15 +463,8 @@ /** * @brief USB clock setting. */ -#if !defined(STM32_USB_CLOCK_ENABLED) || defined(__DOXYGEN__) -#define STM32_USB_CLOCK_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the I2S clock source. - */ -#if !defined(STM32_I2S_CLOCK_ENABLED) || defined(__DOXYGEN__) -#define STM32_I2S_CLOCK_ENABLED FALSE +#if !defined(STM32_CLOCK48_REQUIRED) || defined(__DOXYGEN__) +#define STM32_CLOCK48_REQUIRED TRUE #endif /** @@ -600,18 +598,11 @@ #define STM32_MCO2PRE STM32_MCO2PRE_DIV5 #endif -/** - * @brief Enables or disables the I2S clock source. - */ -#if !defined(STM32_I2S_CLOCK_ENABLED) || defined(__DOXYGEN__) -#define STM32_I2S_CLOCK_ENABLED FALSE -#endif - /** * @brief I2S clock source. */ #if !defined(STM32_I2SSRC) || defined(__DOXYGEN__) -#define STM32_I2SSRC STM32_I2CSRC_PLLI2S +#define STM32_I2SSRC STM32_I2CSRC_CKIN #endif /** @@ -714,10 +705,9 @@ #error "HSI not enabled, required by STM32_MCO2SEL" #endif -#if STM32_I2S_CLOCK_ENABLED && \ - (STM32_I2SSRC == STM32_I2CSRC_PLLI2S) && \ +#if (STM32_I2SSRC == STM32_I2CSRC_PLLI2S) && \ (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_I2S_CLOCK_ENABLED and STM32_I2SSRC" +#error "HSI not enabled, required by STM32_I2SSRC" #endif #endif /* !STM32_HSI_ENABLED */ @@ -755,10 +745,9 @@ #error "HSE not enabled, required by STM32_MCO2SEL" #endif -#if STM32_I2S_CLOCK_ENABLED && \ - (STM32_I2SSRC == STM32_I2CSRC_PLLI2S) && \ +#if (STM32_I2SSRC == STM32_I2CSRC_PLLI2S) && \ (STM32_PLLSRC == STM32_PLLSRC_HSE) -#error "HSE not enabled, required by STM32_I2S_CLOCK_ENABLED and STM32_I2SSRC" +#error "HSE not enabled, required by STM32_I2SSRC" #endif #if STM32_RTCSEL == STM32_RTCSEL_HSEDIV @@ -800,10 +789,38 @@ #endif /* !#if STM32_LSE_ENABLED */ +/** + * @brief STM32_PLLM field. + */ +#if ((STM32_PLLM_VALUE >= 2) && (STM32_PLLM_VALUE <= 63)) || \ + defined(__DOXYGEN__) +#define STM32_PLLM (STM32_PLLM_VALUE << 0) +#else +#error "invalid STM32_PLLM_VALUE value specified" +#endif + +/** + * @brief PLLs input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PLLM_VALUE) +#elif STM32_PLLSRC == STM32_PLLSRC_HSI +#define STM32_PLLCLKIN (STM32_HSICLK / STM32_PLLM_VALUE) +#else +#error "invalid STM32_PLLSRC value specified" +#endif + /* - * PLL related checks. + * PLLs input frequency range check. */ -#if STM32_USB_CLOCK_ENABLED || \ +#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) +#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/* + * PLL enable check. + */ +#if STM32_CLOCK48_REQUIRED || \ (STM32_SW == STM32_SW_PLL) || \ (STM32_MCO1SEL == STM32_MCO1SEL_PLL) || \ (STM32_MCO2SEL == STM32_MCO2SEL_PLL) || \ @@ -816,16 +833,6 @@ #define STM32_ACTIVATE_PLL FALSE #endif -/** - * @brief STM32_PLLM field. - */ -#if ((STM32_PLLM_VALUE >= 2) && (STM32_PLLM_VALUE <= 63)) || \ - defined(__DOXYGEN__) -#define STM32_PLLM (STM32_PLLM_VALUE << 0) -#else -#error "invalid STM32_PLLM_VALUE value specified" -#endif - /** * @brief STM32_PLLN field. */ @@ -854,39 +861,22 @@ /** * @brief STM32_PLLQ field. */ -#if ((STM32_PLLQ_VALUE >= 4) && (STM32_PLLQ_VALUE <= 15)) || \ +#if ((STM32_PLLQ_VALUE >= 4) && (STM32_PLLQ_VALUE <= 15)) || \ defined(__DOXYGEN__) #define STM32_PLLQ (STM32_PLLQ_VALUE << 24) #else #error "invalid STM32_PLLQ_VALUE value specified" #endif -/** - * @brief PLL input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PLLM_VALUE) -#elif STM32_PLLSRC == STM32_PLLSRC_HSI -#define STM32_PLLCLKIN (STM32_HSICLK / STM32_PLLM_VALUE) -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/* PLL input frequency range check.*/ -#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) -#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - /** * @brief PLL VCO frequency. */ -#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) +#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) /* - * PLL output frequency range check. + * PLL VCO frequency range check. */ #if (STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX) -#error STM32_PLLVCO #error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" #endif @@ -895,7 +885,9 @@ */ #define STM32_PLLCLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) -/* PLL output frequency range check.*/ +/* + * PLL output frequency range check. + */ #if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) #error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" #endif @@ -1000,14 +992,61 @@ #error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" #endif +/* + * PLLI2S enable check. + */ +#if (STM32_I2CSRC == STM32_I2CSRC_PLLI2S) || defined(__DOXYGEN__) /** - * @brief RTC frequency. + * @brief PLL activation flag. */ -#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ +#define STM32_ACTIVATE_PLLI2S TRUE +#else +#define STM32_ACTIVATE_PLLI2S FALSE +#endif + +/** + * @brief STM32_PLLI2SN field. + */ +#if ((STM32_PLLI2SN_VALUE >= 192) && (STM32_PLLI2SN_VALUE <= 432)) || \ defined(__DOXYGEN__) -#define STM32_RTCPRE (STM32_RTCPRE_VALUE << 16) +#define STM32_PLLI2SN (STM32_PLLI2SN_VALUE << 6) #else -#error "invalid STM32_RTCPRE value specified" +#error "invalid STM32_PLLI2SN_VALUE value specified" +#endif + +/** + * @brief STM32_PLLI2SR field. + */ +#if ((STM32_PLLI2SR_VALUE >= 2) && (STM32_PLLI2SR_VALUE <= 7)) || \ + defined(__DOXYGEN__) +#define STM32_PLLI2SR (STM32_PLLI2SR_VALUE << 28) +#else +#error "invalid STM32_PLLI2SR_VALUE value specified" +#endif + +/** + * @brief PLL VCO frequency. + */ +#define STM32_PLLI2SVCO (STM32_PLLCLKIN * STM32_PLLI2SN_VALUE) + +/* + * PLLI2S VCO frequency range check. + */ +#if (STM32_PLLI2SVCO < STM32_PLLVCO_MIN) || \ + (STM32_PLLI2SVCO > STM32_PLLVCO_MAX) +#error "STM32_PLLI2SVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLLI2S output clock frequency. + */ +#define STM32_PLLI2SCLKOUT (STM32_PLLI2SVCO / STM32_PLLI2SR) + +/* + * PLLI2S output frequency range check. + */ +#if STM32_PLLI2SCLKOUT > STM32_SPII2S_MAX +#error "STM32_PLLI2SCLKOUT outside acceptable range (STM32_SPII2S_MAX)" #endif /** @@ -1084,6 +1123,16 @@ #error "invalid STM32_RTCPRE value specified" #endif +/** + * @brief RTC HSE divider setting. + */ +#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_RTCPRE (STM32_RTCPRE_VALUE << 16) +#else +#error "invalid STM32_RTCPRE value specified" +#endif + /** * @brief RTC clock. */ @@ -1100,9 +1149,13 @@ #endif /** - * @brief OTG frequency. + * @brief 48MHz frequency. */ -#define STM32_OTGFSCLK (STM32_PLLVCO / STM32_PLLQ_VALUE) +#if STM32_CLOCK48_REQUIRED || defined(__DOXYGEN__) +#define STM32_PLL48CLK (STM32_PLLVCO / STM32_PLLQ_VALUE) +#else +#define STM32_PLL48CLK 0 +#endif /** * @brief Timers 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14 clock. @@ -1156,7 +1209,7 @@ /*===========================================================================*/ /* STM32 DMA support code.*/ -//#include "stm32_dma.h" +#include "stm32_dma.h" #ifdef __cplusplus extern "C" { -- cgit v1.2.3 From d5fa815855e904a5928441a45a37b798a0d618e9 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 5 Nov 2011 10:58:13 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3469 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/stm32_rcc.h | 2 +- os/hal/platforms/STM32F4xx/hal_lld.c | 13 +- os/hal/platforms/STM32F4xx/stm32_rcc.h | 887 +++++++++++++++++++++++++++++++++ os/hal/platforms/STM32L1xx/stm32_rcc.h | 2 +- 4 files changed, 895 insertions(+), 9 deletions(-) create mode 100644 os/hal/platforms/STM32F4xx/stm32_rcc.h (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/stm32_rcc.h b/os/hal/platforms/STM32F1xx/stm32_rcc.h index 2a5daaadd..aa55d4fca 100644 --- a/os/hal/platforms/STM32F1xx/stm32_rcc.h +++ b/os/hal/platforms/STM32F1xx/stm32_rcc.h @@ -373,7 +373,7 @@ /** @} */ /** - * @brief I2c peripherals specific RCC operations + * @brief I2C peripherals specific RCC operations * @{ */ /** diff --git a/os/hal/platforms/STM32F4xx/hal_lld.c b/os/hal/platforms/STM32F4xx/hal_lld.c index 74afa4bdb..ae399242b 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.c +++ b/os/hal/platforms/STM32F4xx/hal_lld.c @@ -58,11 +58,12 @@ */ void hal_lld_init(void) { - /* Reset of all peripherals.*/ -// RCC->APB1RSTR = 0xFFFFFFFF; -// RCC->APB2RSTR = 0xFFFFFFFF; -// RCC->APB1RSTR = 0; -// RCC->APB2RSTR = 0; + /* Reset of all peripherals. AHB3 is not reseted because it could have + been initialized in the board initialization file (board.c).*/ + rccResetAHB1(!0); + rccResetAHB2(!0); + rccResetAPB1(!RCC_APB1RSTR_PWRRST); + rccResetAPB2(!RCC_APB2RSTR_SYSCFGRST); /* SysTick initialization using the system clock.*/ SysTick->LOAD = STM32_HCLK / CH_FREQUENCY - 1; @@ -71,8 +72,6 @@ void hal_lld_init(void) { SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk; - - #if defined(STM32_DMA_REQUIRED) dmaInit(); #endif diff --git a/os/hal/platforms/STM32F4xx/stm32_rcc.h b/os/hal/platforms/STM32F4xx/stm32_rcc.h new file mode 100644 index 000000000..3a10e57b2 --- /dev/null +++ b/os/hal/platforms/STM32F4xx/stm32_rcc.h @@ -0,0 +1,887 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32F4xx/stm32_rcc.h + * @brief RCC helper driver header. + * @note This file requires definitions from the ST header file + * @p stm32f4xx.h. + * + * @addtogroup STM32F4xx_RCC + * @{ + */ + +#ifndef _STM32_RCC_ +#define _STM32_RCC_ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @name Generic RCC operations + * @{ + */ +/** + * @brief Enables the clock of one or more peripheral on the APB1 bus. + * + * @param[in] mask APB1 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableAPB1(mask, lp) { \ + RCC->APB1ENR |= (mask); \ + if (lp) \ + RCC->APB1LPENR |= (mask); \ +} + +/** + * @brief Disables the clock of one or more peripheral on the APB1 bus. + * + * @param[in] mask APB1 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableAPB1(mask, lp) { \ + RCC->APB1ENR &= ~(mask); \ + if (lp) \ + RCC->APB1LPENR &= ~(mask); \ +} + +/** + * @brief Resets one or more peripheral on the APB1 bus. + * + * @param[in] mask APB1 peripherals mask + * + * @api + */ +#define rccResetAPB1(mask) { \ + RCC->APB1RSTR |= (mask); \ + RCC->APB1RSTR = 0; \ +} + +/** + * @brief Enables the clock of one or more peripheral on the APB2 bus. + * + * @param[in] mask APB2 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableAPB2(mask, lp) { \ + RCC->APB2ENR |= (mask); \ + if (lp) \ + RCC->APB2LPENR |= (mask); \ +} + +/** + * @brief Disables the clock of one or more peripheral on the APB2 bus. + * + * @param[in] mask APB2 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableAPB2(mask, lp) { \ + RCC->APB2ENR &= ~(mask); \ + if (lp) \ + RCC->APB2LPENR &= ~(mask); \ +} + +/** + * @brief Resets one or more peripheral on the APB2 bus. + * + * @param[in] mask APB2 peripherals mask + * + * @api + */ +#define rccResetAPB2(mask) { \ + RCC->APB2RSTR |= (mask); \ + RCC->APB2RSTR = 0; \ +} + +/** + * @brief Enables the clock of one or more peripheral on the AHB1 bus. + * + * @param[in] mask AHB1 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableAHB1(mask, lp) { \ + RCC->AHB1ENR |= (mask); \ + if (lp) \ + RCC->AHB1LPENR |= (mask); \ +} + +/** + * @brief Disables the clock of one or more peripheral on the AHB1 bus. + * + * @param[in] mask AHB1 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableAHB1(mask, lp) { \ + RCC->AHB1ENR &= ~(mask); \ + if (lp) \ + RCC->AHB1LPENR &= ~(mask); \ +} + +/** + * @brief Resets one or more peripheral on the AHB1 bus. + * + * @param[in] mask AHB1 peripherals mask + * + * @api + */ +#define rccResetAHB1(mask) { \ + RCC->AHB1RSTR |= (mask); \ + RCC->AHB1RSTR = 0; \ +} + +/** + * @brief Enables the clock of one or more peripheral on the AHB2 bus. + * + * @param[in] mask AHB2 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableAHB2(mask, lp) { \ + RCC->AHB2ENR |= (mask); \ + if (lp) \ + RCC->AHB2LPENR |= (mask); \ +} + +/** + * @brief Disables the clock of one or more peripheral on the AHB2 bus. + * + * @param[in] mask AHB2 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableAHB2(mask, lp) { \ + RCC->AHB2ENR &= ~(mask); \ + if (lp) \ + RCC->AHB2LPENR &= ~(mask); \ +} + +/** + * @brief Resets one or more peripheral on the AHB2 bus. + * + * @param[in] mask AHB2 peripherals mask + * + * @api + */ +#define rccResetAHB2(mask) { \ + RCC->AHB2RSTR |= (mask); \ + RCC->AHB2RSTR = 0; \ +} + +/** + * @brief Enables the clock of one or more peripheral on the AHB3 (FSMC) bus. + * + * @param[in] mask AHB3 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableAHB3(mask, lp) { \ + RCC->AHB3ENR |= (mask); \ + if (lp) \ + RCC->AHB3LPENR |= (mask); \ +} + +/** + * @brief Disables the clock of one or more peripheral on the AHB3 (FSMC) bus. + * + * @param[in] mask AHB3 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableAHB3(mask, lp) { \ + RCC->AHB3ENR &= ~(mask); \ + if (lp) \ + RCC->AHB3LPENR &= ~(mask); \ +} + +/** + * @brief Resets one or more peripheral on the AHB3 (FSMC) bus. + * + * @param[in] mask AHB3 peripherals mask + * + * @api + */ +#define rccResetAHB3(mask) { \ + RCC->AHB3RSTR |= (mask); \ + RCC->AHB3RSTR = 0; \ +} +/** @} */ + +/** + * @brief ADC peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the ADC1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableADC1(lp) rccEnableAPB2(RCC_APB2ENR_ADC1EN, lp) + +/** + * @brief Disables the ADC1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableADC1(lp) rccDisableAPB2(RCC_APB2ENR_ADC1EN, lp) + +/** + * @brief Resets the ADC1 peripheral. + * + * @api + */ +#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST) + +/** + * @brief Enables the ADC2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableADC2(lp) rccEnableAPB2(RCC_APB2ENR_ADC2EN, lp) + +/** + * @brief Disables the ADC2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableADC2(lp) rccDisableAPB2(RCC_APB2ENR_ADC2EN, lp) + +/** + * @brief Resets the ADC2 peripheral. + * + * @api + */ +#define rccResetADC2() rccResetAPB2(RCC_APB2RSTR_ADC2RST) + +/** + * @brief Enables the ADC3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableADC3(lp) rccEnableAPB2(RCC_APB2ENR_ADC3EN, lp) + +/** + * @brief Disables the ADC3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableADC3(lp) rccDisableAPB2(RCC_APB2ENR_ADC3EN, lp) + +/** + * @brief Resets the ADC3 peripheral. + * + * @api + */ +#define rccResetADC3() rccResetAPB2(RCC_APB2RSTR_ADC3RST) +/** @} */ + +/** + * @brief DMA peripheral specific RCC operations + * @{ + */ +/** + * @brief Enables the DMA1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableDMA1(lp) rccEnableAHB(RCC_AHB1ENR_DMA1EN, lp) + +/** + * @brief Disables the DMA1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableDMA1(lp) rccDisableAHB(RCC_AHB1ENR_DMA1EN, lp) + +/** + * @brief Resets the DMA1 peripheral. + * + * @api + */ +#define rccResetDMA1() rccResetAHB(RCC_AHB1RSTR_DMA1RST) + +/** + * @brief Enables the DMA2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableDMA2(lp) rccEnableAHB(RCC_AHB1ENR_DMA2EN, lp) + +/** + * @brief Disables the DMA2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableDMA2(lp) rccDisableAHB(RCC_AHB1ENR_DMA2EN, lp) + +/** + * @brief Resets the DMA2 peripheral. + * + * @api + */ +#define rccResetDMA2() rccResetAHB(RCC_AHB1RSTR_DMA2RST) +/** @} */ + +/** + * @brief I2C peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the I2C1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableI2C1(lp) rccEnableAPB1(RCC_APB1ENR_I2C1EN, lp) + +/** + * @brief Disables the I2C1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableI2C1(lp) rccDisableAPB1(RCC_APB1ENR_I2C1EN, lp) + +/** + * @brief Resets the I2C1 peripheral. + * + * @api + */ +#define rccResetI2C1() rccResetAPB1(RCC_APB1RSTR_I2C1RST) + +/** + * @brief Enables the I2C2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableI2C2(lp) rccEnableAPB1(RCC_APB1ENR_I2C2EN, lp) + +/** + * @brief Disables the I2C2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableI2C2(lp) rccDisableAPB1(RCC_APB1ENR_I2C2EN, lp) + +/** + * @brief Resets the I2C2 peripheral. + * + * @api + */ +#define rccResetI2C2() rccResetAPB1(RCC_APB1RSTR_I2C2RST) + +/** + * @brief Enables the I2C3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableI2C3(lp) rccEnableAPB1(RCC_APB1ENR_I2C3EN, lp) + +/** + * @brief Disables the I2C3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableI2C3(lp) rccDisableAPB1(RCC_APB1ENR_I2C3EN, lp) + +/** + * @brief Resets the I2C3 peripheral. + * + * @api + */ +#define rccResetI2C3() rccResetAPB1(RCC_APB1RSTR_I2C3RST) +/** @} */ + +/** + * @brief SPI peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the SPI1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableSPI1(lp) rccEnableAPB2(RCC_APB2ENR_SPI1EN, lp) + +/** + * @brief Disables the SPI1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableSPI1(lp) rccDisableAPB2(RCC_APB2ENR_SPI1EN, lp) + +/** + * @brief Resets the SPI1 peripheral. + * + * @api + */ +#define rccResetSPI1() rccResetAPB2(RCC_APB2RSTR_SPI1RST) + +/** + * @brief Enables the SPI2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableSPI2(lp) rccEnableAPB1(RCC_APB1ENR_SPI2EN, lp) + +/** + * @brief Disables the SPI2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableSPI2(lp) rccDisableAPB1(RCC_APB1ENR_SPI2EN, lp) + +/** + * @brief Resets the SPI2 peripheral. + * + * @api + */ +#define rccResetSPI2() rccResetAPB1(RCC_APB1RSTR_SPI2RST) + +/** + * @brief Enables the SPI3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableSPI3(lp) rccEnableAPB1(RCC_APB1ENR_SPI3EN, lp) + +/** + * @brief Disables the SPI3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableSPI3(lp) rccDisableAPB1(RCC_APB1ENR_SPI3EN, lp) + +/** + * @brief Resets the SPI3 peripheral. + * + * @api + */ +#define rccResetSPI3() rccResetAPB1(RCC_APB1RSTR_SPI3RST) +/** @} */ + +/** + * @brief TIM peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the TIM1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM1(lp) rccEnableAPB2(RCC_APB2ENR_TIM1EN, lp) + +/** + * @brief Disables the TIM1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableTIM1(lp) rccDisableAPB2(RCC_APB2ENR_TIM1EN, lp) + +/** + * @brief Resets the TIM1 peripheral. + * + * @api + */ +#define rccResetTIM1() rccResetAPB2(RCC_APB2RSTR_TIM1RST) + +/** + * @brief Enables the TIM2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM2(lp) rccEnableAPB1(RCC_APB1ENR_TIM2EN, lp) + +/** + * @brief Disables the TIM2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableTIM2(lp) rccDisableAPB1(RCC_APB1ENR_TIM2EN, lp) + +/** + * @brief Resets the TIM2 peripheral. + * + * @api + */ +#define rccResetTIM2() rccResetAPB1(RCC_APB1RSTR_TIM2RST) + +/** + * @brief Enables the TIM3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM3(lp) rccEnableAPB1(RCC_APB1ENR_TIM3EN, lp) + +/** + * @brief Disables the TIM3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableTIM3(lp) rccDisableAPB1(RCC_APB1ENR_TIM3EN, lp) + +/** + * @brief Resets the TIM3 peripheral. + * + * @api + */ +#define rccResetTIM3() rccResetAPB1(RCC_APB1RSTR_TIM3RST) + +/** + * @brief Enables the TIM4 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM4(lp) rccEnableAPB1(RCC_APB1ENR_TIM4EN, lp) + +/** + * @brief Disables the TIM4 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableTIM4(lp) rccDisableAPB1(RCC_APB1ENR_TIM4EN, lp) + +/** + * @brief Resets the TIM4 peripheral. + * + * @api + */ +#define rccResetTIM4() rccResetAPB1(RCC_APB1RSTR_TIM4RST) + +/** + * @brief Enables the TIM5 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM5(lp) rccEnableAPB1(RCC_APB1ENR_TIM5EN, lp) + +/** + * @brief Disables the TIM5 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableTIM5(lp) rccDisableAPB1(RCC_APB1ENR_TIM5EN, lp) + +/** + * @brief Resets the TIM5 peripheral. + * + * @api + */ +#define rccResetTIM5() rccResetAPB1(RCC_APB1RSTR_TIM5RST) + +/** + * @brief Enables the TIM8 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM8(lp) rccEnableAPB2(RCC_APB2ENR_TIM8EN, lp) + +/** + * @brief Disables the TIM8 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableTIM8(lp) rccDisableAPB2(RCC_APB2ENR_TIM8EN, lp) + +/** + * @brief Resets the TIM8 peripheral. + * + * @api + */ +#define rccResetTIM8() rccResetAPB2(RCC_APB2RSTR_TIM8RST) +/** @} */ + +/** + * @brief USART/UART peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the USART1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUSART1(lp) rccEnableAPB2(RCC_APB2ENR_USART1EN, lp) + +/** + * @brief Disables the USART1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUSART1(lp) rccDisableAPB2(RCC_APB2ENR_USART1EN, lp) + +/** + * @brief Resets the USART1 peripheral. + * + * @api + */ +#define rccResetUSART1() rccResetAPB2(RCC_APB2RSTR_USART1RST) + +/** + * @brief Enables the USART2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUSART2(lp) rccEnableAPB1(RCC_APB1ENR_USART2EN, lp) + +/** + * @brief Disables the USART2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUSART2(lp) rccDisableAPB1(RCC_APB1ENR_USART2EN, lp) + +/** + * @brief Resets the USART2 peripheral. + * + * @api + */ +#define rccResetUSART2() rccResetAPB1(RCC_APB1RSTR_USART2RST) + +/** + * @brief Enables the USART3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUSART3(lp) rccEnableAPB1(RCC_APB1ENR_USART3EN, lp) + +/** + * @brief Disables the USART3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUSART3(lp) rccDisableAPB1(RCC_APB1ENR_USART3EN, lp) + +/** + * @brief Resets the USART3 peripheral. + * + * @api + */ +#define rccResetUSART3() rccResetAPB1(RCC_APB1RSTR_USART3RST) + +/** + * @brief Enables the USART6 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUSART6(lp) rccEnableAPB2(RCC_APB2ENR_USART6EN, lp) + +/** + * @brief Disables the USART6 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUSART6(lp) rccDisableAPB2(RCC_APB2ENR_USART6EN, lp) + +/** + * @brief Enables the UART4 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUART4(lp) rccEnableAPB1(RCC_APB1ENR_UART4EN, lp) + +/** + * @brief Disables the UART4 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUART4(lp) rccDisableAPB1(RCC_APB1ENR_UART4EN, lp) + +/** + * @brief Resets the UART4 peripheral. + * + * @api + */ +#define rccResetUART4() rccResetAPB1(RCC_APB1RSTR_UART4RST) + +/** + * @brief Enables the UART5 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUART5(lp) rccEnableAPB1(RCC_APB1ENR_UART5EN, lp) + +/** + * @brief Disables the UART5 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUART5(lp) rccDisableAPB1(RCC_APB1ENR_UART5EN, lp) + +/** + * @brief Resets the UART5 peripheral. + * + * @api + */ +#define rccResetUART5() rccResetAPB1(RCC_APB1RSTR_UART5RST) + +/** + * @brief Resets the USART6 peripheral. + * + * @api + */ +#define rccResetUSART6() rccResetAPB2(RCC_APB2RSTR_USART6RST) +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif + +#endif /* _STM32_RCC_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32L1xx/stm32_rcc.h b/os/hal/platforms/STM32L1xx/stm32_rcc.h index e2460a41f..9ffcc07b4 100644 --- a/os/hal/platforms/STM32L1xx/stm32_rcc.h +++ b/os/hal/platforms/STM32L1xx/stm32_rcc.h @@ -237,7 +237,7 @@ /** @} */ /** - * @brief I2c peripherals specific RCC operations + * @brief I2C peripherals specific RCC operations * @{ */ /** -- cgit v1.2.3 From cdf83ce254198264167a1102c9c615b141b3c1dd Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 5 Nov 2011 14:40:48 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3472 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/GPIOv2/pal_lld.c | 9 ++++++++- os/hal/platforms/STM32F4xx/hal_lld.h | 7 ++++--- os/hal/platforms/STM32F4xx/stm32_dma.h | 2 +- os/hal/platforms/STM32F4xx/stm32f4xx.h | 4 +++- os/hal/platforms/STM32L1xx/stm32l1xx.h | 2 ++ 5 files changed, 18 insertions(+), 6 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/GPIOv2/pal_lld.c b/os/hal/platforms/STM32/GPIOv2/pal_lld.c index bde24db25..affdaaedb 100644 --- a/os/hal/platforms/STM32/GPIOv2/pal_lld.c +++ b/os/hal/platforms/STM32/GPIOv2/pal_lld.c @@ -40,7 +40,14 @@ RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | \ RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | \ RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN | \ - RCC_AHB1ENR_GPIOIEN) + RCC_AHB1ENR_GPIOIEN) +#define AHB1_LPEN_MASK AHB1_EN_MASK +#elif defined(STM32F4XX) +#define AHB1_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) #define AHB1_LPEN_MASK AHB1_EN_MASK #else #error "missing or usupported platform for GPIOv2 PAL driver" diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index 337b67b55..ca46e5287 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -781,13 +781,13 @@ #error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" #endif -#else /* !#if STM32_LSE_ENABLED */ +#else /* !STM32_LSE_ENABLED */ #if STM32_RTCSEL == STM32_RTCSEL_LSE #error "LSE not enabled, required by STM32_RTCSEL" #endif -#endif /* !#if STM32_LSE_ENABLED */ +#endif /* !STM32_LSE_ENABLED */ /** * @brief STM32_PLLM field. @@ -1208,8 +1208,9 @@ /* External declarations. */ /*===========================================================================*/ -/* STM32 DMA support code.*/ +/* STM32 DMA and RCC helpers.*/ #include "stm32_dma.h" +#include "stm32_rcc.h" #ifdef __cplusplus extern "C" { diff --git a/os/hal/platforms/STM32F4xx/stm32_dma.h b/os/hal/platforms/STM32F4xx/stm32_dma.h index a1266fec4..327b1bc55 100644 --- a/os/hal/platforms/STM32F4xx/stm32_dma.h +++ b/os/hal/platforms/STM32F4xx/stm32_dma.h @@ -155,7 +155,7 @@ * @brief STM32 DMA stream descriptor structure. */ typedef struct { - DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ + DMA_Stream_TypeDef *stream; /**< @brief Associated DMA channel. */ volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */ uint8_t ishift; /**< @brief Bits offset in xIFCR register. */ diff --git a/os/hal/platforms/STM32F4xx/stm32f4xx.h b/os/hal/platforms/STM32F4xx/stm32f4xx.h index 60dc0622a..ccc1a3565 100644 --- a/os/hal/platforms/STM32F4xx/stm32f4xx.h +++ b/os/hal/platforms/STM32F4xx/stm32f4xx.h @@ -646,7 +646,8 @@ typedef struct /** * @brief General Purpose I/O */ - +/* CHIBIOS FIX */ +#if 0 typedef struct { __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ @@ -660,6 +661,7 @@ typedef struct __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ } GPIO_TypeDef; +#endif /** * @brief System configuration controller diff --git a/os/hal/platforms/STM32L1xx/stm32l1xx.h b/os/hal/platforms/STM32L1xx/stm32l1xx.h index 48be82360..9723158c8 100644 --- a/os/hal/platforms/STM32L1xx/stm32l1xx.h +++ b/os/hal/platforms/STM32L1xx/stm32l1xx.h @@ -411,6 +411,7 @@ typedef struct /** * @brief General Purpose IO */ +/* CHIBIOS FIX */ #if 0 typedef struct { @@ -429,6 +430,7 @@ typedef struct __IO uint32_t AFR[2]; } GPIO_TypeDef; #endif +#endif /** * @brief SysTem Configuration -- cgit v1.2.3 From 9e51498e1196b28e5c073a7505df2ae08f05b59a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 6 Nov 2011 09:39:57 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3474 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/GPIOv2/pal_lld.c | 2 +- os/hal/platforms/STM32F4xx/hal_lld.c | 15 ++++----------- 2 files changed, 5 insertions(+), 12 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/GPIOv2/pal_lld.c b/os/hal/platforms/STM32/GPIOv2/pal_lld.c index affdaaedb..728523719 100644 --- a/os/hal/platforms/STM32/GPIOv2/pal_lld.c +++ b/os/hal/platforms/STM32/GPIOv2/pal_lld.c @@ -99,7 +99,7 @@ void _pal_lld_init(const PALConfig *config) { */ #if defined(STM32L1XX_MD) rccEnableAHB(AHB_EN_MASK, TRUE); -#elif defined(STM32F2XX) +#elif defined(STM32F2XX) || defined(STM32F4XX) RCC->AHB1ENR |= AHB1_EN_MASK; RCC->AHB1LPENR |= AHB1_LPEN_MASK; #endif diff --git a/os/hal/platforms/STM32F4xx/hal_lld.c b/os/hal/platforms/STM32F4xx/hal_lld.c index ae399242b..bd88ad2da 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.c +++ b/os/hal/platforms/STM32F4xx/hal_lld.c @@ -84,10 +84,6 @@ void hal_lld_init(void) { * * @special */ -#if defined(STM32F2XX) || defined(__DOXYGEN__) -/** - * @brief Clocks and internal voltage initialization. - */ void stm32_clock_init(void) { #if !STM32_NO_INIT @@ -135,7 +131,7 @@ void stm32_clock_init(void) { #if STM32_ACTIVATE_PLLI2S /* PLLI2S activation.*/ - RCC->PLLI2SCFGR = STM32_PLI2SR_VALUE | STM32_PLLI2SN_VALUE; + RCC->PLLI2SCFGR = STM32_PLLI2SR_VALUE | STM32_PLLI2SN_VALUE; RCC->CR |= RCC_CR_PLLI2SON; while (!(RCC->CR & RCC_CR_PLLI2SRDY)) ; /* Waits until PLLI2S is stable. */ @@ -145,19 +141,16 @@ void stm32_clock_init(void) { RCC->CFGR |= STM32_MCO2PRE | STM32_MCO2SEL | STM32_MCO1PRE | STM32_MCO1SEL | STM32_RTCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; - /* Flash setup. */ + /* Flash setup.*/ FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN | STM32_FLASHBITS; - /* Switching to the configured clock source if it is different from MSI. */ + /* Switching to the configured clock source if it is different from MSI.*/ #if (STM32_SW != STM32_SW_HSI) - RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ + RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) ; #endif #endif /* STM32_NO_INIT */ } -#else -void stm32_clock_init(void) {} -#endif /** @} */ -- cgit v1.2.3 From 2848e99c07e4174412dd0879046b9c3f82961695 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 6 Nov 2011 12:25:34 +0000 Subject: STM32F4 support working, most device drivers still to test, report added. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3475 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/serial_lld.c | 4 ++++ os/hal/platforms/STM32F4xx/hal_lld.c | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/serial_lld.c b/os/hal/platforms/STM32/serial_lld.c index ce412dedb..d9d0836fd 100644 --- a/os/hal/platforms/STM32/serial_lld.c +++ b/os/hal/platforms/STM32/serial_lld.c @@ -90,7 +90,11 @@ static void usart_init(SerialDriver *sdp, const SerialConfig *config) { /* * Baud rate setting. */ +#if STM32_HAS_USART6 + if ((sdp->usart == USART1) || (sdp->usart == USART6)) +#else if (sdp->usart == USART1) +#endif u->BRR = STM32_PCLK2 / config->sc_speed; else u->BRR = STM32_PCLK1 / config->sc_speed; diff --git a/os/hal/platforms/STM32F4xx/hal_lld.c b/os/hal/platforms/STM32F4xx/hal_lld.c index bd88ad2da..5033c41c8 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.c +++ b/os/hal/platforms/STM32F4xx/hal_lld.c @@ -142,7 +142,8 @@ void stm32_clock_init(void) { STM32_RTCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; /* Flash setup.*/ - FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN | STM32_FLASHBITS; + FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN | + STM32_FLASHBITS; /* Switching to the configured clock source if it is different from MSI.*/ #if (STM32_SW != STM32_SW_HSI) -- cgit v1.2.3 From bfcc14cb5cb5fdce3d3cb1ae29e250be4252da80 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 6 Nov 2011 14:56:31 +0000 Subject: Added support for USART6 to STM32 serial driver, fixed bug 3434094. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3477 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/serial_lld.c | 50 ++++++++++++++++++++++++++++++++++++- os/hal/platforms/STM32/serial_lld.h | 33 ++++++++++++++++++++---- 2 files changed, 77 insertions(+), 6 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/serial_lld.c b/os/hal/platforms/STM32/serial_lld.c index d9d0836fd..c5dda231b 100644 --- a/os/hal/platforms/STM32/serial_lld.c +++ b/os/hal/platforms/STM32/serial_lld.c @@ -60,6 +60,11 @@ SerialDriver SD4; SerialDriver SD5; #endif +/** @brief USART6 serial driver identifier.*/ +#if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__) +SerialDriver SD6; +#endif + /*===========================================================================*/ /* Driver local variables. */ /*===========================================================================*/ @@ -127,7 +132,7 @@ static void usart_deinit(USART_TypeDef *u) { #if STM32_SERIAL_USE_USART1 || STM32_SERIAL_USE_USART2 || \ STM32_SERIAL_USE_USART3 || STM32_SERIAL_USE_UART4 || \ - USE_STM32_USART5 + STM32_SERIAL_USE_UART5 || STM32_SERIAL_USE_USART6 /** * @brief Error handling routine. * @@ -241,6 +246,14 @@ static void notify5(GenericQueue *qp) { } #endif +#if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__) +static void notify6(GenericQueue *qp) { + + (void)qp; + USART6->CR1 |= USART_CR1_TXEIE; +} +#endif + /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ @@ -325,6 +338,22 @@ CH_IRQ_HANDLER(UART5_IRQHandler) { } #endif +#if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__) +/** + * @brief USART1 interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(USART6_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + serve_interrupt(&SD6); + + CH_IRQ_EPILOGUE(); +} +#endif + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -360,6 +389,11 @@ void sd_lld_init(void) { sdObjectInit(&SD5, NULL, notify5); SD5.usart = UART5; #endif + +#if STM32_SERIAL_USE_USART6 + sdObjectInit(&SD6, NULL, notify6); + SD6.usart = USART6; +#endif } /** @@ -412,6 +446,13 @@ void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) { NVICEnableVector(UART5_IRQn, CORTEX_PRIORITY_MASK(STM32_SERIAL_UART5_PRIORITY)); } +#endif +#if STM32_SERIAL_USE_USART6 + if (&SD6 == sdp) { + rccEnableUSART6(FALSE); + NVICEnableVector(USART6_IRQn, + CORTEX_PRIORITY_MASK(STM32_SERIAL_USART6_PRIORITY)); + } #endif } usart_init(sdp, config); @@ -464,6 +505,13 @@ void sd_lld_stop(SerialDriver *sdp) { NVICDisableVector(UART5_IRQn); return; } +#endif +#if STM32_SERIAL_USE_USART6 + if (&SD6 == sdp) { + rccDisableUSART6(FALSE); + NVICDisableVector(USART6_IRQn); + return; + } #endif } } diff --git a/os/hal/platforms/STM32/serial_lld.h b/os/hal/platforms/STM32/serial_lld.h index ceeccff67..fdd168201 100644 --- a/os/hal/platforms/STM32/serial_lld.h +++ b/os/hal/platforms/STM32/serial_lld.h @@ -42,7 +42,7 @@ /** * @brief USART1 driver enable switch. * @details If set to @p TRUE the support for USART1 is included. - * @note The default is @p FALSE. + * @note The default is @p TRUE. */ #if !defined(STM32_SERIAL_USE_USART1) || defined(__DOXYGEN__) #define STM32_SERIAL_USE_USART1 TRUE @@ -60,7 +60,7 @@ /** * @brief USART3 driver enable switch. * @details If set to @p TRUE the support for USART3 is included. - * @note The default is @p FALSE. + * @note The default is @p TRUE. */ #if !defined(STM32_SERIAL_USE_USART3) || defined(__DOXYGEN__) #define STM32_SERIAL_USE_USART3 TRUE @@ -69,7 +69,7 @@ /** * @brief UART4 driver enable switch. * @details If set to @p TRUE the support for UART4 is included. - * @note The default is @p FALSE. + * @note The default is @p TRUE. */ #if !defined(STM32_SERIAL_USE_UART4) || defined(__DOXYGEN__) #define STM32_SERIAL_USE_UART4 TRUE @@ -78,12 +78,21 @@ /** * @brief UART5 driver enable switch. * @details If set to @p TRUE the support for UART5 is included. - * @note The default is @p FALSE. + * @note The default is @p TRUE. */ #if !defined(STM32_SERIAL_USE_UART5) || defined(__DOXYGEN__) #define STM32_SERIAL_USE_UART5 TRUE #endif +/** + * @brief USART6 driver enable switch. + * @details If set to @p TRUE the support for USART6 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_SERIAL_USE_USART6) || defined(__DOXYGEN__) +#define STM32_SERIAL_USE_USART6 TRUE +#endif + /** * @brief USART1 interrupt priority level setting. */ @@ -119,6 +128,13 @@ #define STM32_SERIAL_UART5_PRIORITY 12 #endif +/** + * @brief USART6 interrupt priority level setting. + */ +#if !defined(STM32_SERIAL_USART6_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SERIAL_USART6_PRIORITY 12 +#endif + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ @@ -143,9 +159,13 @@ #error "UART5 not present in the selected device" #endif +#if STM32_SERIAL_USE_USART6 && !STM32_HAS_USART6 +#error "USART6 not present in the selected device" +#endif + #if !STM32_SERIAL_USE_USART1 && !STM32_SERIAL_USE_USART2 && \ !STM32_SERIAL_USE_USART3 && !STM32_SERIAL_USE_UART4 && \ - !STM32_SERIAL_USE_UART5 + !STM32_SERIAL_USE_UART5 && !STM32_SERIAL_USE_USART6 #error "SERIAL driver activated but no USART/UART peripheral assigned" #endif @@ -230,6 +250,9 @@ extern SerialDriver SD4; #if STM32_SERIAL_USE_UART5 && !defined(__DOXYGEN__) extern SerialDriver SD5; #endif +#if STM32_SERIAL_USE_USART6 && !defined(__DOXYGEN__) +extern SerialDriver SD6; +#endif #ifdef __cplusplus extern "C" { -- cgit v1.2.3 From d3adba6d993ef0c15e5b8d33297d3cd108e2f8b6 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 6 Nov 2011 15:27:54 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3478 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/stm32_dma.c | 66 ++++++++++++++------------------ os/hal/platforms/STM32F4xx/stm32_dma.h | 69 +++++++++++++++++++++++++++++++--- 2 files changed, 92 insertions(+), 43 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/stm32_dma.c b/os/hal/platforms/STM32F4xx/stm32_dma.c index e35d93543..dd5a92afb 100644 --- a/os/hal/platforms/STM32F4xx/stm32_dma.c +++ b/os/hal/platforms/STM32F4xx/stm32_dma.c @@ -22,7 +22,7 @@ * @file STM32F4xx/stm32_dma.c * @brief Enhanced DMA helper driver code. * - * @addtogroup STM32_DMA + * @addtogroup STM32F4xx_DMA * @details DMA sharing helper driver. In the STM32 the DMA streams are a * shared resource, this driver allows to allocate and free DMA * streams at runtime in order to allow all the other device @@ -76,22 +76,22 @@ * instead: @p STM32_DMA1_STREAM0, @p STM32_DMA1_STREAM1 etc. */ const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { - {0, DMA1, DMA1_Stream0, &DMA1->LIFCR, 0}, - {1, DMA1, DMA1_Stream1, &DMA1->LIFCR, 6}, - {2, DMA1, DMA1_Stream2, &DMA1->LIFCR, 16}, - {3, DMA1, DMA1_Stream3, &DMA1->LIFCR, 22}, - {4, DMA1, DMA1_Stream4, &DMA1->HIFCR, 0}, - {5, DMA1, DMA1_Stream5, &DMA1->HIFCR, 6}, - {6, DMA1, DMA1_Stream6, &DMA1->HIFCR, 16}, - {7, DMA1, DMA1_Stream7, &DMA1->HIFCR, 22}, - {8, DMA2, DMA2_Stream0, &DMA2->LIFCR, 0}, - {9, DMA2, DMA2_Stream1, &DMA2->LIFCR, 6}, - {10, DMA2, DMA2_Stream2, &DMA2->LIFCR, 16}, - {11, DMA2, DMA2_Stream3, &DMA2->LIFCR, 22}, - {12, DMA2, DMA2_Stream4, &DMA2->HIFCR, 0}, - {13, DMA2, DMA2_Stream5, &DMA2->HIFCR, 6}, - {14, DMA2, DMA2_Stream6, &DMA2->HIFCR, 16}, - {15, DMA2, DMA2_Stream7, &DMA2->HIFCR, 22}, + {DMA1_Stream0, &DMA1->LIFCR, 0, 0, DMA1_Stream0_IRQn}, + {DMA1_Stream1, &DMA1->LIFCR, 6, 1, DMA1_Stream1_IRQn}, + {DMA1_Stream2, &DMA1->LIFCR, 16, 2, DMA1_Stream2_IRQn}, + {DMA1_Stream3, &DMA1->LIFCR, 22, 3, DMA1_Stream3_IRQn}, + {DMA1_Stream4, &DMA1->HIFCR, 0, 4, DMA1_Stream4_IRQn}, + {DMA1_Stream5, &DMA1->HIFCR, 6, 5, DMA1_Stream5_IRQn}, + {DMA1_Stream6, &DMA1->HIFCR, 16, 6, DMA1_Stream6_IRQn}, + {DMA1_Stream7, &DMA1->HIFCR, 22, 7, DMA1_Stream7_IRQn}, + {DMA2_Stream0, &DMA2->LIFCR, 0, 8, DMA2_Stream0_IRQn}, + {DMA2_Stream1, &DMA2->LIFCR, 6, 9, DMA2_Stream1_IRQn}, + {DMA2_Stream2, &DMA2->LIFCR, 16, 10, DMA2_Stream2_IRQn}, + {DMA2_Stream3, &DMA2->LIFCR, 22, 11, DMA2_Stream3_IRQn}, + {DMA2_Stream4, &DMA2->HIFCR, 0, 12, DMA2_Stream4_IRQn}, + {DMA2_Stream5, &DMA2->HIFCR, 6, 13, DMA2_Stream5_IRQn}, + {DMA2_Stream6, &DMA2->HIFCR, 16, 14, DMA2_Stream6_IRQn}, + {DMA2_Stream7, &DMA2->HIFCR, 22, 15, DMA2_Stream7_IRQn}, }; /*===========================================================================*/ @@ -102,8 +102,8 @@ const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { * @brief DMA ISR redirector type. */ typedef struct { - stm32_dmaisr_t dma_func; - void *dma_param; + stm32_dmaisr_t dma_func; /**< @brief DMA callback function. */ + void *dma_param; /**< @brief DMA callback parameter. */ } dma_isr_redir_t; /** @@ -467,7 +467,7 @@ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, chDbgCheck(dmastp != NULL, "dmaAllocate"); /* Checks if the stream is already taken.*/ - if ((dma_streams_mask & dmastp->mask) != 0) + if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0) return TRUE; /* Marks the stream as allocated.*/ @@ -476,14 +476,10 @@ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, dma_streams_mask |= (1 << dmastp->selfindex); /* Enabling DMA clocks required by the current streams set.*/ - if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) { - RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; - RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA1LPEN; - } - if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) { - RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; - RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA2LPEN; - } + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) + rccEnableDMA1(FALSE); + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) + rccEnableDMA2(FALSE); /* Putting the stream in a safe state.*/ dmaStreamDisable(dmastp); @@ -516,7 +512,7 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { chDbgCheck(dmastp != NULL, "dmaRelease"); /* Check if the streams is not taken.*/ - chDbgAssert((dma_streams_mask & dmastp->mask) != 0, + chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0, "dmaRelease(), #1", "not allocated"); /* Disables the associated IRQ vector.*/ @@ -526,14 +522,10 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { dma_streams_mask &= ~(1 << dmastp->selfindex); /* Shutting down clocks that are no more required, if any.*/ - if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) { - RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA1EN; - RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA1LPEN; - } - if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) { - RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA2EN; - RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA2LPEN; - } + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) + rccDisableDMA1(FALSE); + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) + rccDisableDMA2(FALSE); } #endif /* STM32_DMA_REQUIRED */ diff --git a/os/hal/platforms/STM32F4xx/stm32_dma.h b/os/hal/platforms/STM32F4xx/stm32_dma.h index 327b1bc55..9aaadb681 100644 --- a/os/hal/platforms/STM32F4xx/stm32_dma.h +++ b/os/hal/platforms/STM32F4xx/stm32_dma.h @@ -21,8 +21,8 @@ /** * @file STM32F4xx/stm32_dma.h * @brief Enhanced-DMA helper driver header. - * @note This file requires definitions from the ST STM32F2xx header file - * stm32f2xx.h. + * @note This file requires definitions from the ST STM32F4xx header file + * stm32f4xx.h. * * @addtogroup STM32_DMA * @{ @@ -95,7 +95,7 @@ /** @} */ /** - * @name CR register constants only found in STM32F2xx + * @name CR register constants only found in STM32F2xx/STM32F4xx */ #define STM32_DMA_CR_DMEIE DMA_SxCR_DMEIE #define STM32_DMA_CR_PFCTRL DMA_SxCR_PFCTRL @@ -155,7 +155,7 @@ * @brief STM32 DMA stream descriptor structure. */ typedef struct { - DMA_Stream_TypeDef *stream; /**< @brief Associated DMA channel. */ + DMA_Stream_TypeDef *stream; /**< @brief Associated DMA stream. */ volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */ uint8_t ishift; /**< @brief Bits offset in xIFCR register. */ @@ -179,6 +179,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /** * @brief Associates a peripheral data register to a DMA stream. * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @param[in] addr value to be written in the PAR register @@ -192,6 +194,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /** * @brief Associates a memory destination to a DMA stream. * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @param[in] addr value to be written in the M0AR register @@ -218,6 +222,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /** * @brief Sets the number of transfers to be performed. * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @param[in] size value to be written in the CNDTR register @@ -231,6 +237,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /** * @brief Returns the number of transfers to be performed. * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @return The number of transfers to be performed. @@ -242,6 +250,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /** * @brief Programs the stream mode settings. * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @param[in] mode value to be written in the CR register @@ -255,6 +265,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /** * @brief Programs the stream FIFO settings. * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @param[in] mode value to be written in the FCR register @@ -268,18 +280,22 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /** * @brief DMA stream enable. * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). * - * @param[in] dmachp pointer to a stm32_dma_stream_t structure + * @param[in] dmastp pointer to a stm32_dma_stream_t structure * * @special */ -#define dmaStreamEnable(dmachp) { \ +#define dmaStreamEnable(dmastp) { \ (dmastp)->stream->CR |= STM32_DMA_CR_EN; \ } /** * @brief DMA stream disable. * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @@ -292,6 +308,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /** * @brief DMA stream interrupt sources clear. * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @@ -301,6 +319,45 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \ } +/** + * @brief Starts a memory to memory operation using the specified stream. + * @note The default transfer data mode is "byte to byte" but it can be + * changed by specifying extra options in the @p mode parameter. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] mode value to be written in the CCR register, this value + * is implicitly ORed with: + * - @p STM32_DMA_CR_MINC + * - @p STM32_DMA_CR_PINC + * - @p STM32_DMA_CR_DIR_M2M + * - @p STM32_DMA_CR_EN + * . + * @param[in] src source address + * @param[in] dst destination address + * @param[in] n number of data units to copy + */ +#define dmaStartMemCopy(dmastp, mode, src, dst, n) { \ + dmaStreamSetPeripheral(dmastp, src); \ + dmaStreamSetMemory0(dmastp, dst); \ + dmaStreamGetTransactionSize(dmastp, n); \ + dmaStreamSetMode(dmastp, (mode) | \ + STM32_DMA_CR_MINC | STM32_DMA_CR_PINC | \ + STM32_DMA_CR_DIR_M2M | STM32_DMA_CR_EN); \ +} + +/** + * @brief Polled wait for DMA transfer end. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + */ +#define dmaWaitCompletion(dmastp) \ + while (((dmastp)->stream->CNDTR > 0) && \ + ((dmastp)->stream->CCR & STM32_DMA_CR_EN)) + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ -- cgit v1.2.3 From ed26815f85668f5eedc6c28581e8900f037cbba1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 10 Nov 2011 17:54:41 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3481 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/ext.h | 5 + os/hal/platforms/STM32/can_lld.h | 5 + os/hal/platforms/STM32/ext_lld.h | 5 + os/hal/platforms/STM32/gpt_lld.h | 5 + os/hal/platforms/STM32/i2c_lld.h | 6 + os/hal/platforms/STM32/icu_lld.h | 5 + os/hal/platforms/STM32/mac_lld.h | 5 + os/hal/platforms/STM32/pwm_lld.h | 5 + os/hal/platforms/STM32/sdc_lld.h | 5 + os/hal/platforms/STM32/serial_lld.h | 5 + os/hal/platforms/STM32/spi_lld.c | 183 ++++++++++++++----------- os/hal/platforms/STM32/spi_lld.h | 136 ++++++++++++++++-- os/hal/platforms/STM32/uart_lld.h | 5 + os/hal/platforms/STM32F1xx/adc_lld.h | 5 + os/hal/platforms/STM32F1xx/hal_lld_f100.h | 5 + os/hal/platforms/STM32F1xx/hal_lld_f103.h | 6 + os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h | 5 + os/hal/platforms/STM32F1xx/stm32_dma.h | 61 +++++++-- os/hal/platforms/STM32F4xx/hal_lld.h | 74 +++++++--- os/hal/platforms/STM32F4xx/platform.mk | 4 +- os/hal/platforms/STM32F4xx/stm32_dma.c | 4 +- os/hal/platforms/STM32F4xx/stm32_dma.h | 92 ++++++++++--- os/hal/platforms/STM32F4xx/stm32_rcc.h | 13 +- os/hal/platforms/STM32L1xx/adc_lld.h | 5 + os/hal/platforms/STM32L1xx/hal_lld.h | 5 + os/hal/platforms/STM32L1xx/stm32_dma.h | 51 ++++++- os/hal/platforms/STM32L1xx/stm32l1xx.h | 1 - 27 files changed, 546 insertions(+), 160 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/ext.h b/os/hal/include/ext.h index 5d904cf4e..852c3d07f 100644 --- a/os/hal/include/ext.h +++ b/os/hal/include/ext.h @@ -81,6 +81,10 @@ typedef struct EXTDriver EXTDriver; /* Driver macros. */ /*===========================================================================*/ +/** + * @name Macro Functions + * @{ + */ /** * @brief Enables an EXT channel. * @@ -100,6 +104,7 @@ typedef struct EXTDriver EXTDriver; * @iclass */ #define extChannelDisableI(extp, channel) ext_lld_channel_disable(extp, channel) +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/platforms/STM32/can_lld.h b/os/hal/platforms/STM32/can_lld.h index a9a086e5b..d99897935 100644 --- a/os/hal/platforms/STM32/can_lld.h +++ b/os/hal/platforms/STM32/can_lld.h @@ -74,6 +74,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ /** * @brief CAN1 driver enable switch. * @details If set to @p TRUE the support for ADC1 is included. @@ -89,6 +93,7 @@ #if !defined(STM32_CAN_CAN1_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_CAN_CAN1_IRQ_PRIORITY 11 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ diff --git a/os/hal/platforms/STM32/ext_lld.h b/os/hal/platforms/STM32/ext_lld.h index 753b12608..1a6102057 100644 --- a/os/hal/platforms/STM32/ext_lld.h +++ b/os/hal/platforms/STM32/ext_lld.h @@ -77,6 +77,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ /** * @brief EXTI0 interrupt priority level setting. */ @@ -174,6 +178,7 @@ #if !defined(STM32_EXT_EXTI22_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_EXT_EXTI22_IRQ_PRIORITY 6 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ diff --git a/os/hal/platforms/STM32/gpt_lld.h b/os/hal/platforms/STM32/gpt_lld.h index ef00c23a9..f61c5d030 100644 --- a/os/hal/platforms/STM32/gpt_lld.h +++ b/os/hal/platforms/STM32/gpt_lld.h @@ -39,6 +39,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ /** * @brief GPTD1 driver enable switch. * @details If set to @p TRUE the support for GPTD1 is included. @@ -134,6 +138,7 @@ #if !defined(STM32_GPT_TIM8_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_GPT_TIM8_IRQ_PRIORITY 7 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ diff --git a/os/hal/platforms/STM32/i2c_lld.h b/os/hal/platforms/STM32/i2c_lld.h index b66ba5d6a..81a9f62dc 100644 --- a/os/hal/platforms/STM32/i2c_lld.h +++ b/os/hal/platforms/STM32/i2c_lld.h @@ -37,6 +37,11 @@ /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ /** * @brief Switch between callback based and synchronouse driver. * @note The default is synchronouse. @@ -98,6 +103,7 @@ #if !defined(STM32_I2C_I2C2_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_I2C_I2C2_IRQ_PRIORITY 0xA0 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ diff --git a/os/hal/platforms/STM32/icu_lld.h b/os/hal/platforms/STM32/icu_lld.h index 4c440b868..3156023eb 100644 --- a/os/hal/platforms/STM32/icu_lld.h +++ b/os/hal/platforms/STM32/icu_lld.h @@ -39,6 +39,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ /** * @brief ICUD1 driver enable switch. * @details If set to @p TRUE the support for ICUD1 is included. @@ -134,6 +138,7 @@ #if !defined(STM32_ICU_TIM8_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_ICU_TIM8_IRQ_PRIORITY 7 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ diff --git a/os/hal/platforms/STM32/mac_lld.h b/os/hal/platforms/STM32/mac_lld.h index 3e00639cc..d6eb4bfc4 100644 --- a/os/hal/platforms/STM32/mac_lld.h +++ b/os/hal/platforms/STM32/mac_lld.h @@ -114,6 +114,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ /** * @brief Number of available transmit buffers. */ @@ -134,6 +138,7 @@ #if !defined(MAC_BUFFERS_SIZE) || defined(__DOXYGEN__) #define MAC_BUFFERS_SIZE 1518 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ diff --git a/os/hal/platforms/STM32/pwm_lld.h b/os/hal/platforms/STM32/pwm_lld.h index d084b3dc7..78e411592 100644 --- a/os/hal/platforms/STM32/pwm_lld.h +++ b/os/hal/platforms/STM32/pwm_lld.h @@ -74,6 +74,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ /** * @brief If advanced timer features switch. * @details If set to @p TRUE the advanced features for TIM1 and TIM8 are @@ -179,6 +183,7 @@ #if !defined(STM32_PWM_TIM8_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_PWM_TIM8_IRQ_PRIORITY 7 #endif +/** @} */ /*===========================================================================*/ /* Configuration checks. */ diff --git a/os/hal/platforms/STM32/sdc_lld.h b/os/hal/platforms/STM32/sdc_lld.h index eea76dadd..f670e6bbe 100644 --- a/os/hal/platforms/STM32/sdc_lld.h +++ b/os/hal/platforms/STM32/sdc_lld.h @@ -40,6 +40,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ /** * @brief SDIO data timeout in SDIO clock cycles. */ @@ -67,6 +71,7 @@ #if !defined(STM32_SDC_UNALIGNED_SUPPORT) || defined(__DOXYGEN__) #define STM32_SDC_UNALIGNED_SUPPORT TRUE #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ diff --git a/os/hal/platforms/STM32/serial_lld.h b/os/hal/platforms/STM32/serial_lld.h index fdd168201..ccafe736a 100644 --- a/os/hal/platforms/STM32/serial_lld.h +++ b/os/hal/platforms/STM32/serial_lld.h @@ -39,6 +39,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ /** * @brief USART1 driver enable switch. * @details If set to @p TRUE the support for USART1 is included. @@ -134,6 +138,7 @@ #if !defined(STM32_SERIAL_USART6_PRIORITY) || defined(__DOXYGEN__) #define STM32_SERIAL_USART6_PRIORITY 12 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ diff --git a/os/hal/platforms/STM32/spi_lld.c b/os/hal/platforms/STM32/spi_lld.c index f8ec8546c..1511547d5 100644 --- a/os/hal/platforms/STM32/spi_lld.c +++ b/os/hal/platforms/STM32/spi_lld.c @@ -31,6 +31,34 @@ #if HAL_USE_SPI || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define SPI1_RX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_SPI_SPI1_RX_DMA_STREAM, \ + STM32_SPI1_RX_DMA_CHN) + +#define SPI1_TX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_SPI_SPI1_TX_DMA_STREAM, \ + STM32_SPI1_TX_DMA_CHN) + +#define SPI2_RX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_SPI_SPI2_RX_DMA_STREAM, \ + STM32_SPI2_RX_DMA_CHN) + +#define SPI2_TX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_SPI_SPI2_TX_DMA_STREAM, \ + STM32_SPI2_TX_DMA_CHN) + +#define SPI3_RX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_SPI_SPI3_RX_DMA_STREAM, \ + STM32_SPI3_RX_DMA_CHN) + +#define SPI3_TX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_SPI_SPI3_TX_DMA_STREAM, \ + STM32_SPI3_TX_DMA_CHN) + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -61,26 +89,6 @@ static uint16_t dummyrx; /* Driver local functions. */ /*===========================================================================*/ -/** - * @brief Stops the SPI DMA channels. - * - * @param[in] spip pointer to the @p SPIDriver object - */ -#define dma_stop(spip) { \ - dmaStreamDisable(spip->dmatx); \ - dmaStreamDisable(spip->dmarx); \ -} - -/** - * @brief Starts the SPI DMA channels. - * - * @param[in] spip pointer to the @p SPIDriver object - */ -#define dma_start(spip) { \ - dmaChannelEnable((spip)->dmarx); \ - dmaChannelEnable((spip)->dmatx); \ -} - /** * @brief Shared end-of-rx service routine. * @@ -99,7 +107,8 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { #endif /* Stop everything.*/ - dma_stop(spip); + dmaStreamDisable(spip->dmatx); + dmaStreamDisable(spip->dmarx); /* Portable SPI ISR code defined in the high level driver, note, it is a macro.*/ @@ -145,26 +154,50 @@ void spi_lld_init(void) { #if STM32_SPI_USE_SPI1 spiObjectInit(&SPID1); - SPID1.thread = NULL; - SPID1.spi = SPI1; - SPID1.dmarx = STM32_DMA1_STREAM2; - SPID1.dmatx = STM32_DMA1_STREAM3; + SPID1.spi = SPI1; + SPID1.dmarx = STM32_DMA_STREAM(STM32_SPI_SPI1_RX_DMA_STREAM); + SPID1.dmatx = STM32_DMA_STREAM(STM32_SPI_SPI1_TX_DMA_STREAM); + SPID1.rxdmamode = STM32_DMA_CR_CHSEL(SPI1_RX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) | + STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | + STM32_DMA_CR_TEIE; + SPID1.txdmamode = STM32_DMA_CR_CHSEL(SPI1_TX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) | + STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_TEIE; #endif #if STM32_SPI_USE_SPI2 spiObjectInit(&SPID2); - SPID2.thread = NULL; - SPID2.spi = SPI2; - SPID2.dmarx = STM32_DMA1_STREAM4; - SPID2.dmatx = STM32_DMA1_STREAM5; + SPID2.spi = SPI2; + SPID2.dmarx = STM32_DMA_STREAM(STM32_SPI_SPI2_RX_DMA_STREAM); + SPID2.dmatx = STM32_DMA_STREAM(STM32_SPI_SPI2_TX_DMA_STREAM); + SPID2.rxdmamode = STM32_DMA_CR_CHSEL(SPI2_RX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) | + STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | + STM32_DMA_CR_TEIE; + SPID2.txdmamode = STM32_DMA_CR_CHSEL(SPI2_TX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) | + STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_TEIE; #endif #if STM32_SPI_USE_SPI3 spiObjectInit(&SPID3); - SPID3.thread = NULL; - SPID3.spi = SPI3; - SPID3.dmarx = STM32_DMA2_STREAM1; - SPID3.dmatx = STM32_DMA2_STREAM2; + SPID3.spi = SPI3; + SPID3.dmarx = STM32_DMA_STREAM(STM32_SPI_SPI3_RX_DMA_STREAM); + SPID3.dmatx = STM32_DMA_STREAM(STM32_SPI_SPI3_TX_DMA_STREAM); + SPID3.rxdmamode = STM32_DMA_CR_CHSEL(SPI3_RX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_SPI_SPI3_DMA_PRIORITY) | + STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | + STM32_DMA_CR_TEIE; + SPID3.txdmamode = STM32_DMA_CR_CHSEL(SPI3_TX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_SPI_SPI3_DMA_PRIORITY) | + STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_TEIE; #endif } @@ -182,12 +215,12 @@ void spi_lld_start(SPIDriver *spip) { #if STM32_SPI_USE_SPI1 if (&SPID1 == spip) { bool_t b; - b = dmaStreamAllocate(STM32_DMA1_STREAM2, + b = dmaStreamAllocate(spip->dmarx, STM32_SPI_SPI1_IRQ_PRIORITY, (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); chDbgAssert(!b, "spi_lld_start(), #1", "stream already allocated"); - b = dmaStreamAllocate(STM32_DMA1_STREAM3, + b = dmaStreamAllocate(spip->dmatx, STM32_SPI_SPI1_IRQ_PRIORITY, (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); @@ -198,12 +231,12 @@ void spi_lld_start(SPIDriver *spip) { #if STM32_SPI_USE_SPI2 if (&SPID2 == spip) { bool_t b; - b = dmaStreamAllocate(STM32_DMA1_STREAM4, + b = dmaStreamAllocate(spip->dmarx, STM32_SPI_SPI2_IRQ_PRIORITY, (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); chDbgAssert(!b, "spi_lld_start(), #3", "stream already allocated"); - b = dmaStreamAllocate(STM32_DMA1_STREAM5, + b = dmaStreamAllocate(spip->dmatx, STM32_SPI_SPI2_IRQ_PRIORITY, (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); @@ -214,12 +247,12 @@ void spi_lld_start(SPIDriver *spip) { #if STM32_SPI_USE_SPI3 if (&SPID3 == spip) { bool_t b; - b = dmaStreamAllocate(STM32_DMA2_STREAM1, + b = dmaStreamAllocate(spip->dmarx, STM32_SPI_SPI3_IRQ_PRIORITY, (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); chDbgAssert(!b, "spi_lld_start(), #5", "stream already allocated"); - b = dmaStreamAllocate(STM32_DMA2_STREAM2, + b = dmaStreamAllocate(spip->dmatx, STM32_SPI_SPI3_IRQ_PRIORITY, (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); @@ -233,18 +266,19 @@ void spi_lld_start(SPIDriver *spip) { dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR); } - /* More DMA setup.*/ - if ((spip->config->cr1 & SPI_CR1_DFF) == 0) - spip->dmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) | - STM32_DMA_CR_TEIE | - STM32_DMA_CR_PSIZE_BYTE | - STM32_DMA_CR_MSIZE_BYTE; /* 8 bits transfers. */ - else - spip->dmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) | - STM32_DMA_CR_TEIE | - STM32_DMA_CR_PSIZE_HWORD | - STM32_DMA_CR_MSIZE_HWORD; /* 16 bits transfers. */ - + /* Configuration-specific DMA setup.*/ + if ((spip->config->cr1 & SPI_CR1_DFF) == 0) { /* 8 bits transfers. */ + spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) | + STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE; + spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) | + STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE; + } + else { /* 16 bits transfers. */ + spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) | + STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; + spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) | + STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; + } /* SPI setup and enable.*/ spip->spi->CR1 = 0; spip->spi->CR1 = spip->config->cr1 | SPI_CR1_MSTR | SPI_CR1_SSM | @@ -267,27 +301,20 @@ void spi_lld_stop(SPIDriver *spip) { /* SPI disable.*/ spip->spi->CR1 = 0; + dmaStreamRelease(spip->dmarx); + dmaStreamRelease(spip->dmatx); #if STM32_SPI_USE_SPI1 - if (&SPID1 == spip) { - dmaStreamRelease(STM32_DMA1_STREAM2); - dmaStreamRelease(STM32_DMA1_STREAM3); + if (&SPID1 == spip) rccDisableSPI1(FALSE); - } #endif #if STM32_SPI_USE_SPI2 - if (&SPID2 == spip) { - dmaStreamRelease(STM32_DMA1_STREAM4); - dmaStreamRelease(STM32_DMA1_STREAM5); + if (&SPID2 == spip) rccDisableSPI2(FALSE); - } #endif #if STM32_SPI_USE_SPI3 - if (&SPID3 == spip) { - dmaStreamRelease(STM32_DMA2_STREAM1); - dmaStreamRelease(STM32_DMA2_STREAM2); + if (&SPID3 == spip) rccDisableSPI3(FALSE); - } #endif } } @@ -332,12 +359,10 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) { dmaStreamSetMemory0(spip->dmarx, &dummyrx); dmaStreamSetTransactionSize(spip->dmarx, n); - dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | - STM32_DMA_CR_TCIE | STM32_DMA_CR_EN); + dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_EN); dmaStreamSetMemory0(spip->dmatx, &dummytx); dmaStreamSetTransactionSize(spip->dmatx, n); - dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | - STM32_DMA_CR_EN); + dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_EN); } /** @@ -360,13 +385,12 @@ void spi_lld_exchange(SPIDriver *spip, size_t n, dmaStreamSetMemory0(spip->dmarx, rxbuf); dmaStreamSetTransactionSize(spip->dmarx, n); - dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | - STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC | - STM32_DMA_CR_EN); + dmaStreamSetMode(spip->dmarx, spip->rxdmamode| STM32_DMA_CR_MINC | + STM32_DMA_CR_EN); dmaStreamSetMemory0(spip->dmatx, txbuf); dmaStreamSetTransactionSize(spip->dmatx, n); - dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | - STM32_DMA_CR_MINC | STM32_DMA_CR_EN); + dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_MINC | + STM32_DMA_CR_EN); } /** @@ -386,12 +410,11 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { dmaStreamSetMemory0(spip->dmarx, &dummyrx); dmaStreamSetTransactionSize(spip->dmarx, n); - dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | - STM32_DMA_CR_TCIE | STM32_DMA_CR_EN); + dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_EN); dmaStreamSetMemory0(spip->dmatx, txbuf); dmaStreamSetTransactionSize(spip->dmatx, n); - dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | - STM32_DMA_CR_MINC | STM32_DMA_CR_EN); + dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_MINC | + STM32_DMA_CR_EN); } /** @@ -411,13 +434,11 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { dmaStreamSetMemory0(spip->dmarx, rxbuf); dmaStreamSetTransactionSize(spip->dmarx, n); - dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | - STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC | - STM32_DMA_CR_EN); + dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC | + STM32_DMA_CR_EN); dmaStreamSetMemory0(spip->dmatx, &dummytx); dmaStreamSetTransactionSize(spip->dmatx, n); - dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | - STM32_DMA_CR_EN); + dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_EN); } /** diff --git a/os/hal/platforms/STM32/spi_lld.h b/os/hal/platforms/STM32/spi_lld.h index c8c1e0661..5f4fd9224 100644 --- a/os/hal/platforms/STM32/spi_lld.h +++ b/os/hal/platforms/STM32/spi_lld.h @@ -39,6 +39,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ /** * @brief SPI1 driver enable switch. * @details If set to @p TRUE the support for SPI1 is included. @@ -68,9 +72,9 @@ /** * @brief SPI1 DMA priority (0..3|lowest..highest). - * @note The priority level is used for both the TX and RX DMA channels but - * because of the channels ordering the RX channel has always priority - * over the TX channel. + * @note The priority level is used for both the TX and RX DMA streams but + * because of the streams ordering the RX stream has always priority + * over the TX stream. */ #if !defined(STM32_SPI_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__) #define STM32_SPI_SPI1_DMA_PRIORITY 1 @@ -78,9 +82,9 @@ /** * @brief SPI2 DMA priority (0..3|lowest..highest). - * @note The priority level is used for both the TX and RX DMA channels but - * because of the channels ordering the RX channel has always priority - * over the TX channel. + * @note The priority level is used for both the TX and RX DMA streams but + * because of the streams ordering the RX stream has always priority + * over the TX stream. */ #if !defined(STM32_SPI_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__) #define STM32_SPI_SPI2_DMA_PRIORITY 1 @@ -88,9 +92,9 @@ /** * @brief SPI3 DMA priority (0..3|lowest..highest). - * @note The priority level is used for both the TX and RX DMA channels but - * because of the channels ordering the RX channel has always priority - * over the TX channel. + * @note The priority level is used for both the TX and RX DMA streams but + * because of the streams ordering the RX stream has always priority + * over the TX stream. */ #if !defined(STM32_SPI_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__) #define STM32_SPI_SPI3_DMA_PRIORITY 1 @@ -119,13 +123,64 @@ /** * @brief SPI DMA error hook. - * @note The default action for DMA errors is a system halt because DMA - * error can only happen because programming errors. */ #if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__) #define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt() #endif +#if STM32_ADVANCED_DMA || defined(__DOXYGEN__) + +/** + * @brief DMA stream used for SPI1 RX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_SPI_SPI1_RX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0) +#endif + +/** + * @brief DMA stream used for SPI1 TX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_SPI_SPI1_TX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#endif + +/** + * @brief DMA stream used for SPI2 RX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_SPI_SPI2_RX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#endif + +/** + * @brief DMA stream used for SPI2 TX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_SPI_SPI2_TX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#endif + +/** + * @brief DMA stream used for SPI3 RX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_SPI_SPI3_RX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) +#endif + +/** + * @brief DMA stream used for SPI3 TX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_SPI_SPI3_TX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#endif + +#endif /* STM32_ADVANCED_DMA*/ +/** @} */ + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ @@ -146,6 +201,53 @@ #error "SPI driver activated but no SPI peripheral assigned" #endif +#if STM32_ADVANCED_DMA + +/* Checks to be performed only on platforms using the advanced DMA + peripheral.*/ +#if STM32_SPI_USE_SPI1 && \ + !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_RX_DMA_STREAM, STM32_SPI1_RX_DMA_MSK) +#error "invalid DMA stream associated to SPI1 RX" +#endif + +#if STM32_SPI_USE_SPI1 && \ + !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_TX_DMA_STREAM, STM32_SPI1_TX_DMA_MSK) +#error "invalid DMA stream associated to SPI1 TX" +#endif + +#if STM32_SPI_USE_SPI2 && \ + !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI2_RX_DMA_STREAM, STM32_SPI2_RX_DMA_MSK) +#error "invalid DMA stream associated to SPI2 RX" +#endif + +#if STM32_SPI_USE_SPI2 && \ + !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI2_TX_DMA_STREAM, STM32_SPI2_TX_DMA_MSK) +#error "invalid DMA stream associated to SPI2 TX" +#endif + +#if STM32_SPI_USE_SPI3 && \ + !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI3_RX_DMA_STREAM, STM32_SPI3_RX_DMA_MSK) +#error "invalid DMA stream associated to SPI3 RX" +#endif + +#if STM32_SPI_USE_SPI3 && \ + !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI3_TX_DMA_STREAM, STM32_SPI3_TX_DMA_MSK) +#error "invalid DMA stream associated to SPI3 TX" +#endif + +#else /* !STM32_ADVANCED_DMA */ + +/* Fixed streams for platforms using the old DMA peripheral, the values are + valid for both STM32F1xx and STM32L1xx.*/ +#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) +#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 6) + +#endif /* !STM32_ADVANCED_DMA */ + #if !defined(STM32_DMA_REQUIRED) #define STM32_DMA_REQUIRED #endif @@ -227,17 +329,21 @@ struct SPIDriver{ */ SPI_TypeDef *spi; /** - * @brief Receive DMA channel. + * @brief Receive DMA stream. */ const stm32_dma_stream_t *dmarx; /** - * @brief Transmit DMA channel. + * @brief Transmit DMA stream. */ const stm32_dma_stream_t *dmatx; /** - * @brief DMA mode bit mask. + * @brief RX DMA mode bit mask. + */ + uint32_t rxdmamode; + /** + * @brief TX DMA mode bit mask. */ - uint32_t dmamode; + uint32_t txdmamode; }; /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/uart_lld.h b/os/hal/platforms/STM32/uart_lld.h index aff7f52ba..d97bea91b 100644 --- a/os/hal/platforms/STM32/uart_lld.h +++ b/os/hal/platforms/STM32/uart_lld.h @@ -39,6 +39,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ /** * @brief UART driver on USART1 enable switch. * @details If set to @p TRUE the support for USART1 is included. @@ -124,6 +128,7 @@ #if !defined(STM32_UART_DMA_ERROR_HOOK) || defined(__DOXYGEN__) #define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt() #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ diff --git a/os/hal/platforms/STM32F1xx/adc_lld.h b/os/hal/platforms/STM32F1xx/adc_lld.h index e3a327afa..bd4ec3dee 100644 --- a/os/hal/platforms/STM32F1xx/adc_lld.h +++ b/os/hal/platforms/STM32F1xx/adc_lld.h @@ -85,6 +85,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ /** * @brief ADC1 driver enable switch. * @details If set to @p TRUE the support for ADC1 is included. @@ -107,6 +111,7 @@ #if !defined(STM32_ADC_ADC1_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_ADC_ADC1_IRQ_PRIORITY 5 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f100.h b/os/hal/platforms/STM32F1xx/hal_lld_f100.h index cdad07bc5..230b415ef 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f100.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f100.h @@ -337,6 +337,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ /** * @brief Main clock source selection. * @note If the selected clock source is not the PLL then the PLL is not @@ -423,6 +427,7 @@ #if !defined(STM32_RTC) || defined(__DOXYGEN__) #define STM32_RTC STM32_RTC_LSI #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f103.h b/os/hal/platforms/STM32F1xx/hal_lld_f103.h index 92144b5dc..ee265fe7f 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f103.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f103.h @@ -508,6 +508,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ /** * @brief Main clock source selection. * @note If the selected clock source is not the PLL then the PLL is not @@ -601,6 +605,8 @@ #if !defined(STM32_RTC) || defined(__DOXYGEN__) #define STM32_RTC STM32_RTC_LSI #endif +/** @} */ + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h index 52de807d2..cc9b2f796 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h @@ -278,6 +278,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ /** * @brief PLL1 main switch. * @note If this constant is set to @p TRUE then the PLL1 is initialized @@ -430,6 +434,7 @@ #if !defined(STM32_RTC) || defined(__DOXYGEN__) #define STM32_RTC STM32_RTC_LSI #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ diff --git a/os/hal/platforms/STM32F1xx/stm32_dma.h b/os/hal/platforms/STM32F1xx/stm32_dma.h index bacd0a809..a33577af8 100644 --- a/os/hal/platforms/STM32F1xx/stm32_dma.h +++ b/os/hal/platforms/STM32F1xx/stm32_dma.h @@ -51,26 +51,56 @@ */ #define STM32_DMA_ISR_MASK 0x0F +/** + * @brief Returns the channel associated to the specified stream. + * + * @param[in] n the stream number (0...STM32_DMA_STREAMS-1) + * @param[in] c a stream/channel association word, one channel per + * nibble, not associated channels must be set to 0xF + * @return Always zero, in this platform there is no dynamic + * association between streams and channels. + */ +#define STM32_DMA_GETCHANNEL(n, c) 0 + /** * @name DMA streams identifiers * @{ */ -#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[0]) -#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[1]) -#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[2]) -#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[3]) -#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[4]) -#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[5]) -#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[6]) -#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[7]) -#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[8]) -#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[9]) -#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[10]) -#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[11]) +/** + * @brief Returns an unique numeric identifier for a DMA stream. + * + * @param[in] dma the DMA unit number + * @param[in] stream the stream number + * @return An unique numeric stream identifier. + */ +#define STM32_DMA_STREAM_ID(dma, stream) ((((dma) - 1) * 7) + ((stream) - 1)) + +/** + * @brief Returns a pointer to a stm32_dma_stream_t structure. + * + * @param[in] n the stream numeric identifier + * @return A pointer to the stm32_dma_stream_t constant structure + * associated to the DMA stream. + */ +#define STM32_DMA_STREAM(n) (&_stm32_dma_streams[n]) + +#define STM32_DMA1_STREAM1 STM32_DMA_STREAM(0) +#define STM32_DMA1_STREAM2 STM32_DMA_STREAM(1) +#define STM32_DMA1_STREAM3 STM32_DMA_STREAM(2) +#define STM32_DMA1_STREAM4 STM32_DMA_STREAM(3) +#define STM32_DMA1_STREAM5 STM32_DMA_STREAM(4) +#define STM32_DMA1_STREAM6 STM32_DMA_STREAM(5) +#define STM32_DMA1_STREAM7 STM32_DMA_STREAM(6) +#define STM32_DMA2_STREAM1 STM32_DMA_STREAM(7) +#define STM32_DMA2_STREAM2 STM32_DMA_STREAM(8) +#define STM32_DMA2_STREAM3 STM32_DMA_STREAM(9) +#define STM32_DMA2_STREAM4 STM32_DMA_STREAM(10) +#define STM32_DMA2_STREAM5 STM32_DMA_STREAM(11) /** @} */ /** * @name CR register constants common to all DMA types + * @{ */ #define STM32_DMA_CR_EN DMA_CCR1_EN #define STM32_DMA_CR_TEIE DMA_CCR1_TEIE @@ -97,6 +127,7 @@ /** * @name CR register constants only found in enhanced DMA + * @{ */ #define STM32_DMA_CR_CHSEL_MASK 0 /**< @brief Ignored by normal DMA. */ #define STM32_DMA_CR_CHSEL(n) 0 /**< @brief Ignored by normal DMA. */ @@ -104,6 +135,7 @@ /** * @name Status flags passed to the ISR callbacks + * @{ */ #define STM32_DMA_ISR_FEIF 0 #define STM32_DMA_ISR_DMEIF 0 @@ -149,6 +181,10 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /* Driver macros. */ /*===========================================================================*/ +/** + * @name Macro Functions + * @{ + */ /** * @brief Associates a peripheral data register to a DMA stream. * @note This function can be invoked in both ISR or thread context. @@ -302,6 +338,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); #define dmaWaitCompletion(dmastp) \ while (((dmastp)->channel->CNDTR > 0) && \ ((dmastp)->channel->CCR & STM32_DMA_CR_EN)) +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index ca46e5287..fc40b51a9 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -40,6 +40,10 @@ #include "stm32f4xx.h" +/* STM32 DMA and RCC helpers.*/ +#include "stm32_dma.h" +#include "stm32_rcc.h" + /*===========================================================================*/ /* Driver constants. */ /*===========================================================================*/ @@ -58,67 +62,67 @@ /** * @brief Maximum HSE clock frequency. */ -#define STM32_HSECLK_MAX 26000000 +#define STM32_HSECLK_MAX 26000000 /** * @brief Minimum HSE clock frequency. */ -#define STM32_HSECLK_MIN 1000000 +#define STM32_HSECLK_MIN 1000000 /** * @brief Maximum LSE clock frequency. */ -#define STM32_LSECLK_MAX 1000000 +#define STM32_LSECLK_MAX 1000000 /** * @brief Minimum LSE clock frequency. */ -#define STM32_LSECLK_MIN 1000 +#define STM32_LSECLK_MIN 1000 /** * @brief Maximum PLLs input clock frequency. */ -#define STM32_PLLIN_MAX 2000000 +#define STM32_PLLIN_MAX 2000000 /** * @brief Maximum PLLs input clock frequency. */ -#define STM32_PLLIN_MIN 950000 +#define STM32_PLLIN_MIN 950000 /** * @brief Maximum PLLs VCO clock frequency. */ -#define STM32_PLLVCO_MAX 432000000 +#define STM32_PLLVCO_MAX 432000000 /** * @brief Maximum PLLs VCO clock frequency. */ -#define STM32_PLLVCO_MIN 192000000 +#define STM32_PLLVCO_MIN 192000000 /** * @brief Maximum PLL output clock frequency. */ -#define STM32_PLLOUT_MAX 168000000 +#define STM32_PLLOUT_MAX 168000000 /** * @brief Maximum PLL output clock frequency. */ -#define STM32_PLLOUT_MIN 24000000 +#define STM32_PLLOUT_MIN 24000000 /** * @brief Maximum APB1 clock frequency. */ -#define STM32_PCLK1_MAX 42000000 +#define STM32_PCLK1_MAX 42000000 /** * @brief Maximum APB2 clock frequency. */ -#define STM32_PCLK2_MAX 84000000 +#define STM32_PCLK2_MAX 84000000 /** * @brief Maximum SPI/I2S clock frequency. */ -#define STM32_SPII2S_MAX 37500000 +#define STM32_SPII2S_MAX 37500000 /** @} */ /** @@ -245,22 +249,30 @@ * @name STM32F4xx capabilities * @{ */ +/* ADC attributes.*/ #define STM32_HAS_ADC1 TRUE #define STM32_HAS_ADC2 TRUE #define STM32_HAS_ADC3 TRUE +/* CAN attributes.*/ #define STM32_HAS_CAN1 TRUE #define STM32_HAS_CAN2 TRUE +/* DAC attributes.*/ #define STM32_HAS_DAC TRUE +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA TRUE #define STM32_HAS_DMA1 TRUE #define STM32_HAS_DMA2 TRUE +/* ETH attributes.*/ #define STM32_HAS_ETH TRUE +/* EXTI attributes.*/ #define STM32_EXTI_NUM_CHANNELS 23 +/* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -271,18 +283,41 @@ #define STM32_HAS_GPIOH TRUE #define STM32_HAS_GPIOI TRUE +/* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE #define STM32_HAS_I2C2 TRUE #define STM32_HAS_I2C3 TRUE +/* RTC attributes.*/ #define STM32_HAS_RTC TRUE +/* SDIO attributes.*/ #define STM32_HAS_SDIO TRUE +/* SPI attributes.*/ #define STM32_HAS_SPI1 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_HAS_SPI3 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_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 + +/* TIM attributes.*/ #define STM32_HAS_TIM1 TRUE #define STM32_HAS_TIM2 TRUE #define STM32_HAS_TIM3 TRUE @@ -301,6 +336,7 @@ #define STM32_HAS_TIM16 FALSE #define STM32_HAS_TIM17 FALSE +/* USART attributes.*/ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 TRUE @@ -308,6 +344,7 @@ #define STM32_HAS_UART5 TRUE #define STM32_HAS_USART6 TRUE +/* USB attributes.*/ #define STM32_HAS_USB FALSE #define STM32_HAS_OTG1 TRUE #define STM32_HAS_OTG2 TRUE @@ -415,6 +452,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ /** * @brief Disables the PWR/RCC initialization in the HAL. */ @@ -620,6 +661,7 @@ #if !defined(STM32_PLLI2SR_VALUE) || defined(__DOXYGEN__) #define STM32_PLLI2SR_VALUE 5 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ @@ -1208,10 +1250,6 @@ /* External declarations. */ /*===========================================================================*/ -/* STM32 DMA and RCC helpers.*/ -#include "stm32_dma.h" -#include "stm32_rcc.h" - #ifdef __cplusplus extern "C" { #endif diff --git a/os/hal/platforms/STM32F4xx/platform.mk b/os/hal/platforms/STM32F4xx/platform.mk index 36d555536..6b7df146b 100644 --- a/os/hal/platforms/STM32F4xx/platform.mk +++ b/os/hal/platforms/STM32F4xx/platform.mk @@ -1,6 +1,8 @@ # List of all the STM32L1xx platform files. -PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F4xx/hal_lld.c \ +PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32L1xx/stm32_dma.c \ + ${CHIBIOS}/os/hal/platforms/STM32F4xx/hal_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/serial_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c # Required include directories diff --git a/os/hal/platforms/STM32F4xx/stm32_dma.c b/os/hal/platforms/STM32F4xx/stm32_dma.c index dd5a92afb..d7005b77b 100644 --- a/os/hal/platforms/STM32F4xx/stm32_dma.c +++ b/os/hal/platforms/STM32F4xx/stm32_dma.c @@ -484,8 +484,8 @@ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, /* Putting the stream in a safe state.*/ dmaStreamDisable(dmastp); dmaStreamClearInterrupt(dmastp); - dmastp->channel->CR = STM32_DMA_CR_RESET_VALUE; - dmastp->channel->FCR = STM32_DMA_FCR_RESET_VALUE; + dmastp->stream->CR = STM32_DMA_CR_RESET_VALUE; + dmastp->stream->FCR = STM32_DMA_FCR_RESET_VALUE; /* Enables the associated IRQ vector if a callback is defined.*/ if (func != NULL) diff --git a/os/hal/platforms/STM32F4xx/stm32_dma.h b/os/hal/platforms/STM32F4xx/stm32_dma.h index 9aaadb681..d07a9dbe9 100644 --- a/os/hal/platforms/STM32F4xx/stm32_dma.h +++ b/os/hal/platforms/STM32F4xx/stm32_dma.h @@ -46,30 +46,81 @@ */ #define STM32_DMA_ISR_MASK 0x3D +/** + * @brief Returns the channel associated to the specified stream. + * + * @param[in] id the unique numeric stream identifier + * @param[in] c a stream/channel association word, one channel per + * nibble + * @return Returns the channel associated to the stream. + */ +#define STM32_DMA_GETCHANNEL(id, c) ((c) >> (((id) & 7) * 4)) + +/** + * @brief Returns an unique numeric identifier for a DMA stream. + * + * @param[in] dma the DMA unit number + * @param[in] stream the stream number + * @return An unique numeric stream identifier. + */ +#define STM32_DMA_STREAM_ID(dma, stream) ((((dma) - 1) * 8) + (stream)) + +/** + * @brief Returns a DMA stream identifier mask. + * + * + * @param[in] dma the DMA unit number + * @param[in] stream the stream number + * @return A DMA stream identifier mask. + */ +#define STM32_DMA_STREAM_ID_MSK(dma, stream) \ + (1 << STM32_DMA_STREAM_ID(dma, stream)) + +/** + * @brief Checks if a DMA stream unique identifier belongs to a mask. + * @param[in] id the stream numeric identifier + * @param[in] mask the stream numeric identifiers mask + * + * @retval The check result. + * @retval FALSE id does not belong to the mask. + * @retval TRUE id belongs to the mask. + */ +#define STM32_DMA_IS_VALID_ID(id, mask) (((1 << (id)) & (mask))) + /** * @name DMA streams identifiers * @{ */ -#define STM32_DMA1_STREAM0 (&_stm32_dma_streams[0]) -#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[1]) -#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[2]) -#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[3]) -#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[4]) -#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[5]) -#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[6]) -#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[7]) -#define STM32_DMA2_STREAM0 (&_stm32_dma_streams[8]) -#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[9]) -#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[10]) -#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[11]) -#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[12]) -#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[13]) -#define STM32_DMA2_STREAM6 (&_stm32_dma_streams[14]) -#define STM32_DMA2_STREAM7 (&_stm32_dma_streams[15]) +/** + * @brief Returns a pointer to a stm32_dma_stream_t structure. + * + * @param[in] id the stream numeric identifier + * @return A pointer to the stm32_dma_stream_t constant structure + * associated to the DMA stream. + */ +#define STM32_DMA_STREAM(id) (&_stm32_dma_streams[id]) + +#define STM32_DMA1_STREAM0 STM32_DMA_STREAM(0) +#define STM32_DMA1_STREAM1 STM32_DMA_STREAM(1) +#define STM32_DMA1_STREAM2 STM32_DMA_STREAM(2) +#define STM32_DMA1_STREAM3 STM32_DMA_STREAM(3) +#define STM32_DMA1_STREAM4 STM32_DMA_STREAM(4) +#define STM32_DMA1_STREAM5 STM32_DMA_STREAM(5) +#define STM32_DMA1_STREAM6 STM32_DMA_STREAM(6) +#define STM32_DMA1_STREAM7 STM32_DMA_STREAM(7) +#define STM32_DMA2_STREAM0 STM32_DMA_STREAM(8) +#define STM32_DMA2_STREAM1 STM32_DMA_STREAM(9) +#define STM32_DMA2_STREAM2 STM32_DMA_STREAM(10) +#define STM32_DMA2_STREAM3 STM32_DMA_STREAM(11) +#define STM32_DMA2_STREAM4 STM32_DMA_STREAM(12) +#define STM32_DMA2_STREAM5 STM32_DMA_STREAM(13) +#define STM32_DMA2_STREAM6 STM32_DMA_STREAM(14) +#define STM32_DMA2_STREAM7 STM32_DMA_STREAM(15) /** @} */ /** * @name CR register constants common to all DMA types + * @{ */ #define STM32_DMA_CR_EN DMA_SxCR_EN #define STM32_DMA_CR_TEIE DMA_SxCR_TEIE @@ -90,12 +141,15 @@ #define STM32_DMA_CR_MSIZE_BYTE 0 #define STM32_DMA_CR_MSIZE_HWORD DMA_SxCR_MSIZE_0 #define STM32_DMA_CR_MSIZE_WORD DMA_SxCR_MSIZE_1 +#define STM32_DMA_CR_SIZE_MASK (STM32_DMA_CR_MSIZE_MASK | \ + STM32_DMA_CR_MSIZE_MASK) #define STM32_DMA_CR_PL_MASK DMA_SxCR_PL #define STM32_DMA_CR_PL(n) ((n) << 16) /** @} */ /** * @name CR register constants only found in STM32F2xx/STM32F4xx + * @{ */ #define STM32_DMA_CR_DMEIE DMA_SxCR_DMEIE #define STM32_DMA_CR_PFCTRL DMA_SxCR_PFCTRL @@ -118,6 +172,7 @@ /** * @name FCR register constants only found in STM32F2xx + * @{ */ #define STM32_DMA_FCR_FEIE DMA_SxFCR_FEIE #define STM32_DMA_FCR_FS_MASK DMA_SxFCR_FS @@ -176,6 +231,10 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /* Driver macros. */ /*===========================================================================*/ +/** + * @name Macro Functions + * @{ + */ /** * @brief Associates a peripheral data register to a DMA stream. * @note This function can be invoked in both ISR or thread context. @@ -357,6 +416,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); #define dmaWaitCompletion(dmastp) \ while (((dmastp)->stream->CNDTR > 0) && \ ((dmastp)->stream->CCR & STM32_DMA_CR_EN)) +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/platforms/STM32F4xx/stm32_rcc.h b/os/hal/platforms/STM32F4xx/stm32_rcc.h index 3a10e57b2..4971a71c5 100644 --- a/os/hal/platforms/STM32F4xx/stm32_rcc.h +++ b/os/hal/platforms/STM32F4xx/stm32_rcc.h @@ -27,7 +27,6 @@ * @addtogroup STM32F4xx_RCC * @{ */ - #ifndef _STM32_RCC_ #define _STM32_RCC_ @@ -347,7 +346,7 @@ * * @api */ -#define rccEnableDMA1(lp) rccEnableAHB(RCC_AHB1ENR_DMA1EN, lp) +#define rccEnableDMA1(lp) rccEnableAHB1(RCC_AHB1ENR_DMA1EN, lp) /** * @brief Disables the DMA1 peripheral clock. @@ -356,14 +355,14 @@ * * @api */ -#define rccDisableDMA1(lp) rccDisableAHB(RCC_AHB1ENR_DMA1EN, lp) +#define rccDisableDMA1(lp) rccDisableAHB1(RCC_AHB1ENR_DMA1EN, lp) /** * @brief Resets the DMA1 peripheral. * * @api */ -#define rccResetDMA1() rccResetAHB(RCC_AHB1RSTR_DMA1RST) +#define rccResetDMA1() rccResetAHB1(RCC_AHB1RSTR_DMA1RST) /** * @brief Enables the DMA2 peripheral clock. @@ -372,7 +371,7 @@ * * @api */ -#define rccEnableDMA2(lp) rccEnableAHB(RCC_AHB1ENR_DMA2EN, lp) +#define rccEnableDMA2(lp) rccEnableAHB1(RCC_AHB1ENR_DMA2EN, lp) /** * @brief Disables the DMA2 peripheral clock. @@ -381,14 +380,14 @@ * * @api */ -#define rccDisableDMA2(lp) rccDisableAHB(RCC_AHB1ENR_DMA2EN, lp) +#define rccDisableDMA2(lp) rccDisableAHB1(RCC_AHB1ENR_DMA2EN, lp) /** * @brief Resets the DMA2 peripheral. * * @api */ -#define rccResetDMA2() rccResetAHB(RCC_AHB1RSTR_DMA2RST) +#define rccResetDMA2() rccResetAHB1(RCC_AHB1RSTR_DMA2RST) /** @} */ /** diff --git a/os/hal/platforms/STM32L1xx/adc_lld.h b/os/hal/platforms/STM32L1xx/adc_lld.h index 0ca41c269..58fb7bda1 100644 --- a/os/hal/platforms/STM32L1xx/adc_lld.h +++ b/os/hal/platforms/STM32L1xx/adc_lld.h @@ -101,6 +101,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ /** * @brief ADC1 driver enable switch. * @details If set to @p TRUE the support for ADC1 is included. @@ -134,6 +138,7 @@ #if !defined(STM32_ADC_ADC1_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_ADC_ADC1_IRQ_PRIORITY 5 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index 9ca34fb7c..f61550170 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -298,6 +298,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ /** * @brief Disables the PWR/RCC initialization in the HAL. */ @@ -456,6 +460,7 @@ #if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) #define STM32_RTCPRE STM32_RTCPRE_DIV2 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ diff --git a/os/hal/platforms/STM32L1xx/stm32_dma.h b/os/hal/platforms/STM32L1xx/stm32_dma.h index e23980f9f..43ffdb668 100644 --- a/os/hal/platforms/STM32L1xx/stm32_dma.h +++ b/os/hal/platforms/STM32L1xx/stm32_dma.h @@ -47,21 +47,51 @@ */ #define STM32_DMA_ISR_MASK 0x0F +/** + * @brief Returns the channel associated to the specified stream. + * + * @param[in] n the stream number (0...STM32_DMA_STREAMS-1) + * @param[in] c a stream/channel association word, one channel per + * nibble, not associated channels must be set to 0xF + * @return Always zero, in this platform there is no dynamic + * association between streams and channels. + */ +#define STM32_DMA_GETCHANNEL(n, c) 0 + /** * @name DMA streams identifiers * @{ */ -#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[0]) -#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[1]) -#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[2]) -#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[3]) -#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[4]) -#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[5]) -#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[6]) +/** + * @brief Returns an unique numeric identifier for a DMA stream. + * + * @param[in] dma the DMA unit number + * @param[in] stream the stream number + * @return An unique numeric stream identifier. + */ +#define STM32_DMA_STREAM_ID(dma, stream) ((stream) - 1) + +/** + * @brief Returns a pointer to a stm32_dma_stream_t structure. + * + * @param[in] n the stream numeric identifier + * @return A pointer to the stm32_dma_stream_t constant structure + * associated to the DMA stream. + */ +#define STM32_DMA_STREAM(n) (&_stm32_dma_streams[n)) + +#define STM32_DMA1_STREAM1 STM32_DMA_STREAM(0) +#define STM32_DMA1_STREAM2 STM32_DMA_STREAM(1) +#define STM32_DMA1_STREAM3 STM32_DMA_STREAM(2) +#define STM32_DMA1_STREAM4 STM32_DMA_STREAM(3) +#define STM32_DMA1_STREAM5 STM32_DMA_STREAM(4) +#define STM32_DMA1_STREAM6 STM32_DMA_STREAM(5) +#define STM32_DMA1_STREAM7 STM32_DMA_STREAM(6) /** @} */ /** * @name CR register constants common to all DMA types + * @{ */ #define STM32_DMA_CR_EN DMA_CCR1_EN #define STM32_DMA_CR_TEIE DMA_CCR1_TEIE @@ -88,6 +118,7 @@ /** * @name CR register constants only found in enhanced DMA + * @{ */ #define STM32_DMA_CR_CHSEL_MASK 0 /**< @brief Ignored by normal DMA. */ #define STM32_DMA_CR_CHSEL(n) 0 /**< @brief Ignored by normal DMA. */ @@ -95,6 +126,7 @@ /** * @name Status flags passed to the ISR callbacks + * @{ */ #define STM32_DMA_ISR_FEIF 0 #define STM32_DMA_ISR_DMEIF 0 @@ -140,6 +172,10 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /* Driver macros. */ /*===========================================================================*/ +/** + * @name Macro Functions + * @{ + */ /** * @brief Associates a peripheral data register to a DMA stream. * @note This function can be invoked in both ISR or thread context. @@ -293,6 +329,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); #define dmaWaitCompletion(dmastp) \ while (((dmastp)->channel->CNDTR > 0) && \ ((dmastp)->channel->CCR & STM32_DMA_CR_EN)) +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/platforms/STM32L1xx/stm32l1xx.h b/os/hal/platforms/STM32L1xx/stm32l1xx.h index 9723158c8..32ddcb79d 100644 --- a/os/hal/platforms/STM32L1xx/stm32l1xx.h +++ b/os/hal/platforms/STM32L1xx/stm32l1xx.h @@ -430,7 +430,6 @@ typedef struct __IO uint32_t AFR[2]; } GPIO_TypeDef; #endif -#endif /** * @brief SysTem Configuration -- cgit v1.2.3 From c505341e78165415765743d423eedf9f62df0d1e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 10 Nov 2011 20:15:51 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3483 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32L1xx/stm32_dma.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32L1xx/stm32_dma.h b/os/hal/platforms/STM32L1xx/stm32_dma.h index 43ffdb668..7cfcf7536 100644 --- a/os/hal/platforms/STM32L1xx/stm32_dma.h +++ b/os/hal/platforms/STM32L1xx/stm32_dma.h @@ -74,11 +74,11 @@ /** * @brief Returns a pointer to a stm32_dma_stream_t structure. * - * @param[in] n the stream numeric identifier + * @param[in] id the stream numeric identifier * @return A pointer to the stm32_dma_stream_t constant structure * associated to the DMA stream. */ -#define STM32_DMA_STREAM(n) (&_stm32_dma_streams[n)) +#define STM32_DMA_STREAM(id) (&_stm32_dma_streams[id]) #define STM32_DMA1_STREAM1 STM32_DMA_STREAM(0) #define STM32_DMA1_STREAM2 STM32_DMA_STREAM(1) @@ -112,6 +112,8 @@ #define STM32_DMA_CR_MSIZE_BYTE 0 #define STM32_DMA_CR_MSIZE_HWORD DMA_CCR1_MSIZE_0 #define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1 +#define STM32_DMA_CR_SIZE_MASK (STM32_DMA_CR_MSIZE_MASK | \ + STM32_DMA_CR_MSIZE_MASK) #define STM32_DMA_CR_PL_MASK DMA_CCR1_PL #define STM32_DMA_CR_PL(n) ((n) << 12) /** @} */ -- cgit v1.2.3 From 1ae84c9323e76f02ec4bc4d71aff4301ba5d00e7 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 10 Nov 2011 20:33:49 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3485 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/stm32_dma.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/stm32_dma.h b/os/hal/platforms/STM32F1xx/stm32_dma.h index a33577af8..e01708d64 100644 --- a/os/hal/platforms/STM32F1xx/stm32_dma.h +++ b/os/hal/platforms/STM32F1xx/stm32_dma.h @@ -78,11 +78,11 @@ /** * @brief Returns a pointer to a stm32_dma_stream_t structure. * - * @param[in] n the stream numeric identifier + * @param[in] id the stream numeric identifier * @return A pointer to the stm32_dma_stream_t constant structure * associated to the DMA stream. */ -#define STM32_DMA_STREAM(n) (&_stm32_dma_streams[n]) +#define STM32_DMA_STREAM(id) (&_stm32_dma_streams[id]) #define STM32_DMA1_STREAM1 STM32_DMA_STREAM(0) #define STM32_DMA1_STREAM2 STM32_DMA_STREAM(1) @@ -121,6 +121,8 @@ #define STM32_DMA_CR_MSIZE_BYTE 0 #define STM32_DMA_CR_MSIZE_HWORD DMA_CCR1_MSIZE_0 #define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1 +#define STM32_DMA_CR_SIZE_MASK (STM32_DMA_CR_MSIZE_MASK | \ + STM32_DMA_CR_MSIZE_MASK) #define STM32_DMA_CR_PL_MASK DMA_CCR1_PL #define STM32_DMA_CR_PL(n) ((n) << 12) /** @} */ -- cgit v1.2.3 From 3d09e9e86c134035e02ecf92255f72d8d08fdcf5 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 11 Nov 2011 14:11:52 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3486 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/spi_lld.h | 30 ++++++++++++------------------ os/hal/platforms/STM32L1xx/hal_lld.h | 29 +++++++++++++++++++++++++++++ os/hal/platforms/STM32L1xx/stm32_dma.h | 22 ++++++++++++++++++++++ 3 files changed, 63 insertions(+), 18 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/spi_lld.h b/os/hal/platforms/STM32/spi_lld.h index 5f4fd9224..ccffe5f8b 100644 --- a/os/hal/platforms/STM32/spi_lld.h +++ b/os/hal/platforms/STM32/spi_lld.h @@ -178,7 +178,18 @@ #define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) #endif -#endif /* STM32_ADVANCED_DMA*/ +#else /* !STM32_ADVANCED_DMA */ + +/* Fixed streams for platforms using the old DMA peripheral, the values are + valid for both STM32F1xx and STM32L1xx.*/ +#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) +#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 6) + +#endif /* !STM32_ADVANCED_DMA*/ /** @} */ /*===========================================================================*/ @@ -201,10 +212,6 @@ #error "SPI driver activated but no SPI peripheral assigned" #endif -#if STM32_ADVANCED_DMA - -/* Checks to be performed only on platforms using the advanced DMA - peripheral.*/ #if STM32_SPI_USE_SPI1 && \ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_RX_DMA_STREAM, STM32_SPI1_RX_DMA_MSK) #error "invalid DMA stream associated to SPI1 RX" @@ -235,19 +242,6 @@ #error "invalid DMA stream associated to SPI3 TX" #endif -#else /* !STM32_ADVANCED_DMA */ - -/* Fixed streams for platforms using the old DMA peripheral, the values are - valid for both STM32F1xx and STM32L1xx.*/ -#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) -#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) -#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) -#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) -#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) -#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 6) - -#endif /* !STM32_ADVANCED_DMA */ - #if !defined(STM32_DMA_REQUIRED) #define STM32_DMA_REQUIRED #endif diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index f61550170..08990ee13 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -168,22 +168,30 @@ * @name STM32L1xx capabilities * @{ */ +/* ADC attributes.*/ #define STM32_HAS_ADC1 TRUE #define STM32_HAS_ADC2 FALSE #define STM32_HAS_ADC3 FALSE +/* CAN attributes.*/ #define STM32_HAS_CAN1 FALSE #define STM32_HAS_CAN2 FALSE +/* DAC attributes.*/ #define STM32_HAS_DAC TRUE +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA FALSE #define STM32_HAS_DMA1 TRUE #define STM32_HAS_DMA2 FALSE +/* ETH attributes.*/ #define STM32_HAS_ETH FALSE +/* EXTI attributes.*/ #define STM32_EXTI_NUM_CHANNELS 23 +/* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -194,18 +202,37 @@ #define STM32_HAS_GPIOH TRUE #define STM32_HAS_GPIOI FALSE +/* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE #define STM32_HAS_I2C2 TRUE #define STM32_HAS_I2C3 FALSE +/* RTC attributes.*/ #define STM32_HAS_RTC TRUE +/* SDIO attributes.*/ #define STM32_HAS_SDIO FALSE +/* SPI attributes.*/ #define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_SPI1_RX_DMA_CHN 0x00000000 +#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_SPI2 TRUE +#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_SPI3 FALSE +#define STM32_SPI3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 5) +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 6) +#define STM32_SPI3_TX_DMA_CHN 0x00000000 +/* TIM attributes.*/ #define STM32_HAS_TIM1 FALSE #define STM32_HAS_TIM2 TRUE #define STM32_HAS_TIM3 TRUE @@ -224,6 +251,7 @@ #define STM32_HAS_TIM16 FALSE #define STM32_HAS_TIM17 FALSE +/* USART attributes.*/ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 TRUE @@ -231,6 +259,7 @@ #define STM32_HAS_UART5 FALSE #define STM32_HAS_USART6 FALSE +/* USB attributes.*/ #define STM32_HAS_USB TRUE #define STM32_HAS_OTG1 FALSE #define STM32_HAS_OTG2 FALSE diff --git a/os/hal/platforms/STM32L1xx/stm32_dma.h b/os/hal/platforms/STM32L1xx/stm32_dma.h index 7cfcf7536..e22d99f2b 100644 --- a/os/hal/platforms/STM32L1xx/stm32_dma.h +++ b/os/hal/platforms/STM32L1xx/stm32_dma.h @@ -71,6 +71,28 @@ */ #define STM32_DMA_STREAM_ID(dma, stream) ((stream) - 1) +/** + * @brief Returns a DMA stream identifier mask. + * + * + * @param[in] dma the DMA unit number + * @param[in] stream the stream number + * @return A DMA stream identifier mask. + */ +#define STM32_DMA_STREAM_ID_MSK(dma, stream) \ + (1 << STM32_DMA_STREAM_ID(dma, stream)) + +/** + * @brief Checks if a DMA stream unique identifier belongs to a mask. + * @param[in] id the stream numeric identifier + * @param[in] mask the stream numeric identifiers mask + * + * @retval The check result. + * @retval FALSE id does not belong to the mask. + * @retval TRUE id belongs to the mask. + */ +#define STM32_DMA_IS_VALID_ID(id, mask) (((1 << (id)) & (mask))) + /** * @brief Returns a pointer to a stm32_dma_stream_t structure. * -- cgit v1.2.3 From 6eae3c1de5a1936247676750132758d17d9bdaf1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 11 Nov 2011 14:40:00 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3487 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/hal_lld_f100.h | 57 ++++++++++++ os/hal/platforms/STM32F1xx/hal_lld_f103.h | 116 +++++++++++++++++++++++++ os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h | 29 +++++++ os/hal/platforms/STM32F1xx/stm32_dma.h | 22 +++++ os/hal/platforms/STM32L1xx/hal_lld.h | 4 +- 5 files changed, 226 insertions(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f100.h b/os/hal/platforms/STM32F1xx/hal_lld_f100.h index 230b415ef..91be2eadb 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f100.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f100.h @@ -128,22 +128,30 @@ * @name STM32F100 LD capabilities * @{ */ +/* ADC attributes.*/ #define STM32_HAS_ADC1 TRUE #define STM32_HAS_ADC2 FALSE #define STM32_HAS_ADC3 FALSE +/* CAN attributes.*/ #define STM32_HAS_CAN1 FALSE #define STM32_HAS_CAN2 FALSE +/* DAC attributes.*/ #define STM32_HAS_DAC TRUE +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA FALSE #define STM32_HAS_DMA1 TRUE #define STM32_HAS_DMA2 FALSE +/* ETH attributes.*/ #define STM32_HAS_ETH FALSE +/* EXTI attributes.*/ #define STM32_EXTI_NUM_CHANNELS 19 +/* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -154,18 +162,36 @@ #define STM32_HAS_GPIOH FALSE #define STM32_HAS_GPIOI FALSE +/* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE #define STM32_HAS_I2C2 FALSE #define STM32_HAS_I2C3 FALSE #define STM32_HAS_RTC TRUE +/* SDIO attributes.*/ #define STM32_HAS_SDIO FALSE +/* SPI attributes.*/ #define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_SPI1_RX_DMA_CHN 0x00000000 +#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_SPI2 FALSE +#define STM32_SPI2_RX_DMA_MSK 0 +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK 0 +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_SPI3 FALSE +#define STM32_SPI3_RX_DMA_MSK 0 +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK 0 +#define STM32_SPI3_TX_DMA_CHN 0x00000000 +/* TIM attributes.*/ #define STM32_HAS_TIM1 TRUE #define STM32_HAS_TIM2 TRUE #define STM32_HAS_TIM3 TRUE @@ -184,6 +210,7 @@ #define STM32_HAS_TIM16 TRUE #define STM32_HAS_TIM17 TRUE +/* USART attributes.*/ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 FALSE @@ -191,6 +218,7 @@ #define STM32_HAS_UART5 FALSE #define STM32_HAS_USART6 FALSE +/* USB attributes.*/ #define STM32_HAS_USB FALSE #define STM32_HAS_OTG1 FALSE #define STM32_HAS_OTG2 FALSE @@ -202,22 +230,30 @@ * @name STM32F100 MD capabilities * @{ */ +/* ADC attributes.*/ #define STM32_HAS_ADC1 TRUE #define STM32_HAS_ADC2 FALSE #define STM32_HAS_ADC3 FALSE +/* CAN attributes.*/ #define STM32_HAS_CAN1 FALSE #define STM32_HAS_CAN2 FALSE +/* DAC attributes.*/ #define STM32_HAS_DAC TRUE +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA FALSE #define STM32_HAS_DMA1 TRUE #define STM32_HAS_DMA2 FALSE +/* ETH attributes.*/ #define STM32_HAS_ETH FALSE +/* EXTI attributes.*/ #define STM32_EXTI_NUM_CHANNELS 19 +/* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -228,18 +264,37 @@ #define STM32_HAS_GPIOH FALSE #define STM32_HAS_GPIOI FALSE +/* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE #define STM32_HAS_I2C2 TRUE #define STM32_HAS_I2C3 FALSE +/* RTC attributes.*/ #define STM32_HAS_RTC TRUE +/* SDIO attributes.*/ #define STM32_HAS_SDIO FALSE +/* SPI attributes.*/ #define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_SPI1_RX_DMA_CHN 0x00000000 +#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_SPI2 TRUE +#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_SPI3 FALSE +#define STM32_SPI3_RX_DMA_MSK 0 +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK 0 +#define STM32_SPI3_TX_DMA_CHN 0x00000000 +/* TIM attributes.*/ #define STM32_HAS_TIM1 TRUE #define STM32_HAS_TIM2 TRUE #define STM32_HAS_TIM3 TRUE @@ -258,6 +313,7 @@ #define STM32_HAS_TIM16 TRUE #define STM32_HAS_TIM17 TRUE +/* USART attributes.*/ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 TRUE @@ -265,6 +321,7 @@ #define STM32_HAS_UART5 FALSE #define STM32_HAS_USART6 FALSE +/* USB attributes.*/ #define STM32_HAS_USB FALSE #define STM32_HAS_OTG1 FALSE #define STM32_HAS_OTG2 FALSE diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f103.h b/os/hal/platforms/STM32F1xx/hal_lld_f103.h index ee265fe7f..1375bf7cf 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f103.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f103.h @@ -138,22 +138,30 @@ * @name STM32F103 LD capabilities * @{ */ +/* ADC attributes.*/ #define STM32_HAS_ADC1 TRUE #define STM32_HAS_ADC2 TRUE #define STM32_HAS_ADC3 FALSE +/* CAN attributes.*/ #define STM32_HAS_CAN1 TRUE #define STM32_HAS_CAN2 FALSE +/* DAC attributes.*/ #define STM32_HAS_DAC FALSE +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA FALSE #define STM32_HAS_DMA1 TRUE #define STM32_HAS_DMA2 FALSE +/* ETH attributes.*/ #define STM32_HAS_ETH FALSE +/* EXTI attributes.*/ #define STM32_EXTI_NUM_CHANNELS 19 +/* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -164,18 +172,37 @@ #define STM32_HAS_GPIOH FALSE #define STM32_HAS_GPIOI FALSE +/* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE #define STM32_HAS_I2C2 FALSE #define STM32_HAS_I2C3 FALSE +/* RTC attributes.*/ #define STM32_HAS_RTC TRUE +/* SDIO attributes.*/ #define STM32_HAS_SDIO FALSE +/* SPI attributes.*/ #define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_SPI1_RX_DMA_CHN 0x00000000 +#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_SPI2 FALSE +#define STM32_SPI2_RX_DMA_MSK 0 +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK 0 +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_SPI3 FALSE +#define STM32_SPI3_RX_DMA_MSK 0 +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK 0 +#define STM32_SPI3_TX_DMA_CHN 0x00000000 +/* TIM attributes.*/ #define STM32_HAS_TIM1 TRUE #define STM32_HAS_TIM2 TRUE #define STM32_HAS_TIM3 TRUE @@ -194,6 +221,7 @@ #define STM32_HAS_TIM16 FALSE #define STM32_HAS_TIM17 FALSE +/* USART attributes.*/ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 FALSE @@ -201,6 +229,7 @@ #define STM32_HAS_UART5 FALSE #define STM32_HAS_USART6 FALSE +/* USB attributes.*/ #define STM32_HAS_USB FALSE #define STM32_HAS_OTG1 FALSE #define STM32_HAS_OTG2 FALSE @@ -212,22 +241,30 @@ * @name STM32F103 MD capabilities * @{ */ +/* ADC attributes.*/ #define STM32_HAS_ADC1 TRUE #define STM32_HAS_ADC2 TRUE #define STM32_HAS_ADC3 FALSE +/* CAN attributes.*/ #define STM32_HAS_CAN1 TRUE #define STM32_HAS_CAN2 FALSE +/* DAC attributes.*/ #define STM32_HAS_DAC FALSE +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA FALSE #define STM32_HAS_DMA1 TRUE #define STM32_HAS_DMA2 FALSE +/* ETH attributes.*/ #define STM32_HAS_ETH FALSE +/* EXTI attributes.*/ #define STM32_EXTI_NUM_CHANNELS 19 +/* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -238,18 +275,37 @@ #define STM32_HAS_GPIOH FALSE #define STM32_HAS_GPIOI FALSE +/* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE #define STM32_HAS_I2C2 TRUE #define STM32_HAS_I2C3 FALSE +/* RTC attributes.*/ #define STM32_HAS_RTC TRUE +/* SDIO attributes.*/ #define STM32_HAS_SDIO FALSE +/* SPI attributes.*/ #define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_SPI1_RX_DMA_CHN 0x00000000 +#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_SPI2 TRUE +#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_SPI3 FALSE +#define STM32_SPI3_RX_DMA_MSK 0 +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK 0 +#define STM32_SPI3_TX_DMA_CHN 0x00000000 +/* TIM attributes.*/ #define STM32_HAS_TIM1 TRUE #define STM32_HAS_TIM2 TRUE #define STM32_HAS_TIM3 TRUE @@ -268,6 +324,7 @@ #define STM32_HAS_TIM16 FALSE #define STM32_HAS_TIM17 FALSE +/* USART attributes.*/ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 TRUE @@ -275,6 +332,7 @@ #define STM32_HAS_UART5 FALSE #define STM32_HAS_USART6 FALSE +/* USB attributes.*/ #define STM32_HAS_USB TRUE #define STM32_HAS_OTG1 FALSE #define STM32_HAS_OTG2 FALSE @@ -286,22 +344,30 @@ * @name STM32F103 HD capabilities * @{ */ +/* ADC attributes.*/ #define STM32_HAS_ADC1 TRUE #define STM32_HAS_ADC2 TRUE #define STM32_HAS_ADC3 TRUE +/* CAN attributes.*/ #define STM32_HAS_CAN1 TRUE #define STM32_HAS_CAN2 FALSE +/* DAC attributes.*/ #define STM32_HAS_DAC TRUE +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA FALSE #define STM32_HAS_DMA1 TRUE #define STM32_HAS_DMA2 TRUE +/* ETH attributes.*/ #define STM32_HAS_ETH FALSE +/* EXTI attributes.*/ #define STM32_EXTI_NUM_CHANNELS 19 +/* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -312,18 +378,37 @@ #define STM32_HAS_GPIOH FALSE #define STM32_HAS_GPIOI FALSE +/* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE #define STM32_HAS_I2C2 TRUE #define STM32_HAS_I2C3 FALSE +/* RTC attributes.*/ #define STM32_HAS_RTC TRUE +/* SDIO attributes.*/ #define STM32_HAS_SDIO TRUE +/* SPI attributes.*/ #define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_SPI1_RX_DMA_CHN 0x00000000 +#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_SPI2 TRUE +#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_SPI3 TRUE +#define STM32_SPI3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 5) +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 6) +#define STM32_SPI3_TX_DMA_CHN 0x00000000 +/* TIM attributes.*/ #define STM32_HAS_TIM1 TRUE #define STM32_HAS_TIM2 TRUE #define STM32_HAS_TIM3 TRUE @@ -342,6 +427,7 @@ #define STM32_HAS_TIM16 FALSE #define STM32_HAS_TIM17 FALSE +/* USART attributes.*/ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 TRUE @@ -349,6 +435,7 @@ #define STM32_HAS_UART5 TRUE #define STM32_HAS_USART6 FALSE +/* USB attributes.*/ #define STM32_HAS_USB TRUE #define STM32_HAS_OTG1 FALSE #define STM32_HAS_OTG2 FALSE @@ -360,22 +447,30 @@ * @name STM32F103 XL capabilities * @{ */ +/* ADC attributes.*/ #define STM32_HAS_ADC1 TRUE #define STM32_HAS_ADC2 TRUE #define STM32_HAS_ADC3 TRUE +/* CAN attributes.*/ #define STM32_HAS_CAN1 TRUE #define STM32_HAS_CAN2 FALSE +/* DAC attributes.*/ #define STM32_HAS_DAC TRUE +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA FALSE #define STM32_HAS_DMA1 TRUE #define STM32_HAS_DMA2 TRUE +/* ETH attributes.*/ #define STM32_HAS_ETH FALSE +/* EXTI attributes.*/ #define STM32_EXTI_NUM_CHANNELS 19 +/* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -386,18 +481,37 @@ #define STM32_HAS_GPIOH FALSE #define STM32_HAS_GPIOI FALSE +/* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE #define STM32_HAS_I2C2 TRUE #define STM32_HAS_I2C3 FALSE +/* RTC attributes.*/ #define STM32_HAS_RTC TRUE +/* SDIO attributes.*/ #define STM32_HAS_SDIO TRUE +/* SPI attributes.*/ #define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_SPI1_RX_DMA_CHN 0x00000000 +#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_SPI2 TRUE +#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_SPI3 TRUE +#define STM32_SPI3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 5) +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 6) +#define STM32_SPI3_TX_DMA_CHN 0x00000000 +/* TIM attributes.*/ #define STM32_HAS_TIM1 TRUE #define STM32_HAS_TIM2 TRUE #define STM32_HAS_TIM3 TRUE @@ -416,6 +530,7 @@ #define STM32_HAS_TIM16 FALSE #define STM32_HAS_TIM17 FALSE +/* USART attributes.*/ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 TRUE @@ -423,6 +538,7 @@ #define STM32_HAS_UART5 TRUE #define STM32_HAS_USART6 FALSE +/* USB attributes.*/ #define STM32_HAS_USB TRUE #define STM32_HAS_OTG1 FALSE #define STM32_HAS_OTG2 FALSE diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h index cc9b2f796..b8eb11c3b 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h @@ -130,22 +130,30 @@ * @name STM32F105/F107 CL capabilities * @{ */ +/* ADC attributes.*/ #define STM32_HAS_ADC1 TRUE #define STM32_HAS_ADC2 TRUE #define STM32_HAS_ADC3 FALSE +/* CAN attributes.*/ #define STM32_HAS_CAN1 TRUE #define STM32_HAS_CAN2 TRUE +/* DAC attributes.*/ #define STM32_HAS_DAC TRUE +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA FALSE #define STM32_HAS_DMA1 TRUE #define STM32_HAS_DMA2 TRUE +/* ETH attributes.*/ #define STM32_HAS_ETH TRUE +/* EXTI attributes.*/ #define STM32_EXTI_NUM_CHANNELS 20 +/* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE #define STM32_HAS_GPIOB TRUE #define STM32_HAS_GPIOC TRUE @@ -156,18 +164,37 @@ #define STM32_HAS_GPIOH FALSE #define STM32_HAS_GPIOI FALSE +/* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE #define STM32_HAS_I2C2 TRUE #define STM32_HAS_I2C3 FALSE +/* RTC attributes.*/ #define STM32_HAS_RTC TRUE +/* SDIO attributes.*/ #define STM32_HAS_SDIO FALSE +/* SPI attributes.*/ #define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_SPI1_RX_DMA_CHN 0x00000000 +#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_SPI2 TRUE +#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_SPI3 TRUE +#define STM32_SPI3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 5) +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 6) +#define STM32_SPI3_TX_DMA_CHN 0x00000000 +/* TIM attributes.*/ #define STM32_HAS_TIM1 TRUE #define STM32_HAS_TIM2 TRUE #define STM32_HAS_TIM3 TRUE @@ -186,6 +213,7 @@ #define STM32_HAS_TIM16 FALSE #define STM32_HAS_TIM17 FALSE +/* USART attributes.*/ #define STM32_HAS_USART1 TRUE #define STM32_HAS_USART2 TRUE #define STM32_HAS_USART3 TRUE @@ -193,6 +221,7 @@ #define STM32_HAS_UART5 TRUE #define STM32_HAS_USART6 FALSE +/* USB attributes.*/ #define STM32_HAS_USB FALSE #define STM32_HAS_OTG1 TRUE #define STM32_HAS_OTG2 FALSE diff --git a/os/hal/platforms/STM32F1xx/stm32_dma.h b/os/hal/platforms/STM32F1xx/stm32_dma.h index e01708d64..4469bef67 100644 --- a/os/hal/platforms/STM32F1xx/stm32_dma.h +++ b/os/hal/platforms/STM32F1xx/stm32_dma.h @@ -62,6 +62,28 @@ */ #define STM32_DMA_GETCHANNEL(n, c) 0 +/** + * @brief Returns a DMA stream identifier mask. + * + * + * @param[in] dma the DMA unit number + * @param[in] stream the stream number + * @return A DMA stream identifier mask. + */ +#define STM32_DMA_STREAM_ID_MSK(dma, stream) \ + (1 << STM32_DMA_STREAM_ID(dma, stream)) + +/** + * @brief Checks if a DMA stream unique identifier belongs to a mask. + * @param[in] id the stream numeric identifier + * @param[in] mask the stream numeric identifiers mask + * + * @retval The check result. + * @retval FALSE id does not belong to the mask. + * @retval TRUE id belongs to the mask. + */ +#define STM32_DMA_IS_VALID_ID(id, mask) (((1 << (id)) & (mask))) + /** * @name DMA streams identifiers * @{ diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index 08990ee13..8d8f1b23b 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -227,9 +227,9 @@ #define STM32_SPI2_TX_DMA_CHN 0x00000000 #define STM32_HAS_SPI3 FALSE -#define STM32_SPI3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 5) +#define STM32_SPI3_RX_DMA_MSK 0 #define STM32_SPI3_RX_DMA_CHN 0x00000000 -#define STM32_SPI3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 6) +#define STM32_SPI3_TX_DMA_MSK 0 #define STM32_SPI3_TX_DMA_CHN 0x00000000 /* TIM attributes.*/ -- cgit v1.2.3 From ec1bf1b741390d7b6128382971b504a3ee9b7111 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 13 Nov 2011 10:55:33 +0000 Subject: STM32F4xx SPI driver working. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3490 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/spi_lld.c | 12 +++++++++++- os/hal/platforms/STM32F1xx/stm32_dma.h | 1 + os/hal/platforms/STM32F4xx/stm32_dma.h | 2 +- os/hal/platforms/STM32L1xx/stm32_dma.h | 1 + 4 files changed, 14 insertions(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/spi_lld.c b/os/hal/platforms/STM32/spi_lld.c index 1511547d5..2610031b6 100644 --- a/os/hal/platforms/STM32/spi_lld.c +++ b/os/hal/platforms/STM32/spi_lld.c @@ -106,9 +106,11 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { (void)flags; #endif - /* Stop everything.*/ + /* Stop everything. The status of the TX DMA is cleared here because its + handler is only invoked in case of error.*/ dmaStreamDisable(spip->dmatx); dmaStreamDisable(spip->dmarx); + dmaStreamClearInterrupt(spip->dmatx); /* Portable SPI ISR code defined in the high level driver, note, it is a macro.*/ @@ -161,10 +163,12 @@ void spi_lld_init(void) { STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_TCIE | + STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; SPID1.txdmamode = STM32_DMA_CR_CHSEL(SPI1_TX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; #endif @@ -177,10 +181,12 @@ void spi_lld_init(void) { STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_TCIE | + STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; SPID2.txdmamode = STM32_DMA_CR_CHSEL(SPI2_TX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; #endif @@ -193,10 +199,12 @@ void spi_lld_init(void) { STM32_DMA_CR_PL(STM32_SPI_SPI3_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_TCIE | + STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; SPID3.txdmamode = STM32_DMA_CR_CHSEL(SPI3_TX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_SPI_SPI3_DMA_PRIORITY) | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; #endif } @@ -360,6 +368,7 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) { dmaStreamSetMemory0(spip->dmarx, &dummyrx); dmaStreamSetTransactionSize(spip->dmarx, n); dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, &dummytx); dmaStreamSetTransactionSize(spip->dmatx, n); dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_EN); @@ -411,6 +420,7 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { dmaStreamSetMemory0(spip->dmarx, &dummyrx); dmaStreamSetTransactionSize(spip->dmarx, n); dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, txbuf); dmaStreamSetTransactionSize(spip->dmatx, n); dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_MINC | diff --git a/os/hal/platforms/STM32F1xx/stm32_dma.h b/os/hal/platforms/STM32F1xx/stm32_dma.h index 4469bef67..fdfd0bc7b 100644 --- a/os/hal/platforms/STM32F1xx/stm32_dma.h +++ b/os/hal/platforms/STM32F1xx/stm32_dma.h @@ -153,6 +153,7 @@ * @name CR register constants only found in enhanced DMA * @{ */ +#define STM32_DMA_CR_DMEIE 0 /**< @brief Ignored by normal DMA. */ #define STM32_DMA_CR_CHSEL_MASK 0 /**< @brief Ignored by normal DMA. */ #define STM32_DMA_CR_CHSEL(n) 0 /**< @brief Ignored by normal DMA. */ /** @} */ diff --git a/os/hal/platforms/STM32F4xx/stm32_dma.h b/os/hal/platforms/STM32F4xx/stm32_dma.h index d07a9dbe9..4b3302f39 100644 --- a/os/hal/platforms/STM32F4xx/stm32_dma.h +++ b/os/hal/platforms/STM32F4xx/stm32_dma.h @@ -171,7 +171,7 @@ /** @} */ /** - * @name FCR register constants only found in STM32F2xx + * @name FCR register constants only found in STM32F2xx/STM32F4xx * @{ */ #define STM32_DMA_FCR_FEIE DMA_SxFCR_FEIE diff --git a/os/hal/platforms/STM32L1xx/stm32_dma.h b/os/hal/platforms/STM32L1xx/stm32_dma.h index e22d99f2b..0d80a39e7 100644 --- a/os/hal/platforms/STM32L1xx/stm32_dma.h +++ b/os/hal/platforms/STM32L1xx/stm32_dma.h @@ -144,6 +144,7 @@ * @name CR register constants only found in enhanced DMA * @{ */ +#define STM32_DMA_CR_DMEIE 0 /**< @brief Ignored by normal DMA. */ #define STM32_DMA_CR_CHSEL_MASK 0 /**< @brief Ignored by normal DMA. */ #define STM32_DMA_CR_CHSEL(n) 0 /**< @brief Ignored by normal DMA. */ /** @} */ -- cgit v1.2.3 From d4187a3454cbfb1735d286d4acf23b062b1febdf Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 15 Nov 2011 19:06:48 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3494 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/hal_lld.h | 9 +++++++++ os/hal/platforms/STM32F4xx/platform.mk | 1 + 2 files changed, 10 insertions(+) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index fc40b51a9..8bcde1083 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -1238,6 +1238,15 @@ #define STM32_FLASHBITS 0x00000007 #endif +/* There are differences in vector names in the various sub-families, + normalizing.*/ +#define TIM1_BRK_IRQn TIM1_BRK_TIM9_IRQn +#define TIM1_UP_IRQn TIM1_UP_TIM10_IRQn +#define TIM1_TRG_COM_IRQn TIM1_TRG_COM_TIM11_IRQn +#define TIM8_BRK_IRQn TIM8_BRK_TIM12_IRQn +#define TIM8_UP_IRQn TIM8_UP_TIM13_IRQn +#define TIM8_TRG_COM_IRQn TIM8_TRG_COM_TIM14_IRQn + /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F4xx/platform.mk b/os/hal/platforms/STM32F4xx/platform.mk index 6b7df146b..ca66471d5 100644 --- a/os/hal/platforms/STM32F4xx/platform.mk +++ b/os/hal/platforms/STM32F4xx/platform.mk @@ -1,6 +1,7 @@ # List of all the STM32L1xx platform files. PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32L1xx/stm32_dma.c \ ${CHIBIOS}/os/hal/platforms/STM32F4xx/hal_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/gpt_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/serial_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c -- cgit v1.2.3 From 5bb68f6827e03e5b343c66f1236d84f73bc07df9 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 16 Nov 2011 17:42:54 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3497 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/hal_lld.h | 11 +++++++++++ os/hal/platforms/STM32F4xx/platform.mk | 5 +++++ 2 files changed, 16 insertions(+) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index 8bcde1083..11bdfedd6 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -251,8 +251,19 @@ */ /* ADC attributes.*/ #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 /* CAN attributes.*/ #define STM32_HAS_CAN1 TRUE diff --git a/os/hal/platforms/STM32F4xx/platform.mk b/os/hal/platforms/STM32F4xx/platform.mk index ca66471d5..1b9ca04dc 100644 --- a/os/hal/platforms/STM32F4xx/platform.mk +++ b/os/hal/platforms/STM32F4xx/platform.mk @@ -1,9 +1,14 @@ # List of all the STM32L1xx platform files. PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32L1xx/stm32_dma.c \ ${CHIBIOS}/os/hal/platforms/STM32F4xx/hal_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/adc_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/ext_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/gpt_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/icu_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/pwm_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/serial_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/uart_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c # Required include directories -- cgit v1.2.3 From 5ed2f28ec0e5031ab79b50f6c61964273023567e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 16 Nov 2011 17:45:07 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3498 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/adc_lld.c | 378 +++++++++++++++++++++++ os/hal/platforms/STM32F4xx/adc_lld.h | 567 +++++++++++++++++++++++++++++++++++ 2 files changed, 945 insertions(+) create mode 100644 os/hal/platforms/STM32F4xx/adc_lld.c create mode 100644 os/hal/platforms/STM32F4xx/adc_lld.h (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/adc_lld.c b/os/hal/platforms/STM32F4xx/adc_lld.c new file mode 100644 index 000000000..f78c7ac0f --- /dev/null +++ b/os/hal/platforms/STM32F4xx/adc_lld.c @@ -0,0 +1,378 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32F4xx/adc_lld.c + * @brief STM32F4xx ADC subsystem low level driver source. + * + * @addtogroup ADC + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_ADC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define ADC1_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_CHN) + +#define ADC2_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_ADC_ADC2_DMA_STREAM, STM32_ADC2_DMA_CHN) + +#define ADC3_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_ADC_ADC3_DMA_STREAM, STM32_ADC3_DMA_CHN) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief ADC1 driver identifier.*/ +#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__) +ADCDriver ADCD1; +#endif + +/** @brief ADC2 driver identifier.*/ +#if STM32_ADC_USE_ADC2 || defined(__DOXYGEN__) +ADCDriver ADCD2; +#endif + +/** @brief ADC3 driver identifier.*/ +#if STM32_ADC_USE_ADC3 || defined(__DOXYGEN__) +ADCDriver ADCD3; +#endif + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* 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) != 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 { + if ((flags & STM32_DMA_ISR_HTIF) != 0) { + /* Half transfer processing.*/ + _adc_isr_half_code(adcp); + } + if ((flags & STM32_DMA_ISR_TCIF) != 0) { + /* Transfer complete processing.*/ + _adc_isr_full_code(adcp); + } + } +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2 || STM32_ADC_USE_ADC3 || \ + defined(__DOXYGEN__) +/** + * @brief ADC interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(ADC1_2_3_IRQHandler) { + uint32_t sr; + + CH_IRQ_PROLOGUE(); + +#if STM32_ADC_USE_ADC1 + sr = ADC1->SR; + ADC1->SR = 0; + if (sr & ADC_SR_OVR) { + /* ADC overflow condition, this could happen only if the DMA is unable + to read data fast enough.*/ + _adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW); + } + /* TODO: Add here analog watchdog handling.*/ +#endif /* STM32_ADC_USE_ADC1 */ + +#if STM32_ADC_USE_ADC2 + sr = ADC2->SR; + ADC2->SR = 0; + if (sr & ADC_SR_OVR) { + /* ADC overflow condition, this could happen only if the DMA is unable + to read data fast enough.*/ + _adc_isr_error_code(&ADCD2, ADC_ERR_OVERFLOW); + } + /* TODO: Add here analog watchdog handling.*/ +#endif /* STM32_ADC_USE_ADC2 */ + +#if STM32_ADC_USE_ADC3 + sr = ADC3->SR; + ADC3->SR = 0; + if (sr & ADC_SR_OVR) { + /* ADC overflow condition, this could happen only if the DMA is unable + to read data fast enough.*/ + _adc_isr_error_code(&ADCD3, ADC_ERR_OVERFLOW); + } + /* TODO: Add here analog watchdog handling.*/ +#endif /* STM32_ADC_USE_ADC3 */ + + CH_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level ADC driver initialization. + * + * @notapi + */ +void adc_lld_init(void) { + + ADC->CCR = STM32_ADC_ADCPRE; + +#if STM32_ADC_USE_ADC1 + /* Driver initialization.*/ + adcObjectInit(&ADCD1); + ADCD1.adc = ADC1; + ADCD1.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC1_DMA_STREAM); + ADCD1.dmamode = STM32_DMA_CR_CHSEL(ADC1_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) | + STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | + STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | + STM32_DMA_CR_TEIE | STM32_DMA_CR_EN; +#endif + +#if STM32_ADC_USE_ADC2 + /* Driver initialization.*/ + adcObjectInit(&ADCD2); + ADCD1.adc = ADC2; + ADCD1.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC2_DMA_STREAM); + ADCD1.dmamode = STM32_DMA_CR_CHSEL(ADC2_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_ADC_ADC2_DMA_PRIORITY) | + STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | + STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | + STM32_DMA_CR_TEIE | STM32_DMA_CR_EN; +#endif + +#if STM32_ADC_USE_ADC3 + /* Driver initialization.*/ + adcObjectInit(&ADCD3); + ADCD1.adc = ADC3; + ADCD1.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC3_DMA_STREAM); + ADCD1.dmamode = STM32_DMA_CR_CHSEL(ADC3_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_ADC_ADC3_DMA_PRIORITY) | + STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | + STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | + STM32_DMA_CR_TEIE | STM32_DMA_CR_EN; +#endif + + /* The shared vector is initialized on driver initialization and never + disabled.*/ + NVICEnableVector(ADC_IRQn, CORTEX_PRIORITY_MASK(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) { + bool_t b; + b = dmaStreamAllocate(adcp->dmastp, + STM32_ADC_ADC1_DMA_IRQ_PRIORITY, + (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, + (void *)adcp); + chDbgAssert(!b, "adc_lld_start(), #1", "stream already allocated"); + dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR); + rccEnableADC1(FALSE); + } +#endif /* STM32_ADC_USE_ADC1 */ + +#if STM32_ADC_USE_ADC2 + if (&ADCD2 == adcp) { + bool_t b; + b = dmaStreamAllocate(adcp->dmastp, + STM32_ADC_ADC2_DMA_IRQ_PRIORITY, + (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, + (void *)adcp); + chDbgAssert(!b, "adc_lld_start(), #2", "stream already allocated"); + dmaStreamSetPeripheral(adcp->dmastp, &ADC2->DR); + rccEnableADC2(FALSE); + } +#endif /* STM32_ADC_USE_ADC2 */ + +#if STM32_ADC_USE_ADC3 + if (&ADCD3 == adcp) { + bool_t b; + b = dmaStreamAllocate(adcp->dmastp, + STM32_ADC_ADC3_DMA_IRQ_PRIORITY, + (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, + (void *)adcp); + chDbgAssert(!b, "adc_lld_start(), #3", "stream already allocated"); + dmaStreamSetPeripheral(adcp->dmastp, &ADC3->DR); + rccEnableADC3(FALSE); + } +#endif /* STM32_ADC_USE_ADC3 */ + + /* ADC initial setup, just resetting control registers in this case.*/ + adcp->adc->CR1 = 0; + adcp->adc->CR2 = 0; + } +} + +/** + * @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.*/ + if (adcp->state == ADC_READY) { + dmaStreamRelease(adcp->dmastp); + adcp->adc->CR1 = 0; + adcp->adc->CR2 = 0; + +#if STM32_ADC_USE_ADC1 + if (&ADCD1 == adcp) + rccDisableADC1(FALSE); +#endif + +#if STM32_ADC_USE_ADC2 + if (&ADCD2 == adcp) + rccDisableADC2(FALSE); +#endif + +#if STM32_ADC_USE_ADC3 + if (&ADCD3 == adcp) + rccDisableADC3(FALSE); +#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; + const ADCConversionGroup *grpp = adcp->grpp; + + /* DMA setup.*/ + mode = adcp->dmamode; + if (grpp->circular) { + mode |= STM32_DMA_CR_CIRC; + } + if (adcp->depth > 1) { + /* If the buffer depth is greater than one then the half transfer interrupt + interrupt is enabled in order to allows 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); + + /* ADC setup.*/ + adcp->adc->SR = 0; + adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN; + adcp->adc->SMPR1 = grpp->smpr1; /* Writing SMPRx requires ADON=0. */ + adcp->adc->SMPR2 = grpp->smpr2; + adcp->adc->CR2 = grpp->cr2 | ADC_CR2_CONT | ADC_CR2_DMA | ADC_CR2_DDS | + ADC_CR2_ADON; + adcp->adc->SQR1 = grpp->sqr1; + adcp->adc->SQR2 = grpp->sqr2; + adcp->adc->SQR3 = grpp->sqr3; + /* Must wait the ADC to be ready for conversion, see 9.3.6 "Timing diagram" + in the Reference Manual.*/ + while ((adcp->adc->SR & ADC_SR_ADONS) == 0) + ; + /* ADC start by raising ADC_CR2_SWSTART.*/ + adcp->adc->CR2 = grpp->cr2 | ADC_CR2_SWSTART | ADC_CR2_CONT | ADC_CR2_DMA | + ADC_CR2_DDS | ADC_CR2_ADON; +} + +/** + * @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; +} + +/** + * @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/os/hal/platforms/STM32F4xx/adc_lld.h b/os/hal/platforms/STM32F4xx/adc_lld.h new file mode 100644 index 000000000..0e846f50a --- /dev/null +++ b/os/hal/platforms/STM32F4xx/adc_lld.h @@ -0,0 +1,567 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32F4xx/adc_lld.h + * @brief STM32F4xx ADC subsystem low level driver header. + * + * @addtogroup ADC + * @{ + */ + +#ifndef _ADC_LLD_H_ +#define _ADC_LLD_H_ + +#if HAL_USE_ADC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Absolute Maximum Ratings + * @{ + */ +/** + * @brief Maximum HSE clock frequency. + */ +#define STM32_ADCCLK_MIN 600000 + +/** + * @brief Maximum HSE clock frequency. + * @note This value is arbitrary defined, the current datasheet does not + * define a maximum value (it is TBD). A value of 36MHz is mentioned + * but without relationship to VDD ranges. + */ +#define STM32_ADCCLK_MAX 42000000 +/** @} */ + +/** + * @name Triggers selection + * @{ + */ +#define ADC_CR2_EXTSEL_SRC(n) ((n) << 24) /**< @brief Trigger source. */ +/** @} */ + +/** + * @name ADC clock divider settings + * @{ + */ +#define ADC_CCR_ADCPRE_DIV2 0 +#define ADC_CCR_ADCPRE_DIV4 1 +#define ADC_CCR_ADCPRE_DIV6 2 +#define ADC_CCR_ADCPRE_DIV8 3 +/** @} */ + +/** + * @name Available analog channels + * @{ + */ +#define ADC_CHANNEL_IN0 0 /**< @brief External analog input 0. */ +#define ADC_CHANNEL_IN1 1 /**< @brief External analog input 1. */ +#define ADC_CHANNEL_IN2 2 /**< @brief External analog input 2. */ +#define ADC_CHANNEL_IN3 3 /**< @brief External analog input 3. */ +#define ADC_CHANNEL_IN4 4 /**< @brief External analog input 4. */ +#define ADC_CHANNEL_IN5 5 /**< @brief External analog input 5. */ +#define ADC_CHANNEL_IN6 6 /**< @brief External analog input 6. */ +#define ADC_CHANNEL_IN7 7 /**< @brief External analog input 7. */ +#define ADC_CHANNEL_IN8 8 /**< @brief External analog input 8. */ +#define ADC_CHANNEL_IN9 9 /**< @brief External analog input 9. */ +#define ADC_CHANNEL_IN10 10 /**< @brief External analog input 10. */ +#define ADC_CHANNEL_IN11 11 /**< @brief External analog input 11. */ +#define ADC_CHANNEL_IN12 12 /**< @brief External analog input 12. */ +#define ADC_CHANNEL_IN13 13 /**< @brief External analog input 13. */ +#define ADC_CHANNEL_IN14 14 /**< @brief External analog input 14. */ +#define ADC_CHANNEL_IN15 15 /**< @brief External analog input 15. */ +#define ADC_CHANNEL_SENSOR 16 /**< @brief Internal temperature sensor. + @note Available onADC1 only. */ +#define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference. + @note Available onADC1 only. */ +#define ADC_CHANNEL_VBAT 18 /**< @brief VBAT. + @note Available onADC1 only. */ +/** @} */ + +/** + * @name Sampling rates + * @{ + */ +#define ADC_SAMPLE_3 0 /**< @brief 3 cycles sampling time. */ +#define ADC_SAMPLE_15 1 /**< @brief 15 cycles sampling time. */ +#define ADC_SAMPLE_28 2 /**< @brief 28 cycles sampling time. */ +#define ADC_SAMPLE_56 3 /**< @brief 56 cycles sampling time. */ +#define ADC_SAMPLE_84 4 /**< @brief 84 cycles sampling time. */ +#define ADC_SAMPLE_112 5 /**< @brief 112 cycles sampling time. */ +#define ADC_SAMPLE_144 6 /**< @brief 144 cycles sampling time. */ +#define ADC_SAMPLE_480 7 /**< @brief 480 cycles sampling time. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief ADC common clock divider. + * @note This setting is influenced by the VDDA voltage and other + * external conditions, please refer to the STM32L15x datasheet + * for more info.
+ * See section 6.3.15 "12-bit ADC characteristics". + */ +#if !defined(STM32_ADC_ADCPRE) || defined(__DOXYGEN__) +#define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV2 +#endif + +/** + * @brief ADC1 driver enable switch. + * @details If set to @p TRUE the support for ADC1 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__) +#define STM32_ADC_USE_ADC1 TRUE +#endif + +/** + * @brief ADC2 driver enable switch. + * @details If set to @p TRUE the support for ADC2 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_ADC_USE_ADC2) || defined(__DOXYGEN__) +#define STM32_ADC_USE_ADC2 TRUE +#endif + +/** + * @brief ADC3 driver enable switch. + * @details If set to @p TRUE the support for ADC3 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_ADC_USE_ADC3) || defined(__DOXYGEN__) +#define STM32_ADC_USE_ADC3 TRUE +#endif + +/** + * @brief DMA stream used for ADC1 operations. + */ +#if !defined(STM32_ADC_ADC1_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#endif + +/** + * @brief DMA stream used for ADC2 operations. + */ +#if !defined(STM32_ADC_ADC2_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) +#endif + +/** + * @brief DMA stream used for ADC3 operations. + */ +#if !defined(STM32_ADC_ADC3_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#endif + +/** + * @brief ADC1 DMA priority (0..3|lowest..highest). + */ +#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_ADC_ADC1_DMA_PRIORITY 2 +#endif + +/** + * @brief ADC2 DMA priority (0..3|lowest..highest). + */ +#if !defined(STM32_ADC_ADC2_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_ADC_ADC2_DMA_PRIORITY 2 +#endif + +/** + * @brief ADC3 DMA priority (0..3|lowest..highest). + */ +#if !defined(STM32_ADC_ADC3_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_ADC_ADC3_DMA_PRIORITY 2 +#endif + +/** + * @brief ADC interrupt priority level setting. + * @note This setting is shared among ADC1, ADC2 and ADC3 because + * all ADCs share the same vector. + */ +#if !defined(STM32_ADC_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_ADC_IRQ_PRIORITY 5 +#endif + +/** + * @brief ADC1 DMA interrupt priority level setting. + */ +#if !defined(STM32_ADC_ADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5 +#endif + +/** + * @brief ADC2 DMA interrupt priority level setting. + */ +#if !defined(STM32_ADC_ADC2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 5 +#endif + +/** + * @brief ADC3 DMA interrupt priority level setting. + */ +#if !defined(STM32_ADC_ADC3_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 5 +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1 +#error "ADC1 not present in the selected device" +#endif + +#if STM32_ADC_USE_ADC2 && !STM32_HAS_ADC2 +#error "ADC2 not present in the selected device" +#endif + +#if STM32_ADC_USE_ADC3 && !STM32_HAS_ADC3 +#error "ADC3 not present in the selected device" +#endif + +#if !STM32_ADC_USE_ADC1 && !STM32_ADC_USE_ADC2 && !STM32_ADC_USE_ADC3 +#error "ADC driver activated but no ADC peripheral assigned" +#endif + +#if STM32_ADC_USE_ADC1 && \ + !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_MSK) +#error "invalid DMA stream associated to ADC1" +#endif + +#if STM32_ADC_USE_ADC2 && \ + !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC2_DMA_STREAM, STM32_ADC2_DMA_MSK) +#error "invalid DMA stream associated to ADC2" +#endif + +#if STM32_ADC_USE_ADC3 && \ + !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC3_DMA_STREAM, STM32_ADC3_DMA_MSK) +#error "invalid DMA stream associated to ADC3" +#endif + +/* ADC clock related settings and checks.*/ +#if STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV2 +#define STM32_ADCCLK (STM32_PCLK2 / 2) +#elif STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV4 +#define STM32_ADCCLK (STM32_PCLK2 / 4) +#elif STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV6 +#define STM32_ADCCLK (STM32_PCLK2 / 6) +#elif STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV8 +#define STM32_ADCCLK (STM32_PCLK2 / 8) +#else +#error "invalid STM32_ADC_ADCPRE value specified" +#endif + +#if (STM32_ADCCLK < STM32_ADCCLK_MIN) || (STM32_ADCCLK > STM32_ADCCLK_MAX) +#error "STM32_ADCCLK outside acceptable range (STM32_ADCCLK_MIN...STM32_ADCCLK_MAX)" +#endif + +#if !defined(STM32_DMA_REQUIRED) +#define STM32_DMA_REQUIRED +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief ADC sample data type. + */ +typedef uint16_t adcsample_t; + +/** + * @brief Channels number in a conversion group. + */ +typedef uint16_t adc_channels_num_t; + +/** + * @brief Possible ADC failure causes. + * @note Error codes are architecture dependent and should not relied + * upon. + */ +typedef enum { + ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */ + ADC_ERR_OVERFLOW = 1 /**< ADC overflow condition. */ +} adcerror_t; + +/** + * @brief Type of a structure representing an ADC driver. + */ +typedef struct ADCDriver ADCDriver; + +/** + * @brief ADC notification callback type. + * + * @param[in] adcp pointer to the @p ADCDriver object triggering the + * callback + * @param[in] buffer pointer to the most recent samples data + * @param[in] n number of buffer rows available starting from @p buffer + */ +typedef void (*adccallback_t)(ADCDriver *adcp, adcsample_t *buffer, size_t n); + +/** + * @brief ADC error callback type. + * + * @param[in] adcp pointer to the @p ADCDriver object triggering the + * callback + */ +typedef void (*adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err); + +/** + * @brief Conversion group configuration structure. + * @details This implementation-dependent structure describes a conversion + * operation. + * @note The use of this configuration structure requires knowledge of + * STM32 ADC cell registers interface, please refer to the STM32 + * reference manual for details. + */ +typedef struct { + /** + * @brief Enables the circular buffer mode for the group. + */ + bool_t circular; + /** + * @brief Number of the analog channels belonging to the conversion group. + */ + adc_channels_num_t num_channels; + /** + * @brief Callback function associated to the group or @p NULL. + */ + adccallback_t end_cb; + /** + * @brief Error callback or @p NULL. + */ + adcerrorcallback_t error_cb; + /* End of the mandatory fields.*/ + /** + * @brief ADC CR1 register initialization data. + * @note All the required bits must be defined into this field except + * @p ADC_CR1_SCAN that is enforced inside the driver. + */ + uint32_t cr1; + /** + * @brief ADC CR2 register initialization data. + * @note All the required bits must be defined into this field except + * @p ADC_CR2_DMA, @p ADC_CR2_CONT and @p ADC_CR2_ADON that are + * enforced inside the driver. + */ + uint32_t cr2; + /** + * @brief ADC SMPR1 register initialization data. + * @details In this field must be specified the sample times for channels + * 10...18. + */ + uint32_t smpr1; + /** + * @brief ADC SMPR2 register initialization data. + * @details In this field must be specified the sample times for channels + * 0...9. + */ + uint32_t smpr2; + /** + * @brief ADC SQR1 register initialization data. + * @details Conversion group sequence 13...16 + sequence length. + */ + uint32_t sqr1; + /** + * @brief ADC SQR2 register initialization data. + * @details Conversion group sequence 7...12. + */ + uint32_t sqr2; + /** + * @brief ADC SQR3 register initialization data. + * @details Conversion group sequence 1...6. + */ + uint32_t sqr3; +} ADCConversionGroup; + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + uint32_t dummy; +} ADCConfig; + +/** + * @brief Structure representing an ADC driver. + */ +struct ADCDriver { + /** + * @brief Driver state. + */ + adcstate_t state; + /** + * @brief Current configuration data. + */ + const ADCConfig *config; + /** + * @brief Current samples buffer pointer or @p NULL. + */ + adcsample_t *samples; + /** + * @brief Current samples buffer depth or @p 0. + */ + size_t depth; + /** + * @brief Current conversion group pointer or @p NULL. + */ + const ADCConversionGroup *grpp; +#if ADC_USE_WAIT || defined(__DOXYGEN__) + /** + * @brief Waiting thread. + */ + Thread *thread; +#endif +#if ADC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) +#if CH_USE_MUTEXES || defined(__DOXYGEN__) + /** + * @brief Mutex protecting the peripheral. + */ + Mutex mutex; +#elif CH_USE_SEMAPHORES + Semaphore semaphore; +#endif +#endif /* ADC_USE_MUTUAL_EXCLUSION */ +#if defined(ADC_DRIVER_EXT_FIELDS) + ADC_DRIVER_EXT_FIELDS +#endif + /* End of the mandatory fields.*/ + /** + * @brief Pointer to the ADCx registers block. + */ + ADC_TypeDef *adc; + /** + * @brief Pointer to associated SMA channel. + */ + const stm32_dma_stream_t *dmastp; + /** + * @brief DMA mode bit mask. + */ + uint32_t dmamode; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @name Sequences building helper macros + * @{ + */ +/** + * @brief Number of channels in a conversion sequence. + */ +#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20) + +#define ADC_SQR3_SQ1_N(n) ((n) << 0) /**< @brief 1st channel in seq. */ +#define ADC_SQR3_SQ2_N(n) ((n) << 5) /**< @brief 2nd channel in seq. */ +#define ADC_SQR3_SQ3_N(n) ((n) << 10) /**< @brief 3rd channel in seq. */ +#define ADC_SQR3_SQ4_N(n) ((n) << 15) /**< @brief 4th channel in seq. */ +#define ADC_SQR3_SQ5_N(n) ((n) << 20) /**< @brief 5th channel in seq. */ +#define ADC_SQR3_SQ6_N(n) ((n) << 25) /**< @brief 6th channel in seq. */ + +#define ADC_SQR2_SQ7_N(n) ((n) << 0) /**< @brief 7th channel in seq. */ +#define ADC_SQR2_SQ8_N(n) ((n) << 5) /**< @brief 8th channel in seq. */ +#define ADC_SQR2_SQ9_N(n) ((n) << 10) /**< @brief 9th channel in seq. */ +#define ADC_SQR2_SQ10_N(n) ((n) << 15) /**< @brief 10th channel in seq.*/ +#define ADC_SQR2_SQ11_N(n) ((n) << 20) /**< @brief 11th channel in seq.*/ +#define ADC_SQR2_SQ12_N(n) ((n) << 25) /**< @brief 12th channel in seq.*/ + +#define ADC_SQR1_SQ13_N(n) ((n) << 0) /**< @brief 13th channel in seq.*/ +#define ADC_SQR1_SQ14_N(n) ((n) << 5) /**< @brief 14th channel in seq.*/ +#define ADC_SQR1_SQ15_N(n) ((n) << 10) /**< @brief 15th channel in seq.*/ +#define ADC_SQR1_SQ16_N(n) ((n) << 15) /**< @brief 16th channel in seq.*/ +/** @} */ + +/** + * @name Sampling rate settings helper macros + * @{ + */ +#define ADC_SMPR2_SMP_AN0(n) ((n) << 0) /**< @brief AN0 sampling time. */ +#define ADC_SMPR2_SMP_AN1(n) ((n) << 3) /**< @brief AN1 sampling time. */ +#define ADC_SMPR2_SMP_AN2(n) ((n) << 6) /**< @brief AN2 sampling time. */ +#define ADC_SMPR2_SMP_AN3(n) ((n) << 9) /**< @brief AN3 sampling time. */ +#define ADC_SMPR2_SMP_AN4(n) ((n) << 12) /**< @brief AN4 sampling time. */ +#define ADC_SMPR2_SMP_AN5(n) ((n) << 15) /**< @brief AN5 sampling time. */ +#define ADC_SMPR2_SMP_AN6(n) ((n) << 18) /**< @brief AN6 sampling time. */ +#define ADC_SMPR2_SMP_AN7(n) ((n) << 21) /**< @brief AN7 sampling time. */ +#define ADC_SMPR2_SMP_AN8(n) ((n) << 24) /**< @brief AN8 sampling time. */ +#define ADC_SMPR2_SMP_AN9(n) ((n) << 27) /**< @brief AN9 sampling time. */ + +#define ADC_SMPR1_SMP_AN10(n) ((n) << 0) /**< @brief AN10 sampling time. */ +#define ADC_SMPR1_SMP_AN11(n) ((n) << 3) /**< @brief AN11 sampling time. */ +#define ADC_SMPR1_SMP_AN12(n) ((n) << 6) /**< @brief AN12 sampling time. */ +#define ADC_SMPR1_SMP_AN13(n) ((n) << 9) /**< @brief AN13 sampling time. */ +#define ADC_SMPR1_SMP_AN14(n) ((n) << 12) /**< @brief AN14 sampling time. */ +#define ADC_SMPR1_SMP_AN15(n) ((n) << 15) /**< @brief AN15 sampling time. */ +#define ADC_SMPR1_SMP_SENSOR(n) ((n) << 18) /**< @brief Temperature Sensor + sampling time. */ +#define ADC_SMPR1_SMP_VREF(n) ((n) << 21) /**< @brief Voltage Reference + sampling time. */ +#define ADC_SMPR1_SMP_VBAT(n) ((n) << 24) /**< @brief VBAT sampling time. */ +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__) +extern ADCDriver ADCD1; +#endif + +#if STM32_ADC_USE_ADC2 && !defined(__DOXYGEN__) +extern ADCDriver ADCD2; +#endif + +#if STM32_ADC_USE_ADC3 && !defined(__DOXYGEN__) +extern ADCDriver ADCD3; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void adc_lld_init(void); + void adc_lld_start(ADCDriver *adcp); + void adc_lld_stop(ADCDriver *adcp); + void adc_lld_start_conversion(ADCDriver *adcp); + void adc_lld_stop_conversion(ADCDriver *adcp); + void adcSTM32EnableTSVREFE(void); + void adcSTM32DisableTSVREFE(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_ADC */ + +#endif /* _ADC_LLD_H_ */ + +/** @} */ -- cgit v1.2.3 From 0435bb5b4e1435924490f4a268dba5f75e998951 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 16 Nov 2011 18:03:48 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3499 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32L1xx/adc_lld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32L1xx/adc_lld.c b/os/hal/platforms/STM32L1xx/adc_lld.c index bc04df615..308fd90d0 100644 --- a/os/hal/platforms/STM32L1xx/adc_lld.c +++ b/os/hal/platforms/STM32L1xx/adc_lld.c @@ -219,7 +219,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) { adcp->adc->SQR3 = grpp->sqr3; adcp->adc->SQR4 = grpp->sqr4; adcp->adc->SQR5 = grpp->sqr5; - /* Must wait the ADC to be ready for conversion, see 9.3.6 "Timing diagram" + /* Must wait the ADC to be ready for conversion, see 10.3.6 "Timing diagram" in the Reference Manual.*/ while ((adcp->adc->SR & ADC_SR_ADONS) == 0) ; -- cgit v1.2.3 From cef04f5f4b8ea66ad3ab5a628a4aad8da509039e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 16 Nov 2011 18:55:34 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3500 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/adc_lld.c | 31 +++++++++++++++++++++++++------ os/hal/platforms/STM32F4xx/adc_lld.h | 2 ++ 2 files changed, 27 insertions(+), 6 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/adc_lld.c b/os/hal/platforms/STM32F4xx/adc_lld.c index f78c7ac0f..f34c4fd61 100644 --- a/os/hal/platforms/STM32F4xx/adc_lld.c +++ b/os/hal/platforms/STM32F4xx/adc_lld.c @@ -321,17 +321,16 @@ void adc_lld_start_conversion(ADCDriver *adcp) { /* ADC setup.*/ adcp->adc->SR = 0; adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN; - adcp->adc->SMPR1 = grpp->smpr1; /* Writing SMPRx requires ADON=0. */ - adcp->adc->SMPR2 = grpp->smpr2; adcp->adc->CR2 = grpp->cr2 | ADC_CR2_CONT | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON; + adcp->adc->SMPR1 = grpp->smpr1; + adcp->adc->SMPR2 = grpp->smpr2; adcp->adc->SQR1 = grpp->sqr1; adcp->adc->SQR2 = grpp->sqr2; adcp->adc->SQR3 = grpp->sqr3; - /* Must wait the ADC to be ready for conversion, see 9.3.6 "Timing diagram" - in the Reference Manual.*/ - while ((adcp->adc->SR & ADC_SR_ADONS) == 0) - ; + /* TODO: According to section 10.3.6 of the reference manual there should + be a 2uS delay between the ADC activation and conversion start.*/ + /* ADC start by raising ADC_CR2_SWSTART.*/ adcp->adc->CR2 = grpp->cr2 | ADC_CR2_SWSTART | ADC_CR2_CONT | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON; @@ -373,6 +372,26 @@ void adcSTM32DisableTSVREFE(void) { ADC->CCR &= ~ADC_CCR_TSVREFE; } +/** + * @brief Enables the VBATE bit. + * @details The VBATE bit is required in order to sample the VBAT channel. + * @note This is an STM32-only functionality. + */ +void adcSTM32EnableVBATE(void) { + + ADC->CCR |= ADC_CCR_VBATE; +} + +/** + * @brief Disables the VBATE bit. + * @details The VBATE bit is required in order to sample the VBAT channel. + * @note This is an STM32-only functionality. + */ +void adcSTM32DisableVBATE(void) { + + ADC->CCR &= ~ADC_CCR_VBATE; +} + #endif /* HAL_USE_ADC */ /** @} */ diff --git a/os/hal/platforms/STM32F4xx/adc_lld.h b/os/hal/platforms/STM32F4xx/adc_lld.h index 0e846f50a..6260773a2 100644 --- a/os/hal/platforms/STM32F4xx/adc_lld.h +++ b/os/hal/platforms/STM32F4xx/adc_lld.h @@ -556,6 +556,8 @@ extern "C" { void adc_lld_stop_conversion(ADCDriver *adcp); void adcSTM32EnableTSVREFE(void); void adcSTM32DisableTSVREFE(void); + void adcSTM32EnableVBATE(void); + void adcSTM32DisableVBATE(void); #ifdef __cplusplus } #endif -- cgit v1.2.3 From d70b7e599250fae96dbdc9cbfab11bb9c6d5a649 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 16 Nov 2011 19:52:54 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3503 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/adc_lld.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/adc_lld.c b/os/hal/platforms/STM32F4xx/adc_lld.c index f34c4fd61..97d1623d8 100644 --- a/os/hal/platforms/STM32F4xx/adc_lld.c +++ b/os/hal/platforms/STM32F4xx/adc_lld.c @@ -178,9 +178,9 @@ void adc_lld_init(void) { #if STM32_ADC_USE_ADC2 /* Driver initialization.*/ adcObjectInit(&ADCD2); - ADCD1.adc = ADC2; - ADCD1.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC2_DMA_STREAM); - ADCD1.dmamode = STM32_DMA_CR_CHSEL(ADC2_DMA_CHANNEL) | + ADCD2.adc = ADC2; + ADCD2.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC2_DMA_STREAM); + ADCD2.dmamode = STM32_DMA_CR_CHSEL(ADC2_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_ADC_ADC2_DMA_PRIORITY) | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | @@ -190,9 +190,9 @@ void adc_lld_init(void) { #if STM32_ADC_USE_ADC3 /* Driver initialization.*/ adcObjectInit(&ADCD3); - ADCD1.adc = ADC3; - ADCD1.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC3_DMA_STREAM); - ADCD1.dmamode = STM32_DMA_CR_CHSEL(ADC3_DMA_CHANNEL) | + ADCD3.adc = ADC3; + ADCD3.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC3_DMA_STREAM); + ADCD3.dmamode = STM32_DMA_CR_CHSEL(ADC3_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_ADC_ADC3_DMA_PRIORITY) | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | -- cgit v1.2.3 From 83d562f6b2842c4ec03ff08662ddc629ccc4e424 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 16 Nov 2011 21:21:28 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3504 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/adc.h | 8 ++++---- os/hal/platforms/STM32F4xx/adc_lld.c | 12 +++++++++--- 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/adc.h b/os/hal/include/adc.h index ff9e6b18f..9ebe3754c 100644 --- a/os/hal/include/adc.h +++ b/os/hal/include/adc.h @@ -134,15 +134,15 @@ typedef enum { * @notapi */ #define _adc_wakeup_isr(adcp) { \ + chSysLockFromIsr(); \ if ((adcp)->thread != NULL) { \ Thread *tp; \ - chSysLockFromIsr(); \ tp = (adcp)->thread; \ (adcp)->thread = NULL; \ tp->p_u.rdymsg = RDY_OK; \ chSchReadyI(tp); \ - chSysUnlockFromIsr(); \ } \ + chSysUnlockFromIsr(); \ } /** @@ -153,15 +153,15 @@ typedef enum { * @notapi */ #define _adc_timeout_isr(adcp) { \ + chSysLockFromIsr(); \ if ((adcp)->thread != NULL) { \ Thread *tp; \ - chSysLockFromIsr(); \ tp = (adcp)->thread; \ (adcp)->thread = NULL; \ tp->p_u.rdymsg = RDY_TIMEOUT; \ chSchReadyI(tp); \ - chSysUnlockFromIsr(); \ } \ + chSysUnlockFromIsr(); \ } #else /* !ADC_USE_WAIT */ diff --git a/os/hal/platforms/STM32F4xx/adc_lld.c b/os/hal/platforms/STM32F4xx/adc_lld.c index 97d1623d8..69cef5d57 100644 --- a/os/hal/platforms/STM32F4xx/adc_lld.c +++ b/os/hal/platforms/STM32F4xx/adc_lld.c @@ -170,9 +170,11 @@ void adc_lld_init(void) { ADCD1.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC1_DMA_STREAM); ADCD1.dmamode = STM32_DMA_CR_CHSEL(ADC1_DMA_CHANNEL) | 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_TEIE | STM32_DMA_CR_EN; + STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | + STM32_DMA_CR_EN; #endif #if STM32_ADC_USE_ADC2 @@ -182,9 +184,11 @@ void adc_lld_init(void) { ADCD2.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC2_DMA_STREAM); ADCD2.dmamode = STM32_DMA_CR_CHSEL(ADC2_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_ADC_ADC2_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_TEIE | STM32_DMA_CR_EN; + STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | + STM32_DMA_CR_EN; #endif #if STM32_ADC_USE_ADC3 @@ -194,9 +198,11 @@ void adc_lld_init(void) { ADCD3.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC3_DMA_STREAM); ADCD3.dmamode = STM32_DMA_CR_CHSEL(ADC3_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_ADC_ADC3_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_TEIE | STM32_DMA_CR_EN; + STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | + STM32_DMA_CR_EN; #endif /* The shared vector is initialized on driver initialization and never -- cgit v1.2.3 From f670263432c8d0496d71739dff806ddf70216961 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 18 Nov 2011 20:28:19 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3505 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/platform.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/platform.mk b/os/hal/platforms/STM32F4xx/platform.mk index 1b9ca04dc..7acce0172 100644 --- a/os/hal/platforms/STM32F4xx/platform.mk +++ b/os/hal/platforms/STM32F4xx/platform.mk @@ -1,7 +1,7 @@ -# List of all the STM32L1xx platform files. -PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32L1xx/stm32_dma.c \ +# List of all the STM32F4xx platform files. +PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F4xx/stm32_dma.c \ ${CHIBIOS}/os/hal/platforms/STM32F4xx/hal_lld.c \ - ${CHIBIOS}/os/hal/platforms/STM32/adc_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32F4xx/adc_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/ext_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/gpt_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/icu_lld.c \ -- cgit v1.2.3 From bcdb92f134f82921cbfe12774cc83e83ddee8eef Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 19 Nov 2011 08:48:19 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3508 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/stm32_dma.h | 2 +- os/hal/platforms/STM32F4xx/adc_lld.c | 12 +++++++++--- os/hal/platforms/STM32F4xx/stm32_dma.h | 2 +- os/hal/platforms/STM32L1xx/stm32_dma.h | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/stm32_dma.h b/os/hal/platforms/STM32F1xx/stm32_dma.h index fdfd0bc7b..7e230d851 100644 --- a/os/hal/platforms/STM32F1xx/stm32_dma.h +++ b/os/hal/platforms/STM32F1xx/stm32_dma.h @@ -347,7 +347,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); #define dmaStartMemCopy(dmastp, mode, src, dst, n) { \ dmaStreamSetPeripheral(dmastp, src); \ dmaStreamSetMemory0(dmastp, dst); \ - dmaStreamGetTransactionSize(dmastp, n); \ + dmaStreamSetTransactionSize(dmastp, n); \ dmaStreamSetMode(dmastp, (mode) | \ STM32_DMA_CR_MINC | STM32_DMA_CR_PINC | \ STM32_DMA_CR_DIR_M2M | STM32_DMA_CR_EN); \ diff --git a/os/hal/platforms/STM32F4xx/adc_lld.c b/os/hal/platforms/STM32F4xx/adc_lld.c index 69cef5d57..603b32135 100644 --- a/os/hal/platforms/STM32F4xx/adc_lld.c +++ b/os/hal/platforms/STM32F4xx/adc_lld.c @@ -116,7 +116,9 @@ CH_IRQ_HANDLER(ADC1_2_3_IRQHandler) { #if STM32_ADC_USE_ADC1 sr = ADC1->SR; ADC1->SR = 0; - if (sr & ADC_SR_OVR) { + /* 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.*/ _adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW); @@ -127,7 +129,9 @@ CH_IRQ_HANDLER(ADC1_2_3_IRQHandler) { #if STM32_ADC_USE_ADC2 sr = ADC2->SR; ADC2->SR = 0; - if (sr & ADC_SR_OVR) { + /* 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(ADCD2.dmastp) > 0)) { /* ADC overflow condition, this could happen only if the DMA is unable to read data fast enough.*/ _adc_isr_error_code(&ADCD2, ADC_ERR_OVERFLOW); @@ -138,7 +142,9 @@ CH_IRQ_HANDLER(ADC1_2_3_IRQHandler) { #if STM32_ADC_USE_ADC3 sr = ADC3->SR; ADC3->SR = 0; - if (sr & ADC_SR_OVR) { + /* 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(ADCD3.dmastp) > 0)) { /* ADC overflow condition, this could happen only if the DMA is unable to read data fast enough.*/ _adc_isr_error_code(&ADCD3, ADC_ERR_OVERFLOW); diff --git a/os/hal/platforms/STM32F4xx/stm32_dma.h b/os/hal/platforms/STM32F4xx/stm32_dma.h index 4b3302f39..fe15dbd22 100644 --- a/os/hal/platforms/STM32F4xx/stm32_dma.h +++ b/os/hal/platforms/STM32F4xx/stm32_dma.h @@ -400,7 +400,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); #define dmaStartMemCopy(dmastp, mode, src, dst, n) { \ dmaStreamSetPeripheral(dmastp, src); \ dmaStreamSetMemory0(dmastp, dst); \ - dmaStreamGetTransactionSize(dmastp, n); \ + dmaStreamSetTransactionSize(dmastp, n); \ dmaStreamSetMode(dmastp, (mode) | \ STM32_DMA_CR_MINC | STM32_DMA_CR_PINC | \ STM32_DMA_CR_DIR_M2M | STM32_DMA_CR_EN); \ diff --git a/os/hal/platforms/STM32L1xx/stm32_dma.h b/os/hal/platforms/STM32L1xx/stm32_dma.h index 0d80a39e7..6afadfcc1 100644 --- a/os/hal/platforms/STM32L1xx/stm32_dma.h +++ b/os/hal/platforms/STM32L1xx/stm32_dma.h @@ -338,7 +338,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); #define dmaStartMemCopy(dmastp, mode, src, dst, n) { \ dmaStreamSetPeripheral(dmastp, src); \ dmaStreamSetMemory0(dmastp, dst); \ - dmaStreamGetTransactionSize(dmastp, n); \ + dmaStreamSetTransactionSize(dmastp, n); \ dmaStreamSetMode(dmastp, (mode) | \ STM32_DMA_CR_MINC | STM32_DMA_CR_PINC | \ STM32_DMA_CR_DIR_M2M | STM32_DMA_CR_EN); \ -- cgit v1.2.3 From b1762e9295dfe92f8d682aba3954adde498ff129 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 19 Nov 2011 09:32:59 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3509 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/adc_lld.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/adc_lld.c b/os/hal/platforms/STM32F4xx/adc_lld.c index 603b32135..b31ca178c 100644 --- a/os/hal/platforms/STM32F4xx/adc_lld.c +++ b/os/hal/platforms/STM32F4xx/adc_lld.c @@ -266,9 +266,9 @@ void adc_lld_start(ADCDriver *adcp) { } #endif /* STM32_ADC_USE_ADC3 */ - /* ADC initial setup, just resetting control registers in this case.*/ + /* ADC initial setup, starting the analog part.*/ adcp->adc->CR1 = 0; - adcp->adc->CR2 = 0; + adcp->adc->CR2 = ADC_CR2_ADON; } } @@ -332,19 +332,16 @@ void adc_lld_start_conversion(ADCDriver *adcp) { /* ADC setup.*/ adcp->adc->SR = 0; - adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN; - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_CONT | ADC_CR2_DMA | ADC_CR2_DDS | - ADC_CR2_ADON; adcp->adc->SMPR1 = grpp->smpr1; adcp->adc->SMPR2 = grpp->smpr2; adcp->adc->SQR1 = grpp->sqr1; adcp->adc->SQR2 = grpp->sqr2; adcp->adc->SQR3 = grpp->sqr3; - /* TODO: According to section 10.3.6 of the reference manual there should - be a 2uS delay between the ADC activation and conversion start.*/ - /* ADC start by raising ADC_CR2_SWSTART.*/ - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_SWSTART | ADC_CR2_CONT | ADC_CR2_DMA | + /* ADC configuration and start, the start is performed using the method + specified in the CR2 configuration, usually ADC_CR2_SWSTART.*/ + adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN; + adcp->adc->CR2 = grpp->cr2 | ADC_CR2_CONT | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON; } @@ -360,6 +357,7 @@ void adc_lld_stop_conversion(ADCDriver *adcp) { dmaStreamDisable(adcp->dmastp); adcp->adc->CR1 = 0; adcp->adc->CR2 = 0; + adcp->adc->CR2 = ADC_CR2_ADON; } /** -- cgit v1.2.3 From ba01ba301e003f5022c5d406e785de4bc65d70fc Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 19 Nov 2011 09:37:41 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3510 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/adc_lld.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/adc_lld.c b/os/hal/platforms/STM32F4xx/adc_lld.c index b31ca178c..29ed6fcc2 100644 --- a/os/hal/platforms/STM32F4xx/adc_lld.c +++ b/os/hal/platforms/STM32F4xx/adc_lld.c @@ -266,7 +266,8 @@ void adc_lld_start(ADCDriver *adcp) { } #endif /* STM32_ADC_USE_ADC3 */ - /* ADC initial setup, starting the analog part.*/ + /* 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 = ADC_CR2_ADON; } -- cgit v1.2.3 From fd9b356d6c3e0c691f51cae7834d72c1c67da100 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 19 Nov 2011 09:53:22 +0000 Subject: STM32F4 ADC driver tested. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3511 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/adc_lld.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/adc_lld.c b/os/hal/platforms/STM32F4xx/adc_lld.c index 29ed6fcc2..5edac0163 100644 --- a/os/hal/platforms/STM32F4xx/adc_lld.c +++ b/os/hal/platforms/STM32F4xx/adc_lld.c @@ -86,13 +86,17 @@ static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE); } else { - if ((flags & STM32_DMA_ISR_HTIF) != 0) { - /* Half transfer processing.*/ - _adc_isr_half_code(adcp); - } - if ((flags & STM32_DMA_ISR_TCIF) != 0) { - /* Transfer complete processing.*/ - _adc_isr_full_code(adcp); + /* 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_HTIF) != 0) { + /* Half transfer processing.*/ + _adc_isr_half_code(adcp); + } + if ((flags & STM32_DMA_ISR_TCIF) != 0) { + /* Transfer complete processing.*/ + _adc_isr_full_code(adcp); + } } } } @@ -121,7 +125,8 @@ CH_IRQ_HANDLER(ADC1_2_3_IRQHandler) { 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.*/ - _adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW); + if (ADCD1.grpp != NULL) + _adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW); } /* TODO: Add here analog watchdog handling.*/ #endif /* STM32_ADC_USE_ADC1 */ @@ -134,7 +139,8 @@ CH_IRQ_HANDLER(ADC1_2_3_IRQHandler) { if ((sr & ADC_SR_OVR) && (dmaStreamGetTransactionSize(ADCD2.dmastp) > 0)) { /* ADC overflow condition, this could happen only if the DMA is unable to read data fast enough.*/ - _adc_isr_error_code(&ADCD2, ADC_ERR_OVERFLOW); + if (ADCD2.grpp != NULL) + _adc_isr_error_code(&ADCD2, ADC_ERR_OVERFLOW); } /* TODO: Add here analog watchdog handling.*/ #endif /* STM32_ADC_USE_ADC2 */ @@ -147,7 +153,8 @@ CH_IRQ_HANDLER(ADC1_2_3_IRQHandler) { if ((sr & ADC_SR_OVR) && (dmaStreamGetTransactionSize(ADCD3.dmastp) > 0)) { /* ADC overflow condition, this could happen only if the DMA is unable to read data fast enough.*/ - _adc_isr_error_code(&ADCD3, ADC_ERR_OVERFLOW); + if (ADCD3.grpp != NULL) + _adc_isr_error_code(&ADCD3, ADC_ERR_OVERFLOW); } /* TODO: Add here analog watchdog handling.*/ #endif /* STM32_ADC_USE_ADC3 */ @@ -342,8 +349,8 @@ void adc_lld_start_conversion(ADCDriver *adcp) { /* ADC configuration and start, the start is performed using the method specified in the CR2 configuration, usually ADC_CR2_SWSTART.*/ adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN; - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_CONT | ADC_CR2_DMA | - ADC_CR2_DDS | ADC_CR2_ADON; + adcp->adc->CR2 = grpp->cr2 | ADC_CR2_CONT | ADC_CR2_DMA | + ADC_CR2_DDS | ADC_CR2_ADON; } /** -- cgit v1.2.3 From 9369d75516d5edb0e892f5ce1a5d7781917a64a5 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 20 Nov 2011 18:04:07 +0000 Subject: STM32F4-Discovery demo working. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3516 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/icu_lld.c | 12 +++---- os/hal/platforms/STM32/icu_lld.h | 4 +-- os/hal/platforms/STM32/pwm_lld.c | 18 +++++------ os/hal/platforms/STM32F1xx/hal_lld.h | 59 +++++++++++++++++++++++++++------- os/hal/platforms/STM32F1xx/stm32f10x.h | 3 ++ os/hal/platforms/STM32F4xx/hal_lld.h | 41 +++++++++++++++++++++++ os/hal/platforms/STM32F4xx/stm32f4xx.h | 3 ++ os/hal/platforms/STM32L1xx/hal_lld.h | 55 +++++++++++++++++++++++++------ os/hal/platforms/STM32L1xx/stm32l1xx.h | 3 ++ 9 files changed, 159 insertions(+), 39 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/icu_lld.c b/os/hal/platforms/STM32/icu_lld.c index 33eff67d5..ab3e12f26 100644 --- a/os/hal/platforms/STM32/icu_lld.c +++ b/os/hal/platforms/STM32/icu_lld.c @@ -343,12 +343,12 @@ void icu_lld_start(ICUDriver *icup) { } else { /* Driver re-configuration scenario, it must be stopped first.*/ - icup->tim->CR1 = 0; /* Timer disabled. */ - icup->tim->DIER = 0; /* All IRQs disabled. */ - icup->tim->SR = 0; /* Clear eventual pending IRQs. */ - icup->tim->CCR1 = 0; /* Comparator 1 disabled. */ - icup->tim->CCR2 = 0; /* Comparator 2 disabled. */ - icup->tim->CNT = 0; /* Counter reset to zero. */ + icup->tim->CR1 = 0; /* Timer disabled. */ + icup->tim->DIER = 0; /* All IRQs disabled. */ + icup->tim->SR = 0; /* Clear eventual pending IRQs. */ + icup->tim->CCR[0] = 0; /* Comparator 1 disabled. */ + icup->tim->CCR[1] = 0; /* Comparator 2 disabled. */ + icup->tim->CNT = 0; /* Counter reset to zero. */ } /* Timer configuration.*/ diff --git a/os/hal/platforms/STM32/icu_lld.h b/os/hal/platforms/STM32/icu_lld.h index 3156023eb..b97930609 100644 --- a/os/hal/platforms/STM32/icu_lld.h +++ b/os/hal/platforms/STM32/icu_lld.h @@ -262,7 +262,7 @@ struct ICUDriver { * * @notapi */ -#define icu_lld_get_width(icup) ((icup)->tim->CCR2 + 1) +#define icu_lld_get_width(icup) ((icup)->tim->CCR[1] + 1) /** * @brief Returns the width of the latest cycle. @@ -274,7 +274,7 @@ struct ICUDriver { * * @notapi */ -#define icu_lld_get_period(icup) ((icup)->tim->CCR1 + 1) +#define icu_lld_get_period(icup) ((icup)->tim->CCR[0] + 1) /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/platforms/STM32/pwm_lld.c b/os/hal/platforms/STM32/pwm_lld.c index ab3c1c2bb..fb5d12adf 100644 --- a/os/hal/platforms/STM32/pwm_lld.c +++ b/os/hal/platforms/STM32/pwm_lld.c @@ -419,13 +419,13 @@ void pwm_lld_start(PWMDriver *pwmp) { } else { /* Driver re-configuration scenario, it must be stopped first.*/ - pwmp->tim->CR1 = 0; /* Timer disabled. */ - pwmp->tim->DIER = 0; /* All IRQs disabled. */ - pwmp->tim->SR = 0; /* Clear eventual pending IRQs. */ - pwmp->tim->CCR1 = 0; /* Comparator 1 disabled. */ - pwmp->tim->CCR2 = 0; /* Comparator 2 disabled. */ - pwmp->tim->CCR3 = 0; /* Comparator 3 disabled. */ - pwmp->tim->CCR4 = 0; /* Comparator 4 disabled. */ + pwmp->tim->CR1 = 0; /* Timer disabled. */ + pwmp->tim->DIER = 0; /* All IRQs disabled. */ + pwmp->tim->SR = 0; /* Clear eventual pending IRQs. */ + pwmp->tim->CCR[0] = 0; /* Comparator 1 disabled. */ + pwmp->tim->CCR[1] = 0; /* Comparator 2 disabled. */ + pwmp->tim->CCR[2] = 0; /* Comparator 3 disabled. */ + pwmp->tim->CCR[3] = 0; /* Comparator 4 disabled. */ pwmp->tim->CNT = 0; /* Counter reset to zero. */ } @@ -599,7 +599,7 @@ void pwm_lld_enable_channel(PWMDriver *pwmp, pwmchannel_t channel, pwmcnt_t width) { - *(&pwmp->tim->CCR1 + (channel * 2)) = width; /* New duty cycle. */ + pwmp->tim->CCR[channel] = width; /* New duty cycle. */ /* If there is a callback defined for the channel then the associated interrupt must be enabled.*/ if (pwmp->config->channels[channel].callback != NULL) { @@ -627,7 +627,7 @@ void pwm_lld_enable_channel(PWMDriver *pwmp, */ void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) { - *(&pwmp->tim->CCR1 + (channel * 2)) = 0; + pwmp->tim->CCR[channel] = 0; pwmp->tim->DIER &= ~(2 << channel); } diff --git a/os/hal/platforms/STM32F1xx/hal_lld.h b/os/hal/platforms/STM32F1xx/hal_lld.h index 9b87b0a85..a4ccd3118 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld.h +++ b/os/hal/platforms/STM32F1xx/hal_lld.h @@ -43,6 +43,12 @@ #ifndef _HAL_LLD_H_ #define _HAL_LLD_H_ +#include "stm32f10x.h" + +/* STM32 DMA and RCC helpers.*/ +#include "stm32_dma.h" +#include "stm32_rcc.h" + /*===========================================================================*/ /* Driver constants. */ /*===========================================================================*/ @@ -100,6 +106,47 @@ /* Driver data structures and types. */ /*===========================================================================*/ +/** + * @brief STM32 TIM registers block. + * @note Removed from the ST headers and redefined because the non uniform + * declaration of the CCR registers among the various sub-families. + */ +typedef struct { + volatile uint16_t CR1; + uint16_t _resvd0; + volatile uint16_t CR2; + uint16_t _resvd1; + volatile uint16_t SMCR; + uint16_t _resvd2; + volatile uint16_t DIER; + uint16_t _resvd3; + volatile uint16_t SR; + uint16_t _resvd4; + volatile uint16_t EGR; + uint16_t _resvd5; + volatile uint16_t CCMR1; + uint16_t _resvd6; + volatile uint16_t CCMR2; + uint16_t _resvd7; + volatile uint16_t CCER; + uint16_t _resvd8; + volatile uint32_t CNT; + volatile uint16_t PSC; + uint16_t _resvd9; + volatile uint32_t ARR; + volatile uint16_t RCR; + uint16_t _resvd10; + volatile uint32_t CCR[4]; + volatile uint16_t BDTR; + uint16_t _resvd11; + volatile uint16_t DCR; + uint16_t _resvd12; + volatile uint16_t DMAR; + uint16_t _resvd13; + volatile uint16_t OR; + uint16_t _resvd14; +} TIM_TypeDef; + /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ @@ -108,18 +155,6 @@ /* External declarations. */ /*===========================================================================*/ -/* Tricks required to make the TRUE/FALSE declaration inside the library - compatible.*/ -#undef FALSE -#undef TRUE -#include "stm32f10x.h" -#define FALSE 0 -#define TRUE (!FALSE) - -/* STM32 DMA and RCC helpers.*/ -#include "stm32_dma.h" -#include "stm32_rcc.h" - #ifdef __cplusplus extern "C" { #endif diff --git a/os/hal/platforms/STM32F1xx/stm32f10x.h b/os/hal/platforms/STM32F1xx/stm32f10x.h index 6697b9648..e8f413763 100644 --- a/os/hal/platforms/STM32F1xx/stm32f10x.h +++ b/os/hal/platforms/STM32F1xx/stm32f10x.h @@ -1198,6 +1198,8 @@ typedef struct * @brief TIM */ +/* CHIBIOS FIX */ +#if 0 typedef struct { __IO uint16_t CR1; @@ -1241,6 +1243,7 @@ typedef struct __IO uint16_t DMAR; uint16_t RESERVED19; } TIM_TypeDef; +#endif /** * @brief Universal Synchronous Asynchronous Receiver Transmitter diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index 11bdfedd6..71207efd5 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -1262,6 +1262,47 @@ /* Driver data structures and types. */ /*===========================================================================*/ +/** + * @brief STM32 TIM registers block. + * @note Removed from the ST headers and redefined because the non uniform + * declaration of the CCR registers among the various sub-families. + */ +typedef struct { + volatile uint16_t CR1; + uint16_t _resvd0; + volatile uint16_t CR2; + uint16_t _resvd1; + volatile uint16_t SMCR; + uint16_t _resvd2; + volatile uint16_t DIER; + uint16_t _resvd3; + volatile uint16_t SR; + uint16_t _resvd4; + volatile uint16_t EGR; + uint16_t _resvd5; + volatile uint16_t CCMR1; + uint16_t _resvd6; + volatile uint16_t CCMR2; + uint16_t _resvd7; + volatile uint16_t CCER; + uint16_t _resvd8; + volatile uint32_t CNT; + volatile uint16_t PSC; + uint16_t _resvd9; + volatile uint32_t ARR; + volatile uint16_t RCR; + uint16_t _resvd10; + volatile uint32_t CCR[4]; + volatile uint16_t BDTR; + uint16_t _resvd11; + volatile uint16_t DCR; + uint16_t _resvd12; + volatile uint16_t DMAR; + uint16_t _resvd13; + volatile uint16_t OR; + uint16_t _resvd14; +} TIM_TypeDef; + /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F4xx/stm32f4xx.h b/os/hal/platforms/STM32F4xx/stm32f4xx.h index ccc1a3565..cd8ed7887 100644 --- a/os/hal/platforms/STM32F4xx/stm32f4xx.h +++ b/os/hal/platforms/STM32F4xx/stm32f4xx.h @@ -868,6 +868,8 @@ typedef struct * @brief TIM */ +/* CHIBIOS FIX */ +#if 0 typedef struct { __IO uint16_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ @@ -907,6 +909,7 @@ typedef struct __IO uint16_t OR; /*!< TIM option register, Address offset: 0x50 */ uint16_t RESERVED14; /*!< Reserved, 0x52 */ } TIM_TypeDef; +#endif /** * @brief Universal Synchronous Asynchronous Receiver Transmitter diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index 8d8f1b23b..d62176a16 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -37,13 +37,11 @@ #ifndef _HAL_LLD_H_ #define _HAL_LLD_H_ -/* Tricks required to make the TRUE/FALSE declaration inside the library - compatible.*/ -#undef FALSE -#undef TRUE #include "stm32l1xx.h" -#define FALSE 0 -#define TRUE (!FALSE) + +/* STM32 DMA and RCC helpers.*/ +#include "stm32_dma.h" +#include "stm32_rcc.h" /*===========================================================================*/ /* Driver constants. */ @@ -933,6 +931,47 @@ /* Driver data structures and types. */ /*===========================================================================*/ +/** + * @brief STM32 TIM registers block. + * @note Removed from the ST headers and redefined because the non uniform + * declaration of the CCR registers among the various sub-families. + */ +typedef struct { + volatile uint16_t CR1; + uint16_t _resvd0; + volatile uint16_t CR2; + uint16_t _resvd1; + volatile uint16_t SMCR; + uint16_t _resvd2; + volatile uint16_t DIER; + uint16_t _resvd3; + volatile uint16_t SR; + uint16_t _resvd4; + volatile uint16_t EGR; + uint16_t _resvd5; + volatile uint16_t CCMR1; + uint16_t _resvd6; + volatile uint16_t CCMR2; + uint16_t _resvd7; + volatile uint16_t CCER; + uint16_t _resvd8; + volatile uint32_t CNT; + volatile uint16_t PSC; + uint16_t _resvd9; + volatile uint32_t ARR; + volatile uint16_t RCR; + uint16_t _resvd10; + volatile uint32_t CCR[4]; + volatile uint16_t BDTR; + uint16_t _resvd11; + volatile uint16_t DCR; + uint16_t _resvd12; + volatile uint16_t DMAR; + uint16_t _resvd13; + volatile uint16_t OR; + uint16_t _resvd14; +} TIM_TypeDef; + /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ @@ -941,10 +980,6 @@ /* External declarations. */ /*===========================================================================*/ -/* STM32 DMA and RCC helpers.*/ -#include "stm32_dma.h" -#include "stm32_rcc.h" - #ifdef __cplusplus extern "C" { #endif diff --git a/os/hal/platforms/STM32L1xx/stm32l1xx.h b/os/hal/platforms/STM32L1xx/stm32l1xx.h index 32ddcb79d..5fadee5db 100644 --- a/os/hal/platforms/STM32L1xx/stm32l1xx.h +++ b/os/hal/platforms/STM32L1xx/stm32l1xx.h @@ -615,6 +615,8 @@ typedef struct * @brief TIM */ +/* CHIBIOS FIX */ +#if 0 typedef struct { __IO uint16_t CR1; @@ -658,6 +660,7 @@ typedef struct __IO uint16_t OR; uint16_t RESERVED20; } TIM_TypeDef; +#endif /** * @brief Universal Synchronous Asynchronous Receiver Transmitter -- cgit v1.2.3 From c399cbbddf5e5f0ed2209aadc8eec0f188d11340 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 22 Nov 2011 08:00:12 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3518 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/GPIOv2/pal_lld.c | 2 +- os/hal/platforms/STM32/GPIOv2/pal_lld.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/GPIOv2/pal_lld.c b/os/hal/platforms/STM32/GPIOv2/pal_lld.c index 728523719..cb9c102df 100644 --- a/os/hal/platforms/STM32/GPIOv2/pal_lld.c +++ b/os/hal/platforms/STM32/GPIOv2/pal_lld.c @@ -20,7 +20,7 @@ /** * @file STM32/GPIOv2/pal_lld.c - * @brief STM32L1xx/STM32F2xx GPIO low level driver code. + * @brief STM32L1xx/STM32F2xx/STM32F4xx GPIO low level driver code. * * @addtogroup PAL * @{ diff --git a/os/hal/platforms/STM32/GPIOv2/pal_lld.h b/os/hal/platforms/STM32/GPIOv2/pal_lld.h index 7f8c2e17a..60dd84307 100644 --- a/os/hal/platforms/STM32/GPIOv2/pal_lld.h +++ b/os/hal/platforms/STM32/GPIOv2/pal_lld.h @@ -20,7 +20,7 @@ /** * @file STM32/GPIOv2/pal_lld.h - * @brief STM32L1xx/STM32F2xx GPIO low level driver header. + * @brief STM32L1xx/STM32F2xx/STM32F4xx GPIO low level driver header. * * @addtogroup PAL * @{ -- cgit v1.2.3 From e241378765ef67e3c804753a54a30e1e6b4431e3 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 23 Nov 2011 19:25:55 +0000 Subject: Fixed DMA assignment for SPI3 on STM32F1xx devices. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3519 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/spi_lld.h | 4 ++-- os/hal/platforms/STM32F1xx/hal_lld_f103.h | 8 ++++---- os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/spi_lld.h b/os/hal/platforms/STM32/spi_lld.h index ccffe5f8b..e10a5edce 100644 --- a/os/hal/platforms/STM32/spi_lld.h +++ b/os/hal/platforms/STM32/spi_lld.h @@ -186,8 +186,8 @@ #define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) #define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) #define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) -#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) -#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 6) +#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) #endif /* !STM32_ADVANCED_DMA*/ /** @} */ diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f103.h b/os/hal/platforms/STM32F1xx/hal_lld_f103.h index 1375bf7cf..4090502a1 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f103.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f103.h @@ -403,9 +403,9 @@ #define STM32_SPI2_TX_DMA_CHN 0x00000000 #define STM32_HAS_SPI3 TRUE -#define STM32_SPI3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 5) +#define STM32_SPI3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 1) #define STM32_SPI3_RX_DMA_CHN 0x00000000 -#define STM32_SPI3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 6) +#define STM32_SPI3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 2) #define STM32_SPI3_TX_DMA_CHN 0x00000000 /* TIM attributes.*/ @@ -506,9 +506,9 @@ #define STM32_SPI2_TX_DMA_CHN 0x00000000 #define STM32_HAS_SPI3 TRUE -#define STM32_SPI3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 5) +#define STM32_SPI3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 1) #define STM32_SPI3_RX_DMA_CHN 0x00000000 -#define STM32_SPI3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 6) +#define STM32_SPI3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 2) #define STM32_SPI3_TX_DMA_CHN 0x00000000 /* TIM attributes.*/ diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h index b8eb11c3b..dff2f7b2e 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h @@ -189,9 +189,9 @@ #define STM32_SPI2_TX_DMA_CHN 0x00000000 #define STM32_HAS_SPI3 TRUE -#define STM32_SPI3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 5) +#define STM32_SPI3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 1) #define STM32_SPI3_RX_DMA_CHN 0x00000000 -#define STM32_SPI3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 6) +#define STM32_SPI3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 2) #define STM32_SPI3_TX_DMA_CHN 0x00000000 /* TIM attributes.*/ -- cgit v1.2.3 From 4286b14a9e6d82823c8e5c759495575b1b7fa5ef Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 23 Nov 2011 19:58:04 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3520 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/spi_lld.c | 2 +- os/hal/platforms/STM32/spi_lld.h | 44 +++++----- os/hal/platforms/STM32/uart_lld.c | 96 +++++++++++++------- os/hal/platforms/STM32/uart_lld.h | 100 +++++++++++++++++++++ os/hal/platforms/STM32F1xx/hal_lld_f100.h | 29 +++++++ os/hal/platforms/STM32F1xx/hal_lld_f103.h | 116 +++++++++++++++++++++++++ os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h | 29 +++++++ os/hal/platforms/STM32F4xx/adc_lld.c | 2 +- os/hal/platforms/STM32F4xx/hal_lld.h | 33 +++++++ os/hal/platforms/STM32L1xx/hal_lld.h | 29 +++++++ 10 files changed, 424 insertions(+), 56 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/spi_lld.c b/os/hal/platforms/STM32/spi_lld.c index 2610031b6..34a892d48 100644 --- a/os/hal/platforms/STM32/spi_lld.c +++ b/os/hal/platforms/STM32/spi_lld.c @@ -99,7 +99,7 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_SPI_DMA_ERROR_HOOK) - if ((flags & STM32_DMA_ISR_TEIF) != 0) { + if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { STM32_SPI_DMA_ERROR_HOOK(spip); } #else diff --git a/os/hal/platforms/STM32/spi_lld.h b/os/hal/platforms/STM32/spi_lld.h index e10a5edce..ee2586ea1 100644 --- a/os/hal/platforms/STM32/spi_lld.h +++ b/os/hal/platforms/STM32/spi_lld.h @@ -70,6 +70,27 @@ #define STM32_SPI_USE_SPI3 FALSE #endif +/** + * @brief SPI1 interrupt priority level setting. + */ +#if !defined(STM32_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SPI_SPI1_IRQ_PRIORITY 10 +#endif + +/** + * @brief SPI2 interrupt priority level setting. + */ +#if !defined(STM32_SPI_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SPI_SPI2_IRQ_PRIORITY 10 +#endif + +/** + * @brief SPI3 interrupt priority level setting. + */ +#if !defined(STM32_SPI_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SPI_SPI3_IRQ_PRIORITY 10 +#endif + /** * @brief SPI1 DMA priority (0..3|lowest..highest). * @note The priority level is used for both the TX and RX DMA streams but @@ -100,27 +121,6 @@ #define STM32_SPI_SPI3_DMA_PRIORITY 1 #endif -/** - * @brief SPI1 interrupt priority level setting. - */ -#if !defined(STM32_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_SPI_SPI1_IRQ_PRIORITY 10 -#endif - -/** - * @brief SPI2 interrupt priority level setting. - */ -#if !defined(STM32_SPI_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_SPI_SPI2_IRQ_PRIORITY 10 -#endif - -/** - * @brief SPI3 interrupt priority level setting. - */ -#if !defined(STM32_SPI_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_SPI_SPI3_IRQ_PRIORITY 10 -#endif - /** * @brief SPI DMA error hook. */ @@ -175,7 +175,7 @@ * @note This option is only available on platforms with enhanced DMA. */ #if !defined(STM32_SPI_SPI3_TX_DMA_STREAM) || defined(__DOXYGEN__) -#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) #endif #else /* !STM32_ADVANCED_DMA */ diff --git a/os/hal/platforms/STM32/uart_lld.c b/os/hal/platforms/STM32/uart_lld.c index 3841be8fa..be63fc695 100644 --- a/os/hal/platforms/STM32/uart_lld.c +++ b/os/hal/platforms/STM32/uart_lld.c @@ -31,6 +31,34 @@ #if HAL_USE_UART || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define USART1_RX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_UART_USART1_RX_DMA_STREAM, \ + STM32_USART1_RX_DMA_CHN) + +#define USART1_TX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_UART_USART1_TX_DMA_STREAM, \ + STM32_USART1_TX_DMA_CHN) + +#define USART2_RX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_UART_USART2_RX_DMA_STREAM, \ + STM32_USART2_RX_DMA_CHN) + +#define USART2_TX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_UART_USART2_TX_DMA_STREAM, \ + STM32_USART2_TX_DMA_CHN) + +#define USART3_RX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_UART_USART3_RX_DMA_STREAM, \ + STM32_USART3_RX_DMA_CHN) + +#define USART3_TX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_UART_USART3_TX_DMA_STREAM, \ + STM32_USART3_TX_DMA_CHN) + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -92,10 +120,9 @@ static void set_rx_idle_loop(UARTDriver *uartp) { /* RX DMA channel preparation, if the char callback is defined then the TCIE interrupt is enabled too.*/ if (uartp->config->rxchar_cb == NULL) - mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TEIE; + mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC; else - mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TEIE | - STM32_DMA_CR_TCIE; + mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TCIE; dmaStreamSetMemory0(uartp->dmarx, &uartp->rxbuf); dmaStreamSetTransactionSize(uartp->dmarx, 1); dmaStreamSetMode(uartp->dmarx, uartp->dmamode | mode); @@ -172,7 +199,7 @@ static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_UART_DMA_ERROR_HOOK) - if ((flags & STM32_DMA_ISR_TEIF) != 0) { + if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { STM32_UART_DMA_ERROR_HOOK(uartp); } #else @@ -192,6 +219,7 @@ static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) { uartp->rxstate = UART_RX_COMPLETE; if (uartp->config->rxend_cb != NULL) uartp->config->rxend_cb(uartp); + /* If the callback didn't explicitly change state then the receiver automatically returns to the idle state.*/ if (uartp->rxstate == UART_RX_COMPLETE) { @@ -211,7 +239,7 @@ static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_UART_DMA_ERROR_HOOK) - if ((flags & STM32_DMA_ISR_TEIF) != 0) { + if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { STM32_UART_DMA_ERROR_HOOK(uartp); } #else @@ -219,10 +247,12 @@ static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) { #endif dmaStreamDisable(uartp->dmatx); + /* A callback is generated, if enabled, after a completed transfer.*/ uartp->txstate = UART_TX_COMPLETE; if (uartp->config->txend1_cb != NULL) uartp->config->txend1_cb(uartp); + /* If the callback didn't explicitly change state then the transmitter automatically returns to the idle state.*/ if (uartp->txstate == UART_TX_COMPLETE) @@ -248,6 +278,7 @@ static void serve_usart_irq(UARTDriver *uartp) { } if (sr & USART_SR_TC) { u->SR = ~USART_SR_TC; + /* End of transmission, a callback is generated.*/ if (uartp->config->txend2_cb != NULL) uartp->config->txend2_cb(uartp); @@ -320,22 +351,22 @@ void uart_lld_init(void) { #if STM32_UART_USE_USART1 uartObjectInit(&UARTD1); UARTD1.usart = USART1; - UARTD1.dmarx = STM32_DMA1_STREAM5; - UARTD1.dmatx = STM32_DMA1_STREAM4; + UARTD1.dmarx = STM32_DMA_STREAM(STM32_UART_USART1_RX_DMA_STREAM); + UARTD1.dmatx = STM32_DMA_STREAM(STM32_UART_USART1_TX_DMA_STREAM); #endif #if STM32_UART_USE_USART2 uartObjectInit(&UARTD2); UARTD2.usart = USART2; - UARTD2.dmarx = STM32_DMA1_STREAM6; - UARTD2.dmatx = STM32_DMA1_STREAM7; + UARTD2.dmarx = STM32_DMA_STREAM(STM32_UART_USART2_RX_DMA_STREAM); + UARTD2.dmatx = STM32_DMA_STREAM(STM32_UART_USART2_TX_DMA_STREAM); #endif #if STM32_UART_USE_USART3 uartObjectInit(&UARTD3); UARTD3.usart = USART3; - UARTD3.dmarx = STM32_DMA1_STREAM3; - UARTD3.dmatx = STM32_DMA1_STREAM2; + UARTD3.dmarx = STM32_DMA_STREAM(STM32_UART_USART3_RX_DMA_STREAM); + UARTD3.dmatx = STM32_DMA_STREAM(STM32_UART_USART3_TX_DMA_STREAM); #endif } @@ -348,35 +379,39 @@ void uart_lld_init(void) { */ void uart_lld_start(UARTDriver *uartp) { + uartp->dmamode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; + if (uartp->state == UART_STOP) { #if STM32_UART_USE_USART1 if (&UARTD1 == uartp) { bool_t b; - b = dmaStreamAllocate(STM32_DMA1_STREAM4, + b = dmaStreamAllocate(uartp->dmarx, STM32_UART_USART1_IRQ_PRIORITY, - (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); chDbgAssert(!b, "uart_lld_start(), #1", "stream already allocated"); - b = dmaStreamAllocate(STM32_DMA1_STREAM5, + b = dmaStreamAllocate(uartp->dmatx, STM32_UART_USART1_IRQ_PRIORITY, - (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); chDbgAssert(!b, "uart_lld_start(), #2", "stream already allocated"); rccEnableUSART1(FALSE); NVICEnableVector(USART1_IRQn, CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY)); + uartp->dmamode |= STM32_DMA_CR_CHSEL(USART1_RX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY); } #endif #if STM32_UART_USE_USART2 if (&UARTD2 == uartp) { bool_t b; - b = dmaStreamAllocate(STM32_DMA1_STREAM6, + b = dmaStreamAllocate(uartp->dmarx, STM32_UART_USART2_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); chDbgAssert(!b, "uart_lld_start(), #3", "stream already allocated"); - b = dmaStreamAllocate(STM32_DMA1_STREAM7, + b = dmaStreamAllocate(uartp->dmatx, STM32_UART_USART2_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); @@ -384,31 +419,34 @@ void uart_lld_start(UARTDriver *uartp) { rccEnableUSART2(FALSE); NVICEnableVector(USART2_IRQn, CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); + uartp->dmamode |= STM32_DMA_CR_CHSEL(USART2_RX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_UART_USART2_DMA_PRIORITY); } #endif #if STM32_UART_USE_USART3 if (&UARTD3 == uartp) { bool_t b; - b = dmaStreamAllocate(STM32_DMA1_STREAM2, + b = dmaStreamAllocate(uartp->dmarx, STM32_UART_USART3_IRQ_PRIORITY, - (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); chDbgAssert(!b, "uart_lld_start(), #5", "stream already allocated"); - b = dmaStreamAllocate(STM32_DMA1_STREAM3, + b = dmaStreamAllocate(uartp->dmatx, STM32_UART_USART3_IRQ_PRIORITY, - (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); chDbgAssert(!b, "uart_lld_start(), #6", "stream already allocated"); rccEnableUSART3(FALSE); NVICEnableVector(USART3_IRQn, CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY)); + uartp->dmamode |= STM32_DMA_CR_CHSEL(USART3_RX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_UART_USART3_DMA_PRIORITY); } #endif /* Static DMA setup, the transfer size depends on the USART settings, it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/ - uartp->dmamode = STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY); if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M) uartp->dmamode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; dmaStreamSetPeripheral(uartp->dmarx, &uartp->usart->DR); @@ -432,11 +470,11 @@ void uart_lld_stop(UARTDriver *uartp) { if (uartp->state == UART_READY) { usart_stop(uartp); + dmaStreamRelease(uartp->dmarx); + dmaStreamRelease(uartp->dmatx); #if STM32_UART_USE_USART1 if (&UARTD1 == uartp) { - dmaStreamRelease(STM32_DMA1_STREAM4); - dmaStreamRelease(STM32_DMA1_STREAM5); NVICDisableVector(USART1_IRQn); rccDisableUSART1(FALSE); return; @@ -445,8 +483,6 @@ void uart_lld_stop(UARTDriver *uartp) { #if STM32_UART_USE_USART2 if (&UARTD2 == uartp) { - dmaStreamRelease(STM32_DMA1_STREAM6); - dmaStreamRelease(STM32_DMA1_STREAM7); NVICDisableVector(USART2_IRQn); rccDisableUSART2(FALSE); return; @@ -455,8 +491,6 @@ void uart_lld_stop(UARTDriver *uartp) { #if STM32_UART_USE_USART3 if (&UARTD3 == uartp) { - dmaStreamRelease(STM32_DMA1_STREAM2); - dmaStreamRelease(STM32_DMA1_STREAM3); NVICDisableVector(USART3_IRQn); rccDisableUSART3(FALSE); return; @@ -482,8 +516,7 @@ void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { dmaStreamSetMemory0(uartp->dmatx, txbuf); dmaStreamSetTransactionSize(uartp->dmatx, n); dmaStreamSetMode(uartp->dmatx, uartp->dmamode | STM32_DMA_CR_DIR_M2P | - STM32_DMA_CR_MINC | STM32_DMA_CR_TEIE | - STM32_DMA_CR_TCIE); + STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE); dmaStreamEnable(uartp->dmatx); } @@ -526,8 +559,7 @@ void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) { dmaStreamSetMemory0(uartp->dmarx, rxbuf); dmaStreamSetTransactionSize(uartp->dmarx, n); dmaStreamSetMode(uartp->dmarx, uartp->dmamode | STM32_DMA_CR_DIR_P2M | - STM32_DMA_CR_MINC | STM32_DMA_CR_TEIE | - STM32_DMA_CR_TCIE); + STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE); dmaStreamEnable(uartp->dmarx); } diff --git a/os/hal/platforms/STM32/uart_lld.h b/os/hal/platforms/STM32/uart_lld.h index d97bea91b..742a8a37d 100644 --- a/os/hal/platforms/STM32/uart_lld.h +++ b/os/hal/platforms/STM32/uart_lld.h @@ -110,6 +110,7 @@ #if !defined(STM32_UART_USART2_DMA_PRIORITY) || defined(__DOXYGEN__) #define STM32_UART_USART2_DMA_PRIORITY 0 #endif + /** * @brief USART3 DMA priority (0..3|lowest..highest). * @note The priority level is used for both the TX and RX DMA channels but @@ -128,6 +129,69 @@ #if !defined(STM32_UART_DMA_ERROR_HOOK) || defined(__DOXYGEN__) #define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt() #endif + +#if STM32_ADVANCED_DMA || defined(__DOXYGEN__) + +/** + * @brief DMA stream used for USART1 RX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_UART_USART1_RX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) +#endif + +/** + * @brief DMA stream used for USART1 TX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_UART_USART1_TX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) +#endif + +/** + * @brief DMA stream used for USART2 RX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_UART_USART2_RX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#endif + +/** + * @brief DMA stream used for USART2 TX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_UART_USART2_TX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#endif + +/** + * @brief DMA stream used for USART3 RX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_UART_USART3_RX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) +#endif + +/** + * @brief DMA stream used for USART3 TX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_UART_USART3_TX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#endif + +#else /* !STM32_ADVANCED_DMA */ + +/* Fixed streams for platforms using the old DMA peripheral, the values are + valid for both STM32F1xx and STM32L1xx.*/ +#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) + +#endif /* !STM32_ADVANCED_DMA*/ /** @} */ /*===========================================================================*/ @@ -151,6 +215,42 @@ #error "UART driver activated but no USART/UART peripheral assigned" #endif +#if STM32_UART_USE_USART1 && \ + !STM32_DMA_IS_VALID_ID(STM32_UART_USART1_RX_DMA_STREAM, \ + STM32_USART1_RX_DMA_MSK) +#error "invalid DMA stream associated to USART1 RX" +#endif + +#if STM32_UART_USE_USART1 && \ + !STM32_DMA_IS_VALID_ID(STM32_UART_USART1_TX_DMA_STREAM, \ + STM32_USART1_TX_DMA_MSK) +#error "invalid DMA stream associated to USART1 TX" +#endif + +#if STM32_UART_USE_USART2 && \ + !STM32_DMA_IS_VALID_ID(STM32_UART_USART2_RX_DMA_STREAM, \ + STM32_USART2_RX_DMA_MSK) +#error "invalid DMA stream associated to USART2 RX" +#endif + +#if STM32_UART_USE_USART2 && \ + !STM32_DMA_IS_VALID_ID(STM32_UART_USART2_TX_DMA_STREAM, \ + STM32_USART2_TX_DMA_MSK) +#error "invalid DMA stream associated to USART2 TX" +#endif + +#if STM32_UART_USE_USART3 && \ + !STM32_DMA_IS_VALID_ID(STM32_UART_USART3_RX_DMA_STREAM, \ + STM32_USART3_RX_DMA_MSK) +#error "invalid DMA stream associated to USART3 RX" +#endif + +#if STM32_UART_USE_USART3 && \ + !STM32_DMA_IS_VALID_ID(STM32_UART_USART3_TX_DMA_STREAM, \ + STM32_USART3_TX_DMA_MSK) +#error "invalid DMA stream associated to USART3 TX" +#endif + #if !defined(STM32_DMA_REQUIRED) #define STM32_DMA_REQUIRED #endif diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f100.h b/os/hal/platforms/STM32F1xx/hal_lld_f100.h index 91be2eadb..3f5d9502b 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f100.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f100.h @@ -212,11 +212,40 @@ /* USART attributes.*/ #define STM32_HAS_USART1 TRUE +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_USART1_RX_DMA_CHN 0x00000000 +#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_USART1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART2 TRUE +#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_USART2_RX_DMA_CHN 0x00000000 +#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_USART2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART3 FALSE +#define STM32_USART3_RX_DMA_MSK 0 +#define STM32_USART3_RX_DMA_CHN 0x00000000 +#define STM32_USART3_TX_DMA_MSK 0 +#define STM32_USART3_TX_DMA_CHN 0x00000000 + #define STM32_HAS_UART4 FALSE +#define STM32_UART4_RX_DMA_MSK 0 +#define STM32_UART4_RX_DMA_CHN 0x00000000 +#define STM32_UART4_TX_DMA_MSK 0 +#define STM32_UART4_TX_DMA_CHN 0x00000000 + #define STM32_HAS_UART5 FALSE +#define STM32_UART5_RX_DMA_MSK 0 +#define STM32_UART5_RX_DMA_CHN 0x00000000 +#define STM32_UART5_TX_DMA_MSK 0 +#define STM32_UART5_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART6 FALSE +#define STM32_USART6_RX_DMA_MSK 0 +#define STM32_USART6_RX_DMA_CHN 0x00000000 +#define STM32_USART6_TX_DMA_MSK 0 +#define STM32_USART6_TX_DMA_CHN 0x00000000 /* USB attributes.*/ #define STM32_HAS_USB FALSE diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f103.h b/os/hal/platforms/STM32F1xx/hal_lld_f103.h index 4090502a1..22d955c65 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f103.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f103.h @@ -223,11 +223,40 @@ /* USART attributes.*/ #define STM32_HAS_USART1 TRUE +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_USART1_RX_DMA_CHN 0x00000000 +#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_USART1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART2 TRUE +#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_USART2_RX_DMA_CHN 0x00000000 +#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_USART2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART3 FALSE +#define STM32_USART3_RX_DMA_MSK 0 +#define STM32_USART3_RX_DMA_CHN 0x00000000 +#define STM32_USART3_TX_DMA_MSK 0 +#define STM32_USART3_TX_DMA_CHN 0x00000000 + #define STM32_HAS_UART4 FALSE +#define STM32_UART4_RX_DMA_MSK 0 +#define STM32_UART4_RX_DMA_CHN 0x00000000 +#define STM32_UART4_TX_DMA_MSK 0 +#define STM32_UART4_TX_DMA_CHN 0x00000000 + #define STM32_HAS_UART5 FALSE +#define STM32_UART5_RX_DMA_MSK 0 +#define STM32_UART5_RX_DMA_CHN 0x00000000 +#define STM32_UART5_TX_DMA_MSK 0 +#define STM32_UART5_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART6 FALSE +#define STM32_USART6_RX_DMA_MSK 0 +#define STM32_USART6_RX_DMA_CHN 0x00000000 +#define STM32_USART6_TX_DMA_MSK 0 +#define STM32_USART6_TX_DMA_CHN 0x00000000 /* USB attributes.*/ #define STM32_HAS_USB FALSE @@ -326,11 +355,40 @@ /* USART attributes.*/ #define STM32_HAS_USART1 TRUE +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_USART1_RX_DMA_CHN 0x00000000 +#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_USART1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART2 TRUE +#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_USART2_RX_DMA_CHN 0x00000000 +#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_USART2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART3 TRUE +#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3)) +#define STM32_USART3_RX_DMA_CHN 0x00000000 +#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_USART3_TX_DMA_CHN 0x00000000 + #define STM32_HAS_UART4 FALSE +#define STM32_UART4_RX_DMA_MSK 0 +#define STM32_UART4_RX_DMA_CHN 0x00000000 +#define STM32_UART4_TX_DMA_MSK 0 +#define STM32_UART4_TX_DMA_CHN 0x00000000 + #define STM32_HAS_UART5 FALSE +#define STM32_UART5_RX_DMA_MSK 0 +#define STM32_UART5_RX_DMA_CHN 0x00000000 +#define STM32_UART5_TX_DMA_MSK 0 +#define STM32_UART5_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART6 FALSE +#define STM32_USART6_RX_DMA_MSK 0 +#define STM32_USART6_RX_DMA_CHN 0x00000000 +#define STM32_USART6_TX_DMA_MSK 0 +#define STM32_USART6_TX_DMA_CHN 0x00000000 /* USB attributes.*/ #define STM32_HAS_USB TRUE @@ -429,11 +487,40 @@ /* USART attributes.*/ #define STM32_HAS_USART1 TRUE +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_USART1_RX_DMA_CHN 0x00000000 +#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_USART1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART2 TRUE +#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_USART2_RX_DMA_CHN 0x00000000 +#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_USART2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART3 TRUE +#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3)) +#define STM32_USART3_RX_DMA_CHN 0x00000000 +#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_USART3_TX_DMA_CHN 0x00000000 + #define STM32_HAS_UART4 TRUE +#define STM32_UART4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3)) +#define STM32_UART4_RX_DMA_CHN 0x00000000 +#define STM32_UART4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_UART4_TX_DMA_CHN 0x00000000 + #define STM32_HAS_UART5 TRUE +#define STM32_UART5_RX_DMA_MSK 0 +#define STM32_UART5_RX_DMA_CHN 0x00000000 +#define STM32_UART5_TX_DMA_MSK 0 +#define STM32_UART5_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART6 FALSE +#define STM32_USART6_RX_DMA_MSK 0 +#define STM32_USART6_RX_DMA_CHN 0x00000000 +#define STM32_USART6_TX_DMA_MSK 0 +#define STM32_USART6_TX_DMA_CHN 0x00000000 /* USB attributes.*/ #define STM32_HAS_USB TRUE @@ -532,11 +619,40 @@ /* USART attributes.*/ #define STM32_HAS_USART1 TRUE +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_USART1_RX_DMA_CHN 0x00000000 +#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_USART1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART2 TRUE +#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_USART2_RX_DMA_CHN 0x00000000 +#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_USART2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART3 TRUE +#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3)) +#define STM32_USART3_RX_DMA_CHN 0x00000000 +#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_USART3_TX_DMA_CHN 0x00000000 + #define STM32_HAS_UART4 TRUE +#define STM32_UART4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3)) +#define STM32_UART4_RX_DMA_CHN 0x00000000 +#define STM32_UART4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_UART4_TX_DMA_CHN 0x00000000 + #define STM32_HAS_UART5 TRUE +#define STM32_UART5_RX_DMA_MSK 0 +#define STM32_UART5_RX_DMA_CHN 0x00000000 +#define STM32_UART5_TX_DMA_MSK 0 +#define STM32_UART5_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART6 FALSE +#define STM32_USART6_RX_DMA_MSK 0 +#define STM32_USART6_RX_DMA_CHN 0x00000000 +#define STM32_USART6_TX_DMA_MSK 0 +#define STM32_USART6_TX_DMA_CHN 0x00000000 /* USB attributes.*/ #define STM32_HAS_USB TRUE diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h index dff2f7b2e..882ec6094 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h @@ -215,11 +215,40 @@ /* USART attributes.*/ #define STM32_HAS_USART1 TRUE +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_USART1_RX_DMA_CHN 0x00000000 +#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_USART1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART2 TRUE +#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_USART2_RX_DMA_CHN 0x00000000 +#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_USART2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART3 TRUE +#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3)) +#define STM32_USART3_RX_DMA_CHN 0x00000000 +#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_USART3_TX_DMA_CHN 0x00000000 + #define STM32_HAS_UART4 TRUE +#define STM32_UART4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3)) +#define STM32_UART4_RX_DMA_CHN 0x00000000 +#define STM32_UART4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_UART4_TX_DMA_CHN 0x00000000 + #define STM32_HAS_UART5 TRUE +#define STM32_UART5_RX_DMA_MSK 0 +#define STM32_UART5_RX_DMA_CHN 0x00000000 +#define STM32_UART5_TX_DMA_MSK 0 +#define STM32_UART5_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART6 FALSE +#define STM32_USART6_RX_DMA_MSK 0 +#define STM32_USART6_RX_DMA_CHN 0x00000000 +#define STM32_USART6_TX_DMA_MSK 0 +#define STM32_USART6_TX_DMA_CHN 0x00000000 /* USB attributes.*/ #define STM32_HAS_USB FALSE diff --git a/os/hal/platforms/STM32F4xx/adc_lld.c b/os/hal/platforms/STM32F4xx/adc_lld.c index 5edac0163..a4bfac99f 100644 --- a/os/hal/platforms/STM32F4xx/adc_lld.c +++ b/os/hal/platforms/STM32F4xx/adc_lld.c @@ -80,7 +80,7 @@ ADCDriver ADCD3; static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { /* DMA errors handling.*/ - if ((flags & STM32_DMA_ISR_TEIF) != 0) { + 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); diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index 71207efd5..bdb8cb86b 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -349,11 +349,44 @@ /* 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 0x00400400 +#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 0x00074040 + #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 /* USB attributes.*/ #define STM32_HAS_USB FALSE diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index d62176a16..b6b0060d6 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -251,11 +251,40 @@ /* USART attributes.*/ #define STM32_HAS_USART1 TRUE +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_USART1_RX_DMA_CHN 0x00000000 +#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_USART1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART2 TRUE +#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_USART2_RX_DMA_CHN 0x00000000 +#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_USART2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART3 TRUE +#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3)) +#define STM32_USART3_RX_DMA_CHN 0x00000000 +#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_USART3_TX_DMA_CHN 0x00000000 + #define STM32_HAS_UART4 FALSE +#define STM32_UART4_RX_DMA_MSK 0 +#define STM32_UART4_RX_DMA_CHN 0x00000000 +#define STM32_UART4_TX_DMA_MSK 0 +#define STM32_UART4_TX_DMA_CHN 0x00000000 + #define STM32_HAS_UART5 FALSE +#define STM32_UART5_RX_DMA_MSK 0 +#define STM32_UART5_RX_DMA_CHN 0x00000000 +#define STM32_UART5_TX_DMA_MSK 0 +#define STM32_UART5_TX_DMA_CHN 0x00000000 + #define STM32_HAS_USART6 FALSE +#define STM32_USART6_RX_DMA_MSK 0 +#define STM32_USART6_RX_DMA_CHN 0x00000000 +#define STM32_USART6_TX_DMA_MSK 0 +#define STM32_USART6_TX_DMA_CHN 0x00000000 /* USB attributes.*/ #define STM32_HAS_USB TRUE -- cgit v1.2.3 From 5a74dd3c2e3aa7c2a72f1bfe69a39b047710c429 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 23 Nov 2011 22:01:13 +0000 Subject: Fixed a problem of inclusion order that caused DMA2 problems in STM32 HAls. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3522 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/hal_lld.h | 8 ++++---- os/hal/platforms/STM32F4xx/hal_lld.h | 8 ++++---- os/hal/platforms/STM32L1xx/hal_lld.h | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/hal_lld.h b/os/hal/platforms/STM32F1xx/hal_lld.h index a4ccd3118..b1ba1a5ed 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld.h +++ b/os/hal/platforms/STM32F1xx/hal_lld.h @@ -45,10 +45,6 @@ #include "stm32f10x.h" -/* STM32 DMA and RCC helpers.*/ -#include "stm32_dma.h" -#include "stm32_rcc.h" - /*===========================================================================*/ /* Driver constants. */ /*===========================================================================*/ @@ -155,6 +151,10 @@ typedef struct { /* External declarations. */ /*===========================================================================*/ +/* STM32 DMA and RCC helpers.*/ +#include "stm32_dma.h" +#include "stm32_rcc.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index bdb8cb86b..29018e86f 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -40,10 +40,6 @@ #include "stm32f4xx.h" -/* STM32 DMA and RCC helpers.*/ -#include "stm32_dma.h" -#include "stm32_rcc.h" - /*===========================================================================*/ /* Driver constants. */ /*===========================================================================*/ @@ -1344,6 +1340,10 @@ typedef struct { /* External declarations. */ /*===========================================================================*/ +/* STM32 DMA and RCC helpers.*/ +#include "stm32_dma.h" +#include "stm32_rcc.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index b6b0060d6..fe2909536 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -39,10 +39,6 @@ #include "stm32l1xx.h" -/* STM32 DMA and RCC helpers.*/ -#include "stm32_dma.h" -#include "stm32_rcc.h" - /*===========================================================================*/ /* Driver constants. */ /*===========================================================================*/ @@ -1009,6 +1005,10 @@ typedef struct { /* External declarations. */ /*===========================================================================*/ +/* STM32 DMA and RCC helpers.*/ +#include "stm32_dma.h" +#include "stm32_rcc.h" + #ifdef __cplusplus extern "C" { #endif -- cgit v1.2.3 From 46870077b874696c09704da37dc4c33c8eb21402 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 24 Nov 2011 17:58:27 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3523 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/ext_lld.c | 16 +++---- os/hal/platforms/STM32L1xx/adc_lld.c | 81 ++++++++++++++++++++---------------- os/hal/platforms/STM32L1xx/adc_lld.h | 14 +++++-- 3 files changed, 64 insertions(+), 47 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/ext_lld.c b/os/hal/platforms/STM32/ext_lld.c index 13eca6f3b..c9b4b75c2 100644 --- a/os/hal/platforms/STM32/ext_lld.c +++ b/os/hal/platforms/STM32/ext_lld.c @@ -282,7 +282,7 @@ CH_IRQ_HANDLER(COMP_IRQHandler) { CH_IRQ_EPILOGUE(); } -#elif defined(STM32F2XX) +#elif defined(STM32F2XX) || defined(STM32F4XX) /** * @brief EXTI[18] interrupt handler (OTG_FS_WKUP). * @@ -462,15 +462,15 @@ void ext_lld_start(EXTDriver *extp) { CORTEX_PRIORITY_MASK(STM32_EXT_EXTI20_IRQ_PRIORITY)); NVICEnableVector(COMP_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI21_IRQ_PRIORITY)); -#elif defined(STM32F2XX) - /* EXTI vectors specific to STM32F2xx.*/ +#elif defined(STM32F2XX) || defined(STM32F4XX) + /* EXTI vectors specific to STM32F2xx/STM32F4xx.*/ NVICEnableVector(OTG_FS_WKUP_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI18_IRQ_PRIORITY)); NVICEnableVector(ETH_WKUP_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI19_IRQ_PRIORITY)); NVICEnableVector(OTG_HS_WKUP_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI20_IRQ_PRIORITY)); - NVICEnableVector(TAMPER_STAMP_IRQn, + NVICEnableVector(TAMP_STAMP_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI21_IRQ_PRIORITY)); NVICEnableVector(RTC_WKUP_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI22_IRQ_PRIORITY)); @@ -500,7 +500,7 @@ void ext_lld_start(EXTDriver *extp) { ftsr |= (1 << i); } } -#if defined(STM32L1XX_MD) || defined(STM32F2XX) +#if defined(STM32L1XX_MD) || defined(STM32F2XX) || defined(STM32F4XX) SYSCFG->EXTICR[0] = extp->config->exti[0]; SYSCFG->EXTICR[1] = extp->config->exti[1]; SYSCFG->EXTICR[2] = extp->config->exti[2]; @@ -544,12 +544,12 @@ void ext_lld_stop(EXTDriver *extp) { NVICDisableVector(TAMPER_STAMP_IRQn); NVICDisableVector(RTC_WKUP_IRQn); NVICDisableVector(COMP_IRQn); -#elif defined(STM32F2XX) - /* EXTI vectors specific to STM32F2xx.*/ +#elif defined(STM32F2XX) || defined(STM32F4XX) + /* EXTI vectors specific to STM32F2xx/STM32F4xx.*/ NVICDisableVector(OTG_FS_WKUP_IRQn); NVICDisableVector(ETH_WKUP_IRQn); NVICDisableVector(OTG_HS_WKUP_IRQn); - NVICDisableVector(TAMPER_STAMP_IRQn); + NVICDisableVector(TAMP_STAMP_IRQn); NVICDisableVector(RTC_WKUP_IRQn); #elif defined(STM32F10X_CL) /* EXTI vectors specific to STM32F1xx Connectivity Line.*/ diff --git a/os/hal/platforms/STM32L1xx/adc_lld.c b/os/hal/platforms/STM32L1xx/adc_lld.c index 308fd90d0..428d8e452 100644 --- a/os/hal/platforms/STM32L1xx/adc_lld.c +++ b/os/hal/platforms/STM32L1xx/adc_lld.c @@ -57,19 +57,23 @@ ADCDriver ADCD1; static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { /* DMA errors handling.*/ - if ((flags & STM32_DMA_ISR_TEIF) != 0) { + 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 { - if ((flags & STM32_DMA_ISR_HTIF) != 0) { - /* Half transfer processing.*/ - _adc_isr_half_code(adcp); - } - if ((flags & STM32_DMA_ISR_TCIF) != 0) { - /* Transfer complete processing.*/ - _adc_isr_full_code(adcp); + /* 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_HTIF) != 0) { + /* Half transfer processing.*/ + _adc_isr_half_code(adcp); + } + if ((flags & STM32_DMA_ISR_TCIF) != 0) { + /* Transfer complete processing.*/ + _adc_isr_full_code(adcp); + } } } } @@ -80,7 +84,7 @@ static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { #if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__) /** - * @brief ADC1 interrupt handler. + * @brief ADC interrupt handler. * * @isr */ @@ -91,10 +95,13 @@ CH_IRQ_HANDLER(ADC1_IRQHandler) { sr = ADC1->SR; ADC1->SR = 0; - if (sr & ADC_SR_OVR) { + /* 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.*/ - _adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW); + if (ADCD1.grpp != NULL) + _adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW); } /* TODO: Add here analog watchdog handling.*/ @@ -119,11 +126,16 @@ void adc_lld_init(void) { ADCD1.adc = ADC1; ADCD1.dmastp = STM32_DMA1_STREAM1; 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_TEIE | STM32_DMA_CR_EN; - ADC->CCR = STM32_ADC_ADCPRE; + STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | + STM32_DMA_CR_EN; #endif + + /* The shared vector is initialized on driver initialization and never + disabled.*/ + NVICEnableVector(ADC1_IRQn, CORTEX_PRIORITY_MASK(STM32_ADC_IRQ_PRIORITY)); } /** @@ -141,20 +153,20 @@ void adc_lld_start(ADCDriver *adcp) { if (&ADCD1 == adcp) { bool_t b; b = dmaStreamAllocate(adcp->dmastp, - STM32_ADC_ADC1_IRQ_PRIORITY, + STM32_ADC_ADC1_DMA_IRQ_PRIORITY, (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, (void *)adcp); chDbgAssert(!b, "adc_lld_start(), #1", "stream already allocated"); dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR); rccEnableADC1(FALSE); - NVICEnableVector(ADC1_IRQn, - CORTEX_PRIORITY_MASK(STM32_ADC_ADC1_IRQ_PRIORITY)); } -#endif +#endif /* STM32_ADC_USE_ADC1 */ + - /* ADC initial setup, just resetting control registers in this case.*/ + /* 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; } } @@ -167,15 +179,15 @@ void adc_lld_start(ADCDriver *adcp) { */ void adc_lld_stop(ADCDriver *adcp) { - /* If in ready state then disables the ADC clock.*/ + /* If in ready state then disables the ADC clock and analog part.*/ if (adcp->state == ADC_READY) { + dmaStreamRelease(adcp->dmastp); + adcp->adc->CR1 = 0; + adcp->adc->CR2 = 0; + #if STM32_ADC_USE_ADC1 - if (&ADCD1 == adcp) { - ADC1->CR1 = 0; - ADC1->CR2 = 0; - dmaStreamRelease(adcp->dmastp); + if (&ADCD1 == adcp) rccDisableADC1(FALSE); - } #endif } } @@ -208,24 +220,20 @@ void adc_lld_start_conversion(ADCDriver *adcp) { /* ADC setup.*/ adcp->adc->SR = 0; - adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN; - adcp->adc->SMPR1 = grpp->smpr1; /* Writing SMPRx requires ADON=0. */ + adcp->adc->SMPR1 = grpp->smpr1; adcp->adc->SMPR2 = grpp->smpr2; adcp->adc->SMPR3 = grpp->smpr3; - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_CONT | ADC_CR2_DMA | ADC_CR2_DDS | - ADC_CR2_ADON; 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; - /* Must wait the ADC to be ready for conversion, see 10.3.6 "Timing diagram" - in the Reference Manual.*/ - while ((adcp->adc->SR & ADC_SR_ADONS) == 0) - ; - /* ADC start by raising ADC_CR2_SWSTART.*/ - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_SWSTART | ADC_CR2_CONT | ADC_CR2_DMA | - ADC_CR2_DDS | ADC_CR2_ADON; + + /* ADC configuration and start, the start is performed using the method + specified in the CR2 configuration, usually ADC_CR2_SWSTART.*/ + adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN; + adcp->adc->CR2 = grpp->cr2 | ADC_CR2_CONT | ADC_CR2_DMA | + ADC_CR2_DDS | ADC_CR2_ADON; } /** @@ -240,6 +248,7 @@ void adc_lld_stop_conversion(ADCDriver *adcp) { dmaStreamDisable(adcp->dmastp); adcp->adc->CR1 = 0; adcp->adc->CR2 = 0; + adcp->adc->CR2 = ADC_CR2_ADON; } /** diff --git a/os/hal/platforms/STM32L1xx/adc_lld.h b/os/hal/platforms/STM32L1xx/adc_lld.h index 58fb7bda1..29b5ff8c5 100644 --- a/os/hal/platforms/STM32L1xx/adc_lld.h +++ b/os/hal/platforms/STM32L1xx/adc_lld.h @@ -133,11 +133,19 @@ #endif /** - * @brief ADC1 interrupt priority level setting. + * @brief ADC interrupt priority level setting. */ -#if !defined(STM32_ADC_ADC1_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_ADC_ADC1_IRQ_PRIORITY 5 +#if !defined(STM32_ADC_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_ADC_IRQ_PRIORITY 5 #endif + +/** + * @brief ADC1 DMA interrupt priority level setting. + */ +#if !defined(STM32_ADC_ADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5 +#endif + /** @} */ /*===========================================================================*/ -- cgit v1.2.3 From e6b38cdd3741b822c3be51aba268f90fc1771032 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 24 Nov 2011 21:00:24 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3524 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32L1xx/adc_lld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32L1xx/adc_lld.c b/os/hal/platforms/STM32L1xx/adc_lld.c index 428d8e452..3d91a9991 100644 --- a/os/hal/platforms/STM32L1xx/adc_lld.c +++ b/os/hal/platforms/STM32L1xx/adc_lld.c @@ -162,10 +162,10 @@ void adc_lld_start(ADCDriver *adcp) { } #endif /* STM32_ADC_USE_ADC1 */ - /* 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; } } -- cgit v1.2.3 From f3bbf4800acff7c34a24306c534b7414fd481b6a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 24 Nov 2011 21:25:10 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3525 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/adc_lld.c | 1 + 1 file changed, 1 insertion(+) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/adc_lld.c b/os/hal/platforms/STM32F4xx/adc_lld.c index a4bfac99f..777804b5a 100644 --- a/os/hal/platforms/STM32F4xx/adc_lld.c +++ b/os/hal/platforms/STM32F4xx/adc_lld.c @@ -276,6 +276,7 @@ void adc_lld_start(ADCDriver *adcp) { /* 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; } } -- cgit v1.2.3 From c1a535d343d6ea6e84f99b9b0b760d9a582ad969 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 26 Nov 2011 10:30:56 +0000 Subject: Unified STM32 registers header file stm32.h. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3526 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/gpt_lld.c | 14 +-- os/hal/platforms/STM32/gpt_lld.h | 2 +- os/hal/platforms/STM32/icu_lld.c | 12 +-- os/hal/platforms/STM32/icu_lld.h | 2 +- os/hal/platforms/STM32/pwm_lld.c | 12 +-- os/hal/platforms/STM32/pwm_lld.h | 2 +- os/hal/platforms/STM32/stm32.h | 169 +++++++++++++++++++++++++++++++++ os/hal/platforms/STM32F1xx/hal_lld.h | 43 +-------- os/hal/platforms/STM32F1xx/stm32f10x.h | 3 - os/hal/platforms/STM32F2xx/stm32f2xx.h | 3 + os/hal/platforms/STM32F4xx/hal_lld.h | 43 +-------- os/hal/platforms/STM32F4xx/stm32f4xx.h | 5 +- os/hal/platforms/STM32L1xx/hal_lld.h | 43 +-------- os/hal/platforms/STM32L1xx/stm32l1xx.h | 4 +- 14 files changed, 199 insertions(+), 158 deletions(-) create mode 100644 os/hal/platforms/STM32/stm32.h (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/gpt_lld.c b/os/hal/platforms/STM32/gpt_lld.c index af8737f04..e40843ccb 100644 --- a/os/hal/platforms/STM32/gpt_lld.c +++ b/os/hal/platforms/STM32/gpt_lld.c @@ -192,7 +192,7 @@ CH_IRQ_HANDLER(TIM5_IRQHandler) { #if STM32_GPT_USE_TIM8 /** - * @brief TIM5 interrupt handler. + * @brief TIM8 interrupt handler. * * @isr */ @@ -219,37 +219,37 @@ void gpt_lld_init(void) { #if STM32_GPT_USE_TIM1 /* Driver initialization.*/ - GPTD1.tim = TIM1; + GPTD1.tim = STM32_TIM1; gptObjectInit(&GPTD1); #endif #if STM32_GPT_USE_TIM2 /* Driver initialization.*/ - GPTD2.tim = TIM2; + GPTD2.tim = STM32_TIM2; gptObjectInit(&GPTD2); #endif #if STM32_GPT_USE_TIM3 /* Driver initialization.*/ - GPTD3.tim = TIM3; + GPTD3.tim = STM32_TIM3; gptObjectInit(&GPTD3); #endif #if STM32_GPT_USE_TIM4 /* Driver initialization.*/ - GPTD4.tim = TIM4; + GPTD4.tim = STM32_TIM4; gptObjectInit(&GPTD4); #endif #if STM32_GPT_USE_TIM5 /* Driver initialization.*/ - GPTD5.tim = TIM5; + GPTD5.tim = STM32_TIM5; gptObjectInit(&GPTD5); #endif #if STM32_GPT_USE_TIM8 /* Driver initialization.*/ - GPTD5.tim = TIM8; + GPTD5.tim = STM32_TIM8; gptObjectInit(&GPTD8); #endif } diff --git a/os/hal/platforms/STM32/gpt_lld.h b/os/hal/platforms/STM32/gpt_lld.h index f61c5d030..13c5e1f4b 100644 --- a/os/hal/platforms/STM32/gpt_lld.h +++ b/os/hal/platforms/STM32/gpt_lld.h @@ -230,7 +230,7 @@ struct GPTDriver { /** * @brief Pointer to the TIMx registers block. */ - TIM_TypeDef *tim; + stm32_tim_t *tim; }; /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/icu_lld.c b/os/hal/platforms/STM32/icu_lld.c index ab3e12f26..e76f8a109 100644 --- a/os/hal/platforms/STM32/icu_lld.c +++ b/os/hal/platforms/STM32/icu_lld.c @@ -239,37 +239,37 @@ void icu_lld_init(void) { #if STM32_ICU_USE_TIM1 /* Driver initialization.*/ icuObjectInit(&ICUD1); - ICUD1.tim = TIM1; + ICUD1.tim = STM32_TIM1; #endif #if STM32_ICU_USE_TIM2 /* Driver initialization.*/ icuObjectInit(&ICUD2); - ICUD2.tim = TIM2; + ICUD2.tim = STM32_TIM2; #endif #if STM32_ICU_USE_TIM3 /* Driver initialization.*/ icuObjectInit(&ICUD3); - ICUD3.tim = TIM3; + ICUD3.tim = STM32_TIM3; #endif #if STM32_ICU_USE_TIM4 /* Driver initialization.*/ icuObjectInit(&ICUD4); - ICUD4.tim = TIM4; + ICUD4.tim = STM32_TIM4; #endif #if STM32_ICU_USE_TIM5 /* Driver initialization.*/ icuObjectInit(&ICUD5); - ICUD5.tim = TIM5; + ICUD5.tim = STM32_TIM5; #endif #if STM32_ICU_USE_TIM8 /* Driver initialization.*/ icuObjectInit(&ICUD8); - ICUD5.tim = TIM8; + ICUD5.tim = STM32_TIM8; #endif } diff --git a/os/hal/platforms/STM32/icu_lld.h b/os/hal/platforms/STM32/icu_lld.h index b97930609..f5b6bf695 100644 --- a/os/hal/platforms/STM32/icu_lld.h +++ b/os/hal/platforms/STM32/icu_lld.h @@ -245,7 +245,7 @@ struct ICUDriver { /** * @brief Pointer to the TIMx registers block. */ - TIM_TypeDef *tim; + stm32_tim_t *tim; }; /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/pwm_lld.c b/os/hal/platforms/STM32/pwm_lld.c index fb5d12adf..4392d5db9 100644 --- a/os/hal/platforms/STM32/pwm_lld.c +++ b/os/hal/platforms/STM32/pwm_lld.c @@ -297,37 +297,37 @@ void pwm_lld_init(void) { #if STM32_PWM_USE_TIM1 /* Driver initialization.*/ pwmObjectInit(&PWMD1); - PWMD1.tim = TIM1; + PWMD1.tim = STM32_TIM1; #endif #if STM32_PWM_USE_TIM2 /* Driver initialization.*/ pwmObjectInit(&PWMD2); - PWMD2.tim = TIM2; + PWMD2.tim = STM32_TIM2; #endif #if STM32_PWM_USE_TIM3 /* Driver initialization.*/ pwmObjectInit(&PWMD3); - PWMD3.tim = TIM3; + PWMD3.tim = STM32_TIM3; #endif #if STM32_PWM_USE_TIM4 /* Driver initialization.*/ pwmObjectInit(&PWMD4); - PWMD4.tim = TIM4; + PWMD4.tim = STM32_TIM4; #endif #if STM32_PWM_USE_TIM5 /* Driver initialization.*/ pwmObjectInit(&PWMD5); - PWMD5.tim = TIM5; + PWMD5.tim = STM32_TIM5; #endif #if STM32_PWM_USE_TIM8 /* Driver initialization.*/ pwmObjectInit(&PWMD8); - PWMD8.tim = TIM8; + PWMD8.tim = STM32_TIM8; #endif } diff --git a/os/hal/platforms/STM32/pwm_lld.h b/os/hal/platforms/STM32/pwm_lld.h index 78e411592..ca890e8f0 100644 --- a/os/hal/platforms/STM32/pwm_lld.h +++ b/os/hal/platforms/STM32/pwm_lld.h @@ -327,7 +327,7 @@ struct PWMDriver { /** * @brief Pointer to the TIMx registers block. */ - TIM_TypeDef *tim; + stm32_tim_t *tim; }; /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/stm32.h b/os/hal/platforms/STM32/stm32.h new file mode 100644 index 000000000..0ee083dcc --- /dev/null +++ b/os/hal/platforms/STM32/stm32.h @@ -0,0 +1,169 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/stm32.h + * @brief STM32 common header. + * @pre One of the following macros must be defined before including + * this header, the macro selects the inclusion of the appropriate + * vendor header: + * - STM32F10X_LD_VL for Value Line Low Density devices. + * - STM32F10X_MD_VL for Value Line Medium Density devices. + * - STM32F10X_LD for Performance Low Density devices. + * - STM32F10X_MD for Performance Medium Density devices. + * - STM32F10X_HD for Performance High Density devices. + * - STM32F10X_XL for Performance eXtra Density devices. + * - STM32F10X_CL for Connectivity Line devices. + * - STM32F2XX for High-performance STM32 F-2 devices. + * - STM32F4XX for High-performance STM32 F-4 devices. + * - STM32L1XX_MD for Ultra Low Power Medium-density devices. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef _STM32_H_ +#define _STM32_H_ + +#if defined(STM32F10X_LD_VL) || defined(STM32F10X_MD_VL) || \ + defined(STM32F10X_HD_VL) || defined(STM32F10X_LD) || \ + defined(STM32F10X_MD) || defined(STM32F10X_HD) || \ + defined(STM32F10X_XL) || defined(STM32F10X_CL) || \ + defined(__DOXYGEN__) +#include "stm32f10x.h" +#endif + +#if defined(STM32F2XX) || defined(__DOXYGEN__) +#include "stm32f2xx.h" +#endif + +#if defined(STM32F4XX) || defined(__DOXYGEN__) +#include "stm32f4xx.h" +#endif + +#if defined(STM32L1XX_MD) || defined(__DOXYGEN__) +#include "stm32l1xx.h" +#endif + +#undef TIM1 +#undef TIM2 +#undef TIM3 +#undef TIM4 +#undef TIM5 +#undef TIM6 +#undef TIM7 +#undef TIM8 +#undef TIM9 +#undef TIM10 +#undef TIM11 +#undef TIM12 +#undef TIM13 +#undef TIM14 + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief STM32 TIM registers block. + * @note Redefined from the ST headers because the non uniform + * declaration of the CCR registers among the various + * sub-families. + */ +typedef struct { + volatile uint16_t CR1; + uint16_t _resvd0; + volatile uint16_t CR2; + uint16_t _resvd1; + volatile uint16_t SMCR; + uint16_t _resvd2; + volatile uint16_t DIER; + uint16_t _resvd3; + volatile uint16_t SR; + uint16_t _resvd4; + volatile uint16_t EGR; + uint16_t _resvd5; + volatile uint16_t CCMR1; + uint16_t _resvd6; + volatile uint16_t CCMR2; + uint16_t _resvd7; + volatile uint16_t CCER; + uint16_t _resvd8; + volatile uint32_t CNT; + volatile uint16_t PSC; + uint16_t _resvd9; + volatile uint32_t ARR; + volatile uint16_t RCR; + uint16_t _resvd10; + volatile uint32_t CCR[4]; + volatile uint16_t BDTR; + uint16_t _resvd11; + volatile uint16_t DCR; + uint16_t _resvd12; + volatile uint16_t DMAR; + uint16_t _resvd13; + volatile uint16_t OR; + uint16_t _resvd14; +} stm32_tim_t; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @name TIM units references + * @{ + */ +#define STM32_TIM1 ((stm32_tim_t *)TIM1_BASE) +#define STM32_TIM2 ((stm32_tim_t *)TIM2_BASE) +#define STM32_TIM3 ((stm32_tim_t *)TIM3_BASE) +#define STM32_TIM4 ((stm32_tim_t *)TIM4_BASE) +#define STM32_TIM5 ((stm32_tim_t *)TIM5_BASE) +#define STM32_TIM6 ((stm32_tim_t *)TIM6_BASE) +#define STM32_TIM7 ((stm32_tim_t *)TIM7_BASE) +#define STM32_TIM8 ((stm32_tim_t *)TIM8_BASE) +#define STM32_TIM9 ((stm32_tim_t *)TIM9_BASE) +#define STM32_TIM10 ((stm32_tim_t *)TIM10_BASE) +#define STM32_TIM11 ((stm32_tim_t *)TIM11_BASE) +#define STM32_TIM12 ((stm32_tim_t *)TIM12_BASE) +#define STM32_TIM13 ((stm32_tim_t *)TIM13_BASE) +#define STM32_TIM14 ((stm32_tim_t *)TIM14_BASE) +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#endif /* _STM32_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32F1xx/hal_lld.h b/os/hal/platforms/STM32F1xx/hal_lld.h index b1ba1a5ed..64cf0165c 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld.h +++ b/os/hal/platforms/STM32F1xx/hal_lld.h @@ -43,7 +43,7 @@ #ifndef _HAL_LLD_H_ #define _HAL_LLD_H_ -#include "stm32f10x.h" +#include "stm32.h" /*===========================================================================*/ /* Driver constants. */ @@ -102,47 +102,6 @@ /* Driver data structures and types. */ /*===========================================================================*/ -/** - * @brief STM32 TIM registers block. - * @note Removed from the ST headers and redefined because the non uniform - * declaration of the CCR registers among the various sub-families. - */ -typedef struct { - volatile uint16_t CR1; - uint16_t _resvd0; - volatile uint16_t CR2; - uint16_t _resvd1; - volatile uint16_t SMCR; - uint16_t _resvd2; - volatile uint16_t DIER; - uint16_t _resvd3; - volatile uint16_t SR; - uint16_t _resvd4; - volatile uint16_t EGR; - uint16_t _resvd5; - volatile uint16_t CCMR1; - uint16_t _resvd6; - volatile uint16_t CCMR2; - uint16_t _resvd7; - volatile uint16_t CCER; - uint16_t _resvd8; - volatile uint32_t CNT; - volatile uint16_t PSC; - uint16_t _resvd9; - volatile uint32_t ARR; - volatile uint16_t RCR; - uint16_t _resvd10; - volatile uint32_t CCR[4]; - volatile uint16_t BDTR; - uint16_t _resvd11; - volatile uint16_t DCR; - uint16_t _resvd12; - volatile uint16_t DMAR; - uint16_t _resvd13; - volatile uint16_t OR; - uint16_t _resvd14; -} TIM_TypeDef; - /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F1xx/stm32f10x.h b/os/hal/platforms/STM32F1xx/stm32f10x.h index e8f413763..6697b9648 100644 --- a/os/hal/platforms/STM32F1xx/stm32f10x.h +++ b/os/hal/platforms/STM32F1xx/stm32f10x.h @@ -1198,8 +1198,6 @@ typedef struct * @brief TIM */ -/* CHIBIOS FIX */ -#if 0 typedef struct { __IO uint16_t CR1; @@ -1243,7 +1241,6 @@ typedef struct __IO uint16_t DMAR; uint16_t RESERVED19; } TIM_TypeDef; -#endif /** * @brief Universal Synchronous Asynchronous Receiver Transmitter diff --git a/os/hal/platforms/STM32F2xx/stm32f2xx.h b/os/hal/platforms/STM32F2xx/stm32f2xx.h index 51bcaf363..5c6e27d76 100644 --- a/os/hal/platforms/STM32F2xx/stm32f2xx.h +++ b/os/hal/platforms/STM32F2xx/stm32f2xx.h @@ -227,6 +227,7 @@ typedef enum IRQn */ #include "core_cm3.h" +/* CHIBIOS FIX */ /* #include "system_stm32f2xx.h" */ #include @@ -634,6 +635,7 @@ typedef struct /** * @brief General Purpose I/O */ +/* CHIBIOS FIX */ #if 0 typedef struct { @@ -649,6 +651,7 @@ typedef struct __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x24-0x28 */ } GPIO_TypeDef; #endif + /** * @brief System configuration controller */ diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index 29018e86f..a4dd1b775 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -38,7 +38,7 @@ #ifndef _HAL_LLD_H_ #define _HAL_LLD_H_ -#include "stm32f4xx.h" +#include "stm32.h" /*===========================================================================*/ /* Driver constants. */ @@ -1291,47 +1291,6 @@ /* Driver data structures and types. */ /*===========================================================================*/ -/** - * @brief STM32 TIM registers block. - * @note Removed from the ST headers and redefined because the non uniform - * declaration of the CCR registers among the various sub-families. - */ -typedef struct { - volatile uint16_t CR1; - uint16_t _resvd0; - volatile uint16_t CR2; - uint16_t _resvd1; - volatile uint16_t SMCR; - uint16_t _resvd2; - volatile uint16_t DIER; - uint16_t _resvd3; - volatile uint16_t SR; - uint16_t _resvd4; - volatile uint16_t EGR; - uint16_t _resvd5; - volatile uint16_t CCMR1; - uint16_t _resvd6; - volatile uint16_t CCMR2; - uint16_t _resvd7; - volatile uint16_t CCER; - uint16_t _resvd8; - volatile uint32_t CNT; - volatile uint16_t PSC; - uint16_t _resvd9; - volatile uint32_t ARR; - volatile uint16_t RCR; - uint16_t _resvd10; - volatile uint32_t CCR[4]; - volatile uint16_t BDTR; - uint16_t _resvd11; - volatile uint16_t DCR; - uint16_t _resvd12; - volatile uint16_t DMAR; - uint16_t _resvd13; - volatile uint16_t OR; - uint16_t _resvd14; -} TIM_TypeDef; - /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F4xx/stm32f4xx.h b/os/hal/platforms/STM32F4xx/stm32f4xx.h index cd8ed7887..f4e88fc17 100644 --- a/os/hal/platforms/STM32F4xx/stm32f4xx.h +++ b/os/hal/platforms/STM32F4xx/stm32f4xx.h @@ -237,8 +237,8 @@ typedef enum IRQn * @} */ - /* CHIBIOS FIX */ #include "core_cm4.h" /* Cortex-M4 processor and core peripherals */ +/* CHIBIOS FIX */ /*#include "system_stm32f4xx.h"*/ #include @@ -868,8 +868,6 @@ typedef struct * @brief TIM */ -/* CHIBIOS FIX */ -#if 0 typedef struct { __IO uint16_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ @@ -909,7 +907,6 @@ typedef struct __IO uint16_t OR; /*!< TIM option register, Address offset: 0x50 */ uint16_t RESERVED14; /*!< Reserved, 0x52 */ } TIM_TypeDef; -#endif /** * @brief Universal Synchronous Asynchronous Receiver Transmitter diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index fe2909536..b25bad51d 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -37,7 +37,7 @@ #ifndef _HAL_LLD_H_ #define _HAL_LLD_H_ -#include "stm32l1xx.h" +#include "stm32.h" /*===========================================================================*/ /* Driver constants. */ @@ -956,47 +956,6 @@ /* Driver data structures and types. */ /*===========================================================================*/ -/** - * @brief STM32 TIM registers block. - * @note Removed from the ST headers and redefined because the non uniform - * declaration of the CCR registers among the various sub-families. - */ -typedef struct { - volatile uint16_t CR1; - uint16_t _resvd0; - volatile uint16_t CR2; - uint16_t _resvd1; - volatile uint16_t SMCR; - uint16_t _resvd2; - volatile uint16_t DIER; - uint16_t _resvd3; - volatile uint16_t SR; - uint16_t _resvd4; - volatile uint16_t EGR; - uint16_t _resvd5; - volatile uint16_t CCMR1; - uint16_t _resvd6; - volatile uint16_t CCMR2; - uint16_t _resvd7; - volatile uint16_t CCER; - uint16_t _resvd8; - volatile uint32_t CNT; - volatile uint16_t PSC; - uint16_t _resvd9; - volatile uint32_t ARR; - volatile uint16_t RCR; - uint16_t _resvd10; - volatile uint32_t CCR[4]; - volatile uint16_t BDTR; - uint16_t _resvd11; - volatile uint16_t DCR; - uint16_t _resvd12; - volatile uint16_t DMAR; - uint16_t _resvd13; - volatile uint16_t OR; - uint16_t _resvd14; -} TIM_TypeDef; - /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32L1xx/stm32l1xx.h b/os/hal/platforms/STM32L1xx/stm32l1xx.h index 5fadee5db..9c665d29b 100644 --- a/os/hal/platforms/STM32L1xx/stm32l1xx.h +++ b/os/hal/platforms/STM32L1xx/stm32l1xx.h @@ -191,6 +191,7 @@ typedef enum IRQn */ #include "core_cm3.h" +/* CHIBIOS FIX */ /*#include "system_stm32l1xx.h"*/ #include @@ -615,8 +616,6 @@ typedef struct * @brief TIM */ -/* CHIBIOS FIX */ -#if 0 typedef struct { __IO uint16_t CR1; @@ -660,7 +659,6 @@ typedef struct __IO uint16_t OR; uint16_t RESERVED20; } TIM_TypeDef; -#endif /** * @brief Universal Synchronous Asynchronous Receiver Transmitter -- cgit v1.2.3 From 163edb0187652af76781cf88a9929b6bd782fe16 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 26 Nov 2011 13:34:15 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3527 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/GPIOv1/pal_lld.h | 5 + os/hal/platforms/STM32/GPIOv2/pal_lld.h | 26 ++- os/hal/platforms/STM32F4xx/platform.dox | 312 ++++++++++++++++++++++++++++++++ os/hal/platforms/STM32L1xx/platform.dox | 3 - 4 files changed, 335 insertions(+), 11 deletions(-) create mode 100644 os/hal/platforms/STM32F4xx/platform.dox (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/GPIOv1/pal_lld.h b/os/hal/platforms/STM32/GPIOv1/pal_lld.h index c9bb99de7..ab1c273bc 100644 --- a/os/hal/platforms/STM32/GPIOv1/pal_lld.h +++ b/os/hal/platforms/STM32/GPIOv1/pal_lld.h @@ -35,6 +35,10 @@ /* Unsupported modes and specific modes */ /*===========================================================================*/ +/** + * @name STM32-specific I/O mode flags + * @{ + */ /** * @brief STM32 specific alternate push-pull output mode. */ @@ -44,6 +48,7 @@ * @brief STM32 specific alternate open-drain output mode. */ #define PAL_MODE_STM32_ALTERNATE_OPENDRAIN 17 +/** @} */ /*===========================================================================*/ /* I/O Ports Types and constants. */ diff --git a/os/hal/platforms/STM32/GPIOv2/pal_lld.h b/os/hal/platforms/STM32/GPIOv2/pal_lld.h index 60dd84307..ac564e8e3 100644 --- a/os/hal/platforms/STM32/GPIOv2/pal_lld.h +++ b/os/hal/platforms/STM32/GPIOv2/pal_lld.h @@ -44,6 +44,10 @@ #undef PAL_MODE_OUTPUT_PUSHPULL #undef PAL_MODE_OUTPUT_OPENDRAIN +/** + * @name STM32-specific I/O mode flags + * @{ + */ #define PAL_STM32_MODE_MASK (3 << 0) #define PAL_STM32_MODE_INPUT (0 << 0) #define PAL_STM32_MODE_OUTPUT (1 << 0) @@ -68,6 +72,19 @@ #define PAL_STM32_ALTERNATE_MASK (15 << 7) #define PAL_STM32_ALTERNATE(n) ((n) << 7) +/** + * @brief Alternate function. + * + * @param[in] n alternate function selector + */ +#define PAL_MODE_ALTERNATE(n) (PAL_STM32_MODE_ALTERNATE | \ + PAL_STM32_ALTERNATE(n)) +/** @} */ + +/** + * @name Standard I/O mode flags + * @{ + */ /** * @brief This mode is implemented as input. */ @@ -111,14 +128,7 @@ */ #define PAL_MODE_OUTPUT_OPENDRAIN (PAL_STM32_MODE_OUTPUT | \ PAL_STM32_OTYPE_OPENDRAIN) - -/** - * @brief Alternate function. - * - * @param[in] n alternate function selector - */ -#define PAL_MODE_ALTERNATE(n) (PAL_STM32_MODE_ALTERNATE | \ - PAL_STM32_ALTERNATE(n)) +/** @} */ /*===========================================================================*/ /* I/O Ports Types and constants. */ diff --git a/os/hal/platforms/STM32F4xx/platform.dox b/os/hal/platforms/STM32F4xx/platform.dox new file mode 100644 index 000000000..ce59d3d99 --- /dev/null +++ b/os/hal/platforms/STM32F4xx/platform.dox @@ -0,0 +1,312 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 . +*/ + +/** + * @defgroup STM32F4xx_DRIVERS STM32F4xx Drivers + * @details This section describes all the supported drivers on the STM32F4xx + * platform and the implementation details of the single drivers. + * + * @ingroup platforms + */ + +/** + * @defgroup STM32F4xx_HAL STM32F4xx Initialization Support + * @details The STM32F4xx HAL support is responsible for system initialization. + * + * @section stm32f4xx_hal_1 Supported HW resources + * - PLL1. + * - PLL2. + * - RCC. + * - Flash. + * . + * @section stm32f4xx_hal_2 STM32F4xx HAL driver implementation features + * - PLL startup and stabilization. + * - Clock tree initialization. + * - Clock source selection. + * - Flash wait states initialization based on the selected clock options. + * - SYSTICK initialization based on current clock and kernel required rate. + * - DMA support initialization. + * . + * @ingroup STM32F4xx_DRIVERS + */ + +/** + * @defgroup STM32F4xx_ADC STM32F4xx ADC Support + * @details The STM32F4xx ADC driver supports the ADC peripherals using DMA + * channels for maximum performance. + * + * @section stm32f4xx_adc_1 Supported HW resources + * - ADC1. + * - ADC2. + * - ADC3. + * - DMA2. + * . + * @section stm32f4xx_adc_2 STM32F4xx ADC driver implementation features + * - Clock stop for reduced power usage when the driver is in stop state. + * - Streaming conversion using DMA for maximum performance. + * - Programmable ADC interrupt priority level. + * - Programmable DMA bus priority for each DMA channel. + * - Programmable DMA interrupt priority for each DMA channel. + * - DMA and ADC errors detection. + * . + * @ingroup STM32F4xx_DRIVERS + */ + +/** + * @defgroup STM32F4xx_EXT STM32F4xx EXT Support + * @details The STM32F4xx EXT driver uses the EXTI peripheral. + * + * @section stm32f4xx_ext_1 Supported HW resources + * - EXTI. + * . + * @section stm32f4xx_ext_2 STM32F4xx EXT driver implementation features + * - Each EXTI channel can be independently enabled and programmed. + * - Programmable EXTI interrupts priority level. + * - Capability to work as event sources (WFE) rather than interrupt sources. + * . + * @ingroup STM32F4xx_DRIVERS + */ + +/** + * @defgroup STM32F4xx_GPT STM32F4xx GPT Support + * @details The STM32F4xx GPT driver uses the TIMx peripherals. + * + * @section stm32f4xx_gpt_1 Supported HW resources + * - TIM1. + * - TIM2. + * - TIM3. + * - TIM4. + * - TIM5. + * - TIM8. + * . + * @section stm32f4xx_gpt_2 STM32F4xx GPT driver implementation features + * - Each timer can be independently enabled and programmed. Unused + * peripherals are left in low power mode. + * - Programmable TIMx interrupts priority level. + * . + * @ingroup STM32F4xx_DRIVERS + */ + +/** + * @defgroup STM32F4xx_ICU STM32F4xx ICU Support + * @details The STM32F4xx ICU driver uses the TIMx peripherals. + * + * @section stm32f4xx_icu_1 Supported HW resources + * - TIM1. + * - TIM2. + * - TIM3. + * - TIM4. + * - TIM5. + * - TIM8. + * . + * @section stm32f4xx_icu_2 STM32F4xx ICU driver implementation features + * - Each timer can be independently enabled and programmed. Unused + * peripherals are left in low power mode. + * - Programmable TIMx interrupts priority level. + * . + * @ingroup STM32F4xx_DRIVERS + */ + +/** + * @defgroup STM32F4xx_PAL STM32F4xx PAL Support + * @details The STM32F4xx PAL driver uses the GPIO peripherals. + * + * @section stm32f4xx_pal_1 Supported HW resources + * - GPIOA. + * - GPIOB. + * - GPIOC. + * - GPIOD. + * - GPIOE. + * - GPIOF. + * - GPIOG. + * - GPIOH. + * - GPIOI. + * . + * @section stm32f4xx_pal_2 STM32F4xx PAL driver implementation features + * The PAL driver implementation fully supports the following hardware + * capabilities: + * - 16 bits wide ports. + * - Atomic set/reset functions. + * - Atomic set+reset function (atomic bus operations). + * - Output latched regardless of the pad setting. + * - Direct read of input pads regardless of the pad setting. + * . + * @section stm32f4xx_pal_3 Supported PAL setup modes + * The STM32F4xx PAL driver supports the following I/O modes: + * - @p PAL_MODE_RESET. + * - @p PAL_MODE_UNCONNECTED. + * - @p PAL_MODE_INPUT. + * - @p PAL_MODE_INPUT_PULLUP. + * - @p PAL_MODE_INPUT_PULLDOWN. + * - @p PAL_MODE_INPUT_ANALOG. + * - @p PAL_MODE_OUTPUT_PUSHPULL. + * - @p PAL_MODE_OUTPUT_OPENDRAIN. + * - @p PAL_MODE_ALTERNATE (non standard). + * . + * Any attempt to setup an invalid mode is ignored. + * + * @section stm32f4xx_pal_4 Suboptimal behavior + * The STM32F4xx GPIO is less than optimal in several areas, the limitations + * should be taken in account while using the PAL driver: + * - Pad/port toggling operations are not atomic. + * - Pad/group mode setup is not atomic. + * . + * @ingroup STM32F4xx_DRIVERS + */ + +/** + * @defgroup STM32F4xx_PWM STM32F4xx PWM Support + * @details The STM32F4xx PWM driver uses the TIMx peripherals. + * + * @section stm32f4xx_pwm_1 Supported HW resources + * - TIM1. + * - TIM2. + * - TIM3. + * - TIM4. + * - TIM5. + * - TIM8. + * . + * @section stm32f4xx_pwm_2 STM32F4xx PWM driver implementation features + * - Each timer can be independently enabled and programmed. Unused + * peripherals are left in low power mode. + * - Four independent PWM channels per timer. + * - Programmable TIMx interrupts priority level. + * . + * @ingroup STM32F4xx_DRIVERS + */ + +/** + * @defgroup STM32F4xx_SERIAL STM32F4xx Serial Support + * @details The STM32F4xx Serial driver uses the USART/UART peripherals in a + * buffered, interrupt driven, implementation. + * + * @section stm32f4xx_serial_1 Supported HW resources + * The serial driver can support any of the following hardware resources: + * - USART1. + * - USART2. + * - USART3. + * - UART4. + * - UART5. + * - USART6. + * . + * @section stm32f4xx_serial_2 STM32F4xx Serial driver implementation features + * - Clock stop for reduced power usage when the driver is in stop state. + * - Each UART/USART can be independently enabled and programmed. Unused + * peripherals are left in low power mode. + * - Fully interrupt driven. + * - Programmable priority levels for each UART/USART. + * . + * @ingroup STM32F4xx_DRIVERS + */ + +/** + * @defgroup STM32F4xx_SPI STM32F4xx SPI Support + * @details The SPI driver supports the STM32F4xx SPI peripherals using DMA + * channels for maximum performance. + * + * @section stm32f4xx_spi_1 Supported HW resources + * - SPI1. + * - SPI2. + * - SPI3. + * - DMA1. + * - DMA2. + * . + * @section stm32f4xx_spi_2 STM32F4xx SPI driver implementation features + * - Clock stop for reduced power usage when the driver is in stop state. + * - Each SPI can be independently enabled and programmed. Unused + * peripherals are left in low power mode. + * - Programmable interrupt priority levels for each SPI. + * - DMA is used for receiving and transmitting. + * - Programmable DMA bus priority for each DMA channel. + * - Programmable DMA interrupt priority for each DMA channel. + * - Programmable DMA error hook. + * . + * @ingroup STM32F4xx_DRIVERS + */ + +/** + * @defgroup STM32F4xx_UART STM32F4xx UART Support + * @details The UART driver supports the STM32F4xx USART peripherals using DMA + * channels for maximum performance. + * + * @section stm32f4xx_uart_1 Supported HW resources + * The UART driver can support any of the following hardware resources: + * - USART1. + * - USART2. + * - USART3. + * - DMA1. + * - DMA2. + * . + * @section stm32f4xx_uart_2 STM32F4xx UART driver implementation features + * - Clock stop for reduced power usage when the driver is in stop state. + * - Each UART/USART can be independently enabled and programmed. Unused + * peripherals are left in low power mode. + * - Programmable interrupt priority levels for each UART/USART. + * - DMA is used for receiving and transmitting. + * - Programmable DMA bus priority for each DMA channel. + * - Programmable DMA interrupt priority for each DMA channel. + * - Programmable DMA error hook. + * . + * @ingroup STM32F4xx_DRIVERS + */ + +/** + * @defgroup STM32F4xx_PLATFORM_DRIVERS STM32F4xx Platform Drivers + * @details Platform support drivers. Platform drivers do not implement HAL + * standard driver templates, their role is to support platform + * specific functionalities. + * + * @ingroup STM32F4xx_DRIVERS + */ + +/** + * @defgroup STM32F4xx_DMA STM32F4xx DMA Support + * @details This DMA helper driver is used by the other drivers in order to + * access the shared DMA resources in a consistent way. + * + * @section stm32f4xx_dma_1 Supported HW resources + * The DMA driver can support any of the following hardware resources: + * - DMA1. + * - DMA2. + * . + * @section stm32f4xx_dma_2 STM32F4xx DMA driver implementation features + * - Exports helper functions/macros to the other drivers that share the + * DMA resource. + * - Automatic DMA clock stop when not in use by any driver. + * - DMA streams and interrupt vectors sharing among multiple drivers. + * . + * @ingroup STM32F4xx_PLATFORM_DRIVERS + */ + +/** + * @defgroup STM32F4xx_RCC STM32F4xx RCC Support + * @details This RCC helper driver is used by the other drivers in order to + * access the shared RCC resources in a consistent way. + * + * @section stm32f1xx_rcc_1 Supported HW resources + * - RCC. + * . + * @section stm32f4xx_rcc_2 STM32F4xx RCC driver implementation features + * - Peripherals reset. + * - Peripherals clock enable. + * - Periplerals clock disable. + * . + * @ingroup STM32F4xx_PLATFORM_DRIVERS + */ diff --git a/os/hal/platforms/STM32L1xx/platform.dox b/os/hal/platforms/STM32L1xx/platform.dox index 33bf706ab..cd244a2c9 100644 --- a/os/hal/platforms/STM32L1xx/platform.dox +++ b/os/hal/platforms/STM32L1xx/platform.dox @@ -168,7 +168,6 @@ * - TIM2. * - TIM3. * - TIM4. - * - TIM5. * . * @section stm32l1xx_pwm_2 STM32L1xx PWM driver implementation features * - Each timer can be independently enabled and programmed. Unused @@ -237,9 +236,7 @@ * - USART1. * - USART2. * - USART3 (where present). - * - UART4 (where present). * - DMA1. - * - DMA2 (where present). * . * @section stm32l1xx_uart_2 STM32L1xx UART driver implementation features * - Clock stop for reduced power usage when the driver is in stop state. -- cgit v1.2.3 From f00651ed156298a6030bdba8840726344b9e621c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 26 Nov 2011 16:43:55 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3529 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/stm32_dma.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/stm32_dma.h b/os/hal/platforms/STM32F4xx/stm32_dma.h index fe15dbd22..bcadf153c 100644 --- a/os/hal/platforms/STM32F4xx/stm32_dma.h +++ b/os/hal/platforms/STM32F4xx/stm32_dma.h @@ -24,7 +24,7 @@ * @note This file requires definitions from the ST STM32F4xx header file * stm32f4xx.h. * - * @addtogroup STM32_DMA + * @addtogroup STM32F4xx_DMA * @{ */ -- cgit v1.2.3 From b7ad6679241b45526b752259488f908828788bea Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 26 Nov 2011 16:48:13 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3530 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/AT91SAM7/ext_lld.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/AT91SAM7/ext_lld.c b/os/hal/platforms/AT91SAM7/ext_lld.c index 2dbfc1562..bee226ca2 100644 --- a/os/hal/platforms/AT91SAM7/ext_lld.c +++ b/os/hal/platforms/AT91SAM7/ext_lld.c @@ -21,8 +21,8 @@ */ /** - * @file STM32/ext_lld.c - * @brief STM32 EXT subsystem low level driver source. + * @file AT91SAM7/ext_lld.c + * @brief AT91SAM7 EXT subsystem low level driver source. * * @addtogroup EXT * @{ -- cgit v1.2.3 From 64df619cf4d100c7c725873c9e58ce0c4b828209 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 26 Nov 2011 16:54:28 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3531 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/USBv1/usb_lld.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/USBv1/usb_lld.c b/os/hal/platforms/STM32/USBv1/usb_lld.c index 3ecf738da..e61fcadae 100644 --- a/os/hal/platforms/STM32/USBv1/usb_lld.c +++ b/os/hal/platforms/STM32/USBv1/usb_lld.c @@ -658,8 +658,6 @@ void usb_lld_start_out(USBDriver *usbp, usbep_t ep) { * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number - * @param[in] buf buffer where to fetch the endpoint data - * @param[in] n maximum number of bytes to copy * * @notapi */ -- cgit v1.2.3 From 6d11e44877536fd464bf6afd18b35bb17187f480 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 26 Nov 2011 21:26:48 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3533 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/hal_lld.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index a4dd1b775..0650c84f8 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -212,11 +212,11 @@ #define STM32_MCO2PRE_DIV4 (6 << 27) /**< MCO2 divided by 4. */ #define STM32_MCO2PRE_DIV5 (7 << 27) /**< MCO2 divided by 5. */ -#define STM32_MCO2SEL_MASK (3 << 30) /**< MCO2 mask. */ -#define STM32_MCO2SEL_SYSCLK (0 << 30) /**< SYSCLK clock on MCO2 pin. */ -#define STM32_MCO2SEL_PLLI2S (1 << 30) /**< PLLI2S clock on MCO2 pin. */ -#define STM32_MCO2SEL_HSE (2 << 30) /**< HSE clock on MCO2 pin. */ -#define STM32_MCO2SEL_PLL (3 << 30) /**< PLL clock on MCO2 pin. */ +#define STM32_MCO2SEL_MASK (3U << 30) /**< MCO2 mask. */ +#define STM32_MCO2SEL_SYSCLK (0U << 30) /**< SYSCLK clock on MCO2 pin. */ +#define STM32_MCO2SEL_PLLI2S (1U << 30) /**< PLLI2S clock on MCO2 pin. */ +#define STM32_MCO2SEL_HSE (2U << 30) /**< HSE clock on MCO2 pin. */ +#define STM32_MCO2SEL_PLL (3U << 30) /**< PLL clock on MCO2 pin. */ /** * @name RCC_PLLI2SCFGR register bits definitions -- cgit v1.2.3 From e5ce81050f699c61b43aa74384d011c861fb31f2 Mon Sep 17 00:00:00 2001 From: barthess Date: Sun, 27 Nov 2011 19:49:48 +0000 Subject: I2C. Minor fixes. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3540 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/i2c_lld.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index a0914e819..c5cd2308f 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -86,7 +86,7 @@ static volatile uint16_t dbgCR2 = 0; /* Driver local functions. */ /*===========================================================================*/ #if I2C_SUPPORTS_CALLBACKS -#if !(STM32_I2C_I2C1_USE_POLLING_WAIT) +#if (!(STM32_I2C_I2C1_USE_POLLING_WAIT)) && STM32_I2C_USE_I2C1 /* I2C1 GPT callback. */ static void i2c1gptcb(GPTDriver *gptp) { (void)gptp; @@ -120,7 +120,7 @@ static const GPTConfig i2c1gptcfg = { }; #endif /* STM32_I2C_I2C1_USE_POLLING_WAIT */ -#if !(STM32_I2C_I2C2_USE_POLLING_WAIT) +#if (!(STM32_I2C_I2C2_USE_POLLING_WAIT)) && STM32_I2C_USE_I2C2 /* I2C2 GPT callback. */ static void i2c2gptcb(GPTDriver *gptp) { (void)gptp; -- cgit v1.2.3 From 5e18cf994d989b1bed035b98e5957e2c68e518cb Mon Sep 17 00:00:00 2001 From: barthess Date: Sun, 27 Nov 2011 22:18:47 +0000 Subject: I2C. Nop. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3542 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/i2c_lld.c | 5 +++++ os/hal/platforms/STM32F4xx/platform.mk | 1 + 2 files changed, 6 insertions(+) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index c5cd2308f..93b4c4061 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -590,8 +590,13 @@ void i2c_lld_set_clock(I2CDriver *i2cp) { regCR2 = i2cp->id_i2c->CR2; /* Get the I2Cx CR2 value */ regCR2 &= (uint16_t)~I2C_CR2_FREQ; /* Clear frequency FREQ[5:0] bits */ freq = (uint16_t)(STM32_PCLK1 / 1000000); /* Set frequency bits depending on pclk1 value */ +#ifdef STM32F4XX + chDbgCheck((freq >= 2) && (freq <= 42), + "i2c_lld_set_clock() : Peripheral clock freq. out of range"); +#else chDbgCheck((freq >= 2) && (freq <= 36), "i2c_lld_set_clock() : Peripheral clock freq. out of range"); +#endif regCR2 |= freq; i2cp->id_i2c->CR2 = regCR2; diff --git a/os/hal/platforms/STM32F4xx/platform.mk b/os/hal/platforms/STM32F4xx/platform.mk index 7acce0172..449b40731 100644 --- a/os/hal/platforms/STM32F4xx/platform.mk +++ b/os/hal/platforms/STM32F4xx/platform.mk @@ -9,6 +9,7 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F4xx/stm32_dma.c \ ${CHIBIOS}/os/hal/platforms/STM32/serial_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/uart_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/i2c_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c # Required include directories -- cgit v1.2.3 From 41e7ec9ad37a2ff9865411b996a9c0015f820d5f Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 28 Nov 2011 20:34:37 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3543 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/icu_lld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/icu_lld.c b/os/hal/platforms/STM32/icu_lld.c index e76f8a109..dfbcee5e6 100644 --- a/os/hal/platforms/STM32/icu_lld.c +++ b/os/hal/platforms/STM32/icu_lld.c @@ -360,7 +360,7 @@ void icu_lld_start(ICUDriver *icup) { icup->tim->ARR = 0xFFFF; /* CCMR1_CC1S = 01 = CH1 Input on TI1. - CCMR1_CC2S = 10 = CH2 Input on TI2.*/ + CCMR1_CC2S = 10 = CH2 Input on TI1.*/ icup->tim->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_1; /* SMCR_TS = 101, input is TI1FP1. -- cgit v1.2.3 From 1965f6c027c2e4ade1f2005d822009b511f346d9 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 29 Nov 2011 07:53:31 +0000 Subject: Removed unnecessary undefs. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3544 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/stm32.h | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/stm32.h b/os/hal/platforms/STM32/stm32.h index 0ee083dcc..c051dafe0 100644 --- a/os/hal/platforms/STM32/stm32.h +++ b/os/hal/platforms/STM32/stm32.h @@ -63,21 +63,6 @@ #include "stm32l1xx.h" #endif -#undef TIM1 -#undef TIM2 -#undef TIM3 -#undef TIM4 -#undef TIM5 -#undef TIM6 -#undef TIM7 -#undef TIM8 -#undef TIM9 -#undef TIM10 -#undef TIM11 -#undef TIM12 -#undef TIM13 -#undef TIM14 - /*===========================================================================*/ /* Driver constants. */ /*===========================================================================*/ -- cgit v1.2.3 From 2ad41625e0dc9ee78dadba2f2527857f9476e40d Mon Sep 17 00:00:00 2001 From: barthess Date: Thu, 1 Dec 2011 14:32:59 +0000 Subject: I2C. Nop. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3545 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/src/i2c.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'os/hal') diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c index 9ce2cc76f..abd3252cf 100644 --- a/os/hal/src/i2c.c +++ b/os/hal/src/i2c.c @@ -182,6 +182,7 @@ void i2cMasterTransmit(I2CDriver *i2cp, /* init slave config field in driver */ i2cp->id_slave_config = i2cscfg; + // TODO: remove this loop. Do only 1 check because mutual exclusion resolve collisions i2c_lld_wait_bus_free(i2cp); chDbgAssert(!(i2c_lld_bus_is_busy(i2cp)), "i2cMasterReceive(), #1", "time is out"); @@ -224,6 +225,7 @@ void i2cMasterReceive(I2CDriver *i2cp, /* init slave config field in driver */ i2cp->id_slave_config = i2cscfg; + // TODO: remove this loop. Do only 1 check because mutual exclusion resolve collisions i2c_lld_wait_bus_free(i2cp); chDbgAssert(!(i2c_lld_bus_is_busy(i2cp)), "i2cMasterReceive(), #1", "time is out"); -- cgit v1.2.3 From 7463a3f1ffd01344e4da4bb9395f887ab6a1ec3f Mon Sep 17 00:00:00 2001 From: barthess Date: Thu, 1 Dec 2011 18:17:30 +0000 Subject: I2C. Totally broken. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3546 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/i2c_lld.c | 365 ++++----------------------------------- os/hal/platforms/STM32/i2c_lld.h | 3 + 2 files changed, 32 insertions(+), 336 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index 93b4c4061..497975d2d 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -46,9 +46,6 @@ /*===========================================================================*/ /* Driver constants. */ /*===========================================================================*/ -#define I2C_STOP_GPT_TIMEOUT 50 /* waiting timer value */ -#define I2C_START_GPT_TIMEOUT 50 /* waiting timer value */ -#define I2C_POLLING_TIMEOUT 0xFFFF /*===========================================================================*/ /* Driver exported variables. */ @@ -77,324 +74,13 @@ static volatile uint16_t dbgCR2 = 0; #endif /* CH_DBG_ENABLE_ASSERTS */ /* defines for convenience purpose */ -#if I2C_SUPPORTS_CALLBACKS #define txBuffp (i2cp->txbuff_p) #define rxBuffp (i2cp->rxbuff_p) -#endif /* I2C_SUPPORTS_CALLBACKS */ /*===========================================================================*/ /* Driver local functions. */ /*===========================================================================*/ -#if I2C_SUPPORTS_CALLBACKS -#if (!(STM32_I2C_I2C1_USE_POLLING_WAIT)) && STM32_I2C_USE_I2C1 -/* I2C1 GPT callback. */ -static void i2c1gptcb(GPTDriver *gptp) { - (void)gptp; - I2CDriver *i2cp = &I2CD1; - - chSysLockFromIsr(); - i2cp->flags &= ~I2C_FLG_TIMER_ARMED; - - switch(i2cp->id_state){ - case I2C_ACTIVE_TRANSMIT: - i2c_lld_master_transmit(i2cp, i2cp->slave_addr, i2cp->txbuf, i2cp->txbytes, i2cp->rxbuf, i2cp->rxbytes); - break; - - case I2C_ACTIVE_RECEIVE: - i2c_lld_master_receive(i2cp, i2cp->slave_addr, i2cp->rxbuf, i2cp->rxbytes); - break; - - case I2C_ACTIVE_TRANSCEIVE: - i2c_lld_master_transceive(i2cp); - break; - - default: - break; - } - chSysUnlockFromIsr(); -} -/* I2C1 GPT configuration. */ -static const GPTConfig i2c1gptcfg = { - 1000000, /* 1MHz timer clock.*/ - i2c1gptcb /* Timer callback.*/ -}; -#endif /* STM32_I2C_I2C1_USE_POLLING_WAIT */ - -#if (!(STM32_I2C_I2C2_USE_POLLING_WAIT)) && STM32_I2C_USE_I2C2 -/* I2C2 GPT callback. */ -static void i2c2gptcb(GPTDriver *gptp) { - (void)gptp; - I2CDriver *i2cp = &I2CD2; - - chSysLockFromIsr(); - i2cp->flags &= ~I2C_FLG_TIMER_ARMED; - - switch(i2cp->id_state){ - case I2C_ACTIVE_TRANSMIT: - i2c_lld_master_transmit(i2cp, i2cp->slave_addr, i2cp->txbuf, i2cp->txbytes, i2cp->rxbuf, i2cp->rxbytes); - break; - - case I2C_ACTIVE_RECEIVE: - i2c_lld_master_receive(i2cp, i2cp->slave_addr, i2cp->rxbuf, i2cp->rxbytes); - break; - - case I2C_ACTIVE_TRANSCEIVE: - i2c_lld_master_transceive(i2cp); - break; - - default: - break; - } - chSysUnlockFromIsr(); -} -/* I2C2 GPT configuration. */ -static const GPTConfig i2c2gptcfg = { - 1000000, /* 1MHz timer clock.*/ - i2c2gptcb /* Timer callback.*/ -}; -#endif /* STM32_I2C_I2C2_USE_POLLING_WAIT */ -#endif /* I2C_SUPPORTS_CALLBACKS */ - -/** - * @brief Function for I2C debugging purpose. - * @note Internal use only. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * - * @notapi - */ -#if CH_DBG_ENABLE_ASSERTS -void _i2c_unhandled_case(I2CDriver *i2cp){ - dbgCR1 = i2cp->id_i2c->CR1; - dbgCR2 = i2cp->id_i2c->CR2; - chDbgAssert((dbgSR1 + dbgSR2) == 0, - "i2c_serve_event_interrupt(), #1", - "unhandled case"); -} -#else -#define _i2c_unhandled_case(i2cp) -#endif /* CH_DBG_ENABLE_ASSERTS */ - -#if I2C_SUPPORTS_CALLBACKS -/** - * @brief Return the last event value from I2C status registers. - * @note Internal use only. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * - * @notapi - */ -static uint32_t i2c_get_event(I2CDriver *i2cp){ - uint16_t regSR1 = i2cp->id_i2c->SR1; - uint16_t regSR2 = i2cp->id_i2c->SR2; - #if CH_DBG_ENABLE_ASSERTS - dbgSR1 = regSR1; - dbgSR2 = regSR2; - #endif /* CH_DBG_ENABLE_ASSERTS */ - - return (I2C_EV_MASK & (regSR1 | (regSR2 << 16))); -} - -/** - * @brief Handle the flags/interrupts. - * @note Internal use only. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * - * @notapi - */ -void _i2c_ev6_master_rec_mode_selected(I2CDriver *i2cp){ - I2C_TypeDef *dp = i2cp->id_i2c; - - switch(i2cp->flags & EV6_SUBEV_MASK) { - - case I2C_EV6_3_MASTER_REC_1BTR_MODE_SELECTED: /* only an single byte to receive */ - dp->CR1 &= (uint16_t)~I2C_CR1_ACK; /* Clear ACK */ - dp->CR1 |= I2C_CR1_STOP; /* Program the STOP */ - break; - - case I2C_EV6_1_MASTER_REC_2BTR_MODE_SELECTED: /* only two bytes to receive */ - dp->CR1 &= (uint16_t)~I2C_CR1_ACK; /* Clear ACK */ - dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; /* Disable the ITBUF in order to have only the BTF interrupt */ - break; - - default: /* more than 2 bytes to receive */ - break; - } -} - -/** - * @brief Handle cases of 2 or 3 bytes receiving. - * @note Internal use only. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * - * @notapi - */ -void _i2c_ev7_master_rec_byte_qued(I2CDriver *i2cp){ - I2C_TypeDef *dp = i2cp->id_i2c; - - switch(i2cp->flags & EV7_SUBEV_MASK) { - - case I2C_EV7_2_MASTER_REC_3BYTES_TO_PROCESS: - /* Only for case of three bytes to be received. - * DataN-2 and DataN-1 already received. */ - dp->CR1 &= (uint16_t)~I2C_CR1_ACK; /* Clear ACK */ - *rxBuffp = dp->DR; /* Read the DataN-2. This clear the RXE & BFT flags and launch the DataN exception in the shift register (ending the SCL stretch) */ - rxBuffp++; - chSysLockFromIsr(); - dp->CR1 |= I2C_CR1_STOP; /* Program the STOP */ - *rxBuffp = dp->DR; /* Read the DataN-1 */ - chSysUnlockFromIsr(); - rxBuffp++; - i2cp->rxbytes -= 2; /* Decrement the number of readed bytes */ - i2cp->flags = 0; - dp->CR2 |= I2C_CR2_ITBUFEN; /* ready for read DataN. Enable interrupt for next (and last) RxNE event*/ - break; - - case I2C_EV7_3_MASTER_REC_2BYTES_TO_PROCESS: - /* only for case of two bytes to be received - * DataN-1 and DataN are received */ - dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN; - dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; - chSysLockFromIsr(); - dp->CR1 |= I2C_CR1_STOP; /* Program the STOP */ - *rxBuffp = dp->DR; /* Read the DataN-1*/ - rxBuffp++; - *rxBuffp = dp->DR; /* Read the DataN*/ - chSysUnlockFromIsr(); - i2cp->rxbytes = 0; - i2cp->flags = 0; - _i2c_isr_code(i2cp, i2cp->id_slave_config); /* Portable I2C ISR code defined in the high level driver. */ - break; - - case I2C_FLG_MASTER_RECEIVER: - /* Some times in hi load scenarions it is possible to "miss" interrupt - * because STM32 I2C has OR'ed interrupt sources. This case handle that - * scenario. */ - if (i2cp->rxbytes > 3){ - *rxBuffp = dp->DR; - rxBuffp++; - (i2cp->rxbytes)--; - } - else{ - _i2c_unhandled_case(i2cp); - } - break; - - default: - _i2c_unhandled_case(i2cp); - break; - } -} - -/** - * @brief Main I2C interrupt handler. - * @note Internal use only. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * - * @notapi - */ -static void i2c_serve_event_interrupt(I2CDriver *i2cp) { - I2C_TypeDef *dp = i2cp->id_i2c; - switch(i2c_get_event(i2cp)) { - - case I2C_EV5_MASTER_MODE_SELECT: - i2cp->flags &= ~I2C_FLG_HEADER_SENT; - dp->DR = i2cp->slave_addr1; - break; - - case I2C_EV9_MASTER_ADDR_10BIT: - if(i2cp->flags & I2C_FLG_MASTER_RECEIVER) { - i2cp->slave_addr1 |= 0x01; - i2cp->flags |= I2C_FLG_HEADER_SENT; - } - dp->DR = i2cp->slave_addr2; - break; - - /************************************************************************** - * Master Transmitter part - */ - case I2C_EV6_MASTER_TRA_MODE_SELECTED: - if(i2cp->flags & I2C_FLG_HEADER_SENT){ - dp->CR1 |= I2C_CR1_START; /* re-send the start in 10-Bit address mode */ - break; - } - txBuffp = (uint8_t*)i2cp->txbuf; /* Initialize the transmit buffer pointer */ - i2cp->txbytes--; - if(i2cp->txbytes == 0) { /* If no further data to be sent, disable the I2C ITBUF in order to not have a TxE interrupt */ - dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; - } - dp->DR = *txBuffp; /* EV8_1 write the first data */ - txBuffp++; - break; - - case I2C_EV8_MASTER_BYTE_TRANSMITTING: - if(i2cp->txbytes > 0) { - i2cp->txbytes--; - if(i2cp->txbytes == 0) { /* If no further data to be sent, disable the ITBUF in order to not have a TxE interrupt */ - dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; - } - dp->DR = *txBuffp; - txBuffp++; - } - break; - - case I2C_EV8_2_MASTER_BYTE_TRANSMITTED: - dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN; /* Disable ITEVT In order to not have again a BTF IT */ - if (i2cp->rxbytes == 0){ /* if nothing to read then generate stop */ - dp->CR1 |= I2C_CR1_STOP; - _i2c_isr_code(i2cp, i2cp->id_slave_config); /* Portable I2C ISR code defined in the high level driver. */ - } - else{ /* start reading operation */ - i2cp->id_i2c->CR1 |= I2C_CR1_START; /* send start bit */ - i2c_lld_master_transceive(i2cp); - } - break; - - /************************************************************************** - * Master Receiver part - */ - case I2C_EV6_MASTER_REC_MODE_SELECTED: - _i2c_ev6_master_rec_mode_selected(i2cp); - rxBuffp = i2cp->rxbuf; /* Initialize receive buffer pointer */ - break; - - case I2C_EV7_MASTER_REC_BYTE_RECEIVED: - if(i2cp->rxbytes > 3) { - *rxBuffp = dp->DR; /* Read the data register */ - rxBuffp++; - i2cp->rxbytes--; - if(i2cp->rxbytes == 3){ /* Disable the ITBUF in order to have only the BTF interrupt */ - dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; - i2cp->flags |= I2C_FLG_3BTR; - } - } - else if (i2cp->rxbytes == 3){ /* Disable the ITBUF in order to have only the BTF interrupt */ - dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; - i2cp->flags |= I2C_FLG_3BTR; - } - break; - - case I2C_EV7_MASTER_REC_BYTE_QUEUED: - _i2c_ev7_master_rec_byte_qued(i2cp); - break; - - default: /* only 1 byte must to be read to complete trasfer. Stop already sent to bus. */ - chDbgAssert((i2cp->rxbytes) == 1, - "i2c_serve_event_interrupt(), #1", - "more than 1 byte to be received"); - *rxBuffp = dp->DR; /* Read the data register */ - i2cp->rxbytes = 0; - dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN; /* disable interrupts */ - dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; - _i2c_isr_code(i2cp, i2cp->id_slave_config); /* Portable I2C ISR code defined in the high level driver.*/ - break; - } -} -#endif /* I2C_SUPPORTS_CALLBACKS */ static void i2c_serve_error_interrupt(I2CDriver *i2cp) { i2cflags_t flags; @@ -447,28 +133,10 @@ static void i2c_serve_error_interrupt(I2CDriver *i2cp) { #if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__) -/** - * @brief I2C1 event interrupt handler. - */ -#if I2C_SUPPORTS_CALLBACKS -CH_IRQ_HANDLER(VectorBC) { - - CH_IRQ_PROLOGUE(); - i2c_serve_event_interrupt(&I2CD1); - CH_IRQ_EPILOGUE(); -} -#endif /* I2C_SUPPORTS_CALLBACKS */ -/** - * @brief I2C1 error interrupt handler. - */ -CH_IRQ_HANDLER(VectorC0) { - - CH_IRQ_PROLOGUE(); - i2c_serve_error_interrupt(&I2CD1); - CH_IRQ_EPILOGUE(); -} +#error "Unrealized yet" #endif /* STM32_I2C_USE_I2C1 */ + #if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__) /** * @brief I2C2 event interrupt handler. @@ -546,10 +214,10 @@ void i2c_lld_start(I2CDriver *i2cp) { if (&I2CD2 == i2cp) { #if I2C_SUPPORTS_CALLBACKS NVICEnableVector(I2C2_EV_IRQn, - CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); + CORTEX_PRIORITY_MASK(STM32_I2C_I2C2_IRQ_PRIORITY)); #endif /* I2C_SUPPORTS_CALLBACKS */ NVICEnableVector(I2C2_ER_IRQn, - CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); + CORTEX_PRIORITY_MASK(STM32_I2C_I2C2_IRQ_PRIORITY)); rccEnableI2C2(FALSE); } #endif @@ -566,7 +234,9 @@ void i2c_lld_reset(I2CDriver *i2cp){ chDbgCheck((i2cp->id_state == I2C_STOP)||(i2cp->id_state == I2C_READY), "i2c_lld_reset: invalid state"); + /*TODO: Check what interface we must reset */ rccResetI2C1(); + rccResetI2C2(); } @@ -717,6 +387,29 @@ void i2c_lld_stop(I2CDriver *i2cp) { #if I2C_SUPPORTS_CALLBACKS + + +/** + * @brief Transmits data via the I2C bus as master. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] slave_addr Slave device address. Bits 0-9 contain slave + * device address. Bit 15 must be set to 1 if 10-bit + * addressing modes used. Otherwise keep it cleared. + * Bits 10-14 unused. + * @param[in] txbuf pointer to the transmit buffer + * @param[in] txbytes number of bytes to be transmitted + * @param[in] rxbuf pointer to the receive buffer + * @param[in] rxbytes number of bytes to be received + */ +void i2c_lld_master_transmit_dma(I2CDriver *i2cp, uint16_t slave_addr, + uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes) { + +} + + + + /** * @brief Transmits data via the I2C bus as master. * diff --git a/os/hal/platforms/STM32/i2c_lld.h b/os/hal/platforms/STM32/i2c_lld.h index 81a9f62dc..24195147a 100644 --- a/os/hal/platforms/STM32/i2c_lld.h +++ b/os/hal/platforms/STM32/i2c_lld.h @@ -308,6 +308,9 @@ void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr, uint8_t *rxbuf, size_t rxbytes); void i2c_lld_master_transceive(I2CDriver *i2cp); +void i2c_lld_master_transmit_dma(I2CDriver *i2cp, uint16_t slave_addr, + uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes); + #ifdef __cplusplus } #endif -- cgit v1.2.3 From 750f1f4ae6ce75e0cbd8d6923b026376b607ffad Mon Sep 17 00:00:00 2001 From: barthess Date: Thu, 1 Dec 2011 18:21:22 +0000 Subject: I2C. Old driver moved to I2Cv1 dir. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3547 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/I2Cv1/i2c_lld.c | 1100 ++++++++++++++++++++++++++++++++ os/hal/platforms/STM32/I2Cv1/i2c_lld.h | 318 +++++++++ 2 files changed, 1418 insertions(+) create mode 100644 os/hal/platforms/STM32/I2Cv1/i2c_lld.c create mode 100644 os/hal/platforms/STM32/I2Cv1/i2c_lld.h (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/I2Cv1/i2c_lld.c b/os/hal/platforms/STM32/I2Cv1/i2c_lld.c new file mode 100644 index 000000000..93b4c4061 --- /dev/null +++ b/os/hal/platforms/STM32/I2Cv1/i2c_lld.c @@ -0,0 +1,1100 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/i2c_lld.c + * @brief STM32 I2C subsystem low level driver source. Slave mode not implemented. + * @addtogroup I2C + * @{ + */ + +#include "ch.h" +#include "hal.h" +#include "i2c_lld.h" + +#if HAL_USE_I2C || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Datasheet notes. */ +/*===========================================================================*/ +/** + * From RM0008.pdf + * + * Note: + * When the STOP, START or PEC bit is set, the software must NOT perform + * any write access to I2C_CR1 before this bit is cleared by hardware. + * Otherwise there is a risk of setting a second STOP, START or PEC request. + */ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ +#define I2C_STOP_GPT_TIMEOUT 50 /* waiting timer value */ +#define I2C_START_GPT_TIMEOUT 50 /* waiting timer value */ +#define I2C_POLLING_TIMEOUT 0xFFFF + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief I2C1 driver identifier.*/ +#if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__) +I2CDriver I2CD1; +#endif + +/** @brief I2C2 driver identifier.*/ +#if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__) +I2CDriver I2CD2; +#endif + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/* Debugging variables */ +#if CH_DBG_ENABLE_ASSERTS +static volatile uint16_t dbgSR1 = 0; +static volatile uint16_t dbgSR2 = 0; +static volatile uint16_t dbgCR1 = 0; +static volatile uint16_t dbgCR2 = 0; +#endif /* CH_DBG_ENABLE_ASSERTS */ + +/* defines for convenience purpose */ +#if I2C_SUPPORTS_CALLBACKS +#define txBuffp (i2cp->txbuff_p) +#define rxBuffp (i2cp->rxbuff_p) +#endif /* I2C_SUPPORTS_CALLBACKS */ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ +#if I2C_SUPPORTS_CALLBACKS +#if (!(STM32_I2C_I2C1_USE_POLLING_WAIT)) && STM32_I2C_USE_I2C1 +/* I2C1 GPT callback. */ +static void i2c1gptcb(GPTDriver *gptp) { + (void)gptp; + I2CDriver *i2cp = &I2CD1; + + chSysLockFromIsr(); + i2cp->flags &= ~I2C_FLG_TIMER_ARMED; + + switch(i2cp->id_state){ + case I2C_ACTIVE_TRANSMIT: + i2c_lld_master_transmit(i2cp, i2cp->slave_addr, i2cp->txbuf, i2cp->txbytes, i2cp->rxbuf, i2cp->rxbytes); + break; + + case I2C_ACTIVE_RECEIVE: + i2c_lld_master_receive(i2cp, i2cp->slave_addr, i2cp->rxbuf, i2cp->rxbytes); + break; + + case I2C_ACTIVE_TRANSCEIVE: + i2c_lld_master_transceive(i2cp); + break; + + default: + break; + } + chSysUnlockFromIsr(); +} +/* I2C1 GPT configuration. */ +static const GPTConfig i2c1gptcfg = { + 1000000, /* 1MHz timer clock.*/ + i2c1gptcb /* Timer callback.*/ +}; +#endif /* STM32_I2C_I2C1_USE_POLLING_WAIT */ + +#if (!(STM32_I2C_I2C2_USE_POLLING_WAIT)) && STM32_I2C_USE_I2C2 +/* I2C2 GPT callback. */ +static void i2c2gptcb(GPTDriver *gptp) { + (void)gptp; + I2CDriver *i2cp = &I2CD2; + + chSysLockFromIsr(); + i2cp->flags &= ~I2C_FLG_TIMER_ARMED; + + switch(i2cp->id_state){ + case I2C_ACTIVE_TRANSMIT: + i2c_lld_master_transmit(i2cp, i2cp->slave_addr, i2cp->txbuf, i2cp->txbytes, i2cp->rxbuf, i2cp->rxbytes); + break; + + case I2C_ACTIVE_RECEIVE: + i2c_lld_master_receive(i2cp, i2cp->slave_addr, i2cp->rxbuf, i2cp->rxbytes); + break; + + case I2C_ACTIVE_TRANSCEIVE: + i2c_lld_master_transceive(i2cp); + break; + + default: + break; + } + chSysUnlockFromIsr(); +} +/* I2C2 GPT configuration. */ +static const GPTConfig i2c2gptcfg = { + 1000000, /* 1MHz timer clock.*/ + i2c2gptcb /* Timer callback.*/ +}; +#endif /* STM32_I2C_I2C2_USE_POLLING_WAIT */ +#endif /* I2C_SUPPORTS_CALLBACKS */ + +/** + * @brief Function for I2C debugging purpose. + * @note Internal use only. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * + * @notapi + */ +#if CH_DBG_ENABLE_ASSERTS +void _i2c_unhandled_case(I2CDriver *i2cp){ + dbgCR1 = i2cp->id_i2c->CR1; + dbgCR2 = i2cp->id_i2c->CR2; + chDbgAssert((dbgSR1 + dbgSR2) == 0, + "i2c_serve_event_interrupt(), #1", + "unhandled case"); +} +#else +#define _i2c_unhandled_case(i2cp) +#endif /* CH_DBG_ENABLE_ASSERTS */ + +#if I2C_SUPPORTS_CALLBACKS +/** + * @brief Return the last event value from I2C status registers. + * @note Internal use only. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * + * @notapi + */ +static uint32_t i2c_get_event(I2CDriver *i2cp){ + uint16_t regSR1 = i2cp->id_i2c->SR1; + uint16_t regSR2 = i2cp->id_i2c->SR2; + #if CH_DBG_ENABLE_ASSERTS + dbgSR1 = regSR1; + dbgSR2 = regSR2; + #endif /* CH_DBG_ENABLE_ASSERTS */ + + return (I2C_EV_MASK & (regSR1 | (regSR2 << 16))); +} + +/** + * @brief Handle the flags/interrupts. + * @note Internal use only. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * + * @notapi + */ +void _i2c_ev6_master_rec_mode_selected(I2CDriver *i2cp){ + I2C_TypeDef *dp = i2cp->id_i2c; + + switch(i2cp->flags & EV6_SUBEV_MASK) { + + case I2C_EV6_3_MASTER_REC_1BTR_MODE_SELECTED: /* only an single byte to receive */ + dp->CR1 &= (uint16_t)~I2C_CR1_ACK; /* Clear ACK */ + dp->CR1 |= I2C_CR1_STOP; /* Program the STOP */ + break; + + case I2C_EV6_1_MASTER_REC_2BTR_MODE_SELECTED: /* only two bytes to receive */ + dp->CR1 &= (uint16_t)~I2C_CR1_ACK; /* Clear ACK */ + dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; /* Disable the ITBUF in order to have only the BTF interrupt */ + break; + + default: /* more than 2 bytes to receive */ + break; + } +} + +/** + * @brief Handle cases of 2 or 3 bytes receiving. + * @note Internal use only. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * + * @notapi + */ +void _i2c_ev7_master_rec_byte_qued(I2CDriver *i2cp){ + I2C_TypeDef *dp = i2cp->id_i2c; + + switch(i2cp->flags & EV7_SUBEV_MASK) { + + case I2C_EV7_2_MASTER_REC_3BYTES_TO_PROCESS: + /* Only for case of three bytes to be received. + * DataN-2 and DataN-1 already received. */ + dp->CR1 &= (uint16_t)~I2C_CR1_ACK; /* Clear ACK */ + *rxBuffp = dp->DR; /* Read the DataN-2. This clear the RXE & BFT flags and launch the DataN exception in the shift register (ending the SCL stretch) */ + rxBuffp++; + chSysLockFromIsr(); + dp->CR1 |= I2C_CR1_STOP; /* Program the STOP */ + *rxBuffp = dp->DR; /* Read the DataN-1 */ + chSysUnlockFromIsr(); + rxBuffp++; + i2cp->rxbytes -= 2; /* Decrement the number of readed bytes */ + i2cp->flags = 0; + dp->CR2 |= I2C_CR2_ITBUFEN; /* ready for read DataN. Enable interrupt for next (and last) RxNE event*/ + break; + + case I2C_EV7_3_MASTER_REC_2BYTES_TO_PROCESS: + /* only for case of two bytes to be received + * DataN-1 and DataN are received */ + dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN; + dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; + chSysLockFromIsr(); + dp->CR1 |= I2C_CR1_STOP; /* Program the STOP */ + *rxBuffp = dp->DR; /* Read the DataN-1*/ + rxBuffp++; + *rxBuffp = dp->DR; /* Read the DataN*/ + chSysUnlockFromIsr(); + i2cp->rxbytes = 0; + i2cp->flags = 0; + _i2c_isr_code(i2cp, i2cp->id_slave_config); /* Portable I2C ISR code defined in the high level driver. */ + break; + + case I2C_FLG_MASTER_RECEIVER: + /* Some times in hi load scenarions it is possible to "miss" interrupt + * because STM32 I2C has OR'ed interrupt sources. This case handle that + * scenario. */ + if (i2cp->rxbytes > 3){ + *rxBuffp = dp->DR; + rxBuffp++; + (i2cp->rxbytes)--; + } + else{ + _i2c_unhandled_case(i2cp); + } + break; + + default: + _i2c_unhandled_case(i2cp); + break; + } +} + +/** + * @brief Main I2C interrupt handler. + * @note Internal use only. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * + * @notapi + */ +static void i2c_serve_event_interrupt(I2CDriver *i2cp) { + I2C_TypeDef *dp = i2cp->id_i2c; + + switch(i2c_get_event(i2cp)) { + + case I2C_EV5_MASTER_MODE_SELECT: + i2cp->flags &= ~I2C_FLG_HEADER_SENT; + dp->DR = i2cp->slave_addr1; + break; + + case I2C_EV9_MASTER_ADDR_10BIT: + if(i2cp->flags & I2C_FLG_MASTER_RECEIVER) { + i2cp->slave_addr1 |= 0x01; + i2cp->flags |= I2C_FLG_HEADER_SENT; + } + dp->DR = i2cp->slave_addr2; + break; + + /************************************************************************** + * Master Transmitter part + */ + case I2C_EV6_MASTER_TRA_MODE_SELECTED: + if(i2cp->flags & I2C_FLG_HEADER_SENT){ + dp->CR1 |= I2C_CR1_START; /* re-send the start in 10-Bit address mode */ + break; + } + txBuffp = (uint8_t*)i2cp->txbuf; /* Initialize the transmit buffer pointer */ + i2cp->txbytes--; + if(i2cp->txbytes == 0) { /* If no further data to be sent, disable the I2C ITBUF in order to not have a TxE interrupt */ + dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; + } + dp->DR = *txBuffp; /* EV8_1 write the first data */ + txBuffp++; + break; + + case I2C_EV8_MASTER_BYTE_TRANSMITTING: + if(i2cp->txbytes > 0) { + i2cp->txbytes--; + if(i2cp->txbytes == 0) { /* If no further data to be sent, disable the ITBUF in order to not have a TxE interrupt */ + dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; + } + dp->DR = *txBuffp; + txBuffp++; + } + break; + + case I2C_EV8_2_MASTER_BYTE_TRANSMITTED: + dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN; /* Disable ITEVT In order to not have again a BTF IT */ + if (i2cp->rxbytes == 0){ /* if nothing to read then generate stop */ + dp->CR1 |= I2C_CR1_STOP; + _i2c_isr_code(i2cp, i2cp->id_slave_config); /* Portable I2C ISR code defined in the high level driver. */ + } + else{ /* start reading operation */ + i2cp->id_i2c->CR1 |= I2C_CR1_START; /* send start bit */ + i2c_lld_master_transceive(i2cp); + } + break; + + /************************************************************************** + * Master Receiver part + */ + case I2C_EV6_MASTER_REC_MODE_SELECTED: + _i2c_ev6_master_rec_mode_selected(i2cp); + rxBuffp = i2cp->rxbuf; /* Initialize receive buffer pointer */ + break; + + case I2C_EV7_MASTER_REC_BYTE_RECEIVED: + if(i2cp->rxbytes > 3) { + *rxBuffp = dp->DR; /* Read the data register */ + rxBuffp++; + i2cp->rxbytes--; + if(i2cp->rxbytes == 3){ /* Disable the ITBUF in order to have only the BTF interrupt */ + dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; + i2cp->flags |= I2C_FLG_3BTR; + } + } + else if (i2cp->rxbytes == 3){ /* Disable the ITBUF in order to have only the BTF interrupt */ + dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; + i2cp->flags |= I2C_FLG_3BTR; + } + break; + + case I2C_EV7_MASTER_REC_BYTE_QUEUED: + _i2c_ev7_master_rec_byte_qued(i2cp); + break; + + default: /* only 1 byte must to be read to complete trasfer. Stop already sent to bus. */ + chDbgAssert((i2cp->rxbytes) == 1, + "i2c_serve_event_interrupt(), #1", + "more than 1 byte to be received"); + *rxBuffp = dp->DR; /* Read the data register */ + i2cp->rxbytes = 0; + dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN; /* disable interrupts */ + dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; + _i2c_isr_code(i2cp, i2cp->id_slave_config); /* Portable I2C ISR code defined in the high level driver.*/ + break; + } +} +#endif /* I2C_SUPPORTS_CALLBACKS */ + +static void i2c_serve_error_interrupt(I2CDriver *i2cp) { + i2cflags_t flags; + I2C_TypeDef *reg; + + reg = i2cp->id_i2c; + flags = I2CD_NO_ERROR; + + if(reg->SR1 & I2C_SR1_BERR) { /* Bus error */ + reg->SR1 &= ~I2C_SR1_BERR; + flags |= I2CD_BUS_ERROR; + } + if(reg->SR1 & I2C_SR1_ARLO) { /* Arbitration lost */ + reg->SR1 &= ~I2C_SR1_ARLO; + flags |= I2CD_ARBITRATION_LOST; + } + if(reg->SR1 & I2C_SR1_AF) { /* Acknowledge fail */ + reg->SR1 &= ~I2C_SR1_AF; + reg->CR1 |= I2C_CR1_STOP; /* setting stop bit */ + while(i2cp->id_i2c->CR1 & I2C_CR1_STOP) + ; + flags |= I2CD_ACK_FAILURE; + } + if(reg->SR1 & I2C_SR1_OVR) { /* Overrun */ + reg->SR1 &= ~I2C_SR1_OVR; + flags |= I2CD_OVERRUN; + } + if(reg->SR1 & I2C_SR1_PECERR) { /* PEC error */ + reg->SR1 &= ~I2C_SR1_PECERR; + flags |= I2CD_PEC_ERROR; + } + if(reg->SR1 & I2C_SR1_TIMEOUT) { /* SMBus Timeout */ + reg->SR1 &= ~I2C_SR1_TIMEOUT; + flags |= I2CD_TIMEOUT; + } + if(reg->SR1 & I2C_SR1_SMBALERT) { /* SMBus alert */ + reg->SR1 &= ~I2C_SR1_SMBALERT; + flags |= I2CD_SMB_ALERT; + } + + if(flags != I2CD_NO_ERROR) { /* send communication end signal */ + chSysLockFromIsr(); + i2cAddFlagsI(i2cp, flags); + chSysUnlockFromIsr(); + #if I2C_SUPPORTS_CALLBACKS + _i2c_isr_err_code(i2cp, i2cp->id_slave_config); + #endif /* I2C_SUPPORTS_CALLBACKS */ + } +} + + +#if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__) +/** + * @brief I2C1 event interrupt handler. + */ +#if I2C_SUPPORTS_CALLBACKS +CH_IRQ_HANDLER(VectorBC) { + + CH_IRQ_PROLOGUE(); + i2c_serve_event_interrupt(&I2CD1); + CH_IRQ_EPILOGUE(); +} +#endif /* I2C_SUPPORTS_CALLBACKS */ +/** + * @brief I2C1 error interrupt handler. + */ +CH_IRQ_HANDLER(VectorC0) { + + CH_IRQ_PROLOGUE(); + i2c_serve_error_interrupt(&I2CD1); + CH_IRQ_EPILOGUE(); +} +#endif /* STM32_I2C_USE_I2C1 */ + +#if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__) +/** + * @brief I2C2 event interrupt handler. + */ +#if I2C_SUPPORTS_CALLBACKS +CH_IRQ_HANDLER(VectorC4) { + + CH_IRQ_PROLOGUE(); + i2c_serve_event_interrupt(&I2CD2); + CH_IRQ_EPILOGUE(); +} +#endif /* I2C_SUPPORTS_CALLBACKS */ +/** + * @brief I2C2 error interrupt handler. + */ +CH_IRQ_HANDLER(VectorC8) { + + CH_IRQ_PROLOGUE(); + i2c_serve_error_interrupt(&I2CD2); + CH_IRQ_EPILOGUE(); +} +#endif /* STM32_I2C_USE_I2C2 */ + +/** + * @brief Low level I2C driver initialization. + */ +void i2c_lld_init(void) { + +#if STM32_I2C_USE_I2C1 + i2cObjectInit(&I2CD1); + I2CD1.id_i2c = I2C1; + +#if I2C_SUPPORTS_CALLBACKS +#if !(STM32_I2C_I2C1_USE_POLLING_WAIT) + I2CD1.timer = &(STM32_I2C_I2C1_USE_GPT_TIM); + I2CD1.timer_cfg = &i2c1gptcfg; +#endif /* !(STM32_I2C_I2C1_USE_POLLING_WAIT) */ +#endif /* I2C_SUPPORTS_CALLBACKS */ + +#endif /* STM32_I2C_USE_I2C */ + +#if STM32_I2C_USE_I2C2 + i2cObjectInit(&I2CD2); + I2CD2.id_i2c = I2C2; + +#if I2C_SUPPORTS_CALLBACKS +#if !(STM32_I2C_I2C2_USE_POLLING_WAIT) + I2CD2.timer = &(STM32_I2C_I2C2_USE_GPT_TIM); + I2CD2.timer_cfg = &i2c2gptcfg; +#endif /* !(STM32_I2C_I2C2_USE_POLLING_WAIT) */ +#endif /* I2C_SUPPORTS_CALLBACKS */ + +#endif /* STM32_I2C_USE_I2C2 */ +} + +/** + * @brief Configures and activates the I2C peripheral. + * + * @param[in] i2cp pointer to the @p I2CDriver object + */ +void i2c_lld_start(I2CDriver *i2cp) { + if (i2cp->id_state == I2C_STOP) { /* If in stopped state then enables the I2C clock.*/ +#if STM32_I2C_USE_I2C1 + if (&I2CD1 == i2cp) { +#if I2C_SUPPORTS_CALLBACKS + NVICEnableVector(I2C1_EV_IRQn, + CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); +#endif /* I2C_SUPPORTS_CALLBACKS */ + NVICEnableVector(I2C1_ER_IRQn, + CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); + rccEnableI2C1(FALSE); + } +#endif +#if STM32_I2C_USE_I2C2 + if (&I2CD2 == i2cp) { +#if I2C_SUPPORTS_CALLBACKS + NVICEnableVector(I2C2_EV_IRQn, + CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); +#endif /* I2C_SUPPORTS_CALLBACKS */ + NVICEnableVector(I2C2_ER_IRQn, + CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); + rccEnableI2C2(FALSE); + } +#endif + } + + i2cp->id_i2c->CR1 = I2C_CR1_SWRST; /* reset i2c peripherial */ + i2cp->id_i2c->CR1 = 0; + i2c_lld_set_clock(i2cp); + i2c_lld_set_opmode(i2cp); + i2cp->id_i2c->CR1 |= 1; /* enable interface */ +} + +void i2c_lld_reset(I2CDriver *i2cp){ + chDbgCheck((i2cp->id_state == I2C_STOP)||(i2cp->id_state == I2C_READY), + "i2c_lld_reset: invalid state"); + + rccResetI2C1(); +} + + +/** + * @brief Set clock speed. + * + * @param[in] i2cp pointer to the @p I2CDriver object + */ +void i2c_lld_set_clock(I2CDriver *i2cp) { + volatile uint16_t regCCR, regCR2, freq, clock_div; + volatile uint16_t pe_bit_saved; + int32_t clock_speed = i2cp->id_config->clock_speed; + i2cdutycycle_t duty = i2cp->id_config->duty_cycle; + + chDbgCheck((i2cp != NULL) && (clock_speed > 0) && (clock_speed <= 4000000), + "i2c_lld_set_clock"); + + /************************************************************************** + * CR2 Configuration + */ + regCR2 = i2cp->id_i2c->CR2; /* Get the I2Cx CR2 value */ + regCR2 &= (uint16_t)~I2C_CR2_FREQ; /* Clear frequency FREQ[5:0] bits */ + freq = (uint16_t)(STM32_PCLK1 / 1000000); /* Set frequency bits depending on pclk1 value */ +#ifdef STM32F4XX + chDbgCheck((freq >= 2) && (freq <= 42), + "i2c_lld_set_clock() : Peripheral clock freq. out of range"); +#else + chDbgCheck((freq >= 2) && (freq <= 36), + "i2c_lld_set_clock() : Peripheral clock freq. out of range"); +#endif + regCR2 |= freq; + i2cp->id_i2c->CR2 = regCR2; + + /************************************************************************** + * CCR Configuration + */ + pe_bit_saved = (i2cp->id_i2c->CR1 & I2C_CR1_PE); + i2cp->id_i2c->CR1 &= (uint16_t)~I2C_CR1_PE; /* Disable the selected I2C peripheral to configure TRISE */ + regCCR = 0; /* Clear F/S, DUTY and CCR[11:0] bits */ + clock_div = I2C_CCR_CCR; + + if (clock_speed <= 100000) { /* Configure clock_div in standard mode */ + chDbgAssert(duty == STD_DUTY_CYCLE, + "i2c_lld_set_clock(), #1", + "Invalid standard mode duty cycle"); + clock_div = (uint16_t)(STM32_PCLK1 / (clock_speed * 2)); /* Standard mode clock_div calculate: Tlow/Thigh = 1/1 */ + if (clock_div < 0x04) clock_div = 0x04; /* Test if CCR value is under 0x4, and set the minimum allowed value */ + regCCR |= (clock_div & I2C_CCR_CCR); /* Set clock_div value for standard mode */ + i2cp->id_i2c->TRISE = freq + 1; /* Set Maximum Rise Time for standard mode */ + } + else if(clock_speed <= 400000) { /* Configure clock_div in fast mode */ + chDbgAssert((duty == FAST_DUTY_CYCLE_2) || + (duty == FAST_DUTY_CYCLE_16_9), + "i2c_lld_set_clock(), #2", + "Invalid fast mode duty cycle"); + if(duty == FAST_DUTY_CYCLE_2) { + clock_div = (uint16_t)(STM32_PCLK1 / (clock_speed * 3)); /* Fast mode clock_div calculate: Tlow/Thigh = 2/1 */ + } + else if(duty == FAST_DUTY_CYCLE_16_9) { + clock_div = (uint16_t)(STM32_PCLK1 / (clock_speed * 25)); /* Fast mode clock_div calculate: Tlow/Thigh = 16/9 */ + regCCR |= I2C_CCR_DUTY; /* Set DUTY bit */ + } + if(clock_div < 0x01) clock_div = 0x01; /* Test if CCR value is under 0x1, and set the minimum allowed value */ + regCCR |= (I2C_CCR_FS | (clock_div & I2C_CCR_CCR)); /* Set clock_div value and F/S bit for fast mode*/ + i2cp->id_i2c->TRISE = (freq * 300 / 1000) + 1; /* Set Maximum Rise Time for fast mode */ + } + chDbgAssert((clock_div <= I2C_CCR_CCR), + "i2c_lld_set_clock(), #3", "Too low clock clock speed selected"); + + i2cp->id_i2c->CCR = regCCR; /* Write to I2Cx CCR */ + i2cp->id_i2c->CR1 |= pe_bit_saved; /* restore the I2C peripheral enabled state */ +} + +/** + * @brief Set operation mode of I2C hardware. + * + * @param[in] i2cp pointer to the @p I2CDriver object + */ +void i2c_lld_set_opmode(I2CDriver *i2cp) { + i2copmode_t opmode = i2cp->id_config->op_mode; + uint16_t regCR1; + + regCR1 = i2cp->id_i2c->CR1; /* Get the I2Cx CR1 value */ + switch(opmode){ + case OPMODE_I2C: + regCR1 &= (uint16_t)~(I2C_CR1_SMBUS|I2C_CR1_SMBTYPE); + break; + case OPMODE_SMBUS_DEVICE: + regCR1 |= I2C_CR1_SMBUS; + regCR1 &= (uint16_t)~(I2C_CR1_SMBTYPE); + break; + case OPMODE_SMBUS_HOST: + regCR1 |= (I2C_CR1_SMBUS|I2C_CR1_SMBTYPE); + break; + } + + i2cp->id_i2c->CR1 = regCR1; /* Write to I2Cx CR1 */ +} + +/** + * @brief Set own address. + * + * @param[in] i2cp pointer to the @p I2CDriver object + */ +void i2c_lld_set_own_address(I2CDriver *i2cp) { + /* TODO: dual address mode */ + + i2cp->id_i2c->OAR1 |= 1 << 14; + + if (&(i2cp->id_config->own_addr_10) == NULL){ /* only 7-bit address */ + i2cp->id_i2c->OAR1 &= (~I2C_OAR1_ADDMODE); + i2cp->id_i2c->OAR1 |= i2cp->id_config->own_addr_7 << 1; + } + else { + chDbgAssert((i2cp->id_config->own_addr_10 < 1024), + "i2c_lld_set_own_address(), #1", "10-bit address longer then 10 bit") + i2cp->id_i2c->OAR1 |= I2C_OAR1_ADDMODE; + i2cp->id_i2c->OAR1 |= i2cp->id_config->own_addr_10; + } +} + + +/** + * @brief Deactivates the I2C peripheral. + * + * @param[in] i2cp pointer to the @p I2CDriver object + */ +void i2c_lld_stop(I2CDriver *i2cp) { + if (i2cp->id_state == I2C_READY) { /* If in ready state then disables the I2C clock.*/ +#if STM32_I2C_USE_I2C1 + if (&I2CD1 == i2cp) { + NVICDisableVector(I2C1_EV_IRQn); + NVICDisableVector(I2C1_ER_IRQn); + rccDisableI2C1(FALSE); + } +#endif +#if STM32_I2C_USE_I2C2 + if (&I2CD2 == i2cp) { + NVICDisableVector(I2C2_EV_IRQn); + NVICDisableVector(I2C2_ER_IRQn); + rccDisableI2C2(FALSE); + } +#endif + } + + i2cp->id_state = I2C_STOP; +} + + +#if I2C_SUPPORTS_CALLBACKS +/** + * @brief Transmits data via the I2C bus as master. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] slave_addr Slave device address. Bits 0-9 contain slave + * device address. Bit 15 must be set to 1 if 10-bit + * addressing modes used. Otherwise keep it cleared. + * Bits 10-14 unused. + * @param[in] txbuf pointer to the transmit buffer + * @param[in] txbytes number of bytes to be transmitted + * @param[in] rxbuf pointer to the receive buffer + * @param[in] rxbytes number of bytes to be received + */ +void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr, + uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes) { + + /* "waiting" for STOP bit routine*/ + #if STM32_I2C_I2C1_USE_POLLING_WAIT + uint32_t timeout = I2C_POLLING_TIMEOUT; + while((i2cp->id_i2c->CR1 & I2C_CR1_STOP) && timeout) + timeout--; + chDbgAssert((timeout > 0), "i2c_lld_master_transmit(), #1", "time to STOP is out"); + #else + chDbgAssert(!(i2cp->flags & I2C_FLG_TIMER_ARMED), "i2c_lld_master_transmit(), #1", "time to STOP is out"); + if ((i2cp->id_i2c->CR1 & I2C_CR1_STOP) && i2cp->timer != NULL && i2cp->timer_cfg != NULL){ + chSysLockFromIsr(); + gptStartOneShotI(i2cp->timer, I2C_STOP_GPT_TIMEOUT); + i2cp->flags |= I2C_FLG_TIMER_ARMED; + chSysUnlockFromIsr(); + return; + } + #endif /* STM32_I2C_I2C1_USE_POLLING_WAIT */ + + /* init driver fields */ + i2cp->slave_addr = slave_addr; + i2cp->txbytes = txbytes; + i2cp->rxbytes = rxbytes; + i2cp->txbuf = txbuf; + i2cp->rxbuf = rxbuf; + + /* init address fields */ + if(slave_addr & 0x8000){ /* 10-bit mode used */ + i2cp->slave_addr1 = ((slave_addr >>7) & 0x0006); /* add the two msb of 10-bit address to the header */ + i2cp->slave_addr1 |= 0xF0; /* add the header bits with LSB = 0 -> write */ + i2cp->slave_addr2 = slave_addr & 0x00FF; /* the remaining 8 bit of 10-bit address */ + } + else{ + i2cp->slave_addr1 = ((slave_addr <<1) & 0x00FE); /* LSB = 0 -> write */ + } + + /* setting flags and register bits */ + i2cp->flags = 0; + i2cp->errors = 0; + i2cp->id_i2c->CR1 &= ~I2C_CR1_POS; + i2cp->id_i2c->CR1 |= I2C_CR1_START; + i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN); /* enable ERR, EVT & BUF ITs */ +} + +/** + * @brief Receives data from the I2C bus. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] slave_addr Slave device address. Bits 0-9 contain slave + * device address. Bit 15 must be set to 1 if 10-bit + * addressing modes used. Otherwise keep it cleared. + * Bits 10-14 unused. + * @param[in] rxbuf pointer to the receive buffer + * @param[in] rxbytes number of bytes to be received + */ +void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr, + uint8_t *rxbuf, size_t rxbytes){ + + chDbgAssert((i2cp->id_i2c->SR1 + i2cp->id_i2c->SR2) == 0, + "i2c_lld_master_receive(), #1", + "some interrupt sources not clear"); + + /* "waiting" for STOP bit routine*/ + #if STM32_I2C_I2C1_USE_POLLING_WAIT + uint32_t timeout = I2C_POLLING_TIMEOUT; + while((i2cp->id_i2c->CR1 & I2C_CR1_STOP) && timeout) + timeout--; + chDbgAssert((timeout > 0), "i2c_lld_master_receive(), #1", "time to STOP is out"); + #else + chDbgAssert(!(i2cp->flags & I2C_FLG_TIMER_ARMED), "i2c_lld_master_receive(), #1", "time to STOP is out"); + if ((i2cp->id_i2c->CR1 & I2C_CR1_STOP) && i2cp->timer != NULL && i2cp->timer_cfg != NULL){ + chSysLockFromIsr(); + gptStartOneShotI(i2cp->timer, I2C_STOP_GPT_TIMEOUT); + i2cp->flags |= I2C_FLG_TIMER_ARMED; + chSysUnlockFromIsr(); + return; + } + #endif /* STM32_I2C_I2C1_USE_POLLING_WAIT */ + + /* init driver fields */ + i2cp->slave_addr = slave_addr; + i2cp->rxbytes = rxbytes; + i2cp->rxbuf = rxbuf; + + /* init address fields */ + if(slave_addr & 0x8000){ /* 10-bit mode used */ + i2cp->slave_addr1 = ((slave_addr >>7) & 0x0006); /* add the two msb of 10-bit address to the header */ + i2cp->slave_addr1 |= 0xF0; /* add the header bits (the LSB -> 1 will be add to second */ + i2cp->slave_addr2 = slave_addr & 0x00FF; /* the remaining 8 bit of 10-bit address */ + } + else{ + i2cp->slave_addr1 = ((slave_addr <<1) | 0x01); /* LSB = 1 -> receive */ + } + + /* setting flags and register bits */ + i2cp->flags |= I2C_FLG_MASTER_RECEIVER; + i2cp->errors = 0; + + i2cp->id_i2c->CR1 |= I2C_CR1_ACK; /* acknowledge returned */ + i2cp->id_i2c->CR1 &= ~I2C_CR1_POS; + + if(i2cp->rxbytes == 1) { /* Only one byte to be received */ + i2cp->flags |= I2C_FLG_1BTR; + } + else if(i2cp->rxbytes == 2) { /* Only two bytes to be received */ + i2cp->flags |= I2C_FLG_2BTR; + i2cp->id_i2c->CR1 |= I2C_CR1_POS; /* Acknowledge Position */ + } + + i2cp->id_i2c->CR1 |= I2C_CR1_START; /* send start bit */ + i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN); /* enable ERR, EVT & BUF ITs */ +} + + +/** + * @brief Realize read-though-write behavior. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * + * @notapi + */ +void i2c_lld_master_transceive(I2CDriver *i2cp){ + + chDbgAssert((i2cp != NULL) && (i2cp->slave_addr1 != 0) &&\ + (i2cp->rxbytes > 0) && (i2cp->rxbuf != NULL), + "i2c_lld_master_transceive(), #1", + ""); + + i2cp->id_state = I2C_ACTIVE_TRANSCEIVE; + + /* "waiting" for START bit routine*/ + #if STM32_I2C_I2C1_USE_POLLING_WAIT + uint32_t timeout = I2C_POLLING_TIMEOUT; + while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout); + timeout--; + chDbgAssert((timeout > 0), "i2c_lld_master_transceive(), #1", "time to START is out"); + #else + chDbgAssert(!(i2cp->flags & I2C_FLG_TIMER_ARMED), "i2c_lld_master_transceive(), #1", "time to START is out"); + if ((i2cp->id_i2c->CR1 & I2C_CR1_START) && i2cp->timer != NULL && i2cp->timer_cfg != NULL){ + chSysLockFromIsr(); + gptStartOneShotI(i2cp->timer, I2C_START_GPT_TIMEOUT); + i2cp->flags |= I2C_FLG_TIMER_ARMED; + chSysUnlockFromIsr(); + return; + } + #endif /* STM32_I2C_I2C1_USE_POLLING_WAIT */ + + /* init address fields */ + if(i2cp->slave_addr & 0x8000){ /* 10-bit mode used */ + i2cp->slave_addr1 = ((i2cp->slave_addr >>7) & 0x0006);/* add the two msb of 10-bit address to the header */ + i2cp->slave_addr1 |= 0xF0; /* add the header bits (the LSB -> 1 will be add to second */ + i2cp->slave_addr2 = i2cp->slave_addr & 0x00FF; /* the remaining 8 bit of 10-bit address */ + } + else{ + i2cp->slave_addr1 |= 0x01; + } + + /* setting flags and register bits */ + i2cp->flags |= I2C_FLG_MASTER_RECEIVER; + i2cp->errors = 0; + i2cp->id_i2c->CR1 |= I2C_CR1_ACK; /* acknowledge returned */ + i2cp->id_i2c->CR1 &= ~I2C_CR1_POS; + + if(i2cp->rxbytes == 1) { /* Only one byte to be received */ + i2cp->flags |= I2C_FLG_1BTR; + } + else if(i2cp->rxbytes == 2) { /* Only two bytes to be received */ + i2cp->flags |= I2C_FLG_2BTR; + i2cp->id_i2c->CR1 |= I2C_CR1_POS; /* Acknowledge Position */ + } + + i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN); /* enable ERR, EVT & BUF ITs */ +} + +#else /*I2C_SUPPORTS_CALLBACKS*/ + +/** + * @brief Synchronously transmits data via the I2C bus as master. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] slave_addr Slave device address. Bits 0-9 contain slave + * device address. Bit 15 must be set to 1 if 10-bit + * addressing modes used. Otherwise keep it cleared. + * Bits 10-14 unused. + * @param[in] txbuf pointer to the transmit buffer + * @param[in] txbytes number of bytes to be transmitted + * @param[in] rxbuf pointer to the receive buffer + * @param[in] rxbytes number of bytes to be received + */ +void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr, + uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes) { + + /* init driver fields */ + i2cp->slave_addr = slave_addr; + i2cp->txbytes = txbytes; + i2cp->rxbytes = rxbytes; + i2cp->txbuf = txbuf; + i2cp->rxbuf = rxbuf; + + /* init address fields */ + if(slave_addr & 0x8000){ /* 10-bit mode used */ + i2cp->slave_addr1 = ((slave_addr >>7) & 0x0006); /* add the two msb of 10-bit address to the header */ + i2cp->slave_addr1 |= 0xF0; /* add the header bits with LSB = 0 -> write */ + i2cp->slave_addr2 = slave_addr & 0x00FF; /* the remaining 8 bit of 10-bit address */ + } + else{ + i2cp->slave_addr1 = ((slave_addr <<1) & 0x00FE); /* LSB = 0 -> write */ + } + + i2cp->flags = 0; + i2cp->errors = 0; + i2cp->id_i2c->CR1 &= ~I2C_CR1_POS; + i2cp->id_i2c->CR2 &= ~I2C_CR2_ITEVTEN; /* disable event interrupts */ + i2cp->id_i2c->CR2 |= I2C_CR2_ITERREN; /* enable error interrupts */ + + i2cp->id_i2c->CR1 |= I2C_CR1_START; + while (!(i2cp->id_i2c->SR1 & I2C_SR1_SB)) + ; + i2cp->id_i2c->DR = i2cp->slave_addr1; + while (!(i2cp->id_i2c->SR1 & I2C_SR1_ADDR)) + ; + while (!(i2cp->id_i2c->SR2 & I2C_SR2_BUSY)) + ; + i2cp->id_i2c->DR = *txbuf; + txbuf++; + i2cp->txbytes--; + while(i2cp->txbytes > 0){ + while(!(i2cp->id_i2c->SR1 & I2C_SR1_BTF)) + ; + i2cp->id_i2c->DR = *txbuf; + txbuf++; + i2cp->txbytes--; + } + while(!(i2cp->id_i2c->SR1 & I2C_SR1_BTF)) + ; + if(rxbytes == 0){ + i2cp->id_i2c->CR1 |= I2C_CR1_STOP; + while (i2cp->id_i2c->CR1 & I2C_CR1_STOP) + ; + } + else{ + i2c_lld_master_receive(i2cp, slave_addr, rxbuf, rxbytes); + } +} + + +/** + * @brief Synchronously receives data from the I2C bus. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] slave_addr Slave device address. Bits 0-9 contain slave + * device address. Bit 15 must be set to 1 if 10-bit + * addressing modes used. Otherwise keep it cleared. + * Bits 10-14 unused. + * @param[in] rxbuf pointer to the receive buffer + * @param[in] rxbytes number of bytes to be received + */ +void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr, + uint8_t *rxbuf, size_t rxbytes){ + + /* init driver fields */ + i2cp->slave_addr = slave_addr; + i2cp->rxbytes = rxbytes; + i2cp->rxbuf = rxbuf; + + /* init address fields */ + if(slave_addr & 0x8000){ /* 10-bit mode used */ + i2cp->slave_addr1 = ((slave_addr >>7) & 0x0006); /* add the two msb of 10-bit address to the header */ + i2cp->slave_addr1 |= 0xF0; /* add the header bits (the LSB -> 1 will be add to second */ + i2cp->slave_addr2 = slave_addr & 0x00FF; /* the remaining 8 bit of 10-bit address */ + } + else{ + i2cp->slave_addr1 = ((slave_addr <<1) | 0x01); /* LSB = 1 -> receive */ + } + + + /* setting flags and register bits */ + i2cp->flags = 0; + i2cp->errors = 0; + i2cp->id_i2c->CR1 &= ~I2C_CR1_POS; + i2cp->id_i2c->CR2 &= ~I2C_CR2_ITEVTEN; /* disable event interrupts */ + i2cp->id_i2c->CR2 |= I2C_CR2_ITERREN; /* enable error interrupts */ + + i2cp->id_i2c->CR1 |= I2C_CR1_START; + while (!(i2cp->id_i2c->SR1 & I2C_SR1_SB)) + ; + + i2cp->id_i2c->DR = i2cp->slave_addr1; + while (!(i2cp->id_i2c->SR1 & I2C_SR1_ADDR)) + ; + + if(i2cp->rxbytes >= 3){ /* more than 2 bytes receiving procedure */ + while(!(i2cp->id_i2c->SR2 & I2C_SR2_BUSY)) /* to clear ADDR bit */ + ; + while(i2cp->rxbytes > 3){ + while(!(i2cp->id_i2c->SR1 & I2C_SR1_BTF)) + ; + *rxbuf = i2cp->id_i2c->DR; + rxbuf++; + i2cp->rxbytes--; + } + while(!(i2cp->id_i2c->SR1 & I2C_SR1_BTF)) /* stopping procedure */ + ; + i2cp->id_i2c->CR1 &= ~I2C_CR1_ACK; + chSysLock(); + i2cp->id_i2c->CR1 |= I2C_CR1_STOP; + *rxbuf = i2cp->id_i2c->DR; + rxbuf++; + i2cp->rxbytes--; + chSysUnlock(); + while(!(i2cp->id_i2c->SR1 & I2C_SR1_RXNE)) + ; + *rxbuf = i2cp->id_i2c->DR; + rxbuf++; + i2cp->rxbytes--; + while (i2cp->id_i2c->CR1 & I2C_CR1_STOP) + ; + i2cp->id_i2c->CR1 |= I2C_CR1_ACK; + } + else{ /* 1 or 2 bytes receiving procedure */ + if(i2cp->rxbytes == 2){ + i2cp->id_i2c->CR1 |= I2C_CR1_POS; + chSysLock(); + while(!(i2cp->id_i2c->SR2 & I2C_SR2_BUSY)) /* to clear ADDR bit */ + ; + i2cp->id_i2c->CR1 &= ~I2C_CR1_ACK; + chSysUnlock(); + while(!(i2cp->id_i2c->SR1 & I2C_SR1_BTF)) + ; + chSysLock(); + i2cp->id_i2c->CR1 |= I2C_CR1_STOP; + *rxbuf = i2cp->id_i2c->DR; + rxbuf++; + i2cp->rxbytes--; + chSysUnlock(); + *rxbuf = i2cp->id_i2c->DR; + rxbuf++; + i2cp->rxbytes--; + while (i2cp->id_i2c->CR1 & I2C_CR1_STOP) + ; + i2cp->id_i2c->CR1 &= ~I2C_CR1_POS; + i2cp->id_i2c->CR1 |= I2C_CR1_ACK; + } + else{ /* 1 byte */ + i2cp->id_i2c->CR1 &= ~I2C_CR1_ACK; + chSysLock(); + while(!(i2cp->id_i2c->SR2 & I2C_SR2_BUSY)) /* to clear ADDR bit */ + ; + i2cp->id_i2c->CR1 |= I2C_CR1_STOP; + chSysUnlock(); + while(!(i2cp->id_i2c->SR1 & I2C_SR1_RXNE)) + ; + *rxbuf = i2cp->id_i2c->DR; + rxbuf++; + i2cp->rxbytes--; + while (i2cp->id_i2c->CR1 & I2C_CR1_STOP) + ; + i2cp->id_i2c->CR1 |= I2C_CR1_ACK; + } + } +} +#endif /* I2C_SUPPORTS_CALLBACKS */ + +#undef rxBuffp +#undef txBuffp + +#endif /* HAL_USE_I2C */ diff --git a/os/hal/platforms/STM32/I2Cv1/i2c_lld.h b/os/hal/platforms/STM32/I2Cv1/i2c_lld.h new file mode 100644 index 000000000..81a9f62dc --- /dev/null +++ b/os/hal/platforms/STM32/I2Cv1/i2c_lld.h @@ -0,0 +1,318 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 STM32/i2c_lld.h + * @brief STM32 I2C subsystem low level driver header. + * @addtogroup I2C + * @{ + */ + +#ifndef _I2C_LLD_H_ +#define _I2C_LLD_H_ + +#if HAL_USE_I2C || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Switch between callback based and synchronouse driver. + * @note The default is synchronouse. + */ +#if !defined(I2C_SUPPORTS_CALLBACKS) || defined(__DOXYGEN__) +#define I2C_SUPPORTS_CALLBACKS TRUE +#endif + +/** + * @brief I2C1 driver synchronization choice between GPT and polling. + * @note The default is polling wait. + */ +#if !defined(STM32_I2C_I2C1_USE_GPT_TIM) || \ + !defined(STM32_I2C_I2C1_USE_POLLING_WAIT) || \ + defined(__DOXYGEN__) +#define STM32_I2C_I2C1_USE_POLLING_WAIT TRUE +#endif + +/** + * @brief I2C2 driver synchronization choice between GPT and polling. + * @note The default is polling wait. + */ +#if !defined(STM32_I2C_I2C2_USE_GPT_TIM) || \ + !defined(STM32_I2C_I2C2_USE_POLLING_WAIT) || \ + defined(__DOXYGEN__) +#define STM32_I2C_I2C2_USE_POLLING_WAIT TRUE +#endif + +/** + * @brief I2C1 driver enable switch. + * @details If set to @p TRUE the support for I2C1 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_I2C_USE_I2C1) || defined(__DOXYGEN__) +#define STM32_I2C_USE_I2C1 TRUE +#endif + +/** + * @brief I2C2 driver enable switch. + * @details If set to @p TRUE the support for I2C2 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_I2C_USE_I2C2) || defined(__DOXYGEN__) +#define STM32_I2C_USE_I2C2 TRUE +#endif + +/** + * @brief I2C1 interrupt priority level setting. + * @note @p BASEPRI_KERNEL >= @p STM32_I2C_I2C1_IRQ_PRIORITY > @p PRIORITY_PENDSV. + */ +#if !defined(STM32_I2C_I2C1_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_I2C_I2C1_IRQ_PRIORITY 0xA0 +#endif + +/** + * @brief I2C2 interrupt priority level setting. + * @note @p BASEPRI_KERNEL >= @p STM32_I2C_I2C2_IRQ_PRIORITY > @p PRIORITY_PENDSV. + */ +#if !defined(STM32_I2C_I2C2_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_I2C_I2C2_IRQ_PRIORITY 0xA0 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/** @brief EV5 */ +#define I2C_EV5_MASTER_MODE_SELECT ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_SB)) /* BUSY, MSL and SB flag */ +/** @brief EV6 */ +#define I2C_EV6_MASTER_TRA_MODE_SELECTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY|I2C_SR2_TRA)<< 16)|I2C_SR1_ADDR|I2C_SR1_TXE)) /* BUSY, MSL, ADDR, TXE and TRA flags */ +#define I2C_EV6_MASTER_REC_MODE_SELECTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_ADDR)) /* BUSY, MSL and ADDR flags */ +/** @brief EV7 */ +#define I2C_EV7_MASTER_REC_BYTE_RECEIVED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_RXNE)) /* BUSY, MSL and RXNE flags */ +#define I2C_EV7_MASTER_REC_BYTE_QUEUED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_BTF|I2C_SR1_RXNE)) /* BUSY, MSL, RXNE and BTF flags*/ +/** @brief EV8 */ +#define I2C_EV8_MASTER_BYTE_TRANSMITTING ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY|I2C_SR2_TRA)<< 16)|I2C_SR1_TXE)) /* TRA, BUSY, MSL, TXE flags */ +/** @brief EV8_2 */ +#define I2C_EV8_2_MASTER_BYTE_TRANSMITTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY|I2C_SR2_TRA)<< 16)|I2C_SR1_BTF|I2C_SR1_TXE)) /* TRA, BUSY, MSL, TXE and BTF flags */ +/** @brief EV9 */ +#define I2C_EV9_MASTER_ADDR_10BIT ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_ADD10)) /* BUSY, MSL and ADD10 flags */ +#define I2C_EV_MASK 0x00FFFFFF /* First byte zeroed because there is no need of PEC register part from SR2 */ + +#define I2C_FLG_1BTR 0x01 /* Single byte to be received and processed */ +#define I2C_FLG_2BTR 0x02 /* Two bytes to be received and processed */ +#define I2C_FLG_3BTR 0x04 /* Last three received bytes to be processed */ +#define I2C_FLG_MASTER_RECEIVER 0x10 +#define I2C_FLG_HEADER_SENT 0x80 +#define I2C_FLG_TIMER_ARMED 0x40 /* Used to check locks on the bus */ + +#define EV6_SUBEV_MASK (I2C_FLG_1BTR|I2C_FLG_2BTR|I2C_FLG_MASTER_RECEIVER) +#define EV7_SUBEV_MASK (I2C_FLG_2BTR|I2C_FLG_3BTR|I2C_FLG_MASTER_RECEIVER) + +#define I2C_EV6_1_MASTER_REC_2BTR_MODE_SELECTED (I2C_FLG_2BTR|I2C_FLG_MASTER_RECEIVER) +#define I2C_EV6_3_MASTER_REC_1BTR_MODE_SELECTED (I2C_FLG_1BTR|I2C_FLG_MASTER_RECEIVER) +#define I2C_EV7_2_MASTER_REC_3BYTES_TO_PROCESS (I2C_FLG_3BTR|I2C_FLG_MASTER_RECEIVER) +#define I2C_EV7_3_MASTER_REC_2BYTES_TO_PROCESS (I2C_FLG_2BTR|I2C_FLG_MASTER_RECEIVER) + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief I2C Driver condition flags type. + */ +typedef uint32_t i2cflags_t; + +typedef enum { + OPMODE_I2C = 1, + OPMODE_SMBUS_DEVICE = 2, + OPMODE_SMBUS_HOST = 3, +} i2copmode_t; + +typedef enum { + STD_DUTY_CYCLE = 1, + FAST_DUTY_CYCLE_2 = 2, + FAST_DUTY_CYCLE_16_9 = 3, +} i2cdutycycle_t; + +/** + * @brief Driver configuration structure. + */ +typedef struct { + i2copmode_t op_mode; /**< @brief Specifies the I2C mode.*/ + uint32_t clock_speed; /**< @brief Specifies the clock frequency. Must be set to a value lower than 400kHz */ + i2cdutycycle_t duty_cycle; /**< @brief Specifies the I2C fast mode duty cycle */ + uint8_t own_addr_7; /**< @brief Specifies the first device 7-bit own address. */ + uint16_t own_addr_10; /**< @brief Specifies the second part of device own address in 10-bit mode. Set to NULL if not used. */ + uint8_t nbit_own_addr; /**< @brief Specifies if 7-bit or 10-bit address is acknowledged */ +} I2CConfig; + + +/** + * @brief Type of a structure representing an I2C driver. + */ +typedef struct I2CDriver I2CDriver; + +/** + * @brief Type of a structure representing an I2C slave config. + */ +typedef struct I2CSlaveConfig I2CSlaveConfig; + +/** + * @brief Structure representing an I2C driver. + */ +struct I2CDriver{ + /** + * @brief Driver state. + */ + i2cstate_t id_state; + +#if I2C_USE_WAIT + /** + * @brief Thread waiting for I/O completion. + */ + Thread *id_thread; +#endif /* I2C_USE_WAIT */ +#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) +#if CH_USE_MUTEXES || defined(__DOXYGEN__) + /** + * @brief Mutex protecting the bus. + */ + Mutex id_mutex; +#elif CH_USE_SEMAPHORES + Semaphore id_semaphore; +#endif +#endif /* I2C_USE_MUTUAL_EXCLUSION */ + + /** + * @brief Current configuration data. + */ + const I2CConfig *id_config; + /** + * @brief Current slave configuration data. + */ + const I2CSlaveConfig *id_slave_config; + + __IO size_t txbytes; /*!< @brief Number of bytes to be transmitted. */ + __IO size_t rxbytes; /*!< @brief Number of bytes to be received. */ + uint8_t *rxbuf; /*!< @brief Pointer to receive buffer. */ + uint8_t *txbuf; /*!< @brief Pointer to transmit buffer.*/ + uint8_t *rxbuff_p; /*!< @brief Pointer to the current byte in slave rx buffer. */ + uint8_t *txbuff_p; /*!< @brief Pointer to the current byte in slave tx buffer. */ + + __IO i2cflags_t errors; /*!< @brief Error flags.*/ + __IO i2cflags_t flags; /*!< @brief State flags.*/ + + uint16_t slave_addr; /*!< @brief Current slave address. */ + uint8_t slave_addr1;/*!< @brief 7-bit address of the slave with r\w bit.*/ + uint8_t slave_addr2;/*!< @brief Uses in 10-bit address mode. */ + +#if CH_USE_EVENTS + EventSource sevent; /*!< @brief Status Change @p EventSource.*/ +#endif + + /*********** End of the mandatory fields. **********************************/ + + /** + * @brief Pointer to the I2Cx registers block. + */ + I2C_TypeDef *id_i2c; + +#if !(STM32_I2C_I2C1_USE_POLLING_WAIT) + /* TODO: capability to switch this GPT fields off */ + /** + * @brief Timer for waiting STOP condition on the bus. + * @details This is workaround for STM32 buggy I2C cell. + */ + GPTDriver *timer; + + /** + * @brief Config for workaround timer. + */ + const GPTConfig *timer_cfg; +#endif /* !(STM32_I2C_I2C1_USE_POLLING_WAIT) */ +}; + + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +#define i2c_lld_bus_is_busy(i2cp) \ + (i2cp->id_i2c->SR2 & I2C_SR2_BUSY) + + +/* Wait until BUSY flag is reset: a STOP has been generated on the bus + * signaling the end of transmission. Normally this wait function + * does not block thread, only if slave not response it does. + */ +#define i2c_lld_wait_bus_free(i2cp) { \ + uint32_t tmo = 0xfffff; \ + while((i2cp->id_i2c->SR2 & I2C_SR2_BUSY) && tmo--) \ + ; \ +} + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/** @cond never*/ +#if STM32_I2C_USE_I2C1 +extern I2CDriver I2CD1; +#endif + +#if STM32_I2C_USE_I2C2 +extern I2CDriver I2CD2; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +void i2c_lld_init(void); +void i2c_lld_reset(I2CDriver *i2cp); +void i2c_lld_set_clock(I2CDriver *i2cp); +void i2c_lld_set_opmode(I2CDriver *i2cp); +void i2c_lld_set_own_address(I2CDriver *i2cp); +void i2c_lld_start(I2CDriver *i2cp); +void i2c_lld_stop(I2CDriver *i2cp); +void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr, + uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes); +void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr, + uint8_t *rxbuf, size_t rxbytes); +void i2c_lld_master_transceive(I2CDriver *i2cp); + +#ifdef __cplusplus +} +#endif +/** @endcond*/ + +#endif /* CH_HAL_USE_I2C */ + +#endif /* _I2C_LLD_H_ */ -- cgit v1.2.3 From 62608271adb730505a4a3d0a9ef49ef2efe91552 Mon Sep 17 00:00:00 2001 From: barthess Date: Thu, 1 Dec 2011 20:17:58 +0000 Subject: I2C. Code compiles but does not work. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3548 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/i2c_lld.c | 472 +++++---------------------------------- os/hal/platforms/STM32/i2c_lld.h | 53 +---- os/hal/src/i2c.c | 8 - 3 files changed, 68 insertions(+), 465 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index 497975d2d..ccec33dbc 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -82,6 +82,12 @@ static volatile uint16_t dbgCR2 = 0; /*===========================================================================*/ +static void i2c_serve_event_interrupt(I2CDriver *i2cp) { + +} + + + static void i2c_serve_error_interrupt(I2CDriver *i2cp) { i2cflags_t flags; I2C_TypeDef *reg; @@ -132,63 +138,54 @@ static void i2c_serve_error_interrupt(I2CDriver *i2cp) { } +static void i2c_lld_serve_rx_end_irq(UARTDriver *i2cp, uint32_t flags) { + +} + +static void i2c_lld_serve_tx_end_irq(UARTDriver *i2cp, uint32_t flags) { + +} + + + #if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__) #error "Unrealized yet" #endif /* STM32_I2C_USE_I2C1 */ - #if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__) /** * @brief I2C2 event interrupt handler. */ -#if I2C_SUPPORTS_CALLBACKS -CH_IRQ_HANDLER(VectorC4) { - +CH_IRQ_HANDLER(I2C2_EV_IRQHandler) { CH_IRQ_PROLOGUE(); i2c_serve_event_interrupt(&I2CD2); CH_IRQ_EPILOGUE(); } -#endif /* I2C_SUPPORTS_CALLBACKS */ /** * @brief I2C2 error interrupt handler. */ -CH_IRQ_HANDLER(VectorC8) { - +CH_IRQ_HANDLER(I2C2_ER_IRQHandler) { CH_IRQ_PROLOGUE(); i2c_serve_error_interrupt(&I2CD2); CH_IRQ_EPILOGUE(); } #endif /* STM32_I2C_USE_I2C2 */ + /** * @brief Low level I2C driver initialization. */ void i2c_lld_init(void) { #if STM32_I2C_USE_I2C1 - i2cObjectInit(&I2CD1); - I2CD1.id_i2c = I2C1; - -#if I2C_SUPPORTS_CALLBACKS -#if !(STM32_I2C_I2C1_USE_POLLING_WAIT) - I2CD1.timer = &(STM32_I2C_I2C1_USE_GPT_TIM); - I2CD1.timer_cfg = &i2c1gptcfg; -#endif /* !(STM32_I2C_I2C1_USE_POLLING_WAIT) */ -#endif /* I2C_SUPPORTS_CALLBACKS */ - +#error "Unrealized yet" #endif /* STM32_I2C_USE_I2C */ #if STM32_I2C_USE_I2C2 i2cObjectInit(&I2CD2); - I2CD2.id_i2c = I2C2; - -#if I2C_SUPPORTS_CALLBACKS -#if !(STM32_I2C_I2C2_USE_POLLING_WAIT) - I2CD2.timer = &(STM32_I2C_I2C2_USE_GPT_TIM); - I2CD2.timer_cfg = &i2c2gptcfg; -#endif /* !(STM32_I2C_I2C2_USE_POLLING_WAIT) */ -#endif /* I2C_SUPPORTS_CALLBACKS */ - + I2CD2.id_i2c = I2C2; + I2CD2.dmarx = STM32_DMA_STREAM(STM32_I2C_I2C2_RX_DMA_STREAM); + I2CD2.dmatx = STM32_DMA_STREAM(STM32_I2C_I2C2_TX_DMA_STREAM); #endif /* STM32_I2C_USE_I2C2 */ } @@ -198,30 +195,49 @@ void i2c_lld_init(void) { * @param[in] i2cp pointer to the @p I2CDriver object */ void i2c_lld_start(I2CDriver *i2cp) { + i2cp->dmamode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; + if (i2cp->id_state == I2C_STOP) { /* If in stopped state then enables the I2C clock.*/ #if STM32_I2C_USE_I2C1 - if (&I2CD1 == i2cp) { -#if I2C_SUPPORTS_CALLBACKS - NVICEnableVector(I2C1_EV_IRQn, - CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); -#endif /* I2C_SUPPORTS_CALLBACKS */ - NVICEnableVector(I2C1_ER_IRQn, - CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); - rccEnableI2C1(FALSE); - } +// if (&I2CD1 == i2cp) { +// NVICEnableVector(I2C1_EV_IRQn, +// CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); +// NVICEnableVector(I2C1_ER_IRQn, +// CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); +// rccEnableI2C1(FALSE); +// } +#error "Unrealized yet" #endif + #if STM32_I2C_USE_I2C2 if (&I2CD2 == i2cp) { -#if I2C_SUPPORTS_CALLBACKS + + bool_t b; + b = dmaStreamAllocate(i2cp->dmarx, + STM32_I2C_I2C2_IRQ_PRIORITY, + (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, + (void *)i2cp); + chDbgAssert(!b, "uart_lld_start(), #3", "stream already allocated"); + b = dmaStreamAllocate(i2cp->dmatx, + STM32_I2C_I2C2_IRQ_PRIORITY, + (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, + (void *)i2cp); + chDbgAssert(!b, "uart_lld_start(), #4", "stream already allocated"); + rccEnableI2C2(FALSE); NVICEnableVector(I2C2_EV_IRQn, CORTEX_PRIORITY_MASK(STM32_I2C_I2C2_IRQ_PRIORITY)); -#endif /* I2C_SUPPORTS_CALLBACKS */ NVICEnableVector(I2C2_ER_IRQn, CORTEX_PRIORITY_MASK(STM32_I2C_I2C2_IRQ_PRIORITY)); - rccEnableI2C2(FALSE); + + //i2cp->dmamode |= STM32_DMA_CR_CHSEL(USART2_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_UART_USART2_DMA_PRIORITY); + // TODO: remove hardcoded "7" + i2cp->dmamode |= STM32_DMA_CR_CHSEL(7) | STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY); } -#endif +#endif /* STM32_I2C_USE_I2C2 */ } + i2cp->dmamode |= STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE; + dmaStreamSetPeripheral(i2cp->dmarx, &i2cp->id_i2c->DR); + dmaStreamSetPeripheral(i2cp->dmatx, &i2cp->id_i2c->DR); i2cp->id_i2c->CR1 = I2C_CR1_SWRST; /* reset i2c peripherial */ i2cp->id_i2c->CR1 = 0; @@ -230,6 +246,9 @@ void i2c_lld_start(I2CDriver *i2cp) { i2cp->id_i2c->CR1 |= 1; /* enable interface */ } + + + void i2c_lld_reset(I2CDriver *i2cp){ chDbgCheck((i2cp->id_state == I2C_STOP)||(i2cp->id_state == I2C_READY), "i2c_lld_reset: invalid state"); @@ -386,9 +405,6 @@ void i2c_lld_stop(I2CDriver *i2cp) { } -#if I2C_SUPPORTS_CALLBACKS - - /** * @brief Transmits data via the I2C bus as master. * @@ -402,390 +418,18 @@ void i2c_lld_stop(I2CDriver *i2cp) { * @param[in] rxbuf pointer to the receive buffer * @param[in] rxbytes number of bytes to be received */ -void i2c_lld_master_transmit_dma(I2CDriver *i2cp, uint16_t slave_addr, - uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes) { - -} - - - - -/** - * @brief Transmits data via the I2C bus as master. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * @param[in] slave_addr Slave device address. Bits 0-9 contain slave - * device address. Bit 15 must be set to 1 if 10-bit - * addressing modes used. Otherwise keep it cleared. - * Bits 10-14 unused. - * @param[in] txbuf pointer to the transmit buffer - * @param[in] txbytes number of bytes to be transmitted - * @param[in] rxbuf pointer to the receive buffer - * @param[in] rxbytes number of bytes to be received - */ void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr, uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes) { - /* "waiting" for STOP bit routine*/ - #if STM32_I2C_I2C1_USE_POLLING_WAIT - uint32_t timeout = I2C_POLLING_TIMEOUT; - while((i2cp->id_i2c->CR1 & I2C_CR1_STOP) && timeout) - timeout--; - chDbgAssert((timeout > 0), "i2c_lld_master_transmit(), #1", "time to STOP is out"); - #else - chDbgAssert(!(i2cp->flags & I2C_FLG_TIMER_ARMED), "i2c_lld_master_transmit(), #1", "time to STOP is out"); - if ((i2cp->id_i2c->CR1 & I2C_CR1_STOP) && i2cp->timer != NULL && i2cp->timer_cfg != NULL){ - chSysLockFromIsr(); - gptStartOneShotI(i2cp->timer, I2C_STOP_GPT_TIMEOUT); - i2cp->flags |= I2C_FLG_TIMER_ARMED; - chSysUnlockFromIsr(); - return; - } - #endif /* STM32_I2C_I2C1_USE_POLLING_WAIT */ - - /* init driver fields */ - i2cp->slave_addr = slave_addr; - i2cp->txbytes = txbytes; - i2cp->rxbytes = rxbytes; - i2cp->txbuf = txbuf; - i2cp->rxbuf = rxbuf; - - /* init address fields */ - if(slave_addr & 0x8000){ /* 10-bit mode used */ - i2cp->slave_addr1 = ((slave_addr >>7) & 0x0006); /* add the two msb of 10-bit address to the header */ - i2cp->slave_addr1 |= 0xF0; /* add the header bits with LSB = 0 -> write */ - i2cp->slave_addr2 = slave_addr & 0x00FF; /* the remaining 8 bit of 10-bit address */ - } - else{ - i2cp->slave_addr1 = ((slave_addr <<1) & 0x00FE); /* LSB = 0 -> write */ - } - - /* setting flags and register bits */ - i2cp->flags = 0; - i2cp->errors = 0; - i2cp->id_i2c->CR1 &= ~I2C_CR1_POS; - i2cp->id_i2c->CR1 |= I2C_CR1_START; - i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN); /* enable ERR, EVT & BUF ITs */ } -/** - * @brief Receives data from the I2C bus. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * @param[in] slave_addr Slave device address. Bits 0-9 contain slave - * device address. Bit 15 must be set to 1 if 10-bit - * addressing modes used. Otherwise keep it cleared. - * Bits 10-14 unused. - * @param[in] rxbuf pointer to the receive buffer - * @param[in] rxbytes number of bytes to be received - */ void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr, uint8_t *rxbuf, size_t rxbytes){ - - chDbgAssert((i2cp->id_i2c->SR1 + i2cp->id_i2c->SR2) == 0, - "i2c_lld_master_receive(), #1", - "some interrupt sources not clear"); - - /* "waiting" for STOP bit routine*/ - #if STM32_I2C_I2C1_USE_POLLING_WAIT - uint32_t timeout = I2C_POLLING_TIMEOUT; - while((i2cp->id_i2c->CR1 & I2C_CR1_STOP) && timeout) - timeout--; - chDbgAssert((timeout > 0), "i2c_lld_master_receive(), #1", "time to STOP is out"); - #else - chDbgAssert(!(i2cp->flags & I2C_FLG_TIMER_ARMED), "i2c_lld_master_receive(), #1", "time to STOP is out"); - if ((i2cp->id_i2c->CR1 & I2C_CR1_STOP) && i2cp->timer != NULL && i2cp->timer_cfg != NULL){ - chSysLockFromIsr(); - gptStartOneShotI(i2cp->timer, I2C_STOP_GPT_TIMEOUT); - i2cp->flags |= I2C_FLG_TIMER_ARMED; - chSysUnlockFromIsr(); - return; - } - #endif /* STM32_I2C_I2C1_USE_POLLING_WAIT */ - - /* init driver fields */ - i2cp->slave_addr = slave_addr; - i2cp->rxbytes = rxbytes; - i2cp->rxbuf = rxbuf; - - /* init address fields */ - if(slave_addr & 0x8000){ /* 10-bit mode used */ - i2cp->slave_addr1 = ((slave_addr >>7) & 0x0006); /* add the two msb of 10-bit address to the header */ - i2cp->slave_addr1 |= 0xF0; /* add the header bits (the LSB -> 1 will be add to second */ - i2cp->slave_addr2 = slave_addr & 0x00FF; /* the remaining 8 bit of 10-bit address */ - } - else{ - i2cp->slave_addr1 = ((slave_addr <<1) | 0x01); /* LSB = 1 -> receive */ - } - - /* setting flags and register bits */ - i2cp->flags |= I2C_FLG_MASTER_RECEIVER; - i2cp->errors = 0; - - i2cp->id_i2c->CR1 |= I2C_CR1_ACK; /* acknowledge returned */ - i2cp->id_i2c->CR1 &= ~I2C_CR1_POS; - - if(i2cp->rxbytes == 1) { /* Only one byte to be received */ - i2cp->flags |= I2C_FLG_1BTR; - } - else if(i2cp->rxbytes == 2) { /* Only two bytes to be received */ - i2cp->flags |= I2C_FLG_2BTR; - i2cp->id_i2c->CR1 |= I2C_CR1_POS; /* Acknowledge Position */ - } - - i2cp->id_i2c->CR1 |= I2C_CR1_START; /* send start bit */ - i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN); /* enable ERR, EVT & BUF ITs */ } - -/** - * @brief Realize read-though-write behavior. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * - * @notapi - */ void i2c_lld_master_transceive(I2CDriver *i2cp){ - chDbgAssert((i2cp != NULL) && (i2cp->slave_addr1 != 0) &&\ - (i2cp->rxbytes > 0) && (i2cp->rxbuf != NULL), - "i2c_lld_master_transceive(), #1", - ""); - - i2cp->id_state = I2C_ACTIVE_TRANSCEIVE; - - /* "waiting" for START bit routine*/ - #if STM32_I2C_I2C1_USE_POLLING_WAIT - uint32_t timeout = I2C_POLLING_TIMEOUT; - while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout); - timeout--; - chDbgAssert((timeout > 0), "i2c_lld_master_transceive(), #1", "time to START is out"); - #else - chDbgAssert(!(i2cp->flags & I2C_FLG_TIMER_ARMED), "i2c_lld_master_transceive(), #1", "time to START is out"); - if ((i2cp->id_i2c->CR1 & I2C_CR1_START) && i2cp->timer != NULL && i2cp->timer_cfg != NULL){ - chSysLockFromIsr(); - gptStartOneShotI(i2cp->timer, I2C_START_GPT_TIMEOUT); - i2cp->flags |= I2C_FLG_TIMER_ARMED; - chSysUnlockFromIsr(); - return; - } - #endif /* STM32_I2C_I2C1_USE_POLLING_WAIT */ - - /* init address fields */ - if(i2cp->slave_addr & 0x8000){ /* 10-bit mode used */ - i2cp->slave_addr1 = ((i2cp->slave_addr >>7) & 0x0006);/* add the two msb of 10-bit address to the header */ - i2cp->slave_addr1 |= 0xF0; /* add the header bits (the LSB -> 1 will be add to second */ - i2cp->slave_addr2 = i2cp->slave_addr & 0x00FF; /* the remaining 8 bit of 10-bit address */ - } - else{ - i2cp->slave_addr1 |= 0x01; - } - - /* setting flags and register bits */ - i2cp->flags |= I2C_FLG_MASTER_RECEIVER; - i2cp->errors = 0; - i2cp->id_i2c->CR1 |= I2C_CR1_ACK; /* acknowledge returned */ - i2cp->id_i2c->CR1 &= ~I2C_CR1_POS; - - if(i2cp->rxbytes == 1) { /* Only one byte to be received */ - i2cp->flags |= I2C_FLG_1BTR; - } - else if(i2cp->rxbytes == 2) { /* Only two bytes to be received */ - i2cp->flags |= I2C_FLG_2BTR; - i2cp->id_i2c->CR1 |= I2C_CR1_POS; /* Acknowledge Position */ - } - - i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN); /* enable ERR, EVT & BUF ITs */ -} - -#else /*I2C_SUPPORTS_CALLBACKS*/ - -/** - * @brief Synchronously transmits data via the I2C bus as master. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * @param[in] slave_addr Slave device address. Bits 0-9 contain slave - * device address. Bit 15 must be set to 1 if 10-bit - * addressing modes used. Otherwise keep it cleared. - * Bits 10-14 unused. - * @param[in] txbuf pointer to the transmit buffer - * @param[in] txbytes number of bytes to be transmitted - * @param[in] rxbuf pointer to the receive buffer - * @param[in] rxbytes number of bytes to be received - */ -void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr, - uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes) { - - /* init driver fields */ - i2cp->slave_addr = slave_addr; - i2cp->txbytes = txbytes; - i2cp->rxbytes = rxbytes; - i2cp->txbuf = txbuf; - i2cp->rxbuf = rxbuf; - - /* init address fields */ - if(slave_addr & 0x8000){ /* 10-bit mode used */ - i2cp->slave_addr1 = ((slave_addr >>7) & 0x0006); /* add the two msb of 10-bit address to the header */ - i2cp->slave_addr1 |= 0xF0; /* add the header bits with LSB = 0 -> write */ - i2cp->slave_addr2 = slave_addr & 0x00FF; /* the remaining 8 bit of 10-bit address */ - } - else{ - i2cp->slave_addr1 = ((slave_addr <<1) & 0x00FE); /* LSB = 0 -> write */ - } - - i2cp->flags = 0; - i2cp->errors = 0; - i2cp->id_i2c->CR1 &= ~I2C_CR1_POS; - i2cp->id_i2c->CR2 &= ~I2C_CR2_ITEVTEN; /* disable event interrupts */ - i2cp->id_i2c->CR2 |= I2C_CR2_ITERREN; /* enable error interrupts */ - - i2cp->id_i2c->CR1 |= I2C_CR1_START; - while (!(i2cp->id_i2c->SR1 & I2C_SR1_SB)) - ; - i2cp->id_i2c->DR = i2cp->slave_addr1; - while (!(i2cp->id_i2c->SR1 & I2C_SR1_ADDR)) - ; - while (!(i2cp->id_i2c->SR2 & I2C_SR2_BUSY)) - ; - i2cp->id_i2c->DR = *txbuf; - txbuf++; - i2cp->txbytes--; - while(i2cp->txbytes > 0){ - while(!(i2cp->id_i2c->SR1 & I2C_SR1_BTF)) - ; - i2cp->id_i2c->DR = *txbuf; - txbuf++; - i2cp->txbytes--; - } - while(!(i2cp->id_i2c->SR1 & I2C_SR1_BTF)) - ; - if(rxbytes == 0){ - i2cp->id_i2c->CR1 |= I2C_CR1_STOP; - while (i2cp->id_i2c->CR1 & I2C_CR1_STOP) - ; - } - else{ - i2c_lld_master_receive(i2cp, slave_addr, rxbuf, rxbytes); - } -} - - -/** - * @brief Synchronously receives data from the I2C bus. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * @param[in] slave_addr Slave device address. Bits 0-9 contain slave - * device address. Bit 15 must be set to 1 if 10-bit - * addressing modes used. Otherwise keep it cleared. - * Bits 10-14 unused. - * @param[in] rxbuf pointer to the receive buffer - * @param[in] rxbytes number of bytes to be received - */ -void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr, - uint8_t *rxbuf, size_t rxbytes){ - - /* init driver fields */ - i2cp->slave_addr = slave_addr; - i2cp->rxbytes = rxbytes; - i2cp->rxbuf = rxbuf; - - /* init address fields */ - if(slave_addr & 0x8000){ /* 10-bit mode used */ - i2cp->slave_addr1 = ((slave_addr >>7) & 0x0006); /* add the two msb of 10-bit address to the header */ - i2cp->slave_addr1 |= 0xF0; /* add the header bits (the LSB -> 1 will be add to second */ - i2cp->slave_addr2 = slave_addr & 0x00FF; /* the remaining 8 bit of 10-bit address */ - } - else{ - i2cp->slave_addr1 = ((slave_addr <<1) | 0x01); /* LSB = 1 -> receive */ - } - - - /* setting flags and register bits */ - i2cp->flags = 0; - i2cp->errors = 0; - i2cp->id_i2c->CR1 &= ~I2C_CR1_POS; - i2cp->id_i2c->CR2 &= ~I2C_CR2_ITEVTEN; /* disable event interrupts */ - i2cp->id_i2c->CR2 |= I2C_CR2_ITERREN; /* enable error interrupts */ - - i2cp->id_i2c->CR1 |= I2C_CR1_START; - while (!(i2cp->id_i2c->SR1 & I2C_SR1_SB)) - ; - - i2cp->id_i2c->DR = i2cp->slave_addr1; - while (!(i2cp->id_i2c->SR1 & I2C_SR1_ADDR)) - ; - - if(i2cp->rxbytes >= 3){ /* more than 2 bytes receiving procedure */ - while(!(i2cp->id_i2c->SR2 & I2C_SR2_BUSY)) /* to clear ADDR bit */ - ; - while(i2cp->rxbytes > 3){ - while(!(i2cp->id_i2c->SR1 & I2C_SR1_BTF)) - ; - *rxbuf = i2cp->id_i2c->DR; - rxbuf++; - i2cp->rxbytes--; - } - while(!(i2cp->id_i2c->SR1 & I2C_SR1_BTF)) /* stopping procedure */ - ; - i2cp->id_i2c->CR1 &= ~I2C_CR1_ACK; - chSysLock(); - i2cp->id_i2c->CR1 |= I2C_CR1_STOP; - *rxbuf = i2cp->id_i2c->DR; - rxbuf++; - i2cp->rxbytes--; - chSysUnlock(); - while(!(i2cp->id_i2c->SR1 & I2C_SR1_RXNE)) - ; - *rxbuf = i2cp->id_i2c->DR; - rxbuf++; - i2cp->rxbytes--; - while (i2cp->id_i2c->CR1 & I2C_CR1_STOP) - ; - i2cp->id_i2c->CR1 |= I2C_CR1_ACK; - } - else{ /* 1 or 2 bytes receiving procedure */ - if(i2cp->rxbytes == 2){ - i2cp->id_i2c->CR1 |= I2C_CR1_POS; - chSysLock(); - while(!(i2cp->id_i2c->SR2 & I2C_SR2_BUSY)) /* to clear ADDR bit */ - ; - i2cp->id_i2c->CR1 &= ~I2C_CR1_ACK; - chSysUnlock(); - while(!(i2cp->id_i2c->SR1 & I2C_SR1_BTF)) - ; - chSysLock(); - i2cp->id_i2c->CR1 |= I2C_CR1_STOP; - *rxbuf = i2cp->id_i2c->DR; - rxbuf++; - i2cp->rxbytes--; - chSysUnlock(); - *rxbuf = i2cp->id_i2c->DR; - rxbuf++; - i2cp->rxbytes--; - while (i2cp->id_i2c->CR1 & I2C_CR1_STOP) - ; - i2cp->id_i2c->CR1 &= ~I2C_CR1_POS; - i2cp->id_i2c->CR1 |= I2C_CR1_ACK; - } - else{ /* 1 byte */ - i2cp->id_i2c->CR1 &= ~I2C_CR1_ACK; - chSysLock(); - while(!(i2cp->id_i2c->SR2 & I2C_SR2_BUSY)) /* to clear ADDR bit */ - ; - i2cp->id_i2c->CR1 |= I2C_CR1_STOP; - chSysUnlock(); - while(!(i2cp->id_i2c->SR1 & I2C_SR1_RXNE)) - ; - *rxbuf = i2cp->id_i2c->DR; - rxbuf++; - i2cp->rxbytes--; - while (i2cp->id_i2c->CR1 & I2C_CR1_STOP) - ; - i2cp->id_i2c->CR1 |= I2C_CR1_ACK; - } - } } -#endif /* I2C_SUPPORTS_CALLBACKS */ #undef rxBuffp #undef txBuffp diff --git a/os/hal/platforms/STM32/i2c_lld.h b/os/hal/platforms/STM32/i2c_lld.h index 24195147a..e4fb8970f 100644 --- a/os/hal/platforms/STM32/i2c_lld.h +++ b/os/hal/platforms/STM32/i2c_lld.h @@ -42,33 +42,6 @@ * @name Configuration options * @{ */ -/** - * @brief Switch between callback based and synchronouse driver. - * @note The default is synchronouse. - */ -#if !defined(I2C_SUPPORTS_CALLBACKS) || defined(__DOXYGEN__) -#define I2C_SUPPORTS_CALLBACKS TRUE -#endif - -/** - * @brief I2C1 driver synchronization choice between GPT and polling. - * @note The default is polling wait. - */ -#if !defined(STM32_I2C_I2C1_USE_GPT_TIM) || \ - !defined(STM32_I2C_I2C1_USE_POLLING_WAIT) || \ - defined(__DOXYGEN__) -#define STM32_I2C_I2C1_USE_POLLING_WAIT TRUE -#endif - -/** - * @brief I2C2 driver synchronization choice between GPT and polling. - * @note The default is polling wait. - */ -#if !defined(STM32_I2C_I2C2_USE_GPT_TIM) || \ - !defined(STM32_I2C_I2C2_USE_POLLING_WAIT) || \ - defined(__DOXYGEN__) -#define STM32_I2C_I2C2_USE_POLLING_WAIT TRUE -#endif /** * @brief I2C1 driver enable switch. @@ -238,25 +211,22 @@ struct I2CDriver{ #endif /*********** End of the mandatory fields. **********************************/ - /** - * @brief Pointer to the I2Cx registers block. + * @brief DMA mode bit mask. */ - I2C_TypeDef *id_i2c; - -#if !(STM32_I2C_I2C1_USE_POLLING_WAIT) - /* TODO: capability to switch this GPT fields off */ + uint32_t dmamode; /** - * @brief Timer for waiting STOP condition on the bus. - * @details This is workaround for STM32 buggy I2C cell. + * @brief Receive DMA channel. */ - GPTDriver *timer; - + const stm32_dma_stream_t *dmarx; /** - * @brief Config for workaround timer. + * @brief Transmit DMA channel. */ - const GPTConfig *timer_cfg; -#endif /* !(STM32_I2C_I2C1_USE_POLLING_WAIT) */ + const stm32_dma_stream_t *dmatx; + /** + * @brief Pointer to the I2Cx registers block. + */ + I2C_TypeDef *id_i2c; }; @@ -308,9 +278,6 @@ void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr, uint8_t *rxbuf, size_t rxbytes); void i2c_lld_master_transceive(I2CDriver *i2cp); -void i2c_lld_master_transmit_dma(I2CDriver *i2cp, uint16_t slave_addr, - uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes); - #ifdef __cplusplus } #endif diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c index abd3252cf..0f46e4e64 100644 --- a/os/hal/src/i2c.c +++ b/os/hal/src/i2c.c @@ -111,10 +111,6 @@ void i2cStart(I2CDriver *i2cp, const I2CConfig *config) { "i2cStart(), #1", "invalid state"); -#if (!(STM32_I2C_I2C2_USE_POLLING_WAIT) && I2C_SUPPORTS_CALLBACKS) - gptStart(i2cp->timer, i2cp->timer_cfg); -#endif /* !(STM32_I2C_I2C2_USE_POLLING_WAIT) */ - chSysLock(); i2cp->id_config = config; i2c_lld_start(i2cp); @@ -136,10 +132,6 @@ void i2cStop(I2CDriver *i2cp) { "i2cStop(), #1", "invalid state"); -#if (!(STM32_I2C_I2C2_USE_POLLING_WAIT) && I2C_SUPPORTS_CALLBACKS) - gptStop(i2cp->timer); -#endif /* !(STM32_I2C_I2C2_USE_POLLING_WAIT) */ - chSysLock(); i2c_lld_stop(i2cp); i2cp->id_state = I2C_STOP; -- cgit v1.2.3 From c995ee2bd31d5ee7173668c57f9c2c80ae7cc1b3 Mon Sep 17 00:00:00 2001 From: barthess Date: Fri, 2 Dec 2011 08:29:27 +0000 Subject: I2C. Added attributes. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3549 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/hal_lld.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index 0650c84f8..1310738d4 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -292,8 +292,24 @@ /* 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)) +#define STM32_I2C1_TX_DMA_CHN 0x10000000 + #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 /* RTC attributes.*/ #define STM32_HAS_RTC TRUE -- cgit v1.2.3 From dbac0ef26b2977c9862ec6ddc22f10dac76b3239 Mon Sep 17 00:00:00 2001 From: barthess Date: Fri, 2 Dec 2011 15:01:31 +0000 Subject: I2C. DMA works. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3550 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/i2c_lld.c | 200 +++++++++++++++++++++++++++++++++++++-- os/hal/src/i2c.c | 2 +- 2 files changed, 191 insertions(+), 11 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index ccec33dbc..9afdc8619 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -43,6 +43,25 @@ * Otherwise there is a risk of setting a second STOP, START or PEC request. */ +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ +#define I2C1_RX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_RX_DMA_STREAM, \ + STM32_I2C1_RX_DMA_CHN) + +#define I2C1_TX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_TX_DMA_STREAM, \ + STM32_I2C1_TX_DMA_CHN) + +#define I2C2_RX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_RX_DMA_STREAM, \ + STM32_I2C2_RX_DMA_CHN) + +#define I2C2_TX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_TX_DMA_STREAM, \ + STM32_I2C2_TX_DMA_CHN) + /*===========================================================================*/ /* Driver constants. */ /*===========================================================================*/ @@ -82,12 +101,71 @@ static volatile uint16_t dbgCR2 = 0; /*===========================================================================*/ + + +#if CH_DBG_ENABLE_ASSERTS +void _i2c_unhandled_case(I2CDriver *i2cp){ + dbgCR1 = i2cp->id_i2c->CR1; + dbgCR2 = i2cp->id_i2c->CR2; + chDbgAssert((dbgSR1 + dbgSR2) == 0, + "i2c_serve_event_interrupt(), #1", + "unhandled case"); +} +#else +#define _i2c_unhandled_case(i2cp) +#endif /* CH_DBG_ENABLE_ASSERTS */ + + + + +/** + * @brief Return the last event value from I2C status registers. + * @note Internal use only. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * + * @notapi + */ +static uint32_t i2c_get_event(I2CDriver *i2cp){ + uint16_t regSR1 = i2cp->id_i2c->SR1; + uint16_t regSR2 = i2cp->id_i2c->SR2; + #if CH_DBG_ENABLE_ASSERTS + dbgSR1 = regSR1; + dbgSR2 = regSR2; + #endif /* CH_DBG_ENABLE_ASSERTS */ + + return (I2C_EV_MASK & (regSR1 | (regSR2 << 16))); +} + + + + + static void i2c_serve_event_interrupt(I2CDriver *i2cp) { + I2C_TypeDef *dp = i2cp->id_i2c; + switch(i2c_get_event(i2cp)){ + case I2C_EV5_MASTER_MODE_SELECT: + i2cp->flags &= ~I2C_FLG_HEADER_SENT; + dp->DR = i2cp->slave_addr1; + break; + + case I2C_EV6_MASTER_REC_MODE_SELECTED: + /* begin receiving via DMA */ + i2cp->id_i2c->CR2 &= ~I2C_CR2_ITBUFEN; /* switch off interrupt because we use DMA*/ + break; + + + + default: + break; + } } + + static void i2c_serve_error_interrupt(I2CDriver *i2cp) { i2cflags_t flags; I2C_TypeDef *reg; @@ -138,16 +216,32 @@ static void i2c_serve_error_interrupt(I2CDriver *i2cp) { } -static void i2c_lld_serve_rx_end_irq(UARTDriver *i2cp, uint32_t flags) { + + + +static void i2c_lld_serve_rx_end_irq(I2CDriver *i2cp, uint32_t flags){ + (void)flags; + + dmaStreamDisable(i2cp->dmarx); + i2cp->id_i2c->CR1 |= I2C_CR1_STOP; + while(i2cp->id_i2c->CR1 & I2C_CR1_STOP) + ; + _i2c_isr_code(i2cp, i2cp->id_slave_config); } -static void i2c_lld_serve_tx_end_irq(UARTDriver *i2cp, uint32_t flags) { + +static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) { + (void)i2cp; + (void)flags; } + + + #if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__) #error "Unrealized yet" #endif /* STM32_I2C_USE_I2C1 */ @@ -172,6 +266,9 @@ CH_IRQ_HANDLER(I2C2_ER_IRQHandler) { #endif /* STM32_I2C_USE_I2C2 */ + + + /** * @brief Low level I2C driver initialization. */ @@ -189,6 +286,11 @@ void i2c_lld_init(void) { #endif /* STM32_I2C_USE_I2C2 */ } + + + + + /** * @brief Configures and activates the I2C peripheral. * @@ -229,9 +331,8 @@ void i2c_lld_start(I2CDriver *i2cp) { NVICEnableVector(I2C2_ER_IRQn, CORTEX_PRIORITY_MASK(STM32_I2C_I2C2_IRQ_PRIORITY)); - //i2cp->dmamode |= STM32_DMA_CR_CHSEL(USART2_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_UART_USART2_DMA_PRIORITY); - // TODO: remove hardcoded "7" - i2cp->dmamode |= STM32_DMA_CR_CHSEL(7) | STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY); + i2cp->dmamode |= STM32_DMA_CR_CHSEL(I2C2_RX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY); } #endif /* STM32_I2C_USE_I2C2 */ } @@ -243,12 +344,15 @@ void i2c_lld_start(I2CDriver *i2cp) { i2cp->id_i2c->CR1 = 0; i2c_lld_set_clock(i2cp); i2c_lld_set_opmode(i2cp); + i2cp->id_i2c->CR1 |= 1; /* enable interface */ } + + void i2c_lld_reset(I2CDriver *i2cp){ chDbgCheck((i2cp->id_state == I2C_STOP)||(i2cp->id_state == I2C_READY), "i2c_lld_reset: invalid state"); @@ -259,6 +363,11 @@ void i2c_lld_reset(I2CDriver *i2cp){ } + + + + + /** * @brief Set clock speed. * @@ -329,6 +438,12 @@ void i2c_lld_set_clock(I2CDriver *i2cp) { i2cp->id_i2c->CR1 |= pe_bit_saved; /* restore the I2C peripheral enabled state */ } + + + + + + /** * @brief Set operation mode of I2C hardware. * @@ -355,6 +470,14 @@ void i2c_lld_set_opmode(I2CDriver *i2cp) { i2cp->id_i2c->CR1 = regCR1; /* Write to I2Cx CR1 */ } + + + + + + + + /** * @brief Set own address. * @@ -378,6 +501,11 @@ void i2c_lld_set_own_address(I2CDriver *i2cp) { } + + + + + /** * @brief Deactivates the I2C peripheral. * @@ -405,6 +533,52 @@ void i2c_lld_stop(I2CDriver *i2cp) { } + + + + +void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr, uint8_t *rxbuf, size_t rxbytes){ + (void)slave_addr; + + uint32_t mode = 0; + + /* init driver fields */ + i2cp->slave_addr = slave_addr; + i2cp->rxbytes = rxbytes; + i2cp->rxbuf = rxbuf; + + /* init address fields */ + if(slave_addr & 0x8000){ /* 10-bit mode used */ + i2cp->slave_addr1 = ((slave_addr >>7) & 0x0006); /* add the two msb of 10-bit address to the header */ + i2cp->slave_addr1 |= 0xF0; /* add the header bits (the LSB -> 1 will be add to second */ + i2cp->slave_addr2 = slave_addr & 0x00FF; /* the remaining 8 bit of 10-bit address */ + } + else{ + i2cp->slave_addr1 = ((slave_addr <<1) | 0x01); /* LSB = 1 -> receive */ + } + + /* setting flags and register bits */ + i2cp->flags |= I2C_FLG_MASTER_RECEIVER; + i2cp->errors = 0; + + mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE; + // TODO: DMA error handling + dmaStreamSetMemory0(i2cp->dmarx, rxbuf); + dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes); + dmaStreamSetMode(i2cp->dmarx, ((i2cp->dmamode) | mode)); + dmaStreamEnable(i2cp->dmarx); + + i2cp->id_i2c->CR2 |= I2C_CR2_DMAEN | I2C_CR2_LAST; + + i2cp->id_i2c->CR2 |= I2C_CR2_ITERREN | I2C_CR2_ITEVTEN; + i2cp->id_i2c->CR1 |= I2C_CR1_START | I2C_CR1_ACK; +} + + + + + + /** * @brief Transmits data via the I2C bus as master. * @@ -420,15 +594,21 @@ void i2c_lld_stop(I2CDriver *i2cp) { */ void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr, uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes) { - + (void)i2cp; + (void)slave_addr; + (void)txbuf; + (void)txbytes; + (void)rxbuf; + (void)rxbytes; } -void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr, - uint8_t *rxbuf, size_t rxbytes){ -} -void i2c_lld_master_transceive(I2CDriver *i2cp){ + + + +void i2c_lld_master_transceive(I2CDriver *i2cp){ + (void)i2cp; } #undef rxBuffp diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c index 0f46e4e64..3add2af98 100644 --- a/os/hal/src/i2c.c +++ b/os/hal/src/i2c.c @@ -210,7 +210,7 @@ void i2cMasterReceive(I2CDriver *i2cp, chDbgCheck((i2cp != NULL) && (i2cscfg != NULL) &&\ (slave_addr != 0) &&\ - (rxbytes > 0) && \ + (rxbytes > 1) && \ (rxbuf != NULL), "i2cMasterReceive"); -- cgit v1.2.3 From 0faef9a2928309385c52f25fb892ac46ced093ab Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 3 Dec 2011 08:49:51 +0000 Subject: Fixed bug 3449139, increased version numbers. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3552 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/hal_lld.c | 7 ++++++- os/hal/platforms/STM32L1xx/hal_lld.c | 8 ++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/hal_lld.c b/os/hal/platforms/STM32F4xx/hal_lld.c index 5033c41c8..6922ff3df 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.c +++ b/os/hal/platforms/STM32F4xx/hal_lld.c @@ -62,8 +62,9 @@ void hal_lld_init(void) { been initialized in the board initialization file (board.c).*/ rccResetAHB1(!0); rccResetAHB2(!0); + rccResetAHB3(!0); rccResetAPB1(!RCC_APB1RSTR_PWRRST); - rccResetAPB2(!RCC_APB2RSTR_SYSCFGRST); + rccResetAPB2(!0); /* SysTick initialization using the system clock.*/ SysTick->LOAD = STM32_HCLK / CH_FREQUENCY - 1; @@ -152,6 +153,10 @@ void stm32_clock_init(void) { ; #endif #endif /* STM32_NO_INIT */ + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, TRUE); } /** @} */ diff --git a/os/hal/platforms/STM32L1xx/hal_lld.c b/os/hal/platforms/STM32L1xx/hal_lld.c index c59aa3f1c..96b18a656 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.c +++ b/os/hal/platforms/STM32L1xx/hal_lld.c @@ -60,8 +60,8 @@ void hal_lld_init(void) { /* Reset of all peripherals.*/ rccResetAHB(!RCC_AHBRSTR_FLITFRST); - rccResetAPB1(!0); - rccResetAPB2(!RCC_APB2RSTR_SYSCFGRST); + rccResetAPB1(!RCC_APB1RSTR_PWRRST); + rccResetAPB2(!0); /* SysTick initialization using the system clock.*/ SysTick->LOAD = STM32_HCLK / CH_FREQUENCY - 1; @@ -170,6 +170,10 @@ void stm32_clock_init(void) { ; #endif #endif /* STM32_NO_INIT */ + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, TRUE); } #else void stm32_clock_init(void) {} -- cgit v1.2.3 From 59014aa2be0488eba89c6ec0fb1934aa43aeb224 Mon Sep 17 00:00:00 2001 From: barthess Date: Sun, 4 Dec 2011 17:46:19 +0000 Subject: I2C. Tested on tmp75, mma8451, max1236. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3553 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/i2c.h | 17 +- os/hal/platforms/STM32/i2c_lld.c | 353 +++++++++++++++++++-------------------- os/hal/platforms/STM32/i2c_lld.h | 85 +++------- os/hal/src/i2c.c | 40 ++--- 4 files changed, 212 insertions(+), 283 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h index cf4d47713..18e93119e 100644 --- a/os/hal/include/i2c.h +++ b/os/hal/include/i2c.h @@ -66,6 +66,13 @@ #define I2C_USE_MUTUAL_EXCLUSION TRUE #endif +/** + * @brief Enables the mutual exclusion APIs on the I2C bus. + */ +#if !defined(I2C_USE_WAIT) || defined(__DOXYGEN__) +#define I2C_USE_WAIT TRUE +#endif + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ @@ -87,7 +94,6 @@ typedef enum { I2C_READY = 2, /**< Ready. */ I2C_ACTIVE_TRANSMIT = 3, /**< Transmitting. */ I2C_ACTIVE_RECEIVE = 4, /**< Receiving. */ - I2C_ACTIVE_TRANSCEIVE = 5, /**< Receiving after transmit. */ } i2cstate_t; #include "i2c_lld.h" @@ -115,11 +121,6 @@ typedef void (*i2ccallback_t)(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg); typedef void (*i2cerrorcallback_t)(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg); -/** - * @brief I2C transmission data block size. - */ -typedef uint8_t i2cblock_t; - /** * @brief Structure representing an I2C slave configuration. * @details Each slave device has its own config structure with input and @@ -252,11 +253,11 @@ extern "C" { void i2cStart(I2CDriver *i2cp, const I2CConfig *config); void i2cStop(I2CDriver *i2cp); void i2cMasterTransmit(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg, - uint16_t slave_addr, + uint8_t slave_addr, uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes); void i2cMasterReceive(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg, - uint16_t slave_addr, uint8_t *rxbuf, size_t rxbytes); + uint8_t slave_addr, uint8_t *rxbuf, size_t rxbytes); void i2cMasterStart(I2CDriver *i2cp); void i2cMasterStop(I2CDriver *i2cp); void i2cAddFlagsI(I2CDriver *i2cp, i2cflags_t mask); diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index 9afdc8619..b49f4b588 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -35,7 +35,7 @@ /* Datasheet notes. */ /*===========================================================================*/ /** - * From RM0008.pdf + * From reference manuals from ST: * * Note: * When the STOP, START or PEC bit is set, the software must NOT perform @@ -49,7 +49,6 @@ #define I2C1_RX_DMA_CHANNEL \ STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_RX_DMA_STREAM, \ STM32_I2C1_RX_DMA_CHN) - #define I2C1_TX_DMA_CHANNEL \ STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_TX_DMA_STREAM, \ STM32_I2C1_TX_DMA_CHN) @@ -57,11 +56,17 @@ #define I2C2_RX_DMA_CHANNEL \ STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_RX_DMA_STREAM, \ STM32_I2C2_RX_DMA_CHN) - #define I2C2_TX_DMA_CHANNEL \ STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_TX_DMA_STREAM, \ STM32_I2C2_TX_DMA_CHN) +#define I2C3_RX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_I2C_I2C3_RX_DMA_STREAM, \ + STM32_I2C3_RX_DMA_CHN) +#define I2C3_TX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_I2C_I2C3_TX_DMA_STREAM, \ + STM32_I2C3_TX_DMA_CHN) + /*===========================================================================*/ /* Driver constants. */ /*===========================================================================*/ @@ -80,10 +85,14 @@ I2CDriver I2CD1; I2CDriver I2CD2; #endif +/** @brief I2C2 driver identifier.*/ +#if STM32_I2C_USE_I2C3 || defined(__DOXYGEN__) +I2CDriver I2CD3; +#endif + /*===========================================================================*/ /* Driver local variables. */ /*===========================================================================*/ - /* Debugging variables */ #if CH_DBG_ENABLE_ASSERTS static volatile uint16_t dbgSR1 = 0; @@ -92,34 +101,13 @@ static volatile uint16_t dbgCR1 = 0; static volatile uint16_t dbgCR2 = 0; #endif /* CH_DBG_ENABLE_ASSERTS */ -/* defines for convenience purpose */ -#define txBuffp (i2cp->txbuff_p) -#define rxBuffp (i2cp->rxbuff_p) - /*===========================================================================*/ /* Driver local functions. */ /*===========================================================================*/ - - - -#if CH_DBG_ENABLE_ASSERTS -void _i2c_unhandled_case(I2CDriver *i2cp){ - dbgCR1 = i2cp->id_i2c->CR1; - dbgCR2 = i2cp->id_i2c->CR2; - chDbgAssert((dbgSR1 + dbgSR2) == 0, - "i2c_serve_event_interrupt(), #1", - "unhandled case"); -} -#else -#define _i2c_unhandled_case(i2cp) -#endif /* CH_DBG_ENABLE_ASSERTS */ - - - - /** * @brief Return the last event value from I2C status registers. + * @details Important but implicit function is clearing interrpts flags. * @note Internal use only. * * @param[in] i2cp pointer to the @p I2CDriver object @@ -146,17 +134,26 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) { switch(i2c_get_event(i2cp)){ case I2C_EV5_MASTER_MODE_SELECT: + /* catch start generated event */ i2cp->flags &= ~I2C_FLG_HEADER_SENT; - dp->DR = i2cp->slave_addr1; + dp->DR = i2cp->slave_addr; break; - case I2C_EV6_MASTER_REC_MODE_SELECTED: - /* begin receiving via DMA */ - i2cp->id_i2c->CR2 &= ~I2C_CR2_ITBUFEN; /* switch off interrupt because we use DMA*/ + case I2C_EV8_2_MASTER_BYTE_TRANSMITTED: + /* catch BTF event after the end of trasmission */ + if (i2cp->rxbytes > 1){ + /* start "read after write" operation */ + i2c_lld_master_receive(i2cp, (i2cp->slave_addr >> 1), i2cp->rxbuf, i2cp->rxbytes); + return; + } + else + i2cp->id_i2c->CR1 |= I2C_CR1_STOP; + // FIXME: change this polling to something else + while(i2cp->id_i2c->CR1 & I2C_CR1_STOP) + ; + _i2c_isr_code(i2cp, i2cp->id_slave_config); break; - - default: break; } @@ -165,6 +162,26 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) { +static void i2c_lld_serve_rx_end_irq(I2CDriver *i2cp){ + dmaStreamDisable(i2cp->dmarx); + + i2cp->id_i2c->CR1 |= I2C_CR1_STOP; + // FIXME: change this polling to something else + while(i2cp->id_i2c->CR1 & I2C_CR1_STOP) + ; + _i2c_isr_code(i2cp, i2cp->id_slave_config); +} + + + + + +static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp){ + dmaStreamDisable(i2cp->dmatx); +} + + + static void i2c_serve_error_interrupt(I2CDriver *i2cp) { i2cflags_t flags; @@ -209,39 +226,13 @@ static void i2c_serve_error_interrupt(I2CDriver *i2cp) { chSysLockFromIsr(); i2cAddFlagsI(i2cp, flags); chSysUnlockFromIsr(); - #if I2C_SUPPORTS_CALLBACKS _i2c_isr_err_code(i2cp, i2cp->id_slave_config); - #endif /* I2C_SUPPORTS_CALLBACKS */ } } - - -static void i2c_lld_serve_rx_end_irq(I2CDriver *i2cp, uint32_t flags){ - (void)flags; - - dmaStreamDisable(i2cp->dmarx); - i2cp->id_i2c->CR1 |= I2C_CR1_STOP; - while(i2cp->id_i2c->CR1 & I2C_CR1_STOP) - ; - _i2c_isr_code(i2cp, i2cp->id_slave_config); -} - - - -static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) { - (void)i2cp; - (void)flags; -} - - - - - - #if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__) #error "Unrealized yet" #endif /* STM32_I2C_USE_I2C1 */ @@ -265,7 +256,9 @@ CH_IRQ_HANDLER(I2C2_ER_IRQHandler) { } #endif /* STM32_I2C_USE_I2C2 */ - +#if STM32_I2C_USE_I2C3 || defined(__DOXYGEN__) +#error "Unrealized yet" +#endif /* STM32_I2C_USE_I2C3 */ @@ -286,7 +279,9 @@ void i2c_lld_init(void) { #endif /* STM32_I2C_USE_I2C2 */ } - +#if STM32_I2C_USE_I2C3 +#error "Unrealized yet" +#endif /* STM32_I2C_USE_I2C */ @@ -336,7 +331,10 @@ void i2c_lld_start(I2CDriver *i2cp) { } #endif /* STM32_I2C_USE_I2C2 */ } - i2cp->dmamode |= STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE; + i2cp->dmamode |= STM32_DMA_CR_PSIZE_BYTE | + STM32_DMA_CR_MSIZE_BYTE | + STM32_DMA_CR_MINC | + STM32_DMA_CR_TCIE; dmaStreamSetPeripheral(i2cp->dmarx, &i2cp->id_i2c->DR); dmaStreamSetPeripheral(i2cp->dmatx, &i2cp->id_i2c->DR); @@ -348,7 +346,16 @@ void i2c_lld_start(I2CDriver *i2cp) { i2cp->id_i2c->CR1 |= 1; /* enable interface */ } - +#if STM32_I2C_USE_I2C3 +// if (&I2CD1 == i2cp) { +// NVICEnableVector(I2C1_EV_IRQn, +// CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); +// NVICEnableVector(I2C1_ER_IRQn, +// CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); +// rccEnableI2C1(FALSE); +// } +#error "Unrealized yet" +#endif /* STM32_I2C_USE_I2C3 */ @@ -357,9 +364,20 @@ void i2c_lld_reset(I2CDriver *i2cp){ chDbgCheck((i2cp->id_state == I2C_STOP)||(i2cp->id_state == I2C_READY), "i2c_lld_reset: invalid state"); - /*TODO: Check what interface we must reset */ - rccResetI2C1(); - rccResetI2C2(); + #if STM32_I2C_USE_I2C1 + if (&I2CD1 == i2cp) + rccResetI2C1(); + #endif /* STM32_I2C_USE_I2C1 */ + + #if STM32_I2C_USE_I2C2 + if (&I2CD2 == i2cp) + rccResetI2C2(); + #endif /* STM32_I2C_USE_I2C2 */ + + #if STM32_I2C_USE_I2C3 + if (&I2CD3 == i2cp) + rccResetI2C3(); + #endif /* STM32_I2C_USE_I2C3 */ } @@ -368,6 +386,80 @@ void i2c_lld_reset(I2CDriver *i2cp){ +void i2c_lld_master_receive(I2CDriver *i2cp, uint8_t slave_addr, + uint8_t *rxbuf, size_t rxbytes){ + + uint32_t mode = 0; + + /* init driver fields */ + i2cp->slave_addr = (slave_addr << 1) | 0x01; /* LSB = 1 -> receive */ + i2cp->rxbytes = rxbytes; + i2cp->rxbuf = rxbuf; + i2cp->flags = 0; + + /* setting flags and register bits */ + i2cp->flags |= I2C_FLG_MASTER_RECEIVER; + i2cp->errors = 0; + + mode = STM32_DMA_CR_DIR_P2M; + // TODO: DMA error handling + dmaStreamSetMemory0(i2cp->dmarx, rxbuf); + dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes); + dmaStreamSetMode(i2cp->dmarx, ((i2cp->dmamode) | mode)); + dmaStreamEnable(i2cp->dmarx); + + i2cp->id_i2c->CR2 |= I2C_CR2_DMAEN | I2C_CR2_LAST; + i2cp->id_i2c->CR2 |= I2C_CR2_ITERREN | I2C_CR2_ITEVTEN; + i2cp->id_i2c->CR1 |= I2C_CR1_START | I2C_CR1_ACK; +} + + + + + + +/** + * @brief Transmits data via the I2C bus as master. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] slave_addr slave device address + * @param[in] txbuf pointer to the transmit buffer + * @param[in] txbytes number of bytes to be transmitted + * @param[in] rxbuf pointer to the receive buffer + * @param[in] rxbytes number of bytes to be received + */ +void i2c_lld_master_transmit(I2CDriver *i2cp, uint8_t slave_addr, + uint8_t *txbuf, size_t txbytes, + uint8_t *rxbuf, size_t rxbytes){ + + uint32_t mode = 0; + + /* init driver fields */ + i2cp->slave_addr = (slave_addr << 1) & 0x00FE; /* LSB = 0 -> write */ + i2cp->txbytes = txbytes; + i2cp->rxbytes = rxbytes; + i2cp->txbuf = txbuf; + i2cp->rxbuf = rxbuf; + + /* setting flags and register bits */ + i2cp->flags = 0; + i2cp->errors = 0; + + mode = STM32_DMA_CR_DIR_M2P; + // TODO: DMA error handling + dmaStreamSetMemory0(i2cp->dmatx, txbuf); + dmaStreamSetTransactionSize(i2cp->dmatx, txbytes); + dmaStreamSetMode(i2cp->dmatx, ((i2cp->dmamode) | mode)); + dmaStreamEnable(i2cp->dmatx); + + i2cp->id_i2c->CR2 |= I2C_CR2_DMAEN | I2C_CR2_LAST; + i2cp->id_i2c->CR2 |= I2C_CR2_ITERREN | I2C_CR2_ITEVTEN; + i2cp->id_i2c->CR1 |= I2C_CR1_START; +} + + + + /** * @brief Set clock speed. * @@ -394,7 +486,7 @@ void i2c_lld_set_clock(I2CDriver *i2cp) { #else chDbgCheck((freq >= 2) && (freq <= 36), "i2c_lld_set_clock() : Peripheral clock freq. out of range"); -#endif +#endif /* define STM32F4XX */ regCR2 |= freq; i2cp->id_i2c->CR2 = regCR2; @@ -439,11 +531,6 @@ void i2c_lld_set_clock(I2CDriver *i2cp) { } - - - - - /** * @brief Set operation mode of I2C hardware. * @@ -473,39 +560,6 @@ void i2c_lld_set_opmode(I2CDriver *i2cp) { - - - - - -/** - * @brief Set own address. - * - * @param[in] i2cp pointer to the @p I2CDriver object - */ -void i2c_lld_set_own_address(I2CDriver *i2cp) { - /* TODO: dual address mode */ - - i2cp->id_i2c->OAR1 |= 1 << 14; - - if (&(i2cp->id_config->own_addr_10) == NULL){ /* only 7-bit address */ - i2cp->id_i2c->OAR1 &= (~I2C_OAR1_ADDMODE); - i2cp->id_i2c->OAR1 |= i2cp->id_config->own_addr_7 << 1; - } - else { - chDbgAssert((i2cp->id_config->own_addr_10 < 1024), - "i2c_lld_set_own_address(), #1", "10-bit address longer then 10 bit") - i2cp->id_i2c->OAR1 |= I2C_OAR1_ADDMODE; - i2cp->id_i2c->OAR1 |= i2cp->id_config->own_addr_10; - } -} - - - - - - - /** * @brief Deactivates the I2C peripheral. * @@ -513,6 +567,7 @@ void i2c_lld_set_own_address(I2CDriver *i2cp) { */ void i2c_lld_stop(I2CDriver *i2cp) { if (i2cp->id_state == I2C_READY) { /* If in ready state then disables the I2C clock.*/ + #if STM32_I2C_USE_I2C1 if (&I2CD1 == i2cp) { NVICDisableVector(I2C1_EV_IRQn); @@ -520,6 +575,7 @@ void i2c_lld_stop(I2CDriver *i2cp) { rccDisableI2C1(FALSE); } #endif + #if STM32_I2C_USE_I2C2 if (&I2CD2 == i2cp) { NVICDisableVector(I2C2_EV_IRQn); @@ -527,91 +583,18 @@ void i2c_lld_stop(I2CDriver *i2cp) { rccDisableI2C2(FALSE); } #endif - } - - i2cp->id_state = I2C_STOP; -} - - - - - -void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr, uint8_t *rxbuf, size_t rxbytes){ - (void)slave_addr; - - uint32_t mode = 0; - - /* init driver fields */ - i2cp->slave_addr = slave_addr; - i2cp->rxbytes = rxbytes; - i2cp->rxbuf = rxbuf; - - /* init address fields */ - if(slave_addr & 0x8000){ /* 10-bit mode used */ - i2cp->slave_addr1 = ((slave_addr >>7) & 0x0006); /* add the two msb of 10-bit address to the header */ - i2cp->slave_addr1 |= 0xF0; /* add the header bits (the LSB -> 1 will be add to second */ - i2cp->slave_addr2 = slave_addr & 0x00FF; /* the remaining 8 bit of 10-bit address */ - } - else{ - i2cp->slave_addr1 = ((slave_addr <<1) | 0x01); /* LSB = 1 -> receive */ +#if STM32_I2C_USE_I2C3 + if (&I2CD3 == i2cp) { + NVICDisableVector(I2C3_EV_IRQn); + NVICDisableVector(I2C3_ER_IRQn); + rccDisableI2C3(FALSE); + } +#endif } - /* setting flags and register bits */ - i2cp->flags |= I2C_FLG_MASTER_RECEIVER; - i2cp->errors = 0; - - mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE; - // TODO: DMA error handling - dmaStreamSetMemory0(i2cp->dmarx, rxbuf); - dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes); - dmaStreamSetMode(i2cp->dmarx, ((i2cp->dmamode) | mode)); - dmaStreamEnable(i2cp->dmarx); - - i2cp->id_i2c->CR2 |= I2C_CR2_DMAEN | I2C_CR2_LAST; - - i2cp->id_i2c->CR2 |= I2C_CR2_ITERREN | I2C_CR2_ITEVTEN; - i2cp->id_i2c->CR1 |= I2C_CR1_START | I2C_CR1_ACK; -} - - - - - - -/** - * @brief Transmits data via the I2C bus as master. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * @param[in] slave_addr Slave device address. Bits 0-9 contain slave - * device address. Bit 15 must be set to 1 if 10-bit - * addressing modes used. Otherwise keep it cleared. - * Bits 10-14 unused. - * @param[in] txbuf pointer to the transmit buffer - * @param[in] txbytes number of bytes to be transmitted - * @param[in] rxbuf pointer to the receive buffer - * @param[in] rxbytes number of bytes to be received - */ -void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr, - uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes) { - (void)i2cp; - (void)slave_addr; - (void)txbuf; - (void)txbytes; - (void)rxbuf; - (void)rxbytes; -} - - - - - - -void i2c_lld_master_transceive(I2CDriver *i2cp){ - (void)i2cp; + i2cp->id_state = I2C_STOP; } -#undef rxBuffp -#undef txBuffp #endif /* HAL_USE_I2C */ diff --git a/os/hal/platforms/STM32/i2c_lld.h b/os/hal/platforms/STM32/i2c_lld.h index e4fb8970f..00eef923d 100644 --- a/os/hal/platforms/STM32/i2c_lld.h +++ b/os/hal/platforms/STM32/i2c_lld.h @@ -83,35 +83,13 @@ /*===========================================================================*/ /** @brief EV5 */ -#define I2C_EV5_MASTER_MODE_SELECT ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_SB)) /* BUSY, MSL and SB flag */ -/** @brief EV6 */ -#define I2C_EV6_MASTER_TRA_MODE_SELECTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY|I2C_SR2_TRA)<< 16)|I2C_SR1_ADDR|I2C_SR1_TXE)) /* BUSY, MSL, ADDR, TXE and TRA flags */ -#define I2C_EV6_MASTER_REC_MODE_SELECTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_ADDR)) /* BUSY, MSL and ADDR flags */ -/** @brief EV7 */ -#define I2C_EV7_MASTER_REC_BYTE_RECEIVED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_RXNE)) /* BUSY, MSL and RXNE flags */ -#define I2C_EV7_MASTER_REC_BYTE_QUEUED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_BTF|I2C_SR1_RXNE)) /* BUSY, MSL, RXNE and BTF flags*/ -/** @brief EV8 */ -#define I2C_EV8_MASTER_BYTE_TRANSMITTING ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY|I2C_SR2_TRA)<< 16)|I2C_SR1_TXE)) /* TRA, BUSY, MSL, TXE flags */ -/** @brief EV8_2 */ -#define I2C_EV8_2_MASTER_BYTE_TRANSMITTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY|I2C_SR2_TRA)<< 16)|I2C_SR1_BTF|I2C_SR1_TXE)) /* TRA, BUSY, MSL, TXE and BTF flags */ -/** @brief EV9 */ -#define I2C_EV9_MASTER_ADDR_10BIT ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_ADD10)) /* BUSY, MSL and ADD10 flags */ +#define I2C_EV5_MASTER_MODE_SELECT ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY) << 16) | I2C_SR1_SB)) /* BUSY, MSL and SB flag */ +#define I2C_EV8_2_MASTER_BYTE_TRANSMITTED ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA) << 16) | I2C_SR1_BTF | I2C_SR1_TXE)) /* TRA, BUSY, MSL, TXE and BTF flags */ #define I2C_EV_MASK 0x00FFFFFF /* First byte zeroed because there is no need of PEC register part from SR2 */ -#define I2C_FLG_1BTR 0x01 /* Single byte to be received and processed */ -#define I2C_FLG_2BTR 0x02 /* Two bytes to be received and processed */ -#define I2C_FLG_3BTR 0x04 /* Last three received bytes to be processed */ #define I2C_FLG_MASTER_RECEIVER 0x10 #define I2C_FLG_HEADER_SENT 0x80 -#define I2C_FLG_TIMER_ARMED 0x40 /* Used to check locks on the bus */ -#define EV6_SUBEV_MASK (I2C_FLG_1BTR|I2C_FLG_2BTR|I2C_FLG_MASTER_RECEIVER) -#define EV7_SUBEV_MASK (I2C_FLG_2BTR|I2C_FLG_3BTR|I2C_FLG_MASTER_RECEIVER) - -#define I2C_EV6_1_MASTER_REC_2BTR_MODE_SELECTED (I2C_FLG_2BTR|I2C_FLG_MASTER_RECEIVER) -#define I2C_EV6_3_MASTER_REC_1BTR_MODE_SELECTED (I2C_FLG_1BTR|I2C_FLG_MASTER_RECEIVER) -#define I2C_EV7_2_MASTER_REC_3BYTES_TO_PROCESS (I2C_FLG_3BTR|I2C_FLG_MASTER_RECEIVER) -#define I2C_EV7_3_MASTER_REC_2BYTES_TO_PROCESS (I2C_FLG_2BTR|I2C_FLG_MASTER_RECEIVER) /*===========================================================================*/ /* Driver data structures and types. */ @@ -141,9 +119,6 @@ typedef struct { i2copmode_t op_mode; /**< @brief Specifies the I2C mode.*/ uint32_t clock_speed; /**< @brief Specifies the clock frequency. Must be set to a value lower than 400kHz */ i2cdutycycle_t duty_cycle; /**< @brief Specifies the I2C fast mode duty cycle */ - uint8_t own_addr_7; /**< @brief Specifies the first device 7-bit own address. */ - uint16_t own_addr_10; /**< @brief Specifies the second part of device own address in 10-bit mode. Set to NULL if not used. */ - uint8_t nbit_own_addr; /**< @brief Specifies if 7-bit or 10-bit address is acknowledged */ } I2CConfig; @@ -186,47 +161,33 @@ struct I2CDriver{ /** * @brief Current configuration data. */ - const I2CConfig *id_config; + const I2CConfig *id_config; /** * @brief Current slave configuration data. */ - const I2CSlaveConfig *id_slave_config; + const I2CSlaveConfig *id_slave_config; - __IO size_t txbytes; /*!< @brief Number of bytes to be transmitted. */ - __IO size_t rxbytes; /*!< @brief Number of bytes to be received. */ - uint8_t *rxbuf; /*!< @brief Pointer to receive buffer. */ - uint8_t *txbuf; /*!< @brief Pointer to transmit buffer.*/ - uint8_t *rxbuff_p; /*!< @brief Pointer to the current byte in slave rx buffer. */ - uint8_t *txbuff_p; /*!< @brief Pointer to the current byte in slave tx buffer. */ + __IO size_t txbytes; /*!< @brief Number of bytes to be transmitted. */ + __IO size_t rxbytes; /*!< @brief Number of bytes to be received. */ + uint8_t *rxbuf; /*!< @brief Pointer to receive buffer. */ + uint8_t *txbuf; /*!< @brief Pointer to transmit buffer.*/ - __IO i2cflags_t errors; /*!< @brief Error flags.*/ - __IO i2cflags_t flags; /*!< @brief State flags.*/ + __IO i2cflags_t errors; /*!< @brief Error flags.*/ + __IO i2cflags_t flags; /*!< @brief State flags.*/ - uint16_t slave_addr; /*!< @brief Current slave address. */ - uint8_t slave_addr1;/*!< @brief 7-bit address of the slave with r\w bit.*/ - uint8_t slave_addr2;/*!< @brief Uses in 10-bit address mode. */ + uint8_t slave_addr; /*!< @brief Current slave address without R/W bit. */ #if CH_USE_EVENTS - EventSource sevent; /*!< @brief Status Change @p EventSource.*/ + EventSource sevent; /*!< @brief Status Change @p EventSource.*/ #endif /*********** End of the mandatory fields. **********************************/ - /** - * @brief DMA mode bit mask. - */ - uint32_t dmamode; - /** - * @brief Receive DMA channel. - */ - const stm32_dma_stream_t *dmarx; - /** - * @brief Transmit DMA channel. - */ - const stm32_dma_stream_t *dmatx; - /** - * @brief Pointer to the I2Cx registers block. - */ - I2C_TypeDef *id_i2c; + + uint32_t dmamode; /*!< @brief DMA mode bit mask.*/ + const stm32_dma_stream_t *dmarx; /*!< @brief Receive DMA channel.*/ + const stm32_dma_stream_t *dmatx; /*!< @brief Transmit DMA channel.*/ + + I2C_TypeDef *id_i2c; /*!< @brief Pointer to the I2Cx registers block. */ }; @@ -261,6 +222,10 @@ extern I2CDriver I2CD1; extern I2CDriver I2CD2; #endif +#if STM32_I2C_USE_I2C3 +extern I2CDriver I2CD3; +#endif + #ifdef __cplusplus extern "C" { #endif @@ -269,14 +234,12 @@ void i2c_lld_init(void); void i2c_lld_reset(I2CDriver *i2cp); void i2c_lld_set_clock(I2CDriver *i2cp); void i2c_lld_set_opmode(I2CDriver *i2cp); -void i2c_lld_set_own_address(I2CDriver *i2cp); void i2c_lld_start(I2CDriver *i2cp); void i2c_lld_stop(I2CDriver *i2cp); -void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr, +void i2c_lld_master_transmit(I2CDriver *i2cp, uint8_t slave_addr, uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes); -void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr, +void i2c_lld_master_receive(I2CDriver *i2cp, uint8_t slave_addr, uint8_t *rxbuf, size_t rxbytes); -void i2c_lld_master_transceive(I2CDriver *i2cp); #ifdef __cplusplus } diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c index 3add2af98..9f443be6c 100644 --- a/os/hal/src/i2c.c +++ b/os/hal/src/i2c.c @@ -73,8 +73,6 @@ void i2cObjectInit(I2CDriver *i2cp) { i2cp->id_state = I2C_STOP; i2cp->id_config = NULL; - i2cp->rxbuff_p = NULL; - i2cp->txbuff_p = NULL; i2cp->rxbuf = NULL; i2cp->txbuf = NULL; i2cp->id_slave_config = NULL; @@ -145,12 +143,12 @@ void i2cStop(I2CDriver *i2cp) { * paradigm. If you want transmit data without any further read, * than set @b rxbytes field to 0. * + * @details Number of receiving byts must be 0 or more than 1 because of stm32 + * hardware restrictions. + * * @param[in] i2cp pointer to the @p I2CDriver object * @param[in] i2cscfg pointer to the @p I2C slave config - * @param[in] slave_addr Slave device address. Bits 0-9 contain slave - * device address. Bit 15 must be set to 1 if 10-bit - * addressing mode used. Otherwise keep it cleared. - * Bits 10-14 unused. + * @param[in] slave_addr Slave device address (7 bits) without R/W bit * @param[in] txbuf pointer to transmit buffer * @param[in] txbytes number of bytes to be transmitted * @param[in] rxbuf pointer to receive buffer @@ -159,7 +157,7 @@ void i2cStop(I2CDriver *i2cp) { */ void i2cMasterTransmit(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg, - uint16_t slave_addr, + uint8_t slave_addr, uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, @@ -168,7 +166,8 @@ void i2cMasterTransmit(I2CDriver *i2cp, chDbgCheck((i2cp != NULL) && (i2cscfg != NULL) &&\ (slave_addr != 0) &&\ (txbytes > 0) &&\ - (txbuf != NULL), + (txbuf != NULL) &&\ + ((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL))), "i2cMasterTransmit"); /* init slave config field in driver */ @@ -183,28 +182,23 @@ void i2cMasterTransmit(I2CDriver *i2cp, i2cp->id_state = I2C_ACTIVE_TRANSMIT; i2c_lld_master_transmit(i2cp, slave_addr, txbuf, txbytes, rxbuf, rxbytes); -#if I2C_SUPPORTS_CALLBACKS _i2c_wait_s(i2cp); -#else - i2cp->id_state = I2C_READY; -#endif /* I2C_SUPPORTS_CALLBACKS */ } /** * @brief Receives data from the I2C bus. + * @details Number of receiving byts must be more than 1 because of stm32 + * hardware restrictions. * * @param[in] i2cp pointer to the @p I2CDriver object * @param[in] i2cscfg pointer to the @p I2C slave config - * @param[in] slave_addr Slave device address. Bits 0-9 contain slave - * device address. Bit 15 must be set to 1 if 10-bit - * addressing mode used. Otherwise keep it cleared. - * Bits 10-14 unused. + * @param[in] slave_addr slave device address (7 bits) without R/W bit * @param[in] rxbytes number of bytes to be received * @param[in] rxbuf pointer to receive buffer */ void i2cMasterReceive(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg, - uint16_t slave_addr, + uint8_t slave_addr, uint8_t *rxbuf, size_t rxbytes){ @@ -226,21 +220,9 @@ void i2cMasterReceive(I2CDriver *i2cp, i2cp->id_state = I2C_ACTIVE_RECEIVE; i2c_lld_master_receive(i2cp, slave_addr, rxbuf, rxbytes); -#if I2C_SUPPORTS_CALLBACKS _i2c_wait_s(i2cp); -#else - i2cp->id_state = I2C_READY; -#endif /* I2C_SUPPORTS_CALLBACKS */ } - -/* FIXME: I do not know what this function must do. And can not test it -uint16_t i2cSMBusAlertResponse(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg) { - i2cMasterReceive(i2cp, i2cscfg); - return i2cp->id_slave_config->slave_addr; -} -*/ - /** * @brief Handles communication events/errors. * @details Must be called from the I/O interrupt service routine in order to -- cgit v1.2.3 From e05d85d2bd73adbdde8174b5ed7edc564808ca5e Mon Sep 17 00:00:00 2001 From: barthess Date: Mon, 5 Dec 2011 17:17:52 +0000 Subject: I2C. Added startup functions for I2C1 and I2C3 interfaces. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3554 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/i2c_lld.c | 178 +++++++++++++++++++++++++++------------ 1 file changed, 123 insertions(+), 55 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index b49f4b588..78a2b334a 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -126,9 +126,11 @@ static uint32_t i2c_get_event(I2CDriver *i2cp){ } - - - +/** + * @brief I2C interrupts handler. + * + * @param[in] i2cp pointer to the @p I2CDriver object + */ static void i2c_serve_event_interrupt(I2CDriver *i2cp) { I2C_TypeDef *dp = i2cp->id_i2c; @@ -160,8 +162,11 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) { } - - +/** + * @brief DMA rx end IRQ handler. + * + * @param[in] i2cp pointer to the @p I2CDriver object + */ static void i2c_lld_serve_rx_end_irq(I2CDriver *i2cp){ dmaStreamDisable(i2cp->dmarx); @@ -173,16 +178,21 @@ static void i2c_lld_serve_rx_end_irq(I2CDriver *i2cp){ } - - - +/** + * @brief DMA tx enr IRQ handler. + * + * @param[in] i2cp pointer to the @p I2CDriver object + */ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp){ dmaStreamDisable(i2cp->dmatx); } - - +/** + * @brief I2C error handler. + * + * @param[in] i2cp pointer to the @p I2CDriver object + */ static void i2c_serve_error_interrupt(I2CDriver *i2cp) { i2cflags_t flags; I2C_TypeDef *reg; @@ -231,10 +241,23 @@ static void i2c_serve_error_interrupt(I2CDriver *i2cp) { } - - #if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__) -#error "Unrealized yet" +/** + * @brief I2C1 event interrupt handler. + */ +CH_IRQ_HANDLER(I2C1_EV_IRQHandler) { + CH_IRQ_PROLOGUE(); + i2c_serve_event_interrupt(&I2CD1); + CH_IRQ_EPILOGUE(); +} +/** + * @brief I2C1 error interrupt handler. + */ +CH_IRQ_HANDLER(I2C1_ER_IRQHandler) { + CH_IRQ_PROLOGUE(); + i2c_serve_error_interrupt(&I2CD1); + CH_IRQ_EPILOGUE(); +} #endif /* STM32_I2C_USE_I2C1 */ #if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__) @@ -257,19 +280,36 @@ CH_IRQ_HANDLER(I2C2_ER_IRQHandler) { #endif /* STM32_I2C_USE_I2C2 */ #if STM32_I2C_USE_I2C3 || defined(__DOXYGEN__) -#error "Unrealized yet" +/** + * @brief I2C3 event interrupt handler. + */ +CH_IRQ_HANDLER(I2C3_EV_IRQHandler) { + CH_IRQ_PROLOGUE(); + i2c_serve_event_interrupt(&I2CD3); + CH_IRQ_EPILOGUE(); +} +/** + * @brief I2C3 error interrupt handler. + */ +CH_IRQ_HANDLER(I2C3_ER_IRQHandler) { + CH_IRQ_PROLOGUE(); + i2c_serve_error_interrupt(&I2CD3); + CH_IRQ_EPILOGUE(); +} #endif /* STM32_I2C_USE_I2C3 */ - /** * @brief Low level I2C driver initialization. */ void i2c_lld_init(void) { #if STM32_I2C_USE_I2C1 -#error "Unrealized yet" -#endif /* STM32_I2C_USE_I2C */ + i2cObjectInit(&I2CD1); + I2CD1.id_i2c = I2C1; + I2CD1.dmarx = STM32_DMA_STREAM(STM32_I2C_I2C1_RX_DMA_STREAM); + I2CD1.dmatx = STM32_DMA_STREAM(STM32_I2C_I2C1_TX_DMA_STREAM); +#endif /* STM32_I2C_USE_I2C1 */ #if STM32_I2C_USE_I2C2 i2cObjectInit(&I2CD2); @@ -277,13 +317,14 @@ void i2c_lld_init(void) { I2CD2.dmarx = STM32_DMA_STREAM(STM32_I2C_I2C2_RX_DMA_STREAM); I2CD2.dmatx = STM32_DMA_STREAM(STM32_I2C_I2C2_TX_DMA_STREAM); #endif /* STM32_I2C_USE_I2C2 */ -} #if STM32_I2C_USE_I2C3 -#error "Unrealized yet" -#endif /* STM32_I2C_USE_I2C */ - - + i2cObjectInit(&I2CD3); + I2CD3.id_i2c = I2C3; + I2CD3.dmarx = STM32_DMA_STREAM(STM32_I2C_I2C3_RX_DMA_STREAM); + I2CD3.dmatx = STM32_DMA_STREAM(STM32_I2C_I2C3_TX_DMA_STREAM); +#endif /* STM32_I2C_USE_I2C3 */ +} /** @@ -296,15 +337,29 @@ void i2c_lld_start(I2CDriver *i2cp) { if (i2cp->id_state == I2C_STOP) { /* If in stopped state then enables the I2C clock.*/ #if STM32_I2C_USE_I2C1 -// if (&I2CD1 == i2cp) { -// NVICEnableVector(I2C1_EV_IRQn, -// CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); -// NVICEnableVector(I2C1_ER_IRQn, -// CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); -// rccEnableI2C1(FALSE); -// } -#error "Unrealized yet" -#endif + if (&I2CD1 == i2cp) { + + bool_t b; + b = dmaStreamAllocate(i2cp->dmarx, + STM32_I2C_I2C1_IRQ_PRIORITY, + (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, + (void *)i2cp); + chDbgAssert(!b, "uart_lld_start(), #3", "stream already allocated"); + b = dmaStreamAllocate(i2cp->dmatx, + STM32_I2C_I2C1_IRQ_PRIORITY, + (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, + (void *)i2cp); + chDbgAssert(!b, "uart_lld_start(), #4", "stream already allocated"); + rccEnableI2C1(FALSE); + NVICEnableVector(I2C1_EV_IRQn, + CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); + NVICEnableVector(I2C1_ER_IRQn, + CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); + + i2cp->dmamode |= STM32_DMA_CR_CHSEL(I2C1_RX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY); + } +#endif /* STM32_I2C_USE_I2C1 */ #if STM32_I2C_USE_I2C2 if (&I2CD2 == i2cp) { @@ -330,6 +385,32 @@ void i2c_lld_start(I2CDriver *i2cp) { STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY); } #endif /* STM32_I2C_USE_I2C2 */ + +#if STM32_I2C_USE_I2C3 + if (&I2CD3 == i2cp) { + + bool_t b; + b = dmaStreamAllocate(i2cp->dmarx, + STM32_I2C_I2C3_IRQ_PRIORITY, + (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, + (void *)i2cp); + chDbgAssert(!b, "uart_lld_start(), #3", "stream already allocated"); + b = dmaStreamAllocate(i2cp->dmatx, + STM32_I2C_I2C3_IRQ_PRIORITY, + (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, + (void *)i2cp); + chDbgAssert(!b, "uart_lld_start(), #4", "stream already allocated"); + rccEnableI2C3(FALSE); + NVICEnableVector(I2C3_EV_IRQn, + CORTEX_PRIORITY_MASK(STM32_I2C_I2C3_IRQ_PRIORITY)); + NVICEnableVector(I2C3_ER_IRQn, + CORTEX_PRIORITY_MASK(STM32_I2C_I2C3_IRQ_PRIORITY)); + + i2cp->dmamode |= STM32_DMA_CR_CHSEL(I2C3_RX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY); + } +#endif /* STM32_I2C_USE_I2C2 */ + } i2cp->dmamode |= STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE | @@ -346,20 +427,10 @@ void i2c_lld_start(I2CDriver *i2cp) { i2cp->id_i2c->CR1 |= 1; /* enable interface */ } -#if STM32_I2C_USE_I2C3 -// if (&I2CD1 == i2cp) { -// NVICEnableVector(I2C1_EV_IRQn, -// CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); -// NVICEnableVector(I2C1_ER_IRQn, -// CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); -// rccEnableI2C1(FALSE); -// } -#error "Unrealized yet" -#endif /* STM32_I2C_USE_I2C3 */ - - - +/** + * @brief Reset interface via RCC. + */ void i2c_lld_reset(I2CDriver *i2cp){ chDbgCheck((i2cp->id_state == I2C_STOP)||(i2cp->id_state == I2C_READY), "i2c_lld_reset: invalid state"); @@ -381,11 +452,14 @@ void i2c_lld_reset(I2CDriver *i2cp){ } - - - - - +/** + * @brief Receive data via the I2C bus as master. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] slave_addr slave device address + * @param[in] rxbuf pointer to the receive buffer + * @param[in] rxbytes number of bytes to be received + */ void i2c_lld_master_receive(I2CDriver *i2cp, uint8_t slave_addr, uint8_t *rxbuf, size_t rxbytes){ @@ -414,10 +488,6 @@ void i2c_lld_master_receive(I2CDriver *i2cp, uint8_t slave_addr, } - - - - /** * @brief Transmits data via the I2C bus as master. * @@ -458,8 +528,6 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, uint8_t slave_addr, } - - /** * @brief Set clock speed. * -- cgit v1.2.3 From 23d0cbc3b552533bf2b627e42aa55c82f5abc522 Mon Sep 17 00:00:00 2001 From: barthess Date: Tue, 6 Dec 2011 07:13:26 +0000 Subject: I2C. Added forgotten I2C3 interface git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3555 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/i2c_lld.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/i2c_lld.h b/os/hal/platforms/STM32/i2c_lld.h index 00eef923d..0e77dadb8 100644 --- a/os/hal/platforms/STM32/i2c_lld.h +++ b/os/hal/platforms/STM32/i2c_lld.h @@ -61,6 +61,15 @@ #define STM32_I2C_USE_I2C2 TRUE #endif +/** + * @brief I2C3 driver enable switch. + * @details If set to @p TRUE the support for I2C3 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_I2C_USE_I2C3) || defined(__DOXYGEN__) +#define STM32_I2C_USE_I2C3 TRUE +#endif + /** * @brief I2C1 interrupt priority level setting. * @note @p BASEPRI_KERNEL >= @p STM32_I2C_I2C1_IRQ_PRIORITY > @p PRIORITY_PENDSV. @@ -76,6 +85,14 @@ #if !defined(STM32_I2C_I2C2_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_I2C_I2C2_IRQ_PRIORITY 0xA0 #endif + +/** + * @brief I2C2 interrupt priority level setting. + * @note @p BASEPRI_KERNEL >= @p STM32_I2C_I2C2_IRQ_PRIORITY > @p PRIORITY_PENDSV. + */ +#if !defined(STM32_I2C_I2C3_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_I2C_I2C3_IRQ_PRIORITY 0xA0 +#endif /** @} */ /*===========================================================================*/ -- cgit v1.2.3 From dbee267868ee52517dd465aee0078619dc68f584 Mon Sep 17 00:00:00 2001 From: barthess Date: Tue, 6 Dec 2011 09:08:26 +0000 Subject: I2C. Added support of stm32f1x. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3557 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/i2c_lld.h | 176 ++++++++++++++++++++++++++++-- os/hal/platforms/STM32F1xx/hal_lld_f103.h | 16 +++ 2 files changed, 183 insertions(+), 9 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/i2c_lld.h b/os/hal/platforms/STM32/i2c_lld.h index 0e77dadb8..f57bead5f 100644 --- a/os/hal/platforms/STM32/i2c_lld.h +++ b/os/hal/platforms/STM32/i2c_lld.h @@ -46,28 +46,28 @@ /** * @brief I2C1 driver enable switch. * @details If set to @p TRUE the support for I2C1 is included. - * @note The default is @p TRUE. + * @note The default is @p FALSE. */ #if !defined(STM32_I2C_USE_I2C1) || defined(__DOXYGEN__) -#define STM32_I2C_USE_I2C1 TRUE +#define STM32_I2C_USE_I2C1 FALSE #endif /** * @brief I2C2 driver enable switch. * @details If set to @p TRUE the support for I2C2 is included. - * @note The default is @p TRUE. + * @note The default is @p FALSE. */ #if !defined(STM32_I2C_USE_I2C2) || defined(__DOXYGEN__) -#define STM32_I2C_USE_I2C2 TRUE +#define STM32_I2C_USE_I2C2 FALSE #endif /** * @brief I2C3 driver enable switch. * @details If set to @p TRUE the support for I2C3 is included. - * @note The default is @p TRUE. + * @note The default is @p FALSE. */ #if !defined(STM32_I2C_USE_I2C3) || defined(__DOXYGEN__) -#define STM32_I2C_USE_I2C3 TRUE +#define STM32_I2C_USE_I2C3 FALSE #endif /** @@ -93,21 +93,179 @@ #if !defined(STM32_I2C_I2C3_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_I2C_I2C3_IRQ_PRIORITY 0xA0 #endif + +/** + * @brief I2C1 DMA error hook. + * @note The default action for DMA errors is a system halt because DMA + * error can only happen because programming errors. + */ +#if !defined(STM32_I2C_DMA_ERROR_HOOK) || defined(__DOXYGEN__) +#define STM32_I2C_DMA_ERROR_HOOK(uartp) chSysHalt() +#endif + +#if STM32_ADVANCED_DMA || defined(__DOXYGEN__) + +/** + * @brief DMA stream used for I2C1 RX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_I2C_I2C1_RX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) +#endif + +/** + * @brief DMA stream used for I2C1 TX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_I2C_I2C1_TX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#endif + +/** + * @brief DMA stream used for I2C2 RX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_I2C_I2C2_RX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#endif + +/** + * @brief DMA stream used for I2C2 TX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_I2C_I2C2_TX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#endif + +/** + * @brief DMA stream used for I2C3 RX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_I2C_I2C3_RX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#endif + +/** + * @brief DMA stream used for I2C3 TX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_I2C_I2C3_TX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#endif + +#else /* !STM32_ADVANCED_DMA */ + +/* Fixed streams for platforms using the old DMA peripheral, the values are + valid for both STM32F1xx and STM32L1xx.*/ +#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#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) + +#endif /* !STM32_ADVANCED_DMA*/ /** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ -/** @brief EV5 */ +/** @brief flags for interrupt handling */ #define I2C_EV5_MASTER_MODE_SELECT ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY) << 16) | I2C_SR1_SB)) /* BUSY, MSL and SB flag */ #define I2C_EV8_2_MASTER_BYTE_TRANSMITTED ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA) << 16) | I2C_SR1_BTF | I2C_SR1_TXE)) /* TRA, BUSY, MSL, TXE and BTF flags */ #define I2C_EV_MASK 0x00FFFFFF /* First byte zeroed because there is no need of PEC register part from SR2 */ -#define I2C_FLG_MASTER_RECEIVER 0x10 -#define I2C_FLG_HEADER_SENT 0x80 +#define I2C_FLG_MASTER_RECEIVER 0x10 +#define I2C_FLG_HEADER_SENT 0x80 + +#if STM32_I2C_USE_I2C1 && !STM32_HAS_I2C1 +#error "I2C1 not present in the selected device" +#endif + +#if STM32_I2C_USE_I2C2 && !STM32_HAS_I2C2 +#error "I2C2 not present in the selected device" +#endif + +#if STM32_I2C_USE_I2C3 && !STM32_HAS_I2C3 +#error "I2C3 not present in the selected device" +#endif + +#if !STM32_I2C_USE_I2C1 && !STM32_I2C_USE_I2C2 && \ + !STM32_I2C_USE_I2C3 +#error "I2C driver activated but no I2C peripheral assigned" +#endif + + + + + + + + + + + + + +#if STM32_I2C_USE_I2C1 && \ + !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_RX_DMA_STREAM, \ + STM32_I2C1_RX_DMA_MSK) +#error "invalid DMA stream associated to USART1 RX" +#endif + +#if STM32_I2C_USE_I2C1 && \ + !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_TX_DMA_STREAM, \ + STM32_I2C1_TX_DMA_MSK) +#error "invalid DMA stream associated to USART1 TX" +#endif + +#if STM32_I2C_USE_I2C2 && \ + !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_RX_DMA_STREAM, \ + STM32_I2C2_RX_DMA_MSK) +#error "invalid DMA stream associated to USART2 RX" +#endif + +#if STM32_I2C_USE_I2C2 && \ + !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_TX_DMA_STREAM, \ + STM32_I2C2_TX_DMA_MSK) +#error "invalid DMA stream associated to USART2 TX" +#endif + +#if STM32_I2C_USE_I2C3 && \ + !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_RX_DMA_STREAM, \ + STM32_I2C3_RX_DMA_MSK) +#error "invalid DMA stream associated to USART3 RX" +#endif + +#if STM32_I2C_USE_I2C3 && \ + !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_TX_DMA_STREAM, \ + STM32_I2C3_TX_DMA_MSK) +#error "invalid DMA stream associated to USART3 TX" +#endif + + + + + + + + + + + + + + + + + + + +#if !defined(STM32_DMA_REQUIRED) +#define STM32_DMA_REQUIRED +#endif + /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f103.h b/os/hal/platforms/STM32F1xx/hal_lld_f103.h index 22d955c65..d251e6a5d 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f103.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f103.h @@ -306,8 +306,24 @@ /* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_I2C1_RX_DMA_CHN 0x00000000 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_I2C1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_I2C2 TRUE +#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C2_RX_DMA_CHN 0x00000000 +#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_I2C2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_I2C3 FALSE +#define STM32_I2C3_RX_DMA_MSK 0 +#define STM32_I2C3_RX_DMA_CHN 0x00000000 +#define STM32_I2C3_TX_DMA_MSK 0 +#define STM32_I2C3_TX_DMA_CHN 0x00000000 + + /* RTC attributes.*/ #define STM32_HAS_RTC TRUE -- cgit v1.2.3 From 6777c09f08b8c20f67879a59aaefc588bb6e7371 Mon Sep 17 00:00:00 2001 From: barthess Date: Tue, 6 Dec 2011 13:37:08 +0000 Subject: I2C. Added checks. Cleaned copypaste errors. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3559 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/i2c_lld.c | 5 +++-- os/hal/platforms/STM32/i2c_lld.h | 14 -------------- 2 files changed, 3 insertions(+), 16 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index 78a2b334a..3b8650dde 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -356,8 +356,9 @@ void i2c_lld_start(I2CDriver *i2cp) { NVICEnableVector(I2C1_ER_IRQn, CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); - i2cp->dmamode |= STM32_DMA_CR_CHSEL(I2C1_RX_DMA_CHANNEL) | - STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY); + i2cp->dmamode |= STM32_DMA_CR_CHSEL(I2C1_RX_DMA_CHANNEL) | \ + STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY); + __NOP(); } #endif /* STM32_I2C_USE_I2C1 */ diff --git a/os/hal/platforms/STM32/i2c_lld.h b/os/hal/platforms/STM32/i2c_lld.h index f57bead5f..b2b346c7d 100644 --- a/os/hal/platforms/STM32/i2c_lld.h +++ b/os/hal/platforms/STM32/i2c_lld.h @@ -194,20 +194,6 @@ #error "I2C driver activated but no I2C peripheral assigned" #endif - - - - - - - - - - - - - - #if STM32_I2C_USE_I2C1 && \ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_RX_DMA_STREAM, \ STM32_I2C1_RX_DMA_MSK) -- cgit v1.2.3 From 2db3c769f1abba36a1e7a843d83e5006de58cbd5 Mon Sep 17 00:00:00 2001 From: barthess Date: Tue, 6 Dec 2011 18:09:34 +0000 Subject: I2C. Bug fixes. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3562 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/i2c_lld.c | 22 ++++++++++++++--- os/hal/platforms/STM32/i2c_lld.h | 47 +++++++++++------------------------- os/hal/platforms/STM32F4xx/hal_lld.h | 11 +++++---- os/hal/src/i2c.c | 1 - 4 files changed, 38 insertions(+), 43 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index 3b8650dde..d843591e1 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -141,6 +141,16 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) { dp->DR = i2cp->slave_addr; break; + case I2C_EV6_MASTER_REC_MODE_SELECTED: + dmaStreamEnable(i2cp->dmarx); + i2cp->id_i2c->CR2 |= I2C_CR2_DMAEN | I2C_CR2_LAST; + break; + + case I2C_EV6_MASTER_TRA_MODE_SELECTED: + dmaStreamEnable(i2cp->dmatx); + i2cp->id_i2c->CR2 |= I2C_CR2_DMAEN | I2C_CR2_LAST; + break; + case I2C_EV8_2_MASTER_BYTE_TRANSMITTED: /* catch BTF event after the end of trasmission */ if (i2cp->rxbytes > 1){ @@ -197,6 +207,14 @@ static void i2c_serve_error_interrupt(I2CDriver *i2cp) { i2cflags_t flags; I2C_TypeDef *reg; + chSysLockFromIsr(); + /* clear interrupt falgs just to be safe */ + dmaStreamClearInterrupt(i2cp->dmatx); + dmaStreamClearInterrupt(i2cp->dmarx); + dmaStreamDisable(i2cp->dmatx); + dmaStreamDisable(i2cp->dmarx); + chSysUnlockFromIsr(); + reg = i2cp->id_i2c; flags = I2CD_NO_ERROR; @@ -481,9 +499,7 @@ void i2c_lld_master_receive(I2CDriver *i2cp, uint8_t slave_addr, dmaStreamSetMemory0(i2cp->dmarx, rxbuf); dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes); dmaStreamSetMode(i2cp->dmarx, ((i2cp->dmamode) | mode)); - dmaStreamEnable(i2cp->dmarx); - i2cp->id_i2c->CR2 |= I2C_CR2_DMAEN | I2C_CR2_LAST; i2cp->id_i2c->CR2 |= I2C_CR2_ITERREN | I2C_CR2_ITEVTEN; i2cp->id_i2c->CR1 |= I2C_CR1_START | I2C_CR1_ACK; } @@ -521,9 +537,7 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, uint8_t slave_addr, dmaStreamSetMemory0(i2cp->dmatx, txbuf); dmaStreamSetTransactionSize(i2cp->dmatx, txbytes); dmaStreamSetMode(i2cp->dmatx, ((i2cp->dmamode) | mode)); - dmaStreamEnable(i2cp->dmatx); - i2cp->id_i2c->CR2 |= I2C_CR2_DMAEN | I2C_CR2_LAST; i2cp->id_i2c->CR2 |= I2C_CR2_ITERREN | I2C_CR2_ITEVTEN; i2cp->id_i2c->CR1 |= I2C_CR1_START; } diff --git a/os/hal/platforms/STM32/i2c_lld.h b/os/hal/platforms/STM32/i2c_lld.h index b2b346c7d..2ca6b872a 100644 --- a/os/hal/platforms/STM32/i2c_lld.h +++ b/os/hal/platforms/STM32/i2c_lld.h @@ -171,12 +171,15 @@ /** @brief flags for interrupt handling */ #define I2C_EV5_MASTER_MODE_SELECT ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY) << 16) | I2C_SR1_SB)) /* BUSY, MSL and SB flag */ +#define I2C_EV6_MASTER_TRA_MODE_SELECTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY|I2C_SR2_TRA)<< 16)|I2C_SR1_ADDR|I2C_SR1_TXE)) /* BUSY, MSL, ADDR, TXE and TRA flags */ +#define I2C_EV6_MASTER_REC_MODE_SELECTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_ADDR)) /* BUSY, MSL and ADDR flags */ #define I2C_EV8_2_MASTER_BYTE_TRANSMITTED ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA) << 16) | I2C_SR1_BTF | I2C_SR1_TXE)) /* TRA, BUSY, MSL, TXE and BTF flags */ #define I2C_EV_MASK 0x00FFFFFF /* First byte zeroed because there is no need of PEC register part from SR2 */ #define I2C_FLG_MASTER_RECEIVER 0x10 #define I2C_FLG_HEADER_SENT 0x80 +/** @brief error checks */ #if STM32_I2C_USE_I2C1 && !STM32_HAS_I2C1 #error "I2C1 not present in the selected device" #endif @@ -197,57 +200,39 @@ #if STM32_I2C_USE_I2C1 && \ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_RX_DMA_STREAM, \ STM32_I2C1_RX_DMA_MSK) -#error "invalid DMA stream associated to USART1 RX" +#error "invalid DMA stream associated to I2C1 RX" #endif #if STM32_I2C_USE_I2C1 && \ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_TX_DMA_STREAM, \ STM32_I2C1_TX_DMA_MSK) -#error "invalid DMA stream associated to USART1 TX" +#error "invalid DMA stream associated to I2C1 TX" #endif #if STM32_I2C_USE_I2C2 && \ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_RX_DMA_STREAM, \ STM32_I2C2_RX_DMA_MSK) -#error "invalid DMA stream associated to USART2 RX" +#error "invalid DMA stream associated to I2C2 RX" #endif #if STM32_I2C_USE_I2C2 && \ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_TX_DMA_STREAM, \ STM32_I2C2_TX_DMA_MSK) -#error "invalid DMA stream associated to USART2 TX" +#error "invalid DMA stream associated to I2C2 TX" #endif #if STM32_I2C_USE_I2C3 && \ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_RX_DMA_STREAM, \ STM32_I2C3_RX_DMA_MSK) -#error "invalid DMA stream associated to USART3 RX" +#error "invalid DMA stream associated to I2C3 RX" #endif #if STM32_I2C_USE_I2C3 && \ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_TX_DMA_STREAM, \ STM32_I2C3_TX_DMA_MSK) -#error "invalid DMA stream associated to USART3 TX" +#error "invalid DMA stream associated to I2C3 TX" #endif - - - - - - - - - - - - - - - - - - #if !defined(STM32_DMA_REQUIRED) #define STM32_DMA_REQUIRED #endif @@ -300,22 +285,22 @@ struct I2CDriver{ /** * @brief Driver state. */ - i2cstate_t id_state; + i2cstate_t id_state; #if I2C_USE_WAIT /** * @brief Thread waiting for I/O completion. */ - Thread *id_thread; + Thread *id_thread; #endif /* I2C_USE_WAIT */ #if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) #if CH_USE_MUTEXES || defined(__DOXYGEN__) /** * @brief Mutex protecting the bus. */ - Mutex id_mutex; + Mutex id_mutex; #elif CH_USE_SEMAPHORES - Semaphore id_semaphore; + Semaphore id_semaphore; #endif #endif /* I2C_USE_MUTUAL_EXCLUSION */ @@ -338,17 +323,13 @@ struct I2CDriver{ uint8_t slave_addr; /*!< @brief Current slave address without R/W bit. */ -#if CH_USE_EVENTS - EventSource sevent; /*!< @brief Status Change @p EventSource.*/ -#endif - /*********** End of the mandatory fields. **********************************/ uint32_t dmamode; /*!< @brief DMA mode bit mask.*/ const stm32_dma_stream_t *dmarx; /*!< @brief Receive DMA channel.*/ const stm32_dma_stream_t *dmatx; /*!< @brief Transmit DMA channel.*/ - I2C_TypeDef *id_i2c; /*!< @brief Pointer to the I2Cx registers block. */ + I2C_TypeDef *id_i2c; /*!< @brief Pointer to the I2Cx registers block. */ }; diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index 1310738d4..577e37834 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -292,15 +292,16 @@ /* 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_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)) +#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 0x10000000 #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_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 diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c index 9f443be6c..4b9160a68 100644 --- a/os/hal/src/i2c.c +++ b/os/hal/src/i2c.c @@ -238,7 +238,6 @@ void i2cAddFlagsI(I2CDriver *i2cp, i2cflags_t mask) { chDbgCheck(i2cp != NULL, "i2cAddFlagsI"); i2cp->errors |= mask; - chEvtBroadcastI(&i2cp->sevent); } /** -- cgit v1.2.3 From 80043ff2a01e97bacf9b2f30833b196e031cb20d Mon Sep 17 00:00:00 2001 From: barthess Date: Wed, 7 Dec 2011 05:44:33 +0000 Subject: I2C. Minor code improvements. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3564 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/i2c.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h index 18e93119e..1923742c7 100644 --- a/os/hal/include/i2c.h +++ b/os/hal/include/i2c.h @@ -211,8 +211,9 @@ struct I2CSlaveConfig{ ((i2cp)->id_slave_config)->id_callback(i2cp, i2cscfg); \ (i2cp)->id_state = I2C_READY; \ } \ - else \ + else{ \ (i2cp)->id_state = I2C_READY; \ + } \ _i2c_wakeup_isr(i2cp); \ } @@ -236,8 +237,9 @@ struct I2CSlaveConfig{ ((i2cp)->id_slave_config)->id_err_callback(i2cp, i2cscfg); \ (i2cp)->id_state = I2C_READY; \ } \ - else \ + else{ \ (i2cp)->id_state = I2C_READY; \ + } \ _i2c_wakeup_isr(i2cp); \ } -- cgit v1.2.3 From 46d388fb246bbba56f75e15a0514376580c0c2fb Mon Sep 17 00:00:00 2001 From: barthess Date: Wed, 7 Dec 2011 07:52:42 +0000 Subject: I2C. Added DMA masks for other MCUs. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3565 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F1xx/hal_lld_f100.h | 14 ++++++++++++++ os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h | 14 ++++++++++++++ os/hal/platforms/STM32F2xx/hal_lld.h | 19 +++++++++++++++++++ os/hal/platforms/STM32L1xx/hal_lld.h | 14 ++++++++++++++ 4 files changed, 61 insertions(+) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f100.h b/os/hal/platforms/STM32F1xx/hal_lld_f100.h index 3f5d9502b..96f5a7f33 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f100.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f100.h @@ -295,8 +295,22 @@ /* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_I2C1_RX_DMA_CHN 0x00000000 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_I2C1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_I2C2 TRUE +#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C2_RX_DMA_CHN 0x00000000 +#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_I2C2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_I2C3 FALSE +#define STM32_I2C3_RX_DMA_MSK 0 +#define STM32_I2C3_RX_DMA_CHN 0x00000000 +#define STM32_I2C3_TX_DMA_MSK 0 +#define STM32_I2C3_TX_DMA_CHN 0x00000000 /* RTC attributes.*/ #define STM32_HAS_RTC TRUE diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h index 882ec6094..9a612b0ee 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h @@ -166,8 +166,22 @@ /* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_I2C1_RX_DMA_CHN 0x00000000 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_I2C1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_I2C2 TRUE +#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C2_RX_DMA_CHN 0x00000000 +#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_I2C2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_I2C3 FALSE +#define STM32_I2C3_RX_DMA_MSK 0 +#define STM32_I2C3_RX_DMA_CHN 0x00000000 +#define STM32_I2C3_TX_DMA_MSK 0 +#define STM32_I2C3_TX_DMA_CHN 0x00000000 /* RTC attributes.*/ #define STM32_HAS_RTC TRUE diff --git a/os/hal/platforms/STM32F2xx/hal_lld.h b/os/hal/platforms/STM32F2xx/hal_lld.h index 91135950f..cad926330 100644 --- a/os/hal/platforms/STM32F2xx/hal_lld.h +++ b/os/hal/platforms/STM32F2xx/hal_lld.h @@ -157,8 +157,27 @@ #define STM32_HAS_GPIOH TRUE #define STM32_HAS_GPIOI TRUE +/* 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 0x10000000 + #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_RTC TRUE diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index b25bad51d..8d6cfd6f0 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -198,8 +198,22 @@ /* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_I2C1_RX_DMA_CHN 0x00000000 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_I2C1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_I2C2 TRUE +#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C2_RX_DMA_CHN 0x00000000 +#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_I2C2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_I2C3 FALSE +#define STM32_I2C3_RX_DMA_MSK 0 +#define STM32_I2C3_RX_DMA_CHN 0x00000000 +#define STM32_I2C3_TX_DMA_MSK 0 +#define STM32_I2C3_TX_DMA_CHN 0x00000000 /* RTC attributes.*/ #define STM32_HAS_RTC TRUE -- cgit v1.2.3 From 6562e684cd3942eb0273a13bd6c8b7027a868745 Mon Sep 17 00:00:00 2001 From: barthess Date: Wed, 7 Dec 2011 12:23:33 +0000 Subject: GPT on F4x. Typo fixed. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3566 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/gpt_lld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/gpt_lld.c b/os/hal/platforms/STM32/gpt_lld.c index e40843ccb..34468ccc3 100644 --- a/os/hal/platforms/STM32/gpt_lld.c +++ b/os/hal/platforms/STM32/gpt_lld.c @@ -249,7 +249,7 @@ void gpt_lld_init(void) { #if STM32_GPT_USE_TIM8 /* Driver initialization.*/ - GPTD5.tim = STM32_TIM8; + GPTD8.tim = STM32_TIM8; gptObjectInit(&GPTD8); #endif } -- cgit v1.2.3 From 11ed726e41afe47beace358939d44118ece4661e Mon Sep 17 00:00:00 2001 From: barthess Date: Wed, 7 Dec 2011 12:30:52 +0000 Subject: GPT on F4x. MCU has TIM6 and TIM7, fixed. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3567 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/hal_lld.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index 577e37834..061ce1304 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -347,8 +347,8 @@ #define STM32_HAS_TIM3 TRUE #define STM32_HAS_TIM4 TRUE #define STM32_HAS_TIM5 TRUE -#define STM32_HAS_TIM6 FALSE -#define STM32_HAS_TIM7 FALSE +#define STM32_HAS_TIM6 TRUE +#define STM32_HAS_TIM7 TRUE #define STM32_HAS_TIM8 TRUE #define STM32_HAS_TIM9 TRUE #define STM32_HAS_TIM10 TRUE -- cgit v1.2.3 From ac8123d2da74ac0bb6cb2d968bf79fe48905ad87 Mon Sep 17 00:00:00 2001 From: barthess Date: Wed, 7 Dec 2011 14:13:57 +0000 Subject: I2C. Added note about different API classes usage. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3569 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/i2c_lld.c | 47 ++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 9 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index d843591e1..f3291f819 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -43,6 +43,30 @@ * Otherwise there is a risk of setting a second STOP, START or PEC request. */ +/*===========================================================================*/ +/* Knowledge base. */ +/*===========================================================================*/ +/* +Not all system functions are usable in a given context. + +The most restrictive type are the i-class, an I-class function is a function that must: +- Not access the "current" thread in any way (from an ISR the current thread +is random so it is meaningless). +- Not reschedule internally (from an ISR the reschedule is done at the end of +the ISR chain, rescheduling from within an ISR is forbidden because would +leave the IRQ stack not empty with all kind of funny consequences. +- Not try to change state for the current thread. +- Must be invoked between a lock() and an unlock() but never lock/unlock internally. + +A bit less restrictive are the S-class that must simply: +- Be invoked between a lock() and an unlock() but never lock/unlock internally. +S-class can reschedule internally, access the current thread implicitly and +also change state so are not eligible for ISR context. + +Normal functions can be invoked from thread context only but have no internal +restrictions. +*/ + /*===========================================================================*/ /* Driver local definitions. */ /*===========================================================================*/ @@ -155,12 +179,12 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) { /* catch BTF event after the end of trasmission */ if (i2cp->rxbytes > 1){ /* start "read after write" operation */ - i2c_lld_master_receive(i2cp, (i2cp->slave_addr >> 1), i2cp->rxbuf, i2cp->rxbytes); + i2c_lld_master_receive(i2cp, (i2cp->slave_addr >> 1), + i2cp->rxbuf, i2cp->rxbytes); return; } else i2cp->id_i2c->CR1 |= I2C_CR1_STOP; - // FIXME: change this polling to something else while(i2cp->id_i2c->CR1 & I2C_CR1_STOP) ; _i2c_isr_code(i2cp, i2cp->id_slave_config); @@ -181,7 +205,6 @@ static void i2c_lld_serve_rx_end_irq(I2CDriver *i2cp){ dmaStreamDisable(i2cp->dmarx); i2cp->id_i2c->CR1 |= I2C_CR1_STOP; - // FIXME: change this polling to something else while(i2cp->id_i2c->CR1 & I2C_CR1_STOP) ; _i2c_isr_code(i2cp, i2cp->id_slave_config); @@ -209,10 +232,10 @@ static void i2c_serve_error_interrupt(I2CDriver *i2cp) { chSysLockFromIsr(); /* clear interrupt falgs just to be safe */ - dmaStreamClearInterrupt(i2cp->dmatx); - dmaStreamClearInterrupt(i2cp->dmarx); dmaStreamDisable(i2cp->dmatx); dmaStreamDisable(i2cp->dmarx); + dmaStreamClearInterrupt(i2cp->dmatx); + dmaStreamClearInterrupt(i2cp->dmarx); chSysUnlockFromIsr(); reg = i2cp->id_i2c; @@ -344,13 +367,13 @@ void i2c_lld_init(void) { #endif /* STM32_I2C_USE_I2C3 */ } - /** * @brief Configures and activates the I2C peripheral. * * @param[in] i2cp pointer to the @p I2CDriver object */ void i2c_lld_start(I2CDriver *i2cp) { + i2cp->dmamode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; if (i2cp->id_state == I2C_STOP) { /* If in stopped state then enables the I2C clock.*/ @@ -641,15 +664,21 @@ void i2c_lld_set_opmode(I2CDriver *i2cp) { } - - /** * @brief Deactivates the I2C peripheral. * * @param[in] i2cp pointer to the @p I2CDriver object */ void i2c_lld_stop(I2CDriver *i2cp) { - if (i2cp->id_state == I2C_READY) { /* If in ready state then disables the I2C clock.*/ + + if (i2cp->id_state != I2C_STOP) { /* If in ready state then disables the I2C clock.*/ + + dmaStreamDisable(i2cp->dmatx); + dmaStreamDisable(i2cp->dmarx); + dmaStreamClearInterrupt(i2cp->dmatx); + dmaStreamClearInterrupt(i2cp->dmarx); + dmaStreamRelease(i2cp->dmatx); + dmaStreamRelease(i2cp->dmarx); #if STM32_I2C_USE_I2C1 if (&I2CD1 == i2cp) { -- cgit v1.2.3 From 0738591b023a4e2c6cacebadebfef08aafea4d6e Mon Sep 17 00:00:00 2001 From: barthess Date: Wed, 7 Dec 2011 17:57:42 +0000 Subject: I2C. Switch to synchronous model. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3570 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/i2c.h | 85 +++------------------------------------- os/hal/platforms/STM32/i2c_lld.c | 36 +++++++++-------- os/hal/platforms/STM32/i2c_lld.h | 15 +------ os/hal/src/i2c.c | 21 +--------- 4 files changed, 29 insertions(+), 128 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h index 1923742c7..8cfd97e75 100644 --- a/os/hal/include/i2c.h +++ b/os/hal/include/i2c.h @@ -66,13 +66,6 @@ #define I2C_USE_MUTUAL_EXCLUSION TRUE #endif -/** - * @brief Enables the mutual exclusion APIs on the I2C bus. - */ -#if !defined(I2C_USE_WAIT) || defined(__DOXYGEN__) -#define I2C_USE_WAIT TRUE -#endif - /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ @@ -98,57 +91,11 @@ typedef enum { #include "i2c_lld.h" -/** - * @brief I2C notification callback type. - * @details This callback invoked when byte transfer finish event occurs, - * no matter if sending or reading. - * - * @param[in] i2cp pointer to the @p I2CDriver object triggering the - * callback - * @param[in] i2cscfg pointer to the @p I2CSlaveConfig object triggering the - * callback - */ -typedef void (*i2ccallback_t)(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg); - -/** - * @brief I2C error notification callback type. - * - * @param[in] i2cp pointer to the @p I2CDriver object triggering the - * callback - * @param[in] i2cscfg pointer to the @p I2CSlaveConfig object triggering the - * callback - */ -typedef void (*i2cerrorcallback_t)(I2CDriver *i2cp, - const I2CSlaveConfig *i2cscfg); - -/** - * @brief Structure representing an I2C slave configuration. - * @details Each slave device has its own config structure with input and - * output buffers for temporally storing data. - */ -struct I2CSlaveConfig{ - /** - * @brief Callback pointer. - * @note Transfer finished callback. Invoke when all data transferred. - * If set to @p NULL then the callback is disabled. - */ - i2ccallback_t id_callback; - /** - * @brief Callback pointer. - * @note This callback will be invoked when error condition occur. - * If set to @p NULL then the callback is disabled. - */ - i2cerrorcallback_t id_err_callback; -#if defined(I2C_SLAVECONFIG_EXT_FIELDS) - I2C_SLAVECONFIG_EXT_FIELDS -#endif -}; /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ -#if I2C_USE_WAIT || defined(__DOXYGEN__) /** * @brief Waits for operation completion. * @details This function waits for the driver to complete the current @@ -186,60 +133,40 @@ struct I2CSlaveConfig{ chSysUnlockFromIsr(); \ } \ } -#else /* !I2C_USE_WAIT */ -#define _i2c_wait_s(i2cp) -#define _i2c_wakeup_isr(i2cp) -#endif /* !I2C_USE_WAIT */ /** * @brief Common ISR code. * @details This code handles the portable part of the ISR code: - * - Callback invocation. - * - Waiting thread wakeup, if any. + * - Waiting thread wakeup. * - Driver state transitions. * * @note This macro is meant to be used in the low level drivers * implementation only. * * @param[in] i2cp pointer to the @p I2CDriver object - * @param[in] i2cscfg pointer to the @p I2CSlaveConfig object * * @notapi */ #define _i2c_isr_code(i2cp, i2cscfg) { \ - if(((i2cp)->id_slave_config)->id_callback) { \ - ((i2cp)->id_slave_config)->id_callback(i2cp, i2cscfg); \ - (i2cp)->id_state = I2C_READY; \ - } \ - else{ \ - (i2cp)->id_state = I2C_READY; \ - } \ + (i2cp)->id_state = I2C_READY; \ _i2c_wakeup_isr(i2cp); \ } /** * @brief Error ISR code. * @details This code handles the portable part of the ISR code: - * - Error callback invocation. - * - Waiting thread wakeup, if any. + * - Waiting thread wakeup. * - Driver state transitions. * * @note This macro is meant to be used in the low level drivers * implementation only. * * @param[in] i2cp pointer to the @p I2CDriver object - * @param[in] i2cscfg pointer to the @p I2CSlaveConfig object * * @notapi */ #define _i2c_isr_err_code(i2cp, i2cscfg) { \ - if(((i2cp)->id_slave_config)->id_err_callback) { \ - ((i2cp)->id_slave_config)->id_err_callback(i2cp, i2cscfg); \ - (i2cp)->id_state = I2C_READY; \ - } \ - else{ \ - (i2cp)->id_state = I2C_READY; \ - } \ + (i2cp)->id_state = I2C_READY; \ _i2c_wakeup_isr(i2cp); \ } @@ -254,11 +181,11 @@ extern "C" { void i2cObjectInit(I2CDriver *i2cp); void i2cStart(I2CDriver *i2cp, const I2CConfig *config); void i2cStop(I2CDriver *i2cp); - void i2cMasterTransmit(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg, + void i2cMasterTransmit(I2CDriver *i2cp, uint8_t slave_addr, uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes); - void i2cMasterReceive(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg, + void i2cMasterReceive(I2CDriver *i2cp, uint8_t slave_addr, uint8_t *rxbuf, size_t rxbytes); void i2cMasterStart(I2CDriver *i2cp); void i2cMasterStop(I2CDriver *i2cp); diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index f3291f819..1345c847b 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -185,8 +185,6 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) { } else i2cp->id_i2c->CR1 |= I2C_CR1_STOP; - while(i2cp->id_i2c->CR1 & I2C_CR1_STOP) - ; _i2c_isr_code(i2cp, i2cp->id_slave_config); break; @@ -205,8 +203,6 @@ static void i2c_lld_serve_rx_end_irq(I2CDriver *i2cp){ dmaStreamDisable(i2cp->dmarx); i2cp->id_i2c->CR1 |= I2C_CR1_STOP; - while(i2cp->id_i2c->CR1 & I2C_CR1_STOP) - ; _i2c_isr_code(i2cp, i2cp->id_slave_config); } @@ -227,7 +223,7 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp){ * @param[in] i2cp pointer to the @p I2CDriver object */ static void i2c_serve_error_interrupt(I2CDriver *i2cp) { - i2cflags_t flags; + i2cflags_t errors; I2C_TypeDef *reg; chSysLockFromIsr(); @@ -239,43 +235,41 @@ static void i2c_serve_error_interrupt(I2CDriver *i2cp) { chSysUnlockFromIsr(); reg = i2cp->id_i2c; - flags = I2CD_NO_ERROR; + errors = I2CD_NO_ERROR; if(reg->SR1 & I2C_SR1_BERR) { /* Bus error */ reg->SR1 &= ~I2C_SR1_BERR; - flags |= I2CD_BUS_ERROR; + errors |= I2CD_BUS_ERROR; } if(reg->SR1 & I2C_SR1_ARLO) { /* Arbitration lost */ reg->SR1 &= ~I2C_SR1_ARLO; - flags |= I2CD_ARBITRATION_LOST; + errors |= I2CD_ARBITRATION_LOST; } if(reg->SR1 & I2C_SR1_AF) { /* Acknowledge fail */ reg->SR1 &= ~I2C_SR1_AF; reg->CR1 |= I2C_CR1_STOP; /* setting stop bit */ - while(i2cp->id_i2c->CR1 & I2C_CR1_STOP) - ; - flags |= I2CD_ACK_FAILURE; + errors |= I2CD_ACK_FAILURE; } if(reg->SR1 & I2C_SR1_OVR) { /* Overrun */ reg->SR1 &= ~I2C_SR1_OVR; - flags |= I2CD_OVERRUN; + errors |= I2CD_OVERRUN; } if(reg->SR1 & I2C_SR1_PECERR) { /* PEC error */ reg->SR1 &= ~I2C_SR1_PECERR; - flags |= I2CD_PEC_ERROR; + errors |= I2CD_PEC_ERROR; } if(reg->SR1 & I2C_SR1_TIMEOUT) { /* SMBus Timeout */ reg->SR1 &= ~I2C_SR1_TIMEOUT; - flags |= I2CD_TIMEOUT; + errors |= I2CD_TIMEOUT; } if(reg->SR1 & I2C_SR1_SMBALERT) { /* SMBus alert */ reg->SR1 &= ~I2C_SR1_SMBALERT; - flags |= I2CD_SMB_ALERT; + errors |= I2CD_SMB_ALERT; } - if(flags != I2CD_NO_ERROR) { /* send communication end signal */ + if(errors != I2CD_NO_ERROR) { /* send communication end signal */ chSysLockFromIsr(); - i2cAddFlagsI(i2cp, flags); + i2cAddFlagsI(i2cp, errors); chSysUnlockFromIsr(); _i2c_isr_err_code(i2cp, i2cp->id_slave_config); } @@ -523,6 +517,10 @@ void i2c_lld_master_receive(I2CDriver *i2cp, uint8_t slave_addr, dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes); dmaStreamSetMode(i2cp->dmarx, ((i2cp->dmamode) | mode)); + /* wait stop bit from previouse transaction*/ + while(i2cp->id_i2c->CR1 & I2C_CR1_STOP) + ; + i2cp->id_i2c->CR2 |= I2C_CR2_ITERREN | I2C_CR2_ITEVTEN; i2cp->id_i2c->CR1 |= I2C_CR1_START | I2C_CR1_ACK; } @@ -561,6 +559,10 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, uint8_t slave_addr, dmaStreamSetTransactionSize(i2cp->dmatx, txbytes); dmaStreamSetMode(i2cp->dmatx, ((i2cp->dmamode) | mode)); + /* wait stop bit from previouse transaction*/ + while(i2cp->id_i2c->CR1 & I2C_CR1_STOP) + ; + i2cp->id_i2c->CR2 |= I2C_CR2_ITERREN | I2C_CR2_ITEVTEN; i2cp->id_i2c->CR1 |= I2C_CR1_START; } diff --git a/os/hal/platforms/STM32/i2c_lld.h b/os/hal/platforms/STM32/i2c_lld.h index 2ca6b872a..4e9051e39 100644 --- a/os/hal/platforms/STM32/i2c_lld.h +++ b/os/hal/platforms/STM32/i2c_lld.h @@ -273,11 +273,6 @@ typedef struct { */ typedef struct I2CDriver I2CDriver; -/** - * @brief Type of a structure representing an I2C slave config. - */ -typedef struct I2CSlaveConfig I2CSlaveConfig; - /** * @brief Structure representing an I2C driver. */ @@ -287,12 +282,11 @@ struct I2CDriver{ */ i2cstate_t id_state; -#if I2C_USE_WAIT /** * @brief Thread waiting for I/O completion. */ Thread *id_thread; -#endif /* I2C_USE_WAIT */ + #if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) #if CH_USE_MUTEXES || defined(__DOXYGEN__) /** @@ -308,10 +302,6 @@ struct I2CDriver{ * @brief Current configuration data. */ const I2CConfig *id_config; - /** - * @brief Current slave configuration data. - */ - const I2CSlaveConfig *id_slave_config; __IO size_t txbytes; /*!< @brief Number of bytes to be transmitted. */ __IO size_t rxbytes; /*!< @brief Number of bytes to be received. */ @@ -341,8 +331,7 @@ struct I2CDriver{ (i2cp->id_i2c->SR2 & I2C_SR2_BUSY) -/* Wait until BUSY flag is reset: a STOP has been generated on the bus - * signaling the end of transmission. Normally this wait function +/* Wait until BUSY flag is reset. Normally this wait function * does not block thread, only if slave not response it does. */ #define i2c_lld_wait_bus_free(i2cp) { \ diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c index 4b9160a68..996343104 100644 --- a/os/hal/src/i2c.c +++ b/os/hal/src/i2c.c @@ -75,11 +75,7 @@ void i2cObjectInit(I2CDriver *i2cp) { i2cp->id_config = NULL; i2cp->rxbuf = NULL; i2cp->txbuf = NULL; - i2cp->id_slave_config = NULL; - -#if I2C_USE_WAIT i2cp->id_thread = NULL; -#endif /* I2C_USE_WAIT */ #if I2C_USE_MUTUAL_EXCLUSION #if CH_USE_MUTEXES @@ -147,7 +143,6 @@ void i2cStop(I2CDriver *i2cp) { * hardware restrictions. * * @param[in] i2cp pointer to the @p I2CDriver object - * @param[in] i2cscfg pointer to the @p I2C slave config * @param[in] slave_addr Slave device address (7 bits) without R/W bit * @param[in] txbuf pointer to transmit buffer * @param[in] txbytes number of bytes to be transmitted @@ -156,24 +151,19 @@ void i2cStop(I2CDriver *i2cp) { * you want transmit only */ void i2cMasterTransmit(I2CDriver *i2cp, - const I2CSlaveConfig *i2cscfg, uint8_t slave_addr, uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes) { - chDbgCheck((i2cp != NULL) && (i2cscfg != NULL) &&\ + chDbgCheck((i2cp != NULL) &&\ (slave_addr != 0) &&\ (txbytes > 0) &&\ (txbuf != NULL) &&\ ((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL))), "i2cMasterTransmit"); - /* init slave config field in driver */ - i2cp->id_slave_config = i2cscfg; - - // TODO: remove this loop. Do only 1 check because mutual exclusion resolve collisions i2c_lld_wait_bus_free(i2cp); chDbgAssert(!(i2c_lld_bus_is_busy(i2cp)), "i2cMasterReceive(), #1", "time is out"); @@ -191,27 +181,21 @@ void i2cMasterTransmit(I2CDriver *i2cp, * hardware restrictions. * * @param[in] i2cp pointer to the @p I2CDriver object - * @param[in] i2cscfg pointer to the @p I2C slave config * @param[in] slave_addr slave device address (7 bits) without R/W bit * @param[in] rxbytes number of bytes to be received * @param[in] rxbuf pointer to receive buffer */ void i2cMasterReceive(I2CDriver *i2cp, - const I2CSlaveConfig *i2cscfg, uint8_t slave_addr, uint8_t *rxbuf, size_t rxbytes){ - chDbgCheck((i2cp != NULL) && (i2cscfg != NULL) &&\ + chDbgCheck((i2cp != NULL) &&\ (slave_addr != 0) &&\ (rxbytes > 1) && \ (rxbuf != NULL), "i2cMasterReceive"); - /* init slave config field in driver */ - i2cp->id_slave_config = i2cscfg; - - // TODO: remove this loop. Do only 1 check because mutual exclusion resolve collisions i2c_lld_wait_bus_free(i2cp); chDbgAssert(!(i2c_lld_bus_is_busy(i2cp)), "i2cMasterReceive(), #1", "time is out"); @@ -298,7 +282,6 @@ void i2cReleaseBus(I2CDriver *i2cp) { chDbgCheck(i2cp != NULL, "i2cReleaseBus"); #if CH_USE_MUTEXES - (void)i2cp; chMtxUnlock(); #elif CH_USE_SEMAPHORES chSemSignal(&i2cp->id_semaphore); -- cgit v1.2.3 From 3799bf56f52f7a5be9eeda6757c6642105c4ed66 Mon Sep 17 00:00:00 2001 From: barthess Date: Wed, 7 Dec 2011 19:23:09 +0000 Subject: I2C. Error handling from userland code added. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3572 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/i2c.h | 5 +++-- os/hal/src/i2c.c | 12 ++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h index 8cfd97e75..5ee4887e9 100644 --- a/os/hal/include/i2c.h +++ b/os/hal/include/i2c.h @@ -181,15 +181,16 @@ extern "C" { void i2cObjectInit(I2CDriver *i2cp); void i2cStart(I2CDriver *i2cp, const I2CConfig *config); void i2cStop(I2CDriver *i2cp); - void i2cMasterTransmit(I2CDriver *i2cp, + i2cflags_t i2cMasterTransmit(I2CDriver *i2cp, uint8_t slave_addr, uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes); - void i2cMasterReceive(I2CDriver *i2cp, + i2cflags_t i2cMasterReceive(I2CDriver *i2cp, uint8_t slave_addr, uint8_t *rxbuf, size_t rxbytes); void i2cMasterStart(I2CDriver *i2cp); void i2cMasterStop(I2CDriver *i2cp); void i2cAddFlagsI(I2CDriver *i2cp, i2cflags_t mask); + i2cflags_t i2cGetAndClearFlags(I2CDriver *i2cp); #if I2C_USE_MUTUAL_EXCLUSION void i2cAcquireBus(I2CDriver *i2cp); diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c index 996343104..f20932ef3 100644 --- a/os/hal/src/i2c.c +++ b/os/hal/src/i2c.c @@ -149,8 +149,10 @@ void i2cStop(I2CDriver *i2cp) { * @param[in] rxbuf pointer to receive buffer * @param[in] rxbytes number of bytes to be received, set it to 0 if * you want transmit only + * + * @return Zero if no errors, otherwise return error code. */ -void i2cMasterTransmit(I2CDriver *i2cp, +i2cflags_t i2cMasterTransmit(I2CDriver *i2cp, uint8_t slave_addr, uint8_t *txbuf, size_t txbytes, @@ -173,6 +175,8 @@ void i2cMasterTransmit(I2CDriver *i2cp, i2cp->id_state = I2C_ACTIVE_TRANSMIT; i2c_lld_master_transmit(i2cp, slave_addr, txbuf, txbytes, rxbuf, rxbytes); _i2c_wait_s(i2cp); + + return i2cGetAndClearFlags(i2cp); } /** @@ -184,8 +188,10 @@ void i2cMasterTransmit(I2CDriver *i2cp, * @param[in] slave_addr slave device address (7 bits) without R/W bit * @param[in] rxbytes number of bytes to be received * @param[in] rxbuf pointer to receive buffer + * + * @return Zero if no errors, otherwise return error code. */ -void i2cMasterReceive(I2CDriver *i2cp, +i2cflags_t i2cMasterReceive(I2CDriver *i2cp, uint8_t slave_addr, uint8_t *rxbuf, size_t rxbytes){ @@ -205,6 +211,8 @@ void i2cMasterReceive(I2CDriver *i2cp, i2cp->id_state = I2C_ACTIVE_RECEIVE; i2c_lld_master_receive(i2cp, slave_addr, rxbuf, rxbytes); _i2c_wait_s(i2cp); + + return i2cGetAndClearFlags(i2cp); } /** -- cgit v1.2.3 From c7c5942ac386fcfddcb77cb3c0e525d0e85063c4 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 8 Dec 2011 08:36:37 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3578 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/i2c.h | 22 ++++++------- os/hal/platforms/STM32F1xx/hal_lld_f100.h | 14 ++++++++ os/hal/platforms/STM32F1xx/hal_lld_f103.h | 44 +++++++++++++++++++++++-- os/hal/platforms/STM32F4xx/hal_lld.h | 30 ++++++++--------- os/hal/src/i2c.c | 54 ++++++++++++++----------------- 5 files changed, 105 insertions(+), 59 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h index 5ee4887e9..f412e8a97 100644 --- a/os/hal/include/i2c.h +++ b/os/hal/include/i2c.h @@ -43,16 +43,16 @@ * @name I2C bus error conditions * @{ */ -#define I2CD_NO_ERROR 0x00 /**< @brief No error. */ -#define I2CD_BUS_ERROR 0x01 /**< @brief Bus Error. */ -#define I2CD_ARBITRATION_LOST 0x02 /**< @brief Arbitration Lost - (master mode). */ -#define I2CD_ACK_FAILURE 0x04 /**< @brief Acknowledge Failure.*/ -#define I2CD_OVERRUN 0x08 /**< @brief Overrun/Underrun. */ -#define I2CD_PEC_ERROR 0x10 /**< @brief PEC Error in - reception. */ -#define I2CD_TIMEOUT 0x20 /**< @brief Timeout Error. */ -#define I2CD_SMB_ALERT 0x40 /**< @brief SMBus Alert. */ +#define I2CD_NO_ERROR 0x00 /**< @brief No error. */ +#define I2CD_BUS_ERROR 0x01 /**< @brief Bus Error. */ +#define I2CD_ARBITRATION_LOST 0x02 /**< @brief Arbitration Lost + (master mode). */ +#define I2CD_ACK_FAILURE 0x04 /**< @brief Acknowledge Failure. */ +#define I2CD_OVERRUN 0x08 /**< @brief Overrun/Underrun. */ +#define I2CD_PEC_ERROR 0x10 /**< @brief PEC Error in + reception. */ +#define I2CD_TIMEOUT 0x20 /**< @brief Timeout Error. */ +#define I2CD_SMB_ALERT 0x40 /**< @brief SMBus Alert. */ /** @} */ /*===========================================================================*/ @@ -187,8 +187,6 @@ extern "C" { uint8_t *rxbuf, size_t rxbytes); i2cflags_t i2cMasterReceive(I2CDriver *i2cp, uint8_t slave_addr, uint8_t *rxbuf, size_t rxbytes); - void i2cMasterStart(I2CDriver *i2cp); - void i2cMasterStop(I2CDriver *i2cp); void i2cAddFlagsI(I2CDriver *i2cp, i2cflags_t mask); i2cflags_t i2cGetAndClearFlags(I2CDriver *i2cp); diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f100.h b/os/hal/platforms/STM32F1xx/hal_lld_f100.h index 96f5a7f33..16bb84cbf 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f100.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f100.h @@ -164,8 +164,22 @@ /* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_I2C1_RX_DMA_CHN 0x00000000 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_I2C1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_I2C2 FALSE +#define STM32_I2C2_RX_DMA_MSK 0 +#define STM32_I2C2_RX_DMA_CHN 0x00000000 +#define STM32_I2C2_TX_DMA_MSK 0 +#define STM32_I2C2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_I2C3 FALSE +#define STM32_SPI3_RX_DMA_MSK 0 +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK 0 +#define STM32_SPI3_TX_DMA_CHN 0x00000000 #define STM32_HAS_RTC TRUE diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f103.h b/os/hal/platforms/STM32F1xx/hal_lld_f103.h index d251e6a5d..108854ff7 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f103.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f103.h @@ -174,8 +174,22 @@ /* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_I2C1_RX_DMA_CHN 0x00000000 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_I2C1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_I2C2 FALSE +#define STM32_I2C2_RX_DMA_MSK 0 +#define STM32_I2C2_RX_DMA_CHN 0x00000000 +#define STM32_I2C2_TX_DMA_MSK 0 +#define STM32_I2C2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_I2C3 FALSE +#define STM32_SPI3_RX_DMA_MSK 0 +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK 0 +#define STM32_SPI3_TX_DMA_CHN 0x00000000 /* RTC attributes.*/ #define STM32_HAS_RTC TRUE @@ -323,8 +337,6 @@ #define STM32_I2C3_TX_DMA_MSK 0 #define STM32_I2C3_TX_DMA_CHN 0x00000000 - - /* RTC attributes.*/ #define STM32_HAS_RTC TRUE @@ -454,8 +466,22 @@ /* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_I2C1_RX_DMA_CHN 0x00000000 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_I2C1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_I2C2 TRUE +#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C2_RX_DMA_CHN 0x00000000 +#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_I2C2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_I2C3 FALSE +#define STM32_I2C3_RX_DMA_MSK 0 +#define STM32_I2C3_RX_DMA_CHN 0x00000000 +#define STM32_I2C3_TX_DMA_MSK 0 +#define STM32_I2C3_TX_DMA_CHN 0x00000000 /* RTC attributes.*/ #define STM32_HAS_RTC TRUE @@ -586,8 +612,22 @@ /* I2C attributes.*/ #define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_I2C1_RX_DMA_CHN 0x00000000 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_I2C1_TX_DMA_CHN 0x00000000 + #define STM32_HAS_I2C2 TRUE +#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C2_RX_DMA_CHN 0x00000000 +#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_I2C2_TX_DMA_CHN 0x00000000 + #define STM32_HAS_I2C3 FALSE +#define STM32_I2C3_RX_DMA_MSK 0 +#define STM32_I2C3_RX_DMA_CHN 0x00000000 +#define STM32_I2C3_TX_DMA_MSK 0 +#define STM32_I2C3_TX_DMA_CHN 0x00000000 /* RTC attributes.*/ #define STM32_HAS_RTC TRUE diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index 061ce1304..1bb69958e 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -292,25 +292,25 @@ /* 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 0x10000000 +#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 0x10000000 #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_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_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 /* RTC attributes.*/ #define STM32_HAS_RTC TRUE diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c index f20932ef3..ae5f9f7a8 100644 --- a/os/hal/src/i2c.c +++ b/os/hal/src/i2c.c @@ -133,13 +133,11 @@ void i2cStop(I2CDriver *i2cp) { } /** - * @brief Sends data via the I2C bus. - * + * @brief Sends data via the I2C bus. * @details Function designed to realize "read-through-write" transfer * paradigm. If you want transmit data without any further read, * than set @b rxbytes field to 0. - * - * @details Number of receiving byts must be 0 or more than 1 because of stm32 + * Number of receiving byts must be 0 or more than 1 because of stm32 * hardware restrictions. * * @param[in] i2cp pointer to the @p I2CDriver object @@ -153,22 +151,21 @@ void i2cStop(I2CDriver *i2cp) { * @return Zero if no errors, otherwise return error code. */ i2cflags_t i2cMasterTransmit(I2CDriver *i2cp, - uint8_t slave_addr, - uint8_t *txbuf, - size_t txbytes, - uint8_t *rxbuf, - size_t rxbytes) { - - chDbgCheck((i2cp != NULL) &&\ - (slave_addr != 0) &&\ - (txbytes > 0) &&\ - (txbuf != NULL) &&\ - ((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL))), - "i2cMasterTransmit"); + uint8_t slave_addr, + uint8_t *txbuf, + size_t txbytes, + uint8_t *rxbuf, + size_t rxbytes) { + + chDbgCheck((i2cp != NULL) && (slave_addr != 0) && + (txbytes > 0) && (txbuf != NULL) && + ((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL))), + "i2cMasterTransmit"); i2c_lld_wait_bus_free(i2cp); - chDbgAssert(!(i2c_lld_bus_is_busy(i2cp)), "i2cMasterReceive(), #1", "time is out"); + chDbgAssert(!(i2c_lld_bus_is_busy(i2cp)), + "i2cMasterReceive(), #1", "time is out"); chDbgAssert(i2cp->id_state == I2C_READY, "i2cMasterTransmit(), #1", "not ready"); @@ -180,8 +177,8 @@ i2cflags_t i2cMasterTransmit(I2CDriver *i2cp, } /** - * @brief Receives data from the I2C bus. - * @details Number of receiving byts must be more than 1 because of stm32 + * @brief Receives data from the I2C bus. + * Number of receiving byts must be more than 1 because of stm32 * hardware restrictions. * * @param[in] i2cp pointer to the @p I2CDriver object @@ -192,19 +189,18 @@ i2cflags_t i2cMasterTransmit(I2CDriver *i2cp, * @return Zero if no errors, otherwise return error code. */ i2cflags_t i2cMasterReceive(I2CDriver *i2cp, - uint8_t slave_addr, - uint8_t *rxbuf, - size_t rxbytes){ + uint8_t slave_addr, + uint8_t *rxbuf, + size_t rxbytes){ - chDbgCheck((i2cp != NULL) &&\ - (slave_addr != 0) &&\ - (rxbytes > 1) && \ - (rxbuf != NULL), - "i2cMasterReceive"); + chDbgCheck((i2cp != NULL) && (slave_addr != 0) && + (rxbytes > 1) && (rxbuf != NULL), + "i2cMasterReceive"); i2c_lld_wait_bus_free(i2cp); - chDbgAssert(!(i2c_lld_bus_is_busy(i2cp)), "i2cMasterReceive(), #1", "time is out"); + chDbgAssert(!(i2c_lld_bus_is_busy(i2cp)), + "i2cMasterReceive(), #1", "time is out"); chDbgAssert(i2cp->id_state == I2C_READY, "i2cMasterReceive(), #1", "not ready"); @@ -253,8 +249,6 @@ i2cflags_t i2cGetAndClearFlags(I2CDriver *i2cp) { return mask; } - - #if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) /** * @brief Gains exclusive access to the I2C bus. -- cgit v1.2.3 From a524ec87f1fffcfea724d8485911fe94a503265f Mon Sep 17 00:00:00 2001 From: barthess Date: Thu, 8 Dec 2011 14:34:44 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3581 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/i2c_lld.c | 10 ++++++++++ os/hal/src/i2c.c | 8 ++------ 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index 1345c847b..bda0ba17b 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -490,6 +490,8 @@ void i2c_lld_reset(I2CDriver *i2cp){ /** * @brief Receive data via the I2C bus as master. + * @details Number of receiving bytes must be more than 1 because of stm32 + * hardware restrictions. * * @param[in] i2cp pointer to the @p I2CDriver object * @param[in] slave_addr slave device address @@ -501,6 +503,8 @@ void i2c_lld_master_receive(I2CDriver *i2cp, uint8_t slave_addr, uint32_t mode = 0; + chDbgCheck((rxbytes > 1), "i2c_lld_master_receive"); + /* init driver fields */ i2cp->slave_addr = (slave_addr << 1) | 0x01; /* LSB = 1 -> receive */ i2cp->rxbytes = rxbytes; @@ -529,6 +533,9 @@ void i2c_lld_master_receive(I2CDriver *i2cp, uint8_t slave_addr, /** * @brief Transmits data via the I2C bus as master. * + * @details Number of receiving bytes must be 0 or more than 1 because of stm32 + * hardware restrictions. + * * @param[in] i2cp pointer to the @p I2CDriver object * @param[in] slave_addr slave device address * @param[in] txbuf pointer to the transmit buffer @@ -542,6 +549,9 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, uint8_t slave_addr, uint32_t mode = 0; + chDbgCheck(((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL))), + "i2cMasterTransmit"); + /* init driver fields */ i2cp->slave_addr = (slave_addr << 1) & 0x00FE; /* LSB = 0 -> write */ i2cp->txbytes = txbytes; diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c index ae5f9f7a8..63c03565a 100644 --- a/os/hal/src/i2c.c +++ b/os/hal/src/i2c.c @@ -137,8 +137,6 @@ void i2cStop(I2CDriver *i2cp) { * @details Function designed to realize "read-through-write" transfer * paradigm. If you want transmit data without any further read, * than set @b rxbytes field to 0. - * Number of receiving byts must be 0 or more than 1 because of stm32 - * hardware restrictions. * * @param[in] i2cp pointer to the @p I2CDriver object * @param[in] slave_addr Slave device address (7 bits) without R/W bit @@ -159,7 +157,7 @@ i2cflags_t i2cMasterTransmit(I2CDriver *i2cp, chDbgCheck((i2cp != NULL) && (slave_addr != 0) && (txbytes > 0) && (txbuf != NULL) && - ((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL))), + ((rxbytes == 0) || ((rxbytes > 0) && (rxbuf != NULL))), "i2cMasterTransmit"); i2c_lld_wait_bus_free(i2cp); @@ -178,8 +176,6 @@ i2cflags_t i2cMasterTransmit(I2CDriver *i2cp, /** * @brief Receives data from the I2C bus. - * Number of receiving byts must be more than 1 because of stm32 - * hardware restrictions. * * @param[in] i2cp pointer to the @p I2CDriver object * @param[in] slave_addr slave device address (7 bits) without R/W bit @@ -194,7 +190,7 @@ i2cflags_t i2cMasterReceive(I2CDriver *i2cp, size_t rxbytes){ chDbgCheck((i2cp != NULL) && (slave_addr != 0) && - (rxbytes > 1) && (rxbuf != NULL), + (rxbytes > 0) && (rxbuf != NULL), "i2cMasterReceive"); i2c_lld_wait_bus_free(i2cp); -- cgit v1.2.3 From edfa9d2fae1d667b3f71a8e61aa954ac2233e493 Mon Sep 17 00:00:00 2001 From: barthess Date: Thu, 8 Dec 2011 19:24:21 +0000 Subject: I2C. Added timeout in functions. Code clean ups. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3583 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/i2c.h | 17 ++++---- os/hal/platforms/STM32/i2c_lld.c | 25 +++-------- os/hal/platforms/STM32/i2c_lld.h | 15 ++----- os/hal/src/i2c.c | 94 +++++++++++++++------------------------- 4 files changed, 55 insertions(+), 96 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h index f412e8a97..31dcb53d5 100644 --- a/os/hal/include/i2c.h +++ b/os/hal/include/i2c.h @@ -108,12 +108,12 @@ typedef enum { * * @notapi */ -#define _i2c_wait_s(i2cp) { \ +#define _i2c_wait_s(i2cp, timeout, rdymsg) { \ chDbgAssert((i2cp)->id_thread == NULL, \ "_i2c_wait(), #1", "already waiting"); \ chSysLock(); \ (i2cp)->id_thread = chThdSelf(); \ - chSchGoSleepS(THD_STATE_SUSPENDED); \ + rdymsg = chSchGoSleepTimeoutS(THD_STATE_SUSPENDED, timeout); \ chSysUnlock(); \ } @@ -181,14 +181,15 @@ extern "C" { void i2cObjectInit(I2CDriver *i2cp); void i2cStart(I2CDriver *i2cp, const I2CConfig *config); void i2cStop(I2CDriver *i2cp); - i2cflags_t i2cMasterTransmit(I2CDriver *i2cp, + msg_t i2cMasterTransmit(I2CDriver *i2cp, uint8_t slave_addr, uint8_t *txbuf, size_t txbytes, - uint8_t *rxbuf, size_t rxbytes); - i2cflags_t i2cMasterReceive(I2CDriver *i2cp, - uint8_t slave_addr, uint8_t *rxbuf, size_t rxbytes); - void i2cAddFlagsI(I2CDriver *i2cp, i2cflags_t mask); - i2cflags_t i2cGetAndClearFlags(I2CDriver *i2cp); + uint8_t *rxbuf, size_t rxbytes, + i2cflags_t *errors, systime_t timeout); + msg_t i2cMasterReceive(I2CDriver *i2cp, + uint8_t slave_addr, + uint8_t *rxbuf, size_t rxbytes, + i2cflags_t *errors, systime_t timeout); #if I2C_USE_MUTUAL_EXCLUSION void i2cAcquireBus(I2CDriver *i2cp); diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index bda0ba17b..84decd64f 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -131,7 +131,7 @@ static volatile uint16_t dbgCR2 = 0; /** * @brief Return the last event value from I2C status registers. - * @details Important but implicit function is clearing interrpts flags. + * @details Important but implicit function is clearing interrupts flags. * @note Internal use only. * * @param[in] i2cp pointer to the @p I2CDriver object @@ -160,8 +160,6 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) { switch(i2c_get_event(i2cp)){ case I2C_EV5_MASTER_MODE_SELECT: - /* catch start generated event */ - i2cp->flags &= ~I2C_FLG_HEADER_SENT; dp->DR = i2cp->slave_addr; break; @@ -176,7 +174,7 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) { break; case I2C_EV8_2_MASTER_BYTE_TRANSMITTED: - /* catch BTF event after the end of trasmission */ + /* catch BTF event after the end of transmission */ if (i2cp->rxbytes > 1){ /* start "read after write" operation */ i2c_lld_master_receive(i2cp, (i2cp->slave_addr >> 1), @@ -224,7 +222,6 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp){ */ static void i2c_serve_error_interrupt(I2CDriver *i2cp) { i2cflags_t errors; - I2C_TypeDef *reg; chSysLockFromIsr(); /* clear interrupt falgs just to be safe */ @@ -234,7 +231,7 @@ static void i2c_serve_error_interrupt(I2CDriver *i2cp) { dmaStreamClearInterrupt(i2cp->dmarx); chSysUnlockFromIsr(); - reg = i2cp->id_i2c; + #define reg (i2cp->id_i2c) errors = I2CD_NO_ERROR; if(reg->SR1 & I2C_SR1_BERR) { /* Bus error */ @@ -268,11 +265,10 @@ static void i2c_serve_error_interrupt(I2CDriver *i2cp) { } if(errors != I2CD_NO_ERROR) { /* send communication end signal */ - chSysLockFromIsr(); - i2cAddFlagsI(i2cp, errors); - chSysUnlockFromIsr(); + i2cp->errors |= errors; _i2c_isr_err_code(i2cp, i2cp->id_slave_config); } + #undef reg } @@ -455,7 +451,7 @@ void i2c_lld_start(I2CDriver *i2cp) { dmaStreamSetPeripheral(i2cp->dmarx, &i2cp->id_i2c->DR); dmaStreamSetPeripheral(i2cp->dmatx, &i2cp->id_i2c->DR); - i2cp->id_i2c->CR1 = I2C_CR1_SWRST; /* reset i2c peripherial */ + i2cp->id_i2c->CR1 = I2C_CR1_SWRST; /* reset i2c peripheral */ i2cp->id_i2c->CR1 = 0; i2c_lld_set_clock(i2cp); i2c_lld_set_opmode(i2cp); @@ -509,10 +505,6 @@ void i2c_lld_master_receive(I2CDriver *i2cp, uint8_t slave_addr, i2cp->slave_addr = (slave_addr << 1) | 0x01; /* LSB = 1 -> receive */ i2cp->rxbytes = rxbytes; i2cp->rxbuf = rxbuf; - i2cp->flags = 0; - - /* setting flags and register bits */ - i2cp->flags |= I2C_FLG_MASTER_RECEIVER; i2cp->errors = 0; mode = STM32_DMA_CR_DIR_P2M; @@ -521,7 +513,7 @@ void i2c_lld_master_receive(I2CDriver *i2cp, uint8_t slave_addr, dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes); dmaStreamSetMode(i2cp->dmarx, ((i2cp->dmamode) | mode)); - /* wait stop bit from previouse transaction*/ + /* wait stop bit from previous transaction*/ while(i2cp->id_i2c->CR1 & I2C_CR1_STOP) ; @@ -558,9 +550,6 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, uint8_t slave_addr, i2cp->rxbytes = rxbytes; i2cp->txbuf = txbuf; i2cp->rxbuf = rxbuf; - - /* setting flags and register bits */ - i2cp->flags = 0; i2cp->errors = 0; mode = STM32_DMA_CR_DIR_M2P; diff --git a/os/hal/platforms/STM32/i2c_lld.h b/os/hal/platforms/STM32/i2c_lld.h index 4e9051e39..378b3a335 100644 --- a/os/hal/platforms/STM32/i2c_lld.h +++ b/os/hal/platforms/STM32/i2c_lld.h @@ -176,9 +176,6 @@ #define I2C_EV8_2_MASTER_BYTE_TRANSMITTED ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA) << 16) | I2C_SR1_BTF | I2C_SR1_TXE)) /* TRA, BUSY, MSL, TXE and BTF flags */ #define I2C_EV_MASK 0x00FFFFFF /* First byte zeroed because there is no need of PEC register part from SR2 */ -#define I2C_FLG_MASTER_RECEIVER 0x10 -#define I2C_FLG_HEADER_SENT 0x80 - /** @brief error checks */ #if STM32_I2C_USE_I2C1 && !STM32_HAS_I2C1 #error "I2C1 not present in the selected device" @@ -309,7 +306,6 @@ struct I2CDriver{ uint8_t *txbuf; /*!< @brief Pointer to transmit buffer.*/ __IO i2cflags_t errors; /*!< @brief Error flags.*/ - __IO i2cflags_t flags; /*!< @brief State flags.*/ uint8_t slave_addr; /*!< @brief Current slave address without R/W bit. */ @@ -327,16 +323,11 @@ struct I2CDriver{ /* Driver macros. */ /*===========================================================================*/ -#define i2c_lld_bus_is_busy(i2cp) \ - (i2cp->id_i2c->SR2 & I2C_SR2_BUSY) - - -/* Wait until BUSY flag is reset. Normally this wait function - * does not block thread, only if slave not response it does. +/** + * Wait until BUSY flag is reset. */ #define i2c_lld_wait_bus_free(i2cp) { \ - uint32_t tmo = 0xfffff; \ - while((i2cp->id_i2c->SR2 & I2C_SR2_BUSY) && tmo--) \ + while(i2cp->id_i2c->SR2 & I2C_SR2_BUSY) \ ; \ } diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c index 63c03565a..f7f7c335e 100644 --- a/os/hal/src/i2c.c +++ b/os/hal/src/i2c.c @@ -145,33 +145,40 @@ void i2cStop(I2CDriver *i2cp) { * @param[in] rxbuf pointer to receive buffer * @param[in] rxbytes number of bytes to be received, set it to 0 if * you want transmit only + * @param[in] errors pointer to variable to store error code, zero means + * no error. + * @param[in] timeout operation timeout * - * @return Zero if no errors, otherwise return error code. + * @return timeout status + * @retval RDY_OK if timeout not reached + * @retval RDY_TIMEOUT if a timeout occurs */ -i2cflags_t i2cMasterTransmit(I2CDriver *i2cp, +msg_t i2cMasterTransmit(I2CDriver *i2cp, uint8_t slave_addr, uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, - size_t rxbytes) { + size_t rxbytes, + i2cflags_t *errors, + systime_t timeout) { + msg_t rdymsg; chDbgCheck((i2cp != NULL) && (slave_addr != 0) && (txbytes > 0) && (txbuf != NULL) && - ((rxbytes == 0) || ((rxbytes > 0) && (rxbuf != NULL))), + ((rxbytes == 0) || ((rxbytes > 0) && (rxbuf != NULL))) && + (timeout > TIME_IMMEDIATE) && (errors != NULL), "i2cMasterTransmit"); - - i2c_lld_wait_bus_free(i2cp); - - chDbgAssert(!(i2c_lld_bus_is_busy(i2cp)), - "i2cMasterReceive(), #1", "time is out"); + i2cp->errors = I2CD_NO_ERROR; /* clear error flags from previous run */ chDbgAssert(i2cp->id_state == I2C_READY, "i2cMasterTransmit(), #1", "not ready"); i2cp->id_state = I2C_ACTIVE_TRANSMIT; i2c_lld_master_transmit(i2cp, slave_addr, txbuf, txbytes, rxbuf, rxbytes); - _i2c_wait_s(i2cp); + _i2c_wait_s(i2cp, timeout, rdymsg); + + *errors = i2cp->errors; - return i2cGetAndClearFlags(i2cp); + return rdymsg; } /** @@ -181,69 +188,40 @@ i2cflags_t i2cMasterTransmit(I2CDriver *i2cp, * @param[in] slave_addr slave device address (7 bits) without R/W bit * @param[in] rxbytes number of bytes to be received * @param[in] rxbuf pointer to receive buffer + * @param[in] errors pointer to variable to store error code, zero means + * no error. + * @param[in] timeout operation timeout * - * @return Zero if no errors, otherwise return error code. + * @return timeout status + * @retval RDY_OK if timeout not reached + * @retval RDY_TIMEOUT if a timeout occurs */ -i2cflags_t i2cMasterReceive(I2CDriver *i2cp, +msg_t i2cMasterReceive(I2CDriver *i2cp, uint8_t slave_addr, uint8_t *rxbuf, - size_t rxbytes){ + size_t rxbytes, + i2cflags_t *errors, + systime_t timeout){ + + msg_t rdymsg; chDbgCheck((i2cp != NULL) && (slave_addr != 0) && - (rxbytes > 0) && (rxbuf != NULL), + (rxbytes > 0) && (rxbuf != NULL) && + (timeout > TIME_IMMEDIATE) && (errors != NULL), "i2cMasterReceive"); - - i2c_lld_wait_bus_free(i2cp); - - chDbgAssert(!(i2c_lld_bus_is_busy(i2cp)), - "i2cMasterReceive(), #1", "time is out"); + i2cp->errors = I2CD_NO_ERROR; /* clear error flags from previous run */ chDbgAssert(i2cp->id_state == I2C_READY, "i2cMasterReceive(), #1", "not ready"); i2cp->id_state = I2C_ACTIVE_RECEIVE; i2c_lld_master_receive(i2cp, slave_addr, rxbuf, rxbytes); - _i2c_wait_s(i2cp); + _i2c_wait_s(i2cp, timeout, rdymsg); - return i2cGetAndClearFlags(i2cp); -} - -/** - * @brief Handles communication events/errors. - * @details Must be called from the I/O interrupt service routine in order to - * notify I/O conditions as errors, signals change etc. - * - * @param[in] i2cp pointer to a @p I2CDriver structure - * @param[in] mask condition flags to be added to the mask - * - * @iclass - */ -void i2cAddFlagsI(I2CDriver *i2cp, i2cflags_t mask) { + *errors = i2cp->errors; - chDbgCheck(i2cp != NULL, "i2cAddFlagsI"); - - i2cp->errors |= mask; + return rdymsg; } -/** - * @brief Returns and clears the errors mask associated to the driver. - * - * @param[in] i2cp pointer to a @p I2CDriver structure - * @return The condition flags modified since last time this - * function was invoked. - * - * @api - */ -i2cflags_t i2cGetAndClearFlags(I2CDriver *i2cp) { - i2cflags_t mask; - - chDbgCheck(i2cp != NULL, "i2cGetAndClearFlags"); - - chSysLock(); - mask = i2cp->errors; - i2cp->errors = I2CD_NO_ERROR; - chSysUnlock(); - return mask; -} #if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) /** -- cgit v1.2.3