示例#1
0
/*
 * Initialise the timer we are going to use.
 */
void PWMIN::_timer_init(void)
{
	/* run with interrupts disabled in case the timer is already
	 * setup. We don't want it firing while we are doing the setup */
	irqstate_t flags = px4_enter_critical_section();

	/* configure input pin */
	px4_arch_configgpio(GPIO_PWM_IN);

	// XXX refactor this out of this driver
	/* configure reset pin */
	px4_arch_configgpio(GPIO_VDD_RANGEFINDER_EN);

	/* claim our interrupt vector */
	irq_attach(PWMIN_TIMER_VECTOR, pwmin_tim_isr, NULL);

	/* Clear no bits, set timer enable bit.*/
	modifyreg32(PWMIN_TIMER_POWER_REG, 0, PWMIN_TIMER_POWER_BIT);

	/* disable and configure the timer */
	rCR1 = 0;
	rCR2 = 0;
	rSMCR = 0;
	rDIER = DIER_PWMIN_A;
	rCCER = 0;		/* unlock CCMR* registers */
	rCCMR1 = CCMR1_PWMIN;
	rCCMR2 = CCMR2_PWMIN;
	rSMCR = SMCR_PWMIN_1;	/* Set up mode */
	rSMCR = SMCR_PWMIN_2;	/* Enable slave mode controller */
	rCCER = CCER_PWMIN;
	rDCR = 0;

	/* for simplicity scale by the clock in MHz. This gives us
	 * readings in microseconds which is typically what is needed
	 * for a PWM input driver */
	uint32_t prescaler = PWMIN_TIMER_CLOCK / 1000000UL;

	/*
	 * define the clock speed. We want the highest possible clock
	 * speed that avoids overflows.
	 */
	rPSC = prescaler - 1;

	/* run the full span of the counter. All timers can handle
	 * uint16 */
	rARR = UINT16_MAX;

	/* generate an update event; reloads the counter, all registers */
	rEGR = GTIM_EGR_UG;

	/* enable the timer */
	rCR1 = GTIM_CR1_CEN;

	/* enable interrupts */
	up_enable_irq(PWMIN_TIMER_VECTOR);

	px4_leave_critical_section(flags);

	_timer_started = true;
}
示例#2
0
__EXPORT void stm32_spiinitialize(void)
{
#ifdef CONFIG_STM32_SPI1
	px4_arch_configgpio(GPIO_SPI_CS_MPU9250);
	px4_arch_configgpio(GPIO_SPI_CS_HMC5983);
	px4_arch_configgpio(GPIO_SPI_CS_MS5611);
	px4_arch_configgpio(GPIO_SPI_CS_ICM_20608_G);

	/* De-activate all peripherals,
	 * required for some peripheral
	 * state machines
	 */
	px4_arch_gpiowrite(GPIO_SPI_CS_MPU9250, 1);
	px4_arch_gpiowrite(GPIO_SPI_CS_HMC5983, 1);
	px4_arch_gpiowrite(GPIO_SPI_CS_MS5611, 1);
	px4_arch_gpiowrite(GPIO_SPI_CS_ICM_20608_G, 1);

	px4_arch_configgpio(GPIO_DRDY_MPU9250);
	px4_arch_configgpio(GPIO_DRDY_HMC5983);
	px4_arch_configgpio(GPIO_DRDY_ICM_20608_G);
#endif

#ifdef CONFIG_STM32_SPI2
	px4_arch_configgpio(GPIO_SPI_CS_FRAM);
	px4_arch_gpiowrite(GPIO_SPI_CS_FRAM, 1);
#endif

}
示例#3
0
int
ToneAlarm::init()
{
	int ret;

	ret = CDev::init();

	if (ret != OK) {
		return ret;
	}

	/* configure the GPIO to the idle state */
	px4_arch_configgpio(GPIO_TONE_ALARM_IDLE);

#ifdef GPIO_TONE_ALARM_NEG

	px4_arch_configgpio(GPIO_TONE_ALARM_NEG);
#endif

	/* clock/power on our timer */
	modifyreg32(TONE_ALARM_CLOCK_POWER_REG, 0, TONE_ALARM_CLOCK_ENABLE);

	/* initialise the timer */
	rCR1 = 0;
	rCR2 = 0;
	rSMCR = 0;
	rDIER = 0;
	rCCER &= TONE_CCER;		/* unlock CCMR* registers */
	rCCMR1 = TONE_CCMR1;
	rCCMR2 = TONE_CCMR2;
	rCCER = TONE_CCER;
	rDCR = 0;

#ifdef rBDTR // If using an advanced timer, you need to activate the output
	rBDTR = ATIM_BDTR_MOE; // enable the main output of the advanced timer
#endif

	/* toggle the CC output each time the count passes 1 */
	TONE_rCCR = 1;

	/* default the timer to a prescale value of 1; playing notes will change this */
	rPSC = 0;

	/* make sure the timer is running */
	rCR1 = GTIM_CR1_CEN;

	DEVICE_DEBUG("ready");
	return OK;
}
示例#4
0
static void
led_pwm_channel_init(unsigned channel)
{
	unsigned timer = led_pwm_channels[channel].timer_index;

	/* configure the GPIO first */

	px4_arch_configgpio(led_pwm_channels[channel].gpio_out);

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

	case 2:
		rCCMR1(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR1_OC2M_SHIFT) | GTIM_CCMR1_OC2PE;
		rCCER(timer) |= GTIM_CCER_CC2E;
		break;

	case 3:
		rCCMR2(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR2_OC3M_SHIFT) | GTIM_CCMR2_OC3PE;
		rCCER(timer) |= GTIM_CCER_CC3E;
		break;

	case 4:
		rCCMR2(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR2_OC4M_SHIFT) | GTIM_CCMR2_OC4PE;
		rCCER(timer) |= GTIM_CCER_CC4E;
		break;
	}
}
示例#5
0
void
ToneAlarm::start_note(unsigned note)
{
	// check if circuit breaker is enabled
	if (_cbrk == CBRK_UNINIT) {
		_cbrk = circuit_breaker_enabled("CBRK_BUZZER", CBRK_BUZZER_KEY);
	}

	if (_cbrk != CBRK_OFF) { return; }

	// compute the divisor
	unsigned divisor = note_to_divisor(note);

	// pick the lowest prescaler value that we can use
	// (note that the effective prescale value is 1 greater)
	unsigned prescale = divisor / 65536;

	// calculate the timer period for the selected prescaler value
	unsigned period = (divisor / (prescale + 1)) - 1;

	rPSC = prescale;	// load new prescaler
	rARR = period;		// load new toggle period
	rEGR = GTIM_EGR_UG;	// force a reload of the period
	rCCER |= TONE_CCER;	// enable the output

	// configure the GPIO to enable timer output
	px4_arch_configgpio(GPIO_TONE_ALARM);
}
示例#6
0
int
TEST_PPM::init()
{
	px4_arch_configgpio(TEST_PPM_PIN);
	start();
	return OK;
}
示例#7
0
文件: auav_init.c 项目: DC00/Firmware
__END_DECLS

