├── .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 | } --------------------------------------------------------------------------------