void init_Usart (void)
{
    ioport_set_pin_dir(PIO_PA21_IDX,IOPORT_DIR_INPUT);
    ioport_set_pin_dir(PIO_PB4_IDX,IOPORT_DIR_OUTPUT);


    const sam_usart_opt_t usart_console_settings = {
        USART_SERIAL_BAUDRATE,
        USART_SERIAL_CHAR_LENGTH,
        USART_SERIAL_PARITY,
        USART_SERIAL_STOP_BIT,
        US_MR_CHMODE_NORMAL
    };
#if SAM4L
    sysclk_enable_peripheral_clock(USART_SERIAL);
#else
    sysclk_enable_peripheral_clock(USART_SERIAL_ID);
#endif
    usart_init_rs232(USART_SERIAL, &usart_console_settings,
                     sysclk_get_main_hz()/2);
    usart_enable_tx(USART_SERIAL);
    usart_enable_rx(USART_SERIAL);
    // how to enable an interrupt( use three steps ):use these functions: -usart_enable_interrupt-    Then  -NVIC_EnableIRQ(USART_SERIAL_IRQ);-    & Then add this function  void USART_SERIAL_ISR_HANDLER(void)
    usart_enable_interrupt(USART_SERIAL, US_IER_RXRDY);
    NVIC_EnableIRQ(USART_SERIAL_IRQ);
}
Exemple #2
0
/**
 * \brief Application entry point for pdc_usart example.
 *
 * \return Unused (ANSI-C compatibility).
 */
int main(void)
{
	/* Initialize the SAM system */
	sysclk_init();
	board_init();    

	/* Initialize the UART console */
	configure_console();

	/* Output example information */
	puts(STRING_HEADER);

	/* Get pointer to USART PDC register base */
	g_p_usart_pdc = usart_get_pdc_base(CONSOLE_UART);

	/* Initialize PDC data packet for transfer */
	g_pdc_usart_packet.ul_addr = (uint32_t) g_uc_pdc_buffer;
	g_pdc_usart_packet.ul_size = BUFFER_SIZE;

	/* Configure PDC for data receive */
	pdc_rx_init(g_p_usart_pdc, &g_pdc_usart_packet, NULL);

	/* Enable PDC transfers */
	pdc_enable_transfer(g_p_usart_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);

	/* Enable USART IRQ */
	usart_enable_interrupt(CONSOLE_UART, US_IER_RXBUFF);

	/* Enable USART interrupt */
	NVIC_EnableIRQ(CONSOLE_USART_IRQn);

	while (1) {
	}
}
Exemple #3
0
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
{
    /* Sanity check arguments */
    MBED_ASSERT(obj);
    IRQn_Type irq_n = (IRQn_Type)0;
    uint32_t vector = 0;

    vector = get_serial_vector(obj);
    irq_n = get_serial_irq_num(obj);

    if (enable) {
        switch (irq) {
        case RxIrq:
            usart_enable_interrupt(_USART(obj), US_IER_RXRDY);
            break;
        case TxIrq:
            break;
        }
        NVIC_ClearPendingIRQ(irq_n);
        NVIC_DisableIRQ(irq_n);
        NVIC_SetVector(irq_n, vector);
        NVIC_EnableIRQ(irq_n);
    } else {
        switch (irq) {
        case RxIrq:
            usart_disable_interrupt(_USART(obj), US_IER_RXRDY);
            break;
        case TxIrq:
            break;
        }
        NVIC_DisableIRQ(irq_n);
    }
}
Exemple #4
0
void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_width, uint32_t handler, uint32_t event, uint8_t char_match, DMAUsage hint)
{
    /* Sanity check arguments */
    MBED_ASSERT(obj);
    MBED_ASSERT(rx != (void*)0);
    if(rx_length == 0) return 0;
    Pdc *pdc_base;
    IRQn_Type irq_n = (IRQn_Type)0;
    pdc_packet_t packet;

    pSERIAL_S(obj)->actrec = true; /* flag for active receive transfer */
    if (event == SERIAL_EVENT_RX_CHARACTER_MATCH) { /* if event is character match alone */
        pSERIAL_S(obj)->events = SERIAL_EVENT_RX_CHARACTER_MATCH;
    }

    irq_n = get_serial_irq_num(obj);

    serial_set_char_match(obj, char_match);

    /* Get board USART PDC base address and enable transmitter. */
    pdc_base = usart_get_pdc_base(_USART(obj));
    pdc_enable_transfer(pdc_base, PERIPH_PTCR_RXTEN);
    packet.ul_addr = (uint32_t)rx;
    packet.ul_size = (uint32_t)rx_length;
    pdc_rx_init(pdc_base, &packet, NULL);

    usart_enable_interrupt(_USART(obj), (US_IER_RXBUFF | US_IER_OVRE | US_IER_FRAME | US_IER_PARE));

    NVIC_ClearPendingIRQ(irq_n);
    NVIC_DisableIRQ(irq_n);
    NVIC_SetVector(irq_n, (uint32_t)handler);
    NVIC_EnableIRQ(irq_n);

}
/**
 * \brief Test the usart sleepwalking in active mode.
 */
static void usart_sleepwalking_test_active(void)
{
	uint32_t temp;

	puts("Test in active mode, press 's' to continue.\r");

	/* Wait for the puts operation to finish. */
	delay_ms(50);

	/* Enable UART IRQ */
	usart_enable_interrupt(CONSOLE_UART, US_IER_CMP);

	/* Enable UART interrupt */
	NVIC_EnableIRQ(CONSOLE_UART_IRQn);

	/* Set the match condition */
	usart_set_sleepwalking(CONSOLE_UART, 's', true, true, 's');

	/* Enable the sleepwalking in PMC */
	pmc_enable_sleepwalking(CONSOLE_UART_ID);

	/* Wait for the match interrupt */
	while (!cmp_flag) {
	}

	usart_read(CONSOLE_UART, &temp);
	puts("'s' character is received.\r\n\r");

}
Exemple #6
0
/**
 * \brief Test LIN transmit.
 *
 * This test initializes the LIN and start a transmit.
 *
 * \param test Current test case.
 */
static void run_lin_test(const struct test_case *test)
{
	st_lin_message lin_desc;

	/* Enable the peripheral clock in the PMC. */
	pmc_enable_periph_clk(ID_USART0);

	/* Enable LIN transceiver */
	gpio_set_pin_high(PIN_USART0_CTS_IDX);
	gpio_set_pin_high(PIN_USART0_RTS_IDX);

	/* Node 0:  LIN_MASTER_MODE */
	lin_init(USART0, true, LIN_MASTER_NODE_NUM, 9600, sysclk_get_cpu_hz());

	/* Configure lin_descriptor */
	/* Init LIN data Node 0 */
	/* Object 0 */
	lin_desc.uc_id = LIN_FRAME_ID_12;
	lin_desc.uc_dlc = sizeof(lin_data_node);
	lin_desc.lin_cmd = PUBLISH;
	lin_desc.uc_status = 0;
	lin_desc.uc_pt_data = lin_data_node;
	lin_register_descriptor(LIN_MASTER_NODE_NUM, 0, &lin_desc);

	configure_tc();
	/* In case of Master Mode, the timing transmission starts... */
	tc_start(TC0, 0);

	/* Configure and enable interrupt of USART */
	NVIC_EnableIRQ(USART0_IRQn);
	usart_enable_interrupt(USART0, US_IER_LINTC);

	delay_ms(200);
	test_assert_true(test, ul_LIN_int_flag, "LIN transmit failed!");
}
Exemple #7
0
void uart_open(uint8_t port)
{
	Usart* usart = get_usart(port);

	if (0 == port) {
		// IO is initialized in board init
		// Enable interrupt with priority higher than USB
		NVIC_SetPriority((IRQn_Type) USART_ID_0, USART_INT_LEVEL_0);
		NVIC_EnableIRQ((IRQn_Type) USART_ID_0);
		NVIC_SetPriority((IRQn_Type) USART_ID_1, USART_INT_LEVEL_1);
		NVIC_EnableIRQ((IRQn_Type) USART_ID_1);
		// Initialize it in RS232 mode.
		pmc_enable_periph_clk(USART_ID_0);
		USART_ENABLE_0();
	} else if (1 == port) {
		// IO is initialized in board init
		// Enable interrupt with priority higher than USB
		NVIC_SetPriority((IRQn_Type) USART_ID_1, USART_INT_LEVEL_1);
		NVIC_EnableIRQ((IRQn_Type) USART_ID_1);
		// Initialize it in RS232 mode.
		pmc_enable_periph_clk(USART_ID_1);
		USART_ENABLE_1();
	} else {
		return;
	}
	if (usart_init_rs232(usart, &usart_options,
				sysclk_get_peripheral_hz())) {
		return;
	}
	// Enable both RX and TX
	usart_enable_tx(usart);
	usart_enable_rx(usart);
	// Enable interrupts
	usart_enable_interrupt(usart, US_IER_RXRDY | US_IER_TXRDY);
}
Exemple #8
0
/************************************
 * TRANSFER FUNCTIONS				*
 ***********************************/