/****************************************************************************
 * Protected Functions
 ****************************************************************************/
/****************************************************************************
 * Public Functions
 ****************************************************************************/
/************************************************************************************
 * Name: board_peripheral_reset
 *
 * Description:
 *
 ************************************************************************************/
__EXPORT void board_peripheral_reset(int ms)
{
	/* set the peripheral rails off */
	px4_arch_configgpio(GPIO_VDD_5V_PERIPH_EN);
	px4_arch_gpiowrite(GPIO_VDD_5V_PERIPH_EN, 1);

	/* wait for the peripheral rail to reach GND */
	usleep(ms * 1000);
	warnx("reset done, %d ms", ms);

	/* re-enable power */

	/* switch the peripheral rail back on */
	px4_arch_gpiowrite(GPIO_VDD_5V_PERIPH_EN, 0);
}
示例#8
0
void CameraInterfaceGPIO::setup()
{
	for (unsigned i = 0; i < arraySize(_pins); i++) {
		px4_arch_configgpio(_gpios[_pins[i]]);
		px4_arch_gpiowrite(_gpios[_pins[i]], !_polarity);
	}
}
示例#9
0
void ToneAlarmInterface::stop_note()
{
	// Stop the current note.
	rSC &= ~TPM_SC_CMOD_MASK;

	// Ensure the GPIO is not driving the speaker.
	px4_arch_configgpio(GPIO_TONE_ALARM_IDLE);
}
示例#10
0
__END_DECLS

__EXPORT void led_init()
{
	/* Configure LED1 GPIO for output */

	px4_arch_configgpio(GPIO_LED1);
}
示例#11
0
/**
 * Initialise the high-resolution timing module.
 */
