Example #1
0
void Encoder::attachInterrupt(void (*callback)(int)) {
	if(mode == MODE_NOSET) return;
	
	if(mode == MODE_CAPTURE && callback != NULL)
	{
		if(_pcapfunc[mcn][0] != NULL || _pcapfunc[mcn][1] != NULL || _pcapfunc[mcn][2] != NULL)	return;
		if(interrupt_init(mcn) == false) return;
		
		mcsif_Disable(mcn, mdn);
	
		io_DisableINT();
		_pcapfunc[mcn][0] = callback;
		_pcapfunc[mcn][1] = callback;
		_pcapfunc[mcn][2] = callback;
		io_RestoreINT();

		clear_INTSTATUS(mcn);
		enable_MCINT(mcn, SIFB_CAP1INTBIT);
		enable_MCINT(mcn, SIFB_CAP2INTBIT);
		enable_MCINT(mcn, SIFB_CAP3INTBIT);
		
		// Enable interrupt option
		for(int i=0; i<3; i++)
		{
			sifIntMode[i](mcn, mdn, MCPFAU_CAP_BOTH_CLEAR);
			sifSetInt[i](mcn, mdn, 1L);
	    }

		mcsif_Enable(mcn, mdn);
		_pcapAttchINT = true;
		return;
	}
	
	if(callback != NULL)
	{
		if(_encfunc[mcn] != NULL) return;
		if(interrupt_init(mcn) == false) return;
		
		mcsif_Disable(mcn, mdn);
		
		io_DisableINT();
		_encfunc[mcn] = callback;
		io_RestoreINT();

		clear_INTSTATUS(mcn);
		enable_MCINT(mcn, SIFB_TRIGRESETBIT);
		enable_MCINT(mcn, SIFB_USEREVTBIT);
		enable_MCINT(mcn, SIFB_PCNT_OV);
		enable_MCINT(mcn, SIFB_PCNT_UV);
		
		// Enable interrupt option
		mcenc_SetCapInterval(mcn, mdn, 1L);
		mcsif_Enable(mcn, mdn);
	}
}
Example #2
0
void Encoder::setRange(unsigned long val, bool condition) {
	if(mode == MODE_NOSET || mode == MODE_CAPTURE || mode == MODE_SSI) return;
	if(val == 0L) return;
    
	mcsif_Disable(mcn, mdn);
    
	if(condition == true)
	{
		mcenc_SetCapMode(mcn, mdn, MCENC_CAP_PCNT_DISABLE + MCENC_CAP_EXTRIG_DISABLE + MCENC_CAP_IDXCOND_ENABLE); // start to use FIFO (mean that capture event will occur)
		io_DisableINT();
		_encmode[mcn] |= INTR_OVERFLOW;
		_encmode[mcn] |= INTR_UNDERFLOW;
		io_RestoreINT();
	}
	else
	{
		if((_encmode[mcn] & (INTR_INDEX | INTR_OVERFLOW | INTR_UNDERFLOW)) == 0 && condition == false)
			mcenc_SetCapMode(mcn, mdn, MCENC_CAP_PCNT_DISABLE + MCENC_CAP_EXTRIG_DISABLE + MCENC_CAP_IDXCOND_DISABLE);
		io_DisableINT();
		_encmode[mcn] &= ~(INTR_OVERFLOW);
		_encmode[mcn] &= ~(INTR_UNDERFLOW);
		io_RestoreINT();
	}
	
	mcenc_SetCntMax(mcn, mdn, val);
	
	mcsif_Enable(mcn, mdn);
}
Example #3
0
void Encoder::setIndexReset(bool condition) {
	if(mode == MODE_NOSET || mode == MODE_CAPTURE || mode == MODE_SSI) return;
	
	mcsif_Disable(mcn, mdn);
	if(condition == true)
	{
		mcenc_SetResetMode(mcn, mdn, MCENC_RESET_INC_CNTMINIDX + MCENC_RESET_DEC_CNTMAXIDX);
		
		if(_setZPol == false) // if you use setInputPolarity() to set Z pin's pol to inverse before setIndexReset()
		{
			// In fact, below actions are same as mcenc_SetIdxCond(mcn, mdn, MCENC_PDIR_IDXCOND_Z, MCENC_ICZ1);
			if(mode == MODE_STEP_DIR || mode == MODE_STEP_DIR_x2)
				mcenc_SetIdxCond(mcn, mdn, MCENC_PDIR_IDXCOND_Z, MCENC_ICZ1);
			else if(mode == MODE_CWCCW || mode == MODE_CWCCW_x2)
				mcenc_SetIdxCond(mcn, mdn, MCENC_CWCCW_IDXCOND_Z, MCENC_ICZ1);
			else if(mode == MODE_AB_PHASE || mode == MODE_AB_PHASE_x2)
				mcenc_SetIdxCond(mcn, mdn, MCENC_PAB_IDXCOND_Z, MCENC_ICZ1);
		}
		
		io_DisableINT();
		_encmode[mcn] |= INTR_INDEX;
		io_RestoreINT();
	}
	else
	{
		mcenc_SetIdxCond(mcn, mdn, MCENC_PDIR_IDXCOND_DISABLE, 0L);
		mcenc_SetResetMode(mcn, mdn, MCENC_RESET_INC_CNTMIN + MCENC_RESET_DEC_CNTMAX);
		
		io_DisableINT();
		_encmode[mcn] &= ~(INTR_INDEX);
		io_RestoreINT();
	}
	mcsif_Enable(mcn, mdn);
}
Example #4
0
void detachInterrupt(uint8_t interruptNum) {
	int i;
	mc = interruptNum/3;
	
	if(interruptNum >= EXTERNAL_NUM_INTERRUPTS) return;
	if(_userfunc[interruptNum] == NULL) return;
	
	mcsif_Disable(mc, md);
	sifIntMode[interruptNum%3](mc, md, MCPFAU_CAP_DISABLE);
	
	io_DisableINT();
	_userfunc[interruptNum] = NULL;
	io_RestoreINT();
	
	for(i=0; i<3; i++)
		if(_userfunc[mc*3+i] != NULL) break;
	if(i == 3) mcmsif_close(); else mcsif_Enable(mc, md);
	
	for(i=0; i<EXTERNAL_NUM_INTERRUPTS; i++)
		if(_userfunc[i] != NULL) break;
	if(i == EXTERNAL_NUM_INTERRUPTS)
	{
		if(irq_UninstallISR(used_irq, (void*)name) == false)
		    printf("irq_install fail\n");
		else
			used_irq = 0xff;
	}
}
Example #5
0
void Encoder::setDigitalFilter(unsigned long width) {
    if(mode == MODE_NOSET) return;
    if(mode == MODE_CAPTURE && _pcapAttchINT == true) return;
    
    mcsif_Disable(mcn, mdn);
    mcsif_SetInputFilter(mcn, mdn, width);
    mcsif_Enable(mcn, mdn);
}
Example #6
0
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
}
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);
}
Example #8
0
// only for COMPAREMATCH and INDEXRESET condition
void Encoder::detachInterrupt() {
    int i;

	if(mode == MODE_CAPTURE)
	{
		if(_pcapfunc[mcn][0] == NULL || _pcapfunc[mcn][1] == NULL || _pcapfunc[mcn][2] == NULL)	return;
		mcsif_Disable(mcn, mdn);
		
		// Disable interrupt option
		for(int i=0; i<3; i++)
		{
			sifIntMode[i](mcn, mdn, MCPFAU_CAP_DISABLE);
			sifSetInt[i](mcn, mdn, 0L);
	    }
		
		io_DisableINT();
		_pcapfunc[mcn][0] = NULL;
		_pcapfunc[mcn][1] = NULL;
		_pcapfunc[mcn][2] = NULL;
		io_RestoreINT();
		
		_pcapAttchINT = false;
		// not enable sif
		return;
	}
	
	
	if(_encfunc[mcn] == NULL) return;
	
	mcsif_Disable(mcn, mdn);
	
	// Disable interrupt option
	mcenc_SetCapInterval(mcn, mdn, 0L);
	
	io_DisableINT();
	_encfunc[mcn] = NULL;
	_encmode[mcn] &= ~(INTR_COMPARE);
	_encmode[mcn] &= ~(INTR_INDEX);
	io_RestoreINT();
	
	// re-enable sif
	mcsif_Enable(mcn, mdn);
}
Example #9
0
void Encoder::write(unsigned long cnt) {
	if(mode == MODE_NOSET || mode == MODE_CAPTURE) return;
	
	mcsif_Disable(mcn, mdn);
	if(mode == MODE_SSI)
		mcssi_SetPulCnt(mcn, mdn, cnt);
	else	
		mcenc_SetPulCnt(mcn, mdn, cnt);
	mcsif_Enable(mcn, mdn);
}
Example #10
0
DMP_INLINE(void) mcmsif_close(int32_t mc)
{
    mcsif_Disable(mc, MCSIF_MODULEB);
#if defined (DMP_DOS_DJGPP)
    io_DisableINT();
#endif
    mcm_init[mc] = false;
#if defined (DMP_DOS_DJGPP)
    io_RestoreINT();
#endif
}
Example #11
0
void Encoder::setComparator(unsigned long evncnt, bool condition) {
	if(mode == MODE_NOSET || mode == MODE_CAPTURE || mode == MODE_SSI) return;
	
	mcsif_Disable(mcn, mdn);
	
	mcenc_SetCntEvt(mcn, mdn, evncnt);
	
	io_DisableINT();
	if(condition == true)
		_encmode[mcn] |= INTR_COMPARE;
	else
		_encmode[mcn] &= ~(INTR_COMPARE);
	io_RestoreINT();
	
	mcsif_Enable(mcn, mdn);
}
Example #12
0
void Encoder::setDigitalFilter(unsigned long width) {
    if(mode == MODE_NOSET) return;
    if(mode == MODE_CAPTURE && _pcapAttchINT == true) return;

#if defined (DMP_LINUX)
	lockMCMSIF();
#endif

    mcsif_Disable(mcn, mdn);
    mcsif_SetInputFilter(mcn, mdn, width);
    mcsif_Enable(mcn, mdn);

#if defined (DMP_LINUX)
	unLockMCMSIF();
#endif
}
Example #13
0
void Encoder::write(unsigned long cnt) {
	if(mode == MODE_NOSET || mode == MODE_CAPTURE) return;

#if defined (DMP_LINUX)
	lockMCMSIF();
#endif

	mcsif_Disable(mcn, mdn);
	if(mode == MODE_SSI)
		mcssi_SetPulCnt(mcn, mdn, cnt);
	else	
		mcenc_SetPulCnt(mcn, mdn, cnt);
	mcsif_Enable(mcn, mdn);

#if defined (DMP_LINUX)
	unLockMCMSIF();
#endif
}
Example #14
0
DMPAPI(void) detachInterrupt(uint8_t interruptNum)
{
#if defined (DMP_LINUX)
    if(interruptNum > MAX_INTR_NUM + 1)
        return;

    OSSPINLOCK(idc.spinlock);
    idc.intr[interruptNum].used = false;
    uint8_t mc = interruptNum/3;
    lockMCMSIF();
    if(mc < 4 && !(idc.intr[mc*3].used) && !(idc.intr[mc*3 + 1].used) && !(idc.intr[mc*3 + 2].used))
        mcmsif_close(mc);
    unLockMCMSIF();
    OSSPINUNLOCK(idc.spinlock);
#elif defined (DMP_DOS_DJGPP)
    int i;
    mc = interruptNum/3;

    if(interruptNum >= EXTERNAL_NUM_INTERRUPTS) return;
    if(_userfunc[interruptNum] == NULL) return;

    mcsif_Disable(mc, md);
    sifIntMode[interruptNum%3](mc, md, MCPFAU_CAP_DISABLE);

    io_DisableINT();
    _userfunc[interruptNum] = NULL;
    io_RestoreINT();

    for(i=0; i<3; i++)
        if(_userfunc[mc*3+i] != NULL) break;
    if(i == 3) mcmsif_close(mc);
    else mcsif_Enable(mc, md);

    for(i=0; i<EXTERNAL_NUM_INTERRUPTS; i++)
        if(_userfunc[i] != NULL) break;
    if(i == EXTERNAL_NUM_INTERRUPTS)
    {
        if(irq_UninstallISR(used_irq, (void*)name) == false)
            printf("irq_install fail\n");
        else
            used_irq = 0xff;
    }
#endif
}
Example #15
0
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;
	}
}
Example #16
0
void Encoder::setIndexReset(bool condition) {
	if(mode == MODE_NOSET || mode == MODE_CAPTURE || mode == MODE_SSI) return;
	
	mcsif_Disable(mcn, mdn);
	
	if(condition == true)
	{
		mcenc_SetResetMode(mcn, mdn, MCENC_RESET_INC_CNTMINIDX + MCENC_RESET_DEC_CNTMAXIDX);
        mcenc_SetCapMode(mcn, mdn, MCENC_CAP_PCNT_DISABLE + MCENC_CAP_EXTRIG_DISABLE + MCENC_CAP_IDXCOND_ENABLE); // start to use FIFO (mean that capture event will occur)

		if(_setZPol == false) // if you use setInputPolarity() to set Z pin's pol to inverse before setIndexReset()
		{
			// In fact, below actions are same as mcenc_SetIdxCond(mcn, mdn, MCENC_PDIR_IDXCOND_Z, MCENC_ICZ1);
			if(mode == MODE_STEP_DIR || mode == MODE_STEP_DIR_x2)
				mcenc_SetIdxCond(mcn, mdn, MCENC_PDIR_IDXCOND_Z, MCENC_ICZ1);
			else if(mode == MODE_CWCCW || mode == MODE_CWCCW_x2)
				mcenc_SetIdxCond(mcn, mdn, MCENC_CWCCW_IDXCOND_Z, MCENC_ICZ1);
			else if(mode == MODE_AB_PHASE || mode == MODE_AB_PHASE_x2)
				mcenc_SetIdxCond(mcn, mdn, MCENC_PAB_IDXCOND_Z, MCENC_ICZ1);
		}
		
		io_DisableINT();
		_encmode[mcn] |= INTR_INDEX;
		io_RestoreINT();
	}
	else
	{
		if((_encmode[mcn] & (INTR_INDEX | INTR_OVERFLOW | INTR_UNDERFLOW)) == 0)
			mcenc_SetCapMode(mcn, mdn, MCENC_CAP_PCNT_DISABLE + MCENC_CAP_EXTRIG_DISABLE + MCENC_CAP_IDXCOND_DISABLE);
		mcenc_SetIdxCond(mcn, mdn, MCENC_PDIR_IDXCOND_DISABLE, 0L);
		mcenc_SetResetMode(mcn, mdn, MCENC_RESET_INC_CNTMIN + MCENC_RESET_DEC_CNTMAX);
		
		io_DisableINT();
		_encmode[mcn] &= ~(INTR_INDEX);
		io_RestoreINT();
	}
    
	mcsif_Enable(mcn, mdn);
}
Example #17
0
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;
	}
}
Example #18
0
static void mcmsif_close(void) {
	mcsif_Disable(mc, md);
	io_DisableINT();
	mcm_init[mc] = false;
	io_RestoreINT();
}
Example #19
0
void Encoder::setInputPolarity(bool pinA, bool pinB, bool pinZ) {
	if(mode == MODE_NOSET || mode == MODE_CAPTURE || mode == MODE_SSI) return;
	
	mcsif_Disable(mcn, mdn);
	if(mode == MODE_STEP_DIR)
	{
		// 8 conditions
		if(pinA == LOW && pinB == HIGH)
		{
			mcenc_SetCntMode(mcn, mdn, MCENC_PDIR_DIR0_INC1TO0 + MCENC_PDIR_DIR1_DEC1TO0);
		}
		else if(pinA == HIGH && pinB == LOW)
		{
			mcenc_SetCntMode(mcn, mdn, MCENC_PDIR_DIR0_DEC0TO1 + MCENC_PDIR_DIR1_INC0TO1);
		}
		else if(pinA == LOW && pinB == LOW)
		{
			mcenc_SetCntMode(mcn, mdn, MCENC_PDIR_DIR0_DEC1TO0 + MCENC_PDIR_DIR1_INC1TO0);
		}
		else // all HIGH
		{
			mcenc_SetCntMode(mcn, mdn, MCENC_PDIR_DIR0_INC0TO1 + MCENC_PDIR_DIR1_DEC0TO1);
		}
		
		if(pinZ == LOW)
		{
			mcenc_SetIdxCond(mcn, mdn, MCENC_PDIR_IDXCOND_Z, MCENC_ICZ0);
			_setZPol = true;
		}
		else
			mcenc_SetIdxCond(mcn, mdn, MCENC_PDIR_IDXCOND_Z, MCENC_ICZ1);
	}
	else if(mode == MODE_CWCCW)
	{
		if(pinA == LOW && pinB == HIGH)
		{
			mcenc_SetCntMode(mcn, mdn, MCENC_CWCCW_CW_INC1TO0 + MCENC_CWCCW_CCW_DEC0TO1);
		}
		else if(pinA == HIGH && pinB == LOW)
		{
			mcenc_SetCntMode(mcn, mdn, MCENC_CWCCW_CW_INC0TO1 + MCENC_CWCCW_CCW_DEC1TO0);
		}
		else if(pinA == LOW && pinB == LOW)
		{
			mcenc_SetCntMode(mcn, mdn, MCENC_CWCCW_CW_INC1TO0 + MCENC_CWCCW_CCW_DEC1TO0);
		}
		else // all NORMAL
		{
			mcenc_SetCntMode(mcn, mdn, MCENC_CWCCW_CW_INC0TO1 + MCENC_CWCCW_CCW_DEC0TO1);
		}
		
		if(pinZ == LOW)
		{
			mcenc_SetIdxCond(mcn, mdn, MCENC_CWCCW_IDXCOND_Z, MCENC_ICZ0);
			_setZPol = true;
		}
		else
			mcenc_SetIdxCond(mcn, mdn, MCENC_CWCCW_IDXCOND_Z, MCENC_ICZ1);
	}
	else if(mode == MODE_AB_PHASE)
	{
		if((pinA == LOW && pinB == LOW) || (pinA == HIGH && pinB == HIGH))
			mcenc_SetCntMode(mcn, mdn, MCENC_PAB_DIR0_INCA + MCENC_PAB_DIR1_DECA);
		else
			mcenc_SetCntMode(mcn, mdn, MCENC_PAB_DIR0_DECA + MCENC_PAB_DIR1_INCA);
		
		if(pinZ == LOW)
		{
			mcenc_SetIdxCond(mcn, mdn, MCENC_PAB_IDXCOND_Z, MCENC_ICZ0);
			_setZPol = true;
		}
		else
			mcenc_SetIdxCond(mcn, mdn, MCENC_PAB_IDXCOND_Z, MCENC_ICZ1);
	}
	// 2X samplerate cases
	else if(mode == MODE_STEP_DIR_x2)
	{
		// 4 conditions
		if(pinB == LOW)
		{
			mcenc_SetCntMode(mcn, mdn, MCENC_PDIR_DIR0_DECBOTH + MCENC_PDIR_DIR1_INCBOTH);
		}
		else // all HIGH
		{
			mcenc_SetCntMode(mcn, mdn, MCENC_PDIR_DIR0_INCBOTH + MCENC_PDIR_DIR1_DECBOTH);
		}
		
		if(pinZ == LOW)
		{
			mcenc_SetIdxCond(mcn, mdn, MCENC_PDIR_IDXCOND_Z, MCENC_ICZ0);
			_setZPol = true;
		}
		else
			mcenc_SetIdxCond(mcn, mdn, MCENC_PDIR_IDXCOND_Z, MCENC_ICZ1);
	}
	else if(mode == MODE_CWCCW_x2)
	{
		if(pinZ == LOW)
		{
			mcenc_SetIdxCond(mcn, mdn, MCENC_CWCCW_IDXCOND_Z, MCENC_ICZ0);
			_setZPol = true;
		}
		else
			mcenc_SetIdxCond(mcn, mdn, MCENC_CWCCW_IDXCOND_Z, MCENC_ICZ1);
	}
	else if(mode == MODE_AB_PHASE_x2)
	{
		if((pinA == LOW && pinB == LOW) || (pinA == HIGH && pinB == HIGH))
			mcenc_SetCntMode(mcn, mdn, MCENC_PAB_DIR0_INCAB + MCENC_PAB_DIR1_DECAB);
		else
			mcenc_SetCntMode(mcn, mdn, MCENC_PAB_DIR0_DECAB + MCENC_PAB_DIR1_INCAB);
		
		if(pinZ == LOW)
		{
			mcenc_SetIdxCond(mcn, mdn, MCENC_PAB_IDXCOND_Z, MCENC_ICZ0);
			_setZPol = true;
		}
		else
			mcenc_SetIdxCond(mcn, mdn, MCENC_PAB_IDXCOND_Z, MCENC_ICZ1);
	}
	mcsif_Enable(mcn, mdn);
}
Example #20
0
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;
	}
}