void Encoder::end() { int i, j; #if defined (DMP_DOS_BC) || (DMP_DOS_DJGPP) detachInterrupt(); io_DisableINT(); if(mode == MODE_NOSET) return; #elif defined (DMP_LINUX) lockMCMSIF(); if(mode == MODE_NOSET) {unLockMCMSIF(); return;} #endif mcsif_Disable(mcn, mdn); #if defined (DMP_DOS_BC) || (DMP_DOS_DJGPP) if(mode == MODE_CAPTURE) { disable_MCINT(mcn, SIFB_CAP1INTBIT); disable_MCINT(mcn, SIFB_CAP2INTBIT); disable_MCINT(mcn, SIFB_CAP3INTBIT); } else { disable_MCINT(mcn, SIFB_TRIGRESETBIT); disable_MCINT(mcn, SIFB_USEREVTBIT); } #endif mode = _mcmode[mcn] = MODE_NOSET; _setZPol = false; _dir = 0; #if defined (DMP_DOS_BC) || (DMP_DOS_DJGPP) io_RestoreINT(); #elif defined (DMP_LINUX) unLockMCMSIF(); #endif for(i=0; i<4; i++) { if(_encfunc[i] != NULL) break; for(j=0; j<3; j++) if(_pcapfunc[i][j] != NULL) break; } #if defined (DMP_DOS_BC) || (DMP_DOS_DJGPP) if(i == 4 && j == 3) { mc_outp(MC_GENERAL, 0x38, mc_inp(MC_GENERAL, 0x38) | (1L << mcn)); if(used_irq == 0xff) return; if(irq_UninstallISR(used_irq, (void*)name) == false) printf("irq_uninstall fail\n"); else used_irq = 0xff; } #endif }
static bool interrupt_init(int mc) { if(used_irq != 0xff) return true; if(irq_InstallISR(GetMCIRQ(), user_int, (void*)name) == false) { printf("irq_install fail\n"); return false; } // enable mcm general interrupt function mc_outp(MC_GENERAL, 0x38, mc_inp(MC_GENERAL, 0x38) & ~(1L << mc)); used_irq = GetMCIRQ(); return true; }
void Encoder::end() { int i, j; if(mode == MODE_NOSET) return; detachInterrupt(); io_DisableINT(); mcsif_Disable(mcn, mdn); if(mode == MODE_CAPTURE) { disable_MCINT(mcn, SIFB_CAP1INTBIT); disable_MCINT(mcn, SIFB_CAP2INTBIT); disable_MCINT(mcn, SIFB_CAP3INTBIT); } else { disable_MCINT(mcn, SIFB_TRIGRESETBIT); disable_MCINT(mcn, SIFB_USEREVTBIT); } mode = _mcmode[mcn] = MODE_NOSET; _setZPol = false; io_RestoreINT(); for(i=0; i<4; i++) { if(_encfunc[i] != NULL) break; for(j=0; j<3; j++) if(_pcapfunc[i][j] != NULL) break; } if(i == 4 && j == 3) { mc_outp(MC_GENERAL, 0x38, mc_inp(MC_GENERAL, 0x38) | (1L << mcn)); if(irq_UninstallISR(used_irq, (void*)name) == false) printf("irq_install fail\n"); else used_irq = 0xff; } }
static int user_int(int irq, void* data) { int i, m, n, evt = 0; unsigned long capdata; // detect interrupt pin for(i=0; i<EXTERNAL_NUM_INTERRUPTS; i++) { m = i/3; // sif mc n = i%3; // offset (capture pin number 1/2/3) if(mcm_init[m] == false) {i += 2; continue;} if((mc_inp(m, 0x04) & ((0x20000000L)<<n)) != 0L) // detect input edge-trigger { mc_outp(m, 0x04, (0x20000000L)<<n); break; } if((mc_inp(m, 0x04) & ((0x04000000L)<<n)) != 0L) // detect input level-trigger { mc_outp(m, 0x04, (0x04000000L)<<n); break; } } // execute user function for the pin if(i < EXTERNAL_NUM_INTERRUPTS) { switch(_usedMode[m][n]) { case MCPFAU_CAP_LEVEL0: case MCPFAU_CAP_LEVEL1: sifSetMask[n](m, MCSIF_MODULEB, MCPFAU_MASK_INACTIVE); sifClearStat[n](m, MCSIF_MODULEB); evt++; break; case MCPFAU_CAP_BOTH: while(readCapStat[n](m, MCSIF_MODULEB)!= MCENC_CAPFIFO_EMPTY) if(readCapFIFO[n](m, MCSIF_MODULEB, &capdata) != MCPFAU_CAP_CAPCNT_OVERFLOW) evt++; break; case MCPFAU_CAP_1TO0: while(readCapStat[n](m, MCSIF_MODULEB)!= MCENC_CAPFIFO_EMPTY) if(readCapFIFO[n](m, MCSIF_MODULEB, &capdata) == MCPFAU_CAP_1TO0EDGE) evt++; break; case MCPFAU_CAP_0TO1: while(readCapStat[n](m, MCSIF_MODULEB)!= MCENC_CAPFIFO_EMPTY) if(readCapFIFO[n](m, MCSIF_MODULEB, &capdata) == MCPFAU_CAP_0TO1EDGE) evt++; break; } // do user's function for(; evt > 0; evt--) _userfunc[i](); // if select level-trigger, switch the MASK to "NONE" after user's function is complete. switch(_usedMode[m][n]) { case MCPFAU_CAP_LEVEL0: case MCPFAU_CAP_LEVEL1: sifSetMask[n](m, MCSIF_MODULEB, MCPFAU_MASK_NONE); break; default: break; } } return ISR_HANDLED; }
static void enable_MCINT(unsigned long used_int) { mc_outp(MC_GENERAL, 0x38, mc_inp(MC_GENERAL, 0x38) & ~(1L << mc)); mc_outp(mc, 0x00, used_int<<mcint_offset[md]); }
static void disable_MCINT(void) { mc_outp(mc, 0x00, 0x00L); // disable mc interrupt mc_outp(MC_GENERAL, 0x38, mc_inp(MC_GENERAL, 0x38) | (1L << mc)); }
static void clear_INTSTATUS(void) { mc_outp(mc, 0x04, 0xff0000ffL); //for EX }
DMP_INLINE(void) enable_MCINT(unsigned long used_int) { mc_outp(MC_GENERAL, 0x38, mc_inp(MC_GENERAL, 0x38) & ~(1L << mc)); mc_outp(mc, 0x00, (mc_inp(mc, 0x00) & ~(0xffL<<mcint_offset[md])) | (used_int << mcint_offset[md])); }
DMP_INLINE(void) disable_MCINT(void) { mc_outp(mc, 0x00, mc_inp(mc, 0x00) & ~(0xffL << mcint_offset[md])); // disable mc interrupt mc_outp(MC_GENERAL, 0x38, mc_inp(MC_GENERAL, 0x38) | (1L << mc)); }
DMP_INLINE(void) clear_INTSTATUS(void) { mc_outp(mc, 0x04, 0xffL << mcint_offset[md]); //for EX }
static void clear_interrupt_state(int mc, int bit) { mc_outp(mc, MCMINT_STAT_REG, (0x01)<<bit); }
static void disable_MCINT(int mc, int bit) { mc_outp(mc, 0x00, mc_inp(mc, 0x00) & ~(0x01<<bit)); }
static void enable_MCINT(int mc, int bit) { mc_outp(mc, 0x00, mc_inp(mc, 0x00) | (0x01<<bit)); }
static void clear_INTSTATUS(int mc) { mc_outp(mc, 0x04, 0xff000000L); //for EX }
static void clear_INTSTATUS(void) { mc_outp(mc, 0x04, 0xffL << mcint_offset[md]); //for EX }