int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint)
{
    /* Sanity check arguments */
    MBED_ASSERT(obj);
    MBED_ASSERT(tx != (void*)0);
    if(tx_length == 0) return 0;
    Pdc *pdc_base;
    IRQn_Type irq_n = (IRQn_Type)0;
    pdc_packet_t packet;

    pSERIAL_S(obj)->acttra = true; /* flag for active transmit transfer */

    irq_n = get_serial_irq_num(obj);

    /* Get board USART PDC base address and enable transmitter. */
    pdc_base = usart_get_pdc_base(_USART(obj));
    pdc_enable_transfer(pdc_base, PERIPH_PTCR_TXTEN);

    packet.ul_addr = (uint32_t)tx;
    packet.ul_size = (uint32_t)tx_length;

    pdc_tx_init(pdc_base, &packet, NULL);
    usart_enable_interrupt(_USART(obj), US_IER_TXBUFE);

    NVIC_ClearPendingIRQ(irq_n);
    NVIC_DisableIRQ(irq_n);
    NVIC_SetVector(irq_n, (uint32_t)handler);
    NVIC_EnableIRQ(irq_n);

    return 0;
}
Exemple #9
0
void serial_set_char_match(serial_t *obj, uint8_t char_match)
{
    /* Sanity check arguments */
    MBED_ASSERT(obj);
    if (char_match != SERIAL_RESERVED_CHAR_MATCH) {
        obj->char_match = char_match;
        _USART(obj)->US_CMPR = (char_match & 0xFF);
        usart_enable_interrupt(_USART(obj), US_IER_CMP);
    }
}
Exemple #10
0
void uart_rx_notify(uint8_t port)
{
	Usart* usart = get_usart(port);
	// If UART is open
	if (usart_get_interrupt_mask(usart)
		& US_IMR_RXRDY) {
		// Enable UART TX interrupt to send a new value
		usart_enable_tx(usart);
		usart_enable_interrupt(usart, US_IER_TXRDY);
	}
}
Exemple #11
0
void uart_rx_notify(uint8_t port)
{
	UNUSED(port);
	// If UART is open
	if (usart_get_interrupt_mask(USART_BASE)
		& US_IMR_RXRDY) {
		// Enable UART TX interrupt to send a new value
		usart_enable_tx(USART_BASE);
		usart_enable_interrupt(USART_BASE, US_IER_TXRDY);
	}
}
Exemple #12
0
/*
 * See the serial.h header file.
 */
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
{
uint32_t ulChar;
xComPortHandle xReturn;
const sam_usart_opt_t xUSARTSettings =
{
	ulWantedBaud,
	US_MR_CHRL_8_BIT,
	US_MR_PAR_NO,
	US_MR_NBSTOP_1_BIT,
	US_MR_CHMODE_NORMAL,
	0 /* Only used in IrDA mode. */
};

	/* Create the queues used to hold Rx/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 ) )
	{
		/* Enable the peripheral clock in the PMC. */
		pmc_enable_periph_clk( serPMC_USART_ID );

		/* Configure USART in serial mode. */
		usart_init_rs232( serUSART_PORT, &xUSARTSettings, sysclk_get_cpu_hz() );

		/* Disable all the interrupts. */
		usart_disable_interrupt( serUSART_PORT, serMASK_ALL_INTERRUPTS );

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

		/* Clear any characters before enabling interrupt. */
		usart_getchar( serUSART_PORT, &ulChar );

		/* Enable Rx end interrupt. */
		usart_enable_interrupt( serUSART_PORT, US_IER_RXRDY );

		/* Configure and enable interrupt of USART. */
		NVIC_SetPriority( serUSART_IRQ, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
		NVIC_EnableIRQ( serUSART_IRQ );
	}
	else
	{
		xReturn = ( xComPortHandle ) 0;
	}

	/* This demo file only supports a single port but we have to return
	something to comply with the standard demo header file. */
	return xReturn;
}
Exemple #13
0
/* ============================================= */
void UartBuffer_Init(void)
{
	sysclk_enable_peripheral_clock(ID_USART0);
	usart_init_rs232(USART0, &usart_console_settings, sysclk_get_cpu_hz());
	usart_disable_interrupt(USART0, ALL_INTERRUPT_MASK);
	usart_enable_tx(USART0);
	usart_enable_rx(USART0);
	usart_enable_interrupt(USART0, US_IER_RXRDY);
	NVIC_EnableIRQ(USART0_IRQn);

	TxIn = TxOut = 0;
	RxIn = RxOut = 0;
}
Exemple #14
0
/**
 *  \brief usart_hard_handshaking_example application entry point.
 *
 *  \return Unused (ANSI-C compatibility).
 */
int main(void)
{
	uint8_t uc_char;
	uint8_t uc_flag;

	/* Initialize the system. */
	sysclk_init();
	board_init();

	/* Configure UART for debug message output. */
	configure_console();

	/* Output example information. */
	puts(STRING_HEADER);

	/* Initialize board USART. */
	configure_usart();

	/* Initialize TC0. */
	configure_tc();

	/* Get board USART PDC base address and enable receiver. */
	g_p_pdc = usart_get_pdc_base(BOARD_USART);
	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);
	pdc_enable_transfer(g_p_pdc, PERIPH_PTCR_RXTEN);

	usart_enable_interrupt(BOARD_USART, US_IER_RXBUFF);

	/* Start the Timer counter. */
	tc_start(TC0, 0);

	while (1) {
		uc_char = 0;
		uc_flag = uart_read(CONSOLE_UART, &uc_char);
		if (!uc_flag) {
			switch (uc_char) {
			case 'd':
			case 'D':
				usart_write_line(BOARD_USART, (char *)gs_dump_buffer);
				break;
			default:
				break;
			}
		}
	}
}
/**
* \brief transmit data.
*
* \param *p_buff  data to be transmitted
* \param ulsize size of all data.
*
*/
uint8_t func_transmit(const uint8_t *p_buff, uint32_t ulsize)
{
	Assert(p_buff);

	while(ulsize > 0) {
		if(0 == usart_write(BOARD_USART, *p_buff)){
			usart_enable_interrupt(BOARD_USART, US_IER_TXRDY | US_IER_TXEMPTY);
			ulsize--;
			p_buff++;
		}
	}

	while(!usart_is_tx_empty(BOARD_USART)) {
		;  /*waiting for transmit over*/
	}

	return 0;
}
Exemple #16
0
/**
 *  \brief Interrupt handler for TC0.
 *
 * Display the number of bytes received during the last second and the total
 * number of bytes received, and then restart a read transfer on the USART if it
 * was stopped.
 */
