Example #1
0
platform_result_t platform_uart_transmit_bytes( platform_uart_driver_t* driver, const uint8_t* data_out, uint32_t size )
{
    UNUSED_PARAMETER(driver);
    UNUSED_PARAMETER(data_out);
    UNUSED_PARAMETER(size);
    pdc_packet_t dma_packet;

    /* Limitation: SAM4S doesn't support DMA transfer from embedded flash.
     * If data_out address is not within RAM range, use normal write to THR.
     */
    if ( data_out >= (const uint8_t*)RAM_START_ADDR && data_out < (const uint8_t*)RAM_END_ADDR )
    {
        /* Initialise TPR and TCR register values. TNPR and TNCR are unused */
        dma_packet.ul_addr = (uint32_t)data_out;
        dma_packet.ul_size = (uint32_t)size;
        pdc_tx_init( usart_get_pdc_base( driver->peripheral->peripheral ), &dma_packet, NULL );

        /* Enable Tx DMA transmission */
        pdc_enable_transfer( usart_get_pdc_base( driver->peripheral->peripheral ), PERIPH_PTCR_TXTEN );

        host_rtos_get_semaphore( &driver->tx_dma_complete, NEVER_TIMEOUT, WICED_FALSE );
    }
    else
    {
        while ( size > 0 )
        {
            usart_putchar( driver->peripheral->peripheral, (uint32_t)*data_out++ );
            size--;
        }
    }

    return PLATFORM_SUCCESS;
}
Example #2
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;
        }
    }
}
Example #3
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);

}
Example #4
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;
}
Example #5
0
platform_result_t platform_uart_deinit( platform_uart_driver_t* driver )
{

    usart_disable_interrupt( driver->peripheral->peripheral, 0xffffffff );

    NVIC_DisableIRQ( platform_uarts_irq_numbers[driver->peripheral->uart_id] );

    pdc_disable_transfer( usart_get_pdc_base( driver->peripheral->peripheral ), PERIPH_PTCR_TXTDIS | PERIPH_PTCR_RXTDIS );

    usart_disable_tx( driver->peripheral->peripheral );
    usart_disable_rx( driver->peripheral->peripheral );

    sysclk_disable_peripheral_clock( driver->peripheral->peripheral_id );

    platform_gpio_deinit( driver->peripheral->tx_pin );
    platform_gpio_deinit( driver->peripheral->rx_pin );

    if ( driver->peripheral->cts_pin != NULL )
    {
        platform_gpio_deinit( driver->peripheral->cts_pin );
    }

    if ( driver->peripheral->rts_pin != NULL )
    {
        platform_gpio_deinit( driver->peripheral->rts_pin );
    }

    host_rtos_deinit_semaphore( &driver->tx_dma_complete );
    host_rtos_deinit_semaphore( &driver->rx_dma_complete );

    driver->peripheral = NULL;
    memset( driver, 0, sizeof(platform_uart_driver_t) );

    return WICED_SUCCESS;
}
Example #6
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) {
	}
}
Example #7
0
void serial_tx_abort_asynch(serial_t *obj)
{
    /* Sanity check arguments */
    MBED_ASSERT(obj);
    Pdc *pdc_base;
    usart_disable_interrupt(_USART(obj), US_IER_TXBUFE);
    pdc_base = usart_get_pdc_base(_USART(obj));
    pdc_disable_transfer(pdc_base, PERIPH_PTCR_TXTEN);
    pSERIAL_S(obj)->acttra = false;
}
Example #8
0
OSStatus platform_uart_transmit_bytes( platform_uart_driver_t* driver, const uint8_t* data_out, uint32_t size )
{
    OSStatus      err = kNoErr;
    pdc_packet_t  pdc_uart_packet;

    platform_mcu_powersave_disable();

#ifndef NO_MICO_RTOS
    mico_rtos_lock_mutex( &driver->tx_mutex );
#endif

    require_action_quiet( ( driver != NULL ) && ( data_out != NULL ) && ( size != 0 ), exit, err = kParamErr);

    /* reset DMA transmission result. the result is assigned in interrupt handler */
    driver->last_transmit_result                    = kGeneralErr;
    driver->tx_size                                 = size;

    pdc_uart_packet.ul_addr = (uint32_t) data_out;
    pdc_uart_packet.ul_size = size;
    pdc_tx_init( usart_get_pdc_base( driver->peripheral->port ), &pdc_uart_packet, NULL);

    /* Enable Tx DMA transmission */
    pdc_enable_transfer( usart_get_pdc_base( driver->peripheral->port ), PERIPH_PTCR_TXTEN );

#ifndef NO_MICO_RTOS
    mico_rtos_get_semaphore( &driver->tx_complete, MICO_NEVER_TIMEOUT );
#else
    while( driver->tx_complete == false);
    driver->tx_complete = false;
#endif

exit:
#ifndef NO_MICO_RTOS
    mico_rtos_unlock_mutex( &driver->tx_mutex );
#endif
    platform_mcu_powersave_enable();
    return err;
}
Example #9
0
void serial_rx_abort_asynch(serial_t *obj)
{
    IRQn_Type irq_n = (IRQn_Type)0;
    /* Sanity check arguments */
    MBED_ASSERT(obj);
    Pdc *pdc_base;
    usart_disable_interrupt(_USART(obj), US_IER_RXBUFF);
    pdc_base = usart_get_pdc_base(_USART(obj));
    pdc_disable_transfer(pdc_base, PERIPH_PTCR_RXTEN);
    irq_n = get_serial_irq_num(obj);
    NVIC_ClearPendingIRQ(irq_n);
    NVIC_DisableIRQ(irq_n);
    pSERIAL_S(obj)->actrec = false;
}
Example #10
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;
			}
		}
	}
}
Example #11
0
OSStatus platform_uart_deinit( platform_uart_driver_t* driver )
{
    OSStatus          err = kNoErr;

    platform_mcu_powersave_disable();
    require_action_quiet( ( driver != NULL ), exit, err = kParamErr);

    usart_disable_interrupt( driver->peripheral->port, 0xffffffff );

    NVIC_DisableIRQ( platform_flexcom_irq_numbers[driver->peripheral->uart_id] );

    pdc_disable_transfer( usart_get_pdc_base( driver->peripheral->port ), PERIPH_PTCR_TXTDIS | PERIPH_PTCR_RXTDIS );

    usart_disable_tx( driver->peripheral->port );
    usart_disable_rx( driver->peripheral->port );

    if( pmc_is_periph_clk_enabled( driver->peripheral->peripheral_id ) == 1  ) {
        flexcom_disable( driver->peripheral->flexcom_base );
    }

    platform_gpio_deinit( driver->peripheral->tx_pin );
    platform_gpio_deinit( driver->peripheral->rx_pin );

    if ( driver->peripheral->cts_pin != NULL )
    {
        platform_gpio_deinit( driver->peripheral->cts_pin );
    }

    if ( driver->peripheral->rts_pin != NULL )
    {
        platform_gpio_deinit( driver->peripheral->rts_pin );
    }

#ifndef NO_MICO_RTOS
    mico_rtos_deinit_semaphore(&driver->rx_complete);
    mico_rtos_deinit_semaphore(&driver->tx_complete);
#endif

    driver->peripheral = NULL;
    memset( driver, 0, sizeof(platform_uart_driver_t) );

exit:
    platform_mcu_powersave_enable();
    return err;
}
/**
 *  \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) {
	}
}
Example #13
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;
	}
}
Example #14
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;
}
Example #15
0
/**
 * \brief Application entry point.
 *
 * Initialize the IrDA and start the main loop.
 *
 * \return Unused (ANSI-C compatibility).
 */
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);

	/* Initialize board 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);

	puts("-I- Press t to transmit, press r to receive...\r");

	/* Main loop. */
	while (1) {
		uc_char = 0;
		uart_read(CONSOLE_UART, (uint8_t *)&uc_char);

		switch (uc_char) {
		case 't':
		case 'T':
			g_uc_state = STATE_TRANSMIT;
			/* Enable transmitter. */
			func_transmitter();
			g_st_packet.ul_addr = (uint32_t)g_uc_send_data;
			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) {
			}

			puts("-I- Sent Done!\r");
			g_ul_sent_done = false;
			g_uc_state = STATE_IDLE;
			puts("-I- Press t to transmit, press r to receive...\r");
			break;

		case 'r':
		case 'R':
			g_uc_state = STATE_RECEIVE;

			/* Enable receiver. */
			puts("-I- IrDA receive mode\r");
			func_receiver();
			g_st_packet.ul_addr = (uint32_t)g_uc_recv_data;
			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) {
			}

			puts("-I- Received Done! \r");
			dump_recv_buf(g_uc_recv_data, BUFFER_SIZE);
			memset(g_uc_recv_data, 0, BUFFER_SIZE);
			g_uc_state = STATE_IDLE;
			g_ul_recv_done = false;
			puts("-I- Press t to transmit, press r to receive...\r");
			break;

		default:
			break;
		}
	}
}
Example #16
0
platform_result_t platform_uart_init( platform_uart_driver_t* driver, const platform_uart_t* peripheral, const platform_uart_config_t* config, wiced_ring_buffer_t* optional_ring_buffer )
{
    sam_usart_opt_t    settings;

    UNUSED_PARAMETER(driver);
    UNUSED_PARAMETER(peripheral);
    UNUSED_PARAMETER(config);
    UNUSED_PARAMETER(optional_ring_buffer);

    pdc_packet_t dma_packet;

    if ( config->flow_control != FLOW_CONTROL_DISABLED )
    {
        return WICED_UNSUPPORTED;
    }

    memset( &settings, 0, sizeof( settings ) );

    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:
        default:
            return WICED_UNSUPPORTED;
    }

    switch ( config->parity )
    {
        case ODD_PARITY:
            settings.parity_type = US_MR_PAR_ODD;
            break;
        case EVEN_PARITY:
            settings.parity_type = US_MR_PAR_EVEN;
            break;
        case NO_PARITY:
            settings.parity_type = US_MR_PAR_NO;
            break;
        default:
            break;
    }

    switch ( config->stop_bits )
    {
        case STOP_BITS_1:
            settings.stop_bits = US_MR_NBSTOP_1_BIT;
            break;
        case STOP_BITS_2:
            settings.stop_bits = US_MR_NBSTOP_2_BIT;
            break;
        default:
            break;
    }

    settings.baudrate     = config->baud_rate;
    settings.channel_mode = US_MR_CHMODE_NORMAL;


    driver->peripheral = peripheral;

