├── .gitattributes
├── .github
└── workflows
│ └── build-firmware.yml
├── .gitignore
├── CMakeLists.txt
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── boards
├── node32s.json
└── pico32_cust.json
├── doc
├── ClickActions.png
├── SelectCommit.png
├── downloadartifacts.png
└── espflashdownloadtool.png
├── img
└── icon.cdr
├── include
└── README
├── lib
└── README
├── pico_partitions.csv
├── platformio.ini
├── sdkconfig.C3Mini
├── sdkconfig.C3Mini_2
├── sdkconfig.C3SuperMini
├── sdkconfig.HappymodelEP82
├── sdkconfig.Node32s_Wroom32
├── sdkconfig.RM_pico
├── sdkconfig.pico32
├── sdkconfig.pico32_debug
├── src
├── .clang-format
├── CMakeLists.txt
├── bt.c
├── bt.h
├── bt_client.c
├── bt_client.h
├── bt_server.c
├── bt_server.h
├── cb.h
├── defines.h
├── frskybt.c
├── frskybt.h
├── main.c
├── settings.c
├── settings.h
├── terminal.c
└── terminal.h
├── test
├── README
└── test_cb.c
└── workspace.code-workspace
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/workflows/build-firmware.yml:
--------------------------------------------------------------------------------
1 | name: Firmware Build
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | paths:
8 | - '.github/workflows/build-firmware.yml'
9 | - 'src/**'
10 |
11 | pull_request:
12 | branches:
13 | - main
14 | paths:
15 | - '.github/workflows/build-firmware.yml'
16 | - 'src/**'
17 |
18 | workflow_dispatch:
19 |
20 | jobs:
21 | build:
22 | runs-on: ubuntu-20.04
23 | container:
24 | image: shaguarger/platformio
25 | volumes:
26 | - ${{ github.workspace }}:/src
27 |
28 | # Steps represent a sequence of tasks that will be executed as part of the job
29 | steps:
30 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
31 | - uses: actions/checkout@v4
32 |
33 | - name: Cache pip
34 | uses: actions/cache@v4
35 | with:
36 | path: ~/.cache/pip
37 | key: ${{ runner.os }}-pip
38 | restore-keys: |
39 | ${{ runner.os }}-pip-
40 |
41 | - name: Cache PlatformIO
42 | uses: actions/cache@v4
43 | with:
44 | path: ~/.platformio
45 | key: ${{ runner.os }}-pio
46 |
47 | - name: Set up Python
48 | uses: actions/setup-python@v4
49 |
50 | - name: Install PlatformIO
51 | run: |
52 | python -m pip install --upgrade pip
53 | pip install --upgrade platformio
54 |
55 | # Runs a single command using the runners shell
56 | - name: Build Firmware Pico32
57 | run: |
58 | cd /src
59 | pio run -e pico32
60 |
61 | - name: Build Firmware Wroom32
62 | run: |
63 | cd /src
64 | pio run -e Node32s_Wroom32
65 |
66 | - name: Build Firmware C3Mini
67 | run: |
68 | cd /src
69 | pio run -e C3Mini
70 |
71 | - name: Build Firmware C3SuperMini
72 | run: |
73 | cd /src
74 | pio run -e C3SuperMini
75 |
76 | - name: Build Firmware RM_pico
77 | run: |
78 | cd /src
79 | pio run -e RM_pico
80 |
81 |
82 | # Runs a set of commands using the runners shell
83 | - name: Package Firmware
84 | uses: 'actions/upload-artifact@v4'
85 | with:
86 | name: firmware
87 | path: |
88 | /src/.pio/build/*/*.bin
89 | retention-days: 60
90 | if-no-files-found: error
91 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # This file is used to ignore files which are generated
2 | # ----------------------------------------------------------------------------
3 |
4 | *~
5 | *.autosave
6 | *.a
7 | *.core
8 | *.moc
9 | *.o
10 | *.obj
11 | *.orig
12 | *.rej
13 | *.so
14 | *.so.*
15 | *_pch.h.cpp
16 | *_resource.rc
17 | *.qm
18 | .#*
19 | *.*#
20 | core
21 | !core/
22 | tags
23 | .DS_Store
24 | .directory
25 | *.debug
26 | Makefile*
27 | *.prl
28 | *.app
29 | moc_*.cpp
30 | ui_*.h
31 | qrc_*.cpp
32 | Thumbs.db
33 | *.res
34 | *.rc
35 | /.qmake.cache
36 | /.qmake.stash
37 |
38 | # qtcreator generated files
39 | *.pro.user*
40 |
41 | # xemacs temporary files
42 | *.flc
43 |
44 | # Vim temporary files
45 | .*.swp
46 |
47 | # Visual Studio generated files
48 | *.ib_pdb_index
49 | *.idb
50 | *.ilk
51 | *.pdb
52 | *.sln
53 | *.suo
54 | *.vcproj
55 | *vcproj.*.*.user
56 | *.ncb
57 | *.sdf
58 | *.opensdf
59 | *.vcxproj
60 | *vcxproj.*
61 | __vm*
62 | Release/
63 |
64 | # MinGW generated files
65 | *.Debug
66 | *.Release
67 |
68 | # Python byte code
69 | *.pyc
70 |
71 | # Binaries
72 | # --------
73 | *.dll
74 | *.exe
75 | .pio
76 | .vscode/*
77 | *.old
78 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.16.0)
2 | include($ENV{IDF_PATH}/tools/cmake/project.cmake)
3 | project(BTWifiModule)
4 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of age, body
7 | size, visible or invisible disability, ethnicity, sex characteristics, gender
8 | identity and expression, level of experience, education, socio-economic status,
9 | nationality, personal appearance, race, religion, or sexual identity
10 | and orientation.
11 |
12 | We pledge to act and interact in ways that contribute to an open, welcoming,
13 | diverse, inclusive, and healthy community.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to a positive environment for our
18 | community include:
19 |
20 | * Demonstrating empathy and kindness toward other people
21 | * Being respectful of differing opinions, viewpoints, and experiences
22 | * Giving and gracefully accepting constructive feedback
23 | * Accepting responsibility and apologizing to those affected by our mistakes,
24 | and learning from the experience
25 | * Focusing on what is best not just for us as individuals, but for the
26 | overall community
27 |
28 | Examples of unacceptable behavior include:
29 |
30 | * The use of sexualized language or imagery, and sexual attention or
31 | advances of any kind
32 | * Trolling, insulting or derogatory comments, and personal or political attacks
33 | * Public or private harassment
34 | * Publishing others' private information, such as a physical or email
35 | address, without their explicit permission
36 | * Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | ## Enforcement Responsibilities
40 |
41 | Community leaders are responsible for clarifying and enforcing our standards of
42 | acceptable behavior and will take appropriate and fair corrective action in
43 | response to any behavior that they deem inappropriate, threatening, offensive,
44 | or harmful.
45 |
46 | Community leaders have the right and responsibility to remove, edit, or reject
47 | comments, commits, code, wiki edits, issues, and other contributions that are
48 | not aligned to this Code of Conduct, and will communicate reasons for moderation
49 | decisions when appropriate.
50 |
51 | ## Scope
52 |
53 | This Code of Conduct applies within all community spaces, and also applies when
54 | an individual is officially representing the community in public spaces.
55 | Examples of representing our community include using an official e-mail address,
56 | posting via an official social media account, or acting as an appointed
57 | representative at an online or offline event.
58 |
59 | ## Enforcement
60 |
61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
62 | reported to the community leaders responsible for enforcement at
63 | cblackburn320@gmail.com.
64 | All complaints will be reviewed and investigated promptly and fairly.
65 |
66 | All community leaders are obligated to respect the privacy and security of the
67 | reporter of any incident.
68 |
69 | ## Enforcement Guidelines
70 |
71 | Community leaders will follow these Community Impact Guidelines in determining
72 | the consequences for any action they deem in violation of this Code of Conduct:
73 |
74 | ### 1. Correction
75 |
76 | **Community Impact**: Use of inappropriate language or other behavior deemed
77 | unprofessional or unwelcome in the community.
78 |
79 | **Consequence**: A private, written warning from community leaders, providing
80 | clarity around the nature of the violation and an explanation of why the
81 | behavior was inappropriate. A public apology may be requested.
82 |
83 | ### 2. Warning
84 |
85 | **Community Impact**: A violation through a single incident or series
86 | of actions.
87 |
88 | **Consequence**: A warning with consequences for continued behavior. No
89 | interaction with the people involved, including unsolicited interaction with
90 | those enforcing the Code of Conduct, for a specified period of time. This
91 | includes avoiding interactions in community spaces as well as external channels
92 | like social media. Violating these terms may lead to a temporary or
93 | permanent ban.
94 |
95 | ### 3. Temporary Ban
96 |
97 | **Community Impact**: A serious violation of community standards, including
98 | sustained inappropriate behavior.
99 |
100 | **Consequence**: A temporary ban from any sort of interaction or public
101 | communication with the community for a specified period of time. No public or
102 | private interaction with the people involved, including unsolicited interaction
103 | with those enforcing the Code of Conduct, is allowed during this period.
104 | Violating these terms may lead to a permanent ban.
105 |
106 | ### 4. Permanent Ban
107 |
108 | **Community Impact**: Demonstrating a pattern of violation of community
109 | standards, including sustained inappropriate behavior, harassment of an
110 | individual, or aggression toward or disparagement of classes of individuals.
111 |
112 | **Consequence**: A permanent ban from any sort of public interaction within
113 | the community.
114 |
115 | ## Attribution
116 |
117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118 | version 2.0, available at
119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
120 |
121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct
122 | enforcement ladder](https://github.com/mozilla/diversity).
123 |
124 | [homepage]: https://www.contributor-covenant.org
125 |
126 | For answers to common questions about this code of conduct, see the FAQ at
127 | https://www.contributor-covenant.org/faq. Translations are available at
128 | https://www.contributor-covenant.org/translations.
129 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## How to Contribute to BTWifiModule
2 |
3 | #### Testing, Bug Reporting
4 |
5 | * We need lots of testers out there to test features and report any bugs found.
6 | * If you find a bug please make sure it hasn't already been reported.
7 | * If it hasn't been reported. Create an issue here [Issues](https://github.com/dlktdr/BTWifiModule/issues)
8 | * Please include as many details as possible.
9 | * Radio type
10 | * Version used
11 | * What your connecting to
12 | * Log files
13 | * Please do not make an issue without details, it is going to be very difficult to help. Include them upfront
14 |
15 | #### Programming, Changes and Pull Requests
16 |
17 | * This is a community project, feel free to make changes, discussion and create pull requests. There are lots of features to be worked on I would appriciate the help.
18 | * Visit the discord chat to chat in realtime on tasks.
19 | * If you find a bug and you can fix it yourself. Awesome! make a Pull Request.
20 | * This project is built with PlatformIO, an excellent way to get into programming microcontrollers. Please visit the documentation on how to get the build environment setup.
21 | * Beginners to advanced users are welcome, don't be affraid to ask questions.
22 |
23 | #### Documentation
24 |
25 | * For a successful and easy to use project good documentation is a must. If you would like to support this
26 |
27 | Thanks,
28 | Cliff @dlktdr
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BTWifiModule
2 | Frsky Bluetooth Emulator
3 |
4 | This code is for use on a ESP Wroom 32, it emulates a FRSky Bluetooth module but with way more future possibilities.
5 |
6 | ## Documentation for this project is at Git Book
7 | ### https://btwifimod.gitbook.io/
8 |
--------------------------------------------------------------------------------
/boards/node32s.json:
--------------------------------------------------------------------------------
1 | {
2 | "build": {
3 | "arduino":{
4 | "ldscript": "esp32_out.ld"
5 | },
6 | "core": "esp32",
7 | "extra_flags": "-DARDUINO_Node32s",
8 | "f_cpu": "240000000L",
9 | "f_flash": "40000000L",
10 | "flash_mode": "dio",
11 | "mcu": "esp32",
12 | "variant": "esp32"
13 | },
14 | "connectivity": [
15 | "wifi",
16 | "bluetooth",
17 | "ethernet",
18 | "can"
19 | ],
20 | "debug": {
21 | "openocd_board": "esp-wroom-32.cfg"
22 | },
23 | "frameworks": [
24 | "arduino",
25 | "espidf"
26 | ],
27 | "name": "Node32s",
28 | "upload": {
29 | "flash_size": "4MB",
30 | "maximum_ram_size": 327680,
31 | "maximum_size": 4194304,
32 | "require_upload_port": true,
33 | "speed": 460800
34 | },
35 | "url": "http://www.ayarafun.com",
36 | "vendor": "Aiyarafun"
37 | }
38 |
--------------------------------------------------------------------------------
/boards/pico32_cust.json:
--------------------------------------------------------------------------------
1 | {
2 | "build": {
3 | "arduino":{
4 | "ldscript": "esp32_out.ld"
5 | },
6 | "core": "esp32",
7 | "extra_flags": "-DARDUINO_ESP32_PICO",
8 | "f_cpu": "240000000L",
9 | "f_flash": "40000000L",
10 | "flash_mode": "dio",
11 | "mcu": "esp32",
12 | "variant": "pico32",
13 | "partitions": "pico_partitions.csv"
14 | },
15 | "connectivity": [
16 | "wifi",
17 | "bluetooth",
18 | "ethernet",
19 | "can"
20 | ],
21 | "debug": {
22 | "openocd_board": "esp-wroom-32.cfg"
23 | },
24 | "frameworks": [
25 | "arduino",
26 | "espidf"
27 | ],
28 | "name": "ESP32 Pico Kit",
29 | "upload": {
30 | "flash_size": "4MB",
31 | "maximum_ram_size": 327680,
32 | "maximum_size": 4194304,
33 | "require_upload_port": true,
34 | "speed": 460800
35 | },
36 | "url": "http://esp-idf.readthedocs.io/en/latest/get-started/get-started-pico-kit.html",
37 | "vendor": "Espressif"
38 | }
39 |
--------------------------------------------------------------------------------
/doc/ClickActions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dlktdr/BTWifiModule/967353d4f14fd2c0340e4ca54054e0e9ce76560f/doc/ClickActions.png
--------------------------------------------------------------------------------
/doc/SelectCommit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dlktdr/BTWifiModule/967353d4f14fd2c0340e4ca54054e0e9ce76560f/doc/SelectCommit.png
--------------------------------------------------------------------------------
/doc/downloadartifacts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dlktdr/BTWifiModule/967353d4f14fd2c0340e4ca54054e0e9ce76560f/doc/downloadartifacts.png
--------------------------------------------------------------------------------
/doc/espflashdownloadtool.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dlktdr/BTWifiModule/967353d4f14fd2c0340e4ca54054e0e9ce76560f/doc/espflashdownloadtool.png
--------------------------------------------------------------------------------
/img/icon.cdr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dlktdr/BTWifiModule/967353d4f14fd2c0340e4ca54054e0e9ce76560f/img/icon.cdr
--------------------------------------------------------------------------------
/include/README:
--------------------------------------------------------------------------------
1 |
2 | This directory is intended for project header files.
3 |
4 | A header file is a file containing C declarations and macro definitions
5 | to be shared between several project source files. You request the use of a
6 | header file in your project source file (C, C++, etc) located in `src` folder
7 | by including it, with the C preprocessing directive `#include'.
8 |
9 | ```src/main.c
10 |
11 | #include "header.h"
12 |
13 | int main (void)
14 | {
15 | ...
16 | }
17 | ```
18 |
19 | Including a header file produces the same results as copying the header file
20 | into each source file that needs it. Such copying would be time-consuming
21 | and error-prone. With a header file, the related declarations appear
22 | in only one place. If they need to be changed, they can be changed in one
23 | place, and programs that include the header file will automatically use the
24 | new version when next recompiled. The header file eliminates the labor of
25 | finding and changing all the copies as well as the risk that a failure to
26 | find one copy will result in inconsistencies within a program.
27 |
28 | In C, the usual convention is to give header files names that end with `.h'.
29 | It is most portable to use only letters, digits, dashes, and underscores in
30 | header file names, and at most one dot.
31 |
32 | Read more about using header files in official GCC documentation:
33 |
34 | * Include Syntax
35 | * Include Operation
36 | * Once-Only Headers
37 | * Computed Includes
38 |
39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
40 |
--------------------------------------------------------------------------------
/lib/README:
--------------------------------------------------------------------------------
1 |
2 | This directory is intended for project specific (private) libraries.
3 | PlatformIO will compile them to static libraries and link into executable file.
4 |
5 | The source code of each library should be placed in a an own separate directory
6 | ("lib/your_library_name/[here are source files]").
7 |
8 | For example, see a structure of the following two libraries `Foo` and `Bar`:
9 |
10 | |--lib
11 | | |
12 | | |--Bar
13 | | | |--docs
14 | | | |--examples
15 | | | |--src
16 | | | |- Bar.c
17 | | | |- Bar.h
18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
19 | | |
20 | | |--Foo
21 | | | |- Foo.c
22 | | | |- Foo.h
23 | | |
24 | | |- README --> THIS FILE
25 | |
26 | |- platformio.ini
27 | |--src
28 | |- main.c
29 |
30 | and a contents of `src/main.c`:
31 | ```
32 | #include
33 | #include
34 |
35 | int main (void)
36 | {
37 | ...
38 | }
39 |
40 | ```
41 |
42 | PlatformIO Library Dependency Finder will find automatically dependent
43 | libraries scanning project source files.
44 |
45 | More information about PlatformIO Library Dependency Finder
46 | - https://docs.platformio.org/page/librarymanager/ldf.html
47 |
--------------------------------------------------------------------------------
/pico_partitions.csv:
--------------------------------------------------------------------------------
1 | # ESP-IDF Partition Table
2 | # Name, Type, SubType, Offset, Size, Flags
3 | nvs, data, nvs, 0x9000, 0x5000,
4 | phy_init, data, phy, 0xf000, 0x1000,
5 | factory, app, factory, 0x10000, 0x150000,
--------------------------------------------------------------------------------
/platformio.ini:
--------------------------------------------------------------------------------
1 | ; PlatformIO Project Configuration File
2 | ;
3 | ; Build options: build flags, source filter
4 | ; Upload options: custom upload port, speed and extra flags
5 | ; Library options: dependencies, extra library storages
6 | ; Advanced options: extra scripting
7 | ;
8 | ; Please visit documentation for the other options and examples
9 | ; https://docs.platformio.org/page/projectconf.html
10 |
11 | [platformio]
12 | default_envs = C3Mini
13 |
14 | [env]
15 | platform = espressif32
16 | framework = espidf
17 | build_unflags = -Werror=all
18 |
19 | [env:pico32_debug]
20 | upload_protocol = esptool
21 | upload_port = COM41
22 | board = pico32_cust
23 | debug_tool = esp-prog
24 | debug_speed = 6000
25 | debug_init_break = tbreak app_main
26 | board_build.partitions = pico_partitions.csv
27 | build_type = debug
28 | build_flags =
29 | -DRTOS_FREERTOS=y
30 | -DPCB_PICO=y
31 | -DCPU_ESP32=y
32 |
33 | [env:pico32]
34 | board = pico32_cust
35 | upload_protocol = esptool
36 | monitor_speed = 115200
37 | build_type = release
38 | board_build.partitions = pico_partitions.csv
39 | build_flags =
40 | -DRTOS_FREERTOS=y
41 | -DPCB_PICO=y
42 | -DCPU_ESP32=y
43 | -DBLUETOOTH=y
44 |
45 | [env:HappymodelEP82]
46 | platform = espressif8266
47 | board = esp8285
48 | board_build.ldscript = eagle.flash.1m144.ld
49 | upload_speed = 921600
50 | monitor_speed = 115200
51 | board_build.f_cpu = 160000000L
52 | upload_protocol = esptool
53 | upload_port = COM6
54 | build_type = release
55 | board_build.partitions = pico_partitions.csv
56 | build_flags =
57 | -DRTOS_FREERTOS=y
58 | -DPCB_HMEP82=y
59 | -DCPU_ESP8285=y
60 | -DSBUS_IN=y
61 |
62 | [env:Node32s_Wroom32]
63 | board = node32s
64 | upload_protocol = esptool
65 | monitor_speed = 115200
66 | upload_port = COM4
67 | #monitor_port = COM41
68 | #debug_tool = esp-prog
69 | #sboard_build.partitions = partitions.csv
70 | build_flags =
71 | -DRTOS_FREERTOS=y
72 | -DPCB_WROOM=y
73 | -DBLUETOOTH=y
74 | -DCPU_ESP32=y
75 |
76 | [env:C3Mini]
77 | board_build.flash_mode: dio
78 | board = esp32-c3-devkitm-1
79 | upload_protocol = esptool
80 | build_type = debug
81 | monitor_speed = 115200
82 | upload_port = COM4
83 | monitor_port = COM4
84 | #debug_tool = esptool
85 | build_flags =
86 | -DRTOS_FREERTOS=y
87 | -DPCB_C3MINI=y
88 | -DCPU_ESP32=y
89 | -DBLUETOOTH=y
90 | -DBLUETOOTH5=y
91 |
92 | [env:C3Mini_2]
93 | board_build.flash_mode: dio
94 | board = esp32-c3-devkitm-1
95 | upload_protocol = esptool
96 | build_type = debug
97 | monitor_speed = 115200
98 | upload_port = COM18
99 | monitor_port = COM18
100 | #debug_tool = esptool
101 | build_flags =
102 | -DRTOS_FREERTOS=y
103 | -DPCB_C3MINI=y
104 | -DCPU_ESP32=y
105 | -DBLUETOOTH=y
106 | -DBLUETOOTH5=y
107 |
108 | [env:RM_pico]
109 | board = pico32_cust
110 | upload_protocol = esptool
111 | monitor_speed = 115200
112 | build_type = release
113 | board_build.partitions = pico_partitions.csv
114 | build_flags =
115 | -DRTOS_FREERTOS=y
116 | -DPCB_RMPICO=y
117 | -DCPU_ESP32=y
118 | -DBLUETOOTH=y
119 |
120 | [env:C3SuperMini]
121 | board_build.flash_mode: dio
122 | board = esp32-c3-devkitm-1
123 | #debug_tool = esptool
124 | upload_protocol = esptool
125 | monitor_speed = 115200
126 | upload_port = /dev/ttyACM0
127 | monitor_port = /dev/ttyACM0
128 | build_flags =
129 | -DRTOS_FREERTOS=y
130 | -DPCB_C3SUPERMINI=y
131 | -DCPU_ESP32=y
132 | -DBLUETOOTH=y
133 | -DBLUETOOTH5=y
134 |
--------------------------------------------------------------------------------
/sdkconfig.HappymodelEP82:
--------------------------------------------------------------------------------
1 | #
2 | # Automatically generated file. DO NOT EDIT.
3 | # Espressif IoT Development Framework (ESP-IDF) Project Configuration
4 | #
5 | CONFIG_IDF_CMAKE=y
6 | CONFIG_IDF_TARGET_ARCH_XTENSA=y
7 | CONFIG_IDF_TARGET="esp32"
8 | CONFIG_IDF_TARGET_ESP32=y
9 | CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000
10 |
11 | #
12 | # SDK tool configuration
13 | #
14 | CONFIG_SDK_TOOLPREFIX="xtensa-esp32-elf-"
15 | # CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS is not set
16 | # end of SDK tool configuration
17 |
18 | #
19 | # Build type
20 | #
21 | CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y
22 | # CONFIG_APP_BUILD_TYPE_ELF_RAM is not set
23 | CONFIG_APP_BUILD_GENERATE_BINARIES=y
24 | CONFIG_APP_BUILD_BOOTLOADER=y
25 | CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y
26 | # end of Build type
27 |
28 | #
29 | # Application manager
30 | #
31 | CONFIG_APP_COMPILE_TIME_DATE=y
32 | # CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set
33 | # CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set
34 | # CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set
35 | CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16
36 | # end of Application manager
37 |
38 | #
39 | # Bootloader config
40 | #
41 | CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000
42 | CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
43 | # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set
44 | # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set
45 | # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set
46 | # CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set
47 | # CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set
48 | # CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set
49 | CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y
50 | # CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set
51 | # CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set
52 | CONFIG_BOOTLOADER_LOG_LEVEL=3
53 | # CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set
54 | CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y
55 | # CONFIG_BOOTLOADER_FACTORY_RESET is not set
56 | # CONFIG_BOOTLOADER_APP_TEST is not set
57 | CONFIG_BOOTLOADER_WDT_ENABLE=y
58 | # CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set
59 | CONFIG_BOOTLOADER_WDT_TIME_MS=9000
60 | # CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set
61 | # CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set
62 | # CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set
63 | # CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set
64 | CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0
65 | # CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set
66 | CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y
67 | # end of Bootloader config
68 |
69 | #
70 | # Security features
71 | #
72 | # CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set
73 | # CONFIG_SECURE_BOOT is not set
74 | # CONFIG_SECURE_FLASH_ENC_ENABLED is not set
75 | # end of Security features
76 |
77 | #
78 | # Serial flasher config
79 | #
80 | CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200
81 | # CONFIG_ESPTOOLPY_NO_STUB is not set
82 | # CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set
83 | # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set
84 | CONFIG_ESPTOOLPY_FLASHMODE_DIO=y
85 | # CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set
86 | CONFIG_ESPTOOLPY_FLASHMODE="dio"
87 | # CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set
88 | CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
89 | # CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set
90 | # CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set
91 | CONFIG_ESPTOOLPY_FLASHFREQ="40m"
92 | # CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
93 | CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y
94 | # CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set
95 | # CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
96 | # CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
97 | CONFIG_ESPTOOLPY_FLASHSIZE="2MB"
98 | CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
99 | CONFIG_ESPTOOLPY_BEFORE_RESET=y
100 | # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
101 | CONFIG_ESPTOOLPY_BEFORE="default_reset"
102 | CONFIG_ESPTOOLPY_AFTER_RESET=y
103 | # CONFIG_ESPTOOLPY_AFTER_NORESET is not set
104 | CONFIG_ESPTOOLPY_AFTER="hard_reset"
105 | # CONFIG_ESPTOOLPY_MONITOR_BAUD_CONSOLE is not set
106 | # CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set
107 | # CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set
108 | CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y
109 | # CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set
110 | # CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B is not set
111 | # CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set
112 | # CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set
113 | CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=115200
114 | CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
115 | # end of Serial flasher config
116 |
117 | #
118 | # Partition Table
119 | #
120 | CONFIG_PARTITION_TABLE_SINGLE_APP=y
121 | # CONFIG_PARTITION_TABLE_TWO_OTA is not set
122 | # CONFIG_PARTITION_TABLE_CUSTOM is not set
123 | CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
124 | CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv"
125 | CONFIG_PARTITION_TABLE_OFFSET=0x8000
126 | CONFIG_PARTITION_TABLE_MD5=y
127 | # end of Partition Table
128 |
129 | #
130 | # Compiler options
131 | #
132 | CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y
133 | # CONFIG_COMPILER_OPTIMIZATION_SIZE is not set
134 | # CONFIG_COMPILER_OPTIMIZATION_PERF is not set
135 | # CONFIG_COMPILER_OPTIMIZATION_NONE is not set
136 | CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
137 | # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set
138 | # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set
139 | # CONFIG_COMPILER_CXX_EXCEPTIONS is not set
140 | # CONFIG_COMPILER_CXX_RTTI is not set
141 | CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y
142 | # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set
143 | # CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set
144 | # CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set
145 | # CONFIG_COMPILER_WARN_WRITE_STRINGS is not set
146 | # CONFIG_COMPILER_DISABLE_GCC8_WARNINGS is not set
147 | # CONFIG_COMPILER_DUMP_RTL_FILES is not set
148 | # end of Compiler options
149 |
150 | #
151 | # Component config
152 | #
153 |
154 | #
155 | # Application Level Tracing
156 | #
157 | # CONFIG_APPTRACE_DEST_TRAX is not set
158 | CONFIG_APPTRACE_DEST_NONE=y
159 | CONFIG_APPTRACE_LOCK_ENABLE=y
160 | # end of Application Level Tracing
161 |
162 | #
163 | # ESP-ASIO
164 | #
165 | # CONFIG_ASIO_SSL_SUPPORT is not set
166 | # end of ESP-ASIO
167 |
168 | #
169 | # Bluetooth
170 | #
171 | # CONFIG_BT_ENABLED is not set
172 | CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0
173 | CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0
174 | CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0
175 | CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=0
176 | CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0
177 | CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0
178 | CONFIG_BTDM_CTRL_PINNED_TO_CORE=0
179 | CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1
180 | CONFIG_BT_CTRL_MODE_EFF=1
181 | CONFIG_BT_CTRL_BLE_MAX_ACT=10
182 | CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=10
183 | CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0
184 | CONFIG_BT_CTRL_PINNED_TO_CORE=0
185 | CONFIG_BT_CTRL_HCI_TL=1
186 | CONFIG_BT_CTRL_ADV_DUP_FILT_MAX=30
187 | CONFIG_BT_CTRL_HW_CCA_EFF=0
188 | CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=0
189 | CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y
190 | CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM=100
191 | CONFIG_BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD=20
192 | CONFIG_BT_CTRL_BLE_SCAN_DUPL=y
193 | CONFIG_BT_CTRL_SCAN_DUPL_TYPE=0
194 | CONFIG_BT_CTRL_SCAN_DUPL_CACHE_SIZE=100
195 | CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EFF=0
196 | CONFIG_BT_CTRL_SLEEP_MODE_EFF=0
197 | CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0
198 | CONFIG_BT_CTRL_HCI_TL_EFF=1
199 | CONFIG_BT_RESERVE_DRAM=0
200 | CONFIG_BT_NIMBLE_USE_ESP_TIMER=y
201 | # end of Bluetooth
202 |
203 | #
204 | # CoAP Configuration
205 | #
206 | CONFIG_COAP_MBEDTLS_PSK=y
207 | # CONFIG_COAP_MBEDTLS_PKI is not set
208 | # CONFIG_COAP_MBEDTLS_DEBUG is not set
209 | CONFIG_COAP_LOG_DEFAULT_LEVEL=0
210 | # end of CoAP Configuration
211 |
212 | #
213 | # Driver configurations
214 | #
215 |
216 | #
217 | # ADC configuration
218 | #
219 | # CONFIG_ADC_FORCE_XPD_FSM is not set
220 | CONFIG_ADC_DISABLE_DAC=y
221 | # end of ADC configuration
222 |
223 | #
224 | # SPI configuration
225 | #
226 | # CONFIG_SPI_MASTER_IN_IRAM is not set
227 | CONFIG_SPI_MASTER_ISR_IN_IRAM=y
228 | # CONFIG_SPI_SLAVE_IN_IRAM is not set
229 | CONFIG_SPI_SLAVE_ISR_IN_IRAM=y
230 | # end of SPI configuration
231 |
232 | #
233 | # TWAI configuration
234 | #
235 | # CONFIG_TWAI_ISR_IN_IRAM is not set
236 | # CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC is not set
237 | # CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST is not set
238 | # CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID is not set
239 | # CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT is not set
240 | # end of TWAI configuration
241 |
242 | #
243 | # UART configuration
244 | #
245 | # CONFIG_UART_ISR_IN_IRAM is not set
246 | # end of UART configuration
247 |
248 | #
249 | # RTCIO configuration
250 | #
251 | # CONFIG_RTCIO_SUPPORT_RTC_GPIO_DESC is not set
252 | # end of RTCIO configuration
253 |
254 | #
255 | # GPIO Configuration
256 | #
257 | # CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set
258 | # end of GPIO Configuration
259 | # end of Driver configurations
260 |
261 | #
262 | # eFuse Bit Manager
263 | #
264 | # CONFIG_EFUSE_CUSTOM_TABLE is not set
265 | # CONFIG_EFUSE_VIRTUAL is not set
266 | # CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set
267 | CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y
268 | # CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set
269 | CONFIG_EFUSE_MAX_BLK_LEN=192
270 | # end of eFuse Bit Manager
271 |
272 | #
273 | # ESP-TLS
274 | #
275 | CONFIG_ESP_TLS_USING_MBEDTLS=y
276 | # CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set
277 | # CONFIG_ESP_TLS_SERVER is not set
278 | # CONFIG_ESP_TLS_PSK_VERIFICATION is not set
279 | # CONFIG_ESP_TLS_INSECURE is not set
280 | # end of ESP-TLS
281 |
282 | #
283 | # ESP32-specific
284 | #
285 | CONFIG_ESP32_REV_MIN_0=y
286 | # CONFIG_ESP32_REV_MIN_1 is not set
287 | # CONFIG_ESP32_REV_MIN_2 is not set
288 | # CONFIG_ESP32_REV_MIN_3 is not set
289 | CONFIG_ESP32_REV_MIN=0
290 | CONFIG_ESP32_DPORT_WORKAROUND=y
291 | # CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set
292 | CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y
293 | # CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set
294 | CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160
295 | # CONFIG_ESP32_SPIRAM_SUPPORT is not set
296 | # CONFIG_ESP32_TRAX is not set
297 | CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0
298 | # CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set
299 | CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y
300 | CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4
301 | # CONFIG_ESP32_ULP_COPROC_ENABLED is not set
302 | CONFIG_ESP32_ULP_COPROC_RESERVE_MEM=0
303 | CONFIG_ESP32_DEBUG_OCDAWARE=y
304 | CONFIG_ESP32_BROWNOUT_DET=y
305 | CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y
306 | # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set
307 | # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set
308 | # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set
309 | # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set
310 | # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set
311 | # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set
312 | # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set
313 | CONFIG_ESP32_BROWNOUT_DET_LVL=0
314 | CONFIG_ESP32_REDUCE_PHY_TX_POWER=y
315 | CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y
316 | # CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set
317 | # CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set
318 | # CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set
319 | CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y
320 | # CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set
321 | # CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set
322 | # CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set
323 | CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024
324 | CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000
325 | CONFIG_ESP32_XTAL_FREQ_40=y
326 | # CONFIG_ESP32_XTAL_FREQ_26 is not set
327 | # CONFIG_ESP32_XTAL_FREQ_AUTO is not set
328 | CONFIG_ESP32_XTAL_FREQ=40
329 | # CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set
330 | # CONFIG_ESP32_NO_BLOBS is not set
331 | # CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set
332 | # CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set
333 | # CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set
334 | CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL=5
335 | # end of ESP32-specific
336 |
337 | #
338 | # ADC-Calibration
339 | #
340 | CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y
341 | CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y
342 | CONFIG_ADC_CAL_LUT_ENABLE=y
343 | # end of ADC-Calibration
344 |
345 | #
346 | # Common ESP-related
347 | #
348 | CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
349 | CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32
350 | CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304
351 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584
352 | CONFIG_ESP_IPC_TASK_STACK_SIZE=1024
353 | CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y
354 | CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048
355 | CONFIG_ESP_CONSOLE_UART_DEFAULT=y
356 | # CONFIG_ESP_CONSOLE_UART_CUSTOM is not set
357 | # CONFIG_ESP_CONSOLE_NONE is not set
358 | CONFIG_ESP_CONSOLE_UART=y
359 | CONFIG_ESP_CONSOLE_MULTIPLE_UART=y
360 | CONFIG_ESP_CONSOLE_UART_NUM=0
361 | CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200
362 | CONFIG_ESP_INT_WDT=y
363 | CONFIG_ESP_INT_WDT_TIMEOUT_MS=300
364 | CONFIG_ESP_INT_WDT_CHECK_CPU1=y
365 | CONFIG_ESP_TASK_WDT=y
366 | # CONFIG_ESP_TASK_WDT_PANIC is not set
367 | CONFIG_ESP_TASK_WDT_TIMEOUT_S=5
368 | CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y
369 | CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y
370 | # CONFIG_ESP_PANIC_HANDLER_IRAM is not set
371 | CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y
372 | CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y
373 | CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y
374 | CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y
375 | # end of Common ESP-related
376 |
377 | #
378 | # Ethernet
379 | #
380 | CONFIG_ETH_ENABLED=y
381 | CONFIG_ETH_USE_ESP32_EMAC=y
382 | CONFIG_ETH_PHY_INTERFACE_RMII=y
383 | # CONFIG_ETH_PHY_INTERFACE_MII is not set
384 | CONFIG_ETH_RMII_CLK_INPUT=y
385 | # CONFIG_ETH_RMII_CLK_OUTPUT is not set
386 | CONFIG_ETH_RMII_CLK_IN_GPIO=0
387 | CONFIG_ETH_DMA_BUFFER_SIZE=512
388 | CONFIG_ETH_DMA_RX_BUFFER_NUM=10
389 | CONFIG_ETH_DMA_TX_BUFFER_NUM=10
390 | CONFIG_ETH_USE_SPI_ETHERNET=y
391 | # CONFIG_ETH_SPI_ETHERNET_DM9051 is not set
392 | # CONFIG_ETH_SPI_ETHERNET_W5500 is not set
393 | # CONFIG_ETH_USE_OPENETH is not set
394 | # end of Ethernet
395 |
396 | #
397 | # Event Loop Library
398 | #
399 | # CONFIG_ESP_EVENT_LOOP_PROFILING is not set
400 | CONFIG_ESP_EVENT_POST_FROM_ISR=y
401 | CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y
402 | # end of Event Loop Library
403 |
404 | #
405 | # GDB Stub
406 | #
407 | # end of GDB Stub
408 |
409 | #
410 | # ESP HTTP client
411 | #
412 | CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y
413 | # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set
414 | # end of ESP HTTP client
415 |
416 | #
417 | # HTTP Server
418 | #
419 | CONFIG_HTTPD_MAX_REQ_HDR_LEN=512
420 | CONFIG_HTTPD_MAX_URI_LEN=512
421 | CONFIG_HTTPD_ERR_RESP_NO_DELAY=y
422 | CONFIG_HTTPD_PURGE_BUF_LEN=32
423 | # CONFIG_HTTPD_LOG_PURGE_DATA is not set
424 | # CONFIG_HTTPD_WS_SUPPORT is not set
425 | # end of HTTP Server
426 |
427 | #
428 | # ESP HTTPS OTA
429 | #
430 | # CONFIG_OTA_ALLOW_HTTP is not set
431 | # end of ESP HTTPS OTA
432 |
433 | #
434 | # ESP HTTPS server
435 | #
436 | # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set
437 | # end of ESP HTTPS server
438 |
439 | #
440 | # ESP NETIF Adapter
441 | #
442 | CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120
443 | CONFIG_ESP_NETIF_TCPIP_LWIP=y
444 | # CONFIG_ESP_NETIF_LOOPBACK is not set
445 | CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=y
446 | # end of ESP NETIF Adapter
447 |
448 | #
449 | # Power Management
450 | #
451 | # CONFIG_PM_ENABLE is not set
452 | # end of Power Management
453 |
454 | #
455 | # ESP System Settings
456 | #
457 | # CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set
458 | CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y
459 | # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set
460 | # CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set
461 | CONFIG_ESP_SYSTEM_PD_FLASH=y
462 | # CONFIG_ESP_SYSTEM_FLASH_LEAKAGE_WORKAROUND is not set
463 |
464 | #
465 | # Memory protection
466 | #
467 | # end of Memory protection
468 | # end of ESP System Settings
469 |
470 | #
471 | # High resolution timer (esp_timer)
472 | #
473 | # CONFIG_ESP_TIMER_PROFILING is not set
474 | CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y
475 | CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y
476 | CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584
477 | # CONFIG_ESP_TIMER_IMPL_FRC2 is not set
478 | CONFIG_ESP_TIMER_IMPL_TG0_LAC=y
479 | # end of High resolution timer (esp_timer)
480 |
481 | #
482 | # Wi-Fi
483 | #
484 | CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10
485 | CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32
486 | # CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set
487 | CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y
488 | CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1
489 | CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32
490 | # CONFIG_ESP32_WIFI_CSI_ENABLED is not set
491 | CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y
492 | CONFIG_ESP32_WIFI_TX_BA_WIN=6
493 | CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
494 | CONFIG_ESP32_WIFI_RX_BA_WIN=6
495 | CONFIG_ESP32_WIFI_NVS_ENABLED=y
496 | CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y
497 | # CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set
498 | CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752
499 | CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32
500 | # CONFIG_WIFI_LOG_DEFAULT_LEVEL_NONE is not set
501 | # CONFIG_WIFI_LOG_DEFAULT_LEVEL_ERROR is not set
502 | # CONFIG_WIFI_LOG_DEFAULT_LEVEL_WARN is not set
503 | CONFIG_WIFI_LOG_DEFAULT_LEVEL_INFO=y
504 | # CONFIG_WIFI_LOG_DEFAULT_LEVEL_DEBUG is not set
505 | # CONFIG_WIFI_LOG_DEFAULT_LEVEL_VERBOSE is not set
506 | CONFIG_ESP32_WIFI_IRAM_OPT=y
507 | CONFIG_ESP32_WIFI_RX_IRAM_OPT=y
508 | CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y
509 | # CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set
510 | # CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set
511 | # end of Wi-Fi
512 |
513 | #
514 | # PHY
515 | #
516 | CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y
517 | # CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set
518 | CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20
519 | CONFIG_ESP32_PHY_MAX_TX_POWER=20
520 | # end of PHY
521 |
522 | #
523 | # Core dump
524 | #
525 | # CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set
526 | # CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set
527 | CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y
528 | # end of Core dump
529 |
530 | #
531 | # FAT Filesystem support
532 | #
533 | # CONFIG_FATFS_CODEPAGE_DYNAMIC is not set
534 | CONFIG_FATFS_CODEPAGE_437=y
535 | # CONFIG_FATFS_CODEPAGE_720 is not set
536 | # CONFIG_FATFS_CODEPAGE_737 is not set
537 | # CONFIG_FATFS_CODEPAGE_771 is not set
538 | # CONFIG_FATFS_CODEPAGE_775 is not set
539 | # CONFIG_FATFS_CODEPAGE_850 is not set
540 | # CONFIG_FATFS_CODEPAGE_852 is not set
541 | # CONFIG_FATFS_CODEPAGE_855 is not set
542 | # CONFIG_FATFS_CODEPAGE_857 is not set
543 | # CONFIG_FATFS_CODEPAGE_860 is not set
544 | # CONFIG_FATFS_CODEPAGE_861 is not set
545 | # CONFIG_FATFS_CODEPAGE_862 is not set
546 | # CONFIG_FATFS_CODEPAGE_863 is not set
547 | # CONFIG_FATFS_CODEPAGE_864 is not set
548 | # CONFIG_FATFS_CODEPAGE_865 is not set
549 | # CONFIG_FATFS_CODEPAGE_866 is not set
550 | # CONFIG_FATFS_CODEPAGE_869 is not set
551 | # CONFIG_FATFS_CODEPAGE_932 is not set
552 | # CONFIG_FATFS_CODEPAGE_936 is not set
553 | # CONFIG_FATFS_CODEPAGE_949 is not set
554 | # CONFIG_FATFS_CODEPAGE_950 is not set
555 | CONFIG_FATFS_CODEPAGE=437
556 | CONFIG_FATFS_LFN_NONE=y
557 | # CONFIG_FATFS_LFN_HEAP is not set
558 | # CONFIG_FATFS_LFN_STACK is not set
559 | CONFIG_FATFS_FS_LOCK=0
560 | CONFIG_FATFS_TIMEOUT_MS=10000
561 | CONFIG_FATFS_PER_FILE_CACHE=y
562 | # CONFIG_FATFS_USE_FASTSEEK is not set
563 | # end of FAT Filesystem support
564 |
565 | #
566 | # Modbus configuration
567 | #
568 | CONFIG_FMB_COMM_MODE_TCP_EN=y
569 | CONFIG_FMB_TCP_PORT_DEFAULT=502
570 | CONFIG_FMB_TCP_PORT_MAX_CONN=5
571 | CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20
572 | CONFIG_FMB_COMM_MODE_RTU_EN=y
573 | CONFIG_FMB_COMM_MODE_ASCII_EN=y
574 | CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150
575 | CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200
576 | CONFIG_FMB_QUEUE_LENGTH=20
577 | CONFIG_FMB_PORT_TASK_STACK_SIZE=4096
578 | CONFIG_FMB_SERIAL_BUF_SIZE=256
579 | CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8
580 | CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000
581 | CONFIG_FMB_PORT_TASK_PRIO=10
582 | # CONFIG_FMB_PORT_TASK_AFFINITY_NO_AFFINITY is not set
583 | CONFIG_FMB_PORT_TASK_AFFINITY_CPU0=y
584 | # CONFIG_FMB_PORT_TASK_AFFINITY_CPU1 is not set
585 | CONFIG_FMB_PORT_TASK_AFFINITY=0x0
586 | CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y
587 | CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233
588 | CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20
589 | CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20
590 | CONFIG_FMB_CONTROLLER_STACK_SIZE=4096
591 | CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20
592 | # CONFIG_FMB_TIMER_PORT_ENABLED is not set
593 | CONFIG_FMB_TIMER_GROUP=0
594 | CONFIG_FMB_TIMER_INDEX=0
595 | CONFIG_FMB_MASTER_TIMER_GROUP=0
596 | CONFIG_FMB_MASTER_TIMER_INDEX=0
597 | # CONFIG_FMB_TIMER_ISR_IN_IRAM is not set
598 | # end of Modbus configuration
599 |
600 | #
601 | # FreeRTOS
602 | #
603 | # CONFIG_FREERTOS_UNICORE is not set
604 | CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF
605 | CONFIG_FREERTOS_CORETIMER_0=y
606 | # CONFIG_FREERTOS_CORETIMER_1 is not set
607 | CONFIG_FREERTOS_HZ=100
608 | CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y
609 | # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set
610 | # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set
611 | CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y
612 | # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
613 | CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y
614 | CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1
615 | CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y
616 | # CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set
617 | # CONFIG_FREERTOS_ASSERT_DISABLE is not set
618 | CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=2304
619 | CONFIG_FREERTOS_ISR_STACKSIZE=1536
620 | # CONFIG_FREERTOS_LEGACY_HOOKS is not set
621 | CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16
622 | CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y
623 | # CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set
624 | CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1
625 | CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048
626 | CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10
627 | CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0
628 | # CONFIG_FREERTOS_USE_TRACE_FACILITY is not set
629 | # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set
630 | CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y
631 | CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y
632 | # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set
633 | # CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set
634 | CONFIG_FREERTOS_DEBUG_OCDAWARE=y
635 | # CONFIG_FREERTOS_FPU_IN_ISR is not set
636 | # end of FreeRTOS
637 |
638 | #
639 | # Heap memory debugging
640 | #
641 | CONFIG_HEAP_POISONING_DISABLED=y
642 | # CONFIG_HEAP_POISONING_LIGHT is not set
643 | # CONFIG_HEAP_POISONING_COMPREHENSIVE is not set
644 | CONFIG_HEAP_TRACING_OFF=y
645 | # CONFIG_HEAP_TRACING_STANDALONE is not set
646 | # CONFIG_HEAP_TRACING_TOHOST is not set
647 | # CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set
648 | # end of Heap memory debugging
649 |
650 | #
651 | # jsmn
652 | #
653 | # CONFIG_JSMN_PARENT_LINKS is not set
654 | # CONFIG_JSMN_STRICT is not set
655 | # end of jsmn
656 |
657 | #
658 | # libsodium
659 | #
660 | # end of libsodium
661 |
662 | #
663 | # Log output
664 | #
665 | # CONFIG_LOG_DEFAULT_LEVEL_NONE is not set
666 | # CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set
667 | # CONFIG_LOG_DEFAULT_LEVEL_WARN is not set
668 | CONFIG_LOG_DEFAULT_LEVEL_INFO=y
669 | # CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set
670 | # CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set
671 | CONFIG_LOG_DEFAULT_LEVEL=3
672 | CONFIG_LOG_COLORS=y
673 | CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y
674 | # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set
675 | # end of Log output
676 |
677 | #
678 | # LWIP
679 | #
680 | CONFIG_LWIP_LOCAL_HOSTNAME="espressif"
681 | CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y
682 | # CONFIG_LWIP_L2_TO_L3_COPY is not set
683 | # CONFIG_LWIP_IRAM_OPTIMIZATION is not set
684 | CONFIG_LWIP_TIMERS_ONDEMAND=y
685 | CONFIG_LWIP_MAX_SOCKETS=10
686 | # CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set
687 | # CONFIG_LWIP_SO_LINGER is not set
688 | CONFIG_LWIP_SO_REUSE=y
689 | CONFIG_LWIP_SO_REUSE_RXTOALL=y
690 | # CONFIG_LWIP_SO_RCVBUF is not set
691 | # CONFIG_LWIP_NETBUF_RECVINFO is not set
692 | CONFIG_LWIP_IP4_FRAG=y
693 | CONFIG_LWIP_IP6_FRAG=y
694 | # CONFIG_LWIP_IP4_REASSEMBLY is not set
695 | # CONFIG_LWIP_IP6_REASSEMBLY is not set
696 | # CONFIG_LWIP_IP_FORWARD is not set
697 | # CONFIG_LWIP_STATS is not set
698 | # CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set
699 | CONFIG_LWIP_ESP_GRATUITOUS_ARP=y
700 | CONFIG_LWIP_GARP_TMR_INTERVAL=60
701 | CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
702 | CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y
703 | # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set
704 | # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set
705 |
706 | #
707 | # DHCP server
708 | #
709 | CONFIG_LWIP_DHCPS=y
710 | CONFIG_LWIP_DHCPS_LEASE_UNIT=60
711 | CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8
712 | # end of DHCP server
713 |
714 | # CONFIG_LWIP_AUTOIP is not set
715 | CONFIG_LWIP_IPV6=y
716 | # CONFIG_LWIP_IPV6_AUTOCONFIG is not set
717 | CONFIG_LWIP_NETIF_LOOPBACK=y
718 | CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8
719 |
720 | #
721 | # TCP
722 | #
723 | CONFIG_LWIP_MAX_ACTIVE_TCP=16
724 | CONFIG_LWIP_MAX_LISTENING_TCP=16
725 | CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y
726 | CONFIG_LWIP_TCP_MAXRTX=12
727 | CONFIG_LWIP_TCP_SYNMAXRTX=12
728 | CONFIG_LWIP_TCP_MSS=1440
729 | CONFIG_LWIP_TCP_TMR_INTERVAL=250
730 | CONFIG_LWIP_TCP_MSL=60000
731 | CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744
732 | CONFIG_LWIP_TCP_WND_DEFAULT=5744
733 | CONFIG_LWIP_TCP_RECVMBOX_SIZE=6
734 | CONFIG_LWIP_TCP_QUEUE_OOSEQ=y
735 | # CONFIG_LWIP_TCP_SACK_OUT is not set
736 | # CONFIG_LWIP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set
737 | CONFIG_LWIP_TCP_OVERSIZE_MSS=y
738 | # CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set
739 | # CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set
740 | CONFIG_LWIP_TCP_RTO_TIME=1500
741 | # end of TCP
742 |
743 | #
744 | # UDP
745 | #
746 | CONFIG_LWIP_MAX_UDP_PCBS=16
747 | CONFIG_LWIP_UDP_RECVMBOX_SIZE=6
748 | # end of UDP
749 |
750 | #
751 | # Checksums
752 | #
753 | # CONFIG_LWIP_CHECKSUM_CHECK_IP is not set
754 | # CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set
755 | CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y
756 | # end of Checksums
757 |
758 | CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072
759 | CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y
760 | # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set
761 | # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set
762 | CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF
763 | # CONFIG_LWIP_PPP_SUPPORT is not set
764 | CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3
765 | CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5
766 | # CONFIG_LWIP_SLIP_SUPPORT is not set
767 |
768 | #
769 | # ICMP
770 | #
771 | CONFIG_LWIP_ICMP=y
772 | # CONFIG_LWIP_MULTICAST_PING is not set
773 | # CONFIG_LWIP_BROADCAST_PING is not set
774 | # end of ICMP
775 |
776 | #
777 | # LWIP RAW API
778 | #
779 | CONFIG_LWIP_MAX_RAW_PCBS=16
780 | # end of LWIP RAW API
781 |
782 | #
783 | # SNTP
784 | #
785 | CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1
786 | CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000
787 | # end of SNTP
788 |
789 | CONFIG_LWIP_ESP_LWIP_ASSERT=y
790 |
791 | #
792 | # Hooks
793 | #
794 | # CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set
795 | CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y
796 | # CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set
797 | CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y
798 | # CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set
799 | # CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set
800 | CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y
801 | # CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set
802 | # CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set
803 | # end of Hooks
804 |
805 | # CONFIG_LWIP_DEBUG is not set
806 | # end of LWIP
807 |
808 | #
809 | # mbedTLS
810 | #
811 | CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y
812 | # CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set
813 | # CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set
814 | CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y
815 | CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384
816 | CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096
817 | # CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set
818 | # CONFIG_MBEDTLS_DEBUG is not set
819 |
820 | #
821 | # Certificate Bundle
822 | #
823 | CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y
824 | CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y
825 | # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set
826 | # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set
827 | # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set
828 | # end of Certificate Bundle
829 |
830 | # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set
831 | # CONFIG_MBEDTLS_CMAC_C is not set
832 | CONFIG_MBEDTLS_HARDWARE_AES=y
833 | CONFIG_MBEDTLS_HARDWARE_MPI=y
834 | CONFIG_MBEDTLS_HARDWARE_SHA=y
835 | CONFIG_MBEDTLS_ROM_MD5=y
836 | # CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set
837 | # CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set
838 | CONFIG_MBEDTLS_HAVE_TIME=y
839 | # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set
840 | CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y
841 | CONFIG_MBEDTLS_SHA512_C=y
842 | CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y
843 | # CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set
844 | # CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set
845 | # CONFIG_MBEDTLS_TLS_DISABLED is not set
846 | CONFIG_MBEDTLS_TLS_SERVER=y
847 | CONFIG_MBEDTLS_TLS_CLIENT=y
848 | CONFIG_MBEDTLS_TLS_ENABLED=y
849 |
850 | #
851 | # TLS Key Exchange Methods
852 | #
853 | # CONFIG_MBEDTLS_PSK_MODES is not set
854 | CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y
855 | CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y
856 | CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y
857 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y
858 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y
859 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y
860 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y
861 | # end of TLS Key Exchange Methods
862 |
863 | CONFIG_MBEDTLS_SSL_RENEGOTIATION=y
864 | # CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set
865 | CONFIG_MBEDTLS_SSL_PROTO_TLS1=y
866 | CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y
867 | CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y
868 | # CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set
869 | CONFIG_MBEDTLS_SSL_ALPN=y
870 | CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y
871 | CONFIG_MBEDTLS_X509_CHECK_KEY_USAGE=y
872 | CONFIG_MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE=y
873 | CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y
874 |
875 | #
876 | # Symmetric Ciphers
877 | #
878 | CONFIG_MBEDTLS_AES_C=y
879 | # CONFIG_MBEDTLS_CAMELLIA_C is not set
880 | # CONFIG_MBEDTLS_DES_C is not set
881 | CONFIG_MBEDTLS_RC4_DISABLED=y
882 | # CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set
883 | # CONFIG_MBEDTLS_RC4_ENABLED is not set
884 | # CONFIG_MBEDTLS_BLOWFISH_C is not set
885 | # CONFIG_MBEDTLS_XTEA_C is not set
886 | CONFIG_MBEDTLS_CCM_C=y
887 | CONFIG_MBEDTLS_GCM_C=y
888 | # CONFIG_MBEDTLS_NIST_KW_C is not set
889 | # end of Symmetric Ciphers
890 |
891 | # CONFIG_MBEDTLS_RIPEMD160_C is not set
892 |
893 | #
894 | # Certificates
895 | #
896 | CONFIG_MBEDTLS_PEM_PARSE_C=y
897 | CONFIG_MBEDTLS_PEM_WRITE_C=y
898 | CONFIG_MBEDTLS_X509_CRL_PARSE_C=y
899 | CONFIG_MBEDTLS_X509_CSR_PARSE_C=y
900 | # end of Certificates
901 |
902 | CONFIG_MBEDTLS_ECP_C=y
903 | CONFIG_MBEDTLS_ECDH_C=y
904 | CONFIG_MBEDTLS_ECDSA_C=y
905 | # CONFIG_MBEDTLS_ECJPAKE_C is not set
906 | CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y
907 | CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y
908 | CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y
909 | CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y
910 | CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y
911 | CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y
912 | CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y
913 | CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y
914 | CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y
915 | CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y
916 | CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y
917 | CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y
918 | CONFIG_MBEDTLS_ECP_NIST_OPTIM=y
919 | # CONFIG_MBEDTLS_POLY1305_C is not set
920 | # CONFIG_MBEDTLS_CHACHA20_C is not set
921 | # CONFIG_MBEDTLS_HKDF_C is not set
922 | # CONFIG_MBEDTLS_THREADING_C is not set
923 | # CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set
924 | # CONFIG_MBEDTLS_SECURITY_RISKS is not set
925 | # end of mbedTLS
926 |
927 | #
928 | # mDNS
929 | #
930 | CONFIG_MDNS_MAX_SERVICES=10
931 | CONFIG_MDNS_TASK_PRIORITY=1
932 | CONFIG_MDNS_TASK_STACK_SIZE=4096
933 | # CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set
934 | CONFIG_MDNS_TASK_AFFINITY_CPU0=y
935 | # CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set
936 | CONFIG_MDNS_TASK_AFFINITY=0x0
937 | CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000
938 | # CONFIG_MDNS_STRICT_MODE is not set
939 | CONFIG_MDNS_TIMER_PERIOD_MS=100
940 | # end of mDNS
941 |
942 | #
943 | # ESP-MQTT Configurations
944 | #
945 | CONFIG_MQTT_PROTOCOL_311=y
946 | CONFIG_MQTT_TRANSPORT_SSL=y
947 | CONFIG_MQTT_TRANSPORT_WEBSOCKET=y
948 | CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y
949 | # CONFIG_MQTT_MSG_ID_INCREMENTAL is not set
950 | # CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set
951 | # CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set
952 | # CONFIG_MQTT_USE_CUSTOM_CONFIG is not set
953 | # CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set
954 | # CONFIG_MQTT_CUSTOM_OUTBOX is not set
955 | # end of ESP-MQTT Configurations
956 |
957 | #
958 | # Newlib
959 | #
960 | CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y
961 | # CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set
962 | # CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set
963 | # CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set
964 | # CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set
965 | CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y
966 | # CONFIG_NEWLIB_NANO_FORMAT is not set
967 | # end of Newlib
968 |
969 | #
970 | # NVS
971 | #
972 | # end of NVS
973 |
974 | #
975 | # OpenSSL
976 | #
977 | # CONFIG_OPENSSL_DEBUG is not set
978 | CONFIG_OPENSSL_ERROR_STACK=y
979 | # CONFIG_OPENSSL_ASSERT_DO_NOTHING is not set
980 | CONFIG_OPENSSL_ASSERT_EXIT=y
981 | # end of OpenSSL
982 |
983 | #
984 | # PThreads
985 | #
986 | CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5
987 | CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072
988 | CONFIG_PTHREAD_STACK_MIN=768
989 | CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y
990 | # CONFIG_PTHREAD_DEFAULT_CORE_0 is not set
991 | # CONFIG_PTHREAD_DEFAULT_CORE_1 is not set
992 | CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1
993 | CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread"
994 | # end of PThreads
995 |
996 | #
997 | # SPI Flash driver
998 | #
999 | # CONFIG_SPI_FLASH_VERIFY_WRITE is not set
1000 | # CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set
1001 | CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y
1002 | CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y
1003 | # CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set
1004 | # CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set
1005 | # CONFIG_SPI_FLASH_USE_LEGACY_IMPL is not set
1006 | # CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set
1007 | # CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set
1008 | CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y
1009 | CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20
1010 | CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1
1011 | CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192
1012 | # CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set
1013 | # CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set
1014 |
1015 | #
1016 | # Auto-detect flash chips
1017 | #
1018 | CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y
1019 | CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y
1020 | CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y
1021 | CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y
1022 | # end of Auto-detect flash chips
1023 |
1024 | CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y
1025 | # end of SPI Flash driver
1026 |
1027 | #
1028 | # SPIFFS Configuration
1029 | #
1030 | CONFIG_SPIFFS_MAX_PARTITIONS=3
1031 |
1032 | #
1033 | # SPIFFS Cache Configuration
1034 | #
1035 | CONFIG_SPIFFS_CACHE=y
1036 | CONFIG_SPIFFS_CACHE_WR=y
1037 | # CONFIG_SPIFFS_CACHE_STATS is not set
1038 | # end of SPIFFS Cache Configuration
1039 |
1040 | CONFIG_SPIFFS_PAGE_CHECK=y
1041 | CONFIG_SPIFFS_GC_MAX_RUNS=10
1042 | # CONFIG_SPIFFS_GC_STATS is not set
1043 | CONFIG_SPIFFS_PAGE_SIZE=256
1044 | CONFIG_SPIFFS_OBJ_NAME_LEN=32
1045 | # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set
1046 | CONFIG_SPIFFS_USE_MAGIC=y
1047 | CONFIG_SPIFFS_USE_MAGIC_LENGTH=y
1048 | CONFIG_SPIFFS_META_LENGTH=4
1049 | CONFIG_SPIFFS_USE_MTIME=y
1050 |
1051 | #
1052 | # Debug Configuration
1053 | #
1054 | # CONFIG_SPIFFS_DBG is not set
1055 | # CONFIG_SPIFFS_API_DBG is not set
1056 | # CONFIG_SPIFFS_GC_DBG is not set
1057 | # CONFIG_SPIFFS_CACHE_DBG is not set
1058 | # CONFIG_SPIFFS_CHECK_DBG is not set
1059 | # CONFIG_SPIFFS_TEST_VISUALISATION is not set
1060 | # end of Debug Configuration
1061 | # end of SPIFFS Configuration
1062 |
1063 | #
1064 | # TCP Transport
1065 | #
1066 |
1067 | #
1068 | # Websocket
1069 | #
1070 | CONFIG_WS_TRANSPORT=y
1071 | CONFIG_WS_BUFFER_SIZE=1024
1072 | # end of Websocket
1073 | # end of TCP Transport
1074 |
1075 | #
1076 | # TinyUSB
1077 | #
1078 | # end of TinyUSB
1079 |
1080 | #
1081 | # Unity unit testing library
1082 | #
1083 | CONFIG_UNITY_ENABLE_FLOAT=y
1084 | CONFIG_UNITY_ENABLE_DOUBLE=y
1085 | # CONFIG_UNITY_ENABLE_COLOR is not set
1086 | CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
1087 | # CONFIG_UNITY_ENABLE_FIXTURE is not set
1088 | # CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set
1089 | # end of Unity unit testing library
1090 |
1091 | #
1092 | # Virtual file system
1093 | #
1094 | CONFIG_VFS_SUPPORT_IO=y
1095 | CONFIG_VFS_SUPPORT_DIR=y
1096 | CONFIG_VFS_SUPPORT_SELECT=y
1097 | CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y
1098 | CONFIG_VFS_SUPPORT_TERMIOS=y
1099 |
1100 | #
1101 | # Host File System I/O (Semihosting)
1102 | #
1103 | CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1
1104 | CONFIG_VFS_SEMIHOSTFS_HOST_PATH_MAX_LEN=128
1105 | # end of Host File System I/O (Semihosting)
1106 | # end of Virtual file system
1107 |
1108 | #
1109 | # Wear Levelling
1110 | #
1111 | # CONFIG_WL_SECTOR_SIZE_512 is not set
1112 | CONFIG_WL_SECTOR_SIZE_4096=y
1113 | CONFIG_WL_SECTOR_SIZE=4096
1114 | # end of Wear Levelling
1115 |
1116 | #
1117 | # Wi-Fi Provisioning Manager
1118 | #
1119 | CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16
1120 | CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30
1121 | # end of Wi-Fi Provisioning Manager
1122 |
1123 | #
1124 | # Supplicant
1125 | #
1126 | CONFIG_WPA_MBEDTLS_CRYPTO=y
1127 | # CONFIG_WPA_WAPI_PSK is not set
1128 | # CONFIG_WPA_DEBUG_PRINT is not set
1129 | # CONFIG_WPA_TESTING_OPTIONS is not set
1130 | # CONFIG_WPA_WPS_STRICT is not set
1131 | # CONFIG_WPA_11KV_SUPPORT is not set
1132 | # end of Supplicant
1133 | # end of Component config
1134 |
1135 | #
1136 | # Compatibility options
1137 | #
1138 | # CONFIG_LEGACY_INCLUDE_COMMON_HEADERS is not set
1139 | # end of Compatibility options
1140 |
1141 | # Deprecated options for backward compatibility
1142 | CONFIG_TOOLPREFIX="xtensa-esp32-elf-"
1143 | # CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set
1144 | # CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set
1145 | # CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set
1146 | CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y
1147 | # CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set
1148 | # CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set
1149 | CONFIG_LOG_BOOTLOADER_LEVEL=3
1150 | # CONFIG_APP_ROLLBACK_ENABLE is not set
1151 | # CONFIG_FLASH_ENCRYPTION_ENABLED is not set
1152 | # CONFIG_FLASHMODE_QIO is not set
1153 | # CONFIG_FLASHMODE_QOUT is not set
1154 | CONFIG_FLASHMODE_DIO=y
1155 | # CONFIG_FLASHMODE_DOUT is not set
1156 | # CONFIG_MONITOR_BAUD_9600B is not set
1157 | # CONFIG_MONITOR_BAUD_57600B is not set
1158 | CONFIG_MONITOR_BAUD_115200B=y
1159 | # CONFIG_MONITOR_BAUD_230400B is not set
1160 | # CONFIG_MONITOR_BAUD_921600B is not set
1161 | # CONFIG_MONITOR_BAUD_2MB is not set
1162 | # CONFIG_MONITOR_BAUD_OTHER is not set
1163 | CONFIG_MONITOR_BAUD_OTHER_VAL=115200
1164 | CONFIG_MONITOR_BAUD=115200
1165 | CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y
1166 | # CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set
1167 | CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
1168 | # CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set
1169 | # CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set
1170 | # CONFIG_CXX_EXCEPTIONS is not set
1171 | CONFIG_STACK_CHECK_NONE=y
1172 | # CONFIG_STACK_CHECK_NORM is not set
1173 | # CONFIG_STACK_CHECK_STRONG is not set
1174 | # CONFIG_STACK_CHECK_ALL is not set
1175 | # CONFIG_WARN_WRITE_STRINGS is not set
1176 | # CONFIG_DISABLE_GCC8_WARNINGS is not set
1177 | # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set
1178 | CONFIG_ESP32_APPTRACE_DEST_NONE=y
1179 | CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y
1180 | CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=0
1181 | CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0
1182 | CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0
1183 | CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0
1184 | CONFIG_ADC2_DISABLE_DAC=y
1185 | # CONFIG_SPIRAM_SUPPORT is not set
1186 | CONFIG_TRACEMEM_RESERVE_DRAM=0x0
1187 | # CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set
1188 | CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y
1189 | CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4
1190 | # CONFIG_ULP_COPROC_ENABLED is not set
1191 | CONFIG_ULP_COPROC_RESERVE_MEM=0
1192 | CONFIG_BROWNOUT_DET=y
1193 | CONFIG_BROWNOUT_DET_LVL_SEL_0=y
1194 | # CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set
1195 | # CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set
1196 | # CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set
1197 | # CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set
1198 | # CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set
1199 | # CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set
1200 | # CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set
1201 | CONFIG_BROWNOUT_DET_LVL=0
1202 | CONFIG_REDUCE_PHY_TX_POWER=y
1203 | CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y
1204 | # CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set
1205 | # CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set
1206 | # CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set
1207 | # CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set
1208 | # CONFIG_NO_BLOBS is not set
1209 | # CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set
1210 | CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
1211 | CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304
1212 | CONFIG_MAIN_TASK_STACK_SIZE=3584
1213 | CONFIG_IPC_TASK_STACK_SIZE=1024
1214 | CONFIG_CONSOLE_UART_DEFAULT=y
1215 | # CONFIG_CONSOLE_UART_CUSTOM is not set
1216 | # CONFIG_ESP_CONSOLE_UART_NONE is not set
1217 | CONFIG_CONSOLE_UART=y
1218 | CONFIG_CONSOLE_UART_NUM=0
1219 | CONFIG_CONSOLE_UART_BAUDRATE=115200
1220 | CONFIG_INT_WDT=y
1221 | CONFIG_INT_WDT_TIMEOUT_MS=300
1222 | CONFIG_INT_WDT_CHECK_CPU1=y
1223 | CONFIG_TASK_WDT=y
1224 | # CONFIG_TASK_WDT_PANIC is not set
1225 | CONFIG_TASK_WDT_TIMEOUT_S=5
1226 | CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y
1227 | CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y
1228 | # CONFIG_EVENT_LOOP_PROFILING is not set
1229 | CONFIG_POST_EVENTS_FROM_ISR=y
1230 | CONFIG_POST_EVENTS_FROM_IRAM_ISR=y
1231 | # CONFIG_ESP32S2_PANIC_PRINT_HALT is not set
1232 | CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y
1233 | # CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set
1234 | # CONFIG_ESP32S2_PANIC_GDBSTUB is not set
1235 | CONFIG_TIMER_TASK_STACK_SIZE=3584
1236 | # CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set
1237 | # CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set
1238 | CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y
1239 | CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150
1240 | CONFIG_MB_MASTER_DELAY_MS_CONVERT=200
1241 | CONFIG_MB_QUEUE_LENGTH=20
1242 | CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096
1243 | CONFIG_MB_SERIAL_BUF_SIZE=256
1244 | CONFIG_MB_SERIAL_TASK_PRIO=10
1245 | CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y
1246 | CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233
1247 | CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20
1248 | CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20
1249 | CONFIG_MB_CONTROLLER_STACK_SIZE=4096
1250 | CONFIG_MB_EVENT_QUEUE_TIMEOUT=20
1251 | # CONFIG_MB_TIMER_PORT_ENABLED is not set
1252 | CONFIG_MB_TIMER_GROUP=0
1253 | CONFIG_MB_TIMER_INDEX=0
1254 | # CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set
1255 | CONFIG_TIMER_TASK_PRIORITY=1
1256 | CONFIG_TIMER_TASK_STACK_DEPTH=2048
1257 | CONFIG_TIMER_QUEUE_LENGTH=10
1258 | # CONFIG_L2_TO_L3_COPY is not set
1259 | # CONFIG_USE_ONLY_LWIP_SELECT is not set
1260 | CONFIG_ESP_GRATUITOUS_ARP=y
1261 | CONFIG_GARP_TMR_INTERVAL=60
1262 | CONFIG_TCPIP_RECVMBOX_SIZE=32
1263 | CONFIG_TCP_MAXRTX=12
1264 | CONFIG_TCP_SYNMAXRTX=12
1265 | CONFIG_TCP_MSS=1440
1266 | CONFIG_TCP_MSL=60000
1267 | CONFIG_TCP_SND_BUF_DEFAULT=5744
1268 | CONFIG_TCP_WND_DEFAULT=5744
1269 | CONFIG_TCP_RECVMBOX_SIZE=6
1270 | CONFIG_TCP_QUEUE_OOSEQ=y
1271 | # CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set
1272 | CONFIG_TCP_OVERSIZE_MSS=y
1273 | # CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set
1274 | # CONFIG_TCP_OVERSIZE_DISABLE is not set
1275 | CONFIG_UDP_RECVMBOX_SIZE=6
1276 | CONFIG_TCPIP_TASK_STACK_SIZE=3072
1277 | CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y
1278 | # CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set
1279 | # CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set
1280 | CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF
1281 | # CONFIG_PPP_SUPPORT is not set
1282 | CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5
1283 | CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072
1284 | CONFIG_ESP32_PTHREAD_STACK_MIN=768
1285 | CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y
1286 | # CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set
1287 | # CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set
1288 | CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1
1289 | CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread"
1290 | CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y
1291 | # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set
1292 | # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set
1293 | CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y
1294 | CONFIG_SUPPORT_TERMIOS=y
1295 | CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1
1296 | CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN=128
1297 | # End of deprecated options
1298 |
--------------------------------------------------------------------------------
/src/.clang-format:
--------------------------------------------------------------------------------
1 | ---
2 | Language: Cpp
3 | BasedOnStyle: Google
4 | BreakBeforeBraces: Linux
5 | BreakConstructorInitializers: AfterColon
6 | ColumnLimit: 100
7 | ...
8 |
9 |
--------------------------------------------------------------------------------
/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # This file was automatically generated for projects
2 | # without default 'CMakeLists.txt' file.
3 |
4 | FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*)
5 |
6 | idf_component_register(SRCS ${app_sources})
7 |
--------------------------------------------------------------------------------
/src/bt.c:
--------------------------------------------------------------------------------
1 | /* Common Bluetooth Code
2 | *
3 | */
4 |
5 | #include "bt.h"
6 |
7 | #include
8 |
9 | #include "esp_bt.h"
10 | #include "esp_bt_main.h"
11 | #include "esp_err.h"
12 | #include "esp_log.h"
13 | #include "freertos/task.h"
14 |
15 |
16 | #define LOG_BT "BT"
17 | #define MAX_BTNAME_LEN 50
18 |
19 | esp_bd_addr_t localbtaddress;
20 | esp_bd_addr_t rmtbtaddress;
21 |
22 | char btname[MAX_BTNAME_LEN] = "Hello";
23 |
24 | void strtobtaddr(esp_bd_addr_t dest, char *src)
25 | {
26 | for (int i = 0; i < 6; i++) {
27 | char str[3] = " ";
28 | memcpy(str, src, 2);
29 | src += 2;
30 | dest[i] = strtoul(str, NULL, 16);
31 | }
32 | }
33 |
34 | char *btaddrtostr(char dest[13], esp_bd_addr_t src)
35 | {
36 | sprintf(dest, "%02X%02X%02X%02X%02X%02X", src[0], src[1], src[2], src[3], src[4], src[5]);
37 | dest[12] = '\0';
38 | return dest;
39 | }
40 |
41 | bool memreleased = false;
42 |
43 | void bt_init()
44 | {
45 | esp_err_t ret;
46 |
47 | if (!memreleased) {
48 | ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
49 | memreleased = true;
50 | }
51 |
52 | esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
53 | ret = esp_bt_controller_init(&bt_cfg);
54 | if (ret) {
55 | ESP_LOGE(LOG_BT, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret));
56 | return;
57 | }
58 |
59 | ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
60 | if (ret) {
61 | ESP_LOGE(LOG_BT, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret));
62 | return;
63 | }
64 |
65 | ret = esp_bluedroid_init();
66 | if (ret) {
67 | ESP_LOGE(LOG_BT, "%s init bluetooth failed: %s\n", __func__, esp_err_to_name(ret));
68 | return;
69 | }
70 |
71 | ret = esp_bluedroid_enable();
72 | if (ret) {
73 | ESP_LOGE(LOG_BT, "%s enable bluetooth failed: %s\n", __func__, esp_err_to_name(ret));
74 | return;
75 | }
76 |
77 | esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT, ESP_PWR_LVL_P9);
78 | }
79 |
80 | void bt_disable()
81 | {
82 | ESP_LOGI(LOG_BT, "Disabling Bluetooth");
83 | esp_bluedroid_disable();
84 | esp_bluedroid_deinit();
85 | esp_bt_controller_disable();
86 | esp_bt_controller_deinit();
87 |
88 | ESP_LOGI(LOG_BT, "Pausing to shutdown");
89 | vTaskDelay(pdMS_TO_TICKS(BT_PAUSE_BEFORE_RESTART));
90 | }
91 |
92 | void btSetName(const char *name)
93 | {
94 | strncpy(btname, name, sizeof(btname));
95 | btname[sizeof(btname) - 1] = '\0';
96 | ESP_LOGI(LOG_BT, "Setting BT Name %s", name);
97 | }
--------------------------------------------------------------------------------
/src/bt.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esp_bt_defs.h"
4 |
5 | #define BT_PAUSE_BEFORE_RESTART 250 // ms
6 |
7 | #define BT_CON_INT_MIN 10
8 | #define BT_CON_INT_MAX 10
9 | #define BT_CON_TIMEOUT 70
10 |
11 |
12 | extern esp_bd_addr_t rmtbtaddress;
13 | extern esp_bd_addr_t localbtaddress;
14 | extern char btname[];
15 |
16 | void strtobtaddr(esp_bd_addr_t dest, char *src);
17 | char *btaddrtostr(char dest[13], esp_bd_addr_t src);
18 | void bt_disable();
19 | void bt_init();
20 | void btSetName(const char *name);
21 |
--------------------------------------------------------------------------------
/src/bt_client.c:
--------------------------------------------------------------------------------
1 | /*
2 | This example code is in the Public Domain (or CC0 licensed, at your option.)
3 |
4 | Unless required by applicable law or agreed to in writing, this
5 | software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
6 | CONDITIONS OF ANY KIND, either express or implied.
7 | */
8 |
9 | /****************************************************************************
10 | *
11 | * Master Mode, Central, Client
12 | *
13 | ****************************************************************************/
14 |
15 | #include "bt_client.h"
16 |
17 | #include
18 | #include
19 | #include
20 | #include
21 |
22 | #include "bt.h"
23 | #include "defines.h"
24 | #include "esp_bt.h"
25 | #include "esp_bt_main.h"
26 | #include "esp_gap_ble_api.h"
27 | #include "esp_gatt_common_api.h"
28 | #include "esp_gatt_defs.h"
29 | #include "esp_gattc_api.h"
30 | #include "esp_log.h"
31 | #include "esp_timer.h"
32 | #include "freertos/FreeRTOS.h"
33 | #include "frskybt.h"
34 | #include "settings.h"
35 | #include "terminal.h"
36 |
37 | #if defined(BLUETOOTH5)
38 | #include "esp_gap_ble_api.h"
39 | #endif
40 |
41 | #define GATTC_TAG "BTCLIENT"
42 | #define REMOTE_SERVICE_UUID 0xFFF0
43 | #define REMOTE_FRSKY_CHAR_UUID 0xFFF6
44 | #define REMOTE_HTRESET_CHAR_UUID 0xAFF2
45 | #define PROFILE_NUM 1
46 | #define PROFILE_A_APP_ID 0
47 | #define INVALID_HANDLE 0
48 |
49 | char *str_ble_board_types[BLE_BOARD_COUNT] = {"Unknown", "CC2540", "PARA", "HeadTracker", "FlySky"};
50 |
51 | static bool get_server = false;
52 | static esp_gattc_char_elem_t *char_elem_result = NULL;
53 | static esp_gattc_descr_elem_t *descr_elem_result = NULL;
54 |
55 | static bool readytoscan = false;
56 | uint8_t bt_scanned_address_cnt = 0;
57 | volatile bool btc_validslavefound = false;
58 | volatile bool btc_connected = false;
59 | volatile bool btc_scan_complete = true;
60 | volatile ble_board_type btc_board_type = BLE_BOARD_UNKNOWN;
61 | volatile bool btc_ht_reset = false;
62 | uint16_t bt_datahandle;
63 | uint16_t bt_htresethandle;
64 |
65 | esp_bt_addr_t_rp btc_scanned_addresses[MAX_BLE_ADDRESSES];
66 |
67 | /* Declare static functions */
68 | static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);
69 | static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
70 | esp_ble_gattc_cb_param_t *param);
71 | static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
72 | esp_ble_gattc_cb_param_t *param);
73 |
74 | static esp_bt_uuid_t remote_filter_service_uuid = {
75 | .len = ESP_UUID_LEN_16,
76 | .uuid =
77 | {
78 | .uuid16 = REMOTE_SERVICE_UUID,
79 | },
80 | };
81 |
82 | static esp_bt_uuid_t notify_descr_uuid = {
83 | .len = ESP_UUID_LEN_16,
84 | .uuid =
85 | {
86 | .uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG,
87 | },
88 | };
89 |
90 | static esp_ble_scan_params_t ble_scan_params = {.scan_type = BLE_SCAN_TYPE_ACTIVE,
91 | .own_addr_type = BLE_ADDR_TYPE_PUBLIC,
92 | .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
93 | .scan_interval = 0x50,
94 | .scan_window = 0x30,
95 | .scan_duplicate = BLE_SCAN_DUPLICATE_ENABLE};
96 |
97 | struct gattc_profile_inst {
98 | esp_gattc_cb_t gattc_cb;
99 | uint16_t gattc_if;
100 | uint16_t app_id;
101 | uint16_t conn_id;
102 | uint16_t service_start_handle;
103 | uint16_t service_end_handle;
104 | uint16_t char_handle;
105 | esp_bd_addr_t remote_bda;
106 | };
107 |
108 | /* One gatt-based profile one app_id and one gattc_if, this array will store the
109 | * gattc_if returned by ESP_GATTS_REG_EVT */
110 | static struct gattc_profile_inst gl_profile_tab[PROFILE_NUM] = {
111 | [PROFILE_A_APP_ID] =
112 | {
113 | .gattc_cb = gattc_profile_event_handler,
114 | .gattc_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is
115 | ESP_GATT_IF_NONE */
116 | },
117 | };
118 |
119 | /* Common Bluetooth Code
120 | *
121 | */
122 |
123 | #include
124 |
125 | #include "bt.h"
126 | #include "esp_bt.h"
127 | #include "esp_bt_main.h"
128 | #include "esp_err.h"
129 | #include "esp_log.h"
130 |
131 | void gattc_update_connection_params(esp_bd_addr_t *remote_bda)
132 | {
133 | esp_ble_conn_update_params_t conn_params;
134 | memcpy(conn_params.bda, remote_bda, sizeof(esp_bd_addr_t));
135 | conn_params.min_int = BT_CON_INT_MIN; // x 1.25ms
136 | conn_params.max_int = BT_CON_INT_MAX; // x 1.25ms
137 | conn_params.latency = 0x00; // number of skippable connection events
138 | conn_params.timeout = BT_CON_TIMEOUT; // x 6.25ms, time before peripheral will assume
139 | // connection is dropped.
140 |
141 | esp_ble_gap_update_conn_params(&conn_params);
142 | }
143 |
144 | static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
145 | esp_ble_gattc_cb_param_t *param)
146 | {
147 | esp_ble_gattc_cb_param_t *p_data = (esp_ble_gattc_cb_param_t *)param;
148 |
149 | switch (event) {
150 | case ESP_GATTC_REG_EVT:
151 | ESP_LOGI(GATTC_TAG, "REG_EVT");
152 | esp_err_t scan_ret = esp_ble_gap_set_scan_params(&ble_scan_params);
153 | if (scan_ret) {
154 | ESP_LOGE(GATTC_TAG, "set scan params error, error code = %x", scan_ret);
155 | }
156 | break;
157 | case ESP_GATTC_CONNECT_EVT: {
158 | btc_connected = true;
159 | esp_ble_conn_update_params_t conn_params = {0};
160 | memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
161 | ESP_LOGI(GATTC_TAG, "ESP_GATTC_CONNECT_EVT conn_id %d, if %d", p_data->connect.conn_id,
162 | gattc_if);
163 | gl_profile_tab[PROFILE_A_APP_ID].conn_id = p_data->connect.conn_id;
164 | memcpy(gl_profile_tab[PROFILE_A_APP_ID].remote_bda, p_data->connect.remote_bda,
165 | sizeof(esp_bd_addr_t));
166 | ESP_LOGI(GATTC_TAG, "REMOTE BDA:");
167 | esp_log_buffer_hex(GATTC_TAG, gl_profile_tab[PROFILE_A_APP_ID].remote_bda,
168 | sizeof(esp_bd_addr_t));
169 | esp_err_t mtu_ret = esp_ble_gattc_send_mtu_req(gattc_if, p_data->connect.conn_id);
170 | if (mtu_ret) {
171 | ESP_LOGE(GATTC_TAG, "config MTU error, error code = %x", mtu_ret);
172 | }
173 | #if defined(BLUETOOTH5)
174 | esp_ble_gap_set_preferred_phy(param->connect.remote_bda,
175 | ESP_BLE_GAP_NO_PREFER_TRANSMIT_PHY|ESP_BLE_GAP_NO_PREFER_RECEIVE_PHY,
176 | ESP_BLE_GAP_PHY_CODED_PREF_MASK,
177 | ESP_BLE_GAP_PHY_CODED_PREF_MASK,
178 | ESP_BLE_GAP_PHY_OPTIONS_PREF_S8_CODING);
179 | #endif
180 | btc_scan_complete = false;
181 | ESP_LOGI(GATTC_TAG, "Starting Service Scan");
182 | esp_ble_gattc_search_service(gattc_if, param->cfg_mtu.conn_id, &remote_filter_service_uuid);
183 | gattc_update_connection_params(¶m->connect.remote_bda);
184 |
185 | break;
186 | }
187 | case ESP_GATTC_OPEN_EVT:
188 | if (param->open.status != ESP_GATT_OK) {
189 | ESP_LOGE(GATTC_TAG, "open failed, status %d", p_data->open.status);
190 | break;
191 | }
192 | ESP_LOGI(GATTC_TAG, "open success");
193 | break;
194 | case ESP_GATTC_DIS_SRVC_CMPL_EVT:
195 | if (param->dis_srvc_cmpl.status != ESP_GATT_OK) {
196 | ESP_LOGE(GATTC_TAG, "discover service failed, status %d", param->dis_srvc_cmpl.status);
197 | break;
198 | }
199 | ESP_LOGI(GATTC_TAG, "discover service complete conn_id %d", param->dis_srvc_cmpl.conn_id);
200 | esp_ble_gattc_search_service(gattc_if, param->cfg_mtu.conn_id, &remote_filter_service_uuid);
201 | break;
202 | case ESP_GATTC_CFG_MTU_EVT:
203 | if (param->cfg_mtu.status != ESP_GATT_OK) {
204 | ESP_LOGE(GATTC_TAG, "config mtu failed, error status = %x", param->cfg_mtu.status);
205 | }
206 | ESP_LOGI(GATTC_TAG, "ESP_GATTC_CFG_MTU_EVT, Status %d, MTU %d, conn_id %d",
207 | param->cfg_mtu.status, param->cfg_mtu.mtu, param->cfg_mtu.conn_id);
208 | break;
209 | case ESP_GATTC_SEARCH_RES_EVT: {
210 | ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x is primary service %d",
211 | p_data->search_res.conn_id, p_data->search_res.is_primary);
212 | ESP_LOGI(GATTC_TAG, "start handle %d end handle %d current handle value %d",
213 | p_data->search_res.start_handle, p_data->search_res.end_handle,
214 | p_data->search_res.srvc_id.inst_id);
215 | if (p_data->search_res.srvc_id.uuid.len == ESP_UUID_LEN_16 &&
216 | p_data->search_res.srvc_id.uuid.uuid.uuid16 == REMOTE_SERVICE_UUID) {
217 | ESP_LOGI(GATTC_TAG, "service found");
218 | get_server = true;
219 | gl_profile_tab[PROFILE_A_APP_ID].service_start_handle = p_data->search_res.start_handle;
220 | gl_profile_tab[PROFILE_A_APP_ID].service_end_handle = p_data->search_res.end_handle;
221 | ESP_LOGI(GATTC_TAG, "UUID16: %x", p_data->search_res.srvc_id.uuid.uuid.uuid16);
222 | }
223 | break;
224 | }
225 | case ESP_GATTC_SEARCH_CMPL_EVT:
226 | if (p_data->search_cmpl.status != ESP_GATT_OK) {
227 | ESP_LOGE(GATTC_TAG, "search service failed, error status = %x", p_data->search_cmpl.status);
228 | break;
229 | }
230 | if (p_data->search_cmpl.searched_service_source == ESP_GATT_SERVICE_FROM_REMOTE_DEVICE) {
231 | ESP_LOGI(GATTC_TAG, "Get service information from remote device");
232 | } else if (p_data->search_cmpl.searched_service_source == ESP_GATT_SERVICE_FROM_NVS_FLASH) {
233 | ESP_LOGI(GATTC_TAG, "Get service information from flash");
234 | } else {
235 | ESP_LOGI(GATTC_TAG, "unknown service source");
236 | }
237 | ESP_LOGI(GATTC_TAG, "ESP_GATTC_SEARCH_CMPL_EVT");
238 | if (get_server) {
239 | uint16_t count = 0;
240 | esp_gatt_status_t status = esp_ble_gattc_get_attr_count(
241 | gattc_if, p_data->search_cmpl.conn_id, ESP_GATT_DB_CHARACTERISTIC,
242 | gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
243 | gl_profile_tab[PROFILE_A_APP_ID].service_end_handle, INVALID_HANDLE, &count);
244 | if (status != ESP_GATT_OK) {
245 | ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error");
246 | }
247 |
248 | ESP_LOGI(GATTC_TAG, "Attr Count %d", count);
249 |
250 | if (count > 0) {
251 | char_elem_result =
252 | (esp_gattc_char_elem_t *)malloc(sizeof(esp_gattc_char_elem_t) * MAX_CHAR_TO_SCAN);
253 | if (!char_elem_result) {
254 | ESP_LOGE(GATTC_TAG, "gattc no mem");
255 | } else {
256 | count = MAX_CHAR_TO_SCAN;
257 | status = esp_ble_gattc_get_all_char(
258 | gattc_if, p_data->search_cmpl.conn_id,
259 | gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
260 | gl_profile_tab[PROFILE_A_APP_ID].service_end_handle, char_elem_result, &count, 0);
261 | if (status != ESP_GATT_OK) {
262 | ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_all_char error");
263 | }
264 |
265 | btc_validslavefound = false;
266 | btc_board_type = BLE_BOARD_UNKNOWN;
267 | for (int i = 0; i < count; i++) {
268 | if (char_elem_result[i].uuid.uuid.uuid16 == 0xFFF6) {
269 | btc_validslavefound = true;
270 | bt_datahandle = char_elem_result[i].char_handle;
271 | ESP_LOGI(GATTC_TAG, "Found the Trainer Characteristic");
272 | if (char_elem_result[i].properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY) {
273 | // Subscribing to the Notify
274 | ESP_LOGI(GATTC_TAG, "Subscribing for Notifications");
275 | gl_profile_tab[PROFILE_A_APP_ID].char_handle = char_elem_result[i].char_handle;
276 | esp_ble_gattc_register_for_notify(gattc_if,
277 | gl_profile_tab[PROFILE_A_APP_ID].remote_bda,
278 | char_elem_result[i].char_handle);
279 | }
280 |
281 | // Update Flash to Save Last Connected BT Address
282 | btaddrtostr(settings.rmtbtaddr, gl_profile_tab[PROFILE_A_APP_ID].remote_bda);
283 | saveSettings();
284 |
285 | } else if (char_elem_result[i].uuid.uuid.uuid16 == 0xAFF2) {
286 | ESP_LOGI(GATTC_TAG,
287 | "Found the reset characteristic. This is a "
288 | "headtracker board");
289 | btc_board_type = BLE_BOARD_HEADTRACKER;
290 | bt_htresethandle = char_elem_result[i].char_handle;
291 |
292 | } else if (char_elem_result[i].uuid.uuid.uuid16 == 0xAFF1) {
293 | ESP_LOGI(GATTC_TAG, "Found the valid channels. This is a headtracker board");
294 | btc_board_type = BLE_BOARD_HEADTRACKER;
295 | }
296 | }
297 | btc_scan_complete = true;
298 | }
299 | /* free char_elem_result */
300 | free(char_elem_result);
301 | } else {
302 | ESP_LOGE(GATTC_TAG, "no char found");
303 | }
304 | }
305 | break;
306 | case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
307 | ESP_LOGI(GATTC_TAG, "ESP_GATTC_REG_FOR_NOTIFY_EVT");
308 | if (p_data->reg_for_notify.status != ESP_GATT_OK) {
309 | ESP_LOGE(GATTC_TAG, "REG FOR NOTIFY failed: error status = %d",
310 | p_data->reg_for_notify.status);
311 | } else {
312 | uint16_t count = 0;
313 | uint16_t notify_en = 1;
314 | esp_gatt_status_t ret_status = esp_ble_gattc_get_attr_count(
315 | gattc_if, gl_profile_tab[PROFILE_A_APP_ID].conn_id, ESP_GATT_DB_DESCRIPTOR,
316 | gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
317 | gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,
318 | gl_profile_tab[PROFILE_A_APP_ID].char_handle, &count);
319 | if (ret_status != ESP_GATT_OK) {
320 | ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error");
321 | }
322 | if (count > 0) {
323 | descr_elem_result = malloc(sizeof(esp_gattc_descr_elem_t) * count);
324 | if (!descr_elem_result) {
325 | ESP_LOGE(GATTC_TAG, "malloc error, gattc no mem");
326 | } else {
327 | ret_status = esp_ble_gattc_get_descr_by_char_handle(
328 | gattc_if, gl_profile_tab[PROFILE_A_APP_ID].conn_id, p_data->reg_for_notify.handle,
329 | notify_descr_uuid, descr_elem_result, &count);
330 | if (ret_status != ESP_GATT_OK) {
331 | ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_descr_by_char_handle error");
332 | }
333 | /* Every char has only one descriptor in our 'ESP_GATTS_DEMO' demo, so
334 | * we used first 'descr_elem_result' */
335 | if (count > 0 && descr_elem_result[0].uuid.len == ESP_UUID_LEN_16 &&
336 | descr_elem_result[0].uuid.uuid.uuid16 == ESP_GATT_UUID_CHAR_CLIENT_CONFIG) {
337 | ret_status = esp_ble_gattc_write_char_descr(
338 | gattc_if, gl_profile_tab[PROFILE_A_APP_ID].conn_id, descr_elem_result[0].handle,
339 | sizeof(notify_en), (uint8_t *)¬ify_en, ESP_GATT_WRITE_TYPE_RSP,
340 | ESP_GATT_AUTH_REQ_NONE);
341 | }
342 |
343 | if (ret_status != ESP_GATT_OK) {
344 | ESP_LOGE(GATTC_TAG, "esp_ble_gattc_write_char_descr error");
345 | }
346 |
347 | /* free descr_elem_result */
348 | free(descr_elem_result);
349 | }
350 | } else {
351 | ESP_LOGE(GATTC_TAG, "decsr not found");
352 | }
353 | }
354 | break;
355 | }
356 | case ESP_GATTC_NOTIFY_EVT:
357 | if (p_data->notify.is_notify) {
358 | // TODO, verify what characteristic is being notified
359 | #ifdef DEBUG_TIMERS
360 | //processFrame(p_data->notify.value,
361 | // p_data->notify.value_len); // Used to decode the channel data for debugging
362 | #endif
363 | /*printf("ToUART");
364 | for(int i=0; i < p_data->notify.value_len; i++) {
365 | printf("%.2x ", p_data->notify.value[i]);
366 | }
367 | printf("\n");*/
368 | uart_write_bytes(uart_num, (void *)p_data->notify.value,
369 | p_data->notify.value_len); // Write the received data to the UART port
370 |
371 | // if(p_data->notify.handle == bt_datahandle) // If notify coming from the
372 | // data handle, send it to the UART port
373 | // else
374 | // ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, receive unknown notify
375 | // value:");
376 | } else {
377 | ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, receive indicate value:");
378 | }
379 |
380 | break;
381 | case ESP_GATTC_WRITE_DESCR_EVT:
382 | if (p_data->write.status != ESP_GATT_OK) {
383 | ESP_LOGE(GATTC_TAG, "write descr failed, error status = %x", p_data->write.status);
384 | break;
385 | }
386 | ESP_LOGI(GATTC_TAG, "write descr success ");
387 | uint8_t write_char_data[35];
388 | for (int i = 0; i < sizeof(write_char_data); ++i) {
389 | write_char_data[i] = i % 256;
390 | }
391 | esp_ble_gattc_write_char(gattc_if, gl_profile_tab[PROFILE_A_APP_ID].conn_id,
392 | gl_profile_tab[PROFILE_A_APP_ID].char_handle,
393 | sizeof(write_char_data), write_char_data, ESP_GATT_WRITE_TYPE_RSP,
394 | ESP_GATT_AUTH_REQ_NONE);
395 | break;
396 | case ESP_GATTC_SRVC_CHG_EVT: {
397 | esp_bd_addr_t bda;
398 | memcpy(bda, p_data->srvc_chg.remote_bda, sizeof(esp_bd_addr_t));
399 | ESP_LOGI(GATTC_TAG, "ESP_GATTC_SRVC_CHG_EVT, bd_addr:");
400 | esp_log_buffer_hex(GATTC_TAG, bda, sizeof(esp_bd_addr_t));
401 | break;
402 | }
403 | case ESP_GATTC_WRITE_CHAR_EVT:
404 | if (p_data->write.status != ESP_GATT_OK) {
405 | ESP_LOGE(GATTC_TAG, "write char failed, error status = %x", p_data->write.status);
406 | break;
407 | }
408 | ESP_LOGI(GATTC_TAG, "write char success ");
409 | break;
410 | case ESP_GATTC_DISCONNECT_EVT:
411 | btc_connected = false;
412 | get_server = false;
413 | ESP_LOGI(GATTC_TAG, "ESP_GATTC_DISCONNECT_EVT, reason = %d", p_data->disconnect.reason);
414 | break;
415 | default:
416 | break;
417 | }
418 | }
419 |
420 | static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
421 | {
422 | switch (event) {
423 | case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: {
424 | readytoscan = true;
425 | break;
426 | }
427 | case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT: {
428 | // scan start complete event to indicate scan start successfully or failed
429 | if (param->scan_start_cmpl.status != ESP_BT_STATUS_SUCCESS) {
430 | ESP_LOGE(GATTC_TAG, "scan start failed, error status = %x", param->scan_start_cmpl.status);
431 | break;
432 | }
433 | ESP_LOGI(GATTC_TAG, "scan start success");
434 |
435 | break;
436 | }
437 | case ESP_GAP_BLE_SCAN_RESULT_EVT: {
438 | esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param;
439 | switch (scan_result->scan_rst.search_evt) {
440 | case ESP_GAP_SEARCH_INQ_RES_EVT: {
441 | // Add address to the list if it doesn't already exist
442 | if (bt_scanned_address_cnt < MAX_BLE_ADDRESSES &&
443 | scan_result->scan_rst.rssi > MIN_BLE_RSSI) {
444 | bool found = false;
445 | for (int i = 0; i < bt_scanned_address_cnt; i++) {
446 | if (memcmp(btc_scanned_addresses[i].addr, scan_result->scan_rst.bda,
447 | sizeof(esp_bd_addr_t)) == 0) {
448 | found = true;
449 | break;
450 | }
451 | }
452 | if (!found) {
453 | btc_scanned_addresses[bt_scanned_address_cnt].type = scan_result->scan_rst.ble_addr_type;
454 | memcpy(btc_scanned_addresses[bt_scanned_address_cnt++].addr, scan_result->scan_rst.bda,
455 |
456 | sizeof(esp_bd_addr_t));
457 | }
458 | }
459 | char addr[13];
460 | btaddrtostr(addr, scan_result->scan_rst.bda);
461 | printf("Disc BT Address %s, RSSI=%d, Addr Type=%d\n", addr, scan_result->scan_rst.rssi,
462 | scan_result->scan_rst.ble_addr_type);
463 | break;
464 | }
465 | case ESP_GAP_SEARCH_INQ_CMPL_EVT: {
466 | btc_scan_complete = true;
467 | break;
468 | }
469 | default: {
470 | break;
471 | }
472 | }
473 | break;
474 | }
475 |
476 | case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT: {
477 | if (param->scan_stop_cmpl.status != ESP_BT_STATUS_SUCCESS) {
478 | ESP_LOGE(GATTC_TAG, "scan stop failed, error status = %x", param->scan_stop_cmpl.status);
479 | break;
480 | }
481 | ESP_LOGI(GATTC_TAG, "stop scan successfully");
482 | break;
483 | }
484 |
485 | case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: {
486 | if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS) {
487 | ESP_LOGE(GATTC_TAG, "adv stop failed, error status = %x", param->adv_stop_cmpl.status);
488 | break;
489 | }
490 | ESP_LOGI(GATTC_TAG, "stop adv successfully");
491 | break;
492 | }
493 | case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: {
494 | ESP_LOGI(GATTC_TAG,
495 | "update connection params status = %d, min_int = %d, max_int = "
496 | "%d,conn_int = %d,latency = %d, timeout = %d",
497 | param->update_conn_params.status, param->update_conn_params.min_int,
498 | param->update_conn_params.max_int, param->update_conn_params.conn_int,
499 | param->update_conn_params.latency, param->update_conn_params.timeout);
500 | break;
501 | }
502 | default: {
503 | break;
504 | }
505 | }
506 | }
507 |
508 | static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
509 | esp_ble_gattc_cb_param_t *param)
510 | {
511 | /* If event is register event, store the gattc_if for each profile */
512 | if (event == ESP_GATTC_REG_EVT) {
513 | if (param->reg.status == ESP_GATT_OK) {
514 | gl_profile_tab[param->reg.app_id].gattc_if = gattc_if;
515 | } else {
516 | ESP_LOGI(GATTC_TAG, "reg app failed, app_id %04x, status %d", param->reg.app_id,
517 | param->reg.status);
518 | return;
519 | }
520 | }
521 |
522 | /* If the gattc_if equal to profile A, call profile A cb handler,
523 | * so here call each profile's callback */
524 | do {
525 | int idx;
526 | for (idx = 0; idx < PROFILE_NUM; idx++) {
527 | if (gattc_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a
528 | certain gatt_if, need to call every
529 | profile cb function */
530 | gattc_if == gl_profile_tab[idx].gattc_if) {
531 | if (gl_profile_tab[idx].gattc_cb) {
532 | gl_profile_tab[idx].gattc_cb(event, gattc_if, param);
533 | }
534 | }
535 | }
536 | } while (0);
537 | }
538 |
539 | void btc_dohtreset()
540 | {
541 | if (btc_connected && btc_scan_complete && btc_board_type == BLE_BOARD_HEADTRACKER) {
542 | esp_err_t status;
543 | status = esp_ble_gattc_write_char(
544 | gl_profile_tab[PROFILE_A_APP_ID].gattc_if, gl_profile_tab[PROFILE_A_APP_ID].conn_id,
545 | bt_htresethandle, 1, (uint8_t *)"R", ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
546 | if (status != ESP_OK) {
547 | ESP_LOGE(GATTC_TAG, "Error Writing to Characteristic");
548 | }
549 | }
550 | }
551 |
552 | void btc_start_scan()
553 | {
554 | if (!readytoscan) {
555 | return;
556 | }
557 |
558 | btc_scan_complete = false;
559 | bt_scanned_address_cnt = 0;
560 | printf("Clearing Addresses\r\n");
561 | uint32_t duration = 1;
562 | esp_ble_gap_start_scanning(duration);
563 | }
564 |
565 | void btc_scan_stop()
566 | {
567 | esp_ble_gap_stop_scanning();
568 | }
569 |
570 | void btc_connect(esp_bd_addr_t addr)
571 | {
572 | if (btc_connected) return;
573 | btc_scan_complete = false;
574 | btc_validslavefound = false;
575 | char saddr[13];
576 | memcpy(rmtbtaddress, addr, sizeof(esp_bd_addr_t));
577 |
578 | bool connstarted=false;
579 | for(int i=0; i < bt_scanned_address_cnt; i++) {
580 | if(memcmp(btc_scanned_addresses[i].addr, rmtbtaddress, sizeof(esp_bd_addr_t)) == 0) {
581 | printf("Connecting to %s\r\n", btaddrtostr(saddr, addr));
582 | if (btc_scanned_addresses[i].type == BLE_ADDR_TYPE_PUBLIC)
583 | esp_ble_gattc_open(gl_profile_tab[PROFILE_A_APP_ID].gattc_if, addr, BLE_ADDR_TYPE_PUBLIC, true);
584 | else if (btc_scanned_addresses[i].type == BLE_ADDR_TYPE_RANDOM)
585 | esp_ble_gattc_open(gl_profile_tab[PROFILE_A_APP_ID].gattc_if, addr, BLE_ADDR_TYPE_RANDOM, true);
586 | break;
587 | }
588 | }
589 | if(!connstarted) {
590 | printf("Unable to connect to %s, address not found in storage\r\n", btaddrtostr(saddr, addr));
591 | }
592 |
593 | }
594 |
595 | void btc_disconnect()
596 | {
597 | if (btc_connected)
598 | esp_ble_gattc_close(gl_profile_tab[PROFILE_A_APP_ID].gattc_if,
599 | gl_profile_tab[PROFILE_A_APP_ID].conn_id);
600 | btc_connected = false;
601 | btc_scan_complete = false;
602 | btc_validslavefound = false;
603 | }
604 |
605 | void btcInit()
606 | {
607 | ESP_LOGI(GATTC_TAG, "Starting Central");
608 |
609 | // register the callback function to the gap module
610 | esp_err_t ret = esp_ble_gap_register_callback(esp_gap_cb);
611 | if (ret) {
612 | ESP_LOGE(GATTC_TAG, "%s gap register failed, error code = %x\n", __func__, ret);
613 | return;
614 | }
615 |
616 | // register the callback function to the gattc module
617 | ret = esp_ble_gattc_register_callback(esp_gattc_cb);
618 | if (ret) {
619 | ESP_LOGE(GATTC_TAG, "%s gattc register failed, error code = %x\n", __func__, ret);
620 | return;
621 | }
622 |
623 | ret = esp_ble_gattc_app_register(PROFILE_A_APP_ID);
624 | if (ret) {
625 | ESP_LOGE(GATTC_TAG, "%s gattc app register failed, error code = %x\n", __func__, ret);
626 | }
627 | esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(85);
628 | if (local_mtu_ret) {
629 | ESP_LOGE(GATTC_TAG, "set local MTU failed, error code = %x", local_mtu_ret);
630 | }
631 |
632 | // Update Local Address
633 | uint8_t adrtype;
634 | esp_ble_gap_get_local_used_addr(localbtaddress, &adrtype);
635 |
636 | vTaskDelay(pdMS_TO_TICKS(500));
637 | // Try to connect to saved address on startup
638 | esp_bd_addr_t addr;
639 | strtobtaddr(addr, settings.rmtbtaddr);
640 | // btc_connect(addr);
641 | }
--------------------------------------------------------------------------------
/src/bt_client.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /*
4 | This example code is in the Public Domain (or CC0 licensed, at your option.)
5 |
6 | Unless required by applicable law or agreed to in writing, this
7 | software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
8 | CONDITIONS OF ANY KIND, either express or implied.
9 | */
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | #include "esp_bt_defs.h"
17 |
18 |
19 | #define MAX_BLE_ADDRESSES 20
20 | #define MIN_BLE_RSSI -85
21 | #define MAX_CHAR_TO_SCAN 15
22 |
23 | typedef enum {
24 | BLE_BOARD_UNKNOWN,
25 | BLE_BOARD_FRSKY_CC2540,
26 | BLE_BOARD_FRSKY_PARA,
27 | BLE_BOARD_HEADTRACKER,
28 | BLE_BOARD_FLYSKY,
29 | BLE_BOARD_HM10,
30 | BLE_BOARD_COUNT
31 | } ble_board_type;
32 |
33 | typedef struct {
34 | esp_bd_addr_t addr;
35 | esp_ble_addr_type_t type;
36 | } esp_bt_addr_t_rp;
37 |
38 | extern char *str_ble_board_types[BLE_BOARD_COUNT];
39 | extern uint8_t bt_scanned_address_cnt;
40 |
41 | extern esp_bt_addr_t_rp btc_scanned_addresses[MAX_BLE_ADDRESSES];
42 | void btc_connect(esp_bd_addr_t addr);
43 | extern volatile bool btc_connected;
44 | extern volatile bool btc_scan_complete;
45 | extern volatile bool btc_validslavefound;
46 | extern volatile bool btc_ht_reset;
47 | extern volatile ble_board_type btc_board_type;
48 | void btcInit();
49 | void btc_disconnect();
50 | void btc_start_scan();
51 | void btc_dohtreset();
52 |
--------------------------------------------------------------------------------
/src/bt_server.c:
--------------------------------------------------------------------------------
1 | /*
2 | This example code is in the Public Domain (or CC0 licensed, at your option.)
3 |
4 | Unless required by applicable law or agreed to in writing, this
5 | software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
6 | CONDITIONS OF ANY KIND, either express or implied.
7 | */
8 |
9 | /****************************************************************************
10 | *
11 | * Slave Mode, Peripheral, Server
12 | *
13 | ****************************************************************************/
14 |
15 | #include "bt_server.h"
16 |
17 | #include
18 | #include
19 | #include
20 |
21 | #include "bt.h"
22 | #include "esp_bt.h"
23 | #include "esp_bt_defs.h"
24 | #include "esp_bt_main.h"
25 | #include "esp_gap_ble_api.h"
26 | #include "esp_gatt_common_api.h"
27 | #include "esp_gatts_api.h"
28 | #include "esp_log.h"
29 | #include "esp_system.h"
30 | #include "freertos/FreeRTOS.h"
31 | #include "freertos/event_groups.h"
32 | #include "freertos/task.h"
33 | #include "nvs_flash.h"
34 | #include "sdkconfig.h"
35 |
36 | #define GATTS_TAG "BTSERVER"
37 |
38 | /// Declare the static function
39 | static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
40 | esp_ble_gatts_cb_param_t *param);
41 |
42 | #define GATTS_SERVICE_FRSKY_UUID 0xFFF0
43 | #define GATTS_CHAR_FRSKY_UUID 0xFFF6
44 | #define GATTS_DESCR_UUID_TEST_A 0x3333
45 | #define GATTS_NUM_HANDLE_TEST_A 8
46 |
47 | #define GATTS_DEMO_CHAR_VAL_LEN_MAX 0x40
48 |
49 | #define PREPARE_BUF_MAX_SIZE 1024
50 |
51 | volatile bool btp_connected = false;
52 |
53 | static uint8_t char1_str[] = {0x11, 0x22, 0x33};
54 | static esp_gatt_char_prop_t a_property = 0;
55 |
56 | static esp_attr_value_t gatts_demo_char1_val = {
57 | .attr_max_len = GATTS_DEMO_CHAR_VAL_LEN_MAX,
58 | .attr_len = sizeof(char1_str),
59 | .attr_value = char1_str,
60 | };
61 |
62 | static uint8_t adv_config_done = 0;
63 | #define adv_config_flag (1 << 0)
64 | #define scan_rsp_config_flag (1 << 1)
65 |
66 | // FORMAT
67 | static uint8_t raw_adv_data[] = {
68 | 0x02, 0x01, 0x06, // General | NoBREDR
69 | 0x03, 0x02, 0xF0, 0xFF, // Available Service
70 | 0x06, 0x09, 'H', 'e', 'l', 'l', 'o', // Name
71 | 0x02, 0x0A, 0x00 // TX Power
72 | };
73 |
74 | // No Scan Response
75 | /*
76 | static uint8_t raw_scan_rsp_data[] = {
77 | 0x0f, 0x09, 0x45, 0x53, 0x50, 0x5f, 0x47, 0x41, 0x54, 0x54, 0x53, 0x5f, 0x44,
78 | 0x45, 0x4d, 0x4f
79 | };*/
80 |
81 | static esp_ble_adv_params_t adv_params = {
82 | .adv_int_min = 0x20,
83 | .adv_int_max = 0x40,
84 | .adv_type = ADV_TYPE_IND,
85 | .own_addr_type = BLE_ADDR_TYPE_PUBLIC,
86 | .channel_map = ADV_CHNL_ALL,
87 | .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
88 | };
89 |
90 | #define PROFILE_NUM 1
91 | #define PROFILE_TRAINER_SL_ID 0
92 |
93 | struct gatts_profile_inst {
94 | esp_gatts_cb_t gatts_cb;
95 | uint16_t gatts_if;
96 | uint16_t app_id;
97 | uint16_t conn_id;
98 | uint16_t service_handle;
99 | esp_gatt_srvc_id_t service_id;
100 | uint16_t char_handle;
101 | esp_bt_uuid_t char_uuid;
102 | esp_gatt_perm_t perm;
103 | esp_gatt_char_prop_t property;
104 | uint16_t descr_handle;
105 | esp_bt_uuid_t descr_uuid;
106 | };
107 |
108 | /* One gatt-based profile one app_id and one gatts_if, this array will store the gatts_if returned
109 | * by ESP_GATTS_REG_EVT */
110 | static struct gatts_profile_inst gl_profile_tab[PROFILE_NUM] = {
111 | [PROFILE_TRAINER_SL_ID] = {
112 | .gatts_cb = gatts_profile_a_event_handler,
113 | .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
114 | }};
115 |
116 | typedef struct {
117 | uint8_t *prepare_buf;
118 | int prepare_len;
119 | } prepare_type_env_t;
120 |
121 | static prepare_type_env_t a_prepare_write_env;
122 |
123 | void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env,
124 | esp_ble_gatts_cb_param_t *param);
125 | void example_exec_write_event_env(prepare_type_env_t *prepare_write_env,
126 | esp_ble_gatts_cb_param_t *param);
127 |
128 | static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
129 | {
130 | switch (event) {
131 | case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
132 | adv_config_done &= (~adv_config_flag);
133 | if (adv_config_done == 0) {
134 | esp_ble_gap_start_advertising(&adv_params);
135 | }
136 | break;
137 | case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT:
138 | adv_config_done &= (~scan_rsp_config_flag);
139 | if (adv_config_done == 0) {
140 | esp_ble_gap_start_advertising(&adv_params);
141 | }
142 | break;
143 | case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
144 | // advertising start complete event to indicate advertising start successfully or failed
145 | if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) {
146 | ESP_LOGE(GATTS_TAG, "Advertising start failed\n");
147 | }
148 | break;
149 | case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
150 | if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS) {
151 | ESP_LOGE(GATTS_TAG, "Advertising stop failed\n");
152 | } else {
153 | ESP_LOGI(GATTS_TAG, "Stop adv successfully\n");
154 | }
155 | break;
156 | case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
157 | ESP_LOGI(GATTS_TAG,
158 | "update connection params status = %d, min_int = %d, max_int = %d,conn_int = "
159 | "%d,latency = %d, timeout = %d",
160 | param->update_conn_params.status, param->update_conn_params.min_int,
161 | param->update_conn_params.max_int, param->update_conn_params.conn_int,
162 | param->update_conn_params.latency, param->update_conn_params.timeout);
163 | break;
164 | default:
165 | break;
166 | }
167 | }
168 |
169 | void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env,
170 | esp_ble_gatts_cb_param_t *param)
171 | {
172 | esp_gatt_status_t status = ESP_GATT_OK;
173 | if (param->write.need_rsp) {
174 | if (param->write.is_prep) {
175 | if (prepare_write_env->prepare_buf == NULL) {
176 | prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE * sizeof(uint8_t));
177 | prepare_write_env->prepare_len = 0;
178 | if (prepare_write_env->prepare_buf == NULL) {
179 | ESP_LOGE(GATTS_TAG, "Gatt_server prep no mem\n");
180 | status = ESP_GATT_NO_RESOURCES;
181 | }
182 | } else {
183 | if (param->write.offset > PREPARE_BUF_MAX_SIZE) {
184 | status = ESP_GATT_INVALID_OFFSET;
185 | } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) {
186 | status = ESP_GATT_INVALID_ATTR_LEN;
187 | }
188 | }
189 |
190 | esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)malloc(sizeof(esp_gatt_rsp_t));
191 | gatt_rsp->attr_value.len = param->write.len;
192 | gatt_rsp->attr_value.handle = param->write.handle;
193 | gatt_rsp->attr_value.offset = param->write.offset;
194 | gatt_rsp->attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE;
195 | memcpy(gatt_rsp->attr_value.value, param->write.value, param->write.len);
196 | esp_err_t response_err = esp_ble_gatts_send_response(gatts_if, param->write.conn_id,
197 | param->write.trans_id, status, gatt_rsp);
198 | if (response_err != ESP_OK) {
199 | ESP_LOGE(GATTS_TAG, "Send response error\n");
200 | }
201 | free(gatt_rsp);
202 | if (status != ESP_GATT_OK) {
203 | return;
204 | }
205 | memcpy(prepare_write_env->prepare_buf + param->write.offset, param->write.value,
206 | param->write.len);
207 | prepare_write_env->prepare_len += param->write.len;
208 |
209 | } else {
210 | esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status,
211 | NULL);
212 | }
213 | }
214 | }
215 |
216 | void example_exec_write_event_env(prepare_type_env_t *prepare_write_env,
217 | esp_ble_gatts_cb_param_t *param)
218 | {
219 | if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC) {
220 | esp_log_buffer_hex(GATTS_TAG, prepare_write_env->prepare_buf, prepare_write_env->prepare_len);
221 | } else {
222 | ESP_LOGI(GATTS_TAG, "ESP_GATT_PREP_WRITE_CANCEL");
223 | }
224 | if (prepare_write_env->prepare_buf) {
225 | free(prepare_write_env->prepare_buf);
226 | prepare_write_env->prepare_buf = NULL;
227 | }
228 | prepare_write_env->prepare_len = 0;
229 | }
230 |
231 | static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
232 | esp_ble_gatts_cb_param_t *param)
233 | {
234 | switch (event) {
235 | case ESP_GATTS_REG_EVT:
236 | ESP_LOGI(GATTS_TAG, "REGISTER_APP_EVT, status %d, app_id %d\n", param->reg.status,
237 | param->reg.app_id);
238 | gl_profile_tab[PROFILE_TRAINER_SL_ID].service_id.is_primary = true;
239 | gl_profile_tab[PROFILE_TRAINER_SL_ID].service_id.id.inst_id = 0x00;
240 | gl_profile_tab[PROFILE_TRAINER_SL_ID].service_id.id.uuid.len = ESP_UUID_LEN_16;
241 | gl_profile_tab[PROFILE_TRAINER_SL_ID].service_id.id.uuid.uuid.uuid16 =
242 | GATTS_SERVICE_FRSKY_UUID;
243 |
244 | /*esp_err_t set_dev_name_ret = esp_ble_gap_set_device_name(devicename);
245 | if (set_dev_name_ret){
246 | ESP_LOGE(GATTS_TAG, "set device name failed, error code = %x", set_dev_name_ret);
247 | }*/
248 | esp_err_t raw_adv_ret = esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data));
249 | if (raw_adv_ret) {
250 | ESP_LOGE(GATTS_TAG, "config raw adv data failed, error code = %x ", raw_adv_ret);
251 | }
252 | adv_config_done |= adv_config_flag;
253 | /*esp_err_t raw_scan_ret = esp_ble_gap_config_scan_rsp_data_raw(raw_scan_rsp_data,
254 | sizeof(raw_scan_rsp_data)); if (raw_scan_ret){ ESP_LOGE(GATTS_TAG, "config raw scan rsp data
255 | failed, error code = %x", raw_scan_ret);
256 | }
257 | adv_config_done |= scan_rsp_config_flag;*/
258 |
259 | esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_TRAINER_SL_ID].service_id,
260 | GATTS_NUM_HANDLE_TEST_A);
261 | break;
262 | case ESP_GATTS_READ_EVT: {
263 | ESP_LOGI(GATTS_TAG, "GATT_READ_EVT, conn_id %d, trans_id %ld, handle %d\n",
264 | param->read.conn_id, param->read.trans_id, param->read.handle);
265 | esp_gatt_rsp_t rsp;
266 | memset(&rsp, 0, sizeof(esp_gatt_rsp_t));
267 | rsp.attr_value.handle = param->read.handle;
268 | rsp.attr_value.len = 4;
269 | rsp.attr_value.value[0] = 0xde;
270 | rsp.attr_value.value[1] = 0xed;
271 | rsp.attr_value.value[2] = 0xbe;
272 | rsp.attr_value.value[3] = 0xef;
273 | esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id, ESP_GATT_OK,
274 | &rsp);
275 | break;
276 | }
277 | case ESP_GATTS_WRITE_EVT: {
278 | ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %ld, handle %d",
279 | param->write.conn_id, param->write.trans_id, param->write.handle);
280 | if (!param->write.is_prep) {
281 | ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len);
282 | esp_log_buffer_hex(GATTS_TAG, param->write.value, param->write.len);
283 | if (gl_profile_tab[PROFILE_TRAINER_SL_ID].descr_handle == param->write.handle &&
284 | param->write.len == 2) {
285 | uint16_t descr_value = param->write.value[1] << 8 | param->write.value[0];
286 | if (descr_value == 0x0001) {
287 | if (a_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY) {
288 | ESP_LOGI(GATTS_TAG, "notify enable");
289 | uint8_t notify_data[15];
290 | for (int i = 0; i < sizeof(notify_data); ++i) {
291 | notify_data[i] = i % 0xff;
292 | }
293 | // the size of notify_data[] need less than MTU size
294 | esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id,
295 | gl_profile_tab[PROFILE_TRAINER_SL_ID].char_handle,
296 | sizeof(notify_data), notify_data, false);
297 | }
298 | } else if (descr_value == 0x0002) {
299 | if (a_property & ESP_GATT_CHAR_PROP_BIT_INDICATE) {
300 | ESP_LOGI(GATTS_TAG, "indicate enable");
301 | uint8_t indicate_data[15];
302 | for (int i = 0; i < sizeof(indicate_data); ++i) {
303 | indicate_data[i] = i % 0xff;
304 | }
305 | // the size of indicate_data[] need less than MTU size
306 | esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id,
307 | gl_profile_tab[PROFILE_TRAINER_SL_ID].char_handle,
308 | sizeof(indicate_data), indicate_data, true);
309 | }
310 | } else if (descr_value == 0x0000) {
311 | ESP_LOGI(GATTS_TAG, "notify/indicate disable ");
312 | } else {
313 | ESP_LOGE(GATTS_TAG, "unknown descr value");
314 | esp_log_buffer_hex(GATTS_TAG, param->write.value, param->write.len);
315 | }
316 | }
317 | }
318 | example_write_event_env(gatts_if, &a_prepare_write_env, param);
319 | break;
320 | }
321 | case ESP_GATTS_EXEC_WRITE_EVT:
322 | ESP_LOGI(GATTS_TAG, "ESP_GATTS_EXEC_WRITE_EVT");
323 | esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id,
324 | ESP_GATT_OK, NULL);
325 | example_exec_write_event_env(&a_prepare_write_env, param);
326 | break;
327 | case ESP_GATTS_MTU_EVT:
328 | ESP_LOGI(GATTS_TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu);
329 | break;
330 | case ESP_GATTS_UNREG_EVT:
331 | break;
332 | case ESP_GATTS_CREATE_EVT:
333 | ESP_LOGI(GATTS_TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d\n",
334 | param->create.status, param->create.service_handle);
335 | gl_profile_tab[PROFILE_TRAINER_SL_ID].service_handle = param->create.service_handle;
336 | gl_profile_tab[PROFILE_TRAINER_SL_ID].char_uuid.len = ESP_UUID_LEN_16;
337 | gl_profile_tab[PROFILE_TRAINER_SL_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_FRSKY_UUID;
338 |
339 | esp_ble_gatts_start_service(gl_profile_tab[PROFILE_TRAINER_SL_ID].service_handle);
340 | a_property = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE |
341 | ESP_GATT_CHAR_PROP_BIT_NOTIFY;
342 | esp_err_t add_char_ret = esp_ble_gatts_add_char(
343 | gl_profile_tab[PROFILE_TRAINER_SL_ID].service_handle,
344 | &gl_profile_tab[PROFILE_TRAINER_SL_ID].char_uuid,
345 | ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, a_property, &gatts_demo_char1_val, NULL);
346 | if (add_char_ret) {
347 | ESP_LOGE(GATTS_TAG, "add char failed, error code =%x", add_char_ret);
348 | }
349 | break;
350 | case ESP_GATTS_ADD_INCL_SRVC_EVT:
351 | break;
352 | case ESP_GATTS_ADD_CHAR_EVT: {
353 | uint16_t length = 0;
354 | const uint8_t *prf_char;
355 |
356 | ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n",
357 | param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
358 | gl_profile_tab[PROFILE_TRAINER_SL_ID].char_handle = param->add_char.attr_handle;
359 | gl_profile_tab[PROFILE_TRAINER_SL_ID].descr_uuid.len = ESP_UUID_LEN_16;
360 | gl_profile_tab[PROFILE_TRAINER_SL_ID].descr_uuid.uuid.uuid16 =
361 | ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
362 | esp_err_t get_attr_ret =
363 | esp_ble_gatts_get_attr_value(param->add_char.attr_handle, &length, &prf_char);
364 | if (get_attr_ret == ESP_FAIL) {
365 | ESP_LOGE(GATTS_TAG, "ILLEGAL HANDLE");
366 | }
367 |
368 | ESP_LOGI(GATTS_TAG, "the gatts demo char length = %x\n", length);
369 | for (int i = 0; i < length; i++) {
370 | ESP_LOGI(GATTS_TAG, "prf_char[%x] =%x\n", i, prf_char[i]);
371 | }
372 | esp_err_t add_descr_ret =
373 | esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_TRAINER_SL_ID].service_handle,
374 | &gl_profile_tab[PROFILE_TRAINER_SL_ID].descr_uuid,
375 | ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL);
376 | if (add_descr_ret) {
377 | ESP_LOGE(GATTS_TAG, "add char descr failed, error code =%x", add_descr_ret);
378 | }
379 | break;
380 | }
381 | case ESP_GATTS_ADD_CHAR_DESCR_EVT:
382 | gl_profile_tab[PROFILE_TRAINER_SL_ID].descr_handle = param->add_char_descr.attr_handle;
383 | ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n",
384 | param->add_char_descr.status, param->add_char_descr.attr_handle,
385 | param->add_char_descr.service_handle);
386 | break;
387 | case ESP_GATTS_DELETE_EVT:
388 | break;
389 | case ESP_GATTS_START_EVT:
390 | ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, status %d, service_handle %d\n", param->start.status,
391 | param->start.service_handle);
392 | break;
393 | case ESP_GATTS_STOP_EVT:
394 | break;
395 | case ESP_GATTS_CONNECT_EVT: {
396 | esp_ble_conn_update_params_t conn_params = {0};
397 | memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
398 | /* For the IOS system, please reference the apple official documents about the ble connection
399 | * parameters restrictions. */
400 | conn_params.latency = 0;
401 | conn_params.max_int = BT_CON_INT_MIN;
402 | conn_params.min_int = BT_CON_INT_MAX;
403 | conn_params.timeout = BT_CON_TIMEOUT;
404 | ESP_LOGI(GATTS_TAG,
405 | "ESP_GATTS_CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:",
406 | param->connect.conn_id, param->connect.remote_bda[0], param->connect.remote_bda[1],
407 | param->connect.remote_bda[2], param->connect.remote_bda[3],
408 | param->connect.remote_bda[4], param->connect.remote_bda[5]);
409 | gl_profile_tab[PROFILE_TRAINER_SL_ID].conn_id = param->connect.conn_id;
410 | // start sent the update connection parameters to the peer device.
411 | esp_ble_gap_update_conn_params(&conn_params);
412 | mempcpy(rmtbtaddress, param->connect.remote_bda, sizeof(esp_bd_addr_t));
413 |
414 | btp_connected = true;
415 | break;
416 | }
417 | case ESP_GATTS_DISCONNECT_EVT:
418 | ESP_LOGI(GATTS_TAG, "ESP_GATTS_DISCONNECT_EVT, disconnect reason 0x%x",
419 | param->disconnect.reason);
420 | esp_ble_gap_start_advertising(&adv_params);
421 | btp_connected = false;
422 | break;
423 | case ESP_GATTS_CONF_EVT:
424 | case ESP_GATTS_OPEN_EVT:
425 | case ESP_GATTS_CANCEL_OPEN_EVT:
426 | case ESP_GATTS_CLOSE_EVT:
427 | case ESP_GATTS_LISTEN_EVT:
428 | case ESP_GATTS_CONGEST_EVT:
429 | default:
430 | break;
431 | }
432 | }
433 |
434 | static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
435 | esp_ble_gatts_cb_param_t *param)
436 | {
437 | /* If event is register event, store the gatts_if for each profile */
438 | if (event == ESP_GATTS_REG_EVT) {
439 | if (param->reg.status == ESP_GATT_OK) {
440 | gl_profile_tab[param->reg.app_id].gatts_if = gatts_if;
441 | } else {
442 | ESP_LOGI(GATTS_TAG, "Reg app failed, app_id %04x, status %d\n", param->reg.app_id,
443 | param->reg.status);
444 | return;
445 | }
446 | }
447 |
448 | /* If the gatts_if equal to profile A, call profile A cb handler,
449 | * so here call each profile's callback */
450 | do {
451 | int idx;
452 | for (idx = 0; idx < PROFILE_NUM; idx++) {
453 | if (gatts_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need
454 | to call every profile cb function */
455 | gatts_if == gl_profile_tab[idx].gatts_if) {
456 | if (gl_profile_tab[idx].gatts_cb) {
457 | gl_profile_tab[idx].gatts_cb(event, gatts_if, param);
458 | }
459 | }
460 | }
461 | } while (0);
462 | }
463 |
464 | int btp_sendChannelData(uint8_t *data, int len)
465 | {
466 | if (!btp_connected) return -1;
467 |
468 | if (gl_profile_tab[PROFILE_TRAINER_SL_ID].gatts_if == ESP_GATT_IF_NONE) return -1;
469 |
470 | // the size of notify_data[] need less than MTU size
471 | esp_ble_gatts_send_indicate(gl_profile_tab[PROFILE_TRAINER_SL_ID].gatts_if,
472 | gl_profile_tab[PROFILE_TRAINER_SL_ID].conn_id,
473 | gl_profile_tab[PROFILE_TRAINER_SL_ID].char_handle, len, data, false);
474 | return 0;
475 | }
476 |
477 | void btpInit(void)
478 | {
479 | ESP_LOGI(GATTS_TAG, "Starting Peripherial");
480 |
481 | esp_err_t ret = esp_ble_gatts_register_callback(gatts_event_handler);
482 | if (ret) {
483 | ESP_LOGE(GATTS_TAG, "gatts register error, error code = %x", ret);
484 | return;
485 | }
486 | ret = esp_ble_gap_register_callback(gap_event_handler);
487 | if (ret) {
488 | ESP_LOGE(GATTS_TAG, "gap register error, error code = %x", ret);
489 | return;
490 | }
491 | ret = esp_ble_gatts_app_register(PROFILE_TRAINER_SL_ID);
492 | if (ret) {
493 | ESP_LOGE(GATTS_TAG, "gatts app register error, error code = %x", ret);
494 | return;
495 | }
496 |
497 | esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(85);
498 | if (local_mtu_ret) {
499 | ESP_LOGE(GATTS_TAG, "set local MTU failed, error code = %x", local_mtu_ret);
500 | }
501 |
502 | // Update Local Address
503 | uint8_t adrtype;
504 | esp_ble_gap_get_local_used_addr(localbtaddress, &adrtype);
505 | }
506 |
--------------------------------------------------------------------------------
/src/bt_server.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /*
3 | This example code is in the Public Domain (or CC0 licensed, at your option.)
4 |
5 | Unless required by applicable law or agreed to in writing, this
6 | software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
7 | CONDITIONS OF ANY KIND, either express or implied.
8 | */
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | void btpInit();
16 | void btp_disconnect();
17 | int btp_sendChannelData(uint8_t *data, int len);
18 |
19 | extern volatile bool btp_connected;
--------------------------------------------------------------------------------
/src/cb.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 |
7 | typedef struct circular_buffer {
8 | char *buffer; // data buffer
9 | char *buffer_end; // end of data buffer
10 | size_t capacity; // maximum number of items in the buffer
11 | size_t count; // number of items in the buffer
12 | char *head; // pointer to head
13 | char *tail; // pointer to tail
14 | } circular_buffer;
15 |
16 | void cb_init(circular_buffer *cb, size_t capacity)
17 | {
18 | cb->buffer = malloc(capacity);
19 | if (cb->buffer == NULL) {
20 | // TODO: handle error
21 | }
22 | cb->buffer_end = cb->buffer + capacity;
23 | cb->capacity = capacity;
24 | cb->count = 0;
25 | cb->head = cb->buffer;
26 | cb->tail = cb->buffer;
27 | }
28 |
29 | void cb_free(circular_buffer *cb) { free(cb->buffer); }
30 |
31 | int cb_push_back(circular_buffer *cb, char *item)
32 | {
33 | if (cb->count == cb->capacity) return -1;
34 |
35 | *cb->head = *item;
36 |
37 | cb->head++;
38 | if (cb->head == cb->buffer_end) cb->head = cb->buffer;
39 | cb->count++;
40 | return 0;
41 | }
42 |
43 | int cb_pop_front(circular_buffer *cb, char *item)
44 | {
45 | if (cb->count == 0) {
46 | return -1;
47 | }
48 | *item = *cb->tail;
49 |
50 | cb->tail++;
51 | if (cb->tail == cb->buffer_end) cb->tail = cb->buffer;
52 | cb->count--;
53 | return 0;
54 | }
--------------------------------------------------------------------------------
/src/defines.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define DEBUG
4 |
5 | #if defined(PCB_PICO)
6 | //#define LEDPIN 6
7 | #define UART_NUM UART_NUM_2
8 | #define UART_TXPIN 4
9 | #define UART_RXPIN 5
10 |
11 | #elif defined(PCB_RMPICO)
12 |
13 | #define UART_NUM UART_NUM_0
14 | #define UART_RXPIN 3
15 | #define UART_TXPIN 1
16 |
17 | #elif defined(PCB_WROOM)
18 |
19 | #define UART_NUM UART_NUM_2
20 | #define UART_TXPIN 18
21 | #define UART_RXPIN 19
22 |
23 | #elif defined(PCB_C3MINI)
24 |
25 | #define UART_NUM UART_NUM_1
26 | #define UART_TXPIN 4
27 | #define UART_RXPIN 5
28 | //#define LEDPIN 6
29 |
30 | #elif defined(PCB_C3SUPERMINI)
31 |
32 | #define UART_NUM UART_NUM_1
33 | #define UART_TXPIN 21
34 | #define UART_RXPIN 20
35 |
36 | #else
37 |
38 | #error "PCB NOT Configured"
39 |
40 | #endif
41 |
42 | #define UART_RX_BUFFER 512
43 | #define UART_TX_BUFFER 512
44 | #define BAUD_RESET_TIMER 1000000 // us
45 | #define BAUD_DEFAULT 115200
46 | #define BAUD_MAXIMUM 921600
47 |
48 | // Optional Debugging Options
49 | #define DEBUG_TIMERS
50 |
51 | #define LEN_BLUETOOTH_NAME 10
52 |
53 | #include
54 | extern const uart_port_t uart_num;
55 |
56 | typedef enum {
57 | ROLE_UNKNOWN=0,
58 | ROLE_BLE_PERIPHERAL,
59 | ROLE_BLE_CENTRAL,
60 | ROLE_ADVANCE,
61 | ROLE_COUNT
62 | } role_t;
63 |
64 | enum features {
65 | FEAT_BLUETOOTH,
66 | FEAT_ESPNOW,
67 | };
68 |
69 | #define PACKED __attribute__((packed))
70 |
--------------------------------------------------------------------------------
/src/frskybt.c:
--------------------------------------------------------------------------------
1 | /* From OpenTX https://github.com/opentx
2 | */
3 |
4 | #include "frskybt.h"
5 |
6 | #include
7 | #include
8 |
9 | #include "bt_server.h"
10 | #include "esp_log.h"
11 | #include "settings.h"
12 |
13 | #define FRSKYBT_TAG "FRSKYBT"
14 |
15 | #define LEN_BLUETOOTH_ADDR 16
16 | #define BLUETOOTH_LINE_LENGTH 32
17 | #define BLUETOOTH_PACKET_SIZE 14
18 |
19 | uint16_t channeldata[BT_CHANNELS];
20 |
21 | /**
22 | * @brief Displays the decoded channel values and time since last receive
23 | *
24 | * @param btdata
25 | * @param len
26 | */
27 |
28 | void logBTFrame(bool valid, char message[])
29 | {
30 | static int64_t ltime = 0;
31 | int64_t timestamp = esp_timer_get_time() - ltime;
32 | ltime = esp_timer_get_time();
33 | if (!valid) {
34 | ESP_LOGE(FRSKYBT_TAG, "(%05lld)Unable to decode data, %s", timestamp, message);
35 | } else {
36 | ESP_LOGI(
37 | FRSKYBT_TAG,
38 | "(%05lld)Ch1[%04d] Ch2[%04d] Ch3[%04d] Ch4[%04d] Ch5[%04d] Ch6[%04d] Ch7[%04d] Ch8[%04d]",
39 | timestamp, channeldata[0], channeldata[1], channeldata[2], channeldata[3], channeldata[4],
40 | channeldata[5], channeldata[6], channeldata[7]);
41 | }
42 | }
43 |
44 | static uint8_t buffer[BLUETOOTH_LINE_LENGTH + 1];
45 | static uint8_t bufferIndex;
46 | static uint8_t crc;
47 |
48 | void pushByte(uint8_t byte)
49 | {
50 | crc ^= byte;
51 | if (byte == START_STOP || byte == BYTE_STUFF) {
52 | buffer[bufferIndex++] = BYTE_STUFF;
53 | byte ^= STUFF_MASK;
54 | }
55 | buffer[bufferIndex++] = byte;
56 | }
57 |
58 | /* Builds Trainer Data
59 | * Returns the length of the encoded PPM + CRC
60 | * Data saved into addr pointer
61 | */
62 |
63 | int setTrainer(uint8_t *addr, uint16_t chan_vals[BT_CHANNELS])
64 | {
65 | // Allocate Channel Mappings, Set Default to all Center
66 | uint8_t *cur = buffer;
67 | bufferIndex = 0;
68 | crc = 0x00;
69 |
70 | buffer[bufferIndex++] = START_STOP; // start byte
71 | pushByte(TRAINER_FRAME); // trainer frame type?
72 | for (int channel = 0; channel < BT_CHANNELS; channel += 2, cur += 3) {
73 | uint16_t channelValue1 = chan_vals[channel];
74 | uint16_t channelValue2 = chan_vals[channel + 1];
75 |
76 | pushByte(channelValue1 & 0x00ff);
77 | pushByte(((channelValue1 & 0x0f00) >> 4) + ((channelValue2 & 0x00f0) >> 4));
78 | pushByte(((channelValue2 & 0x000f) << 4) + ((channelValue2 & 0x0f00) >> 8));
79 | }
80 |
81 | buffer[bufferIndex++] = crc;
82 | buffer[bufferIndex++] = START_STOP; // end byte
83 |
84 | // Copy data to array
85 | memcpy(addr, buffer, bufferIndex);
86 |
87 | return bufferIndex;
88 | }
89 |
90 | //----------------------------------
91 | // Receieve Code
92 | //----------------------------------
93 |
94 | enum { STATE_DATA_IDLE, STATE_DATA_START, STATE_DATA_XOR, STATE_DATA_IN_FRAME };
95 |
96 | static uint8_t _otxbuffer[BLUETOOTH_LINE_LENGTH + 2] = {START_STOP};
97 | static uint8_t *otxbuffer = _otxbuffer + 1;
98 | static uint8_t rsndbuf[BLUETOOTH_LINE_LENGTH + 2];
99 | uint8_t rsndbufindex = 0;
100 | uint8_t otxbufferIndex = 0;
101 | bool btprocessed = false;
102 |
103 | void appendTrainerByte(uint8_t data)
104 | {
105 | if (otxbufferIndex < BLUETOOTH_LINE_LENGTH) {
106 | otxbuffer[otxbufferIndex++] = data;
107 | } else {
108 | ESP_LOGE(FRSKYBT_TAG, "OTX Buffer Overflow");
109 | otxbufferIndex = 0;
110 | }
111 | }
112 |
113 | void processTrainerFrame(const uint8_t *otxbuffer)
114 | {
115 | for (uint8_t channel = 0, i = 1; channel < BT_CHANNELS; channel += 2, i += 3) {
116 | // +-500 != 512, but close enough.
117 | channeldata[channel] = otxbuffer[i] + ((otxbuffer[i + 1] & 0xf0) << 4);
118 | channeldata[channel + 1] = ((otxbuffer[i + 1] & 0x0f) << 4) + ((otxbuffer[i + 2] & 0xf0) >> 4) +
119 | ((otxbuffer[i + 2] & 0x0f) << 8);
120 | }
121 |
122 | if (settings.role == ROLE_BLE_PERIPHERAL) {
123 | rsndbuf[rsndbufindex++] = 0x7e;
124 | /*printf("BTDatOut ");
125 | for(int i=0; i < rsndbufindex; i++) {
126 | printf("%.2x ", rsndbuf[i]);
127 | }
128 | printf("\n");*/
129 | btp_sendChannelData(rsndbuf, rsndbufindex);
130 | }
131 | }
132 |
133 | void frSkyProcessByte(uint8_t data)
134 | {
135 | static uint8_t dataState = STATE_DATA_IDLE;
136 |
137 | switch (dataState) {
138 | case STATE_DATA_START:
139 | if (data == START_STOP) {
140 | dataState = STATE_DATA_IN_FRAME;
141 | otxbufferIndex = 0;
142 | rsndbufindex = 0;
143 | } else {
144 | appendTrainerByte(data);
145 | }
146 | break;
147 |
148 | case STATE_DATA_IN_FRAME:
149 | if (data == BYTE_STUFF) {
150 | dataState = STATE_DATA_XOR; // XOR next byte
151 | } else if (data == START_STOP) {
152 | dataState = STATE_DATA_IN_FRAME;
153 | otxbufferIndex = 0;
154 | rsndbufindex = 0;
155 | } else {
156 | appendTrainerByte(data);
157 | }
158 | break;
159 |
160 | case STATE_DATA_XOR:
161 | switch (data) {
162 | case BYTE_STUFF ^ STUFF_MASK:
163 | case START_STOP ^ STUFF_MASK:
164 | // Expected content, save the data
165 | appendTrainerByte(data ^ STUFF_MASK);
166 | dataState = STATE_DATA_IN_FRAME;
167 | break;
168 | case START_STOP: // Illegal situation, as we have START_STOP, try to start from the
169 | // beginning
170 | otxbufferIndex = 0;
171 | rsndbufindex = 0;
172 | dataState = STATE_DATA_IN_FRAME;
173 | break;
174 | default:
175 | // Illegal situation, start looking for a new START_STOP byte
176 | dataState = STATE_DATA_START;
177 | break;
178 | }
179 | break;
180 |
181 | case STATE_DATA_IDLE:
182 | if (data == START_STOP) {
183 | otxbufferIndex = 0;
184 | rsndbufindex = 0;
185 | dataState = STATE_DATA_START;
186 | } else {
187 | appendTrainerByte(data);
188 | }
189 | break;
190 | }
191 |
192 | if (otxbufferIndex >= BLUETOOTH_PACKET_SIZE) {
193 | if(rsndbufindex <= BLUETOOTH_LINE_LENGTH+1)
194 | rsndbuf[rsndbufindex++] = data;
195 | uint8_t crc = 0x00;
196 | for (int i = 0; i < BLUETOOTH_PACKET_SIZE - 1; i++) {
197 | crc ^= otxbuffer[i];
198 | }
199 | if (crc == otxbuffer[BLUETOOTH_PACKET_SIZE - 1]) {
200 | if (otxbuffer[0] == TRAINER_FRAME) {
201 | processTrainerFrame(otxbuffer);
202 | // logBTFrame(true, "");
203 | } else {
204 | //logBTFrame(false, "Not a trainer frame");
205 | }
206 | } else {
207 | //logBTFrame(false, "CRC Fault");
208 | }
209 | dataState = STATE_DATA_IDLE;
210 | } else {
211 | // Create a copy, split at start/stop
212 | if(rsndbufindex <= BLUETOOTH_LINE_LENGTH+1)
213 | rsndbuf[rsndbufindex++] = data;
214 | }
215 | }
216 |
217 | void processFrame(const uint8_t *frame, uint8_t len)
218 | {
219 | for (int i = 0; i < len; i++) {
220 | frSkyProcessByte(frame[i]);
221 | }
222 | }
--------------------------------------------------------------------------------
/src/frskybt.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | #define START_STOP 0x7E
8 | #define BYTE_STUFF 0x7D
9 | #define TRAINER_FRAME 0x80
10 | #define STUFF_MASK 0x20
11 | #define BT_CHANNELS 8
12 |
13 | enum {
14 | BT_CRC_FAULT = -1,
15 | BT_SUCCESS = 0,
16 | };
17 |
18 | int setTrainer(uint8_t *addr, uint16_t chan_vals[BT_CHANNELS]);
19 | void frSkyProcessByte(uint8_t data);
20 | void processFrame(const uint8_t *frame, uint8_t len);
--------------------------------------------------------------------------------
/src/main.c:
--------------------------------------------------------------------------------
1 | /*
2 | This example code is in the Public Domain (or CC0 licensed, at your option.)
3 |
4 | Unless required by applicable law or agreed to in writing, this
5 | software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
6 | CONDITIONS OF ANY KIND, either express or implied.
7 | */
8 |
9 | /****************************************************************************
10 | *
11 | * This demo showcases creating a GATT database using a predefined attribute
12 | *table. It acts as a GATT server and can send adv data, be connected by client.
13 | * Run the gatt_client demo, the client demo will automatically connect to the
14 | *gatt_server_service_table demo. Client demo will enable GATT server's notify
15 | *after connection. The two devices will then exchange data.
16 | *
17 | ****************************************************************************/
18 |
19 | #include "bt.h"
20 | #include "defines.h"
21 | #include "driver/adc.h"
22 | #include "driver/gpio.h"
23 | #include "driver/uart.h"
24 | #include "esp_log.h"
25 | #include "esp_system.h"
26 | #include "freertos/FreeRTOS.h"
27 | #include "freertos/event_groups.h"
28 | #include "freertos/task.h"
29 | #include "nvs_flash.h"
30 | #include "settings.h"
31 | #include "terminal.h"
32 |
33 | nvs_handle_t nvs_flsh_btw;
34 |
35 | #if defined(LEDPIN)
36 | void runBlinky()
37 | {
38 | gpio_set_direction(LEDPIN, GPIO_MODE_DEF_OUTPUT);
39 | for (;;) {
40 | gpio_set_level(LEDPIN, 0);
41 | vTaskDelay(pdMS_TO_TICKS(100));
42 | gpio_set_level(LEDPIN, 1);
43 | vTaskDelay(pdMS_TO_TICKS(100));
44 | }
45 | }
46 | #endif
47 |
48 | void app_main(void)
49 | {
50 | TaskHandle_t tUartHnd = NULL;
51 | xTaskCreate(runUARTHead, "UART", 4096, NULL, tskIDLE_PRIORITY + 2, &tUartHnd);
52 | configASSERT(tUartHnd);
53 |
54 | #if defined(LEDPIN)
55 | TaskHandle_t tBlinkHnd = NULL;
56 | xTaskCreate(runBlinky, "Blinky", 1024, NULL, tskIDLE_PRIORITY, &tBlinkHnd);
57 | configASSERT(tBlinkHnd);
58 | #endif
59 |
60 | esp_err_t ret;
61 |
62 | /* Initialize NVS. */
63 | ret = nvs_flash_init();
64 | if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
65 | ESP_ERROR_CHECK(nvs_flash_erase());
66 | ret = nvs_flash_init();
67 | }
68 | ESP_ERROR_CHECK(ret);
69 |
70 | ESP_ERROR_CHECK(nvs_open("btwifi", NVS_READWRITE, &nvs_flsh_btw));
71 |
72 | loadSettings();
73 | }
74 |
--------------------------------------------------------------------------------
/src/settings.c:
--------------------------------------------------------------------------------
1 | #include "settings.h"
2 |
3 | #include "esp_log.h"
4 | #include "nvs_flash.h"
5 |
6 | #define LOG_SET "SETTINGS"
7 |
8 | #define NVS_STRUCT_KEY "skey"
9 |
10 | void _loadSettings(settings_t *set);
11 |
12 | settings_t settings = {.role = ROLE_UNKNOWN};
13 | extern nvs_handle_t nvs_flsh_btw;
14 | volatile bool settings_ok = false;
15 |
16 | // TODO - Add a delay here, so multiple calls don't write twice
17 | void saveSettings()
18 | {
19 | settings_t flashsettings;
20 | _loadSettings(&flashsettings);
21 |
22 | if (!memcmp((void *)&flashsettings, (void *)&settings, sizeof(settings_t))) {
23 | ESP_LOGI(LOG_SET, "No data differs, not writing to flash");
24 | return;
25 | } else {
26 | ESP_LOGI(LOG_SET, "Data is different, FR=%d, MR=%d", flashsettings.role, settings.role);
27 | }
28 |
29 | esp_err_t err = nvs_set_blob(nvs_flsh_btw, NVS_STRUCT_KEY, (void *)&settings, sizeof(settings_t));
30 | if (err == ESP_OK) {
31 | ESP_LOGI(LOG_SET, "Blob store success");
32 | } else {
33 | ESP_LOGE(LOG_SET, "Unable to store blob - %s", esp_err_to_name(err));
34 | }
35 | err = nvs_commit(nvs_flsh_btw);
36 | if (err == ESP_OK) {
37 | ESP_LOGI(LOG_SET, "Settings written Successfully");
38 | } else {
39 | ESP_LOGE(LOG_SET, "Unable to write settings - %s", esp_err_to_name(err));
40 | }
41 | }
42 |
43 | void _loadSettings(settings_t *s)
44 | {
45 | ESP_LOGI(LOG_SET, "Reading settings");
46 | size_t length = sizeof(settings_t);
47 | esp_err_t ret = nvs_get_blob(nvs_flsh_btw, NVS_STRUCT_KEY, (void *)s, &length);
48 | if (ret == ESP_OK && length == sizeof(settings_t)) {
49 | ESP_LOGI(LOG_SET, "Settings Read Successfully");
50 | return;
51 | } else {
52 | if (ret == ESP_OK) {
53 | ESP_LOGE(LOG_SET, "Incorrect Settings Length");
54 | } else {
55 | ESP_LOGE(LOG_SET, "Error (%s) reading\n", esp_err_to_name(ret));
56 | }
57 | }
58 | // Settings invalid, clear the memory
59 | memset(s, 0, sizeof(settings_t));
60 | }
61 |
62 | void loadSettings()
63 | {
64 | // Load settings into global settings struct.
65 | _loadSettings(&settings);
66 |
67 | // Will be filled properly here or nulled out
68 | settings_ok = true;
69 | }
--------------------------------------------------------------------------------
/src/settings.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "bt_client.h"
4 | #include "defines.h"
5 |
6 | typedef struct {
7 | // uint8_t version // Todo the version info here, check on load it matches otherwise ignore
8 | char rmtbtaddr[13];
9 | role_t role;
10 | } settings_t;
11 |
12 | extern settings_t settings;
13 | extern volatile bool settings_ok;
14 |
15 | void loadSettings();
16 | void saveSettings();
--------------------------------------------------------------------------------
/src/terminal.c:
--------------------------------------------------------------------------------
1 | #include "terminal.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include "bt.h"
9 | #include "bt_client.h"
10 | #include "bt_server.h"
11 | #include "cb.h"
12 | #include "defines.h"
13 | #include "esp_log.h"
14 | #include "esp_timer.h"
15 | #include "frskybt.h"
16 | #include "settings.h"
17 |
18 | #define LOG_UART "UART"
19 |
20 | #define UART_RX_BUFFER 512
21 | #define REUSABLE_BUFFER 250
22 | #define AT_CMD_MAX_LEN 40
23 | #define BT_CMD_MAX_LEN 30
24 |
25 | void runBT();
26 | void setBaudRate(uint32_t baudRate);
27 | void setRole(role_t role);
28 |
29 | const uart_port_t uart_num = UART_NUM;
30 |
31 | #define UART_WRITE_STRING(x, y) uart_write_bytes(x, y, sizeof(y) - 1)
32 |
33 | typedef enum {
34 | CENTRAL_STATE_DISCONNECT,
35 | CENTRAL_STATE_IDLE,
36 | CENTRAL_STATE_SCAN_START,
37 | CENTRAL_STATE_SCANNING,
38 | CENTRAL_STATE_SCAN_COMPLETE,
39 | CENTRAL_STATE_CONNECT,
40 | CENTRAL_STATE_WAITING_CONNECTION,
41 | CENTRAL_STATE_CONNECTED,
42 | } btcentralstate;
43 |
44 | typedef enum {
45 | PERIPHERIAL_STATE_DISCONNECTED,
46 | PERIPHERIAL_STATE_CONNECTED,
47 | } btperipheralstate;
48 |
49 | role_t curMode = ROLE_UNKNOWN;
50 | btcentralstate btCentralState = CENTRAL_STATE_DISCONNECT;
51 | btperipheralstate btPeripherialState = PERIPHERIAL_STATE_DISCONNECTED;
52 | int64_t baudTimer = 0;
53 | int laddcnt = 0;
54 |
55 | char rmtaddress[13] = "000000000000";
56 | char reusablebuff[REUSABLE_BUFFER];
57 |
58 | void sendBTMode()
59 | {
60 | char lcladdress[13] = "000000000000";
61 | btaddrtostr(lcladdress, localbtaddress);
62 | ESP_LOGI(LOG_UART, "Local Addr %s", lcladdress);
63 | if (curMode == ROLE_BLE_PERIPHERAL) {
64 | snprintf(reusablebuff, sizeof(reusablebuff), "Peripheral:%s\r\n", lcladdress);
65 | uart_write_bytes(uart_num, reusablebuff, strlen(reusablebuff));
66 | } else if (curMode == ROLE_BLE_CENTRAL) {
67 | snprintf(reusablebuff, sizeof(reusablebuff), "Central:%s\r\n", lcladdress);
68 | uart_write_bytes(uart_num, reusablebuff, strlen(reusablebuff));
69 | }
70 | }
71 |
72 | void parserATCommand(char atcommand[])
73 | {
74 | // Strip trailing whitespace
75 | bool done = false;
76 | while (!done) {
77 | int len = strlen(atcommand);
78 | if (len > 0 && (atcommand[len - 1] == '\n' || atcommand[len - 1] == '\r'))
79 | atcommand[len - 1] = '\0';
80 | else
81 | done = true;
82 | }
83 |
84 | if (strncmp(atcommand, "+ROLE0", 6) == 0) {
85 | ESP_LOGI(LOG_UART, "Setting role as Peripheral");
86 | UART_WRITE_STRING(uart_num, "OK+Role:0\r\n");
87 | setRole(ROLE_BLE_PERIPHERAL);
88 | sendBTMode();
89 |
90 | } else if (strncmp(atcommand, "+ROLE1", 6) == 0) {
91 | ESP_LOGI(LOG_UART, "Setting role as Central");
92 | UART_WRITE_STRING(uart_num, "OK+Role:1\r\n");
93 | setRole(ROLE_BLE_CENTRAL);
94 | sendBTMode();
95 |
96 | } else if (strncmp(atcommand, "+CON", 4) == 0) {
97 | if (curMode == ROLE_BLE_CENTRAL) {
98 | // Connect to device specified
99 | snprintf(reusablebuff, sizeof(reusablebuff), "OK+CONNA\r\nConnecting to:%s\r\n",
100 | atcommand + 4);
101 | uart_write_bytes(uart_num, reusablebuff, strlen(reusablebuff));
102 | // Store Remote Address to Connect to
103 | strcpy(rmtaddress, atcommand + 4);
104 | // Start connection
105 | btCentralState = CENTRAL_STATE_CONNECT;
106 | } else {
107 | UART_WRITE_STRING(uart_num, "ERROR");
108 | }
109 |
110 | } else if (strncmp(atcommand, "+NAME", 5) == 0) {
111 | ESP_LOGI(LOG_UART, "Setting Name to %s", atcommand + 5);
112 | btSetName(atcommand + 5);
113 | snprintf(reusablebuff, sizeof(reusablebuff), "OK+Name:%s\r\n", atcommand + 5);
114 | uart_write_bytes(uart_num, reusablebuff, strlen(reusablebuff));
115 | sendBTMode();
116 |
117 | } else if (strncmp(atcommand, "+TXPW", 5) == 0) {
118 | ESP_LOGI(LOG_UART, "Setting Power to %s", atcommand + 5);
119 | UART_WRITE_STRING(uart_num, "OK+Txpw:0\r\n");
120 | sendBTMode();
121 |
122 | } else if (strncmp(atcommand, "+DISC?", 6) == 0) {
123 | if (curMode == ROLE_BLE_CENTRAL) {
124 | ESP_LOGI(LOG_UART, "Discovery Requested");
125 | UART_WRITE_STRING(uart_num, "OK+DISCS\r\n");
126 | laddcnt = 0;
127 | if (btCentralState != CENTRAL_STATE_SCAN_START && btCentralState != CENTRAL_STATE_SCANNING)
128 | btCentralState = CENTRAL_STATE_SCAN_START;
129 | }
130 |
131 | } else if (strncmp(atcommand, "+CLEAR", 6) == 0) {
132 | if (curMode == ROLE_BLE_CENTRAL) {
133 | btCentralState = CENTRAL_STATE_DISCONNECT;
134 | UART_WRITE_STRING(uart_num, "OK+CLEAR\r\n");
135 | }
136 |
137 | } else if (strncmp(atcommand, "+BAUD", 5) == 0) {
138 | strncpy(reusablebuff, &atcommand[6], sizeof(reusablebuff));
139 | int baudrate = atoi(reusablebuff);
140 | ESP_LOGI(LOG_UART, "Baud Rate Change Requested to %d", baudrate);
141 |
142 | baudTimer = esp_timer_get_time() + BAUD_RESET_TIMER;
143 | // setBaudRate(baudrate); TODO
144 | // UART_WRITE_STRING(uart_num, "OK+BAUD\r\n");
145 |
146 | // TO DO: We need to check if the new baud worked. If the above timer elapses
147 | // before an AT+ACK or something is seen. Then revert back to the default
148 | // baud
149 |
150 | } else if (strncmp(atcommand, "+HTRESET", 8) == 0) {
151 | if (btc_board_type == BLE_BOARD_HEADTRACKER) {
152 | ESP_LOGI(LOG_UART, "Reset Head Tracker Requested");
153 | UART_WRITE_STRING(uart_num, "OK+HTRESET\r\n");
154 | btc_dohtreset();
155 | } else {
156 | UART_WRITE_STRING(uart_num, "ERROR");
157 | }
158 |
159 | } else {
160 | ESP_LOGE(LOG_UART, "Unknown AT Cmd: %s", atcommand);
161 | }
162 | }
163 |
164 | // Ticks to wait for data stream to come in
165 |
166 | uart_config_t uart_config = {
167 | .baud_rate = BAUD_DEFAULT,
168 | .data_bits = UART_DATA_8_BITS,
169 | .parity = UART_PARITY_DISABLE,
170 | .stop_bits = UART_STOP_BITS_1,
171 | .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
172 | .source_clk = UART_SCLK_APB,
173 | };
174 |
175 | void setBaudRate(uint32_t baudRate)
176 | {
177 | if (baudRate < BAUD_DEFAULT || baudRate > BAUD_MAXIMUM) return;
178 | uart_config.baud_rate = baudRate;
179 | ESP_ERROR_CHECK(uart_param_config(uart_num, &uart_config));
180 | }
181 |
182 | char atcommand[AT_CMD_MAX_LEN];
183 | int atcommandlen = -1;
184 |
185 | circular_buffer uartinbuf;
186 |
187 | void runUARTHead()
188 | {
189 | // Setup UART Port
190 | ESP_ERROR_CHECK(uart_param_config(uart_num, &uart_config));
191 | ESP_ERROR_CHECK(
192 | uart_driver_install(uart_num, UART_RX_BUFFER * 2, UART_RX_BUFFER * 2, 0, NULL, 0));
193 | ESP_ERROR_CHECK(
194 | uart_set_pin(uart_num, UART_TXPIN, UART_RXPIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
195 |
196 | cb_init(&uartinbuf, UART_RX_BUFFER * 2);
197 |
198 | ESP_LOGI(LOG_UART, "Waiting for settings to be read");
199 | while (!settings_ok) {
200 | vTaskDelay(50);
201 | }; // Pause until settings are read
202 | ESP_LOGI(LOG_UART, "Setting initial role");
203 | if (settings.role == ROLE_UNKNOWN) {
204 | ESP_LOGE(LOG_UART, "Invalid role loaded, defaulting to central");
205 | settings.role = ROLE_BLE_CENTRAL;
206 | }
207 | setRole(settings.role);
208 |
209 | char* data = (char*)malloc(UART_RX_BUFFER + 1);
210 | if (data == NULL) {
211 | ESP_LOGE(LOG_UART, "No Memory!!!!!\nHALT");
212 | for (;;) {
213 | }
214 | }
215 |
216 | while (1) {
217 | int cnt = uart_read_bytes(uart_num, data, UART_RX_BUFFER, 0);
218 | for (int i = 0; i < cnt; i++) cb_push_back(&uartinbuf, &data[i]);
219 |
220 | char c;
221 | while (!cb_pop_front(&uartinbuf, &c)) {
222 | if (atcommandlen >= 0) {
223 | atcommand[atcommandlen++] = c;
224 | // Check for buffer overflow
225 | if (atcommandlen >= sizeof(atcommand) - 1) {
226 | ESP_LOGE(LOG_UART, "AT Command Buffer Overflow");
227 | atcommandlen = -1;
228 | continue;
229 | }
230 | // AT Command Termination
231 | if (c == '\n') {
232 | atcommand[atcommandlen] = '\0';
233 | parserATCommand(atcommand);
234 | atcommandlen = -1;
235 | }
236 | } else {
237 | // Scan for characters AT in the byte stream
238 | static char lc = 0;
239 | if (lc == 'A' && c == 'T') {
240 | atcommandlen = 0;
241 | } else {
242 | frSkyProcessByte(c);
243 | }
244 |
245 | lc = c;
246 | }
247 | }
248 |
249 | runBT();
250 | vTaskDelay(1);
251 | }
252 | free(data);
253 | vTaskDelete(NULL);
254 | }
255 |
256 | void setRole(role_t role)
257 | {
258 | ESP_LOGI(LOG_UART, "Switching from mode %d to %d", curMode, role);
259 | if (role == curMode) return;
260 |
261 | // Shutdown
262 | switch (curMode) {
263 | case ROLE_BLE_CENTRAL:
264 | case ROLE_BLE_PERIPHERAL:
265 | bt_disable();
266 | default:
267 | break;
268 | }
269 |
270 | // Update Role
271 | curMode = role;
272 | settings.role = curMode;
273 |
274 | // Initialize
275 | switch (curMode) {
276 | case ROLE_BLE_CENTRAL:
277 | btCentralState = CENTRAL_STATE_DISCONNECT;
278 | bt_init();
279 | btcInit();
280 | break;
281 | case ROLE_BLE_PERIPHERAL:
282 | btPeripherialState = PERIPHERIAL_STATE_DISCONNECTED;
283 | bt_init();
284 | btpInit();
285 | break;
286 | default:
287 | break;
288 | }
289 |
290 | // Save new role to flash
291 | saveSettings();
292 | }
293 |
294 | void runBTCentral()
295 | {
296 | switch (btCentralState) {
297 | case CENTRAL_STATE_DISCONNECT: {
298 | // Stop scanning, disconnect from all periferials
299 | btc_disconnect();
300 | break;
301 | }
302 | case CENTRAL_STATE_SCAN_START: {
303 | laddcnt = 0;
304 | btc_start_scan();
305 | btCentralState = CENTRAL_STATE_SCANNING;
306 | break;
307 | }
308 |
309 | case CENTRAL_STATE_SCANNING: {
310 | // New item(s) added
311 | for (int i = laddcnt; i < bt_scanned_address_cnt; i++) {
312 | char addr[13];
313 | sprintf(reusablebuff, "OK+DISC:%s\r\n", btaddrtostr(addr, btc_scanned_addresses[i].addr));
314 | // printf("%s",reusablebuff);
315 | uart_write_bytes(uart_num, reusablebuff, strlen(reusablebuff));
316 | }
317 | laddcnt = bt_scanned_address_cnt;
318 | if (btc_scan_complete) {
319 | btCentralState = CENTRAL_STATE_SCAN_COMPLETE;
320 | }
321 | break;
322 | }
323 | case CENTRAL_STATE_SCAN_COMPLETE: {
324 | UART_WRITE_STRING(uart_num, "OK+DISCE\r\n");
325 | btCentralState = CENTRAL_STATE_IDLE;
326 | break;
327 | }
328 | case CENTRAL_STATE_IDLE: {
329 | // TODO Automatically try to connect to the last known bluetooth address
330 | // esp_bd_addr_t btaddr;
331 | // if(!readBTAddress(btaddr)) {
332 | // btCentralState = CENTRAL_STATE_CONNECT;
333 | //}
334 | // Do Nothing
335 | break;
336 | }
337 |
338 | // Connection was requested
339 | case CENTRAL_STATE_CONNECT: {
340 | esp_bd_addr_t addr;
341 | strtobtaddr(addr, rmtaddress);
342 | btc_connect(addr);
343 | btCentralState = CENTRAL_STATE_WAITING_CONNECTION;
344 | break;
345 | }
346 | case CENTRAL_STATE_WAITING_CONNECTION: {
347 | if (btc_scan_complete) {
348 | if (btc_validslavefound) {
349 | sprintf(reusablebuff, "Connected:%s\r\n", rmtaddress);
350 | uart_write_bytes(uart_num, reusablebuff, strlen(reusablebuff));
351 | sprintf(
352 | reusablebuff,
353 | "MTU Size:65\r\nMTU Size: 65\r\nPHT Update Complete\r\nCurrent PHY:2M\r\n"); // Fix
354 | // me
355 | uart_write_bytes(uart_num, reusablebuff, strlen(reusablebuff));
356 | sprintf(reusablebuff, "Board:%s\r\n", str_ble_board_types[btc_board_type]);
357 | uart_write_bytes(uart_num, reusablebuff, strlen(reusablebuff));
358 | btCentralState = CENTRAL_STATE_CONNECTED;
359 | // TODO: Add
360 |
361 | } else {
362 | btCentralState = CENTRAL_STATE_DISCONNECT;
363 | }
364 | }
365 | break;
366 | }
367 |
368 | case CENTRAL_STATE_CONNECTED: {
369 | if (!btc_connected) { // Connection Lost
370 | btCentralState = CENTRAL_STATE_CONNECT;
371 | }
372 | }
373 | }
374 | }
375 |
376 | void runBTPeripherial()
377 | {
378 | switch (btPeripherialState) {
379 | case PERIPHERIAL_STATE_DISCONNECTED:
380 | if (btp_connected) {
381 | // Save Remote Address
382 | btaddrtostr(rmtaddress, rmtbtaddress);
383 | sprintf(reusablebuff, "Connected:%s\r\n", rmtaddress);
384 | uart_write_bytes(uart_num, reusablebuff, strlen(reusablebuff));
385 | btPeripherialState = PERIPHERIAL_STATE_CONNECTED;
386 | }
387 | break;
388 | case PERIPHERIAL_STATE_CONNECTED:
389 | if (!btp_connected) {
390 | btPeripherialState = PERIPHERIAL_STATE_DISCONNECTED;
391 | uart_write_bytes(uart_num, "DisConnected\r\nERROR\r\nERROR\r\n", 28);
392 | }
393 | break;
394 | }
395 | }
396 |
397 | void runBT()
398 | {
399 | switch (curMode) {
400 | case ROLE_BLE_CENTRAL:
401 | runBTCentral();
402 | break;
403 | case ROLE_BLE_PERIPHERAL:
404 | runBTPeripherial();
405 | break;
406 | /*case ROLE_BTEDR_AUDIO_SOURCE:
407 | break;
408 | case ROLE_ESPNOW_CENTRAL:
409 | break;
410 | case ROLE_ESPNOW_PERIPHERAL:
411 | break;*/
412 | default:
413 | break;
414 | }
415 | }
--------------------------------------------------------------------------------
/src/terminal.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "defines.h"
4 |
5 | // NOTE:: Not used at the moment.
6 | // Future planning/thinking to enable more robust packet
7 | // format for features that could be added while keeping
8 | // interface cleaner
9 | //
10 |
11 | // Packet Format
12 | typedef struct {
13 | uint8_t len; // Data length. Max 255 per packet
14 | uint8_t type; // Packet Type
15 | uint8_t data[256]; // User Data
16 | uint16_t crc; // CRC16:xxxx of the packet
17 | } packet_s;
18 |
19 | // Struct for a PACKET_TYPE_8_CHANNEL
20 | // channelmask is the bitmask of the valid channels
21 | // Keeping SBUS Style 11 Bits of channel info
22 |
23 | typedef struct PACKED {
24 | uint16_t ch01 : 11;
25 | uint16_t ch02 : 11;
26 | uint16_t ch03 : 11;
27 | uint16_t ch04 : 11;
28 | uint16_t ch05 : 11;
29 | uint16_t ch06 : 11;
30 | uint16_t ch07 : 11;
31 | uint16_t ch08 : 11;
32 | uint16_t ch09 : 11;
33 | uint16_t ch11 : 11;
34 | uint16_t ch12 : 11;
35 | uint16_t ch13 : 11;
36 | uint16_t ch14 : 11;
37 | uint16_t ch15 : 11;
38 | uint16_t ch16 : 11;
39 | uint16_t ch17 : 11;
40 | uint16_t ch18 : 11;
41 | uint16_t ch19 : 11;
42 | uint16_t ch20 : 11;
43 | uint16_t ch21 : 11;
44 | uint16_t ch22 : 11;
45 | uint16_t ch23 : 11;
46 | uint16_t ch24 : 11;
47 | uint16_t ch26 : 11;
48 | uint16_t ch27 : 11;
49 | uint16_t ch28 : 11;
50 | uint16_t ch29 : 11;
51 | uint16_t ch30 : 11;
52 | uint16_t ch31 : 11;
53 | uint16_t ch32 : 11; // 352 bits, 44 bytes
54 | uint32_t channelmask;
55 | } channeldata_s; // 48 bytes total
56 |
57 | // Packet Type Field
58 | // Bit [0:4] - Packet Type
59 | // Bit [5] - Require an acknowledge to be returned
60 | // Bit [6] - Continuation Packet
61 |
62 | // 0 1 2 3 4 5 6 7
63 | // 1 (0:6) Packets Remaining
64 | // 1 (6:7) ACK required
65 | // m m m m m 0 0 0 (0:5) Packet Type
66 |
67 | // x x x x x x 1 x -
68 | // If Bit7 clear (type&^0x80) then,
69 | // Type is defines as the below ennums
70 | // If Bit7 set then Bits0:6 = Remaining Packets to receive
71 |
72 | enum {
73 | PACKET_TYPE_ACK = 0, // Got it.
74 | PACKET_TYPE_NAK, // Didn't Ack, need resend
75 | PACKET_TYPE_SETMODE, // Mode change request
76 | PACKET_TYPE_COMMAND, // A Command (Do something in current mode)
77 | PACKET_TYPE_8_CHANNEL, // Contains 8 11bit Channels
78 | PACKET_TYPE_16_CHANNEL, // Contains 16 11bit Channels
79 | PACKET_TYPE_32_CHANNEL, // Contains 32 11bit Channels
80 | PACKET_TYPE_TELEMETRY, // Contains a telemetery sensor
81 | PACKET_TYPE_AUDIO, // Contains streamed audio data
82 | };
83 |
84 | void runUARTHead();
85 | void logBTFrame(const char btdata[], int len);
--------------------------------------------------------------------------------
/test/README:
--------------------------------------------------------------------------------
1 |
2 | This directory is intended for PlatformIO Unit Testing and project tests.
3 |
4 | Unit Testing is a software testing method by which individual units of
5 | source code, sets of one or more MCU program modules together with associated
6 | control data, usage procedures, and operating procedures, are tested to
7 | determine whether they are fit for use. Unit testing finds problems early
8 | in the development cycle.
9 |
10 | More information about PlatformIO Unit Testing:
11 | - https://docs.platformio.org/page/plus/unit-testing.html
12 |
--------------------------------------------------------------------------------
/test/test_cb.c:
--------------------------------------------------------------------------------
1 | #include "unity.h"
2 | #include "cb.h"
3 |
4 |
5 | void test_basics(void) {
6 | char xval;
7 | circular_buffer buffer;
8 | cb_init(&buffer, 200);
9 |
10 | char* test = "Hello world";
11 | for (int i = 0; i < sizeof(test); i++) {
12 | cb_push_back(&buffer, test+i);
13 | }
14 |
15 | TEST_ASSERT_TRUE(buffer.count == sizeof(test));
16 |
17 | for (int i = 0; i < sizeof(test); i++) {
18 | char charval;
19 | int retval = cb_pop_front(&buffer, &charval);
20 | TEST_ASSERT_TRUE(retval == 0);
21 | TEST_ASSERT_TRUE(test[i] == charval);
22 | }
23 |
24 | TEST_ASSERT_TRUE(cb_pop_front(&buffer, &xval) == -1);
25 | }
26 |
27 | void test_simple_circle(void) {
28 | char xval;
29 | circular_buffer buffer;
30 | cb_init(&buffer, 200);
31 |
32 | for (int i = 0; i < 5000; i++) {
33 | for (int j = 0; j < 17; j++) {
34 | char inval = 'A' + j;
35 | TEST_ASSERT_FALSE(cb_push_back(&buffer, &inval));
36 | }
37 |
38 | // printf("buffer=%p buffer_end=%p capacity=%d count=%d head=%p tail=%p\n",
39 | // buffer.buffer, buffer.buffer_end, buffer.capacity,
40 | // buffer.count, buffer.head, buffer.tail);
41 |
42 | for (int j = 0; j < 17; j++) {
43 | char retval;
44 | TEST_ASSERT_FALSE(cb_pop_front(&buffer, &retval));
45 | TEST_ASSERT_TRUE((char)('A' + j) == retval);
46 | }
47 |
48 | TEST_ASSERT_TRUE(cb_pop_front(&buffer, &xval) == -1);
49 | }
50 | }
51 |
52 | void test_overflow(void) {
53 | circular_buffer buffer;
54 | cb_init(&buffer, 42);
55 |
56 | for (int i = 0; i < 5000; i++) {
57 | for (int j = 0; j < 50; j++) {
58 | char inval = 'A' + j;
59 | int retval = cb_push_back(&buffer, &inval);
60 | TEST_ASSERT_TRUE(retval == (j < 42 ? 0 : -1));
61 | }
62 |
63 | for (int j = 0; j < 50; j++) {
64 | int retval;
65 | char retchar;
66 | retval = cb_pop_front(&buffer, &retchar);
67 | if (j < 42) {
68 | TEST_ASSERT_FALSE(retval);
69 | if ((char)('A' + j) != retchar) {
70 | char mesg[300];
71 | snprintf(mesg, 300, "loop=%d, j=%d, retchar=%d\n", i, j, retchar);
72 | TEST_FAIL_MESSAGE(mesg);
73 | }
74 | TEST_ASSERT_TRUE((char)('A' + j) == retchar);
75 | } else {
76 | TEST_ASSERT_TRUE(retval == -1);
77 | }
78 | }
79 |
80 | TEST_ASSERT_TRUE(buffer.count == 0);
81 | }
82 | }
83 |
84 | int runUnityTests(void) {
85 | UNITY_BEGIN();
86 | RUN_TEST(test_basics);
87 | RUN_TEST(test_simple_circle);
88 | RUN_TEST(test_overflow);
89 | return UNITY_END();
90 | }
91 |
92 |
93 | /**
94 | * For native dev-platform or for some embedded frameworks
95 | */
96 | int main(void) {
97 | return runUnityTests();
98 | }
99 |
100 | /**
101 | * For ESP-IDF framework
102 | */
103 | void app_main() {
104 | runUnityTests();
105 | }
--------------------------------------------------------------------------------
/workspace.code-workspace:
--------------------------------------------------------------------------------
1 | {
2 | "folders": [
3 | {
4 | "path": "."
5 | }
6 | ],
7 | "settings": {
8 | "files.associations": {
9 | "esp_gap_ble_api.h": "c",
10 | "*.ipp": "c",
11 | "system_error": "c"
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------