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); }
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ) { /* Create the queues used to hold Rx and Tx characters. */ xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) ); xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed char ) ); /* If the queues were created correctly then setup the serial port hardware. */ if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) ) { portENTER_CRITICAL(); { uartControl = ALTERA_AVALON_UART_CONTROL_RTS_MSK | ALTERA_AVALON_UART_CONTROL_RRDY_MSK | ALTERA_AVALON_UART_CONTROL_DCTS_MSK; IOWR_ALTERA_AVALON_UART_CONTROL( UART_BASE, uartControl ); /* register the interrupt handler */ alt_irq_register ( UART_IRQ, NULL, vUARTInterruptHandler ); } portEXIT_CRITICAL(); } else { return ( xComPortHandle ) 0; } return ( xComPortHandle ) 1; }
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); }
bool altera_avalon_uart_init(struct cyg_devtab_entry *tab) { serial_channel *chan = (serial_channel *)tab->priv; altera_avalon_uart_dev *uart_chan = (altera_avalon_uart_dev *)chan->dev_priv; (chan->callbacks->serial_init)(chan); /* enable interrupts at the device */ if (chan->out_cbuf.len != 0) { cyg_drv_interrupt_create(uart_chan->irq, 99, /* Priority - unused */ (cyg_addrword_t)chan, /* Data item passed to interrupt handler */ altera_avalon_uart_ISR, altera_avalon_uart_DSR, &uart_chan->serial_interrupt_handle, &uart_chan->serial_interrupt); cyg_drv_interrupt_attach(uart_chan->serial_interrupt_handle); IOWR_ALTERA_AVALON_UART_CONTROL(uart_chan->base, ALTERA_AVALON_UART_CONTROL_RTS_MSK | ALTERA_AVALON_UART_CONTROL_RRDY_MSK | ALTERA_AVALON_UART_CONTROL_DCTS_MSK); cyg_drv_interrupt_unmask(uart_chan->irq); } return true; }
static void altera_avalon_uart_stop_xmit(serial_channel *chan) { cyg_uint32 ctrl; altera_avalon_uart_dev *uart_chan = (altera_avalon_uart_dev *)chan->dev_priv; ctrl = IORD_ALTERA_AVALON_UART_CONTROL(uart_chan->base); IOWR_ALTERA_AVALON_UART_CONTROL(uart_chan->base, ctrl & ~(ALTERA_AVALON_UART_CONTROL_TRDY_MSK | ALTERA_AVALON_UART_CONTROL_DCTS_MSK)); }
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; }
static void vUARTTransmitHandler( alt_u32 status ) { signed char cChar; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; /* Transfer data if there is some ready to be transferred */ if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE ) { IOWR_ALTERA_AVALON_UART_TXDATA( UART_BASE, cChar ); } else { uartControl &= ~ALTERA_AVALON_UART_CONTROL_TRDY_MSK; } IOWR_ALTERA_AVALON_UART_CONTROL( UART_BASE, uartControl ); portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); }
/** * 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); }
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime ) { signed portBASE_TYPE lReturn = pdPASS; /* Place the character in the queue of characters to be transmitted. */ if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) == pdPASS ) { /*Triggers an interrupt on every character or (down) when queue is full. */ uartControl |= ALTERA_AVALON_UART_CONTROL_TRDY_MSK; IOWR_ALTERA_AVALON_UART_CONTROL( UART_BASE, uartControl ); lReturn = pdPASS; } else { lReturn = pdFAIL; } return lReturn; }
signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime ) { /* The port handle is not required as this driver only supports one port. */ ( void ) pxPort; /* Get the next character from the buffer. Return false if no characters are available, or arrive before xBlockTime expires. */ if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) ) { return pdTRUE; } else { uartControl |= ALTERA_AVALON_UART_CONTROL_RRDY_MSK; IOWR_ALTERA_AVALON_UART_CONTROL( UART_BASE, uartControl ); return pdFALSE; } }
static void vUARTReceiveHandler( alt_u32 status ) { signed char cChar; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; /* If there was an error, discard the data */ if ( status & ( ALTERA_AVALON_UART_STATUS_PE_MSK | ALTERA_AVALON_UART_STATUS_FE_MSK ) ) { asm("break"); return; } /* Transfer data from the device to the circular buffer */ cChar = IORD_ALTERA_AVALON_UART_RXDATA( UART_BASE ); if ( pdTRUE != xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken ) ) { /* If the circular buffer was full, disable interrupts. Interrupts will be re-enabled when data is removed from the buffer. */ uartControl &= ~ALTERA_AVALON_UART_CONTROL_RRDY_MSK; IOWR_ALTERA_AVALON_UART_CONTROL( UART_BASE, uartControl ); } portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); }
/**************************************************************************** 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); }
int altera_avalon_uart_read(altera_avalon_uart_state* sp, char* ptr, int len, int flags) { alt_irq_context context; int block; alt_u8 read_would_block = 0; int count = 0; /* * Construct a flag to indicate whether the device is being accessed in * blocking or non-blocking mode. */ block = !(flags & O_NONBLOCK); /* * When running in a multi threaded environment, obtain the "read_lock" * semaphore. This ensures that reading from the device is thread-safe. */ ALT_SEM_PEND (sp->read_lock, 0); /* * Loop, copying data from the circular buffer to the destination address * supplied in "ptr". This loop is terminated when the required number of * bytes have been read. If the circular buffer is empty, and no data has * been read, then the loop will block (when in blocking mode). * * If the circular buffer is empty, and some data has already been * transferred, or the device is being accessed in non-blocking mode, then * the loop terminates without necessarily reading all the requested data. */ do { /* * Read the required amount of data, until the circular buffer runs * empty */ while ((count < len) && (sp->rx_start != sp->rx_end)) { count++; *ptr++ = sp->rx_buf[sp->rx_start]; sp->rx_start = (sp->rx_start+1) & ALT_AVALON_UART_BUF_MSK; } /* * If no data has been transferred, the circular buffer is empty, and * this is not a non-blocking access, block waiting for data to arrive. */ if (!count && (sp->rx_start == sp->rx_end)) { if (!block) { /* Set errno to indicate the reason we're not returning any data */ ALT_ERRNO = EWOULDBLOCK; read_would_block = 1; break; } else { /* Block waiting for some data to arrive */ /* First, ensure read interrupts are enabled to avoid deadlock */ context = alt_irq_disable_all (); sp->ctrl |= ALTERA_AVALON_UART_CONTROL_RRDY_MSK; IOWR_ALTERA_AVALON_UART_CONTROL(sp->base, sp->ctrl); alt_irq_enable_all (context); /* * When running in a multi-threaded mode, we pend on the read event * flag set in the interrupt service routine. This avoids wasting CPU * cycles waiting in this thread, when we could be doing something more * profitable elsewhere. */ ALT_FLAG_PEND (sp->events, ALT_UART_READ_RDY, OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME, 0); } } } while (!count && len); /* * Now that access to the circular buffer is complete, release the read * semaphore so that other threads can access the buffer. */ ALT_SEM_POST (sp->read_lock); /* * Ensure that interrupts are enabled, so that the circular buffer can * re-fill. */ context = alt_irq_disable_all (); sp->ctrl |= ALTERA_AVALON_UART_CONTROL_RRDY_MSK; IOWR_ALTERA_AVALON_UART_CONTROL(sp->base, sp->ctrl); alt_irq_enable_all (context); /* Return the number of bytes read */ if(read_would_block) { return -EWOULDBLOCK; } else { return count; } }