From df5d0e27aab8de253490a02c455b1c07415f6ae9 Mon Sep 17 00:00:00 2001 From: Theodore Ateba Date: Wed, 9 Aug 2017 20:13:29 +0000 Subject: [PATCH] Add AVR XMega PAL low level driver files. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10376 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/AVR/XMEGA/LLD/GPIOv1/driver.mk | 9 + .../ports/AVR/XMEGA/LLD/GPIOv1/hal_pal_lld.c | 157 +++++++++ .../ports/AVR/XMEGA/LLD/GPIOv1/hal_pal_lld.h | 314 ++++++++++++++++++ 3 files changed, 480 insertions(+) create mode 100644 os/hal/ports/AVR/XMEGA/LLD/GPIOv1/driver.mk create mode 100644 os/hal/ports/AVR/XMEGA/LLD/GPIOv1/hal_pal_lld.c create mode 100644 os/hal/ports/AVR/XMEGA/LLD/GPIOv1/hal_pal_lld.h diff --git a/os/hal/ports/AVR/XMEGA/LLD/GPIOv1/driver.mk b/os/hal/ports/AVR/XMEGA/LLD/GPIOv1/driver.mk new file mode 100644 index 000000000..ae1d395da --- /dev/null +++ b/os/hal/ports/AVR/XMEGA/LLD/GPIOv1/driver.mk @@ -0,0 +1,9 @@ +ifeq ($(USE_SMART_BUILD),yes) +ifneq ($(findstring HAL_USE_PAL TRUE,$(HALCONF)),) +PLATFORMSRC += $(CHIBIOS)/os/hal/ports/AVR/XMEGA/LLD/GPIOv1/hal_pal_lld.c +endif +else +PLATFORMSRC += $(CHIBIOS)/os/hal/ports/AVR/XMEGA/LLD/GPIOv1/hal_pal_lld.c +endif + +PLATFORMINC += $(CHIBIOS)/os/hal/ports/AVR/XMEGA/LLD/GPIOv1 diff --git a/os/hal/ports/AVR/XMEGA/LLD/GPIOv1/hal_pal_lld.c b/os/hal/ports/AVR/XMEGA/LLD/GPIOv1/hal_pal_lld.c new file mode 100644 index 000000000..e7f220da4 --- /dev/null +++ b/os/hal/ports/AVR/XMEGA/LLD/GPIOv1/hal_pal_lld.c @@ -0,0 +1,157 @@ +/* + ChibiOS - Copyright (C) 2017 Theodore Ateba + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file GPIOv1/hal_pal_lld.c + * @brief AVR XMEGA GPIO low level driver source file. + * + * @addtogroup PAL + * @{ + */ + +#include "hal.h" + +#if HAL_USE_PAL || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief AVR GPIO ports configuration. + * @details GPIO registers initialization. + * + * @param[in] config the XMEGA AVR ports configuration + * + * @notapi + */ +void _pal_lld_init(const PALConfig *config) { + +#if defined(PORTA) || defined(__DOXYGEN__) + PORTA.OUT = config->porta.out; + PORTA.DIR = config->porta.dir; +#endif + +#if defined(PORTB) || defined(__DOXYGEN__) + PORTB.OUT = config->portb.out; + PORTB.DIR = config->portb.dir; +#endif + +#if defined(PORTC) || defined(__DOXYGEN__) + PORTC.OUT = config->portc.out; + PORTC.DIR = config->portc.dir; +#endif + +#if defined(PORTD) || defined(__DOXYGEN__) + PORTD.OUT = config->portd.out; + PORTD.DIR = config->portd.dir; +#endif + +#if defined(PORTE) || defined(__DOXYGEN__) + PORTE.OUT = config->porte.out; + PORTE.DIR = config->porte.dir; +#endif + +#if defined(PORTF) || defined(__DOXYGEN__) + PORTF.OUT = config->portf.out; + PORTF.DIR = config->portf.dir; +#endif + +#if defined(PORTG) || defined(__DOXYGEN__) + PORTG.OUT = config->portg.out; + PORTG.DIR = config->portg.dir; +#endif + +#if defined(PORTH) || defined(__DOXYGEN__) + PORTH.OUT = config->porth.out; + PORTH.DIR = config->porth.dir; +#endif + +#if defined(PORTJ) || defined(__DOXYGEN__) + PORTJ.OUT = config->portj.out; + PORTJ.DIR = config->portj.dir; +#endif + +#if defined(PORTK) || defined(__DOXYGEN__) + PORTK.OUT = config->portk.out; + PORTK.DIR = config->portk.dir; +#endif + +#if defined(PORTL) || defined(__DOXYGEN__) + PORTL.OUT = config->portl.out; + PORTL.DIR = config->portl.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 + */ +void _pal_lld_setgroupmode(ioportid_t port, + ioportmask_t mask, + iomode_t mode) { + + switch (mode) { + case PAL_MODE_RESET: + case PAL_MODE_INPUT: + case PAL_MODE_INPUT_ANALOG: + port->DIRCLR = mask; + port->OUT = mask; + break; + case PAL_MODE_UNCONNECTED: + case PAL_MODE_INPUT_PULLUP: + port->DIRCLR = mask; + port->OUT = mask; + break; + case PAL_MODE_OUTPUT_PUSHPULL: + port->DIRSET = mask; + break; + } +} + +#endif /* HAL_USE_PAL */ + +/** @} */ + diff --git a/os/hal/ports/AVR/XMEGA/LLD/GPIOv1/hal_pal_lld.h b/os/hal/ports/AVR/XMEGA/LLD/GPIOv1/hal_pal_lld.h new file mode 100644 index 000000000..9e98a66da --- /dev/null +++ b/os/hal/ports/AVR/XMEGA/LLD/GPIOv1/hal_pal_lld.h @@ -0,0 +1,314 @@ +/* + ChibiOS - Copyright (C) 2017 Theodore Ateba + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file GPIOv1/hal_pal_lld.h + * @brief AVR XMEGA GPIO low level driver header file. + * + * @addtogroup PAL + * @{ + */ + +#ifndef HAL_PAL_LLD_H +#define HAL_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. + * @details 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; + +/** + * @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 + * PAL driver. Example: PORT F on Mega128. + */ +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 +#if defined(PORTF) || defined(__DOXYGEN__) + avr_gpio_setup_t portf; +#endif +#if defined(PORTG) || defined(__DOXYGEN__) + avr_gpio_setup_t portg; +#endif +#if defined(PORTH) || defined(__DOXYGEN__) + avr_gpio_setup_t porth; +#endif +#if defined(PORTJ) || defined(__DOXYGEN__) + avr_gpio_setup_t portj; +#endif +#if defined(PORTK) || defined(__DOXYGEN__) + avr_gpio_setup_t portk; +#endif +#if defined(PORTL) || defined(__DOXYGEN__) + avr_gpio_setup_t portl; +#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 volatile avr_gpio_registers_t * ioportid_t; +typedef volatile PORT_t * ioportid_t; + +/*===========================================================================*/ +/* I/O Ports Identifiers. */ +/*===========================================================================*/ + +#if defined(PORTA) || defined(__DOXYGEN__) +/** + * @brief GPIO port A identifier. + */ +#define IOPORT1 (&PORTA) +#endif + +#if defined(PORTB) || defined(__DOXYGEN__) +/** + * @brief GPIO port B identifier. + */ +#define IOPORT2 (&PORTB) +#endif + +#if defined(PORTC) || defined(__DOXYGEN__) +/** + * @brief GPIO port C identifier. + */ +#define IOPORT3 (&PORTC) +#endif + +#if defined(PORTD) || defined(__DOXYGEN__) +/** + * @brief GPIO port D identifier. + */ +#define IOPORT4 (&PORTD) +#endif + +#if defined(PORTE) || defined(__DOXYGEN__) +/** + * @brief GPIO port E identifier. + */ +#define IOPORT5 (&PORTE) +#endif + +#if defined(PORTF) || defined(__DOXYGEN__) +/** + * @brief GPIO port F identifier. + */ +#define IOPORT6 (&PORTF) +#endif + +#if defined(PORTG) || defined(__DOXYGEN__) +/** + * @brief GPIO port G identifier. + */ +#define IOPORT7 (&PORTG) +#endif + +#if defined(PORTH) || defined(__DOXYGEN__) +/** + * @brief GPIO port H identifier. + */ +#define IOPORT8 (&PORTH) +#endif + +#if defined(PORTJ) || defined(__DOXYGEN__) +/** + * @brief GPIO port J identifier. + */ +#define IOPORT9 (&PORTJ) +#endif + +#if defined(PORTK) || defined(__DOXYGEN__) +/** + * @brief GPIO port K identifier. + */ +#define IOPORT10 (&PORTK) +#endif + +#if defined(PORTL) || defined(__DOXYGEN__) +/** + * @brief GPIO port L identifier. + */ +#define IOPORT11 (&PORTL) +#endif + +/*===========================================================================*/ +/* Implementation, some of the following macros could be implemented as */ +/* functions, if so please put them in hal_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 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 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 port identifier + * @param[in] bits 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 port identifier + * @param[in] mask group mask + * @param[in] offset group bit offset within the port + * @param[in] mode group mode + * + * @notapi + */ +#define pal_lld_setgroupmode(port, mask, offset, mode) \ + _pal_lld_setgroupmode(port, mask << offset, mode) + +/** + * @brief Sets a pad logical state to @p PAL_HIGH. + * + * @param[in] port port identifier + * @param[in] pad pad number within the port + * + * @notapi + */ +#define pal_lld_setpad(port, pad) ((port)->OUTSET |= (1 << pad)) + +/** + * @brief Clears a pad logical state to @p PAL_LOW. + * + * @param[in] port port identifier + * @param[in] pad pad number within the port + * + * @notapi + */ +#define pal_lld_clearpad(port, pad) ((port)->OUTCLR |= (1 << 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 /* HAL_PAL_LLD_H */ + +/** @} */