void TC0_Handler(void)
{
	uint32_t ul_status;
	static uint32_t bytes_total = 0;

	/* Read TC0 status. */
	ul_status = tc_get_status(TC0, 0);

	/* RC compare. */
	if ((ul_status & TC_SR_CPCS) == TC_SR_CPCS) {
		if((pdc_read_rx_counter(g_p_pdc) != 0) &&
				(pdc_read_rx_counter(g_p_pdc) != BUFFER_SIZE)) {
			if(pdc_read_rx_next_counter(g_p_pdc) == 0) {
				g_ul_bytes_received += (2 * BUFFER_SIZE - pdc_read_rx_counter(g_p_pdc));
			} else {
				g_ul_bytes_received += (BUFFER_SIZE - pdc_read_rx_counter(g_p_pdc));
			}
			memset(gs_dump_buffer, 0, BUFFER_SIZE);
			memcpy(gs_dump_buffer, gs_puc_buffer, BUFFER_SIZE -
					pdc_read_rx_counter(g_p_pdc));
		} else if((pdc_read_rx_counter(g_p_pdc) == BUFFER_SIZE) &&
				(pdc_read_rx_next_counter(g_p_pdc) == 0)) {
			g_ul_bytes_received += BUFFER_SIZE;
			memcpy(gs_dump_buffer, gs_puc_buffer, BUFFER_SIZE);
		}

		/* Display info. */
		bytes_total += g_ul_bytes_received;
		memset(g_puc_string, 0, BUFFER_SIZE);
		sprintf((char *)g_puc_string, "Bps: %4lu; Tot: %6lu\r\n",
				(unsigned long)g_ul_bytes_received,
				(unsigned long)bytes_total);
		usart_write_line(BOARD_USART, (char *)g_puc_string);
		/* Resume transfer */
		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);
			usart_enable_interrupt(BOARD_USART, US_IER_RXBUFF);

		g_ul_bytes_received = 0;
	}
}
Exemple #17
0
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime )
{
signed portBASE_TYPE xReturn;

	/* This simple example only supports one port. */
	( void ) pxPort;

	if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) == pdPASS )
	{
		xReturn = pdPASS;
		usart_enable_interrupt( serUSART_PORT, US_IER_TXRDY );
	}
	else
	{
		xReturn = pdFAIL;
	}

	return xReturn;
}
/**
 * \ingroup freertos_usart_peripheral_control_group
 * \brief Initiate a completely asynchronous multi-byte write operation on a
 * USART peripheral.
 *
 * freertos_usart_write_packet_async() is an ASF specific FreeRTOS driver
 * function.  It configures the USART peripheral DMA controller (PDC) to
 * transmit data on the USART port, then returns.
 * freertos_usart_write_packet_async() does not wait for the transmission to
 * complete before returning.
 *
 * The FreeRTOS USART driver is initialized using a call to
 * freertos_usart_serial_init().  The freertos_driver_parameters.options_flags
 * parameter passed into the initialization function defines the driver behavior.
 * freertos_usart_write_packet_async() can only be used if the
 * freertos_driver_parameters.options_flags parameter passed to the initialization
 * function had the WAIT_TX_COMPLETE bit clear.
 *
 * freertos_usart_write_packet_async() is an advanced function and readers are
 * recommended to also reference the application note and examples that
 * accompany the FreeRTOS ASF drivers.  freertos_usart_write_packet() is a
 * version that does not exit until the PDC transfer is complete, but still
 * allows other RTOS tasks to execute while the transmission is in progress.
 *
 * The FreeRTOS ASF driver both installs and handles the USART PDC interrupts.
 * Users do not need to concern themselves with interrupt handling, and must
 * not install their own interrupt handler.
 *
 * \param p_usart    The handle to the USART peripheral returned by the
 *     freertos_usart_serial_init() call used to initialise the peripheral.
 * \param data    A pointer to the data to be transmitted.
 * \param len    The number of bytes to transmit.
 * \param block_time_ticks    The FreeRTOS ASF USART driver is initialized using
 *     a call to freertos_usart_serial_init().  The
 *     freertos_driver_parameters.options_flags parameter passed to the
 *     initialization function defines the driver behavior.  If
 *     freertos_driver_parameters.options_flags had the USE_TX_ACCESS_MUTEX bit
 *     set, then the driver will only write to the USART peripheral if it has
 *     first gained exclusive access to it.  block_time_ticks specifies the
 *     maximum amount of time the driver will wait to get exclusive access
 *     before aborting the write operation.  Other tasks will execute during any
 *     waiting time.  block_time_ticks is specified in RTOS tick periods.  To
 *     specify a block time in milliseconds, divide the milliseconds value by
 *     portTICK_RATE_MS, and pass the result in block_time_ticks.
 *     portTICK_RATE_MS is defined by FreeRTOS.
 * \param notification_semaphore    The RTOS task that calls the transmit
 *     function exits the transmit function as soon as the transmission starts.
 *     The data being transmitted by the PDC must not be modified until after
 *     the transmission has completed.  The PDC interrupt (handled internally by
 *     the FreeRTOS ASF driver) 'gives' the semaphore when the PDC transfer
 *     completes.  The notification_semaphore therefore provides a mechanism for
 *     the calling task to know when the PDC has finished accessing the data.
 *     The calling task can call standard FreeRTOS functions to block on the
 *     semaphore until the PDC interrupt occurs.  Other RTOS tasks will execute
 *     while the the calling task is in the Blocked state.  The semaphore must
 *     be created using the FreeRTOS vSemaphoreCreateBinary() API function
 *     before it is used as a parameter.
 *
 * \return     ERR_INVALID_ARG is returned if an input parameter is invalid.
 *     ERR_TIMEOUT is returned if block_time_ticks passed before exclusive
 *     access to the USART peripheral could be obtained.  STATUS_OK is returned
 *     if the PDC was successfully configured to perform the USART write
 *     operation.
 */
status_code_t freertos_usart_write_packet_async(freertos_usart_if p_usart,
		const uint8_t *data, size_t len, portTickType block_time_ticks,
		xSemaphoreHandle notification_semaphore)
{
	status_code_t return_value;
	portBASE_TYPE usart_index;
	Usart *usart_base;

	usart_base = (Usart *) p_usart;
	usart_index = get_pdc_peripheral_details(all_usart_definitions,
			MAX_USARTS,
			(void *) usart_base);

	/* Don't do anything unless a valid USART pointer was used. */
	if (usart_index < MAX_USARTS) {
		return_value = freertos_obtain_peripheral_access_mutex(
				&(tx_dma_control[usart_index]),
				&block_time_ticks);

		if (return_value == STATUS_OK) {
			freertos_start_pdc_tx(&(tx_dma_control[usart_index]),
					data, len,
					all_usart_definitions[usart_index].pdc_base_address,
					notification_semaphore);

			/* Catch the end of transmission so the access mutex can be
			returned, and the task notified (if it supplied a notification
			semaphore).  The interrupt can be enabled here because the ENDTX
			signal from the PDC to the USART will have been de-asserted when
			the next transfer was configured. */
			usart_enable_interrupt(usart_base, US_IER_ENDTX);

			return_value = freertos_optionally_wait_transfer_completion(
					&(tx_dma_control[usart_index]),
					notification_semaphore,
					block_time_ticks);
		}
	} else {
		return_value = ERR_INVALID_ARG;
	}

	return return_value;
}
/**
* \brief transmit data in synchronous mode.
*
* \param *p_buff  data to be transmitted
* \param ulsize size of all data.
*
*/
static uint8_t transmit_mode_sync(uint8_t *p_buff, uint32_t ulsize)
{
	Assert(p_buff);

	while(ulsize > 0) {
		if(0 == usart_write(BOARD_USART, *p_buff)){
			usart_enable_interrupt(BOARD_USART, US_IER_TXRDY | US_IER_TXEMPTY);
			ulsize--;
			p_buff++;
		}
	}

	while(!usart_is_tx_empty(BOARD_USART)) {
				;  /*waiting for transmit over*/
	}

	g_ul_sent_done = true;
	return 0;
}
Exemple #20
0
void uart_open(uint8_t port)
{
	UNUSED(port);

	// IO is initialized in board init
	// Enable interrupt with priority higher than USB
	NVIC_SetPriority(USART_INT_IRQn, USART_INT_LEVEL);
	NVIC_EnableIRQ(USART_INT_IRQn);

	// Initialize it in RS232 mode.
	USART_PERIPH_CLK_ENABLE();
	if (usart_init_rs232(USART_BASE, &usart_options,
			sysclk_get_peripheral_bus_hz(USART_BASE))) {
		return;
	}
	// Enable USART
	USART_ENABLE();

	// Enable both RX and TX
	usart_enable_tx(USART_BASE);
	usart_enable_rx(USART_BASE);
	// Enable interrupts
	usart_enable_interrupt(USART_BASE, US_IER_RXRDY | US_IER_TXRDY);
}
/**
 * \brief Application entry point for usart_serial example.
 *
 * \return Unused (ANSI-C compatibility).
 */
int main(void)
{
	/* Initialize the SAM system. */
	sysclk_init();
	board_init();

	/* Configure UART for debug message output. */
	configure_console();

	/* Output example information. */
	puts(STRING_HEADER);
	puts("-- Start to echo serial inputs with PDCA -- \r\n\r");

	/* Configure TC. */
	configure_tc();

	/* Enable PDCA module clock */
	pdca_enable(PDCA);
	/* Init PDCA channel with the pdca_options.*/
	pdca_channel_set_config(PDCA_RX_CHANNEL, &pdca_rx_options);
	pdca_channel_set_config(PDCA_TX_CHANNEL, &pdca_tx_options);
	/* Enable PDCA channel, start receiving data. */
	pdca_channel_enable(PDCA_RX_CHANNEL);
	pdca_channel_enable(PDCA_TX_CHANNEL);

	/* Enable USART RXBUFF interrupt */
	usart_enable_interrupt(BOARD_USART, US_IER_RXBUFF);
	/* Configure and enable interrupt of USART. */
	NVIC_EnableIRQ(USART_IRQn);

	/* Start timer. */
	tc_start(TC0, 0);

	while (1) {
	}
}
Exemple #22
0
/**
 * \brief This function opens an USART
 *
 * \note Opening of the specified USART implies initializing local variables and
 * opening required hardware with the following configuration:
 * - bauds as specified
 * - 8 bits, no parity, 1 stop bit
 * - enable interrupts
 *
 * \param chn			Communication channel [0, 1]
 * \param bauds			Communication speed in bauds
 *
 * \retval true on success.
 * \retval false on failure.
 */
