예제 #1
0
파일: uart.c 프로젝트: hezlog/rt-thread
static int fh_uart_putc(struct rt_serial_device *serial, char c)
{
    struct fh_uart *uart = serial->parent.user_data;
    unsigned int ret;
    ret = uart_get_status(uart->uart_port);
    if(serial->parent.open_flag & RT_DEVICE_FLAG_INT_TX) {
        //RT_DEVICE_FLAG_INT_TX

        if(c == '\n') {
            fh_uart_putc(serial,'\r');
        }
        if(ret & UART_USR_TFNF) {
            uart_putc(uart->uart_port, c);
            return 1;
        }
        //open tx isr here..
        uart_enable_irq(uart->uart_port,UART_IER_ETBEI);
        return -1;
    }
    //poll mode
    else {

        while(!(uart_get_status(uart->uart_port) & UART_USR_TFNF))
            ;
        uart_putc(uart->uart_port, c);
        return 1;


    }



}
예제 #2
0
파일: uart.c 프로젝트: hezlog/rt-thread
void rt_fh_uart_handler(int vector, void *param)
{
    int status;
    unsigned int ret;
    struct fh_uart *uart;
    unsigned int reg_status;
    rt_device_t dev = (rt_device_t)param;
    uart = (struct fh_uart *)dev->user_data;
    status = uart_get_iir_status(uart->uart_port);
    if (status & UART_IIR_NOINT)
    {
        return;
    }
    if(status & UART_IIR_THREMPTY) {
        //first close tx isr
        uart_disable_irq(uart->uart_port,UART_IER_ETBEI);

        rt_hw_serial_isr((struct rt_serial_device *)dev, RT_SERIAL_EVENT_TX_DONE);
    }
    else if((status & UART_IIR_CHRTOUT)==UART_IIR_CHRTOUT) {
        //bug....
        //if no data in rx fifo
        reg_status = uart_get_status(uart->uart_port);
        if((reg_status & 1<<3) == 0)
            ret = uart_getc(uart->uart_port);
    }
    else {
        rt_interrupt_enter();
        rt_hw_serial_isr((struct rt_serial_device *)dev, RT_SERIAL_EVENT_RX_IND);
        rt_interrupt_leave();
    }
}
예제 #3
0
void UART_Handler(void)
{
    tUartControl *pControl;
	uint32_t ul_status;
	uint8_t c;

	pControl = uart_control[0]; 

	/* Read UART Status. */
	ul_status = uart_get_status(UART);

	if (ul_status & UART_SR_RXRDY)
	{
		uart_read(UART, &c);
		
		/* Check if buffer has more space
		 * If no space, data will be discarded
		 */
		if (str_buf_is_full (&pControl->rx_buffer))
        {
            pControl->rx_buffer.header.err_overflow = 1;
        }
        else
        {
            str_buf_putc (&pControl->rx_buffer, c);
		}
	}
	
	if (ul_status & UART_SR_TXRDY)
	{
		uart_disable_interrupt (UART, UART_IER_TXRDY);

    	while (!str_buf_is_empty (&pControl->tx_buffer))
        {
            c = str_buf_getc (&pControl->tx_buffer);
            uart_write (pControl->uart_def_p, c);
    
            if ( !uart_is_tx_ready (pControl->uart_def_p) )
                break;
        }
        
        /* If there is no more data to send, disable the transmit
            interrupt - else enable it or keep it enabled */
	    if (str_buf_is_empty (&pControl->tx_buffer)) 
        {
		    uart_disable_interrupt (UART, UART_IER_TXRDY);
            pControl->TxIntEnabled = false;
        }
        else
        {
            // Set Tx Interrupt state
            pControl->TxIntEnabled = true;
            uart_enable_interrupt (UART, UART_IER_TXRDY);
        }

	} //
	
}
예제 #4
0
/**
 * \brief Interrupt handler for UART interrupt.
 */
void console_uart_irq_handler(void)
{
	/* Get UART status and check if CMP is set */
	if (uart_get_status(CONSOLE_UART) & UART_SR_CMP) {
		cmp_flag = 1;
		/* Disable UART IRQ */
		uart_disable_interrupt(CONSOLE_UART, UART_IDR_CMP);
	}
}
예제 #5
0
/**
 * \brief Interrupt handler for UART interrupt.
 */