//    /* Initialise TX and RX complete semaphores */
    host_rtos_init_semaphore( &driver->tx_dma_complete );
    host_rtos_init_semaphore( &driver->rx_dma_complete );

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

    /* Init CTS and RTS pins (if available) */
    if ( peripheral->cts_pin != NULL )
    {
        platform_gpio_peripheral_pin_init( peripheral->cts_pin, ( IOPORT_MODE_MUX_A | IOPORT_MODE_PULLUP ) );
    }

    if ( peripheral->rts_pin != NULL )
    {
        platform_gpio_peripheral_pin_init( peripheral->rts_pin, ( IOPORT_MODE_MUX_A | IOPORT_MODE_PULLUP ) );
    }

    /* Enable the peripheral clock in the PMC. */
    sysclk_enable_peripheral_clock( peripheral->peripheral_id );

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

    /* Configure USART in serial mode. */
    usart_init_rs232( peripheral->peripheral, &settings, CPU_CLOCK_HZ );

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

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

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

    driver->rx_ring_buffer = optional_ring_buffer;

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


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

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

    return PLATFORM_SUCCESS;
}
Example #17
0
	GCodeResult SetColours(GCodeBuffer& gb, const StringRef& reply)
	{
		if (busy)											// if we sent something
		{
			if ((DotStarUsart->US_CSR & US_CSR_ENDTX) == 0)	// if we are still sending
			{
				return GCodeResult::notFinished;
			}
			busy = false;									// we finished the last transfer
		}

		bool seen = false;
		uint32_t red = 0, green = 0, blue = 0, brightness = 16, numLeds = MaxChunkSize, following = 0;
		gb.TryGetUIValue('R', red, seen);
		gb.TryGetUIValue('U', green, seen);
		gb.TryGetUIValue('B', blue, seen);
		gb.TryGetUIValue('Y', brightness, seen);
		gb.TryGetUIValue('S', numLeds, seen);
		gb.TryGetUIValue('F', following, seen);
		if (!seen || (numLeds == 0 && !needStartFrame && !following))
		{
			return GCodeResult::ok;
		}

		if (numRemaining != 0)
		{
			numLeds = numRemaining;												// we have come back to do another chunk
		}

		// Set up the data in the DMA buffer.
		// Sending at least 32 zero bits (start frame) tells the LEDs that this is new data starting with the first LED in the strip.
		// The first 1 bit indicates the start of the data frame for the first LED.
		// There is a half-bit delay in each LED before the data is shifted out to the next LED. This means that we need to send at least an extra N/2 bits of data,
		// where N is the number of LEDs in the strip. The datasheet says to send 32 bits of 1 but this is only sufficient for up to 64 LEDs. Sending 1s can lead to a spurious
		// white LED at the end if we don't provide data for all the LEDs. So instead we send 32 or more bits of zeros.
		// See https://cpldcpu.wordpress.com/2014/11/30/understanding-the-apa102-superled/ for more.
		unsigned int spaceLeft = MaxChunkSize;
		uint32_t *p = chunkBuffer;
		if (needStartFrame)
		{
			*p++ = 0;															// start frame
			--spaceLeft;														// one less slot available for data
			totalSent = 0;
		}

		// Can we fit the remaining data and stop bits in the buffer?
		unsigned int numStopWordsNeeded = (following) ? 0 : min<unsigned int>((numLeds + totalSent + 63)/64, MaxChunkSize - 1);
		unsigned int thisChunk;
		if (numLeds + numStopWordsNeeded <= spaceLeft)
		{
			thisChunk = numLeds;
		}
		else
		{
			thisChunk = min<unsigned int>(spaceLeft, numLeds - 1);
			numStopWordsNeeded = 0;
		}

		numRemaining = numLeds - thisChunk;
		totalSent += thisChunk;
		needStartFrame = (numRemaining == 0 && following == 0);

		for (unsigned int i = 0; i < thisChunk; ++i)
		{
			// According to the Adafruit web site, current production uses the order BGR
			*p++ = (brightness & 31) | 0xE0 | ((blue & 255) << 8) | ((green & 255) << 16) | ((red & 255) << 24);	// LED frame
		}

		for (unsigned int i = 0; i < numStopWordsNeeded; ++i)
		{
			*p++ = 0;															// append some stop bits
		}

		// DMA the data
		DotStarUsart->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_TXDIS;			// reset transmitter and receiver, disable transmitter
		Pdc * const usartPdc = usart_get_pdc_base(DotStarUsart);
		usartPdc->PERIPH_PTCR = PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS;		// disable the PDC
		usartPdc->PERIPH_TPR = reinterpret_cast<uint32_t>(&chunkBuffer);
		usartPdc->PERIPH_TCR = 4 * (p - chunkBuffer);							// number of bytes to transfer
		usartPdc->PERIPH_PTCR = PERIPH_PTCR_TXTEN;								// enable the PDC to send data

		DotStarUsart->US_CR = US_CR_TXEN;										// enable transmitter

		busy = true;
		return (numRemaining == 0) ? GCodeResult::ok : GCodeResult::notFinished;
	}
/**
 * \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;
		}
	}
}