mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-21 15:25:36 +03:00
Handle USART TX pulldown (#12929)
SA is always unidirectional Only switch AT32 TX line to input when transmission is complete
This commit is contained in:
parent
6ba117d69e
commit
1333771140
8 changed files with 20 additions and 25 deletions
|
@ -93,7 +93,7 @@ void uartReconfigure(uartPort_t *uartPort)
|
||||||
//init
|
//init
|
||||||
usart_init(uartPort->USARTx,
|
usart_init(uartPort->USARTx,
|
||||||
uartPort->port.baudRate,
|
uartPort->port.baudRate,
|
||||||
(uartPort->port.options & SERIAL_PARITY_EVEN)? USART_DATA_9BITS:USART_DATA_8BITS,
|
USART_DATA_8BITS,
|
||||||
(uartPort->port.options & SERIAL_STOPBITS_2) ? USART_STOP_2_BIT : USART_STOP_1_BIT);
|
(uartPort->port.options & SERIAL_STOPBITS_2) ? USART_STOP_2_BIT : USART_STOP_1_BIT);
|
||||||
|
|
||||||
//set parity
|
//set parity
|
||||||
|
@ -196,7 +196,7 @@ bool checkUsartTxOutput(uartPort_t *s)
|
||||||
|
|
||||||
// Enable USART TX output
|
// Enable USART TX output
|
||||||
uart->txPinState = TX_PIN_ACTIVE;
|
uart->txPinState = TX_PIN_ACTIVE;
|
||||||
IOConfigGPIOAF(txIO, IOCFG_AF_PP, uart->hardware->af);
|
IOConfigGPIOAF(txIO, IOCFG_AF_PP, uart->tx.af);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// TX line is pulled low so don't enable USART TX
|
// TX line is pulled low so don't enable USART TX
|
||||||
|
@ -210,11 +210,14 @@ bool checkUsartTxOutput(uartPort_t *s)
|
||||||
void uartTxMonitor(uartPort_t *s)
|
void uartTxMonitor(uartPort_t *s)
|
||||||
{
|
{
|
||||||
uartDevice_t *uart = container_of(s, uartDevice_t, port);
|
uartDevice_t *uart = container_of(s, uartDevice_t, port);
|
||||||
IO_t txIO = IOGetByTag(uart->tx.pin);
|
|
||||||
|
|
||||||
// Switch TX to an input with pullup so it's state can be monitored
|
if (uart->txPinState == TX_PIN_ACTIVE) {
|
||||||
uart->txPinState = TX_PIN_MONITOR;
|
IO_t txIO = IOGetByTag(uart->tx.pin);
|
||||||
IOConfigGPIO(txIO, IOCFG_IPU);
|
|
||||||
|
// Switch TX to an input with pullup so it's state can be monitored
|
||||||
|
uart->txPinState = TX_PIN_MONITOR;
|
||||||
|
IOConfigGPIO(txIO, IOCFG_IPU);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_DMA
|
#ifdef USE_DMA
|
||||||
|
@ -263,11 +266,9 @@ void uartTryStartTxDMA(uartPort_t *s)
|
||||||
|
|
||||||
static void handleUsartTxDma(uartPort_t *s)
|
static void handleUsartTxDma(uartPort_t *s)
|
||||||
{
|
{
|
||||||
uartDevice_t *uart = container_of(s, uartDevice_t, port);
|
|
||||||
|
|
||||||
uartTryStartTxDMA(s);
|
uartTryStartTxDMA(s);
|
||||||
|
|
||||||
if (s->txDMAEmpty && (uart->txPinState != TX_PIN_IGNORE)) {
|
if (s->txDMAEmpty) {
|
||||||
// Switch TX to an input with pullup so it's state can be monitored
|
// Switch TX to an input with pullup so it's state can be monitored
|
||||||
uartTxMonitor(s);
|
uartTxMonitor(s);
|
||||||
}
|
}
|
||||||
|
@ -314,9 +315,6 @@ void uartIrqHandler(uartPort_t *s)
|
||||||
s->port.txBufferTail = (s->port.txBufferTail + 1) % s->port.txBufferSize;
|
s->port.txBufferTail = (s->port.txBufferTail + 1) % s->port.txBufferSize;
|
||||||
} else {
|
} else {
|
||||||
usart_interrupt_enable(s->USARTx, USART_TDBE_INT, FALSE);
|
usart_interrupt_enable(s->USARTx, USART_TDBE_INT, FALSE);
|
||||||
|
|
||||||
// Switch TX to an input with pullup so it's state can be monitored
|
|
||||||
uartTxMonitor(s);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -315,7 +315,7 @@ uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode,
|
||||||
if ((mode & MODE_TX) && txIO) {
|
if ((mode & MODE_TX) && txIO) {
|
||||||
IOInit(txIO, OWNER_SERIAL_TX, RESOURCE_INDEX(device));
|
IOInit(txIO, OWNER_SERIAL_TX, RESOURCE_INDEX(device));
|
||||||
|
|
||||||
if ((options & SERIAL_INVERTED) == SERIAL_NOT_INVERTED) {
|
if (((options & SERIAL_INVERTED) == SERIAL_NOT_INVERTED) && !(options & SERIAL_BIDIR_PP_PD)) {
|
||||||
uartdev->txPinState = TX_PIN_ACTIVE;
|
uartdev->txPinState = TX_PIN_ACTIVE;
|
||||||
// Switch TX to an input with pullup so it's state can be monitored
|
// Switch TX to an input with pullup so it's state can be monitored
|
||||||
uartTxMonitor(s);
|
uartTxMonitor(s);
|
||||||
|
|
|
@ -264,9 +264,10 @@ bool checkUsartTxOutput(uartPort_t *s)
|
||||||
void uartTxMonitor(uartPort_t *s)
|
void uartTxMonitor(uartPort_t *s)
|
||||||
{
|
{
|
||||||
uartDevice_t *uart = container_of(s, uartDevice_t, port);
|
uartDevice_t *uart = container_of(s, uartDevice_t, port);
|
||||||
IO_t txIO = IOGetByTag(uart->tx.pin);
|
|
||||||
|
|
||||||
if (uart->txPinState == TX_PIN_ACTIVE) {
|
if (uart->txPinState == TX_PIN_ACTIVE) {
|
||||||
|
IO_t txIO = IOGetByTag(uart->tx.pin);
|
||||||
|
|
||||||
// Switch TX to an input with pullup so it's state can be monitored
|
// Switch TX to an input with pullup so it's state can be monitored
|
||||||
uart->txPinState = TX_PIN_MONITOR;
|
uart->txPinState = TX_PIN_MONITOR;
|
||||||
IOConfigGPIO(txIO, IOCFG_IPU);
|
IOConfigGPIO(txIO, IOCFG_IPU);
|
||||||
|
|
|
@ -245,9 +245,10 @@ bool checkUsartTxOutput(uartPort_t *s)
|
||||||
void uartTxMonitor(uartPort_t *s)
|
void uartTxMonitor(uartPort_t *s)
|
||||||
{
|
{
|
||||||
uartDevice_t *uart = container_of(s, uartDevice_t, port);
|
uartDevice_t *uart = container_of(s, uartDevice_t, port);
|
||||||
IO_t txIO = IOGetByTag(uart->tx.pin);
|
|
||||||
|
|
||||||
if (uart->txPinState == TX_PIN_ACTIVE) {
|
if (uart->txPinState == TX_PIN_ACTIVE) {
|
||||||
|
IO_t txIO = IOGetByTag(uart->tx.pin);
|
||||||
|
|
||||||
// Switch TX to an input with pullup so it's state can be monitored
|
// Switch TX to an input with pullup so it's state can be monitored
|
||||||
uart->txPinState = TX_PIN_MONITOR;
|
uart->txPinState = TX_PIN_MONITOR;
|
||||||
IOConfigGPIO(txIO, IOCFG_IPU);
|
IOConfigGPIO(txIO, IOCFG_IPU);
|
||||||
|
@ -334,7 +335,7 @@ uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode,
|
||||||
if ((mode & MODE_TX) && txIO) {
|
if ((mode & MODE_TX) && txIO) {
|
||||||
IOInit(txIO, OWNER_SERIAL_TX, RESOURCE_INDEX(device));
|
IOInit(txIO, OWNER_SERIAL_TX, RESOURCE_INDEX(device));
|
||||||
|
|
||||||
if ((options & SERIAL_INVERTED) == SERIAL_NOT_INVERTED) {
|
if (((options & SERIAL_INVERTED) == SERIAL_NOT_INVERTED) && !(options & SERIAL_BIDIR_PP_PD)) {
|
||||||
uart->txPinState = TX_PIN_ACTIVE;
|
uart->txPinState = TX_PIN_ACTIVE;
|
||||||
// Switch TX to an input with pullup so it's state can be monitored
|
// Switch TX to an input with pullup so it's state can be monitored
|
||||||
uartTxMonitor(s);
|
uartTxMonitor(s);
|
||||||
|
|
|
@ -376,7 +376,7 @@ uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode,
|
||||||
if ((mode & MODE_TX) && txIO) {
|
if ((mode & MODE_TX) && txIO) {
|
||||||
IOInit(txIO, OWNER_SERIAL_TX, RESOURCE_INDEX(device));
|
IOInit(txIO, OWNER_SERIAL_TX, RESOURCE_INDEX(device));
|
||||||
|
|
||||||
if ((options & SERIAL_INVERTED) == SERIAL_NOT_INVERTED) {
|
if (((options & SERIAL_INVERTED) == SERIAL_NOT_INVERTED) && !(options & SERIAL_BIDIR_PP_PD)) {
|
||||||
uartdev->txPinState = TX_PIN_ACTIVE;
|
uartdev->txPinState = TX_PIN_ACTIVE;
|
||||||
// Switch TX to an input with pullup so it's state can be monitored
|
// Switch TX to an input with pullup so it's state can be monitored
|
||||||
uartTxMonitor(s);
|
uartTxMonitor(s);
|
||||||
|
|
|
@ -309,7 +309,7 @@ uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode,
|
||||||
if ((mode & MODE_TX) && txIO) {
|
if ((mode & MODE_TX) && txIO) {
|
||||||
IOInit(txIO, OWNER_SERIAL_TX, RESOURCE_INDEX(device));
|
IOInit(txIO, OWNER_SERIAL_TX, RESOURCE_INDEX(device));
|
||||||
|
|
||||||
if ((options & SERIAL_INVERTED) == SERIAL_NOT_INVERTED) {
|
if (((options & SERIAL_INVERTED) == SERIAL_NOT_INVERTED) && !(options & SERIAL_BIDIR_PP_PD)) {
|
||||||
uartdev->txPinState = TX_PIN_ACTIVE;
|
uartdev->txPinState = TX_PIN_ACTIVE;
|
||||||
// Switch TX to an input with pullup so it's state can be monitored
|
// Switch TX to an input with pullup so it's state can be monitored
|
||||||
uartTxMonitor(s);
|
uartTxMonitor(s);
|
||||||
|
|
|
@ -486,7 +486,7 @@ uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode,
|
||||||
if ((mode & MODE_TX) && txIO) {
|
if ((mode & MODE_TX) && txIO) {
|
||||||
IOInit(txIO, OWNER_SERIAL_TX, RESOURCE_INDEX(device));
|
IOInit(txIO, OWNER_SERIAL_TX, RESOURCE_INDEX(device));
|
||||||
|
|
||||||
if ((options & SERIAL_INVERTED) == SERIAL_NOT_INVERTED) {
|
if (((options & SERIAL_INVERTED) == SERIAL_NOT_INVERTED) && !(options & SERIAL_BIDIR_PP_PD)) {
|
||||||
uartdev->txPinState = TX_PIN_ACTIVE;
|
uartdev->txPinState = TX_PIN_ACTIVE;
|
||||||
// Switch TX to an input with pullup so it's state can be monitored
|
// Switch TX to an input with pullup so it's state can be monitored
|
||||||
uartTxMonitor(s);
|
uartTxMonitor(s);
|
||||||
|
|
|
@ -707,12 +707,7 @@ bool vtxSmartAudioInit(void)
|
||||||
// the SA protocol instead requires pulldowns, and therefore uses SERIAL_BIDIR_PP_PD instead of SERIAL_BIDIR_PP
|
// the SA protocol instead requires pulldowns, and therefore uses SERIAL_BIDIR_PP_PD instead of SERIAL_BIDIR_PP
|
||||||
const serialPortConfig_t *portConfig = findSerialPortConfig(FUNCTION_VTX_SMARTAUDIO);
|
const serialPortConfig_t *portConfig = findSerialPortConfig(FUNCTION_VTX_SMARTAUDIO);
|
||||||
if (portConfig) {
|
if (portConfig) {
|
||||||
portOptions_e portOptions = SERIAL_STOPBITS_2 | SERIAL_BIDIR_NOPULL;
|
portOptions_e portOptions = SERIAL_STOPBITS_2 | SERIAL_BIDIR | SERIAL_BIDIR_PP_PD;
|
||||||
#if defined(USE_VTX_COMMON)
|
|
||||||
portOptions = portOptions | (vtxConfig()->halfDuplex ? SERIAL_BIDIR | SERIAL_BIDIR_PP_PD : SERIAL_UNIDIR);
|
|
||||||
#else
|
|
||||||
portOptions = SERIAL_BIDIR;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
smartAudioSerialPort = openSerialPort(portConfig->identifier, FUNCTION_VTX_SMARTAUDIO, NULL, NULL, 4800, MODE_RXTX, portOptions);
|
smartAudioSerialPort = openSerialPort(portConfig->identifier, FUNCTION_VTX_SMARTAUDIO, NULL, NULL, 4800, MODE_RXTX, portOptions);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue