Exemple #1
0
// Communicating with mast via SPI
void COMM_Manager(void)
{
	static uint16_t unCOM_Buff[COMM_FIFO_LENGTH];
	static uint32_t unLastFrameCNT = 0;
	static uint32_t unLastCheckTime = 0;
	// All transactions are handled in interrupt
	if (tMotor.structMotor.MSR.bNewComFrameReceived == TRUE)
	{
		memcpy(unCOM_Buff, unCOM_SPI_ReadData, COMM_FIFO_LENGTH);
		tMotor.structMotor.MSR.bNewComFrameReceived = FALSE;
		if (CRC16((uint8_t *)unCOM_Buff, (IS_COMM_RD_CMD(unCOM_Buff[0]) ? ((COMM_RD_CMD_CNT - 1) << 1) : ((COMM_WR_CMD_CNT - 1) << 1))) ==
				(IS_COMM_RD_CMD(unCOM_Buff[0]) ? unCOM_Buff[COMM_RD_CMD_CNT - 1] : unCOM_Buff[COMM_WR_CMD_CNT - 1]))
		{
			unValidFrameCNT++;
			// safe zone
			if (IS_COMM_RD_CMD(unCOM_Buff[0]))
			{
				nReadCommandHandler(unCOM_Buff);
			}
			else
			{
				nWriteCommandHandler(unCOM_Buff);
			}
		}
		else
		{
			unCOM_SPI_TransErrCNT++;
		}
	}
	
	// Comm protection 1: If have NOT received any frame in 500ms, error
	if ((uint32_t)(unSystemTick - unLastCheckTime) > 500)
	{
		unLastCheckTime = unSystemTick;
		if ((uint32_t)(unValidFrameCNT - unLastFrameCNT) < 1)
		{
			BLDC_stopMotor();
			setError(ERR_COMMUNICATION_FAIL);
		}
		unLastFrameCNT = unValidFrameCNT;
	}
	// Comm protection 2: If received error frame exceed some threshold, error
	if (unCOM_SPI_TransErrCNT > COM_SPI_TRANS_ERR_THRESHOLD)
	{
		BLDC_stopMotor();
		setError(ERR_COMMUNICATION_FAIL);
	}
}
Exemple #2
0
/***************************************************************
 * Function:	void MOT_commandDutyCycle(uint16_t dutyCycle)
 *
 * Purpose:		To update the duty cycle required by higher-
 * 					level software
 *
 * Parameters:	uint16_t dutyCycle		This is the fixed-point representation
 * 										of the motor duty cycle.  0%-100% is scaled
 * 										to 0-65535
 *
 * Returns:		none
 *
 * Globals affected:	none
 **************************************************************/
void
MOT_commandDutyCycle(uint16_t dutyCycle)
{
	if(dutyCycle < MOT_MIN_DUTY_CYCLE)
	{
		dutyCycle = 0;
		MOT_stopMotor();
	}
	else
	{
		MOT_startMotor();
	}

	switch(motor.type)
	{
		case MOT_DC:
			MDC_commandDutyCycle(dutyCycle);
			break;

		case MOT_BLDC:
			BLDC_commandDutyCycle(dutyCycle);
			break;

		default:
			BLDC_stopMotor();
			break;
	}

	return;
} // END MOT_commandDutyCycle
__INLINE void dutyProtection(void)
{
	// Duty too big protection
	if ((tMotor.structMotor.unActualDuty > MAX_MOTOR_PWR_DUTY) || (PWM->CMR[1] > MAX_MOTOR_PWR_DUTY))
	{
		BLDC_stopMotor();
		setError(ERR_INTERNAL);
	}
}
Exemple #4
0
/***************************************************************
 * Function:	void MOT_stopMotor(void)
 *
 * Purpose:		To stop the appropriate motor based on the
 * 					previously defined motor type
 *
 * Parameters:	none
 *
 * Returns:		none
 *
 * Globals affected:	none
 **************************************************************/
void
MOT_stopMotor(void)
{
	switch(motor.type)
	{
		case MOT_DC:
			MDC_stopMotor();
			break;

		case MOT_BLDC:
			BLDC_stopMotor();
			break;

		default:
			BLDC_stopMotor();
			break;
	}

	return;
} // END MOT_stopMotor()
Exemple #5
0
/***************************************************************
 * Function:	void MOT_defineMotorType(_MOT_motorType motorType)
 *
 * Purpose:		This defines the motor type to be used, which chooses
 * 					the motor library to be utilized
 *
 * Parameters:	_MOT_motorType motorType
 *
 * Returns:		none
 *
 * Globals affected:	motor.type
 **************************************************************/
