From: Tobias Date: Thu, 16 Feb 2017 21:16:20 +0000 (+0100) Subject: Check in X-Git-Url: http://git.smho.de/gw/?p=owTools.git;a=commitdiff_plain;h=c7561c5e50f1df4015c0c250bdbaa2efbb95a3bd Check in --- c7561c5e50f1df4015c0c250bdbaa2efbb95a3bd diff --git a/AUTHORS b/AUTHORS new file mode 100755 index 0000000..e69de29 diff --git a/COPYING b/COPYING new file mode 100755 index 0000000..94a9ed0 --- /dev/null +++ b/COPYING @@ -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/INSTALL b/INSTALL new file mode 100755 index 0000000..2099840 --- /dev/null +++ b/INSTALL @@ -0,0 +1,370 @@ +Installation Instructions +************************* + +Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, +Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell command `./configure && make && make install' +should configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + HP-UX `make' updates targets which have the same time stamps as +their prerequisites, which makes it generally unusable when shipped +generated files such as `configure' are involved. Use GNU `make' +instead. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf limitation. Until the limitation is lifted, you can use +this workaround: + + CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. diff --git a/Makefile.am b/Makefile.am new file mode 100755 index 0000000..9776aac --- /dev/null +++ b/Makefile.am @@ -0,0 +1,3 @@ +AUTOMAKE_OPTIONS = foreign +SUBDIRS=src + diff --git a/NEWS b/NEWS new file mode 100755 index 0000000..e69de29 diff --git a/README b/README new file mode 100755 index 0000000..e69de29 diff --git a/configure.ac b/configure.ac new file mode 100755 index 0000000..56ad330 --- /dev/null +++ b/configure.ac @@ -0,0 +1,42 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ([2.69]) +AC_INIT([owTools], [0.5], [tm@tm3d.de]) +AM_INIT_AUTOMAKE +AC_CONFIG_SRCDIR([config.h.in]) +AC_CONFIG_HEADERS([config.h]) + +# Checks for programs. +AC_PROG_CXX +AC_PROG_CC + +# Checks for libraries. +# FIXME: Replace `main' with a function in `-lpthread': +AC_CHECK_LIB([pthread], [main]) +# FIXME: Replace `main' with a function in `-lrt': +AC_CHECK_LIB([rt], [main]) +# FIXME: Replace `main' with a function in `-lusb': +AC_CHECK_LIB([usb], [main]) + +# Checks for header files. +AC_CHECK_HEADERS([fcntl.h memory.h stdint.h stdlib.h string.h sys/ioctl.h sys/time.h termios.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_INLINE +AC_TYPE_INT16_T +AC_TYPE_INT32_T +AC_TYPE_INT8_T +AC_TYPE_SIZE_T +AC_TYPE_UINT16_T +AC_TYPE_UINT32_T +AC_TYPE_UINT64_T +AC_TYPE_UINT8_T + +# Checks for library functions. +AC_FUNC_MMAP +AC_CHECK_FUNCS([gettimeofday memset select strncasecmp strstr strtol]) + +AC_CONFIG_FILES([Makefile + src/Makefile]) +AC_OUTPUT diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100755 index 0000000..3f69e36 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,8 @@ + +AM_CPPFLAGS = -Wall -std=c++11 -I/usr/include/mysql +owToolsprgdir=../ +owToolsprg_PROGRAMS=owTools +owTools_SOURCES=main.cpp mySensorDB.cpp owInterface.cpp owPiGPioInterface.cpp libusbds2490.c owUSBInterface.cpp hexfile.cpp owCOMInterface.cpp owDevice.cpp owDeviceConfig.cpp +owTools_LDADD = -lpthread -lrt -lusb -lmysqlclient + + diff --git a/src/hexfile.cpp b/src/hexfile.cpp new file mode 100755 index 0000000..32ce679 --- /dev/null +++ b/src/hexfile.cpp @@ -0,0 +1,99 @@ +// Copyright (c) 2016, Tobias Mueller tm(at)tm3d.de +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// * All advertising materials mentioning features or use of this +// software must display the following acknowledgement: This product +// includes software developed by tm3d.de and its contributors. +// * Neither the name of tm3d.de nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include "hexfile.h" + +#include +#include +#include +#include +#include + +hexFile::hexFile(std::string fname) { + std::ifstream hf(fname); + if (!hf) { + lastError=3; + return; + } + std::string line; + std::stringstream ss; + lastError=0; + while (std::getline(hf, line)) { + //QueryArray.push_back(line); + if (line[0]==':') { + //ss << std::hex << line.substr(1,2); + //ss >> bc; + uint8_t bc=std::stoul( line.substr(1,2), nullptr, 16); + uint32_t fw=std::stoul(line.substr(3,4),nullptr, 16); + uint8_t ty=std::stoul(line.substr(7,2),nullptr,16); + uint32_t chsm = bc + (fw >> 8) + (fw & 0xFF) + ty; + for (int i = 0; i < bc; i++) { + int p = 9 + i * 2; + uint8_t b = std::stoul(line.substr(p, 2),nullptr, 16); + chsm = chsm + b; + prog.push_back(b); + } + chsm=(chsm+std::stoul(line.substr(9+bc*2,2),nullptr,16))&0xFF; + if (chsm!=0) { + lastError=1; + return; + //std::cout <<"ERROR"<(bc)<<" "<< line< hexFile::getBlock(unsigned int pos,unsigned int length){ + std::vector rvec1; + if (pos>prog.size()) return rvec1; + if ((pos+length) > prog.size()) { + std::vector rvec(prog.begin()+pos,prog.end()); + return rvec; + }else { + std::vector rvec(prog.begin()+pos,prog.begin()+pos+length); + return rvec; + } +} + +unsigned int hexFile::getBlockCount(unsigned int length){ + unsigned int count=prog.size()/length; + if ((prog.size()%length)!=0) count++; + return count; +} + diff --git a/src/hexfile.h b/src/hexfile.h new file mode 100755 index 0000000..001eeef --- /dev/null +++ b/src/hexfile.h @@ -0,0 +1,50 @@ +// Copyright (c) 2016, Tobias Mueller tm(at)tm3d.de +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// * All advertising materials mentioning features or use of this +// software must display the following acknowledgement: This product +// includes software developed by tm3d.de and its contributors. +// * Neither the name of tm3d.de nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef ___HEXFILE_H_ +#define ___HEXFILE_H_ + +#include +#include +#include + +class hexFile { +protected: + std::vector prog; +public: + int lastError; + hexFile (std::string fname); + std::vector getBlock(unsigned int pos,unsigned int length); + unsigned int getBlockCount(unsigned int length); + +}; +#endif diff --git a/src/libusbds2490.c b/src/libusbds2490.c new file mode 100755 index 0000000..ae992f6 --- /dev/null +++ b/src/libusbds2490.c @@ -0,0 +1,473 @@ +//--------------------------------------------------------------------------- +// Copyright (C) 2004 Dallas Semiconductor MAXIM Corporation, All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES +// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// Except as contained in this notice, the name of Dallas Semiconductor MAXIM +// shall not be used except as stated in the Dallas Semiconductor MAXIM +// Branding Policy. +//--------------------------------------------------------------------------- +// +// libusblds2490.c - DS2490 utility functions for Windows. +// (Requires libusb http://libusb.sourceforge.net +// or http://libusb-win32.sourceforge.net) +// +// Version: +// + +//#include "ownet.h" +#include "libusbds2490.h" +#include +#include + +#define TRUE 1 +#define FALSE 0 +#define OWERROR_ADAPTER_ERROR 110 +#define OWERROR(err) printf("%i",err); + +#define MAX_PORTNUM 20 +// handles for the USB ports +extern struct usb_dev_handle *usb_dev_handle_list[MAX_PORTNUM]; + +// global DS2490 state +SMALLINT USBLevel[MAX_PORTNUM]; +SMALLINT USBSpeed[MAX_PORTNUM]; +SMALLINT USBVersion[MAX_PORTNUM]; +SMALLINT USBVpp[MAX_PORTNUM]; + +long msGettick(void) +{ +#if USE_WINDOWS_TIME + return GetTickCount(); +#else + struct timezone tmzone; + struct timeval tmval; + long ms; + + gettimeofday(&tmval,&tmzone); + ms = (tmval.tv_sec & 0xFFFF) * 1000 + tmval.tv_usec / 1000; + return ms; +#endif +} + +//--------------------------------------------------------------------------- +// Attempt to resync and detect a DS2490 +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// +// Returns: TRUE - DS2490 detected successfully +// FALSE - Could not detect DS2490 +// +SMALLINT DS2490Detect(usb_dev_handle *hDevice) +{ + SMALLINT present,vpp; + SETUP_PACKET setup; + + // reset the DS2490 + //printf("DS2490Detect\n"); + DS2490Reset(hDevice); + + // set the strong pullup duration to infinite + setup.RequestTypeReservedBits = 0x40; + setup.Request = COMM_CMD; + setup.Value = COMM_SET_DURATION | COMM_IM; + setup.Index = 0x0000; + setup.Length = 0; + setup.DataOut = FALSE; + // call the libusb driver + /*ret =*/ usb_control_msg(hDevice, + setup.RequestTypeReservedBits, + setup.Request, + setup.Value, + setup.Index, + NULL, + setup.Length, + TIMEOUT_LIBUSB); + + // set the 12V pullup duration to 512us + setup.RequestTypeReservedBits = 0x40; + setup.Request = COMM_CMD; + setup.Value = COMM_SET_DURATION | COMM_IM | COMM_TYPE; + setup.Index = 0x0040; + setup.Length = 0; + setup.DataOut = FALSE; + // call the libusb driver + /* ret = */usb_control_msg(hDevice, + setup.RequestTypeReservedBits, + setup.Request, + setup.Value, + setup.Index, + NULL, + setup.Length, + TIMEOUT_LIBUSB); + + // disable strong pullup, but leave program pulse enabled (faster) + setup.RequestTypeReservedBits = 0x40; + setup.Request = MODE_CMD; + setup.Value = MOD_PULSE_EN; + setup.Index = ENABLEPULSE_PRGE; + setup.Length = 0x00; + setup.DataOut = FALSE; + // call the libusb driver + /*ret = */usb_control_msg(hDevice, + setup.RequestTypeReservedBits, + setup.Request, + setup.Value, + setup.Index, + NULL, + setup.Length, + TIMEOUT_LIBUSB); + + // return result of short check + return DS2490ShortCheck(hDevice,&present,&vpp); +} + + +//--------------------------------------------------------------------------- +// Check to see if there is a short on the 1-Wire bus. Used to stop +// communication with the DS2490 while the short is in effect to not +// overrun the buffers. +// +// '*present' - flag set (1) if device presence detected +// '*vpp' - flag set (1) if Vpp programming voltage detected +// +// Returns: TRUE - DS2490 1-Wire is NOT shorted +// FALSE - Could not detect DS2490 or 1-Wire shorted +// +SMALLINT DS2490ShortCheck(usb_dev_handle *hDevice, SMALLINT *present, SMALLINT *vpp) +{ + STATUS_PACKET status; + uchar nResultRegisters; + uint8_t i; + + // get the result registers (if any) + if (!DS2490GetStatus(hDevice, &status, &nResultRegisters)) + return FALSE; + + // get vpp present flag + *vpp = ((status.StatusFlags & STATUSFLAGS_12VP) != 0); + + // Check for short + if(status.CommBufferStatus != 0) + { + return FALSE; + } + else + { + // check for short + for (i = 0; i < nResultRegisters; i++) + { + // check for SH bit (0x02), ignore 0xA5 + if (status.CommResultCodes[i] & COMMCMDERRORRESULT_SH) + { + // short detected + return FALSE; + } + } + } + + // check for No 1-Wire device condition + *present = TRUE; + // loop through result registers + for (i = 0; i < nResultRegisters; i++) + { + // only check for error conditions when the condition is not a ONEWIREDEVICEDETECT + if (status.CommResultCodes[i] != ONEWIREDEVICEDETECT) + { + // check for NRS bit (0x01) + if (status.CommResultCodes[i] & COMMCMDERRORRESULT_NRS) + { + // empty bus detected + *present = FALSE; + } + } + } + + return TRUE; +} + + +//--------------------------------------------------------------------------- +// Stop any on-going pulses +// +// Returns: TRUE - pulse stopped +// FALSE - Could not stop pulse +// +SMALLINT DS2490HaltPulse(usb_dev_handle *hDevice) +{ + STATUS_PACKET status; + uchar nResultRegisters; + SETUP_PACKET setup; + SMALLINT ret; + long limit; + + + // set a time limit + limit = msGettick() + 300; + // loop until confirm pulse has ended or timeout + do + { + // HalExecWhenIdle, Resume Execution to stop an infinite pulse + + // HalExecWhenIdle + setup.RequestTypeReservedBits = 0x40; + setup.Request = CONTROL_CMD; + setup.Value = CTL_HALT_EXE_IDLE; + setup.Index = 0x00; + setup.Length = 0x00; + setup.DataOut = FALSE; + + // call the libusb driver + ret = usb_control_msg(hDevice, + setup.RequestTypeReservedBits, + setup.Request, + setup.Value, + setup.Index, + NULL, + setup.Length, + TIMEOUT_LIBUSB); + + if (ret < 0) + { + // failure + break; + } + + // Resume Execution + setup.RequestTypeReservedBits = 0x40; + setup.Request = CONTROL_CMD; + setup.Value = CTL_RESUME_EXE; + setup.Index = 0x00; + setup.Length = 0x00; + setup.DataOut = FALSE; + + // call the libusb driver + ret = usb_control_msg(hDevice, + setup.RequestTypeReservedBits, + setup.Request, + setup.Value, + setup.Index, + NULL, + setup.Length, + TIMEOUT_LIBUSB); + + if (ret < 0) + { + // failure + break; + } + + // read the status to see if the pulse has been stopped + if (!DS2490GetStatus(hDevice, &status, &nResultRegisters)) + { + // failure + break; + } + else + { + // check the SPU flag + if ((status.StatusFlags & STATUSFLAGS_SPUA) == 0) + { + // success + // disable both pulse types + setup.RequestTypeReservedBits = 0x40; + setup.Request = MODE_CMD; + setup.Value = MOD_PULSE_EN; + setup.Index = 0; + setup.Length = 0x00; + setup.DataOut = FALSE; + // call the libusb driver + ret = usb_control_msg(hDevice, + setup.RequestTypeReservedBits, + setup.Request, + setup.Value, + setup.Index, + NULL, + setup.Length, + TIMEOUT_LIBUSB); + + return TRUE; + } + } + } + while (limit > msGettick()); + + return FALSE; +} + +//--------------------------------------------------------------------------- +// Description: Gets the status of the DS2490 device +// Input: hDevice - the handle to the DS2490 device +// pStatus - the Status Packet to be filled with data +// pResultSize - the number of result register codes returned +// +// Returns: FALSE on failure, TRUE on success +// +SMALLINT DS2490GetStatus(usb_dev_handle *hDevice, STATUS_PACKET *status, uchar *pResultSize) +{ + // buffer to retrieve status + uchar buffer[32]; + uint8_t i = 0; + SMALLINT bufferlength = 0; + + // initialize buffer + memset(&buffer[0],0x00,32); + // get status buffer + bufferlength = usb_bulk_read(hDevice,DS2490_EP1,&buffer[0],32,TIMEOUT_LIBUSB); + + if (bufferlength < 0) + { + OWERROR(OWERROR_ADAPTER_ERROR); + return FALSE; + } + + // make status packet from return buffer + status->EnableFlags = buffer[0]; + status->OneWireSpeed = buffer[1]; + status->StrongPullUpDuration = buffer[2]; + status->ProgPulseDuration = buffer[3]; + status->PullDownSlewRate = buffer[4]; + status->Write1LowTime = buffer[5]; + status->DSOW0RecoveryTime = buffer[6]; + status->Reserved1 = buffer[7]; + status->StatusFlags = buffer[8]; + status->CurrentCommCmd1 = buffer[9]; + status->CurrentCommCmd2 = buffer[10]; + status->CommBufferStatus = buffer[11]; + status->WriteBufferStatus = buffer[12]; + status->ReadBufferStatus = buffer[13]; + status->Reserved2 = buffer[14]; + status->Reserved3 = buffer[15]; + + // take care for CommResultCodes (if they exist) + if (bufferlength > 15) + { + for (i=0; i<16; i++) + { + status->CommResultCodes[i] = buffer[16 + i]; + } + *pResultSize = bufferlength - 16; // This should be the size of CommResultCodes... + } + else + { + *pResultSize = 0; + } + return TRUE; +} + + +//--------------------------------------------------------------------------- +// Description: Perfroms a hardware reset of the DS2490 equivalent to a +// power-on reset +// Input: hDevice - the handle to the DS2490 device +// Returns: FALSE on failure, TRUE on success +// Error Codes: DS2490COMM_ERR_USBDEVICE +// +SMALLINT DS2490Reset(usb_dev_handle *hDevice) +{ + SETUP_PACKET setup; + SMALLINT ret = 0; + + // setup for reset + setup.RequestTypeReservedBits = 0x40; + setup.Request = CONTROL_CMD; + setup.Value = CTL_RESET_DEVICE; + setup.Index = 0x00; + setup.Length = 0x00; + setup.DataOut = FALSE; + // call the libusb driver + ret = usb_control_msg(hDevice, + setup.RequestTypeReservedBits, + setup.Request, + setup.Value, + setup.Index, + NULL, + setup.Length, + TIMEOUT_LIBUSB); + if (ret < 0) + { + OWERROR(OWERROR_ADAPTER_ERROR); + return FALSE; + } + return TRUE; +} + + +//--------------------------------------------------------------------------- +// Description: Reads data from EP3 +// Input: hDevice - the handle to the DS2490 device +// buffer - the size must be >= nBytes +// pnBytes - the number of bytes to read from the device +// Returns: FALSE on failure, TRUE on success +// +SMALLINT DS2490Read(usb_dev_handle *hDevice, uchar *buffer, ushort *pnBytes) +{ + + // Synchronous read: + SMALLINT numOfBytesToRead = *pnBytes; + int nBytes = 0; + + // read + nBytes = usb_bulk_read(hDevice, // handle + DS2490_EP3, // which endpoint to read from + buffer, // buffer to contain read results + numOfBytesToRead, // number of bytes to read + TIMEOUT_LIBUSB); // libusb timeout + + if (nBytes < 0) + { + OWERROR(OWERROR_ADAPTER_ERROR); + return FALSE; + } + *pnBytes = (ushort)nBytes; + return TRUE; +} + +//--------------------------------------------------------------------------- +// Description: Writes data to EP2 +// Input: hDevice - the handle to the DS2490 device +// buffer - the size must be >= nBytes +// pnBytes - the number of bytes to write to the device +// Returns: FALSE on failure, TRUE on success +// +SMALLINT DS2490Write(usb_dev_handle *hDevice, uchar *buffer, ushort *pnBytes) +{ + // Synchronous write: + // assume enough room for write + int nBytes = 0; + int numOfBytesToRead = *pnBytes; + + // write + nBytes = usb_bulk_write(hDevice, // handle + DS2490_EP2, // which endpoint to write + buffer, // buffer to write to endpoint + numOfBytesToRead, // number of bytes to write + TIMEOUT_LIBUSB); // libusb timeout + + if (nBytes < 0) + { + OWERROR(OWERROR_ADAPTER_ERROR); + return FALSE; + } + + *pnBytes = (ushort)nBytes; + return TRUE; +} + diff --git a/src/libusbds2490.h b/src/libusbds2490.h new file mode 100755 index 0000000..157f067 --- /dev/null +++ b/src/libusbds2490.h @@ -0,0 +1,300 @@ +//--------------------------------------------------------------------------- +// Copyright (C) 2004 Dallas Semiconductor Corporation, All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES +// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// Except as contained in this notice, the name of Dallas Semiconductor +// shall not be used except as stated in the Dallas Semiconductor +// Branding Policy. +//--------------------------------------------------------------------------- +// + +#ifndef _ds2490comm_h_ +#define _ds2490comm_h_ + +#define SMALLINT char +#define uchar char + +/*#if defined(_WINDOWS) || defined(__WINDOWS__) || defined(_WIN32) || defined(WIN32) + #define USE_WINDOWS_TIME 1 + #include + #include "win32/usb.h" // libusb header +#else*/ + #define USE_WINDOWS_TIME 0 + #include + #include + + #include +//#endif + +#ifndef ushort +#define ushort uint16_t +#endif + +#ifndef ulong +#define ulong uint32_t +#endif + + +// single byte alignment on structures +#pragma pack(push, 1) + +/** EP1 -- control read */ +#define DS2490_EP1 0x81 +/** EP2 -- bulk write */ +#define DS2490_EP2 0x02 +/** EP3 -- bulk read */ +#define DS2490_EP3 0x83 + +// Error codes +#define DS2490COMM_ERR_NOERROR 0 // an error has not yet been encountered +#define DS2490COMM_ERR_GETLASTERROR 1 // use GetLastError() for more information +#define DS2490COMM_ERR_RESULTREGISTERS 2 // use DS2490COMM_GetLastResultRegister() for more info +#define DS2490COMM_ERR_USBDEVICE 3 // error from USB device driver +#define DS2490COMM_ERR_READWRITE 4 // an I/O error occurred while communicating w/ device +#define DS2490COMM_ERR_TIMEOUT 5 // an operation timed out before completion +#define DS2490COMM_ERR_INCOMPLETEWRITE 6 // not all data could be sent for output +#define DS2490COMM_ERR_INCOMPLETEREAD 7 // not all data could be received for an input +#define DS2490COMM_ERR_INITTOUCHBYTE 8 // the touch byte thread could not be started +#define g_DS2490COMM_LAST_SHORTEDBUS 9 // 1Wire bus shorted on +#define g_DS2490COMM_LAST_EMPTYBUS 10 // 1Wire bus empty + +#define IOCTL_INBUF_SIZE 512 +#define IOCTL_OUTBUF_SIZE 512 +#define TIMEOUT_PER_BYTE 15 //1000 modified 4/27/00 BJV +#define TIMEOUT_LIBUSB 5000 + +// Definition is taken from DDK +typedef struct _USB_DEVICE_DESCRIPTOR { + uchar bLength; + uchar bDescriptorType; + ushort bcdUSB; + ushort bDeviceClass; + uchar bDeviceSubClass; + uchar bDeviceProtocol; + uchar bMaxPacketSize0; + ushort idVendor; + ushort idProduct; + ushort bcdDevice; + uchar iManufacturer; + uchar iProduct; + uchar iSerialNumber; + uchar bNumConfigurations; +} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR; + +// IOCTL codes +#define DS2490_IOCTL_VENDOR CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DS2490_IOCTL_STATUS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DS2490_IOCTL_DEVICE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS) + + +// Device Information is put here +typedef struct _USB_DEVICE_INFO +{ + ulong DriverVersion; + USB_DEVICE_DESCRIPTOR Descriptor; + uchar Unit; +} USB_DEVICE_INFO, *PUSB_DEVICE_INFO; + +// Setup packet +typedef struct _SETUP_PACKET +{ + // Only for vendor specifc bits for COMM commands. + uchar RequestTypeReservedBits; + // The Request byte + uchar Request; + // The Value byte + ushort Value; + // The Index byte + ushort Index; + // The length of extra Data In or Out + ushort Length; + // Does the extra data go In, or Out? + SMALLINT DataOut; + // If there is extra data In, it goes here. + uchar DataInBuffer[0]; +} SETUP_PACKET, *PSETUP_PACKET; + +// Request byte, Command Type Code Constants +#define CONTROL_CMD 0x00 +#define COMM_CMD 0x01 +#define MODE_CMD 0x02 +#define TEST_CMD 0x03 + +// +// Value field, Control commands +// +// Control Command Code Constants +#define CTL_RESET_DEVICE 0x0000 +#define CTL_START_EXE 0x0001 +#define CTL_RESUME_EXE 0x0002 +#define CTL_HALT_EXE_IDLE 0x0003 +#define CTL_HALT_EXE_DONE 0x0004 +#define CTL_CANCEL_CMD 0x0005 +#define CTL_CANCEL_MACRO 0x0006 +#define CTL_FLUSH_COMM_CMDS 0x0007 +#define CTL_FLUSH_RCV_BUFFER 0x0008 +#define CTL_FLUSH_XMT_BUFFER 0x0009 +#define CTL_GET_COMM_CMDS 0x000A + +// +// Value field COMM Command options +// +// COMM Bits (bitwise or into COMM commands to build full value byte pairs) +// Byte 1 +#define COMM_TYPE 0x0008 +#define COMM_SE 0x0008 +#define COMM_D 0x0008 +#define COMM_Z 0x0008 +#define COMM_CH 0x0008 +#define COMM_SM 0x0008 +#define COMM_R 0x0008 +#define COMM_IM 0x0001 + +// Byte 2 +#define COMM_PS 0x4000 +#define COMM_PST 0x4000 +#define COMM_CIB 0x4000 +#define COMM_RTS 0x4000 +#define COMM_DT 0x2000 +#define COMM_SPU 0x1000 +#define COMM_F 0x0800 +#define COMM_ICP 0x0200 +#define COMM_RST 0x0100 + +// Read Straight command, special bits +#define COMM_READ_STRAIGHT_NTF 0x0008 +#define COMM_READ_STRAIGHT_ICP 0x0004 +#define COMM_READ_STRAIGHT_RST 0x0002 +#define COMM_READ_STRAIGHT_IM 0x0001 + +// +// Value field COMM Command options (0-F plus assorted bits) +// +#define COMM_ERROR_ESCAPE 0x0601 +#define COMM_SET_DURATION 0x0012 +#define COMM_BIT_IO 0x0020 +#define COMM_PULSE 0x0030 +#define COMM_1_WIRE_RESET 0x0042 +#define COMM_BYTE_IO 0x0052 +#define COMM_MATCH_ACCESS 0x0064 +#define COMM_BLOCK_IO 0x0074 +#define COMM_READ_STRAIGHT 0x0080 +#define COMM_DO_RELEASE 0x6092 +#define COMM_SET_PATH 0x00A2 +#define COMM_WRITE_SRAM_PAGE 0x00B2 +#define COMM_WRITE_EPROM 0x00C4 +#define COMM_READ_CRC_PROT_PAGE 0x00D4 +#define COMM_READ_REDIRECT_PAGE_CRC 0x21E4 +#define COMM_SEARCH_ACCESS 0x00F4 + +// Mode Command Code Constants +// Enable Pulse Constants +#define ENABLEPULSE_PRGE 0x01 // strong pull-up +#define ENABLEPULSE_SPUE 0x02 // programming pulse + +// 1Wire Bus Speed Setting Constants +#define ONEWIREBUSSPEED_REGULAR 0x00 +#define ONEWIREBUSSPEED_FLEXIBLE 0x01 +#define ONEWIREBUSSPEED_OVERDRIVE 0x02 + +// +// Value field Mode Commands options +// +#define MOD_PULSE_EN 0x0000 +#define MOD_SPEED_CHANGE_EN 0x0001 +#define MOD_1WIRE_SPEED 0x0002 +#define MOD_STRONG_PU_DURATION 0x0003 +#define MOD_PULLDOWN_SLEWRATE 0x0004 +#define MOD_PROG_PULSE_DURATION 0x0005 +#define MOD_WRITE1_LOWTIME 0x0006 +#define MOD_DSOW0_TREC 0x0007 + +// +// This is the status structure as returned by DS2490_IOCTL_STATUS. +// +typedef struct _STATUS_PACKET +{ + uchar EnableFlags; + uchar OneWireSpeed; + uchar StrongPullUpDuration; + uchar ProgPulseDuration; + uchar PullDownSlewRate; + uchar Write1LowTime; + uchar DSOW0RecoveryTime; + uchar Reserved1; + uchar StatusFlags; + uchar CurrentCommCmd1; + uchar CurrentCommCmd2; + uchar CommBufferStatus; // Buffer for COMM commands + uchar WriteBufferStatus; // Buffer we write to + uchar ReadBufferStatus; // Buffer we read from + uchar Reserved2; + uchar Reserved3; + // There may be up to 16 bytes here, or there may not. + uchar CommResultCodes[16]; +} STATUS_PACKET, *PSTATUS_PACKET; + + +// +// STATUS FLAGS +// +// Enable Flags +#define ENABLEFLAGS_SPUE 0x01 // if set Strong Pull-up to 5V enabled +#define ENABLEFLAGS_PRGE 0x02 // if set 12V programming pulse enabled +#define ENABLEFLAGS_SPCE 0x04 // if set a dynamic 1-Wire bus speed change through Comm. Cmd. enabled + +// Device Status Flags +#define STATUSFLAGS_SPUA 0x01 // if set Strong Pull-up is active +#define STATUSFLAGS_PRGA 0x02 // if set a 12V programming pulse is being generated +#define STATUSFLAGS_12VP 0x04 // if set the external 12V programming voltage is present +#define STATUSFLAGS_PMOD 0x08 // if set the DS2490 powered from USB and external sources +#define STATUSFLAGS_HALT 0x10 // if set the DS2490 is currently halted +#define STATUSFLAGS_IDLE 0x20 // if set the DS2490 is currently idle + +// Result Registers +#define ONEWIREDEVICEDETECT 0xA5 // 1-Wire device detected on bus +#define COMMCMDERRORRESULT_NRS 0x01 // if set 1-WIRE RESET did not reveal a Presence Pulse or SET PATH did not get a Presence Pulse from the branch to be connected +#define COMMCMDERRORRESULT_SH 0x02 // if set 1-WIRE RESET revealed a short on the 1-Wire bus or the SET PATH couln not connect a branch due to short +#define COMMCMDERRORRESULT_APP 0x04 // if set a 1-WIRE RESET revealed an Alarming Presence Pulse +#define COMMCMDERRORRESULT_VPP 0x08 // if set during a PULSE with TYPE=1 or WRITE EPROM command the 12V programming pulse not seen on 1-Wire bus +#define COMMCMDERRORRESULT_CMP 0x10 // if set there was an error reading confirmation byte of SET PATH or WRITE EPROM was unsuccessful +#define COMMCMDERRORRESULT_CRC 0x20 // if set a CRC occurred for one of the commands: WRITE SRAM PAGE, WRITE EPROM, READ EPROM, READ CRC PROT PAGE, or READ REDIRECT PAGE W/CRC +#define COMMCMDERRORRESULT_RDP 0x40 // if set READ REDIRECT PAGE WITH CRC encountered a redirected page +#define COMMCMDERRORRESULT_EOS 0x80 // if set SEARCH ACCESS with SM=1 ended sooner than expected with too few ROM IDs + +// Strong Pullup +#define SPU_MULTIPLE_MS 128 +#define SPU_DEFAULT_CODE 512 / SPU_MULTIPLE_MS // default Strong pullup value + +// Programming Pulse +#define PRG_MULTIPLE_US 8 // Programming Pulse Time Multiple (Time = PRG_MULTIPLE_US * DurationCode) +#define PRG_DEFAULT_CODE 512 / PRG_MULTIPLE_US // default Programming pulse value + +// Support functions +SMALLINT DS2490Detect(usb_dev_handle *hDevice); +SMALLINT DS2490GetStatus(usb_dev_handle *hDevice, STATUS_PACKET *status, uchar *pResultSize); +SMALLINT DS2490ShortCheck(usb_dev_handle *hDevice, SMALLINT *present, SMALLINT *vpp); +SMALLINT DS2490Reset(usb_dev_handle *hDevice); +SMALLINT DS2490Read(usb_dev_handle *hDevice, uchar *buffer, ushort *pnBytes); +SMALLINT DS2490Write(usb_dev_handle *hDevice, uchar *buffer, ushort *pnBytes); +SMALLINT DS2490HaltPulse(usb_dev_handle *hDevice); +SMALLINT AdapterRecover(int portnum); + +#endif // _ds2490comm_h_ diff --git a/src/main.cpp b/src/main.cpp new file mode 100755 index 0000000..1987435 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,615 @@ +// Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// * All advertising materials mentioning features or use of this +// software must display the following acknowledgement: This product +// includes software developed by tm3d.de and its contributors. +// * Neither the name of tm3d.de nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include +#include "mySensorDB.h" +#include +#include +#include +#include +#include /* For O_RDWR */ +#include +#include +#include +#include +#include "owTools.h" +#include "hexfile.h" +#include +#include +#include +#include + + + +#define RB "\e(0\x6a\e(B" // 188 Right Bottom corner +#define RT "\e(0\x6b\e(B" // 187 Right Top corner +#define LT "\e(0\x6c\e(B" // 201 Left Top cornet +#define LB "\e(0\x6d\e(B" // 200 Left Bottom corner +#define MC "\e(0\x6e\e(B" // 206 Midle Cross +#define HL "\e(0\x71\e(B" // 205 Horizontal Line +#define LC "\e(0\x74\e(B" // 204 Left Cross +#define RC "\e(0\x75\e(B" // 185 Right Cross +#define BC "\e(0\x76\e(B" // 202 Bottom Cross +#define TC "\e(0\x77\e(B" // 203 Top Cross +#define VL "\e(0\x78\e(B" // 186 Vertical Line +#define SP " " // space string + + +void printhelp() { +printf("owTools - Programm for reading und controlling 1-Wire Devices from www.tm3d.de\n\n"); +printf("run: owTools -a [COMn|USBn|GPIOn] [options]\n\n"); +printf(" COMn -> Adapter DS9097 and compatible (e.g. LinkUSB)\n"); +printf(" n=1 -> Windows COM1 -> Linux /dev/ttyS1\n"); +printf(" USBn -> Adapter DS2490/DS9490 \n"); +printf(" n=1 -> first USB-Adapter \n"); +printf(" GPIOn -> port of Raspberry PI (port Name not Pin number)\n\n"); +printf("options:\n"); +printf(" -i interactive mode\n"); +printf(" select a device and get information about it\n"); +printf(" -c read and print all continuous\n"); +printf(" -p time in sec between readings\n"); +printf(" -d [config file] put all Data in mysql Database descripted in Config file\n"); +printf(" Config file: \n"); +printf(" [server]\n"); +printf(" [port] -> 3306\n"); +printf(" [user] \n"); +printf(" [password]\n"); +printf(" [database]\n"); +printf(" [prefix] -> a prefix of all tables \n\n"); +printf(" -r Search everytime for new Devices\n"); +printf(" -f hexfile Flash new\n"); +printf(" -n change id \n"); +printf(" -g get from server\n"); +printf(" -w [1|2] show Warnings (1) or all Infos (2)\n"); + + + +} + + +typedef struct { + std::string flag; + std::string arg; +} arg_t ; + + +//length of shown chars of an UTF8 string ... sometimes not the same as byte count +std::size_t utf8_length(std::string const &s) { + std::size_t len = 0; + std::string::const_iterator begin = s.begin(), end = s.end(); + while (begin != end) { + unsigned char c = *begin; + int n=1; + if ((c & 0x80) == 0) n = 1; + else if ((c & 0xE0) == 0xC0) n = 2; + else if ((c & 0xF0) == 0xE0) n = 3; + else if ((c & 0xF8) == 0xF0) n = 4; + + len += 1; + begin += n; + } + return len; +} + + +std::vector comlist; + +std::string getArg(std::string flag) { + for(arg_t a:comlist) { + if (a.flag==flag) return a.arg; + } + return ""; +} + + + +int getArgi(std::string flag) { + return atoi(getArg(flag).c_str()); +} + + +int database=0; +mySensorDB *sdb=NULL; + + +snum_t getArgsnum(std::string flag) { + snum_t snum; + snum.num=0; + return snum; +} + +int findCPU(std::string cpu) { + std::ifstream fileInput; + std::string line; + fileInput.open("/proc/cpuinfo"); + if(fileInput.is_open()) { + for(unsigned int curLine = 0; getline(fileInput, line); curLine++) { + if (line.find(cpu) != std::string::npos) { + fileInput.close(); + return 1; + } + } + fileInput.close(); + + } + return 0; +} + + + + +owInterface *owi= NULL; + +void setLogMode() { + if (getArg("w")=="2") + owi->log->setLogLevel(0); + else if (getArg("w")=="2") owi->log->setLogLevel(0); + else owi->log->setLogLevel(OWLOG_ERROR); + +} + + +void continuous(std::vector *devices,int intervall,int headline,int searchrom) { + int first=1; + while (1) { + if (searchrom) { + owi->log->clear(); + owi->Find(); + if (owi->isDevicesChanged()||(first==1)) { + first=0; + if (headline) { + printf(" \t"); + for (owDevice* dev :*devices) { + if (dev->configstate!=OWDCS_NONE) { + for (size_t i=0;i<4;i++) { + if (dev->config->getPropertyID(i)!=0) + printf("\033[1;34m%02X.%02X%02X\033[0m\t",dev->getNum().byte[7],dev->getNum().byte[1],dev->getNum().byte[0]); + } + } + } + printf("\ntime \t"); + for (owDevice* dev :*devices) { + if (dev->configstate!=OWDCS_NONE) { + for (size_t i=0;i<4;i++) { + if (dev->config->getPropertyID(i)!=0) + printf("\033[0;36m%s\033[0m\t",dev->config->getQuantity(i).substr(0,7).c_str()); + } + } + } + printf("\n \t"); + for (owDevice* dev :*devices) { + if (dev->configstate!=OWDCS_NONE) { + for (size_t i=0;i<4;i++) { + if (dev->config->getPropertyID(i)!=0) + printf("\033[3;34m[%s] \033[0m\t",dev->config->getUnit(i).c_str()); + } + } + } + + } + printf("\n"); + + if (database) { + //owi->log->setLogLevel(0); + for (owDevice* dev : *devices) { + sdb->createDeviceTable(dev); + } + } + } + + } + time_t t=time(NULL); + int st=(int)t; + struct tm tm = *localtime(&t); + printf("%d-%02d-%02d %02d:%02d:%02d\t", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); + for (owDevice* dev :*devices) { + for(int k=0;kmaxrepeat;k++){ + dev->convertAll(); + if (owi->log->last()log->clear(); + } + if (owi->log->last()configstate!=OWDCS_NONE) { + for (size_t i=0;i<4;i++) { + if (dev->config->getPropertyID(i)!=0) { + if (dev->values[i]<10) + printf("%0.4f \t",dev->values[i]); + else if (dev->values[i]<100) + printf("%0.3f \t",dev->values[i]); + else if (dev->values[i]<1000) + printf("%0.2f \t",dev->values[i]); + else + printf("%0.1f \t",dev->values[i]); + fflush(stdout); + } + } + } + if (database) { + sdb->insertValues(dev); + } + } else { + owi->log->setLogLevel(OWLOG_INFO); + owi->log->set(OWLOG_ERROR,"Too many errors, mybee conection is dead."); + return; + } + + + } + printf("\n"); + while (((int)time(NULL))<(st+intervall)) sleep(1); + } +} + +void device_menu(owDevice* d) { + for(int i=0;i<70;i++) printf(HL);printf("\n"); + printf("Selected Device: "); + snum_t snum=d->getNum(); + printf("\033[1;34m%016llX\033[0m",(unsigned long long)snum.num); + printf(" \n"); + printf("Chip Info: "); + std::vector info=d->getFamilyInfo(); + for (std::string s : info) printf(" %s",s.c_str()); + printf("\n"); + printf("Values info: "); + int tm3d=d->readConfig(); + for (size_t i=0;i<4;i++) { + printf("%s in %s",d->config->getQuantity(i).c_str(),d->config->getUnit(i).c_str()); + if (i<4) printf("; "); + } + if (tm3d) printf(" (tm3d.de)"); else printf(" (default)"); + printf("\n"); + d->convertAll(); + for (size_t i=0;ivalues.size();i++) { + printf("\033[1;33m%0.4f %s\033[0m ",d->values[i],d->config->getUnit(i).c_str()); + } + printf("\n"); + for(int i=0;i<70;i++) printf(HL);printf("\n"); + printf("0) Exit\n"); + printf("1) Run continuous\n"); + std::string inp; + while (1) { + printf("Select an option: ");std::getline (std::cin,inp); + int dnr=atoi(inp.c_str()); + if (dnr<=0) return; + if (dnr==1) { + std::vector v; + v.push_back(d); + continuous(&v,1,1,0); + } +// if (dnr<=i) break; + // printf("\033[4;33mSelect a number between 0 and %i\033[0m\n",i); + } + + +} + +int selectDevice() { + owi->Find(); + int i=0; + for (owDevice* dev :owi->devices) { + i++; + snum_t snum=dev->getNum(); + printf("%i) ",i); + printf("\033[1;34m%016llX\033[0m",(unsigned long long)snum.num); + + printf(" "); + for (int j=0;j<4;j++) printf("%s ",dev->config->getQuantity(j).c_str()); + printf("\n"); + } + printf("0) Exit Programm\n"); + std::string inp; + int dnr=0; + while (1) { + printf("Select device with number: ");std::getline (std::cin,inp); + dnr=atoi(inp.c_str()); + if (dnr<=0) return 0; + if (dnr<=i) break; + printf("\033[4;33mSelect a number between 0 and %i\033[0m\n",i); + } + return dnr; + +} + +int questionYesNo(std::string text) { + std::string inp; + printf("%s [Y/n] ",text.c_str());std::getline (std::cin,inp); + if (inp=="Y") return 1; else return 0; + +} + +void interactive(owInterface *owi) { + while (1) { + int i=selectDevice(); + if (i==0 ) return; + device_menu(owi->devices[i-1]); + } +} + +int main(int argc, char *argv[]) { + int i; + arg_t a; + //printf("Kommando: %s:\n", argv[0]); + while (--argc) { + if (**++argv != '-') { + //printf(" Arg. = %s\n", *argv); + if (comlist.empty()) { + a.flag="."; + a.arg=*argv; + comlist.push_back(a); + } else { + if ((*(comlist.end()-1)).arg!="1") { + a.flag="."; + a.arg=*argv; + comlist.push_back(a); + } else { + (*(comlist.end()-1)).arg=*argv; + } + } + } else { + for( i=1; (*argv)[i] != '\0'; i++) { + //printf(" Flag = (%c)\n", (*argv)[i]); + a.flag=(*argv)[i]; + a.arg="1"; + comlist.push_back(a); + } + } + } + + //for(arg_t a:comlist) printf("%s->%s\n",a.flag.c_str(),a.arg.c_str()); + if (getArg("h")=="1") { + printhelp(); + return 0; + } + std::string adapter=getArg("a"); + if (adapter.empty()) { + printhelp(); + return 0; + } + std::transform(adapter.begin(), adapter.end(),adapter.begin(), ::toupper); + + std::string s; + + if(adapter.find("COM")!=std::string::npos) { + owi=new owCOMInterface(); + int port=atoi(adapter.substr(adapter.find("COM")+3).c_str()); + printf("Open /dev/ttyS%i\n",port); + owi->InitAdapter(port); + } else + if(adapter.find("USB")!=std::string::npos) { + owi=new owUSBInterface(); + int port=atoi(adapter.substr(adapter.find("USB")+3).c_str()); + printf("Open the %i. USB Adapter\n",port); + int err; + if ((err=owi->InitAdapter(port))<0) { + if (err==-1) printf("No Adapter found!\n On Linux, try: sudo owTools....\n On Windows: Install libusb0 driver\n"); + if (err==-2) printf("Maybe Adapter is used ... (try sudo)\nOn Linux: If the kernel modul is loaded type: sudo rmmod ds2490\n"); + exit(0); + } + } else + if(adapter.find("GPIO")!=std::string::npos) { + if (findCPU("BCM2708")) { + printf("\033[1;33mRaspberry Pi 1 is dedected. 1-wire on the GPIO port can have many errors in the transfer.\033[0m\n"); + owi=new owPiGPioInterface(); + int port=atoi(adapter.substr(adapter.find("GPIO")+4).c_str()); + printf("Open GPIO %i\n",port); + } else if (findCPU("BCM2709")) { + owi=new owPiGPioInterface(); + int port=atoi(adapter.substr(adapter.find("GPIO")+4).c_str()); + printf("Open GPIO %i\n",port); + owi->InitAdapter(port); + } else { + printf("\033[1;31mGPIO works with Raspberry PI only \033[0m\n"); + } + } + if (owi==NULL) { + return 0; + } + + setLogMode(); + + + if (getArg("i")=="1") { + interactive(owi); + } else + if (getArg("c")=="1") { + int reload=(getArg("r")=="1"); + owi->Find(); + printf("\n"); + //owi->log->setLogLevel(3); + std::string s; + int pause; + if ((s=getArg("p")) !="") { + pause=atoi(s.c_str()); + } else pause=30; + if ((s=getArg("d")) !="") { + reload=1; + printf("Use Database\n"); + sdb=new mySensorDB(s,owi->log); + if (sdb->log->last()>OWLOG_WARNING) { + exit(1); + } + sdb->connect(); + if (sdb->log->last()>OWLOG_WARNING) { + exit(1); + } + sdb->createSensorTable(); + if (sdb->log->last()>OWLOG_WARNING) { + exit(1); + } + database=1; + } + + + continuous(&(owi->devices),pause,1,reload); + } else + if ((s=getArg("f"))!="") { + printf("Flash %s in selected Device\n",s.c_str()); + int sel=selectDevice(); + if (sel==0) exit(0); + int resetid=questionYesNo("Would you reset to default ID? (This is necessary if another device is used!)"); + owi->log->setLogLevel(OWLOG_INFO); + owi->flashHEXFile(s,owi->device_nums[sel-1],resetid,1); + setLogMode(); + owi->Clean(); + owi->Find(); + for (owDevice* dev :owi->devices) { + snum_t snum=dev->getNum(); + printf("\033[1;34m%016llX\033[0m",(unsigned long long)snum.num); + + printf("\n"); + } + printf("%i Devices found\n",(int)owi->devices.size()); + + } else + + if ((s=getArg("n"))!="") { + printf("Change id of selected Device\n"); + int sel=selectDevice(); + if (sel==0) exit(0); + sel-=1; + + snum_t snum=owi->devices[sel]->getNum(); + if ((getArg("g"))=="1") { + printf("get ID from Server\n"); + char s[255]; + sprintf(s,"wget -q http://www.tm3d.de/shop99/owid.php?fam=%02X -O id.txt",snum.byte[0]); + int err; + if ((err=system(s))==0) { + printf("OK!\n"); + std::string rs; + std::stringstream str; + std::ifstream fs; + fs.open ("id.txt" ); + snum_t isnum; + int i=0; int br=0; + if(fs.is_open()) { + while(fs.peek() != EOF) { + char c= (char) fs.get(); + if (br==0) { + if (c=='x') br=1; + } else { + if ((c==',')|(c=='}')) { + isnum.byte[i]=strtol(s, NULL, 16); + //printf("%x\n",strtol(s, NULL, 16)); + i++; + br=0; + s[0]=0; + } else { + s[br-1]=c; + s[br]=0; + br++; + } + } + if (c=='}') break; + } + + fs.close(); + } + snum.num=isnum.num; + } else (printf("ERROR %i\n",err)); + } else { + snum.num+=256; + } + + + printf("New ID: "); + printf("\033[1;34m%016llX\033[0m",(unsigned long long)snum.num); + + printf("\n"); + + owi->devices[sel]->changeID(snum); + + owi->Clean(); + owi->Find(); + for (owDevice* dev :owi->devices) { + snum_t snum=dev->getNum(); + printf("\033[1;34m%016llX\033[0m",(unsigned long long)snum.num); + + printf("\n"); + } + printf("%i Devices found\n",(int)owi->devices.size()); + + } else { + owi->Find(); + for (owDevice* dev :owi->devices) { + printf("_______________________________________________________________________\n"); + snum_t snum=dev->getNum(); + printf("\033[1;34m%016llX\033[0m ",(unsigned long long)snum.num); + switch (dev->configstate) { + case OWDCS_16:printf("old Configcode from www.tm3d.de");break; + case OWDCS_24:printf("Configcode from www.tm3d.de");break; + case OWDCS_DEFAULT:printf("Default Configcode set by this Software");break; + case OWDCS_NONE:printf("No Configcode");break; + } + printf( " - ("); + for(int i=0;i<3;i++) + printf(" %s",dev->getFamilyInfo()[i].c_str()); + printf(" )\n"); + if (dev->configstate!=OWDCS_NONE) { + std::vector> ia; + std::vector maxcol; + dev->convertAll(); + for(int i=0;i<4;i++) { + std::vector colm; + size_t max=0; + colm.push_back(dev->config->getSensorChip(i)); + if (maxconfig->getQuantity(i)); + if (maxconfig->getUnit(i)); + if (maxconfig->getPropertyID(i)==0) { + colm.push_back(""); + } else { + char hs[50]; + sprintf(hs,"%0.3f",dev->values[i]); + colm.push_back(hs); + } + if (maxdevices.size()); + } + return 0; + +} diff --git a/src/mySensorDB.cpp b/src/mySensorDB.cpp new file mode 100755 index 0000000..76631e3 --- /dev/null +++ b/src/mySensorDB.cpp @@ -0,0 +1,210 @@ +// Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// * All advertising materials mentioning features or use of this +// software must display the following acknowledgement: This product +// includes software developed by tm3d.de and its contributors. +// * Neither the name of tm3d.de nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include "mySensorDB.h" +#include +#include +#include +#include +mySensorDB::mySensorDB(std::string configfile, owLog* log) { + this->log=log; + log->clear(); + my=0; + readConfigFile(configfile); + if (log->last()set(OWLOG_ERROR,"ERROR: Could not initialize Mysql"); + } + } +} + +int mySensorDB::readConfigFile(std::string configfile) { + std::ifstream dbc(configfile); + if (!dbc) { + log->set(OWLOG_ERROR,"Error reading database config file %s",configfile.c_str()); + return -1; + } + int lc=0; + std::string line; + while (std::getline(dbc, line)) { + switch (lc) { + case 0:myserver=line;break; + case 1:myport=line;break; + case 2:myuser=line;break; + case 3:mypass=line;break; + case 4:mydb=line;break; + case 5:mypre=line;break; + } + lc++; + if (lc==6) break; + } + if (lc<6) { + log->set(OWLOG_ERROR,"ERROR: Database config file isn't correct. (not 6 lines)\n"); + return -2; + } + return 0; +} + + +int mySensorDB::connect() { + if( mysql_real_connect ( + my, /* Zeiger auf MYSQL-Handler */ + myserver.c_str(), /* Host-Name */ + myuser.c_str(), /* User-Name */ + mypass.c_str(), /* Passwort für user_name */ + mydb.c_str(), /* Name der Datenbank */ + atol(myport.c_str()), /* Port (default=0) */ + NULL, /* Socket (default=NULL) */ + 0 /* keine Flags */ ) == NULL) { + + log->set(OWLOG_ERROR,"ERROR mysql_real_connect(): %u (%s)\n",mysql_errno (my), mysql_error (my)); + return -1; + } + printf("DB ok\n"); + return 0; +} + +int mySensorDB::createSensorTable() { + std::string query="CREATE TABLE IF NOT EXISTS `"+mypre+"sensors` (" + " `sid` varchar(20) NOT NULL COMMENT 'owID + number of 1 to 4' ," + " `sdescription` varchar(128) DEFAULT NULL," + " `schip` varchar(120) DEFAULT NULL COMMENT 'Chip of mesasurement'," + " `smaxval` double DEFAULT NULL COMMENT 'Maximal value'," + " `sminval` double DEFAULT NULL COMMENT 'Minimal value'," + " `slocation` varchar(60) DEFAULT NULL COMMENT 'Position of Sensor, if needed'," + " `stype` varchar(40) DEFAULT NULL COMMENT 'Name of pysical property'," + " `sunit` varchar(20) DEFAULT NULL COMMENT 'Physical unit'," + " `sprecision` double DEFAULT NULL COMMENT '+- precission'," + " `sprecisionlong` text DEFAULT NULL COMMENT 'a table of specific precission values'," + " `sfirstuse` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP," + " `scalib_m` double DEFAULT '0' COMMENT 'an optional addition value'," + " `scalib_n` double DEFAULT '1' COMMENT 'an optimal multip. value', " + " `shidden` tinyint(1) DEFAULT '0' COMMENT 'for automatic presentation'," + " `sformelcode` tinyint(1) DEFAULT '0' COMMENT 'code of the formel'," + " `stypecode` tinyint(1) DEFAULT '0' COMMENT 'code of the property'," + " PRIMARY KEY (`sid`)" + ") DEFAULT CHARSET=utf8;"; + + if (mysql_query(my,query.c_str() )) { + log->set(OWLOG_ERROR, "ERROR mysql_query: %u (%s)\n",mysql_errno (my), mysql_error (my)); + return -1; + } + return 0; +} + + + +int mySensorDB::createDeviceTable(owDevice *dev) { + if (dev->config->valid) { + std::string s; + char hs[50]; + s="SELECT sid FROM "+mypre+"sensors WHERE sid='"; + sprintf(hs,"%016llX",(unsigned long long)dev->getNum().num); + s=s+hs+"_1';"; + if (mysql_query(my,s.c_str())) { + //printf("ERROR communicating Database\n"); + log->set(OWLOG_ERROR,"ERROR mysql_query: %u (%s)\n",mysql_errno (my), mysql_error (my)); + return -1; + } + MYSQL_RES *result = mysql_store_result(my); + if (result == NULL) { + //finish_with_error(my); + log->set(OWLOG_ERROR,"ERROR get result from Database\n"); + return -1; + } + if (mysql_num_rows(result)==0) { + log->set(OWLOG_INFO,"Sensor not in Database\n"); + std::string cols; + cols="CREATE TABLE IF NOT EXISTS `"+mypre+"OW"+std::string(hs)+"` (`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP "; + for (size_t i=0;i<4;i++) { + if (dev->config->getPropertyID(i)!=0) { + cols+=", `"; + cols+=std::string(hs)+"_"+std::to_string(i+1); + cols+="` double DEFAULT NULL "; + std::string query; + query="INSERT INTO "+mypre+"sensors (sid,schip,stype,sunit,sformelcode,stypecode) VALUES ('"+std::string(hs)+"_"+std::to_string(i+1)+"' "; + query+=", '"+dev->config->getSensorChip(i)+"' , '"; + query+=dev->config->getQuantity(i)+"' , '"; + query+=dev->config->getUnit(i)+"' ," ; + query+=std::to_string(dev->config->getFormulaID(i))+" ,"; + query+=std::to_string(dev->config->getPropertyID(i))+");"; + //printf("%s\n",query.c_str()); + if (mysql_query(my,query.c_str())) { + log->set(OWLOG_ERROR, "ERROR mysql_query: %u (%s)\n",mysql_errno (my), mysql_error (my)); + return -1; + } + } + } + cols+=", PRIMARY KEY (`time`) ) DEFAULT CHARSET=utf8;"; + //printf("%s\n",cols.c_str()); + if (mysql_query(my,cols.c_str())) { + log->set(OWLOG_ERROR, "ERROR mysql_query: %u (%s)\n",mysql_errno (my), mysql_error (my)); + return -1; + } + + } + //int num_fields=mysql_num_fields(result) + //MYSQL_ROW row; + //while ((row = mysql_fetch_row(result))) { + // for(int i = 0; i < num_fields; i++) { + // printf("%s ", row[i] ? row[i] : "NULL"); + // } + // printf("\n"); + //} + mysql_free_result(result); + } + return 0; +} + +int mySensorDB::insertValues(owDevice *dev) { + if (dev->config->valid) { + char hs[50]; + sprintf(hs,"%016llX",(unsigned long long)dev->getNum().num); + std::string query; + query="INSERT INTO `"+mypre+"OW"+std::string(hs)+"` ("; + for (size_t i=0;i<4;i++) if (dev->config->getPropertyID(i)!=0) query+=std::string(hs)+"_"+std::to_string(i+1)+", "; + query.pop_back();query.pop_back(); + query+=") VALUES ("; + for (size_t i=0;i<4;i++) if (dev->config->getPropertyID(i)!=0) query+=std::to_string(dev->values[i])+", "; + query.pop_back();query.pop_back(); + query+=");"; + //printf("%s\n",query.c_str()); + if (mysql_query(my,query.c_str())) { + log->set(OWLOG_ERROR, "ERROR mysql_query: %u (%s)\n",mysql_errno (my), mysql_error (my)); + return -1; + } + } + + return 0; +} diff --git a/src/mySensorDB.h b/src/mySensorDB.h new file mode 100755 index 0000000..c09e75c --- /dev/null +++ b/src/mySensorDB.h @@ -0,0 +1,65 @@ +// Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// * All advertising materials mentioning features or use of this +// software must display the following acknowledgement: This product +// includes software developed by tm3d.de and its contributors. +// * Neither the name of tm3d.de nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef __MYSENSORDB_H_ +#define __MYSENSORDB_H_ +#include "owInterface.h" +#include +#include +#include +#include +#include + +#include + + +class mySensorDB { +protected: + std::string myserver; + std::string myport; + std::string myuser; + std::string mypass; + std::string mydb; + std::string mypre; + + MYSQL *my; + int readConfigFile(std::string configfile); +public: + owLog *log; + mySensorDB(std::string configfile , owLog* log); + int connect(); + int createSensorTable(); + int createDeviceTable(owDevice *d); + int insertValues(owDevice *d); +}; + +#endif diff --git a/src/owCOMInterface.cpp b/src/owCOMInterface.cpp new file mode 100755 index 0000000..b825b6e --- /dev/null +++ b/src/owCOMInterface.cpp @@ -0,0 +1,686 @@ +// Copyright (c) 2016, Tobias Mueller tm(at)tm3d.de +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// * All advertising materials mentioning features or use of this +// software must display the following acknowledgement: This product +// includes software developed by tm3d.de and its contributors. +// * Neither the name of tm3d.de nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "owCOMInterface.h" + +// Mode Commands +#define MODE_DATA 0xE1 +#define MODE_COMMAND 0xE3 +#define MODE_STOP_PULSE 0xF1 + +// Return byte value +#define RB_CHIPID_MASK 0x1C +#define RB_RESET_MASK 0x03 +#define RB_1WIRESHORT 0x00 +#define RB_PRESENCE 0x01 +#define RB_ALARMPRESENCE 0x02 +#define RB_NOPRESENCE 0x03 + +#define RB_BIT_MASK 0x03 +#define RB_BIT_ONE 0x03 +#define RB_BIT_ZERO 0x00 + +// Masks for all bit ranges +#define CMD_MASK 0x80 +#define FUNCTSEL_MASK 0x60 +#define BITPOL_MASK 0x10 +#define SPEEDSEL_MASK 0x0C +#define MODSEL_MASK 0x02 +#define PARMSEL_MASK 0x70 +#define PARMSET_MASK 0x0E +#define VERSION_MASK 0x1C + +// Command or config bit +#define CMD_COMM 0x81 +#define CMD_CONFIG 0x01 + +// Function select bits +#define FUNCTSEL_BIT 0x00 +#define FUNCTSEL_SEARCHON 0x30 +#define FUNCTSEL_SEARCHOFF 0x20 +#define FUNCTSEL_RESET 0x40 +#define FUNCTSEL_CHMOD 0x60 + +// Bit polarity/Pulse voltage bits +#define BITPOL_ONE 0x10 +#define BITPOL_ZERO 0x00 +#define BITPOL_5V 0x00 +#define BITPOL_12V 0x10 + +// One Wire speed bits +#define SPEEDSEL_STD 0x00 +#define SPEEDSEL_FLEX 0x04 +#define SPEEDSEL_OD 0x08 +#define SPEEDSEL_PULSE 0x0C + +// Data/Command mode select bits +#define MODSEL_DATA 0x00 +#define MODSEL_COMMAND 0x02 + +// 5V Follow Pulse select bits (If 5V pulse +// will be following the next byte or bit.) +#define PRIME5V_TRUE 0x02 +#define PRIME5V_FALSE 0x00 + +// Parameter select bits +#define PARMSEL_PARMREAD 0x00 +#define PARMSEL_SLEW 0x10 +#define PARMSEL_12VPULSE 0x20 +#define PARMSEL_5VPULSE 0x30 +#define PARMSEL_WRITE1LOW 0x40 +#define PARMSEL_SAMPLEOFFSET 0x50 +#define PARMSEL_ACTIVEPULLUPTIME 0x60 +#define PARMSEL_BAUDRATE 0x70 + +// Pull down slew rate. +#define PARMSET_Slew15Vus 0x00 +#define PARMSET_Slew2p2Vus 0x02 +#define PARMSET_Slew1p65Vus 0x04 +#define PARMSET_Slew1p37Vus 0x06 +#define PARMSET_Slew1p1Vus 0x08 +#define PARMSET_Slew0p83Vus 0x0A +#define PARMSET_Slew0p7Vus 0x0C +#define PARMSET_Slew0p55Vus 0x0E + +// 12V programming pulse time table +#define PARMSET_32us 0x00 +#define PARMSET_64us 0x02 +#define PARMSET_128us 0x04 +#define PARMSET_256us 0x06 +#define PARMSET_512us 0x08 +#define PARMSET_1024us 0x0A +#define PARMSET_2048us 0x0C +#define PARMSET_infinite 0x0E + +// 5V strong pull up pulse time table +#define PARMSET_16p4ms 0x00 +#define PARMSET_65p5ms 0x02 +#define PARMSET_131ms 0x04 +#define PARMSET_262ms 0x06 +#define PARMSET_524ms 0x08 +#define PARMSET_1p05s 0x0A +#define PARMSET_2p10s 0x0C +#define PARMSET_infinite 0x0E + +// Write 1 low time +#define PARMSET_Write8us 0x00 +#define PARMSET_Write9us 0x02 +#define PARMSET_Write10us 0x04 +#define PARMSET_Write11us 0x06 +#define PARMSET_Write12us 0x08 +#define PARMSET_Write13us 0x0A +#define PARMSET_Write14us 0x0C +#define PARMSET_Write15us 0x0E + +// Data sample offset and Write 0 recovery time +#define PARMSET_SampOff3us 0x00 +#define PARMSET_SampOff4us 0x02 +#define PARMSET_SampOff5us 0x04 +#define PARMSET_SampOff6us 0x06 +#define PARMSET_SampOff7us 0x08 +#define PARMSET_SampOff8us 0x0A +#define PARMSET_SampOff9us 0x0C +#define PARMSET_SampOff10us 0x0E + +// Active pull up on time +#define PARMSET_PullUp0p0us 0x00 +#define PARMSET_PullUp0p5us 0x02 +#define PARMSET_PullUp1p0us 0x04 +#define PARMSET_PullUp1p5us 0x06 +#define PARMSET_PullUp2p0us 0x08 +#define PARMSET_PullUp2p5us 0x0A +#define PARMSET_PullUp3p0us 0x0C +#define PARMSET_PullUp3p5us 0x0E + +// Baud rate bits +#define PARMSET_9600 0x00 +#define PARMSET_19200 0x02 +#define PARMSET_57600 0x04 +#define PARMSET_115200 0x06 + +// DS2480B program voltage available +#define DS2480PROG_MASK 0x20 + +// mode bit flags +#define MODE_NORMAL 0x00 +#define MODE_OVERDRIVE 0x01 +#define MODE_STRONG5 0x02 +#define MODE_PROGRAM 0x04 +#define MODE_BREAK 0x08 + +// Versions of DS2480 +#define VER_LINK 0x1C +#define VER_DS2480 0x08 +#define VER_DS2480B 0x0C + + + + +//--------------------------------------------------------------------------- +// Description: +// flush the rx and tx buffers +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// +void owCOMInterface::FlushCOM() { + tcflush(fd, TCIOFLUSH); +} + + +int owCOMInterface::OpenCOM(uint8_t comnr) { + struct termios t; // see man termios - declared as above + int rc; + //int fd; + char port_zstr[100]; + if (com_init) return fd; + + sprintf(port_zstr,"/dev/ttyUSB%i",comnr); + + fd = open(port_zstr, O_RDWR|O_NONBLOCK); + if (fd<0) + { + log->set(OWLOG_ERROR,"ERROR open Com %s return %i",port_zstr,fd); + return fd; + } + rc = tcgetattr (fd, &t); + if (rc < 0) + { + int tmp; + tmp = errno; + close(fd); + errno = tmp; + log->set(OWLOG_ERROR,"OWERROR_SYSTEM_RESOURCE_INIT_FAILED %s",port_zstr); + return rc; // changed (2.00), used to return rc; + } + + cfsetospeed(&t, B9600); + cfsetispeed (&t, B9600); + + // Get terminal parameters. (2.00) removed raw + tcgetattr(fd,&t); + // Save original settings. + origterm = t; + + // Set to non-canonical mode, and no RTS/CTS handshaking + t.c_iflag &= ~(BRKINT|ICRNL|IGNCR|INLCR|INPCK|ISTRIP|IXON|IXOFF|PARMRK); + t.c_iflag |= IGNBRK|IGNPAR; + t.c_oflag &= ~(OPOST); + t.c_cflag &= ~(CRTSCTS|CSIZE|HUPCL|PARENB); + t.c_cflag |= (CLOCAL|CS8|CREAD); + t.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|IEXTEN|ISIG); + t.c_cc[VMIN] = 0; + t.c_cc[VTIME] = 3; + + rc = tcsetattr(fd, TCSAFLUSH, &t); + tcflush(fd,TCIOFLUSH); + + if (rc < 0) + { + int tmp; + tmp = errno; + close(fd); + errno = tmp; + log->set(OWLOG_ERROR,"OWERROR_SYSTEM_RESOURCE_INIT_FAILED %s",port_zstr); + return rc; // changed (2.00), used to return rc; + } + com_init=1; + return fd; // changed (2.00), used to return fd; +} + + +//--------------------------------------------------------------------------- +// Closes the connection to the port. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// +void owCOMInterface::CloseCOM() +{ + // restore tty settings + tcsetattr(fd, TCSAFLUSH, &origterm); + FlushCOM(); + close(fd); + com_init=0; + +} + + +//-------------------------------------------------------------------------- +// Write an array of bytes to the COM port, verify that it was +// sent out. Assume that baud rate has been set. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number provided will +// be used to indicate the port number desired when calling +// all other functions in this library. +// Returns 1 for success and 0 for failure +// +int owCOMInterface::WriteCOM( int outlen, uint8_t *outbuf) +{ + long count = outlen; + int i = write(fd, outbuf, outlen); + + tcdrain(fd); + return (i == count); +} + + +//-------------------------------------------------------------------------- +// Read an array of bytes to the COM port, verify that it was +// sent out. Assume that baud rate has been set. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// 'outlen' - number of bytes to write to COM port +// 'outbuf' - pointer ot an array of bytes to write +// +// Returns: TRUE(1) - success +// FALSE(0) - failure +// +int owCOMInterface::ReadCOM( int inlen, uint8_t *inbuf) +{ + fd_set filedescr; + struct timeval tval; + int cnt; + + // loop to wait until each byte is available and read it + for (cnt = 0; cnt < inlen; cnt++) + { + // set a descriptor to wait for a character available + FD_ZERO(&filedescr); + FD_SET(fd,&filedescr); + // set timeout to 10ms + tval.tv_sec = 0; + tval.tv_usec = 10000; + + // if byte available read or return bytes read + if (select(fd+1,&filedescr,NULL,NULL,&tval) != 0) + { + if (read(fd,&inbuf[cnt],1) != 1) { + log->set(OWLOG_ERROR,"Read Error on Serial"); + + return cnt; + } + } + else { + log->set(OWLOG_ERROR,"Read Error on Serial (select)"); + return cnt; + } + } + + // success, so return desired length + return inlen; +} + + + + +//-------------------------------------------------------------------------- +// Description: +// Send a break on the com port for at least 2 ms +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// +void owCOMInterface::BreakCOM() +{ + int duration = 0; // see man termios break may be + tcsendbreak(fd, duration); // too long +} + + +//-------------------------------------------------------------------------- +// Set the baud rate on the com port. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// 'new_baud' - new baud rate defined as +// PARMSET_9600 0x00 +// PARMSET_19200 0x02 +// PARMSET_57600 0x04 +// PARMSET_115200 0x06 +// +void owCOMInterface::SetBaudCOM( uint8_t new_baud) +{ + struct termios t; + int rc; + speed_t baud; + + // read the attribute structure + rc = tcgetattr(fd, &t); + if (rc < 0) + { + close(fd); + log->set(OWLOG_ERROR,"Error on Serial (set Boudrate)"); + + return; + } + + // convert parameter to linux baud rate + switch(new_baud) + { + case PARMSET_9600: + baud = B9600; + break; + case PARMSET_19200: + baud = B19200; + break; + case PARMSET_57600: + baud = B57600; + break; + case PARMSET_115200: + baud = B115200; + break; + default: + baud = B9600; + break; + } + + // set baud in structure + cfsetospeed(&t, baud); + cfsetispeed(&t, baud); + + // change baud on port + rc = tcsetattr(fd, TCSAFLUSH, &t); + if (rc < 0) { + log->set(OWLOG_ERROR,"Error on Serial (set Boudrate)"); + + close(fd); + } +} + + +//--------------------------------------------------------------------------- +// Attempt to resyc and detect a DS2480B +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// +// Returns: TRUE - DS2480B detected successfully +// FALSE - Could not detect DS2480B +// + +int8_t owCOMInterface::DS2480Detect(){ + uint8_t sendpacket[10],readbuffer[10]; + uint8_t sendlen=0; + + // reset modes + UMode = MODSEL_COMMAND; + UBaud = PARMSET_9600; + USpeed = SPEEDSEL_FLEX; + + // set the baud rate to 9600 + SetBaudCOM((uint8_t)UBaud); + + // send a break to reset the DS2480 + BreakCOM(); + + // delay to let line settle + usleep(2000); + + // flush the buffers + FlushCOM(); + + // send the timing byte + sendpacket[0] = 0xC1; + if (WriteCOM(1,sendpacket) != 1) + { + log->set(OWLOG_ERROR,"Error on Serial (Write in DS2480Detect)"); + return FALSE; + } + + // delay to let line settle + usleep(4000); + + // set the FLEX configuration parameters + // default PDSRC = 1.37Vus + sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_SLEW | PARMSET_Slew1p37Vus; + // default W1LT = 10us + sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_WRITE1LOW | PARMSET_Write10us; + // default DSO/WORT = 8us + sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_SAMPLEOFFSET | PARMSET_SampOff8us; + + // construct the command to read the baud rate (to test command block) + sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_PARMREAD | (PARMSEL_BAUDRATE >> 3); + + // also do 1 bit operation (to test 1-Wire block) + sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_BIT | UBaud | BITPOL_ONE; + + // flush the buffers + FlushCOM(); + + // send the packet + if (WriteCOM(sendlen,sendpacket)) + { + // read back the response + if (ReadCOM(5,readbuffer) == 5) + { + // look at the baud rate and bit operation + // to see if the response makes sense + if (((readbuffer[3] & 0xF1) == 0x00) && + ((readbuffer[3] & 0x0E) == UBaud) && + ((readbuffer[4] & 0xF0) == 0x90) && + ((readbuffer[4] & 0x0C) == UBaud)) + return TRUE; + else + log->set(OWLOG_ERROR,"OWERROR_DS2480_BAD_RESPONSE\n"); + } + else + // printf("OWERROR_READCOM_FAILED\n"); + log->set(OWLOG_ERROR,"OWERROR_READCOM_FAILED"); + } + else + //printf("OWERROR_READCOM_FAILED\n"); + log->set(OWLOG_ERROR,"OWERROR_WRITECOM_FAILED"); + + return FALSE; +} + + + + + + + + + + + + + + + + + + +int owCOMInterface::InitAdapter(uint8_t nr) { + // attempt to open the communications port + if ((fd = OpenCOM(nr)) < 0) + { + log->set(OWLOG_ERROR,"OWERROR_OPENCOM_FAILED"); + return -1; + } + + // detect DS2480 + if (!DS2480Detect()) + { + CloseCOM(); + log->set(OWLOG_ERROR,"OWERROR_DS2480_NOT_DETECTED"); + return -1; + } + com_init=1; + return 1; +} + +void owCOMInterface::ReleaseAdapter() { + CloseCOM(); +} + + +int owCOMInterface::Reset() { + uint8_t readbuffer[10],sendpacket[10]; + uint8_t sendlen=0; + + // check if correct mode + if (UMode != MODSEL_COMMAND) { + UMode = MODSEL_COMMAND; + sendpacket[sendlen++] = MODE_COMMAND; + } + + // construct the command + sendpacket[sendlen++] = (uint8_t)(CMD_COMM | FUNCTSEL_RESET | USpeed); + // flush the buffers + FlushCOM(); + // send the packet + if (WriteCOM(sendlen,sendpacket)) + { + // read back the 1 byte response + if (ReadCOM(1,readbuffer) == 1) + { + // make sure this byte looks like a reset byte + if (((readbuffer[0] & RB_RESET_MASK) == RB_PRESENCE) || + ((readbuffer[0] & RB_RESET_MASK) == RB_ALARMPRESENCE)) + { + // check if programming voltage available + UVersion = (readbuffer[0] & VERSION_MASK); + return 1; + } + else + log->set(OWLOG_ERROR,"OWERROR_RESET_FAILED"); + + } + else + log->set(OWLOG_ERROR,"OWERROR_READCOM_FAILED"); + } + else + log->set(OWLOG_ERROR,"OWERROR_WRITECOM_FAILED"); + + // an error occured so re-sync with DS2480 + DS2480Detect(); + + return FALSE; + +} + +uint8_t owCOMInterface::sendrecivBit(uint8_t bit) { + uint8_t readbuffer[10],sendpacket[10]; + uint8_t sendlen=0; + + // check if correct mode + if (UMode != MODSEL_COMMAND) { + UMode = MODSEL_COMMAND; + sendpacket[sendlen++] = MODE_COMMAND; + } + + // construct the command + sendpacket[sendlen] = (bit != 0) ? BITPOL_ONE : BITPOL_ZERO; + sendpacket[sendlen++] |= CMD_COMM | FUNCTSEL_BIT | USpeed; + // flush the buffers + FlushCOM(); + + // send the packet + if (WriteCOM(sendlen,sendpacket)) { + // read back the response + if (ReadCOM(1,readbuffer) == 1) { + // interpret the response + if (((readbuffer[0] & 0xE0) == 0x80) && + ((readbuffer[0] & RB_BIT_MASK) == RB_BIT_ONE)) + return 1; + else + return 0; + } + else + log->set(OWLOG_ERROR,"OWERROR_READCOM_FAILED"); + } else + log->set(OWLOG_ERROR,"OWERROR_WRITECOM_FAILED"); + + // an error occured so re-sync with DS2480 + DS2480Detect(); + return 0; +} + + +uint8_t owCOMInterface::sendrecivByte(uint8_t byte) { + uint8_t readbuffer[10],sendpacket[10]; + uint8_t sendlen=0; + + + // check if correct mode + if (UMode != MODSEL_DATA) + { + UMode = MODSEL_DATA; + sendpacket[sendlen++] = MODE_DATA; + } + + // add the byte to send + sendpacket[sendlen++] = byte; + + // check for duplication of data that looks like COMMAND mode + if (byte ==(uint8_t)MODE_COMMAND) + sendpacket[sendlen++] = (uint8_t)byte; + + // flush the buffers + FlushCOM(); + + // send the packet + if (WriteCOM(sendlen,sendpacket)) + { + // read back the 1 byte response + if (ReadCOM(1,readbuffer) == 1) + { + + // return the response + return readbuffer[0]; + } + else + log->set(OWLOG_ERROR,"OWERROR_READCOM_FAILED"); + } + else + log->set(OWLOG_ERROR,"OWERROR_WRITECOM_FAILED"); + + // an error occured so re-sync with DS2480 + DS2480Detect(); + return 0; +} + + diff --git a/src/owCOMInterface.h b/src/owCOMInterface.h new file mode 100755 index 0000000..cd41e0e --- /dev/null +++ b/src/owCOMInterface.h @@ -0,0 +1,73 @@ +// Copyright (c) 2016, Tobias Mueller tm(at)tm3d.de +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// * All advertising materials mentioning features or use of this +// software must display the following acknowledgement: This product +// includes software developed by tm3d.de and its contributors. +// * Neither the name of tm3d.de nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef __OWCOMINTERFACES_H_ +#define __OWCOMINTERFACES_H_ + +#include "owInterface.h" + +class owCOMInterface:public owInterface{ +protected: + int fd; + int com_init; +public: + owCOMInterface():owInterface() { + fd=0; + com_init=0; + } + virtual int InitAdapter(uint8_t); + virtual int Reset(); + virtual uint8_t sendrecivBit(uint8_t bit); + virtual uint8_t sendrecivByte(uint8_t byte); + virtual void ReleaseAdapter(); + +protected: + uint8_t ULevel; // current DS2480B 1-Wire Net level + uint8_t UBaud; // current DS2480B baud rate + uint8_t UMode; // current DS2480B command or data mode state + uint8_t USpeed; // current DS2480B 1-Wire Net communication speed + uint8_t UVersion; // current DS2480B version + struct termios origterm; + + + int OpenCOM(uint8_t comnr); + void CloseCOM(); + void FlushCOM(); + int WriteCOM(int outlen, uint8_t *outbuf); + int ReadCOM(int inlen, uint8_t *inbuf); + void BreakCOM(); + void SetBaudCOM(uint8_t new_baud); + int8_t DS2480Detect(); +}; + +#endif diff --git a/src/owDevice.cpp b/src/owDevice.cpp new file mode 100755 index 0000000..840a0b2 --- /dev/null +++ b/src/owDevice.cpp @@ -0,0 +1,489 @@ +// Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// * All advertising materials mentioning features or use of this +// software must display the following acknowledgement: This product +// includes software developed by tm3d.de and its contributors. +// * Neither the name of tm3d.de nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include "owInterface.h" +#include + +owDevice::owDevice(owInterface *owi_,snum_t num) { + snum=num; + owi=owi_; + config=new owDeviceConfig; + configstate=OWDCS_NONE; + raw.insert(raw.begin(),4,0); + values.insert(values.begin(),4,0); + lastfound=0; + } + +void owDevice::setDefaultConfig() { + config->setInvalid(); + } + +std::vector owDevice::getFamilyInfo() { + return owDeviceConfig::getFamilyInfo(snum.byte[0]); + } +int owDevice::readConfig() { + std::vector cl; + int r=owi->maxrepeat+1; + setDefaultConfig(); + int conf16=0; + do { + owi->log->clear(); + cl.clear(); + cl.push_back(0x85); + Communicate(&cl, 1, 26); + //for (uint8_t v:cl) printf("%02X ",v); + if ((cl[1]==0xFF)||(cl[2]==0xFF)) { + owi->log->set(OWLOG_INFO,"Get Config not work, maybe not a emulation from www.tm3d.de"); + return 0; + } + int oldInfo=1; + //all Code pos +1 + for(int i=19;i<27;i++) if (cl[i]!=0xFF) {oldInfo=0;break;} + if (oldInfo) { + owi->log->set(OWLOG_INFO,"Old 16 Byte Config"); + if (cl[18]==0xFF) { + if (!owi->calcCRC8(std::vector(cl.begin()+1,cl.begin()+17))) { + owi->log->set(OWLOG_WARNING,"CRC8 ERROR Reading Config"); + } + } else { + if (!owi->testCRC16(cl)) { + owi->log->set(OWLOG_WARNING,"CRC16 ERROR Reading Config "); + } + } + if (owi->log->last()calcCRC8(std::vector(cl.begin()+1,cl.begin()+25))) { + owi->log->set(OWLOG_WARNING,"CRC8 ERROR Reading Config"); + } + } else { + if (!owi->testCRC16(cl)) { + owi->log->set(OWLOG_WARNING,"CRC16 ERROR Reading Config "); + } + } + } + r--; + } + while ((owi->log->last()>=OWLOG_WARNING)&&(r>0)); + if (r==0) { + owi->log->set(OWLOG_ERROR,"To much Errors while read config"); + return -1; + } + config->setConfig(std::vector(cl.begin()+1,cl.begin()+25)); + if (config->valid) { + if (conf16) configstate=OWDCS_16; else configstate=OWDCS_24; + } else configstate=OWDCS_NONE; + return 1; +} + + +int owDevice::Communicate(std::vector *data, int scount, int rcount) { + owi->Wait_Free(); + owi->MatchRom(snum); + if (owi->log->last()==OWLOG_ERROR) {owi->Free();return 0;} + owi->Communicate(data, scount, rcount); + if (owi->log->last()==OWLOG_ERROR) {owi->Free();return 0;} + owi->Free(); + return 1; +} + +int owDevice::CommunicateShort(std::vector *data, int scount, int rcount) { + owi->Wait_Free(); + owi->Reset(); + if (owi->log->last()==OWLOG_ERROR) {owi->Free();return 0;} + owi->Communicate(data, scount, rcount); + if (owi->log->last()==OWLOG_ERROR) {owi->Free();return 0;} + owi->Free(); + return 1; +} + + +void owDevice::changeID(snum_t nid) { + int i; + if (nid.byte[0] != snum.byte[0]) { + owi->log->set(OWLOG_ERROR,"Family ID should not be changed, no correct ID"); + return; + } + std::vector id; + for(i=0;i<7;i++) id.push_back(nid.byte[i]); + id.push_back(owi->calcCRC8(id)); + std::vector cl; + int r=owi->maxrepeat+1; + do { + owi->log->clear(); + cl.clear(); + cl.push_back(0x75); + cl.insert(cl.begin()+1,id.begin(),id.end()); + Communicate(&cl, 9,0); + if (owi->log->last()==OWLOG_ERROR) {r--;continue;} + cl.clear(); + cl.push_back(0xA7); + Communicate(&cl, 1, 8); + if (owi->log->last()==OWLOG_ERROR) {r--;continue;} + for (i = 0; i < 8; i++) { + if (cl[i + 1] != id[i]) { + owi->log->set(OWLOG_WARNING,"changeID Comunication ERROR"); + break; + } + } + r--; + } + while ((owi->log->last()>=OWLOG_WARNING)&&(r>0)); + if (r==0) { + owi->log->set(OWLOG_ERROR,"Can not change ID"); + return; + } + cl.clear(); + cl.push_back(0x79); + cl.push_back(snum.byte[1]); + cl.push_back(snum.byte[5]); + cl.push_back(snum.byte[6]); + Communicate(&cl, 4, 0); + usleep(50000); +} + +void owDevice::runFlasher() { + std::vector cl; + cl.push_back(0x88); + this->Communicate(&cl, 1, 0); + this->Communicate(&cl, 1, 0); + this->Communicate(&cl, 1, 0); +} + + + + + + + + + +void owDeviceDS18B20::setDefaultConfig() { + config->setConfig({1,1, 0,0, 0,0, 0,0, 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); + configstate=OWDCS_DEFAULT; +}; + +int owDeviceDS18B20::readScratchpad(std::vector *sp) { + std::vector cl; + int r=owi->maxrepeat+1; + do { + cl.clear(); + cl.push_back(0xBE); + Communicate(&cl, 1, 9); + if (owi->log->last()>=OWLOG_ERROR) return -1; + sp->clear(); + sp->insert(sp->begin(),cl.begin()+1,cl.end()); + if (owi->calcCRC8(*sp)==0) return 1; + owi->log->set(OWLOG_WARNING,"CRC ERROR reading DS18B20 Scrachpad"); + r--; + } while ((owi->log->last()>=OWLOG_WARNING)&&(r>0)); + + return 0; +} + +int owDeviceDS18B20::convertAll() { + std::vector sp; + sp.push_back(0x44); + Communicate(&sp, 1, 0); + usleep(750000); + + if (readScratchpad(&sp)) { + int16_t tsht; + tsht = sp[0] | ((int)sp[1] << 8); + if (sp[1] & 0x080) + tsht |= 0xFFFFF0000; + raw[0]=tsht; + values[0]=config->calculateValue(0, raw); + return 1; + } + return 0; +} + + +void owDeviceDS2438::setDefaultConfig() { + config->setConfig({1,6, 6,8, 4,7, 7,17, 0,2,3,12,4,0,0,0,0,0,0,0,0,0,0,0}); + configstate=OWDCS_DEFAULT; +} + + +int owDeviceDS2438::readScratchpad(std::vector *sp, uint8_t page, int recall) { + std::vector cl; + int r=owi->maxrepeat+1; + do { + if (recall) { + cl.clear(); + cl.push_back(0xB8); //recall + cl.push_back(page); + Communicate(&cl, 2, 0); + if (owi->log->last()>=OWLOG_ERROR) return -1; + } + cl.clear(); + cl.push_back(0xBE); + cl.push_back(page); + Communicate(&cl, 2, 9); + if (owi->log->last()>=OWLOG_ERROR) return -1; + sp->clear(); + sp->insert(sp->begin(),cl.begin()+2,cl.end()); + if (owi->calcCRC8(*sp)==0) return 1; + owi->log->set(OWLOG_WARNING,"CRC ERROR reading DS2438 Scrachpad"); + r--; + } while ((owi->log->last()>=OWLOG_WARNING)&&(r>0)); + + return 0; +} + +int owDeviceDS2438::setConfigByte(uint8_t cb) { + std::vector sp; + int k; + for(k=0;kmaxrepeat;k++) { + owi->log->clear(); + sp.clear(); + sp.push_back(0x4E); + sp.push_back(0x00); + sp.push_back(cb); + Communicate(&sp,3,0); + if (owi->log->last()>=OWLOG_ERROR) return -1; + sp.clear(); + readScratchpad(&sp,0,0); + if (owi->log->last()>=OWLOG_ERROR) return -2; + if (cb==sp[0]) return 1; + owi->log->set(OWLOG_WARNING,"ERROR set config byte of DS2438"); + } + owi->log->set(OWLOG_WARNING,"Config of DS2438 byte not set"); + return 0; +} + +inline int16_t ow_fconvert(uint8_t b1, uint16_t b2) { + int tsht; + tsht=b1 |((int)b2<<8); + if (b2 & 0x080) + tsht |= 0xFFFFF0000; + return tsht; +} + +int owDeviceDS2438::convertAll() { + for(int k=0;kmaxrepeat;k++) { + std::vector sp; + sp.push_back(0x44); + Communicate(&sp, 1, 0); + if (owi->log->last()>=OWLOG_ERROR) continue; + usleep(100000); + if (setConfigByte(0x08)<=0) continue; + for(int k=0;kmaxrepeat;k++) { + sp.clear(); + sp.push_back(0xB4); + Communicate(&sp, 1, 0); + } + if (owi->log->last()>=OWLOG_ERROR) continue; + usleep(100000); + + + readScratchpad(&sp,0,1); + int temp=ow_fconvert(sp[1],sp[2]); + int VDD=ow_fconvert(sp[3],sp[4]); + if (setConfigByte(0x00)<=0) continue; + + for(int k=0;kmaxrepeat;k++) { + sp.clear(); + sp.push_back(0xB4); + Communicate(&sp, 1, 0); + } + if (owi->log->last()>=OWLOG_ERROR) continue; + + usleep(100000); + + + + readScratchpad(&sp,0,1); + if (owi->log->last()>=OWLOG_ERROR) continue; + int I=ow_fconvert(sp[5],sp[6]); + int VAD=ow_fconvert(sp[3],sp[4]); + raw[0]=temp; + raw[1]=VDD; + raw[2]=VAD; + raw[3]=I; + for(int i=0;i<4;i++) values[i]=config->calculateValue(i, raw); + break; + } + if (owi->log->last()>=OWLOG_ERROR) return 0; + return 1; +} + + +void owDeviceDS2450::setDefaultConfig() { + config->setConfig({6,9, 6,9, 6,9, 6,9, 0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0}); + configstate=OWDCS_DEFAULT; +} + +int owDeviceDS2450::convertAll() { + convert(0x0F,0); + if (owi->log->last()>=OWLOG_WARNING) { + return 0; + } + std::vector sp; + readMemory(0,&sp); + if (owi->log->last()>=OWLOG_WARNING) { + return 0; + } + + for(int i=0;i<4;i++) { + raw[i]=(sp[2 * i] | sp[2 * i + 1] << 8); + } + for(int i=0;i<4;i++) { + values[i]=config->calculateValue(i, raw); + } + return 1; + +} + +void owDeviceDS2450::readMemory(uint8_t addr,std::vector *sp) { + std::vector cl; + cl.push_back(0xAA); + cl.push_back(addr); + cl.push_back(0x00); + Communicate(&cl,3,10-addr); + if (owi->log->last()>=OWLOG_WARNING) { + return; + } + if (!owi->testCRC16(cl)) { + owi->log->set(OWLOG_ERROR,"CRC ERROR Reading Memory of DS2450"); + return; + } + sp->clear(); + sp->insert(sp->begin(),cl.begin()+3,cl.end()-2); +} + +void owDeviceDS2450::writeMemory(uint8_t addr,std::vector *sp) { + std::vector cl; + cl.push_back(0x55); + cl.push_back(addr); + cl.push_back(0x00); + owi->MatchRom(snum); + if (owi->log->last()>=OWLOG_WARNING) { + return; + } + for(uint8_t b: (*sp)) { + cl.push_back(b); + owi->Communicate(&cl,cl.size(),2); + if (owi->log->last()>=OWLOG_WARNING) { + return; + } + if (!owi->testCRC16(cl)) { + owi->log->set(OWLOG_ERROR,"CRC ERROR Writing Memory of DS2450"); + return; + } + cl.clear(); + owi->Communicate(&cl, 0, 1); + if (owi->log->last()>=OWLOG_WARNING) { + return; + } + if (cl[0] != b) { + owi->log->set(OWLOG_ERROR,"ERROR Writing Memory of DS2450"); + return; + } + cl.clear(); + } +} + +void owDeviceDS2450::convert(uint8_t mask, uint8_t preset) { + std::vector cl; + cl.push_back(0x3C); + cl.push_back(mask); + cl.push_back(preset); + Communicate(&cl, 3, 2); + if (!owi->testCRC16(cl)) { + owi->log->set(OWLOG_ERROR,"CRC ERROR Convert Command of DS2450"); + return; + } + usleep(10000); +} + + + + + + + + + + + +void owDeviceDS2423::setDefaultConfig() { + config->setConfig({9,13, 9,13, 9,13, 9,13, 0,19,19,19,19,0,0,0,0,0,0,0,0,0,0,0}); + configstate=OWDCS_DEFAULT; +} + +int owDeviceDS2423::convertAll() { + for(uint8_t i=12;i<16;i++) { + raw[i-12]=readCounter(i); + } + for(int i=0;i<4;i++) { + values[i]=config->calculateValue(i, raw); + } + return 1; +} +uint32_t owDeviceDS2423::readCounter(uint8_t page) { + std::vector cl; + cl.push_back(0xA5); + uint16_t addr=(page<<5)+31; + cl.push_back(addr&0xFF); + cl.push_back(addr>>8); + Communicate(&cl,3,11); + //for (uint8_t v :cl) printf("%02X ",v); + //printf("\n"); + if (!owi->testCRC16(cl)) { + owi->log->set(OWLOG_ERROR,"CRC ERROR Reading Counter of DS2423"); + return 0; + } + uint32_t ret=0; + + for(size_t i=cl.size()-8;i>cl.size()-11;i--) { + ret<<=8; + ret|=cl[i]; + + } + + return ret; +} + + + + + + + diff --git a/src/owDeviceConfig.cpp b/src/owDeviceConfig.cpp new file mode 100644 index 0000000..21dc7fe --- /dev/null +++ b/src/owDeviceConfig.cpp @@ -0,0 +1,276 @@ +// Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// * All advertising materials mentioning features or use of this +// software must display the following acknowledgement: This product +// includes software developed by tm3d.de and its contributors. +// * Neither the name of tm3d.de nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include "owDeviceConfig.h" +#include + +std::vector owDeviceConfig::getFamilyInfo(uint8_t famcode) { + std::vector l; + switch (famcode) { + case 1: + l.push_back("DS2401,DS2411"); + l.push_back("DS1990A"); + l.push_back("silicon serial number"); + break; + case 2: + l.push_back("DS1425"); + l.push_back("DS1991"); + l.push_back("multikey 1153bit secure"); + break; + case 4: + l.push_back("DS2404"); + l.push_back("DS1994"); + l.push_back("econoram time chip"); + break; + case 5: + l.push_back("DS2405"); + l.push_back(""); + l.push_back("push_backresable Switch"); + break; + case 6: + l.push_back(""); l.push_back("DS1993"); + l.push_back("4k memory ibutton"); + break; + case 8: + l.push_back(""); l.push_back("DS1992"); + l.push_back("1k memory ibutton"); + break; + case 9: + l.push_back("DS2502"); l.push_back("DS1982"); + l.push_back("1k add - only memory"); + break; + case 0x0A: l.push_back(""); l.push_back("DS1995"); + l.push_back("16k memory ibutton"); break; + case 0x0B: l.push_back("DS2505"); l.push_back("DS1985"); + l.push_back("16k add - only memory"); break; + case 0x0C: l.push_back(""); l.push_back("DS1996"); + l.push_back("64k memory ibutton"); break; + case 0x0F: l.push_back("DS2506"); l.push_back("1986"); + l.push_back("64k add - only  memory"); break; + case 0x10:l.push_back("DS18S20"); l.push_back("DS1920"); + l.push_back("high precision digital thermometer"); break; + case 0x12:l.push_back("DS2406,DS2407"); l.push_back(""); + l.push_back("dual addressable switch plus 1k memory"); break; + case 0x14:l.push_back("DS2430A"); l.push_back("1971"); + l.push_back("256 eeprom"); break; + case 0x1A:l.push_back(""); l.push_back("DS1963L"); + l.push_back("4k Monetary"); break; + case 0x1B:l.push_back("DS2436"); l.push_back(""); + l.push_back("battery id / monitor chip"); break; + case 0x1C:l.push_back("DS28E04-100"); l.push_back(""); + l.push_back("4k EEPROM with PIO 1C"); break; + case 0x1D:l.push_back("DS2423"); l.push_back(""); + l.push_back("4k ram with counter"); break; + case 0x1F:l.push_back("DS2409"); l.push_back(""); + l.push_back("microlan coupler"); break; + case 0x20 : l.push_back("DS2450"); l.push_back(""); + l.push_back("quad a / d converter"); break; + case 0x21: l.push_back(""); l.push_back("DS1921"); + l.push_back("Thermachron"); break; + case 0x22: l.push_back("DS1822"); l.push_back(""); + l.push_back("Econo Digital Thermometer"); break; + case 0x23: l.push_back("DS2433"); l.push_back(""); + l.push_back("4k eeprom"); break; + case 0x24: l.push_back("DS2415"); l.push_back(""); + l.push_back("time chip"); break; + case 0x26: l.push_back("DS2438"); l.push_back(""); + l.push_back("smart battery monitor"); break; + case 0x27:l.push_back("DS2417"); l.push_back(""); + l.push_back("time chip with interrupt"); break; + case 0x28:l.push_back("DS18B20"); l.push_back(""); + l.push_back("programmable resolution digital thermometer"); break; + case 0x29:l.push_back("DS2408"); l.push_back(""); + l.push_back("8 - channel addressable switch"); break; + case 0x2C:l.push_back("DS2890"); l.push_back(""); + l.push_back("digital potentiometer"); break; + case 0x2D:l.push_back("DS2431"); l.push_back(""); + l.push_back("1k eeprom"); break; + case 0x2E:l.push_back("DS2770"); l.push_back(""); + l.push_back("battery monitor and charge controller"); break; + case 0x30:l.push_back("DS2760/61/62"); l.push_back(""); + l.push_back("high - precision li + battery monitor"); break; + case 0x31:l.push_back("DS2720"); l.push_back(""); + l.push_back("efficient addressable single - cell rechargable lithium protection ic"); break; + case 0x33: l.push_back("DS2432"); l.push_back("DS1961S"); + l.push_back("1k protected eeprom with SHA - 1"); break; + case 0x36:l.push_back("DS2740"); l.push_back(""); + l.push_back("high precision coulomb counter"); break; + case 0x37: l.push_back(""); l.push_back("DS1977"); + l.push_back("Password protected 32k eeprom"); break; + case 0x3A:l.push_back("DS2413"); l.push_back(""); + l.push_back("dual channel addressable switch"); break; + case 0x41:l.push_back("DS2422"); l.push_back("DS1922L/DS1922T/DS1923"); + l.push_back("Temperature Logger 8k mem"); break; + case 0x51:l.push_back("DS2751"); l.push_back(""); + l.push_back("multichemistry battery fuel gauge"); break; + case 0x81: l.push_back(""); l.push_back("DS1420"); + l.push_back("Serial ID Button"); break; + case 0x84:l.push_back("DS2404S"); l.push_back(""); + l.push_back("dual port plus time"); break; + case 0x89:l.push_back("DS2502-E48"); l.push_back("DS1982U"); + l.push_back("48 bit node address chip"); break; + case 0x8B:l.push_back("DS2502/DS2505"); l.push_back("DS1985U"); + l.push_back("16k add - only"); break; + case 0x8F:l.push_back("DS2506"); l.push_back("DS1986U"); + l.push_back("64k add - only uniqueware"); break; + case 0xFF:l.push_back("LCD"); l.push_back(""); + l.push_back("(Swart)"); break; + case 0xA3:l.push_back("ATTINY84A"); l.push_back(""); + l.push_back("1-Wire Flasher"); break; + default:l.push_back("unknown"); l.push_back("unknown"); + l.push_back("Device not int list"); + break; + } + return l; + } + +std::vector owDeviceConfig::getQuantityFromNumber(uint8_t code) { + std::vector l; + switch (code) { + case 1: + l.push_back("temperature"); + l.push_back("Temperatur"); + l.push_back("°C"); + break; + case 2: + l.push_back("pressure"); + l.push_back("Druck"); + l.push_back("hPa"); + break; + case 3: + l.push_back("illuminance"); + l.push_back("Beleuchtungsstärke"); + l.push_back("lux"); + break; + case 4: + l.push_back("humidity"); + l.push_back("Luftfeuchte"); + l.push_back("%"); + break; + case 5: + l.push_back("constant"); + l.push_back("Konstante"); + l.push_back(""); + break; + case 6: + l.push_back("voltage"); + l.push_back("Spannung"); + l.push_back("V"); + break; + case 7: + l.push_back("current"); + l.push_back("Strom"); + l.push_back("mA"); + break; + case 8: + l.push_back("VOC"); + l.push_back("VOC"); + l.push_back("ppm"); + case 9: + l.push_back("Counter"); + l.push_back("Zähler"); + l.push_back(""); + break; + case 10: + l.push_back("CO2"); + l.push_back("CO2"); + l.push_back("ppm"); + break; + case 11: + l.push_back("resistance"); + l.push_back("Widerstand"); + l.push_back("kOhm"); + break; + default: + l.push_back(""); + l.push_back(""); + l.push_back(""); + + } + //Optimization necessary + if (language==OWDC_LANGUAGE_ENGLISH) l.erase(l.begin()+1); + if (language==OWDC_LANGUAGE_GERMAN) l.erase(l.begin()); + + return l; +} + +double owDeviceConfig::calculateValueFromNumber(int code, int vn, std::vector V) { + switch (code) { + case 01: return V[vn] / 16.0; break; + case 2:return V[vn]/1.6; break; + case 3:return V[vn]*0.2 + 700; break; + case 4:return exp(V[vn] / 160.0); break; + case 5:return V[vn]*62.5 + 55000; break; + case 6:return V[vn] / 256.0; break; + case 7:return (((double)V[2] / (double)V[1] - 0.16) / 0.0062) / (1.0546 - 0.00216*V[0]/256.0); break; + case 8:return V[vn] / 100.0; break; + case 9:return V[vn] / 65535.0*5.1; break; + case 10:return V[vn] / 65535.0*2.55; break; + case 11:return V[vn] / 65535.0*1.1; break; + case 12:return V[vn] / 10.0; break; + case 13:return V[vn]; break; + case 14:return (V[vn] - 32767.0) / 100.0; break; + case 15:return exp((V[vn]-32767.0)/1000.0); break; + case 16:return V[vn]/32.0; break; + case 17:return 5120.0/V[vn]; break; //Current of DS2438 with 0.025 Ohm; + default:return 0; + } +} + +std::string owDeviceConfig::getSensorChip(uint8_t ch) { + if (ch>4) return ""; + std::string s; + switch(config.sens[ch]) { + case 1: s="DS18B20";break; + case 2: s="DS2438";break; //Temperatur Sensor + case 3: s="DS2438";break; //Spannung + case 4: s="DS2438";break; // Spannung / Strom + case 5: s="DS2450";break; // Spannung + case 6: s="Thermoelement";break; // Hochtemperatur Sensor + case 7: s="SHT21";break; // Feuchte/Temperatur Sensor + case 8: s="SHT25";break; // Feuchte/Temperatur Präzisionssensor + case 9: s="DHT22";break; // Feuchte/Temperatur Sensor + case 10: s="HIH9021";break; // Feuchte/Temperatur Präzisionssensor + case 11: s="HDC1080";break; // Feuchte/Temperatur Sensor + case 12: s="HIH4030";break; // Feuchte/Temperatur Sensor analog + case 13: s="HIH5030";break; // Feuchte/Temperatur Sensor analog + case 14: s="BMP280";break; // Luftdrucksensor + case 15: s="MAX44009";break; // Umgebungslicht-Sensor + case 16: s="CDM7160";break; // CO2-Sensor + case 17: s="MAX1164/TGS8100";break; // VOC-Sensor + case 18: s="TGS8100 direkt";break; // VOC-Sensor + case 19: s="DS2423";break; // Counter + default: return ""; + } + return s; +} diff --git a/src/owDeviceConfig.h b/src/owDeviceConfig.h new file mode 100644 index 0000000..7502a9e --- /dev/null +++ b/src/owDeviceConfig.h @@ -0,0 +1,126 @@ +// Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// * All advertising materials mentioning features or use of this +// software must display the following acknowledgement: This product +// includes software developed by tm3d.de and its contributors. +// * Neither the name of tm3d.de nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + +#ifndef __OWDEVICECONFIG_H_ +#define __OWDEVICECONFIG_H_ + +#include "owInterface.h" + +struct owd_val { + uint8_t prop; + uint8_t form; +}; + +struct owd_config { + owd_val val[4]; + uint8_t uc; + uint8_t sens[4]; + uint8_t sp[4]; + uint8_t id2[7]; + uint8_t crc; + uint8_t crc2; +}; + + +#define OWDC_LANGUAGE_ENGLISH 0 +#define OWDC_LANGUAGE_GERMAN 1 + +class owDeviceConfig { + owd_config config; + int language; +public: + int valid; + owDeviceConfig() { + language=OWDC_LANGUAGE_ENGLISH; + setInvalid(); + }; + void checkValid() { + for(int i=0;i<4;i++) { + if ((config.val[i].prop==0xFF)||(config.val[i].form==0xFF)) {valid=0;return;} + if (config.val[i].prop!=0) valid=1; + } + } + void setInvalid() { + valid=0; + } + void setLanguage(int lang) { + language=lang; + } + void setConfig(std::vector v) { + int i=0; + for (uint8_t w :v) { + ((uint8_t*)&config)[i]=w; + i++; + if (i>=26) break; + } + checkValid(); + } + void setConfig(const uint8_t v[24]) { + for (int i=0;i<24;i++) { + ((uint8_t*)&config)[i]=v[i]; + if (i>=26) break; + } + checkValid(); + } + static std::vector getFamilyInfo(uint8_t famcode); + std::vector getQuantityFromNumber(uint8_t code); + double calculateValueFromNumber(int code, int vn, std::vector V); + + std::string getQuantity(uint8_t ch) { + if (ch>4) return getQuantityFromNumber(255)[0]; + return getQuantityFromNumber(config.val[ch].prop)[0]; + } + std::string getUnit(uint8_t ch) { + if (ch>4) return getQuantityFromNumber(255)[0]; + return getQuantityFromNumber(config.val[ch].prop)[1]; + } + std::string getSensorChip(uint8_t ch); + double calculateValue(int ch, std::vector V) { + if (ch>4) return 0; + return calculateValueFromNumber(config.val[ch].form,ch,V); + } + uint8_t getPropertyID(uint8_t ch) { + if (ch>4) return 0; + return config.val[ch].prop; + } + + uint8_t getFormulaID(uint8_t ch) { + if (ch>4) return 0; + return config.val[ch].form; + } + + +}; +#endif + diff --git a/src/owInterface.cpp b/src/owInterface.cpp new file mode 100755 index 0000000..66ea440 --- /dev/null +++ b/src/owInterface.cpp @@ -0,0 +1,553 @@ +// Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// * All advertising materials mentioning features or use of this +// software must display the following acknowledgement: This product +// includes software developed by tm3d.de and its contributors. +// * Neither the name of tm3d.de nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include "owInterface.h" +#include +#include +#include "hexfile.h" + +static short oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; +static unsigned char owi_dscrc_table[] = { + 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, + 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, + 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, + 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, + 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, + 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, + 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, + 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, + 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, + 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, + 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, + 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, + 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, + 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, + 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, + 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53}; + + +uint8_t owInterface::docrc8(uint8_t value) { + // See Application Note 27 + + // TEST BUILD + crc8 = owi_dscrc_table[crc8 ^ value]; + return crc8; +} + +uint16_t owInterface::docrc16(uint16_t cdata) { + cdata = (cdata ^ (crc16 & 0xff)) & 0xff; + crc16 >>= 8; + + if (oddparity[cdata & 0xf] ^ oddparity[cdata >> 4]) + crc16 ^= 0xc001; + + cdata <<= 6; + crc16 ^= cdata; + cdata <<= 1; + crc16 ^= cdata; + + return crc16; + + +} + +uint8_t owInterface::calcCRC8(std::vector data) { + crc8 = 0; + for(uint8_t v: data) + docrc8(v); + return crc8; //0 bei erfolg oder crc wenn crc nicht babei +} + +uint16_t owInterface::calcCRC16(std::vector data) { + crc16=0; + for(uint8_t v:data) { + docrc16(v); + } + return crc16; +} + +int owInterface::testCRC16(std::vector data) { + return calcCRC16(data)==0xB001; +} + +void owInterface::resetFlasher() { // go back from Bootloader + std::vector data; + data.push_back(0x89); + Wait_Free(); + snum_t snum; + snum.num=0xfa55aa55aa55aaa3; + MatchRom(snum); + if (log->last()==OWLOG_ERROR) {Free(); return;} + Communicate(&data, 1, 0); + + Free(); + if (log->last()==OWLOG_ERROR) return; + usleep(50); +} + +void owInterface::resetID() { + std::vector data; + data.push_back(0x8B); + Wait_Free(); + snum_t snum; + snum.num=0xfa55aa55aa55aaa3; + MatchRom(snum); + if (log->last()==OWLOG_ERROR) {Free(); return;} + Communicate(&data, 1, 0); + Free(); +} + +int owInterface::programmPage(int pagenr, std::vector page, int pagesize) { + snum_t snum; + snum.num=0xfa55aa55aa55aaa3; +// printf("programm page %i",pagenr); + + + int diff = pagesize - page.size(); + if (diff>0) { + for (int i = 0; i < (diff); i++) page.push_back(0xFF); + } + std::vector cl; + std::vector clb; //backup + cl.push_back(0x0F); //code for Flashing + cl.push_back((pagenr*pagesize) & 0xFF); //adress in byte + cl.push_back((pagenr*pagesize) >> 8); + cl.insert(cl.end(),page.begin(),page.end()); //page + clb=cl; //make backup + Wait_Free(); + MatchRom(snum); + if (log->last()==OWLOG_ERROR) {Free();return -3;} + Communicate(&cl, 3+pagesize, 0); //send (resive page) + Free(); + if (log->last()==OWLOG_ERROR) return -3; + int err=0; + for(int k=0;klast()==OWLOG_ERROR) {Free();return -3;} + Communicate(&cl, 1, 2+pagesize); // read back scratchpad + Free(); + if (log->last()==OWLOG_ERROR) return -3; + err=0; + for (int i = 0; i < pagesize+2; i++) { + if (clb[i + 1] != cl[i + 1]) { //test + usleep(50000); + err=1; + break; + } + } + if (err==0) break; + } + if (err==1) { + usleep(50000); + return -1; //error in scratchpad + } + cl.clear(); + cl.push_back(0x55);//Programm + Wait_Free(); + MatchRom(snum); + if (log->last()==OWLOG_ERROR) {Free();return -3;} + Communicate(&cl, 1, 0); + Free(); + if (log->last()==OWLOG_ERROR) return -3; + usleep(50000); + cl.clear(); + cl.push_back(0xB8);//recal programm memory to scratchpad + cl.push_back((pagenr*pagesize) & 0xFF); + cl.push_back((pagenr*pagesize) >> 8); + Wait_Free(); + MatchRom(snum); + if (log->last()==OWLOG_ERROR) {Free();return -3;} + Communicate(&cl, 3, 0); //Copy programm memory to scratch + Free(); + if (log->last()==OWLOG_ERROR) return -3; + usleep(50000); + + for(int k=0;klast()==OWLOG_ERROR) {Free();return -3;} + Communicate(&cl, 1, 2 + pagesize); //Reread scratch + Free(); + if (log->last()==OWLOG_ERROR) return -3; + err=0; + for (int i = 0; i < pagesize + 2; i++) { + if (cl[i + 1] != clb[i + 1]) { + usleep(50000); + err=1; + break; + } + } + if (err==0) break; + } + if (err==1) { + usleep(50000); + return -2; + } + + + return 0; +} + + +int owInterface::flashHEXFile(std::string filename,snum_t dev,int resetid,int progress) { + log->set(OWLOG_INFO,"Open Hex-File: %s",filename.c_str()); + hexFile *hf=new hexFile(filename); + if (hf->lastError==1) {log->set(OWLOG_ERROR,"CRC Error in HEX-File %s",filename.c_str());return -1;} + if (hf->lastError==2) {log->set(OWLOG_ERROR,"Error interpreting HEX-File %s",filename.c_str());return -2;} + if (hf->lastError==3) {log->set(OWLOG_ERROR,"File could not be opened: %s",filename.c_str());return -3;} + unsigned int blcount=hf->getBlockCount(64); + if (blcount>118) { + log->set(OWLOG_ERROR,"Code to big, max 7552 Byte allowed (118 Pages). Code has %i pages!",blcount); + return -5; + } + log->set(OWLOG_INFO,"Try to start Bootloader on device %llX",dev.num); + int r=maxrepeat+1; + int found; + do { + log->clear(); + std::vector data; + MatchRom(dev); + data.push_back(0x88); + Communicate(&data, 1, 0); + MatchRom(dev); + Communicate(&data, 1, 0); + MatchRom(dev); + Communicate(&data, 1, 0); + sleep(3); + log->set(OWLOG_INFO,"Search for Bootloader..."); + log->setLogLevel(OWLOG_WARNING); + Find(); + log->setLogLevel(OWLOG_INFO); + found=0; + for (owDevice* dev :devices) { + if (dev->getNum().num==0xfa55aa55aa55aaa3) { + found=1; + break; + } + } + if (found==0) log->set(OWLOG_WARNING,"Bootloader not found"); + r--; + } while ((found==0)&&(r>0)); + if (r==0) { + log->set(OWLOG_ERROR,"Can not start Bootloader on this device %llX",dev.num); + return -4; + } + log->set(OWLOG_INFO,"Start Programm %i Pages",blcount); + int rp=0; + int er=0; + unsigned int i =0; + for ( i= 0; i < blcount; i++) { + std::vector blk = hf->getBlock(i*64, 64); + int errc = maxrepeat*5; + while (errc != 0) { + log->clear(); + if (programmPage(i, blk, 64) >= 0) { + if (progress) {printf("#");fflush(stdout);} + break; + } + + errc -= 1; + rp++; + if (progress) {printf("\033[1;31m#\033[0m");fflush(stdout);} //printf("\033[1;33m%s\033[0m\n",s); + + } + if (errc == 0) { er++; break; } + } + if (progress) printf("\n"); + if (er != 0) { + log->set(OWLOG_ERROR,"ERROR Writing Program Memory!!!"); + if (i==0) { + log->set(OWLOG_ERROR,"If Fuse SELFPRGEN enabled?"); + } else + log->set(OWLOG_ERROR,"Maybe 1-Wire Connection is verry bad!"); + } else { + if (resetid) { + log->set(OWLOG_INFO,"Set 1-Wire ID to ID in hexfile...",blcount); + resetID(); + sleep(3); + resetID(); + sleep(3); + } + } + + log->set(OWLOG_INFO,"Back from bootloader to normal device...",blcount); + + + resetFlasher(); + sleep(1); + resetFlasher(); + sleep(3); + + Find(); + + return 1; + +} + + +int owInterface::owSearch() { + int id_bit_number; + int last_zero, rom_byte_number, search_result; + int id_bit, cmp_id_bit; + unsigned char rom_byte_mask, search_direction; + + // initialize for search + id_bit_number = 1; + last_zero = 0; + rom_byte_number = 0; + rom_byte_mask = 1; + search_result = 0; + crc8 = 0; + + // if the last call was not the last one + if (!LastDeviceFlag) { + // 1-Wire reset + Wait_Free(); + if (!Reset()) { + // reset the search + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + Free(); + return FALSE; + } + if (log->last()==OWLOG_ERROR) return -3; + // issue the search command + sendrecivByte(0xF0); + if (log->last()==OWLOG_ERROR) return -3; + + // loop to do the search + do { + // read a bit and its complement + id_bit = sendrecivBit(1); + cmp_id_bit = sendrecivBit(1); + // check for no devices on 1-wire + if ((id_bit == 1) && (cmp_id_bit == 1)) + break; + else { + // all devices coupled have 0 or 1 + if (id_bit != cmp_id_bit) + search_direction = id_bit; // bit write value for search + else { + // if this discrepancy if before the Last Discrepancy + // on a previous next then pick the same as last time + if (id_bit_number < LastDiscrepancy) + search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0); + else + // if equal to last pick 1, if not then pick 0 + search_direction = (id_bit_number == LastDiscrepancy); + + // if 0 was picked then record its position in LastZero + if (search_direction == 0) { + last_zero = id_bit_number; + // check for Last discrepancy in family + if (last_zero < 9) + LastFamilyDiscrepancy = last_zero; + } + } + // set or clear the bit in the ROM byte rom_byte_number + // with mask rom_byte_mask + if (search_direction == 1) + ROM_NO[rom_byte_number] |= rom_byte_mask; + else + ROM_NO[rom_byte_number] &= ~rom_byte_mask; + // serial number search direction write bit + sendrecivBit(search_direction); + //usleep(50); + + // increment the byte counter id_bit_number + // and shift the mask rom_byte_mask + id_bit_number++; + rom_byte_mask <<= 1; + + // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask + if (rom_byte_mask == 0) { + docrc8(ROM_NO[rom_byte_number]); // accumulate the CRC + rom_byte_number++; + rom_byte_mask = 1; + } + } + } + while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 + // if the search was successful then + if (!((id_bit_number < 65) || (crc8 != 0))) { + // search successful so set LastDiscrepancy,LastDeviceFlag,search_result + LastDiscrepancy = last_zero; + // check for last device + if (LastDiscrepancy == 0) + LastDeviceFlag = TRUE; + search_result = TRUE; + } else { + log->set(OWLOG_WARNING,"CRC Error on Search Rom"); + } + } + + // if no device found then reset counters so next 'search' will be like a first + if (!search_result || !ROM_NO[0]) { + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + search_result = FALSE; + } + Free(); + return search_result; + + +} +void owInterface::Clean() { + for (owDevice* dev :devices) { + delete dev; + } + devices.clear(); + device_nums.clear(); + devices_changed=1; +} + +int owInterface::Find() { + int rslt,i,cnt=0; + std::vector found; + for (int k=0;kclear(); + found.clear(); + rslt = owFirst(); + if (log->last()>=OWLOG_WARNING) continue; + while (rslt){ + snum_t snum; + // print device found + for (i = 7; i >= 0; i--) + snum.byte[i]=ROM_NO[i]; + //printf("%02X", ROM_NO[i]); + //printf(" %d\n",++cnt); + found.push_back(snum); + cnt++; + log->clear(); + rslt = owNext(); + if (log->last()>=OWLOG_WARNING) {rslt=-1;break;} + } + if (rslt==0) break; + + } + if (log->last()>=OWLOG_WARNING) { + log->set(OWLOG_ERROR,"To much Errors while search rom"); + //Alles so lassen wie es ist? + return 0; + } + for(snum_t snum:found) { + int snum_found=0; + //Device schon forhanden? + for(snum_t d : device_nums) { + if (snum.num==d.num) {snum_found=1;break;} + } + //nein, dann anlegen. + if (!snum_found) { + log->set(OWLOG_INFO,"new dev %llx\n",snum.num); + devices_changed=1; + device_nums.push_back(snum); + owDevice *d=NULL; + + switch (snum.byte[0]) { + case 0x28:d=new owDeviceDS18B20(this,snum);break; + case 0x26:d=new owDeviceDS2438(this,snum);break; + case 0x20:d=new owDeviceDS2450(this,snum);break; + case 0x1D:d=new owDeviceDS2423(this,snum);break; + default:d=new owDevice(this,snum); + } + devices.push_back(d); + if (d!=NULL) {d->readConfig();} + } + } + //Pruefe nach nicht mehr vorhandenen devices + int dpos=0; + for(snum_t d:device_nums) { + int snum_found=0; + for(snum_t fd:found) { + if (fd.num==d.num) {snum_found=1;break;} + } + //Device nicht gefunden, vieleicht nur Fehler? + if (!snum_found) { + devices[dpos]->lastfound++; + log->set(OWLOG_INFO,"%llx not found %i times \n",device_nums[dpos].num,devices[dpos]->lastfound); + + if (devices[dpos]->lastfound>2) { + + log->set(OWLOG_INFO,"del device %llx (pos %i)\n",device_nums[dpos].num,dpos); + + devices_changed=1; + delete devices[dpos]; + device_nums.erase(device_nums.begin()+dpos); + devices.erase(devices.begin()+dpos); + //printf("new length %i\n",devices.size()); + dpos--; + } + + } else { + devices[dpos]->lastfound=0; + } + dpos++; + + } + return cnt; +} + +int owInterface::MatchRom(snum_t snum) { + Reset(); + sendrecivByte(0x55); + usleep(20); + for(int i=0;i<8;i++) { + sendrecivByte(snum.byte[i]); + usleep(20); + } + if (log->last()>OWLOG_WARNING) return 0; + return 1; +} +int owInterface::Communicate(std::vector *data, int scount, int rcount) { + int i=0; + data->resize(scount); + for(uint8_t v:*data) { + (*data)[i]=sendrecivByte(v);i++; + usleep(20); + } + for(i=0;ipush_back(sendrecivByte(0xFF)); + usleep(20); + + } + return 0; +} + diff --git a/src/owInterface.h b/src/owInterface.h new file mode 100755 index 0000000..83ab326 --- /dev/null +++ b/src/owInterface.h @@ -0,0 +1,291 @@ +// Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// * All advertising materials mentioning features or use of this +// software must display the following acknowledgement: This product +// includes software developed by tm3d.de and its contributors. +// * Neither the name of tm3d.de nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef __OWINTERFACES_H_ +#define __OWINTERFACES_H_ + +#include +#include +#include +#include +#include + + +class owDevice; +class owDeviceConfig; +#include "owDeviceConfig.h" + +#if defined(_WINDOWS) || defined(__WINDOWS__) || defined(_WIN32) || defined(WIN32) + #define USE_WINDOWS_TIME 1 + #include + #include "win32/usb.h" // libusb header +#else + #define USE_WINDOWS_TIME 0 + #include + #include + + #include +#endif + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#define OWLOG_INFO 1 +#define OWLOG_WARNING 2 +#define OWLOG_ERROR 3 + +class owLog { + int lcount; + std::string logtext; + int level; + int loglevel; + +public: + owLog() { + lcount=0; + loglevel=0; + } + virtual int set(int llevel,const char *format, ...) { + char s[300]; + va_list arg; + int done; + va_start (arg, format); + done = vsprintf (s, format, arg); + va_end (arg); + logtext=s; + level=llevel; + lcount++; + if (level>=loglevel) { + if (loglevel==OWLOG_ERROR) printf("\033[1;31m%s\033[0m\n",s); + else if (loglevel==OWLOG_WARNING) printf("\033[1;33m%s\033[0m\n",s); + else printf("%s\n",s); + } + return done; + } + virtual void clear() { + lcount=0; + } + virtual int last() { + if (lcount) return level; else return 0; + } + virtual void setLogLevel(int llevel ){ + loglevel=llevel; + } + +}; + + +typedef union { + uint8_t byte[8]; + uint64_t num; +} snum_t; + +class owInterface { +protected: + int block; + uint8_t crc8; + uint16_t crc16; + uint8_t docrc8(uint8_t value); + uint16_t docrc16(uint16_t cdata); + + // global search state + unsigned char ROM_NO[8]; + int LastDiscrepancy; + int LastFamilyDiscrepancy; + int LastDeviceFlag; + + int devices_changed; + +public: + std::vector device_nums; + std::vector devices; + int maxrepeat; + owLog *log; + owInterface() { + block=0; + log=new owLog(); + maxrepeat=4; + devices_changed=0; + } + void Wait_Free() { + while (block) {}; + block = 1; + } + void Free() { + block = 0; + } + + int isDevicesChanged() { + int dc=devices_changed; + devices_changed=0; + return dc; + } + virtual void Clean(); + virtual int Find() ; + virtual int InitAdapter(std::string s) { + uint8_t param=atoi(s.c_str()); + return InitAdapter(param); + } + virtual void ReleaseAdapter() {} + virtual int InitAdapter(uint8_t)=0; + //Return 1 if Devices Present + virtual int Reset()=0; + virtual uint8_t sendrecivBit(uint8_t bit) =0; + + + + virtual uint8_t sendrecivByte(uint8_t byte) { + uint8_t b=byte; + uint8_t rb=0; + for(int i=0;i<8;i++) { + rb=rb>>1; + rb|=sendrecivBit(b&1)<<7; + b=b>>1; + } + return rb; + } + + virtual int MatchRom(snum_t snum); + virtual int Communicate(std::vector *data, int scount, int rcount); + + + + uint8_t calcCRC8(std::vector data); + uint16_t calcCRC16(std::vector data); + int testCRC16(std::vector data); + + void resetFlasher(); + void resetID(); + int programmPage(int pagenr, std::vector page, int pagesize); + int flashHEXFile(std::string filename,snum_t dev,int resetid,int progress); + + + int owFirst() { + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + return owSearch(); + } + int owNext() { + return owSearch(); + } + virtual ~owInterface() { + ReleaseAdapter(); + } +protected: + int owSearch(); + +}; + +#define OWDCS_NONE 0 +#define OWDCS_DEFAULT 1 +#define OWDCS_16 2 +#define OWDCS_24 3 + + +class owDevice { +protected: + owInterface* owi; + snum_t snum; + std::vector raw; +public: + owDeviceConfig *config; + int configstate; + std::vector values; + int lastfound; //0 found in last searchrom, 1 found in the searchrom befor, and so on + owDevice(owInterface *owi_,snum_t num); + //return 1 for real Config, return 0 for DefaultConig + int readConfig(); + virtual void setDefaultConfig(); + //Information zum owDevice + std::vector getFamilyInfo(); + + snum_t getNum() {return snum;} + + int Communicate(std::vector *data, int scount, int rcount); + int CommunicateShort(std::vector *data, int scount, int rcount); + void changeID(snum_t nid); + void runFlasher(); + virtual int convertAll() {return 1;} + virtual ~owDevice() {} +}; + +class owDeviceDS18B20:public owDevice { +public: + owDeviceDS18B20(owInterface *owi_,snum_t num):owDevice(owi_,num) { } + virtual void setDefaultConfig(); + int readScratchpad(std::vector *sp); + virtual int convertAll(); +} ; + + +class owDeviceDS2438:public owDevice { +public: + owDeviceDS2438(owInterface *owi_,snum_t num):owDevice(owi_,num) {} + virtual void setDefaultConfig(); + + int setConfigByte(uint8_t cb); + int readScratchpad(std::vector *sp, uint8_t page, int recall); + + virtual int convertAll(); + +} ; +class owDeviceDS2450:public owDevice { +public: + owDeviceDS2450(owInterface *owi_,snum_t num):owDevice(owi_,num) {} + + virtual void setDefaultConfig(); + virtual int convertAll(); + void readMemory(uint8_t addr,std::vector *sp); + void writeMemory(uint8_t addr,std::vector *sp); + void convert(uint8_t mask, uint8_t preset); + +} ; + + +class owDeviceDS2423:public owDevice { +public: + owDeviceDS2423(owInterface *owi_,snum_t num):owDevice(owi_,num) {} + + virtual void setDefaultConfig(); + virtual int convertAll(); + uint32_t readCounter(uint8_t page); + +} ; + + +#endif diff --git a/src/owPiGPioInterface.cpp b/src/owPiGPioInterface.cpp new file mode 100755 index 0000000..30ee11f --- /dev/null +++ b/src/owPiGPioInterface.cpp @@ -0,0 +1,245 @@ +// Copyright (c) 2016, Tobias Mueller tm(at)tm3d.de +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// * All advertising materials mentioning features or use of this +// software must display the following acknowledgement: This product +// includes software developed by tm3d.de and its contributors. +// * Neither the name of tm3d.de nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include "owPiGPioInterface.h" +#include +#include +#include +#include +#include /* For O_RDWR */ +#include +#include +#include +#include +#include + +namespace gpio_1w { + + +#ifndef MAP_LOCKED +#define MAP_LOCKED 0 +#endif +static volatile uint32_t pi_peri_phys =0; + + +#define GPIO_BASE (pi_peri_phys + 0x00200000) +#define SYST_BASE (pi_peri_phys + 0x00003000) + +#define GPIO_LEN 0xB4 +#define SYST_LEN 0x1C + +#define USD(ms) {unsigned int t=TICK+ms;while (TICK>5); +int BIT=0;//=(1<<(owpin&0x1F)); + +#define OW_READ ((*(gpioReg_read) & BIT) != 0) + +int piCores; + +unsigned PIHardwareRevision(void) +{ + static unsigned rev = 0; + + FILE * filp; + char buf[512]; + char term; + + if (rev) return rev; + + piCores = 0; + + filp = fopen ("/proc/cpuinfo", "r"); + + if (filp != NULL) + { + while (fgets(buf, sizeof(buf), filp) != NULL) + { + if (piCores == 0) + { + if (!strncasecmp("model name", buf, 10)) + { + if (strstr (buf, "ARMv6") != NULL) + { + piCores = 1; + pi_peri_phys = 0x20000000; + // pi_dram_bus = 0x40000000; + // pi_mem_flag = 0x0C; + } + else if (strstr (buf, "ARMv7") != NULL) + { + piCores = 4; + pi_peri_phys = 0x3F000000; + //pi_dram_bus = 0xC0000000; + //pi_mem_flag = 0x04; + } + else if (strstr (buf, "ARMv8") != NULL) + { + piCores = 4; + pi_peri_phys = 0x3F000000; + // pi_dram_bus = 0xC0000000; + // pi_mem_flag = 0x04; + } + } + } + + if (!strncasecmp("revision\t:", buf, 10)) + { + if (sscanf(buf+10, "%x%c", &rev, &term) == 2) + { + if (term != '\n') rev = 0; + else rev &= 0xFFFFFF; /* mask out warranty bit */ + } + } + } + + fclose(filp); + } + return rev; +} + + + + + + +} +using namespace gpio_1w; + + +int owPiGPioInterface::InitAdapter(uint8_t pin){ + owpin=pin; + PIHardwareRevision(); + if (fdMem==-1) { + if ((fdMem = open("/dev/mem", O_RDWR | O_SYNC) ) < 0) { + log->set(OWLOG_ERROR,"No permission to change Port States, try running as root (sudo)"); + exit(-1); + } + + systReg = (uint32_t *) mmap(0, SYST_LEN, PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_SHARED|MAP_LOCKED, fdMem, SYST_BASE); + gpioReg = (uint32_t *) mmap(0, GPIO_LEN, PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_SHARED|MAP_LOCKED, fdMem, GPIO_BASE); + //if (level == PI_OFF) *(gpioReg + GPCLR0 + BANK) = BIT; + //else *(gpioReg + GPSET0 + BANK) = BIT; + *(gpioReg + GPCLR0 + BANK) = BIT; + + gpioReg_read=gpioReg + GPLEV0 + BANK; + + gpio_reg=owpin/10; + gpio_shift= (owpin%10) * 3; + gpio_shift_=~(7<>5); + BIT=(1<<(owpin&0x1F)); + } + return 0; + +} +int owPiGPioInterface::Reset() { + int read; + OW_SET_LOW; + USD(480); + OW_RELEASE_LOW; + USD(65); + read=OW_READ; + USD(410); + if (read) { + OW_SET_LOW; + USD(480); + OW_RELEASE_LOW; + USD(65); + read=OW_READ; + USD(410); + + } + return read==0; +} + + +uint8_t owPiGPioInterface::sendrecivBit(uint8_t bit) { + unsigned int lmis; + uint8_t read=0; + //pinMode(owpin,OUTPUT); + lmis=TICK; + + //cli_(); + OW_SET_LOW; + lmis+=6; + while (TICK +#include +#include +#include +#include +#include + + + + +extern "C" { +#include "libusbds2490.h" +} + + + + +namespace usb_1w { + + +#define FALSE 0 +#define TRUE 1 +int usb_num_devices = -1; +usb_dev_handle *usb_dev_handle_list[20]; +//static SMALLINT usbhnd_init = 0; +struct usb_device *usb_dev_list[20]; +static void DS2490Discover(void) +{ + struct usb_bus *bus; + struct usb_device *dev; + + // initialize USB subsystem +#ifdef LIBUSB_DEBUG_DISABLE // Use this define at compile time to turn off LIBUSB debug info + usb_set_debug(0); +#endif + usb_init(); + usb_find_busses(); + usb_find_devices(); + + usb_num_devices = 0; // avoid port zero to make it look like other builds + + for (bus = usb_get_busses(); bus; bus = bus->next) + { + + for (dev = bus->devices; dev; dev = dev->next) + { + //printf("%04X:%04X\n",dev->descriptor.idVendor,dev->descriptor.idProduct); + if (dev->descriptor.idVendor == 0x04FA && + dev->descriptor.idProduct == 0x2490) + { + //printf("DS2490Discover-find\n"); + usb_dev_list[++usb_num_devices] = dev; + + } + } + } +} + + +uint8_t AdapterRecover(usb_dev_handle *hDevice) +{ + // detect DS2490 and set it up + if (DS2490Detect(hDevice)) + { + //USBSpeed[portnum] = MODE_NORMAL; // current DS2490 1-Wire Net communication speed + //USBLevel[portnum] = MODE_NORMAL; // current DS2490 1-Wire Net level + return TRUE; + } + else + { + //OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED); + return FALSE; + } +} + +} + +using namespace usb_1w; +int id[8]; +int first=1; + +int owUSBInterface::InitAdapter(uint8_t pin){ + if(!usbhnd_init) // check to see the USB bus has been setup properly + { + // discover all DS2490s on USB bus... + DS2490Discover(); + usbhnd_init = 1; + } + if (usb_num_devices==0) return -1; + + // check to see if the portnumber is valid + if ((usb_num_devices set(OWLOG_ERROR,"OWERROR_LIBUSB_NO_ADAPTER_FOUND"); + return -1; + } + + // check to see if opening the device is valid + if (hDevice!= NULL) + { + // error - USB Device already open + log->set(OWLOG_ERROR,"OWERROR_LIBUSB_DEVICE_ALREADY_OPENED"); + return -1; + } + + // open the device + hDevice = usb_open(usb_dev_list[pin]); + if (hDevice == NULL) + { + // Failed to open usb device + log->set(OWLOG_ERROR,"OWERROR_LIBUSB_OPEN_FAILED"); + return -1; + } + + // set the configuration + if (usb_set_configuration(hDevice, 1)) + { + // Failed to set configuration + log->set(OWLOG_ERROR,"OWERROR_LIBUSB_SET_CONFIGURATION_ERROR"); + usb_close(hDevice); // close handle + return -2; + } + + // claim the interface + if (usb_claim_interface(hDevice, 0)) + { + // Failed to claim interface + //printf("%s\n", usb_strerror()); + log->set(OWLOG_ERROR,"OWERROR_LIBUSB_CLAIM_INTERFACE_ERROR"); + usb_close(hDevice); // close handle + return -1; + } + + // set the alt interface + if (usb_set_altinterface(hDevice, 3)) + { + // Failed to set altinterface + //printf("%s\n", usb_strerror()); + log->set(OWLOG_ERROR,"OWERROR_LIBUSB_SET_ALTINTERFACE_ERROR"); + usb_release_interface(hDevice, 0); // release interface + usb_close(hDevice); // close handle + return -1; + } + + + // clear USB endpoints before doing anything with them. + usb_clear_halt(hDevice, DS2490_EP3); + usb_clear_halt(hDevice, DS2490_EP2); + usb_clear_halt(hDevice, DS2490_EP1); + + // verify adapter is working + if (!AdapterRecover(hDevice)) + { + log->set(OWLOG_ERROR,"Adapter don't work"); + usb_release_interface(hDevice, 0); // release interface + usb_close(hDevice); // close handle + return -1; + } + + // reset the 1-Wire + Reset(); + + return 1; + } +int owUSBInterface::Reset() { + SETUP_PACKET setup; + SMALLINT present,vpp; + SMALLINT ret = 0; + + // construct command + setup.RequestTypeReservedBits = 0x40; + setup.Request = COMM_CMD; + setup.Value = COMM_1_WIRE_RESET | COMM_F | COMM_IM | COMM_SE; + setup.Index = ONEWIREBUSSPEED_REGULAR;// ONEWIREBUSSPEED_FLEXIBLE; + setup.Length = 0; + setup.DataOut = FALSE; + // call the libusb driver + ret = usb_control_msg(hDevice, + setup.RequestTypeReservedBits, + setup.Request, + setup.Value, + setup.Index, + NULL, + setup.Length, + TIMEOUT_LIBUSB); + if (ret < 0) + { + // failure + log->set(OWLOG_ERROR,"OWERROR_RESET_FAILED"); + //AdapterRecover(portnum); + return FALSE; + } + else + { + // extra delay for alarming DS1994/DS2404 complience + // if ((FAMILY_CODE_04_ALARM_TOUCHRESET_COMPLIANCE) && (USBSpeed[portnum] != MODE_OVERDRIVE)) + // msDelay(5); + + // success, check for shorts + if (DS2490ShortCheck(hDevice, &present,&vpp)) + { + //USBVpp[portnum] = vpp; + return present; + } + else + { + log->set(OWLOG_ERROR,"OWERROR_OW_SHORTED"); + // short occuring + usleep(300); + //AdapterRecover(portnum); + return FALSE; + } + } +} + + +uint8_t owUSBInterface::sendrecivBit(uint8_t bit) { + SETUP_PACKET setup; + ushort nBytes; + uchar buf[2]; + SMALLINT ret = 0; + + // set to do touchbit + setup.RequestTypeReservedBits = 0x40; + setup.Request = COMM_CMD; + setup.Value = COMM_BIT_IO | COMM_IM | ((bit) ? COMM_D : 0); + setup.Index = 0; + setup.Length = 0; + setup.DataOut = FALSE; + + // call the libusb driver + ret = usb_control_msg(hDevice, + setup.RequestTypeReservedBits, + setup.Request, + setup.Value, + setup.Index, + NULL, + setup.Length, + TIMEOUT_LIBUSB); + if (ret < 0) + { + // failure + log->set(OWLOG_ERROR,"OWERROR_ADAPTER_ERROR"); + AdapterRecover(hDevice); + return 0; + } + else + { + // success, read the result + nBytes = 1; + if (DS2490Read(hDevice, buf, &nBytes)) { + usleep(70); + return buf[0]; + } + else + { + log->set(OWLOG_ERROR,"OWERROR_ADAPTER_ERROR"); + AdapterRecover(hDevice); + return 0; + } + } +} + +uint8_t owUSBInterface::sendrecivByte(uint8_t byte) { + SETUP_PACKET setup; + ushort nBytes; + uchar buf[2]; + SMALLINT ret = 0; + + // set to do touchbyte + setup.RequestTypeReservedBits = 0x40; + setup.Request = COMM_CMD; + setup.Value = COMM_BYTE_IO | COMM_IM; + setup.Index = byte & 0xFF; + setup.Length = 0; + setup.DataOut = FALSE; + + // call the libusb driver + ret = usb_control_msg(hDevice, + setup.RequestTypeReservedBits, + setup.Request, + setup.Value, + setup.Index, + NULL, + setup.Length, + TIMEOUT_LIBUSB); + if (ret < 0) + { + // failure + log->set(OWLOG_ERROR,"OWERROR_ADAPTER_ERROR"); + AdapterRecover(hDevice); + return 0; + } + else + { + // success, read the result + nBytes = 1; + + if (DS2490Read(hDevice, buf, &nBytes)) { + usleep(80); + return buf[0]; + } + else + { + log->set(OWLOG_ERROR,"OWERROR_ADAPTER_ERROR"); + AdapterRecover(hDevice); + return 0; + } + } +} + +void owUSBInterface::ReleaseAdapter() { + usb_release_interface(hDevice, 0); + usb_close(hDevice); + hDevice = NULL; +} diff --git a/src/owUSBInterface.h b/src/owUSBInterface.h new file mode 100755 index 0000000..a2b893a --- /dev/null +++ b/src/owUSBInterface.h @@ -0,0 +1,57 @@ +// Copyright (c) 2016, Tobias Mueller tm(at)tm3d.de +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// * All advertising materials mentioning features or use of this +// software must display the following acknowledgement: This product +// includes software developed by tm3d.de and its contributors. +// * Neither the name of tm3d.de nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef __OWUSBINTERFACES_H_ +#define __OWUSBINTERFACES_H_ + +#include "owInterface.h" + +class owUSBInterface:public owInterface{ +protected: + usb_dev_handle *hDevice; + int usbhnd_init; +public: + owUSBInterface():owInterface() { + + hDevice=NULL; + usbhnd_init=0; + } + virtual int InitAdapter(uint8_t); + virtual int Reset(); + virtual uint8_t sendrecivBit(uint8_t bit); + virtual uint8_t sendrecivByte(uint8_t byte); + virtual void ReleaseAdapter(); + +}; + +#endif