├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── Kconfig ├── LICENSE ├── Makefile ├── PCB ├── Makefile ├── Round │ ├── .gitignore │ ├── README.md │ ├── Round-90.png │ ├── Round-bottom.png │ ├── Round-panel-bottom.png │ ├── Round-panel.png │ ├── Round.kicad_pcb │ ├── Round.kicad_prl │ ├── Round.kicad_pro │ ├── Round.kicad_sch │ ├── Round.png │ ├── Round.scad │ ├── Round.stl │ └── production │ │ ├── bom.csv │ │ ├── designators.csv │ │ ├── gerber.zip │ │ ├── netlist.ipc │ │ └── positions.csv └── Square │ ├── .gitignore │ ├── Cable.stl │ ├── README.md │ ├── Square-90.png │ ├── Square-bottom.png │ ├── Square.kicad_pcb │ ├── Square.kicad_prl │ ├── Square.kicad_pro │ ├── Square.kicad_sch │ ├── Square.png │ ├── Square.scad │ ├── Thick.stl │ ├── Wall.stl │ └── production │ ├── bom.csv │ ├── designators.csv │ ├── gerber.zip │ ├── netlist.ipc │ └── positions.csv ├── PN532.pages ├── README.md ├── component.mk ├── idf_component.yml ├── include └── pn532.h ├── makeloop.c ├── pn532.c └── tools ├── .gitignore ├── Makefile └── pn532test.c /.gitignore: -------------------------------------------------------------------------------- 1 | makeloop 2 | makeloop.c.BAK 3 | makeloop.dSYM 4 | *.o 5 | *~ 6 | *.swp 7 | .DS_Store 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "PCB/PCBCase"] 2 | path = PCB/PCBCase 3 | url = https://github.com/revk/PCBCase 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register( 2 | SRCS "pn532.c" 3 | INCLUDE_DIRS "include" 4 | REQUIRES "driver" 5 | ) 6 | -------------------------------------------------------------------------------- /Kconfig: -------------------------------------------------------------------------------- 1 | menu "PN532" 2 | 3 | config PN532_DEBUG_DX 4 | bool "Debug DX" 5 | default n 6 | help 7 | Debug DESFire messages and errors 8 | 9 | config PN532_DEBUG_MSG 10 | bool "Debug MSG" 11 | default n 12 | help 13 | Debug message level 14 | 15 | config PN532_DUMP 16 | bool "Dump Serial" 17 | default n 18 | help 19 | Dump all serial data to/from PN532 20 | 21 | endmenu 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | {one line to give the program's name and a brief idea of what it does.} 635 | Copyright (C) {year} {name of author} 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | {project} Copyright (C) {year} {fullname} 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | makeloop: makeloop.c 2 | gcc -I/usr/local/include -L/usr/local/lib -O -o $@ $< -lpopt -lm -g 3 | 4 | clean: 5 | idf.py clean 6 | 7 | pull: 8 | git pull 9 | git submodule update --recursive 10 | 11 | update: 12 | -git pull 13 | -git commit -a 14 | git submodule update --init --recursive --remote 15 | idf.py update-dependencies 16 | -git commit -a -m "Library update" 17 | 18 | KiCad/PN532-wall.stl: KiCad/PN532.scad Makefile 19 | /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD $< -o $@ -Dbase=0 -Dthick=3 -Draspox=false -Dspox=true -Dtamper=true -Dbell=false -Dmilligrid=false -Dscrews=true 20 | 21 | KiCad/PN532-cable.stl: KiCad/PN532.scad Makefile 22 | /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD $< -o $@ -Dbase=1 -Dthick=3 -Draspox=true -Dspox=false -Dtamper=true -Dbell=false -Dmilligrid=false -Dscrews=false 23 | 24 | KiCad/PN532-thick.stl: KiCad/PN532.scad Makefile 25 | /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD $< -o $@ -Dbase=10 -Dthick=3 -Draspox=false -Dspox=true -Dtamper=true -Dbell=false -Dmilligrid=false -Dscrews=true 26 | 27 | PCBCase/case: PCBCase/case.c 28 | make -C PCBCase 29 | 30 | %.stl: %.scad 31 | echo "Making $@" 32 | /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD $< -o $@ 33 | echo "Made $@" 34 | 35 | stl: PCB/Round/Round.stl PCB/Square/Wall.stl PCB/Square/Cable.stl PCB/Square/Thick.stl 36 | 37 | PCB/Round/Round.scad: PCB/Round/Round.kicad_pcb PCBCase/case Makefile 38 | PCBCase/case -n -o $@ $< --base=0.8 --top=2.5 --ignore=J1,J2 --pcb=2 39 | @echo "base();" >> $@ 40 | @echo "translate([spacing,0,0])difference(){top();translate([casewall+pcbwidth/2-13/2,casewall+pcblength/2+6.5-5/2,-1])cube([15.5,5,10]);}" >> $@ 41 | 42 | PCB/Square/Wall.stl: PCB/Square/Square.scad Makefile 43 | /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD $< -o $@ -Dbase=0 -Dthick=3 -Draspox=false -Dspox=true -Dtamper=true -Dbell=false -Dmilligrid=false -Dscrews=true 44 | 45 | PCB/Square/Cable.stl: PCB/Square/Square.scad Makefile 46 | /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD $< -o $@ -Dbase=1 -Dthick=3 -Draspox=true -Dspox=false -Dtamper=true -Dbell=false -Dmilligrid=false -Dscrews=false 47 | 48 | PCB/Square/Thick.stl: PCB/Square/Square.scad Makefile 49 | /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD $< -o $@ -Dbase=10 -Dthick=3 -Draspox=false -Dspox=true -Dtamper=true -Dbell=false -Dmilligrid=false -Dscrews=true 50 | 51 | -------------------------------------------------------------------------------- /PCB/Makefile: -------------------------------------------------------------------------------- 1 | all: png 2 | 3 | png: $(patsubst %.kicad_pcb,%.png,$(wildcard */*.kicad_pcb)) 4 | 5 | PCBCase/case: PCBCase/case.c 6 | make -C PCBCase 7 | 8 | PCBCase/clean: PCBCase/clean.c 9 | make -C PCBCase 10 | 11 | %.stl: %.scad 12 | echo "Making $@" 13 | /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD $< -o $@ 14 | echo "Made $@" 15 | 16 | %.png: %.kicad_pcb PCBCase/clean PCBCase/render Makefile 17 | PCBCase/render $< 18 | -------------------------------------------------------------------------------- /PCB/Round/.gitignore: -------------------------------------------------------------------------------- 1 | *-backups 2 | *cache* 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /PCB/Round/README.md: -------------------------------------------------------------------------------- 1 | # Round 2 | 3 | These files are for use in [KiCad](https://www.kicad.org). 4 | 5 | ## Trademark 6 | 7 | This is an open source project, but bear in mind you cannot sell boards bearing the Andrews & Arnold Ltd name, the A&A logo, the registered trademark AJK logo, or the GS1 allocated EANs assigned to Andrews & Arnold Ltd. 8 | 9 | ## Images 10 | 11 | 12 | 13 | 14 | *Auto generated 2025-01-19T12:50:51* 15 | -------------------------------------------------------------------------------- /PCB/Round/Round-90.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Round/Round-90.png -------------------------------------------------------------------------------- /PCB/Round/Round-bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Round/Round-bottom.png -------------------------------------------------------------------------------- /PCB/Round/Round-panel-bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Round/Round-panel-bottom.png -------------------------------------------------------------------------------- /PCB/Round/Round-panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Round/Round-panel.png -------------------------------------------------------------------------------- /PCB/Round/Round.kicad_prl: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "active_layer": 0, 4 | "active_layer_preset": "", 5 | "auto_track_width": true, 6 | "hidden_netclasses": [], 7 | "hidden_nets": [], 8 | "high_contrast_mode": 1, 9 | "net_color_mode": 1, 10 | "opacity": { 11 | "images": 0.6, 12 | "pads": 1.0, 13 | "shapes": 1.0, 14 | "tracks": 1.0, 15 | "vias": 1.0, 16 | "zones": 0.6 17 | }, 18 | "ratsnest_display_mode": 0, 19 | "selection_filter": { 20 | "dimensions": true, 21 | "footprints": true, 22 | "graphics": true, 23 | "keepouts": true, 24 | "lockedItems": true, 25 | "otherItems": true, 26 | "pads": true, 27 | "text": true, 28 | "tracks": true, 29 | "vias": true, 30 | "zones": true 31 | }, 32 | "visible_items": [ 33 | 0, 34 | 1, 35 | 2, 36 | 3, 37 | 4, 38 | 5, 39 | 8, 40 | 9, 41 | 10, 42 | 11, 43 | 12, 44 | 13, 45 | 14, 46 | 15, 47 | 16, 48 | 17, 49 | 18, 50 | 19, 51 | 20, 52 | 21, 53 | 22, 54 | 23, 55 | 24, 56 | 25, 57 | 26, 58 | 27, 59 | 28, 60 | 29, 61 | 30, 62 | 32, 63 | 33, 64 | 34, 65 | 35, 66 | 36, 67 | 41 68 | ], 69 | "visible_layers": "0fffffff_ffffffff", 70 | "zone_display_mode": 0 71 | }, 72 | "git": { 73 | "repo_password": "", 74 | "repo_type": "", 75 | "repo_username": "", 76 | "ssh_key": "" 77 | }, 78 | "meta": { 79 | "filename": "Round.kicad_prl", 80 | "version": 4 81 | }, 82 | "net_inspector_panel": { 83 | "col_hidden": [ 84 | false, 85 | false, 86 | false, 87 | false, 88 | false, 89 | false, 90 | false, 91 | false, 92 | false, 93 | false 94 | ], 95 | "col_order": [ 96 | 0, 97 | 1, 98 | 2, 99 | 3, 100 | 4, 101 | 5, 102 | 6, 103 | 7, 104 | 8, 105 | 9 106 | ], 107 | "col_widths": [ 108 | 156, 109 | 141, 110 | 103, 111 | 71, 112 | 103, 113 | 103, 114 | 103, 115 | 74, 116 | 103, 117 | 103 118 | ], 119 | "custom_group_rules": [], 120 | "expanded_rows": [], 121 | "filter_by_net_name": true, 122 | "filter_by_netclass": true, 123 | "filter_text": "", 124 | "group_by_constraint": false, 125 | "group_by_netclass": false, 126 | "show_unconnected_nets": false, 127 | "show_zero_pad_nets": false, 128 | "sort_ascending": true, 129 | "sorting_column": 0 130 | }, 131 | "project": { 132 | "files": [] 133 | }, 134 | "schematic": { 135 | "selection_filter": { 136 | "graphics": true, 137 | "images": true, 138 | "labels": true, 139 | "lockedItems": false, 140 | "otherItems": true, 141 | "pins": true, 142 | "symbols": true, 143 | "text": true, 144 | "wires": true 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /PCB/Round/Round.kicad_pro: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "3dviewports": [], 4 | "design_settings": { 5 | "defaults": { 6 | "apply_defaults_to_fp_fields": false, 7 | "apply_defaults_to_fp_shapes": false, 8 | "apply_defaults_to_fp_text": false, 9 | "board_outline_line_width": 0.05, 10 | "copper_line_width": 0.2, 11 | "copper_text_italic": false, 12 | "copper_text_size_h": 1.5, 13 | "copper_text_size_v": 1.5, 14 | "copper_text_thickness": 0.3, 15 | "copper_text_upright": false, 16 | "courtyard_line_width": 0.05, 17 | "dimension_precision": 4, 18 | "dimension_units": 3, 19 | "dimensions": { 20 | "arrow_length": 1270000, 21 | "extension_offset": 500000, 22 | "keep_text_aligned": true, 23 | "suppress_zeroes": false, 24 | "text_position": 0, 25 | "units_format": 1 26 | }, 27 | "fab_line_width": 0.1, 28 | "fab_text_italic": false, 29 | "fab_text_size_h": 1.0, 30 | "fab_text_size_v": 1.0, 31 | "fab_text_thickness": 0.15, 32 | "fab_text_upright": false, 33 | "other_line_width": 0.1, 34 | "other_text_italic": false, 35 | "other_text_size_h": 1.0, 36 | "other_text_size_v": 1.0, 37 | "other_text_thickness": 0.15, 38 | "other_text_upright": false, 39 | "pads": { 40 | "drill": 1.8, 41 | "height": 1.8, 42 | "width": 1.8 43 | }, 44 | "silk_line_width": 0.12, 45 | "silk_text_italic": false, 46 | "silk_text_size_h": 1.0, 47 | "silk_text_size_v": 1.0, 48 | "silk_text_thickness": 0.15, 49 | "silk_text_upright": false, 50 | "zones": { 51 | "45_degree_only": false, 52 | "min_clearance": 0.25 53 | } 54 | }, 55 | "diff_pair_dimensions": [ 56 | { 57 | "gap": 0.0, 58 | "via_gap": 0.0, 59 | "width": 0.0 60 | } 61 | ], 62 | "drc_exclusions": [], 63 | "meta": { 64 | "filename": "board_design_settings.json", 65 | "version": 2 66 | }, 67 | "rule_severities": { 68 | "annular_width": "error", 69 | "clearance": "error", 70 | "connection_width": "warning", 71 | "copper_edge_clearance": "warning", 72 | "copper_sliver": "warning", 73 | "courtyards_overlap": "error", 74 | "creepage": "error", 75 | "diff_pair_gap_out_of_range": "error", 76 | "diff_pair_uncoupled_length_too_long": "error", 77 | "drill_out_of_range": "error", 78 | "duplicate_footprints": "warning", 79 | "extra_footprint": "warning", 80 | "footprint": "error", 81 | "footprint_filters_mismatch": "ignore", 82 | "footprint_symbol_mismatch": "warning", 83 | "footprint_type_mismatch": "error", 84 | "hole_clearance": "error", 85 | "hole_near_hole": "error", 86 | "hole_to_hole": "warning", 87 | "holes_co_located": "warning", 88 | "invalid_outline": "error", 89 | "isolated_copper": "warning", 90 | "item_on_disabled_layer": "error", 91 | "items_not_allowed": "error", 92 | "length_out_of_range": "error", 93 | "lib_footprint_issues": "warning", 94 | "lib_footprint_mismatch": "warning", 95 | "malformed_courtyard": "error", 96 | "microvia_drill_out_of_range": "error", 97 | "mirrored_text_on_front_layer": "warning", 98 | "missing_courtyard": "ignore", 99 | "missing_footprint": "warning", 100 | "net_conflict": "warning", 101 | "nonmirrored_text_on_back_layer": "warning", 102 | "npth_inside_courtyard": "ignore", 103 | "padstack": "error", 104 | "pth_inside_courtyard": "ignore", 105 | "shorting_items": "error", 106 | "silk_edge_clearance": "warning", 107 | "silk_over_copper": "ignore", 108 | "silk_overlap": "warning", 109 | "skew_out_of_range": "error", 110 | "solder_mask_bridge": "error", 111 | "starved_thermal": "error", 112 | "text_height": "warning", 113 | "text_thickness": "warning", 114 | "through_hole_pad_without_hole": "error", 115 | "too_many_vias": "error", 116 | "track_angle": "error", 117 | "track_dangling": "warning", 118 | "track_segment_length": "error", 119 | "track_width": "error", 120 | "tracks_crossing": "error", 121 | "unconnected_items": "error", 122 | "unresolved_variable": "error", 123 | "via_dangling": "warning", 124 | "zones_intersect": "error" 125 | }, 126 | "rule_severitieslegacy_courtyards_overlap": true, 127 | "rule_severitieslegacy_no_courtyard_defined": false, 128 | "rules": { 129 | "allow_blind_buried_vias": false, 130 | "allow_microvias": false, 131 | "max_error": 0.005, 132 | "min_clearance": 0.125, 133 | "min_connection": 0.0, 134 | "min_copper_edge_clearance": 0.1, 135 | "min_groove_width": 0.0, 136 | "min_hole_clearance": 0.1, 137 | "min_hole_to_hole": 0.2, 138 | "min_microvia_diameter": 0.3, 139 | "min_microvia_drill": 0.2, 140 | "min_resolved_spokes": 1, 141 | "min_silk_clearance": 0.0, 142 | "min_text_height": 0.5, 143 | "min_text_thickness": 0.08, 144 | "min_through_hole_diameter": 0.2, 145 | "min_track_width": 0.125, 146 | "min_via_annular_width": 0.05, 147 | "min_via_diameter": 0.4, 148 | "solder_mask_to_copper_clearance": 0.005, 149 | "use_height_for_length_calcs": true 150 | }, 151 | "teardrop_options": [ 152 | { 153 | "td_onpthpad": true, 154 | "td_onroundshapesonly": false, 155 | "td_onsmdpad": true, 156 | "td_ontrackend": true, 157 | "td_onvia": true 158 | } 159 | ], 160 | "teardrop_parameters": [ 161 | { 162 | "td_allow_use_two_tracks": true, 163 | "td_curve_segcount": 5, 164 | "td_height_ratio": 1.0, 165 | "td_length_ratio": 0.5, 166 | "td_maxheight": 2.0, 167 | "td_maxlen": 1.0, 168 | "td_on_pad_in_zone": true, 169 | "td_target_name": "td_round_shape", 170 | "td_width_to_size_filter_ratio": 0.9 171 | }, 172 | { 173 | "td_allow_use_two_tracks": true, 174 | "td_curve_segcount": 5, 175 | "td_height_ratio": 1.0, 176 | "td_length_ratio": 0.5, 177 | "td_maxheight": 2.0, 178 | "td_maxlen": 1.0, 179 | "td_on_pad_in_zone": true, 180 | "td_target_name": "td_rect_shape", 181 | "td_width_to_size_filter_ratio": 0.9 182 | }, 183 | { 184 | "td_allow_use_two_tracks": true, 185 | "td_curve_segcount": 5, 186 | "td_height_ratio": 1.0, 187 | "td_length_ratio": 0.5, 188 | "td_maxheight": 2.0, 189 | "td_maxlen": 1.0, 190 | "td_on_pad_in_zone": true, 191 | "td_target_name": "td_track_end", 192 | "td_width_to_size_filter_ratio": 0.9 193 | } 194 | ], 195 | "track_widths": [ 196 | 0.0, 197 | 0.125, 198 | 0.2, 199 | 0.25, 200 | 0.3, 201 | 0.5 202 | ], 203 | "tuning_pattern_settings": { 204 | "diff_pair_defaults": { 205 | "corner_radius_percentage": 80, 206 | "corner_style": 1, 207 | "max_amplitude": 1.0, 208 | "min_amplitude": 0.2, 209 | "single_sided": false, 210 | "spacing": 1.0 211 | }, 212 | "diff_pair_skew_defaults": { 213 | "corner_radius_percentage": 80, 214 | "corner_style": 1, 215 | "max_amplitude": 1.0, 216 | "min_amplitude": 0.2, 217 | "single_sided": false, 218 | "spacing": 0.6 219 | }, 220 | "single_track_defaults": { 221 | "corner_radius_percentage": 80, 222 | "corner_style": 1, 223 | "max_amplitude": 1.0, 224 | "min_amplitude": 0.2, 225 | "single_sided": false, 226 | "spacing": 0.6 227 | } 228 | }, 229 | "via_dimensions": [ 230 | { 231 | "diameter": 0.0, 232 | "drill": 0.0 233 | } 234 | ], 235 | "zones_allow_external_fillets": false, 236 | "zones_use_no_outline": true 237 | }, 238 | "ipc2581": { 239 | "dist": "", 240 | "distpn": "", 241 | "internal_id": "", 242 | "mfg": "", 243 | "mpn": "" 244 | }, 245 | "layer_pairs": [], 246 | "layer_presets": [], 247 | "viewports": [] 248 | }, 249 | "boards": [], 250 | "cvpcb": { 251 | "equivalence_files": [] 252 | }, 253 | "erc": { 254 | "erc_exclusions": [], 255 | "meta": { 256 | "version": 0 257 | }, 258 | "pin_map": [ 259 | [ 260 | 0, 261 | 0, 262 | 0, 263 | 0, 264 | 0, 265 | 0, 266 | 1, 267 | 0, 268 | 0, 269 | 0, 270 | 0, 271 | 2 272 | ], 273 | [ 274 | 0, 275 | 2, 276 | 0, 277 | 1, 278 | 0, 279 | 0, 280 | 1, 281 | 0, 282 | 2, 283 | 2, 284 | 2, 285 | 2 286 | ], 287 | [ 288 | 0, 289 | 0, 290 | 0, 291 | 0, 292 | 0, 293 | 0, 294 | 1, 295 | 0, 296 | 1, 297 | 0, 298 | 1, 299 | 2 300 | ], 301 | [ 302 | 0, 303 | 1, 304 | 0, 305 | 0, 306 | 0, 307 | 0, 308 | 1, 309 | 1, 310 | 2, 311 | 1, 312 | 1, 313 | 2 314 | ], 315 | [ 316 | 0, 317 | 0, 318 | 0, 319 | 0, 320 | 0, 321 | 0, 322 | 1, 323 | 0, 324 | 0, 325 | 0, 326 | 0, 327 | 2 328 | ], 329 | [ 330 | 0, 331 | 0, 332 | 0, 333 | 0, 334 | 0, 335 | 0, 336 | 0, 337 | 0, 338 | 0, 339 | 0, 340 | 0, 341 | 2 342 | ], 343 | [ 344 | 1, 345 | 1, 346 | 1, 347 | 1, 348 | 1, 349 | 0, 350 | 1, 351 | 1, 352 | 1, 353 | 1, 354 | 1, 355 | 2 356 | ], 357 | [ 358 | 0, 359 | 0, 360 | 0, 361 | 1, 362 | 0, 363 | 0, 364 | 1, 365 | 0, 366 | 0, 367 | 0, 368 | 0, 369 | 2 370 | ], 371 | [ 372 | 0, 373 | 2, 374 | 1, 375 | 2, 376 | 0, 377 | 0, 378 | 1, 379 | 0, 380 | 2, 381 | 2, 382 | 2, 383 | 2 384 | ], 385 | [ 386 | 0, 387 | 2, 388 | 0, 389 | 1, 390 | 0, 391 | 0, 392 | 1, 393 | 0, 394 | 2, 395 | 0, 396 | 0, 397 | 2 398 | ], 399 | [ 400 | 0, 401 | 2, 402 | 1, 403 | 1, 404 | 0, 405 | 0, 406 | 1, 407 | 0, 408 | 2, 409 | 0, 410 | 0, 411 | 2 412 | ], 413 | [ 414 | 2, 415 | 2, 416 | 2, 417 | 2, 418 | 2, 419 | 2, 420 | 2, 421 | 2, 422 | 2, 423 | 2, 424 | 2, 425 | 2 426 | ] 427 | ], 428 | "rule_severities": { 429 | "bus_definition_conflict": "error", 430 | "bus_entry_needed": "error", 431 | "bus_to_bus_conflict": "error", 432 | "bus_to_net_conflict": "error", 433 | "conflicting_netclasses": "error", 434 | "different_unit_footprint": "error", 435 | "different_unit_net": "error", 436 | "duplicate_reference": "error", 437 | "duplicate_sheet_names": "error", 438 | "endpoint_off_grid": "warning", 439 | "extra_units": "error", 440 | "footprint_filter": "ignore", 441 | "footprint_link_issues": "warning", 442 | "four_way_junction": "ignore", 443 | "global_label_dangling": "warning", 444 | "hier_label_mismatch": "error", 445 | "label_dangling": "error", 446 | "label_multiple_wires": "warning", 447 | "lib_symbol_issues": "warning", 448 | "lib_symbol_mismatch": "warning", 449 | "missing_bidi_pin": "warning", 450 | "missing_input_pin": "warning", 451 | "missing_power_pin": "error", 452 | "missing_unit": "warning", 453 | "multiple_net_names": "warning", 454 | "net_not_bus_member": "warning", 455 | "no_connect_connected": "warning", 456 | "no_connect_dangling": "warning", 457 | "pin_not_connected": "error", 458 | "pin_not_driven": "error", 459 | "pin_to_pin": "warning", 460 | "power_pin_not_driven": "error", 461 | "same_local_global_label": "warning", 462 | "similar_label_and_power": "warning", 463 | "similar_labels": "warning", 464 | "similar_power": "warning", 465 | "simulation_model_issue": "ignore", 466 | "single_global_label": "ignore", 467 | "unannotated": "error", 468 | "unconnected_wire_endpoint": "warning", 469 | "unit_value_mismatch": "error", 470 | "unresolved_variable": "error", 471 | "wire_dangling": "error" 472 | } 473 | }, 474 | "libraries": { 475 | "pinned_footprint_libs": [], 476 | "pinned_symbol_libs": [] 477 | }, 478 | "meta": { 479 | "filename": "Round.kicad_pro", 480 | "version": 2 481 | }, 482 | "net_settings": { 483 | "classes": [ 484 | { 485 | "bus_width": 12, 486 | "clearance": 0.125, 487 | "diff_pair_gap": 0.25, 488 | "diff_pair_via_gap": 0.25, 489 | "diff_pair_width": 0.2, 490 | "line_style": 0, 491 | "microvia_diameter": 0.3, 492 | "microvia_drill": 0.1, 493 | "name": "Default", 494 | "pcb_color": "rgba(0, 0, 0, 0.000)", 495 | "priority": 2147483647, 496 | "schematic_color": "rgba(0, 0, 0, 0.000)", 497 | "track_width": 0.125, 498 | "via_diameter": 0.8, 499 | "via_drill": 0.4, 500 | "wire_width": 6 501 | }, 502 | { 503 | "bus_width": 12, 504 | "clearance": 0.125, 505 | "diff_pair_gap": 0.25, 506 | "diff_pair_via_gap": 0.25, 507 | "diff_pair_width": 0.2, 508 | "line_style": 0, 509 | "microvia_diameter": 0.3, 510 | "microvia_drill": 0.1, 511 | "name": "Power", 512 | "pcb_color": "rgba(0, 0, 0, 0.000)", 513 | "priority": 0, 514 | "schematic_color": "rgba(0, 0, 0, 0.000)", 515 | "track_width": 0.25, 516 | "via_diameter": 0.8, 517 | "via_drill": 0.4, 518 | "wire_width": 6 519 | } 520 | ], 521 | "meta": { 522 | "version": 4 523 | }, 524 | "net_colors": null, 525 | "netclass_assignments": null, 526 | "netclass_patterns": [ 527 | { 528 | "netclass": "Power", 529 | "pattern": "GND" 530 | }, 531 | { 532 | "netclass": "Power", 533 | "pattern": "5V" 534 | } 535 | ] 536 | }, 537 | "pcbnew": { 538 | "last_paths": { 539 | "gencad": "", 540 | "idf": "", 541 | "netlist": "", 542 | "plot": "", 543 | "pos_files": "", 544 | "specctra_dsn": "", 545 | "step": "", 546 | "svg": "", 547 | "vrml": "" 548 | }, 549 | "page_layout_descr_file": "" 550 | }, 551 | "schematic": { 552 | "annotate_start_num": 0, 553 | "bom_export_filename": "", 554 | "bom_fmt_presets": [], 555 | "bom_fmt_settings": { 556 | "field_delimiter": ",", 557 | "keep_line_breaks": false, 558 | "keep_tabs": false, 559 | "name": "CSV", 560 | "ref_delimiter": ",", 561 | "ref_range_delimiter": "", 562 | "string_delimiter": "\"" 563 | }, 564 | "bom_presets": [], 565 | "bom_settings": { 566 | "exclude_dnp": false, 567 | "fields_ordered": [ 568 | { 569 | "group_by": false, 570 | "label": "Reference", 571 | "name": "Reference", 572 | "show": true 573 | }, 574 | { 575 | "group_by": true, 576 | "label": "Value", 577 | "name": "Value", 578 | "show": true 579 | }, 580 | { 581 | "group_by": false, 582 | "label": "Datasheet", 583 | "name": "Datasheet", 584 | "show": true 585 | }, 586 | { 587 | "group_by": false, 588 | "label": "Footprint", 589 | "name": "Footprint", 590 | "show": true 591 | }, 592 | { 593 | "group_by": false, 594 | "label": "Qty", 595 | "name": "${QUANTITY}", 596 | "show": true 597 | }, 598 | { 599 | "group_by": true, 600 | "label": "DNP", 601 | "name": "${DNP}", 602 | "show": true 603 | } 604 | ], 605 | "filter_string": "", 606 | "group_symbols": true, 607 | "include_excluded_from_bom": false, 608 | "name": "Grouped By Value", 609 | "sort_asc": true, 610 | "sort_field": "Reference" 611 | }, 612 | "connection_grid_size": 50.0, 613 | "drawing": { 614 | "dashed_lines_dash_length_ratio": 12.0, 615 | "dashed_lines_gap_length_ratio": 3.0, 616 | "default_line_thickness": 6.0, 617 | "default_text_size": 50.0, 618 | "field_names": [], 619 | "intersheets_ref_own_page": false, 620 | "intersheets_ref_prefix": "", 621 | "intersheets_ref_short": false, 622 | "intersheets_ref_show": false, 623 | "intersheets_ref_suffix": "", 624 | "junction_size_choice": 3, 625 | "label_size_ratio": 0.25, 626 | "operating_point_overlay_i_precision": 3, 627 | "operating_point_overlay_i_range": "~A", 628 | "operating_point_overlay_v_precision": 3, 629 | "operating_point_overlay_v_range": "~V", 630 | "overbar_offset_ratio": 1.23, 631 | "pin_symbol_size": 25.0, 632 | "text_offset_ratio": 0.08 633 | }, 634 | "legacy_lib_dir": "", 635 | "legacy_lib_list": [], 636 | "meta": { 637 | "version": 1 638 | }, 639 | "net_format_name": "", 640 | "ngspice": { 641 | "fix_include_paths": true, 642 | "fix_passive_vals": false, 643 | "meta": { 644 | "version": 0 645 | }, 646 | "model_mode": 0, 647 | "workbook_filename": "" 648 | }, 649 | "page_layout_descr_file": "", 650 | "plot_directory": "", 651 | "space_save_all_events": true, 652 | "spice_adjust_passive_values": false, 653 | "spice_current_sheet_as_root": false, 654 | "spice_external_command": "spice \"%I\"", 655 | "spice_model_current_sheet_as_root": true, 656 | "spice_save_all_currents": false, 657 | "spice_save_all_dissipations": false, 658 | "spice_save_all_voltages": false, 659 | "subpart_first_id": 65, 660 | "subpart_id_separator": 0 661 | }, 662 | "sheets": [ 663 | [ 664 | "0217dfc4-fc13-4699-99ad-d9948522648e", 665 | "Root" 666 | ] 667 | ], 668 | "text_variables": { 669 | "DATE": "2023-03-22" 670 | } 671 | } 672 | -------------------------------------------------------------------------------- /PCB/Round/Round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Round/Round.png -------------------------------------------------------------------------------- /PCB/Round/Round.scad: -------------------------------------------------------------------------------- 1 | // Generated case design for PCB/Round/Round.kicad_pcb 2 | // By https://github.com/revk/PCBCase 3 | // Generated 2023-07-01 11:21:10 4 | // title: PN532 NFC reader (HSU) 5 | // date: ${DATE} 6 | // rev: 7 7 | // company: Adrian Kennard Andrews & Arnold Ltd 8 | // comment: www.m.euk 9 | // 10 | 11 | // Globals 12 | margin=0.500000; 13 | overlap=2.000000; 14 | lip=0.000000; 15 | casebase=0.800000; 16 | casetop=2.500000; 17 | casewall=3.000000; 18 | fit=0.000000; 19 | edge=1.000000; 20 | pcbthickness=0.800000; 21 | nohull=false; 22 | hullcap=1.000000; 23 | hulledge=1.000000; 24 | useredge=false; 25 | 26 | module outline(h=pcbthickness,r=0){linear_extrude(height=h)offset(r=r)polygon(points=[[46.000000,23.000000],[45.961088,21.662669],[45.844482,20.329863],[45.650578,19.006092],[45.380032,17.695835],[45.033759,16.403526],[44.612930,15.133537],[44.118970,13.890165],[43.553551,12.677619],[42.918584,11.500000],[42.216220,10.361294],[41.448833,9.265352],[40.619022,8.215885],[39.729594,7.216442],[38.783558,6.270406],[37.784115,5.380978],[36.734648,4.551167],[35.638706,3.783780],[34.500000,3.081416],[33.322381,2.446449],[32.109835,1.881030],[30.866463,1.387070],[29.596474,0.966241],[28.304165,0.619968],[26.993908,0.349422],[25.670137,0.155518],[24.337331,0.038912],[23.000000,0.000000],[21.662669,0.038912],[20.329863,0.155518],[19.006092,0.349422],[17.695835,0.619968],[16.403526,0.966241],[15.133537,1.387070],[13.890165,1.881030],[12.677619,2.446449],[11.500000,3.081416],[10.361294,3.783780],[9.265352,4.551167],[8.215885,5.380978],[7.216442,6.270406],[6.270406,7.216442],[5.380978,8.215885],[4.551167,9.265352],[3.783780,10.361294],[3.081416,11.500000],[2.446449,12.677619],[1.881030,13.890165],[1.387070,15.133537],[0.966241,16.403526],[0.619968,17.695835],[0.349422,19.006092],[0.155518,20.329863],[0.038912,21.662669],[0.000000,23.000000],[0.038912,24.337331],[0.155518,25.670137],[0.349422,26.993908],[0.619968,28.304165],[0.966241,29.596474],[1.387070,30.866463],[1.881030,32.109835],[2.446449,33.322381],[3.081416,34.500000],[3.783780,35.638706],[4.551167,36.734648],[5.380978,37.784115],[6.270406,38.783558],[7.216442,39.729594],[8.215885,40.619022],[9.265352,41.448833],[10.361294,42.216220],[11.500000,42.918584],[12.677619,43.553551],[13.890165,44.118970],[15.133537,44.612930],[16.403526,45.033759],[17.695835,45.380032],[19.006092,45.650578],[20.329863,45.844482],[21.662669,45.961088],[23.000000,46.000000],[24.337331,45.961088],[25.670137,45.844482],[26.993908,45.650578],[28.304165,45.380032],[29.596474,45.033759],[30.866463,44.612930],[32.109835,44.118970],[33.322381,43.553551],[34.500000,42.918584],[35.638706,42.216220],[36.734648,41.448833],[37.784115,40.619022],[38.783558,39.729594],[39.729594,38.783558],[40.619022,37.784115],[41.448833,36.734648],[42.216220,35.638706],[42.918584,34.500000],[43.553551,33.322381],[44.118970,32.109835],[44.612930,30.866463],[45.033759,29.596474],[45.380032,28.304165],[45.650578,26.993908],[45.844482,25.670137],[45.961088,24.337331]],paths=[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107]]);} 27 | 28 | module pcb(h=pcbthickness,r=0){linear_extrude(height=h)offset(r=r)polygon(points=[[46.000000,23.000000],[45.961088,21.662669],[45.844482,20.329863],[45.650578,19.006092],[45.380032,17.695835],[45.033759,16.403526],[44.612930,15.133537],[44.118970,13.890165],[43.553551,12.677619],[42.918584,11.500000],[42.216220,10.361294],[41.448833,9.265352],[40.619022,8.215885],[39.729594,7.216442],[38.783558,6.270406],[37.784115,5.380978],[36.734648,4.551167],[35.638706,3.783780],[34.500000,3.081416],[33.322381,2.446449],[32.109835,1.881030],[30.866463,1.387070],[29.596474,0.966241],[28.304165,0.619968],[26.993908,0.349422],[25.670137,0.155518],[24.337331,0.038912],[23.000000,0.000000],[21.662669,0.038912],[20.329863,0.155518],[19.006092,0.349422],[17.695835,0.619968],[16.403526,0.966241],[15.133537,1.387070],[13.890165,1.881030],[12.677619,2.446449],[11.500000,3.081416],[10.361294,3.783780],[9.265352,4.551167],[8.215885,5.380978],[7.216442,6.270406],[6.270406,7.216442],[5.380978,8.215885],[4.551167,9.265352],[3.783780,10.361294],[3.081416,11.500000],[2.446449,12.677619],[1.881030,13.890165],[1.387070,15.133537],[0.966241,16.403526],[0.619968,17.695835],[0.349422,19.006092],[0.155518,20.329863],[0.038912,21.662669],[0.000000,23.000000],[0.038912,24.337331],[0.155518,25.670137],[0.349422,26.993908],[0.619968,28.304165],[0.966241,29.596474],[1.387070,30.866463],[1.881030,32.109835],[2.446449,33.322381],[3.081416,34.500000],[3.783780,35.638706],[4.551167,36.734648],[5.380978,37.784115],[6.270406,38.783558],[7.216442,39.729594],[8.215885,40.619022],[9.265352,41.448833],[10.361294,42.216220],[11.500000,42.918584],[12.677619,43.553551],[13.890165,44.118970],[15.133537,44.612930],[16.403526,45.033759],[17.695835,45.380032],[19.006092,45.650578],[20.329863,45.844482],[21.662669,45.961088],[23.000000,46.000000],[24.337331,45.961088],[25.670137,45.844482],[26.993908,45.650578],[28.304165,45.380032],[29.596474,45.033759],[30.866463,44.612930],[32.109835,44.118970],[33.322381,43.553551],[34.500000,42.918584],[35.638706,42.216220],[36.734648,41.448833],[37.784115,40.619022],[38.783558,39.729594],[39.729594,38.783558],[40.619022,37.784115],[41.448833,36.734648],[42.216220,35.638706],[42.918584,34.500000],[43.553551,33.322381],[44.118970,32.109835],[44.612930,30.866463],[45.033759,29.596474],[45.380032,28.304165],[45.650578,26.993908],[45.844482,25.670137],[45.961088,24.337331]],paths=[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107]]);} 29 | spacing=62.000000; 30 | pcbwidth=46.000000; 31 | pcblength=46.000000; 32 | // Populated PCB 33 | module board(pushed=false,hulled=false){ 34 | translate([16.875000,26.440000,0.800000])rotate([0,0,90.000000])m2(pushed,hulled); // RevK:Crystal-3.2x2.5 Crystal_SMD_Abracon_ABM8G-4Pin_3.2x2.5mm (back) 35 | // Missing D2.1 LED_1206_3216Metric_Castellated 36 | // Missing D3.1 LED_1206_3216Metric_Castellated 37 | translate([12.800000,23.000000,0.800000])rotate([0,0,180.000000])translate([2.050000,0.000000,1.150000])rotate([-0.000000,-0.000000,-90.000000])m7(pushed,hulled); // RevK:ESE13 ESE13V01D (back) 38 | // Missing D1.1 LED_1206_3216Metric_Castellated 39 | translate([24.375000,31.240000,0.800000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 40 | translate([26.800000,39.350000,0.800000])rotate([0,0,90.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 41 | translate([24.700000,38.600000,0.800000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 42 | translate([32.000000,30.640000,0.800000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back) 43 | translate([16.900000,38.600000,0.800000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back) 44 | translate([29.150000,26.840000,0.800000])rotate([0,0,-90.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 45 | translate([28.400000,29.140000,0.800000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 46 | translate([16.875000,31.690000,0.800000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 47 | translate([16.875000,28.940000,0.800000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 48 | translate([32.000000,26.140000,0.800000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back) 49 | translate([32.000000,24.640000,0.800000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back) 50 | translate([22.300000,21.290000,0.800000])rotate([0,0,90.000000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back) 51 | translate([23.000000,26.440000,0.800000])rotate([0,0,-90.000000])m14(pushed,hulled); // RevK:QFN-40-1EP_6x6mm_P0.5mm_EP4.6x4.6mm QFN-40-1EP_6x6mm_P0.5mm_EP4.6x4.6mm (back) 52 | translate([16.875000,23.940000,0.800000])rotate([0,0,180.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 53 | translate([21.625000,32.590000,0.800000])rotate([0,0,180.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 54 | translate([16.100000,33.590000,0.800000])rotate([0,0,-90.000000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back) 55 | translate([32.000000,29.140000,0.800000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back) 56 | translate([32.000000,27.640000,0.800000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back) 57 | translate([20.700000,21.290000,0.800000])rotate([0,0,90.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 58 | translate([27.650000,26.840000,0.800000])rotate([0,0,-90.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 59 | translate([16.100000,36.240000,0.800000])rotate([0,0,90.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 60 | translate([24.270000,16.500000,0.800000])rotate([0,0,90.000000])m16(pushed,hulled,5); // RevK:PinHeader_1x05_P2.54mm_Vertical_SMD_Pin1Left PinHeader_1x05_P2.54mm_Vertical_SMD_Pin1Left (back) 61 | translate([24.375000,32.590000,0.800000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 62 | translate([24.700000,40.135000,0.800000])rotate([0,0,180.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 63 | translate([21.300000,38.600000,0.800000])rotate([0,0,180.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 64 | translate([28.600000,21.290000,0.800000])rotate([0,0,90.000000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back) 65 | translate([24.650000,20.540000,0.800000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back) 66 | translate([16.875000,30.340000,0.800000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 67 | translate([24.650000,22.040000,0.800000])rotate([0,0,180.000000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back) 68 | translate([26.250000,35.440000,0.800000])rotate([0,0,45.000000])m18(pushed,hulled); // Inductor_SMD:L_1008_2520Metric L_1008_2520Metric (back) 69 | translate([19.750000,35.440000,0.800000])rotate([0,0,-45.000000])m18(pushed,hulled); // Inductor_SMD:L_1008_2520Metric L_1008_2520Metric (back) 70 | translate([19.200000,39.350000,0.800000])rotate([0,0,-90.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 71 | translate([27.000000,21.290000,0.800000])rotate([0,0,-90.000000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back) 72 | translate([32.000000,32.540000,0.800000])m19(pushed,hulled); // RevK:SOT-363_SC-70-6 SOT-363_SC-70-6 (back) 73 | translate([32.000000,18.240000,0.800000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 74 | translate([32.000000,22.740000,0.800000])m19(pushed,hulled); // RevK:SOT-363_SC-70-6 SOT-363_SC-70-6 (back) 75 | translate([32.000000,20.140000,0.800000])rotate([0,0,180.000000])m19(pushed,hulled); // RevK:SOT-363_SC-70-6 SOT-363_SC-70-6 (back) 76 | translate([21.300000,40.135000,0.800000])rotate([0,0,180.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back) 77 | translate([23.000000,44.410000,0.800000])rotate([0,0,90.000000])m25(pushed,hulled); // RevK:R_0805_ R_0805_2012Metric (back) 78 | translate([24.770000,42.510000,0.800000])rotate([0,0,90.000000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back) 79 | translate([21.230000,42.510000,0.800000])rotate([0,0,90.000000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back) 80 | translate([23.000000,23.000000,0.800000])translate([9.000000,14.000000,0.500000])scale([0.580000,0.580000,0.580000])rotate([-0.000000,90.000000,35.000000])m29(pushed,hulled); // RevK:PN532-Antenna6 653612 (back) 81 | translate([23.000000,23.000000,0.800000])translate([9.000000,-14.000000,0.500000])scale([0.580000,0.580000,0.580000])rotate([-0.000000,90.000000,-35.000000])m29(pushed,hulled); // RevK:PN532-Antenna6 653612 (back) 82 | translate([23.000000,23.000000,0.800000])translate([-12.000000,0.000000,1.300000])scale([0.580000,0.580000,0.580000])rotate([-0.000000,90.000000,-90.000000])m29(pushed,hulled); // RevK:PN532-Antenna6 653612 (back) 83 | } 84 | 85 | module b(cx,cy,z,w,l,h){translate([cx-w/2,cy-l/2,z])cube([w,l,h]);} 86 | module m2(pushed=false,hulled=false) 87 | { // RevK:Crystal-3.2x2.5 Crystal_SMD_Abracon_ABM8G-4Pin_3.2x2.5mm 88 | cube([3.2,2.5,1],center=true); 89 | } 90 | 91 | module m7(pushed=false,hulled=false) 92 | { // RevK:ESE13 ESE13V01D 93 | if(!hulled&&pushed) translate([0,2.05,-1.15]) 94 | { 95 | b(0,0,0,3.6+0.4,4.2+0.4,1.2); 96 | b(0,-3.08,0,1.2+0.4,1.95+0.4,0.9); 97 | } 98 | 99 | } 100 | 101 | module m10(pushed=false,hulled=false) 102 | { // RevK:C_0603 C_0603_1608Metric 103 | b(0,0,0,1.6,0.95,0.2); // Pad size 104 | b(0,0,0,1.6,0.8,1); // Chip 105 | } 106 | 107 | module m13(pushed=false,hulled=false) 108 | { // RevK:R_0603 R_0603_1608Metric 109 | b(0,0,0,1.6,0.95,0.2); // Pad size 110 | b(0,0,0,1.6,0.8,0.5); // Chip 111 | } 112 | 113 | module m14(pushed=false,hulled=false) 114 | { // RevK:QFN-40-1EP_6x6mm_P0.5mm_EP4.6x4.6mm QFN-40-1EP_6x6mm_P0.5mm_EP4.6x4.6mm 115 | cube([4.6,4.6,1],center=true); 116 | } 117 | 118 | module m16(pushed=false,hulled=false,n=0) 119 | { // RevK:PinHeader_1x05_P2.54mm_Vertical_SMD_Pin1Left PinHeader_1x05_P2.54mm_Vertical_SMD_Pin1Left 120 | b(0,0,0,5.08,2.54*n,0.5); 121 | if(!hulled&&!pushed) 122 | { 123 | b(0,0,0,2.54,2.54*n,2.54); 124 | b(0,0,0,0.5,2.54*(n-1)+0.5,10); 125 | translate([0,0,4])b(0,0,0,5.08,n*2.54,100); 126 | } 127 | } 128 | 129 | module m18(pushed=false,hulled=false) 130 | { // Inductor_SMD:L_1008_2520Metric L_1008_2520Metric 131 | b(0,0,0,2.62,2.45,1.83); // Pad size 132 | } 133 | 134 | module m19(pushed=false,hulled=false) 135 | { // RevK:SOT-363_SC-70-6 SOT-363_SC-70-6 136 | b(0,0,0,1.15,2.0,1.1); 137 | b(0,0,0,2.1,2.0,0.6); 138 | } 139 | 140 | module m25(pushed=false,hulled=false) 141 | { // RevK:R_0805_ R_0805_2012Metric 142 | b(0,0,0,2,1.45,0.2); // Pad size 143 | b(0,0,0,2,1.2,0.5); // Chip 144 | } 145 | 146 | module m29(pushed=false,hulled=false) 147 | { // RevK:PN532-Antenna6 653612 148 | // Screw 6mm 149 | if(!hulled&&!pushed) 150 | rotate([0,-90,0],$fn=24) 151 | { 152 | hull()for(x=[-1,1])translate([x,0,-2])cylinder(d=12,h=2); 153 | hull()for(x=[-1,1])translate([x,0,0])cylinder(d1=12,d2=6,h=3); 154 | hull()for(x=[-1,1])translate([x,0,0])cylinder(d=6,h=100); 155 | } 156 | 157 | } 158 | 159 | height=casebase+pcbthickness+casetop; 160 | $fn=48; 161 | 162 | module boardh(pushed=false) 163 | { // Board with hulled parts 164 | union() 165 | { 166 | if(!nohull)intersection() 167 | { 168 | translate([0,0,hullcap-casebase])outline(casebase+pcbthickness+casetop-hullcap*2,-hulledge); 169 | hull()board(pushed,true); 170 | } 171 | board(pushed,false); 172 | pcb(); 173 | } 174 | } 175 | 176 | module boardf() 177 | { // This is the board, but stretched up to make a push out in from the front 178 | render() 179 | { 180 | intersection() 181 | { 182 | translate([-casewall-1,-casewall-1,-casebase-1]) cube([pcbwidth+casewall*2+2,pcblength+casewall*2+2,height+2]); 183 | union() 184 | { 185 | minkowski() 186 | { 187 | boardh(true); 188 | cylinder(h=height+100,d=margin,$fn=8); 189 | } 190 | board(false,false); 191 | } 192 | } 193 | } 194 | } 195 | 196 | module boardb() 197 | { // This is the board, but stretched down to make a push out in from the back 198 | render() 199 | { 200 | intersection() 201 | { 202 | translate([-casewall-1,-casewall-1,-casebase-1]) cube([pcbwidth+casewall*2+2,pcblength+casewall*2+2,height+2]); 203 | union() 204 | { 205 | minkowski() 206 | { 207 | boardh(true); 208 | translate([0,0,-height-100]) 209 | cylinder(h=height+100,d=margin,$fn=8); 210 | } 211 | board(false,false); 212 | } 213 | } 214 | } 215 | } 216 | 217 | module boardm() 218 | { 219 | render() 220 | { 221 | minkowski() 222 | { 223 | translate([0,0,-margin/2])cylinder(d=margin,h=margin,$fn=8); 224 | boardh(false); 225 | } 226 | //intersection() 227 | //{ 228 | //translate([0,0,-(casebase-hullcap)])pcb(pcbthickness+(casebase-hullcap)+(casetop-hullcap)); 229 | //translate([0,0,-(casebase-hullcap)])outline(pcbthickness+(casebase-hullcap)+(casetop-hullcap)); 230 | boardh(false); 231 | //} 232 | } 233 | } 234 | 235 | module pcbh(h=pcbthickness,r=0) 236 | { // PCB shape for case 237 | if(useredge)outline(h,r); 238 | else hull()outline(h,r); 239 | } 240 | 241 | module pyramid() 242 | { // A pyramid 243 | polyhedron(points=[[0,0,0],[-height,-height,height],[-height,height,height],[height,height,height],[height,-height,height]],faces=[[0,1,2],[0,2,3],[0,3,4],[0,4,1],[4,3,2,1]]); 244 | } 245 | 246 | module wall(d=0) 247 | { // The case wall 248 | translate([0,0,-casebase-d]) 249 | { 250 | if(useredge) 251 | intersection() 252 | { 253 | pcb(height+d*2,margin/2+d); 254 | pcbh(height+d*2,margin/2+d); 255 | } 256 | else pcbh(height+d*2,margin/2+d); 257 | } 258 | } 259 | 260 | module cutf() 261 | { // This cut up from base in the wall 262 | intersection() 263 | { 264 | boardf(); 265 | difference() 266 | { 267 | translate([-casewall+0.01,-casewall+0.01,-casebase+0.01])cube([pcbwidth+casewall*2-0.02,pcblength+casewall*2-0.02,casebase+overlap+lip]); 268 | wall(); 269 | boardb(); 270 | } 271 | } 272 | } 273 | 274 | module cutb() 275 | { // The cut down from top in the wall 276 | intersection() 277 | { 278 | boardb(); 279 | difference() 280 | { 281 | translate([-casewall+0.01,-casewall+0.01,0.01])cube([pcbwidth+casewall*2-0.02,pcblength+casewall*2-0.02,casetop+pcbthickness]); 282 | wall(); 283 | boardf(); 284 | } 285 | } 286 | } 287 | 288 | module cutpf() 289 | { // the push up but pyramid 290 | render() 291 | intersection() 292 | { 293 | minkowski() 294 | { 295 | pyramid(); 296 | cutf(); 297 | } 298 | difference() 299 | { 300 | translate([-casewall-0.01,-casewall-0.01,-casebase-0.01])cube([pcbwidth+casewall*2+0.02,pcblength+casewall*2+0.02,casebase+overlap+lip+0.02]); 301 | wall(); 302 | boardh(true); 303 | } 304 | translate([-casewall,-casewall,-casebase])case(); 305 | } 306 | } 307 | 308 | module cutpb() 309 | { // the push down but pyramid 310 | render() 311 | intersection() 312 | { 313 | minkowski() 314 | { 315 | scale([1,1,-1])pyramid(); 316 | cutb(); 317 | } 318 | difference() 319 | { 320 | translate([-casewall-0.01,-casewall-0.01,-0.01])cube([pcbwidth+casewall*2+0.02,pcblength+casewall*2+0.02,casetop+pcbthickness+0.02]); 321 | wall(); 322 | boardh(true); 323 | } 324 | translate([-casewall,-casewall,-casebase])case(); 325 | } 326 | } 327 | 328 | module case() 329 | { // The basic case 330 | hull() 331 | { 332 | translate([casewall,casewall,0])pcbh(height,casewall-edge); 333 | translate([casewall,casewall,edge])pcbh(height-edge*2,casewall); 334 | } 335 | } 336 | 337 | module cut(d=0) 338 | { // The cut point in the wall 339 | translate([casewall,casewall,casebase+lip])pcbh(casetop+pcbthickness-lip+1,casewall/2+d/2+margin/4); 340 | } 341 | 342 | module base() 343 | { // The base 344 | difference() 345 | { 346 | case(); 347 | difference() 348 | { 349 | union() 350 | { 351 | translate([-1,-1,casebase+overlap+lip])cube([pcbwidth+casewall*2+2,pcblength+casewall*2+2,casetop+1]); 352 | cut(fit); 353 | } 354 | } 355 | translate([casewall,casewall,casebase])boardf(); 356 | translate([casewall,casewall,casebase])boardm(); 357 | translate([casewall,casewall,casebase])cutpf(); 358 | } 359 | translate([casewall,casewall,casebase])cutpb(); 360 | } 361 | 362 | module top() 363 | { 364 | translate([0,pcblength+casewall*2,height])rotate([180,0,0]) 365 | { 366 | difference() 367 | { 368 | case(); 369 | difference() 370 | { 371 | translate([-1,-1,-1])cube([pcbwidth+casewall*2+2,pcblength+casewall*2+2,casebase+overlap+lip-margin+1]); 372 | cut(-fit); 373 | } 374 | translate([casewall,casewall,casebase])boardb(); 375 | translate([casewall,casewall,casebase])boardm(); 376 | translate([casewall,casewall,casebase])cutpb(); 377 | } 378 | translate([casewall,casewall,casebase])cutpf(); 379 | } 380 | } 381 | 382 | module test() 383 | { 384 | translate([0*spacing,0,0])base(); 385 | translate([1*spacing,0,0])top(); 386 | translate([2*spacing,0,0])pcb(); 387 | translate([3*spacing,0,0])outline(); 388 | translate([4*spacing,0,0])wall(); 389 | translate([5*spacing,0,0])board(); 390 | translate([6*spacing,0,0])board(false,true); 391 | translate([7*spacing,0,0])board(true); 392 | translate([8*spacing,0,0])boardh(); 393 | translate([9*spacing,0,0])boardf(); 394 | translate([10*spacing,0,0])boardb(); 395 | translate([11*spacing,0,0])cutpf(); 396 | translate([12*spacing,0,0])cutpb(); 397 | translate([13*spacing,0,0])cutf(); 398 | translate([14*spacing,0,0])cutb(); 399 | translate([15*spacing,0,0])case(); 400 | } 401 | 402 | module parts() 403 | { 404 | base(); 405 | translate([spacing,0,0])top(); 406 | } 407 | base(); 408 | translate([spacing,0,0])difference(){top();translate([casewall+pcbwidth/2-13/2,casewall+pcblength/2+6.5-5/2,-1])cube([15.5,5,10]);} 409 | -------------------------------------------------------------------------------- /PCB/Round/production/bom.csv: -------------------------------------------------------------------------------- 1 | Designator,Footprint,Quantity,Value,LCSC Part # 2 | "C1, C2",C_0603,2,160pF, 3 | "C10, C13, C15",C_0603,3,4.7uF, 4 | "C11, C12, C14, C18, C7, C9",C_0603,6,100nF, 5 | "C16, C17, C3, C4",C_0603,4,22pF, 6 | C19,C_0603,1,33pF, 7 | C20,C_1206,1,100uF 6.3V, 8 | "C5, C6",C_0603,2,220pF, 9 | C8,C_0603,1,1nF, 10 | D1,LED_1206_Rev_Square,1,G,C157737 11 | "D10, D4, D5, D6, D7, D8, D9",DFN1006-2L,7,~,C5137770 12 | D2,LED_1206_Rev_Square,1,A,C125108 13 | D3,LED_1206_Rev_Square,1,R,C125107 14 | J3,PinHeader_1x05_P2.54mm_Vertical_SMD_Pin1Left,1,Conn,C780063 15 | "L1, L2",1008,2,560nH,C75639 16 | "R1, R3",R_0603_,2,0R, 17 | "R10, R12, R13, R14, R8, R9",R_0603,6,100R, 18 | "R11, R15, R6",R_0603,3,10K, 19 | R2,R_0805_,1,0R, 20 | R4,R_0603,1,2k7 1%,C114612 21 | R5,R_0603,1,1k 1%,C22548 22 | R7,R_0603,1,20K, 23 | SW1,ESE13,1,ESE13V01D, 24 | U1,QFN-40-1EP_6x6mm_P0.5mm_EP4.6x4.6mm,1,PN532, 25 | Y1,Crystal-3.2x2.5,1,27.12MHz,C70591 26 | -------------------------------------------------------------------------------- /PCB/Round/production/designators.csv: -------------------------------------------------------------------------------- 1 | A1:1 2 | C1:1 3 | C10:1 4 | C11:1 5 | C12:1 6 | C13:1 7 | C14:1 8 | C15:1 9 | C16:1 10 | C17:1 11 | C18:1 12 | C19:1 13 | C2:1 14 | C20:1 15 | C3:1 16 | C4:1 17 | C5:1 18 | C6:1 19 | C7:1 20 | C8:1 21 | C9:1 22 | D1:1 23 | D10:1 24 | D2:1 25 | D3:1 26 | D4:1 27 | D5:1 28 | D6:1 29 | D7:1 30 | D8:1 31 | D9:1 32 | J3:1 33 | JP1:1 34 | L1:1 35 | L2:1 36 | PCB1:1 37 | R1:1 38 | R10:1 39 | R11:1 40 | R12:1 41 | R13:1 42 | R14:1 43 | R15:1 44 | R2:1 45 | R3:1 46 | R4:1 47 | R5:1 48 | R6:1 49 | R7:1 50 | R8:1 51 | R9:1 52 | SW1:1 53 | U1:1 54 | U2:1 55 | V1:1 56 | V2:1 57 | V3:1 58 | V4:1 59 | Y1:1 60 | -------------------------------------------------------------------------------- /PCB/Round/production/gerber.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Round/production/gerber.zip -------------------------------------------------------------------------------- /PCB/Round/production/netlist.ipc: -------------------------------------------------------------------------------- 1 | P CODE 00 2 | P UNITS CUST 0 3 | P arrayDim N 4 | 317GND VIA MD0157PA00X+014843Y+011772X0315Y0000R000S3 5 | 317GND VIA MD0157PA00X+011024Y+013727X0315Y0000R000S3 6 | 317GND VIA MD0157PA00X+014173Y+014724X0315Y0000R000S3 7 | 317GND VIA MD0157PA00X+015950Y+014802X0315Y0000R000S3 8 | 317GND VIA MD0157PA00X+013740Y+011811X0315Y0000R000S3 9 | 317GND VIA MD0157PA00X+013780Y+017959X0315Y0000R000S3 10 | 317GND VIA MD0157PA00X+015043Y+013704X0315Y0000R000S3 11 | 317GND VIA MD0157PA00X+018071Y+013268X0315Y0000R000S3 12 | 317GND VIA MD0157PA00X+013780Y+015118X0315Y0000R000S3 13 | 317GND VIA MD0157PA00X+018071Y+011299X0315Y0000R000S3 14 | 317GND VIA MD0157PA00X+013386Y+015528X0315Y0000R000S3 15 | 317GND VIA MD0157PA00X+013386Y+014740X0315Y0000R000S3 16 | 317GND VIA MD0157PA00X+016024Y+013858X0315Y0000R000S3 17 | 317GND VIA MD0157PA00X+018071Y+016535X0315Y0000R000S3 18 | 317GND VIA MD0157PA00X+012620Y+013804X0315Y0000R000S3 19 | 317GND VIA MD0157PA00X+014843Y+016654X0315Y0000R000S3 20 | 317GND VIA MD0157PA00X+016181Y+012382X0315Y0000R000S3 21 | 317GND VIA MD0157PA00X+018071Y+015236X0315Y0000R000S3 22 | 317GND VIA MD0157PA00X+012283Y+012126X0315Y0000R000S3 23 | 317GND VIA MD0157PA00X+014173Y+015528X0315Y0000R000S3 24 | 317GND VIA MD0157PA00X+015945Y+015945X0315Y0000R000S3 25 | 317GND VIA MD0157PA00X+012185Y+015852X0315Y0000R000S3 26 | 317+5V VIA MD0157PA00X+015787Y+016496X0315Y0000R000S3 27 | 317+5V VIA MD0157PA00X+013701Y+012205X0315Y0000R000S3 28 | 317NET-(U1-VMID) VIA MD0157PA00X+011496Y+017614X0315Y0000R000S3 29 | 317NET-(U1-VMID) VIA MD0157PA00X+012372Y+016738X0315Y0000R000S3 30 | 317+3.3V VIA MD0157PA00X+016831Y+013445X0315Y0000R000S3 31 | 317+3.3V VIA MD0157PA00X+016575Y+015866X0315Y0000R000S3 32 | 317+3.3V VIA MD0157PA00X+012736Y+017024X0315Y0000R000S3 33 | 317+3.3V VIA MD0157PA00X+010846Y+012602X0315Y0000R000S3 34 | 317+3.3V VIA MD0157PA00X+010709Y+017949X0315Y0000R000S3 35 | 317+3.3V VIA MD0157PA00X+013592Y+017228X0315Y0000R000S3 36 | 327NET-(U1-OSCIN) Y1 -1 A01X+011024Y+015587X0512Y0413R270S2 37 | 327GND Y1 -2 A01X+011024Y+014681X0512Y0413R270S2 38 | 327ET-(U1-OSCOUT) Y1 -3 A01X+011713Y+014681X0512Y0413R270S2 39 | 327GND Y1 -4 A01X+011713Y+015587X0512Y0413R270S2 40 | 327GND D2 -1 A01X+018701Y+013268X0630Y0315R000S2 41 | 327NET-(D2-A) D2 -2 A01X+018701Y+014291X0630Y0315R000S2 42 | 327GND D3 -1 A01X+018701Y+015236X0630Y0315R000S2 43 | 327NET-(D3-A) D3 -2 A01X+018701Y+016260X0630Y0315R000S2 44 | 327N/C SW1 A01X+009173Y+013140X0276Y0413R180S2 45 | 327N/C SW1 A01X+009173Y+014419X0276Y0413R180S2 46 | 327GND SW1 -1 A01X+010354Y+013140X0276Y0413R180S2 47 | 327SLASH}UART_RX) SW1 -2 A01X+010354Y+014419X0276Y0413R180S2 48 | 327GND D1 -1 A01X+018701Y+011299X0630Y0315R000S2 49 | 327NET-(D1-A) D1 -2 A01X+018701Y+012323X0630Y0315R000S2 50 | 327+3.3V C7 -1 A01X+014016Y+017024X0315Y0374R000S2 51 | 327GND C7 -2 A01X+014626Y+017024X0315Y0374R000S2 52 | 327NET-(C3-PAD1) C3 -1 A01X+015276Y+019911X0315Y0374R270S2 53 | 327NET-(A1-PAD1) C3 -2 A01X+015276Y+020522X0315Y0374R270S2 54 | 327GND C5 -1 A01X+014144Y+019921X0315Y0374R000S2 55 | 327NET-(C3-PAD1) C5 -2 A01X+014754Y+019921X0315Y0374R000S2 56 | 327T-(U1-RSTPD_N) R6 -1 A01X+016998Y+016181X0315Y0374R000S2 57 | 327+5V R6 -2 A01X+017648Y+016181X0315Y0374R000S2 58 | 327NET-(C8-PAD2) R4 -1 A01X+011053Y+019921X0315Y0374R000S2 59 | 327NET-(C4-PAD2) R4 -2 A01X+011703Y+019921X0315Y0374R000S2 60 | 327+3.3V C13 -1 A01X+016201Y+015596X0315Y0374R090S2 61 | 327GND C13 -2 A01X+016201Y+014986X0315Y0374R090S2 62 | 327+5V C14 -1 A01X+015600Y+016197X0315Y0374R000S2 63 | 327GND C14 -2 A01X+016211Y+016197X0315Y0374R000S2 64 | 327NET-(U1-VMID) C9 -1 A01X+011063Y+017201X0315Y0374R000S2 65 | 327GND C9 -2 A01X+011673Y+017201X0315Y0374R000S2 66 | 327NET-(U1-OSCIN) C16 -1 A01X+011063Y+016118X0315Y0374R000S2 67 | 327GND C16 -2 A01X+011673Y+016118X0315Y0374R000S2 68 | 327-(U1-P32_INT0) R9 -1 A01X+016998Y+014764X0315Y0374R000S2 69 | 327NET-(D2-A) R9 -2 A01X+017648Y+014764X0315Y0374R000S2 70 | 327{SLASH}DBG_TX) R8 -1 A01X+016998Y+014291X0315Y0374R000S2 71 | 327NET-(D1-A) R8 -2 A01X+017648Y+014291X0315Y0374R000S2 72 | 327+3.3V R11 -1 A01X+013504Y+012781X0315Y0374R270S2 73 | 327SLASH}UART_RX) R11 -2 A01X+013504Y+013431X0315Y0374R270S2 74 | 327GND U1 -1 A01X+014665Y+016276X0276Y0098R090S2 75 | 327-LOADMOD-PAD2) U1 -2 A01X+014469Y+016276X0276Y0098R090S2 76 | 327GND U1 -3 A01X+014272Y+016276X0276Y0098R090S2 77 | 327NET-(U1-TX1) U1 -4 A01X+014075Y+016276X0276Y0098R090S2 78 | 327+3.3V U1 -5 A01X+013878Y+016276X0276Y0098R090S2 79 | 327NET-(U1-TX2) U1 -6 A01X+013681Y+016276X0276Y0098R090S2 80 | 327GND U1 -7 A01X+013484Y+016276X0276Y0098R090S2 81 | 327+3.3V U1 -8 A01X+013287Y+016276X0276Y0098R090S2 82 | 327NET-(U1-VMID) U1 -9 A01X+013091Y+016276X0276Y0098R090S2 83 | 327NET-(U1-RX) U1 -10 A01X+012894Y+016276X0276Y0098R090S2 84 | 327GND U1 -11 A01X+012638Y+016020X0098Y0276R090S2 85 | 327U1-AUX1-PAD12) U1 -12 A01X+012638Y+015823X0098Y0276R090S2 86 | 327U1-AUX2-PAD13) U1 -13 A01X+012638Y+015626X0098Y0276R090S2 87 | 327NET-(U1-OSCIN) U1 -14 A01X+012638Y+015429X0098Y0276R090S2 88 | 327ET-(U1-OSCOUT) U1 -15 A01X+012638Y+015232X0098Y0276R090S2 89 | 327GND U1 -16 A01X+012638Y+015035X0098Y0276R090S2 90 | 327NET-(JP1-C) U1 -17 A01X+012638Y+014839X0098Y0276R090S2 91 | 327GND U1 -18 A01X+012638Y+014642X0098Y0276R090S2 92 | 327(U1-P35-PAD19) U1 -19 A01X+012638Y+014445X0098Y0276R090S2 93 | 327-(U1-NC-PAD20) U1 -20 A01X+012638Y+014248X0098Y0276R090S2 94 | 327-(U1-NC-PAD21) U1 -21 A01X+012894Y+013992X0276Y0098R090S2 95 | 327-(U1-NC-PAD22) U1 -22 A01X+013091Y+013992X0276Y0098R090S2 96 | 327+3.3V U1 -23 A01X+013287Y+013992X0276Y0098R090S2 97 | 327SLASH}UART_RX) U1 -24 A01X+013484Y+013992X0276Y0098R090S2 98 | 327P70_IRQ-PAD25) U1 -25 A01X+013681Y+013992X0276Y0098R090S2 99 | 327STOUT_N-PAD26) U1 -26 A01X+013878Y+013992X0276Y0098R090S2 100 | 327{SLASH}HSU_RX) U1 -27 A01X+014075Y+013992X0276Y0098R090S2 101 | 327{SLASH}HSU_TX) U1 -28 A01X+014272Y+013992X0276Y0098R090S2 102 | 327ASH}P71-PAD29) U1 -29 A01X+014469Y+013992X0276Y0098R090S2 103 | 327SCK{SLASH}P72) U1 -30 A01X+014665Y+013992X0276Y0098R090S2 104 | 327{SLASH}DBG_TX) U1 -31 A01X+014921Y+014248X0098Y0276R090S2 105 | 327-(U1-P32_INT0) U1 -32 A01X+014921Y+014445X0098Y0276R090S2 106 | 327-(U1-P33_INT1) U1 -33 A01X+014921Y+014642X0098Y0276R090S2 107 | 327SIG_CLK-PAD34) U1 -34 A01X+014921Y+014839X0098Y0276R090S2 108 | 327-SIGOUT-PAD35) U1 -35 A01X+014921Y+015035X0098Y0276R090S2 109 | 327U1-SIGN-PAD36) U1 -36 A01X+014921Y+015232X0098Y0276R090S2 110 | 327U1-SVDD-PAD37) U1 -37 A01X+014921Y+015429X0098Y0276R090S2 111 | 327T-(U1-RSTPD_N) U1 -38 A01X+014921Y+015626X0098Y0276R090S2 112 | 327+3.3V U1 -39 A01X+014921Y+015823X0098Y0276R090S2 113 | 327+5V U1 -40 A01X+014921Y+016020X0098Y0276R090S2 114 | 327GND U1 -41 A01X+013780Y+015134X1732Y1732R090S2 115 | 327ET-(U1-OSCOUT) C17 -1 A01X+011673Y+014150X0315Y0374R180S2 116 | 327GND C17 -2 A01X+011063Y+014150X0315Y0374R180S2 117 | 327+3.3V C12 -1 A01X+013543Y+017555X0315Y0374R180S2 118 | 327GND C12 -2 A01X+012933Y+017555X0315Y0374R180S2 119 | 327NET-(U1-RX) R5 -1 A01X+011063Y+018274X0315Y0374R090S2 120 | 327NET-(U1-VMID) R5 -2 A01X+011063Y+017624X0315Y0374R090S2 121 | 327T-(U1-RSTPD_N) R7 -1 A01X+016998Y+015709X0315Y0374R000S2 122 | 327GND R7 -2 A01X+017648Y+015709X0315Y0374R000S2 123 | 327-(U1-P33_INT1) R10 -1 A01X+016998Y+015236X0315Y0374R000S2 124 | 327NET-(D3-A) R10 -2 A01X+017648Y+015236X0315Y0374R000S2 125 | 327+3.3V C18 -1 A01X+012874Y+012801X0315Y0374R270S2 126 | 327GND C18 -2 A01X+012874Y+013411X0315Y0374R270S2 127 | 327+3.3V C11 -1 A01X+015610Y+015596X0315Y0374R090S2 128 | 327GND C11 -2 A01X+015610Y+014986X0315Y0374R090S2 129 | 327NET-(U1-RX) C8 -1 A01X+011063Y+018687X0315Y0374R270S2 130 | 327NET-(C8-PAD2) C8 -2 A01X+011063Y+019297X0315Y0374R270S2 131 | 327GND J3 -1 A01X+012280Y+010569X0988Y0394R270S2 132 | 327+5V J3 -2 A01X+013280Y+011872X0988Y0394R270S2 133 | 327NET-(J3-PIN_3) J3 -3 A01X+014280Y+010569X0988Y0394R270S2 134 | 327NET-(J3-PIN_4) J3 -4 A01X+015280Y+011872X0988Y0394R270S2 135 | 327NET-(J3-PIN_5) J3 -5 A01X+016280Y+010569X0988Y0394R270S2 136 | 327+3.3V C10 -1 A01X+014016Y+017555X0315Y0374R000S2 137 | 327GND C10 -2 A01X+014626Y+017555X0315Y0374R000S2 138 | 327NET-(A1-PAD1) C1 -1 A01X+014754Y+020526X0315Y0374R180S2 139 | 327GND C1 -2 A01X+014144Y+020526X0315Y0374R180S2 140 | 327GND C6 -1 A01X+013415Y+019921X0315Y0374R180S2 141 | 327NET-(C4-PAD2) C6 -2 A01X+012805Y+019921X0315Y0374R180S2 142 | 327GND JP1 -1 A01X+011161Y+013008X0394Y0197R000S2 143 | 327NET-(JP1-C) JP1 -2 A01X+011673Y+013008X0394Y0591R000S2 144 | 327+3.3V JP1 -3 A01X+012185Y+013008X0394Y0197R000S2 145 | 327NET-(J3-PIN_3) R13 -1 A01X+014104Y+012811X0315Y0374R000S2 146 | 327{SLASH}HSU_TX) R13 -2 A01X+014754Y+012811X0315Y0374R000S2 147 | 327+3.3V C15 -1 A01X+011063Y+016669X0315Y0374R000S2 148 | 327GND C15 -2 A01X+011673Y+016669X0315Y0374R000S2 149 | 327NET-(J3-PIN_4) R14 -1 A01X+014754Y+013402X0315Y0374R180S2 150 | 327{SLASH}HSU_RX) R14 -2 A01X+014104Y+013402X0315Y0374R180S2 151 | 327NET-(U1-TX1) L1 -1 A01X+014760Y+018378X0492Y0866R315S2 152 | 327NET-(C3-PAD1) L1 -2 A01X+015358Y+018976X0492Y0866R315S2 153 | 327NET-(C4-PAD2) L2 -1 A01X+012201Y+018976X0492Y0866R045S2 154 | 327NET-(U1-TX2) L2 -2 A01X+012799Y+018378X0492Y0866R045S2 155 | 327NET-(A1-PAD3) C4 -1 A01X+012283Y+020522X0315Y0374R090S2 156 | 327NET-(C4-PAD2) C4 -2 A01X+012283Y+019911X0315Y0374R090S2 157 | 327NET-(J3-PIN_5) R12 -1 A01X+015906Y+013435X0315Y0374R090S2 158 | 327SCK{SLASH}P72) R12 -2 A01X+015906Y+012785X0315Y0374R090S2 159 | 327NET-(D2-A) D5 -1 A01X+018701Y+014596X0217Y0256R270S2 160 | 327GND D5 -2 A01X+018701Y+014931X0217Y0256R270S2 161 | 327N/C U2 -- A01X+013228Y+008071X0551Y0079R000S3 162 | 327N/C U2 -- A01X+013701Y+008189X0079Y0315R000S3 163 | 327N/C U2 -- A01X+013937Y+008071X0079Y0079R000S3 164 | 327N/C U2 -- A01X+014331Y+008071X0551Y0079R000S3 165 | 327N/C U2 -- A01X+012992Y+008346X0079Y0472R000S3 166 | 327N/C U2 -- A01X+013465Y+008346X0079Y0472R000S3 167 | 327N/C U2 -- A01X+013622Y+008189X0079Y0157R000S3 168 | 327N/C U2 -- A01X+013858Y+008228X0079Y0236R000S3 169 | 327N/C U2 -- A01X+014094Y+008346X0079Y0472R000S3 170 | 327N/C U2 -- A01X+014567Y+008346X0079Y0472R000S3 171 | 327N/C U2 -- A01X+013228Y+008307X0236Y0236R000S3 172 | 327N/C U2 -- A01X+013937Y+008228X0079Y0079R000S3 173 | 327N/C U2 -- A01X+014331Y+008307X0236Y0236R000S3 174 | 327N/C U2 -- A01X+013622Y+008504X0079Y0315R000S3 175 | 327N/C U2 -- A01X+013937Y+008504X0079Y0157R000S3 176 | 327N/C U2 -- A01X+013228Y+008543X0394Y0079R000S3 177 | 327N/C U2 -- A01X+013780Y+008661X0079Y0315R000S3 178 | 327N/C U2 -- A01X+014331Y+008543X0394Y0079R000S3 179 | 327N/C U2 -- A01X+013701Y+008661X0079Y0157R000S3 180 | 327N/C U2 -- A01X+013858Y+008701X0079Y0236R000S3 181 | 327N/C U2 -- A01X+013031Y+008740X0157Y0157R000S3 182 | 327N/C U2 -- A01X+013228Y+008701X0079Y0079R000S3 183 | 327N/C U2 -- A01X+013504Y+008701X0157Y0079R000S3 184 | 327N/C U2 -- A01X+013937Y+008701X0079Y0079R000S3 185 | 327N/C U2 -- A01X+014173Y+008701X0236Y0079R000S3 186 | 327N/C U2 -- A01X+014449Y+008740X0157Y0157R000S3 187 | 327N/C U2 -- A01X+013386Y+008780X0079Y0079R000S3 188 | 327N/C U2 -- A01X+014094Y+008819X0079Y0157R000S3 189 | 327N/C U2 -- A01X+014331Y+008780X0079Y0079R000S3 190 | 327N/C U2 -- A01X+014567Y+008780X0079Y0079R000S3 191 | 327N/C U2 -- A01X+013150Y+008858X0079Y0079R000S3 192 | 327N/C U2 -- A01X+013307Y+008937X0079Y0236R000S3 193 | 327N/C U2 -- A01X+013465Y+008858X0079Y0079R000S3 194 | 327N/C U2 -- A01X+013622Y+009016X0079Y0394R000S3 195 | 327N/C U2 -- A01X+013976Y+008898X0157Y0157R000S3 196 | 327N/C U2 -- A01X+014488Y+008858X0079Y0079R000S3 197 | 327N/C U2 -- A01X+013071Y+008937X0079Y0079R000S3 198 | 327N/C U2 -- A01X+013228Y+008937X0079Y0079R000S3 199 | 327N/C U2 -- A01X+013386Y+008976X0079Y0157R000S3 200 | 327N/C U2 -- A01X+013543Y+008976X0079Y0157R000S3 201 | 327N/C U2 -- A01X+013858Y+008976X0079Y0157R000S3 202 | 327N/C U2 -- A01X+014173Y+008976X0079Y0157R000S3 203 | 327N/C U2 -- A01X+014331Y+008937X0079Y0079R000S3 204 | 327N/C U2 -- A01X+014567Y+009094X0079Y0394R000S3 205 | 327N/C U2 -- A01X+013465Y+009016X0079Y0079R000S3 206 | 327N/C U2 -- A01X+013740Y+009016X0157Y0079R000S3 207 | 327N/C U2 -- A01X+014094Y+009016X0079Y0079R000S3 208 | 327N/C U2 -- A01X+013780Y+009291X0079Y0472R000S3 209 | 327N/C U2 -- A01X+013937Y+009134X0079Y0157R000S3 210 | 327N/C U2 -- A01X+014488Y+009094X0079Y0079R000S3 211 | 327N/C U2 -- A01X+013228Y+009173X0551Y0079R000S3 212 | 327N/C U2 -- A01X+013701Y+009173X0079Y0079R000S3 213 | 327N/C U2 -- A01X+014173Y+009173X0236Y0079R000S3 214 | 327N/C U2 -- A01X+014409Y+009173X0079Y0079R000S3 215 | 327N/C U2 -- A01X+012992Y+009449X0079Y0472R000S3 216 | 327N/C U2 -- A01X+013465Y+009449X0079Y0472R000S3 217 | 327N/C U2 -- A01X+013858Y+009252X0079Y0079R000S3 218 | 327N/C U2 -- A01X+014016Y+009252X0079Y0079R000S3 219 | 327N/C U2 -- A01X+014173Y+009291X0079Y0157R000S3 220 | 327N/C U2 -- A01X+014488Y+009331X0079Y0236R000S3 221 | 327N/C U2 -- A01X+013228Y+009409X0236Y0236R000S3 222 | 327N/C U2 -- A01X+013701Y+009488X0079Y0394R000S3 223 | 327N/C U2 -- A01X+014094Y+009370X0079Y0157R000S3 224 | 327N/C U2 -- A01X+014409Y+009331X0079Y0079R000S3 225 | 327N/C U2 -- A01X+013622Y+009409X0079Y0079R000S3 226 | 327N/C U2 -- A01X+013858Y+009488X0079Y0236R000S3 227 | 327N/C U2 -- A01X+014016Y+009409X0079Y0079R000S3 228 | 327N/C U2 -- A01X+014331Y+009409X0079Y0079R000S3 229 | 327N/C U2 -- A01X+014567Y+009488X0079Y0236R000S3 230 | 327N/C U2 -- A01X+014173Y+009488X0079Y0079R000S3 231 | 327N/C U2 -- A01X+013622Y+009606X0079Y0157R000S3 232 | 327N/C U2 -- A01X+013976Y+009567X0157Y0079R000S3 233 | 327N/C U2 -- A01X+014291Y+009567X0157Y0079R000S3 234 | 327N/C U2 -- A01X+013228Y+009646X0394Y0079R000S3 235 | 327N/C U2 -- A01X+013937Y+009646X0079Y0079R000S3 236 | 327N/C U2 -- A01X+014134Y+009646X0157Y0079R000S3 237 | 327{SLASH}HSU_RX) C19 -1 A01X+015315Y+012805X0315Y0374R270S2 238 | 327GND C19 -2 A01X+015315Y+013415X0315Y0374R270S2 239 | 327NET-(D1-A) D4 -1 A01X+018701Y+012628X0217Y0256R270S2 240 | 327GND D4 -2 A01X+018701Y+012963X0217Y0256R270S2 241 | 327NET-(J3-PIN_5) D6 -1 A01X+016742Y+012126X0217Y0256R180S2 242 | 327GND D6 -2 A01X+016407Y+012126X0217Y0256R180S2 243 | 327GND C20 -1 A01X+015285Y+016811X0453Y0709R000S2 244 | 327+5V C20 -2 A01X+016447Y+016811X0453Y0709R000S2 245 | 327NET-(D3-A) D7 -1 A01X+018701Y+016565X0217Y0256R270S2 246 | 327GND D7 -2 A01X+018701Y+016900X0217Y0256R270S2 247 | 327GND D8 -1 A01X+014094Y+012037X0217Y0256R270S2 248 | 327NET-(J3-PIN_3) D8 -2 A01X+014094Y+012372X0217Y0256R270S2 249 | 327GND C2 -1 A01X+013415Y+020526X0315Y0374R180S2 250 | 327NET-(A1-PAD3) C2 -2 A01X+012805Y+020526X0315Y0374R180S2 251 | 327NET-(J3-PIN_4) D9 -1 A01X+014764Y+012382X0217Y0256R090S2 252 | 327GND D9 -2 A01X+014764Y+012047X0217Y0256R090S2 253 | 367N/C PCB1 D0787UA00X+000984Y+026575X0787Y0000R000S0 254 | 367N/C PCB1 D0787UA00X+000984Y+000984X0787Y0000R000S0 255 | 327N/C PCB1 A01X+001969Y+026043X0394Y0000R000S3 256 | 327N/C PCB1 A02X+001969Y+026043X0394Y0000R000S1 257 | 327N/C PCB1 A01X+001969Y+001516X0394Y0000R000S3 258 | 327N/C PCB1 A02X+001969Y+001516X0394Y0000R000S1 259 | 327N/C PCB1 A01X+025591Y+026043X0394Y0000R000S3 260 | 327N/C PCB1 A02X+025591Y+026043X0394Y0000R000S1 261 | 327N/C PCB1 A01X+025591Y+001516X0394Y0000R000S3 262 | 327N/C PCB1 A02X+025591Y+001516X0394Y0000R000S1 263 | 367N/C PCB1 D0787UA00X+026575Y+026575X0787Y0000R000S0 264 | 367N/C PCB1 D0787UA00X+026575Y+000984X0787Y0000R000S0 265 | 327GND D10 -1 A01X+012589Y+012126X0217Y0256R000S2 266 | 327+5V D10 -2 A01X+012923Y+012126X0217Y0256R000S2 267 | 3171-LOOP-PAD0)_7 A1 -0 D0098PA00X+012787Y+021776X0197Y0000R000S3 268 | 3271-LOOP-PAD0)_7 A1 -0 A01X+013031Y+021776X0492Y0197R000S3 269 | 3171-LOOP-PAD0)_7 A1 -0 D0098PA00X+013406Y+022602X0197Y0000R000S3 270 | 3271-LOOP-PAD0)_7 A1 -0 A01X+013406Y+022602X0197Y0197R000S3 271 | 3271-LOOP-PAD0)_7 A1 -0 A00X+013780Y+022602X0748Y0197R000S3 272 | 3171-LOOP-PAD0)_7 A1 -0 D0098PA00X+014154Y+022602X0197Y0000R000S3 273 | 3271-LOOP-PAD0)_7 A1 -0 A02X+014154Y+022602X0197Y0197R000S3 274 | 3271-LOOP-PAD0)_7 A1 -0 A01X+014528Y+021776X0492Y0197R000S3 275 | 327NET-(A1-PAD1) A1 -1 A01X+014476Y+021146X0394Y0197R000S2 276 | 327GND A1 -2 A01X+013780Y+021815X0551Y0197R000S2 277 | 327NET-(A1-PAD3) A1 -3 A01X+013083Y+021146X0394Y0197R000S2 278 | 327+3.3V R15 -1 A01X+016457Y+013445X0315Y0374R090S2 279 | 327SCK{SLASH}P72) R15 -2 A01X+016457Y+012795X0315Y0374R090S2 280 | 999 281 | -------------------------------------------------------------------------------- /PCB/Round/production/positions.csv: -------------------------------------------------------------------------------- 1 | Designator,Mid X,Mid Y,Rotation,Layer 2 | C1,36.7,52.135,180.0,top 3 | C10,36.375,44.59,0.0,top 4 | C11,39.65,38.84,270.0,top 5 | C12,33.625,44.59,180.0,top 6 | C13,41.15,38.84,270.0,top 7 | C14,40.4,41.14,0.0,top 8 | C15,28.875,42.34,0.0,top 9 | C16,28.875,40.94,0.0,top 10 | C17,28.875,35.94,180.0,top 11 | C18,32.7,33.29,90.0,top 12 | C19,38.9,33.3,90.0,top 13 | C2,33.3,52.135,180.0,top 14 | C20,40.3,42.7,0.0,top 15 | C3,38.8,51.35,90.0,top 16 | C4,31.2,51.35,270.0,top 17 | C5,36.7,50.6,0.0,top 18 | C6,33.3,50.6,180.0,top 19 | C7,36.375,43.24,0.0,top 20 | C8,28.1,48.24,90.0,top 21 | C9,28.875,43.69,0.0,top 22 | D1,47.5,30.0,90.0,top 23 | D10,32.4,30.8,0.0,top 24 | D2,47.5,35.0,90.0,top 25 | D3,47.5,40.0,90.0,top 26 | D4,47.5,32.5,90.0,top 27 | D5,47.5,37.5,90.0,top 28 | D6,42.1,30.8,180.0,top 29 | D7,47.5,42.5,90.0,top 30 | D8,35.8,31.0,90.0,top 31 | D9,37.5,31.025,270.0,top 32 | J3,36.27,28.5,90.0,top 33 | L1,38.25,47.44,45.0,top 34 | L2,31.75,47.44,315.0,top 35 | R1,33.23,54.51,90.0,top 36 | R10,44.0,38.7,0.0,top 37 | R11,34.3,33.29,90.0,top 38 | R12,40.4,33.3,270.0,top 39 | R13,36.65,32.54,0.0,top 40 | R14,36.65,34.04,180.0,top 41 | R15,41.8,33.325,270.0,top 42 | R2,35.0,56.41,90.0,top 43 | R3,36.77,54.51,90.0,top 44 | R4,28.9,50.6,0.0,top 45 | R5,28.1,45.59,270.0,top 46 | R6,44.0,41.1,0.0,top 47 | R7,44.0,39.9,0.0,top 48 | R8,44.0,36.3,0.0,top 49 | R9,44.0,37.5,0.0,top 50 | SW1,24.8,35.0,180.0,top 51 | U1,35.0,38.44,180.0,top 52 | Y1,28.875,38.44,90.0,top 53 | -------------------------------------------------------------------------------- /PCB/Square/.gitignore: -------------------------------------------------------------------------------- 1 | *-backups 2 | *cache* 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /PCB/Square/README.md: -------------------------------------------------------------------------------- 1 | # Square 2 | 3 | These files are for use in [KiCad](https://www.kicad.org). 4 | 5 | ## Trademark 6 | 7 | This is an open source project, but bear in mind you cannot sell boards bearing the Andrews & Arnold Ltd name, the A&A logo, the registered trademark AJK logo, or the GS1 allocated EANs assigned to Andrews & Arnold Ltd. 8 | 9 | ## Images 10 | 11 | 12 | 13 | *Auto generated 2025-01-19T12:52:54* 14 | -------------------------------------------------------------------------------- /PCB/Square/Square-90.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Square/Square-90.png -------------------------------------------------------------------------------- /PCB/Square/Square-bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Square/Square-bottom.png -------------------------------------------------------------------------------- /PCB/Square/Square.kicad_prl: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "active_layer": 0, 4 | "active_layer_preset": "", 5 | "auto_track_width": true, 6 | "hidden_netclasses": [], 7 | "hidden_nets": [], 8 | "high_contrast_mode": 0, 9 | "net_color_mode": 1, 10 | "opacity": { 11 | "images": 0.6, 12 | "pads": 1.0, 13 | "shapes": 1.0, 14 | "tracks": 1.0, 15 | "vias": 1.0, 16 | "zones": 1.0 17 | }, 18 | "ratsnest_display_mode": 0, 19 | "selection_filter": { 20 | "dimensions": true, 21 | "footprints": true, 22 | "graphics": true, 23 | "keepouts": true, 24 | "lockedItems": true, 25 | "otherItems": true, 26 | "pads": true, 27 | "text": true, 28 | "tracks": true, 29 | "vias": true, 30 | "zones": true 31 | }, 32 | "visible_items": [ 33 | 0, 34 | 1, 35 | 2, 36 | 3, 37 | 4, 38 | 5, 39 | 8, 40 | 9, 41 | 10, 42 | 11, 43 | 12, 44 | 13, 45 | 14, 46 | 15, 47 | 16, 48 | 17, 49 | 18, 50 | 19, 51 | 20, 52 | 21, 53 | 22, 54 | 23, 55 | 24, 56 | 25, 57 | 26, 58 | 27, 59 | 28, 60 | 29, 61 | 30, 62 | 32, 63 | 33, 64 | 34, 65 | 35, 66 | 36, 67 | 41 68 | ], 69 | "visible_layers": "0003d3fc_80000001", 70 | "zone_display_mode": 0 71 | }, 72 | "git": { 73 | "repo_password": "", 74 | "repo_type": "", 75 | "repo_username": "", 76 | "ssh_key": "" 77 | }, 78 | "meta": { 79 | "filename": "Square.kicad_prl", 80 | "version": 4 81 | }, 82 | "net_inspector_panel": { 83 | "col_hidden": [ 84 | false, 85 | false, 86 | false, 87 | false, 88 | false, 89 | false, 90 | false, 91 | false, 92 | false, 93 | false 94 | ], 95 | "col_order": [ 96 | 0, 97 | 1, 98 | 2, 99 | 3, 100 | 4, 101 | 5, 102 | 6, 103 | 7, 104 | 8, 105 | 9 106 | ], 107 | "col_widths": [ 108 | 156, 109 | 141, 110 | 103, 111 | 71, 112 | 103, 113 | 103, 114 | 103, 115 | 74, 116 | 103, 117 | 103 118 | ], 119 | "custom_group_rules": [], 120 | "expanded_rows": [], 121 | "filter_by_net_name": true, 122 | "filter_by_netclass": true, 123 | "filter_text": "", 124 | "group_by_constraint": false, 125 | "group_by_netclass": false, 126 | "show_unconnected_nets": false, 127 | "show_zero_pad_nets": false, 128 | "sort_ascending": true, 129 | "sorting_column": 0 130 | }, 131 | "project": { 132 | "files": [] 133 | }, 134 | "schematic": { 135 | "selection_filter": { 136 | "graphics": true, 137 | "images": true, 138 | "labels": true, 139 | "lockedItems": false, 140 | "otherItems": true, 141 | "pins": true, 142 | "symbols": true, 143 | "text": true, 144 | "wires": true 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /PCB/Square/Square.kicad_pro: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "3dviewports": [], 4 | "design_settings": { 5 | "defaults": { 6 | "apply_defaults_to_fp_fields": false, 7 | "apply_defaults_to_fp_shapes": false, 8 | "apply_defaults_to_fp_text": false, 9 | "board_outline_line_width": 0.05, 10 | "copper_line_width": 0.2, 11 | "copper_text_italic": false, 12 | "copper_text_size_h": 1.5, 13 | "copper_text_size_v": 1.5, 14 | "copper_text_thickness": 0.3, 15 | "copper_text_upright": false, 16 | "courtyard_line_width": 0.05, 17 | "dimension_precision": 4, 18 | "dimension_units": 3, 19 | "dimensions": { 20 | "arrow_length": 1270000, 21 | "extension_offset": 500000, 22 | "keep_text_aligned": true, 23 | "suppress_zeroes": false, 24 | "text_position": 0, 25 | "units_format": 1 26 | }, 27 | "fab_line_width": 0.1, 28 | "fab_text_italic": false, 29 | "fab_text_size_h": 1.0, 30 | "fab_text_size_v": 1.0, 31 | "fab_text_thickness": 0.15, 32 | "fab_text_upright": false, 33 | "other_line_width": 0.1, 34 | "other_text_italic": false, 35 | "other_text_size_h": 1.0, 36 | "other_text_size_v": 1.0, 37 | "other_text_thickness": 0.15, 38 | "other_text_upright": false, 39 | "pads": { 40 | "drill": 0.0, 41 | "height": 1.2, 42 | "width": 0.5 43 | }, 44 | "silk_line_width": 0.12, 45 | "silk_text_italic": false, 46 | "silk_text_size_h": 1.0, 47 | "silk_text_size_v": 1.0, 48 | "silk_text_thickness": 0.15, 49 | "silk_text_upright": false, 50 | "zones": { 51 | "45_degree_only": false, 52 | "min_clearance": 0.25 53 | } 54 | }, 55 | "diff_pair_dimensions": [ 56 | { 57 | "gap": 0.0, 58 | "via_gap": 0.0, 59 | "width": 0.0 60 | } 61 | ], 62 | "drc_exclusions": [], 63 | "meta": { 64 | "filename": "board_design_settings.json", 65 | "version": 2 66 | }, 67 | "rule_severities": { 68 | "annular_width": "error", 69 | "clearance": "error", 70 | "connection_width": "warning", 71 | "copper_edge_clearance": "warning", 72 | "copper_sliver": "warning", 73 | "courtyards_overlap": "error", 74 | "creepage": "error", 75 | "diff_pair_gap_out_of_range": "error", 76 | "diff_pair_uncoupled_length_too_long": "error", 77 | "drill_out_of_range": "error", 78 | "duplicate_footprints": "warning", 79 | "extra_footprint": "warning", 80 | "footprint": "error", 81 | "footprint_filters_mismatch": "ignore", 82 | "footprint_symbol_mismatch": "warning", 83 | "footprint_type_mismatch": "error", 84 | "hole_clearance": "error", 85 | "hole_near_hole": "error", 86 | "hole_to_hole": "warning", 87 | "holes_co_located": "warning", 88 | "invalid_outline": "error", 89 | "isolated_copper": "warning", 90 | "item_on_disabled_layer": "error", 91 | "items_not_allowed": "error", 92 | "length_out_of_range": "error", 93 | "lib_footprint_issues": "warning", 94 | "lib_footprint_mismatch": "warning", 95 | "malformed_courtyard": "error", 96 | "microvia_drill_out_of_range": "error", 97 | "mirrored_text_on_front_layer": "warning", 98 | "missing_courtyard": "ignore", 99 | "missing_footprint": "warning", 100 | "net_conflict": "warning", 101 | "nonmirrored_text_on_back_layer": "warning", 102 | "npth_inside_courtyard": "ignore", 103 | "padstack": "error", 104 | "pth_inside_courtyard": "ignore", 105 | "shorting_items": "error", 106 | "silk_edge_clearance": "warning", 107 | "silk_over_copper": "warning", 108 | "silk_overlap": "warning", 109 | "skew_out_of_range": "error", 110 | "solder_mask_bridge": "error", 111 | "starved_thermal": "error", 112 | "text_height": "warning", 113 | "text_thickness": "warning", 114 | "through_hole_pad_without_hole": "error", 115 | "too_many_vias": "error", 116 | "track_angle": "error", 117 | "track_dangling": "warning", 118 | "track_segment_length": "error", 119 | "track_width": "error", 120 | "tracks_crossing": "error", 121 | "unconnected_items": "error", 122 | "unresolved_variable": "error", 123 | "via_dangling": "warning", 124 | "zone_has_empty_net": "error", 125 | "zones_intersect": "error" 126 | }, 127 | "rule_severitieslegacy_courtyards_overlap": true, 128 | "rule_severitieslegacy_no_courtyard_defined": false, 129 | "rules": { 130 | "allow_blind_buried_vias": false, 131 | "allow_microvias": false, 132 | "max_error": 0.005, 133 | "min_clearance": 0.125, 134 | "min_connection": 0.0, 135 | "min_copper_edge_clearance": 0.2, 136 | "min_groove_width": 0.0, 137 | "min_hole_clearance": 0.125, 138 | "min_hole_to_hole": 0.2, 139 | "min_microvia_diameter": 0.3, 140 | "min_microvia_drill": 0.2, 141 | "min_resolved_spokes": 2, 142 | "min_silk_clearance": 0.0, 143 | "min_text_height": 0.8, 144 | "min_text_thickness": 0.08, 145 | "min_through_hole_diameter": 0.2, 146 | "min_track_width": 0.125, 147 | "min_via_annular_width": 0.05, 148 | "min_via_diameter": 0.4, 149 | "solder_mask_to_copper_clearance": 0.0, 150 | "use_height_for_length_calcs": true 151 | }, 152 | "teardrop_options": [ 153 | { 154 | "td_onpthpad": true, 155 | "td_onroundshapesonly": false, 156 | "td_onsmdpad": true, 157 | "td_ontrackend": false, 158 | "td_onvia": true 159 | } 160 | ], 161 | "teardrop_parameters": [ 162 | { 163 | "td_allow_use_two_tracks": true, 164 | "td_curve_segcount": 0, 165 | "td_height_ratio": 1.0, 166 | "td_length_ratio": 0.5, 167 | "td_maxheight": 2.0, 168 | "td_maxlen": 1.0, 169 | "td_on_pad_in_zone": false, 170 | "td_target_name": "td_round_shape", 171 | "td_width_to_size_filter_ratio": 0.9 172 | }, 173 | { 174 | "td_allow_use_two_tracks": true, 175 | "td_curve_segcount": 0, 176 | "td_height_ratio": 1.0, 177 | "td_length_ratio": 0.5, 178 | "td_maxheight": 2.0, 179 | "td_maxlen": 1.0, 180 | "td_on_pad_in_zone": false, 181 | "td_target_name": "td_rect_shape", 182 | "td_width_to_size_filter_ratio": 0.9 183 | }, 184 | { 185 | "td_allow_use_two_tracks": true, 186 | "td_curve_segcount": 0, 187 | "td_height_ratio": 1.0, 188 | "td_length_ratio": 0.5, 189 | "td_maxheight": 2.0, 190 | "td_maxlen": 1.0, 191 | "td_on_pad_in_zone": false, 192 | "td_target_name": "td_track_end", 193 | "td_width_to_size_filter_ratio": 0.9 194 | } 195 | ], 196 | "track_widths": [ 197 | 0.0, 198 | 0.125, 199 | 0.2, 200 | 0.25, 201 | 0.3, 202 | 0.5 203 | ], 204 | "tuning_pattern_settings": { 205 | "diff_pair_defaults": { 206 | "corner_radius_percentage": 80, 207 | "corner_style": 1, 208 | "max_amplitude": 1.0, 209 | "min_amplitude": 0.2, 210 | "single_sided": false, 211 | "spacing": 1.0 212 | }, 213 | "diff_pair_skew_defaults": { 214 | "corner_radius_percentage": 80, 215 | "corner_style": 1, 216 | "max_amplitude": 1.0, 217 | "min_amplitude": 0.2, 218 | "single_sided": false, 219 | "spacing": 0.6 220 | }, 221 | "single_track_defaults": { 222 | "corner_radius_percentage": 80, 223 | "corner_style": 1, 224 | "max_amplitude": 1.0, 225 | "min_amplitude": 0.2, 226 | "single_sided": false, 227 | "spacing": 0.6 228 | } 229 | }, 230 | "via_dimensions": [ 231 | { 232 | "diameter": 0.0, 233 | "drill": 0.0 234 | } 235 | ], 236 | "zones_allow_external_fillets": false, 237 | "zones_use_no_outline": true 238 | }, 239 | "ipc2581": { 240 | "dist": "", 241 | "distpn": "", 242 | "internal_id": "", 243 | "mfg": "", 244 | "mpn": "" 245 | }, 246 | "layer_pairs": [], 247 | "layer_presets": [], 248 | "viewports": [] 249 | }, 250 | "boards": [], 251 | "cvpcb": { 252 | "equivalence_files": [] 253 | }, 254 | "erc": { 255 | "erc_exclusions": [], 256 | "meta": { 257 | "version": 0 258 | }, 259 | "pin_map": [ 260 | [ 261 | 0, 262 | 0, 263 | 0, 264 | 0, 265 | 0, 266 | 0, 267 | 1, 268 | 0, 269 | 0, 270 | 0, 271 | 0, 272 | 2 273 | ], 274 | [ 275 | 0, 276 | 2, 277 | 0, 278 | 1, 279 | 0, 280 | 0, 281 | 1, 282 | 0, 283 | 2, 284 | 2, 285 | 2, 286 | 2 287 | ], 288 | [ 289 | 0, 290 | 0, 291 | 0, 292 | 0, 293 | 0, 294 | 0, 295 | 1, 296 | 0, 297 | 1, 298 | 0, 299 | 1, 300 | 2 301 | ], 302 | [ 303 | 0, 304 | 1, 305 | 0, 306 | 0, 307 | 0, 308 | 0, 309 | 1, 310 | 1, 311 | 2, 312 | 1, 313 | 1, 314 | 2 315 | ], 316 | [ 317 | 0, 318 | 0, 319 | 0, 320 | 0, 321 | 0, 322 | 0, 323 | 1, 324 | 0, 325 | 0, 326 | 0, 327 | 0, 328 | 2 329 | ], 330 | [ 331 | 0, 332 | 0, 333 | 0, 334 | 0, 335 | 0, 336 | 0, 337 | 0, 338 | 0, 339 | 0, 340 | 0, 341 | 0, 342 | 2 343 | ], 344 | [ 345 | 1, 346 | 1, 347 | 1, 348 | 1, 349 | 1, 350 | 0, 351 | 1, 352 | 1, 353 | 1, 354 | 1, 355 | 1, 356 | 2 357 | ], 358 | [ 359 | 0, 360 | 0, 361 | 0, 362 | 1, 363 | 0, 364 | 0, 365 | 1, 366 | 0, 367 | 0, 368 | 0, 369 | 0, 370 | 2 371 | ], 372 | [ 373 | 0, 374 | 2, 375 | 1, 376 | 2, 377 | 0, 378 | 0, 379 | 1, 380 | 0, 381 | 2, 382 | 2, 383 | 2, 384 | 2 385 | ], 386 | [ 387 | 0, 388 | 2, 389 | 0, 390 | 1, 391 | 0, 392 | 0, 393 | 1, 394 | 0, 395 | 2, 396 | 0, 397 | 0, 398 | 2 399 | ], 400 | [ 401 | 0, 402 | 2, 403 | 1, 404 | 1, 405 | 0, 406 | 0, 407 | 1, 408 | 0, 409 | 2, 410 | 0, 411 | 0, 412 | 2 413 | ], 414 | [ 415 | 2, 416 | 2, 417 | 2, 418 | 2, 419 | 2, 420 | 2, 421 | 2, 422 | 2, 423 | 2, 424 | 2, 425 | 2, 426 | 2 427 | ] 428 | ], 429 | "rule_severities": { 430 | "bus_definition_conflict": "error", 431 | "bus_entry_needed": "error", 432 | "bus_label_syntax": "error", 433 | "bus_to_bus_conflict": "error", 434 | "bus_to_net_conflict": "error", 435 | "different_unit_footprint": "error", 436 | "different_unit_net": "error", 437 | "duplicate_reference": "error", 438 | "duplicate_sheet_names": "error", 439 | "endpoint_off_grid": "warning", 440 | "extra_units": "error", 441 | "footprint_filter": "ignore", 442 | "footprint_link_issues": "warning", 443 | "four_way_junction": "ignore", 444 | "global_label_dangling": "warning", 445 | "hier_label_mismatch": "error", 446 | "label_dangling": "error", 447 | "label_multiple_wires": "warning", 448 | "lib_symbol_issues": "warning", 449 | "lib_symbol_mismatch": "warning", 450 | "missing_bidi_pin": "warning", 451 | "missing_input_pin": "warning", 452 | "missing_power_pin": "error", 453 | "missing_unit": "warning", 454 | "multiple_net_names": "warning", 455 | "net_not_bus_member": "warning", 456 | "no_connect_connected": "warning", 457 | "no_connect_dangling": "warning", 458 | "pin_not_connected": "error", 459 | "pin_not_driven": "error", 460 | "pin_to_pin": "warning", 461 | "power_pin_not_driven": "error", 462 | "same_local_global_label": "warning", 463 | "similar_label_and_power": "warning", 464 | "similar_labels": "warning", 465 | "similar_power": "warning", 466 | "simulation_model_issue": "ignore", 467 | "single_global_label": "ignore", 468 | "unannotated": "error", 469 | "unconnected_wire_endpoint": "warning", 470 | "unit_value_mismatch": "error", 471 | "unresolved_variable": "error", 472 | "wire_dangling": "error" 473 | } 474 | }, 475 | "libraries": { 476 | "pinned_footprint_libs": [], 477 | "pinned_symbol_libs": [] 478 | }, 479 | "meta": { 480 | "filename": "Square.kicad_pro", 481 | "version": 2 482 | }, 483 | "net_settings": { 484 | "classes": [ 485 | { 486 | "bus_width": 12, 487 | "clearance": 0.125, 488 | "diff_pair_gap": 0.25, 489 | "diff_pair_via_gap": 0.25, 490 | "diff_pair_width": 0.2, 491 | "line_style": 0, 492 | "microvia_diameter": 0.3, 493 | "microvia_drill": 0.1, 494 | "name": "Default", 495 | "pcb_color": "rgba(0, 0, 0, 0.000)", 496 | "priority": 2147483647, 497 | "schematic_color": "rgba(0, 0, 0, 0.000)", 498 | "track_width": 0.125, 499 | "via_diameter": 0.8, 500 | "via_drill": 0.4, 501 | "wire_width": 6 502 | }, 503 | { 504 | "bus_width": 12, 505 | "clearance": 0.125, 506 | "diff_pair_gap": 0.25, 507 | "diff_pair_via_gap": 0.25, 508 | "diff_pair_width": 0.2, 509 | "line_style": 0, 510 | "microvia_diameter": 0.3, 511 | "microvia_drill": 0.1, 512 | "name": "Power", 513 | "pcb_color": "rgba(0, 0, 0, 0.000)", 514 | "priority": 0, 515 | "schematic_color": "rgba(0, 0, 0, 0.000)", 516 | "track_width": 0.25, 517 | "via_diameter": 0.8, 518 | "via_drill": 0.4, 519 | "wire_width": 6 520 | } 521 | ], 522 | "meta": { 523 | "version": 4 524 | }, 525 | "net_colors": null, 526 | "netclass_assignments": null, 527 | "netclass_patterns": [ 528 | { 529 | "netclass": "Power", 530 | "pattern": "GND" 531 | } 532 | ] 533 | }, 534 | "pcbnew": { 535 | "last_paths": { 536 | "gencad": "", 537 | "idf": "", 538 | "netlist": "", 539 | "plot": "", 540 | "pos_files": "", 541 | "specctra_dsn": "", 542 | "step": "", 543 | "svg": "", 544 | "vrml": "" 545 | }, 546 | "page_layout_descr_file": "" 547 | }, 548 | "schematic": { 549 | "annotate_start_num": 0, 550 | "bom_export_filename": "${PROJECTNAME}.csv", 551 | "bom_fmt_presets": [], 552 | "bom_fmt_settings": { 553 | "field_delimiter": ",", 554 | "keep_line_breaks": false, 555 | "keep_tabs": false, 556 | "name": "CSV", 557 | "ref_delimiter": ",", 558 | "ref_range_delimiter": "", 559 | "string_delimiter": "\"" 560 | }, 561 | "bom_presets": [], 562 | "bom_settings": { 563 | "exclude_dnp": false, 564 | "fields_ordered": [ 565 | { 566 | "group_by": false, 567 | "label": "Reference", 568 | "name": "Reference", 569 | "show": true 570 | }, 571 | { 572 | "group_by": false, 573 | "label": "Qty", 574 | "name": "${QUANTITY}", 575 | "show": true 576 | }, 577 | { 578 | "group_by": true, 579 | "label": "Value", 580 | "name": "Value", 581 | "show": true 582 | }, 583 | { 584 | "group_by": true, 585 | "label": "DNP", 586 | "name": "${DNP}", 587 | "show": true 588 | }, 589 | { 590 | "group_by": true, 591 | "label": "Exclude from BOM", 592 | "name": "${EXCLUDE_FROM_BOM}", 593 | "show": true 594 | }, 595 | { 596 | "group_by": true, 597 | "label": "Exclude from Board", 598 | "name": "${EXCLUDE_FROM_BOARD}", 599 | "show": true 600 | }, 601 | { 602 | "group_by": true, 603 | "label": "Footprint", 604 | "name": "Footprint", 605 | "show": true 606 | }, 607 | { 608 | "group_by": false, 609 | "label": "Datasheet", 610 | "name": "Datasheet", 611 | "show": true 612 | } 613 | ], 614 | "filter_string": "", 615 | "group_symbols": true, 616 | "include_excluded_from_bom": true, 617 | "name": "Default Editing", 618 | "sort_asc": true, 619 | "sort_field": "Reference" 620 | }, 621 | "connection_grid_size": 50.0, 622 | "drawing": { 623 | "dashed_lines_dash_length_ratio": 12.0, 624 | "dashed_lines_gap_length_ratio": 3.0, 625 | "default_line_thickness": 6.0, 626 | "default_text_size": 50.0, 627 | "field_names": [], 628 | "intersheets_ref_own_page": false, 629 | "intersheets_ref_prefix": "", 630 | "intersheets_ref_short": false, 631 | "intersheets_ref_show": false, 632 | "intersheets_ref_suffix": "", 633 | "junction_size_choice": 3, 634 | "label_size_ratio": 0.25, 635 | "operating_point_overlay_i_precision": 3, 636 | "operating_point_overlay_i_range": "~A", 637 | "operating_point_overlay_v_precision": 3, 638 | "operating_point_overlay_v_range": "~V", 639 | "overbar_offset_ratio": 1.23, 640 | "pin_symbol_size": 25.0, 641 | "text_offset_ratio": 0.08 642 | }, 643 | "legacy_lib_dir": "", 644 | "legacy_lib_list": [], 645 | "meta": { 646 | "version": 1 647 | }, 648 | "net_format_name": "", 649 | "ngspice": { 650 | "fix_include_paths": true, 651 | "fix_passive_vals": false, 652 | "meta": { 653 | "version": 0 654 | }, 655 | "model_mode": 0, 656 | "workbook_filename": "" 657 | }, 658 | "page_layout_descr_file": "", 659 | "plot_directory": "", 660 | "space_save_all_events": true, 661 | "spice_adjust_passive_values": false, 662 | "spice_current_sheet_as_root": false, 663 | "spice_external_command": "spice \"%I\"", 664 | "spice_model_current_sheet_as_root": true, 665 | "spice_save_all_currents": false, 666 | "spice_save_all_dissipations": false, 667 | "spice_save_all_voltages": false, 668 | "subpart_first_id": 65, 669 | "subpart_id_separator": 0 670 | }, 671 | "sheets": [ 672 | [ 673 | "0217dfc4-fc13-4699-99ad-d9948522648e", 674 | "Root" 675 | ] 676 | ], 677 | "text_variables": { 678 | "DATE": "2022-08-05", 679 | "URL": "pn532.revk.uk" 680 | } 681 | } 682 | -------------------------------------------------------------------------------- /PCB/Square/Square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Square/Square.png -------------------------------------------------------------------------------- /PCB/Square/Square.scad: -------------------------------------------------------------------------------- 1 | // Case for NFC reader 2 | // Controls 3 | cover=0; // How much to cover the SMD LEDs on antenna side 4 | // Note it is assumed leaded components cut flush 5 | base=0; // How much extra base (e.g. for mounting off metal) 6 | thick=3; // Wall thickness 7 | led=1; // LED/front thickness 8 | 9 | raspox=true; // Right angle SPOX side cable 10 | spox=true; // Straight SPOX rear 11 | tamper=true; // Tamper button fitted 12 | tamperth=false; // Tamper is through hole 13 | bell=true; // Tamper 2 pin header rear 14 | screws=true; 15 | 16 | corner=8; // PCB corner radius 17 | chamfer=1; // Case chamfer 18 | size=20; // PCB size/2 19 | pcb=0.8; // PCB thickness 20 | slide=1; // Screw hold slide 21 | 22 | $fn=100; 23 | 24 | module b(cx,cy,z,w,l,h) 25 | { 26 | translate([cx-w/2,cy-l/2,z])cube([w,l,h]); 27 | } 28 | 29 | module base() 30 | { 31 | difference() 32 | { 33 | union() 34 | { 35 | hull()for(x=[corner-size,size-corner])for(y=[corner-size,size-corner])translate([x,y,0])cylinder(r=corner+0.2,h=4.9+base); 36 | if(base>0)hull()for(x=[-12,12])for(y=[-12,12])translate([x,y,4.9]) 37 | { 38 | if(base>1)translate([0,0,base-1])cylinder(r=9+thick+base-1,h=1); 39 | cylinder(r=corner+thick,h=base); 40 | } 41 | } 42 | translate([0,0,-0.1])hull()for(x=[-12,12])for(y=[-12,12])translate([x,y,0])cylinder(r=5,h=3); 43 | if(raspox)b(0,-8.9-6.6+7.9/2-2-20,-0.01,12.4+0.2,7.9+0.2+40,4.92); 44 | if(spox)b(0,-8.9+3.1-4.9/2,-0.01,12.4+0.5,4.9+0.5,5+base); 45 | if(tamper)b(-11.5,0,0,7,7,3.9); // Under 6x6 but SMD so may not be exact placement 46 | if(bell)b(12,-6,-0.01,4.82+0.4,5.64+0.4,5+base); 47 | if(screws)for(t=[-12,12])translate([t,-t,2.9]) 48 | { // Screws in base 49 | hull()for(t=[-slide/2,slide/2]) 50 | translate([t,t,-1])cylinder(d=3.5,h=3+base+2); 51 | hull()for(t=[-slide/2,slide/2]) 52 | translate([t,t,-0.01])cylinder(d=7,h=base/2+0.5); 53 | hull()for(t=[-slide/2,slide/2]) 54 | translate([t,t,0.48+base/2])cylinder(d1=7,d2=3.5,h=2); 55 | } 56 | for(y=[-9,9])hull() 57 | { // Clip 58 | b(-size,y,3.901,1,8+0.2,1); 59 | b(-size-1,y,2.9,1,8+0.2,1); 60 | } 61 | translate([-1,size-5,-0.01]) 62 | cube([2,6,1]); // Resistor to ground on antenna 63 | } 64 | } 65 | 66 | module top() 67 | { 68 | difference() 69 | { 70 | hull()for(x=[corner-size,size-corner])for(y=[corner-size,size-corner])translate([x,y,0]) 71 | { 72 | translate([0,0,chamfer]) 73 | cylinder(r=corner+thick,h=led+cover+pcb+4.9-chamfer-(base>0?0:chamfer)); 74 | cylinder(r=corner+thick-chamfer,h=led+cover+pcb+4.9); 75 | } 76 | translate([0,0,led+cover]) 77 | hull() 78 | { 79 | for(x=[corner-size,size-corner])for(y=[corner-size,size-corner])translate([x,y,0])cylinder(r=corner+0.2,h=pcb+4.9+1); 80 | } 81 | // LEDs 82 | for(y=[12,6,0]) 83 | { 84 | // New reverse LED 85 | translate([12,y,0.2])cylinder(d=1.4,h=2+led); 86 | // older surface LED 87 | *b(12,y,-0.01,1.4,1.6,1); 88 | *b(12,y,cover+led-0.3,1.8,4.6,1); 89 | } 90 | if(spox||raspox)b(0,-8.9,cover+0.7,10,2.5,1); 91 | if(tamperth)b(-11.5,-3.25,cover+0.5,7.5,2.5,1); 92 | if(tamperth)b(-11.5,+3.25,cover+0.5,7.5,2.5,1); 93 | if(bell)b(12,-6,cover+0.5,2.54,2.54*2,1); 94 | if(raspox)b(0,-8.9-6.6+7.9-20,led+cover+pcb+1,4,40,4); // cable 95 | } 96 | for(t=[-12,12])translate([t,-t,0])cylinder(d=3,h=led+cover+pcb); 97 | for(y=[-9,9])hull() 98 | { // Clip 99 | b(-size,y,led+cover+pcb+3.9,1,8,1); 100 | b(-size-1,y,led+cover+pcb+3.9-1,1,8,1); 101 | } 102 | } 103 | 104 | 105 | translate([0,0,4.9+base])rotate([180,0,0])base(); 106 | translate([45+thick+base,0,0])top(); 107 | 108 | -------------------------------------------------------------------------------- /PCB/Square/production/bom.csv: -------------------------------------------------------------------------------- 1 | Designator,Footprint,Quantity,Value,LCSC Part # 2 | "C1, C2",C_0603,2,160pF, 3 | "C10, C13, C15",C_0603,3,4.7uF, 4 | "C11, C12, C14, C18, C7, C9",C_0603,6,100nF, 5 | "C16, C17, C3, C4",C_0603,4,22pF, 6 | C19,C_0603,1,33pF, 7 | "C5, C6",C_0603,2,220pF, 8 | C8,C_0603,1,1nF, 9 | D1,STP_156120xx7530,1,G, 10 | D2,STP_156120xx7530,1,A, 11 | D3,STP_156120xx7530,1,R, 12 | "D4, D5, D6",SOT-363_SC-70-6,3,BAV99S, 13 | "L1, L2",L_1206_1008,2,560nH, 14 | "R1, R3",R_0603_,2,0R, 15 | "R10, R12, R13, R14, R8, R9",R_0603,6,100R, 16 | "R11, R15, R6",R_0603,3,10K, 17 | R2,R_0805_,1,0R, 18 | R4,R_0603,1,2K7 1%, 19 | R5,R_0603,1,1K 1%, 20 | R7,R_0603,1,20K, 21 | SW1,ESE13,1,ESE13V01D, 22 | U1,QFN-40-1EP_6x6mm_P0.5mm_EP4.6x4.6mm,1,PN532, 23 | Y1,Crystal-3.2x2.5,1,27.12MHz, 24 | -------------------------------------------------------------------------------- /PCB/Square/production/designators.csv: -------------------------------------------------------------------------------- 1 | A1:1 2 | AJK1:1 3 | C1:1 4 | C10:1 5 | C11:1 6 | C12:1 7 | C13:1 8 | C14:1 9 | C15:1 10 | C16:1 11 | C17:1 12 | C18:1 13 | C19:1 14 | C2:1 15 | C3:1 16 | C4:1 17 | C5:1 18 | C6:1 19 | C7:1 20 | C8:1 21 | C9:1 22 | D1:1 23 | D2:1 24 | D3:1 25 | D4:1 26 | D5:1 27 | D6:1 28 | H1:1 29 | H2:1 30 | J1:1 31 | J2:1 32 | JP1:1 33 | L1:1 34 | L2:1 35 | R1:1 36 | R10:1 37 | R11:1 38 | R12:1 39 | R13:1 40 | R14:1 41 | R15:1 42 | R2:1 43 | R3:1 44 | R4:1 45 | R5:1 46 | R6:1 47 | R7:1 48 | R8:1 49 | R9:1 50 | SW1:1 51 | TP1:1 52 | U1:1 53 | U2:1 54 | U3:1 55 | Y1:1 56 | -------------------------------------------------------------------------------- /PCB/Square/production/gerber.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Square/production/gerber.zip -------------------------------------------------------------------------------- /PCB/Square/production/netlist.ipc: -------------------------------------------------------------------------------- 1 | P CODE 00 2 | P UNITS CUST 0 3 | P arrayDim N 4 | 317GND VIA MD0157PA00X+041102Y-040669X0315Y0000R000S3 5 | 317GND VIA MD0157PA00X+043680Y-035812X0315Y0000R000S3 6 | 317GND VIA MD0157PA00X+036614Y-040777X0315Y0000R000S3 7 | 317GND VIA MD0157PA00X+035945Y-040787X0315Y0000R000S3 8 | 317GND VIA MD0157PA00X+041541Y-039702X0315Y0000R000S3 9 | 317GND VIA MD0157PA00X+039370Y-036545X0315Y0000R000S3 10 | 317GND VIA MD0157PA00X+042913Y-042232X0315Y0000R000S3 11 | 317GND VIA MD0157PA00X+039370Y-039386X0315Y0000R000S3 12 | 317GND VIA MD0157PA00X+043701Y-040591X0315Y0000R000S3 13 | 317GND VIA MD0157PA00X+043547Y-038039X0315Y0000R000S3 14 | 317GND VIA MD0157PA00X+039764Y-039780X0315Y0000R000S3 15 | 317GND VIA MD0157PA00X+038210Y-040700X0315Y0000R000S3 16 | 317GND VIA MD0157PA00X+038976Y-039764X0315Y0000R000S3 17 | 317GND VIA MD0157PA00X+041801Y-037598X0315Y0000R000S3 18 | 317GND VIA MD0157PA00X+042913Y-040542X0315Y0000R000S3 19 | 317GND VIA MD0157PA00X+042913Y-041565X0315Y0000R000S3 20 | 317GND VIA MD0157PA00X+039764Y-038976X0315Y0000R000S3 21 | 317GND VIA MD0157PA00X+038976Y-038976X0315Y0000R000S3 22 | 317GND VIA MD0157PA00X+037776Y-038652X0315Y0000R000S3 23 | 317+3V3 VIA MD0157PA00X+038327Y-037480X0315Y0000R000S3 24 | 317+3V3 VIA MD0157PA00X+042165Y-037953X0315Y0000R000S3 25 | 317+3V3 VIA MD0157PA00X+036299Y-036555X0315Y0000R000S3 26 | 317+3V3 VIA MD0157PA00X+042165Y-040906X0315Y0000R000S3 27 | 317+3V3 VIA MD0157PA00X+042165Y-041693X0315Y0000R000S3 28 | 317+3V3 VIA MD0157PA00X+035984Y-041732X0315Y0000R000S3 29 | 317+3V3 VIA MD0157PA00X+039182Y-037276X0315Y0000R000S3 30 | 317+5V VIA MD0157PA00X+042913Y-037156X0315Y0000R000S3 31 | 317+5V VIA MD0157PA00X+041437Y-037835X0315Y0000R000S3 32 | 317+5V VIA MD0157PA00X+041437Y-037156X0315Y0000R000S3 33 | 317NET-(D1-PAD2) VIA MD0157PA00X+044295Y-038291X0315Y0000R000S3 34 | 317NET-(D1-PAD2) VIA MD0157PA00X+043573Y-039783X0315Y0000R000S3 35 | 317NET-(D2-PAD2) VIA MD0157PA00X+044096Y-035812X0315Y0000R000S3 36 | 317NET-(D2-PAD2) VIA MD0157PA00X+043921Y-038165X0315Y0000R000S3 37 | 317NET-(D3-PAD2) VIA MD0157PA00X+042953Y-039142X0315Y0000R000S3 38 | 317NET-(D3-PAD2) VIA MD0157PA00X+043263Y-035812X0315Y0000R000S3 39 | 317NET-(C9-PAD1) VIA MD0157PA00X+037087Y-036890X0315Y0000R000S3 40 | 317NET-(C9-PAD1) VIA MD0157PA00X+037962Y-037766X0315Y0000R000S3 41 | 317NET-(J2-PAD4) VIA MD0157PA00X+041693Y-042126X0315Y0000R000S3 42 | 327NET-(C16-PAD1) Y1 -1 A01X+036614Y-038917X0512Y0413R270S2 43 | 327GND Y1 -2 A01X+036614Y-039823X0512Y0413R270S2 44 | 327NET-(C17-PAD1) Y1 -3 A01X+037303Y-039823X0512Y0413R270S2 45 | 327GND Y1 -4 A01X+037303Y-038917X0512Y0413R270S2 46 | 367N/C H2 D1260UA00X+034646Y-034646X1260Y0000R000S0 47 | 367N/C H1 D1260UA00X+044094Y-044094X1260Y0000R000S0 48 | 317N/C D2 D0709PA00X+044094Y-037008X0717Y0000R270S0 49 | 327GND D2 -1 A01X+044094Y-037648X0197Y0197R270S2 50 | 327NET-(D2-PAD2) D2 -2 A01X+044094Y-036368X0197Y0197R090S2 51 | 317N/C D3 D0709PA00X+044094Y-034646X0717Y0000R270S0 52 | 327GND D3 -1 A01X+044094Y-035285X0197Y0197R270S2 53 | 327NET-(D3-PAD2) D3 -2 A01X+044094Y-034006X0197Y0197R090S2 54 | 327N/C SW1 A01X+035898Y-040197X0276Y0472R270S2 55 | 327N/C SW1 A01X+034508Y-040197X0276Y0472R270S2 56 | 327GND SW1 -1 A01X+034496Y-041378X0276Y0472R270S2 57 | 327NET-(R11-PAD2) SW1 -2 A01X+035898Y-041378X0276Y0472R270S2 58 | 317N/C D1 D0709PA00X+044094Y-039370X0717Y0000R270S0 59 | 327GND D1 -1 A01X+044094Y-040010X0197Y0197R270S2 60 | 327NET-(D1-PAD2) D1 -2 A01X+044094Y-038730X0197Y0197R090S2 61 | 327+3V3 C7 -1 A01X+039606Y-037480X0315Y0374R000S2 62 | 327GND C7 -2 A01X+040217Y-037480X0315Y0374R000S2 63 | 327NET-(C3-PAD1) C3 -1 A01X+040866Y-034764X0315Y0374R270S2 64 | 327NET-(A1-PAD1) C3 -2 A01X+040866Y-034154X0315Y0374R270S2 65 | 327GND C5 -1 A01X+039734Y-034754X0315Y0374R000S2 66 | 327NET-(C3-PAD1) C5 -2 A01X+040344Y-034754X0315Y0374R000S2 67 | 327NET-(R6-PAD1) R6 -1 A01X+042589Y-037717X0315Y0374R000S2 68 | 327+5V R6 -2 A01X+043238Y-037717X0315Y0374R000S2 69 | 327NET-(C8-PAD2) R4 -1 A01X+036644Y-034754X0315Y0374R000S2 70 | 327NET-(C4-PAD2) R4 -2 A01X+037293Y-034754X0315Y0374R000S2 71 | 327+3V3 C13 -1 A01X+041791Y-038907X0315Y0374R090S2 72 | 327GND C13 -2 A01X+041791Y-039518X0315Y0374R090S2 73 | 327+5V C14 -1 A01X+041191Y-038307X0315Y0374R000S2 74 | 327GND C14 -2 A01X+041801Y-038307X0315Y0374R000S2 75 | 327NET-(C9-PAD1) C9 -1 A01X+036654Y-037303X0315Y0374R000S2 76 | 327GND C9 -2 A01X+037264Y-037303X0315Y0374R000S2 77 | 327NET-(C16-PAD1) C16 -1 A01X+036654Y-038386X0315Y0374R000S2 78 | 327GND C16 -2 A01X+037264Y-038386X0315Y0374R000S2 79 | 327NET-(R9-PAD1) R9 -1 A01X+042589Y-039488X0315Y0374R000S2 80 | 327NET-(D2-PAD2) R9 -2 A01X+043238Y-039488X0315Y0374R000S2 81 | 327NET-(R8-PAD1) R8 -1 A01X+042589Y-040079X0315Y0374R000S2 82 | 327NET-(D1-PAD2) R8 -2 A01X+043238Y-040079X0315Y0374R000S2 83 | 327+3V3 R11 -1 A01X+039094Y-041722X0315Y0374R270S2 84 | 327NET-(R11-PAD2) R11 -2 A01X+039094Y-041073X0315Y0374R270S2 85 | 327GND U1 -1 A01X+040256Y-038228X0276Y0098R090S2 86 | 327CTED-(U1-PAD2) U1 -2 A01X+040059Y-038228X0276Y0098R090S2 87 | 327GND U1 -3 A01X+039862Y-038228X0276Y0098R090S2 88 | 327NET-(L1-PAD1) U1 -4 A01X+039665Y-038228X0276Y0098R090S2 89 | 327+3V3 U1 -5 A01X+039469Y-038228X0276Y0098R090S2 90 | 327NET-(L2-PAD2) U1 -6 A01X+039272Y-038228X0276Y0098R090S2 91 | 327GND U1 -7 A01X+039075Y-038228X0276Y0098R090S2 92 | 327+3V3 U1 -8 A01X+038878Y-038228X0276Y0098R090S2 93 | 327NET-(C9-PAD1) U1 -9 A01X+038681Y-038228X0276Y0098R090S2 94 | 327NET-(C8-PAD1) U1 -10 A01X+038484Y-038228X0276Y0098R090S2 95 | 327GND U1 -11 A01X+038228Y-038484X0098Y0276R090S2 96 | 327TED-(U1-PAD12) U1 -12 A01X+038228Y-038681X0098Y0276R090S2 97 | 327TED-(U1-PAD13) U1 -13 A01X+038228Y-038878X0098Y0276R090S2 98 | 327NET-(C16-PAD1) U1 -14 A01X+038228Y-039075X0098Y0276R090S2 99 | 327NET-(C17-PAD1) U1 -15 A01X+038228Y-039272X0098Y0276R090S2 100 | 327GND U1 -16 A01X+038228Y-039469X0098Y0276R090S2 101 | 327NET-(JP1-PAD2) U1 -17 A01X+038228Y-039665X0098Y0276R090S2 102 | 327GND U1 -18 A01X+038228Y-039862X0098Y0276R090S2 103 | 327TED-(U1-PAD19) U1 -19 A01X+038228Y-040059X0098Y0276R090S2 104 | 327TED-(U1-PAD20) U1 -20 A01X+038228Y-040256X0098Y0276R090S2 105 | 327TED-(U1-PAD21) U1 -21 A01X+038484Y-040512X0276Y0098R090S2 106 | 327TED-(U1-PAD22) U1 -22 A01X+038681Y-040512X0276Y0098R090S2 107 | 327+3V3 U1 -23 A01X+038878Y-040512X0276Y0098R090S2 108 | 327NET-(R11-PAD2) U1 -24 A01X+039075Y-040512X0276Y0098R090S2 109 | 327TED-(U1-PAD25) U1 -25 A01X+039272Y-040512X0276Y0098R090S2 110 | 327TED-(U1-PAD26) U1 -26 A01X+039469Y-040512X0276Y0098R090S2 111 | 327NET-(C19-PAD1) U1 -27 A01X+039665Y-040512X0276Y0098R090S2 112 | 327NET-(D6-PAD6) U1 -28 A01X+039862Y-040512X0276Y0098R090S2 113 | 327TED-(U1-PAD29) U1 -29 A01X+040059Y-040512X0276Y0098R090S2 114 | 327NET-(D4-PAD3) U1 -30 A01X+040256Y-040512X0276Y0098R090S2 115 | 327NET-(R8-PAD1) U1 -31 A01X+040512Y-040256X0098Y0276R090S2 116 | 327NET-(R9-PAD1) U1 -32 A01X+040512Y-040059X0098Y0276R090S2 117 | 327NET-(R10-PAD1) U1 -33 A01X+040512Y-039862X0098Y0276R090S2 118 | 327TED-(U1-PAD34) U1 -34 A01X+040512Y-039665X0098Y0276R090S2 119 | 327TED-(U1-PAD35) U1 -35 A01X+040512Y-039469X0098Y0276R090S2 120 | 327TED-(U1-PAD36) U1 -36 A01X+040512Y-039272X0098Y0276R090S2 121 | 327TED-(U1-PAD37) U1 -37 A01X+040512Y-039075X0098Y0276R090S2 122 | 327NET-(R6-PAD1) U1 -38 A01X+040512Y-038878X0098Y0276R090S2 123 | 327+3V3 U1 -39 A01X+040512Y-038681X0098Y0276R090S2 124 | 327+5V U1 -40 A01X+040512Y-038484X0098Y0276R090S2 125 | 327GND U1 -41 A01X+039370Y-039370X1732Y1732R090S2 126 | 327NET-(C17-PAD1) C17 -1 A01X+037264Y-040354X0315Y0374R180S2 127 | 327GND C17 -2 A01X+036654Y-040354X0315Y0374R180S2 128 | 317GND J1 -1 D0394PA00X+044094Y-042232X0669Y0669R180S0 129 | 317NET-(J1-PAD2) J1 -2 D0394PA00X+044094Y-041232X0669Y0669R180S0 130 | 327+3V3 C12 -1 A01X+039134Y-036949X0315Y0374R180S2 131 | 327GND C12 -2 A01X+038524Y-036949X0315Y0374R180S2 132 | 327NET-(C8-PAD1) R5 -1 A01X+036654Y-036230X0315Y0374R090S2 133 | 327NET-(C9-PAD1) R5 -2 A01X+036654Y-036880X0315Y0374R090S2 134 | 327NET-(R6-PAD1) R7 -1 A01X+042589Y-038307X0315Y0374R000S2 135 | 327GND R7 -2 A01X+043238Y-038307X0315Y0374R000S2 136 | 327NET-(R10-PAD1) R10 -1 A01X+042589Y-038898X0315Y0374R000S2 137 | 327NET-(D3-PAD2) R10 -2 A01X+043238Y-038898X0315Y0374R000S2 138 | 327+3V3 C18 -1 A01X+038465Y-041703X0315Y0374R270S2 139 | 327GND C18 -2 A01X+038465Y-041093X0315Y0374R270S2 140 | 327+3V3 C11 -1 A01X+041201Y-038907X0315Y0374R090S2 141 | 327GND C11 -2 A01X+041201Y-039518X0315Y0374R090S2 142 | 327NET-(C8-PAD1) C8 -1 A01X+036654Y-035817X0315Y0374R270S2 143 | 327NET-(C8-PAD2) C8 -2 A01X+036654Y-035207X0315Y0374R270S2 144 | 317GND J2 -1 D0335PA00X+037894Y-042874X0669Y0728R000S0 145 | 317+5V J2 -2 D0335PA00X+038878Y-042874X0669Y0728R000S0 146 | 317NET-(J2-PAD3) J2 -3 D0335PA00X+039862Y-042874X0669Y0728R000S0 147 | 317NET-(J2-PAD4) J2 -4 D0335PA00X+040846Y-042874X0669Y0728R000S0 148 | 327+3V3 C10 -1 A01X+039606Y-036949X0315Y0374R000S2 149 | 327GND C10 -2 A01X+040217Y-036949X0315Y0374R000S2 150 | 327NET-(A1-PAD1) C1 -1 A01X+040344Y-034134X0315Y0374R180S2 151 | 327GND C1 -2 A01X+039734Y-034134X0315Y0374R180S2 152 | 327GND C6 -1 A01X+039006Y-034754X0315Y0374R180S2 153 | 327NET-(C4-PAD2) C6 -2 A01X+038396Y-034754X0315Y0374R180S2 154 | 327+3V3 R15 -1 A01X+041575Y-041722X0315Y0374R270S2 155 | 327NET-(D4-PAD3) R15 -2 A01X+041575Y-041073X0315Y0374R270S2 156 | 317NET-(L1-PAD1) TP1 -1 D0315PA00X+039862Y-036378X0472Y0000R180S0 157 | 317NET-(L2-PAD2) TP1 -2 D0315PA00X+038878Y-036378X0472Y0000R180S0 158 | 327GND JP1 -1 A01X+036752Y-041496X0394Y0197R000S2 159 | 327NET-(JP1-PAD2) JP1 -2 A01X+037264Y-041496X0394Y0591R000S2 160 | 327+3V3 JP1 -3 A01X+037776Y-041496X0394Y0197R000S2 161 | 327NET-(J2-PAD3) R13 -1 A01X+039695Y-041693X0315Y0374R000S2 162 | 327NET-(D6-PAD6) R13 -2 A01X+040344Y-041693X0315Y0374R000S2 163 | 327+3V3 C15 -1 A01X+036654Y-037835X0315Y0374R000S2 164 | 327GND C15 -2 A01X+037264Y-037835X0315Y0374R000S2 165 | 327NET-(J2-PAD4) R14 -1 A01X+040344Y-041102X0315Y0374R180S2 166 | 327NET-(C19-PAD1) R14 -2 A01X+039695Y-041102X0315Y0374R180S2 167 | 327NET-(L1-PAD1) L1 -1 A01X+040371Y-036105X0276Y0984R315S2 168 | 327NET-(L1-PAD1) L1 -1 A01X+040260Y-036217X0402Y0760R315S2 169 | 327NET-(C3-PAD1) L1 -2 A01X+041039Y-035437X0402Y0760R315S2 170 | 327NET-(C3-PAD1) L1 -2 A01X+040928Y-035548X0276Y0984R315S2 171 | 327NET-(C4-PAD2) L2 -1 A01X+037701Y-035437X0402Y0760R045S2 172 | 327NET-(C4-PAD2) L2 -1 A01X+037812Y-035548X0276Y0984R045S2 173 | 327NET-(L2-PAD2) L2 -2 A01X+038369Y-036105X0276Y0984R045S2 174 | 327NET-(L2-PAD2) L2 -2 A01X+038480Y-036217X0402Y0760R045S2 175 | 327NET-(A1-PAD3) C4 -1 A01X+037874Y-034154X0315Y0374R090S2 176 | 327NET-(C4-PAD2) C4 -2 A01X+037874Y-034764X0315Y0374R090S2 177 | 327NET-(D4-PAD3) R12 -1 A01X+040945Y-041073X0315Y0374R090S2 178 | 327NET-(J1-PAD2) R12 -2 A01X+040945Y-041722X0315Y0374R090S2 179 | 327GND D5 -1 A01X+042539Y-036713X0256Y0157R000S2 180 | 327+3V3 D5 -2 A01X+042539Y-036969X0256Y0157R000S2 181 | 327NET-(D3-PAD2) D5 -3 A01X+042539Y-037224X0256Y0157R000S2 182 | 327GND D5 -4 A01X+043287Y-037224X0256Y0157R000S2 183 | 327+3V3 D5 -5 A01X+043287Y-036969X0256Y0157R000S2 184 | 327NET-(D2-PAD2) D5 -6 A01X+043287Y-036713X0256Y0157R000S2 185 | 327N/C U2 A01X+035197Y-042992X0079Y0236R000S3 186 | 327N/C U2 A01X+034567Y-043425X0079Y0157R000S3 187 | 327N/C U2 A01X+034409Y-042953X0079Y0472R000S3 188 | 327N/C U2 A01X+035236Y-044173X0157Y0079R000S3 189 | 327N/C U2 A01X+035039Y-043780X0079Y0236R000S3 190 | 327N/C U2 A01X+035748Y-044331X0551Y0079R000S3 191 | 327N/C U2 A01X+035748Y-044094X0236Y0236R000S3 192 | 327N/C U2 A01X+035984Y-043268X0079Y0315R000S3 193 | 327N/C U2 A01X+035669Y-043268X0079Y0157R000S3 194 | 327N/C U2 A01X+035748Y-043622X0079Y0079R000S3 195 | 327N/C U2 A01X+035118Y-043307X0236Y0079R000S3 196 | 327N/C U2 A01X+035039Y-043150X0079Y0236R000S3 197 | 327N/C U2 A01X+034646Y-044331X0551Y0079R000S3 198 | 327N/C U2 A01X+035118Y-042835X0079Y0079R000S3 199 | 327N/C U2 A01X+035906Y-042835X0079Y0079R000S3 200 | 327N/C U2 A01X+035669Y-043543X0079Y0079R000S3 201 | 327N/C U2 A01X+035433Y-043701X0236Y0079R000S3 202 | 327N/C U2 A01X+035669Y-043071X0079Y0079R000S3 203 | 327N/C U2 A01X+034488Y-043701X0236Y0079R000S3 204 | 327N/C U2 A01X+035354Y-043898X0079Y0157R000S3 205 | 327N/C U2 A01X+035197Y-043740X0079Y0472R000S3 206 | 327N/C U2 A01X+035591Y-043150X0079Y0236R000S3 207 | 327N/C U2 A01X+034606Y-043543X0157Y0079R000S3 208 | 327N/C U2 A01X+035433Y-043465X0079Y0079R000S3 209 | 327N/C U2 A01X+034882Y-044055X0079Y0472R000S3 210 | 327N/C U2 A01X+035315Y-044094X0157Y0079R000S3 211 | 327N/C U2 A01X+035512Y-043071X0079Y0079R000S3 212 | 327N/C U2 A01X+034646Y-042756X0394Y0079R000S3 213 | 327N/C U2 A01X+035984Y-042835X0079Y0236R000S3 214 | 327N/C U2 A01X+035512Y-043504X0079Y0315R000S3 215 | 327N/C U2 A01X+035591Y-043425X0079Y0157R000S3 216 | 327N/C U2 A01X+034449Y-043543X0157Y0236R000S3 217 | 327N/C U2 A01X+035394Y-043307X0157Y0079R000S3 218 | 327N/C U2 A01X+035591Y-042913X0079Y0079R000S3 219 | 327N/C U2 A01X+035276Y-042835X0079Y0236R000S3 220 | 327N/C U2 A01X+035315Y-043228X0157Y0079R000S3 221 | 327N/C U2 A01X+034646Y-044094X0236Y0236R000S3 222 | 327N/C U2 A01X+034882Y-043386X0079Y0079R000S3 223 | 327N/C U2 A01X+035984Y-044055X0079Y0472R000S3 224 | 327N/C U2 A01X+035118Y-044252X0079Y0079R000S3 225 | 327N/C U2 A01X+035512Y-044055X0079Y0472R000S3 226 | 327N/C U2 A01X+034646Y-043228X0551Y0079R000S3 227 | 327N/C U2 A01X+035945Y-043622X0157Y0079R000S3 228 | 327N/C U2 A01X+035039Y-044173X0079Y0079R000S3 229 | 327N/C U2 A01X+035354Y-043504X0079Y0157R000S3 230 | 327N/C U2 A01X+035827Y-043071X0079Y0079R000S3 231 | 327N/C U2 A01X+034843Y-043701X0315Y0079R000S3 232 | 327N/C U2 A01X+035748Y-042795X0079Y0157R000S3 233 | 327N/C U2 A01X+035276Y-043150X0079Y0079R000S3 234 | 327N/C U2 A01X+035906Y-042992X0079Y0079R000S3 235 | 327N/C U2 A01X+034724Y-043425X0079Y0157R000S3 236 | 327N/C U2 A01X+035118Y-043150X0079Y0079R000S3 237 | 327N/C U2 A01X+035118Y-044016X0079Y0236R000S3 238 | 327N/C U2 A01X+034882Y-042953X0079Y0472R000S3 239 | 327N/C U2 A01X+034646Y-042992X0236Y0236R000S3 240 | 327N/C U2 A01X+035354Y-042795X0079Y0157R000S3 241 | 327N/C U2 A01X+035748Y-043858X0394Y0079R000S3 242 | 327N/C U2 A01X+034882Y-043543X0079Y0079R000S3 243 | 327N/C U2 A01X+035039Y-043465X0079Y0079R000S3 244 | 327N/C U2 A01X+034961Y-043504X0079Y0315R000S3 245 | 327N/C U2 A01X+035276Y-043780X0079Y0079R000S3 246 | 327N/C U2 A01X+035827Y-043661X0079Y0157R000S3 247 | 327N/C U2 A01X+035276Y-043622X0079Y0079R000S3 248 | 327N/C U2 A01X+035433Y-043071X0079Y0236R000S3 249 | 327N/C U2 A01X+034409Y-044055X0079Y0472R000S3 250 | 327N/C U2 A01X+035118Y-043622X0079Y0079R000S3 251 | 327N/C U2 A01X+035197Y-043386X0236Y0079R000S3 252 | 327N/C U2 A01X+035197Y-044331X0079Y0079R000S3 253 | 327N/C U2 A01X+035591Y-042756X0079Y0079R000S3 254 | 327N/C U2 A01X+035039Y-042835X0079Y0236R000S3 255 | 327N/C U2 A01X+035354Y-044291X0079Y0157R000S3 256 | 327N/C U2 A01X+034646Y-043858X0394Y0079R000S3 257 | 327N/C U2 A01X+035787Y-043228X0157Y0079R000S3 258 | 327NET-(C19-PAD1) C19 -1 A01X+042608Y-042598X0315Y0374R000S2 259 | 327GND C19 -2 A01X+043219Y-042598X0315Y0374R000S2 260 | 327GND D4 -1 A01X+042539Y-040571X0256Y0157R000S2 261 | 327+3V3 D4 -2 A01X+042539Y-040827X0256Y0157R000S2 262 | 327NET-(D4-PAD3) D4 -3 A01X+042539Y-041083X0256Y0157R000S2 263 | 327GND D4 -4 A01X+043287Y-041083X0256Y0157R000S2 264 | 327+3V3 D4 -5 A01X+043287Y-040827X0256Y0157R000S2 265 | 327NET-(D1-PAD2) D4 -6 A01X+043287Y-040571X0256Y0157R000S2 266 | 327GND D6 -1 A01X+043287Y-042106X0256Y0157R180S2 267 | 327+3V3 D6 -2 A01X+043287Y-041850X0256Y0157R180S2 268 | 327NET-(C19-PAD1) D6 -3 A01X+043287Y-041594X0256Y0157R180S2 269 | 327GND D6 -4 A01X+042539Y-041594X0256Y0157R180S2 270 | 327+3V3 D6 -5 A01X+042539Y-041850X0256Y0157R180S2 271 | 327NET-(D6-PAD6) D6 -6 A01X+042539Y-042106X0256Y0157R180S2 272 | 327N/C A1 A01X+039370Y-031890X0197Y0591R090S2 273 | 317N/C A1 D0098PA00X+039764Y-031890X0236Y0000R090S3 274 | 317N/C A1 D0098PA00X+038976Y-031890X0236Y0000R090S3 275 | 327N/C A1 A01X+038189Y-032677X0197Y0197R000S3 276 | 327N/C A1 A02X+039370Y-031890X0591Y0197R000S3 277 | 317N/C A1 D0098PA00X+038189Y-032677X0236Y0000R090S3 278 | 327N/C A1 A01X+039370Y-031890X0591Y0197R000S3 279 | 327N/C A1 A01X+040157Y-032736X0315Y0374R090S2 280 | 327N/C A1 A01X+038583Y-032736X0315Y0374R090S2 281 | 327NET-(A1-PAD1) A1 -1 A01X+040157Y-033406X0315Y0374R090S2 282 | 327GND A1 -2 A01X+039370Y-032677X0197Y0591R090S2 283 | 327NET-(A1-PAD3) A1 -3 A01X+038583Y-033406X0315Y0374R090S2 284 | 327GND C2 -1 A01X+039006Y-034134X0315Y0374R180S2 285 | 327NET-(A1-PAD3) C2 -2 A01X+038396Y-034134X0315Y0374R180S2 286 | 327N/C U3 A02X+035748Y-043228X0551Y0079R180S3 287 | 327N/C U3 A02X+034882Y-043071X0079Y0079R180S3 288 | 327N/C U3 A02X+034803Y-043425X0079Y0157R180S3 289 | 327N/C U3 A02X+034409Y-043268X0079Y0315R180S3 290 | 327N/C U3 A02X+035118Y-043780X0079Y0079R180S3 291 | 327N/C U3 A02X+035039Y-043504X0079Y0157R180S3 292 | 327N/C U3 A02X+034803Y-043150X0079Y0236R180S3 293 | 327N/C U3 A02X+034488Y-042835X0079Y0079R180S3 294 | 327N/C U3 A02X+035787Y-043543X0157Y0079R180S3 295 | 327N/C U3 A02X+035551Y-043701X0315Y0079R180S3 296 | 327N/C U3 A02X+035512Y-043543X0079Y0079R180S3 297 | 327N/C U3 A02X+035433Y-043504X0079Y0315R180S3 298 | 327N/C U3 A02X+034646Y-043622X0079Y0079R180S3 299 | 327N/C U3 A02X+035079Y-043228X0157Y0079R180S3 300 | 327N/C U3 A02X+034606Y-043228X0157Y0079R180S3 301 | 327N/C U3 A02X+035945Y-043543X0157Y0236R180S3 302 | 327N/C U3 A02X+035984Y-042953X0079Y0472R180S3 303 | 327N/C U3 A02X+035354Y-042835X0079Y0236R180S3 304 | 327N/C U3 A02X+035906Y-043701X0236Y0079R180S3 305 | 327N/C U3 A02X+034882Y-044055X0079Y0472R180S3 306 | 327N/C U3 A02X+034409Y-042835X0079Y0236R180S3 307 | 327N/C U3 A02X+035354Y-044173X0079Y0079R180S3 308 | 327N/C U3 A02X+035197Y-043740X0079Y0472R180S3 309 | 327N/C U3 A02X+035276Y-043622X0079Y0079R180S3 310 | 327N/C U3 A02X+035276Y-042835X0079Y0079R180S3 311 | 327N/C U3 A02X+034882Y-043504X0079Y0315R180S3 312 | 327N/C U3 A02X+035000Y-043307X0157Y0079R180S3 313 | 327N/C U3 A02X+034961Y-043465X0079Y0079R180S3 314 | 327N/C U3 A02X+035118Y-042835X0079Y0236R180S3 315 | 327N/C U3 A02X+035197Y-044331X0079Y0079R180S3 316 | 327N/C U3 A02X+035748Y-042756X0394Y0079R180S3 317 | 327N/C U3 A02X+034409Y-044055X0079Y0472R180S3 318 | 327N/C U3 A02X+035512Y-043386X0079Y0079R180S3 319 | 327N/C U3 A02X+035354Y-043465X0079Y0079R180S3 320 | 327N/C U3 A02X+035079Y-044094X0157Y0079R180S3 321 | 327N/C U3 A02X+035039Y-043898X0079Y0157R180S3 322 | 327N/C U3 A02X+035748Y-042992X0236Y0236R180S3 323 | 327N/C U3 A02X+034646Y-044094X0236Y0236R180S3 324 | 327N/C U3 A02X+035197Y-042992X0079Y0236R180S3 325 | 327N/C U3 A02X+034961Y-043071X0079Y0236R180S3 326 | 327N/C U3 A02X+035276Y-043307X0236Y0079R180S3 327 | 327N/C U3 A02X+034567Y-043661X0079Y0157R180S3 328 | 327N/C U3 A02X+035827Y-043425X0079Y0157R180S3 329 | 327N/C U3 A02X+034646Y-043858X0394Y0079R180S3 330 | 327N/C U3 A02X+034724Y-043543X0079Y0079R180S3 331 | 327N/C U3 A02X+035197Y-043386X0236Y0079R180S3 332 | 327N/C U3 A02X+035748Y-043858X0394Y0079R180S3 333 | 327N/C U3 A02X+035748Y-044094X0236Y0236R180S3 334 | 327N/C U3 A02X+034488Y-042992X0079Y0079R180S3 335 | 327N/C U3 A02X+034724Y-043268X0079Y0157R180S3 336 | 327N/C U3 A02X+035276Y-044252X0079Y0079R180S3 337 | 327N/C U3 A02X+035354Y-043150X0079Y0236R180S3 338 | 327N/C U3 A02X+035512Y-044055X0079Y0472R180S3 339 | 327N/C U3 A02X+035669Y-043425X0079Y0157R180S3 340 | 327N/C U3 A02X+035984Y-044055X0079Y0472R180S3 341 | 327N/C U3 A02X+034803Y-042756X0079Y0079R180S3 342 | 327N/C U3 A02X+034803Y-042913X0079Y0079R180S3 343 | 327N/C U3 A02X+035276Y-044016X0079Y0236R180S3 344 | 327N/C U3 A02X+035276Y-043150X0079Y0079R180S3 345 | 327N/C U3 A02X+035039Y-044291X0079Y0157R180S3 346 | 327N/C U3 A02X+035354Y-043780X0079Y0236R180S3 347 | 327N/C U3 A02X+035512Y-042953X0079Y0472R180S3 348 | 327N/C U3 A02X+035118Y-043622X0079Y0079R180S3 349 | 327N/C U3 A02X+034724Y-043071X0079Y0079R180S3 350 | 327N/C U3 A02X+035748Y-044331X0551Y0079R180S3 351 | 327N/C U3 A02X+035157Y-044173X0157Y0079R180S3 352 | 327N/C U3 A02X+035039Y-042795X0079Y0157R180S3 353 | 327N/C U3 A02X+034961Y-043701X0236Y0079R180S3 354 | 327N/C U3 A02X+034567Y-043071X0079Y0079R180S3 355 | 327N/C U3 A02X+035118Y-043150X0079Y0079R180S3 356 | 327N/C U3 A02X+034646Y-044331X0551Y0079R180S3 357 | 327N/C U3 A02X+034449Y-043622X0157Y0079R180S3 358 | 327N/C U3 A02X+034646Y-042795X0079Y0157R180S3 359 | 999 360 | -------------------------------------------------------------------------------- /PCB/Square/production/positions.csv: -------------------------------------------------------------------------------- 1 | Designator,Mid X,Mid Y,Rotation,Layer 2 | AJK1,89.7,-92.2,0.0,top 3 | C1,101.7,-86.7,180.0,top 4 | C10,101.375,-93.85,0.0,top 5 | C11,104.65,-99.6,270.0,top 6 | C12,98.625,-93.85,180.0,top 7 | C13,106.15,-99.6,270.0,top 8 | C14,105.4,-97.3,0.0,top 9 | C15,93.875,-96.1,0.0,top 10 | C16,93.875,-97.5,0.0,top 11 | C17,93.875,-102.5,180.0,top 12 | C18,97.7,-105.15,90.0,top 13 | C19,109.0,-108.2,0.0,top 14 | C2,98.3,-86.7,180.0,top 15 | C3,103.8,-87.525,90.0,top 16 | C4,96.2,-87.525,270.0,top 17 | C5,101.7,-88.275,0.0,top 18 | C6,98.3,-88.275,180.0,top 19 | C7,101.375,-95.2,0.0,top 20 | C8,93.1,-90.2,90.0,top 21 | C9,93.875,-94.75,0.0,top 22 | D1,112.0,-100.0,90.0,top 23 | D2,112.0,-94.0,90.0,top 24 | D3,112.0,-88.0,90.0,top 25 | D4,109.0,-103.7,0.0,top 26 | D5,109.0,-93.9,0.0,top 27 | D6,109.0,-106.3,180.0,top 28 | J1,112.0,-107.27,180.0,top 29 | J2,100.0,-108.9,0.0,top 30 | L1,103.25,-91.0,45.0,top 31 | L2,96.75,-91.0,315.0,top 32 | R1,98.0,-84.0,90.0,top 33 | R10,109.0,-98.8,0.0,top 34 | R11,99.3,-105.15,90.0,top 35 | R12,104.0,-105.15,270.0,top 36 | R13,101.65,-105.9,0.0,top 37 | R14,101.65,-104.4,180.0,top 38 | R15,105.6,-105.15,90.0,top 39 | R2,100.0,-82.0,90.0,top 40 | R3,102.0,-84.0,90.0,top 41 | R4,93.9,-88.275,0.0,top 42 | R5,93.1,-92.85,270.0,top 43 | R6,109.0,-95.8,0.0,top 44 | R7,109.0,-97.3,0.0,top 45 | R8,109.0,-101.8,0.0,top 46 | R9,109.0,-100.3,0.0,top 47 | SW1,89.4,-103.6,90.0,top 48 | TP1,100.0,-92.4,180.0,top 49 | U1,100.0,-100.0,270.0,top 50 | U3,89.4,-110.6,180.0,bottom 51 | Y1,93.875,-100.0,90.0,top 52 | -------------------------------------------------------------------------------- /PN532.pages: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PN532.pages -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESP32-PN532 2 | 3 | PN532 (HSU) library 4 | - Platform: ESP-IDF (e.g. ESP32) 5 | - Can work with DESFireAES library for NXP MIFARE DESFire EV1 cards 6 | - See include file for details of functions 7 | 8 | Includes KiCad PCB design for PN532 based NFC reader board and 3D case designs. Unlike some NFC boards this includes three traffic light LEDs, a tamper switch, and external contacts for a door bell push, all accessable as GPIO over the HSU connection. 9 | 10 | ![293554](https://user-images.githubusercontent.com/996983/218126563-452273b7-6dc6-40e4-8c08-a95a43e02ddb.jpg) 11 | 12 | Copyright © 2019-23 Adrian Kennard, Andrews & Arnold Ltd. See LICENCE file for details. GPL 3.0 13 | -------------------------------------------------------------------------------- /component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # "main" pseudo-component makefile. 3 | # 4 | # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) 5 | 6 | -------------------------------------------------------------------------------- /idf_component.yml: -------------------------------------------------------------------------------- 1 | ## IDF Component Manager Manifest File 2 | dependencies: 3 | espressif/led_strip: "*" 4 | ## Required IDF version 5 | idf: 6 | version: ">=4.1.0" 7 | # # Put list of dependencies here 8 | # # For components maintained by Espressif: 9 | # component: "~1.0.0" 10 | # # For 3rd party components: 11 | # username/component: ">=1.0.0,<2.0.0" 12 | # username2/component2: 13 | # version: "~1.0.0" 14 | # # For transient dependencies `public` flag can be set. 15 | # # `public` flag doesn't have an effect dependencies of the `main` component. 16 | # # All dependencies of `main` are public by default. 17 | # public: true 18 | -------------------------------------------------------------------------------- /include/pn532.h: -------------------------------------------------------------------------------- 1 | // PN532 functions 2 | // Copyright © 2019 Adrian Kennard, Andrews & Arnold Ltd. See LICENCE file for details. GPL 3.0 3 | 4 | #ifndef PN532_H 5 | #define PN532_H 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define pn532_errs \ 15 | p(OK) \ 16 | p(NULL) \ 17 | p(NOTPENDING) \ 18 | p(CMDPENDING) \ 19 | p(CMDMISMATCH) \ 20 | p(TIMEOUT) \ 21 | p(TIMEOUTACK) \ 22 | p(BADACK) \ 23 | p(NACK) \ 24 | p(HEADER) \ 25 | p(SHORT) \ 26 | p(SPACE) \ 27 | p(CHECKSUM) \ 28 | p(POSTAMBLE) \ 29 | p(STATUS) \ 30 | s(0x01,TIMEOUT) \ 31 | s(0x02,CRC) \ 32 | s(0x03,PARITY) \ 33 | s(0x04,BITCOUNT) \ 34 | s(0x05,FRAMING) \ 35 | s(0x06,COLLISION) \ 36 | s(0x07,SPACE) \ 37 | s(0x09,OVERFLOW) \ 38 | s(0x0A,NOFIELD) \ 39 | s(0x0B,PROTOCOL) \ 40 | s(0x0D,TEMPERATURE) \ 41 | s(0x0E,INTOVERFLOW) \ 42 | s(0x10,PARAMETER) \ 43 | s(0x12,DEPPROTOCOL) \ 44 | s(0x13,DEPFORMAT) \ 45 | s(0x14,MIFAREAUTH) \ 46 | s(0x23,UIDCHECK) \ 47 | s(0x25,DEPSTATE) \ 48 | s(0x26,NOTALLOWED) \ 49 | s(0x27,NOTACCEPTABLE) \ 50 | s(0x29,RELEASED) \ 51 | s(0x2A,CARDSWAPPED) \ 52 | s(0x2B,DISAPPEARED) \ 53 | s(0x2C,MISMATCHID) \ 54 | s(0x2D,OVERCURRENT) \ 55 | s(0x2E,NADMISSING) \ 56 | s(0x2F,MAX) \ 57 | 58 | typedef enum { 59 | #define p(n) PN532_ERR_##n, 60 | #define s(v,n) PN532_ERR_STATUS_##n=PN532_ERR_STATUS+v, 61 | pn532_errs 62 | #undef p 63 | #undef s 64 | } pn532_err_t; 65 | 66 | typedef struct pn532_s pn532_t; 67 | 68 | // Functions 69 | 70 | pn532_t *pn532_init(int8_t uart, uint8_t baud, int8_t tx, int8_t rx, uint8_t p3); // Init PN532 (P3 is port 3 output bits in use), baud is speed code 0-8 for 9600-1288000 71 | void *pn532_end(pn532_t * p); // Close and free 72 | 73 | pn532_err_t pn532_lasterr(pn532_t *); 74 | const char *pn532_err_to_name(pn532_err_t); 75 | 76 | // Low level access functions 77 | int pn532_tx(pn532_t *, uint8_t cmd, int, uint8_t *, int, uint8_t *); // Send data to PN532 (up to two blocks) return 0 or negative for error. Starts byte after cmd 78 | int pn532_ready(pn532_t * p); // For async command handling: >0 if response ready, 0 if not, -ve if error (e.g. no response expected) 79 | int pn532_rx(pn532_t *, int, uint8_t *, int, uint8_t *, int ms); // Recv data from PN532, (in to up to two blocks) return total length or -ve for error, checks res=cmd+1 and returns from byte after 80 | uint8_t *pn532_nfcid(pn532_t *, char text[21]); // Get NFCID (first byte is len of following) 81 | uint8_t *pn532_ats(pn532_t *); // Get ATS (first byte is len of following - note, not as received were it is len inc the length byte) 82 | 83 | // Card access function - sends to card starting CMD byte, and receives reply in to same buffer, starting status byte, returns len 84 | int pn532_dx(void *, unsigned int len, uint8_t * data, unsigned int max, const char **errstr); 85 | 86 | // Higher level useful PN532 functions 87 | int pn532_deselect(pn532_t * p, uint8_t n); // Send deselect ID 1 or 2 88 | int pn532_release(pn532_t * p, uint8_t n); // Send release ID 1 or 2 89 | int pn532_write_GPIO(pn532_t * p, uint8_t value); // (P72/P71 in top bits, P35-30 in rest) 90 | int pn532_read_GPIO(pn532_t * p); // P72/P71 in top bits, P35-30 in rest) 91 | int pn532_ILPT_Send(pn532_t * p); // Async InListPassiveTarget - used pn532_ready to check when to do pn532_Cards 92 | int pn532_Cards(pn532_t * p); // How many cards present (does pn532_ILPT_Send if needed) 93 | int pn532_Present(pn532_t * p); // Check if present still 94 | 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /makeloop.c: -------------------------------------------------------------------------------- 1 | /* General spiral track - for PN532 antenna */ 2 | /* (c) 2021 Adrian Kennard Andrews & Arnold Ltd */ 3 | 4 | #define _GNU_SOURCE 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | int 20 | main (int argc, const char *argv[]) 21 | { 22 | const char *name = "PN532-Antenna6"; 23 | const char *text = NULL; 24 | double startr = 22.69; 25 | double width = 0.5; 26 | double step = 1.0; 27 | double starta = NAN; 28 | double enda = NAN; 29 | double stepa = 30; 30 | double edge = NAN; 31 | double ring = NAN; 32 | double texth = 3; 33 | double textr = 18.5; 34 | double textt = 0.4; 35 | double screwx = NAN; 36 | double screwy = 0; 37 | double screwz = 1.25; 38 | double zone = 8; // Fill exclude zone starts away from antenna 39 | double zap = 5; // Fill exclusion zone has slots this deep 40 | double spoke = 12; // Exclude spoke angle 41 | double slot = 1; // Exclude slot angle 42 | int outside = 0; 43 | int debug = 0; 44 | poptContext optCon; /* context for parsing command - line options */ 45 | { 46 | const struct poptOption optionsTable[] = { 47 | {"name", 0, POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &name, 0, "Name"}, 48 | {"text", 0, POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &text, 0, "Text"}, 49 | {"texth", 0, POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &texth, 0, "Text height"}, 50 | {"startr", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &startr, 0, "Start (outer) radius"}, 51 | {"textr", 0, POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &textr, 0, "Text radius"}, 52 | {"textt", 0, POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &textt, 0, "Text thickness"}, 53 | {"width", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &width, 0, "Track width"}, 54 | {"step", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &step, 0, "Step per turn"}, 55 | {"starta", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &starta, 0, "Start angle"}, 56 | {"enda", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &enda, 0, "End angle"}, 57 | {"stepa", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &stepa, 0, "Step angle"}, 58 | {"screwx", 0, POPT_ARG_DOUBLE, &screwx, 0, "Screw X"}, 59 | {"screwy", 0, POPT_ARG_DOUBLE, &screwy, 0, "Screw Y"}, 60 | {"screwz", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &screwz, 0, "Screw Z"}, 61 | {"edge", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &edge, 0, "Edge"}, 62 | {"ring", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &ring, 0, "Ring"}, 63 | {"zone", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &zone, 0, "Keepout clearance"}, 64 | {"zap", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &zap, 0, "Keepout slot length"}, 65 | {"spoke", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &spoke, 0, "Keepout slot spacing"}, 66 | {"slot", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &slot, 0, "Keepout slot width"}, 67 | {"outside", 0, POPT_ARG_NONE, &outside, 0, "Outside contact"}, 68 | {"debug", 'v', POPT_ARG_NONE, &debug, 0, "Debug"}, 69 | POPT_AUTOHELP {} 70 | }; 71 | 72 | optCon = poptGetContext (NULL, argc, argv, optionsTable, 0); 73 | /* poptSetOtherOptionHelp(optCon, ""); */ 74 | 75 | int c; 76 | if ((c = poptGetNextOpt (optCon)) < -1) 77 | errx (1, "%s: %s\n", poptBadOption (optCon, POPT_BADOPTION_NOALIAS), poptStrerror (c)); 78 | 79 | } 80 | if (!outside && isnan (screwx)) 81 | screwx = startr * 12 / 23; 82 | if (isnan (starta)) 83 | starta = outside ? 7 : 2.4; 84 | if (isnan (enda)) 85 | enda = outside ? 722.7 : 713; 86 | if (!outside && !text) 87 | text = "PN532 HSU NFC READER PN532.REVK.UK"; 88 | if (!outside && isnan (ring)) 89 | ring = 16; 90 | 91 | #define LF "%.2lf" 92 | #define RES 100 93 | double basex = 0, 94 | basey = 0; 95 | 96 | inline double xr (double a, double r) 97 | { 98 | return round ((r * sin (a * M_PI / 180.0) - basex) * RES) / RES; 99 | } 100 | inline double x (double a) 101 | { 102 | double r = startr - step * a / 360; 103 | if (a < 0) 104 | r = startr; 105 | return xr (a, r); 106 | } 107 | inline double yr (double a, double r) 108 | { 109 | return round ((-r * cos (a * M_PI / 180.0) + step / 4 - basey) * RES) / RES; 110 | } 111 | inline double y (double a) 112 | { 113 | double r = startr - step * a / 360; 114 | if (a < 0) 115 | r = startr; 116 | return yr (a, r); 117 | } 118 | 119 | printf ("(footprint \"%s\" (layer \"F.Cu\") (version 20211014) ", name); 120 | printf ("(attr through_hole exclude_from_pos_files exclude_from_bom)"); 121 | printf ("(fp_text reference \"Ref**\" (at 0 0) (layer \"F.SilkS\") hide (effects (font (size 1.27 1.27) (thickness 0.15))))"); 122 | printf ("(fp_text value \"Val**\" (at 0 0) (layer \"F.SilkS\") hide (effects (font (size 1.27 1.27) (thickness 0.15))))"); 123 | if (!isnan (edge) && edge) 124 | printf ("(fp_circle (center 0 0) (end " LF " 0) (layer \"Edge.Cuts\") (width 0.1) (fill none))", edge); 125 | if (!isnan (ring) && ring) 126 | printf ("(fp_circle (center 0 0) (end " LF " 0) (layer \"Dwgs.User\") (width 0.2) (fill none))", ring); 127 | if (text && *text) 128 | { 129 | const char thin[] = ".:'"; 130 | double s = texth / (textr - texth / 2) * 0.9, 131 | a = 0; 132 | for (const char *p = text; *p; p++) 133 | a += (strchr (thin, *p) ? s / 2 : s); 134 | a = M_PI - a / 2 + s / 2; 135 | for (const char *p = text; *p; p++) 136 | { 137 | if (strchr (thin, *p)) 138 | a -= s / 4; 139 | if (*p != ' ') 140 | printf ("(fp_text user \"%c\" (at " LF " " LF " " LF " unlocked) (layer \"F.SilkS\")(effects (font (size " LF " " LF 141 | ") (thickness " LF "))))", *p, textr * sin (a), -textr * cos (a), -180 * a / M_PI, texth, texth, textt); 142 | if (strchr (thin, *p)) 143 | a -= s / 4; 144 | a += s; 145 | } 146 | } 147 | { /* Components */ 148 | /* top link */ 149 | int d = outside ? -1 : 1; 150 | double dy = y (roundl (enda / 360) * 360) - y (roundl (starta / 360) * 360); 151 | if (dy > 1.5 && dy < 2.5) 152 | { /* 0805 2mm high */ 153 | double a = outside ? enda : starta; 154 | double Y = y (a); 155 | double W = x (a) * 2; 156 | // Holes 157 | printf ("(pad \"0\" thru_hole circle (at " LF " " LF ") (size " LF " " LF ") (drill " LF ") (layers *.Cu))", W / 2, Y, 158 | width, width, width / 2); 159 | printf ("(pad \"0\" thru_hole circle (at " LF " " LF ") (size " LF " " LF ") (drill " LF ") (layers *.Cu))", -W / 2, Y, 160 | width, width, width / 2); 161 | // Join holes 162 | printf ("(pad \"0\" smd rect (at 0 " LF " 0) (size " LF " " LF ") (layers \"F.Cu\" \"B.Cu\"))", Y, W, width); 163 | // Centre tap pad 164 | printf ("(pad \"0\" smd rect (at 0 " LF " 0) (size 1.4 " LF ") (layers \"F.Paste\" \"F.Mask\"))", Y, width); 165 | // Centre dot 166 | Y += d; 167 | printf ("(fp_circle (center 0 " LF ") (end 0.05 " LF ") (layer \"Dwgs.User\") (width 0.12) (fill none))", Y, Y); 168 | // Contact pad 169 | Y += d; 170 | printf ("(pad \"2\" smd rect (at 0 " LF " 0) (size 1.4 " LF ") (layers \"F.Cu\" \"F.Paste\" \"F.Mask\"))", Y, width); 171 | } 172 | /* 0603 1.6 mm high */ 173 | double a = outside ? starta : enda; 174 | // Hole 175 | printf ("(pad \"0\" thru_hole circle (at " LF " " LF ") (size " LF " " LF ") (drill " LF ") (layers *.Cu))", x (a), y (a), 176 | width, width, width / 2); 177 | for (int m = -1; m <= 1; m += 2) 178 | { 179 | double X = x (a) + width / 4; 180 | double Y = y (a); 181 | if (outside) 182 | X -= 1 + width; 183 | // Copper 184 | printf ("(pad \"0\" smd rect (at " LF " " LF " 0) (size " LF " " LF ") (layers \"F.Cu\"))", 185 | m * (X + 0.5 + (outside ? width / 2 : 0)), Y, 1 + width / 2, width); 186 | // Mask 187 | X += width / 4; 188 | printf ("(pad \"0\" smd rect (at " LF " " LF " 0) (size 1 " LF ") (layers \"F.Paste\" \"F.Mask\"))", m * (X + 0.5), Y, 189 | width); 190 | // Dot 191 | Y += d * 0.8; 192 | printf ("(fp_circle (center " LF " " LF ") (end " LF " " LF ") (layer \"Dwgs.User\") (width 0.12) (fill none))", 193 | m * (X + 0.5), Y, m * (X + 0.5 + 0.05), Y); 194 | Y += d * 0.8; 195 | printf ("(pad \"%d\" smd rect (at " LF " " LF " 0) (size 1 " LF ") (layers \"F.Cu\" \"F.Paste\" \"F.Mask\"))", m + 2, 196 | m * (X + 0.5), Y, width); 197 | } 198 | if (!isnan (screwx)) 199 | { 200 | printf ("(model \"/Users/adrian/Documents/KiCad/3D/653612.stp\" (offset (xyz " LF " " LF " " LF 201 | ")) (scale (xyz 0.58 0.58 0.58)) (rotate (xyz 0 -90 -35)))", screwx, screwy, screwz); 202 | printf ("(model \"/Users/adrian/Documents/KiCad/3D/653612.stp\" (offset (xyz " LF " " LF " " LF 203 | ")) (scale (xyz 0.58 0.58 0.58)) (rotate (xyz 0 -90 -35)))", -screwx, -screwy, screwz); 204 | } 205 | } 206 | void pad (const char *layer, double flip) 207 | { 208 | basex = basey = 0; 209 | printf ("(pad \"0\" smd custom (at " LF " " LF ") (size " LF " " LF 210 | ") (layers \"%s\") (options (clearance outline) (anchor circle)) (primitives ", flip * x (starta), y (starta), width, 211 | width, layer); 212 | basex = x (starta); 213 | basey = y (starta); 214 | void arc (double s, double e) 215 | { 216 | double m = (s + e) / 2; 217 | printf ("(gr_arc (start " LF " " LF ") (mid " LF " " LF ") (end " LF " " LF ") (width " LF "))", flip * x (s), y (s), 218 | flip * x (m), y (m), flip * x (e), y (e), width); 219 | } 220 | double a = 0; 221 | if (starta < 0) 222 | arc (starta, 0); 223 | else if (starta > 0 && starta < stepa) 224 | arc (starta, a = stepa); 225 | for (; a + stepa < enda; a += stepa) 226 | arc (a, a + stepa); 227 | if (a < enda) 228 | arc (a, enda); 229 | printf ("))"); 230 | basex = basey = 0; 231 | } 232 | /* the antenna itself */ 233 | pad ("F.Cu", -1); 234 | pad ("B.Cu", 1); 235 | if (zone) 236 | { 237 | printf 238 | ("(zone(net 0)(net_name \"0\")(layers \"F&B.Cu\")(hatch edge 0.5)(connect_pads(clearance 0))(min_thickness 0.25)(filled_areas_thickness no)(keepout(tracks allowed)(vias allowed)(pads allowed)(copperpour not_allowed)(footprints allowed))(fill(thermal_gap 0.5)(thermal_bridge_width 0.5))(polygon(pts"); 239 | double delta = spoke / 2; 240 | void zy (double a, double r) 241 | { 242 | printf ("(xy " LF " " LF ")", xr (a + delta, r), yr (a + delta, r)); 243 | } 244 | zy (0, startr + step * 2 + zone); 245 | for (double a = -slot / 2; a < 360; a += spoke) 246 | { 247 | zy (a, startr + step * 2 + zone); 248 | zy (a, startr + step * 2 + zone + zap); 249 | zy (a + slot, startr + step * 2 + zone + zap); 250 | zy (a + slot, startr + step * 2 + zone); 251 | } 252 | zy (0, startr + step * 2 + zone); 253 | zy (0, startr - zone); 254 | for (double a = -slot / 2; a < 360; a += spoke) 255 | { 256 | zy (-a, startr - zone); 257 | zy (-a, startr - zone - zap); 258 | zy (-a - slot, startr - zone - zap); 259 | zy (-a - slot, startr - zone); 260 | } 261 | zy (0, startr - zone); 262 | printf (")))"); 263 | } 264 | printf (")"); 265 | poptFreeContext (optCon); 266 | return 0; 267 | } 268 | -------------------------------------------------------------------------------- /pn532.c: -------------------------------------------------------------------------------- 1 | // PN532 functions 2 | // Copyright © 2019 Adrian Kennard, Andrews & Arnold Ltd. See LICENCE file for details. GPL 3.0 3 | static const char TAG[] = "PN532"; 4 | 5 | #include "sdkconfig.h" 6 | #include "pn532.h" 7 | #include "esp_log.h" 8 | #include 9 | #include 10 | 11 | #define HEXLOG ESP_LOG_INFO 12 | #define DXLOG ESP_LOG_INFO 13 | #define MSGLOG ESP_LOG_ERROR 14 | #define RX_BUF 280 15 | #define TX_BUF 280 16 | 17 | struct pn532_s 18 | { 19 | uint8_t uart; // Which UART 20 | volatile uint8_t pending; // Pending response 21 | uint8_t lasterr; // Last error (obviously not for PN532_ERR_NULL) 22 | uint8_t cards; // Cards present (0, 1 or 2) 23 | uint8_t tg; // First card target id (normally 1) 24 | uint16_t sens_res; // From InListPassiveTarget 25 | uint8_t sel_res; // From InListPassiveTarget 26 | uint8_t nfcid[11]; // First card ID last seen (starts with len) 27 | uint8_t ats[30]; // First card ATS last seen (starts with len) 28 | SemaphoreHandle_t mutex; // DX mutex 29 | }; 30 | 31 | // Data 32 | static const char *const pn532_err_str[PN532_ERR_STATUS_MAX + 1] = { 33 | #define p(n) [PN532_ERR_##n]="PN532_ERR_"#n, 34 | #define s(v,n) [PN532_ERR_STATUS_##n]="PN532_ERR_STATUS_"#n, 35 | pn532_errs 36 | #undef p 37 | #undef s 38 | }; 39 | 40 | pn532_err_t 41 | pn532_lasterr (pn532_t * p) 42 | { 43 | if (!p) 44 | return -PN532_ERR_NULL; 45 | #if 0 46 | if (p->lasterr > PN532_ERR_STATUS) 47 | ESP_LOGI (TAG, "Last err status %02X", p->lasterr - PN532_ERR_STATUS); 48 | else 49 | ESP_LOGI (TAG, "Last err %d", p->lasterr); 50 | #endif 51 | return p->lasterr; 52 | } 53 | 54 | const char * 55 | pn532_err_to_name (pn532_err_t e) 56 | { 57 | if (e < 0) 58 | e = -e; 59 | if (e > PN532_ERR_STATUS_MAX) 60 | return "PN532_ERR_UNKNOWN"; 61 | return pn532_err_str[e]; 62 | } 63 | 64 | static int 65 | uart_rx (pn532_t * p, uint8_t * buf, uint32_t length, int ms) 66 | { // Low level UART rx with optional logging 67 | if (!p) 68 | return -PN532_ERR_NULL; 69 | ms /= portTICK_PERIOD_MS; 70 | if (ms < 2) 71 | ms = 2; // Ensure some timeout 72 | int l = uart_read_bytes (p->uart, buf, length, ms); 73 | #ifdef CONFIG_PN532_DUMP 74 | if (l > 0) 75 | ESP_LOG_BUFFER_HEX_LEVEL ("NFCRx", buf, l, HEXLOG); 76 | if (l != length) 77 | ESP_LOGI (TAG, "Rx %d/%ld %d*%ldms", l, length, ms, portTICK_PERIOD_MS); 78 | #endif 79 | return l; 80 | } 81 | 82 | static int 83 | uart_tx (pn532_t * p, const uint8_t * src, size_t size) 84 | { // Low level UART tx with optional logging 85 | if (!p) 86 | return -PN532_ERR_NULL; 87 | int l = uart_write_bytes (p->uart, (char *) src, size); 88 | #ifdef CONFIG_PN532_DUMP 89 | if (l > 0) 90 | ESP_LOG_BUFFER_HEX_LEVEL ("NFCTx", src, l, HEXLOG); 91 | if (l != size) 92 | ESP_LOGI (TAG, "Tx %d/%d", l, size); 93 | #endif 94 | return l; 95 | } 96 | 97 | static int 98 | uart_preamble (pn532_t * p, int ms) 99 | { // Wait for preamble 100 | if (!p) 101 | return -PN532_ERR_NULL; 102 | uint8_t last = 0xFF; 103 | while (1) 104 | { 105 | uint8_t c; 106 | int l = uart_rx (p, &c, 1, ms); 107 | if (l < 1) 108 | return l; 109 | if (last == 0x00 && c == 0xFF) 110 | return 2; 111 | last = c; 112 | } 113 | } 114 | 115 | void * 116 | pn532_end (pn532_t * p) 117 | { 118 | if (p) 119 | { 120 | vSemaphoreDelete (p->mutex); 121 | free (p); 122 | } 123 | return NULL; 124 | } 125 | 126 | pn532_t * 127 | pn532_init (int8_t uart, uint8_t baud, int8_t tx, int8_t rx, uint8_t outputs) 128 | { // Init PN532 (baud is 0-8 for 9600-1288000 129 | if (uart < 0 || tx < 0 || rx < 0 || tx == rx) 130 | return NULL; 131 | if (!GPIO_IS_VALID_OUTPUT_GPIO (tx) || !GPIO_IS_VALID_GPIO (rx)) 132 | return NULL; 133 | pn532_t *p = malloc (sizeof (*p)); 134 | if (!p) 135 | return p; 136 | memset (p, 0, sizeof (*p)); 137 | p->uart = uart; 138 | p->mutex = xSemaphoreCreateBinary (); 139 | xSemaphoreGive (p->mutex); 140 | esp_err_t err = 0; 141 | { // Init UART 142 | uart_config_t uart_config = { 143 | .baud_rate = 115200, 144 | .data_bits = UART_DATA_8_BITS, 145 | .parity = UART_PARITY_DISABLE, 146 | .stop_bits = UART_STOP_BITS_1, 147 | .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, 148 | .source_clk = UART_SCLK_DEFAULT, 149 | }; 150 | if (!err) 151 | err = uart_param_config (uart, &uart_config); 152 | if (!err) 153 | err = gpio_reset_pin (tx); 154 | if (!err && tx != rx) 155 | err = gpio_reset_pin (rx); 156 | if (!err) 157 | err = uart_set_pin (uart, tx, rx, -1, -1); 158 | if (!err && !uart_is_driver_installed (uart)) 159 | { 160 | ESP_LOGI (TAG, "Installing UART driver %d", uart); 161 | err = uart_driver_install (uart, RX_BUF, TX_BUF, 0, NULL, 0); 162 | } 163 | if (err) 164 | { 165 | ESP_LOGE (TAG, "UART fail %s", esp_err_to_name (err)); 166 | return pn532_end (p); 167 | } 168 | } 169 | ESP_LOGD (TAG, "UART %d Tx %d Rx %d", uart, tx, rx); 170 | gpio_set_drive_capability (tx, GPIO_DRIVE_CAP_3); // Oomph? 171 | int n; 172 | uint8_t buf[30] = { 0 }; 173 | int e = sizeof (buf); 174 | buf[--e] = 0x55; // Idle 175 | buf[--e] = 0x55; 176 | buf[--e] = 0x55; 177 | uart_flush_input (p->uart); 178 | uart_tx (p, buf, sizeof (buf)); 179 | uart_wait_tx_done (p->uart, 100 / portTICK_PERIOD_MS); 180 | if (baud != 4 && baud <= 8) 181 | { // Not the default Baud rate, go through the change of Baud rate step by step 182 | if (pn532_tx (p, 0x10, 1, &baud, 0, NULL) < 0 || pn532_rx (p, 0, NULL, sizeof (buf), buf, 20) < 0) 183 | { 184 | ESP_LOGE (TAG, "Baud rate change failed %s", pn532_err_to_name (pn532_lasterr (p))); 185 | return pn532_end (p); 186 | } 187 | // We have to send ACK at current Baud rate 188 | uint8_t ack[] = { 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00 }; 189 | uart_tx (p, ack, sizeof (ack)); 190 | uart_wait_tx_done (p->uart, 100 / portTICK_PERIOD_MS); 191 | usleep (10000); 192 | // Change rate 193 | const uint32_t rate[] = { 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600, 1288000 }; 194 | uart_config_t uart_config = { 195 | .baud_rate = rate[baud], 196 | .data_bits = UART_DATA_8_BITS, 197 | .parity = UART_PARITY_DISABLE, 198 | .stop_bits = UART_STOP_BITS_1, 199 | .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, 200 | .source_clk = UART_SCLK_DEFAULT, 201 | }; 202 | if (!err) 203 | err = uart_param_config (uart, &uart_config); 204 | if (err) 205 | { 206 | ESP_LOGE (TAG, "UART fail %s", esp_err_to_name (err)); 207 | return pn532_end (p); 208 | } 209 | ESP_LOGE (TAG, "Baud rate %ld", rate[baud]); 210 | usleep (10000); 211 | } 212 | // Set up PN532 (SAM first as in vLowBat mode) 213 | // SAMConfiguration 214 | n = 0; 215 | buf[n++] = 0x01; // Normal 216 | buf[n++] = 20; // *50ms timeout 217 | buf[n++] = 0x00; // Not use IRQ 218 | if (pn532_tx (p, 0x14, 0, NULL, n, buf) < 0 || pn532_rx (p, 0, NULL, sizeof (buf), buf, 50) < 0) 219 | { // Again 220 | uart_rx (p, buf, sizeof (buf), 100); // Wait long enough for command response timeout before we try again 221 | // SAMConfiguration 222 | n = 0; 223 | buf[n++] = 0x01; // Normal 224 | buf[n++] = 20; // *50ms timeout 225 | buf[n++] = 0x00; // Not use IRQ 226 | if (pn532_tx (p, 0x14, 0, NULL, n, buf) < 0 || pn532_rx (p, 0, NULL, sizeof (buf), buf, 50) < 0) 227 | { 228 | ESP_LOGE (TAG, "SAMConfiguration fail %s", pn532_err_to_name (pn532_lasterr (p))); 229 | return pn532_end (p); 230 | } 231 | } 232 | // GetFirmwareVersion 233 | if (pn532_tx (p, 0x02, 0, NULL, 0, NULL) < 0 || pn532_rx (p, 0, NULL, sizeof (buf), buf, 50) < 0) 234 | { 235 | ESP_LOGE (TAG, "GetFirmwareVersion fail %s", pn532_err_to_name (pn532_lasterr (p))); 236 | return pn532_end (p); 237 | } 238 | //uint32_t ver = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3]; 239 | // RFConfiguration (retries) 240 | n = 0; 241 | buf[n++] = 5; // Config item 5 (MaxRetries) 242 | buf[n++] = 0xFF; // MxRtyATR (default = 0xFF) 243 | buf[n++] = 0x01; // MxRtyPSL (default = 0x01) 244 | buf[n++] = 0x01; // MxRtyPassiveActivation 245 | if (pn532_tx (p, 0x32, 0, NULL, n, buf) < 0 || pn532_rx (p, 0, NULL, sizeof (buf), buf, 50) < 0) 246 | { 247 | ESP_LOGE (TAG, "RFConfiguration fail %s", pn532_err_to_name (pn532_lasterr (p))); 248 | return pn532_end (p); 249 | } 250 | // WriteRegister 251 | n = 0; 252 | // AB are 00=open drain, 10=quasi bidi, 01=input (high imp), 11=output (push/pull) 253 | buf[n++] = 0xFF; // P3CFGA 254 | buf[n++] = 0xFC; // P3CFGA 255 | buf[n++] = (outputs & 0x3F); // Define output bits 256 | buf[n++] = 0xFF; // P3CFGB 257 | buf[n++] = 0xFD; // P3CFGB 258 | buf[n++] = 0xFF; // 0xFF 259 | buf[n++] = 0xFF; // P3 260 | buf[n++] = 0xB0; // P3 261 | buf[n++] = 0xFF; // All high 262 | buf[n++] = 0xFF; // P7CFGA 263 | buf[n++] = 0xF4; // P7CFGA 264 | buf[n++] = ((outputs >> 5) & 0x06); // Define output bits 265 | buf[n++] = 0xFF; // P7CFGB 266 | buf[n++] = 0xF5; // P7CFGB 267 | buf[n++] = 0xFF; // 0xFF 268 | buf[n++] = 0xFF; // P7 269 | buf[n++] = 0xF7; // P7 270 | buf[n++] = 0xFF; // All high 271 | if (n && (pn532_tx (p, 0x08, 0, NULL, n, buf) < 0 || pn532_rx (p, 0, NULL, sizeof (buf), buf, 50) < 0)) 272 | { 273 | ESP_LOGE (TAG, "WriteRegister fail %s", pn532_err_to_name (pn532_lasterr (p))); 274 | return pn532_end (p); 275 | } 276 | // RFConfiguration 277 | n = 0; 278 | buf[n++] = 0x04; // MaxRtyCOM 279 | buf[n++] = 1; // Retries (default 0) 280 | if (pn532_tx (p, 0x32, 0, NULL, n, buf) < 0 || pn532_rx (p, 0, NULL, sizeof (buf), buf, 50) < 0) 281 | { 282 | ESP_LOGE (TAG, "RFConfiguration fail %s", pn532_err_to_name (pn532_lasterr (p))); 283 | return pn532_end (p); 284 | } 285 | // RFConfiguration 286 | n = 0; 287 | buf[n++] = 0x02; // Various timings (100*2^(n-1))us 288 | buf[n++] = 0x00; // RFU 289 | buf[n++] = 0x0B; // Default (102.4 ms) 290 | buf[n++] = 0x0A; // Default is 0x0A (51.2 ms) 291 | if (pn532_tx (p, 0x32, 0, NULL, n, buf) < 0 || pn532_rx (p, 0, NULL, sizeof (buf), buf, 50) < 0) 292 | { 293 | ESP_LOGE (TAG, "RFConfiguration fail %s", pn532_err_to_name (pn532_lasterr (p))); 294 | return pn532_end (p); 295 | } 296 | return p; 297 | } 298 | 299 | // Data access 300 | uint8_t * 301 | pn532_ats (pn532_t * p) 302 | { 303 | return p->ats; 304 | } 305 | 306 | uint8_t * 307 | pn532_nfcid (pn532_t * p, char text[21]) 308 | { 309 | if (text) 310 | { 311 | char *o = text; 312 | uint8_t *i = p->nfcid; 313 | if (*i <= 10) 314 | { 315 | int len = *i++; 316 | while (len--) 317 | o += sprintf (o, "%02X", *i++); 318 | } 319 | *o++ = 0; // End 320 | } 321 | return p->nfcid; 322 | } 323 | 324 | // Low level access functions 325 | int 326 | pn532_tx_mutex (pn532_t * p, uint8_t cmd, int len1, uint8_t * data1, int len2, uint8_t * data2) 327 | { // Send data to PN532 328 | if (p->pending) 329 | return -(p->lasterr = PN532_ERR_CMDPENDING); 330 | uint8_t buf[20], 331 | *b = buf; 332 | *b++ = 0x55; 333 | *b++ = 0x55; 334 | *b++ = 0x55; 335 | *b++ = 0x00; // Preamble 336 | *b++ = 0x00; // Start 1 337 | *b++ = 0xFF; // Start 2 338 | int l = len1 + len2 + 2; 339 | if (l >= 0x100) 340 | { 341 | *b++ = 0xFF; // Extended len 342 | *b++ = 0xFF; 343 | *b++ = (l >> 8); // len 344 | *b++ = (l & 0xFF); 345 | *b++ = -(l >> 8) - (l & 0xFF); // Checksum 346 | } else 347 | { 348 | *b++ = l; // Len 349 | *b++ = -l; // Checksum 350 | } 351 | *b++ = 0xD4; // Direction (host to PN532) 352 | *b++ = cmd; 353 | uint8_t sum = 0xD4 + cmd; 354 | for (l = 0; l < len1; l++) 355 | sum += data1[l]; 356 | for (l = 0; l < len2; l++) 357 | sum += data2[l]; 358 | uart_flush_input (p->uart); 359 | // Send data 360 | uart_tx (p, buf, b - buf); 361 | if (len1) 362 | uart_tx (p, data1, len1); 363 | if (len2) 364 | uart_tx (p, data2, len2); 365 | buf[0] = -sum; // Checksum 366 | buf[1] = 0x00; // Postamble 367 | uart_tx (p, buf, 2); 368 | uart_wait_tx_done (p->uart, 1000 / portTICK_PERIOD_MS); 369 | // Get ACK and check it 370 | l = uart_preamble (p, 50); 371 | if (l < 2) 372 | return -(p->lasterr = PN532_ERR_TIMEOUTACK); 373 | l = uart_rx (p, buf, 3, 10); 374 | if (l < 3) 375 | return -(p->lasterr = PN532_ERR_TIMEOUTACK); 376 | if (buf[2]) 377 | return -(p->lasterr = PN532_ERR_BADACK); 378 | if (buf[0] == 0xFF && !buf[1]) 379 | return -(p->lasterr = PN532_ERR_NACK); 380 | if (buf[0] || buf[1] != 0xFF) 381 | return -(p->lasterr = PN532_ERR_BADACK); // Bad 382 | p->pending = cmd + 1; 383 | return len1 + len2; 384 | } 385 | 386 | int 387 | pn532_tx (pn532_t * p, uint8_t cmd, int len1, uint8_t * data1, int len2, uint8_t * data2) 388 | { // Send data to PN532 389 | if (!p) 390 | return -PN532_ERR_NULL; 391 | #ifdef CONFIG_PN532_DEBUG_MSG 392 | { // Messy 393 | uint8_t buf[100], 394 | *p = buf; 395 | *p++ = cmd; 396 | if (len1) 397 | { 398 | memcpy (p, data1, len1); 399 | p += len1; 400 | } 401 | if (len2) 402 | { 403 | memcpy (p, data2, len2); 404 | p += len2; 405 | } 406 | ESP_LOG_BUFFER_HEX_LEVEL ("NFCTx", buf, (int) (p - buf), MSGLOG); 407 | } 408 | #endif 409 | xSemaphoreTake (p->mutex, portMAX_DELAY); 410 | int l = pn532_tx_mutex (p, cmd, len1, data1, len2, data2); 411 | if (!p->pending) 412 | xSemaphoreGive (p->mutex); 413 | return l; 414 | } 415 | 416 | int 417 | pn532_rx_mutex (pn532_t * p, int max1, uint8_t * data1, int max2, uint8_t * data2, int ms) 418 | { // Recv data from PN532 419 | uint8_t pending = p->pending; 420 | p->pending = 0; 421 | int l = uart_preamble (p, ms); 422 | if (l < 2) 423 | return -(p->lasterr = PN532_ERR_TIMEOUT); 424 | uint8_t buf[9]; 425 | l = uart_rx (p, buf, 4, 10); 426 | if (l < 4) 427 | return -(p->lasterr = PN532_ERR_TIMEOUT); 428 | int len = 0; 429 | if (buf[0] == 0xFF && buf[1] == 0xFF) 430 | { // Extended 431 | l = uart_rx (p, buf + 4, 3, 10); 432 | if (l < 3) 433 | return -(p->lasterr = PN532_ERR_TIMEOUT); 434 | if ((uint8_t) (buf[2] + buf[3] + buf[4])) 435 | return -(p->lasterr = PN532_ERR_HEADER); // Bad checksum 436 | len = (buf[2] << 8) + buf[3]; 437 | if (buf[5] != 0xD5) 438 | return -(p->lasterr = PN532_ERR_HEADER); // Not reply 439 | if (buf[6] != pending) 440 | return -(p->lasterr = PN532_ERR_CMDMISMATCH); // Not right reply 441 | } else 442 | { // Normal 443 | if ((uint8_t) (buf[0] + buf[1])) 444 | return -(p->lasterr = PN532_ERR_HEADER); // Bad checksum 445 | len = buf[0]; 446 | if (buf[2] != 0xD5) 447 | return -(p->lasterr = PN532_ERR_HEADER); // Not reply 448 | if (buf[3] != pending) 449 | return -(p->lasterr = PN532_ERR_CMDMISMATCH); // Not right reply 450 | } 451 | if (len < 2) 452 | return -(p->lasterr = PN532_ERR_HEADER); // Invalid 453 | len -= 2; 454 | int res = len; 455 | uint8_t sum = 0xD5 + pending; 456 | if (len > max1 + max2) 457 | return -(p->lasterr = PN532_ERR_SPACE); // Too big 458 | #ifdef CONFIG_PN532_DEBUG_MSG 459 | uint8_t len1 = 0, 460 | len2 = 0; 461 | #endif 462 | if (data1) 463 | { 464 | l = max1; 465 | if (l > len) 466 | l = len; 467 | if (l) 468 | { 469 | #ifdef CONFIG_PN532_DEBUG_MSG 470 | len1 = l; 471 | #endif 472 | if (uart_rx (p, data1, l, 10) < l) 473 | return -(p->lasterr = PN532_ERR_TIMEOUT); // Bad read 474 | len -= l; 475 | while (l) 476 | sum += data1[--l]; 477 | } 478 | } 479 | if (data2) 480 | { 481 | l = max2; 482 | if (l > len) 483 | l = len; 484 | if (l) 485 | { 486 | #ifdef CONFIG_PN532_DEBUG_MSG 487 | len2 = l; 488 | #endif 489 | if (uart_rx (p, data2, l, 10) < l) 490 | return -(p->lasterr = PN532_ERR_TIMEOUT); // Bad read 491 | len -= l; 492 | while (l) 493 | sum += data2[--l]; 494 | } 495 | } 496 | l = uart_rx (p, buf, 2, 10); 497 | if (l < 2) 498 | return -(p->lasterr = PN532_ERR_TIMEOUT); // Postamble 499 | if ((uint8_t) (buf[0] + sum)) 500 | return -(p->lasterr = PN532_ERR_CHECKSUM); // checksum 501 | if (buf[1]) 502 | return -(p->lasterr = PN532_ERR_POSTAMBLE); // postamble 503 | #ifdef CONFIG_PN532_DEBUG_MSG 504 | { // Messy 505 | uint8_t buf[100], 506 | *p = buf; 507 | *p++ = pending; 508 | if (len1) 509 | { 510 | memcpy (p, data1, len1); 511 | p += len1; 512 | } 513 | if (len2) 514 | { 515 | memcpy (p, data2, len2); 516 | p += len2; 517 | } 518 | ESP_LOG_BUFFER_HEX_LEVEL ("NFCRx", buf, (int) (p - buf), MSGLOG); 519 | } 520 | #endif 521 | return res; 522 | } 523 | 524 | int 525 | pn532_rx (pn532_t * p, int max1, uint8_t * data1, int max2, uint8_t * data2, int ms) 526 | { // Recv data from PN532 527 | if (!p) 528 | return -PN532_ERR_NULL; 529 | if (!p->pending) 530 | return -(p->lasterr = PN532_ERR_NOTPENDING); 531 | int l = pn532_rx_mutex (p, max1, data1, max2, data2, ms); 532 | xSemaphoreGive (p->mutex); 533 | return l; 534 | } 535 | 536 | int 537 | pn532_ready (pn532_t * p) 538 | { 539 | if (!p) 540 | return -PN532_ERR_NULL; 541 | if (!p->pending) 542 | return -(p->lasterr = PN532_ERR_NOTPENDING); // Nothing pending 543 | size_t length; 544 | if (uart_get_buffered_data_len (p->uart, &length)) 545 | return -(p->lasterr = 2); // Error 546 | return length; 547 | } 548 | 549 | // Data exchange (for DESFire use) 550 | int 551 | pn532_dx (void *pv, unsigned int len, uint8_t * data, unsigned int max, const char **strerr) 552 | { // Card access function - sends to card starting CMD byte, and receives reply in to same buffer, starting status byte, returns len 553 | if (strerr) 554 | *strerr = "No error"; 555 | pn532_t *p = pv; 556 | if (!p) 557 | return -PN532_ERR_NULL; 558 | if (!p->cards) 559 | return 0; // No card 560 | #ifdef CONFIG_PN532_DEBUG_DX 561 | #ifndef CONFIG_PN532_DUMP 562 | ESP_LOG_BUFFER_HEX_LEVEL ("NFCTx", data, len, DXLOG); 563 | #endif 564 | #endif 565 | int l = pn532_tx (p, 0x40, 1, &p->tg, len, data); 566 | if (l >= 0) 567 | { 568 | uint8_t status; 569 | l = pn532_rx (p, 1, &status, max, data, 500); 570 | if (!l) 571 | l = -PN532_ERR_SHORT; 572 | else if (l >= 1 && status) 573 | l = -PN532_ERR_STATUS - status; 574 | #ifdef CONFIG_PN532_DEBUG_DX 575 | #ifndef CONFIG_PN532_DUMP 576 | if (l > 0) 577 | ESP_LOG_BUFFER_HEX_LEVEL ("NFCRx", data, l - 1, DXLOG); 578 | #endif 579 | #endif 580 | } 581 | if (l < 0) 582 | { 583 | p->lasterr = -l; 584 | #ifdef CONFIG_PN532_DEBUG_DX 585 | ESP_LOG_LEVEL (DXLOG, "NFCErr", "%s", pn532_err_to_name (p->lasterr)); 586 | #endif 587 | if (strerr) 588 | *strerr = pn532_err_to_name (p->lasterr); 589 | } else 590 | l--; // Allow for status 591 | return l; 592 | } 593 | 594 | // Other higher level functions 595 | int 596 | pn532_ILPT_Send (pn532_t * p) 597 | { 598 | if (!p) 599 | return -PN532_ERR_NULL; 600 | uint8_t buf[3]; 601 | // InListPassiveTarget 602 | buf[0] = 2; // 2 tags (we only report 1) 603 | buf[1] = 0; // 106 kbps type A (ISO/IEC14443 Type A) 604 | int l = pn532_tx (p, 0x4A, 2, buf, 0, NULL); 605 | if (l < 0) 606 | return l; 607 | return 0; // Waiting 608 | } 609 | 610 | int 611 | pn532_Present (pn532_t * p) 612 | { 613 | if (!p) 614 | return -PN532_ERR_NULL; 615 | uint8_t buf[1]; 616 | if (!p->pending && p->cards && *p->ats && (p->ats[1] == 0x75 // DESFire 617 | //|| p->ats[1] == 0x78 // ISO 618 | )) 619 | { // We have cards, check in field still 620 | buf[0] = 6; // Test 6 Attention Request Test or ISO/IEC14443-4 card presence detection 621 | int l = pn532_tx (p, 0x00, 1, buf, 0, NULL); 622 | if (l >= 0) 623 | l = pn532_rx (p, 0, NULL, sizeof (buf), buf, 110); 624 | if (l < 0) 625 | return l; 626 | if (l < 1) 627 | return -(p->lasterr = PN532_ERR_SHORT); 628 | if (!*buf) 629 | return p->cards; // Still in field 630 | } 631 | return pn532_Cards (p); // Look for card - older MIFARE need re-doing to see if present still 632 | } 633 | 634 | int 635 | pn532_deselect (pn532_t * p, uint8_t n) 636 | { // Send a release 637 | if (!p) 638 | return -PN532_ERR_NULL; 639 | uint8_t buf[2]; 640 | buf[0] = n; 641 | int l = pn532_tx (p, 0x44, 1, buf, 0, NULL); 642 | if (l >= 0) 643 | l = pn532_rx (p, 0, NULL, sizeof (buf), buf, 100); 644 | return l; 645 | } 646 | 647 | int 648 | pn532_release (pn532_t * p, uint8_t n) 649 | { // Send a release 650 | if (!p) 651 | return -PN532_ERR_NULL; 652 | uint8_t buf[2]; 653 | buf[0] = n; 654 | int l = pn532_tx (p, 0x52, 1, buf, 0, NULL); 655 | if (l >= 0) 656 | l = pn532_rx (p, 0, NULL, sizeof (buf), buf, 100); 657 | return l; 658 | } 659 | 660 | int 661 | pn532_write_GPIO (pn532_t * p, uint8_t value) 662 | { // Write P3/P7 (P72/P71 in top bits, P35-30 in rest) 663 | if (!p) 664 | return -PN532_ERR_NULL; 665 | uint8_t buf[2]; 666 | buf[0] = 0x80 | (value & 0x3F); 667 | buf[1] = 0x80 | ((value >> 5) & 0x06); 668 | int l = pn532_tx (p, 0x0E, 2, buf, 0, NULL); 669 | if (l >= 0) 670 | l = pn532_rx (p, 0, NULL, sizeof (buf), buf, 50); 671 | return l; 672 | } 673 | 674 | int 675 | pn532_read_GPIO (pn532_t * p) 676 | { // Read P3/P7 (P72/P71 in top bits, P35-30 in rest) 677 | if (!p) 678 | return -PN532_ERR_NULL; 679 | uint8_t buf[3]; 680 | int l = pn532_tx (p, 0x0C, 0, NULL, 0, NULL); 681 | if (l >= 0) 682 | l = pn532_rx (p, 0, NULL, sizeof (buf), buf, 50); 683 | if (l < 0) 684 | return l; 685 | if (l < 3) 686 | return -(p->lasterr = PN532_ERR_SHORT); 687 | return (buf[0] & 0x3F) | ((buf[1] & 0x06) << 5); 688 | } 689 | 690 | int 691 | pn532_Cards (pn532_t * p) 692 | { // -ve for error, else number of cards 693 | if (!p) 694 | return -PN532_ERR_NULL; 695 | uint8_t buf[100]; 696 | // InListPassiveTarget to get card count and baseID 697 | if (!p->pending) 698 | pn532_ILPT_Send (p); 699 | if (p->pending != 0x4B) 700 | return -(p->lasterr = PN532_ERR_CMDMISMATCH); // We expect to be waiting for InListPassiveTarget response 701 | int l = pn532_rx (p, 0, NULL, sizeof (buf), buf, 110); 702 | if (l < 0) 703 | return l; 704 | memset (p->nfcid, 0, sizeof (p->nfcid)); 705 | memset (p->ats, 0, sizeof (p->ats)); 706 | // Extract first card ID 707 | uint8_t *b = buf, 708 | *e = buf + l; // end 709 | if (b >= e) 710 | return -(p->lasterr = PN532_ERR_SHORT); // No card count 711 | p->cards = *b++; 712 | if (p->cards) 713 | { // Get details of first card 714 | if (b + 5 > e) 715 | return -(p->lasterr = PN532_ERR_SPACE); // No card data 716 | p->tg = *b++; 717 | p->sens_res = (b[0] << 8) + b[1]; 718 | b += 2; 719 | p->sel_res = *b++; 720 | if (b + *b + 1 > e) 721 | return -(p->lasterr = PN532_ERR_SHORT); // Too short 722 | if (*b < sizeof (p->nfcid)) 723 | memcpy (p->nfcid, b, *b + 1); // OK 724 | else 725 | memset (p->nfcid, 0, sizeof (p->nfcid)); // Too big 726 | b += *b + 1; 727 | if (b < e) 728 | { // ATS 729 | if (!*b || b + *b > e) 730 | return -(p->lasterr = PN532_ERR_SHORT); // Zero or missing ATS 731 | if (*b <= sizeof (p->ats)) 732 | { 733 | memcpy (p->ats, b, *b); // OK 734 | (*p->ats)--; // Make len of what follows for consistency 735 | } 736 | b += *b; // ready for second target (which we are not looking at) 737 | } 738 | } 739 | return p->cards; 740 | } 741 | -------------------------------------------------------------------------------- /tools/.gitignore: -------------------------------------------------------------------------------- 1 | pn532test 2 | -------------------------------------------------------------------------------- /tools/Makefile: -------------------------------------------------------------------------------- 1 | all: pn532test 2 | 3 | pn532test: pn532test.c 4 | cc -Wall -Wextra -O -o pn532test pn532test.c -I. -lpopt 5 | -------------------------------------------------------------------------------- /tools/pn532test.c: -------------------------------------------------------------------------------- 1 | /* PN532 via serial port */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int debug = 0; 12 | uint8_t pending = 0; 13 | 14 | int 15 | swrite(int p, uint8_t * buf, int l) 16 | { 17 | if (debug) 18 | for (int n = 0; n < l; n++) 19 | fprintf(stderr, " %02X", buf[n]); 20 | int r = write(p, buf, l); 21 | if (r < 0) 22 | err(1, "Write failed (%d!=%d)", r, l); 23 | return r; 24 | } 25 | 26 | int 27 | sread(int p, uint8_t * buf, int l) 28 | { 29 | int q = 0; 30 | while (q < l) 31 | { 32 | fd_set f; 33 | FD_ZERO(&f); 34 | FD_SET(p, &f); 35 | struct timeval t = {0, 100000}; 36 | if (select(p + 1, &f, NULL, NULL, &t) < 1) 37 | return 0; 38 | int r = read(p, buf + q, l - q); 39 | if (r <= 0) 40 | err(1, "Read failed (%d!=%d)", r, l); 41 | q += r; 42 | } 43 | if (debug) 44 | for (int n = 0; n < l; n++) 45 | fprintf(stderr, " %02X", buf[n]); 46 | return l; 47 | } 48 | 49 | int 50 | pn532_tx(int p, uint8_t cmd, int len1, uint8_t * data1, int len2, uint8_t * data2) 51 | { 52 | if (debug) 53 | fprintf(stderr, "Tx:"); 54 | if (pending) 55 | return -__LINE__; 56 | uint8_t buf[20]; 57 | uint8_t *b = buf; 58 | int l = len1 + len2 + 2; 59 | *b++ = 0x55; 60 | *b++ = 0x55; 61 | *b++ = 0x55; 62 | *b++ = 0x00; /* Preamble */ 63 | *b++ = 0x00; /* Start 1 */ 64 | *b++ = 0xFF; /* Start 2 */ 65 | if (l >= 0x100) 66 | { 67 | *b++ = 0xFF; 68 | /* Extended len */ 69 | *b++ = 0xFF; 70 | *b++ = (l >> 8); 71 | /* len */ 72 | *b++ = (l & 0xFF); 73 | *b++ = -(l >> 8) - (l & 0xFF); 74 | /* Checksum */ 75 | } else 76 | { 77 | *b++ = l; 78 | /* Len */ 79 | *b++ = -l; 80 | /* Checksum */ 81 | } 82 | *b++ = 0xD4; 83 | /* Direction(host to PN532) */ 84 | *b++ = cmd; 85 | uint8_t sum = 0xD4 + cmd; 86 | for (l = 0; l < len1; l++) 87 | sum += data1[l]; 88 | for (l = 0; l < len2; l++) 89 | sum += data2[l]; 90 | /* Send data */ 91 | swrite(p, buf, b - buf); 92 | if (len1) 93 | write(p, data1, len1); 94 | if (len2) 95 | swrite(p, data2, len2); 96 | buf[0] = -sum; 97 | /* Checksum */ 98 | buf[1] = 0x00; 99 | /* Postamble */ 100 | swrite(p, buf, 2); 101 | if (debug) 102 | fprintf(stderr, "\nRx:"); 103 | /* Get ACK and check it */ 104 | while ((l = sread(p, buf, 1)) == 1 && *buf != 0x00); 105 | if (l <= 0) 106 | return -__LINE__; 107 | while ((l = sread(p, buf, 1)) == 1 && *buf != 0xFF); 108 | if (l <= 0) 109 | return -__LINE__; 110 | l = sread(p, buf, 3); 111 | if (l < 3) 112 | return -__LINE__; 113 | if (buf[2]) 114 | return -__LINE__; 115 | if (buf[0] == 0xFF && !buf[1]) 116 | return -__LINE__; 117 | if (buf[0] || buf[1] != 0xFF) 118 | return -__LINE__; 119 | pending = cmd + 1; /* Expected reply */ 120 | if (debug) 121 | fprintf(stderr, "\n"); 122 | return len1 + len2; 123 | } 124 | 125 | int 126 | pn532_rx(int p, int max1, uint8_t * data1, int max2, uint8_t * data2) 127 | { 128 | if (debug) 129 | fprintf(stderr, "Rx:"); 130 | if (!pending) 131 | return -__LINE__; 132 | uint8_t expect = pending; 133 | pending = 0; 134 | /* Recv data from PN532 */ 135 | uint8_t buf[9]; 136 | int l; 137 | while ((l = sread(p, buf, 1)) == 1 && *buf != 0x00); 138 | if (l <= 0) 139 | return -__LINE__; 140 | while ((l = sread(p, buf, 1)) == 1 && *buf != 0xFF); 141 | if (l <= 0) 142 | return -__LINE__; 143 | l = sread(p, buf, 4); 144 | if (l < 4) 145 | return -__LINE__; 146 | int len = 0; 147 | if (buf[0] == 0xFF && buf[1] == 0xFF) 148 | { /* Extended */ 149 | l = sread(p, buf + 4, 3); 150 | if (l < 3) 151 | return -__LINE__; 152 | if ((uint8_t) (buf[2] + buf[3] + buf[4])) 153 | return -__LINE__; 154 | len = (buf[2] << 8) + buf[3]; 155 | if (buf[5] != 0xD5) 156 | return -__LINE__; 157 | if (buf[6] != expect) 158 | return -__LINE__; 159 | } else 160 | { /* Normal */ 161 | if ((uint8_t) (buf[0] + buf[1])) 162 | return -__LINE__; 163 | len = buf[0]; 164 | if (buf[2] != 0xD5) 165 | return -__LINE__; 166 | if (buf[3] != expect) 167 | return -__LINE__; 168 | } 169 | if (len < 2) 170 | return -__LINE__; 171 | len -= 2; 172 | int res = len; 173 | uint8_t sum = 0xD5 + expect; 174 | if (len > max1 + max2) 175 | return -__LINE__; 176 | if (data1) 177 | { 178 | l = max1; 179 | if (l > len) 180 | l = len; 181 | if (l) 182 | { 183 | if (sread(p, data1, l) < l) 184 | return -__LINE__; 185 | len -= l; 186 | while (l) 187 | sum += data1[--l]; 188 | } 189 | } 190 | if (data2) 191 | { 192 | l = max2; 193 | if (l > len) 194 | l = len; 195 | if (l) 196 | { 197 | if (sread(p, data2, l) < l) 198 | return -__LINE__; 199 | len -= l; 200 | while (l) 201 | sum += data2[--l]; 202 | } 203 | } 204 | l = sread(p, buf, 2); 205 | if (l < 2) 206 | return -__LINE__; 207 | if ((uint8_t) (buf[0] + sum)) 208 | return -__LINE__; 209 | if (buf[1]) 210 | return -__LINE__; 211 | if (debug) 212 | fprintf(stderr, "\n"); 213 | return res; 214 | } 215 | int 216 | main(int argc, const char *argv[]) 217 | { 218 | const char *port = NULL; 219 | { /* POPT */ 220 | poptContext optCon; 221 | const struct poptOption optionsTable[] = { 222 | {"port", 'p', POPT_ARG_STRING, &port, 0, "Port", "/dev/cu.usbserial..."}, 223 | {"debug", 'v', POPT_ARG_NONE, &debug, 0, "Debug", 0}, 224 | POPT_AUTOHELP {} 225 | }; 226 | 227 | optCon = poptGetContext(NULL, argc, argv, optionsTable, 0); 228 | 229 | int c; 230 | if ((c = poptGetNextOpt(optCon)) < -1) 231 | errx(1, "%s: %s\n", poptBadOption(optCon, POPT_BADOPTION_NOALIAS), poptStrerror(c)); 232 | 233 | if (!port && poptPeekArg(optCon)) 234 | port = poptGetArg(optCon); 235 | 236 | if (!port || poptPeekArg(optCon)) 237 | { 238 | poptPrintUsage(optCon, stderr, 0); 239 | return -1; 240 | } 241 | poptFreeContext(optCon); 242 | } 243 | int p = open(port, O_RDWR); 244 | if (p < 0) 245 | err(1, "Cannot open %s", port); 246 | struct termios t; 247 | if (tcgetattr(p, &t) < 0) 248 | err(1, "Cannot get termios"); 249 | cfsetspeed(&t, 115200); /* The default HSU baud rate */ 250 | if (tcsetattr(p, TCSANOW, &t) < 0) 251 | err(1, "Cannot set termios"); 252 | usleep(100000); 253 | tcflush(p, TCIOFLUSH); 254 | 255 | uint8_t buf[300]; 256 | int n, 257 | l; 258 | while (1) 259 | { 260 | /* SAM config */ 261 | n = 0; 262 | buf[n++] = 0x01; /* Normal */ 263 | buf[n++] = 20; /* *50 ms timeout */ 264 | buf[n++] = 0x01; /* Use IRQ */ 265 | if ((l = pn532_tx(p, 0x14, 0, NULL, n, buf)) < 0 || (l = pn532_rx(p, 0, NULL, sizeof(buf), buf)) < 0) 266 | warnx("GetFirmwareVersion fail (%d)", -l); 267 | else 268 | break; 269 | } 270 | /* RFConfiguration */ 271 | n = 0; 272 | buf[n++] = 5; /* Config item 5(MaxRetries) */ 273 | buf[n++] = 0xFF; /* MxRtyATR(default = 0xFF) */ 274 | buf[n++] = 0x01; /* MxRtyPSL(default = 0x01) */ 275 | buf[n++] = 0x01; /* MxRtyPassiveActivation */ 276 | if ((l = pn532_tx(p, 0x32, 0, NULL, n, buf)) < 0 || (l = pn532_rx(p, 0, NULL, sizeof(buf), buf)) < 0) 277 | errx(1, "RFConfiguration fail (%d)", -l); 278 | /* RFConfiguration */ 279 | n = 0; 280 | buf[n++] = 0x04; /* MaxRtyCOM */ 281 | buf[n++] = 1; /* Retries (default 0) */ 282 | if ((l = pn532_tx(p, 0x32, 0, NULL, n, buf)) < 0 || (l = pn532_rx(p, 0, NULL, sizeof(buf), buf)) < 0) 283 | errx(1, "RFConfiguration fail (%d)", -l); 284 | /* RFConfiguration */ 285 | n = 0; 286 | buf[n++] = 0x02; /* Various timings (100*2^(n-1))us */ 287 | buf[n++] = 0x00; /* RFU */ 288 | buf[n++] = 0x0B; /* Default (102.4 ms) */ 289 | buf[n++] = 0x0A; /* Default is 0x0A (51.2 ms) */ 290 | if ((l = pn532_tx(p, 0x32, 0, NULL, n, buf)) < 0 || (l = pn532_rx(p, 0, NULL, sizeof(buf), buf)) < 0) 291 | errx(1, "RFConfiguration fail (%d)", -l); 292 | 293 | while (1) 294 | { 295 | /* InListPassiveTarget */ 296 | buf[0] = 2; /* 2 tags(we only report 1) */ 297 | buf[1] = 0; /* 106 kbps type A(ISO / IEC14443 Type A) */ 298 | if ((l = pn532_tx(p, 0x4A, 2, buf, 0, NULL)) < 0 || (l = pn532_rx(p, 0, NULL, sizeof(buf), buf)) < 0) 299 | if (l < 0) 300 | warnx("Bad ILPT (%d)", -l); 301 | if (l > 1) 302 | { 303 | //Found a card 304 | fprintf(stderr, "Card:"); 305 | for (int n = 0; n < l; n++) 306 | fprintf(stderr, " %02X", buf[n]); 307 | fprintf(stderr, "\n"); 308 | } 309 | } 310 | 311 | close(p); 312 | return 0; 313 | } 314 | --------------------------------------------------------------------------------