int8_t busart_if_open(uint8_t chn, uint32_t bauds)
{
#if defined(CONF_BOARD_USART0_RXD) || defined(CONF_BOARD_USART1_RXD)
	sam_usart_opt_t usart_console_settings;

	/* Expected baud rate. */
	usart_console_settings.baudrate = bauds;

	/* Configure channel mode (Normal, Automatic, Local_loopback or
	 * Remote_loopback) */
	usart_console_settings.channel_mode = US_MR_CHMODE_NORMAL;
	/* Initialize value for USART mode register */
	usart_console_settings.parity_type = US_MR_PAR_NO;
	usart_console_settings.char_length = US_MR_CHRL_8_BIT;
	usart_console_settings.stop_bits = US_MR_NBSTOP_1_BIT;
#else
	UNUSED(bauds);
#endif
	/* check usart and it is close */
	if (chn >= 2) {
		return false;
	}

	if (busart_chn_open[chn]) {
		return false;
	}

	switch (chn) {
#ifdef CONF_BOARD_USART0_RXD
	case 0:
	{
		/* Configure PMC. */
		pmc_enable_periph_clk(ID_USART0);
		/* Configure USART. */
		usart_init_rs232(USART0, &usart_console_settings,
				sysclk_get_peripheral_hz());

		/* Assign buffers to pointers */
		busart_comm_data_0.puc_tq_buf = ptr_tx_usart_buf0;
		busart_comm_data_0.puc_rq_buf = ptr_rx_usart_buf0;
		busart_comm_data_0.us_rq_count = 0;
		busart_comm_data_0.us_rq_idx = 0;
		busart_comm_data_0.us_wq_idx = 0;

		/* Get board USART0 PDC base address and enable receiver and
		 * transmitter. */
		g_p_usart_pdc0 = usart_get_pdc_base(USART0);
		pdc_enable_transfer(g_p_usart_pdc0,
				PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);

		/* Start receiving data and start timer. */
		g_st_usart_rx_packet0.ul_addr = (uint32_t)gs_puc_usart_buf0;
		g_st_usart_rx_packet0.ul_size = USART_BUFFER_SIZE;
		pdc_rx_init(g_p_usart_pdc0, &g_st_usart_rx_packet0, NULL);

		/* Stop transmitting data */
		g_st_usart_tx_packet0.ul_addr = (uint32_t)busart_comm_data_0.puc_tq_buf;
		g_st_usart_tx_packet0.ul_size = 0;
		pdc_tx_init(g_p_usart_pdc0, &g_st_usart_tx_packet0, NULL);

		gs_ul_size_usart_buf0 = USART_BUFFER_SIZE;

		/* Transfer to PDC communication mode, disable RXRDY interrupt
		 * and enable RXBUFF interrupt. */
		usart_disable_interrupt(USART0, US_IDR_RXRDY);
		usart_enable_interrupt(USART0, US_IER_RXBUFF);

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

		/* Configure and enable interrupt of USART. */
		NVIC_SetPriority((IRQn_Type)USART0_IRQn, USART0_PRIO);
		NVIC_EnableIRQ(USART0_IRQn);

		busart_chn_open[chn] = true;
		num_bytes_rx_usart0 = 0;

		/* Configure TC usart */
		_configure_TC_usart();
		tc_start(TC_USART, TC_USART_CHN);

		return true;
	}
	break;
#endif
#ifdef CONF_BOARD_USART1_RXD
	case 1:
	{
		/* Configure PMC. */
		pmc_enable_periph_clk(ID_USART1);
		/* Configure USART. */
		usart_init_rs232(USART1, &usart_console_settings,
				sysclk_get_peripheral_hz());

		/* Assign buffers to pointers */
		busart_comm_data_1.puc_tq_buf = ptr_tx_usart_buf1;
		busart_comm_data_1.puc_rq_buf = ptr_rx_usart_buf1;
		busart_comm_data_1.us_rq_count = 0;
		busart_comm_data_1.us_rq_idx = 0;
		busart_comm_data_1.us_wq_idx = 0;

		/* Get board USART1 PDC base address and enable receiver and
		 * transmitter. */
		g_p_usart_pdc1 = usart_get_pdc_base(USART1);
		pdc_enable_transfer(g_p_usart_pdc1,
				PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);

		/* Start receiving data and start timer. */
		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);

		/* Stop transmitting data */
		g_st_usart_tx_packet1.ul_addr = (uint32_t)busart_comm_data_1.puc_tq_buf;
		g_st_usart_tx_packet1.ul_size = 0;
		pdc_tx_init(g_p_usart_pdc1, &g_st_usart_tx_packet1, NULL);

		gs_ul_size_usart_buf1 = USART_BUFFER_SIZE;

		/* Transfer to PDC communication mode, disable RXRDY interrupt
		 * and enable RXBUFF interrupt. */
		usart_disable_interrupt(USART1, US_IDR_RXRDY);
		usart_enable_interrupt(USART1, US_IER_RXBUFF);

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

		/* Configure and enable interrupt of USART. */
		NVIC_SetPriority((IRQn_Type)USART1_IRQn, USART1_PRIO);
		NVIC_EnableIRQ(USART1_IRQn);

		busart_chn_open[chn] = true;
		num_bytes_rx_usart1 = 0;

		/* Configure TC usart */
		_configure_TC_usart();
		tc_start(TC_USART, TC_USART_CHN);

		return true;
	}
	break;
#endif
	default:
		return false;
	}
}
Exemple #23
0
void uart_config(uint8_t port, usb_cdc_line_coding_t * cfg)
{
	Usart* usart = get_usart(port);
	uint32_t stopbits, parity, databits;
	uint32_t imr;

	switch (cfg->bCharFormat) {
	case CDC_STOP_BITS_2:
		stopbits = US_MR_NBSTOP_2_BIT;
		break;
	case CDC_STOP_BITS_1_5:
		stopbits = US_MR_NBSTOP_1_5_BIT;
		break;
	case CDC_STOP_BITS_1:
	default:
		// Default stop bit = 1 stop bit
		stopbits = US_MR_NBSTOP_1_BIT;
		break;
	}

	switch (cfg->bParityType) {
	case CDC_PAR_EVEN:
		parity = US_MR_PAR_EVEN;
		break;
	case CDC_PAR_ODD:
		parity = US_MR_PAR_ODD;
		break;
	case CDC_PAR_MARK:
		parity = US_MR_PAR_MARK;
		break;
	case CDC_PAR_SPACE:
		parity = US_MR_PAR_SPACE;
		break;
	default:
	case CDC_PAR_NONE:
		parity = US_MR_PAR_NO;
		break;
	}
	
	switch(cfg->bDataBits) {
	case 5: case 6: case 7:
		databits = cfg->bDataBits - 5;
		break;
	default:
	case 8:
		databits = US_MR_CHRL_8_BIT;
		break;
	}

	// Options for USART.
	usart_options.baudrate = LE32_TO_CPU(cfg->dwDTERate);
	usart_options.char_length = databits;
	usart_options.parity_type = parity;
	usart_options.stop_bits = stopbits;
	usart_options.channel_mode = US_MR_CHMODE_NORMAL;
	imr = usart_get_interrupt_mask(usart);
	usart_disable_interrupt(usart, 0xFFFFFFFF);
	usart_init_rs232(usart, &usart_options,
			sysclk_get_peripheral_hz());
	// Restore both RX and TX
	usart_enable_tx(usart);
	usart_enable_rx(usart);
	usart_enable_interrupt(usart, imr);
}
Exemple #24
0
OSStatus platform_uart_init( platform_uart_driver_t* driver, const platform_uart_t* peripheral, const platform_uart_config_t* config, ring_buffer_t* optional_ring_buffer )
{
    pdc_packet_t      pdc_uart_packet, pdc_uart_tx_packet;
    OSStatus          err = kNoErr;
    sam_usart_opt_t   settings;
    bool              hardware_shaking = false;

    platform_mcu_powersave_disable();

    require_action_quiet( ( driver != NULL ) && ( peripheral != NULL ) && ( config != NULL ), exit, err = kParamErr);
    require_action_quiet( (optional_ring_buffer->buffer != NULL ) && (optional_ring_buffer->size != 0), exit, err = kUnsupportedErr);

    driver->rx_size              = 0;
    driver->tx_size              = 0;
    driver->rx_ring_buffer       = optional_ring_buffer;
    driver->last_transmit_result = kNoErr;
    driver->last_receive_result  = kNoErr;
    driver->peripheral           = (platform_uart_t*)peripheral;
#ifndef NO_MICO_RTOS
    mico_rtos_init_semaphore( &driver->tx_complete, 1 );
    mico_rtos_init_semaphore( &driver->rx_complete, 1 );
    mico_rtos_init_semaphore( &driver->sem_wakeup,  1 );
    mico_rtos_init_mutex    ( &driver->tx_mutex );
#else
    driver->tx_complete = false;
    driver->rx_complete = false;
#endif

    /* Set Tx and Rx pin mode to UART peripheral */
    platform_gpio_peripheral_pin_init( peripheral->tx_pin, ( peripheral->tx_pin_mux_mode | IOPORT_MODE_PULLUP ) );
    platform_gpio_peripheral_pin_init( peripheral->rx_pin, ( peripheral->rx_pin_mux_mode | IOPORT_MODE_PULLUP ) );

    /* Init CTS and RTS pins (if available) */
    if ( peripheral->cts_pin != NULL && (config->flow_control == FLOW_CONTROL_CTS || config->flow_control == FLOW_CONTROL_CTS_RTS) )
    {
        hardware_shaking = true;
        platform_gpio_peripheral_pin_init( peripheral->cts_pin, ( peripheral->cts_pin_mux_mode | IOPORT_MODE_PULLUP ) );
    }

    if ( peripheral->rts_pin != NULL && (config->flow_control == FLOW_CONTROL_CTS || config->flow_control == FLOW_CONTROL_CTS_RTS) )
    {
        hardware_shaking = true;
        platform_gpio_peripheral_pin_init( peripheral->rts_pin, ( peripheral->rts_pin_mux_mode | IOPORT_MODE_PULLUP ) );
    }

    /* Enable the clock. */
    if( pmc_is_periph_clk_enabled( peripheral->peripheral_id ) == 0  ) {
        flexcom_enable( peripheral->flexcom_base );
    }
    flexcom_set_opmode( peripheral->flexcom_base, FLEXCOM_USART );

    /* Enable the receiver and transmitter. */
    usart_reset_tx( peripheral->port );
    usart_reset_rx( peripheral->port );

    /* Disable all the interrupts. */
    usart_disable_interrupt( peripheral->port, 0xffffffff );

    switch ( config->parity ) {
    case NO_PARITY:
        settings.parity_type = US_MR_PAR_NO;
        break;
    case EVEN_PARITY:
        settings.parity_type = US_MR_PAR_EVEN;
        break;
    case ODD_PARITY:
        settings.parity_type = US_MR_PAR_ODD;
        break;
    default:
        err = kParamErr;
        goto exit;
    }
    switch ( config->data_width) {
    case DATA_WIDTH_5BIT:
        settings.char_length = US_MR_CHRL_5_BIT;
        break;
    case DATA_WIDTH_6BIT:
        settings.char_length = US_MR_CHRL_6_BIT;
        break;
    case DATA_WIDTH_7BIT:
        settings.char_length = US_MR_CHRL_7_BIT;
        break;
    case DATA_WIDTH_8BIT:
        settings.char_length = US_MR_CHRL_8_BIT;
        break;
    case DATA_WIDTH_9BIT:
        settings.char_length = US_MR_MODE9;
        break;
    default:
        err = kParamErr;
        goto exit;
    }
    settings.baudrate = config->baud_rate;
    settings.stop_bits = ( config->stop_bits == STOP_BITS_1 ) ? US_MR_NBSTOP_1_BIT : US_MR_NBSTOP_2_BIT;
    settings.channel_mode= US_MR_CHMODE_NORMAL;

    /* Configure USART in serial mode. */
    if (!hardware_shaking) {
        usart_init_rs232( peripheral->port, &settings, sysclk_get_peripheral_hz());
    } else {
        usart_init_hw_handshaking( peripheral->port, &settings, sysclk_get_peripheral_hz());
    }

    /* Enable uart interrupt */
    NVIC_SetPriority( platform_flexcom_irq_numbers[peripheral->uart_id], 0x06 );
    NVIC_EnableIRQ( platform_flexcom_irq_numbers[peripheral->uart_id] );

    /* Enable PDC transmit */
    pdc_enable_transfer( usart_get_pdc_base( peripheral->port ), PERIPH_PTCR_TXTEN | PERIPH_PTCR_RXTEN );
    pdc_disable_transfer( usart_get_pdc_base( driver->peripheral->port ), PERIPH_PTCR_TXTDIS );

    pdc_uart_packet.ul_addr = (uint32_t)driver->rx_ring_buffer->buffer;
    pdc_uart_packet.ul_size = (uint32_t)driver->rx_ring_buffer->size;
    pdc_rx_init( usart_get_pdc_base( peripheral->port ), &pdc_uart_packet, &pdc_uart_packet );

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

    pdc_tx_init( usart_get_pdc_base( driver->peripheral->port ), &pdc_uart_tx_packet, NULL );

    usart_enable_interrupt( peripheral->port, US_IER_ENDRX | US_IER_RXBUFF | US_IER_RXRDY | US_IER_ENDTX );

    /* Enable the receiver and transmitter. */
    usart_enable_tx( peripheral->port );
    usart_enable_rx( peripheral->port );

exit:
    platform_mcu_powersave_enable( );
    return err;
}
/**
 * \brief Application entry point.
 *
 * Configure USART in synchronous master/slave mode to start a transmission
 * between two boards.
 * \return Unused.
 */
