Open mkolchurin opened 2 years ago
Could PR #40907 help ?
The LL_USART_SetTransferDirection is set in both Tx and RX during the uart_stm32_init When disabling the Rx, we expect the LL_USART_DIRECTION_TX is still present, and at one point, the LL_USART_DIRECTION_RX should be restored.
I guess that controlling the direction is possible keeping the LL_USART_GetTransferDirection uart_stm32_irq_rx_disable --> reset LL_USART_DIRECTION_RX but keep LL_USART_DIRECTION_TX if present uart_stm32_irq_rx_enable --> set LL_USART_DIRECTION_RX and keep LL_USART_DIRECTION_TX if present uart_stm32_irq_tx_disable --> reset LL_USART_DIRECTION_TX but keep LL_USART_DIRECTION_RX if present uart_stm32_irq_tx_enable --> set LL_USART_DIRECTION_TX and keep LL_USART_DIRECTION_RX if present
I extended the standard Zephyr API with the function
int uart_direction(const struct device *dev, uint8_t dir);
which chooses one of three directions
enum uart_config_direction{
UART_CFG_RX_DIRECTION,
UART_CFG_TX_DIRECTION,
UART_CFG_RX_TX_DIRECTION,
};
and added this to modbus_serial_rx_on, modbus_serial_tx_on and modbus_serial_disable (UART_CFG_RX_TX_DIRECTION)
I don't know if it's necessary or possible to create a pull request to extend the standard API, but this solved the problem
I think so. Maybe you could test with this change : https://github.com/FRASTM/zephyr/commit/190c3f881a5546d9b78ca90eedec13729cbdc005
I extended the standard Zephyr API with the function
int uart_direction(const struct device *dev, uint8_t dir);
which chooses one of three directions
enum uart_config_direction{ UART_CFG_RX_DIRECTION, UART_CFG_TX_DIRECTION, UART_CFG_RX_TX_DIRECTION, };
and added this to modbus_serial_rx_on, modbus_serial_tx_on and modbus_serial_disable (UART_CFG_RX_TX_DIRECTION)
I don't know if it's necessary or possible to create a pull request to extend the standard API, but this solved the problem
@dcpleung @jfischer-no do you think this solution is worth pushing ?
https://github.com/FRASTM/zephyr/commit/190c3f881a5546d9b78ca90eedec13729cbdc005
Thanks for the answer! I can't test right now but will definitely do so tomorrow. I think it will work in this case, but uart_stm32_poll_in will not work after calling uart_stm32_irq_rx_disable (but I don't know if there is a scenario when it is necessary to use polling and interrupts at the same time)
Here are the changes that I think should be made: uart: https://github.com/mkolchurin/zephyr/commit/bb9f3f92e2fd0fe0e137e51a6e9a79040ccaf008 modbus: https://github.com/mkolchurin/zephyr/commit/ca0c3064a5c9e82dc6244de57ad5736b235bd490
@dcpleung @jfischer-no do you think this solution is worth pushing ?
What is "Selects direction of UART", does it change TX and RX lines? That is probably RS-485 specific and should be prefixed / abstracted accordingly. NACK for MODBUS RTU changes, that should be solved differently, there is already bus transceiver control over GPIO lines.
Changing this from 'Bug' to 'Enhancement' and removing STM32 tag is this is likely generic .
Hi we experienced a similar problem with the uart driver (v2.7.x) in order integrate a third party IO-Link core stack. which requires direct control over the different irqs rx, tx-empty, tx-complete at rather high speed, low latency (IO-Link COM2 @ 230kBaud Allowed gaps: 1 TBit @ 230kBaud approx. 4.3 us rx byte gap: max 1 TBit (which is not so much "our" Zepyhr OS firmware side) rx - tx response gap : 1 - 10 Tbit tx byte gap: max. 3Tbit
We have written a STM32 specific extension in our company internal framework, but would be happy to see that or similar implemented in Zephyr OS directly and not for STM32 only.
When trying to start modbus on a device with a st485bdr transceiver, where receive is constantly active (RE always low, DE controls by software), a busfault occurs during transmission. This problem occurs on both STM32F105 and STM32F427 boards.
I was able to determine that when waiting for a transmit complete interrupt (TC) and before turning off transmit mode (after all bytes have been sent to the shift register), an unexpected receive interrupt occurs that sends the device into a busfault. I think this is due to the fact that the signal transmitted to the RS485 line is also present at the RO output and creates interference.
I added to the existing disable/enable interrupt functions (in uart_stm32.c) disable/enable the transmitter and receiver:
after which modbus worked, however, I understand the problems of this solution, and I hope there is a successful solution to this problem.