/** * Definition of the UART isr */ void ISRUART(void* context, unsigned int id) { unsigned int stat; INT8U chr; //get serial status stat = IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE); //character receiving if (stat & ALTERA_AVALON_UART_STATUS_RRDY_MSK) { //Check if UART is ready to offer access to the RXDATA register chr = IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE); IOWR_ALTERA_AVALON_UART_STATUS(UART_0_BASE, 0); //clear the status bits again OSQPost(uartQsem, (void*) chr); //write new char in que } IOWR_ALTERA_AVALON_UART_STATUS(UART_0_BASE, 0); //reset interrupt }
void Uart_init() { IOWR_ALTERA_AVALON_UART_CONTROL(RS232_BASE,0x80); IOWR_ALTERA_AVALON_UART_STATUS(RS232_BASE,0x0); alt_irq_register(RS232_IRQ,NULL,Uart_ISR); }
int altera_avalon_uart_read(altera_avalon_uart_state* sp, char* ptr, int len, int flags) { int block; unsigned int status; block = !(flags & O_NONBLOCK); do { status = IORD_ALTERA_AVALON_UART_STATUS(sp->base); /* clear any error flags */ IOWR_ALTERA_AVALON_UART_STATUS(sp->base, 0); if (status & ALTERA_AVALON_UART_CONTROL_RRDY_MSK) { ptr[0] = IORD_ALTERA_AVALON_UART_RXDATA(sp->base); if (!(status & (ALTERA_AVALON_UART_STATUS_PE_MSK | ALTERA_AVALON_UART_STATUS_FE_MSK))) { return 1; } } } while (block); ALT_ERRNO = EWOULDBLOCK; return 0; }
void rt_hw_uart_init(void) { // init uart set_baudrate(115200); IOWR_ALTERA_AVALON_UART_CONTROL(RS232_BASE, 0x80);//接收中断使能 IOWR_ALTERA_AVALON_UART_STATUS(RS232_BASE, 0x0); // clean status alt_irq_register(RS232_IRQ, NULL, uart_isr); // register device uart_device.type = RT_Device_Class_Char; /* device interface */ uart_device.init = rt_uart_init; uart_device.open = rt_uart_open; uart_device.close = rt_uart_close; uart_device.read = rt_uart_read; uart_device.write = rt_uart_write; uart_device.control = rt_uart_control; uart_device.user_data = RT_NULL; uart_device.rx_indicate = RT_NULL; uart_device.tx_complete = RT_NULL; rt_device_register(&uart_device, "uart", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX); }
static unsigned char altera_avalon_uart_getc(serial_channel *chan) { altera_avalon_uart_dev *uart_chan = (altera_avalon_uart_dev *)chan->dev_priv; cyg_addrword_t port = uart_chan->base; cyg_uint32 status; unsigned char data; do { do { status = IORD_ALTERA_AVALON_UART_STATUS(port); /* clear any error flags */ IOWR_ALTERA_AVALON_UART_STATUS(port, 0); } while (!(status & ALTERA_AVALON_UART_CONTROL_RRDY_MSK)); data = (unsigned char) IORD_ALTERA_AVALON_UART_RXDATA(port); } while (status & (ALTERA_AVALON_UART_STATUS_PE_MSK | ALTERA_AVALON_UART_STATUS_FE_MSK)); return data; }
static void serial_irq_0(void* context, alt_u32 id) { unsigned int stat; INT8U chr; //get serial status stat = IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE); //character Rx if (stat & ALTERA_AVALON_UART_STATUS_RRDY_MSK) { chr = IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE); IOWR_ALTERA_AVALON_UART_STATUS(UART_0_BASE, 0); if (chr != 254) { OSQPost(qsemMsg, (void*) chr); } } IOWR_ALTERA_AVALON_UART_STATUS(UART_0_BASE, 0); }
static rt_err_t rt_uart_init (rt_device_t dev) { set_baudrate(115200); IOWR_ALTERA_AVALON_UART_CONTROL(RS232_BASE, 0x80);//接收中断使能 IOWR_ALTERA_AVALON_UART_STATUS(RS232_BASE, 0x0); // clean status rx_put_index = 0; rx_get_index = 0; return RT_EOK; }
/** * Initiating UART Core with: * 115200 Baudrate * refer to /documentation/n2cpu_nii51010.pdf for more info */ void diverInitUART(int baud) { //Each Bit in the control register enables an IRQ for a corresponding bit in the status register. int control = ALTERA_AVALON_UART_CONTROL_RRDY_MSK | //enable Read Interrupts ALTERA_AVALON_UART_CONTROL_E_MSK; //enable Exceptions for each Interrupt IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE, control); //write contorl bitmask in the control register IOWR_ALTERA_AVALON_UART_STATUS(UART_0_BASE, 0x00); //writing 0 in the status Register clears the dcts,e,toe,roe,brk,fe, and pe bits //writing up the Baudrate-divisor //setting Baudrate-divisor: div = clk / desired Baudrate + 0,5 int divisor = (int) (50000000 / baud + 0.5); //div will be 434 IOWR_ALTERA_AVALON_UART_DIVISOR(UART_0_BASE, divisor); //install IRQ service routine alt_irq_register(UART_0_IRQ, 0, (alt_isr_func) ISRUART); alt_irq_enable(UART_0_IRQ); }
static void vUARTInterruptHandler( void* context, alt_u32 id ) { alt_u32 status; /* Read the status register in order to determine the cause of the interrupt. */ status = IORD_ALTERA_AVALON_UART_STATUS( UART_BASE ); /* Clear any error flags set at the device */ IOWR_ALTERA_AVALON_UART_STATUS( UART_BASE, 0 ); /* process a read irq */ if ( status & ALTERA_AVALON_UART_STATUS_RRDY_MSK ) { vUARTReceiveHandler( status ); } /* process a write irq */ if ( status & ( ALTERA_AVALON_UART_STATUS_TRDY_MSK ) ) { vUARTTransmitHandler( status ); } }
/**************************************************************************** Function: void uart_init(long Address, unsigned char flag) Description: This function initializes the UART Precondition: None Parameters: long Address - UART Address unsigned char flag - Control-Flag Returns: None Remarks: None ***************************************************************************/ void uart_init(long Address, unsigned char flag) { IOWR_ALTERA_AVALON_UART_CONTROL(Address, flag); IOWR_ALTERA_AVALON_UART_STATUS(Address, 0x00); }
void uart_interrupt(void* context, unsigned long id) { IOWR_ALTERA_AVALON_UART_STATUS(UART_0_BASE, 0); }
static void altera_avalon_uart_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t handle) { cyg_uint32 status, save_status = 0; serial_channel *chan = (serial_channel *)handle; altera_avalon_uart_dev *uart_chan = (altera_avalon_uart_dev *)chan->dev_priv; cyg_addrword_t port = uart_chan->base; cyg_uint32 data; bool canXmit = false; int space_avail; unsigned char* space; for (;;) { int num; bool canReceive = (chan->callbacks->data_rcv_req)(chan, 4096, &space_avail, &space) == CYG_RCV_OK; num = space_avail; if (!canReceive) { /* drop all receive chars we can't keep up */ for (;;) { status = IORD_ALTERA_AVALON_UART_STATUS(port); save_status |= status; IOWR_ALTERA_AVALON_UART_STATUS(port, 0); if (!(status & ALTERA_AVALON_UART_STATUS_RRDY_MSK)) { goto xmit; } data = IORD_ALTERA_AVALON_UART_RXDATA(port); } } while (space_avail > 0) { /* * Read the status register in order to determine the cause of the * interrupt. */ status = IORD_ALTERA_AVALON_UART_STATUS(port); save_status |= status; /* Clear any error flags set at the device */ IOWR_ALTERA_AVALON_UART_STATUS(port, 0); /* process a read irq */ if (status & ALTERA_AVALON_UART_STATUS_RRDY_MSK) { data = IORD_ALTERA_AVALON_UART_RXDATA(port); /* pass the data to the higher layers only if there was no error */ if (!(status & (ALTERA_AVALON_UART_STATUS_PE_MSK | ALTERA_AVALON_UART_STATUS_FE_MSK))) { //(chan->callbacks->rcv_char)(chan, data); *space++=data; space_avail--; } } else { (chan->callbacks->data_rcv_done)(chan, num-space_avail); goto xmit; } } (chan->callbacks->data_rcv_done)(chan, num-space_avail); } xmit: /* process a write irq */ if (save_status & (ALTERA_AVALON_UART_STATUS_TRDY_MSK | ALTERA_AVALON_UART_STATUS_DCTS_MSK)) { (chan->callbacks->xmt_char)(chan); } cyg_drv_interrupt_unmask(vector); }