#include "chip.h" #include "board.h" #include "sema.h" static SemaphoreHandle_t gate_mutex[SEMA_GATE_MAX] = {0}; static QueueHandle_t gate_status[SEMA_GATE_MAX] = {0}; static sema_gate_state_e sema_gate_status(sema_gate_e gate) { if (gate >= SEMA_GATE_MAX) return pdFAIL; return (sema_gate_state_e)(rSemaGate(gate)&0x3); } static int sema_gate_lock(sema_gate_e gate) { int ret = 1; rSemaGate(gate) = (LOCAL_CPx + 1); if (sema_gate_status(gate) != (sema_gate_state_e)(LOCAL_CPx + 1)) { ret = 0; } return ret; } static int sema_gate_unlock(sema_gate_e gate) { int ret = 1; rSemaGate(gate) = SEMA_GATE_S_UNLOCK; if (sema_gate_status(gate) != SEMA_GATE_S_FREE) { ret = 0; } return ret; } static void sema_int_enable(sema_gate_e gate, int enable) { if (enable) { rSemaCPINE(gate / 32) |= ( 1<< (gate % 32)); } else { rSemaCPINE(gate / 32) &= ~( 1<< (gate % 32)); } } static void sema_clear_int_flag(void) { rSemaIRQCLR = 0x1; } static int sema_get_int_flag(sema_gate_e gate) { return (rSemaCPINTFLG(gate / 32) & (1 << (gate % 32)))? 1 : 0; } static void sema_reset_gate(sema_gate_e gate, int all_gate) { unsigned int gate_n = gate; if (all_gate) { gate_n = 64; } rSemaRSTGT = (gate_n << 8) | 0xe2; rSemaRSTGT = (gate_n << 8) | 0x1d; } static void sema_reset_int_notify(sema_gate_e gate, int all_gate) { unsigned int gate_n = gate; if (all_gate) { gate_n = 64; } rSemaRSTNTF = (gate_n << 8) | 0x47; rSemaRSTNTF = (gate_n << 8) | 0xb8; } void sema_int_handler(void *param) { int i; for (i=0; i= SEMA_GATE_MAX) return pdFAIL; if (xSemaphoreTake(gate_mutex[gate], xTicksToWait) != pdPASS) { return pdFAIL; } sema_int_enable(gate, 1); xQueueReset(gate_status[gate]); while (!sema_gate_lock(gate)) { ret = xQueueReceive(gate_status[gate], NULL, (xTicksToWait > 0)?1:0); if (ret == pdPASS) break; if (xTicksToWait > 0) xTicksToWait--; if (xTicksToWait == 0) break; } sema_int_enable(gate, 0); if (ret != pdPASS) { if (sema_gate_status(gate) == (sema_gate_state_e)(LOCAL_CPx + 1)) ret = pdPASS; } if (ret != pdPASS) { xSemaphoreGive(gate_mutex[gate]); } return ret; } int sema_give(sema_gate_e gate) { int ret = pdPASS; if (gate >= SEMA_GATE_MAX) return pdFAIL; ret = sema_gate_unlock(gate); if (!uxSemaphoreGetCount(gate_mutex[gate])) { xSemaphoreGive(gate_mutex[gate]); } return ret; } void sema_init(void) { int i; //sema_reset_gate(0, 1); //sema_reset_int_notify(0, 1); for (i=0; i