Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12627 Discussions

UART gets stuck when enabling IRQ (NIOS II)

Vincent_F
Beginner
181 Views

Hi,

I'm reopening an old post from 2013 that apparently never got a reply.

I'm facing the same problem. I have a small NIOS II system (used as a demo for my students) that features a jTAG UART and a standard UART. I use the jTAG UART as my stdin/out etc. and run the program from a terminal (either Eclipse or NIOS command shell) to send and receive data from the standard UART. When I use the file mode (i.e. open a file to the UART to use fprintf, fgets, etc.) everything works well, I can send and receive data to and from the UART. But when I register an IRQ for the UART, the file mode doesn't work anymore. Note that my program checks the status register until the UART is ready to send or receive data before calling fprintf. I tried to disable the UART IRQ before fprintf and event tried to unregister the IRQ (using alt_ac_irq_register(UART_ID, UART_IRQ, NULL, NULL, NULL);). Nothing would work.

 

Below is the program. I run it on a DE10-Lite board interfaced with an RFS2 board, which features the UART. In this configuration (no IRQ registered) I'm able to send data. When the RFS2_UART_init(); line is uncommented (in main), the program gets stuck in an interrupt, even when no data is received by the UART. Uncommenting the following lines has no effect:

//alt_ic_irq_disable(RFS2_UART_IRQ_INTERRUPT_CONTROLLER_ID,RFS2_UART_IRQ);
//alt_ic_isr_register(RFS2_UART_IRQ_INTERRUPT_CONTROLLER_ID, RFS2_UART_IRQ, NULL, NULL, NULL);
//IOWR_ALTERA_AVALON_UART_CONTROL(RFS2_UART_BASE, 0);

Note that, when using the direct TX macro, everything works like a charm. Still, I would like to understand why fprintf won't work when registering (and unregistering...!) the IRQ. Any advice, solution or explanation would be appreciated.

Best regards

Vincent

 

// Test program

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <io.h>
#include "system.h"
#include "altera_avalon_uart_regs.h"
#include "altera_avalon_uart.h"
#include "sys/alt_irq.h"
#include "terasic_includes.h"

#define MAX_BUFFER_SIZE 1024

FILE *fJTAG;
FILE *fUART;

char buffer[MAX_BUFFER_SIZE];
static volatile int buffer_index = 0;

// Définition du contexte
static volatile int context;
volatile int uart_flag;

// Fonction d'interruption de service (ISR)
#ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT
static void UART_ISR(void* context)
#else
static void UART_ISR(void* context, alt_u32 id)
#endif
//void UART_ISR(void* context)
{
// Read data received by UART
char received = IORD_ALTERA_AVALON_UART_RXDATA(RFS2_UART_BASE);
// printf("carac %c\r\n",received);

// Check interrupt acknowledgement
// if ((IORD_ALTERA_AVALON_UART_STATUS(RFS2_UART_BASE) & ALTERA_AVALON_UART_STATUS_RRDY_MSK) == 0) {
// printf("IRQ acknowledged.\n");
// NULL;
// } else {
// printf("IRQ error.\n");
// }

// Store data in buffer
if (buffer_index < MAX_BUFFER_SIZE - 1) {
buffer[buffer_index++] = received;
}

// Check end of chain
if (received == '\0') {
uart_flag = 1;
// printf("End of chain received.\n");
}
}

// Initialize UART
void RFS2_UART_init(void) {
void *uart_context = (void *) context;

// Configure UART, activate RX IRQ
IOWR_ALTERA_AVALON_UART_CONTROL(RFS2_UART_BASE, ALTERA_AVALON_UART_CONTROL_RRDY_MSK);

// Deactivate TX IRQ
int control = IORD_ALTERA_AVALON_UART_CONTROL(RFS2_UART_BASE);
control &= ~ALTERA_AVALON_UART_CONTROL_TRDY_MSK;
IOWR_ALTERA_AVALON_UART_CONTROL(RFS2_UART_BASE, control);

// Configure IRQ
alt_ic_isr_register(RFS2_UART_IRQ_INTERRUPT_CONTROLLER_ID, RFS2_UART_IRQ, UART_ISR, uart_context, 0);
}

