Merge branch 'main' into dev-twi
This commit is contained in:
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2025 Erick Ahmed
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
PROJECT = vase-control
|
PROJECT = plant-manager
|
||||||
|
|
||||||
MCU = atmega328p
|
MCU = atmega328p
|
||||||
F_CPU = 16000000UL
|
F_CPU = 16000000UL
|
||||||
|
|||||||
@@ -23,3 +23,13 @@ void eepromWrite(uint8_t address, uint8_t data) {
|
|||||||
EECR |= (1 << EEPE);
|
EECR |= (1 << EEPE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void eepromFlush(uint8_t address) {
|
||||||
|
if (eepromRead(address) != 0) {
|
||||||
|
EEAR = address;
|
||||||
|
EEDR = 0;
|
||||||
|
|
||||||
|
EECR |= (1 << EEMPE);
|
||||||
|
EECR |= (1 << EEPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(plant-manager)
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
git \
|
||||||
|
wget \
|
||||||
|
flex \
|
||||||
|
bison \
|
||||||
|
gperf \
|
||||||
|
python3 \
|
||||||
|
python3-pip \
|
||||||
|
python3-venv \
|
||||||
|
cmake \
|
||||||
|
ninja-build \
|
||||||
|
ccache \
|
||||||
|
libffi-dev \
|
||||||
|
libssl-dev \
|
||||||
|
dfu-util \
|
||||||
|
libusb-1.0-0 \
|
||||||
|
&& apt-get autoremove
|
||||||
|
|
||||||
|
WORKDIR /usr/src/
|
||||||
|
|
||||||
|
ENV IDF_PATH=/usr/src/esp/esp-idf
|
||||||
|
ENV IDF_PATH_FORCE=1
|
||||||
|
|
||||||
|
RUN mkdir -p /usr/src/esp/firmware
|
||||||
|
RUN git clone --recursive https://github.com/espressif/esp-idf.git $IDF_PATH
|
||||||
|
|
||||||
|
RUN cd $IDF_PATH && ./install.sh esp32c3
|
||||||
|
|
||||||
|
COPY . /usr/src/esp/firmware/
|
||||||
|
|
||||||
|
WORKDIR /usr/src/esp/firmware/
|
||||||
|
|
||||||
|
# Create sdkconfig.defaults with correct flash settings
|
||||||
|
RUN echo "CONFIG_ESPTOOLPY_FLASHMODE=dio" > sdkconfig.defaults && \
|
||||||
|
echo "CONFIG_ESPTOOLPY_FLASHFREQ=40m" >> sdkconfig.defaults && \
|
||||||
|
echo "CONFIG_ESPTOOLPY_FLASHSIZE=4MB" >> sdkconfig.defaults
|
||||||
|
|
||||||
|
RUN rm -rf build && /bin/bash -c "source $IDF_PATH/export.sh && idf.py set-target esp32c3 && idf.py build"
|
||||||
|
|
||||||
|
RUN mkdir -p /usr/src/build && \
|
||||||
|
cp build/bootloader/bootloader.bin /usr/src/build/ && \
|
||||||
|
cp build/partition_table/partition-table.bin /usr/src/build/ && \
|
||||||
|
cp build/plant-manager.bin /usr/src/build/
|
||||||
Executable
+27
@@ -0,0 +1,27 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
IMAGE_NAME="esp32-builder"
|
||||||
|
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||||
|
DOCKERFILE="$SCRIPT_DIR/Dockerfile"
|
||||||
|
BUILD_CTX="$SCRIPT_DIR"
|
||||||
|
DEST_DIR="$SCRIPT_DIR/build"
|
||||||
|
|
||||||
|
docker build -t "$IMAGE_NAME" -f "$DOCKERFILE" "$BUILD_CTX"
|
||||||
|
|
||||||
|
mkdir -p "$DEST_DIR"
|
||||||
|
|
||||||
|
docker run --rm -v "$DEST_DIR":/output "$IMAGE_NAME" cp -r /usr/src/build/. /output/
|
||||||
|
|
||||||
|
#echo "Erasing flash..."
|
||||||
|
#esptool --chip esp32c3 --port /dev/tty.usbmodem101 erase-flash
|
||||||
|
|
||||||
|
esptool --chip esp32c3 --port /dev/tty.usbmodem101 --baud 115200 write-flash \
|
||||||
|
--flash-mode dio \
|
||||||
|
--flash-freq 40m \
|
||||||
|
--flash-size 4MB \
|
||||||
|
0x0000 "$DEST_DIR/bootloader.bin" \
|
||||||
|
0x8000 "$DEST_DIR/partition-table.bin" \
|
||||||
|
0x10000 "$DEST_DIR/plant-manager.bin"
|
||||||
|
|
||||||
|
screen -fn /dev/tty.usbmodem101 115200
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern volatile bool criticalErrorFlag;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef WIFI_CREDENTIALS_H
|
||||||
|
#define WIFI_CREDENTIALS_H
|
||||||
|
|
||||||
|
#define SSID "your_wifi_ssid"
|
||||||
|
#define PASSWORD "your_wifi_password"
|
||||||
|
#define AUTH_MODE WIFI_AUTH_WPA2_PSK
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef WIFI_HPP
|
||||||
|
#define WIFI_HPP
|
||||||
|
|
||||||
|
void wifiTask(void *pvParameters);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
idf_component_register(SRCS "./main.cpp"
|
||||||
|
"./wifi.cpp"
|
||||||
|
INCLUDE_DIRS "../include"
|
||||||
|
REQUIRES esp_wifi
|
||||||
|
nvs_flash
|
||||||
|
esp_pm
|
||||||
|
esp_hw_support
|
||||||
|
esp_system
|
||||||
|
freertos
|
||||||
|
log)
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_pm.h"
|
||||||
|
#include "esp_task_wdt.h"
|
||||||
|
#include "wifi.hpp"
|
||||||
|
|
||||||
|
static const char* TAG = "MAIN";
|
||||||
|
|
||||||
|
volatile bool criticalErrorFlag = false;
|
||||||
|
|
||||||
|
static void watchdogTask(void *pvParameters) {
|
||||||
|
esp_task_wdt_config_t twdt_config = {
|
||||||
|
.timeout_ms = 12000,
|
||||||
|
.idle_core_mask = 0,
|
||||||
|
.trigger_panic = true,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_task_wdt_deinit());
|
||||||
|
ESP_ERROR_CHECK(esp_task_wdt_init(&twdt_config));
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_task_wdt_add(NULL));
|
||||||
|
|
||||||
|
const TickType_t keepAlivePeriod = pdMS_TO_TICKS(8000);
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
if (criticalErrorFlag) {
|
||||||
|
ESP_LOGE(TAG, "Critical error flag raised. Rebooting.");
|
||||||
|
esp_restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_task_wdt_reset());
|
||||||
|
ESP_LOGI(TAG, "WDT reset");
|
||||||
|
|
||||||
|
vTaskDelay(keepAlivePeriod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void app_main(void)
|
||||||
|
{
|
||||||
|
static const esp_pm_config_t pm_cfg = {
|
||||||
|
.max_freq_mhz = 160,
|
||||||
|
.min_freq_mhz = 10,
|
||||||
|
.light_sleep_enable = true
|
||||||
|
};
|
||||||
|
esp_pm_configure(&pm_cfg);
|
||||||
|
|
||||||
|
xTaskCreate(watchdogTask, "watchdogs", 2048, NULL, configMAX_PRIORITIES-1, NULL);
|
||||||
|
xTaskCreate(wifiTask, "wifi", 4096, NULL, configMAX_PRIORITIES-4, NULL);
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/event_groups.h"
|
||||||
|
#include "esp_task_wdt.h"
|
||||||
|
#include "esp_wifi.h"
|
||||||
|
#include "esp_event.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "nvs_flash.h"
|
||||||
|
#include "main.hpp"
|
||||||
|
#include "wifi-credentials.h"
|
||||||
|
|
||||||
|
#define WIFI_TIMEOUT_TICKS pdMS_TO_TICKS(8000)
|
||||||
|
|
||||||
|
static const char* TAG = "WIFI";
|
||||||
|
const int WIFI_CONNECTED_BIT = BIT0;
|
||||||
|
|
||||||
|
EventGroupHandle_t wifi_event_group;
|
||||||
|
|
||||||
|
static void wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {
|
||||||
|
if (event_base == WIFI_EVENT) {
|
||||||
|
switch (event_id) {
|
||||||
|
case WIFI_EVENT_STA_START:
|
||||||
|
ESP_LOGI(TAG, "Wi-Fi process started, connecting...");
|
||||||
|
|
||||||
|
esp_wifi_connect();
|
||||||
|
break;
|
||||||
|
case WIFI_EVENT_STA_DISCONNECTED: {
|
||||||
|
wifi_event_sta_disconnected_t* disconn = (wifi_event_sta_disconnected_t*) event_data;
|
||||||
|
ESP_LOGW(TAG, "Disconnected, reason: %d", disconn->reason);
|
||||||
|
|
||||||
|
xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT);
|
||||||
|
esp_wifi_connect();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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(TAG, "Got IP: " IPSTR, IP2STR(&event->ip_info.ip));
|
||||||
|
xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wifi_init_sta(void) {
|
||||||
|
esp_err_t nvs_err = nvs_flash_init();
|
||||||
|
|
||||||
|
if (nvs_err == ESP_ERR_NVS_NO_FREE_PAGES || nvs_err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||||
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||||
|
ESP_ERROR_CHECK(nvs_flash_init());
|
||||||
|
}
|
||||||
|
|
||||||
|
wifi_event_group = xEventGroupCreate();
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_netif_init());
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||||
|
|
||||||
|
esp_netif_create_default_wifi_sta();
|
||||||
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, NULL));
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, NULL));
|
||||||
|
|
||||||
|
wifi_config_t wifi_config{};
|
||||||
|
strncpy((char*)wifi_config.sta.ssid, SSID, sizeof(wifi_config.sta.ssid));
|
||||||
|
strncpy((char*)wifi_config.sta.password, PASSWORD, sizeof(wifi_config.sta.password));
|
||||||
|
wifi_config.sta.threshold.authmode = AUTH_MODE;
|
||||||
|
wifi_config.sta.pmf_cfg.capable = true;
|
||||||
|
wifi_config.sta.pmf_cfg.required = false;
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_start());
|
||||||
|
}
|
||||||
|
|
||||||
|
void wifiTask(void *pvParameters) {
|
||||||
|
ESP_LOGI(TAG, "WiFi task started");
|
||||||
|
|
||||||
|
wifi_init_sta();
|
||||||
|
ESP_ERROR_CHECK(esp_task_wdt_add(NULL));
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
EventBits_t bits = xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_BIT, pdFALSE, pdTRUE, WIFI_TIMEOUT_TICKS);
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_task_wdt_reset());
|
||||||
|
ESP_LOGI(TAG, "Wi-Fi task reset");
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(4000));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/task.h"
|
|
||||||
#include "driver/gpio.h"
|
|
||||||
|
|
||||||
extern "C" void app_main(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user