diff options
Diffstat (limited to 'os/hal/platforms/STM32/GPIOv1')
| -rw-r--r-- | os/hal/platforms/STM32/GPIOv1/pal_lld.c | 186 | ||||
| -rw-r--r-- | os/hal/platforms/STM32/GPIOv1/pal_lld.h | 344 | 
2 files changed, 530 insertions, 0 deletions
diff --git a/os/hal/platforms/STM32/GPIOv1/pal_lld.c b/os/hal/platforms/STM32/GPIOv1/pal_lld.c new file mode 100644 index 000000000..a0a1fb6e5 --- /dev/null +++ b/os/hal/platforms/STM32/GPIOv1/pal_lld.c @@ -0,0 +1,186 @@ +/*
 +    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 <http://www.gnu.org/licenses/>.
 +*/
 +
 +/**
 + * @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.                                                   */
 +/*===========================================================================*/
 +
 +/*===========================================================================*/
 +/* 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->APB2ENR |= APB2_EN_MASK;
 +
 +  /*
 +   * Initial GPIO setup.
 +   */
 +  GPIOA->ODR = config->PAData.odr;
 +  GPIOA->CRH = config->PAData.crh;
 +  GPIOA->CRL = config->PAData.crl;
 +  GPIOB->ODR = config->PBData.odr;
 +  GPIOB->CRH = config->PBData.crh;
 +  GPIOB->CRL = config->PBData.crl;
 +  GPIOC->ODR = config->PCData.odr;
 +  GPIOC->CRH = config->PCData.crh;
 +  GPIOC->CRL = config->PCData.crl;
 +  GPIOD->ODR = config->PDData.odr;
 +  GPIOD->CRH = config->PDData.crh;
 +  GPIOD->CRL = config->PDData.crl;
 +#if STM32_HAS_GPIOE || defined(__DOXYGEN__)
 +  GPIOE->ODR = config->PEData.odr;
 +  GPIOE->CRH = config->PEData.crh;
 +  GPIOE->CRL = config->PEData.crl;
 +#if STM32_HAS_GPIOF || defined(__DOXYGEN__)
 +  GPIOF->ODR = config->PFData.odr;
 +  GPIOF->CRH = config->PFData.crh;
 +  GPIOF->CRL = config->PFData.crl;
 +#if STM32_HAS_GPIOG || defined(__DOXYGEN__)
 +  GPIOG->ODR = config->PGData.odr;
 +  GPIOG->CRH = config->PGData.crh;
 +  GPIOG->CRL = config->PGData.crl;
 +#endif
 +#endif
 +#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) {
 +  static const uint8_t cfgtab[] = {
 +    4,          /* PAL_MODE_RESET, implemented as input.*/
 +    2,          /* PAL_MODE_UNCONNECTED, implemented as push pull output 2MHz.*/
 +    4,          /* PAL_MODE_INPUT */
 +    8,          /* PAL_MODE_INPUT_PULLUP */
 +    8,          /* PAL_MODE_INPUT_PULLDOWN */
 +    0,          /* PAL_MODE_INPUT_ANALOG */
 +    3,          /* PAL_MODE_OUTPUT_PUSHPULL, 50MHz.*/
 +    7,          /* PAL_MODE_OUTPUT_OPENDRAIN, 50MHz.*/
 +    8,          /* Reserved.*/
 +    8,          /* Reserved.*/
 +    8,          /* Reserved.*/
 +    8,          /* Reserved.*/
 +    8,          /* Reserved.*/
 +    8,          /* Reserved.*/
 +    8,          /* Reserved.*/
 +    8,          /* Reserved.*/
 +    0xB,        /* PAL_MODE_STM32_ALTERNATE_PUSHPULL, 50MHz.*/
 +    0xF,        /* PAL_MODE_STM32_ALTERNATE_OPENDRAIN, 50MHz.*/
 +  };
 +  uint32_t mh, ml, crh, crl, cfg;
 +  unsigned i;
 +
 +  if (mode == PAL_MODE_INPUT_PULLUP)
 +    port->BSRR = mask;
 +  else if (mode == PAL_MODE_INPUT_PULLDOWN)
 +    port->BRR = mask;
 +  cfg = cfgtab[mode];
 +  mh = ml = crh = crl = 0;
 +  for (i = 0; i < 8; i++) {
 +    ml <<= 4;
 +    mh <<= 4;
 +    crl <<= 4;
 +    crh <<= 4;
 +    if ((mask & 0x0080) == 0)
 +      ml |= 0xf;
 +    else
 +      crl |= cfg;
 +    if ((mask & 0x8000) == 0)
 +      mh |= 0xf;
 +    else
 +      crh |= cfg;
 +    mask <<= 1;
 +  }
 +  port->CRH = (port->CRH & mh) | crh;
 +  port->CRL = (port->CRL & ml) | crl;
 +}
 +
 +#endif /* HAL_USE_PAL */
 +
 +/** @} */
 diff --git a/os/hal/platforms/STM32/GPIOv1/pal_lld.h b/os/hal/platforms/STM32/GPIOv1/pal_lld.h new file mode 100644 index 000000000..fe2102637 --- /dev/null +++ b/os/hal/platforms/STM32/GPIOv1/pal_lld.h @@ -0,0 +1,344 @@ +/*
 +    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 <http://www.gnu.org/licenses/>.
 +*/
 +
 +/**
 + * @file    STM32/pal_lld.h
 + * @brief   STM32 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                                      */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   STM32 specific alternate push-pull output mode.
 + */
 +#define PAL_MODE_STM32_ALTERNATE_PUSHPULL   16
 +
 +/**
 + * @brief   STM32 specific alternate open-drain output mode.
 + */
 +#define PAL_MODE_STM32_ALTERNATE_OPENDRAIN  17
 +
 +/*===========================================================================*/
 +/* I/O Ports Types and constants.                                            */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   GPIO port setup info.
 + */
 +typedef struct {
 +  /** Initial value for ODR register.*/
 +  uint32_t      odr;
 +  /** Initial value for CRL register.*/
 +  uint32_t      crl;
 +  /** Initial value for CRH register.*/
 +  uint32_t      crh;
 +} 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 || defined(__DOXYGEN__)
 +  /** @brief Port E setup data.*/
 +  stm32_gpio_setup_t    PEData;
 +#if STM32_HAS_GPIOF || defined(__DOXYGEN__)
 +  /** @brief Port F setup data.*/
 +  stm32_gpio_setup_t    PFData;
 +#if STM32_HAS_GPIOG || defined(__DOXYGEN__)
 +  /** @brief Port G setup data.*/
 +  stm32_gpio_setup_t    PGData;
 +#endif
 +#endif
 +#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 = (bits))
 +
 +/**
 + * @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.
 + *
 + * @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)->BRR = (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 = ((~(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_ */
 +
 +/** @} */
  | 
