Esempio n. 1
0
/**
 * \brief Send a char to ISO7816.
 *
 * \param uc_char Char to be sent.
 *
 * \return status of US_CSR.
 */
static uint32_t iso7816_send_char(uint8_t uc_char)
{
	uint32_t ul_status;

	if (USART_RCV == gs_uc_state) {
		usart_reset_status(ISO7816_USART);
		usart_reset_iterations(ISO7816_USART);
		usart_reset_nack(ISO7816_USART);
		gs_uc_state = USART_SEND;
	}

	/* Wait USART ready for transmit. */
	while ((usart_get_status(ISO7816_USART) & US_CSR_TXRDY) == 0) {
	}

	/* There is no character in the US_THR, transmit a char. */
	usart_write(ISO7816_USART, uc_char);

	ul_status = usart_get_status(ISO7816_USART) & (US_CSR_OVRE |
			US_CSR_FRAME | US_CSR_PARE | US_CSR_TIMEOUT |
			US_CSR_NACK | US_CSR_ITER);

	if (ul_status != 0) {
		/** There are errors happened, reset the status bit. */
		usart_reset_status(ISO7816_USART);
	}

	/* Return status. */
	return (ul_status);
}
Esempio n. 2
0
/**
 *  \brief Interrupt handler for USART.
 *
 * Increment the number of bytes received in the current second and start
 * another transfer if the desired bps has not been met yet.
 *
 */
void USART_Handler(void)
{
	uint32_t ul_status;

	tc_stop(TC0, 0);

	/* Read USART status. */
	ul_status = usart_get_status(BOARD_USART);

	/* Receive buffer is full. */
	if (ul_status & US_CSR_RXBUFF) {
		g_ul_bytes_received += 2 * BUFFER_SIZE;
		if (g_ul_bytes_received < MAX_BPS) {
			/* Restart transfer if BPS is not high enough. */
			g_st_packet.ul_addr = (uint32_t)gs_puc_buffer;
			g_st_packet.ul_size = BUFFER_SIZE;
			g_st_nextpacket.ul_addr = (uint32_t)gs_puc_nextbuffer;
			g_st_nextpacket.ul_size = BUFFER_SIZE;
			pdc_rx_init(g_p_pdc, &g_st_packet, &g_st_nextpacket);
		} else {
			/* Otherwise disable interrupt. */
			usart_disable_interrupt(BOARD_USART, US_IDR_RXBUFF);
		}
		memcpy(gs_dump_buffer, gs_puc_buffer, BUFFER_SIZE);
	}
	tc_start(TC0, 0);
}
/**
 * \brief Interrupt handler for USART interrupt.
 */
void console_uart_irq_handler(void)
{
	/* Get USART status and check if CMP is set */
	if (usart_get_status(CONSOLE_UART) & US_CSR_CMP) {
		cmp_flag = 1;
		/* Disable USART IRQ */
		usart_disable_interrupt(CONSOLE_UART, US_IDR_CMP);
	}
}
Esempio n. 4
0
/**
 * \brief Interrupt handler for USART interrupt.
 */
