DMP_INLINE(int) addIRQEntry(uint8_t interruptNum, void (*callback)(void), int mode, uint32_t timeout) { OSSPINLOCK(idc.spinlock); idc.intr[interruptNum].used = true; idc.intr[interruptNum].callback = callback; idc.intr[interruptNum].mode = mode; idc.intr[interruptNum].start = micros(); idc.intr[interruptNum].timeout = timeout; pinMode(pin_interrupt[interruptNum], INPUT); if(mode != LOW && mode != HIGH && timeout == 0) { uint16_t crossbar_ioaddr; int32_t mc = interruptNum/3; int32_t md = MCSIF_MODULEB; lockMCMSIF(); if(mcm_init[mc] == false) mcmsif_init(mc); crossbar_ioaddr = sb_Read16(0x64)&0xfffe; if (mc == 0) io_outpb(crossbar_ioaddr + 2, 0x01); // GPIO port2: 0A, 0B, 0C, 3A else if (mc == 1) io_outpb(crossbar_ioaddr + 3, 0x02); // GPIO port3: 1A, 1B, 1C, 3B else if(mc == 2) io_outpb(crossbar_ioaddr, 0x03); // GPIO port0: 2A, 2B, 2C, 3C else if(mc == 3) { io_outpb(crossbar_ioaddr + 2, 0x01); io_outpb(crossbar_ioaddr + 3, 0x02); io_outpb(crossbar_ioaddr, 0x03); } mcsif_Disable(mc, md); switch (mode) { case CHANGE: sifIntMode[interruptNum%3](mc, md, MCPFAU_CAP_BOTH); break; case FALLING: sifIntMode[interruptNum%3](mc, md, MCPFAU_CAP_1TO0); break; case RISING: sifIntMode[interruptNum%3](mc, md, MCPFAU_CAP_0TO1); break; default: break; } // switch crossbar to MCM_SIF_PIN io_outpb(crossbar_ioaddr + 0x90 + pin_offset[interruptNum], 0x08);//RICH IO mcsif_Enable(mc, md); unLockMCMSIF(); } OSSPINUNLOCK(idc.spinlock); }
void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) { int i; unsigned short crossbar_ioaddr; if(interruptNum >= EXTERNAL_NUM_INTERRUPTS) { printf("This interrupt%d has no one pin to use\n", interruptNum); return; } mc = interruptNum/3; md = MCSIF_MODULEB; if(_userfunc[interruptNum] != NULL) return; if(interrupt_init() == false) return; mcmsif_init(); clear_INTSTATUS(); enable_MCINT(0xfc); // SIFB FAULT INT3/2/1 + STAT3/2/1 = 6 bits crossbar_ioaddr = sb_Read16(0x64)&0xfffe; if (mc == 0) io_outpb(crossbar_ioaddr + 2, 0x01); // GPIO port2: 0A, 0B, 0C, 3A else if (mc == 1) io_outpb(crossbar_ioaddr + 3, 0x02); // GPIO port3: 1A, 1B, 1C, 3B else if(mc == 2) io_outpb(crossbar_ioaddr, 0x03); // GPIO port0: 2A, 2B, 2C, 3C else if(mc == 3) { io_outpb(crossbar_ioaddr + 2, 0x01); io_outpb(crossbar_ioaddr + 3, 0x02); io_outpb(crossbar_ioaddr, 0x03); } mcsif_Disable(mc, md); io_DisableINT(); _userfunc[interruptNum] = userFunc; io_RestoreINT(); switch (mode) { case LOW: sifSetPol[interruptNum%3](mc, md, MCPFAU_POL_INVERSE); sifSetMask[interruptNum%3](mc, md, MCPFAU_MASK_INACTIVE); sifSetRelease[interruptNum%3](mc, md, MCPFAU_FAURELS_FSTAT0); sifClearStat[interruptNum%3](mc, md); _usedMode[mc][interruptNum%3] = MCPFAU_CAP_LEVEL0; clear_INTSTATUS(); break; case HIGH: sifSetMask[interruptNum%3](mc, md, MCPFAU_MASK_INACTIVE); sifSetRelease[interruptNum%3](mc, md, MCPFAU_FAURELS_FSTAT0); sifClearStat[interruptNum%3](mc, md); _usedMode[mc][interruptNum%3] = MCPFAU_CAP_LEVEL1; clear_INTSTATUS(); break; case CHANGE: sifIntMode[interruptNum%3](mc, md, MCPFAU_CAP_BOTH); _usedMode[mc][interruptNum%3] = MCPFAU_CAP_BOTH; break; case FALLING: sifIntMode[interruptNum%3](mc, md, MCPFAU_CAP_1TO0); _usedMode[mc][interruptNum%3] = MCPFAU_CAP_1TO0; break; case RISING: sifIntMode[interruptNum%3](mc, md, MCPFAU_CAP_0TO1); _usedMode[mc][interruptNum%3] = MCPFAU_CAP_0TO1; break; default: printf("No support this mode\n"); return; } // switch crossbar to MCM_SIF_PIN io_outpb(crossbar_ioaddr + 0x90 + pin_offset[interruptNum], 0x08);//RICH IO mcsif_Enable(mc, md); // If select level-trigger, switch the MASK to "NONE" after sif is enabled. switch (mode) { case LOW: case HIGH: sifSetMask[interruptNum%3](mc, md, MCPFAU_MASK_NONE); break; default: break; } }
void attachInterrupt(uint8_t interruptNum, void (*userCallBackFunc)(void), int mode) { unsigned short crossbar_ioaddr; if(interruptNum >= EXTERNAL_NUM_INTERRUPTS) { printf("This interrupt%d has no one pin to use\n", interruptNum); return; } mc = PIN86[INTPINSMAP[interruptNum]].ENCMC; md = PIN86[INTPINSMAP[interruptNum]].ENCMD; if(PIN86[INTPINSMAP[interruptNum]].userfunc != NULL) return; if(interrupt_init() == false) return; mcmsif_init(); clear_INTSTATUS(); enable_MCINT(0xfc); // SIFB FAULT INT3/2/1 + STAT3/2/1 = 6 bits crossbar_ioaddr = sb_Read16(0x64)&0xfffe; mcsif_Disable(mc, md); io_DisableINT(); PIN86[INTPINSMAP[interruptNum]].userfunc = userCallBackFunc; io_RestoreINT(); switch (mode) { case LOW: sifSetPol[interruptNum%3](mc, md, MCPFAU_POL_INVERSE); sifSetMask[interruptNum%3](mc, md, MCPFAU_MASK_INACTIVE); sifSetRelease[interruptNum%3](mc, md, MCPFAU_FAURELS_FSTAT0); sifClearStat[interruptNum%3](mc, md); _usedMode[mc][interruptNum%3] = MCPFAU_CAP_LEVEL0; clear_INTSTATUS(); break; case HIGH: sifSetMask[interruptNum%3](mc, md, MCPFAU_MASK_INACTIVE); sifSetRelease[interruptNum%3](mc, md, MCPFAU_FAURELS_FSTAT0); sifClearStat[interruptNum%3](mc, md); _usedMode[mc][interruptNum%3] = MCPFAU_CAP_LEVEL1; clear_INTSTATUS(); break; case CHANGE: sifIntMode[interruptNum%3](mc, md, MCPFAU_CAP_BOTH); _usedMode[mc][interruptNum%3] = MCPFAU_CAP_BOTH; break; case FALLING: sifIntMode[interruptNum%3](mc, md, MCPFAU_CAP_1TO0); _usedMode[mc][interruptNum%3] = MCPFAU_CAP_1TO0; break; case RISING: sifIntMode[interruptNum%3](mc, md, MCPFAU_CAP_0TO1); _usedMode[mc][interruptNum%3] = MCPFAU_CAP_0TO1; break; default: printf("No support this mode\n"); return; } // switch crossbar to MCM_SIF_PIN io_outpb(crossbar_ioaddr + 0x90 + PIN86[INTPINSMAP[interruptNum]].gpN, 0x08);//RICH IO mcsif_Enable(mc, md); // If select level-trigger, switch the MASK to "NONE" after sif is enabled. switch (mode) { case LOW: case HIGH: sifSetMask[interruptNum%3](mc, md, MCPFAU_MASK_NONE); break; default: break; } }