void
hrt_init(void)
{
	sq_init(&callout_queue);
	hrt_tim_init();

#ifdef HRT_PPM_CHANNEL
	/* configure the PPM input pin */
	px4_arch_configgpio(GPIO_PPM_IN);
#endif
}
示例#12
0
void
ToneAlarm::stop_note()
{
	/* stop the current note */
	rCCER &= ~TONE_CCER;

	/*
	 * Make sure the GPIO is not driving the speaker.
	 */
	px4_arch_configgpio(GPIO_TONE_ALARM_IDLE);
}
示例#13
0
void ToneAlarmInterface::init()
{
#ifdef GPIO_TONE_ALARM_NEG
	px4_arch_configgpio(GPIO_TONE_ALARM_NEG);
#else
	// Configure the GPIO to the idle state.
	px4_arch_configgpio(GPIO_TONE_ALARM_IDLE);
#endif

	// Select a the clock source to the TPM.
	uint32_t regval = _REG(KINETIS_SIM_SOPT2);

	regval &= ~(SIM_SOPT2_TPMSRC_MASK);
	regval |= BOARD_TPM_CLKSRC;

	_REG(KINETIS_SIM_SOPT2) = regval;

	// Enabled System Clock Gating Control for TPM.
	regval = _REG(KINETIS_SIM_SCGC2);
	regval |= TONE_ALARM_SIM_SCGC2_TPM;
	_REG(KINETIS_SIM_SCGC2) = regval;

	// Disable and configure the timer.
	rSC       = TPM_SC_TOF;
	rCNT      = 0;
	rMOD      = TONE_ALARM_COUNTER_PERIOD - 1;
	rSTATUS   = (TPM_STATUS_TOF | STATUS);

	// Configure for output compare to toggle on over flow.
	rCNSC     = (TPM_CnSC_CHF | TPM_CnSC_MSA | TPM_CnSC_ELSA);

	rCOMBINE  = 0;
	rPOL      = 0;
	rFILTER   = 0;
	rQDCTRL   = 0;
	rCONF     = TPM_CONF_DBGMODE_CONT;

	rCNV      = 0;  // Toggle the CC output each time the count passes 0.
	rSC      |= (TPM_SC_CMOD_LPTPM_CLK | TONE_ALARM_TIMER_PRESCALE); // Enable the timer.
	rMOD      = 0;  // Default the timer to a modulo value of 1; playing notes will change this.
}
示例#14
0
void
GPS::cmd_reset()
{
#ifdef GPIO_GPS_NRESET
	PX4_WARN("Toggling GPS reset pin");
	px4_arch_configgpio(GPIO_GPS_NRESET);
	px4_arch_gpiowrite(GPIO_GPS_NRESET, 0);
	usleep(100);
	px4_arch_gpiowrite(GPIO_GPS_NRESET, 1);
	PX4_WARN("Toggled GPS reset pin");
#endif
}
示例#15
0
文件: auav_spi.c 项目: DC00/Firmware
__EXPORT void stm32_spiinitialize(void)
{
#ifdef CONFIG_STM32_SPI1

	px4_arch_configgpio(GPIO_SPI_CS_ICM_20608_G);
	px4_arch_configgpio(GPIO_SPI_CS_BARO);
	px4_arch_configgpio(GPIO_SPI_CS_MPU);

	/* De-activate all peripherals,
	 * required for some peripheral
	 * state machines
	 */
	px4_arch_gpiowrite(GPIO_SPI_CS_ICM_20608_G, 1);
	px4_arch_gpiowrite(GPIO_SPI_CS_BARO, 1);
	px4_arch_gpiowrite(GPIO_SPI_CS_MPU, 1);

	px4_arch_configgpio(GPIO_EXTI_MPU_DRDY);
	px4_arch_configgpio(GPIO_EXTI_ICM_20608_G_DRDY);
#endif

#ifdef CONFIG_STM32_SPI2
	px4_arch_configgpio(GPIO_SPI_CS_FRAM);
	px4_arch_gpiowrite(GPIO_SPI_CS_FRAM, 1);
#endif

}
示例#16
0
文件: usb.c 项目: Aerovinci/Firmware
__EXPORT void stm32_usbinitialize(void)
{
	/* The OTG FS has an internal soft pull-up */

	/* Configure the OTG FS VBUS sensing GPIO, Power On, and Overcurrent GPIOs */

#ifdef CONFIG_STM32_OTGFS
	px4_arch_configgpio(GPIO_OTGFS_VBUS);
	/* XXX We only support device mode
	px4_arch_configgpio(GPIO_OTGFS_PWRON);
	px4_arch_configgpio(GPIO_OTGFS_OVER);
	*/
#endif
}
示例#17
0
void ToneAlarmInterface::start_note(unsigned frequency)
{
	// Calculate the signal switching period.
	// (Signal switching period is one half of the frequency period).
	float signal_period = (1.0f / frequency) * 0.5f;

	// Calculate the hardware clock divisor rounded to the nearest integer.
	unsigned int divisor = std::round(signal_period * TONE_ALARM_CLOCK);

	rCNT = 0;
	rMOD = divisor;        // Load new signal switching period.
	rSC |= (TPM_SC_CMOD_LPTPM_CLK);

	// Configure the GPIO to enable timer output.
	px4_arch_configgpio(GPIO_TONE_ALARM);
}
示例#18
0
static void
led_pwm_channel_init(unsigned channel)
{
	/* Only initialize used channels */

	if (led_pwm_channels[channel].timer_channel) {
        
		unsigned timer = led_pwm_channels[channel].timer_index;
        printf("init led pwm timer #%d, channel #%d\n", timer, channel);

		/* configure the GPIO first */
		px4_arch_configgpio(led_pwm_channels[channel].gpio_out);

        uint16_t polarity = 0; //led_pwm_channels[channel].masks;
        printf("polarity for channel #%d: %d\n", channel, polarity);

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

		case 2:
			rCCMR1(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR1_OC2M_SHIFT) | GTIM_CCMR1_OC2PE;
			rCCER(timer) |= polarity | GTIM_CCER_CC2E;
			break;

		case 3:
			rCCMR2(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR2_OC3M_SHIFT) | GTIM_CCMR2_OC3PE;
			rCCER(timer) |= polarity | GTIM_CCER_CC3E;
			break;

		case 4:
			rCCMR2(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR2_OC4M_SHIFT) | GTIM_CCMR2_OC4PE;
			rCCER(timer) |= polarity | GTIM_CCER_CC4E;
			break;
		}
	}
}
示例#19
0
文件: spi.c 项目: AlexisTM/Firmware
__EXPORT void stm32_spiinitialize(void)
{
#ifdef CONFIG_STM32_SPI1

	px4_arch_configgpio(GPIO_SPI_CS_ICM_2060X);
	px4_arch_configgpio(GPIO_SPI_CS_BARO);
	px4_arch_configgpio(GPIO_SPI_CS_MPU);

	px4_arch_configgpio(GPIO_EXTI_MPU_DRDY);
	px4_arch_configgpio(GPIO_EXTI_ICM_2060X_DRDY);
#endif

#ifdef CONFIG_STM32_SPI2
	px4_arch_configgpio(GPIO_SPI_CS_FRAM);
#endif

}
示例#20
0
void
interface_init(void)
{
	pc_txns = perf_alloc(PC_ELAPSED, "txns");
	pc_errors = perf_alloc(PC_COUNT, "errors");
	pc_ore = perf_alloc(PC_COUNT, "overrun");
	pc_fe = perf_alloc(PC_COUNT, "framing");
	pc_ne = perf_alloc(PC_COUNT, "noise");
	pc_idle = perf_alloc(PC_COUNT, "idle");
	pc_badidle = perf_alloc(PC_COUNT, "badidle");
	pc_regerr = perf_alloc(PC_COUNT, "regerr");
	pc_crcerr = perf_alloc(PC_COUNT, "crcerr");

	/* allocate DMA */
	tx_dma = stm32_dmachannel(PX4FMU_SERIAL_TX_DMA);
	rx_dma = stm32_dmachannel(PX4FMU_SERIAL_RX_DMA);

	/* configure pins for serial use */
	px4_arch_configgpio(PX4FMU_SERIAL_TX_GPIO);
	px4_arch_configgpio(PX4FMU_SERIAL_RX_GPIO);

	/* reset and configure the UART */
	rCR1 = 0;
	rCR2 = 0;
	rCR3 = 0;

	/* clear status/errors */
	(void)rSR;
	(void)rDR;

	/* configure line speed */
	uint32_t usartdiv32 = PX4FMU_SERIAL_CLOCK / (PX4FMU_SERIAL_BITRATE / 2);
	uint32_t mantissa = usartdiv32 >> 5;
	uint32_t fraction = (usartdiv32 - (mantissa << 5) + 1) >> 1;
	rBRR = (mantissa << USART_BRR_MANT_SHIFT) | (fraction << USART_BRR_FRAC_SHIFT);

	/* connect our interrupt */
	irq_attach(PX4FMU_SERIAL_VECTOR, serial_interrupt, NULL);
	up_enable_irq(PX4FMU_SERIAL_VECTOR);

	/* enable UART and error/idle interrupts */
	rCR3 = USART_CR3_EIE;
	rCR1 = USART_CR1_RE | USART_CR1_TE | USART_CR1_UE | USART_CR1_IDLEIE;

#if 0	/* keep this for signal integrity testing */

	for (;;) {
		while (!(rSR & USART_SR_TXE))
			;

		rDR = 0xfa;

		while (!(rSR & USART_SR_TXE))
			;

		rDR = 0xa0;
	}

#endif

	/* configure RX DMA and return to listening state */
	dma_reset();

	debug("serial init");
}
示例#21
0
__END_DECLS

/****************************************************************************
 * Protected Functions
 ****************************************************************************/
/****************************************************************************
 * Public Functions
 ****************************************************************************/
