Forum Discussion
Altera_Forum
Honored Contributor
19 years agoHi Tyrone,
So you enable the Tx IRQ during init, this will immidiately generate an interrupt (assuming the ISR has been registered) because the UART Tx holding register is empty. Your Tx ring is also, presumably, empty so what does the ISR do? I'm assuming the ISR writes to the status register in order to clear the source of the interrupt (otherwise you would keep re-entering the ISR), if this is the case then what is the mechanism to make interrupts happen again after you put something in the ring? The following works for me, maybe you can compare stuff. The first section is my init function, the second is my function to put characters into the ring and the third is the ISR. Note, I've bypassed the INDESCRIBABLY_TEDIOUS_ALTERA_IO_DEVICE_DEFINITIONS and gone for the IORD and IOWR functions directly (and used numbers!). void serial_init(unsigned int channel, unsigned int baud) { unsigned int i; /* inhibit all IRQ sources */ IOWR(UART_1_BASE, 3, 0x00); /* empty the Rx and Tx buffers */ rx_in_index_0 = rx_out_index_0 = 0; tx_in_index_0 = tx_out_index_0 = 0; rx_overrun_0 = 0; /* set Baud rate */ IOWR(UART_1_BASE, 4, baud); /* flush any characters sitting in the holding register */ i = IORD(UART_1_BASE, 0); i = IORD(UART_1_BASE, 0); /* reset most of the status register bits */ IOWR(UART_1_BASE, 2, 0x00); /* install IRQ service routine */ alt_irq_register(UART_1_IRQ, 0, serial_irq_0); /* enable irq for Rx. */ IOWR(UART_1_BASE, 3, 0x0080); } void tx_char(unsigned int channel, unsigned char txch) { unsigned int temp; while (((tx_in_index_0+1) & TXB_SIZE_MASK) == tx_out_index_0) ; txring_0[tx_in_index_0] = txch; tx_in_index_0++; tx_in_index_0 &= TXB_SIZE_MASK; temp = IORD(UART_1_BASE, 3); IOWR(UART_1_BASE, 3, (temp | 0x40)); } static void serial_irq_0(void* context, alt_u32 id) { unsigned int stat, chr, temp; /* get serial status */ stat = IORD(UART_1_BASE, 2); /* character Rx */ if (stat & 0x0080) { chr = IORD(UART_1_BASE, 0); (*rx_vect_0)(chr); if (((rx_in_index_0+1) & RXB_SIZE_MASK) != rx_out_index_0) { rxring_0[rx_in_index_0] = (unsigned char)chr; rx_in_index_0++; rx_in_index_0 &= RXB_SIZE_MASK; } else rx_overrun_0 = 1; } /* character Tx */ if (stat & 0x0040) { if (tx_in_index_0 == tx_out_index_0) { /* buffer is empty, turn off Tx irq */ temp = IORD(UART_1_BASE, 3); IOWR(UART_1_BASE, 3, (temp&(~0x40))); } else { /* send next character */ IOWR(UART_1_BASE, 1, txring_0[tx_out_index_0]); tx_out_index_0++; tx_out_index_0 &= TXB_SIZE_MASK; } } } Banx.