int main(void)
{
	uint8_t uc_char;
	uint8_t *p_data;

	/* Initialize the SAM system. */
	sysclk_init();
	board_init();

	/* Configure UART for debug message output. */
	configure_console();

	/* Output example information. */
	puts(STRING_HEADER);

	/* Display main menu. */
	display_main_menu();

	/* Configure USART. */
	configure_usart(SYNC_MASTER, g_ul_freq[g_uc_freq_idx]);

	g_uc_transfer_mode = SYNC_MASTER;

	g_uc_state = STATE_WRITE;

	puts("-- USART in MASTER mode --\r");

	while (1) {
		uc_char = 0;
		scanf("%c", (char *)&uc_char);
		switch (uc_char) {
		case '0':
		case '1':
		case '2':
		case '3':
			g_uc_freq_idx = uc_char - '0';
			printf("-- The clock freq is: %luHz.\r\n",
				(unsigned long)g_ul_freq[g_uc_freq_idx]);
			configure_usart(SYNC_MASTER, g_ul_freq[g_uc_freq_idx]);
			break;
		case 'i':
		case 'I':
			if (g_uc_transfer_mode == SYNC_MASTER) {
				printf("-- USART is MASTER at %luHz.\r\n",
					(unsigned long)g_ul_freq[g_uc_freq_idx]);
			} else {
				puts("-- USART is SLAVE \r");
			}
			break;
		case 's':
		case 'S':
			if (g_uc_transfer_mode == SYNC_MASTER) {
				g_uc_transfer_mode = SYNC_SLAVE;
				configure_usart(SYNC_SLAVE, g_ul_freq[g_uc_freq_idx]);
				puts("-- USART in SLAVE mode --\r");
			} else {
				if (g_uc_transfer_mode == SYNC_SLAVE) {
					g_uc_transfer_mode = SYNC_MASTER;
					configure_usart(SYNC_MASTER, g_ul_freq[g_uc_freq_idx]);
					puts("-- USART in MASTER mode --\r");
				}
			}
			break;
		case 'w':
		case 'W':
			g_uc_state = STATE_WRITE;
			p_data = (uint8_t *)&tran_buff[0];
			transmit_mode_sync(p_data, BUFFER_SIZE);

			while (!g_ul_sent_done) {
			}
			if (g_ul_sent_done) {
				printf("-- %s sent done --\r\n",
						g_uc_transfer_mode ? "MASTER" :
						"SLAVE");
			}
			break;
		case 'r':
		case 'R':
			g_uc_state = STATE_READ;
			g_ulcount = 0;
			p_revdata = &g_c_recv_buff[0];
			if (g_uc_transfer_mode == SYNC_MASTER) {
				puts("----USART MASTER Read----\r");
			} else {
				puts("----USART SLAVE Read----\r");
			}

			usart_enable_interrupt(BOARD_USART, US_IER_RXRDY);

			while (!g_ul_recv_done) {
			}
			if (g_ul_recv_done) {
				if (strncmp((char*)g_c_recv_buff, tran_buff, BUFFER_SIZE)) {
					puts(" -F-: Failed!\r");
				} else {
					/* successfully received */
					dump_info((char*)g_c_recv_buff, BUFFER_SIZE);
				}
				puts("----END of read----\r");
				memset(g_c_recv_buff, 0, sizeof(g_c_recv_buff));
				g_ul_recv_done = false;
			}
			break;
		case 'm':
		case 'M':
			display_main_menu();
			break;
		default:
			break;
		}
	}
}
/*
 * For internal use only.
 * Configures the Rx DMA to receive data into free space within the Rx buffer.
 */
static void configure_rx_dma(uint32_t usart_index,
		enum buffer_operations operation_performed)
{
	freertos_pdc_rx_control_t *rx_buffer_definition;

	rx_buffer_definition = &(rx_buffer_definitions[usart_index]);

	/* How much space is there between the start of the DMA buffer and the
	current read pointer?  */

	if (((uint32_t)rx_buffer_definition->next_byte_to_read) ==
			rx_buffer_definition->rx_pdc_parameters.ul_addr) {
		/* The read pointer and the write pointer are equal.  If this function
		was called because data was added to the buffer, then there is no free
		space in the buffer remaining.  If this function was called because data
		was removed from the buffer, then the space remaining is from the write
		pointer up to the end of the buffer. */
		if (operation_performed == data_added) {
			rx_buffer_definition->rx_pdc_parameters.ul_size = 0UL;
		} else {
			rx_buffer_definition->rx_pdc_parameters.ul_size =
				rx_buffer_definition->past_rx_buffer_end_address - rx_buffer_definition->rx_pdc_parameters.ul_addr;
		}
	} else if (((uint32_t)rx_buffer_definition->next_byte_to_read) >
			rx_buffer_definition->rx_pdc_parameters.ul_addr) {
		/* The read pointer is ahead of the write pointer.  The space available
		is up to the write pointer to ensure unread data is not overwritten. */
		rx_buffer_definition->rx_pdc_parameters.ul_size =
			((uint32_t) rx_buffer_definition->next_byte_to_read) - rx_buffer_definition->rx_pdc_parameters.ul_addr;
	} else {
		/* The write pointer is ahead of the read pointer so the space
		available is up to the end of the buffer. */
		rx_buffer_definition->rx_pdc_parameters.ul_size =
			rx_buffer_definition->past_rx_buffer_end_address - rx_buffer_definition->rx_pdc_parameters.ul_addr;
	}

	configASSERT((rx_buffer_definition->rx_pdc_parameters.ul_addr +
			rx_buffer_definition->rx_pdc_parameters.ul_size) <=
			rx_buffer_definition->past_rx_buffer_end_address);

	if (rx_buffer_definition->rx_pdc_parameters.ul_size > 0) {
		/* Restart the DMA to receive into whichever space was calculated
		as remaining.  First clear any characters that might already be in the
		registers. */
		pdc_rx_init(
				all_usart_definitions[usart_index].pdc_base_address, &rx_buffer_definition->rx_pdc_parameters,
				NULL);
		pdc_enable_transfer(
				all_usart_definitions[usart_index].pdc_base_address,
				PERIPH_PTCR_RXTEN);
		usart_enable_interrupt(
				all_usart_definitions[usart_index].peripheral_base_address, US_IER_ENDRX |
				US_IER_TIMEOUT);
	} else {
		/* The write pointer has reached the read pointer.  There is no
		more room so the DMA is not re-enabled until a read has created
		space. */
		usart_disable_interrupt(
				all_usart_definitions[usart_index].peripheral_base_address, US_IER_ENDRX |
				US_IER_TIMEOUT);
	}
}
/**
 * \ingroup freertos_usart_peripheral_control_group
 * \brief Initializes the FreeRTOS ASF USART driver for the specified USART
 * port.
 *
 * freertos_usart_serial_init() is an ASF specific FreeRTOS driver function.  It
 * must be called before any other ASF specific FreeRTOS driver functions
 * attempt to access the same USART port.
 *
 * If freertos_driver_parameters->operation_mode equals USART_RS232 then
 * freertos_usart_serial_init() will configure the USART port for standard RS232
 * operation.  If freertos_driver_parameters->operation_mode equals any other
 * value then freertos_usart_serial_init() will not take any action.
 *
 * Other ASF USART functions can be called after freertos_usart_serial_init()
 * has completed successfully.
 *
 * The FreeRTOS ASF driver both installs and handles the USART PDC interrupts.
 * Users do not need to concern themselves with interrupt handling, and must
 * not install their own interrupt handler.
 *
 * This driver is provided with an application note, and an example project that
 * demonstrates the use of this function.
 *
 * \param p_usart    The USART peripheral being initialized.
 * \param uart_parameters    Structure that defines the USART bus and transfer
 *     parameters, such the baud rate and the number of data bits.
 *     sam_usart_opt_t is a standard ASF type (it is not FreeRTOS specific).
 * \param freertos_driver_parameters    Defines the driver behavior.  See the
 *    freertos_peripheral_options_t documentation, and the application note that
 *    accompanies the ASF specific FreeRTOS functions.
 *
 * \return If the initialization completes successfully then a handle that can
 *     be used with FreeRTOS USART read and write functions is returned.  If
 *     the initialisation fails then NULL is returned.
 */
