Date
1 - 2 of 2
mps2_an521 UART interrupt issue
I am running Zephyr on an mps2_an521. I am having trouble with a very simple example that has three UARTs that are active.
One UART serves as a console and the other two UARTs provide a bidirectional passthrough. When the callback function is invoked due to data transfer, a single character at a time is read out of the UART's input FIFO and is pushed to the output FIFO of the other UART. I have tested this connection by pushing data through the UART at close to 1Mbaud without error.
If I enable the TX interrupt for one of the UARTs by calling uart_irq_tx_enable, I lose the bidirectional passthrough capability. Data is able to be pushed in one direction only. I am on occasion able to see a single byte pass through in the other direction after which no data passes through.
Why does enabling the tx interrupt break the receive interrupt?
I am using the default mps2_an521-common.dtsi and I don't see any interrupts that are shared.
void serial_cb(const struct device *dev, void *user_data)
{
uint8_t c;
if (!uart_irq_update(dev)) {
return;
}
while (uart_irq_rx_ready(dev)) {
uart_fifo_read(dev, &c, 1);
if (dev == uart_ros2) {
uart_fifo_fill(uart_tmc, &c, 1);
}
else if (dev == uart_tmc) {
uart_fifo_fill(uart_ros2, &c, 1);
}
else {
uart_fifo_fill(uart_ros2, &c, 1);
uart_fifo_fill(uart_tmc, &c, 1);
}
}
}
void main(void)
{
check_uart_ready(uart_console, "console");
check_uart_ready(uart_ros2, "ros2");
check_uart_ready(uart_tmc, "tmc");
/* configure interrupt and callback to receive data */
uart_irq_callback_user_data_set(uart_ros2, serial_cb, NULL);
uart_irq_rx_enable(uart_ros2);
/* The passthrough breaks if I uncomment the line below */
// uart_irq_tx_enable(uart_ros2);
uart_irq_callback_user_data_set(uart_tmc, serial_cb, NULL);
uart_irq_rx_enable(uart_tmc);
uart_irq_callback_user_data_set(uart_console, serial_cb, NULL);
uart_irq_rx_enable(uart_console);
while(true) {
;
}
}
nandojve@...
I got problems with mps2_an521. My workaround is:
Define ISR handler:
uart_irq_callback_user_data_set(dev, interrupt_handler, mydata);
if (uart_irq_rx_ready(dev)) {
if (uart_irq_tx_ready(dev)) {
At ISR handle process loop as below:
void interrupt_handler(const struct device *dev, void *dt)
{
struct user_data *data;
data = (struct user_data *) dt;
do {
uart_irq_update(dev);
{
struct user_data *data;
data = (struct user_data *) dt;
do {
uart_irq_update(dev);
if (uart_irq_rx_ready(dev)) {
process_rx(dev, data);
}
if (uart_irq_tx_ready(dev)) {
process_tx(dev, data);
}
} while (uart_irq_is_pending(dev));
}
}
See:
Em sex., 14 de out. de 2022 às 04:29, Michael Eskowitz via lists.zephyrproject.org <Michael_Eskowitz=yahoo.com@...> escreveu:
[Edited Message Follows]
I am running Zephyr on an mps2_an521. I am having trouble with a very simple example that has three UARTs that are active.One UART serves as a console and the other two UARTs provide a bidirectional passthrough. When the callback function is invoked due to data transfer, a single character at a time is read out of the UART's input FIFO and is pushed to the output FIFO of the other UART. I have tested this connection by pushing data through the UART at close to 1Mbaud without error.If I enable the TX interrupt for one of the UARTs by calling uart_irq_tx_enable, I lose the bidirectional passthrough capability. Data is able to be pushed in one direction only. I am on occasion able to see a single byte pass through in the other direction after which no data passes through.Why does enabling the tx interrupt break the receive interrupt?I am using the default mps2_an521-common.dtsi and I don't see any interrupts that are shared.void serial_cb(const struct device *dev, void *user_data){uint8_t c;if (!uart_irq_update(dev)) {return;}while (uart_irq_rx_ready(dev)) {uart_fifo_read(dev, &c, 1);if (dev == uart_ros2) {uart_fifo_fill(uart_tmc, &c, 1);}else if (dev == uart_tmc) {uart_fifo_fill(uart_ros2, &c, 1);}else {uart_fifo_fill(uart_ros2, &c, 1);uart_fifo_fill(uart_tmc, &c, 1);}}}void main(void){check_uart_ready(uart_console, "console");check_uart_ready(uart_ros2, "ros2");check_uart_ready(uart_tmc, "tmc");/* configure interrupt and callback to receive data */uart_irq_callback_user_data_set(uart_ros2, serial_cb, NULL);uart_irq_rx_enable(uart_ros2);/* The passthrough breaks if I uncomment the line below */// uart_irq_tx_enable(uart_ros2);uart_irq_callback_user_data_set(uart_tmc, serial_cb, NULL);uart_irq_rx_enable(uart_tmc);uart_irq_callback_user_data_set(uart_console, serial_cb, NULL);uart_irq_rx_enable(uart_console);while(true) {;}}