libopencm3
A free/libre/open-source firmware library for various ARM Cortex-M3 microcontrollers.
gpio.c
Go to the documentation of this file.
1/**
2 * @ingroup PAC55xx_gpio
3 * @brief <b>PAC55xxxx General-Purpose Input/Output (GPIO)</b>
4 * @author @htmlonly &copy; @endhtmlonly 2019 Brian Viele <vielster@allocor.tech>
5 * @date December 1, 2019
6 *
7 * This library supports the GPIO module in the PAC55xx SoC from Qorvo.
8 *
9 * LGPL License Terms @ref lgpl_license
10 */
11/*
12 * This file is part of the libopencm3 project.
13 *
14 * This library is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public License
25 * along with this library. If not, see <http://www.gnu.org/licenses/>.
26 */
28
29static uint32_t get_ccs_port_base(uint32_t gpioport) {
30 switch (gpioport) {
31 case GPIOA:
32 return CCS_PORTA;
33 case GPIOB:
34 return CCS_PORTB;
35 case GPIOC:
36 return CCS_PORTC;
37 case GPIOD:
38 return CCS_PORTD;
39 case GPIOE:
40 return CCS_PORTE;
41 case GPIOF:
42 return CCS_PORTF;
43 case GPIOG:
44 return CCS_PORTG;
45 default:
46 return 0U;
47 }
48}
49
50void gpio_mode_setup(uint32_t gpioport, gpio_mode_t mode,
51 ccs_pull_updown_t pull_up_down, uint16_t gpios) {
52 /* Read the current value of the register. */
53 uint32_t reg = GPIO_MODER(gpioport);
54 uint32_t port = get_ccs_port_base(gpioport);
55
56 /* Loop through only set bits, utilize built-ins for optimized assembly. */
57 int ffs = __builtin_ffs(gpios);
58 while (ffs) {
59 const int pin = ffs - 1;
60 const int bit = (1 << pin);
61
62 /* Update the cached mode value by clearing then setting values. */
63 reg &= ~GPIO_MODER_MASK_PIN(pin);
64 reg |= GPIO_MODER_MODE(pin, mode);
65
66 /* Set the pinmux configurations for the pull-up / pull-down. */
67 if (pull_up_down == CCS_IO_PULL_UP) {
68 CCS_PDENR(port) &= ~bit;
69 CCS_PUENR(port) |= bit;
70 } else if (pull_up_down == CCS_IO_PULL_DOWN) {
71 CCS_PUENR(port) &= ~bit;
72 CCS_PDENR(port) |= bit;
73 } else {
74 CCS_PDENR(port) &= ~bit;
75 CCS_PUENR(port) &= ~bit;
76 }
77 gpios ^= bit; /* Clear the bit we just serviced. */
78 ffs = __builtin_ffs(gpios);
79 }
80 GPIO_MODER(gpioport) = reg;
81}
82
83void gpio_set_outmask(uint32_t gpioport, bool enable, uint16_t gpios) {
84 uint32_t reg = GPIO_OUTMASKR(gpioport);
85 if (enable) {
86 reg |= gpios;
87 } else {
88 reg &= ~gpios;
89 }
90 GPIO_OUTMASKR(gpioport) = reg;
91}
92
93void gpio_set(uint32_t gpioport, uint16_t gpios) {
94 GPIO_DOSETR(gpioport) = gpios;
95}
96
97void gpio_clear(uint32_t gpioport, uint16_t gpios) {
98 GPIO_DOCLEARR(gpioport) = gpios;
99}
100
101uint16_t gpio_get(uint32_t gpioport, uint16_t gpios) {
102 return GPIO_INR(gpioport) & gpios;
103}
104
105void gpio_set_af(uint32_t gpioport, ccs_muxsel_func_t muxsel, uint16_t gpios) {
106 uint32_t port = get_ccs_port_base(gpioport);
107
108 /* Update each of the pin configs. */
109 uint32_t reg = CCS_MUXSELR(port);
110 int ffs = __builtin_ffs(gpios);
111 while (ffs) {
112 const int pin = ffs - 1;
113
114 reg &= ~CCS_MUXSELR_MASK_PIN(pin);
115 reg |= CCS_MUXSELR_VAL(pin, muxsel);
116
117 /* Set the pinmux configurations for the pull-up / pull-down. */
118 gpios ^= (1 << pin); /* Clear the bit we just serviced. */
119 ffs = __builtin_ffs(gpios);
120 }
121 CCS_MUXSELR(port) = reg;
122}
123
124void gpio_set_output_options(uint32_t gpioport, ccs_drive_strength_t strength,
125 uint16_t gpios) {
126 uint32_t port = get_ccs_port_base(gpioport);
127
128 /* Update each of the pin configs. */
129 uint32_t reg = CCS_DSR(port);
130 int ffs = __builtin_ffs(gpios);
131 while (ffs) {
132 const int pin = ffs - 1;
133
134 reg &= ~CCS_DSR_MASK_PIN(pin);
135 reg |= CCS_DSR_DS_VAL(pin, strength);
136
137 /* Set the pinmux configurations for the pull-up / pull-down. */
138 gpios ^= (1 << pin); /* Clear the bit we just serviced. */
139 ffs = __builtin_ffs(gpios);
140 }
141 CCS_DSR(port) = reg;
142}
143
144void gpio_set_schmidt_trigger(uint32_t gpioport, bool enable, uint16_t gpios) {
145 uint32_t port = get_ccs_port_base(gpioport);
146
147 /* Update each of the pin configs. */
148 uint32_t reg = CCS_DSR(port);
149 int ffs = __builtin_ffs(gpios);
150 while (ffs) {
151 const int pin = ffs - 1;
152 if (enable) {
153 reg |= CCS_DSR_SCHMIDT_PIN(pin);
154 } else {
155 reg &= ~CCS_DSR_SCHMIDT_PIN(pin);
156 }
157
158 /* Set the pinmux configurations for the pull-up / pull-down. */
159 gpios ^= (1 << pin); /* Clear the bit we just serviced. */
160 ffs = __builtin_ffs(gpios);
161 }
162 CCS_DSR(port) = reg;
163}
static uint32_t get_ccs_port_base(uint32_t gpioport)
PAC55xxxx General-Purpose Input/Output (GPIO)
Definition: gpio.c:29
ccs_drive_strength_t
Drive strength enumeration for type specificity.
Definition: ccs.h:206
#define CCS_DSR(base)
Definition: ccs.h:192
#define CCS_DSR_SCHMIDT_PIN(pin)
Definition: ccs.h:203
#define CCS_DSR_DS_VAL(pin, ds)
Definition: ccs.h:202
void gpio_mode_setup(uint32_t gpioport, gpio_mode_t mode, ccs_pull_updown_t pull_up_down, uint16_t gpios)
Set the IO mode and pull-up/down configuration for the pins.
Definition: gpio.c:50
void gpio_set_schmidt_trigger(uint32_t gpioport, bool enable, uint16_t gpios)
Set input schmidt trigger for glitch rejection on the input pin.
Definition: gpio.c:144
uint16_t gpio_get(uint32_t gpioport, uint16_t gpios)
Return a masked bitfield of the port specified.
Definition: gpio.c:101
void gpio_set_outmask(uint32_t gpioport, bool enable, uint16_t gpios)
Set the output mask (disable changes) to the output pins specified.
Definition: gpio.c:83
void gpio_set(uint32_t gpioport, uint16_t gpios)
Set the port pins specified to the true state.
Definition: gpio.c:93
void gpio_clear(uint32_t gpioport, uint16_t gpios)
Clear the port pins specified to the false state.
Definition: gpio.c:97
void gpio_set_output_options(uint32_t gpioport, ccs_drive_strength_t strength, uint16_t gpios)
Set special output options for the gpio pin.
Definition: gpio.c:124
void gpio_set_af(uint32_t gpioport, ccs_muxsel_func_t muxsel, uint16_t gpios)
Set the function of the pin for this port.
Definition: gpio.c:105
#define GPIO_DOCLEARR(base)
Definition: gpio.h:241
#define GPIO_DOSETR(base)
Definition: gpio.h:228
#define GPIO_INR(base)
Definition: gpio.h:120
#define GPIO_MODER(base)
Definition: gpio.h:77
gpio_mode_t
Definition: gpio.h:71
#define GPIO_MODER_MODE(pin, mode)
Definition: gpio.h:87
#define GPIO_OUTMASKR(base)
Definition: gpio.h:94
#define GPIOG
Definition: gpio.h:49
#define GPIOC
Definition: gpio.h:45
#define GPIOF
Definition: gpio.h:48
#define GPIOB
Definition: gpio.h:44
#define GPIOD
Definition: gpio.h:46
#define GPIOA
Definition: gpio.h:43
#define GPIOE
Definition: gpio.h:47
#define CCS_PDENR(base)
Definition: ccs.h:173
ccs_pull_updown_t
Pull Up/Down enum for type specificity.
Definition: ccs.h:182
#define CCS_PUENR(base)
Definition: ccs.h:165
@ CCS_IO_PULL_DOWN
Definition: ccs.h:185
@ CCS_IO_PULL_UP
Definition: ccs.h:184
ccs_muxsel_func_t
Definition: ccs.h:150
#define CCS_MUXSELR_VAL(pin, muxsel)
Definition: ccs.h:147
#define CCS_MUXSELR(base)
Definition: ccs.h:137
#define CCS_PORTA
Definition: ccs.h:125
#define CCS_PORTG
Definition: ccs.h:131
#define CCS_PORTB
Definition: ccs.h:126
#define CCS_PORTD
Definition: ccs.h:128
#define CCS_PORTE
Definition: ccs.h:129
#define CCS_PORTF
Definition: ccs.h:130
#define CCS_PORTC
Definition: ccs.h:127