/************************************************************************************
 * Name: stm32_boardinitialize
 *
 * Description:
 *   All STM32 architectures must provide the following entry point.  This entry point
 *   is called early in the intitialization -- after all memory has been configured
 *   and mapped but before any devices have been initialized.
 *
 ************************************************************************************/

__EXPORT void
stm32_boardinitialize(void)
{
	/* configure LEDs */

	board_autoled_initialize();

	/* configure ADC pins */

	px4_arch_configgpio(GPIO_ADC1_IN4);	/* VDD_5V_SENS */
	px4_arch_configgpio(GPIO_ADC1_IN10);	/* BATT_CURRENT_SENS */
	px4_arch_configgpio(GPIO_ADC1_IN12);	/* BATT_VOLTAGE_SENS */
	px4_arch_configgpio(GPIO_ADC1_IN11);	/* RSSI analog in */
	px4_arch_configgpio(GPIO_ADC1_IN13);	/* FMU_AUX_ADC_1 */
	px4_arch_configgpio(GPIO_ADC1_IN14);	/* FMU_AUX_ADC_2 */
	px4_arch_configgpio(GPIO_ADC1_IN15);	/* PRESSURE_SENS */

	/* configure power supply control/sense pins */

	px4_arch_configgpio(GPIO_SBUS_INV);
	px4_arch_configgpio(GPIO_FRSKY_INV);

	/* configure the GPIO pins to outputs and keep them low */
	px4_arch_configgpio(GPIO_GPIO0_OUTPUT);
	px4_arch_configgpio(GPIO_GPIO1_OUTPUT);
	px4_arch_configgpio(GPIO_GPIO2_OUTPUT);
	px4_arch_configgpio(GPIO_GPIO3_OUTPUT);
	px4_arch_configgpio(GPIO_GPIO4_OUTPUT);
	px4_arch_configgpio(GPIO_GPIO5_OUTPUT);
	px4_arch_configgpio(GPIO_GPIO6_OUTPUT);
	px4_arch_configgpio(GPIO_GPIO7_OUTPUT);

	/* configure SPI interfaces */

	stm32_spiinitialize();

	stm32_configgpio(GPIO_I2C2_SCL);
	stm32_configgpio(GPIO_I2C2_SDA);

	stm32_configgpio(GPIO_I2C1_SCL);
	stm32_configgpio(GPIO_I2C1_SDA);

}
示例#22
0
__EXPORT void board_spi_reset(int ms)
{
	/* disable SPI bus */
	px4_arch_configgpio(GPIO_SPI_CS_GYRO_OFF);
	px4_arch_configgpio(GPIO_SPI_CS_ACCEL_MAG_OFF);
	px4_arch_configgpio(GPIO_SPI_CS_BARO_OFF);
	px4_arch_configgpio(GPIO_SPI_CS_MPU_OFF);

	px4_arch_gpiowrite(GPIO_SPI_CS_GYRO_OFF, 0);
	px4_arch_gpiowrite(GPIO_SPI_CS_ACCEL_MAG_OFF, 0);
	px4_arch_gpiowrite(GPIO_SPI_CS_BARO_OFF, 0);
	px4_arch_gpiowrite(GPIO_SPI_CS_MPU_OFF, 0);

	px4_arch_configgpio(GPIO_SPI1_SCK_OFF);
	px4_arch_configgpio(GPIO_SPI1_MISO_OFF);
	px4_arch_configgpio(GPIO_SPI1_MOSI_OFF);

	px4_arch_gpiowrite(GPIO_SPI1_SCK_OFF, 0);
	px4_arch_gpiowrite(GPIO_SPI1_MISO_OFF, 0);
	px4_arch_gpiowrite(GPIO_SPI1_MOSI_OFF, 0);

	px4_arch_configgpio(GPIO_GYRO_DRDY_OFF);
	px4_arch_configgpio(GPIO_ACCEL_DRDY_OFF);
	px4_arch_configgpio(GPIO_MAG_DRDY_OFF);
	px4_arch_configgpio(GPIO_EXTI_MPU_DRDY_OFF);

	px4_arch_gpiowrite(GPIO_GYRO_DRDY_OFF, 0);
	px4_arch_gpiowrite(GPIO_ACCEL_DRDY_OFF, 0);
	px4_arch_gpiowrite(GPIO_MAG_DRDY_OFF, 0);
	px4_arch_gpiowrite(GPIO_EXTI_MPU_DRDY_OFF, 0);

	/* set the sensor rail off */
	px4_arch_configgpio(GPIO_VDD_3V3_SENSORS_EN);
	px4_arch_gpiowrite(GPIO_VDD_3V3_SENSORS_EN, 0);

	/* wait for the sensor rail to reach GND */
	usleep(ms * 1000);
	warnx("reset done, %d ms", ms);

	/* re-enable power */

	/* switch the sensor rail back on */
	px4_arch_gpiowrite(GPIO_VDD_3V3_SENSORS_EN, 1);

	/* wait a bit before starting SPI, different times didn't influence results */
	usleep(100);

	/* reconfigure the SPI pins */
#ifdef CONFIG_STM32_SPI4
	px4_arch_configgpio(GPIO_SPI_CS_GYRO);
	px4_arch_configgpio(GPIO_SPI_CS_ACCEL_MAG);
	px4_arch_configgpio(GPIO_SPI_CS_BARO);
	px4_arch_configgpio(GPIO_SPI_CS_MPU);

	/* De-activate all peripherals,
	 * required for some peripheral
	 * state machines
	 */
	px4_arch_gpiowrite(GPIO_SPI_CS_GYRO, 1);
	px4_arch_gpiowrite(GPIO_SPI_CS_ACCEL_MAG, 1);
	px4_arch_gpiowrite(GPIO_SPI_CS_BARO, 1);
	px4_arch_gpiowrite(GPIO_SPI_CS_MPU, 1);

	px4_arch_configgpio(GPIO_SPI4_SCK);
	px4_arch_configgpio(GPIO_SPI4_MISO);
	px4_arch_configgpio(GPIO_SPI4_MOSI);


#endif
}
示例#23
0
int UavcanNode::start(uavcan::NodeID node_id, uint32_t bitrate)
{
	if (_instance != nullptr) {
		warnx("Already started");
		return -1;
	}

	/*
	 * GPIO config.
	 * Forced pull up on CAN2 is required for Pixhawk v1 where the second interface lacks a transceiver.
	 * If no transceiver is connected, the RX pin will float, occasionally causing CAN controller to
	 * fail during initialization.
	 */
#if defined(GPIO_CAN1_RX)
	px4_arch_configgpio(GPIO_CAN1_RX);
	px4_arch_configgpio(GPIO_CAN1_TX);
#endif
#if defined(GPIO_CAN2_RX)
	px4_arch_configgpio(GPIO_CAN2_RX | GPIO_PULLUP);
	px4_arch_configgpio(GPIO_CAN2_TX);
#endif
#if !defined(GPIO_CAN1_RX) &&  !defined(GPIO_CAN2_RX)
# error  "Need to define GPIO_CAN1_RX and/or GPIO_CAN2_RX"
#endif

	/*
	 * CAN driver init
	 * Note that we instantiate and initialize CanInitHelper only once, because the STM32's bxCAN driver
	 * shipped with libuavcan does not support deinitialization.
	 */
	static CanInitHelper* can = nullptr;

	if (can == nullptr) {

		can = new CanInitHelper();

		if (can == nullptr) {                    // We don't have exceptions so bad_alloc cannot be thrown
			warnx("Out of memory");
			return -1;
		}

		const int can_init_res = can->init(bitrate);

		if (can_init_res < 0) {
			warnx("CAN driver init failed %i", can_init_res);
			return can_init_res;
		}
	}

	/*
	 * Node init
	 */
	_instance = new UavcanNode(can->driver, uavcan_stm32::SystemClock::instance());

	if (_instance == nullptr) {
		warnx("Out of memory");
		return -1;
	}

	if (_instance == nullptr) {
		warnx("Out of memory");
		return -1;
	}

	const int node_init_res = _instance->init(node_id);

	if (node_init_res < 0) {
		delete _instance;
		_instance = nullptr;
		warnx("Node init failed %i", node_init_res);
		return node_init_res;
	}

	/*
	 * Start the task. Normally it should never exit.
	 */
	static auto run_trampoline = [](int, char *[]) {return UavcanNode::_instance->run();};
	_instance->_task = px4_task_spawn_cmd("uavcan", SCHED_DEFAULT, SCHED_PRIORITY_ACTUATOR_OUTPUTS, StackSize,
					      static_cast<main_t>(run_trampoline), nullptr);

	if (_instance->_task < 0) {
		warnx("start failed: %d", errno);
		return -errno;
	}

	return OK;
}
示例#24
0
PX4IO_serial_f7::PX4IO_serial_f7() :
	_tx_dma(nullptr),
	_rx_dma(nullptr),
	_current_packet(nullptr),
	_rx_dma_status(_dma_status_inactive),
	_completion_semaphore(SEM_INITIALIZER(0)),
