static void reset_hsync_timers()
{
    // Stop both timers
    TIM_Cmd(dev_cfg->pixel_timer.timer, DISABLE);

    uint32_t tim_id;
    const struct pios_tim_channel *channels = &dev_cfg->hsync_capture;

    // BUG: This is nuts this line is needed.  It simply results in allocating
    // all the memory but somehow leaving it out breaks the timer functionality.
    // I do not see how these can be related
    if (failcount == 0) {
        if (PIOS_TIM_InitChannels(&tim_id, channels, 1, &px_callback, 0) < 0) {
            failcount++;
        }
    }

    dev_cfg->pixel_timer.timer->CNT = 0xFFFF - 100; // dc;

    // Listen to Channel1 (HSYNC)
    switch (dev_cfg->hsync_capture.timer_chan) {
    case TIM_Channel_1:
        TIM_SelectInputTrigger(dev_cfg->pixel_timer.timer, TIM_TS_TI1FP1);
        break;
    case TIM_Channel_2:
        TIM_SelectInputTrigger(dev_cfg->pixel_timer.timer, TIM_TS_TI2FP2);
        break;
    default:
        PIOS_Assert(0);
    }
    TIM_SelectSlaveMode(dev_cfg->pixel_timer.timer, TIM_SlaveMode_Trigger);
}
示例#2
0
/**
* Initialise Servos
*/
int32_t PIOS_Brushless_Init(const struct pios_brushless_cfg * cfg)
{
	uintptr_t tim_id;
	if (PIOS_TIM_InitChannels(&tim_id, cfg->channels, cfg->num_channels, NULL, 0)) {
		return -1;
	}

	/* Store away the requested configuration */
	brushless_cfg = cfg;

	/* Configure the channels to be in output compare mode */
	for (uint8_t i = 0; i < cfg->num_channels; i++) {
		const struct pios_tim_channel * chan = &cfg->channels[i];

		/* Set up for output compare function */
		switch(chan->timer_chan) {
			case TIM_Channel_1:
				TIM_OC1Init(chan->timer, (TIM_OCInitTypeDef*)&cfg->tim_oc_init);
				TIM_OC1PreloadConfig(chan->timer, TIM_OCPreload_Enable);
				break;
			case TIM_Channel_2:
				TIM_OC2Init(chan->timer, (TIM_OCInitTypeDef*)&cfg->tim_oc_init);
				TIM_OC2PreloadConfig(chan->timer, TIM_OCPreload_Enable);
				break;
			case TIM_Channel_3:
				TIM_OC3Init(chan->timer, (TIM_OCInitTypeDef*)&cfg->tim_oc_init);
				TIM_OC3PreloadConfig(chan->timer, TIM_OCPreload_Enable);
				break;
			case TIM_Channel_4:
				TIM_OC4Init(chan->timer, (TIM_OCInitTypeDef*)&cfg->tim_oc_init);
				TIM_OC4PreloadConfig(chan->timer, TIM_OCPreload_Enable);
				break;
		}

		TIM_ARRPreloadConfig(chan->timer, ENABLE);
		TIM_CtrlPWMOutputs(chan->timer, ENABLE);
		TIM_Cmd(chan->timer, ENABLE);
	}

	for (uint8_t i = 0 ; i < NUM_BGC_CHANNELS; i++) {
		// Enable the available enable lines
		if (cfg->enables[i].gpio) {
			GPIO_Init(cfg->enables[i].gpio, (GPIO_InitTypeDef *) &cfg->enables[i].init);
			GPIO_SetBits(cfg->enables[i].gpio, cfg->enables[i].init.GPIO_Pin);
		}
	}

	// Start main task
	taskHandle = PIOS_Thread_Create(
			PIOS_BRUSHLESS_Task, "pios_brushless", STACK_SIZE_BYTES, NULL, TASK_PRIORITY);

	return 0;
}
static void configure_hsync_timers()
{
    // Stop both timers
    TIM_Cmd(dev_cfg->pixel_timer.timer, DISABLE);

    // This is overkill but used for consistency.  No interrupts used for pixel clock
    // but this function calls the GPIO_Remap
    uint32_t tim_id;
    const struct pios_tim_channel *channels;

    // Init the channel to output the pixel clock
    channels = &dev_cfg->pixel_timer;
    PIOS_TIM_InitChannels(&tim_id, channels, 1, &px_callback, 0);

    // Init the channel to capture the pulse
    channels = &dev_cfg->hsync_capture;
    PIOS_TIM_InitChannels(&tim_id, channels, 1, &px_callback, 0);

    // Configure the input capture channel
    TIM_ICInitTypeDef TIM_ICInitStructure;
    switch (dev_cfg->hsync_capture.timer_chan) {
    case TIM_Channel_1:
        TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
        break;
    case TIM_Channel_2:
        TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
        break;
    default:
        PIOS_Assert(0);
    }
    TIM_ICInitStructure.TIM_ICPolarity  = TIM_ICPolarity_Falling;
    // TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStructure.TIM_ICFilter    = 0;
    TIM_ICInit(dev_cfg->pixel_timer.timer, &TIM_ICInitStructure);

    // Set up the channel to output the pixel clock
    switch (dev_cfg->pixel_timer.timer_chan) {
    case TIM_Channel_1:
        TIM_OC1Init(dev_cfg->pixel_timer.timer, &dev_cfg->tim_oc_init);
        TIM_OC1PreloadConfig(dev_cfg->pixel_timer.timer, TIM_OCPreload_Enable);
        TIM_SetCompare1(dev_cfg->pixel_timer.timer, dc);
        break;
    case TIM_Channel_2:
        TIM_OC2Init(dev_cfg->pixel_timer.timer, &dev_cfg->tim_oc_init);
        TIM_OC2PreloadConfig(dev_cfg->pixel_timer.timer, TIM_OCPreload_Enable);
        TIM_SetCompare2(dev_cfg->pixel_timer.timer, dc);
        break;
    case TIM_Channel_3:
        TIM_OC3Init(dev_cfg->pixel_timer.timer, &dev_cfg->tim_oc_init);
        TIM_OC3PreloadConfig(dev_cfg->pixel_timer.timer, TIM_OCPreload_Enable);
        TIM_SetCompare3(dev_cfg->pixel_timer.timer, dc);
        break;
    case TIM_Channel_4:
        TIM_OC4Init(dev_cfg->pixel_timer.timer, &dev_cfg->tim_oc_init);
        TIM_OC4PreloadConfig(dev_cfg->pixel_timer.timer, TIM_OCPreload_Enable);
        TIM_SetCompare4(dev_cfg->pixel_timer.timer, dc);
        break;
    }
    TIM_ARRPreloadConfig(dev_cfg->pixel_timer.timer, ENABLE);
    TIM_CtrlPWMOutputs(dev_cfg->pixel_timer.timer, ENABLE);

    // This shouldn't be needed as it should come from the config struture.  Something
    // is clobbering that
    TIM_PrescalerConfig(dev_cfg->pixel_timer.timer, 0, TIM_PSCReloadMode_Immediate);
    TIM_SetAutoreload(dev_cfg->pixel_timer.timer, period);
}
示例#4
0
extern int32_t PIOS_PPM_Init(uint32_t * ppm_id, const struct pios_ppm_cfg * cfg)
{
	PIOS_DEBUG_Assert(ppm_id);
	PIOS_DEBUG_Assert(cfg);

	struct pios_ppm_dev * ppm_dev;

	ppm_dev = (struct pios_ppm_dev *) PIOS_PPM_alloc();
	if (!ppm_dev) goto out_fail;

	/* Bind the configuration to the device instance */
	ppm_dev->cfg = cfg;

	/* Set up the state variables */
	ppm_dev->PulseIndex = 0;
	ppm_dev->PreviousTime = 0;
	ppm_dev->CurrentTime = 0;
	ppm_dev->DeltaTime = 0;
	ppm_dev->LargeCounter = 0;
	ppm_dev->NumChannels = -1;
	ppm_dev->NumChannelsPrevFrame = -1;
	ppm_dev->NumChannelCounter = 0;
	ppm_dev->Tracking = FALSE;
	ppm_dev->Fresh = FALSE;

	for (uint8_t i = 0; i < PIOS_PPM_IN_MAX_NUM_CHANNELS; i++) {
		/* Flush counter variables */
		ppm_dev->CaptureValue[i] = 0;
		ppm_dev->CaptureValueNewFrame[i] = 0;

	}

	uint32_t tim_id;
	if (PIOS_TIM_InitChannels(&tim_id, cfg->channels, cfg->num_channels, &tim_callbacks, (uint32_t)ppm_dev)) {
		return -1;
	}

	/* Configure the channels to be in capture/compare mode */
	for (uint8_t i = 0; i < cfg->num_channels; i++) {
		const struct pios_tim_channel * chan = &cfg->channels[i];

		/* Configure timer for input capture */
		TIM_ICInitTypeDef TIM_ICInitStructure = cfg->tim_ic_init;
		TIM_ICInitStructure.TIM_Channel = chan->timer_chan;
		TIM_ICInit(chan->timer, &TIM_ICInitStructure);

		/* Enable the Capture Compare Interrupt Request */
		switch (chan->timer_chan) {
		case TIM_Channel_1:
			TIM_ITConfig(chan->timer, TIM_IT_CC1 | TIM_IT_Update, ENABLE);
			break;
		case TIM_Channel_2:
			TIM_ITConfig(chan->timer, TIM_IT_CC2 | TIM_IT_Update, ENABLE);
			break;
		case TIM_Channel_3:
			TIM_ITConfig(chan->timer, TIM_IT_CC3 | TIM_IT_Update, ENABLE);
			break;
		case TIM_Channel_4:
			TIM_ITConfig(chan->timer, TIM_IT_CC4 | TIM_IT_Update, ENABLE);
			break;
		}
	}

	/* Setup local variable which stays in this scope */
	/* Doing this here and using a local variable saves doing it in the ISR */
	TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
	TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	TIM_ICInitStructure.TIM_ICFilter = 0x0;

	if (!PIOS_RTC_RegisterTickCallback(PIOS_PPM_Supervisor, (uint32_t)ppm_dev)) {
		PIOS_DEBUG_Assert(0);
	}

	*ppm_id = (uint32_t)ppm_dev;

	return(0);

out_fail:
	return(-1);
}
示例#5
0
/**
* Initialises all the pins
*/
int32_t PIOS_PWM_Init(uint32_t * pwm_id, const struct pios_pwm_cfg * cfg)
{
	PIOS_DEBUG_Assert(pwm_id);
	PIOS_DEBUG_Assert(cfg);

	struct pios_pwm_dev * pwm_dev;

	pwm_dev = (struct pios_pwm_dev *) PIOS_PWM_alloc();
	if (!pwm_dev) goto out_fail;

	/* Bind the configuration to the device instance */
	pwm_dev->cfg = cfg;

	for (uint8_t i = 0; i < PIOS_PWM_NUM_INPUTS; i++) {
		/* Flush counter variables */
		pwm_dev->CaptureState[i] = 0;
		pwm_dev->RiseValue[i] = 0;
		pwm_dev->FallValue[i] = 0;
		pwm_dev->CaptureValue[i] = PIOS_RCVR_TIMEOUT;
	}

	uint32_t tim_id;
	if (PIOS_TIM_InitChannels(&tim_id, cfg->channels, cfg->num_channels, &tim_callbacks, (uint32_t)pwm_dev)) {
		return -1;
	}

	/* Configure the channels to be in capture/compare mode */
	for (uint8_t i = 0; i < cfg->num_channels; i++) {
		const struct pios_tim_channel * chan = &cfg->channels[i];

		/* Configure timer for input capture */
		TIM_ICInitTypeDef TIM_ICInitStructure = cfg->tim_ic_init;
		TIM_ICInitStructure.TIM_Channel = chan->timer_chan;
		TIM_ICInit(chan->timer, &TIM_ICInitStructure);
		
		/* Enable the Capture Compare Interrupt Request */
		switch (chan->timer_chan) {
		case TIM_Channel_1:
			TIM_ITConfig(chan->timer, TIM_IT_CC1, ENABLE);
			break;
		case TIM_Channel_2:
			TIM_ITConfig(chan->timer, TIM_IT_CC2, ENABLE);
			break;
		case TIM_Channel_3:
			TIM_ITConfig(chan->timer, TIM_IT_CC3, ENABLE);
			break;
		case TIM_Channel_4:
			TIM_ITConfig(chan->timer, TIM_IT_CC4, ENABLE);
			break;
		}

		// Need the update event for that timer to detect timeouts
		TIM_ITConfig(chan->timer, TIM_IT_Update, ENABLE);

	}

	*pwm_id = (uint32_t) pwm_dev;

	return (0);

out_fail:
	return (-1);
}