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.
This commit is contained in:
committed by
Karl Palsson
parent
9598b7f424
commit
a3406f100b
@@ -35,6 +35,8 @@ TGT_CFLAGS += $(DEBUG_FLAGS)
|
||||
TGT_CFLAGS += $(STANDARD_FLAGS)
|
||||
ARFLAGS = rcs
|
||||
|
||||
OBJS += gpio.o
|
||||
|
||||
VPATH += ../cm3
|
||||
|
||||
|
||||
|
||||
164
lib/pac55xx/gpio.c
Normal file
164
lib/pac55xx/gpio.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/** @file
|
||||
* @ingroup PAC55xx_gpio
|
||||
* @brief <b>PAC55xxxx General-Purpose Input/Output (GPIO)</b>
|
||||
* @author @htmlonly © @endhtmlonly 2019 Brian Viele <vielster@allocor.tech>
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <libopencm3/pac55xx/gpio.h>
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user