void console_usart_irq_handler(void)
{
	/* Get USART status and check if PDC receive buffer is full */
	if ((usart_get_status(CONSOLE_UART) & US_CSR_RXBUFF) == US_CSR_RXBUFF) {
		/* Configure PDC for data transfer (RX and TX) */
		pdc_rx_init(g_p_usart_pdc, &g_pdc_usart_packet, NULL);
		pdc_tx_init(g_p_usart_pdc, &g_pdc_usart_packet, NULL);
	}
}
Esempio n. 5
0
void platform_uart_irq( platform_uart_driver_t* driver )
{
    uint32_t status = usart_get_status( driver->peripheral->peripheral );
    uint32_t mask = usart_get_interrupt_mask( driver->peripheral->peripheral );
    Pdc* pdc_register = usart_get_pdc_base( driver->peripheral->peripheral );

    /* ENDTX flag is set when Tx DMA transfer is done
     */
    if ( ( mask & US_IMR_ENDTX ) && ( status & US_CSR_ENDTX ) )
    {
        pdc_packet_t dma_packet;

        /* ENDTX is cleared when TCR or TNCR is set to a non-zero value, which effectively
         * starts another Tx DMA transaction. To work around this, disable Tx before
         * performing a dummy Tx init.
         */
        pdc_disable_transfer( usart_get_pdc_base( driver->peripheral->peripheral ), PERIPH_PTCR_TXTDIS );

        dma_packet.ul_addr = (uint32_t)0;
        dma_packet.ul_size = (uint32_t)1;

        pdc_tx_init( usart_get_pdc_base( USART1 ), &dma_packet, NULL );

        /* Notifies waiting thread that Tx DMA transfer is complete */
        host_rtos_set_semaphore( &driver->tx_dma_complete, WICED_TRUE );
    }

    /* ENDRX flag is set when RCR is 0. RNPR and RNCR values are then copied into
     * RPR and RCR, respectively, while the Tx tranfer continues. We now need to
     * prepare RNPR and RNCR for the next iteration.
     */
    if ( ( mask & US_IMR_ENDRX ) && ( status & US_CSR_ENDRX ) )
    {
        pdc_register->PERIPH_RNPR = (uint32_t)driver->rx_ring_buffer->buffer;
        pdc_register->PERIPH_RNCR = (uint32_t)driver->rx_ring_buffer->size;
    }

    /* RXRDY interrupt is triggered and flag is set when a new character has been
     * received but not yet read from the US_RHR. When this interrupt executes,
     * the DMA engine already read the character out from the US_RHR and RXRDY flag
     * is no longer asserted. The code below updates the ring buffer parameters
     * to keep them current
     */
    if ( mask & US_CSR_RXRDY )
    {
        driver->rx_ring_buffer->tail = driver->rx_ring_buffer->size - pdc_register->PERIPH_RCR;

        // Notify thread if sufficient data are available
        if ( ( driver->rx_transfer_size > 0 ) && ( ring_buffer_used_space( driver->rx_ring_buffer ) >= driver->rx_transfer_size ) )
        {
            host_rtos_set_semaphore( &driver->rx_dma_complete, WICED_TRUE );
            driver->rx_transfer_size = 0;
        }
    }
}
Esempio n. 6
0
/**
 * \brief Interrupt handler for USART. Echo the bytes received and start the
 * next receive.
 */
void USART0_Handler(void)
{
	uint32_t status;
	status = usart_get_status(USART0);

	/* Check the LIN transmit complete flag */
	if (status & US_IMR_LINTC) {
		usart_disable_interrupt(USART0, US_IDR_LINTC);
		ul_LIN_int_flag = 1;
	}
}
Esempio n. 7
0
/** @brief	Interruption handler for USART1
 *
 */
void USART1_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 = usart_get_status(USART1);

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

		/* change RX buffer */
		gs_ul_size_usart_buf1 = USART_BUFFER_SIZE;

		/* Restart read on buffer. */
		g_st_usart_rx_packet1.ul_addr = (uint32_t)gs_puc_usart_buf1;
		g_st_usart_rx_packet1.ul_size = USART_BUFFER_SIZE;
		pdc_rx_init(g_p_usart_pdc1, &g_st_usart_rx_packet1, NULL);

		/* Restart timer. */
		tc_start(TC_USART, TC_USART_CHN);
	}
}
Esempio n. 8
0
/**
 * \brief
 *
 * \param
 *
 * \return void
 */
void USART1_Handler(void)
{
	uint32_t ul_status;

	/* Read USART Status. */
	ul_status = usart_get_status( BOARD_USART1 );

	/* Receive buffer is full. */
	if (ul_status & US_CSR_RXRDY)
	{
		usart_read( BOARD_USART1, (uint32_t *)&gs_ul_read_buffer[0] );
	}
}
Esempio n. 9
0
/**
 * \brief Get a character from ISO7816.
 *
 * \param p_char_received Pointer for store the received char.
 *
 * \return 0: if timeout else status of US_CSR.
 */
