[LPC11Uxx]: Initial support for GPIO (PAL)

This commit is contained in:
codetector 2020-11-26 23:31:17 -05:00
parent 4b53c6a0f5
commit 4e5d4015b8
No known key found for this signature in database
GPG Key ID: 7D42AB4D2C7B40A4
6 changed files with 544 additions and 23 deletions

View File

@ -487,35 +487,59 @@ typedef struct { /*!< (@ 0x40048000) SYSCON Structure
} LPC_SYSCON_Type;
// SYSCON_SYSPLLCTRL
#define SYSCON_SYSPLLCTRL_MSEL_POS 0U
#define SYSCON_SYSPLLCTRL_MSEL_MASK 0x1FU << SYSPLLCTRL_MSEL_POS
#define SYSCON_SYSPLLCTRL_PSEL_POS 5U
#define SYSCON_SYSPLLCTRL_PSEL_MASK 0x03U << SYSPLLCTRL_PSEL_POS
#define SYSCON_SYSPLLCTRL_MSEL_POS (0U)
#define SYSCON_SYSPLLCTRL_MSEL_MASK (0x1FU << SYSPLLCTRL_MSEL_POS)
#define SYSCON_SYSPLLCTRL_PSEL_POS (5U)
#define SYSCON_SYSPLLCTRL_PSEL_MASK (0x03U << SYSPLLCTRL_PSEL_POS)
// SYSCON_SYSPLLSTAT
#define SYSCON_SYSPLLSTAT_LOCK 0x1
// SYSCON_SYSPLLCLKSEL
#define SYSCON_SYSPLLCLKSEL_IRC 0x00U << 0
#define SYSCON_SYSPLLCLKSEL_SYSOSC 0x01U << 0
#define SYSCON_SYSPLLCLKSEL_IRC (0x00U << 0)
#define SYSCON_SYSPLLCLKSEL_SYSOSC (0x01U << 0)
#define SYSCON_SYSPLLCLKUEN_ENA 0x01
#define SYSCON_MAINCLKSEL_IRC 0x00U << 0
#define SYSCON_MAINCLKSEL_PLLIN 0x01U << 0
#define SYSCON_MAINCLKSEL_WATCHDOG 0x02U << 0
#define SYSCON_MAINCLKSEL_PLLOUT 0x03U << 0
#define SYSCON_MAINCLKSEL_IRC (0x00U << 0)
#define SYSCON_MAINCLKSEL_PLLIN (0x01U << 0)
#define SYSCON_MAINCLKSEL_WATCHDOG (0x02U << 0)
#define SYSCON_MAINCLKSEL_PLLOUT (0x03U << 0)
#define SYSCON_MAINCLKUEN_ENA 0x01
#define SYS_CON_PDRUNCFG_IRCOUT_PD 0x1U << 0U
#define SYS_CON_PDRUNCFG_IRC_PD 0x1U << 1U
#define SYS_CON_PDRUNCFG_FLASH_PD 0x1U << 2U
#define SYS_CON_PDRUNCFG_BOD_PD 0x1U << 3U
#define SYS_CON_PDRUNCFG_ADC_PD 0x1U << 4U
#define SYS_CON_PDRUNCFG_SYSSOC_PD 0x1U << 5U
#define SYS_CON_PDRUNCFG_WDTOSC_PD 0x1U << 6U
#define SYS_CON_PDRUNCFG_SYSPLL_PD 0x1U << 7U
#define SYS_CON_PDRUNCFG_USBPLL_PD 0x1U << 8U
#define SYS_CON_PDRUNCFG_USBPAD_PD 0x1U << 10U
#define SYSAHBCLKCTRL_SYS (1U << 0)
#define SYSAHBCLKCTRL_ROM (1U << 1)
#define SYSAHBCLKCTRL_RAM0 (1U << 2)
#define SYSAHBCLKCTRL_FLASHREG (1U << 3)
#define SYSAHBCLKCTRL_FLASHARRAY (1U << 4)
#define SYSAHBCLKCTRL_I2C (1U << 5)
#define SYSAHBCLKCTRL_GPIO (1U << 6)
#define SYSAHBCLKCTRL_CT16B0 (1U << 7)
#define SYSAHBCLKCTRL_CT16B1 (1U << 8)
#define SYSAHBCLKCTRL_CT32B0 (1U << 9)
#define SYSAHBCLKCTRL_CT32B1 (1U << 10)
#define SYSAHBCLKCTRL_SSP0 (1U << 11)
#define SYSAHBCLKCTRL_USART (1U << 12)
#define SYSAHBCLKCTRL_ADC (1U << 13)
#define SYSAHBCLKCTRL_USB (1U << 14)
#define SYSAHBCLKCTRL_WWDT (1U << 15)
#define SYSAHBCLKCTRL_IOCON (1U << 16)
#define SYSAHBCLKCTRL_SSP1 (1U << 18)
#define SYSAHBCLKCTRL_PINT (1U << 19)
#define SYSAHBCLKCTRL_GROUP0INT (1U << 23)
#define SYSAHBCLKCTRL_GROUP1INT (1U << 24)
#define SYSAHBCLKCTRL_RAM1 (1U << 26)
#define SYSAHBCLKCTRL_USBRAM (1U << 27)
#define SYSCON_PDRUNCFG_IRCOUT_PD (1U << 0U)
#define SYSCON_PDRUNCFG_IRC_PD (1U << 1U)
#define SYSCON_PDRUNCFG_FLASH_PD (1U << 2U)
#define SYSCON_PDRUNCFG_BOD_PD (1U << 3U)
#define SYSCON_PDRUNCFG_ADC_PD (1U << 4U)
#define SYSCON_PDRUNCFG_SYSSOC_PD (1U << 5U)
#define SYSCON_PDRUNCFG_WDTOSC_PD (1U << 6U)
#define SYSCON_PDRUNCFG_SYSPLL_PD (1U << 7U)
#define SYSCON_PDRUNCFG_USBPLL_PD (1U << 8U)
#define SYSCON_PDRUNCFG_USBPAD_PD (1U << 10U)
// ------------------------------------------------------------------------------------------------
// ----- GPIO_PIN_INT -----
// ------------------------------------------------------------------------------------------------

View File

@ -0,0 +1,3 @@
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/LPC/LLD/GPIO/hal_pal_lld.c
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/LPC/LLD/GPIO

View File

@ -0,0 +1,108 @@
/*
ChibiOS - Copyright (C) 2020 Yaotian Feng / Codetector
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file hal_pal_lld.c
* @brief LPC11Uxx PAL subsystem low level driver source.
*
* @addtogroup PAL
* @{
*/
#include "hal.h"
#if (HAL_USE_PAL == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief LPC1Uxx I/O ports configuration.
*
* @notapi
*/
void _pal_lld_init(void) {
// Enable GPIO / IOCON CLK
LPC_SYSCON->SYSAHBCLKCTRL |= SYSAHBCLKCTRL_GPIO | SYSAHBCLKCTRL_IOCON;
}
/**
* @brief Group 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
*
* @notapi
*/
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
iomode_t mode) {
for (uint8_t i = 0; i < PAL_IOPORTS_WIDTH; ++i)
{
if (mask & (1U << i)) {
_pal_lld_setpadmode(port, i, mode);
}
}
}
/**
* @brief Pads mode setup.
* @details This function programs a pads with the specified mode.
*
* @param[in] port the port identifier
* @param[in] pad the pad id
* @param[in] mode the mode
*
* @notapi
*/
void _pal_lld_setpadmode(ioportid_t port, iopadid_t pad, iomode_t mode) {
((uint32_t *)LPC_IOCON)[(PAL_IOPORTS_WIDTH * LPC_IOPORT_NUM(port)) + pad]
= mode & MODE_IOCONF_MASK;
if (mode & MODE_DIR_MASK) {
LPC_GPIO->DIR[LPC_IOPORT_NUM(port)] |= 1U << pad;
} else {
LPC_GPIO->DIR[LPC_IOPORT_NUM(port)] &= ~(1U << pad);
}
}
#endif /* HAL_USE_PAL == TRUE */
/** @} */

