stm32-project/Core/Src/esp_at.c

244 lines
5.3 KiB
C
Raw Normal View History

2026-04-18 14:37:49 +00:00
#include "main.h"
#include "esp_at.h"
#include "wifi_portal.h"
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#define ESP_RX_BUF_SIZE 1024
static char esp_rx_buf[ESP_RX_BUF_SIZE];
static volatile uint16_t esp_rx_idx = 0;
extern UART_HandleTypeDef huart1; // ESP
extern UART_HandleTypeDef huart3; // DEBUG
/*************************************************/
static void dbg(const char *s)
{
HAL_UART_Transmit(&huart3, (uint8_t *)s, strlen(s), HAL_MAX_DELAY);
}
/*************************************************/
void ESP_RxByte(uint8_t byte)
{
if (esp_rx_idx < ESP_RX_BUF_SIZE - 1)
{
esp_rx_buf[esp_rx_idx++] = byte;
esp_rx_buf[esp_rx_idx] = 0;
}
}
/*************************************************/
char* ESP_GetBuffer(void)
{
return esp_rx_buf;
}
/*************************************************/
void ESP_ClearBuffer(void)
{
esp_rx_idx = 0;
esp_rx_buf[0] = 0;
}
/*************************************************/
static bool ESP_WaitFor(const char *expect, uint32_t timeout)
{
uint32_t start = HAL_GetTick();
while ((HAL_GetTick() - start) < timeout)
{
if (strstr(esp_rx_buf, expect))
return true;
if (strstr(esp_rx_buf, "ERROR"))
return false;
if (strstr(esp_rx_buf, "busy"))
{
HAL_Delay(100); // 🔥 ESP ocupado → espera
ESP_ClearBuffer();
start = HAL_GetTick();
}
}
return false;
}
/*************************************************/
bool ESP_SendCmd(const char *cmd, const char *expect, uint32_t timeout)
{
ESP_ClearBuffer();
HAL_UART_Transmit(&huart1, (uint8_t *)cmd, strlen(cmd), HAL_MAX_DELAY);
HAL_UART_Transmit(&huart1, (uint8_t *)"\r\n", 2, HAL_MAX_DELAY);
dbg(">> ");
dbg(cmd);
dbg("\r\n");
bool ok = ESP_WaitFor(expect, timeout);
dbg("<< ");
dbg(esp_rx_buf);
dbg("\r\n");
HAL_Delay(50); // 🔥 estabiliza ESP
return ok;
}
/*************************************************/
bool ESP_EnableMultiConn(void)
{
return ESP_SendCmd("AT+CIPMUX=1", "OK", 3000);
}
bool ESP_StartSoftAP(const char *ssid, const char *pass)
{
char cmd[160];
if (!ESP_SendCmd("AT+CWMODE=2", "OK", 3000))
return false;
snprintf(cmd, sizeof(cmd),
"AT+CWSAP=\"%s\",\"%s\",1,3,4",
ssid, pass);
return ESP_SendCmd(cmd, "OK", 5000);
}
bool ESP_StartServer(uint16_t port)
{
char cmd[64];
snprintf(cmd, sizeof(cmd), "AT+CIPSERVER=1,%u", port);
return ESP_SendCmd(cmd, "OK", 5000);
}
/*************************************************/
bool ESP_SendLinkData(int link_id, const char *data)
{
char cmd[64];
size_t len = strlen(data);
ESP_ClearBuffer();
snprintf(cmd, sizeof(cmd), "AT+CIPSEND=%d,%u", link_id, (unsigned)len);
HAL_UART_Transmit(&huart1, (uint8_t *)cmd, strlen(cmd), HAL_MAX_DELAY);
HAL_UART_Transmit(&huart1, (uint8_t *)"\r\n", 2, HAL_MAX_DELAY);
if (!ESP_WaitFor(">", 3000))
return false;
HAL_UART_Transmit(&huart1, (uint8_t *)data, len, HAL_MAX_DELAY);
return ESP_WaitFor("SEND OK", 5000);
}
int ESP_HasIPD(void)
{
if (strstr(ESP_GetBuffer(), "+IPD"))
return 1;
return 0;
}
void ESP_SendData(const char *data)
{
HAL_UART_Transmit(&huart1, (uint8_t*)data, strlen(data), 1000);
}
/*************************************************/
bool ESP_CloseLink(int link_id)
{
char cmd[32];
snprintf(cmd, sizeof(cmd), "AT+CIPCLOSE=%d", link_id);
return ESP_SendCmd(cmd, "OK", 3000);
}
/*************************************************/
void ESP_Init(void)
{
HAL_Delay(1000);
ESP_SendCmd("AT", "OK", 2000);
ESP_SendCmd("ATE0", "OK", 2000);
ESP_SendCmd("AT+CIPDINFO=1", "OK", 2000);
ESP_SendCmd("AT+CWMODE=2", "OK", 2000);
ESP_SendCmd("AT+CWSAP=\"STM32\",\"12345678\",1,3,4", "OK", 5000);
HAL_Delay(3000); // 🔥 importante
ESP_SendCmd("AT+CIPSERVER=0", "OK", 2000); // mata server se existir
// ESP_SendCmd("AT+CIPCLOSE=5", "OK", 2000); // fecha tudo (modo multi)
HAL_Delay(500);
if (!ESP_SendCmd("AT+CIPMUX=1", "OK", 3000))
dbg("CIPMUX FAIL\r\n");
if (!ESP_SendCmd("AT+CIPSERVER=1,80", "OK", 3000))
dbg("CIPSERVER FAIL\r\n");
}
/*************************************************/
__attribute__((unused))
static int parse_ipd_link(const char *p)
{
int link = -1;
sscanf(p, "+IPD,%d,", &link);
return link;
}
/*************************************************/
void ESP_Task(void)
{
char *p = strstr(ESP_GetBuffer(), "+IPD,");
if (p)
{
int link_id = -1;
int len = 0;
// extrair link_id e tamanho
sscanf(p, "+IPD,%d,%d:", &link_id, &len);
dbg("IPD DETECTADO\r\n");
// 🔥 esperar fim do pacote
HAL_Delay(50);
const char *resp =
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Connection: close\r\n"
"\r\n"
"<h1>PORTAL XUPA FUNCIONA</h1>";
char cmd[64];
snprintf(cmd, sizeof(cmd), "AT+CIPSEND=%d,%d", link_id, strlen(resp));
if (ESP_SendCmd(cmd, ">", 2000))
{
ESP_SendData(resp);
ESP_WaitFor("SEND OK", 3000);
}
snprintf(cmd, sizeof(cmd), "AT+CIPCLOSE=%d", link_id);
ESP_SendCmd(cmd, "OK", 2000);
ESP_ClearBuffer(); // 🔥 só aqui
}
}