static uint32_t iso7816_get_char(uint8_t *p_char_received)
{
	uint32_t ul_data;
	uint32_t ul_status;
	uint32_t ul_timeout = 0;

	if (gs_uc_state == USART_SEND) {
		while ((usart_get_status(ISO7816_USART) & US_CSR_TXEMPTY) == 0) {
		}
		usart_reset_status(ISO7816_USART);
		usart_reset_iterations(ISO7816_USART);
		usart_reset_nack(ISO7816_USART);
		gs_uc_state = USART_RCV;
	}

	/* Wait USART ready for reception. */
	while (((usart_get_status(ISO7816_USART) & US_CSR_RXRDY) == 0)) {
		if (ul_timeout++ > RX_TIMEOUT * (g_ul_clk / 1000000)) {
			return (0);
		}
	}

	/* At least one complete character has been received and US_RHR has not yet been read. */
	usart_read(ISO7816_USART, &ul_data);
	/* ISO7816 only has 8 bits data. */
	*p_char_received = 0xFF & ul_data;

	ul_status = usart_get_status(ISO7816_USART) & (US_CSR_OVRE |
			US_CSR_FRAME | US_CSR_PARE | US_CSR_TIMEOUT |
			US_CSR_NACK | US_CSR_ITER);

	if (ul_status != 0) {
		usart_reset_status(ISO7816_USART);
	}

	/* Return status. */
	return (ul_status);
}
Esempio n. 10
0
static inline void uart_irq(Usart *const usart, uint32_t index)
{
    MBED_ASSERT(usart != (void*)0);
    uint32_t mask, status;
    /* Read and clear mask. */
    status = usart_get_status(usart);
    mask = usart_get_interrupt_mask(usart);
    status &= mask;

    if (serial_irq_ids[index] != 0) {
        if (status & US_IER_RXRDY) { /*For Receive Complete*/
            if (irq_handler) {
                irq_handler(serial_irq_ids[index], RxIrq);
            }
        }
    }
}
Esempio n. 11
0
/**
 * \brief USART IRQ handler.
 *
 * Interrupt handler for USART. After reception is done, set g_ul_recv_done to true,
 * and if transmission is done, set g_ul_sent_done to true.
 *
 */
void USART_Handler(void)
{
	uint32_t ul_status;

	/* Read USART Status. */
	ul_status = usart_get_status(BOARD_USART);

	/* Receive buffer is full. */
	if ((ul_status & US_CSR_RXBUFF) && (g_uc_state == STATE_READ)) {
		g_ul_recv_done = true;
		usart_disable_interrupt(BOARD_USART, US_IDR_RXBUFF);
	}
	if ((ul_status & US_CSR_TXBUFE) && (g_uc_state == STATE_WRITE)) {
		g_ul_sent_done = true;
		usart_disable_interrupt(BOARD_USART, US_IDR_TXBUFE);
	}
}
Esempio n. 12
0
static void usart_handler(uint8_t port)
{
	Usart* usart = get_usart(port);
	uint32_t sr = usart_get_status(usart);
	if (sr & US_CSR_RXRDY) {
		// Data received
		ui_com_tx_start();
		uint32_t value;
		bool b_error = usart_read(usart, &value) ||
			(sr & (US_CSR_FRAME | US_CSR_TIMEOUT | US_CSR_PARE));
		if (b_error) {
			usart_reset_rx(usart);
			usart_enable_rx(usart);
			udi_cdc_multi_signal_framing_error(port);
			ui_com_error();
		}
		// Transfer UART RX fifo to CDC TX
		if (!udi_cdc_multi_is_tx_ready(port)) {
			// Fifo full
			udi_cdc_multi_signal_overrun(port);
			ui_com_overflow();
		} else {
			udi_cdc_multi_putc(port, value);
		}
		ui_com_tx_stop();
		return;
	}

	if (sr & US_CSR_TXRDY) {
		// Data send
		if (udi_cdc_multi_is_rx_ready(port)) {
			// Transmit next data
			ui_com_rx_start();
			int c = udi_cdc_multi_getc(port);
			usart_write(usart, c);
			
		} else {
			// Fifo empty then Stop UART transmission
			usart_disable_tx(usart);
			usart_disable_interrupt(usart, US_IDR_TXRDY);
			ui_com_rx_stop();
		}
	}
}
Esempio n. 13
0
/*
 * It should be noted that the com test tasks (which use make use of this file)
 * are included to demonstrate queues being used to communicate between tasks
 * and interrupts, and to demonstrate a context switch being performed from
 * inside an interrupt service routine.  The serial driver used here is *not*
 * intended to represent an efficient implementation.  Real applications should
 * make use of the USARTS peripheral DMA channel (PDC).
 */
