├── .github └── workflows │ └── release.yml ├── .gitignore ├── .gitmodules ├── LICENSE.md ├── README.md ├── boards.txt ├── cores └── arduino │ ├── Arduino.h │ ├── api │ ├── ArduinoAPI.h │ ├── Binary.h │ ├── Client.h │ ├── Common.cpp │ ├── Common.h │ ├── Compat.h │ ├── HardwareSerial.cpp │ ├── HardwareSerial.h │ ├── IPAddress.cpp │ ├── IPAddress.h │ ├── Interrupts.h │ ├── Print.cpp │ ├── Print.h │ ├── Printable.h │ ├── RingBuffer.h │ ├── Server.h │ ├── Stream.cpp │ ├── Stream.h │ ├── String.cpp │ ├── String.h │ ├── Udp.h │ ├── WCharacter.h │ ├── deprecated-avr-comp │ │ └── avr │ │ │ ├── dtostrf.c.impl │ │ │ ├── dtostrf.h │ │ │ ├── interrupt.h │ │ │ └── pgmspace.h │ ├── deprecated │ │ ├── Client.h │ │ ├── HardwareSerial.h │ │ ├── IPAddress.h │ │ ├── Print.h │ │ ├── Printable.h │ │ ├── Server.h │ │ ├── Stream.h │ │ ├── Udp.h │ │ └── WString.h │ └── itoa.h │ ├── hal │ ├── wch-hal-i2c.c │ └── wch-hal-i2c.h │ ├── main.cpp │ ├── wiring.c │ ├── wiring_digital.cpp │ └── wiring_private.h ├── examples ├── CH32V003-Blink │ └── CH32V003-Blink.ino ├── CH32V003-DigitalRead │ └── CH32V003-DigitalRead.ino ├── CH32V003-I2C-1 │ └── CH32V003-I2C-1.ino └── CH32V003-USART │ └── CH32V003-USART.ino ├── libraries └── Wire │ ├── library.properties │ └── src │ └── Wire.h ├── platform.txt ├── programmers.txt └── variants └── CH32V003 ├── cflags.txt ├── includes.txt ├── ldflags.txt └── pins_arduino.h /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | tags: 4 | - 'v*' 5 | 6 | name: Create Release 7 | 8 | jobs: 9 | release: 10 | name: Create Release 11 | runs-on: ubuntu-latest 12 | permissions: 13 | contents: write 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Extract Tag 17 | id: get_tag 18 | run: echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT 19 | - name: Set filenames 20 | id: filenames 21 | run: | 22 | echo "bundle=arduino-wch32v003-${{steps.get_tag.outputs.tag}}.tar.gz" >> $GITHUB_OUTPUT 23 | echo "sha=arduino-wch32v003-${{steps.get_tag.outputs.tag}}.tar.gz.sha" >> $GITHUB_OUTPUT 24 | - name: Create Arduino Distribution 25 | run: | 26 | set -x 27 | # Fetch submodules 28 | git submodule update --init 29 | 30 | # Copy ch32v003 sources and remove submodule 31 | cp -r ch32v003fun/ch32v003fun cores/arduino 32 | rm -rf ch32v003fun 33 | 34 | # Create bundle 35 | NAME="arduino_wch32v003_${{steps.get_tag.outputs.tag}}" 36 | mkdir "/tmp/$NAME" 37 | cp -r * "/tmp/$NAME" 38 | mv "/tmp/$NAME" . 39 | 40 | # Cleanup 41 | find "$NAME" -name '.git*' -exec rm -rv {} \; || true 42 | 43 | tar -czf ${{steps.filenames.outputs.bundle}} "$NAME" 44 | sha256sum ${{steps.filenames.outputs.bundle}} > ${{steps.filenames.outputs.sha}} 45 | - name: Create Release 46 | id: create_release 47 | uses: softprops/action-gh-release@v1 48 | with: 49 | tag_name: ${{steps.get_tag.outputs.tag}} 50 | body: | 51 | **Arduino Core for CH32V003** 52 | 53 | `${{steps.filenames.outputs.bundle}}` contains the bundle file used for the board manager inside Arduino IDE. 54 | draft: true 55 | prerelease: true 56 | files: | 57 | ${{steps.filenames.outputs.bundle}} 58 | ${{steps.filenames.outputs.sha}} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | CMakeLists.txt 2 | cmake-build-debug 3 | .idea/ 4 | .vscode/ 5 | examples/**/build 6 | 7 | # Copied by script 8 | cores/arduino/ch32v003fun -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ch32v003fun"] 2 | path = ch32v003fun 3 | url = https://github.com/cnlohr/ch32v003fun 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.] 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | 474 | Copyright (C) 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 489 | USA 490 | 491 | Also add information on how to contact you by electronic and paper mail. 492 | 493 | You should also get your employer (if you work as a programmer) or your 494 | school, if any, to sign a "copyright disclaimer" for the library, if 495 | necessary. Here is a sample; alter the names: 496 | 497 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 498 | library `Frob' (a library for tweaking knobs) written by James Random 499 | Hacker. 500 | 501 | , 1 April 1990 502 | Ty Coon, President of Vice 503 | 504 | That's all there is to it! -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arduino Core for CH32V003 2 | 3 | This is a new Arduino Core for the CH32V003 series of microcontrollers. 4 | 5 | It is based on the work from [CNLohr/ch32v003fun](https://github.com/CNLohr/ch32v003fun). 6 | 7 | 8 | ## Overview 9 | CH32V003 series is based on QingKe RISC-V2A core design of industrial-grade general-purpose microcontroller, support 48MHz system main frequency, with wide voltage, 1-wire serial debug interface, low-power consumption, ultra-small package, etc. CH32V003 series built-in a group of DMA controller, a group of 10-bit ADC, a group of op-amp comparators, multiple timers and standard communication interfaces USART, I2C, SPI, etc. 10 | 11 | ## System Block Diagram 12 | frame 13 | 14 | ### Features 15 | - QingKe 32-bit RISC-V2A processor, supporting 2 levels of interrupt nesting 16 | - Maximum 48MHz system main frequency 17 | - 2KB SRAM, 16KB Flash 18 | - Power supply voltage: 3.3/5V 19 | - Multiple low-power modes: Sleep, Standby 20 | - Power on/off reset, programmable voltage detector 21 | - 1 group of 1-channel general-purpose DMA controller 22 | - 1 group of op-amp comparator 23 | - 1 group of 10-bit ADC 24 | - 1×16-bit advanced-control timer, 1×16-bit general-purpose timer 25 | - 2 WDOG, 1×32-bit SysTick 26 | - 1 USART interface, 1 group of I2C interface, 1 group of SPI interface 27 | - 18 I/O ports, mapping an external interrupt 28 | - 64-bit chip unique ID 29 | - 1-wire serial debug interface (SDI) 30 | - Package: TSSOP20, QFN20, SOP16, SOP8 31 | 32 | ## Installation 33 | 34 | Use the following board manager URL under Preferences → Additional Board Manager URLs to install the core: 35 | 36 | https://alexandermandera.github.io/arduino-wch32v003/package_ch32v003_index.json 37 | 38 | Install the "WCH Boards" platform inside the Board Manager. 39 | 40 | For Windows users that use the WCH-LinkE programmers, follow the additional steps in the [Wiki](https://github.com/AlexanderMandera/arduino-wch32v003/wiki/Additional-Installation-Steps). 41 | 42 | ## State of Development 43 | 44 | This core is currently in development and is not prepared to handle 45 | every aspect that Arduino Core provides. Several peripheral implementations 46 | are work-in-progress but examples from `ch32v003fun` can always be used inside the Arduino IDE. 47 | 48 | All major operating systems (Windows, Linux, macOS) for most CPU architectures (amd64, arm64, armhf) 49 | should be supported. 50 | 51 | The version of the Arduino Board Manager package will be updated after major additions or changes 52 | to the Core which will correspond to the `master` branch. 53 | Pre-release or untested changes are made inside the `develop` branch. 54 | 55 | **What does work:** 56 | * `delay`/`delayMicroseconds` 57 | * `millis()` / `micros()` (untested) 58 | * Digital IO: `pinMode`/`digitalWrite`/`digitalRead` 59 | * USART implementation 60 | * I2C Implementation (w/o Wire implementation) 61 | 62 | **Work in Progress:** 63 | * I2C `Wire.h` implementation 64 | 65 | **To be Done:** 66 | * Optimization 67 | * Several peripherals (ADC, SPI...) 68 | * and much more... 69 | 70 | ## Licensing and Credits 71 | 72 | Thanks to the following projects that make this project possible: 73 | 74 | * [`ArduinoCore-API`](https://github.com/arduino/ArduinoCore-API) by the Arduino Team is licensed under the LGPL-2.1 License 75 | * [`CH32V003 SDK`](https://github.com/openwch/ch32v003) by OpenWCH is used as a reference (and for information inside this README). 76 | * [`ch32v003fun`](https://github.com/cnlohr/ch32v003fun) by CNLohr is used for the basic toolchain, bootstrap code and flashing utility. 77 | * [`ArduinoCore-ch58x`](https://github.com/ElectronicCats/arduino-wch58x) by Electronic Cats as a reference on how to create an Arduino Core for WCH platform. 78 | -------------------------------------------------------------------------------- /boards.txt: -------------------------------------------------------------------------------- 1 | wch32v003.name=CH32V003 2 | wch32v003.build.core=arduino 3 | wch32v003.build.crossprefix=riscv-none-elf- 4 | wch32v003.build.variant=CH32V003 5 | wch32v003.build.mcu=rv32ec 6 | wch32v003.build.extra_flags= 7 | wch32v003.build.architecture=rv32ec 8 | wch32v003.build.board=CH32V003 9 | wch32v003.build.ldscript={build.core.path}/ch32v003fun/ch32v003fun.ld 10 | wch32v003.compiler.wch.arch.define=-DARDUINO_ARCH_WCH32V003 11 | wch32v003.compiler.wch.includes={build.variant.path}/includes.txt 12 | wch32v003.upload.tool=minichlink -------------------------------------------------------------------------------- /cores/arduino/Arduino.h: -------------------------------------------------------------------------------- 1 | /* 2 | Arduino.h - Main include file for the Arduino SDK 3 | Copyright (c) 2005-2013 Arduino Team. All right reserved. 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public 13 | License along with this library; if not, write to the Free Software 14 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 15 | */ 16 | 17 | #if !defined(Arduino_h) 18 | #define Arduino_h 19 | 20 | #define SYSTEM_CORE_CLOCK 48000000 21 | #define APB_CLOCK SYSTEM_CORE_CLOCK 22 | #define SYSTICK_USE_HCLK 23 | 24 | #include "api/ArduinoAPI.h" 25 | #include 26 | #include "ch32v003fun.h" 27 | 28 | #ifndef _NOP 29 | #define _NOP() do { __asm__ volatile ("nop"); } while (0) 30 | #endif 31 | 32 | // undefine stdlib's abs if encountered 33 | #ifdef abs 34 | #undef abs 35 | #endif // abs 36 | #define abs(x) ((x)>0?(x):-(x)) 37 | 38 | #define interrupts() PFIC_EnableAllIRQ() 39 | #define noInterrupts() PFIC_DisableAllIRQ() 40 | 41 | // AVR compatibility macros...naughty and accesses the HW directly 42 | #define digitalPinToPort(pin) (0) 43 | #define digitalPinToBitMask(pin) (1UL << (pin)) 44 | #define digitalPinToTimer(pin) (0) 45 | #define digitalPinToInterrupt(pin) (pin) 46 | #define NOT_AN_INTERRUPT (-1) 47 | #define portOutputRegister(port) ((volatile uint32_t*) sio_hw->gpio_out) 48 | #define portInputRegister(port) ((volatile uint32_t*) sio_hw->gpio_in) 49 | #define portModeRegister(port) ((volatile uint32_t*) sio_hw->gpio_oe) 50 | 51 | // We provide analogReadResolution and analogWriteResolution APIs 52 | void analogReadResolution(int bits); 53 | void analogWriteResolution(int bits); 54 | 55 | #endif -------------------------------------------------------------------------------- /cores/arduino/api/ArduinoAPI.h: -------------------------------------------------------------------------------- 1 | /* 2 | Arduino API main include 3 | Copyright (c) 2016 Arduino LLC. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef ARDUINO_API_H 21 | #define ARDUINO_API_H 22 | 23 | // version 1.3.0 24 | #define ARDUINO_API_VERSION 10300 25 | 26 | #include "Binary.h" 27 | 28 | #ifdef __cplusplus 29 | #include "Interrupts.h" 30 | #include "IPAddress.h" 31 | #include "Print.h" 32 | #include "Printable.h" 33 | #include "Server.h" 34 | #include "String.h" 35 | #include "Stream.h" 36 | #include "Udp.h" 37 | #include "WCharacter.h" 38 | #include "HardwareSerial.h" 39 | #endif 40 | 41 | /* Standard C library includes */ 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | // Misc Arduino core functions 49 | #include "Common.h" 50 | 51 | #ifdef __cplusplus 52 | // Compatibility layer for older code 53 | #include "Compat.h" 54 | #endif 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /cores/arduino/api/Binary.h: -------------------------------------------------------------------------------- 1 | /* 2 | binary.h - Definitions for binary constants 3 | Deprecated -- use 0b binary literals instead 4 | Copyright (c) 2006 David A. Mellis. All right reserved. 5 | 6 | This library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | This library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with this library; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef Binary_h 22 | #define Binary_h 23 | 24 | /* If supported, 0b binary literals are preferable to these constants. 25 | * In that case, warn the user about these being deprecated (if possible). */ 26 | #if __cplusplus >= 201402L 27 | /* C++14 introduces binary literals; C++11 introduces [[deprecated()]] */ 28 | #define DEPRECATED(x) [[deprecated("use " #x " instead")]] 29 | #elif __GNUC__ >= 6 30 | /* GCC 4.3 supports binary literals; GCC 6 supports __deprecated__ on enums*/ 31 | #define DEPRECATED(x) __attribute__ ((__deprecated__ ("use " #x " instead"))) 32 | #else 33 | /* binary literals not supported, or "deprecated" warning not displayable */ 34 | #define DEPRECATED(x) 35 | #endif 36 | 37 | enum { 38 | B0 DEPRECATED(0b0 ) = 0, 39 | B00 DEPRECATED(0b00 ) = 0, 40 | B000 DEPRECATED(0b000 ) = 0, 41 | B0000 DEPRECATED(0b0000 ) = 0, 42 | B00000 DEPRECATED(0b00000 ) = 0, 43 | B000000 DEPRECATED(0b000000 ) = 0, 44 | B0000000 DEPRECATED(0b0000000 ) = 0, 45 | B00000000 DEPRECATED(0b00000000) = 0, 46 | B1 DEPRECATED(0b1 ) = 1, 47 | B01 DEPRECATED(0b01 ) = 1, 48 | B001 DEPRECATED(0b001 ) = 1, 49 | B0001 DEPRECATED(0b0001 ) = 1, 50 | B00001 DEPRECATED(0b00001 ) = 1, 51 | B000001 DEPRECATED(0b000001 ) = 1, 52 | B0000001 DEPRECATED(0b0000001 ) = 1, 53 | B00000001 DEPRECATED(0b00000001) = 1, 54 | B10 DEPRECATED(0b10 ) = 2, 55 | B010 DEPRECATED(0b010 ) = 2, 56 | B0010 DEPRECATED(0b0010 ) = 2, 57 | B00010 DEPRECATED(0b00010 ) = 2, 58 | B000010 DEPRECATED(0b000010 ) = 2, 59 | B0000010 DEPRECATED(0b0000010 ) = 2, 60 | B00000010 DEPRECATED(0b00000010) = 2, 61 | B11 DEPRECATED(0b11 ) = 3, 62 | B011 DEPRECATED(0b011 ) = 3, 63 | B0011 DEPRECATED(0b0011 ) = 3, 64 | B00011 DEPRECATED(0b00011 ) = 3, 65 | B000011 DEPRECATED(0b000011 ) = 3, 66 | B0000011 DEPRECATED(0b0000011 ) = 3, 67 | B00000011 DEPRECATED(0b00000011) = 3, 68 | B100 DEPRECATED(0b100 ) = 4, 69 | B0100 DEPRECATED(0b0100 ) = 4, 70 | B00100 DEPRECATED(0b00100 ) = 4, 71 | B000100 DEPRECATED(0b000100 ) = 4, 72 | B0000100 DEPRECATED(0b0000100 ) = 4, 73 | B00000100 DEPRECATED(0b00000100) = 4, 74 | B101 DEPRECATED(0b101 ) = 5, 75 | B0101 DEPRECATED(0b0101 ) = 5, 76 | B00101 DEPRECATED(0b00101 ) = 5, 77 | B000101 DEPRECATED(0b000101 ) = 5, 78 | B0000101 DEPRECATED(0b0000101 ) = 5, 79 | B00000101 DEPRECATED(0b00000101) = 5, 80 | B110 DEPRECATED(0b110 ) = 6, 81 | B0110 DEPRECATED(0b0110 ) = 6, 82 | B00110 DEPRECATED(0b00110 ) = 6, 83 | B000110 DEPRECATED(0b000110 ) = 6, 84 | B0000110 DEPRECATED(0b0000110 ) = 6, 85 | B00000110 DEPRECATED(0b00000110) = 6, 86 | B111 DEPRECATED(0b111 ) = 7, 87 | B0111 DEPRECATED(0b0111 ) = 7, 88 | B00111 DEPRECATED(0b00111 ) = 7, 89 | B000111 DEPRECATED(0b000111 ) = 7, 90 | B0000111 DEPRECATED(0b0000111 ) = 7, 91 | B00000111 DEPRECATED(0b00000111) = 7, 92 | B1000 DEPRECATED(0b1000 ) = 8, 93 | B01000 DEPRECATED(0b01000 ) = 8, 94 | B001000 DEPRECATED(0b001000 ) = 8, 95 | B0001000 DEPRECATED(0b0001000 ) = 8, 96 | B00001000 DEPRECATED(0b00001000) = 8, 97 | B1001 DEPRECATED(0b1001 ) = 9, 98 | B01001 DEPRECATED(0b01001 ) = 9, 99 | B001001 DEPRECATED(0b001001 ) = 9, 100 | B0001001 DEPRECATED(0b0001001 ) = 9, 101 | B00001001 DEPRECATED(0b00001001) = 9, 102 | B1010 DEPRECATED(0b1010 ) = 10, 103 | B01010 DEPRECATED(0b01010 ) = 10, 104 | B001010 DEPRECATED(0b001010 ) = 10, 105 | B0001010 DEPRECATED(0b0001010 ) = 10, 106 | B00001010 DEPRECATED(0b00001010) = 10, 107 | B1011 DEPRECATED(0b1011 ) = 11, 108 | B01011 DEPRECATED(0b01011 ) = 11, 109 | B001011 DEPRECATED(0b001011 ) = 11, 110 | B0001011 DEPRECATED(0b0001011 ) = 11, 111 | B00001011 DEPRECATED(0b00001011) = 11, 112 | B1100 DEPRECATED(0b1100 ) = 12, 113 | B01100 DEPRECATED(0b01100 ) = 12, 114 | B001100 DEPRECATED(0b001100 ) = 12, 115 | B0001100 DEPRECATED(0b0001100 ) = 12, 116 | B00001100 DEPRECATED(0b00001100) = 12, 117 | B1101 DEPRECATED(0b1101 ) = 13, 118 | B01101 DEPRECATED(0b01101 ) = 13, 119 | B001101 DEPRECATED(0b001101 ) = 13, 120 | B0001101 DEPRECATED(0b0001101 ) = 13, 121 | B00001101 DEPRECATED(0b00001101) = 13, 122 | B1110 DEPRECATED(0b1110 ) = 14, 123 | B01110 DEPRECATED(0b01110 ) = 14, 124 | B001110 DEPRECATED(0b001110 ) = 14, 125 | B0001110 DEPRECATED(0b0001110 ) = 14, 126 | B00001110 DEPRECATED(0b00001110) = 14, 127 | B1111 DEPRECATED(0b1111 ) = 15, 128 | B01111 DEPRECATED(0b01111 ) = 15, 129 | B001111 DEPRECATED(0b001111 ) = 15, 130 | B0001111 DEPRECATED(0b0001111 ) = 15, 131 | B00001111 DEPRECATED(0b00001111) = 15, 132 | B10000 DEPRECATED(0b10000 ) = 16, 133 | B010000 DEPRECATED(0b010000 ) = 16, 134 | B0010000 DEPRECATED(0b0010000 ) = 16, 135 | B00010000 DEPRECATED(0b00010000) = 16, 136 | B10001 DEPRECATED(0b10001 ) = 17, 137 | B010001 DEPRECATED(0b010001 ) = 17, 138 | B0010001 DEPRECATED(0b0010001 ) = 17, 139 | B00010001 DEPRECATED(0b00010001) = 17, 140 | B10010 DEPRECATED(0b10010 ) = 18, 141 | B010010 DEPRECATED(0b010010 ) = 18, 142 | B0010010 DEPRECATED(0b0010010 ) = 18, 143 | B00010010 DEPRECATED(0b00010010) = 18, 144 | B10011 DEPRECATED(0b10011 ) = 19, 145 | B010011 DEPRECATED(0b010011 ) = 19, 146 | B0010011 DEPRECATED(0b0010011 ) = 19, 147 | B00010011 DEPRECATED(0b00010011) = 19, 148 | B10100 DEPRECATED(0b10100 ) = 20, 149 | B010100 DEPRECATED(0b010100 ) = 20, 150 | B0010100 DEPRECATED(0b0010100 ) = 20, 151 | B00010100 DEPRECATED(0b00010100) = 20, 152 | B10101 DEPRECATED(0b10101 ) = 21, 153 | B010101 DEPRECATED(0b010101 ) = 21, 154 | B0010101 DEPRECATED(0b0010101 ) = 21, 155 | B00010101 DEPRECATED(0b00010101) = 21, 156 | B10110 DEPRECATED(0b10110 ) = 22, 157 | B010110 DEPRECATED(0b010110 ) = 22, 158 | B0010110 DEPRECATED(0b0010110 ) = 22, 159 | B00010110 DEPRECATED(0b00010110) = 22, 160 | B10111 DEPRECATED(0b10111 ) = 23, 161 | B010111 DEPRECATED(0b010111 ) = 23, 162 | B0010111 DEPRECATED(0b0010111 ) = 23, 163 | B00010111 DEPRECATED(0b00010111) = 23, 164 | B11000 DEPRECATED(0b11000 ) = 24, 165 | B011000 DEPRECATED(0b011000 ) = 24, 166 | B0011000 DEPRECATED(0b0011000 ) = 24, 167 | B00011000 DEPRECATED(0b00011000) = 24, 168 | B11001 DEPRECATED(0b11001 ) = 25, 169 | B011001 DEPRECATED(0b011001 ) = 25, 170 | B0011001 DEPRECATED(0b0011001 ) = 25, 171 | B00011001 DEPRECATED(0b00011001) = 25, 172 | B11010 DEPRECATED(0b11010 ) = 26, 173 | B011010 DEPRECATED(0b011010 ) = 26, 174 | B0011010 DEPRECATED(0b0011010 ) = 26, 175 | B00011010 DEPRECATED(0b00011010) = 26, 176 | B11011 DEPRECATED(0b11011 ) = 27, 177 | B011011 DEPRECATED(0b011011 ) = 27, 178 | B0011011 DEPRECATED(0b0011011 ) = 27, 179 | B00011011 DEPRECATED(0b00011011) = 27, 180 | B11100 DEPRECATED(0b11100 ) = 28, 181 | B011100 DEPRECATED(0b011100 ) = 28, 182 | B0011100 DEPRECATED(0b0011100 ) = 28, 183 | B00011100 DEPRECATED(0b00011100) = 28, 184 | B11101 DEPRECATED(0b11101 ) = 29, 185 | B011101 DEPRECATED(0b011101 ) = 29, 186 | B0011101 DEPRECATED(0b0011101 ) = 29, 187 | B00011101 DEPRECATED(0b00011101) = 29, 188 | B11110 DEPRECATED(0b11110 ) = 30, 189 | B011110 DEPRECATED(0b011110 ) = 30, 190 | B0011110 DEPRECATED(0b0011110 ) = 30, 191 | B00011110 DEPRECATED(0b00011110) = 30, 192 | B11111 DEPRECATED(0b11111 ) = 31, 193 | B011111 DEPRECATED(0b011111 ) = 31, 194 | B0011111 DEPRECATED(0b0011111 ) = 31, 195 | B00011111 DEPRECATED(0b00011111) = 31, 196 | B100000 DEPRECATED(0b100000 ) = 32, 197 | B0100000 DEPRECATED(0b0100000 ) = 32, 198 | B00100000 DEPRECATED(0b00100000) = 32, 199 | B100001 DEPRECATED(0b100001 ) = 33, 200 | B0100001 DEPRECATED(0b0100001 ) = 33, 201 | B00100001 DEPRECATED(0b00100001) = 33, 202 | B100010 DEPRECATED(0b100010 ) = 34, 203 | B0100010 DEPRECATED(0b0100010 ) = 34, 204 | B00100010 DEPRECATED(0b00100010) = 34, 205 | B100011 DEPRECATED(0b100011 ) = 35, 206 | B0100011 DEPRECATED(0b0100011 ) = 35, 207 | B00100011 DEPRECATED(0b00100011) = 35, 208 | B100100 DEPRECATED(0b100100 ) = 36, 209 | B0100100 DEPRECATED(0b0100100 ) = 36, 210 | B00100100 DEPRECATED(0b00100100) = 36, 211 | B100101 DEPRECATED(0b100101 ) = 37, 212 | B0100101 DEPRECATED(0b0100101 ) = 37, 213 | B00100101 DEPRECATED(0b00100101) = 37, 214 | B100110 DEPRECATED(0b100110 ) = 38, 215 | B0100110 DEPRECATED(0b0100110 ) = 38, 216 | B00100110 DEPRECATED(0b00100110) = 38, 217 | B100111 DEPRECATED(0b100111 ) = 39, 218 | B0100111 DEPRECATED(0b0100111 ) = 39, 219 | B00100111 DEPRECATED(0b00100111) = 39, 220 | B101000 DEPRECATED(0b101000 ) = 40, 221 | B0101000 DEPRECATED(0b0101000 ) = 40, 222 | B00101000 DEPRECATED(0b00101000) = 40, 223 | B101001 DEPRECATED(0b101001 ) = 41, 224 | B0101001 DEPRECATED(0b0101001 ) = 41, 225 | B00101001 DEPRECATED(0b00101001) = 41, 226 | B101010 DEPRECATED(0b101010 ) = 42, 227 | B0101010 DEPRECATED(0b0101010 ) = 42, 228 | B00101010 DEPRECATED(0b00101010) = 42, 229 | B101011 DEPRECATED(0b101011 ) = 43, 230 | B0101011 DEPRECATED(0b0101011 ) = 43, 231 | B00101011 DEPRECATED(0b00101011) = 43, 232 | B101100 DEPRECATED(0b101100 ) = 44, 233 | B0101100 DEPRECATED(0b0101100 ) = 44, 234 | B00101100 DEPRECATED(0b00101100) = 44, 235 | B101101 DEPRECATED(0b101101 ) = 45, 236 | B0101101 DEPRECATED(0b0101101 ) = 45, 237 | B00101101 DEPRECATED(0b00101101) = 45, 238 | B101110 DEPRECATED(0b101110 ) = 46, 239 | B0101110 DEPRECATED(0b0101110 ) = 46, 240 | B00101110 DEPRECATED(0b00101110) = 46, 241 | B101111 DEPRECATED(0b101111 ) = 47, 242 | B0101111 DEPRECATED(0b0101111 ) = 47, 243 | B00101111 DEPRECATED(0b00101111) = 47, 244 | B110000 DEPRECATED(0b110000 ) = 48, 245 | B0110000 DEPRECATED(0b0110000 ) = 48, 246 | B00110000 DEPRECATED(0b00110000) = 48, 247 | B110001 DEPRECATED(0b110001 ) = 49, 248 | B0110001 DEPRECATED(0b0110001 ) = 49, 249 | B00110001 DEPRECATED(0b00110001) = 49, 250 | B110010 DEPRECATED(0b110010 ) = 50, 251 | B0110010 DEPRECATED(0b0110010 ) = 50, 252 | B00110010 DEPRECATED(0b00110010) = 50, 253 | B110011 DEPRECATED(0b110011 ) = 51, 254 | B0110011 DEPRECATED(0b0110011 ) = 51, 255 | B00110011 DEPRECATED(0b00110011) = 51, 256 | B110100 DEPRECATED(0b110100 ) = 52, 257 | B0110100 DEPRECATED(0b0110100 ) = 52, 258 | B00110100 DEPRECATED(0b00110100) = 52, 259 | B110101 DEPRECATED(0b110101 ) = 53, 260 | B0110101 DEPRECATED(0b0110101 ) = 53, 261 | B00110101 DEPRECATED(0b00110101) = 53, 262 | B110110 DEPRECATED(0b110110 ) = 54, 263 | B0110110 DEPRECATED(0b0110110 ) = 54, 264 | B00110110 DEPRECATED(0b00110110) = 54, 265 | B110111 DEPRECATED(0b110111 ) = 55, 266 | B0110111 DEPRECATED(0b0110111 ) = 55, 267 | B00110111 DEPRECATED(0b00110111) = 55, 268 | B111000 DEPRECATED(0b111000 ) = 56, 269 | B0111000 DEPRECATED(0b0111000 ) = 56, 270 | B00111000 DEPRECATED(0b00111000) = 56, 271 | B111001 DEPRECATED(0b111001 ) = 57, 272 | B0111001 DEPRECATED(0b0111001 ) = 57, 273 | B00111001 DEPRECATED(0b00111001) = 57, 274 | B111010 DEPRECATED(0b111010 ) = 58, 275 | B0111010 DEPRECATED(0b0111010 ) = 58, 276 | B00111010 DEPRECATED(0b00111010) = 58, 277 | B111011 DEPRECATED(0b111011 ) = 59, 278 | B0111011 DEPRECATED(0b0111011 ) = 59, 279 | B00111011 DEPRECATED(0b00111011) = 59, 280 | B111100 DEPRECATED(0b111100 ) = 60, 281 | B0111100 DEPRECATED(0b0111100 ) = 60, 282 | B00111100 DEPRECATED(0b00111100) = 60, 283 | B111101 DEPRECATED(0b111101 ) = 61, 284 | B0111101 DEPRECATED(0b0111101 ) = 61, 285 | B00111101 DEPRECATED(0b00111101) = 61, 286 | B111110 DEPRECATED(0b111110 ) = 62, 287 | B0111110 DEPRECATED(0b0111110 ) = 62, 288 | B00111110 DEPRECATED(0b00111110) = 62, 289 | B111111 DEPRECATED(0b111111 ) = 63, 290 | B0111111 DEPRECATED(0b0111111 ) = 63, 291 | B00111111 DEPRECATED(0b00111111) = 63, 292 | B1000000 DEPRECATED(0b1000000 ) = 64, 293 | B01000000 DEPRECATED(0b01000000) = 64, 294 | B1000001 DEPRECATED(0b1000001 ) = 65, 295 | B01000001 DEPRECATED(0b01000001) = 65, 296 | B1000010 DEPRECATED(0b1000010 ) = 66, 297 | B01000010 DEPRECATED(0b01000010) = 66, 298 | B1000011 DEPRECATED(0b1000011 ) = 67, 299 | B01000011 DEPRECATED(0b01000011) = 67, 300 | B1000100 DEPRECATED(0b1000100 ) = 68, 301 | B01000100 DEPRECATED(0b01000100) = 68, 302 | B1000101 DEPRECATED(0b1000101 ) = 69, 303 | B01000101 DEPRECATED(0b01000101) = 69, 304 | B1000110 DEPRECATED(0b1000110 ) = 70, 305 | B01000110 DEPRECATED(0b01000110) = 70, 306 | B1000111 DEPRECATED(0b1000111 ) = 71, 307 | B01000111 DEPRECATED(0b01000111) = 71, 308 | B1001000 DEPRECATED(0b1001000 ) = 72, 309 | B01001000 DEPRECATED(0b01001000) = 72, 310 | B1001001 DEPRECATED(0b1001001 ) = 73, 311 | B01001001 DEPRECATED(0b01001001) = 73, 312 | B1001010 DEPRECATED(0b1001010 ) = 74, 313 | B01001010 DEPRECATED(0b01001010) = 74, 314 | B1001011 DEPRECATED(0b1001011 ) = 75, 315 | B01001011 DEPRECATED(0b01001011) = 75, 316 | B1001100 DEPRECATED(0b1001100 ) = 76, 317 | B01001100 DEPRECATED(0b01001100) = 76, 318 | B1001101 DEPRECATED(0b1001101 ) = 77, 319 | B01001101 DEPRECATED(0b01001101) = 77, 320 | B1001110 DEPRECATED(0b1001110 ) = 78, 321 | B01001110 DEPRECATED(0b01001110) = 78, 322 | B1001111 DEPRECATED(0b1001111 ) = 79, 323 | B01001111 DEPRECATED(0b01001111) = 79, 324 | B1010000 DEPRECATED(0b1010000 ) = 80, 325 | B01010000 DEPRECATED(0b01010000) = 80, 326 | B1010001 DEPRECATED(0b1010001 ) = 81, 327 | B01010001 DEPRECATED(0b01010001) = 81, 328 | B1010010 DEPRECATED(0b1010010 ) = 82, 329 | B01010010 DEPRECATED(0b01010010) = 82, 330 | B1010011 DEPRECATED(0b1010011 ) = 83, 331 | B01010011 DEPRECATED(0b01010011) = 83, 332 | B1010100 DEPRECATED(0b1010100 ) = 84, 333 | B01010100 DEPRECATED(0b01010100) = 84, 334 | B1010101 DEPRECATED(0b1010101 ) = 85, 335 | B01010101 DEPRECATED(0b01010101) = 85, 336 | B1010110 DEPRECATED(0b1010110 ) = 86, 337 | B01010110 DEPRECATED(0b01010110) = 86, 338 | B1010111 DEPRECATED(0b1010111 ) = 87, 339 | B01010111 DEPRECATED(0b01010111) = 87, 340 | B1011000 DEPRECATED(0b1011000 ) = 88, 341 | B01011000 DEPRECATED(0b01011000) = 88, 342 | B1011001 DEPRECATED(0b1011001 ) = 89, 343 | B01011001 DEPRECATED(0b01011001) = 89, 344 | B1011010 DEPRECATED(0b1011010 ) = 90, 345 | B01011010 DEPRECATED(0b01011010) = 90, 346 | B1011011 DEPRECATED(0b1011011 ) = 91, 347 | B01011011 DEPRECATED(0b01011011) = 91, 348 | B1011100 DEPRECATED(0b1011100 ) = 92, 349 | B01011100 DEPRECATED(0b01011100) = 92, 350 | B1011101 DEPRECATED(0b1011101 ) = 93, 351 | B01011101 DEPRECATED(0b01011101) = 93, 352 | B1011110 DEPRECATED(0b1011110 ) = 94, 353 | B01011110 DEPRECATED(0b01011110) = 94, 354 | B1011111 DEPRECATED(0b1011111 ) = 95, 355 | B01011111 DEPRECATED(0b01011111) = 95, 356 | B1100000 DEPRECATED(0b1100000 ) = 96, 357 | B01100000 DEPRECATED(0b01100000) = 96, 358 | B1100001 DEPRECATED(0b1100001 ) = 97, 359 | B01100001 DEPRECATED(0b01100001) = 97, 360 | B1100010 DEPRECATED(0b1100010 ) = 98, 361 | B01100010 DEPRECATED(0b01100010) = 98, 362 | B1100011 DEPRECATED(0b1100011 ) = 99, 363 | B01100011 DEPRECATED(0b01100011) = 99, 364 | B1100100 DEPRECATED(0b1100100 ) = 100, 365 | B01100100 DEPRECATED(0b01100100) = 100, 366 | B1100101 DEPRECATED(0b1100101 ) = 101, 367 | B01100101 DEPRECATED(0b01100101) = 101, 368 | B1100110 DEPRECATED(0b1100110 ) = 102, 369 | B01100110 DEPRECATED(0b01100110) = 102, 370 | B1100111 DEPRECATED(0b1100111 ) = 103, 371 | B01100111 DEPRECATED(0b01100111) = 103, 372 | B1101000 DEPRECATED(0b1101000 ) = 104, 373 | B01101000 DEPRECATED(0b01101000) = 104, 374 | B1101001 DEPRECATED(0b1101001 ) = 105, 375 | B01101001 DEPRECATED(0b01101001) = 105, 376 | B1101010 DEPRECATED(0b1101010 ) = 106, 377 | B01101010 DEPRECATED(0b01101010) = 106, 378 | B1101011 DEPRECATED(0b1101011 ) = 107, 379 | B01101011 DEPRECATED(0b01101011) = 107, 380 | B1101100 DEPRECATED(0b1101100 ) = 108, 381 | B01101100 DEPRECATED(0b01101100) = 108, 382 | B1101101 DEPRECATED(0b1101101 ) = 109, 383 | B01101101 DEPRECATED(0b01101101) = 109, 384 | B1101110 DEPRECATED(0b1101110 ) = 110, 385 | B01101110 DEPRECATED(0b01101110) = 110, 386 | B1101111 DEPRECATED(0b1101111 ) = 111, 387 | B01101111 DEPRECATED(0b01101111) = 111, 388 | B1110000 DEPRECATED(0b1110000 ) = 112, 389 | B01110000 DEPRECATED(0b01110000) = 112, 390 | B1110001 DEPRECATED(0b1110001 ) = 113, 391 | B01110001 DEPRECATED(0b01110001) = 113, 392 | B1110010 DEPRECATED(0b1110010 ) = 114, 393 | B01110010 DEPRECATED(0b01110010) = 114, 394 | B1110011 DEPRECATED(0b1110011 ) = 115, 395 | B01110011 DEPRECATED(0b01110011) = 115, 396 | B1110100 DEPRECATED(0b1110100 ) = 116, 397 | B01110100 DEPRECATED(0b01110100) = 116, 398 | B1110101 DEPRECATED(0b1110101 ) = 117, 399 | B01110101 DEPRECATED(0b01110101) = 117, 400 | B1110110 DEPRECATED(0b1110110 ) = 118, 401 | B01110110 DEPRECATED(0b01110110) = 118, 402 | B1110111 DEPRECATED(0b1110111 ) = 119, 403 | B01110111 DEPRECATED(0b01110111) = 119, 404 | B1111000 DEPRECATED(0b1111000 ) = 120, 405 | B01111000 DEPRECATED(0b01111000) = 120, 406 | B1111001 DEPRECATED(0b1111001 ) = 121, 407 | B01111001 DEPRECATED(0b01111001) = 121, 408 | B1111010 DEPRECATED(0b1111010 ) = 122, 409 | B01111010 DEPRECATED(0b01111010) = 122, 410 | B1111011 DEPRECATED(0b1111011 ) = 123, 411 | B01111011 DEPRECATED(0b01111011) = 123, 412 | B1111100 DEPRECATED(0b1111100 ) = 124, 413 | B01111100 DEPRECATED(0b01111100) = 124, 414 | B1111101 DEPRECATED(0b1111101 ) = 125, 415 | B01111101 DEPRECATED(0b01111101) = 125, 416 | B1111110 DEPRECATED(0b1111110 ) = 126, 417 | B01111110 DEPRECATED(0b01111110) = 126, 418 | B1111111 DEPRECATED(0b1111111 ) = 127, 419 | B01111111 DEPRECATED(0b01111111) = 127, 420 | B10000000 DEPRECATED(0b10000000) = 128, 421 | B10000001 DEPRECATED(0b10000001) = 129, 422 | B10000010 DEPRECATED(0b10000010) = 130, 423 | B10000011 DEPRECATED(0b10000011) = 131, 424 | B10000100 DEPRECATED(0b10000100) = 132, 425 | B10000101 DEPRECATED(0b10000101) = 133, 426 | B10000110 DEPRECATED(0b10000110) = 134, 427 | B10000111 DEPRECATED(0b10000111) = 135, 428 | B10001000 DEPRECATED(0b10001000) = 136, 429 | B10001001 DEPRECATED(0b10001001) = 137, 430 | B10001010 DEPRECATED(0b10001010) = 138, 431 | B10001011 DEPRECATED(0b10001011) = 139, 432 | B10001100 DEPRECATED(0b10001100) = 140, 433 | B10001101 DEPRECATED(0b10001101) = 141, 434 | B10001110 DEPRECATED(0b10001110) = 142, 435 | B10001111 DEPRECATED(0b10001111) = 143, 436 | B10010000 DEPRECATED(0b10010000) = 144, 437 | B10010001 DEPRECATED(0b10010001) = 145, 438 | B10010010 DEPRECATED(0b10010010) = 146, 439 | B10010011 DEPRECATED(0b10010011) = 147, 440 | B10010100 DEPRECATED(0b10010100) = 148, 441 | B10010101 DEPRECATED(0b10010101) = 149, 442 | B10010110 DEPRECATED(0b10010110) = 150, 443 | B10010111 DEPRECATED(0b10010111) = 151, 444 | B10011000 DEPRECATED(0b10011000) = 152, 445 | B10011001 DEPRECATED(0b10011001) = 153, 446 | B10011010 DEPRECATED(0b10011010) = 154, 447 | B10011011 DEPRECATED(0b10011011) = 155, 448 | B10011100 DEPRECATED(0b10011100) = 156, 449 | B10011101 DEPRECATED(0b10011101) = 157, 450 | B10011110 DEPRECATED(0b10011110) = 158, 451 | B10011111 DEPRECATED(0b10011111) = 159, 452 | B10100000 DEPRECATED(0b10100000) = 160, 453 | B10100001 DEPRECATED(0b10100001) = 161, 454 | B10100010 DEPRECATED(0b10100010) = 162, 455 | B10100011 DEPRECATED(0b10100011) = 163, 456 | B10100100 DEPRECATED(0b10100100) = 164, 457 | B10100101 DEPRECATED(0b10100101) = 165, 458 | B10100110 DEPRECATED(0b10100110) = 166, 459 | B10100111 DEPRECATED(0b10100111) = 167, 460 | B10101000 DEPRECATED(0b10101000) = 168, 461 | B10101001 DEPRECATED(0b10101001) = 169, 462 | B10101010 DEPRECATED(0b10101010) = 170, 463 | B10101011 DEPRECATED(0b10101011) = 171, 464 | B10101100 DEPRECATED(0b10101100) = 172, 465 | B10101101 DEPRECATED(0b10101101) = 173, 466 | B10101110 DEPRECATED(0b10101110) = 174, 467 | B10101111 DEPRECATED(0b10101111) = 175, 468 | B10110000 DEPRECATED(0b10110000) = 176, 469 | B10110001 DEPRECATED(0b10110001) = 177, 470 | B10110010 DEPRECATED(0b10110010) = 178, 471 | B10110011 DEPRECATED(0b10110011) = 179, 472 | B10110100 DEPRECATED(0b10110100) = 180, 473 | B10110101 DEPRECATED(0b10110101) = 181, 474 | B10110110 DEPRECATED(0b10110110) = 182, 475 | B10110111 DEPRECATED(0b10110111) = 183, 476 | B10111000 DEPRECATED(0b10111000) = 184, 477 | B10111001 DEPRECATED(0b10111001) = 185, 478 | B10111010 DEPRECATED(0b10111010) = 186, 479 | B10111011 DEPRECATED(0b10111011) = 187, 480 | B10111100 DEPRECATED(0b10111100) = 188, 481 | B10111101 DEPRECATED(0b10111101) = 189, 482 | B10111110 DEPRECATED(0b10111110) = 190, 483 | B10111111 DEPRECATED(0b10111111) = 191, 484 | B11000000 DEPRECATED(0b11000000) = 192, 485 | B11000001 DEPRECATED(0b11000001) = 193, 486 | B11000010 DEPRECATED(0b11000010) = 194, 487 | B11000011 DEPRECATED(0b11000011) = 195, 488 | B11000100 DEPRECATED(0b11000100) = 196, 489 | B11000101 DEPRECATED(0b11000101) = 197, 490 | B11000110 DEPRECATED(0b11000110) = 198, 491 | B11000111 DEPRECATED(0b11000111) = 199, 492 | B11001000 DEPRECATED(0b11001000) = 200, 493 | B11001001 DEPRECATED(0b11001001) = 201, 494 | B11001010 DEPRECATED(0b11001010) = 202, 495 | B11001011 DEPRECATED(0b11001011) = 203, 496 | B11001100 DEPRECATED(0b11001100) = 204, 497 | B11001101 DEPRECATED(0b11001101) = 205, 498 | B11001110 DEPRECATED(0b11001110) = 206, 499 | B11001111 DEPRECATED(0b11001111) = 207, 500 | B11010000 DEPRECATED(0b11010000) = 208, 501 | B11010001 DEPRECATED(0b11010001) = 209, 502 | B11010010 DEPRECATED(0b11010010) = 210, 503 | B11010011 DEPRECATED(0b11010011) = 211, 504 | B11010100 DEPRECATED(0b11010100) = 212, 505 | B11010101 DEPRECATED(0b11010101) = 213, 506 | B11010110 DEPRECATED(0b11010110) = 214, 507 | B11010111 DEPRECATED(0b11010111) = 215, 508 | B11011000 DEPRECATED(0b11011000) = 216, 509 | B11011001 DEPRECATED(0b11011001) = 217, 510 | B11011010 DEPRECATED(0b11011010) = 218, 511 | B11011011 DEPRECATED(0b11011011) = 219, 512 | B11011100 DEPRECATED(0b11011100) = 220, 513 | B11011101 DEPRECATED(0b11011101) = 221, 514 | B11011110 DEPRECATED(0b11011110) = 222, 515 | B11011111 DEPRECATED(0b11011111) = 223, 516 | B11100000 DEPRECATED(0b11100000) = 224, 517 | B11100001 DEPRECATED(0b11100001) = 225, 518 | B11100010 DEPRECATED(0b11100010) = 226, 519 | B11100011 DEPRECATED(0b11100011) = 227, 520 | B11100100 DEPRECATED(0b11100100) = 228, 521 | B11100101 DEPRECATED(0b11100101) = 229, 522 | B11100110 DEPRECATED(0b11100110) = 230, 523 | B11100111 DEPRECATED(0b11100111) = 231, 524 | B11101000 DEPRECATED(0b11101000) = 232, 525 | B11101001 DEPRECATED(0b11101001) = 233, 526 | B11101010 DEPRECATED(0b11101010) = 234, 527 | B11101011 DEPRECATED(0b11101011) = 235, 528 | B11101100 DEPRECATED(0b11101100) = 236, 529 | B11101101 DEPRECATED(0b11101101) = 237, 530 | B11101110 DEPRECATED(0b11101110) = 238, 531 | B11101111 DEPRECATED(0b11101111) = 239, 532 | B11110000 DEPRECATED(0b11110000) = 240, 533 | B11110001 DEPRECATED(0b11110001) = 241, 534 | B11110010 DEPRECATED(0b11110010) = 242, 535 | B11110011 DEPRECATED(0b11110011) = 243, 536 | B11110100 DEPRECATED(0b11110100) = 244, 537 | B11110101 DEPRECATED(0b11110101) = 245, 538 | B11110110 DEPRECATED(0b11110110) = 246, 539 | B11110111 DEPRECATED(0b11110111) = 247, 540 | B11111000 DEPRECATED(0b11111000) = 248, 541 | B11111001 DEPRECATED(0b11111001) = 249, 542 | B11111010 DEPRECATED(0b11111010) = 250, 543 | B11111011 DEPRECATED(0b11111011) = 251, 544 | B11111100 DEPRECATED(0b11111100) = 252, 545 | B11111101 DEPRECATED(0b11111101) = 253, 546 | B11111110 DEPRECATED(0b11111110) = 254, 547 | B11111111 DEPRECATED(0b11111111) = 255 548 | }; 549 | 550 | #undef DEPRECATED 551 | 552 | #endif 553 | -------------------------------------------------------------------------------- /cores/arduino/api/Client.h: -------------------------------------------------------------------------------- 1 | /* 2 | Client.h - Base class that provides Client 3 | Copyright (c) 2011 Adrian McEwen. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #pragma once 21 | 22 | #include "Stream.h" 23 | #include "IPAddress.h" 24 | 25 | namespace arduino { 26 | 27 | class Client : public Stream { 28 | 29 | public: 30 | virtual int connect(IPAddress ip, uint16_t port) =0; 31 | virtual int connect(const char *host, uint16_t port) =0; 32 | virtual size_t write(uint8_t) =0; 33 | virtual size_t write(const uint8_t *buf, size_t size) =0; 34 | virtual int available() = 0; 35 | virtual int read() = 0; 36 | virtual int read(uint8_t *buf, size_t size) = 0; 37 | virtual int peek() = 0; 38 | virtual void flush() = 0; 39 | virtual void stop() = 0; 40 | virtual uint8_t connected() = 0; 41 | virtual operator bool() = 0; 42 | protected: 43 | uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; 44 | }; 45 | 46 | } -------------------------------------------------------------------------------- /cores/arduino/api/Common.cpp: -------------------------------------------------------------------------------- 1 | #include "Common.h" 2 | 3 | /* C++ prototypes */ 4 | long map(long x, long in_min, long in_max, long out_min, long out_max) 5 | { 6 | return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; 7 | } 8 | 9 | uint16_t makeWord(uint16_t w) { return w; } 10 | uint16_t makeWord(uint8_t h, uint8_t l) { return (h << 8) | l; } -------------------------------------------------------------------------------- /cores/arduino/api/Common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #ifdef __cplusplus 6 | extern "C"{ 7 | #endif 8 | 9 | void yield(void); 10 | 11 | typedef enum { 12 | LOW = 0, 13 | HIGH = 1, 14 | CHANGE = 2, 15 | FALLING = 3, 16 | RISING = 4, 17 | } PinStatus; 18 | 19 | typedef enum { 20 | INPUT = 0x0, 21 | OUTPUT = 0x1, 22 | INPUT_PULLUP = 0x2, 23 | INPUT_PULLDOWN = 0x3, 24 | OUTPUT_OPENDRAIN = 0x4, 25 | } PinMode; 26 | 27 | typedef enum { 28 | LSBFIRST = 0, 29 | MSBFIRST = 1, 30 | } BitOrder; 31 | 32 | #define PI 3.1415926535897932384626433832795 33 | #define HALF_PI 1.5707963267948966192313216916398 34 | #define TWO_PI 6.283185307179586476925286766559 35 | #define DEG_TO_RAD 0.017453292519943295769236907684886 36 | #define RAD_TO_DEG 57.295779513082320876798154814105 37 | #define EULER 2.718281828459045235360287471352 38 | 39 | #define SERIAL 0x0 40 | #define DISPLAY 0x1 41 | 42 | #ifndef constrain 43 | #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) 44 | #endif 45 | 46 | #ifndef radians 47 | #define radians(deg) ((deg)*DEG_TO_RAD) 48 | #endif 49 | 50 | #ifndef degrees 51 | #define degrees(rad) ((rad)*RAD_TO_DEG) 52 | #endif 53 | 54 | #ifndef sq 55 | #define sq(x) ((x)*(x)) 56 | #endif 57 | 58 | typedef void (*voidFuncPtr)(void); 59 | typedef void (*voidFuncPtrParam)(void*); 60 | 61 | // interrupts() / noInterrupts() must be defined by the core 62 | 63 | #define lowByte(w) ((uint8_t) ((w) & 0xff)) 64 | #define highByte(w) ((uint8_t) ((w) >> 8)) 65 | 66 | #define bitRead(value, bit) (((value) >> (bit)) & 0x01) 67 | #define bitSet(value, bit) ((value) |= (1UL << (bit))) 68 | #define bitClear(value, bit) ((value) &= ~(1UL << (bit))) 69 | #define bitToggle(value, bit) ((value) ^= (1UL << (bit))) 70 | #define bitWrite(value, bit, bitvalue) ((bitvalue) ? bitSet((value), (bit)) : bitClear((value), (bit))) 71 | 72 | #ifndef bit 73 | #define bit(b) (1UL << (b)) 74 | #endif 75 | 76 | /* TODO: request for removal */ 77 | typedef bool boolean; 78 | typedef uint8_t byte; 79 | typedef uint16_t word; 80 | 81 | void init(void); 82 | void initVariant(void); 83 | 84 | #ifndef HOST 85 | int atexit(void (*func)()) __attribute__((weak)); 86 | #endif 87 | int main() __attribute__((weak)); 88 | 89 | #ifdef EXTENDED_PIN_MODE 90 | // Platforms who want to declare more than 256 pins need to define EXTENDED_PIN_MODE globally 91 | typedef uint32_t pin_size_t; 92 | #else 93 | typedef uint8_t pin_size_t; 94 | #endif 95 | 96 | void pinMode(pin_size_t pinNumber, PinMode pinMode); 97 | void digitalWrite(pin_size_t pinNumber, PinStatus status); 98 | PinStatus digitalRead(pin_size_t pinNumber); 99 | int analogRead(pin_size_t pinNumber); 100 | void analogReference(uint8_t mode); 101 | void analogWrite(pin_size_t pinNumber, int value); 102 | 103 | unsigned long millis(void); 104 | unsigned long micros(void); 105 | void delay(unsigned long); 106 | void delayMicroseconds(unsigned int us); 107 | unsigned long pulseIn(pin_size_t pin, uint8_t state, unsigned long timeout); 108 | unsigned long pulseInLong(pin_size_t pin, uint8_t state, unsigned long timeout); 109 | 110 | void shiftOut(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder, uint8_t val); 111 | uint8_t shiftIn(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder); 112 | 113 | void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, PinStatus mode); 114 | void attachInterruptParam(pin_size_t interruptNumber, voidFuncPtrParam callback, PinStatus mode, void* param); 115 | void detachInterrupt(pin_size_t interruptNumber); 116 | 117 | void setup(void); 118 | void loop(void); 119 | 120 | #ifdef __cplusplus 121 | } // extern "C" 122 | #endif 123 | 124 | #ifdef __cplusplus 125 | template 126 | auto min(const T& a, const L& b) -> decltype((b < a) ? b : a) 127 | { 128 | return (b < a) ? b : a; 129 | } 130 | 131 | template 132 | auto max(const T& a, const L& b) -> decltype((b < a) ? b : a) 133 | { 134 | return (a < b) ? b : a; 135 | } 136 | #else 137 | #ifndef min 138 | #define min(a,b) \ 139 | ({ __typeof__ (a) _a = (a); \ 140 | __typeof__ (b) _b = (b); \ 141 | _a < _b ? _a : _b; }) 142 | #endif 143 | #ifndef max 144 | #define max(a,b) \ 145 | ({ __typeof__ (a) _a = (a); \ 146 | __typeof__ (b) _b = (b); \ 147 | _a > _b ? _a : _b; }) 148 | #endif 149 | #endif 150 | 151 | #ifdef __cplusplus 152 | 153 | /* C++ prototypes */ 154 | uint16_t makeWord(uint16_t w); 155 | uint16_t makeWord(byte h, byte l); 156 | 157 | #define word(...) makeWord(__VA_ARGS__) 158 | 159 | unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); 160 | unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); 161 | 162 | void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0); 163 | void noTone(uint8_t _pin); 164 | 165 | // WMath prototypes 166 | long random(long); 167 | long random(long, long); 168 | void randomSeed(unsigned long); 169 | long map(long, long, long, long, long); 170 | 171 | #endif // __cplusplus 172 | -------------------------------------------------------------------------------- /cores/arduino/api/Compat.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMPAT_H__ 2 | #define __COMPAT_H__ 3 | 4 | namespace arduino { 5 | 6 | inline void pinMode(pin_size_t pinNumber, int mode) { 7 | pinMode(pinNumber, (PinMode)mode); 8 | }; 9 | 10 | inline void digitalWrite(pin_size_t pinNumber, int status) { 11 | digitalWrite(pinNumber, (PinStatus)status); 12 | }; 13 | 14 | } 15 | 16 | #endif -------------------------------------------------------------------------------- /cores/arduino/api/HardwareSerial.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ch32v003fun.h" 3 | #include "HardwareSerial.h" 4 | 5 | HardwareSerial Serial; 6 | 7 | extern "C" { 8 | #define RX_BUFFER_SIZE 100 9 | u8 rxBuffer[RX_BUFFER_SIZE] = {0}; 10 | volatile u8 rxBufferHead = 0; 11 | volatile u8 rxBufferTail = 0; 12 | } 13 | 14 | void HardwareSerial::begin(unsigned long baud, uint16_t config) { 15 | // Hardware Serial Pins D5 / D6 16 | RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_USART1; // Enable UART 17 | GPIOD->CFGLR &= ~(0xf<<(4*5)); 18 | GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*5); 19 | 20 | GPIOD->CFGLR &= ~(0xf<<(4*6)); 21 | GPIOD->CFGLR |= (GPIO_CNF_IN_FLOATING)<<(4*6); 22 | 23 | USART1->CTLR1 = USART_WordLength_8b | USART_Parity_No | USART_Mode_Rx | USART_Mode_Tx; 24 | USART1->CTLR2 = USART_StopBits_1; 25 | USART1->CTLR3 = USART_HardwareFlowControl_None; 26 | 27 | // Set Baudrate 28 | uint32_t integerDivider = ((25 * APB_CLOCK)) / (OVER8DIV * baud); 29 | uint32_t fractionalDivider = integerDivider % 100; 30 | 31 | USART1->BRR = ((integerDivider / 100) << 4) | (((fractionalDivider * (OVER8DIV * 2) + 50) / 100) & 7); 32 | 33 | // Enable Interrupt 34 | USART1->CTLR1 |= USART_FLAG_RXNE; 35 | NVIC_EnableIRQ(USART1_IRQn); 36 | 37 | // Enable UART 38 | USART1->CTLR1 |= CTLR1_UE_Set; 39 | } 40 | 41 | void HardwareSerial::begin(unsigned long baud) { 42 | begin(baud, 0); 43 | } 44 | 45 | void HardwareSerial::end() { 46 | USART1->CTLR1 &= CTLR1_UE_Reset; 47 | } 48 | 49 | int HardwareSerial::available() { 50 | return rxBufferTail - rxBufferHead; 51 | } 52 | 53 | int HardwareSerial::peek() { 54 | return rxBuffer[rxBufferHead]; 55 | } 56 | 57 | int HardwareSerial::read() { 58 | if(rxBufferHead == rxBufferTail) return -1; 59 | 60 | uint8_t c = rxBuffer[rxBufferHead]; 61 | 62 | rxBufferHead = (rxBufferHead + 1) % RX_BUFFER_SIZE; 63 | if(rxBufferHead != rxBufferTail) { 64 | USART1->CTLR1 |= USART_FLAG_RXNE; 65 | } 66 | 67 | return c; 68 | } 69 | 70 | void HardwareSerial::flush() { 71 | } 72 | 73 | int HardwareSerial::availableForWrite() { 74 | return USART1->CTLR1 & CTLR1_UE_Set; 75 | } 76 | 77 | size_t HardwareSerial::write(uint8_t c) { 78 | while( !(USART1->STATR & USART_FLAG_TC)); 79 | USART1->DATAR = c; 80 | return 1; 81 | } 82 | 83 | size_t HardwareSerial::write(const uint8_t *buffer, size_t size) 84 | { 85 | size_t n = 0; 86 | while (size--) { 87 | if (write(*buffer++)) n++; 88 | else break; 89 | } 90 | return n; 91 | } 92 | 93 | HardwareSerial::operator bool() { 94 | return availableForWrite(); 95 | } 96 | 97 | // Removed IRQ handler for testing 98 | extern "C" void USART1_IRQHandler( void ) __attribute__((interrupt)); 99 | extern "C" void USART1_IRQHandler(void) { 100 | if(USART1->STATR & USART_FLAG_RXNE) { 101 | // Write into buffer 102 | rxBuffer[rxBufferTail] = USART1->DATAR & (uint16_t)0x01FF; 103 | 104 | rxBufferTail = (rxBufferTail + 1) % RX_BUFFER_SIZE; 105 | 106 | if(rxBufferTail == rxBufferHead) { 107 | // Buffer empty, disable USART interrupt 108 | USART1->CTLR1 &= ~USART_FLAG_RXNE; 109 | return; 110 | } 111 | } 112 | } -------------------------------------------------------------------------------- /cores/arduino/api/HardwareSerial.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | #include "Stream.h" 23 | 24 | // XXX: Those constants should be defined as const int / enums? 25 | // XXX: shall we use namespaces too? 26 | #define SERIAL_PARITY_EVEN (0x1ul) 27 | #define SERIAL_PARITY_ODD (0x2ul) 28 | #define SERIAL_PARITY_NONE (0x3ul) 29 | #define SERIAL_PARITY_MARK (0x4ul) 30 | #define SERIAL_PARITY_SPACE (0x5ul) 31 | #define SERIAL_PARITY_MASK (0xFul) 32 | 33 | #define SERIAL_STOP_BIT_1 (0x10ul) 34 | #define SERIAL_STOP_BIT_1_5 (0x20ul) 35 | #define SERIAL_STOP_BIT_2 (0x30ul) 36 | #define SERIAL_STOP_BIT_MASK (0xF0ul) 37 | 38 | #define SERIAL_DATA_5 (0x100ul) 39 | #define SERIAL_DATA_6 (0x200ul) 40 | #define SERIAL_DATA_7 (0x300ul) 41 | #define SERIAL_DATA_8 (0x400ul) 42 | #define SERIAL_DATA_MASK (0xF00ul) 43 | 44 | #define SERIAL_5N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_5) 45 | #define SERIAL_6N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_6) 46 | #define SERIAL_7N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_7) 47 | #define SERIAL_8N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_8) 48 | #define SERIAL_5N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_5) 49 | #define SERIAL_6N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_6) 50 | #define SERIAL_7N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_7) 51 | #define SERIAL_8N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_8) 52 | #define SERIAL_5E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_5) 53 | #define SERIAL_6E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_6) 54 | #define SERIAL_7E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_7) 55 | #define SERIAL_8E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_8) 56 | #define SERIAL_5E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_5) 57 | #define SERIAL_6E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_6) 58 | #define SERIAL_7E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_7) 59 | #define SERIAL_8E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_8) 60 | #define SERIAL_5O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_5) 61 | #define SERIAL_6O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_6) 62 | #define SERIAL_7O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_7) 63 | #define SERIAL_8O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_8) 64 | #define SERIAL_5O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_5) 65 | #define SERIAL_6O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_6) 66 | #define SERIAL_7O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_7) 67 | #define SERIAL_8O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_8) 68 | #define SERIAL_5M1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_MARK | SERIAL_DATA_5) 69 | #define SERIAL_6M1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_MARK | SERIAL_DATA_6) 70 | #define SERIAL_7M1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_MARK | SERIAL_DATA_7) 71 | #define SERIAL_8M1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_MARK | SERIAL_DATA_8) 72 | #define SERIAL_5M2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_MARK | SERIAL_DATA_5) 73 | #define SERIAL_6M2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_MARK | SERIAL_DATA_6) 74 | #define SERIAL_7M2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_MARK | SERIAL_DATA_7) 75 | #define SERIAL_8M2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_MARK | SERIAL_DATA_8) 76 | #define SERIAL_5S1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_SPACE | SERIAL_DATA_5) 77 | #define SERIAL_6S1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_SPACE | SERIAL_DATA_6) 78 | #define SERIAL_7S1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_SPACE | SERIAL_DATA_7) 79 | #define SERIAL_8S1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_SPACE | SERIAL_DATA_8) 80 | #define SERIAL_5S2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_SPACE | SERIAL_DATA_5) 81 | #define SERIAL_6S2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_SPACE | SERIAL_DATA_6) 82 | #define SERIAL_7S2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_SPACE | SERIAL_DATA_7) 83 | #define SERIAL_8S2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_SPACE | SERIAL_DATA_8) 84 | 85 | class HardwareSerial : public Stream 86 | { 87 | public: 88 | void begin(unsigned long); 89 | void begin(unsigned long baudrate, uint16_t config); 90 | void end(); 91 | int available(void) override; 92 | int peek(void) override; 93 | int read(void) override; 94 | void flush(void); 95 | int availableForWrite() override; 96 | size_t write(uint8_t) override; 97 | size_t write(const uint8_t *buffer, size_t size) override; 98 | size_t write(const char * buffer, size_t size) 99 | { 100 | return write((uint8_t*) buffer, size); 101 | } 102 | size_t write(const char *str) 103 | { 104 | return write((uint8_t*) str, strlen(str)); 105 | } 106 | inline size_t write(unsigned long n) 107 | { 108 | return write((uint8_t) n); 109 | } 110 | inline size_t write(long n) 111 | { 112 | return write((uint8_t) n); 113 | } 114 | inline size_t write(unsigned int n) 115 | { 116 | return write((uint8_t) n); 117 | } 118 | inline size_t write(int n) 119 | { 120 | return write((uint8_t) n); 121 | } 122 | operator bool(); 123 | }; 124 | 125 | // XXX: Are we keeping the serialEvent API? 126 | extern void serialEventRun(void) __attribute__((weak)); 127 | 128 | extern HardwareSerial Serial; -------------------------------------------------------------------------------- /cores/arduino/api/IPAddress.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | IPAddress.cpp - Base class that provides IPAddress 3 | Copyright (c) 2011 Adrian McEwen. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include "IPAddress.h" 21 | #include "Print.h" 22 | 23 | using namespace arduino; 24 | 25 | IPAddress::IPAddress() : IPAddress(IPv4) {} 26 | 27 | IPAddress::IPAddress(IPType ip_type) 28 | { 29 | _type = ip_type; 30 | memset(_address.bytes, 0, sizeof(_address.bytes)); 31 | } 32 | 33 | IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) 34 | { 35 | _type = IPv4; 36 | memset(_address.bytes, 0, sizeof(_address.bytes)); 37 | _address.bytes[IPADDRESS_V4_BYTES_INDEX] = first_octet; 38 | _address.bytes[IPADDRESS_V4_BYTES_INDEX + 1] = second_octet; 39 | _address.bytes[IPADDRESS_V4_BYTES_INDEX + 2] = third_octet; 40 | _address.bytes[IPADDRESS_V4_BYTES_INDEX + 3] = fourth_octet; 41 | } 42 | 43 | IPAddress::IPAddress(uint8_t o1, uint8_t o2, uint8_t o3, uint8_t o4, uint8_t o5, uint8_t o6, uint8_t o7, uint8_t o8, uint8_t o9, uint8_t o10, uint8_t o11, uint8_t o12, uint8_t o13, uint8_t o14, uint8_t o15, uint8_t o16) { 44 | _type = IPv6; 45 | _address.bytes[0] = o1; 46 | _address.bytes[1] = o2; 47 | _address.bytes[2] = o3; 48 | _address.bytes[3] = o4; 49 | _address.bytes[4] = o5; 50 | _address.bytes[5] = o6; 51 | _address.bytes[6] = o7; 52 | _address.bytes[7] = o8; 53 | _address.bytes[8] = o9; 54 | _address.bytes[9] = o10; 55 | _address.bytes[10] = o11; 56 | _address.bytes[11] = o12; 57 | _address.bytes[12] = o13; 58 | _address.bytes[13] = o14; 59 | _address.bytes[14] = o15; 60 | _address.bytes[15] = o16; 61 | } 62 | 63 | IPAddress::IPAddress(uint32_t address) 64 | { 65 | // IPv4 only 66 | _type = IPv4; 67 | memset(_address.bytes, 0, sizeof(_address.bytes)); 68 | _address.dword[IPADDRESS_V4_DWORD_INDEX] = address; 69 | 70 | // NOTE on conversion/comparison and uint32_t: 71 | // These conversions are host platform dependent. 72 | // There is a defined integer representation of IPv4 addresses, 73 | // based on network byte order (will be the value on big endian systems), 74 | // e.g. http://2398766798 is the same as http://142.250.70.206, 75 | // However on little endian systems the octets 0x83, 0xFA, 0x46, 0xCE, 76 | // in that order, will form the integer (uint32_t) 3460758158 . 77 | } 78 | 79 | IPAddress::IPAddress(const uint8_t *address) : IPAddress(IPv4, address) {} 80 | 81 | IPAddress::IPAddress(IPType ip_type, const uint8_t *address) 82 | { 83 | _type = ip_type; 84 | if (ip_type == IPv4) { 85 | memset(_address.bytes, 0, sizeof(_address.bytes)); 86 | memcpy(&_address.bytes[IPADDRESS_V4_BYTES_INDEX], address, sizeof(uint32_t)); 87 | } else { 88 | memcpy(_address.bytes, address, sizeof(_address.bytes)); 89 | } 90 | } 91 | 92 | bool IPAddress::fromString(const char *address) { 93 | if (!fromString4(address)) { 94 | return fromString6(address); 95 | } 96 | return true; 97 | } 98 | 99 | bool IPAddress::fromString4(const char *address) 100 | { 101 | // TODO: add support for "a", "a.b", "a.b.c" formats 102 | 103 | int16_t acc = -1; // Accumulator 104 | uint8_t dots = 0; 105 | 106 | memset(_address.bytes, 0, sizeof(_address.bytes)); 107 | while (*address) 108 | { 109 | char c = *address++; 110 | if (c >= '0' && c <= '9') 111 | { 112 | acc = (acc < 0) ? (c - '0') : acc * 10 + (c - '0'); 113 | if (acc > 255) { 114 | // Value out of [0..255] range 115 | return false; 116 | } 117 | } 118 | else if (c == '.') 119 | { 120 | if (dots == 3) { 121 | // Too many dots (there must be 3 dots) 122 | return false; 123 | } 124 | if (acc < 0) { 125 | /* No value between dots, e.g. '1..' */ 126 | return false; 127 | } 128 | _address.bytes[IPADDRESS_V4_BYTES_INDEX + dots++] = acc; 129 | acc = -1; 130 | } 131 | else 132 | { 133 | // Invalid char 134 | return false; 135 | } 136 | } 137 | 138 | if (dots != 3) { 139 | // Too few dots (there must be 3 dots) 140 | return false; 141 | } 142 | if (acc < 0) { 143 | /* No value between dots, e.g. '1..' */ 144 | return false; 145 | } 146 | _address.bytes[IPADDRESS_V4_BYTES_INDEX + 3] = acc; 147 | _type = IPv4; 148 | return true; 149 | } 150 | 151 | bool IPAddress::fromString6(const char *address) { 152 | uint32_t acc = 0; // Accumulator 153 | int colons = 0, double_colons = -1; 154 | 155 | while (*address) 156 | { 157 | char c = tolower(*address++); 158 | if (isalnum(c) && c <= 'f') { 159 | if (c >= 'a') 160 | c -= 'a' - '0' - 10; 161 | acc = acc * 16 + (c - '0'); 162 | if (acc > 0xffff) 163 | // Value out of range 164 | return false; 165 | } 166 | else if (c == ':') { 167 | if (*address == ':') { 168 | if (double_colons >= 0) { 169 | // :: allowed once 170 | return false; 171 | } 172 | if (*address != '\0' && *(address + 1) == ':') { 173 | // ::: not allowed 174 | return false; 175 | } 176 | // remember location 177 | double_colons = colons + !!acc; 178 | address++; 179 | } else if (*address == '\0') { 180 | // can't end with a single colon 181 | return false; 182 | } 183 | if (colons == 7) 184 | // too many separators 185 | return false; 186 | _address.bytes[colons * 2] = acc >> 8; 187 | _address.bytes[colons * 2 + 1] = acc & 0xff; 188 | colons++; 189 | acc = 0; 190 | } 191 | else 192 | // Invalid char 193 | return false; 194 | } 195 | 196 | if (double_colons == -1 && colons != 7) { 197 | // Too few separators 198 | return false; 199 | } 200 | if (double_colons > -1 && colons > 6) { 201 | // Too many segments (double colon must be at least one zero field) 202 | return false; 203 | } 204 | _address.bytes[colons * 2] = acc >> 8; 205 | _address.bytes[colons * 2 + 1] = acc & 0xff; 206 | colons++; 207 | 208 | if (double_colons != -1) { 209 | for (int i = colons * 2 - double_colons * 2 - 1; i >= 0; i--) 210 | _address.bytes[16 - colons * 2 + double_colons * 2 + i] = _address.bytes[double_colons * 2 + i]; 211 | for (int i = double_colons * 2; i < 16 - colons * 2 + double_colons * 2; i++) 212 | _address.bytes[i] = 0; 213 | } 214 | 215 | _type = IPv6; 216 | return true; 217 | } 218 | 219 | IPAddress& IPAddress::operator=(const uint8_t *address) 220 | { 221 | // IPv4 only conversion from byte pointer 222 | _type = IPv4; 223 | memset(_address.bytes, 0, sizeof(_address.bytes)); 224 | memcpy(&_address.bytes[IPADDRESS_V4_BYTES_INDEX], address, sizeof(uint32_t)); 225 | return *this; 226 | } 227 | 228 | IPAddress& IPAddress::operator=(uint32_t address) 229 | { 230 | // IPv4 conversion 231 | // See note on conversion/comparison and uint32_t 232 | _type = IPv4; 233 | memset(_address.bytes, 0, sizeof(_address.bytes)); 234 | _address.dword[IPADDRESS_V4_DWORD_INDEX] = address; 235 | return *this; 236 | } 237 | 238 | bool IPAddress::operator==(const IPAddress& addr) const { 239 | return (addr._type == _type) 240 | && (memcmp(addr._address.bytes, _address.bytes, sizeof(_address.bytes)) == 0); 241 | } 242 | 243 | bool IPAddress::operator==(const uint8_t* addr) const 244 | { 245 | // IPv4 only comparison to byte pointer 246 | // Can't support IPv6 as we know our type, but not the length of the pointer 247 | return _type == IPv4 && memcmp(addr, &_address.bytes[IPADDRESS_V4_BYTES_INDEX], sizeof(uint32_t)) == 0; 248 | } 249 | 250 | uint8_t IPAddress::operator[](int index) const { 251 | if (_type == IPv4) { 252 | return _address.bytes[IPADDRESS_V4_BYTES_INDEX + index]; 253 | } 254 | return _address.bytes[index]; 255 | } 256 | 257 | uint8_t& IPAddress::operator[](int index) { 258 | if (_type == IPv4) { 259 | return _address.bytes[IPADDRESS_V4_BYTES_INDEX + index]; 260 | } 261 | return _address.bytes[index]; 262 | } 263 | 264 | size_t IPAddress::printTo(Print& p) const 265 | { 266 | size_t n = 0; 267 | 268 | if (_type == IPv6) { 269 | // IPv6 IETF canonical format: compress left-most longest run of two or more zero fields, lower case 270 | int8_t longest_start = -1; 271 | int8_t longest_length = 1; 272 | int8_t current_start = -1; 273 | int8_t current_length = 0; 274 | for (int8_t f = 0; f < 8; f++) { 275 | if (_address.bytes[f * 2] == 0 && _address.bytes[f * 2 + 1] == 0) { 276 | if (current_start == -1) { 277 | current_start = f; 278 | current_length = 1; 279 | } else { 280 | current_length++; 281 | } 282 | if (current_length > longest_length) { 283 | longest_start = current_start; 284 | longest_length = current_length; 285 | } 286 | } else { 287 | current_start = -1; 288 | } 289 | } 290 | for (int f = 0; f < 8; f++) { 291 | if (f < longest_start || f >= longest_start + longest_length) { 292 | uint8_t c1 = _address.bytes[f * 2] >> 4; 293 | uint8_t c2 = _address.bytes[f * 2] & 0xf; 294 | uint8_t c3 = _address.bytes[f * 2 + 1] >> 4; 295 | uint8_t c4 = _address.bytes[f * 2 + 1] & 0xf; 296 | if (c1 > 0) { 297 | n += p.print((char)(c1 < 10 ? '0' + c1 : 'a' + c1 - 10)); 298 | } 299 | if (c1 > 0 || c2 > 0) { 300 | n += p.print((char)(c2 < 10 ? '0' + c2 : 'a' + c2 - 10)); 301 | } 302 | if (c1 > 0 || c2 > 0 || c3 > 0) { 303 | n += p.print((char)(c3 < 10 ? '0' + c3 : 'a' + c3 - 10)); 304 | } 305 | n += p.print((char)(c4 < 10 ? '0' + c4 : 'a' + c4 - 10)); 306 | if (f < 7) { 307 | n += p.print(':'); 308 | } 309 | } else if (f == longest_start) { 310 | if (longest_start == 0) { 311 | n += p.print(':'); 312 | } 313 | n += p.print(':'); 314 | } 315 | } 316 | return n; 317 | } 318 | 319 | // IPv4 320 | for (int i =0; i < 3; i++) 321 | { 322 | n += p.print(_address.bytes[IPADDRESS_V4_BYTES_INDEX + i], DEC); 323 | n += p.print('.'); 324 | } 325 | n += p.print(_address.bytes[IPADDRESS_V4_BYTES_INDEX + 3], DEC); 326 | return n; 327 | } 328 | 329 | const IPAddress arduino::IN6ADDR_ANY(IPv6); 330 | const IPAddress arduino::INADDR_NONE(0,0,0,0); 331 | -------------------------------------------------------------------------------- /cores/arduino/api/IPAddress.h: -------------------------------------------------------------------------------- 1 | /* 2 | IPAddress.h - Base class that provides IPAddress 3 | Copyright (c) 2011 Adrian McEwen. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include "Printable.h" 24 | #include "String.h" 25 | 26 | #define IPADDRESS_V4_BYTES_INDEX 12 27 | #define IPADDRESS_V4_DWORD_INDEX 3 28 | 29 | // forward declarations of global name space friend classes 30 | class EthernetClass; 31 | class DhcpClass; 32 | class DNSClient; 33 | 34 | namespace arduino { 35 | 36 | // A class to make it easier to handle and pass around IP addresses 37 | 38 | enum IPType { 39 | IPv4, 40 | IPv6 41 | }; 42 | 43 | class IPAddress : public Printable { 44 | private: 45 | union { 46 | uint8_t bytes[16]; 47 | uint32_t dword[4]; 48 | } _address; 49 | IPType _type; 50 | 51 | // Access the raw byte array containing the address. Because this returns a pointer 52 | // to the internal structure rather than a copy of the address this function should only 53 | // be used when you know that the usage of the returned uint8_t* will be transient and not 54 | // stored. 55 | uint8_t* raw_address() { return _type == IPv4 ? &_address.bytes[IPADDRESS_V4_BYTES_INDEX] : _address.bytes; } 56 | 57 | public: 58 | // Constructors 59 | 60 | // Default IPv4 61 | IPAddress(); 62 | IPAddress(IPType ip_type); 63 | IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); 64 | IPAddress(uint8_t o1, uint8_t o2, uint8_t o3, uint8_t o4, uint8_t o5, uint8_t o6, uint8_t o7, uint8_t o8, uint8_t o9, uint8_t o10, uint8_t o11, uint8_t o12, uint8_t o13, uint8_t o14, uint8_t o15, uint8_t o16); 65 | // IPv4; see implementation note 66 | IPAddress(uint32_t address); 67 | // Default IPv4 68 | IPAddress(const uint8_t *address); 69 | IPAddress(IPType ip_type, const uint8_t *address); 70 | 71 | bool fromString(const char *address); 72 | bool fromString(const String &address) { return fromString(address.c_str()); } 73 | 74 | // Overloaded cast operator to allow IPAddress objects to be used where a uint32_t is expected 75 | // NOTE: IPv4 only; see implementation note 76 | operator uint32_t() const { return _type == IPv4 ? _address.dword[IPADDRESS_V4_DWORD_INDEX] : 0; }; 77 | 78 | bool operator==(const IPAddress& addr) const; 79 | bool operator!=(const IPAddress& addr) const { return !(*this == addr); }; 80 | 81 | // NOTE: IPv4 only; we don't know the length of the pointer 82 | bool operator==(const uint8_t* addr) const; 83 | 84 | // Overloaded index operator to allow getting and setting individual octets of the address 85 | uint8_t operator[](int index) const; 86 | uint8_t& operator[](int index); 87 | 88 | // Overloaded copy operators to allow initialisation of IPAddress objects from other types 89 | // NOTE: IPv4 only 90 | IPAddress& operator=(const uint8_t *address); 91 | // NOTE: IPv4 only; see implementation note 92 | IPAddress& operator=(uint32_t address); 93 | 94 | virtual size_t printTo(Print& p) const; 95 | 96 | IPType type() { return _type; } 97 | 98 | friend class UDP; 99 | friend class Client; 100 | friend class Server; 101 | 102 | friend ::EthernetClass; 103 | friend ::DhcpClass; 104 | friend ::DNSClient; 105 | 106 | protected: 107 | bool fromString4(const char *address); 108 | bool fromString6(const char *address); 109 | }; 110 | 111 | extern const IPAddress IN6ADDR_ANY; 112 | extern const IPAddress INADDR_NONE; 113 | } 114 | 115 | using arduino::IPAddress; -------------------------------------------------------------------------------- /cores/arduino/api/Interrupts.h: -------------------------------------------------------------------------------- 1 | #ifndef W_INTERRUPTS_CPP 2 | #define W_INTERRUPTS_CPP 3 | #ifdef __cplusplus 4 | 5 | #include 6 | #include 7 | #include 8 | #include "Common.h" 9 | 10 | namespace arduino { 11 | 12 | template 13 | using voidTemplateFuncPtrParam = void (*)(T param); 14 | 15 | template struct __container__ { 16 | void* param; 17 | voidTemplateFuncPtrParam function; 18 | }; 19 | 20 | // C++ only overloaded version of attachInterrupt function 21 | template void attachInterrupt(pin_size_t interruptNum, voidTemplateFuncPtrParam userFunc, PinStatus mode, T& param) { 22 | 23 | struct __container__ *cont = new __container__(); 24 | cont->param = ¶m; 25 | cont->function = userFunc; 26 | 27 | // TODO: check lambda scope 28 | // TODO: add structure to delete(__container__) when detachInterrupt() is called 29 | auto f = [](void* a) -> void 30 | { 31 | T param = *(T*)((struct __container__*)a)->param; 32 | (((struct __container__*)a)->function)(param); 33 | }; 34 | 35 | attachInterruptParam(interruptNum, f, mode, cont); 36 | } 37 | 38 | template void attachInterrupt(pin_size_t interruptNum, voidTemplateFuncPtrParam userFunc, PinStatus mode, T* param) { 39 | attachInterruptParam(interruptNum, (voidFuncPtrParam)userFunc, mode, (void*)param); 40 | } 41 | 42 | } 43 | #endif 44 | #endif 45 | -------------------------------------------------------------------------------- /cores/arduino/api/Print.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "Print.h" 25 | 26 | using namespace arduino; 27 | 28 | // Public Methods ////////////////////////////////////////////////////////////// 29 | 30 | /* default implementation: may be overridden */ 31 | size_t Print::write(const uint8_t *buffer, size_t size) 32 | { 33 | size_t n = 0; 34 | while (size--) { 35 | if (write(*buffer++)) n++; 36 | else break; 37 | } 38 | return n; 39 | } 40 | 41 | size_t Print::print(const __FlashStringHelper *ifsh) 42 | { 43 | #if defined(__AVR__) 44 | PGM_P p = reinterpret_cast(ifsh); 45 | size_t n = 0; 46 | while (1) { 47 | unsigned char c = pgm_read_byte(p++); 48 | if (c == 0) break; 49 | if (write(c)) n++; 50 | else break; 51 | } 52 | return n; 53 | #else 54 | return print(reinterpret_cast(ifsh)); 55 | #endif 56 | } 57 | 58 | size_t Print::print(const String &s) 59 | { 60 | return write(s.c_str(), s.length()); 61 | } 62 | 63 | size_t Print::print(const char str[]) 64 | { 65 | return write(str); 66 | } 67 | 68 | size_t Print::print(char c) 69 | { 70 | return write(c); 71 | } 72 | 73 | size_t Print::print(unsigned char b, int base) 74 | { 75 | return print((unsigned long) b, base); 76 | } 77 | 78 | size_t Print::print(int n, int base) 79 | { 80 | return print((long) n, base); 81 | } 82 | 83 | size_t Print::print(unsigned int n, int base) 84 | { 85 | return print((unsigned long) n, base); 86 | } 87 | 88 | size_t Print::print(long n, int base) 89 | { 90 | if (base == 0) { 91 | return write(n); 92 | } else if (base == 10) { 93 | if (n < 0) { 94 | int t = print('-'); 95 | n = -n; 96 | return printNumber(n, 10) + t; 97 | } 98 | return printNumber(n, 10); 99 | } else { 100 | return printNumber(n, base); 101 | } 102 | } 103 | 104 | size_t Print::print(unsigned long n, int base) 105 | { 106 | if (base == 0) return write(n); 107 | else return printNumber(n, base); 108 | } 109 | 110 | size_t Print::print(long long n, int base) 111 | { 112 | if (base == 0) { 113 | return write(n); 114 | } else if (base == 10) { 115 | if (n < 0) { 116 | int t = print('-'); 117 | n = -n; 118 | return printULLNumber(n, 10) + t; 119 | } 120 | return printULLNumber(n, 10); 121 | } else { 122 | return printULLNumber(n, base); 123 | } 124 | } 125 | 126 | size_t Print::print(unsigned long long n, int base) 127 | { 128 | if (base == 0) return write(n); 129 | else return printULLNumber(n, base); 130 | } 131 | 132 | size_t Print::print(double n, int digits) 133 | { 134 | return printFloat(n, digits); 135 | } 136 | 137 | size_t Print::println(const __FlashStringHelper *ifsh) 138 | { 139 | size_t n = print(ifsh); 140 | n += println(); 141 | return n; 142 | } 143 | 144 | size_t Print::print(const Printable& x) 145 | { 146 | return x.printTo(*this); 147 | } 148 | 149 | size_t Print::println(void) 150 | { 151 | return write("\r\n"); 152 | } 153 | 154 | size_t Print::println(const String &s) 155 | { 156 | size_t n = print(s); 157 | n += println(); 158 | return n; 159 | } 160 | 161 | size_t Print::println(const char c[]) 162 | { 163 | size_t n = print(c); 164 | n += println(); 165 | return n; 166 | } 167 | 168 | size_t Print::println(char c) 169 | { 170 | size_t n = print(c); 171 | n += println(); 172 | return n; 173 | } 174 | 175 | size_t Print::println(unsigned char b, int base) 176 | { 177 | size_t n = print(b, base); 178 | n += println(); 179 | return n; 180 | } 181 | 182 | size_t Print::println(int num, int base) 183 | { 184 | size_t n = print(num, base); 185 | n += println(); 186 | return n; 187 | } 188 | 189 | size_t Print::println(unsigned int num, int base) 190 | { 191 | size_t n = print(num, base); 192 | n += println(); 193 | return n; 194 | } 195 | 196 | size_t Print::println(long num, int base) 197 | { 198 | size_t n = print(num, base); 199 | n += println(); 200 | return n; 201 | } 202 | 203 | size_t Print::println(unsigned long num, int base) 204 | { 205 | size_t n = print(num, base); 206 | n += println(); 207 | return n; 208 | } 209 | 210 | size_t Print::println(long long num, int base) 211 | { 212 | size_t n = print(num, base); 213 | n += println(); 214 | return n; 215 | } 216 | 217 | size_t Print::println(unsigned long long num, int base) 218 | { 219 | size_t n = print(num, base); 220 | n += println(); 221 | return n; 222 | } 223 | 224 | size_t Print::println(double num, int digits) 225 | { 226 | size_t n = print(num, digits); 227 | n += println(); 228 | return n; 229 | } 230 | 231 | size_t Print::println(const Printable& x) 232 | { 233 | size_t n = print(x); 234 | n += println(); 235 | return n; 236 | } 237 | 238 | // Private Methods ///////////////////////////////////////////////////////////// 239 | 240 | size_t Print::printNumber(unsigned long n, uint8_t base) 241 | { 242 | char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. 243 | char *str = &buf[sizeof(buf) - 1]; 244 | 245 | *str = '\0'; 246 | 247 | // prevent crash if called with base == 1 248 | if (base < 2) base = 10; 249 | 250 | do { 251 | char c = n % base; 252 | n /= base; 253 | 254 | *--str = c < 10 ? c + '0' : c + 'A' - 10; 255 | } while(n); 256 | 257 | return write(str); 258 | } 259 | 260 | // REFERENCE IMPLEMENTATION FOR ULL 261 | // size_t Print::printULLNumber(unsigned long long n, uint8_t base) 262 | // { 263 | // // if limited to base 10 and 16 the bufsize can be smaller 264 | // char buf[65]; 265 | // char *str = &buf[64]; 266 | 267 | // *str = '\0'; 268 | 269 | // // prevent crash if called with base == 1 270 | // if (base < 2) base = 10; 271 | 272 | // do { 273 | // unsigned long long t = n / base; 274 | // char c = n - t * base; // faster than c = n%base; 275 | // n = t; 276 | // *--str = c < 10 ? c + '0' : c + 'A' - 10; 277 | // } while(n); 278 | 279 | // return write(str); 280 | // } 281 | 282 | // FAST IMPLEMENTATION FOR ULL 283 | size_t Print::printULLNumber(unsigned long long n64, uint8_t base) 284 | { 285 | // if limited to base 10 and 16 the bufsize can be 20 286 | char buf[64]; 287 | uint8_t i = 0; 288 | uint8_t innerLoops = 0; 289 | 290 | // prevent crash if called with base == 1 291 | if (base < 2) base = 10; 292 | 293 | // process chunks that fit in "16 bit math". 294 | uint16_t top = 0xFFFF / base; 295 | uint16_t th16 = 1; 296 | while (th16 < top) 297 | { 298 | th16 *= base; 299 | innerLoops++; 300 | } 301 | 302 | while (n64 > th16) 303 | { 304 | // 64 bit math part 305 | uint64_t q = n64 / th16; 306 | uint16_t r = n64 - q*th16; 307 | n64 = q; 308 | 309 | // 16 bit math loop to do remainder. (note buffer is filled reverse) 310 | for (uint8_t j=0; j < innerLoops; j++) 311 | { 312 | uint16_t qq = r/base; 313 | buf[i++] = r - qq*base; 314 | r = qq; 315 | } 316 | } 317 | 318 | uint16_t n16 = n64; 319 | while (n16 > 0) 320 | { 321 | uint16_t qq = n16/base; 322 | buf[i++] = n16 - qq*base; 323 | n16 = qq; 324 | } 325 | 326 | size_t bytes = i; 327 | for (; i > 0; i--) 328 | write((char) (buf[i - 1] < 10 ? 329 | '0' + buf[i - 1] : 330 | 'A' + buf[i - 1] - 10)); 331 | 332 | return bytes; 333 | } 334 | 335 | size_t Print::printFloat(double number, int digits) 336 | { 337 | if (digits < 0) 338 | digits = 2; 339 | 340 | size_t n = 0; 341 | 342 | if (isnan(number)) return print("nan"); 343 | if (isinf(number)) return print("inf"); 344 | if (number > 4294967040.0) return print ("ovf"); // constant determined empirically 345 | if (number <-4294967040.0) return print ("ovf"); // constant determined empirically 346 | 347 | // Handle negative numbers 348 | if (number < 0.0) 349 | { 350 | n += print('-'); 351 | number = -number; 352 | } 353 | 354 | // Round correctly so that print(1.999, 2) prints as "2.00" 355 | double rounding = 0.5; 356 | for (uint8_t i=0; i 0) { 368 | n += print("."); 369 | } 370 | 371 | // Extract digits from the remainder one at a time 372 | while (digits-- > 0) 373 | { 374 | remainder *= 10.0; 375 | unsigned int toPrint = (unsigned int)remainder; 376 | n += print(toPrint); 377 | remainder -= toPrint; 378 | } 379 | 380 | return n; 381 | } 382 | -------------------------------------------------------------------------------- /cores/arduino/api/Print.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | #include // for size_t 23 | 24 | #include "String.h" 25 | #include "Printable.h" 26 | 27 | #define DEC 10 28 | #define HEX 16 29 | #define OCT 8 30 | #define BIN 2 31 | 32 | namespace arduino { 33 | 34 | class Print 35 | { 36 | private: 37 | int write_error; 38 | size_t printNumber(unsigned long, uint8_t); 39 | size_t printULLNumber(unsigned long long, uint8_t); 40 | size_t printFloat(double, int); 41 | protected: 42 | void setWriteError(int err = 1) { write_error = err; } 43 | public: 44 | Print() : write_error(0) {} 45 | 46 | int getWriteError() { return write_error; } 47 | void clearWriteError() { setWriteError(0); } 48 | 49 | virtual size_t write(uint8_t) = 0; 50 | size_t write(const char *str) { 51 | if (str == NULL) return 0; 52 | return write((const uint8_t *)str, strlen(str)); 53 | } 54 | virtual size_t write(const uint8_t *buffer, size_t size); 55 | size_t write(const char *buffer, size_t size) { 56 | return write((const uint8_t *)buffer, size); 57 | } 58 | 59 | // default to zero, meaning "a single write may block" 60 | // should be overridden by subclasses with buffering 61 | virtual int availableForWrite() { return 0; } 62 | 63 | size_t print(const __FlashStringHelper *); 64 | size_t print(const String &); 65 | size_t print(const char[]); 66 | size_t print(char); 67 | size_t print(unsigned char, int = DEC); 68 | size_t print(int, int = DEC); 69 | size_t print(unsigned int, int = DEC); 70 | size_t print(long, int = DEC); 71 | size_t print(unsigned long, int = DEC); 72 | size_t print(long long, int = DEC); 73 | size_t print(unsigned long long, int = DEC); 74 | size_t print(double, int = 2); 75 | size_t print(const Printable&); 76 | 77 | size_t println(const __FlashStringHelper *); 78 | size_t println(const String &s); 79 | size_t println(const char[]); 80 | size_t println(char); 81 | size_t println(unsigned char, int = DEC); 82 | size_t println(int, int = DEC); 83 | size_t println(unsigned int, int = DEC); 84 | size_t println(long, int = DEC); 85 | size_t println(unsigned long, int = DEC); 86 | size_t println(long long, int = DEC); 87 | size_t println(unsigned long long, int = DEC); 88 | size_t println(double, int = 2); 89 | size_t println(const Printable&); 90 | size_t println(void); 91 | 92 | virtual void flush() { /* Empty implementation for backward compatibility */ } 93 | }; 94 | 95 | } 96 | using arduino::Print; -------------------------------------------------------------------------------- /cores/arduino/api/Printable.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | namespace arduino { 24 | 25 | class Print; 26 | 27 | /** The Printable class provides a way for new classes to allow themselves to be printed. 28 | By deriving from Printable and implementing the printTo method, it will then be possible 29 | for users to print out instances of this class by passing them into the usual 30 | Print::print and Print::println methods. 31 | */ 32 | 33 | class Printable 34 | { 35 | public: 36 | virtual size_t printTo(Print& p) const = 0; 37 | }; 38 | 39 | } -------------------------------------------------------------------------------- /cores/arduino/api/RingBuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifdef __cplusplus 20 | 21 | #ifndef _RING_BUFFER_ 22 | #define _RING_BUFFER_ 23 | 24 | #include 25 | #include 26 | 27 | namespace arduino { 28 | 29 | // Define constants and variables for buffering incoming serial data. We're 30 | // using a ring buffer (I think), in which head is the index of the location 31 | // to which to write the next incoming character and tail is the index of the 32 | // location from which to read. 33 | #define SERIAL_BUFFER_SIZE 64 34 | 35 | template 36 | class RingBufferN 37 | { 38 | public: 39 | uint8_t _aucBuffer[N] ; 40 | volatile int _iHead ; 41 | volatile int _iTail ; 42 | volatile int _numElems; 43 | 44 | public: 45 | RingBufferN( void ) ; 46 | void store_char( uint8_t c ) ; 47 | void clear(); 48 | int read_char(); 49 | int available(); 50 | int availableForStore(); 51 | int peek(); 52 | bool isFull(); 53 | 54 | private: 55 | int nextIndex(int index); 56 | inline bool isEmpty() const { return (_numElems == 0); } 57 | }; 58 | 59 | typedef RingBufferN RingBuffer; 60 | 61 | 62 | template 63 | RingBufferN::RingBufferN( void ) 64 | { 65 | memset( _aucBuffer, 0, N ) ; 66 | clear(); 67 | } 68 | 69 | template 70 | void RingBufferN::store_char( uint8_t c ) 71 | { 72 | // if we should be storing the received character into the location 73 | // just before the tail (meaning that the head would advance to the 74 | // current location of the tail), we're about to overflow the buffer 75 | // and so we don't write the character or advance the head. 76 | if (!isFull()) 77 | { 78 | _aucBuffer[_iHead] = c ; 79 | _iHead = nextIndex(_iHead); 80 | _numElems++; 81 | } 82 | } 83 | 84 | template 85 | void RingBufferN::clear() 86 | { 87 | _iHead = 0; 88 | _iTail = 0; 89 | _numElems = 0; 90 | } 91 | 92 | template 93 | int RingBufferN::read_char() 94 | { 95 | if (isEmpty()) 96 | return -1; 97 | 98 | uint8_t value = _aucBuffer[_iTail]; 99 | _iTail = nextIndex(_iTail); 100 | _numElems--; 101 | 102 | return value; 103 | } 104 | 105 | template 106 | int RingBufferN::available() 107 | { 108 | return _numElems; 109 | } 110 | 111 | template 112 | int RingBufferN::availableForStore() 113 | { 114 | return (N - _numElems); 115 | } 116 | 117 | template 118 | int RingBufferN::peek() 119 | { 120 | if (isEmpty()) 121 | return -1; 122 | 123 | return _aucBuffer[_iTail]; 124 | } 125 | 126 | template 127 | int RingBufferN::nextIndex(int index) 128 | { 129 | return (uint32_t)(index + 1) % N; 130 | } 131 | 132 | template 133 | bool RingBufferN::isFull() 134 | { 135 | return (_numElems == N); 136 | } 137 | 138 | } 139 | 140 | #endif /* _RING_BUFFER_ */ 141 | #endif /* __cplusplus */ -------------------------------------------------------------------------------- /cores/arduino/api/Server.h: -------------------------------------------------------------------------------- 1 | /* 2 | Server.h - Base class that provides Server 3 | Copyright (c) 2011 Adrian McEwen. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #pragma once 21 | 22 | #include "Print.h" 23 | 24 | namespace arduino { 25 | 26 | class Server : public Print { 27 | public: 28 | virtual void begin() = 0; 29 | }; 30 | 31 | } -------------------------------------------------------------------------------- /cores/arduino/api/Stream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Stream.cpp - adds parsing methods to Stream class 3 | Copyright (c) 2008 David A. Mellis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Created July 2011 20 | parsing functions based on TextFinder library by Michael Margolis 21 | 22 | findMulti/findUntil routines written by Jim Leonard/Xuth 23 | */ 24 | 25 | #include "Common.h" 26 | #include "Stream.h" 27 | 28 | #define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait 29 | 30 | using namespace arduino; 31 | 32 | // private method to read stream with timeout 33 | int Stream::timedRead() 34 | { 35 | int c; 36 | _startMillis = millis(); 37 | do { 38 | c = read(); 39 | if (c >= 0) return c; 40 | } while(millis() - _startMillis < _timeout); 41 | return -1; // -1 indicates timeout 42 | } 43 | 44 | // private method to peek stream with timeout 45 | int Stream::timedPeek() 46 | { 47 | int c; 48 | _startMillis = millis(); 49 | do { 50 | c = peek(); 51 | if (c >= 0) return c; 52 | } while(millis() - _startMillis < _timeout); 53 | return -1; // -1 indicates timeout 54 | } 55 | 56 | // returns peek of the next digit in the stream or -1 if timeout 57 | // discards non-numeric characters 58 | int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal) 59 | { 60 | int c; 61 | while (1) { 62 | c = timedPeek(); 63 | 64 | if( c < 0 || 65 | c == '-' || 66 | (c >= '0' && c <= '9') || 67 | (detectDecimal && c == '.')) return c; 68 | 69 | switch( lookahead ){ 70 | case SKIP_NONE: return -1; // Fail code. 71 | case SKIP_WHITESPACE: 72 | switch( c ){ 73 | case ' ': 74 | case '\t': 75 | case '\r': 76 | case '\n': break; 77 | default: return -1; // Fail code. 78 | } 79 | case SKIP_ALL: 80 | break; 81 | } 82 | read(); // discard non-numeric 83 | } 84 | } 85 | 86 | // Public Methods 87 | ////////////////////////////////////////////////////////////// 88 | 89 | void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait 90 | { 91 | _timeout = timeout; 92 | } 93 | 94 | // find returns true if the target string is found 95 | bool Stream::find(const char *target) 96 | { 97 | return findUntil(target, strlen(target), NULL, 0); 98 | } 99 | 100 | // reads data from the stream until the target string of given length is found 101 | // returns true if target string is found, false if timed out 102 | bool Stream::find(const char *target, size_t length) 103 | { 104 | return findUntil(target, length, NULL, 0); 105 | } 106 | 107 | // as find but search ends if the terminator string is found 108 | bool Stream::findUntil(const char *target, const char *terminator) 109 | { 110 | return findUntil(target, strlen(target), terminator, strlen(terminator)); 111 | } 112 | 113 | // reads data from the stream until the target string of the given length is found 114 | // search terminated if the terminator string is found 115 | // returns true if target string is found, false if terminated or timed out 116 | bool Stream::findUntil(const char *target, size_t targetLen, const char *terminator, size_t termLen) 117 | { 118 | if (terminator == NULL) { 119 | MultiTarget t[1] = {{target, targetLen, 0}}; 120 | return findMulti(t, 1) == 0; 121 | } else { 122 | MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}}; 123 | return findMulti(t, 2) == 0; 124 | } 125 | } 126 | 127 | // returns the first valid (long) integer value from the current position. 128 | // lookahead determines how parseInt looks ahead in the stream. 129 | // See LookaheadMode enumeration at the top of the file. 130 | // Lookahead is terminated by the first character that is not a valid part of an integer. 131 | // Once parsing commences, 'ignore' will be skipped in the stream. 132 | long Stream::parseInt(LookaheadMode lookahead, char ignore) 133 | { 134 | bool isNegative = false; 135 | long value = 0; 136 | int c; 137 | 138 | c = peekNextDigit(lookahead, false); 139 | // ignore non numeric leading characters 140 | if(c < 0) 141 | return 0; // zero returned if timeout 142 | 143 | do{ 144 | if((char)c == ignore) 145 | ; // ignore this character 146 | else if(c == '-') 147 | isNegative = true; 148 | else if(c >= '0' && c <= '9') // is c a digit? 149 | value = value * 10 + c - '0'; 150 | read(); // consume the character we got with peek 151 | c = timedPeek(); 152 | } 153 | while( (c >= '0' && c <= '9') || (char)c == ignore ); 154 | 155 | if(isNegative) 156 | value = -value; 157 | return value; 158 | } 159 | 160 | // as parseInt but returns a floating point value 161 | float Stream::parseFloat(LookaheadMode lookahead, char ignore) 162 | { 163 | bool isNegative = false; 164 | bool isFraction = false; 165 | double value = 0.0; 166 | int c; 167 | double fraction = 1.0; 168 | 169 | c = peekNextDigit(lookahead, true); 170 | // ignore non numeric leading characters 171 | if(c < 0) 172 | return 0; // zero returned if timeout 173 | 174 | do{ 175 | if((char)c == ignore) 176 | ; // ignore 177 | else if(c == '-') 178 | isNegative = true; 179 | else if (c == '.') 180 | isFraction = true; 181 | else if(c >= '0' && c <= '9') { // is c a digit? 182 | if(isFraction) { 183 | fraction *= 0.1; 184 | value = value + fraction * (c - '0'); 185 | } else { 186 | value = value * 10 + c - '0'; 187 | } 188 | } 189 | read(); // consume the character we got with peek 190 | c = timedPeek(); 191 | } 192 | while( (c >= '0' && c <= '9') || (c == '.' && !isFraction) || (char)c == ignore ); 193 | 194 | if(isNegative) 195 | value = -value; 196 | 197 | return value; 198 | } 199 | 200 | // read characters from stream into buffer 201 | // terminates if length characters have been read, or timeout (see setTimeout) 202 | // returns the number of characters placed in the buffer 203 | // the buffer is NOT null terminated. 204 | // 205 | size_t Stream::readBytes(char *buffer, size_t length) 206 | { 207 | size_t count = 0; 208 | while (count < length) { 209 | int c = timedRead(); 210 | if (c < 0) break; 211 | *buffer++ = (char)c; 212 | count++; 213 | } 214 | return count; 215 | } 216 | 217 | 218 | // as readBytes with terminator character 219 | // terminates if length characters have been read, timeout, or if the terminator character detected 220 | // returns the number of characters placed in the buffer (0 means no valid data found) 221 | 222 | size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) 223 | { 224 | size_t index = 0; 225 | while (index < length) { 226 | int c = timedRead(); 227 | if (c < 0 || (char)c == terminator) break; 228 | *buffer++ = (char)c; 229 | index++; 230 | } 231 | return index; // return number of characters, not including null terminator 232 | } 233 | 234 | String Stream::readString() 235 | { 236 | String ret; 237 | int c = timedRead(); 238 | while (c >= 0) 239 | { 240 | ret += (char)c; 241 | c = timedRead(); 242 | } 243 | return ret; 244 | } 245 | 246 | String Stream::readStringUntil(char terminator) 247 | { 248 | String ret; 249 | int c = timedRead(); 250 | while (c >= 0 && (char)c != terminator) 251 | { 252 | ret += (char)c; 253 | c = timedRead(); 254 | } 255 | return ret; 256 | } 257 | 258 | int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) { 259 | // any zero length target string automatically matches and would make 260 | // a mess of the rest of the algorithm. 261 | for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { 262 | if (t->len <= 0) 263 | return t - targets; 264 | } 265 | 266 | while (1) { 267 | int c = timedRead(); 268 | if (c < 0) 269 | return -1; 270 | 271 | for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { 272 | // the simple case is if we match, deal with that first. 273 | if ((char)c == t->str[t->index]) { 274 | if (++t->index == t->len) 275 | return t - targets; 276 | else 277 | continue; 278 | } 279 | 280 | // if not we need to walk back and see if we could have matched further 281 | // down the stream (ie '1112' doesn't match the first position in '11112' 282 | // but it will match the second position so we can't just reset the current 283 | // index to 0 when we find a mismatch. 284 | if (t->index == 0) 285 | continue; 286 | 287 | int origIndex = t->index; 288 | do { 289 | --t->index; 290 | // first check if current char works against the new current index 291 | if ((char)c != t->str[t->index]) 292 | continue; 293 | 294 | // if it's the only char then we're good, nothing more to check 295 | if (t->index == 0) { 296 | t->index++; 297 | break; 298 | } 299 | 300 | // otherwise we need to check the rest of the found string 301 | int diff = origIndex - t->index; 302 | size_t i; 303 | for (i = 0; i < t->index; ++i) { 304 | if (t->str[i] != t->str[i + diff]) 305 | break; 306 | } 307 | 308 | // if we successfully got through the previous loop then our current 309 | // index is good. 310 | if (i == t->index) { 311 | t->index++; 312 | break; 313 | } 314 | 315 | // otherwise we just try the next index 316 | } while (t->index); 317 | } 318 | } 319 | // unreachable 320 | return -1; 321 | } 322 | -------------------------------------------------------------------------------- /cores/arduino/api/Stream.h: -------------------------------------------------------------------------------- 1 | /* 2 | Stream.h - base class for character-based streams. 3 | Copyright (c) 2010 David A. Mellis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | parsing functions based on TextFinder library by Michael Margolis 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include "Print.h" 26 | 27 | // compatibility macros for testing 28 | /* 29 | #define getInt() parseInt() 30 | #define getInt(ignore) parseInt(ignore) 31 | #define getFloat() parseFloat() 32 | #define getFloat(ignore) parseFloat(ignore) 33 | #define getString( pre_string, post_string, buffer, length) 34 | readBytesBetween( pre_string, terminator, buffer, length) 35 | */ 36 | 37 | namespace arduino { 38 | 39 | // This enumeration provides the lookahead options for parseInt(), parseFloat() 40 | // The rules set out here are used until either the first valid character is found 41 | // or a time out occurs due to lack of input. 42 | enum LookaheadMode{ 43 | SKIP_ALL, // All invalid characters are ignored. 44 | SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid. 45 | SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped. 46 | }; 47 | 48 | #define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field 49 | 50 | class Stream : public Print 51 | { 52 | protected: 53 | unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read 54 | unsigned long _startMillis; // used for timeout measurement 55 | int timedRead(); // private method to read stream with timeout 56 | int timedPeek(); // private method to peek stream with timeout 57 | int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout 58 | 59 | public: 60 | virtual int available() = 0; 61 | virtual int read() = 0; 62 | virtual int peek() = 0; 63 | 64 | Stream() {_timeout=1000;} 65 | 66 | // parsing methods 67 | 68 | void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second 69 | unsigned long getTimeout(void) { return _timeout; } 70 | 71 | bool find(const char *target); // reads data from the stream until the target string is found 72 | bool find(const uint8_t *target) { return find ((const char *)target); } 73 | // returns true if target string is found, false if timed out (see setTimeout) 74 | 75 | bool find(const char *target, size_t length); // reads data from the stream until the target string of given length is found 76 | bool find(const uint8_t *target, size_t length) { return find ((const char *)target, length); } 77 | // returns true if target string is found, false if timed out 78 | 79 | bool find(char target) { return find (&target, 1); } 80 | 81 | bool findUntil(const char *target, const char *terminator); // as find but search ends if the terminator string is found 82 | bool findUntil(const uint8_t *target, const char *terminator) { return findUntil((const char *)target, terminator); } 83 | 84 | bool findUntil(const char *target, size_t targetLen, const char *terminate, size_t termLen); // as above but search ends if the terminate string is found 85 | bool findUntil(const uint8_t *target, size_t targetLen, const char *terminate, size_t termLen) {return findUntil((const char *)target, targetLen, terminate, termLen); } 86 | 87 | long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); 88 | // returns the first valid (long) integer value from the current position. 89 | // lookahead determines how parseInt looks ahead in the stream. 90 | // See LookaheadMode enumeration at the top of the file. 91 | // Lookahead is terminated by the first character that is not a valid part of an integer. 92 | // Once parsing commences, 'ignore' will be skipped in the stream. 93 | 94 | float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); 95 | // float version of parseInt 96 | 97 | size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer 98 | size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } 99 | // terminates if length characters have been read or timeout (see setTimeout) 100 | // returns the number of characters placed in the buffer (0 means no valid data found) 101 | 102 | size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character 103 | size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); } 104 | // terminates if length characters have been read, timeout, or if the terminator character detected 105 | // returns the number of characters placed in the buffer (0 means no valid data found) 106 | 107 | // Arduino String functions to be added here 108 | String readString(); 109 | String readStringUntil(char terminator); 110 | 111 | protected: 112 | long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); } 113 | float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); } 114 | // These overload exists for compatibility with any class that has derived 115 | // Stream and used parseFloat/Int with a custom ignore character. To keep 116 | // the public API simple, these overload remains protected. 117 | 118 | struct MultiTarget { 119 | const char *str; // string you're searching for 120 | size_t len; // length of string you're searching for 121 | size_t index; // index used by the search routine. 122 | }; 123 | 124 | // This allows you to search for an arbitrary number of strings. 125 | // Returns index of the target that is found first or -1 if timeout occurs. 126 | int findMulti(struct MultiTarget *targets, int tCount); 127 | }; 128 | 129 | #undef NO_IGNORE_CHAR 130 | 131 | } 132 | 133 | using arduino::Stream; -------------------------------------------------------------------------------- /cores/arduino/api/String.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | String library for Wiring & Arduino 3 | ...mostly rewritten by Paul Stoffregen... 4 | Copyright (c) 2009-10 Hernando Barragan. All rights reserved. 5 | Copyright 2011, Paul Stoffregen, paul@pjrc.com 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include "String.h" 23 | #include "Common.h" 24 | #include "itoa.h" 25 | #include "deprecated-avr-comp/avr/dtostrf.h" 26 | 27 | #include 28 | 29 | namespace arduino { 30 | 31 | /*********************************************/ 32 | /* Static Member Initialisation */ 33 | /*********************************************/ 34 | 35 | size_t const String::FLT_MAX_DECIMAL_PLACES; 36 | size_t const String::DBL_MAX_DECIMAL_PLACES; 37 | 38 | /*********************************************/ 39 | /* Constructors */ 40 | /*********************************************/ 41 | 42 | String::String(const char *cstr) 43 | { 44 | init(); 45 | if (cstr) copy(cstr, strlen(cstr)); 46 | } 47 | 48 | String::String(const char *cstr, unsigned int length) 49 | { 50 | init(); 51 | if (cstr) copy(cstr, length); 52 | } 53 | 54 | String::String(const String &value) 55 | { 56 | init(); 57 | *this = value; 58 | } 59 | 60 | String::String(const __FlashStringHelper *pstr) 61 | { 62 | init(); 63 | *this = pstr; 64 | } 65 | 66 | #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) 67 | String::String(String &&rval) 68 | : buffer(rval.buffer) 69 | , capacity(rval.capacity) 70 | , len(rval.len) 71 | { 72 | rval.buffer = NULL; 73 | rval.capacity = 0; 74 | rval.len = 0; 75 | } 76 | #endif 77 | 78 | String::String(char c) 79 | { 80 | init(); 81 | char buf[2]; 82 | buf[0] = c; 83 | buf[1] = 0; 84 | *this = buf; 85 | } 86 | 87 | String::String(unsigned char value, unsigned char base) 88 | { 89 | init(); 90 | char buf[1 + 8 * sizeof(unsigned char)]; 91 | utoa(value, buf, base); 92 | *this = buf; 93 | } 94 | 95 | String::String(int value, unsigned char base) 96 | { 97 | init(); 98 | char buf[2 + 8 * sizeof(int)]; 99 | itoa(value, buf, base); 100 | *this = buf; 101 | } 102 | 103 | String::String(unsigned int value, unsigned char base) 104 | { 105 | init(); 106 | char buf[1 + 8 * sizeof(unsigned int)]; 107 | utoa(value, buf, base); 108 | *this = buf; 109 | } 110 | 111 | String::String(long value, unsigned char base) 112 | { 113 | init(); 114 | char buf[2 + 8 * sizeof(long)]; 115 | ltoa(value, buf, base); 116 | *this = buf; 117 | } 118 | 119 | String::String(unsigned long value, unsigned char base) 120 | { 121 | init(); 122 | char buf[1 + 8 * sizeof(unsigned long)]; 123 | ultoa(value, buf, base); 124 | *this = buf; 125 | } 126 | 127 | String::String(float value, unsigned char decimalPlaces) 128 | { 129 | static size_t const FLOAT_BUF_SIZE = FLT_MAX_10_EXP + FLT_MAX_DECIMAL_PLACES + 1 /* '-' */ + 1 /* '.' */ + 1 /* '\0' */; 130 | init(); 131 | char buf[FLOAT_BUF_SIZE]; 132 | decimalPlaces = min(decimalPlaces, FLT_MAX_DECIMAL_PLACES); 133 | *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); 134 | } 135 | 136 | String::String(double value, unsigned char decimalPlaces) 137 | { 138 | static size_t const DOUBLE_BUF_SIZE = DBL_MAX_10_EXP + DBL_MAX_DECIMAL_PLACES + 1 /* '-' */ + 1 /* '.' */ + 1 /* '\0' */; 139 | init(); 140 | char buf[DOUBLE_BUF_SIZE]; 141 | decimalPlaces = min(decimalPlaces, DBL_MAX_DECIMAL_PLACES); 142 | *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); 143 | } 144 | 145 | String::~String() 146 | { 147 | if (buffer) free(buffer); 148 | } 149 | 150 | /*********************************************/ 151 | /* Memory Management */ 152 | /*********************************************/ 153 | 154 | inline void String::init(void) 155 | { 156 | buffer = NULL; 157 | capacity = 0; 158 | len = 0; 159 | } 160 | 161 | void String::invalidate(void) 162 | { 163 | if (buffer) free(buffer); 164 | buffer = NULL; 165 | capacity = len = 0; 166 | } 167 | 168 | bool String::reserve(unsigned int size) 169 | { 170 | if (buffer && capacity >= size) return 1; 171 | if (changeBuffer(size)) { 172 | if (len == 0) buffer[0] = 0; 173 | return true; 174 | } 175 | return false; 176 | } 177 | 178 | bool String::changeBuffer(unsigned int maxStrLen) 179 | { 180 | char *newbuffer = (char *)realloc(buffer, maxStrLen + 1); 181 | if (newbuffer) { 182 | buffer = newbuffer; 183 | capacity = maxStrLen; 184 | return true; 185 | } 186 | return false; 187 | } 188 | 189 | /*********************************************/ 190 | /* Copy and Move */ 191 | /*********************************************/ 192 | 193 | String & String::copy(const char *cstr, unsigned int length) 194 | { 195 | if (!reserve(length)) { 196 | invalidate(); 197 | return *this; 198 | } 199 | len = length; 200 | memcpy(buffer, cstr, length); 201 | buffer[len] = '\0'; 202 | return *this; 203 | } 204 | 205 | String & String::copy(const __FlashStringHelper *pstr, unsigned int length) 206 | { 207 | if (!reserve(length)) { 208 | invalidate(); 209 | return *this; 210 | } 211 | len = length; 212 | strcpy_P(buffer, (PGM_P)pstr); 213 | return *this; 214 | } 215 | 216 | #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) 217 | void String::move(String &rhs) 218 | { 219 | if (this != &rhs) 220 | { 221 | free(buffer); 222 | 223 | buffer = rhs.buffer; 224 | len = rhs.len; 225 | capacity = rhs.capacity; 226 | 227 | rhs.buffer = NULL; 228 | rhs.len = 0; 229 | rhs.capacity = 0; 230 | } 231 | } 232 | #endif 233 | 234 | String & String::operator = (const String &rhs) 235 | { 236 | if (this == &rhs) return *this; 237 | 238 | if (rhs.buffer) copy(rhs.buffer, rhs.len); 239 | else invalidate(); 240 | 241 | return *this; 242 | } 243 | 244 | #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) 245 | String & String::operator = (String &&rval) 246 | { 247 | move(rval); 248 | return *this; 249 | } 250 | #endif 251 | 252 | String & String::operator = (const char *cstr) 253 | { 254 | if (cstr) copy(cstr, strlen(cstr)); 255 | else invalidate(); 256 | 257 | return *this; 258 | } 259 | 260 | String & String::operator = (const __FlashStringHelper *pstr) 261 | { 262 | if (pstr) copy(pstr, strlen_P((PGM_P)pstr)); 263 | else invalidate(); 264 | 265 | return *this; 266 | } 267 | 268 | /*********************************************/ 269 | /* concat */ 270 | /*********************************************/ 271 | 272 | bool String::concat(const String &s) 273 | { 274 | return concat(s.buffer, s.len); 275 | } 276 | 277 | bool String::concat(const char *cstr, unsigned int length) 278 | { 279 | unsigned int newlen = len + length; 280 | if (!cstr) return false; 281 | if (length == 0) return true; 282 | if (!reserve(newlen)) return false; 283 | memcpy(buffer + len, cstr, length); 284 | len = newlen; 285 | buffer[len] = '\0'; 286 | return true; 287 | } 288 | 289 | bool String::concat(const char *cstr) 290 | { 291 | if (!cstr) return false; 292 | return concat(cstr, strlen(cstr)); 293 | } 294 | 295 | bool String::concat(char c) 296 | { 297 | return concat(&c, 1); 298 | } 299 | 300 | bool String::concat(unsigned char num) 301 | { 302 | char buf[1 + 3 * sizeof(unsigned char)]; 303 | itoa(num, buf, 10); 304 | return concat(buf); 305 | } 306 | 307 | bool String::concat(int num) 308 | { 309 | char buf[2 + 3 * sizeof(int)]; 310 | itoa(num, buf, 10); 311 | return concat(buf); 312 | } 313 | 314 | bool String::concat(unsigned int num) 315 | { 316 | char buf[1 + 3 * sizeof(unsigned int)]; 317 | utoa(num, buf, 10); 318 | return concat(buf); 319 | } 320 | 321 | bool String::concat(long num) 322 | { 323 | char buf[2 + 3 * sizeof(long)]; 324 | ltoa(num, buf, 10); 325 | return concat(buf); 326 | } 327 | 328 | bool String::concat(unsigned long num) 329 | { 330 | char buf[1 + 3 * sizeof(unsigned long)]; 331 | ultoa(num, buf, 10); 332 | return concat(buf); 333 | } 334 | 335 | bool String::concat(float num) 336 | { 337 | char buf[20]; 338 | char* string = dtostrf(num, 4, 2, buf); 339 | return concat(string); 340 | } 341 | 342 | bool String::concat(double num) 343 | { 344 | char buf[20]; 345 | char* string = dtostrf(num, 4, 2, buf); 346 | return concat(string); 347 | } 348 | 349 | bool String::concat(const __FlashStringHelper * str) 350 | { 351 | if (!str) return false; 352 | int length = strlen_P((const char *) str); 353 | if (length == 0) return true; 354 | unsigned int newlen = len + length; 355 | if (!reserve(newlen)) return false; 356 | strcpy_P(buffer + len, (const char *) str); 357 | len = newlen; 358 | return true; 359 | } 360 | 361 | /*********************************************/ 362 | /* Concatenate */ 363 | /*********************************************/ 364 | 365 | StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) 366 | { 367 | StringSumHelper &a = const_cast(lhs); 368 | if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); 369 | return a; 370 | } 371 | 372 | StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) 373 | { 374 | StringSumHelper &a = const_cast(lhs); 375 | if (!cstr || !a.concat(cstr)) a.invalidate(); 376 | return a; 377 | } 378 | 379 | StringSumHelper & operator + (const StringSumHelper &lhs, char c) 380 | { 381 | StringSumHelper &a = const_cast(lhs); 382 | if (!a.concat(c)) a.invalidate(); 383 | return a; 384 | } 385 | 386 | StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) 387 | { 388 | StringSumHelper &a = const_cast(lhs); 389 | if (!a.concat(num)) a.invalidate(); 390 | return a; 391 | } 392 | 393 | StringSumHelper & operator + (const StringSumHelper &lhs, int num) 394 | { 395 | StringSumHelper &a = const_cast(lhs); 396 | if (!a.concat(num)) a.invalidate(); 397 | return a; 398 | } 399 | 400 | StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) 401 | { 402 | StringSumHelper &a = const_cast(lhs); 403 | if (!a.concat(num)) a.invalidate(); 404 | return a; 405 | } 406 | 407 | StringSumHelper & operator + (const StringSumHelper &lhs, long num) 408 | { 409 | StringSumHelper &a = const_cast(lhs); 410 | if (!a.concat(num)) a.invalidate(); 411 | return a; 412 | } 413 | 414 | StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) 415 | { 416 | StringSumHelper &a = const_cast(lhs); 417 | if (!a.concat(num)) a.invalidate(); 418 | return a; 419 | } 420 | 421 | StringSumHelper & operator + (const StringSumHelper &lhs, float num) 422 | { 423 | StringSumHelper &a = const_cast(lhs); 424 | if (!a.concat(num)) a.invalidate(); 425 | return a; 426 | } 427 | 428 | StringSumHelper & operator + (const StringSumHelper &lhs, double num) 429 | { 430 | StringSumHelper &a = const_cast(lhs); 431 | if (!a.concat(num)) a.invalidate(); 432 | return a; 433 | } 434 | 435 | StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) 436 | { 437 | StringSumHelper &a = const_cast(lhs); 438 | if (!a.concat(rhs)) a.invalidate(); 439 | return a; 440 | } 441 | 442 | /*********************************************/ 443 | /* Comparison */ 444 | /*********************************************/ 445 | 446 | int String::compareTo(const String &s) const 447 | { 448 | if (!buffer || !s.buffer) { 449 | if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; 450 | if (buffer && len > 0) return *(unsigned char *)buffer; 451 | return 0; 452 | } 453 | return strcmp(buffer, s.buffer); 454 | } 455 | 456 | int String::compareTo(const char *cstr) const 457 | { 458 | if (!buffer || !cstr) { 459 | if (cstr && *cstr) return 0 - *(unsigned char *)cstr; 460 | if (buffer && len > 0) return *(unsigned char *)buffer; 461 | return 0; 462 | } 463 | return strcmp(buffer, cstr); 464 | } 465 | 466 | bool String::equals(const String &s2) const 467 | { 468 | return (len == s2.len && compareTo(s2) == 0); 469 | } 470 | 471 | bool String::equals(const char *cstr) const 472 | { 473 | if (len == 0) return (cstr == NULL || *cstr == 0); 474 | if (cstr == NULL) return buffer[0] == 0; 475 | return strcmp(buffer, cstr) == 0; 476 | } 477 | 478 | bool String::equalsIgnoreCase( const String &s2 ) const 479 | { 480 | if (this == &s2) return true; 481 | if (len != s2.len) return false; 482 | if (len == 0) return true; 483 | const char *p1 = buffer; 484 | const char *p2 = s2.buffer; 485 | while (*p1) { 486 | if (tolower(*p1++) != tolower(*p2++)) return false; 487 | } 488 | return true; 489 | } 490 | 491 | bool String::startsWith( const String &s2 ) const 492 | { 493 | if (len < s2.len) return false; 494 | return startsWith(s2, 0); 495 | } 496 | 497 | bool String::startsWith( const String &s2, unsigned int offset ) const 498 | { 499 | if (offset > len - s2.len || !buffer || !s2.buffer) return false; 500 | return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0; 501 | } 502 | 503 | bool String::endsWith( const String &s2 ) const 504 | { 505 | if ( len < s2.len || !buffer || !s2.buffer) return false; 506 | return strcmp(&buffer[len - s2.len], s2.buffer) == 0; 507 | } 508 | 509 | /*********************************************/ 510 | /* Character Access */ 511 | /*********************************************/ 512 | 513 | char String::charAt(unsigned int loc) const 514 | { 515 | return operator[](loc); 516 | } 517 | 518 | void String::setCharAt(unsigned int loc, char c) 519 | { 520 | if (loc < len) buffer[loc] = c; 521 | } 522 | 523 | char & String::operator[](unsigned int index) 524 | { 525 | static char dummy_writable_char; 526 | if (index >= len || !buffer) { 527 | dummy_writable_char = 0; 528 | return dummy_writable_char; 529 | } 530 | return buffer[index]; 531 | } 532 | 533 | char String::operator[]( unsigned int index ) const 534 | { 535 | if (index >= len || !buffer) return 0; 536 | return buffer[index]; 537 | } 538 | 539 | void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const 540 | { 541 | if (!bufsize || !buf) return; 542 | if (index >= len) { 543 | buf[0] = 0; 544 | return; 545 | } 546 | unsigned int n = bufsize - 1; 547 | if (n > len - index) n = len - index; 548 | strncpy((char *)buf, buffer + index, n); 549 | buf[n] = 0; 550 | } 551 | 552 | /*********************************************/ 553 | /* Search */ 554 | /*********************************************/ 555 | 556 | int String::indexOf(char c) const 557 | { 558 | return indexOf(c, 0); 559 | } 560 | 561 | int String::indexOf( char ch, unsigned int fromIndex ) const 562 | { 563 | if (fromIndex >= len) return -1; 564 | const char* temp = strchr(buffer + fromIndex, ch); 565 | if (temp == NULL) return -1; 566 | return temp - buffer; 567 | } 568 | 569 | int String::indexOf(const String &s2) const 570 | { 571 | return indexOf(s2, 0); 572 | } 573 | 574 | int String::indexOf(const String &s2, unsigned int fromIndex) const 575 | { 576 | if (fromIndex >= len) return -1; 577 | const char *found = strstr(buffer + fromIndex, s2.buffer); 578 | if (found == NULL) return -1; 579 | return found - buffer; 580 | } 581 | 582 | int String::lastIndexOf( char theChar ) const 583 | { 584 | return lastIndexOf(theChar, len - 1); 585 | } 586 | 587 | int String::lastIndexOf(char ch, unsigned int fromIndex) const 588 | { 589 | if (fromIndex >= len) return -1; 590 | char tempchar = buffer[fromIndex + 1]; 591 | buffer[fromIndex + 1] = '\0'; 592 | char* temp = strrchr( buffer, ch ); 593 | buffer[fromIndex + 1] = tempchar; 594 | if (temp == NULL) return -1; 595 | return temp - buffer; 596 | } 597 | 598 | int String::lastIndexOf(const String &s2) const 599 | { 600 | return lastIndexOf(s2, len - s2.len); 601 | } 602 | 603 | int String::lastIndexOf(const String &s2, unsigned int fromIndex) const 604 | { 605 | if (s2.len == 0 || len == 0 || s2.len > len) return -1; 606 | if (fromIndex >= len) fromIndex = len - 1; 607 | int found = -1; 608 | for (char *p = buffer; p <= buffer + fromIndex; p++) { 609 | p = strstr(p, s2.buffer); 610 | if (!p) break; 611 | if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; 612 | } 613 | return found; 614 | } 615 | 616 | String String::substring(unsigned int left, unsigned int right) const 617 | { 618 | if (left > right) { 619 | unsigned int temp = right; 620 | right = left; 621 | left = temp; 622 | } 623 | String out; 624 | if (left >= len) return out; 625 | if (right > len) right = len; 626 | out.copy(buffer + left, right - left); 627 | return out; 628 | } 629 | 630 | /*********************************************/ 631 | /* Modification */ 632 | /*********************************************/ 633 | 634 | void String::replace(char find, char replace) 635 | { 636 | if (!buffer) return; 637 | for (char *p = buffer; *p; p++) { 638 | if (*p == find) *p = replace; 639 | } 640 | } 641 | 642 | void String::replace(const String& find, const String& replace) 643 | { 644 | if (len == 0 || find.len == 0) return; 645 | int diff = replace.len - find.len; 646 | char *readFrom = buffer; 647 | char *foundAt; 648 | if (diff == 0) { 649 | while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { 650 | memcpy(foundAt, replace.buffer, replace.len); 651 | readFrom = foundAt + replace.len; 652 | } 653 | } else if (diff < 0) { 654 | unsigned int size = len; // compute size needed for result 655 | while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { 656 | readFrom = foundAt + find.len; 657 | diff = 0 - diff; 658 | size -= diff; 659 | } 660 | if (size == len) return; 661 | int index = len - 1; 662 | while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { 663 | readFrom = buffer + index + find.len; 664 | memmove(readFrom - diff, readFrom, len - (readFrom - buffer)); 665 | len -= diff; 666 | buffer[len] = 0; 667 | memcpy(buffer + index, replace.buffer, replace.len); 668 | index--; 669 | } 670 | } else { 671 | unsigned int size = len; // compute size needed for result 672 | while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { 673 | readFrom = foundAt + find.len; 674 | size += diff; 675 | } 676 | if (size == len) return; 677 | if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! 678 | int index = len - 1; 679 | while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { 680 | readFrom = buffer + index + find.len; 681 | memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); 682 | len += diff; 683 | buffer[len] = 0; 684 | memcpy(buffer + index, replace.buffer, replace.len); 685 | index--; 686 | } 687 | } 688 | } 689 | 690 | void String::remove(unsigned int index){ 691 | // Pass the biggest integer as the count. The remove method 692 | // below will take care of truncating it at the end of the 693 | // string. 694 | remove(index, (unsigned int)-1); 695 | } 696 | 697 | void String::remove(unsigned int index, unsigned int count){ 698 | if (index >= len) { return; } 699 | if (count <= 0) { return; } 700 | if (count > len - index) { count = len - index; } 701 | char *writeTo = buffer + index; 702 | len = len - count; 703 | memmove(writeTo, buffer + index + count,len - index); 704 | buffer[len] = 0; 705 | } 706 | 707 | void String::toLowerCase(void) 708 | { 709 | if (!buffer) return; 710 | for (char *p = buffer; *p; p++) { 711 | *p = tolower(*p); 712 | } 713 | } 714 | 715 | void String::toUpperCase(void) 716 | { 717 | if (!buffer) return; 718 | for (char *p = buffer; *p; p++) { 719 | *p = toupper(*p); 720 | } 721 | } 722 | 723 | void String::trim(void) 724 | { 725 | if (!buffer || len == 0) return; 726 | char *begin = buffer; 727 | while (isspace(*begin)) begin++; 728 | char *end = buffer + len - 1; 729 | while (isspace(*end) && end >= begin) end--; 730 | len = end + 1 - begin; 731 | if (begin > buffer) memmove(buffer, begin, len); 732 | buffer[len] = 0; 733 | } 734 | 735 | /*********************************************/ 736 | /* Parsing / Conversion */ 737 | /*********************************************/ 738 | 739 | long String::toInt(void) const 740 | { 741 | if (buffer) return atol(buffer); 742 | return 0; 743 | } 744 | 745 | float String::toFloat(void) const 746 | { 747 | return float(toDouble()); 748 | } 749 | 750 | double String::toDouble(void) const 751 | { 752 | if (buffer) return atof(buffer); 753 | return 0; 754 | } 755 | 756 | } // namespace arduino 757 | -------------------------------------------------------------------------------- /cores/arduino/api/String.h: -------------------------------------------------------------------------------- 1 | /* 2 | String library for Wiring & Arduino 3 | ...mostly rewritten by Paul Stoffregen... 4 | Copyright (c) 2009-10 Hernando Barragan. All right reserved. 5 | Copyright 2011, Paul Stoffregen, paul@pjrc.com 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifdef __cplusplus 23 | 24 | #ifndef __ARDUINO_STRINGS__ 25 | #define __ARDUINO_STRINGS__ 26 | 27 | #include 28 | #include 29 | #include 30 | #if defined(__AVR__) 31 | #include "avr/pgmspace.h" 32 | #else 33 | #include "deprecated-avr-comp/avr/pgmspace.h" 34 | #endif 35 | 36 | namespace arduino { 37 | 38 | // When compiling programs with this class, the following gcc parameters 39 | // dramatically increase performance and memory (RAM) efficiency, typically 40 | // with little or no increase in code size. 41 | // -felide-constructors 42 | // -std=c++0x 43 | 44 | class __FlashStringHelper; 45 | #define F(string_literal) (reinterpret_cast(PSTR(string_literal))) 46 | 47 | // An inherited class for holding the result of a concatenation. These 48 | // result objects are assumed to be writable by subsequent concatenations. 49 | class StringSumHelper; 50 | 51 | // The string class 52 | class String 53 | { 54 | friend class StringSumHelper; 55 | // use a function pointer to allow for "if (s)" without the 56 | // complications of an operator bool(). for more information, see: 57 | // http://www.artima.com/cppsource/safebool.html 58 | typedef void (String::*StringIfHelperType)() const; 59 | void StringIfHelper() const {} 60 | 61 | static size_t const FLT_MAX_DECIMAL_PLACES = 10; 62 | static size_t const DBL_MAX_DECIMAL_PLACES = FLT_MAX_DECIMAL_PLACES; 63 | 64 | public: 65 | // constructors 66 | // creates a copy of the initial value. 67 | // if the initial value is null or invalid, or if memory allocation 68 | // fails, the string will be marked as invalid (i.e. "if (s)" will 69 | // be false). 70 | String(const char *cstr = ""); 71 | String(const char *cstr, unsigned int length); 72 | String(const uint8_t *cstr, unsigned int length) : String((const char*)cstr, length) {} 73 | String(const String &str); 74 | String(const __FlashStringHelper *str); 75 | #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) 76 | String(String &&rval); 77 | #endif 78 | explicit String(char c); 79 | explicit String(unsigned char, unsigned char base=10); 80 | explicit String(int, unsigned char base=10); 81 | explicit String(unsigned int, unsigned char base=10); 82 | explicit String(long, unsigned char base=10); 83 | explicit String(unsigned long, unsigned char base=10); 84 | explicit String(float, unsigned char decimalPlaces=2); 85 | explicit String(double, unsigned char decimalPlaces=2); 86 | ~String(void); 87 | 88 | // memory management 89 | // return true on success, false on failure (in which case, the string 90 | // is left unchanged). reserve(0), if successful, will validate an 91 | // invalid string (i.e., "if (s)" will be true afterwards) 92 | bool reserve(unsigned int size); 93 | inline unsigned int length(void) const {return len;} 94 | 95 | // creates a copy of the assigned value. if the value is null or 96 | // invalid, or if the memory allocation fails, the string will be 97 | // marked as invalid ("if (s)" will be false). 98 | String & operator = (const String &rhs); 99 | String & operator = (const char *cstr); 100 | String & operator = (const __FlashStringHelper *str); 101 | #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) 102 | String & operator = (String &&rval); 103 | #endif 104 | 105 | // concatenate (works w/ built-in types) 106 | 107 | // returns true on success, false on failure (in which case, the string 108 | // is left unchanged). if the argument is null or invalid, the 109 | // concatenation is considered unsuccessful. 110 | bool concat(const String &str); 111 | bool concat(const char *cstr); 112 | bool concat(const char *cstr, unsigned int length); 113 | bool concat(const uint8_t *cstr, unsigned int length) {return concat((const char*)cstr, length);} 114 | bool concat(char c); 115 | bool concat(unsigned char num); 116 | bool concat(int num); 117 | bool concat(unsigned int num); 118 | bool concat(long num); 119 | bool concat(unsigned long num); 120 | bool concat(float num); 121 | bool concat(double num); 122 | bool concat(const __FlashStringHelper * str); 123 | 124 | // if there's not enough memory for the concatenated value, the string 125 | // will be left unchanged (but this isn't signalled in any way) 126 | String & operator += (const String &rhs) {concat(rhs); return (*this);} 127 | String & operator += (const char *cstr) {concat(cstr); return (*this);} 128 | String & operator += (char c) {concat(c); return (*this);} 129 | String & operator += (unsigned char num) {concat(num); return (*this);} 130 | String & operator += (int num) {concat(num); return (*this);} 131 | String & operator += (unsigned int num) {concat(num); return (*this);} 132 | String & operator += (long num) {concat(num); return (*this);} 133 | String & operator += (unsigned long num) {concat(num); return (*this);} 134 | String & operator += (float num) {concat(num); return (*this);} 135 | String & operator += (double num) {concat(num); return (*this);} 136 | String & operator += (const __FlashStringHelper *str){concat(str); return (*this);} 137 | 138 | friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); 139 | friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); 140 | friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); 141 | friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); 142 | friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); 143 | friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); 144 | friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); 145 | friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); 146 | friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); 147 | friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); 148 | friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); 149 | 150 | // comparison (only works w/ Strings and "strings") 151 | operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; } 152 | int compareTo(const String &s) const; 153 | int compareTo(const char *cstr) const; 154 | bool equals(const String &s) const; 155 | bool equals(const char *cstr) const; 156 | 157 | friend bool operator == (const String &a, const String &b) { return a.equals(b); } 158 | friend bool operator == (const String &a, const char *b) { return a.equals(b); } 159 | friend bool operator == (const char *a, const String &b) { return b == a; } 160 | friend bool operator < (const String &a, const String &b) { return a.compareTo(b) < 0; } 161 | friend bool operator < (const String &a, const char *b) { return a.compareTo(b) < 0; } 162 | friend bool operator < (const char *a, const String &b) { return b.compareTo(a) > 0; } 163 | 164 | friend bool operator != (const String &a, const String &b) { return !(a == b); } 165 | friend bool operator != (const String &a, const char *b) { return !(a == b); } 166 | friend bool operator != (const char *a, const String &b) { return !(a == b); } 167 | friend bool operator > (const String &a, const String &b) { return b < a; } 168 | friend bool operator > (const String &a, const char *b) { return b < a; } 169 | friend bool operator > (const char *a, const String &b) { return b < a; } 170 | friend bool operator <= (const String &a, const String &b) { return !(b < a); } 171 | friend bool operator <= (const String &a, const char *b) { return !(b < a); } 172 | friend bool operator <= (const char *a, const String &b) { return !(b < a); } 173 | friend bool operator >= (const String &a, const String &b) { return !(a < b); } 174 | friend bool operator >= (const String &a, const char *b) { return !(a < b); } 175 | friend bool operator >= (const char *a, const String &b) { return !(a < b); } 176 | 177 | bool equalsIgnoreCase(const String &s) const; 178 | bool startsWith( const String &prefix) const; 179 | bool startsWith(const String &prefix, unsigned int offset) const; 180 | bool endsWith(const String &suffix) const; 181 | 182 | // character access 183 | char charAt(unsigned int index) const; 184 | void setCharAt(unsigned int index, char c); 185 | char operator [] (unsigned int index) const; 186 | char& operator [] (unsigned int index); 187 | void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const; 188 | void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const 189 | { getBytes((unsigned char *)buf, bufsize, index); } 190 | const char* c_str() const { return buffer; } 191 | char* begin() { return buffer; } 192 | char* end() { return buffer + length(); } 193 | const char* begin() const { return c_str(); } 194 | const char* end() const { return c_str() + length(); } 195 | 196 | // search 197 | int indexOf( char ch ) const; 198 | int indexOf( char ch, unsigned int fromIndex ) const; 199 | int indexOf( const String &str ) const; 200 | int indexOf( const String &str, unsigned int fromIndex ) const; 201 | int lastIndexOf( char ch ) const; 202 | int lastIndexOf( char ch, unsigned int fromIndex ) const; 203 | int lastIndexOf( const String &str ) const; 204 | int lastIndexOf( const String &str, unsigned int fromIndex ) const; 205 | String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); }; 206 | String substring( unsigned int beginIndex, unsigned int endIndex ) const; 207 | 208 | // modification 209 | void replace(char find, char replace); 210 | void replace(const String& find, const String& replace); 211 | void remove(unsigned int index); 212 | void remove(unsigned int index, unsigned int count); 213 | void toLowerCase(void); 214 | void toUpperCase(void); 215 | void trim(void); 216 | 217 | // parsing/conversion 218 | long toInt(void) const; 219 | float toFloat(void) const; 220 | double toDouble(void) const; 221 | 222 | protected: 223 | char *buffer; // the actual char array 224 | unsigned int capacity; // the array length minus one (for the '\0') 225 | unsigned int len; // the String length (not counting the '\0') 226 | protected: 227 | void init(void); 228 | void invalidate(void); 229 | bool changeBuffer(unsigned int maxStrLen); 230 | 231 | // copy and move 232 | String & copy(const char *cstr, unsigned int length); 233 | String & copy(const __FlashStringHelper *pstr, unsigned int length); 234 | #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) 235 | void move(String &rhs); 236 | #endif 237 | }; 238 | 239 | class StringSumHelper : public String 240 | { 241 | public: 242 | StringSumHelper(const String &s) : String(s) {} 243 | StringSumHelper(const char *p) : String(p) {} 244 | StringSumHelper(char c) : String(c) {} 245 | StringSumHelper(unsigned char num) : String(num) {} 246 | StringSumHelper(int num) : String(num) {} 247 | StringSumHelper(unsigned int num) : String(num) {} 248 | StringSumHelper(long num) : String(num) {} 249 | StringSumHelper(unsigned long num) : String(num) {} 250 | StringSumHelper(float num) : String(num) {} 251 | StringSumHelper(double num) : String(num) {} 252 | }; 253 | 254 | } // namespace arduino 255 | 256 | using arduino::__FlashStringHelper; 257 | using arduino::String; 258 | 259 | #endif // __cplusplus 260 | #endif // __ARDUINO_STRINGS__ 261 | -------------------------------------------------------------------------------- /cores/arduino/api/Udp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Udp.cpp: Library to send/receive UDP packets. 3 | * 4 | * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) 5 | * 1) UDP does not guarantee the order in which assembled UDP packets are received. This 6 | * might not happen often in practice, but in larger network topologies, a UDP 7 | * packet can be received out of sequence. 8 | * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being 9 | * aware of it. Again, this may not be a concern in practice on small local networks. 10 | * For more information, see http://www.cafeaulait.org/course/week12/35.html 11 | * 12 | * MIT License: 13 | * Copyright (c) 2008 Bjoern Hartmann 14 | * Permission is hereby granted, free of charge, to any person obtaining a copy 15 | * of this software and associated documentation files (the "Software"), to deal 16 | * in the Software without restriction, including without limitation the rights 17 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | * copies of the Software, and to permit persons to whom the Software is 19 | * furnished to do so, subject to the following conditions: 20 | * 21 | * The above copyright notice and this permission notice shall be included in 22 | * all copies or substantial portions of the Software. 23 | * 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 30 | * THE SOFTWARE. 31 | * 32 | * bjoern@cs.stanford.edu 12/30/2008 33 | */ 34 | 35 | #pragma once 36 | 37 | #include "Stream.h" 38 | #include "IPAddress.h" 39 | 40 | namespace arduino { 41 | 42 | class UDP : public Stream { 43 | 44 | public: 45 | virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use 46 | virtual uint8_t beginMulticast(IPAddress, uint16_t) { return 0; } // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 on failure 47 | virtual void stop() =0; // Finish with the UDP socket 48 | 49 | // Sending UDP packets 50 | 51 | // Start building up a packet to send to the remote host specified in ip and port 52 | // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port 53 | virtual int beginPacket(IPAddress ip, uint16_t port) =0; 54 | // Start building up a packet to send to the remote host specified in host and port 55 | // Returns 1 if successful, 0 if there was a problem resolving the hostname or port 56 | virtual int beginPacket(const char *host, uint16_t port) =0; 57 | // Finish off this packet and send it 58 | // Returns 1 if the packet was sent successfully, 0 if there was an error 59 | virtual int endPacket() =0; 60 | // Write a single byte into the packet 61 | virtual size_t write(uint8_t) =0; 62 | // Write size bytes from buffer into the packet 63 | virtual size_t write(const uint8_t *buffer, size_t size) =0; 64 | 65 | // Start processing the next available incoming packet 66 | // Returns the size of the packet in bytes, or 0 if no packets are available 67 | virtual int parsePacket() =0; 68 | // Number of bytes remaining in the current packet 69 | virtual int available() =0; 70 | // Read a single byte from the current packet 71 | virtual int read() =0; 72 | // Read up to len bytes from the current packet and place them into buffer 73 | // Returns the number of bytes read, or 0 if none are available 74 | virtual int read(unsigned char* buffer, size_t len) =0; 75 | // Read up to len characters from the current packet and place them into buffer 76 | // Returns the number of characters read, or 0 if none are available 77 | virtual int read(char* buffer, size_t len) =0; 78 | // Return the next byte from the current packet without moving on to the next byte 79 | virtual int peek() =0; 80 | virtual void flush() =0; // Finish reading the current packet 81 | 82 | // Return the IP address of the host who sent the current incoming packet 83 | virtual IPAddress remoteIP() =0; 84 | // Return the port of the host who sent the current incoming packet 85 | virtual uint16_t remotePort() =0; 86 | protected: 87 | uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; 88 | }; 89 | 90 | } 91 | 92 | using arduino::UDP; -------------------------------------------------------------------------------- /cores/arduino/api/WCharacter.h: -------------------------------------------------------------------------------- 1 | /* 2 | WCharacter.h - Character utility functions for Wiring & Arduino 3 | Copyright (c) 2010 Hernando Barragan. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef Character_h 21 | #define Character_h 22 | 23 | #include 24 | 25 | namespace arduino { 26 | 27 | // WCharacter.h prototypes 28 | inline bool isAlphaNumeric(int c) __attribute__((always_inline)); 29 | inline bool isAlpha(int c) __attribute__((always_inline)); 30 | inline bool isAscii(int c) __attribute__((always_inline)); 31 | inline bool isWhitespace(int c) __attribute__((always_inline)); 32 | inline bool isControl(int c) __attribute__((always_inline)); 33 | inline bool isDigit(int c) __attribute__((always_inline)); 34 | inline bool isGraph(int c) __attribute__((always_inline)); 35 | inline bool isLowerCase(int c) __attribute__((always_inline)); 36 | inline bool isPrintable(int c) __attribute__((always_inline)); 37 | inline bool isPunct(int c) __attribute__((always_inline)); 38 | inline bool isSpace(int c) __attribute__((always_inline)); 39 | inline bool isUpperCase(int c) __attribute__((always_inline)); 40 | inline bool isHexadecimalDigit(int c) __attribute__((always_inline)); 41 | inline int toAscii(int c) __attribute__((always_inline)); 42 | inline int toLowerCase(int c) __attribute__((always_inline)); 43 | inline int toUpperCase(int c)__attribute__((always_inline)); 44 | 45 | 46 | // Checks for an alphanumeric character. 47 | // It is equivalent to (isalpha(c) || isdigit(c)). 48 | inline bool isAlphaNumeric(int c) 49 | { 50 | return ( isalnum(c) == 0 ? false : true); 51 | } 52 | 53 | 54 | // Checks for an alphabetic character. 55 | // It is equivalent to (isupper(c) || islower(c)). 56 | inline bool isAlpha(int c) 57 | { 58 | return ( isalpha(c) == 0 ? false : true); 59 | } 60 | 61 | 62 | // Checks whether c is a 7-bit unsigned char value 63 | // that fits into the ASCII character set. 64 | inline bool isAscii(int c) 65 | { 66 | return ( isascii (c) == 0 ? false : true); 67 | } 68 | 69 | 70 | // Checks for a blank character, that is, a space or a tab. 71 | inline bool isWhitespace(int c) 72 | { 73 | return ( isblank (c) == 0 ? false : true); 74 | } 75 | 76 | 77 | // Checks for a control character. 78 | inline bool isControl(int c) 79 | { 80 | return ( iscntrl (c) == 0 ? false : true); 81 | } 82 | 83 | 84 | // Checks for a digit (0 through 9). 85 | inline bool isDigit(int c) 86 | { 87 | return ( isdigit (c) == 0 ? false : true); 88 | } 89 | 90 | 91 | // Checks for any printable character except space. 92 | inline bool isGraph(int c) 93 | { 94 | return ( isgraph (c) == 0 ? false : true); 95 | } 96 | 97 | 98 | // Checks for a lower-case character. 99 | inline bool isLowerCase(int c) 100 | { 101 | return (islower (c) == 0 ? false : true); 102 | } 103 | 104 | 105 | // Checks for any printable character including space. 106 | inline bool isPrintable(int c) 107 | { 108 | return ( isprint (c) == 0 ? false : true); 109 | } 110 | 111 | 112 | // Checks for any printable character which is not a space 113 | // or an alphanumeric character. 114 | inline bool isPunct(int c) 115 | { 116 | return ( ispunct (c) == 0 ? false : true); 117 | } 118 | 119 | 120 | // Checks for white-space characters. For the avr-libc library, 121 | // these are: space, formfeed ('\f'), newline ('\n'), carriage 122 | // return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). 123 | inline bool isSpace(int c) 124 | { 125 | return ( isspace (c) == 0 ? false : true); 126 | } 127 | 128 | 129 | // Checks for an uppercase letter. 130 | inline bool isUpperCase(int c) 131 | { 132 | return ( isupper (c) == 0 ? false : true); 133 | } 134 | 135 | 136 | // Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7 137 | // 8 9 a b c d e f A B C D E F. 138 | inline bool isHexadecimalDigit(int c) 139 | { 140 | return ( isxdigit (c) == 0 ? false : true); 141 | } 142 | 143 | 144 | // Converts c to a 7-bit unsigned char value that fits into the 145 | // ASCII character set, by clearing the high-order bits. 146 | inline int toAscii(int c) 147 | { 148 | return toascii (c); 149 | } 150 | 151 | 152 | // Warning: 153 | // Many people will be unhappy if you use this function. 154 | // This function will convert accented letters into random 155 | // characters. 156 | 157 | // Converts the letter c to lower case, if possible. 158 | inline int toLowerCase(int c) 159 | { 160 | return tolower (c); 161 | } 162 | 163 | 164 | // Converts the letter c to upper case, if possible. 165 | inline int toUpperCase(int c) 166 | { 167 | return toupper (c); 168 | } 169 | 170 | } 171 | #endif -------------------------------------------------------------------------------- /cores/arduino/api/deprecated-avr-comp/avr/dtostrf.c.impl: -------------------------------------------------------------------------------- 1 | /* 2 | dtostrf - Emulation for dtostrf function from avr-libc 3 | Copyright (c) 2016 Arduino LLC. All rights reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | // This is a default implementation for dtostrf function. 21 | // This file should be used if the standard lib doesn't provide an 22 | // implementation of dtostrf. 23 | 24 | // Create a file called "dtostrf.c" with the following include: 25 | // #include "api/deprecated-avr-comp/avr/dtostrf.c.impl" 26 | 27 | #include 28 | 29 | char *dtostrf (double val, signed char width, unsigned char prec, char *sout) { 30 | asm(".global _printf_float"); 31 | 32 | char fmt[20]; 33 | sprintf(fmt, "%%%d.%df", width, prec); 34 | sprintf(sout, fmt, val); 35 | return sout; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /cores/arduino/api/deprecated-avr-comp/avr/dtostrf.h: -------------------------------------------------------------------------------- 1 | /* 2 | dtostrf - Emulation for dtostrf function from avr-libc 3 | Copyright (c) 2015 Arduino LLC. All rights reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #pragma once 21 | 22 | #if !defined(ARDUINO_ARCH_AVR) 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | char *dtostrf(double val, signed char width, unsigned char prec, char *sout); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /cores/arduino/api/deprecated-avr-comp/avr/interrupt.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LCC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | /* 20 | Empty file. 21 | This file is here to allow compatibility with sketches (made for AVR) 22 | that include 23 | */ 24 | -------------------------------------------------------------------------------- /cores/arduino/api/deprecated-avr-comp/avr/pgmspace.h: -------------------------------------------------------------------------------- 1 | /* 2 | pgmspace.h - Definitions for compatibility with AVR pgmspace macros 3 | 4 | Copyright (c) 2015 Arduino LLC 5 | 6 | Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com) 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE 25 | */ 26 | 27 | #ifndef __PGMSPACE_H_ 28 | #define __PGMSPACE_H_ 1 29 | 30 | #include 31 | 32 | #define PROGMEM 33 | #define PGM_P const char * 34 | #define PSTR(str) (str) 35 | 36 | #define _SFR_BYTE(n) (n) 37 | 38 | typedef void prog_void; 39 | typedef char prog_char; 40 | typedef unsigned char prog_uchar; 41 | typedef int8_t prog_int8_t; 42 | typedef uint8_t prog_uint8_t; 43 | typedef int16_t prog_int16_t; 44 | typedef uint16_t prog_uint16_t; 45 | typedef int32_t prog_int32_t; 46 | typedef uint32_t prog_uint32_t; 47 | typedef int64_t prog_int64_t; 48 | typedef uint64_t prog_uint64_t; 49 | 50 | typedef const void* int_farptr_t; 51 | typedef const void* uint_farptr_t; 52 | 53 | #define memchr_P(s, c, n) memchr((s), (c), (n)) 54 | #define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n)) 55 | #define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n)) 56 | #define memcpy_P(dest, src, n) memcpy((dest), (src), (n)) 57 | #define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen)) 58 | #define memrchr_P(s, c, n) memrchr((s), (c), (n)) 59 | #define strcat_P(dest, src) strcat((dest), (src)) 60 | #define strchr_P(s, c) strchr((s), (c)) 61 | #define strchrnul_P(s, c) strchrnul((s), (c)) 62 | #define strcmp_P(a, b) strcmp((a), (b)) 63 | #define strcpy_P(dest, src) strcpy((dest), (src)) 64 | #define strcasecmp_P(s1, s2) strcasecmp((s1), (s2)) 65 | #define strcasestr_P(haystack, needle) strcasestr((haystack), (needle)) 66 | #define strcspn_P(s, accept) strcspn((s), (accept)) 67 | #define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n)) 68 | #define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n)) 69 | #define strlen_P(a) strlen((a)) 70 | #define strnlen_P(s, n) strnlen((s), (n)) 71 | #define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n)) 72 | #define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n)) 73 | #define strncat_P(s1, s2, n) strncat((s1), (s2), (n)) 74 | #define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n)) 75 | #define strpbrk_P(s, accept) strpbrk((s), (accept)) 76 | #define strrchr_P(s, c) strrchr((s), (c)) 77 | #define strsep_P(sp, delim) strsep((sp), (delim)) 78 | #define strspn_P(s, accept) strspn((s), (accept)) 79 | #define strstr_P(a, b) strstr((a), (b)) 80 | #define strtok_P(s, delim) strtok((s), (delim)) 81 | #define strtok_rP(s, delim, last) strtok((s), (delim), (last)) 82 | 83 | #define strlen_PF(a) strlen((a)) 84 | #define strnlen_PF(src, len) strnlen((src), (len)) 85 | #define memcpy_PF(dest, src, len) memcpy((dest), (src), (len)) 86 | #define strcpy_PF(dest, src) strcpy((dest), (src)) 87 | #define strncpy_PF(dest, src, len) strncpy((dest), (src), (len)) 88 | #define strcat_PF(dest, src) strcat((dest), (src)) 89 | #define strlcat_PF(dest, src, len) strlcat((dest), (src), (len)) 90 | #define strncat_PF(dest, src, len) strncat((dest), (src), (len)) 91 | #define strcmp_PF(s1, s2) strcmp((s1), (s2)) 92 | #define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n)) 93 | #define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2)) 94 | #define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n)) 95 | #define strstr_PF(s1, s2) strstr((s1), (s2)) 96 | #define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n)) 97 | #define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n)) 98 | 99 | #define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) 100 | #define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__) 101 | 102 | #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) 103 | #define pgm_read_word(addr) (*(const unsigned short *)(addr)) 104 | #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) 105 | #define pgm_read_float(addr) (*(const float *)(addr)) 106 | #define pgm_read_ptr(addr) (*(void *const *)(addr)) 107 | 108 | #define pgm_read_byte_near(addr) pgm_read_byte(addr) 109 | #define pgm_read_word_near(addr) pgm_read_word(addr) 110 | #define pgm_read_dword_near(addr) pgm_read_dword(addr) 111 | #define pgm_read_float_near(addr) pgm_read_float(addr) 112 | #define pgm_read_ptr_near(addr) pgm_read_ptr(addr) 113 | 114 | #define pgm_read_byte_far(addr) pgm_read_byte(addr) 115 | #define pgm_read_word_far(addr) pgm_read_word(addr) 116 | #define pgm_read_dword_far(addr) pgm_read_dword(addr) 117 | #define pgm_read_float_far(addr) pgm_read_float(addr) 118 | #define pgm_read_ptr_far(addr) pgm_read_ptr(addr) 119 | 120 | #define pgm_get_far_address(addr) (&(addr)) 121 | 122 | #endif 123 | -------------------------------------------------------------------------------- /cores/arduino/api/deprecated/Client.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | // including Client.h is deprecated, for all future projects use Arduino.h instead 20 | 21 | // This include is added for compatibility, it will be removed on the next 22 | // major release of the API 23 | #include "../Client.h" 24 | 25 | 26 | -------------------------------------------------------------------------------- /cores/arduino/api/deprecated/HardwareSerial.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | // including HardwareSerial.h is deprecated, for all future projects use Arduino.h instead 20 | 21 | // This include is added for compatibility, it will be removed on the next 22 | // major release of the API 23 | #include "../HardwareSerial.h" 24 | 25 | 26 | -------------------------------------------------------------------------------- /cores/arduino/api/deprecated/IPAddress.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | // including IPAddress.h is deprecated, for all future projects use Arduino.h instead 20 | 21 | // This include is added for compatibility, it will be removed on the next 22 | // major release of the API 23 | #include "../IPAddress.h" 24 | 25 | 26 | -------------------------------------------------------------------------------- /cores/arduino/api/deprecated/Print.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | // including Print.h is deprecated, for all future projects use Arduino.h instead 20 | 21 | // This include is added for compatibility, it will be removed on the next 22 | // major release of the API 23 | #include "../Print.h" 24 | 25 | -------------------------------------------------------------------------------- /cores/arduino/api/deprecated/Printable.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | // including Printable.h is deprecated, for all future projects use Arduino.h instead 20 | 21 | // This include is added for compatibility, it will be removed on the next 22 | // major release of the API 23 | #include "../Printable.h" 24 | 25 | -------------------------------------------------------------------------------- /cores/arduino/api/deprecated/Server.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | // including Server.h is deprecated, for all future projects use Arduino.h instead 20 | 21 | // This include is added for compatibility, it will be removed on the next 22 | // major release of the API 23 | #include "../Server.h" 24 | 25 | 26 | -------------------------------------------------------------------------------- /cores/arduino/api/deprecated/Stream.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | // including Stream.h is deprecated, for all future projects use Arduino.h instead 20 | 21 | // This include is added for compatibility, it will be removed on the next 22 | // major release of the API 23 | #include "../Stream.h" 24 | 25 | 26 | -------------------------------------------------------------------------------- /cores/arduino/api/deprecated/Udp.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | // including Udp.h is deprecated, for all future projects use Arduino.h instead 20 | 21 | // This include is added for compatibility, it will be removed on the next 22 | // major release of the API 23 | #include "../Udp.h" 24 | 25 | 26 | -------------------------------------------------------------------------------- /cores/arduino/api/deprecated/WString.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016, Arduino LLC. All Right Reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | // including WString.h is deprecated, for all future projects use Arduino.h instead 20 | 21 | // This include is added for compatibility, it will be removed on the next 22 | // major release of the API 23 | #include "../String.h" 24 | 25 | -------------------------------------------------------------------------------- /cores/arduino/api/itoa.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #pragma once 20 | 21 | // Standard C functions required in Arduino API 22 | // If these functions are not provided by the standard library, the 23 | // core should supply an implementation of them. 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | extern char* itoa(int value, char *string, int radix); 30 | extern char* ltoa(long value, char *string, int radix); 31 | extern char* utoa(unsigned value, char *string, int radix); 32 | extern char* ultoa(unsigned long value, char *string, int radix); 33 | 34 | #ifdef __cplusplus 35 | } // extern "C" 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /cores/arduino/hal/wch-hal-i2c.c: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "wch-hal-i2c.h" 3 | #include "ch32v003fun.h" 4 | 5 | void i2c_init(uint32_t clockSpeed, uint16_t dutyCycle, uint16_t ownAddress, 6 | uint16_t ack, uint16_t ackAddress) { 7 | // Enable I2C Pins 8 | RCC->APB2PCENR |= (RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO); 9 | RCC->APB1PCENR |= RCC_APB1Periph_I2C1; 10 | 11 | uint8_t pinConfig = GPIO_Speed_50MHz | GPIO_CNF_OUT_OD_AF; 12 | GPIOC->CFGLR &= ~(0xF << (2 * 4)); 13 | GPIOC->CFGLR |= (pinConfig << (2 * 4)); 14 | GPIOC->CFGLR &= ~(0xF << (1 * 4)); 15 | GPIOC->CFGLR |= (pinConfig << (1 * 4)); 16 | 17 | // Configure I2C peripheral 18 | 19 | uint16_t tmpReg, freqRange, result; 20 | uint32_t pClk1; 21 | 22 | tmpReg = I2C1->CTLR2; 23 | tmpReg &= CTLR2_FREQ_Reset; 24 | 25 | if (((RCC->CFGR0 & CFGR0_HPRE_Set_Mask) >> 4) < 8) { 26 | pClk1 = SYSTEM_CORE_CLOCK / ((((RCC->CFGR0 & CFGR0_HPRE_Set_Mask) >> 4) % 8) + 1); 27 | } else { 28 | pClk1 = SYSTEM_CORE_CLOCK >> ((((RCC->CFGR0 & CFGR0_HPRE_Set_Mask) >> 4) % 8) + 1); 29 | } 30 | 31 | freqRange = (uint16_t) (pClk1 / 1000000); 32 | tmpReg |= freqRange; 33 | I2C1->CTLR2 = tmpReg; 34 | 35 | I2C1->CTLR1 &= CTLR1_PE_Reset; 36 | tmpReg = 0; 37 | 38 | if (clockSpeed <= 100000) { 39 | result = (uint16_t) (pClk1 / (clockSpeed << 1)); 40 | if (result < 0x04) { 41 | result = 0x04; 42 | } 43 | tmpReg |= result; 44 | } else { 45 | if (dutyCycle == I2C_DutyCycle_2) { 46 | result = (uint16_t) (pClk1 / (clockSpeed * 3)); 47 | } else { 48 | result = (uint16_t) (pClk1 / (clockSpeed * 25)); 49 | result |= I2C_DutyCycle_16_9; 50 | } 51 | 52 | if ((result & CKCFGR_CCR_Set) == 0) { 53 | result |= (uint16_t) 0x0001; 54 | } 55 | 56 | tmpReg |= (uint16_t) (result | CKCFGR_FS_Set); 57 | } 58 | 59 | I2C1->CKCFGR = tmpReg; 60 | I2C1->CTLR1 |= CTLR1_PE_Set; 61 | 62 | tmpReg = I2C1->CTLR1; 63 | tmpReg &= I2C_CTLR1_CLEAR_Mask; 64 | tmpReg |= ack; 65 | I2C1->CTLR1 = tmpReg; 66 | 67 | I2C1->OADDR1 = (ackAddress | ownAddress); 68 | 69 | while (i2c_get_flag_status(I2C1, I2C_FLAG_BUSY)); 70 | } 71 | 72 | void i2c_deinit(void) { 73 | RCC->APB1PRSTR |= RCC_APB1Periph_I2C1; 74 | RCC->APB1PRSTR &= ~RCC_APB1Periph_I2C1; 75 | } 76 | 77 | void i2c_write_bit(uint8_t address, uint8_t data) { 78 | i2c_write(address, &data, 1); 79 | } 80 | 81 | void i2c_write(uint8_t address, uint8_t *data, uint8_t length) { 82 | i2c_send_start(); 83 | while (!i2c_check_event(I2C_EVENT_MASTER_MODE_SELECT)); 84 | 85 | i2c_send_address(address << 1, I2C_Direction_Transmitter); 86 | while (!i2c_check_event(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); 87 | 88 | while(length) { 89 | if(i2c_get_flag_status(I2C1, I2C_FLAG_TXE)) { 90 | i2c_send_data(*data++); 91 | length--; 92 | } 93 | } 94 | 95 | while (!i2c_check_event(I2C_EVENT_MASTER_BYTE_TRANSMITTED)); 96 | i2c_send_stop(); 97 | } 98 | 99 | uint8_t i2c_read_bit(uint8_t address) { 100 | uint8_t data = 0; 101 | i2c_read(address, &data, 1); 102 | return data; 103 | } 104 | 105 | void i2c_read(uint8_t address, uint8_t *data, uint8_t length) { 106 | i2c_send_start(); 107 | 108 | while (!i2c_check_event(I2C_EVENT_MASTER_MODE_SELECT)); 109 | 110 | i2c_send_address(address << 1, I2C_Direction_Receiver); 111 | 112 | while (!i2c_check_event(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); 113 | 114 | while(length) { 115 | if(i2c_get_flag_status(I2C1, I2C_FLAG_RXNE)) { 116 | *data++ = i2c_receive_data(); 117 | length--; 118 | } 119 | } 120 | 121 | i2c_send_stop(); 122 | } 123 | 124 | void i2c_send_address(uint8_t address, uint8_t direction) { 125 | if (direction != I2C_Direction_Transmitter) { 126 | address |= OADDR1_ADD0_Set; 127 | } else { 128 | address &= OADDR1_ADD0_Reset; 129 | } 130 | 131 | I2C1->DATAR = address; 132 | } 133 | 134 | void i2c_send_start(void) { 135 | I2C1->CTLR1 |= CTLR1_START_Set; 136 | } 137 | 138 | void i2c_send_stop(void) { 139 | I2C1->CTLR1 |= CTLR1_STOP_Set; 140 | } 141 | 142 | bool i2c_is_init(void) { 143 | return true; 144 | } 145 | 146 | bool i2c_get_flag_status(I2C_TypeDef *I2Cx, uint32_t flag) { 147 | bool bitstatus = false; 148 | __IO uint32_t i2creg = 0, i2cxbase = 0; 149 | 150 | i2cxbase = (uint32_t)I2Cx; 151 | i2creg = flag >> 28; 152 | flag &= I2c_FLAG_Mask; 153 | 154 | if(i2creg != 0) 155 | { 156 | i2cxbase += 0x14; 157 | } 158 | else 159 | { 160 | flag = (uint32_t)(flag >> 16); 161 | i2cxbase += 0x18; 162 | } 163 | 164 | if(((*(__IO uint32_t *)i2cxbase) & flag) != (uint32_t)RESET) 165 | { 166 | bitstatus = true; 167 | } 168 | else 169 | { 170 | bitstatus = false; 171 | } 172 | 173 | return bitstatus; 174 | } 175 | 176 | bool i2c_check_event(uint32_t event) { 177 | uint32_t lastevent = 0; 178 | uint32_t flag1 = 0, flag2 = 0; 179 | bool status = false; 180 | 181 | flag1 = I2C1->STAR1; 182 | flag2 = I2C1->STAR2; 183 | flag2 = flag2 << 16; 184 | 185 | lastevent = (flag1 | flag2) & I2c_FLAG_Mask; 186 | 187 | if((lastevent & event) == event) 188 | { 189 | status = true; 190 | } 191 | else 192 | { 193 | status = false; 194 | } 195 | 196 | return status; 197 | } 198 | 199 | inline uint8_t i2c_receive_data() { 200 | return I2C1->DATAR; 201 | } 202 | 203 | inline void i2c_send_data(uint8_t data) { 204 | I2C1->DATAR = data; 205 | } -------------------------------------------------------------------------------- /cores/arduino/hal/wch-hal-i2c.h: -------------------------------------------------------------------------------- 1 | #ifndef _WCH_HAL_I2C_H 2 | #define _WCH_HAL_I2C_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "ch32v003fun.h" 9 | #include "stdbool.h" 10 | 11 | void i2c_init(uint32_t clockSpeed, uint16_t dutyCycle, uint16_t ownAddress, uint16_t ack, uint16_t ackAddress); 12 | void i2c_deinit(void); 13 | void i2c_write_bit(uint8_t address, uint8_t data); 14 | void i2c_write(uint8_t address, uint8_t *data, uint8_t length); 15 | uint8_t i2c_read_bit(uint8_t address); 16 | void i2c_read(uint8_t address, uint8_t *data, uint8_t length); 17 | void i2c_send_address(uint8_t address, uint8_t direction); 18 | void i2c_send_start(void); 19 | void i2c_send_stop(void); 20 | bool i2c_is_init(void); 21 | 22 | bool i2c_get_flag_status(I2C_TypeDef *I2Cx, uint32_t flag); 23 | bool i2c_check_event(uint32_t event); 24 | inline uint8_t i2c_receive_data(); 25 | inline void i2c_send_data(uint8_t data); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif // _WCH_HAL_I2C_H_ 32 | -------------------------------------------------------------------------------- /cores/arduino/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | main.cpp - Main loop for Arduino sketches 3 | Copyright (c) 2005-2013 Arduino Team. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | 22 | // Declared weak in Arduino.h to allow user redefinitions. 23 | int atexit(void (* /*func*/ )()) { return 0; } 24 | 25 | // Weak empty variant initialization function. 26 | // May be redefined by variant files. 27 | void initVariant() __attribute__((weak)); 28 | void initVariant() { } 29 | 30 | void setupUSB() __attribute__((weak)); 31 | void setupUSB() { } 32 | 33 | int main() 34 | { 35 | init(); 36 | initVariant(); 37 | setup(); 38 | 39 | for (;;) { 40 | loop(); 41 | //if (arduino::serialEventRun) arduino::serialEventRun(); 42 | } 43 | 44 | return 0; 45 | } 46 | 47 | extern "C" void NMI_Handler(void) {} 48 | extern "C" void HardFault_Handler(void) 49 | { 50 | while (1) 51 | { 52 | } 53 | } -------------------------------------------------------------------------------- /cores/arduino/wiring.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #include "Arduino.h" 20 | #include "ch32v003fun.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | #define SYSTICK_SR_CNTIF (1<<0) 27 | #define SYSTICK_CTLR_STE (1<<0) 28 | #define SYSTICK_CTLR_STIE (1<<1) 29 | #define SYSTICK_CTLR_STCLK (1<<2) 30 | #define SYSTICK_CTLR_STRE (1<<3) 31 | #define SYSTICK_CTLR_SWIE (1<<31) 32 | 33 | volatile uint32_t systick_counter; 34 | 35 | unsigned long millis() 36 | { 37 | return systick_counter; 38 | } 39 | 40 | unsigned long micros() 41 | { 42 | uint32_t currentSysTick = systick_counter; 43 | uint32_t ticksDifference = (SysTick->CNT + DELAY_MS_TIME) - SysTick->CMP; 44 | 45 | return currentSysTick * 1000u + ticksDifference / DELAY_US_TIME; 46 | } 47 | 48 | void delay(unsigned long ms) 49 | { 50 | Delay_Ms(ms); 51 | } 52 | 53 | void delayMicroseconds(unsigned int us) 54 | { 55 | Delay_Us(us); 56 | } 57 | 58 | void init( void ) 59 | { 60 | SystemInit48HSI(); 61 | 62 | SysTick->CTLR = 0; 63 | NVIC_EnableIRQ(SysTicK_IRQn); 64 | 65 | SysTick->CMP = DELAY_MS_TIME - 1; 66 | SysTick->CNT = 0; 67 | systick_counter = 0; 68 | 69 | SysTick->CTLR = SYSTICK_CTLR_STE | SYSTICK_CTLR_STIE | 70 | SYSTICK_CTLR_STCLK; 71 | } 72 | 73 | void SysTick_Handler(void) __attribute__((interrupt)); 74 | void SysTick_Handler(void) 75 | { 76 | SysTick->CMP += DELAY_MS_TIME; 77 | SysTick->SR = 0; 78 | systick_counter++; 79 | } 80 | 81 | #ifdef __cplusplus 82 | } 83 | #endif -------------------------------------------------------------------------------- /cores/arduino/wiring_digital.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_digital.cpp - digital input and output functions 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2018-2019 Arduino SA 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | */ 22 | 23 | #include "Arduino.h" 24 | #include "ch32v003fun.h" 25 | #include "wiring_private.h" 26 | 27 | static uint8_t gpioForPin(pin_size_t pin) 28 | { 29 | if (pin < 2) { 30 | return 0; 31 | } else if(pin < 10) { 32 | return 2; 33 | } else { 34 | return 3; 35 | } 36 | } 37 | 38 | static GPIO_TypeDef* gpioRegister(uint8_t gpio) 39 | { 40 | if(gpio == 0) { 41 | return GPIOA; 42 | } else if(gpio == 2) { 43 | return GPIOC; 44 | } else { 45 | return GPIOD; 46 | } 47 | } 48 | 49 | static uint8_t gpioPin(uint8_t gpio, pin_size_t pin) 50 | { 51 | if(gpio == 0) { 52 | return pin + 1; 53 | } else if(gpio == 2) { 54 | return pin - 2; 55 | } else { 56 | return pin - 10; 57 | } 58 | } 59 | 60 | void pinMode(pin_size_t pin, PinMode mode) 61 | { 62 | uint8_t gpio = gpioForPin(pin); 63 | GPIO_TypeDef* port = gpioRegister(gpio); 64 | uint8_t p = gpioPin(gpio, pin); 65 | 66 | // Enable GPIO 67 | RCC->APB2PCENR |= (0x04 << gpio); 68 | 69 | // Configure pin 70 | uint8_t pinConfig = 0; 71 | switch (mode) { 72 | case INPUT: 73 | pinConfig = GPIO_CNF_IN_FLOATING; 74 | break; 75 | case OUTPUT: 76 | pinConfig = GPIO_Speed_50MHz | GPIO_CNF_OUT_PP; 77 | break; 78 | case INPUT_PULLUP: 79 | pinConfig = GPIO_CNF_IN_PUPD; 80 | port->BSHR = (((uint32_t)0x01) << p); 81 | break; 82 | case INPUT_PULLDOWN: 83 | default: 84 | pinConfig = GPIO_CNF_IN_PUPD; 85 | port->BCR = (((uint32_t)0x01) << p); 86 | break; 87 | } 88 | 89 | port->CFGLR &= ~(0xf << (p * 4)); 90 | port->CFGLR |= (pinConfig << (p * 4)); 91 | } 92 | 93 | 94 | void digitalWrite(pin_size_t pin, PinStatus val) 95 | { 96 | uint8_t gpio = gpioForPin(pin); 97 | GPIO_TypeDef* port = gpioRegister(gpio); 98 | uint8_t p = gpioPin(gpio, pin); 99 | 100 | if(val == HIGH) { 101 | port->BSHR = ((uint32_t)1 << p); 102 | } else { 103 | port->BCR = ((uint32_t)1 << p); 104 | } 105 | } 106 | 107 | PinStatus digitalRead(pin_size_t pin) 108 | { 109 | uint8_t gpio = gpioForPin(pin); 110 | GPIO_TypeDef* port = gpioRegister(gpio); 111 | uint8_t p = gpioPin(gpio, pin); 112 | 113 | return (port->INDR & (1 << p)) != 0 ? HIGH : LOW; 114 | } 115 | -------------------------------------------------------------------------------- /cores/arduino/wiring_private.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Arduino.h" 4 | 5 | static uint8_t gpioForPin(pin_size_t pin); 6 | static GPIO_TypeDef* gpioRegister(uint8_t gpio); 7 | static uint8_t gpioPin(uint8_t gpio, pin_size_t pin); -------------------------------------------------------------------------------- /examples/CH32V003-Blink/CH32V003-Blink.ino: -------------------------------------------------------------------------------- 1 | uint32_t count; 2 | 3 | void setup() { 4 | pinMode(D0, OUTPUT); 5 | pinMode(C0, OUTPUT); 6 | } 7 | 8 | void loop() { 9 | digitalWrite(D0, LOW); 10 | delay(250); 11 | digitalWrite(D0, HIGH); 12 | delay(250); 13 | digitalWrite(C0, LOW); 14 | delay(100); 15 | digitalWrite(C0, HIGH); 16 | delay(100); 17 | count++; 18 | } 19 | -------------------------------------------------------------------------------- /examples/CH32V003-DigitalRead/CH32V003-DigitalRead.ino: -------------------------------------------------------------------------------- 1 | void setup() { 2 | pinMode(D0, OUTPUT); 3 | pinMode(D4, INPUT_PULLUP); 4 | 5 | digitalWrite(D0, LOW); 6 | } 7 | 8 | void loop() { 9 | bool in = digitalRead(D4); 10 | if(in == HIGH) { 11 | digitalWrite(D0, LOW); 12 | } else { 13 | digitalWrite(D0, HIGH); 14 | } 15 | delay(100); 16 | } -------------------------------------------------------------------------------- /examples/CH32V003-I2C-1/CH32V003-I2C-1.ino: -------------------------------------------------------------------------------- 1 | #include "hal/wch-hal-i2c.h" 2 | 3 | void setup() { 4 | // Initialize Serial Port 5 | Serial.begin(115200); 6 | 7 | // Initialize I2C 8 | i2c_init(80000, I2C_DutyCycle_16_9, 0x02, I2C_Ack_Enable, I2C_AcknowledgedAddress_7bit); 9 | } 10 | 11 | uint8_t read_data[10] = {0}; 12 | 13 | void loop() { 14 | delay(1000); 15 | 16 | Serial.println("Trying to read 6 bytes from 0x30"); 17 | 18 | // Read 6 bits from slave 19 | i2c_read(0x30, read_data, 6); 20 | 21 | Serial.println("Done reading"); 22 | 23 | Serial.print("Recv: "); 24 | for(uint8_t d = 0; d < 6; d++) { 25 | Serial.print(read_data[d]); 26 | } 27 | Serial.println(); 28 | } 29 | -------------------------------------------------------------------------------- /examples/CH32V003-USART/CH32V003-USART.ino: -------------------------------------------------------------------------------- 1 | void setup() { 2 | Serial.begin(115200); 3 | } 4 | 5 | void loop() { 6 | if(Serial.available()) { 7 | Serial.print("I have received: "); 8 | 9 | while(Serial.available()) { 10 | char c = Serial.read(); 11 | Serial.print(c); 12 | } 13 | 14 | Serial.println(); 15 | } 16 | delay(500); 17 | } 18 | -------------------------------------------------------------------------------- /libraries/Wire/library.properties: -------------------------------------------------------------------------------- 1 | name=Wire 2 | version=1.0 3 | author=Alexander Mandera 4 | maintainer=Alexander Mandera 5 | sentence=This library allows you to communicate with I2C and Two Wire Interface devices. 6 | paragraph=It allows the communication with I2C devices like temperature sensors, realtime clocks and many others using SDA (Data Line) and SCL (Clock Line). 7 | category=Communication 8 | url=http://www.arduino.cc/en/Reference/Wire 9 | architectures=riscv -------------------------------------------------------------------------------- /libraries/Wire/src/Wire.h: -------------------------------------------------------------------------------- 1 | /* 2 | TwoWire.h - TWI/I2C library for Arduino & Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public 13 | License along with this library; if not, write to the Free Software 14 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 15 | 16 | Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts 17 | Modified 2020 by Greyson Christoforo (grey@christoforo.net) to implement timeouts 18 | Modified 2023 by Alexander Mandera (alexander@mandera.eu) to implement WCH RISC-V support 19 | */ 20 | 21 | #ifndef TwoWire_h 22 | #define TwoWire_h 23 | 24 | #include 25 | #include "Stream.h" 26 | 27 | #define BUFFER_LENGTH 32 28 | 29 | // WIRE_HAS_END means Wire has end() 30 | #define WIRE_HAS_END 1 31 | 32 | class TwoWire : public Stream 33 | { 34 | private: 35 | static uint8_t rxBuffer[]; 36 | static uint8_t rxBufferIndex; 37 | static uint8_t rxBufferLength; 38 | 39 | static uint8_t txAddress; 40 | static uint8_t txBuffer[]; 41 | static uint8_t txBufferIndex; 42 | static uint8_t txBufferLength; 43 | 44 | static uint8_t transmitting; 45 | static void (*user_onRequest)(void); 46 | static void (*user_onReceive)(int); 47 | static void onRequestService(void); 48 | static void onReceiveService(uint8_t*, int); 49 | public: 50 | TwoWire(); 51 | void begin(); 52 | void begin(uint8_t); 53 | void begin(int); 54 | void end(); 55 | void setClock(uint32_t); 56 | void setWireTimeout(uint32_t timeout = 25000, bool reset_with_timeout = false); 57 | bool getWireTimeoutFlag(void); 58 | void clearWireTimeoutFlag(void); 59 | void beginTransmission(uint8_t); 60 | void beginTransmission(int); 61 | uint8_t endTransmission(void); 62 | uint8_t endTransmission(uint8_t); 63 | uint8_t requestFrom(uint8_t, uint8_t); 64 | uint8_t requestFrom(uint8_t, uint8_t, uint8_t); 65 | uint8_t requestFrom(uint8_t, uint8_t, uint32_t, uint8_t, uint8_t); 66 | uint8_t requestFrom(int, int); 67 | uint8_t requestFrom(int, int, int); 68 | virtual size_t write(uint8_t); 69 | virtual size_t write(const uint8_t *, size_t); 70 | virtual int available(void); 71 | virtual int read(void); 72 | virtual int peek(void); 73 | virtual void flush(void); 74 | void onReceive( void (*)(int) ); 75 | void onRequest( void (*)(void) ); 76 | 77 | inline size_t write(unsigned long n) { return write((uint8_t)n); } 78 | inline size_t write(long n) { return write((uint8_t)n); } 79 | inline size_t write(unsigned int n) { return write((uint8_t)n); } 80 | inline size_t write(int n) { return write((uint8_t)n); } 81 | using Print::write; 82 | }; 83 | 84 | extern TwoWire Wire; 85 | 86 | #endif -------------------------------------------------------------------------------- /platform.txt: -------------------------------------------------------------------------------- 1 | # Arduino WCH Core for CH32V003 RISC-V Boards 2 | 3 | name=WCH Boards 4 | version=0.0.1 5 | 6 | # Tools 7 | tools.minichlink.path={runtime.tools.minichlink.path} 8 | tools.minichlink.cmd=minichlink 9 | tools.minichlink.cmd.windows=minichlink.exe 10 | 11 | # Compiler 12 | 13 | compiler.warning_flags=-w 14 | compiler.warning_flags.none=-w 15 | compiler.warning_flags.default= 16 | compiler.warning_flags.more=-Wall 17 | compiler.warning_flags.all=-Wall -Wextra 18 | 19 | compiler.path={runtime.tools.riscv-none-elf-gcc.path}/bin/ 20 | compiler.c.cmd={build.crossprefix}gcc 21 | compiler.c.flags=-g -Os -flto -ffunction-sections -fdata-sections -static-libgcc -lgcc -march=rv32ec -mabi=ilp32e -I/usr/include/newlib -nostdlib -DTINYVECTOR -DCPLUSPLUS 22 | compiler.c.elf.cmd={build.crossprefix}g++ 23 | compiler.c.elf.flags=-Wl,--gc-sections {compiler.warning_flags} -Wl,--as-needed -march=rv32ec -mabi=ilp32e 24 | compiler.S.cmd={build.crossprefix}g++ 25 | compiler.S.flags=-c -x assembler-with-cpp -march=rv32ec -mabi=ilp32e 26 | compiler.cpp.cmd={build.crossprefix}g++ 27 | compiler.cpp.flags=-g -Os -flto -ffunction-sections -fdata-sections -static-libgcc -lgcc -march=rv32ec -mabi=ilp32e -I/usr/include/newlib -nostdlib -DTINYVECTOR -fno-rtti -DCPLUSPLUS 28 | compiler.ar.cmd={build.crossprefix}ar 29 | compiler.ar.flags=rcs 30 | compiler.objcopy.cmd= 31 | compiler.objcopy.eep.flags= 32 | compiler.elf2hex.bin.flags=-O binary 33 | compiler.elf2hex.hex.flags=-O ihex -R .eeprom 34 | compiler.elf2hex.cmd={build.crossprefix}objcopy 35 | compiler.ldflags= 36 | compiler.libraries.ldflags= 37 | compiler.size.cmd={build.crossprefix}size 38 | compiler.define=-DARDUINO= 39 | 40 | # this can be overriden in boards.txt 41 | build.extra_flags= 42 | build.extra_ldflags= 43 | compiler.wch= 44 | 45 | # These can be overridden in platform.local.txt 46 | compiler.c.extra_flags="-I{build.core.path}/" "-I{build.core.path}/ch32v003fun/" "-I{build.core.path}/hal/" 47 | compiler.cpp.extra_flags="-I{build.core.path}/" "-I{build.core.path}/ch32v003fun/" "-I{build.core.path}/hal/" 48 | compiler.c.elf.extra_flags= 49 | compiler.S.extra_flags= 50 | 51 | compiler.ar.extra_flags= 52 | compiler.objcopy.eep.extra_flags= 53 | compiler.elf2hex.extra_flags= 54 | 55 | # {build.library_discovery_phase} is set to 1 by the builder during library discovery. 56 | # (this is available since arduino-builder>=1.5.5, keeping the default here for backward compatiblity) 57 | build.library_discovery_phase=0 58 | build.library_discovery_phase_flag=-DARDUINO_LIBRARY_DISCOVERY_PHASE={build.library_discovery_phase} 59 | 60 | # USB Flags 61 | # --------- 62 | build.usb_flags= 63 | 64 | # Default usb manufacturer will be replaced at compile time using 65 | # numeric vendor ID if available or by board's specific value. 66 | #build.usb_manufacturer="Unknown" 67 | 68 | build.zip.pattern={recipe.size.pattern} 69 | 70 | # Linux compile patterns 71 | # ----------------------- 72 | 73 | ## Compile c files 74 | recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" -c "{source_file}" -o "{object_file}" {compiler.c.flags} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_ARCH_WCH {build.extra_flags} {build.extra_ldflags} {compiler.c.extra_flags} "-I{build.core.path}/api/deprecated" "-I{build.core.path}/api/deprecated-avr-comp" {includes} "-iprefix{build.core.path}" "@{compiler.wch.includes}" 75 | 76 | ## Compile c++ files 77 | recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" -c "{source_file}" -o "{object_file}" {compiler.cpp.flags} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_ARCH_WCH {build.extra_flags} {build.extra_ldflags} {compiler.c.extra_flags} "-I{build.core.path}/api/deprecated" "-I{build.core.path}/api/deprecated-avr-comp" {includes} "-iprefix{build.core.path}" "@{compiler.wch.includes}" 78 | 79 | ## Compile asm files 80 | recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_ARCH_WCH {includes} {build.extra_flags} {build.extra_ldflags} {compiler.cpp.extra_flags} "-I{build.core.path}/api/deprecated" "-I{build.core.path}/api/deprecated-avr-comp" "-iprefix{build.core.path}" "@{compiler.wch.includes}" "{source_file}" -o "{object_file}" 81 | 82 | ## Create archives 83 | recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}" 84 | 85 | ## Preprocess linker script 86 | recipe.hooks.linking.prelink.1.pattern="{compiler.path}{compiler.c.elf.cmd}" -E -P -x c {build.extra_ldflags} "{build.core.path}/ch32v003fun/ch32v003fun.ld" -o "{build.path}/build.ldscript" 87 | 88 | ## Combine gc-sections, archives, and objects 89 | recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {object_files} "-T{build.path}/build.ldscript" -Wl,--whole-archive "{build.path}/{archive_file}" {compiler.wch} -Wl,--no-whole-archive -o "{build.path}/{build.project_name}.elf" -Wl,--gc-sections -flto -ffunction-sections -fdata-sections -fno-rtti -march=rv32ec -mabi=ilp32e -I/usr/include/newlib -nostdlib -static-libgcc -lgcc 90 | 91 | ## Create eeprom 92 | recipe.objcopy.eep.pattern= 93 | 94 | ## Create output (bin file) 95 | recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.bin.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin" 96 | 97 | ## Create output (hex file) 98 | recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex" 99 | 100 | ## Compute size 101 | recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" 102 | recipe.size.regex.data=^(?:\.data|\.bss)\s+([0-9]+).* 103 | recipe.size.regex=^(?:\.data|\.text|\.rodata)\S*?\s+([0-9]+).* 104 | 105 | ## Save hex 106 | recipe.output.tmp_file={build.project_name}.bin 107 | recipe.output.save_file={build.project_name}.{build.variant}.bin 108 | 109 | # MiniCHLink 110 | tools.minichlink.upload.protocol=usb 111 | tools.minichlink.upload.params.verbose= 112 | tools.minichlink.upload.params.quiet= 113 | tools.minichlink.upload.pattern_args=-w "{build.path}/{build.project_name}.bin" flash -b 114 | tools.minichlink.upload.pattern="{path}/{cmd}" {upload.pattern_args} -------------------------------------------------------------------------------- /programmers.txt: -------------------------------------------------------------------------------- 1 | wchlinke.name=WCH-LinkE 2 | wchlinke.communication=USB 3 | wchlinke.protocol= 4 | wchlinke.program.protocol= 5 | wchlinke.program.tool=minichlink 6 | wchlinke.program.tool.default=minichlink 7 | wchlinke.program.extra_params= 8 | wchlinke.program.pattern_args=-w "{build.path}/{build.project_name}.bin" -b 9 | wchlinke.program.pattern="{path}/{cmd}" {upload.pattern_args} -------------------------------------------------------------------------------- /variants/CH32V003/cflags.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexanderMandera/arduino-wch32v003/9c9e6d9007795632bc359f90d0b87c132cf5a11e/variants/CH32V003/cflags.txt -------------------------------------------------------------------------------- /variants/CH32V003/includes.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexanderMandera/arduino-wch32v003/9c9e6d9007795632bc359f90d0b87c132cf5a11e/variants/CH32V003/includes.txt -------------------------------------------------------------------------------- /variants/CH32V003/ldflags.txt: -------------------------------------------------------------------------------- 1 | -nostartfiles 2 | -Xlinker 3 | --gc-sections 4 | --specs=nano.specs 5 | -g -------------------------------------------------------------------------------- /variants/CH32V003/pins_arduino.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // GPIO A1~A2 4 | static const uint8_t A1 = 0u; 5 | static const uint8_t A2 = 1u; 6 | // GPIO C0~C7 7 | static const uint8_t C0 = 2u; 8 | static const uint8_t C1 = 3u; 9 | static const uint8_t C2 = 4u; 10 | static const uint8_t C3 = 5u; 11 | static const uint8_t C4 = 6u; 12 | static const uint8_t C5 = 7u; 13 | static const uint8_t C6 = 8u; 14 | static const uint8_t C7 = 9u; 15 | // GPIO D0~D7 16 | static const uint8_t D0 = 10u; 17 | static const uint8_t D1 = 11u; 18 | static const uint8_t D2 = 12u; 19 | static const uint8_t D3 = 13u; 20 | static const uint8_t D4 = 14u; 21 | static const uint8_t D5 = 15u; 22 | static const uint8_t D6 = 16u; 23 | static const uint8_t D7 = 17u; --------------------------------------------------------------------------------