summaryrefslogtreecommitdiff
path: root/bsp/w60x/drivers/drv_pin.c
blob: 315647e77f067201e1436ac9169bb4f9631a08df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
 * 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_uint8_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_uint8_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 rt_ssize_t 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_base_t pin,
                                  rt_uint8_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_base_t pin)
{
    return RT_EOK;
}

static rt_err_t wm_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint8_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 */