#if 0
	_pc_dmasetup(perf_alloc(PC_ELAPSED,	"io_dmasetup ")),
	_pc_dmaerrs(perf_alloc(PC_COUNT,	"io_dmaerrs  "))
#else
	_pc_dmasetup(nullptr),
	_pc_dmaerrs(nullptr)
#endif
{
}

PX4IO_serial_f7::~PX4IO_serial_f7()
{
	if (_tx_dma != nullptr) {
		stm32_dmastop(_tx_dma);
		stm32_dmafree(_tx_dma);
	}

	if (_rx_dma != nullptr) {
		stm32_dmastop(_rx_dma);
		stm32_dmafree(_rx_dma);
	}

	/* reset the UART */
	rCR1 = 0;
	rCR2 = 0;
	rCR3 = 0;

	/* detach our interrupt handler */
	up_disable_irq(PX4IO_SERIAL_VECTOR);
	irq_detach(PX4IO_SERIAL_VECTOR);

	/* restore the GPIOs */
	px4_arch_unconfiggpio(PX4IO_SERIAL_TX_GPIO);
	px4_arch_unconfiggpio(PX4IO_SERIAL_RX_GPIO);

	/* Disable APB clock for the USART peripheral */
	modifyreg32(PX4IO_SERIAL_RCC_REG, PX4IO_SERIAL_RCC_EN, 0);

	/* and kill our semaphores */
	px4_sem_destroy(&_completion_semaphore);

	perf_free(_pc_dmasetup);
	perf_free(_pc_dmaerrs);
}

