Ejemplo n.º 1
0
Archivo: uart.c Proyecto: MatKub/RIOT
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
{
    /* do basic initialization */
    int res = uart_init_blocking(uart, baudrate);
    if(res < 0) {
        return res;
    }

    /* remember callback addresses */
    uart_config[uart].rx_cb = rx_cb;
    uart_config[uart].arg = arg;

    /* enable receive and send interrupt */
    switch(uart) {
#if UART_0_EN
    case UART_0:
    NVIC_SetPriority(UART_0_IRQ_RX_CHAN, UART_0_IRQ_RX_PRIO);
    NVIC_EnableIRQ(UART_0_IRQ_RX_CHAN);
    USART_IntEnable(UART_0_DEV, _USART_IEN_RXDATAV_MASK);
#if UART_0_ENABLE_BUF
    ringbuffer_init(&rb_uart0, buffer0, UART_0_BUFSIZE);
    NVIC_SetPriority(UART_0_IRQ_TX_CHAN, UART_0_IRQ_TX_PRIO);
    NVIC_EnableIRQ(UART_0_IRQ_TX_CHAN);
    USART_IntEnable(UART_0_DEV, _USART_IEN_TXBL_MASK);
#endif
    break;
#endif
#if UART_1_EN
    case UART_1:
    NVIC_SetPriority(UART_1_IRQ_RX_CHAN, UART_1_IRQ_RX_PRIO);
    NVIC_SetPriority(UART_1_IRQ_TX_CHAN, UART_1_IRQ_TX_PRIO);
    NVIC_EnableIRQ(UART_1_IRQ_RX_CHAN);
    NVIC_EnableIRQ(UART_1_IRQ_TX_CHAN);
    USART_IntEnable(UART_1_DEV, _USART_IEN_RXDATAV_MASK);
#if UART_1_ENABLE_BUF
    ringbuffer_init(&rb_uart1, buffer1, UART_1_BUFSIZE);
    NVIC_SetPriority(UART_1_IRQ_TX_CHAN, UART_1_IRQ_TX_PRIO);
    NVIC_EnableIRQ(UART_1_IRQ_TX_CHAN);
    USART_IntEnable(UART_1_DEV, _USART_IEN_TXBL_MASK);
#endif
    break;
#endif
    /* UART2 is considered as LEUART device which is functionable in low power mode */
#if UART_2_EN
    case UART_2:
        NVIC_SetPriority(UART_2_IRQ, UART_2_IRQ_PRIO);
        NVIC_EnableIRQ(UART_2_IRQ);
        LEUART_IntEnable(UART_2_DEV, LEUART_IEN_RXDATAV);
#if UART_2_ENABLE_BUF
        ringbuffer_init(&rb_uart2, buffer2, UART_2_BUFSIZE);
        LEUART_IntEnable(UART_2_DEV, _LEUART_IEN_TXBL_MASK);
#endif
        break;
#endif
    default:
        /* Invalid usart device */
        return -1;
    }
    return 0;
}
Ejemplo n.º 2
0
static void leuartInit(void)
{
    LEUART_Init_TypeDef leuart0Init;
    leuart0Init.enable = leuartEnable;       /* Activate data reception on LEUn_TX pin. */
    leuart0Init.refFreq = 0;                 /* Inherit the clock frequenzy from the LEUART clock source */
    leuart0Init.baudrate = LEUART0_BAUDRATE; /* Baudrate = 9600 bps */
    leuart0Init.databits = leuartDatabits8;  /* Each LEUART frame containes 8 databits */
    leuart0Init.parity = leuartNoParity;     /* No parity bits in use */
    leuart0Init.stopbits = leuartStopbits2;  /* Setting the number of stop bits in a frame to 2 bitperiods */

    CMU_ClockEnable(cmuClock_CORELE, true);
    CMU_ClockEnable(cmuClock_LEUART0, true);

    LEUART_Reset(LEUART0);
    LEUART_Init(LEUART0, &leuart0Init);

    LEUART0->SIGFRAME = '\n';

    /* Enable LEUART Signal Frame Interrupt */
    LEUART_IntEnable(LEUART0, LEUART_IEN_SIGF);

    /* Enable LEUART0 interrupt vector */
    NVIC_SetPriority(LEUART0_IRQn, LEUART0_INT_PRIORITY);

    LEUART0->ROUTE = LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN | LEUART0_LOCATION;

    GPIO_PinModeSet(LEUART0_PORT, LEUART0_TX, gpioModePushPull, 1);
    GPIO_PinModeSet(LEUART0_PORT, LEUART0_RX, gpioModeInputPull, 1);

    lineEndReceived = xSemaphoreCreateBinary();

    DMADRV_AllocateChannel(&dmaChannel, NULL);
}
/*
 *Function name: LEUART0_IRQHandler
 *Description : Interrupt Service Routine for LEUART0.
 */
