sw.teach.me
Posts: 3
Joined: Mon May 29, 2023 3:43 pm

UART TX produce endless interrupts.

Mon May 29, 2023 8:49 pm

Hello,

When transmitting the UART produce endless interrupts.
I edited the example "uart_advanced" to show the problem, it occurs with or without fifos enabled.

to show the problem on the oscilloscope I toggled gpio in the interrupt handler.
in the attached image:
- channel 1 is the uart tx line gpio (8)
- channel 2 is the interrupt handler gpio (16)

the code is attached also

How do I acknowlage the interrupt?
What I'm missing here?

Regards

Code: Select all

#include "pico/stdlib.h"
#include "hardware/uart.h"
#include "hardware/irq.h"
#include "hardware/gpio.h"


#define UART_ID			uart1
#define BAUD_RATE		115200
#define DATA_BITS		8
#define STOP_BITS		1
#define PARITY			UART_PARITY_NONE

#define UART_TX_PIN		8
#define UART_RX_PIN		9

#define D_GPIO_TEST		16


// interrupt handler
void on_uart_interrupt() {
	for( int i = 0; i < 8; ++i ) {
		gpio_put( D_GPIO_TEST, true ) ;
	}
	gpio_put( D_GPIO_TEST, false ) ;
}


int main() {
gpio_init( D_GPIO_TEST ) ;
gpio_set_dir( D_GPIO_TEST, GPIO_OUT ) ;
gpio_pull_up( D_GPIO_TEST ) ;
gpio_put( D_GPIO_TEST, false ) ;

   // Set up our UART with a basic baud rate.
    uart_init(UART_ID, 2400);

    // Set the TX and RX pins by using the function select on the GPIO
    // Set datasheet for more information on function select
    gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
    gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);

    // Actually, we want a different speed
    // The call will return the actual baud rate selected, which will be as close as
    // possible to that requested
    int __unused actual = uart_set_baudrate(UART_ID, BAUD_RATE);

    // Set UART flow control CTS/RTS, we don't want these, so turn them off
    uart_set_hw_flow(UART_ID, false, false);

    // Set our data format
    uart_set_format(UART_ID, DATA_BITS, STOP_BITS, PARITY);

    // Turn on FIFO's 
    //uart_set_fifo_enabled(UART_ID, true);

    // Set up a interrupt
    // We need to set up the handler first
    // Select correct interrupt for the UART we are using
    int UART_IRQ = UART_ID == uart0 ? UART0_IRQ : UART1_IRQ;

    // And set up and enable the interrupt handlers
    irq_set_exclusive_handler(UART_IRQ, on_uart_interrupt);
    irq_set_enabled(UART_IRQ, true);

    // Now enable the UART interrupts
    uart_set_irq_enables(UART_ID, false, true);

	sleep_ms( 10 ) ;

    uart_puts(UART_ID, "Hello uart\n");

    while (1)
        tight_loop_contents();
}
Attachments
uart_advanced.zip
(235.96 KiB) Downloaded 8 times

aalm
Posts: 36
Joined: Sun Apr 11, 2021 7:23 pm

Re: UART TX produce endless interrupts.

Tue May 30, 2023 12:53 am

sw.teach.me wrote:
Mon May 29, 2023 8:49 pm
How do I acknowlage the interrupt?
What I'm missing here?
Just guessing, and don't have time to see what is in the zip, but for uart_set_irq_enables() in the docs reads:
Parameters
uart UART instance. uart0 or uart1
rx_has_data If true an interrupt will be fired when the RX FIFO contains data.
tx_needs_data If true an interrupt will be fired when the TX FIFO needs data.
So, I think you should be feeding it from the interrupt to clear the condition? Or disable it if there's nothing to tx.

edit: btw. what you're doing in the irq handler doesn't really make any sense given there's even no delay within loop.
and with just added delay you'd have to be toggling the same pin from the other core while that loop is running to see any effect.

sw.teach.me
Posts: 3
Joined: Mon May 29, 2023 3:43 pm

Re: UART TX produce endless interrupts.

Tue May 30, 2023 6:43 am

Thanks for the response.

The zip file has the oscilloscope measurement image and the c source file, so you can try it on your board.

Regarding what I'm doing in the irq handler, you can't call sleep_us() within the handler it will hang the system so I'm creating delay via setting the GPIO to '1' logic again and again and than clearing it to '0' logic. this is just to toggle the pin to see the interrupt on the oscilloscope.

No matter what I'll do in irq handler, it still go crazy when transmitting.

PiGraham
Posts: 5352
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: UART TX produce endless interrupts.

Tue May 30, 2023 7:38 am

To toggle a gpio for diagnostics you can toggle it in a single instruction. DFo that each time on entry to the interrupt and you will see the timing of each irq as a new edge on your scope trace.

See https://www.raspberrypi.com/documentati ... 19f25ea7fd


tx interrupt should fire as soon as the TX buffer empties.

You probably need to disable the interrupt if you have nothing to send.

sw.teach.me
Posts: 3
Joined: Mon May 29, 2023 3:43 pm

Re: UART TX produce endless interrupts.

Fri Jun 02, 2023 10:15 pm

In order to clear (acknowladge) the interrupt feed the FIFO if you have additional data to transmit otherwise clear the tx interrupt.

see below how to clear the tx interrupt.

Code: Select all

// interrupt handler
void on_uart_interrupt() {

    // The missing line to clear the TX interrupt
    uart_get_hw(UART_ID)->icr = UART_UARTICR_TXIC_BITS ;

    for( int i = 0; i < 8; ++i ) {
        gpio_put( D_GPIO_TEST, true ) ;
    }
    gpio_put( D_GPIO_TEST, false ) ;
}

Return to “SDK”