int
PX4IO_serial_f7::init()
{
	/* initialize base implementation */
	int r;

	if ((r = PX4IO_serial::init((IOPacket *)ROUND_UP_TO_POW2_CT((uintptr_t)_io_buffer_storage, CACHE_LINE_SIZE))) != 0) {
		return r;
	}

	/* allocate DMA */
	_tx_dma = stm32_dmachannel(PX4IO_SERIAL_TX_DMAMAP);
	_rx_dma = stm32_dmachannel(PX4IO_SERIAL_RX_DMAMAP);

	if ((_tx_dma == nullptr) || (_rx_dma == nullptr)) {
		return -1;
	}

	/* Enable the APB clock for the USART peripheral */
	modifyreg32(PX4IO_SERIAL_RCC_REG, 0, PX4IO_SERIAL_RCC_EN);

	/* configure pins for serial use */
	px4_arch_configgpio(PX4IO_SERIAL_TX_GPIO);
	px4_arch_configgpio(PX4IO_SERIAL_RX_GPIO);

	/* reset & configure the UART */
	rCR1 = 0;
	rCR2 = 0;
	rCR3 = 0;

	/* clear data that may be in the RDR and clear overrun error: */
	if (rISR & USART_ISR_RXNE) {
		(void)rRDR;
	}

	rICR = rISR & rISR_ERR_FLAGS_MASK;	/* clear the flags */

	/* configure line speed */
	uint32_t usartdiv32 = (PX4IO_SERIAL_CLOCK + (PX4IO_SERIAL_BITRATE) / 2) / (PX4IO_SERIAL_BITRATE);
	rBRR = usartdiv32;

	/* attach serial interrupt handler */
	irq_attach(PX4IO_SERIAL_VECTOR, _interrupt, this);
	up_enable_irq(PX4IO_SERIAL_VECTOR);

	/* enable UART in DMA mode, enable error and line idle interrupts */
	rCR3 = USART_CR3_EIE;
	/* TODO: maybe use DDRE */

	rCR1 = USART_CR1_RE | USART_CR1_TE | USART_CR1_UE | USART_CR1_IDLEIE;
	/* TODO: maybe we need to adhere to the procedure as described in the reference manual page 1251 (34.5.2) */

	/* create semaphores */
	px4_sem_init(&_completion_semaphore, 0, 0);

	/* _completion_semaphore use case is a signal */

	px4_sem_setprotocol(&_completion_semaphore, SEM_PRIO_NONE);

	/* XXX this could try talking to IO */

	return 0;
}
示例#25
0
文件: auav_init.c 项目: DC00/Firmware
__EXPORT int nsh_archinitialize(void)
{

	/* configure ADC pins */
	px4_arch_configgpio(GPIO_ADC1_IN2);	/* BATT_VOLTAGE_SENS */
	px4_arch_configgpio(GPIO_ADC1_IN3);	/* BATT_CURRENT_SENS */
	px4_arch_configgpio(GPIO_ADC1_IN4);	/* VDD_5V_SENS */
	px4_arch_configgpio(GPIO_ADC1_IN13);	/* FMU_AUX_ADC_1 */
	px4_arch_configgpio(GPIO_ADC1_IN14);	/* FMU_AUX_ADC_2 */
	px4_arch_configgpio(GPIO_ADC1_IN15);	/* PRESSURE_SENS */

	/* configure power supply control/sense pins */
	px4_arch_configgpio(GPIO_VDD_5V_PERIPH_EN);
	px4_arch_configgpio(GPIO_VDD_3V3_SENSORS_EN);
	px4_arch_configgpio(GPIO_VDD_BRICK_VALID);
	px4_arch_configgpio(GPIO_VDD_5V_PERIPH_OC);

	/* configure the GPIO pins to outputs and keep them low */
	px4_arch_configgpio(GPIO_GPIO0_OUTPUT);
	px4_arch_configgpio(GPIO_GPIO1_OUTPUT);
	px4_arch_configgpio(GPIO_GPIO2_OUTPUT);
	px4_arch_configgpio(GPIO_GPIO3_OUTPUT);
	px4_arch_configgpio(GPIO_GPIO4_OUTPUT);
	px4_arch_configgpio(GPIO_GPIO5_OUTPUT);

	/* configure the high-resolution time/callout interface */
	hrt_init();

	/* configure the DMA allocator */

	if (board_dma_alloc_init() < 0) {
		message("DMA alloc FAILED");
	}

	/* configure CPU load estimation */
#ifdef CONFIG_SCHED_INSTRUMENTATION
	cpuload_initialize_once();
#endif

	/* set up the serial DMA polling */
	static struct hrt_call serial_dma_call;
	struct timespec ts;

	/*
	 * Poll at 1ms intervals for received bytes that have not triggered
	 * a DMA event.
	 */
	ts.tv_sec = 0;
	ts.tv_nsec = 1000000;

	hrt_call_every(&serial_dma_call,
		       ts_to_abstime(&ts),
		       ts_to_abstime(&ts),
		       (hrt_callout)stm32_serial_dma_poll,
		       NULL);

	/* initial LED state */
	drv_led_start();
	led_off(LED_AMBER);

	/* Configure SPI-based devices */

	spi1 = px4_spibus_initialize(1);

	if (!spi1) {
		message("[boot] FAILED to initialize SPI port 1\n");
		up_ledon(LED_AMBER);
		return -ENODEV;
	}

	/* Default SPI1 to 1MHz and de-assert the known chip selects. */
	SPI_SETFREQUENCY(spi1, 10000000);
	SPI_SETBITS(spi1, 8);
	SPI_SETMODE(spi1, SPIDEV_MODE3);
	SPI_SELECT(spi1, PX4_SPIDEV_ICM, false);
	SPI_SELECT(spi1, PX4_SPIDEV_BARO, false);
	SPI_SELECT(spi1, PX4_SPIDEV_MPU, false);
	up_udelay(20);

	/* Get the SPI port for the FRAM */

	spi2 = px4_spibus_initialize(2);

	if (!spi2) {
		message("[boot] FAILED to initialize SPI port 2\n");
		up_ledon(LED_AMBER);
		return -ENODEV;
	}

	/* Default SPI2 to 37.5 MHz (40 MHz rounded to nearest valid divider, F4 max)
	 * and de-assert the known chip selects. */

	// XXX start with 10.4 MHz in FRAM usage and go up to 37.5 once validated
	SPI_SETFREQUENCY(spi2, 12 * 1000 * 1000);
	SPI_SETBITS(spi2, 8);
	SPI_SETMODE(spi2, SPIDEV_MODE3);
	SPI_SELECT(spi2, SPIDEV_FLASH, false);


#ifdef CONFIG_MMCSD
	/* First, get an instance of the SDIO interface */

	sdio = sdio_initialize(CONFIG_NSH_MMCSDSLOTNO);

	if (!sdio) {
		message("[boot] Failed to initialize SDIO slot %d\n",
			CONFIG_NSH_MMCSDSLOTNO);
		return -ENODEV;
	}

	/* Now bind the SDIO interface to the MMC/SD driver */
	int ret = mmcsd_slotinitialize(CONFIG_NSH_MMCSDMINOR, sdio);

	if (ret != OK) {
		message("[boot] Failed to bind SDIO to the MMC/SD driver: %d\n", ret);
		return ret;
	}

	/* Then let's guess and say that there is a card in the slot. There is no card detect GPIO. */
	sdio_mediachange(sdio, true);

#endif

	return OK;
}
示例#26
0
文件: spi.c 项目: AlexisTM/Firmware
__EXPORT void board_spi_reset(int ms)
{
	/* disable SPI bus */
	px4_arch_configgpio(GPIO_SPI_CS_ICM_2060X_OFF);
	px4_arch_configgpio(GPIO_SPI_CS_BARO_OFF);
	px4_arch_configgpio(GPIO_SPI_CS_MPU_OFF);

	px4_arch_gpiowrite(GPIO_SPI_CS_ICM_2060X_OFF, 0);
	px4_arch_gpiowrite(GPIO_SPI_CS_BARO_OFF, 0);
	px4_arch_gpiowrite(GPIO_SPI_CS_MPU_OFF, 0);

	px4_arch_configgpio(GPIO_SPI1_SCK_OFF);
	px4_arch_configgpio(GPIO_SPI1_MISO_OFF);
	px4_arch_configgpio(GPIO_SPI1_MOSI_OFF);

	px4_arch_gpiowrite(GPIO_SPI1_SCK_OFF, 0);
	px4_arch_gpiowrite(GPIO_SPI1_MISO_OFF, 0);
	px4_arch_gpiowrite(GPIO_SPI1_MOSI_OFF, 0);

	px4_arch_configgpio(GPIO_EXTI_ICM_2060X_DRDY_OFF);
	px4_arch_configgpio(GPIO_EXTI_MPU_DRDY_OFF);

	px4_arch_gpiowrite(GPIO_EXTI_ICM_2060X_DRDY_OFF, 0);
	px4_arch_gpiowrite(GPIO_EXTI_MPU_DRDY_OFF, 0);

	/* set the sensor rail off */
	px4_arch_configgpio(GPIO_VDD_3V3_SENSORS_EN);
	px4_arch_gpiowrite(GPIO_VDD_3V3_SENSORS_EN, 0);

	/* wait for the sensor rail to reach GND */
	usleep(ms * 1000);
	syslog(LOG_DEBUG, "reset done, %d ms\n", ms);

	/* re-enable power */

	/* switch the sensor rail back on */
	px4_arch_gpiowrite(GPIO_VDD_3V3_SENSORS_EN, 1);

	/* wait a bit before starting SPI, different times didn't influence results */
	usleep(100);

	/* reconfigure the SPI pins */
#ifdef CONFIG_STM32_SPI1
	px4_arch_configgpio(GPIO_SPI_CS_ICM_2060X);
	px4_arch_configgpio(GPIO_SPI_CS_BARO);
	px4_arch_configgpio(GPIO_SPI_CS_MPU);

	px4_arch_configgpio(GPIO_SPI1_SCK);
	px4_arch_configgpio(GPIO_SPI1_MISO);
	px4_arch_configgpio(GPIO_SPI1_MOSI);

	// // XXX bring up the EXTI pins again
	// px4_arch_configgpio(GPIO_EXTI_MPU_DRDY);
	// px4_arch_configgpio(GPIO_EXTI_ICM_2060X_DRDY);

#endif
}
示例#27
0
void
Syslink::task_main()
{
	_bridge = new SyslinkBridge(this);
	_bridge->init();

	_memory = new SyslinkMemory(this);
	_memory->init();

	_battery.reset(&_battery_status);


	//	int ret;

	/* Open serial port */
	const char *dev = "/dev/ttyS2";
	_fd = open_serial(dev);

	if (_fd < 0) {
		err(1, "can't open %s", dev);
		return;
	}


	/* Set non-blocking */
	/*
	int flags = fcntl(_fd, F_GETFL, 0);
	fcntl(_fd, F_SETFL, flags | O_NONBLOCK);
	*/

	px4_arch_configgpio(GPIO_NRF_TXEN);

	px4_pollfd_struct_t fds[2];
	fds[0].fd = _fd;
	fds[0].events = POLLIN;

	_params_sub = orb_subscribe(ORB_ID(parameter_update));
	fds[1].fd = _params_sub;
	fds[1].events = POLLIN;

	int error_counter = 0;

	char buf[64];
	int nread;

	syslink_parse_state state;
	syslink_message_t msg;

	syslink_parse_init(&state);

	//setup initial parameters
	update_params(true);

	while (_task_running) {
		int poll_ret = px4_poll(fds, 2, 500);

		/* handle the poll result */
		if (poll_ret == 0) {
			/* timeout: this means none of our providers is giving us data */

		} else if (poll_ret < 0) {
			/* this is seriously bad - should be an emergency */
			if (error_counter < 10 || error_counter % 50 == 0) {
				/* use a counter to prevent flooding (and slowing us down) */
				PX4_ERR("[syslink] ERROR return value from poll(): %d"
					, poll_ret);
			}

			error_counter++;

		} else {
			if (fds[0].revents & POLLIN) {
				if ((nread = read(_fd, buf, sizeof(buf))) < 0) {
					continue;
				}

				for (int i = 0; i < nread; i++) {
					if (syslink_parse_char(&state, buf[i], &msg)) {
						handle_message(&msg);
					}
				}
			}

			if (fds[1].revents & POLLIN) {
				struct parameter_update_s update;
				orb_copy(ORB_ID(parameter_update), _params_sub, &update);
				update_params(false);
			}
		}

	}

	close(_fd);

}
示例#28
0
__EXPORT void
stm32_boardinitialize(void)
{
	/* configure LEDs */

	board_autoled_initialize();

	/* configure ADC pins */

	px4_arch_configgpio(GPIO_ADC1_IN2);	/* BATT_VOLTAGE_SENS */
	px4_arch_configgpio(GPIO_ADC1_IN3);	/* BATT_CURRENT_SENS */
	px4_arch_configgpio(GPIO_ADC1_IN4);	/* VDD_5V_SENS */
	px4_arch_configgpio(GPIO_ADC1_IN13);	/* FMU_AUX_ADC_1 */
	px4_arch_configgpio(GPIO_ADC1_IN14);	/* FMU_AUX_ADC_2 */
	px4_arch_configgpio(GPIO_ADC1_IN15);	/* PRESSURE_SENS */

	/* configure power supply control/sense pins */
	px4_arch_configgpio(GPIO_VDD_5V_PERIPH_EN);
	px4_arch_configgpio(GPIO_VDD_3V3_SENSORS_EN);
	px4_arch_configgpio(GPIO_VDD_BRICK_VALID);
	px4_arch_configgpio(GPIO_VDD_5V_PERIPH_OC);

	/* configure the GPIO pins to outputs and keep them low */
	px4_arch_configgpio(GPIO_GPIO0_OUTPUT);
	px4_arch_configgpio(GPIO_GPIO1_OUTPUT);
	px4_arch_configgpio(GPIO_GPIO2_OUTPUT);
	px4_arch_configgpio(GPIO_GPIO3_OUTPUT);
	px4_arch_configgpio(GPIO_GPIO4_OUTPUT);
	px4_arch_configgpio(GPIO_GPIO5_OUTPUT);

	/* configure SPI interfaces */

	stm32_spiinitialize();

	/* configure USB interface */

	stm32_usbinitialize();

}
int UavcanNode::start(uavcan::NodeID node_id, uint32_t bitrate)
{


	if (_instance != nullptr) {
		warnx("Already started");
		return -1;
	}

	/*
	 * GPIO config.
	 * Forced pull up on CAN2 is required for Pixhawk v1 where the second interface lacks a transceiver.
	 * If no transceiver is connected, the RX pin will float, occasionally causing CAN controller to
	 * fail during initialization.
	 */
	px4_arch_configgpio(GPIO_CAN1_RX);
	px4_arch_configgpio(GPIO_CAN1_TX);
#if defined(GPIO_CAN2_RX)
	px4_arch_configgpio(GPIO_CAN2_RX | GPIO_PULLUP);
	px4_arch_configgpio(GPIO_CAN2_TX);
#endif
	/*
	 * CAN driver init
	 */
	static CanInitHelper can;
	static bool can_initialized = false;

	if (!can_initialized) {
		const int can_init_res = can.init(bitrate);

		if (can_init_res < 0) {
			warnx("CAN driver init failed %i", can_init_res);
			return can_init_res;
		}

		can_initialized = true;
	}

	/*
	 * Node init
	 */
	_instance = new UavcanNode(can.driver, uavcan_stm32::SystemClock::instance());

	if (_instance == nullptr) {
		warnx("Out of memory");
		return -1;
	}


	resources("Before _instance->init:");
	const int node_init_res = _instance->init(node_id);
	resources("After _instance->init:");

	if (node_init_res < 0) {
		delete _instance;
		_instance = nullptr;
		warnx("Node init failed %i", node_init_res);
		return node_init_res;
	}


	/* Keep the bit rate for reboots on BenginFirmware updates */

	_instance->active_bitrate = bitrate;

	/*
	 * Start the task. Normally it should never exit.
	 */
	static auto run_trampoline = [](int, char *[]) {return UavcanNode::_instance->run();};
	_instance->_task = px4_task_spawn_cmd("uavcan", SCHED_DEFAULT, SCHED_PRIORITY_ACTUATOR_OUTPUTS, StackSize,
					      static_cast<main_t>(run_trampoline), nullptr);

	if (_instance->_task < 0) {
		warnx("start failed: %d", errno);
		return -errno;
	}

	return OK;
}
示例#30
0
PX4IO_serial_f4::PX4IO_serial_f4() :
	_tx_dma(nullptr),
	_rx_dma(nullptr),
	_current_packet(nullptr),
	_rx_dma_status(_dma_status_inactive),
	_completion_semaphore(SEM_INITIALIZER(0)),