void USART0_Handler( void )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
uint8_t ucChar;
uint32_t ulChar;
uint32_t ulUSARTStatus, ulUSARTMask;

	ulUSARTStatus = usart_get_status( serUSART_PORT );
	ulUSARTMask = usart_get_interrupt_mask( serUSART_PORT );
	ulUSARTStatus &= ulUSARTMask;

	if( ( ulUSARTStatus & US_CSR_TXRDY ) != 0UL )
	{
		/* The interrupt was caused by the TX register becoming empty.  Are
		there any more characters to transmit? */
		if( xQueueReceiveFromISR( xCharsForTx, &ucChar, &xHigherPriorityTaskWoken ) == pdTRUE )
		{
			/* A character was retrieved from the queue so can be sent to the
			USART now. */
			usart_putchar( serUSART_PORT, ( uint32_t ) ucChar );
		}
		else
		{
			usart_disable_interrupt( serUSART_PORT, US_IER_TXRDY );
		}
	}

	if( ( ulUSARTStatus & US_CSR_RXRDY ) != 0UL )
	{
		/* A character has been received on the USART, send it to the Rx
		handler task. */
		usart_getchar( serUSART_PORT, &ulChar );
		ucChar = ( uint8_t ) ( ulChar & 0xffUL );
		xQueueSendFromISR( xRxedChars, &ucChar, &xHigherPriorityTaskWoken );
	}

	/* If sending or receiving from a queue has 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 xHigherPriorityTaskWoken
	will have automatically been set to pdTRUE within the queue send or receive
	function.  portEND_SWITCHING_ISR() will then ensure that this ISR returns
	directly to the higher priority unblocked task. */
	portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
Esempio n. 14
0
int serial_rx_irq_handler_asynch(serial_t *obj)
{
    /* Sanity check arguments */
    MBED_ASSERT(obj);
    uint32_t ul_status, ulmask;

    /* Read USART Status. */
    ul_status = usart_get_status(_USART(obj));
    ulmask = usart_get_interrupt_mask(_USART(obj));
    ul_status &= ulmask;

    if (ul_status & US_CSR_OVRE) { /* Overrun Error */
        usart_disable_interrupt(_USART(obj), US_IDR_OVRE);
        serial_rx_abort_asynch(obj);
        return SERIAL_EVENT_RX_OVERFLOW;
    }
    if (ul_status & US_CSR_FRAME) { /* Framing Error */
        usart_disable_interrupt(_USART(obj), US_IDR_FRAME);
        serial_rx_abort_asynch(obj);
        return SERIAL_EVENT_RX_FRAMING_ERROR;
    }
    if (ul_status & US_CSR_PARE) { /* Parity Error */
        usart_disable_interrupt(_USART(obj), US_IDR_PARE);
        serial_rx_abort_asynch(obj);
        return SERIAL_EVENT_RX_PARITY_ERROR;
    }
    if ((ul_status & (US_IER_RXBUFF | US_IER_CMP)) ==  (US_IER_RXBUFF | US_IER_CMP)) { /* Character match in last character in transfer*/
        usart_disable_interrupt(_USART(obj), US_IDR_CMP);
        serial_rx_abort_asynch(obj);
        return SERIAL_EVENT_RX_COMPLETE|SERIAL_EVENT_RX_CHARACTER_MATCH;
    }
    if (ul_status & US_IER_CMP) { /* Character match */
        usart_disable_interrupt(_USART(obj), US_IDR_CMP);
        if (pSERIAL_S(obj)->events == SERIAL_EVENT_RX_CHARACTER_MATCH) { /*if character match is the only event abort transfer */
            serial_rx_abort_asynch(obj);
        }
        return SERIAL_EVENT_RX_CHARACTER_MATCH;
    }
    if (ul_status & US_IER_RXBUFF) { /* Reception Complete */
        serial_rx_abort_asynch(obj);
        return SERIAL_EVENT_RX_COMPLETE;
    }
    return 0;
}
Esempio n. 15
0
/**
  * \brief USART IRQ Handler, handling RXBUFF and TXBUFE status.
  */
