I am currently using SIM800C module with STM32F103C8 microcontroller. As SIM800C is configured using AT commands, I am using UART to communicate. Currently, I have configured USART3 at baud of 9600 in interrupt mode (I tried to use simple receive, but it only receives the first character. I think it is because the answer is too fast or smth). So, here is the code, where I send AT command:
static void send_at(char *at_cmd, char *reply, uint16_t timeout)
{
offset = strlen(at_cmd) + 1; // offset of reply of SIM800
len = strlen(reply) + 2 + offset; // overall reply length
rx_buffer = (char *) calloc(len, sizeof(char));
expected_ans = (char *) calloc(len, sizeof(char));
sprintf(expected_ans, "%s\r\n", reply);
HAL_UART_Receive_IT(sim_uart, (uint8_t *) rx_buffer, len); // \r\r\n
HAL_Delay(10);
HAL_UART_Transmit(sim_uart, (uint8_t *) at_cmd, strlen(at_cmd), timeout);
}
For "AT\r\n" command, SIM800 returns "AT\r\nOK\r\n", so, offset is pointer where only reply starts (in this case 4, which skips "AT\r\n" part). So, when I receive answer, I check it in callback function:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *uart)
{
rx_buffer[len] = 0; // truncate garbage data
if (!strcmp(rx_buffer + offset, expected_ans))
++state;
else
state = 0;
}
state is variable, which shows which AT command to send (apparently, when state increases, next AT command will be executed). Everything works fine, but... if reply overflows, everything is over.
For example, for AT command "AT+SAPBR=1,1\r\n", which enables GPRS, there can be an answer "ERROR" instead of "OK". As, I already called RX interrupt for the length of "OK", after "ER" interrupt fires. However, for every other interrupt call after this, interrupt does not fire, even if answer is "OK". Basically, reply "ERROR" overflows and next interrupts are disabled. I do not know what is the problem and why this happens. Is there any way to know the size of incoming data beforehand or to flush buffer in callback function?
Here is my main function:
void sim800_init(UART_HandleTypeDef *uart)
{
sim_uart = uart;
while(state < 8)
{
switch (state)
{
case 0:
send_at(AT, "OK", 1000);
break;
case 1:
send_at(AT_SAPBR_CONTYPE, "OK", 5000);
break;
case 2:
send_at(AT_SAPBR_SET_APN, "OK", 5000);
break;
case 3:
send_at(AT_ENABLE_GPRS, "OK", 5000);
break;
case 4:
send_at(AT_HTTP_INIT, "OK", 10000);
break;
case 5:
send_at(AT_HTTPPARA_CID, "OK", 10000);
break;
case 6:
send_at(AT_HTTPPARA_URL, "OK", 5000);
break;
case 7:
send_at(AT_HTTPPARA_CONTENT, "OK", 5000);
break;
}
HAL_Delay(1000);
}
}