View File

@ -0,0 +1,383 @@
/*
ChibiOS - Copyright (C) 2020 Yaotian Feng / Codetector
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file hal_pal_lld.h
* @brief LPC11Uxx PAL subsystem low level driver header.
*
* @addtogroup PAL
* @{
*/
#ifndef HAL_PAL_LLD_H
#define HAL_PAL_LLD_H
#if (HAL_USE_PAL == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Unsupported modes and specific modes */
/*===========================================================================*/
/* Specifies palInit() without parameter, required until all platforms will
be updated to the new style.*/
#define PAL_NEW_INIT
/*===========================================================================*/
/* I/O Ports Types and constants. */
/*===========================================================================*/
/**
* @name Port related definitions
* @{
*/
/**
* @brief Width, in bits, of an I/O port.
*/
#define PAL_IOPORTS_WIDTH 32U
/**
* @brief Whole port mask.
* @details This macro specifies all the valid bits into a port.
*/
#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFFFFFFU)
/** @} */
/**
* @name Line handling macros
* @{
*/
/**
* @brief Forms a line identifier.
* @details A port/pad pair are encoded into an @p ioline_t type. The encoding
* of this type is platform-dependent.
*/
#define PAL_LINE(port, pad) \
((ioline_t)((uint32_t)(port)) | ((uint32_t)(pad)))
/**
* @brief Decodes a port identifier from a line identifier.
*/
#define PAL_PORT(line) \
(((uint32_t)(line)) & 0xFFFFFFE0U)
/**
* @brief Decodes a pad identifier from a line identifier.
*/
#define PAL_PAD(line) \
(((uint32_t)(line) & 0x0000001FU))
/**
* @brief Value identifying an invalid line.
*/
#define PAL_NOLINE 0U
/** @} */
/**
* @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.
* @note Implementations may extend this structure to contain more,
* architecture dependent, fields.
*/
typedef struct {
} PALConfig;
/**
* @brief Digital I/O port sized unsigned type.
*/
typedef uint32_t ioportmask_t;
/**
* @brief Digital I/O modes.
*/
typedef uint32_t iomode_t;
#define MODE_IOCONF_MASK 0xFFFF
#define MODE_FUNC_POS 0U
#define MODE_FUNC_MASK (0x7U << MODE_FUNC_POS)
#define MODE_FUNC_DEFAULT (0x0U << MODE_FUNC_POS)
#define MODE_FUNC_ALT1 (0x1U << MODE_FUNC_POS)
#define MODE_FUNC_ALT2 (0x2U << MODE_FUNC_POS)
#define MODE_FUNC_ALT3 (0x3U << MODE_FUNC_POS)
#define MODE_FUNC_ALT4 (0x4U << MODE_FUNC_POS)
#define MODE_FUNC_ALT5 (0x5U << MODE_FUNC_POS)
#define MODE_FUNC_ALT6 (0x6U << MODE_FUNC_POS)
#define MODE_FUNC_ALT7 (0x7U << MODE_FUNC_POS)
#define MODE_MODE_POS 3U
#define MODE_MODE_MASK (0x3U << MODE_MODE_POS)
#define MODE_MODE_INACTIVE (0x0U << MODE_MODE_POS)
#define MODE_MODE_PULL_DOWN (0x1U << MODE_MODE_POS)
#define MODE_MODE_PULL_UP (0x2U << MODE_MODE_POS)
#define MODE_MODE_REPEATER (0x3U << MODE_MODE_POS)
#define MODE_DIR_POS 31U
#define MODE_DIR_MASK (0x1U << MODE_DIR_POS)
#define MODE_DIR_IN (0U << MODE_DIR_POS)
#define MODE_DIR_OUT (1U << MODE_DIR_POS)
/**
* @brief Type of an I/O line.
*/
typedef uint32_t ioline_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 uint32_t ioportid_t;
/**
* @brief Type of an pad identifier.
*/
typedef uint32_t iopadid_t;
/*===========================================================================*/
/* I/O Ports Identifiers. */
/*===========================================================================*/
/**
* @brief First I/O port identifier.
* @details Low level drivers can define multiple ports, it is suggested to
* use this naming convention.
*/
#define LPC_IOPORT_ID(x) (x << 5U)
#define LPC_IOPORT_NUM(x) (x >> 5U)
#define IOPORT0 LPC_IOPORT_ID(0)
#define IOPORT1 LPC_IOPORT_ID(1)
/*===========================================================================*/
/* 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.
*
* @notapi
*/
#define pal_lld_init() _pal_lld_init()
/**
* @brief Reads the physical I/O port states.
*
* @param[in] port port identifier
* @return The port bits.
*
* @notapi
*/
#define pal_lld_readport(port) \
(LPC_GPIO->PIN[LPC_IOPORT_NUM(port)])
/**
* @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) \
(LPC_GPIO->PIN[LPC_IOPORT_NUM(port)])
/**
* @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) \
do { \
(LPC_GPIO->PIN[LPC_IOPORT_NUM(port)]) = bits; \
} while (false)
/**
* @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 bits mask on a I/O port.
* @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.
*
* @param[in] port port identifier
* @param[in] bits bits to be ORed on the specified port
*
* @notapi
*/
#define pal_lld_setport(port, bits) \
do { \
(LPC_GPIO->SET[LPC_IOPORT_NUM(port)]) = bits; \
} while (false)
/**
* @brief Clears a bits mask on a I/O port.
* @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.
*
* @param[in] port port identifier
* @param[in] bits bits to be cleared on the specified port
*
* @notapi
*/
#define pal_lld_clearport(port, bits) \
do { \
(LPC_GPIO->CLR[LPC_IOPORT_NUM(port)]) = bits; \
} while (false)
/**
* @brief Toggles a bits mask on a I/O port.
* @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.
*
* @param[in] port port identifier
* @param[in] bits bits to be XORed on the specified port
*
* @notapi
*/
#define pal_lld_toggleport(port, bits) \
do { \
(LPC_GPIO->NOT[LPC_IOPORT_NUM(port)]) = bits; \
} while (false)
/**
* @brief Reads a logical state from an I/O pad.
* @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.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
* @return The logical state.
* @retval PAL_LOW low logical state.
* @retval PAL_HIGH high logical state.
*
* @notapi
*/
#define pal_lld_readpad(port, pad) \
(LPC_GPIO->B[(PAL_IOPORTS_WIDTH * LPC_IOPORT_NUM(port)) + pad])
/**
* @brief Writes a logical state on an output 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.
*
* @param[in] port port identifier
* @param[in] pad 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) \
do { \
(LPC_GPIO->B[(PAL_IOPORTS_WIDTH * LPC_IOPORT_NUM(port)) + pad]) = bit; \ \
} while (false)
/**
* @brief Pad mode setup.
* @details This function programs a pad with the specified mode.
* @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.
* @note Programming an unknown or unsupported mode is silently ignored.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
* @param[in] mode pad mode
*
* @notapi
*/
#define pal_lld_setpadmode(port, pad, mode) \
_pal_lld_setpadmode(port, pad, mode)
/**
* @brief Returns a PAL event structure associated to a pad.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
*
* @notapi
*/
#define pal_lld_get_pad_event(port, pad) \
&_pal_events[0]; (void)(port); (void)pad
/**
* @brief Returns a PAL event structure associated to a line.
*
* @param[in] line line identifier
*
* @notapi
*/
#define pal_lld_get_line_event(line) \
&_pal_events[0]; (void)line
#if !defined(__DOXYGEN__)
#if (PAL_USE_WAIT == TRUE) || (PAL_USE_CALLBACKS == TRUE)
extern palevent_t _pal_events[1];
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
void _pal_lld_init(void);
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
iomode_t mode);
void _pal_lld_setpadmode(ioportid_t port,
iopadid_t pad,
iomode_t mode);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_PAL == TRUE */
#endif /* HAL_PAL_LLD_H */
/** @} */