void LEUART0_IRQHandler(void)
{
	leuartif = LEUART_IntGet(LEUART0); 	// Store the interrupt flag

	LEUART_IntClear(LEUART0, leuartif); //Clear interrupts

	if (leuartif & LEUART_IF_SIGF)
	{
		int temp = 0, i = 0;
		char tempChar[7];						// To store the Value of Temperature in char to transmit
		char temp_string[TX_bufferSize];	// Concatenated string for Message and Temperature, this will be transfered
		char copyCmp[sizeof(commandString)/sizeof(char)];							// string to store the Received string from Buffer to compare

		// Stop the LEUART reception and DMA Transfers
		for (i = 0; i < (strlen(commandString)); i++)		// Run loop till the return message (RetTemp!) length and copy RX buffer to copyCmp for comparing

		{
			copyCmp[i] = RX_Buffer[i];
		}

		copyCmp[8]='\0';

    	/* To extract the digits of the temperature variable and put in tempChar. A basic digit extraction algorithm is used and then each digit is passed one by one. */
		if (!strcmp(commandString,copyCmp)) 			// If valid Command is Received ie RetTemp!
		{
			temp = temperature*10;
			tempChar[0] = (temp/100)+48;
			temp = temp%100;
			tempChar[1] = (temp/10)+48;
			temp  = temp%10;
			tempChar[2] = '.';
			tempChar[3] = (temp)+48;
			tempChar[4] = 'C';
			tempChar[5] = '\r';
			tempChar[6] = '\n';

			strcpy(temp_string,returnMsg);					//Copy the returnMsg message in the temporary string
			strcat(temp_string,tempChar);					// Concatenate with tempChar to get the final message to be transfered

			// Enable DMA wake-up from LEUART0 TX
			LEUART0->CTRL = LEUART_CTRL_TXDMAWU;				// Enable DMA wake up for LEUART TX in EM2
			// Activate DMA for LEUART TX transfers
			DMA_ActivateBasic(DMA_CHANNEL_TX, true, false, (void *)&(LEUART0->TXDATA), (void *)temp_string, strlen(temp_string)- 1);	// -1 for the Null character which we wont transmit
		}
		else
		{
			LEUART0->CTRL = LEUART_CTRL_TXDMAWU;				// Enable DMA wake up for LEUART0 TX in EM2
			// Activate DMA for LEUART TX transfers
			DMA_ActivateBasic(DMA_CHANNEL_TX, true, false, (void *)&(LEUART0->TXDATA), (void *)errorMsg, strlen(errorMsg)-2);	// -1 for the Null character which we wont transmit
		}
		LEUART_IntEnable(LEUART0, LEUART_IF_RXDATAV); //Enable RXDATA Interrupt to check for received characters
		DMA_ActivateBasic(DMA_CHANNEL_RX, true, false, NULL, NULL, LEUART0_BUFFER-1);
	}
	else if (leuartif & LEUART_IF_RXDATAV)
	{
		LEUART_IntDisable(LEUART0, LEUART_IF_RXDATAV);	// Disable after receiving
	}

}
/*
 * Function Name: main();
 * Description: All the function calls are done in main(). The CPU goes to sleep while in main(); until Interupt is generated.
 */
int main(void)
{

    CHIP_Init();

    CMU_HFRCOBandSet(cmuHFRCOBand_14MHz);
    CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFRCO);
    CMU_OscillatorEnable(cmuOsc_HFXO, false, false);

    blockSleepMode(EM2); //Prevents the CPU to go below EM3 mode.

#if DEBUG_ON
    BSP_TraceSwoSetup(); //For simplicity studio Energy profiler code correlation.
#endif
    LETIMER_setup(); //Initialize LETIMER.

    ADC_Setup(); //Initialize the ADC

    DMA_Init();	//Initialize DMA.

    DMA_Setup(); //Setup DMA.

    LEUART_Setup(); //Initialize LEUART.

    GPIO_Init(); //Initialize GPOIs.

    LETIMER_IntEnable(LETIMER0, LETIMER_IF_UF); //Enable underflow UF interrupt.

    LEUART_IntEnable(LEUART0, LEUART_IF_SIGF);	// Enable SF RXDATAV

    NVIC_EnableIRQ(LETIMER0_IRQn); //Enable LETIMER0 interrupt vector in NVIC (Nested Vector Interrupt Controller)

    NVIC_EnableIRQ(LEUART0_IRQn); //Enable LETIMER0 interrupt vector in NVIC (Nested Vector Interrupt Controller)

	LEUART0->SIGFRAME = '!';							// Set LEUART signal frame to '!'

	LEUART0->CTRL |= LEUART_CTRL_RXDMAWU;				// Enable DMA wake up for LEUART RX in EM2
    DMA_ActivateBasic(DMA_CHANNEL_RX, true, false, (void *)RX_Buffer, (void *)&(LEUART0->RXDATA), LEUART0_BUFFER-1);

    // Enable Sleep-on-Exit
