364 lines
12 KiB
C
Raw Normal View History

#include <sys/cdefs.h>
#include <stdio.h>
#include <esp_err.h>
#include <esp_wifi.h>
#include <esp_event.h>
#include <esp_log.h>
#include <nvs_flash.h>
#include <mqtt_client.h>
#include <esp_crt_bundle.h>
#include "fab-reader2.h"
#include "platform.h"
#include "st25R3911_interrupt.h"
#include "DEV_Config.h"
#include "pollingtagdetect.h"
#include "epd.h"
#include "ota.h"
#define SPI_CLK 5
#define SPI_MOSI 6
#define SPI_MISO 7
#define ESP_INTR_FLAG_DEFAULT 0
portMUX_TYPE CommProtectLock = portMUX_INITIALIZER_UNLOCKED;
esp_err_t init_mqtt(void);
static void IRAM_ATTR gpio_isr_handler(void *arg) {
st25r3911Isr();
ets_printf("Interrupt\n");
}
static void network_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
esp_wifi_connect();
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI("network", "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
ESP_ERROR_CHECK(init_mqtt());
ESP_LOGI("main", "init_mqtt done");
}
}
/*
* @brief Event handler registered to receive MQTT events
*
* This function is called by the MQTT client event loop.
*
* @param handler_args user data registered to the event.
* @param base Event base for the handler(always MQTT Base in this example).
* @param event_id The id for the received event.
* @param event_data The data for the event, esp_mqtt_event_handle_t.
*/
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
ESP_LOGD("mqtt", "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
esp_mqtt_event_handle_t event = event_data;
esp_mqtt_client_handle_t client = event->client;
int msg_id;
switch ((esp_mqtt_event_id_t)event_id) {
case MQTT_EVENT_CONNECTED:
ESP_LOGI("mqtt", "MQTT_EVENT_CONNECTED");
char id[6] = "00000";
sprintf(id, "%05d", CONFIG_FABREADER2_ID);
// Register Reader
msg_id = esp_mqtt_client_publish(client, "fabreader", id, 0, 0, 0);
ESP_LOGI("mqtt", "sent publish successful, msg_id=%d", msg_id);
char topic_requestOTA[] = "fabreader/00000/requestOTA";
sprintf(topic_requestOTA, "fabreader/%05d/requestOTA", CONFIG_FABREADER2_ID);
msg_id = esp_mqtt_client_subscribe(client, topic_requestOTA, 0);
ESP_LOGI("mqtt", "sent subscribe successful, msg_id=%d", msg_id);
char topic_stopOTA[] = "fabreader/00000/stopOTA";
sprintf(topic_stopOTA, "fabreader/%05d/stopOTA", CONFIG_FABREADER2_ID);
msg_id = esp_mqtt_client_subscribe(client, topic_stopOTA, 0);
ESP_LOGI("mqtt", "sent subscribe successful, msg_id=%d", msg_id);
char topic_display[] = "fabreader/00000/display/#";
sprintf(topic_display, "fabreader/%05d/display/#", CONFIG_FABREADER2_ID);
msg_id = esp_mqtt_client_subscribe(client, topic_display, 0);
ESP_LOGI("mqtt", "sent subscribe successful, msg_id=%d", msg_id);
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI("mqtt", "MQTT_EVENT_DISCONNECTED");
break;
case MQTT_EVENT_SUBSCRIBED:
ESP_LOGI("mqtt", "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_UNSUBSCRIBED:
ESP_LOGI("mqtt", "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGI("mqtt", "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_DATA:
ESP_LOGI("mqtt", "MQTT_EVENT_DATA");
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
printf("DATA=%.*s\r\n", event->data_len, event->data);
if (hasActiveOTA()) {
continueOTA(client, event->topic, event->data, event->data_len);
}
break;
case MQTT_EVENT_ERROR:
ESP_LOGE("mqtt", "MQTT_EVENT_ERROR");
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
ESP_LOGE("mqtt", "Last error code reported from esp-tls: 0x%x", event->error_handle->esp_tls_last_esp_err);
ESP_LOGE("mqtt", "Last tls stack error number: 0x%x", event->error_handle->esp_tls_stack_err);
ESP_LOGE("mqtt", "Last captured errno : %d (%s)", event->error_handle->esp_transport_sock_errno,
strerror(event->error_handle->esp_transport_sock_errno));
} else if (event->error_handle->error_type == MQTT_ERROR_TYPE_CONNECTION_REFUSED) {
ESP_LOGE("mqtt", "Connection refused error: 0x%x", event->error_handle->connect_return_code);
} else {
ESP_LOGW("mqtt", "Unknown error type: 0x%x", event->error_handle->error_type);
}
break;
default:
ESP_LOGI("mqtt", "Other event id:%d", event->event_id);
break;
}
}
esp_err_t init_gpio(void) {
gpio_config_t io_conf = {};
//disable interrupt
io_conf.intr_type = GPIO_INTR_DISABLE;
//set as output mode
io_conf.mode = GPIO_MODE_INPUT_OUTPUT;
//bit mask of the pins that you want to set,e.g.GPIO18/19
io_conf.pin_bit_mask = (1ULL << ST25R391X_SS_PIN) | (1ULL << EPD_CS_PIN) | (1ULL << EPD_DC_PIN) | (1ULL << EPD_RST_PIN);
//disable pull-down mode
io_conf.pull_down_en = 0;
//disable pull-up mode
io_conf.pull_up_en = 0;
//configure GPIO with the given settings
esp_err_t ret = gpio_config(&io_conf);
ESP_ERROR_CHECK(ret);
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pin_bit_mask = (1ULL << EPD_BUSY_PIN);
ret = gpio_config(&io_conf);
ESP_ERROR_CHECK(ret);
//interrupt of rising edge
io_conf.intr_type = GPIO_INTR_POSEDGE;
//bit mask of the pins, use GPIO4/5 here
io_conf.pin_bit_mask = (1ULL << ST25R391X_INT_PIN);
//set as input mode
io_conf.mode = GPIO_MODE_INPUT;
//disable pull-down mode
io_conf.pull_down_en = 0;
//enable pull-up mode
io_conf.pull_up_en = 0;
ESP_ERROR_CHECK(gpio_config(&io_conf));
ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT));
//hook isr handler for specific gpio pin
ESP_ERROR_CHECK(gpio_isr_handler_add(ST25R391X_INT_PIN, gpio_isr_handler, NULL));
return ret;
}
esp_err_t init_spi(void) {
spi_bus_config_t buscfg = {
.miso_io_num=SPI_MISO,
.mosi_io_num=SPI_MOSI,
.sclk_io_num=SPI_CLK,
.quadwp_io_num=-1,
.quadhd_io_num=-1,
};
esp_err_t ret = spi_bus_initialize(SPI3_HOST, &buscfg, SPI_DMA_CH_AUTO);
ESP_ERROR_CHECK(ret);
spi_device_interface_config_t nfc_devcfg = {
.clock_speed_hz=SPI_MASTER_FREQ_8M, //Clock out at 26 MHz
.mode=1, //SPI mode 1
.spics_io_num=-1, //CS pin
.queue_size=1, //We want to be able to queue 7 transactions at a time
};
spi_device_handle_t nfc_spi;
ret = spi_bus_add_device(SPI3_HOST, &nfc_devcfg, &nfc_spi);
ESP_ERROR_CHECK(ret);
st25r3911_spi_init(nfc_spi);
spi_device_interface_config_t epd_devcfg = {
.clock_speed_hz=SPI_MASTER_FREQ_8M, //Clock out at 26 MHz
.mode=0, //SPI mode 1
.spics_io_num=-1, //CS pin
.queue_size=1, //We want to be able to queue 7 transactions at a time
};
spi_device_handle_t epd_spi;
ret = spi_bus_add_device(SPI3_HOST, &epd_devcfg, &epd_spi);
ESP_ERROR_CHECK(ret);
DEV_SPI_Init(epd_spi);
return ret;
}
esp_err_t init_eventloop() {
esp_err_t ret = esp_event_loop_create_default();
ESP_ERROR_CHECK(ret);
return ret;
}
esp_err_t init_wifi() {
esp_err_t ret;
ret = esp_netif_init();
ESP_ERROR_CHECK(ret);
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ret = esp_wifi_init(&cfg);
ESP_ERROR_CHECK(ret);
ret = esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &network_event_handler, NULL, NULL);
ESP_ERROR_CHECK(ret);
ret = esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &network_event_handler, NULL, NULL);
ESP_ERROR_CHECK(ret);
// Initialize default station as network interface instance (esp-netif)
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
assert(sta_netif);
// Initialize and start WiFi
wifi_config_t wifi_config = {
.sta = {
.ssid = DEFAULT_SSID,
.password = DEFAULT_PWD,
.scan_method = DEFAULT_SCAN_METHOD,
.sort_method = DEFAULT_SORT_METHOD,
.threshold.rssi = DEFAULT_RSSI,
.threshold.authmode = DEFAULT_AUTHMODE,
},
};
ret = esp_wifi_set_mode(WIFI_MODE_STA);
ESP_ERROR_CHECK(ret);
ret = esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
ESP_ERROR_CHECK(ret);
ret = esp_wifi_start();
ESP_ERROR_CHECK(ret);
return ret;
}
esp_err_t init_nvs() {
// Initialize NVS
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );
return ret;
}
esp_err_t init_mqtt() {
esp_err_t ret;
const esp_mqtt_client_config_t mqtt_cfg = {
.uri = CONFIG_BROKER_URI,
.crt_bundle_attach = esp_crt_bundle_attach
};
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
ret = esp_mqtt_client_register_event(client, MQTT_EVENT_ANY, mqtt_event_handler, NULL);
ESP_ERROR_CHECK(ret);
ret = esp_mqtt_client_start(client);
ESP_ERROR_CHECK(ret);
mqtt_client = client;
return ret;
}
esp_err_t init_epd() {
esp_err_t ret;
reader_info_t reader_info = {
.reader_id = CONFIG_FABREADER2_ID,
.battery_level = 100
};
buttons_t buttons = {
.btn0 = "X",
.btn1 = "<",
.btn2 = "O",
.btn3 = ">"
};
display_t display = {
.canvas = NULL,
.image = NULL,
.machine_name = "",
.state = "IDLE",
.buttons = buttons,
.reader_info = reader_info
};
ret = epd_init(display);
ESP_ERROR_CHECK(ret);
return ret;
}
_Noreturn static void cycle_task(void *arg) {
while (1) {
TagDetectCycle();
// ESP_LOGI("cycle_task", "running tag detect cycle_task");
}
}
void app_main(void) {
// Log basic information about the system
ESP_LOGI("startup", "Startup..");
ESP_LOGI("startup", "Built with IDF version: %s", esp_get_idf_version());
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
ESP_LOGI("startup", "This is %s chip with %d CPU cores, WiFi%s%s, ",
chip_info.model == CHIP_ESP32S3 ? "ESP32S3" : CHIP_ESP32S2 ? "ESP32S2" : "unknown",
chip_info.cores,
(chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
(chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
// Initialize peripherals
ESP_ERROR_CHECK(init_gpio());
ESP_LOGI("main", "init_gpio done");
ESP_ERROR_CHECK(init_spi());
ESP_LOGI("main", "init_spi done");
// ESP_ERROR_CHECK(init_epd());
ESP_LOGI("main", "init_epd done");
ESP_ERROR_CHECK(init_nvs());
ESP_LOGI("main", "init_nvs done");
ESP_ERROR_CHECK(init_eventloop());
ESP_LOGI("main", "init_eventloop done");
ESP_ERROR_CHECK(init_wifi());
ESP_LOGI("main", "init_wifi done");
// epd_update_state("OTA...");
// Start main application
ESP_ERROR_CHECK(TagDetectInit());
ESP_LOGI("main", "TagDetectInit done");
xTaskCreate(cycle_task, "cycle_task", 4096, NULL, tskIDLE_PRIORITY, NULL);
ESP_LOGI("main", "cycle_task sheduled");
ESP_LOGI("app", "Free memory: %d bytes", esp_get_free_heap_size());
}