void
MOT_defineMotorType(_MOT_motorType motorType)
{
	// Stop all motor activity
	BLDC_stopMotor();
	MDC_stopMotor();

	// Change the motor type
	motor.type = motorType;

	MOT_initMotor();

	return;
} // END MOT_defineMotorType()
__INLINE void phaseDurationProtection(uint32_t unLastPhaseChangeTime)
{
	static uint32_t unCurrentPHCHG;
	// Single phase duration too long protection
	if (TRUE == tMotor.structMotor.MSR.bMotorPowerOn)
	{
		if (unCurrentPHCHG != PWM->PHCHG)
		{
			unCurrentPHCHG = PWM->PHCHG;
			unLastPhaseChangeTime = unSystemTick;
		}
		else
		{
			if ((uint32_t)(unSystemTick - unLastPhaseChangeTime) > MAX_SINGLE_PHASE_DURATION)
			{
				BLDC_stopMotor();
				setError(ERR_INTERNAL);
			}
		}
	}
}
// Take charge of all Motot control
void BLDC_SensorLessManager(void)
{
	uint16_t unMotorAlreadyRotatingPhaseTime;
	static uint32_t iEnterTimeBeforeWait;

	dutyProtection();
	phaseDurationProtection(unLastPhaseChangeTime);

	switch (tMotorState)
	{
	case MOTOR_IDLE:
		if (tMotor.structMotor.MCR.bMotorNeedToRun && NO_MOTOR_EEROR)
		{
			unRotateDetectStartTime = unSystemTick;
			tRotateDetectState = DETECT_START;
			tMotorState = MOTOR_START;
		}
		break;
		
	case MOTOR_START:
		if (tMotor.structMotor.MCR.bMotorNeedToRun && NO_MOTOR_EEROR)
		{
			// Later implement this when motor can rotate
			// Then stop it while rotating to measure the waveform
			// Manually rotate it is too slow 
			unMotorAlreadyRotatingPhaseTime = canMotorContinueRunning();
			if (unMotorAlreadyRotatingPhaseTime != IS_ROTATING_DETECTING)
			{
				if (unMotorAlreadyRotatingPhaseTime > 0)
				{
					// 1 to 65534
					tMotorState = MOTOR_LOCKED;
				}
				else
				{
					// When back to Idle state the motor was already shut down
					// MOTOR_SHUT_DOWN;
					unCurrentPhase = 0;
					unLocateIndex = 0;
					tMotor.structMotor.MSR.unMissedZXD_CNT = 0;
					unLastPhaseChangeTime = unSystemTick;
					tMotor.structMotor.MSR.bMotorPowerOn = TRUE;
					// Clear start detect zero cross flag
					tMotor.structMotor.MSR.bZeroCrossDetecting = FALSE;
					tMotor.structMotor.MSR.bLocked = FALSE;
					//setPhaseManually(tMotor.structMotor.LCT_DUTY, unCurrentPhase);
					BRG_ENABLE;
					tMotorState = MOTOR_LOCATE;
				}
			}
		}
		else
		{
			BLDC_stopMotor();
		}
		break;

	case MOTOR_LOCATE:
		if (tMotor.structMotor.MCR.bMotorNeedToRun && NO_MOTOR_EEROR)
		{
			if (BLDC_LocatingManager() == STATUS_FINISHED)
			{
				iEnterTimeBeforeWait = unSystemTick;
				tMotorState = MOTOR_WAIT_AFTER_LOCATE;
			}
		}
		else
		{
			BLDC_stopMotor();
		}
		break;

	case MOTOR_WAIT_AFTER_LOCATE:
		if (tMotor.structMotor.MCR.bMotorNeedToRun && NO_MOTOR_EEROR)
		{
			if ((uint32_t)(unSystemTick - iEnterTimeBeforeWait) >= WAIT_AFTER_LOCATE_TIME)
			{
				tMotor.structMotor.unActualDuty = tMotor.structMotor.unRampUpDuty;
				tMotor.structMotor.unActualPeriod = tMotor.structMotor.unRampUpPeriod;
				tMotor.structMotor.MSR.bMotorPowerOn = TRUE;
				PHASE_INCREASE(unCurrentPhase);
				setPhaseManually(tMotor.structMotor.unActualDuty, unCurrentPhase);
				BRG_ENABLE;
				// Set timer 0 valure, use timer 0 to change phase automatically
				// ************************************************************************
				// ----==== From here current unCurrentPhase is actually next phase ====----
				// ----==== Because we want to use the HW auto phase changer (PWM->PHCHGNXT) ====----
				// So increase unCurrentPhase again. Want to get real current phase value? Read PWM->PHCHG.
				// ************************************************************************
				PHASE_INCREASE(unCurrentPhase);
				PWM->PHCHGNXT = GET_PHASE_VALUE(unCurrentPhase);
				// !!!! Need to make sure CPU runs to here every min tMotor.structMotor.ACT_PERIOD time !!!
				// !!!! If not , timer counter may already passed tMotor.structMotor.ACT_PERIOD, !!!!
				// !!!! then need to count to max timer counter number (which is 2^24), !!!!
				// !!!! go back to 0 and triger interrupt when reach ACT_PERIOD again !!!!
				TIMER_SET_CMP_VALUE(TIMER0, tMotor.structMotor.unActualPeriod);
				TIMER_Start(TIMER0);	// Once started, running and interrupting until Motor stop
				TIMER_EnableInt(TIMER0);
				unPeriodChangeCNT_AfterPR_ReachMini = 0;
				unPhaseChangeCNT_AtCurrentDuty = 0;
				unPhaseChangeCNT_AtCurrentPeriod = 0;
				tMotorState = MOTOR_RAMPUP_WO_ZXD;
			}
		}
		else
		{
			BLDC_stopMotor();
		}
		break;

	case MOTOR_RAMPUP_WO_ZXD:	// without zero cross detection
		if (tMotor.structMotor.MCR.bMotorNeedToRun && NO_MOTOR_EEROR)
		{
			BLDCRampUp_Manager();
			if (tMotor.structMotor.unActualPeriod <= MOTOR_START_ZXD_SPEED)	//(iRampUpPeriodMiniCNT > MOTOR_START_ZXD_MINROT_CNT)  //
			{
				tMotor.structMotor.MSR.bThisPhaseDetectedZX = FALSE;
				tMotor.structMotor.MSR.bZeroCrossDetecting = TRUE;
				// Speed is enough for zero cross detecting
				// Prepare everything
				// T0 used to change phase automatically -- already configured
				// T1 used to filter ZX

//				TIMER_SET_CMP_VALUE(TIMER1, GET_TIM1_CMP_VALUE(TIMER1->TDR + AVOID_ZXD_AFTER_PHCHG));
//				FLAG_TIM1_USEAGE = ENUM_TIM1_AVOID_ZXD;
				ACMP0_ENABLE;
				TIMER_Start(TIMER1);	// Once started, running until Motor stop
//				TIMER_EnableInt(TIMER1);
				// Suppose last ZX detected time 
//				unLastZXDetectedTime = MINI51_TIM_CNT_MAX - tMotor.structMotor.ACT_PERIOD / 2;
				tMotorState = MOTOR_RAMPUP_W_ZXD;
			}
		}
		else
		{
			BLDC_stopMotor();
		}
		break;

	case MOTOR_RAMPUP_W_ZXD:	// with zero cross detection
		if (tMotor.structMotor.MCR.bMotorNeedToRun && NO_MOTOR_EEROR)
		{
			if (TRUE == tMotor.structMotor.MSR.bLocked)
			{
				// Finally, everything was prepared:
				// T0 used to change phase automatically
				// T1 used to filter ZX
				tMotorState = MOTOR_LOCKED;
			}
			else
			{
				if (unPeriodChangeCNT_AfterPR_ReachMini < RAMP_UP_MIN_PERIOD_NUM_THRS)
				{
					BLDCRampUp_Manager(); 
				}
				else
				{
					setError(ERR_RAMPUP_FAIL);
				}
			}
		}
		else
		{
			BLDC_stopMotor();
		}
		break;

	case MOTOR_LOCKED:
		if (tMotor.structMotor.MCR.bMotorNeedToRun && NO_MOTOR_EEROR)
		{
			BLDCSpeedManager();	// Mainly PWM duty increase/decrease
		}
		else
		{
			BLDC_stopMotor();
		}
		break;

	default:
		break;
	}
}