Issue with UART Communication Between MCU and EG915U Modem

Hi,

I’m currently working on a solution involving an MCU and an EG915U modem. However, I’m facing an issue with managing the UART communication between the modem and the MCU. Let me explain the problem in detail:

Hardware Configuration

  • The MCU utilizes two UART interfaces:
    • SERCOM5: Used to send data externally (currently to a PC via PuTTY).
    • SERCOM0: Used to send AT commands to the EG915U modem (via MAIN_TXD/RXD).
      • Note: Both UARTs have been tested using an oscilloscope. SERCOM0 was also verified by communicating with a PC via PuTTY. Voltage levels are correct: 1.8V on the EG915U side and 3.3V on the MCU side.
  • Pin configuration:
    • SERCOM5:
      • RX5 → PIN 62 → PB01 → SERCOM5/PAD[3]
      • TX5 → PIN 63 → PB02 → SERCOM5/PAD[0]
    • SERCOM0:
      • RX0 → PIN 14 → PA05 → SERCOM0/PAD[1]
      • TX0 → PIN 13 → PA04 → SERCOM0/PAD[0]

Software Logic

The main logic is as follows:

int main() {  
    /* Initialize all modules */  
    SYS_Initialize(NULL);  
    SYSTICK_TimerStart();  

    // Enable UART transmitter and receiver  
    SERCOM0_USART_TransmitterEnable();  
    SERCOM0_USART_ReceiverEnable();  
    SERCOM5_USART_TransmitterEnable();  
    SERCOM5_USART_ReceiverEnable();  

    powerOnModuleQuectel(); // Executed once  

    send_at_command("ATI\r\n");  
    SYSTICK_DelayMs(1000); // Allow modem time to respond  
    receive_response();  
}  

// Function to send AT commands  
static void send_at_command(const char *command) {  
    bool result = false;  
    // Send the AT command  
    result = SERCOM0_USART_Write((uint8_t *)command, strlen(command));  
    if (result) {  
        SERCOM5_USART_Write(&okMessageSERCOM0[0], sizeof(okMessageSERCOM0));  
        SERCOM5_USART_Write((uint8_t *)command, strlen(command));  
    } else {  
        SERCOM5_USART_Write(&errorMessageSERCOM0[0], sizeof(errorMessageSERCOM0));  
    }  
}  

// Function to receive response  
static void receive_response(void) {  
    char data = 0;  
    char receiveBuffer[RX_BUFFERS_SIZE] = {};  
    uint16_t rxCounter = 0;  

    // Poll for data  
    SERCOM5_USART_Write(&enter_Poll_for_Data[0], sizeof(enter_Poll_for_Data));  

    while (SERCOM0_USART_ReceiverIsReady()) {  
        SERCOM5_USART_Write(&enterWhile[0], sizeof(enterWhile));  
        SERCOM0_USART_Read(&data, 1); // <--- GETS STUCK HERE  
        SERCOM5_USART_WriteByte((int)data);  
        if ((data == '\n') || (data == '\r')) {  
            SERCOM5_USART_Write(&newLine[0], sizeof(newLine));  
            SERCOM5_USART_Write(&receiveBuffer[0], rxCounter);  
            SERCOM5_USART_Write(&newLine[0], sizeof(newLine));  
            SERCOM5_USART_Write(&exitSERCOM5Write[0], sizeof(exitSERCOM5Write));  
            break;  
        } else {  
            receiveBuffer[rxCounter++] = data;  
        }  
    } // End of while  

    SERCOM5_USART_Write(&exit_Poll_for_Data[0], sizeof(exit_Poll_for_Data));  
}

Issue Details

The program gets stuck at the following point:

while ((SERCOM0_REGS->USART_INT.SERCOM_INTFLAG & SERCOM_USART_INT_INTFLAG_RXC_Msk) == 0U) {  
    /* Do nothing */  
}

I’m unsure whether the issue lies in the hardware connections (I’m using a custom board) or in the code itself. Additionally, I’m not certain if hardware flow control (RTS/CTS) is necessary for this setup, though I suspect it may not be required.

Additional Information

  • Attached are images of the SERCOM0/5 configurations using MPLAB Harmony Version 3.

  • Any insights or suggestions to resolve this issue would be greatly appreciated.

Thank you in advance for your help!

Best regards,
Fer Mercado.

I forgot to say the MCU that I’m using is ATSAME53J19A.

I think before you send any AT command, you should send the ATE0 first.

1 Like

Hi Bean,

Thank you for your suggestion. However, I believe the issue lies elsewhere. As I mentioned earlier, the code gets stuck in the function:

SERCOM0_USART_Read(&data, 1);

This happens because I’m using a blocking UART implementation. Specifically, the code enters this while loop and remains stuck waiting for new data:

/* Check if USART has new data /
while ((SERCOM0_REGS->USART_INT.SERCOM_INTFLAG & SERCOM_USART_INT_INTFLAG_RXC_Msk) == 0U) {
/
Do nothing */
}

To summarize, I am able to send data to the Quectel module, but I cannot receive a response from it. I’m still unsure what might be causing this issue.

Let me know if you have any further insights or suggestions.

Best regards,
Fer Mercado.