void USART_Handler(void)
{
	uint32_t ul_status;

	/* Read USART Status. */
	ul_status = usart_get_status(BOARD_USART);

	/* Receiving is done. */
	if ((ul_status & US_CSR_RXBUFF) && (g_uc_state == STATE_RECEIVE)) {
		g_ul_recv_done = true;
		usart_disable_interrupt(BOARD_USART, US_IDR_RXBUFF);
	}

	/* Transmitting is done. */
	if ((ul_status & US_CSR_TXBUFE) && (g_uc_state == STATE_TRANSMIT)) {
		g_ul_sent_done = true;
		usart_disable_interrupt(BOARD_USART, US_IDR_TXBUFE);
	}
}
Esempio n. 16
0
/* ============================================= */
void UartBuffer_Interrupt(void)
{
	static uint32_t ul_status;
	uint32_t c;

	/* Read USART Status. */
	ul_status = usart_get_status(USART0);

	if ( ul_status & US_CSR_TXBUFE ) {
		if ( TxOut != TxIn ) {
			usart_putchar(USART0, TxBuffer[TxOut]);
			TxOut++;
		}
	} 
	if ( usart_is_rx_ready(USART0)) {
		usart_getchar(USART0, &c);
		RxBuffer[RxIn] = c;
		RxIn++;		
	}
}
Esempio n. 17
0
/**
 *  \brief Handler for USART interrupt.
 *
 */
void USART_Handler(void)
{
	uint32_t ul_status;

	/* Read USART status. */
	ul_status = usart_get_status(BOARD_USART);

	/* Receiving interrupt. */
	if ((ul_status & US_CSR_ENDRX) && (g_state == RECEIVING)) {
		/* Indicate receiving finished. */
		g_state = RECEIVED;
		usart_disable_interrupt(BOARD_USART, US_IDR_ENDRX);
	}
	/* Transmitting interrupt. */
	else if ((ul_status & US_CSR_ENDTX) && g_state == TRANSMITTING) {
		/* Transmit continuously. */
		g_state = TRANSMITTED;
		usart_disable_interrupt(BOARD_USART, US_IDR_ENDTX);
	}
}
Esempio n. 18
0
int serial_irq_handler_asynch(serial_t *obj)
{
    /* Sanity check arguments */
    MBED_ASSERT(obj);
    uint32_t ul_status, ulmask;

    /* Read USART Status. */
    ul_status = usart_get_status(_USART(obj));
    ulmask = usart_get_interrupt_mask(_USART(obj));

    ul_status &= ulmask;

    if (ul_status & (US_CSR_RXBUFF | US_CSR_OVRE | US_CSR_FRAME | US_CSR_PARE | US_IER_CMP)) {
        return serial_rx_irq_handler_asynch(obj);
    }
    if (ul_status & US_CSR_TXBUFE) {
        return serial_tx_irq_handler_asynch(obj);
    }
    return 0;
}
Esempio n. 19
0
/**
 * \brief Interrupt handler for USART. Echo the bytes received and start the
 * next receive.
 */
void USART_Handler(void)
{
	uint32_t ul_status;

	/* Read USART Status. */
	ul_status = usart_get_status(BOARD_USART);

	/* Receive buffer is full. */
	if (ul_status & US_CSR_RXBUFF) {
		/* Disable timer. */
		tc_stop(TC0, 0);

		/* Echo back buffer. */
		pdca_channel_write_load(PDCA_TX_CHANNEL,
				(void *)gs_puc_buffer[gs_uc_buf_num],
				gs_ul_size_buffer);
		pdca_channel_write_reload(PDCA_TX_CHANNEL,
				(void *)gs_puc_nextbuffer[gs_uc_buf_num],
				gs_ul_size_nextbuffer);

		if (g_uc_transend_flag) {
			gs_ul_size_buffer = BUFFER_SIZE;
			gs_ul_size_nextbuffer = BUFFER_SIZE;
			g_uc_transend_flag = 0;
		}

		gs_uc_buf_num = MAX_BUF_NUM - gs_uc_buf_num;

		/* Restart read on buffer. */
		pdca_channel_write_load(PDCA_RX_CHANNEL,
				(void *)gs_puc_buffer[gs_uc_buf_num], BUFFER_SIZE);
		pdca_channel_write_reload(PDCA_RX_CHANNEL,
				(void *)gs_puc_nextbuffer[gs_uc_buf_num], BUFFER_SIZE);

		/* Restart timer. */
		tc_start(TC0, 0);
	}
}
/**
 *  \brief Handler for USART interrupt.
 *
 */
