diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..567609b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..245f296 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "idf.adapterTargetName": "esp32s3" +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..3bb7ee8 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(EXTRA_COMPONENT_DIRS "./components/rotary_encoder") + +project(pile_cm) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2a35a34 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := wifi_station +EXTRA_COMPONENT_DIRS += $(IDF_PATH)/examples/common_components +EXTRA_COMPONENT_DIRS += $(IDF_PATH)/examples/peripherals/pcnt/rotary_encoder/components + +include $(IDF_PATH)/make/project.mk diff --git a/README.md b/README.md index a778c26..e69de29 100644 --- a/README.md +++ b/README.md @@ -1,118 +0,0 @@ -# Wi-Fi Station Example - -(See the README.md file in the upper level 'examples' directory for more information about examples.) - -This example shows how to use the Wi-Fi Station functionality of the Wi-Fi driver of ESP for connecting to an Access Point. - -## How to use example - -### Configure the project - -Open the project configuration menu (`idf.py menuconfig`). - -In the `Example Configuration` menu: - -* Set the Wi-Fi configuration. - * Set `WiFi SSID`. - * Set `WiFi Password`. - -Optional: If you need, change the other options according to your requirements. - -### Build and Flash - -Build the project and flash it to the board, then run the monitor tool to view the serial output: - -Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. - -(To exit the serial monitor, type ``Ctrl-]``.) - -See the Getting Started Guide for all the steps to configure and use the ESP-IDF to build projects. - -* [ESP-IDF Getting Started Guide on ESP32](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html) -* [ESP-IDF Getting Started Guide on ESP32-S2](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/get-started/index.html) -* [ESP-IDF Getting Started Guide on ESP32-C3](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/get-started/index.html) - -## Example Output -Note that the output, in particular the order of the output, may vary depending on the environment. - -Console output if station connects to AP successfully: -``` -I (589) wifi station: ESP_WIFI_MODE_STA -I (599) wifi: wifi driver task: 3ffc08b4, prio:23, stack:3584, core=0 -I (599) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE -I (599) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE -I (629) wifi: wifi firmware version: 2d94f02 -I (629) wifi: config NVS flash: enabled -I (629) wifi: config nano formating: disabled -I (629) wifi: Init dynamic tx buffer num: 32 -I (629) wifi: Init data frame dynamic rx buffer num: 32 -I (639) wifi: Init management frame dynamic rx buffer num: 32 -I (639) wifi: Init management short buffer num: 32 -I (649) wifi: Init static rx buffer size: 1600 -I (649) wifi: Init static rx buffer num: 10 -I (659) wifi: Init dynamic rx buffer num: 32 -I (759) phy: phy_version: 4180, cb3948e, Sep 12 2019, 16:39:13, 0, 0 -I (769) wifi: mode : sta (30:ae:a4:d9:bc:c4) -I (769) wifi station: wifi_init_sta finished. -I (889) wifi: new:<6,0>, old:<1,0>, ap:<255,255>, sta:<6,0>, prof:1 -I (889) wifi: state: init -> auth (b0) -I (899) wifi: state: auth -> assoc (0) -I (909) wifi: state: assoc -> run (10) -I (939) wifi: connected with #!/bin/test, aid = 1, channel 6, BW20, bssid = ac:9e:17:7e:31:40 -I (939) wifi: security type: 3, phy: bgn, rssi: -68 -I (949) wifi: pm start, type: 1 - -I (1029) wifi: AP's beacon interval = 102400 us, DTIM period = 3 -I (2089) esp_netif_handlers: sta ip: 192.168.77.89, mask: 255.255.255.0, gw: 192.168.77.1 -I (2089) wifi station: got ip:192.168.77.89 -I (2089) wifi station: connected to ap SSID:myssid password:mypassword -``` - -Console output if the station failed to connect to AP: -``` -I (589) wifi station: ESP_WIFI_MODE_STA -I (599) wifi: wifi driver task: 3ffc08b4, prio:23, stack:3584, core=0 -I (599) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE -I (599) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE -I (629) wifi: wifi firmware version: 2d94f02 -I (629) wifi: config NVS flash: enabled -I (629) wifi: config nano formating: disabled -I (629) wifi: Init dynamic tx buffer num: 32 -I (629) wifi: Init data frame dynamic rx buffer num: 32 -I (639) wifi: Init management frame dynamic rx buffer num: 32 -I (639) wifi: Init management short buffer num: 32 -I (649) wifi: Init static rx buffer size: 1600 -I (649) wifi: Init static rx buffer num: 10 -I (659) wifi: Init dynamic rx buffer num: 32 -I (759) phy: phy_version: 4180, cb3948e, Sep 12 2019, 16:39:13, 0, 0 -I (759) wifi: mode : sta (30:ae:a4:d9:bc:c4) -I (769) wifi station: wifi_init_sta finished. -I (889) wifi: new:<6,0>, old:<1,0>, ap:<255,255>, sta:<6,0>, prof:1 -I (889) wifi: state: init -> auth (b0) -I (1889) wifi: state: auth -> init (200) -I (1889) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1 -I (1889) wifi station: retry to connect to the AP -I (1899) wifi station: connect to the AP fail -I (3949) wifi station: retry to connect to the AP -I (3949) wifi station: connect to the AP fail -I (4069) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1 -I (4069) wifi: state: init -> auth (b0) -I (5069) wifi: state: auth -> init (200) -I (5069) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1 -I (5069) wifi station: retry to connect to the AP -I (5069) wifi station: connect to the AP fail -I (7129) wifi station: retry to connect to the AP -I (7129) wifi station: connect to the AP fail -I (7249) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1 -I (7249) wifi: state: init -> auth (b0) -I (8249) wifi: state: auth -> init (200) -I (8249) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1 -I (8249) wifi station: retry to connect to the AP -I (8249) wifi station: connect to the AP fail -I (10299) wifi station: connect to the AP fail -I (10299) wifi station: Failed to connect to SSID:myssid, password:mypassword -``` - -## Troubleshooting - -For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/components/motor_ctrl_timer/CMakeLists.txt b/components/motor_ctrl_timer/CMakeLists.txt new file mode 100644 index 0000000..4f440a7 --- /dev/null +++ b/components/motor_ctrl_timer/CMakeLists.txt @@ -0,0 +1,5 @@ +set(COMPONENT_SRCS "motor_ctrl_timer.c") + +idf_component_register(SRCS "${COMPONENT_SRCS}" + INCLUDE_DIRS . + PRIV_REQUIRES "driver") diff --git a/components/motor_ctrl_timer/component.mk b/components/motor_ctrl_timer/component.mk new file mode 100644 index 0000000..27ad11a --- /dev/null +++ b/components/motor_ctrl_timer/component.mk @@ -0,0 +1 @@ +COMPONENT_ADD_INCLUDEDIRS := . diff --git a/components/motor_ctrl_timer/motor_ctrl_timer.c b/components/motor_ctrl_timer/motor_ctrl_timer.c new file mode 100644 index 0000000..1a76ad2 --- /dev/null +++ b/components/motor_ctrl_timer/motor_ctrl_timer.c @@ -0,0 +1,141 @@ +/* To set the control period for DC motor Timer + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +#include +#include "motor_ctrl_timer.h" +#include "esp_check.h" + +#define MOTOR_CTRL_TIMER_DIVIDER (16) // Hardware timer clock divider +#define MOTOR_CTRL_TIMER_SCALE (TIMER_BASE_CLK / MOTOR_CTRL_TIMER_DIVIDER) // convert counter value to seconds + +#define MOTOR_CONTROL_TIMER_GROUP TIMER_GROUP_0 +#define MOTOR_CONTROL_TIMER_ID TIMER_0 + +static const char *TAG = "motor_ctrl_timer"; + +/** + * @brief Callback function of timer intterupt + * + * @param args The parameter transmited to callback function from timer_isr_callback_add. Args here is for timer_info. + * @return + * - True Do task yield at the end of ISR + * - False Not do task yield at the end of ISR +*/ +static bool IRAM_ATTR motor_ctrl_timer_isr_callback(void *args) +{ + BaseType_t high_task_awoken = pdFALSE; + motor_ctrl_timer_info_t *info = (motor_ctrl_timer_info_t *) args; + info->pulse_info.pulse_cnt = info->pulse_info.get_pulse_callback(info->pulse_info.callback_args); + + /* Now just send the event data back to the main program task */ + xQueueSendFromISR(info->timer_evt_que, info, &high_task_awoken); + + return high_task_awoken == pdTRUE; // return whether we need to yield at the end of ISR +} + +/** + * @brief Initialize the motor control timer + * + * @param timer_info the secondary pointer of motor_ctrl_timer_info_t + * @param evt_que timer event queue + * @param ctrl_period_ms motor control period + * @param pulse_info quadrature encoder pulse information + * @return + * - ESP_OK: Motor control timer initialized successfully + * - ESP_FAIL: motor control timer failed to initialize because of other errors + */ +esp_err_t motor_ctrl_new_timer(motor_ctrl_timer_info_t **timer_info, + QueueHandle_t evt_que, + unsigned int ctrl_period_ms, + pulse_info_t pulse_info) +{ + esp_err_t ret = ESP_FAIL; + /* Select and initialize basic parameters of the timer */ + timer_config_t config = { + .divider = MOTOR_CTRL_TIMER_DIVIDER, + .counter_dir = TIMER_COUNT_UP, + .counter_en = TIMER_PAUSE, + .alarm_en = TIMER_ALARM_EN, + .auto_reload = true, + }; // default clock source is APB + ret = timer_init(MOTOR_CONTROL_TIMER_GROUP, MOTOR_CONTROL_TIMER_ID, &config); + ESP_RETURN_ON_ERROR(ret, TAG, "timer init failed\n"); + + /* Timer's counter will initially start from value below. + Since auto_reload is set, this value will be automatically reload on alarm */ + timer_set_counter_value(MOTOR_CONTROL_TIMER_GROUP, MOTOR_CONTROL_TIMER_ID, 0); + + /* Configure the alarm value and the interrupt on alarm. */ + timer_set_alarm_value(MOTOR_CONTROL_TIMER_GROUP, MOTOR_CONTROL_TIMER_ID, ctrl_period_ms * MOTOR_CTRL_TIMER_SCALE / 1000); + timer_enable_intr(MOTOR_CONTROL_TIMER_GROUP, MOTOR_CONTROL_TIMER_ID); + + /* Check the pointers */ + ESP_GOTO_ON_FALSE(evt_que, ESP_ERR_INVALID_ARG, err, TAG, "timer event queue handler is NULL\n"); + ESP_GOTO_ON_FALSE(timer_info, ESP_ERR_INVALID_ARG, err, TAG, "timer info structure pointer is NULL\n"); + /* Alloc and config the infomation structure for this file */ + *timer_info = calloc(1, sizeof(motor_ctrl_timer_info_t)); + ESP_GOTO_ON_FALSE(*timer_info, ESP_ERR_NO_MEM, err, TAG, "timer_info calloc failed\n"); + (*timer_info)->timer_group = MOTOR_CONTROL_TIMER_GROUP; + (*timer_info)->timer_idx = MOTOR_CONTROL_TIMER_ID; + (*timer_info)->timer_evt_que = evt_que; + (*timer_info)->ctrl_period_ms = ctrl_period_ms; + (*timer_info)->pulse_info = pulse_info; + timer_isr_callback_add(MOTOR_CONTROL_TIMER_GROUP, MOTOR_CONTROL_TIMER_ID, motor_ctrl_timer_isr_callback, *timer_info, 0); + + return ret; +err: + timer_deinit(MOTOR_CONTROL_TIMER_GROUP, MOTOR_CONTROL_TIMER_ID); + return ret; +} + +/** + * @brief Set timer alarm period + * + * @param period Timer alarm period + * @return + * - void + */ +void motor_ctrl_timer_set_period(unsigned int period) +{ + timer_set_alarm_value(MOTOR_CONTROL_TIMER_GROUP, MOTOR_CONTROL_TIMER_ID, period * MOTOR_CTRL_TIMER_SCALE / 1000); +} + +/** + * @brief Start the timer + */ +void motor_ctrl_timer_start(void) +{ + /* start the timer */ + timer_start(MOTOR_CONTROL_TIMER_GROUP, MOTOR_CONTROL_TIMER_ID); +} + + +/** + * @brief Pause the timer and clear the counting value + */ +void motor_ctrl_timer_stop(void) +{ + /* stop the timer */ + timer_pause(MOTOR_CONTROL_TIMER_GROUP, MOTOR_CONTROL_TIMER_ID); + timer_set_counter_value(MOTOR_CONTROL_TIMER_GROUP, MOTOR_CONTROL_TIMER_ID, 0); +} + +/** + * @brief Deinitialize the timer + * + * @param timer_info the secondary pointer of motor_ctrl_timer_info_t, the memory will be freed + */ +void motor_ctrl_timer_deinit(motor_ctrl_timer_info_t **timer_info) +{ + if (*timer_info != NULL) { + timer_deinit(MOTOR_CONTROL_TIMER_GROUP, MOTOR_CONTROL_TIMER_ID); + free(*timer_info); + *timer_info = NULL; + } +} diff --git a/components/motor_ctrl_timer/motor_ctrl_timer.h b/components/motor_ctrl_timer/motor_ctrl_timer.h new file mode 100644 index 0000000..ca9646f --- /dev/null +++ b/components/motor_ctrl_timer/motor_ctrl_timer.h @@ -0,0 +1,78 @@ +/* To set the control period for DC motor Timer + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "driver/timer.h" + +typedef struct { + int (*get_pulse_callback)(void *); + void *callback_args; + int pulse_cnt; +} pulse_info_t; + + +typedef struct { + timer_group_t timer_group; /* Timer Group number */ + timer_idx_t timer_idx; /* Timer ID */ + unsigned int ctrl_period_ms; /* Motor control period, unit in ms */ + QueueHandle_t timer_evt_que; /* The queue of timer events */ + pulse_info_t pulse_info; +} motor_ctrl_timer_info_t; + +/** + * @brief Initialize the motor control timer + * + * @param timer_info the secondary pointer of motor_ctrl_timer_info_t + * @param evt_que timer event queue + * @param ctrl_period_ms motor control period + * @param pulse_info quadrature encoder pulse information + * @return + * - ESP_OK: Motor control timer initialized successfully + * - ESP_FAIL: motor control timer failed to initialize because of other errors + */ +esp_err_t motor_ctrl_new_timer(motor_ctrl_timer_info_t **timer_info, + QueueHandle_t evt_que, + unsigned int ctrl_period_ms, + pulse_info_t pulse_info); + +/** + * @brief Set timer alarm period + * + * @param period Timer alarm period + */ +void motor_ctrl_timer_set_period(unsigned int period); + +/** + * @brief Start the timer + */ +void motor_ctrl_timer_start(void); + + +/** + * @brief Pause the timer and clear the counting value + */ +void motor_ctrl_timer_stop(void); + +/** + * @brief Deinitialize the timer + * + * @param timer_info the secondary pointer of motor_ctrl_timer_info_t, the memory will be freed + */ +void motor_ctrl_timer_deinit(motor_ctrl_timer_info_t **timer_info); + +#ifdef __cplusplus +} +#endif diff --git a/components/rotary_encoder/CMakeLists.txt b/components/rotary_encoder/CMakeLists.txt new file mode 100644 index 0000000..2396f78 --- /dev/null +++ b/components/rotary_encoder/CMakeLists.txt @@ -0,0 +1,7 @@ +set(component_srcs "src/rotary_encoder_pcnt_ec11.c") + +idf_component_register(SRCS "${component_srcs}" + INCLUDE_DIRS "include" + PRIV_INCLUDE_DIRS "" + PRIV_REQUIRES "driver" + REQUIRES "") diff --git a/components/rotary_encoder/component.mk b/components/rotary_encoder/component.mk new file mode 100644 index 0000000..24cab8b --- /dev/null +++ b/components/rotary_encoder/component.mk @@ -0,0 +1,3 @@ +COMPONENT_ADD_INCLUDEDIRS := include + +COMPONENT_SRCDIRS := src diff --git a/components/rotary_encoder/include/rotary_encoder.h b/components/rotary_encoder/include/rotary_encoder.h new file mode 100644 index 0000000..3b5c797 --- /dev/null +++ b/components/rotary_encoder/include/rotary_encoder.h @@ -0,0 +1,127 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "esp_err.h" + +/** + * @brief Type of Rotary underlying device handle + * + */ +typedef void *rotary_encoder_dev_t; + +/** + * @brief Type of rotary encoder configuration + * + */ +typedef struct { + rotary_encoder_dev_t dev; /*!< Underlying device handle */ + int phase_a_gpio_num; /*!< Phase A GPIO number */ + int phase_b_gpio_num; /*!< Phase B GPIO number */ + int flags; /*!< Extra flags */ +} rotary_encoder_config_t; + +/** + * @brief Default rotary encoder configuration + * + */ +#define ROTARY_ENCODER_DEFAULT_CONFIG(dev_hdl, gpio_a, gpio_b) \ + { \ + .dev = dev_hdl, \ + .phase_a_gpio_num = gpio_a, \ + .phase_b_gpio_num = gpio_b, \ + .flags = 0, \ + } + +/** + * @brief Type of rotary encoder handle + * + */ +typedef struct rotary_encoder_t rotary_encoder_t; + +/** + * @brief Rotary encoder interface + * + */ +struct rotary_encoder_t { + /** + * @brief Filter out glitch from input signals + * + * @param encoder Rotary encoder handle + * @param max_glitch_us Maximum glitch duration, in us + * @return + * - ESP_OK: Set glitch filter successfully + * - ESP_FAIL: Set glitch filter failed because of other error + */ + esp_err_t (*set_glitch_filter)(rotary_encoder_t *encoder, uint32_t max_glitch_us); + + /** + * @brief Start rotary encoder + * + * @param encoder Rotary encoder handle + * @return + * - ESP_OK: Start rotary encoder successfully + * - ESP_FAIL: Start rotary encoder failed because of other error + */ + esp_err_t (*start)(rotary_encoder_t *encoder); + + /** + * @brief Stop rotary encoder + * + * @param encoder Rotary encoder handle + * @return + * - ESP_OK: Stop rotary encoder successfully + * - ESP_FAIL: Stop rotary encoder failed because of other error + */ + esp_err_t (*stop)(rotary_encoder_t *encoder); + + /** + * @brief Recycle rotary encoder memory + * + * @param encoder Rotary encoder handle + * @return + * - ESP_OK: Recycle rotary encoder memory successfully + * - ESP_FAIL: rotary encoder memory failed because of other error + */ + esp_err_t (*del)(rotary_encoder_t *encoder); + + /** + * @brief Get rotary encoder counter value + * + * @param encoder Rotary encoder handle + * @return Current counter value (the sign indicates the direction of rotation) + */ + int (*get_counter_value)(rotary_encoder_t *encoder); +}; + +/** + * @brief Create rotary encoder instance for EC11 + * + * @param config Rotary encoder configuration + * @param ret_encoder Returned rotary encoder handle + * @return + * - ESP_OK: Create rotary encoder instance successfully + * - ESP_ERR_INVALID_ARG: Create rotary encoder instance failed because of some invalid argument + * - ESP_ERR_NO_MEM: Create rotary encoder instance failed because there's no enough capable memory + * - ESP_FAIL: Create rotary encoder instance failed because of other error + */ +esp_err_t rotary_encoder_new_ec11(const rotary_encoder_config_t *config, rotary_encoder_t **ret_encoder); +esp_err_t ec11_pcnt_clear(pcnt_unit_t); +#ifdef __cplusplus +} +#endif diff --git a/components/rotary_encoder/src/rotary_encoder_pcnt_ec11.c b/components/rotary_encoder/src/rotary_encoder_pcnt_ec11.c new file mode 100644 index 0000000..40d5806 --- /dev/null +++ b/components/rotary_encoder/src/rotary_encoder_pcnt_ec11.c @@ -0,0 +1,238 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include +#include +#include +#include "esp_compiler.h" +#include "esp_log.h" +#include "driver/pcnt.h" +#include "sys/lock.h" +#include "hal/pcnt_hal.h" +#include "rotary_encoder.h" + +static const char *TAG = "rotary_encoder"; + +#define ROTARY_CHECK(a, msg, tag, ret, ...) \ + do \ + { \ + if (unlikely(!(a))) \ + { \ + ESP_LOGE(TAG, "%s(%d): " msg, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + ret_code = ret; \ + goto tag; \ + } \ + } while (0) + +#define EC11_PCNT_DEFAULT_HIGH_LIMIT (32767) +#define EC11_PCNT_DEFAULT_LOW_LIMIT (-32768) + +// A flag to identify if pcnt isr service has been installed. +static bool is_pcnt_isr_service_installed = false; +// A lock to avoid pcnt isr service being installed twice in multiple threads. +static _lock_t isr_service_install_lock; +#define LOCK_ACQUIRE() _lock_acquire(&isr_service_install_lock) +#define LOCK_RELEASE() _lock_release(&isr_service_install_lock) + +typedef struct +{ + int accumu_count; + rotary_encoder_t parent; + pcnt_unit_t pcnt_unit; +} ec11_t; + +static esp_err_t ec11_set_glitch_filter(rotary_encoder_t *encoder, uint32_t max_glitch_us) +{ + esp_err_t ret_code = ESP_OK; + ec11_t *ec11 = __containerof(encoder, ec11_t, parent); + + /* Configure and enable the input filter */ + ROTARY_CHECK(pcnt_set_filter_value(ec11->pcnt_unit, max_glitch_us * 80) == ESP_OK, "set glitch filter failed", err, ESP_FAIL); + + if (max_glitch_us) + { + pcnt_filter_enable(ec11->pcnt_unit); + } + else + { + pcnt_filter_disable(ec11->pcnt_unit); + } + + return ESP_OK; +err: + return ret_code; +} + +static esp_err_t ec11_start(rotary_encoder_t *encoder) +{ + ec11_t *ec11 = __containerof(encoder, ec11_t, parent); + pcnt_counter_resume(ec11->pcnt_unit); + return ESP_OK; +} + +static esp_err_t ec11_stop(rotary_encoder_t *encoder) +{ + ec11_t *ec11 = __containerof(encoder, ec11_t, parent); + pcnt_counter_pause(ec11->pcnt_unit); + return ESP_OK; +} + +static int ec11_get_counter_value(rotary_encoder_t *encoder) +{ + ec11_t *ec11 = __containerof(encoder, ec11_t, parent); + int16_t val = 0; + pcnt_get_counter_value(ec11->pcnt_unit, &val); + return val + ec11->accumu_count; +} + +static esp_err_t ec11_del(rotary_encoder_t *encoder) +{ + ec11_t *ec11 = __containerof(encoder, ec11_t, parent); + free(ec11); + return ESP_OK; +} + +static void ec11_pcnt_overflow_handler(void *arg) +{ + ec11_t *ec11 = (ec11_t *)arg; + uint32_t status = 0; + pcnt_get_event_status(ec11->pcnt_unit, &status); + + if (status & PCNT_EVT_H_LIM) + { + ec11->accumu_count += EC11_PCNT_DEFAULT_HIGH_LIMIT; + } + else if (status & PCNT_EVT_L_LIM) + { + ec11->accumu_count += EC11_PCNT_DEFAULT_LOW_LIMIT; + } +} + +esp_err_t rotary_encoder_new_ec11(const rotary_encoder_config_t *config, rotary_encoder_t **ret_encoder) +{ + esp_err_t ret_code = ESP_OK; + ec11_t *ec11 = NULL; + + ROTARY_CHECK(config, "configuration can't be null", err, ESP_ERR_INVALID_ARG); + ROTARY_CHECK(ret_encoder, "can't assign context to null", err, ESP_ERR_INVALID_ARG); + + ec11 = calloc(1, sizeof(ec11_t)); + ROTARY_CHECK(ec11, "allocate context memory failed", err, ESP_ERR_NO_MEM); + + ec11->pcnt_unit = (pcnt_unit_t)(config->dev); + + // Configure channel 0 + pcnt_config_t dev_config = { + .pulse_gpio_num = config->phase_a_gpio_num, + .ctrl_gpio_num = config->phase_b_gpio_num, + .channel = PCNT_CHANNEL_0, + .unit = ec11->pcnt_unit, + .pos_mode = PCNT_COUNT_DEC, + .neg_mode = PCNT_COUNT_INC, + .lctrl_mode = PCNT_MODE_REVERSE, + .hctrl_mode = PCNT_MODE_KEEP, + .counter_h_lim = EC11_PCNT_DEFAULT_HIGH_LIMIT, + .counter_l_lim = EC11_PCNT_DEFAULT_LOW_LIMIT, + }; + if (config->flags == 1) + { + dev_config.pulse_gpio_num = config->phase_b_gpio_num; + dev_config.ctrl_gpio_num = config->phase_a_gpio_num; + } + if (config->flags == 2) + { + dev_config.pos_mode = PCNT_COUNT_DIS; + dev_config.neg_mode = PCNT_COUNT_INC; + dev_config.lctrl_mode = PCNT_MODE_KEEP; + dev_config.hctrl_mode = PCNT_MODE_REVERSE; + } + else if (config->flags == 3) + { + dev_config.pos_mode = PCNT_COUNT_DIS; + dev_config.neg_mode = PCNT_COUNT_INC; + dev_config.lctrl_mode = PCNT_MODE_REVERSE; + dev_config.hctrl_mode = PCNT_MODE_KEEP; + } + ROTARY_CHECK(pcnt_unit_config(&dev_config) == ESP_OK, "config pcnt channel 0 failed", err, ESP_FAIL); + + // Configure channel 1 + dev_config.pulse_gpio_num = config->phase_b_gpio_num; + dev_config.ctrl_gpio_num = config->phase_a_gpio_num; + dev_config.channel = PCNT_CHANNEL_1; + dev_config.pos_mode = PCNT_COUNT_INC; + dev_config.neg_mode = PCNT_COUNT_DEC; + if (config->flags == 1) + { + dev_config.pulse_gpio_num = config->phase_a_gpio_num; + dev_config.ctrl_gpio_num = config->phase_b_gpio_num; + } + else if (config->flags == 2) + { + dev_config.pulse_gpio_num = config->phase_a_gpio_num, + dev_config.ctrl_gpio_num = config->phase_b_gpio_num, + dev_config.pos_mode = PCNT_COUNT_DIS; + dev_config.neg_mode = PCNT_COUNT_DEC ; + dev_config.lctrl_mode = PCNT_MODE_REVERSE; + dev_config.hctrl_mode = PCNT_MODE_KEEP; + } + else if (config->flags == 3) + { + dev_config.pulse_gpio_num = config->phase_a_gpio_num, + dev_config.ctrl_gpio_num = config->phase_b_gpio_num, + dev_config.pos_mode = PCNT_COUNT_DIS; + dev_config.neg_mode = PCNT_COUNT_DEC ; + dev_config.lctrl_mode = PCNT_MODE_KEEP; + dev_config.hctrl_mode = PCNT_MODE_REVERSE; + } + ROTARY_CHECK(pcnt_unit_config(&dev_config) == ESP_OK, "config pcnt channel 1 failed", err, ESP_FAIL); + + // PCNT pause and reset value + pcnt_counter_pause(ec11->pcnt_unit); + pcnt_counter_clear(ec11->pcnt_unit); + + // register interrupt handler in a thread-safe way + LOCK_ACQUIRE(); + if (!is_pcnt_isr_service_installed) + { + ROTARY_CHECK(pcnt_isr_service_install(0) == ESP_OK, "install isr service failed", err, ESP_FAIL); + // make sure pcnt isr service won't be installed more than one time + is_pcnt_isr_service_installed = true; + } + LOCK_RELEASE(); + + pcnt_isr_handler_add(ec11->pcnt_unit, ec11_pcnt_overflow_handler, ec11); + + pcnt_event_enable(ec11->pcnt_unit, PCNT_EVT_H_LIM); + pcnt_event_enable(ec11->pcnt_unit, PCNT_EVT_L_LIM); + + ec11->parent.del = ec11_del; + ec11->parent.start = ec11_start; + ec11->parent.stop = ec11_stop; + ec11->parent.set_glitch_filter = ec11_set_glitch_filter; + ec11->parent.get_counter_value = ec11_get_counter_value; + + *ret_encoder = &(ec11->parent); + return ESP_OK; +err: + if (ec11) + { + free(ec11); + } + return ret_code; +} + + +int ec11_pcnt_clear(pcnt_unit_t unit) +{ + return pcnt_counter_clear(unit); +} \ No newline at end of file diff --git a/dependencies.lock b/dependencies.lock new file mode 100644 index 0000000..356f9c1 --- /dev/null +++ b/dependencies.lock @@ -0,0 +1,9 @@ +dependencies: + idf: + component_hash: null + source: + type: idf + version: 4.4.4 +manifest_hash: dcf4d39b94252de130019eadceb989d72b0dbc26b552cfdcbb50f6da531d2b92 +target: esp32s3 +version: 1.0.0 diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt new file mode 100644 index 0000000..0b6de46 --- /dev/null +++ b/main/CMakeLists.txt @@ -0,0 +1,18 @@ +idf_component_register(SRCS "main.c" +"modbus-tcp.c" +"can_network.c" +"./stm32/ads1220.c" +"./stm32/bl0939.c" +"./stm32/capture.c" +"./stm32/comm.c" +"./stm32/depth.c" +"./stm32/fram.c" +"./stm32/flow.c" +"./stm32/utils.c" +"./stm32/config.c" +"./stm32/ModbusS.c" +"./stm32/ModbusM.c" +"./stm32/uart0_modbus_slave.c" +"wifi_softap.c" +INCLUDE_DIRS ".") + diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild new file mode 100644 index 0000000..2d127ee --- /dev/null +++ b/main/Kconfig.projbuild @@ -0,0 +1,45 @@ +menu "Example Configuration" + + config ESP_WIFI_SSID + string "WiFi SSID" + default "myssid" + help + SSID (network name) for the example to connect to. + + config ESP_WIFI_PASSWORD + string "WiFi Password" + default "mypassword" + help + WiFi password (WPA or WPA2) for the example to use. + + config ESP_MAXIMUM_RETRY + int "Maximum retry" + default 5 + help + Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent. + + choice ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD + prompt "WiFi Scan auth mode threshold" + default ESP_WIFI_AUTH_OPEN + help + The weakest authmode to accept in the scan mode. + + config ESP_WIFI_AUTH_OPEN + bool "OPEN" + config ESP_WIFI_AUTH_WEP + bool "WEP" + config ESP_WIFI_AUTH_WPA_PSK + bool "WPA PSK" + config ESP_WIFI_AUTH_WPA2_PSK + bool "WPA2 PSK" + config ESP_WIFI_AUTH_WPA_WPA2_PSK + bool "WPA/WPA2 PSK" + config ESP_WIFI_AUTH_WPA3_PSK + bool "WPA3 PSK" + config ESP_WIFI_AUTH_WPA2_WPA3_PSK + bool "WPA2/WPA3 PSK" + config ESP_WIFI_AUTH_WAPI_PSK + bool "WAPI PSK" + endchoice + +endmenu diff --git a/main/can_network.c b/main/can_network.c new file mode 100644 index 0000000..6abd0c6 --- /dev/null +++ b/main/can_network.c @@ -0,0 +1,257 @@ +/* TWAI Network Slave Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +/* + * The following example demonstrates a slave node in a TWAI network. The slave + * node is responsible for sending data messages to the master. The example will + * execute multiple iterations, with each iteration the slave node will do the + * following: + * 1) Start the TWAI driver + * 2) Listen for ping messages from master, and send ping response + * 3) Listen for start command from master + * 4) Send data messages to master and listen for stop command + * 5) Send stop response to master + * 6) Stop the TWAI driver + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "esp_err.h" +#include "esp_log.h" +#include "driver/twai.h" + +#include "can_network.h" + +/* --------------------- Definitions and static variables ------------------ */ +// Example Configuration +#define DATA_PERIOD_MS 50 +#define NO_OF_ITERS 3 +#define ITER_DELAY_MS 1000 +#define RX_TASK_PRIO 41 // Receiving task priority +#define TX_TASK_PRIO 42 // Sending task priority +#define CTRL_TSK_PRIO 10 // Control task priority +#define TX_GPIO_NUM 14 +#define RX_GPIO_NUM 21 +#define TAG "CAN" + +#define ID_MASTER_STOP_CMD 0x0A0 +#define ID_MASTER_START_CMD 0x0A1 +#define ID_MASTER_PING 0x0A2 +#define ID_SLAVE_STOP_RESP 0x0B0 +#define ID_SLAVE_DATA 0x0B1 +#define ID_SLAVE_PING_RESP 0x0B2 + +typedef enum +{ + TX_SEND_PING_RESP, + TX_SEND_DATA, + TX_SEND_STOP_RESP, + TX_TASK_EXIT, +} tx_task_action_t; + +typedef enum +{ + RX_RECEIVE_PING, + RX_RECEIVE_START_CMD, + RX_RECEIVE_STOP_CMD, + RX_TASK_EXIT, +} rx_task_action_t; + + + +static const twai_timing_config_t t_config = TWAI_TIMING_CONFIG_250KBITS(); +static const twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL(); +static const twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(TX_GPIO_NUM, RX_GPIO_NUM, TWAI_MODE_NORMAL); + +// static const twai_message_t ping_resp = {.identifier = ID_SLAVE_PING_RESP, .data_length_code = 0, .data = {0, 0, 0, 0, 0, 0, 0, 0}}; +// static const twai_message_t stop_resp = {.identifier = ID_SLAVE_STOP_RESP, .data_length_code = 0, .data = {0, 0, 0, 0, 0, 0, 0, 0}}; +// Data bytes of data message will be initialized in the transmit task +// twai_message_t data_message = {.identifier = ID_SLAVE_DATA, .data_length_code = 8, .data = {0, 0, 0, 0, 0, 0, 0, 0}}; + +// static QueueHandle_t tx_task_queue; +// static QueueHandle_t rx_task_queue; +// static SemaphoreHandle_t ctrl_task_sem; +// static SemaphoreHandle_t stop_data_sem; +// static SemaphoreHandle_t done_sem; + +/* --------------------------- Tasks and Functions -------------------------- */ + +static void twai_receive_task(void *arg) +{ + twai_message_t rx_msg; + int i; + while (1) + { + char msg_data_str[32]; + int index = 0; + esp_err_t err = twai_receive(&rx_msg, portMAX_DELAY); + if (err == ESP_OK) + { + for (i = 0; i < rx_msg.data_length_code; i++) + { + index += sprintf(&msg_data_str[i], "%02x ", rx_msg.data[i]); + } + ESP_LOGI(TAG, "recive msg id=%x,len=%d,data=[%s]", rx_msg.identifier, rx_msg.data_length_code, msg_data_str); + } + } +} + +// static void twai_transmit_task(void *arg) +// { +// while (1) +// { +// tx_task_action_t action; +// xQueueReceive(tx_task_queue, &action, portMAX_DELAY); + +// if (action == TX_SEND_PING_RESP) +// { +// // Transmit ping response to master +// twai_transmit(&ping_resp, portMAX_DELAY); +// ESP_LOGI(EXAMPLE_TAG, "Transmitted ping response"); +// xSemaphoreGive(ctrl_task_sem); +// } +// else if (action == TX_SEND_DATA) +// { +// // Transmit data messages until stop command is received +// ESP_LOGI(EXAMPLE_TAG, "Start transmitting data"); +// while (1) +// { +// // FreeRTOS tick count used to simulate sensor data +// uint32_t sensor_data = xTaskGetTickCount(); +// for (int i = 0; i < 4; i++) +// { +// data_message.data[i] = (sensor_data >> (i * 8)) & 0xFF; +// } +// twai_transmit(&data_message, portMAX_DELAY); +// ESP_LOGI(EXAMPLE_TAG, "Transmitted data value %d", sensor_data); +// vTaskDelay(pdMS_TO_TICKS(DATA_PERIOD_MS)); +// if (xSemaphoreTake(stop_data_sem, 0) == pdTRUE) +// { +// break; +// } +// } +// } +// else if (action == TX_SEND_STOP_RESP) +// { +// // Transmit stop response to master +// twai_transmit(&stop_resp, portMAX_DELAY); +// ESP_LOGI(EXAMPLE_TAG, "Transmitted stop response"); +// xSemaphoreGive(ctrl_task_sem); +// } +// else if (action == TX_TASK_EXIT) +// { +// break; +// } +// } +// vTaskDelete(NULL); +// } + +// static void twai_control_task(void *arg) +// { +// xSemaphoreTake(ctrl_task_sem, portMAX_DELAY); +// tx_task_action_t tx_action; +// rx_task_action_t rx_action; + +// for (int iter = 0; iter < NO_OF_ITERS; iter++) +// { +// ESP_ERROR_CHECK(twai_start()); +// ESP_LOGI(EXAMPLE_TAG, "Driver started"); + +// // Listen of pings from master +// rx_action = RX_RECEIVE_PING; +// xQueueSend(rx_task_queue, &rx_action, portMAX_DELAY); +// xSemaphoreTake(ctrl_task_sem, portMAX_DELAY); + +// // Send ping response +// tx_action = TX_SEND_PING_RESP; +// xQueueSend(tx_task_queue, &tx_action, portMAX_DELAY); +// xSemaphoreTake(ctrl_task_sem, portMAX_DELAY); + +// // Listen for start command +// rx_action = RX_RECEIVE_START_CMD; +// xQueueSend(rx_task_queue, &rx_action, portMAX_DELAY); +// xSemaphoreTake(ctrl_task_sem, portMAX_DELAY); + +// // Start sending data messages and listen for stop command +// tx_action = TX_SEND_DATA; +// rx_action = RX_RECEIVE_STOP_CMD; +// xQueueSend(tx_task_queue, &tx_action, portMAX_DELAY); +// xQueueSend(rx_task_queue, &rx_action, portMAX_DELAY); +// xSemaphoreTake(ctrl_task_sem, portMAX_DELAY); + +// // Send stop response +// tx_action = TX_SEND_STOP_RESP; +// xQueueSend(tx_task_queue, &tx_action, portMAX_DELAY); +// xSemaphoreTake(ctrl_task_sem, portMAX_DELAY); + +// // Wait for bus to become free +// twai_status_info_t status_info; +// twai_get_status_info(&status_info); +// while (status_info.msgs_to_tx > 0) +// { +// vTaskDelay(pdMS_TO_TICKS(100)); +// twai_get_status_info(&status_info); +// } + +// ESP_ERROR_CHECK(twai_stop()); +// ESP_LOGI(EXAMPLE_TAG, "Driver stopped"); +// vTaskDelay(pdMS_TO_TICKS(ITER_DELAY_MS)); +// } + +// // Stop TX and RX tasks +// tx_action = TX_TASK_EXIT; +// rx_action = RX_TASK_EXIT; +// xQueueSend(tx_task_queue, &tx_action, portMAX_DELAY); +// xQueueSend(rx_task_queue, &rx_action, portMAX_DELAY); + +// // Delete Control task +// xSemaphoreGive(done_sem); +// vTaskDelete(NULL); +// } + + +void can_init(void) +{ + // Add short delay to allow master it to initialize first + + // Create semaphores and tasks + // tx_task_queue = xQueueCreate(1, sizeof(tx_task_action_t)); + // rx_task_queue = xQueueCreate(1, sizeof(rx_task_action_t)); + // ctrl_task_sem = xSemaphoreCreateBinary(); + // stop_data_sem = xSemaphoreCreateBinary();; + // done_sem = xSemaphoreCreateBinary();; + ESP_ERROR_CHECK(twai_driver_install(&g_config, &t_config, &f_config)); + ESP_LOGI(TAG, "Driver installed"); + + xTaskCreatePinnedToCore(twai_receive_task, "CAN_rx", 1024, NULL, RX_TASK_PRIO, NULL, tskNO_AFFINITY); + twai_start(); + // xTaskCreatePinnedToCore(twai_transmit_task, "TWAI_tx", 4096, NULL, TX_TASK_PRIO, NULL, tskNO_AFFINITY); + // xTaskCreatePinnedToCore(twai_control_task, "TWAI_ctrl", 4096, NULL, CTRL_TSK_PRIO, NULL, tskNO_AFFINITY); + + // Install TWAI driver, trigger tasks to start + // ESP_ERROR_CHECK(twai_driver_install(&g_config, &t_config, &f_config)); + + // xSemaphoreGive(ctrl_task_sem); // Start Control task + // xSemaphoreTake(done_sem, portMAX_DELAY); // Wait for tasks to complete + + // //Uninstall TWAI driver + // ESP_ERROR_CHECK(twai_driver_uninstall()); + // ESP_LOGI(EXAMPLE_TAG, "Driver uninstalled"); + + // //Cleanup + // vSemaphoreDelete(ctrl_task_sem); + // vSemaphoreDelete(stop_data_sem); + // vSemaphoreDelete(done_sem); + // vQueueDelete(tx_task_queue); + // vQueueDelete(rx_task_queue); +} diff --git a/main/can_network.h b/main/can_network.h new file mode 100644 index 0000000..0b90067 --- /dev/null +++ b/main/can_network.h @@ -0,0 +1,19 @@ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __CAN_NETWORK_H +#define __CAN_NETWORK_H + +#ifdef __cplusplus +extern "C" { +#endif + + + +void can_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __HELLOWERLOD_H */ + +/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/ diff --git a/main/component.mk b/main/component.mk new file mode 100644 index 0000000..0adf456 --- /dev/null +++ b/main/component.mk @@ -0,0 +1,8 @@ +# +# Main component makefile. +# +# This Makefile can be left empty. By default, it will take the sources in the +# src/ directory, compile them and link them into lib(subdirectory_name).a +# in the build directory. This behaviour is entirely configurable, +# please read the ESP-IDF documents if you need to do this. +# diff --git a/main/main.c b/main/main.c new file mode 100644 index 0000000..9665c67 --- /dev/null +++ b/main/main.c @@ -0,0 +1,108 @@ +/* WiFi station Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "esp_system.h" +#include "esp_wifi.h" +#include "esp_event.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "lwip/err.h" +#include "lwip/sys.h" +#include +#include "driver/ledc.h" +#include "esp_err.h" +#include "can_network.h" +#include "freertos/queue.h" +#include "esp_check.h" +#include "soc/rtc.h" +#include "driver/mcpwm.h" + +/* The examples use WiFi configuration that you can set via project configuration menu + + If you'd rather not, just change the below entries to strings with + the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" +*/ +#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID +#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD +#define EXAMPLE_ESP_MAXIMUM_RETRY CONFIG_ESP_MAXIMUM_RETRY + +#if CONFIG_ESP_WIFI_AUTH_OPEN +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN +#elif CONFIG_ESP_WIFI_AUTH_WEP +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP +#elif CONFIG_ESP_WIFI_AUTH_WPA_PSK +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK +#elif CONFIG_ESP_WIFI_AUTH_WPA2_PSK +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK +#elif CONFIG_ESP_WIFI_AUTH_WPA_WPA2_PSK +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK +#elif CONFIG_ESP_WIFI_AUTH_WPA3_PSK +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK +#elif CONFIG_ESP_WIFI_AUTH_WPA2_WPA3_PSK +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK +#elif CONFIG_ESP_WIFI_AUTH_WAPI_PSK +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK +#endif + +/* FreeRTOS event group to signal when we are connected*/ +static EventGroupHandle_t s_wifi_event_group; + +/* The event group allows multiple bits for each event, but we only care about two events: + * - we are connected to the AP with an IP + * - we failed to connect after the maximum amount of retries */ +#define WIFI_CONNECTED_BIT BIT0 +#define WIFI_FAIL_BIT BIT1 + +static const char *TAG = "main"; + +static int s_retry_num = 0; + +extern void wifi_init_softap(void); + +void ads1220_init(void); + +extern void can_init(void); +extern void FLOW_init(); +extern void DEPTH_init(); +extern void BL0939_init(void); +extern void ads1220_task_start(void); +extern void ModBusTCPSlave_init(void); +extern esp_err_t i2c_master_init(void); +extern void config_load(void); +extern void uart0_modbus_slave_init(void); +uint32_t rtc_clk_apb_freq; + +void app_main(void) +{ + //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); + ESP_ERROR_CHECK(i2c_master_init()); + config_load(); + ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); + rtc_clk_apb_freq = rtc_clk_apb_freq_get(); + ESP_LOGI(TAG, "rtc_clk_apb_freq=%d", rtc_clk_apb_freq); + wifi_init_softap(); + // wifi_init_sta(); + // can_init(); + + ModBusTCPSlave_init(); + ads1220_task_start(); // test succeed + BL0939_init(); // test succeed + DEPTH_init(); + FLOW_init(); + uart0_modbus_slave_init(); +} diff --git a/main/modbus-tcp.c b/main/modbus-tcp.c new file mode 100644 index 0000000..f0b7334 --- /dev/null +++ b/main/modbus-tcp.c @@ -0,0 +1,138 @@ + +/* Includes ------------------------------------------------------------------*/ +#include +#include + +#include "lwip/ip_addr.h" +#include "lwip/tcp.h" +#include "lwip/err.h" +#include "lwip/opt.h" +#include "lwip/sockets.h" +#include "stm32/ModbusS.h" +// #include "log.h" + +#define LOG_TAG "[mb_tcp_sr]: " +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +// static err_t ModBusSlave_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); +// static err_t ModBusSlave_accept(void *arg, struct tcp_pcb *pcb, err_t err); +// static void ModBusSlave_conn_err(void *arg, err_t err); +// static err_t ModBusSlave_poll(void *arg, struct tcp_pcb *pcb); +/* Private functions ---------------------------------------------------------*/ +/** + * @brief Called when a data is received on the telnet connection + * @param arg the user argument + * @param pcb the tcp_pcb that has received the data + * @param p the packet buffer + * @param err the error value linked with the received data + * @retval error value + */ +int ModBusTcpMonitor; +static err_t ModBusSlave_recv(void *arg, struct tcp_pcb *newpcb, struct pbuf *p, err_t err) { + /* We perform here any necessary processing on the pbuf */ + if (p != NULL) { + uint8_t *txbuf; + uint8_t *rxbuf; + int txlen, rxlen; + /* We call this function to tell the LwIp that we have processed the data */ + /* This lets the stack advertise a larger window, so more data can be received*/ + tcp_recved(newpcb, p->tot_len); + rxbuf = (uint8_t *)p->payload; + rxlen = p->len; + if (rxlen < 6) { + pbuf_free(p); + return tcp_close(newpcb); + } + txbuf = (uint8_t *)mem_malloc(1024 + 16); + if (txbuf == NULL) { + return tcp_close(newpcb); + } + ModBusTcpMonitor = 0; + txlen = ModbusSlaveProcess(&txbuf[6], &rxbuf[6], (rxlen - 6), 0); //以前有 2023年4月24日14:39:11 + // log_printf(LINFO, LOG_TAG "[%s] ModbusSlaveProcess (ret=%d)", __FUNCTION__, txlen); + if (txlen > 0) { + int i; + for (i = 0; i < 4; i++) { + txbuf[i] = rxbuf[i]; + } + txbuf[4] = (uint8_t)(txlen >> 8); + txbuf[5] = (uint8_t)(txlen & 0xff); + tcp_write(newpcb, txbuf, txlen + 6, 1); + ModBusTcpMonitor = 0; + } + mem_free(txbuf); + /* End of processing, we free the pbuf */ + pbuf_free(p); + } else if (err == ERR_OK) { + /* When the pbuf is NULL and the err is ERR_OK, the remote end is closing the connection. */ + /* We free the allocated memory and we close the connection */ + // log_printf(LWARN, LOG_TAG "remote end is closing the connection\n"); + tcp_err(newpcb, NULL); + tcp_recv(newpcb, NULL); + tcp_poll(newpcb, NULL, 120); // 60 second timeout + // return tcp_close(newpcb); + err_t err_p = tcp_close(newpcb); + if (ERR_OK != err_p) { + // log_printf(LERROR, LOG_TAG "close error. err:%d\n", err_p); + } + return err_p; + } + return ERR_OK; +} +/** + * @brief This function is called when an error occurs on the connection + * @param arg + * @parm err + * @retval None + */ +static void ModBusSlave_conn_err(void *arg, err_t err) { + // log_printf(LERROR, LOG_TAG "connection error, err:%d\n", err); +} +static err_t ModBusSlave_poll(void *arg, struct tcp_pcb *newpcb) { + if (newpcb) { + // log_printf(LERROR, LOG_TAG "close pcb\n"); + tcp_close(newpcb); + newpcb = NULL; + } + return ERR_OK; +} +/** + * @brief This function when the Telnet connection is established + * @param arg user supplied argument + * @param pcb the tcp_pcb which accepted the connection + * @param err error value + * @retval ERR_OK + */ +static err_t ModBusSlave_accept(void *arg, struct tcp_pcb *pcb, err_t err) { + /* Tell LwIP to associate this structure with this connection. */ + // tcp_arg(pcb, mem_calloc(sizeof(struct name), 1)); + /* Configure LwIP to use our call back functions. */ + tcp_err(pcb, ModBusSlave_conn_err); + tcp_recv(pcb, ModBusSlave_recv); + tcp_poll(pcb, ModBusSlave_poll, 120); // 60 second timeout + /* Send out the first message */ + // tcp_write(pcb, GREETING, strlen(GREETING), 1); + return ERR_OK; +} +/** + * @brief Initialize the hello application + * @param None + * @retval None + */ +void ModBusTCPSlave_init(void) { + struct tcp_pcb *pcb; + /* Create a new TCP control block */ + pcb = tcp_new(); + /* Assign to the new pcb a local IP address and a port number */ + /* Using IP_ADDR_ANY allow the pcb to be used by any local interface */ + tcp_bind(pcb, IP_ADDR_ANY, 502); + /* Set the connection to the LISTEN state */ + pcb = tcp_listen(pcb); + /* Specify the function to be called when a connection is established */ + tcp_accept(pcb, ModBusSlave_accept); + // LSAPI_Log_Debug("ModBus Tcp server listen port:%d\n", 502); +} +/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/ diff --git a/main/modbus-tcp.h b/main/modbus-tcp.h new file mode 100644 index 0000000..d8b4e2e --- /dev/null +++ b/main/modbus-tcp.h @@ -0,0 +1,27 @@ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __HELLOWERLOD_H +#define __HELLOWERLOD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ + +/** @defgroup helloworld_Exported_Functions + * @{ + */ + +void HelloWorld_init(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __HELLOWERLOD_H */ + +/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/ diff --git a/main/stm32/ModbusM.c b/main/stm32/ModbusM.c new file mode 100644 index 0000000..4727397 --- /dev/null +++ b/main/stm32/ModbusM.c @@ -0,0 +1,680 @@ +#include +#include +#include "ModbusM.h" +#include "ModbusS.h" +#include "config.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "esp_err.h" +#include "uart.h" +#include "driver/uart.h" + +#define ZB_CHANNEL 1 + +extern uint16_t gWordVar[]; +//uint16_t g_tmp[100]; +device_t zb_device[ZB_CHANNEL]; + +send_t zb_send[16]; + +#define GetTicks xTaskGetTickCount +#define UART1_TXBUF_SIZE 256 + +int zbapi_send_write(device_t *device, send_t *sender); +int zbapi_send_req(device_t *device); +int max(int x, int y) +{ + if (x > y) + return x; + else + return y; +} + +//static float pow_user(float x, float y) +//{ +// int i; +// float tmp = 1; +// for (i = 0; i < y; i++) +// { +// tmp = tmp * x; +// } +// return tmp; +//} +uint16_t bin2bcd(uint16_t bin) +{ + uint16_t bcd; + uint8_t buf[4]; + if (bin > 9999) + { + bin = 9999; + } + buf[0] = bin % 10; + bin /= 10; + buf[1] = bin % 10; + bin /= 10; + buf[2] = bin % 10; + buf[3] = bin / 10; + bcd = buf[0] | (buf[1] << 4) | (buf[2] << 8) | (buf[3] << 12); + return bcd; +} +int min(int x, int y) +{ + if (x < y) + return x; + else + return y; +} +// ��������sn ֵ +uint8_t get_new_sn(int device_id) +{ + int i; + int sn = 0; + for (i = 0; i < 16; i++) + { + if (zb_send[i].device_id == device_id) + { + sn = max(zb_send[i].sn, sn); + } + } + return sn + 1; +} + +// �����豸��Сsn��Ӧ���±� +int device_get_send(int device_id) +{ + int i; + int sn = 255; + int min_index = -1; + for (i = 0; i < 16; i++) + { + if (zb_send[i].device_id == device_id) + { + if (zb_send[i].sn < sn) + { + sn = zb_send[i].sn; + min_index = i; + } + } + } + return min_index; +} +void on_in_pack_error(device_t *device) +{ + if (device->in_err_cnt[device->in_index] < device->in->max_err_cnt) + { + if (++device->in_err_cnt[device->in_index] >= device->in->max_err_cnt) + { + const packet_t *in_pack = device->in->packets + device->in_index; + int i; + for (i = 0; i < in_pack->length; i++) + { + uint32_t reg_addr = in_pack->local_addr + i; + if (reg_addr < gWORD_SIZE) + { + gWordVar[reg_addr] = 0; + } + } + if (device->protocol == 255) + { + if (in_pack->slave > 0 && in_pack->slave <= 10) + { + int i; + for (i = 0; i < 10; i++) + { + gWordVar[in_pack->local_addr] = 0; + } + } + if (in_pack->slave == 0) + { + gWordVar[64 + 10] = 0; + } + } + // on_data_error(device); + } + } +} +extern int page; +void modbus_master_poll(int n) +{ + uint32_t now = GetTicks(); + // printf("status == %d\n",zb_device[n].status); + if (zb_device[n].status == 0) // 空闲状态 + { + if (zb_device[n].out_pending > 0) ////如果有发送请求先处理发送 + { + // printf("out_pending > 0\n"); + int send_index = device_get_send(n); + if (send_index >= 0) + { + if (now >= zb_send[send_index].next_try_time) + { + zb_device[n].out_index = send_index; + zb_device[n].send_req_time = now; + zbapi_send_write(&zb_device[n], &zb_send[send_index]); + zb_device[n].status = 0x10; + return; + } + } + else + { + zb_device[n].out_pending = 0; + } + } + if (now >= zb_device[n].next_scan_time) + { + // printf("now >= zb_device[%d]\n",n); + zb_device[n].send_req_time = now; + zbapi_send_req(&zb_device[n]); + zb_device[n].status = 2; + } + } + else if (zb_device[n].status == 1 || zb_device[n].status == 2) // + { + + if ((now - zb_device[n].send_req_time) > zb_device[n].in->time_out * 100) + { + zb_device[n].status = 0; //��ʱ + zb_device[n].ErrCode = 0x01; + zb_device[n].ErrCount++; + on_in_pack_error(&zb_device[n]); + if ((++zb_device[n].try_times >= zb_device[n].in->max_try_times) || + (zb_device[n].in_err_cnt[zb_device[n].in_index] >= zb_device[n].in->max_err_cnt)) + { + if (++zb_device[n].in_index >= zb_device[n].in->packet_cnt) + { + zb_device[n].in_index = 0; + zb_device[n].group_start_time = now; + } + //zb_device[n].next_scan_time = zb_device[n].group_start_time + zb_device[n].in->scan_rate*10; + zb_device[n].try_times = 0; + } + zb_device[n].next_scan_time = zb_device[n].group_start_time + zb_device[n].in->scan_rate * 10; + zb_device[n].status = 0; + } + } + else if (zb_device[n].status == 3) // ���յ��ظ� + { + if (++zb_device[n].in_index >= zb_device[n].in->packet_cnt) + { + zb_device[n].in_index = 0; + zb_device[n].group_start_time = now; //+ zb_device[n].in->scan_rate*10; + } + zb_device[n].next_scan_time = zb_device[n].group_start_time + zb_device[n].in->scan_rate * 10; + zb_device[n].status = 255; + zb_device[n].try_times = 0; + } + else if (zb_device[n].status == 0x10) // �������������ѷ����ȴ���Ӧ���߳�ʱ + { + int index = zb_device[n].out_index; + if ((now - zb_device[n].send_req_time) > zb_device[n].in->time_out * 100) + { + zb_device[n].status = 0; //��ʱ + zb_device[n].ErrCode = 0x01; + zb_device[n].ErrCount++; + if (++zb_send[index].try_times >= zb_device[n].out->max_try_times) //����������Դ���������ʧ�� + { + zb_send[index].device_id = 0xff; + } + else + { + zb_send[index].next_try_time = now + zb_device[n].out->try_space * 100; + } + zb_device[n].status = 0; + zb_device[n].try_times = 0; + } + } + else if (zb_device[n].status == 0x11) // ���յ���������ȷ�� + { + zb_send[zb_device[n].out_index].device_id = 0xff; + zb_device[n].status = 255; + zb_device[n].try_times = 0; + } + else + { + if ((now - zb_device[n].revice_resp_time) >= (zb_device[n].in->scan_space)) + { + zb_device[n].status = 0; + zb_device[n].try_times = 0; + } + } +} +// �����ཻ +int intersection(int x0, int x1, int y0, int y1, int *s, int *e) +{ + int ret = 0; + if ((y0 >= x0) && (y0 < x1)) + { + *s = y0; + *e = min(x1, y1); + ret = 1; + } + else if ((y1 > x0) && (y1 <= x1)) + { + *s = y1 - 1; + *e = min(x1, y1); + ret = 1; + } + else if ((x0 >= y0) && (x0 < y1)) + { + *s = x0; + *e = min(y1, x1); + ret = 1; + } + else if ((x1 > y0) && (x1 <= y1)) + { + *s = x1 - 1; + *e = min(y1, x1); + ret = 1; + } + return ret; +} +int zb_ModBusWordWriteHook(uint16_t addr, uint16_t length) +{ + int i, j; + int ret = 0; + for (i = 0; i < ZB_CHANNEL; i++) + { + if (zb_device[i].out == NULL) + { + continue; + } + for (j = 0; j < zb_device[i].out->packet_cnt; j++) + { + int s1, e1; + int s2, e2; + int s, e; + int n; + s1 = zb_device[i].out->packets[j].local_addr; + e1 = zb_device[i].out->packets[j].local_addr + zb_device[i].out->packets[j].length; + s2 = addr; + e2 = addr + length; + if (intersection(s1, e1, s2, e2, &s, &e)) + //if((s2 >= s1 && s2 < e1) || (e2 >= s1 && s2 < e1)) + { + for (n = 0; n < 16; n++) + { + if (zb_send[n].device_id == 0xff) + { + zb_send[n].sn = get_new_sn(i); + zb_send[n].device_id = i; + zb_send[n].packet_index = j; + zb_send[n].address = s; + zb_send[n].length = e - s; + zb_send[n].next_try_time = 0; + zb_send[n].try_times = 0; + zb_device[i].out_pending++; + ret = 1; + break; + } + } + } + } + } + return ret; +} + +//extern uint8_t Uart3TxBuf[]; +//#define txbuf Uart3TxBuf + +int zbapi_send_req(device_t *device) +{ + if (device->protocol == 255) + { + device->txbuf[0] = device->in->packets[device->in_index].slave; + device->txbuf[1] = 0x5a; + device->txbuf[2] = 0xaa; + device->write(device->txbuf, 3); + } + else + { + uint16_t crc; + device->txbuf[0] = device->in->packets[device->in_index].slave; + device->txbuf[1] = device->in->packets[device->in_index].funcode; + device->txbuf[2] = device->in->packets[device->in_index].address >> 8; + device->txbuf[3] = device->in->packets[device->in_index].address & 0xff; + device->txbuf[4] = device->in->packets[device->in_index].length >> 8; + device->txbuf[5] = device->in->packets[device->in_index].length & 0xff; + crc = crc16(device->txbuf, 6); + device->txbuf[6] = crc >> 8; + device->txbuf[7] = crc & 0xff; + device->write(device->txbuf, 8); + } + return 0; +} +int zbapi_send_write(device_t *device, send_t *sender) +{ + { + int n = 0; + uint16_t crc; + const packet_t *out_pack = &device->out->packets[sender->packet_index]; + if (sender->length == 0) + { + return 0; + } + device->txbuf[0] = device->out->packets[sender->packet_index].slave; + if (sender->length > 1) + { + int addr = out_pack->address + (sender->address - out_pack->local_addr); + int i; + int len; + device->txbuf[1] = 0x10; + device->txbuf[2] = addr >> 8; + device->txbuf[3] = addr & 0xff; + device->txbuf[4] = sender->length >> 8; + device->txbuf[5] = sender->length & 0xff; + device->txbuf[6] = (sender->length * 2) & 0xff; + len = 7; + for (i = 0; i < sender->length; i++) + { + uint16_t reg16 = gWordVar[sender->address + i]; + if (out_pack->device_type == 5) + { + reg16 = bin2bcd(reg16); + } + device->txbuf[len++] = reg16 >> 8; + device->txbuf[len++] = reg16 & 0xff; + } + crc = crc16(device->txbuf, len); + device->txbuf[len++] = crc >> 8; + device->txbuf[len++] = crc & 0xff; + n += len; + } + else + { + int addr = out_pack->address + (sender->address - out_pack->local_addr); + uint16_t reg16 = gWordVar[sender->address]; + device->txbuf[1] = 0x06; + device->txbuf[2] = addr >> 8; + device->txbuf[3] = addr & 0xff; + if (out_pack->device_type == 5) + { + reg16 = bin2bcd(reg16); + } + if ((device->protocol == 5) || (device->protocol == 6)) + { + reg16 *= 10; + } + device->txbuf[4] = reg16 >> 8; + device->txbuf[5] = reg16 & 0xff; + crc = crc16(device->txbuf, 6); + device->txbuf[6] = crc >> 8; + device->txbuf[7] = crc & 0xff; + n += 8; + } + if (device->write != NULL) + { + device->write(device->txbuf, n); + } + } + return 1; +} + +extern uint16_t Is_SetFromScreen; + +int modbus_master_on_revice(int ch, uint8_t *rxbuf, int length) +{ + int i; +// uint8_t src_addr[8]; + if (length < 4) + { + return -1; + } + i = ch; + //for(i=0; ipackets[index].slave == rxbuf[0]) && + zb_device[i].in->packets[index].funcode == rxbuf[1]) + { + uint16_t crcChk = crc16(rxbuf, length - 2); + uint16_t crcData = (rxbuf[length - 2] << 8) | rxbuf[length - 1]; + if (crcData != crcChk) + { + zb_device[i].ErrCode = 2; //CRC error + zb_device[i].ErrCount++; + } + else if (rxbuf[0] != zb_device[i].in->packets[index].slave) + { + zb_device[i].ErrCode = 3; //ADD error + zb_device[i].ErrCount++; + } + else if (rxbuf[1] != zb_device[i].in->packets[index].funcode) + { + zb_device[i].ErrCode = 4; //Fun err; + zb_device[i].ErrCount++; + } + else if (rxbuf[2] != (zb_device[i].in->packets[index].length * 2)) + { + zb_device[i].ErrCode = 1; //byte miss + zb_device[i].ErrCount++; + } + else + { + int n = 0; + // uint32_t reg32; + uint16_t addr = zb_device[i].in->packets[index].local_addr; + uint8_t len = rxbuf[2] / 2; + if (addr >= gWORD_SIZE) + { + zb_device[i].ErrCode = 5; //regaddr err; + goto done; + } + zb_device[i].ErrCode = 0; + switch (zb_device[i].in->packets[index].device_type) + { + default: + + for (n = 0; n < len; n++) + { + if (addr + n < gWORD_SIZE) + { + gWordVar[addr + n] = (rxbuf[3 + n * 2] << 8) | (rxbuf[3 + n * 2 + 1]); + } + else + { + break; + } + } + break; + } + zb_device[i].in_err_cnt[zb_device[i].in_index] = 0; + } + done: + zb_device[i].status = 3; + } + } + } + else if (zb_device[i].status == 0x10) + { + zb_device[i].revice_resp_time = GetTicks(); + //if(memcmp(src_addr,((zb_dev_t*)zb_device[i].ext)->zb_addr,8) == 0) + { + zb_device[i].status = 0x11; + } + } + } + return 0; +} + +//int meter_count = 4; + +//#define meter_count meter_cfg.count +//const int reg_offset[] = {0, 2, 3, 4, 1}; + +//static char input_buf[1][414]; +//static char output_buf[1][212]; +static char in_err_cnt_buf[1][25]; +struct input{ + input_t input; + packet_t packet[5]; +}; +struct output{ + output_t output; + packet_t packet[5]; +}; +struct input input1; +struct output output1; + +extern int uart1_tx_start(uint8_t *data, int length); +extern uint8_t uart1_txbuf[]; +//static uint8_t uart_txbuf[ 256 ]; +//static uint8_t uart_rxbuf[ 256 ]; + +static int uart_send(uint8_t *buf, int len) +{ + // uart1_tx_start(buf, len); + uart_write_bytes(RS485_UART_PORT_NUM, buf, len); + //HAL_UART_Transmit_DMA(&huart1,buf,len); + return len; +} +int ModbusM_init(void) +{ + int i = 0; +// int meter_count[4] = {0, 0, 0, 0}; +// int size; +// char *p; + // int n; +// uint8_t *in_err_cnt; + + zb_device[0].txbuf = uart1_txbuf; + zb_device[0].txbuf_size = UART1_TXBUF_SIZE; + zb_device[0].write = uart_send; + + { + input_t *input; + output_t *output; + uint8_t *in_err_cnt; + + + // memset(input_buf[i], 0, sizeof(input_buf[i])); + // memset(output_buf[i], 0, sizeof(output_buf[i])); + // memset(in_err_cnt_buf[i], 0, sizeof(in_err_cnt_buf[i])); + + output = &output1.output; + input = &input1.input; + in_err_cnt = (uint8_t *)in_err_cnt_buf[i]; + + zb_device[i].in_err_cnt = in_err_cnt; + + input->scan_rate = 10; //*10ms + input->time_out = 10; //*100ms + input->max_try_times = 2; + input->scan_space = 50; //*10ms + input->max_err_cnt = 30; + + output->max_try_times = 3; + output->try_space = 40; + + zb_device[i].channl = i; + zb_device[i].next_scan_time = 0; + zb_device[i].status = 0; + zb_device[i].try_times = 0; + zb_device[i].in_index = 0; + zb_device[i].out_pending = 0; + zb_device[i].in_err_cnt = in_err_cnt; + zb_device[i].in = input; + zb_device[i].out = output; + // zb_device[i].ext = &serial_port_cfg[i]; + } + { + device_t *dev = (device_t *)&zb_device; + dev->in->packets[dev->in->packet_cnt].slave = 1; + dev->in->packets[dev->in->packet_cnt].funcode = 3; + dev->in->packets[dev->in->packet_cnt].address = 0; + dev->in->packets[dev->in->packet_cnt].length = 3; + dev->in->packets[dev->in->packet_cnt].device_type = 0; + dev->in->packets[dev->in->packet_cnt].local_addr = TILT_SENSER_ADDR; + dev->in->packets[dev->in->packet_cnt].ch = 0; + dev->in->packet_cnt++; + + dev->out->packets[dev->out->packet_cnt].slave = 1; + dev->out->packets[dev->out->packet_cnt].funcode = 6; + dev->out->packets[dev->out->packet_cnt].local_addr = 10; + dev->out->packets[dev->out->packet_cnt].length = 1; + dev->out->packets[dev->out->packet_cnt].address = 5; + dev->out->packets[dev->out->packet_cnt].device_type = 0; + dev->in->packets[dev->in->packet_cnt].ch = 0; + dev->out->packet_cnt++; + } + return 0; +} +extern int meter_type; + +void ModbusM_reinit(void) +{ + int i; + for (i = 64; i < 64 + 128; i++) + { + gWordVar[i] = 0; + } + ModbusM_init(); +} + +int fill_data(uint8_t *pData, uint16_t local_addr, uint8_t remote_offset, uint8_t length) +{ + uint16_t *pWordVar; + int i; + *pData++ = remote_offset; + *pData++ = length; + pWordVar = &gWordVar[local_addr]; + for (i = 0; i < length; i++) + { + *pData++ = *pWordVar >> 8; + *pData++ = *pWordVar & 0xff; + pWordVar++; + } + return i * 2 + 2; +} +int build_data(int dest_addr, const int *src_addr_map, int length) +{ + int i; + int change_cnt = 0; + for (i = 0; i < length; i++) + { + int src_addr = src_addr_map[i]; + if (dest_addr < gWORD_SIZE && src_addr >= 0 && src_addr < gWORD_SIZE) + { + if (gWordVar[dest_addr] != gWordVar[src_addr]) + { + gWordVar[dest_addr] = gWordVar[src_addr]; + change_cnt++; + } + } + else + { + return -1; + } + dest_addr++; + } + return change_cnt; +} +int copy_data(int dest_addr, int src_addr, int length) +{ + int i; + int change_cnt = 0; + for (i = 0; i < length; i++) + { + //int src_addr = src_addr_map[i]; + if (dest_addr < gWORD_SIZE && src_addr >= 0 && src_addr < gWORD_SIZE) + { + if (gWordVar[dest_addr] != gWordVar[src_addr]) + { + gWordVar[dest_addr] = gWordVar[src_addr]; + change_cnt++; + } + } + else + { + return -1; + } + dest_addr++; + src_addr++; + } + return change_cnt; +} diff --git a/main/stm32/ModbusM.h b/main/stm32/ModbusM.h new file mode 100644 index 0000000..a216e42 --- /dev/null +++ b/main/stm32/ModbusM.h @@ -0,0 +1,120 @@ +#ifndef _MODBUSM_H_ +#define _MODBUSM_H_ +#define uint8 unsigned char +#define uint16 unsigned short +#define uint32 unsigned int + +typedef struct _MODBUS_MASTRT_ +{ + uint8 Status; + uint8 ErrCode; + + uint8 Slave; + uint8 Function; + + uint8 PackId; + uint8 Length; + uint16 Address; + + uint16 *Data; + + uint32 txtime; + uint32 rxtime; + uint16 TxCont; + uint16 TimeOut; + uint16 CrcErr; + uint16 ByteMiss; + uint16 OtherErr; +}MODBUS_MASTERT_T; +typedef struct _MODBUS_READ_T_ +{ + uint8 SaveAdd; + uint8 Length; + uint16 RegAdd; + uint16 *pDat; +}MODBUS_READ_T; + + + +typedef struct _packet_ +{ + uint8_t device_type; + uint8_t slave; + uint8_t funcode; + uint8_t ch; + uint16_t length; + uint16_t address; + uint16_t local_addr; + uint16_t ext_flg; + const void* ext; +}packet_t; + +typedef struct _input_ +{ + uint8_t packet_cnt; + uint8_t max_try_times; + uint8_t time_out; + + uint16_t scan_rate; + uint16_t scan_space; + + uint8_t max_err_cnt; + uint8_t ch; + uint8_t rsv[2]; + packet_t packets[1]; +}input_t; + +typedef struct _output_ +{ + uint8_t packet_cnt; + uint8_t max_try_times; + uint8_t try_space; + uint8_t rsv; + packet_t packets[1]; +}output_t; + +typedef struct _device_ +{ + uint8_t channl; + uint8_t protocol; + uint8_t status; + uint8_t in_index; + + uint8_t try_times; + uint8_t out_pending; + uint8_t out_index; + uint8_t ErrCode; + + uint8_t continue_err; + uint8_t max_coutinue; + uint16_t ErrCount; + uint16_t PackId; + + uint32_t group_start_time; + uint32_t next_scan_time; + uint32_t send_req_time; + uint32_t revice_resp_time; + uint8_t *txbuf; + int txbuf_size; + int (*write)(uint8*, int); + uint8_t *in_err_cnt; + input_t *in; + output_t *out; + void *ext; +}device_t; + +typedef struct _send_ +{ + uint8_t device_id; + uint8_t sn; + uint8_t packet_index; + uint8_t try_times; + uint16_t address; + uint16_t length; + uint32_t next_try_time; +}send_t; +extern int ModbusM_init(void); +extern int ModbusMastertRx(MODBUS_MASTERT_T *m,uint8 *rxbuf, uint8 len); +extern void ModbusMastertPoll(MODBUS_MASTERT_T *m); +extern int zb_ModBusWordWriteHook(unsigned short addr, unsigned short length); +#endif diff --git a/main/stm32/ModbusS.c b/main/stm32/ModbusS.c new file mode 100644 index 0000000..d4fb4ab --- /dev/null +++ b/main/stm32/ModbusS.c @@ -0,0 +1,345 @@ +#include +#include "ModbusS.h" +#include "config.h" +#include +#include "driver/ledc.h" +#include "esp_err.h" +#include + + + +static const uint8_t auchCRCHi[] = +{ + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 +} ; +/* CRC??????*/ +static const uint8_t auchCRCLo[] = +{ + 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, + 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, + 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, + 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, + 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, + 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, + 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, + 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, + 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, + 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, + 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, + 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, + 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, + 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, + 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, + 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, + 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, + 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, + 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, + 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, + 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, + 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, + 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, + 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, + 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, + 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 +} ; + +uint16_t crc16(uint8_t *puchMsg, uint16_t usDataLen) +{ + uint8_t uchCRCHi = 0xFF ; /* ?CRC????? */ + uint8_t uchCRCLo = 0xFF ; /* ?CRC ????? */ + uint32_t uIndex ; /* CRC?????? */ + while (usDataLen--) /* ??????? */ + { + uIndex = uchCRCHi ^ *puchMsg++ ; /* ??CRC */ + uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ; + uchCRCLo = auchCRCLo[uIndex] ; + } + return (uchCRCHi << 8 | uchCRCLo) ; +}//uint16 crc16(uint8 *puchMsg, uint16 usDataLen) + + + +#pragma pack(0x10) +uint16_t gWordVar[gWORD_SIZE]; +uint8_t gBitVar[(gBIT_SIZE+7)/8]; +#pragma pack() + +int isBitHI(uint16_t Add) +{ + if(gBitVar[(Add)>>3] & (1<<((Add)&0x07))) + { + return 1; + } + else + { + return 0; + } +} + +void ModBusBitWriteHook(uint16_t addr, uint16_t length) +{ +} +extern void reset_depth(void); +uint16_t reboot_req ; +extern uint16_t last_pile_id; +extern int zb_ModBusWordWriteHook(uint16_t addr, uint16_t length); +void ModBusWordWriteHook(uint16_t addr, uint16_t length) +{ + + if(addr == RECORD_REG_ADDR && gWordVar[RECORD_REG_ADDR] == 0xffff){ + reset_depth(); + gWordVar[RECORD_REG_ADDR] = 0; + } + if(addr == DEPTH_RESET_ADDR && gWordVar[DEPTH_RESET_ADDR] == 0x5555){ + config_load(); + gWordVar[DEPTH_RESET_ADDR] = 0; + } + if(addr == DEPTH_RESET_ADDR && gWordVar[DEPTH_RESET_ADDR] == 0x55aa){ + gWordVar[RECORD_REG_ADDR] = 9999; //强制增加桩号 + reset_depth(); + gWordVar[DEPTH_RESET_ADDR] = 0; + } + if(addr == LAST_PILE_ID_ADDR){ + last_pile_id = gWordVar[LAST_PILE_ID_ADDR]; + } + else if(addr == FLOW_CONFIG_ADDR && gWordVar[FLOW_CONFIG_ADDR] == 0x55aa){ + save_flow_cfg(); + } + else if(addr == DEPTH_CONFIG_ADDR && gWordVar[DEPTH_CONFIG_ADDR] == 0x55aa){ + save_depth_cfg(); + } + else if(addr == CAL_4_20MA_ADDR && gWordVar[CAL_4_20MA_ADDR] == 0x55aa){ + save_cal_4_20ma(); + } + else if(addr == REBOOT_REW_ADDR ){ + if(gWordVar[REBOOT_REW_ADDR] == 0x55aa){ + reboot_req = 0x55aa; + } + else if(gWordVar[REBOOT_REW_ADDR] == 0x55ab){ + esp_restart(); + } + else if(gWordVar[REBOOT_REW_ADDR] == 0xaa55){ + restore_default(); + esp_restart(); + } + } + else{ + zb_ModBusWordWriteHook(addr,length); + } +} +extern volatile int modbus_save_flg; + +uint16_t modbus_addr = 1; +int ModbusSlaveProcess(uint8_t *txbuf, uint8_t *rxbuf, uint16_t rxLen, int is_crc) +{ + uint16_t crcData,crcChk; + uint8_t Offset,ByteAdd; + uint16_t ByteNumber; + uint16_t add; + uint16_t length; + int out_len = 0; + int i; + uint8_t *pDat; + uint16_t *pWordVar; + if(rxLen<4) + return 0; + if((rxbuf[0]==modbus_addr) || (rxbuf[0]==255)) + { + if(is_crc != 0) + { + crcData = rxbuf[rxLen-1]+(rxbuf[rxLen-2]<<8); + crcChk = crc16(rxbuf,rxLen-2); + if( crcData != crcChk) + { + return 0; + } + } + add = ((uint16_t)rxbuf[2]<<8)+ rxbuf[3]; + //if(Length != + length = (rxbuf[4]<<8) | rxbuf[5]; + + txbuf[0] = rxbuf[0]; + switch(rxbuf[1]) + { + case 0x01: //Read Coils + if((add+length) > gBIT_SIZE) + { + txbuf[1] = 0x81; + txbuf[2] = 0x02; //ILLEGAL DATA ADDRESS + out_len = 3; + break; + } + txbuf[1]=0x01; + ByteNumber = (length+7)/8; + txbuf[2]= ByteNumber; + ByteAdd = add>>3; //add/8 + Offset = add&0x07; //add%8 + for(i=0; i<(ByteNumber-1); i++) + { + txbuf[3+i] = gBitVar[ByteAdd+i]>>Offset; + txbuf[3+i] |= gBitVar[ByteAdd+i+1]<<(8-Offset); + } + txbuf[3+ByteNumber-1] = gBitVar[ByteAdd+ByteNumber-1]>>Offset; + txbuf[3+ByteNumber-1] &= 0xff>>Offset; + out_len = ByteNumber+3; + break; + case 0x03: + case 0x04: //Read Holding Registers + if((add+length) > gWORD_SIZE) + { + txbuf[1] = 0x80 + rxbuf[1]; + txbuf[2] = 0x02; //ILLEGAL DATA ADDRESS + out_len = 3;; + break; + } + if(length > 512) + { + length = 512; + } + if(rxbuf[1]==4) + { + add += 64; + } + txbuf[1]=rxbuf[1]; + ByteNumber = length*2; + txbuf[2]= ByteNumber&0xff; + pDat = &txbuf[3]; + pWordVar = (uint16_t *)&gWordVar[add]; + for(i=0; i>8; + *pDat++ = *pWordVar&0xff; + pWordVar++; + } + out_len = ByteNumber+3; + break; + case 0x05: //Write Single Coil + if(add >= gBIT_SIZE) + { + txbuf[1] = 0x85; + txbuf[2] = 0x02; //ILLEGAL DATA ADDRESS + out_len = 3; + break; + } + ByteAdd = add>>3; //same add/8 + Offset = add&0x07; //same add%8 + if(rxbuf[4] == 0) + { + clrBit(add); + } + else if(rxbuf[4] == 0xff) + { + setBit(add); + } + else + { + txbuf[1] = 0x85; + txbuf[2] = 0x03; //ILLEGAL DATA VALUE + out_len = 3; + break; + } + memcpy(txbuf,rxbuf,6); + ModBusBitWriteHook(add,1); + out_len = 6; + break; + case 0x06: //Write Single Register + if(add >= gWORD_SIZE) + { + txbuf[1] = 0x86; + txbuf[2] = 0x02; //ILLEGAL DATA ADDRESS + out_len = 3; + break; + } + gWordVar[add] = (rxbuf[4]<<8)+rxbuf[5]; + memcpy(txbuf,rxbuf,6); + ModBusWordWriteHook(add,1); + out_len = 6; + break; + case 0x0F: //Write Multiple Coil + if((add+length) > gBIT_SIZE) + { + txbuf[1] = 0x8F; + txbuf[2] = 0x02; //ILLEGAL DATA ADDRESS + out_len = 3; + } + + txbuf[1]=0x0F; + txbuf[2] = rxbuf[2]; + txbuf[3] = rxbuf[3]; + txbuf[4] = 0; + txbuf[5] = length&0xff; + pDat = rxbuf+7; + for(i=0; i>3)) & (1<<(i&0x07))) + setBit(i+add); + else + clrBit(i+add); + } + ModBusBitWriteHook(add,length); + out_len = 6; + break; + case 0x10: //Write Multiple registers + if((add+length) > gWORD_SIZE) + { + txbuf[1] = 0x90; + txbuf[2] = 0x02; //ILLEGAL DATA ADDRESS + crcChk = crc16(txbuf,3); + txbuf[3] = crcChk>>8; + txbuf[4] = crcChk; + out_len = 3; + } + txbuf[1]=0x10; + txbuf[2] = rxbuf[2]; + txbuf[3] = rxbuf[3]; + txbuf[4]= 0; + txbuf[5]= length&0xff; + pDat = rxbuf+7; + pWordVar = (uint16_t *)&gWordVar[add]; + { + for(i=0; i 0) + { + crcChk = crc16(txbuf,out_len); + txbuf[out_len++] = crcChk>>8; + txbuf[out_len++] = crcChk & 0xff; + } + } + return out_len; +} diff --git a/main/stm32/ModbusS.h b/main/stm32/ModbusS.h new file mode 100644 index 0000000..67dd57b --- /dev/null +++ b/main/stm32/ModbusS.h @@ -0,0 +1,74 @@ +#ifndef _MODBUS_H +#define _MODBUS_H +#include +//#define uint8_t unsigned char +//#define uint16_t unsigned short +//#define uint32 unsigned int + +#define setBit(Add) gBitVar[(Add)>>3] |= (1<<((Add)&0x07)) +#define clrBit(Add) gBitVar[(Add)>>3] &= ~(1<<((Add)&0x07)) +//#define ModBusTxData uart1_tx + +extern uint16_t crc16(uint8_t *puchMsg, uint16_t usDataLen); +extern int ModbusSlaveProcess(uint8_t *txbuf, uint8_t *rxbuf, uint16_t rxLen, int is_crc); + + + + +int isBitHI(uint16_t Add); +void xorBit(uint16_t Add); + +void WriteBit(uint16_t Add,uint8_t bit_value); +#define gBIT_SIZE 128 +#define gWORD_SIZE 512 +extern uint8_t gBitVar[(gBIT_SIZE+7)/8]; +extern uint16_t gWordVar[gWORD_SIZE]; +extern uint16_t modbus_addr; + +// #include "usart.h" +// #include "gpio.h" +// #include "main.h" +#define BUFFER_SIZE 2000 +extern uint8_t rx_buffer[256]; +extern uint8_t tx_buffer[256]; +extern uint16_t rx_buff_len; +// extern __IO uint8_t recv_end_flag; +extern uint8_t recv_end_flag; +extern void modbus_recv_mode(void); +extern void usart2_dma_recv_start(void); +extern void modbus_send(uint8_t *buf, uint8_t len); +// extern void save_flow_cfg(void); +extern int check_mastrt_recv(void); + +#endif + + +// #ifndef _MODBUS_H +// #define _MODBUS_H +// #include +// #define uint8_t unsigned char +// #define uint16_t unsigned short +// #define uint32 unsigned int + +// #define setBit(Add) gBitVar[(Add) >> 3] |= (1 << ((Add)&0x07)) +// #define clrBit(Add) gBitVar[(Add) >> 3] &= ~(1 << ((Add)&0x07)) +// //#define ModBusTxData uart1_tx + +// extern uint16_t crc16(uint8_t *puchMsg, uint16_t usDataLen); +// extern int ModbusSlaveProcess(uint8_t *txbuf, uint8_t *rxbuf, uint16_t rxLen, int is_crc); + + + +// int isBitHI(uint16_t Add); +// void xorBit(uint16_t Add); + +// void WriteBit(uint16_t Add, uint8_t bit_value); +// #define gBIT_SIZE 128 +// #define gWORD_SIZE 12288 +// extern uint8_t gBitVar[(gBIT_SIZE + 7) / 8]; +// extern uint16_t gWordVar[gWORD_SIZE]; + +// void modbus(void); +// void rs485_send(void *buf, uint16_t len); + +// #endif diff --git a/main/stm32/ads1220.c b/main/stm32/ads1220.c new file mode 100644 index 0000000..457a0b1 --- /dev/null +++ b/main/stm32/ads1220.c @@ -0,0 +1,516 @@ +#include "ads1220.h" +// #include "main.h" +#include "config.h" +#include "ModbusS.h" +#include "ModbusM.h" +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "driver/spi_master.h" +#include "driver/gpio.h" +#include "esp_log.h" +#include "freertos/queue.h" +#include "utils.h" +#include "config.h" +#include "driver/mcpwm.h" + +#define TAG "ADS1220" + +#define ADS1220_HOST SPI2_HOST + +#define SPI2_PIN_NUM_MISO 40 +#define SPI2_PIN_NUM_MOSI 41 +#define SPI2_PIN_NUM_CLK 37 +#define SPI2_PIN_NUM_CS 38 + +#define PIN_NUM_DC 9 +#define PIN_NUM_RST 4 +#define PIN_NUM_BCKL 5 + +// To speed up transfers, every SPI transfer sends a bunch of lines. This define specifies how many. More means more memory use, +// but less overhead for setting up / finishing transfers. Make sure 240 is dividable by this. +#define PARALLEL_LINES 16 +static spi_device_handle_t spi2; + +/*************************************************** + * + *ADS1220���� + *1.������ADS1220�������ӵ����Ŷ˿� + * + * + * + * + */ +/****************ADS1220���ź궨��*******************/ +#define ADS1220_nCS_HIGH() gpio_set_level(GPIO_NUM_38, 1) +#define ADS1220_nCS_LOW() gpio_set_level(GPIO_NUM_38, 0) + +/*****************************************************/ +#define ADS1220_CMD_WREG 0x40 // д�Ĵ������� +#define ADS1220_CMD_RREG 0x20 // ���Ĵ������� +#define ADS1220_CMD_RESET 0x06 // ��λ���� +#define ADS1220_CMD_START 0x08 // ��ʼת������ +#define ADS1220_CMD_POWERDOWN 0x02 // �͹��ĵ������� +#define ADS1220_CMD_RDATA 0x10 // ���������� + +#define Channal1 0x00 // ͨ��1 +#define Channal2 0x10 // ͨ��2 +#define Channal3 0x20 // ͨ��3 +#define Channal4 0x30 // ͨ��4 + +#define ADS1220_REG0 0x00 // �Ĵ��� 0 +#define ADS1220_REG1 0x01 // �Ĵ��� 1 +#define ADS1220_REG2 0x02 // �Ĵ��� 2 +#define ADS1220_REG3 0x03 // �Ĵ��� 3 + +#define PGAGain1 0x00 // PGA���� Ĭ�� +#define PGAGain2 0x02 // +#define PGAGain4 0x04 // +#define PGAGain8 0x06 // +#define PGAGain16 0x08 // +#define PGAGain32 0x0A // +#define PGAGain64 0x0C // +#define PGAGain128 0x0E // + +#define ADS1220_Standby 0 // ת������ +#define ADS1220_ConvStart 1 // ת����ʼ +#define ADS1220_ConvFinish 2 // ת����� + +#define ADS1220_Channal1 0 // ͨ��1 +#define ADS1220_Channal2 1 // ͨ��2 +#define ADS1220_Channal3 2 // ͨ��3 +#define ADS1220_Channal4 3 // ͨ��4 + +#define LED1_GPIO_PIN 11 +#define LED2_GPIO_PIN 12 + +#define GPIO_OUTPUT_PIN_SEL ((1ULL << LED1_GPIO_PIN) | (1ULL << LED2_GPIO_PIN)) + +#define GPIO_INPUT_IO_39 39 +#define GPIO_INPUT_PIN_SEL (1ULL << GPIO_INPUT_IO_39) +// #define GPIO_INPUT_IO_1 5 +// #define GPIO_INPUT_PIN_SEL ((1ULL<cap_value; + xQueueSendFromISR(gpio_evt_queue, &ad_update_time[ch], NULL); +} + +static void GPIO_Init(void) +{ + // zero-initialize the config structure. + gpio_config_t io_conf = {}; + // disable interrupt + io_conf.intr_type = GPIO_INTR_DISABLE; + // set as output mode + io_conf.mode = GPIO_MODE_OUTPUT; + // bit mask of the pins that you want to set,e.g.GPIO18/19 + io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL; + // 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 + gpio_config(&io_conf); + + // interrupt of rising edge + // io_conf.intr_type = GPIO_INTR_NEGEDGE; + // // bit mask of the pins, use GPIO4/5 here + // io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL; + // // set as input mode + // io_conf.mode = GPIO_MODE_INPUT; + // // enable pull-up mode + // io_conf.pull_up_en = 1; + // gpio_config(&io_conf); + + // change gpio intrrupt type for one pin + // gpio_set_intr_type(GPIO_INPUT_IO_39, GPIO_INTR_NEGEDGE); + + // create a queue to handle gpio event from isr + gpio_evt_queue = xQueueCreate(1, sizeof(uint32_t)); + // install gpio isr service + // gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); + // // hook isr handler for specific gpio pin + // gpio_isr_handler_add(GPIO_INPUT_IO_39, gpio_isr_handler, (void *)GPIO_INPUT_IO_39); + + ESP_ERROR_CHECK(mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM_CAP_1, GPIO_INPUT_IO_39)); + // enable pull down CAP0, to reduce noise + ESP_ERROR_CHECK(gpio_pullup_en(GPIO_INPUT_IO_39)); + // enable both edge capture on CAP0 + mcpwm_capture_config_t conf = { + .cap_edge = MCPWM_NEG_EDGE, + .cap_prescale = 1, + .capture_cb = ads1220_done_handler, // 绑定深度中断处理函数 + .user_data = NULL}; + ESP_ERROR_CHECK(mcpwm_capture_enable_channel(MCPWM_UNIT_0, MCPWM_SELECT_CAP1, &conf)); +} + +uint8_t ret = 0; + +/**** + * ADS1220���Ĵ��� + **/ +u8 ADS1220_ReadReg(u8 reg) +{ + u8 Val; + esp_err_t ret; + spi_transaction_t t; + memset(&t, 0, sizeof(t)); // Zero out the transaction + t.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA; + t.tx_data[0] = ADS1220_CMD_RREG | ((reg & 0x03) << 2); + t.length = 2 * 8; + ret = spi_device_polling_transmit(spi2, &t); // Transmit! + assert(ret == ESP_OK); + Val = t.rx_data[1]; + return Val; +} +/*** + * ��ADS1220������д��24Bits + * + **/ + +// static u32 ADS1220_ReadWrite24Bits(u32 dat) +// { +// uint8_t tmp[3]; +// static int val = 0; + +// HAL_SPI_TransmitReceive(&spi2, (uint8_t *)&dat, (uint8_t *)tmp, 3, 500); + +// val = ((uint32_t)tmp[0] << 16) + ((uint32_t)tmp[1] << 8) + ((uint32_t)tmp[2] << 0); + +// // ������λ 23λ ��1 ��Ϊ �з��� +// if (val & 0x800000) +// { +// val |= 0xFF000000; +// } +// return val; +// } + +// ADS1220������ +s32 ADS1220_ReadData(void) +{ + s32 Val = 0; + esp_err_t ret; + spi_transaction_t t; + memset(&t, 0, sizeof(t)); // Zero out the transaction + t.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA; + t.tx_data[0] = ADS1220_CMD_RDATA; + t.length = 4 * 8; // Command is 24 bits + ret = spi_device_polling_transmit(spi2, &t); // Transmit! + assert(ret == ESP_OK); + Val = (t.rx_data[1] << 16) | (t.rx_data[2] << 8) | t.rx_data[3]; + if (Val & 0x800000) + { + Val |= 0xFF000000; + } + return Val; +} +// ADS1220д�Ĵ��� +void ADS1220_WriteReg(u8 reg, u8 dat) +{ + esp_err_t ret; + spi_transaction_t t; + memset(&t, 0, sizeof(t)); // Zero out the transaction + t.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA; + // t.flags = SPI_TRANS_USE_TXDATA; + t.tx_data[0] = ADS1220_CMD_WREG | ((reg & 0x03) << 2); + t.tx_data[1] = dat; + t.length = 2 * 8; // Command is 16 bits + ret = spi_device_polling_transmit(spi2, &t); // Transmit! + assert(ret == ESP_OK); +} + +// ADS1220д���� +void ADS1220_WriteCommand(u8 cmd) +{ + + esp_err_t ret; + spi_transaction_t t; + memset(&t, 0, sizeof(t)); // Zero out the transaction + t.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA; + t.length = 8 * 2; // Command is 8 bits + t.tx_data[0] = cmd; // The data is the cmd itself + // ESP_LOGI(TAG, "spi_device_polling_transmit befor.\n"); + ret = spi_device_polling_transmit(spi2, &t); // Transmit! + // ESP_LOGI(TAG, "spi_device_polling_transmit after.\n"); + assert(ret == ESP_OK); + // // ADS1220_CS=0; + // ADS1220_nCS_LOW(); + // ADS1220_ReadWriteByte(cmd); + // // ADS1220_CS=1; + // ADS1220_nCS_HIGH(); +} + +// ADS1220�������ģʽ +void ADS1220_PowerDown(void) +{ + ADS1220_WriteCommand(ADS1220_CMD_POWERDOWN); // +} + +// ADS1220����ת�� +void ADS1220_StartConv(u8 channal) +{ + /* + u8 val ; + val = ADS1220_ReadReg(ADS1220_REG0); + + ADS1220.CurrentCH = ADS1220_Channal1; + val = val & 0x0f | Channal1; + ADS1220_WriteReg(ADS1220_REG0, val ); // �Ĵ���0 ����: AIN P = AIN0, AIN N = AIN1 ���ģʽ ʹ��PGA 64 (110) ����PGA (0) + */ + ADS1220_WriteCommand(ADS1220_CMD_START); // ����ת�� +} + +// ADS1220��λ +void ADS1220_Reset(void) +{ + ADS1220_WriteCommand(ADS1220_CMD_RESET); // ��λADS1220 +} + +// ADS1220 PGA���� +void ADS1220_PGASet(u8 gain) +{ + u8 val; + val = ADS1220_ReadReg(ADS1220_REG0); + val = (val & 0xF1) | gain; + + ADS1220_WriteReg(ADS1220_REG0, val); + // val = ADS1220_ReadReg(ADS1220_REG0); + ADS1220_StartConv(ADS1220_Channal1); // ����ת�� +} +// static uint8_t dara_rate = 0x40; +void ADS1220_Config(void) +{ + static uint8_t read[4]; + ADS1220_WriteCommand(ADS1220_CMD_RESET); // ��λADS1220 + vTaskDelay(10); + // ESP_LOGI(TAG, "ADS1220_WriteCommand.\n"); + ADS1220_WriteReg(ADS1220_REG0, 0xa0); // �Ĵ���0 ����: ����: AIN P = AIN0, AIN N = AVSS ����ģʽ ʹ��PGA1 (100) ����PGA(0) + + ADS1220_WriteReg(ADS1220_REG1, 0x00); // �Ĵ���1 ����: Turboģʽ 40.SPS(00000)��ʹ���¶ȴ�����(0) �رյ������(0) + + ADS1220_WriteReg(ADS1220_REG2, 0x20); // �Ĵ���2 ����: ��ѹ��׼ �ڲ�2.048-v�ο�(00) ʹ��оƬFIR�˲�50Hz(10) ����Դ0ma // Low-side��Դ���� Ĭ��(0) ����Դ �ر� + ADS1220_WriteReg(ADS1220_REG3, 0x00); // �Ĵ���3 ����: : IDAC1 connect to AIN2 : IDAC2 disabled + + read[0] = ADS1220_ReadReg(ADS1220_REG0); + read[1] = ADS1220_ReadReg(ADS1220_REG1); + read[2] = ADS1220_ReadReg(ADS1220_REG2); + read[3] = ADS1220_ReadReg(ADS1220_REG3); + printf("ads1220 reg %02x %02x %02x %02x \n", read[0], read[1], read[2], read[3]); +} + +void LED2_Toggle(void) +{ + static unsigned char flg = 1; + if (flg) + { + gpio_set_level(LED2_GPIO_PIN, 0); + flg = 0; + } + else + { + gpio_set_level(LED2_GPIO_PIN, 1); + flg = 1; + } +} +static void SPI2_Init(void) +{ + esp_err_t ret; + + spi_bus_config_t buscfg2 = { + .miso_io_num = SPI2_PIN_NUM_MISO, + .mosi_io_num = SPI2_PIN_NUM_MOSI, + .sclk_io_num = SPI2_PIN_NUM_CLK, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .max_transfer_sz = 8}; + + spi_device_interface_config_t devcfg2 = { + .clock_speed_hz = 1 * 1000 * 1000, // Clock out at 1 MHz + .mode = 0, // SPI mode 0 + .cs_ena_posttrans = 2, // Keep the CS low 2 cycles after transaction, to stop slave from missing the last bit when CS has less propagation delay than SPI CLK + .spics_io_num = SPI2_PIN_NUM_CS, // CS pin + .queue_size = 1, // We want to be able to queue 7 transactions at a time + // .address_bits = 8, + // .pre_cb = lcd_spi_pre_transfer_callback, // Specify pre-transfer callback to handle D/C line + // .command_bits = 8, + }; + // Initialize the SPI bus + ret = spi_bus_initialize(ADS1220_HOST, &buscfg2, SPI_DMA_CH_AUTO); + ESP_ERROR_CHECK(ret); + // Attach the ADS1220 to the SPI bus + ret = spi_bus_add_device(ADS1220_HOST, &devcfg2, &spi2); + ESP_ERROR_CHECK(ret); +} + +extern void zero_totalflow(int ch); + +extern int zero_totalflow_req; +extern int abs_sub(uint32_t enc_update_time, uint32_t _enc_update_time); +extern cal_4_20ma_t *cal_4_20ma; +extern flow_config_t *flow_config; +extern flow_t *pflow; +extern uint8_t timeout[2]; +extern int flow_rem[2]; +void ads1220_task(void) +{ + uint32_t io_num; + u32 data; + static uint32_t ad_flow_tick = 10; + while (1) + { + // ESP_LOGI(TAG, "xQueueReceive before\n "); + if (xQueueReceive(gpio_evt_queue, &io_num, 200)) + { + int ad_ch; + // ESP_LOGI(TAG, "xQueueReceive during\n "); + ads1220_watchdog = 0; + int ad_raw = ADS1220_ReadData(); + // ESP_LOGI(TAG, "ad_raw : %d\n ", ad_raw); + ad_value[ch] = ad_raw / 128; + ad_ch = ch; + gWordVar[AD_RAW_REG_ADDR + ch] = ad_value[ch] / 2; + // ESP_LOGI(TAG, "channel : %d ad_value: %d\n ", ch, ad_value[ch]); + ch++; + if (ch >= sizeof(ch_cmd)) + { + ch = 0; + } + ADS1220_WriteReg(ADS1220_REG0, ch_cmd[ch]); + ADS1220_WriteCommand(ADS1220_CMD_START); + ad_watchdog_cnt = 0; + LED2_Toggle(); + if ((ad_ch == 1 || ad_ch == 3) && flow_config->input_type == 1) + { + int flow_ch = ad_ch / 2; + int time_diff = abs_sub(ad_update_time[ad_ch], pflow[flow_ch].update_time); + ad_flow_cal_t *cal = flow_config->ad_cal; + int t_flow; // time_diff时间段总流量 + pflow[flow_ch].flow_ = scale(ad_value[ad_ch], cal_4_20ma->ch[flow_ch].ad_4ma, cal_4_20ma->ch[flow_ch].ad_20ma, cal[flow_ch].flow_min, cal[flow_ch].flow_max); + if (pflow[flow_ch].flow_ < flow_config->min_flow[flow_ch]) // 小流量切除 + { + pflow[flow_ch].flow = 0; + } + else + { + pflow[flow_ch].flow = pflow[flow_ch].flow_; + } + // 累计流量计算 pflow[i].flow 单位为0.01L/分钟 time_diff 单位为1us + // flow = pflow[i].flow / 60.0 * 10000; 将流量换算成uL/s + // t_diff = time_diff / 1000 将时间差换算成秒 + // t_flow = flow * t_diff 计算t_diff时间段的流量 单位uL + // 取出0.01L的整数部分累加,余数部分和下次值累加 + // t_flow = pflow[i].flow * 1000 * time_diff / 1000000 / 60; + int time_diff_us = time_diff / (APB_CLK_FREQ / 1000000); + t_flow = pflow[flow_ch].flow * (long long)time_diff_us / 60 / 100; //(5 * 60); + flow_rem[flow_ch] += t_flow; + int sub_flow = flow_rem[flow_ch] / 10000; + pflow[flow_ch].total_flow += sub_flow; + flow_rem[flow_ch] = flow_rem[flow_ch] - sub_flow * 10000; + pflow[flow_ch].update_time = ad_update_time[ad_ch]; + timeout[flow_ch] = 0; + // ESP_LOGI(TAG, "(type1) flow_rem[%d].flow: %u time_diff=%d", flow_ch ,pflow[flow_ch].flow,time_diff); + } + } + else + { + ADS1220_Init(); + } + if (zero_totalflow_req) + { + zero_totalflow_req = 0; + zero_totalflow(0); + zero_totalflow(1); + } + } +} + +void ads1220_task_start(void) +{ + SPI2_Init(); + GPIO_Init(); + ADS1220_Init(); + xTaskCreate(ads1220_task, "ads1220_task", 4096, NULL, 10, NULL); +} + +// void ADS1220_set_rate(int i) +//{ +// switch (i) +// { +// case 1 :dara_rate = 0x00;//20SPS +// break; +// case 2 :dara_rate = 0x20;//45SPS +// break; +// case 3 :dara_rate = 0x40;//90SPS +// break; +// case 4 :dara_rate = 0x60;//175SPS +// break; +// default:dara_rate = 0x00;//20SPS +// break; +// } +// } + +// int ADS1220_get_rate(void) +//{ +// switch (dara_rate) +// { +// case 0x00 :return 20*100;//20SPS +// break; +// case 0x20 :return 45*100;//45SPS +// break; +// case 0x40 :return 90*100;//90SPS +// break; +// case 0x60 :return 175*100;//175SPS +// break; +// default:return 20*100;//20SPS +// break; +// } +// } +// ch0 0.5V 3478 +// ch0 1.0V 0 +// ch0 1.5V 10429 + +// ch1 4.000ma 12783 +// ch1 12.00ma 38349 + +// ch2 4.000ma 12764 +// ch2 12.00ma 38336 diff --git a/main/stm32/ads1220.h b/main/stm32/ads1220.h new file mode 100644 index 0000000..9d9269f --- /dev/null +++ b/main/stm32/ads1220.h @@ -0,0 +1,61 @@ +#ifndef __ADS1220_H +#define __ADS1220_H +// #include "main.h" +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "driver/spi_master.h" +#include "driver/gpio.h" + +typedef uint8_t u8; +typedef uint32_t u32; +typedef int32_t s32; +#define LED1_GPIO_PIN 11 +#define LED2_GPIO_PIN 12 + +#define GPIO_INPUT_IO_39 39 + +typedef struct +{ + + int ch0_4ma; + int ch0_12ma; + float ch0_4ma_yl; + float ch0_12ma_yl; + + int ch1_4ma; + int ch1_12ma; + float ch1_4ma_yl; + float ch1_12ma_yl; + + int ch2_4ma; + int ch2_12ma; + float ch2_4ma_yl; + float ch2_12ma_yl; +}ads_cali_t; + +//extern ads_cali_t ads_cali; + + +uint32_t get_now_20us(void); +int32_t tim_diff(uint32_t a,uint32_t b); +int ADS1220_get_rate(void); +void ADS1220_set_rate(int i); +void ADS1220_Init(void); // ADS1220��ʼ�� +void ADS1220_Config(void); // ADS1220���� +void ADS1220_StartConv(u8 channal); // ADS1220����ת�� +void ADS1220_Reset(void); // ADS1220��λ +void ADS1220_PowerDown(void); // ADS1220�������ģʽ +void ADS1220_PGASet(u8 gain); // ADS1220 PGA���� +void ADS1220_WriteCommand(u8 cmd); // ADS1220д���� +s32 ADS1220_ReadData(void); // ADS1220������ +void ADS1220_WriteReg(u8 reg,u8 dat); // ADS1220д�Ĵ��� +u8 ADS1220_ReadReg(u8 reg); // ADS1220���Ĵ��� +u8 ADS1220_ReadWriteByte(u8 dat); // ��SPI������д��һ�ֽ� +u32 ADS1220_ReadWrite24Bits(u32 dat); // ��ADS1220������д��24Bits + +int scale(int raw, int raw_min, int raw_max,int eng_min, int eng_max); +#endif diff --git a/main/stm32/bl0939.c b/main/stm32/bl0939.c new file mode 100644 index 0000000..515f453 --- /dev/null +++ b/main/stm32/bl0939.c @@ -0,0 +1,295 @@ +#include "bl0939.h" +#include "string.h" +#include "utils.h" +// #include "ModbusS.h" +#include "config.h" + +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "driver/spi_master.h" +#include "driver/gpio.h" +#include "esp_log.h" + +#define TAG "BL0939" + +#define BL0939_HOST SPI3_HOST + +#define SPI1_PIN_NUM_MISO 6 +#define SPI1_PIN_NUM_MOSI 5 +#define SPI1_PIN_NUM_CLK 4 +#define SPI1_PIN_NUM_CS 42 + +#define PIN_NUM_DC 9 +#define PIN_NUM_RST 4 +#define PIN_NUM_BCKL 5 + +extern move_t *pMoveCtx; +// To speed up transfers, every SPI transfer sends a bunch of lines. This define specifies how many. More means more memory use, +// but less overhead for setting up / finishing transfers. Make sure 240 is dividable by this. +#define PARALLEL_LINES 16 +static spi_device_handle_t spi1; + +static void SPI1_Init(void) +{ + esp_err_t ret; + + spi_bus_config_t buscfg1 = { + .miso_io_num = SPI1_PIN_NUM_MISO, + .mosi_io_num = SPI1_PIN_NUM_MOSI, + .sclk_io_num = SPI1_PIN_NUM_CLK, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .max_transfer_sz = PARALLEL_LINES * 320 * 2 + 8}; + + spi_device_interface_config_t devcfg1 = { +#ifdef CONFIG_LCD_OVERCLOCK + .clock_speed_hz = 26 * 1000 * 1000, // Clock out at 26 MHz +#else + .clock_speed_hz = 8 * 100 * 1000, // Clock out at 800kHz +#endif + + .mode = 1, // SPI mode 1 + .spics_io_num = SPI1_PIN_NUM_CS, // CS pin + .queue_size = 7, // We want to be able to queue 7 transactions at a time + // .command_bits = 8, + // .pre_cb = lcd_spi_pre_transfer_callback, // Specify pre-transfer callback to handle D/C line + }; + // Initialize the SPI bus + ret = spi_bus_initialize(BL0939_HOST, &buscfg1, SPI_DMA_CH_AUTO); + ESP_ERROR_CHECK(ret); + // Attach the ADS1220 to the SPI bus + ret = spi_bus_add_device(BL0939_HOST, &devcfg1, &spi1); + ESP_ERROR_CHECK(ret); +} + +void bl0939_spi_reset(void); + +static void BL0939_SPI_TransmitReceive(uint8_t *tbuff, uint8_t *rbuff, + uint16_t len) +{ + esp_err_t ret; + spi_transaction_t t; + memset(&t, 0, sizeof(t)); // Zero out the transaction + t.tx_buffer = tbuff; + t.rx_buffer = rbuff; + t.length = len * 8; // Command is 16 bits + ret = spi_device_polling_transmit(spi1, &t); // Transmit! + assert(ret == ESP_OK); +} + +static uint32_t bl0939_read_reg(uint8_t reg) +{ + uint8_t tx_buf[6] = {0x55, reg, 0, 0, 0, 0}; + uint8_t rx_buf[6] = {0}; + // bl0939_spi_reset(); + BL0939_SPI_TransmitReceive(tx_buf, rx_buf, 6); + if (rx_buf[5] == (uint8_t) ~(0x55 + reg + rx_buf[2] + rx_buf[3] + rx_buf[4])) + { + return (uint32_t)rx_buf[2] << 16 | + (uint32_t)rx_buf[3] << 8 | + (uint32_t)rx_buf[4] << 0; + } + return 0; +} + +uint32_t r_temp = 0; +static int bl0939_write_reg(uint8_t reg, uint32_t val, int check) +{ + int i = 5; + uint8_t h = val >> 16; + uint8_t m = val >> 8; + uint8_t l = val >> 0; + do + { + i--; + vTaskDelay(5); + // bl0939_spi_reset(); + uint8_t tx_buf[6] = {0xA5, reg, h, m, l, ~(0XA5 + reg + h + m + l)}; + uint8_t rx_buf[6] = {0}; + BL0939_SPI_TransmitReceive(tx_buf, rx_buf, 6); + vTaskDelay(10); + if (0 == check) + return 0; + r_temp = bl0939_read_reg(reg); + if (r_temp == val) + return 0; + } while (i > 0); + return 1; +} + +void bl0939_spi_reset(void) +{ + uint8_t tx_buf[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + uint8_t rx_buf[6] = {0}; + BL0939_SPI_TransmitReceive(tx_buf, rx_buf, 6); +} + +uint32_t comp_threshold(float mA) +{ + return (uint32_t)(mA * 1 * 324004 * 0.00140625f * 0.95f / (600 * 1.218f)); +} + +void bl0939_reset(void) +{ + bl0939_spi_reset(); + bl0939_write_reg(0x19, 0x005a5a5a, 0); // ��λ�û��Ĵ��� + bl0939_write_reg(0x1a, 0x00000055, 1); // ���д���� + bl0939_write_reg(0x10, 0xffff, 0); // Threshold A + bl0939_write_reg(0x1E, 0xffff, 1); // Threshold B + bl0939_write_reg(0x18, 0x00002000, 1); // cf + bl0939_write_reg(0x1B, 0x000047ff, 0); // cf + bl0939_write_reg(0x1a, 0x00000000, 1); // д���� +} + +// T = 40ms +int bl0939_get_current_A() +{ + bl0939_spi_reset(); + uint32_t Ia = bl0939_read_reg(0x00); + // return Ia * 1.218f / (float) ( 324004 * 1 ); + return Ia; +} +// T = 40ms +int bl0939_get_current_B() +{ + bl0939_spi_reset(); + uint32_t Ib = bl0939_read_reg(0x07); + // return Ib * 1.218f / (float) ( 324004 * 1 ); + return Ib; +} +// T = 400ms +int bl0939_get_voltage() +{ + bl0939_spi_reset(); + uint32_t v = bl0939_read_reg(0x06); + // return v * 1.218f * ( 2 + 2000 ) / (float) ( 79931 * 2 * 1000 ); + return v; +} + +/// @brief +uint8_t bl0939_cmd[36] = + { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x55, 0x00, 0, 0, 0, 0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x55, 0x07, 0, 0, 0, 0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x55, 0x06, 0, 0, 0, 0}; + +int check_sum_ch(uint8_t *buf, int offset) +{ + uint8_t sum = ~(0x55 + bl0939_cmd[offset - 1] + buf[offset] + buf[offset + 1] + buf[offset + 2]); + if (buf[offset + 3] == sum) + { + return 1; + } + return 0; +} +uint32_t readUint24LE(uint8_t *buf, int offset) +{ + return buf[offset] | buf[offset + 1] << 8 | buf[offset + 2] << 16; +} +uint32_t readUint24BE(uint8_t *buf, int offset) +{ + return buf[offset] << 16 | buf[offset + 1] << 8 | buf[offset + 2]; +} + +// __IO uint8_t bl0939_Transfer_done = 0; +uint8_t bl0939_Transfer_done = 0; + +void bl0939_init(void) +{ + bl0939_reset(); +} + +float ac_current_coef[3] = { + 1.218f / (324004.f * 0.225 * 1000 / 2000) * 100.f, + 1.218f / (324004.f * 0.23 * 1000 / 2000) * 100.f, + 1.218f / (79931.f * 0.002 * 500) * 100.f}; +uint8_t bl0939_rxbuf[2][36]; +int32_t ac_ad_values[3] = {0}; +int move_time = 0; +int move_req = 0; +extern uint16_t gWordVar[]; +int move_status = 0; + +void BL0939_task() +{ + int index = 0; + while (1) + { + vTaskDelay(10); + // ESP_LOGI(TAG, "BL0939_SPI_TransmitReceive before\n "); + bl0939_Transfer_done = 1; + + BL0939_SPI_TransmitReceive(bl0939_cmd, bl0939_rxbuf[index & 1], 36); + if (!memcmp(bl0939_rxbuf[0], bl0939_rxbuf[1], sizeof(bl0939_rxbuf[0]))) + { + index++; + bl0939_Transfer_done = 0; + // continue; + } + // ESP_LOGI(TAG, "BL0939_SPI_TransmitReceive after\n "); + if (bl0939_Transfer_done) + { + int ch; + // ESP_LOGI(TAG, "bl0939_Transfer_done \n "); + bl0939_Transfer_done = 0; + for (ch = 0; ch < 3; ch++) + { + if (check_sum_ch(bl0939_rxbuf[index & 1], 8 + ch * 12)) + { + ac_ad_values[ch] = readUint24BE(bl0939_rxbuf[index & 1], 8 + ch * 12); + // ESP_LOGI(TAG, "channel : %d ac_ad_values: %d\n ", ch, ac_ad_values[ch]); + gWordVar[AC_CURRENT_REG_ADDR + ch] = ac_ad_values[ch] * ac_current_coef[ch]; + } + // ac_ad_values[ch] = readUint24BE(bl0939_rxbuf,8+ch*12); + // ESP_LOGI(TAG, "channel : %d ac_ad_values: %d\n ", ch, ac_ad_values[ch]); + } + if (pMoveCtx->status == 0) + { // 停止状态,等待启动 + int move_current_channel = depth_config->move_current_channel; + if (move_current_channel > 2 || move_current_channel < 0) + { + move_current_channel = 2; + } + if (gWordVar[AC_CURRENT_REG_ADDR + move_current_channel] > depth_config->current_on_threshold) + { + if (++pMoveCtx->time_count > depth_config->move_on_duratino) + { + pMoveCtx->status = 1; + pMoveCtx->time_count = 0; + pMoveCtx->pile_inc_req = 1; + } + } + } + else if (pMoveCtx->status == 1) + { + int move_current_channel = depth_config->move_current_channel; + if (move_current_channel > 2 || move_current_channel < 0) + { + move_current_channel = 2; + } + if (gWordVar[AC_CURRENT_REG_ADDR + 2] < depth_config->current_off_threshold) + { + if (++pMoveCtx->time_count > depth_config->move_off_duration) + { + pMoveCtx->status = 0; + pMoveCtx->time_count = 0; + } + } + } + } + } +} + +void BL0939_init(void) +{ + SPI1_Init(); + bl0939_init(); + xTaskCreate(BL0939_task, "BL0939_task", 4096, NULL, 10, NULL); +} diff --git a/main/stm32/bl0939.h b/main/stm32/bl0939.h new file mode 100644 index 0000000..bc25657 --- /dev/null +++ b/main/stm32/bl0939.h @@ -0,0 +1,31 @@ +#ifndef BL0939_H__ +#define BL0939_H__ + + + +// #include "main.h" +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "driver/spi_master.h" +#include "driver/gpio.h" + + + +void bl0939_reset(void); +int bl0939_get_current_A(void); +int bl0939_get_current_B(void); +int bl0939_get_voltage(void); + +//DMA +void bl0939_get_abv(uint8_t * buf); +int bl0939_parse_abv(uint8_t * buf,unsigned int * data); + + +#endif + + + diff --git a/main/stm32/capture.c b/main/stm32/capture.c new file mode 100644 index 0000000..c92c131 --- /dev/null +++ b/main/stm32/capture.c @@ -0,0 +1,156 @@ +/* + +*/ + + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "esp_log.h" +#include "esp_check.h" +#include "soc/rtc.h" +#include "driver/mcpwm.h" + +const static char *TAG = "capture"; + +typedef struct capture_event +{ + int ch; + uint32_t val; +}capture_event_t; + + +#define FLOW1_PIN_ECHO GPIO_NUM_9 //捕获GPIO端口 +#define FLOW2_PIN_ECHO GPIO_NUM_10 //捕获GPIO端口 + + +#define TRIGGER_THREAD_PRIORITY 5 + +typedef struct { + uint32_t capture_signal; + mcpwm_capture_signal_t sel_cap_signal; +} capture; + +static uint32_t cap_val_begin_of_flow1 = 0; +static uint32_t cap_val_end_of_flow1 = 0; +static uint32_t cap_val_begin_of_flow2 = 0; +static uint32_t cap_val_end_of_flow2 = 0; + +static xQueueHandle cap_queue; +extern uint32_t rtc_clk_apb_freq; +uint32_t volatile t15_ccr[2]; +uint16_t volatile t15_ccr_times[2]; + +static bool flow1_isr_handler(mcpwm_unit_t mcpwm, mcpwm_capture_channel_id_t cap_sig, const cap_event_data_t *edata, + void *arg) { + //calculate the interval in the ISR, + //so that the interval will be always correct even when cap_queue is not handled in time and overflow. + BaseType_t high_task_wakeup = pdFALSE; + + cap_val_end_of_flow1 = edata->cap_value; + capture_event_t cap_event = {.val = 0, .ch = 1}; + cap_event.val = cap_val_end_of_flow1 - cap_val_begin_of_flow1; + t15_ccr_times[0] = cap_event.val * (1000000.0 / rtc_clk_apb_freq); + t15_ccr[0]++; + return high_task_wakeup == pdTRUE; +} + +void capture_flow1_init() +{ + ESP_ERROR_CHECK(mcpwm_gpio_init(MCPWM_UNIT_1, MCPWM_CAP_1, FLOW1_PIN_ECHO)); + // enable pull down CAP0, to reduce noise + ESP_ERROR_CHECK(gpio_pullup_en(FLOW1_PIN_ECHO)); + // enable both edge capture on CAP0 + mcpwm_capture_config_t conf = { + .cap_edge = MCPWM_NEG_EDGE, + .cap_prescale = 1, + .capture_cb = flow1_isr_handler, //绑定流量捕获中断处理函数 + .user_data = NULL + }; + ESP_ERROR_CHECK(mcpwm_capture_enable_channel(MCPWM_UNIT_1, MCPWM_SELECT_CAP1, &conf)); + mcpwm_set_frequency(MCPWM_UNIT_1, MCPWM_TIMER_1, 1000000); + int value = mcpwm_capture_signal_get_value(MCPWM_UNIT_1,MCPWM_SELECT_CAP1); + ESP_LOGI(TAG, "capture_flow_init value=%d",value); +} + +static bool flow2_isr_handler(mcpwm_unit_t mcpwm, mcpwm_capture_channel_id_t cap_sig, const cap_event_data_t *edata, + void *arg) { + //calculate the interval in the ISR, + //so that the interval will be always correct even when cap_queue is not handled in time and overflow. + BaseType_t high_task_wakeup = pdFALSE; + + cap_val_end_of_flow2 = edata->cap_value; + capture_event_t cap_event = {.val = 0, .ch = 2}; + cap_event.val = cap_val_end_of_flow2 - cap_val_begin_of_flow2; + t15_ccr_times[1] = cap_event.val * (1000000.0 / rtc_clk_apb_freq); + t15_ccr[1]++; + // send measurement back though queue + // xQueueSendFromISR(cap_queue, &cap_event, &high_task_wakeup); + + return high_task_wakeup == pdTRUE; +} + +void capture_flow2_init() +{ + ESP_ERROR_CHECK(mcpwm_gpio_init(MCPWM_UNIT_1, MCPWM_CAP_2, FLOW2_PIN_ECHO)); + // enable pull down CAP0, to reduce noise + ESP_ERROR_CHECK(gpio_pulldown_en(FLOW2_PIN_ECHO)); + // enable both edge capture on CAP0 + mcpwm_capture_config_t conf = { + .cap_edge = MCPWM_NEG_EDGE, + .cap_prescale = 1, + .capture_cb = flow2_isr_handler, //绑定流量捕获中断处理函数 + .user_data = NULL + }; + ESP_ERROR_CHECK(mcpwm_capture_enable_channel(MCPWM_UNIT_1, MCPWM_SELECT_CAP2, &conf)); + mcpwm_set_frequency(MCPWM_UNIT_1, MCPWM_TIMER_2, 1000000); + ESP_LOGI(TAG, "capture_flow_init"); +} + + +// void capture_task(void) +// { +// while (true) { +// capture_event_t cap_event = {.val = 0, .ch = 1}; +// uint32_t pulse_width_us = 0; +// // block and wait for new measurement +// // ESP_LOGI(TAG, "xQueueReceive started"); +// xQueueReceive(cap_queue, &cap_event, portMAX_DELAY); +// // ESP_LOGI(TAG, "xQueueReceive after"); +// // ESP_LOGI(TAG, " cap_event.val: %d, cap_event.ch : %d", cap_event.val, cap_event.ch); +// switch (cap_event.ch) +// { +// case 1: //flow1 capture +// pulse_width_us = cap_event.val * (1000000.0 / rtc_clk_apb_freq); + +// ESP_LOGI(TAG, " (flow1 capture) Pulse width: %uus", pulse_width_us); +// break; +// case 2: //flow2 capture +// pulse_width_us = cap_event.val * (1000000.0 / rtc_clk_apb_freq); +// ESP_LOGI(TAG, "(flow2 capture) Pulse width: %uus", pulse_width_us); +// break; +// default: ESP_LOGI(TAG, " default\n"); +// break; +// } +// } +// } + + +// void capture_depth_init(); +// void pcnt_rotary_encoder_init(void); +void capture_init(void) +{ + // cap_queue = xQueueCreate(3, sizeof(capture_event_t)); + // if (cap_queue == NULL) { + // ESP_LOGE(TAG, "failed to alloc cap_queue"); + // return; + // } + + // capture_depth_init(); + capture_flow1_init(); + capture_flow2_init(); + // start gcapture_task + // xTaskCreate(capture_task, "capture_task", 4096, NULL, TRIGGER_THREAD_PRIORITY, NULL); + // ESP_LOGI(TAG, "capture_task started"); + // pcnt_rotary_encoder_init(); +} diff --git a/main/stm32/comm.c b/main/stm32/comm.c new file mode 100644 index 0000000..e24e70c --- /dev/null +++ b/main/stm32/comm.c @@ -0,0 +1,105 @@ +#include "stdlib.h" +#include "utils.h" +#include "fram.h" +#include "ModbusS.h" +#include "ads1220.h" +// #include "SEGGER_RTT.h" +#include "ModbusM.h" + +uint32_t TickDiff(uint32_t comptime); +extern void modbus_master_poll(int n); +extern int modbus_master_on_revice(int ch, uint8_t *rxbuf, int length); + +extern uint8_t uart1_txbuf[]; +extern uint8_t uart1_rxbuf[]; + +extern uint8_t uart2_txbuf[]; +extern uint8_t uart2_rxbuf[]; + +extern int uart1_rx_start(void); +extern int uart1_rx_check(void); +extern int uart1_tx_start(uint8_t *data, int length); + + +extern int uart2_rx_start(void); +extern int uart2_rx_check(void); +extern int uart2_tx_start(uint8_t *data, int length); + +void RS485_init(); +void print_init(); + +extern uint8_t led_toggle_count; + + + +void comm_poll(void) +{ + + static uint32_t modbus_master_tick = 0; + static uint32_t tick_100ms = 0; + static int uart1_timeout = 0; + static int uart2_timeout = 0; + int rxlen,txlen; +// if((rxlen = uart1_rx_check()) > 0){ +// txlen = ModbusSlaveProcess(uart1_txbuf,uart1_rxbuf,rxlen,1); +// if(txlen > 0) +// { +// HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); +// uart1_tx_start(uart1_txbuf,txlen); +// } +// else{ +// uart1_rx_start(); +// } +// } + if((rxlen = uart2_rx_check()) > 0){ + + txlen = ModbusSlaveProcess(uart2_txbuf,uart2_rxbuf,rxlen,1); + if(txlen > 0) + { + uart2_tx_start(uart2_txbuf,txlen); + } + else{ + uart2_rx_start(); + } + led_toggle_count = 0; + uart1_timeout = 0; + } + if(TickDiff(tick_100ms) > 100) + { + tick_100ms = xTaskGetTickCount(); + if(++uart1_timeout > 100){ + uart1_timeout = 0; +// HAL_UART_MspDeInit(&huart2); +// MX_USART2_UART_Init(); + uart2_rx_start(); + } + if(++uart2_timeout > 1000){ + uart2_timeout = 0; +// HAL_UART_MspDeInit(&huart1); +// MX_USART1_UART_Init(); + } + } + if(TickDiff(modbus_master_tick) > 10) + { + modbus_master_tick = xTaskGetTickCount(); + modbus_master_poll(0); + } + if((rxlen = uart1_rx_check()) > 0){ // 做一个uart1_rx_check 读串口 + modbus_master_on_revice(0,uart1_rxbuf,rxlen); + uart2_timeout = 0; + } +} + +void comm_init(void) +{ + // MX_USART1_UART_Init(); + // MX_USART2_UART_Init(); + RS485_init(); + print_init(); + ModbusM_init(); + uart2_rx_start(); +} + + + + diff --git a/main/stm32/config.c b/main/stm32/config.c new file mode 100644 index 0000000..c6a90ef --- /dev/null +++ b/main/stm32/config.c @@ -0,0 +1,150 @@ + +#include "config.h" +#include "fram.h" +#include "utils.h" +#include "modbuss.h" +#include "stdint.h" +#include "esp_log.h" +// #include "flow.h" +// #include "depth.h" +// config_data_t * config_para = (config_data_t*)&gWordVar[256]; +// extern real_t * real; + +static const char *TAG = "config"; + +extern cal_4_20ma_t *cal_4_20ma; +extern flow_config_t *flow_config; +extern depth_config_t *depth_config; + +extern float ac_current_coef[3]; +// 三标一号机 +const cal_4_20ma_t default_cal_4_20ma = {0, {{12740, 63845}, {12760, 63953}}}; +const flow_config_t default_flow_cfg = {0, 1, {0, 0}, {{0, 10000}, {0, 10000}}, {6944, 6944}}; // 4~20MA 输入6m/H 100.00L/min +// const flow_config_t default_flow_cfg = {0,1,{60,60},{{0,20000},{0,20000}},{6944,6944}}; //脉冲输入 12m/H +// const depth_config_t default_depth_cfg = {0, 2,0, 1000, 32, -100, 12000, 100, -100, 1000,500, 500, 100, 150, 150}; // 方向脉冲编码器 10线2倍频 +const depth_config_t default_depth_cfg = { + .magic = 0, + .input_type = 0, + .port = 1, + .N = 1000, + .M = 640, + .min_depth = -100, + .max_depth = 12000, + .sample_depth = 100, + .depth_offset = -100, + .min_valid_depth = 1000, + .inc_pile_depth = 5000, + .current_on_threshold = 500, + .current_off_threshold = 100, + .move_on_duratino = 150, + .move_off_duration = 150, + .move_current_channel = 2, + }; // 方向脉冲编码器 10线2倍频 + +// const depth_config_t default_depth_cfg = {0,3,0,3800,-200,16000,100,-200}; //200线开漏型正交 +// const depth_config_t default_depth_cfg = {0,1,0,76000,-200,16000,100,-200}; + +#define MAGIC 30627 +#define EE_CAL_4_20MA_ADDR 16 +#define EE_FLOW_CFG_ADDR (EE_CAL_4_20MA_ADDR + sizeof(default_cal_4_20ma)) +#define EE_DEPTH_CFG_ADDR (EE_FLOW_CFG_ADDR + sizeof(default_flow_cfg)) + +extern uint16_t last_pile_id = 0; + +extern void init_comm(void); + +// void sys_init(void) +// { +// // HAL_Delay(100); +// // GetCompileDateTime(&gWordVar[0]); +// // flash_load(); +// // modbus_addr = config_para->modbus_addr; +// // sliding_window_filter_init(&sliding_window_a,real->data_long,200); +// // HAL_TIM_Base_Start(&htim6);//ms��ʱ�� +// // HAL_TIM_Base_Start_IT(&htim17);//us��ʱ�� +// //// HAL_TIM_Encoder_Start_IT(&htim1,TIM_CHANNEL_ALL);//enc +// // HAL_TIM_Encoder_Start(&htim3,TIM_CHANNEL_ALL);//enc +// // HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_1);//ll +// // HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_2);//ll +// // HAL_TIM_IC_Start_IT(&htim15,TIM_CHANNEL_1);//ll +// // HAL_TIM_IC_Start_IT(&htim15,TIM_CHANNEL_2);//ll +// // HAL_UART_Receive_IT(&huart1,&temp_rx_data,1); +// // init_comm(); +// // if(config_para->traffic_mode == MA_4_20) +// // { +// // ADS1220_Init(); +// // } +// // HAL_GPIO_WritePin(GPS_PWR_EN_GPIO_Port, GPS_PWR_EN_Pin, GPIO_PIN_SET); +// // HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin,0); +// // HAL_Delay(500); +// } +void config_load(void) +{ + uint16_t temp[2]; + fram_read(0, &temp, sizeof(temp)); + { + if (temp[0] == MAGIC) + { + last_pile_id = temp[1]; + } + } + fram_read(EE_CAL_4_20MA_ADDR, cal_4_20ma, sizeof(default_cal_4_20ma)); + if (cal_4_20ma->magic != MAGIC) + { + ESP_LOGI(TAG, "fram_read cal_4_20ma failed, use default value"); + memcpy(cal_4_20ma, &default_cal_4_20ma, sizeof(default_cal_4_20ma)); + } + fram_read(EE_FLOW_CFG_ADDR, flow_config, sizeof(default_flow_cfg)); + if (flow_config->magic != MAGIC) + { + ESP_LOGW(TAG, "fram_read flow_config failed, use default value"); + memcpy(flow_config, &default_flow_cfg, sizeof(default_flow_cfg)); + } + + fram_read(EE_DEPTH_CFG_ADDR, depth_config, sizeof(default_depth_cfg)); + if (depth_config->magic != MAGIC) + { + ESP_LOGW(TAG, "fram_read depth_config failed, use default value"); + memcpy(depth_config, &default_depth_cfg, sizeof(default_depth_cfg)); + } + fram_read(EE_DEPTH_CFG_ADDR, depth_config, sizeof(default_depth_cfg)); + if (depth_config->magic != MAGIC) + { + ESP_LOGW(TAG, "fram_read depth_config failed, use default value"); + memcpy(depth_config, &default_depth_cfg, sizeof(default_depth_cfg)); + } +} + +void restore_default(void) +{ + memcpy(cal_4_20ma, &default_cal_4_20ma, sizeof(default_cal_4_20ma)); + memcpy(flow_config, &default_flow_cfg, sizeof(default_flow_cfg)); + memcpy(depth_config, &default_depth_cfg, sizeof(default_depth_cfg)); + fram_write(EE_CAL_4_20MA_ADDR, cal_4_20ma, sizeof(default_cal_4_20ma)); + fram_write(EE_FLOW_CFG_ADDR, flow_config, sizeof(default_flow_cfg)); + fram_write(EE_DEPTH_CFG_ADDR, depth_config, sizeof(default_depth_cfg)); +} + +void save_cal_4_20ma(void) +{ + cal_4_20ma->magic = MAGIC; + cal_4_20ma->magic = fram_write(EE_CAL_4_20MA_ADDR, cal_4_20ma, sizeof(default_cal_4_20ma)); +} + +void save_flow_cfg(void) +{ + flow_config->magic = MAGIC; + flow_config->magic = fram_write(EE_FLOW_CFG_ADDR, flow_config, sizeof(default_flow_cfg)); +} + +void save_depth_cfg(void) +{ + depth_config->magic = MAGIC; + depth_config->magic = fram_write(EE_DEPTH_CFG_ADDR, depth_config, sizeof(default_depth_cfg)); +} + +void save_pile_id(void) +{ + uint16_t temp[2] = {MAGIC, last_pile_id}; + fram_write(0, &temp, sizeof(temp)); +} diff --git a/main/stm32/config.h b/main/stm32/config.h new file mode 100644 index 0000000..fa60f0d --- /dev/null +++ b/main/stm32/config.h @@ -0,0 +1,99 @@ +#ifndef SYS_H__ +#define SYS_H__ + +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "esp_err.h" + +typedef struct +{ + uint16_t magic; + struct _ch + { + uint16_t ad_4ma; + uint16_t ad_20ma; + } ch[2]; +} cal_4_20ma_t; + +typedef struct +{ + int16_t flow_min; + int16_t flow_max; +} ad_flow_cal_t; + +typedef struct +{ + uint16_t magic; + uint16_t input_type; // 1 : 4~20ma 2: 0~3.6K + int16_t min_flow[2]; // 小流量切除 + ad_flow_cal_t ad_cal[2]; + uint16_t pulse_coef[2]; + uint16_t rsv[6]; +} flow_config_t; + +typedef struct +{ + uint16_t magic; + uint8_t input_type; // 0:正交 1:正交反向 2:方向脉冲 3:方向脉冲反向 + uint8_t port; // 编码器端口 + uint16_t N; //编码器系数分子 + uint16_t M; //编码器系数分母 + // int pluse_coef; // 脉冲系数0.001mm + int16_t min_depth; // 最小深度 mm + int16_t max_depth; // 最大深度 mm + int16_t sample_depth; // 采样深度 mm + int16_t depth_offset; // 默认深度偏移 + int16_t min_valid_depth; // 最小有效深度 + int16_t inc_pile_depth; // 允许换桩深度 + uint16_t current_on_threshold; // 行走电机开启电流 + uint16_t current_off_threshold; // 行走电机关闭电流 + uint16_t move_on_duratino; // 持续时间 + uint16_t move_off_duration; // 持续时间 + uint16_t move_current_channel; //行走电流通道 +} depth_config_t; + +typedef struct +{ + int16_t flow_; + int16_t flow; + int32_t total_flow; + uint32_t update_time; +} flow_t; + +typedef struct +{ + uint16_t status; // 0:未开始 1:开始 2:结束 + uint16_t time_count; //持续时间 + uint16_t pile_inc_req; +} move_t; + + +extern depth_config_t *depth_config; + +#define FLOW_REG_ADDR 0 +#define DEPTH_REG_ADDR 12 +#define AC_CURRENT_REG_ADDR 24 +#define MOVE_REG_ADDR 27 +#define TILT_SENSER_ADDR 30 +#define RECORD_REG_ADDR 32 + +#define CAL_4_20MA_ADDR 384 +#define FLOW_CONFIG_ADDR (CAL_4_20MA_ADDR + (sizeof(cal_4_20ma_t) + 15) / 16 * 8) +#define DEPTH_CONFIG_ADDR (FLOW_CONFIG_ADDR + (sizeof(flow_config_t) + 15) / 16 * 8) + +#define AD_RAW_REG_ADDR 444 +#define LAST_PILE_ID_ADDR 509 +#define DEPTH_RESET_ADDR 510 +#define REBOOT_REW_ADDR 511 +void config_load(void); +void save_cal_4_20ma(void); +void save_flow_cfg(void); +void save_depth_cfg(void); +void restore_default(void); + +#endif diff --git a/main/stm32/depth.c b/main/stm32/depth.c new file mode 100644 index 0000000..e116475 --- /dev/null +++ b/main/stm32/depth.c @@ -0,0 +1,507 @@ +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "esp_err.h" +#include "stdlib.h" +#include "config.h" +#include "utils.h" +#include "ads1220.h" +#include "fram.h" +#include "ModbusM.h" +#include "ModbusS.h" +#include "rotary_encoder.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_log.h" +#include "esp_log.h" +#include "esp_check.h" +#include "soc/rtc.h" +#include "driver/mcpwm.h" +#include "config.h" + +static const char *TAG = "depth"; + +typedef struct +{ + uint32_t capture_signal; + mcpwm_capture_signal_t sel_cap_signal; +} capture; + +typedef struct capture_event +{ + int ch; + uint32_t val; +} capture_event_t; + +// #define DEPTH_PIN_CLK GPIO_NUM_36 // 捕获GPIO端口 +// #define GPIO_PCNT_PIN_1 36 // Set GPIO 18 as phaseA/C1 +// #define GPIO_PCNT_PIN_2 35 // Set GPIO 19 as phaseB/C2 +// #define DEPTH_PIN_PULSE 36 //深度脉冲GPIO端口 +// #define DEPTH_PIN_CTRL 35 //深度控制GPIO端口 + +#define FLOW_SYNC_PIN 39 // 捕获GPIO端口 + +#define DEPTH_PIN_PULSE 9 // 深度脉冲GPIO端口 +#define DEPTH_PIN_CTRL 10 // 深度控制GPIO端口 +#define DEPTH_PIN_ENC_A 36 // 深度脉冲GPIO端口 +#define DEPTH_PIN_ENC_B 35 // 深度控制GPIO端口 + +// #define DEPTH_PIN_ENC_A 36 // 深度脉冲GPIO端口 +// #define DEPTH_PIN_ENC_B 35 // 深度控制GPIO端口 + +void add_recod_item(void); + +extern int get_total_flow_by_time(int ch, uint32_t time); +extern void zero_totalflow(int ch); + +extern void reset_depth(void); + +void capture_depth_init(); +extern flow_t *pflow; +extern uint16_t last_pile_id; +uint32_t enc1_update_time; +uint32_t _enc1_update_time; +int32_t enc1_value; + +uint32_t enc2_update_time; +uint32_t _enc2_update_time; +int32_t enc2_value; + +extern rotary_encoder_t *encoder; + +typedef struct +{ + int16_t max_depth; + uint16_t pile_id; + uint16_t count; + uint16_t work_time; + struct _item + { + int16_t speed; + int16_t depth; + int16_t flow[2]; + uint32_t total_flow[2]; + int16_t tilt_x; + int16_t tilt_y; + uint16_t current1; + uint16_t current2; + } item[10]; +} record_t; + +typedef struct +{ + int16_t up_down; // 12 + int16_t speed; // 13 + int16_t depth; // 14 + uint16_t sample_count; // 15 + uint16_t depth_flow[2]; // 16~17 + uint32_t last_total_flow[2]; // 18~21 + int16_t depth_offset; // 22 + // uint32_t update_time; + // int16_t tilt_x; + // int16_t tilt_y; + // uint16_t current1; + // uint16_t current2; + // uint16_t current3; +} depth_t; + +record_t *record = (record_t *)&gWordVar[RECORD_REG_ADDR]; +depth_t *depth_data = (depth_t *)&gWordVar[DEPTH_REG_ADDR]; + +move_t *pMoveCtx = (move_t *)&gWordVar[MOVE_REG_ADDR]; + +depth_config_t *depth_config = (depth_config_t *)&gWordVar[DEPTH_CONFIG_ADDR]; + +rotary_encoder_t *encoder = NULL; // 编码器测量深度参数 + +static uint32_t cap_val_begin_of_depth = 0; +static uint32_t cap_val_end_of_depth = 0; +extern uint32_t rtc_clk_apb_freq; +/** + * @brief this is an ISR callback, we take action according to the captured edge + */ +static bool depth_isr_handler(mcpwm_unit_t mcpwm, mcpwm_capture_channel_id_t cap_sig, const cap_event_data_t *edata, + void *arg) +{ + + // 双边沿触发中断,只有一个边缘会更新值,所以只有在值发生变化是才更新时间 + int value = encoder->get_counter_value(encoder); + if (value != enc1_value) + { + enc1_value = value; + enc1_update_time = edata->cap_value; + } + return false; +} + +void capture_depth_init() +{ + int pulse_pin; + if (depth_config->port) + { + pulse_pin = DEPTH_PIN_ENC_A; + } + else + { + pulse_pin = DEPTH_PIN_PULSE; + } + ESP_ERROR_CHECK(mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM_CAP_0, pulse_pin)); + // enable pull down CAP0, to reduce noise + ESP_ERROR_CHECK(gpio_pullup_en(pulse_pin)); + // enable both edge capture on CAP0 + mcpwm_capture_config_t conf = { + .cap_edge = MCPWM_NEG_EDGE, + .cap_prescale = 1, + .capture_cb = depth_isr_handler, // 绑定深度中断处理函数 + .user_data = NULL}; + if (depth_config->input_type > 1) + { + conf.cap_edge = MCPWM_BOTH_EDGE; + } + ESP_ERROR_CHECK(mcpwm_capture_enable_channel(MCPWM_UNIT_0, MCPWM_SELECT_CAP0, &conf)); + ESP_LOGI(TAG, "capture_depth_init"); +} + +void pcnt_rotary_encoder_init(void) +{ + // Rotary encoder underlying device is represented by a PCNT unit in this example + uint32_t pcnt_unit = 0; + int pulse_pin; + int ctrl_pin; + if (depth_config->port) + { + pulse_pin = DEPTH_PIN_ENC_A; + ctrl_pin = DEPTH_PIN_ENC_B; + } + else + { + pulse_pin = DEPTH_PIN_PULSE; + ctrl_pin = DEPTH_PIN_CTRL; + } + // Create rotary encoder instance + rotary_encoder_config_t config = ROTARY_ENCODER_DEFAULT_CONFIG((rotary_encoder_dev_t)pcnt_unit, pulse_pin, ctrl_pin); + config.flags = depth_config->input_type; + ESP_ERROR_CHECK(rotary_encoder_new_ec11(&config, &encoder)); + // Filter out glitch (1us) + ESP_ERROR_CHECK(encoder->set_glitch_filter(encoder, 10)); + // Start encoder + ESP_ERROR_CHECK(encoder->start(encoder)); +} + +void depth_init(void) +{ + // if (depth_config->input_type == 1) + // { // 电压型 方向+脉冲信号 使用比较器通道,IO口中断方式采集 + + // // GPIO_InitTypeDef GPIO_InitStruct = {0}; + // // /*Configure GPIO pin : PtPin */ + // // GPIO_InitStruct.Pin = ROLLER_DIR_Pin; + // // GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + // // GPIO_InitStruct.Pull = GPIO_PULLUP; + // // HAL_GPIO_Init(ROLLER_GPIO_Port, &GPIO_InitStruct); + + // // /*Configure GPIO pin : PtPin */ + // // GPIO_InitStruct.Pin = ROLLER_CLK_Pin; + // // GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; + // // GPIO_InitStruct.Pull = GPIO_PULLUP; + // // HAL_GPIO_Init(ROLLER_GPIO_Port, &GPIO_InitStruct); + // } + // else if (depth_config->input_type == 2) + // { // 电压型 正交编码器 使用比较器通道,TIM1编码器通道采集 + // MX_TIM1_Init(); + // pcnt_rotary_encoder_init(); // 编码器初始化 + // capture_depth_init(); + // HAL_TIM_Encoder_Start(&htim1, TIM_CHANNEL_ALL); + // } + // else if (depth_config->input_type == 3) + // { // 开漏输出 正交编码器 使用光耦输入通道,TIM3编码器通道采集 + // // MX_TIM3_Init(); + // // HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL); + // } + depth_data->depth_offset = -depth_config->depth_offset; + depth_data->up_down = 1; // 默认工作 +} + +enum +{ + REST = -1, + STOP = 0, + DOWN = 1, + UP = 2, +}; + +int last_enc_value = 0; +uint32_t _enc_update_time; +uint32_t enc_update_time; +int last_sample_depth = 0; +int last_flow[2] = {0}; +int16_t prev_depth = 0; +uint32_t prev_update_time = 0; +int16_t target_sample_depth = 0; + +// 正交编码器的深度 : encoder->get_counter_value(encoder) + +int abs_sub(uint32_t enc_update_time, uint32_t _enc_update_time) +{ + if (enc_update_time >= _enc_update_time) + { + return enc_update_time - _enc_update_time; + } + else + { + return (0xffffffff - _enc_update_time + enc_update_time + 1); + } +} + +void depth_task(void) +{ + // int enc_value; + int time_diff = 0; + int speed_timeout = 0; + int last_speed_enc_value = 0; // 上次速度计算的编码器值 + int speed_enc_update_time = 0; // 上次速度计算的编码器值 + int speed_calc_count = 0; + int enc_value = 0; + int count = 0; + depth_data->depth_offset = -depth_config->depth_offset; + depth_data->up_down = 1; // 默认工作 + record->pile_id = ++last_pile_id; + gWordVar[LAST_PILE_ID_ADDR] = last_pile_id; + while (1) + { + if (_enc1_update_time != enc1_update_time) + { + // int enc_update_time = enc1_update_time; + enc_update_time = enc1_update_time; + enc_value = enc1_value; + time_diff = abs_sub(enc_update_time, _enc1_update_time); + _enc1_update_time = enc_update_time; + } + // } + if (time_diff != 0) + { + int16_t depth = enc_value * depth_config->N / depth_config->M; // 1mm + depth_data->depth = depth - depth_data->depth_offset; + if (depth_data->depth > depth_config->max_depth) + { + depth_data->depth_offset = depth - depth_config->max_depth; + depth_data->depth = depth_config->max_depth; + } + else if (depth_data->depth < depth_config->min_depth) + { + depth_data->depth_offset = depth - depth_config->min_depth; + depth_data->depth = depth_config->min_depth; + } + if (depth_data->depth > record->max_depth) + { + record->max_depth = depth_data->depth; + } + if (speed_calc_count++ > 50) // 500ms计算一次速度 + { + speed_calc_count = 0; + int speed_time_diff = abs_sub(enc_update_time, speed_enc_update_time); + int time_diff_us = speed_time_diff / (APB_CLK_FREQ / 1000000); + if (time_diff_us > 0 && time_diff_us < 5000000) + { + ESP_LOGI(TAG, "time_diff_us:%d,dist_diff=%d", time_diff_us, enc_value - last_speed_enc_value); + // speed = dist_diff / speed_time_diff speed 单位mm/min dist_diff 单位mm speed_time_diff 单位us + depth_data->speed = (enc_value - last_speed_enc_value) * depth_config->N / depth_config->M * 600000ll / time_diff_us; + speed_timeout = 0; + speed_enc_update_time = enc_update_time; + last_speed_enc_value = enc_value; + } + else + { + if (++speed_timeout > 10) + { + depth_data->speed = 0; + speed_timeout = 0; + speed_enc_update_time = enc_update_time; + last_speed_enc_value = enc_value; + } + } + } + if (depth_data->up_down > STOP) + { + if (enc_value > last_enc_value) + { // 下钻,深度增加 + if (depth_data->up_down != 1) + { // 方向改变 + depth_data->up_down = 1; + target_sample_depth = (depth_data->depth / depth_config->sample_depth) * depth_config->sample_depth; + if (abs(depth_data->depth - target_sample_depth) < depth_config->sample_depth / 2) + { // 小于半个采样长度的合并到下一个采样点 + target_sample_depth += depth_config->sample_depth; + } + } + if (depth_data->depth >= target_sample_depth) + { // 到达或超过目标采样点 + // 由于编码器精度问题不能确保数据在采样点上,需要通过插值计算采样点 + // 当使用10线编码器时每个脉冲深度达6.25cm,当采样间隔为10cm时抖动值太大 + if ((prev_depth - depth_data->depth) != 0) + { + int i; + uint32_t time = (target_sample_depth - prev_depth) * (enc_update_time - prev_update_time) / (depth_data->depth - prev_depth) + prev_update_time; + for (i = 0; i < 2; i++) + { + // int total_flow = get_total_flow_by_time(i, time); + int total_flow = get_total_flow_by_time(i, pflow[i].update_time); + int flow = total_flow - depth_data->last_total_flow[i]; + if (flow < 0) + { + flow = 0; + } + depth_data->depth_flow[i] = flow; + depth_data->last_total_flow[i] = total_flow; + } + depth_data->sample_count++; + target_sample_depth += depth_config->sample_depth; + add_recod_item(); + } + } + } + else if (enc_value < last_enc_value) + { + if (depth_data->up_down != 2) + { // 方向改变 + depth_data->up_down = 2; + // target_sample_depth -= depth_config->sample_depth; + target_sample_depth = (depth_data->depth / depth_config->sample_depth - 1) * depth_config->sample_depth; + if (abs(depth_data->depth - target_sample_depth) < depth_config->sample_depth / 2) + { // 小于半个采样长度的合并到下一个采样点 + target_sample_depth -= depth_config->sample_depth; + } + } + if (depth_data->depth <= target_sample_depth) + { + // 由于编码器精度问题不能确保数据在采样点上,需要通过插值计算采样点 + // 当使用10线编码器时每个脉冲深度达7.6cm,当采样间隔为10cm时抖动值太大 + if ((prev_depth - depth_data->depth) != 0) + { + int i; + uint32_t time = (prev_depth - target_sample_depth) * (enc_update_time - prev_update_time) / (prev_depth - depth_data->depth) + prev_update_time; + for (i = 0; i < 2; i++) + { + // int total_flow = get_total_flow_by_time(i, time); + int total_flow = get_total_flow_by_time(i, pflow[i].update_time); + int flow = total_flow - depth_data->last_total_flow[i]; + if (flow < 0) + { + flow = 0; + } + depth_data->depth_flow[i] = flow; + depth_data->last_total_flow[i] = total_flow; + } + depth_data->sample_count++; + add_recod_item(); + target_sample_depth -= depth_config->sample_depth; + } + } + } + else + { + // depth_data->up_down = 0; + } + if (depth_data->depth < depth_config->inc_pile_depth) // 小于指定深度时才允许行走清零 + { + if (pMoveCtx->pile_inc_req == 1) + { + pMoveCtx->pile_inc_req = 0; + reset_depth(); + } + } + else + { + if (pMoveCtx->pile_inc_req == 1) + { + pMoveCtx->pile_inc_req = 0; + } + } + } + prev_depth = depth_data->depth; + prev_update_time = enc_update_time; + last_enc_value = enc_value; + } + + // if (++count > 100) + // { + // count = 0; + // ESP_LOGI(TAG, "encoder:%d", encoder->get_counter_value(encoder)); + // } + vTaskDelay(10); + } +} + +void add_recod_item(void) +{ + record->count = depth_data->sample_count; + memmove(&record->item[1], &record->item[0], sizeof(record->item[0]) * 9); + record->item[0].flow[0] = depth_data->depth_flow[0]; + record->item[0].flow[1] = depth_data->depth_flow[1]; + record->item[0].total_flow[0] = depth_data->last_total_flow[0]; + record->item[0].total_flow[1] = depth_data->last_total_flow[1]; + if (depth_config->move_current_channel == 2) // 1 + { + record->item[0].current1 = gWordVar[AC_CURRENT_REG_ADDR]; + record->item[0].current2 = gWordVar[AC_CURRENT_REG_ADDR + 1]; + } + else if (depth_config->move_current_channel == 1) + { + record->item[0].current1 = gWordVar[AC_CURRENT_REG_ADDR]; + record->item[0].current2 = gWordVar[AC_CURRENT_REG_ADDR + 2]; + } + else + { + record->item[0].current1 = gWordVar[AC_CURRENT_REG_ADDR + 1]; + record->item[0].current2 = gWordVar[AC_CURRENT_REG_ADDR + 2]; + } + + record->item[0].tilt_x = (short)gWordVar[TILT_SENSER_ADDR]; + record->item[0].tilt_y = (short)gWordVar[TILT_SENSER_ADDR + 1]; + record->item[0].speed = depth_data->speed; + record->item[0].depth = depth_data->depth; +} +extern int zero_totalflow_req; +extern void save_pile_id(void); +void reset_depth(void) +{ + uint16_t pile_id; + last_sample_depth = 0; + last_flow[0] = 0; + last_flow[1] = 0; + prev_depth = 0; + prev_update_time = 0; + target_sample_depth = 0; + zero_totalflow_req = 1; + if (record->count > 0) + { + record->count = 0; + memset(record->item, 0, sizeof(record->item)); + } + memset(depth_data, 0, sizeof(*depth_data)); + if (record->max_depth >= depth_config->min_valid_depth) // 上一个桩有一定深度数据 + { + save_pile_id(); + last_pile_id++; + gWordVar[LAST_PILE_ID_ADDR] = last_pile_id; + } + memset(record, 0, sizeof(*record)); + record->pile_id = last_pile_id; + ec11_pcnt_clear(0); + depth_data->depth_offset = -depth_config->depth_offset; + depth_data->depth = depth_config->depth_offset; + enc1_value = 0; + enc1_update_time = 0; + depth_data->up_down = 1; // 默认工作 +} + +void DEPTH_init() +{ + + // depth_init(); + + pcnt_rotary_encoder_init(); + capture_depth_init(); + xTaskCreate(depth_task, "depth_task", 4096, NULL, 10, NULL); +} \ No newline at end of file diff --git a/main/stm32/flow.c b/main/stm32/flow.c new file mode 100644 index 0000000..f9fdcea --- /dev/null +++ b/main/stm32/flow.c @@ -0,0 +1,316 @@ +#include "stdlib.h" +#include "utils.h" +#include "config.h" +#include "ads1220.h" +#include "fram.h" +#include "modbuss.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_check.h" +#include "soc/rtc.h" +#include "driver/mcpwm.h" +int zero_totalflow_req = 0; +const static char *TAG = "flow"; + + +typedef struct capture_event +{ + int ch; + uint32_t val; +} capture_event_t; + +#define FLOW1_PIN_ECHO GPIO_NUM_9 // 捕获GPIO端口 +#define FLOW2_PIN_ECHO GPIO_NUM_10 // 捕获GPIO端口 +#define DEPTH_PIN_ECHO GPIO_NUM_35 // 捕获GPIO端口 + +#define TRIGGER_THREAD_PRIORITY 5 + +extern int abs_sub(uint32_t enc_update_time, uint32_t _enc_update_time); + +typedef struct +{ + uint32_t capture_signal; + mcpwm_capture_signal_t sel_cap_signal; +} capture; + +static uint32_t cap_val_begin_of_flow1 = 0; +static uint32_t cap_val_end_of_flow1 = 0; +static uint32_t cap_val_begin_of_flow2 = 0; +static uint32_t cap_val_end_of_flow2 = 0; + +static xQueueHandle cap_queue; +extern uint32_t rtc_clk_apb_freq; +uint32_t volatile t15_ccr[2]; +uint16_t volatile t15_ccr_times[2]; + +cal_4_20ma_t *cal_4_20ma = (cal_4_20ma_t *)&gWordVar[CAL_4_20MA_ADDR]; +flow_config_t *flow_config = (flow_config_t *)&gWordVar[FLOW_CONFIG_ADDR]; +flow_t *pflow = (flow_t *)&gWordVar[FLOW_REG_ADDR]; +void capture_flow1_init(); +void capture_flow2_init(); +extern void ADS1220_Init(void); + +uint32_t volatile last_ccr[2] = {0}; + +extern int ad_value[4]; +extern int ad_update_time[4]; + +extern uint8_t ad_watchdog_cnt; + +extern int ad_values[4]; +extern int ad_update_time[4]; +uint32_t flow_update_time[2]; +uint8_t timeout[2] = {0}; +int flow_rem[2] = {0}; + +static bool flow1_isr_handler(mcpwm_unit_t mcpwm, mcpwm_capture_channel_id_t cap_sig, const cap_event_data_t *edata, + void *arg) +{ + // calculate the interval in the ISR, + // so that the interval will be always correct even when cap_queue is not handled in time and overflow. + BaseType_t high_task_wakeup = pdFALSE; + + t15_ccr[0] = edata->cap_value; + t15_ccr_times[0]++; + return high_task_wakeup == pdFALSE; +} + +void capture_flow1_init() +{ + ESP_ERROR_CHECK(mcpwm_gpio_init(MCPWM_UNIT_1, MCPWM_CAP_1, FLOW1_PIN_ECHO)); + // enable pull down CAP0, to reduce noise + ESP_ERROR_CHECK(gpio_pulldown_en(FLOW1_PIN_ECHO)); + // enable both edge capture on CAP0 + mcpwm_capture_config_t conf = { + .cap_edge = MCPWM_NEG_EDGE, + .cap_prescale = 1, + .capture_cb = flow1_isr_handler, // 绑定流量捕获中断处理函数 + .user_data = NULL}; + ESP_ERROR_CHECK(mcpwm_capture_enable_channel(MCPWM_UNIT_1, MCPWM_SELECT_CAP1, &conf)); + ESP_LOGI(TAG, "capture_flow_init"); +} + +static bool flow2_isr_handler(mcpwm_unit_t mcpwm, mcpwm_capture_channel_id_t cap_sig, const cap_event_data_t *edata, + void *arg) +{ + // calculate the interval in the ISR, + // so that the interval will be always correct even when cap_queue is not handled in time and overflow. + BaseType_t high_task_wakeup = pdFALSE; + + t15_ccr[1] = edata->cap_value; + // t15_ccr_times[1] = cap_event.val * (1000000.0 / rtc_clk_apb_freq); + t15_ccr_times[1]++; + // send measurement back though queue + // xQueueSendFromISR(cap_queue, &cap_event, &high_task_wakeup); + + return high_task_wakeup == pdFALSE; +} + +void capture_flow2_init() +{ + ESP_ERROR_CHECK(mcpwm_gpio_init(MCPWM_UNIT_1, MCPWM_CAP_2, FLOW2_PIN_ECHO)); + // enable pull down CAP0, to reduce noise + ESP_ERROR_CHECK(gpio_pulldown_en(FLOW2_PIN_ECHO)); + // enable both edge capture on CAP0 + mcpwm_capture_config_t conf = { + .cap_edge = MCPWM_NEG_EDGE, + .cap_prescale = 1, + .capture_cb = flow2_isr_handler, // 绑定流量捕获中断处理函数 + .user_data = NULL}; + ESP_ERROR_CHECK(mcpwm_capture_enable_channel(MCPWM_UNIT_1, MCPWM_SELECT_CAP2, &conf)); + ESP_LOGI(TAG, "capture_flow_init"); +} + +// void capture_task(void) +// { +// while (true) { +// capture_event_t cap_event = {.val = 0, .ch = 1}; +// uint32_t pulse_width_us = 0; +// // block and wait for new measurement +// // ESP_LOGI(TAG, "xQueueReceive started"); +// xQueueReceive(cap_queue, &cap_event, portMAX_DELAY); +// // ESP_LOGI(TAG, "xQueueReceive after"); +// // ESP_LOGI(TAG, " cap_event.val: %d, cap_event.ch : %d", cap_event.val, cap_event.ch); +// switch (cap_event.ch) +// { +// case 1: //flow1 capture +// pulse_width_us = cap_event.val * (1000000.0 / rtc_clk_apb_freq); + +// ESP_LOGI(TAG, " (flow1 capture) Pulse width: %uus", pulse_width_us); +// break; +// case 2: //flow2 capture +// pulse_width_us = cap_event.val * (1000000.0 / rtc_clk_apb_freq); +// ESP_LOGI(TAG, "(flow2 capture) Pulse width: %uus", pulse_width_us); +// break; +// default: ESP_LOGI(TAG, " default\n"); +// break; +// } +// } +// } + +void flow_init(void) +{ + // 流量 初始化捕获定时器 + + // capture_flow2_init(); + // MX_TIM15_Init(); + // HAL_TIM_Base_Start_IT(&htim15); + if (flow_config->input_type == 1) + { // 4~20ma + // ADS1220_Init(); + } + else if (flow_config->input_type == 2) + { // freq + // HAL_TIM_IC_Start_IT(&htim15, TIM_CHANNEL_1); + // HAL_TIM_IC_Start_IT(&htim15, TIM_CHANNEL_2); + capture_flow1_init(); + capture_flow2_init(); + } +} +extern void zero_totalflow(int ch); +void flow_task(void) +{ + static uint32_t cp_flow_tick = 0; + static uint32_t ad_flow_tick = 100; + int lock_time_out = 0; + while (1) + { + vTaskDelay(50); + + if (flow_config->input_type == 2 && TickDiff(cp_flow_tick) > 100) + { + int ch; + cp_flow_tick = xTaskGetTickCount(); + for (ch = 0; ch < 2; ch++) + { + if (t15_ccr_times[ch] > 0) + { + int ccr_times; + int time_diff; + uint32_t ccr; + // __disable_irq(); + ccr_times = t15_ccr_times[ch]; + + t15_ccr_times[ch] = 0; + ccr = t15_ccr[ch]; + ccr = ccr / (rtc_clk_apb_freq / 1000000); + // __enable_irq(); + time_diff = ccr - last_ccr[ch]; + ESP_LOGI(TAG, "(type2) t15_ccr_times[%d]: %u %u time_diff: %u", ch, ccr, ccr_times, time_diff); + printf("rtc_clk_apb_freq : %u\n", rtc_clk_apb_freq); + if (time_diff != 0) + { + int t_flow; + + pflow[ch].flow_ = flow_config->pulse_coef[ch] * 600 * (int64_t)ccr_times / time_diff; + if (pflow[ch].flow_ < flow_config->min_flow[ch]) + { + pflow[ch].flow = 0; + } + else + { + pflow[ch].flow = pflow[ch].flow_; + } + t_flow = pflow[ch].flow * time_diff / (5 * 60); + flow_rem[ch] += t_flow; + pflow[ch].total_flow += flow_rem[ch] / 10000; + flow_rem[ch] = flow_rem[ch] % 10000; + pflow[ch].update_time = ccr; + last_ccr[ch] = ccr; + timeout[ch] = 0; + // ESP_LOGI(TAG, "(type2) pflow[%d].flow: %u", ch ,pflow[ch].flow); + } + } + if (++timeout[ch] > 5) + { + timeout[ch] = 0; + pflow[ch].flow = 0; + pflow[ch].flow_ = 0; + } + } + } + if (flow_config->input_type == 1 && TickDiff(ad_flow_tick) > 200) + { + int i; + ad_flow_cal_t *cal = flow_config->ad_cal; + ad_flow_tick = xTaskGetTickCount(); + for (i = 0; i < 2; i++) + { + int ad_ch = i * 2 + 1; + int time_diff = abs_sub(ad_update_time[ad_ch], pflow[i].update_time); + if (time_diff != 0) + { + int t_flow; // time_diff时间段总流量 + pflow[i].flow_ = scale(ad_value[ad_ch], cal_4_20ma->ch[i].ad_4ma, cal_4_20ma->ch[i].ad_20ma, cal[i].flow_min, cal[i].flow_max); + if (pflow[i].flow_ < flow_config->min_flow[i]) + { + pflow[i].flow = 0; + } + else + { + pflow[i].flow = pflow[i].flow_; + } + // 累计流量计算 pflow[i].flow 单位为0.01L/分钟 time_diff 单位为20uS + // flow = pflow[i].flow / 60.0 * 10000; 将流量换算成uL/s + // t_diff = time_diff / 50000 将时间差换算成秒 + // t_flow = flow * t_diff 计算t_diff时间段的流量 单位uL + // 取出0.01L的整数部分累加,余数部分和下次值累加 + // t_flow = pflow[i].flow * 1000 * time_diff / 500000 / 60; + int time_diff_us = time_diff / (APB_CLK_FREQ / 1000000); + t_flow = pflow[i].flow * time_diff_us / 60 / 100; + flow_rem[i] += t_flow; + pflow[i].total_flow += flow_rem[i] / 10000; + flow_rem[i] = flow_rem[i] % 10000; + pflow[i].update_time = ad_update_time[ad_ch]; + timeout[i] = 0; + ESP_LOGI(TAG, "(type1) flow_rem[%d].flow: %u", i, pflow[i].flow); + } + if (++timeout[i] > 10) + { + timeout[i] = 0; + pflow[i].flow = 0; + pflow[i].flow_ = 0; + } + } + } + if(zero_totalflow_req){ + zero_totalflow_req = 0; + zero_totalflow(0); + zero_totalflow(1); + } + } +} + +// 获取给定时刻累计流量 +int get_total_flow_by_time(int ch, uint32_t time) +{ + int delta_t; + int delta_flow; + if (ch > 1) + { + return 0; + } + delta_t = abs_sub(time, pflow[ch].update_time) / (APB_CLK_FREQ / 1000000); // 换算成us + delta_flow = pflow[ch].flow * delta_t / 60 / 100; + return pflow[ch].total_flow + delta_flow; +} + +void zero_totalflow(int ch) +{ + if (ch > 1) + { + return; + } + pflow[ch].total_flow = 0; + flow_rem[ch] = 0; +} + +void FLOW_init() +{ + flow_init(); + xTaskCreate(flow_task, "flow_task", 4096, NULL, 10, NULL); +} diff --git a/main/stm32/fram.c b/main/stm32/fram.c new file mode 100644 index 0000000..d7da455 --- /dev/null +++ b/main/stm32/fram.c @@ -0,0 +1,131 @@ +#include "fram.h" +#include "string.h" + +#include +#include "esp_log.h" +#include "driver/i2c.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "sdkconfig.h" + +static const char *TAG = "i2c-simple-example"; + +#define I2C_MASTER_SCL_IO 1 /*!< GPIO number used for I2C master clock */ +#define I2C_MASTER_SDA_IO 2 /*!< GPIO number used for I2C master data */ +#define I2C_MASTER_NUM 0 /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */ +#define I2C_MASTER_FREQ_HZ 400000 /*!< I2C master clock frequency */ +#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ +#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ +#define I2C_MASTER_TIMEOUT_MS 1000 + +#define MPU9250_SENSOR_ADDR 0x68 /*!< Slave address of the MPU9250 sensor */ +#define MPU9250_WHO_AM_I_REG_ADDR 0x75 /*!< Register addresses of the "who am I" register */ + +#define MPU9250_PWR_MGMT_1_REG_ADDR 0x6B /*!< Register addresses of the power managment register */ +#define MPU9250_RESET_BIT 7 + +#define WRITE_BIT I2C_MASTER_WRITE +#define ACK_CHECK_EN 0x1 +#define TAG "FREM" + +/** + * @brief Read a sequence of bytes from a MPU9250 sensor registers + */ +// static esp_err_t mpu9250_register_read(uint8_t reg_addr, uint8_t *data, size_t len) +// { +// return i2c_master_write_read_device(I2C_MASTER_NUM, MPU9250_SENSOR_ADDR, ®_addr, 1, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); +// } + +/** + * @brief Write a byte to a MPU9250 sensor register + */ +// static esp_err_t mpu9250_register_write_byte(uint8_t reg_addr, uint8_t data) +// { +// int ret; +// uint8_t write_buf[2] = {reg_addr, data}; + +// ret = i2c_master_write_to_device(I2C_MASTER_NUM, MPU9250_SENSOR_ADDR, write_buf, sizeof(write_buf), I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); + +// return ret; +// } + +/** + * @brief i2c master initialization + */ +esp_err_t i2c_master_init(void) +{ + int i2c_master_port = I2C_MASTER_NUM; + + i2c_config_t conf = { + .mode = I2C_MODE_MASTER, + .sda_io_num = I2C_MASTER_SDA_IO, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_pullup_en = GPIO_PULLUP_ENABLE, + .scl_pullup_en = GPIO_PULLUP_ENABLE, + .master.clk_speed = I2C_MASTER_FREQ_HZ, + }; + + i2c_param_config(i2c_master_port, &conf); + + return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); +} + +int fram_write(uint16_t addr, void * buf,uint32_t len) +{ + esp_err_t ret; + uint8_t slave_addr = (0xA0) | ((addr >> 8) & 0x7);/*page select*/ + uint8_t low_addr = addr &0xff; + // return HAL_I2C_Mem_Write(&hi2c1,slave_addr,addr&0xff,I2C_MEMADD_SIZE_8BIT,buf,len,200); + // ret = i2c_master_write_to_device(I2C_MASTER_NUM, slave_addr, txbuf, len+1, 10); + // // ret = i2c_master_write_read_device(I2C_MASTER_NUM, slave_addr, buf, len, 10); + // // assert(ret == ESP_OK); + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, slave_addr | WRITE_BIT, ACK_CHECK_EN); + i2c_master_write(cmd, &low_addr, 1, ACK_CHECK_EN); + i2c_master_write(cmd, buf, len, ACK_CHECK_EN); + i2c_master_stop(cmd); + ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS); + if (ret != ESP_OK) { + printf("esp_err : %s \n", esp_err_to_name(ret)); + return ret; + } + i2c_cmd_link_delete(cmd); + return ret; +} +int fram_read(uint16_t addr,void * buf,uint32_t len) +{ + // esp_err_t err = i2c_param_config(i2c_master_port, &conf); + + esp_err_t ret; + uint8_t slave_addr = (0xA0>>1) | ((addr >> 8) & 0x7);/*page select*/ + uint8_t low_addr = addr &0xff; + // return HAL_I2C_Mem_Read(&hi2c1,slave_addr,addr&0xff,I2C_MEMADD_SIZE_8BIT,buf,len,200); + ret = i2c_master_write_read_device(I2C_MASTER_NUM, slave_addr, &low_addr,1, buf, len, 10); + if (ret != ESP_OK) { + ESP_LOGE(TAG,"esp_err : %s \n", esp_err_to_name(ret)); + return ret; + } + ESP_LOGI(TAG,"fram_read succeed\n"); + // ESP_LOGI(TAG, "buf value : %d \n ", buf[0]); + return 0; +} + +void save_para(void) +{ + +} +void save_encode(void) +{ + +} +void read_para() +{ + +} + +void clear_para() +{ + +} diff --git a/main/stm32/fram.h b/main/stm32/fram.h new file mode 100644 index 0000000..7c680d2 --- /dev/null +++ b/main/stm32/fram.h @@ -0,0 +1,31 @@ +#ifndef FRAM_H__ +#define FRAM_H__ + + + +// #include "main.h" +// #include "i2c.h" +#include +#include "esp_log.h" +#include "driver/i2c.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "esp_err.h" + + + +int fram_write(uint16_t addr, void * buf,uint32_t len); +int fram_read(uint16_t addr,void * buf,uint32_t len); +//extern void fram_write_para(fram_para_t *para,uint32_t len); +//extern void fram_read_para(fram_para_t *para,uint32_t len); + + +void save_para(void); +void save_encode(void); +void read_para(void); +void clear_para(void); +#endif + + diff --git a/main/stm32/master.c b/main/stm32/master.c new file mode 100644 index 0000000..0c6273e --- /dev/null +++ b/main/stm32/master.c @@ -0,0 +1,296 @@ +// Copyright 2016-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "string.h" +#include "esp_log.h" +#include "modbus_params.h" // for modbus parameters structures +#include "mbcontroller.h" +#include "sdkconfig.h" + +#define MB_PORT_NUM (CONFIG_MB_UART_PORT_NUM) // Number of UART port used for Modbus connection +#define MB_DEV_SPEED (CONFIG_MB_UART_BAUD_RATE) // The communication speed of the UART + +// Note: Some pins on target chip cannot be assigned for UART communication. +// See UART documentation for selected board and target to configure pins using Kconfig. + +// The number of parameters that intended to be used in the particular control process +#define MASTER_MAX_CIDS num_device_parameters + +// Number of reading of parameters from slave +#define MASTER_MAX_RETRY 30 + +// Timeout to update cid over Modbus +#define UPDATE_CIDS_TIMEOUT_MS (500) +#define UPDATE_CIDS_TIMEOUT_TICS (UPDATE_CIDS_TIMEOUT_MS / portTICK_RATE_MS) + +// Timeout between polls +#define POLL_TIMEOUT_MS (1) +#define POLL_TIMEOUT_TICS (POLL_TIMEOUT_MS / portTICK_RATE_MS) + +// The macro to get offset for parameter in the appropriate structure +#define HOLD_OFFSET(field) ((uint16_t)(offsetof(holding_reg_params_t, field) + 1)) +#define INPUT_OFFSET(field) ((uint16_t)(offsetof(input_reg_params_t, field) + 1)) +#define COIL_OFFSET(field) ((uint16_t)(offsetof(coil_reg_params_t, field) + 1)) +// Discrete offset macro +#define DISCR_OFFSET(field) ((uint16_t)(offsetof(discrete_reg_params_t, field) + 1)) + +#define STR(fieldname) ((const char*)( fieldname )) +// Options can be used as bit masks or parameter limits +#define OPTS(min_val, max_val, step_val) { .opt1 = min_val, .opt2 = max_val, .opt3 = step_val } + +static const char *TAG = "MASTER_TEST"; + +// Enumeration of modbus device addresses accessed by master device +enum { + MB_DEVICE_ADDR1 = 1 // Only one slave device used for the test (add other slave addresses here) +}; + +// Enumeration of all supported CIDs for device (used in parameter definition table) +enum { + CID_INP_DATA_0 = 0, + CID_HOLD_DATA_0, + CID_INP_DATA_1, + CID_HOLD_DATA_1, + CID_INP_DATA_2, + CID_HOLD_DATA_2, + CID_HOLD_TEST_REG, + CID_RELAY_P1, + CID_RELAY_P2, + CID_COUNT +}; + +// Example Data (Object) Dictionary for Modbus parameters: +// The CID field in the table must be unique. +// Modbus Slave Addr field defines slave address of the device with correspond parameter. +// Modbus Reg Type - Type of Modbus register area (Holding register, Input Register and such). +// Reg Start field defines the start Modbus register number and Reg Size defines the number of registers for the characteristic accordingly. +// The Instance Offset defines offset in the appropriate parameter structure that will be used as instance to save parameter value. +// Data Type, Data Size specify type of the characteristic and its data size. +// Parameter Options field specifies the options that can be used to process parameter value (limits or masks). +// Access Mode - can be used to implement custom options for processing of characteristic (Read/Write restrictions, factory mode values and etc). +const mb_parameter_descriptor_t device_parameters[] = { + // { CID, Param Name, Units, Modbus Slave Addr, Modbus Reg Type, Reg Start, Reg Size, Instance Offset, Data Type, Data Size, Parameter Options, Access Mode} + { CID_INP_DATA_0, STR("Data_channel_0"), STR("Volts"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0, 2, + INPUT_OFFSET(input_data0), PARAM_TYPE_FLOAT, 4, OPTS( -10, 10, 1 ), PAR_PERMS_READ_WRITE_TRIGGER }, + { CID_HOLD_DATA_0, STR("Humidity_1"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0, 2, + HOLD_OFFSET(holding_data0), PARAM_TYPE_FLOAT, 4, OPTS( 0, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER }, + { CID_INP_DATA_1, STR("Temperature_1"), STR("C"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 2, 2, + INPUT_OFFSET(input_data1), PARAM_TYPE_FLOAT, 4, OPTS( -40, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER }, + { CID_HOLD_DATA_1, STR("Humidity_2"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 2, 2, + HOLD_OFFSET(holding_data1), PARAM_TYPE_FLOAT, 4, OPTS( 0, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER }, + { CID_INP_DATA_2, STR("Temperature_2"), STR("C"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 4, 2, + INPUT_OFFSET(input_data2), PARAM_TYPE_FLOAT, 4, OPTS( -40, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER }, + { CID_HOLD_DATA_2, STR("Humidity_3"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 4, 2, + HOLD_OFFSET(holding_data2), PARAM_TYPE_FLOAT, 4, OPTS( 0, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER }, + { CID_HOLD_TEST_REG, STR("Test_regs"), STR("__"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 10, 58, + HOLD_OFFSET(test_regs), PARAM_TYPE_ASCII, 116, OPTS( 0, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER }, + { CID_RELAY_P1, STR("RelayP1"), STR("on/off"), MB_DEVICE_ADDR1, MB_PARAM_COIL, 0, 8, + COIL_OFFSET(coils_port0), PARAM_TYPE_U16, 2, OPTS( BIT1, 0, 0 ), PAR_PERMS_READ_WRITE_TRIGGER }, + { CID_RELAY_P2, STR("RelayP2"), STR("on/off"), MB_DEVICE_ADDR1, MB_PARAM_COIL, 8, 8, + COIL_OFFSET(coils_port1), PARAM_TYPE_U16, 2, OPTS( BIT0, 0, 0 ), PAR_PERMS_READ_WRITE_TRIGGER } +}; + +// Calculate number of parameters in the table +const uint16_t num_device_parameters = (sizeof(device_parameters)/sizeof(device_parameters[0])); + +// The function to get pointer to parameter storage (instance) according to parameter description table +static void* master_get_param_data(const mb_parameter_descriptor_t* param_descriptor) +{ + assert(param_descriptor != NULL); + void* instance_ptr = NULL; + if (param_descriptor->param_offset != 0) { + switch(param_descriptor->mb_param_type) + { + case MB_PARAM_HOLDING: + instance_ptr = ((void*)&holding_reg_params + param_descriptor->param_offset - 1); + break; + case MB_PARAM_INPUT: + instance_ptr = ((void*)&input_reg_params + param_descriptor->param_offset - 1); + break; + case MB_PARAM_COIL: + instance_ptr = ((void*)&coil_reg_params + param_descriptor->param_offset - 1); + break; + case MB_PARAM_DISCRETE: + instance_ptr = ((void*)&discrete_reg_params + param_descriptor->param_offset - 1); + break; + default: + instance_ptr = NULL; + break; + } + } else { + ESP_LOGE(TAG, "Wrong parameter offset for CID #%d", param_descriptor->cid); + assert(instance_ptr != NULL); + } + return instance_ptr; +} + +// User operation function to read slave values and check alarm +static void master_operation_func(void *arg) +{ + esp_err_t err = ESP_OK; + float value = 0; + bool alarm_state = false; + const mb_parameter_descriptor_t* param_descriptor = NULL; + + ESP_LOGI(TAG, "Start modbus test..."); + + for(uint16_t retry = 0; retry <= MASTER_MAX_RETRY && (!alarm_state); retry++) { + // Read all found characteristics from slave(s) + for (uint16_t cid = 0; (err != ESP_ERR_NOT_FOUND) && cid < MASTER_MAX_CIDS; cid++) + { + // Get data from parameters description table + // and use this information to fill the characteristics description table + // and having all required fields in just one table + err = mbc_master_get_cid_info(cid, ¶m_descriptor); + if ((err != ESP_ERR_NOT_FOUND) && (param_descriptor != NULL)) { + void* temp_data_ptr = master_get_param_data(param_descriptor); + assert(temp_data_ptr); + uint8_t type = 0; + if ((param_descriptor->param_type == PARAM_TYPE_ASCII) && + (param_descriptor->cid == CID_HOLD_TEST_REG)) { + // Check for long array of registers of type PARAM_TYPE_ASCII + err = mbc_master_get_parameter(cid, (char*)param_descriptor->param_key, + (uint8_t*)temp_data_ptr, &type); + if (err == ESP_OK) { + ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = (0x%08x) read successful.", + param_descriptor->cid, + (char*)param_descriptor->param_key, + (char*)param_descriptor->param_units, + *(uint32_t*)temp_data_ptr); + // Initialize data of test array and write to slave + if (*(uint32_t*)temp_data_ptr != 0xAAAAAAAA) { + memset((void*)temp_data_ptr, 0xAA, param_descriptor->param_size); + *(uint32_t*)temp_data_ptr = 0xAAAAAAAA; + err = mbc_master_set_parameter(cid, (char*)param_descriptor->param_key, + (uint8_t*)temp_data_ptr, &type); + if (err == ESP_OK) { + ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = (0x%08x), write successful.", + param_descriptor->cid, + (char*)param_descriptor->param_key, + (char*)param_descriptor->param_units, + *(uint32_t*)temp_data_ptr); + } else { + ESP_LOGE(TAG, "Characteristic #%d (%s) write fail, err = 0x%x (%s).", + param_descriptor->cid, + (char*)param_descriptor->param_key, + (int)err, + (char*)esp_err_to_name(err)); + } + } + } else { + ESP_LOGE(TAG, "Characteristic #%d (%s) read fail, err = 0x%x (%s).", + param_descriptor->cid, + (char*)param_descriptor->param_key, + (int)err, + (char*)esp_err_to_name(err)); + } + } else { + err = mbc_master_get_parameter(cid, (char*)param_descriptor->param_key, + (uint8_t*)&value, &type); + if (err == ESP_OK) { + *(float*)temp_data_ptr = value; + if ((param_descriptor->mb_param_type == MB_PARAM_HOLDING) || + (param_descriptor->mb_param_type == MB_PARAM_INPUT)) { + ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %f (0x%x) read successful.", + param_descriptor->cid, + (char*)param_descriptor->param_key, + (char*)param_descriptor->param_units, + value, + *(uint32_t*)temp_data_ptr); + if (((value > param_descriptor->param_opts.max) || + (value < param_descriptor->param_opts.min))) { + alarm_state = true; + break; + } + } else { + uint16_t state = *(uint16_t*)temp_data_ptr; + const char* rw_str = (state & param_descriptor->param_opts.opt1) ? "ON" : "OFF"; + ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %s (0x%x) read successful.", + param_descriptor->cid, + (char*)param_descriptor->param_key, + (char*)param_descriptor->param_units, + (const char*)rw_str, + *(uint16_t*)temp_data_ptr); + if (state & param_descriptor->param_opts.opt1) { + alarm_state = true; + break; + } + } + } else { + ESP_LOGE(TAG, "Characteristic #%d (%s) read fail, err = 0x%x (%s).", + param_descriptor->cid, + (char*)param_descriptor->param_key, + (int)err, + (char*)esp_err_to_name(err)); + } + } + vTaskDelay(POLL_TIMEOUT_TICS); // timeout between polls + } + } + vTaskDelay(UPDATE_CIDS_TIMEOUT_TICS); // + } + + if (alarm_state) { + ESP_LOGI(TAG, "Alarm triggered by cid #%d.", + param_descriptor->cid); + } else { + ESP_LOGE(TAG, "Alarm is not triggered after %d retries.", + MASTER_MAX_RETRY); + } + ESP_LOGI(TAG, "Destroy master..."); + ESP_ERROR_CHECK(mbc_master_destroy()); +} + +// Modbus master initialization +static esp_err_t master_init(void) +{ + // Initialize and start Modbus controller + mb_communication_info_t comm = { + .port = MB_PORT_NUM, +#if CONFIG_MB_COMM_MODE_ASCII + .mode = MB_MODE_ASCII, //串口 +#elif CONFIG_MB_COMM_MODE_RTU + .mode = MB_MODE_RTU, //RS485 +#endif + .baudrate = MB_DEV_SPEED, + .parity = MB_PARITY_NONE + }; + void* master_handler = NULL; + + esp_err_t err = mbc_master_init(MB_PORT_SERIAL_MASTER, &master_handler); + MB_RETURN_ON_FALSE((master_handler != NULL), ESP_ERR_INVALID_STATE, TAG, + "mb controller initialization fail."); + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG, + "mb controller initialization fail, returns(0x%x).", + (uint32_t)err); + err = mbc_master_setup((void*)&comm); + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG, + "mb controller setup fail, returns(0x%x).", + (uint32_t)err); + + // Set UART pin numbers + err = uart_set_pin(MB_PORT_NUM, CONFIG_MB_UART_TXD, CONFIG_MB_UART_RXD, + CONFIG_MB_UART_RTS, UART_PIN_NO_CHANGE); + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG, + "mb serial set pin failure, uart_set_pin() returned (0x%x).", (uint32_t)err); + + err = mbc_master_start(); + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG, + "mb controller start fail, returns(0x%x).", + (uint32_t)err); + + // Set driver mode to Half Duplex + err = uart_set_mode(MB_PORT_NUM, UART_MODE_RS485_HALF_DUPLEX); + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG, + \ No newline at end of file diff --git a/main/stm32/uart0_modbus_slave.c b/main/stm32/uart0_modbus_slave.c new file mode 100644 index 0000000..ad32592 --- /dev/null +++ b/main/stm32/uart0_modbus_slave.c @@ -0,0 +1,124 @@ +/* UART Echo Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/uart.h" +#include "driver/gpio.h" +#include "sdkconfig.h" +#include "esp_log.h" +#include "uart.h" + +static const char *TAG = "UART0"; + +#define BAUD_RATE (115200) +#define UART_PORT_NUM (0) +#define BUF_SIZE (256) +#define UART_READ_TOUT (5 / portTICK_RATE_MS) + +#define LED1_GPIO_PIN 11 + +uint8_t txbuf[BUF_SIZE]; +uint8_t rxbuf[BUF_SIZE]; +extern int ModbusSlaveProcess(uint8_t *txbuf, uint8_t *rxbuf, uint16_t rxLen, int is_crc); + +void uart0_init(void) +{ + const int uart_num = UART_PORT_NUM; + uart_config_t uart_config = { + .baud_rate = BAUD_RATE, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .rx_flow_ctrl_thresh = 122, + .source_clk = UART_SCLK_APB, + }; + // Set UART log level + // esp_log_level_set(TAG, ESP_LOG_NONE); + + ESP_LOGI(TAG, "Start RS485 application test and configure UART."); + + // Install UART driver (we don't need an event queue here) + // In this example we don't even use a buffer for sending data. + ESP_ERROR_CHECK(uart_driver_install(uart_num, BUF_SIZE * 2, 0, 0, NULL, 0)); + + // Configure UART parameters + ESP_ERROR_CHECK(uart_param_config(uart_num, &uart_config)); + ESP_LOGI(TAG, "UART set pins, mode and install driver."); + // Set UART pins as per KConfig settings + // ESP_ERROR_CHECK(uart_set_pin(uart_num, UART_TXD_PIN, UART_RXD_PIN, UART_RTS_PIN, UART_CTS_PIN)); + // Set RS485 half duplex mode + ESP_ERROR_CHECK(uart_set_mode(uart_num, UART_MODE_RS485_HALF_DUPLEX)); + // Set read timeout of UART TOUT feature + ESP_ERROR_CHECK(uart_set_rx_timeout(uart_num, UART_READ_TOUT)); +} + +void LED1_Toggle(void) +{ + static unsigned char flg = 1; + if (flg) + { + gpio_set_level(LED1_GPIO_PIN, 0); + flg = 0; + } + else + { + gpio_set_level(LED1_GPIO_PIN, 1); + flg = 1; + } +} + +void uart0_modbus_slave_task(void) +{ + + while (1) + { + // Read data from UART + int txlen = 0; + int len = uart_read_bytes(UART_PORT_NUM, rxbuf, BUF_SIZE, UART_READ_TOUT); + uint32_t tick = xTaskGetTickCount(); + // Write data back to UART + if (len > 0) + { + // uart_write_bytes(UART_PORT_NUM, rxbuf, len); + // ESP_LOGI(TAG, "uart_read_bytes len=%d", len); + txlen = ModbusSlaveProcess(txbuf, rxbuf, len, 1); + if (txlen > 0) + { + LED1_Toggle(); + uart_write_bytes(UART_PORT_NUM, txbuf, txlen); + } + } + // if (tick - last_rxtick >= PACKET_READ_TICS) + // { + // com_poll_modbus_master_poll(0); + // // if (++mcu_watch_dog_cnt > mcu_watch_dog_timeout) //如果通讯中断会相互重启,计数器不起作用 + // if (gpio_get_level(0)) // cpu 启动后会拉低GPIO0 + // { + // mcu_watch_dog_cnt = 0; + // if (mcu_pwr_off_cnt < 2) + // { + // mcu_pwr_off_cnt++; + // gpio_set_level(12, 1); // 3v8 off + // vTaskDelay(3000 / portTICK_RATE_MS); + // gpio_set_level(12, 0); // 3v8 off + // mcu_watch_dog_timeout = 12000 / (portTICK_RATE_MS * PACKET_READ_TICS); + // } + // } + // } + // last_rxtick = tick; + } +} + +void uart0_modbus_slave_init(void) +{ + uart0_init(); + xTaskCreate(uart0_modbus_slave_task, "uart0_modbus_slave_task", 4096, NULL, 10, NULL); +} diff --git a/main/stm32/uart1_modbus_master.c b/main/stm32/uart1_modbus_master.c new file mode 100644 index 0000000..6f5100b --- /dev/null +++ b/main/stm32/uart1_modbus_master.c @@ -0,0 +1,112 @@ +/* UART Echo Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/uart.h" +#include "driver/gpio.h" +#include "sdkconfig.h" +#include "esp_log.h" +#include "uart.h" + +/** + * This is an example which echos any data it receives on configured UART back to the sender, + * with hardware flow control turned off. It does not use UART driver event queue. + * + * - Port: configured UART + * - Receive (Rx) buffer: on + * - Transmit (Tx) buffer: off + * - Flow control: off + * - Event queue: off + * - Pin assignment: see defines below (See Kconfig) + */ + +#define UART_TXD_PIN 17 +#define UART_RXD_PIN 18 +#define UART_RTS_PIN 8 +#define UART_CTS_PIN (-1) + +static const char *TAG = "UART1"; + +#define BAUD_RATE (9600) +#define UART_PORT_NUM (1) +#define RX_BUF_SIZE (256) +#define TX_BUF_SIZE (256) + +#define UART_READ_TOUT (5 / portTICK_PERIOD_MS) + +static void uart1_rs485_init(void) +{ + + uart_config_t uart_config = { + .baud_rate = BAUD_RATE, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .rx_flow_ctrl_thresh = 122, + .source_clk = UART_SCLK_APB, + }; + + ESP_LOGI(TAG, "Start RS485 application test and configure UART."); + + // Install UART driver (we don't need an event queue here) + // In this example we don't even use a buffer for sending data. + ESP_ERROR_CHECK(uart_driver_install(UART_PORT_NUM, RX_BUF_SIZE, TX_BUF_SIZE, 0, NULL, 0)); + + // Configure UART parameters + ESP_ERROR_CHECK(uart_param_config(UART_PORT_NUM, &uart_config)); + + ESP_LOGI(TAG, "UART set pins, mode and install driver."); + + // Set UART pins as per KConfig settings + ESP_ERROR_CHECK(uart_set_pin(UART_PORT_NUM, UART_TXD_PIN, UART_RXD_PIN, UART_RTS_PIN, UART_CTS_PIN)); + + // Set RS485 half duplex mode + ESP_ERROR_CHECK(uart_set_mode(UART_PORT_NUM, UART_MODE_RS485_HALF_DUPLEX)); + + // Set read timeout of UART TOUT feature + ESP_ERROR_CHECK(uart_set_rx_timeout(UART_PORT_NUM, UART_READ_TOUT)); +} + +static void uart0_com_poll_task(void *arg) +{ + + uint32_t last_rxtick = 0; + uint8_t rx_data[RX_BUF_SIZE]; + uint8_t tx_data[RX_BUF_SIZE]; + while (1) + { + // Read data from UART + int len = uart_read_bytes(UART_PORT_NUM, rx_data, RX_BUF_SIZE, UART_READ_TOUT); + uint32_t tick = xTaskGetTickCount(); + // Write data back to UART + if (len > 0) + { + // ESP_LOGI(TAG, "uart_read_bytes len=%d", len); + int err = com_poll_modbus_master_on_revice(0, data, len); + if (err == 0) + { + } + } + if (tick - last_rxtick >= UART_READ_TOUT) + { + com_poll_modbus_master_poll(0); + // if (++mcu_watch_dog_cnt > mcu_watch_dog_timeout) //如果通讯中断会相互重启,计数器不起作用 + } + } + vTaskDelete(NULL); +} + +void uart1_task_init(void) +{ + ESP_LOGI(TAG, "uart1_com_poll_task"); + // A uart read/write example without event queue; + xTaskCreate(uart0_com_poll_task, "uart0_com_poll_task", 1024, NULL, 9, NULL); +} diff --git a/main/stm32/uart2_printer.c b/main/stm32/uart2_printer.c new file mode 100644 index 0000000..bf31345 --- /dev/null +++ b/main/stm32/uart2_printer.c @@ -0,0 +1,61 @@ +/* UART Echo Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/uart.h" +#include "driver/gpio.h" +#include "sdkconfig.h" +#include "esp_log.h" +#include "uart.h" + +/** + * This is an example which echos any data it receives on configured UART back to the sender, + * with hardware flow control turned off. It does not use UART driver event queue. + * + * - Port: configured UART + * - Receive (Rx) buffer: on + * - Transmit (Tx) buffer: off + * - Flow control: off + * - Event queue: off + * - Pin assignment: see defines below (See Kconfig) + */ + +#define UART_TXD_PIN 16 +#define UART_RXD_PIN 15 +#define UART_RTS_PIN (-1) +#define UART_CTS_PIN 3 + +static const char *TAG = "UART2"; +#define UART2_BAUD_RATE (115200) +#define UART_PORT_NUM (2) +#define BUF_SIZE (1024) + +static void uart2_init(void) +{ + uart_config_t uart_config = { + .baud_rate = UART2_BAUD_RATE, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .source_clk = UART_SCLK_APB, + }; + int intr_alloc_flags = 0; + +#if CONFIG_UART_ISR_IN_IRAM + intr_alloc_flags = ESP_INTR_FLAG_IRAM; +#endif + + ESP_ERROR_CHECK(uart_driver_install(UART_PORT_NUM, BUF_SIZE * 2, 0, 0, NULL, intr_alloc_flags)); + ESP_ERROR_CHECK(uart_param_config(UART_PORT_NUM, &uart_config)); + ESP_ERROR_CHECK(uart_set_pin(UART_PORT_NUM, UART_TXD_PIN, UART_RXD_PIN, UART_RTS_PIN, UART_CTS_PIN)); +} + + \ No newline at end of file diff --git a/main/stm32/utils.c b/main/stm32/utils.c new file mode 100644 index 0000000..a41b95a --- /dev/null +++ b/main/stm32/utils.c @@ -0,0 +1,60 @@ +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "utils.h" +#include +#include +int GetCompileDateTime(uint16_t *DateTime) +{ + const int MONTH_PER_YEAR=13; + static char szEnglishMonth[][4] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; + char szTmpDate[40]= {0}; + char szTmpTime[20]= {0}; + char szMonth[4]= {0}; + int iYear,iMonth,iDay,iHour,iMin,iSec;//,, + int i; + //获取编译日期、时间 + sprintf(szTmpDate,"%s",__DATE__); //"Sep 18 2010" + sprintf(szTmpTime,"%s",__TIME__); //"10:59:19" + + sscanf(szTmpDate,"%s %d %d",szMonth,&iDay,&iYear); + sscanf(szTmpTime,"%d:%d:%d",&iHour,&iMin,&iSec); + + for(i=0; MONTH_PER_YEAR; i++) + { + if(strncmp(szMonth,szEnglishMonth[i],3)==0) + { + iMonth=i+1; + break; + } + } + + //printf("%d,%d,%d,%d,%d,%d\n",iYear,iMonth,iDay,iHour,iMin,iSec); + //sprintf(szDateTime,"%04d-%02d-%02d %02d:%02d:%02d",iYear,iMonth,iDay,iHour,iMin,iSec); + DateTime[0] = iYear; + DateTime[1] = iMonth*100; + DateTime[1] += iDay; + DateTime[2] = iHour*100; + DateTime[2] += iMin; + return 0; +} + +unsigned int TickDiff(unsigned int comptime) +{ + unsigned int nowtime = xTaskGetTickCount(); + if(nowtime >= comptime) + return (nowtime - comptime); + else + return (0 - (comptime - nowtime)); +} + +int scale(int raw, int raw_min, int raw_max,int eng_min, int eng_max) +{ + int result = 0; + if(raw_max != raw_min) + { + result = (raw - raw_min) * (eng_max - eng_min) / (raw_max - raw_min) + eng_min; + } + return result; +} diff --git a/main/stm32/utils.h b/main/stm32/utils.h new file mode 100644 index 0000000..8b5bd17 --- /dev/null +++ b/main/stm32/utils.h @@ -0,0 +1,6 @@ + +#ifndef _UTILS_H_ +#define _UTILS_H_ +int GetCompileDateTime(uint16_t *DateTime); +extern unsigned int TickDiff(unsigned int comptime); +#endif diff --git a/main/uart.h b/main/uart.h new file mode 100644 index 0000000..ecaf7a9 --- /dev/null +++ b/main/uart.h @@ -0,0 +1,28 @@ +#ifndef _UART_H_ +#define _UART_H_ + +#define RS485_TXD_PIN 17 +#define RS485_RXD_PIN 18 +#define RS485_RTS_PIN 8 +#define RS485_CTS_PIN (-1) + +// #define MCU_TXD_PIN 17 +// #define MCU_RXD_PIN 18 + + +#define PRINT_TXD_PIN 16 +#define PRINT_RXD_PIN 15 +#define PRINT_RTS_PIN (-1) +#define PRINT_CTS_PIN 3 + + +#define RS485_UART_PORT_NUM (0) +#define RS485_UART_BAUD_RATE (115200) +#define RS485_TASK_STACK_SIZE (1024) + +#define PRINT_UART_PORT_NUM (1) +#define PRINT_UART_BAUD_RATE (115200) +#define PRINT_TASK_STACK_SIZE (1024) + + +#endif diff --git a/main/uart_example.c b/main/uart_example.c new file mode 100644 index 0000000..7247c49 --- /dev/null +++ b/main/uart_example.c @@ -0,0 +1,97 @@ +/* UART Echo Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/uart.h" +#include "driver/gpio.h" +#include "sdkconfig.h" +#include "esp_log.h" +#include "uart.h" + +/** + * This is an example which echos any data it receives on configured UART back to the sender, + * with hardware flow control turned off. It does not use UART driver event queue. + * + * - Port: configured UART + * - Receive (Rx) buffer: on + * - Transmit (Tx) buffer: off + * - Flow control: off + * - Event queue: off + * - Pin assignment: see defines below (See Kconfig) + */ + +#define RS485_TXD_PIN 17 +#define RS485_RXD_PIN 18 +#define RS485_RTS_PIN 8 +#define RS485_CTS_PIN (-1) + +// #define MCU_TXD_PIN 17 +// #define MCU_RXD_PIN 18 + + +#define PRINT_TXD_PIN 16 +#define PRINT_RXD_PIN 15 +#define PRINT_RTS_PIN (-1) +#define PRINT_CTS_PIN 3 + + +#define RS485_UART_PORT_NUM (0) +#define RS485_UART_BAUD_RATE (115200) +#define RS485_TASK_STACK_SIZE (1024) + +#define PRINT_UART_PORT_NUM (1) +#define PRINT_UART_BAUD_RATE (115200) +#define PRINT_TASK_STACK_SIZE (1024) + +static const char *TAG = "UART"; + +#define BUF_SIZE (1024) + +void RS485_init(void) +{ + uart_config_t uart_config = { + .baud_rate = RS485_UART_BAUD_RATE, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .source_clk = UART_SCLK_APB, + }; + int intr_alloc_flags = 0; + +#if CONFIG_UART_ISR_IN_IRAM + intr_alloc_flags = ESP_INTR_FLAG_IRAM; +#endif + + ESP_ERROR_CHECK(uart_driver_install(RS485_UART_PORT_NUM, BUF_SIZE * 2, 0, 0, NULL, intr_alloc_flags)); + ESP_ERROR_CHECK(uart_param_config(RS485_UART_PORT_NUM, &uart_config)); + ESP_ERROR_CHECK(uart_set_pin(RS485_UART_PORT_NUM, RS485_TXD_PIN, RS485_RXD_PIN, RS485_RTS_PIN, RS485_CTS_PIN)); +} + +void print_init(void) +{ + uart_config_t uart_config = { + .baud_rate = PRINT_UART_BAUD_RATE, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .source_clk = UART_SCLK_APB, + }; + int intr_alloc_flags = 0; + +#if CONFIG_UART_ISR_IN_IRAM + intr_alloc_flags = ESP_INTR_FLAG_IRAM; +#endif + + ESP_ERROR_CHECK(uart_driver_install(PRINT_UART_PORT_NUM, BUF_SIZE * 2, 0, 0, NULL, intr_alloc_flags)); + ESP_ERROR_CHECK(uart_param_config(PRINT_UART_PORT_NUM, &uart_config)); + ESP_ERROR_CHECK(uart_set_pin(PRINT_UART_PORT_NUM, PRINT_TXD_PIN, PRINT_RXD_PIN, PRINT_RTS_PIN, PRINT_CTS_PIN)); +} diff --git a/main/wifi_softap.c b/main/wifi_softap.c new file mode 100644 index 0000000..a6c9318 --- /dev/null +++ b/main/wifi_softap.c @@ -0,0 +1,154 @@ +/* WiFi softAP Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "esp_wifi.h" +#include "esp_event.h" +#include "esp_log.h" +#include "nvs_flash.h" + +#include "lwip/err.h" +#include "lwip/sys.h" + +#include "driver/ledc.h" +#include "esp_err.h" + +/* The examples use WiFi configuration that you can set via project configuration menu. + + If you'd rather not, just change the below entries to strings with + the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" +*/ +#define ESP_WIFI_SSID "T2N_056455" +#define ESP_WIFI_PASS "01010101" +#define ESP_WIFI_CHANNEL 1 +#define MAX_STA_CONN 8 + +static const char *TAG = "wifi softAP"; + +#define LEDC_TIMER LEDC_TIMER_0 +#define LEDC_MODE LEDC_LOW_SPEED_MODE +#define LEDC_OUTPUT_IO (21) // Define the output GPIO +#define LEDC_CHANNEL LEDC_CHANNEL_0 +#define LEDC_DUTY_RES LEDC_TIMER_13_BIT // Set duty resolution to 13 bits +#define LEDC_DUTY (4095) // Set duty to 50%. ((2 ** 13) - 1) * 50% = 4095 +#define LEDC_FREQUENCY (3840) // Frequency in Hertz. Set frequency at 5 kHz + +static void wifi_event_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + if (event_id == WIFI_EVENT_AP_STACONNECTED) + { + wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *)event_data; + ESP_LOGI(TAG, "station " MACSTR " join, AID=%d", + MAC2STR(event->mac), event->aid); + } + else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) + { + wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data; + ESP_LOGI(TAG, "station " MACSTR " leave, AID=%d", + MAC2STR(event->mac), event->aid); + } +} +extern void ModBusTCPSlave_init(void); +void wifi_init_softap(void) +{ + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + esp_netif_create_default_wifi_ap(); + + 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)); + + wifi_config_t wifi_config = { + .ap = { + .ssid = ESP_WIFI_SSID, + .ssid_len = strlen(ESP_WIFI_SSID), + .channel = ESP_WIFI_CHANNEL, + .password = ESP_WIFI_PASS, + .max_connection = MAX_STA_CONN, + .authmode = WIFI_AUTH_WPA_WPA2_PSK}, + }; + + nvs_handle_t my_handle; + esp_err_t err = nvs_open("wifi", NVS_READWRITE, &my_handle); + if (err == ESP_OK) + { + size_t len; + char temp_str[64]; + uint8_t channel; + if (nvs_get_str(my_handle, "ap_ssid", temp_str, &len) == ESP_OK) + { + strncpy((char*)wifi_config.ap.ssid, temp_str, len); + wifi_config.ap.ssid_len = len; + } + if (nvs_get_str(my_handle, "ap_psk", temp_str, &len) == ESP_OK) + { + strncpy((char*)wifi_config.ap.password, temp_str, len); + } + if (nvs_get_u8(my_handle, "ap_ch", &channel) == ESP_OK) + { + wifi_config.ap.channel = channel; + } + + nvs_close(my_handle); + } + if (strlen(ESP_WIFI_PASS) == 0) + { + wifi_config.ap.authmode = WIFI_AUTH_OPEN; + } + + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); + + ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d", + ESP_WIFI_SSID, ESP_WIFI_PASS, ESP_WIFI_CHANNEL); +} + +// void app_main2(void) +// { +// // 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); + +// ESP_LOGI(TAG, "ESP_WIFI_MODE_AP"); +// wifi_init_softap(); +// // ledc_init(); +// // ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, LEDC_DUTY)); +// // // Update duty to apply the new value +// // ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); +// // gpio_config_t io_conf = {}; +// // // disable interrupt +// // io_conf.intr_type = GPIO_INTR_DISABLE; +// // // set as output mode +// // io_conf.mode = GPIO_MODE_OUTPUT; +// // // bit mask of the pins that you want to set,e.g.GPIO18/19 +// // io_conf.pin_bit_mask = 1 << 9; +// // // 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 +// // gpio_config(&io_conf); +// // gpio_set_level(9, 1); +// } diff --git a/sdkconfig b/sdkconfig new file mode 100644 index 0000000..3131c3c --- /dev/null +++ b/sdkconfig @@ -0,0 +1,1410 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) Project Configuration +# +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET="esp32s3" +CONFIG_IDF_TARGET_ESP32S3=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0009 + +# +# SDK tool configuration +# +CONFIG_SDK_TOOLPREFIX="xtensa-esp32s3-elf-" +# CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS is not set +# end of SDK tool configuration + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# end of Build type + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 +# end of Application manager + +# +# Bootloader config +# +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x0 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=3 +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_SUPPORTS_RSA=y +CONFIG_SECURE_TARGET_HAS_SECURE_ROM_DL_MODE=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +# end of Security features + +# +# Boot ROM Behavior +# +CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y +# CONFIG_BOOT_ROM_LOG_ALWAYS_OFF is not set +# CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH is not set +# CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW is not set +# end of Boot ROM Behavior + +# +# Serial flasher config +# +CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_OCT_FLASH is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHMODE="dio" +# CONFIG_ESPTOOLPY_FLASHFREQ_120M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="80m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +# CONFIG_ESPTOOLPY_MONITOR_BAUD_CONSOLE is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set +CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y +# CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set +CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=115200 +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_CUSTOM is not set +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Example Configuration +# +CONFIG_ESP_WIFI_SSID="CMCC-xRSZ" +CONFIG_ESP_WIFI_PASSWORD="dughk9gm" +CONFIG_ESP_MAXIMUM_RETRY=5 +CONFIG_ESP_WIFI_AUTH_OPEN=y +# CONFIG_ESP_WIFI_AUTH_WEP is not set +# CONFIG_ESP_WIFI_AUTH_WPA_PSK is not set +# CONFIG_ESP_WIFI_AUTH_WPA2_PSK is not set +# CONFIG_ESP_WIFI_AUTH_WPA_WPA2_PSK is not set +# CONFIG_ESP_WIFI_AUTH_WPA3_PSK is not set +# CONFIG_ESP_WIFI_AUTH_WPA2_WPA3_PSK is not set +# CONFIG_ESP_WIFI_AUTH_WAPI_PSK is not set +# end of Example Configuration + +# +# Compiler options +# +CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y +# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set +# CONFIG_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +# CONFIG_COMPILER_DISABLE_GCC8_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# ESP-ASIO +# +# CONFIG_ASIO_SSL_SUPPORT is not set +# end of ESP-ASIO + +# +# Bluetooth +# +# CONFIG_BT_ENABLED is not set +# end of Bluetooth + +# +# CoAP Configuration +# +CONFIG_COAP_MBEDTLS_PSK=y +# CONFIG_COAP_MBEDTLS_PKI is not set +# CONFIG_COAP_MBEDTLS_DEBUG is not set +CONFIG_COAP_LOG_DEFAULT_LEVEL=0 +# end of CoAP Configuration + +# +# Driver configurations +# + +# +# ADC configuration +# +# CONFIG_ADC_FORCE_XPD_FSM is not set +CONFIG_ADC_DISABLE_DAC=y +# end of ADC configuration + +# +# MCPWM configuration +# +# CONFIG_MCPWM_ISR_IN_IRAM is not set +# end of MCPWM configuration + +# +# SPI configuration +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of SPI configuration + +# +# TWAI configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +# end of TWAI configuration + +# +# UART configuration +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of UART configuration + +# +# GDMA Configuration +# +# CONFIG_GDMA_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GDMA_ISR_IRAM_SAFE is not set +# end of GDMA Configuration +# end of Driver configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +CONFIG_EFUSE_MAX_BLK_LEN=256 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ESP32S3-Specific +# +# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_80 is not set +CONFIG_ESP32S3_DEFAULT_CPU_FREQ_160=y +# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240 is not set +CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=160 + +# +# Cache config +# +CONFIG_ESP32S3_INSTRUCTION_CACHE_16KB=y +# CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB is not set +CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE=0x4000 +# CONFIG_ESP32S3_INSTRUCTION_CACHE_4WAYS is not set +CONFIG_ESP32S3_INSTRUCTION_CACHE_8WAYS=y +CONFIG_ESP32S3_ICACHE_ASSOCIATED_WAYS=8 +# CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B is not set +CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B=y +CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_SIZE=32 +# CONFIG_ESP32S3_INSTRUCTION_CACHE_WRAP is not set +# CONFIG_ESP32S3_DATA_CACHE_16KB is not set +CONFIG_ESP32S3_DATA_CACHE_32KB=y +# CONFIG_ESP32S3_DATA_CACHE_64KB is not set +CONFIG_ESP32S3_DATA_CACHE_SIZE=0x8000 +# CONFIG_ESP32S3_DATA_CACHE_4WAYS is not set +CONFIG_ESP32S3_DATA_CACHE_8WAYS=y +CONFIG_ESP32S3_DCACHE_ASSOCIATED_WAYS=8 +# CONFIG_ESP32S3_DATA_CACHE_LINE_16B is not set +CONFIG_ESP32S3_DATA_CACHE_LINE_32B=y +# CONFIG_ESP32S3_DATA_CACHE_LINE_64B is not set +CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE=32 +# CONFIG_ESP32S3_DATA_CACHE_WRAP is not set +# end of Cache config + +# CONFIG_ESP32S3_SPIRAM_SUPPORT is not set +# CONFIG_ESP32S3_TRAX is not set +CONFIG_ESP32S3_TRACEMEM_RESERVE_DRAM=0x0 +# CONFIG_ESP32S3_ULP_COPROC_ENABLED is not set +CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM=0 +CONFIG_ESP32S3_DEBUG_OCDAWARE=y +CONFIG_ESP32S3_BROWNOUT_DET=y +CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_7=y +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_1 is not set +CONFIG_ESP32S3_BROWNOUT_DET_LVL=7 +CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32S3_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32S3_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32S3_RTC_CLK_SRC_INT_RC=y +# CONFIG_ESP32S3_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32S3_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32S3_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_ESP32S3_RTC_CLK_CAL_CYCLES=1024 +CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY=2000 +# CONFIG_ESP32S3_NO_BLOBS is not set +# CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM is not set +# CONFIG_ESP32S3_USE_FIXED_STATIC_RAM_SIZE is not set +# end of ESP32S3-Specific + +# +# ADC-Calibration +# +# end of ADC-Calibration + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# Ethernet +# +CONFIG_ETH_ENABLED=y +CONFIG_ETH_USE_SPI_ETHERNET=y +# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set +# CONFIG_ETH_SPI_ETHERNET_W5500 is not set +# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set +# CONFIG_ETH_USE_OPENETH is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +# end of GDB Stub + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH=y +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_OTA_ALLOW_HTTP is not set +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y +# CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES_TWO is not set +CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES=4 +# end of MAC Config + +# +# Sleep Config +# +# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND=y +CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU=y +# end of Sleep Config + +# +# RTC Clock Config +# +CONFIG_RTC_CLOCK_BBPLL_POWER_ON_WITH_USB=y +# end of RTC Clock Config +# end of Hardware Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1536 +CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y +CONFIG_ESP_IPC_ISR_ENABLE=y +# end of IPC (Inter-Processor Call) + +# +# LCD and Touch Panel +# + +# +# LCD Peripheral Configuration +# +CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 +# CONFIG_LCD_RGB_ISR_IRAM_SAFE is not set +# end of LCD Peripheral Configuration +# end of LCD and Touch Panel + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=y +# end of ESP NETIF Adapter + +# +# PHY +# +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +CONFIG_ESP_PHY_ENABLE_USB=y +# end of PHY + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=y +CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP=y +# end of Power Management + +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + +# +# ESP System Settings +# +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set +CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y +CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y + +# +# Memory protection +# +# end of Memory protection + +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +# CONFIG_ESP_CONSOLE_UART_DEFAULT is not set +# CONFIG_ESP_CONSOLE_USB_CDC is not set +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_SECONDARY_NONE=y +CONFIG_ESP_CONSOLE_MULTIPLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=-1 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_INT_WDT_CHECK_CPU1=y +CONFIG_ESP_TASK_WDT=y +# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y +# end of ESP System Settings + +# +# High resolution timer (esp_timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_IMPL_SYSTIMER=y +# end of High resolution timer (esp_timer) + +# +# Wi-Fi +# +CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +# CONFIG_ESP_WIFI_FTM_ENABLE is not set +# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set +# CONFIG_ESP_WIFI_GCMP_SUPPORT is not set +# CONFIG_ESP_WIFI_GMAC_SUPPORT is not set +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# end of Wi-Fi + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +# end of FAT Filesystem support + +# +# Modbus configuration +# +CONFIG_FMB_COMM_MODE_TCP_EN=y +CONFIG_FMB_TCP_PORT_DEFAULT=502 +CONFIG_FMB_TCP_PORT_MAX_CONN=5 +CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 +CONFIG_FMB_COMM_MODE_RTU_EN=y +CONFIG_FMB_COMM_MODE_ASCII_EN=y +CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150 +CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_FMB_QUEUE_LENGTH=20 +CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 +CONFIG_FMB_SERIAL_BUF_SIZE=256 +CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 +CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 +CONFIG_FMB_PORT_TASK_PRIO=10 +# CONFIG_FMB_PORT_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_FMB_PORT_TASK_AFFINITY_CPU0=y +# CONFIG_FMB_PORT_TASK_AFFINITY_CPU1 is not set +CONFIG_FMB_PORT_TASK_AFFINITY=0x0 +CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 +CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 +# CONFIG_FMB_TIMER_PORT_ENABLED is not set +# CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD is not set +# end of Modbus configuration + +# +# FreeRTOS +# +# CONFIG_FREERTOS_UNICORE is not set +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_TICK_SUPPORT_SYSTIMER=y +CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL1=y +# CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL3 is not set +CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y +# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set +# CONFIG_FREERTOS_ASSERT_DISABLE is not set +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +# CONFIG_FREERTOS_LEGACY_HOOKS is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +# CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH is not set +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# end of Heap memory debugging + +# +# jsmn +# +# CONFIG_JSMN_PARENT_LINKS is not set +# CONFIG_JSMN_STRICT is not set +# end of jsmn + +# +# libsodium +# +# end of libsodium + +# +# Log output +# +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=3 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=3 +CONFIG_LOG_COLORS=y +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Log output + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# CONFIG_LWIP_SO_RCVBUF is not set +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP4_FRAG=y +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +# CONFIG_LWIP_IP6_REASSEMBLY is not set +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 + +# +# DHCP server +# +CONFIG_LWIP_DHCPS=y +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +# CONFIG_LWIP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +# end of SNTP + +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y +# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set +CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y +# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set +# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# mbedTLS v2.28.x related +# +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +# end of mbedTLS v2.28.x related + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +# CONFIG_MBEDTLS_CMAC_C is not set +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_AES_USE_INTERRUPT=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +# CONFIG_MBEDTLS_PSK_MODES is not set +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +# CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set +CONFIG_MBEDTLS_SSL_PROTO_TLS1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_X509_CHECK_KEY_USAGE=y +CONFIG_MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +CONFIG_MBEDTLS_RC4_DISABLED=y +# CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set +# CONFIG_MBEDTLS_RC4_ENABLED is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +# CONFIG_MBEDTLS_SECURITY_RISKS is not set +# end of mbedTLS + +# +# mDNS +# +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_TASK_STACK_SIZE=4096 +# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_MDNS_TASK_AFFINITY_CPU0=y +# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set +CONFIG_MDNS_TASK_AFFINITY=0x0 +CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 +# CONFIG_MDNS_STRICT_MODE is not set +CONFIG_MDNS_TIMER_PERIOD_MS=100 +# CONFIG_MDNS_NETWORKING_SOCKET is not set +CONFIG_MDNS_MULTIPLE_INSTANCE=y +# end of mDNS + +# +# ESP-MQTT Configurations +# +CONFIG_MQTT_PROTOCOL_311=y +CONFIG_MQTT_TRANSPORT_SSL=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +# end of Newlib + +# +# NVS +# +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# end of NVS + +# +# OpenSSL +# +# CONFIG_OPENSSL_DEBUG is not set +CONFIG_OPENSSL_ERROR_STACK=y +# CONFIG_OPENSSL_ASSERT_DO_NOTHING is not set +CONFIG_OPENSSL_ASSERT_EXIT=y +# end of OpenSSL + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set +# end of OpenThread + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y +# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set +# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +# CONFIG_SPI_FLASH_ROM_IMPL is not set +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_USE_LEGACY_IMPL is not set +# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_TH_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP=y +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# end of Websocket +# end of TCP Transport + +# +# TinyUSB Stack +# +# CONFIG_TINYUSB is not set +# end of TinyUSB Stack + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_64BIT is not set +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# USB-OTG +# +CONFIG_USB_OTG_SUPPORTED=y +CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE=256 +CONFIG_USB_HOST_HW_BUFFER_BIAS_BALANCED=y +# CONFIG_USB_HOST_HW_BUFFER_BIAS_IN is not set +# CONFIG_USB_HOST_HW_BUFFER_BIAS_PERIODIC_OUT is not set +# end of USB-OTG + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_VFS_SUPPORT_TERMIOS=y + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# end of Host File System I/O (Semihosting) +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set +# end of Wi-Fi Provisioning Manager + +# +# Supplicant +# +CONFIG_WPA_MBEDTLS_CRYPTO=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_SUITE_B_192 is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set +# end of Supplicant +# end of Component config + +# +# Compatibility options +# +# CONFIG_LEGACY_INCLUDE_COMMON_HEADERS is not set +# end of Compatibility options + +# Deprecated options for backward compatibility +CONFIG_TOOLPREFIX="xtensa-esp32s3-elf-" +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=3 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set +CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DOUT is not set +# CONFIG_MONITOR_BAUD_9600B is not set +# CONFIG_MONITOR_BAUD_57600B is not set +CONFIG_MONITOR_BAUD_115200B=y +# CONFIG_MONITOR_BAUD_230400B is not set +# CONFIG_MONITOR_BAUD_921600B is not set +# CONFIG_MONITOR_BAUD_2MB is not set +# CONFIG_MONITOR_BAUD_OTHER is not set +CONFIG_MONITOR_BAUD_OTHER_VAL=115200 +CONFIG_MONITOR_BAUD=115200 +CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_DISABLE_GCC8_WARNINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_ADC2_DISABLE_DAC=y +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +# CONFIG_ESP_SYSTEM_PD_FLASH is not set +CONFIG_ESP32C3_LIGHTSLEEP_GPIO_RESET_WORKAROUND=y +CONFIG_IPC_TASK_STACK_SIZE=1536 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +CONFIG_ESP_SYSTEM_PM_POWER_DOWN_CPU=y +# CONFIG_ESP32S2_PANIC_PRINT_HALT is not set +CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32S2_PANIC_GDBSTUB is not set +CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP=y +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=3584 +# CONFIG_CONSOLE_UART_DEFAULT is not set +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART_NUM=-1 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_INT_WDT_CHECK_CPU1=y +CONFIG_TASK_WDT=y +# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_TIMEOUT_S=5 +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set +CONFIG_TIMER_TASK_STACK_SIZE=3584 +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150 +CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_MB_QUEUE_LENGTH=20 +CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096 +CONFIG_MB_SERIAL_BUF_SIZE=256 +CONFIG_MB_SERIAL_TASK_PRIO=10 +CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_MB_CONTROLLER_STACK_SIZE=4096 +CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 +# CONFIG_MB_TIMER_PORT_ENABLED is not set +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_L2_TO_L3_COPY is not set +# CONFIG_USE_ONLY_LWIP_SELECT is not set +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5744 +CONFIG_TCP_WND_DEFAULT=5744 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +# CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +# CONFIG_USB_ENABLED is not set +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# End of deprecated options