void console_uart_irq_handler(void)
{
	/* Get UART status and check if PDC receive buffer is full */
	if ((uart_get_status(CONSOLE_UART) & UART_SR_RXBUFF) == UART_SR_RXBUFF) {
		/* Configure PDC for data transfer (RX and TX) */
		pdc_rx_init(g_p_uart_pdc, &g_pdc_uart_packet, NULL);
		pdc_tx_init(g_p_uart_pdc, &g_pdc_uart_packet, NULL);
	}
}
예제 #6
0
파일: buart_if.c 프로젝트: Realtime-7/asf
/** @brief	Interruption handler for UART1
 *
 */
void UART1_Handler(void)
{
	uint32_t ul_status;
	uint16_t us_wr_idx, us_data_count;
	uint16_t us_end_size, us_free_size, us_part_size;

	/* Read USART Status. */
	ul_status = uart_get_status(UART1);

	/* Receive buffer is full. */
	if (ul_status & US_CSR_ENDRX) {
		/* manage data */
		us_wr_idx = buart_comm_data_1.us_wq_idx;
		us_data_count = buart_comm_data_1.us_rq_count;
		us_free_size = RX_UART_BUF1_SIZE - us_data_count;
		if (gs_ul_size_uart_buf1 <= us_free_size) {
			/* there is enough space to write all data */
			us_end_size = RX_UART_BUF1_SIZE - us_wr_idx;
			if (us_end_size >= gs_ul_size_uart_buf1) {
				/* there is no overflow of us_wq_idx */
				memcpy(&buart_comm_data_1.puc_rq_buf[us_wr_idx],
						gs_puc_uart_buf1, gs_ul_size_uart_buf1);
				/* update counters */
				buart_comm_data_1.us_rq_count += gs_ul_size_uart_buf1;
				buart_comm_data_1.us_wq_idx += gs_ul_size_uart_buf1;
			} else {
				/* there is overflow of us_wq_idx -> write in 2
				 * steps	*/
				memcpy(&buart_comm_data_1.puc_rq_buf[us_wr_idx],
						gs_puc_uart_buf1, us_end_size);
				us_part_size = gs_ul_size_uart_buf1 - us_end_size;
				memcpy(&buart_comm_data_1.puc_rq_buf[0],
						&gs_puc_uart_buf1[us_end_size], us_part_size);
				/* update counters */
				buart_comm_data_1.us_rq_count += gs_ul_size_uart_buf1;
				buart_comm_data_1.us_wq_idx = us_part_size;
			}
		} else { /* there is not enough space to write all data */
			tc_start(TC_UART, TC_UART_CHN);
		}

		/* change RX buffer */
		gs_ul_size_uart_buf1 = UART_BUFFER_SIZE;

		/* Restart read on buffer. */
		g_st_uart_rx_packet1.ul_addr = (uint32_t)gs_puc_uart_buf1;
		g_st_uart_rx_packet1.ul_size = UART_BUFFER_SIZE;
		pdc_rx_init(g_p_uart_pdc1, &g_st_uart_rx_packet1, NULL);

		/* Restart timer. */
		tc_start(TC_UART, TC_UART_CHN);
	}
}
예제 #7
0
void UART0_Handler (void){	
	uint32_t ul_status;
	ul_status = uart_get_status(UART0);
	
	if (ul_status & UART_SR_RXRDY){
		uart_read(UART0, &uc_char);
		if (cont_char == 0){
			clear_keys();
		}
		//Fim do comando, character "Enter"
		if (uc_char == 13){
			cont_char = 0;
			uc_flag = 1;
		} 
		//Implementando Backspace:
		else if ( uc_char == 8 ){
			keys[--cont_char] = 0;
		}
		else {
			keys[cont_char++] = uc_char;
		}
	}
}
/*
 * For internal use only.
 * A common UART interrupt handler that is called for all UART peripherals.
 */