#if 0
	_pc_dmasetup(perf_alloc(PC_ELAPSED,	"io_dmasetup ")),
	_pc_dmaerrs(perf_alloc(PC_COUNT,	"io_dmaerrs  "))
#else
	_pc_dmasetup(nullptr),
	_pc_dmaerrs(nullptr)
#endif
{
}

PX4IO_serial_f4::~PX4IO_serial_f4()
{
	if (_tx_dma != nullptr) {
		stm32_dmastop(_tx_dma);
		stm32_dmafree(_tx_dma);
	}

	if (_rx_dma != nullptr) {
		stm32_dmastop(_rx_dma);
		stm32_dmafree(_rx_dma);
	}

	/* reset the UART */
	rCR1 = 0;
	rCR2 = 0;
	rCR3 = 0;

	/* detach our interrupt handler */
	up_disable_irq(PX4IO_SERIAL_VECTOR);
	irq_detach(PX4IO_SERIAL_VECTOR);

	/* restore the GPIOs */
	px4_arch_unconfiggpio(PX4IO_SERIAL_TX_GPIO);
	px4_arch_unconfiggpio(PX4IO_SERIAL_RX_GPIO);

	/* Disable APB clock for the USART peripheral */
	modifyreg32(PX4IO_SERIAL_RCC_REG, PX4IO_SERIAL_RCC_EN, 0);

	/* and kill our semaphores */
	px4_sem_destroy(&_completion_semaphore);

	perf_free(_pc_dmasetup);
	perf_free(_pc_dmaerrs);
}

