commit 1497821b2ef2159bf83b3c8f859b7dca5f060907 Author: Sébastien Millet Date: Fri Jun 4 11:57:28 2021 +0200 Initial Upload diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..36a8603 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build +build-uno +tmpout* diff --git a/Debug.cpp b/Debug.cpp new file mode 100644 index 0000000..1174f14 --- /dev/null +++ b/Debug.cpp @@ -0,0 +1,63 @@ +// Debug.cpp + +/* + Provides some useful functions to output debug from Arduino on the serial + line. + Used and tested with an Arduino nano. +*/ + +/* + Copyright 2021 Sébastien Millet + + `rf433any' is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + `rf433any' is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + . +*/ + +#include "Debug.h" +#include +#include + +// What items to include in the debug lines: + +static char buffer[150]; +static char progmem_reading_buffer[100]; + +#ifdef __arm__ +// should use uinstd.h to define sbrk but Due causes a conflict +extern "C" char* sbrk(int incr); +#else // __ARM__ +extern char *__brkval; +#endif // __arm__ + +void dbgfunc(const char* file, long int line, const char* progmem_str) { + strcpy_P(progmem_reading_buffer, progmem_str); + Serial.print(progmem_reading_buffer); + Serial.print("\n"); +} + +void dbgffunc(const char* file, long int line, const char* progmem_fmt, ...) { + strcpy_P(progmem_reading_buffer, progmem_fmt); + va_list args; + + // FIXME +#pragma GCC diagnostic ignored "-Wvarargs" + va_start(args, progmem_reading_buffer); + + vsnprintf(buffer, sizeof(buffer), progmem_reading_buffer, args); + va_end(args); + Serial.print(buffer); + Serial.print("\n"); +} + +// vim: ts=4:sw=4:tw=80:et diff --git a/Debug.h b/Debug.h new file mode 100644 index 0000000..b47e7b1 --- /dev/null +++ b/Debug.h @@ -0,0 +1,40 @@ +// Debug.h + +/* + Copyright 2021 Sébastien Millet + + `rf433any' is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + `rf433any' is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + . +*/ + +#ifndef _DEBUG_H +#define _DEBUG_H + +#define dbg(a) \ + { static const char tmp[] PROGMEM = {a}; \ + dbgfunc(__FILE__, __LINE__, tmp); \ + } + +#define dbgf(a, ...) \ + { static const char tmp[] PROGMEM = {a}; \ + dbgffunc(__FILE__, __LINE__, tmp, __VA_ARGS__); \ + } + +void dbgfunc(const char* file, long int line, const char *msg); +void dbgffunc(const char* file, long int line, const char *format, ...) + __attribute__((format(printf, 3, 4))); + +#endif // _DEBUG_H + +// vim: ts=4:sw=4:tw=80:et diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..87a2a68 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +ARDUINO_DIR = /usr/share/arduino +ARDUINO_LIBS = +ARDMK_DIR = /home/sebastien/.arduino_mk + +# USER_LIB_PATH = /home/sebastien/travail/cpp/seb/arduino/libraries + +BOARD_TAG = uno +MCU = atmega328 + +include $(ARDMK_DIR)/Arduino.mk diff --git a/README.md b/README.md new file mode 100644 index 0000000..de72316 --- /dev/null +++ b/README.md @@ -0,0 +1,90 @@ +RF433any +======== + +Uses a RF433Mhz component plugged on an Arduino to listen to signals and decode +it. + + +Installation +------------ + +Download a zip of this repository, then include it from the Arduino IDE. + + +Schematic +--------- + +1. Arduino board. Tested with NANO and UNO. + +2. Radio Frequence 433Mhz RECEIVER like MX-RM-5V. + +RF433 RECEIVER data pin must be plugged on a board' digital PIN that can +trigger interrupts, that is, D2 or D3. + +This RECEIVER PIN is defined at the time a 'Track' object is created. This +library does not set it at compile time. + +See file schema.fzz (Fritzing format) or schema.png, for a circuit example with +receiver plugged on D2. + + +Usage +----- + +See [examples/output-signal-timings/output-signal-timings.ino](examples/output-signal-timings/output-signal-timings.ino) for an example. + + +More details +------------ + +The library assumes one of the following auto-synchronization protocols (tiret +for high signal, underscore for low radio signal): + + Tri-bit __- versus _-- + + Tri-bit inverted -__ versus --_ + + Manchester _- versus -_ + +The decoder tries to be as flexible as possible to decode any protocols, +without pre-knowledge about signal timings. To be generic enough, only the +_relationships_ between timings is analyzed, to deduct the 'short' and 'long' +duration on 'low' and 'high' radio frequence signal value. No pre-defined +timing is used. + +Most often, 'long' is twice as long as 'short', and the durations on the low +signal are the same as on the high signal, but this library doesn't assume it. +'long' are not necessarily twice as long as 'short', and the high signal +timings can be totally different from the low signal timings. + +The signal can also contain the below: + +* A 'prefix' made of a first succession of 'low, high' durations that don't +match short and long durations encountered later. Such a prefix has been seen +on FLO/R telecommands, likely, to distinguish between FLO (fixed code) and +FLO/R (rolling code). + +* A 'sync' prefix made of a succession of low and high of the same duration. +Note such a prefix could be regarded as Manchester encoding of as many '0' bits +(when using CONVENTION_0, see below). The library assumes that such a sequence, +if seen at the beginning ('short' and 'long' durations are not yet known), +corresponds to a synchronization prefix, not to a Manchester encoding of '0' +bits. + +The signal decoding can be done using two conventions. +Switching from one convention to another for the same signal will simply invert +bit values. + + +Bit value depending on convention +--------------------------------- + +| | Signal shape | CONVENTION_0 | CONVENTION_1 | +| ---------------- | --------------------- | ------------ | ------------ | +| Tri-bit | low short, high long | 0 | 1 | +| Tri-bit | low long, high short | 1 | 0 | +| Tri-bit Inverted | high short, low long | 0 | 1 | +| Tri-bit Inverted | high long, low short | 1 | 0 | +| Manchester | low short, high short | 0 | 1 | +| Manchester | high short, low short | 1 | 0 | + diff --git a/RF433any.cpp b/RF433any.cpp new file mode 100644 index 0000000..e98a30f --- /dev/null +++ b/RF433any.cpp @@ -0,0 +1,1676 @@ +// RF433any.cpp + +// See README.md about the purpose of this library + +/* + Copyright 2021 Sébastien Millet + + `RF433any' is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + `RF433any' is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + . +*/ + +/* + Schematic + + 1. Arduino board. Tested with NANO and UNO. + 2. Radio Frequence 433Mhz RECEIVER like MX-RM-5V. + + RF433 RECEIVER data pin must be plugged on a board' digital PIN that can + trigger interrupts, that is, D2 or D3. + This RECEIVER PIN is defined at the time a 'Track' object is created. This + library does not set it at compile time. + See file schema.fzz (Fritzing format) or schema.png, for a circuit example + with receiver plugged on D2. +*/ + +/* + +**About the classes Band, Rail and Track** + +1. About none of these - the signal as we see it. + +The Radio-Frequence signal is supposed to be OOK (On-Off Keying), and +auto-synchronized. + +The signal is a succession of low signal and high signal, low when no RF signal +received, high when a RF signal is received. +The coding relies on durations being either 'short' or 'long', and sometimes +much longer (to initialize, and to separate signal pieces). + +The durations can be one of: + - short + - long, typically, twice as long as short + - separator, much longer than the long one (at least 3 or 4 times longer) + - initialization, at least as long as the separator, often much longer. It + serves to make receiver ready to receive coded signal to come. + +A signal structure is as follows: + 1. Initialization (very long high signal) + 2. Succession of low and high signals being 'short' or 'long' + 3. Separator (high signal) + 4. Possibly, repetition of steps 2 and 3 + +The succession of 'short' and 'long' is then decoded into original data, either +based on tri-bit scheme (inverted or not), or, Manchester. + +Note that there can be complexities: + +- After the long initialization high signal, addition of 'intermediate' prefix + to the signal (longer than 'long', but shorter than 'separator'). Seen on a + NICE FLO/R telecommand (/R means Rolling Code), while not seen on NICE FLO + (fix code). The author guesses this prefix serves to let the receiver know the + signal to come is FLO/R instead of FLO. + +- After the long initialization high signal, succession of {low=short, + high=short} followed by a separator. This serves as a synchronization + sequence. + +- While most protocols use same lengths for low and high signals, on NICE FLO/R + this rule is not met, that is: the 'short' and 'long' durations of the low + signal are different from 'short' and 'long' durations of the high signal. + +2. About Rail + +The Rail manages the succession of durations for one, and only one, of signal +realms (low or high). + +That is, if you note dow the signal as usually (by line, one low followed by one +high): + LOW, HIGH + 150, 200 + 145, 400 + 290, 195 + ... + +Then the values below LOW (150, 145, 290, ...) are one Rail, and the values +below HIGH (200, 400, 195, ...) are another Rail. + +3. About Bands + +A band aims to categorize a duration, short or long. Therefore, a Rail is made +of 2 bands, one for the short duration, one for the long duration. + +4. About Tracks + +Rails live their own live but at some point, they must work in conjunction +(start and stop together, and provide final decoded values). This is the purpose +of a Track, that is made of 2 Rails. + +In the end, a Track provides a convenient interface to the caller. + +5. Overall schema + +track -> r_low -> b_short = manage short duration on LOW signal + | `-> b_long = manage long duration on LOW signal + | + `-> r_high -> b_short = manage short duration on HIGH signal + `-> b_long = manage long duration on HIGH signal + +*/ + +#include "RF433any.h" +#include + +void assert_failed(int line) { +#ifdef ASSERT_OUTPUT_TO_SERIAL + Serial.print("\nRF433any.cpp:"); + Serial.print(line); + Serial.println(": assertion failed, aborted."); +#endif + while (1) + ; +} + + +// * **** ********************************************************************* +// * Band ********************************************************************* +// * **** ********************************************************************* + +inline void Band::breset() { + inf = 0; + sup = 0; + mid = 0; +} + +inline bool Band::init(uint16_t d) { +#ifdef DBG_TRACE + dbgf("B> init: %u", d); +#endif + + if (d >= BAND_MIN_D && d <= BAND_MAX_D) { + mid = d; + uint16_t d_divided_by_4 = d >> 2; + inf = d - d_divided_by_4; + sup = d + d_divided_by_4; + got_it = true; + } else { + got_it = false; + } + + return got_it; +} + +inline bool Band::init_sep(uint16_t d) { +#ifdef DBG_TRACE + dbgf("BSEP> init: %u", d); +#endif + + sup = MAX_SEP_DURATION; + inf = d >> 1; + inf += (inf >> 2); + mid = d; + + got_it = true; + return got_it; +} + +inline bool Band::test_value_init_if_needed(uint16_t d) { + if (!mid) { + init(d); + } else { + got_it = (d >= inf && d <= sup); +#ifdef DBG_TRACE + dbgf("B> cmp %u to [%u, %u]", d, inf, sup); +#endif + } +#ifdef DBG_TRACE + dbgf("B> res: %d", got_it); +#endif + return got_it; +} + +inline bool Band::test_value(uint16_t d) { + if (!mid) { + got_it = false; +#ifdef DBG_TRACE + dbgf("BSEP> cmp %u to uninitialized d", d); +#endif + } else { + got_it = (d >= inf && d <= sup); +#ifdef DBG_TRACE + dbgf("BSEP> cmp %u to [%u, %u]", d, inf, sup); +#endif + } +#ifdef DBG_TRACE + dbgf("BSEP> res: %d", got_it); +#endif + return got_it; +} + + +// * **** ********************************************************************* +// * Rail ********************************************************************* +// * **** ********************************************************************* + +Rail::Rail(byte arg_mood):mood(arg_mood) { + rreset(); +} + +inline void Rail::rreset() { + rreset_soft(); + + b_short.breset(); + b_long.breset(); + b_sep.breset(); +} + +inline void Rail::rreset_soft() { + status = RAIL_OPEN; + index = 0; + rec = 0; +} + +inline bool Rail::rail_eat(uint16_t d) { +#ifdef DBG_TRACE + dbgf("R> index = %d, d = %u", index, d); +#endif + + if (status != RAIL_OPEN) + return false; + + byte count_got_it = 0; + if (b_short.test_value_init_if_needed(d)) + ++count_got_it; + if (b_long.test_value_init_if_needed(d)) + ++count_got_it; + + byte band_count = get_band_count(); + +#ifdef DBG_TRACE + dbgf("R> b_short.got_it = %d, b_long.got_it = %d, " + "band_count = %d", b_short.got_it, b_long.got_it, + band_count); + for (int i = 0; i < 2; ++i) { + dbgf("R> [%i]: inf = %u, mid = %u, sup = %u", i, + (i == 0 ? b_short.inf : b_long.inf), + (i == 0 ? b_short.mid : b_long.mid), + (i == 0 ? b_short.sup : b_long.sup)); + } +#endif + + if (band_count == 1 && !count_got_it) { + Band *pband; + // IMPORTANT + // We are using below 'unsigned long' although they are + // initialized using uint16_t values. + // We need 'unsigned long' because later in the code, we check + // whether 'big' is not more than 4 times 'short' (if it is, then + // the coding shape is too distorted and we give up). + // We do this check by calculating 'small << 2', therefore it + // could be that this operation ends up above 16-bit max unsigned + // integer value. + unsigned long small; + unsigned long big; + if (d < b_short.inf) { + pband = &b_short; + small = d; + big = b_short.mid; + } else if (d > b_short.sup) { + pband = &b_long; + small = b_short.mid; + big = d; + } else { + // Should not happen. + // If value is within band range, then why the hell didn't the + // range grab it? + assert(false); + } + +#ifdef DBG_TRACE + dbg("R> P0"); +#endif + + if ((small << 2) >= big) { + if (pband->init(d)) { + +#ifdef DBG_TRACE + dbg("R> P1"); +#endif + + // As we now know who's who (b_short is b_short and b_long + // is b_long, yes), we can adjust boundaries accordingly. + + b_short.inf = (b_short.mid >> 1) - (b_short.mid >> 3); + if (mood == RAIL_MOOD_LAXIST) { + b_short.sup = (b_short.mid + b_long.mid) >> 1; + b_long.inf = b_short.sup + 1; + } + b_long.sup = b_long.mid + (b_long.mid >> 1) + (b_long.mid >> 3); + + count_got_it = 1; + band_count = 2; + + // Test if intervals overlap? + // That is, test if b_short.sup >= b_long.inf? + // Not done for now... + ; + + if (pband == &b_short) { + // The first N signals received ('N' equals 'index') + // happened to be LONG ones => to be recorded as as many + // ONEs. + rec = ((recorded_t)1 << index) - 1; + } + } + } + } + + if (!band_count) { + status = RAIL_ERROR; + return false; + } + + if (!count_got_it || (band_count == 2 && count_got_it == 2)) { + if (!b_sep.mid) { + // BAND_MAX_D is 30000, and multiplying .mid by 2 will produce a + // maximum value of 60000, that's OK for an unsigned 16-bit int. + if (d >= (b_short.mid << 1) && d >= (b_long.mid << 1)) { +#ifdef DBG_TRACE + dbg("R> init b_sep"); +#endif + // We can end up with an overlap between b_sep and b_long. + // Not an issue. + b_sep.init_sep(d); + } else { +#ifdef DBG_TRACE + dbg("R> no init of b_sep (d too small)"); +#endif + } + } + status = (b_sep.test_value(d) ? RAIL_STP_RCVD : RAIL_ERROR); + +#ifdef DBG_TRACE + dbgf("R> rail terminated, status = %d", status); +#endif + + } else { + + if (band_count == 2) { + if (b_short.got_it == b_long.got_it) { + assert(false); + } + last_bit_recorded = (b_short.got_it ? 0 : 1); + rec = (rec << 1) | last_bit_recorded; + } else { + last_bit_recorded = 0; + } + if (++index == (sizeof(rec) << 3)) { + status = RAIL_FULL; + } + + } + + return (status == RAIL_OPEN); +} + +#ifdef RF433ANY_DBG_TRACK +const char* status_names[] = { + "open", + "full", + "stop received", + "closed", + "error" +}; +void Rail::rail_debug() const { + dbgf(" \"bits\":%i,\"v\":0x" FMTRECORDEDT + ",\"railstatus\":\"%s\",\"n\":%d,", index, rec, status_names[status], + (b_short.mid == b_long.mid ? 1 : 2)); + for (byte i = 0; i < 3; ++i) { + dbgf(" \"%s\":{\"inf\":%u,\"mid\":%u,\"sup\":%u}%s", + (i == 0 ? "b_short" : (i == 1 ? "b_long" : "b_sep")), + (i == 0 ? b_short.inf : (i == 1 ? b_long.inf : b_sep.inf)), + (i == 0 ? b_short.mid : (i == 1 ? b_long.mid : b_sep.mid)), + (i == 0 ? b_short.sup : (i == 1 ? b_long.sup : b_sep.sup)), + (i == 2 ? "" : ",") + ); + } +} +#endif + +byte Rail::get_band_count() const { + return b_short.mid == b_long.mid ? (b_short.mid ? 1 : 0) : 2; +} + + +// * **** ********************************************************************* +// * Misc ********************************************************************* +// * **** ********************************************************************* + +#ifdef RF433ANY_DBG_RAWCODE +const char *sts_names[] = { + "CONT", + "XSEP", + "SSEP", + "LSEP", + "2SEP", + "ERR" +}; + +void RawCode::debug_rawcode() const { + dbgf("> nb_sections = %d, initseq = %u", + nb_sections, initseq); + for (byte i = 0; i < nb_sections; ++i) { + const Section *psec = §ions[i]; + dbgf(" %02d %s", i, sts_names[psec->sts]); + dbgf(" sep = %u", psec->ts.sep); + dbgf(" low: [%d] n = %2d, v = 0x" FMTRECORDEDT "", + psec->low_bands, psec->low_bits, psec->low_rec); + dbgf(" high: [%d] n = %2d, v = 0x" FMTRECORDEDT "", + psec->high_bands, psec->high_bits, psec->high_rec); + } +} +#endif + + +// * ********* **************************************************************** +// * BitVector **************************************************************** +// * ********* **************************************************************** + +BitVector::BitVector(): + array(nullptr), + allocated(0), + nb_bits(0) { + +} + +BitVector::~BitVector() { + if (array) + free(array); +} + +void BitVector::add_bit(byte v) { + if (!allocated) + array = (uint8_t*)malloc(1); + if (nb_bits >= (allocated << 3)) { + byte old_allocated = allocated; + + ++allocated; // Could be another formula ('<<= 1', ...) + + array = (uint8_t*)realloc(array, allocated); + for (byte i = old_allocated; i < allocated; ++i) + array[i] = 0; + } + + ++nb_bits; + for (short i = allocated - 1; i >= 0; --i) { + + byte b; + if (i > 0) { + b = !!(array[i - 1] & 0x80); + } else { + // Defensive programming: + // Normally v is 0 or 1, but I normalize it, just in case. + b = !!v; + } + + array[i]= (array[i] << 1) | b; + + } +} + +int BitVector::get_nb_bits() const { + return nb_bits; +} + +byte BitVector::get_nb_bytes() const { + return (nb_bits + 7) >> 3; +} + + // Bit numbering starts at 0 +byte BitVector::get_nth_bit(byte n) const { + assert(n >= 0 && n < nb_bits); + byte index = (n >> 3); + byte bitread = (1 << (n & 0x07)); + return !!(array[index] & bitread); +} + + // Bit numbering starts at 0 +byte BitVector::get_nth_byte(byte n) const { + assert(n >= 0 && n < get_nb_bytes()); + return array[n]; +} + + // *IMPORTANT* + // If no data got received, returns nullptr. So, you must test the + // returned value. + // + // *IMPORTANT (2)* + // The return value is malloc'd so caller must think of freeing it. + // For example: + // char *s = data_to_str_with_malloc(data); + // ... + // if (s) // DON'T FORGET (s can be null) + // free(s); // DON'T FORGET! (if non-null, s must be freed) +char* BitVector::to_str() const { + if (!get_nb_bits()) + return nullptr; + + byte nb_bytes = get_nb_bytes(); + + char *ret = (char*)malloc(nb_bytes * 3); + char tmp[3]; + int j = 0; + for (int i = nb_bytes - 1; i >= 0 ; --i) { + snprintf(tmp, sizeof(tmp), "%02x", get_nth_byte(i)); + ret[j] = tmp[0]; + ret[j + 1] = tmp[1]; + ret[j + 2] = (i > 0 ? ' ' : '\0'); + j += 3; + } + assert(j <= nb_bytes * 3); + + return ret; +} + +short BitVector::cmp(const BitVector *p) const { + assert(p); + short cmp_nb_bits = (get_nb_bits() > p->get_nb_bits()); + if (!cmp_nb_bits) + cmp_nb_bits = -(get_nb_bits() < p->get_nb_bits()); + + if (cmp_nb_bits) + return cmp_nb_bits; + + for (int i = get_nb_bits() - 1; i >= 0; --i) { + byte v1 = get_nth_bit(i); + byte v2 = p->get_nth_bit(i); + if (v1 > v2) + return 1; + if (v1 < v2) + return -1; + } + + return 0; +} + + +// * ******* ****************************************************************** +// * Decoder ****************************************************************** +// * ******* ****************************************************************** + +#ifdef RF433ANY_DBG_DECODER +const char *dec_id_names[] = { + "INC", + "SYN", + "TRI", + "TRN", + "MAN", + "UNK" +}; +#endif + +Decoder::Decoder(byte arg_convention): + next(nullptr), + pdata(new BitVector()), + convention(arg_convention), + nb_errors(0) { + tsext.initseq = 0; + tsext.first_low = 0; + tsext.first_high = 0; + tsext.first_low_ignored = 0; + tsext.last_low = 0; +} + +Decoder::~Decoder() { + if (pdata) + delete pdata; + if (next) + delete next; +} + +Decoder* Decoder::build_decoder(byte id, byte convention) { + switch (id) { + case DEC_ID_RAW_SYNC: + return new DecoderRawSync(0); + case DEC_ID_TRIBIT: + return new DecoderTriBit(convention); + case DEC_ID_TRIBIT_INV: + return new DecoderTriBitInv(convention); + case DEC_ID_MANCHESTER: + return new DecoderManchester(convention); + case DEC_ID_RAW_UNKNOWN_CODING: + return new DecoderRawUnknownCoding(); + default: + assert(false); + } + return nullptr; // Never executed +} + +void Decoder::attach(Decoder *pdec) { + assert(!next); + next = pdec; +} + +void Decoder::detach() { + next = nullptr; +} + +void Decoder::add_data_bit(byte valbit) { + pdata->add_bit(valbit); +} + +byte Decoder::get_nb_errors() const { return nb_errors; } + +int Decoder::get_nb_bits() const { return pdata ? pdata->get_nb_bits() : 0; } + +void Decoder::set_ts(const uint16_t& arg_initseq, const Timings& ts) { + tsext.initseq = arg_initseq; + tsext.low_short = ts.low_short; + tsext.low_long = ts.low_long; + tsext.high_short = ts.high_short; + tsext.high_long = ts.high_long; + tsext.sep = ts.sep; +} + +void Decoder::get_tsext(TimingsExt *p_tsext) const { + *p_tsext = tsext; + p_tsext->first_low_ignored = first_lo_ignored(); +} + +void Decoder::take_into_account_first_low_high(const Section *psec, + bool is_cont_of_prev_sec) { + if (is_cont_of_prev_sec) + return; + tsext.first_low = psec->first_low; + tsext.first_high = psec->first_high; + tsext.last_low = psec->last_low; + + Signal e[2]; + for (short i = 0; i < 2; ++i) { + uint16_t d = (i == 0 ? tsext.first_low : tsext.first_high); + uint16_t short_d = (i == 0 ? psec->ts.low_short : psec->ts.high_short); + uint16_t long_d = (i == 0 ? psec->ts.low_long : psec->ts.high_long); + Band b_short; + Band b_long; + b_short.init(short_d); + b_long.init(long_d); + +// b_short.sup = (b_short.mid + b_long.mid) >> 1; +// b_long.inf = b_short.sup + 1; + + bool is_short = b_short.test_value(d); + bool is_long = b_long.test_value(d); + + if (is_short && !is_long) { + e[i] = Signal::SHORT; + } else if (!is_short && is_long) { + e[i] = Signal::LONG; + } else if (is_short && is_long && short_d == long_d) { + e[i] = Signal::SHORT; + } else { + e[i] = Signal::OTHER; + } + } + + if (e[0] != Signal::OTHER && e[1] != Signal::OTHER) { + add_signal_step(e[0], e[1]); + tsext.first_low = 0; + tsext.first_high = 0; + } +} + +void Decoder::decode_section(const Section *psec, bool is_cont_of_prev_sec) { + take_into_account_first_low_high(psec, is_cont_of_prev_sec); + + byte pos_low = psec->low_bits; + byte pos_high = psec->high_bits; + + while (pos_low >= 1 || pos_high >= 1) { + Signal sd_low = Signal::OTHER; + Signal sd_high = Signal::OTHER; + if (pos_low >= 1) { + --pos_low; + sd_low = ((((recorded_t)1 << pos_low) & psec->low_rec) ? + Signal::LONG : Signal::SHORT); + } + if (pos_high >= 1) { + --pos_high; + sd_high = + ((((recorded_t)1 << pos_high) & psec->high_rec) ? + Signal::LONG : Signal::SHORT); + } + add_signal_step(sd_low, sd_high); + } +} + +uint16_t Decoder::first_lo_ignored() const { + return 0; +} + +const BitVector* Decoder::get_pdata() const { + return pdata; +} + +BitVector* Decoder::take_away_data() { + if (pdata) { + BitVector *ret = pdata; + pdata = nullptr; + return ret; + } else + return nullptr; +} + +#ifdef RF433ANY_DBG_DECODER +void Decoder::dbg_data(byte seq) const { + char *buf = pdata->to_str(); + if (buf) { + dbgf("[%d] Received %d bits%s: %s", seq, get_nb_bits(), + (get_nb_errors() ? "(!)" : ""), buf); + free(buf); + } else { + dbgf("[%d] No data received, type = %s", seq, dec_id_names[get_id()]); + } +} + +void Decoder::dbg_meta(byte disp_level) const { + if (disp_level <= 1) + return; + if (!tsext.first_low && !tsext.first_high) { + if (!tsext.high_short && !tsext.high_long) { + dbgf(" T=%s, E=%u, I=%u, S=%u, L=%u, P=%u, Y=%u, Z=%u", + dec_id_names[get_id()], nb_errors, tsext.initseq, + tsext.low_short, tsext.low_long, tsext.sep, + first_lo_ignored(), tsext.last_low); + } else { + dbgf(" T=%s, E=%u, I=%u, S(lo)=%u, L(lo)=%u, " + "S(hi)=%u, L(hi)=%u, P=%u, Y=%u, Z=%u", + dec_id_names[get_id()], nb_errors, tsext.initseq, + tsext.low_short, tsext.low_long, tsext.high_short, + tsext.high_long, tsext.sep, first_lo_ignored(), + tsext.last_low); + } + } else { + if (!tsext.high_short && !tsext.high_long) { + dbgf(" T=%s, E=%u, I=%u, S=%u, L=%u, P=%u, U=%u, " + "V=%u, Y=%u, Z=%u", + dec_id_names[get_id()], nb_errors, tsext.initseq, + tsext.low_short, tsext.low_long, tsext.sep, tsext.first_low, + tsext.first_high, first_lo_ignored(), tsext.last_low); + } else { + dbgf(" T=%s, E=%u, I=%u, S(lo)=%u, L(lo)=%u, " + "S(hi)=%u, L(hi)=%u, P=%u, U=%u, V=%u, Y=%u, Z=%u", + dec_id_names[get_id()], nb_errors, tsext.initseq, + tsext.low_short, tsext.low_long, tsext.high_short, + tsext.high_long, tsext.sep, tsext.first_low, + tsext.first_high, first_lo_ignored(), tsext.last_low); + } + } +} + +void Decoder::dbg_next(byte disp_level, byte seq) const { + if (next) + next->dbg_decoder(disp_level, seq + 1); +} + +#endif + + +// * ********************** *************************************************** +// * DecoderRawInconsistent *************************************************** +// * ********************** *************************************************** + +#ifdef RF433ANY_DBG_DECODER +void DecoderRawInconsistent::dbg_decoder(byte disp_level, byte seq) const { + dbgf("[%d] Inconsistent signal", seq); + dbg_meta(disp_level); + dbg_next(disp_level, seq); +} +#endif + + +// * ************** *********************************************************** +// * DecoderRawSync *********************************************************** +// * ************** *********************************************************** + +void DecoderRawSync::add_signal_step(Signal lo, Signal hi) { + if (!sync_shape_set) { + sync_shape = lo; + sync_shape_set = true; + } + + if (lo != sync_shape) { + ++nb_errors; + } else if (hi == Signal::OTHER) { + } else if (lo != hi) { + ++nb_errors; + } else { + ++nb_low_high; + } +} + +void DecoderRawSync::add_sync(byte n) { + nb_low_high += n; +} + +int DecoderRawSync::get_nb_bits() const { return nb_low_high; } + +#ifdef RF433ANY_DBG_DECODER +void DecoderRawSync::dbg_decoder(byte disp_level, byte seq) const { + dbgf("[%d] Sync %d", seq, nb_low_high); + dbg_meta(disp_level); + dbg_next(disp_level, seq); +} +#endif + + +// * *********************** ************************************************** +// * DecoderRawUnknownCoding ************************************************** +// * *********************** ************************************************** + +void DecoderRawUnknownCoding::add_signal_step(Signal lo, Signal hi) { + if (hi == Signal::OTHER) { + unused_final_low = lo; + terminates_with_sep = true; + return; + } + + for (short i = 0; i < 2; ++i) { + Signal x = (i ? hi : lo); + add_data_bit(x == Signal::SHORT ? 0 : 1); + } +} + +#ifdef RF433ANY_DBG_DECODER +void DecoderRawUnknownCoding::dbg_decoder(byte disp_level, byte seq) const { + dbgf("[%d] Unknown encoding: %d signal bits", seq, pdata->get_nb_bits()); + + if (disp_level <= 1) + return; + + int n = pdata->get_nb_bits(); + assert(!(n & 1)); + + int sz = ((int)n * 3) / 2 + 4; + char *buf = new char[sz]; + int p = 0; + for (int i = n - 1; i >= 1; i -= 2) { + byte vlo = pdata->get_nth_bit(i); + byte vhi = pdata->get_nth_bit(i - 1); + buf[p] = (vlo ? 'L' : 'S'); + buf[p + 1] = (vhi ? 'L' : 'S'); + buf[p + 2] = ':'; + p += 3; + } + assert(p + 2 < sz); + if (terminates_with_sep) { + if (unused_final_low == Signal::SHORT) + buf[p] = 'S'; + else + buf[p] = 'L'; + buf[p + 1] = 'P'; + buf[p + 2] = '\0'; + } else { + if (!p) + buf[p] = '\0'; + else + buf[p - 1] = '\0'; + } + Serial.print(" Signal: "); + Serial.print(buf); + Serial.print("\n"); + delete buf; + + dbg_meta(disp_level); + dbg_next(disp_level, seq); +} +#endif + + +// * ************* ************************************************************ +// * DecoderTriBit ************************************************************ +// * ************* ************************************************************ + +void DecoderTriBit::add_signal_step(Signal lo, Signal hi) { + if (hi == Signal::OTHER) + return; + + byte valbit; + if (lo == Signal::SHORT && hi == Signal::LONG) + valbit = convention; + else if (lo == Signal::LONG && hi == Signal::SHORT) + valbit = !convention; + else { + ++nb_errors; + return; + } + + add_data_bit(valbit); +} + +#ifdef RF433ANY_DBG_DECODER +void DecoderTriBit::dbg_decoder(byte disp_level, byte seq) const { + dbg_data(seq); + dbg_meta(disp_level); + dbg_next(disp_level, seq); +} +#endif + + +// * **************** ********************************************************* +// * DecoderTriBitInv ********************************************************* +// * **************** ********************************************************* + +void DecoderTriBitInv::add_signal_step(Signal lo, Signal hi) { + if (first_call_to_add_sgn_lo_hi) { + first_call_to_add_sgn_lo_hi = false; + unused_initial_low = lo; + last_hi = hi; + return; + } + + bool add_it = true; + byte valbit; + if (lo == Signal::SHORT && last_hi == Signal::LONG) + valbit = !convention; + else if (lo == Signal::LONG && last_hi == Signal::SHORT) + valbit = convention; + else { + ++nb_errors; + add_it = false; + } + + if (add_it) + add_data_bit(valbit); + + last_hi = hi; +} + +uint16_t DecoderTriBitInv::first_lo_ignored() const { + switch (unused_initial_low) { + case Signal::OTHER: + return 0; + case Signal::SHORT: + return tsext.low_short; + case Signal::LONG: + return tsext.low_long; + default: + assert(false); + }; + return 0; // Never executed +} + +#ifdef RF433ANY_DBG_DECODER +void DecoderTriBitInv::dbg_decoder(byte disp_level, byte seq) const { + dbg_data(seq); + dbg_meta(disp_level); + dbg_next(disp_level, seq); +} +#endif + + +// * ***************** ******************************************************** +// * DecoderManchester ******************************************************** +// * ***************** ******************************************************** + +DecoderManchester::DecoderManchester(byte arg_convention) + :Decoder(arg_convention), + buf_pos(0), + leading_lo_hi_has_been_passed(false) { + for (byte i = 0; i < sizeof(buf) / sizeof(*buf); ++i) { + buf[i] = 0; + } +} + +inline void DecoderManchester::add_buf(byte r) { + assert(buf_pos < sizeof(buf) /sizeof(*buf)); + buf[buf_pos++] = r; +} + +void DecoderManchester::consume_buf() { + if (buf_pos >= 2) { + if (leading_lo_hi_has_been_passed) { + if (buf[0] == 0 && buf[1] == 1) { + add_data_bit(convention); + } else if (buf[0] == 1 && buf[1] == 0) { + add_data_bit(!convention); + } else { + // FIXME: créer register_error pour gérer ça de manière + // cohérente entre les différents descendants de Decoder. + ++nb_errors; + } + } else { + if (buf[0] != 0 || buf[1] != 1) { + ++nb_errors; + } + leading_lo_hi_has_been_passed = true; + } + // Not always necessary, but harmless if done while not necessary + buf[0] = buf[2]; + buf_pos -= 2; + } +} + +void DecoderManchester::add_signal_step(Signal lo, Signal hi) { + if (lo == Signal::OTHER) { + ++nb_errors; + return; + } + + for (byte i = 0; i < 2; ++i) { + Signal sgn = (i == 0 ? lo : hi); + add_buf(i); + if (sgn == Signal::LONG) + add_buf(i); + consume_buf(); + } +} + +#ifdef RF433ANY_DBG_DECODER +void DecoderManchester::dbg_decoder(byte disp_level, byte seq) const { + dbg_data(seq); + dbg_meta(disp_level); + dbg_next(disp_level, seq); +} +#endif + + +// * ***** ******************************************************************** +// * Track ******************************************************************** +// * ***** ******************************************************************** + +#ifdef RF433ANY_DBG_SIMULATE +SerialLine sl; +char buffer[SERIAL_LINE_BUF_LEN]; + +uint16_t sim_timings[SIM_TIMINGS_LEN]; + +uint16_t sim_timings_count = 0; + +unsigned int sim_int_count = 0; +unsigned int sim_int_count_svg; +unsigned int counter; +#endif + +#ifdef DBG_TIMINGS +uint16_t Track::ih_dbg_timings[40]; +uint16_t Track::ih_dbg_exec[40]; +unsigned int Track::ih_dbg_pos = 0; +#endif +volatile IH_timing_t Track::IH_timings[IH_SIZE]; +volatile unsigned char Track::IH_write_head = 0; +volatile unsigned char Track::IH_read_head = 0; +byte Track::IH_max_pending_timings = 0; +bool Track::IH_interrupt_handler_is_attached = false; + + // Set when Track object is created +byte Track::pin_number = 99; + +Track::Track(int arg_pin_number, byte mood): + r_low(mood), + r_high(mood) { + pin_number = arg_pin_number; + treset(); +} + +void Track::treset() { + trk = TRK_WAIT; + rawcode.nb_sections = 0; +} + +void Track::ih_handle_interrupt() { + static unsigned long last_t = 0; + const unsigned long t = micros(); + +#ifdef RF433ANY_DBG_SIMULATE + unsigned long d; + byte r = sim_int_count % 2; + if (sim_int_count >= sim_timings_count) { + d = 100; + sim_int_count = sim_timings_count + 1; + } else { + d = sim_timings[sim_int_count++]; + } + (void)last_t; + (void)t; +#else + unsigned long d = t - last_t; + last_t = t; + byte r = (digitalRead(pin_number) == HIGH ? 1 : 0); +#endif + + if (d > MAX_DURATION) + d = MAX_DURATION; + + unsigned char next_IH_write_head = (IH_write_head + 1) & IH_MASK; + // No ideal solution here: we reached the buffer size, so either we + // write nothing, or, we loose the oldest entry that was the next one to + // read. + // Solution here: we loose oldest entry in buffer and do the write. + if (next_IH_write_head == IH_read_head) { + IH_read_head = (IH_read_head + 1) & IH_MASK; + } + IH_write_head = next_IH_write_head; + IH_timings[IH_write_head].r = r; + IH_timings[IH_write_head].d = d; +} + +void Track::force_stop_recv() { +#ifdef DBG_TRACE + dbg("T> running force_stop_recv()"); +#endif + if (get_trk() == TRK_RECV) { + track_eat(0, 0); + track_eat(1, 0); + do_events(); + } +} + +void Track::reset_border_mgmt() { + count = 0; + first_low = 0; + first_high = 0; + last_low = 0; +} + +inline void Track::track_eat(byte r, uint16_t d) { + +#ifdef DBG_TRACE + dbgf("T> trk = %d, r = %d, d = %u", trk, r, d); +#endif + + if (trk == TRK_WAIT) { + if (r == 1 && d >= TRACK_MIN_INITSEQ_DURATION) { + r_low.rreset(); + r_high.rreset(); + prev_r = r; + rawcode.initseq = d; + rawcode.max_code_d = d - (d >> 2); + reset_border_mgmt(); + trk = TRK_RECV; + } + return; + } else if (trk != TRK_RECV) { + return; + } + + bool enforce_b_to_false = false; + // [COMMENT002] + // We missed an interrupt apparently (two calls with same r), so we + // had better discard the actual signal. + if (r == prev_r) { + enforce_b_to_false = true; + } + prev_r = r; + + ++count; +#ifdef DBG_TRACE + dbgf("T> count = %d", count); +#endif + + if (count == 1) { + if ((d < BAND_MIN_D || d >= rawcode.max_code_d) + && count < TRACK_MIN_BITS && !rawcode.nb_sections) { +#ifdef DBG_TRACE + dbg("T> case 1"); +#endif + treset(); + // WARNING + // Re-entrant call... not ideal. + track_eat(r, d); + } else { +#ifdef DBG_TRACE + dbg("T> case 2"); +#endif + first_low = d; + } + return; + } else if (count == 2) { + if ((d < BAND_MIN_D || d >= rawcode.max_code_d) + && count < TRACK_MIN_BITS && !rawcode.nb_sections) { +#ifdef DBG_TRACE + dbg("T> case 3"); +#endif + treset(); + // WARNING + // Re-entrant call... not ideal. + track_eat(r, d); + } else { +#ifdef DBG_TRACE + dbg("T> case 4"); +#endif + first_high = d; + } + return; + } +#ifdef DBG_TRACE + dbg("T> case 5"); +#endif + + Rail *prail = (r == 0 ? &r_low : &r_high); + if (prail->status != RAIL_OPEN) + return; + + if (r == 0) + last_low = d; + + bool b; + if ((d < BAND_MIN_D || d >= rawcode.max_code_d) + && count < TRACK_MIN_BITS) { + enforce_b_to_false = true; + } else if (abs(r_low.index - r_high.index) >= 2) { + enforce_b_to_false = true; + } else if (!enforce_b_to_false) { + b = prail->rail_eat(d); + } + + if (enforce_b_to_false) { + r = 1; + b = false; + } + + if (r == 1 && (!b || r_low.status != RAIL_OPEN)) { + +#ifdef DBG_TRACE + dbgf("T> b = %d", b); +#endif + + if (r_low.status == RAIL_OPEN) + r_low.status = RAIL_CLOSED; + if (r_high.status == RAIL_OPEN) + r_high.status = RAIL_CLOSED; + + section_term_status_t sts; + if (r_low.status == RAIL_FULL && r_high.status == RAIL_FULL) { + sts = STS_CONTINUED; + } else if (r_high.status == RAIL_STP_RCVD) { + if (r_low.status == RAIL_CLOSED || r_low.status == RAIL_FULL + || r_low.status == RAIL_ERROR) { // FIXME (RAIL_ERROR) + sts = (r_low.last_bit_recorded ? STS_LONG_SEP : STS_SHORT_SEP); + } else if (r_low.status == RAIL_STP_RCVD) { + sts = STS_SEP_SEP; // FIXME (Need STS_X_SEP) + } else { + sts = STS_ERROR; + } + } else { + sts = STS_ERROR; + } + +/* +Tests implemented below reproduce the following decision table + +Notations: + "pr=cont": the previous track terminated as STS_CONTINUED + "pr!=cont": the previous track didn't terminate as STS_CONTINUED + "nbsec": nb_sections + "cur": how did current track end? -> + "sep": it ended with a separator + "err": it ended with an error + "full": it didn't end but record is full + CUR?: shall we record the current track? + NEXT?: what to do next? (reset track, start new section) + + FIXME? + When a section (that is not the first) ends in error, the current section + is discarded _but_ previous sections are kept and shown to the caller + (enter 'DATA' state). + This is questionnable because, why keeping previous section? + Also it leads to different results depending on recorded_t size, that is an + internal, intermediate artefact, the nature of which shall not change + result as seen by caller. + I leave this behavior though, as a tradeoff between strictness and lax. + In a possible, future improvement, I might change this behavior, and + discard previous sections would an error be encountered. + + +---------------+-------- +----------+-------++-------+--------------+ + |nb_bits | nbsec | prev | cur || CUR? | NEXT? | + +---------------+-------- +----------+-------++-------+--------------+ + |bits0 | pr=cont | sep || REC | NEWSEC | + | | | | err || DISC | DATA | + | | | | full || n/a | n/a | + | | nbsec>0 | pr!=cont | sep || DISC | DATA | + | | | | err || DISC | DATA | + | | | | full || n/a | n/a | + |bits>=min_bits | !nbsec | n/a | sep || REC | NEWSEC | + | | | | err || DISC | RESET | + | | | | ful || REC | NEWSEC(CONT) | + | | nbsec>0 | pr=cont | sep || REC | NEWSEC | + | | | | err || DISC | DATA | + | | | | ful || REC | NEWSEC(CONT) | + | | nbsec>0 | pr!=cont | sep || REC | NEWSEC | + | | | | err || DISC | DATA | + | | | | ful || REC | NEWSEC(CONT) | + +---------------+-------- +----------+-------++-------+--------------+ +*/ + + bool record_current_section; + +#ifdef RF433ANY_DBG_TRACK + bool do_track_debug = false; + (void)do_track_debug; +#endif + + if (r_low.index < TRACK_MIN_BITS || r_high.index < TRACK_MIN_BITS) { + record_current_section = + (sts != STS_ERROR + && rawcode.nb_sections + && rawcode.sections[rawcode.nb_sections - 1].sts + == STS_CONTINUED); + +#ifdef RF433ANY_DBG_TRACK + do_track_debug = record_current_section; +#endif + + } else { + record_current_section = (sts != STS_ERROR); + +#ifdef RF433ANY_DBG_TRACK + do_track_debug = true; +#endif + + } + +#ifdef DBG_TRACE + dbgf("T> reccursec=%i, sts=%i", record_current_section, sts); +#endif +#if defined(RF433ANY_DBG_SIMULATE) && defined(RF433ANY_DBG_TRACK) + if (do_track_debug) { + dbgf("%s {", counter >= 2 ? ",\n" : ""); + dbgf(" \"N\":%d,\"start\":%u,\"end\":%u,", + sim_timings_count, sim_int_count_svg, sim_int_count - 1); + track_debug(); + dbg(" }"); + } +#endif + + if (record_current_section) { +#ifdef DBG_TRACE + dbg("T> recording current section"); +#endif + Section *psec = &rawcode.sections[rawcode.nb_sections++]; + psec->sts = sts; + + psec->ts.sep = (sts == STS_SHORT_SEP + || sts == STS_LONG_SEP + || sts == STS_SEP_SEP ? d : 0); + if (r_low.b_short.test_value(r_high.b_short.mid) + && !r_low.b_short.test_value(r_high.b_long.mid) + && !r_low.b_long.test_value(r_high.b_short.mid) + && r_low.b_long.test_value(r_high.b_long.mid)) { + psec->ts.low_short = (r_low.b_short.mid + r_high.b_short.mid) + >> 1; + psec->ts.low_long = (r_low.b_long.mid + r_high.b_long.mid) + >> 1; + psec->ts.high_short = 0; + psec->ts.high_long = 0; + } else { + psec->ts.low_short = r_low.b_short.mid; + psec->ts.low_long = r_low.b_long.mid; + psec->ts.high_short = r_high.b_short.mid; + psec->ts.high_long = r_high.b_long.mid; + } + + psec->low_rec = r_low.rec; + psec->low_bits = r_low.index; + psec->low_bands = r_low.get_band_count(); + psec->high_rec = r_high.rec; + psec->high_bits = r_high.index; + psec->high_bands = r_high.get_band_count(); + + psec->first_low = first_low; + psec->first_high = first_high; + psec->last_low = last_low; + + trk = ((rawcode.nb_sections == RF433ANY_MAX_SECTIONS) + ? TRK_DATA : TRK_RECV); + +#ifdef DBG_TRACE + dbgf("T> rawcode.nb_sections = %d", rawcode.nb_sections); +#endif + + if (trk == TRK_RECV) { +#ifdef DBG_TRACE + dbg("T> keep receiving (soft reset)"); +#endif + r_low.rreset_soft(); + r_high.rreset_soft(); + if (sts != STS_CONTINUED) { + reset_border_mgmt(); + } + } else { +#ifdef DBG_TRACE + dbg("T> stop receiving (data)"); +#endif + } + } else { + if (rawcode.nb_sections) { + trk = TRK_DATA; + } else { + treset(); + // WARNING + // Re-entrant call... not ideal. + track_eat(r, d); + } + } + + } +} + + // Returns true if a timing got processed, false otherwise. + // Do nothing (and returns false) if Track is in the status TRK_DATA. + // NOTE + // When Track is in the TRK_DATA state, no erase can happen + // (track_eat() will exit immediately). + // Therefore the safeguard of explicitly doing nothing if in the status + // TRK_DATA is redundant => it is defensive programming. +bool Track::process_interrupt_timing() { + if (get_trk() == TRK_DATA) + return false; + + unsigned char IH_pending_timings = + (IH_write_head - IH_read_head) & IH_MASK; + if (IH_pending_timings > IH_max_pending_timings) + IH_max_pending_timings = IH_pending_timings; + + bool ret; + + cli(); + if (IH_read_head != IH_write_head) { + IH_timing_t timing = IH_timings[IH_read_head]; + IH_read_head = (IH_read_head + 1) & IH_MASK; + + sei(); +#ifdef DBG_TIMINGS + unsigned long t0 = micros(); +#endif + track_eat(timing.r, timing.d); +#ifdef DBG_TIMINGS + unsigned long d = micros() - t0; + if (d > MAX_DURATION) + d = MAX_DURATION; + ih_dbg_exec[ih_dbg_pos] = d; + if (get_trk() == TRK_WAIT) + ih_dbg_pos = 0; + else { + if (ih_dbg_pos < sizeof(ih_dbg_timings) / sizeof(*ih_dbg_timings)) + ih_dbg_timings[ih_dbg_pos++] = timing.d; + } +#endif + + ret = true; + + } else { + + sei(); + ret = false; + } + + return ret; +} + +void Track::activate_recording() { +#ifndef RF433ANY_DBG_SIMULATE + if (!IH_interrupt_handler_is_attached) { + attachInterrupt(digitalPinToInterrupt(pin_number), &ih_handle_interrupt, + CHANGE); + IH_interrupt_handler_is_attached = true; + } +#endif +} + +void Track::deactivate_recording() { +#ifndef RF433ANY_DBG_SIMULATE + if (IH_interrupt_handler_is_attached) { + detachInterrupt(digitalPinToInterrupt(pin_number)); + IH_interrupt_handler_is_attached = false; + } +#endif +} + +bool Track::do_events() { + activate_recording(); + while (process_interrupt_timing()) + ; + if (get_trk() == TRK_DATA) { + deactivate_recording(); +#ifdef RF433ANY_DBG_RAWCODE + dbgf("IH_max_pending_timings = %d", ih_get_max_pending_timings()); + rawcode.debug_rawcode(); +#endif + return true; + } + return false; +} + +Decoder* Track::get_data_core(byte convention) { + Decoder *pdec_head = nullptr; + Decoder *pdec_tail = nullptr; + Decoder *pdec = nullptr; + + for (byte i = 0; i < rawcode.nb_sections; ++i) { + + const Section *psec = &rawcode.sections[i]; + + if (abs(psec->low_bits - psec->high_bits) >= 2) { + // Defensive programming (should never happen). + if (!pdec) { + pdec = new DecoderRawInconsistent(); + } + + } else if (psec->low_bands == 1 && psec->high_bands == 1) { + byte n = (psec->low_bits < psec->high_bits ? + psec->low_bits : psec->high_bits); + if (pdec) { + pdec->add_sync(n); + } else { + pdec = new DecoderRawSync(n); + pdec->take_into_account_first_low_high(psec, false); + } + + } else if (psec->low_bands == 1 || psec->high_bands == 1) { + if (!pdec) { + pdec = new DecoderRawInconsistent(); + } + + } else { + byte enum_decoders = DEC_ID_START; + bool is_continuation_of_prev_section = pdec; + do { + if (!pdec) + pdec = Decoder::build_decoder(enum_decoders, convention); + + pdec->decode_section(psec, is_continuation_of_prev_section); + + if (!is_continuation_of_prev_section && pdec->get_nb_errors()) { + delete pdec; + pdec = nullptr; + } + } while (!pdec && ++enum_decoders <= DEC_ID_END); + + } + // The last enumerated decoder is DecoderRawUnknownCoding, that + // never produces any error and MUST be chosen in the end (if no + // other worked). + assert(pdec); + + pdec->set_ts((pdec_head ? 0 : rawcode.initseq), psec->ts); + + if (psec->sts != STS_CONTINUED || i == rawcode.nb_sections - 1) { + if (!pdec_head) { + assert(!pdec_tail); + pdec_head = pdec; + pdec_tail = pdec; + } else { + assert(pdec_tail); + pdec_tail->attach(pdec); + pdec_tail = pdec; + } + pdec = nullptr; + } + } + + return pdec_head; +} + +Decoder* Track::get_data(uint16_t filter, byte convention) { + Decoder *pdec0 = get_data_core(convention); + Decoder *prev_pdec = pdec0; + Decoder *pdec = pdec0; + + while (pdec) { + pdec->reset_repeats(); + + bool keep = true; + + if (filter & RF433ANY_FD_DECODED) { + if (!pdec->data_got_decoded()) + keep = false; + } + + if (filter & RF433ANY_FD_NO_ERROR) { + if (pdec->get_nb_errors()) + keep = false; + } + + if (filter & RF433ANY_FD_DEDUP) { + if (pdec != prev_pdec && pdec->get_id() == prev_pdec->get_id()) { + const BitVector *p1; + const BitVector *p2; + if ((p1 = pdec->get_pdata()) && (p2 = prev_pdec->get_pdata())) { + if (!p1->cmp(p2)) { + keep = false; + prev_pdec->inc_repeats(); + } + } + } + } + + if (filter & (RF433ANY_FD_TRI | RF433ANY_FD_TRN | RF433ANY_FD_MAN)) { + if (!(filter & RF433ANY_FD_TRI) + && pdec->get_id() == DEC_ID_TRIBIT) + keep = false; + if (!(filter & RF433ANY_FD_TRN) + && pdec->get_id() == DEC_ID_TRIBIT_INV) + keep = false; + if (!(filter & RF433ANY_FD_MAN) + && pdec->get_id() == DEC_ID_MANCHESTER) + keep = false; + } + + if (keep) { + prev_pdec = pdec; + pdec = pdec->get_next(); + } else { + Decoder *pdec_to_remove = pdec; + if (pdec == pdec0) { + assert(pdec0 == prev_pdec); + pdec0 = pdec->get_next(); + prev_pdec = pdec0; + pdec = pdec0; + } else { + pdec = pdec->get_next(); + prev_pdec->detach(); + prev_pdec->attach(pdec); + } + pdec_to_remove->detach(); + delete pdec_to_remove; + } + } + + return pdec0; +} + +#ifdef DBG_TIMINGS +void Track::dbg_timings() const { + for (unsigned int i = 0; i + 1 < ih_dbg_pos; i += 2) { + dbgf("%4u, %4u | %5u, %5u", ih_dbg_timings[i], ih_dbg_timings[i + 1], + ih_dbg_exec[i], ih_dbg_exec[i + 1]); + } +} +#endif + +#ifdef RF433ANY_DBG_TRACK +const char* trk_names[] = { + "TRK_WAIT", + "TRK_RECV", + "TRK_DATA" +}; +void Track::track_debug() const { + recorded_t xorval = r_low.rec ^ r_high.rec; + dbgf(" \"trk\":%s,\"xorval\":0x" FMTRECORDEDT ",", + trk_names[trk], xorval); + if (trk != TRK_WAIT) { + for (byte i = 0; i < 2; ++i) { + dbgf(" \"%s\":{", (i == 0 ? "r_low" : "r_high")); + (i == 0 ? &r_low : &r_high)->rail_debug(); + dbgf(" }%s", i == 1 ? "" : ","); + } + } + +} +#endif + +// vim: ts=4:sw=4:tw=80:et diff --git a/RF433any.h b/RF433any.h new file mode 100644 index 0000000..6e48ac2 --- /dev/null +++ b/RF433any.h @@ -0,0 +1,660 @@ +// RF433any.h + +/* + Copyright 2021 Sébastien Millet + + `RF433any' is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + `RF433any' is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + . +*/ + +#ifndef _RF433ANY_H +#define _RF433ANY_H + +// **************************************************************************** +// RF433ANY_TESTPLAN ********************************************************** +#if RF433ANY_TESTPLAN == 1 + +#define RF433ANY_DBG_SIMULATE +#define RF433ANY_DBG_TRACK + +#elif RF433ANY_TESTPLAN == 2 // RF433ANY_TESTPLAN + +#define RF433ANY_DBG_SIMULATE +#define RF433ANY_DBG_RAWCODE + +#elif RF433ANY_TESTPLAN == 3 // RF433ANY_TESTPLAN + +#define RF433ANY_DBG_SIMULATE +#define RF433ANY_DBG_DECODER + +#elif RF433ANY_TESTPLAN == 4 // RF433ANY_TESTPLAN + +#define RF433ANY_DBG_SIMULATE +#define RF433ANY_DBG_DECODER +#define RF433ANY_DBG_SMALL_RECORDED +#define RF433ANY_MAX_SECTIONS 12 + +#elif RF433ANY_TESTPLAN == 5 // RF433ANY_TESTPLAN + +#define RF433ANY_DBG_SIMULATE +#define RF433ANY_DBG_SMALL_RECORDED + +#else // RF433ANY_TESTPLAN + +#ifdef RF433ANY_TESTPLAN +#error "RF433ANY_TESTPLAN macro has an illegal value." +#endif +// RF433ANY_TESTPLAN ********************************************************** +// **************************************************************************** + + +// It is OK to update the below, because if this code is compiled, then we are +// not in the test plan. + +//#define RF433ANY_DBG_SIMULATE +//#define DBG_TRACE +//#define DBG_TIMINGS +//#define RF433ANY_DBG_TRACK +//#define RF433ANY_DBG_RAWCODE +//#define RF433ANY_DBG_DECODER +//#define RF433ANY_DBG_SMALL_RECORDED + +#endif // RF433ANY_TESTPLAN + +#if defined(RF433ANY_DBG_SIMULATE) || defined(DBG_TRACE) \ + || defined(DBG_TIMINGS) || defined(RF433ANY_DBG_TRACK) \ + || defined(RF433ANY_DBG_RAWCODE) || defined(RF433ANY_DBG_DECODER) +#define DEBUG +#endif + +#ifdef RF433ANY_DBG_SIMULATE +#include "Serial.h" +#define SIM_TIMINGS_LEN 140 +#endif + +#ifdef DEBUG + +#include "Debug.h" + +#else + +#define dbg(a) +#define dbgf(...) + +#endif + +#include + +#define MAX_DURATION 65535 +#define MAX_SEP_DURATION 65535 +#ifndef RF433ANY_MAX_SECTIONS +#define RF433ANY_MAX_SECTIONS 8 +#endif + +#define ASSERT_OUTPUT_TO_SERIAL + +#define assert(cond) { \ + if (!(cond)) { \ + assert_failed(__LINE__); \ + } \ +} +void assert_failed(int line); + + +// * **** ********************************************************************* +// * Band ********************************************************************* +// * **** ********************************************************************* + +#define BAND_MIN_D 64 + // IMPORTANT + // Value must be so that BAND_MAX_D * 2 can be stored in a uint16_t. + // That means BAND_MAX_D must be lower than 32768. +#define BAND_MAX_D 30000 + +struct Band { + uint16_t inf; + uint16_t mid; + uint16_t sup; + + bool got_it; + + bool test_value_init_if_needed(uint16_t d); + bool test_value(uint16_t d); + + void breset(); + bool init(uint16_t d); + bool init_sep(uint16_t d); +}; + + +// * **** ********************************************************************* +// * Rail ********************************************************************* +// * **** ********************************************************************* + +#ifdef RF433ANY_DBG_SIMULATE + +#ifdef RF433ANY_DBG_SMALL_RECORDED + +typedef uint8_t recorded_t; +#define FMTRECORDEDT "%02X" + +#else + +typedef uint32_t recorded_t; +#define FMTRECORDEDT "%08lX" + +#endif + +#else // RF433ANY_DBG_SIMULATE + +typedef uint16_t recorded_t; +#define FMTRECORDEDT "%04lx" + +#endif + +#define RAIL_MOOD_STRICT 0 +#define RAIL_MOOD_LAXIST 1 + +#define DEFAULT_RAIL_MOOD RAIL_MOOD_LAXIST + +#define RAIL_OPEN 0 +#define RAIL_FULL 1 +#define RAIL_STP_RCVD 2 +#define RAIL_CLOSED 3 +#define RAIL_ERROR 4 + +class Rail { + friend class Track; + + private: + Band b_short; + Band b_long; + Band b_sep; + + byte last_bit_recorded; + recorded_t rec; + byte status; + byte index; + + byte mood; + + public: + Rail(byte arg_mood); + bool rail_eat(uint16_t d); + void rreset(); + void rreset_soft(); +#ifdef RF433ANY_DBG_TRACK + void rail_debug() const; +#endif + byte get_band_count() const; +}; + + +// * **** ********************************************************************* +// * Misc ********************************************************************* +// * **** ********************************************************************* + +typedef enum { + STS_CONTINUED, + STS_X_SEP, // FIXME + STS_SHORT_SEP, + STS_LONG_SEP, + STS_SEP_SEP, + STS_ERROR +} section_term_status_t; + +struct Timings { + uint16_t low_short; + uint16_t low_long; + uint16_t high_short; + uint16_t high_long; + uint16_t sep; +}; + +struct TimingsExt: public Timings { + uint16_t initseq; + uint16_t first_low; + uint16_t first_high; + uint16_t first_low_ignored; + uint16_t last_low; +}; + +struct Section { + recorded_t low_rec; + unsigned char low_bits :6; + unsigned char low_bands :2; + recorded_t high_rec; + unsigned char high_bits :6; + unsigned char high_bands :2; + + uint16_t first_low; + uint16_t first_high; + uint16_t last_low; + + Timings ts; + + section_term_status_t sts; +}; + +struct RawCode { + uint16_t initseq; + uint16_t max_code_d; + byte nb_sections; + Section sections[RF433ANY_MAX_SECTIONS]; + + void debug_rawcode() const; +}; + + +// * ********* **************************************************************** +// * BitVector **************************************************************** +// * ********* **************************************************************** + +// vector-like of the (very) poor man. No time to make it fancier. +// It'll simply accept to add a bit at the beginning (add_bit), +// to get the number of bits and bytes, and access the Nth bit or byte. +// Also, an iterator would be best to walk through bits, but it is 'TO DO' for +// now. +class BitVector { + private: + uint8_t* array; + byte allocated; + byte nb_bits; + public: + BitVector(); + virtual ~BitVector(); + + virtual void add_bit(byte v); + + virtual int get_nb_bits() const; + virtual byte get_nb_bytes() const; + virtual byte get_nth_bit(byte n) const; + virtual byte get_nth_byte(byte n) const; + + virtual char *to_str() const; + virtual short cmp(const BitVector *p) const; +}; + + +// * ******* ****************************************************************** +// * Decoder ****************************************************************** +// * ******* ****************************************************************** + + // IMPORTANT + // VALUES ARE NOT ARBITRARY. + // CONVENTION_0 must be 0 and CONVENTION_1 must be 1. + // This is due to the decoding that uses a bit value ultimately coming + // from CONVENTION_0 or CONVENTION_1. +#define CONVENTION_0 0 +#define CONVENTION_1 1 + +enum class Signal { + SHORT, + LONG, + OTHER +}; + + // FD = Filter Data + // Bit-mask values, to be used in conjunction +#define RF433ANY_FD_ALL 0 +#define RF433ANY_FD_DECODED 1 +#define RF433ANY_FD_NO_ERROR 2 +#define RF433ANY_FD_DEDUP 4 +#define RF433ANY_FD_TRI 8 +#define RF433ANY_FD_TRN 16 +#define RF433ANY_FD_MAN 32 + +#define DEC_ID_RAW_INCONSISTENT 0 +#define DEC_ID_START 1 // Start of enumeration of real decoders +#define DEC_ID_RAW_SYNC 1 +#define DEC_ID_TRIBIT 2 +#define DEC_ID_TRIBIT_INV 3 +#define DEC_ID_MANCHESTER 4 +#define DEC_ID_RAW_UNKNOWN_CODING 5 // At last we use this one, that'll always + // produce a successful result. +#define DEC_ID_END 5 // End of enumeration of real decoders + +class Decoder { + private: + Decoder *next; + byte repeats; + + protected: + BitVector* pdata; + byte convention; + byte nb_errors; + + TimingsExt tsext; + + void add_data_bit(byte valbit); + virtual void add_signal_step(Signal low, Signal high) = 0; + + public: + Decoder(byte arg_convention); + virtual ~Decoder(); + virtual byte get_id() const = 0; + virtual char get_id_letter() const = 0; + + static Decoder *build_decoder(byte id, byte convention); + + virtual void add_sync(byte n) { } + virtual byte get_nb_errors() const; + virtual int get_nb_bits() const; + + virtual void get_tsext(TimingsExt *p_tsext) const; + virtual void set_ts(const uint16_t& arg_initseq, const Timings& arg_ts); + virtual void decode_section(const Section *psec, + bool is_cont_of_prev_sec); + virtual void take_into_account_first_low_high(const Section *psec, + bool is_cont_of_prev_sec); + virtual uint16_t first_lo_ignored() const; + + virtual void attach(Decoder *pdec); + virtual void detach(); + + virtual bool data_got_decoded() const { return false; } + virtual const BitVector* get_pdata() const; + virtual BitVector* take_away_data(); + virtual Decoder* get_next() const { return next; } + + virtual void reset_repeats() { repeats = 0; } + virtual void inc_repeats() { ++repeats; } + virtual byte get_repeats() const { return repeats; }; + +#ifdef RF433ANY_DBG_DECODER + virtual void dbg_data(byte seq) const; + virtual void dbg_meta(byte disp_level) const; + virtual void dbg_decoder(byte disp_level = 1, byte seq = 0) const + = 0; + virtual void dbg_next(byte disp_level, byte seq) const; +#endif +}; + + +// * ********************** *************************************************** +// * DecoderRawInconsistent *************************************************** +// * ********************** *************************************************** + +class DecoderRawInconsistent: public Decoder { + public: + DecoderRawInconsistent(): Decoder(CONVENTION_0) { } + ~DecoderRawInconsistent() { } + + virtual byte get_id() const override { return DEC_ID_RAW_INCONSISTENT; } + virtual char get_id_letter() const override { return 'I'; } + + virtual void add_signal_step(Signal lo, Signal hi) override { } + +#ifdef RF433ANY_DBG_DECODER + virtual void dbg_decoder(byte disp_level, byte seq) const override; +#endif +}; + + +// * ************** *********************************************************** +// * DecoderRawSync *********************************************************** +// * ************** *********************************************************** + +class DecoderRawSync: public Decoder { + private: + byte nb_low_high; + Signal sync_shape; + bool sync_shape_set; + + public: + DecoderRawSync(byte arg_nb_low_high): + Decoder(CONVENTION_0), + nb_low_high(arg_nb_low_high), + sync_shape_set(false) { } + ~DecoderRawSync() { } + + virtual byte get_id() const override { return DEC_ID_RAW_SYNC; } + virtual char get_id_letter() const override { return 'S'; } + + virtual void add_signal_step(Signal lo, Signal hi) override; + + virtual void add_sync(byte n) override; + + virtual int get_nb_bits() const override; + +#ifdef RF433ANY_DBG_DECODER + virtual void dbg_decoder(byte disp_level, byte seq) const override; +#endif + +}; + + +// * *********************** ************************************************** +// * DecoderRawUnknownCoding ************************************************** +// * *********************** ************************************************** + +class DecoderRawUnknownCoding: public Decoder { + private: + Signal unused_final_low; + bool terminates_with_sep; + + public: + DecoderRawUnknownCoding(): + Decoder(CONVENTION_0), + unused_final_low(Signal::OTHER), + terminates_with_sep(false) { } + ~DecoderRawUnknownCoding() { } + + virtual byte get_id() const override + { return DEC_ID_RAW_UNKNOWN_CODING; } + virtual char get_id_letter() const override { return 'U'; } + + virtual void add_signal_step(Signal lo, Signal hi) override; + +#ifdef RF433ANY_DBG_DECODER + virtual void dbg_decoder(byte disp_level, byte seq) const override; +#endif + +}; + + +// * ************* ************************************************************ +// * DecoderTriBit ************************************************************ +// * ************* ************************************************************ + +class DecoderTriBit: public Decoder { + public: + DecoderTriBit(byte arg_convention = CONVENTION_0) + :Decoder(arg_convention) { + } + ~DecoderTriBit() { } + + virtual byte get_id() const override { return DEC_ID_TRIBIT; } + virtual char get_id_letter() const override { return 'T'; } + virtual void add_signal_step(Signal low, Signal high) + override; + + virtual bool data_got_decoded() const override { return true; } + +#ifdef RF433ANY_DBG_DECODER + virtual void dbg_decoder(byte disp_level, byte seq) const override; +#endif + +}; + + +// * **************** ********************************************************* +// * DecoderTriBitInv ********************************************************* +// * **************** ********************************************************* + +class DecoderTriBitInv: public Decoder { + private: + bool first_call_to_add_sgn_lo_hi; + Signal unused_initial_low; + Signal last_hi; + + public: + DecoderTriBitInv(byte arg_convention = CONVENTION_0) + :Decoder(arg_convention), + first_call_to_add_sgn_lo_hi(true), + unused_initial_low(Signal::OTHER) { + } + ~DecoderTriBitInv() { } + + virtual byte get_id() const override { return DEC_ID_TRIBIT_INV; } + virtual char get_id_letter() const override { return 'N'; } + virtual void add_signal_step(Signal low, Signal high) + override; + + virtual bool data_got_decoded() const override { return true; } + + virtual uint16_t first_lo_ignored() const override; + +#ifdef RF433ANY_DBG_DECODER + virtual void dbg_decoder(byte disp_level, byte seq) const override; +#endif + +}; + + +// * ***************** ******************************************************** +// * DecoderManchester ******************************************************** +// * ***************** ******************************************************** + +class DecoderManchester: public Decoder { + private: + byte buf[3]; + byte buf_pos; + // Manchester encoding comes with a mandatory leading 'short low' + // (otherwise we could not distinguish it from the initialization + // sequence). + // Said differently: Manchester needs a leading '0' bit (if + // considering low-then-high is '0'), that is not part of data. + bool leading_lo_hi_has_been_passed; + + void add_buf(byte r); + void consume_buf(); + + public: + DecoderManchester(byte arg_convention = CONVENTION_0); + ~DecoderManchester() { } + + virtual byte get_id() const override { return DEC_ID_MANCHESTER; } + virtual char get_id_letter() const override { return 'M'; } + virtual void add_signal_step(Signal low, Signal high) + override; + + virtual bool data_got_decoded() const override { return true; } + +#ifdef RF433ANY_DBG_DECODER + virtual void dbg_decoder(byte disp_level, byte seq) const override; +#endif + +}; + + +// * ***** ******************************************************************** +// * Track ******************************************************************** +// * ***** ******************************************************************** + +#define TRACK_MIN_INITSEQ_DURATION 4000 +#define TRACK_MIN_BITS 7 + + // IMPORTANT + // IH_MASK must be equal to the size of IH_timings - 1. + // The size of IH_timings must be a power of 2. + // Thus, IH_MASK allows to quickly calculate modulo, while walking through + // IH_timings. +#define IH_SIZE 4 +#define IH_MASK (IH_SIZE - 1) + +struct IH_timing_t { + byte r; + uint16_t d; + + IH_timing_t() { } + IH_timing_t(const volatile IH_timing_t& t) { + r = t.r; + d = t.d; + } +}; + +// NOTE - ABOUT STATIC MEMBER VARIABLES AND FUNCTIONS IN THE TRACK CLASS +// The class is designed so that one object is useful at a time. This comes +// from the fact that we attach interrupt handler to a static method (as is +// mandatory: an object method would not be possible, compiler would block +// because no way to populate 'this' pointer.) +// At last, the distinction between static and non-static members is a bit +// arbitrary. +// I decided that variables and functions _directly_ tied to interrupt handler +// are static, while all others are non-static. +typedef enum {TRK_WAIT, TRK_RECV, TRK_DATA} trk_t; +class Track { + private: + + +#ifdef DBG_TIMINGS + static uint16_t ih_dbg_timings[40]; + static uint16_t ih_dbg_exec[40]; + static unsigned int ih_dbg_pos; +#endif + static byte pin_number; + static volatile IH_timing_t IH_timings[IH_SIZE]; + static volatile unsigned char IH_write_head; + static volatile unsigned char IH_read_head; + static byte IH_max_pending_timings; + static bool IH_interrupt_handler_is_attached; + + volatile trk_t trk; + byte count; + + Rail r_low; + Rail r_high; + byte prev_r; + + uint16_t first_low; + uint16_t first_high; + uint16_t last_low; + + RawCode rawcode; + + void reset_border_mgmt(); + Decoder* get_data_core(byte convention); + + public: + Track(int arg_pin_number, byte mood = DEFAULT_RAIL_MOOD); + + static void ih_handle_interrupt(); + static byte ih_get_max_pending_timings() { + return IH_max_pending_timings; + } + + void treset(); + void track_eat(byte r, uint16_t d); +#ifdef RF433ANY_DBG_TRACK + void track_debug() const; +#endif +#ifdef DBG_TIMINGS + void dbg_timings() const; +#endif + + trk_t get_trk() const { return trk; } + + void force_stop_recv(); + + void activate_recording(); + void deactivate_recording(); + bool process_interrupt_timing(); + bool do_events(); + Decoder* get_data(uint16_t filter, byte convention = CONVENTION_0); +}; + +#endif // _RF433ANY_H + +// vim: ts=4:sw=4:tw=80:et diff --git a/Serial.cpp b/Serial.cpp new file mode 100644 index 0000000..8b6372d --- /dev/null +++ b/Serial.cpp @@ -0,0 +1,103 @@ +// Serial.cpp + +/* + Provides a way to read lines on serial +*/ + +/* + Copyright 2021 Sébastien Millet + + `rf433any' is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + `rf433any' is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + . +*/ + +#include "Serial.h" +#include + +SerialLine::SerialLine():head(0),got_a_line(false) { }; + +void SerialLine::do_events() { + if (got_a_line) + return; + if (!Serial.available()) + return; + + int b; + do { + b = Serial.read(); + if (b == -1) + break; + buf[head++] = (char)b; + } while (head < SERIAL_LINE_BUF_LEN - 1 && b != '\n' && Serial.available()); + + if (head < SERIAL_LINE_BUF_LEN - 1 && b != '\n') + return; + + buf[head] = '\0'; + + // Remove trailing cr and/or nl + // FIXME? + // WON'T WORK WITH MAC-OS NEWLINES! + // (SEE ABOVE: NO STOP IF ONLY CR ENCOUNTERED) + if (head >= 1 && buf[head - 1] == '\n') + buf[--head] = '\0'; + if (head >= 1 && buf[head - 1] == '\r') + buf[--head] = '\0'; + got_a_line = true; +} + +bool SerialLine::is_line_available() { + do_events(); + return got_a_line; +} + +void SerialLine::reset() { + head = 0; + got_a_line = false; +} + +// Get USB input as a simple line, copied in caller buffer. +// A 'line' is a set of non-null characters followed by 'new line', 'new line' +// being either as per Unix or Windows convention, see below. +// Returns true if a copy was done (there was a line available), false if not +// (in which case, s is not updated). +// The terminating newline character (or 2-character CR-LF sequence) is NOT part +// of the string given to the caller. +// If the line length is above the buffer size (SERIAL_LINE_BUF_LEN), then it'll +// be cut into smaller pieces. +// Because of the way the received buffer is parsed, and when using CR-LF as +// end-of-line marker (default even under Linux), it can result in a empty +// string seen after a first string with a length close to the limit. +// +// About new lines: +// - Works fine with Unix new lines (\n), tested +// - Supposed to work fine with Windows new lines (\r\n), NOT TESTED +// - WON'T WORK WITH MAC-OS NEW LINES (\r) +bool SerialLine::get_line(char *s, size_t len) { + do_events(); + if (!got_a_line) + return false; + snprintf(s, len, buf); + reset(); + return true; +} + +// Same as get_line, but with blocking I/O = +// Wait without time limit, until a line comes in. +void SerialLine::get_line_blocking(char *s, size_t len) { + while (!get_line(s, len)) + ; +} + +// vim: ts=4:sw=4:tw=80:et diff --git a/Serial.h b/Serial.h new file mode 100644 index 0000000..caf9c32 --- /dev/null +++ b/Serial.h @@ -0,0 +1,48 @@ +// Serial.h + +/* + Copyright 2021 Sébastien Millet + + `rf433any' is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + `rf433any' is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + . +*/ + +#ifndef _SERIAL_H +#define _SERIAL_H + +#include + +#define SERIAL_LINE_BUF_LEN 19 + +class SerialLine { + private: + char buf[SERIAL_LINE_BUF_LEN]; // 16-character strings (then CR+LF then + // NULL-terminating). + size_t head; + bool got_a_line; + void reset(); + + public: + SerialLine(); + + void do_events(); + bool is_line_available(); + bool get_line(char *s, size_t len); + void get_line_blocking(char *s, size_t len); + void split_s_into_func_args(char *s, char **func, char **args) const; +}; + +#endif // _SERIAL_H + +// vim: ts=4:sw=4:tw=80:et diff --git a/examples/output-signal-timings/Makefile b/examples/output-signal-timings/Makefile new file mode 100644 index 0000000..ba06c3f --- /dev/null +++ b/examples/output-signal-timings/Makefile @@ -0,0 +1,10 @@ +ARDUINO_DIR = /usr/share/arduino +ARDUINO_LIBS = RF433any +ARDMK_DIR = /home/sebastien/.arduino_mk + +# USER_LIB_PATH = /home/sebastien/travail/cpp/seb/arduino/libraries + +BOARD_TAG = uno +MCU = atmega328 + +include $(ARDMK_DIR)/Arduino.mk diff --git a/examples/output-signal-timings/am b/examples/output-signal-timings/am new file mode 100755 index 0000000..8ae2812 --- /dev/null +++ b/examples/output-signal-timings/am @@ -0,0 +1,343 @@ +#!/usr/bin/bash + +# am + +# Copyright 2019, 2020, 2021 Sébastien Millet + +# Can perform the following: +# 1. Compile the code +# 2. Upload to Arduino +# 3. Read (continually) what is arriving from the USB port the Arduino is +# connected to + +# Versions history (as of 1.3) +# 1.3 Output from Arduino is recorded in files named with numbers instead of +# date-time string. +# 1.4 Adds -t (--testplan) option, to set TESTPLAN macro +# 1.5 -t (or --testplan) now comes with a value, so as to manage multiple test +# plans. +# 1.6 Updated to work fine with Arch arduino package instead of the manually +# installed (from tar.gz source) package used so far. +# 1.7 Renames archlinux-arduino back to arduino, and created corresponding +# symlink (was cleaner to do s). + +set -euo pipefail + +VERSION=1.7 + +PORT= +BOARD= +SPEED= +FQBN= +BUILDDIR= +RECORDDIR=out +READSPEED= +RECORDFILE= + +UPLOAD="no" +VERBOSE="no" +CATUSB="no" +STTY="no" +RECORDUSB="no" +COMPILE="yes" +TESTPLAN= + +DISPLAYSEP=no + +function finish { + if [ "${DISPLAYSEP}" == "yes" ]; then + echo "-----END ARDUINO OUTPUT-----" | tee -a "${RECORDFILE}" + fi +} + +trap finish EXIT + +function usage { + echo "Usage:" + echo " am [OPTIONS...] FILE" + echo "Compile FILE using arduino-builder." + echo "Example: am sketch.ino" + echo "" + echo "ENVIRONMENT VARIABLES" + echo " If ARDUINO_USER_LIBS is defined and non empty, then arduino-builder" + echo " is called with the supplementary option -libraries followed by" + echo " ARDUINO_USER_LIBS' value." + echo "" + echo "OPTIONS" + echo " -h --help Display this help screen" + echo " -V --version Output version information and quit" + echo " -v --verbose Be more talkative" + echo " -u --upload Upload compiled code into Arduino" + echo " -b --board Board, either 'uno' or 'nano'" + echo " -p --port Port, for ex. '/dev/ttyUSB0'" + echo " -s --speed Upload speed, for ex. 115200" + echo " Normally, speed is infered from device type:" + echo " 115200 for Uno, 57600 for Nano" + echo " -B --fqbn Board Fully Qualified Name, like 'arduino:avr:uno'" + echo " -d --builddir Build directory" + echo " -c --catusb Display (continually) what Arduino writes on USB" + echo " --stty Tune stty properly for later communication (implied" + echo " by --catusb)" + echo " -r --recordusb Write USB (continually) to a file (implies -c)" + echo " --recordfile Output file if -r option is set" + echo " -n --nocompile Don't compile code" + echo " --readspeed Read speed of USB. If not specified, this script" + echo " will try to infere it from source file. If it" + echo " fails, it'll fallback to 9600." + echo " This option is useful only if USB is read" + echo " (-c or --stty option set)" + echo " -t --testplan Set TESTPLAN macro value" + echo " (as if #define TESTPLAN VALUE)" + exit 1 +} + +function version { + echo "am version ${VERSION}" + exit +} + +OPTS=$(getopt -o hVvub:p:s:B:d:crnt: --long help,version,verbose,upload,board:,port:,speed:,fqbn:,builddir:,catusb,stty,recordusb,nocompile,readspeed:,recordfile:,testplan: -n 'am' -- "$@") + +eval set -- "$OPTS" + +while true; do + case "$1" in + -h | --help ) usage; shift ;; + -V | --version ) version; shift ;; + -v | --verbose ) VERBOSE="yes"; shift ;; + -u | --upload ) UPLOAD="yes"; shift ;; + -b | --board ) BOARD="$2"; shift 2 ;; + -p | --port ) PORT="$2"; shift 2 ;; + -s | --speed ) SPEED="$2"; shift 2 ;; + -B | --fqbn ) FQBN="$2"; shift 2 ;; + -d | --builddir ) BUILDDIR="$2"; shift 2 ;; + -c | --catusb ) CATUSB="yes"; shift ;; + -r | --recordusb ) RECORDUSB="yes"; CATUSB="yes"; shift ;; + -n | --nocompile ) COMPILE="no"; shift ;; + --readspeed ) READSPEED="$2"; shift 2 ;; + --recordfile ) RECORDFILE="$2"; shift 2 ;; + --stty ) STTY="yes"; shift ;; + -t | --testplan ) TESTPLAN="$2"; shift 2 ;; + -- ) shift; break ;; + * ) break ;; + esac +done + +FILE=${1:-} +TRAILINGOPTS=${2:-} + +if [ -n "${TRAILINGOPTS}" ]; then + echo "Error: trailing options" + exit 1; +fi +if [ -z "${FILE}" ]; then + echo "Error: no input file" + exit 1; +fi + +set +e + +if [ -n "${BOARD}" ]; then + if [ "${BOARD}" != "uno" ] && [ "${BOARD}" != "nano" ]; then + echo "Error: board '${BOARD}' unknown" + exit 1 + fi +fi + +#ARDUINODIR=$(LANG='' type -a arduino \ +# | tail -n 1 \ +# | sed 's/\S\+\sis\s//') +#ARDUINODIR=$(readlink -f "${ARDUINODIR}") +#ARDUINODIR=$(dirname "${ARDUINODIR}") + +ARDUINODIR=/usr/share/arduino + +COUNTUNO=$(compgen -G '/dev/ttyACM*' | wc -l) +COUNTNANO=$(compgen -G '/dev/ttyUSB*' | wc -l) + +if [ -z "${BOARD}" ]; then + if [ "${COUNTUNO}" -ge 1 ] && [ "${COUNTNANO}" -ge 1 ]; then + echo "Error: cannot guess board, found ${COUNTUNO} uno(s), ${COUNTNANO} nano(s)" + exit 10 + fi + if [ "${COUNTUNO}" -ge 1 ]; then + BOARD=uno + elif [ "${COUNTNANO}" -ge 1 ]; then + BOARD=nano + fi + if [ -z "${BOARD}" ]; then + echo "Error: cannot guess board, none found"; + exit 10 + fi +fi + +if [ "${UPLOAD}" == "yes" ] || [ "${CATUSB}" == "yes" ]; then + if [ -z "${PORT}" ]; then + if [ "${BOARD}" == "uno" ]; then + COUNT=${COUNTUNO} + PORT=$(compgen -G '/dev/ttyACM*') + elif [ "${BOARD}" == "nano" ]; then + COUNT=${COUNTNANO} + PORT=$(compgen -G '/dev/ttyUSB*') + else + echo "FATAL #001, CHECK THIS CODE" + exit 99 + fi + + if [ "${COUNT}" -ge 2 ]; then + echo "Error: cannot guess port, more than 1 board '${BOARD}' found" + exit 10 + fi + if [ -z "${PORT}" ]; then + echo "Error: cannot guess port, none found" + exit 10 + fi + fi + + if [ -z "${SPEED}" ]; then + if [ "${BOARD}" == "uno" ]; then + SPEED=115200 + elif [ "${BOARD}" == "nano" ]; then + SPEED=57600 + else + echo "FATAL #002, CHECK THIS CODE" + exit 99 + fi + fi + + if [ ! -e "${PORT}" ]; then + echo "Error: port not found" + exit 10 + fi +fi + +if [ -z "${FQBN}" ]; then + if [ "${BOARD}" == "uno" ]; then + FQBN="arduino:avr:uno" + elif [ "${BOARD}" == "nano" ]; then + FQBN="arduino:avr:nano:cpu=atmega328old" + else + echo "FATAL #003, CHECK THIS CODE" + exit 99 + fi +fi + +if [ -z "${BUILDDIR}" ]; then + if [[ "${FILE}" == */* ]]; then + BUILDDIR=${FILE%/*} + BUILDDIR="${BUILDDIR%/}/build" + else + BUILDDIR=build + fi +fi + +if [ "${RECORDUSB}" == "yes" ]; then + if [ -z "${RECORDFILE}" ]; then + V=${FILE##*/} + V=${V%.*} + V=${V:-out} + PREV= + for i in {15..00}; do + F="${RECORDDIR}/${V}-$i.txt" + if [ -e "${F}" ] && [ -n "${PREV}" ]; then + mv "${F}" "${PREV}" + fi + PREV="${F}" + done + RECORDFILE="${F}" + mkdir -p "${RECORDDIR}" + fi +else + RECORDFILE="/dev/null" +fi + +if [ "${VERBOSE}" == "yes" ]; then + echo "-- Settings" + echo "Arduino dir: ${ARDUINODIR}" + echo "Board: ${BOARD}" + echo "Port: ${PORT}" + echo "Speed: ${SPEED}" + echo "Fqbn: ${FQBN}" + echo "Upload: ${UPLOAD}" + echo "Catusb: ${CATUSB}" + echo "Recordusb: ${RECORDUSB}" + echo "Record file: ${RECORDFILE}" + echo "Verbose: ${VERBOSE}" + echo "File: ${FILE}" + echo "Build dir: ${BUILDDIR}" +fi + +set -e + +if [ "${COMPILE}" == "yes" ]; then + echo "-- Compile" + + mkdir -p "${BUILDDIR}" + + OPT_LIB= + TMP_ULIB=${ARDUINO_USER_LIBS:-} + if [ -n "${TMP_ULIB}" ]; then + OPT_LIB="-libraries ""${TMP_ULIB}""" + fi + + TESTPLAN_OPT="" + if [ -n "${TESTPLAN}" ]; then + TESTPLAN_OPT="-prefs=build.extra_flags=-DTESTPLAN=${TESTPLAN}" + fi + + # shellcheck disable=SC2086 + # (We don't want to quote OPT_LIB as it can contain multiple options.) + "${ARDUINODIR}/arduino-builder" \ + -hardware "${ARDUINODIR}/hardware" \ + -tools "${ARDUINODIR}/hardware/tools/avr" \ + -tools "${ARDUINODIR}/tools-builder" \ + -built-in-libraries "${ARDUINODIR}/libraries" \ + ${OPT_LIB} \ + -fqbn "${FQBN}" \ + -build-path "${BUILDDIR}" \ + ${TESTPLAN_OPT} \ + "${FILE}" +fi + +FILEBASENAME=${FILE##*/} + +if [ "${UPLOAD}" == "yes" ]; then + echo "-- Upload" + "/usr/bin/avrdude" \ + -q -q -patmega328p -carduino -P"${PORT}" -b"${SPEED}" -D \ + -Uflash:w:"${BUILDDIR}/${FILEBASENAME}".hex:i +fi + +if [ "${CATUSB}" == "yes" ] || [ "${STTY}" == "yes" ]; then + if [ -z "${READSPEED}" ]; then + TFILE=$(mktemp) + gcc -fpreprocessed -dD -x c++ -E "${FILE}" > "${TFILE}" + for sp in 9600 19200 28800 38400 57600 115200; do + if grep ${sp} "${TFILE}" > /dev/null; then + READSPEED=${sp} + fi + done + READSPEED=${READSPEED:-9600} + rm "${TFILE}" + fi + + stty -F "${PORT}" -hupcl -echo "${READSPEED}" + echo "-- usb setup with speed ${READSPEED}" +fi + +if [ "${CATUSB}" == "yes" ]; then + echo "-- Read usb (Ctrl-C to quit)" + DISPLAYSEP=yes + { + echo "speed=${READSPEED}" + echo "fqbn=${FQBN}" + echo "port=${PORT}" + echo "file=${FILE}" + echo "filedate=$(date +"%Y-%m-%dT%H:%M:%SZ" -d @$(stat -c '%Y' "${FILE}"))" + echo "date=$(date +'%Y-%m-%dT%H:%M:%SZ')" + echo "" + echo "-----BEGIN ARDUINO OUTPUT-----" + } | tee "${RECORDFILE}" + tee -a "${RECORDFILE}" < "${PORT}" +fi + diff --git a/examples/output-signal-timings/output-signal-timings.ino b/examples/output-signal-timings/output-signal-timings.ino new file mode 100644 index 0000000..f6314c0 --- /dev/null +++ b/examples/output-signal-timings/output-signal-timings.ino @@ -0,0 +1,102 @@ +// output-signal-timings.ino + +// Example sketch that comes along with RF433any library + +/* + Copyright 2021 Sébastien Millet + + `RF433any' is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + `RF433any' is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + . +*/ + +// +// Schematic: see RF433any library +// + +#include "RF433any.h" +#include + +#define PIN_RFINPUT 2 + +char serial_printf_buffer[150]; +void serial_printf(const char* msg, ...) + __attribute__((format(printf, 1, 2))); + + // NOTE + // Assume Serial has been initialized (Serial.begin(...)) +void serial_printf(const char* msg, ...) { + va_list args; + + va_start(args, msg); + + vsnprintf(serial_printf_buffer, sizeof(serial_printf_buffer), msg, args); + va_end(args); + Serial.print(serial_printf_buffer); +} + +void setup() { + pinMode(PIN_RFINPUT, INPUT); + Serial.begin(115200); + Serial.print("Waiting for signal\n"); +} + +Track track(PIN_RFINPUT); + +void output_timings(Decoder *pdec) { + TimingsExt tsext; + if (!pdec) + return; + pdec->get_tsext(&tsext); + serial_printf(" I=%u, LS=%u, LL=%u, HS=%u, HL=%u, S=%u, U=%u, V=%u, " + "Y=%u, Z=%u\n", tsext.initseq, tsext.low_short, tsext.low_long, + tsext.high_short, tsext.high_long, tsext.sep, tsext.first_low, + tsext.first_high, tsext.first_low_ignored, tsext.last_low); +} + +void loop() { + track.treset(); + + while (!track.do_events()) + delay(1); + + Decoder *pdec0 = track.get_data(RF433ANY_FD_DEDUP); + Decoder *pdec = pdec0; + while(pdec) { + BitVector *pdata = pdec->take_away_data(); + + serial_printf("Decoded: %s, err: %d, code: %c, " + "rep: %d, bits: %2d", + (pdec->data_got_decoded() ? "yes" : "no "), + pdec->get_nb_errors(), pdec->get_id_letter(), + pdec->get_repeats() + 1, pdec->get_nb_bits()); + + if (pdec->data_got_decoded()) { + Serial.print(", data: "); + if (pdata) { + char *buf = pdata->to_str(); + if (buf) { + Serial.print(buf); + free(buf); + } + delete pdata; + } +// output_timings(pdec); + } + Serial.print("\n"); + pdec = pdec->get_next(); + } + delete pdec0; +} + +// vim: ts=4:sw=4:tw=80:et diff --git a/library.properties b/library.properties new file mode 100644 index 0000000..c9e61f3 --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=RF433any +version=0.5 +author=Sébastien Millet +maintainer=Sébastien Millet +sentence=A library to decode any protocol received on a 433 Mhz Radio Frequence receiver like MX-RM-5V +paragraph=Use this library to decode any protocol received on a 433 Mhz Radio Frequence receiver like MX-RM-5V. Allow to display low level data (raw code), user-level data (code received) and code timings. +category=Communication +url=https://github.com/sebmillet/RF433any +architectures=avr +includes=RF433any.h diff --git a/schema.fzz b/schema.fzz new file mode 100644 index 0000000..9e11c18 Binary files /dev/null and b/schema.fzz differ diff --git a/schema.png b/schema.png new file mode 100644 index 0000000..a7670a8 Binary files /dev/null and b/schema.png differ diff --git a/testplan/clean.sh b/testplan/clean.sh new file mode 100755 index 0000000..0641f21 --- /dev/null +++ b/testplan/clean.sh @@ -0,0 +1,22 @@ +#!/usr/bin/bash + +set -euo pipefail + +cd track + +for d in [0-9][0-9]; do + rm -f "${d}"/tmpout*.txt +done + +cd ../decoder + +for d in [0-9][0-9]; do + rm -f "${d}"/tmpout*.txt +done + +cd ../user + +for d in [0-9][0-9]; do + rm -f "${d}"/tmpout*.txt +done + diff --git a/testplan/decoder/01/code.txt b/testplan/decoder/01/code.txt new file mode 100644 index 0000000..719c5cd --- /dev/null +++ b/testplan/decoder/01/code.txt @@ -0,0 +1,12 @@ +0 , 9000 +1236, 576 +536, 1280 +1232, 608 +1232, 596 +528, 1292 +1228, 600 +1228, 600 +1228, 608 +528, 1316 +522, 7020 +0, 0 diff --git a/testplan/decoder/01/expect3.txt b/testplan/decoder/01/expect3.txt new file mode 100644 index 0000000..e0d0741 --- /dev/null +++ b/testplan/decoder/01/expect3.txt @@ -0,0 +1,2 @@ +[0] Received 9 bits: 01 6e + T=TRI, E=0, I=9000, S=572, L=1256, P=7020, Y=0, Z=522 diff --git a/testplan/decoder/01/expect4.txt b/testplan/decoder/01/expect4.txt new file mode 100644 index 0000000..c183e24 --- /dev/null +++ b/testplan/decoder/01/expect4.txt @@ -0,0 +1,2 @@ +[0] Received 9 bits: 01 6e + T=TRI, E=0, I=9000, S=572, L=1256, P=7020, Y=0, Z=528 diff --git a/testplan/decoder/02/code.txt b/testplan/decoder/02/code.txt new file mode 100644 index 0000000..ca09eef --- /dev/null +++ b/testplan/decoder/02/code.txt @@ -0,0 +1,12 @@ +0 , 9000 +1236, 576 +536, 1280 +1232, 608 +1232, 596 +528, 1292 +1228, 600 +1228, 600 +1228, 608 +1232, 1316 +522, 7020 +0, 0 diff --git a/testplan/decoder/02/expect3.txt b/testplan/decoder/02/expect3.txt new file mode 100644 index 0000000..2974998 --- /dev/null +++ b/testplan/decoder/02/expect3.txt @@ -0,0 +1,3 @@ +[0] Unknown encoding: 18 signal bits + Signal: LS:SL:LS:LS:SL:LS:LS:LS:LL:SP + T=UNK, E=0, I=9000, S=572, L=1256, P=7020, Y=0, Z=522 diff --git a/testplan/decoder/02/expect4.txt b/testplan/decoder/02/expect4.txt new file mode 100644 index 0000000..795253c --- /dev/null +++ b/testplan/decoder/02/expect4.txt @@ -0,0 +1,3 @@ +[0] Unknown encoding: 18 signal bits + Signal: LS:SL:LS:LS:SL:LS:LS:LS:LL:SP + T=UNK, E=0, I=9000, S=572, L=1256, P=7020, Y=0, Z=1232 diff --git a/testplan/decoder/03/code.txt b/testplan/decoder/03/code.txt new file mode 100644 index 0000000..427be11 --- /dev/null +++ b/testplan/decoder/03/code.txt @@ -0,0 +1,69 @@ +0, 6908 +1272, 520 +564, 1276 +1172, 632 +1160, 640 +472, 1284 +1252, 556 +592, 1240 +1292, 500 +572, 1200 +612, 1172 +1284, 528 +1260, 576 +528, 1336 +1164, 692 +428, 1380 +1172, 588 +520, 1228 +1268, 528 +1300, 512 +580, 1224 +1272, 552 +1268, 564 +560, 1300 +1216, 640 +448, 1356 +432, 1336 +468, 1292 +520, 1260 +560, 1252 +568, 1260 +560, 1284 +560, 1208 +560, 7036 +1152, 608 +484, 1272 +1232, 540 +1280, 540 +584, 1240 +1276, 548 +572, 1260 +1272, 540 +544, 1292 +476, 1352 +1136, 672 +1132, 656 +468, 1300 +1232, 588 +560, 1276 +1268, 524 +564, 1232 +1248, 556 +1240, 564 +528, 1320 +1172, 688 +1128, 728 +408, 1376 +1188, 580 +528, 1232 +548, 1236 +556, 1240 +552, 1260 +552, 1268 +552, 1308 +504, 1376 +452, 1352 +408, 6984 +1260, 520 +572, 1224 diff --git a/testplan/decoder/03/expect3.txt b/testplan/decoder/03/expect3.txt new file mode 100644 index 0000000..92d94c5 --- /dev/null +++ b/testplan/decoder/03/expect3.txt @@ -0,0 +1,4 @@ +[0] Received 32 bits: b5 35 6d 00 + T=TRI, E=0, I=6908, S=598, L=1224, P=7036, Y=0, Z=560 +[1] Received 32 bits: b5 35 6d 00 + T=TRI, E=0, I=0, S=598, L=1224, P=6984, Y=0, Z=408 diff --git a/testplan/decoder/03/expect4.txt b/testplan/decoder/03/expect4.txt new file mode 100644 index 0000000..8c911cf --- /dev/null +++ b/testplan/decoder/03/expect4.txt @@ -0,0 +1,4 @@ +[0] Received 32 bits: b5 35 6d 00 + T=TRI, E=0, I=6908, S=598, L=1224, P=7036, Y=0, Z=572 +[1] Received 32 bits: b5 35 6d 00 + T=TRI, E=0, I=0, S=598, L=1224, P=6984, Y=0, Z=544 diff --git a/testplan/decoder/10/code-adf7.txt b/testplan/decoder/10/code-adf7.txt new file mode 100644 index 0000000..dd6acb1 --- /dev/null +++ b/testplan/decoder/10/code-adf7.txt @@ -0,0 +1,69 @@ +0, 5436 +1256, 1068 +1268, 2184 +1216, 1092 +1216, 1096 +1204, 1096 +1208, 1096 +1212, 1096 +2356, 2272 +1180, 1128 +2328, 2288 +1172, 1144 +1164, 1140 +2328, 1148 +1152, 1172 +1148, 2332 +2292, 2324 +2288, 2340 +1128, 1188 +2272, 1192 +1120, 2356 +1128, 1188 +1112, 1192 +1120, 1196 +2272, 1192 +1112, 1204 +1112, 6724 +1120, 1192 +1120, 2356 +1112, 1192 +1112, 1200 +1112, 1204 +1120, 1192 +1112, 1200 +2264, 2356 +1120, 1204 +2260, 2352 +1112, 1208 +1104, 1212 +2248, 1224 +1096, 1216 +1108, 2356 +2248, 2380 +2252, 2368 +1096, 1212 +2264, 1220 +1088, 2364 +1112, 1212 +1096, 1216 +1092, 1224 +2244, 1224 +1088, 1224 +1088, 6740 +1096, 1224 +1100, 2368 +1092, 1216 +1096, 1224 +1088, 1220 +1096, 1224 +1088, 1220 +2252, 2368 +1088, 1220 +2252, 2376 +1092, 1224 +1088, 1220 +2256, 1228 +1080, 1224 +1092, 2376 +2244, 2388 diff --git a/testplan/decoder/10/expect3.txt b/testplan/decoder/10/expect3.txt new file mode 100644 index 0000000..47f607c --- /dev/null +++ b/testplan/decoder/10/expect3.txt @@ -0,0 +1,4 @@ +[0] Received 32 bits: 7e dc 56 78 + T=MAN, E=0, I=5436, S=1180, L=2270, P=6724, Y=0, Z=1112 +[1] Received 32 bits: 7e dc 56 78 + T=MAN, E=0, I=0, S=1180, L=2270, P=6740, Y=0, Z=1088 diff --git a/testplan/decoder/10/expect4.txt b/testplan/decoder/10/expect4.txt new file mode 100644 index 0000000..61e2139 --- /dev/null +++ b/testplan/decoder/10/expect4.txt @@ -0,0 +1,6 @@ +[0] Received 32 bits: 7e dc 56 78 + T=MAN, E=0, I=5436, S=1180, L=2270, P=6724, Y=0, Z=1180 +[1] Received 32 bits: 7e dc 56 78 + T=MAN, E=0, I=0, S=1180, L=2270, P=6740, Y=0, Z=1120 +[2] Received 9 bits: 00 fd + T=MAN, E=0, I=0, S=1180, L=2270, P=0, Y=0, Z=1088 diff --git a/testplan/decoder/11/code-adf8.txt b/testplan/decoder/11/code-adf8.txt new file mode 100644 index 0000000..d2ab0ef --- /dev/null +++ b/testplan/decoder/11/code-adf8.txt @@ -0,0 +1,69 @@ +0, 5568 +1120, 2348 +2264, 1212 +1096, 1200 +1108, 2364 +1104, 1196 +1112, 1192 +2260, 2360 +1100, 1200 +2260, 2364 +1104, 1208 +1088, 1220 +2248, 1216 +1096, 1216 +1100, 2364 +2248, 2384 +2252, 2360 +1104, 1208 +2260, 1216 +1092, 2368 +1096, 1216 +1088, 1224 +1096, 1216 +1092, 1216 +1096, 1220 +1088, 1216 +1100, 5576 +1104, 2364 +2260, 1216 +1100, 1220 +1088, 2372 +1096, 1212 +1096, 1224 +2244, 2372 +1096, 1224 +2248, 2372 +1096, 1224 +1080, 1232 +2244, 1216 +1092, 1232 +1080, 2384 +2244, 2376 +2236, 2392 +1080, 1232 +2236, 1220 +1104, 2368 +1092, 1232 +1084, 1224 +1088, 1228 +1084, 1224 +1084, 1232 +1084, 1232 +1080, 5584 +1100, 2384 +2244, 1224 +1092, 1224 +1084, 2384 +1088, 1228 +1080, 1224 +2240, 2392 +1088, 1216 +2244, 2380 +1088, 1224 +1092, 1224 +2236, 1232 +1088, 1224 +1080, 2384 +2236, 2392 +2236, 2380 diff --git a/testplan/decoder/11/expect3.txt b/testplan/decoder/11/expect3.txt new file mode 100644 index 0000000..22e6402 --- /dev/null +++ b/testplan/decoder/11/expect3.txt @@ -0,0 +1,4 @@ +[0] Received 32 bits: 8e dc 56 7f + T=MAN, E=0, I=5568, S=1154, L=2314, P=5576, Y=0, Z=1100 +[1] Received 32 bits: 8e dc 56 7f + T=MAN, E=0, I=0, S=1154, L=2314, P=5584, Y=0, Z=1080 diff --git a/testplan/decoder/11/expect4.txt b/testplan/decoder/11/expect4.txt new file mode 100644 index 0000000..893dc13 --- /dev/null +++ b/testplan/decoder/11/expect4.txt @@ -0,0 +1,6 @@ +[0] Received 32 bits: 8e dc 56 7f + T=MAN, E=0, I=5568, S=1154, L=2314, P=5576, Y=0, Z=2260 +[1] Received 32 bits: 8e dc 56 7f + T=MAN, E=0, I=0, S=1154, L=2314, P=5584, Y=0, Z=2248 +[2] Received 11 bits: 04 76 + T=MAN, E=0, I=0, S=1154, L=2314, P=0, Y=0, Z=2244 diff --git a/testplan/decoder/12/code-adfF.txt b/testplan/decoder/12/code-adfF.txt new file mode 100644 index 0000000..b611fa1 --- /dev/null +++ b/testplan/decoder/12/code-adfF.txt @@ -0,0 +1,69 @@ +0, 5468 +1240, 2272 +1264, 1044 +1224, 1084 +1224, 1088 +1208, 1092 +1216, 1096 +1212, 1088 +2356, 2264 +1180, 1128 +2340, 2288 +1172, 1132 +1168, 1140 +2320, 1164 +1148, 1176 +1132, 2336 +2296, 2332 +2288, 2340 +1124, 1188 +2272, 1196 +1120, 2348 +1120, 1196 +1120, 1192 +1112, 1200 +2272, 1204 +1112, 1204 +1104, 6716 +1128, 2348 +1112, 1208 +1116, 1196 +1112, 1204 +1104, 1204 +1120, 1200 +1104, 1204 +2264, 2356 +1116, 1196 +2264, 2360 +1108, 1216 +1104, 1204 +2256, 1212 +1096, 1220 +1096, 2360 +2256, 2380 +2248, 2372 +1100, 1216 +2252, 1216 +1088, 2376 +1092, 1216 +1096, 1232 +1092, 1216 +2244, 1224 +1100, 1216 +1088, 6732 +1100, 2384 +1096, 1220 +1096, 1208 +1096, 1224 +1088, 1220 +1096, 1216 +1096, 1216 +2252, 2368 +1096, 1224 +2244, 2376 +1092, 1216 +1100, 1216 +2252, 1224 +1080, 1232 +1080, 2380 +2248, 2376 diff --git a/testplan/decoder/12/expect3.txt b/testplan/decoder/12/expect3.txt new file mode 100644 index 0000000..8ac85c3 --- /dev/null +++ b/testplan/decoder/12/expect3.txt @@ -0,0 +1,4 @@ +[0] Received 32 bits: fe dc 56 78 + T=MAN, E=0, I=5468, S=1154, L=2310, P=6716, Y=0, Z=1104 +[1] Received 32 bits: fe dc 56 78 + T=MAN, E=0, I=0, S=1154, L=2310, P=6732, Y=0, Z=1088 diff --git a/testplan/decoder/12/expect4.txt b/testplan/decoder/12/expect4.txt new file mode 100644 index 0000000..6b185e6 --- /dev/null +++ b/testplan/decoder/12/expect4.txt @@ -0,0 +1,6 @@ +[0] Received 32 bits: fe dc 56 78 + T=MAN, E=0, I=5468, S=1154, L=2310, P=6716, Y=0, Z=1180 +[1] Received 32 bits: fe dc 56 78 + T=MAN, E=0, I=0, S=1154, L=2310, P=6732, Y=0, Z=1116 +[2] Received 9 bits: 01 fd + T=MAN, E=0, I=0, S=1154, L=2310, P=0, Y=0, Z=1096 diff --git a/testplan/decoder/13/code-adf7-err.txt b/testplan/decoder/13/code-adf7-err.txt new file mode 100644 index 0000000..dc71bd7 --- /dev/null +++ b/testplan/decoder/13/code-adf7-err.txt @@ -0,0 +1,69 @@ +0, 5436 +1256, 1068 +1268, 2184 +1216, 1092 +1216, 1096 +1204, 1096 +1208, 1096 +1212, 1096 +2356, 2272 +1180, 1128 +2328, 2288 +1172, 1144 +1164, 1140 +2328, 1148 +1152, 1172 +1148, 2332 +2292, 2324 +2288, 2340 +1128, 1188 +2272, 1192 +1120, 2356 +1128, 1188 +1112, 1192 +1120, 1196 +2272, 1192 +1112, 1204 +1112, 6724 +1120, 1192 +1120, 2356 +1112, 1192 +1112, 1200 +1112, 1204 +1120, 1192 +1112, 1200 +2264, 2356 +1120, 1204 +2260, 2352 +1112, 1208 +1104, 1212 +2248, 1224 +1096, 1216 +1108, 2356 +2248, 2380 +1108, 2368 +1096, 1212 +2264, 1220 +1088, 2364 +1112, 1212 +1096, 1216 +1092, 1224 +2244, 1224 +1088, 1224 +1088, 6740 +1096, 1224 +1100, 2368 +1092, 1216 +1096, 1224 +1088, 1220 +1096, 1224 +1088, 1220 +2252, 2368 +1088, 1220 +2252, 2376 +1092, 1224 +1088, 1220 +2256, 1228 +1080, 1224 +1092, 2376 +2244, 2388 diff --git a/testplan/decoder/13/expect3.txt b/testplan/decoder/13/expect3.txt new file mode 100644 index 0000000..eb2046c --- /dev/null +++ b/testplan/decoder/13/expect3.txt @@ -0,0 +1,5 @@ +[0] Received 32 bits: 7e dc 56 78 + T=MAN, E=0, I=5436, S=1180, L=2270, P=6724, Y=0, Z=1112 +[1] Unknown encoding: 50 signal bits + Signal: SS:SL:SS:SS:SS:SS:SS:LL:SS:LL:SS:SS:LS:SS:SL:LL:SL:SS:LS:SL:SS:SS:SS:LS:SS:SP + T=UNK, E=0, I=0, S=1180, L=2270, P=6740, Y=0, Z=1088 diff --git a/testplan/decoder/13/expect4.txt b/testplan/decoder/13/expect4.txt new file mode 100644 index 0000000..307e83e --- /dev/null +++ b/testplan/decoder/13/expect4.txt @@ -0,0 +1,6 @@ +[0] Received 32 bits: 7e dc 56 78 + T=MAN, E=0, I=5436, S=1180, L=2270, P=6724, Y=0, Z=1180 +[1] Received 27 bits(!): 03 f6 e2 a3 + T=MAN, E=4, I=0, S=1180, L=2270, P=6740, Y=0, Z=1120 +[2] Received 9 bits: 00 fd + T=MAN, E=0, I=0, S=1180, L=2270, P=0, Y=0, Z=1088 diff --git a/testplan/decoder/20/code-portail1.txt b/testplan/decoder/20/code-portail1.txt new file mode 100644 index 0000000..d358515 --- /dev/null +++ b/testplan/decoder/20/code-portail1.txt @@ -0,0 +1,69 @@ +0, 14916 +356, 364 +348, 364 +348, 360 +348, 372 +340, 372 +340, 368 +348, 372 +340, 372 +344, 364 +340, 380 +340, 368 +348, 3724 +716, 380 +340, 752 +716, 380 +348, 744 +340, 752 +340, 744 +356, 740 +720, 372 +356, 740 +344, 756 +340, 744 +724, 376 +716, 376 +708, 380 +712, 388 +340, 744 +340, 752 +340, 752 +716, 380 +716, 376 +340, 752 +716, 376 +340, 752 +344, 752 +340, 752 +716, 380 +716, 376 +344, 752 +340, 752 +340, 756 +332, 760 +332, 760 +344, 752 +340, 752 +336, 760 +708, 384 +336, 760 +332, 752 +344, 752 +716, 376 +340, 756 +340, 752 +716, 384 +708, 388 +332, 760 +336, 752 +340, 752 +716, 380 +708, 392 +328, 760 +340, 752 +708, 384 +704, 388 +708, 384 +708, 388 +708, 3000 diff --git a/testplan/decoder/20/expect3.txt b/testplan/decoder/20/expect3.txt new file mode 100644 index 0000000..4cbd517 --- /dev/null +++ b/testplan/decoder/20/expect3.txt @@ -0,0 +1,4 @@ +[0] Sync 11 + T=SYN, E=0, I=14916, S(lo)=348, L(lo)=348, S(hi)=364, L(hi)=364, P=3724, Y=0, Z=348 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=356, L=734, P=3000, Y=0, Z=344 diff --git a/testplan/decoder/20/expect4.txt b/testplan/decoder/20/expect4.txt new file mode 100644 index 0000000..ff7e8d3 --- /dev/null +++ b/testplan/decoder/20/expect4.txt @@ -0,0 +1,4 @@ +[0] Sync 11 + T=SYN, E=0, I=14916, S(lo)=348, L(lo)=348, S(hi)=364, L(hi)=364, P=3724, Y=0, Z=344 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=356, L=734, P=3000, Y=0, Z=356 diff --git a/testplan/decoder/21/code-portail2.txt b/testplan/decoder/21/code-portail2.txt new file mode 100644 index 0000000..b2336ba --- /dev/null +++ b/testplan/decoder/21/code-portail2.txt @@ -0,0 +1,69 @@ +0, 14924 +340, 364 +348, 364 +348, 360 +348, 380 +332, 380 +332, 384 +328, 384 +332, 388 +324, 376 +336, 376 +340, 380 +340, 3740 +332, 760 +708, 368 +344, 760 +716, 368 +348, 752 +340, 752 +708, 380 +340, 760 +336, 760 +700, 392 +708, 384 +696, 392 +700, 400 +320, 772 +696, 392 +332, 760 +328, 768 +324, 768 +700, 396 +700, 384 +708, 396 +324, 768 +324, 768 +320, 768 +324, 768 +696, 400 +316, 772 +688, 408 +692, 400 +692, 404 +684, 408 +320, 776 +316, 768 +320, 776 +312, 784 +684, 400 +328, 768 +324, 768 +320, 776 +692, 400 +320, 776 +316, 776 +692, 404 +692, 400 +316, 772 +312, 776 +308, 780 +688, 408 +684, 408 +320, 776 +308, 784 +684, 408 +684, 408 +684, 404 +692, 400 +692, 3000 diff --git a/testplan/decoder/21/expect3.txt b/testplan/decoder/21/expect3.txt new file mode 100644 index 0000000..b44d5fe --- /dev/null +++ b/testplan/decoder/21/expect3.txt @@ -0,0 +1,4 @@ +[0] Sync 11 + T=SYN, E=0, I=14924, S(lo)=348, L(lo)=348, S(hi)=364, L(hi)=364, P=3740, Y=0, Z=340 +[1] Received 55 bits: 29 3d 1c 2f 08 98 cf + T=TRI, E=0, I=0, S=356, L=734, P=3000, Y=0, Z=316 diff --git a/testplan/decoder/21/expect4.txt b/testplan/decoder/21/expect4.txt new file mode 100644 index 0000000..3fb7e01 --- /dev/null +++ b/testplan/decoder/21/expect4.txt @@ -0,0 +1,4 @@ +[0] Sync 11 + T=SYN, E=0, I=14924, S(lo)=348, L(lo)=348, S(hi)=364, L(hi)=364, P=3740, Y=0, Z=324 +[1] Received 55 bits: 29 3d 1c 2f 08 98 cf + T=TRI, E=0, I=0, S=356, L=734, P=3000, Y=0, Z=336 diff --git a/testplan/decoder/22/code-portx.txt b/testplan/decoder/22/code-portx.txt new file mode 100644 index 0000000..8eb2715 --- /dev/null +++ b/testplan/decoder/22/code-portx.txt @@ -0,0 +1,70 @@ +0, 14916 +356, 364 +348, 364 +348, 360 +348, 372 +340, 372 +340, 368 +348, 372 +340, 372 +344, 364 +340, 380 +340, 368 +348, 3724 +716, 380 +340, 752 +716, 380 +348, 744 +340, 752 +340, 744 +356, 740 +720, 372 +356, 740 +344, 756 +340, 744 +724, 376 +716, 376 +708, 380 +712, 388 +340, 744 +340, 752 +340, 752 +716, 380 +716, 376 +340, 752 +716, 376 +340, 752 +344, 752 +340, 752 +716, 380 +716, 376 +344, 752 +340, 752 +340, 756 +332, 760 +332, 760 +344, 752 +328, 15284 +340, 388 +340, 380 +340, 376 +344, 384 +332, 388 +332, 388 +332, 384 +344, 376 +340, 388 +332, 388 +332, 384 +336, 3740 +716, 380 +340, 752 +716, 380 +348, 744 +340, 752 +340, 744 +356, 740 +720, 372 +356, 740 +336, 3740 +0, 0 diff --git a/testplan/decoder/22/expect3.txt b/testplan/decoder/22/expect3.txt new file mode 100644 index 0000000..5918b88 --- /dev/null +++ b/testplan/decoder/22/expect3.txt @@ -0,0 +1,8 @@ +[0] Sync 11 + T=SYN, E=0, I=14916, S(lo)=348, L(lo)=348, S(hi)=364, L(hi)=364, P=3724, Y=0, Z=348 +[1] Received 33 bits: 01 42 3c 68 c0 + T=TRI, E=0, I=0, S=356, L=734, P=15284, Y=0, Z=344 +[2] Sync 11 + T=SYN, E=0, I=0, S=356, L=734, P=3740, Y=0, Z=336 +[3] Received 9 bits: 01 42 + T=TRI, E=0, I=0, S=356, L=734, P=3740, Y=0, Z=336 diff --git a/testplan/decoder/22/expect4.txt b/testplan/decoder/22/expect4.txt new file mode 100644 index 0000000..f41ea2c --- /dev/null +++ b/testplan/decoder/22/expect4.txt @@ -0,0 +1,8 @@ +[0] Sync 11 + T=SYN, E=0, I=14916, S(lo)=348, L(lo)=348, S(hi)=364, L(hi)=364, P=3724, Y=0, Z=344 +[1] Received 33 bits: 01 42 3c 68 c0 + T=TRI, E=0, I=0, S=356, L=734, P=15284, Y=0, Z=356 +[2] Sync 11 + T=SYN, E=0, I=0, S=356, L=734, P=3740, Y=0, Z=340 +[3] Received 9 bits: 01 42 + T=TRI, E=0, I=0, S=356, L=734, P=3740, Y=0, Z=356 diff --git a/testplan/decoder/23/code-porty.txt b/testplan/decoder/23/code-porty.txt new file mode 100644 index 0000000..7ce518e --- /dev/null +++ b/testplan/decoder/23/code-porty.txt @@ -0,0 +1,70 @@ +0, 14916 +356, 364 +348, 364 +348, 360 +348, 372 +340, 372 +340, 368 +348, 372 +340, 372 +344, 364 +340, 380 +340, 368 +348, 3724 +716, 380 +340, 752 +716, 380 +348, 744 +340, 752 +340, 744 +356, 740 +720, 372 +356, 740 +344, 756 +340, 744 +724, 376 +716, 376 +708, 380 +712, 388 +340, 744 +340, 752 +340, 752 +716, 380 +716, 376 +340, 752 +716, 376 +340, 752 +344, 752 +340, 752 +716, 380 +716, 376 +344, 752 +340, 752 +340, 756 +332, 760 +332, 760 +344, 752 +328, 15284 +340, 388 +340, 380 +340, 376 +344, 384 +332, 388 +332, 388 +332, 384 +344, 376 +340, 388 +332, 388 +332, 384 +336, 3740 +716, 380 +340, 752 +716, 380 +348, 744 +340, 752 +340, 744 +356, 740 +720, 372 +356, 740 +340, 752 +328, 15284 diff --git a/testplan/decoder/23/expect3.txt b/testplan/decoder/23/expect3.txt new file mode 100644 index 0000000..61b8aeb --- /dev/null +++ b/testplan/decoder/23/expect3.txt @@ -0,0 +1,8 @@ +[0] Sync 11 + T=SYN, E=0, I=14916, S(lo)=348, L(lo)=348, S(hi)=364, L(hi)=364, P=3724, Y=0, Z=348 +[1] Received 33 bits: 01 42 3c 68 c0 + T=TRI, E=0, I=0, S=356, L=734, P=15284, Y=0, Z=344 +[2] Sync 11 + T=SYN, E=0, I=0, S=356, L=734, P=3740, Y=0, Z=336 +[3] Received 10 bits: 02 84 + T=TRI, E=0, I=0, S=356, L=734, P=15284, Y=0, Z=328 diff --git a/testplan/decoder/23/expect4.txt b/testplan/decoder/23/expect4.txt new file mode 100644 index 0000000..35699c0 --- /dev/null +++ b/testplan/decoder/23/expect4.txt @@ -0,0 +1,8 @@ +[0] Sync 11 + T=SYN, E=0, I=14916, S(lo)=348, L(lo)=348, S(hi)=364, L(hi)=364, P=3724, Y=0, Z=344 +[1] Received 33 bits: 01 42 3c 68 c0 + T=TRI, E=0, I=0, S=356, L=734, P=15284, Y=0, Z=356 +[2] Sync 11 + T=SYN, E=0, I=0, S=356, L=734, P=3740, Y=0, Z=340 +[3] Received 10 bits: 02 84 + T=TRI, E=0, I=0, S=356, L=734, P=15284, Y=0, Z=356 diff --git a/testplan/decoder/24/code-portail1-err.txt b/testplan/decoder/24/code-portail1-err.txt new file mode 100644 index 0000000..15e0991 --- /dev/null +++ b/testplan/decoder/24/code-portail1-err.txt @@ -0,0 +1,69 @@ +0, 14916 +356, 364 +348, 364 +348, 360 +348, 372 +340, 372 +340, 368 +348, 372 +340, 372 +344, 364 +340, 380 +340, 368 +348, 3724 +716, 380 +340, 752 +716, 380 +348, 744 +340, 752 +340, 744 +356, 740 +720, 372 +356, 740 +344, 756 +340, 744 +724, 376 +716, 376 +708, 380 +712, 388 +340, 744 +340, 752 +340, 752 +716, 380 +716, 376 +340, 752 +716, 376 +340, 752 +344, 752 +340, 752 +716, 380 +716, 376 +344, 752 +340, 752 +340, 756 +332, 760 +332, 760 +717, 752 +340, 752 +336, 760 +708, 384 +336, 760 +332, 752 +344, 752 +716, 376 +340, 756 +340, 752 +716, 384 +708, 388 +332, 760 +336, 752 +340, 752 +716, 380 +708, 392 +328, 760 +340, 752 +708, 384 +704, 388 +708, 384 +708, 388 +708, 384 diff --git a/testplan/decoder/24/expect3.txt b/testplan/decoder/24/expect3.txt new file mode 100644 index 0000000..b131121 --- /dev/null +++ b/testplan/decoder/24/expect3.txt @@ -0,0 +1,5 @@ +[0] Sync 11 + T=SYN, E=0, I=14916, S(lo)=348, L(lo)=348, S(hi)=364, L(hi)=364, P=3724, Y=0, Z=348 +[1] Unknown encoding: 66 signal bits + Signal: LS:SL:LS:SL:SL:SL:SL:LS:SL:SL:SL:LS:LS:LS:LS:SL:SL:SL:LS:LS:SL:LS:SL:SL:SL:LS:LS:SL:SL:SL:SL:SL:LL + T=UNK, E=0, I=0, S=356, L=734, P=0, Y=0, Z=717 diff --git a/testplan/decoder/24/expect4.txt b/testplan/decoder/24/expect4.txt new file mode 100644 index 0000000..cd146cf --- /dev/null +++ b/testplan/decoder/24/expect4.txt @@ -0,0 +1,4 @@ +[0] Sync 11 + T=SYN, E=0, I=14916, S(lo)=348, L(lo)=348, S(hi)=364, L(hi)=364, P=3724, Y=0, Z=344 +[1] Received 48 bits(!): a1 1e 34 60 22 63 + T=TRI, E=1, I=0, S=356, L=734, P=0, Y=0, Z=356 diff --git a/testplan/decoder/25/code-portail1-err2.txt b/testplan/decoder/25/code-portail1-err2.txt new file mode 100644 index 0000000..65ead3f --- /dev/null +++ b/testplan/decoder/25/code-portail1-err2.txt @@ -0,0 +1,55 @@ +0, 14916 +356, 364 +348, 364 +348, 360 +348, 372 +340, 372 +340, 368 +348, 372 +340, 372 +344, 364 +340, 380 +340, 368 +348, 3724 +716, 380 +340, 752 +380, 380 +340, 744 +356, 740 +720, 372 +356, 740 +344, 756 +340, 756 +340, 752 +716, 384 +708, 388 +332, 760 +336, 752 +340, 752 +716, 380 +708, 392 +328, 760 +340, 752 +708, 384 +704, 384 +332, 760 +696, 392 +700, 392 +328, 15284 +340, 388 +340, 380 +340, 376 +344, 384 +332, 388 +332, 388 +332, 388 +332, 384 +336, 3740 +708, 388 +332, 760 +708, 384 +332, 752 +340, 752 +336, 752 +340, 752 +708, 392 diff --git a/testplan/decoder/25/expect3.txt b/testplan/decoder/25/expect3.txt new file mode 100644 index 0000000..023447f --- /dev/null +++ b/testplan/decoder/25/expect3.txt @@ -0,0 +1,7 @@ +[0] Sync 11 + T=SYN, E=0, I=14916, S(lo)=348, L(lo)=348, S(hi)=364, L(hi)=364, P=3724, Y=0, Z=348 +[1] Unknown encoding: 48 signal bits + Signal: LS:SL:SS:SL:SL:LS:SL:SL:SL:SL:LS:LS:SL:SL:SL:LS:LS:SL:SL:LS:LS:SL:LS:LS:SP + T=UNK, E=0, I=0, S=356, L=736, P=15284, Y=0, Z=328 +[2] Sync 8 + T=SYN, E=0, I=0, S=356, L=736, P=3740, Y=0, Z=336 diff --git a/testplan/decoder/25/expect4.txt b/testplan/decoder/25/expect4.txt new file mode 100644 index 0000000..acd2de4 --- /dev/null +++ b/testplan/decoder/25/expect4.txt @@ -0,0 +1,7 @@ +[0] Sync 11 + T=SYN, E=0, I=14916, S(lo)=348, L(lo)=348, S(hi)=364, L(hi)=364, P=3724, Y=0, Z=344 +[1] Unknown encoding: 48 signal bits + Signal: LS:SL:SS:SL:SL:LS:SL:SL:SL:SL:LS:LS:SL:SL:SL:LS:LS:SL:SL:LS:LS:SL:LS:LS:SP + T=UNK, E=0, I=0, S=356, L=736, P=15284, Y=0, Z=340 +[2] Sync 8 + T=SYN, E=0, I=0, S=356, L=736, P=3740, Y=0, Z=336 diff --git a/testplan/decoder/30/code-sonoff1.txt b/testplan/decoder/30/code-sonoff1.txt new file mode 100644 index 0000000..0ffa9be --- /dev/null +++ b/testplan/decoder/30/code-sonoff1.txt @@ -0,0 +1,69 @@ +0, 5652 +1180, 300 +440, 924 +1164, 236 +1136, 264 +1156, 244 +408, 952 +416, 948 +1144, 256 +400, 964 +1124, 276 +400, 968 +400, 976 +1104, 304 +1088, 312 +392, 984 +1104, 296 +384, 992 +384, 992 +1096, 304 +380, 1000 +360, 1012 +1108, 304 +356, 1012 +372, 1008 +364, 10664 +1104, 308 +368, 1000 +1092, 316 +1084, 316 +1080, 328 +360, 1008 +372, 1008 +1084, 324 +364, 1008 +1080, 328 +356, 1012 +360, 1016 +1076, 332 +1076, 324 +356, 1032 +1068, 332 +340, 1040 +340, 1028 +1064, 340 +344, 1044 +332, 1040 +1052, 352 +340, 1036 +332, 1052 +324, 10688 +1068, 340 +340, 1028 +1072, 332 +1068, 344 +1052, 348 +340, 1052 +320, 1052 +1044, 348 +328, 1052 +1044, 356 +324, 1060 +328, 1052 +1036, 356 +1056, 352 +328, 1068 +1028, 364 +328, 1060 +308, 1068 diff --git a/testplan/decoder/30/expect3.txt b/testplan/decoder/30/expect3.txt new file mode 100644 index 0000000..f599694 --- /dev/null +++ b/testplan/decoder/30/expect3.txt @@ -0,0 +1,4 @@ +[0] Received 24 bits: b9 4d 24 + T=TRI, E=0, I=5652, S=338, L=1044, P=10664, Y=0, Z=364 +[1] Received 24 bits: b9 4d 24 + T=TRI, E=0, I=0, S=338, L=1044, P=10688, Y=0, Z=324 diff --git a/testplan/decoder/30/expect4.txt b/testplan/decoder/30/expect4.txt new file mode 100644 index 0000000..c882413 --- /dev/null +++ b/testplan/decoder/30/expect4.txt @@ -0,0 +1,6 @@ +[0] Received 24 bits: b9 4d 24 + T=TRI, E=0, I=5652, S=338, L=1044, P=10664, Y=0, Z=400 +[1] Received 24 bits: b9 4d 24 + T=TRI, E=0, I=0, S=338, L=1044, P=10688, Y=0, Z=364 +[2] Received 17 bits: 01 72 9a + T=TRI, E=0, I=0, S=338, L=1044, P=0, Y=0, Z=328 diff --git a/testplan/decoder/31/code-sonoff2.txt b/testplan/decoder/31/code-sonoff2.txt new file mode 100644 index 0000000..2eb3fe0 --- /dev/null +++ b/testplan/decoder/31/code-sonoff2.txt @@ -0,0 +1,69 @@ +0, 10680 +1100, 304 +368, 984 +1088, 304 +1092, 316 +1076, 324 +356, 1008 +356, 1012 +1076, 320 +348, 1024 +1064, 332 +344, 1028 +348, 1024 +1076, 332 +1076, 332 +340, 1048 +1052, 336 +340, 1044 +340, 1040 +1052, 340 +340, 1052 +324, 1044 +1052, 344 +340, 1052 +324, 1052 +328, 10700 +1060, 328 +348, 1044 +1052, 340 +1068, 340 +1060, 348 +344, 1044 +324, 1056 +1036, 348 +332, 1060 +1040, 360 +328, 1052 +328, 1052 +1036, 356 +1052, 364 +320, 1060 +1036, 372 +308, 1064 +312, 1060 +1036, 364 +320, 1068 +316, 1060 +1032, 372 +316, 1060 +320, 1060 +316, 10708 +1040, 356 +332, 1052 +1048, 352 +1048, 364 +1044, 360 +316, 1060 +320, 1052 +1044, 372 +312, 1060 +1036, 372 +308, 1068 +312, 1068 +1036, 348 +1060, 356 +328, 1060 +1028, 380 +312, 1060 +308, 1064 diff --git a/testplan/decoder/31/expect3.txt b/testplan/decoder/31/expect3.txt new file mode 100644 index 0000000..f71c6ee --- /dev/null +++ b/testplan/decoder/31/expect3.txt @@ -0,0 +1,4 @@ +[0] Received 24 bits: b9 4d 24 + T=TRI, E=0, I=10680, S=336, L=1036, P=10700, Y=0, Z=328 +[1] Received 24 bits: b9 4d 24 + T=TRI, E=0, I=0, S=336, L=1036, P=10708, Y=0, Z=316 diff --git a/testplan/decoder/31/expect4.txt b/testplan/decoder/31/expect4.txt new file mode 100644 index 0000000..e7586a3 --- /dev/null +++ b/testplan/decoder/31/expect4.txt @@ -0,0 +1,6 @@ +[0] Received 24 bits: b9 4d 24 + T=TRI, E=0, I=10680, S=336, L=1036, P=10700, Y=0, Z=348 +[1] Received 24 bits: b9 4d 24 + T=TRI, E=0, I=0, S=336, L=1036, P=10708, Y=0, Z=332 +[2] Received 17 bits: 01 72 9a + T=TRI, E=0, I=0, S=336, L=1036, P=0, Y=0, Z=312 diff --git a/testplan/decoder/32/code-sonoff1-err.txt b/testplan/decoder/32/code-sonoff1-err.txt new file mode 100644 index 0000000..90ae501 --- /dev/null +++ b/testplan/decoder/32/code-sonoff1-err.txt @@ -0,0 +1,69 @@ +0, 5652 +1180, 300 +440, 924 +1164, 236 +1136, 264 +1156, 244 +408, 952 +416, 948 +1144, 256 +400, 964 +400, 276 +400, 968 +400, 976 +1104, 304 +1088, 312 +392, 984 +1104, 296 +384, 992 +384, 992 +1096, 304 +380, 1000 +360, 1012 +1108, 304 +356, 1012 +372, 1008 +364, 10664 +1104, 308 +368, 1000 +1092, 316 +1084, 316 +1080, 328 +360, 1008 +372, 1008 +1084, 324 +364, 1008 +1080, 328 +356, 1012 +360, 1016 +1076, 332 +1076, 324 +356, 1032 +1068, 332 +340, 1040 +340, 1028 +1064, 340 +344, 1044 +332, 1040 +1052, 352 +340, 1036 +332, 1052 +324, 10688 +1068, 340 +340, 1028 +1072, 332 +1068, 344 +1052, 348 +340, 1052 +320, 1052 +1044, 348 +328, 1052 +1044, 356 +324, 1060 +328, 1052 +1036, 356 +1056, 352 +328, 1068 +1028, 364 +328, 1060 +308, 1068 diff --git a/testplan/decoder/32/expect3.txt b/testplan/decoder/32/expect3.txt new file mode 100644 index 0000000..6c0eade --- /dev/null +++ b/testplan/decoder/32/expect3.txt @@ -0,0 +1,5 @@ +[0] Unknown encoding: 48 signal bits + Signal: LS:SL:LS:LS:LS:SL:SL:LS:SL:SS:SL:SL:LS:LS:SL:LS:SL:SL:LS:SL:SL:LS:SL:SL:SP + T=UNK, E=0, I=5652, S=338, L=1044, P=10664, Y=0, Z=364 +[1] Received 24 bits: b9 4d 24 + T=TRI, E=0, I=0, S=338, L=1044, P=10688, Y=0, Z=324 diff --git a/testplan/decoder/32/expect4.txt b/testplan/decoder/32/expect4.txt new file mode 100644 index 0000000..7cceb4a --- /dev/null +++ b/testplan/decoder/32/expect4.txt @@ -0,0 +1,6 @@ +[0] Received 23 bits(!): 5c 8d 24 + T=TRI, E=1, I=5652, S=338, L=1044, P=10664, Y=0, Z=400 +[1] Received 24 bits: b9 4d 24 + T=TRI, E=0, I=0, S=338, L=1044, P=10688, Y=0, Z=364 +[2] Received 17 bits: 01 72 9a + T=TRI, E=0, I=0, S=338, L=1044, P=0, Y=0, Z=328 diff --git a/testplan/decoder/40/code-flo1.txt b/testplan/decoder/40/code-flo1.txt new file mode 100644 index 0000000..2ae4afd --- /dev/null +++ b/testplan/decoder/40/code-flo1.txt @@ -0,0 +1,53 @@ +0, 23908 +700, 644 +1340, 1356 +668, 632 +1388, 1296 +728, 604 +1388, 1292 +720, 612 +1372, 1308 +700, 632 +1344, 1352 +640, 688 +1320, 1368 +656, 23912 +724, 624 +1396, 1296 +712, 620 +1368, 1336 +672, 664 +1332, 1372 +636, 700 +1312, 1376 +664, 660 +1352, 1340 +668, 664 +1336, 1352 +664, 23936 +672, 668 +1324, 1372 +644, 692 +1320, 1372 +664, 660 +1352, 1344 +676, 656 +1344, 1344 +672, 668 +1328, 1368 +640, 700 +1308, 1380 +628, 23956 +680, 656 +1360, 1328 +692, 640 +1368, 1336 +688, 656 +1336, 1360 +640, 700 +1308, 1380 +636, 700 +1320, 1376 +648, 684 +1332, 1356 +656, 23936 diff --git a/testplan/decoder/40/expect3.txt b/testplan/decoder/40/expect3.txt new file mode 100644 index 0000000..45b017e --- /dev/null +++ b/testplan/decoder/40/expect3.txt @@ -0,0 +1,8 @@ +[0] Received 12 bits: 05 55 + T=TRN, E=0, I=23908, S=650, L=1348, P=23912, Y=650, Z=656 +[1] Received 12 bits: 05 55 + T=TRN, E=0, I=0, S=650, L=1348, P=23936, Y=650, Z=664 +[2] Received 12 bits: 05 55 + T=TRN, E=0, I=0, S=650, L=1348, P=23956, Y=650, Z=628 +[3] Received 12 bits: 05 55 + T=TRN, E=0, I=0, S=650, L=1348, P=23936, Y=650, Z=656 diff --git a/testplan/decoder/40/expect4.txt b/testplan/decoder/40/expect4.txt new file mode 100644 index 0000000..fe76ad1 --- /dev/null +++ b/testplan/decoder/40/expect4.txt @@ -0,0 +1,8 @@ +[0] Received 12 bits: 05 55 + T=TRN, E=0, I=23908, S=650, L=1348, P=23912, Y=650, Z=700 +[1] Received 12 bits: 05 55 + T=TRN, E=0, I=0, S=650, L=1348, P=23936, Y=650, Z=664 +[2] Received 12 bits: 05 55 + T=TRN, E=0, I=0, S=650, L=1348, P=23956, Y=650, Z=672 +[3] Received 12 bits: 05 55 + T=TRN, E=0, I=0, S=650, L=1348, P=23936, Y=650, Z=636 diff --git a/testplan/decoder/41/code-flo2.txt b/testplan/decoder/41/code-flo2.txt new file mode 100644 index 0000000..9404587 --- /dev/null +++ b/testplan/decoder/41/code-flo2.txt @@ -0,0 +1,60 @@ +0, 23908 +736, 596 +1368, 1344 +676, 656 +1336, 1336 +680, 636 +1372, 1308 +720, 604 +1396, 1292 +708, 616 +1376, 1320 +664, 676 +1324, 1380 +636, 23956 +700, 636 +1372, 1308 +700, 632 +1368, 1328 +704, 640 +1360, 1348 +664, 680 +1320, 1384 +632, 692 +1332, 1364 +672, 664 +1352, 1344 +636, 23964 +644, 700 +1328, 1360 +664, 676 +1344, 1344 +672, 672 +1344, 1352 +656, 676 +1332, 1372 +636, 704 +1296, 1396 +624, 708 +1316, 1380 +640, 23952 +680, 652 +1344, 1348 +676, 664 +1328, 1376 +632, 708 +1308, 1388 +636, 700 +1320, 1368 +656, 684 +1340, 1356 +648, 684 +1328, 1368 +648, 23952 +640, 700 +1316, 1380 +648, 688 +1336, 1360 +664, 668 +1344, 1360 +664, 668 diff --git a/testplan/decoder/41/expect3.txt b/testplan/decoder/41/expect3.txt new file mode 100644 index 0000000..0c0581a --- /dev/null +++ b/testplan/decoder/41/expect3.txt @@ -0,0 +1,8 @@ +[0] Received 12 bits: 05 55 + T=TRN, E=0, I=23908, S=666, L=1356, P=23956, Y=666, Z=636 +[1] Received 12 bits: 05 55 + T=TRN, E=0, I=0, S=666, L=1356, P=23964, Y=666, Z=636 +[2] Received 12 bits: 05 55 + T=TRN, E=0, I=0, S=666, L=1356, P=23952, Y=666, Z=640 +[3] Received 12 bits: 05 55 + T=TRN, E=0, I=0, S=666, L=1356, P=23952, Y=666, Z=648 diff --git a/testplan/decoder/41/expect4.txt b/testplan/decoder/41/expect4.txt new file mode 100644 index 0000000..e262718 --- /dev/null +++ b/testplan/decoder/41/expect4.txt @@ -0,0 +1,8 @@ +[0] Received 12 bits: 05 55 + T=TRN, E=0, I=23908, S=666, L=1356, P=23956, Y=666, Z=708 +[1] Received 12 bits: 05 55 + T=TRN, E=0, I=0, S=666, L=1356, P=23964, Y=666, Z=632 +[2] Received 12 bits: 05 55 + T=TRN, E=0, I=0, S=666, L=1356, P=23952, Y=666, Z=636 +[3] Received 12 bits: 05 55 + T=TRN, E=0, I=0, S=666, L=1356, P=23952, Y=666, Z=656 diff --git a/testplan/decoder/42/code-flo1-err.txt b/testplan/decoder/42/code-flo1-err.txt new file mode 100644 index 0000000..950471a --- /dev/null +++ b/testplan/decoder/42/code-flo1-err.txt @@ -0,0 +1,53 @@ +0, 23908 +700, 644 +1340, 1356 +668, 632 +1388, 1296 +728, 604 +720, 612 +1388, 1292 +1372, 1308 +700, 632 +1344, 1352 +640, 688 +1320, 1368 +656, 23912 +724, 624 +1396, 1296 +712, 620 +1368, 1336 +672, 664 +1332, 1372 +636, 700 +1312, 1376 +664, 660 +1352, 1340 +668, 664 +1336, 1352 +664, 23936 +680, 656 +1360, 1328 +692, 640 +1368, 1336 +688, 656 +1336, 1360 +640, 700 +1308, 1380 +636, 700 +636, 1376 +648, 684 +1332, 1356 +656, 23936 +672, 668 +1324, 1372 +644, 692 +1320, 1372 +664, 660 +1352, 1344 +676, 656 +1344, 1344 +672, 668 +1328, 1368 +640, 700 +1308, 1380 +628, 23956 diff --git a/testplan/decoder/42/expect3.txt b/testplan/decoder/42/expect3.txt new file mode 100644 index 0000000..9e4dd85 --- /dev/null +++ b/testplan/decoder/42/expect3.txt @@ -0,0 +1,10 @@ +[0] Unknown encoding: 24 signal bits + Signal: SS:LL:SS:LL:SS:SS:LL:LL:SS:LL:SS:LL:SP + T=UNK, E=0, I=23908, S=650, L=1348, P=23912, Y=0, Z=656 +[1] Received 12 bits: 05 55 + T=TRN, E=0, I=0, S=650, L=1348, P=23936, Y=650, Z=664 +[2] Unknown encoding: 24 signal bits + Signal: SS:LL:SS:LL:SS:LL:SS:LL:SS:SL:SS:LL:SP + T=UNK, E=0, I=0, S=650, L=1348, P=23936, Y=0, Z=656 +[3] Received 12 bits: 05 55 + T=TRN, E=0, I=0, S=650, L=1348, P=23956, Y=650, Z=628 diff --git a/testplan/decoder/42/expect4.txt b/testplan/decoder/42/expect4.txt new file mode 100644 index 0000000..d473b22 --- /dev/null +++ b/testplan/decoder/42/expect4.txt @@ -0,0 +1,9 @@ +[0] Unknown encoding: 24 signal bits + Signal: SS:LL:SS:LL:SS:SS:LL:LL:SS:LL:SS:LL:SP + T=UNK, E=0, I=23908, S=650, L=1348, P=23912, Y=0, Z=700 +[1] Received 12 bits: 05 55 + T=TRN, E=0, I=0, S=650, L=1348, P=23936, Y=650, Z=664 +[2] Received 11 bits(!): 02 ad + T=TRN, E=1, I=0, S=650, L=1348, P=23936, Y=650, Z=636 +[3] Received 12 bits: 05 55 + T=TRN, E=0, I=0, S=650, L=1348, P=23956, Y=650, Z=672 diff --git a/testplan/decoder/50/code-portaila.txt b/testplan/decoder/50/code-portaila.txt new file mode 100644 index 0000000..2127ebf --- /dev/null +++ b/testplan/decoder/50/code-portaila.txt @@ -0,0 +1,70 @@ +0, 14916 +2500, 2500 +356, 364 +348, 364 +348, 360 +348, 372 +340, 372 +340, 368 +348, 372 +340, 372 +344, 364 +340, 380 +340, 368 +348, 3724 +716, 380 +340, 752 +716, 380 +348, 744 +340, 752 +340, 744 +356, 740 +720, 372 +356, 740 +344, 756 +340, 744 +724, 376 +716, 376 +708, 380 +712, 388 +340, 744 +340, 752 +340, 752 +716, 380 +716, 376 +340, 752 +716, 376 +340, 752 +344, 752 +340, 752 +716, 380 +716, 376 +344, 752 +340, 752 +340, 756 +332, 760 +332, 760 +344, 752 +340, 752 +336, 760 +708, 384 +336, 760 +332, 752 +344, 752 +716, 376 +340, 756 +340, 752 +716, 384 +708, 388 +332, 760 +336, 752 +340, 752 +716, 380 +708, 392 +328, 760 +340, 752 +708, 384 +704, 388 +708, 384 +708, 388 +708, 3000 diff --git a/testplan/decoder/50/expect3.txt b/testplan/decoder/50/expect3.txt new file mode 100644 index 0000000..b9c1cae --- /dev/null +++ b/testplan/decoder/50/expect3.txt @@ -0,0 +1,4 @@ +[0] Sync 11 + T=SYN, E=0, I=14916, S(lo)=356, L(lo)=356, S(hi)=364, L(hi)=364, P=3724, U=2500, V=2500, Y=0, Z=348 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=360, L=734, P=3000, Y=0, Z=344 diff --git a/testplan/decoder/50/expect4.txt b/testplan/decoder/50/expect4.txt new file mode 100644 index 0000000..b56ac39 --- /dev/null +++ b/testplan/decoder/50/expect4.txt @@ -0,0 +1,4 @@ +[0] Sync 11 + T=SYN, E=0, I=14916, S(lo)=356, L(lo)=356, S(hi)=364, L(hi)=364, P=3724, U=2500, V=2500, Y=0, Z=340 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=360, L=734, P=3000, Y=0, Z=356 diff --git a/testplan/decoder/51/code-portailb.txt b/testplan/decoder/51/code-portailb.txt new file mode 100644 index 0000000..62e1524 --- /dev/null +++ b/testplan/decoder/51/code-portailb.txt @@ -0,0 +1,66 @@ +0, 14916 +2500, 2500 +356, 364 +340, 368 +348, 372 +340, 372 +344, 364 +340, 380 +340, 368 +348, 3724 +716, 380 +340, 752 +716, 380 +348, 744 +340, 752 +340, 744 +356, 740 +720, 372 +356, 740 +344, 756 +340, 744 +724, 376 +716, 376 +708, 380 +712, 388 +340, 744 +340, 752 +340, 752 +716, 380 +716, 376 +340, 752 +716, 376 +340, 752 +344, 752 +340, 752 +716, 380 +716, 376 +344, 752 +340, 752 +340, 756 +332, 760 +332, 760 +344, 752 +340, 752 +336, 760 +708, 384 +336, 760 +332, 752 +344, 752 +716, 376 +340, 756 +340, 752 +716, 384 +708, 388 +332, 760 +336, 752 +340, 752 +716, 380 +708, 392 +328, 760 +340, 752 +708, 384 +704, 388 +708, 384 +708, 388 +708, 3000 diff --git a/testplan/decoder/51/expect3.txt b/testplan/decoder/51/expect3.txt new file mode 100644 index 0000000..8da1537 --- /dev/null +++ b/testplan/decoder/51/expect3.txt @@ -0,0 +1,4 @@ +[0] Sync 7 + T=SYN, E=0, I=14916, S(lo)=356, L(lo)=356, S(hi)=364, L(hi)=364, P=3724, U=2500, V=2500, Y=0, Z=348 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=360, L=734, P=3000, Y=0, Z=344 diff --git a/testplan/decoder/51/expect4.txt b/testplan/decoder/51/expect4.txt new file mode 100644 index 0000000..991092e --- /dev/null +++ b/testplan/decoder/51/expect4.txt @@ -0,0 +1,4 @@ +[0] Sync 7 + T=SYN, E=0, I=14916, S(lo)=356, L(lo)=356, S(hi)=364, L(hi)=364, P=3724, U=2500, V=2500, Y=0, Z=348 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=360, L=734, P=3000, Y=0, Z=356 diff --git a/testplan/decoder/52/code-portailc.txt b/testplan/decoder/52/code-portailc.txt new file mode 100644 index 0000000..f6696f3 --- /dev/null +++ b/testplan/decoder/52/code-portailc.txt @@ -0,0 +1,67 @@ +0, 14916 +2500, 2500 +356, 364 +340, 368 +348, 372 +340, 372 +344, 364 +344, 364 +340, 380 +340, 368 +348, 3724 +716, 380 +340, 752 +716, 380 +348, 744 +340, 752 +340, 744 +356, 740 +720, 372 +356, 740 +344, 756 +340, 744 +724, 376 +716, 376 +708, 380 +712, 388 +340, 744 +340, 752 +340, 752 +716, 380 +716, 376 +340, 752 +716, 376 +340, 752 +344, 752 +340, 752 +716, 380 +716, 376 +344, 752 +340, 752 +340, 756 +332, 760 +332, 760 +344, 752 +340, 752 +336, 760 +708, 384 +336, 760 +332, 752 +344, 752 +716, 376 +340, 756 +340, 752 +716, 384 +708, 388 +332, 760 +336, 752 +340, 752 +716, 380 +708, 392 +328, 760 +340, 752 +708, 384 +704, 388 +708, 384 +708, 388 +708, 3000 diff --git a/testplan/decoder/52/expect3.txt b/testplan/decoder/52/expect3.txt new file mode 100644 index 0000000..0595f23 --- /dev/null +++ b/testplan/decoder/52/expect3.txt @@ -0,0 +1,4 @@ +[0] Sync 8 + T=SYN, E=0, I=14916, S(lo)=356, L(lo)=356, S(hi)=364, L(hi)=364, P=3724, U=2500, V=2500, Y=0, Z=348 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=360, L=734, P=3000, Y=0, Z=344 diff --git a/testplan/decoder/52/expect4.txt b/testplan/decoder/52/expect4.txt new file mode 100644 index 0000000..8403b04 --- /dev/null +++ b/testplan/decoder/52/expect4.txt @@ -0,0 +1,4 @@ +[0] Sync 8 + T=SYN, E=0, I=14916, S(lo)=356, L(lo)=356, S(hi)=364, L(hi)=364, P=3724, U=2500, V=2500, Y=0, Z=340 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=360, L=734, P=3000, Y=0, Z=356 diff --git a/testplan/decoder/53/code-portaild.txt b/testplan/decoder/53/code-portaild.txt new file mode 100644 index 0000000..736d4aa --- /dev/null +++ b/testplan/decoder/53/code-portaild.txt @@ -0,0 +1,66 @@ +0, 14916 +356, 364 +340, 368 +348, 372 +340, 372 +344, 364 +344, 364 +340, 380 +340, 368 +348, 3724 +716, 380 +340, 752 +716, 380 +348, 744 +340, 752 +340, 744 +356, 740 +720, 372 +356, 740 +344, 756 +340, 744 +724, 376 +716, 376 +708, 380 +712, 388 +340, 744 +340, 752 +340, 752 +716, 380 +716, 376 +340, 752 +716, 376 +340, 752 +344, 752 +340, 752 +716, 380 +716, 376 +344, 752 +340, 752 +340, 756 +332, 760 +332, 760 +344, 752 +340, 752 +336, 760 +708, 384 +336, 760 +332, 752 +344, 752 +716, 376 +340, 756 +340, 752 +716, 384 +708, 388 +332, 760 +336, 752 +340, 752 +716, 380 +708, 392 +328, 760 +340, 752 +708, 384 +704, 388 +708, 384 +708, 388 +708, 3000 diff --git a/testplan/decoder/53/expect3.txt b/testplan/decoder/53/expect3.txt new file mode 100644 index 0000000..e122720 --- /dev/null +++ b/testplan/decoder/53/expect3.txt @@ -0,0 +1,4 @@ +[0] Sync 8 + T=SYN, E=0, I=14916, S(lo)=340, L(lo)=340, S(hi)=368, L(hi)=368, P=3724, Y=0, Z=348 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=354, L=734, P=3000, Y=0, Z=344 diff --git a/testplan/decoder/53/expect4.txt b/testplan/decoder/53/expect4.txt new file mode 100644 index 0000000..0089a4e --- /dev/null +++ b/testplan/decoder/53/expect4.txt @@ -0,0 +1,4 @@ +[0] Sync 8 + T=SYN, E=0, I=14916, S(lo)=340, L(lo)=340, S(hi)=368, L(hi)=368, P=3724, Y=0, Z=348 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=354, L=734, P=3000, Y=0, Z=356 diff --git a/testplan/decoder/54/code-portaile.txt b/testplan/decoder/54/code-portaile.txt new file mode 100644 index 0000000..a0214d0 --- /dev/null +++ b/testplan/decoder/54/code-portaile.txt @@ -0,0 +1,67 @@ +0, 14916 +356, 364 +340, 368 +348, 372 +340, 372 +344, 364 +344, 364 +340, 380 +340, 368 +340, 368 +348, 3724 +716, 380 +340, 752 +716, 380 +348, 744 +340, 752 +340, 744 +356, 740 +720, 372 +356, 740 +344, 756 +340, 744 +724, 376 +716, 376 +708, 380 +712, 388 +340, 744 +340, 752 +340, 752 +716, 380 +716, 376 +340, 752 +716, 376 +340, 752 +344, 752 +340, 752 +716, 380 +716, 376 +344, 752 +340, 752 +340, 756 +332, 760 +332, 760 +344, 752 +340, 752 +336, 760 +708, 384 +336, 760 +332, 752 +344, 752 +716, 376 +340, 756 +340, 752 +716, 384 +708, 388 +332, 760 +336, 752 +340, 752 +716, 380 +708, 392 +328, 760 +340, 752 +708, 384 +704, 388 +708, 384 +708, 388 +708, 3000 diff --git a/testplan/decoder/54/expect3.txt b/testplan/decoder/54/expect3.txt new file mode 100644 index 0000000..0c357a3 --- /dev/null +++ b/testplan/decoder/54/expect3.txt @@ -0,0 +1,4 @@ +[0] Sync 9 + T=SYN, E=0, I=14916, S(lo)=340, L(lo)=340, S(hi)=368, L(hi)=368, P=3724, Y=0, Z=348 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=354, L=734, P=3000, Y=0, Z=344 diff --git a/testplan/decoder/54/expect4.txt b/testplan/decoder/54/expect4.txt new file mode 100644 index 0000000..4ce5671 --- /dev/null +++ b/testplan/decoder/54/expect4.txt @@ -0,0 +1,4 @@ +[0] Sync 9 + T=SYN, E=0, I=14916, S(lo)=340, L(lo)=340, S(hi)=368, L(hi)=368, P=3724, Y=0, Z=340 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=354, L=734, P=3000, Y=0, Z=356 diff --git a/testplan/decoder/55/code-portailf.txt b/testplan/decoder/55/code-portailf.txt new file mode 100644 index 0000000..8abc913 --- /dev/null +++ b/testplan/decoder/55/code-portailf.txt @@ -0,0 +1,68 @@ +0, 14916 +356, 364 +340, 368 +348, 372 +348, 372 +340, 372 +344, 364 +344, 364 +340, 380 +340, 368 +340, 368 +348, 3724 +716, 380 +340, 752 +716, 380 +348, 744 +340, 752 +340, 744 +356, 740 +720, 372 +356, 740 +344, 756 +340, 744 +724, 376 +716, 376 +708, 380 +712, 388 +340, 744 +340, 752 +340, 752 +716, 380 +716, 376 +340, 752 +716, 376 +340, 752 +344, 752 +340, 752 +716, 380 +716, 376 +344, 752 +340, 752 +340, 756 +332, 760 +332, 760 +344, 752 +340, 752 +336, 760 +708, 384 +336, 760 +332, 752 +344, 752 +716, 376 +340, 756 +340, 752 +716, 384 +708, 388 +332, 760 +336, 752 +340, 752 +716, 380 +708, 392 +328, 760 +340, 752 +708, 384 +704, 388 +708, 384 +708, 388 +708, 3000 diff --git a/testplan/decoder/55/expect3.txt b/testplan/decoder/55/expect3.txt new file mode 100644 index 0000000..3ce09f4 --- /dev/null +++ b/testplan/decoder/55/expect3.txt @@ -0,0 +1,4 @@ +[0] Sync 10 + T=SYN, E=0, I=14916, S(lo)=340, L(lo)=340, S(hi)=368, L(hi)=368, P=3724, Y=0, Z=348 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=354, L=734, P=3000, Y=0, Z=344 diff --git a/testplan/decoder/55/expect4.txt b/testplan/decoder/55/expect4.txt new file mode 100644 index 0000000..2fc9d0f --- /dev/null +++ b/testplan/decoder/55/expect4.txt @@ -0,0 +1,4 @@ +[0] Sync 10 + T=SYN, E=0, I=14916, S(lo)=340, L(lo)=340, S(hi)=368, L(hi)=368, P=3724, Y=0, Z=340 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=354, L=734, P=3000, Y=0, Z=356 diff --git a/testplan/decoder/56/code-portailg.txt b/testplan/decoder/56/code-portailg.txt new file mode 100644 index 0000000..7d6c8e9 --- /dev/null +++ b/testplan/decoder/56/code-portailg.txt @@ -0,0 +1,68 @@ +0, 14916 +3000, 3000 +356, 364 +340, 368 +348, 372 +340, 372 +344, 364 +344, 364 +340, 380 +340, 368 +340, 368 +348, 3724 +716, 380 +340, 752 +716, 380 +348, 744 +340, 752 +340, 744 +356, 740 +720, 372 +356, 740 +344, 756 +340, 744 +724, 376 +716, 376 +708, 380 +712, 388 +340, 744 +340, 752 +340, 752 +716, 380 +716, 376 +340, 752 +716, 376 +340, 752 +344, 752 +340, 752 +716, 380 +716, 376 +344, 752 +340, 752 +340, 756 +332, 760 +332, 760 +344, 752 +340, 752 +336, 760 +708, 384 +336, 760 +332, 752 +344, 752 +716, 376 +340, 756 +340, 752 +716, 384 +708, 388 +332, 760 +336, 752 +340, 752 +716, 380 +708, 392 +328, 760 +340, 752 +708, 384 +704, 388 +708, 384 +708, 388 +708, 3000 diff --git a/testplan/decoder/56/expect3.txt b/testplan/decoder/56/expect3.txt new file mode 100644 index 0000000..bd3c65f --- /dev/null +++ b/testplan/decoder/56/expect3.txt @@ -0,0 +1,4 @@ +[0] Sync 9 + T=SYN, E=0, I=14916, S(lo)=356, L(lo)=356, S(hi)=364, L(hi)=364, P=3724, U=3000, V=3000, Y=0, Z=348 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=360, L=734, P=3000, Y=0, Z=344 diff --git a/testplan/decoder/56/expect4.txt b/testplan/decoder/56/expect4.txt new file mode 100644 index 0000000..07edaa6 --- /dev/null +++ b/testplan/decoder/56/expect4.txt @@ -0,0 +1,4 @@ +[0] Sync 9 + T=SYN, E=0, I=14916, S(lo)=356, L(lo)=356, S(hi)=364, L(hi)=364, P=3724, U=3000, V=3000, Y=0, Z=340 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=360, L=734, P=3000, Y=0, Z=356 diff --git a/testplan/decoder/57/code-portailh.txt b/testplan/decoder/57/code-portailh.txt new file mode 100644 index 0000000..d3c1a03 --- /dev/null +++ b/testplan/decoder/57/code-portailh.txt @@ -0,0 +1,69 @@ +0, 14916 +1200, 1200 +356, 364 +340, 368 +348, 372 +348, 372 +340, 372 +344, 364 +344, 364 +340, 380 +340, 368 +340, 368 +348, 3724 +716, 380 +340, 752 +716, 380 +348, 744 +340, 752 +340, 744 +356, 740 +720, 372 +356, 740 +344, 756 +340, 744 +724, 376 +716, 376 +708, 380 +712, 388 +340, 744 +340, 752 +340, 752 +716, 380 +716, 376 +340, 752 +716, 376 +340, 752 +344, 752 +340, 752 +716, 380 +716, 376 +344, 752 +340, 752 +340, 756 +332, 760 +332, 760 +344, 752 +340, 752 +336, 760 +708, 384 +336, 760 +332, 752 +344, 752 +716, 376 +340, 756 +340, 752 +716, 384 +708, 388 +332, 760 +336, 752 +340, 752 +716, 380 +708, 392 +328, 760 +340, 752 +708, 384 +704, 388 +708, 384 +708, 388 +708, 3000 diff --git a/testplan/decoder/57/expect3.txt b/testplan/decoder/57/expect3.txt new file mode 100644 index 0000000..777f9bd --- /dev/null +++ b/testplan/decoder/57/expect3.txt @@ -0,0 +1,4 @@ +[0] Sync 10 + T=SYN, E=0, I=14916, S(lo)=356, L(lo)=356, S(hi)=364, L(hi)=364, P=3724, U=1200, V=1200, Y=0, Z=348 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=360, L=734, P=3000, Y=0, Z=344 diff --git a/testplan/decoder/57/expect4.txt b/testplan/decoder/57/expect4.txt new file mode 100644 index 0000000..90b9192 --- /dev/null +++ b/testplan/decoder/57/expect4.txt @@ -0,0 +1,4 @@ +[0] Sync 10 + T=SYN, E=0, I=14916, S(lo)=356, L(lo)=356, S(hi)=364, L(hi)=364, P=3724, U=1200, V=1200, Y=0, Z=340 +[1] Received 55 bits: 50 8f 1a 30 08 98 cf + T=TRI, E=0, I=0, S=360, L=734, P=3000, Y=0, Z=356 diff --git a/testplan/exectest.sh b/testplan/exectest.sh new file mode 100755 index 0000000..cd6dcc2 --- /dev/null +++ b/testplan/exectest.sh @@ -0,0 +1,25 @@ +#!/usr/bin/bash + +set -euo pipefail + +INPFILE=${1:-} +OUTFILE=${2:-} +PORT=${3:-} + +if [ -z "${PORT}" ] || [ -n "${4:-}" ]; then + echo "Usage:" + echo " exectest.sh INPFILE OUTFILE PORT" + echo "Example:" + echo " exectest.sh codes.txt results.txt /dev/ttyUSB0" + exit 1 +fi + +../read_test_result_from_board.sh "${PORT}" > "${OUTFILE}" & + +sleep 0.2 + +cat "${INPFILE}" > "${PORT}" +echo "." > "${PORT}" + +wait + diff --git a/testplan/read_test_result_from_board.sh b/testplan/read_test_result_from_board.sh new file mode 100755 index 0000000..5d14e84 --- /dev/null +++ b/testplan/read_test_result_from_board.sh @@ -0,0 +1,44 @@ +#!/usr/bin/bash + +# read_test_result_from_board.sh + +# Copyright 2021 Sébastien Millet + +# Read the test result from the board on PORT specified as argument, typically +# /dev/ttyUSB0. +# The test result is supposed enclosed between +# ----- BEGIN TEST ----- +# and +# ----- END TEST ----- +# lines. + +set -euo pipefail + +# Trick to read line by line in bash: +# https://stackoverflow.com/questions/10929453/read-a-file-line-by-line-assigning-the-value-to-a-variable + +REC=0 + +PORT=${1:-} + +if [ -z "${PORT}" ] || [ -n "${2-}" ]; then + echo "Usage:" + echo " read_test_result_from_board.sh PORT" + echo "For example:" + echo " read_test_result_from_board.sh /dev/ttyUSB0" + exit 1 +fi + +while IFS= read -r l; do + if [ "${l}" == "----- END TEST -----" ]; then + exit 0 + fi + if [ $REC -eq 1 ]; then + echo "${l}" + fi + if [ "${l}" == "----- BEGIN TEST -----" ]; then + REC=1 + fi +done < "${PORT}" + +exit 1 diff --git a/testplan/test/Makefile b/testplan/test/Makefile new file mode 100644 index 0000000..ba06c3f --- /dev/null +++ b/testplan/test/Makefile @@ -0,0 +1,10 @@ +ARDUINO_DIR = /usr/share/arduino +ARDUINO_LIBS = RF433any +ARDMK_DIR = /home/sebastien/.arduino_mk + +# USER_LIB_PATH = /home/sebastien/travail/cpp/seb/arduino/libraries + +BOARD_TAG = uno +MCU = atmega328 + +include $(ARDMK_DIR)/Arduino.mk diff --git a/testplan/test/am b/testplan/test/am new file mode 100755 index 0000000..e0d6bd7 --- /dev/null +++ b/testplan/test/am @@ -0,0 +1,345 @@ +#!/usr/bin/bash + +# am +# Has an update specific to RF433any library (RF433ANY_TESTPLAN macro used +# instead of TESTPLAN). + +# Copyright 2019, 2020, 2021 Sébastien Millet + +# Can perform the following: +# 1. Compile the code +# 2. Upload to Arduino +# 3. Read (continually) what is arriving from the USB port the Arduino is +# connected to + +# Versions history (as of 1.3) +# 1.3 Output from Arduino is recorded in files named with numbers instead of +# date-time string. +# 1.4 Adds -t (--testplan) option, to set TESTPLAN macro +# 1.5 -t (or --testplan) now comes with a value, so as to manage multiple test +# plans. +# 1.6 Updated to work fine with Arch arduino package instead of the manually +# installed (from tar.gz source) package used so far. +# 1.7 Renames archlinux-arduino back to arduino, and created corresponding +# symlink (was cleaner to do s). + +set -euo pipefail + +VERSION=1.7 + +PORT= +BOARD= +SPEED= +FQBN= +BUILDDIR= +RECORDDIR=out +READSPEED= +RECORDFILE= + +UPLOAD="no" +VERBOSE="no" +CATUSB="no" +STTY="no" +RECORDUSB="no" +COMPILE="yes" +TESTPLAN= + +DISPLAYSEP=no + +function finish { + if [ "${DISPLAYSEP}" == "yes" ]; then + echo "-----END ARDUINO OUTPUT-----" | tee -a "${RECORDFILE}" + fi +} + +trap finish EXIT + +function usage { + echo "Usage:" + echo " am [OPTIONS...] FILE" + echo "Compile FILE using arduino-builder." + echo "Example: am sketch.ino" + echo "" + echo "ENVIRONMENT VARIABLES" + echo " If ARDUINO_USER_LIBS is defined and non empty, then arduino-builder" + echo " is called with the supplementary option -libraries followed by" + echo " ARDUINO_USER_LIBS' value." + echo "" + echo "OPTIONS" + echo " -h --help Display this help screen" + echo " -V --version Output version information and quit" + echo " -v --verbose Be more talkative" + echo " -u --upload Upload compiled code into Arduino" + echo " -b --board Board, either 'uno' or 'nano'" + echo " -p --port Port, for ex. '/dev/ttyUSB0'" + echo " -s --speed Upload speed, for ex. 115200" + echo " Normally, speed is infered from device type:" + echo " 115200 for Uno, 57600 for Nano" + echo " -B --fqbn Board Fully Qualified Name, like 'arduino:avr:uno'" + echo " -d --builddir Build directory" + echo " -c --catusb Display (continually) what Arduino writes on USB" + echo " --stty Tune stty properly for later communication (implied" + echo " by --catusb)" + echo " -r --recordusb Write USB (continually) to a file (implies -c)" + echo " --recordfile Output file if -r option is set" + echo " -n --nocompile Don't compile code" + echo " --readspeed Read speed of USB. If not specified, this script" + echo " will try to infere it from source file. If it" + echo " fails, it'll fallback to 9600." + echo " This option is useful only if USB is read" + echo " (-c or --stty option set)" + echo " -t --testplan Set TESTPLAN macro value" + echo " (as if #define TESTPLAN VALUE)" + exit 1 +} + +function version { + echo "am version ${VERSION}" + exit +} + +OPTS=$(getopt -o hVvub:p:s:B:d:crnt: --long help,version,verbose,upload,board:,port:,speed:,fqbn:,builddir:,catusb,stty,recordusb,nocompile,readspeed:,recordfile:,testplan: -n 'am' -- "$@") + +eval set -- "$OPTS" + +while true; do + case "$1" in + -h | --help ) usage; shift ;; + -V | --version ) version; shift ;; + -v | --verbose ) VERBOSE="yes"; shift ;; + -u | --upload ) UPLOAD="yes"; shift ;; + -b | --board ) BOARD="$2"; shift 2 ;; + -p | --port ) PORT="$2"; shift 2 ;; + -s | --speed ) SPEED="$2"; shift 2 ;; + -B | --fqbn ) FQBN="$2"; shift 2 ;; + -d | --builddir ) BUILDDIR="$2"; shift 2 ;; + -c | --catusb ) CATUSB="yes"; shift ;; + -r | --recordusb ) RECORDUSB="yes"; CATUSB="yes"; shift ;; + -n | --nocompile ) COMPILE="no"; shift ;; + --readspeed ) READSPEED="$2"; shift 2 ;; + --recordfile ) RECORDFILE="$2"; shift 2 ;; + --stty ) STTY="yes"; shift ;; + -t | --testplan ) TESTPLAN="$2"; shift 2 ;; + -- ) shift; break ;; + * ) break ;; + esac +done + +FILE=${1:-} +TRAILINGOPTS=${2:-} + +if [ -n "${TRAILINGOPTS}" ]; then + echo "Error: trailing options" + exit 1; +fi +if [ -z "${FILE}" ]; then + echo "Error: no input file" + exit 1; +fi + +set +e + +if [ -n "${BOARD}" ]; then + if [ "${BOARD}" != "uno" ] && [ "${BOARD}" != "nano" ]; then + echo "Error: board '${BOARD}' unknown" + exit 1 + fi +fi + +#ARDUINODIR=$(LANG='' type -a arduino \ +# | tail -n 1 \ +# | sed 's/\S\+\sis\s//') +#ARDUINODIR=$(readlink -f "${ARDUINODIR}") +#ARDUINODIR=$(dirname "${ARDUINODIR}") + +ARDUINODIR=/usr/share/arduino + +COUNTUNO=$(compgen -G '/dev/ttyACM*' | wc -l) +COUNTNANO=$(compgen -G '/dev/ttyUSB*' | wc -l) + +if [ -z "${BOARD}" ]; then + if [ "${COUNTUNO}" -ge 1 ] && [ "${COUNTNANO}" -ge 1 ]; then + echo "Error: cannot guess board, found ${COUNTUNO} uno(s), ${COUNTNANO} nano(s)" + exit 10 + fi + if [ "${COUNTUNO}" -ge 1 ]; then + BOARD=uno + elif [ "${COUNTNANO}" -ge 1 ]; then + BOARD=nano + fi + if [ -z "${BOARD}" ]; then + echo "Error: cannot guess board, none found"; + exit 10 + fi +fi + +if [ "${UPLOAD}" == "yes" ] || [ "${CATUSB}" == "yes" ]; then + if [ -z "${PORT}" ]; then + if [ "${BOARD}" == "uno" ]; then + COUNT=${COUNTUNO} + PORT=$(compgen -G '/dev/ttyACM*') + elif [ "${BOARD}" == "nano" ]; then + COUNT=${COUNTNANO} + PORT=$(compgen -G '/dev/ttyUSB*') + else + echo "FATAL #001, CHECK THIS CODE" + exit 99 + fi + + if [ "${COUNT}" -ge 2 ]; then + echo "Error: cannot guess port, more than 1 board '${BOARD}' found" + exit 10 + fi + if [ -z "${PORT}" ]; then + echo "Error: cannot guess port, none found" + exit 10 + fi + fi + + if [ -z "${SPEED}" ]; then + if [ "${BOARD}" == "uno" ]; then + SPEED=115200 + elif [ "${BOARD}" == "nano" ]; then + SPEED=57600 + else + echo "FATAL #002, CHECK THIS CODE" + exit 99 + fi + fi + + if [ ! -e "${PORT}" ]; then + echo "Error: port not found" + exit 10 + fi +fi + +if [ -z "${FQBN}" ]; then + if [ "${BOARD}" == "uno" ]; then + FQBN="arduino:avr:uno" + elif [ "${BOARD}" == "nano" ]; then + FQBN="arduino:avr:nano:cpu=atmega328old" + else + echo "FATAL #003, CHECK THIS CODE" + exit 99 + fi +fi + +if [ -z "${BUILDDIR}" ]; then + if [[ "${FILE}" == */* ]]; then + BUILDDIR=${FILE%/*} + BUILDDIR="${BUILDDIR%/}/build" + else + BUILDDIR=build + fi +fi + +if [ "${RECORDUSB}" == "yes" ]; then + if [ -z "${RECORDFILE}" ]; then + V=${FILE##*/} + V=${V%.*} + V=${V:-out} + PREV= + for i in {15..00}; do + F="${RECORDDIR}/${V}-$i.txt" + if [ -e "${F}" ] && [ -n "${PREV}" ]; then + mv "${F}" "${PREV}" + fi + PREV="${F}" + done + RECORDFILE="${F}" + mkdir -p "${RECORDDIR}" + fi +else + RECORDFILE="/dev/null" +fi + +if [ "${VERBOSE}" == "yes" ]; then + echo "-- Settings" + echo "Arduino dir: ${ARDUINODIR}" + echo "Board: ${BOARD}" + echo "Port: ${PORT}" + echo "Speed: ${SPEED}" + echo "Fqbn: ${FQBN}" + echo "Upload: ${UPLOAD}" + echo "Catusb: ${CATUSB}" + echo "Recordusb: ${RECORDUSB}" + echo "Record file: ${RECORDFILE}" + echo "Verbose: ${VERBOSE}" + echo "File: ${FILE}" + echo "Build dir: ${BUILDDIR}" +fi + +set -e + +if [ "${COMPILE}" == "yes" ]; then + echo "-- Compile" + + mkdir -p "${BUILDDIR}" + + OPT_LIB= + TMP_ULIB=${ARDUINO_USER_LIBS:-} + if [ -n "${TMP_ULIB}" ]; then + OPT_LIB="-libraries ""${TMP_ULIB}""" + fi + + TESTPLAN_OPT="" + if [ -n "${TESTPLAN}" ]; then + TESTPLAN_OPT="-prefs=build.extra_flags=-DRF433ANY_TESTPLAN=${TESTPLAN}" + fi + + # shellcheck disable=SC2086 + # (We don't want to quote OPT_LIB as it can contain multiple options.) + "${ARDUINODIR}/arduino-builder" \ + -hardware "${ARDUINODIR}/hardware" \ + -tools "${ARDUINODIR}/hardware/tools/avr" \ + -tools "${ARDUINODIR}/tools-builder" \ + -built-in-libraries "${ARDUINODIR}/libraries" \ + ${OPT_LIB} \ + -fqbn "${FQBN}" \ + -build-path "${BUILDDIR}" \ + ${TESTPLAN_OPT} \ + "${FILE}" +fi + +FILEBASENAME=${FILE##*/} + +if [ "${UPLOAD}" == "yes" ]; then + echo "-- Upload" + "/usr/bin/avrdude" \ + -q -q -patmega328p -carduino -P"${PORT}" -b"${SPEED}" -D \ + -Uflash:w:"${BUILDDIR}/${FILEBASENAME}".hex:i +fi + +if [ "${CATUSB}" == "yes" ] || [ "${STTY}" == "yes" ]; then + if [ -z "${READSPEED}" ]; then + TFILE=$(mktemp) + gcc -fpreprocessed -dD -x c++ -E "${FILE}" > "${TFILE}" + for sp in 9600 19200 28800 38400 57600 115200; do + if grep ${sp} "${TFILE}" > /dev/null; then + READSPEED=${sp} + fi + done + READSPEED=${READSPEED:-9600} + rm "${TFILE}" + fi + + stty -F "${PORT}" -hupcl -echo "${READSPEED}" + echo "-- usb setup with speed ${READSPEED}" +fi + +if [ "${CATUSB}" == "yes" ]; then + echo "-- Read usb (Ctrl-C to quit)" + DISPLAYSEP=yes + { + echo "speed=${READSPEED}" + echo "fqbn=${FQBN}" + echo "port=${PORT}" + echo "file=${FILE}" + echo "filedate=$(date +"%Y-%m-%dT%H:%M:%SZ" -d @$(stat -c '%Y' "${FILE}"))" + echo "date=$(date +'%Y-%m-%dT%H:%M:%SZ')" + echo "" + echo "-----BEGIN ARDUINO OUTPUT-----" + } | tee "${RECORDFILE}" + tee -a "${RECORDFILE}" < "${PORT}" +fi + diff --git a/testplan/test/test.ino b/testplan/test/test.ino new file mode 100644 index 0000000..618803d --- /dev/null +++ b/testplan/test/test.ino @@ -0,0 +1,177 @@ +// test.ino + +// Perform RF433any library test plan + +/* + Copyright 2021 Sébastien Millet + + `RF433any' is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + `RF433any' is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + . +*/ + +// +// Schematic: see RF433any library +// + +#define PIN_RFINPUT 2 + +#include "RF433any.h" +#include "Serial.h" +#include + +extern uint16_t sim_timings_count; +extern unsigned int counter; +extern unsigned int sim_int_count; +extern char buffer[SERIAL_LINE_BUF_LEN]; +extern SerialLine sl; +extern uint16_t sim_timings[SIM_TIMINGS_LEN]; +extern unsigned int sim_int_count_svg; + +bool filter_mask_set; +uint16_t filter_mask; + +void setup() { + pinMode(PIN_RFINPUT, INPUT); + Serial.begin(115200); +} + +Track track(PIN_RFINPUT); + +void read_simulated_timings_from_usb() { + filter_mask_set = false; + sim_timings_count = 0; + sim_int_count = 0; + counter = 0; + buffer[0] = '\0'; + for ( ; + strcmp(buffer, "."); + sl.get_line_blocking(buffer, sizeof(buffer)) + ) { + + if (!strlen(buffer)) + continue; + + char *p = buffer; + while (*p != ',' && *p != '\0') + ++p; + if (*p != ',') { + dbg("FATAL: each line must have a ',' character!"); + assert(false); + } + + *p = '\0'; + unsigned int l = atoi(buffer); + unsigned int h = atoi(p + 1); + + if (sim_timings_count >= + sizeof(sim_timings) / sizeof(*sim_timings) - 1) { + dbg("FATAL: timings buffer full!"); + assert(false); + } + +#if RF433ANY_TESTPLAN == 5 + if (!filter_mask_set) { + filter_mask_set = true; + filter_mask = l; + } else { + sim_timings[sim_timings_count++] = l; + sim_timings[sim_timings_count++] = h; + } +#else + sim_timings[sim_timings_count++] = l; + sim_timings[sim_timings_count++] = h; +#endif + } +} + +#if RF433ANY_TESTPLAN == 5 +void output_decoder(Decoder *pdec) { + while(pdec) { + int nb_bits = pdec->get_nb_bits(); + BitVector *pdata = pdec->take_away_data(); + + dbgf("Decoded: %s, err: %d, code: %c, " + "rep: %d, bits: %2d", + (pdec->data_got_decoded() ? "yes" : "no "), + pdec->get_nb_errors(), pdec->get_id_letter(), + pdec->get_repeats() + 1, nb_bits); + + if (pdec->data_got_decoded()) { + Serial.print(" Data: "); + if (pdata) { + char *buf = pdata->to_str(); + if (buf) { + Serial.print(buf); + free(buf); + } + delete pdata; + } + Serial.print("\n"); + } + pdec = pdec->get_next(); + } +} +#endif + +void loop() { + if (sim_int_count >= sim_timings_count) + read_simulated_timings_from_usb(); + + if (!counter) { + delay(100); + dbg("----- BEGIN TEST -----"); +#ifdef RF433ANY_DBG_TRACK + dbg("["); +#endif + } + + ++counter; + + track.treset(); + sim_int_count_svg = sim_int_count; + while (track.get_trk() != TRK_DATA && sim_int_count <= sim_timings_count) { + for (int i = 0; i < 2; ++i) { + Track::ih_handle_interrupt(); + } + track.do_events(); + } + track.force_stop_recv(); + +#ifdef DBG_TIMINGS + track.dbg_timings(); +#endif + +#ifdef RF433ANY_DBG_TRACK + if (sim_int_count >= sim_timings_count) { + dbg("]"); + } +#endif + + Decoder *pdec = track.get_data(filter_mask); + if (pdec) { +#ifdef RF433ANY_DBG_DECODER + pdec->dbg_decoder(2); +#endif +#if RF433ANY_TESTPLAN == 5 + output_decoder(pdec); +#endif + delete pdec; + } + + if (sim_int_count >= sim_timings_count) { + dbg("----- END TEST -----"); + } +} + +// vim: ts=4:sw=4:tw=80:et diff --git a/testplan/track/01/code-simple.txt b/testplan/track/01/code-simple.txt new file mode 100644 index 0000000..f73b450 --- /dev/null +++ b/testplan/track/01/code-simple.txt @@ -0,0 +1,35 @@ +0 , 9604 +1236, 576 +536, 1280 +1232, 608 +1232, 596 +528, 1292 +1228, 600 +1228, 608 +528, 1316 +1228, 632 +524, 1332 +528, 1316 +1228, 628 +532, 1328 +1232, 596 +528, 1276 +1228, 600 +524, 1284 +1224, 596 +1224, 604 +524, 1312 +1224, 624 +1224, 628 +524, 1336 +1224, 604 +520, 1316 +520, 1324 +520, 1284 +524, 1344 +524, 1296 +524, 1304 +520, 1328 +521, 1268 +522, 7020 +0, 0 diff --git a/testplan/track/01/expect1.txt b/testplan/track/01/expect1.txt new file mode 100644 index 0000000..be501a8 --- /dev/null +++ b/testplan/track/01/expect1.txt @@ -0,0 +1,18 @@ +[ + { + "N":70,"start":0,"end":69, + "trk":TRK_RECV,"xorval":0x244048FF, + "r_low":{ + "bits":32,"v":0x6D2ADA00,"railstatus":"full","n":2, + "b_short":{"inf":201,"mid":536,"sup":884}, + "b_long":{"inf":885,"mid":1232,"sup":2002}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":31,"v":0x496A92FF,"railstatus":"stop received","n":2, + "b_short":{"inf":228,"mid":608,"sup":944}, + "b_long":{"inf":945,"mid":1280,"sup":2080}, + "b_sep":{"inf":4387,"mid":7020,"sup":65535} + } + } +] diff --git a/testplan/track/01/expect2.txt b/testplan/track/01/expect2.txt new file mode 100644 index 0000000..b3ac3e1 --- /dev/null +++ b/testplan/track/01/expect2.txt @@ -0,0 +1,6 @@ +IH_max_pending_timings = 2 +> nb_sections = 1, initseq = 9604 + 00 SSEP + sep = 7020 + low: [2] n = 32, v = 0x6D2ADA00 + high: [2] n = 31, v = 0x496A92FF diff --git a/testplan/track/02/code-err.txt b/testplan/track/02/code-err.txt new file mode 100644 index 0000000..ef11348 --- /dev/null +++ b/testplan/track/02/code-err.txt @@ -0,0 +1,12 @@ +0, 75000, + 248, 500, + 248, 496, + 244, 504, + 244, 504, + 240, 504, + 244, 504, + 244, 504, + 240, 508, + 240, 3868, + 228, 888, +100, 100, diff --git a/testplan/track/02/expect1.txt b/testplan/track/02/expect1.txt new file mode 100644 index 0000000..b0e15e1 --- /dev/null +++ b/testplan/track/02/expect1.txt @@ -0,0 +1,18 @@ +[ + { + "N":24,"start":0,"end":21, + "trk":TRK_RECV,"xorval":0x00000000, + "r_low":{ + "bits":8,"v":0x00000000,"railstatus":"closed","n":1, + "b_short":{"inf":186,"mid":248,"sup":310}, + "b_long":{"inf":186,"mid":248,"sup":310}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":7,"v":0x00000000,"railstatus":"stop received","n":1, + "b_short":{"inf":372,"mid":496,"sup":620}, + "b_long":{"inf":372,"mid":496,"sup":620}, + "b_sep":{"inf":2417,"mid":3868,"sup":65535} + } + } +] diff --git a/testplan/track/02/expect2.txt b/testplan/track/02/expect2.txt new file mode 100644 index 0000000..2008113 --- /dev/null +++ b/testplan/track/02/expect2.txt @@ -0,0 +1,6 @@ +IH_max_pending_timings = 2 +> nb_sections = 1, initseq = 9464 + 00 SSEP + sep = 3868 + low: [1] n = 8, v = 0x00000000 + high: [1] n = 7, v = 0x00000000 diff --git a/testplan/track/03/code-err1.txt b/testplan/track/03/code-err1.txt new file mode 100644 index 0000000..da20736 --- /dev/null +++ b/testplan/track/03/code-err1.txt @@ -0,0 +1,13 @@ +0, 65000, + 249, 500, + 248, 496, + 244, 504, + 240, 504, + 240, 504, + 240, 504, + 400, 504, + 240, 508, + 900, 3868, + 100, 10, + 100, 100, +0, 14999, diff --git a/testplan/track/03/expect1.txt b/testplan/track/03/expect1.txt new file mode 100644 index 0000000..327b8aa --- /dev/null +++ b/testplan/track/03/expect1.txt @@ -0,0 +1,18 @@ +[ + { + "N":26,"start":0,"end":21, + "trk":TRK_RECV,"xorval":0x00000002, + "r_low":{ + "bits":7,"v":0x00000002,"railstatus":"stop received","n":2, + "b_short":{"inf":93,"mid":248,"sup":324}, + "b_long":{"inf":325,"mid":400,"sup":650}, + "b_sep":{"inf":562,"mid":900,"sup":65535} + }, + "r_high":{ + "bits":7,"v":0x00000000,"railstatus":"stop received","n":1, + "b_short":{"inf":372,"mid":496,"sup":620}, + "b_long":{"inf":372,"mid":496,"sup":620}, + "b_sep":{"inf":2417,"mid":3868,"sup":65535} + } + } +] diff --git a/testplan/track/03/expect2.txt b/testplan/track/03/expect2.txt new file mode 100644 index 0000000..06ecb58 --- /dev/null +++ b/testplan/track/03/expect2.txt @@ -0,0 +1,6 @@ +IH_max_pending_timings = 3 +> nb_sections = 1, initseq = 65000 + 00 2SEP + sep = 3868 + low: [2] n = 7, v = 0x00000002 + high: [1] n = 7, v = 0x00000000 diff --git a/testplan/track/04/code-errn.txt b/testplan/track/04/code-errn.txt new file mode 100644 index 0000000..7c01ef0 --- /dev/null +++ b/testplan/track/04/code-errn.txt @@ -0,0 +1,62 @@ +0, 15000, + 248, 500, + 248, 496, + 244, 504, + 240, 504, + 240, 504, + 240, 504, + 244, 504, + 240, 508, + 240, 3868, + 228, 888, +100, 100, + 0, 15000, + 249, 500, + 248, 496, + 244, 504, + 240, 504, + 400, 504, + 240, 508, + 240, 508, + 240, 508, + 940, 3868, + 900, 888, + 100, 100, +0, 15000, + 249, 500, + 248, 496, + 244, 504, + 240, 504, + 400, 504, + 400, 504, + 400, 504, + 240, 508, + 940, 10, + 0, 0, + 100, 100, +0, 15000, + 249, 500, + 248, 496, + 244, 504, + 240, 504, + 240, 504, + 240, 504, + 400, 504, + 240, 508, + 900, 500, + 100, 10, + 100, 100, +0, 14999, + 247, 501, + 248, 496, + 244, 504, + 240, 504, + 240, 504, + 240, 508, + 240, 508, + 240, 508, + 2000, 1008, + 100, 500, + 100, 100, +100, 100, +100, 100, diff --git a/testplan/track/04/expect1.txt b/testplan/track/04/expect1.txt new file mode 100644 index 0000000..ea3fbb2 --- /dev/null +++ b/testplan/track/04/expect1.txt @@ -0,0 +1,86 @@ +[ + { + "N":124,"start":0,"end":21, + "trk":TRK_RECV,"xorval":0x00000000, + "r_low":{ + "bits":8,"v":0x00000000,"railstatus":"closed","n":1, + "b_short":{"inf":186,"mid":248,"sup":310}, + "b_long":{"inf":186,"mid":248,"sup":310}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":7,"v":0x00000000,"railstatus":"stop received","n":1, + "b_short":{"inf":372,"mid":496,"sup":620}, + "b_long":{"inf":372,"mid":496,"sup":620}, + "b_sep":{"inf":2417,"mid":3868,"sup":65535} + } + } +, + { + "N":124,"start":26,"end":45, + "trk":TRK_RECV,"xorval":0x00000008, + "r_low":{ + "bits":7,"v":0x00000008,"railstatus":"stop received","n":2, + "b_short":{"inf":93,"mid":248,"sup":324}, + "b_long":{"inf":325,"mid":400,"sup":650}, + "b_sep":{"inf":587,"mid":940,"sup":65535} + }, + "r_high":{ + "bits":7,"v":0x00000000,"railstatus":"stop received","n":1, + "b_short":{"inf":372,"mid":496,"sup":620}, + "b_long":{"inf":372,"mid":496,"sup":620}, + "b_sep":{"inf":2417,"mid":3868,"sup":65535} + } + } +, + { + "N":124,"start":50,"end":69, + "trk":TRK_RECV,"xorval":0x0000000E, + "r_low":{ + "bits":7,"v":0x0000000E,"railstatus":"stop received","n":2, + "b_short":{"inf":93,"mid":248,"sup":324}, + "b_long":{"inf":325,"mid":400,"sup":650}, + "b_sep":{"inf":587,"mid":940,"sup":65535} + }, + "r_high":{ + "bits":7,"v":0x00000000,"railstatus":"error","n":1, + "b_short":{"inf":372,"mid":496,"sup":620}, + "b_long":{"inf":372,"mid":496,"sup":620}, + "b_sep":{"inf":0,"mid":0,"sup":0} + } + } +, + { + "N":124,"start":50,"end":93, + "trk":TRK_RECV,"xorval":0x00000002, + "r_low":{ + "bits":7,"v":0x00000002,"railstatus":"stop received","n":2, + "b_short":{"inf":93,"mid":248,"sup":324}, + "b_long":{"inf":325,"mid":400,"sup":650}, + "b_sep":{"inf":562,"mid":900,"sup":65535} + }, + "r_high":{ + "bits":8,"v":0x00000000,"railstatus":"closed","n":1, + "b_short":{"inf":372,"mid":496,"sup":620}, + "b_long":{"inf":372,"mid":496,"sup":620}, + "b_sep":{"inf":0,"mid":0,"sup":0} + } + } +, + { + "N":124,"start":50,"end":117, + "trk":TRK_RECV,"xorval":0x00000001, + "r_low":{ + "bits":7,"v":0x00000000,"railstatus":"stop received","n":1, + "b_short":{"inf":186,"mid":248,"sup":310}, + "b_long":{"inf":186,"mid":248,"sup":310}, + "b_sep":{"inf":1250,"mid":2000,"sup":65535} + }, + "r_high":{ + "bits":8,"v":0x00000001,"railstatus":"closed","n":2, + "b_short":{"inf":186,"mid":496,"sup":752}, + "b_long":{"inf":753,"mid":1008,"sup":1638}, + "b_sep":{"inf":0,"mid":0,"sup":0} + } + } +] diff --git a/testplan/track/04/expect2.txt b/testplan/track/04/expect2.txt new file mode 100644 index 0000000..c6b1e5d --- /dev/null +++ b/testplan/track/04/expect2.txt @@ -0,0 +1,12 @@ +IH_max_pending_timings = 3 +> nb_sections = 1, initseq = 15000 + 00 SSEP + sep = 3868 + low: [1] n = 8, v = 0x00000000 + high: [1] n = 7, v = 0x00000000 +IH_max_pending_timings = 3 +> nb_sections = 1, initseq = 15000 + 00 2SEP + sep = 3868 + low: [2] n = 7, v = 0x00000008 + high: [1] n = 7, v = 0x00000000 diff --git a/testplan/track/05/code-err.txt b/testplan/track/05/code-err.txt new file mode 100644 index 0000000..3dfaf9f --- /dev/null +++ b/testplan/track/05/code-err.txt @@ -0,0 +1,11 @@ +0, 15000, + 248, 500, + 248, 496, + 244, 504, + 240, 504, + 240, 504, + 244, 504, + 244, 504, + 240, 3868, + 228, 888, +100, 100, diff --git a/testplan/track/05/expect1.txt b/testplan/track/05/expect1.txt new file mode 100644 index 0000000..0d4f101 --- /dev/null +++ b/testplan/track/05/expect1.txt @@ -0,0 +1,2 @@ +[ +] diff --git a/testplan/track/05/expect2.txt b/testplan/track/05/expect2.txt new file mode 100644 index 0000000..e69de29 diff --git a/testplan/track/06/code-1 b/testplan/track/06/code-1 new file mode 100644 index 0000000..2db85a6 --- /dev/null +++ b/testplan/track/06/code-1 @@ -0,0 +1,13 @@ +0, 15000, +0, 45000, + 248, 500, + 248, 500, + 248, 496, + 244, 504, + 240, 504, + 240, 504, + 244, 504, + 244, 504, + 240, 3868, + 228, 888, +100, 100, diff --git a/testplan/track/06/expect1.txt b/testplan/track/06/expect1.txt new file mode 100644 index 0000000..d89124d --- /dev/null +++ b/testplan/track/06/expect1.txt @@ -0,0 +1,18 @@ +[ + { + "N":26,"start":0,"end":23, + "trk":TRK_RECV,"xorval":0x00000000, + "r_low":{ + "bits":8,"v":0x00000000,"railstatus":"closed","n":1, + "b_short":{"inf":186,"mid":248,"sup":310}, + "b_long":{"inf":186,"mid":248,"sup":310}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":7,"v":0x00000000,"railstatus":"stop received","n":1, + "b_short":{"inf":375,"mid":500,"sup":625}, + "b_long":{"inf":375,"mid":500,"sup":625}, + "b_sep":{"inf":2417,"mid":3868,"sup":65535} + } + } +] diff --git a/testplan/track/06/expect2.txt b/testplan/track/06/expect2.txt new file mode 100644 index 0000000..e3fdc58 --- /dev/null +++ b/testplan/track/06/expect2.txt @@ -0,0 +1,6 @@ +IH_max_pending_timings = 3 +> nb_sections = 1, initseq = 45000 + 00 SSEP + sep = 3868 + low: [1] n = 8, v = 0x00000000 + high: [1] n = 7, v = 0x00000000 diff --git a/testplan/track/07/code-2 b/testplan/track/07/code-2 new file mode 100644 index 0000000..b94c002 --- /dev/null +++ b/testplan/track/07/code-2 @@ -0,0 +1,15 @@ +0, 15000, +0, 15000, + 248, 500, +248, 15000, + 248, 500, + 248, 500, + 248, 496, + 244, 504, + 240, 504, + 240, 504, + 244, 504, + 244, 504, + 240, 3868, + 228, 888, +100, 100, diff --git a/testplan/track/07/expect1.txt b/testplan/track/07/expect1.txt new file mode 100644 index 0000000..85e2e5b --- /dev/null +++ b/testplan/track/07/expect1.txt @@ -0,0 +1,18 @@ +[ + { + "N":30,"start":0,"end":27, + "trk":TRK_RECV,"xorval":0x00000000, + "r_low":{ + "bits":8,"v":0x00000000,"railstatus":"closed","n":1, + "b_short":{"inf":186,"mid":248,"sup":310}, + "b_long":{"inf":186,"mid":248,"sup":310}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":7,"v":0x00000000,"railstatus":"stop received","n":1, + "b_short":{"inf":375,"mid":500,"sup":625}, + "b_long":{"inf":375,"mid":500,"sup":625}, + "b_sep":{"inf":2417,"mid":3868,"sup":65535} + } + } +] diff --git a/testplan/track/07/expect2.txt b/testplan/track/07/expect2.txt new file mode 100644 index 0000000..18dc65b --- /dev/null +++ b/testplan/track/07/expect2.txt @@ -0,0 +1,6 @@ +IH_max_pending_timings = 3 +> nb_sections = 1, initseq = 15000 + 00 SSEP + sep = 3868 + low: [1] n = 8, v = 0x00000000 + high: [1] n = 7, v = 0x00000000 diff --git a/testplan/track/08/code-2 b/testplan/track/08/code-2 new file mode 100644 index 0000000..c01069a --- /dev/null +++ b/testplan/track/08/code-2 @@ -0,0 +1,15 @@ +0, 15000, +0, 15000, + 248, 500, +248, 15000, + 248, 500, + 248, 500, + 248, 496, + 244, 504, + 240, 504, + 240, 504, + 244, 504, + 244, 504, + 2400, 504, + 228, 888, +100, 100, diff --git a/testplan/track/08/expect1.txt b/testplan/track/08/expect1.txt new file mode 100644 index 0000000..c6f140c --- /dev/null +++ b/testplan/track/08/expect1.txt @@ -0,0 +1,18 @@ +[ + { + "N":30,"start":0,"end":27, + "trk":TRK_RECV,"xorval":0x00000000, + "r_low":{ + "bits":7,"v":0x00000000,"railstatus":"stop received","n":1, + "b_short":{"inf":186,"mid":248,"sup":310}, + "b_long":{"inf":186,"mid":248,"sup":310}, + "b_sep":{"inf":1500,"mid":2400,"sup":65535} + }, + "r_high":{ + "bits":8,"v":0x00000000,"railstatus":"closed","n":1, + "b_short":{"inf":375,"mid":500,"sup":625}, + "b_long":{"inf":375,"mid":500,"sup":625}, + "b_sep":{"inf":0,"mid":0,"sup":0} + } + } +] diff --git a/testplan/track/08/expect2.txt b/testplan/track/08/expect2.txt new file mode 100644 index 0000000..e69de29 diff --git a/testplan/track/09/code-flo.txt b/testplan/track/09/code-flo.txt new file mode 100644 index 0000000..76ea731 --- /dev/null +++ b/testplan/track/09/code-flo.txt @@ -0,0 +1,69 @@ +0, 8484 +608, 724 +1292, 1396 +1284, 1412 +624, 716 +1292, 1404 +596, 736 +612, 720 +596, 752 +1276, 1420 +1268, 1420 +596, 736 +1280, 1424 +608, 24028 +608, 728 +1300, 1412 +596, 736 +1288, 1424 +592, 748 +1284, 1420 +596, 736 +1284, 1428 +612, 720 +1280, 1424 +592, 752 +1280, 1420 +600, 24052 +588, 752 +1268, 1420 +604, 736 +1300, 1412 +588, 744 +1296, 1412 +592, 748 +1276, 1428 +588, 752 +1260, 1440 +580, 760 +1280, 1420 +584, 24048 +612, 736 +1260, 1440 +580, 760 +1268, 1436 +580, 760 +1256, 1440 +596, 744 +1276, 1424 +596, 736 +1292, 1404 +596, 752 +1264, 1432 +576, 24056 +572, 776 +1256, 1448 +580, 752 +1276, 1424 +592, 744 +1284, 1420 +616, 728 +1268, 1424 +588, 752 +1256, 1448 +568, 776 +1240, 1464 +580, 24040 +576, 764 +1260, 1440 +616, 716 diff --git a/testplan/track/09/expect1.txt b/testplan/track/09/expect1.txt new file mode 100644 index 0000000..11e0732 --- /dev/null +++ b/testplan/track/09/expect1.txt @@ -0,0 +1,82 @@ +[ + { + "N":138,"start":0,"end":29, + "trk":TRK_RECV,"xorval":0x00000B97, + "r_low":{ + "bits":12,"v":0x00000D1A,"railstatus":"closed","n":2, + "b_short":{"inf":234,"mid":624,"sup":958}, + "b_long":{"inf":959,"mid":1292,"sup":2099}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":11,"v":0x0000068D,"railstatus":"stop received","n":2, + "b_short":{"inf":269,"mid":716,"sup":1056}, + "b_long":{"inf":1057,"mid":1396,"sup":2268}, + "b_sep":{"inf":15017,"mid":24028,"sup":65535} + } + } + { + "N":138,"start":0,"end":55, + "trk":TRK_RECV,"xorval":0x00000FFF, + "r_low":{ + "bits":12,"v":0x00000AAA,"railstatus":"closed","n":2, + "b_short":{"inf":234,"mid":624,"sup":958}, + "b_long":{"inf":959,"mid":1292,"sup":2099}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":11,"v":0x00000555,"railstatus":"stop received","n":2, + "b_short":{"inf":269,"mid":716,"sup":1056}, + "b_long":{"inf":1057,"mid":1396,"sup":2268}, + "b_sep":{"inf":15017,"mid":24028,"sup":65535} + } + } + { + "N":138,"start":0,"end":81, + "trk":TRK_RECV,"xorval":0x00000FFF, + "r_low":{ + "bits":12,"v":0x00000AAA,"railstatus":"closed","n":2, + "b_short":{"inf":234,"mid":624,"sup":958}, + "b_long":{"inf":959,"mid":1292,"sup":2099}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":11,"v":0x00000555,"railstatus":"stop received","n":2, + "b_short":{"inf":269,"mid":716,"sup":1056}, + "b_long":{"inf":1057,"mid":1396,"sup":2268}, + "b_sep":{"inf":15017,"mid":24028,"sup":65535} + } + } + { + "N":138,"start":0,"end":107, + "trk":TRK_RECV,"xorval":0x00000FFF, + "r_low":{ + "bits":12,"v":0x00000AAA,"railstatus":"closed","n":2, + "b_short":{"inf":234,"mid":624,"sup":958}, + "b_long":{"inf":959,"mid":1292,"sup":2099}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":11,"v":0x00000555,"railstatus":"stop received","n":2, + "b_short":{"inf":269,"mid":716,"sup":1056}, + "b_long":{"inf":1057,"mid":1396,"sup":2268}, + "b_sep":{"inf":15017,"mid":24028,"sup":65535} + } + } + { + "N":138,"start":0,"end":133, + "trk":TRK_RECV,"xorval":0x00000FFF, + "r_low":{ + "bits":12,"v":0x00000AAA,"railstatus":"closed","n":2, + "b_short":{"inf":234,"mid":624,"sup":958}, + "b_long":{"inf":959,"mid":1292,"sup":2099}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":11,"v":0x00000555,"railstatus":"stop received","n":2, + "b_short":{"inf":269,"mid":716,"sup":1056}, + "b_long":{"inf":1057,"mid":1396,"sup":2268}, + "b_sep":{"inf":15017,"mid":24028,"sup":65535} + } + } +] diff --git a/testplan/track/09/expect2.txt b/testplan/track/09/expect2.txt new file mode 100644 index 0000000..625e1b1 --- /dev/null +++ b/testplan/track/09/expect2.txt @@ -0,0 +1,22 @@ +IH_max_pending_timings = 3 +> nb_sections = 5, initseq = 8484 + 00 SSEP + sep = 24028 + low: [2] n = 12, v = 0x00000D1A + high: [2] n = 11, v = 0x0000068D + 01 SSEP + sep = 24052 + low: [2] n = 12, v = 0x00000AAA + high: [2] n = 11, v = 0x00000555 + 02 SSEP + sep = 24048 + low: [2] n = 12, v = 0x00000AAA + high: [2] n = 11, v = 0x00000555 + 03 SSEP + sep = 24056 + low: [2] n = 12, v = 0x00000AAA + high: [2] n = 11, v = 0x00000555 + 04 SSEP + sep = 24040 + low: [2] n = 12, v = 0x00000AAA + high: [2] n = 11, v = 0x00000555 diff --git a/testplan/track/10/code-portail.txt b/testplan/track/10/code-portail.txt new file mode 100644 index 0000000..516461b --- /dev/null +++ b/testplan/track/10/code-portail.txt @@ -0,0 +1,69 @@ +, 5656 +304, 416 +296, 420 +296, 416 +296, 416 +308, 404 +300, 416 +296, 416 +300, 412 +300, 416 +296, 416 +300, 412 +300, 3764 +676, 416 +676, 416 +304, 788 +676, 424 +672, 420 +296, 800 +296, 796 +672, 424 +296, 796 +296, 800 +668, 424 +296, 800 +668, 424 +296, 796 +296, 800 +296, 796 +672, 424 +668, 424 +672, 424 +668, 424 +296, 796 +668, 424 +668, 424 +296, 800 +296, 804 +656, 428 +288, 804 +296, 804 +664, 432 +656, 436 +656, 432 +668, 432 +288, 800 +296, 804 +288, 808 +648, 440 +288, 804 +284, 812 +288, 804 +656, 440 +280, 820 +272, 812 +652, 448 +648, 444 +272, 820 +272, 820 +276, 820 +648, 444 +648, 444 +272, 820 +280, 812 +656, 440 +656, 436 +648, 448 +648, 444 +648, 448 diff --git a/testplan/track/10/expect1.txt b/testplan/track/10/expect1.txt new file mode 100644 index 0000000..0522954 --- /dev/null +++ b/testplan/track/10/expect1.txt @@ -0,0 +1,50 @@ +[ + { + "N":138,"start":0,"end":27, + "trk":TRK_RECV,"xorval":0x00000000, + "r_low":{ + "bits":11,"v":0x00000000,"railstatus":"closed","n":1, + "b_short":{"inf":222,"mid":296,"sup":370}, + "b_long":{"inf":222,"mid":296,"sup":370}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":10,"v":0x00000000,"railstatus":"stop received","n":1, + "b_short":{"inf":315,"mid":420,"sup":525}, + "b_long":{"inf":315,"mid":420,"sup":525}, + "b_sep":{"inf":2352,"mid":3764,"sup":65535} + } + } + { + "N":138,"start":0,"end":93, + "trk":TRK_RECV,"xorval":0xFFFFFFFF, + "r_low":{ + "bits":32,"v":0xB251EC9E,"railstatus":"full","n":2, + "b_short":{"inf":111,"mid":296,"sup":486}, + "b_long":{"inf":487,"mid":676,"sup":1098}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":32,"v":0x4DAE1361,"railstatus":"full","n":2, + "b_short":{"inf":158,"mid":420,"sup":604}, + "b_long":{"inf":605,"mid":788,"sup":1280}, + "b_sep":{"inf":2352,"mid":3764,"sup":65535} + } + } + { + "N":138,"start":0,"end":138, + "trk":TRK_RECV,"xorval":0x007FFFFF, + "r_low":{ + "bits":23,"v":0x0011319F,"railstatus":"error","n":2, + "b_short":{"inf":111,"mid":296,"sup":486}, + "b_long":{"inf":487,"mid":676,"sup":1098}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":23,"v":0x006ECE60,"railstatus":"error","n":2, + "b_short":{"inf":158,"mid":420,"sup":604}, + "b_long":{"inf":605,"mid":788,"sup":1280}, + "b_sep":{"inf":2352,"mid":3764,"sup":65535} + } + } +] diff --git a/testplan/track/10/expect2.txt b/testplan/track/10/expect2.txt new file mode 100644 index 0000000..73d4ab6 --- /dev/null +++ b/testplan/track/10/expect2.txt @@ -0,0 +1,10 @@ +IH_max_pending_timings = 3 +> nb_sections = 2, initseq = 5656 + 00 SSEP + sep = 3764 + low: [1] n = 11, v = 0x00000000 + high: [1] n = 10, v = 0x00000000 + 01 CONT + sep = 0 + low: [2] n = 32, v = 0xB251EC9E + high: [2] n = 32, v = 0x4DAE1361 diff --git a/testplan/track/11/code-adf.txt b/testplan/track/11/code-adf.txt new file mode 100644 index 0000000..154681a --- /dev/null +++ b/testplan/track/11/code-adf.txt @@ -0,0 +1,57 @@ +0,5288 +1300, 1212 +1268, 2436 +2540, 1204 +1236, 1220 +1276, 1196 +1268, 1216 +1252, 1228 +1244, 1256 +1220, 1248 +1244, 1248 +1248, 1224 +1260, 1212 +1240, 1244 +1236, 2472 +1264, 1200 +1288, 1212 +2496, 1244 +1252, 1224 +1260, 2424 +2516, 1240 +1220, 2480 +2552, 2436 +2488, 1232 +1280, 2420 +1272, 1212 +2504, 2464 +1288, 5304 +1248, 1252 +1236, 2456 +2516, 1212 +1280, 1208 +1240, 1236 +1224, 1260 +1236, 1268 +1228, 1236 +1240, 1232 +1232, 1252 +1216, 1256 +1240, 1244 +1224, 1268 +1196, 2488 +1248, 1244 +1236, 1240 +2504, 1240 +1248, 1232 +1228, 2464 +2496, 1240 +1216, 2484 +2496, 2484 +2516, 1224 +1224, 2464 +1260, 1224 +2512, 2464 +1264, 5324 +1216, 1268 +1248, 2452 diff --git a/testplan/track/11/expect1.txt b/testplan/track/11/expect1.txt new file mode 100644 index 0000000..b58187d --- /dev/null +++ b/testplan/track/11/expect1.txt @@ -0,0 +1,34 @@ +[ + { + "N":114,"start":0,"end":57, + "trk":TRK_RECV,"xorval":0x00001407, + "r_low":{ + "bits":26,"v":0x010004B2,"railstatus":"closed","n":2, + "b_short":{"inf":476,"mid":1268,"sup":1904}, + "b_long":{"inf":1905,"mid":2540,"sup":4127}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":25,"v":0x010010B5,"railstatus":"stop received","n":2, + "b_short":{"inf":452,"mid":1204,"sup":1820}, + "b_long":{"inf":1821,"mid":2436,"sup":3958}, + "b_sep":{"inf":3315,"mid":5304,"sup":65535} + } + } + { + "N":114,"start":0,"end":111, + "trk":TRK_RECV,"xorval":0x00001407, + "r_low":{ + "bits":26,"v":0x010004B2,"railstatus":"closed","n":2, + "b_short":{"inf":476,"mid":1268,"sup":1904}, + "b_long":{"inf":1905,"mid":2540,"sup":4127}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":25,"v":0x010010B5,"railstatus":"stop received","n":2, + "b_short":{"inf":452,"mid":1204,"sup":1820}, + "b_long":{"inf":1821,"mid":2436,"sup":3958}, + "b_sep":{"inf":3315,"mid":5304,"sup":65535} + } + } +] diff --git a/testplan/track/11/expect2.txt b/testplan/track/11/expect2.txt new file mode 100644 index 0000000..7de6ece --- /dev/null +++ b/testplan/track/11/expect2.txt @@ -0,0 +1,10 @@ +IH_max_pending_timings = 3 +> nb_sections = 2, initseq = 5288 + 00 SSEP + sep = 5304 + low: [2] n = 26, v = 0x010004B2 + high: [2] n = 25, v = 0x010010B5 + 01 SSEP + sep = 5324 + low: [2] n = 26, v = 0x010004B2 + high: [2] n = 25, v = 0x010010B5 diff --git a/testplan/track/12/code-adf.txt b/testplan/track/12/code-adf.txt new file mode 100644 index 0000000..56ba0f4 --- /dev/null +++ b/testplan/track/12/code-adf.txt @@ -0,0 +1,56 @@ +0,5288 +1300, 1212 +1268, 2436 +2540, 1204 +1236, 1220 +1268, 1216 +1252, 1228 +1244, 1256 +1220, 1248 +1244, 1248 +1248, 1224 +1260, 1212 +1240, 1244 +1236, 2472 +1264, 1200 +1288, 1212 +2496, 1244 +1252, 1224 +1260, 2424 +2516, 1240 +1220, 2480 +2552, 2436 +2488, 1232 +1280, 2420 +1272, 1212 +2504, 2464 +1288, 5304 +1248, 1252 +1236, 2456 +2516, 1212 +1280, 1208 +1240, 1236 +1224, 1260 +1236, 1268 +1228, 1236 +1240, 1232 +1232, 1252 +1216, 1256 +1240, 1244 +1224, 1268 +1196, 2488 +1248, 1244 +1236, 1240 +2504, 1240 +1248, 1232 +1228, 2464 +2496, 1240 +1216, 2484 +2496, 2484 +2516, 1224 +1224, 2464 +1260, 1224 +2512, 2464 +1264, 5324 +1216, 1268 +1248, 2452 diff --git a/testplan/track/12/expect1.txt b/testplan/track/12/expect1.txt new file mode 100644 index 0000000..ab88d60 --- /dev/null +++ b/testplan/track/12/expect1.txt @@ -0,0 +1,34 @@ +[ + { + "N":112,"start":0,"end":55, + "trk":TRK_RECV,"xorval":0x00001407, + "r_low":{ + "bits":25,"v":0x008004B2,"railstatus":"closed","n":2, + "b_short":{"inf":476,"mid":1268,"sup":1904}, + "b_long":{"inf":1905,"mid":2540,"sup":4127}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":24,"v":0x008010B5,"railstatus":"stop received","n":2, + "b_short":{"inf":452,"mid":1204,"sup":1820}, + "b_long":{"inf":1821,"mid":2436,"sup":3958}, + "b_sep":{"inf":3315,"mid":5304,"sup":65535} + } + } + { + "N":112,"start":0,"end":109, + "trk":TRK_RECV,"xorval":0x00001407, + "r_low":{ + "bits":26,"v":0x010004B2,"railstatus":"closed","n":2, + "b_short":{"inf":476,"mid":1268,"sup":1904}, + "b_long":{"inf":1905,"mid":2540,"sup":4127}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":25,"v":0x010010B5,"railstatus":"stop received","n":2, + "b_short":{"inf":452,"mid":1204,"sup":1820}, + "b_long":{"inf":1821,"mid":2436,"sup":3958}, + "b_sep":{"inf":3315,"mid":5304,"sup":65535} + } + } +] diff --git a/testplan/track/12/expect2.txt b/testplan/track/12/expect2.txt new file mode 100644 index 0000000..33406d4 --- /dev/null +++ b/testplan/track/12/expect2.txt @@ -0,0 +1,10 @@ +IH_max_pending_timings = 3 +> nb_sections = 2, initseq = 5288 + 00 SSEP + sep = 5304 + low: [2] n = 25, v = 0x008004B2 + high: [2] n = 24, v = 0x008010B5 + 01 SSEP + sep = 5324 + low: [2] n = 26, v = 0x010004B2 + high: [2] n = 25, v = 0x010010B5 diff --git a/testplan/track/13/code-adf.txt b/testplan/track/13/code-adf.txt new file mode 100644 index 0000000..a0edeab --- /dev/null +++ b/testplan/track/13/code-adf.txt @@ -0,0 +1,55 @@ +0,5288 +1300, 1212 +1268, 2436 +2540, 1204 +1268, 1216 +1252, 1228 +1244, 1256 +1220, 1248 +1244, 1248 +1248, 1224 +1260, 1212 +1240, 1244 +1236, 2472 +1264, 1200 +1288, 1212 +2496, 1244 +1252, 1224 +1260, 2424 +2516, 1240 +1220, 2480 +2552, 2436 +2488, 1232 +1280, 2420 +1272, 1212 +2504, 2464 +1288, 5304 +1248, 1252 +1236, 2456 +2516, 1212 +1280, 1208 +1240, 1236 +1224, 1260 +1236, 1268 +1228, 1236 +1240, 1232 +1232, 1252 +1216, 1256 +1240, 1244 +1224, 1268 +1196, 2488 +1248, 1244 +1236, 1240 +2504, 1240 +1248, 1232 +1228, 2464 +2496, 1240 +1216, 2484 +2496, 2484 +2516, 1224 +1224, 2464 +1260, 1224 +2512, 2464 +1264, 5324 +1216, 1268 +1248, 2452 diff --git a/testplan/track/13/expect1.txt b/testplan/track/13/expect1.txt new file mode 100644 index 0000000..ef1aa34 --- /dev/null +++ b/testplan/track/13/expect1.txt @@ -0,0 +1,34 @@ +[ + { + "N":110,"start":0,"end":53, + "trk":TRK_RECV,"xorval":0x00001407, + "r_low":{ + "bits":24,"v":0x004004B2,"railstatus":"closed","n":2, + "b_short":{"inf":476,"mid":1268,"sup":1904}, + "b_long":{"inf":1905,"mid":2540,"sup":4127}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":23,"v":0x004010B5,"railstatus":"stop received","n":2, + "b_short":{"inf":452,"mid":1204,"sup":1820}, + "b_long":{"inf":1821,"mid":2436,"sup":3958}, + "b_sep":{"inf":3315,"mid":5304,"sup":65535} + } + } + { + "N":110,"start":0,"end":107, + "trk":TRK_RECV,"xorval":0x00001407, + "r_low":{ + "bits":26,"v":0x010004B2,"railstatus":"closed","n":2, + "b_short":{"inf":476,"mid":1268,"sup":1904}, + "b_long":{"inf":1905,"mid":2540,"sup":4127}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":25,"v":0x010010B5,"railstatus":"stop received","n":2, + "b_short":{"inf":452,"mid":1204,"sup":1820}, + "b_long":{"inf":1821,"mid":2436,"sup":3958}, + "b_sep":{"inf":3315,"mid":5304,"sup":65535} + } + } +] diff --git a/testplan/track/13/expect2.txt b/testplan/track/13/expect2.txt new file mode 100644 index 0000000..bcd7f76 --- /dev/null +++ b/testplan/track/13/expect2.txt @@ -0,0 +1,10 @@ +IH_max_pending_timings = 3 +> nb_sections = 2, initseq = 5288 + 00 SSEP + sep = 5304 + low: [2] n = 24, v = 0x004004B2 + high: [2] n = 23, v = 0x004010B5 + 01 SSEP + sep = 5324 + low: [2] n = 26, v = 0x010004B2 + high: [2] n = 25, v = 0x010010B5 diff --git a/testplan/track/14/code-adf.txt b/testplan/track/14/code-adf.txt new file mode 100644 index 0000000..91e58e4 --- /dev/null +++ b/testplan/track/14/code-adf.txt @@ -0,0 +1,54 @@ +0,5288 +1300, 1212 +1268, 2436 +2540, 1204 +1268, 1216 +1252, 1228 +1244, 1256 +1220, 1248 +1248, 1224 +1260, 1212 +1240, 1244 +1236, 2472 +1264, 1200 +1288, 1212 +2496, 1244 +1252, 1224 +1260, 2424 +2516, 1240 +1220, 2480 +2552, 2436 +2488, 1232 +1280, 2420 +1272, 1212 +2504, 2464 +1288, 5304 +1248, 1252 +1236, 2456 +2516, 1212 +1280, 1208 +1240, 1236 +1224, 1260 +1236, 1268 +1228, 1236 +1240, 1232 +1232, 1252 +1216, 1256 +1240, 1244 +1224, 1268 +1196, 2488 +1248, 1244 +1236, 1240 +2504, 1240 +1248, 1232 +1228, 2464 +2496, 1240 +1216, 2484 +2496, 2484 +2516, 1224 +1224, 2464 +1260, 1224 +2512, 2464 +1264, 5324 +1216, 1268 +1248, 2452 diff --git a/testplan/track/14/expect1.txt b/testplan/track/14/expect1.txt new file mode 100644 index 0000000..a60a8df --- /dev/null +++ b/testplan/track/14/expect1.txt @@ -0,0 +1,34 @@ +[ + { + "N":108,"start":0,"end":51, + "trk":TRK_RECV,"xorval":0x00001407, + "r_low":{ + "bits":23,"v":0x002004B2,"railstatus":"closed","n":2, + "b_short":{"inf":476,"mid":1268,"sup":1904}, + "b_long":{"inf":1905,"mid":2540,"sup":4127}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":22,"v":0x002010B5,"railstatus":"stop received","n":2, + "b_short":{"inf":452,"mid":1204,"sup":1820}, + "b_long":{"inf":1821,"mid":2436,"sup":3958}, + "b_sep":{"inf":3315,"mid":5304,"sup":65535} + } + } + { + "N":108,"start":0,"end":105, + "trk":TRK_RECV,"xorval":0x00001407, + "r_low":{ + "bits":26,"v":0x010004B2,"railstatus":"closed","n":2, + "b_short":{"inf":476,"mid":1268,"sup":1904}, + "b_long":{"inf":1905,"mid":2540,"sup":4127}, + "b_sep":{"inf":0,"mid":0,"sup":0} + }, + "r_high":{ + "bits":25,"v":0x010010B5,"railstatus":"stop received","n":2, + "b_short":{"inf":452,"mid":1204,"sup":1820}, + "b_long":{"inf":1821,"mid":2436,"sup":3958}, + "b_sep":{"inf":3315,"mid":5304,"sup":65535} + } + } +] diff --git a/testplan/track/14/expect2.txt b/testplan/track/14/expect2.txt new file mode 100644 index 0000000..339d3a3 --- /dev/null +++ b/testplan/track/14/expect2.txt @@ -0,0 +1,10 @@ +IH_max_pending_timings = 3 +> nb_sections = 2, initseq = 5288 + 00 SSEP + sep = 5304 + low: [2] n = 23, v = 0x002004B2 + high: [2] n = 22, v = 0x002010B5 + 01 SSEP + sep = 5324 + low: [2] n = 26, v = 0x010004B2 + high: [2] n = 25, v = 0x010010B5 diff --git a/testplan/tt.sh b/testplan/tt.sh new file mode 100755 index 0000000..501a9ae --- /dev/null +++ b/testplan/tt.sh @@ -0,0 +1,94 @@ +#!/usr/bin/bash + +# tt.sh + +# Execute test plan of RF433any library +# Requires an Arduino plugged on PC + +# Accepts one optional argument, the test number to execute. +# Without argument, runs all tests. + +# Copyright 2021 Sébastien Millet +# +# `RF433any' is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# `RF433any' is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program. If not, see +# . + +set -euo pipefail + +PORT=/dev/ttyUSB0 + +PASSED=0 +FAILED=0 + +cd .. + +START=1 +STOP=5 +if [ -n "${1:-}" ]; then + START="$1"; + STOP="$1"; +fi + +for ((i=START; i<=STOP; i++)); do + + echo "== ROUND $i" + + testplan/test/am testplan/test/test.ino -u --stty -t "${i}" + + sleep 2 + + if [ "${i}" -le 2 ]; then + cd testplan/track + elif [ "${i}" -le 4 ]; then + cd testplan/decoder + elif [ "${i}" -le 5 ]; then + cd testplan/user + else + + echo "Unknown testplan number, aborted." + exit 99 + fi + + for d in [0-9][0-9]; do + inpfile=$(ls "${d}"/code*) + tmpout="${d}/tmpout${i}.txt" + expfile="${d}/expect${i}.txt" + ../exectest.sh "${inpfile}" "${tmpout}" "${PORT}" + echo -n "$i:${d}" + if cmp "${expfile}" "${tmpout}" > /dev/null 2> /dev/null; then + PASSED=$((PASSED + 1)) + echo " test ok" + else + FAILED=$((FAILED + 1)) + echo " ** TEST KO, actual output differs from expected" + fi + done + + cd ../.. + +done + +echo "------" +echo "PASSED: ${PASSED}" +echo "FAILED: ${FAILED}" + +if [ "${FAILED}" -eq 0 ]; then + echo "OK" +else + echo + echo "**************" + echo "***** KO *****" + echo "**************" + exit 1 +fi diff --git a/testplan/user/01/code-1.txt b/testplan/user/01/code-1.txt new file mode 100644 index 0000000..c1c9399 --- /dev/null +++ b/testplan/user/01/code-1.txt @@ -0,0 +1,53 @@ +0, 0 +0, 9000 +596, 596 +506, 506 +600, 600 +600, 600 +600, 600 +600, 600 +600, 600 +600, 600 +600 , 9000 +1236, 576 +536, 1280 +1232, 596 +528, 1292 +1228, 600 +1228, 600 +1228, 608 +528, 1316 +529, 1319 +522, 7020 +1236, 576 +536, 1280 +1232, 596 +528, 1292 +1228, 600 +1228, 600 +1228, 608 +528, 1316 +529, 1319 +522, 7020 +576, 1236, +576, 536, +1280, 1232, +596, 528, +1292, 1228, +600, 1228, +600, 1228, +608, 528, +1316, 529, +1316, 529, +529, 7020 +700, 644 +700, 644 +700, 644 +700, 644 +700, 644 +700, 644 +700, 644 +700, 644 +1309, 23912 +0, 0 +0, 0 diff --git a/testplan/user/01/expect5.txt b/testplan/user/01/expect5.txt new file mode 100644 index 0000000..15eee35 --- /dev/null +++ b/testplan/user/01/expect5.txt @@ -0,0 +1,8 @@ +Decoded: no , err: 0, code: S, rep: 1, bits: 8 +Decoded: yes, err: 0, code: T, rep: 1, bits: 9 + Data: 01 5c +Decoded: yes, err: 0, code: T, rep: 1, bits: 9 + Data: 01 5c +Decoded: yes, err: 1, code: N, rep: 1, bits: 9 + Data: 01 5c +Decoded: no , err: 0, code: U, rep: 1, bits: 14 diff --git a/testplan/user/02/code-1.txt b/testplan/user/02/code-1.txt new file mode 100644 index 0000000..7c82182 --- /dev/null +++ b/testplan/user/02/code-1.txt @@ -0,0 +1,53 @@ +1, 0 +0, 9000 +596, 596 +506, 506 +600, 600 +600, 600 +600, 600 +600, 600 +600, 600 +600, 600 +600 , 9000 +1236, 576 +536, 1280 +1232, 596 +528, 1292 +1228, 600 +1228, 600 +1228, 608 +528, 1316 +529, 1319 +522, 7020 +1236, 576 +536, 1280 +1232, 596 +528, 1292 +1228, 600 +1228, 600 +1228, 608 +528, 1316 +529, 1319 +522, 7020 +576, 1236, +576, 536, +1280, 1232, +596, 528, +1292, 1228, +600, 1228, +600, 1228, +608, 528, +1316, 529, +1316, 529, +529, 7020 +700, 644 +700, 644 +700, 644 +700, 644 +700, 644 +700, 644 +700, 644 +700, 644 +1309, 23912 +0, 0 +0, 0 diff --git a/testplan/user/02/expect5.txt b/testplan/user/02/expect5.txt new file mode 100644 index 0000000..610d636 --- /dev/null +++ b/testplan/user/02/expect5.txt @@ -0,0 +1,6 @@ +Decoded: yes, err: 0, code: T, rep: 1, bits: 9 + Data: 01 5c +Decoded: yes, err: 0, code: T, rep: 1, bits: 9 + Data: 01 5c +Decoded: yes, err: 1, code: N, rep: 1, bits: 9 + Data: 01 5c