void USART_Handler(void)
{
	uint32_t ul_status;
	uint8_t uc_char;

	/* Read USART status. */
	ul_status = usart_get_status(BOARD_USART);

	/*transmit interrupt rises*/
	if(ul_status & (US_IER_TXRDY | US_IER_TXEMPTY)) {
		usart_disable_interrupt(BOARD_USART, (US_IER_TXRDY | US_IER_TXEMPTY));
	}

	/*receive interrupt rise, store character to receiver buffer*/
	if((g_state == RECEIVING) && (usart_read(BOARD_USART, (uint32_t *)&uc_char) == 0)) {
		*p_revdata++ = uc_char;
		g_ulcount++;
		if(g_ulcount >= BUFFER_SIZE) {
			g_state = RECEIVED;
			usart_disable_interrupt(BOARD_USART, US_IER_RXRDY);
		}
	}
}
/**
 * \brief USART IRQ handler.
 *
 * Interrupt handler for USART. After reception is done, set g_ul_recv_done to true,
 * and if transmission is done, set g_ul_sent_done to true.
 *
 */
void USART0_Handler(void)
{
	uint32_t ul_status;
	uint8_t uc_char;

	/* Read USART Status. */
	ul_status = usart_get_status(BOARD_USART);

	if(ul_status & (US_IER_TXRDY | US_IER_TXEMPTY)) {
		usart_disable_interrupt(BOARD_USART, (US_IER_TXRDY | US_IER_TXEMPTY));
	}

	/* Receive register is full. */
	if((g_uc_state == STATE_READ) && (usart_read(BOARD_USART, (uint32_t *)&uc_char) == 0)) {
		*p_revdata++ = uc_char;
		g_ulcount++;
		if(g_ulcount >= BUFFER_SIZE) {
			usart_disable_interrupt(BOARD_USART, US_IER_RXRDY);
			g_ul_recv_done = true;
		}
	}

}
Esempio n. 22
0
/*
 * For internal use only.
 * A common USART interrupt handler that is called for all USART peripherals.
 */
