示例#1
0
USART_ID usartOpen(USART_ID usartId, uint32_t ulWantedBaud, uint16_t uxTxQueueLength, uint16_t uxRxQueueLength )
{
	uint8_t * dataPtr;

	/* Create the ring-buffers for the USART. */
	if( (dataPtr = (uint8_t *)pvPortMalloc( sizeof(uint8_t) * uxRxQueueLength )))
		ringBuffer_InitBuffer( &(usartComBuf[usartId].xRxedChars), dataPtr, uxRxQueueLength);

	if( (dataPtr = (uint8_t *)pvPortMalloc( sizeof(uint8_t) * uxTxQueueLength )))
		ringBuffer_InitBuffer( &(usartComBuf[usartId].xCharsForTx), dataPtr, uxTxQueueLength);

	// create a working buffer for vsnprintf on the heap (so we can use extended RAM, if available).
	// create the structures on the heap (so they can be moved later).
	if( !(usartComBuf[usartId].workBuffer = (uint8_t *)pvPortMalloc( sizeof(uint8_t) * uxTxQueueLength )))
		usartComBuf[usartId].workBuffer = NULL;

	usartComBuf[usartId].workBufferSize = uxTxQueueLength; // size of the working buffer for vsnprintf
	usartComBuf[usartId].workBufferInUse = USART_VACANT;  // clear the occupation flag.

	portENTER_CRITICAL();  // Disable interrupts during configuration
	/*
	 * Calculate the baud rate register value from the equation in the data sheet. */

	/* As the 16MHz Arduino boards have bad karma for serial port, we're using the 2x clock U2X0 */
	// for Arduino at 16MHz; above data sheet calculation is wrong. Need below from <util/setbaud.h>
	// This provides correct rounding truncation to get closest to correct speed.
	// Normal mode gives 3.7% error, which is too much. Use 2x mode gives 2.1% error.
	// Or, use 22.1184 MHz over clock which gives 0.00% error, for all rates.

	// ulBaudRateCounter = ((configCPU_CLOCK_HZ + ulWantedBaud * 8UL) / (ulWantedBaud * 16UL) - 1); // for normal mode
	// ulBaudRateCounter = (uint16_t)((configCPU_CLOCK_HZ + ulWantedBaud * 4UL) / (ulWantedBaud * 8UL) - 1);  // for 2x mode
	*usartReg[usartId].ubbrPtr = (uint16_t)((configCPU_CLOCK_HZ + ulWantedBaud * 4UL) / (ulWantedBaud * 8UL) - 1);  // for 2x mode, using 16 bit avr-gcc capability.
	/* Set the 2x speed mode bit */
	*usartReg[usartId].ucsrAPtr = U2X_BIT;  /* bits 7:2 are status bits, bit 0 set to 0 disables multi-processor comms mode */

	/* Enable the Rx and Tx. Also enable the Rx interrupt. The Tx interrupt will get enabled later. */
	*usartReg[usartId].ucsrBPtr = RXCIE_BIT | RXEN_BIT | TXEN_BIT;

	/* Set the data bit register to 8n1. */
	/* Set to asycrhnoous USART (bits 7:6 set to 0), parity disables (bits 5:4 is 0) 1 stop bit (bit 3 set to 0)
	 * 8 data bits (UCSZ1, UCSZ0 set to 1)
	 */
	*usartReg[usartId].ucsrCPtr = UCSZ1_BIT | UCSZ0_BIT;  // 011 stored in UCSZ2:1 - bit UCSZ2 is zero in register ucsrB (above instruction)

	portEXIT_CRITICAL(); // Enables interrupts after configuration

	return usartId;
}
示例#2
0
xComPortHandle xSerialPortInitMinimal( eCOMPort ePort, uint32_t ulWantedBaud, uint16_t uxTxQueueLength, uint16_t uxRxQueueLength )
{
    uint8_t * dataPtr;

    xComPortHandle newComPort;

    /* Create the ring-buffers used by the serial communications task. */
    if( (dataPtr = (uint8_t *)pvPortMalloc( sizeof(uint8_t) * uxRxQueueLength )))
        ringBuffer_InitBuffer( &(newComPort.xRxedChars), dataPtr, uxRxQueueLength);

    if( (dataPtr = (uint8_t *)pvPortMalloc( sizeof(uint8_t) * uxTxQueueLength )))
        ringBuffer_InitBuffer( &(newComPort.xCharsForTx), dataPtr, uxTxQueueLength);

    // create a working buffer for vsnprintf on the heap (so we can use extended RAM, if available).
    // create the structures on the heap (so they can be moved later).
    if( !(newComPort.serialWorkBuffer = (uint8_t *)pvPortMalloc( sizeof(uint8_t) * uxTxQueueLength )))
        newComPort.serialWorkBuffer = NULL;

    newComPort.usart = ePort; // containing eCOMPort
    newComPort.serialWorkBufferSize = uxTxQueueLength; // size of the working buffer for vsnprintf
    newComPort.serialWorkBufferInUse = VACANT;  // clear the occupation flag.

    portENTER_CRITICAL();

    switch (newComPort.usart)
    {
    case USART0:
        /*
         * Calculate the baud rate register value from the equation in the data sheet. */

        /* As the 16MHz Arduino boards have bad karma for serial port, we're using the 2x clock U2X0 */
        // for Arduino at 16MHz; above data sheet calculation is wrong. Need below from <util/setbaud.h>
        // This provides correct rounding truncation to get closest to correct speed.
        // Normal mode gives 3.7% error, which is too much. Use 2x mode gives 2.1% error.
        // Or, use 22.1184 MHz over clock which gives 0.00% error, for all rates.

        // ulBaudRateCounter = ((configCPU_CLOCK_HZ + ulWantedBaud * 8UL) / (ulWantedBaud * 16UL) - 1); // for normal mode
        // ulBaudRateCounter = (uint16_t)((configCPU_CLOCK_HZ + ulWantedBaud * 4UL) / (ulWantedBaud * 8UL) - 1);  // for 2x mode
        UBRR0 = (uint16_t)((configCPU_CLOCK_HZ + ulWantedBaud * 4UL) / (ulWantedBaud * 8UL) - 1);  // for 2x mode, using 16 bit avr-gcc capability.

        /* Set the 2x speed mode bit */
        UCSR0A = _BV(U2X0);

        /* Enable the Rx and Tx. Also enable the Rx interrupt. The Tx interrupt will get enabled later. */
        UCSR0B = ( _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0));

        /* Set the data bit register to 8n1. */
        UCSR0C = ( _BV(UCSZ01) | _BV(UCSZ00) );

        break;

    case USART1:
#if defined(__AVR_ATmega324P__)  || defined(__AVR_ATmega644P__)|| defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega644PA__) ||defined(__AVR_ATmega640__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
        UBRR1 = (uint16_t)((configCPU_CLOCK_HZ + ulWantedBaud * 4UL) / (ulWantedBaud * 8UL) - 1);
        UCSR1A = _BV(U2X1);
        UCSR1B = ( _BV(RXCIE1) | _BV(RXEN1) | _BV(TXEN1));
        UCSR1C = ( _BV(UCSZ11) | _BV(UCSZ10) );

        break;
#endif

    case USART2:
    case USART3:
    default:
        break;
    }

    portEXIT_CRITICAL();

    return newComPort;
}