forked from test34/can_wizard
initial commit
This commit is contained in:
commit
3fb1c8dd81
20 changed files with 2776 additions and 0 deletions
143
.clang-format
Normal file
143
.clang-format
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveMacros: true
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: Align
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllConstructorInitializersOnNextLine: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
AllowShortLambdasOnASingleLine: None
|
||||||
|
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
|
||||||
|
AllowShortEnumsOnASingleLine: false
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
BinPackArguments: false
|
||||||
|
BinPackParameters: false
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: false
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: true
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 140
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DeriveLineEnding: false
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
EmptyLineAfterAccessModifier: Never
|
||||||
|
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||||
|
ExperimentalAutoDetectBinPacking: true
|
||||||
|
FixNamespaceComments: false
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
IncludeIsMainRegex: '(Test)?$'
|
||||||
|
IncludeIsMainSourceRegex: ''
|
||||||
|
IndentAccessModifiers: false
|
||||||
|
IndentCaseLabels: true
|
||||||
|
IndentGotoLabels: true
|
||||||
|
IndentPPDirectives: BeforeHash
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
# Requires Clang >= 15, could also cause incorrect code formatting:
|
||||||
|
# InsertBraces: true
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: All
|
||||||
|
PackConstructorInitializers: NextLine
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
|
PointerAlignment: Left
|
||||||
|
ReferenceAlignment: Pointer
|
||||||
|
ReflowComments: true
|
||||||
|
SeparateDefinitionBlocks: Always
|
||||||
|
SortIncludes: false
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: true
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCaseColon: false
|
||||||
|
SpaceBeforeCpp11BracedList: true
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatementsExceptForEachMacros
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
|
SpacesInContainerLiterals: false
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
SpaceAroundPointerQualifiers: Default
|
||||||
|
Standard: Latest
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
|
TabWidth: 8
|
||||||
|
UseCRLF: false
|
||||||
|
UseTab: Never
|
||||||
|
...
|
||||||
|
|
3
.clangd
Normal file
3
.clangd
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
CompileFlags:
|
||||||
|
Add: [-march=rv32imc]
|
||||||
|
Remove: [-fstrict-volatile-bitfields, -fno-tree-switch-conversion, -fstrict-volatile-bitfields, -mlongcalls]
|
26
.editorconfig
Normal file
26
.editorconfig
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# EditorConfig is awesome: https://EditorConfig.org
|
||||||
|
|
||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
# Unix-style newlines with a newline ending every file
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
# Set default charset
|
||||||
|
charset = utf-8
|
||||||
|
|
||||||
|
# 4 space indentation
|
||||||
|
[*.{c, h, cpp}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
# Tab indentation (no size specified)
|
||||||
|
[Makefile]
|
||||||
|
indent_style = tab
|
||||||
|
|
||||||
|
# Matches the exact files either package.json or .travis.yml
|
||||||
|
[{package.json,.travis.yml}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
.devcontainer
|
||||||
|
.vscode
|
||||||
|
build
|
||||||
|
sdkconfig.old
|
||||||
|
dependencies.lock
|
||||||
|
.idea/
|
||||||
|
cmake-build-debug/
|
||||||
|
.cache/
|
6
CMakeLists.txt
Normal file
6
CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# The following 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.16)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(can_wizard)
|
154
README.md
Normal file
154
README.md
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
|
||||||
|
| ----------------- | ----- | -------- | -------- | -------- |
|
||||||
|
|
||||||
|
# Console Example
|
||||||
|
|
||||||
|
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||||
|
|
||||||
|
This example illustrates the usage of the [Console Component](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/console.html#console) to create an interactive shell on the ESP32. The interactive shell running on the ESP32 can then be controlled/interacted with over a serial port (UART).
|
||||||
|
|
||||||
|
The interactive shell implemented in this example contains a wide variety of commands, and can act as a basis for applications that require a command-line interface (CLI).
|
||||||
|
|
||||||
|
## How to use example
|
||||||
|
|
||||||
|
### Hardware Required
|
||||||
|
|
||||||
|
This example should be able to run on any commonly available ESP32 development board.
|
||||||
|
|
||||||
|
### Configure the project
|
||||||
|
|
||||||
|
```
|
||||||
|
idf.py menuconfig
|
||||||
|
```
|
||||||
|
|
||||||
|
* Enable/disable `Example Configuration > Store command history in flash` as necessary
|
||||||
|
|
||||||
|
### Build and Flash
|
||||||
|
|
||||||
|
Build the project and flash it to the board, then run monitor tool to view serial output:
|
||||||
|
|
||||||
|
```
|
||||||
|
idf.py -p PORT flash monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
(Replace PORT with the name of the serial port to use.)
|
||||||
|
|
||||||
|
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||||
|
|
||||||
|
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||||
|
|
||||||
|
## Example Output
|
||||||
|
|
||||||
|
Enter the `help` command get a full list of all available commands. The following is a sample session of the Console Example where a variety of commands provided by the Console Example are used. Note that GPIO15 is connected to GND to remove the boot log output.
|
||||||
|
|
||||||
|
```
|
||||||
|
This is an example of ESP-IDF console component.
|
||||||
|
Type 'help' to get the list of commands.
|
||||||
|
Use UP/DOWN arrows to navigate through command history.
|
||||||
|
Press TAB when typing command name to auto-complete.
|
||||||
|
[esp32]> help
|
||||||
|
help
|
||||||
|
Print the list of registered commands
|
||||||
|
|
||||||
|
free
|
||||||
|
Get the total size of heap memory available
|
||||||
|
|
||||||
|
restart
|
||||||
|
Restart the program
|
||||||
|
|
||||||
|
deep_sleep [-t <t>] [--io=<n>] [--io_level=<0|1>]
|
||||||
|
Enter deep sleep mode. Two wakeup modes are supported: timer and GPIO. If no
|
||||||
|
wakeup option is specified, will sleep indefinitely.
|
||||||
|
-t, --time=<t> Wake up time, ms
|
||||||
|
--io=<n> If specified, wakeup using GPIO with given number
|
||||||
|
--io_level=<0|1> GPIO level to trigger wakeup
|
||||||
|
|
||||||
|
join [--timeout=<t>] <ssid> [<pass>]
|
||||||
|
Join WiFi AP as a station
|
||||||
|
--timeout=<t> Connection timeout, ms
|
||||||
|
<ssid> SSID of AP
|
||||||
|
<pass> PSK of AP
|
||||||
|
|
||||||
|
[esp32]> free
|
||||||
|
257200
|
||||||
|
[esp32]> deep_sleep -t 1000
|
||||||
|
I (146929) deep_sleep: Enabling timer wakeup, timeout=1000000us
|
||||||
|
I (619) heap_init: Initializing. RAM available for dynamic allocation:
|
||||||
|
I (620) heap_init: At 3FFAE2A0 len 00001D60 (7 KiB): DRAM
|
||||||
|
I (626) heap_init: At 3FFB7EA0 len 00028160 (160 KiB): DRAM
|
||||||
|
I (645) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
|
||||||
|
I (664) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
|
||||||
|
I (684) heap_init: At 40093EA8 len 0000C158 (48 KiB): IRAM
|
||||||
|
|
||||||
|
This is an example of ESP-IDF console component.
|
||||||
|
Type 'help' to get the list of commands.
|
||||||
|
Use UP/DOWN arrows to navigate through command history.
|
||||||
|
Press TAB when typing command name to auto-complete.
|
||||||
|
[esp32]> join --timeout 10000 test_ap test_password
|
||||||
|
I (182639) connect: Connecting to 'test_ap'
|
||||||
|
I (184619) connect: Connected
|
||||||
|
[esp32]> free
|
||||||
|
212328
|
||||||
|
[esp32]> restart
|
||||||
|
I (205639) restart: Restarting
|
||||||
|
I (616) heap_init: Initializing. RAM available for dynamic allocation:
|
||||||
|
I (617) heap_init: At 3FFAE2A0 len 00001D60 (7 KiB): DRAM
|
||||||
|
I (623) heap_init: At 3FFB7EA0 len 00028160 (160 KiB): DRAM
|
||||||
|
I (642) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
|
||||||
|
I (661) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
|
||||||
|
I (681) heap_init: At 40093EA8 len 0000C158 (48 KiB): IRAM
|
||||||
|
|
||||||
|
This is an example of ESP-IDF console component.
|
||||||
|
Type 'help' to get the list of commands.
|
||||||
|
Use UP/DOWN arrows to navigate through command history.
|
||||||
|
Press TAB when typing command name to auto-complete.
|
||||||
|
[esp32]>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Line Endings
|
||||||
|
|
||||||
|
The line endings in the Console Example are configured to match particular serial monitors. Therefore, if the following log output appears, consider using a different serial monitor (e.g. Putty for Windows) or modify the example's [UART configuration](#Configuring-UART-and-VFS).
|
||||||
|
|
||||||
|
```
|
||||||
|
This is an example of ESP-IDF console component.
|
||||||
|
Type 'help' to get the list of commands.
|
||||||
|
Use UP/DOWN arrows to navigate through command history.
|
||||||
|
Press TAB when typing command name to auto-complete.
|
||||||
|
Your terminal application does not support escape sequences.
|
||||||
|
Line editing and history features are disabled.
|
||||||
|
On Windows, try using Putty instead.
|
||||||
|
esp32>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example Breakdown
|
||||||
|
|
||||||
|
### Configuring UART
|
||||||
|
|
||||||
|
The ``initialize_console()`` function in the example configures some aspects of UART relevant to the operation of the console.
|
||||||
|
|
||||||
|
- **Line Endings**: The default line endings are configured to match those expected/generated by common serial monitor programs, such as `screen`, `minicom`, and the `esp-idf-monitor` included in the SDK. The default behavior for these commands are:
|
||||||
|
- When 'enter' key is pressed on the keyboard, `CR` (0x13) code is sent to the serial device.
|
||||||
|
- To move the cursor to the beginning of the next line, serial device needs to send `CR LF` (0x13 0x10) sequence.
|
||||||
|
|
||||||
|
### Line editing
|
||||||
|
|
||||||
|
The main source file of the example illustrates how to use `linenoise` library, including line completion, hints, and history.
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
Several commands are registered using `esp_console_cmd_register()` function. See the `register_wifi()` and `register_system()` functions in `cmd_wifi.c` and `cmd_system.c` files.
|
||||||
|
|
||||||
|
### Command handling
|
||||||
|
|
||||||
|
Main loop inside `app_main()` function illustrates how to use `linenoise` and `esp_console_run()` to implement read/eval loop.
|
||||||
|
|
||||||
|
### Argument parsing
|
||||||
|
|
||||||
|
Several commands implemented in `cmd_wifi.c` and `cmd_system.c` use the Argtable3 library to parse and check the arguments.
|
||||||
|
|
||||||
|
### Command history
|
||||||
|
|
||||||
|
Each time a new command line is obtained from `linenoise`, it is written into history and the history is saved into a file in flash memory. On reset, history is initialized from that file.
|
13
main/CMakeLists.txt
Normal file
13
main/CMakeLists.txt
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
set(COMPONENT_SRCS
|
||||||
|
"main.c"
|
||||||
|
"cmd_system.c"
|
||||||
|
"can.c"
|
||||||
|
"console_task.c"
|
||||||
|
"fs.c"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(COMPONENT_ADD_INCLUDEDIRS
|
||||||
|
"."
|
||||||
|
)
|
||||||
|
|
||||||
|
register_component()
|
15
main/Kconfig.env_caps
Normal file
15
main/Kconfig.env_caps
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
config ENV_GPIO_RANGE_MIN
|
||||||
|
int
|
||||||
|
default 0
|
||||||
|
|
||||||
|
config ENV_GPIO_RANGE_MAX
|
||||||
|
int
|
||||||
|
default 21
|
||||||
|
|
||||||
|
config ENV_GPIO_IN_RANGE_MAX
|
||||||
|
int
|
||||||
|
default ENV_GPIO_RANGE_MAX
|
||||||
|
|
||||||
|
config ENV_GPIO_OUT_RANGE_MAX
|
||||||
|
int
|
||||||
|
default ENV_GPIO_RANGE_MAX
|
37
main/Kconfig.projbuild
Normal file
37
main/Kconfig.projbuild
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
menu "Can_wizard Configuration"
|
||||||
|
|
||||||
|
orsource "Kconfig.env_caps"
|
||||||
|
|
||||||
|
config CAN_RX_GPIO
|
||||||
|
int "CAN RX GPIO number"
|
||||||
|
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
|
||||||
|
default 9
|
||||||
|
help
|
||||||
|
GPIO number (IOxx) to connect ESP to CAN transceiver.
|
||||||
|
Some GPIOs are used for other purposes (USB, flash connections, etc.) and cannot be used for CAN.
|
||||||
|
|
||||||
|
config CAN_TX_GPIO
|
||||||
|
int "CAN TX GPIO number"
|
||||||
|
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
|
||||||
|
default 8
|
||||||
|
help
|
||||||
|
GPIO number (IOxx) to connect ESP to CAN transceiver.
|
||||||
|
Some GPIOs are used for other purposes (USB, flash connections, etc.) and cannot be used for CAN.
|
||||||
|
|
||||||
|
config CAN_TASK_PRIORITY
|
||||||
|
int "CAN task priority"
|
||||||
|
range 0 22
|
||||||
|
default 5
|
||||||
|
help
|
||||||
|
A priority of FreeRTOS task can_task. See more about tasks priorities in FreeRTOS documentation.
|
||||||
|
|
||||||
|
config CONSOLE_TASK_PRIORITY
|
||||||
|
int "Console task priority"
|
||||||
|
range 0 22
|
||||||
|
default 2
|
||||||
|
help
|
||||||
|
A priority of FreeRTOS task can_task. See more about tasks priorities in FreeRTOS documentation.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
endmenu
|
81
main/can.c
Normal file
81
main/can.c
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
//
|
||||||
|
// Created by okhsunrog on 8/17/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "can.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "hal/twai_types.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static const twai_timing_config_t t_config = TWAI_TIMING_CONFIG_125KBITS();
|
||||||
|
static const twai_general_config_t g_config = {
|
||||||
|
.mode = TWAI_MODE_NORMAL,
|
||||||
|
.tx_io = CONFIG_CAN_TX_GPIO,
|
||||||
|
.rx_io = CONFIG_CAN_RX_GPIO,
|
||||||
|
.clkout_io = TWAI_IO_UNUSED,
|
||||||
|
.bus_off_io = TWAI_IO_UNUSED,
|
||||||
|
.tx_queue_len = 5,
|
||||||
|
.rx_queue_len = 5,
|
||||||
|
.alerts_enabled = TWAI_ALERT_BUS_OFF | TWAI_ALERT_BUS_RECOVERED,
|
||||||
|
.clkout_divider = 0,
|
||||||
|
.intr_flags = ESP_INTR_FLAG_LEVEL1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* LOG_TAG = "can";
|
||||||
|
|
||||||
|
void can_init() {
|
||||||
|
// Install CAN driver
|
||||||
|
// calculate_hw_can_filter(CONFIG_DEVICE_ID, &f_config, false);
|
||||||
|
static twai_filter_config_t f_config = {.acceptance_code = 0, .acceptance_mask = 0xFFFFFFFF, .single_filter = true};
|
||||||
|
ESP_ERROR_CHECK(twai_driver_install(&g_config, &t_config, &f_config));
|
||||||
|
ESP_LOGI(LOG_TAG, "CAN driver installed");
|
||||||
|
// Start CAN driver
|
||||||
|
ESP_ERROR_CHECK(twai_start());
|
||||||
|
ESP_LOGI(LOG_TAG, "CAN driver started");
|
||||||
|
}
|
||||||
|
|
||||||
|
void can_stop() {
|
||||||
|
// stop and uninstall twai driver to change hardware filters
|
||||||
|
ESP_ERROR_CHECK(twai_stop());
|
||||||
|
ESP_ERROR_CHECK(twai_driver_uninstall());
|
||||||
|
}
|
||||||
|
|
||||||
|
// filtering subset of CAN IDs with hardware filters, need more filtering in software
|
||||||
|
void calculate_hw_can_filter(uint32_t device_id, twai_filter_config_t* filter, bool ota_mode) {
|
||||||
|
filter->single_filter = true;
|
||||||
|
filter->acceptance_code = device_id << 11;
|
||||||
|
if (ota_mode) {
|
||||||
|
filter->acceptance_code += 0x100000 << 11;
|
||||||
|
filter->acceptance_mask = ~((0x1000FF) << 11);
|
||||||
|
} else {
|
||||||
|
filter->acceptance_mask = ~((device_id | 0x1F0000) << 11);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void can_bus_off_check() {
|
||||||
|
uint32_t alerts = 0;
|
||||||
|
if (twai_read_alerts(&alerts, 0) == ESP_OK) {
|
||||||
|
if (alerts & TWAI_ALERT_BUS_OFF) {
|
||||||
|
ESP_ERROR_CHECK(twai_initiate_recovery());
|
||||||
|
}
|
||||||
|
if (alerts & TWAI_ALERT_BUS_RECOVERED) {
|
||||||
|
ESP_ERROR_CHECK(twai_start());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void can_task(void* arg) {
|
||||||
|
twai_message_t rx_msg;
|
||||||
|
// ESP_ERROR_CHECK(esp_task_wdt_add(NULL));
|
||||||
|
for (;;) { // A Task shall never return or exit.
|
||||||
|
// esp_task_wdt_reset();
|
||||||
|
can_bus_off_check();
|
||||||
|
if (twai_receive(&rx_msg, pdMS_TO_TICKS(10)) != ESP_OK) continue;
|
||||||
|
// TODO: add software filtering
|
||||||
|
// if ((((rx_msg.identifier >> 8) & 0xFF) != CONFIG_DEVICE_ID) && (((rx_msg.identifier >> 8) & 0xFF) != 0xFF)) continue;
|
||||||
|
ESP_LOGI(LOG_TAG, "received can package with ID: %" PRIu32, rx_msg.identifier);
|
||||||
|
// printf("received can package with ID: %" PRIu32, rx_msg.identifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
19
main/can.h
Normal file
19
main/can.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
//
|
||||||
|
// Created by okhsunrog on 8/17/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MAIN_CAN_H
|
||||||
|
#define MAIN_CAN_H
|
||||||
|
|
||||||
|
#include "driver/twai.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
// functions
|
||||||
|
|
||||||
|
void can_init();
|
||||||
|
void can_stop();
|
||||||
|
void calculate_hw_can_filter(uint32_t device_id, twai_filter_config_t* filter, bool ota_mode);
|
||||||
|
void can_bus_off_check();
|
||||||
|
void can_task(void* arg);
|
||||||
|
|
||||||
|
#endif // MAIN_CAN_H
|
277
main/cmd_system.c
Normal file
277
main/cmd_system.c
Normal file
|
@ -0,0 +1,277 @@
|
||||||
|
/* Console example — various system commands
|
||||||
|
|
||||||
|
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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_console.h"
|
||||||
|
#include "esp_chip_info.h"
|
||||||
|
#include "esp_sleep.h"
|
||||||
|
#include "esp_flash.h"
|
||||||
|
#include "driver/rtc_io.h"
|
||||||
|
#include "driver/uart.h"
|
||||||
|
#include "argtable3/argtable3.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "cmd_system.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
|
||||||
|
#define WITH_TASKS_INFO 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const char *TAG = "cmd_system";
|
||||||
|
|
||||||
|
static void register_free(void);
|
||||||
|
static void register_heap(void);
|
||||||
|
static void register_version(void);
|
||||||
|
static void register_restart(void);
|
||||||
|
#if WITH_TASKS_INFO
|
||||||
|
static void register_tasks(void);
|
||||||
|
#endif
|
||||||
|
static void register_log_level(void);
|
||||||
|
|
||||||
|
void register_system_common(void)
|
||||||
|
{
|
||||||
|
register_free();
|
||||||
|
register_heap();
|
||||||
|
register_version();
|
||||||
|
register_restart();
|
||||||
|
#if WITH_TASKS_INFO
|
||||||
|
register_tasks();
|
||||||
|
#endif
|
||||||
|
register_log_level();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void register_system(void)
|
||||||
|
{
|
||||||
|
register_system_common();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 'version' command */
|
||||||
|
static int get_version(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const char *model;
|
||||||
|
esp_chip_info_t info;
|
||||||
|
uint32_t flash_size;
|
||||||
|
esp_chip_info(&info);
|
||||||
|
|
||||||
|
switch(info.model) {
|
||||||
|
case CHIP_ESP32:
|
||||||
|
model = "ESP32";
|
||||||
|
break;
|
||||||
|
case CHIP_ESP32S2:
|
||||||
|
model = "ESP32-S2";
|
||||||
|
break;
|
||||||
|
case CHIP_ESP32S3:
|
||||||
|
model = "ESP32-S3";
|
||||||
|
break;
|
||||||
|
case CHIP_ESP32C3:
|
||||||
|
model = "ESP32-C3";
|
||||||
|
break;
|
||||||
|
case CHIP_ESP32H2:
|
||||||
|
model = "ESP32-H2";
|
||||||
|
break;
|
||||||
|
case CHIP_ESP32C2:
|
||||||
|
model = "ESP32-C2";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
model = "Unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(esp_flash_get_size(NULL, &flash_size) != ESP_OK) {
|
||||||
|
printf("Get flash size failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("IDF Version:%s\r\n", esp_get_idf_version());
|
||||||
|
printf("Chip info:\r\n");
|
||||||
|
printf("\tmodel:%s\r\n", model);
|
||||||
|
printf("\tcores:%d\r\n", info.cores);
|
||||||
|
printf("\tfeature:%s%s%s%s%"PRIu32"%s\r\n",
|
||||||
|
info.features & CHIP_FEATURE_WIFI_BGN ? "/802.11bgn" : "",
|
||||||
|
info.features & CHIP_FEATURE_BLE ? "/BLE" : "",
|
||||||
|
info.features & CHIP_FEATURE_BT ? "/BT" : "",
|
||||||
|
info.features & CHIP_FEATURE_EMB_FLASH ? "/Embedded-Flash:" : "/External-Flash:",
|
||||||
|
flash_size / (1024 * 1024), " MB");
|
||||||
|
printf("\trevision number:%d\r\n", info.revision);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void register_version(void)
|
||||||
|
{
|
||||||
|
const esp_console_cmd_t cmd = {
|
||||||
|
.command = "version",
|
||||||
|
.help = "Get version of chip and SDK",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &get_version,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 'restart' command restarts the program */
|
||||||
|
|
||||||
|
static int restart(int argc, char **argv)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Restarting");
|
||||||
|
esp_restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void register_restart(void)
|
||||||
|
{
|
||||||
|
const esp_console_cmd_t cmd = {
|
||||||
|
.command = "restart",
|
||||||
|
.help = "Software reset of the chip",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &restart,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 'free' command prints available heap memory */
|
||||||
|
|
||||||
|
static int free_mem(int argc, char **argv)
|
||||||
|
{
|
||||||
|
printf("%"PRIu32"\n", esp_get_free_heap_size());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void register_free(void)
|
||||||
|
{
|
||||||
|
const esp_console_cmd_t cmd = {
|
||||||
|
.command = "free",
|
||||||
|
.help = "Get the current size of free heap memory",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &free_mem,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 'heap' command prints minumum heap size */
|
||||||
|
static int heap_size(int argc, char **argv)
|
||||||
|
{
|
||||||
|
uint32_t heap_size = heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT);
|
||||||
|
printf("min heap size: %"PRIu32"\n", heap_size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void register_heap(void)
|
||||||
|
{
|
||||||
|
const esp_console_cmd_t heap_cmd = {
|
||||||
|
.command = "heap",
|
||||||
|
.help = "Get minimum size of free heap memory that was available during program execution",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &heap_size,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK( esp_console_cmd_register(&heap_cmd) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 'tasks' command prints the list of tasks and related information */
|
||||||
|
#if WITH_TASKS_INFO
|
||||||
|
|
||||||
|
static int tasks_info(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const size_t bytes_per_task = 40; /* see vTaskList description */
|
||||||
|
char *task_list_buffer = malloc(uxTaskGetNumberOfTasks() * bytes_per_task);
|
||||||
|
if (task_list_buffer == NULL) {
|
||||||
|
ESP_LOGE(TAG, "failed to allocate buffer for vTaskList output");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fputs("Task Name\tStatus\tPrio\tHWM\tTask#", stdout);
|
||||||
|
#ifdef CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID
|
||||||
|
fputs("\tAffinity", stdout);
|
||||||
|
#endif
|
||||||
|
fputs("\n", stdout);
|
||||||
|
vTaskList(task_list_buffer);
|
||||||
|
fputs(task_list_buffer, stdout);
|
||||||
|
free(task_list_buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void register_tasks(void)
|
||||||
|
{
|
||||||
|
const esp_console_cmd_t cmd = {
|
||||||
|
.command = "tasks",
|
||||||
|
.help = "Get information about running tasks",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &tasks_info,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // WITH_TASKS_INFO
|
||||||
|
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
struct arg_str *tag;
|
||||||
|
struct arg_str *level;
|
||||||
|
struct arg_end *end;
|
||||||
|
} log_level_args;
|
||||||
|
|
||||||
|
static const char* s_log_level_names[] = {
|
||||||
|
"none",
|
||||||
|
"error",
|
||||||
|
"warn",
|
||||||
|
"info",
|
||||||
|
"debug",
|
||||||
|
"verbose"
|
||||||
|
};
|
||||||
|
|
||||||
|
static int log_level(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int nerrors = arg_parse(argc, argv, (void **) &log_level_args);
|
||||||
|
if (nerrors != 0) {
|
||||||
|
arg_print_errors(stderr, log_level_args.end, argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
assert(log_level_args.tag->count == 1);
|
||||||
|
assert(log_level_args.level->count == 1);
|
||||||
|
const char* tag = log_level_args.tag->sval[0];
|
||||||
|
const char* level_str = log_level_args.level->sval[0];
|
||||||
|
esp_log_level_t level;
|
||||||
|
size_t level_len = strlen(level_str);
|
||||||
|
for (level = ESP_LOG_NONE; level <= ESP_LOG_VERBOSE; level++) {
|
||||||
|
if (memcmp(level_str, s_log_level_names[level], level_len) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (level > ESP_LOG_VERBOSE) {
|
||||||
|
printf("Invalid log level '%s', choose from none|error|warn|info|debug|verbose\n", level_str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (level > CONFIG_LOG_MAXIMUM_LEVEL) {
|
||||||
|
printf("Can't set log level to %s, max level limited in menuconfig to %s. "
|
||||||
|
"Please increase CONFIG_LOG_MAXIMUM_LEVEL in menuconfig.\n",
|
||||||
|
s_log_level_names[level], s_log_level_names[CONFIG_LOG_MAXIMUM_LEVEL]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
esp_log_level_set(tag, level);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void register_log_level(void)
|
||||||
|
{
|
||||||
|
log_level_args.tag = arg_str1(NULL, NULL, "<tag|*>", "Log tag to set the level for, or * to set for all tags");
|
||||||
|
log_level_args.level = arg_str1(NULL, NULL, "<none|error|warn|debug|verbose>", "Log level to set. Abbreviated words are accepted.");
|
||||||
|
log_level_args.end = arg_end(2);
|
||||||
|
|
||||||
|
const esp_console_cmd_t cmd = {
|
||||||
|
.command = "log_level",
|
||||||
|
.help = "Set log level for all tags or a specific tag.",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &log_level,
|
||||||
|
.argtable = &log_level_args
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
|
||||||
|
}
|
13
main/cmd_system.h
Normal file
13
main/cmd_system.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef MAIN_CMD_SYSTEM_H
|
||||||
|
#define MAIN_CMD_SYSTEM_H
|
||||||
|
|
||||||
|
// Register all system functions
|
||||||
|
void register_system(void);
|
||||||
|
|
||||||
|
// Register common system functions: "version", "restart", "free", "heap", "tasks"
|
||||||
|
void register_system_common(void);
|
||||||
|
|
||||||
|
// Register deep and light sleep functions
|
||||||
|
void register_system_sleep(void);
|
||||||
|
|
||||||
|
#endif // MAIN_CMD_SYSTEM_H
|
81
main/console_task.c
Normal file
81
main/console_task.c
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
#include "console_task.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "esp_system.h"
|
||||||
|
//#include "argtable3/argtable3.h"
|
||||||
|
#include "linenoise/linenoise.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_console.h"
|
||||||
|
#include "fs.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
|
||||||
|
#define PROMPT_STR "[root@can_wiz ~]$ "
|
||||||
|
|
||||||
|
static const char* TAG = "console task";
|
||||||
|
|
||||||
|
|
||||||
|
void console_task(void* arg) {
|
||||||
|
|
||||||
|
/* Prompt to be printed before each line.
|
||||||
|
* This can be customized, made dynamic, etc.
|
||||||
|
*/
|
||||||
|
const char* prompt = LOG_COLOR_E PROMPT_STR LOG_RESET_COLOR;
|
||||||
|
|
||||||
|
printf("\n"
|
||||||
|
"Type 'help' to get the list of commands.\n"
|
||||||
|
"Use UP/DOWN arrows to navigate through command history.\n"
|
||||||
|
"Press TAB when typing command name to auto-complete.\n"
|
||||||
|
"Ctrl+C will terminate the console environment.\n");
|
||||||
|
|
||||||
|
/* Figure out if the terminal supports escape sequences */
|
||||||
|
int probe_status = linenoiseProbe();
|
||||||
|
if (probe_status) { /* zero indicates success */
|
||||||
|
printf("\n"
|
||||||
|
"Your terminal application does not support escape sequences.\n"
|
||||||
|
"Line editing and history features are disabled.\n"
|
||||||
|
"On Windows, try using Putty instead.\n");
|
||||||
|
linenoiseSetDumbMode(1);
|
||||||
|
#if CONFIG_LOG_COLORS
|
||||||
|
/* Since the terminal doesn't support escape sequences,
|
||||||
|
* don't use color codes in the prompt.
|
||||||
|
*/
|
||||||
|
prompt = PROMPT_STR;
|
||||||
|
#endif // CONFIG_LOG_COLORS
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Main loop */
|
||||||
|
while (true) {
|
||||||
|
/* Get a line using linenoise.
|
||||||
|
* The line is returned when ENTER is pressed.
|
||||||
|
*/
|
||||||
|
char* line = linenoise(prompt);
|
||||||
|
if (line == NULL) { /* Break on EOF or error */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Add the command to the history if not empty*/
|
||||||
|
if (strlen(line) > 0) {
|
||||||
|
linenoiseHistoryAdd(line);
|
||||||
|
/* Save command history to filesystem */
|
||||||
|
linenoiseHistorySave(HISTORY_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to run the command */
|
||||||
|
int ret;
|
||||||
|
esp_err_t err = esp_console_run(line, &ret);
|
||||||
|
if (err == ESP_ERR_NOT_FOUND) {
|
||||||
|
printf("Unrecognized command\n");
|
||||||
|
} else if (err == ESP_ERR_INVALID_ARG) {
|
||||||
|
// command was empty
|
||||||
|
} else if (err == ESP_OK && ret != ESP_OK) {
|
||||||
|
printf("Command returned non-zero error code: 0x%x (%s)\n", ret, esp_err_to_name(ret));
|
||||||
|
} else if (err != ESP_OK) {
|
||||||
|
printf("Internal error: %s\n", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
/* linenoise allocates line buffer on the heap, so need to free it */
|
||||||
|
linenoiseFree(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGE(TAG, "Error or end-of-input, terminating console");
|
||||||
|
esp_console_deinit();
|
||||||
|
}
|
8
main/console_task.h
Normal file
8
main/console_task.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef MAIN_CONSOLE_TASK_H
|
||||||
|
#define MAIN_CONSOLE_TASK_H
|
||||||
|
|
||||||
|
// functions
|
||||||
|
|
||||||
|
void console_task(void* arg);
|
||||||
|
|
||||||
|
#endif // MAIN_CONSOLE_TASK_H
|
20
main/fs.c
Normal file
20
main/fs.c
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include "fs.h"
|
||||||
|
#include "esp_vfs_fat.h"
|
||||||
|
|
||||||
|
static const char* TAG = "fs";
|
||||||
|
|
||||||
|
/* Console command history can be stored to and loaded from a file.
|
||||||
|
* The easiest way to do this is to use FATFS filesystem on top of
|
||||||
|
* wear_levelling library.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void initialize_filesystem(void) {
|
||||||
|
static wl_handle_t wl_handle;
|
||||||
|
const esp_vfs_fat_mount_config_t mount_config = {.max_files = 4, .format_if_mount_failed = true};
|
||||||
|
esp_err_t err = esp_vfs_fat_spiflash_mount_rw_wl(MOUNT_PATH, "storage", &mount_config, &wl_handle);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
11
main/fs.h
Normal file
11
main/fs.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef MAIN_FS_H
|
||||||
|
#define MAIN_FS_H
|
||||||
|
|
||||||
|
#define MOUNT_PATH "/data"
|
||||||
|
#define HISTORY_PATH MOUNT_PATH "/history.txt"
|
||||||
|
|
||||||
|
// functions
|
||||||
|
|
||||||
|
void initialize_filesystem(void);
|
||||||
|
|
||||||
|
#endif // MAIN_FS_H
|
83
main/main.c
Normal file
83
main/main.c
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_console.h"
|
||||||
|
#include "esp_vfs_dev.h"
|
||||||
|
#include "linenoise/linenoise.h"
|
||||||
|
#include "esp_vfs_usb_serial_jtag.h"
|
||||||
|
#include "driver/usb_serial_jtag.h"
|
||||||
|
#include "cmd_system.h"
|
||||||
|
#include "can.h"
|
||||||
|
#include "fs.h"
|
||||||
|
#include "console_task.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void initialize_console(void) {
|
||||||
|
/* Disable buffering on stdin */
|
||||||
|
setvbuf(stdin, NULL, _IONBF, 0);
|
||||||
|
|
||||||
|
/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
|
||||||
|
esp_vfs_dev_usb_serial_jtag_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
|
||||||
|
/* Move the caret to the beginning of the next line on '\n' */
|
||||||
|
esp_vfs_dev_usb_serial_jtag_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
|
||||||
|
|
||||||
|
/* Enable non-blocking mode on stdin and stdout */
|
||||||
|
fcntl(fileno(stdout), F_SETFL, 0);
|
||||||
|
fcntl(fileno(stdin), F_SETFL, 0);
|
||||||
|
|
||||||
|
usb_serial_jtag_driver_config_t usb_serial_jtag_config = USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT();
|
||||||
|
|
||||||
|
/* Install USB-SERIAL-JTAG driver for interrupt-driven reads and writes */
|
||||||
|
ESP_ERROR_CHECK(usb_serial_jtag_driver_install(&usb_serial_jtag_config));
|
||||||
|
|
||||||
|
/* Tell vfs to use usb-serial-jtag driver */
|
||||||
|
esp_vfs_usb_serial_jtag_use_driver();
|
||||||
|
|
||||||
|
/* Initialize the console */
|
||||||
|
esp_console_config_t console_config = {
|
||||||
|
.max_cmdline_args = 8,
|
||||||
|
.max_cmdline_length = 256,
|
||||||
|
#if CONFIG_LOG_COLORS
|
||||||
|
.hint_color = atoi(LOG_COLOR_CYAN)
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_console_init(&console_config));
|
||||||
|
|
||||||
|
/* Configure linenoise line completion library */
|
||||||
|
/* Enable multiline editing. If not set, long commands will scroll within
|
||||||
|
* single line.
|
||||||
|
*/
|
||||||
|
linenoiseSetMultiLine(1);
|
||||||
|
|
||||||
|
/* Tell linenoise where to get command completions and hints */
|
||||||
|
linenoiseSetCompletionCallback(&esp_console_get_completion);
|
||||||
|
linenoiseSetHintsCallback((linenoiseHintsCallback*) &esp_console_get_hint);
|
||||||
|
|
||||||
|
/* Set command history size */
|
||||||
|
linenoiseHistorySetMaxLen(100);
|
||||||
|
|
||||||
|
/* Set command maximum length */
|
||||||
|
linenoiseSetMaxLineLen(console_config.max_cmdline_length);
|
||||||
|
|
||||||
|
/* Allow empty lines */
|
||||||
|
linenoiseAllowEmpty(true);
|
||||||
|
|
||||||
|
/* Load command history from filesystem */
|
||||||
|
linenoiseHistoryLoad(HISTORY_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_main(void) {
|
||||||
|
can_init();
|
||||||
|
xTaskCreate(can_task, "can task", 4096, NULL, CONFIG_CAN_TASK_PRIORITY, NULL);
|
||||||
|
initialize_filesystem();
|
||||||
|
initialize_console();
|
||||||
|
|
||||||
|
/* Register commands */
|
||||||
|
esp_console_register_help_command();
|
||||||
|
register_system();
|
||||||
|
|
||||||
|
xTaskCreate(console_task, "console task", 4096, NULL, CONFIG_CONSOLE_TASK_PRIORITY, NULL);
|
||||||
|
|
||||||
|
}
|
6
partitions.csv
Normal file
6
partitions.csv
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||||
|
nvs, data, nvs, 0x9000, 0x6000,
|
||||||
|
phy_init, data, phy, 0xf000, 0x1000,
|
||||||
|
factory, app, factory, 0x10000, 1M,
|
||||||
|
storage, data, fat, , 1M,
|
|
Loading…
Reference in a new issue