// Send chain to UART
void UART_write(char * out_data, int length) {

int control;
int status;

bool token = false;
// Open UART file
if (fUART != NULL) {
NULL;
} else {
printf("Opening fUART\n");
fUART = fopen(RFS2_UART_NAME, "w");
token = true;
}

// Read part of file to send
char *out_buffer = malloc(length + 3);
out_buffer = out_data;
out_buffer[length] = '\0'; // add "End of chain" character
/
// Using direct TX macro (works like a charm…!)
/* while (*out_buffer) {
// Send character on UART
IOWR_ALTERA_AVALON_UART_TXDATA(RFS2_UART_BASE, *out_buffer++);
// Wait until character has been sent
while ((IORD_ALTERA_AVALON_UART_STATUS(RFS2_UART_BASE) & ALTERA_AVALON_UART_STATUS_TRDY_MSK) == 0);
} */

// TX via fprintf (does not work :-(..!)
while(IORD_ALTERA_AVALON_UART_STATUS(RFS2_UART_NAME) & ALTERA_AVALON_UART_STATUS_RRDY_MSK) {
// Read the data to clear the IRQ
(void)IORD_ALTERA_AVALON_UART_RXDATA(RFS2_UART_NAME);
}
while ((IORD_ALTERA_AVALON_UART_STATUS(RFS2_UART_BASE) & ALTERA_AVALON_UART_STATUS_TRDY_MSK) == 0) {
IOWR_ALTERA_AVALON_UART_TXDATA(RFS2_UART_BASE, '\0');
}
if (fflush(fUART) == 0) {
printf("fflush succeeded\n");
} else {
printf("fflush failed\n");
}
fflush(stdout);
// Check if ready for TX
if (IORD_ALTERA_AVALON_UART_STATUS(RFS2_UART_BASE) & ALTERA_AVALON_UART_STATUS_TRDY_MSK) {
printf("UART is ready to accept data\n");
status = IORD_ALTERA_AVALON_UART_STATUS(RFS2_UART_BASE);
control = IORD_ALTERA_AVALON_UART_CONTROL(RFS2_UART_BASE);
printf("status %x\r\n",status);
printf("control %x\r\n",control);
// TX chain via file ==> THAT WERE THINGS GO BAD..!
fprintf(fUART, "%s\r\n", out_buffer);
} else {
printf("UART is not ready to accept data\n");
}
// alt_ic_irq_enable(RFS2_UART_IRQ_INTERRUPT_CONTROLLER_ID,RFS2_UART_IRQ);

// Close UART file
if (token == true) {
fflush(fUART);
fclose(fUART);
if (fclose(fUART) != EOF) {
printf("fUART closed\n");
fUART = NULL; // Successfully closed the file
} else {
printf("Failed to close file: %s\n", strerror(errno));
}
token = false;
}

}

int main() {

bool token = false;
int length = 0;
int length_of_str = 0;
int control;
int status;
char WFT_buffer[MAX_BUFFER_SIZE];

uart_flag = 0;
printf("Hello NIOS!\r\n");

// Initialize UART
//RFS2_UART_init();

if (fJTAG != NULL) {
NULL;
} else {
printf("Opening fJTAG\n");
fJTAG = fopen(JTAG_UART_NAME, "rw+");
token = true;
}

while (1){

if (uart_flag == 1) {
printf("Received data: %s\r\n", buffer);
buffer_index = 0;
uart_flag = 0;
} else {
printf("Enter text:");
if (fgets(WFT_buffer + length, sizeof(WFT_buffer) - length,
fJTAG) != NULL)
{
if (strstr(WFT_buffer + length, "\n") != NULL)
{
status = IORD_ALTERA_AVALON_UART_STATUS(RFS2_UART_BASE);
control = IORD_ALTERA_AVALON_UART_CONTROL(RFS2_UART_BASE);
printf("status %x\r\n",status);
printf("control %x\r\n",control);
// strcat(WFT_buffer, "\r\n");
length_of_str = strlen(WFT_buffer);
//alt_ic_irq_disable(RFS2_UART_IRQ_INTERRUPT_CONTROLLER_ID,RFS2_UART_IRQ);
//alt_ic_isr_register(RFS2_UART_IRQ_INTERRUPT_CONTROLLER_ID, RFS2_UART_IRQ, NULL, NULL, NULL);
//IOWR_ALTERA_AVALON_UART_CONTROL(RFS2_UART_BASE, 0);
UART_write(WFT_buffer, length_of_str);
length = 0;
} else length += strlen(WFT_buffer + length);
}
}


}

if (token == true) {
fflush(fJTAG);
fclose(fJTAG);
if (fclose(fJTAG) != EOF) {
fJTAG = NULL; // Successfully closed the file
} else {
printf("Failed to close file: %s\n", strerror(errno));
}
token = false;
}

return 0;
}

0 Kudos
4 Replies
JingyangTeh
Employee
83 Views

HI


From the code I see that you are are enabling the interrupt for transmit ready.

Could you try to enable disable that and enable the Read ready mask instead.

ALTERA_AVALON_UART_CONTROL_TRDY_MSK <--- Transmit Ready Mask

ALTERA_AVALON_UART_CONTROL_RRDY_MSK < ---- Read Ready Mask


Regards

Jingyang, Teh


0 Kudos
Vincent_F
Beginner
55 Views

Hi,

Thanks for your suggestion. Unfortunately, I've already tried it and it won't work either. Whatever the interrupt (transmit or read) the symptoms are the same.

Best regards

Vincent

0 Kudos
JingyangTeh
Employee
19 Views

Hi


Could you try out the example design below on your board?

The example design is using uart in interrupt mode.


Regards

Jingyang, Teh


0 Kudos
Vincent_F
Beginner
10 Views

Hi,

Thanks for your reply. I can try your example but I can't see any source file. Could you check if the files or code were attached to your reply?

Best regards

Vincent

0 Kudos
Reply