/**************************************************************************** Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED. This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT be copied by any method or incorporated into another program without the express written consent of Aerospace C.Power. This Information or any portion thereof remains the property of Aerospace C.Power. The Information contained herein is believed to be accurate and Aerospace C.Power assumes no responsibility or liability for its use in any way and conveys no license or title under any patent or copyright and makes no representation or warranty that this Information is free from patent or copyright infringement. ****************************************************************************/ /* os shim includes */ #include "iot_config.h" #include "os_types.h" /* plc public api includes */ #include "plc_fr.h" #include "plc_const.h" #include "iot_bitops.h" /* driver includes */ #include "iot_irq.h" /* mac module internal includes */ #include "mac.h" #include "mac_dsr.h" #include "mac_rf_isr.h" #include "mac_reset.h" #include "mac_pdev.h" #if HW_PLATFORM != HW_PLATFORM_SIMU #include "rfplc_reg_base.h" #include "hw_reg_api.h" #include "mac_sys_reg.h" #include "rf_mac_reg.h" #include "mac_int.h" #include "mac_rf_common_hw.h" #include "mac_rf_timer.h" #include "mac_rf_sched_hw.h" #endif #if (HW_PLATFORM == HW_PLATFORM_SIMU || HPLC_RF_DEV_SUPPORT == 0) void mac_rf_hw_isr_enable(uint8_t id) { (void)id; } void mac_rf_sw_isr_enable(uint8_t id) { (void)id; } void mac_rf_hw_isr_disable(uint8_t id) { (void)id; } void mac_rf_sw_isr_disable(uint8_t id) { (void)id; } void mac_rf_set_sw_irq_to_bbcpu(uint8_t id) { (void)id; } void mac_rf_isr_start() { } void mac_rf_dsr_isr_start() { } dsr_notification_func_t mac_rf_get_dsr_callback() { return NULL; } void mac_rf_isr_init(dsr_notification_func_t callback) { (void)callback; } #else /* HW_PLATFORM == HW_PLATFORM_SIMU */ /* global mac isr context */ rf_mac_isr_ctx_t g_rf_mac_isr_0; rf_mac_isr_ctx_t *p_rf_mac_isr_0 = &g_rf_mac_isr_0; uint8_t IRAM_ATTR mac_rf_isr_get_dsr_id(uint32_t isr_id) { uint32_t dsr_id = MAC_DSR_MAX_ID; if (isr_id == RF_MAC_SW_ISR_TX_MPDU_COMPLETE) { dsr_id = MAC_DSR_MPDU_TX_COMP_ID; } else if (isr_id == RF_MAC_SW_ISR_RX_MPDU_COMPLETE) { dsr_id = MAC_DSR_MPDU_RX_ID; } return dsr_id; } uint32_t IRAM_ATTR mac_rf_get_hw_interrupt_sts() { return RF_MAC_READ_REG(CFG_RF_MAC_COMMON_INT_REG_6_ADDR); } void IRAM_ATTR mac_rf_clear_hw_interrupt(uint32_t irq_sts) { RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_4_ADDR, irq_sts); } static uint32_t IRAM_ATTR mac_rf_get_sw_interrupt_sts() { return RF_MAC_READ_REG(CFG_RF_MAC_COMMON_INT_REG_26_ADDR); } static void IRAM_ATTR mac_rf_clear_sw_interrupt(uint32_t irq_sts) { RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_24_ADDR, irq_sts); } /* get share intrrupt status, sw interrupt */ uint32_t mac_rf_get_share_interrupt_sts() { return RF_MAC_READ_REG(CFG_RF_MAC_COMMON_INT_REG_16_ADDR); } /* clear common intrrupt status, sw interrupt */ void mac_rf_clear_share_interrupt(uint32_t irq_sts) { RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_14_ADDR, irq_sts); } static void IRAM_ATTR mac_rf_dsr_isr_stop() { /* disable soc irq */ iot_interrupt_mask(p_rf_mac_isr_0->isr_hw_h); iot_interrupt_mask(p_rf_mac_isr_0->isr_sw_h); } static uint32_t IRAM_ATTR mac_rf_isr_handler(uint32_t vector, iot_addrword_t data) { uint8_t i, j, tmp; uint32_t sw_int_sts, hw_int_sts; uint8_t dsr[32], cnt; (void)vector; (void)data; /* get sw interrupt status */ sw_int_sts = mac_rf_get_sw_interrupt_sts(); mac_rf_clear_sw_interrupt(sw_int_sts); /* get hw interrupt status */ hw_int_sts = mac_rf_get_hw_interrupt_sts(); mac_rf_clear_hw_interrupt(hw_int_sts); /* sw isr handle */ i = 0; cnt = 0; while (sw_int_sts) { tmp = sw_int_sts & 0xFF; while (tmp) { j = iot_bitops_fls(tmp) - 1; tmp &= ~(0x1 << j); dsr[cnt] = mac_rf_isr_get_dsr_id(i + j); cnt++; } sw_int_sts >>= 8; i += 8; } if (cnt) { dsr[cnt] = MAC_RF_DSR_ISR_SYNC_ID; cnt++; p_rf_mac_isr_0->rf_dsr_callback(dsr, cnt); mac_rf_dsr_isr_stop(); } return 0; } static uint32_t IRAM_ATTR mac_rf_timer_isr_handler(uint32_t vector, iot_addrword_t data) { uint32_t timer_int_sts, cmdlist_id; (void)vector; (void)data; /* get timer interrupt status */ timer_int_sts = mac_rf_timer_get_timeout_ids(); mac_rf_timer_clr_timeout_ids(timer_int_sts); cmdlist_id = RF_MAC_SW_ISR_CMDLIST_BBCPU_DONE - RF_MAC_SW_INT_MAX; /* handle cmdlist cpu done */ if (timer_int_sts & (1 << cmdlist_id)) { /* clear sw int status */ timer_int_sts &= ~(1 << cmdlist_id); mac_rf_handle_cmdlist_done(); } #if HPLC_RF_ASYNC_TX uint32_t set_pcs_id = RF_MAC_SW_ISR_SET_HPLC_PCS - RF_MAC_SW_INT_MAX; /* handle set hplc to pcs */ if (timer_int_sts & (1 << set_pcs_id)) { /* clear sw int status */ timer_int_sts &= ~(1 << set_pcs_id); /* get hplc pcs status */ if (mac_rf_get_hplc_pcs_reg()) { /* set pcs busy */ mac_set_pcs_busy_from_isr(1, 1); /* set pcs status */ mac_rf_set_hplc_pcs_sts_reg(1); } else { /* free pcs busy */ mac_set_pcs_busy_from_isr(0, 0); } } #endif return 0; } static void mac_rf_hw_isr_reset(void) { /* disable all mac interrupt */ p_rf_mac_isr_0->isr_hw_mask = 0; RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_8_ADDR, p_rf_mac_isr_0->isr_hw_mask); RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_0_ADDR, p_rf_mac_isr_0->isr_hw_mask); /* clean up all pending interrupt */ RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_4_ADDR, RF_MAC_COMMON_IRQ_SW_CLR_CPU1_MASK); } static void mac_rf_sw_isr_reset(void) { /* sw interrupt */ /* disable all mac interrupt */ p_rf_mac_isr_0->isr_sw_mask = 0; RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_28_ADDR, p_rf_mac_isr_0->isr_sw_mask); RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_20_ADDR, p_rf_mac_isr_0->isr_sw_mask); /* clean up all pending interrupt */ RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_24_ADDR, RF_MAC_COM_SHARE_IRQ_SW_CLR_CPU1_MASK); /* timer interrupt */ p_rf_mac_isr_0->isr_timer_mask = 0; mac_rf_timer_disable_all(); } static void mac_rf_share_isr_reset(void) { /* disable all mac interrupt */ RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_18_ADDR, 0); RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_10_ADDR, 0); /* clean up all pending interrupt */ RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_14_ADDR, RF_MAC_COMMON_SHARE_IRQ_SW_CLR_CPU1_MASK); } static void mac_rf_share_isr_enable_all(void) { /* enable all mac interrupt */ RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_18_ADDR, RF_MAC_COMMON_SHARE_IRQ_MASK_CPU1_MASK); RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_10_ADDR, RF_MAC_COMMON_SHARE_IRQ_SW_EN_CPU1_MASK); } void mac_rf_hw_isr_enable(uint8_t id) { uint32_t int_mask; int_mask = 1 << id; if (!(p_rf_mac_isr_0->isr_hw_mask & int_mask)) { p_rf_mac_isr_0->isr_hw_mask |= int_mask; RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_8_ADDR, p_rf_mac_isr_0->isr_hw_mask); RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_0_ADDR, p_rf_mac_isr_0->isr_hw_mask); } } void mac_rf_sw_isr_enable(uint8_t id) { uint32_t int_mask; if (id < RF_MAC_SW_INT_MAX) { int_mask = 1 << id; if (!(p_rf_mac_isr_0->isr_sw_mask & int_mask)) { p_rf_mac_isr_0->isr_sw_mask |= int_mask; RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_28_ADDR, p_rf_mac_isr_0->isr_sw_mask); RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_20_ADDR, p_rf_mac_isr_0->isr_sw_mask); } } else { IOT_ASSERT(id < RF_MAC_SW2_INT_MAX); int_mask = 1 << (id - RF_MAC_SW_INT_MAX); if (!(p_rf_mac_isr_0->isr_timer_mask & int_mask)) { p_rf_mac_isr_0->isr_timer_mask |= int_mask; mac_rf_timer_enable(p_rf_mac_isr_0->isr_timer_mask); } } } void mac_rf_hw_isr_disable(uint8_t id) { uint32_t int_mask; int_mask = 1 << id; if (p_rf_mac_isr_0->isr_hw_mask & int_mask) { p_rf_mac_isr_0->isr_hw_mask &= ~int_mask; RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_8_ADDR, p_rf_mac_isr_0->isr_hw_mask); RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_0_ADDR, p_rf_mac_isr_0->isr_hw_mask); } } void mac_rf_sw_isr_disable(uint8_t id) { uint32_t int_mask; if (id < RF_MAC_SW_INT_MAX) { int_mask = 1 << id; if (p_rf_mac_isr_0->isr_sw_mask & int_mask) { p_rf_mac_isr_0->isr_sw_mask &= ~int_mask; RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_28_ADDR, p_rf_mac_isr_0->isr_sw_mask); RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_20_ADDR, p_rf_mac_isr_0->isr_sw_mask); } } else { IOT_ASSERT(id < RF_MAC_SW2_INT_MAX); int_mask = 1 << (id - RF_MAC_SW_INT_MAX); if (p_rf_mac_isr_0->isr_timer_mask & int_mask) { p_rf_mac_isr_0->isr_timer_mask &= ~int_mask; mac_rf_timer_enable(p_rf_mac_isr_0->isr_timer_mask); } } } void mac_rf_set_sw_irq_to_bbcpu(uint8_t id) { IOT_ASSERT(id < RF_MAC_SW_INT_MAX); RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_23_ADDR, (1 << id)); } void mac_rf_dsr_isr_start() { /* enable soc irq */ iot_interrupt_unmask(p_rf_mac_isr_0->isr_hw_h); iot_interrupt_unmask(p_rf_mac_isr_0->isr_sw_h); } void mac_rf_isr_start() { /* enable soc irq */ iot_interrupt_unmask(p_rf_mac_isr_0->isr_hw_h); iot_interrupt_unmask(p_rf_mac_isr_0->isr_sw_h); iot_interrupt_unmask(p_rf_mac_isr_0->isr_timer_h); } dsr_notification_func_t mac_rf_get_dsr_callback() { return p_rf_mac_isr_0->rf_dsr_callback; } void mac_rf_isr_init(dsr_notification_func_t callback) { os_mem_set(p_rf_mac_isr_0, 0, sizeof(*p_rf_mac_isr_0)); p_rf_mac_isr_0->rf_dsr_callback = callback; mac_rf_hw_isr_reset(); mac_rf_sw_isr_reset(); mac_rf_share_isr_reset(); /* enable all share int */ mac_rf_share_isr_enable_all(); /* allocate soc irq resource */ p_rf_mac_isr_0->isr_hw_h = iot_interrupt_create(HAL_VECTOR_RFMAC_INT0, HAL_INTR_PRI_7, (iot_addrword_t)NULL, mac_rf_isr_handler); p_rf_mac_isr_0->isr_sw_h = iot_interrupt_create(HAL_VECTOR_RFMAC_INT0, HAL_INTR_PRI_7, (iot_addrword_t)NULL, mac_rf_isr_handler); /* attach soc irq resource */ iot_interrupt_attach(p_rf_mac_isr_0->isr_hw_h); iot_interrupt_attach(p_rf_mac_isr_0->isr_sw_h); /* timer irq need isr handle */ p_rf_mac_isr_0->isr_timer_h = iot_interrupt_create(HAL_VECTOR_RFMAC_TIMEOUT_INT0, HAL_INTR_PRI_6, (iot_addrword_t)NULL, mac_rf_timer_isr_handler); iot_interrupt_attach(p_rf_mac_isr_0->isr_timer_h); } #endif /* HW_PLATFORM == HW_PLATFORM_SIMU */