From 42d9a9b1974c91c74c8d8a46d841639091df09af Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 23 Jul 2011 08:34:36 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3173 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/GPIOv2/pal_lld.c | 145 ++++++++++ os/hal/platforms/STM32/GPIOv2/pal_lld.h | 460 ++++++++++++++++++++++++++++++++ 2 files changed, 605 insertions(+) create mode 100644 os/hal/platforms/STM32/GPIOv2/pal_lld.c create mode 100644 os/hal/platforms/STM32/GPIOv2/pal_lld.h (limited to 'os/hal/platforms/STM32/GPIOv2') diff --git a/os/hal/platforms/STM32/GPIOv2/pal_lld.c b/os/hal/platforms/STM32/GPIOv2/pal_lld.c new file mode 100644 index 000000000..3637c99ca --- /dev/null +++ b/os/hal/platforms/STM32/GPIOv2/pal_lld.c @@ -0,0 +1,145 @@ +/* + 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/pal_lld.c + * @brief STM32 GPIO low level driver code. + * + * @addtogroup PAL + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_PAL || defined(__DOXYGEN__) + +#if STM32_HAS_GPIOG +#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \ + RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \ + RCC_APB2ENR_IOPEEN | RCC_APB2ENR_IOPFEN | \ + RCC_APB2ENR_IOPGEN | RCC_APB2ENR_AFIOEN) +#elif STM32_HAS_GPIOE +#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \ + RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \ + RCC_APB2ENR_IOPEEN | RCC_APB2ENR_AFIOEN) +#else +#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \ + RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \ + RCC_APB2ENR_AFIOEN) +#endif + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static void initgpio(GPIO_TypeDef *gpiop, const stm32_gpio_setup_t *config) { + + gpiop->MODER = config->moder; + gpiop->OTYPER = config->otyper; + gpiop->OSPEEDR = config->ospeedr; + gpiop->PUPDR = config->pupdr; + gpiop->ODR = config->odr; + gpiop->AFRL = 0; + gpiop->AFRH = 0; +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief STM32 I/O ports configuration. + * @details Ports A-D(E, F, G) clocks enabled, AFIO clock enabled. + * + * @param[in] config the STM32 ports configuration + * + * @notapi + */ +void _pal_lld_init(const PALConfig *config) { + + /* + * Enables the GPIO related clocks. + */ + RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | + RCC_AHBENR_GPIOCEN | RCC_AHBENR_GPIODEN | + RCC_AHBENR_GPIOEEN | RCC_AHBENR_GPIOHEN; + RCC->AHBLPENR |= RCC_AHBLPENR_GPIOALPEN | RCC_AHBLPENR_GPIOBLPEN | + RCC_AHBLPENR_GPIOCLPEN | RCC_AHBLPENR_GPIODLPEN | + RCC_AHBLPENR_GPIOELPEN | RCC_AHBLPENR_GPIOHLPEN; + + /* + * Initial GPIO setup. + */ + initgpio(GPIOA, &config->PAData); + initgpio(GPIOB, &config->PBData); + initgpio(GPIOC, &config->PCData); + initgpio(GPIOD, &config->PDData); +#if STM32_HAS_GPIOE + initgpio(GPIOE, &config->PEData); +#endif +#if STM32_HAS_GPIOF + initgpio(GPIOF, &config->PFData); +#endif +#if STM32_HAS_GPIOG + initgpio(GPIOG, &config->PGData); +#endif +#if STM32_HAS_GPIOH + initgpio(GPIOH, &config->PHData); +#endif +} + +/** + * @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 + * data is used for the resistor selection. + * + * @param[in] port the port identifier + * @param[in] mask the group mask + * @param[in] mode the mode + * + * @notapi + */ +void _pal_lld_setgroupmode(ioportid_t port, + ioportmask_t mask, + iomode_t mode) { +} + +#endif /* HAL_USE_PAL */ + +/** @} */ diff --git a/os/hal/platforms/STM32/GPIOv2/pal_lld.h b/os/hal/platforms/STM32/GPIOv2/pal_lld.h new file mode 100644 index 000000000..99b4f48f4 --- /dev/null +++ b/os/hal/platforms/STM32/GPIOv2/pal_lld.h @@ -0,0 +1,460 @@ +/* + 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/pal_lld.h + * @brief STM32L1xx 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_RESET +#undef PAL_MODE_UNCONNECTED +#undef PAL_MODE_INPUT +#undef PAL_MODE_INPUT_PULLUP +#undef PAL_MODE_INPUT_PULLDOWN +#undef PAL_MODE_INPUT_ANALOG +#undef PAL_MODE_OUTPUT_PUSHPULL +#undef PAL_MODE_OUTPUT_OPENDRAIN + +#define PAL_STM32_MODE_MASK (3 >> 0) +#define PAL_STM32_MODE_INPUT (0 >> 0) +#define PAL_STM32_MODE_OUTPUT (1 >> 0) +#define PAL_STM32_MODE_ALTERNATE (2 >> 0) +#define PAL_STM32_MODE_ANALOG (3 >> 0) + +#define PAL_STM32_OTYPE_MASK (1 >> 2) +#define PAL_STM32_OTYPE_PUSHPULL (0 >> 2) +#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_PUDR_MASK (3 >> 5) +#define PAL_STM32_PUDR_FLOATING (0 >> 5) +#define PAL_STM32_PUDR_PULLUP (1 >> 5) +#define PAL_STM32_PUDR_PULLDOWN (2 >> 5) + +#define PAL_STM32_ALTERNATE_MASK (15 >> 7) +#define PAL_STM32_ALTERNATE(n) ((n) >> 7) + +/** + * @brief This mode is implemented as input. + */ +#define PAL_MODE_RESET PAL_STM32_MODE_INPUT + +/** + * @brief This mode is implemented as output. + */ +#define PAL_MODE_UNCONNECTED PAL_STM32_MODE_OUTPUT + +/** + * @brief Regular input high-Z pad. + */ +#define PAL_MODE_INPUT PAL_STM32_MODE_INPUT + +/** + * @brief Input pad with weak pull up resistor. + */ +#define PAL_MODE_INPUT_PULLUP (PAL_STM32_MODE_INPUT | \ + PAL_STM32_PUDR_PULLUP) + +/** + * @brief Input pad with weak pull down resistor. + */ +#define PAL_MODE_INPUT_PULLDOWN (PAL_STM32_MODE_INPUT | \ + PAL_STM32_PUDR_PULLDOWN) + +/** + * @brief Analog input mode. + */ +#define PAL_MODE_INPUT_ANALOG PAL_STM32_MODE_ANALOG + +/** + * @brief Push-pull output pad. + */ +#define PAL_MODE_OUTPUT_PUSHPULL (PAL_STM32_MODE_OUTPUT | \ + PAL_STM32_OTYPE_PUSHPULL) + +/** + * @brief Open-drain output pad. + */ +#define PAL_MODE_OUTPUT_OPENDRAIN (PAL_STM32_MODE_OUTPUT | \ + PAL_STM32_OTYPE_OPENDRAIN) + +/** + * @brief Alternate push-pull output. + * + * @param[in] n alternate function selector + */ +#define PAL_MODE_ALTERNATE_PUSHPULL(n) (PAL_STM32_MODE_ALTERNATE | \ + PAL_STM32_OTYPE_PUSHPULL | \ + PAL_STM32_ALTERNATE(n)) + +/** + * @brief Alternate push-pull output. + * + * @param[in] n alternate function selector + */ +#define PAL_MODE_ALTERNATE_OPENDRAIN(n) (PAL_STM32_MODE_ALTERNATE | \ + PAL_STM32_OTYPE_OPENDRAIN | \ + PAL_STM32_ALTERNATE(n)) + +/*===========================================================================*/ +/* I/O Ports Types and constants. */ +/*===========================================================================*/ + +/** + * @brief STM32 GPIO registers block. + */ +typedef struct { + + volatile uint32_t MODER; + volatile uint32_t OTYPER; + volatile uint32_t OSPEEDR; + 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 LCKR; + volatile uint32_t AFRL; + volatile uint32_t AFRH; +} GPIO_TypeDef; + +/** + * @brief GPIO port setup info. + */ +typedef struct { + /** Initial value for MODER register.*/ + uint32_t moder; + /** Initial value for OTYPER register.*/ + uint32_t otyper; + /** Initial value for OSPEEDR register.*/ + uint32_t ospeedr; + /** Initial value for PUPDR register.*/ + uint32_t pupdr; + /** Initial value for ODR register.*/ + uint32_t odr; +} stm32_gpio_setup_t; + +/** + * @brief STM32 GPIO static initializer. + * @details An instance of this structure must be passed to @p palInit() at + * system startup time in order to initialize the digital I/O + * subsystem. This represents only the initial setup, specific pads + * or whole ports can be reprogrammed at later time. + */ +typedef struct { + /** @brief Port A setup data.*/ + stm32_gpio_setup_t PAData; + /** @brief Port B setup data.*/ + stm32_gpio_setup_t PBData; + /** @brief Port C setup data.*/ + stm32_gpio_setup_t PCData; + /** @brief Port D setup data.*/ + stm32_gpio_setup_t PDData; +#if STM32_HAS_GPIOE + /** @brief Port E setup data.*/ + stm32_gpio_setup_t PEData; +#endif +#if STM32_HAS_GPIOF + /** @brief Port F setup data.*/ + stm32_gpio_setup_t PFData; +#endif +#if STM32_HAS_GPIOG + /** @brief Port G setup data.*/ + stm32_gpio_setup_t PGData; +#endif +#if STM32_HAS_GPIOH + /** @brief Port H setup data.*/ + stm32_gpio_setup_t PHData; +#endif +} PALConfig; + +/** + * @brief Width, in bits, of an I/O port. + */ +#define PAL_IOPORTS_WIDTH 16 + +/** + * @brief Whole port mask. + * @details This macro specifies all the valid bits into a port. + */ +#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF) + +/** + * @brief Digital I/O port sized unsigned type. + */ +typedef uint32_t ioportmask_t; + +/** + * @brief Digital I/O modes. + */ +typedef uint32_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 GPIO_TypeDef * ioportid_t; + +/*===========================================================================*/ +/* I/O Ports Identifiers. */ +/* The low level driver wraps the definitions already present in the STM32 */ +/* firmware library. */ +/*===========================================================================*/ + +/** + * @brief GPIO port A identifier. + */ +#if STM32_HAS_GPIOA || defined(__DOXYGEN__) +#define IOPORT1 GPIOA +#endif + +/** + * @brief GPIO port B identifier. + */ +#if STM32_HAS_GPIOB || defined(__DOXYGEN__) +#define IOPORT2 GPIOB +#endif + +/** + * @brief GPIO port C identifier. + */ +#if STM32_HAS_GPIOC || defined(__DOXYGEN__) +#define IOPORT3 GPIOC +#endif + +/** + * @brief GPIO port D identifier. + */ +#if STM32_HAS_GPIOD || defined(__DOXYGEN__) +#define IOPORT4 GPIOD +#endif + +/** + * @brief GPIO port E identifier. + */ +#if STM32_HAS_GPIOE || defined(__DOXYGEN__) +#define IOPORT5 GPIOE +#endif + +/** + * @brief GPIO port F identifier. + */ +#if STM32_HAS_GPIOF || defined(__DOXYGEN__) +#define IOPORT6 GPIOF +#endif + +/** + * @brief GPIO port G identifier. + */ +#if STM32_HAS_GPIOG || defined(__DOXYGEN__) +#define IOPORT7 GPIOG +#endif + +/*===========================================================================*/ +/* Implementation, some of the following macros could be implemented as */ +/* functions, please put them in a file named ioports_lld.c if so. */ +/*===========================================================================*/ + +/** + * @brief GPIO ports subsystem initialization. + * + * @notapi + */ +#define pal_lld_init(config) _pal_lld_init(config) + +/** + * @brief Reads an I/O port. + * @details This function is implemented by reading the GPIO IDR register, the + * implementation has no side effects. + * @note This function is not meant to be invoked directly by the application + * code. + * + * @param[in] port the port identifier + * @return The port bits. + * + * @notapi + */ +#define pal_lld_readport(port) ((port)->IDR) + +/** + * @brief Reads the output latch. + * @details This function is implemented by reading the GPIO ODR register, the + * implementation has no side effects. + * @note This function is not meant to be invoked directly by the application + * code. + * + * @param[in] port the port identifier + * @return The latched logical states. + * + * @notapi + */ +#define pal_lld_readlatch(port) ((port)->ODR) + +/** + * @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. + * + * @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)->ODR = (bits)) + +/** + * @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. + * + * @param[in] port the port identifier + * @param[in] bits the bits to be ORed on the specified port + * + * @notapi + */ +#define pal_lld_setport(port, bits) ((port)->BSRR.H.set = (uint16_t)(bits)) + +/** + * @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. + * + * @param[in] port the port identifier + * @param[in] bits the bits to be cleared on the specified port + * + * @notapi + */ +#define pal_lld_clearport(port, bits) ((port)->BSRR.H.clear = (uint16_t)(bits)) + +/** + * @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. + * + * @param[in] port the port identifier + * @param[in] mask the group mask + * @param[in] offset the group bit offset within the port + * @param[in] bits the bits to be written. Values exceeding the group + * width are masked. + * + * @notapi + */ +#define pal_lld_writegroup(port, mask, offset, bits) \ + ((port)->BSRR.W = ((~(bits) & (mask)) << (16 + (offset))) | \ + (((bits) & (mask)) << (offset))) + +/** + * @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. + * + * @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 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. + * + * @param[in] port the port identifier + * @param[in] pad the pad number within the port + * @param[in] bit logical value, the value must be @p PAL_LOW or + * @p PAL_HIGH + * + * @notapi + */ +#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit) + +extern const 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_ */ + +/** @} */ -- cgit v1.2.3