#include "include.h" #define EXT_ISR_MAX_VECTOR_MAP ((int)(sizeof(ext_vector_cb) / sizeof(ext_vector_sel))) static const ext_vector_sel ext_vector_cb[] = { {IO_PA0, PORT_INT0_VECTOR},{IO_PA1, PORT_INT0_VECTOR},{IO_PA2, PORT_INT0_VECTOR},{IO_PA3, PORT_INT0_VECTOR}, {IO_PA4, PORT_INT1_VECTOR},{IO_PA5, PORT_INT1_VECTOR},{IO_PA6, PORT_INT1_VECTOR},{IO_PA7, PORT_INT1_VECTOR}, {IO_PB0, PORT_INT2_VECTOR},{IO_PB3, PORT_INT2_VECTOR},{IO_PB5, PORT_INT2_VECTOR},{IO_PB6, PORT_INT2_VECTOR}, {IO_PB1, PORT_INT3_VECTOR},{IO_PE5, PORT_INT3_VECTOR},{IO_PF0, PORT_INT3_VECTOR},{IO_PF1, PORT_INT3_VECTOR}, {IO_PB2, PORT_INT4_VECTOR},{IO_PB7, PORT_INT4_VECTOR},{IO_PE3, PORT_INT4_VECTOR},{IO_PE4, PORT_INT4_VECTOR}, {IO_PB4, PORT_INT5_VECTOR},{IO_PE0, PORT_INT5_VECTOR},{IO_PE1, PORT_INT5_VECTOR},{IO_PE2, PORT_INT5_VECTOR}, {IO_PE6, PORT_INT6_VECTOR},{IO_PF2, PORT_INT6_VECTOR},{IO_PF3, PORT_INT6_VECTOR},{IO_EDGE_FALL, PORT_INT6_VECTOR}, {IO_PE7, PORT_INT7_VECTOR},{IO_PF4, PORT_INT7_VECTOR},{IO_PF5, PORT_INT7_VECTOR},{IO_EDGE_RISE, PORT_INT7_VECTOR}, }; static port_int_cb_t port_int_cb[EXT_ISR_MAX_ID]; static bool is_sleep_mode = 0; //根据中断向量号查询中断结构体 port_int_cb_t *extab_user_isr_inqure_cb_from_irq(int irq_num) { port_int_cb_t *pi_cb = NULL; for (u8 i = 0; i < EXT_ISR_MAX_ID; i++) { pi_cb = &port_int_cb[i]; if ((pi_cb->flag == true) && (pi_cb->vector == irq_num)) { return pi_cb; } } return NULL; } //根据GPIO查询中断结构体 port_int_cb_t *extab_user_isr_inqure_cb_from_gpio(u8 io_num) { port_int_cb_t *pi_cb = NULL; for (u8 i = 0; i < EXT_ISR_MAX_ID; i++) { pi_cb = &port_int_cb[i]; if ((pi_cb->flag == true) && (pi_cb->io_num == io_num)) { return pi_cb; } } return NULL; } //设置中断 void extab_user_isr_set_do(port_int_cb_t *pi_cb, bool reg_en) { if (reg_en) { port_irq_register(pi_cb->vector, pi_cb->callback); } if (pi_cb->stand) { port_wakeup_init(pi_cb->io_num, pi_cb->edg, pi_cb->pupd_type); } else { port_wakeup_all_init(pi_cb->io_num, pi_cb->edg, pi_cb->pupd_type); } } //清除中断 void extab_user_isr_clr_do(port_int_cb_t *pi_cb) { port_irq_free(pi_cb->vector); port_wakeup_exit(pi_cb->io_num); } bool extab_user_isr_set(u8 gpio_num, ext_edge_type edg, ext_pupd_type pupd_type, isr_t callback_func) { if ((gpio_num == IO_NONE) || (gpio_num > IO_PF5)) { return false; } //是否已经建立 port_int_cb_t *p = NULL; for (u8 i = 0; i < EXT_ISR_MAX_ID; i++) { p = &port_int_cb[i]; if ((p->io_num == gpio_num) && (p->flag == true)) { p->callback = callback_func; return true; } } for (u8 i = 0; i < EXT_ISR_MAX_ID; i++) { p = &port_int_cb[i]; if (p->flag == false) { //向量号查询 for (u8 k = 0; k < EXT_ISR_MAX_VECTOR_MAP; k++) { if (gpio_num == ext_vector_cb[k].io_num) { p->vector = ext_vector_cb[k].irq_num; p->stand = true; break; } } //非独立中断,采用通用中断 if (!p->stand) { p->vector = (edg == RISE_EDGE ? PORT_INT7_VECTOR : PORT_INT6_VECTOR); } p->pupd_type = pupd_type; //上下拉模式 p->callback = callback_func; //回调 p->io_num = gpio_num; //引脚 p->edg = edg; //触发边沿 p->flag = true; //设置标志 p->mode = MODE_ONLY_AWAKEN; //默认模式 extab_user_isr_set_do(p, true); break; } } return true; } bool extab_user_isr_clr(u8 gpio_num) { port_int_cb_t *p = NULL; p = extab_user_isr_inqure_cb_from_gpio(gpio_num); if (p != NULL) { extab_user_isr_clr_do(p); memset(p, 0, sizeof(port_int_cb_t)); return true; } return false; } bool extab_user_isr_mode_set(u8 gpio_num, ext_mode_type mode) { port_int_cb_t *p = NULL; p = extab_user_isr_inqure_cb_from_gpio(gpio_num); if (p != NULL) { p->mode = mode; return true; } return false; } //-------------------------------------------------------------------------------- //中断进休眠设置 void port_int_disable_to_sleep(void) { port_int_cb_t *p = NULL; for(u8 i = 0; i < EXT_ISR_MAX_ID; i++) { p = &port_int_cb[i]; if ((p->flag == true)) { if (p->mode == MODE_ONLY_AWAKEN) { extab_user_isr_clr_do(p); } else if (p->mode >= MODE_BOTH_AWAKEN_SLEEP) { extab_user_isr_set_do(p, false); } } } is_sleep_mode = true; } //中断退休眠设置 void port_int_enable_exit_sleep(void) { is_sleep_mode = false; port_int_cb_t *p = NULL; for(u8 i = 0; i < EXT_ISR_MAX_ID; i++) { p = &port_int_cb[i]; if ((p->flag == true)) { extab_user_isr_set_do(p, true); } } } //中断休眠处理 AT(.text.lowpwr.sleep) void port_int_sleep_process(u32 *wku) { if (!is_sleep_mode) { return; } int bit = 0; u32 weakpu, pending, status; weakpu = pending = status = *(u32 *)wku; port_int_cb_t *p = NULL; while (status) { bit = xbs_ff1(status); p = extab_user_isr_inqure_cb_from_irq(bit); status &= ~BIT(bit); weakpu &= ~BIT(bit); if (p) { if (p->callback != NULL && p->mode >= MODE_BOTH_AWAKEN_SLEEP) { p->callback(); } if (p->mode == MODE_BOTH_AWAKEN_SLEEP_PWK) { pending &= ~BIT(bit); weakpu |= BIT(bit); } } else { pending &= ~BIT(bit); weakpu |= BIT(bit); } } if (*(u32 *)wku) { WKUPCPND = ((u8)pending) << 16; *(u32 *)wku = ((u8)weakpu); } }