Reply
Posts: 1
Registered: ‎12-19-2016

Help me! efr32mg usart receive interupt not working

Hi~ I'm newbie.. T.T

 

I want UART comunication between efr32mg boards using expansion head, 14(RX), 12(TX) and 1(GND).

 

First, I did CMU setup:

 

SystemHFXOClockSet(32000000);

CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
CMU_OscillatorEnable(cmuOsc_HFXO, true, true);
CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
CMU_ClockEnable(cmuClock_HFPER, true);
CMU_ClockEnable(cmuClock_USART0, true);
CMU_ClockEnable(cmuClock_GPIO, true);

 

(I didn't know what's mean.. I just copy and paste..T.T)

 

Second, I set UART configuration.:

 

GPIO_PinModeSet(gpioPortA, 0, gpioModePushPull, 1);
GPIO_PinModeSet(gpioPortA, 1, gpioModeInput, 0);

 

uartInit.enable       = usartDisable;    //Don't enable UART upon intialization

 

/* Initialize USART with uartInit struct */
USART_InitAsync(uart, &uartInit);

 

// $[USART_InitPrsTrigger]
USART_PrsTriggerInit_TypeDef initprs = USART_INITPRSTRIGGER_DEFAULT;
    initprs.rxTriggerEnable = 0;
    initprs.txTriggerEnable = 0;
    initprs.prsTriggerChannel = usartPrsTriggerCh0;

USART_InitPrsTrigger(USART1, &initprs);

 

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

 

/* Clear previous RX interrupts */
USART_IntClear(uart, _USART_IF_MASK);
USART_IntClear(uart, USART_IF_RXDATAV);
NVIC_ClearPendingIRQ(USART0_RX_IRQn);
NVIC_ClearPendingIRQ(USART0_TX_IRQn);

 

 /* Enable RX interrupts */
USART_IntEnable(uart, USART_IF_RXDATAV);
NVIC_EnableIRQ(USART0_RX_IRQn);
NVIC_EnableIRQ(USART0_TX_IRQn);

 

/* Finally enable it *//* Enable UART */
USART_Enable(uart, usartEnable);

 

Finally, I sent welcomeString!

 

uartPutData((uint8_t*) welcomeString, welLen);

 

void uartPutData(uint8_t * dataPtr, uint32_t dataLen)
{
  uint32_t i = 0;

  /* Check if buffer is large enough for data */
  if (dataLen > BUFFERSIZE)
  {
    /* Buffer can never fit the requested amount of data */
    return;
  }

  /* Check if buffer has room for new data */
  if ((txBuf.pendingBytes + dataLen) > BUFFERSIZE)
  {
    /* Wait until room */
    while ((txBuf.pendingBytes + dataLen) > BUFFERSIZE) ;
  }

  /* Fill dataPtr[0:dataLen-1] into txBuffer */
  while (i < dataLen)
  {
    txBuf.data[txBuf.wrI] = *(dataPtr + i);
    txBuf.wrI             = (txBuf.wrI + 1) % BUFFERSIZE;
    i++;
  }

  /* Increment pending byte counter */
  txBuf.pendingBytes += dataLen;

  /* Enable interrupt on USART TX Buffer*/
  USART_IntEnable(uart, USART_IF_TXBL);
}

 

void USART0_TX_IRQHandler(void)
{
  /* Clear interrupt flags by reading them. */
  //USART_IntGet(uart);

  /* Check TX buffer level status */
  if (uart->STATUS & USART_STATUS_TXBL)
  {

 if (txBuf.pendingBytes > 0)
 {
  //Transmit pending character

  USART_Tx(uart, txBuf.data[txBuf.rdI]);
  txBuf.rdI = (txBuf.rdI + 1) % BUFFERSIZE;
  txBuf.pendingBytes--;
 }

    /* Disable Tx interrupt if no more bytes in queue */
    if (txBuf.pendingBytes == 0)
    {
     txBuf.wrI = (uint32_t)0;
     txBuf.rdI = (uint32_t)0;
      USART_IntDisable(uart, USART_IF_TXBL);

    }
  }
}

 

I saw that txBuf was deliveried very well.. (I saw using breakpoints in debug on Simplicity studio)

 

But, another board cannot receive welcomeString T.T

Receive Interupter is..

 

void USART0_RX_IRQHandler(void)
{
  /* Check for RX data valid interrupt */
  if (uart->STATUS & USART_STATUS_RXDATAV)
  {
    /* Copy data into RX Buffer */
    uint8_t rxData = USART_Rx(uart);
    rxBuf.data[rxBuf.wrI] = rxData;
    rxBuf.wrI             = (rxBuf.wrI + 1) % BUFFERSIZE;
    rxBuf.pendingBytes++;

 

    /* Flag Rx overflow */
    if (rxBuf.pendingBytes > BUFFERSIZE)
    {
      rxBuf.overflow = true;
    } else if (rxBuf.pendingBytes == BUFFERSIZE) {
     uint8_t tmpBuf[BUFFERSIZE];
     int len = uartGetData(tmpBuf, 0);

    }

    /* Clear RXDATAV interrupt */
    USART_IntClear(uart, USART_IF_RXDATAV);
  }
}

 

reBuf always contain 0(\0) and 254 ('þ').

 

How can I receive welcomeString?

Posts: 323
Registered: ‎09-04-2013

Re: Help me! efr32mg usart receive interupt not working

@ZidanevsRaul As you are using the EFR32 Wireless STK board, there is a virtual COM poart on the board can be used to communicate between the PC host and the EFR32 MCU using USART0, Location 0 (TX pin PA0, RX pin PA1).

 

After connecting the mini USB connector on the STK to USB host, you should see the virtual COM port named like as "JLink CDC UART Port (COMx)" showing under "Ports (COM & LPT)" in the Windows Device Manager on the PC.

 

Therefore, you can run any common terminal tool, like as Tera Term, to test the UART data transfer for your UART TX and RX boards individually.

 

Regarding the MCU USART configuration, you can try to use the Configurator in Simplicity Studio, but use EFM32PG part number instead of the EFR32 devices. EFM32PG should be pin to pin compatible with EFR32 (same package), the pins for RF function are NC in EFM32PG.

Also, refer to AN0045 describing how to use the EFM32 MCU UART. This application note can be found in Simplicity Studio, this also requires to enter a EFM32 device name. Or from Silabs website here:

http://www.silabs.com/products/mcu/Pages/32-bit-mcu-application-notes.aspx

Highlighted
Posts: 2,813
Registered: ‎02-07-2002

Re: Help me! efr32mg usart receive interupt not working

But remember that this Virtual COM port only supports a baudrate of 115200.