aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKing Kévin <kingkevin@cuvoodoo.info>2021-09-16 14:19:59 +0200
committerKing Kévin <kingkevin@cuvoodoo.info>2021-09-16 17:05:21 +0200
commit17dce0d517c8145d38fd93b0b30d14df5540459c (patch)
tree7daf13a1ad7a5ec055d4943e782a13b72bd0ceb8
parent8bd98693f6f6c059268f697a8acdbe261e70fe34 (diff)
esp8266: add timeout and return successHEADmaster
-rw-r--r--lib/radio_esp8266.c135
-rw-r--r--lib/radio_esp8266.h16
2 files changed, 114 insertions, 37 deletions
diff --git a/lib/radio_esp8266.c b/lib/radio_esp8266.c
index 6cade0b..3f52368 100644
--- a/lib/radio_esp8266.c
+++ b/lib/radio_esp8266.c
@@ -6,13 +6,13 @@
* @note peripherals used: USART @ref radio_esp8266_usart
*/
-/* standard libraries */
+// standard libraries
#include <stdint.h> // standard integer types
#include <stdlib.h> // general utilities
#include <string.h> // string and memory utilities
#include <stdio.h> // string utilities
-/* STM32 (including CM3) libraries */
+// STM32 (including CM3) libraries
#include <libopencm3/stm32/rcc.h> // real-time control clock library
#include <libopencm3/stm32/gpio.h> // general purpose input output library
#include <libopencm3/stm32/usart.h> // universal synchronous asynchronous receiver transmitter library
@@ -31,14 +31,15 @@
#define RADIO_ESP8266_AF GPIO_AF7 /**< alternate function for UART pins */
/** @} */
-/* input and output buffers and used memory */
+// input and output buffers and used memory
static uint8_t rx_buffer[24] = {0}; /**< buffer for received data (we only expect AT responses) */
static volatile uint16_t rx_used = 0; /**< number of byte in receive buffer */
static uint8_t tx_buffer[256] = {0}; /**< buffer for data to transmit */
static volatile uint16_t tx_used = 0; /**< number of bytes used in transmit buffer */
-volatile bool radio_esp8266_activity = false;
-volatile bool radio_esp8266_success = false;
+// response status
+volatile bool radio_esp8266_response = false; /**< when a response has been received (OK or ERROR) */
+volatile bool radio_esp8266_success = false; /**< if the response is OK (else ERROR), set when radio_esp8266_response is set to true */
/** transmit data to radio
* @param[in] data data to transmit
@@ -50,7 +51,7 @@ static void radio_esp8266_transmit(const uint8_t* data, uint8_t length) {
__WFI(); // sleep until something happened
}
usart_disable_tx_interrupt(USART(RADIO_ESP8266_USART)); // ensure transmit interrupt is disable to prevent index corruption (the ISR should already have done it)
- radio_esp8266_activity = false; // reset status because of new activity
+ radio_esp8266_response = false; // reset status because of new activity
for (tx_used = 0; tx_used < length && tx_used < LENGTH(tx_buffer); tx_used++) { // copy data
tx_buffer[tx_used] = data[length - 1 - tx_used]; // put character in buffer (in reverse order)
}
@@ -59,7 +60,7 @@ static void radio_esp8266_transmit(const uint8_t* data, uint8_t length) {
}
}
-void radio_esp8266_setup(void)
+bool radio_esp8266_setup(void)
{
// configure pins
rcc_periph_clock_enable(GPIO_RCC(RADIO_ESP8266_TX)); // enable clock for USART TX pin port peripheral
@@ -84,57 +85,133 @@ void radio_esp8266_setup(void)
usart_enable_rx_interrupt(USART(RADIO_ESP8266_USART)); // enable receive interrupt
usart_enable(USART(RADIO_ESP8266_USART)); // enable UART
- /* reset buffer states */
+ // reset buffer states
rx_used = 0;
tx_used = 0;
- radio_esp8266_activity = false;
- radio_esp8266_success = false;
+ // verify if ESP8266 is reachable
+ uint16_t timeout = 0; // reset timeout counter
radio_esp8266_transmit((uint8_t*)"AT\r\n", 4); // verify if module is present
- while (!radio_esp8266_activity || !radio_esp8266_success) { // wait for response
- __WFI(); // sleep until something happened
+ while (!radio_esp8266_response) { // wait for response
+ if (timeout > 100) { // response takes too long
+ return false;
+ }
+ sleep_ms(10); // wait a tiny bit
+ timeout += 10; // remember we waited
+ }
+ if (!radio_esp8266_success) {
+ return false;
}
+
+ // reset module so it connects to AP
+ timeout = 0; // reset timeout counter
radio_esp8266_transmit((uint8_t*)"AT+RST\r\n", 8); // reset module
- while (!radio_esp8266_activity || !radio_esp8266_success) { // wait for response
- __WFI(); // sleep until something happened
+ while (!radio_esp8266_response) { // wait for response
+ if (timeout > 100) { // response takes too long
+ return false;
+ }
+ sleep_ms(10); // wait a tiny bit
+ timeout += 10; // remember we waited
+ }
+ if (!radio_esp8266_success) {
+ return false;
}
+ timeout = 0; // reset timeout counter
while(rx_used < 13 || 0 != memcmp((char*)&rx_buffer[rx_used - 13], "WIFI GOT IP\r\n", 13)) { // wait to have IP
- __WFI(); // sleep until something happened
+ if (timeout > 10000) { // connection takes too long
+ return false;
+ }
+ sleep_ms(10); // wait a tiny bit
+ timeout += 10; // remember we waited
}
- radio_esp8266_transmit((uint8_t*)"ATE0\r\n", 6); // disable echoing
- while (!radio_esp8266_activity || !radio_esp8266_success) { // wait for response
- __WFI(); // sleep until something happened
+
+ // disable echo for better parsing
+ timeout = 0; // reset timeout counter
+ while (!radio_esp8266_response) { // wait for response
+ if (timeout > 100) { // response takes too long
+ return false;
+ }
+ sleep_ms(10); // wait a tiny bit
+ timeout += 10; // remember we waited
+ }
+ if (!radio_esp8266_success) {
+ return false;
}
+
+ return true;
}
-void radio_esp8266_open(const char* host, uint16_t port, bool tcp)
+bool radio_esp8266_open(const char* host, uint16_t port, bool tcp)
{
char command[256] = {0}; // string to create command
int length = snprintf(command, LENGTH(command), "AT+CIPSTART=\"%s\",\"%s\",%u\r\n", tcp ? "TCP" : "UDP", host, port); // create AT command to establish a TCP connection
if (length > 0) {
+ uint16_t timeout = 0; // reset timeout counter
radio_esp8266_transmit((uint8_t*)command, length);
+ while (!radio_esp8266_response) { // wait for response
+ if (timeout > 1000) { // response takes too long
+ return false;
+ }
+ sleep_ms(10); // wait a tiny bit
+ timeout += 10; // remember we waited
+ }
+ if (!radio_esp8266_success) {
+ return false;
+ }
}
+ return true;
}
-void radio_esp8266_send(const uint8_t* data, uint8_t length)
+bool radio_esp8266_send(const uint8_t* data, uint8_t length)
{
char command[16 + 1] = {0}; // string to create command
int command_length = snprintf(command, LENGTH(command), "AT+CIPSEND=%u\r\n", length); // create AT command to send data
if (command_length > 0) {
+ // start sending
+ uint16_t timeout = 0; // reset timeout counter
radio_esp8266_transmit((uint8_t*)command, command_length); // transmit AT command
- while (!radio_esp8266_activity || !radio_esp8266_success) { // wait for response
- __WFI(); // sleep until something happened
+ while (!radio_esp8266_response) { // wait for response
+ if (timeout > 1000) { // response takes too long
+ return false;
+ }
+ sleep_ms(10); // wait a tiny bit
+ timeout += 10; // remember we waited
}
- if (!radio_esp8266_success) { // send AT command did not succeed
- return; // don't transmit data
+ if (!radio_esp8266_success) {
+ return false;
}
+ // send actual data
+ timeout = 0; // reset timeout counter
radio_esp8266_transmit(data, length); // transmit data
+ while (!radio_esp8266_response) { // wait for response
+ if (timeout > 1000) { // response takes too long
+ return false;
+ }
+ sleep_ms(10); // wait a tiny bit
+ timeout += 10; // remember we waited
+ }
+ if (!radio_esp8266_success) {
+ return false;
+ }
}
+ return true;
}
-void radio_esp8266_close(void)
+bool radio_esp8266_close(void)
{
+ uint16_t timeout = 0; // reset timeout counter
radio_esp8266_transmit((uint8_t*)"AT+CIPCLOSE\r\n", 13); // send AT command to close established connection
+ while (!radio_esp8266_response) { // wait for response
+ if (timeout > 1000) { // response takes too long
+ return false;
+ }
+ sleep_ms(10); // wait a tiny bit
+ timeout += 10; // remember we waited
+ }
+ if (!radio_esp8266_success) {
+ return false;
+ }
+ return true;
}
/** USART interrupt service routine called when data has been transmitted or received */
@@ -155,12 +232,12 @@ void USART_ISR(RADIO_ESP8266_USART)(void)
}
rx_buffer[rx_used++] = usart_recv(USART(RADIO_ESP8266_USART)); // put character in buffer
// if the used send a packet with these strings during the commands detection the AT command response will break (AT commands are hard to handle perfectly)
- if (rx_used >= 4 && 0 == memcmp((char*)&rx_buffer[rx_used-4], "OK\r\n", 4)) { // OK received
- radio_esp8266_activity = true; // response received
+ if (rx_used >= 4 && 0 == memcmp((char*)&rx_buffer[rx_used - 4], "OK\r\n", 4)) { // OK received
+ radio_esp8266_response = true; // response received
radio_esp8266_success = true; // command succeeded
rx_used = 0; // reset buffer
- } else if (rx_used >= 7 && 0 == memcmp((char*)&rx_buffer[rx_used-7], "ERROR\r\n", 7)) { // ERROR received
- radio_esp8266_activity = true; // response received
+ } else if (rx_used >= 7 && 0 == memcmp((char*)&rx_buffer[rx_used - 7], "ERROR\r\n", 7)) { // ERROR received
+ radio_esp8266_response = true; // response received
radio_esp8266_success = false; // command failed
rx_used = 0; // reset buffer
}
diff --git a/lib/radio_esp8266.h b/lib/radio_esp8266.h
index 6af4614..0798759 100644
--- a/lib/radio_esp8266.h
+++ b/lib/radio_esp8266.h
@@ -13,23 +13,23 @@ extern volatile bool radio_esp8266_activity;
extern volatile bool radio_esp8266_success;
/** setup peripherals to communicate with radio
- * @note this is blocking to ensure we are connected to the WiFi network
+ * @return if it connected to AP
*/
-void radio_esp8266_setup(void);
+bool radio_esp8266_setup(void);
/** establish TCP connection
* @param[in] host host to connect to
* @param[in] port port number to connect to
* @param[in] tcp if connect to a TCP port (else UDP)
- * @note wait for activity to get success status
+ * @return if operation succeeded
*/
-void radio_esp8266_open(const char* host, uint16_t port, bool tcp);
+bool radio_esp8266_open(const char* host, uint16_t port, bool tcp);
/** send data (requires established connection)
* @param[in] data data to send
* @param[in] length size of data to send
- * @note wait for activity to get success status
+ * @return if operation succeeded
*/
-void radio_esp8266_send(const uint8_t* data, uint8_t length);
+bool radio_esp8266_send(const uint8_t* data, uint8_t length);
/** close established connection
- * @note wait for activity to get success status
+ * @return if operation succeeded
*/
-void radio_esp8266_close(void);
+bool radio_esp8266_close(void);