/* * Copyright (c) 2019 Winner Microelectronics Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-09-15 flyingcys 1st version */ #include <rtthread.h> #include <rtdevice.h> #include <rthw.h> #include "wm_type_def.h" #include "wm_io.h" #include "wm_gpio.h" #include "pin_map.h" #include "drv_pin.h" #ifdef BSP_USING_PIN static void wm_pin_mode(struct rt_device *device, rt_base_t pin, rt_base_t mode) { rt_int16_t gpio_pin; gpio_pin = wm_get_pin(pin); if (gpio_pin < 0) { return; } if (mode == PIN_MODE_INPUT) { tls_gpio_cfg((enum tls_io_name)gpio_pin, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_FLOATING); } else if (mode == PIN_MODE_INPUT_PULLUP) { tls_gpio_cfg((enum tls_io_name)gpio_pin, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_PULLHIGH); } else if (mode == PIN_MODE_INPUT_PULLDOWN) { tls_gpio_cfg((enum tls_io_name)gpio_pin, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_PULLLOW); } else if (mode == PIN_MODE_OUTPUT) { tls_gpio_cfg((enum tls_io_name)gpio_pin, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH); } return; } static void wm_pin_write(struct rt_device *device, rt_base_t pin, rt_base_t value) { rt_int16_t gpio_pin; gpio_pin = wm_get_pin(pin); if (gpio_pin < 0) { return; } tls_gpio_write((enum tls_io_name)gpio_pin, value); return; } static int wm_pin_read(struct rt_device *device, rt_base_t pin) { rt_int16_t gpio_pin; gpio_pin = wm_get_pin(pin); if (gpio_pin < 0) { return PIN_LOW; } return tls_gpio_read((enum tls_io_name)gpio_pin); } static rt_err_t wm_pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args) { rt_int16_t gpio_pin; rt_base_t level; gpio_pin = wm_get_pin(pin); if (gpio_pin < 0) { return -RT_ENOSYS; } level = rt_hw_interrupt_disable(); /*irq mode set*/ switch (mode) { case PIN_IRQ_MODE_RISING: tls_gpio_irq_cfg((enum tls_io_name)gpio_pin, WM_GPIO_IRQ_TRIG_RISING_EDGE); break; case PIN_IRQ_MODE_FALLING: tls_gpio_irq_cfg((enum tls_io_name)gpio_pin, WM_GPIO_IRQ_TRIG_FALLING_EDGE); break; case PIN_IRQ_MODE_RISING_FALLING: tls_gpio_irq_cfg((enum tls_io_name)gpio_pin, WM_GPIO_IRQ_TRIG_DOUBLE_EDGE); break; case PIN_IRQ_MODE_HIGH_LEVEL: tls_gpio_irq_cfg((enum tls_io_name)gpio_pin, WM_GPIO_IRQ_TRIG_HIGH_LEVEL); break; case PIN_IRQ_MODE_LOW_LEVEL: tls_gpio_irq_cfg((enum tls_io_name)gpio_pin, WM_GPIO_IRQ_TRIG_LOW_LEVEL); break; default: rt_hw_interrupt_enable(level); return -RT_ENOSYS; } tls_gpio_isr_register((enum tls_io_name)gpio_pin, hdr, args); rt_hw_interrupt_enable(level); return RT_EOK; } static rt_err_t wm_pin_detach_irq(struct rt_device *device, rt_int32_t pin) { return RT_EOK; } static rt_err_t wm_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) { rt_int16_t gpio_pin; rt_base_t level; gpio_pin = wm_get_pin(pin); if (gpio_pin < 0) { return -RT_ENOSYS; } level = rt_hw_interrupt_disable(); if (enabled == PIN_IRQ_ENABLE) { tls_clr_gpio_irq_status((enum tls_io_name)gpio_pin); tls_gpio_irq_enable((enum tls_io_name)gpio_pin); rt_hw_interrupt_enable(level); return RT_EOK; } else if (enabled == PIN_IRQ_DISABLE) { tls_gpio_irq_disable((enum tls_io_name)gpio_pin); rt_hw_interrupt_enable(level); return RT_EOK; } else { rt_hw_interrupt_enable(level); return -RT_ENOSYS; } } struct rt_pin_ops _wm_pin_ops = { wm_pin_mode, wm_pin_write, wm_pin_read, wm_pin_attach_irq, wm_pin_detach_irq, wm_pin_irq_enable, RT_NULL, }; int wm_hw_pin_init(void) { int ret = rt_device_pin_register("pin", &_wm_pin_ops, RT_NULL); return ret; } INIT_BOARD_EXPORT(wm_hw_pin_init); void WM_GPIOA_IRQHandler(void) { rt_interrupt_enter(); GPIOA_IRQHandler(); rt_interrupt_leave(); } void WM_GPIOB_IRQHandler(void) { rt_interrupt_enter(); GPIOB_IRQHandler(); rt_interrupt_leave(); } #endif /* BSP_USING_PIN */