freertos_usart_if freertos_usart_serial_init(Usart *p_usart,
		const sam_usart_opt_t *const uart_parameters,
		const freertos_peripheral_options_t *const freertos_driver_parameters)
{
	portBASE_TYPE usart_index;
	bool is_valid_operating_mode;
	freertos_usart_if return_value;
	const enum peripheral_operation_mode valid_operating_modes[] = {USART_RS232};

	/* Find the index into the all_usart_definitions array that holds details of
	the p_usart peripheral. */
	usart_index = get_pdc_peripheral_details(all_usart_definitions,
			MAX_USARTS,
			(void *) p_usart);

	/* Check the requested operating mode is valid for the peripheral. */
	is_valid_operating_mode = check_requested_operating_mode(
			freertos_driver_parameters->operation_mode,
			valid_operating_modes,
			sizeof(valid_operating_modes) /
			sizeof(enum peripheral_operation_mode));

	/* Don't do anything unless a valid p_usart pointer was used, and a valid
	operating mode was requested. */
	if ((usart_index < MAX_USARTS) && (is_valid_operating_mode == true)) {
		/* This function must be called exactly once per supported USART.  Check it
		has not been called	before. */
		configASSERT(rx_buffer_definitions[usart_index].next_byte_to_read == NULL);

		/* Disable everything before enabling the clock. */
		usart_disable_tx(p_usart);
		usart_disable_rx(p_usart);
		pdc_disable_transfer(all_usart_definitions[usart_index].pdc_base_address,
				(PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS));

#if (SAMG55)
		/* Enable the peripheral and set USART mode. */
		uint32_t temp = (uint32_t)all_usart_definitions[usart_index].peripheral_base_address - 0x200;
		Flexcom *p_flexcom = (Flexcom *)temp;
		flexcom_enable(p_flexcom);
		flexcom_set_opmode(p_flexcom, FLEXCOM_USART);
#else
		/* Enable the peripheral clock in the PMC. */
		pmc_enable_periph_clk(
				all_usart_definitions[usart_index].peripheral_id);
#endif

		switch (freertos_driver_parameters->operation_mode) {
		case USART_RS232:
			/* Call the standard ASF init function. */
			usart_init_rs232(p_usart, uart_parameters,
					sysclk_get_cpu_hz());
			break;

		default:
			/* Other modes are not currently supported. */
			break;
		}

		/* Disable all the interrupts. */
		usart_disable_interrupt(p_usart, MASK_ALL_INTERRUPTS);

		/* Create any required peripheral access mutexes and transaction complete
		semaphores.  This peripheral is full duplex so only the Tx semaphores
		are created in the following function.  The the Rx semaphores are
		created	separately. */
		create_peripheral_control_semaphores(
				freertos_driver_parameters->options_flags,
				&(tx_dma_control[usart_index]),
				NULL /* The rx structures are not created in this function. */);

		/* Is the driver also going to receive? */
		if (freertos_driver_parameters->receive_buffer != NULL) {
			/* rx_event_semaphore is used to signal the arival of new data.  It
			must be a counting semaphore for the following reason:  If the Rx
			DMA places data at the end of its circular buffer it will give the
			semaphore to indicate the presence of unread data.  If it then
			receives more data, it will write this to the start of the circular
			buffer, then give the semaphore again.  Now, if a task reads data
			out of the same circular buffer, and requests less data than is
			available, but more than is available between the next read pointer
			and the end of the buffer, the actual amount returned will be
			capped to that available up to the end of the buffer only.  If this
			semaphore was a binary semaphore, it would then be 'taken' even
			though, unknown to the reading task, unread and therefore available
			data remained at the beginning of the buffer. */
			rx_buffer_definitions[usart_index].rx_event_semaphore =
					xSemaphoreCreateCounting(portMAX_DELAY, 0);
			configASSERT(rx_buffer_definitions[usart_index].rx_event_semaphore);

			/* Set the timeout to 5ms, then start waiting for a character (the
			timeout is not started until characters have started to	be
			received). */
			usart_set_rx_timeout(p_usart,
					(uart_parameters->baudrate / BITS_PER_5_MS));
			usart_start_rx_timeout(p_usart);

			/* The receive buffer is currently empty, so the DMA has control
			over the entire buffer. */
			rx_buffer_definitions[usart_index].rx_pdc_parameters.ul_addr =
					(uint32_t)freertos_driver_parameters->receive_buffer;
			rx_buffer_definitions[usart_index].rx_pdc_parameters.ul_size =
					freertos_driver_parameters->receive_buffer_size;
			pdc_rx_init(
					all_usart_definitions[usart_index].pdc_base_address,
					&(rx_buffer_definitions[usart_index].rx_pdc_parameters),
					NULL);

			/* Set the next byte to read to the start of the buffer as no data
			has yet been read. */
			rx_buffer_definitions[usart_index].next_byte_to_read =
					freertos_driver_parameters->receive_buffer;

			/* Remember the limits of entire buffer. */
			rx_buffer_definitions[usart_index].rx_buffer_start_address =
					rx_buffer_definitions[usart_index].rx_pdc_parameters.ul_addr;
			rx_buffer_definitions[usart_index].past_rx_buffer_end_address =
					rx_buffer_definitions[usart_index].rx_buffer_start_address +
					freertos_driver_parameters->receive_buffer_size;

			/* If the rx driver is to be thread aware, create an access control
			mutex. */
			if ((freertos_driver_parameters->options_flags &
					USE_RX_ACCESS_MUTEX) != 0) {
				rx_buffer_definitions[usart_index].rx_access_mutex =
					xSemaphoreCreateMutex();
				configASSERT(rx_buffer_definitions[usart_index].rx_access_mutex);
			}

			/* Catch the DMA running out of Rx space, and gaps in the
			reception.  These events are both used to signal that there is
			data available in the Rx buffer. */
			usart_enable_interrupt(p_usart, US_IER_ENDRX | US_IER_TIMEOUT);

			/* The Rx DMA is running all the time, so enable it now. */
			pdc_enable_transfer(
					all_usart_definitions[usart_index].pdc_base_address,
					PERIPH_PTCR_RXTEN);
		} else {
			/* next_byte_to_read is used to check to see if this function
			has been called before, so it must be set to something, even if
			it is not going to be used.  The value it is set to is not
			important, provided it is not zero (NULL). */
			rx_buffer_definitions[usart_index].next_byte_to_read = RX_NOT_USED;
		}

		/* Configure and enable the USART interrupt in the interrupt controller. */
		configure_interrupt_controller(all_usart_definitions[usart_index].peripheral_irq,
				freertos_driver_parameters->interrupt_priority);

		/* Error interrupts are always enabled. */
		usart_enable_interrupt(
				all_usart_definitions[usart_index].peripheral_base_address,
				IER_ERROR_INTERRUPTS);

		/* Finally, enable the receiver and transmitter. */
		usart_enable_tx(p_usart);
		usart_enable_rx(p_usart);

		return_value = (freertos_usart_if) p_usart;
	} else {
		return_value = NULL;
	}

	return return_value;
}
/**
 * \brief Application entry point.
 *
 * Configure USART in synchronous master/slave mode to start a transmission
 * between two boards.
 * \return Unused.
 */