int
PX4IO_serial_f4::init()
{
	/* initialize base implementation */
	int r;

	if ((r = PX4IO_serial::init(&_io_buffer_storage)) != 0) {
		return r;
	}

	/* allocate DMA */
	_tx_dma = stm32_dmachannel(PX4IO_SERIAL_TX_DMAMAP);
	_rx_dma = stm32_dmachannel(PX4IO_SERIAL_RX_DMAMAP);

	if ((_tx_dma == nullptr) || (_rx_dma == nullptr)) {
		return -1;
	}

	/* Enable the APB clock for the USART peripheral */
	modifyreg32(PX4IO_SERIAL_RCC_REG, 0, PX4IO_SERIAL_RCC_EN);

	/* configure pins for serial use */
	px4_arch_configgpio(PX4IO_SERIAL_TX_GPIO);
	px4_arch_configgpio(PX4IO_SERIAL_RX_GPIO);

	/* reset & configure the UART */
	rCR1 = 0;
	rCR2 = 0;
	rCR3 = 0;

	/* eat any existing interrupt status */
	(void)rSR;
	(void)rDR;


	/* configure line speed */
	uint32_t usartdiv32 = PX4IO_SERIAL_CLOCK / (PX4IO_SERIAL_BITRATE / 2);
	uint32_t mantissa = usartdiv32 >> 5;
	uint32_t fraction = (usartdiv32 - (mantissa << 5) + 1) >> 1;
	rBRR = (mantissa << USART_BRR_MANT_SHIFT) | (fraction << USART_BRR_FRAC_SHIFT);

	/* attach serial interrupt handler */
	irq_attach(PX4IO_SERIAL_VECTOR, _interrupt, this);
	up_enable_irq(PX4IO_SERIAL_VECTOR);

	/* enable UART in DMA mode, enable error and line idle interrupts */
	rCR3 = USART_CR3_EIE;

	rCR1 = USART_CR1_RE | USART_CR1_TE | USART_CR1_UE | USART_CR1_IDLEIE;

	/* create semaphores */
	px4_sem_init(&_completion_semaphore, 0, 0);

	/* _completion_semaphore use case is a signal */

	px4_sem_setprotocol(&_completion_semaphore, SEM_PRIO_NONE);

	/* XXX this could try talking to IO */

	return 0;
}