View File

@ -58,7 +58,7 @@
#error "Using a wrong mcuconf.h file, LPC11Uxx_MCUCONF not defined"
#endif
#if (defined(LPC_USE_SYSOSC) && LPC_USE_SYSOSC == FALSE) || !defined(LPC_SYSOSC_FREQUENCY)
#if defined(LPC_USE_SYSOSC) && LPC_USE_SYSOSC != FALSE && !defined(LPC_SYSOSC_FREQUENCY)
#error "LPC_SYSOSC_FREQUENCY must be defined if LPC_USE_SYSOSC"
#endif
@ -89,7 +89,7 @@ SYSCON_SYSPLLCLKSEL_SYSOSC"
// PLL OUT
#if defined(LPC_SYSPLL_MULT) && LPC_SYSPLL_MULT > 0 && LPC_SYSPLL_MULT <= 32 \
&& defined(LPC_SYSPLL_PDIV) && (LPC_SYSPLL_PDIV == 2 || LPC_SYSPLL_PDIV == 4 \
&& LPC_SYSPLL_PDIV == 8 || LPC_SYSPLL_PDIV == 16)
|| LPC_SYSPLL_PDIV == 8 || LPC_SYSPLL_PDIV == 16)
#if LPC_SYSPLL_PDIV == 2
#define LPC_SYSPLL_PSEL_VAL 0x0U
@ -99,7 +99,9 @@ SYSCON_SYSPLLCLKSEL_SYSOSC"
#define LPC_SYSPLL_PSEL_VAL 0x2U
#elif LPC_SYSPLL_PDIV == 16
#define LPC_SYSPLL_PSEL_VAL 0x3U
#endif
#else
#error "INVALID PDIV VALUE"
#endif //LPC_SYSPLL_PDIV == xx
#if (LPC_SYSPLLIN_FREQUENCY * LPC_SYSPLL_MULT * LPC_SYSPLL_PDIV < 156000000UL) ||\
(LPC_SYSPLLIN_FREQUENCY * LPC_SYSPLL_MULT * LPC_SYSPLL_PDIV > 320000000UL)

View File

@ -7,6 +7,7 @@ PLATFORMINC = ${CHIBIOS}/os/hal/ports/common/ARMCMx \
${CHIBIOS_CONTRIB}/os/hal/ports/LPC/LPC11Uxx
include $(CHIBIOS_CONTRIB)/os/hal/ports/LPC/LLD/STM/driver.mk
include $(CHIBIOS_CONTRIB)/os/hal/ports/LPC/LLD/GPIO/driver.mk
# Shared variables
ALLCSRC += $(PLATFORMSRC)