static void local_usart_handler(const portBASE_TYPE usart_index)
{
	portBASE_TYPE higher_priority_task_woken = pdFALSE;
	uint32_t usart_status;
	freertos_pdc_rx_control_t *rx_buffer_definition;

	usart_status = usart_get_status(
			all_usart_definitions[usart_index].peripheral_base_address);
	usart_status &= usart_get_interrupt_mask(
			all_usart_definitions[usart_index].peripheral_base_address);

	rx_buffer_definition = &(rx_buffer_definitions[usart_index]);

	/* Has the PDC completed a transmission? */
	if ((usart_status & US_CSR_ENDTX) != 0UL) {
		usart_disable_interrupt(
				all_usart_definitions[usart_index].peripheral_base_address,
				US_IER_ENDTX);

		/* If the driver is supporting multi-threading, then return the access
		mutex. */
		if (tx_dma_control[usart_index].peripheral_access_mutex != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[usart_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[usart_index].transaction_complete_notification_semaphore != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[usart_index].transaction_complete_notification_semaphore,
					&higher_priority_task_woken);
		}
	}

	if ((usart_status & US_CSR_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(usart_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);
		}
	}

	if ((usart_status & US_IER_TIMEOUT) != 0UL) {
		/* More characters have been placed into the Rx buffer.

		Restart the timeout after more data has been received. */
		usart_start_rx_timeout(all_usart_definitions[usart_index].peripheral_base_address);

		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 ((usart_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. */
		usart_reset_status(
				all_usart_definitions[usart_index].peripheral_base_address);
		if (tx_dma_control[usart_index].peripheral_access_mutex != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[usart_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);
}
Esempio n. 23
0
/**
 * \brief
 *
 * \param
 *
 * \return void
 */
void uart_config(void)
{
	const sam_uart_opt_t uart_settings = {
		.ul_mck = sysclk_get_peripheral_hz(),
		.ul_baudrate = 19200,
		.ul_mode = UART_MR_PAR_NO
	};

	sysclk_enable_peripheral_clock(ID_UART);
	uart_init( BOARD_UART, &uart_settings );

}
/**
 * \brief
 *
 * \param
 *
 * \return void
 */
void usart0_config(void)
{

	const sam_usart_opt_t usart_0_settings = {
		.baudrate = 19200,
		.char_length = US_MR_CHRL_8_BIT,
		.parity_type = US_MR_PAR_NO,
		.stop_bits = US_MR_NBSTOP_1_BIT,
		.channel_mode = US_MR_CHMODE_NORMAL,
		/* This field is only used in IrDA mode. */
		.irda_filter = 0
	};
	sysclk_enable_peripheral_clock(BOART_ID_USART0);
	usart_init_rs232(BOARD_USART0, &usart_0_settings, sysclk_get_peripheral_hz());

	/* Disable all the interrupts. */
	usart_disable_interrupt(BOARD_USART0, 0xffffffff);

	/* Enable the receiver and transmitter. */
	usart_enable_tx(BOARD_USART0);
	usart_enable_rx(BOARD_USART0);

	/* Configure and enable interrupt of USART. */
	NVIC_EnableIRQ(USART0_IRQn);

	usart_enable_interrupt(BOARD_USART0, US_IER_RXRDY);
}

/**
 * \brief
 *
 * \param
 *
 * \return void
 */
void usart1_config(void)
{
	const sam_usart_opt_t usart_1_settings = {
		.baudrate = 115200,
		.char_length = US_MR_CHRL_8_BIT,
		.parity_type = US_MR_PAR_NO,
		.stop_bits = US_MR_NBSTOP_1_BIT,
		.channel_mode = US_MR_CHMODE_NORMAL,
		/* This field is only used in IrDA mode. */
		.irda_filter = 0
	};

	sysclk_enable_peripheral_clock( BOART_ID_USART1 );
	usart_init_rs232( BOARD_USART1, &usart_1_settings, sysclk_get_peripheral_hz() );

	/* Disable all the interrupts. */
	usart_disable_interrupt(BOARD_USART1, 0xffffffff);

	/* Enable the receiver and transmitter. */
	usart_enable_tx(BOARD_USART1);
	usart_enable_rx(BOARD_USART1);

	/* Configure and enable interrupt of USART. */
	NVIC_EnableIRQ( USART1_IRQn );

	usart_enable_interrupt( BOARD_USART1, US_IER_RXRDY);
}

/**
 * \brief
 *
 * \param uxPriority
 *
 * \return void
 */
void vStartUartTaskLauncher( unsigned portBASE_TYPE uxPriority )
{
	/* Spawn the Sentinel task. */
	xTaskCreate( vUartTask, (const signed portCHAR *)"SPILAUNCH",
				TASK_RADIO_STACK_SIZE, NULL, uxPriority,
				(xTaskHandle *)NULL );
}

/**
 * \brief UART handle task..
 *
 * \param
 * \param
 *
 * \return None
 */
portTASK_FUNCTION_PROTO( vUartTask, pvParameters )
{
	uint8_t	i, sms_text[] = "AT\r";

	(void)pvParameters;

	/* Initialize UART model.*/
	uart_config();
	usart0_config();
	usart1_config();

	gpio_set_pin_low( PIO_PA17_IDX );

	for (;;)
	{
		vTaskDelay(1000);

		uart_write( BOARD_UART, '1' );
		usart_serial_write_packet( BOARD_USART1, sms_text, sizeof(sms_text) );
	}
}

/**
 * \brief
 *
 * \param
 *
 * \return void
 */
void USART0_Handler(void)
{
	uint32_t ul_status;

	/* Read USART Status. */
	ul_status = usart_get_status( BOARD_USART0 );

	/* Receive buffer is full. */
	if (ul_status & US_CSR_RXRDY)
	{
		usart_read( BOARD_USART0, (uint32_t *)&gs_ul_read_buffer[0] );
	}
}