| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485 |
- /**
- * @file wm_gpio.c
- *
- * @brief GPIO Driver Module
- *
- * @author dave
- *
- * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
- */
- #include "wm_gpio.h"
- #include "wm_regs.h"
- #include "wm_irq.h"
- #include "wm_osal.h"
- #include "tls_common.h"
- struct gpio_irq_context{
- tls_gpio_irq_callback callback;
- void *arg;
- };
- static struct gpio_irq_context gpio_context[WM_IO_PB_31 - WM_IO_PA_00 + 1] = {{0,0}};
- ATTRIBUTE_ISR void GPIOA_IRQHandler(void)
- {
- u8 i = 0;
- u8 found = 0;
- u32 reg = 0;
- csi_kernel_intrpt_enter();
- reg = tls_reg_read32(HR_GPIO_MIS);
- for (i = 0; i <= WM_IO_PA_15; i++)
- {
- if (reg & BIT(i))
- {
- found = 1;
- break;
- }
- }
- if (found)
- {
- if (NULL != gpio_context[i].callback)
- gpio_context[i].callback(gpio_context[i].arg);
- }
- csi_kernel_intrpt_exit();
- }
- ATTRIBUTE_ISR void GPIOB_IRQHandler(void)
- {
- u8 i = 0;
- u8 found = 0;
- u32 reg = 0;
- csi_kernel_intrpt_enter();
- reg = tls_reg_read32(HR_GPIO_MIS + TLS_IO_AB_OFFSET);
- for (i = WM_IO_PB_00; i <= WM_IO_PB_31; i++)
- {
- if (reg & BIT(i - WM_IO_PB_00))
- {
- found = 1;
- break;
- }
- }
- if (found)
- {
- if (NULL != gpio_context[i].callback)
- gpio_context[i].callback(gpio_context[i].arg);
- }
- csi_kernel_intrpt_exit();
- }
- /**
- * @brief This function is used to config gpio function
- *
- * @param[in] gpio_pin gpio pin num
- * @param[in] dir gpio direction
- * @param[in] attr gpio attribute
- *
- * @return None
- *
- * @note
- */
- void tls_gpio_cfg(enum tls_io_name gpio_pin, enum tls_gpio_dir dir, enum tls_gpio_attr attr)
- {
- u8 pin;
- u16 offset;
- if (gpio_pin >= WM_IO_PB_00)
- {
- pin = gpio_pin - WM_IO_PB_00;
- offset = TLS_IO_AB_OFFSET;
- }
- else
- {
- pin = gpio_pin;
- offset = 0;
- }
- /* enable gpio function */
- tls_io_cfg_set(gpio_pin, WM_IO_OPT5_GPIO);
- /* gpio direction */
- if (WM_GPIO_DIR_OUTPUT == dir)
- tls_reg_write32(HR_GPIO_DIR + offset, tls_reg_read32(HR_GPIO_DIR + offset) | BIT(pin)); /* 1 set output */
- else if (WM_GPIO_DIR_INPUT == dir)
- tls_reg_write32(HR_GPIO_DIR + offset, tls_reg_read32(HR_GPIO_DIR + offset) & (~BIT(pin))); /* 0 set input */
- /* gpio attribute */
- if (WM_GPIO_ATTR_FLOATING == attr)
- {
- tls_reg_write32(HR_GPIO_PULLUP_EN + offset, tls_reg_read32(HR_GPIO_PULLUP_EN + offset) | BIT(pin)); /* 1 disable pullup */
- tls_reg_write32(HR_GPIO_PULLDOWN_EN + offset, tls_reg_read32(HR_GPIO_PULLDOWN_EN + offset)&(~BIT(pin))); /* 1 disable pulldown */
-
- }
- if (WM_GPIO_ATTR_PULLHIGH == attr)
- {
- tls_reg_write32(HR_GPIO_PULLUP_EN + offset, tls_reg_read32(HR_GPIO_PULLUP_EN + offset) & (~BIT(pin))); /* 0 enable pullup */
- tls_reg_write32(HR_GPIO_PULLDOWN_EN + offset, tls_reg_read32(HR_GPIO_PULLDOWN_EN + offset) &(~BIT(pin))); /* 0 disable pulldown */
- }
- if (WM_GPIO_ATTR_PULLLOW == attr)
- {
- tls_reg_write32(HR_GPIO_PULLUP_EN + offset, tls_reg_read32(HR_GPIO_PULLUP_EN + offset) | BIT(pin)); /* 0 disable pullup */
- tls_reg_write32(HR_GPIO_PULLDOWN_EN + offset, tls_reg_read32(HR_GPIO_PULLDOWN_EN + offset) | BIT(pin)); /* 1 disable pulldown */
- }
- }
- /**
- * @brief This function is used to read gpio status
- *
- * @param[in] gpio_pin gpio pin num
- *
- * @retval 0 power level is low
- * @retval 1 power level is high
- *
- * @note None
- */
- __attribute__((section (".ram_run"))) u8 tls_gpio_read(enum tls_io_name gpio_pin)
- {
- u32 reg_en;
- u32 reg;
- u8 pin;
- u16 offset;
- if (gpio_pin >= WM_IO_PB_00)
- {
- pin = gpio_pin - WM_IO_PB_00;
- offset = TLS_IO_AB_OFFSET;
- }
- else
- {
- pin = gpio_pin;
- offset = 0;
- }
- u32 cpu_sr = 0;
- cpu_sr = tls_os_set_critical();
- // reg_en = tls_reg_read32(HR_GPIO_DATA_EN + offset);
- // tls_reg_write32(HR_GPIO_DATA_EN + offset, reg_en | (1 << pin));
- reg = tls_reg_read32(HR_GPIO_DATA + offset);
- // tls_reg_write32(HR_GPIO_DATA_EN + offset, reg_en);
- tls_os_release_critical(cpu_sr);
- if(reg & (0x1 << pin))
- return 1;
- else
- return 0;
- }
- /**
- * @brief This function is used to modify gpio status
- *
- * @param[in] gpio_pin gpio pin num
- * @param[in] value power level
- * 0: low power level
- * 1: high power level
- *
- * @return None
- *
- * @note None
- */
- __attribute__((section (".ram_run"))) void tls_gpio_write(enum tls_io_name gpio_pin, u8 value)
- {
- u32 cpu_sr = 0;
- u32 reg;
- u32 reg_en;
- u8 pin;
- u16 offset;
- if (gpio_pin >= WM_IO_PB_00)
- {
- pin = gpio_pin - WM_IO_PB_00;
- offset = TLS_IO_AB_OFFSET;
- }
- else
- {
- pin = gpio_pin;
- offset = 0;
- }
-
- cpu_sr = tls_os_set_critical();
-
- // reg_en = tls_reg_read32(HR_GPIO_DATA_EN + offset);
- // tls_reg_write32(HR_GPIO_DATA_EN + offset, reg_en | (1 << pin));
- reg = tls_reg_read32(HR_GPIO_DATA + offset);
- if(value)
- tls_reg_write32(HR_GPIO_DATA + offset, reg | (1 << pin)); /* write high */
- else
- tls_reg_write32(HR_GPIO_DATA + offset, reg & (~(1 << pin)));/* write low */
- // tls_reg_write32(HR_GPIO_DATA_EN + offset, reg_en);
- tls_os_release_critical(cpu_sr);
- }
- //add by hyj, 2022-05-20
- // 以极限速度输出io脉冲
- __attribute__((section (".ram_run"))) void tls_gpio_pulse(enum tls_io_name gpio_pin,u8* level,u16 len,u16 delay)
- {
- u32 cpu_sr = 0;
- u32 reg;
- u32 reg_en;
- u8 pin;
- u16 offset;
- u16 i;
- volatile u32 del=delay;
- if (gpio_pin >= WM_IO_PB_00)
- {
- pin = gpio_pin - WM_IO_PB_00;
- offset = TLS_IO_AB_OFFSET;
- }
- else
- {
- pin = gpio_pin;
- offset = 0;
- }
- cpu_sr = tls_os_set_critical();
- int GPIO_DATA = HR_GPIO_DATA + offset;
- // reg_en = tls_reg_read32(HR_GPIO_DATA_EN + offset);
- // tls_reg_write32(HR_GPIO_DATA_EN + offset, reg_en | (1 << pin));
- reg = tls_reg_read32(GPIO_DATA);
- u32 reg_high = reg | (1 << pin);
- u32 reg_low = reg & (~(1 << pin));
- for(i=0; i<len; i++)
- {
- if(level[i/8]&(0x80>>(i%8)))
- tls_reg_write32(GPIO_DATA, reg_high); /* write high */
- else
- tls_reg_write32(GPIO_DATA, reg_low); /* write low */
- del = delay;
- while(del--);
- }
- // tls_reg_write32(HR_GPIO_DATA_EN + offset, reg_en);
- tls_os_release_critical(cpu_sr);
- }
- /**
- * @brief This function is used to config gpio interrupt
- *
- * @param[in] gpio_pin gpio pin num
- * @param[in] mode interrupt trigger type
- *
- * @return None
- *
- * @note None
- */
- void tls_gpio_irq_enable(enum tls_io_name gpio_pin, enum tls_gpio_irq_trig mode)
- {
- u32 reg;
- u8 pin;
- u16 offset;
- u8 vec_no;
- if (gpio_pin >= WM_IO_PB_00)
- {
- pin = gpio_pin - WM_IO_PB_00;
- offset = TLS_IO_AB_OFFSET;
- vec_no = GPIOB_IRQn;
- }
- else
- {
- pin = gpio_pin;
- offset = 0;
- vec_no = GPIOA_IRQn;
- }
- // TLS_DBGPRT_INFO("\r\ntls_gpio_int_enable gpio pin =%d,mode==%d\r\n",gpio_pin,mode);
- switch(mode)
- {
- case WM_GPIO_IRQ_TRIG_RISING_EDGE:
- reg = tls_reg_read32(HR_GPIO_IS + offset);
- reg &= (~(0x1 << pin));
- // TLS_DBGPRT_INFO("\r\nrising edge is ret=%x\r\n",reg);
- tls_reg_write32(HR_GPIO_IS + offset, reg); /* 0 edge trigger */
- reg = tls_reg_read32(HR_GPIO_IBE + offset);
- reg &= (~(0x1 << pin));
- // TLS_DBGPRT_INFO("\r\nrising edge ibe ret=%x\r\n",reg);
- tls_reg_write32(HR_GPIO_IBE + offset, reg); /* 0 edge trigger */
- reg = tls_reg_read32(HR_GPIO_IEV + offset);
- reg |= (0x1 << pin);
- // TLS_DBGPRT_INFO("\r\nrising edge iev ret=%x\r\n",reg);
- tls_reg_write32(HR_GPIO_IEV + offset, reg); /* 1 rising edge trigger */
- break;
- case WM_GPIO_IRQ_TRIG_FALLING_EDGE:
- reg = tls_reg_read32(HR_GPIO_IS + offset);
- reg &= (~(0x1 << pin));
- // TLS_DBGPRT_INFO("\falling edge is ret=%x\n",reg);
- tls_reg_write32(HR_GPIO_IS + offset, reg); /* 0 edge trigger */
- reg = tls_reg_read32(HR_GPIO_IBE + offset);
- reg &= (~(0x1 << pin));
- // TLS_DBGPRT_INFO("\falling edge ibe ret=%x\n",reg);
- tls_reg_write32(HR_GPIO_IBE + offset, reg); /* 0 edge trigger */
- reg = tls_reg_read32(HR_GPIO_IEV + offset);
- reg &= (~(0x1 << pin));
- // TLS_DBGPRT_INFO("\falling edge iev ret=%x\n",reg);
- tls_reg_write32(HR_GPIO_IEV + offset, reg); /* 0 falling edge trigger */
- break;
- case WM_GPIO_IRQ_TRIG_DOUBLE_EDGE:
- reg = tls_reg_read32(HR_GPIO_IS + offset);
- tls_reg_write32(HR_GPIO_IS + offset, reg & (~(0x1 << pin))); /* 0 edge trigger */
- reg = tls_reg_read32(HR_GPIO_IBE + offset);
- tls_reg_write32(HR_GPIO_IBE + offset, reg | (0x1 << pin)); /* 1 double edge trigger */
- break;
- case WM_GPIO_IRQ_TRIG_HIGH_LEVEL:
- reg = tls_reg_read32(HR_GPIO_IS + offset);
- tls_reg_write32(HR_GPIO_IS + offset, reg | (0x1 << pin)); /* 1 level trigger */
- reg = tls_reg_read32(HR_GPIO_IEV + offset);
- tls_reg_write32(HR_GPIO_IEV + offset, reg | (0x1 << pin)); /* 1 high level trigger */
- break;
- case WM_GPIO_IRQ_TRIG_LOW_LEVEL:
- reg = tls_reg_read32(HR_GPIO_IS + offset);
- tls_reg_write32(HR_GPIO_IS + offset, reg | (0x1 << pin)); /* 1 level trigger */
- reg = tls_reg_read32(HR_GPIO_IEV + offset);
- tls_reg_write32(HR_GPIO_IEV + offset, reg & (~(0x1 << pin))); /* 0 low level trigger */
- break;
- }
- reg = tls_reg_read32(HR_GPIO_IE + offset);
- reg |= (0x1 << pin);
- // TLS_DBGPRT_INFO("\nie ret=%x\n",reg);
- tls_reg_write32(HR_GPIO_IE + offset, reg); /* enable interrupt */
- tls_irq_enable(vec_no);
- }
- /**
- * @brief This function is used to disable gpio interrupt
- *
- * @param[in] gpio_pin gpio pin num
- *
- * @return None
- *
- * @note None
- */
- void tls_gpio_irq_disable(enum tls_io_name gpio_pin)
- {
- u32 reg;
- u8 pin;
- u16 offset;
- if (gpio_pin >= WM_IO_PB_00)
- {
- pin = gpio_pin - WM_IO_PB_00;
- offset = TLS_IO_AB_OFFSET;
- reg = tls_reg_read32(HR_GPIO_IE + offset);
- tls_reg_write32(HR_GPIO_IE + offset, reg & (~(0x1 << pin))); /* disable interrupt */
- reg = reg&(~(0x1 << pin));
- if (reg == 0)
- {
- tls_irq_disable(GPIOB_IRQn);
- }
- }
- else
- {
- pin = gpio_pin;
- offset = 0;
- reg = tls_reg_read32(HR_GPIO_IE + offset);
- tls_reg_write32(HR_GPIO_IE + offset, reg & (~(0x1 << pin))); /* disable interrupt */
- reg = (reg&(~(0x1 << pin)))&0xFFFF;
- if (reg == 0)
- {
- tls_irq_disable(GPIOA_IRQn);
- }
- }
- }
- /**
- * @brief This function is used to get gpio interrupt status
- *
- * @param[in] gpio_pin gpio pin num
- *
- * @retval 0 no interrupt happened
- * @retval 1 interrupt happened
- *
- * @note None
- */
- u8 tls_get_gpio_irq_status(enum tls_io_name gpio_pin)
- {
- u32 reg;
- u8 pin;
- u16 offset;
- if (gpio_pin >= WM_IO_PB_00)
- {
- pin = gpio_pin - WM_IO_PB_00;
- offset = TLS_IO_AB_OFFSET;
- }
- else
- {
- pin = gpio_pin;
- offset = 0;
- }
- reg = tls_reg_read32(HR_GPIO_RIS + offset);
- if(reg & (0x1 << pin))
- return 1;
- else
- return 0;
- }
- /**
- * @brief This function is used to clear gpio interrupt flag
- *
- * @param[in] gpio_pin gpio pin num
- *
- * @return None
- *
- * @note None
- */
- void tls_clr_gpio_irq_status(enum tls_io_name gpio_pin)
- {
- u8 pin;
- u16 offset;
- if (gpio_pin >= WM_IO_PB_00)
- {
- pin = gpio_pin - WM_IO_PB_00;
- offset = TLS_IO_AB_OFFSET;
- }
- else
- {
- pin = gpio_pin;
- offset = 0;
- }
- tls_reg_write32(HR_GPIO_IC + offset, (0x1 << pin)); /* 1 clear interrupt status */
- }
- /**
- * @brief This function is used to register gpio interrupt
- *
- * @param[in] gpio_pin gpio pin num
- * @param[in] callback the gpio interrupt call back function
- * @param[in] arg parammeter for the callback
- *
- * @return None
- *
- * @note
- * gpio callback function is called in interrupt,
- * so can not operate the critical data in the callback fuuction,
- * recommendation to send messages to other tasks to operate it.
- */
- void tls_gpio_isr_register(enum tls_io_name gpio_pin,
- tls_gpio_irq_callback callback,
- void *arg)
- {
- gpio_context[gpio_pin].callback = callback;
- gpio_context[gpio_pin].arg = arg;
- }
|