123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- /*
- * Copyright (c) 2006-2021, YICHIP Technology Co.,Ltd.
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2021-09-09 WSY first version
- */
- #include <rtthread.h>
- #include <rtdevice.h>
- #include <board.h>
- #include <rthw.h>
- #define PIN_MAX_NUM (48)
- typedef void (*pin_callback_t)(void *args);
- struct pin
- {
- uint32_t package_index;
- const char *name;
- IRQn_Type irq;
- rt_uint32_t irq_mode;
- pin_callback_t callback;
- void *callback_args;
- };
- typedef struct pin pin_t;
- struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
- {
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- {-1, 0, RT_NULL, RT_NULL},
- };
- static void yc_pin_mode(rt_device_t dev, rt_base_t pin, rt_uint8_t mode)
- {
- /* Configure GPIO_InitStructure */
- if (mode == PIN_MODE_OUTPUT)
- {
- /* output setting */
- GPIO_CONFIG(pin) = OUTPUT_LOW;
- }
- else if (mode == PIN_MODE_INPUT)
- {
- /* input setting: not pull. */
- GPIO_CONFIG(pin) = INPUT;
- }
- else if (mode == PIN_MODE_INPUT_PULLUP)
- {
- /* input setting: pull up. */
- GPIO_CONFIG(pin) = PULL_UP;
- }
- else if (mode == PIN_MODE_INPUT_PULLDOWN)
- {
- /* input setting: pull down. */
- GPIO_CONFIG(pin) = PULL_DOWN;
- }
- else if (mode == PIN_MODE_OUTPUT_OD)
- {
- /* output setting: od. */
- GPIO_CONFIG(pin) = PULL_UP;
- }
- }
- static void yc_pin_write(rt_device_t dev, rt_base_t pin, rt_uint8_t value)
- {
- if (value)
- {
- GPIO_CONFIG(pin) = OUTPUT_HIGH;
- }
- else
- {
- GPIO_CONFIG(pin) = OUTPUT_LOW;
- }
- }
- static rt_ssize_t yc_pin_read(rt_device_t dev, rt_base_t pin)
- {
- return GPIO_IN(pin / 16) & (1 << (pin % 16)) ? 1 : 0;
- }
- static rt_err_t yc_pin_attach_irq(struct rt_device *device,
- rt_base_t pin,
- rt_uint8_t mode,
- pin_callback_t cb,
- void *args)
- {
- rt_int32_t index = -1;
- rt_base_t level;
- if (pin >= PIN_MAX_NUM)
- {
- return -RT_EINVAL;
- }
- index = pin;
- level = rt_hw_interrupt_disable();
- pin_irq_hdr_tab[index].pin = pin;
- pin_irq_hdr_tab[index].hdr = cb;
- pin_irq_hdr_tab[index].mode = mode;
- pin_irq_hdr_tab[index].args = args;
- rt_hw_interrupt_enable(level);
- return RT_EOK;
- }
- static rt_err_t yc_pin_detach_irq(struct rt_device *device, rt_base_t pin)
- {
- rt_int32_t index = -1;
- rt_base_t level;
- if (pin >= PIN_MAX_NUM)
- {
- return -RT_EINVAL;
- }
- index = pin;
- level = rt_hw_interrupt_disable();
- pin_irq_hdr_tab[index].pin = -1;
- pin_irq_hdr_tab[index].hdr = RT_NULL;
- pin_irq_hdr_tab[index].mode = 0;
- pin_irq_hdr_tab[index].args = RT_NULL;
- rt_hw_interrupt_enable(level);
- return RT_EOK;
- }
- static rt_err_t yc_pin_irq_enable(struct rt_device *device,
- rt_base_t pin,
- rt_uint8_t enabled)
- {
- rt_int32_t index;
- rt_base_t level = 0;
- if (pin >= PIN_MAX_NUM)
- {
- return -RT_EINVAL;
- }
- index = pin;
- if (enabled == PIN_IRQ_ENABLE)
- {
- switch (pin_irq_hdr_tab[index].mode)
- {
- case PIN_IRQ_MODE_RISING:
- break;
- case PIN_IRQ_MODE_FALLING:
- break;
- case PIN_IRQ_MODE_RISING_FALLING:
- break;
- case PIN_IRQ_MODE_HIGH_LEVEL:
- GPIO_CONFIG(pin) = PULL_DOWN;
- GPIO_TRIG_MODE(pin / 16) &= (1 << (pin % 16));
- break;
- case PIN_IRQ_MODE_LOW_LEVEL:
- GPIO_CONFIG(pin) = PULL_UP;
- GPIO_TRIG_MODE(pin / 16) |= (1 << (pin % 16));
- break;
- default:
- rt_hw_interrupt_enable(level);
- return -RT_EINVAL;
- }
- level = rt_hw_interrupt_disable();
- NVIC_EnableIRQ(GPIO_IRQn);
- GPIO_INTR_EN(pin / 16) |= (1 << (pin % 16));
- rt_hw_interrupt_enable(level);
- }
- else if (enabled == PIN_IRQ_DISABLE)
- {
- NVIC_DisableIRQ(GPIO_IRQn);
- GPIO_INTR_EN(pin / 16) &= ~(1 << (pin % 16));
- }
- else
- {
- return -RT_ENOSYS;
- }
- return RT_EOK;
- }
- const static struct rt_pin_ops yc3121_pin_ops =
- {
- yc_pin_mode,
- yc_pin_write,
- yc_pin_read,
- yc_pin_attach_irq,
- yc_pin_detach_irq,
- yc_pin_irq_enable,
- RT_NULL,
- };
- int rt_hw_pin_init(void)
- {
- int result;
- result = rt_device_pin_register("pin", &yc3121_pin_ops, RT_NULL);
- return result;
- }
- INIT_BOARD_EXPORT(rt_hw_pin_init);
- void GPIO_IRQHandler(void)
- {
- int i;
- rt_interrupt_enter();
- for (i = 0; i < PIN_MAX_NUM; i++)
- {
- if ((GPIO_TRIG_MODE(i / 16) & (1 << (i % 16))) == (GPIO_IN(i / 16) & (1 << (i % 16))))
- {
- if (pin_irq_hdr_tab[i].hdr)
- {
- pin_irq_hdr_tab[i].hdr(pin_irq_hdr_tab[i].args);
- }
- }
- }
- rt_interrupt_leave();
- }
|