static void local_uart_handler(const portBASE_TYPE uart_index)
{
	portBASE_TYPE higher_priority_task_woken = pdFALSE;
	uint32_t uart_status;
	freertos_pdc_rx_control_t *rx_buffer_definition;

	uart_status = uart_get_status(
			all_uart_definitions[uart_index].peripheral_base_address);
	uart_status &= uart_get_interrupt_mask(
			all_uart_definitions[uart_index].peripheral_base_address);

	rx_buffer_definition = &(rx_buffer_definitions[uart_index]);

	/* Has the PDC completed a transmission? */
	if ((uart_status & UART_SR_ENDTX) != 0UL) {
		uart_disable_interrupt(
				all_uart_definitions[uart_index].peripheral_base_address,
				UART_IDR_ENDTX);

		/* If the driver is supporting multi-threading, then return the access
		mutex. */
		if (tx_dma_control[uart_index].peripheral_access_mutex != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[uart_index].peripheral_access_mutex,
					&higher_priority_task_woken);
		}

		/* if the sending task supplied a notification semaphore, then
		notify the task that the transmission has completed. */
		if (tx_dma_control[uart_index].transaction_complete_notification_semaphore != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[uart_index].transaction_complete_notification_semaphore,
					&higher_priority_task_woken);
		}
	}

	if ((uart_status & UART_SR_ENDRX) != 0UL) {
		/* It is possible to initialise the peripheral to only use Tx and not Rx.
		Check that Rx has been initialised. */
		configASSERT(rx_buffer_definition->next_byte_to_read);
		configASSERT(rx_buffer_definition->next_byte_to_read !=
				RX_NOT_USED);

		/* Out of DMA buffer, configure the next buffer.  Start by moving
		the DMA buffer start address up to the end of the previously defined
		buffer. */
		rx_buffer_definition->rx_pdc_parameters.ul_addr +=
				rx_buffer_definition->rx_pdc_parameters.ul_size;

		/* If the end of the buffer has been reached, wrap back to the start. */
		if (rx_buffer_definition->rx_pdc_parameters.ul_addr >=
				rx_buffer_definition->past_rx_buffer_end_address)
		{
			rx_buffer_definition->rx_pdc_parameters.ul_addr =
					rx_buffer_definition->rx_buffer_start_address;
		}

		/* Reset the Rx DMA to receive data into whatever free space remains in
		the Rx buffer. */
		configure_rx_dma(uart_index, data_added);

		if (rx_buffer_definition->rx_event_semaphore != NULL) {
			/* Notify that new data is available. */
			xSemaphoreGiveFromISR(
					rx_buffer_definition->rx_event_semaphore,
					&higher_priority_task_woken);
		}
	}

	/**
	 * Normally the uart_status can't be "0" when the interrupt happened.
	 * It happened only when in PDC mode with TXRDY and RXRDY interrupts since
	 * the flags has been cleared by PDC.
	 * As the TXRDY is never enabled in this service, here we
	 * check the RXRDY interrupt case.
	 */
	if (uart_status == 0UL) {
		/* Character has been placed into the Rx buffer. */
		if (rx_buffer_definition->rx_event_semaphore != NULL) {
			/* Notify that new data is available. */
			xSemaphoreGiveFromISR(
					rx_buffer_definition->rx_event_semaphore,
					&higher_priority_task_woken);
		}
	}

	if ((uart_status & SR_ERROR_INTERRUPTS) != 0) {
		/* An error occurred in either a transmission or reception.  Abort, and
		ensure the peripheral access mutex is made available to tasks. */
		uart_reset_status(
				all_uart_definitions[uart_index].peripheral_base_address);
		if (tx_dma_control[uart_index].peripheral_access_mutex != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[uart_index].peripheral_access_mutex,
					&higher_priority_task_woken);
		}
	}

	/* If giving a semaphore caused a task to unblock, and the unblocked task
	has a priority equal to or higher than the currently running task (the task
	this ISR interrupted), then higher_priority_task_woken will have
	automatically been set to pdTRUE within the semaphore function.
	portEND_SWITCHING_ISR() will then ensure that this ISR returns directly to
	the higher priority unblocked task. */
	portEND_SWITCHING_ISR(higher_priority_task_woken);
}