예제 #1
0
static void
pwm_channel_init(unsigned channel)
{
	unsigned timer = pwm_channels[channel].timer_index;

	/* configure the GPIO first */
	stm32_configgpio(pwm_channels[channel].gpio);

	/* configure the channel */
	switch (pwm_channels[channel].timer_channel) {
	case 1:
		rCCMR1(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR1_OC1M_SHIFT) | GTIM_CCMR1_OC1PE;
		rCCR1(timer) = pwm_channels[channel].default_value;
		rCCER(timer) |= GTIM_CCER_CC1E;
		break;

	case 2:
		rCCMR1(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR1_OC2M_SHIFT) | GTIM_CCMR1_OC2PE;
		rCCR2(timer) = pwm_channels[channel].default_value;
		rCCER(timer) |= GTIM_CCER_CC2E;
		break;

	case 3:
		rCCMR2(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR2_OC3M_SHIFT) | GTIM_CCMR2_OC3PE;
		rCCR3(timer) = pwm_channels[channel].default_value;
		rCCER(timer) |= GTIM_CCER_CC3E;
		break;

	case 4:
		rCCMR2(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR2_OC4M_SHIFT) | GTIM_CCMR2_OC4PE;
		rCCR4(timer) = pwm_channels[channel].default_value;
		rCCER(timer) |= GTIM_CCER_CC4E;
		break;
	}
}
예제 #2
0
servo_position_t
up_pwm_servo_get(unsigned channel)
{
	if (channel >= PWM_SERVO_MAX_CHANNELS)
		return 0;

	unsigned timer = pwm_channels[channel].timer_index;
	servo_position_t value = 0;

	/* test timer for validity */
	if ((pwm_timers[timer].base == 0) ||
	    (pwm_channels[channel].timer_channel == 0))
		return 0;

	/* configure the channel */
	switch (pwm_channels[channel].timer_channel) {
	case 1:
		value = rCCR1(timer);
		break;

	case 2:
		value = rCCR2(timer);
		break;

	case 3:
		value = rCCR3(timer);
		break;

	case 4:
		value = rCCR4(timer);
		break;
	}

	return value + 1;
}
예제 #3
0
static servo_position_t
pwm_channel_get(unsigned channel)
{
	if (channel >= PWM_SERVO_MAX_CHANNELS) {
		lldbg("pwm_channel_get: bogus channel %u\n", channel);
		return 0;
	}

	unsigned timer = cfg->channels[channel].timer_index;
	servo_position_t value = 0;

	/* test timer for validity */
	if ((cfg->timers[timer].base == 0) ||
	    (cfg->channels[channel].gpio == 0))
		return 0;

	/* configure the channel */
	switch (cfg->channels[channel].timer_channel) {
		case 1:
			value = rCCR1(timer);
			break;
		case 2:
			value = rCCR2(timer);
			break;
		case 3:
			value = rCCR3(timer);
			break;
		case 4:
			value = rCCR4(timer);
			break;
	}
	return value;
}
예제 #4
0
static void
pwm_channel_init(unsigned channel)
{
	unsigned timer = cfg->channels[channel].timer_index;

	/* configure the GPIO first */
	stm32_configgpio(cfg->channels[channel].gpio);

	/* configure the channel */
	switch (cfg->channels[channel].timer_channel) {
		case 1:
			rCCMR1(timer) |= (6 << 4);
			rCCR1(timer) = cfg->channels[channel].default_value;
			rCCER(timer) |= (1 << 0);
			break;
		case 2:
			rCCMR1(timer) |= (6 << 12);
			rCCR2(timer) = cfg->channels[channel].default_value;
			rCCER(timer) |= (1 << 4);
			break;
		case 3:
			rCCMR2(timer) |= (6 << 4);
			rCCR3(timer) = cfg->channels[channel].default_value;
			rCCER(timer) |= (1 << 8);
			break;
		case 4:
			rCCMR2(timer) |= (6 << 12);
			rCCR4(timer) = cfg->channels[channel].default_value;
			rCCER(timer) |= (1 << 12);
			break;
	}
}
예제 #5
0
int
led_pwm_servo_set(unsigned channel, uint8_t  cvalue)
{
	if (channel >= arraySize(led_pwm_channels)) {
		return -1;
	}

	unsigned timer = led_pwm_channels[channel].timer_index;

	/* test timer for validity */
	if ((led_pwm_timers[timer].base == 0) ||
	    (led_pwm_channels[channel].gpio_out == 0)) {
		return -1;
	}

	unsigned period = led_pwm_timer_get_period(timer);

#if defined(BOARD_LED_PWM_DRIVE_ACTIVE_LOW)
	unsigned value = period - (unsigned)cvalue * period / 255;
#else
	unsigned value = (unsigned)cvalue * period / 255;
#endif

	/* configure the channel */
	if (value > 0) {
		value--;
	}


	switch (led_pwm_channels[channel].timer_channel) {
	case 1:
		rCCR1(timer) = value;
		break;

	case 2:
		rCCR2(timer) = value;
		break;

	case 3:
		rCCR3(timer) = value;
		break;

	case 4:
		rCCR4(timer) = value;
		break;

	default:
		return -1;
	}

	return 0;
}
예제 #6
0
static void
pwm_channel_init(unsigned channel)
{
	unsigned timer = pwm_channels[channel].timer_index;

	/* configure the GPIO first */
	stm32_configgpio(pwm_channels[channel].gpio);

	/* configure the channel */
	switch (pwm_channels[channel].timer_channel) {
	case 1:
		rCCMR1(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR1_OC1M_SHIFT) | GTIM_CCMR1_OC1PE;
		rCCR1(timer) = pwm_channels[channel].default_value;
		#if defined(CONFIG_ARCH_BOARD_TMRFC_V1)
        if(channel == 12)
            rCCER(timer) |= GTIM_CCER_CC1NE; /* complementary output enable */
        else
		#endif
		rCCER(timer) |= GTIM_CCER_CC1E;
		break;

	case 2:
		rCCMR1(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR1_OC2M_SHIFT) | GTIM_CCMR1_OC2PE;
		rCCR2(timer) = pwm_channels[channel].default_value;
		#if defined(CONFIG_ARCH_BOARD_TMRFC_V1)
        if(channel == 6)
            rCCER(timer) |= GTIM_CCER_CC2NE;  /* complementary output enable */
        else
		#endif
		rCCER(timer) |= GTIM_CCER_CC2E;
		break;

	case 3:
		rCCMR2(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR2_OC3M_SHIFT) | GTIM_CCMR2_OC3PE;
		rCCR3(timer) = pwm_channels[channel].default_value;
		#if defined(CONFIG_ARCH_BOARD_TMRFC_V1)
        if(channel == 7)
            rCCER(timer) |= GTIM_CCER_CC3NE;  /* complementary output enable */
        else
		#endif
		rCCER(timer) |= GTIM_CCER_CC3E;
		break;

	case 4:
		rCCMR2(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR2_OC4M_SHIFT) | GTIM_CCMR2_OC4PE;
		rCCR4(timer) = pwm_channels[channel].default_value;
		rCCER(timer) |= GTIM_CCER_CC4E;
		break;
	}
}
예제 #7
0
static void led_pwm_timer_init_timer(unsigned timer)
{
	irqstate_t flags = px4_enter_critical_section();

	/* enable the timer clock before we try to talk to it */

	modifyreg32(led_pwm_timers[timer].clock_register, 0, led_pwm_timers[timer].clock_bit);

	/* disable and configure the timer */
	rCR1(timer) = 0;
	rCR2(timer) = 0;
	rSMCR(timer) = 0;
	rDIER(timer) = 0;
	rCCER(timer) = 0;
	rCCMR1(timer) = 0;
	rCCMR2(timer) = 0;
	rCCR1(timer) = 0;
	rCCR2(timer) = 0;
	rCCR3(timer) = 0;
	rCCR4(timer) = 0;
	rCCER(timer) = 0;
	rDCR(timer) = 0;

	if ((led_pwm_timers[timer].base == STM32_TIM1_BASE) || (led_pwm_timers[timer].base == STM32_TIM8_BASE)) {

		/* master output enable = on */

		rBDTR(timer) = ATIM_BDTR_MOE;
	}

	/* If the timer clock source provided as clock_freq is the STM32_APBx_TIMx_CLKIN
	 * then configure the timer to free-run at 1MHz.
	 * Otherwise, other frequencies are attainable by adjusting .clock_freq accordingly.
	 */

	rPSC(timer) = (led_pwm_timers[timer].clock_freq / 1000000) - 1;

	/* configure the timer to update at the desired rate */

	rARR(timer) = (1000000 / LED_PWM_RATE) - 1;

	/* generate an update event; reloads the counter and all registers */
	rEGR(timer) = GTIM_EGR_UG;

	px4_leave_critical_section(flags);

}
예제 #8
0
uint16_t
input_pwm_decode(uint32_t status, uint8_t timer, uint8_t timer_channel)
{
	uint16_t count;

	// for now we don't care about CCxOF, state machine will take care of it
	switch (timer_channel) {

	case 1:
		count = rCCR1(timer);
		break;
		/* did we miss an edge? */
		if (status & GTIM_SR_CC1OF)
			goto error;

	case 2:
		count = rCCR2(timer);
		break;
		/* did we miss an edge? */
		if (status & GTIM_SR_CC2OF)
			goto error;

	case 3:
		count = rCCR3(timer);
		break;
		/* did we miss an edge? */
		if (status & GTIM_SR_CC3OF)
			goto error;

	case 4:
		count = rCCR4(timer);
		break;
		/* did we miss an edge? */
		if (status & GTIM_SR_CC4OF)
			goto error;

	}
	return count;
        /* the state machine is corrupted; reset it */
error:
        /* we don't like the state of the decoder, reset it and try again */
	printf("overwrite error\n");
	return 0;
}
예제 #9
0
int
up_pwm_servo_set(unsigned channel, servo_position_t value)
{
	if (channel >= PWM_SERVO_MAX_CHANNELS)
		return -1;

	unsigned timer = pwm_channels[channel].timer_index;

	/* test timer for validity */
	if ((pwm_timers[timer].base == 0) ||
	    (pwm_channels[channel].gpio == 0))
		return -1;

	/* configure the channel */
	if (value > 0)
		value--;

	switch (pwm_channels[channel].timer_channel) {
	case 1:
		rCCR1(timer) = value;
		break;

	case 2:
		rCCR2(timer) = value;
		break;

	case 3:
		rCCR3(timer) = value;
		break;

	case 4:
		rCCR4(timer) = value;
		break;

	case 5:
		rCCR2(timer) = value;
		break;

	default:
		return -1;
	}

	return 0;
}
예제 #10
0
static void
input_pwm_channel_init(unsigned channel)
{
	unsigned timer = input_pwm_channels[channel].timer_index;

	/* configure the GPIO first */
	stm32_configgpio(input_pwm_channels[channel].gpio);

	/* configure the channel */
	switch (input_pwm_channels[channel].timer_channel) {
	case 1:
		rDIER(timer) |= GTIM_DIER_CC1IE;
		rCCMR1(timer) |= (GTIM_CCMR_CCS_CCIN1 << GTIM_CCMR1_CC1S_SHIFT);
		rCCR1(timer) = 1000;
		rCCER(timer) |= GTIM_CCER_CC1E | GTIM_CCER_CC1P | GTIM_CCER_CC1NP;
		break;

	case 2:
		rDIER(timer) |= GTIM_DIER_CC2IE;
		rCCMR1(timer) |= (GTIM_CCMR_CCS_CCIN1 << GTIM_CCMR1_CC2S_SHIFT);
		rCCR2(timer) = 1000;
		rCCER(timer) |= GTIM_CCER_CC2E | GTIM_CCER_CC2P | GTIM_CCER_CC2NP;
		break;

	case 3:
		rDIER(timer) |= GTIM_DIER_CC3IE;
		rCCMR2(timer) |= (GTIM_CCMR_CCS_CCIN1 << GTIM_CCMR2_CC3S_SHIFT);
		rCCR3(timer) = 1000;
		rCCER(timer) |= GTIM_CCER_CC3E | GTIM_CCER_CC3P | GTIM_CCER_CC3NP;
		break;

	case 4:
		rDIER(timer) |= GTIM_DIER_CC4IE;
		rCCMR2(timer) |= (GTIM_CCMR_CCS_CCIN1 << GTIM_CCMR2_CC4S_SHIFT);
		rCCR4(timer) = 1000;
		rCCER(timer) |= GTIM_CCER_CC4E | GTIM_CCER_CC4P | GTIM_CCER_CC4NP;
		break;
	}
}
예제 #11
0
unsigned
led_pwm_servo_get(unsigned channel)
{
	if (channel >= 3) {
		return 0;
	}

	unsigned timer = led_pwm_channels[channel].timer_index;
	servo_position_t value = 0;

	/* test timer for validity */
	if ((led_pwm_timers[timer].base == 0) ||
	    (led_pwm_channels[channel].timer_channel == 0)) {
		return 0;
	}

	/* configure the channel */
	switch (led_pwm_channels[channel].timer_channel) {
	case 1:
		value = rCCR1(timer);
		break;

	case 2:
		value = rCCR2(timer);
		break;

	case 3:
		value = rCCR3(timer);
		break;

	case 4:
		value = rCCR4(timer);
		break;
	}

	unsigned period = led_pwm_timer_get_period(timer);
	return ((value + 1) * 255 / period);
}
예제 #12
0
static int pwm_input_timer_isr(void)
{
	uint16_t count = 0;

	for (unsigned i = 0; i < PWM_INPUT_MAX_TIMERS; i++) {
		status = rSR(i);
		 //ack the interrupts we just read
		rSR(i) = ~status;

		if (status & (GTIM_SR_CC1IF | GTIM_SR_CC1OF))
		{
			count = rCCR1(i);
			//printf("Captured on T%uC1  %u\n", i, count);
			for (unsigned j = 0; j < PWM_INPUT_MAX_CHANNELS; j++) {
				if ((pwm_input_channels[j].timer_channel == 1) && (pwm_input_channels[j].timer_index == i)) {

					rc[j] = count - rc_last[j];
					rc_last[j] = count;

					if (rc[j] <= MAX_PULSEWIDTH) {
						ppm_buffer[j]=rc[j];
						ppm_last_valid_decode = hrt_absolute_time();
					}

					//printf("RC%u: %u\n", j, rc[j]);
				}
			}
		}
		if (status & (GTIM_SR_CC2IF | GTIM_SR_CC2OF))
		{
			count = rCCR2(i);
			//printf("Captured on T%uC2  %u\n", i, count);
			for (unsigned j = 0; j < PWM_INPUT_MAX_CHANNELS; j++) {
				if ((pwm_input_channels[j].timer_channel == 2) && (pwm_input_channels[j].timer_index == i)) {

					rc[j] = count - rc_last[j];
					rc_last[j] = count;

					if (rc[j] <= MAX_PULSEWIDTH) {
						ppm_buffer[j]=rc[j];
						ppm_last_valid_decode = hrt_absolute_time();
					}

					//printf("RC%u: %u\n", j, rc[j]);
				}
			}
		}
		if (status & (GTIM_SR_CC3IF | GTIM_SR_CC3OF))
		{
			count = rCCR3(i);
			//printf("Captured on T%uC3  %u\n", i, count);
			for (unsigned j = 0; j < PWM_INPUT_MAX_CHANNELS; j++) {
				if ((pwm_input_channels[j].timer_channel == 3) && (pwm_input_channels[j].timer_index == i)) {

					rc[j] = count - rc_last[j];
					rc_last[j] = count;

					if (rc[j] <= MAX_PULSEWIDTH) {
						ppm_buffer[j]=rc[j];
						ppm_last_valid_decode = hrt_absolute_time();
					}

					//printf("RC%u: %u\n", j, rc[j]);
				}
			}
		}
		if (status & (GTIM_SR_CC4IF | GTIM_SR_CC4OF))
		{
			count = rCCR4(i);
			//printf("Captured on T%uC3  %u\n", i, count);
			for (unsigned j = 0; j < PWM_INPUT_MAX_CHANNELS; j++) {
				if ((pwm_input_channels[j].timer_channel == 4) && (pwm_input_channels[j].timer_index == i)) {

					rc[j] = count - rc_last[j];
					rc_last[j] = count;

					if (rc[j] <= MAX_PULSEWIDTH) {
						ppm_buffer[j]=rc[j];
						ppm_last_valid_decode = hrt_absolute_time();
					}

					//printf("RC%u: %u\n", j, rc[j]);
				}
			}
		}
	}

	return;
  	
}
예제 #13
0
uint16_t
input_pwm_decode(uint32_t status, uint8_t timer, uint8_t timer_channel)
{
	uint16_t count;

	// for now we don't care about CCxOF, state machine will take care of it 
	switch (timer_channel) {
		
	case 1:
		count = rCCR1(timer);
		break;
		/* did we miss an edge? */
		if (status & GTIM_SR_CC1OF)
			goto error;

	case 2:
		count = rCCR2(timer);
		break;
		/* did we miss an edge? */
		if (status & GTIM_SR_CC2OF)
			goto error;

	case 3:
		count = rCCR3(timer);
		break;
		/* did we miss an edge? */
		if (status & GTIM_SR_CC3OF)
			goto error;

	case 4:
		count = rCCR4(timer);
		break;
		/* did we miss an edge? */
		if (status & GTIM_SR_CC4OF)
			goto error;

	}
	//printf("count = %d\n", count);
	return count;

        /* how long since the last edge? - this handles counter wrapping implicitely. */
        /*width = count - pwm.last_edge;

        switch (pwm.phase) {

        case ARM:
*/
                /* frame length is everything including the start gap */
/*              pwm.phase = ACTIVE;
                break;

        case ACTIVE:
  */              /* if the mark-mark timing is out of bounds, abandon the frame */
    /*            if ((width < PWM_MIN_CHANNEL_VALUE) || (width > PWM_MAX_CHANNEL_VALUE))
                {
//                        goto error;
                }
                else
                {
*/                /* if we have room to store the value, do so */
/*                //if (ppm.next_channel < RC_INPUT_MAX_CHANNELS)
                        _temp_rc_buffer[0] = width;
                        _decoded_channels = 1;

                pwm.phase = ARM;

                printf("PWM captured = %d\n", width);
                }
                break;

        }

        pwm.last_edge = count;

        return;
*/
                //InputPWM::me->rc_decode(status);
        /* the state machine is corrupted; reset it */
error:
        /* we don't like the state of the decoder, reset it and try again */
	printf("overwrite error\n");
	return 0;
        //pwm.phase = ARM;
        //_decoded_channels = 0;

}