1
0
Fork 0
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:
Steve Evans 2023-07-02 21:09:00 +01:00 committed by GitHub
parent 6ba117d69e
commit 1333771140
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 20 additions and 25 deletions

View file

@ -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);
} }
} }

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);
} }