diff --git a/flight/modules/UAVOHottBridge/uavohottbridge.c b/flight/modules/UAVOHottBridge/uavohottbridge.c index 663045d08..2fbab124e 100644 --- a/flight/modules/UAVOHottBridge/uavohottbridge.c +++ b/flight/modules/UAVOHottBridge/uavohottbridge.c @@ -123,7 +123,8 @@ static int32_t uavoHoTTBridgeInitialize(void) // HoTT telemetry baudrate is fixed to 19200 PIOS_COM_ChangeBaud(PIOS_COM_HOTT, 19200); - PIOS_COM_SetHalfDuplex(PIOS_COM_HOTT, true); + bool param = true; + PIOS_COM_Ioctl(PIOS_COM_HOTT, PIOS_IOCTL_USART_SET_HALFDUPLEX, ¶m); HoTTBridgeSettingsInitialize(); HoTTBridgeStatusInitialize(); diff --git a/flight/pios/common/pios_board_io.c b/flight/pios/common/pios_board_io.c index 78c59e682..e43b3053c 100644 --- a/flight/pios/common/pios_board_io.c +++ b/flight/pios/common/pios_board_io.c @@ -165,10 +165,10 @@ void PIOS_BOARD_IO_Configure_USB() { uint8_t hwsettings_usb_hidport; uint8_t hwsettings_usb_vcpport; - + HwSettingsUSB_HIDPortGet(&hwsettings_usb_hidport); HwSettingsUSB_VCPPortGet(&hwsettings_usb_vcpport); - + PIOS_BOARD_IO_Configure_USB_Function((PIOS_BOARD_IO_USB_HID_Function)hwsettings_usb_hidport, (PIOS_BOARD_IO_USB_VCP_Function)hwsettings_usb_vcpport); } diff --git a/flight/pios/common/pios_board_sensors.c b/flight/pios/common/pios_board_sensors.c index 7d204757f..4abfe1e02 100644 --- a/flight/pios/common/pios_board_sensors.c +++ b/flight/pios/common/pios_board_sensors.c @@ -186,7 +186,7 @@ void PIOS_BOARD_Sensors_Configure() #ifdef PIOS_INCLUDE_ADC const struct pios_adc_cfg *adc_cfg = PIOS_BOARD_HW_DEFS_GetAdcCfg(pios_board_info_blob.board_rev); - if(adc_cfg) { + if (adc_cfg) { PIOS_ADC_Init(adc_cfg); # ifndef PIOS_EXCLUDE_ADVANCED_FEATURES uint8_t adc_config[HWSETTINGS_ADCROUTING_NUMELEM]; diff --git a/flight/pios/common/pios_com.c b/flight/pios/common/pios_com.c index 1a813ba3c..fb8fe3044 100644 --- a/flight/pios/common/pios_com.c +++ b/flight/pios/common/pios_com.c @@ -296,31 +296,7 @@ int32_t PIOS_COM_ChangeBaud(uint32_t com_id, uint32_t baud) return 0; } -/** - * Change the port type to halfduplex (shared rx/tx medium) - * \param[in] port COM port - * \param[in] halfduplex enabled - * \return -1 if port not available - * \return 0 on success - */ -int32_t PIOS_COM_SetHalfDuplex(uint32_t com_id, bool halfduplex) -{ - struct pios_com_dev *com_dev = (struct pios_com_dev *)com_id; - - if (!PIOS_COM_validate(com_dev)) { - /* Undefined COM port for this board (see pios_board.c) */ - return -1; - } - - /* Invoke the driver function if it exists */ - if (com_dev->driver->set_halfduplex) { - com_dev->driver->set_halfduplex(com_dev->lower_id, halfduplex); - } - - return 0; -} - -int32_t PIOS_COM_ChangeConfig(uint32_t com_id, enum PIOS_COM_Word_Length word_len, enum PIOS_COM_StopBits stop_bits, enum PIOS_COM_Parity parity, uint32_t baud_rate, enum PIOS_COM_Mode mode) +int32_t PIOS_COM_ChangeConfig(uint32_t com_id, enum PIOS_COM_Word_Length word_len, enum PIOS_COM_Parity parity, enum PIOS_COM_StopBits stop_bits, uint32_t baud_rate) { struct pios_com_dev *com_dev = (struct pios_com_dev *)com_id; @@ -331,7 +307,7 @@ int32_t PIOS_COM_ChangeConfig(uint32_t com_id, enum PIOS_COM_Word_Length word_le /* Invoke the driver function if it exists */ if (com_dev->driver->set_config) { - com_dev->driver->set_config(com_dev->lower_id, word_len, stop_bits, parity, baud_rate, mode); + com_dev->driver->set_config(com_dev->lower_id, word_len, parity, stop_bits, baud_rate); } return 0; diff --git a/flight/pios/common/pios_dsm.c b/flight/pios/common/pios_dsm.c index af52ce985..747e2b91f 100644 --- a/flight/pios/common/pios_dsm.c +++ b/flight/pios/common/pios_dsm.c @@ -332,7 +332,7 @@ int32_t PIOS_DSM_Init(uint32_t *dsm_id, /* Set comm driver parameters */ PIOS_DEBUG_Assert(driver->set_config); - driver->set_config(lower_id, PIOS_COM_Word_length_8b, PIOS_COM_StopBits_1, PIOS_COM_Parity_No, 115200, PIOS_COM_Mode_Rx); + driver->set_config(lower_id, PIOS_COM_Word_length_8b, PIOS_COM_Parity_No, PIOS_COM_StopBits_1, 115200); /* Set irq priority */ if (driver->ioctl) { diff --git a/flight/pios/common/pios_exbus.c b/flight/pios/common/pios_exbus.c index c29564075..edb416233 100644 --- a/flight/pios/common/pios_exbus.c +++ b/flight/pios/common/pios_exbus.c @@ -309,7 +309,7 @@ int32_t PIOS_EXBUS_Init(uint32_t *exbus_id, /* Set comm driver parameters */ PIOS_DEBUG_Assert(driver->set_config); - driver->set_config(lower_id, PIOS_COM_Word_length_8b, PIOS_COM_StopBits_1, PIOS_COM_Parity_No, 125000, PIOS_COM_Mode_Rx); + driver->set_config(lower_id, PIOS_COM_Word_length_8b, PIOS_COM_Parity_No, PIOS_COM_StopBits_1, 125000); /* Set irq priority */ if (driver->ioctl) { diff --git a/flight/pios/common/pios_hott.c b/flight/pios/common/pios_hott.c index 04f2fc940..c823cc8fe 100644 --- a/flight/pios/common/pios_hott.c +++ b/flight/pios/common/pios_hott.c @@ -327,7 +327,7 @@ int32_t PIOS_HOTT_Init(uint32_t *hott_id, /* Set comm driver parameters */ PIOS_DEBUG_Assert(driver->set_config); - driver->set_config(lower_id, PIOS_COM_Word_length_8b, PIOS_COM_StopBits_1, PIOS_COM_Parity_No, 115200, PIOS_COM_Mode_Rx); + driver->set_config(lower_id, PIOS_COM_Word_length_8b, PIOS_COM_Parity_No, PIOS_COM_StopBits_1, 115200); /* Set irq priority */ if (driver->ioctl) { diff --git a/flight/pios/common/pios_ibus.c b/flight/pios/common/pios_ibus.c index 953ef8865..8dd4595e6 100644 --- a/flight/pios/common/pios_ibus.c +++ b/flight/pios/common/pios_ibus.c @@ -176,7 +176,7 @@ int32_t PIOS_IBUS_Init(uint32_t *ibus_id, const struct pios_com_driver *driver, /* Set comm driver parameters */ PIOS_DEBUG_Assert(driver->set_config); - driver->set_config(lower_id, PIOS_COM_Word_length_8b, PIOS_COM_StopBits_1, PIOS_COM_Parity_No, 115200, PIOS_COM_Mode_Rx); + driver->set_config(lower_id, PIOS_COM_Word_length_8b, PIOS_COM_Parity_No, PIOS_COM_StopBits_1, 115200); /* Set irq priority */ if (driver->ioctl) { diff --git a/flight/pios/common/pios_sbus.c b/flight/pios/common/pios_sbus.c index 979c6a856..f7cd3f475 100644 --- a/flight/pios/common/pios_sbus.c +++ b/flight/pios/common/pios_sbus.c @@ -168,7 +168,7 @@ int32_t PIOS_SBus_Init(uint32_t *sbus_id, /* Set rest of the parameters */ if (driver->set_config) { - driver->set_config(lower_id, PIOS_COM_Word_length_8b, PIOS_COM_StopBits_2, PIOS_COM_Parity_Even, 100000, PIOS_COM_Mode_Rx); + driver->set_config(lower_id, PIOS_COM_Word_length_8b, PIOS_COM_Parity_Even, PIOS_COM_StopBits_2, 100000); } /* Set inverted UART and IRQ priority */ diff --git a/flight/pios/common/pios_srxl.c b/flight/pios/common/pios_srxl.c index b0595ed8e..4dcd69d85 100644 --- a/flight/pios/common/pios_srxl.c +++ b/flight/pios/common/pios_srxl.c @@ -158,7 +158,7 @@ int32_t PIOS_SRXL_Init(uint32_t *srxl_id, /* Set comm driver parameters */ PIOS_DEBUG_Assert(driver->set_config); - driver->set_config(lower_id, PIOS_COM_Word_length_8b, PIOS_COM_StopBits_1, PIOS_COM_Parity_No, 115200, PIOS_COM_Mode_Rx); + driver->set_config(lower_id, PIOS_COM_Word_length_8b, PIOS_COM_Parity_No, PIOS_COM_StopBits_1, 115200); /* Set irq priority */ if (driver->ioctl) { diff --git a/flight/pios/inc/pios_board_io.h b/flight/pios/inc/pios_board_io.h index 75a4f18cd..cf0533b02 100644 --- a/flight/pios/inc/pios_board_io.h +++ b/flight/pios/inc/pios_board_io.h @@ -224,15 +224,15 @@ typedef enum { typedef enum { PIOS_BOARD_IO_USB_VCP_NONE = HWSETTINGS_USB_VCPPORT_DISABLED, - PIOS_BOARD_IO_USB_VCP_TELEMETRY = HWSETTINGS_USB_VCPPORT_USBTELEMETRY, - PIOS_BOARD_IO_USB_VCP_COMBRIDGE = HWSETTINGS_USB_VCPPORT_COMBRIDGE, + PIOS_BOARD_IO_USB_VCP_TELEMETRY = HWSETTINGS_USB_VCPPORT_USBTELEMETRY, + PIOS_BOARD_IO_USB_VCP_COMBRIDGE = HWSETTINGS_USB_VCPPORT_COMBRIDGE, PIOS_BOARD_IO_USB_VCP_DEBUGCONSOLE = HWSETTINGS_USB_VCPPORT_DEBUGCONSOLE, PIOS_BOARD_IO_USB_VCP_MAVLINK = HWSETTINGS_USB_VCPPORT_MAVLINK, } PIOS_BOARD_IO_USB_VCP_Function; void PIOS_BOARD_IO_Configure_USB_Function(PIOS_BOARD_IO_USB_HID_Function hid_function, PIOS_BOARD_IO_USB_VCP_Function vcp_function); -# endif -#endif +# endif // ifndef BOOTLOADER +#endif // ifdef PIOS_INCLUDE_USB #ifdef PIOS_INCLUDE_PWM void PIOS_BOARD_IO_Configure_PWM(const struct pios_pwm_cfg *pwm_cfg); #endif diff --git a/flight/pios/inc/pios_com.h b/flight/pios/inc/pios_com.h index a150691a3..113f38d6f 100644 --- a/flight/pios/inc/pios_com.h +++ b/flight/pios/inc/pios_com.h @@ -71,8 +71,7 @@ enum PIOS_COM_Mode { struct pios_com_driver { void (*set_baud)(uint32_t id, uint32_t baud); - void (*set_halfduplex)(uint32_t id, bool halfduplex); - void (*set_config)(uint32_t usart_id, enum PIOS_COM_Word_Length word_len, enum PIOS_COM_StopBits stop_bits, enum PIOS_COM_Parity parity, uint32_t baud_rate, enum PIOS_COM_Mode mode); + void (*set_config)(uint32_t usart_id, enum PIOS_COM_Word_Length word_len, enum PIOS_COM_Parity parity, enum PIOS_COM_StopBits stop_bits, uint32_t baud_rate); void (*set_ctrl_line)(uint32_t id, uint32_t mask, uint32_t state); void (*tx_start)(uint32_t id, uint16_t tx_bytes_avail); void (*rx_start)(uint32_t id, uint16_t rx_bytes_avail); @@ -92,8 +91,7 @@ struct pios_com_driver { /* Public Functions */ extern int32_t PIOS_COM_Init(uint32_t *com_id, const struct pios_com_driver *driver, uint32_t lower_id, uint8_t *rx_buffer, uint16_t rx_buffer_len, uint8_t *tx_buffer, uint16_t tx_buffer_len); extern int32_t PIOS_COM_ChangeBaud(uint32_t com_id, uint32_t baud); -extern int32_t PIOS_COM_SetHalfDuplex(uint32_t com_id, bool halfduplex); -extern int32_t PIOS_COM_ChangeConfig(uint32_t com_id, enum PIOS_COM_Word_Length word_len, enum PIOS_COM_StopBits stop_bits, enum PIOS_COM_Parity parity, uint32_t baud_rate, enum PIOS_COM_Mode mode); +extern int32_t PIOS_COM_ChangeConfig(uint32_t com_id, enum PIOS_COM_Word_Length word_len, enum PIOS_COM_Parity parity, enum PIOS_COM_StopBits stop_bits, uint32_t baud_rate); extern int32_t PIOS_COM_SetCtrlLine(uint32_t com_id, uint32_t mask, uint32_t state); extern int32_t PIOS_COM_RegisterCtrlLineCallback(uint32_t usart_id, pios_com_callback_ctrl_line ctrl_line_cb, uint32_t context); extern int32_t PIOS_COM_RegisterBaudRateCallback(uint32_t usart_id, pios_com_callback_baud_rate baud_rate_cb, uint32_t context); diff --git a/flight/pios/inc/pios_usart.h b/flight/pios/inc/pios_usart.h index 49ac3c92a..35e35c89b 100644 --- a/flight/pios/inc/pios_usart.h +++ b/flight/pios/inc/pios_usart.h @@ -43,15 +43,15 @@ enum PIOS_USART_Inverted { PIOS_USART_Inverted_RxTx = (PIOS_USART_Inverted_Rx | PIOS_USART_Inverted_Tx) }; -#define PIOS_IOCTL_USART_SET_INVERTED COM_IOCTL(COM_IOCTL_TYPE_USART, 1, enum PIOS_USART_Inverted) -#define PIOS_IOCTL_USART_SET_SWAPPIN COM_IOCTL(COM_IOCTL_TYPE_USART, 2, bool) -#define PIOS_IOCTL_USART_SET_ONEWIRE COM_IOCTL(COM_IOCTL_TYPE_USART, 3, bool) +#define PIOS_IOCTL_USART_SET_INVERTED COM_IOCTL(COM_IOCTL_TYPE_USART, 1, enum PIOS_USART_Inverted) +#define PIOS_IOCTL_USART_SET_SWAPPIN COM_IOCTL(COM_IOCTL_TYPE_USART, 2, bool) +#define PIOS_IOCTL_USART_SET_HALFDUPLEX COM_IOCTL(COM_IOCTL_TYPE_USART, 3, bool) -#define PIOS_IOCTL_USART_GET_RXGPIO COM_IOCTL(COM_IOCTL_TYPE_USART, 4, struct stm32_gpio) -#define PIOS_IOCTL_USART_GET_TXGPIO COM_IOCTL(COM_IOCTL_TYPE_USART, 5, struct stm32_gpio) +#define PIOS_IOCTL_USART_GET_RXGPIO COM_IOCTL(COM_IOCTL_TYPE_USART, 4, struct stm32_gpio) +#define PIOS_IOCTL_USART_GET_TXGPIO COM_IOCTL(COM_IOCTL_TYPE_USART, 5, struct stm32_gpio) /* PIOS_IRQ_PRIO_ values */ -#define PIOS_IOCTL_USART_SET_IRQ_PRIO COM_IOCTL(COM_IOCTL_TYPE_USART, 6, uint8_t) +#define PIOS_IOCTL_USART_SET_IRQ_PRIO COM_IOCTL(COM_IOCTL_TYPE_USART, 6, uint8_t) #endif /* PIOS_USART_H */ diff --git a/flight/pios/stm32f0x/pios_usart.c b/flight/pios/stm32f0x/pios_usart.c index 21a1dceed..7666bc8df 100644 --- a/flight/pios/stm32f0x/pios_usart.c +++ b/flight/pios/stm32f0x/pios_usart.c @@ -39,7 +39,7 @@ /* Provide a COM driver */ static void PIOS_USART_ChangeBaud(uint32_t usart_id, uint32_t baud); #ifndef BOOTLOADER -static void PIOS_USART_ChangeConfig(uint32_t usart_id, enum PIOS_COM_Word_Length word_len, enum PIOS_COM_StopBits stop_bits, enum PIOS_COM_Parity parity, uint32_t baud_rate, enum PIOS_COM_Mode mode); +static void PIOS_USART_ChangeConfig(uint32_t usart_id, enum PIOS_COM_Word_Length word_len, enum PIOS_COM_Parity parity, enum PIOS_COM_StopBits stop_bits, uint32_t baud_rate); #endif static void PIOS_USART_RegisterRxCallback(uint32_t usart_id, pios_com_callback rx_in_cb, uint32_t context); static void PIOS_USART_RegisterTxCallback(uint32_t usart_id, pios_com_callback tx_out_cb, uint32_t context); @@ -186,15 +186,8 @@ int32_t PIOS_USART_Init(uint32_t *usart_id, const struct pios_usart_cfg *cfg) /* Initialize the comm parameter structure */ USART_StructInit(&usart_dev->init); // 9600 8n1 - /* Enable the USART Pins Software Remapping */ - if (usart_dev->cfg->remap) { - GPIO_PinAFConfig(cfg->rx.gpio, __builtin_ctz(cfg->rx.init.GPIO_Pin), cfg->remap); - GPIO_PinAFConfig(cfg->tx.gpio, __builtin_ctz(cfg->tx.init.GPIO_Pin), cfg->remap); - } - - /* Initialize the USART Rx and Tx pins */ - GPIO_Init(cfg->rx.gpio, (GPIO_InitTypeDef *)&cfg->rx.init); - GPIO_Init(cfg->tx.gpio, (GPIO_InitTypeDef *)&cfg->tx.init); + /* We will set modes later, depending on installed callbacks */ + usart_dev->init.USART_Mode = 0; /* Enable USART clock */ switch ((uint32_t)cfg->regs) { @@ -217,21 +210,51 @@ int32_t PIOS_USART_Init(uint32_t *usart_id, const struct pios_usart_cfg *cfg) #endif } - /* Configure the USART */ - USART_Init(cfg->regs, (USART_InitTypeDef *)&usart_dev->init); *usart_id = (uint32_t)usart_dev; PIOS_USART_SetIrqPrio(usart_dev, PIOS_IRQ_PRIO_MID); - USART_ITConfig(cfg->regs, USART_IT_RXNE, ENABLE); - USART_ITConfig(cfg->regs, USART_IT_TXE, ENABLE); - USART_ITConfig(cfg->regs, USART_IT_ORE, DISABLE); - USART_ITConfig(cfg->regs, USART_IT_TC, DISABLE); - /* Enable USART */ - USART_Cmd(cfg->regs, ENABLE); + + /* Disable overrun detection */ + USART_OverrunDetectionConfig(usart_dev->cfg->regs, USART_OVRDetection_Disable); return 0; } +static void PIOS_USART_Setup(struct pios_usart_dev *usart_dev) +{ + /* Configure RX GPIO */ + if ((usart_dev->init.USART_Mode & USART_Mode_Rx) && (usart_dev->cfg->rx.gpio)) { + if (usart_dev->cfg->remap) { + GPIO_PinAFConfig(usart_dev->cfg->rx.gpio, + __builtin_ctz(usart_dev->cfg->rx.init.GPIO_Pin), + usart_dev->cfg->remap); + } + + GPIO_Init(usart_dev->cfg->rx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->rx.init); + + USART_ITConfig(usart_dev->cfg->regs, USART_IT_RXNE, ENABLE); + } + + /* Configure TX GPIO */ + if ((usart_dev->init.USART_Mode & USART_Mode_Tx) && usart_dev->cfg->tx.gpio) { + if (usart_dev->cfg->remap) { + GPIO_PinAFConfig(usart_dev->cfg->tx.gpio, + __builtin_ctz(usart_dev->cfg->tx.init.GPIO_Pin), + usart_dev->cfg->remap); + } + + GPIO_Init(usart_dev->cfg->tx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->tx.init); + } + + /* Write new configuration */ + USART_Init(usart_dev->cfg->regs, &usart_dev->init); + + /* + * Re enable USART. + */ + USART_Cmd(usart_dev->cfg->regs, ENABLE); +} + static void PIOS_USART_RxStart(uint32_t usart_id, __attribute__((unused)) uint16_t rx_bytes_avail) { const struct pios_usart_dev *usart_dev = PIOS_USART_validate(usart_id); @@ -257,10 +280,7 @@ static void PIOS_USART_ChangeBaud(uint32_t usart_id, uint32_t baud) /* Use our working copy of the usart init structure */ usart_dev->init.USART_BaudRate = baud; - /* Write back the modified configuration */ - USART_Init(usart_dev->cfg->regs, &usart_dev->init); - - USART_Cmd(usart_dev->cfg->regs, ENABLE); + PIOS_USART_Setup(usart_dev); } #ifndef BOOTLOADER /** @@ -275,10 +295,9 @@ static void PIOS_USART_ChangeBaud(uint32_t usart_id, uint32_t baud) */ static void PIOS_USART_ChangeConfig(uint32_t usart_id, enum PIOS_COM_Word_Length word_len, - enum PIOS_COM_StopBits stop_bits, enum PIOS_COM_Parity parity, - uint32_t baud_rate, - enum PIOS_COM_Mode mode) + enum PIOS_COM_StopBits stop_bits, + uint32_t baud_rate) { struct pios_usart_dev *usart_dev = PIOS_USART_validate(usart_id); @@ -325,27 +344,7 @@ static void PIOS_USART_ChangeConfig(uint32_t usart_id, usart_dev->init.USART_BaudRate = baud_rate; } - switch (mode) { - case PIOS_COM_Mode_Rx: - usart_dev->init.USART_Mode = USART_Mode_Rx; - break; - case PIOS_COM_Mode_Tx: - usart_dev->init.USART_Mode = USART_Mode_Tx; - break; - case PIOS_COM_Mode_RxTx: - usart_dev->init.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; - break; - default: - break; - } - - /* Write back the modified configuration */ - USART_Init(usart_dev->cfg->regs, &usart_dev->init); - - /* - * Re enable USART. - */ - USART_Cmd(usart_dev->cfg->regs, ENABLE); + PIOS_USART_Setup(usart_dev); } #endif /* BOOTLOADER */ @@ -357,8 +356,12 @@ static void PIOS_USART_RegisterRxCallback(uint32_t usart_id, pios_com_callback r * Order is important in these assignments since ISR uses _cb * field to determine if it's ok to dereference _cb and _context */ - usart_dev->rx_in_context = context; + usart_dev->rx_in_context = context; usart_dev->rx_in_cb = rx_in_cb; + + usart_dev->init.USART_Mode |= USART_Mode_Rx; + + PIOS_USART_Setup(usart_dev); } static void PIOS_USART_RegisterTxCallback(uint32_t usart_id, pios_com_callback tx_out_cb, uint32_t context) @@ -369,8 +372,12 @@ static void PIOS_USART_RegisterTxCallback(uint32_t usart_id, pios_com_callback t * Order is important in these assignments since ISR uses _cb * field to determine if it's ok to dereference _cb and _context */ - usart_dev->tx_out_context = context; + usart_dev->tx_out_context = context; usart_dev->tx_out_cb = tx_out_cb; + + usart_dev->init.USART_Mode |= USART_Mode_Tx; + + PIOS_USART_Setup(usart_dev); } static void PIOS_USART_generic_irq_handler(uint32_t usart_id) diff --git a/flight/pios/stm32f10x/pios_usart.c b/flight/pios/stm32f10x/pios_usart.c index cc2d13fc0..cc1e23232 100644 --- a/flight/pios/stm32f10x/pios_usart.c +++ b/flight/pios/stm32f10x/pios_usart.c @@ -37,7 +37,7 @@ #include /* Provide a COM driver */ -static void PIOS_USART_ChangeConfig(uint32_t usart_id, enum PIOS_COM_Word_Length word_len, enum PIOS_COM_StopBits stop_bits, enum PIOS_COM_Parity parity, uint32_t baud_rate, enum PIOS_COM_Mode mode); +static void PIOS_USART_ChangeConfig(uint32_t usart_id, enum PIOS_COM_Word_Length word_len, enum PIOS_COM_Parity parity, enum PIOS_COM_StopBits stop_bits, uint32_t baud_rate); static void PIOS_USART_ChangeBaud(uint32_t usart_id, uint32_t baud); static void PIOS_USART_RegisterRxCallback(uint32_t usart_id, pios_com_callback rx_in_cb, uint32_t context); static void PIOS_USART_RegisterTxCallback(uint32_t usart_id, pios_com_callback tx_out_cb, uint32_t context); @@ -185,17 +185,10 @@ int32_t PIOS_USART_Init(uint32_t *usart_id, const struct pios_usart_cfg *cfg) /* Initialize the comm parameter structure */ USART_StructInit(&usart_dev->init); // 9600 8n1 - /* Enable the USART Pins Software Remapping */ - if (usart_dev->cfg->remap) { - GPIO_PinRemapConfig(usart_dev->cfg->remap, ENABLE); - } + /* We will set modes later, depending on installed callbacks */ + usart_dev->init.USART_Mode = 0; - /* Initialize the USART Rx and Tx pins */ - GPIO_Init(usart_dev->cfg->rx.gpio, &usart_dev->cfg->rx.init); - GPIO_Init(usart_dev->cfg->tx.gpio, &usart_dev->cfg->tx.init); - - /* Configure the USART */ - USART_Init(usart_dev->cfg->regs, &usart_dev->init); + /* DTR handling? */ *usart_id = (uint32_t)usart_dev; @@ -217,18 +210,44 @@ int32_t PIOS_USART_Init(uint32_t *usart_id, const struct pios_usart_cfg *cfg) PIOS_USART_SetIrqPrio(usart_dev, PIOS_IRQ_PRIO_MID); - USART_ITConfig(usart_dev->cfg->regs, USART_IT_RXNE, ENABLE); - USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, ENABLE); - - /* Enable USART */ - USART_Cmd(usart_dev->cfg->regs, ENABLE); - return 0; out_fail: return -1; } +static void PIOS_USART_Setup(struct pios_usart_dev *usart_dev) +{ + /* Configure RX GPIO */ + if ((usart_dev->init.USART_Mode & USART_Mode_Rx) && (usart_dev->cfg->rx.gpio)) { + if (usart_dev->cfg->remap) { + GPIO_PinRemapConfig(usart_dev->cfg->remap, ENABLE); + } + + GPIO_Init(usart_dev->cfg->rx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->rx.init); + + USART_ITConfig(usart_dev->cfg->regs, USART_IT_RXNE, ENABLE); + } + + /* Configure TX GPIO */ + if ((usart_dev->init.USART_Mode & USART_Mode_Tx) && usart_dev->cfg->tx.gpio) { + if (usart_dev->cfg->remap) { + GPIO_PinRemapConfig(usart_dev->cfg->remap, ENABLE); + } + + GPIO_Init(usart_dev->cfg->tx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->tx.init); + } + + /* Write new configuration */ + USART_Init(usart_dev->cfg->regs, &usart_dev->init); + + /* + * Re enable USART. + */ + USART_Cmd(usart_dev->cfg->regs, ENABLE); +} + + static void PIOS_USART_RxStart(uint32_t usart_id, __attribute__((unused)) uint16_t rx_bytes_avail) { struct pios_usart_dev *usart_dev = (struct pios_usart_dev *)usart_id; @@ -266,8 +285,7 @@ static void PIOS_USART_ChangeBaud(uint32_t usart_id, uint32_t baud) /* Use our working copy of the usart init structure */ usart_dev->init.USART_BaudRate = baud; - /* Write back the modified configuration */ - USART_Init(usart_dev->cfg->regs, &usart_dev->init); + PIOS_USART_Setup(usart_dev); } /** @@ -282,10 +300,9 @@ static void PIOS_USART_ChangeBaud(uint32_t usart_id, uint32_t baud) */ static void PIOS_USART_ChangeConfig(uint32_t usart_id, enum PIOS_COM_Word_Length word_len, - enum PIOS_COM_StopBits stop_bits, enum PIOS_COM_Parity parity, - uint32_t baud_rate, - enum PIOS_COM_Mode mode) + enum PIOS_COM_StopBits stop_bits, + uint32_t baud_rate) { struct pios_usart_dev *usart_dev = (struct pios_usart_dev *)usart_id; @@ -339,27 +356,7 @@ static void PIOS_USART_ChangeConfig(uint32_t usart_id, usart_dev->init.USART_BaudRate = baud_rate; } - switch (mode) { - case PIOS_COM_Mode_Rx: - usart_dev->init.USART_Mode = USART_Mode_Rx; - break; - case PIOS_COM_Mode_Tx: - usart_dev->init.USART_Mode = USART_Mode_Tx; - break; - case PIOS_COM_Mode_RxTx: - usart_dev->init.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; - break; - default: - break; - } - - /* Write back the modified configuration */ - USART_Init(usart_dev->cfg->regs, &usart_dev->init); - - /* - * Re enable USART. - */ - USART_Cmd(usart_dev->cfg->regs, ENABLE); + PIOS_USART_Setup(usart_dev); } static void PIOS_USART_RegisterRxCallback(uint32_t usart_id, pios_com_callback rx_in_cb, uint32_t context) @@ -374,8 +371,12 @@ static void PIOS_USART_RegisterRxCallback(uint32_t usart_id, pios_com_callback r * Order is important in these assignments since ISR uses _cb * field to determine if it's ok to dereference _cb and _context */ - usart_dev->rx_in_context = context; + usart_dev->rx_in_context = context; usart_dev->rx_in_cb = rx_in_cb; + + usart_dev->init.USART_Mode |= USART_Mode_Rx; + + PIOS_USART_Setup(usart_dev); } static void PIOS_USART_RegisterTxCallback(uint32_t usart_id, pios_com_callback tx_out_cb, uint32_t context) @@ -390,8 +391,12 @@ static void PIOS_USART_RegisterTxCallback(uint32_t usart_id, pios_com_callback t * Order is important in these assignments since ISR uses _cb * field to determine if it's ok to dereference _cb and _context */ - usart_dev->tx_out_context = context; + usart_dev->tx_out_context = context; usart_dev->tx_out_cb = tx_out_cb; + + usart_dev->init.USART_Mode |= USART_Mode_Tx; + + PIOS_USART_Setup(usart_dev); } static void PIOS_USART_generic_irq_handler(uint32_t usart_id) @@ -467,6 +472,9 @@ static int32_t PIOS_USART_Ioctl(uint32_t usart_id, uint32_t ctl, void *param) case PIOS_IOCTL_USART_GET_TXGPIO: *(struct stm32_gpio *)param = usart_dev->cfg->tx; break; + case PIOS_IOCTL_USART_SET_HALFDUPLEX: + USART_HalfDuplexCmd(usart_dev->cfg->regs, *(bool *)param ? ENABLE : DISABLE); + break; default: if (usart_dev->cfg->ioctl) { return usart_dev->cfg->ioctl(usart_id, ctl, param); diff --git a/flight/pios/stm32f4xx/pios_usart.c b/flight/pios/stm32f4xx/pios_usart.c index 7b9f93649..3731bb658 100644 --- a/flight/pios/stm32f4xx/pios_usart.c +++ b/flight/pios/stm32f4xx/pios_usart.c @@ -41,8 +41,7 @@ /* Provide a COM driver */ static void PIOS_USART_ChangeBaud(uint32_t usart_id, uint32_t baud); -static void PIOS_USART_SetHalfDuplex(uint32_t usart_id, bool halfduplex); -static void PIOS_USART_ChangeConfig(uint32_t usart_id, enum PIOS_COM_Word_Length word_len, enum PIOS_COM_StopBits stop_bits, enum PIOS_COM_Parity parity, uint32_t baud_rate, enum PIOS_COM_Mode mode); +static void PIOS_USART_ChangeConfig(uint32_t usart_id, enum PIOS_COM_Word_Length word_len, enum PIOS_COM_Parity parity, enum PIOS_COM_StopBits stop_bits, uint32_t baud_rate); static void PIOS_USART_SetCtrlLine(uint32_t usart_id, uint32_t mask, uint32_t state); static void PIOS_USART_RegisterRxCallback(uint32_t usart_id, pios_com_callback rx_in_cb, uint32_t context); static void PIOS_USART_RegisterTxCallback(uint32_t usart_id, pios_com_callback tx_out_cb, uint32_t context); @@ -51,15 +50,14 @@ static void PIOS_USART_RxStart(uint32_t usart_id, uint16_t rx_bytes_avail); static int32_t PIOS_USART_Ioctl(uint32_t usart_id, uint32_t ctl, void *param); const struct pios_com_driver pios_usart_com_driver = { - .set_baud = PIOS_USART_ChangeBaud, - .set_halfduplex = PIOS_USART_SetHalfDuplex, - .set_config = PIOS_USART_ChangeConfig, - .set_ctrl_line = PIOS_USART_SetCtrlLine, - .tx_start = PIOS_USART_TxStart, - .rx_start = PIOS_USART_RxStart, - .bind_tx_cb = PIOS_USART_RegisterTxCallback, - .bind_rx_cb = PIOS_USART_RegisterRxCallback, - .ioctl = PIOS_USART_Ioctl, + .set_baud = PIOS_USART_ChangeBaud, + .set_config = PIOS_USART_ChangeConfig, + .set_ctrl_line = PIOS_USART_SetCtrlLine, + .tx_start = PIOS_USART_TxStart, + .rx_start = PIOS_USART_RxStart, + .bind_tx_cb = PIOS_USART_RegisterTxCallback, + .bind_rx_cb = PIOS_USART_RegisterRxCallback, + .ioctl = PIOS_USART_Ioctl, }; enum pios_usart_dev_magic { @@ -211,20 +209,9 @@ int32_t PIOS_USART_Init(uint32_t *usart_id, const struct pios_usart_cfg *cfg) /* Initialize the comm parameter structure */ USART_StructInit(&usart_dev->init); // 9600 8n1 - /* Map pins to USART function */ - /* note __builtin_ctz() due to the difference between GPIO_PinX and GPIO_PinSourceX */ - if (usart_dev->cfg->remap) { - GPIO_PinAFConfig(usart_dev->cfg->rx.gpio, - __builtin_ctz(usart_dev->cfg->rx.init.GPIO_Pin), - usart_dev->cfg->remap); - GPIO_PinAFConfig(usart_dev->cfg->tx.gpio, - __builtin_ctz(usart_dev->cfg->tx.init.GPIO_Pin), - usart_dev->cfg->remap); - } + /* We will set modes later, depending on installed callbacks */ + usart_dev->init.USART_Mode = 0; - /* Initialize the USART Rx and Tx pins */ - GPIO_Init(usart_dev->cfg->rx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->rx.init); - GPIO_Init(usart_dev->cfg->tx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->tx.init); /* If a DTR line is specified, initialize it */ if (usart_dev->cfg->dtr.gpio) { @@ -232,9 +219,6 @@ int32_t PIOS_USART_Init(uint32_t *usart_id, const struct pios_usart_cfg *cfg) PIOS_USART_SetCtrlLine((uint32_t)usart_dev, COM_CTRL_LINE_DTR_MASK, 0); } - /* Configure the USART */ - USART_Init(usart_dev->cfg->regs, (USART_InitTypeDef *)&usart_dev->init); - *usart_id = (uint32_t)usart_dev; /* Configure USART Interrupts */ @@ -267,13 +251,6 @@ int32_t PIOS_USART_Init(uint32_t *usart_id, const struct pios_usart_cfg *cfg) break; } PIOS_USART_SetIrqPrio(usart_dev, PIOS_IRQ_PRIO_MID); - USART_ITConfig(usart_dev->cfg->regs, USART_IT_RXNE, ENABLE); - USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, ENABLE); - - // FIXME XXX Clear / reset uart here - sends NUL char else - - /* Enable USART */ - USART_Cmd(usart_dev->cfg->regs, ENABLE); return 0; @@ -281,6 +258,42 @@ out_fail: return -1; } +static void PIOS_USART_Setup(struct pios_usart_dev *usart_dev) +{ + /* Configure RX GPIO */ + if ((usart_dev->init.USART_Mode & USART_Mode_Rx) && (usart_dev->cfg->rx.gpio)) { + if (usart_dev->cfg->remap) { + GPIO_PinAFConfig(usart_dev->cfg->rx.gpio, + __builtin_ctz(usart_dev->cfg->rx.init.GPIO_Pin), + usart_dev->cfg->remap); + } + + GPIO_Init(usart_dev->cfg->rx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->rx.init); + + /* just enable RX right away, cause rcvr modules do not call rx_start method */ + USART_ITConfig(usart_dev->cfg->regs, USART_IT_RXNE, ENABLE); + } + + /* Configure TX GPIO */ + if ((usart_dev->init.USART_Mode & USART_Mode_Tx) && usart_dev->cfg->tx.gpio) { + if (usart_dev->cfg->remap) { + GPIO_PinAFConfig(usart_dev->cfg->tx.gpio, + __builtin_ctz(usart_dev->cfg->tx.init.GPIO_Pin), + usart_dev->cfg->remap); + } + + GPIO_Init(usart_dev->cfg->tx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->tx.init); + } + + /* Write new configuration */ + USART_Init(usart_dev->cfg->regs, &usart_dev->init); + + /* + * Re enable USART. + */ + USART_Cmd(usart_dev->cfg->regs, ENABLE); +} + static void PIOS_USART_RxStart(uint32_t usart_id, __attribute__((unused)) uint16_t rx_bytes_avail) { struct pios_usart_dev *usart_dev = (struct pios_usart_dev *)usart_id; @@ -319,24 +332,7 @@ static void PIOS_USART_ChangeBaud(uint32_t usart_id, uint32_t baud) /* Use our working copy of the usart init structure */ usart_dev->init.USART_BaudRate = baud; - /* Write back the modified configuration */ - USART_Init(usart_dev->cfg->regs, &usart_dev->init); -} - -/** - * Sets the USART peripheral into half duplex mode - * \param[in] usart_id USART name (GPS, TELEM, AUX) - * \param[in] bool wether to set half duplex or not - */ -static void PIOS_USART_SetHalfDuplex(uint32_t usart_id, bool halfduplex) -{ - struct pios_usart_dev *usart_dev = (struct pios_usart_dev *)usart_id; - - bool valid = PIOS_USART_validate(usart_dev); - - PIOS_Assert(valid); - - USART_HalfDuplexCmd(usart_dev->cfg->regs, halfduplex ? ENABLE : DISABLE); + PIOS_USART_Setup(usart_dev); } /** @@ -351,10 +347,9 @@ static void PIOS_USART_SetHalfDuplex(uint32_t usart_id, bool halfduplex) */ static void PIOS_USART_ChangeConfig(uint32_t usart_id, enum PIOS_COM_Word_Length word_len, - enum PIOS_COM_StopBits stop_bits, enum PIOS_COM_Parity parity, - uint32_t baud_rate, - enum PIOS_COM_Mode mode) + enum PIOS_COM_StopBits stop_bits, + uint32_t baud_rate) { struct pios_usart_dev *usart_dev = (struct pios_usart_dev *)usart_id; @@ -408,27 +403,7 @@ static void PIOS_USART_ChangeConfig(uint32_t usart_id, usart_dev->init.USART_BaudRate = baud_rate; } - switch (mode) { - case PIOS_COM_Mode_Rx: - usart_dev->init.USART_Mode = USART_Mode_Rx; - break; - case PIOS_COM_Mode_Tx: - usart_dev->init.USART_Mode = USART_Mode_Tx; - break; - case PIOS_COM_Mode_RxTx: - usart_dev->init.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; - break; - default: - break; - } - - /* Write back the modified configuration */ - USART_Init(usart_dev->cfg->regs, &usart_dev->init); - - /* - * Re enable USART. - */ - USART_Cmd(usart_dev->cfg->regs, ENABLE); + PIOS_USART_Setup(usart_dev); } static void PIOS_USART_SetCtrlLine(uint32_t usart_id, uint32_t mask, uint32_t state) @@ -459,8 +434,12 @@ static void PIOS_USART_RegisterRxCallback(uint32_t usart_id, pios_com_callback r * Order is important in these assignments since ISR uses _cb * field to determine if it's ok to dereference _cb and _context */ - usart_dev->rx_in_context = context; + usart_dev->rx_in_context = context; usart_dev->rx_in_cb = rx_in_cb; + + usart_dev->init.USART_Mode |= USART_Mode_Rx; + + PIOS_USART_Setup(usart_dev); } static void PIOS_USART_RegisterTxCallback(uint32_t usart_id, pios_com_callback tx_out_cb, uint32_t context) @@ -475,8 +454,12 @@ static void PIOS_USART_RegisterTxCallback(uint32_t usart_id, pios_com_callback t * Order is important in these assignments since ISR uses _cb * field to determine if it's ok to dereference _cb and _context */ - usart_dev->tx_out_context = context; + usart_dev->tx_out_context = context; usart_dev->tx_out_cb = tx_out_cb; + + usart_dev->init.USART_Mode |= USART_Mode_Tx; + + PIOS_USART_Setup(usart_dev); } static void PIOS_USART_generic_irq_handler(uint32_t usart_id) @@ -547,6 +530,9 @@ static int32_t PIOS_USART_Ioctl(uint32_t usart_id, uint32_t ctl, void *param) case PIOS_IOCTL_USART_GET_TXGPIO: *(struct stm32_gpio *)param = usart_dev->cfg->tx; break; + case PIOS_IOCTL_USART_SET_HALFDUPLEX: + USART_HalfDuplexCmd(usart_dev->cfg->regs, *(bool *)param ? ENABLE : DISABLE); + break; default: if (usart_dev->cfg->ioctl) { return usart_dev->cfg->ioctl(usart_id, ctl, param); diff --git a/flight/targets/boards/simposix/firmware/inc/pios_config.h b/flight/targets/boards/simposix/firmware/inc/pios_config.h index 36f84be85..8e29dc590 100644 --- a/flight/targets/boards/simposix/firmware/inc/pios_config.h +++ b/flight/targets/boards/simposix/firmware/inc/pios_config.h @@ -52,7 +52,7 @@ #define PIOS_INCLUDE_SPI #define PIOS_INCLUDE_SYS #define PIOS_INCLUDE_TASK_MONITOR -//#define PIOS_INCLUDE_USART +// #define PIOS_INCLUDE_USART // #define PIOS_INCLUDE_USB #define PIOS_INCLUDE_USB_HID // #define PIOS_INCLUDE_GPIO @@ -87,8 +87,8 @@ #define PIOS_INCLUDE_RCVR #define PIOS_INCLUDE_DSM // #define PIOS_INCLUDE_SBUS -//#define PIOS_INCLUDE_PPM -//#define PIOS_INCLUDE_PWM +// #define PIOS_INCLUDE_PPM +// #define PIOS_INCLUDE_PWM /* #define PIOS_INCLUDE_GCSRCVR */ /* #define PIOS_INCLUDE_OPLINKRCVR */ #define PIOS_INCLUDE_IAP