S32K116 UART not receiving

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

S32K116 UART not receiving

Jump to solution
2,370 Views
joseponc
Contributor III

Hi, I'm new to the platform and have been developing a few tasks for almost a month on the S32K116 EVB, but I'm having trouble with the UART driver. I'm trying to set an UART communication but I can send but I can't receive. I have been trying to follow the platform examples but I get the same issue with the examples: the EVB sends without a problem but doesn't receive a thing.

Thank you beforehand for your comments.

Labels (1)
0 Kudos
1 Solution
2,142 Views
joseponc
Contributor III

Hello Daniel. Thank you for your reply!

I used the platform driver example (attached below).  I wil try to update and look for that project example, since I don't have UART project examples. just driver examples. 

I'm checking communication using a logic analyzer and also debugging to test if my receiving buffer is being populated or not. So far, my results have been: If I send a message before trying to receive something, my receiving buffer is filled with as many zeroes as the amount of bytes I sent in the message before trying to receive. If I don't send a message before trying to receive then I don't even receive zeroes.

This is the receive part in main.c

  while (1)
  {
      /* Receive and store data byte by byte until new line character is received,
       * or the buffer becomes full (256 characters received)
       */
      LPUART_DRV_ReceiveData(INST_LPUART1, buffer, 1U);
      /* Wait for transfer to be completed */
      while(LPUART_DRV_GetReceiveStatus(INST_LPUART1, &bytesRemaining) == STATUS_BUSY);

      /* Check the status */
      status = LPUART_DRV_GetReceiveStatus(INST_LPUART1, &bytesRemaining);

      if (status != STATUS_SUCCESS)
      {
          /* If an error occurred, send the error message and exit the loop */
          LPUART_DRV_SendDataBlocking(INST_LPUART1, (uint8_t *)errorMsg, strlen(errorMsg), TIMEOUT);
          break;
      }

      /* Append string terminator to the received data */
      bufferIdx++;
      buffer[bufferIdx] = 0U;

      /* If the received string is "Hello Board", send back "Hello World" */
      if(strcmp((char *)buffer, "Hello Board\n") == 0)
      {
          strcpy((char *)buffer, "Hello World\n");
      }

      /* Send the received data back */
      LPUART_DRV_SendDataBlocking(INST_LPUART1, buffer, bufferIdx, TIMEOUT);
      /* Reset the buffer index to start a new reception */
      bufferIdx = 0U;
  }

  /*** Don't write any code pass this line, or it will be deleted during code generation. ***/
  /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
  #ifdef PEX_RTOS_START
    PEX_RTOS_START();                  /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of RTOS startup code.  ***/
  /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
  for(;;) {
    if(exit_code != 0) {
      break;
    }
  }
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Here is the receive data function:

