Пример #1
0
// Turn PWM off for the given pin
void pwmOff(const IOPin* pin){
	const TimerCompare* channel = compareFromIOPin(pin);
	if(channel){
//		compareDetach(channel);
		compareSetOutputMode(channel, CHANNEL_MODE_DISCONNECT);
	}
}
Пример #2
0
static void setConnected(__ACTUATOR *actuator, boolean connected){
	TOSHIBA_TB6612FNG_2pin_MOTOR* motor = (TOSHIBA_TB6612FNG_2pin_MOTOR*)actuator;
	const TimerCompare* channel1 = compareFromIOPin(motor->pwm1);
	const TimerCompare* channel2 = compareFromIOPin(motor->pwm2);

	if(connected){
		// connect
		// restore previous speed
		setSpeed(actuator, act_getSpeed(motor));
	}else{
		// Set both outputs to low to coast - by setting duty cycle to TOP
		compareSetThreshold(channel1, timerGetTOP(compareGetTimer(channel1)));
		compareSetThreshold(channel2, timerGetTOP(compareGetTimer(channel2)));
	}

}
Пример #3
0
static void setConnected(__ACTUATOR *actuator, boolean connected){
	MOTOR* motor = (MOTOR*)actuator;
	const TimerCompare* channel = compareFromIOPin(motor->pwm);

	// Turn on/off the pin to start/stop sending PWM
	compareSetOutputMode(channel, (connected) ? CHANNEL_MODE_NON_INVERTING : CHANNEL_MODE_DISCONNECT);
}
Пример #4
0
static void setConnected(__ACTUATOR *actuator, boolean connected){
	MOTOR* motor = (MOTOR*)actuator;
	const TimerCompare* channel = compareFromIOPin(motor->pwm);

	// Turn on/off the pin to start/stop sending PWM
	// reverts to default output logic level of low
	compareSetOutputMode(channel, (connected) ? CHANNEL_MODE_NON_INVERTING : CHANNEL_MODE_DISCONNECT);
	pin_make_output(motor->direction1,FALSE);
}
Пример #5
0
// Set up PWM on the given pin
boolean pwmInitDeciHertz(const IOPin* pin, uint32_t deciHertz, PERCENTAGE duty, uint32_t* actualDeciHertz){
	boolean rtn = FALSE;
	const TimerCompare* channel = compareFromIOPin(pin);

	if(channel==null){
		setError(PWM_PIN_NOT_AVAILABLE);
	}else{
		// The pin is valid
		// The pin is valid and available
		TIMER_MODE mode;
		uint16_t icr;
		uint16_t prescaler;
		uint32_t actual;

		const Timer* timer = compareGetTimer(channel);

		// Find the best PWM setting
		boolean valid = timerCalcPwm(timer, deciHertz, 100, &mode, &icr, &prescaler, &actual);

		if(!valid){
			// There is no PWM setting that is valid
			setError( (timerIsInUse(timer)) ? PWM_TIMER_IN_USE : TIMER_HAS_NO_PWM );
		}else{
			// Lets set up the PWM
			timerSetMode(timer,mode);
			if(modeIsICR(mode)){
				// Set the ICR
				PORT icrPort = pgm_read_word(&timer->pgm_icr);
				_SFR_MEM16(icrPort)=icr;
			}

			// Mark the channel as in use
//			compareAttach(channel,&nullTimerCompareCallback,0,null);

			// Turn the pin into an output, low
			pin_make_output(pin, FALSE);

			// Turn on the PWM pin output
			compareSetOutputMode(channel, CHANNEL_MODE_NON_INVERTING);

			// Turn on the timer
			timerSetPrescaler(timer,prescaler);

			// Set the initial duty cycle
			pwmSetDutyCycle(pin,duty);

			// Set the return value
			if(actualDeciHertz){
				*actualDeciHertz = actual;
			}

			rtn = TRUE;
		}
	}
	return rtn;
}
Пример #6
0
// Callback - for when the speed has been set
static void setSpeed(__ACTUATOR *actuator, DRIVE_SPEED speed){
	TOSHIBA_TB6612FNG_2pin_MOTOR* motor = (TOSHIBA_TB6612FNG_2pin_MOTOR*)actuator;
	const TimerCompare* channel1 = compareFromIOPin(motor->pwm1);
	const TimerCompare* channel2 = compareFromIOPin(motor->pwm2);

	// New compare threshold
	uint16_t delay=0;

	if( speed > 0 ){
		delay = interpolateU(speed, 0, DRIVE_SPEED_MAX, 0, timerGetTOP(compareGetTimer(channel2)));
		compareSetThreshold(channel1,0);	    // Keep permanently high
		compareSetThreshold(channel2,delay);	// pwm channel 2
	}else if(speed < 0){
		delay = interpolateU(speed, 0, DRIVE_SPEED_MIN,  0 , timerGetTOP(compareGetTimer(channel1)));
		compareSetThreshold(channel2,0);	    // Keep permanently high
		compareSetThreshold(channel1,delay);	// pwm channel 1
	}else{
		// brake
		// Set both pins high
		compareSetThreshold(channel1,0);	    // Keep permanently high
		compareSetThreshold(channel2,0);	    // Keep permanently high
	}
}
Пример #7
0
static boolean initPWM(const IOPin* pin, uint32_t deciHertz){
	const TimerCompare* channel = compareFromIOPin(pin);

	if(channel==null){
		setError(PWM_PIN_NOT_AVAILABLE);
		return FALSE;
	}
	if(compareIsInUse(channel)){
		setError(PWM_PIN_IN_USE);
		return FALSE;
	}

	TIMER_MODE mode;
	uint16_t icr;
	uint16_t prescaler;

	const Timer* timer = compareGetTimer(channel);

	// Find the best PWM setting for 10kHz, with 128 steps
	boolean valid = timerCalcPwm(timer, deciHertz, 128, &mode, &icr, &prescaler);

	if(!valid){
		// There is no PWM setting that is valid
		setError( (timerIsInUse(timer)) ? PWM_TIMER_IN_USE : TIMER_HAS_NO_PWM );
	}else{
		// Lets set up the PWM
		if(!timerIsInUse(timer)){
			timerSetMode(timer,mode);
			if(modeIsICR(mode)){
				// Set the ICR
				PORT icrPort = pgm_read_word(&timer->pgm_icr);
				_SFR_MEM16(icrPort)=icr;
			}
		}

		// Make it an output pin and set high for brake
		pin_make_output(pin,TRUE);

		// Use inverting PWM
		compareSetOutputMode(channel,CHANNEL_MODE_INVERTING);

		// Mark the channels as in use
		compareAttach(channel,&nullTimerCompareCallback,0,null);

		// Do this last as it then turns on the timer
		timerSetPrescaler(timer,prescaler);
	}
	return valid;
}
Пример #8
0
// Call back - for when the speed has been set
static void setSpeed(__ACTUATOR *actuator, DRIVE_SPEED speed){
	MOTOR* motor = (MOTOR*)actuator;
	const TimerCompare* channel = compareFromIOPin(motor->pwm);
	const Timer* timer = compareGetTimer(channel);
	uint16_t top = timerGetTOP(timer);

	// New compare threshold
	uint16_t delay=0;

	if( speed > 0 ){
		delay = interpolateU(speed, 0, DRIVE_SPEED_MAX, 0 , top);

		if(motor->direction2==null){
			// one wire so delay = top - delay
			delay = top - delay;
		}

		// Set direction1 high, direction2 low (if there is one)
		pin_make_output(motor->direction1,TRUE);
		pin_make_output(motor->direction2,FALSE);
	}else if(speed < 0){
		delay = interpolateU(speed, 0, DRIVE_SPEED_MIN,  0 , top);

		// Set direction1 low, direction2 high (if there is one)
		pin_make_output(motor->direction1,FALSE);
		pin_make_output(motor->direction2,TRUE);
	}else{
		// brake
		if(motor->direction2){
			// There are two direction pins - so set both to same value
			pin_make_output(motor->direction1,FALSE);
			pin_make_output(motor->direction2,FALSE);
			delay = top; // full speed brake
		}else{
			// Only has one direction pin
			// Set direction1 low
			pin_make_output(motor->direction1,FALSE);
			// PWM delay = 0 so pwm = low
			// ie both low = brake
		}
	}

	// Change the duty cycle
	compareSetThreshold(channel,delay);
}
Пример #9
0
PERCENTAGE pwmGetDutyCycle(const IOPin* pin){
	PERCENTAGE rtn = 0;

	const TimerCompare* channel = compareFromIOPin(pin);
	if(channel){
		const Timer* timer = compareGetTimer(channel);
		uint32_t top = timerGetTOP(timer);
		uint32_t duty = compareGetThreshold(channel);
		// top => 100
		// duty => x
		// x = (100 * duty) / top
		duty *= 100;
		duty /= top;
		rtn = duty;
	}

	return rtn;
}
Пример #10
0
void speechInit(const IOPin* pin){
	pwmPin = pin;
	timeFactor = roundup(cpu_speed,550000UL);

	// Use 20kHz PWM on the pin
	pwmInitHertz(pin,20000,50,null);

	// Find the compare values for volume levels 0-15
	channel = compareFromIOPin(pin);
	if(channel){
		const Timer* timer = compareGetTimer(channel);
		uint32_t top = timerGetTOP(timer)-1;

		for(int8_t v =0; v<16; v++){
			uint16_t delay = interpolateU(v, 0,15, 0,top);
			Volume[v] = delay;
		}
	}
}
Пример #11
0
// Set the duty cycle
void pwmSetDutyCycle(const IOPin* pin, PERCENTAGE duty){
	const TimerCompare* channel = compareFromIOPin(pin);
	if(channel){
		const Timer* timer = compareGetTimer(channel);
		uint32_t top = timerGetTOP(timer);

		// Limit the duty cycle
		if(duty>100)
			duty=100;

		// 100 => top
		// duty => x
		// x = (top * duty) / 100
//		top *= duty;
//		top /= 100;
//		uint16_t delay =  top;
		uint16_t delay = interpolateU(duty, 0,100, 0,top);

		// Change the duty cycle
		compareSetThreshold(channel,delay);
	}
}
Пример #12
0
// Call back - for when the speed has been set
static void setSpeed(__ACTUATOR *actuator, DRIVE_SPEED speed){
	MOTOR* motor = (MOTOR*)actuator;
	const TimerCompare* channel = compareFromIOPin(motor->pwm);
	const Timer* timer = compareGetTimer(channel);
	uint16_t top = timerGetTOP(timer);

	// New compare threshold
	uint16_t delay=0;

	if( speed > 0 ){
		delay = interpolateU(speed, 0, DRIVE_SPEED_MAX, 0 , top);

		// Set direction1 high, direction2 low
		pin_make_output(motor->direction1,TRUE);
		pin_make_output(motor->direction2,FALSE);
	}else if(speed < 0){
		delay = interpolateU(speed, 0, DRIVE_SPEED_MIN,  0 , top);

		// Set direction1 low, direction2 high low
		pin_make_output(motor->direction1,FALSE);
		pin_make_output(motor->direction2,TRUE);
	}else{
		// brake

		if(motor->direction2){
			// There are two direction pins - so set both to same value
			pin_make_output(motor->direction1,FALSE);
			pin_make_output(motor->direction2,FALSE);
		}else{
			// Only has one direction pin
			// Set direction1 to an input with no pullup ie disconnect
			pin_make_input(motor->direction1,FALSE);
		}
	}

	// Change the duty cycle
	compareSetThreshold(channel,delay);
}