commit 3c6f0dd50f95dc771f5c191d1405ddaa3a451bd5 Author: Frank Voorburg Date: Thu Nov 10 17:55:56 2011 +0000 git-svn-id: https://svn.code.sf.net/p/openblt/code/trunk@1 5dc33758-31d5-4daf-9ae8-b24bf3d40d73 diff --git a/Doc/license.html b/Doc/license.html new file mode 100644 index 00000000..18e02da2 --- /dev/null +++ b/Doc/license.html @@ -0,0 +1,733 @@ + + + + + + + + + + +The GNU General Public License v3.0 - GNU Project - Free Software Foundation (FSF) + + + + + + + + + + + + + + + + +
+

Introduction

+

The OpenBLT source code is licensed by the modified GNU General +Public License (GPL) text provided below.  The OpenBLT download +also includes demo application source code, some of which is provided +by third parties AND IS LICENSED SEPARATELY FROM OPENBLT. For the +avoidance of any doubt refer to the comment included at the top of each +source and header file for license and copyright information.
+
+This is a list of files for which Feaser is not the copyright owner and are NOT COVERED BY THE GPL.
+

+
    +
  1. Various header files provided by silicon manufacturers and tool +vendors that define processor specific memory addresses and utility +macros. Permission has been granted by the various copyright holders +for these files to be included in the OpenBLT download. Users must +ensure license conditions are adhered to for any use other than +compilation of the OpenBLT demo applications.
  2. +
  3. Various peripheral driver source files and binaries provided by silicon +manufacturers and tool vendors. Permission has been granted by the +various copyright holders for these files to be included in the OpenBLT +download. Users must ensure license conditions are adhered to for any +use other than compilation of the OpenBLT demo applications.
  4. +
+

Errors and omissions should be reported to Feaser, contact details can be obtained from http://www.feaser.com.
+
+The GPL license text follows. A special exception to the GPL is +included to allow you to distribute a combined work that includes +OpenBLT without being obliged to provide the source code for any +proprietary components. The exception text is included at the bottom of +this file.
+

+
+ +

GNU GENERAL PUBLIC LICENSE

+

Version 3, 29 June 2007

+ +

Copyright © 2007 Free Software Foundation, Inc. + <http://fsf.org/>

+ 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.

+
+

OpenBLT GPL Exception Text
+

+ +

Any OpenBLT source code, whether modified or in it's original +release form, or whether in whole or in part, can only be distributed +by you under the terms
+of the GNU General Public License plus this exception. An independent +module is a module which is not derived from or based on OpenBLT.
+

+

Clause 1

+

Linking OpenBLT statically or dynamically with other modules is +making a combined work based on OpenBLT. Thus, the terms and conditions +of the GNU General Public License cover the whole combination.
+
+As a special exception, the copyright holder of OpenBLT gives you +permission to link OpenBLT with independent modules that communicate +with OpenBLT solely through the OpenBLT API interface, regardless of +the license terms of these independent modules, and to copy and +distribute the resulting combined work under terms of your choice, +provided that
+
+

+
    +
  • Every copy of the combined work is accompanied by a written +statement that details to the recipient the version of OpenBLT used and +an offer by yourself to provide the OpenBLT source code (including any +modifications you may have made) should the recipient request it.
  • +
  • The combined work is not itself a bootloader or related product.
  • +
  • The independent modules add significant and primary functionality +to OpenBLT and do not merely extend the existing functionality already +present in OpenBLT.
  • +
+

Clause 2

+

OpenBLT may not be used for any competitive or comparative purpose, +including the publication of any form of run time or compile time +metric, without the express permission of Feaser (this is the norm +within the industry andis intended to ensure information accuracy).
+

+


+

+ + +
\ No newline at end of file diff --git a/Host/MicroBoot.exe b/Host/MicroBoot.exe new file mode 100644 index 00000000..e56187e9 Binary files /dev/null and b/Host/MicroBoot.exe differ diff --git a/Host/Pcan_usb.dll b/Host/Pcan_usb.dll new file mode 100644 index 00000000..25a0b7fc Binary files /dev/null and b/Host/Pcan_usb.dll differ diff --git a/Host/Source/MainUnit.dfm b/Host/Source/MainUnit.dfm new file mode 100644 index 00000000..8e824357 Binary files /dev/null and b/Host/Source/MainUnit.dfm differ diff --git a/Host/Source/MainUnit.pas b/Host/Source/MainUnit.pas new file mode 100644 index 00000000..1883e99c --- /dev/null +++ b/Host/Source/MainUnit.pas @@ -0,0 +1,767 @@ +unit MainUnit; +//*************************************************************************************** +// Project Name: MicroBoot for Borland Delphi +// Description: Contains the GUI for MicroBoot +// File Name: MainUnit.pas +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** +interface + + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + ExtCtrls, StdCtrls, Menus, ComCtrls, uBootInterface, Registry, SettingsUnit, StopWatch; + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +type + TmainForm = class(TForm) + pnlHeader: TPanel; + imgHeader: TImage; + lblAppName: TLabel; + lblInterfaceName: TLabel; + bvlFooter: TBevel; + btnCancel: TButton; + btnSettings: TButton; + ntbPages: TNotebook; + edtDownloadFile: TEdit; + btnBrowse: TButton; + lblDownloadFile: TLabel; + prgDownload: TProgressBar; + lblDownloadProgress: TLabel; + OpenDialog: TOpenDialog; + Timer: TTimer; + lblElapsedTime: TLabel; + procedure btnCancelClick(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure btnBrowseClick(Sender: TObject); + procedure btnSettingsClick(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure TimerTimer(Sender: TObject); + procedure edtDownloadFileKeyPress(Sender: TObject; var Key: Char); + private + { Private declarations } + MbiLogging : Boolean; + MbiLibFile : ShortString; + MbiInterfaced : Boolean; + MbiInterface : TMicroBootInterface; + LogLines : TStrings; + ExePath : string; + StopWatch : TStopWatch; + StayOpen : Boolean; + FormCaption : string; + procedure OnMbiStarted(length: Longword); + procedure OnMbiProgress(progress: Longword); + procedure OnMbiDone; + procedure OnMbiError(error: ShortString); + procedure OnMbiLog(info: ShortString); + procedure OnMbiInfo(info: ShortString); + procedure StartFileDownload(fileName : ShortString); + procedure UpdateInterfaceLabel; + public + { Public declarations } + function IsMbiInterface(libFile : string) : Boolean; + function GetMbiInfoString(libFile : string) : string; + function GetActiveMbi : string; + procedure SetActiveMbi(libFile : string); + procedure ConfigureMbi; + procedure GetInterfaceFileList(fileList : TStrings); + end; + + +//*************************************************************************************** +// Global Variables +//*************************************************************************************** +var + mainForm: TmainForm; + +implementation + +{$R *.DFM} + +//*************************************************************************************** +// NAME: OnMbiStarted +// PARAMETER: length of the download in bytes. +// RETURN VALUE: none +// DESCRIPTION: Called by the Mbi interface DLL after successfully starting a down- +// load. The value of the length parameter can be used to set the max +// value of the progress bar. +// +//*************************************************************************************** +procedure TmainForm.OnMbiStarted(length: Longword); +begin + prgDownload.Max := length; // set max length for progress bar + lblElapsedTime.Caption := 'Elapsed time: ' + StopWatch.Interval; + StopWatch.Start; // start the stopwatch + Timer.Enabled := true; // start the timer to update the stopwatch interval display +end; //*** end of OnMbiStarted *** + + +//*************************************************************************************** +// NAME: OnMbiProgress +// PARAMETER: number of already downloaded bytes. +// RETURN VALUE: none +// DESCRIPTION: Called by the Mbi interface DLL to provide us with an update on the +// download progress. The progress parameter can be used to update the +// position of the progress bar. +// +//*************************************************************************************** +procedure TmainForm.OnMbiProgress(progress: Longword); +begin + prgDownload.Position := progress; // update the progress bar +end; //*** end of OnMbiProgress *** + + +//*************************************************************************************** +// NAME: OnMbiDone +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Called by the Mbi interface DLL when a download was successfully +// completed. +// +//*************************************************************************************** +procedure TmainForm.OnMbiDone; +begin + Timer.Enabled := false; // stop the timer + StopWatch.Stop; // stop the stopwatch + mainForm.Caption := FormCaption; // restore caption + + if StayOpen then + begin + NtbPages.PageIndex := 0; // go to the next page + btnSettings.Enabled := true; // settings can't be changed anymore + end + else + Close; // done so close the application +end; //*** end of OnMbiDone *** + + +//*************************************************************************************** +// NAME: OnMbiError +// PARAMETER: additional info on the error that occurred in string format. +// RETURN VALUE: none +// DESCRIPTION: Called by the Mbi interface DLL in case an error occurred. The para- +// meter contains more information on the error. +// +//*************************************************************************************** +procedure TmainForm.OnMbiError(error: ShortString); +begin + ShowMessage(error); // display error + Timer.Enabled := false; // stop the timer + StopWatch.Stop; // stop the stopwatch + mainForm.Caption := FormCaption; // restore caption + + if StayOpen then + begin + NtbPages.PageIndex := 0; // go to the next page + btnSettings.Enabled := true; // settings can't be changed anymore + end + else + Close; // can't continue so close the application +end; //*** end of OnMbiError *** + + +//*************************************************************************************** +// NAME: OnMbiLog +// PARAMETER: info on the log event in string format. +// RETURN VALUE: none +// DESCRIPTION: Called by the Mbi interface DLL in case info for logging purpose +// was made available by the DLL. +// +//*************************************************************************************** +procedure TmainForm.OnMbiLog(info: ShortString); +begin + if MbiLogging = True then + begin + LogLines.Add(info); // add to log + end; +end; //*** end of OnMbiLog *** + + +//*************************************************************************************** +// NAME: OnMbiInfo +// PARAMETER: details on the info event in string format. +// RETURN VALUE: none +// DESCRIPTION: Called by the Mbi interface DLL in case details for info purposes +// were made available by the DLL. +// +//*************************************************************************************** +procedure TmainForm.OnMbiInfo(info: ShortString); +begin + if NtbPages.PageIndex = 1 then + lblDownloadProgress.Caption := info; +end; //*** end of OnMbiLog *** + + +//*************************************************************************************** +// NAME: GetActiveMbi +// PARAMETER: none +// RETURN VALUE: filename with full path +// DESCRIPTION: Returns the file name with full path of the active Mbi interface +// library +// +//*************************************************************************************** +function TmainForm.GetActiveMbi : string; +begin + if IsMbiInterface(MbiLibFile) then + Result := MbiLibFile + else + Result := ''; +end; //*** end of GetActiveMbi *** + + +//*************************************************************************************** +// NAME: SetActiveMbi +// PARAMETER: filename with full path +// RETURN VALUE: none +// DESCRIPTION: Enables the Mbi interface library that is specified as the parameter. +// +//*************************************************************************************** +procedure TmainForm.SetActiveMbi(libFile : string); +begin + MbiInterfaced := false; // reset + + if IsMbiInterface(libFile) then + begin + MbiLibFile := libFile; + MbiInterfaced := MbiInterface.Enable(libFile, OnMbiStarted, OnMbiProgress, + OnMbiDone, OnMbiError, OnMbiLog, OnMbiInfo); + end; + + UpdateInterfaceLabel; +end; //*** end of SetActiveMbi *** + + +//*************************************************************************************** +// NAME: ConfigureMbi +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Submits request to the Mbi interface library for the user to configure +// the interface. +// +//*************************************************************************************** +procedure TmainForm.ConfigureMbi; +begin + if MbiInterfaced = True then + begin + MbiInterface.Configure; + end; +end; //*** end of ConfigureMbi *** + + +//*************************************************************************************** +// NAME: IsMbiInterface +// PARAMETER: filename with full path of the Mbi interface DLL +// RETURN VALUE: true if it is a valid Mbi interface DLL, otherwise false +// DESCRIPTION: Called to check whether a specified interface DLL is truly an Mbi +// interface DLL. +// +//*************************************************************************************** +function TmainForm.IsMbiInterface(libFile : string) : Boolean; +var + LibHandle : THandle; + LibValid : Boolean; +begin + LibValid := False; + + // make sure the file exists + if FileExists(libFile) then + begin + // make sure it is a DLL file + if LowerCase(ExtractFileExt(libFile)) = '.dll' then + begin + // make sure the DLL file is a microBoot interface library + LibHandle := LoadLibrary(PChar(ExtractShortPathName(libFile))); // get handle + if LibHandle <> 0 then + begin + if GetProcAddress(LibHandle, 'MbiInit') <> nil then + begin + LibValid := True; + FreeLibrary(LibHandle); + end; + end; + end; + end; + Result := LibValid; +end; //*** end of IsMbiInterface *** + + +//*************************************************************************************** +// NAME: GetMbiInfoString +// PARAMETER: filename with full path of the Mbi interface DLL +// RETURN VALUE: string that described the name and version of the Mbi interface DLL +// DESCRIPTION: Used to obtain a string that describes the Mbi interface DLL. +// +//*************************************************************************************** +function TmainForm.GetMbiInfoString(libFile : string) : string; +var + LibHandle : THandle; + DescriptionFnc : TDllMbiDescription; + VersionFnc : TDllMbiVersion; + Major : integer; + Minor : integer; + Bugfix : integer; +begin + Result := ''; + + // make sure the file is a valid Mbi interface library + if IsMbiInterface(libFile) then + begin + LibHandle := LoadLibrary(PChar(ExtractShortPathName(libFile))); // get handle + if LibHandle <> 0 then + begin + // obtain DLL function pointers + @DescriptionFnc := GetProcAddress(LibHandle, 'MbiDescription'); + @VersionFnc := GetProcAddress(LibHandle, 'MbiVersion'); + + if Assigned(DescriptionFnc) then + begin + Result := Result + DescriptionFnc; + end; + + if Assigned(VersionFnc) then + begin + // split up version numbers + Major := VersionFnc div 10000; + Minor := (versionFnc mod 10000) div 100; + Bugfix := (versionFnc mod 100); + + Result := Result + ' (' + Format('v%d.%2.2d.%2.2d', [Major, Minor, Bugfix]) + ')'; + end; + FreeLibrary(LibHandle); + end; + end; +end; //*** end of GetMbiInfoString *** + + +//*************************************************************************************** +// NAME: GetInterfaceFileList +// PARAMETER: string list where filelist will be stored +// RETURN VALUE: none +// DESCRIPTION: Searches all the DLL files in the directory where the program's EXE +// runs from. If the found DLL file is a valib Mbi interface library, +// then it is added to the list. +// +//*************************************************************************************** +procedure TmainForm.GetInterfaceFileList(fileList : TStrings); +var + SR : TSearchRec; +begin + // search all dll's in the applicatioin's directory + fileList.BeginUpdate; + if FindFirst(ExePath + '*.dll', faAnyFile, SR) = 0 then + begin + repeat + if (SR.Attr <> faDirectory) then + begin + if IsMbiInterface(ExePath + SR.Name) = True then + fileList.Add(SR.Name); + end; + until FindNext(SR) <> 0; + FindClose(SR); + end; + fileList.EndUpdate; +end; //*** end of GetInterfaceFileList *** + + +//*************************************************************************************** +// NAME: StartFileDownload +// PARAMETER: file that is to be downloaded +// RETURN VALUE: none +// DESCRIPTION: Initiates the file download. The file is verified for existence and if +// all is okay, the next page is shown and the download is started. +// +//*************************************************************************************** +procedure TmainForm.StartFileDownload(fileName : ShortString); +begin + if FileExists(fileName) and (MbiInterfaced = True) then + begin + FormCaption := mainForm.Caption; // backup original caption + mainForm.Caption := FormCaption + ' - Downloading ' + + ExtractFileName(fileName) + '...'; + prgDownload.Position := 0; // reset the progress bar + NtbPages.PageIndex := 1; // go to the next page + btnSettings.Enabled := false; // settings can't be changed anymore + MbiInterface.Download(fileName); + end; +end; //*** end of StartFileDownload *** + + +//*************************************************************************************** +// NAME: UpdateInterfaceLabel +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Updates the interface label caption based on the active Mbi interface +// library +// +//*************************************************************************************** +procedure TmainForm.UpdateInterfaceLabel; +begin + // display interface library description + if MbiInterfaced = True then + begin + lblInterfaceName.Caption := 'for ' + MbiInterface.Description; + end + else + begin + lblInterfaceName.Caption := 'Error - No Interface Library Loaded'; + end; +end; //*** end of UpdateInterfaceLabel *** + + +//*************************************************************************************** +// NAME: btnCancelClick +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Exits the application +// +//*************************************************************************************** +procedure TmainForm.btnCancelClick(Sender: TObject); +begin + // pass on cancel request to the library + if MbiInterfaced = True then + begin + MbiInterface.Cancel; + end; + + Close; +end; //*** end of btnCancelClick *** + + +//*************************************************************************************** +// NAME: FormCreate +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Initializes all the class properties and attempts to search and enable +// the Mbi interface library. +// +//*************************************************************************************** +procedure TmainForm.FormCreate(Sender: TObject); +var + cnt : integer; + foundInterface : boolean; + foundLibrary : string; + winRegistry : TRegistry; + libFileList : TStrings; +begin + LogLines := TStringList.Create; + StayOpen := false; + MbiLogging := false; + MbiInterfaced := false; // Mbi interface not enabled at startup + MbiLibFile := ''; // reset lib file + MbiInterface := TMicroBootInterface.Create(Self); // create instance + foundInterface := false; // init before searching + ExePath := ExtractFilePath(Application.ExeName); + + // determine if logging should be enabled + if (ParamCount > 0) then + begin + // no options will be in Param 0 + for cnt := 1 to ParamCount do + begin + // look for -l option + if System.Pos('-l', ParamStr(cnt)) > 0 then + begin + MbiLogging := True; + end; + end; + end; + + // this feature is unstable so do not yet support it in a release version + // determine if tool should stay open after a download completion + //if (ParamCount > 0) then + //begin + // // no options will be in Param 0 + // for cnt := 1 to ParamCount do + // begin + // // look for -l option + // if System.Pos('-s', ParamStr(cnt)) > 0 then + // begin + // StayOpen := True; + // end; + // end; + //end; + + // determine what interface library to use on startup + // 1) -------- From commandline parameter --------------- + foundLibrary := ''; + // parameters okay, now extract the command line options if any + if (ParamCount > 0) then + begin + // no options will be in Param 0 + for cnt := 1 to ParamCount do + begin + // look for -i option + if System.Pos('-i', ParamStr(cnt)) > 0 then + begin + foundLibrary := ExePath + System.Copy(ParamStr(cnt), + System.Pos('-i', ParamStr(cnt))+2, Length(ParamStr(cnt))); + end; + end; + end; + + // interface library specified on the commandline? + if foundLibrary <> '' then + begin + // is it a valid Mbi interface library? + if IsMbiInterface(foundLibrary) = True then + begin + MbiLibFile := foundLibrary; + foundInterface := True; + end; + end; + + // 2) -------- From registry --------------- + if not foundInterface then + begin + // open registry key + winRegistry := TRegistry.Create; + winRegistry.RootKey := HKEY_LOCAL_MACHINE; + winRegistry.OpenKeyReadOnly('Software\Feaser\MicroBoot'); + + // attempt to read out the stored interface filename (without path) + if winRegistry.ReadString('Interface') <> '' then + begin + // obtain the interface library file name from the registry key + foundLibrary := ExePath + winRegistry.ReadString('Interface'); + + // is it a valid Mbi interface library? + if IsMbiInterface(foundLibrary) = True then + begin + MbiLibFile := foundLibrary; + foundInterface := True; + end; + end; + winRegistry.Free; // registry access no longer needed + end; + + // 3) -------- first interface library found --------------- + if not foundInterface then + begin + libFileList := TStringList.Create; + libFileList.Clear; + GetInterfaceFileList(libFileList); + if libFileList.Count > 0 then + begin + foundLibrary := ExePath + libFileList.Strings[0]; + // is it a valid Mbi interface library? + if IsMbiInterface(foundLibrary) = True then + begin + MbiLibFile := foundLibrary; + foundInterface := True; + end; + end; + libFileList.Free; + end; + + // did we find a Mbi interface library? + if foundInterface = True then + begin + SetActiveMbi(MbiLibFile); + end; + + // create the stopwatch timer + StopWatch := TStopWatch.Create; +end; //*** end of FormCreate *** + + +//*************************************************************************************** +// NAME: FormDestroy +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: DeInitializes all the class properties that where instanciated. +// +//*************************************************************************************** +procedure TmainForm.FormDestroy(Sender: TObject); +begin + MbiInterface.Free; // release the interface + LogLines.Free; + + // release the stopwatch timer + StopWatch.Free; +end; //*** end of FormDestroy *** + + +//*************************************************************************************** +// NAME: FormShow +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Loads and displays the interface library description. If a valid +// download file is selected as a command line parameter the download +// is started right away. If the -p command line parameter was specified, +// then the open file dialog is displayed automatically. +// +//*************************************************************************************** +procedure TmainForm.FormShow(Sender: TObject); +var + cnt : integer; +begin + UpdateInterfaceLabel; + + // was an existing download file specified as a command line param? + if (ParamCount > 0) and (FileExists(ParamStr(ParamCount))) then + begin + edtDownloadFile.Text := ParamStr(ParamCount); + StartFileDownload(ParamStr(ParamCount)); + Exit; // nothing more todo + end; + + // was the -p command line option specified? + // parameters okay, now extract the command line options if any + if (ParamCount > 0) then + begin + // no options will be in Param 0 + for cnt := 1 to ParamCount do + begin + // look for -i option + if System.Pos('-p', ParamStr(cnt)) > 0 then + begin + if OpenDialog.Execute then + begin + if FileExists(OpenDialog.FileName) then + begin + edtDownloadFile.Text := OpenDialog.FileName; + StartFileDownload(OpenDialog.FileName); + end; + end; + end; + end; + end; +end; //*** end of FormShow *** + + +//*************************************************************************************** +// NAME: btnBrowseClick +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Prompts the user to select a file to download. +// +//*************************************************************************************** +procedure TmainForm.btnBrowseClick(Sender: TObject); +begin + if OpenDialog.Execute then + begin + if FileExists(OpenDialog.FileName) then + begin + edtDownloadFile.Text := OpenDialog.FileName; + StartFileDownload(OpenDialog.FileName); + end; + end; +end; //*** end of btnBrowseClick *** + + +//*************************************************************************************** +// NAME: btnSettingsClick +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Opens the settings form where the user can select and configure the +// Mbi interface library. +// +//*************************************************************************************** +procedure TmainForm.btnSettingsClick(Sender: TObject); +var + winRegistry : TRegistry; +begin + if SettingsForm.ShowModal = mrOK then + begin + if MbiInterfaced then + begin + // store last used library in register + winRegistry := TRegistry.Create; + winRegistry.RootKey := HKEY_LOCAL_MACHINE; + winRegistry.OpenKey('Software\Feaser\MicroBoot', true); + winRegistry.WriteString('Interface', ExtractFileName(MbiLibFile)); + winRegistry.Free; + end; + UpdateInterfaceLabel; + end; +end; //*** end of btnSettingsClick *** + + +//*************************************************************************************** +// NAME: FormClose +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Saves the log to a file before closing the application. +// +//*************************************************************************************** +procedure TmainForm.FormClose(Sender: TObject; var Action: TCloseAction); +begin + // save the log to a file before closing the app + if MbiLogging = True then + begin + LogLines.SaveToFile(ExePath + 'log.txt'); + end; +end; //*** end of FormClose *** + + +//*************************************************************************************** +// NAME: TimeTimer +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Timer event handler to update stopwatch info +// +//*************************************************************************************** +procedure TmainForm.TimerTimer(Sender: TObject); +begin + lblElapsedTime.Caption := 'Elapsed time: ' + StopWatch.Interval; +end; //*** end of TimerTimer *** + +procedure TmainForm.edtDownloadFileKeyPress(Sender: TObject; + var Key: Char); +begin + // filter out enter key + if key = #13 then + begin + // ignore further enter key processing + key := #0; + + // start the download + if FileExists(edtDownloadFile.Text) then + begin + StartFileDownload(edtDownloadFile.Text); + end; + + end; +end; + +end. +//******************************** end of MainUnit.pas ********************************** + diff --git a/Host/Source/MicroBoot.cfg b/Host/Source/MicroBoot.cfg new file mode 100644 index 00000000..baee3e0e --- /dev/null +++ b/Host/Source/MicroBoot.cfg @@ -0,0 +1,35 @@ +-$A+ +-$B- +-$C+ +-$D+ +-$E- +-$F- +-$G+ +-$H+ +-$I+ +-$J+ +-$K- +-$L+ +-$M- +-$N+ +-$O+ +-$P+ +-$Q- +-$R- +-$S- +-$T- +-$U- +-$V+ +-$W- +-$X+ +-$YD +-$Z1 +-cg +-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +-H+ +-W+ +-M +-$M16384,1048576 +-K$00400000 +-E../ +-LNc:\program files (x86)\borland\delphi4\Lib diff --git a/Host/Source/MicroBoot.dof b/Host/Source/MicroBoot.dof new file mode 100644 index 00000000..07fb676d --- /dev/null +++ b/Host/Source/MicroBoot.dof @@ -0,0 +1,86 @@ +[Compiler] +A=1 +B=0 +C=1 +D=1 +E=0 +F=0 +G=1 +H=1 +I=1 +J=1 +K=0 +L=1 +M=0 +N=1 +O=1 +P=1 +Q=0 +R=0 +S=0 +T=0 +U=0 +V=1 +W=0 +X=1 +Y=1 +Z=1 +ShowHints=1 +ShowWarnings=1 +UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +[Linker] +MapFile=0 +OutputObjs=0 +ConsoleApp=1 +DebugInfo=0 +RemoteSymbols=0 +MinStackSize=16384 +MaxStackSize=1048576 +ImageBase=4194304 +ExeDescription= +[Directories] +OutputDir=../ +UnitOutputDir= +PackageDLLOutputDir= +PackageDCPOutputDir= +SearchPath= +Packages=Vcl40;Vclx40;Vcldb40;vcldbx40;VclSmp40;Qrpt40 +Conditionals= +DebugSourceDirs= +UsePackages=0 +[Parameters] +RunParams= +HostApplication= +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1031 +CodePage=1252 +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= +[Excluded Packages] +$(DELPHI)\Lib\dclusr40.bpl=Borland User +[HistoryLists\hlUnitAliases] +Count=1 +Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +[HistoryLists\hlOutputDirectorry] +Count=1 +Item0=../ diff --git a/Host/Source/MicroBoot.dpr b/Host/Source/MicroBoot.dpr new file mode 100644 index 00000000..dc5a1876 --- /dev/null +++ b/Host/Source/MicroBoot.dpr @@ -0,0 +1,55 @@ +program MicroBoot; +//*************************************************************************************** +// Project Name: MicroBoot for Borland Delphi +// Description: Contains the main program entry +// File Name: MicroBoot.dpr +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** + +uses + Forms, + MainUnit in 'MainUnit.pas' {mainForm}, + SettingsUnit in 'SettingsUnit.pas' {settingsForm}, + StopWatch in 'StopWatch.pas'; + +{$R *.RES} + +begin + Application.Initialize; + Application.Title := 'MicroBoot'; + Application.CreateForm(TmainForm, mainForm); + Application.CreateForm(TsettingsForm, settingsForm); + Application.Run; +end. +//******************************** end of MicroBoot.dpr ********************************* + diff --git a/Host/Source/MicroBoot.ico b/Host/Source/MicroBoot.ico new file mode 100644 index 00000000..3846b392 Binary files /dev/null and b/Host/Source/MicroBoot.ico differ diff --git a/Host/Source/SettingsUnit.dfm b/Host/Source/SettingsUnit.dfm new file mode 100644 index 00000000..4e0f9173 Binary files /dev/null and b/Host/Source/SettingsUnit.dfm differ diff --git a/Host/Source/SettingsUnit.pas b/Host/Source/SettingsUnit.pas new file mode 100644 index 00000000..791c64ae --- /dev/null +++ b/Host/Source/SettingsUnit.pas @@ -0,0 +1,229 @@ +unit SettingsUnit; +//*************************************************************************************** +// Project Name: MicroBoot for Borland Delphi +// Description: Contains the Settings Window for MicroBoot +// File Name: SettingsUnit.pas +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +interface + + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, ExtCtrls; + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +type + TsettingsForm = class(TForm) + btnOk: TButton; + pnlFooter: TPanel; + grbTargetInterface: TGroupBox; + cbbInterfaces: TComboBox; + btnOptions: TButton; + procedure btnOkClick(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure btnOptionsClick(Sender: TObject); + procedure cbbInterfacesChange(Sender: TObject); + private + { Private declarations } + libFileNameList : TStrings; + libFileInfoList : TStrings; + ExePath : string; + public + { Public declarations } + end; + +//*************************************************************************************** +// Global Variables +//*************************************************************************************** +var + settingsForm: TsettingsForm; + +implementation + +//*************************************************************************************** +// Local Includes +//*************************************************************************************** +uses MainUnit; + +{$R *.DFM} + + +//*************************************************************************************** +// NAME: btnOkClick +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Closes the dialog and sends a positive response back to the +// application. +// +//*************************************************************************************** +procedure TsettingsForm.btnOkClick(Sender: TObject); +begin + ModalResult := mrOK; +end; //*** end of btnOkClick *** + + +//*************************************************************************************** +// NAME: FormCreate +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Constructs the form an creates instances of the objects we intend to +// use. +// +//*************************************************************************************** +procedure TsettingsForm.FormCreate(Sender: TObject); +begin + // instanciate string lists + libFileNameList := TStringList.Create; + libFileInfoList := TStringList.Create; + + ExePath := ExtractFilePath(Application.ExeName); + +end; //*** end of FormCreate *** + + +//*************************************************************************************** +// NAME: FormDestroy +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Destroys the form an frees instances of the objects we used. +// +//*************************************************************************************** +procedure TsettingsForm.FormDestroy(Sender: TObject); +begin + libFileNameList.Free; + libFileInfoList.Free; +end; //*** end of FormDestroy *** + + +//*************************************************************************************** +// NAME: FormShow +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Obtains list with interface libraries and adds each one of these +// to the combobox with a description so it's easy for users to select +// one. +// +//*************************************************************************************** +procedure TsettingsForm.FormShow(Sender: TObject); +var + cnt : integer; + activeLib : string; +begin + // clear string lists before using them + libFileNameList.Clear; + libFileInfoList.Clear; + cbbInterfaces.Items.Clear; + + // obtian list with available Mbi interface DLL's that are found in the EXE path + mainForm.GetInterfaceFileList(libFileNameList); + + activeLib := ExtractFileName(mainForm.GetActiveMbi); + + for cnt := 0 to libFileNameList.Count-1 do + begin + cbbInterfaces.Items.Add(mainForm.GetMbiInfoString(ExePath + + libFileNameList[cnt])); + + //select the active one + if libFileNameList[cnt] = activeLib then + begin + cbbInterfaces.ItemIndex := cnt; + end; + end; +end; //*** end of FormShow *** + + +//*************************************************************************************** +// NAME: btnOptionsClick +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Submits a request to the interface library to display extra +// configuration options. +// +//*************************************************************************************** +procedure TsettingsForm.btnOptionsClick(Sender: TObject); +var + cnt : integer; + activeLib : string; +begin + // submit configuration request to interface library + mainForm.ConfigureMbi; + + // clear string lists before using them + libFileNameList.Clear; + libFileInfoList.Clear; + cbbInterfaces.Items.Clear; + + // obtian list with available Mbi interface DLL's that are found in the EXE path + mainForm.GetInterfaceFileList(libFileNameList); + + activeLib := ExtractFileName(mainForm.GetActiveMbi); + + for cnt := 0 to libFileNameList.Count-1 do + begin + cbbInterfaces.Items.Add(mainForm.GetMbiInfoString(ExePath + + libFileNameList[cnt])); + + //select the active one + if libFileNameList[cnt] = activeLib then + begin + cbbInterfaces.ItemIndex := cnt; + end; + end; +end; //*** end of btnOptionsClick *** + + +//*************************************************************************************** +// NAME: cbbInterfacesChange +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Updates the interface library that is linked to the application. +// +//*************************************************************************************** +procedure TsettingsForm.cbbInterfacesChange(Sender: TObject); +begin + // enable the selected mbi interface + mainForm.SetActiveMbi(ExePath + libFileNameList[cbbInterfaces.ItemIndex]); +end; //*** end of cbbInterfacesChange *** + +end. +//******************************** end of SettingsUnit.pas ****************************** + diff --git a/Host/Source/StopWatch.pas b/Host/Source/StopWatch.pas new file mode 100644 index 00000000..11a9fbf4 --- /dev/null +++ b/Host/Source/StopWatch.pas @@ -0,0 +1,143 @@ +unit StopWatch; +//*************************************************************************************** +// Description: StopWatch timer for counting minutes and seconds +// File Name: StopWatch.pas +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** +interface + + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, Messages, SysUtils, Classes, ExtCtrls; + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +type + TStopWatch = class(TObject) + private + FStartTime : TDateTime; + FRunning : boolean; + public + constructor Create; + procedure Start; + procedure Stop; + function Interval : string; + end; + + +implementation +//*************************************************************************************** +// NAME: Create +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class constructor +// +//*************************************************************************************** +constructor TStopWatch.Create; +begin + // call inherited constructor + inherited Create; + + // initialize variables + FRunning := false; +end; //*** end of Create *** + + +//*************************************************************************************** +// NAME: Start +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Starts the stopwatch timer +// +//*************************************************************************************** +procedure TStopWatch.Start; +begin + // store the start time + FStartTime := Time; + + // start the stopwatch + FRunning := true; +end; //*** end of Start *** + + +//*************************************************************************************** +// NAME: Stop +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Stops the stopwatch timer +// +//*************************************************************************************** +procedure TStopWatch.Stop; +begin + // stop the stopwatch + FRunning := false; +end; //*** end of Stop *** + + +//*************************************************************************************** +// NAME: Interval +// PARAMETER: none +// RETURN VALUE: stopwatch time as string in format [min]:[sec]. +// DESCRIPTION: Obtains the stopwatch time as a formatted string. +// +//*************************************************************************************** +function TStopWatch.Interval : string; +var + hr : word; + min : word; + sec : word; + ms : word; +begin + // decode the elased stopwatch time + DecodeTime(Time-FStartTime, hr, min, sec, ms); + + // check if stopwatch is running + if not FRunning then + begin + min := 0; + sec := 0; + end; + + // update the formatted stopwatch time string + result := Format('%2.2d:%2.2d', [min, sec]); +end; //*** end of Interval *** + + +end. +//******************************** end of StopWatch.pas ********************************* + diff --git a/Host/Source/interfaces/SRecReader.pas b/Host/Source/interfaces/SRecReader.pas new file mode 100644 index 00000000..66ed33d0 --- /dev/null +++ b/Host/Source/interfaces/SRecReader.pas @@ -0,0 +1,649 @@ +unit SRecReader; +//*************************************************************************************** +// Project Name: Motorola S-Record Reader +// Description: Class used to read S-Record files. Supports both S19 and S28 records. +// File Name: SRecReader.pas +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** +interface + + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, Messages, SysUtils, Classes, Forms; + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +type + PByte = ^Byte; + TSRecLineType = (ltInvalid, ltS0, ltS1, ltS2, ltS3, ltS7, ltS8, ltS9); + TSRecType = (tpS1, tpS2, tpS3, tpMixed); + +type + TSRecData = record + val : Byte; + addr : LongWord; + end; + +type + PRegion = ^TRegion; + TRegion = record + addr : LongWord; + size : LongWord; + end; + +type + TSRecReader = class(TObject) + private + FFileName : String; + FDataSize : Longword; + FFirstAddr : LongWord; + FLastAddr : LongWord; + FFileType : TSRecType; + FRegions : TList; + FRegionsCnt : Word; + function GetLineType(line: String) : TSRecLineType; + function GetLineSize(line: String; var size: Word) : Boolean; + function GetLineData(line: String; index: Word; var data: TSRecData) : Boolean; + function GetLineAddress(line: String; var address: LongWord) : Boolean; + procedure UpdateRegions(addr: LongWord; size: Word); + public + constructor Create; + destructor Destroy; override; + function SetFileName(fileName : String) : Boolean; + function GetFileName : String; + function GetDataSize : Longword; + function GetFirstAddress : Longword; + function GetLastAddress : Longword; + function GetRegionCount : Word; + procedure GetRegion(index : Word; var addr : Longword; var length : Longword); + procedure GetData(var buffer : array of Byte; addr : Longword; length : Longword); + function GetFileType : TSRecType; + function BlankCheck(addr : Longword; length : Longword) : Boolean; + end; + + +implementation + +//*************************************************************************************** +// NAME: Create +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class constructore +// +//*************************************************************************************** +constructor TSRecReader.Create; +begin + inherited Create; + FRegions := TList.Create; +end; //*** end of Create *** + + +//*************************************************************************************** +// NAME: Destroy +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class destructor +// +//*************************************************************************************** +destructor TSRecReader.Destroy; +var + index : Word; + region: PRegion; +begin + if FRegions.Count > 0 then + begin + for index := 0 to FRegions.Count-1 do + begin + region := FRegions.Items[index]; + Dispose(region); + end; + end; + + FRegions.Free; + inherited; +end; //*** end of Destroy *** + + +//*************************************************************************************** +// NAME: UpdateRegions +// PARAMETER: addr: start address of data +// size: length of data +// RETURN VALUE: none +// DESCRIPTION: Processes the data by categorizing it into a region. +// +//*************************************************************************************** +procedure TSRecReader.UpdateRegions(addr: LongWord; size: Word); +var + index : Word; + added : Boolean; + region: PRegion; +begin + added := False; + + if FRegions.Count > 0 then + begin + // loop through all existing regions + for index := 0 to FRegions.Count-1 do + begin + // set pointer to this region + region := FRegions.Items[index]; + + // does data fit at the end? + if (region^.addr+region^.size) = addr then + begin + // add at the end of this region + region^.size := region^.size + size; + added := True; + end + // does data fit at the start? + else if region^.addr = (addr+size) then + begin + // add at the start of this region + region^.addr := region^.addr - size; + added := True; + end; + + // was data added to a region? + if added then + begin + Break; // no need to continue loop + end; + end; + end; + + // data couldn't be added to an existing region? + if not added then + begin + // create a new region and add the data there + New(region); + region^.addr := addr; + region^.size := size; + FRegions.Add(region); + end; +end; //*** end of UpdateRegions *** + + +//*************************************************************************************** +// NAME: GetLineType +// PARAMETER: Line from S-Record +// RETURN VALUE: line type +// DESCRIPTION: Determines what type of S-Record line we're dealing with. +// +//*************************************************************************************** +function TSRecReader.GetLineType(line: String) : TSRecLineType; +begin + Result := ltInvalid; + + if Pos('S0', UpperCase(line)) > 0 then Result := ltS0; + if Pos('S1', UpperCase(line)) > 0 then Result := ltS1; + if Pos('S2', UpperCase(line)) > 0 then Result := ltS2; + if Pos('S3', UpperCase(line)) > 0 then Result := ltS3; + if Pos('S7', UpperCase(line)) > 0 then Result := ltS7; + if Pos('S8', UpperCase(line)) > 0 then Result := ltS8; + if Pos('S9', UpperCase(line)) > 0 then Result := ltS9; +end; //*** end of GetLineType *** + + +//*************************************************************************************** +// NAME: GetLineSize +// PARAMETER: Line from S-Record +// RETURN VALUE: Number of data bytes +// DESCRIPTION: Obtains the number of databytes in the specified S-Record line. +// +//*************************************************************************************** +function TSRecReader.GetLineSize(line: String; var size: Word) : Boolean; +var + unusedBytes : Byte; +begin + Result := false; // init + + if GetLineType(line) = ltS1 then + unusedBytes := 3 // 2 for address and 1 for checksum + else if GetLineType(line) = ltS2 then + unusedBytes := 4 // 3 for address and 1 for checksum + else if GetLineType(line) = ltS3 then + unusedBytes := 5 // 4 for address and 1 for checksum + else + Exit; // not a S1 or S2 line + + size := StrToInt('$' + Copy(line, 3, 2)) - unusedBytes; + Result := true; +end; //*** end of GetLineSize *** + + +//*************************************************************************************** +// NAME: GetLineData +// PARAMETER: Line from S-Record +// RETURN VALUE: data at a specific index (starts at 0) +// DESCRIPTION: Obtains the data at a specific index in the specified S-Record line. +// +//*************************************************************************************** +function TSRecReader.GetLineData(line: String; index: Word; var data: TSRecData) : Boolean; +var + dataOffset : Byte; + lineSize : Word; + lineAddr : LongWord; +begin + Result := false; // init + + if GetLineType(line) = ltS1 then + dataOffset := 9 // characters untill we reach actual data + else if GetLineType(line) = ltS2 then + dataOffset := 11 // characters untill we reach actual data + else if GetLineType(line) = ltS3 then + dataOffset := 13 // characters untill we reach actual data + else + Exit; // not a S1, S2 or S3 line + + // make sure index parameter is valid + if not GetLineSize(line, lineSize) then + Exit + else + if index > (lineSize-1) then Exit; + + // obtain the start address of the line + if not GetLineAddress(line, lineAddr) then + Exit; + + data.val := StrToInt('$' + Copy(line, dataOffset+(index*2), 2)); + data.addr := lineAddr + index; + + Result := true; +end; //*** end of GetLineData *** + + +//*************************************************************************************** +// NAME: GetLineAddress +// PARAMETER: Line from S-Record +// RETURN VALUE: Start address +// DESCRIPTION: Obtains the start address as specified in the S-Record line. +// +//*************************************************************************************** +function TSRecReader.GetLineAddress(line: String; var address: LongWord) : Boolean; +var + addrLength : Byte; +begin + Result := false; // init + + if GetLineType(line) = ltS1 then + addrLength := 4 // 2 byte address + else if GetLineType(line) = ltS2 then + addrLength := 6 // 3 byte address + else if GetLineType(line) = ltS3 then + addrLength := 8 // 4 byte address + else + Exit; // not a S1, S2 or S3 line + + address := StrToInt('$' + Copy(line, 5, addrLength)); + Result := true; +end; //*** end of GetLineAddress *** + + +//*************************************************************************************** +// NAME: SetFileName +// PARAMETER: Filename with full path +// RETURN VALUE: True when the S-Record was valid and could be loaded, otherwise False. +// DESCRIPTION: Function verifies that the file is actually a S-Record. If so, then +// the most class properties are set based on the info in the S-Record. +// +//*************************************************************************************** +function TSRecReader.SetFileName(fileName : String) : Boolean; +var + SRecFile : TextFile; + Line : string; + ValidSRec : Boolean; + LineSize : Word; + LineAddr : LongWord; + S1RecFound : Boolean; + S2RecFound : Boolean; + S3RecFound : Boolean; +begin + // first reset all the internal properties + FFileName := ''; + FDataSize := 0; + FFirstAddr := $ffffffff; + FLastAddr := 0; + FFileType := tpS1; + FRegionsCnt := 0; + FRegions.Clear; + + // init locals + S1RecFound := false; + S2RecFound := false; + S3RecFound := false; + Result := false; + ValidSRec := false; + + // 1. Verify if file exists + if not FileExists(fileName) then Exit; + + // 2. Verify if file contains S-Records + AssignFile(SRecFile, fileName); // get file handle + Reset(SRecFile); // go to start of file + while not Eof(SRecFile) do + begin + ReadLn(SRecFile, Line); // read line from file + if (GetLineType(Line) = ltS1) or (GetLineType(Line) = ltS2) or + (GetLineType(Line) = ltS3) then + begin + ValidSRec := true; + Break; // valid S-Record + end; + end; + CloseFile(SRecFile); // release file + if not ValidSRec then Exit; + + // 3. Calculate datasize, first address and last address + AssignFile(SRecFile, fileName); // get file handle + Reset(SRecFile); // go to start of file + while not Eof(SRecFile) do + begin + ReadLn(SRecFile, Line); // read line from file + LineSize := 0; // init + if GetLineSize(Line, LineSize) then + FDataSize := FDataSize + LineSize; // add to previous value + + if GetLineAddress(Line, LineAddr) then + begin + if LineAddr < FFirstAddr then + FFirstAddr := LineAddr; + + if LineAddr > FLastAddr then + FLastAddr := LineAddr + LineSize -1; + end; + + // check line type + if GetLineType(line) = ltS1 then + S1RecFound := true; + if GetLineType(line) = ltS2 then + S2RecFound := true; + if GetLineType(line) = ltS3 then + S3RecFound := true; + + end; + CloseFile(SRecFile); // release file + + // set file type + if (S1RecFound) and (not S2RecFound) and (not S3RecFound) then + FFileType := tpS1 + else if (S2RecFound) and (not S1RecFound) and (not S3RecFound) then + FFileType := tpS2 + else if (not S2RecFound) and (not S1RecFound) and (S3RecFound) then + FFileType := tpS3 + else + FFileType := tpMixed; + + // 4. Determine regions + AssignFile(SRecFile, fileName); // get file handle + Reset(SRecFile); // go to start of file + while not Eof(SRecFile) do + begin + ReadLn(SRecFile, Line); // read line from file + LineSize := 0; // init + + if GetLineAddress(Line, LineAddr) then + begin + if GetLineSize(Line, LineSize) then + begin + UpdateRegions(LineAddr, LineSize); + end; + end; + end; + CloseFile(SRecFile); // release file + + // set region count + FRegionsCnt := FRegions.Count; + + // 5. Verify properties and if ok, set the FFilename property + if (FDataSize <> 0) and (FFirstAddr <> $ffffffff) and (FLastAddr <> 0) then + begin + FFileName := fileName; // set the filename property + Result := true; + end; +end; //*** end of SetFileName *** + + +//*************************************************************************************** +// NAME: GetFileName +// PARAMETER: none +// RETURN VALUE: Filename with full path or '' when invalid. +// DESCRIPTION: S-Record filename that is configured to be read be this class. +// +//*************************************************************************************** +function TSRecReader.GetFileName : String; +begin + Result := FFileName; +end; //*** end of GetFileName *** + + +//*************************************************************************************** +// NAME: GetDataSize +// PARAMETER: none +// RETURN VALUE: Size of data. +// DESCRIPTION: Obtains the number of databytes in the S-Record. 0xFF values are +// not included. +// +//*************************************************************************************** +function TSRecReader.GetDataSize : Longword; +begin + Result := FDataSize; +end; //*** end of GetDataSize *** + + +//*************************************************************************************** +// NAME: GetFirstAddress +// PARAMETER: none +// RETURN VALUE: First address in S-Record. +// DESCRIPTION: Obtains the first memory address with data in the S-Record. +// +//*************************************************************************************** +function TSRecReader.GetFirstAddress : Longword; +begin + Result := FFirstAddr; +end; //*** end of GetFirstAddress *** + + +//*************************************************************************************** +// NAME: GetLastAddress +// PARAMETER: none +// RETURN VALUE: Last address in S-Record. +// DESCRIPTION: Obtains the last memory address with data in the S-Record. +// +//*************************************************************************************** +function TSRecReader.GetLastAddress : Longword; +begin + Result := FLastAddr; +end; //*** end of GetLastAddress *** + + +//*************************************************************************************** +// NAME: GetRegionCount +// PARAMETER: none +// RETURN VALUE: Number of address regions +// DESCRIPTION: Obtains the number of address regions found in the S-record. +// +//*************************************************************************************** +function TSRecReader.GetRegionCount : Word; +begin + Result := FRegionsCnt; +end; //*** end of GetRegionCount *** + + +//*************************************************************************************** +// NAME: GetRegion +// PARAMETER: index: region index to retrieve info from +// addr: destination for region's start address +// length: destination for region's length +// RETURN VALUE: none +// DESCRIPTION: Obtains the address region info. +// +//*************************************************************************************** +procedure TSRecReader.GetRegion(index : Word; var addr : Longword; var length : Longword); +var + region: PRegion; +begin + // initialize return values + addr := 0; + length := 0; + + if FRegions.Count > 0 then + begin + if index < FRegions.Count then + begin + // set pointer to this region + region := FRegions.Items[index]; + + // obtain region info + addr := region^.addr; + length := region^.size; + end; + end; +end; //*** end of GetRegion *** + + +//*************************************************************************************** +// NAME: GetData +// PARAMETER: buffer is a pointer to a byte buffer where the data will be written +// to from memory address addr to addr+length. +// RETURN VALUE: none +// DESCRIPTION: Obtains the data in the S-Record for a memory block that starts at +// addr and goes until addr+length and stores the data in buffer. empty +// data will be filled with 0xFF. +// +//*************************************************************************************** +procedure TSRecReader.GetData(var buffer : array of Byte; addr : Longword; length : Longword); +var + data : TSRecData; + line : string; + lineAddr : LongWord; + lineSize : Word; + SRecFile : TextFile; + cnt : Word; + ok2Continue : boolean; +begin + // check parameters + if length = 0 then Exit; + + // first init entire buffer to 0xff + for cnt := 0 to length-1 do + begin + buffer[cnt] := $ff; + end; + + // go through each line to see if it has data for us + AssignFile(SRecFile, FFileName); // get file handle + Reset(SRecFile); // go to start of file + while not Eof(SRecFile) do + begin + // this can take a while so process messages to not stall the parent app + Application.ProcessMessages; + + ReadLn(SRecFile, line); // read line from file + ok2Continue := true; // init + + // obtain line properties + if not GetLineAddress(line, lineAddr) then ok2Continue := false; + if not GetLineSize(line, lineSize) then ok2Continue := false; + + if ok2Continue then + begin + // process all data on the line + for cnt := 0 to lineSize-1 do + begin + // read data info + if not GetLineData(line, cnt, data) then ok2Continue := false; + if ok2Continue then + begin + // is this one for us? + if (data.addr >= addr) and (data.addr <= (addr+length-1)) then + begin + // store it in the memory buffer + buffer[data.addr-addr] := data.val; + end; + end; + end; + end; + + end; + CloseFile(SRecFile); // release file +end; //*** end of GetData *** + + +//*************************************************************************************** +// NAME: GetFileType +// PARAMETER: none +// RETURN VALUE: S-Record file type +// DESCRIPTION: Determines is the file contains just S1 data lines, just S2 data +// lines. or a combination of these two. +// +//*************************************************************************************** +function TSRecReader.GetFileType : TSRecType; +begin + Result := FFileType; +end; //*** end of GetFileType *** + + +//*************************************************************************************** +// NAME: BlankCheck +// PARAMETER: checks from addr to addr+length-1. +// RETURN VALUE: true if all bytes are 0xff, false otherwise +// DESCRIPTION: Checks if a memory range in the S-Record file is empty (0xff) or not. +// +//*************************************************************************************** +function TSRecReader.BlankCheck(addr : Longword; length : Longword) : Boolean; +var + buffer : array of Byte; + cnt : LongWord; +begin + Result := true; + SetLength(buffer, length); // init size of the dynamic array + GetData(buffer, addr, length); // fill it with the data contents from the S-Record + + for cnt := 0 to length-1 do + begin + if buffer[cnt] <> $ff then + begin + Result := false; // memory range is not blank + Break; // no need to continue loop + end; + end; +end; //*** end of BlankCheck *** + +end. +//******************************** end of SRecReader.pas ******************************** + diff --git a/Host/Source/interfaces/XcpDataFile.pas b/Host/Source/interfaces/XcpDataFile.pas new file mode 100644 index 00000000..00ee8fa6 --- /dev/null +++ b/Host/Source/interfaces/XcpDataFile.pas @@ -0,0 +1,219 @@ +unit XcpDataFile; +//*************************************************************************************** +// Description: XCP data file interface. +// File Name: XcpDataFile.pas +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** +interface + + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, Messages, SysUtils, Classes, Forms, SRecReader; + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +type + TXcpDataFile = class(TObject) + private + FDataFileReady : Boolean; + FRegionCount : Word; + FDataFile : TSRecReader; + public + constructor Create(dataFile: string); + destructor Destroy; override; + function GetDataCnt : LongWord; + function GetRegionCnt : Word; + procedure GetRegionInfo(region : Word; var addr : Longword; var len : Longword); + function GetRegionData(region : Word; var data : array of Byte) : LongWord; + end; + + +implementation + +//*************************************************************************************** +// NAME: Create +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class constructor +// +//*************************************************************************************** +constructor TXcpDataFile.Create(dataFile: string); +begin + // call inherited constructor + inherited Create; + + // instantiate S-Record reader object + FDataFile := TSRecReader.Create; + + // reset data file ready flag + FDataFileReady := false; + + // reset the region count + FRegionCount := 0; + + // open the data file as an S-Record file + if FDataFile.SetFileName(dataFile) then + begin + // set data file ready flag + FDataFileReady := true; + + // obtain the number of data regions + FRegionCount := FDataFile.GetRegionCount; + end; +end; //*** end of Create *** + + +//*************************************************************************************** +// NAME: Destroy +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class destructor +// +//*************************************************************************************** +destructor TXcpDataFile.Destroy; +begin + // release S-Record reader object + FDataFile.Free; + + // call inherited destructor + inherited; +end; //*** end of Destroy *** + + +//*************************************************************************************** +// NAME: GetDataCnt +// PARAMETER: none +// RETURN VALUE: number of data bytes +// DESCRIPTION: Returns the number of data bytes in the data file +// +//*************************************************************************************** +function TXcpDataFile.GetDataCnt : LongWord; +begin + // init return value + result := 0; + + // verify data file state + if not FDataFileReady then Exit; + + // return the number of data bytes in the data file + result := FDataFile.GetDataSize; +end; //*** end of GetDataCnt *** + + +//*************************************************************************************** +// NAME: GetRegionCnt +// PARAMETER: none +// RETURN VALUE: number of data regions +// DESCRIPTION: Returns the number of data regions in the data file +// +//*************************************************************************************** +function TXcpDataFile.GetRegionCnt : Word; +begin + // init return value + result := 0; + + // verify data file state + if not FDataFileReady then Exit; + + // return the number of data regions + result := FRegionCount; +end; //*** end of GetRegionCnt *** + + +//*************************************************************************************** +// NAME: GetRegionInfo +// PARAMETER: region index and parameters where to store the region start address +// and length info. +// RETURN VALUE: none +// DESCRIPTION: Returns the number of data bytes in the specified region and its +// start address. +// +//*************************************************************************************** +procedure TXcpDataFile.GetRegionInfo(region : Word; var addr : Longword; var len : Longword); +begin + // init return parameters + addr := 0; + len := 0; + + // verify data file state + if not FDataFileReady then Exit; + + // validate input parameter + if region > FRegionCount-1 then Exit; + + // obtain the region information + FDataFile.GetRegion(region, addr, len); +end; //*** end of GetRegionInfo *** + + +//*************************************************************************************** +// NAME: GetRegionData +// PARAMETER: region index and a pointer to the data buffer where the data will be +// stored. +// RETURN VALUE: Number of data bytes stored in the data buffer +// DESCRIPTION: Reads the data from a specific region into the specified data buffer. +// +//*************************************************************************************** +function TXcpDataFile.GetRegionData(region : Word; var data : array of Byte) : LongWord; +var + addr : LongWord; + len : LongWord; +begin + // init return value + result := 0; + + // verify data file state + if not FDataFileReady then Exit; + + // validate input parameter + if region > FRegionCount-1 then Exit; + + // obtain region info + FDataFile.GetRegion(region, addr, len); + + // obtain the region data + FDataFile.GetData(data, addr, len); + + // return the number of data bytes stored in the data buffer + result := len; +end; //*** end of GetRegionData *** + + +end. +//******************************** end of XcpDataFile.pas ******************************* + diff --git a/Host/Source/interfaces/XcpIcon.bmp b/Host/Source/interfaces/XcpIcon.bmp new file mode 100644 index 00000000..c7923878 Binary files /dev/null and b/Host/Source/interfaces/XcpIcon.bmp differ diff --git a/Host/Source/interfaces/XcpLoader.pas b/Host/Source/interfaces/XcpLoader.pas new file mode 100644 index 00000000..59307b58 --- /dev/null +++ b/Host/Source/interfaces/XcpLoader.pas @@ -0,0 +1,1241 @@ +unit XcpLoader; +//*************************************************************************************** +// Description: XCP Master Communication Protocol Layer for Bootloader. +// File Name: XcpLoader.pas +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** +interface + + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, Messages, SysUtils, Classes, Forms, XcpTransport, XcpProtection, IniFiles; + +//*************************************************************************************** +// Global Constants +//*************************************************************************************** +// XCP command codes +const kCmdCONNECT = $FF; +const kCmdDISCONNECT = $FE; +const kCmdGET_STATUS = $FD; +const kCmdSYNCH = $FC; +const kCmdGET_ID = $FA; +const kCmdGET_SEED = $F8; +const kCmdUNLOCK = $F7; +const kCmdSET_MTA = $F6; +const kCmdUPLOAD = $F5; +const kCmdSHORT_UPLOAD = $F4; +const kCmdBUILD_CHECKSUM = $F3; +const kCmdDOWNLOAD = $F0; +const kCmdDOWNLOAD_MAX = $EE; +const kCmdSET_CAL_PAGE = $EB; +const kCmdGET_CAL_PAGE = $EA; +const kCmdPROGRAM_START = $D2; +const kCmdPROGRAM_CLEAR = $D1; +const kCmdPROGRAM = $D0; +const kCmdPROGRAM_RESET = $CF; +const kCmdPROGRAM_PREPARE = $CC; +const kCmdPROGRAM_MAX = $C9; + +// XCP command response packet IDs +const kCmdPidRES = $FF; // positive response packet +const kCmdPidERR = $FE; // error packet +const kCmdPidEV = $FD; // event packet +const kCmdPidSERV = $FC; // service request packet + +// XCP resources +const kResPGM = $10; // programming resource + +// XCP error codes +const kErrCMD_SYNCH = $00; // Command processor synchronization +const kErrCMD_BUSY = $10; // Command was not executed. +const kErrDAQ_ACTIVE = $11; // Command rejected because DAQ is running. +const kErrPGM_ACTIVE = $12; // Command rejected because PGM is running. +const kErrCMD_UNKNOWN = $20; // Unknown command or not implemented optional command. +const kErrCMD_SYNTAX = $21; // Command syntax invalid +const kErrOUT_OF_RANGE = $22; // Command syntax valid but command parameter(s) out of range. +const kErrWRITE_PROTECTED = $23; // The memory location is write protected. +const kErrACCESS_DENIED = $24; // The memory location is not accessible. +const kErrACCESS_LOCKED = $25; // Access denied, Seed & Key is required +const kErrPAGE_NOT_VALID = $26; // Selected page not available +const kErrMODE_NOT_VALID = $27; // Selected page mode not available +const kErrSEGMENT_NOT_VALID = $28; // Selected segment not valid +const kErrSEQUENCE = $29; // Sequence error +const kErrDAQ_CONFIG = $2A; // DAQ configuration not valid +const kErrMEMORY_OVERFLOW = $30; // Memory overflow error +const kErrGENERIC = $31; // Generic error +const kErrVERIFY = $32; // The slave internal program verify routine detects an error. + +// Feaser error Codes +const kErrFsrExecuteCmd = $80; // Could not execute command +const kErrFsrResourceUnavailable = $81; // Resource needed but not available +const kErrFsrSeedKeyDllInvalid = $82; // Seed/Key DLL is invalid +const kErrFsrKeyAlgoMissing = $83; // Key computation algorithm is missing + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +type + TXcpLoader = class(TObject) + private + FIsConnected : Boolean; + FTimerInterval : array[1..7] of Word; + FIsIntel : Boolean; + FCtoPacketLen : Byte; + FCtoPGMPacketLen : Byte; + FDtoPacketLen : Word; + FSeedKeyDll : string; + FLastError : Byte; + FResources : Byte; + FProtection : Byte; + FMta : LongWord; + procedure WaitT7; + function GetOrderedWord(data : PByteArray) : Word; + procedure SetOrderedLong(value: LongWord; data : PByteArray); + function SendSynchedPacket(timeMs : Word; useMta : Boolean) : Boolean; + function CmdSynch(useMta : Boolean) : Boolean; + function CmdConnect : Boolean; + function CmdDisconnect : Boolean; + function CmdProgramStart : Boolean; + function CmdGetStatus : Boolean; + function CmdGetSeed(seed : PByteArray; resource : Byte; var len : Byte) : Boolean; + function CmdUnlock(key : PByteArray; len : Byte) : Boolean; + function CmdProgramReset : Boolean; + function CmdProgram(data : PByteArray; len : Byte) : Boolean; + function CmdProgramMax(data : PByteArray) : Boolean; + function CmdSetMta(addr : LongWord) : Boolean; + function CmdProgramClear(len : LongWord) : Boolean; + public + comDriver : TXcpTransport; + constructor Create; + destructor Destroy; override; + function GetLastError(var info : string) : Byte; + procedure Configure(iniFile : string); + procedure Connect; + procedure Disconnect; + function StartProgrammingSession : Boolean; + function StopProgrammingSession : Boolean; + function ClearMemory(addr : LongWord; len : LongWord) : Boolean; + function WriteData(addr : LongWord; len : LongWord; data : PByteArray) : Boolean; + end; + + +implementation +//*************************************************************************************** +// NAME: Create +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class constructor +// +//*************************************************************************************** +constructor TXcpLoader.Create; +begin + // call inherited constructor + inherited Create; + + // reset error + FLastError := 0; + + // reset memory transfer address + FMta := 0; + + // not connected upon creation + FIsConnected := false; + + // reset seed/key dll filename + FSeedKeyDll := ''; + + // set communication defaults + FIsIntel := False; // motorola byte order by default + FResources := 0; // no resources available + FProtection := 0; // all resources unprotected by default + + // set XCP packet length defaults + FCtoPacketLen := 8; // must be at least 8 for connect command response + FDtoPacketLen := 8; + FCtoPGMPacketLen := 8; + + // set interval time defaults + FTimerInterval[1] := 1000; // t1 = 1000ms - standard command timeout + FTimerInterval[2] := 2000; // t2 = 2000ms - build checksum timeout + FTimerInterval[3] := 2000; // t3 = 2000ms - program start timeout + FTimerInterval[4] := 10000; // t4 = 10000ms - erase timeout + FTimerInterval[5] := 1000; // t5 = 1000ms - write and reset timeout + FTimerInterval[6] := 1000; // t6 = 1000ms - user specific connect + FTimerInterval[7] := 2000; // t7 = 2000ms - wait timer + + // create instance of XCP transport layer object + comDriver := TXcpTransport.Create; +end; //*** end of Create *** + + +//*************************************************************************************** +// NAME: Destroy +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class destructor +// +//*************************************************************************************** +destructor TXcpLoader.Destroy; +begin + // disconnect the XCP transport layer + comDriver.Disconnect; + + // release XCP transport layer object + comDriver.Free; + + // call inherited destructor + inherited; +end; //*** end of Destroy *** + + +//*************************************************************************************** +// NAME: WaitRoutine +// PARAMETER: number of milliseconds to wait +// RETURN VALUE: none +// DESCRIPTION: Basic routine that waits for the specified amount of time before +// continueing. +// +//*************************************************************************************** +procedure TXcpLoader.WaitT7; +begin + Sleep(FTimerInterval[7]); +end; //*** end of WaitRoutine *** + + +//*************************************************************************************** +// NAME: GetOrderedWord +// PARAMETER: pointer to byte array +// RETURN VALUE: word value +// DESCRIPTION: Returns the word value from the byte array taking into account Intel +// or Motorola byte ordering. +// +//*************************************************************************************** +function TXcpLoader.GetOrderedWord(data : PByteArray) : Word; +begin + result := 0; + + if FIsIntel then + begin + result := result or (data[1] shl 8); + result := result or (data[0]); + end + else + begin + result := result or (data[0] shl 8); + result := result or (data[1]); + end; +end; //*** end of GetOrderedWord *** + + +//*************************************************************************************** +// NAME: SetOrderedLong +// PARAMETER: pointer to byte array and 32-bit value +// RETURN VALUE: none +// DESCRIPTION: Stores a 32-bit value into a byte buffer taking into account Intel +// or Motorola byte ordering. +// +//*************************************************************************************** +procedure TXcpLoader.SetOrderedLong(value: LongWord; data : PByteArray); +begin + if FIsIntel then + begin + data[3] := Byte(value shr 24); + data[2] := Byte(value shr 16); + data[1] := Byte(value shr 8); + data[0] := Byte(value); + end + else + begin + data[0] := Byte(value shr 24); + data[1] := Byte(value shr 16); + data[2] := Byte(value shr 8); + data[3] := Byte(value); + end; +end; //*** end of SetOrderedLong *** + + +//*************************************************************************************** +// NAME: GetLastError +// PARAMETER: destination string from error information +// RETURN VALUE: error code +// DESCRIPTION: Return the last error value. +// +//*************************************************************************************** +function TXcpLoader.GetLastError(var info : string) : Byte; +begin + // set info string + case FLastError of + kErrCMD_SYNCH : info := '0x00 - Command processor synchronization'; + kErrCMD_BUSY : info := '0x10 - Command was not executed'; + kErrDAQ_ACTIVE : info := '0x11 - Command rejected because DAQ is running'; + kErrPGM_ACTIVE : info := '0x12 - Command rejected because PGM is running'; + kErrCMD_UNKNOWN : info := '0x20 - Unknown command or not implemented optional command'; + kErrCMD_SYNTAX : info := '0x21 - Command syntax invalid'; + kErrOUT_OF_RANGE : info := '0x22 - Command syntax valid but command parameter(s) out of range'; + kErrWRITE_PROTECTED : info := '0x23 - The memory location is write protected'; + kErrACCESS_DENIED : info := '0x24 - The memory location is not accessible'; + kErrACCESS_LOCKED : info := '0x25 - Access denied, Seed & Key is required'; + kErrPAGE_NOT_VALID : info := '0x26 - Selected page not available'; + kErrMODE_NOT_VALID : info := '0x27 - Selected page mode not available'; + kErrSEGMENT_NOT_VALID : info := '0x28 - Selected segment not valid'; + kErrSEQUENCE : info := '0x29 - Sequence error'; + kErrDAQ_CONFIG : info := '0x2A - DAQ configuration not valid'; + kErrMEMORY_OVERFLOW : info := '0x30 - Memory overflow error'; + kErrGENERIC : info := '0x31 - Generic error'; + kErrVERIFY : info := '0x32 - The slave internal program verify routine detects an error'; + kErrFsrExecuteCmd : info := '0x80 - Could not execute command'; + kErrFsrResourceUnavailable: info := '0x81 - Resource needed but not available'; + kErrFsrSeedKeyDllInvalid : info := '0x82 - Seed/Key DLL is invalid'; + kErrFsrKeyAlgoMissing : info := '0x83 - Key computation algorithm is missing'; + end; + + // return the error code + result := FLastError; +end; //*** end of GetLastError *** + + +//*************************************************************************************** +// NAME: Configure +// PARAMETER: filename of the INI +// RETURN VALUE: none +// DESCRIPTION: Configures both this class and the transport layer from the settings +// in the INI. +// +//*************************************************************************************** +procedure TXcpLoader.Configure(iniFile : string); +var + settingsIni : TIniFile; + wasConnected : Boolean; +begin + // backup connection state + wasConnected := FIsConnected; + + // disconnect + if FIsConnected then DisConnect; + + // configure comDriver + comDriver.Configure(iniFile); + + // read XCP configuration from INI + if FileExists(iniFile) then + begin + // create ini file object + settingsIni := TIniFile.Create(iniFile); + + FSeedKeyDll := settingsIni.ReadString('xcp', 'seedkey', ExtractFilePath(ParamStr(0))+'FeaserKey.dll'); + + // if no path specified, then assume dll is located in the executable's path + if ExtractFilePath(FSeedKeyDll) = '' then + FSeedKeyDll := ExtractFilePath(ParamStr(0))+FSeedKeyDll; + + FTimerInterval[1] := settingsIni.ReadInteger('xcp', 't1', 1000); + FTimerInterval[3] := settingsIni.ReadInteger('xcp', 't3', 1000); + FTimerInterval[4] := settingsIni.ReadInteger('xcp', 't4', 1000); + FTimerInterval[5] := settingsIni.ReadInteger('xcp', 't5', 1000); + FTimerInterval[7] := settingsIni.ReadInteger('xcp', 't7', 1000); + + // release ini file object + settingsIni.Free; + end; + + // restore connection + if WasConnected then Connect; +end; //*** end of Configure *** + + +//*************************************************************************************** +// NAME: Connect +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Connects the XCP transport layer +// +//*************************************************************************************** +procedure TXcpLoader.Connect; +begin + // connect the XCP transport layer + comDriver.Connect; + FIsConnected := true; +end; //*** end of Connect *** + + +//*************************************************************************************** +// NAME: Disconnect +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Disconnects the XCP transport layer +// +//*************************************************************************************** +procedure TXcpLoader.Disconnect; +begin + // disconnect the XCP transport layer + FIsConnected := false; + comDriver.Disconnect; +end; //*** end of Disconnect *** + + +//*************************************************************************************** +// NAME: SendSynchedPacket +// PARAMETER: timeout time in ms and info if mta should be resend +// RETURN VALUE: True is successful, False otherwise +// DESCRIPTION: Sends out the XCP packet using the "2 Retry with SYNCH" method at +// outlined in the XCP protocol error handling. in case an error +// occurred, a FLastError will be set. If useMta = true then a SET_MTA +// packet will be send right after the SYNCH packet. +// +//*************************************************************************************** +function TXcpLoader.SendSynchedPacket(timeMs : Word; useMta : Boolean) : Boolean; +var + dataCpy : array of Byte; + cnt : Word; +begin + // init return value + Result := false; + + // make a copy of the packet data because the synch command could overwrite it + SetLength(dataCpy, comDriver.packetLen); + for cnt := 0 to comDriver.packetLen-1 do + dataCpy[cnt] := comDriver.packetData[cnt]; + + // send out the command with t1 timeout + if not comDriver.SendPacket(timeMs) then + begin + CmdSynch(useMta); // perform pre-action for 1st retry + + // prepare to send the command packet again + comDriver.packetLen := Length(dataCpy); + for cnt := 0 to comDriver.packetLen-1 do + comDriver.packetData[cnt] := dataCpy[cnt]; + + if not comDriver.SendPacket(timeMs) then + begin + CmdSynch(useMta); // perform pre-action for 2nd and last retry + + // prepare to send the command packet again + comDriver.packetLen := Length(dataCpy); + for cnt := 0 to comDriver.packetLen-1 do + comDriver.packetData[cnt] := dataCpy[cnt]; + + if comDriver.SendPacket(timeMs) then + result := true; // success + end + else + result := true; // success + end + else + result := true; // sucess + + if result = false then + FLastError := kErrFsrExecuteCmd; // Could not execute command +end; //*** end of SendSynchedPacket *** + + +//*************************************************************************************** +// NAME: CmdSynch +// PARAMETER: useMta is a SET_MTA should be included +// RETURN VALUE: True is successful, False otherwise +// DESCRIPTION: Sends out the synchronise command +// +//*************************************************************************************** +function TXcpLoader.CmdSynch(useMta : Boolean) : Boolean; +begin + // init return value + Result := false; + + // prepare the command packet + comDriver.packetData[0] := kCmdSYNCH; + comDriver.packetLen := 1; + + // send out the command with t1 timeout + if not comDriver.SendPacket(FTimerInterval[1]) then + begin + Exit; + end; + + // is response an error packet as expected? + if comDriver.packetData[0] = kCmdPidERR then + begin + // is it the expected processor synchronization error? + if comDriver.packetData[1] = kErrCMD_SYNCH then + begin + result := true; + end; + end; + + // should MTA be resend aswell? + if (useMta = true) and (result = true) then + begin + // prepare the command packet + comDriver.packetData[0] := kCmdSET_MTA; + comDriver.packetData[1] := 0; // reserved + comDriver.packetData[2] := 0; // reserved + comDriver.packetData[3] := 0; // address extension not supported + + // set address taking into account byte ordering + SetOrderedLong(FMta, @comDriver.packetData[4]); + + comDriver.packetLen := 8; + + // send packet with SYNCH retry feature + if not SendSynchedPacket(FTimerInterval[1], false) then + begin + result := false; + Exit; + end; + end; +end; //*** end of CmdSynch *** + + +//*************************************************************************************** +// NAME: CmdConnect +// PARAMETER: none +// RETURN VALUE: True is successful, False otherwise +// DESCRIPTION: Connects the XCP slave to start the XCP session +// +//*************************************************************************************** +function TXcpLoader.CmdConnect : Boolean; +begin + // init return value + Result := false; + + // prepare the connect command packet + comDriver.packetData[0] := kCmdCONNECT; + comDriver.packetData[1] := 0; // normal mode + comDriver.packetLen := 2; + + // send out the command with 20ms timeout. note that this timeout is not required at + // all by the XCP protocol. here it is set quite short to accomodate the OpenBTL + // bootloader default backdoor entry feature + if comDriver.SendPacket(20) then + begin + // check to see if it was an error packet + if comDriver.packetData[0] = kCmdPidERR then + begin + // store error and stop + FLastError := comDriver.packetData[1]; + Exit; + end; + + // store byte order configuration + if (comDriver.packetData[2] and $01) = $00 then FIsIntel := true; + + // store available resources + FResources := comDriver.packetData[1]; + + // store cto packet length + FCtoPacketLen := comDriver.packetData[3]; + FCtoPGMPacketLen := FCtoPacketLen; + + // store dto packet length + FDtoPacketLen := GetOrderedWord(@comDriver.packetData[4]); + + // success + result := true; + end + else + begin + FLastError := kErrFsrExecuteCmd; // Could not execute command; + end; +end; //*** end of CmdConnect *** + + +//*************************************************************************************** +// NAME: CmdDisconnect +// PARAMETER: none +// RETURN VALUE: True is successful, False otherwise +// DESCRIPTION: Disconnects the XCP slave to end the XCP session +// +//*************************************************************************************** +function TXcpLoader.CmdDisconnect : Boolean; +begin + // init return value + Result := false; + + // prepare the disconnect command packet + comDriver.packetData[0] := kCmdDISCONNECT; + comDriver.packetLen := 1; + + // send packet with SYNCH retry feature + if not SendSynchedPacket(FTimerInterval[1], false) then Exit; + + // was the response an error packet? + if comDriver.packetData[0] = kCmdPidERR then + begin + // busy or programming active error received? + if (comDriver.packetData[1] = kErrCMD_BUSY) or + (comDriver.packetData[1] = kErrPGM_ACTIVE) then + begin + WaitT7; // wait the predescribed time + result := CmdDisconnect; // repeat this command + Exit; + end + else + begin + FLastError := comDriver.packetData[1]; // Store error info + Exit; + end; + end; + + // no error so it must have been a positive response + result := true; +end; //*** end of CmdDisconnect *** + + +//*************************************************************************************** +// NAME: CmdProgramStart +// PARAMETER: none +// RETURN VALUE: True is successful, False otherwise +// DESCRIPTION: Informs the slave that programming of non volatile memory starts. +// +//*************************************************************************************** +function TXcpLoader.CmdProgramStart : Boolean; +begin + // init return value + Result := false; + + // prepare the command packet + comDriver.packetData[0] := kCmdPROGRAM_START; + comDriver.packetLen := 1; + + // send packet with SYNCH retry feature + if not SendSynchedPacket(FTimerInterval[3], false) then Exit; + + // was the response an error packet? + if comDriver.packetData[0] = kCmdPidERR then + begin + // busy or programming active error received? + if comDriver.packetData[1] = kErrCMD_BUSY then + begin + WaitT7; // wait the predescribed time + result := CmdProgramStart; // repeat this command + Exit; + end + else + begin + FLastError := comDriver.packetData[1]; // Store error info + Exit; + end; + end; + + // no error so it must have been a positive response + result := true; + + // update max cto packet length in programming mode if supported + if comDriver.packetData[3] <> 0 then + FCtoPGMPacketLen := comDriver.packetData[3]; +end; //*** end of CmdProgramStart *** + + +//*************************************************************************************** +// NAME: CmdGetStatus +// PARAMETER: none +// RETURN VALUE: True is successful, False otherwise +// DESCRIPTION: Obtains the resource protection info from the XCP slave +// +//*************************************************************************************** +function TXcpLoader.CmdGetStatus : Boolean; +begin + // init return value + result := false; + + // prepare the get status command packet + comDriver.packetData[0] := kCmdGET_STATUS; + comDriver.packetLen := 1; + + // send packet with SYNCH retry feature + if not SendSynchedPacket(FTimerInterval[1], false) then Exit; + + // was the response an error packet? + if comDriver.packetData[0] = kCmdPidERR then + begin + FLastError := comDriver.packetData[1]; // Store error info + Exit; + end; + + // no error so it must have been a positive response + result := true; + + // store protection info + FProtection := comDriver.packetData[2]; +end; //*** end of CmdGetStatus *** + + +//*************************************************************************************** +// NAME: CmdGetSeed +// PARAMETER: seed destination buffer and the resource +// RETURN VALUE: True is successful, False otherwise +// DESCRIPTION: Obtains the seed from the specified resource +// +//*************************************************************************************** +function TXcpLoader.CmdGetSeed(seed : PByteArray; resource : Byte; var len : Byte) : Boolean; +var + cnt : byte; +begin + // init return value + result := false; + + // prepare the get seed command packet + comDriver.packetData[0] := kCmdGET_SEED; + comDriver.packetData[1] := 0; // seeds of up to six bytes are supported + comDriver.packetData[2] := resource; + comDriver.packetLen := 3; + + // send packet with SYNCH retry feature + if not SendSynchedPacket(FTimerInterval[1], false) then Exit; + + // was the response an error packet? + if comDriver.packetData[0] = kCmdPidERR then + begin + // busy or programming active error received? + if (comDriver.packetData[1] = kErrCMD_BUSY) or + (comDriver.packetData[1] = kErrPGM_ACTIVE) then + begin + WaitT7; // wait the predescribed time + result := CmdGetSeed(seed, resource, len); // repeat this command + Exit; + end + else + begin + FLastError := comDriver.packetData[1]; // Store error info + Exit; + end; + end; + + // no error so it must have been a positive response + result := true; + + // now store the seed info + len := comDriver.packetData[1]; + for cnt := 0 to len-1 do + seed[cnt] := comDriver.packetData[cnt+2]; +end; //*** end of CmdGetSeed *** + + +//*************************************************************************************** +// NAME: CmdUnlock +// PARAMETER: key source buffer and key length +// RETURN VALUE: True is successful, False otherwise +// DESCRIPTION: Unlocks the resource by sending the key +// +//*************************************************************************************** +function TXcpLoader.CmdUnlock(key : PByteArray; len : Byte) : Boolean; +var + cnt : byte; +begin + // init return value + result := false; + + // prepare the command packet + comDriver.packetData[0] := kCmdUNLOCK; + comDriver.packetData[1] := len; // key length + for cnt := 0 to len-1 do + comDriver.packetData[cnt+2] := key[cnt]; + comDriver.packetLen := len + 2; + + // send packet with SYNCH retry feature + if not SendSynchedPacket(FTimerInterval[1], false) then Exit; + + // was the response an error packet? + if comDriver.packetData[0] = kCmdPidERR then + begin + // busy or programming active error received? + if (comDriver.packetData[1] = kErrCMD_BUSY) or + (comDriver.packetData[1] = kErrPGM_ACTIVE) then + begin + WaitT7; // wait the predescribed time + result := CmdUnlock(key, len); // repeat this command + Exit; + end + else + begin + FLastError := comDriver.packetData[1]; // Store error info + Exit; + end; + end; + + // no error so it must have been a positive response + result := true; + + // store the new resource protection mask + FProtection := comDriver.packetData[1]; +end; //*** end of CmdUnlock *** + + +//*************************************************************************************** +// NAME: CmdProgramReset +// PARAMETER: none +// RETURN VALUE: True is successful, False otherwise +// DESCRIPTION: Requests the ECU to perform a reset. +// +//*************************************************************************************** +function TXcpLoader.CmdProgramReset : Boolean; +begin + // init return value + result := false; + + // prepare the command packet + comDriver.packetData[0] := kCmdPROGRAM_RESET; + comDriver.packetLen := 1; + + // send packet without SYNCH retry feature. ignore negative return value because this + // command does not require a response + if not comDriver.SendPacket(FTimerInterval[5]) then + begin + result := true; // ok to not have a response + Exit; // no response to process to stop here + end; + + // was the response an error packet? + if comDriver.packetData[0] = kCmdPidERR then + begin + // busy or programming active error received? + if (comDriver.packetData[1] = kErrCMD_BUSY) or + (comDriver.packetData[1] = kErrPGM_ACTIVE) then + begin + WaitT7; // wait the predescribed time + result := CmdProgramReset; // repeat this command + Exit; + end + else + begin + FLastError := comDriver.packetData[1]; // Store error info + Exit; + end; + end; + + // no error so it must have been a positive response + result := true; +end; //*** end of CmdProgramReset *** + + +//*************************************************************************************** +// NAME: CmdProgram +// PARAMETER: data source buffer and data length +// RETURN VALUE: True is successful, False otherwise +// DESCRIPTION: Programs the data into non-volatile memory +// +//*************************************************************************************** +function TXcpLoader.CmdProgram(data : PByteArray; len : Byte) : Boolean; +var + cnt : byte; +begin + // init return value + result := false; + + // prepare the command packet + comDriver.packetData[0] := kCmdPROGRAM; + comDriver.packetData[1] := len; // key length + + if len > 0 then + begin + for cnt := 0 to len-1 do + comDriver.packetData[cnt+2] := data[cnt]; + end; + comDriver.packetLen := len + 2; + + // send packet with SYNCH retry feature + if not SendSynchedPacket(FTimerInterval[5], true) then Exit; + + // was the response an error packet? + if comDriver.packetData[0] = kCmdPidERR then + begin + // busy or programming active error received? + if (comDriver.packetData[1] = kErrCMD_BUSY) then + begin + WaitT7; // wait the predescribed time + result := CmdProgram(data, len); // repeat this command + Exit; + end + else + begin + FLastError := comDriver.packetData[1]; // Store error info + Exit; + end; + end; + + // no error so it must have been a positive response + result := true; +end; //*** end of CmdProgram *** + + +//*************************************************************************************** +// NAME: CmdProgramMax +// PARAMETER: data source buffer +// RETURN VALUE: True is successful, False otherwise +// DESCRIPTION: Programs the data into non-volatile memory +// +//*************************************************************************************** +function TXcpLoader.CmdProgramMax(data : PByteArray) : Boolean; +var + cnt : byte; +begin + // init return value + result := false; + + // prepare the command packet + comDriver.packetData[0] := kCmdPROGRAM_MAX; + for cnt := 0 to FCtoPGMPacketLen-2 do + comDriver.packetData[cnt+1] := data[cnt]; + comDriver.packetLen := FCtoPGMPacketLen; + + // send packet with SYNCH retry feature + if not SendSynchedPacket(FTimerInterval[5], true) then Exit; + + // was the response an error packet? + if comDriver.packetData[0] = kCmdPidERR then + begin + // busy or programming active error received? + if (comDriver.packetData[1] = kErrCMD_BUSY) then + begin + WaitT7; // wait the predescribed time + result := CmdProgramMax(data); // repeat this command + Exit; + end + else + begin + FLastError := comDriver.packetData[1]; // Store error info + Exit; + end; + end; + + // no error so it must have been a positive response + result := true; +end; //*** end of CmdProgramMax *** + + +//*************************************************************************************** +// NAME: CmdSetMta +// PARAMETER: 32-bit address +// RETURN VALUE: True is successful, False otherwise +// DESCRIPTION: Sets the memory transfer address +// +//*************************************************************************************** +function TXcpLoader.CmdSetMta(addr : LongWord) : Boolean; +begin + // init return value + result := false; + + // prepare the command packet + comDriver.packetData[0] := kCmdSET_MTA; + comDriver.packetData[1] := 0; // reserved + comDriver.packetData[2] := 0; // reserved + comDriver.packetData[3] := 0; // address extension not supported + + // set address taking into account byte ordering + SetOrderedLong(addr, @comDriver.packetData[4]); + + comDriver.packetLen := 8; + + // send packet with SYNCH retry feature + if not SendSynchedPacket(FTimerInterval[1], false) then Exit; + + // was the response an error packet? + if comDriver.packetData[0] = kCmdPidERR then + begin + // busy or programming active error received? + if (comDriver.packetData[1] = kErrCMD_BUSY) or + (comDriver.packetData[1] = kErrPGM_ACTIVE) then + begin + WaitT7; // wait the predescribed time + result := CmdSetMta(addr); // repeat this command + Exit; + end + else + begin + FLastError := comDriver.packetData[1]; // Store error info + Exit; + end; + end; + + // no error so it must have been a positive response + result := true; + + // store current memory transfer address + FMta := addr; +end; //*** end of CmdSetMta *** + + +//*************************************************************************************** +// NAME: CmdProgramClear +// PARAMETER: number of bytes in memory to clear +// RETURN VALUE: True is successful, False otherwise +// DESCRIPTION: Clears the number of bytes in non-volatile memory starting at the +// mta address. +// +//*************************************************************************************** +function TXcpLoader.CmdProgramClear(len : LongWord) : Boolean; +begin + // init return value + result := false; + + // prepare the command packet + comDriver.packetData[0] := kCmdPROGRAM_CLEAR; + comDriver.packetData[1] := 0; // use absolute mode + comDriver.packetData[2] := 0; // reserved + comDriver.packetData[3] := 0; // reserved + + // set address taking into account byte ordering + SetOrderedLong(len, @comDriver.packetData[4]); + + comDriver.packetLen := 8; + + // send packet with SYNCH retry feature + if not SendSynchedPacket(FTimerInterval[4], true) then Exit; + + // was the response an error packet? + if comDriver.packetData[0] = kCmdPidERR then + begin + // busy or programming active error received? + if comDriver.packetData[1] = kErrCMD_BUSY then + begin + WaitT7; // wait the predescribed time + result := CmdProgramClear(len); // repeat this command + Exit; + end + else + begin + FLastError := comDriver.packetData[1]; // Store error info + Exit; + end; + end; + + // no error so it must have been a positive response + result := true; +end; //*** end of CmdProgramClear *** + + +//*************************************************************************************** +// NAME: StartProgrammingSession +// PARAMETER: none +// RETURN VALUE: True is successful, False otherwise +// DESCRIPTION: Starts the programming session using the following XCP command +// sequence: +// * CONNECT +// * GET_STATUS +// * GETSEED (if applicable) +// * UNLOCK (if applicable) +// * PROGRAM_START +// +//*************************************************************************************** +function TXcpLoader.StartProgrammingSession : Boolean; +var + xcpProtection : TXcpProtection; + supportedRes : Byte; + seedData : array[0..5] of Byte; + seedLen : byte; + keyData : array[0..5] of Byte; + keyLen : byte; +begin + // init return value + result := false; + + // send the CONNECT command + if not CmdConnect then Exit; + + // make sure the programming resource is supported + if (FResources and kResPGM) <> kResPGM then + begin + FLastError := kErrFsrResourceUnavailable; + Exit; + end; + + // send the GET_STATUS command + if not CmdGetStatus then Exit; + + // check if we need to unlock the programming resource + if (FProtection and kResPGM) = kResPGM then + begin + // ceate xcp protection object + xcpProtection := TXcpProtection.Create(FSeedKeyDll); + + // make sure it contains the unlock algorithm for the PGM resource + if xcpProtection.GetPrivileges(@supportedRes) <> 0 then + begin + FLastError := kErrFsrSeedKeyDllInvalid; // error calling DLL function + xcpProtection.Free; // release the object + Exit; + end; + if (supportedRes and kResPGM) <> kResPGM then + begin + FLastError := kErrFsrKeyAlgoMissing; // key algorithm not present + xcpProtection.Free; // release the object + Exit; + end; + + // obtain the seed for the programming resource + if not CmdGetSeed(@seedData, kResPGM, seedLen) then + begin + xcpProtection.Free; // release the object + Exit; + end; + + // compute the key + keyLen := Length(keyData); + if xcpProtection.ComputKeyFromSeed(kResPGM, seedLen, @seedData, @keyLen, @keyData) <> 0 then + begin + FLastError := kErrFsrSeedKeyDllInvalid; // error calling DLL function + xcpProtection.Free; // release the object + Exit; + end; + + // release the object..no longer needed + xcpProtection.Free; + + // we have the key so now unlock the resource + if not CmdUnlock(@keyData, keyLen) then Exit; + + // make sure the PGM resource is really unprotected now + if (FProtection and kResPGM) = kResPGM then + begin + FLastError := kErrACCESS_LOCKED; + Exit; + end; + end; + + // send the PROGRAM_START command + if not CmdProgramStart then Exit; + + // successfully started the programming session + result := true; +end; //*** end of StartProgrammingSession *** + + +//*************************************************************************************** +// NAME: StopProgrammingSession +// PARAMETER: none +// RETURN VALUE: True is successful, False otherwise +// DESCRIPTION: Stops the programming session using the following XCP command +// sequence: +// * PROGRAM (size=0) +// * PROGRAM_RESET +// +//*************************************************************************************** +function TXcpLoader.StopProgrammingSession : Boolean; +begin + // init return value + result := false; + + // send the program command with size 0 to indicate end of programming session + if not CmdProgram(nil, 0) then Exit; + + // finish off by resetting the ECU + if not CmdProgramReset then Exit; + + // successfully stopped the programming session + result := true; +end; //*** end of StopProgrammingSession *** + + +//*************************************************************************************** +// NAME: ClearMemory +// PARAMETER: start address and the number of bytes to clear +// RETURN VALUE: True is successful, False otherwise +// DESCRIPTION: Clears the specified memory range using the following XCP command +// sequence: +// * SET_MTA +// * PROGRAM_CLEAR +// +//*************************************************************************************** +function TXcpLoader.ClearMemory(addr : LongWord; len : LongWord) : Boolean; +begin + // init return value + result := false; + + // set the start address for the erase operation + if not CmdSetMta(addr) then Exit; + + // finish off by resetting the ECU + if not CmdProgramClear(len) then Exit; + + // successfully cleared the memory + result := true; +end; //*** end of ClearMemory *** + + +//*************************************************************************************** +// NAME: WriteData +// PARAMETER: start address, the number of bytes to program, and the data buffer +// RETURN VALUE: True is successful, False otherwise +// DESCRIPTION: Programs specified memory range using the following XCP command +// sequence: +// * SET_MTA +// * PROGRAM(_MAX) +// +//*************************************************************************************** +function TXcpLoader.WriteData(addr : LongWord; len : LongWord; data : PByteArray) : Boolean; +var + currentWriteCnt : Byte; + bufferOffset : LongWord; +begin + // init return value + result := false; + + // set the start address for the program operation + if not CmdSetMta(addr) then Exit; + + // init buffer indexer + bufferOffset := 0; + + while len > 0 do + begin + // set the current write length to make optimal use of the available packet data + currentWriteCnt := len mod (FCtoPGMPacketLen-1); + if currentWriteCnt = 0 then currentWriteCnt := FCtoPGMPacketLen-1; + + // prepare the packet data for PROGRAM + if currentWriteCnt < FCtoPGMPacketLen-1 then + begin + if not CmdProgram(@data[bufferOffset], currentWriteCnt) then Exit; + end + // prepare the packet data for PROGRAM_MAX + else + begin + if not CmdProgramMax(@data[bufferOffset]) then Exit; + end; + + // update loop variables + len := len - currentWriteCnt; + bufferOffset := bufferOffset + currentWriteCnt; + end; + + // successfully programmed the memory + result := true; +end; //*** end of WriteData *** + + +end. +//******************************** end of XcpLoader.pas ********************************* + diff --git a/Host/Source/interfaces/XcpProtection.pas b/Host/Source/interfaces/XcpProtection.pas new file mode 100644 index 00000000..e0b23cbf --- /dev/null +++ b/Host/Source/interfaces/XcpProtection.pas @@ -0,0 +1,172 @@ +unit XcpProtection; +//*************************************************************************************** +// Description: XCP seed and key resource protection interface. +// File Name: XcpProtection.pas +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** +interface + + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, Messages, SysUtils, Classes, Forms; + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +// DLL Interface Methods +type + TXcpGetAvailablePrivileges = function(resourcePtr: PByte) : DWORD; cdecl; + TXcpComputKeyFromSeed = function(resource: Byte; seedLen: Byte; seedPtr: PByteArray; + keyLenPtr: PByte; keyPtr: PByteArray) : DWORD; cdecl; + +type + TXcpProtection = class(TObject) + private + FLibHandle : THandle; + FLibInitialized : Boolean; + FGetAvailablePrivileges: TXcpGetAvailablePrivileges; + FComputKeyFromSeed : TXcpComputKeyFromSeed; + public + constructor Create(libFile: string); + destructor Destroy; override; + function GetPrivileges(resourcePtr: PByte) : DWORD; + function ComputKeyFromSeed(resource: Byte; seedLen: Byte; seedPtr: PByteArray; + keyLenPtr: PByte; keyPtr: PByteArray) : DWORD; + end; + + +implementation + +//*************************************************************************************** +// NAME: Create +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class constructor +// +//*************************************************************************************** +constructor TXcpProtection.Create(libFile: string); +begin + // call inherited constructor + inherited Create; + + // library not yet initialized + FLibInitialized := false; + + // attempt to obtain the library handle + if (FileExists(libFile)) and (LowerCase(ExtractFileExt(libFile)) = '.dll') then + begin + FLibHandle := LoadLibrary(PChar(libFile)); + + if FLibHandle <> 0 then FLibInitialized := true; + end; + + // only continue if everything was okay sofar + if FLibInitialized = false then Exit; + + // attempt to obtain the function pointers from the interface library + @FComputKeyFromSeed := GetProcAddress(FLibHandle, 'XCP_ComputeKeyFromSeed'); + @FGetAvailablePrivileges := GetProcAddress(FLibHandle, 'XCP_GetAvailablePrivileges'); + + // check if the functions were found in the interface library + if not Assigned(FComputKeyFromSeed) then FLibInitialized := false; + if not Assigned(FGetAvailablePrivileges) then FLibInitialized := false; +end; //*** end of Create *** + + +//*************************************************************************************** +// NAME: Destroy +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class destructor +// +//*************************************************************************************** +destructor TXcpProtection.Destroy; +begin + // release the library and its handle + if FLibHandle <> 0 then + begin + FreeLibrary(FLibHandle); + end; + + // call inherited destructor + inherited; +end; //*** end of Destroy *** + + +//*************************************************************************************** +// NAME: GetPrivileges +// PARAMETER: resourcePtr : pointer where to store the supported resources +// for the key computation +// RETURN VALUE: 0 if success +// DESCRIPTION: obtains the privileges with available unlock algorithms in the +// external library file +// +//*************************************************************************************** +function TXcpProtection.GetPrivileges(resourcePtr: PByte) : DWORD; +begin + if FLibInitialized then + result := FGetAvailablePrivileges(resourcePtr) + else + result := 0; +end; //*** end of GetPrivileges *** + + +//*************************************************************************************** +// NAME: ComputKeyFromSeed +// PARAMETER: resource : resource for which the unlock key is requested +// seedLen : length of the seed +// seedPtr : pointer to the seed data +// keyLenPtr: pointer where to store the key length +// keyPtr : pointer where to store the key data +// RETURN VALUE: 0 if success +// DESCRIPTION: Computes the key for the requested resource. +// +//*************************************************************************************** +function TXcpProtection.ComputKeyFromSeed(resource: Byte; seedLen: Byte; + seedPtr: PByteArray; keyLenPtr: PByte; + keyPtr: PByteArray) : DWORD; +begin + if FLibInitialized then + result := FComputKeyFromSeed(resource, seedLen, seedPtr, keyLenPtr, keyPtr) + else + result := 0; +end; //*** end of ComputKeyFromSeed *** + + +end. +//******************************** end of XcpProtection.pas ***************************** + diff --git a/Host/Source/interfaces/can/peak/CANIcon.bmp b/Host/Source/interfaces/can/peak/CANIcon.bmp new file mode 100644 index 00000000..6ca58cdf Binary files /dev/null and b/Host/Source/interfaces/can/peak/CANIcon.bmp differ diff --git a/Host/Source/interfaces/can/peak/PCANdrvD.pas b/Host/Source/interfaces/can/peak/PCANdrvD.pas new file mode 100644 index 00000000..f3928d13 --- /dev/null +++ b/Host/Source/interfaces/can/peak/PCANdrvD.pas @@ -0,0 +1,547 @@ +unit PCANdrvD; +//*************************************************************************************** +// Project Name: TPCanDriver component for Borland Delphi +// Description: Encapsulates PCAN's Light driver into a VCL component for PCANUSB 1CH. +// File Name: PCANdrvD.pas +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** +interface + + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Pcan_usb; + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +type + TPCanChannel = ( pcanchannel0 ); + TPCanHardware = ( PCAN_USB1CH ); + TPCanDirection = ( PcanTx, PCanRx ); + TPCanMessage = packed record + id : LongInt; + dlc : Byte; + data : array [0..7] of Byte; + time : LongInt; + ext : Boolean; + end; + +type + TPCanMessageEvent = procedure( Sender: TObject; Direction: TPCanDirection; Message: TPCanMessage ) of object; + +type + TPCanEventThread = class(TThread) + private + { Private declarations } + FMethod: TThreadMethod; + protected + procedure Execute; override; + public + property Method : TThreadMethod read FMethod write FMethod; + end; + +type + TPCanDriver = class(TComponent) + private + { Private declarations } + FCanEventThread: TPCanEventThread; + FThreadRunning : boolean; + FCanConnected : boolean; + FStartTickCnt : DWORD; + function IsThreadRunning: boolean; + procedure ProcessReception; + protected + { Protected declarations } + FBaudRate : LongInt; + FChannel : TPCanChannel; + FHardware : TPCanHardware; + FPriority : TThreadPriority; + FExtendedId : Boolean; + FOnMessage : TPCanMessageEvent; + procedure SetBaudRate( Value: LongInt ); + procedure SetChannel( Value: TPCanChannel ); + procedure SetHardware( Value: TPCanHardware ); + procedure SetPriority( Value: TThreadPriority ); + procedure SetExtendedId( Value: Boolean ); + public + { Public declarations } + constructor Create( AOwner: TComponent ); override; + destructor Destroy; override; + function Connect: boolean; virtual; + procedure Disconnect; virtual; + function Transmit( Message: TPCanMessage): boolean; virtual; + function IsConnected: boolean; virtual; + published + { Published declarations } + property BaudRate : LongInt read FBaudRate write SetBaudRate default 500000; + property Channel : TPCanChannel read FChannel write SetChannel default pcanchannel0; + property Hardware : TPCanHardware read FHardware write SetHardware default PCAN_USB1CH; + property Priority : TThreadPriority read FPriority write SetPriority default tpNormal; + property ExtendedId : Boolean read FExtendedId write SetExtendedId default False; + property OnMessage : TPCanMessageEvent read FOnMessage write FOnMessage; + end; + + +//*************************************************************************************** +// Prototypes +//*************************************************************************************** +procedure Register; + +implementation +//*************************************************************************************** +// NAME: Execute +// PRECONDITIONS: none +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Overriden Execute function for the CanEventThread. Calls and synchro- +// nizes with the TCanDriver.ProcessEvents function. +// +//*************************************************************************************** +procedure TPCanEventThread.Execute; +begin + while not Terminated do + begin + if Assigned(Method) then // make sure TPCanDriver.ProcessEvents is set + Synchronize(Method); // call and synchronize + end; +end; //*** end of Execute *** + + +//*************************************************************************************** +// NAME: Create +// PRECONDITIONS: none +// PARAMETER: AOwner : owner of the component +// RETURN VALUE: none +// DESCRIPTION: Component constructor. Calls TComponent's constructor and initializes +// the private property variables to their default values. +// +//*************************************************************************************** +constructor TPCanDriver.Create( AOwner: TComponent ); +begin + // call inherited constructor + inherited Create( AOwner ); + + // set defaults for internal variables + FThreadRunning := False; + FCanConnected := False; + + // set defaults for properties + FBaudRate := 500000; + FChannel := pcanchannel0; + FHardware := PCAN_USB1CH; + FPriority := tpNormal; + FExtendedId := False; +end; //*** end of Create *** + + +//*************************************************************************************** +// NAME: Destroy +// PRECONDITIONS: none +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Component destructor. Calls TComponent's destructor +// +//*************************************************************************************** +destructor TPCanDriver.Destroy; +begin + Disconnect; // close the port and driver + inherited Destroy; // call inherited destructor +end; //*** end of Destroy *** + + +//*************************************************************************************** +// NAME: IsConnected +// PRECONDITIONS: none +// PARAMETER: none +// RETURN VALUE: True or False +// DESCRIPTION: Determines whether or not the CAN driver is connected and active +// +//*************************************************************************************** +function TPCanDriver.IsConnected: boolean; +begin + Result := FCanConnected; +end; //*** end of IsConnected *** + + +//*************************************************************************************** +// NAME: IsThreadRunning +// PRECONDITIONS: none +// PARAMETER: none +// RETURN VALUE: True or False +// DESCRIPTION: Determines whether or not the CAN event thread is running +// +//*************************************************************************************** +function TPCanDriver.IsThreadRunning: boolean; +begin + if FThreadRunning = True then + Result := True + else + Result := False; +end; //*** end of IsThreadRunning *** + + +//*************************************************************************************** +// NAME: SetBaudRate +// PRECONDITIONS: none +// PARAMETER: Value : new baudrate value [0 - 1000000 bps] +// RETURN VALUE: none +// DESCRIPTION: Configures the baudrate +// +// |------------------------------------------------------------------------------------ +// | Update baudrate configuration +// |------------------------------------------------------------------------------------ +//*************************************************************************************** +procedure TPCanDriver.SetBaudRate( Value: LongInt ); +begin + FBaudRate := Value; // update property +end; //*** end of SetBaudRate *** + + +//*************************************************************************************** +// NAME: SetChannel +// PRECONDITIONS: none +// PARAMETER: Value : channel0 or channel1 +// RETURN VALUE: none +// DESCRIPTION: Configures the used CAN channel +// +// |------------------------------------------------------------------------------------ +// | Update channel configuration +// |------------------------------------------------------------------------------------ +//*************************************************************************************** +procedure TPCanDriver.SetChannel( Value: TPCanChannel ); +begin + FChannel := Value; +end; //*** end of SetChannel *** + + +//*************************************************************************************** +// NAME: SetHardware +// PRECONDITIONS: none +// PARAMETER: Value : type of CAN hardware (Virtual, CANcardXL, etc.) +// RETURN VALUE: none +// DESCRIPTION: Configures the used CAN hardware +// +// |------------------------------------------------------------------------------------ +// | Update hardware configuration +// |------------------------------------------------------------------------------------ +//*************************************************************************************** +procedure TPCanDriver.SetHardware( Value: TPCanHardware ); +begin + FHardware := Value; +end; //*** end of SetHardware *** + + +//*************************************************************************************** +// NAME: SetPriority +// PRECONDITIONS: none +// PARAMETER: Value : thread priority +// RETURN VALUE: none +// DESCRIPTION: Configures the priority for the CAN event thread +// +// |------------------------------------------------------------------------------------ +// | y\ Is Thread running? /n +// |------------------------------------------------------------------------------------ +// | Stop Thread | +// | Update Thread priority | Update Thread priority +// | Restart Thread | +// |------------------------------------------------------------------------------------ +//*************************************************************************************** +procedure TPCanDriver.SetPriority( Value: TThreadPriority ); +begin + if IsThreadRunning then + begin + FCanEventThread.Suspend; // suspend the thread + FPriority := Value; // update the priority + FCanEventThread.Resume; // resume the thread + end + else + begin + FPriority := Value; // update the priority + end; +end; //*** end of SetPriority *** + + +//*************************************************************************************** +// NAME: SetExtendedId +// PRECONDITIONS: none +// PARAMETER: Value : true = support only 29-bit id's, false = support only 11-bit +// RETURN VALUE: none +// DESCRIPTION: Configures the support of extended 29-bit identifiers +// +// |------------------------------------------------------------------------------------ +// | Update extended id support selection +// |------------------------------------------------------------------------------------ +//*************************************************************************************** +procedure TPCanDriver.SetExtendedId( Value: Boolean ); +begin + FExtendedId := Value; +end; //*** end of SetExtendedId ***/ + + +//*************************************************************************************** +// NAME: Connect +// PRECONDITIONS: Disconnected from CAN bus +// PARAMETER: none +// RETURN VALUE: True or False for succees or error, respectively +// DESCRIPTION: Initializes the CAN driver and synchronizes the hardware with the CAN +// bus. +// +//*************************************************************************************** +function TPCanDriver.Connect: boolean; +var + Baudcode : Word; + MsgType : Integer; + +begin + Result := False; + FThreadRunning := False; + FCanConnected := False; + + // convert baudrate in bps to supported baudrate code + Baudcode := CAN_BAUD_500K; // init local + case FBaudRate of + 5000 : Baudcode := CAN_BAUD_5K; + 10000 : Baudcode := CAN_BAUD_10K; + 20000 : Baudcode := CAN_BAUD_20K; + 33333 : Baudcode := $1D14; + 50000 : Baudcode := CAN_BAUD_50K; + 83333 : Baudcode := $4B14; + 100000 : Baudcode := CAN_BAUD_100K; + 125000 : Baudcode := CAN_BAUD_125K; + 250000 : Baudcode := CAN_BAUD_250K; + 500000 : Baudcode := CAN_BAUD_500K; + 1000000 : Baudcode := CAN_BAUD_1M; + end; + + // convert extented id info + if FExtendedId then + MsgType := 1 + else + MsgType := 0; + + //-------------------------- open the driver ------------------------------------------ + if CAN_Init(Baudcode, MsgType) <> CAN_ERR_OK then Exit; + + + //-------------------------- open the acceptance filter -------------------------------- + if CAN_ResetFilter <> CAN_ERR_OK then + begin + CAN_Close; + Exit; + end; + + if FExtendedId then + begin + if CAN_MsgFilter($000, $1FFFFFFF, MSGTYPE_EXTENDED) <> CAN_ERR_OK then + begin + CAN_Close; + Exit; + end; + end + else + begin + if CAN_MsgFilter($000, $7FF, MSGTYPE_STANDARD) <> CAN_ERR_OK then + begin + CAN_Close; + Exit; + end; + end; + + //-------------------------- reset message queues ------------------------------------- + if CAN_ResetClient <> CAN_ERR_OK then + begin + CAN_Close; + Exit; + end; + + //-------------------------- start CAN event thread ----------------------------------- + FCanEventThread := TPCanEventThread.Create(True); // create and suspend + FCanEventThread.FreeOnTerminate := True; // auto free on termination + FCanEventThread.Method := ProcessReception; // set method + FCanEventThread.Resume; // start + FThreadRunning := True; + + + //-------------------------- store start time for time stamps ------------------------- + FStartTickCnt := GetTickCount; + + //-------------------------- success -------------------------------------------------- + FCanConnected := True; + Result := True; // successfully initialized the driver +end; //*** end of Connect *** + + +//*************************************************************************************** +// NAME: Disconnect +// PRECONDITIONS: none +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Disconnects the CAN driver +// +//*************************************************************************************** +procedure TPCanDriver.Disconnect; +begin + if IsConnected = True then // are we connected? + begin + FCanConnected := False; + // close the channel + CAN_Close; + end; + + if IsThreadRunning then + begin + FCanEventThread.Terminate; // stop + FThreadRunning := False; + end; +end; //*** end of Disconnect *** + + +//*************************************************************************************** +// NAME: Transmit +// PRECONDITIONS: Driver initialized using 'Connect' +// PARAMETER: Message: CAN message that is to be transmitted +// RETURN VALUE: True or False for succees or error, respectively +// DESCRIPTION: Transmits a CAN message. +// +//*************************************************************************************** +function TPCanDriver.Transmit( Message: TPCanMessage): boolean; +var + cnt : Byte; + msg : TPCANMsg; + msgcpy : TPCanMessage; +begin + // make sure the CAN driver is connected + if not IsConnected then + begin + Result := False; // can't transmit it not connected + exit; // no need to continue + end; + + // set the message identifier + msg.ID := Message.id; + if Message.ext then + msg.MSGTYPE := MSGTYPE_EXTENDED + else + msg.MSGTYPE := MSGTYPE_STANDARD; + + // set the data length + msg.LEN := Message.dlc; + + // store the data bytes + for cnt :=0 to Message.dlc do + begin + msg.DATA[cnt] := Message.data[cnt]; + end; + + // submit the transmit request + if CAN_Write(msg) <> CAN_ERR_OK then + begin + Result := False; + exit; + end; + + //---------------- process transmission confirmation -------------------------- + if Assigned( FOnMessage ) then + begin + msgcpy := Message; + msgcpy.time := GetTickCount - FStartTickCnt; + FOnMessage( Self, PCanTx, msgcpy ); // call application's event handler + end; + + Result := True; +end; //*** end of Transmit *** + + +//*************************************************************************************** +// NAME: ProcessReception +// PRECONDITIONS: thread running +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Called by the CAN event tread. This function traps and processes CAN +// events for OnMessage. +// +//*************************************************************************************** +procedure TPCanDriver.ProcessReception; +var + cnt : Byte; + msg : TPCanMessage; + msgraw : TPCANMsg; +begin + //---------------- process reception indication ------------------------------- + // continue only if a new message is present in the queue + if CAN_Read(msgraw) <> CAN_ERR_OK then + Exit; + + // only process CAN messages and not the status messages + if (msgraw.MSGTYPE = MSGTYPE_EXTENDED) or (msgraw.MSGTYPE = MSGTYPE_STANDARD) then + begin + // copy the message info + msg.time := GetTickCount - FStartTickCnt; + msg.id := msgraw.ID; + msg.dlc := msgraw.LEN; + // store the data bytes + for cnt :=0 to msg.dlc do + begin + msg.data[cnt] := msgraw.DATA[cnt]; + end; + + if Assigned( FOnMessage ) then + begin + FOnMessage( Self, PCanRx, msg ); // call application's event handler + end; + end; +end; //*** end of ProcessReception *** + + +//*************************************************************************************** +// NAME: Register +// PRECONDITIONS: none +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Registers the TPCanDriver component into Borland Delphi's IDE. +// +//*************************************************************************************** +procedure Register; +begin + RegisterComponents('Feaser', [TPCanDriver]); +end; //*** end of Register *** + + +end. +//********************************** end of PCANdrvD.pas ******************************** + + diff --git a/Host/Source/interfaces/can/peak/Pcan_usb.pas b/Host/Source/interfaces/can/peak/Pcan_usb.pas new file mode 100644 index 00000000..f62f7ef3 --- /dev/null +++ b/Host/Source/interfaces/can/peak/Pcan_usb.pas @@ -0,0 +1,296 @@ +/////////////////////////////////////////////////////////////////////////////// +// PCAN-Light +// PCAN_USB.pas +// +// Version 1.5 +// +// ~~~~~~~~~~ +// +// Basic Idea: +// +// ~~~~~~~~~~ +// +// Definition of the PCAN-Light API. +// The Driver support a Hardware and a Software who want to communicate with CAN-busses +// +// ~~~~~~~~~~~~ +// +// PCAN-Light -API +// +// ~~~~~~~~~~~~ +// +// - CAN_Init(wBTR0BTR1: Word; CANMsgType: Integer) +// - CAN_Close() +// - CAN_Status() +// - CAN_Write(var MsgBuff: TPCANMsg) +// - CAN_Read(var MsgBuff: TPCANMsg) +// - CAN_VersionInfo(lpszTextBuff: PChar) +// - CAN_ResetClient() +// - CAN_MsgFilter(FromID, ToID: LongWord; _Type: Integer) +// - CAN_ResetFilter() +// - SetUSBDeviceNr(DevNum: Longint) +// - GetUSBDeviceNr(var DevNum: Longint) +// +// ------------------------------------------------------------------ +// Author : Hoppe, Wilhelm +// Modified By: Wagner (13.08.2008) +// +// Sprache: PASCAL OO +// ------------------------------------------------------------------ +// +// Copyright (C) 1999-2006 PEAK-System Technik GmbH, Darmstadt +// +unit pcan_usb; + +interface + +const + // Constants definitions - Frame Type + // + CAN_INIT_TYPE_EX = $01; //Extended Frame + CAN_INIT_TYPE_ST = $00; //Standart Frame + + // Constants definitions - ID + // + CAN_MAX_STANDARD_ID = $7ff; + CAN_MAX_EXTENDED_ID = $1fffffff; + + // Constants definitions - CAN message types + // + MSGTYPE_STANDARD = $00; // Standard Data frame (11-bit ID) + MSGTYPE_RTR = $01; // 1, if Remote Request frame + MSGTYPE_EXTENDED = $02; // 1, if Extended Data frame (CAN 2.0B, 29-bit ID) + MSGTYPE_ERROR = $80; // 1, if Status information + + // Baud rate codes = BTR0/BTR1 register values for the CAN controller. + // You can define your own Baudrate with the BTROBTR1 register !! + // take a look at www.peak-system.com for our software BAUDTOOL to + // calculate the BTROBTR1 register for every baudrate and sample point. + // + CAN_BAUD_1M = $0014; // 1 MBit/s + CAN_BAUD_500K = $001C; // 500 kBit/s + CAN_BAUD_250K = $011C; // 250 kBit/s + CAN_BAUD_125K = $031C; // 125 kBit/s + CAN_BAUD_100K = $432F; // 100 kBit/s + CAN_BAUD_50K = $472F; // 50 kBit/s + CAN_BAUD_20K = $532F; // 20 kBit/s + CAN_BAUD_10K = $672F; // 10 kBit/s + CAN_BAUD_5K = $7F7F; // 5 kBit/s + + // Error codes (bit code) + // + CAN_ERR_OK = $0000; // No error + CAN_ERR_XMTFULL = $0001; // Transmit buffer in CAN controller is full + CAN_ERR_OVERRUN = $0002; // CAN controller was read too late + CAN_ERR_BUSLIGHT = $0004; // Bus error: an error counter reached the 'light' limit + CAN_ERR_BUSHEAVY = $0008; // Bus error: an error counter reached the 'heavy' limit + CAN_ERR_BUSOFF = $0010; // Bus error: the CAN controller is in bus-off state + CAN_ERR_QRCVEMPTY = $0020; // Receive queue is empty + CAN_ERR_QOVERRUN = $0040; // Receive queue was read too late + CAN_ERR_QXMTFULL = $0080; // Transmit queue is full + CAN_ERR_REGTEST = $0100; // Test of the CAN controller hardware registers failed (no hardware found) + CAN_ERR_NOVXD = $0200; // Driver not loaded + CAN_ERR_RESOURCE = $2000; // Resource (FIFO, Client, timeout) cannot be created + CAN_ERR_ILLPARAMTYPE = $4000; // Invalid parameter + CAN_ERR_ILLPARAMVAL = $8000; // Invalid parameter value + CAN_ERRMASK_ILLHANDLE = $1C00; // Mask for all handle errors + CAN_ERR_ANYBUSERR = (CAN_ERR_BUSLIGHT or CAN_ERR_BUSHEAVY or CAN_ERR_BUSOFF); + // All further error conditions <> 0 please ask PEAK when required.......internal driver failure ........ + +type + // CAN Message + // + TPCANMsg = record + ID: LongWord; // 11/29 bit identifier + MSGTYPE: Byte; // Bits from MSGTYPE_* + LEN: Byte; // Data Length Code of the Msg (0..8) + DATA: array[0..7] of Byte; // Data 0 .. 7 + end; + +/////////////////////////////////////////////////////////////////////////////// +// CAN_Init() +// This function make the following: +// - Activate a Hardware +// - Make a Register Test of 82C200/SJA1000 +// - Allocate a Send buffer and a Hardware handle +// - Programs the configuration of the transmit/receive driver +// - Set the Baudrate register +// - Set the Controller in RESET condition +// +// If CANMsgType=0 ---> ID 11Bit +// If CANMsgType=1 ---> ID 11/29Bit +// +// Possible Errors: NOVXD ILLHW REGTEST RESOURCE +// +function CAN_Init(wBTR0BTR1: Word; + CANMsgType: Integer): LongWord; stdcall; + +/////////////////////////////////////////////////////////////////////////////// +// CAN_Close() +// This function terminate and release the configured hardware and all +// allocated resources +// +// Possible Errors: NOVXD +// +function CAN_Close: LongWord; stdcall; + +/////////////////////////////////////////////////////////////////////////////// +// CAN_Status() +// This function request the current status of the hardware (b.e. BUS-OFF) +// +// Possible Errors: NOVXD BUSOFF BUSHEAVY OVERRUN +// +function CAN_Status: LongWord; stdcall; + +/////////////////////////////////////////////////////////////////////////////// +// CAN_Write() +// This function Place a CAN message into the Transmit Queue of the CAN Hardware +// +// Possible Errors: NOVXD RESOURCE BUSOFF QXMTFULL +// +function CAN_Write(var MsgBuff: TPCANMsg): LongWord; stdcall; + +/////////////////////////////////////////////////////////////////////////////// +// CAN_Read() +// This function get the next message or the next error from the Receive Queue of +// the CAN Hardware. +// REMARK: +// - Check always the type of the received Message (MSGTYPE_STANDARD,MSGTYPE_RTR, +// MSGTYPE_EXTENDED,MSGTYPE_STATUS) +// - The function will return ERR_OK always that you receive a CAN message successfully +// although if the messages is a MSGTYPE_STATUS message. +// - When a MSGTYPE_STATUS mesasge is got, the ID and Length information of the message +// will be treated as indefined values. Actually information of the received message +// should be interpreted using the first 4 data bytes as follow: +// * Data0 Data1 Data2 Data3 Kind of Error +// 0x00 0x00 0x00 0x02 CAN_ERR_OVERRUN 0x0002 CAN Controller was read to late +// 0x00 0x00 0x00 0x04 CAN_ERR_BUSLIGHT 0x0004 Bus Error: An error counter limit reached (96) +// 0x00 0x00 0x00 0x08 CAN_ERR_BUSHEAVY 0x0008 Bus Error: An error counter limit reached (128) +// 0x00 0x00 0x00 0x10 CAN_ERR_BUSOFF 0x0010 Bus Error: Can Controller went "Bus-Off" +// - If a CAN_ERR_BUSOFF status message is received, the CAN Controller must to be +// initialized again using the Init() function. Otherwise, will be not possible +// to send/receive more messages. +// - The message will be written to 'msgbuff'. +// +// Possible Errors: NOVXD QRCVEMPTY +// +function CAN_Read(var MsgBuff: TPCANMsg): LongWord; stdcall; + +/////////////////////////////////////////////////////////////////////////////// +// CAN_VersionInfo() +// This function get the Version and copyright of the hardware as text +// (max. 255 characters) +// +// Possible Errors: NOVXD +// +function CAN_VersionInfo( + lpszTextBuff: PChar + ): LongWord; stdcall; + +/////////////////////////////////////////////////////////////////////////////// +// CAN_SpecialFunktion() +// This function is an special function to be used "ONLY" for distributors +// Return: 1 - the given parameters and the parameters in the hardware agree +// 0 - otherwise +// +// Possible Errors: NOVXD +// +function CAN_SpecialFunktion( + distributorcode: LongWord; + codenumber: Integer + ): LongWord; stdcall; + +////////////////////////////////////////////////////////////////////////////// +// CAN_ResetClient() +// This function delete the both queues (Transmit,Receive) of the CAN Controller +// using a RESET +// +// Possible Errors: ERR_ILLCLIENT ERR_NOVXD +// +function CAN_ResetClient: LongWord; stdcall; + +/////////////////////////////////////////////////////////////////////////////// +// CAN_MsgFilter(FromID, ToID, int Type) +// This function set the receive message filter of the CAN Controller. +// REMARK: +// - A quick register of all messages is possible using the parameters FromID and ToID = 0 +// - Every call of this function maybe cause an extention of the receive filter of the +// CAN controller, which one can go briefly to RESET +// - New in Ver 2.x: +// * Standard frames will be put it down in the acc_mask/code as Bits 28..13 +// * Hardware driver for 82C200 must to be moved to Bits 10..0 again! +// WARNING: +// It is not guaranteed to receive ONLY the registered messages. +// +// Possible Errors: NOVXD ILLCLIENT ILLNET REGTEST +// +function CAN_MsgFilter(FromID, ToID: LongWord; _Type: Integer): LongWord; stdcall; + +/////////////////////////////////////////////////////////////////////////////// +// CAN_ResetFilter() +// This function close completely the Message Filter of the Hardware. +// They will be no more messages received. +// +// Possible Errors: NOVXD +// +function CAN_ResetFilter: LongWord; stdcall; + +////////////////////////////////////////////////////////////////////////////// +// SetUSBDeviceNr() +// This function set an identification number to the USB CAN hardware +// +// Possible Errors: NOVXD ILLHW ILLPARAMTYPE ILLPARAMVAL REGTEST +// +function SetUSBDeviceNr(DevNum: Longint): LongWord; stdcall; + +////////////////////////////////////////////////////////////////////////////// +// GetUSBDeviceNr() +// This function read the device number of a USB CAN Hardware +// +// Possible Errors: NOVXD ILLHW ILLPARAMTYPE +// +function GetUSBDeviceNr(var DevNum: Longint): LongWord; stdcall; + +implementation + +uses SysUtils; + +const DLL_Name = 'PCAN_USB.dll'; + +function CAN_Init(wBTR0BTR1: Word; CANMsgType: Integer): LongWord; stdcall; +external DLL_Name; + +function CAN_Close: LongWord; stdcall; +external DLL_Name; + +function CAN_Status: LongWord; stdcall; +external DLL_Name; + +function CAN_Write(var MsgBuff: TPCANMsg): LongWord; stdcall; +external DLL_Name; + +function CAN_Read(var MsgBuff: TPCANMsg): LongWord; stdcall; +external DLL_Name; + +function CAN_VersionInfo(lpszTextBuff: PChar): LongWord; stdcall; +external DLL_Name; + +function CAN_SpecialFunktion(distributorcode: LongWord; codenumber: Integer): LongWord; stdcall; +external DLL_Name; + +function CAN_ResetClient: LongWord; stdcall; +external DLL_Name; + +function CAN_MsgFilter(FromID, ToID: LongWord; _Type: Integer): LongWord; stdcall; +external DLL_Name; + +function CAN_ResetFilter: LongWord; stdcall; +external DLL_Name; + +function SetUSBDeviceNr(DevNum: Longint): LongWord; stdcall; +external DLL_Name; + +function GetUSBDeviceNr(var DevNum: Longint): LongWord; stdcall; +external DLL_Name; + +end. diff --git a/Host/Source/interfaces/can/peak/XcpSettings.dfm b/Host/Source/interfaces/can/peak/XcpSettings.dfm new file mode 100644 index 00000000..ae3b3a1b Binary files /dev/null and b/Host/Source/interfaces/can/peak/XcpSettings.dfm differ diff --git a/Host/Source/interfaces/can/peak/XcpSettings.pas b/Host/Source/interfaces/can/peak/XcpSettings.pas new file mode 100644 index 00000000..5707cbfe --- /dev/null +++ b/Host/Source/interfaces/can/peak/XcpSettings.pas @@ -0,0 +1,289 @@ +unit XcpSettings; +//*************************************************************************************** +// Description: XCP settings interface for CAN +// File Name: XcpSettings.pas +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** +interface + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, ComCtrls, ExtCtrls, IniFiles; + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +type + TXcpSettingsForm = class(TForm) + pnlFooter: TPanel; + btnOK: TButton; + btnCancel: TButton; + pageControl: TPageControl; + tabXcp: TTabSheet; + tabCan: TTabSheet; + iconCan: TImage; + lblCan: TLabel; + lblXcp: TLabel; + iconXcp2: TImage; + lblHardware: TLabel; + cmbHardware: TComboBox; + lblChannel: TLabel; + cmbChannel: TComboBox; + lblBaudRate: TLabel; + chbExtendedId: TCheckBox; + edtBaudRate: TEdit; + lblT1: TLabel; + lblT3: TLabel; + lblT4: TLabel; + lblT5: TLabel; + lblT7: TLabel; + edtT1: TEdit; + edtT3: TEdit; + edtT4: TEdit; + edtT5: TEdit; + edtT7: TEdit; + tabProt: TTabSheet; + iconXcp1: TImage; + lblPort: TLabel; + edtSeedKey: TEdit; + btnBrowse: TButton; + lblTransmitId: TLabel; + Label1: TLabel; + edtTransmitId: TEdit; + edtReceiveId: TEdit; + openDialog: TOpenDialog; + procedure btnOKClick(Sender: TObject); + procedure btnCancelClick(Sender: TObject); + procedure btnBrowseClick(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + end; + +type + TXcpSettings = class(TObject) + private + FSettingsForm : TXcpSettingsForm; + FIniFile : string; + public + constructor Create(iniFile : string); + destructor Destroy; override; + function Configure : Boolean; + end; + + +implementation +{$R *.DFM} +//*************************************************************************************** +// NAME: btnOKClick +// PARAMETER: none +// RETURN VALUE: modal result +// DESCRIPTION: Sets the module result to okay. +// +//*************************************************************************************** +procedure TXcpSettingsForm.btnOKClick(Sender: TObject); +begin + ModalResult := mrOK; +end; //*** end of btnOKClick *** + + +//*************************************************************************************** +// NAME: btnCancelClick +// PARAMETER: none +// RETURN VALUE: modal result +// DESCRIPTION: Sets the module result to cancel. +// +//*************************************************************************************** +procedure TXcpSettingsForm.btnCancelClick(Sender: TObject); +begin + ModalResult := mrCancel; +end; //*** end of btnCancelClick *** + + +//*************************************************************************************** +// NAME: btnBrowseClick +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Prompts the user to select the seed/key dll file. +// +//*************************************************************************************** +procedure TXcpSettingsForm.btnBrowseClick(Sender: TObject); +begin + openDialog.InitialDir := ExtractFilePath(ParamStr(0)); + if openDialog.Execute then + begin + edtSeedKey.Text := openDialog.FileName; + end; +end; //*** end of btnBrowseClick *** + + +//*************************************************************************************** +// NAME: Create +// PARAMETER: Name of the INI file where the settings are and will be stored +// RETURN VALUE: none +// DESCRIPTION: Class constructor +// +//*************************************************************************************** +constructor TXcpSettings.Create(iniFile : string); +begin + // call inherited constructor + inherited Create; + + // set the inifile + FIniFile := iniFile; + + // create an instance of the settings form + FSettingsForm := TXcpSettingsForm.Create(nil); +end; //*** end of Create *** + + +//*************************************************************************************** +// NAME: Destroy +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class destructor +// +//*************************************************************************************** +destructor TXcpSettings.Destroy; +begin + // releaase the settings form object + FSettingsForm.Free; + + // call inherited destructor + inherited; +end; //*** end of Destroy *** + + +//*************************************************************************************** +// NAME: Configure +// PARAMETER: none +// RETURN VALUE: True if configuration was successfully changed, False otherwise +// DESCRIPTION: Allows the user to configure the XCP interface using a GUI. +// +//*************************************************************************************** +function TXcpSettings.Configure : Boolean; +var + settingsIni: TIniFile; +begin + // initialize the return value + result := false; + + // init the form elements using the configuration found in the INI + if FileExists(FIniFile) then + begin + // create ini file object + settingsIni := TIniFile.Create(FIniFile); + + // CAN related elements + FSettingsForm.cmbHardware.ItemIndex := settingsIni.ReadInteger('can', 'hardware', 0); + FSettingsForm.cmbChannel.ItemIndex := settingsIni.ReadInteger('can', 'channel', 0); + FSettingsForm.edtBaudRate.Text := IntToStr(settingsIni.ReadInteger('can', 'baudrate', 500)); + FSettingsForm.chbExtendedId.Checked := settingsIni.ReadBool('can', 'extended', false); + FSettingsForm.edtTransmitId.Text := Format('%x',[settingsIni.ReadInteger('can', 'txid', $667)]); + FSettingsForm.edtReceiveId.Text := Format('%x',[settingsIni.ReadInteger('can', 'rxid', $7e1)]); + + // XCP related elements + FSettingsForm.edtSeedKey.Text := settingsIni.ReadString('xcp', 'seedkey', ''); + FSettingsForm.edtT1.Text := IntToStr(settingsIni.ReadInteger('xcp', 't1', 1000)); + FSettingsForm.edtT3.Text := IntToStr(settingsIni.ReadInteger('xcp', 't3', 2000)); + FSettingsForm.edtT4.Text := IntToStr(settingsIni.ReadInteger('xcp', 't4', 10000)); + FSettingsForm.edtT5.Text := IntToStr(settingsIni.ReadInteger('xcp', 't5', 1000)); + FSettingsForm.edtT7.Text := IntToStr(settingsIni.ReadInteger('xcp', 't7', 2000)); + + // release ini file object + settingsIni.Free; + end + else + begin + // set defaults + // CAN related elements + FSettingsForm.cmbHardware.ItemIndex := 0; + FSettingsForm.cmbChannel.ItemIndex := 0; + FSettingsForm.edtBaudRate.Text := IntToStr(500); + FSettingsForm.chbExtendedId.Checked := false; + FSettingsForm.edtTransmitId.Text := Format('%x',[$667]); + FSettingsForm.edtReceiveId.Text := Format('%x',[$7e1]); + + // XCP related elements + FSettingsForm.edtSeedKey.Text := ''; + FSettingsForm.edtT1.Text := IntToStr(1000); + FSettingsForm.edtT3.Text := IntToStr(2000); + FSettingsForm.edtT4.Text := IntToStr(10000); + FSettingsForm.edtT5.Text := IntToStr(1000); + FSettingsForm.edtT7.Text := IntToStr(2000); + + end; + + // show the form as modal so we can get the result here + if FSettingsForm.ShowModal = mrOK then + begin + if FIniFile <> '' then + begin + // create ini file object + settingsIni := TIniFile.Create(FIniFile); + + // CAN related elements + settingsIni.WriteInteger('can', 'hardware', FSettingsForm.cmbHardware.ItemIndex); + settingsIni.WriteInteger('can', 'channel', FSettingsForm.cmbChannel.ItemIndex); + settingsIni.WriteInteger('can', 'baudrate', StrToInt(FSettingsForm.edtBaudRate.Text)); + settingsIni.WriteBool('can', 'extended', FSettingsForm.chbExtendedId.Checked); + settingsIni.WriteInteger('can', 'txid', StrToInt('$'+FSettingsForm.edtTransmitId.Text)); + settingsIni.WriteInteger('can', 'rxid', StrToInt('$'+FSettingsForm.edtReceiveId.Text)); + + // XCP related elements + settingsIni.WriteString('xcp', 'seedkey', FSettingsForm.edtSeedKey.Text); + settingsIni.WriteInteger('xcp', 't1', StrToInt(FSettingsForm.edtT1.Text)); + settingsIni.WriteInteger('xcp', 't3', StrToInt(FSettingsForm.edtT3.Text)); + settingsIni.WriteInteger('xcp', 't4', StrToInt(FSettingsForm.edtT4.Text)); + settingsIni.WriteInteger('xcp', 't5', StrToInt(FSettingsForm.edtT5.Text)); + settingsIni.WriteInteger('xcp', 't7', StrToInt(FSettingsForm.edtT7.Text)); + + // release ini file object + settingsIni.Free; + + // indicate that the settings where successfully updated + result := true; + end; + end; +end; //*** end of Configure *** + + +end. +//******************************** end of XcpSettings.pas ******************************* + + diff --git a/Host/Source/interfaces/can/peak/XcpTransport.pas b/Host/Source/interfaces/can/peak/XcpTransport.pas new file mode 100644 index 00000000..b8f79f36 --- /dev/null +++ b/Host/Source/interfaces/can/peak/XcpTransport.pas @@ -0,0 +1,362 @@ +unit XcpTransport; +//*************************************************************************************** +// Description: XCP transport layer for CAN. +// File Name: XcpTransport.pas +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** +interface + + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, Messages, SysUtils, Classes, Forms, IniFiles, PCANdrvD; + + +//*************************************************************************************** +// Global Constants +//*************************************************************************************** +const kMaxPacketSize = 256; + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +type + TXcpTransportInfo = (kNone, kResponse, kError); + + +type + TXcpTransport = class(TObject) + private + comEventInfo : TXcpTransportInfo; + comEvent : THandle; + packetTxId : LongWord; + packetRxId : Longword; + extendedId : Boolean; + procedure OnCanMessage(Sender: TObject; Direction: TPCanDirection; Message: TPCanMessage); + function MsgWaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD; + public + packetData : array[0..kMaxPacketSize-1] of Byte; + packetLen : Word; + pcanDriver : TPCanDriver; + constructor Create; + procedure Configure(iniFile : string); + procedure Connect; + function SendPacket(timeOutms: LongWord): Boolean; + procedure Disconnect; + destructor Destroy; override; + end; + + +implementation + +//*************************************************************************************** +// NAME: Create +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class constructore +// +//*************************************************************************************** +constructor TXcpTransport.Create; +begin + // call inherited constructor + inherited Create; + + // reset can event info + comEventInfo := kNone; + + // create the event that requires manual reset + comEvent := CreateEvent(nil, True, False, nil); + + if comEvent = 0 then + Application.MessageBox( 'Could not obtain event placeholder.', + 'Error', MB_OK or MB_ICONERROR ); + + // create a pcan driver instance + pcanDriver := TPCanDriver.Create(nil); + + // set can driver event handlers + pcanDriver.OnMessage := OnCanMessage; + + // reset the packet ids + packetTxId := 0; + packetRxId := 0; + + // use standard id's by default + extendedId := false; + + // reset packet length + packetLen := 0; +end; //*** end of Create *** + + +//*************************************************************************************** +// NAME: Destroy +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class destructor +// +//*************************************************************************************** +destructor TXcpTransport.Destroy; +begin + // release can driver instance + pcanDriver.Free; + + // release event handle + CloseHandle(comEvent); + + // call inherited destructor + inherited; +end; //*** end of Destroy *** + + +//*************************************************************************************** +// NAME: Configure +// PARAMETER: filename of the INI +// RETURN VALUE: none +// DESCRIPTION: Configures both this class from the settings in the INI. +// +//*************************************************************************************** +procedure TXcpTransport.Configure(iniFile : string); +var + settingsIni : TIniFile; + hwIndex : integer; +begin + // read XCP configuration from INI + if FileExists(iniFile) then + begin + // create ini file object + settingsIni := TIniFile.Create(iniFile); + + // set message configuration + packetTxId := settingsIni.ReadInteger('can', 'txid', $667); + packetRxId := settingsIni.ReadInteger('can', 'rxid', $7e1); + extendedId := settingsIni.ReadBool('can', 'extended', false); + + // configure can hardware + hwIndex := settingsIni.ReadInteger('can', 'hardware', 0); + pcanDriver.Hardware := PCAN_USB1CH; // init to PCAN_USB1CH + case hwIndex of + 0 : pcanDriver.Hardware := PCAN_USB1CH; + end; + + // configure baudrate + pcanDriver.BaudRate := settingsIni.ReadInteger('can', 'baudrate', 500) * 1000; + + // only 1 channel on PCAN USB 1CH + pcanDriver.Channel := pcanchannel0; + + // release ini file object + settingsIni.Free; + end; +end; //*** end of Configure *** + + +//*************************************************************************************** +// NAME: Connect +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Connects the transport layer device. +// +//*************************************************************************************** +procedure TXcpTransport.Connect; +begin + if not pcanDriver.Connect then + Application.MessageBox( 'Could not connect to CAN bus.', + 'Error', MB_OK or MB_ICONERROR ); +end; //*** end of Connect *** + + +//*************************************************************************************** +// NAME: SendPacket +// PARAMETER: the time[ms] allowed for the reponse from the slave to come in. +// RETURN VALUE: True if response received from slave, False otherwise +// DESCRIPTION: Sends the XCP packet using the data in 'packetData' and length in +// 'packetLen' and waits for the response to come in. +// +//*************************************************************************************** +function TXcpTransport.SendPacket(timeOutms: LongWord): Boolean; +var + pcanmsg : TPCanMessage; + cnt : byte; + waitResult: Integer; +begin + // prepare the packet + pcanmsg.id := LongInt(PacketTxId); + pcanmsg.dlc := packetLen; + pcanmsg.ext := extendedId; + for cnt := 0 to packetLen-1 do + begin + pcanmsg.data[cnt] := packetData[cnt]; + end; + + // make sure the event is reset + ResetEvent(comEvent); + comEventInfo := kNone; + + // submit the packet transmission request + if not pcanDriver.Transmit(pcanmsg) then + begin + // unable to submit tx request + result := False; + Exit; + end; + + // packet is being transmitted. Now wait for the response to come in + waitResult := MsgWaitForSingleObject(comEvent, timeOutms); + + if waitResult <> WAIT_OBJECT_0 then + begin + // no com event triggered so either a timeout or internal error occurred + result := False; + Exit; + end; + + // com event was triggered. now check if the reponse was correctly received + if comEventInfo <> kResponse then + begin + result := False; + Exit; + end; + + // packet successfully transmitted and response packet received + result := True; +end; //*** end of SendPacket *** + + +//*************************************************************************************** +// NAME: Disconnect +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Disconnects the transport layer device. +// +//*************************************************************************************** +procedure TXcpTransport.Disconnect; +begin + pcanDriver.Disconnect; +end; //*** end of Disconnect *** + + +//*************************************************************************************** +// NAME: OnCanMessage +// PRECONDITIONS: none +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Can message event handler +// +//*************************************************************************************** +procedure TXcpTransport.OnCanMessage(Sender: TObject; Direction: TPCanDirection; Message: TPCanMessage); +var + cnt : integer; +begin + // the event we are interested in is the reception of the command response from + // slave. + if Direction = PCanRx then + begin + if Message.id = LongInt(PacketRxId) then + begin + // store response data + for cnt := 0 to Message.dlc-1 do + begin + packetData[cnt] := Message.data[cnt]; + end; + + // store response length + packetLen := Message.dlc; + + // set event flag + comEventInfo := kResponse; + + // trigger the event + SetEvent(comEvent); + end; + end; +end; //*** end of OnCanMessage *** + + +//*************************************************************************************** +// NAME: MsgWaitForSingleObject +// PRECONDITIONS: none +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Improved version of WaitForSingleObject. This version actually +// processes messages in the queue instead of blocking them. +// +//*************************************************************************************** +function TXcpTransport.MsgWaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD; +var + dwEnd:DWord; +begin + // compute the time when the WaitForSingleObject is supposed to time out + dwEnd := GetTickCount + dwMilliseconds; + + repeat + // wait for an event to happen or a message to be in the queue + result := MsgWaitForMultipleObjects(1, hHandle, False, dwMilliseconds, QS_ALLINPUT); + + // a message was in the queue? + if result = WAIT_OBJECT_0 + 1 then + begin + // process these messages + Application.ProcessMessages; + + // check for timeout manually because if a message in the queue occurred, the + // MsgWaitForMultipleObjects will be called again and the timer will start from + // scratch. we need to make sure the correct timeout time is used. + dwMilliseconds := GetTickCount; + if dwMilliseconds < dwEnd then + begin + dwMilliseconds := dwEnd - dwMilliseconds; + end + else + begin + // timeout occured + result := WAIT_TIMEOUT; + Break; + end; + end + else + // the event occured? + begin + // we can stop + Break; + end; + until True = False; +end; //*** end of MsgWaitForSingleObject *** + + +end. +//******************************** end of XcpTransport.pas ****************************** + diff --git a/Host/Source/interfaces/can/peak/openblt_can_peak.cfg b/Host/Source/interfaces/can/peak/openblt_can_peak.cfg new file mode 100644 index 00000000..b7fa021f --- /dev/null +++ b/Host/Source/interfaces/can/peak/openblt_can_peak.cfg @@ -0,0 +1,35 @@ +-$A+ +-$B- +-$C+ +-$D+ +-$E- +-$F- +-$G+ +-$H+ +-$I+ +-$J+ +-$K- +-$L+ +-$M- +-$N+ +-$O+ +-$P+ +-$Q- +-$R- +-$S- +-$T- +-$U- +-$V+ +-$W- +-$X+ +-$YD +-$Z1 +-cg +-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +-H+ +-W+ +-M +-$M16384,1048576 +-K$00400000 +-E../../../../ +-LNc:\program files (x86)\borland\delphi4\Lib diff --git a/Host/Source/interfaces/can/peak/openblt_can_peak.dof b/Host/Source/interfaces/can/peak/openblt_can_peak.dof new file mode 100644 index 00000000..0e2c2a16 --- /dev/null +++ b/Host/Source/interfaces/can/peak/openblt_can_peak.dof @@ -0,0 +1,87 @@ +[Compiler] +A=1 +B=0 +C=1 +D=1 +E=0 +F=0 +G=1 +H=1 +I=1 +J=1 +K=0 +L=1 +M=0 +N=1 +O=1 +P=1 +Q=0 +R=0 +S=0 +T=0 +U=0 +V=1 +W=0 +X=1 +Y=1 +Z=1 +ShowHints=1 +ShowWarnings=1 +UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +[Linker] +MapFile=0 +OutputObjs=0 +ConsoleApp=1 +DebugInfo=0 +RemoteSymbols=0 +MinStackSize=16384 +MaxStackSize=1048576 +ImageBase=4194304 +ExeDescription= +[Directories] +OutputDir=../../../../ +UnitOutputDir= +PackageDLLOutputDir= +PackageDCPOutputDir= +SearchPath= +Packages=Vcl40;Vclx40;Vcldb40;vcldbx40;VclSmp40;Qrpt40 +Conditionals= +DebugSourceDirs= +UsePackages=0 +[Parameters] +RunParams= +HostApplication= +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1031 +CodePage=1252 +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= +[Excluded Packages] +$(DELPHI)\Lib\dclusr40.bpl=Borland User +[HistoryLists\hlUnitAliases] +Count=1 +Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +[HistoryLists\hlOutputDirectorry] +Count=2 +Item0=../../../../ +Item1=../../../ diff --git a/Host/Source/interfaces/can/peak/openblt_can_peak.dpr b/Host/Source/interfaces/can/peak/openblt_can_peak.dpr new file mode 100644 index 00000000..07263dc5 --- /dev/null +++ b/Host/Source/interfaces/can/peak/openblt_can_peak.dpr @@ -0,0 +1,605 @@ +library openblt_can_peak; +//*************************************************************************************** +// Project Name: MicroBoot Interface for Borland Delphi +// Description: XCP - CAN interface for MicroBoot supporting PEAK CAN +// File Name: openblt_can_peak.dpr +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** + + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, + Messages, + Graphics, + Controls, + Forms, + Dialogs, + SysUtils, + Classes, + Extctrls, + XcpProtection in '..\..\XcpProtection.pas', + SRecReader in '..\..\SRecReader.pas', + XcpDataFile in '..\..\XcpDataFile.pas', + XcpLoader in '..\..\XcpLoader.pas', + XcpTransport in 'XcpTransport.pas', + XcpSettings in 'XcpSettings.pas' {XcpSettingsForm}, + pcan_usb in 'Pcan_usb.pas', + PCANdrvD in 'PCANdrvD.pas'; + + +//*************************************************************************************** +// Global Constants +//*************************************************************************************** +const kMaxProgLen = 256; // maximum number of bytes to progam at one time + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +// DLL Interface Callbacks - modifications requires potential update of all interfaces! +type + TStartedEvent = procedure(length: Longword) of object; + TProgressEvent = procedure(progress: Longword) of object; + TDoneEvent = procedure of object; + TErrorEvent = procedure(error: ShortString) of object; + TLogEvent = procedure(info: ShortString) of object; + TInfoEvent = procedure(info: ShortString) of object; + +type + TEventHandlers = class // create a dummy class + procedure OnTimeout(Sender: TObject); + end; + +//*************************************************************************************** +// Global Variables +//*************************************************************************************** +var + //--- begin of don't change --- + AppOnStarted : TStartedEvent; + AppOnProgress : TProgressEvent; + AppOnDone : TDoneEvent; + AppOnError : TErrorEvent; + AppOnLog : TLogEvent; + AppOnInfo : TInfoEvent; + //--- end of don't change --- + timer : TTimer; + events : TEventHandlers; + loader : TXcpLoader; + datafile : TXcpDataFile; + progdata : array of Byte; + progfile : string; + stopRequest : boolean; + + +//*************************************************************************************** +// NAME: MbiCallbackOnStarted +// PARAMETER: length of the file that is being downloaded. +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnStarted(length: Longword); +begin + if Assigned(AppOnStarted) then + begin + AppOnStarted(length); + end; +end; //** end of MbiCallbackOnStarted *** + + +//*************************************************************************************** +// NAME: MbiCallbackOnProgress +// PARAMETER: progress of the file download. +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnProgress(progress: Longword); +begin + if Assigned(AppOnProgress) then + begin + AppOnProgress(progress); + end; +end; //** end of MbiCallbackOnProgress *** + + +//*************************************************************************************** +// NAME: MbiCallbackOnDone +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnDone; +begin + if Assigned(AppOnDone) then + begin + AppOnDone; + end; +end; //** end of MbiCallbackOnDone *** + + +//*************************************************************************************** +// NAME: MbiCallbackOnError +// PARAMETER: info about the error that occured. +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnError(error: ShortString); +begin + if Assigned(AppOnError) then + begin + AppOnError(error); + end; +end; //** end of MbiCallbackOnError *** + + +//*************************************************************************************** +// NAME: MbiCallbackOnLog +// PARAMETER: info on the log event. +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnLog(info: ShortString); +begin + if Assigned(AppOnLog) then + begin + AppOnLog(info); + end; +end; //** end of MbiCallbackOnLog *** + + +//*************************************************************************************** +// NAME: MbiCallbackOnInfo +// PARAMETER: details on the info event. +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnInfo(info: ShortString); +begin + if Assigned(AppOnInfo) then + begin + AppOnInfo(info); + end; +end; //** end of MbiCallbackOnLog *** + + +//*************************************************************************************** +// NAME: LogData +// PARAMETER: pointer to byte array and the data length +// RETURN VALUE: none +// DESCRIPTION: Writes the program data formatted to the logfile +// +//*************************************************************************************** +procedure LogData(data : PByteArray; len : longword); stdcall; +var + currentWriteCnt : byte; + cnt : byte; + logStr : string; + bufferOffset : longword; +begin + bufferOffset := 0; + + while len > 0 do + begin + // set the current write length optimized to log 32 bytes per line + currentWriteCnt := len mod 32; + if currentWriteCnt = 0 then currentWriteCnt := 32; + logStr := ''; + + // prepare the line to add to the log + for cnt := 0 to currentWriteCnt-1 do + begin + logStr := logStr + Format('%2.2x ', [data[bufferOffset+cnt]]); + end; + + // update the log + MbiCallbackOnLog(logStr); + + // update loop variables + len := len - currentWriteCnt; + bufferOffset := bufferOffset + currentWriteCnt; + end; +end; //*** end of LogData *** + + +//*************************************************************************************** +// NAME: OnTimeout +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Timer event handler. A timer is used in this example to simulate the +// progress of a file download. It also demonstrates how to use the +// application callbacks to keep the application informed. +// +//*************************************************************************************** +procedure TEventHandlers.OnTimeout(Sender: TObject); +var + errorInfo : string; + progress : longword; + regionCnt : longword; + currentWriteCnt : word; + bufferOffset : longword; + addr : longword; + len : longword; + dataSizeKB : real; +begin + timer.Enabled := False; + + // connect the transport layer + MbiCallbackOnLog('Connecting the transport layer. t='+TimeToStr(Time)); + loader.Connect; + + //---------------- start the programming session -------------------------------------- + MbiCallbackOnLog('Starting the programming session. t='+TimeToStr(Time)); + if not loader.StartProgrammingSession then + begin + // update the user info + MbiCallbackOnInfo('Could not connect. Please reset your target...'); + MbiCallbackOnLog('Connect failed. Switching to backdoor entry mode. t='+TimeToStr(Time)); + Application.ProcessMessages; + end; + + while not loader.StartProgrammingSession do + begin + Application.ProcessMessages; + Sleep(5); + if stopRequest then + begin + MbiCallbackOnError('Programming session cancelled by user.'); + Exit; + end; + end; + + // still here so programming session was started + MbiCallbackOnLog('Programming session started. t='+TimeToStr(Time)); + + // create the datafile object + datafile := TXcpDataFile.Create(progfile); + + // compute the size in kbytes + dataSizeKB := datafile.GetDataCnt / 1024; + + // Call application callback when we start the actual download + MbiCallbackOnStarted(datafile.GetDataCnt); + + // Init progress to 0 progress + progress := 0; + MbiCallbackOnProgress(progress); + + //---------------- next clear the memory regions -------------------------------------- + // update the user info + MbiCallbackOnInfo('Erasing memory...'); + + for regionCnt := 0 to datafile.GetRegionCnt-1 do + begin + // obtain the region info + datafile.GetRegionInfo(regionCnt, addr, len); + + // erase the memory + MbiCallbackOnLog('Clearing Memory '+Format('addr:0x%x,len:0x%x',[addr,len])+'. t='+TimeToStr(Time)); + if not loader.ClearMemory(addr, len) then + begin + loader.GetLastError(errorInfo); + MbiCallbackOnLog('Could not clear memory ('+errorInfo+'). t='+TimeToStr(Time)); + MbiCallbackOnError('Could not clear memory ('+errorInfo+').'); + datafile.Free; + Exit; + end; + MbiCallbackOnLog('Memory cleared. t='+TimeToStr(Time)); + end; + + //---------------- next program the memory regions ------------------------------------ + for regionCnt := 0 to datafile.GetRegionCnt-1 do + begin + // update the user info + MbiCallbackOnInfo('Reading file...'); + + // obtain the region info + datafile.GetRegionInfo(regionCnt, addr, len); + // dynamically allocated buffer memory + SetLength(progdata, len); + // obtain the regiond data + datafile.GetRegionData(regionCnt, progdata); + + bufferOffset := 0; + while len > 0 do + begin + // set the current write length taking into account kMaxProgLen + currentWriteCnt := len mod kMaxProgLen; + if currentWriteCnt = 0 then currentWriteCnt := kMaxProgLen; + + // program the data + MbiCallbackOnLog('Programming Data '+Format('addr:0x%x,len:0x%x',[addr,currentWriteCnt])+'. t='+TimeToStr(Time)); + LogData(@progdata[bufferOffset], currentWriteCnt); + + if not loader.WriteData(addr, currentWriteCnt, @progdata[bufferOffset]) then + begin + loader.GetLastError(errorInfo); + MbiCallbackOnLog('Could not program data ('+errorInfo+'). t='+TimeToStr(Time)); + MbiCallbackOnError('Could not program data ('+errorInfo+').'); + datafile.Free; + Exit; + end; + MbiCallbackOnLog('Data Programmed. t='+TimeToStr(Time)); + + // update progress + progress := progress + currentWriteCnt; + MbiCallbackOnProgress(progress); + + // update loop variables + len := len - currentWriteCnt; + addr := addr + currentWriteCnt; + bufferOffset := bufferOffset + currentWriteCnt; + + // update the user info + MbiCallbackOnInfo('Programming data... ' + Format('(%.1n of %.1n Kbytes)',[(progress/1024), dataSizeKB])); + + end; + end; + + //---------------- stop the programming session --------------------------------------- + MbiCallbackOnLog('Stopping the programming session. t='+TimeToStr(Time)); + if not loader.StopProgrammingSession then + begin + loader.GetLastError(errorInfo); + MbiCallbackOnLog('Could not stop the programming session ('+errorInfo+'). t='+TimeToStr(Time)); + MbiCallbackOnError('Could not stop the programming session ('+errorInfo+').'); + datafile.Free; + Exit; + end; + MbiCallbackOnLog('Programming session stopped. t='+TimeToStr(Time)); + + // all done so set progress to 100% and finish up + progress := datafile.GetDataCnt; + datafile.Free; + MbiCallbackOnProgress(progress); + MbiCallbackOnLog('File successfully downloaded t='+TimeToStr(Time)); + MbiCallbackOnDone; + +end; //*** end of OnTimeout *** + + +//*************************************************************************************** +// NAME: MbiInit +// PARAMETER: callback function pointers +// RETURN VALUE: none +// DESCRIPTION: Called by the application to initialize the interface library. +// +//*************************************************************************************** +procedure MbiInit(cbStarted: TStartedEvent; cbProgress: TProgressEvent; + cbDone: TDoneEvent; cbError: TErrorEvent; cbLog: TLogEvent; + cbInfo: TInfoEvent); stdcall; +begin + //--- begin of don't change --- + AppOnStarted := cbStarted; + AppOnProgress := cbProgress; + AppOnDone := cbDone; + AppOnLog := cbLog; + AppOnInfo := cbInfo; + AppOnError := cbError; + //--- end of don't change --- + + // create xcp loader object + loader := TXcpLoader.Create; + + // update to the latest configuration + loader.Configure(ExtractFilePath(ParamStr(0))+'openblt_can_peak.ini'); + + // create and init a timer + events := TEventHandlers.Create; + timer := TTimer.Create(nil); + timer.Enabled := False; + timer.Interval := 100; + timer.OnTimer := events.OnTimeout; +end; //*** end of MbiInit *** + + +//*************************************************************************************** +// NAME: MbiStart +// PARAMETER: filename of the file that is to be downloaded. +// RETURN VALUE: none +// DESCRIPTION: Called by the application to request the interface library to download +// the file that is passed as a parameter. +// +//*************************************************************************************** +procedure MbiStart(fileName: ShortString); stdcall; +begin + // update the user info + MbiCallbackOnInfo(''); + + // start the log + MbiCallbackOnLog('--- Downloading "'+fileName+'" ---'); + + // reset stop request + stopRequest := false; + + // start the startup timer which gives microBoot a chance to paint itself + timer.Enabled := True; + + // store the program's filename + progfile := fileName; +end; //*** end of MbiStart *** + + +//*************************************************************************************** +// NAME: MbiStop +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Called by the application to request the interface library to stop +// a download that could be in progress. +// +//*************************************************************************************** +procedure MbiStop; stdcall; +begin + // set stop request + stopRequest := true; + + // disconnect the transport layer + MbiCallbackOnLog('Disconnecting the transport layer. t='+TimeToStr(Time)); + loader.Disconnect; +end; //*** end of MbiStop *** + + +//*************************************************************************************** +// NAME: MbiDeInit +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Called by the application to uninitialize the interface library. +// +//*************************************************************************************** +procedure MbiDeInit; stdcall; +begin + // release xcp loader object + loader.Free; + + // release the timer and events object + timer.Free; + events.Free; + + //--- begin of don't change --- + AppOnStarted := nil; + AppOnProgress := nil; + AppOnDone := nil; + AppOnLog := nil; + AppOnInfo := nil; + AppOnError := nil; + //--- end of don't change --- +end; //*** end of MbiDeInit *** + + +//*************************************************************************************** +// NAME: MbiName +// PARAMETER: none +// RETURN VALUE: name of the interface library +// DESCRIPTION: Called by the application to obtain the name of the interface library. +// +//*************************************************************************************** +function MbiName : ShortString; stdcall; +begin + Result := 'OpenBLT CAN Peak'; +end; //*** end of MbiName *** + + +//*************************************************************************************** +// NAME: MbiDescription +// PARAMETER: none +// RETURN VALUE: description of the interface library +// DESCRIPTION: Called by the application to obtain the description of the interface +// library. +// +//*************************************************************************************** +function MbiDescription : ShortString; stdcall; +begin + Result := 'OpenBLT using Peak CAN Interface'; +end; //*** end of MbiDescription *** + + +//*************************************************************************************** +// NAME: MbiVersion +// PARAMETER: none +// RETURN VALUE: version number +// DESCRIPTION: Called by the application to obtain the version number of the +// interface library. +// +//*************************************************************************************** +function MbiVersion : Longword; stdcall; +begin + Result := 10000; // v1.00.00 +end; //*** end of MbiVersion *** + + +//*************************************************************************************** +// NAME: MbiVInterface +// PARAMETER: none +// RETURN VALUE: version number of the supported interface +// DESCRIPTION: Called by the application to obtain the version number of the +// Mbi interface uBootInterface.pas (not the interface library). This can +// be used by the application for backward compatibility. +// +//*************************************************************************************** +function MbiVInterface : Longword; stdcall; +begin + Result := 10001; // v1.00.01 +end; //*** end of MbiVInterface *** + + +//*************************************************************************************** +// NAME: MbiConfigure +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Called by the application to enable the user to configure the inter- +// face library through the application. +// +//*************************************************************************************** +procedure MbiConfigure; stdcall; +var + settings : TXcpSettings; +begin + // create xcp settings object + settings := TXcpSettings.Create(ExtractFilePath(ParamStr(0))+'openblt_can_peak.ini'); + + // display the modal configuration dialog + settings.Configure; + + // release the xcp settings object + settings.Free; + + // update to the latest configuration + loader.Configure(ExtractFilePath(ParamStr(0))+'openblt_can_peak.ini'); +end; //*** end of MbiConfigure *** + + +//*************************************************************************************** +// External Declarations +//*************************************************************************************** +exports + //--- begin of don't change --- + MbiInit index 1, + MbiStart index 2, + MbiStop index 3, + MbiDeInit index 4, + MbiName index 5, + MbiDescription index 6, + MbiVersion index 7, + MbiConfigure index 8, + MbiVInterface index 9; + //--- end of don't change --- + +end. +//********************************** end of openblt_can_peak.dpr ************************ diff --git a/Host/Source/interfaces/can/vector/CANIcon.bmp b/Host/Source/interfaces/can/vector/CANIcon.bmp new file mode 100644 index 00000000..6ca58cdf Binary files /dev/null and b/Host/Source/interfaces/can/vector/CANIcon.bmp differ diff --git a/Host/Source/interfaces/can/vector/CANdrvD.pas b/Host/Source/interfaces/can/vector/CANdrvD.pas new file mode 100644 index 00000000..52e0b9d8 --- /dev/null +++ b/Host/Source/interfaces/can/vector/CANdrvD.pas @@ -0,0 +1,740 @@ +unit CANdrvD; +//*************************************************************************************** +// Project Name: TCanDriver component for Borland Delphi +// Description: Encapsulates Vector's CANlib v4.3 into a VCL component +// File Name: CANdrvD.pas +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** +interface + + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, CANlibD; + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +type + TChannel = ( channel0, channel1 ); + THardware = ( Virtual, CANcardX, CANcardXL, CANcaseXL, CANboardXL, + CANboardXL_Compact, CANac2, CANac2Pci, CANpari, CANdongle, + CANcard, CANcardY, CANcard2, EDICcard ); + TDirection = ( Tx, Rx ); + TCanMsg = packed record + id : LongInt; + dlc : Byte; + data : array [0..MAX_MSG_LEN-1] of Byte; + time : LongInt; + ext : Boolean; + end; + +type + TMessageEvent = procedure( Sender: TObject; Direction: TDirection; Message: TCanMsg ) of object; + TErrorFrameEvent = procedure( Sender: TObject; time: LongInt ) of object; + TBusOffEvent = procedure( Sender: TObject; time: LongInt ) of object; + +type + TCanEventThread = class(TThread) + private + { Private declarations } + FMethod: TThreadMethod; + protected + FEventHndl: LongInt; + procedure Execute; override; + public + property Method : TThreadMethod read FMethod write FMethod; + property EventHandle: LongInt read FEventHndl write FEventHndl; + end; + +type + TCanDriver = class(TComponent) + private + { Private declarations } + FPortHandle : VPortHandle; + FChannelMask : Vaccess; + FPermissionMask: Vaccess; + FCanEventThread: TCanEventThread; + FThreadRunning : boolean; + FEventHandle : LongInt; + function IsThreadRunning: boolean; + procedure ProcessEvents; + procedure CopyMessage(event: Vevent; var msg: TCanMsg); + protected + { Protected declarations } + FBaudRate : LongInt; + FChannel : TChannel; + FHardware : THardware; + FFilterMask : LongInt; + FFilterCode : LongInt; + FPriority : TThreadPriority; + FExtendedId : Boolean; + FOnMessage : TMessageEvent; + FOnErrorFrame: TErrorFrameEvent; + FOnBusOff : TBusOffEvent; + procedure SetBaudRate( Value: LongInt ); + procedure SetChannel( Value: TChannel ); + procedure SetHardware( Value: THardware ); + procedure SetFilterMask( Value: LongInt ); + procedure SetFilterCode( Value: LongInt ); + procedure SetPriority( Value: TThreadPriority ); + procedure SetExtendedId( Value: Boolean ); + public + { Public declarations } + constructor Create( AOwner: TComponent ); override; + destructor Destroy; override; + function Connect: boolean; virtual; + procedure Disconnect; virtual; + function Transmit( Message: TCanMsg): boolean; virtual; + function IsConnected: boolean; virtual; + published + { Published declarations } + property BaudRate : LongInt read FBaudRate write SetBaudRate default 500000; + property Channel : TChannel read FChannel write SetChannel default channel0; + property Hardware : THardware read FHardware write SetHardware default Virtual; + property FilterMask : LongInt read FFilterMask write SetFilterMask default 0; + property FilterCode : LongInt read FFilterCode write SetFilterCode default 0; + property Priority : TThreadPriority read FPriority write SetPriority default tpNormal; + property ExtendedId : Boolean read FExtendedId write SetExtendedId default False; + property OnMessage : TMessageEvent read FOnMessage write FOnMessage; + property OnErrorFrame: TErrorFrameEvent read FOnErrorFrame write FOnErrorFrame; + property OnBusOff : TBusOffEvent read FOnBusOff write FOnBusOff; + end; + + +//*************************************************************************************** +// Prototypes +//*************************************************************************************** +procedure Register; + +implementation +//*************************************************************************************** +// Constants +//*************************************************************************************** +const + Channels: array[channel0..channel1] of integer = ( 0, 1 ); + HardwareTypes: array[Virtual..EDICcard] of integer = ( + HWTYPE_VIRTUAL, HWTYPE_CANCARDX, HWTYPE_CANCARDXL, HWTYPE_CANCASEXL, HWTYPE_CANBOARDXL, + HWTYPE_CANBOARDXL_COMPACT, HWTYPE_CANAC2, HWTYPE_CANAC2PCI, HWTYPE_CANPARI, + HWTYPE_CANDONGLE, HWTYPE_CANCARD, HWTYPE_CANCARDY, HWTYPE_CANCARD2, HWTYPE_EDICCARD); + + +//*************************************************************************************** +// NAME: Execute +// PRECONDITIONS: none +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Overriden Execute function for the CanEventThread. Calls and synchro- +// nizes with the TCanDriver.ProcessEvents function. +// +//*************************************************************************************** +procedure TCanEventThread.Execute; +begin + while not Terminated do + begin + if FEventHndl <> 0 then // make sure event is configured + begin + // wait for receive event + WaitForSingleObject(FEventHndl, 1000); + + if Assigned(Method) then // make sure TCanDriver.ProcessEvents is set + Synchronize(Method); // call and synchronize + end; + end; +end; //*** end of Execute *** + + +//*************************************************************************************** +// NAME: Create +// PRECONDITIONS: none +// PARAMETER: AOwner : owner of the component +// RETURN VALUE: none +// DESCRIPTION: Component constructor. Calls TComponent's constructor and initializes +// the private property variables to their default values. +// +//*************************************************************************************** +constructor TCanDriver.Create( AOwner: TComponent ); +begin + // call inherited constructor + inherited Create( AOwner ); + + // set defaults for internal variables + FPortHandle := INVALID_PORTHANDLE; + FChannelMask := 0; + FPermissionMask:= 0; + FThreadRunning := False; + FEventHandle := 0; + + // set defaults for properties + FBaudRate := 500000; + FChannel := channel0; + FHardware := Virtual; + FFilterMask := 0; + FFilterCode := 0; + FPriority := tpNormal; + FExtendedId := False; +end; //*** end of Create *** + + +//*************************************************************************************** +// NAME: Destroy +// PRECONDITIONS: none +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Component destructor. Calls TComponent's destructor +// +//*************************************************************************************** +destructor TCanDriver.Destroy; +begin + Disconnect; // close the port and driver + inherited Destroy; // call inherited destructor +end; //*** end of Destroy *** + + +//*************************************************************************************** +// NAME: IsConnected +// PRECONDITIONS: none +// PARAMETER: none +// RETURN VALUE: True or False +// DESCRIPTION: Determines whether or not the CAN driver is connected and active +// +//*************************************************************************************** +function TCanDriver.IsConnected: boolean; +begin + if FPortHandle <> INVALID_PORTHANDLE then + Result := True + else + Result := False; +end; //*** end of IsConnected *** + + +//*************************************************************************************** +// NAME: IsThreadRunning +// PRECONDITIONS: none +// PARAMETER: none +// RETURN VALUE: True or False +// DESCRIPTION: Determines whether or not the CAN event thread is running +// +//*************************************************************************************** +function TCanDriver.IsThreadRunning: boolean; +begin + if FThreadRunning = True then + Result := True + else + Result := False; +end; //*** end of IsThreadRunning *** + + +//*************************************************************************************** +// NAME: CopyMessage +// PRECONDITIONS: none +// PARAMETER: event: msg tx or rx event information (source) +// msg: buffer to copy message to (destination) +// RETURN VALUE: none +// DESCRIPTION: Copies a CAN message from an event type to a TCanMsg type. +// +//*************************************************************************************** +procedure TCanDriver.CopyMessage(event: Vevent; var msg: TCanMsg); +var + cnt: integer; +begin + if (event.msg.id and EXT_MSG) = EXT_MSG then // 29-bit id? + begin + msg.id := (event.msg.id and not EXT_MSG); // reset ext bit + msg.ext := True; // this is an 29-bit id + end + else + begin + msg.id := event.msg.id; // store id + msg.ext := False; // this is an 11-bit id + end; + msg.dlc := event.msg.dlc; + msg.time := event.timeStamp; + + // copy the data bytes + for cnt :=0 to MAX_MSG_LEN-1 do + begin + if cnt < event.msg.dlc then + msg.data[cnt] := event.msg.data[cnt] + else + msg.data[cnt] := 0; + end; +end; //*** end of CopyMessage *** + + +//*************************************************************************************** +// NAME: SetBaudRate +// PRECONDITIONS: none +// PARAMETER: Value : new baudrate value [0 - 1000000 bps] +// RETURN VALUE: none +// DESCRIPTION: Configures the baudrate +// +// |------------------------------------------------------------------------------------ +// | Update baudrate configuration +// |------------------------------------------------------------------------------------ +//*************************************************************************************** +procedure TCanDriver.SetBaudRate( Value: LongInt ); +begin + FBaudRate := Value; // update property +end; //*** end of SetBaudRate *** + + +//*************************************************************************************** +// NAME: SetChannel +// PRECONDITIONS: none +// PARAMETER: Value : channel0 or channel1 +// RETURN VALUE: none +// DESCRIPTION: Configures the used CAN channel +// +// |------------------------------------------------------------------------------------ +// | Update channel configuration +// |------------------------------------------------------------------------------------ +//*************************************************************************************** +procedure TCanDriver.SetChannel( Value: TChannel ); +begin + FChannel := Value; +end; //*** end of SetChannel *** + + +//*************************************************************************************** +// NAME: SetHardware +// PRECONDITIONS: none +// PARAMETER: Value : type of CAN hardware (Virtual, CANcardXL, etc.) +// RETURN VALUE: none +// DESCRIPTION: Configures the used CAN hardware +// +// |------------------------------------------------------------------------------------ +// | Update hardware configuration +// |------------------------------------------------------------------------------------ +//*************************************************************************************** +procedure TCanDriver.SetHardware( Value: THardware ); +begin + FHardware := Value; +end; //*** end of SetHardware *** + + +//*************************************************************************************** +// NAME: SetFilterMask +// PRECONDITIONS: none +// PARAMETER: Value : acceptance filter mask +// RETURN VALUE: none +// DESCRIPTION: Configures the acceptance filter mask for the CAN channel +// +// |------------------------------------------------------------------------------------ +// | Update filter mask value +// |------------------------------------------------------------------------------------ +//*************************************************************************************** +procedure TCanDriver.SetFilterMask( Value: LongInt ); +begin + FFilterMask := Value; +end; //*** end of SetFilterMask *** + + +//*************************************************************************************** +// NAME: SetFilterCode +// PRECONDITIONS: none +// PARAMETER: Value : acceptance filter code +// RETURN VALUE: none +// DESCRIPTION: Configures the acceptance filter code for the CAN channel +// +// |------------------------------------------------------------------------------------ +// | Update filter code value +// |------------------------------------------------------------------------------------ +//*************************************************************************************** +procedure TCanDriver.SetFilterCode( Value: LongInt ); +begin + FFilterCode := Value; +end; //*** end of SetFilterCode *** + + +//*************************************************************************************** +// NAME: SetPriority +// PRECONDITIONS: none +// PARAMETER: Value : thread priority +// RETURN VALUE: none +// DESCRIPTION: Configures the priority for the CAN event thread +// +// |------------------------------------------------------------------------------------ +// | y\ Is Thread running? /n +// |------------------------------------------------------------------------------------ +// | Stop Thread | +// | Update Thread priority | Update Thread priority +// | Restart Thread | +// |------------------------------------------------------------------------------------ +//*************************************************************************************** +procedure TCanDriver.SetPriority( Value: TThreadPriority ); +begin + if IsThreadRunning then + begin + FCanEventThread.Suspend; // suspend the thread + FPriority := Value; // update the priority + FCanEventThread.Resume; // resume the thread + end + else + begin + FPriority := Value; // update the priority + end; +end; //*** end of SetPriority *** + + +//*************************************************************************************** +// NAME: SetExtendedId +// PRECONDITIONS: none +// PARAMETER: Value : true = support only 29-bit id's, false = support only 11-bit +// RETURN VALUE: none +// DESCRIPTION: Configures the support of extended 29-bit identifiers +// +// |------------------------------------------------------------------------------------ +// | Update extended id support selection +// |------------------------------------------------------------------------------------ +//*************************************************************************************** +procedure TCanDriver.SetExtendedId( Value: Boolean ); +begin + FExtendedId := Value; +end; //*** end of SetExtendedId ***/ + + +//*************************************************************************************** +// NAME: Connect +// PRECONDITIONS: Disconnected from CAN bus +// PARAMETER: none +// RETURN VALUE: True or False for succees or error, respectively +// DESCRIPTION: Initializes the CAN driver and synchronizes the hardware with the CAN +// bus. +// +// |------------------------------------------------------------------------------------ +// | y\ Connected? /n +// |------------------------------------------------------------------------------------ +// | Open the driver (ncdOpenDriver) +// | Obtain mask to channel (ncdGetChannelMask) +// | Open the port using this mask (ncdOpenPort) +// |------------------------------------------------------------------------------------ +// | y\ Permission to change settings? /n +// |------------------------------------------------------------------------------------ +// | Configure baudrate (ncdSetChannelBitrate) | +// |------------------------------------------------------------------------------------ +// | Configure acceptance filter (ncdSetChannelAcceptance) +// | Enable error frames and chipstate events (ncdSetReceiveMode) +// | Create synchronizatio object (ncdSetNotification) +// | Reset internal clock (ncdResetClock) +// | Sync to the CAN bus (ncdActivateChannel) +// | Empty transmit and receive queue's (ncdFlushXxxQueue) +// |------------------------------------------------------------------------------------ +// | y\ Errors occurred during init? /n +// |------------------------------------------------------------------------------------ +// | y\ Port opened? /n | +// |-------------------------------------------------------------| Start CAN event thread +// | Close port (ncdClosePort) | | Return TRUE +// |-------------------------------------------------------------| +// | Return FALSE | +// |------------------------------------------------------------------------------------ +//*************************************************************************************** +function TCanDriver.Connect: boolean; +var + vErr : Vstatus; + acc : VsetAcceptance; +label + error; +begin + // reset internal variables + FPortHandle := INVALID_PORTHANDLE; + FChannelMask := 0; + FPermissionMask:= 0; + FThreadRunning := False; + FEventHandle := 0; + + //-------------------------- open the driver ------------------------------------------ + vErr := ncdOpenDriver; + if vErr <> VSUCCESS then goto error; + + //-------------------------- select a channel ----------------------------------------- + FChannelMask := ncdGetChannelMask(HardwareTypes[FHardware], 0, Channels[FChannel]); + if FChannelMask=0 then goto error; + + //-------------------------- open a port ---------------------------------------------- + FPermissionMask := FChannelMask; + vErr := ncdOpenPort(FPortHandle, 'TCanDriver0', FChannelMask, FPermissionMask, + FPermissionMask, 1024); + if vErr <> VSUCCESS then goto error; + + //-------------------------- set baudrate --------------------------------------------- + if FPermissionMask<>0 then + begin + vErr := ncdSetChannelBitrate(FPortHandle, FPermissionMask, FBaudRate); + if vErr <> VSUCCESS then goto error; + end; + + //-------------------------- set the acceptance filter -------------------------------- + acc.mask := FFilterMask; + acc.code := FFilterCode; + if FExtendedId = True then // 29-bit id used? + begin + acc.mask := acc.mask or LongInt(EXT_MSG); + acc.code := acc.code or LongInt(EXT_MSG); + end; + vErr := ncdSetChannelAcceptance(FPortHandle, FChannelMask, acc); + if vErr <> VSUCCESS then goto error; + + //-------------------------- enable error frames and chipstate events ----------------- + vErr := ncdSetReceiveMode(FPortHandle, 0, 0); + if vErr <> VSUCCESS then goto error; + + //-------------------------- create synchronisation object ---------------------------- + FEventHandle := CreateEvent(nil, FALSE, FALSE, nil); + if FEventHandle = 0 then goto error; + vErr := ncdSetNotification(FPortHandle, FEventHandle, 1); + if vErr<>VSUCCESS then goto error; + + //-------------------------- reset the clock ------------------------------------------ + vErr := ncdResetClock(FPortHandle); + if vErr <> VSUCCESS then goto error; + + //-------------------------- sync with bus -------------------------------------------- + vErr := ncdActivateChannel(FPortHandle, FChannelMask); + if vErr <> VSUCCESS then goto error; + + //-------------------------- flush queue's -------------------------------------------- + vErr := ncdFlushReceiveQueue(FPortHandle); + if vErr <> VSUCCESS then goto error; + vErr := ncdFlushTransmitQueue(FPortHandle, FChannelMask); + if vErr <> VSUCCESS then goto error; + + //-------------------------- start CAN event thread ----------------------------------- + FCanEventThread := TCanEventThread.Create(True); // create and suspend + FCanEventThread.FreeOnTerminate := True; // auto free on termination + FCanEventThread.Method := ProcessEvents; // set method + FCanEventThread.FEventHndl := FEventHandle; // set event handle + FCanEventThread.Resume; // start + FThreadRunning := True; + + //-------------------------- success -------------------------------------------------- + Result := True; // successfully initialized the driver + exit; // stop here + + //-------------------------- error occurred ------------------------------------------- + error: + if FEventHandle <> 0 then + CloseHandle(FEventHandle); + if FPortHandle <> INVALID_PORTHANDLE then + begin + ncdClosePort(FPortHandle); + FPortHandle := INVALID_PORTHANDLE; + end; + Result := False; +end; //*** end of Connect *** + + +//*************************************************************************************** +// NAME: Disconnect +// PRECONDITIONS: none +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Disconnects the CAN driver +// +// |------------------------------------------------------------------------------------ +// | y\ Connected? /n +// |------------------------------------------------------------------------------------ +// | Deactivate the channel (ncdDeactivateChannel) | +// | Close port (ncdClosePort) | +// |------------------------------------------------------------------------------------ +// | Close the driver (ncdCloseDriver) +// |------------------------------------------------------------------------------------ +// | y\ CAN event thread active? /n +// |------------------------------------------------------------------------------------ +// | Stop CAN event thread | +// |------------------------------------------------------------------------------------ +//*************************************************************************************** +procedure TCanDriver.Disconnect; +begin + if IsConnected = True then begin // are we connected? + ncdDeactivateChannel(FPortHandle, FChannelMask); // deactivate channel + if FEventHandle <> 0 then + CloseHandle(FEventHandle); + ncdClosePort(FPortHandle); // close the port + FPortHandle := INVALID_PORTHANDLE; // invalidate handle + end; + ncdCloseDriver; // close the driver + if IsThreadRunning then + begin + FCanEventThread.FEventHndl := 0; // reset event handle + FCanEventThread.Terminate; // stop + FThreadRunning := False; + end; +end; //*** end of Disconnect *** + + +//*************************************************************************************** +// NAME: Transmit +// PRECONDITIONS: Driver initialized using 'Connect' +// PARAMETER: Message: CAN message that is to be transmitted +// RETURN VALUE: True or False for succees or error, respectively +// DESCRIPTION: Transmits a CAN message. +// +// |------------------------------------------------------------------------------------ +// | y\ Connected? /n +// |------------------------------------------------------------------------------------ +// | Transmit message using ncdTransmit | +// |----------------------------------------------| Return FALSE +// | Return TRUE | +// |------------------------------------------------------------------------------------ +//*************************************************************************************** +function TCanDriver.Transmit( Message: TCanMsg): boolean; +var + vErr : Vstatus; + event : Vevent; + cnt : integer; +begin + // make sure the CAN driver is connected + if not IsConnected then + begin + Result := False; // can't transmit it not connected + exit; // no need to continue + end; + + // configure message as tx with acknowledge + event.tag := V_TRANSMIT_MSG; + event.msg.flags := MSGFLAG_TX; + + // set the message identifier + if Message.ext = True then + event.msg.id := Message.id or LongInt(EXT_MSG) + else + event.msg.id := Message.id; + + // set the data length + event.msg.dlc := Message.dlc; + + // store the data bytes + for cnt :=0 to MAX_MSG_LEN-1 do + begin + event.msg.data[cnt] := Message.data[cnt]; + end; + + vErr := ncdTransmit(FPortHandle, FChannelMask, event); + + if vErr <> VSUCCESS then + Result := False + else + Result := True; +end; //*** end of Transmit *** + + +//*************************************************************************************** +// NAME: ProcessEvents +// PRECONDITIONS: thread running +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Called by the CAN event tread. This function traps and processes CAN +// events for OnMessage, OnBusOff, and OnErrorFrame. +// +//*************************************************************************************** +procedure TCanDriver.ProcessEvents; +var + vErr : Vstatus; + pEvent : PVEvent; + msg : TCanMsg; +begin + while True do + begin + vErr := ncdReceive1(FPortHandle, pEvent); + + if (vErr<>VSUCCESS) and (vErr<>VERR_QUEUE_IS_EMPTY) then break; + if vErr=VERR_QUEUE_IS_EMPTY then break; + + case pEvent^.tag of + V_RECEIVE_MSG, V_TRANSMIT_MSG: + begin + if (pEvent^.msg.flags and MSGFLAG_ERROR_FRAME) = MSGFLAG_ERROR_FRAME then + begin + //---------------- process errorframe ----------------------------------------- + if Assigned( FOnErrorFrame ) then + begin + FOnErrorFrame( Self, pEvent^.timeStamp ); // call application's event handler + end; + end + else if pEvent^.msg.flags = 0 then // msg rx indication + begin + //---------------- process reception indication ------------------------------- + CopyMessage(pEvent^, msg); + if Assigned( FOnMessage ) then + begin + FOnMessage( Self, Rx, msg ); // call application's event handler + end; + end + else if (pEvent^.msg.flags and MSGFLAG_TX) = MSGFLAG_TX then // msg tx confirmation + begin + //---------------- process transmission confirmation -------------------------- + CopyMessage(pEvent^, msg); + if Assigned( FOnMessage ) then + begin + FOnMessage( Self, Tx, msg ); // call application's event handler + end; + end; + end; + V_CHIP_STATE: + begin + if (pEvent^.chipState.busStatus and CHIPSTAT_BUSOFF) = CHIPSTAT_BUSOFF then + begin + //---------------- process bus off event -------------------------------------- + if Assigned( FOnBusOff ) then + begin + FOnBusOff( Self, pEvent^.timeStamp ); // call application's event handler + end; + end; + end; + end; + end; +end; //*** end of ProcessEvents *** + + +//*************************************************************************************** +// NAME: Register +// PRECONDITIONS: none +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Registers the TCanDriver component into Borland Delphi's IDE. +// +//*************************************************************************************** +procedure Register; +begin + RegisterComponents('Feaser', [TCanDriver]); +end; //*** end of Register *** + + +end. +//********************************** end of CANdrvD.pas ********************************* + + diff --git a/Host/Source/interfaces/can/vector/CANlibD.pas b/Host/Source/interfaces/can/vector/CANlibD.pas new file mode 100644 index 00000000..e6e6a3af --- /dev/null +++ b/Host/Source/interfaces/can/vector/CANlibD.pas @@ -0,0 +1,959 @@ +unit CANlibD; + +(*---------------------------------------------------------------------------- +| File: +| CANlibD.pas +| Project: +| Unit for Delphi32 samples (V2.0) +| +|----------------------------------------------------------------------------- +| Ported from cantrace.c by Torsten Lang +|----------------------------------------------------------------------------- +| Copyright (c) 1998 BSK Datentechnik GmbH, Kiesacker 14, 35418 Buseck / +| 1998 by Vector Informatik GmbH, Friolzheimer Str. 6, 70499 Stuttgart +| All rights reserved. +| +| BSK Datentechnik rumt der Vector Informatik GmbH das nicht ausschlieliche Recht +| ein, CANlibD.pas fr eigene Zwecke zu nutzen. Vector ist es gestattet, die +| Software zu kopieren, abzundern, zu erweitern, weiterzugeben und in Software von +| Vector zu integrieren. Im Quelltext enthaltene Copyright-Hinweise drfen hierbei +| nicht entfernt oder gendert werden. +| Vector darf aus von ihm vorgenommenen Anpassungen und/oder Erweiterungen der +| CANlibD.pas keine Rechte an irgendwelchen Teilen der Software gegenber BSK +| Datentechnik geltend machen. + ----------------------------------------------------------------------------*) + +{ environment switches } +(******************************************************************************* +Attention: +1. All functions that use pointers to structures (either explicitly or by using + var parameters) may change the contents of the structures right after the + funtction returns. +*******************************************************************************) +{$ifdef WIN32} +{$define CanLib4Delphi32} +{$else} +{$ifdef CONSOLE} +{$define CanLib4Delphi32} +{$endif} +{$endif} + +{ public interface } + +interface + +type + ncdStringType = PChar; + Vstatus = Word; + +const + MAX_APPNAME = 32; + + VCAN_WAIT = 0; + VCAN_POLL = 1; + {$ifdef CanLib4Delphi32} + { Attention: This exists only under Win32 } + VCAN_NOTIFY = 2; + {$endif} + + VSUCCESS = 0; + VPENDING = 1; + VERROR = 255; + VERR_QUEUE_IS_EMPTY = 10; + VERR_QUEUE_IS_FULL = 11; + VERR_TX_NOT_POSSIBLE = 12; + VERR_NO_LICENSE = 14; + VERR_WRONG_PARAMETER = 101; + VERR_TWICE_REGISTER = 110; + VERR_INVALID_CHAN_INDEX = 111; + VERR_INVALID_ACCESS = 112; + VERR_PORT_IS_OFFLINE = 113; + VERR_CHAN_IS_ONLINE = 116; + VERR_INVALID_PORT = 118; + VERR_HW_NOT_READY = 120; + VERR_CMD_TIMEOUT = 121; + VERR_HW_NOT_PRESENT = 129; + VERR_NOTIFY_ALREADY_ACTIVE = 131; + VERR_CANNOT_OPEN_DRIVER = 201; + +{ +//------------------------------------------------------------------------------ +// accessmask +} +type + Vaccess = LongInt; { unsigned long doesn't exist for Delphi32 / Borland Pascal 7! } + +{ +//------------------------------------------------------------------------------ +// porthandle +} + +const + INVALID_PORTHANDLE = -1; + +type + VportHandle = LongInt; + +{ +//------------------------------------------------------------------------------ +// acceptance filter +} + +type + VsetAcceptance = packed record + code : LongInt; {unsigned long doesn't exist!} + mask : LongInt; {unsigned long doesn't exist!} + end; + PVsetAcceptance = ^VsetAcceptance; + +{ +//------------------------------------------------------------------------------ +// bit timing +} + +type + VchipParams = packed record + bitRate : LongInt; {unsigned long doesn't exist!} + sjw : Byte; + tseg1 : Byte; + tseg2 : Byte; + sam : Byte; { 1 or 3 } + end; + PVchipParams = ^VchipParams; + +{ +//------------------------------------------------------------------------------ +// definitions for the events and commands used by the driver +} + +const + V_RECEIVE_MSG = 1; + V_CHIP_STATE = 4; + V_CLOCK_OVERFLOW = 5; + V_TRIGGER = 6; + V_TIMER = 8; + V_TRANSCEIVER = 9; + V_TRANSMIT_MSG = 10; + +type + VeventTag = Byte; + +{ +//------------------------------------------------------------------------------ +// events +} + +{ +//------------------------------------------------------------------------------ +// structure for V_RECEIVE_MSG +} + +const + MAX_MSG_LEN = 8; + EXT_MSG = $80000000; { signs an extended identifier } + + MSGFLAG_ERROR_FRAME = $01; { Msg is a bus error } + MSGFLAG_OVERRUN = $02; { Msgs following this has been lost } + MSGFLAG_NERR = $04; { NERR active during this msg } + MSGFLAG_WAKEUP = $08; { Msg rcv'd in wakeup mode } + MSGFLAG_REMOTE_FRAME = $10; { Msg is a remote frame } + MSGFLAG_RESERVED_1 = $20; { Reserved for future usage } + MSGFLAG_TX = $40; { TX acknowledge } + MSGFLAG_TXRQ = $80; { TX request } + +type + _Vmsg = packed record + id : LongInt; {unsigned long doesn't exist!} + flags : Byte; + dlc : Byte; + data : array [0..MAX_MSG_LEN-1] of Byte; + end; { 14 Bytes } + _PVmsg = ^_Vmsg; + +{ +// structure for V_CHIP_STATE +} + +const + CHIPSTAT_BUSOFF = $01; + CHIPSTAT_ERROR_PASSIVE = $02; + CHIPSTAT_ERROR_WARNING = $04; + CHIPSTAT_ERROR_ACTIVE = $08; + +type + _VchipState = packed record + busStatus : Byte; + txErrorCounter : Byte; + rxErrorCounter : Byte; + end; + _PVchipState = ^_VchipState; + +{ +// structure for V_TRANSCEIVER +} + +const + TRANSCEIVER_EVENT_ERROR = 1; + TRANSCEIVER_EVENT_CHANGED = 2; + + TRANSCEIVER_TYPE_NONE = 0; + TRANSCEIVER_TYPE_251 = 1; + TRANSCEIVER_TYPE_252 = 2; + TRANSCEIVER_TYPE_DNOPTO = 3; + TRANSCEIVER_TYPE_W210 = 4; + + TRANSCEIVER_LINEMODE_NA = 0; + TRANSCEIVER_LINEMODE_TWO_LINE = 1; + TRANSCEIVER_LINEMODE_CAN_H = 2; + TRANSCEIVER_LINEMODE_CAN_L = 3; + + TRANSCEIVER_RESNET_NA = 0; + TRANSCEIVER_RESNET_MASTER = 1; + TRANSCEIVER_RESNET_MASTER_STBY = 2; + TRANSCEIVER_RESNET_SLAVE = 3; + +type + _Vtransceiver = packed record + event : Byte; { TRANSCEIVER_EVENT_xxx } + end; + _PVtransceiver = ^_Vtransceiver; + + Vevent = packed record + tag : VeventTag; { 1 } + chanIndex : Byte; { 1 } + _transId : Byte; { 1 not implemented yet !!!! } + portHandle : Byte; { 1 internal use only !!!! } + timeStamp : LongInt; { 4 } { unsigned long doesn't exist! } + case {tagData:}Byte of + 0 : (msg : _Vmsg); + 1 : (chipState : _VchipState); + 2 : (transceiver : _Vtransceiver); + { 14 Bytes (_VMessage) } + end; + { -------- } + { 22 Bytes } + PVevent = ^Vevent; + +{ +//------------------------------------------------------------------------------ +// structure for SET_OUTPUT_MODE +} + +const + OUTPUT_MODE_SILENT = 0; + OUTPUT_MODE_NORMAL = 1; + +{ +//------------------------------------------------------------------------------ +// configuration +} + +{ +// defines for the supported hardware +} +const + HWTYPE_NONE = 0; + HWTYPE_VIRTUAL = 1; + HWTYPE_CANCARDX = 2; + HWTYPE_CANPARI = 3; + HWTYPE_CANDONGLE = 4; + HWTYPE_CANAC2 = 5; + HWTYPE_CANAC2PCI = 6; + HWTYPE_CANCARD = 7; + HWTYPE_CANCARDY = 12; + HWTYPE_CANCARDXL = 15; + HWTYPE_CANCARD2 = 17; + HWTYPE_EDICCARD = 19; + HWTYPE_CANCASEXL = 21; + HWTYPE_CANBOARDXL = 25; + HWTYPE_CANBOARDXL_COMPACT = 27; + MAX_HWTYPE = 27; + +{ +// defines for the tranceiver type +} +const + (* + TRANSCEIVER_TYPE_NONE = 0; + TRANSCEIVER_TYPE_251 = 1; + TRANSCEIVER_TYPE_252 = 2; + TRANSCEIVER_TYPE_DNOPTO = 3; + TRANSCEIVER_TYPE_W210 = 4; + *) { These have already been defined above } + MAX_TRANSCEIVER_TYPE = 4; + + MAX_CHAN_NAME = 31; + MAX_DRIVER_NAME = 31; + +type + VChannelConfig = packed record + name : array [0..MAX_CHAN_NAME] of Char; + hwType : Byte; { HWTYPE_xxxx (see above) } + hwIndex : Byte; { Index of the hardware (same type) (0,1,...) } + hwChannel : Byte; { Index of the channel (same hardware) (0,1,...) } + tranceiverType : Byte; { TRANCEIVER_TYPE_xxxx (see above) } + channelIndex : Byte; { Global channel index (0,1,...) } + channelMask : LongInt; { Global channel mask (=1<. +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** +interface + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, ComCtrls, ExtCtrls, IniFiles; + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +type + TXcpSettingsForm = class(TForm) + pnlFooter: TPanel; + btnOK: TButton; + btnCancel: TButton; + pageControl: TPageControl; + tabXcp: TTabSheet; + tabCan: TTabSheet; + iconCan: TImage; + lblCan: TLabel; + lblXcp: TLabel; + iconXcp2: TImage; + lblHardware: TLabel; + cmbHardware: TComboBox; + lblChannel: TLabel; + cmbChannel: TComboBox; + lblBaudRate: TLabel; + chbExtendedId: TCheckBox; + edtBaudRate: TEdit; + lblT1: TLabel; + lblT3: TLabel; + lblT4: TLabel; + lblT5: TLabel; + lblT7: TLabel; + edtT1: TEdit; + edtT3: TEdit; + edtT4: TEdit; + edtT5: TEdit; + edtT7: TEdit; + tabProt: TTabSheet; + iconXcp1: TImage; + lblPort: TLabel; + edtSeedKey: TEdit; + btnBrowse: TButton; + lblTransmitId: TLabel; + Label1: TLabel; + edtTransmitId: TEdit; + edtReceiveId: TEdit; + openDialog: TOpenDialog; + procedure btnOKClick(Sender: TObject); + procedure btnCancelClick(Sender: TObject); + procedure btnBrowseClick(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + end; + +type + TXcpSettings = class(TObject) + private + FSettingsForm : TXcpSettingsForm; + FIniFile : string; + public + constructor Create(iniFile : string); + destructor Destroy; override; + function Configure : Boolean; + end; + + +implementation +{$R *.DFM} +//*************************************************************************************** +// NAME: btnOKClick +// PARAMETER: none +// RETURN VALUE: modal result +// DESCRIPTION: Sets the module result to okay. +// +//*************************************************************************************** +procedure TXcpSettingsForm.btnOKClick(Sender: TObject); +begin + ModalResult := mrOK; +end; //*** end of btnOKClick *** + + +//*************************************************************************************** +// NAME: btnCancelClick +// PARAMETER: none +// RETURN VALUE: modal result +// DESCRIPTION: Sets the module result to cancel. +// +//*************************************************************************************** +procedure TXcpSettingsForm.btnCancelClick(Sender: TObject); +begin + ModalResult := mrCancel; +end; //*** end of btnCancelClick *** + + +//*************************************************************************************** +// NAME: btnBrowseClick +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Prompts the user to select the seed/key dll file. +// +//*************************************************************************************** +procedure TXcpSettingsForm.btnBrowseClick(Sender: TObject); +begin + openDialog.InitialDir := ExtractFilePath(ParamStr(0)); + if openDialog.Execute then + begin + edtSeedKey.Text := openDialog.FileName; + end; +end; //*** end of btnBrowseClick *** + + +//*************************************************************************************** +// NAME: Create +// PARAMETER: Name of the INI file where the settings are and will be stored +// RETURN VALUE: none +// DESCRIPTION: Class constructor +// +//*************************************************************************************** +constructor TXcpSettings.Create(iniFile : string); +begin + // call inherited constructor + inherited Create; + + // set the inifile + FIniFile := iniFile; + + // create an instance of the settings form + FSettingsForm := TXcpSettingsForm.Create(nil); +end; //*** end of Create *** + + +//*************************************************************************************** +// NAME: Destroy +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class destructor +// +//*************************************************************************************** +destructor TXcpSettings.Destroy; +begin + // releaase the settings form object + FSettingsForm.Free; + + // call inherited destructor + inherited; +end; //*** end of Destroy *** + + +//*************************************************************************************** +// NAME: Configure +// PARAMETER: none +// RETURN VALUE: True if configuration was successfully changed, False otherwise +// DESCRIPTION: Allows the user to configure the XCP interface using a GUI. +// +//*************************************************************************************** +function TXcpSettings.Configure : Boolean; +var + settingsIni: TIniFile; +begin + // initialize the return value + result := false; + + // init the form elements using the configuration found in the INI + if FileExists(FIniFile) then + begin + // create ini file object + settingsIni := TIniFile.Create(FIniFile); + + // CAN related elements + FSettingsForm.cmbHardware.ItemIndex := settingsIni.ReadInteger('can', 'hardware', 0); + FSettingsForm.cmbChannel.ItemIndex := settingsIni.ReadInteger('can', 'channel', 0); + FSettingsForm.edtBaudRate.Text := IntToStr(settingsIni.ReadInteger('can', 'baudrate', 500)); + FSettingsForm.chbExtendedId.Checked := settingsIni.ReadBool('can', 'extended', false); + FSettingsForm.edtTransmitId.Text := Format('%x',[settingsIni.ReadInteger('can', 'txid', $667)]); + FSettingsForm.edtReceiveId.Text := Format('%x',[settingsIni.ReadInteger('can', 'rxid', $7e1)]); + + // XCP related elements + FSettingsForm.edtSeedKey.Text := settingsIni.ReadString('xcp', 'seedkey', ''); + FSettingsForm.edtT1.Text := IntToStr(settingsIni.ReadInteger('xcp', 't1', 1000)); + FSettingsForm.edtT3.Text := IntToStr(settingsIni.ReadInteger('xcp', 't3', 2000)); + FSettingsForm.edtT4.Text := IntToStr(settingsIni.ReadInteger('xcp', 't4', 10000)); + FSettingsForm.edtT5.Text := IntToStr(settingsIni.ReadInteger('xcp', 't5', 1000)); + FSettingsForm.edtT7.Text := IntToStr(settingsIni.ReadInteger('xcp', 't7', 2000)); + + // release ini file object + settingsIni.Free; + end + else + begin + // set defaults + // CAN related elements + FSettingsForm.cmbHardware.ItemIndex := 0; + FSettingsForm.cmbChannel.ItemIndex := 0; + FSettingsForm.edtBaudRate.Text := IntToStr(500); + FSettingsForm.chbExtendedId.Checked := false; + FSettingsForm.edtTransmitId.Text := Format('%x',[$667]); + FSettingsForm.edtReceiveId.Text := Format('%x',[$7e1]); + + // XCP related elements + FSettingsForm.edtSeedKey.Text := ''; + FSettingsForm.edtT1.Text := IntToStr(1000); + FSettingsForm.edtT3.Text := IntToStr(2000); + FSettingsForm.edtT4.Text := IntToStr(10000); + FSettingsForm.edtT5.Text := IntToStr(1000); + FSettingsForm.edtT7.Text := IntToStr(2000); + + end; + + // show the form as modal so we can get the result here + if FSettingsForm.ShowModal = mrOK then + begin + if FIniFile <> '' then + begin + // create ini file object + settingsIni := TIniFile.Create(FIniFile); + + // CAN related elements + settingsIni.WriteInteger('can', 'hardware', FSettingsForm.cmbHardware.ItemIndex); + settingsIni.WriteInteger('can', 'channel', FSettingsForm.cmbChannel.ItemIndex); + settingsIni.WriteInteger('can', 'baudrate', StrToInt(FSettingsForm.edtBaudRate.Text)); + settingsIni.WriteBool('can', 'extended', FSettingsForm.chbExtendedId.Checked); + settingsIni.WriteInteger('can', 'txid', StrToInt('$'+FSettingsForm.edtTransmitId.Text)); + settingsIni.WriteInteger('can', 'rxid', StrToInt('$'+FSettingsForm.edtReceiveId.Text)); + + // XCP related elements + settingsIni.WriteString('xcp', 'seedkey', FSettingsForm.edtSeedKey.Text); + settingsIni.WriteInteger('xcp', 't1', StrToInt(FSettingsForm.edtT1.Text)); + settingsIni.WriteInteger('xcp', 't3', StrToInt(FSettingsForm.edtT3.Text)); + settingsIni.WriteInteger('xcp', 't4', StrToInt(FSettingsForm.edtT4.Text)); + settingsIni.WriteInteger('xcp', 't5', StrToInt(FSettingsForm.edtT5.Text)); + settingsIni.WriteInteger('xcp', 't7', StrToInt(FSettingsForm.edtT7.Text)); + + // release ini file object + settingsIni.Free; + + // indicate that the settings where successfully updated + result := true; + end; + end; +end; //*** end of Configure *** + + +end. +//******************************** end of XcpSettings.pas ******************************* + + diff --git a/Host/Source/interfaces/can/vector/XcpTransport.pas b/Host/Source/interfaces/can/vector/XcpTransport.pas new file mode 100644 index 00000000..5d61293b --- /dev/null +++ b/Host/Source/interfaces/can/vector/XcpTransport.pas @@ -0,0 +1,398 @@ +unit XcpTransport; +//*************************************************************************************** +// Description: XCP transport layer for CAN. +// File Name: XcpTransport.pas +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** +interface + + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, Messages, SysUtils, Classes, Forms, CANdrvD, IniFiles; + + +//*************************************************************************************** +// Global Constants +//*************************************************************************************** +const kMaxPacketSize = 256; + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +type + TXcpTransportInfo = (kNone, kResponse, kError); + + +type + TXcpTransport = class(TObject) + private + comEventInfo : TXcpTransportInfo; + comEvent : THandle; + packetTxId : LongWord; + packetRxId : Longword; + extendedId : Boolean; + procedure OnCanMessage(Sender: TObject; Direction: TDirection; Message: TCanMsg); + procedure OnBusOff(Sender: TObject; time: LongInt); + function MsgWaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD; + public + packetData : array[0..kMaxPacketSize-1] of Byte; + packetLen : Word; + canDriver : TCanDriver; + constructor Create; + procedure Configure(iniFile : string); + procedure Connect; + function SendPacket(timeOutms: LongWord): Boolean; + procedure Disconnect; + destructor Destroy; override; + end; + + +implementation + +//*************************************************************************************** +// NAME: Create +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class constructore +// +//*************************************************************************************** +constructor TXcpTransport.Create; +begin + // call inherited constructor + inherited Create; + + // reset can event info + comEventInfo := kNone; + + // create the event that requires manual reset + comEvent := CreateEvent(nil, True, False, nil); + + if comEvent = 0 then + Application.MessageBox( 'Could not obtain event placeholder.', + 'Error', MB_OK or MB_ICONERROR ); + + // create a can driver instance + canDriver := TCanDriver.Create(nil); + + // set can driver event handlers + canDriver.OnMessage := OnCanMessage; + canDriver.OnBusOff := OnBusOff; + + + // reset the packet ids + packetTxId := 0; + packetRxId := 0; + + // use standard id's by default + extendedId := false; + + // reset packet length + packetLen := 0; +end; //*** end of Create *** + + +//*************************************************************************************** +// NAME: Destroy +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class destructor +// +//*************************************************************************************** +destructor TXcpTransport.Destroy; +begin + // release can driver instances + canDriver.Free; + + // release event handle + CloseHandle(comEvent); + + // call inherited destructor + inherited; +end; //*** end of Destroy *** + + +//*************************************************************************************** +// NAME: Configure +// PARAMETER: filename of the INI +// RETURN VALUE: none +// DESCRIPTION: Configures both this class from the settings in the INI. +// +//*************************************************************************************** +procedure TXcpTransport.Configure(iniFile : string); +var + settingsIni : TIniFile; + hwIndex : integer; +begin + // read XCP configuration from INI + if FileExists(iniFile) then + begin + // create ini file object + settingsIni := TIniFile.Create(iniFile); + + // set message configuration + packetTxId := settingsIni.ReadInteger('can', 'txid', $667); + packetRxId := settingsIni.ReadInteger('can', 'rxid', $7e1); + extendedId := settingsIni.ReadBool('can', 'extended', false); + + // configure can hardware + hwIndex := settingsIni.ReadInteger('can', 'hardware', 0); + canDriver.Hardware := Virtual; // init to virtual channel + case hwIndex of + 0 : canDriver.Hardware := Virtual; + 1 : canDriver.Hardware := CANcardX; + 2 : canDriver.Hardware := CANcardXL; + 3 : canDriver.Hardware := CANcaseXL; + 4 : canDriver.Hardware := CANboardXL; + 5 : canDriver.Hardware := CANboardXL_Compact; + 6 : canDriver.Hardware := CANac2; + 7 : canDriver.Hardware := CANac2Pci; + 8 : canDriver.Hardware := CANpari; + 9 : canDriver.Hardware := CANdongle; + 10: canDriver.Hardware := CANcard; + 11: canDriver.Hardware := CANcardY; + 12: canDriver.Hardware := CANcard2; + 13: canDriver.Hardware := EDICcard; + end; + + // configure baudrate + canDriver.BaudRate := settingsIni.ReadInteger('can', 'baudrate', 500) * 1000; + + if settingsIni.ReadInteger('can', 'channel', 0) = 0 then + canDriver.Channel := channel0 + else + canDriver.Channel := channel1; + + // release ini file object + settingsIni.Free; + end; +end; //*** end of Configure *** + + +//*************************************************************************************** +// NAME: Connect +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Connects the transport layer device. +// +//*************************************************************************************** +procedure TXcpTransport.Connect; +begin + if not canDriver.Connect then + Application.MessageBox( 'Could not connect to CAN bus.', + 'Error', MB_OK or MB_ICONERROR ); +end; //*** end of Connect *** + + +//*************************************************************************************** +// NAME: SendPacket +// PARAMETER: the time[ms] allowed for the reponse from the slave to come in. +// RETURN VALUE: True if response received from slave, False otherwise +// DESCRIPTION: Sends the XCP packet using the data in 'packetData' and length in +// 'packetLen' and waits for the response to come in. +// +//*************************************************************************************** +function TXcpTransport.SendPacket(timeOutms: LongWord): Boolean; +var + msg: TCanMsg; + cnt : byte; + waitResult: Integer; +begin + // prepare the packet + msg.id := LongInt(PacketTxId); + msg.dlc := packetLen; + msg.ext := extendedId; + for cnt := 0 to packetLen-1 do + begin + msg.data[cnt] := packetData[cnt]; + end; + + // make sure the event is reset + ResetEvent(comEvent); + comEventInfo := kNone; + + // submit the packet transmission request + if not canDriver.Transmit(msg) then + begin + // unable to submit tx request + result := False; + Exit; + end; + + // packet is being transmitted. Now wait for the response to come in + waitResult := MsgWaitForSingleObject(comEvent, timeOutms); + + if waitResult <> WAIT_OBJECT_0 then + begin + // no com event triggered so either a timeout or internal error occurred + result := False; + Exit; + end; + + // com event was triggered. now check if the reponse was correctly received + if comEventInfo <> kResponse then + begin + result := False; + Exit; + end; + + // packet successfully transmitted and response packet received + result := True; +end; //*** end of SendPacket *** + + +//*************************************************************************************** +// NAME: Disconnect +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Disconnects the transport layer device. +// +//*************************************************************************************** +procedure TXcpTransport.Disconnect; +begin + canDriver.Disconnect; +end; //*** end of Disconnect *** + + +//*************************************************************************************** +// NAME: OnCanMessage +// PRECONDITIONS: none +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Can message event handler +// +//*************************************************************************************** +procedure TXcpTransport.OnCanMessage( Sender: TObject; Direction: TDirection; Message: TCanMsg ); +var + cnt : integer; +begin + // the event we are interested in is the reception of the command response from + // slave. + if Direction = Rx then + begin + if Message.id = LongInt(PacketRxId) then + begin + // store response data + for cnt := 0 to Message.dlc-1 do + begin + packetData[cnt] := Message.data[cnt]; + end; + + // store response length + packetLen := Message.dlc; + + // set event flag + comEventInfo := kResponse; + + // trigger the event + SetEvent(comEvent); + end; + end; +end; //*** end of OnCanMessage *** + + +//*************************************************************************************** +// NAME: OnBusOff +// PRECONDITIONS: none +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Bus off event handler +// +//*************************************************************************************** +procedure TXcpTransport.OnBusOff(Sender: TObject; time: LongInt); +begin + // set error event flag + comEventInfo := kError; + + // trigger the event + SetEvent(comEvent); +end; //*** end of OnBusOff *** + + +//*************************************************************************************** +// NAME: MsgWaitForSingleObject +// PRECONDITIONS: none +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Improved version of WaitForSingleObject. This version actually +// processes messages in the queue instead of blocking them. +// +//*************************************************************************************** +function TXcpTransport.MsgWaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD; +var + dwEnd:DWord; +begin + // compute the time when the WaitForSingleObject is supposed to time out + dwEnd := GetTickCount + dwMilliseconds; + + repeat + // wait for an event to happen or a message to be in the queue + result := MsgWaitForMultipleObjects(1, hHandle, False, dwMilliseconds, QS_ALLINPUT); + + // a message was in the queue? + if result = WAIT_OBJECT_0 + 1 then + begin + // process these messages + Application.ProcessMessages; + + // check for timeout manually because if a message in the queue occurred, the + // MsgWaitForMultipleObjects will be called again and the timer will start from + // scratch. we need to make sure the correct timeout time is used. + dwMilliseconds := GetTickCount; + if dwMilliseconds < dwEnd then + begin + dwMilliseconds := dwEnd - dwMilliseconds; + end + else + begin + // timeout occured + result := WAIT_TIMEOUT; + Break; + end; + end + else + // the event occured? + begin + // we can stop + Break; + end; + until True = False; +end; //*** end of MsgWaitForSingleObject *** + + +end. +//******************************** end of XcpTransport.pas ****************************** + diff --git a/Host/Source/interfaces/can/vector/openblt_can_vector.cfg b/Host/Source/interfaces/can/vector/openblt_can_vector.cfg new file mode 100644 index 00000000..b7fa021f --- /dev/null +++ b/Host/Source/interfaces/can/vector/openblt_can_vector.cfg @@ -0,0 +1,35 @@ +-$A+ +-$B- +-$C+ +-$D+ +-$E- +-$F- +-$G+ +-$H+ +-$I+ +-$J+ +-$K- +-$L+ +-$M- +-$N+ +-$O+ +-$P+ +-$Q- +-$R- +-$S- +-$T- +-$U- +-$V+ +-$W- +-$X+ +-$YD +-$Z1 +-cg +-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +-H+ +-W+ +-M +-$M16384,1048576 +-K$00400000 +-E../../../../ +-LNc:\program files (x86)\borland\delphi4\Lib diff --git a/Host/Source/interfaces/can/vector/openblt_can_vector.dof b/Host/Source/interfaces/can/vector/openblt_can_vector.dof new file mode 100644 index 00000000..223c7e52 --- /dev/null +++ b/Host/Source/interfaces/can/vector/openblt_can_vector.dof @@ -0,0 +1,86 @@ +[Compiler] +A=1 +B=0 +C=1 +D=1 +E=0 +F=0 +G=1 +H=1 +I=1 +J=1 +K=0 +L=1 +M=0 +N=1 +O=1 +P=1 +Q=0 +R=0 +S=0 +T=0 +U=0 +V=1 +W=0 +X=1 +Y=1 +Z=1 +ShowHints=1 +ShowWarnings=1 +UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +[Linker] +MapFile=0 +OutputObjs=0 +ConsoleApp=1 +DebugInfo=0 +RemoteSymbols=0 +MinStackSize=16384 +MaxStackSize=1048576 +ImageBase=4194304 +ExeDescription= +[Directories] +OutputDir=../../../../ +UnitOutputDir= +PackageDLLOutputDir= +PackageDCPOutputDir= +SearchPath= +Packages=Vcl40;Vclx40;Vcldb40;vcldbx40;VclSmp40;Qrpt40 +Conditionals= +DebugSourceDirs= +UsePackages=0 +[Parameters] +RunParams= +HostApplication= +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1031 +CodePage=1252 +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= +[Excluded Packages] +$(DELPHI)\Lib\dclusr40.bpl=Borland User +[HistoryLists\hlUnitAliases] +Count=1 +Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +[HistoryLists\hlOutputDirectorry] +Count=1 +Item0=../../../../ diff --git a/Host/Source/interfaces/can/vector/openblt_can_vector.dpr b/Host/Source/interfaces/can/vector/openblt_can_vector.dpr new file mode 100644 index 00000000..e11e8d5b --- /dev/null +++ b/Host/Source/interfaces/can/vector/openblt_can_vector.dpr @@ -0,0 +1,605 @@ +library openblt_can_vector; +//*************************************************************************************** +// Project Name: MicroBoot Interface for Borland Delphi +// Description: XCP - CAN interface for MicroBoot supporting Vector CAN +// File Name: openblt_can_vector.dpr +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** + + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, + Messages, + Graphics, + Controls, + Forms, + Dialogs, + SysUtils, + Classes, + Extctrls, + XcpProtection in '..\..\XcpProtection.pas', + SRecReader in '..\..\SRecReader.pas', + XcpDataFile in '..\..\XcpDataFile.pas', + XcpLoader in '..\..\XcpLoader.pas', + XcpTransport in 'XcpTransport.pas', + CANdrvD in 'CANdrvD.pas', + CANlibD in 'CANlibD.pas', + XcpSettings in 'XcpSettings.pas' {XcpSettingsForm}; + + +//*************************************************************************************** +// Global Constants +//*************************************************************************************** +const kMaxProgLen = 256; // maximum number of bytes to progam at one time + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +// DLL Interface Callbacks - modifications requires potential update of all interfaces! +type + TStartedEvent = procedure(length: Longword) of object; + TProgressEvent = procedure(progress: Longword) of object; + TDoneEvent = procedure of object; + TErrorEvent = procedure(error: ShortString) of object; + TLogEvent = procedure(info: ShortString) of object; + TInfoEvent = procedure(info: ShortString) of object; + +type + TEventHandlers = class // create a dummy class + procedure OnTimeout(Sender: TObject); + end; + +//*************************************************************************************** +// Global Variables +//*************************************************************************************** +var + //--- begin of don't change --- + AppOnStarted : TStartedEvent; + AppOnProgress : TProgressEvent; + AppOnDone : TDoneEvent; + AppOnError : TErrorEvent; + AppOnLog : TLogEvent; + AppOnInfo : TInfoEvent; + //--- end of don't change --- + timer : TTimer; + events : TEventHandlers; + loader : TXcpLoader; + datafile : TXcpDataFile; + progdata : array of Byte; + progfile : string; + stopRequest : boolean; + + +//*************************************************************************************** +// NAME: MbiCallbackOnStarted +// PARAMETER: length of the file that is being downloaded. +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnStarted(length: Longword); +begin + if Assigned(AppOnStarted) then + begin + AppOnStarted(length); + end; +end; //** end of MbiCallbackOnStarted *** + + +//*************************************************************************************** +// NAME: MbiCallbackOnProgress +// PARAMETER: progress of the file download. +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnProgress(progress: Longword); +begin + if Assigned(AppOnProgress) then + begin + AppOnProgress(progress); + end; +end; //** end of MbiCallbackOnProgress *** + + +//*************************************************************************************** +// NAME: MbiCallbackOnDone +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnDone; +begin + if Assigned(AppOnDone) then + begin + AppOnDone; + end; +end; //** end of MbiCallbackOnDone *** + + +//*************************************************************************************** +// NAME: MbiCallbackOnError +// PARAMETER: info about the error that occured. +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnError(error: ShortString); +begin + if Assigned(AppOnError) then + begin + AppOnError(error); + end; +end; //** end of MbiCallbackOnError *** + + +//*************************************************************************************** +// NAME: MbiCallbackOnLog +// PARAMETER: info on the log event. +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnLog(info: ShortString); +begin + if Assigned(AppOnLog) then + begin + AppOnLog(info); + end; +end; //** end of MbiCallbackOnLog *** + + +//*************************************************************************************** +// NAME: MbiCallbackOnInfo +// PARAMETER: details on the info event. +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnInfo(info: ShortString); +begin + if Assigned(AppOnInfo) then + begin + AppOnInfo(info); + end; +end; //** end of MbiCallbackOnLog *** + + +//*************************************************************************************** +// NAME: LogData +// PARAMETER: pointer to byte array and the data length +// RETURN VALUE: none +// DESCRIPTION: Writes the program data formatted to the logfile +// +//*************************************************************************************** +procedure LogData(data : PByteArray; len : longword); stdcall; +var + currentWriteCnt : byte; + cnt : byte; + logStr : string; + bufferOffset : longword; +begin + bufferOffset := 0; + + while len > 0 do + begin + // set the current write length optimized to log 32 bytes per line + currentWriteCnt := len mod 32; + if currentWriteCnt = 0 then currentWriteCnt := 32; + logStr := ''; + + // prepare the line to add to the log + for cnt := 0 to currentWriteCnt-1 do + begin + logStr := logStr + Format('%2.2x ', [data[bufferOffset+cnt]]); + end; + + // update the log + MbiCallbackOnLog(logStr); + + // update loop variables + len := len - currentWriteCnt; + bufferOffset := bufferOffset + currentWriteCnt; + end; +end; //*** end of LogData *** + + +//*************************************************************************************** +// NAME: OnTimeout +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Timer event handler. A timer is used in this example to simulate the +// progress of a file download. It also demonstrates how to use the +// application callbacks to keep the application informed. +// +//*************************************************************************************** +procedure TEventHandlers.OnTimeout(Sender: TObject); +var + errorInfo : string; + progress : longword; + regionCnt : longword; + currentWriteCnt : word; + bufferOffset : longword; + addr : longword; + len : longword; + dataSizeKB : real; +begin + timer.Enabled := False; + + // connect the transport layer + MbiCallbackOnLog('Connecting the transport layer. t='+TimeToStr(Time)); + loader.Connect; + + //---------------- start the programming session -------------------------------------- + MbiCallbackOnLog('Starting the programming session. t='+TimeToStr(Time)); + if not loader.StartProgrammingSession then + begin + // update the user info + MbiCallbackOnInfo('Could not connect. Please reset your target...'); + MbiCallbackOnLog('Connect failed. Switching to backdoor entry mode. t='+TimeToStr(Time)); + Application.ProcessMessages; + end; + + while not loader.StartProgrammingSession do + begin + Application.ProcessMessages; + Sleep(5); + if stopRequest then + begin + MbiCallbackOnError('Programming session cancelled by user.'); + Exit; + end; + end; + + // still here so programming session was started + MbiCallbackOnLog('Programming session started. t='+TimeToStr(Time)); + + // create the datafile object + datafile := TXcpDataFile.Create(progfile); + + // compute the size in kbytes + dataSizeKB := datafile.GetDataCnt / 1024; + + // Call application callback when we start the actual download + MbiCallbackOnStarted(datafile.GetDataCnt); + + // Init progress to 0 progress + progress := 0; + MbiCallbackOnProgress(progress); + + //---------------- next clear the memory regions -------------------------------------- + // update the user info + MbiCallbackOnInfo('Erasing memory...'); + + for regionCnt := 0 to datafile.GetRegionCnt-1 do + begin + // obtain the region info + datafile.GetRegionInfo(regionCnt, addr, len); + + // erase the memory + MbiCallbackOnLog('Clearing Memory '+Format('addr:0x%x,len:0x%x',[addr,len])+'. t='+TimeToStr(Time)); + if not loader.ClearMemory(addr, len) then + begin + loader.GetLastError(errorInfo); + MbiCallbackOnLog('Could not clear memory ('+errorInfo+'). t='+TimeToStr(Time)); + MbiCallbackOnError('Could not clear memory ('+errorInfo+').'); + datafile.Free; + Exit; + end; + MbiCallbackOnLog('Memory cleared. t='+TimeToStr(Time)); + end; + + //---------------- next program the memory regions ------------------------------------ + for regionCnt := 0 to datafile.GetRegionCnt-1 do + begin + // update the user info + MbiCallbackOnInfo('Reading file...'); + + // obtain the region info + datafile.GetRegionInfo(regionCnt, addr, len); + // dynamically allocated buffer memory + SetLength(progdata, len); + // obtain the regiond data + datafile.GetRegionData(regionCnt, progdata); + + bufferOffset := 0; + while len > 0 do + begin + // set the current write length taking into account kMaxProgLen + currentWriteCnt := len mod kMaxProgLen; + if currentWriteCnt = 0 then currentWriteCnt := kMaxProgLen; + + // program the data + MbiCallbackOnLog('Programming Data '+Format('addr:0x%x,len:0x%x',[addr,currentWriteCnt])+'. t='+TimeToStr(Time)); + LogData(@progdata[bufferOffset], currentWriteCnt); + + if not loader.WriteData(addr, currentWriteCnt, @progdata[bufferOffset]) then + begin + loader.GetLastError(errorInfo); + MbiCallbackOnLog('Could not program data ('+errorInfo+'). t='+TimeToStr(Time)); + MbiCallbackOnError('Could not program data ('+errorInfo+').'); + datafile.Free; + Exit; + end; + MbiCallbackOnLog('Data Programmed. t='+TimeToStr(Time)); + + // update progress + progress := progress + currentWriteCnt; + MbiCallbackOnProgress(progress); + + // update loop variables + len := len - currentWriteCnt; + addr := addr + currentWriteCnt; + bufferOffset := bufferOffset + currentWriteCnt; + + // update the user info + MbiCallbackOnInfo('Programming data... ' + Format('(%.1n of %.1n Kbytes)',[(progress/1024), dataSizeKB])); + + end; + end; + + //---------------- stop the programming session --------------------------------------- + MbiCallbackOnLog('Stopping the programming session. t='+TimeToStr(Time)); + if not loader.StopProgrammingSession then + begin + loader.GetLastError(errorInfo); + MbiCallbackOnLog('Could not stop the programming session ('+errorInfo+'). t='+TimeToStr(Time)); + MbiCallbackOnError('Could not stop the programming session ('+errorInfo+').'); + datafile.Free; + Exit; + end; + MbiCallbackOnLog('Programming session stopped. t='+TimeToStr(Time)); + + // all done so set progress to 100% and finish up + progress := datafile.GetDataCnt; + datafile.Free; + MbiCallbackOnProgress(progress); + MbiCallbackOnLog('File successfully downloaded t='+TimeToStr(Time)); + MbiCallbackOnDone; + +end; //*** end of OnTimeout *** + + +//*************************************************************************************** +// NAME: MbiInit +// PARAMETER: callback function pointers +// RETURN VALUE: none +// DESCRIPTION: Called by the application to initialize the interface library. +// +//*************************************************************************************** +procedure MbiInit(cbStarted: TStartedEvent; cbProgress: TProgressEvent; + cbDone: TDoneEvent; cbError: TErrorEvent; cbLog: TLogEvent; + cbInfo: TInfoEvent); stdcall; +begin + //--- begin of don't change --- + AppOnStarted := cbStarted; + AppOnProgress := cbProgress; + AppOnDone := cbDone; + AppOnLog := cbLog; + AppOnInfo := cbInfo; + AppOnError := cbError; + //--- end of don't change --- + + // create xcp loader object + loader := TXcpLoader.Create; + + // update to the latest configuration + loader.Configure(ExtractFilePath(ParamStr(0))+'openblt_can_vector.ini'); + + // create and init a timer + events := TEventHandlers.Create; + timer := TTimer.Create(nil); + timer.Enabled := False; + timer.Interval := 100; + timer.OnTimer := events.OnTimeout; +end; //*** end of MbiInit *** + + +//*************************************************************************************** +// NAME: MbiStart +// PARAMETER: filename of the file that is to be downloaded. +// RETURN VALUE: none +// DESCRIPTION: Called by the application to request the interface library to download +// the file that is passed as a parameter. +// +//*************************************************************************************** +procedure MbiStart(fileName: ShortString); stdcall; +begin + // update the user info + MbiCallbackOnInfo(''); + + // start the log + MbiCallbackOnLog('--- Downloading "'+fileName+'" ---'); + + // reset stop request + stopRequest := false; + + // start the startup timer which gives microBoot a chance to paint itself + timer.Enabled := True; + + // store the program's filename + progfile := fileName; +end; //*** end of MbiStart *** + + +//*************************************************************************************** +// NAME: MbiStop +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Called by the application to request the interface library to stop +// a download that could be in progress. +// +//*************************************************************************************** +procedure MbiStop; stdcall; +begin + // set stop request + stopRequest := true; + + // disconnect the transport layer + MbiCallbackOnLog('Disconnecting the transport layer. t='+TimeToStr(Time)); + loader.Disconnect; +end; //*** end of MbiStop *** + + +//*************************************************************************************** +// NAME: MbiDeInit +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Called by the application to uninitialize the interface library. +// +//*************************************************************************************** +procedure MbiDeInit; stdcall; +begin + // release xcp loader object + loader.Free; + + // release the timer and events object + timer.Free; + events.Free; + + //--- begin of don't change --- + AppOnStarted := nil; + AppOnProgress := nil; + AppOnDone := nil; + AppOnLog := nil; + AppOnInfo := nil; + AppOnError := nil; + //--- end of don't change --- +end; //*** end of MbiDeInit *** + + +//*************************************************************************************** +// NAME: MbiName +// PARAMETER: none +// RETURN VALUE: name of the interface library +// DESCRIPTION: Called by the application to obtain the name of the interface library. +// +//*************************************************************************************** +function MbiName : ShortString; stdcall; +begin + Result := 'OpenBLT CAN Vector'; +end; //*** end of MbiName *** + + +//*************************************************************************************** +// NAME: MbiDescription +// PARAMETER: none +// RETURN VALUE: description of the interface library +// DESCRIPTION: Called by the application to obtain the description of the interface +// library. +// +//*************************************************************************************** +function MbiDescription : ShortString; stdcall; +begin + Result := 'OpenBLT using Vector CAN Interface'; +end; //*** end of MbiDescription *** + + +//*************************************************************************************** +// NAME: MbiVersion +// PARAMETER: none +// RETURN VALUE: version number +// DESCRIPTION: Called by the application to obtain the version number of the +// interface library. +// +//*************************************************************************************** +function MbiVersion : Longword; stdcall; +begin + Result := 10000; // v1.00.00 +end; //*** end of MbiVersion *** + + +//*************************************************************************************** +// NAME: MbiVInterface +// PARAMETER: none +// RETURN VALUE: version number of the supported interface +// DESCRIPTION: Called by the application to obtain the version number of the +// Mbi interface uBootInterface.pas (not the interface library). This can +// be used by the application for backward compatibility. +// +//*************************************************************************************** +function MbiVInterface : Longword; stdcall; +begin + Result := 10001; // v1.00.01 +end; //*** end of MbiVInterface *** + + +//*************************************************************************************** +// NAME: MbiConfigure +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Called by the application to enable the user to configure the inter- +// face library through the application. +// +//*************************************************************************************** +procedure MbiConfigure; stdcall; +var + settings : TXcpSettings; +begin + // create xcp settings object + settings := TXcpSettings.Create(ExtractFilePath(ParamStr(0))+'openblt_can_vector.ini'); + + // display the modal configuration dialog + settings.Configure; + + // release the xcp settings object + settings.Free; + + // update to the latest configuration + loader.Configure(ExtractFilePath(ParamStr(0))+'openblt_can_vector.ini'); +end; //*** end of MbiConfigure *** + + +//*************************************************************************************** +// External Declarations +//*************************************************************************************** +exports + //--- begin of don't change --- + MbiInit index 1, + MbiStart index 2, + MbiStop index 3, + MbiDeInit index 4, + MbiName index 5, + MbiDescription index 6, + MbiVersion index 7, + MbiConfigure index 8, + MbiVInterface index 9; + //--- end of don't change --- + +end. +//********************************** end of openblt_can_vector.dpr ********************** diff --git a/Host/Source/interfaces/uart/CPDrv.ico b/Host/Source/interfaces/uart/CPDrv.ico new file mode 100644 index 00000000..d0125faa Binary files /dev/null and b/Host/Source/interfaces/uart/CPDrv.ico differ diff --git a/Host/Source/interfaces/uart/CPDrv.pas b/Host/Source/interfaces/uart/CPDrv.pas new file mode 100644 index 00000000..d92882da --- /dev/null +++ b/Host/Source/interfaces/uart/CPDrv.pas @@ -0,0 +1,1158 @@ +//*************************************************************************************** +// 20060225: Updated by Frank Voorburg - Feaser +// +// - When using ReadXxx the windows messages are now being processed +// - When using ReadXxx the loop will stop (FCancel) upon disconnect +//*************************************************************************************** + +//------------------------------------------------------------------------ +// UNIT : CPDrv.pas +// CONTENTS : TCommPortDriver component +// VERSION : 2.1 +// TARGET : (Inprise's) Borland Delphi 4.0 +// AUTHOR : Marco Cocco +// STATUS : Freeware +// INFOS : Implementation of TCommPortDriver component: +// - non multithreaded serial I/O +// KNOWN BUGS : none +// COMPATIBILITY : Windows 95/98/NT/2000 +// REPLACES : TCommPortDriver v2.00 (Delphi 4.0) +// TCommPortDriver v1.08/16 (Delphi 1.0) +// TCommPortDriver v1.08/32 (Delphi 2.0/3.0) +// BACK/COMPAT. : partial - a lot of properties have been renamed +// RELEASE DATE : 06/06/2000 +// (Replaces v2.0 released on 30/NOV/1998) +//------------------------------------------------------------------------ +// FOR UPDATES : - sorry, no home page - +// BUGS REPORT : mail to : mcocco@libero.it +// or: ditrek@tiscalinet.it +//------------------------------------------------------------------------ +// +// Copyright (c) 1996-2000 by Marco Cocco. All rights reseved. +// Copyright (c) 1996-2000 by d3k Software Company. All rights reserved. +// +//****************************************************************************** +//* Permission to use, copy, modify, and distribute this software and its * +//* documentation without fee for any purpose is hereby granted, * +//* provided that the above copyright notice appears on all copies and that * +//* both that copyright notice and this permission notice appear in all * +//* supporting documentation. * +//* * +//* NO REPRESENTATIONS ARE MADE ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY * +//* PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. * +//* NEITHER MARCO COCCO OR D3K SHALL BE LIABLE FOR ANY DAMAGES SUFFERED BY * +//* THE USE OF THIS SOFTWARE. * +//****************************************************************************** + +unit CPDrv; + +interface + +uses + // Delphi units + Windows, Messages, SysUtils, Classes, Forms + // ComDrv32 units + ; + +//------------------------------------------------------------------------ +// Property types +//------------------------------------------------------------------------ + +type + // Baud Rates (custom or 110...256k bauds) + TBaudRate = ( brCustom, + br110, br300, br600, br1200, br2400, br4800, + br9600, br14400, br19200, br38400, br56000, + br57600, br115200, br128000, br256000 ); + // Port Numbers ( custom or COM1..COM16 ) + TPortNumber = ( pnCustom, + pnCOM1, pnCOM2, pnCOM3, pnCOM4, pnCOM5, pnCOM6, pnCOM7, + pnCOM8, pnCOM9, pnCOM10, pnCOM11, pnCOM12, pnCOM13, + pnCOM14, pnCOM15, pnCOM16 ); + // Data bits ( 5, 6, 7, 8 ) + TDataBits = ( db5BITS, db6BITS, db7BITS, db8BITS ); + // Stop bits ( 1, 1.5, 2 ) + TStopBits = ( sb1BITS, sb1HALFBITS, sb2BITS ); + // Parity ( None, odd, even, mark, space ) + TParity = ( ptNONE, ptODD, ptEVEN, ptMARK, ptSPACE ); + // Hardware Flow Control ( None, None + RTS always on, RTS/CTS ) + THwFlowControl = ( hfNONE, hfNONERTSON, hfRTSCTS ); + // Software Flow Control ( None, XON/XOFF ) + TSwFlowControl = ( sfNONE, sfXONXOFF ); + // What to do with incomplete (incoming) packets ( Discard, Pass ) + TPacketMode = ( pmDiscard, pmPass ); + +//------------------------------------------------------------------------ +// Event types +//------------------------------------------------------------------------ + +type + // RX event ( packet mode disabled ) + TReceiveDataEvent = procedure( Sender: TObject; DataPtr: pointer; DataSize: DWORD ) of object; + // RX event ( packed mode enabled ) + TReceivePacketEvent = procedure( Sender: TObject; Packet: pointer; DataSize: DWORD ) of object; + +//------------------------------------------------------------------------ +// Other types +//------------------------------------------------------------------------ + +type + // Line status ( Clear To Send, Data Set Ready, Ring, Carrier Detect ) + TLineStatus = ( lsCTS, lsDSR, lsRING, lsCD ); + // Set of line status + TLineStatusSet = set of TLineStatus; + +//------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------ + +const + RELEASE_NOCLOSE_PORT = HFILE(INVALID_HANDLE_VALUE-1); + +//------------------------------------------------------------------------ +// TCommPortDriver component +//------------------------------------------------------------------------ + +type + TCommPortDriver = class( TComponent ) + protected + // Device Handle ( File Handle ) + FHandle : HFILE; + // # of the COM port to use, or pnCustom to use custom port name + FPort : TPortNumber; + // Custom port name ( usually '\\.\COMn', with n = 1..x ) + FPortName : string; + // COM Port speed (brXXX) + FBaudRate : TBaudRate; + // Baud rate ( actual numeric value ) + FBaudRateValue : DWORD; + // Data bits size (dbXXX) + FDataBits : TDataBits; + // How many stop bits to use (sbXXX) + FStopBits : TStopBits; + // Type of parity to use (ptXXX) + FParity : TParity; + // Type of hw handshaking (hw flow control) to use (hfXXX) + FHwFlow : THwFlowControl; + // Type of sw handshaking (sw flow control) to use (sFXXX) + FSwFlow : TSwFlowControl; + // Size of the input buffer + FInBufSize : DWORD; + // Size of the output buffer + FOutBufSize : DWORD; + // Size of a data packet + FPacketSize : smallint; + // ms to wait for a complete packet (<=0 = disabled) + FPacketTimeout : integer; + // What to do with incomplete packets (pmXXX) + FPacketMode : TPacketMode; + // Event to raise on data reception (asynchronous) + FOnReceiveData : TReceiveDataEvent; + // Event to raise on packet reception (asynchronous) + FOnReceivePacket : TReceivePacketEvent; + // ms of delay between COM port pollings + FPollingDelay : word; + // Specifies if the DTR line must be enabled/disabled on connect + FEnableDTROnOpen : boolean; + // Output timeout - milliseconds + FOutputTimeout : word; + // Timeout for ReadData + FInputTimeout : DWORD; + // Set to TRUE to prevent hangs when no device connected or + // device is OFF + FCkLineStatus : boolean; + // This is used for the timer + FNotifyWnd : HWND; + // Temporary buffer (RX) - used internally + FTempInBuffer : pointer; + // Time of the first byte of current RX packet + FFirstByteOfPacketTime : DWORD; + // Number of RX polling timer pauses + FRXPollingPauses : integer; + + FCancel : Boolean; + + // Sets the COM port handle + procedure SetHandle( Value: HFILE ); + // Selects the COM port to use + procedure SetPort( Value: TPortNumber ); + // Sets the port name + procedure SetPortName( Value: string ); + // Selects the baud rate + procedure SetBaudRate( Value: TBaudRate ); + // Selects the baud rate ( actual baud rate value ) + procedure SetBaudRateValue( Value: DWORD ); + // Selects the number of data bits + procedure SetDataBits( Value: TDataBits ); + // Selects the number of stop bits + procedure SetStopBits( Value: TStopBits ); + // Selects the kind of parity + procedure SetParity( Value: TParity ); + // Selects the kind of hardware flow control + procedure SetHwFlowControl( Value: THwFlowControl ); + // Selects the kind of software flow control + procedure SetSwFlowControl( Value: TSwFlowControl ); + // Sets the RX buffer size + procedure SetInBufSize( Value: DWORD ); + // Sets the TX buffer size + procedure SetOutBufSize( Value: DWORD ); + // Sets the size of incoming packets + procedure SetPacketSize( Value: smallint ); + // Sets the timeout for incoming packets + procedure SetPacketTimeout( Value: integer ); + // Sets the delay between polling checks + procedure SetPollingDelay( Value: word ); + // Applies current settings to open COM port + function ApplyCOMSettings: boolean; + // Polling proc + procedure TimerWndProc( var msg: TMessage ); + public + // Constructor + constructor Create( AOwner: TComponent ); override; + // Destructor + destructor Destroy; override; + + // Opens the COM port and takes of it. Returns false if something + // goes wrong. + function Connect: boolean; + // Closes the COM port and releases control of it + procedure Disconnect; + // Returns true if COM port has been opened + function Connected: boolean; + // Returns the current state of CTS, DSR, RING and RLSD (CD) lines. + // The function fails if the hardware does not support the control-register + // values (that is, returned set is always empty). + function GetLineStatus: TLineStatusSet; + // Returns true if polling has not been paused + function IsPolling: boolean; + // Pauses polling + procedure PausePolling; + // Re-starts polling (after pause) + procedure ContinuePolling; + // Flushes the rx/tx buffers + function FlushBuffers( inBuf, outBuf: boolean ): boolean; + // Returns number of received bytes in the RX buffer + function CountRX: integer; + // Returns the output buffer free space or 65535 if not connected + function OutFreeSpace: word; + // Sends binary data + function SendData( DataPtr: pointer; DataSize: DWORD ): DWORD; + // Sends binary data. Returns number of bytes sent. Timeout overrides + // the value specifiend in the OutputTimeout property + function SendDataEx( DataPtr: pchar; DataSize, Timeout: DWORD ): DWORD; + // Sends a byte. Returns true if the byte has been sent + function SendByte( Value: byte ): boolean; + // Sends a char. Returns true if the char has been sent + function SendChar( Value: char ): boolean; + // Sends a pascal string (NULL terminated if $H+ (default)) + function SendString( s: string ): boolean; + // Sends a C-style strings (NULL terminated) + function SendZString( s: pchar ): boolean; + // Reads binary data. Returns number of bytes read + function ReadData( DataPtr: pchar; MaxDataSize: DWORD ): DWORD; + // Reads a byte. Returns true if the byte has been read + function ReadByte( var Value: byte ): boolean; + // Reads a char. Returns true if char has been read + function ReadChar( var Value: char ): boolean; + // Set DTR line high (onOff=TRUE) or low (onOff=FALSE). + // You must not use HW handshaking. + procedure ToggleDTR( onOff: boolean ); + // Set RTS line high (onOff=TRUE) or low (onOff=FALSE). + // You must not use HW handshaking. + procedure ToggleRTS( onOff: boolean ); + + // Make the Handle of the COM port public (for TAPI...) [read/write] + property Handle: HFILE read FHandle write SetHandle; + published + // # of the COM Port to use ( or pnCustom for port by name ) + property Port: TPortNumber read FPort write SetPort default pnCOM2; + // Name of COM port + property PortName: string read FPortName write SetPortName; + // Speed ( Baud Rate ) + property BaudRate: TBaudRate read FBaudRate write SetBaudRate default br9600; + // Speed ( Actual Baud Rate value ) + property BaudRateValue: DWORD read FBaudRateValue write SetBaudRateValue default 9600; + // Data bits to use (5..8, for the 8250 the use of 5 data bits with 2 stop + // bits is an invalid combination, as is 6, 7, or 8 data bits with 1.5 stop + // bits) + property DataBits: TDataBits read FDataBits write SetDataBits default db8BITS; + // Stop bits to use (1, 1.5, 2) + property StopBits: TStopBits read FStopBits write SetStopBits default sb1BITS; + // Kind of Parity to use (none,odd,even,mark,space) + property Parity: TParity read FParity write SetParity default ptNONE; + // Kind of Hardware Flow Control to use: + // hfNONE none + // hfNONERTSON no flow control but keep RTS line on + // hfRTSCTS Request-To-Send/Clear-To-Send + property HwFlow: THwFlowControl read FHwFlow write SetHwFlowControl default hfNONERTSON; + // Kind of Software Flow Control to use: + // sfNONE none + // sfXONXOFF XON/XOFF + property SwFlow: TSwFlowControl read FSwFlow write SetSwFlowControl default sfNONE; + // Input Buffer size ( suggested - driver might ignore this setting ! ) + property InBufSize: DWORD read FInBufSize write SetInBufSize default 2048; + // Output Buffer size ( suggested - driver usually ignores this setting ! ) + property OutBufSize: DWORD read FOutBufSize write SetOutBufSize default 2048; + // RX packet size ( this value must be less than InBufSize ) + // A value <= 0 means "no packet mode" ( i.e. standard mode enabled ) + property PacketSize: smallint read FPacketSize write SetPacketSize default -1; + // Timeout (ms) for a complete packet (in RX) + property PacketTimeout: integer read FPacketTimeout write SetPacketTimeout default -1; + // What to do with incomplete packets (in RX) + property PacketMode: TPacketMode read FPacketMode write FPacketMode default pmDiscard; + // ms of delay between COM port pollings + property PollingDelay: word read FPollingDelay write SetPollingDelay default 50; + // Set to TRUE to enable DTR line on connect and to leave it on until disconnect. + // Set to FALSE to disable DTR line on connect. + property EnableDTROnOpen: boolean read FEnableDTROnOpen write FEnableDTROnOpen default true; + // Output timeout (milliseconds) + property OutputTimeout: word read FOutputTimeOut write FOutputTimeout default 500; + // Input timeout (milliseconds) + property InputTimeout: DWORD read FInputTimeOut write FInputTimeout default 200; + // Set to TRUE to prevent hangs when no device connected or device is OFF + property CheckLineStatus: boolean read FCkLineStatus write FCkLineStatus default false; + // Event to raise when there is data available (input buffer has data) + // (called only if PacketSize <= 0) + property OnReceiveData: TReceiveDataEvent read FOnReceiveData write FOnReceiveData; + // Event to raise when there is data packet available (called only if PacketSize > 0) + property OnReceivePacket: TReceivePacketEvent read FOnReceivePacket write FOnReceivePacket; + end; + +function BaudRateOf( bRate: TBaudRate ): DWORD; +function DelayForRX( bRate: TBaudRate; DataSize: DWORD ): DWORD; + +implementation + +const + Win32BaudRates: array[br110..br256000] of DWORD = + ( CBR_110, CBR_300, CBR_600, CBR_1200, CBR_2400, CBR_4800, CBR_9600, + CBR_14400, CBR_19200, CBR_38400, CBR_56000, CBR_57600, CBR_115200, + CBR_128000, CBR_256000 ); + +const + dcb_Binary = $00000001; + dcb_ParityCheck = $00000002; + dcb_OutxCtsFlow = $00000004; + dcb_OutxDsrFlow = $00000008; + dcb_DtrControlMask = $00000030; + dcb_DtrControlDisable = $00000000; + dcb_DtrControlEnable = $00000010; + dcb_DtrControlHandshake = $00000020; + dcb_DsrSensivity = $00000040; + dcb_TXContinueOnXoff = $00000080; + dcb_OutX = $00000100; + dcb_InX = $00000200; + dcb_ErrorChar = $00000400; + dcb_NullStrip = $00000800; + dcb_RtsControlMask = $00003000; + dcb_RtsControlDisable = $00000000; + dcb_RtsControlEnable = $00001000; + dcb_RtsControlHandshake = $00002000; + dcb_RtsControlToggle = $00003000; + dcb_AbortOnError = $00004000; + dcb_Reserveds = $FFFF8000; + +function GetWinPlatform: string; +var ov: TOSVERSIONINFO; +begin + ov.dwOSVersionInfoSize := sizeof(ov); + if GetVersionEx( ov ) then + begin + case ov.dwPlatformId of + VER_PLATFORM_WIN32s: // Win32s on Windows 3.1 + Result := 'W32S'; + VER_PLATFORM_WIN32_WINDOWS: // Win32 on Windows 95/98 + Result := 'W95'; + VER_PLATFORM_WIN32_NT: // Windows NT + Result := 'WNT'; + end; + end + else + Result := '??'; +end; + +function GetWinVersion: DWORD; +var ov: TOSVERSIONINFO; +begin + ov.dwOSVersionInfoSize := sizeof(ov); + if GetVersionEx( ov ) then + Result := MAKELONG( ov.dwMinorVersion, ov.dwMajorVersion ) + else + Result := $00000000; +end; + +function BaudRateOf( bRate: TBaudRate ): DWORD; +begin + if bRate = brCustom then + Result := 0 + else + Result := Win32BaudRates[ bRate ]; +end; + +function DelayForRX( bRate: TBaudRate; DataSize: DWORD ): DWORD; +begin + Result := round( DataSize / (BaudRateOf(bRate) / 10) * 1000 ); +end; + +constructor TCommPortDriver.Create( AOwner: TComponent ); +begin + inherited Create( AOwner ); + // Initialize to default values ----------------------- + // not canceled + FCancel := false; + // Not connected + FHandle := INVALID_HANDLE_VALUE; + // COM 2 + FPort := pnCOM2; + FPortName := '\\.\COM2'; + // 9600 bauds + FBaudRate := br9600; + FBaudRateValue := BaudRateOf( br9600 ); + // 8 data bits + FDataBits := db8BITS; + // 1 stop bit + FStopBits := sb1BITS; + // no parity + FParity := ptNONE; + // No hardware flow control but RTS on + FHwFlow := hfNONERTSON; + // No software flow control + FSwFlow := sfNONE; + // Input buffer of 2048 bytes + FInBufSize := 2048; + // Output buffer of 2048 bytes + FOutBufSize := 2048; + // Don't pack data + FPacketSize := -1; + // Packet timeout disabled + FPacketTimeout := -1; + // Discard incomplete packets + FPacketMode := pmDiscard; + // Poll COM port every 50ms + FPollingDelay := 50; + // Output timeout of 500ms + FOutputTimeout := 500; + // Timeout for ReadData(), 200ms + FInputTimeout := 200; + // DTR high on connect + FEnableDTROnOpen := true; + // Time not valid ( used by the packing routines ) + FFirstByteOfPacketTime := DWORD(-1); + // Don't check of off-line devices + FCkLineStatus := false; + // Init number of RX polling timer pauses - not paused + FRXPollingPauses := 0; + // Temporary buffer for received data + FTempInBuffer := AllocMem( FInBufSize ); + // Allocate a window handle to catch timer's notification messages + if not (csDesigning in ComponentState) then + FNotifyWnd := AllocateHWnd( TimerWndProc ); +end; + +destructor TCommPortDriver.Destroy; +begin + // Be sure to release the COM port + Disconnect; + // Free the temporary buffer + FreeMem( FTempInBuffer, FInBufSize ); + // Destroy the timer's window + if not (csDesigning in ComponentState) then + DeallocateHWnd( FNotifyWnd ); + // Call inherited destructor + inherited Destroy; +end; + +// The COM port handle made public and writeable. +// This lets you connect to external opened com port. +// Setting ComPortHandle to INVALID_PORT_HANDLE acts as Disconnect. +procedure TCommPortDriver.SetHandle( Value: HFILE ); +begin + // If same COM port then do nothing + if FHandle = Value then + exit; + // If value is RELEASE_NOCLOSE_PORT then stop controlling the COM port + // without closing in + if Value = RELEASE_NOCLOSE_PORT then + begin + // Stop the timer + if Connected then + KillTimer( FNotifyWnd, 1 ); + // No more connected + FHandle := INVALID_HANDLE_VALUE; + end + else + begin + // Disconnect + Disconnect; + // If Value is INVALID_HANDLE_VALUE then exit now + if Value = INVALID_HANDLE_VALUE then + exit; + // Set COM port handle + FHandle := Value; + // Start the timer ( used for polling ) + SetTimer( FNotifyWnd, 1, FPollingDelay, nil ); + end; +end; + +// Selects the COM port to use +procedure TCommPortDriver.SetPort( Value: TPortNumber ); +begin + // Be sure we are not using any COM port + if Connected then + exit; + // Change COM port + FPort := Value; + // Update the port name + if FPort <> pnCustom then + FPortName := Format( '\\.\COM%d', [ord(FPort)] ); +end; + +// Sets the port name +procedure TCommPortDriver.SetPortName( Value: string ); +begin + // Be sure we are not using any COM port + if Connected then + exit; + // Change COM port + FPort := pnCustom; + // Update the port name + FPortName := Value; +end; + +// Selects the baud rate +procedure TCommPortDriver.SetBaudRate( Value: TBaudRate ); +begin + // Set new COM speed + FBaudRate := Value; + if FBaudRate <> brCustom then + FBaudRateValue := BaudRateOf( FBaudRate ); + // Apply changes + if Connected then + ApplyCOMSettings; +end; + +// Selects the baud rate ( actual baud rate value ) +procedure TCommPortDriver.SetBaudRateValue( Value: DWORD ); +begin + // Set new COM speed + FBaudRate := brCustom; + FBaudRateValue := Value; + // Apply changes + if Connected then + ApplyCOMSettings; +end; + +// Selects the number of data bits +procedure TCommPortDriver.SetDataBits( Value: TDataBits ); +begin + // Set new data bits + FDataBits := Value; + // Apply changes + if Connected then + ApplyCOMSettings; +end; + +// Selects the number of stop bits +procedure TCommPortDriver.SetStopBits( Value: TStopBits ); +begin + // Set new stop bits + FStopBits := Value; + // Apply changes + if Connected then + ApplyCOMSettings; +end; + +// Selects the kind of parity +procedure TCommPortDriver.SetParity( Value: TParity ); +begin + // Set new parity + FParity := Value; + // Apply changes + if Connected then + ApplyCOMSettings; +end; + +// Selects the kind of hardware flow control +procedure TCommPortDriver.SetHwFlowControl( Value: THwFlowControl ); +begin + // Set new hardware flow control + FHwFlow := Value; + // Apply changes + if Connected then + ApplyCOMSettings; +end; + +// Selects the kind of software flow control +procedure TCommPortDriver.SetSwFlowControl( Value: TSwFlowControl ); +begin + // Set new software flow control + FSwFlow := Value; + // Apply changes + if Connected then + ApplyCOMSettings; +end; + +// Sets the RX buffer size +procedure TCommPortDriver.SetInBufSize( Value: DWORD ); +begin + // Do nothing if connected + if Connected then + exit; + // Free the temporary input buffer + FreeMem( FTempInBuffer, FInBufSize ); + // Set new input buffer size + if Value > 8192 then + Value := 8192 + else if Value < 128 then + Value := 128; + FInBufSize := Value; + // Allocate the temporary input buffer + FTempInBuffer := AllocMem( FInBufSize ); + // Adjust the RX packet size + SetPacketSize( FPacketSize ); +end; + +// Sets the TX buffer size +procedure TCommPortDriver.SetOutBufSize( Value: DWORD ); +begin + // Do nothing if connected + if Connected then + exit; + // Set new output buffer size + if Value > 8192 then + Value := 8192 + else if Value < 128 then + Value := 128; + FOutBufSize := Value; +end; + +// Sets the size of incoming packets +procedure TCommPortDriver.SetPacketSize( Value: smallint ); +begin + // PackeSize <= 0 if data isn't to be 'packetized' + if Value <= 0 then + FPacketSize := -1 + // If the PacketSize if greater than then RX buffer size then + // increase the RX buffer size + else if DWORD(Value) > FInBufSize then + begin + FPacketSize := Value; + SetInBufSize( FPacketSize ); + end; +end; + +// Sets the timeout for incoming packets +procedure TCommPortDriver.SetPacketTimeout( Value: integer ); +begin + // PacketTimeout <= 0 if packet timeout is to be disabled + if Value < 1 then + FPacketTimeout := -1 + // PacketTimeout cannot be less than polling delay + some extra ms + else if Value < FPollingDelay then + FPacketTimeout := FPollingDelay + (FPollingDelay*40) div 100; +end; + +// Sets the delay between polling checks +procedure TCommPortDriver.SetPollingDelay( Value: word ); +begin + // Make it greater than 4 ms + if Value < 5 then + Value := 5; + // If new delay is not equal to previous value... + if Value <> FPollingDelay then + begin + // Stop the timer + if Connected then + KillTimer( FNotifyWnd, 1 ); + // Store new delay value + FPollingDelay := Value; + // Restart the timer + if Connected then + SetTimer( FNotifyWnd, 1, FPollingDelay, nil ); + // Adjust the packet timeout + SetPacketTimeout( FPacketTimeout ); + end; +end; + +// Apply COM settings +function TCommPortDriver.ApplyCOMSettings: boolean; +var dcb: TDCB; +begin + // Do nothing if not connected + Result := false; + if not Connected then + exit; + + // ** Setup DCB (Device Control Block) fields ****************************** + + // Clear all + fillchar( dcb, sizeof(dcb), 0 ); + // DCB structure size + dcb.DCBLength := sizeof(dcb); + // Baud rate + dcb.BaudRate := FBaudRateValue; + // Set fBinary: Win32 does not support non binary mode transfers + // (also disable EOF check) + dcb.Flags := dcb_Binary; + // Enables the DTR line when the device is opened and leaves it on + if EnableDTROnOpen then + dcb.Flags := dcb.Flags or dcb_DtrControlEnable; + // Kind of hw flow control to use + case FHwFlow of + // No hw flow control + hfNONE:; + // No hw flow control but set RTS high and leave it high + hfNONERTSON: + dcb.Flags := dcb.Flags or dcb_RtsControlEnable; + // RTS/CTS (request-to-send/clear-to-send) flow control + hfRTSCTS: + dcb.Flags := dcb.Flags or dcb_OutxCtsFlow or dcb_RtsControlHandshake; + end; + // Kind of sw flow control to use + case FSwFlow of + // No sw flow control + sfNONE:; + // XON/XOFF sw flow control + sfXONXOFF: + dcb.Flags := dcb.Flags or dcb_OutX or dcb_InX; + end; + // Set XONLim: specifies the minimum number of bytes allowed in the input + // buffer before the XON character is sent (or CTS is set). + if (GetWinPlatform = 'WNT') and (GetWinVersion >= $00040000) then + begin + // WinNT 4.0 + Service Pack 3 needs XONLim to be less than or + // equal to 4096 bytes. Win95/98 doesn't have such limit. + if FInBufSize div 4 > 4096 then + dcb.XONLim := 4096 + else + dcb.XONLim := FInBufSize div 4; + end + else + dcb.XONLim := FInBufSize div 4; + // Specifies the maximum number of bytes allowed in the input buffer before + // the XOFF character is sent (or CTS is set low). The maximum number of bytes + // allowed is calculated by subtracting this value from the size, in bytes, of + // the input buffer. + dcb.XOFFLim := dcb.XONLim; + // How many data bits to use + dcb.ByteSize := 5 + ord(FDataBits); + // Kind of parity to use + dcb.Parity := ord(FParity); + // How many stop bits to use + dcb.StopBits := ord(FStopbits); + // XON ASCII char - DC1, Ctrl-Q, ASCII 17 + dcb.XONChar := #17; + // XOFF ASCII char - DC3, Ctrl-S, ASCII 19 + dcb.XOFFChar := #19; + + // Apply new settings + Result := SetCommState( FHandle, dcb ); + if not Result then + exit; + // Flush buffers + Result := FlushBuffers( true, true ); + if not Result then + exit; + // Setup buffers size + Result := SetupComm( FHandle, FInBufSize, FOutBufSize ); +end; + +function TCommPortDriver.Connect: boolean; +var tms: TCOMMTIMEOUTS; +begin + // not canceled + FCancel := false; + + // Do nothing if already connected + Result := Connected; + if Result then + exit; + // Open the COM port + FHandle := CreateFile( pchar(FPortName), + GENERIC_READ or GENERIC_WRITE, + 0, // Not shared + nil, // No security attributes + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + 0 // No template + ) ; + Result := Connected; + if not Result then + exit; + // Apply settings + Result := ApplyCOMSettings; + if not Result then + begin + Disconnect; + exit; + end; + // Set ReadIntervalTimeout: Specifies the maximum time, in milliseconds, + // allowed to elapse between the arrival of two characters on the + // communications line. + // We disable timeouts because we are polling the com port! + tms.ReadIntervalTimeout := 1; + // Set ReadTotalTimeoutMultiplier: Specifies the multiplier, in milliseconds, + // used to calculate the total time-out period for read operations. + tms.ReadTotalTimeoutMultiplier := 0; + // Set ReadTotalTimeoutConstant: Specifies the constant, in milliseconds, + // used to calculate the total time-out period for read operations. + tms.ReadTotalTimeoutConstant := 1; + // Set WriteTotalTimeoutMultiplier: Specifies the multiplier, in milliseconds, + // used to calculate the total time-out period for write operations. + tms.WriteTotalTimeoutMultiplier := 0; + // Set WriteTotalTimeoutConstant: Specifies the constant, in milliseconds, + // used to calculate the total time-out period for write operations. + tms.WriteTotalTimeoutConstant := 10; + // Apply timeouts + SetCommTimeOuts( FHandle, tms ); + // Start the timer (used for polling) + SetTimer( FNotifyWnd, 1, FPollingDelay, nil ); +end; + +procedure TCommPortDriver.Disconnect; +begin + // not canceled + FCancel := true; + + + if Connected then + begin + // Stop the timer (used for polling) + KillTimer( FNotifyWnd, 1 ); + // Release the COM port + CloseHandle( FHandle ); + // No more connected + FHandle := INVALID_HANDLE_VALUE; + end; +end; + +// Returns true if connected +function TCommPortDriver.Connected: boolean; +begin + Result := FHandle <> INVALID_HANDLE_VALUE; +end; + +// Returns CTS, DSR, RING and RLSD (CD) signals status +function TCommPortDriver.GetLineStatus: TLineStatusSet; +var dwS: DWORD; +begin + Result := []; + if not Connected then + exit; + // Retrieves modem control-register values. + // The function fails if the hardware does not support the control-register + // values. + if not GetCommModemStatus( FHandle, dwS ) then + exit; + if dwS and MS_CTS_ON <> 0 then Result := Result + [lsCTS]; + if dwS and MS_DSR_ON <> 0 then Result := Result + [lsDSR]; + if dwS and MS_RING_ON <> 0 then Result := Result + [lsRING]; + if dwS and MS_RLSD_ON <> 0 then Result := Result + [lsCD]; +end; + +// Returns true if polling has not been paused +function TCommPortDriver.IsPolling: boolean; +begin + Result := FRXPollingPauses <= 0; +end; + +// Pauses polling +procedure TCommPortDriver.PausePolling; +begin + // Inc. RX polling pauses counter + inc( FRXPollingPauses ); +end; + +// Re-starts polling (after pause) +procedure TCommPortDriver.ContinuePolling; +begin + // Dec. RX polling pauses counter + dec( FRXPollingPauses ); +end; + +// Flush rx/tx buffers +function TCommPortDriver.FlushBuffers( inBuf, outBuf: boolean ): boolean; +var dwAction: DWORD; +begin + // Do nothing if not connected + Result := false; + if not Connected then + exit; + // Flush the RX data buffer + dwAction := 0; + if outBuf then + dwAction := dwAction or PURGE_TXABORT or PURGE_TXCLEAR; + // Flush the TX data buffer + if inBuf then + dwAction := dwAction or PURGE_RXABORT or PURGE_RXCLEAR; + Result := PurgeComm( FHandle, dwAction ); + // Used by the RX packet mechanism + if Result then + FFirstByteOfPacketTime := DWORD(-1); +end; + +// Returns number of received bytes in the RX buffer +function TCommPortDriver.CountRX: integer; +var stat: TCOMSTAT; + errs: DWORD; +begin + // Do nothing if port has not been opened + Result := 65535; + if not Connected then + exit; + // Get count + ClearCommError( FHandle, errs, @stat ); + Result := stat.cbInQue; +end; + +// Returns the output buffer free space or 65535 if not connected +function TCommPortDriver.OutFreeSpace: word; +var stat: TCOMSTAT; + errs: DWORD; +begin + if not Connected then + Result := 65535 + else + begin + ClearCommError( FHandle, errs, @stat ); + Result := FOutBufSize - stat.cbOutQue; + end; +end; + +// Sends binary data. Returns number of bytes sent. Timeout overrides +// the value specifiend in the OutputTimeout property +function TCommPortDriver.SendDataEx( DataPtr: pchar; DataSize, Timeout: DWORD ): DWORD; +var nToSend, nSent, t1: DWORD; +begin + // Do nothing if port has not been opened + Result := 0; + if not Connected then + exit; + // Current time + t1 := GetTickCount; + // Loop until all data sent or timeout occurred + while DataSize > 0 do + begin + // Get TX buffer free space + nToSend := OutFreeSpace; + // If output buffer has some free space... + if nToSend > 0 then + begin + // Check signals + if FCkLineStatus and (GetLineStatus = []) then + exit; + // Don't send more bytes than we actually have to send + if nToSend > DataSize then + nToSend := DataSize; + // Send + WriteFile( FHandle, DataPtr^, nToSend, nSent, nil ); + nSent := abs( nSent ); + if nSent > 0 then + begin + // Update number of bytes sent + Result := Result + nSent; + // Decrease the count of bytes to send + DataSize := DataSize - nSent; + // Inc. data pointer + DataPtr := DataPtr + nSent; + // Get current time + t1 := GetTickCount; + // Continue. This skips the time check below (don't stop + // trasmitting if the Timeout is set too low) + continue; + end; + end; + // Buffer is full. If we are waiting too long then exit + if DWORD(GetTickCount-t1) > Timeout then + exit; + end; +end; + +// Send data (breaks the data in small packets if it doesn't fit in the output +// buffer) +function TCommPortDriver.SendData( DataPtr: pointer; DataSize: DWORD ): DWORD; +begin + Result := SendDataEx( DataPtr, DataSize, FOutputTimeout ); +end; + +// Sends a byte. Returns true if the byte has been sent +function TCommPortDriver.SendByte( Value: byte ): boolean; +begin + Result := SendData( @Value, 1 ) = 1; +end; + +// Sends a char. Returns true if the char has been sent +function TCommPortDriver.SendChar( Value: char ): boolean; +begin + Result := SendData( @Value, 1 ) = 1; +end; + +// Sends a pascal string (NULL terminated if $H+ (default)) +function TCommPortDriver.SendString( s: string ): boolean; +var len: DWORD; +begin + len := length( s ); + {$IFOPT H+} // New syle pascal string (NULL terminated) + Result := SendData( pchar(s), len ) = len; + {$ELSE} // Old style pascal string (s[0] = length) + Result := SendData( pchar(@s[1]), len ) = len; + {$ENDIF} +end; + +// Sends a C-style string (NULL terminated) +function TCommPortDriver.SendZString( s: pchar ): boolean; +var len: DWORD; +begin + len := strlen( s ); + Result := SendData( s, len ) = len; +end; + +// Reads binary data. Returns number of bytes read +function TCommPortDriver.ReadData( DataPtr: pchar; MaxDataSize: DWORD ): DWORD; +var nToRead, nRead, t1: DWORD; +begin + // Do nothing if port has not been opened + Result := 0; + if not Connected then + exit; + // Pause polling + PausePolling; + // Current time + t1 := GetTickCount; + // Loop until all requested data read or timeout occurred + while MaxDataSize > 0 do + begin + Application.ProcessMessages; // ##Vg process these messages + + if FCancel then exit; + + // Get data bytes count in RX buffer + nToRead := CountRX; + // If input buffer has some data... + if nToRead > 0 then + begin + // Don't read more bytes than we actually have to read + if nToRead > MaxDataSize then + nToRead := MaxDataSize; + // Read + ReadFile( FHandle, DataPtr^, nToRead, nRead, nil ); + // Update number of bytes read + Result := Result + nRead; + // Decrease the count of bytes to read + MaxDataSize := MaxDataSize - nRead; + // Inc. data pointer + DataPtr := DataPtr + nRead; + // Get current time + t1 := GetTickCount; + // Continue. This skips the time check below (don't stop + // reading if the FInputTimeout is set too low) + continue; + end; + // Buffer is empty. If we are waiting too long then exit + if (GetTickCount-t1) > FInputTimeout then + break; + end; + // Continue polling + ContinuePolling; +end; + +// Reads a byte. Returns true if the byte has been read +function TCommPortDriver.ReadByte( var Value: byte ): boolean; +begin + Result := ReadData( @Value, 1 ) = 1; +end; + +// Reads a char. Returns true if char has been read +function TCommPortDriver.ReadChar( var Value: char ): boolean; +begin + Result := ReadData( @Value, 1 ) = 1; +end; + +// Set DTR line high (onOff=TRUE) or low (onOff=FALSE). +// You must not use HW handshaking. +procedure TCommPortDriver.ToggleDTR( onOff: boolean ); +const funcs: array[boolean] of integer = (CLRDTR,SETDTR); +begin + if Connected then + EscapeCommFunction( FHandle, funcs[onOff] ); +end; + +// Set RTS line high (onOff=TRUE) or low (onOff=FALSE). +// You must not use HW handshaking. +procedure TCommPortDriver.ToggleRTS( onOff: boolean ); +const funcs: array[boolean] of integer = (CLRRTS,SETRTS); +begin + if Connected then + EscapeCommFunction( FHandle, funcs[onOff] ); +end; + +// COM port polling proc +procedure TCommPortDriver.TimerWndProc( var msg: TMessage ); +var nRead, nToRead, dummy: DWORD; + comStat: TCOMSTAT; +begin + if (msg.Msg = WM_TIMER) and Connected then + begin + // Do nothing if RX polling has been paused + if FRXPollingPauses > 0 then + exit; + // If PacketSize is > 0 then raise the OnReceiveData event only if the RX + // buffer has at least PacketSize bytes in it. + ClearCommError( FHandle, dummy, @comStat ); + if FPacketSize > 0 then + begin + // Complete packet received ? + if DWORD(comStat.cbInQue) >= DWORD(FPacketSize) then + begin + repeat + // Read the packet and pass it to the app + nRead := 0; + if ReadFile( FHandle, FTempInBuffer^, FPacketSize, nRead, nil ) then + if (nRead <> 0) and Assigned(FOnReceivePacket) then + FOnReceivePacket( Self, FTempInBuffer, nRead ); + // Adjust time + //if comStat.cbInQue >= FPacketSize then + FFirstByteOfPacketTime := FFirstByteOfPacketTime + + DelayForRX( FBaudRate, FPacketSize ); + comStat.cbInQue := comStat.cbInQue - WORD(FPacketSize); + if comStat.cbInQue = 0 then + FFirstByteOfPacketTime := DWORD(-1); + until DWORD(comStat.cbInQue) < DWORD(FPacketSize); + // Done + exit; + end; + // Handle packet timeouts + if (FPacketTimeout > 0) and (FFirstByteOfPacketTime <> DWORD(-1)) and + (GetTickCount - FFirstByteOfPacketTime > DWORD(FPacketTimeout)) then + begin + nRead := 0; + // Read the "incomplete" packet + if ReadFile( FHandle, FTempInBuffer^, comStat.cbInQue, nRead, nil ) then + // If PacketMode is not pmDiscard then pass the packet to the app + if (FPacketMode <> pmDiscard) and (nRead <> 0) and Assigned(FOnReceivePacket) then + FOnReceivePacket( Self, FTempInBuffer, nRead ); + // Restart waiting for a packet + FFirstByteOfPacketTime := DWORD(-1); + // Done + exit; + end; + // Start time + if (comStat.cbInQue > 0) and (FFirstByteOfPacketTime = DWORD(-1)) then + FFirstByteOfPacketTime := GetTickCount; + // Done + exit; + end; + + // Standard data handling + nRead := 0; + nToRead := comStat.cbInQue; + if (nToRead > 0) and ReadFile( FHandle, FTempInBuffer^, nToRead, nRead, nil ) then + if (nRead <> 0) and Assigned(FOnReceiveData) then + FOnReceiveData( Self, FTempInBuffer, nRead ); + end + // Let Windows handle other messages + else + Msg.Result := DefWindowProc( FNotifyWnd, Msg.Msg, Msg.wParam, Msg.lParam ) ; +end; + +end. diff --git a/Host/Source/interfaces/uart/XcpSettings.dfm b/Host/Source/interfaces/uart/XcpSettings.dfm new file mode 100644 index 00000000..6d833d1d Binary files /dev/null and b/Host/Source/interfaces/uart/XcpSettings.dfm differ diff --git a/Host/Source/interfaces/uart/XcpSettings.pas b/Host/Source/interfaces/uart/XcpSettings.pas new file mode 100644 index 00000000..e9ac7299 --- /dev/null +++ b/Host/Source/interfaces/uart/XcpSettings.pas @@ -0,0 +1,270 @@ +unit XcpSettings; +//*************************************************************************************** +// Description: XCP settings interface for SCI +// File Name: XcpSettings.pas +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** +interface + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, ComCtrls, ExtCtrls, IniFiles; + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +type + TXcpSettingsForm = class(TForm) + pnlFooter: TPanel; + btnOK: TButton; + btnCancel: TButton; + pageControl: TPageControl; + tabXcp: TTabSheet; + tabSci: TTabSheet; + iconSci: TImage; + lblSci: TLabel; + lblXcp: TLabel; + iconXcp2: TImage; + lblComport: TLabel; + cmbComport: TComboBox; + lblBaudrate: TLabel; + cmbBaudrate: TComboBox; + lblT1: TLabel; + lblT3: TLabel; + lblT4: TLabel; + lblT5: TLabel; + lblT7: TLabel; + edtT1: TEdit; + edtT3: TEdit; + edtT4: TEdit; + edtT5: TEdit; + edtT7: TEdit; + tabProt: TTabSheet; + iconXcp1: TImage; + lblPort: TLabel; + edtSeedKey: TEdit; + btnBrowse: TButton; + openDialog: TOpenDialog; + procedure btnOKClick(Sender: TObject); + procedure btnCancelClick(Sender: TObject); + procedure btnBrowseClick(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + end; + +type + TXcpSettings = class(TObject) + private + FSettingsForm : TXcpSettingsForm; + FIniFile : string; + public + constructor Create(iniFile : string); + destructor Destroy; override; + function Configure : Boolean; + end; + + +implementation +{$R *.DFM} +//*************************************************************************************** +// NAME: btnOKClick +// PARAMETER: none +// RETURN VALUE: modal result +// DESCRIPTION: Sets the module result to okay. +// +//*************************************************************************************** +procedure TXcpSettingsForm.btnOKClick(Sender: TObject); +begin + ModalResult := mrOK; +end; //*** end of btnOKClick *** + + +//*************************************************************************************** +// NAME: btnCancelClick +// PARAMETER: none +// RETURN VALUE: modal result +// DESCRIPTION: Sets the module result to cancel. +// +//*************************************************************************************** +procedure TXcpSettingsForm.btnCancelClick(Sender: TObject); +begin + ModalResult := mrCancel; +end; //*** end of btnCancelClick *** + + +//*************************************************************************************** +// NAME: btnBrowseClick +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Prompts the user to select the seed/key dll file. +// +//*************************************************************************************** +procedure TXcpSettingsForm.btnBrowseClick(Sender: TObject); +begin + openDialog.InitialDir := ExtractFilePath(ParamStr(0)); + if openDialog.Execute then + begin + edtSeedKey.Text := openDialog.FileName; + end; +end; //*** end of btnBrowseClick *** + + +//*************************************************************************************** +// NAME: Create +// PARAMETER: Name of the INI file where the settings are and will be stored +// RETURN VALUE: none +// DESCRIPTION: Class constructor +// +//*************************************************************************************** +constructor TXcpSettings.Create(iniFile : string); +begin + // call inherited constructor + inherited Create; + + // set the inifile + FIniFile := iniFile; + + // create an instance of the settings form + FSettingsForm := TXcpSettingsForm.Create(nil); +end; //*** end of Create *** + + +//*************************************************************************************** +// NAME: Destroy +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class destructor +// +//*************************************************************************************** +destructor TXcpSettings.Destroy; +begin + // releaase the settings form object + FSettingsForm.Free; + + // call inherited destructor + inherited; +end; //*** end of Destroy *** + + +//*************************************************************************************** +// NAME: Configure +// PARAMETER: none +// RETURN VALUE: True if configuration was successfully changed, False otherwise +// DESCRIPTION: Allows the user to configure the XCP interface using a GUI. +// +//*************************************************************************************** +function TXcpSettings.Configure : Boolean; +var + settingsIni: TIniFile; +begin + // initialize the return value + result := false; + + // init the form elements using the configuration found in the INI + if FileExists(FIniFile) then + begin + // create ini file object + settingsIni := TIniFile.Create(FIniFile); + + // SCI related elements + FSettingsForm.cmbComport.ItemIndex := settingsIni.ReadInteger('sci', 'port', 0); + FSettingsForm.cmbBaudrate.ItemIndex := settingsIni.ReadInteger('sci', 'baudrate', 6); + + // XCP related elements + FSettingsForm.edtSeedKey.Text := settingsIni.ReadString('xcp', 'seedkey', ExtractFilePath(ParamStr(0))+''); + FSettingsForm.edtT1.Text := IntToStr(settingsIni.ReadInteger('xcp', 't1', 1000)); + FSettingsForm.edtT3.Text := IntToStr(settingsIni.ReadInteger('xcp', 't3', 2000)); + FSettingsForm.edtT4.Text := IntToStr(settingsIni.ReadInteger('xcp', 't4', 10000)); + FSettingsForm.edtT5.Text := IntToStr(settingsIni.ReadInteger('xcp', 't5', 1000)); + FSettingsForm.edtT7.Text := IntToStr(settingsIni.ReadInteger('xcp', 't7', 2000)); + + // release ini file object + settingsIni.Free; + end + else + begin + // set defaults + // SCI related elements + FSettingsForm.cmbComport.ItemIndex := 0; + FSettingsForm.cmbBaudrate.ItemIndex := 6; + + // XCP related elements + FSettingsForm.edtSeedKey.Text := ExtractFilePath(ParamStr(0))+''; + FSettingsForm.edtT1.Text := IntToStr(1000); + FSettingsForm.edtT3.Text := IntToStr(2000); + FSettingsForm.edtT4.Text := IntToStr(10000); + FSettingsForm.edtT5.Text := IntToStr(1000); + FSettingsForm.edtT7.Text := IntToStr(2000); + + end; + + // show the form as modal so we can get the result here + if FSettingsForm.ShowModal = mrOK then + begin + if FIniFile <> '' then + begin + // create ini file object + settingsIni := TIniFile.Create(FIniFile); + + // SCI related elements + settingsIni.WriteInteger('sci', 'port', FSettingsForm.cmbComport.ItemIndex); + settingsIni.WriteInteger('sci', 'baudrate', FSettingsForm.cmbBaudrate.ItemIndex); + + // XCP related elements + settingsIni.WriteString('xcp', 'seedkey', FSettingsForm.edtSeedKey.Text); + settingsIni.WriteInteger('xcp', 't1', StrToInt(FSettingsForm.edtT1.Text)); + settingsIni.WriteInteger('xcp', 't3', StrToInt(FSettingsForm.edtT3.Text)); + settingsIni.WriteInteger('xcp', 't4', StrToInt(FSettingsForm.edtT4.Text)); + settingsIni.WriteInteger('xcp', 't5', StrToInt(FSettingsForm.edtT5.Text)); + settingsIni.WriteInteger('xcp', 't7', StrToInt(FSettingsForm.edtT7.Text)); + + // release ini file object + settingsIni.Free; + + // indicate that the settings where successfully updated + result := true; + end; + end; +end; //*** end of Configure *** + + +end. +//******************************** end of XcpSettings.pas ******************************* + + diff --git a/Host/Source/interfaces/uart/XcpTransport.pas b/Host/Source/interfaces/uart/XcpTransport.pas new file mode 100644 index 00000000..dd7ebf6d --- /dev/null +++ b/Host/Source/interfaces/uart/XcpTransport.pas @@ -0,0 +1,267 @@ +unit XcpTransport; +//*************************************************************************************** +// Description: XCP transport layer for SCI. +// File Name: XcpTransport.pas +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** +interface + + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, Messages, SysUtils, Classes, Forms, CPDrv, IniFiles; + + +//*************************************************************************************** +// Global Constants +//*************************************************************************************** +const kMaxPacketSize = 256; + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +type + TXcpTransport = class(TObject) + private + public + packetData : array[0..kMaxPacketSize-1] of Byte; + packetLen : Word; + sciDriver : TCommPortDriver; + constructor Create; + procedure Configure(iniFile : string); + procedure Connect; + function SendPacket(timeOutms: LongWord): Boolean; + procedure Disconnect; + destructor Destroy; override; + end; + + +implementation + +//*************************************************************************************** +// NAME: Create +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class constructore +// +//*************************************************************************************** +constructor TXcpTransport.Create; +begin + // call inherited constructor + inherited Create; + + // create a sci driver instance + sciDriver := TCommPortDriver.Create(nil); + + // init sci settings + sciDriver.DataBits := db8BITS; + sciDriver.StopBits := sb1BITS; + sciDriver.Parity := ptNONE; + sciDriver.SwFlow := sfNONE; + sciDriver.PollingDelay := 5; + + // reset packet length + packetLen := 0; +end; //*** end of Create *** + + +//*************************************************************************************** +// NAME: Destroy +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Class destructor +// +//*************************************************************************************** +destructor TXcpTransport.Destroy; +begin + // release sci driver instance + sciDriver.Free; + + // call inherited destructor + inherited; +end; //*** end of Destroy *** + + +//*************************************************************************************** +// NAME: Configure +// PARAMETER: filename of the INI +// RETURN VALUE: none +// DESCRIPTION: Configures both this class from the settings in the INI. +// +//*************************************************************************************** +procedure TXcpTransport.Configure(iniFile : string); +var + settingsIni : TIniFile; + configIndex : integer; +begin + // read XCP configuration from INI + if FileExists(iniFile) then + begin + // create ini file object + settingsIni := TIniFile.Create(iniFile); + + // configure baudrate + configIndex := settingsIni.ReadInteger('sci', 'baudrate', 6); + sciDriver.BaudRate := br38400; // init to default value + case configIndex of + 0 : sciDriver.BaudRate := br1200; + 1 : sciDriver.BaudRate := br2400; + 2 : sciDriver.BaudRate := br4800; + 3 : sciDriver.BaudRate := br9600; + 4 : sciDriver.BaudRate := br14400; + 5 : sciDriver.BaudRate := br19200; + 6 : sciDriver.BaudRate := br38400; + 7 : sciDriver.BaudRate := br56000; + 8 : sciDriver.BaudRate := br57600; + 9 : sciDriver.BaudRate := br115200; + 10: sciDriver.BaudRate := br128000; + 11: sciDriver.BaudRate := br256000; + end; + + // configure port + configIndex := settingsIni.ReadInteger('sci', 'port', 0); + sciDriver.Port := pnCOM1; // init to default value + case configIndex of + 0 : sciDriver.Port := pnCOM1; + 1 : sciDriver.Port := pnCOM2; + 2 : sciDriver.Port := pnCOM3; + 3 : sciDriver.Port := pnCOM4; + 4 : sciDriver.Port := pnCOM5; + 5 : sciDriver.Port := pnCOM6; + 6 : sciDriver.Port := pnCOM7; + 7 : sciDriver.Port := pnCOM8; + end; + + // release ini file object + settingsIni.Free; + end; +end; //*** end of Configure *** + + +//*************************************************************************************** +// NAME: Connect +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Connects the transport layer device. +// +//*************************************************************************************** +procedure TXcpTransport.Connect; +begin + if not sciDriver.Connect then + Application.MessageBox( 'Could not connect to COM port.', + 'Error', MB_OK or MB_ICONERROR ); +end; //*** end of Connect *** + + +//*************************************************************************************** +// NAME: SendPacket +// PARAMETER: the time[ms] allowed for the reponse from the slave to come in. +// RETURN VALUE: True if response received from slave, False otherwise +// DESCRIPTION: Sends the XCP packet using the data in 'packetData' and length in +// 'packetLen' and waits for the response to come in. +// +//*************************************************************************************** +function TXcpTransport.SendPacket(timeOutms: LongWord): Boolean; +var + msgData : array of Byte; + resLen : byte; + cnt : byte; + dwEnd :DWord; +begin + // init the return value + result := false; + + // prepare the packet. length goes in the first byte followed by the packet data + SetLength(msgData, packetLen+1); + msgData[0] := packetLen; + for cnt := 0 to packetLen-1 do + begin + msgData[cnt+1] := packetData[cnt]; + end; + + // submit the packet transmission request + if sciDriver.SendData(@msgData[0], packetLen+1) <> (packetLen+1) then + begin + // unable to submit tx request + Exit; + end; + + // compute timeout time + dwEnd := GetTickCount + timeOutms; + + // configure timeout for first byte + sciDriver.InputTimeout := timeOutms; + + // receive the first byte which holds the packet length + if sciDriver.ReadByte(resLen) = true then + begin + timeOutms := GetTickCount; + if timeOutms < dwEnd then + begin + // configure timeout for remaining bytes + sciDriver.InputTimeout := dwEnd - timeOutms; + end + else + begin + Exit; // timed out + end; + + // receive the actual packet data + if sciDriver.ReadData(@packetData[0], resLen) = resLen then + begin + packetLen := resLen; + result := true; + end; + end; +end; //*** end of SendPacket *** + + +//*************************************************************************************** +// NAME: Disconnect +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Disconnects the transport layer device. +// +//*************************************************************************************** +procedure TXcpTransport.Disconnect; +begin + sciDriver.Disconnect; +end; //*** end of Disconnect *** + + +end. +//******************************** end of XcpTransport.pas ****************************** + diff --git a/Host/Source/interfaces/uart/openblt_uart.cfg b/Host/Source/interfaces/uart/openblt_uart.cfg new file mode 100644 index 00000000..c757c9ae --- /dev/null +++ b/Host/Source/interfaces/uart/openblt_uart.cfg @@ -0,0 +1,35 @@ +-$A+ +-$B- +-$C+ +-$D+ +-$E- +-$F- +-$G+ +-$H+ +-$I+ +-$J+ +-$K- +-$L+ +-$M- +-$N+ +-$O+ +-$P+ +-$Q- +-$R- +-$S- +-$T- +-$U- +-$V+ +-$W- +-$X+ +-$YD +-$Z1 +-cg +-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +-H+ +-W+ +-M +-$M16384,1048576 +-K$00400000 +-E../../../ +-LNc:\program files (x86)\borland\delphi4\Lib diff --git a/Host/Source/interfaces/uart/openblt_uart.dof b/Host/Source/interfaces/uart/openblt_uart.dof new file mode 100644 index 00000000..09cc9d39 --- /dev/null +++ b/Host/Source/interfaces/uart/openblt_uart.dof @@ -0,0 +1,86 @@ +[Compiler] +A=1 +B=0 +C=1 +D=1 +E=0 +F=0 +G=1 +H=1 +I=1 +J=1 +K=0 +L=1 +M=0 +N=1 +O=1 +P=1 +Q=0 +R=0 +S=0 +T=0 +U=0 +V=1 +W=0 +X=1 +Y=1 +Z=1 +ShowHints=1 +ShowWarnings=1 +UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +[Linker] +MapFile=0 +OutputObjs=0 +ConsoleApp=1 +DebugInfo=0 +RemoteSymbols=0 +MinStackSize=16384 +MaxStackSize=1048576 +ImageBase=4194304 +ExeDescription= +[Directories] +OutputDir=../../../ +UnitOutputDir= +PackageDLLOutputDir= +PackageDCPOutputDir= +SearchPath= +Packages=Vcl40;Vclx40;Vcldb40;vcldbx40;VclSmp40;Qrpt40 +Conditionals= +DebugSourceDirs= +UsePackages=0 +[Parameters] +RunParams= +HostApplication= +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1031 +CodePage=1252 +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= +[Excluded Packages] +$(DELPHI)\Lib\dclusr40.bpl=Borland User +[HistoryLists\hlUnitAliases] +Count=1 +Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +[HistoryLists\hlOutputDirectorry] +Count=1 +Item0=../../../ diff --git a/Host/Source/interfaces/uart/openblt_uart.dpr b/Host/Source/interfaces/uart/openblt_uart.dpr new file mode 100644 index 00000000..c1a78482 --- /dev/null +++ b/Host/Source/interfaces/uart/openblt_uart.dpr @@ -0,0 +1,605 @@ +library openblt_uart; +//*************************************************************************************** +// Project Name: MicroBoot Interface for Borland Delphi +// Description: XCP - SCI interface for MicroBoot +// File Name: openblt_uart.dpr +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// L I C E N S E +//--------------------------------------------------------------------------------------- +// This file is part of OpenBLT. OpenBLT 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. +// +// OpenBLT 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 OpenBLT. +// If not, see . +// +// A special exception to the GPL is included to allow you to distribute a combined work +// that includes OpenBLT without being obliged to provide the source code for any +// proprietary components. The exception text is included at the bottom of the license +// file . +// +//*************************************************************************************** + + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, + Messages, + Graphics, + Controls, + Forms, + Dialogs, + SysUtils, + Classes, + Extctrls, + XcpProtection in '..\XcpProtection.pas', + SRecReader in '..\SRecReader.pas', + XcpDataFile in '..\XcpDataFile.pas', + XcpLoader in '..\XcpLoader.pas', + XcpTransport in 'XcpTransport.pas', + XcpSettings in 'XcpSettings.pas' {XcpSettingsForm}, + CPDrv in 'CPDrv.pas'; + + +//*************************************************************************************** +// Global Constants +//*************************************************************************************** +const kMaxProgLen = 256; // maximum number of bytes to progam at one time + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +// DLL Interface Callbacks - modifications requires potential update of all interfaces! +type + TStartedEvent = procedure(length: Longword) of object; + TProgressEvent = procedure(progress: Longword) of object; + TDoneEvent = procedure of object; + TErrorEvent = procedure(error: ShortString) of object; + TLogEvent = procedure(info: ShortString) of object; + TInfoEvent = procedure(info: ShortString) of object; + +type + TEventHandlers = class // create a dummy class + procedure OnTimeout(Sender: TObject); + end; + +//*************************************************************************************** +// Global Variables +//*************************************************************************************** +var + //--- begin of don't change --- + AppOnStarted : TStartedEvent; + AppOnProgress : TProgressEvent; + AppOnDone : TDoneEvent; + AppOnError : TErrorEvent; + AppOnLog : TLogEvent; + AppOnInfo : TInfoEvent; + //--- end of don't change --- + timer : TTimer; + events : TEventHandlers; + loader : TXcpLoader; + datafile : TXcpDataFile; + progdata : array of Byte; + progfile : string; + stopRequest : boolean; + + +//*************************************************************************************** +// NAME: MbiCallbackOnStarted +// PARAMETER: length of the file that is being downloaded. +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnStarted(length: Longword); +begin + if Assigned(AppOnStarted) then + begin + AppOnStarted(length); + end; +end; //** end of MbiCallbackOnStarted *** + + +//*************************************************************************************** +// NAME: MbiCallbackOnProgress +// PARAMETER: progress of the file download. +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnProgress(progress: Longword); +begin + if Assigned(AppOnProgress) then + begin + AppOnProgress(progress); + end; +end; //** end of MbiCallbackOnProgress *** + + +//*************************************************************************************** +// NAME: MbiCallbackOnDone +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnDone; +begin + if Assigned(AppOnDone) then + begin + AppOnDone; + end; +end; //** end of MbiCallbackOnDone *** + + +//*************************************************************************************** +// NAME: MbiCallbackOnError +// PARAMETER: info about the error that occured. +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnError(error: ShortString); +begin + if Assigned(AppOnError) then + begin + AppOnError(error); + end; +end; //** end of MbiCallbackOnError *** + + +//*************************************************************************************** +// NAME: MbiCallbackOnLog +// PARAMETER: info on the log event. +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnLog(info: ShortString); +begin + if Assigned(AppOnLog) then + begin + AppOnLog(info); + end; +end; //** end of MbiCallbackOnLog *** + + +//*************************************************************************************** +// NAME: MbiCallbackOnInfo +// PARAMETER: details on the info event. +// RETURN VALUE: none +// DESCRIPTION: Wrapper function for safely calling an application callback +// +//*************************************************************************************** +procedure MbiCallbackOnInfo(info: ShortString); +begin + if Assigned(AppOnInfo) then + begin + AppOnInfo(info); + end; +end; //** end of MbiCallbackOnLog *** + + +//*************************************************************************************** +// NAME: LogData +// PARAMETER: pointer to byte array and the data length +// RETURN VALUE: none +// DESCRIPTION: Writes the program data formatted to the logfile +// +//*************************************************************************************** +procedure LogData(data : PByteArray; len : longword); stdcall; +var + currentWriteCnt : byte; + cnt : byte; + logStr : string; + bufferOffset : longword; +begin + bufferOffset := 0; + + while len > 0 do + begin + // set the current write length optimized to log 32 bytes per line + currentWriteCnt := len mod 32; + if currentWriteCnt = 0 then currentWriteCnt := 32; + logStr := ''; + + // prepare the line to add to the log + for cnt := 0 to currentWriteCnt-1 do + begin + logStr := logStr + Format('%2.2x ', [data[bufferOffset+cnt]]); + end; + + // update the log + MbiCallbackOnLog(logStr); + + // update loop variables + len := len - currentWriteCnt; + bufferOffset := bufferOffset + currentWriteCnt; + end; +end; //*** end of LogData *** + + +//*************************************************************************************** +// NAME: OnTimeout +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Timer event handler. A timer is used in this example to simulate the +// progress of a file download. It also demonstrates how to use the +// application callbacks to keep the application informed. +// +//*************************************************************************************** +procedure TEventHandlers.OnTimeout(Sender: TObject); +var + errorInfo : string; + progress : longword; + regionCnt : longword; + currentWriteCnt : word; + bufferOffset : longword; + addr : longword; + len : longword; + dataSizeKB : real; +begin + timer.Enabled := False; + + // connect the transport layer + MbiCallbackOnLog('Connecting the transport layer. t='+TimeToStr(Time)); + loader.Connect; + + //---------------- start the programming session -------------------------------------- + MbiCallbackOnLog('Starting the programming session. t='+TimeToStr(Time)); + + if not loader.StartProgrammingSession then + begin + // update the user info + MbiCallbackOnInfo('Could not connect. Please reset your target...'); + MbiCallbackOnLog('Connect failed. Switching to backdoor entry mode. t='+TimeToStr(Time)); + Application.ProcessMessages; + end; + + while not loader.StartProgrammingSession do + begin + Application.ProcessMessages; + Sleep(5); + if stopRequest then + begin + MbiCallbackOnError('Programming session cancelled by user.'); + Exit; + end; + end; + + // still here so programming session was started + MbiCallbackOnLog('Programming session started. t='+TimeToStr(Time)); + + // create the datafile object + datafile := TXcpDataFile.Create(progfile); + + // compute the size in kbytes + dataSizeKB := datafile.GetDataCnt / 1024; + + // Call application callback when we start the actual download + MbiCallbackOnStarted(datafile.GetDataCnt); + + // Init progress to 0 progress + progress := 0; + MbiCallbackOnProgress(progress); + + //---------------- next clear the memory regions -------------------------------------- + // update the user info + MbiCallbackOnInfo('Erasing memory...'); + + for regionCnt := 0 to datafile.GetRegionCnt-1 do + begin + // obtain the region info + datafile.GetRegionInfo(regionCnt, addr, len); + + // erase the memory + MbiCallbackOnLog('Clearing Memory '+Format('addr:0x%x,len:0x%x',[addr,len])+'. t='+TimeToStr(Time)); + if not loader.ClearMemory(addr, len) then + begin + loader.GetLastError(errorInfo); + MbiCallbackOnLog('Could not clear memory ('+errorInfo+'). t='+TimeToStr(Time)); + MbiCallbackOnError('Could not clear memory ('+errorInfo+').'); + datafile.Free; + Exit; + end; + MbiCallbackOnLog('Memory cleared. t='+TimeToStr(Time)); + end; + + //---------------- next program the memory regions ------------------------------------ + for regionCnt := 0 to datafile.GetRegionCnt-1 do + begin + // update the user info + MbiCallbackOnInfo('Reading file...'); + + // obtain the region info + datafile.GetRegionInfo(regionCnt, addr, len); + // dynamically allocated buffer memory + SetLength(progdata, len); + // obtain the regiond data + datafile.GetRegionData(regionCnt, progdata); + + bufferOffset := 0; + while len > 0 do + begin + // set the current write length taking into account kMaxProgLen + currentWriteCnt := len mod kMaxProgLen; + if currentWriteCnt = 0 then currentWriteCnt := kMaxProgLen; + + // program the data + MbiCallbackOnLog('Programming Data '+Format('addr:0x%x,len:0x%x',[addr,currentWriteCnt])+'. t='+TimeToStr(Time)); + LogData(@progdata[bufferOffset], currentWriteCnt); + + if not loader.WriteData(addr, currentWriteCnt, @progdata[bufferOffset]) then + begin + loader.GetLastError(errorInfo); + MbiCallbackOnLog('Could not program data ('+errorInfo+'). t='+TimeToStr(Time)); + MbiCallbackOnError('Could not program data ('+errorInfo+').'); + datafile.Free; + Exit; + end; + MbiCallbackOnLog('Data Programmed. t='+TimeToStr(Time)); + + // update progress + progress := progress + currentWriteCnt; + MbiCallbackOnProgress(progress); + + // update loop variables + len := len - currentWriteCnt; + addr := addr + currentWriteCnt; + bufferOffset := bufferOffset + currentWriteCnt; + + // update the user info + MbiCallbackOnInfo('Programming data... ' + Format('(%.1n of %.1n Kbytes)',[(progress/1024), dataSizeKB])); + + end; + end; + + //---------------- stop the programming session --------------------------------------- + MbiCallbackOnLog('Stopping the programming session. t='+TimeToStr(Time)); + if not loader.StopProgrammingSession then + begin + loader.GetLastError(errorInfo); + MbiCallbackOnLog('Could not stop the programming session ('+errorInfo+'). t='+TimeToStr(Time)); + MbiCallbackOnError('Could not stop the programming session ('+errorInfo+').'); + datafile.Free; + Exit; + end; + MbiCallbackOnLog('Programming session stopped. t='+TimeToStr(Time)); + + // all done so set progress to 100% and finish up + progress := datafile.GetDataCnt; + datafile.Free; + MbiCallbackOnProgress(progress); + MbiCallbackOnLog('File successfully downloaded t='+TimeToStr(Time)); + MbiCallbackOnDone; + +end; //*** end of OnTimeout *** + + +//*************************************************************************************** +// NAME: MbiInit +// PARAMETER: callback function pointers +// RETURN VALUE: none +// DESCRIPTION: Called by the application to initialize the interface library. +// +//*************************************************************************************** +procedure MbiInit(cbStarted: TStartedEvent; cbProgress: TProgressEvent; + cbDone: TDoneEvent; cbError: TErrorEvent; cbLog: TLogEvent; + cbInfo: TInfoEvent); stdcall; +begin + //--- begin of don't change --- + AppOnStarted := cbStarted; + AppOnProgress := cbProgress; + AppOnDone := cbDone; + AppOnLog := cbLog; + AppOnInfo := cbInfo; + AppOnError := cbError; + //--- end of don't change --- + + // create xcp loader object + loader := TXcpLoader.Create; + + // update to the latest configuration + loader.Configure(ExtractFilePath(ParamStr(0))+'openblt_uart.ini'); + + // create and init a timer + events := TEventHandlers.Create; + timer := TTimer.Create(nil); + timer.Enabled := False; + timer.Interval := 100; + timer.OnTimer := events.OnTimeout; +end; //*** end of MbiInit *** + + +//*************************************************************************************** +// NAME: MbiStart +// PARAMETER: filename of the file that is to be downloaded. +// RETURN VALUE: none +// DESCRIPTION: Called by the application to request the interface library to download +// the file that is passed as a parameter. +// +//*************************************************************************************** +procedure MbiStart(fileName: ShortString); stdcall; +begin + // update the user info + MbiCallbackOnInfo(''); + + // start the log + MbiCallbackOnLog('--- Downloading "'+fileName+'" ---'); + + // reset stop request + stopRequest := false; + + // start the startup timer which gives microBoot a chance to paint itself + timer.Enabled := True; + + // store the program's filename + progfile := fileName; +end; //*** end of MbiStart *** + + +//*************************************************************************************** +// NAME: MbiStop +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Called by the application to request the interface library to stop +// a download that could be in progress. +// +//*************************************************************************************** +procedure MbiStop; stdcall; +begin + // set stop request + stopRequest := true; + + // disconnect the transport layer + MbiCallbackOnLog('Disconnecting the transport layer. t='+TimeToStr(Time)); + loader.Disconnect; +end; //*** end of MbiStop *** + + +//*************************************************************************************** +// NAME: MbiDeInit +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Called by the application to uninitialize the interface library. +// +//*************************************************************************************** +procedure MbiDeInit; stdcall; +begin + // release xcp loader object + loader.Free; + + // release the timer and events object + timer.Free; + events.Free; + + //--- begin of don't change --- + AppOnStarted := nil; + AppOnProgress := nil; + AppOnDone := nil; + AppOnLog := nil; + AppOnInfo := nil; + AppOnError := nil; + //--- end of don't change --- +end; //*** end of MbiDeInit *** + + +//*************************************************************************************** +// NAME: MbiName +// PARAMETER: none +// RETURN VALUE: name of the interface library +// DESCRIPTION: Called by the application to obtain the name of the interface library. +// +//*************************************************************************************** +function MbiName : ShortString; stdcall; +begin + Result := 'OpenBLT UART'; +end; //*** end of MbiName *** + + +//*************************************************************************************** +// NAME: MbiDescription +// PARAMETER: none +// RETURN VALUE: description of the interface library +// DESCRIPTION: Called by the application to obtain the description of the interface +// library. +// +//*************************************************************************************** +function MbiDescription : ShortString; stdcall; +begin + Result := 'OpenBLT using UART'; +end; //*** end of MbiDescription *** + + +//*************************************************************************************** +// NAME: MbiVersion +// PARAMETER: none +// RETURN VALUE: version number +// DESCRIPTION: Called by the application to obtain the version number of the +// interface library. +// +//*************************************************************************************** +function MbiVersion : Longword; stdcall; +begin + Result := 10000; // v1.00.00 +end; //*** end of MbiVersion *** + + +//*************************************************************************************** +// NAME: MbiVInterface +// PARAMETER: none +// RETURN VALUE: version number of the supported interface +// DESCRIPTION: Called by the application to obtain the version number of the +// Mbi interface uBootInterface.pas (not the interface library). This can +// be used by the application for backward compatibility. +// +//*************************************************************************************** +function MbiVInterface : Longword; stdcall; +begin + Result := 10001; // v1.00.01 +end; //*** end of MbiVInterface *** + + +//*************************************************************************************** +// NAME: MbiConfigure +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Called by the application to enable the user to configure the inter- +// face library through the application. +// +//*************************************************************************************** +procedure MbiConfigure; stdcall; +var + settings : TXcpSettings; +begin + // create xcp settings object + settings := TXcpSettings.Create(ExtractFilePath(ParamStr(0))+'openblt_uart.ini'); + + // display the modal configuration dialog + settings.Configure; + + // release the xcp settings object + settings.Free; + + // update to the latest configuration + loader.Configure(ExtractFilePath(ParamStr(0))+'openblt_uart.ini'); +end; //*** end of MbiConfigure *** + + +//*************************************************************************************** +// External Declarations +//*************************************************************************************** +exports + //--- begin of don't change --- + MbiInit index 1, + MbiStart index 2, + MbiStop index 3, + MbiDeInit index 4, + MbiName index 5, + MbiDescription index 6, + MbiVersion index 7, + MbiConfigure index 8, + MbiVInterface index 9; + //--- end of don't change --- + +end. +//********************************** end of openblt_uart.dpr **************************** diff --git a/Host/Source/uBootInterface.pas b/Host/Source/uBootInterface.pas new file mode 100644 index 00000000..0af2e588 --- /dev/null +++ b/Host/Source/uBootInterface.pas @@ -0,0 +1,422 @@ +unit uBootInterface; +//*************************************************************************************** +// Project Name: TMicroBootInterface component for Borland Delphi +// Description: Encapsulates the MicroBoot DLL interface +// File Name: uBootInterface.pas +// +//--------------------------------------------------------------------------------------- +// C O P Y R I G H T +//--------------------------------------------------------------------------------------- +// Copyright (c) by Feaser LLC All rights reserved. +// +// This software has been carefully tested, but is not guaranteed for any particular +// purpose. The author does not offer any warranties and does not guarantee the accuracy, +// adequacy, or completeness of the software and is not responsible for any errors or +// omissions or the results obtained from use of the software. +// +//--------------------------------------------------------------------------------------- +// A U T H O R I D E N T I T Y +//--------------------------------------------------------------------------------------- +// Initials Name Contact +// -------- --------------------- ---------------------- +// Vg Frank Voorburg voorburg@feaser.com +// +//--------------------------------------------------------------------------------------- +// R E V I S I O N H I S T O R Y +//--------------------------------------------------------------------------------------- +// Date Version Author Description +// --------- ------- ------ -------------------------------------------------------- +// 01-Aug-05 1.00.00 Vg - Creation +//*************************************************************************************** +interface + + +//*************************************************************************************** +// Includes +//*************************************************************************************** +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; + + +//*************************************************************************************** +// Type Definitions +//*************************************************************************************** +// DLL Interface Callbacks - modifications requires potential update of all interfaces! +type + TStartedEvent = procedure(length: Longword) of object; + TProgressEvent = procedure(progress: Longword) of object; + TDoneEvent = procedure of object; + TErrorEvent = procedure(error: ShortString) of object; + TLogEvent = procedure(info: ShortString) of object; + TInfoEvent = procedure(info: ShortString) of object; + +// DLL Interface Methods - modifications requires potential update of all interfaces! +type + TDllMbiInit = procedure(cbStarted: TStartedEvent; cbProgress: TProgressEvent; + cbDone: TDoneEvent; cbError: TErrorEvent; + cbLog: TLogEvent; cbInfo: TInfoEvent); stdcall; + TDllMbiStart = procedure(fileName: ShortString); stdcall; + TDllMbiStop = procedure; stdcall; + TDllMbiDeInit = procedure; stdcall; + TDllMbiName = function : ShortString; stdcall; + TDllMbiDescription = function : ShortString; stdcall; + TDllMbiVersion = function : Longword; stdcall; + TDllMbiConfigure = procedure; stdcall; + TDllMbiVInterface = function : Longword; stdcall; + +// Interface Class +type + TMicroBootInterface = class(TComponent) + private + { Private declarations } + DllMbiInit : TDllMbiInit; + DllMbiStart : TDllMbiStart; + DllMbiStop : TDllMbiStop; + DllMbiDeInit : TDllMbiDeInit; + DllMbiName : TDllMbiName; + DllMbiDescription : TDllMbiDescription; + DllMbiVersion : TDllMbiVersion; + DllMbiConfigure : TDllMbiConfigure; + DllMbiVInterface : TDllMbiVInterface; + protected + { Protected declarations } + FLibraryFile : string; + FLibraryHandle : THandle; + FOnStarted : TStartedEvent; + FOnProgress : TProgressEvent; + FOnDone : TDoneEvent; + FOnError : TErrorEvent; + FOnLog : TLogEvent; + FOnInfo : TInfoEvent; + public + { Public declarations } + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + function Enable(libraryFile: string; evStarted: TStartedEvent; + evProgress: TProgressEvent; evDone: TDoneEvent; + evError: TErrorEvent; evLog: TLogEvent; + evInfo: TInfoEvent) : Boolean; + procedure Disable; + procedure Download(fileName: ShortString); + procedure Cancel; + function Name : ShortString; + function Description : ShortString; + function Version : Longword; + procedure Configure; + function VInterface : Longword; + published + { Published declarations } + end; + + +implementation +//*************************************************************************************** +// NAME: Create +// PARAMETER: AOwner : owner of the component +// RETURN VALUE: none +// DESCRIPTION: Component constructor. Calls TComponent's constructor and initializes +// the private property variables to their default values. +// +//*************************************************************************************** +constructor TMicroBootInterface.Create(AOwner: TComponent); +begin + // call inherited constructor + inherited Create( AOwner ); + + // initialize the callback pointers + FOnStarted := nil; + FOnProgress := nil; + FOnDone := nil; + FOnError := nil; + FOnLog := nil; + FOnInfo := nil; + + // initialize the properties + FLibraryFile := ''; + FLibraryHandle := 0; +end; //*** end of Create *** + + +//*************************************************************************************** +// NAME: Destroy +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Component destructor. Calls TComponent's destructor +// +//*************************************************************************************** +destructor TMicroBootInterface.Destroy; +begin + if FLibraryHandle = 0 then //##Vg shouldn't this be <> 0? + begin + FreeLibrary(FLibraryHandle); // release the handle + end; + + inherited Destroy; // call inherited destructor +end; //*** end of Destroy *** + + +//*************************************************************************************** +// NAME: Enable +// PARAMETER: name of library file and pointers to the callback functions. +// RETURN VALUE: true: interface library ready, false: error occurred. +// DESCRIPTION: Used to connect the interface library to the application. +// +//*************************************************************************************** +function TMicroBootInterface.Enable(libraryFile: string; evStarted: TStartedEvent; + evProgress: TProgressEvent; evDone: TDoneEvent; + evError: TErrorEvent; evLog: TLogEvent; + evInfo :TInfoEvent) : Boolean; +var + Initialized : Boolean; +begin + Initialized := True; + + // first make sure the interface is disabled + Disable; + + // set the library file + if (FileExists(libraryFile)) and (LowerCase(ExtractFileExt(libraryFile)) = '.dll') then + begin + FLibraryFile := libraryFile; + end; + + // set the callback functions + if Assigned(evStarted) then FOnStarted := evStarted; + if Assigned(evProgress) then FOnProgress := evProgress; + if Assigned(evDone) then FOnDone := evDone; + if Assigned(evError) then FOnError := evError; + if Assigned(evLog) then FOnLog := evLog; + if Assigned(evInfo) then FOnInfo := evInfo; + + // check if callback functions are configured properly + if not Assigned(FOnStarted) then Initialized := False; + if not Assigned(FOnProgress) then Initialized := False; + if not Assigned(FOnDone) then Initialized := False; + if not Assigned(FOnError) then Initialized := False; + if not Assigned(FOnLog) then Initialized := False; + if not Assigned(FOnInfo) then Initialized := False; + + // check if a proper library file is configured + if FLibraryFile = '' then Initialized := False; + + // only continue if everything was okay sofar + if Initialized = True then + begin + // attempt to obtain a handle to the interface library + FLibraryHandle := LoadLibrary(PChar(FLibraryFile)); + if FLibraryHandle = 0 then Initialized := False; + end; + + // only continue if everything was okay sofar + if Initialized = True then + begin + // attempt to obtain the function pointers from the interface library + @DllMbiInit := GetProcAddress(FLibraryHandle, 'MbiInit'); + @DllMbiStart := GetProcAddress(FLibraryHandle, 'MbiStart'); + @DllMbiStop := GetProcAddress(FLibraryHandle, 'MbiStop'); + @DllMbiDeInit := GetProcAddress(FLibraryHandle, 'MbiDeInit'); + @DllMbiName := GetProcAddress(FLibraryHandle, 'MbiName'); + @DllMbiDescription := GetProcAddress(FLibraryHandle, 'MbiDescription'); + @DllMbiVersion := GetProcAddress(FLibraryHandle, 'MbiVersion'); + @DllMbiConfigure := GetProcAddress(FLibraryHandle, 'MbiConfigure'); + @DllMbiVInterface := GetProcAddress(FLibraryHandle, 'MbiVInterface'); + end; + + // check if the functions were found in the interface library + if not Assigned(DllMbiInit) then Initialized := False; + if not Assigned(DllMbiStart) then Initialized := False; + if not Assigned(DllMbiStop) then Initialized := False; + if not Assigned(DllMbiDeInit) then Initialized := False; + if not Assigned(DllMbiName) then Initialized := False; + if not Assigned(DllMbiDescription) then Initialized := False; + if not Assigned(DllMbiVersion) then Initialized := False; + if not Assigned(DllMbiConfigure) then Initialized := False; + if not Assigned(DllMbiVInterface) then Initialized := False; + + // only continue if everything was okay sofar + if Initialized = True then + begin + // pass callback function pointers on to the interface library + DllMbiInit(FOnStarted, FOnProgress, FOnDone, FOnError, FOnLog, FOnInfo); + end + else + begin + // error occured so make sure to reset the handle to the interface library + FLibraryHandle := 0; + end; + + Result := Initialized; +end; //*** end of Enable *** + + +//*************************************************************************************** +// NAME: Download +// PARAMETER: filename with full path +// RETURN VALUE: none +// DESCRIPTION: Requests the interface library to start the download of a file. +// +//*************************************************************************************** +procedure TMicroBootInterface.Download(fileName: ShortString); +begin + // only continue with we have a valid interface library handle + if FLibraryHandle <> 0 then + begin + // pass control for file download to the library + DllMbiStart(fileName); + end; +end; //*** end of Download *** + + +//*************************************************************************************** +// NAME: Cancel +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Cancels a possible active file download. +// +//*************************************************************************************** +procedure TMicroBootInterface.Cancel; +begin + // only continue with we have a valid interface library handle + if FLibraryHandle <> 0 then + begin + DllMbiStop; // let interface library handle the stop request + end; +end; //*** end of Cancel *** + + +//*************************************************************************************** +// NAME: Disable +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Disables the interface library. +// +//*************************************************************************************** +procedure TMicroBootInterface.Disable; +begin + // only continue with we have a valid interface library handle + if FLibraryHandle <> 0 then + begin + DllMbiDeInit; // inform the dll aswell that we're disabling + FreeLibrary(FLibraryHandle); // release the handle + end; + + // initialize the callback pointers + FOnStarted := nil; + FOnProgress := nil; + FOnDone := nil; + FOnError := nil; + FOnLog := nil; + FOnInfo := nil; + + // initialize the properties + FLibraryFile := ''; + FLibraryHandle := 0; +end; //*** end of Disable *** + + +//*************************************************************************************** +// NAME: Name +// PARAMETER: none +// RETURN VALUE: Name of the interface library +// DESCRIPTION: Obtains the name of the interface library. +// +//*************************************************************************************** +function TMicroBootInterface.Name : ShortString; +begin + // only continue with we have a valid interface library handle + if FLibraryHandle <> 0 then + begin + Result := DllMbiName; // obtain the request info from the interface + end + else + begin + Result := ''; + end; +end; //*** end of Name *** + + +//*************************************************************************************** +// NAME: Description +// PARAMETER: none +// RETURN VALUE: Description of the interface library +// DESCRIPTION: Obtains the description of the interface library. +// +//*************************************************************************************** +function TMicroBootInterface.Description : ShortString; +begin + // only continue with we have a valid interface library handle + if FLibraryHandle <> 0 then + begin + Result := DllMbiDescription; // obtain the request info from the interface + end + else + begin + Result := ''; + end; +end; //*** end of Description *** + + +//*************************************************************************************** +// NAME: Version +// PARAMETER: none +// RETURN VALUE: version of the library interface +// DESCRIPTION: Obtains the version of the interface library. +// +//*************************************************************************************** +function TMicroBootInterface.Version : Longword; +begin + // only continue with we have a valid interface library handle + if FLibraryHandle <> 0 then + begin + Result := DllMbiVersion; // obtain the request info from the interface + end + else + begin + Result := 0; + end; +end; //*** end of Version *** + + +//*************************************************************************************** +// NAME: VInterface +// PARAMETER: none +// RETURN VALUE: Version of uBootInterface.pas +// DESCRIPTION: Obtains the version of the uBootInterface that is supported by the +// interface library. +// +//*************************************************************************************** +function TMicroBootInterface.VInterface : Longword; +begin + // only continue with we have a valid interface library handle + if FLibraryHandle <> 0 then + begin + Result := DllMbiVInterface; // obtain the request info from the interface + end + else + begin + Result := 0; + end; +end; //*** end of Version *** + + +//*************************************************************************************** +// NAME: Configure +// PARAMETER: none +// RETURN VALUE: none +// DESCRIPTION: Used to request the configuration of the interface library. +// +//*************************************************************************************** +procedure TMicroBootInterface.Configure; +begin + // only continue with we have a valid interface library handle + if FLibraryHandle <> 0 then + begin + DllMbiConfigure; // let interface handle the configuration request + end; +end; //*** end of Configure *** + + +end. +//******************************* end of uBootInterface.pas ***************************** + + diff --git a/Host/openblt_can_peak.dll b/Host/openblt_can_peak.dll new file mode 100644 index 00000000..11d0e1ac Binary files /dev/null and b/Host/openblt_can_peak.dll differ diff --git a/Host/openblt_can_peak.ini b/Host/openblt_can_peak.ini new file mode 100644 index 00000000..3e08adc7 --- /dev/null +++ b/Host/openblt_can_peak.ini @@ -0,0 +1,14 @@ +[can] +hardware=0 +channel=0 +baudrate=500 +extended=0 +txid=1639 +rxid=2017 +[xcp] +seedkey= +t1=1000 +t3=2000 +t4=10000 +t5=1000 +t7=2000 diff --git a/Host/openblt_can_vector.dll b/Host/openblt_can_vector.dll new file mode 100644 index 00000000..19ec27e2 Binary files /dev/null and b/Host/openblt_can_vector.dll differ diff --git a/Host/openblt_can_vector.ini b/Host/openblt_can_vector.ini new file mode 100644 index 00000000..b19f2962 --- /dev/null +++ b/Host/openblt_can_vector.ini @@ -0,0 +1,14 @@ +[can] +hardware=2 +channel=0 +baudrate=500 +extended=0 +txid=1639 +rxid=2017 +[xcp] +seedkey= +t1=1000 +t3=2000 +t4=10000 +t5=1000 +t7=2000 diff --git a/Host/openblt_uart.dll b/Host/openblt_uart.dll new file mode 100644 index 00000000..66698418 Binary files /dev/null and b/Host/openblt_uart.dll differ diff --git a/Host/openblt_uart.ini b/Host/openblt_uart.ini new file mode 100644 index 00000000..56b278d5 --- /dev/null +++ b/Host/openblt_uart.ini @@ -0,0 +1,10 @@ +[sci] +port=3 +baudrate=8 +[xcp] +seedkey= +t1=1000 +t3=2000 +t4=10000 +t5=1000 +t7=2000 diff --git a/Host/vcand32.dll b/Host/vcand32.dll new file mode 100644 index 00000000..56dcfe98 Binary files /dev/null and b/Host/vcand32.dll differ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/bin/openbtl_olimex_lpc_l2294_20mhz.elf b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/bin/openbtl_olimex_lpc_l2294_20mhz.elf new file mode 100644 index 00000000..3981fbeb Binary files /dev/null and b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/bin/openbtl_olimex_lpc_l2294_20mhz.elf differ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/bin/openbtl_olimex_lpc_l2294_20mhz.hex b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/bin/openbtl_olimex_lpc_l2294_20mhz.hex new file mode 100644 index 00000000..b2a52ca8 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/bin/openbtl_olimex_lpc_l2294_20mhz.hex @@ -0,0 +1,361 @@ +:1000000018F09FE518F09FE518F09FE518F09FE5C0 +:1000100018F09FE50000A0E118F09FE510F09FE5C3 +:100020005000000034150000A0000000341500004E +:1000300034150000E41400000C150000000000005E +:10004000E4009FE50110A0E3001080E5000000EF50 +:10005000D8009FE5DBF021E300D0A0E1040040E2FE +:10006000D7F021E300D0A0E1040040E2D1F021E389 +:1000700000D0A0E1040040E2D2F021E300D0A0E1F2 +:10008000040040E2D3F021E300D0A0E1040040E20C +:10009000DFF021E300D0A0E1150000EB290000EA29 +:1000A00088009FE5DBF021E300D0A0E1040040E2FE +:1000B000D7F021E300D0A0E1040040E2D1F021E339 +:1000C00000D0A0E1040040E2D2F021E300D0A0E1A2 +:1000D000040040E2D3F021E300D0A0E1040040E2BC +:1000E000DFF021E300D0A0E1010000EBB80000EB5D +:1000F000140000EA38109FE538209FE538309FE56E +:10010000030052E10400913404008234FBFFFF3A03 +:100110000000A0E324109FE524209FE5020051E1A8 +:1001200004008134FCFFFF3A1EFF2FE140C01FE0B6 +:10013000DC1E00407C16000000020040000200406F +:1001400000020040F406004010402DE908D04DE2C6 +:10015000FC309FE5003093E504308DE503308DE2FF +:100160000040A0E3EC109FE5EC209FE50100F3E5E3 +:10017000910000E0260A40E2160E40E2020050E143 +:100180000800009A014084E2FF4004E2040054E3C6 +:10019000F5FFFF1AC4009FE57010A0E3C0309FE593 +:1001A0000FE0A0E113FF2FE18422A0E1022082E30F +:1001B000FF2002E2AC309FE58420C3E55510E0E368 +:1001C0008C10C3E55520A0E38C20C3E50100A0E31B +:1001D0008000C3E58C10C3E58C20C3E5B828D3E1CB +:1001E000010B12E3FCFFFF0A78309FE50320A0E338 +:1001F0008020C3E55520E0E38C20C3E5AB2082E2FC +:100200008C20C3E50020A0E30020C3E5042082E2A7 +:100210000420C3E50220A0E30020C3E50120A0E301 +:10022000013C83E20020C3E53C309FE5002093E5DC +:10023000052082E3002083E530309FE50FE0A0E158 +:1002400013FF2FE128409FE50FE0A0E114FF2FE10D +:10025000FCFFFFEA58150000C0D40100A080020096 +:10026000241600007C0A000000C01FE000C002E06D +:1002700078020000C402000008402DE930309FE5FC +:100280000FE0A0E113FF2FE128309FE50FE0A0E190 +:1002900013FF2FE120309FE50FE0A0E113FF2FE1D6 +:1002A00018309FE50FE0A0E113FF2FE10840BDE803 +:1002B0001EFF2FE1740A0000440A0000800D0000B8 +:1002C0000003000008402DE924309FE50FE0A0E185 +:1002D00013FF2FE11C309FE50FE0A0E113FF2FE19A +:1002E00014309FE50FE0A0E113FF2FE10840BDE8C7 +:1002F0001EFF2FE1780A000068030000C809000013 +:1003000004E02DE50CD04DE20030E0E30430CDE513 +:100310000030A0E30530CDE538309FE50FE0A0E1E7 +:1003200013FF2FE130309FE50FE0A0E113FF2FE135 +:1003300028309FE50030D3E5010053E304008D022F +:100340001C309F050FE0A00113FF2F010CD08DE2A0 +:1003500004E09DE41EFF2FE148040000DC0B0000D8 +:10036000000200409C04000008402DE924009FE5A5 +:1003700024309FE50FE0A0E113FF2FE1010050E3DF +:1003800010009F0514309F050FE0A00113FF2F01FF +:100390000840BDE81EFF2FE104020040C40C00002D +:1003A0009C04000008402DE9FF1001E218309FE591 +:1003B0000FE0A0E113FF2FE110309FE50FE0A0E177 +:1003C00013FF2FE10840BDE81EFF2FE11C0C0000C9 +:1003D000880400000120A0E304309FE50020C3E56D +:1003E0001EFF2FE10002004004309FE50000D3E52E +:1003F0001EFF2FE10002004008402DE90C309FE570 +:100400000FE0A0E113FF2FE10840BDE81EFF2FE140 +:10041000700400000020A0E304309FE50120C3E544 +:100420001EFF2FE14402004014309FE50120E0E36D +:100430000320C3E50400C3E50220A0E3B424C3E124 +:100440001EFF2FE1440200401C309FE50020A0E386 +:100450000020C3E5482083E54320C3E5B424C3E17D +:100460000220C3E50120C3E51EFF2FE14402004046 +:100470000C309FE50000D3E5000050E20100A0131E +:100480001EFF2FE1440200400020A0E304309FE55E +:100490004320C3E51EFF2FE14402004038402DE910 +:1004A0000040A0E10030D0E5FF0053E31200001A45 +:1004B000D7FFFFEBEC349FE50120A0E30020C3E56C +:1004C0000010E0E30310C3E51010A0E30410C3E53F +:1004D0000010A0E30510C3E54000A0E30600C3E55B +:1004E0000700C3E50810C3E50920C3E50A20C3E5FA +:1004F0000820A0E3B424C3E11B0100EAA4249FE583 +:100500000020D2E5010052E32401001AC93043E281 +:10051000350053E303F19F97110100EAC80700007B +:100520006409000064090000580900006409000023 +:1005300064090000340900001C080000F0080000F5 +:10054000B8080000640900006409000064090000A4 +:1005500064090000640900006409000064090000E7 +:1005600064090000640900006409000064090000D7 +:1005700064090000640900006409000064090000C7 +:1005800064090000640900006409000064090000B7 +:1005900064090000640900006409000064090000A7 +:1005A0006409000064090000640900006409000097 +:1005B0006409000064090000640900006409000087 +:1005C00064090000CC0600004C060000F4050000A1 +:1005D000AC06000064090000640900006409000022 +:1005E0002C07000064090000640700007007000089 +:1005F000A40700000120D0E53F0052E30200009A6A +:100600002200A0E387FFFFEBD70000EA94539FE5A9 +:10061000040085E2481095E58C339FE50FE0A0E1EA +:1006200013FF2FE10030E0E30330C5E50120D4E5FE +:10063000483095E5033082E0483085E50130D4E567 +:10064000013083E2B434C5E1C70000EA0130D0E5EF +:100650003F0053E30200009A2200A0E371FFFFEB8A +:10066000C10000EA041090E538539FE5481085E585 +:10067000040085E20120D4E52C339FE50FE0A0E1E2 +:1006800013FF2FE10030E0E30330C5E50120D4E59E +:10069000483095E5033082E0483085E50130D4E507 +:1006A000013083E2B434C5E1AF0000EAF4329FE5E3 +:1006B0000020E0E30320C3E5042090E5482083E523 +:1006C0000120A0E3B424C3E1A70000EAD4C29FE55F +:1006D0000030E0E30330CCE548109CE5043090E5C1 +:1006E000000053E30020A0030500000A0020A0E35F +:1006F0000100D1E4002082E0FF2002E2013053E259 +:10070000FAFFFF1A07208CE598329FE50120A0E34D +:100710000420C3E50020A0E30520C3E50620C3E5CF +:100720000820A0E3B424C3E18F0000EA74329FE5FF +:100730000020E0E30320C3E570229FE5482083E525 +:100740000020A0E30420C3E50520C3E50620C3E59F +:100750000720A0E3072083E50820A0E3B424C3E139 +:10076000810000EA0000A0E32EFFFFEB7E0000EA1C +:1007700030329FE50020E0E30320C3E50020A0E342 +:100780000420C3E50110D3E50510C3E50620C3E549 +:100790000720C3E50820C3E50620A0E3B424C3E195 +:1007A000710000EAFC419FE50030A0E30030C4E5A1 +:1007B00017FFFFEB0030E0E30330C4E50130A0E3B6 +:1007C000B434C4E1680000EAD8319FE5480093E5FD +:1007D0003F10A0E3012084E2D4319FE50FE0A0E1C7 +:1007E00013FF2FE1000050E30200001A3100A0E3E4 +:1007F0000CFFFFEB5C0000EAA8319FE50020E0E37E +:100800000320C3E5482093E53F2082E2482083E5AA +:100810000120A0E3B424C3E1530000EA0130D0E595 +:100820003E0053E30200009A2200A0E3FDFEFFEB2E +:100830004D0000EA6C319FE50020E0E30320C3E5B2 +:100840000120A0E3B424C3E10110D0E5000051E38E +:100850000700001A5C319FE50FE0A0E113FF2FE1D4 +:10086000000050E34000001A3100A0E3EDFEFFEB72 +:100870003D0000EA2C319FE5480093E5022084E228 +:100880002C319FE50FE0A0E113FF2FE1000050E3C2 +:100890000200001A3100A0E3E2FEFFEB320000EAA2 +:1008A00000319FE50110D4E5482093E5022081E066 +:1008B000482083E52C0000EAE8309FE50020E0E3D3 +:1008C0000320C3E50020A0E30420C3E50520C3E521 +:1008D0004010A0E30610C3E50720C3E50820C3E5E8 +:1008E0000920C3E50720A0E3B424C3E11E0000EA09 +:1008F000B0309FE5480093E5041094E5B8309FE5DB +:100900000FE0A0E113FF2FE1000050E30200001A06 +:100910003100A0E3C3FEFFEB130000EA84309FE543 +:100920000020E0E30320C3E50120A0E3B424C3E1F9 +:100930000D0000EA84309FE50FE0A0E113FF2FE1F6 +:1009400060309FE50020E0E30320C3E50120A0E341 +:10095000B424C3E1040000EA3100A0E3B1FEFFEBE0 +:10096000010000EA2000A0E3AEFEFFEB34309FE57B +:100970004330D3E5010053E31000A003A9FEFF0BB1 +:1009800020309FE50120A0E34320C3E5030083E27C +:10099000B414D3E128309FE50FE0A0E113FF2FE16D +:1009A0003840BDE81EFF2FE144020040A40A0000C9 +:1009B0005C1500009C0D0000F00D0000B80D00005B +:1009C000380B0000A403000008402DE95C309FE5CF +:1009D0000FE0A0E113FF2FE1010050E31100000A36 +:1009E0004C309FE50030D3E5010053E30D00001AC1 +:1009F00040309FE50FE0A0E113FF2FE1310050E30D +:100A00000800009A0020A0E324309FE50020C3E501 +:100A100024309FE50FE0A0E113FF2FE11C309FE59C +:100A20000FE0A0E113FF2FE10840BDE81EFF2FE11A +:100A3000F803000090020040C80E0000240E0000E1 +:100A4000E80A000008402DE90120A0E318309FE5E6 +:100A50000020C3E514309FE50FE0A0E113FF2FE174 +:100A6000D8FFFFEB0840BDE81EFF2FE190020040D9 +:100A7000800E00001EFF2FE11EFF2FE110402DE928 +:100A800014309FE5000083E5041083E50C409FE5EA +:100A90000FE0A0E114FF2FE1FCFFFFEA9402004009 +:100AA000780A0000F8402DE90140A0E1005052E230 +:100AB0000900000A0060A0E124709FE50130D4E441 +:100AC0000130C6E40FE0A0E117FF2FE1015045E23D +:100AD0000558A0E12558B0E1F7FFFF1AF840BDE83E +:100AE0001EFF2FE1780A000008402DE93C309FE509 +:100AF0000FE0A0E113FF2FE1000050E30900000A1E +:100B00000101A0E3021AA0E34020A0E3E4FFFFEB11 +:100B10000220A0E318309FE5402083E50131A0E3E7 +:100B20000FE0A0E113FF2FE10840BDE81EFF2FE119 +:100B3000D40D000000C01FE008402DE90C309FE5F7 +:100B40000FE0A0E113FF2FE10840BDE81EFF2FE1F9 +:100B5000500000001C309FE51430D3E5010013E382 +:100B600010309F150030D3150030C0150100A013C0 +:100B70000000A0031EFF2FE100C000E038402DE977 +:100B80004C309FE51430D3E5200013E30000A003B0 +:100B90000D00000A38309FE50000C3E51430D3E5AE +:100BA000200013E30100A0130700001A24509FE562 +:100BB0001C409FE50FE0A0E115FF2FE11430D4E5C4 +:100BC000200013E3FAFFFF0A0100A0E33840BDE86C +:100BD0001EFF2FE100C000E0780A000034309FE5DE +:100BE0000020A0E30420C3E50820C3E51420C3E5EA +:100BF0007F10E0E30C10C3E54110A0E30010C3E553 +:100C00000420C3E50320A0E30C20C3E50720A0E3F4 +:100C10000820C3E51EFF2FE100C000E0F8452DE9E4 +:100C20000050A0E10140A0E1400051E384009F8515 +:100C30008310A08380309F850FE0A08113FF2F8158 +:100C40000400A0E1CCFFFFEB010050E364009F151E +:100C50008610A01360309F150FE0A01113FF2F1115 +:100C60000460A0E1000054E31000000A0040A0E38B +:100C700048709FE53C809FE53CA09FE50FE0A0E128 +:100C800017FF2FE10400D5E7BBFFFFEB010050E3A6 +:100C90000800A0118E10A0130FE0A0111AFF2F1151 +:100CA000014084E20438A0E1230856E1F2FFFF8A04 +:100CB000F845BDE81EFF2FE12C1600007C0A00005D +:100CC000780A000070402DE90050A0E1A0309FE5B7 +:100CD0000030D3E5000053E30A00001A94009FE5BA +:100CE0009BFFFFEB010050E30000A0131E00001A61 +:100CF0007C309FE50120A0E30020C3E50000A0E3D5 +:100D00004500C3E5180000EA64009FE54540D0E5D2 +:100D1000040080E0050080E28DFFFFEB010050E35E +:100D20000000A0131000001A014084E2FF2004E23A +:100D30003C309FE54520C3E50430D3E5020053E194 +:100D40000000A0130800001A24609FE50500A0E140 +:100D5000051086E220309FE50FE0A0E113FF2FE1B0 +:100D60000030A0E30030C6E50100A0E37040BDE81C +:100D70001EFF2FE19C020040A0020040A40A0000D8 +:100D800008402DE90C309FE50FE0A0E113FF2FE1B3 +:100D90000840BDE81EFF2FE11C12000008402DE9AD +:100DA0000C309FE50FE0A0E113FF2FE10840BDE804 +:100DB0001EFF2FE13412000008402DE90C309FE5A2 +:100DC0000FE0A0E113FF2FE10840BDE81EFF2FE177 +:100DD000A012000008402DE90C309FE50FE0A0E1D3 +:100DE00013FF2FE10840BDE81EFF2FE14014000073 +:100DF00008402DE920309FE50FE0A0E113FF2FE12F +:100E0000000050E30000A00310309F150FE0A01178 +:100E100013FF2F110840BDE81EFF2FE1D41300007F +:100E20008814000014309FE50020A0E3042083E52F +:100E30000C2083E5082083E5102083E51EFF2FE1C9 +:100E4000004000E01C309FE5082093E518309FE546 +:100E5000001093E5011082E0040093E5011060E0CA +:100E6000060083E81EFF2FE1004000E0E40200409E +:100E700004309FE5000083E51EFF2FE1E4020040FF +:100E800008402DE930309FE50000A0E3140083E521 +:100E9000280083E524209FE50C2083E50120A0E3C2 +:100EA000042083E5082093E514309FE5042083E5C2 +:100EB000EEFFFFEB0840BDE81EFF2FE1004000E021 +:100EC0005FEA0000E402004008402DE9DCFFFFEB90 +:100ED00008309FE5000093E50840BDE81EFF2FE1C4 +:100EE000E4020040F0412DE90060A0E10040A0E3F1 +:100EF0000450A0E158809FE558709FE50FE0A0E105 +:100F000018FF2FE1043097E7060053E10900008A3B +:100F1000041087E0041091E5013083E0030056E1FE +:100F20000400002A852085E028309FE5023183E017 +:100F30000800D3E5040000EA015085E20C4084E299 +:100F4000C00054E3ECFFFF1AFF00A0E3F041BDE84E +:100F50001EFF2FE1780A00006415000030402DE9E3 +:100F600024D04DE20040A0E1000090E5DCFFFFEB63 +:100F7000FF0050E30000A0033D00000A3230A0E370 +:100F80000C308DE510008DE514008DE50130A0E3F7 +:100F900000308DE5E4309FE50FE0A0E113FF2FE185 +:100FA0000C008DE20D10A0E13A31E0E30FE0A0E18A +:100FB00013FF2FE100309DE5000053E30000A01374 +:100FC0002B00001A3330A0E30C308DE50450A0E173 +:100FD000043095E410308DE514508DE5023CA0E31B +:100FE00018308DE598309FE51C308DE50130A0E389 +:100FF00000308DE584309FE50FE0A0E113FF2FE185 +:101000000C008DE20D10A0E13A31E0E30FE0A0E129 +:1010100013FF2FE100309DE5000053E30000A01313 +:101020001300001A3830A0E30C308DE5003094E551 +:1010300010308DE514508DE5023CA0E318308DE5AD +:101040000130A0E300308DE530309FE50FE0A0E1F6 +:1010500013FF2FE10C008DE20D10A0E13A31E0E327 +:101060000FE0A0E113FF2FE100009DE5010070E219 +:101070000000A03324D08DE23040BDE81EFF2FE1F8 +:10108000780A000060EA000008402DE9813BB0E1E9 +:101090000000A0130900001A003090E5010053E1A0 +:1010A0000100A0030500000A041080E4022CA0E364 +:1010B00010309FE50FE0A0E113FF2FE10100A0E356 +:1010C0000840BDE81EFF2FE1A40A000038402DE9CA +:1010D0000040A0E10150A0E14C309FE5030050E149 +:1010E0000600000A020A51E30600000A9AFFFFEB1D +:1010F000000050E30040A0030800000A020000EADC +:1011000028409FE5000000EA1C409FE50400A0E1A4 +:101110000510A0E1DBFFFFEB000050E30040A0035F +:101120000400A0E13840BDE81EFF2FE1F0040040BC +:10113000EC020040F0472DE90050A0E10140A0E1A1 +:101140000270A0E10360A0E1A194A0E18994A0E174 +:10115000003090E5010073E30400001A0910A0E1DB +:10116000C8FFFFEB000050E30000A0032600000AC8 +:10117000003095E5090053E10500000A0500A0E1F3 +:101180000910A0E1D0FFFFEB005050E20000A003E7 +:101190001D00000A003095E5044063E0044085E04E +:1011A000044084E268809FE568A09FE5029C89E294 +:1011B0000FE0A0E118FF2FE1043085E2043063E086 +:1011C0000A0053E10500009A0500A0E10910A0E122 +:1011D000BDFFFFEB005050E20800000A044085E22A +:1011E0000130D7E40030C4E5016046E20668A0E1C2 +:1011F0002668B0E10300000A014084E2EBFFFFEA49 +:101200000000A0E3000000EA0100A0E3F047BDE811 +:101210001EFF2FE1780A0000FF0100000C309FE55F +:101220000020E0E3002083E5042283E51EFF2FE198 +:10123000EC02004070402DE90040A0E10150A0E127 +:101240000260A0E126FFFFEBFF0050E30000A003D7 +:101250000E00000A010044E2050080E020FFFFEBE1 +:10126000FF0050E30000A0030800000AA434A0E13E +:10127000100053E30538A0E118009F0518009F15E2 +:101280000410A0E10620A0E12338A0E1A8FFFFEBB5 +:101290007040BDE81EFF2FE1F0040040EC0200406A +:1012A00070402DE920D04DE20050A0E10160A0E1A6 +:1012B0000BFFFFEB0040A0E1010045E2060080E0EB +:1012C00007FFFFEB0050A0E1FF0050E3FF005413C5 +:1012D0000000A0033900000A050054E10000A083CB +:1012E0003600008A000054E30000A0033300000A27 +:1012F000100055E30000A0833000008A3230A0E3E4 +:1013000038008DE80130A0E314308DE5B8309FE55A +:101310000FE0A0E113FF2FE10D00A0E114108DE21A +:101320003A31E0E30FE0A0E113FF2FE114309DE537 +:10133000000053E30000A0132000001A3430A0E3A3 +:1013400038008DE884309FE50C308DE50130A0E356 +:1013500014308DE570309FE50FE0A0E113FF2FE121 +:101360000D00A0E114108DE23A31E0E30FE0A0E1BE +:1013700013FF2FE114309DE5000053E30000A0139C +:101380000E00001A3530A0E338008DE80130A0E3EC +:1013900014308DE530309FE50FE0A0E113FF2FE121 +:1013A0000D00A0E114108DE23A31E0E30FE0A0E17E +:1013B00013FF2FE114009DE5010070E20000A0334F +:1013C00020D08DE27040BDE81EFF2FE1780A0000BA +:1013D00060EA000004E02DE50CD04DE254209FE5CA +:1013E000823F82E2030093E9011080E0082292E547 +:1013F000021081E00C2093E5021081E0102093E5BB +:10140000021081E0182093E5021081E01C2093E592 +:10141000023081E0003063E208208DE2043022E5F2 +:1014200014009FE50410A0E381FFFFEB0CD08DE2D8 +:1014300004E09DE41EFF2FE1EC02004014200000B8 +:10144000023AA0E3050093E8000082E0082093E55B +:10145000020080E00C2093E5020080E0102093E57C +:10146000020080E0142093E5020080E0182093E55C +:10147000020080E01C3093E5030080E0010070E290 +:101480000000A0331EFF2FE108402DE948309FE502 +:10149000043293E5010073E30400000A3C009FE579 +:1014A000ADFEFFEB000050E30000A0030800000ABF +:1014B00024309FE5003093E5010073E30100A003B1 +:1014C0000300000A10009FE5A3FEFFEB000050E2BE +:1014D0000100A0130840BDE81EFF2FE1EC02004010 +:1014E000F004004004E04EE21F402DE910009FE5AB +:1014F0003810A0E30C309FE50FE0A0E113FF2FE1CF +:101500001F80FDE8501600007C0A000004E04EE257 +:101510000F502DE910009FE54610A0E30C309FE529 +:101520000FE0A0E113FF2FE10F90FDE8501600003F +:101530007C0A00000F502DE910009FE55410A0E335 +:101540000C309FE50FE0A0E113FF2FE10F90FDE8C5 +:10155000501600007C0A0000010204084F70656EFE +:10156000424C540000200000002000000100000058 +:1015700000400000002000000200000000600000A9 +:101580000020000003000000008000000020000098 +:101590000400000000A00000002000000500000082 +:1015A00000C00000002000000600000000E0000075 +:1015B0000020000007000000000001000000010002 +:1015C0000800000000000200000001000900000007 +:1015D00000000300002000000A00000000200300BB +:1015E000002000000B00000000400300002000006D +:1015F0000C00000000600300002000000D0000004F +:1016000000800300002000000E00000000A0030086 +:10161000002000000F00000000C0030000200000B8 +:10162000100000006D61696E2E6300002E2E2F2EBB +:101630002E2F2E2E2F536F757263652F41524D370B +:101640005F4C5043323030302F756172742E63001E +:101650002E2E2F2E2E2F2E2E2F536F757263652F49 +:1016600041524D375F4C5043323030302F47434367 +:0C1670002F766563746F72732E630000A8 +:00000001FF diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/bin/openbtl_olimex_lpc_l2294_20mhz.map b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/bin/openbtl_olimex_lpc_l2294_20mhz.map new file mode 100644 index 00000000..49cf82a0 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/bin/openbtl_olimex_lpc_l2294_20mhz.map @@ -0,0 +1,176 @@ + +bin/openbtl_olimex_lpc_l2294_20mhz.elf: file format elf32-littlearm +bin/openbtl_olimex_lpc_l2294_20mhz.elf +architecture: arm, flags 0x00000112: +EXEC_P, HAS_SYMS, D_PAGED +start address 0x00000000 + +Program Header: + LOAD off 0x00008000 vaddr 0x00000000 paddr 0x00000000 align 2**15 + filesz 0x0000167c memsz 0x0000167c flags r-x + LOAD off 0x00010200 vaddr 0x40000200 paddr 0x0000167c align 2**15 + filesz 0x00000000 memsz 0x000004f4 flags rw- +private flags = 5000000: [Version5 EABI] + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .text 0000167c 00000000 00000000 00008000 2**2 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 1 .bss 000004f4 40000200 0000167c 00010200 2**2 + ALLOC + 2 .ARM.attributes 00000030 00000000 00000000 0000967c 2**0 + CONTENTS, READONLY + 3 .comment 0000002a 00000000 00000000 000096ac 2**0 + CONTENTS, READONLY + 4 .debug_abbrev 00000a61 00000000 00000000 000096d6 2**0 + CONTENTS, READONLY, DEBUGGING + 5 .debug_info 0000173b 00000000 00000000 0000a137 2**0 + CONTENTS, READONLY, DEBUGGING + 6 .debug_line 00000873 00000000 00000000 0000b872 2**0 + CONTENTS, READONLY, DEBUGGING + 7 .debug_pubtypes 00000312 00000000 00000000 0000c0e5 2**0 + CONTENTS, READONLY, DEBUGGING + 8 .debug_str 000008fa 00000000 00000000 0000c3f7 2**0 + CONTENTS, READONLY, DEBUGGING + 9 .debug_loc 00000be6 00000000 00000000 0000ccf1 2**0 + CONTENTS, READONLY, DEBUGGING + 10 .debug_pubnames 000003af 00000000 00000000 0000d8d7 2**0 + CONTENTS, READONLY, DEBUGGING + 11 .debug_aranges 000001a0 00000000 00000000 0000dc86 2**0 + CONTENTS, READONLY, DEBUGGING + 12 .debug_frame 0000063c 00000000 00000000 0000de28 2**2 + CONTENTS, READONLY, DEBUGGING +SYMBOL TABLE: +00000000 l d .text 00000000 .text +40000200 l d .bss 00000000 .bss +00000000 l d .ARM.attributes 00000000 .ARM.attributes +00000000 l d .comment 00000000 .comment +00000000 l d .debug_abbrev 00000000 .debug_abbrev +00000000 l d .debug_info 00000000 .debug_info +00000000 l d .debug_line 00000000 .debug_line +00000000 l d .debug_pubtypes 00000000 .debug_pubtypes +00000000 l d .debug_str 00000000 .debug_str +00000000 l d .debug_loc 00000000 .debug_loc +00000000 l d .debug_pubnames 00000000 .debug_pubnames +00000000 l d .debug_aranges 00000000 .debug_aranges +00000000 l d .debug_frame 00000000 .debug_frame +00000004 l *ABS* 00000000 UND_STACK_SIZE +00000004 l *ABS* 00000000 ABT_STACK_SIZE +00000004 l *ABS* 00000000 FIQ_STACK_SIZE +00000004 l *ABS* 00000000 IRQ_STACK_SIZE +00000004 l *ABS* 00000000 SVC_STACK_SIZE +00000010 l *ABS* 00000000 MODE_USR +00000011 l *ABS* 00000000 MODE_FIQ +00000012 l *ABS* 00000000 MODE_IRQ +00000013 l *ABS* 00000000 MODE_SVC +00000017 l *ABS* 00000000 MODE_ABT +0000001b l *ABS* 00000000 MODE_UND +0000001f l *ABS* 00000000 MODE_SYS +00000080 l *ABS* 00000000 I_BIT +00000040 l *ABS* 00000000 F_BIT +e01fc040 l *ABS* 00000000 MEMMAP +00000000 l .text 00000000 _vectors +00000020 l .text 00000000 Reset_Addr +00000024 l .text 00000000 Undef_Addr +00000028 l .text 00000000 SWI_Addr +0000002c l .text 00000000 PAbt_Addr +00000030 l .text 00000000 DAbt_Addr +00000038 l .text 00000000 IRQ_Addr +00000034 l .text 00000000 FIQ_Addr +000000a0 l .text 00000000 Reset_Handler_SWI +00000000 l df *ABS* 00000000 hooks.c +00000000 l df *ABS* 00000000 main.c +00001558 l O .text 00000004 C.0.2157 +00000000 l df *ABS* 00000000 boot.c +00000000 l df *ABS* 00000000 com.c +40000200 l O .bss 00000001 comEntryStateConnect +40000204 l O .bss 00000040 xcpCtoReqPacket.1371 +00000000 l df *ABS* 00000000 xcp.c +00000414 l F .text 00000014 XcpProtectResources +00000428 l F .text 00000020 XcpSetCtoError +0000155c l O .text 00000008 xcpStationId +40000244 l O .bss 0000004c xcpInfo +00000000 l df *ABS* 00000000 backdoor.c +40000290 l O .bss 00000001 backdoorOpen +00000000 l df *ABS* 00000000 cop.c +00000000 l df *ABS* 00000000 assert.c +40000294 l O .bss 00000004 assert_failure_file +40000298 l O .bss 00000004 assert_failure_line +00000000 l df *ABS* 00000000 cpu.c +00000000 l df *ABS* 00000000 can.c +00000000 l df *ABS* 00000000 uart.c +00000b54 l F .text 00000028 UartReceiveByte +00000b7c l F .text 00000060 UartTransmitByte +4000029c l O .bss 00000001 xcpCtoRxInProgress.1383 +400002a0 l O .bss 00000041 xcpCtoReqPacket.1381 +400002e1 l O .bss 00000001 xcpCtoRxLength.1382 +00000000 l df *ABS* 00000000 nvm.c +00000000 l df *ABS* 00000000 timer.c +400002e4 l O .bss 00000004 millisecond_counter +400002e8 l O .bss 00000004 free_running_counter_last +00000000 l df *ABS* 00000000 flash.c +00000ee4 l F .text 00000078 FlashGetSector +00000f5c l F .text 0000012c FlashWriteBlock +00001088 l F .text 00000044 FlashInitBlock +000010cc l F .text 00000068 FlashSwitchBlock +00001134 l F .text 000000e8 FlashAddToBlock +00001564 l O .text 000000c0 flashLayout +400002ec l O .bss 00000204 blockInfo +400004f0 l O .bss 00000204 bootBlockInfo +00000000 l df *ABS* 00000000 vectors.c +00000300 g F .text 00000068 ComInit +00001234 g F .text 0000006c FlashWrite +00000a7c g F .text 00000028 AssertFailure +0000150c g F .text 00000028 IRQ_ISR +00000e44 g F .text 0000002c TimerUpdate +00000488 g F .text 00000014 XcpPacketTransmitted +00000368 g F .text 0000003c ComTask +000003d4 g F .text 00000014 ComSetConnectEntryState +00000278 g F .text 0000004c BootInit +00000a44 g F .text 00000030 BackDoorInit +00000a78 g F .text 00000004 CopService +0000167c g .text 00000000 _etext +00000e24 g F .text 00000020 TimerReset +000002c4 g F .text 0000003c BootTask +000013d4 g F .text 0000006c FlashWriteChecksum +40000200 g .bss 00000000 _bss_start +000003a4 g F .text 00000030 ComTransmitPacket +00000000 g .text 00000000 _startup +00000470 g F .text 00000018 XcpIsConnected +00000d80 g F .text 0000001c NvmInit +0000121c g F .text 00000018 FlashInit +400006f4 g *ABS* 00000000 _bss_end +00000050 g .text 00000000 Reset_Handler +00000bdc g F .text 00000040 UartInit +00000db8 g F .text 0000001c NvmErase +0000049c g F .text 0000052c XcpPacketReceived +00001488 g F .text 0000005c FlashDone +00000040 g .text 00000000 EntryFromProg +000003e8 g F .text 00000010 ComIsConnectEntryState +00000448 g F .text 00000028 XcpInit +000012a0 g F .text 00000134 FlashErase +00000148 g F .text 00000130 main +00000df0 g F .text 00000034 NvmDone +00000c1c g F .text 000000a8 UartTransmitPacket +00000dd4 g F .text 0000001c NvmVerifyChecksum +00000aa4 g F .text 00000044 CpuMemCopy +40001edc g *ABS* 00000000 _stack_end +00000e70 g F .text 00000010 TimerSet +000014e4 g F .text 00000028 FIQ_ISR +00000cc4 g F .text 000000bc UartReceivePacket +40000200 g .text 00000000 _data +00000a74 g F .text 00000004 CopInit +00000b38 g F .text 0000001c CpuReset +000000f4 g .text 00000000 SetupRAM +00000d9c g F .text 0000001c NvmWrite +00000ae8 g F .text 00000050 CpuStartUserProgram +00001440 g F .text 00000048 FlashVerifyChecksum +40000200 g .text 00000000 _edata +400006f4 g *ABS* 00000000 _end +00001534 g F .text 00000024 UNDEF_ISR +000003f8 g F .text 0000001c ComIsConnected +000009c8 g F .text 0000007c BackDoorCheck +00000ec8 g F .text 0000001c TimerGet +00000e80 g F .text 00000048 TimerInit + + diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/build.bat b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/build.bat new file mode 100644 index 00000000..44c0c1b8 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/build.bat @@ -0,0 +1,2 @@ +@echo off +make --directory=../ all diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/clean.bat b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/clean.bat new file mode 100644 index 00000000..32c4b5f2 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/clean.bat @@ -0,0 +1,2 @@ +@echo off +make --directory=../ clean diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/debug.bat b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/debug.bat new file mode 100644 index 00000000..12fe88aa --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/debug.bat @@ -0,0 +1,5 @@ +@echo off +REM Establishes a JTAG connection with the CPU so that a GDB or Insight +REM debugging session can be started. Settings are for Remote/TCP +REM with hostname localhost on port 3333. +"C:\Program Files (x86)\OpenOCD\0.4.0\bin\openocd.exe" -f debug.cfg \ No newline at end of file diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/debug.cfg b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/debug.cfg new file mode 100644 index 00000000..bb1c2f58 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/debug.cfg @@ -0,0 +1,67 @@ +set CPUTAPID 0x4f1f0f0f + +source [find interface/olimex-arm-usb-tiny-h.cfg] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME lpc2294 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +if { [info exists CPUTAPID ] } { + set _CPUTAPID $CPUTAPID +} else { + # force an error till we get a good number + set _CPUTAPID 0xffffffff +} + +jtag_nsrst_delay 200 +jtag_ntrst_delay 200 + +#use combined on interfaces or targets that can't set TRST/SRST separately +reset_config trst_and_srst srst_pulls_trst + +#jtag scan chain +jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME -variant arm7tdmi-s_r4 +$_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup 0 + +#flash configuration +#flash bank lpc2000 0 0 +set _FLASHNAME $_CHIPNAME.flash +flash bank $_FLASHNAME lpc2000 0x0 0x40000 0 0 $_TARGETNAME lpc2000_v1 20000 calc_checksum + +jtag_khz 0 + +flash bank none cfi 0x80000000 0x200000 2 2 $_TARGETNAME + +init +arm7_9 dcc_downloads enable +arm7_9 fast_memory_access enable +reset +sleep 500 +halt +soft_reset_halt +gdb_breakpoint_override hard +#PLL according to Ecos +mww 0xE01FC080 0x1 +mww 0xE01FC084 0x22 +mww 0xE01FC08C 0xAA +mww 0xE01FC08C 0x55 +sleep 200 +mww 0xE01FC080 0x3 +mww 0xE01FC08C 0xAA +mww 0xE01FC08C 0x55 +mww 0xE01FC004 0x4 +mww 0xE01FC000 0x2 + +#MEMMAP +mww 0xE01FC040 0x0001 diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/flash.bat b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/flash.bat new file mode 100644 index 00000000..9fae8956 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/flash.bat @@ -0,0 +1,3 @@ +@echo off +REM Loads the program into flash eeprom through the JTAG interface +"C:\Program Files (x86)\OpenOCD\0.4.0\bin\openocd.exe" -f flash.cfg \ No newline at end of file diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/flash.cfg b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/flash.cfg new file mode 100644 index 00000000..157b9de3 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/cmd/flash.cfg @@ -0,0 +1,79 @@ +set CPUTAPID 0x4f1f0f0f + +source [find interface/olimex-arm-usb-tiny-h.cfg] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME lpc2294 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +if { [info exists CPUTAPID ] } { + set _CPUTAPID $CPUTAPID +} else { + # force an error till we get a good number + set _CPUTAPID 0xffffffff +} + +jtag_nsrst_delay 200 +jtag_ntrst_delay 200 + +#use combined on interfaces or targets that can't set TRST/SRST separately +reset_config trst_and_srst srst_pulls_trst + +#jtag scan chain +jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME -variant arm7tdmi-s_r4 +$_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup 0 + +#flash configuration +#flash bank lpc2000 0 0 +set _FLASHNAME $_CHIPNAME.flash +flash bank $_FLASHNAME lpc2000 0x0 0x40000 0 0 $_TARGETNAME lpc2000_v1 20000 calc_checksum + +jtag_khz 0 + +flash bank none cfi 0x80000000 0x200000 2 2 $_TARGETNAME + + + +init +arm7_9 dcc_downloads enable +arm7_9 fast_memory_access enable +reset +sleep 500 +halt +soft_reset_halt +#PLL according to Ecos +mww 0xE01FC080 0x1 +mww 0xE01FC084 0x22 +mww 0xE01FC08C 0xAA +mww 0xE01FC08C 0x55 +sleep 200 +mww 0xE01FC080 0x3 +mww 0xE01FC08C 0xAA +mww 0xE01FC08C 0x55 +sleep 200 +mww 0xE01FC004 0x4 +mww 0xE01FC000 0x2 +sleep 200 + +#MEMMAP +mww 0xE01FC040 0x0001 + +reset run +sleep 500 +halt +flash probe 0 +sleep 1000 +flash write_image erase unlock ../bin/openbtl_olimex_lpc_l2294_20mhz.elf +reset run +shutdown diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/config.h b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/config.h new file mode 100644 index 00000000..57d6bc31 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/config.h @@ -0,0 +1,128 @@ +/**************************************************************************************** +| Description: bootloader configuration header file +| File Name: config.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef CONFIG_H +#define CONFIG_H + +/**************************************************************************************** +* C P U D R I V E R C O N F I G U R A T I O N +****************************************************************************************/ +/* To properly initialize the baudrate clocks of the communication interface, typically + * the speed of the crystal oscillator and/or the speed at which the system runs is + * needed. Set these through configurables BOOT_CPU_XTAL_SPEED_KHZ and + * BOOT_CPU_SYSTEM_SPEED_KHZ, respectively. To enable data exchange with the host that is + * not dependent on the targets architecture, the byte ordering needs to be known. + * Setting BOOT_CPU_BYTE_ORDER_MOTOROLA to 1 selects little endian mode and 0 selects + * big endian mode. + */ +#define BOOT_CPU_XTAL_SPEED_KHZ (20000) +#define BOOT_CPU_SYSTEM_SPEED_KHZ (60000) +#define BOOT_CPU_BYTE_ORDER_MOTOROLA (0) + + +/**************************************************************************************** +* C O M M U N I C A T I O N I N T E R F A C E C O N F I G U R A T I O N +****************************************************************************************/ +/* The CAN communication interface is selected by setting the BOOT_COM_CAN_ENABLE + * configurable to 1. Configurable BOOT_COM_CAN_BAUDRATE selects the communication speed + * in bits/second. Two CAN messages are reserved for communication with the host. The + * message identifier for sending data from the target to the host is configured with + * BOOT_COM_CAN_TXMSG_ID. The one for receiving data from the host is configured with + * BOOT_COM_CAN_RXMSG_ID. The maximum amount of data bytes in a message for data + * transmission and reception is set through BOOT_COM_CAN_TX_MAX_DATA and + * BOOT_COM_CAN_RX_MAX_DATA, respectively. It is common for a microcontroller to have more + * than 1 CAN controller on board. The zero-based BOOT_COM_CAN_CHANNEL_INDEX selects the + * CAN controller channel. + * + */ +#define BOOT_COM_CAN_ENABLE (0) +#define BOOT_COM_CAN_BAUDRATE (500000) +#define BOOT_COM_CAN_TX_MSG_ID (0x7E1) +#define BOOT_COM_CAN_TX_MAX_DATA (8) +#define BOOT_COM_CAN_RX_MSG_ID (0x667) +#define BOOT_COM_CAN_RX_MAX_DATA (8) +#define BOOT_COM_CAN_CHANNEL_INDEX (0) + +/* The UART communication interface is selected by setting the BOOT_COM_UART_ENABLE + * configurable to 1. Configurable BOOT_COM_UART_BAUDRATE selects the communication speed + * in bits/second. The maximum amount of data bytes in a message for data transmission + * and reception is set through BOOT_COM_UART_TX_MAX_DATA and BOOT_COM_UART_RX_MAX_DATA, + * respectively. It is common for a microcontroller to have more than 1 UART interface + * on board. The zero-based BOOT_COM_UART_CHANNEL_INDEX selects the UART interface. + * + */ +#define BOOT_COM_UART_ENABLE (1) +#define BOOT_COM_UART_BAUDRATE (57600) +#define BOOT_COM_UART_TX_MAX_DATA (64) +#define BOOT_COM_UART_RX_MAX_DATA (64) +#define BOOT_COM_UART_CHANNEL_INDEX (0) + + +/**************************************************************************************** +* B A C K D O O R E N T R Y C O N F I G U R A T I O N +****************************************************************************************/ +/* It is possible to implement an application specific method to force the bootloader to + * stay active after a reset. Such a backdoor entry into the bootloader is desired in + * situations where the user program does not run properly and therefore cannot + * reactivate the bootloader. By enabling these hook functions, the application can + * implement the backdoor, which overrides the default backdoor entry that is programmed + * into the bootloader. When desired for security purposes, these hook functions can + * also be implemented in a way that disables the backdoor entry altogether. + */ +#define BOOT_BACKDOOR_HOOKS_ENABLE (0) + + +/**************************************************************************************** +* N O N - V O L A T I L E M E M O R Y D R I V E R C O N F I G U R A T I O N +****************************************************************************************/ +/* The NVM driver typically supports erase and program operations of the internal memory + * present on the microcontroller. Through these hook functions the NVM driver can be + * extended to support additional memory types such as external flash memory and serial + * eeproms. The size of the internal memory in kilobytes is specified with configurable + * BOOT_NVM_SIZE_KB. + */ +#define BOOT_NVM_HOOKS_ENABLE (0) +#define BOOT_NVM_SIZE_KB (256) + + +/**************************************************************************************** +* W A T C H D O G D R I V E R C O N F I G U R A T I O N +****************************************************************************************/ +/* The COP driver cannot be configured internally in the bootloader, because its use + * and configuration is application specific. The bootloader does need to service the + * watchdog in case it is used. When the application requires the use of a watchdog, + * set BOOT_COP_HOOKS_ENABLE to be able to initialize and service the watchdog through + * hook functions. + */ +#define BOOT_COP_HOOKS_ENABLE (0) + + +#endif /* CONFIG_H */ +/*********************************** end of config.h ***********************************/ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/hooks.c b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/hooks.c new file mode 100644 index 00000000..e46906ec --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/hooks.c @@ -0,0 +1,187 @@ +/**************************************************************************************** +| Description: bootloader callback source file +| File Name: hooks.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ +#include "lpc2294.h" /* CPU register definitions */ + + +/**************************************************************************************** +* B A C K D O O R E N T R Y H O O K F U N C T I O N S +****************************************************************************************/ + +#if (BOOT_BACKDOOR_HOOKS_ENABLE > 0) +/**************************************************************************************** +** NAME: BackDoorInitHook +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Initializes the backdoor entry option. +** +****************************************************************************************/ +void BackDoorInitHook(void) +{ + /* configure the button connected to P0.16 as a digital input */ + IO0DIR &= ~(1<<16); +} /*** end of BackDoorInitHook ***/ + + +/**************************************************************************************** +** NAME: BackDoorEntryHook +** PARAMETER: none +** RETURN VALUE: BLT_TRUE if the backdoor entry is requested, BLT_FALSE otherwise. +** DESCRIPTION: Checks if a backdoor entry is requested. +** +****************************************************************************************/ +blt_bool BackDoorEntryHook(void) +{ + /* button P0.16 has a pullup, so will read high by default. enter backdoor only when + * this button is pressed. this is the case when it reads low */ + if ((IO0PIN & (1<<16)) == 0) + { + return BLT_TRUE; + } + return BLT_FALSE; +} /*** end of BackDoorEntryHook ***/ +#endif /* BOOT_BACKDOOR_HOOKS_ENABLE > 0 */ + + +/**************************************************************************************** +* N O N - V O L A T I L E M E M O R Y D R I V E R H O O K F U N C T I O N S +****************************************************************************************/ + +#if (BOOT_NVM_HOOKS_ENABLE > 0) +/**************************************************************************************** +** NAME: NvmInitHook +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Callback that gets called at the start of the internal NVM driver +** initialization routine. +** +****************************************************************************************/ +void NvmInitHook(void) +{ +} /*** end of NvmInitHook ***/ + + +/**************************************************************************************** +** NAME: NvmWriteHook +** PARAMETER: addr start address +** len length in bytes +** data pointer to the data buffer. +** RETURN VALUE: BTL_NVM_OKAY if successful, BTL_NVM_NOT_IN_RANGE if the address is +** not within the supported memory range, or BTL_NVM_ERROR is the write +** operation failed. +** DESCRIPTION: Callback that gets called at the start of the NVM driver write +** routine. It allows additional memory to be operated on. If the address +** is not within the range of the additional memory, then +** BTL_NVM_NOT_IN_RANGE must be returned to indicate that the data hasn't +** been written yet. +** +** +****************************************************************************************/ +blt_int8u NvmWriteHook(blt_addr addr, blt_int32u len, blt_int8u *data) +{ + return BTL_NVM_NOT_IN_RANGE; +} /*** end of NvmWriteHook ***/ + + +/**************************************************************************************** +** NAME: NvmEraseHook +** PARAMETER: addr start address +** len length in bytes +** RETURN VALUE: BTL_NVM_OKAY if successful, BTL_NVM_NOT_IN_RANGE if the address is +** not within the supported memory range, or BTL_NVM_ERROR is the erase +** operation failed. +** DESCRIPTION: Callback that gets called at the start of the NVM driver erase +** routine. It allows additional memory to be operated on. If the address +** is not within the range of the additional memory, then +** BTL_NVM_NOT_IN_RANGE must be returned to indicate that the memory +** hasn't been erased yet. +** +****************************************************************************************/ +blt_bool NvmEraseHook(blt_addr addr, blt_int32u len) +{ + return BTL_NVM_NOT_IN_RANGE; +} /*** end of NvmEraseHook ***/ + + +/**************************************************************************************** +** NAME: NvmDoneHook +** PARAMETER: none +** RETURN VALUE: BLT_TRUE is successful, BLT_FALSE otherwise. +** DESCRIPTION: Callback that gets called at the end of the NVM programming session. +** +****************************************************************************************/ +blt_bool NvmDoneHook(void) +{ + return BLT_TRUE; +} /*** end of NvmDoneHook ***/ +#endif /* BOOT_NVM_HOOKS_ENABLE > 0 */ + + +/**************************************************************************************** +* W A T C H D O G D R I V E R H O O K F U N C T I O N S +****************************************************************************************/ + +#if (BOOT_COP_HOOKS_ENABLE > 0) +/**************************************************************************************** +** NAME: CopInitHook +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Callback that gets called at the end of the internal COP driver +** initialization routine. It can be used to configure and enable the +** watchdog. +** +****************************************************************************************/ +void CopInitHook(void) +{ +} /*** end of CopInitHook ***/ + + +/**************************************************************************************** +** NAME: CopServiceHook +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Callback that gets called at the end of the internal COP driver +** service routine. This gets called upon initialization and during +** potential long lasting loops and routine. It can be used to service +** the watchdog to prevent a watchdog reset. +** +****************************************************************************************/ +void CopServiceHook(void) +{ +} /*** end of CopServiceHook ***/ +#endif /* BOOT_COP_HOOKS_ENABLE > 0 */ + + +/*********************************** end of hooks.c ************************************/ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/ide/DemoBoot.project b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/ide/DemoBoot.project new file mode 100644 index 00000000..d496df15 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/ide/DemoBoot.project @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + break main +continue + + + + + + + make clean + make + + + + None + $(WorkspacePath)/.. + + + + + + + + + + + + + + + + + + + + + + + make clean + make + + + + None + $(WorkspacePath) + + + + + + + + diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/ide/DemoBoot.workspace b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/ide/DemoBoot.workspace new file mode 100644 index 00000000..7957a1d7 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/ide/DemoBoot.workspace @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/ide/readme.txt b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/ide/readme.txt new file mode 100644 index 00000000..8a340a19 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/ide/readme.txt @@ -0,0 +1,4 @@ +Integrated Development Environment +---------------------------------- +Codelite was used as the editor during the development of this software program. This directory contains the Codelite +workspace and project files. Codelite is a cross platform open source C/C++ IDE, available at http://www.codelite.org/. \ No newline at end of file diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/lpc2294.h b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/lpc2294.h new file mode 100644 index 00000000..209015fb --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/lpc2294.h @@ -0,0 +1,409 @@ +/**************************************************************************************** +| Description: NXP LPC2294 register definitions +| File Name: lpc2294.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef LPC2294_H +#define LPC2294_H + + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +/* EXTERNAL MEMORY CONTROLLER (EMC) */ +#define BCFG0 (*((volatile unsigned long *) 0xFFE00000)) /* lpc22xx only */ +#define BCFG1 (*((volatile unsigned long *) 0xFFE00004)) /* lpc22xx only */ +#define BCFG2 (*((volatile unsigned long *) 0xFFE00008)) /* lpc22xx only */ +#define BCFG3 (*((volatile unsigned long *) 0xFFE0000C)) /* lpc22xx only */ + +/* External Interrupts */ +#define EXTINT (*((volatile unsigned char *) 0xE01FC140)) +#define EXTWAKE (*((volatile unsigned char *) 0xE01FC144)) +#define EXTMODE (*((volatile unsigned char *) 0xE01FC148)) /* no in lpc210x*/ +#define EXTPOLAR (*((volatile unsigned char *) 0xE01FC14C)) /* no in lpc210x*/ + +/* SMemory mapping control. */ +#define MEMMAP (*((volatile unsigned long *) 0xE01FC040)) + +/* Phase Locked Loop (PLL) */ +#define PLLCON (*((volatile unsigned char *) 0xE01FC080)) +#define PLLCFG (*((volatile unsigned char *) 0xE01FC084)) +#define PLLSTAT (*((volatile unsigned short*) 0xE01FC088)) +#define PLLFEED (*((volatile unsigned char *) 0xE01FC08C)) + +/* Power Control */ +#define PCON (*((volatile unsigned char *) 0xE01FC0C0)) +#define PCONP (*((volatile unsigned long *) 0xE01FC0C4)) + +/* VPB Divider */ +#define VPBDIV (*((volatile unsigned char *) 0xE01FC100)) + +/* Memory Accelerator Module (MAM) */ +#define MAMCR (*((volatile unsigned char *) 0xE01FC000)) +#define MAMTIM (*((volatile unsigned char *) 0xE01FC004)) + +/* Vectored Interrupt Controller (VIC) */ +#define VICIRQStatus (*((volatile unsigned long *) 0xFFFFF000)) +#define VICFIQStatus (*((volatile unsigned long *) 0xFFFFF004)) +#define VICRawIntr (*((volatile unsigned long *) 0xFFFFF008)) +#define VICIntSelect (*((volatile unsigned long *) 0xFFFFF00C)) +#define VICIntEnable (*((volatile unsigned long *) 0xFFFFF010)) +#define VICIntEnClr (*((volatile unsigned long *) 0xFFFFF014)) +#define VICSoftInt (*((volatile unsigned long *) 0xFFFFF018)) +#define VICSoftIntClear (*((volatile unsigned long *) 0xFFFFF01C)) +#define VICProtection (*((volatile unsigned long *) 0xFFFFF020)) +#define VICVectAddr (*((volatile unsigned long *) 0xFFFFF030)) +#define VICDefVectAddr (*((volatile unsigned long *) 0xFFFFF034)) +#define VICVectAddr0 (*((volatile unsigned long *) 0xFFFFF100)) +#define VICVectAddr1 (*((volatile unsigned long *) 0xFFFFF104)) +#define VICVectAddr2 (*((volatile unsigned long *) 0xFFFFF108)) +#define VICVectAddr3 (*((volatile unsigned long *) 0xFFFFF10C)) +#define VICVectAddr4 (*((volatile unsigned long *) 0xFFFFF110)) +#define VICVectAddr5 (*((volatile unsigned long *) 0xFFFFF114)) +#define VICVectAddr6 (*((volatile unsigned long *) 0xFFFFF118)) +#define VICVectAddr7 (*((volatile unsigned long *) 0xFFFFF11C)) +#define VICVectAddr8 (*((volatile unsigned long *) 0xFFFFF120)) +#define VICVectAddr9 (*((volatile unsigned long *) 0xFFFFF124)) +#define VICVectAddr10 (*((volatile unsigned long *) 0xFFFFF128)) +#define VICVectAddr11 (*((volatile unsigned long *) 0xFFFFF12C)) +#define VICVectAddr12 (*((volatile unsigned long *) 0xFFFFF130)) +#define VICVectAddr13 (*((volatile unsigned long *) 0xFFFFF134)) +#define VICVectAddr14 (*((volatile unsigned long *) 0xFFFFF138)) +#define VICVectAddr15 (*((volatile unsigned long *) 0xFFFFF13C)) +#define VICVectCntl0 (*((volatile unsigned long *) 0xFFFFF200)) +#define VICVectCntl1 (*((volatile unsigned long *) 0xFFFFF204)) +#define VICVectCntl2 (*((volatile unsigned long *) 0xFFFFF208)) +#define VICVectCntl3 (*((volatile unsigned long *) 0xFFFFF20C)) +#define VICVectCntl4 (*((volatile unsigned long *) 0xFFFFF210)) +#define VICVectCntl5 (*((volatile unsigned long *) 0xFFFFF214)) +#define VICVectCntl6 (*((volatile unsigned long *) 0xFFFFF218)) +#define VICVectCntl7 (*((volatile unsigned long *) 0xFFFFF21C)) +#define VICVectCntl8 (*((volatile unsigned long *) 0xFFFFF220)) +#define VICVectCntl9 (*((volatile unsigned long *) 0xFFFFF224)) +#define VICVectCntl10 (*((volatile unsigned long *) 0xFFFFF228)) +#define VICVectCntl11 (*((volatile unsigned long *) 0xFFFFF22C)) +#define VICVectCntl12 (*((volatile unsigned long *) 0xFFFFF230)) +#define VICVectCntl13 (*((volatile unsigned long *) 0xFFFFF234)) +#define VICVectCntl14 (*((volatile unsigned long *) 0xFFFFF238)) +#define VICVectCntl15 (*((volatile unsigned long *) 0xFFFFF23C)) + +/* Pin Connect Block */ +#define PINSEL0 (*((volatile unsigned long *) 0xE002C000)) +#define PINSEL1 (*((volatile unsigned long *) 0xE002C004)) +#define PINSEL2 (*((volatile unsigned long *) 0xE002C014)) /* no in lpc210x*/ + +/* General Purpose Input/Output (GPIO) */ +#define IOPIN (*((volatile unsigned long *) 0xE0028000)) /* lpc210x only */ +#define IOSET (*((volatile unsigned long *) 0xE0028004)) /* lpc210x only */ +#define IODIR (*((volatile unsigned long *) 0xE0028008)) /* lpc210x only */ +#define IOCLR (*((volatile unsigned long *) 0xE002800C)) /* lpc210x only */ + +#define IO0PIN (*((volatile unsigned long *) 0xE0028000)) /* no in lpc210x*/ +#define IO0SET (*((volatile unsigned long *) 0xE0028004)) /* no in lpc210x*/ +#define IO0DIR (*((volatile unsigned long *) 0xE0028008)) /* no in lpc210x*/ +#define IO0CLR (*((volatile unsigned long *) 0xE002800C)) /* no in lpc210x*/ + +#define IO1PIN (*((volatile unsigned long *) 0xE0028010)) /* no in lpc210x*/ +#define IO1SET (*((volatile unsigned long *) 0xE0028014)) /* no in lpc210x*/ +#define IO1DIR (*((volatile unsigned long *) 0xE0028018)) /* no in lpc210x*/ +#define IO1CLR (*((volatile unsigned long *) 0xE002801C)) /* no in lpc210x*/ + +#define IO2PIN (*((volatile unsigned long *) 0xE0028020)) /* lpc22xx only */ +#define IO2SET (*((volatile unsigned long *) 0xE0028024)) /* lpc22xx only */ +#define IO2DIR (*((volatile unsigned long *) 0xE0028028)) /* lpc22xx only */ +#define IO2CLR (*((volatile unsigned long *) 0xE002802C)) /* lpc22xx only */ + +#define IO3PIN (*((volatile unsigned long *) 0xE0028030)) /* lpc22xx only */ +#define IO3SET (*((volatile unsigned long *) 0xE0028034)) /* lpc22xx only */ +#define IO3DIR (*((volatile unsigned long *) 0xE0028038)) /* lpc22xx only */ +#define IO3CLR (*((volatile unsigned long *) 0xE002803C)) /* lpc22xx only */ + +/* Universal Asynchronous Receiver Transmitter 0 (UART0) */ +#define U0RBR (*((volatile unsigned char *) 0xE000C000)) +#define U0THR (*((volatile unsigned char *) 0xE000C000)) +#define U0IER (*((volatile unsigned char *) 0xE000C004)) +#define U0IIR (*((volatile unsigned char *) 0xE000C008)) +#define U0FCR (*((volatile unsigned char *) 0xE000C008)) +#define U0LCR (*((volatile unsigned char *) 0xE000C00C)) +#define U0LSR (*((volatile unsigned char *) 0xE000C014)) +#define U0SCR (*((volatile unsigned char *) 0xE000C01C)) +#define U0DLL (*((volatile unsigned char *) 0xE000C000)) +#define U0DLM (*((volatile unsigned char *) 0xE000C004)) + +/* Universal Asynchronous Receiver Transmitter 1 (UART1) */ +#define U1RBR (*((volatile unsigned char *) 0xE0010000)) +#define U1THR (*((volatile unsigned char *) 0xE0010000)) +#define U1IER (*((volatile unsigned char *) 0xE0010004)) +#define U1IIR (*((volatile unsigned char *) 0xE0010008)) +#define U1FCR (*((volatile unsigned char *) 0xE0010008)) +#define U1LCR (*((volatile unsigned char *) 0xE001000C)) +#define U1MCR (*((volatile unsigned char *) 0xE0010010)) +#define U1LSR (*((volatile unsigned char *) 0xE0010014)) +#define U1MSR (*((volatile unsigned char *) 0xE0010018)) +#define U1SCR (*((volatile unsigned char *) 0xE001001C)) +#define U1DLL (*((volatile unsigned char *) 0xE0010000)) +#define U1DLM (*((volatile unsigned char *) 0xE0010004)) + +/* I2C (8/16 bit data bus) */ +#define I2CONSET (*((volatile unsigned long *) 0xE001C000)) +#define I2STAT (*((volatile unsigned long *) 0xE001C004)) +#define I2DAT (*((volatile unsigned long *) 0xE001C008)) +#define I2ADR (*((volatile unsigned long *) 0xE001C00C)) +#define I2SCLH (*((volatile unsigned long *) 0xE001C010)) +#define I2SCLL (*((volatile unsigned long *) 0xE001C014)) +#define I2CONCLR (*((volatile unsigned long *) 0xE001C018)) + +/* SPI (Serial Peripheral Interface) */ + /* only for lpc210x*/ +#define SPI_SPCR (*((volatile unsigned char *) 0xE0020000)) +#define SPI_SPSR (*((volatile unsigned char *) 0xE0020004)) +#define SPI_SPDR (*((volatile unsigned char *) 0xE0020008)) +#define SPI_SPCCR (*((volatile unsigned char *) 0xE002000C)) +#define SPI_SPINT (*((volatile unsigned char *) 0xE002001C)) + +#define S0PCR (*((volatile unsigned char *) 0xE0020000)) /* no in lpc210x*/ +#define S0PSR (*((volatile unsigned char *) 0xE0020004)) /* no in lpc210x*/ +#define S0PDR (*((volatile unsigned char *) 0xE0020008)) /* no in lpc210x*/ +#define S0PCCR (*((volatile unsigned char *) 0xE002000C)) /* no in lpc210x*/ +#define S0PINT (*((volatile unsigned char *) 0xE002001C)) /* no in lpc210x*/ + +#define S1PCR (*((volatile unsigned char *) 0xE0030000)) /* no in lpc210x*/ +#define S1PSR (*((volatile unsigned char *) 0xE0030004)) /* no in lpc210x*/ +#define S1PDR (*((volatile unsigned char *) 0xE0030008)) /* no in lpc210x*/ +#define S1PCCR (*((volatile unsigned char *) 0xE003000C)) /* no in lpc210x*/ +#define S1PINT (*((volatile unsigned char *) 0xE003001C)) /* no in lpc210x*/ + +/* CAN CONTROLLERS AND ACCEPTANCE FILTER */ +#define CAN1MOD (*((volatile unsigned long *) 0xE0044000)) /* All CAN Parts */ +#define CAN1CMR (*((volatile unsigned long *) 0xE0044004)) /* All CAN Parts */ +#define CAN1GSR (*((volatile unsigned long *) 0xE0044008)) /* All CAN Parts */ +#define CAN1ICR (*((volatile unsigned long *) 0xE004400C)) /* All CAN Parts */ +#define CAN1IER (*((volatile unsigned long *) 0xE0044010)) /* All CAN Parts */ +#define CAN1BTR (*((volatile unsigned long *) 0xE0044014)) /* All CAN Parts */ +#define CAN1EWL (*((volatile unsigned long *) 0xE0044018)) /* All CAN Parts */ +#define CAN1SR (*((volatile unsigned long *) 0xE004401C)) /* All CAN Parts */ +#define CAN1RFS (*((volatile unsigned long *) 0xE0044020)) /* All CAN Parts */ +#define CAN1RID (*((volatile unsigned long *) 0xE0044024)) /* All CAN Parts */ +#define CAN1RDA (*((volatile unsigned long *) 0xE0044028)) /* All CAN Parts */ +#define CAN1RDB (*((volatile unsigned long *) 0xE004402C)) /* All CAN Parts */ +#define CAN1TFI1 (*((volatile unsigned long *) 0xE0044030)) /* All CAN Parts */ +#define CAN1TID1 (*((volatile unsigned long *) 0xE0044034)) /* All CAN Parts */ +#define CAN1TDA1 (*((volatile unsigned long *) 0xE0044038)) /* All CAN Parts */ +#define CAN1TDB1 (*((volatile unsigned long *) 0xE004403C)) /* All CAN Parts */ +#define CAN1TFI2 (*((volatile unsigned long *) 0xE0044040)) /* All CAN Parts */ +#define CAN1TID2 (*((volatile unsigned long *) 0xE0044044)) /* All CAN Parts */ +#define CAN1TDA2 (*((volatile unsigned long *) 0xE0044048)) /* All CAN Parts */ +#define CAN1TDB2 (*((volatile unsigned long *) 0xE004404C)) /* All CAN Parts */ +#define CAN1TFI3 (*((volatile unsigned long *) 0xE0044050)) /* All CAN Parts */ +#define CAN1TID3 (*((volatile unsigned long *) 0xE0044054)) /* All CAN Parts */ +#define CAN1TDA3 (*((volatile unsigned long *) 0xE0044058)) /* All CAN Parts */ +#define CAN1TDB3 (*((volatile unsigned long *) 0xE004405C)) /* All CAN Parts */ + +#define CAN2MOD (*((volatile unsigned long *) 0xE0048000)) /* All CAN Parts */ +#define CAN2CMR (*((volatile unsigned long *) 0xE0048004)) /* All CAN Parts */ +#define CAN2GSR (*((volatile unsigned long *) 0xE0048008)) /* All CAN Parts */ +#define CAN2ICR (*((volatile unsigned long *) 0xE004800C)) /* All CAN Parts */ +#define CAN2IER (*((volatile unsigned long *) 0xE0048010)) /* All CAN Parts */ +#define CAN2BTR (*((volatile unsigned long *) 0xE0048014)) /* All CAN Parts */ +#define CAN2EWL (*((volatile unsigned long *) 0xE0048018)) /* All CAN Parts */ +#define CAN2SR (*((volatile unsigned long *) 0xE004801C)) /* All CAN Parts */ +#define CAN2RFS (*((volatile unsigned long *) 0xE0048020)) /* All CAN Parts */ +#define CAN2RID (*((volatile unsigned long *) 0xE0048024)) /* All CAN Parts */ +#define CAN2RDA (*((volatile unsigned long *) 0xE0048028)) /* All CAN Parts */ +#define CAN2RDB (*((volatile unsigned long *) 0xE004802C)) /* All CAN Parts */ +#define CAN2TFI1 (*((volatile unsigned long *) 0xE0048030)) /* All CAN Parts */ +#define CAN2TID1 (*((volatile unsigned long *) 0xE0048034)) /* All CAN Parts */ +#define CAN2TDA1 (*((volatile unsigned long *) 0xE0048038)) /* All CAN Parts */ +#define CAN2TDB1 (*((volatile unsigned long *) 0xE004803C)) /* All CAN Parts */ +#define CAN2TFI2 (*((volatile unsigned long *) 0xE0048040)) /* All CAN Parts */ +#define CAN2TID2 (*((volatile unsigned long *) 0xE0048044)) /* All CAN Parts */ +#define CAN2TDA2 (*((volatile unsigned long *) 0xE0048048)) /* All CAN Parts */ +#define CAN2TDB2 (*((volatile unsigned long *) 0xE004804C)) /* All CAN Parts */ +#define CAN2TFI3 (*((volatile unsigned long *) 0xE0048050)) /* All CAN Parts */ +#define CAN2TID3 (*((volatile unsigned long *) 0xE0048054)) /* All CAN Parts */ +#define CAN2TDA3 (*((volatile unsigned long *) 0xE0048058)) /* All CAN Parts */ +#define CAN2TDB3 (*((volatile unsigned long *) 0xE004805C)) /* All CAN Parts */ + +#define CAN3MOD (*((volatile unsigned long *) 0xE004C000)) /* lpc2194\lpc2294 only */ +#define CAN3CMR (*((volatile unsigned long *) 0xE004C004)) /* lpc2194\lpc2294 only */ +#define CAN3GSR (*((volatile unsigned long *) 0xE004C008)) /* lpc2194\lpc2294 only */ +#define CAN3ICR (*((volatile unsigned long *) 0xE004C00C)) /* lpc2194\lpc2294 only */ +#define CAN3IER (*((volatile unsigned long *) 0xE004C010)) /* lpc2194\lpc2294 only */ +#define CAN3BTR (*((volatile unsigned long *) 0xE004C014)) /* lpc2194\lpc2294 only */ +#define CAN3EWL (*((volatile unsigned long *) 0xE004C018)) /* lpc2194\lpc2294 only */ +#define CAN3SR (*((volatile unsigned long *) 0xE004C01C)) /* lpc2194\lpc2294 only */ +#define CAN3RFS (*((volatile unsigned long *) 0xE004C020)) /* lpc2194\lpc2294 only */ +#define CAN3RID (*((volatile unsigned long *) 0xE004C024)) /* lpc2194\lpc2294 only */ +#define CAN3RDA (*((volatile unsigned long *) 0xE004C028)) /* lpc2194\lpc2294 only */ +#define CAN3RDB (*((volatile unsigned long *) 0xE004C02C)) /* lpc2194\lpc2294 only */ +#define CAN3TFI1 (*((volatile unsigned long *) 0xE004C030)) /* lpc2194\lpc2294 only */ +#define CAN3TID1 (*((volatile unsigned long *) 0xE004C034)) /* lpc2194\lpc2294 only */ +#define CAN3TDA1 (*((volatile unsigned long *) 0xE004C038)) /* lpc2194\lpc2294 only */ +#define CAN3TDB1 (*((volatile unsigned long *) 0xE004C03C)) /* lpc2194\lpc2294 only */ +#define CAN3TFI2 (*((volatile unsigned long *) 0xE004C040)) /* lpc2194\lpc2294 only */ +#define CAN3TID2 (*((volatile unsigned long *) 0xE004C044)) /* lpc2194\lpc2294 only */ +#define CAN3TDA2 (*((volatile unsigned long *) 0xE004C048)) /* lpc2194\lpc2294 only */ +#define CAN3TDB2 (*((volatile unsigned long *) 0xE004C04C)) /* lpc2194\lpc2294 only */ +#define CAN3TFI3 (*((volatile unsigned long *) 0xE004C050)) /* lpc2194\lpc2294 only */ +#define CAN3TID3 (*((volatile unsigned long *) 0xE004C054)) /* lpc2194\lpc2294 only */ +#define CAN3TDA3 (*((volatile unsigned long *) 0xE004C058)) /* lpc2194\lpc2294 only */ +#define CAN3TDB3 (*((volatile unsigned long *) 0xE004C05C)) /* lpc2194\lpc2294 only */ + +#define CAN4MOD (*((volatile unsigned long *) 0xE0050000)) /* lpc2194\lpc2294 only */ +#define CAN4CMR (*((volatile unsigned long *) 0xE0050004)) /* lpc2194\lpc2294 only */ +#define CAN4GSR (*((volatile unsigned long *) 0xE0050008)) /* lpc2194\lpc2294 only */ +#define CAN4ICR (*((volatile unsigned long *) 0xE005000C)) /* lpc2194\lpc2294 only */ +#define CAN4IER (*((volatile unsigned long *) 0xE0050010)) /* lpc2194\lpc2294 only */ +#define CAN4BTR (*((volatile unsigned long *) 0xE0050014)) /* lpc2194\lpc2294 only */ +#define CAN4EWL (*((volatile unsigned long *) 0xE0050018)) /* lpc2194\lpc2294 only */ +#define CAN4SR (*((volatile unsigned long *) 0xE005001C)) /* lpc2194\lpc2294 only */ +#define CAN4RFS (*((volatile unsigned long *) 0xE0050020)) /* lpc2194\lpc2294 only */ +#define CAN4RID (*((volatile unsigned long *) 0xE0050024)) /* lpc2194\lpc2294 only */ +#define CAN4RDA (*((volatile unsigned long *) 0xE0050028)) /* lpc2194\lpc2294 only */ +#define CAN4RDB (*((volatile unsigned long *) 0xE005002C)) /* lpc2194\lpc2294 only */ +#define CAN4TFI1 (*((volatile unsigned long *) 0xE0050030)) /* lpc2194\lpc2294 only */ +#define CAN4TID1 (*((volatile unsigned long *) 0xE0050034)) /* lpc2194\lpc2294 only */ +#define CAN4TDA1 (*((volatile unsigned long *) 0xE0050038)) /* lpc2194\lpc2294 only */ +#define CAN4TDB1 (*((volatile unsigned long *) 0xE005003C)) /* lpc2194\lpc2294 only */ +#define CAN4TFI2 (*((volatile unsigned long *) 0xE0050040)) /* lpc2194\lpc2294 only */ +#define CAN4TID2 (*((volatile unsigned long *) 0xE0050044)) /* lpc2194\lpc2294 only */ +#define CAN4TDA2 (*((volatile unsigned long *) 0xE0050048)) /* lpc2194\lpc2294 only */ +#define CAN4TDB2 (*((volatile unsigned long *) 0xE005004C)) /* lpc2194\lpc2294 only */ +#define CAN4TFI3 (*((volatile unsigned long *) 0xE0050050)) /* lpc2194\lpc2294 only */ +#define CAN4TID3 (*((volatile unsigned long *) 0xE0050054)) /* lpc2194\lpc2294 only */ +#define CAN4TDA3 (*((volatile unsigned long *) 0xE0050058)) /* lpc2194\lpc2294 only */ +#define CAN4TDB3 (*((volatile unsigned long *) 0xE005005C)) /* lpc2194\lpc2294 only */ + + +#define CANTxSR (*((volatile unsigned long *) 0xE0040000)) /* ALL CAN Parts */ +#define CANRxSR (*((volatile unsigned long *) 0xE0040004)) /* ALL CAN Parts */ +#define CANMSR (*((volatile unsigned long *) 0xE0040008)) /* ALL CAN Parts */ + +#define CANAFMR (*((volatile unsigned char *) 0xE003C000)) /* ALL CAN Parts */ +#define CANSFF_sa (*((volatile unsigned short*) 0xE003C004)) /* ALL CAN Parts */ +#define CANSFF_GRP_sa (*((volatile unsigned short*) 0xE003C008)) /* ALL CAN Parts */ +#define CANEFF_sa (*((volatile unsigned short*) 0xE003C00C)) /* ALL CAN Parts */ +#define CANEFF_GRP_sa (*((volatile unsigned short*) 0xE003C010)) /* ALL CAN Parts */ +#define CANENDofTable (*((volatile unsigned short*) 0xE003C014)) /* ALL CAN Parts */ +#define CANLUTerrAd (*((volatile unsigned short*) 0xE003C018)) /* ALL CAN Parts */ +#define CANLUTerr (*((volatile unsigned char *) 0xE003C01C)) /* ALL CAN Parts */ + + +/* Timer 0 */ +#define T0IR (*((volatile unsigned long *) 0xE0004000)) +#define T0TCR (*((volatile unsigned long *) 0xE0004004)) +#define T0TC (*((volatile unsigned long *) 0xE0004008)) +#define T0PR (*((volatile unsigned long *) 0xE000400C)) +#define T0PC (*((volatile unsigned long *) 0xE0004010)) +#define T0MCR (*((volatile unsigned long *) 0xE0004014)) +#define T0MR0 (*((volatile unsigned long *) 0xE0004018)) +#define T0MR1 (*((volatile unsigned long *) 0xE000401C)) +#define T0MR2 (*((volatile unsigned long *) 0xE0004020)) +#define T0MR3 (*((volatile unsigned long *) 0xE0004024)) +#define T0CCR (*((volatile unsigned long *) 0xE0004028)) +#define T0CR0 (*((volatile unsigned long *) 0xE000402C)) +#define T0CR1 (*((volatile unsigned long *) 0xE0004030)) +#define T0CR2 (*((volatile unsigned long *) 0xE0004034)) +#define T0CR3 (*((volatile unsigned long *) 0xE0004038)) +#define T0EMR (*((volatile unsigned long *) 0xE000403C)) + +/* Timer 1 */ +#define T1IR (*((volatile unsigned long *) 0xE0008000)) +#define T1TCR (*((volatile unsigned long *) 0xE0008004)) +#define T1TC (*((volatile unsigned long *) 0xE0008008)) +#define T1PR (*((volatile unsigned long *) 0xE000800C)) +#define T1PC (*((volatile unsigned long *) 0xE0008010)) +#define T1MCR (*((volatile unsigned long *) 0xE0008014)) +#define T1MR0 (*((volatile unsigned long *) 0xE0008018)) +#define T1MR1 (*((volatile unsigned long *) 0xE000801C)) +#define T1MR2 (*((volatile unsigned long *) 0xE0008020)) +#define T1MR3 (*((volatile unsigned long *) 0xE0008024)) +#define T1CCR (*((volatile unsigned long *) 0xE0008028)) +#define T1CR0 (*((volatile unsigned long *) 0xE000802C)) +#define T1CR1 (*((volatile unsigned long *) 0xE0008030)) +#define T1CR2 (*((volatile unsigned long *) 0xE0008034)) +#define T1CR3 (*((volatile unsigned long *) 0xE0008038)) +#define T1EMR (*((volatile unsigned long *) 0xE000803C)) + +/* Pulse Width Modulator (PWM) */ +#define PWMIR (*((volatile unsigned long *) 0xE0014000)) +#define PWMTCR (*((volatile unsigned long *) 0xE0014004)) +#define PWMTC (*((volatile unsigned long *) 0xE0014008)) +#define PWMPR (*((volatile unsigned long *) 0xE001400C)) +#define PWMPC (*((volatile unsigned long *) 0xE0014010)) +#define PWMMCR (*((volatile unsigned long *) 0xE0014014)) +#define PWMMR0 (*((volatile unsigned long *) 0xE0014018)) +#define PWMMR1 (*((volatile unsigned long *) 0xE001401C)) +#define PWMMR2 (*((volatile unsigned long *) 0xE0014020)) +#define PWMMR3 (*((volatile unsigned long *) 0xE0014024)) +#define PWMMR4 (*((volatile unsigned long *) 0xE0014040)) +#define PWMMR5 (*((volatile unsigned long *) 0xE0014044)) +#define PWMMR6 (*((volatile unsigned long *) 0xE0014048)) +#define PWMPCR (*((volatile unsigned long *) 0xE001404C)) +#define PWMLER (*((volatile unsigned long *) 0xE0014050)) + +/* A/D CONVERTER */ +#define ADCR (*((volatile unsigned long *) 0xE0034000)) /* no in lpc210x*/ +#define ADDR (*((volatile unsigned long *) 0xE0034004)) /* no in lpc210x*/ + +/* Real Time Clock */ +#define ILR (*((volatile unsigned char *) 0xE0024000)) +#define CTC (*((volatile unsigned short*) 0xE0024004)) +#define CCR (*((volatile unsigned char *) 0xE0024008)) +#define CIIR (*((volatile unsigned char *) 0xE002400C)) +#define AMR (*((volatile unsigned char *) 0xE0024010)) +#define CTIME0 (*((volatile unsigned long *) 0xE0024014)) +#define CTIME1 (*((volatile unsigned long *) 0xE0024018)) +#define CTIME2 (*((volatile unsigned long *) 0xE002401C)) +#define SEC (*((volatile unsigned char *) 0xE0024020)) +#define MIN (*((volatile unsigned char *) 0xE0024024)) +#define HOUR (*((volatile unsigned char *) 0xE0024028)) +#define DOM (*((volatile unsigned char *) 0xE002402C)) +#define DOW (*((volatile unsigned char *) 0xE0024030)) +#define DOY (*((volatile unsigned short*) 0xE0024034)) +#define MONTH (*((volatile unsigned char *) 0xE0024038)) +#define YEAR (*((volatile unsigned short*) 0xE002403C)) +#define ALSEC (*((volatile unsigned char *) 0xE0024060)) +#define ALMIN (*((volatile unsigned char *) 0xE0024064)) +#define ALHOUR (*((volatile unsigned char *) 0xE0024068)) +#define ALDOM (*((volatile unsigned char *) 0xE002406C)) +#define ALDOW (*((volatile unsigned char *) 0xE0024070)) +#define ALDOY (*((volatile unsigned short*) 0xE0024074)) +#define ALMON (*((volatile unsigned char *) 0xE0024078)) +#define ALYEAR (*((volatile unsigned short*) 0xE002407C)) +#define PREINT (*((volatile unsigned short*) 0xE0024080)) +#define PREFRAC (*((volatile unsigned short*) 0xE0024084)) + +/* Watchdog */ +#define WDMOD (*((volatile unsigned char *) 0xE0000000)) +#define WDTC (*((volatile unsigned long *) 0xE0000004)) +#define WDFEED (*((volatile unsigned char *) 0xE0000008)) +#define WDTV (*((volatile unsigned long *) 0xE000000C)) + +#endif /* LPC2294_H */ +/*********************************** end of lpc2294.h **********************************/ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/main.c b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/main.c new file mode 100644 index 00000000..bd9c8bab --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/main.c @@ -0,0 +1,158 @@ +/**************************************************************************************** +| Description: bootloader application source file +| File Name: main.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ +#include "lpc2294.h" /* CPU register definitions */ + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +static void Init(void); + + +/**************************************************************************************** +** NAME: main +** PARAMETER: none +** RETURN VALUE: program return code +** DESCRIPTION: This is the entry point for the bootloader application and is called +** by the reset interrupt vector after the C-startup routines executed. +** +****************************************************************************************/ +int main(void) +{ + /* initialize the microcontroller */ + Init(); + /* initialize the bootloader */ + BootInit(); + /* start the infinite program loop */ + while (1) + { + /* run the bootloader task */ + BootTask(); + } + + /* program should never get here */ + return 0; +} /*** end of main ***/ + + +/**************************************************************************************** +** NAME: Init +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Initializes the microcontroller. The Fpll is set to 60MHz and Fvpb is +** configured equal to Fpll. The GPIO pin of the status LED is configured +** as digital output. +** +****************************************************************************************/ +static void Init(void) +{ + blt_int8u m_sel; /* pll multiplier register value */ + blt_int8u pll_dividers[] = { 1, 2, 4, 8 }; /* possible pll dividers */ + blt_int8u p_sel_cnt; /* loop counter to find p_sel */ + blt_int32u f_cco; /* current controller oscillator */ + + /* check that pll multiplier value will be in the range 1..32 */ + ASSERT_CT((BOOT_CPU_SYSTEM_SPEED_KHZ + ((BOOT_CPU_XTAL_SPEED_KHZ+1)/2)) / \ + BOOT_CPU_XTAL_SPEED_KHZ >= 1); + + ASSERT_CT((BOOT_CPU_SYSTEM_SPEED_KHZ + ((BOOT_CPU_XTAL_SPEED_KHZ+1)/2)) / \ + BOOT_CPU_XTAL_SPEED_KHZ <= 32); + + /* calculate MSEL: M = round(Fcclk / Fosc) */ + m_sel = (BOOT_CPU_SYSTEM_SPEED_KHZ + ((BOOT_CPU_XTAL_SPEED_KHZ+1)/2)) / \ + BOOT_CPU_XTAL_SPEED_KHZ; + /* value for the PLLCFG register is -1 */ + m_sel--; + + /* find PSEL value so that Fcco(= Fcclk * 2 * P) is in the 156000..320000 kHz range. */ + for (p_sel_cnt=0; p_sel_cnt= 156000) && (f_cco <= 320000) ) + { + /* found a valid pll divider value */ + break; + } + } + /* check that a valid value was found */ + ASSERT_RT(p_sel_cnt < (sizeof(pll_dividers)/sizeof(pll_dividers[0]))); + + /* set multiplier and divider values */ + PLLCFG = (p_sel_cnt << 5) | m_sel; + PLLFEED = 0xAA; + PLLFEED = 0x55; + /* enable the PLL */ + PLLCON = 0x1; + PLLFEED = 0xAA; + PLLFEED = 0x55; + /* wait for the PLL to lock to set frequency */ + while(!(PLLSTAT & 0x400)) { ; } + /* connect the PLL as the clock source */ + PLLCON = 0x3; + PLLFEED = 0xAA; + PLLFEED = 0x55; + /* enable MAM and set number of clocks used for Flash memory fetch. Recommended: + * Fcclk >= 60 MHz: 4 clock cycles + * Fcclk >= 40 MHz: 3 clock cycles + * Fcclk >= 20 MHz: 2 clock cycles + * Fcclk < 20 MHz: 1 clock cycle + */ + MAMCR = 0x0; +#if (BOOT_CPU_SYSTEM_SPEED_KHZ >= 60) + MAMTIM = 4; +#elif (BOOT_CPU_SYSTEM_SPEED_KHZ >= 40) + MAMTIM = 3; +#elif (BOOT_CPU_SYSTEM_SPEED_KHZ >= 20) + MAMTIM = 2; +#else + MAMTIM = 1; +#endif + MAMCR = 0x2; + /* setting peripheral Clock (pclk) to System Clock (cclk) */ + VPBDIV = 0x1; +#if (BOOT_COM_UART_ENABLE > 0) + /* configure P0.0 for UART0 Tx and P0.1 for UART0 Rx functionality */ + PINSEL0 |= 0x05; +#endif +#if (BOOT_COM_CAN_ENABLE > 0) + /* configure P0.25 for CAN1 Rx functionality */ + PINSEL1 |= 0x00040000L; +#endif +} /*** end of Init ***/ + + +/*********************************** end of main.c *************************************/ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/makefile b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/makefile new file mode 100644 index 00000000..40744340 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Boot/makefile @@ -0,0 +1,163 @@ +#**************************************************************************************** +#| Description: Makefile for NXP LPC2000 using CodeSourcery GNU GCC compiler toolset +#| File Name: makefile +#| +#|--------------------------------------------------------------------------------------- +#| C O P Y R I G H T +#|--------------------------------------------------------------------------------------- +#| Copyright (c) 2011 by Feaser LLC http://www.feaser.com All rights reserved +#| +#|--------------------------------------------------------------------------------------- +#| L I C E N S E +#|--------------------------------------------------------------------------------------- +#| This file is part of OpenBTL. OpenBTL 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. +#| +#| OpenBTL 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 OpenBTL. +#| If not, see . +#| +#**************************************************************************************** +SHELL = sh + +#|---------------------------------------------------------------------------------------| +#| Configure project name | +#|---------------------------------------------------------------------------------------| +PROJ_NAME=openbtl_olimex_lpc_l2294_20mhz + + +#|---------------------------------------------------------------------------------------| +#| Speficy project source files | +#|---------------------------------------------------------------------------------------| +PROJ_FILES= \ +config.h \ +hooks.c \ +main.c \ +lpc2294.h \ +../../../Source/boot.c \ +../../../Source/boot.h \ +../../../Source/com.c \ +../../../Source/com.h \ +../../../Source/xcp.c \ +../../../Source/xcp.h \ +../../../Source/backdoor.c \ +../../../Source/backdoor.h \ +../../../Source/cop.c \ +../../../Source/cop.h \ +../../../Source/assert.c \ +../../../Source/assert.h \ +../../../Source/plausibility.h \ +../../../Source/ARM7_LPC2000/types.h \ +../../../Source/ARM7_LPC2000/cpu.c \ +../../../Source/ARM7_LPC2000/cpu.h \ +../../../Source/ARM7_LPC2000/can.c \ +../../../Source/ARM7_LPC2000/can.h \ +../../../Source/ARM7_LPC2000/uart.c \ +../../../Source/ARM7_LPC2000/uart.h \ +../../../Source/ARM7_LPC2000/nvm.c \ +../../../Source/ARM7_LPC2000/nvm.h \ +../../../Source/ARM7_LPC2000/timer.c \ +../../../Source/ARM7_LPC2000/timer.h \ +../../../Source/ARM7_LPC2000/GCC/flash.c \ +../../../Source/ARM7_LPC2000/GCC/flash.h \ +../../../Source/ARM7_LPC2000/GCC/vectors.c \ +../../../Source/ARM7_LPC2000/GCC/cstart.s + + +#|---------------------------------------------------------------------------------------| +#| Compiler binaries | +#|---------------------------------------------------------------------------------------| +CC = arm-none-eabi-gcc +LN = arm-none-eabi-gcc +OC = arm-none-eabi-objcopy +OD = arm-none-eabi-objdump +AS = arm-none-eabi-as +SZ = arm-none-eabi-size + + +#|---------------------------------------------------------------------------------------| +#| Extract file names | +#|---------------------------------------------------------------------------------------| +PROJ_ASRCS = $(filter %.s,$(foreach file,$(PROJ_FILES),$(notdir $(file)))) +PROJ_CSRCS = $(filter %.c,$(foreach file,$(PROJ_FILES),$(notdir $(file)))) +PROJ_CHDRS = $(filter %.h,$(foreach file,$(PROJ_FILES),$(notdir $(file)))) +PROJ_CCMPL = $(patsubst %.c,%.cpl,$(PROJ_CSRCS)) +PROJ_ACMPL = $(patsubst %.s,%.cpl,$(PROJ_ASRCS)) + + +#|---------------------------------------------------------------------------------------| +#| Set important path variables | +#|---------------------------------------------------------------------------------------| +VPATH = $(foreach path,$(sort $(foreach file,$(PROJ_FILES),$(dir $(file)))) $(subst \,/,$(OBJ_PATH)),$(path) :) +OBJ_PATH = ./obj +BIN_PATH = ./bin +INC_PATH = $(patsubst %,-I%,$(sort $(foreach file,$(filter %.h,$(PROJ_FILES)),$(dir $(file))))) +INC_PATH += -I. +LIB_PATH = -L../../../Source/ARM7_LPC2000/GCC/ + + +#|---------------------------------------------------------------------------------------| +#| Options for compiler binaries | +#|---------------------------------------------------------------------------------------| +AFLAGS = -ahls -mapcs-32 -mcpu=arm7tdmi-s -mfpu=softfpa +CFLAGS = $(INC_PATH) -O1 -Wall -fmessage-length=0 -mcpu=arm7tdmi-s -g -mlong-calls +CFLAGS += -Wa,-adhlns="$(OBJ_PATH)/$(subst .o,.lst,$@)" +LFLAGS = $(LIB_PATH) -T"memory.x" -g -mcpu=arm7tdmi-s -nostartfiles +OCFLAGS = -O ihex +ODFLAGS = -x +SZFLAGS = -B -d + + +#|---------------------------------------------------------------------------------------| +#| Define targets | +#|---------------------------------------------------------------------------------------| +AOBJS = $(patsubst %.s,%.o,$(PROJ_ASRCS)) +COBJS = $(patsubst %.c,%.o,$(PROJ_CSRCS)) + + +#|---------------------------------------------------------------------------------------| +#| Make ALL | +#|---------------------------------------------------------------------------------------| +all : $(BIN_PATH)/$(PROJ_NAME).hex + +$(BIN_PATH)/$(PROJ_NAME).hex : $(BIN_PATH)/$(PROJ_NAME).elf + @$(OC) $(OCFLAGS) $< $@ + @$(OD) $(ODFLAGS) $< > $(BIN_PATH)/$(PROJ_NAME).map + @echo +++ Summary of memory consumption: + @$(SZ) $(SZFLAGS) $< + @echo +++ Build complete [$(notdir $@)] + +$(BIN_PATH)/$(PROJ_NAME).elf : $(AOBJS) $(COBJS) + @echo +++ Linking [$(notdir $@)] + @$(LN) $(LFLAGS) -o $@ $(patsubst %.o,$(OBJ_PATH)/%.o,$(^F)) + + +#|---------------------------------------------------------------------------------------| +#| Compile and assemble | +#|---------------------------------------------------------------------------------------| +$(AOBJS): %.o: %.s $(PROJ_CHDRS) + @echo +++ Assembling [$@] + @$(AS) $(AFLAGS) $< -o $(OBJ_PATH)/$(@F) > $(subst .o,.lst,$(OBJ_PATH)/$(@F)) + +$(COBJS): %.o: %.c $(PROJ_CHDRS) + @echo +++ Compiling [$@] + @$(CC) $(CFLAGS) -c -o $(OBJ_PATH)/$(@F) $< + +#|---------------------------------------------------------------------------------------| +#| Make CLEAN | +#|---------------------------------------------------------------------------------------| +clean : + @echo +++ Cleaning build environment + @rm -f $(foreach file,$(AOBJS),$(OBJ_PATH)/$(file)) + @rm -f $(foreach file,$(COBJS),$(OBJ_PATH)/$(file)) + @rm -f $(patsubst %.o,%.lst,$(foreach file,$(AOBJS),$(OBJ_PATH)/$(file))) + @rm -f $(patsubst %.o,%.lst,$(foreach file,$(COBJS),$(OBJ_PATH)/$(file))) + @rm -f $(BIN_PATH)/$(PROJ_NAME).hex $(BIN_PATH)/$(PROJ_NAME).map $(BIN_PATH)/$(PROJ_NAME).elf + @echo +++ Clean complete + + diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/bin/demoprog_olimex_lpc_l2294_20mhz.elf b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/bin/demoprog_olimex_lpc_l2294_20mhz.elf new file mode 100644 index 00000000..3ccf6e27 Binary files /dev/null and b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/bin/demoprog_olimex_lpc_l2294_20mhz.elf differ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/bin/demoprog_olimex_lpc_l2294_20mhz.map b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/bin/demoprog_olimex_lpc_l2294_20mhz.map new file mode 100644 index 00000000..618fbdae --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/bin/demoprog_olimex_lpc_l2294_20mhz.map @@ -0,0 +1,122 @@ + +bin/demoprog_olimex_lpc_l2294_20mhz.elf: file format elf32-littlearm +bin/demoprog_olimex_lpc_l2294_20mhz.elf +architecture: arm, flags 0x00000112: +EXEC_P, HAS_SYMS, D_PAGED +start address 0x00002000 + +Program Header: + LOAD off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**15 + filesz 0x000028e8 memsz 0x000028e8 flags r-x + LOAD off 0x00008200 vaddr 0x40000200 paddr 0x000028e8 align 2**15 + filesz 0x00000000 memsz 0x0000005c flags rw- +private flags = 5000002: [Version5 EABI] [has entry point] + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .text 000008e8 00002000 00002000 00002000 2**2 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 1 .bss 0000005c 40000200 000028e8 00008200 2**2 + ALLOC + 2 .ARM.attributes 00000030 00000000 00000000 000028e8 2**0 + CONTENTS, READONLY + 3 .comment 0000002a 00000000 00000000 00002918 2**0 + CONTENTS, READONLY + 4 .debug_abbrev 0000029c 00000000 00000000 00002942 2**0 + CONTENTS, READONLY, DEBUGGING + 5 .debug_info 000004b9 00000000 00000000 00002bde 2**0 + CONTENTS, READONLY, DEBUGGING + 6 .debug_line 00000222 00000000 00000000 00003097 2**0 + CONTENTS, READONLY, DEBUGGING + 7 .debug_loc 00000390 00000000 00000000 000032b9 2**0 + CONTENTS, READONLY, DEBUGGING + 8 .debug_pubnames 00000175 00000000 00000000 00003649 2**0 + CONTENTS, READONLY, DEBUGGING + 9 .debug_aranges 000000c0 00000000 00000000 000037be 2**0 + CONTENTS, READONLY, DEBUGGING + 10 .debug_str 000002a8 00000000 00000000 0000387e 2**0 + CONTENTS, READONLY, DEBUGGING + 11 .debug_frame 000002e0 00000000 00000000 00003b28 2**2 + CONTENTS, READONLY, DEBUGGING +SYMBOL TABLE: +00002000 l d .text 00000000 .text +40000200 l d .bss 00000000 .bss +00000000 l d .ARM.attributes 00000000 .ARM.attributes +00000000 l d .comment 00000000 .comment +00000000 l d .debug_abbrev 00000000 .debug_abbrev +00000000 l d .debug_info 00000000 .debug_info +00000000 l d .debug_line 00000000 .debug_line +00000000 l d .debug_loc 00000000 .debug_loc +00000000 l d .debug_pubnames 00000000 .debug_pubnames +00000000 l d .debug_aranges 00000000 .debug_aranges +00000000 l d .debug_str 00000000 .debug_str +00000000 l d .debug_frame 00000000 .debug_frame +00000100 l *ABS* 00000000 UND_STACK_SIZE +00000100 l *ABS* 00000000 ABT_STACK_SIZE +00000100 l *ABS* 00000000 FIQ_STACK_SIZE +00000100 l *ABS* 00000000 IRQ_STACK_SIZE +00000100 l *ABS* 00000000 SVC_STACK_SIZE +00000010 l *ABS* 00000000 MODE_USR +00000011 l *ABS* 00000000 MODE_FIQ +00000012 l *ABS* 00000000 MODE_IRQ +00000013 l *ABS* 00000000 MODE_SVC +00000017 l *ABS* 00000000 MODE_ABT +0000001b l *ABS* 00000000 MODE_UND +0000001f l *ABS* 00000000 MODE_SYS +00000080 l *ABS* 00000000 I_BIT +00000040 l *ABS* 00000000 F_BIT +00002000 l .text 00000000 _vectors +00002020 l .text 00000000 Reset_Addr +00002024 l .text 00000000 Undef_Addr +00002028 l .text 00000000 SWI_Addr +0000202c l .text 00000000 PAbt_Addr +00002030 l .text 00000000 DAbt_Addr +0000203c l .text 00000000 FIQ_Addr +00002038 l .text 00000000 IRQ_Addr +00000000 l df *ABS* 00000000 vectors.c +00000000 l df *ABS* 00000000 main.c +0000217c l F .text 000001f0 Init +000028e4 l O .text 00000004 C.0.2054 +00000000 l df *ABS* 00000000 boot.c +0000236c l F .text 0000002c BootActivate +00002538 l F .text 00000064 UartReceiveByte +40000200 l .bss 00000000 xcpCtoRxInProgress.1301 +40000204 l .bss 00000000 xcpCtoReqPacket.1299 +40000245 l .bss 00000000 xcpCtoRxLength.1300 +00000000 l df *ABS* 00000000 irq.c +40000248 l .bss 00000000 oldInterruptStatus +4000024c l .bss 00000000 interruptNesting +0000259c l F .text 00000028 IrqGetCPSR +000025c4 l F .text 00000024 IrqSetCPSR +00000000 l df *ABS* 00000000 led.c +40000250 l .bss 00000000 timer_counter_last.1292 +40000254 l .bss 00000000 led_toggle_state.1291 +00000000 l df *ABS* 00000000 timer.c +40000258 l .bss 00000000 millisecond_counter +00002868 g F .text 0000002c TimerUpdate +000025e8 g F .text 00000030 IrqInterruptEnable +000020d8 g F .text 00000044 TIMER0_ISR +000028e8 g .text 00000000 _etext +40000200 g .bss 00000000 _bss_start +00002000 g .text 00000000 _startup +4000025c g *ABS* 00000000 _bss_end +00002040 g .text 00000000 Reset_Handler +000026f4 g F .text 0000003c LedInit +00002684 g F .text 00000070 IrqInterruptRestore +0000213c g F .text 00000040 main +40003edc g *ABS* 00000000 _stack_end +00002894 g F .text 0000002c TimerSet +00002398 g F .text 000000b8 BootComInit +00002128 g F .text 00000008 FIQ_ISR +40000200 g .text 00000000 _data +00002730 g F .text 000000b4 LedToggle +40000200 g .text 00000000 _edata +4000025c g *ABS* 00000000 _end +00002130 g F .text 0000000c UNDEF_ISR +0000211c g F .text 0000000c SWI_ISR +00002618 g F .text 0000006c IrqInterruptDisable +00002450 g F .text 000000e8 BootComCheckActivationRequest +000028c0 g F .text 00000024 TimerGet +000027e4 g F .text 00000084 TimerInit + + diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/bin/demoprog_olimex_lpc_l2294_20mhz.sx b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/bin/demoprog_olimex_lpc_l2294_20mhz.sx new file mode 100644 index 00000000..a7897859 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/bin/demoprog_olimex_lpc_l2294_20mhz.sx @@ -0,0 +1,145 @@ +S029000062696E2F64656D6F70726F675F6F6C696D65785F6C70635F6C323239345F32306D687A2E7378C1 +S113200018F09FE518F09FE518F09FE518F09FE59C +S113201018F09FE50000A0E1F0FF1FE518F09FE530 +S113202040200000302100001C210000302100006D +S11320303021000000000000000000002821000002 +S113204078009FE5DBF021E300D0A0E1010C40E241 +S1132050D7F021E300D0A0E1010C40E2D1F021E36C +S113206000D0A0E1010C40E2D2F021E300D0A0E1D5 +S1132070010C40E2D3F021E300D0A0E1010C40E2E6 +S1132080DFF021E300D0A0E134109FE534209FE588 +S113209034309FE5030052E104009134040082349B +S11320A0FBFFFF3A0000A0E320109FE520209FE5FE +S11320B0020051E104008134FCFFFF3A1E0000EAF3 +S11320C0DC3E0040E828000000020040000200401E +S11320D0000200405C02004004E04EE21F582DE97B +S11320E01CB08DE224309FE50120A0E3002083E5AD +S11320F01C309FE50020A0E3002083E514309FE519 +S11321000FE0A0E113FF2FE11CD04BE21F98FDE884 +S1132110004000E030F0FFFF6828000004B02DE527 +S113212000B08DE2FEFFFFEA04B04DE2FEFFFFEADD +S113213004B02DE500B08DE2FEFFFFEA00482DE972 +S113214004B08DE20C0000EB20309FE50FE0A0E12D +S113215013FF2FE118309FE50FE0A0E113FF2FE1FB +S113216010309FE50FE0A0E113FF2FE1F8FFFFEA35 +S113217098230000302700005024000000482DE977 +S113218004B08DE210D04DE2A8319FE5003093E514 +S113219010300BE50330A0E306304BE506305BE579 +S11321A0013043E206304BE50030A0E305304BE557 +S11321B01A0000EA05205BE50B30E0E304104BE273 +S11321C0022081E0033082E00030D3E50320A0E167 +S11321D00230A0E18332A0E1033062E00331A0E1E8 +S11321E0023083E00322A0E1022063E00233A0E195 +S11321F00C300BE50C201BE53C319FE5030052E15C +S11322000300009A0C201BE530319FE5030052E1E6 +S11322100600009A05305BE5013083E205304BE5AA +S113222005305BE5030053E3E1FFFF9A000000EA99 +S11322300000A0E108319FE505205BE58222A0E1D2 +S1132240FF1002E206205BE5022081E1FF2002E2AA +S1132250FF2002E20020C3E5E8309FE55520E0E3DB +S11322600020C3E5DC309FE55520A0E30020C3E552 +S1132270D4309FE50120A0E30020C3E5C4309FE5EE +S11322805520E0E30020C3E5B8309FE55520A0E3E6 +S11322900020C3E50000A0E1B0309FE5B030D3E1F9 +S11322A00338A0E12338A0E1013B03E2000053E33B +S11322B0F8FFFF0A90309FE50320A0E30020C3E568 +S11322C080309FE55520E0E30020C3E574309FE5AE +S11322D05520A0E30020C3E574309FE50020A0E36F +S11322E00020C3E56C309FE50420A0E30020C3E593 +S11322F05C309FE50220A0E30020C3E558309FE551 +S11323000120A0E30020C3E550309FE50FE0A0E1E9 +S113231013FF2FE148309FE50FE0A0E113FF2FE109 +S113232040309FE50FE0A0E113FF2FE104D04BE222 +S11323300048BDE81EFF2FE1E42800005F610200B1 +S113234000E2040084C01FE08CC01FE080C01FE0D6 +S113235088C01FE000C01FE004C01FE000C11FE0F0 +S1132360F4260000E4270000E825000000482DE9D9 +S113237004B08DE208D04DE24030A0E308300BE514 +S113238008301BE50FE0A0E113FF2FE104D04BE27E +S11323900048BDE81EFF2FE104B02DE500B08DE23A +S11323A00CD04DE28C309FE588209FE5002092E51B +S11323B0052082E3002083E57C309FE50020A0E334 +S11323C00020C3E574309FE50020A0E30020C3E5AE +S11323D06C309FE50020A0E30020C3E564309FE556 +S11323E07F20E0E30020C3E54130A0E308300BE5A3 +S11323F054309FE508201BE5FF2002E20020C3E5DE +S113240034309FE508201BE52224A0E1FF2002E2EE +S11324100020C3E52C309FE50320A0E30020C3E5A2 +S113242018309FE50720A0E30020C3E500D08BE22D +S113243004B09DE41EFF2FE100C002E004C000E0F0 +S113244008C000E014C000E00CC000E000C000E0E0 +S113245000482DE904B08DE2CC309FE50030D3E58F +S1132460000053E30B00001AC0009FE5310000EBAD +S11324700030A0E1010053E32800001AA8309FE5D2 +S11324800120A0E30020C3E5A4309FE50020A0E3E1 +S11324900020C3E5210000EA94309FE50030D3E535 +S11324A0012083E284309FE5033082E00300A0E151 +S11324B0200000EB0030A0E1010053E31700001AF4 +S11324C06C309FE50030D3E5013083E2FF2003E266 +S11324D05C309FE50020C3E550309FE50020D3E544 +S11324E04C309FE50030D3E5030052E10B00001AA5 +S11324F034309FE50020A0E30020C3E52C309FE5A5 +S11325000130D3E5FF0053E30400001A1C309FE5BB +S11325100230D3E5000053E30000001A92FFFFEB02 +S113252004D04BE20048BDE81EFF2FE1000200404A +S1132530040200404502004004B02DE500B08DE2E5 +S11325400CD04DE208000BE544309FE50030D3E5A4 +S1132550FF3003E2013003E2FF3003E2000053E303 +S11325600600000A2C309FE50030D3E5FF2003E28B +S113257008301BE50020C3E50130A0E3000000EAB9 +S11325800030A0E30300A0E100D08BE204B09DE49E +S11325901EFF2FE114C000E000C000E010082DE988 +S11325A004B08DE208D04DE200400FE108400BE595 +S11325B008301BE50300A0E104D04BE21008BDE89D +S11325C01EFF2FE104B02DE500B08DE20CD04DE2EA +S11325D008000BE508301BE503F029E100D08BE28D +S11325E004B09DE41EFF2FE100482DE904B08DE204 +S11325F008D04DE2E8FFFFEB08000BE508301BE5CF +S11326008030C3E30300A0E1EDFFFFEB04D04BE215 +S11326100048BDE81EFF2FE100482DE904B08DE21B +S113262008D04DE250309FE50030D3E5000053E37D +S11326300800001AD8FFFFEB08000BE508301BE583 +S1132640803083E30300A0E1DDFFFFEB2C309FE546 +S113265008201BE5002083E51C309FE50030D3E50E +S1132660013083E2FF2003E20C309FE50020C3E544 +S113267004D04BE20048BDE81EFF2FE14C020040AD +S11326804802004000482DE904B08DE208D04DE234 +S113269054309FE50030D3E5013043E2FF2003E2EC +S11326A044309FE50020C3E53C309FE50030D3E58E +S11326B0000053E30900001AB7FFFFEB08000BE525 +S11326C008301BE58020C3E320309FE5003093E50C +S11326D0803003E2033082E10300A0E1B8FFFFEBA6 +S11326E004D04BE20048BDE81EFF2FE14C0200403D +S11326F04802004004B02DE500B08DE224309FE58F +S113270020209FE5002092E5022582E3002083E556 +S113271014309FE50225A0E3002083E500D08BE27E +S113272004B09DE41EFF2FE1188002E0148002E053 +S113273000482DE904B08DE208D04DE288309FE5D1 +S11327400FE0A0E113FF2FE108000BE57C309FE5CB +S1132750003093E508201BE5022063E070309FE51C +S1132760030052E11400009A68309FE50030D3E57D +S1132770000053E30600001A58309FE50120A0E34F +S11327800020C3E550309FE50225A0E3002083E547 +S1132790050000EA3C309FE50020A0E30020C3E5EB +S11327A038309FE50225A0E3002083E51C309FE537 +S11327B008201BE5002083E5000000EA0000A0E1FA +S11327C004D04BE20048BDE81EFF2FE1C028000002 +S11327D050020040F3010000540200401C8002E05B +S11327E0148002E000482DE904B08DE254309FE5E6 +S11327F054209FE5002083E550309FE50320A0E3AB +S1132800002083E548309FE50120A0E3002083E514 +S113281040309FE540209FE5002083E53C309FE564 +S11328202420A0E3002083E534309FE51020A0E3BA +S1132830002083E50000A0E3150000EB04D04BE288 +S11328400048BDE81EFF2FE1184000E05FEA0000E9 +S1132850144000E0044000E000F1FFFFD820000035 +S113286000F2FFFF10F0FFFF04B02DE500B08DE291 +S113287018309FE5003093E5012083E20C309FE59A +S1132880002083E500D08BE204B09DE41EFF2FE11D +S11328905802004004B02DE500B08DE20CD04DE2AA +S11328A008000BE510309FE508201BE5002083E5B8 +S11328B000D08BE204B09DE41EFF2FE158020040DB +S11328C004B02DE500B08DE210309FE5003093E5B3 +S11328D00300A0E100D08BE204B09DE41EFF2FE1D1 +S10B28E0580200400102040843 +S9032000DC diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/boot.c b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/boot.c new file mode 100644 index 00000000..b375cc13 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/boot.c @@ -0,0 +1,353 @@ +/**************************************************************************************** +| Description: demo program bootloader interface source file +| File Name: boot.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "header.h" /* generic header */ + + +/**************************************************************************************** +** NAME: BootActivate +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Bootloader activation function. +** +****************************************************************************************/ +static void BootActivate(void) +{ + void (*pEntryFromProgFnc)(void); + + /* set pointer to the address of function EntryFromProg in the bootloader */ + pEntryFromProgFnc = (void*)0x00000040; + /* call EntryFromProg to activate the bootloader. */ + pEntryFromProgFnc(); +} /*** end of BootActivate ***/ + + +#if (BOOT_COM_UART_ENABLE > 0) +/**************************************************************************************** +* U N I V E R S A L A S Y N C H R O N O U S R X T X I N T E R F A C E +****************************************************************************************/ + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +#define UART_DLAB (0x80) /* divisor latch access bit */ +#define UART_MODE_8N1 (0x03) /* 8 data and 1 stop bit, no parity */ +#define UART_FIFO_RX1 (0x07) /* FIFO reset and RX FIFO 1 deep */ +#define UART_RDR (0x01) /* receiver data ready */ + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +static unsigned char UartReceiveByte(unsigned char *data); + + +/**************************************************************************************** +** NAME: BootComInit +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Initializes the UART communication interface +** +****************************************************************************************/ +void BootComInit(void) +{ + unsigned long baud_reg_value; /* baudrate register value */ + + /* configure P0.0 for UART0 Tx and P0.1 for UART0 Rx functionality */ + PINSEL0 |= 0x05; + /* disable UART related interrupt generation. this driver works in polling mode */ + U0IER = 0; + /* clear interrupt id register */ + U0IIR = 0; + /* clear line status register */ + U0LSR = 0; + /* set divisor latch DLAB = 1 so buadrate can be configured */ + U0LCR = UART_DLAB; + /* Baudrate calculation: + * y = BOOT_CPU_SYSTEM_SPEED_KHZ * 1000 / 16 / BOOT_COM_UART_BAUDRATE and add + * smartness to automatically round the value up/down using the following trick: + * y = x/n can round with y = (x + (n + 1)/2 ) / n + */ + baud_reg_value = (((BOOT_CPU_SYSTEM_SPEED_KHZ*1000/16)+ \ + ((BOOT_COM_UART_BAUDRATE+1)/2))/BOOT_COM_UART_BAUDRATE); + /* write the calculated baudrate selector value to the registers */ + U0DLL = (unsigned char)baud_reg_value; + U0DLM = (unsigned char)(baud_reg_value >> 8); + /* configure 8 data bits, no parity and 1 stop bit and set DLAB = 0 */ + U0LCR = UART_MODE_8N1; + /* enable and reset transmit and receive FIFO. necessary for UART operation */ + U0FCR = UART_FIFO_RX1; +} /*** end of BootComInit ***/ + + +/**************************************************************************************** +** NAME: BootComCheckActivationRequest +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Receives the CONNECT request from the host, which indicates that the +** bootloader should be activated and, if so, activates it. +** +****************************************************************************************/ +void BootComCheckActivationRequest(void) +{ + static unsigned char xcpCtoReqPacket[BOOT_COM_UART_RX_MAX_DATA+1]; + static unsigned char xcpCtoRxLength; + static unsigned char xcpCtoRxInProgress = 0; + + /* start of cto packet received? */ + if (xcpCtoRxInProgress == 0) + { + /* store the message length when received */ + if (UartReceiveByte(&xcpCtoReqPacket[0]) == 1) + { + /* indicate that a cto packet is being received */ + xcpCtoRxInProgress = 1; + + /* reset packet data count */ + xcpCtoRxLength = 0; + } + } + else + { + /* store the next packet byte */ + if (UartReceiveByte(&xcpCtoReqPacket[xcpCtoRxLength+1]) == 1) + { + /* increment the packet data count */ + xcpCtoRxLength++; + + /* check to see if the entire packet was received */ + if (xcpCtoRxLength == xcpCtoReqPacket[0]) + { + /* done with cto packet reception */ + xcpCtoRxInProgress = 0; + + /* check if this was an XCP CONNECT command */ + if ((xcpCtoReqPacket[1] == 0xff) && (xcpCtoReqPacket[2] == 0x00)) + { + /* connection request received so start the bootloader */ + BootActivate(); + } + } + } + } +} /*** end of BootComCheckActivationRequest ***/ + + +/**************************************************************************************** +** NAME: UartReceiveByte +** PARAMETER: data pointer to byte where the data is to be stored. +** RETURN VALUE: 1 if a byte was received, 0 otherwise. +** DESCRIPTION: Receives a communication interface byte if one is present. +** +****************************************************************************************/ +static unsigned char UartReceiveByte(unsigned char *data) +{ + /* check if a new byte was received by means of the RDR-bit */ + if((U0LSR & UART_RDR) != 0) + { + /* store the received byte */ + data[0] = U0RBR; + /* inform caller of the newly received byte */ + return 1; + } + /* inform caller that no new data was received */ + return 0; +} /*** end of UartReceiveByte ***/ +#endif /* BOOT_COM_UART_ENABLE > 0 */ + + +#if (BOOT_COM_CAN_ENABLE > 0) +/**************************************************************************************** +* C O N T R O L L E R A R E A N E T W O R K I N T E R F A C E +****************************************************************************************/ + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +#define CAN_TBS1 (0x00000004) /* transmit buffer 1 idle */ +#define CAN_TCS1 (0x00000008) /* transmit buffer 1 complete */ +#define CAN_RRB (0x04) /* receive buffer release */ +#define CAN_RBS (0x01) /* receive buffer status */ +#define CAN_TR (0x01) /* transmission request */ +#define CAN_STB1 (0x20) /* select tx buffer 1 for transmit */ + + +/**************************************************************************************** +* Type definitions +****************************************************************************************/ +typedef struct t_can_bus_timing +{ + unsigned char tseg1; /* CAN time segment 1 */ + unsigned char tseg2; /* CAN time segment 2 */ +} tCanBusTiming; /* bus timing structure type */ + + +/**************************************************************************************** +* Local constant declarations +****************************************************************************************/ +/* According to the CAN protocol 1 bit-time can be made up of between 8..25 time quanta + * (TQ). The total TQ in a bit is SYNC + TSEG1 + TSEG2 with SYNC always being 1. + * The sample point is (SYNC + TSEG1) / (SYNC + TSEG1 + SEG2) * 100%. This array contains + * possible and valid time quanta configurations with a sample point between 68..78%. + */ +static const tCanBusTiming canTiming[] = +{ /* TQ | TSEG1 | TSEG2 | SP */ + /* ------------------------- */ + { 5, 2 }, /* 8 | 5 | 2 | 75% */ + { 6, 2 }, /* 9 | 6 | 2 | 78% */ + { 6, 3 }, /* 10 | 6 | 3 | 70% */ + { 7, 3 }, /* 11 | 7 | 3 | 73% */ + { 8, 3 }, /* 12 | 8 | 3 | 75% */ + { 9, 3 }, /* 13 | 9 | 3 | 77% */ + { 9, 4 }, /* 14 | 9 | 4 | 71% */ + { 10, 4 }, /* 15 | 10 | 4 | 73% */ + { 11, 4 }, /* 16 | 11 | 4 | 75% */ + { 12, 4 }, /* 17 | 12 | 4 | 76% */ + { 12, 5 }, /* 18 | 12 | 5 | 72% */ + { 13, 5 }, /* 19 | 13 | 5 | 74% */ + { 14, 5 }, /* 20 | 14 | 5 | 75% */ + { 15, 5 }, /* 21 | 15 | 5 | 76% */ + { 15, 6 }, /* 22 | 15 | 6 | 73% */ + { 16, 6 }, /* 23 | 16 | 6 | 74% */ + { 16, 7 }, /* 24 | 16 | 7 | 71% */ + { 16, 8 } /* 25 | 16 | 8 | 68% */ +}; + + +/**************************************************************************************** +** NAME: CanGetSpeedConfig +** PARAMETER: baud The desired baudrate in kbps. Valid values are 10..1000. +** btr Pointer to where the value for register CANxBTR will be stored. +** RETURN VALUE: 1 if the CAN bustiming register values were found, 0 otherwise. +** DESCRIPTION: Search algorithm to match the desired baudrate to a possible bus +** timing configuration. +** +****************************************************************************************/ +static unsigned char CanGetSpeedConfig(unsigned short baud, unsigned long *btr) +{ + unsigned short prescaler; + unsigned char cnt; + + /* loop through all possible time quanta configurations to find a match */ + for (cnt=0; cnt < sizeof(canTiming)/sizeof(canTiming[0]); cnt++) + { + if ((BOOT_CPU_SYSTEM_SPEED_KHZ % (baud*(canTiming[cnt].tseg1+canTiming[cnt].tseg2+1))) == 0) + { + /* compute the prescaler that goes with this TQ configuration */ + prescaler = BOOT_CPU_SYSTEM_SPEED_KHZ/(baud*(canTiming[cnt].tseg1+canTiming[cnt].tseg2+1)); + + /* make sure the prescaler is valid */ + if ( (prescaler > 0) && (prescaler <= 1024) ) + { + /* store the prescaler and bustiming register value */ + *btr = prescaler - 1; + *btr |= ((canTiming[cnt].tseg2 - 1) << 20) | ((canTiming[cnt].tseg1 - 1) << 16); + /* found a good bus timing configuration */ + return 1; + } + } + } + /* could not find a good bus timing configuration */ + return 0; +} /*** end of CanGetSpeedConfig ***/ + + +/**************************************************************************************** +** NAME: BootComInit +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Initializes the CAN communication interface +** +****************************************************************************************/ +void BootComInit(void) +{ + unsigned long btr_reg_value; + + /* configure acceptance filter for bypass mode so it receives all messages */ + CANAFMR = 0x00000002L; + /* take CAN controller offline and go into reset mode */ + CAN1MOD = 1; + /* disable all interrupts. driver only needs to work in polling mode */ + CAN1IER = 0; + /* reset CAN controller status */ + CAN1GSR = 0; + /* configure the bittiming */ + if (CanGetSpeedConfig(BOOT_COM_CAN_BAUDRATE/1000, &btr_reg_value) == 1) + { + /* write the bittiming configuration to the register */ + CAN1BTR = btr_reg_value; + } + /* enter normal operating mode and synchronize to the CAN bus */ + CAN1MOD = 0; +} /*** end of BootComInit ***/ + + +/**************************************************************************************** +** NAME: BootComCheckActivationRequest +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Receives the CONNECT request from the host, which indicates that the +** bootloader should be activated and, if so, activates it. +** +****************************************************************************************/ +void BootComCheckActivationRequest(void) +{ + unsigned char data[2]; + + /* check if a new message was received */ + if ((CAN1SR & CAN_RBS) == 0) + { + return; + } + /* see if this is the message identifier that we are interested in */ + if (CAN1RID != BOOT_COM_CAN_RX_MSG_ID) + { + return; + } + /* store the message data */ + data[0] = (unsigned char)CAN1RDA; + data[1] = (unsigned char)(CAN1RDA >> 8); + /* release the receive buffer */ + CAN1CMR = CAN_RRB; + /* check if this was an XCP CONNECT command */ + if ((data[0] == 0xff) && (data[1] == 0x00)) + { + /* connection request received so start the bootloader */ + BootActivate(); + } +} /*** end of BootComCheckActivationRequest ***/ +#endif /* BOOT_COM_CAN_ENABLE > 0 */ + + +/*********************************** end of boot.c *************************************/ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/boot.h b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/boot.h new file mode 100644 index 00000000..92789052 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/boot.h @@ -0,0 +1,42 @@ +/**************************************************************************************** +| Description: demo program bootloader interface header file +| File Name: boot.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef BOOT_H +#define BOOT_H + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void BootComInit(void); +void BootComCheckActivationRequest(void); + + +#endif /* BOOT_H */ +/*********************************** end of boot.h *************************************/ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/cmd/build.bat b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/cmd/build.bat new file mode 100644 index 00000000..44c0c1b8 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/cmd/build.bat @@ -0,0 +1,2 @@ +@echo off +make --directory=../ all diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/cmd/clean.bat b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/cmd/clean.bat new file mode 100644 index 00000000..32c4b5f2 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/cmd/clean.bat @@ -0,0 +1,2 @@ +@echo off +make --directory=../ clean diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/cstart.s b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/cstart.s new file mode 100644 index 00000000..dd3af60a --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/cstart.s @@ -0,0 +1,136 @@ +/**************************************************************************************** +| Description: demo program C-startup assembly file +| File Name: cstart.s +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +/* stack Sizes */ +.set UND_STACK_SIZE, 0x00000100 /* stack for "undef" interrupts is 4 bytes */ +.set ABT_STACK_SIZE, 0x00000100 /* stack for "abort" interrupts is 4 bytes */ +.set FIQ_STACK_SIZE, 0x00000100 /* stack for "FIQ" interrupts is 4 bytes */ +.set IRQ_STACK_SIZE, 0X00000100 /* stack for "IRQ" normal interrupts is 4 bytes */ +.set SVC_STACK_SIZE, 0x00000100 /* stack for "SVC" supervisor mode is 4 bytes */ + +/* mode bits and Interrupt (I & F) flags in program status registers (PSRs) */ +.set MODE_USR, 0x10 /* Normal User Mode */ +.set MODE_FIQ, 0x11 /* FIQ Processing Fast Interrupts Mode */ +.set MODE_IRQ, 0x12 /* IRQ Processing Standard Interrupts Mode */ +.set MODE_SVC, 0x13 /* Supervisor Processing Software Interrupts Mode */ +.set MODE_ABT, 0x17 /* Abort Processing memory Faults Mode */ +.set MODE_UND, 0x1B /* Undefined Processing Undefined Instructions Mode */ +.set MODE_SYS, 0x1F /* System Running Priviledged OS Tasks Mode */ +.set I_BIT, 0x80 /* when I bit is set, IRQ is disabled */ +.set F_BIT, 0x40 /* when F bit is set, FIQ is disabled */ + + +.text +.arm + +.global Reset_Handler +.global _startup +.func _startup + +_startup: +/**************************************************************************************** +* Interrupt vector table +****************************************************************************************/ +_vectors: ldr PC, Reset_Addr /* point to Reset_Handler address */ + ldr PC, Undef_Addr /* point to UNDEF_ISR address */ + ldr PC, SWI_Addr /* point to SWI_ISR address */ + ldr PC, PAbt_Addr /* point to UNDEF_ISR address */ + ldr PC, DAbt_Addr /* point to UNDEF_ISR address */ + nop /* reserved for OpenBLT checksum */ + ldr PC, [PC,#-0xFF0] /* point to VIC table */ + ldr PC, FIQ_Addr /* point to FIQ_ISR address */ + +Reset_Addr: .word Reset_Handler /* defined in this module below */ +Undef_Addr: .word UNDEF_ISR /* defined in vectors.c */ +SWI_Addr: .word SWI_ISR /* defined in vectors.c */ +PAbt_Addr: .word UNDEF_ISR /* defined in vectors.c */ +DAbt_Addr: .word UNDEF_ISR /* defined in vectors.c */ + .word 0 +IRQ_Addr: .word 0 +FIQ_Addr: .word FIQ_ISR /* defined in vectors.c */ + + +/**************************************************************************************** +** NAME: Reset_Handler +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Reset interrupt service routine. Configures the stack for each mode, +** disables the IRQ and FIQ interrupts, initializes RAM and jumps to +** function main. +** +****************************************************************************************/ +Reset_Handler: + /* setup a stack and disable interrupts for each mode */ + ldr r0, =_stack_end + msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */ + mov sp, r0 + sub r0, r0, #UND_STACK_SIZE + msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */ + mov sp, r0 + sub r0, r0, #ABT_STACK_SIZE + msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */ + mov sp, r0 + sub r0, r0, #FIQ_STACK_SIZE + msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */ + mov sp, r0 + sub r0, r0, #IRQ_STACK_SIZE + msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */ + mov sp, r0 + sub r0, r0, #SVC_STACK_SIZE + msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* User Mode */ + mov sp, r0 + /* copy .data section (Copy from ROM to RAM) */ + ldr R1, =_etext + ldr R2, =_data + ldr R3, =_edata +1: cmp R2, R3 + ldrlo R0, [R1], #4 + strlo R0, [R2], #4 + blo 1b + /* clear .bss section (Zero init) */ + mov R0, #0 + ldr R1, =_bss_start + ldr R2, =_bss_end +2: cmp R1, R2 + strlo R0, [R1], #4 + blo 2b + /* start bootloader program by jumping to main() */ + b main +/*** end of Reset_Handler ***/ +.endfunc + + +.end +/*********************************** end of cstart.s ***********************************/ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/header.h b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/header.h new file mode 100644 index 00000000..1a21e96e --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/header.h @@ -0,0 +1,46 @@ +/**************************************************************************************** +| Description: generic header file +| File Name: header.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef HEADER_H +#define HEADER_H + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "../Boot/config.h" /* bootloader configuration */ +#include "lpc2294.h" /* CPU register definitions */ +#include "boot.h" /* bootloader interface driver */ +#include "irq.h" /* IRQ driver */ +#include "led.h" /* LED driver */ +#include "timer.h" /* Timer driver */ + + +#endif /* HEADER_H */ +/*********************************** end of header.h ***********************************/ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/ide/DemoProg.project b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/ide/DemoProg.project new file mode 100644 index 00000000..6d9b215c --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/ide/DemoProg.project @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + break main +continue + + + + + + + make clean + make + + + + None + $(WorkspacePath)/.. + + + + + + + + + + + + + + + + + + + + + + + make clean + make + + + + None + $(WorkspacePath) + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/ide/DemoProg.workspace b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/ide/DemoProg.workspace new file mode 100644 index 00000000..4060139b --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/ide/DemoProg.workspace @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/ide/readme.txt b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/ide/readme.txt new file mode 100644 index 00000000..8a340a19 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/ide/readme.txt @@ -0,0 +1,4 @@ +Integrated Development Environment +---------------------------------- +Codelite was used as the editor during the development of this software program. This directory contains the Codelite +workspace and project files. Codelite is a cross platform open source C/C++ IDE, available at http://www.codelite.org/. \ No newline at end of file diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/irq.c b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/irq.c new file mode 100644 index 00000000..ceec7732 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/irq.c @@ -0,0 +1,140 @@ +/**************************************************************************************** +| Description: IRQ driver source file +| File Name: irq.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "header.h" /* generic header */ + + +/**************************************************************************************** +* Local data definitions +****************************************************************************************/ +static unsigned long oldInterruptStatus; /* used for global interrupt en/disable */ +static unsigned char interruptNesting = 0; /* used for global interrupt en/disable */ + + +/**************************************************************************************** +** NAME: IrqGetCPSR +** PARAMETER: none +** RETURN VALUE: CPSR value +** DESCRIPTION: Obtains current value of CPSR CPU register. +** NOTE: Derived from a sample by R O Software that is Copyright 2004, +** R O SoftWare, and can be used for hobby or commercial purposes. +** +****************************************************************************************/ +static unsigned long IrqGetCPSR(void) +{ + unsigned long retval; + asm volatile (" mrs %0, cpsr" : "=r" (retval) : /* no inputs */ ); + return retval; +} /*** end of IrqGetCPSR ***/ + + +/**************************************************************************************** +** NAME: IrqSetCPSR +** PARAMETER: CPSR value +** RETURN VALUE: none +** DESCRIPTION: Update value of CPSR CPU register. +** NOTE: Derived from a sample by R O Software that is Copyright 2004, +** R O SoftWare, and can be used for hobby or commercial purposes. +** +****************************************************************************************/ +static void IrqSetCPSR(unsigned long val) +{ + asm volatile (" msr cpsr, %0" : /* no outputs */ : "r" (val) ); +} /*** end of IrqSetCPSR ***/ + + +/**************************************************************************************** +** NAME: IrqInterruptEnable +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Enables the generation IRQ interrupts. Typically called once during +** software startup after completion of the initialization. +** +****************************************************************************************/ +void IrqInterruptEnable(void) +{ + unsigned _cpsr; + + _cpsr = IrqGetCPSR(); + IrqSetCPSR(_cpsr & ~0x00000080); +} /*** end of IrqInterruptEnable ***/ + + +/**************************************************************************************** +** NAME: HwInterruptDisable +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Disables the generation IRQ interrupts and stores information on +** whether or not the interrupts were already disabled before explicitly +** disabling them with this function. Normally used as a pair together +** with IrqInterruptRestore during a critical section. +** +****************************************************************************************/ +void IrqInterruptDisable(void) +{ + unsigned long _cpsr; + + if (interruptNesting == 0) + { + _cpsr = IrqGetCPSR(); + IrqSetCPSR(_cpsr | 0x00000080); + oldInterruptStatus = _cpsr; + } + interruptNesting++; +} /*** end of IrqInterruptDisable ***/ + + +/**************************************************************************************** +** NAME: IrqInterruptRestore +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Restore the generation IRQ interrupts to the setting it had prior to +** calling IrqInterruptDisable. Normally used as a pair together with +** IrqInterruptDisable during a critical section. +** +****************************************************************************************/ +void IrqInterruptRestore(void) +{ + unsigned _cpsr; + + interruptNesting--; + if (interruptNesting == 0) + { + _cpsr = IrqGetCPSR(); + IrqSetCPSR((_cpsr & ~0x00000080) | (oldInterruptStatus & 0x00000080)); + } +} /*** end of IrqInterruptRestore ***/ + + +/*********************************** end of irq.c **************************************/ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/irq.h b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/irq.h new file mode 100644 index 00000000..9f12faf4 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/irq.h @@ -0,0 +1,43 @@ +/**************************************************************************************** +| Description: IRQ driver header file +| File Name: irq.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef IRQ_H +#define IRQ_H + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void IrqInterruptEnable(void); +void IrqInterruptDisable(void); +void IrqInterruptRestore(void); + + +#endif /* IRQ_H */ +/*********************************** end of irq.h **************************************/ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/led.c b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/led.c new file mode 100644 index 00000000..7e579999 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/led.c @@ -0,0 +1,100 @@ +/**************************************************************************************** +| Description: LED driver source file +| File Name: led.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "header.h" /* generic header */ + + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +#define LED_TOGGLE_MS (500) /* toggle interval time in millisecodns */ + + +/**************************************************************************************** +** NAME: LedInit +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Initializes the LED. +** +****************************************************************************************/ +void LedInit(void) +{ + /* set io pins for led P1.23 */ + IO1DIR |= 0x00800000; + /* turn the led off */ + IO1SET = 0x00800000; +} /*** end of LedInit ***/ + + +/**************************************************************************************** +** NAME: LedToggle +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Toggles the LED at a fixed time interval. +** +****************************************************************************************/ +void LedToggle(void) +{ + static unsigned char led_toggle_state = 0; + static unsigned long timer_counter_last = 0; + unsigned long timer_counter_now; + + /* check if toggle interval time passed */ + timer_counter_now = TimerGet(); + if ( (timer_counter_now - timer_counter_last) < LED_TOGGLE_MS) + { + /* not yet time to toggle */ + return; + } + + /* determine toggle action */ + if (led_toggle_state == 0) + { + led_toggle_state = 1; + /* turn the LED on */ + IO1CLR = 0x00800000; + } + else + { + led_toggle_state = 0; + /* turn the LED off */ + IO1SET = 0x00800000; + } + + /* store toggle time to determine next toggle interval */ + timer_counter_last = timer_counter_now; +} /*** end of LedToggle ***/ + + +/*********************************** end of led.c **************************************/ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/led.h b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/led.h new file mode 100644 index 00000000..f69b6a44 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/led.h @@ -0,0 +1,42 @@ +/**************************************************************************************** +| Description: LED driver header file +| File Name: led.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef LED_H +#define LED_H + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void LedInit(void); +void LedToggle(void); + + +#endif /* LED_H */ +/*********************************** end of led.h **************************************/ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/lpc2294.h b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/lpc2294.h new file mode 100644 index 00000000..209015fb --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/lpc2294.h @@ -0,0 +1,409 @@ +/**************************************************************************************** +| Description: NXP LPC2294 register definitions +| File Name: lpc2294.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef LPC2294_H +#define LPC2294_H + + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +/* EXTERNAL MEMORY CONTROLLER (EMC) */ +#define BCFG0 (*((volatile unsigned long *) 0xFFE00000)) /* lpc22xx only */ +#define BCFG1 (*((volatile unsigned long *) 0xFFE00004)) /* lpc22xx only */ +#define BCFG2 (*((volatile unsigned long *) 0xFFE00008)) /* lpc22xx only */ +#define BCFG3 (*((volatile unsigned long *) 0xFFE0000C)) /* lpc22xx only */ + +/* External Interrupts */ +#define EXTINT (*((volatile unsigned char *) 0xE01FC140)) +#define EXTWAKE (*((volatile unsigned char *) 0xE01FC144)) +#define EXTMODE (*((volatile unsigned char *) 0xE01FC148)) /* no in lpc210x*/ +#define EXTPOLAR (*((volatile unsigned char *) 0xE01FC14C)) /* no in lpc210x*/ + +/* SMemory mapping control. */ +#define MEMMAP (*((volatile unsigned long *) 0xE01FC040)) + +/* Phase Locked Loop (PLL) */ +#define PLLCON (*((volatile unsigned char *) 0xE01FC080)) +#define PLLCFG (*((volatile unsigned char *) 0xE01FC084)) +#define PLLSTAT (*((volatile unsigned short*) 0xE01FC088)) +#define PLLFEED (*((volatile unsigned char *) 0xE01FC08C)) + +/* Power Control */ +#define PCON (*((volatile unsigned char *) 0xE01FC0C0)) +#define PCONP (*((volatile unsigned long *) 0xE01FC0C4)) + +/* VPB Divider */ +#define VPBDIV (*((volatile unsigned char *) 0xE01FC100)) + +/* Memory Accelerator Module (MAM) */ +#define MAMCR (*((volatile unsigned char *) 0xE01FC000)) +#define MAMTIM (*((volatile unsigned char *) 0xE01FC004)) + +/* Vectored Interrupt Controller (VIC) */ +#define VICIRQStatus (*((volatile unsigned long *) 0xFFFFF000)) +#define VICFIQStatus (*((volatile unsigned long *) 0xFFFFF004)) +#define VICRawIntr (*((volatile unsigned long *) 0xFFFFF008)) +#define VICIntSelect (*((volatile unsigned long *) 0xFFFFF00C)) +#define VICIntEnable (*((volatile unsigned long *) 0xFFFFF010)) +#define VICIntEnClr (*((volatile unsigned long *) 0xFFFFF014)) +#define VICSoftInt (*((volatile unsigned long *) 0xFFFFF018)) +#define VICSoftIntClear (*((volatile unsigned long *) 0xFFFFF01C)) +#define VICProtection (*((volatile unsigned long *) 0xFFFFF020)) +#define VICVectAddr (*((volatile unsigned long *) 0xFFFFF030)) +#define VICDefVectAddr (*((volatile unsigned long *) 0xFFFFF034)) +#define VICVectAddr0 (*((volatile unsigned long *) 0xFFFFF100)) +#define VICVectAddr1 (*((volatile unsigned long *) 0xFFFFF104)) +#define VICVectAddr2 (*((volatile unsigned long *) 0xFFFFF108)) +#define VICVectAddr3 (*((volatile unsigned long *) 0xFFFFF10C)) +#define VICVectAddr4 (*((volatile unsigned long *) 0xFFFFF110)) +#define VICVectAddr5 (*((volatile unsigned long *) 0xFFFFF114)) +#define VICVectAddr6 (*((volatile unsigned long *) 0xFFFFF118)) +#define VICVectAddr7 (*((volatile unsigned long *) 0xFFFFF11C)) +#define VICVectAddr8 (*((volatile unsigned long *) 0xFFFFF120)) +#define VICVectAddr9 (*((volatile unsigned long *) 0xFFFFF124)) +#define VICVectAddr10 (*((volatile unsigned long *) 0xFFFFF128)) +#define VICVectAddr11 (*((volatile unsigned long *) 0xFFFFF12C)) +#define VICVectAddr12 (*((volatile unsigned long *) 0xFFFFF130)) +#define VICVectAddr13 (*((volatile unsigned long *) 0xFFFFF134)) +#define VICVectAddr14 (*((volatile unsigned long *) 0xFFFFF138)) +#define VICVectAddr15 (*((volatile unsigned long *) 0xFFFFF13C)) +#define VICVectCntl0 (*((volatile unsigned long *) 0xFFFFF200)) +#define VICVectCntl1 (*((volatile unsigned long *) 0xFFFFF204)) +#define VICVectCntl2 (*((volatile unsigned long *) 0xFFFFF208)) +#define VICVectCntl3 (*((volatile unsigned long *) 0xFFFFF20C)) +#define VICVectCntl4 (*((volatile unsigned long *) 0xFFFFF210)) +#define VICVectCntl5 (*((volatile unsigned long *) 0xFFFFF214)) +#define VICVectCntl6 (*((volatile unsigned long *) 0xFFFFF218)) +#define VICVectCntl7 (*((volatile unsigned long *) 0xFFFFF21C)) +#define VICVectCntl8 (*((volatile unsigned long *) 0xFFFFF220)) +#define VICVectCntl9 (*((volatile unsigned long *) 0xFFFFF224)) +#define VICVectCntl10 (*((volatile unsigned long *) 0xFFFFF228)) +#define VICVectCntl11 (*((volatile unsigned long *) 0xFFFFF22C)) +#define VICVectCntl12 (*((volatile unsigned long *) 0xFFFFF230)) +#define VICVectCntl13 (*((volatile unsigned long *) 0xFFFFF234)) +#define VICVectCntl14 (*((volatile unsigned long *) 0xFFFFF238)) +#define VICVectCntl15 (*((volatile unsigned long *) 0xFFFFF23C)) + +/* Pin Connect Block */ +#define PINSEL0 (*((volatile unsigned long *) 0xE002C000)) +#define PINSEL1 (*((volatile unsigned long *) 0xE002C004)) +#define PINSEL2 (*((volatile unsigned long *) 0xE002C014)) /* no in lpc210x*/ + +/* General Purpose Input/Output (GPIO) */ +#define IOPIN (*((volatile unsigned long *) 0xE0028000)) /* lpc210x only */ +#define IOSET (*((volatile unsigned long *) 0xE0028004)) /* lpc210x only */ +#define IODIR (*((volatile unsigned long *) 0xE0028008)) /* lpc210x only */ +#define IOCLR (*((volatile unsigned long *) 0xE002800C)) /* lpc210x only */ + +#define IO0PIN (*((volatile unsigned long *) 0xE0028000)) /* no in lpc210x*/ +#define IO0SET (*((volatile unsigned long *) 0xE0028004)) /* no in lpc210x*/ +#define IO0DIR (*((volatile unsigned long *) 0xE0028008)) /* no in lpc210x*/ +#define IO0CLR (*((volatile unsigned long *) 0xE002800C)) /* no in lpc210x*/ + +#define IO1PIN (*((volatile unsigned long *) 0xE0028010)) /* no in lpc210x*/ +#define IO1SET (*((volatile unsigned long *) 0xE0028014)) /* no in lpc210x*/ +#define IO1DIR (*((volatile unsigned long *) 0xE0028018)) /* no in lpc210x*/ +#define IO1CLR (*((volatile unsigned long *) 0xE002801C)) /* no in lpc210x*/ + +#define IO2PIN (*((volatile unsigned long *) 0xE0028020)) /* lpc22xx only */ +#define IO2SET (*((volatile unsigned long *) 0xE0028024)) /* lpc22xx only */ +#define IO2DIR (*((volatile unsigned long *) 0xE0028028)) /* lpc22xx only */ +#define IO2CLR (*((volatile unsigned long *) 0xE002802C)) /* lpc22xx only */ + +#define IO3PIN (*((volatile unsigned long *) 0xE0028030)) /* lpc22xx only */ +#define IO3SET (*((volatile unsigned long *) 0xE0028034)) /* lpc22xx only */ +#define IO3DIR (*((volatile unsigned long *) 0xE0028038)) /* lpc22xx only */ +#define IO3CLR (*((volatile unsigned long *) 0xE002803C)) /* lpc22xx only */ + +/* Universal Asynchronous Receiver Transmitter 0 (UART0) */ +#define U0RBR (*((volatile unsigned char *) 0xE000C000)) +#define U0THR (*((volatile unsigned char *) 0xE000C000)) +#define U0IER (*((volatile unsigned char *) 0xE000C004)) +#define U0IIR (*((volatile unsigned char *) 0xE000C008)) +#define U0FCR (*((volatile unsigned char *) 0xE000C008)) +#define U0LCR (*((volatile unsigned char *) 0xE000C00C)) +#define U0LSR (*((volatile unsigned char *) 0xE000C014)) +#define U0SCR (*((volatile unsigned char *) 0xE000C01C)) +#define U0DLL (*((volatile unsigned char *) 0xE000C000)) +#define U0DLM (*((volatile unsigned char *) 0xE000C004)) + +/* Universal Asynchronous Receiver Transmitter 1 (UART1) */ +#define U1RBR (*((volatile unsigned char *) 0xE0010000)) +#define U1THR (*((volatile unsigned char *) 0xE0010000)) +#define U1IER (*((volatile unsigned char *) 0xE0010004)) +#define U1IIR (*((volatile unsigned char *) 0xE0010008)) +#define U1FCR (*((volatile unsigned char *) 0xE0010008)) +#define U1LCR (*((volatile unsigned char *) 0xE001000C)) +#define U1MCR (*((volatile unsigned char *) 0xE0010010)) +#define U1LSR (*((volatile unsigned char *) 0xE0010014)) +#define U1MSR (*((volatile unsigned char *) 0xE0010018)) +#define U1SCR (*((volatile unsigned char *) 0xE001001C)) +#define U1DLL (*((volatile unsigned char *) 0xE0010000)) +#define U1DLM (*((volatile unsigned char *) 0xE0010004)) + +/* I2C (8/16 bit data bus) */ +#define I2CONSET (*((volatile unsigned long *) 0xE001C000)) +#define I2STAT (*((volatile unsigned long *) 0xE001C004)) +#define I2DAT (*((volatile unsigned long *) 0xE001C008)) +#define I2ADR (*((volatile unsigned long *) 0xE001C00C)) +#define I2SCLH (*((volatile unsigned long *) 0xE001C010)) +#define I2SCLL (*((volatile unsigned long *) 0xE001C014)) +#define I2CONCLR (*((volatile unsigned long *) 0xE001C018)) + +/* SPI (Serial Peripheral Interface) */ + /* only for lpc210x*/ +#define SPI_SPCR (*((volatile unsigned char *) 0xE0020000)) +#define SPI_SPSR (*((volatile unsigned char *) 0xE0020004)) +#define SPI_SPDR (*((volatile unsigned char *) 0xE0020008)) +#define SPI_SPCCR (*((volatile unsigned char *) 0xE002000C)) +#define SPI_SPINT (*((volatile unsigned char *) 0xE002001C)) + +#define S0PCR (*((volatile unsigned char *) 0xE0020000)) /* no in lpc210x*/ +#define S0PSR (*((volatile unsigned char *) 0xE0020004)) /* no in lpc210x*/ +#define S0PDR (*((volatile unsigned char *) 0xE0020008)) /* no in lpc210x*/ +#define S0PCCR (*((volatile unsigned char *) 0xE002000C)) /* no in lpc210x*/ +#define S0PINT (*((volatile unsigned char *) 0xE002001C)) /* no in lpc210x*/ + +#define S1PCR (*((volatile unsigned char *) 0xE0030000)) /* no in lpc210x*/ +#define S1PSR (*((volatile unsigned char *) 0xE0030004)) /* no in lpc210x*/ +#define S1PDR (*((volatile unsigned char *) 0xE0030008)) /* no in lpc210x*/ +#define S1PCCR (*((volatile unsigned char *) 0xE003000C)) /* no in lpc210x*/ +#define S1PINT (*((volatile unsigned char *) 0xE003001C)) /* no in lpc210x*/ + +/* CAN CONTROLLERS AND ACCEPTANCE FILTER */ +#define CAN1MOD (*((volatile unsigned long *) 0xE0044000)) /* All CAN Parts */ +#define CAN1CMR (*((volatile unsigned long *) 0xE0044004)) /* All CAN Parts */ +#define CAN1GSR (*((volatile unsigned long *) 0xE0044008)) /* All CAN Parts */ +#define CAN1ICR (*((volatile unsigned long *) 0xE004400C)) /* All CAN Parts */ +#define CAN1IER (*((volatile unsigned long *) 0xE0044010)) /* All CAN Parts */ +#define CAN1BTR (*((volatile unsigned long *) 0xE0044014)) /* All CAN Parts */ +#define CAN1EWL (*((volatile unsigned long *) 0xE0044018)) /* All CAN Parts */ +#define CAN1SR (*((volatile unsigned long *) 0xE004401C)) /* All CAN Parts */ +#define CAN1RFS (*((volatile unsigned long *) 0xE0044020)) /* All CAN Parts */ +#define CAN1RID (*((volatile unsigned long *) 0xE0044024)) /* All CAN Parts */ +#define CAN1RDA (*((volatile unsigned long *) 0xE0044028)) /* All CAN Parts */ +#define CAN1RDB (*((volatile unsigned long *) 0xE004402C)) /* All CAN Parts */ +#define CAN1TFI1 (*((volatile unsigned long *) 0xE0044030)) /* All CAN Parts */ +#define CAN1TID1 (*((volatile unsigned long *) 0xE0044034)) /* All CAN Parts */ +#define CAN1TDA1 (*((volatile unsigned long *) 0xE0044038)) /* All CAN Parts */ +#define CAN1TDB1 (*((volatile unsigned long *) 0xE004403C)) /* All CAN Parts */ +#define CAN1TFI2 (*((volatile unsigned long *) 0xE0044040)) /* All CAN Parts */ +#define CAN1TID2 (*((volatile unsigned long *) 0xE0044044)) /* All CAN Parts */ +#define CAN1TDA2 (*((volatile unsigned long *) 0xE0044048)) /* All CAN Parts */ +#define CAN1TDB2 (*((volatile unsigned long *) 0xE004404C)) /* All CAN Parts */ +#define CAN1TFI3 (*((volatile unsigned long *) 0xE0044050)) /* All CAN Parts */ +#define CAN1TID3 (*((volatile unsigned long *) 0xE0044054)) /* All CAN Parts */ +#define CAN1TDA3 (*((volatile unsigned long *) 0xE0044058)) /* All CAN Parts */ +#define CAN1TDB3 (*((volatile unsigned long *) 0xE004405C)) /* All CAN Parts */ + +#define CAN2MOD (*((volatile unsigned long *) 0xE0048000)) /* All CAN Parts */ +#define CAN2CMR (*((volatile unsigned long *) 0xE0048004)) /* All CAN Parts */ +#define CAN2GSR (*((volatile unsigned long *) 0xE0048008)) /* All CAN Parts */ +#define CAN2ICR (*((volatile unsigned long *) 0xE004800C)) /* All CAN Parts */ +#define CAN2IER (*((volatile unsigned long *) 0xE0048010)) /* All CAN Parts */ +#define CAN2BTR (*((volatile unsigned long *) 0xE0048014)) /* All CAN Parts */ +#define CAN2EWL (*((volatile unsigned long *) 0xE0048018)) /* All CAN Parts */ +#define CAN2SR (*((volatile unsigned long *) 0xE004801C)) /* All CAN Parts */ +#define CAN2RFS (*((volatile unsigned long *) 0xE0048020)) /* All CAN Parts */ +#define CAN2RID (*((volatile unsigned long *) 0xE0048024)) /* All CAN Parts */ +#define CAN2RDA (*((volatile unsigned long *) 0xE0048028)) /* All CAN Parts */ +#define CAN2RDB (*((volatile unsigned long *) 0xE004802C)) /* All CAN Parts */ +#define CAN2TFI1 (*((volatile unsigned long *) 0xE0048030)) /* All CAN Parts */ +#define CAN2TID1 (*((volatile unsigned long *) 0xE0048034)) /* All CAN Parts */ +#define CAN2TDA1 (*((volatile unsigned long *) 0xE0048038)) /* All CAN Parts */ +#define CAN2TDB1 (*((volatile unsigned long *) 0xE004803C)) /* All CAN Parts */ +#define CAN2TFI2 (*((volatile unsigned long *) 0xE0048040)) /* All CAN Parts */ +#define CAN2TID2 (*((volatile unsigned long *) 0xE0048044)) /* All CAN Parts */ +#define CAN2TDA2 (*((volatile unsigned long *) 0xE0048048)) /* All CAN Parts */ +#define CAN2TDB2 (*((volatile unsigned long *) 0xE004804C)) /* All CAN Parts */ +#define CAN2TFI3 (*((volatile unsigned long *) 0xE0048050)) /* All CAN Parts */ +#define CAN2TID3 (*((volatile unsigned long *) 0xE0048054)) /* All CAN Parts */ +#define CAN2TDA3 (*((volatile unsigned long *) 0xE0048058)) /* All CAN Parts */ +#define CAN2TDB3 (*((volatile unsigned long *) 0xE004805C)) /* All CAN Parts */ + +#define CAN3MOD (*((volatile unsigned long *) 0xE004C000)) /* lpc2194\lpc2294 only */ +#define CAN3CMR (*((volatile unsigned long *) 0xE004C004)) /* lpc2194\lpc2294 only */ +#define CAN3GSR (*((volatile unsigned long *) 0xE004C008)) /* lpc2194\lpc2294 only */ +#define CAN3ICR (*((volatile unsigned long *) 0xE004C00C)) /* lpc2194\lpc2294 only */ +#define CAN3IER (*((volatile unsigned long *) 0xE004C010)) /* lpc2194\lpc2294 only */ +#define CAN3BTR (*((volatile unsigned long *) 0xE004C014)) /* lpc2194\lpc2294 only */ +#define CAN3EWL (*((volatile unsigned long *) 0xE004C018)) /* lpc2194\lpc2294 only */ +#define CAN3SR (*((volatile unsigned long *) 0xE004C01C)) /* lpc2194\lpc2294 only */ +#define CAN3RFS (*((volatile unsigned long *) 0xE004C020)) /* lpc2194\lpc2294 only */ +#define CAN3RID (*((volatile unsigned long *) 0xE004C024)) /* lpc2194\lpc2294 only */ +#define CAN3RDA (*((volatile unsigned long *) 0xE004C028)) /* lpc2194\lpc2294 only */ +#define CAN3RDB (*((volatile unsigned long *) 0xE004C02C)) /* lpc2194\lpc2294 only */ +#define CAN3TFI1 (*((volatile unsigned long *) 0xE004C030)) /* lpc2194\lpc2294 only */ +#define CAN3TID1 (*((volatile unsigned long *) 0xE004C034)) /* lpc2194\lpc2294 only */ +#define CAN3TDA1 (*((volatile unsigned long *) 0xE004C038)) /* lpc2194\lpc2294 only */ +#define CAN3TDB1 (*((volatile unsigned long *) 0xE004C03C)) /* lpc2194\lpc2294 only */ +#define CAN3TFI2 (*((volatile unsigned long *) 0xE004C040)) /* lpc2194\lpc2294 only */ +#define CAN3TID2 (*((volatile unsigned long *) 0xE004C044)) /* lpc2194\lpc2294 only */ +#define CAN3TDA2 (*((volatile unsigned long *) 0xE004C048)) /* lpc2194\lpc2294 only */ +#define CAN3TDB2 (*((volatile unsigned long *) 0xE004C04C)) /* lpc2194\lpc2294 only */ +#define CAN3TFI3 (*((volatile unsigned long *) 0xE004C050)) /* lpc2194\lpc2294 only */ +#define CAN3TID3 (*((volatile unsigned long *) 0xE004C054)) /* lpc2194\lpc2294 only */ +#define CAN3TDA3 (*((volatile unsigned long *) 0xE004C058)) /* lpc2194\lpc2294 only */ +#define CAN3TDB3 (*((volatile unsigned long *) 0xE004C05C)) /* lpc2194\lpc2294 only */ + +#define CAN4MOD (*((volatile unsigned long *) 0xE0050000)) /* lpc2194\lpc2294 only */ +#define CAN4CMR (*((volatile unsigned long *) 0xE0050004)) /* lpc2194\lpc2294 only */ +#define CAN4GSR (*((volatile unsigned long *) 0xE0050008)) /* lpc2194\lpc2294 only */ +#define CAN4ICR (*((volatile unsigned long *) 0xE005000C)) /* lpc2194\lpc2294 only */ +#define CAN4IER (*((volatile unsigned long *) 0xE0050010)) /* lpc2194\lpc2294 only */ +#define CAN4BTR (*((volatile unsigned long *) 0xE0050014)) /* lpc2194\lpc2294 only */ +#define CAN4EWL (*((volatile unsigned long *) 0xE0050018)) /* lpc2194\lpc2294 only */ +#define CAN4SR (*((volatile unsigned long *) 0xE005001C)) /* lpc2194\lpc2294 only */ +#define CAN4RFS (*((volatile unsigned long *) 0xE0050020)) /* lpc2194\lpc2294 only */ +#define CAN4RID (*((volatile unsigned long *) 0xE0050024)) /* lpc2194\lpc2294 only */ +#define CAN4RDA (*((volatile unsigned long *) 0xE0050028)) /* lpc2194\lpc2294 only */ +#define CAN4RDB (*((volatile unsigned long *) 0xE005002C)) /* lpc2194\lpc2294 only */ +#define CAN4TFI1 (*((volatile unsigned long *) 0xE0050030)) /* lpc2194\lpc2294 only */ +#define CAN4TID1 (*((volatile unsigned long *) 0xE0050034)) /* lpc2194\lpc2294 only */ +#define CAN4TDA1 (*((volatile unsigned long *) 0xE0050038)) /* lpc2194\lpc2294 only */ +#define CAN4TDB1 (*((volatile unsigned long *) 0xE005003C)) /* lpc2194\lpc2294 only */ +#define CAN4TFI2 (*((volatile unsigned long *) 0xE0050040)) /* lpc2194\lpc2294 only */ +#define CAN4TID2 (*((volatile unsigned long *) 0xE0050044)) /* lpc2194\lpc2294 only */ +#define CAN4TDA2 (*((volatile unsigned long *) 0xE0050048)) /* lpc2194\lpc2294 only */ +#define CAN4TDB2 (*((volatile unsigned long *) 0xE005004C)) /* lpc2194\lpc2294 only */ +#define CAN4TFI3 (*((volatile unsigned long *) 0xE0050050)) /* lpc2194\lpc2294 only */ +#define CAN4TID3 (*((volatile unsigned long *) 0xE0050054)) /* lpc2194\lpc2294 only */ +#define CAN4TDA3 (*((volatile unsigned long *) 0xE0050058)) /* lpc2194\lpc2294 only */ +#define CAN4TDB3 (*((volatile unsigned long *) 0xE005005C)) /* lpc2194\lpc2294 only */ + + +#define CANTxSR (*((volatile unsigned long *) 0xE0040000)) /* ALL CAN Parts */ +#define CANRxSR (*((volatile unsigned long *) 0xE0040004)) /* ALL CAN Parts */ +#define CANMSR (*((volatile unsigned long *) 0xE0040008)) /* ALL CAN Parts */ + +#define CANAFMR (*((volatile unsigned char *) 0xE003C000)) /* ALL CAN Parts */ +#define CANSFF_sa (*((volatile unsigned short*) 0xE003C004)) /* ALL CAN Parts */ +#define CANSFF_GRP_sa (*((volatile unsigned short*) 0xE003C008)) /* ALL CAN Parts */ +#define CANEFF_sa (*((volatile unsigned short*) 0xE003C00C)) /* ALL CAN Parts */ +#define CANEFF_GRP_sa (*((volatile unsigned short*) 0xE003C010)) /* ALL CAN Parts */ +#define CANENDofTable (*((volatile unsigned short*) 0xE003C014)) /* ALL CAN Parts */ +#define CANLUTerrAd (*((volatile unsigned short*) 0xE003C018)) /* ALL CAN Parts */ +#define CANLUTerr (*((volatile unsigned char *) 0xE003C01C)) /* ALL CAN Parts */ + + +/* Timer 0 */ +#define T0IR (*((volatile unsigned long *) 0xE0004000)) +#define T0TCR (*((volatile unsigned long *) 0xE0004004)) +#define T0TC (*((volatile unsigned long *) 0xE0004008)) +#define T0PR (*((volatile unsigned long *) 0xE000400C)) +#define T0PC (*((volatile unsigned long *) 0xE0004010)) +#define T0MCR (*((volatile unsigned long *) 0xE0004014)) +#define T0MR0 (*((volatile unsigned long *) 0xE0004018)) +#define T0MR1 (*((volatile unsigned long *) 0xE000401C)) +#define T0MR2 (*((volatile unsigned long *) 0xE0004020)) +#define T0MR3 (*((volatile unsigned long *) 0xE0004024)) +#define T0CCR (*((volatile unsigned long *) 0xE0004028)) +#define T0CR0 (*((volatile unsigned long *) 0xE000402C)) +#define T0CR1 (*((volatile unsigned long *) 0xE0004030)) +#define T0CR2 (*((volatile unsigned long *) 0xE0004034)) +#define T0CR3 (*((volatile unsigned long *) 0xE0004038)) +#define T0EMR (*((volatile unsigned long *) 0xE000403C)) + +/* Timer 1 */ +#define T1IR (*((volatile unsigned long *) 0xE0008000)) +#define T1TCR (*((volatile unsigned long *) 0xE0008004)) +#define T1TC (*((volatile unsigned long *) 0xE0008008)) +#define T1PR (*((volatile unsigned long *) 0xE000800C)) +#define T1PC (*((volatile unsigned long *) 0xE0008010)) +#define T1MCR (*((volatile unsigned long *) 0xE0008014)) +#define T1MR0 (*((volatile unsigned long *) 0xE0008018)) +#define T1MR1 (*((volatile unsigned long *) 0xE000801C)) +#define T1MR2 (*((volatile unsigned long *) 0xE0008020)) +#define T1MR3 (*((volatile unsigned long *) 0xE0008024)) +#define T1CCR (*((volatile unsigned long *) 0xE0008028)) +#define T1CR0 (*((volatile unsigned long *) 0xE000802C)) +#define T1CR1 (*((volatile unsigned long *) 0xE0008030)) +#define T1CR2 (*((volatile unsigned long *) 0xE0008034)) +#define T1CR3 (*((volatile unsigned long *) 0xE0008038)) +#define T1EMR (*((volatile unsigned long *) 0xE000803C)) + +/* Pulse Width Modulator (PWM) */ +#define PWMIR (*((volatile unsigned long *) 0xE0014000)) +#define PWMTCR (*((volatile unsigned long *) 0xE0014004)) +#define PWMTC (*((volatile unsigned long *) 0xE0014008)) +#define PWMPR (*((volatile unsigned long *) 0xE001400C)) +#define PWMPC (*((volatile unsigned long *) 0xE0014010)) +#define PWMMCR (*((volatile unsigned long *) 0xE0014014)) +#define PWMMR0 (*((volatile unsigned long *) 0xE0014018)) +#define PWMMR1 (*((volatile unsigned long *) 0xE001401C)) +#define PWMMR2 (*((volatile unsigned long *) 0xE0014020)) +#define PWMMR3 (*((volatile unsigned long *) 0xE0014024)) +#define PWMMR4 (*((volatile unsigned long *) 0xE0014040)) +#define PWMMR5 (*((volatile unsigned long *) 0xE0014044)) +#define PWMMR6 (*((volatile unsigned long *) 0xE0014048)) +#define PWMPCR (*((volatile unsigned long *) 0xE001404C)) +#define PWMLER (*((volatile unsigned long *) 0xE0014050)) + +/* A/D CONVERTER */ +#define ADCR (*((volatile unsigned long *) 0xE0034000)) /* no in lpc210x*/ +#define ADDR (*((volatile unsigned long *) 0xE0034004)) /* no in lpc210x*/ + +/* Real Time Clock */ +#define ILR (*((volatile unsigned char *) 0xE0024000)) +#define CTC (*((volatile unsigned short*) 0xE0024004)) +#define CCR (*((volatile unsigned char *) 0xE0024008)) +#define CIIR (*((volatile unsigned char *) 0xE002400C)) +#define AMR (*((volatile unsigned char *) 0xE0024010)) +#define CTIME0 (*((volatile unsigned long *) 0xE0024014)) +#define CTIME1 (*((volatile unsigned long *) 0xE0024018)) +#define CTIME2 (*((volatile unsigned long *) 0xE002401C)) +#define SEC (*((volatile unsigned char *) 0xE0024020)) +#define MIN (*((volatile unsigned char *) 0xE0024024)) +#define HOUR (*((volatile unsigned char *) 0xE0024028)) +#define DOM (*((volatile unsigned char *) 0xE002402C)) +#define DOW (*((volatile unsigned char *) 0xE0024030)) +#define DOY (*((volatile unsigned short*) 0xE0024034)) +#define MONTH (*((volatile unsigned char *) 0xE0024038)) +#define YEAR (*((volatile unsigned short*) 0xE002403C)) +#define ALSEC (*((volatile unsigned char *) 0xE0024060)) +#define ALMIN (*((volatile unsigned char *) 0xE0024064)) +#define ALHOUR (*((volatile unsigned char *) 0xE0024068)) +#define ALDOM (*((volatile unsigned char *) 0xE002406C)) +#define ALDOW (*((volatile unsigned char *) 0xE0024070)) +#define ALDOY (*((volatile unsigned short*) 0xE0024074)) +#define ALMON (*((volatile unsigned char *) 0xE0024078)) +#define ALYEAR (*((volatile unsigned short*) 0xE002407C)) +#define PREINT (*((volatile unsigned short*) 0xE0024080)) +#define PREFRAC (*((volatile unsigned short*) 0xE0024084)) + +/* Watchdog */ +#define WDMOD (*((volatile unsigned char *) 0xE0000000)) +#define WDTC (*((volatile unsigned long *) 0xE0000004)) +#define WDFEED (*((volatile unsigned char *) 0xE0000008)) +#define WDTV (*((volatile unsigned long *) 0xE000000C)) + +#endif /* LPC2294_H */ +/*********************************** end of lpc2294.h **********************************/ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/main.c b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/main.c new file mode 100644 index 00000000..1c4b590a --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/main.c @@ -0,0 +1,151 @@ +/**************************************************************************************** +| Description: demo program application source file +| File Name: main.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "header.h" /* generic header */ + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +static void Init(void); + + +/**************************************************************************************** +** NAME: main +** PARAMETER: none +** RETURN VALUE: program return code +** DESCRIPTION: This is the entry point for the bootloader application and is called +** by the reset interrupt vector after the C-startup routines executed. +** +****************************************************************************************/ +int main(void) +{ + /* initialize the microcontroller */ + Init(); + + /* initialize the bootloader interface */ + BootComInit(); + + /* start the infinite program loop */ + while (1) + { + /* toggle LED with a fixed frequency */ + LedToggle(); + + /* check for bootloader activation request */ + BootComCheckActivationRequest(); + } + + /* program should never get here */ + return 0; +} /*** end of main ***/ + + +/**************************************************************************************** +** NAME: Init +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Initializes the microcontroller. The Fpll is set to 60MHz and Fvpb is +** configured equal to Fpll. The GPIO pin of the status LED is configured +** as digital output. +** +****************************************************************************************/ +static void Init(void) +{ + unsigned char m_sel; /* pll multiplier register value */ + unsigned char pll_dividers[] = { 1, 2, 4, 8 }; /* possible pll dividers */ + unsigned char p_sel_cnt; /* loop counter to find p_sel */ + unsigned long f_cco; /* current controller oscillator */ + + /* calculate MSEL: M = round(Fcclk / Fosc) */ + m_sel = (BOOT_CPU_SYSTEM_SPEED_KHZ + ((BOOT_CPU_XTAL_SPEED_KHZ+1)/2)) / \ + BOOT_CPU_XTAL_SPEED_KHZ; + /* value for the PLLCFG register is -1 */ + m_sel--; + + /* find PSEL value so that Fcco(= Fcclk * 2 * P) is in the 156000..320000 kHz range. */ + for (p_sel_cnt=0; p_sel_cnt= 156000) && (f_cco <= 320000) ) + { + /* found a valid pll divider value */ + break; + } + } + + /* set multiplier and divider values */ + PLLCFG = (p_sel_cnt << 5) | m_sel; + PLLFEED = 0xAA; + PLLFEED = 0x55; + /* enable the PLL */ + PLLCON = 0x1; + PLLFEED = 0xAA; + PLLFEED = 0x55; + /* wait for the PLL to lock to set frequency */ + while(!(PLLSTAT & 0x400)) { ; } + /* connect the PLL as the clock source */ + PLLCON = 0x3; + PLLFEED = 0xAA; + PLLFEED = 0x55; + /* enable MAM and set number of clocks used for Flash memory fetch. Recommended: + * Fcclk >= 60 MHz: 4 clock cycles + * Fcclk >= 40 MHz: 3 clock cycles + * Fcclk >= 20 MHz: 2 clock cycles + * Fcclk < 20 MHz: 1 clock cycle + */ + MAMCR = 0x0; +#if (BOOT_CPU_SYSTEM_SPEED_KHZ >= 60) + MAMTIM = 4; +#elif (BOOT_CPU_SYSTEM_SPEED_KHZ >= 40) + MAMTIM = 3; +#elif (BOOT_CPU_SYSTEM_SPEED_KHZ >= 20) + MAMTIM = 2; +#else + MAMTIM = 1; +#endif + MAMCR = 0x2; + /* setting peripheral Clock (pclk) to System Clock (cclk) */ + VPBDIV = 0x1; + /* init the led driver */ + LedInit(); + /* init the timer driver */ + TimerInit(); + /* enable IRQ's */ + IrqInterruptEnable(); +} /*** end of Init ***/ + + +/*********************************** end of main.c *************************************/ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/makefile b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/makefile new file mode 100644 index 00000000..bf7e81b1 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/makefile @@ -0,0 +1,144 @@ +#**************************************************************************************** +#| Description: Makefile for NXP LPC2000 using CodeSourcery GNU GCC compiler toolset +#| File Name: makefile +#| +#|--------------------------------------------------------------------------------------- +#| C O P Y R I G H T +#|--------------------------------------------------------------------------------------- +#| Copyright (c) 2011 by Feaser LLC http://www.feaser.com All rights reserved +#| +#|--------------------------------------------------------------------------------------- +#| L I C E N S E +#|--------------------------------------------------------------------------------------- +#| This file is part of OpenBTL. OpenBTL 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. +#| +#| OpenBTL 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 OpenBTL. +#| If not, see . +#| +#**************************************************************************************** +SHELL = sh + +#|---------------------------------------------------------------------------------------| +#| Configure project name | +#|---------------------------------------------------------------------------------------| +PROJ_NAME=demoprog_olimex_lpc_l2294_20mhz + + +#|---------------------------------------------------------------------------------------| +#| Speficy project source files | +#|---------------------------------------------------------------------------------------| +PROJ_FILES= \ +lpc2294.h \ +vectors.c \ +main.c \ +boot.c \ +boot.h \ +irq.c \ +irq.h \ +led.c \ +led.h \ +timer.c \ +timer.h \ +header.h \ +cstart.s + + +#|---------------------------------------------------------------------------------------| +#| Compiler binaries | +#|---------------------------------------------------------------------------------------| +CC = arm-none-eabi-gcc +LN = arm-none-eabi-gcc +OC = arm-none-eabi-objcopy +OD = arm-none-eabi-objdump +AS = arm-none-eabi-as +SZ = arm-none-eabi-size + + +#|---------------------------------------------------------------------------------------| +#| Extract file names | +#|---------------------------------------------------------------------------------------| +PROJ_ASRCS = $(filter %.s,$(foreach file,$(PROJ_FILES),$(notdir $(file)))) +PROJ_CSRCS = $(filter %.c,$(foreach file,$(PROJ_FILES),$(notdir $(file)))) +PROJ_CHDRS = $(filter %.h,$(foreach file,$(PROJ_FILES),$(notdir $(file)))) +PROJ_CCMPL = $(patsubst %.c,%.cpl,$(PROJ_CSRCS)) +PROJ_ACMPL = $(patsubst %.s,%.cpl,$(PROJ_ASRCS)) + + +#|---------------------------------------------------------------------------------------| +#| Set important path variables | +#|---------------------------------------------------------------------------------------| +VPATH = $(foreach path,$(sort $(foreach file,$(PROJ_FILES),$(dir $(file)))) $(subst \,/,$(OBJ_PATH)),$(path) :) +OBJ_PATH = ./obj +BIN_PATH = ./bin +INC_PATH = $(patsubst %,-I%,$(sort $(foreach file,$(filter %.h,$(PROJ_FILES)),$(dir $(file))))) +INC_PATH += -I. +LIB_PATH = -L. + + +#|---------------------------------------------------------------------------------------| +#| Options for compiler binaries | +#|---------------------------------------------------------------------------------------| +AFLAGS = -ahls -mapcs-32 -mcpu=arm7tdmi-s -mfpu=softfpa +CFLAGS = $(INC_PATH) -O0 -Wall -fmessage-length=0 -mcpu=arm7tdmi-s -g -mlong-calls +CFLAGS += -Wa,-adhlns="$(OBJ_PATH)/$(subst .o,.lst,$@)" +LFLAGS = $(LIB_PATH) -T"memory.x" -g -mcpu=arm7tdmi-s -nostartfiles +OCFLAGS = -O srec +ODFLAGS = -x +SZFLAGS = -B -d + + +#|---------------------------------------------------------------------------------------| +#| Define targets | +#|---------------------------------------------------------------------------------------| +AOBJS = $(patsubst %.s,%.o,$(PROJ_ASRCS)) +COBJS = $(patsubst %.c,%.o,$(PROJ_CSRCS)) + + +#|---------------------------------------------------------------------------------------| +#| Make ALL | +#|---------------------------------------------------------------------------------------| +all : $(BIN_PATH)/$(PROJ_NAME).sx + +$(BIN_PATH)/$(PROJ_NAME).sx : $(BIN_PATH)/$(PROJ_NAME).elf + @$(OC) $(OCFLAGS) $< $@ + @$(OD) $(ODFLAGS) $< > $(BIN_PATH)/$(PROJ_NAME).map + @echo +++ Summary of memory consumption: + @$(SZ) $(SZFLAGS) $< + @echo +++ Build complete [$(notdir $@)] + +$(BIN_PATH)/$(PROJ_NAME).elf : $(AOBJS) $(COBJS) + @echo +++ Linking [$(notdir $@)] + @$(LN) $(LFLAGS) -o $@ $(patsubst %.o,$(OBJ_PATH)/%.o,$(^F)) + + +#|---------------------------------------------------------------------------------------| +#| Compile and assemble | +#|---------------------------------------------------------------------------------------| +$(AOBJS): %.o: %.s $(PROJ_CHDRS) + @echo +++ Assembling [$@] + @$(AS) $(AFLAGS) $< -o $(OBJ_PATH)/$(@F) > $(subst .o,.lst,$(OBJ_PATH)/$(@F)) + +$(COBJS): %.o: %.c $(PROJ_CHDRS) + @echo +++ Compiling [$@] + @$(CC) $(CFLAGS) -c -o $(OBJ_PATH)/$(@F) $< + +#|---------------------------------------------------------------------------------------| +#| Make CLEAN | +#|---------------------------------------------------------------------------------------| +clean : + @echo +++ Cleaning build environment + @rm -f $(foreach file,$(AOBJS),$(OBJ_PATH)/$(file)) + @rm -f $(foreach file,$(COBJS),$(OBJ_PATH)/$(file)) + @rm -f $(patsubst %.o,%.lst,$(foreach file,$(AOBJS),$(OBJ_PATH)/$(file))) + @rm -f $(patsubst %.o,%.lst,$(foreach file,$(COBJS),$(OBJ_PATH)/$(file))) + @rm -f $(BIN_PATH)/$(PROJ_NAME).sx $(BIN_PATH)/$(PROJ_NAME).map $(BIN_PATH)/$(PROJ_NAME).elf + @echo +++ Clean complete + + diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/memory.x b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/memory.x new file mode 100644 index 00000000..a3b8a9e4 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/memory.x @@ -0,0 +1,51 @@ +/* identify the Entry Point */ +ENTRY(_startup) + +/* specify the LPC2294 memory areas */ +MEMORY +{ + flash : ORIGIN = 0x00002000, LENGTH = 240K /* FLASH ROM for the user program */ + ram_vectors(A) : ORIGIN = 0x40000000, LENGTH = 64 /* RAM vectors of the user program */ + ram_monitor(A) : ORIGIN = 0x40000040, LENGTH = 224 /* variables used by Philips RealMonitor */ + ram_isp_low(A) : ORIGIN = 0x40000120, LENGTH = 224 /* variables used by Philips ISP bootloader */ + ram : ORIGIN = 0x40000200, LENGTH = 15584 /* free RAM area */ + ram_isp_high(A) : ORIGIN = 0x40003EE0, LENGTH = 288 /* variables used by Philips ISP bootloader */ +} + +/* define a global symbol _stack_end, placed at the very end of unused RAM */ +_stack_end = 0x40003EE0 - 4; + +/* now define the output sections */ +SECTIONS +{ + . = 0; /* set location counter to address zero */ + startup : { *(.startup)} >flash /* the startup code goes into FLASH */ + + .text : /* collect all sections that should go into FLASH after startup */ + { + *(.text) /* all .text sections (code) */ + *(.rodata) /* all .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* all .rodata* sections (constants, strings, etc.) */ + *(.glue_7) /* all .glue_7 sections (no idea what these are) */ + *(.glue_7t) /* all .glue_7t sections (no idea what these are) */ + _etext = .; /* define a global symbol _etext just after the last code byte */ + } >flash /* put all the above into FLASH */ + + .data : /* collect all initialized .data sections that go into RAM */ + { + _data = .; /* create a global symbol marking the start of the .data section */ + *(.data) /* all .data sections */ + _edata = .; /* define a global symbol marking the end of the .data section */ + } >ram AT >flash /* put all the above into RAM (but load the LMA copy into FLASH) */ + + .bss : /* collect all uninitialized .bss sections that go into RAM */ + { + _bss_start = .; /* define a global symbol marking the start of the .bss section */ + *(.bss) /* all .bss sections */ + } >ram /* put all the above in RAM (it will be cleared in the startup code */ + + . = ALIGN(4); /* advance location counter to the next 32-bit boundary */ + _bss_end = . ; /* define a global symbol marking the end of the .bss section */ +} + _end = .; /* define a global symbol marking the end of application RAM */ + diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/timer.c b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/timer.c new file mode 100644 index 00000000..6aa579af --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/timer.c @@ -0,0 +1,119 @@ +/**************************************************************************************** +| Description: Timer driver source file +| File Name: timer.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "header.h" /* generic header */ + + +/**************************************************************************************** +* Local data declarations +****************************************************************************************/ +static unsigned long millisecond_counter; + + +/**************************************************************************************** +* External functions +****************************************************************************************/ +extern void TIMER0_ISR(void); + + +/**************************************************************************************** +** NAME: TimerInit +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Initializes the timer. +** +****************************************************************************************/ +void TimerInit(void) +{ + /* configure timer0 as 1 ms software output compare */ + T0MR0 = BOOT_CPU_SYSTEM_SPEED_KHZ-1; + /* enable interrupt and automatic reset upon compare */ + T0MCR = 0x01 | 0x02; + /* enable the output compare */ + T0TCR = 0x01; + /* set the interrupt service routine for the output compare event */ + VICVectAddr0 = (unsigned long)TIMER0_ISR; + /* connect vectored IRQ slot 0 to Timer0's channel 4 */ + VICVectCntl0 = 0x20 | 4; + /* enable the timer0 interrupt */ + VICIntEnable = 0x10; + /* reset the millisecond counter */ + TimerSet(0); +} /*** end of TimerInit ***/ + + +/**************************************************************************************** +** NAME: TimerUpdate +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Updates the millisecond timer. Should be called every millisecond by +** the timer interrupt service routine. +** +****************************************************************************************/ +void TimerUpdate(void) +{ + /* increment the millisecond counter */ + millisecond_counter++; +} /*** end of TimerUpdate ***/ + + +/**************************************************************************************** +** NAME: TimerSet +** PARAMETER: timer_value initialize value of the millisecond timer. +** RETURN VALUE: none +** DESCRIPTION: Sets the initial counter value of the millisecond timer. +** +****************************************************************************************/ +void TimerSet(unsigned long timer_value) +{ + /* set the millisecond counter */ + millisecond_counter = timer_value; +} /*** end of TimerSet ***/ + + +/**************************************************************************************** +** NAME: TimerGet +** PARAMETER: none +** RETURN VALUE: current value of the millisecond timer +** DESCRIPTION: Obtains the counter value of the millisecond timer. +** +****************************************************************************************/ +unsigned long TimerGet(void) +{ + /* read and return the millisecond counter value */ + return millisecond_counter; +} /*** end of TimerGet ***/ + + +/*********************************** end of timer.c ************************************/ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/timer.h b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/timer.h new file mode 100644 index 00000000..e1bb1754 --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/timer.h @@ -0,0 +1,44 @@ +/**************************************************************************************** +| Description: Timer driver header file +| File Name: timer.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef TIMER_H +#define TIMER_H + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void TimerInit(void); +void TimerUpdate(void); +void TimerSet(unsigned long timer_value); +unsigned long TimerGet(void); + + +#endif /* TIMER_H */ +/*********************************** end of timer.h ************************************/ diff --git a/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/vectors.c b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/vectors.c new file mode 100644 index 00000000..7b5682bc --- /dev/null +++ b/Target/Demo/ARM7_LPC2000_Olimex_LPC_L2294_GCC/Prog/vectors.c @@ -0,0 +1,107 @@ +/**************************************************************************************** +| Description: demo program interrupt vectors source file +| File Name: vectors.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "header.h" /* generic header */ + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void __attribute__ ((interrupt("IRQ"))) TIMER0_ISR(void); +void __attribute__ ((interrupt("SWI"))) SWI_ISR(void); +void __attribute__ ((interrupt("FIQ"))) FIQ_ISR(void); +void __attribute__ ((interrupt("UNDEF"))) UNDEF_ISR(void); + + +/**************************************************************************************** +** NAME: TIMER0_ISR +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Timer0 exception routine. +** +****************************************************************************************/ +void TIMER0_ISR(void) +{ + /* clear the interrupt flag */ + T0IR = 0x01; + /* acknowledge interrupt */ + VICVectAddr = 0; + /* process time tick */ + TimerUpdate(); +} /*** end of TIMER0_ISR ***/ + + +/**************************************************************************************** +** NAME: SWI_ISR +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: SWI exception routine. +** +****************************************************************************************/ +void SWI_ISR(void) +{ + /* unexpected interrupt so halt program */ + for (;;) { ; } +} /*** end of SWI_ISR ***/ + + +/**************************************************************************************** +** NAME: FIQ_ISR +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: FIQ exception routine. +** +****************************************************************************************/ +void FIQ_ISR(void) +{ + /* unexpected interrupt so halt program */ + for (;;) { ; } +} /*** end of FIQ_ISR ***/ + + +/**************************************************************************************** +** NAME: UNDEF_ISR +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: UNDEF exception routine. +** +****************************************************************************************/ +void UNDEF_ISR(void) +{ + /* unexpected interrupt so halt program */ + for (;;) { ; } +} /*** end of UNDEF_ISR ***/ + + +/*********************************** end of vectors.c **********************************/ diff --git a/Target/Source/ARM7_LPC2000/GCC/cstart.s b/Target/Source/ARM7_LPC2000/GCC/cstart.s new file mode 100644 index 00000000..8888deea --- /dev/null +++ b/Target/Source/ARM7_LPC2000/GCC/cstart.s @@ -0,0 +1,237 @@ +/**************************************************************************************** +| Description: bootloader C-startup assembly file +| File Name: cstart.s +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +/* stack Sizes */ +.set UND_STACK_SIZE, 0x00000004 /* stack for "undef" interrupts is 4 bytes */ +.set ABT_STACK_SIZE, 0x00000004 /* stack for "abort" interrupts is 4 bytes */ +.set FIQ_STACK_SIZE, 0x00000004 /* stack for "FIQ" interrupts is 4 bytes */ +.set IRQ_STACK_SIZE, 0X00000004 /* stack for "IRQ" normal interrupts is 4 bytes */ +.set SVC_STACK_SIZE, 0x00000004 /* stack for "SVC" supervisor mode is 4 bytes */ + +/* mode bits and Interrupt (I & F) flags in program status registers (PSRs) */ +.set MODE_USR, 0x10 /* Normal User Mode */ +.set MODE_FIQ, 0x11 /* FIQ Processing Fast Interrupts Mode */ +.set MODE_IRQ, 0x12 /* IRQ Processing Standard Interrupts Mode */ +.set MODE_SVC, 0x13 /* Supervisor Processing Software Interrupts Mode */ +.set MODE_ABT, 0x17 /* Abort Processing memory Faults Mode */ +.set MODE_UND, 0x1B /* Undefined Processing Undefined Instructions Mode */ +.set MODE_SYS, 0x1F /* System Running Priviledged OS Tasks Mode */ +.set I_BIT, 0x80 /* when I bit is set, IRQ is disabled */ +.set F_BIT, 0x40 /* when F bit is set, FIQ is disabled */ + +/* microcontroller registers */ +.set MEMMAP, 0xE01FC040 /* MEMMAP register */ + +.text +.arm + +.extern ComSetConnectEntryState +.global EntryFromProg +.global Reset_Handler +.global SetupRAM +.global _startup +.func _startup + +_startup: +/**************************************************************************************** +* Interrupt vector table +****************************************************************************************/ +_vectors: ldr PC, Reset_Addr /* point to Reset_Handler address */ + ldr PC, Undef_Addr /* point to UNDEF_ISR address */ + ldr PC, SWI_Addr /* point to SWI_ISR address */ + ldr PC, PAbt_Addr /* point to UNDEF_ISR address */ + ldr PC, DAbt_Addr /* point to UNDEF_ISR address */ + nop /* reserved for Philips ISP checksum */ + ldr PC, IRQ_Addr /* point to IRQ_ISR address */ + ldr PC, FIQ_Addr /* point to FIQ_ISR address */ + +Reset_Addr: .word Reset_Handler /* defined in this module below */ +Undef_Addr: .word UNDEF_ISR /* defined in vectors.c */ +SWI_Addr: .word Reset_Handler_SWI /* defined in this module below */ +PAbt_Addr: .word UNDEF_ISR /* defined in vectors.c */ +DAbt_Addr: .word UNDEF_ISR /* defined in vectors.c */ +FIQ_Addr: .word FIQ_ISR /* defined in vectors.c */ +IRQ_Addr: .word IRQ_ISR /* defined in vectors.c */ + .word 0 /* rounds vectors and ISR addresses to */ + /* 64 bytes */ + + +/**************************************************************************************** +** NAME: EntryFromProg +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Called by the user program to activate the bootloader. Do not place +** any assembly code between this function and the end of the vector +** table. This guarantees that this function is located at address +** 0x00000040. The user program can call this function from C in the +** following way: +** void ActivateBootloader(void) +** { +** void (*pEntryFromProgFnc)(void); +** +** pEntryFromProgFnc = (void*)0x00000040; +** pEntryFromProgFnc(); +** } +** +****************************************************************************************/ +EntryFromProg: + /* remap interrupt vector table back to ROM to make sure the bootloader + * vectors are used: + * MEMMAP = 0x01; + */ + ldr r0, =MEMMAP + mov r1, #1 + str r1, [r0, #0] + /* trigger SWI to entry supervisor mode and run Reset_Handler_SWI */ + swi 0 + /*** end of EntryFromProg ***/ + + +/**************************************************************************************** +** NAME: Reset_Handler +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Reset interrupt service routine. Configures the stack for each mode, +** disables the IRQ and FIQ interrupts, initializes RAM and jumps to +** function main. +** +****************************************************************************************/ +Reset_Handler: + /* setup a stack and disable interrupts for each mode */ + ldr r0, =_stack_end + msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */ + mov sp, r0 + sub r0, r0, #UND_STACK_SIZE + msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */ + mov sp, r0 + sub r0, r0, #ABT_STACK_SIZE + msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */ + mov sp, r0 + sub r0, r0, #FIQ_STACK_SIZE + msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */ + mov sp, r0 + sub r0, r0, #IRQ_STACK_SIZE + msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */ + mov sp, r0 + sub r0, r0, #SVC_STACK_SIZE + msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* User Mode */ + mov sp, r0 + /* copy .data section from ROM to RAM and zero out .bss section */ + bl SetupRAM + /* start bootloader program by jumping to main() */ + b main +/*** end of Reset_Handler ***/ + + +/**************************************************************************************** +** NAME: Reset_Handler_SWI +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Reset handler for a software reset after the user program activated +** the bootloader. Configures the stack for each mode, disables the IRQ +** and FIQ interrupts, initializes RAM. Most importantly, before jumping +** to function main to start the bootloader program, the COM interface +** is configured to start in a connected state. Here is why: +** At the start of a new programming session, the host sends the XCP +** CONNECT command. Upon reception, the user program activates the +** bootloader by jumping to function EntryFromProg(), which triggers the +** SWI instruction that gets the program to this point. When the +** bootloader is started, it now needs to send the response to the XCP +** CONNECT command, because the host is waiting for this before it can +** continue. +** +****************************************************************************************/ +Reset_Handler_SWI: + /* setup a stack and disable interrupts for each mode */ + ldr r0, =_stack_end + msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */ + mov sp, r0 + sub r0, r0, #UND_STACK_SIZE + msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */ + mov sp, r0 + sub r0, r0, #ABT_STACK_SIZE + msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */ + mov sp, r0 + sub r0, r0, #FIQ_STACK_SIZE + msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */ + mov sp, r0 + sub r0, r0, #IRQ_STACK_SIZE + msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */ + mov sp, r0 + sub r0, r0, #SVC_STACK_SIZE + msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* User Mode */ + mov sp, r0 + /* copy .data section from ROM to RAM and zero out .bss section */ + bl SetupRAM + /* this part makes the difference with the normal Reset_Handler */ + bl ComSetConnectEntryState + /* start bootloader program by jumping to main() */ + b main +/*** end of Reset_Handler_SWI ***/ + + +/**************************************************************************************** +** NAME: SetupRAM +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Initializes RAM by copying .data section from ROM to RAM and zero-ing +** out .bss section. +** +****************************************************************************************/ +SetupRAM: + /* copy .data section (Copy from ROM to RAM) */ + ldr R1, =_etext + ldr R2, =_data + ldr R3, =_edata +1: cmp R2, R3 + ldrlo R0, [R1], #4 + strlo R0, [R2], #4 + blo 1b + + /* clear .bss section (Zero init) */ + mov R0, #0 + ldr R1, =_bss_start + ldr R2, =_bss_end +2: cmp R1, R2 + strlo R0, [R1], #4 + blo 2b + /* return */ + bx lr +/*** end of SetupRAM ***/ +.endfunc + + +.end +/*********************************** end of cstart.s ***********************************/ diff --git a/Target/Source/ARM7_LPC2000/GCC/flash.c b/Target/Source/ARM7_LPC2000/GCC/flash.c new file mode 100644 index 00000000..5e10bc44 --- /dev/null +++ b/Target/Source/ARM7_LPC2000/GCC/flash.c @@ -0,0 +1,705 @@ +/**************************************************************************************** +| Description: bootloader flash driver source file +| File Name: flash.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ + + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +#define FLASH_INVALID_SECTOR (0xff) +#define FLASH_INVALID_ADDRESS (0xffffffff) +#define FLASH_WRITE_BLOCK_SIZE (512) +#define FLASH_TOTAL_SECTORS (sizeof(flashLayout)/sizeof(flashLayout[0])) +/* entry address for the IAP algorithms, enabling a switch to thumb mode */ +#define IAP_ENTRY_ADDRESS (0x7ffffff1) +/* command codes */ +#define IAP_CMD_PREPARE_SECTORS (50) +#define IAP_CMD_COPY_RAM_TO_FLASH (51) +#define IAP_CMD_ERASE_SECTORS (52) +#define IAP_CMD_BLANK_CHECK_SECTORS (53) +#define IAP_CMD_COMPARE (56) +/* result codes */ +#define IAP_CMD_SUCCESS (0) + + +/**************************************************************************************** +* Type definitions +****************************************************************************************/ +/* function pointer type that is needed to call IAP functions of the NXP LPC2xxx */ +typedef void (*pIapHandler)(blt_int32u command[], blt_int32u result[]); + +/* flash sector descriptor type */ +typedef struct +{ + blt_addr sector_start; /* sector start address */ + blt_int32u sector_size; /* sector size in bytes */ + blt_int8u sector_num; /* sector number */ +} tFlashSector; /* flash sector description */ + +/* programming is done per block of max FLASH_WRITE_BLOCK_SIZE. for this a flash block + * manager is implemented in this driver. this flash block manager depends on this + * flash block info structure. It holds the base address of the flash block and the + * data that should be programmed into the flash block. Note that the .data member must + * be 32-bit aligned by the linker. the .base_addr must be a multiple of + * FLASH_WRITE_BLOCK_SIZE. + */ +typedef struct +{ + blt_addr base_addr; + blt_int8u data[FLASH_WRITE_BLOCK_SIZE] __attribute__ ((aligned (4))); +} tFlashBlockInfo; + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +static blt_bool FlashInitBlock(tFlashBlockInfo *block, blt_addr address); +static tFlashBlockInfo *FlashSwitchBlock(tFlashBlockInfo *block, blt_addr base_addr); +static blt_bool FlashAddToBlock(tFlashBlockInfo *block, blt_addr address, + blt_int8u *data, blt_int16u len); +static blt_bool FlashWriteBlock(tFlashBlockInfo *block); +static blt_bool FlashEraseSectors(blt_int8u first_sector, blt_int8u last_sector); +static blt_int8u FlashGetSector(blt_addr address); + + +/**************************************************************************************** +* Local constant declarations +****************************************************************************************/ +/* The current flash layout supports the NXP LPC21xx and LPC22xx targets. LPC23xx have + * a slightly different layout. To support the LPC23xx, simply update this flash layout. + */ +static const tFlashSector flashLayout[] = +{ +#if (BOOT_NVM_SIZE_KB == 64) + /* { 0x00000000, 0x02000, 0}, flash sector 0 - reserved for bootloader */ + { 0x00002000, 0x02000, 1}, /* flash sector 1 */ + { 0x00004000, 0x02000, 2}, /* flash sector 2 */ + { 0x00006000, 0x02000, 3}, /* flash sector 3 */ + { 0x00008000, 0x02000, 4}, /* flash sector 4 */ + { 0x0000A000, 0x02000, 5}, /* flash sector 5 */ + { 0x0000C000, 0x02000, 6}, /* flash sector 6 */ + /* { 0x0000E000, 0x02000, 7}, flash sector 7 - used by NXP bootcode */ +#endif +#if (BOOT_NVM_SIZE_KB == 128) + /* { 0x00000000, 0x02000, 0}, flash sector 0 - reserved for bootloader */ + { 0x00002000, 0x02000, 1}, /* flash sector 1 */ + { 0x00004000, 0x02000, 2}, /* flash sector 2 */ + { 0x00006000, 0x02000, 3}, /* flash sector 3 */ + { 0x00008000, 0x02000, 4}, /* flash sector 4 */ + { 0x0000A000, 0x02000, 5}, /* flash sector 5 */ + { 0x0000C000, 0x02000, 6}, /* flash sector 6 */ + { 0x0000E000, 0x02000, 7}, /* flash sector 7 */ + { 0x00010000, 0x02000, 8}, /* flash sector 8 */ + { 0x00012000, 0x02000, 9}, /* flash sector 9 */ + { 0x00014000, 0x02000, 10}, /* flash sector 10 */ + { 0x00016000, 0x02000, 11}, /* flash sector 11 */ + { 0x00018000, 0x02000, 12}, /* flash sector 12 */ + { 0x0001A000, 0x02000, 13}, /* flash sector 13 */ + { 0x0001C000, 0x02000, 14}, /* flash sector 14 */ + /* { 0x0001E000, 0x02000, 15}, flash sector 15 - used by NXP bootcode */ +#endif +#if (BOOT_NVM_SIZE_KB == 256) + /* { 0x00000000, 0x02000, 0}, flash sector 0 - reserved for bootloader */ + { 0x00002000, 0x02000, 1}, /* flash sector 1 */ + { 0x00004000, 0x02000, 2}, /* flash sector 2 */ + { 0x00006000, 0x02000, 3}, /* flash sector 3 */ + { 0x00008000, 0x02000, 4}, /* flash sector 4 */ + { 0x0000A000, 0x02000, 5}, /* flash sector 5 */ + { 0x0000C000, 0x02000, 6}, /* flash sector 6 */ + { 0x0000E000, 0x02000, 7}, /* flash sector 7 */ + { 0x00010000, 0x10000, 8}, /* flash sector 8 */ + { 0x00020000, 0x10000, 9}, /* flash sector 9 */ + { 0x00030000, 0x02000, 10}, /* flash sector 10 */ + { 0x00032000, 0x02000, 11}, /* flash sector 11 */ + { 0x00034000, 0x02000, 12}, /* flash sector 12 */ + { 0x00036000, 0x02000, 13}, /* flash sector 13 */ + { 0x00038000, 0x02000, 14}, /* flash sector 14 */ + { 0x0003A000, 0x02000, 15}, /* flash sector 15 */ + { 0x0003C000, 0x02000, 16}, /* flash sector 16 */ + /* { 0x0003E000, 0x02000, 17}, flash sector 17 - used by NXP bootcode */ +#endif +}; + + +/**************************************************************************************** +* Local data declarations +****************************************************************************************/ +/* The smallest amount of flash that can be programmed is FLASH_WRITE_BLOCK_SIZE. A flash + * block manager is implemented in this driver and stores info in this variable. Whenever + * new data should be flashed, it is first added to a RAM buffer, which is part of this + * variable. Whenever the RAM buffer, which has the size of a flash block, is full or + * data needs to be written to a different block, the contents of the RAM buffer are + * programmed to flash. The flash block manager requires some software overhead, yet + * results is faster flash programming because data is first harvested, ideally until + * there is enough to program an entire flash block, before the flash device is actually + * operated on. + */ +static tFlashBlockInfo blockInfo; + +/* The first block of the user program holds the vector table, which on the LPC2000 is + * also the where the checksum is written to. Is it likely that the vector table is + * first flashed and then, at the end of the programming sequence, the checksum. This + * means that this flash block need to be written to twice. Normally this is not a + * problem with flash memory, as long as you write the same values to those bytes that + * are not supposed to be changed and the locations where you do write to are still in + * the erased 0xFF state. Unfortunately, writing twice to flash this way, does not work + * reliably on the LPC2000. This is why we need to have an extra block, the bootblock, + * placed under the management of the block manager. This way is it possible to implement + * functionality so that the bootblock is only written to once at the end of the + * programming sequency. + */ +static tFlashBlockInfo bootBlockInfo; + + +/**************************************************************************************** +** NAME: FlashInit +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Initializes the flash driver. +** +****************************************************************************************/ +void FlashInit(void) +{ + /* check the flash block data buffer alignments */ + if ((((blt_addr)blockInfo.data % 4) != 0) || (((blt_addr)bootBlockInfo.data % 4) != 0)) + { + /* incorrect alignment */ + ASSERT_RT(BLT_FALSE); + } + /* init the flash block info structs by setting the address to an invalid address */ + blockInfo.base_addr = FLASH_INVALID_ADDRESS; + bootBlockInfo.base_addr = FLASH_INVALID_ADDRESS; +} /*** end of FlashInit ***/ + + +/**************************************************************************************** +** NAME: FlashWrite +** PARAMETER: addr start address +** len length in bytes +** data pointer to the data buffer. +** RETURN VALUE: BLT_TRUE if successful, BLT_FALSE otherwise. +** DESCRIPTION: Writes the data to flash through a flash block manager. Note that this +** function also checks that no data is programmed outside the flash +** memory region, so the bootloader can never be overwritten. +** +****************************************************************************************/ +blt_bool FlashWrite(blt_addr addr, blt_int32u len, blt_int8u *data) +{ + blt_addr base_addr; + + /* make sure the addresses are within the flash device */ + if ( (FlashGetSector(addr) == FLASH_INVALID_SECTOR) || \ + (FlashGetSector(addr+len-1) == FLASH_INVALID_SECTOR) ) + { + return BLT_FALSE; + } + + /* if this is the bootblock, then let the boot block manager handle it */ + base_addr = (addr/FLASH_WRITE_BLOCK_SIZE)*FLASH_WRITE_BLOCK_SIZE; + if (base_addr == flashLayout[0].sector_start) + { + /* let the boot block manager handle it */ + return FlashAddToBlock(&bootBlockInfo, addr, data, len); + } + /* let the block manager handle it */ + return FlashAddToBlock(&blockInfo, addr, data, len); +} /*** end of FlashWrite ***/ + + +/**************************************************************************************** +** NAME: FlashErase +** PARAMETER: addr start address +** len length in bytes +** RETURN VALUE: BLT_TRUE if successful, BLT_FALSE otherwise. +** DESCRIPTION: Erases the flash memory. Note that this function also checks that no +** data is erased outside the flash memory region, so the bootloader can +** never be erased. +** +****************************************************************************************/ +blt_bool FlashErase(blt_addr addr, blt_int32u len) +{ + blt_int8u first_sector; + blt_int8u last_sector; + + /* obtain the first and last sector number */ + first_sector = FlashGetSector(addr); + last_sector = FlashGetSector(addr+len-1); + /* check them */ + if ( (first_sector == FLASH_INVALID_SECTOR) || (last_sector == FLASH_INVALID_SECTOR) ) + { + return BLT_FALSE; + } + /* erase the sectors */ + return FlashEraseSectors(first_sector, last_sector); +} /*** end of FlashErase ***/ + + +/**************************************************************************************** +** NAME: FlashWriteChecksum +** PARAMETER: none +** RETURN VALUE: BLT_TRUE is successful, BTL_FALSE otherwise. +** DESCRIPTION: Writes a checksum of the user program to non-volatile memory. This is +** performed once the entire user program has been programmed. Through +** the checksum, the bootloader can check if the programming session +** was completed, which indicates that a valid user programming is +** present and can be started. +** +****************************************************************************************/ +blt_bool FlashWriteChecksum(void) +{ + blt_int32u signature_checksum = 0; + + /* The ARM7 core already has a spot reserved for a checksum that the bootloader can + * store at the end of a programming session. In order for the bootloader to be able + * to program the checksum, it is important that address 0x******14, which is reserved + * for the checksum, is set to 0xffffffff in the user program. + * + * Layout of the vector table (* = don't care) + * 0x******00 Reset Exception + * 0x******04 Undefined Instruction Exception + * 0x******08 Software Interrupt Exception + * 0x******0C Prefetch Exception + * 0x******10 Abort Exception + * 0x******14 [reserved for signature checksum] + * 0x******18 IRQ Exception + * 0x******1C FIQ Exception + * + * signature_checksum = Two's complement of (SUM(exception address values)) + */ + + /* compute the checksum. note that the user program's vectors are not yet written + * to flash but are present in the bootblock data structure at this point. + */ + signature_checksum += *((blt_int32u*)(&bootBlockInfo.data[0+0x00])); + signature_checksum += *((blt_int32u*)(&bootBlockInfo.data[0+0x04])); + signature_checksum += *((blt_int32u*)(&bootBlockInfo.data[0+0x08])); + signature_checksum += *((blt_int32u*)(&bootBlockInfo.data[0+0x0C])); + signature_checksum += *((blt_int32u*)(&bootBlockInfo.data[0+0x10])); + signature_checksum += *((blt_int32u*)(&bootBlockInfo.data[0+0x18])); + signature_checksum += *((blt_int32u*)(&bootBlockInfo.data[0+0x1C])); + signature_checksum = ~signature_checksum; /* one's complement */ + signature_checksum += 1; /* two's complement */ + + /* write the checksum */ + return FlashWrite(flashLayout[0].sector_start+0x14, sizeof(blt_addr), + (blt_int8u*)&signature_checksum); +} /*** end of FlashWriteChecksum ***/ + + +/**************************************************************************************** +** NAME: FlashVerifyChecksum +** PARAMETER: none +** RETURN VALUE: BLT_TRUE is successful, BTL_FALSE otherwise. +** DESCRIPTION: Verifies the checksum, which indicates that a valid user program is +** present and can be started. +** +****************************************************************************************/ +blt_bool FlashVerifyChecksum(void) +{ + blt_int32u signature_checksum = 0; + + /* verify the checksum based on how it was written by CpuWriteChecksum() */ + signature_checksum += *((blt_int32u*)(flashLayout[0].sector_start)); + signature_checksum += *((blt_int32u*)(flashLayout[0].sector_start+0x04)); + signature_checksum += *((blt_int32u*)(flashLayout[0].sector_start+0x08)); + signature_checksum += *((blt_int32u*)(flashLayout[0].sector_start+0x0C)); + signature_checksum += *((blt_int32u*)(flashLayout[0].sector_start+0x10)); + signature_checksum += *((blt_int32u*)(flashLayout[0].sector_start+0x14)); + signature_checksum += *((blt_int32u*)(flashLayout[0].sector_start+0x18)); + signature_checksum += *((blt_int32u*)(flashLayout[0].sector_start+0x1C)); + + /* sum should add up to an unsigned 32-bit value of 0 */ + if (signature_checksum == 0) + { + /* checksum okay */ + return BLT_TRUE; + } + /* checksum incorrect */ + return BLT_FALSE; +} /*** end of FlashVerifyChecksum ***/ + + +/**************************************************************************************** +** NAME: FlashDone +** PARAMETER: none +** RETURN VALUE: BLT_TRUE is succesful, BLT_FALSE otherwise. +** DESCRIPTION: Finilizes the flash driver operations. There could still be data in +** the currently active block that needs to be flashed. +** +****************************************************************************************/ +blt_bool FlashDone(void) +{ + /* check if there is still data waiting to be programmed in the boot block */ + if (bootBlockInfo.base_addr != FLASH_INVALID_ADDRESS) + { + if (FlashWriteBlock(&bootBlockInfo) == BLT_FALSE) + { + return BLT_FALSE; + } + } + + /* check if there is still data waiting to be programmed */ + if (blockInfo.base_addr != FLASH_INVALID_ADDRESS) + { + if (FlashWriteBlock(&blockInfo) == BLT_FALSE) + { + return BLT_FALSE; + } + } + /* still here so all is okay */ + return BLT_TRUE; +} /*** end of FlashDone ***/ + + +/**************************************************************************************** +** NAME: FlashInitBlock +** PARAMETER: block pointer to flash block info structure to operate on. +** address base address of the block data. +** RETURN VALUE: BLT_TRUE is succesful, BLT_FALSE otherwise. +** DESCRIPTION: Copies data currently in flash to the block->data and sets the +** base address. +** +****************************************************************************************/ +static blt_bool FlashInitBlock(tFlashBlockInfo *block, blt_addr address) +{ + /* check address alignment */ + if ((address % FLASH_WRITE_BLOCK_SIZE) != 0) + { + return BLT_FALSE; + } + /* make sure that we are initializing a new block and not the same one */ + if (block->base_addr == address) + { + /* block already initialized, so nothing to do */ + return BLT_TRUE; + } + /* set the base address and copies the current data from flash */ + block->base_addr = address; + CpuMemCopy((blt_addr)block->data, address, FLASH_WRITE_BLOCK_SIZE); + return BLT_TRUE; +} /*** end of FlashInitBlock ***/ + + +/**************************************************************************************** +** NAME: FlashSwitchBlock +** PARAMETER: block pointer to flash block info structure to operate on. +** base_addr base address for the next block +** RETURN VALUE: the pointer of the block info struct that is no being used, or a NULL +** pointer in case of error. +** DESCRIPTION: Switches blocks by programming the current one and initializing the +** next. +** +****************************************************************************************/ +static tFlashBlockInfo *FlashSwitchBlock(tFlashBlockInfo *block, blt_addr base_addr) +{ + /* check if a switch needs to be made away from the boot block. in this case the boot + * block shouldn't be written yet, because this is done at the end of the programming + * session by FlashDone(), this is right after the checksum was written. + */ + if (block == &bootBlockInfo) + { + /* switch from the boot block to the generic block info structure */ + block = &blockInfo; + } + /* check if a switch back into the bootblock is needed. in this case the generic block + * doesn't need to be written here yet. + */ + else if (base_addr == flashLayout[0].sector_start) + { + /* switch from the generic block to the boot block info structure */ + block = &bootBlockInfo; + base_addr = flashLayout[0].sector_start; + } + else + { + /* need to switch to a new block, so program the current one and init the next */ + if (FlashWriteBlock(block) == BLT_FALSE) + { + return BLT_NULL; + } + } + + /* initialize tne new block when necessary */ + if (FlashInitBlock(block, base_addr) == BLT_FALSE) + { + return BLT_NULL; + } + + /* still here to all is okay */ + return block; +} /*** end of FlashSwitchBlock ***/ + + +/**************************************************************************************** +** NAME: FlashAddToBlock +** PARAMETER: block pointer to flash block info structure to operate on. +** address flash destination address +** data pointer to the byte array with data +** len number of bytes to add to the block +** RETURN VALUE: BLT_TRUE if successful, BLT_FALSE otherwise. +** DESCRIPTION: Programming is done per block. This function adds data to the block +** that is currently collecting data to be written to flash. If the +** address is outside of the current block, the current block is written +** to flash an a new block is initialized. +** +****************************************************************************************/ +static blt_bool FlashAddToBlock(tFlashBlockInfo *block, blt_addr address, + blt_int8u *data, blt_int16u len) +{ + blt_addr current_base_addr; + blt_int8u *dst; + blt_int8u *src; + + /* determine the current base address */ + current_base_addr = (address/FLASH_WRITE_BLOCK_SIZE)*FLASH_WRITE_BLOCK_SIZE; + + /* make sure the blockInfo is not uninitialized */ + if (block->base_addr == FLASH_INVALID_ADDRESS) + { + /* initialize the blockInfo struct for the current block */ + if (FlashInitBlock(block, current_base_addr) == BLT_FALSE) + { + return BLT_FALSE; + } + } + + /* check if the new data fits in the current block */ + if (block->base_addr != current_base_addr) + { + /* need to switch to a new block, so program the current one and init the next */ + block = FlashSwitchBlock(block, current_base_addr); + if (block == BLT_NULL) + { + return BLT_FALSE; + } + } + + /* add the data to the current block, but check for block overflow */ + dst = &(block->data[address - block->base_addr]); + src = data; + do + { + /* keep the watchdog happy */ + CopService(); + /* buffer overflow? */ + if ((blt_addr)(dst-&(block->data[0])) >= FLASH_WRITE_BLOCK_SIZE) + { + /* need to switch to a new block, so program the current one and init the next */ + block = FlashSwitchBlock(block, current_base_addr+FLASH_WRITE_BLOCK_SIZE); + if (block == BLT_NULL) + { + return BLT_FALSE; + } + /* reset destination pointer */ + dst = &(block->data[0]); + } + /* write the data to the buffer */ + *dst = *src; + /* update pointers */ + dst++; + src++; + /* decrement byte counter */ + len--; + } + while (len > 0); + /* still here so all is good */ + return BLT_TRUE; +} /*** end of FlashAddToBlock ***/ + + +/**************************************************************************************** +** NAME: FlashWriteBlock +** PARAMETER: block pointer to flash block info structure to operate on. +** RETURN VALUE: BLT_TRUE if successful, BLT_FALSE otherwise. +** DESCRIPTION: Programs FLASH_WRITE_BLOCK_SIZE bytes to flash from the block->data +** array. +** +****************************************************************************************/ +static blt_bool FlashWriteBlock(tFlashBlockInfo *block) +{ + blt_int32u iap_command[5]; + blt_int32u iap_result[3]; + blt_int8u sector_num; + pIapHandler iapHandler = (void *)IAP_ENTRY_ADDRESS; + + /* check that address is actually within flash */ + sector_num = FlashGetSector(block->base_addr); + if (sector_num == FLASH_INVALID_SECTOR) + { + return BLT_FALSE; + } + /* send the prepare sector command for just this one sector */ + iap_command[0] = IAP_CMD_PREPARE_SECTORS; + iap_command[1] = sector_num; + iap_command[2] = sector_num; + iap_result[0] = !IAP_CMD_SUCCESS; + /* service the watchdog before calling the IAP handler */ + CopService(); + iapHandler(iap_command, iap_result); + if (iap_result[0] != IAP_CMD_SUCCESS) + { + return BLT_FALSE; + } + /* send the erase sector command */ + iap_command[0] = IAP_CMD_COPY_RAM_TO_FLASH; + iap_command[1] = (blt_int32u)block->base_addr; + iap_command[2] = (blt_int32u)block->data; + iap_command[3] = FLASH_WRITE_BLOCK_SIZE; + iap_command[4] = BOOT_CPU_SYSTEM_SPEED_KHZ; + iap_result[0] = !IAP_CMD_SUCCESS; + /* service the watchdog before calling the IAP handler */ + CopService(); + iapHandler(iap_command, iap_result); + if (iap_result[0] != IAP_CMD_SUCCESS) + { + return BLT_FALSE; + } + /* perform a comparison for verification purposes */ + iap_command[0] = IAP_CMD_COMPARE; + iap_command[1] = (blt_int32u)block->base_addr; + iap_command[2] = (blt_int32u)block->data; + iap_command[3] = FLASH_WRITE_BLOCK_SIZE; + iap_result[0] = !IAP_CMD_SUCCESS; + /* service the watchdog before calling the IAP handler */ + CopService(); + iapHandler(iap_command, iap_result); + if (iap_result[0] != IAP_CMD_SUCCESS) + { + return BLT_FALSE; + } + /* still here so all is okay */ + return BLT_TRUE; + +} /*** end of FlashWriteBlock ***/ + + +/**************************************************************************************** +** NAME: FlashEraseSectors +** PARAMETER: first_sector first flash sector number +** last_sector last flash sector number +** RETURN VALUE: BLT_TRUE if successful, BLT_FALSE otherwise. +** DESCRIPTION: Erases the flash sectors from first_sector up until last_sector +** +****************************************************************************************/ +static blt_bool FlashEraseSectors(blt_int8u first_sector, blt_int8u last_sector) +{ + blt_int32u iap_command[5]; + blt_int32u iap_result[3]; + pIapHandler iapHandler = (void *)IAP_ENTRY_ADDRESS; + + /* validate the sector numbers */ + if (first_sector > last_sector) + { + return BLT_FALSE; + } + if ( (first_sector < flashLayout[0].sector_num) || \ + (last_sector > flashLayout[FLASH_TOTAL_SECTORS-1].sector_num) ) + { + return BLT_FALSE; + } + + /* send the prepare sector command for just this one sector */ + iap_command[0] = IAP_CMD_PREPARE_SECTORS; + iap_command[1] = first_sector; + iap_command[2] = last_sector; + iap_result[0] = !IAP_CMD_SUCCESS; + /* service the watchdog before calling the IAP handler */ + CopService(); + iapHandler(iap_command, iap_result); + if (iap_result[0] != IAP_CMD_SUCCESS) + { + return BLT_FALSE; + } + /* send the erase sector command */ + iap_command[0] = IAP_CMD_ERASE_SECTORS; + iap_command[1] = first_sector; + iap_command[2] = last_sector; + iap_command[3] = BOOT_CPU_SYSTEM_SPEED_KHZ; + iap_result[0] = !IAP_CMD_SUCCESS; + /* service the watchdog before calling the IAP handler */ + CopService(); + iapHandler(iap_command, iap_result); + if (iap_result[0] != IAP_CMD_SUCCESS) + { + return BLT_FALSE; + } + /* perform a blank check for verification purposes */ + iap_command[0] = IAP_CMD_BLANK_CHECK_SECTORS ; + iap_command[1] = first_sector; + iap_command[2] = last_sector; + iap_result[0] = !IAP_CMD_SUCCESS; + /* service the watchdog before calling the IAP handler */ + CopService(); + iapHandler(iap_command, iap_result); + if (iap_result[0] != IAP_CMD_SUCCESS) + { + return BLT_FALSE; + } + /* still here so all went okay */ + return BLT_TRUE; +} /*** end of FlashEraseSectors ***/ + + +/**************************************************************************************** +** NAME: FlashGetSector +** PARAMETER: address address in the flash sector +** RETURN VALUE: flash sector number or FLASH_INVALID_SECTOR +** DESCRIPTION: Determines the flash sector the address is in. +** +****************************************************************************************/ +static blt_int8u FlashGetSector(blt_addr address) +{ + blt_int8u sectorIdx; + + /* search through the sectors to find the right one */ + for (sectorIdx = 0; sectorIdx < FLASH_TOTAL_SECTORS; sectorIdx++) + { + /* keep the watchdog happy */ + CopService(); + /* is the address in this sector? */ + if ( (address >= flashLayout[sectorIdx].sector_start) && \ + (address < (flashLayout[sectorIdx].sector_start + \ + flashLayout[sectorIdx].sector_size)) ) + { + /* return the sector number */ + return flashLayout[sectorIdx].sector_num; + } + } + /* still here so no valid sector found */ + return FLASH_INVALID_SECTOR; +} /*** end of FlashGetSector ***/ + + +/*********************************** end of flash.c ************************************/ diff --git a/Target/Source/ARM7_LPC2000/GCC/flash.h b/Target/Source/ARM7_LPC2000/GCC/flash.h new file mode 100644 index 00000000..9cae116f --- /dev/null +++ b/Target/Source/ARM7_LPC2000/GCC/flash.h @@ -0,0 +1,46 @@ +/**************************************************************************************** +| Description: bootloader flash driver header file +| File Name: flash.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef FLASH_H +#define FLASH_H + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void FlashInit(void); +blt_bool FlashWrite(blt_addr addr, blt_int32u len, blt_int8u *data); +blt_bool FlashErase(blt_addr addr, blt_int32u len); +blt_bool FlashWriteChecksum(void); +blt_bool FlashVerifyChecksum(void); +blt_bool FlashDone(void); + + +#endif /* FLASH_H */ +/*********************************** end of flash.h ************************************/ diff --git a/Target/Source/ARM7_LPC2000/GCC/memory.x b/Target/Source/ARM7_LPC2000/GCC/memory.x new file mode 100644 index 00000000..a31919b0 --- /dev/null +++ b/Target/Source/ARM7_LPC2000/GCC/memory.x @@ -0,0 +1,54 @@ +/* identify the Entry Point */ +ENTRY(_startup) + +/* specify the LPC2xxx memory areas. note that the RAM is configured to be only 8kb. this is + * the smallest in the LPC2xxx series, making this memory layout compatible with all devices + * in this serie of microcontrollers. + */ +MEMORY +{ + flash : ORIGIN = 0x00000000, LENGTH = 16K /* FLASH ROM reserved for the bootloader */ + ram_vectors(A) : ORIGIN = 0x40000000, LENGTH = 64 /* RAM vectors of the user program */ + ram_monitor(A) : ORIGIN = 0x40000040, LENGTH = 224 /* variables used by Philips RealMonitor */ + ram_isp_low(A) : ORIGIN = 0x40000120, LENGTH = 224 /* variables used by Philips ISP bootloader */ + ram : ORIGIN = 0x40000200, LENGTH = 7392 /* free RAM area */ + ram_isp_high(A) : ORIGIN = 0x40001EE0, LENGTH = 288 /* variables used by Philips ISP bootloader */ +} + +/* define a global symbol _stack_end, placed at the very end of unused RAM */ +_stack_end = 0x40001EE0 - 4; + +/* now define the output sections */ +SECTIONS +{ + . = 0; /* set location counter to address zero */ + startup : { *(.startup)} >flash /* the startup code goes into FLASH */ + + .text : /* collect all sections that should go into FLASH after startup */ + { + *(.text) /* all .text sections (code) */ + *(.rodata) /* all .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* all .rodata* sections (constants, strings, etc.) */ + *(.glue_7) /* all .glue_7 sections (no idea what these are) */ + *(.glue_7t) /* all .glue_7t sections (no idea what these are) */ + _etext = .; /* define a global symbol _etext just after the last code byte */ + } >flash /* put all the above into FLASH */ + + .data : /* collect all initialized .data sections that go into RAM */ + { + _data = .; /* create a global symbol marking the start of the .data section */ + *(.data) /* all .data sections */ + _edata = .; /* define a global symbol marking the end of the .data section */ + } >ram AT >flash /* put all the above into RAM (but load the LMA copy into FLASH) */ + + .bss : /* collect all uninitialized .bss sections that go into RAM */ + { + _bss_start = .; /* define a global symbol marking the start of the .bss section */ + *(.bss) /* all .bss sections */ + } >ram /* put all the above in RAM (it will be cleared in the startup code */ + + . = ALIGN(4); /* advance location counter to the next 32-bit boundary */ + _bss_end = . ; /* define a global symbol marking the end of the .bss section */ +} + _end = .; /* define a global symbol marking the end of application RAM */ + diff --git a/Target/Source/ARM7_LPC2000/GCC/vectors.c b/Target/Source/ARM7_LPC2000/GCC/vectors.c new file mode 100644 index 00000000..7ea10d06 --- /dev/null +++ b/Target/Source/ARM7_LPC2000/GCC/vectors.c @@ -0,0 +1,88 @@ +/**************************************************************************************** +| Description: bootloader interrupt vectors source file +| File Name: vectors.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void __attribute__ ((interrupt("FIQ"))) FIQ_ISR(void); +void __attribute__ ((interrupt("IRQ"))) IRQ_ISR(void); +void __attribute__ ((interrupt("UNDEF"))) UNDEF_ISR(void); + + +/**************************************************************************************** +** NAME: FIQ_ISR +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: FIQ exception routine. +** +****************************************************************************************/ +void FIQ_ISR(void) +{ + /* unexpected interrupt so trigger assertion */ + ASSERT_RT(BLT_FALSE); +} /*** end of FIQ_ISR ***/ + + +/**************************************************************************************** +** NAME: IRQ_ISR +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: IRQ exception routine. +** +****************************************************************************************/ +void IRQ_ISR(void) +{ + /* unexpected interrupt so trigger assertion */ + ASSERT_RT(BLT_FALSE); +} /*** end of IRQ_ISR ***/ + + +/**************************************************************************************** +** NAME: UNDEF_ISR +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: UNDEF exception routine. +** +****************************************************************************************/ +void UNDEF_ISR(void) +{ + /* unexpected interrupt so trigger assertion */ + ASSERT_RT(BLT_FALSE); +} /*** end of UNDEF_ISR ***/ + + +/*********************************** end of vectors.c **********************************/ diff --git a/Target/Source/ARM7_LPC2000/can.c b/Target/Source/ARM7_LPC2000/can.c new file mode 100644 index 00000000..91e07874 --- /dev/null +++ b/Target/Source/ARM7_LPC2000/can.c @@ -0,0 +1,253 @@ +/**************************************************************************************** +| Description: bootloader CAN communication interface source file +| File Name: can.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ + + +#if (BOOT_COM_CAN_ENABLE > 0) +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +#define CAN_TBS1 (0x00000004) /* transmit buffer 1 idle */ +#define CAN_TCS1 (0x00000008) /* transmit buffer 1 complete */ +#define CAN_RRB (0x04) /* receive buffer release */ +#define CAN_RBS (0x01) /* receive buffer status */ +#define CAN_TR (0x01) /* transmission request */ +#define CAN_STB1 (0x20) /* select tx buffer 1 for transmit */ + + +/**************************************************************************************** +* Register definitions +****************************************************************************************/ +#define CANAFMR (*((volatile blt_int8u *) 0xE003C000)) +#define CAN1MOD (*((volatile blt_int32u *) 0xE0044000)) +#define CAN1IER (*((volatile blt_int32u *) 0xE0044010)) +#define CAN1GSR (*((volatile blt_int32u *) 0xE0044008)) +#define CAN1BTR (*((volatile blt_int32u *) 0xE0044014)) +#define CAN1TFI1 (*((volatile blt_int32u *) 0xE0044030)) +#define CAN1TID1 (*((volatile blt_int32u *) 0xE0044034)) +#define CAN1TDA1 (*((volatile blt_int32u *) 0xE0044038)) +#define CAN1TDB1 (*((volatile blt_int32u *) 0xE004403C)) +#define CAN1CMR (*((volatile blt_int32u *) 0xE0044004)) +#define CAN1SR (*((volatile blt_int32u *) 0xE004401C)) +#define CAN1RID (*((volatile blt_int32u *) 0xE0044024)) +#define CAN1RDA (*((volatile blt_int32u *) 0xE0044028)) +#define CAN1RDB (*((volatile blt_int32u *) 0xE004402C)) + + +/**************************************************************************************** +* Type definitions +****************************************************************************************/ +typedef struct t_can_bus_timing +{ + blt_int8u tseg1; /* CAN time segment 1 */ + blt_int8u tseg2; /* CAN time segment 2 */ +} tCanBusTiming; /* bus timing structure type */ + + +/**************************************************************************************** +* Local constant declarations +****************************************************************************************/ +/* According to the CAN protocol 1 bit-time can be made up of between 8..25 time quanta + * (TQ). The total TQ in a bit is SYNC + TSEG1 + TSEG2 with SYNC always being 1. + * The sample point is (SYNC + TSEG1) / (SYNC + TSEG1 + SEG2) * 100%. This array contains + * possible and valid time quanta configurations with a sample point between 68..78%. + */ +static const tCanBusTiming canTiming[] = +{ /* TQ | TSEG1 | TSEG2 | SP */ + /* ------------------------- */ + { 5, 2 }, /* 8 | 5 | 2 | 75% */ + { 6, 2 }, /* 9 | 6 | 2 | 78% */ + { 6, 3 }, /* 10 | 6 | 3 | 70% */ + { 7, 3 }, /* 11 | 7 | 3 | 73% */ + { 8, 3 }, /* 12 | 8 | 3 | 75% */ + { 9, 3 }, /* 13 | 9 | 3 | 77% */ + { 9, 4 }, /* 14 | 9 | 4 | 71% */ + { 10, 4 }, /* 15 | 10 | 4 | 73% */ + { 11, 4 }, /* 16 | 11 | 4 | 75% */ + { 12, 4 }, /* 17 | 12 | 4 | 76% */ + { 12, 5 }, /* 18 | 12 | 5 | 72% */ + { 13, 5 }, /* 19 | 13 | 5 | 74% */ + { 14, 5 }, /* 20 | 14 | 5 | 75% */ + { 15, 5 }, /* 21 | 15 | 5 | 76% */ + { 15, 6 }, /* 22 | 15 | 6 | 73% */ + { 16, 6 }, /* 23 | 16 | 6 | 74% */ + { 16, 7 }, /* 24 | 16 | 7 | 71% */ + { 16, 8 } /* 25 | 16 | 8 | 68% */ +}; + + +/**************************************************************************************** +** NAME: CanGetSpeedConfig +** PARAMETER: baud The desired baudrate in kbps. Valid values are 10..1000. +** btr Pointer to where the value for register CANxBTR will be stored. +** RETURN VALUE: BLT_TRUE if the CAN bustiming register values were found, BLT_FALSE +** otherwise. +** DESCRIPTION: Search algorithm to match the desired baudrate to a possible bus +** timing configuration. +** +****************************************************************************************/ +static blt_bool CanGetSpeedConfig(blt_int16u baud, blt_int32u *btr) +{ + blt_int16u prescaler; + blt_int8u cnt; + + /* loop through all possible time quanta configurations to find a match */ + for (cnt=0; cnt < sizeof(canTiming)/sizeof(canTiming[0]); cnt++) + { + if ((BOOT_CPU_SYSTEM_SPEED_KHZ % (baud*(canTiming[cnt].tseg1+canTiming[cnt].tseg2+1))) == 0) + { + /* compute the prescaler that goes with this TQ configuration */ + prescaler = BOOT_CPU_SYSTEM_SPEED_KHZ/(baud*(canTiming[cnt].tseg1+canTiming[cnt].tseg2+1)); + + /* make sure the prescaler is valid */ + if ( (prescaler > 0) && (prescaler <= 1024) ) + { + /* store the prescaler and bustiming register value */ + *btr = prescaler - 1; + *btr |= ((canTiming[cnt].tseg2 - 1) << 20) | ((canTiming[cnt].tseg1 - 1) << 16); + /* found a good bus timing configuration */ + return BLT_TRUE; + } + } + } + /* could not find a good bus timing configuration */ + return BLT_FALSE; +} /*** end of CanGetSpeedConfig ***/ + + +/**************************************************************************************** +** NAME: CanInit +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Initializes the CAN controller and synchronizes it to the CAN bus. +** +****************************************************************************************/ +void CanInit(void) +{ + blt_bool result; + blt_int32u btr_reg_value; + + /* the current implementation supports CAN1, which has channel index 0. throw an + * assertion error in case a different CAN channel is configured. + */ + ASSERT_CT(BOOT_COM_CAN_CHANNEL_INDEX == 0); + /* configure acceptance filter for bypass mode so it receives all messages */ + CANAFMR = 0x00000002L; + /* take CAN controller offline and go into reset mode */ + CAN1MOD = 1; + /* disable all interrupts. driver only needs to work in polling mode */ + CAN1IER = 0; + /* reset CAN controller status */ + CAN1GSR = 0; + /* configure the bittiming */ + result = CanGetSpeedConfig(BOOT_COM_CAN_BAUDRATE/1000, &btr_reg_value); + /* check that a valid baudrate configuration was found */ + ASSERT_RT(result == BLT_TRUE); + /* write the bittiming configuration to the register */ + CAN1BTR = btr_reg_value; + /* enter normal operating mode and synchronize to the CAN bus */ + CAN1MOD = 0; +} /*** end of CanInit ***/ + + +/**************************************************************************************** +** NAME: CanTransmitPacket +** PARAMETER: data pointer to byte array with data that it to be transmitted. +** len number of bytes that are to be transmitted. +** RETURN VALUE: none +** DESCRIPTION: Transmits a packet formatted for the communication interface. +** +****************************************************************************************/ +void CanTransmitPacket(blt_int8u *data, blt_int8u len) +{ + /* check that transmit buffer 1 is ready to accept a new message */ + ASSERT_RT((CAN1SR & CAN_TBS1) != 0); + /* write dlc and configure message as a standard message with 11-bit identifier */ + CAN1TFI1 = (len << 16); + /* write the message identifier */ + CAN1TID1 = BOOT_COM_CAN_TX_MSG_ID; + /* write the first set of 4 data bytes */ + CAN1TDA1 = (data[3] << 24) + (data[2] << 16) + (data[1] << 8) + data[0]; + /* write the second set of 4 data bytes */ + CAN1TDB1 = (data[7] << 24) + (data[6] << 16) + (data[5] << 8) + data[4]; + /* write transmission request for transmit buffer 1 */ + CAN1CMR = CAN_TR | CAN_STB1; + /* wait for transmit completion */ + while ((CAN1SR & CAN_TCS1) == 0) + { + /* keep the watchdog happy */ + CopService(); + } +} /*** end of CanTransmitPacket ***/ + + +/**************************************************************************************** +** NAME: CanReceivePacket +** PARAMETER: data pointer to byte array where the data is to be stored. +** RETURN VALUE: BLT_TRUE is a packet was received, BLT_FALSE otherwise. +** DESCRIPTION: Receives a communication interface packet if one is present. +** +****************************************************************************************/ +blt_bool CanReceivePacket(blt_int8u *data) +{ + /* check if a new message was received */ + if ((CAN1SR & CAN_RBS) == 0) + { + return BLT_FALSE; + } + /* see if this is the message identifier that we are interested in */ + if (CAN1RID != BOOT_COM_CAN_RX_MSG_ID) + { + return BLT_FALSE; + } + /* store the message data */ + data[0] = (blt_int8u)CAN1RDA; + data[1] = (blt_int8u)(CAN1RDA >> 8); + data[2] = (blt_int8u)(CAN1RDA >> 16); + data[3] = (blt_int8u)(CAN1RDA >> 24); + data[4] = (blt_int8u)CAN1RDB; + data[5] = (blt_int8u)(CAN1RDB >> 8); + data[6] = (blt_int8u)(CAN1RDB >> 16); + data[7] = (blt_int8u)(CAN1RDB >> 24); + /* release the receive buffer */ + CAN1CMR = CAN_RRB; + /* inform called that a new data was received */ + return BLT_TRUE; +} /*** end of CanReceivePacket ***/ +#endif /* BOOT_COM_CAN_ENABLE > 0 */ + + +/*********************************** end of can.c **************************************/ diff --git a/Target/Source/ARM7_LPC2000/can.h b/Target/Source/ARM7_LPC2000/can.h new file mode 100644 index 00000000..2a60a6f9 --- /dev/null +++ b/Target/Source/ARM7_LPC2000/can.h @@ -0,0 +1,45 @@ +/**************************************************************************************** +| Description: bootloader CAN communication interface header file +| File Name: can.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef CAN_H +#define CAN_H + +#if (BOOT_COM_CAN_ENABLE > 0) +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void CanInit(void); +void CanTransmitPacket(blt_int8u *data, blt_int8u len); +blt_bool CanReceivePacket(blt_int8u *data); +#endif /* BOOT_COM_CAN_ENABLE > 0 */ + + +#endif /* CAN_H */ +/*********************************** end of can.h **************************************/ diff --git a/Target/Source/ARM7_LPC2000/cpu.c b/Target/Source/ARM7_LPC2000/cpu.c new file mode 100644 index 00000000..7b8fec93 --- /dev/null +++ b/Target/Source/ARM7_LPC2000/cpu.c @@ -0,0 +1,138 @@ +/**************************************************************************************** +| Description: bootloader cpu module source file +| File Name: cpu.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ + + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +#define CPU_USER_PROG_VECTORS_START_ADDR ((blt_addr)0x00002000) +#define CPU_RAM_VECTORS_START_ADDR ((blt_addr)0x40000000) +#define CPU_VECTORS_TABLE_SIZE (64) + + +/**************************************************************************************** +* Register definitions +****************************************************************************************/ +#define MEMMAP (*((volatile blt_int32u *) 0xE01FC040)) + + +/**************************************************************************************** +* External functions +****************************************************************************************/ +extern void Reset_Handler(void); /* reset service routine in cstart.s */ + + +/**************************************************************************************** +** NAME: CpuStartUserProgram +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Starts the user program, if one is present. In this case this function +** does not return. +** +****************************************************************************************/ +void CpuStartUserProgram(void) +{ + void (*pProgResetHandler)(void); + + /* check if a user program is present by verifying the checksum */ + if (NvmVerifyChecksum() == BLT_FALSE) + { + /* not a valid user program so it cannot be started */ + return; + } + + /* copy the user program's interrupt vector table to RAM */ + CpuMemCopy(CPU_RAM_VECTORS_START_ADDR, CPU_USER_PROG_VECTORS_START_ADDR, \ + CPU_VECTORS_TABLE_SIZE); + + /* select RAM vector table */ + MEMMAP = 0x02; + + /* set the address where the bootloader needs to jump to */ + pProgResetHandler = (void*)CPU_RAM_VECTORS_START_ADDR; + + /* start the user program by acticating its reset interrupt service routine */ + pProgResetHandler(); +} /*** end of CpuStartUserProgram ***/ + + +/**************************************************************************************** +** NAME: CpuMemCopy +** PARAMETER: dest destination address for the data. +** src source address of the data. +** len length of the data in bytes. +** RETURN VALUE: none +** DESCRIPTION: Copies data from the source to the destination address. +** +****************************************************************************************/ +void CpuMemCopy(blt_addr dest, blt_addr src, blt_int16u len) +{ + blt_int8u *from, *to; + + /* set casted pointers */ + from = (blt_int8u *)src; + to = (blt_int8u *)dest; + + /* copy all bytes from source address to destination address */ + while(len-- > 0) + { + /* store byte value from source to destination */ + *to++ = *from++; + /* keep the watchdog happy */ + CopService(); + } +} /*** end of CpuMemCopy ***/ + + +/**************************************************************************************** +** NAME: CpuReset +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Perform a soft reset of the microcontroller by starting from the reset +** ISR. +** +****************************************************************************************/ +void CpuReset(void) +{ + /* perform a software reset by calling the reset ISR routine. note that this requires + * access to the processor status registers (PSRs), which works because the entire + * bootloader runs in supervisor mode. + */ + Reset_Handler(); +} /*** end of CpuReset ***/ + + +/*********************************** end of cpu.c **************************************/ diff --git a/Target/Source/ARM7_LPC2000/cpu.h b/Target/Source/ARM7_LPC2000/cpu.h new file mode 100644 index 00000000..3b558162 --- /dev/null +++ b/Target/Source/ARM7_LPC2000/cpu.h @@ -0,0 +1,44 @@ +/**************************************************************************************** +| Description: bootloader cpu module header file +| File Name: cpu.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef CPU_H +#define CPU_H + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void CpuStartUserProgram(void); +void CpuMemCopy(blt_addr dest, blt_addr src, blt_int16u len); +void CpuReset(void); + + +#endif /* CPU_H */ +/*********************************** end of cpu.h **************************************/ diff --git a/Target/Source/ARM7_LPC2000/nvm.c b/Target/Source/ARM7_LPC2000/nvm.c new file mode 100644 index 00000000..a6bc6040 --- /dev/null +++ b/Target/Source/ARM7_LPC2000/nvm.c @@ -0,0 +1,201 @@ +/**************************************************************************************** +| Description: bootloader non-volatile memory driver source file +| File Name: nvm.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ + + +/**************************************************************************************** +* Hook functions +****************************************************************************************/ +#if (BOOT_NVM_HOOKS_ENABLE > 0) +extern void NvmInitHook(void); +extern blt_int8u NvmWriteHook(blt_addr addr, blt_int32u len, blt_int8u *data); +extern blt_int8u NvmEraseHook(blt_addr addr, blt_int32u len); +extern blt_bool NvmDoneHook(void); +#endif + + +/**************************************************************************************** +** NAME: NvmInit +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Initializes the NVM driver. +** +****************************************************************************************/ +void NvmInit(void) +{ +#if (BOOT_NVM_HOOKS_ENABLE > 0) + /* give the application a chance to initialize a driver for operating on NVM + * that is not by default supported by this driver. + */ + NvmInitHook(); +#endif + + /* init the internal driver */ + FlashInit(); +} /*** end of NvmInit ***/ + + +/**************************************************************************************** +** NAME: NvmWrite +** PARAMETER: addr start address +** len length in bytes +** data pointer to the data buffer. +** RETURN VALUE: BLT_TRUE if successful, BLT_FALSE otherwise. +** DESCRIPTION: Programs the non-volatile memory. +** +****************************************************************************************/ +blt_bool NvmWrite(blt_addr addr, blt_int32u len, blt_int8u *data) +{ +#if (BOOT_NVM_HOOKS_ENABLE > 0) + blt_int8u result = BTL_NVM_NOT_IN_RANGE; +#endif + +#if (BOOT_NVM_HOOKS_ENABLE > 0) + /* give the application a chance to operate on memory that is not by default supported + * by this driver. + */ + result = NvmWriteHook(addr, len, data); + + /* process the return code */ + if (result == BTL_NVM_OKAY) + { + /* data was within range of the additionally supported memory and succesfully + * programmed, so we are all done. + */ + return BLT_TRUE; + } + else if (result == BTL_NVM_ERROR) + { + /* data was within range of the additionally supported memory and attempted to be + * programmed, but an error occurred, so we can't continue. + */ + return BLT_FALSE; + } +#endif + + /* still here to the internal driver should try and perform the program operation */ + return FlashWrite(addr, len, data); +} /*** end of NvmWrite ***/ + + +/**************************************************************************************** +** NAME: NvmErase +** PARAMETER: addr start address +** len length in bytes +** RETURN VALUE: BLT_TRUE if successful, BLT_FALSE otherwise. +** DESCRIPTION: Erases the non-volatile memory. +** +****************************************************************************************/ +blt_bool NvmErase(blt_addr addr, blt_int32u len) +{ +#if (BOOT_NVM_HOOKS_ENABLE > 0) + blt_int8u result = BTL_NVM_NOT_IN_RANGE; +#endif + +#if (BOOT_NVM_HOOKS_ENABLE > 0) + /* give the application a chance to operate on memory that is not by default supported + * by this driver. + */ + result = NvmEraseHook(addr, len); + + /* process the return code */ + if (result == BTL_NVM_OKAY) + { + /* address was within range of the additionally supported memory and succesfully + * erased, so we are all done. + */ + return BLT_TRUE; + } + else if (result == BTL_NVM_ERROR) + { + /* address was within range of the additionally supported memory and attempted to be + * erased, but an error occurred, so we can't continue. + */ + return BLT_FALSE; + } +#endif + + /* still here to the internal driver should try and perform the erase operation */ + return FlashErase(addr, len); +} /*** end of NvmErase ***/ + + +/**************************************************************************************** +** NAME: NvmVerifyChecksum +** PARAMETER: none +** RETURN VALUE: BLT_TRUE is successful, BTL_FALSE otherwise. +** DESCRIPTION: Verifies the checksum, which indicates that a valid user program is +** present and can be started. +** +****************************************************************************************/ +blt_bool NvmVerifyChecksum(void) +{ + /* check checksum */ + return FlashVerifyChecksum(); +} /*** end of NvmVerifyChecksum ***/ + + +/**************************************************************************************** +** NAME: NvmDone +** PARAMETER: none +** RETURN VALUE: BLT_TRUE is successful, BLT_FALSE otherwise. +** DESCRIPTION: Once all erase and programming operations are completed, this +** function is called, so at the end of the programming session and +** right before a software reset is performed. It is used to calculate +** a checksum and program this into flash. This checksum is later used +** to determine if a valid user program is present in flash. +** +****************************************************************************************/ +blt_bool NvmDone(void) +{ +#if (BOOT_NVM_HOOKS_ENABLE > 0) + /* give the application's NVM driver a chance to finish up */ + if (NvmDoneHook() == BLT_FALSE) + { + /* error so no need to continue */ + return BLT_FALSE; + } +#endif + /* compute and write checksum, which is programmed by the internal driver */ + if (FlashWriteChecksum() == BLT_FALSE) + { + return BLT_FALSE; + } + /* finish up internal driver operations */ + return FlashDone(); +} /*** end of NvmDone ***/ + + +/*********************************** end of nvm.c **************************************/ diff --git a/Target/Source/ARM7_LPC2000/nvm.h b/Target/Source/ARM7_LPC2000/nvm.h new file mode 100644 index 00000000..943ca0a2 --- /dev/null +++ b/Target/Source/ARM7_LPC2000/nvm.h @@ -0,0 +1,60 @@ +/**************************************************************************************** +| Description: bootloader non-volatile memory driver header file +| File Name: nvm.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef NVM_H +#define NVM_H + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "flash.h" /* LPC2xxx flash driver */ + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void NvmInit(void); +blt_bool NvmWrite(blt_addr addr, blt_int32u len, blt_int8u *data); +blt_bool NvmErase(blt_addr addr, blt_int32u len); +blt_bool NvmVerifyChecksum(void); +blt_bool NvmDone(void); + + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +/* return codes for hook function NvmWrite/Erase */ +#define BTL_NVM_ERROR (0x00) /* return code for success */ +#define BTL_NVM_OKAY (0x01) /* return code for error */ +#define BTL_NVM_NOT_IN_RANGE (0x02) /* return code for not in range */ + + +#endif /* NVM_H */ +/*********************************** end of nvm.h **************************************/ diff --git a/Target/Source/ARM7_LPC2000/timer.c b/Target/Source/ARM7_LPC2000/timer.c new file mode 100644 index 00000000..d8943a77 --- /dev/null +++ b/Target/Source/ARM7_LPC2000/timer.c @@ -0,0 +1,152 @@ +/**************************************************************************************** +| Description: bootloader timer driver source file +| File Name: timer.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ + + +/**************************************************************************************** +* Local data declarations +****************************************************************************************/ +static blt_int32u free_running_counter_last; +static blt_int32u millisecond_counter; + + +/**************************************************************************************** +* Register definitions +****************************************************************************************/ +#define T0MCR (*((volatile blt_int32u *) 0xE0004014)) +#define T0CCR (*((volatile blt_int32u *) 0xE0004028)) +#define T0PR (*((volatile blt_int32u *) 0xE000400C)) +#define T0PC (*((volatile blt_int32u *) 0xE0004010)) +#define T0TCR (*((volatile blt_int32u *) 0xE0004004)) +#define T0TC (*((volatile blt_int32u *) 0xE0004008)) + + +/**************************************************************************************** +** NAME: TimerInit +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Initializes the polling based millisecond timer driver. +** +****************************************************************************************/ +void TimerInit(void) +{ + /* disable timer 0 interrupts */ + T0MCR = 0x00; + T0CCR = 0x00; + /* set prescaler so that free running counter runs at 1 kHz */ + T0PR = BOOT_CPU_SYSTEM_SPEED_KHZ - 1; + /* start free running counter for timer 0 */ + T0TCR = 0x01; + /* store the start value of the free running counter */ + free_running_counter_last = T0TC; + /* reset the millisecond counter value */ + TimerSet(0); +} /*** end of TimerInit ***/ + + +/**************************************************************************************** +** NAME: TimerReset +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Reset the timer by placing the timer back into it's default reset +** configuration. +** +****************************************************************************************/ +void TimerReset(void) +{ + /* reset the timer */ + T0TCR = 0; + /* reset the prescaler */ + T0PR = 0; + /* reset the timer counter */ + T0TC = 0; + /* reset the prescaled counter */ + T0PC = 0; +} /* TimerReset */ + + +/**************************************************************************************** +** NAME: TimerUpdate +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Updates the millisecond timer. +** +****************************************************************************************/ +void TimerUpdate(void) +{ + blt_int32u free_running_counter_now; + + /* update the millisecond counter */ + free_running_counter_now = T0TC; + millisecond_counter += (free_running_counter_now - free_running_counter_last); + /* store current free running counter value for next time around */ + free_running_counter_last = free_running_counter_now; +} /*** end of TimerUpdate ***/ + + +/**************************************************************************************** +** NAME: TimerSet +** PARAMETER: timer_value initialize value of the millisecond timer. +** RETURN VALUE: none +** DESCRIPTION: Sets the initial counter value of the millisecond timer. +** +****************************************************************************************/ +void TimerSet(blt_int32u timer_value) +{ + /* set the millisecond counter value */ + millisecond_counter = timer_value; +} /*** end of TimerSet ***/ + + +/**************************************************************************************** +** NAME: TimerGet +** PARAMETER: none +** RETURN VALUE: current value of the millisecond timer +** DESCRIPTION: Obtains the counter value of the millisecond timer. +** +****************************************************************************************/ +blt_int32u TimerGet(void) +{ + /* updating timer here allows this function to be called in a loop with timeout + * detection. + */ + TimerUpdate(); + + /* read and return the amount of milliseconds that passed since initialization */ + return millisecond_counter; +} /*** end of TimerGet ***/ + + +/*********************************** end of timer.c ************************************/ diff --git a/Target/Source/ARM7_LPC2000/timer.h b/Target/Source/ARM7_LPC2000/timer.h new file mode 100644 index 00000000..9e7f7e8c --- /dev/null +++ b/Target/Source/ARM7_LPC2000/timer.h @@ -0,0 +1,45 @@ +/**************************************************************************************** +| Description: bootloader timer driver header file +| File Name: timer.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef TIMER_H +#define TIMER_H + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void TimerInit(void); +void TimerUpdate(void); +void TimerSet(blt_int32u timer_value); +blt_int32u TimerGet(void); +void TimerReset(void); + + +#endif /* TIMER_H */ +/*********************************** end of timer.h ************************************/ diff --git a/Target/Source/ARM7_LPC2000/types.h b/Target/Source/ARM7_LPC2000/types.h new file mode 100644 index 00000000..339a0f20 --- /dev/null +++ b/Target/Source/ARM7_LPC2000/types.h @@ -0,0 +1,58 @@ +/**************************************************************************************** +| Description: bootloader types header file +| File Name: types.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef TYPES_H +#define TYPES_H + + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +#define BLT_TRUE (1) +#define BLT_FALSE (0) +#define BLT_NULL ((void *)0) + + +/**************************************************************************************** +* Type definitions +****************************************************************************************/ +typedef unsigned char blt_bool; /* boolean type */ +typedef char blt_char; /* character type */ +typedef unsigned long blt_addr; /* memory address type */ +typedef unsigned char blt_int8u; /* 8-bit unsigned integer */ +typedef signed char blt_int8s; /* 8-bit signed integer */ +typedef unsigned short blt_int16u; /* 16-bit unsigned integer */ +typedef signed short blt_int16s; /* 16-bit signed integer */ +typedef unsigned int blt_int32u; /* 32-bit unsigned integer */ +typedef signed int blt_int32s; /* 32-bit signed integer */ + + +#endif /* TYPES_H */ +/*********************************** end of types.h ************************************/ diff --git a/Target/Source/ARM7_LPC2000/uart.c b/Target/Source/ARM7_LPC2000/uart.c new file mode 100644 index 00000000..4bb19095 --- /dev/null +++ b/Target/Source/ARM7_LPC2000/uart.c @@ -0,0 +1,251 @@ +/**************************************************************************************** +| Description: bootloader UART communication interface source file +| File Name: uart.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ + + +#if (BOOT_COM_UART_ENABLE > 0) +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +#define UART_DLAB (0x80) /* divisor latch access bit */ +#define UART_MODE_8N1 (0x03) /* 8 data and 1 stop bit, no parity */ +#define UART_FIFO_RX1 (0x07) /* FIFO reset and RX FIFO 1 deep */ +#define UART_RDR (0x01) /* receiver data ready */ +#define UART_THRE (0x20) /* transmitter holding register empty */ + + +/**************************************************************************************** +* Register definitions +****************************************************************************************/ +#define U0RBR (*((volatile blt_int8u *) 0xE000C000)) +#define U0THR (*((volatile blt_int8u *) 0xE000C000)) +#define U0IER (*((volatile blt_int8u *) 0xE000C004)) +#define U0IIR (*((volatile blt_int8u *) 0xE000C008)) +#define U0FCR (*((volatile blt_int8u *) 0xE000C008)) +#define U0LCR (*((volatile blt_int8u *) 0xE000C00C)) +#define U0LSR (*((volatile blt_int8u *) 0xE000C014)) +#define U0SCR (*((volatile blt_int8u *) 0xE000C01C)) +#define U0DLL (*((volatile blt_int8u *) 0xE000C000)) +#define U0DLM (*((volatile blt_int8u *) 0xE000C004)) + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +static blt_bool UartReceiveByte(blt_int8u *data); +static blt_bool UartTransmitByte(blt_int8u data); + + +/**************************************************************************************** +** NAME: UartInit +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Initializes the UART communication interface +** +****************************************************************************************/ +void UartInit(void) +{ + blt_int32u baud_reg_value; /* baudrate register value */ + + /* the current implementation supports UART0. throw an assertion error in case + * a different UART channel is configured. + */ + ASSERT_CT(BOOT_COM_UART_CHANNEL_INDEX == 0); + /* disable UART related interrupt generation. this driver works in polling mode */ + U0IER = 0; + /* clear interrupt id register */ + U0IIR = 0; + /* clear line status register */ + U0LSR = 0; + /* set divisor latch DLAB = 1 so buadrate can be configured */ + U0LCR = UART_DLAB; + /* Baudrate calculation: + * y = BOOT_CPU_SYSTEM_SPEED_KHZ * 1000 / 16 / BOOT_COM_UART_BAUDRATE and add + * smartness to automatically round the value up/down using the following trick: + * y = x/n can round with y = (x + (n + 1)/2 ) / n + */ + /* check that baudrate register value is not 0 */ + ASSERT_CT((((BOOT_CPU_SYSTEM_SPEED_KHZ*1000/16)+((BOOT_COM_UART_BAUDRATE+1)/2))/ \ + BOOT_COM_UART_BAUDRATE) > 0); + /* check that baudrate register value is not greater than max 16-bit unsigned value */ + ASSERT_CT((((BOOT_CPU_SYSTEM_SPEED_KHZ*1000/16)+((BOOT_COM_UART_BAUDRATE+1)/2))/ \ + BOOT_COM_UART_BAUDRATE) <= 65535); + baud_reg_value = (((BOOT_CPU_SYSTEM_SPEED_KHZ*1000/16)+ \ + ((BOOT_COM_UART_BAUDRATE+1)/2))/BOOT_COM_UART_BAUDRATE); + /* write the calculated baudrate selector value to the registers */ + U0DLL = (blt_int8u)baud_reg_value; + U0DLM = (blt_int8u)(baud_reg_value >> 8); + /* configure 8 data bits, no parity and 1 stop bit and set DLAB = 0 */ + U0LCR = UART_MODE_8N1; + /* enable and reset transmit and receive FIFO. necessary for UART operation */ + U0FCR = UART_FIFO_RX1; +} /*** end of UartInit ***/ + + +/**************************************************************************************** +** NAME: UartTransmitPacket +** PARAMETER: data pointer to byte array with data that it to be transmitted. +** len number of bytes that are to be transmitted. +** RETURN VALUE: none +** DESCRIPTION: Transmits a packet formatted for the communication interface. +** +****************************************************************************************/ +void UartTransmitPacket(blt_int8u *data, blt_int8u len) +{ + blt_int16u data_index; + + /* verify validity of the len-paramenter */ + ASSERT_RT(len <= BOOT_COM_TX_MAX_DATA); + + /* first transmit the length of the packet */ + ASSERT_RT(UartTransmitByte(len) == BLT_TRUE); + + /* transmit all the packet bytes one-by-one */ + for (data_index = 0; data_index < len; data_index++) + { + /* keep the watchdog happy */ + CopService(); + /* write byte */ + ASSERT_RT(UartTransmitByte(data[data_index]) == BLT_TRUE); + } +} /*** end of UartTransmitPacket ***/ + + +/**************************************************************************************** +** NAME: UartReceivePacket +** PARAMETER: data pointer to byte array where the data is to be stored. +** RETURN VALUE: BLT_TRUE if a packet was received, BLT_FALSE otherwise. +** DESCRIPTION: Receives a communication interface packet if one is present. +** +****************************************************************************************/ +blt_bool UartReceivePacket(blt_int8u *data) +{ + static blt_int8u xcpCtoReqPacket[XCP_CTO_PACKET_LEN+1]; /* one extra for length */ + static blt_int8u xcpCtoRxLength; + static blt_bool xcpCtoRxInProgress = BLT_FALSE; + + /* start of cto packet received? */ + if (xcpCtoRxInProgress == BLT_FALSE) + { + /* store the message length when received */ + if (UartReceiveByte(&xcpCtoReqPacket[0]) == BLT_TRUE) + { + /* indicate that a cto packet is being received */ + xcpCtoRxInProgress = BLT_TRUE; + + /* reset packet data count */ + xcpCtoRxLength = 0; + } + } + else + { + /* store the next packet byte */ + if (UartReceiveByte(&xcpCtoReqPacket[xcpCtoRxLength+1]) == BLT_TRUE) + { + /* increment the packet data count */ + xcpCtoRxLength++; + + /* check to see if the entire packet was received */ + if (xcpCtoRxLength == xcpCtoReqPacket[0]) + { + /* copy the packet data */ + CpuMemCopy((blt_int32u)data, (blt_int32u)&xcpCtoReqPacket[1], xcpCtoRxLength); + /* done with cto packet reception */ + xcpCtoRxInProgress = BLT_FALSE; + + /* packet reception complete */ + return BLT_TRUE; + } + } + } + + /* packet reception not yet complete */ + return BLT_FALSE; +} /*** end of UartReceivePacket ***/ + + +/**************************************************************************************** +** NAME: UartReceiveByte +** PARAMETER: data pointer to byte where the data is to be stored. +** RETURN VALUE: BLT_TRUE if a byte was received, BLT_FALSE otherwise. +** DESCRIPTION: Receives a communication interface byte if one is present. +** +****************************************************************************************/ +static blt_bool UartReceiveByte(blt_int8u *data) +{ + /* check if a new byte was received by means of the RDR-bit */ + if((U0LSR & UART_RDR) != 0) + { + /* store the received byte */ + data[0] = U0RBR; + /* inform caller of the newly received byte */ + return BLT_TRUE; + } + /* inform caller that no new data was received */ + return BLT_FALSE; +} /*** end of UartReceiveByte ***/ + + +/**************************************************************************************** +** NAME: UartTransmitByte +** PARAMETER: data value of byte that is to be transmitted. +** RETURN VALUE: BLT_TRUE if the byte was transmitted, BLT_FALSE otherwise. +** DESCRIPTION: Transmits a communication interface byte. +** +****************************************************************************************/ +static blt_bool UartTransmitByte(blt_int8u data) +{ + /* check if tx holding register can accept new data and throw assertion error if not */ + if ((U0LSR & UART_THRE) == 0) + { + /* UART not ready. should not happen */ + return BLT_FALSE; + } + /* write byte to transmit holding register */ + U0THR = data; + /* wait for tx holding register to be empty */ + while((U0LSR & UART_THRE) == 0) + { + /* keep the watchdog happy */ + CopService(); + } + /* byte transmitted */ + return BLT_TRUE; +} /*** end of UartTransmitByte ***/ +#endif /* BOOT_COM_UART_ENABLE > 0 */ + + +/*********************************** end of uart.c *************************************/ diff --git a/Target/Source/ARM7_LPC2000/uart.h b/Target/Source/ARM7_LPC2000/uart.h new file mode 100644 index 00000000..9121ac81 --- /dev/null +++ b/Target/Source/ARM7_LPC2000/uart.h @@ -0,0 +1,45 @@ +/**************************************************************************************** +| Description: bootloader UART communication interface header file +| File Name: uart.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef UART_H +#define UART_H + +#if (BOOT_COM_UART_ENABLE > 0) +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void UartInit(void); +void UartTransmitPacket(blt_int8u *data, blt_int8u len); +blt_bool UartReceivePacket(blt_int8u *data); +#endif /* BOOT_COM_UART_ENABLE > 0 */ + + +#endif /* UART_H */ +/*********************************** end of uart.h *************************************/ diff --git a/Target/Source/assert.c b/Target/Source/assert.c new file mode 100644 index 00000000..1a56d4ec --- /dev/null +++ b/Target/Source/assert.c @@ -0,0 +1,70 @@ +/**************************************************************************************** +| Description: bootloader assertion module source file +| File Name: assert.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ + + +#ifndef NDEBUG +/**************************************************************************************** +* Local data declarations +****************************************************************************************/ +static volatile blt_char *assert_failure_file; +static volatile blt_int32u assert_failure_line; + + +/**************************************************************************************** +** NAME: AssertFailure +** PARAMETER: file name of the source file where the assertion occurred. +** line linenumber in the source file where the assertion occurred. +** RETURN VALUE: none +** DESCRIPTION: Called when a runtime assertion failed. It stores information about +** where the assertion occurred and halts the software program. +** +****************************************************************************************/ +void AssertFailure(blt_char *file, blt_int32u line) +{ + /* store the file string and line number so that it can be read on a breakpoint*/ + assert_failure_file = file; + assert_failure_line = line; + /* hang the software so that it requires a hard reset */ + for(;;) + { + /* keep servicing the watchdog so that this one does not cause a reset */ + CopService(); + } +} /*** end of AssertFailure ***/ +#endif /* !NDEBUG */ + + +/*********************************** end of assert.c ***********************************/ diff --git a/Target/Source/assert.h b/Target/Source/assert.h new file mode 100644 index 00000000..e366c445 --- /dev/null +++ b/Target/Source/assert.h @@ -0,0 +1,63 @@ +/**************************************************************************************** +| Description: bootloader assertion module header file +| File Name: assert.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef ASSERT_H +#define ASSERT_H + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +/* declare assertion macro's. ASSERT_CT is for compile time assertions and ASSERT_RT is + * for runtime assertions. + */ +#ifdef NDEBUG + #define ASSERT_CT(cond) ((void)0) + #define ASSERT_RT(cond) ((void)0) +#else + #define ASSERT_CONCAT_(a, b) a##b + #define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b) + #define ASSERT_CT(cond) enum { ASSERT_CONCAT(assert_error_on_line_, __LINE__) = 1/(!!(cond)) } + #define ASSERT_RT(cond) \ + if (cond) \ + { ; } \ + else \ + AssertFailure(__FILE__, __LINE__) +#endif /* NDEBUG */ + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +#ifndef NDEBUG +void AssertFailure(blt_char *file, blt_int32u line); +#endif + +#endif /* ASSERT_H */ +/*********************************** end of assert.h ***********************************/ diff --git a/Target/Source/backdoor.c b/Target/Source/backdoor.c new file mode 100644 index 00000000..84d0944f --- /dev/null +++ b/Target/Source/backdoor.c @@ -0,0 +1,135 @@ +/**************************************************************************************** +| Description: bootloader backdoor entry source file +| File Name: backdoor.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ + + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +#if (BOOT_BACKDOOR_HOOKS_ENABLE == 0) + /* set the time in milliseconds that the backdoor is open */ + #define BACKDOOR_ENTRY_TIMEOUT_MS (50) +#endif + +/**************************************************************************************** +* Hook functions +****************************************************************************************/ +#if (BOOT_BACKDOOR_HOOKS_ENABLE > 0) +void BackDoorInitHook(void); +blt_bool BackDoorEntryHook(void); +#endif + + +/**************************************************************************************** +* Local data declarations +****************************************************************************************/ +#if (BOOT_BACKDOOR_HOOKS_ENABLE == 0) +static blt_bool backdoorOpen; +#endif + + +/**************************************************************************************** +** NAME: BackDoorInit +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Initializes the backdoor entry option. +** +****************************************************************************************/ +void BackDoorInit(void) +{ +#if (BOOT_BACKDOOR_HOOKS_ENABLE > 0) + /* initialize application's backdoor functionality */ + BackDoorInitHook(); + + /* attempt to start the user program when no backdoor entry is requested or + * a pending COM module connection request. + */ + if ( (BackDoorEntryHook() == BLT_FALSE) && (ComIsConnectEntryState() == BLT_FALSE) ) + { + /* this function does not return if a valid user program is present */ + CpuStartUserProgram(); + } + +#else + /* open the backdoor after a reset */ + backdoorOpen = BLT_TRUE; + /* initialize default backdoor entry */ + TimerInit(); +#endif + /* perform the first check that open/closes the backdoor */ + BackDoorCheck(); +} /*** end of BackDoorInit ***/ + + +/**************************************************************************************** +** NAME: BackDoorCheck +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: The default backdoor entry feature keeps the bootloader active for a +** predetermined time after reset, allowing the host application to +** establish a connection and start a programming sequence. This function +** controls the opening/closing of the backdoor. +** +****************************************************************************************/ +void BackDoorCheck(void) +{ +#if (BOOT_BACKDOOR_HOOKS_ENABLE == 0) + /* check if a connection with the host was already established. in this case the + * backdoor stays open anyway, so no need to check if it needs to be closed + */ + if (ComIsConnected() == BLT_TRUE) + { + return; + } + + /* when the backdoor is still open, check if it's time to close it */ + if (backdoorOpen == BLT_TRUE) + { + /* check if the backdoor entry time window elapsed */ + if (TimerGet() >= BACKDOOR_ENTRY_TIMEOUT_MS) + { + /* close the backdoor */ + backdoorOpen = BLT_FALSE; + /* reset the timer */ + TimerReset(); + /* this function does not return if a valid user program is present */ + CpuStartUserProgram(); + } + } +#endif +} /*** end of BackDoorCheck ***/ + + +/*********************************** end of backdoor.c *********************************/ diff --git a/Target/Source/backdoor.h b/Target/Source/backdoor.h new file mode 100644 index 00000000..007cb48b --- /dev/null +++ b/Target/Source/backdoor.h @@ -0,0 +1,41 @@ +/**************************************************************************************** +| Description: bootloader backdoor entry header file +| File Name: backdoor.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef BACKDOOR_H +#define BACKDOOR_H + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void BackDoorInit(void); +void BackDoorCheck(void); + +#endif /* BACKDOOR_H */ +/*********************************** end of backdoor.h *********************************/ diff --git a/Target/Source/boot.c b/Target/Source/boot.c new file mode 100644 index 00000000..fb31811c --- /dev/null +++ b/Target/Source/boot.c @@ -0,0 +1,76 @@ +/**************************************************************************************** +| Description: bootloader core module source file +| File Name: boot.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ + + +/**************************************************************************************** +** NAME: BootInit +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Initializes the bootloader core. +** +****************************************************************************************/ +void BootInit(void) +{ + /* initialize the watchdog */ + CopInit(); + /* initialize the backdoor entry */ + BackDoorInit(); + /* initialize the non-volatile memory driver */ + NvmInit(); + /* initialize the communication module */ + ComInit(); +} /*** end of BootInit ***/ + + +/**************************************************************************************** +** NAME: BootTask +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Task function of the bootloader core that drives the program. +** +****************************************************************************************/ +void BootTask(void) +{ + /* service the watchdog */ + CopService(); + /* process possibly pending communication data */ + ComTask(); + /* control the backdoor */ + BackDoorCheck(); +} /*** end of BootTask ***/ + + +/*********************************** end of boot.c *************************************/ diff --git a/Target/Source/boot.h b/Target/Source/boot.h new file mode 100644 index 00000000..880004f7 --- /dev/null +++ b/Target/Source/boot.h @@ -0,0 +1,58 @@ +/**************************************************************************************** +| Description: bootloader core module header file +| File Name: boot.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef BOOT_H +#define BOOT_H + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "types.h" /* variable types */ +#include "assert.h" /* assertion checks */ +#include "config.h" /* bootloader configuration */ +#include "plausibility.h" /* plausibility checks */ +#include "cpu.h" /* cpu driver module */ +#include "cop.h" /* watchdog driver module */ +#include "nvm.h" /* memory driver module */ +#include "timer.h" /* timer driver module */ +#include "backdoor.h" /* backdoor entry module */ +#include "com.h" /* communication interface */ +#include "xcp.h" /* xcp communication layer */ + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void BootInit(void); +void BootTask(void); + + +#endif /* BOOT_H */ +/*********************************** end of boot.h *************************************/ diff --git a/Target/Source/com.c b/Target/Source/com.c new file mode 100644 index 00000000..805ade4e --- /dev/null +++ b/Target/Source/com.c @@ -0,0 +1,191 @@ +/**************************************************************************************** +| Description: bootloader communication interface source file +| File Name: com.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ +#if (BOOT_COM_CAN_ENABLE > 0) + #include "can.h" /* can driver module */ +#endif +#if (BOOT_COM_UART_ENABLE > 0) + #include "uart.h" /* uart driver module */ +#endif + + +/**************************************************************************************** +* Local data declarations +****************************************************************************************/ +/* This variable holds state information about the bootloader being started by a reset + * event or by an activation from a running user program. In the latter case, the COM + * interface should proceed after initialization as if it already received a connection + * request, which the running user program did before it activated the bootloader. It's + * volatile because some targets might call functions that access this variable from + * assembly, which might cause the C compiler to incorrectly remove this variable during + * an optimization step. + */ +static volatile blt_bool comEntryStateConnect = BLT_FALSE; + + +/**************************************************************************************** +** NAME: ComInit +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Initializes the communication module including the hardware needed for +** the communication. +** +****************************************************************************************/ +void ComInit(void) +{ + blt_int8u xcpCtoConnectCmdPacket[2] = { 0xff, 0x00 }; + + /* initialize the XCP communication protocol */ + XcpInit(); +#if (BOOT_COM_CAN_ENABLE > 0) + /* initialize the CAN controller */ + CanInit(); +#endif +#if (BOOT_COM_UART_ENABLE > 0) + /* initialize the UART interface */ + UartInit(); +#endif + /* simulate the reception of a CONNECT command if requested */ + if (comEntryStateConnect == BLT_TRUE) + { + XcpPacketReceived(&xcpCtoConnectCmdPacket[0]); + } +} /*** end of ComInit ***/ + + +/**************************************************************************************** +** NAME: ComTask +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Updates the communication module by checking if new data was received +** and submitting the request to process newly received data. +** +****************************************************************************************/ +void ComTask(void) +{ + /* make xcpCtoReqPacket static for runtime efficiency */ +#if (BOOT_COM_CAN_ENABLE > 0) + static unsigned char xcpCtoReqPacket[BOOT_COM_CAN_RX_MAX_DATA]; +#endif +#if (BOOT_COM_UART_ENABLE > 0) + static unsigned char xcpCtoReqPacket[BOOT_COM_UART_RX_MAX_DATA]; +#endif + +#if (BOOT_COM_CAN_ENABLE > 0) + if (CanReceivePacket(&xcpCtoReqPacket[0]) == BLT_TRUE) + { + /* process packet */ + XcpPacketReceived(&xcpCtoReqPacket[0]); + } +#endif +#if (BOOT_COM_UART_ENABLE > 0) + if (UartReceivePacket(&xcpCtoReqPacket[0]) == BLT_TRUE) + { + /* process packet */ + XcpPacketReceived(&xcpCtoReqPacket[0]); + } +#endif +} /*** end of ComTask ***/ + + +/**************************************************************************************** +** NAME: ComTransmitPacket +** PARAMETER: data pointer to the byte buffer with packet data. +** len number of data bytes that need to be transmitted. +** RETURN VALUE: none +** DESCRIPTION: Transmits the packet using the xcp transport layer. +** +****************************************************************************************/ +void ComTransmitPacket(blt_int8u *data, blt_int16u len) +{ +#if (BOOT_COM_CAN_ENABLE > 0) + /* transmit the packet. note that len can only be 8 on CAN, so cast is okay */ + CanTransmitPacket(data, (blt_int8u)len); +#endif +#if (BOOT_COM_UART_ENABLE > 0) + /* transmit the packet */ + UartTransmitPacket(data, len); +#endif + + /* send signal that the packet was transmitted */ + XcpPacketTransmitted(); +} /*** end of ComTransmitPacket ***/ + + +/**************************************************************************************** +** NAME: ComSetConnectEntryState +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: This function should be called by the function that is called to +** enter the bootloader from a running user program after the stack +** pointer, data section and bss section are initialized, but before +** function main is called. It stores state information that indicates +** that the COM module must be initialized in a connected state. +** +****************************************************************************************/ +void ComSetConnectEntryState(void) +{ + comEntryStateConnect = BLT_TRUE; +} /*** end of ComSetConnectEntryState ***/ + + +/**************************************************************************************** +** NAME: ComIsConnectEntryState +** PARAMETER: none +** RETURN VALUE: BLT_TRUE is there is a pending connection request, BLT_FALSE otherwise +** DESCRIPTION: This function checks if there is a pending request for a connection +** upon COM module initialization. +** +****************************************************************************************/ +blt_bool ComIsConnectEntryState(void) +{ + return comEntryStateConnect; +} /*** end of ComIsConnectEntryState ***/ + + +/**************************************************************************************** +** NAME: ComIsConnected +** PARAMETER: none +** RETURN VALUE: BLT_TRUE when an XCP connection is established, BLT_FALSE otherwise. +** DESCRIPTION: This function obtains the XCP connection state. +** +****************************************************************************************/ +blt_bool ComIsConnected(void) +{ + return XcpIsConnected(); +} /*** end of ComIsConnected ***/ + + +/*********************************** end of com.c **************************************/ diff --git a/Target/Source/com.h b/Target/Source/com.h new file mode 100644 index 00000000..9e80d429 --- /dev/null +++ b/Target/Source/com.h @@ -0,0 +1,63 @@ +/**************************************************************************************** +| Description: bootloader communication interface header file +| File Name: com.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef COM_H +#define COM_H + + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +#if (BOOT_COM_CAN_ENABLE > 0) + #define BOOT_COM_TX_MAX_DATA (BOOT_COM_CAN_TX_MAX_DATA) + #define BOOT_COM_RX_MAX_DATA (BOOT_COM_CAN_RX_MAX_DATA) +#endif +#if (BOOT_COM_UART_ENABLE > 0) + #define BOOT_COM_TX_MAX_DATA (BOOT_COM_UART_TX_MAX_DATA) + #define BOOT_COM_RX_MAX_DATA (BOOT_COM_UART_RX_MAX_DATA) +#endif + + + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void ComInit(void); +void ComTask(void); +void ComTransmitPacket(blt_int8u *data, blt_int16u len); +void ComSetConnectEntryState(void); +blt_bool ComIsConnectEntryState(void); +void ComSetConnected(blt_bool connected); +blt_bool ComIsConnected(void); + + +#endif /* COM_H */ +/*********************************** end of com.h **************************************/ diff --git a/Target/Source/cop.c b/Target/Source/cop.c new file mode 100644 index 00000000..f5c2904f --- /dev/null +++ b/Target/Source/cop.c @@ -0,0 +1,77 @@ +/**************************************************************************************** +| Description: bootloader watchdog module source file +| File Name: cop.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ + + +/**************************************************************************************** +* Hook functions +****************************************************************************************/ +#if (BOOT_COP_HOOKS_ENABLE > 0) +extern void CopInitHook(void); +extern void CopServiceHook(void); +#endif + + +/**************************************************************************************** +** NAME: CopInit +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Watchdog initialization function +** +****************************************************************************************/ +void CopInit(void) +{ +#if (BOOT_COP_HOOKS_ENABLE > 0) + CopInitHook(); +#endif +} /*** end of CopInit ***/ + + +/**************************************************************************************** +** NAME: CopService +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Watchdog service function to prevent the watchdog from timing out. +** +****************************************************************************************/ +void CopService(void) +{ +#if (BOOT_COP_HOOKS_ENABLE > 0) + CopServiceHook(); +#endif +} /*** end of CopService ***/ + + +/*********************************** end of cop.c **************************************/ diff --git a/Target/Source/cop.h b/Target/Source/cop.h new file mode 100644 index 00000000..b70a8af4 --- /dev/null +++ b/Target/Source/cop.h @@ -0,0 +1,42 @@ +/**************************************************************************************** +| Description: bootloader watchdog module header file +| File Name: cop.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef COP_H +#define COP_H + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void CopInit(void); +void CopService(void); + + +#endif /* COP_H */ +/*********************************** end of cop.h **************************************/ diff --git a/Target/Source/plausibility.h b/Target/Source/plausibility.h new file mode 100644 index 00000000..1ca171f8 --- /dev/null +++ b/Target/Source/plausibility.h @@ -0,0 +1,212 @@ +/**************************************************************************************** +| Description: bootloader plausibility check header file +| File Name: plausibility.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef PLAUSIBILITY_H +#define PLAUSIBILITY_H + +/**************************************************************************************** +* C P U D R I V E R C O N F I G U R A T I O N C H E C K +****************************************************************************************/ +#ifndef BOOT_CPU_XTAL_SPEED_KHZ +#error "BOOT_CPU_XTAL_SPEED_KHZ is missing in config.h" +#endif + +#if (BOOT_CPU_XTAL_SPEED_KHZ <= 0) +#error "BOOT_CPU_XTAL_SPEED_KHZ must be > 0" +#endif + +#ifndef BOOT_CPU_SYSTEM_SPEED_KHZ +#error "BOOT_CPU_SYSTEM_SPEED_KHZ is missing in config.h" +#endif + +#if (BOOT_CPU_SYSTEM_SPEED_KHZ <= 0) +#error "BOOT_CPU_SYSTEM_SPEED_KHZ must be > 0" +#endif + +#ifndef BOOT_CPU_BYTE_ORDER_MOTOROLA +#error "BOOT_CPU_BYTE_ORDER_MOTOROLA is missing in config.h" +#endif + +#if (BOOT_CPU_BYTE_ORDER_MOTOROLA < 0) || (BOOT_CPU_BYTE_ORDER_MOTOROLA > 1) +#error "BOOT_CPU_BYTE_ORDER_MOTOROLA must be 0 or 1" +#endif + + +/**************************************************************************************** +* C O M M U N I C A T I O N I N T E R F A C E C O N F I G U R A T I O N C H E C K +****************************************************************************************/ +#ifndef BOOT_COM_CAN_ENABLE +#define BOOT_COM_CAN_ENABLE (0) +#endif + +#if (BOOT_COM_CAN_ENABLE > 0) + #ifndef BOOT_COM_CAN_BAUDRATE + #error "BOOT_COM_CAN_BAUDRATE is missing in config.h" + #endif + + #if (BOOT_COM_CAN_BAUDRATE <= 0) + #error "BOOT_COM_CAN_BAUDRATE must be > 0" + #endif + + #ifndef BOOT_COM_CAN_TX_MSG_ID + #error "BOOT_COM_CAN_TX_MSG_ID is missing in config.h" + #endif + + #if (BOOT_COM_CAN_TX_MSG_ID <= 0) + #error "BOOT_COM_CAN_TX_MSG_ID must be > 0" + #endif + + #ifndef BOOT_COM_CAN_TX_MAX_DATA + #error "BOOT_COM_CAN_TX_MAX_DATA is missing in config.h" + #endif + + #if (BOOT_COM_CAN_TX_MAX_DATA <= 0) + #error "BOOT_COM_CAN_TX_MAX_DATA must be > 0" + #endif + + #ifndef BOOT_COM_CAN_RX_MSG_ID + #error "BOOT_COM_CAN_RX_MSG_ID is missing in config.h" + #endif + + #if (BOOT_COM_CAN_RX_MSG_ID <= 0) + #error "BOOT_COM_CAN_RX_MSG_ID must be > 0" + #endif + + #ifndef BOOT_COM_CAN_RX_MAX_DATA + #error "BOOT_COM_CAN_RX_MAX_DATA is missing in config.h" + #endif + + #if (BOOT_COM_CAN_RX_MAX_DATA <= 0) + #error "BOOT_COM_CAN_RX_MAX_DATA must be > 0" + #endif + + #ifndef BOOT_COM_CAN_CHANNEL_INDEX + #error "BOOT_COM_CAN_CHANNEL_INDEX is missing in config.h" + #endif + + #if (BOOT_COM_CAN_CHANNEL_INDEX < 0) + #error "BOOT_COM_CAN_CHANNEL_INDEX must be >= 0" + #endif +#endif /* BOOT_COM_CAN_ENABLE > 0 */ + +#ifndef BOOT_COM_UART_ENABLE +#define BOOT_COM_UART_ENABLE (0) +#endif + +#if (BOOT_COM_UART_ENABLE > 0) + #ifndef BOOT_COM_UART_BAUDRATE + #error "BOOT_COM_UART_BAUDRATE is missing in config.h" + #endif + + #if (BOOT_COM_UART_BAUDRATE <= 0) + #error "BOOT_COM_UART_BAUDRATE must be > 0" + #endif + + #ifndef BOOT_COM_UART_TX_MAX_DATA + #error "BOOT_COM_UART_TX_MAX_DATA is missing in config.h" + #endif + + #if (BOOT_COM_UART_TX_MAX_DATA <= 0) + #error "BOOT_COM_UART_TX_MAX_DATA must be > 0" + #endif + + #ifndef BOOT_COM_UART_RX_MAX_DATA + #error "BOOT_COM_UART_RX_MAX_DATA is missing in config.h" + #endif + + #if (BOOT_COM_UART_RX_MAX_DATA <= 0) + #error "BOOT_COM_UART_RX_MAX_DATA must be > 0" + #endif + + #ifndef BOOT_COM_UART_CHANNEL_INDEX + #error "BOOT_COM_UART_CHANNEL_INDEX is missing in config.h" + #endif + + #if (BOOT_COM_UART_CHANNEL_INDEX < 0) + #error "BOOT_COM_UART_CHANNEL_INDEX must be >= 0" + #endif +#endif /* BOOT_COM_UART_ENABLE > 0 */ + +#if (BOOT_COM_CAN_ENABLE == 0) && \ + (BOOT_COM_UART_ENABLE == 0) +#error "No communication interface enabled (BOOT_COM_XXX_ENABLE) in config.h" +#endif + +#if ((BOOT_COM_CAN_ENABLE + BOOT_COM_UART_ENABLE) > 1) +#error "Too many communication interfaces enabled (BOOT_COM_XXX_ENABLE) in config.h" +#endif + + +/**************************************************************************************** +* B A C K D O O R E N T R Y C H E C K +****************************************************************************************/ +#ifndef BOOT_BACKDOOR_HOOKS_ENABLE +#define BOOT_BACKDOOR_HOOKS_ENABLE (0) +#endif + +#if (BOOT_BACKDOOR_HOOKS_ENABLE < 0) || (BOOT_BACKDOOR_HOOKS_ENABLE > 1) +#error "BOOT_BACKDOOR_HOOKS_ENABLE must be 0 or 1" +#endif + + +/**************************************************************************************** +* N V M D R I V E R C O N F I G U R A T I O N C H E C K +****************************************************************************************/ +#ifndef BOOT_NVM_HOOKS_ENABLE +#define BOOT_NVM_HOOKS_ENABLE (0) +#endif + +#if (BOOT_NVM_HOOKS_ENABLE < 0) || (BOOT_NVM_HOOKS_ENABLE > 1) +#error "BOOT_NVM_HOOKS_ENABLE must be 0 or 1" +#endif + +#ifndef BOOT_NVM_SIZE_KB +#error "BOOT_NVM_SIZE_KB is missing in config.h" +#endif + +#if (BOOT_NVM_SIZE_KB <= 0) +#error "BOOT_NVM_SIZE_KB must be > 0" +#endif + + +/**************************************************************************************** +* W A T C H D O G D R I V E R C O N F I G U R A T I O N C H E C K +****************************************************************************************/ +#ifndef BOOT_COP_HOOKS_ENABLE +#define BOOT_COP_HOOKS_ENABLE (0) +#endif + +#if (BOOT_COP_HOOKS_ENABLE < 0) || (BOOT_COP_HOOKS_ENABLE > 1) +#error "BOOT_COP_HOOKS_ENABLE must be 0 or 1" +#endif + + +#endif /* PLAUSIBILITY_H */ +/*********************************** end of plausibility.h *****************************/ diff --git a/Target/Source/xcp.c b/Target/Source/xcp.c new file mode 100644 index 00000000..138d4a0d --- /dev/null +++ b/Target/Source/xcp.c @@ -0,0 +1,1326 @@ +/**************************************************************************************** +| Description: XCP 1.0 protocol core source file +| File Name: xcp.c +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ + + +/**************************************************************************************** +* Defines +****************************************************************************************/ +/* XCP protocol layer version number (16-bit) */ +#define XCP_VERSION_PROTOCOL_LAYER (0x0100) + +/* XCP transport layer version number (16-bit) */ +#define XCP_VERSION_TRANSPORT_LAYER (0x0100) + +/* XCP packet identifiers */ +#define XCP_PID_RES (0xff) /* command response packet */ +#define XCP_PID_ERR (0xfe) /* error packet */ + +/* XCP error codes */ +#define XCP_ERR_CMD_SYNCH (0x00) /* cmd processor synchronization */ +#define XCP_ERR_CMD_BUSY (0x10) /* command was not executed */ +#define XCP_ERR_CMD_UNKNOWN (0x20) /* unknown or unsupported command*/ +#define XCP_ERR_OUT_OF_RANGE (0x22) /* parameter out of range */ +#define XCP_ERR_ACCESS_LOCKED (0x25) /* protected. seed/key required */ +#define XCP_ERR_PAGE_NOT_VALID (0x26) /* cal page not valid */ +#define XCP_ERR_SEQUENCE (0x29) /* sequence error */ +#define XCP_ERR_GENERIC (0x31) /* generic error */ + +/* XCP command codes */ +#define XCP_CMD_CONNECT (0xff) /* CONNECT command code */ +#define XCP_CMD_DISCONNECT (0xfe) /* DISCONNECT command code */ +#define XCP_CMD_GET_STATUS (0xfd) /* GET_STATUS command code */ +#define XCP_CMD_SYNCH (0xfc) /* SYNCH command code */ +#define XCP_CMD_GET_ID (0xfa) /* GET_ID command code */ +#define XCP_CMD_GET_SEED (0xf8) /* GET_SEED command code */ +#define XCP_CMD_UNLOCK (0xf7) /* UNLOCK command code */ +#define XCP_CMD_SET_MTA (0xf6) /* SET_MTA command code */ +#define XCP_CMD_UPLOAD (0xf5) /* UPLOAD command code */ +#define XCP_CMD_SHORT_UPLOAD (0xf4) /* SHORT_UPLOAD command code */ +#define XCP_CMD_BUILD_CHECKSUM (0xf3) /* BUILD_CHECKSUM command code */ +#define XCP_CMD_DOWNLOAD (0xf0) /* DOWNLOAD command code */ +#define XCP_CMD_DOWLOAD_MAX (0xee) /* DOWNLOAD_MAX command code */ +#define XCP_CMD_SET_CAL_PAGE (0xeb) /* SET_CALPAGE command code */ +#define XCP_CMD_GET_CAL_PAGE (0xea) /* GET_CALPAGE command code */ +#define XCP_CMD_PROGRAM_START (0xd2) /* PROGRAM_START command code */ +#define XCP_CMD_PROGRAM_CLEAR (0xd1) /* PROGRAM_CLEAR command code */ +#define XCP_CMD_PROGRAM (0xd0) /* PROGRAM command code */ +#define XCP_CMD_PROGRAM_RESET (0xcf) /* PROGRAM_RESET command code */ +#define XCP_CMD_PROGRAM_PREPARE (0xcc) /* PROGRAM_PREPARE command code */ +#define XCP_CMD_PROGRAM_MAX (0xc9) /* PROGRAM_MAX command code */ + + +/**************************************************************************************** +* Type definitions +****************************************************************************************/ +/* XCP internal module information type */ +typedef struct +{ + blt_int8u connected; /* connection established */ + blt_int8u protection; /* protection state */ + blt_int8u s_n_k_resource; /* for seed/key sequence */ + blt_int8u ctoData[XCP_CTO_PACKET_LEN]; /* cto packet data buffer */ + blt_int8u ctoPending; /* cto transmission pending flag */ + blt_int16s ctoLen; /* cto current packet length */ + blt_int32u mta; /* memory transfer address */ +} tXcpInfo; + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +/* transport layer specific functions */ +static void XcpTransmitPacket(blt_int8u *data, blt_int16s len); + +/* application specific functions */ +static blt_int8u XcpComputeChecksum(blt_int32u address, blt_int32u length, + blt_int32u *checksum); + +#if (XCP_SEED_KEY_PROTECTION_EN == 1) +static blt_int8u XcpGetSeed(blt_int8u resource, blt_int8u *seed); +static blt_int8u XcpVerifyKey(blt_int8u resource, blt_int8u *key, blt_int8u len); +#endif + +/* general utility functions */ +static void XcpProtectResources(void); +static void XcpSetCtoError(blt_int8u error); + +/* XCP command processors */ +static void XcpCmdConnect(blt_int8u *data); +static void XcpCmdDisconnect(blt_int8u *data); +static void XcpCmdGetStatus(blt_int8u *data); +static void XcpCmdSynch(blt_int8u *data); +static void XcpCmdGetId(blt_int8u *data); +static void XcpCmdSetMta(blt_int8u *data); +static void XcpCmdUpload(blt_int8u *data); +static void XcpCmdShortUpload(blt_int8u *data); +static void XcpCmdBuildCheckSum(blt_int8u *data); +#if (XCP_SEED_KEY_PROTECTION_EN == 1) +static void XcpCmdGetSeed(blt_int8u *data); +static void XcpCmdUnlock(blt_int8u *data); +#endif +#if (XCP_RES_CALIBRATION_EN == 1) +static void XcpCmdDownload(blt_int8u *data); +static void XcpCmdDownloadMax(blt_int8u *data); +#endif +#if (XCP_RES_PAGING_EN == 1) +static void XcpCmdSetCalPage(blt_int8u *data); +static void XcpCmdGetCalPage(blt_int8u *data); +#endif +#if (XCP_RES_PROGRAMMING_EN == 1) +static void XcpCmdProgramMax(blt_int8u *data); +static void XcpCmdProgram(blt_int8u *data); +static void XcpCmdProgramStart(blt_int8u *data); +static void XcpCmdProgramClear(blt_int8u *data); +static void XcpCmdProgramReset(blt_int8u *data); +static void XcpCmdProgramPrepare(blt_int8u *data); +#endif + + +/**************************************************************************************** +* Hook functions +****************************************************************************************/ +#if F_CAL_RES_PAGING_EN == 1 +blt_int8u AppCalSetPage(blt_int8u segment, blt_int8u page); +blt_int8u AppCalGetPage(blt_int8u segment); +#endif + + +/**************************************************************************************** +* Local constants +****************************************************************************************/ +/* string buffer with station id */ +static const blt_int8s xcpStationId[] = XCP_STATION_ID_STRING; + + +/**************************************************************************************** +* Local data definitions +****************************************************************************************/ +static tXcpInfo xcpInfo; /* XCP internal module info */ + + +/**************************************************************************************** +** NAME: XcpInit +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Initializes the XCP driver. Should be called once upon system startup. +** +****************************************************************************************/ +void XcpInit(void) +{ + /* reset xcp module info */ + xcpInfo.connected = 0; + xcpInfo.mta = 0; + xcpInfo.ctoPending = 0; + xcpInfo.ctoLen = 0; + xcpInfo.s_n_k_resource = 0; + xcpInfo.protection = 0; +} /*** end of XcpInit ***/ + + +/**************************************************************************************** +** NAME: XcpIsConnected +** PARAMETER: none +** RETURN VALUE: BLT_TRUE is an XCP connection is established, BLT_FALSE otherwise. +** DESCRIPTION: Obtains information about the XCP connection state. +** +****************************************************************************************/ +blt_bool XcpIsConnected(void) +{ + if (xcpInfo.connected == 0) + { + return BLT_FALSE; + } + return BLT_TRUE; +} /*** end of XcpIsConnected ***/ + + +/**************************************************************************************** +** NAME: XcpPacketTransmitted +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Informs the core that a pending packet transmission was completed by +** the transport layer. +** +****************************************************************************************/ +void XcpPacketTransmitted(void) +{ + /* reset packet transmission pending flag */ + xcpInfo.ctoPending = 0; +} /*** end of XcpPacketTransmitted ***/ + + +/**************************************************************************************** +** NAME: XcpPacketReceived +** PARAMETER: data pointer to byte buffer with packet data +** RETURN VALUE: none +** DESCRIPTION: Informs the core that a new packet was received by the transport +** layer. +** +****************************************************************************************/ +void XcpPacketReceived(blt_int8u *data) +{ + /* was this a connect command? */ + if (data[0] == XCP_CMD_CONNECT) + { + /* process the connect command */ + XcpCmdConnect(data); + } + /* only continue if connected */ + else if (xcpInfo.connected == 1) + { + switch (data[0]) + { + case XCP_CMD_UPLOAD: + XcpCmdUpload(data); + break; + case XCP_CMD_SHORT_UPLOAD: + XcpCmdShortUpload(data); + break; + case XCP_CMD_SET_MTA: + XcpCmdSetMta(data); + break; + case XCP_CMD_BUILD_CHECKSUM: + XcpCmdBuildCheckSum(data); + break; + case XCP_CMD_GET_ID: + XcpCmdGetId(data); + break; + case XCP_CMD_SYNCH: + XcpCmdSynch(data); + break; + case XCP_CMD_GET_STATUS: + XcpCmdGetStatus(data); + break; + case XCP_CMD_DISCONNECT: + XcpCmdDisconnect(data); + break; +#if (XCP_RES_CALIBRATION_EN == 1) + case XCP_CMD_DOWNLOAD: + XcpCmdDownload(data); + break; + case XCP_CMD_DOWLOAD_MAX: + XcpCmdDownloadMax(data); + break; +#endif +#if (XCP_RES_PROGRAMMING_EN == 1) + case XCP_CMD_PROGRAM_MAX: + XcpCmdProgramMax(data); + break; + case XCP_CMD_PROGRAM: + XcpCmdProgram(data); + break; + case XCP_CMD_PROGRAM_START: + XcpCmdProgramStart(data); + break; + case XCP_CMD_PROGRAM_CLEAR: + XcpCmdProgramClear(data); + break; + case XCP_CMD_PROGRAM_RESET: + XcpCmdProgramReset(data); + break; + case XCP_CMD_PROGRAM_PREPARE: + XcpCmdProgramPrepare(data); + break; +#endif +#if (XCP_SEED_KEY_PROTECTION_EN == 1) + case XCP_CMD_GET_SEED: + XcpCmdGetSeed(data); + break; + case XCP_CMD_UNLOCK: + XcpCmdUnlock(data); + break; +#endif +#if (XCP_RES_PAGING_EN == 1) + case XCP_CMD_SET_CAL_PAGE: + XcpCmdSetCalPage(data); + break; + case XCP_CMD_GET_CAL_PAGE: + XcpCmdGetCalPage(data); + break; +#endif + default: + XcpSetCtoError(XCP_ERR_CMD_UNKNOWN); + break; + } + } + else + { + /* return to make sure response packet is not send because we are not connected */ + return; + } + + /* make sure the previous command was completed */ + if (xcpInfo.ctoPending == 1) + { + /* command overrun occurred */ + XcpSetCtoError(XCP_ERR_CMD_BUSY); + } + + /* set cto packet transmission pending flag */ + xcpInfo.ctoPending = 1; + + /* transmit the cto response packet */ + XcpTransmitPacket(xcpInfo.ctoData, xcpInfo.ctoLen); +} /*** end of XcpPacketReceived ***/ + + +/**************************************************************************************** +** NAME: XcpTransmitPacket +** PARAMETER: data pointer to the byte buffer with packet data. +** len number of data bytes that need to be transmitted. +** RETURN VALUE: none +** DESCRIPTION: Transmits the packet using the xcp transport layer. +** +****************************************************************************************/ +static void XcpTransmitPacket(blt_int8u *data, blt_int16s len) +{ + /* submit packet to the communication interface for transmission */ + ComTransmitPacket(data, len); +} /*** end of XcpTransmitPacket ***/ + + +/**************************************************************************************** +** NAME: XcpComputeChecksum +** PARAMETER: address the start address of the memory region. +** length length of the memory region in bytes. +** checksum pointer to where the calculated checksum is to be stored. +** RETURN VALUE: none +** DESCRIPTION: Called by the BUILD_CHECKSUM command to perform a checksum calculation +** over the specified memory region. +** +****************************************************************************************/ +static blt_int8u XcpComputeChecksum(blt_int32u address, blt_int32u length, + blt_int32u *checksum) +{ + blt_int8u cs = 0; + + /* this example computes the checksum using the add byte to byte algorithm */ + while (length-- > 0) + { + cs += *((blt_int8u*)(blt_addr)address); + address++; + } + + *checksum = cs; + + return XCP_CS_ADD11; +} /*** end of XcpComputeChecksum ***/ + + +#if (XCP_SEED_KEY_PROTECTION_EN == 1) +/**************************************************************************************** +** NAME: XcpGetSeed +** PARAMETER: resource resource that the seed if requested for (XCP_RES_XXX). +** seed pointer to byte buffer wher the seed will be stored. +** RETURN VALUE: none +** DESCRIPTION: Provides a seed to the XCP master that will be used for the key +** generation when the master attempts to unlock the specified resource. +** Called by the GET_SEED command. +** +****************************************************************************************/ +static blt_int8u XcpGetSeed(blt_int8u resource, blt_int8u *seed) +{ + /* request seed for unlocking ProGraMming resource */ + if ((resource & XCP_RES_PGM) != 0) + { + seed[0] = 0x55; + } + + /* request seed for unlocking CALibration and PAGing resource */ + if ((resource & XCP_RES_CALPAG) != 0) + { + seed[0] = 0xaa; + } + + /* return seed length */ + return 1; +} /*** end of XcpGetSeed ***/ + + +/**************************************************************************************** +** NAME: XcpVerifyKey +** PARAMETER: resource resource to unlock (XCP_RES_XXX). +** key pointer to the byte buffer holding the key. +** len length of the key in bytes. +** RETURN VALUE: none +** DESCRIPTION: Called by the UNLOCK command and checks if the key to unlock the +** specified resource was correct. If so, then the resource protection +** will be removed. +** +****************************************************************************************/ +static blt_int8u XcpVerifyKey(blt_int8u resource, blt_int8u *key, blt_int8u len) +{ + /* suppress compiler warning for unused parameter */ + len = len; + + /* the example key algorithm in "FeaserKey.dll" works as follows: + * - PGM will be unlocked if key = seed - 1 + * - CAL_PAG will be unlocked if key = seed + 1 + */ + + /* check key for unlocking ProGraMming resource */ + if ((resource == XCP_RES_PGM) && (key[0] == (0x55-1))) + { + /* correct key received for unlocking PGM resource */ + return 1; + } + + /* check key for unlocking CALibration and PAGing resource */ + if ((resource == XCP_RES_CALPAG) && (key[0] == (0xaa+1))) + { + /* correct key received for unlocking CAL_PAG resource */ + return 1; + } + + /* still here so key incorrect */ + return 0; +} /*** end of XcpVerifyKey ***/ +#endif /* XCP_SEED_KEY_PROTECTION_EN == 1 */ + + +/**************************************************************************************** +** NAME: XcpProtectResources +** PARAMETER: none +** RETURN VALUE: none +** DESCRIPTION: Utility function to protects all the available resources. +** +****************************************************************************************/ +static void XcpProtectResources(void) +{ + xcpInfo.protection = 0; + +#if (XCP_SEED_KEY_PROTECTION_EN == 1) + #if (XCP_RES_CALIBRATION_EN == 1) + xcpInfo.protection |= XCP_RES_CALPAG; + #endif + + #if (XCP_RES_PAGING_EN == 1) + xcpInfo.protection |= XCP_RES_CALPAG; + #endif + + #if (XCP_RES_PROGRAMMING_EN == 1) + xcpInfo.protection |= XCP_RES_PGM; + #endif + + #if (XCP_RES_DATA_ACQUISITION_EN == 1) + xcpInfo.protection |= XCP_RES_DAQ; + #endif + + #if (XCP_RES_DATA_STIMULATION_EN == 1) + xcpInfo.protection |= XCP_RES_STIM; + #endif +#endif /* XCP_SEED_KEY_PROTECTION_EN == 1 */ +} /*** end of XcpProtectResources ***/ + + +/**************************************************************************************** +** NAME: XcpSetCtoError +** PARAMETER: error xcp error code (XCP_ERR_XXX) +** RETURN VALUE: none +** DESCRIPTION: Prepares the cto packet data for the specified error. +** +****************************************************************************************/ +static void XcpSetCtoError(blt_int8u error) +{ + /* prepare the error packet */ + xcpInfo.ctoData[0] = XCP_PID_ERR; + xcpInfo.ctoData[1] = error; + xcpInfo.ctoLen = 2; +} /*** end of XcpSetCtoError ***/ + + +/**************************************************************************************** +** NAME: XcpCmdConnect +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the CONNECT command as +** defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdConnect(blt_int8u *data) +{ + /* suppress compiler warning for unused parameter */ + data = data; + + /* enable resource protection */ + XcpProtectResources(); + + /* indicate that the connection is established */ + xcpInfo.connected = 1; + + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* report available resources */ + xcpInfo.ctoData[1] = 0; +#if (XCP_RES_CALIBRATION_EN == 1) + xcpInfo.ctoData[1] |= XCP_RES_CALPAG; +#endif + +#if (XCP_RES_PAGING_EN == 1) + xcpInfo.ctoData[1] |= XCP_RES_CALPAG; +#endif + +#if (XCP_RES_PROGRAMMING_EN == 1) + xcpInfo.ctoData[1] |= XCP_RES_PGM; +#endif + +#if (XCP_RES_DATA_ACQUISITION_EN == 1) + xcpInfo.ctoData[1] |= XCP_RES_DAQ; +#endif + +#if (XCP_RES_DATA_STIMULATION_EN == 1) + xcpInfo.ctoData[1] |= XCP_RES_STIM; +#endif + + /* report communication mode info. only byte granularity is supported */ + xcpInfo.ctoData[2] = 0; + /* configure for motorola or intel byte ordering */ + xcpInfo.ctoData[2] |= XCP_MOTOROLA_FORMAT; + + /* report max cto data length */ + xcpInfo.ctoData[3] = XCP_CTO_PACKET_LEN; + + /* report max dto data length */ +#if (XCP_MOTOROLA_FORMAT == 0) + xcpInfo.ctoData[4] = (blt_int8u)XCP_DTO_PACKET_LEN; + xcpInfo.ctoData[5] = (blt_int8u)(XCP_DTO_PACKET_LEN >> 8); +#else + xcpInfo.ctoData[4] = (blt_int8u)(XCP_DTO_PACKET_LEN >> 8); + xcpInfo.ctoData[5] = (blt_int8u)XCP_DTO_PACKET_LEN; +#endif + + /* report msb of protocol layer version number */ + xcpInfo.ctoData[6] = XCP_VERSION_PROTOCOL_LAYER >> 8; + + /* report msb of transport layer version number */ + xcpInfo.ctoData[7] = XCP_VERSION_TRANSPORT_LAYER >> 8; + + /* set packet length */ + xcpInfo.ctoLen = 8; +} /*** end of XcpCmdConnect ***/ + + +/**************************************************************************************** +** NAME: XcpCmdDisconnect +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the DISCONNECT command as +** defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdDisconnect(blt_int8u *data) +{ + /* suppress compiler warning for unused parameter */ + data = data; + + /* indicate that the xcp connection is disconnected */ + xcpInfo.connected = 0; + + /* enable resource protection */ + XcpProtectResources(); + + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* set packet length */ + xcpInfo.ctoLen = 1; +} /*** end of XcpCmdDisconnect ***/ + + +/**************************************************************************************** +** NAME: XcpCmdGetStatus +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the GET_STATUS command as +** defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdGetStatus(blt_int8u *data) +{ + /* suppress compiler warning for unused parameter */ + data = data; + + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* report session status */ + xcpInfo.ctoData[1] = 0; + + /* report current resource protection status */ + xcpInfo.ctoData[2] = xcpInfo.protection; + + /* reset reserved and session configuration id values */ + xcpInfo.ctoData[3] = 0; + xcpInfo.ctoData[4] = 0; + xcpInfo.ctoData[5] = 0; + + /* set packet length */ + xcpInfo.ctoLen = 6; +} /*** end of XcpCmdGetStatus ***/ + + +/**************************************************************************************** +** NAME: XcpCmdSynch +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the SYNCH command as +** defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdSynch(blt_int8u *data) +{ + /* suppress compiler warning for unused parameter */ + data = data; + + /* synch requires a negative response */ + XcpSetCtoError(XCP_ERR_CMD_SYNCH); +} /*** end of XcpCmdSynch ***/ + + +/**************************************************************************************** +** NAME: XcpCmdGetId +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the GET_ID command as +** defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdGetId(blt_int8u *data) +{ + /* suppress compiler warning for unused parameter */ + data = data; + + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* point mta to start of station id string */ + xcpInfo.mta = (blt_int32u)&xcpStationId[0]; + + /* set station id mode to 0 */ + xcpInfo.ctoData[1] = 0; + + /* reset reserved values */ + xcpInfo.ctoData[2] = 0; + xcpInfo.ctoData[3] = 0; + + /* store station id length (excl. null termination) for response packet */ + *(blt_int32u*)&xcpInfo.ctoData[4] = (sizeof(xcpStationId)/sizeof(xcpStationId[0])) - 1; + + /* set packet length */ + xcpInfo.ctoLen = 8; +} /*** end of XcpCmdGetId ***/ + + +/**************************************************************************************** +** NAME: XcpCmdSetMta +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the SET_MTA command as +** defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdSetMta(blt_int8u *data) +{ + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* update mta. current implementation ignores address extension */ + xcpInfo.mta = *(blt_int32u*)&data[4]; + + /* set packet length */ + xcpInfo.ctoLen = 1; +} /*** end of XcpCmdSetMta ***/ + + +/**************************************************************************************** +** NAME: XcpCmdUpload +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the UPLOAD command as +** defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdUpload(blt_int8u *data) +{ + /* validate length of upload request */ + if (data[1] > (XCP_CTO_PACKET_LEN-1)) + { + /* requested data length is too long */ + XcpSetCtoError(XCP_ERR_OUT_OF_RANGE); + return; + } + + /* copy the data from memory to the data packet */ + CpuMemCopy(((blt_addr)(blt_int32u)&xcpInfo.ctoData[1]),(blt_addr)xcpInfo.mta, data[1]); + + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* post increment the mta */ + xcpInfo.mta += data[1]; + + /* set packet length */ + xcpInfo.ctoLen = data[1]+1; +} /*** end of XcpCmdUpload ***/ + + +/**************************************************************************************** +** NAME: XcpCmdShortUpload +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the SHORT_UPLOAD command as +** defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdShortUpload(blt_int8u *data) +{ + /* validate length of upload request */ + if (data[1] > (XCP_CTO_PACKET_LEN-1)) + { + /* requested data length is too long */ + XcpSetCtoError(XCP_ERR_OUT_OF_RANGE); + return; + } + + /* update mta. current implementation ignores address extension */ + xcpInfo.mta = *(blt_int32u*)&data[4]; + + /* copy the data from memory to the data packet */ + CpuMemCopy((blt_addr)((blt_int32u)&xcpInfo.ctoData[1]),(blt_addr)xcpInfo.mta, data[1]); + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* post increment the mta */ + xcpInfo.mta += data[1]; + + /* set packet length */ + xcpInfo.ctoLen = data[1]+1; +} /*** end of XcpCmdShortUpload ***/ + + +#if (XCP_RES_CALIBRATION_EN == 1) +/**************************************************************************************** +** NAME: XcpCmdDownload +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the DOWNLOAD command as +** defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdDownload(blt_int8u *data) +{ +#if (XCP_SEED_KEY_PROTECTION_EN == 1) + /* check if CAL_PAG resource is unlocked */ + if ((xcpInfo.protection & XCP_RES_CALPAG) != 0) + { + /* resource is locked. use seed/key sequence to unlock */ + XcpSetCtoError(XCP_ERR_ACCESS_LOCKED); + return; + } +#endif + + /* validate length of download request */ + if (data[1] > (XCP_CTO_PACKET_LEN-2)) + { + /* requested data length is too long */ + XcpSetCtoError(XCP_ERR_OUT_OF_RANGE); + return; + } + + /* copy the data from the data packet to memory */ + CpuMemCopy((blt_addr)xcpInfo.mta, (blt_addr)((blt_int32u)&data[2]), data[1]); + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* post increment the mta */ + xcpInfo.mta += data[1]; + + /* set packet length */ + xcpInfo.ctoLen = 1; +} /*** end of XcpCmdDownload ***/ + + +/**************************************************************************************** +** NAME: XcpCmdDownloadMax +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the DOWNLOAD_MAX command +** as defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdDownloadMax(blt_int8u *data) +{ +#if (XCP_SEED_KEY_PROTECTION_EN == 1) + /* check if CAL_PAG resource is unlocked */ + if ((xcpInfo.protection & XCP_RES_CALPAG) != 0) + { + /* resource is locked. use seed/key sequence to unlock */ + XcpSetCtoError(XCP_ERR_ACCESS_LOCKED); + return; + } +#endif + + /* copy the data from the data packet to memory */ + CpuMemCopy((blt_addr)xcpInfo.mta, (blt_addr)((blt_int32u)&data[1]), \ + XCP_CTO_PACKET_LEN-1); + + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* post increment the mta */ + xcpInfo.mta += XCP_CTO_PACKET_LEN-1; + + /* set packet length */ + xcpInfo.ctoLen = 1; +} /*** end of XcpCmdDownloadMax ***/ +#endif /* XCP_RES_CALIBRATION_EN == 1 */ + + +/**************************************************************************************** +** NAME: XcpCmdBuildCheckSum +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the BUILD_CHECKSUM +** command as defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdBuildCheckSum(blt_int8u *data) +{ + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* obtain checksum and checksum type */ + xcpInfo.ctoData[1] = XcpComputeChecksum(xcpInfo.mta, *(blt_int32u*)&data[4], + (blt_int32u*)&xcpInfo.ctoData[4]); + + /* initialize reserved parameters */ + xcpInfo.ctoData[2] = 0; + xcpInfo.ctoData[3] = 0; + + /* set packet length */ + xcpInfo.ctoLen = 8; +} /*** end of XcpCmdBuildCheckSum ***/ + + +#if (XCP_SEED_KEY_PROTECTION_EN == 1) +/**************************************************************************************** +** NAME: XcpCmdGetSeed +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the GET_SEED command as +** defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdGetSeed(blt_int8u *data) +{ + blt_int8u resourceOK; + + /* init resource check variable as if an illegal resource is requested */ + resourceOK = 0; + + /* check if calibration/paging resource is requested for seed/key and make + * sure this is the only requested resource + */ + if (((data[2] & XCP_RES_CALPAG) > 0) && ((data[2] & ~XCP_RES_CALPAG) == 0)) + { + resourceOK = 1; + } + + /* check if programming resource is requested for seed/key and make + * sure this is the only requested resource + */ + if (((data[2] & XCP_RES_PGM) > 0) && ((data[2] & ~XCP_RES_PGM) == 0)) + { + resourceOK = 1; + } + + /* check if data acquisition resource is requested for seed/key and make + * sure this is the only requested resource + */ + if (((data[2] & XCP_RES_DAQ) > 0) && ((data[2] & ~XCP_RES_DAQ) == 0)) + { + resourceOK = 1; + } + + /* check if data stimulation resource is requested for seed/key and make + * sure this is the only requested resource + */ + if (((data[2] & XCP_RES_STIM) > 0) && ((data[2] & ~XCP_RES_STIM) == 0)) + { + resourceOK = 1; + } + + /* now process the resource validation */ + if (resourceOK == 0) + { + XcpSetCtoError(XCP_ERR_OUT_OF_RANGE); + return; + } + + /* store resource for which the seed/key sequence is started */ + xcpInfo.s_n_k_resource = data[2]; + + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* request the seed from the application */ + xcpInfo.ctoData[1] = XcpGetSeed(xcpInfo.s_n_k_resource, &xcpInfo.ctoData[2]); + + /* seed cannot be longer than XCP_CTO_PACKET_LEN-2 */ + if (xcpInfo.ctoData[1] > (XCP_CTO_PACKET_LEN-2)) + { + /* seed length length is too long */ + XcpSetCtoError(XCP_ERR_OUT_OF_RANGE); + return; + } + + /* set packet length */ + xcpInfo.ctoLen = xcpInfo.ctoData[1] + 2; +} /*** end of XcpCmdGetSeed ***/ + + +/**************************************************************************************** +** NAME: XcpCmdUnlock +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the UNLOCK command as +** defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdUnlock(blt_int8u *data) +{ + /* key cannot be longer than XCP_CTO_PACKET_LEN-2 */ + if (data[1] > (XCP_CTO_PACKET_LEN-2)) + { + /* key is too long incorrect */ + XcpSetCtoError(XCP_ERR_SEQUENCE); + return; + } + + /* verify the key */ + if (XcpVerifyKey(xcpInfo.s_n_k_resource, &data[2], data[1]) == 0) + { + /* invalid key so inform the master and do a disconnect */ + XcpSetCtoError(XCP_ERR_ACCESS_LOCKED); + + /* indicate that the xcp connection is disconnected */ + xcpInfo.connected = 0; + + /* enable resource protection */ + XcpProtectResources(); + + return; + } + + /* key correct so unlock the resource */ + xcpInfo.protection &= ~xcpInfo.s_n_k_resource; + + /* reset seed/key resource variable for possible next unlock */ + xcpInfo.s_n_k_resource = 0; + + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* report the current resource protection */ + xcpInfo.ctoData[1] = xcpInfo.protection; + + /* set packet length */ + xcpInfo.ctoLen = 2; +} /*** end of XcpCmdUnlock ***/ +#endif /* XCP_SEED_KEY_PROTECTION_EN == 1 */ + + +#if (XCP_RES_PAGING_EN == 1) +/**************************************************************************************** +** NAME: XcpCmdSetCalPage +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the SET_CAL_PAGE command +** as defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdSetCalPage(blt_int8u *data) +{ +#if (XCP_SEED_KEY_PROTECTION_EN == 1) + /* check if CAL_PAG resource is unlocked */ + if ((xcpInfo.protection & XCP_RES_CALPAG) == XCP_RES_CALPAG) + { + /* resource is locked. use seed/key sequence to unlock */ + XcpSetCtoError(XCP_ERR_ACCESS_LOCKED); + return; + } +#endif + + /* select the page. note that the mode parameter is ignored */ + if (AppCalSetPage(data[2], data[3]) == 0) + { + /* calibration page could not be selected */ + XcpSetCtoError(XCP_ERR_PAGE_NOT_VALID); + return; + } + + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* set packet length */ + xcpInfo.ctoLen = 1; +} /*** end of XcpCmdSetCalPage ***/ + + +/**************************************************************************************** +** NAME: XcpCmdGetCalPage +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the GET_CAL_PAGE command +** as defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdGetCalPage(blt_int8u *data) +{ +#if (XCP_SEED_KEY_PROTECTION_EN == 1) + /* check if CAL_PAG resource is unlocked */ + if ((xcpInfo.protection & XCP_RES_CALPAG) == XCP_RES_CALPAG) + { + /* resource is locked. use seed/key sequence to unlock */ + XcpSetCtoError(XCP_ERR_ACCESS_LOCKED); + return; + } +#endif + + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* initialize reserved parameters */ + xcpInfo.ctoData[1] = 0; + xcpInfo.ctoData[2] = 0; + + /* store the calibration page */ + xcpInfo.ctoData[3] = AppCalGetPage(data[2]); + + /* set packet length */ + xcpInfo.ctoLen = 4; +} /*** end of XcpCmdGetCalPage ***/ +#endif /* XCP_RES_PAGING_EN == 1 */ + + +#if (XCP_RES_PROGRAMMING_EN == 1) +/**************************************************************************************** +** NAME: XcpCmdProgramStart +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the PROGRAM_START command +** as defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdProgramStart(blt_int8u *data) +{ + /* suppress compiler warning for unused parameter */ + data = data; + +#if (XCP_SEED_KEY_PROTECTION_EN == 1) + /* check if PGM resource is unlocked */ + if ((xcpInfo.protection & XCP_RES_PGM) == XCP_RES_PGM) + { + /* resource is locked. use seed/key sequence to unlock */ + XcpSetCtoError(XCP_ERR_ACCESS_LOCKED); + return; + } +#endif + + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* initialize reserved parameter */ + xcpInfo.ctoData[1] = 0; + + /* no special communication mode supported during programming */ + xcpInfo.ctoData[2] = 0; + + /* cto packet length stays the same during programming */ + xcpInfo.ctoData[3] = XCP_CTO_PACKET_LEN; + + /* no block size, st-min time, or queue size supported */ + xcpInfo.ctoData[4] = 0; + xcpInfo.ctoData[5] = 0; + xcpInfo.ctoData[6] = 0; + + /* set packet length */ + xcpInfo.ctoLen = 7; +} /*** end of XcpCmdProgramStart ***/ + + +/**************************************************************************************** +** NAME: XcpCmdProgramMax +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the PROGRAM_MAX command +** as defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdProgramMax(blt_int8u *data) +{ +#if (XCP_SEED_KEY_PROTECTION_EN == 1) + /* check if PGM resource is unlocked */ + if ((xcpInfo.protection & XCP_RES_PGM) == XCP_RES_PGM) + { + /* resource is locked. use seed/key sequence to unlock */ + XcpSetCtoError(XCP_ERR_ACCESS_LOCKED); + return; + } +#endif + + /* program the data */ + if (NvmWrite((blt_addr)xcpInfo.mta, XCP_CTO_PACKET_LEN-1, &data[1]) == 0) + { + /* error occurred during programming */ + XcpSetCtoError(XCP_ERR_GENERIC); + return; + } + + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* post increment the mta */ + xcpInfo.mta += XCP_CTO_PACKET_LEN-1; + + /* set packet length */ + xcpInfo.ctoLen = 1; +} /*** end of XcpCmdProgramMax ***/ + + +/**************************************************************************************** +** NAME: XcpCmdProgram +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the PROGRAM command as +** defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdProgram(blt_int8u *data) +{ +#if (XCP_SEED_KEY_PROTECTION_EN == 1) + /* check if PGM resource is unlocked */ + if ((xcpInfo.protection & XCP_RES_PGM) == XCP_RES_PGM) + { + /* resource is locked. use seed/key sequence to unlock */ + XcpSetCtoError(XCP_ERR_ACCESS_LOCKED); + return; + } +#endif + + /* validate length of download request */ + if (data[1] > (XCP_CTO_PACKET_LEN-2)) + { + /* requested data length is too long */ + XcpSetCtoError(XCP_ERR_OUT_OF_RANGE); + return; + } + + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* set packet length */ + xcpInfo.ctoLen = 1; + + /* end of programming sequence (datasize is 0)? */ + if (data[1] == 0) + { + /* call erase/programming cleanup routine */ + if (NvmDone() == BLT_FALSE) + { + /* error occurred while finishing up programming */ + XcpSetCtoError(XCP_ERR_GENERIC); + } + return; + } + /* program the data */ + if (NvmWrite((blt_addr)xcpInfo.mta, data[1], &data[2]) == 0) + { + /* error occurred during programming */ + XcpSetCtoError(XCP_ERR_GENERIC); + return; + } + + /* post increment the mta */ + xcpInfo.mta += data[1]; +} /*** end of XcpCmdProgram ***/ + + +/**************************************************************************************** +** NAME: XcpCmdProgramClear +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the PROGRAM_CLEAR command +** as defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdProgramClear(blt_int8u *data) +{ +#if (XCP_SEED_KEY_PROTECTION_EN == 1) + /* check if PGM resource is unlocked */ + if ((xcpInfo.protection & XCP_RES_PGM) == XCP_RES_PGM) + { + /* resource is locked. use seed/key sequence to unlock */ + XcpSetCtoError(XCP_ERR_ACCESS_LOCKED); + return; + } +#endif + + /* erase the memory */ + if (NvmErase((blt_addr)xcpInfo.mta, *(blt_int32u*)&data[4]) == 0) + { + /* error occurred during erasure */ + XcpSetCtoError(XCP_ERR_GENERIC); + return; + } + + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* set packet length */ + xcpInfo.ctoLen = 1; +} /*** end of XcpCmdProgramClear ***/ + + +/**************************************************************************************** +** NAME: XcpCmdProgramReset +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the PROGRAM_RESET command +** as defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdProgramReset(blt_int8u *data) +{ + /* suppress compiler warning for unused parameter */ + data = data; + +#if (XCP_SEED_KEY_PROTECTION_EN == 1) + /* check if PGM resource is unlocked */ + if ((xcpInfo.protection & XCP_RES_PGM) == XCP_RES_PGM) + { + /* resource is locked. use seed/key sequence to unlock */ + XcpSetCtoError(XCP_ERR_ACCESS_LOCKED); + return; + } +#endif + + /* reset the ecu. it is okay if the code does not return here after the reset */ + CpuReset(); + + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* set packet length */ + xcpInfo.ctoLen = 1; +} /*** end of XcpCmdProgramReset ***/ + + +/**************************************************************************************** +** NAME: XcpCmdProgramPrepare +** PARAMETER: data pointer to a byte buffer with the packet data. +** RETURN VALUE: none +** DESCRIPTION: XCP command processor function which handles the PROGRAM_PREPARE +** command as defined by the protocol. +** +****************************************************************************************/ +static void XcpCmdProgramPrepare(blt_int8u *data) +{ +#if (XCP_SEED_KEY_PROTECTION_EN == 1) + /* check if PGM resource is unlocked */ + if ((xcpInfo.protection & XCP_RES_PGM) == XCP_RES_PGM) + { + /* resource is locked. use seed/key sequence to unlock */ + XcpSetCtoError(XCP_ERR_ACCESS_LOCKED); + return; + } +#endif + + /* programming with kernel currently not needed and therefore not supported */ + XcpSetCtoError(XCP_ERR_GENERIC); + return; + + /* set packet id to command response packet */ + xcpInfo.ctoData[0] = XCP_PID_RES; + + /* set packet length */ + xcpInfo.ctoLen = 1; +} /*** end of XcpCmdProgramPrepare ***/ +#endif /* XCP_RES_PROGRAMMING_EN == 1 */ + + +/******************************** end of xcp.c *****************************************/ diff --git a/Target/Source/xcp.h b/Target/Source/xcp.h new file mode 100644 index 00000000..0110cee9 --- /dev/null +++ b/Target/Source/xcp.h @@ -0,0 +1,226 @@ +/**************************************************************************************** +| Description: XCP 1.0 protocol core header file +| File Name: xcp.h +| +|---------------------------------------------------------------------------------------- +| C O P Y R I G H T +|---------------------------------------------------------------------------------------- +| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved +| +|---------------------------------------------------------------------------------------- +| L I C E N S E +|---------------------------------------------------------------------------------------- +| This file is part of OpenBLT. OpenBLT 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. +| +| OpenBLT 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 OpenBLT. +| If not, see . +| +| A special exception to the GPL is included to allow you to distribute a combined work +| that includes OpenBLT without being obliged to provide the source code for any +| proprietary components. The exception text is included at the bottom of the license +| file . +| +****************************************************************************************/ +#ifndef XCP_H +#define XCP_H + +/**************************************************************************************** +* Configuration +****************************************************************************************/ +/* Maximum length of the transport layer's command transmit object packet. + */ +#define XCP_CTO_PACKET_LEN (BOOT_COM_RX_MAX_DATA) + +/* Maximum length of the transport layer's data transmit object packet. + */ +#define XCP_DTO_PACKET_LEN (BOOT_COM_TX_MAX_DATA) + +/* Name in string format that is used to identify the ECU to the XCP master + * using the GET_ID command. + */ +#define XCP_STATION_ID_STRING "OpenBLT" + +/* XCP byte ordering + */ +#if (BOOT_CPU_BYTE_ORDER_MOTOROLA > 0) + #define XCP_MOTOROLA_FORMAT (0x01) +#else + #define XCP_MOTOROLA_FORMAT (0x00) +#endif + +/* Enable (=1) or disable (=0) support for the calibration resource. This is + * required when data is written to RAM during the XCP session. + */ +#define XCP_RES_CALIBRATION_EN (0) + +/* Enable (=1) or disable (=0) support for the paging resource. This is + * required when switching between application specific calibration pages + * should be supported. In this case the application specific external + * functions AppCalSetPage and AppCalGetPage must be provided. + */ +#define XCP_RES_PAGING_EN (0) + +/* Enable (=1) or disable (=0) support for the programming resource. This is + * required when non-volatile memory will be erased or programmed during an + * XCP session. In this case the following external hardware specific + * functions must be provided: HwNvmWriteMemory, HwNvmEraseMemory and + * HwCpuReset. + */ +#define XCP_RES_PROGRAMMING_EN (1) + +/* Enable (=1) or disable (=0) support for the data acquisition resource. This + * note that this feature is currently not supported by the XCP driver. + */ +#define XCP_RES_DATA_ACQUISITION_EN (0) + +/* Enable (=1) or disable (=0) support for the data stimulation resource. This + * note that this feature is currently not supported by the XCP driver. + */ +#define XCP_RES_DATA_STIMULATION_EN (0) + +/* Enable (=1) or disable (=0) support for the seed/key protection feature. + * If enabled, the XCP master has to perform a GET_SEED/UNLOCK sequence to + * obtain access to a resource. The protection algorithm is implemented in + * XcpGetSeed and XcpVerifyKey. + */ +#define XCP_SEED_KEY_PROTECTION_EN (0) + + +/**************************************************************************************** +* Defines +****************************************************************************************/ +/* xcp supported resources */ +#define XCP_RES_PGM (0x10) /* ProGraMming */ +#define XCP_RES_STIM (0x08) /* data STIMulation */ +#define XCP_RES_DAQ (0x04) /* Data AcQuisition */ +#define XCP_RES_CALPAG (0x01) /* CALibration and PAGing */ + +/* xcp checksum types */ +#define XCP_CS_ADD11 (0x01) /* add byte into byte checksum */ +#define XCP_CS_ADD12 (0x02) /* add byte into word checksum */ +#define XCP_CS_ADD14 (0x03) /* add byte into dword checksum */ +#define XCP_CS_ADD22 (0x04) /* add word into word checksum */ +#define XCP_CS_ADD24 (0x05) /* add word into dword checksum */ +#define XCP_CS_ADD44 (0x06) /* add dword into dword checksum */ +#define XCP_CS_CRC16 (0x07) /* use 16-bit CRC algorithm */ +#define XCP_CS_CRC16CITT (0x08) /* use 16-bit CRC CITT algorithm */ +#define XCP_CS_CRC32 (0x09) /* use 32-bit CRC algorithm */ +#define XCP_CS_USER (0xff) /* use user defined algorithm */ + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void XcpInit(void); +blt_bool XcpIsConnected(void); +void XcpPacketTransmitted(void); +void XcpPacketReceived(blt_int8u *data); + + +/**************************************************************************************** +* Configuration check +****************************************************************************************/ +#if (XCP_RES_DATA_ACQUISITION_EN == 1) +#error "XCP.H, Current XCP driver does not support Data AcQuisition resource." +#endif + + +#if (XCP_RES_DATA_STIMULATION_EN == 1) +#error "XCP.H, Current XCP driver does not support Data StIMulation resource." +#endif + + +#ifndef XCP_CTO_PACKET_LEN +#error "XCP.H, Configuration macro XCP_CTO_PACKET_LEN is missing." +#endif + +#if (XCP_CTO_PACKET_LEN < 1) +#error "XCP.H, XCP_CTO_PACKET_LEN must be at least 1." +#endif + +#if (XCP_CTO_PACKET_LEN > 256) +#error "XCP.H, XCP_CTO_PACKET_LEN cannot be larger than 256." +#endif + + +#ifndef XCP_DTO_PACKET_LEN +#error "XCP.H, Configuration macro XCP_DTO_PACKET_LEN is missing." +#endif + +#if (XCP_DTO_PACKET_LEN < 1) +#error "XCP.H, XCP_DTO_PACKET_LEN must be at least 1." +#endif + +#if (XCP_DTO_PACKET_LEN > 65536) +#error "XCP.H, XCP_DTO_PACKET_LEN cannot be larger than 256." +#endif + + +#ifndef XCP_STATION_ID_STRING +#error "XCP.H, Configuration macro XCP_STATION_ID_STRING is missing." +#endif + + +#ifndef XCP_RES_CALIBRATION_EN +#error "XCP.H, Configuration macro XCP_RES_CALIBRATION_EN is missing." +#endif + +#if (XCP_RES_CALIBRATION_EN < 0) || (XCP_RES_CALIBRATION_EN > 1) +#error "XCP.H, XCP_RES_CALIBRATION_EN must be 0 or 1." +#endif + + +#ifndef XCP_RES_PAGING_EN +#error "XCP.H, Configuration macro XCP_RES_PAGING_EN is missing." +#endif + +#if (XCP_RES_PAGING_EN < 0) || (XCP_RES_PAGING_EN > 1) +#error "XCP.H, XCP_RES_PAGING_EN must be 0 or 1." +#endif + + +#ifndef XCP_RES_PROGRAMMING_EN +#error "XCP.H, Configuration macro XCP_RES_PAGING_EN is missing." +#endif + +#if (XCP_RES_PROGRAMMING_EN < 0) || (XCP_RES_PROGRAMMING_EN > 1) +#error "XCP.H, XCP_RES_PROGRAMMING_EN must be 0 or 1." +#endif + + +#ifndef XCP_RES_DATA_ACQUISITION_EN +#error "XCP.H, Configuration macro XCP_RES_DATA_ACQUISITION_EN is missing." +#endif + +#if (XCP_RES_DATA_ACQUISITION_EN < 0) || (XCP_RES_DATA_ACQUISITION_EN > 1) +#error "XCP.H, XCP_RES_DATA_ACQUISITION_EN must be 0 or 1." +#endif + + +#ifndef XCP_RES_DATA_STIMULATION_EN +#error "XCP.H, Configuration macro XCP_RES_DATA_STIMULATION_EN is missing." +#endif + +#if (XCP_RES_DATA_STIMULATION_EN < 0) || (XCP_RES_DATA_STIMULATION_EN > 1) +#error "XCP.H, XCP_RES_DATA_STIMULATION_EN must be 0 or 1." +#endif + + +#ifndef XCP_SEED_KEY_PROTECTION_EN +#error "XCP.H, Configuration macro XCP_SEED_KEY_PROTECTION_EN is missing." +#endif + +#if (XCP_SEED_KEY_PROTECTION_EN < 0) || (XCP_SEED_KEY_PROTECTION_EN > 1) +#error "XCP.H, XCP_SEED_KEY_PROTECTION_EN must be 0 or 1." +#endif + + +#endif /* XCP_H */ +/******************************** end of xcp.h *~~~~~***********************************/