#if SLEEPONEXIT
    SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;	// Setting the corresponding bit for SleepOnExit
#endif

    while(1)
    {
        sleep(); //CPU goes to EM3 Mode to save energy, waits there until Interrupt is generated.
    }

}
Ejemplo n.º 5
0
/**************************************************************************//**
 * @brief UART/LEUART IRQ Handler
 *****************************************************************************/
void RETARGET_IRQ_NAME(void)
{
#if defined(RETARGET_USART)
  if (RETARGET_UART->STATUS & USART_STATUS_RXDATAV)
  {
#else
  if (RETARGET_UART->IF & LEUART_IF_RXDATAV)
  {
#endif

    /* Store Data */
    rxBuffer[rxWriteIndex] = RETARGET_RX(RETARGET_UART);
    rxWriteIndex++;
    rxCount++;
    if (rxWriteIndex == RXBUFSIZE)
    {
      rxWriteIndex = 0;
    }
    /* Check for overflow - flush buffer */
    if (rxCount > RXBUFSIZE)
    {
      rxWriteIndex = 0;
      rxCount      = 0;
      rxReadIndex  = 0;
    }
  }
}

/** @} (end group RetargetIo) */

/**************************************************************************//**
 * @brief UART/LEUART toggle LF to CRLF conversion
 * @param on If non-zero, automatic LF to CRLF conversion will be enabled
 *****************************************************************************/
void RETARGET_SerialCrLf(int on)
{
  if (on)
    LFtoCRLF = 1;
  else
    LFtoCRLF = 0;
}


/**************************************************************************//**
 * @brief Intializes UART/LEUART
 *****************************************************************************/
void RETARGET_SerialInit(void)
{
  /* Enable peripheral clocks */
  CMU_ClockEnable(cmuClock_HFPER, true);
  /* Configure GPIO pins */
  CMU_ClockEnable(cmuClock_GPIO, true);
  /* To avoid false start, configure output as high */
  GPIO_PinModeSet(RETARGET_TXPORT, RETARGET_TXPIN, gpioModePushPull, 1);
  GPIO_PinModeSet(RETARGET_RXPORT, RETARGET_RXPIN, gpioModeInput, 0);

#if defined(RETARGET_USART)
  USART_TypeDef           *usart = RETARGET_UART;
  USART_InitAsync_TypeDef init   = USART_INITASYNC_DEFAULT;

  /* Enable DK RS232/UART switch */
  RETARGET_PERIPHERAL_ENABLE();

  CMU_ClockEnable(RETARGET_CLK, true);

  /* Configure USART for basic async operation */
  init.enable = usartDisable;
  USART_InitAsync(usart, &init);

  /* Enable pins at correct UART/USART location. */
  #if defined( USART_ROUTEPEN_RXPEN )
  usart->ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN;
  usart->ROUTELOC0 = ( usart->ROUTELOC0 &
                       ~( _USART_ROUTELOC0_TXLOC_MASK
                          | _USART_ROUTELOC0_RXLOC_MASK ) )
                     | ( RETARGET_TX_LOCATION << _USART_ROUTELOC0_TXLOC_SHIFT )
                     | ( RETARGET_RX_LOCATION << _USART_ROUTELOC0_RXLOC_SHIFT );
  #else
  usart->ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | RETARGET_LOCATION;
  #endif

  /* Clear previous RX interrupts */
  USART_IntClear(RETARGET_UART, USART_IF_RXDATAV);
  NVIC_ClearPendingIRQ(RETARGET_IRQn);

  /* Enable RX interrupts */
  USART_IntEnable(RETARGET_UART, USART_IF_RXDATAV);
  NVIC_EnableIRQ(RETARGET_IRQn);

  /* Finally enable it */
  USART_Enable(usart, usartEnable);

#else
  LEUART_TypeDef      *leuart = RETARGET_UART;
  LEUART_Init_TypeDef init    = LEUART_INIT_DEFAULT;

  /* Enable DK LEUART/RS232 switch */
  RETARGET_PERIPHERAL_ENABLE();

  /* Enable CORE LE clock in order to access LE modules */
  CMU_ClockEnable(cmuClock_CORELE, true);

#if defined(RETARGET_VCOM)
  /* Select HFXO/2 for LEUARTs (and wait for it to stabilize) */
  CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_CORELEDIV2);
#else
  /* Select LFXO for LEUARTs (and wait for it to stabilize) */
  CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO);