status_t LPUART_DRV_ReceiveData(uint32_t instance,
                                uint8_t * rxBuff,
                                uint32_t rxSize)
{
    DEV_ASSERT(instance < LPUART_INSTANCE_COUNT);
    DEV_ASSERT(rxBuff != NULL);

    status_t retVal = STATUS_SUCCESS;
    lpuart_state_t * lpuartState = (lpuart_state_t *)s_lpuartStatePtr[instance];

    /* Indicates this is a non-blocking transaction. */
    lpuartState->isRxBlocking = false;

    DEV_ASSERT((lpuartState->transferType == LPUART_USING_INTERRUPTS) ||
               (lpuartState->transferType == LPUART_USING_DMA));

    if (lpuartState->transferType == LPUART_USING_INTERRUPTS)
    {
        /* Start the reception process using interrupts */
        retVal = LPUART_DRV_StartReceiveDataUsingInt(instance, rxBuff, rxSize);
    }
#if FEATURE_LPUART_HAS_DMA_ENABLE
    else
    {
        /* Start the reception process using DMA */
        retVal = LPUART_DRV_StartReceiveDataUsingDma(instance, rxBuff, rxSize);
    }
#endif

    return retVal;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Here is the receive data using interruptions:

static status_t LPUART_DRV_StartReceiveDataUsingInt(uint32_t instance,
                                                    uint8_t * rxBuff,
                                                    uint32_t rxSize)
{
    DEV_ASSERT(instance < LPUART_INSTANCE_COUNT);
    DEV_ASSERT(rxBuff != NULL);

    lpuart_state_t * lpuartState = (lpuart_state_t *)s_lpuartStatePtr[instance];
    LPUART_Type * base = s_lpuartBase[instance];

    /* Check it's not busy receiving data from a previous function call */
    if (lpuartState->isRxBusy)
    {
        return STATUS_BUSY;
    }

    /* Check the validity of the parameters */
    DEV_ASSERT(rxSize > 0U);
    DEV_ASSERT((lpuartState->bitCountPerChar == LPUART_8_BITS_PER_CHAR) ||
               ((rxSize & 1U) == 0U));

    /* Initialize the module driver state struct to indicate transfer in progress
     * and with the buffer and byte count data. */
    lpuartState->isRxBusy = true;
    lpuartState->rxBuff = rxBuff;
    lpuartState->rxSize = rxSize;
    lpuartState->receiveStatus = STATUS_BUSY;

    /* Enable the receiver */
    LPUART_SetReceiverCmd(base, true);

    /* Enable error interrupts */
    LPUART_SetErrorInterrupts(base, true);

    /* Enable receive data full interrupt */
    LPUART_SetIntMode(base, LPUART_INT_RX_DATA_REG_FULL, true);

    return STATUS_SUCCESS;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Finally, those are used to receive here, in the interrup handler:

static void LPUART_DRV_RxIrqHandler(uint32_t instance)
{
    lpuart_state_t * lpuartState = (lpuart_state_t *)s_lpuartStatePtr[instance];

    /* Get data and put in receive buffer  */
    LPUART_DRV_GetData(instance);

    /* Update the internal state */
    if (lpuartState->bitCountPerChar == LPUART_8_BITS_PER_CHAR)
    {
        ++lpuartState->rxBuff;
        --lpuartState->rxSize;
    }
    else
    {
        lpuartState->rxBuff = &lpuartState->rxBuff[2];
        lpuartState->rxSize -= 2U;
    }

    /* Check if this was the last byte in the current buffer */
    if (lpuartState->rxSize == 0U)
    {
        /* Invoke callback if there is one (callback may reset the rx buffer for continuous reception) */
        if (lpuartState->rxCallback != NULL)
        {
            lpuartState->rxCallback(lpuartState, UART_EVENT_RX_FULL, lpuartState->rxCallbackParam);
        }
    }

    /* Finish reception if this was the last byte received */
    if (lpuartState->rxSize == 0U)
    {
        /* Complete transfer (disable rx logic) */
        LPUART_DRV_CompleteReceiveDataUsingInt(instance);

        /* Invoke callback if there is one */
        if (lpuartState->rxCallback != NULL)
        {
            lpuartState->rxCallback(lpuartState, UART_EVENT_END_TRANSFER, lpuartState->rxCallbackParam);
        }
    }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The GetData function accesses the register in which the receive data should be allocated. I'm sorry if I pasted too much code.

Update: I downloaded S32DS v2.2 and checked that example. It still isn't working. Do I have to change something to make it work?

Update 2: Somehow the debugger is interferring with instance LPUART0, so I wasn't able to receive through PORTB0 but I was able to receive through USB instead. Thank you for your help!

Thank you, 

Regards, Jose.

View solution in original post

0 Kudos
3 Replies
2,142 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hello Jose,

Have you tried the simple S32K116_Project_LPUART example from S32DS v2.2:

pastedImage_1.png

Do you monitor the RX pin with an oscilloscope / logic analyzer?

Can you share a test code?

Thank you,

Regards,

Daniel

2,143 Views
joseponc
Contributor III

Hello Daniel. Thank you for your reply!

I used the platform driver example (attached below).  I wil try to update and look for that project example, since I don't have UART project examples. just driver examples. 

I'm checking communication using a logic analyzer and also debugging to test if my receiving buffer is being populated or not. So far, my results have been: If I send a message before trying to receive something, my receiving buffer is filled with as many zeroes as the amount of bytes I sent in the message before trying to receive. If I don't send a message before trying to receive then I don't even receive zeroes.

This is the receive part in main.c

  while (1)
  {
      /* Receive and store data byte by byte until new line character is received,
       * or the buffer becomes full (256 characters received)
       */
      LPUART_DRV_ReceiveData(INST_LPUART1, buffer, 1U);
      /* Wait for transfer to be completed */
      while(LPUART_DRV_GetReceiveStatus(INST_LPUART1, &bytesRemaining) == STATUS_BUSY);

      /* Check the status */
      status = LPUART_DRV_GetReceiveStatus(INST_LPUART1, &bytesRemaining);

      if (status != STATUS_SUCCESS)
      {
          /* If an error occurred, send the error message and exit the loop */
          LPUART_DRV_SendDataBlocking(INST_LPUART1, (uint8_t *)errorMsg, strlen(errorMsg), TIMEOUT);
          break;
      }

      /* Append string terminator to the received data */
      bufferIdx++;
      buffer[bufferIdx] = 0U;

      /* If the received string is "Hello Board", send back "Hello World" */
      if(strcmp((char *)buffer, "Hello Board\n") == 0)
      {
          strcpy((char *)buffer, "Hello World\n");
      }

      /* Send the received data back */
      LPUART_DRV_SendDataBlocking(INST_LPUART1, buffer, bufferIdx, TIMEOUT);
      /* Reset the buffer index to start a new reception */
      bufferIdx = 0U;
  }

  /*** Don't write any code pass this line, or it will be deleted during code generation. ***/
  /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
  #ifdef PEX_RTOS_START
    PEX_RTOS_START();                  /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of RTOS startup code.  ***/
  /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
  for(;;) {
    if(exit_code != 0) {
      break;
    }
  }
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Here is the receive data function:

status_t LPUART_DRV_ReceiveData(uint32_t instance,
                                uint8_t * rxBuff,
                                uint32_t rxSize)
{
    DEV_ASSERT(instance < LPUART_INSTANCE_COUNT);
    DEV_ASSERT(rxBuff != NULL);

    status_t retVal = STATUS_SUCCESS;
    lpuart_state_t * lpuartState = (lpuart_state_t *)s_lpuartStatePtr[instance];

    /* Indicates this is a non-blocking transaction. */
    lpuartState->isRxBlocking = false;

    DEV_ASSERT((lpuartState->transferType == LPUART_USING_INTERRUPTS) ||
               (lpuartState->transferType == LPUART_USING_DMA));

    if (lpuartState->transferType == LPUART_USING_INTERRUPTS)
    {
        /* Start the reception process using interrupts */
        retVal = LPUART_DRV_StartReceiveDataUsingInt(instance, rxBuff, rxSize);
    }
#if FEATURE_LPUART_HAS_DMA_ENABLE
    else
    {
        /* Start the reception process using DMA */
        retVal = LPUART_DRV_StartReceiveDataUsingDma(instance, rxBuff, rxSize);
    }
#endif

    return retVal;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Here is the receive data using interruptions:

static status_t LPUART_DRV_StartReceiveDataUsingInt(uint32_t instance,
                                                    uint8_t * rxBuff,
                                                    uint32_t rxSize)
{
    DEV_ASSERT(instance < LPUART_INSTANCE_COUNT);
    DEV_ASSERT(rxBuff != NULL);

    lpuart_state_t * lpuartState = (lpuart_state_t *)s_lpuartStatePtr[instance];
    LPUART_Type * base = s_lpuartBase[instance];

    /* Check it's not busy receiving data from a previous function call */
    if (lpuartState->isRxBusy)
    {
        return STATUS_BUSY;
    }

    /* Check the validity of the parameters */
    DEV_ASSERT(rxSize > 0U);
    DEV_ASSERT((lpuartState->bitCountPerChar == LPUART_8_BITS_PER_CHAR) ||
               ((rxSize & 1U) == 0U));

    /* Initialize the module driver state struct to indicate transfer in progress
     * and with the buffer and byte count data. */
    lpuartState->isRxBusy = true;
    lpuartState->rxBuff = rxBuff;
    lpuartState->rxSize = rxSize;
    lpuartState->receiveStatus = STATUS_BUSY;

    /* Enable the receiver */
    LPUART_SetReceiverCmd(base, true);

    /* Enable error interrupts */
    LPUART_SetErrorInterrupts(base, true);

    /* Enable receive data full interrupt */
    LPUART_SetIntMode(base, LPUART_INT_RX_DATA_REG_FULL, true);

    return STATUS_SUCCESS;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Finally, those are used to receive here, in the interrup handler:

static void LPUART_DRV_RxIrqHandler(uint32_t instance)
{
    lpuart_state_t * lpuartState = (lpuart_state_t *)s_lpuartStatePtr[instance];

    /* Get data and put in receive buffer  */
    LPUART_DRV_GetData(instance);

    /* Update the internal state */
    if (lpuartState->bitCountPerChar == LPUART_8_BITS_PER_CHAR)
    {
        ++lpuartState->rxBuff;
        --lpuartState->rxSize;
    }
    else
    {
        lpuartState->rxBuff = &lpuartState->rxBuff[2];
        lpuartState->rxSize -= 2U;
    }

    /* Check if this was the last byte in the current buffer */
    if (lpuartState->rxSize == 0U)
    {
        /* Invoke callback if there is one (callback may reset the rx buffer for continuous reception) */
        if (lpuartState->rxCallback != NULL)
        {
            lpuartState->rxCallback(lpuartState, UART_EVENT_RX_FULL, lpuartState->rxCallbackParam);
        }
    }

    /* Finish reception if this was the last byte received */
    if (lpuartState->rxSize == 0U)
    {
        /* Complete transfer (disable rx logic) */
        LPUART_DRV_CompleteReceiveDataUsingInt(instance);

        /* Invoke callback if there is one */
        if (lpuartState->rxCallback != NULL)
        {
            lpuartState->rxCallback(lpuartState, UART_EVENT_END_TRANSFER, lpuartState->rxCallbackParam);
        }
    }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The GetData function accesses the register in which the receive data should be allocated. I'm sorry if I pasted too much code.

Update: I downloaded S32DS v2.2 and checked that example. It still isn't working. Do I have to change something to make it work?

Update 2: Somehow the debugger is interferring with instance LPUART0, so I wasn't able to receive through PORTB0 but I was able to receive through USB instead. Thank you for your help!

Thank you, 

Regards, Jose.

0 Kudos
2,142 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hello Jose,

So I understand that it works for you through the Virtual serial port.

The PTB0/PTB1 pins are routed to the OpenSDA programmer.

pastedImage_1.png

But you don't have to use the pins 

pastedImage_2.png

Regards,

Daniel

0 Kudos