/* * Copyright (c) 2020-2020, BLUETRUM Development Team * * SPDX-License-Identifier: Apache-2.0 */ #include "ab32vg1_hal.h" #ifdef HAL_GPIO_MODULE_ENABLED #if 0 #define HAL_LOG(...) hal_printf(__VA_ARGS__) #else #define HAL_LOG(...) #endif void gpio_afinit(hal_sfr_t gpiox, uint8_t pin, uint32_t alternate, uint32_t af_con) { uint32_t is_rx_map_tx = (alternate & UT1RXMAP_TX) || (alternate & UT0RXMAP_TX); if ((af_con & 0xf0u) != GPIO_AFDIS) { gpiox[GPIOxFEN] |= BIT(pin); switch (is_rx_map_tx) { case UT1RXMAP_TX: FUNCMCONx(GPIO_GET_AFCON(af_con)) |= GPIO_AF_MAP_CLR(UT1RXMAP_AF); break; case UT0RXMAP_TX: FUNCMCONx(GPIO_GET_AFCON(af_con)) |= GPIO_AF_MAP_CLR(UT0RXMAP_AF); break; default: break; } FUNCMCONx(GPIO_GET_AFCON(af_con)) |= GPIO_AF_MAP_CLR(af_con & 0x1f); FUNCMCONx(GPIO_GET_AFCON(af_con)) |= alternate; HAL_LOG("af_con=0x%X AFCON=%d alternate=%d\n", af_con, GPIO_GET_AFCON(af_con), (af_con & 0x1f)); } } /** * @brief Initialize the gpio. * * @param port GPIO port(GPIOAN, GPIOBN, GPIOEN, GPIOFN). * @param gpio_init the configuration of the specified GPIO peripheral. */ void hal_gpio_init(hal_sfr_t gpiox, gpio_init_t gpio_init) { uint8_t iocurrent = 0; if (gpio_init == HAL_NULL) { return; } for (iocurrent = 0; iocurrent < 8; iocurrent++) { if ((gpio_init->pin & BIT(iocurrent)) == 0) { continue; } gpio_afinit(gpiox, iocurrent, gpio_init->alternate, gpio_init->af_con); switch (gpio_init->dir) { case GPIO_DIR_INPUT: /* When set to input, clear all pull-ups of the port. */ gpiox[GPIOxDIR] |= BIT(iocurrent); gpiox[GPIOxPU] &= ~BIT(iocurrent); gpiox[GPIOxPU200K] &= ~BIT(iocurrent); gpiox[GPIOxPD200K] &= ~BIT(iocurrent); gpiox[GPIOxPU300K] &= ~BIT(iocurrent); gpiox[GPIOxPD300K] &= ~BIT(iocurrent); switch (gpio_init->pull) { case GPIO_PULLUP: gpiox[GPIOxPD] &= ~BIT(iocurrent); gpiox[GPIOxPU] |= BIT(iocurrent); break; case GPIO_PULLDOWN: gpiox[GPIOxPU] &= ~BIT(iocurrent); gpiox[GPIOxPD] |= BIT(iocurrent); break; case GPIO_NOPULL: gpiox[GPIOxPU] &= ~BIT(iocurrent); gpiox[GPIOxPD] &= ~BIT(iocurrent); default: break; } break; case GPIO_DIR_OUTPUT: gpiox[GPIOxDIR] &= ~BIT(iocurrent); break; default: break; } switch (gpio_init->de) { case GPIO_DIGITAL: gpiox[GPIOxDE] |= BIT(iocurrent); break; case GPIO_ANALOG: gpiox[GPIOxDE] &= ~BIT(iocurrent); break; default: break; } } } /** * @brief Read the specified input port pin. * * @param port GPIO port(GPIOAN, GPIOBN, GPIOEN, GPIOFN). * @param pin This parameter can be GPIO_PIN_x where x can be (0.15). * @return uint8_t The input port pin value. */ uint8_t hal_gpio_read(hal_sfr_t gpiox, uint8_t pin) { return ((gpiox[GPIOx] & BIT(pin)) != GPIO_PIN_LOW) ? GPIO_PIN_HIGH : GPIO_PIN_LOW; } /** * @brief Set or clear the selected data port bit. * * @param port GPIO port(GPIOAN, GPIOBN, GPIOEN, GPIOFN). * @param pin This parameter can be GPIO_PIN_x where x can be (0.15). * @param state specifies the value to be written to the selected bit. * @arg GPIO_PIN_LOW: * @arg GPIO_PIN_HIGH: */ void hal_gpio_write(hal_sfr_t gpiox, uint8_t pin, uint8_t state) { if (state == GPIO_PIN_LOW) { gpiox[GPIOx] &= ~BIT(pin); } else { gpiox[GPIOx] |= BIT(pin); } } /** * @brief Toggle the specified GPIO pin. * * @param port GPIO port(GPIOAN, GPIOBN, GPIOEN, GPIOFN). * @param pin This parameter can be GPIO_PIN_x where x can be (0.15). */ void hal_gpio_toggle(hal_sfr_t gpiox, uint8_t pin) { gpiox[GPIOx] ^= BIT(pin); } #endif