#endif

  CMU_ClockEnable(RETARGET_CLK, true);

  /* Do not prescale clock */
  CMU_ClockDivSet(RETARGET_CLK, cmuClkDiv_1);

  /* Configure LEUART */
  init.enable = leuartDisable;
#if defined(RETARGET_VCOM)
  init.baudrate = 115200;
#endif
  LEUART_Init(leuart, &init);
  /* Enable pins at default location */
  leuart->ROUTE = LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN | RETARGET_LOCATION;

  /* Clear previous RX interrupts */
  LEUART_IntClear(RETARGET_UART, LEUART_IF_RXDATAV);
  NVIC_ClearPendingIRQ(RETARGET_IRQn);

  /* Enable RX interrupts */
  LEUART_IntEnable(RETARGET_UART, LEUART_IF_RXDATAV);
  NVIC_EnableIRQ(RETARGET_IRQn);

  /* Finally enable it */
  LEUART_Enable(leuart, leuartEnable);
#endif

#if !defined(__CROSSWORKS_ARM) && defined(__GNUC__)
  setvbuf(stdout, NULL, _IONBF, 0);   /*Set unbuffered mode for stdout (newlib)*/
#endif

  initialized = true;
}
Ejemplo n.º 6
0
Archivo: uart.c Proyecto: MatKub/RIOT
void uart_write(uart_t uart, const uint8_t *data, size_t len)
{
    switch(uart) {
#if UART_0_EN
    case UART_0:
#if UART_0_ENABLE_BUF
    for(int count = 0; count < len; count++) {
        NVIC_DisableIRQ(UART_0_IRQ_TX_CHAN);
        ringbuffer_add_one(&rb_uart0, data[count]);
        NVIC_EnableIRQ(UART_0_IRQ_TX_CHAN);
    }
    USART_IntEnable(UART_0_DEV, USART_IF_TXBL);
#else
    for(size_t i = 0; i < len; i++) {
        /* Check that transmit buffer is empty */
        while(!(UART_0_DEV->STATUS & USART_STATUS_TXBL))
        ;
        /* Write data to buffer */
        UART_0_DEV->TXDATA = (uint32_t)data[i];
    }
#endif
    break;
#endif
#if UART_1_EN
    case UART_1:
#if UART_1_ENABLE_BUF
    for(int count = 0; count < len; count++) {
        NVIC_DisableIRQ(UART_1_IRQ_TX_CHAN);
        ringbuffer_add_one(&rb_uart1, data[count]);
        NVIC_EnableIRQ(UART_1_IRQ_TX_CHAN);
    }
    USART_IntEnable(UART_1_DEV, USART_IF_TXBL);
#else
    for(size_t i = 0; i < len; i++)
    {
        /* Check that transmit buffer is empty */
        while(!(UART_1_DEV->STATUS & USART_STATUS_TXBL))
        ;
        /* Write data to buffer */
        UART_1_DEV->TXDATA = (uint32_t)data[i];
    }
#endif
    break;
#endif
#if UART_2_EN
    case UART_2:
#if UART_2_ENABLE_BUF
        for(int count = 0; count < len; count++) {
            NVIC_DisableIRQ(UART_2_IRQ);
            ringbuffer_add_one(&rb_uart2, data[count]);
            NVIC_EnableIRQ(UART_2_IRQ);
        }
        LEUART_IntEnable(UART_2_DEV, LEUART_IF_TXBL);
#else
        for(size_t i = 0; i < len; i++)
        {
            /* Check that transmit buffer is empty */
            while (!(UART_2_DEV->STATUS & LEUART_STATUS_TXBL))
            ;
            /* Avoid deadlock if modifying the same register twice when freeze mode is */
            /* activated. */
            if (!(UART_2_DEV->FREEZE & LEUART_FREEZE_REGFREEZE))
            {
                /* Wait for any pending previous write operation to have been completed */
                /* in low frequency domain */
                while (UART_2_DEV->SYNCBUSY & LEUART_SYNCBUSY_TXDATA);
                ;
                UART_2_DEV->TXDATA = (uint32_t)data[i];
            }

        }
#endif
        break;
#endif
    }
}