From a3406f100b4f948b453d4275ba7db9552712ebbf Mon Sep 17 00:00:00 2001 From: Brian Viele Date: Sun, 1 Dec 2019 21:46:07 -0500 Subject: [PATCH] pac55xx: gpio: Initial Implementation of PAC55xx GPIO Driver * Conforms mostly to the STM32 GPIO API where possible. * Supports pin configuration (direction, pull-up/down, etc.) as well as pinmux configuration. * Supports set/clear/get operations to the GPIO port/pins. * Created base doxy header and groups to align with existing formatting. --- include/libopencm3/pac55xx/ccs.h | 141 ++++++++++ include/libopencm3/pac55xx/doc-pac55xx.h | 22 ++ include/libopencm3/pac55xx/gpio.h | 332 +++++++++++++++++++++++ include/libopencm3/pac55xx/memorymap.h | 77 ++++++ lib/pac55xx/Makefile | 2 + lib/pac55xx/gpio.c | 164 +++++++++++ lib/pac55xx/vector_chipset.c | 3 +- 7 files changed, 739 insertions(+), 2 deletions(-) create mode 100644 include/libopencm3/pac55xx/ccs.h create mode 100644 include/libopencm3/pac55xx/doc-pac55xx.h create mode 100644 include/libopencm3/pac55xx/gpio.h create mode 100644 include/libopencm3/pac55xx/memorymap.h create mode 100644 lib/pac55xx/gpio.c diff --git a/include/libopencm3/pac55xx/ccs.h b/include/libopencm3/pac55xx/ccs.h new file mode 100644 index 00000000..29ff6d6a --- /dev/null +++ b/include/libopencm3/pac55xx/ccs.h @@ -0,0 +1,141 @@ +/** @file + * + * Clock Control and System Defines for the Qorvo PAC55xx series of microcontrollers. + * + * @defgroup system_defines Clock Config and System Defines + * @ingroup PAC55xx_defines + * @author Brian Viele + * LGPL License Terms @ref lgpl_license + * @date 1 Dec 2019 + * + * Definitions in this file come from the PAC55XX Family User Guide Rev 1.21 + * by Active-Semi dated August 26, 2019. + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +#ifndef INCLUDE_LIBOPENCM3_PAC55XX_CCS_H_ +#define INCLUDE_LIBOPENCM3_PAC55XX_CCS_H_ + +#include + +/** Clock Control Registers + * @defgroup clock_config_regs Clock Config Registers. + * @ingroup system_defines + * @{*/ +#define CCSCTL MMIO32(SCC_BASE) +#define CCSPLLCTL MMIO32(SCC_BASE + 0x04) +#define CCSROSCTRIM MMIO32(SCC_BASE + 0x08) +/**@}*/ + +/** Port Pin Config Addresses + * @defgroup port_pin_addresses Port Pinmux Register Base. + * @ingroup system_defines + * @{*/ +#define CCS_PORTA (SCC_BASE + 0x0C) +#define CCS_PORTB (SCC_BASE + 0x10) +#define CCS_PORTC (SCC_BASE + 0x14) +#define CCS_PORTD (SCC_BASE + 0x18) +#define CCS_PORTE (SCC_BASE + 0x1C) +#define CCS_PORTF (SCC_BASE + 0x20) +#define CCS_PORTG (SCC_BASE + 0x24) +/**@}*/ + +/** Port Pin Mux Select Registers + * @defgroup pmux_sel_regs PMUXSEL register mapping. + * @ingroup system_defines + * @{*/ +#define CCS_MUXSELR(base) MMIO32(base) +#define CCS_PAMUXSELR CCS_MUXSELR(CCS_PORTA) +#define CCS_PBMUXSELR CCS_MUXSELR(CCS_PORTB) +#define CCS_PCMUXSELR CCS_MUXSELR(CCS_PORTC) +#define CCS_PDMUXSELR CCS_MUXSELR(CCS_PORTD) +#define CCS_PEMUXSELR CCS_MUXSELR(CCS_PORTE) +#define CCS_PFMUXSELR CCS_MUXSELR(CCS_PORTF) +#define CCS_PGMUXSELR CCS_MUXSELR(CCS_PORTG) +#define CCS_MUXSELR_MASK 0x7 +/* Enum type for port function setting for type specificity. */ +typedef enum { + CCS_MUXSEL_GPIO = 0, + CCS_MUXSEL_AF1 = 1, + CCS_MUXSEL_AF2 = 2, + CCS_MUXSEL_AF3 = 3, + CCS_MUXSEL_AF4 = 4, + CCS_MUXSEL_AF5 = 5, + CCS_MUXSEL_AF6 = 6, + CCS_MUXSEL_AF7 = 7, +} ccs_muxsel_func_t; +/**@}*/ + +/** Port Pull-Up/Down Enable Registers. + * @defgroup pden_regs PUEN PDEN register mapping. + * @ingroup system_defines + * @{*/ +#define CCS_PUENR(base) MMIO32(base + 0x1C) +#define CCS_PAPUENR CCS_PUENR(CCS_PORTA) +#define CCS_PBPUENR CCS_PUENR(CCS_PORTB) +#define CCS_PCPUENR CCS_PUENR(CCS_PORTC) +#define CCS_PDPUENR CCS_PUENR(CCS_PORTD) +#define CCS_PEPUENR CCS_PUENR(CCS_PORTE) +#define CCS_PFPUENR CCS_PUENR(CCS_PORTF) +#define CCS_PGPUENR CCS_PUENR(CCS_PORTG) +#define CCS_PDENR(base) MMIO32(base + 0x38) +#define CCS_PAPDENR CCS_PDENR(CCS_PORTA) +#define CCS_PBPDENR CCS_PDENR(CCS_PORTB) +#define CCS_PCPDENR CCS_PDENR(CCS_PORTC) +#define CCS_PDPDENR CCS_PDENR(CCS_PORTD) +#define CCS_PEPDENR CCS_PDENR(CCS_PORTE) +#define CCS_PFPDENR CCS_PDENR(CCS_PORTF) +#define CCS_PGPDENR CCS_PDENR(CCS_PORTG) +/* Pull Up/Down enum for type specificity. */ +typedef enum { + CCS_IO_PULL_NONE = 0, + CCS_IO_PULL_UP = 1, + CCS_IO_PULL_DOWN = 2 +} ccs_pull_updown_t; +/**@}*/ + +/** Port Drive Strength Enable Registers. + * @defgroup dsr_regs DSR register mapping. + * @ingroup system_defines + * @{*/ +#define CCS_DSR(base) MMIO32(base + 0x54) +#define CCS_PADSR CCS_DSR(CCS_PORTA) +#define CCS_PBDSR CCS_DSR(CCS_PORTB) +#define CCS_PCDSR CCS_DSR(CCS_PORTC) +#define CCS_PDDSR CCS_DSR(CCS_PORTD) +#define CCS_PEDSR CCS_DSR(CCS_PORTE) +#define CCS_PFDSR CCS_DSR(CCS_PORTF) +#define CCS_PGDSR CCS_DSR(CCS_PORTG) +#define CCS_DSR_MASK 0x7 +#define CCS_DSR_MASK_PIN(pin) (CCS_DSR_MASK << ((pin)) * 4) +#define CCS_DSR_DS_VAL(pin, ds) (((ds)&CCS_DSR_MASK) << ((pin)*4)) +#define CCS_DSR_SCHMIDT_PIN(pin) (BIT0 << (((pin)*4) + 3)) + +/* Drive strength enumeration for type specificity. */ +typedef enum { + CCS_DSR_DS_6MA = 0x00, + CCS_DSR_DS_8MA = 0x01, + CCS_DSR_DS_11MA = 0x02, + CCS_DSR_DS_14MA = 0x03, + CCS_DSR_DS_17MA = 0x04, + CCS_DSR_DS_20MA = 0x05, + CCS_DSR_DS_22MA = 0x06, + CCS_DSR_DS_25MA = 0x07, +} ccs_drive_strength_t; +/**@}*/ + +#endif /* INCLUDE_LIBOPENCM3_PAC55XX_CCS_H_ */ diff --git a/include/libopencm3/pac55xx/doc-pac55xx.h b/include/libopencm3/pac55xx/doc-pac55xx.h new file mode 100644 index 00000000..4b218dd7 --- /dev/null +++ b/include/libopencm3/pac55xx/doc-pac55xx.h @@ -0,0 +1,22 @@ +/** @page libopencm3 PAC55xx + +@version 1.0.0 + +API documentation for Qorvo PAC55xx series MCUs. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup peripheral_apis Peripheral APIs + * APIs for device peripherals + */ + +/** @defgroup PAC55xx_defines PAC55xx Defines + +@brief Defined Constants and Types for the PAC55xx series + +@version 1.0.0 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/include/libopencm3/pac55xx/gpio.h b/include/libopencm3/pac55xx/gpio.h new file mode 100644 index 00000000..fa4e9748 --- /dev/null +++ b/include/libopencm3/pac55xx/gpio.h @@ -0,0 +1,332 @@ +/** @file + * + * GPIO definitions for the Qorvo PAC55xx series of microcontrollers. + * + * @addtogroup PAC55xx_gpio GPIO + * @ingroup PAC55xx_defines + * @author Brian Viele + * LGPL License Terms @ref lgpl_license + * @date 1 Dec 2019 + * + * Definitions in this file come from the PAC55XX Family User Guide Rev 1.21 + * by Active-Semi dated August 26, 2019. + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +#ifndef INCLUDE_LIBOPENCM3_PAC55XX_GPIO_H_ +#define INCLUDE_LIBOPENCM3_PAC55XX_GPIO_H_ + +#include + +/* Note: CCS include file defines pinmux, drive strength, pull-up/pull-down, etc. */ +#include +#include + +/** GPIO port base addresses (for convenience) + * @defgroup gpio_port_id GPIO Port IDs + * @ingroup PAC55xx_gpio + * @{*/ +#define GPIOA GPIOA_BASE +#define GPIOB GPIOB_BASE +#define GPIOC GPIOC_BASE +#define GPIOD GPIOD_BASE +#define GPIOE GPIOE_BASE +#define GPIOF GPIOF_BASE +#define GPIOG GPIOG_BASE +/**@}*/ + +/** GPIO number definitions (for convenience) + * @defgroup gpio_pin_id GPIO Pin Identifiers + * @ingroup PAC55xx_gpio + * @{*/ +#define GPIO_MAX_PIN (7U) +#define GPIO0 BIT0 +#define GPIO1 BIT1 +#define GPIO2 BIT2 +#define GPIO3 BIT3 +#define GPIO4 BIT4 +#define GPIO5 BIT5 +#define GPIO6 BIT6 +#define GPIO7 BIT7 +#define GPIO_ALL 0xff +/**@}*/ + +/** GPIO Mode Register Definitions + * @defgroup gpio_mode_regs GPIO MODE register mapping. + * @ingroup PAC55xx_gpio + * @{*/ +/* Enum definitions for at least minimal type safety. */ +typedef enum { + GPIO_ANALOG_INPUT = 0, + GPIO_PUSH_PULL_OUTPUT = 1, + GPIO_OPEN_DRAIN_OUTPUT = 2, + GPIO_HIGH_IMPEDENCE_INPUT = 3, +} gpio_mode_t; +#define GPIO_MODER(base) MMIO32((base) + 0x00) +#define GPIOA_MODER GPIO_MODER(GPIOA) +#define GPIOB_MODER GPIO_MODER(GPIOB) +#define GPIOC_MODER GPIO_MODER(GPIOC) +#define GPIOD_MODER GPIO_MODER(GPIOD) +#define GPIOE_MODER GPIO_MODER(GPIOE) +#define GPIOF_MODER GPIO_MODER(GPIOF) +#define GPIOG_MODER GPIO_MODER(GPIOG) +#define GPIO_MODER_MASK 0x3 +#define GPIO_MODER_MASK_PIN(pin) (GPIO_MODER_MASK << ((pin)*2)) +#define GPIO_MODER_MODE(pin, mode) (((mode)&GPIO_MODER_MASK) << ((pin)*2)) +/**@}*/ + +/** GPIO Output Mask Register Definitions. This register may be used to lock the output value of + * a pin as changes to masked pins will have no effect. + * @defgroup gpio_outmask_regs GPIO OUTMASK register mapping. + * @ingroup PAC55xx_gpio + * @{*/ +#define GPIO_OUTMASKR(base) MMIO32((base) + 0x04) +#define GPIOA_OUTMASKR GPIO_OUTMASKR(GPIOA) +#define GPIOB_OUTMASKR GPIO_OUTMASKR(GPIOB) +#define GPIOC_OUTMASKR GPIO_OUTMASKR(GPIOC) +#define GPIOD_OUTMASKR GPIO_OUTMASKR(GPIOD) +#define GPIOE_OUTMASKR GPIO_OUTMASKR(GPIOE) +#define GPIOF_OUTMASKR GPIO_OUTMASKR(GPIOF) +#define GPIOG_OUTMASKR GPIO_OUTMASKR(GPIOG) +/**@}*/ + +/** GPIO Output Register Definitions. + * @defgroup gpio_out_regs GPIO OUT register mapping. + * @ingroup PAC55xx_gpio + * @{*/ +#define GPIO_OUTR(base) MMIO32((base) + 0x08) +#define GPIOA_OUTR GPIO_OUTR(GPIOA) +#define GPIOB_OUTR GPIO_OUTR(GPIOB) +#define GPIOC_OUTR GPIO_OUTR(GPIOC) +#define GPIOD_OUTR GPIO_OUTR(GPIOD) +#define GPIOE_OUTR GPIO_OUTR(GPIOE) +#define GPIOF_OUTR GPIO_OUTR(GPIOF) +#define GPIOG_OUTR GPIO_OUTR(GPIOG) +/**@}*/ + +/** GPIO Input Register Definitions. + * @defgroup gpio_out_regs GPIO IN register mapping. + * @ingroup PAC55xx_gpio + * @{*/ +#define GPIO_INR(base) MMIO32((base) + 0x0C) +#define GPIOA_INR GPIO_INR(GPIOA) +#define GPIOB_INR GPIO_INR(GPIOB) +#define GPIOC_INR GPIO_INR(GPIOC) +#define GPIOD_INR GPIO_INR(GPIOD) +#define GPIOE_INR GPIO_INR(GPIOE) +#define GPIOF_INR GPIO_INR(GPIOF) +#define GPIOG_INR GPIO_INR(GPIOG) +/**@}*/ + +/** GPIO Interrupt Enable Register Definitions. + * @defgroup gpio_inten_regs GPIO INTEN register mapping. + * @ingroup PAC55xx_gpio + * @{*/ +#define GPIO_INTENR(base) MMIO32((base) + 0x10) +#define GPIOA_INTENR GPIO_INTENR(GPIOA) +#define GPIOB_INTENR GPIO_INTENR(GPIOB) +#define GPIOC_INTENR GPIO_INTENR(GPIOC) +#define GPIOD_INTENR GPIO_INTENR(GPIOD) +#define GPIOE_INTENR GPIO_INTENR(GPIOE) +#define GPIOF_INTENR GPIO_INTENR(GPIOF) +#define GPIOG_INTENR GPIO_INTENR(GPIOG) +/**@}*/ + +/** GPIO Interrupt Flag Register Definitions. + * @defgroup gpio_intflag_regs GPIO INTFLAG register mapping. + * @ingroup PAC55xx_gpio + * @{*/ +#define GPIO_INTFLAGR(base) MMIO32((base) + 0x14) +#define GPIOA_INTFLAGR GPIO_INTFLAGR(GPIOA) +#define GPIOB_INTFLAGR GPIO_INTFLAGR(GPIOB) +#define GPIOC_INTFLAGR GPIO_INTFLAGR(GPIOC) +#define GPIOD_INTFLAGR GPIO_INTFLAGR(GPIOD) +#define GPIOE_INTFLAGR GPIO_INTFLAGR(GPIOE) +#define GPIOF_INTFLAGR GPIO_INTFLAGR(GPIOF) +#define GPIOG_INTFLAGR GPIO_INTFLAGR(GPIOG) +/**@}*/ + +/** GPIO Interrupt Clear Register Definitions. + * @defgroup gpio_intclear_regs GPIO INTCLEAR register mapping. + * @ingroup PAC55xx_gpio + * @{*/ +#define GPIO_INTCLEARR(base) MMIO32((base) + 0x1C) +#define GPIOA_INTCLEARR GPIO_INTCLEARR(GPIOA) +#define GPIOB_INTCLEARR GPIO_INTCLEARR(GPIOB) +#define GPIOC_INTCLEARR GPIO_INTCLEARR(GPIOC) +#define GPIOD_INTCLEARR GPIO_INTCLEARR(GPIOD) +#define GPIOE_INTCLEARR GPIO_INTCLEARR(GPIOE) +#define GPIOF_INTCLEARR GPIO_INTCLEARR(GPIOF) +#define GPIOG_INTCLEARR GPIO_INTCLEARR(GPIOG) +/**@}*/ + +/** GPIO Interrupt Type Register Definitions. + * @defgroup gpio_inttype_regs GPIO INTTYPE register mapping. + * @ingroup PAC55xx_gpio + * @{*/ +#define GPIO_INTTYPE_EDGE 0U +#define GPIO_INTTYPE_LEVEL 1U +#define GPIO_INTTYPER(base) MMIO32((base) + 0x20) +#define GPIOA_INTTYPER GPIO_INTTYPER(GPIOA) +#define GPIOB_INTTYPER GPIO_INTTYPER(GPIOB) +#define GPIOC_INTTYPER GPIO_INTTYPER(GPIOC) +#define GPIOD_INTTYPER GPIO_INTTYPER(GPIOD) +#define GPIOE_INTTYPER GPIO_INTTYPER(GPIOE) +#define GPIOF_INTTYPER GPIO_INTTYPER(GPIOF) +#define GPIOG_INTTYPER GPIO_INTTYPER(GPIOG) +/**@}*/ + +/** GPIO Interrupt Config Register Definitions. + * @defgroup gpio_intcfg_regs GPIO INTCFG register mapping. + * @ingroup PAC55xx_gpio + * @{*/ +#define GPIO_INTCFG_FALLING_LOW 0U +#define GPIO_INTCFG_RISING_HIGH 1U +#define GPIO_INTCFGR(base) MMIO32((base) + 0x24) +#define GPIOA_INTCFGR GPIO_INTCFGR(GPIOA) +#define GPIOB_INTCFGR GPIO_INTCFGR(GPIOB) +#define GPIOC_INTCFGR GPIO_INTCFGR(GPIOC) +#define GPIOD_INTCFGR GPIO_INTCFGR(GPIOD) +#define GPIOE_INTCFGR GPIO_INTCFGR(GPIOE) +#define GPIOF_INTCFGR GPIO_INTCFGR(GPIOF) +#define GPIOG_INTCFGR GPIO_INTCFGR(GPIOG) +/**@}*/ + +/** GPIO Interrupt Edge Both Definitions. This overrides the config if set. + * @defgroup gpio_intedgeboth_regs GPIO INTEDGEBOTH register mapping. + * @ingroup PAC55xx_gpio + * @{*/ +#define GPIO_INTEDGEBOTHR(base) MMIO32((base) + 0x28) +#define GPIOA_INTEDGEBOTHR GPIO_INTEDGEBOTHR(GPIOA) +#define GPIOB_INTEDGEBOTHR GPIO_INTEDGEBOTHR(GPIOB) +#define GPIOC_INTEDGEBOTHR GPIO_INTEDGEBOTHR(GPIOC) +#define GPIOD_INTEDGEBOTHR GPIO_INTEDGEBOTHR(GPIOD) +#define GPIOE_INTEDGEBOTHR GPIO_INTEDGEBOTHR(GPIOE) +#define GPIOF_INTEDGEBOTHR GPIO_INTEDGEBOTHR(GPIOF) +#define GPIOG_INTEDGEBOTHR GPIO_INTEDGEBOTHR(GPIOG) +/**@}*/ + +/** GPIO Clock Synchronization Settings. When set, this enables 3-clock synchronizer on pins. + * @defgroup gpio_clksync_regs GPIO CLKSYNC register mapping. + * @ingroup PAC55xx_gpio + * @{*/ +#define GPIO_CLKSYNCR(base) MMIO32((base) + 0x2C) +#define GPIOA_CLKSYNCR GPIO_CLKSYNCR(GPIOA) +#define GPIOB_CLKSYNCR GPIO_CLKSYNCR(GPIOB) +#define GPIOC_CLKSYNCR GPIO_CLKSYNCR(GPIOC) +#define GPIOD_CLKSYNCR GPIO_CLKSYNCR(GPIOD) +#define GPIOE_CLKSYNCR GPIO_CLKSYNCR(GPIOE) +#define GPIOF_CLKSYNCR GPIO_CLKSYNCR(GPIOF) +#define GPIOG_CLKSYNCR GPIO_CLKSYNCR(GPIOG) +/**@}*/ + +/** GPIO Set Register. This register can be used for atomic setting of outputs. + * @defgroup gpio_doset_regs GPIO DOSET register mapping. + * @ingroup PAC55xx_gpio + * @{*/ +#define GPIO_DOSETR(base) MMIO32((base) + 0x30) +#define GPIOA_DOSETR GPIO_DOSETR(GPIOA) +#define GPIOB_DOSETR GPIO_DOSETR(GPIOB) +#define GPIOC_DOSETR GPIO_DOSETR(GPIOC) +#define GPIOD_DOSETR GPIO_DOSETR(GPIOD) +#define GPIOE_DOSETR GPIO_DOSETR(GPIOE) +#define GPIOF_DOSETR GPIO_DOSETR(GPIOF) +#define GPIOG_DOSETR GPIO_DOSETR(GPIOG) +/**@}*/ + +/** GPIO Set Register. This register can be used for atomic setting of outputs. + * @defgroup gpio_doclear_regs GPIO DOCLEAR register mapping. + * @ingroup PAC55xx_gpio + * @{*/ +#define GPIO_DOCLEARR(base) MMIO32((base) + 0x34) +#define GPIOA_DOCLEARR GPIO_DOCLEARR(GPIOA) +#define GPIOB_DOCLEARR GPIO_DOCLEARR(GPIOB) +#define GPIOC_DOCLEARR GPIO_DOCLEARR(GPIOC) +#define GPIOD_DOCLEARR GPIO_DOCLEARR(GPIOD) +#define GPIOE_DOCLEARR GPIO_DOCLEARR(GPIOE) +#define GPIOF_DOCLEARR GPIO_DOCLEARR(GPIOF) +#define GPIOG_DOCLEARR GPIO_DOCLEARR(GPIOG) +/**@}*/ + +BEGIN_DECLS +/** GPIO Application Programming Interface. + * @defgroup gpio_api GPIO Peripheral API + * @ingroup peripheral_apis +@{*/ +/** + * Set the IO mode and pull-up/down configuration for the pins. + * @param gpioport[in] Port to configure the alternate function on. + * @param mode[in] IO Mode to configure (analog, input, output). + * @param pull_up_down[in] Pull configuration (up/down/none) to set for the pins.. + * @param gpios[in] Pins to set with the mode and pull config specified. + */ +void gpio_mode_setup(uint32_t gpioport, gpio_mode_t mode, + ccs_pull_updown_t pull_up_down, uint16_t gpios); +/** + * Set the output mask (disable changes) to the output pins specified. + * @param[in] gpioport Port to set output mask on. + * @param[in] enable Whether to enable or disable output masking. + * @param[in] gpios bitfield of pins to set. + */ +void gpio_set_outmask(uint32_t gpioport, bool enable, uint16_t gpios); +/** + * Set the port pins specified to the true state. + * @param[in] gpioport Port to set bits on. + * @param[in] gpios bitfield of pins to set. + */ +void gpio_set(uint32_t gpioport, uint16_t gpios); +/** + * Clear the port pins specified to the false state. + * @param[in] gpioport Port to clear bits on. + * @param[in] gpios bitfield of pins to clear. + */ +void gpio_clear(uint32_t gpioport, uint16_t gpios); +/** + * Return a masked bitfield of the port specified. + * @param gpioport[in] Port to read the bits from. + * @param gpios[in] bitfield mask to apply to the port read. + * @return masked bitfield of the port. + */ +uint16_t gpio_get(uint32_t gpioport, uint16_t gpios); +/** + * Set the function of the pin for this port. This will modify the pinmux, + * @param gpioport[in] Port to configure the alternate function on. + * @param muxsel[in] Mux select mode to configure on the port and pins. + * @param gpios[in] Pins to set with the function specified. + */ +void gpio_set_af(uint32_t gpioport, ccs_muxsel_func_t muxsel, uint16_t gpios); + +/** + * Set special output options for the gpio pin. For this MCU, this is only the drive strength. + * @param gpioport[in] Port to configure the alternate function on. + * @param strength[in] Drive strength (DS_XXMA from ccs.h). + * @param gpios[in] Pins to set with the drive strength specified. + */ +void gpio_set_output_options(uint32_t gpioport, ccs_drive_strength_t strength, + uint16_t gpios); +/** + * Set input schmidt trigger for glitch rejection on the input pin. + * @param gpioport[in] Port to configure the alternate function on. + * @param enable[in] True to enable, false to disable the schmidt trigger. + * @param gpios[in] Pins to set with the schmidt trigger setting specified. + */ +void gpio_set_schmidt_trigger(uint32_t gpioport, bool enable, uint16_t gpios); +/**@}*/ + +END_DECLS + +#endif /* INCLUDE_LIBOPENCM3_PAC55XX_GPIO_H_ */ diff --git a/include/libopencm3/pac55xx/memorymap.h b/include/libopencm3/pac55xx/memorymap.h new file mode 100644 index 00000000..126bd309 --- /dev/null +++ b/include/libopencm3/pac55xx/memorymap.h @@ -0,0 +1,77 @@ +/** @file + * @defgroup memorymap + * + * Peripheral Memory Map for the PAC55xx series of microcontrolelrs. + * + * @ingroup PAC55xx_defines + * @author Brian Viele + * LGPL License Terms @ref lgpl_license + * @date 1 Dec 2019 + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +#ifndef INCLUDE_LIBOPENCM3_PAC55XX_MEMORYMAP_H_ +#define INCLUDE_LIBOPENCM3_PAC55XX_MEMORYMAP_H_ + +/* Memory and Peripheral memory Mapping */ + +/** @defgroup address_memory Address Memory Map. +@ingroup memorymap +@{*/ +#define FLASH_BASE (0x00000000UL) +#define INFO1_FLASH_BASE (0x00100000UL) +#define INFO2_FLASH_BASE (0x00100400UL) +#define INFO3_FLASH_BASE (0x00100800UL) +#define SRAM_BASE (0x20000000UL) +#define PERIPH_BASE (0x40000000UL) +/**@}*/ +/** @defgroup peripheral_addresses Core Peripheral Memory Map. +@ingroup memorymap +@{*/ +#define ADC_BASE (PERIPH_BASE + 0x00000) +#define I2C_BASE (PERIPH_BASE + 0x10000) +#define USARTA_BASE (PERIPH_BASE + 0x20000) +#define USARTB_BASE (PERIPH_BASE + 0x30000) +#define USARTC_BASE (PERIPH_BASE + 0x40000) +#define USARTD_BASE (PERIPH_BASE + 0x50000) +#define TIMERA_BASE (PERIPH_BASE + 0x60000) +#define TIMERB_BASE (PERIPH_BASE + 0x70000) +#define TIMERC_BASE (PERIPH_BASE + 0x80000) +#define TIMERD_BASE (PERIPH_BASE + 0x90000) +#define CAN_BASE (PERIPH_BASE + 0xA0000) +#define GPTIMERA_BASE (PERIPH_BASE + 0xB0000) +#define GPTIMERB_BASE (PERIPH_BASE + 0xC0000) +#define SYS_PERIPH_BASE (PERIPH_BASE + 0xD0000) +/**@}*/ +/** @defgroup system_peripheral_addresses System Peripheral Memory Map. +@ingroup memorymap +@{*/ +#define MEMCTL_BASE (SYS_PERIPH_BASE + 0x0000) +#define SCC_BASE (SYS_PERIPH_BASE + 0x0400) +#define WWDT_BASE (SYS_PERIPH_BASE + 0x0800) +#define RTC_BASE (SYS_PERIPH_BASE + 0x0C00) +#define CRC_BASE (SYS_PERIPH_BASE + 0x1000) +#define GPIOA_BASE (SYS_PERIPH_BASE + 0x1400) +#define GPIOB_BASE (SYS_PERIPH_BASE + 0x1800) +#define GPIOC_BASE (SYS_PERIPH_BASE + 0x1C00) +#define GPIOD_BASE (SYS_PERIPH_BASE + 0x2000) +#define GPIOE_BASE (SYS_PERIPH_BASE + 0x2400) +#define GPIOF_BASE (SYS_PERIPH_BASE + 0x2800) +#define GPIOG_BASE (SYS_PERIPH_BASE + 0x2C00) +/**@}*/ + +#endif /* INCLUDE_LIBOPENCM3_PAC55XX_MEMORYMAP_H_ */ diff --git a/lib/pac55xx/Makefile b/lib/pac55xx/Makefile index 8255c82d..36e2fdb2 100644 --- a/lib/pac55xx/Makefile +++ b/lib/pac55xx/Makefile @@ -35,6 +35,8 @@ TGT_CFLAGS += $(DEBUG_FLAGS) TGT_CFLAGS += $(STANDARD_FLAGS) ARFLAGS = rcs +OBJS += gpio.o + VPATH += ../cm3 diff --git a/lib/pac55xx/gpio.c b/lib/pac55xx/gpio.c new file mode 100644 index 00000000..3d925428 --- /dev/null +++ b/lib/pac55xx/gpio.c @@ -0,0 +1,164 @@ +/** @file + * @ingroup PAC55xx_gpio + * @brief PAC55xxxx General-Purpose Input/Output (GPIO) + * @author @htmlonly © @endhtmlonly 2019 Brian Viele + * @date December 1, 2019 + * + * This library supports the GPIO module in the PAC55xx SoC from Qorvo. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +#include + +static uint32_t get_ccs_port_base(uint32_t gpioport) { + switch (gpioport) { + case GPIOA: + return CCS_PORTA; + case GPIOB: + return CCS_PORTB; + case GPIOC: + return CCS_PORTC; + case GPIOD: + return CCS_PORTD; + case GPIOE: + return CCS_PORTE; + case GPIOF: + return CCS_PORTF; + case GPIOG: + return CCS_PORTG; + default: + return 0U; + } +} + +void gpio_mode_setup(uint32_t gpioport, gpio_mode_t mode, + ccs_pull_updown_t pull_up_down, uint16_t gpios) { + /* Read the current value of the register. */ + uint32_t reg = GPIO_MODER(gpioport); + uint32_t port = get_ccs_port_base(gpioport); + + /* Loop through only set bits, utilize built-ins for optimized assembly. */ + int ffs = __builtin_ffs(gpios); + while (ffs) { + const int pin = ffs - 1; + const int bit = (1 << pin); + + /* Update the cached mode value by clearing then setting values. */ + reg &= ~GPIO_MODER_MASK_PIN(pin); + reg |= GPIO_MODER_MODE(pin, mode); + + /* Set the pinmux configurations for the pull-up / pull-down. */ + if (pull_up_down == CCS_IO_PULL_UP) { + CCS_PDENR(port) &= ~bit; + CCS_PUENR(port) |= bit; + } else if (pull_up_down == CCS_IO_PULL_DOWN) { + CCS_PUENR(port) &= ~bit; + CCS_PDENR(port) |= bit; + } else { + CCS_PDENR(port) &= ~bit; + CCS_PUENR(port) &= ~bit; + } + gpios ^= bit; /* Clear the bit we just serviced. */ + ffs = __builtin_ffs(gpios); + } + GPIO_MODER(gpioport) = reg; +} + +void gpio_set_outmask(uint32_t gpioport, bool enable, uint16_t gpios) { + uint32_t reg = GPIO_OUTMASKR(gpioport); + if (enable) { + reg |= gpios; + } else { + reg &= ~gpios; + } + GPIO_OUTMASKR(gpioport) = reg; +} + +void gpio_set(uint32_t gpioport, uint16_t gpios) { + GPIO_DOSETR(gpioport) = gpios; +} + +void gpio_clear(uint32_t gpioport, uint16_t gpios) { + GPIO_DOCLEARR(gpioport) = gpios; +} + +uint16_t gpio_get(uint32_t gpioport, uint16_t gpios) { + return GPIO_INR(gpioport) & gpios; +} + +void gpio_set_af(uint32_t gpioport, ccs_muxsel_func_t muxsel, uint16_t gpios) { + uint32_t port = get_ccs_port_base(gpioport); + + /* Update each of the pin configs. */ + uint32_t reg = CCS_MUXSELR(port); + int ffs = __builtin_ffs(gpios); + while (ffs) { + const int pin = ffs - 1; + const int shift = pin * 4; + + reg &= CCS_MUXSELR_MASK << shift; + reg |= muxsel << shift; + + /* Set the pinmux configurations for the pull-up / pull-down. */ + gpios ^= (1 << pin); /* Clear the bit we just serviced. */ + ffs = __builtin_ffs(gpios); + } + CCS_MUXSELR(port) = reg; +} + +void gpio_set_output_options(uint32_t gpioport, ccs_drive_strength_t strength, + uint16_t gpios) { + uint32_t port = get_ccs_port_base(gpioport); + + /* Update each of the pin configs. */ + uint32_t reg = CCS_DSR(port); + int ffs = __builtin_ffs(gpios); + while (ffs) { + const int pin = ffs - 1; + + reg &= ~CCS_DSR_MASK_PIN(pin); + reg |= CCS_DSR_DS_VAL(pin, strength); + + /* Set the pinmux configurations for the pull-up / pull-down. */ + gpios ^= (1 << pin); /* Clear the bit we just serviced. */ + ffs = __builtin_ffs(gpios); + } + CCS_DSR(port) = reg; +} + +void gpio_set_schmidt_trigger(uint32_t gpioport, bool enable, uint16_t gpios) { + uint32_t port = get_ccs_port_base(gpioport); + + /* Update each of the pin configs. */ + uint32_t reg = CCS_DSR(port); + int ffs = __builtin_ffs(gpios); + while (ffs) { + const int pin = ffs - 1; + if (enable) { + reg |= CCS_DSR_SCHMIDT_PIN(pin); + } else { + reg &= ~CCS_DSR_SCHMIDT_PIN(pin); + } + + /* Set the pinmux configurations for the pull-up / pull-down. */ + gpios ^= (1 << pin); /* Clear the bit we just serviced. */ + ffs = __builtin_ffs(gpios); + } + CCS_DSR(port) = reg; +} diff --git a/lib/pac55xx/vector_chipset.c b/lib/pac55xx/vector_chipset.c index 96293f1a..6605f682 100644 --- a/lib/pac55xx/vector_chipset.c +++ b/lib/pac55xx/vector_chipset.c @@ -18,8 +18,7 @@ */ /* Standard Cortex-M4F initialization of FPU. */ -static void pre_main(void) -{ +static void pre_main(void) { /* Enable FPU */ SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11); }