183 lines
4.2 KiB
C
183 lines
4.2 KiB
C
/*
|
|
* Copyright (c) 2020-2020, Bluetrum Development Team
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Change Logs:
|
|
* Date Author Notes
|
|
* 2020-11-19 greedyhao first version
|
|
*/
|
|
|
|
#include "drv_gpio.h"
|
|
|
|
#ifdef RT_USING_PIN
|
|
|
|
// #define DRV_DEBUG
|
|
#define LOG_TAG "drv.gpio"
|
|
#include <drv_log.h>
|
|
|
|
struct port_info
|
|
{
|
|
uint8_t start_pin;
|
|
uint8_t delta_pin;
|
|
uint8_t total_pin;
|
|
};
|
|
|
|
/* It needs to be adjusted to the hardware. */
|
|
static const struct port_info port_table[] =
|
|
{
|
|
{0, 8, 0}, /* PA0-PA7 */
|
|
{0, 5, 8}, /* PB0-PB5 */
|
|
{0, 8, 13}, /* PE0-PE7 */
|
|
{0, 6, 21}, /* PF0-PF6 */
|
|
};
|
|
|
|
static const hal_sfr_t port_sfr[] =
|
|
{
|
|
GPIOA_BASE,
|
|
GPIOB_BASE,
|
|
GPIOE_BASE,
|
|
GPIOF_BASE,
|
|
};
|
|
|
|
static uint8_t _pin_port(uint32_t pin)
|
|
{
|
|
uint8_t port = 0;
|
|
for (port = 0; port < 3; port++) {
|
|
if (pin < (port_table[port].total_pin + port_table[port].delta_pin)) {
|
|
break;
|
|
}
|
|
}
|
|
return port;
|
|
}
|
|
|
|
#define PIN_NUM(port, no) ((uint8_t)(port_table[port].total_pin + no - port_table[port].start_pin))
|
|
#define PIN_PORT(pin) _pin_port(pin)
|
|
#define PORT_SFR(port) (port_sfr[(port)])
|
|
#define PIN_NO(pin) (uint8_t)((pin) & 0xFu)
|
|
|
|
// #define PIN_ABPIN(pin) (uint8_t)(port_table[PIN_PORT(pin)].total_pin + PIN_NO(pin))
|
|
|
|
static rt_base_t ab32_pin_get(const char *name)
|
|
{
|
|
rt_base_t pin = 0;
|
|
int hw_port_num, hw_pin_num = 0;
|
|
int i, name_len;
|
|
|
|
name_len = rt_strlen(name);
|
|
|
|
if ((name_len < 4) || (name_len >= 6))
|
|
{
|
|
return -RT_EINVAL;
|
|
}
|
|
if ((name[0] != 'P') || (name[2] != '.'))
|
|
{
|
|
return -RT_EINVAL;
|
|
}
|
|
|
|
if ((name[1] >= 'A') && (name[1] <= 'B'))
|
|
{
|
|
hw_port_num = (int)(name[1] - 'A');
|
|
}
|
|
else if ((name[1] >= 'E') && (name[1] <= 'G'))
|
|
{
|
|
hw_port_num = (int)(name[1] - 'A') - 2; /* Without 'C' and 'D'. */
|
|
}
|
|
else
|
|
{
|
|
return -RT_EINVAL;
|
|
}
|
|
|
|
for (i = 3; i < name_len; i++)
|
|
{
|
|
hw_pin_num *= 10;
|
|
hw_pin_num += name[i] - '0';
|
|
}
|
|
|
|
pin = PIN_NUM(hw_port_num, hw_pin_num);
|
|
LOG_D("name=%s", name);
|
|
LOG_D("hw_port_num=%d hw_pin_num=%d pin=%d", hw_port_num, hw_pin_num, pin);
|
|
|
|
return pin;
|
|
}
|
|
|
|
static void ab32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
|
|
{
|
|
uint8_t port = PIN_PORT(pin);
|
|
uint8_t gpio_pin = pin - port_table[port].total_pin;
|
|
hal_gpio_write(PORT_SFR(port), gpio_pin, (uint8_t)value);
|
|
}
|
|
|
|
static int ab32_pin_read(rt_device_t dev, rt_base_t pin)
|
|
{
|
|
uint8_t port = PIN_PORT(pin);
|
|
uint8_t gpio_pin = pin - port_table[port].total_pin;
|
|
return hal_gpio_read(PORT_SFR(port), gpio_pin);
|
|
}
|
|
|
|
static void ab32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
|
|
{
|
|
struct gpio_init gpio_init;
|
|
uint8_t port = PIN_PORT(pin);
|
|
|
|
gpio_init.pin = BIT(pin - port_table[port].total_pin);
|
|
gpio_init.de = GPIO_DIGITAL;
|
|
gpio_init.af_con = GPIO_AFDIS;
|
|
LOG_D("port=%d pin=%d", port, gpio_init.pin);
|
|
|
|
switch (mode)
|
|
{
|
|
case PIN_MODE_INPUT:
|
|
case PIN_MODE_INPUT_PULLUP:
|
|
gpio_init.pull = GPIO_PULLUP;
|
|
gpio_init.dir = GPIO_DIR_INPUT;
|
|
break;
|
|
case PIN_MODE_INPUT_PULLDOWN:
|
|
gpio_init.pull = GPIO_PULLDOWN;
|
|
gpio_init.dir = GPIO_DIR_INPUT;
|
|
break;
|
|
case PIN_MODE_OUTPUT:
|
|
case PIN_MODE_OUTPUT_OD:
|
|
default:
|
|
gpio_init.pull = GPIO_NOPULL;
|
|
gpio_init.dir = GPIO_DIR_OUTPUT;
|
|
break;
|
|
}
|
|
hal_gpio_init(PORT_SFR(port), &gpio_init);
|
|
}
|
|
|
|
static rt_err_t ab32_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
|
|
rt_uint32_t mode, void (*hdr)(void *args), void *args)
|
|
{
|
|
return -RT_ERROR;
|
|
}
|
|
|
|
static rt_err_t ab32_pin_dettach_irq(struct rt_device *device, rt_int32_t pin)
|
|
{
|
|
return -RT_ERROR;
|
|
}
|
|
|
|
static rt_err_t ab32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
|
|
rt_uint32_t enabled)
|
|
{
|
|
return -RT_ERROR;
|
|
}
|
|
|
|
const static struct rt_pin_ops _ab32_pin_ops =
|
|
{
|
|
ab32_pin_mode,
|
|
ab32_pin_write,
|
|
ab32_pin_read,
|
|
ab32_pin_attach_irq,
|
|
ab32_pin_dettach_irq,
|
|
ab32_pin_irq_enable,
|
|
ab32_pin_get,
|
|
};
|
|
|
|
int rt_hw_pin_init(void)
|
|
{
|
|
return rt_device_pin_register("pin", &_ab32_pin_ops, RT_NULL);
|
|
}
|
|
|
|
#endif
|