int main(void)
{
	uint8_t uc_char;

	/* Initialize the SAM system. */
	sysclk_init();
	board_init();

	/* Configure UART for debug message output. */
	configure_console();

	/* Output example information. */
	puts(STRING_HEADER);

	/* Display main menu. */
	display_main_menu();

	/* Configure USART. */
	configure_usart(SYNC_MASTER, g_ul_freq[g_uc_freq_idx]);

	/* Get board USART PDC base address and enable receiver and transmitter. */
	g_p_pdc = usart_get_pdc_base(BOARD_USART);
	pdc_enable_transfer(g_p_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);

	g_uc_transfer_mode = SYNC_MASTER;

	g_uc_state = STATE_WRITE;

	puts("-- USART in MASTER mode --\r");

	while (1) {
		uc_char = 0;
		scanf("%c", (char *)&uc_char);
		switch (uc_char) {
		case '0':
		case '1':
		case '2':
		case '3':
			g_uc_freq_idx = uc_char - '0';
			printf("-- The clock freq is: %luHz.\r\n",
				(unsigned long)g_ul_freq[g_uc_freq_idx]);
			configure_usart(SYNC_MASTER, g_ul_freq[g_uc_freq_idx]);
			break;
		case 'i':
		case 'I':
			if (g_uc_transfer_mode == SYNC_MASTER) {
				printf("-- USART is MASTER at %luHz.\r\n",
					(unsigned long)g_ul_freq[g_uc_freq_idx]);
			} else {
				puts("-- USART is SLAVE \r");
			}
			break;
		case 's':
		case 'S':
			if (g_uc_transfer_mode == SYNC_MASTER) {
				g_uc_transfer_mode = SYNC_SLAVE;
				configure_usart(SYNC_SLAVE, g_ul_freq[g_uc_freq_idx]);
				puts("-- USART in SLAVE mode --\r");
			} else {
				if (g_uc_transfer_mode == SYNC_SLAVE) {
					g_uc_transfer_mode = SYNC_MASTER;
					configure_usart(SYNC_MASTER, g_ul_freq[g_uc_freq_idx]);
					puts("-- USART in MASTER mode --\r");
				}
			}
			break;
		case 'w':
		case 'W':
			g_uc_state = STATE_WRITE;
			g_st_packet.ul_addr = (uint32_t)tran_buff;
			g_st_packet.ul_size = BUFFER_SIZE;
			pdc_tx_init(g_p_pdc, &g_st_packet, NULL);
			usart_enable_interrupt(BOARD_USART, US_IER_TXBUFE);
			while (!g_ul_sent_done) {
			}
			if (g_ul_sent_done) {
				printf("-- %s sent done --\r\n",
						g_uc_transfer_mode ? "MASTER" :
						"SLAVE");
			}
			break;
		case 'r':
		case 'R':
			g_uc_state = STATE_READ;
			if (g_uc_transfer_mode == SYNC_MASTER) {
				puts("----USART MASTER Read----\r");
			} else {
				puts("----USART SLAVE Read----\r");
			}
			g_st_packet.ul_addr = (uint32_t)g_c_recv_buff;
			g_st_packet.ul_size = BUFFER_SIZE;
			pdc_rx_init(g_p_pdc, &g_st_packet, NULL);
			usart_enable_interrupt(BOARD_USART, US_IER_RXBUFF);
			while (!g_ul_recv_done) {
			}
			if (g_ul_recv_done) {
				if (strncmp((char*)g_c_recv_buff, tran_buff, BUFFER_SIZE)) {
					puts(" -F-: Failed!\r");
				} else {
					/* successfully received */
					dump_info((char*)g_c_recv_buff, BUFFER_SIZE);
				}
				puts("----END of read----\r");
				memset(g_c_recv_buff, 0, sizeof(g_c_recv_buff));
				g_ul_recv_done = false;
			}
			break;
		case 'm':
		case 'M':
			display_main_menu();
			break;
		default:
			break;
		}
	}
}
/**
 *  \brief usart_rs485 Application entry point.
 *
 *  Configure USART in RS485 mode. If the application starts earlier, it acts
 *  as a receiver. Otherwise, it should be a transmitter.
 *
 *  \return Unused (ANSI-C compatibility).
 */
int main(void)
{
	static uint8_t uc_sync = SYNC_CHAR;
	uint32_t time_elapsed = 0;
	uint32_t ul_i;

	/* Initialize the SAM system. */
	sysclk_init();
	board_init();

	/* Configure UART for debug message output. */
	configure_console();

	/* Output example information. */
	puts(STRING_HEADER);

	/* Configure USART. */
	configure_usart();

	/* Get board USART PDC base address and enable receiver and transmitter. */
	g_p_pdc = usart_get_pdc_base(BOARD_USART);
	pdc_enable_transfer(g_p_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);

	/* 1ms tick. */
	configure_systick();

	/* Initialize receiving buffer to distinguish with the sent frame. */
	memset(g_uc_receive_buffer, 0x0, BUFFER_SIZE);

	/*
	 * Enable transmitter here, and disable receiver first, to avoid receiving
	 * characters sent by itself. It's necessary for half duplex RS485.
	 */
	usart_enable_tx(BOARD_USART);
	usart_disable_rx(BOARD_USART);

	/* Send a sync character XON (0x11). */
	g_st_packet.ul_addr = (uint32_t)&uc_sync;
	g_st_packet.ul_size = 1;
	pdc_tx_init(g_p_pdc, &g_st_packet, NULL);

	/* Delay until the line is cleared, an estimated time used. */
	wait(50);

	/* Read the acknowledgement. */
	g_st_packet.ul_addr = (uint32_t)&uc_sync;
	g_st_packet.ul_size = 1;
	pdc_rx_init(g_p_pdc, &g_st_packet, NULL);

	/* Then enable receiver. */
	usart_enable_rx(BOARD_USART);

	/* Wait until time out or acknowledgement is received. */
	time_elapsed = get_tick_count();
	while (!usart_is_rx_buf_end(BOARD_USART)) {
		if (get_tick_count() - time_elapsed > TIMEOUT) {
			break;
		}
	}

	/* If acknowledgement received in a short time. */
	if (usart_is_rx_buf_end(BOARD_USART)) {
		/* Acknowledgement. */
		if (uc_sync == ACK_CHAR) {
			/* Act as transmitter, start transmitting. */
			g_state = TRANSMITTING;
			puts("-I- Start transmitting!\r");
			g_st_packet.ul_addr = (uint32_t)g_uc_transmit_buffer;
			g_st_packet.ul_size = PDC_BUF_SIZE;
			pdc_tx_init(g_p_pdc, &g_st_packet, NULL);

			/* Enable transmitting interrupt. */
			usart_enable_interrupt(BOARD_USART, US_IER_ENDTX);
		}
	} else {
		/* Start receiving, act as receiver. */
		g_st_packet.ul_addr = (uint32_t)&uc_sync;
		g_st_packet.ul_size = 1;
		pdc_rx_init(g_p_pdc, &g_st_packet, NULL);
		puts("-I- Receiving sync character.\r");
		while (!usart_is_rx_buf_end(BOARD_USART)) {
		}

		/* Sync character is received. */
		if (uc_sync == SYNC_CHAR) {
			/* SEND XOff as acknowledgement. */
			uc_sync = ACK_CHAR;

			/*
			 * Delay to prevent the character from being discarded by
			 * transmitter due to responding too soon.
			 */
			wait(100);
			pio_set_pin_high(PIN_RE_IDX);
			g_st_packet.ul_addr = (uint32_t)&uc_sync;
			g_st_packet.ul_size = 1;
			pdc_tx_init(g_p_pdc, &g_st_packet, NULL);

			g_state = RECEIVING;
			puts("-I- Start receiving!\r");
			g_st_packet.ul_addr = (uint32_t)g_uc_receive_buffer;
			g_st_packet.ul_size = PDC_BUF_SIZE;
			pdc_rx_init(g_p_pdc, &g_st_packet, NULL);
			pio_set_pin_low(PIN_RE_IDX);
			/* Enable receiving interrupt. */
			usart_enable_interrupt(BOARD_USART, US_IER_ENDRX);
		}
	}
	while (g_state != RECEIVED) {
	}

	ul_i = 0;
	/* Print received frame out. */
	while ((ul_i < BUFFER_SIZE) && (g_uc_receive_buffer[ul_i] != '\0')) {
		if (g_uc_transmit_buffer[ul_i] != g_uc_receive_buffer[ul_i]) {
			puts("-E- Error occurred while receiving!\r");
			/* Infinite loop here. */
			while (1) {
			}
		}
		ul_i++;
	}
	puts("-I- Received successfully!\r");

	while (1) {
	}
}
Exemple #30
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] );
	}
}