mirror of https://github.com/marqs85/ossc.git
Initial public release (FW 0.64)
This commit is contained in:
commit
388c464f63
|
@ -0,0 +1,674 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 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.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
|
@ -0,0 +1,4 @@
|
|||
Open Source Scan Converter
|
||||
==============
|
||||
|
||||
Documentation coming soon...
|
|
@ -0,0 +1,126 @@
|
|||
/******************************************************************************
|
||||
* *
|
||||
* License Agreement *
|
||||
* *
|
||||
* Copyright (c) 2015 Altera Corporation, San Jose, California, USA. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
* copy of this software and associated documentation files (the "Software"), *
|
||||
* to deal in the Software without restriction, including without limitation *
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
|
||||
* and/or sell copies of the Software, and to permit persons to whom the *
|
||||
* Software is furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in *
|
||||
* all copies or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
|
||||
* DEALINGS IN THE SOFTWARE. *
|
||||
* *
|
||||
* This agreement shall be governed in all respects by the laws of the State *
|
||||
* of California and by the laws of the United States of America. *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __ALT_EPCQ_CONTROLLER_H__
|
||||
#define __ALT_EPCQ_CONTROLLER_H__
|
||||
|
||||
#include "alt_types.h"
|
||||
#include "sys/alt_flash_dev.h"
|
||||
#include "sys/alt_llist.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* Description of the EPCQ controller
|
||||
*/
|
||||
typedef struct alt_epcq_controller_dev
|
||||
{
|
||||
alt_flash_dev dev;
|
||||
|
||||
alt_u32 data_base; /** base address of data slave */
|
||||
alt_u32 data_end; /** end address of data slave (not inclusive) */
|
||||
alt_u32 csr_base; /** base address of CSR slave */
|
||||
alt_u32 size_in_bytes; /** size of memory in bytes */
|
||||
alt_u32 is_epcs; /** 1 if device is an EPCS device */
|
||||
alt_u32 number_of_sectors; /** number of flash sectors */
|
||||
alt_u32 sector_size; /** size of each flash sector */
|
||||
alt_u32 page_size; /** page size */
|
||||
alt_u32 silicon_id; /** ID of silicon used with EPCQ IP */
|
||||
} alt_epcq_controller_dev;
|
||||
|
||||
/**
|
||||
* Macros used by alt_sys_init.c to create data storage for driver instance
|
||||
*/
|
||||
#define ALTERA_EPCQ_CONTROLLER_MOD_AVL_MEM_AVL_CSR_INSTANCE(epcq_name, avl_mem, avl_csr, epcq_dev) \
|
||||
alt_epcq_controller_dev epcq_dev = \
|
||||
{ \
|
||||
.dev = { \
|
||||
.llist = ALT_LLIST_ENTRY, \
|
||||
.name = avl_mem##_NAME, \
|
||||
.write = alt_epcq_controller_write, \
|
||||
.read = alt_epcq_controller_read, \
|
||||
.get_info = alt_epcq_controller_get_info, \
|
||||
.erase_block = alt_epcq_controller_erase_block, \
|
||||
.write_block = alt_epcq_controller_write_block, \
|
||||
.base_addr = ((void*)(avl_mem##_BASE)), \
|
||||
.length = ((int)(avl_mem##_SPAN)), \
|
||||
.lock = alt_epcq_controller_lock , \
|
||||
}, \
|
||||
.data_base = ((alt_u32)(avl_mem##_BASE)), \
|
||||
.data_end = ((alt_u32)(avl_mem##_BASE) + (alt_u32)(avl_mem##_SPAN)), \
|
||||
.csr_base = ((alt_u32)(avl_csr##_BASE)), \
|
||||
.size_in_bytes = ((alt_u32)(avl_mem##_SPAN)), \
|
||||
.is_epcs = ((alt_u32)(avl_mem##_IS_EPCS)), \
|
||||
.number_of_sectors = ((alt_u32)(avl_mem##_NUMBER_OF_SECTORS)), \
|
||||
.sector_size = ((alt_u32)(avl_mem##_SECTOR_SIZE)), \
|
||||
.page_size = ((alt_u32)(avl_mem##_PAGE_SIZE)) , \
|
||||
}
|
||||
|
||||
/*
|
||||
Public API
|
||||
|
||||
Refer to Using Flash Devices in the
|
||||
Developing Programs Using the Hardware Abstraction Layer chapter
|
||||
of the Nios II Software Developer's Handbook.
|
||||
|
||||
*/
|
||||
int alt_epcq_controller_read(alt_flash_dev *flash_info, int offset, void *dest_addr, int length);
|
||||
|
||||
int alt_epcq_controller_get_info(alt_flash_fd *fd, flash_region **info, int *number_of_regions);
|
||||
|
||||
int alt_epcq_controller_erase_block(alt_flash_dev *flash_info, int block_offset);
|
||||
|
||||
int alt_epcq_controller_write_block(alt_flash_dev *flash_info, int block_offset, int data_offset, const void *data, int length);
|
||||
|
||||
int alt_epcq_controller_write(alt_flash_dev *flash_info, int offset, const void *src_addr, int length);
|
||||
|
||||
int alt_epcq_controller_lock(alt_flash_dev *flash_info, alt_u32 sectors_to_lock);
|
||||
|
||||
|
||||
/*
|
||||
* Initialization function
|
||||
*/
|
||||
extern alt_32 altera_epcq_controller_init(alt_epcq_controller_dev *dev);
|
||||
|
||||
/*
|
||||
* alt_sys_init.c will call this macro automatically initialize the driver instance
|
||||
*/
|
||||
#define ALTERA_EPCQ_CONTROLLER_MOD_INIT(name, dev) \
|
||||
altera_epcq_controller_init(&dev);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __ALT_EPCQ_CONTROLLER_H__ */
|
|
@ -0,0 +1,797 @@
|
|||
/******************************************************************************
|
||||
* *
|
||||
* License Agreement *
|
||||
* *
|
||||
* Copyright (c) 2015 Altera Corporation, San Jose, California, USA. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
* copy of this software and associated documentation files (the "Software"), *
|
||||
* to deal in the Software without restriction, including without limitation *
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
|
||||
* and/or sell copies of the Software, and to permit persons to whom the *
|
||||
* Software is furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in *
|
||||
* all copies or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
|
||||
* DEALINGS IN THE SOFTWARE. *
|
||||
* *
|
||||
* This agreement shall be governed in all respects by the laws of the State *
|
||||
* of California and by the laws of the United States of America. *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
#include <errno.h>
|
||||
#include <io.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include "sys/param.h"
|
||||
#include "alt_types.h"
|
||||
#include "altera_epcq_controller_mod_regs.h"
|
||||
#include "altera_epcq_controller_mod.h"
|
||||
#include "priv/alt_busy_sleep.h"
|
||||
#include "sys/alt_debug.h"
|
||||
#include "sys/alt_cache.h"
|
||||
|
||||
|
||||
ALT_INLINE alt_32 static alt_epcq_validate_read_write_arguments(alt_epcq_controller_dev *flash_info,alt_u32 offset, alt_u32 length);
|
||||
alt_32 static alt_epcq_poll_for_write_in_progress(alt_epcq_controller_dev* epcq_flash_info);
|
||||
|
||||
/*
|
||||
* Public API
|
||||
*
|
||||
* Refer to “Using Flash Devices” in the
|
||||
* Developing Programs Using the Hardware Abstraction Layer chapter
|
||||
* of the Nios II Software Developer’s Handbook.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* alt_epcq_controller_lock
|
||||
*
|
||||
* Locks the range of the memory sectors, which
|
||||
* protected from write and erase.
|
||||
*
|
||||
* Arguments:
|
||||
* - *flash_info: Pointer to general flash device structure.
|
||||
* - sectors_to_lock: Block protection bits in EPCQ ==> Bit4 | Bit3 | Bit2 | Bit1 | Bit0
|
||||
* TB | BP3 | BP2 | BP1 | BP0
|
||||
* For details of setting sectors protection, please refer to EPCQ datasheet.
|
||||
*
|
||||
* Returns:
|
||||
* 0 -> success
|
||||
* -EINVAL -> Invalid arguments
|
||||
* -ETIME -> Time out and skipping the looping after 0.7 sec.
|
||||
* -ENOLCK -> Sectors lock failed.
|
||||
**/
|
||||
int alt_epcq_controller_lock(alt_flash_dev *flash_info, alt_u32 sectors_to_lock)
|
||||
{
|
||||
alt_u32 mem_op_value = 0; /* value to write to EPCQ_MEM_OP register */
|
||||
alt_epcq_controller_dev* epcq_flash_info = NULL;
|
||||
alt_u32 result = 0;
|
||||
alt_32 status = 0;
|
||||
|
||||
/* return -EINVAL if flash_info is NULL */
|
||||
if(NULL == flash_info || 0 > sectors_to_lock)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
epcq_flash_info = (alt_epcq_controller_dev*)flash_info;
|
||||
|
||||
/* sector value should occupy bits 17:8 */
|
||||
mem_op_value = sectors_to_lock << 8;
|
||||
|
||||
/* sector protect commands 0b11 occupies lower 2 bits */
|
||||
mem_op_value |= ALTERA_EPCQ_CONTROLLER_MEM_OP_SECTOR_PROTECT_CMD;
|
||||
|
||||
/* write sector protect command to EPCQ_MEM_OP register to protect sectors */
|
||||
IOWR_ALTERA_EPCQ_CONTROLLER_MEM_OP(epcq_flash_info->csr_base, mem_op_value);
|
||||
|
||||
/* poll write in progress to make sure no operation is in progress */
|
||||
status = alt_epcq_poll_for_write_in_progress(epcq_flash_info);
|
||||
if(status != 0)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
status = IORD_ALTERA_EPCQ_CONTROLLER_STATUS(epcq_flash_info->csr_base);
|
||||
result |= (status >> 2) & 0x07; /* extract out BP3 - BP0 */
|
||||
result |= (status >> 3) & 0x08; /* extract out BP4 */
|
||||
result |= (status >> 1) & 0x10; /* extract out TOP/BOTTOM bit */
|
||||
|
||||
if(result != sectors_to_lock)
|
||||
{
|
||||
return -ENOLCK;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* alt_epcq_controller_get_info
|
||||
*
|
||||
* Pass the table of erase blocks to the user. This flash will return a single
|
||||
* flash_region that gives the number and size of sectors for the device used.
|
||||
*
|
||||
* Arguments:
|
||||
* - *fd: Pointer to general flash device structure.
|
||||
* - **info: Pointer to flash region
|
||||
* - *number_of_regions: Pointer to number of regions
|
||||
*
|
||||
* For details of setting sectors protection, please refer to EPCQ datasheet.
|
||||
*
|
||||
* Returns:
|
||||
* 0 -> success
|
||||
* -EINVAL -> Invalid arguments
|
||||
* -EIO -> Could be hardware problem.
|
||||
**/
|
||||
int alt_epcq_controller_get_info
|
||||
(
|
||||
alt_flash_fd *fd, /** flash device descriptor */
|
||||
flash_region **info, /** pointer to flash_region will be stored here */
|
||||
int *number_of_regions /** number of regions will be stored here */
|
||||
)
|
||||
{
|
||||
alt_flash_dev* flash = NULL;
|
||||
|
||||
/* return -EINVAL if fd,info and number_of_regions are NULL */
|
||||
if(NULL == fd || NULL == info || NULL == number_of_regions)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
flash = (alt_flash_dev*)fd;
|
||||
|
||||
*number_of_regions = flash->number_of_regions;
|
||||
|
||||
if (!flash->number_of_regions)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
else
|
||||
{
|
||||
*info = &flash->region_info[0];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* alt_epcq_controller_erase_block
|
||||
*
|
||||
* This function erases a single flash sector.
|
||||
*
|
||||
* Arguments:
|
||||
* - *flash_info: Pointer to EPCQ flash device structure.
|
||||
* - block_offset: byte-addressed offset, from start of flash, of the sector to be erased
|
||||
*
|
||||
* Returns:
|
||||
* 0 -> success
|
||||
* -EINVAL -> Invalid arguments
|
||||
* -EIO -> write failed, sector might be protected
|
||||
**/
|
||||
int alt_epcq_controller_erase_block(alt_flash_dev *flash_info, int block_offset)
|
||||
{
|
||||
alt_32 ret_code = 0;
|
||||
alt_u32 mem_op_value = 0; /* value to write to EPCQ_MEM_OP register */
|
||||
alt_epcq_controller_dev* epcq_flash_info = NULL;
|
||||
alt_u32 sector_number = 0;
|
||||
|
||||
/* return -EINVAL if flash_info is NULL */
|
||||
if(NULL == flash_info)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
epcq_flash_info = (alt_epcq_controller_dev*)flash_info;
|
||||
|
||||
/*
|
||||
* Sanity checks that block_offset is within the flash memory span and that the
|
||||
* block offset is sector aligned.
|
||||
*
|
||||
*/
|
||||
if((block_offset < 0)
|
||||
|| (block_offset >= epcq_flash_info->size_in_bytes)
|
||||
|| (block_offset & (epcq_flash_info->sector_size - 1)) != 0)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* calculate current sector/block number */
|
||||
sector_number = (block_offset/(epcq_flash_info->sector_size));
|
||||
|
||||
/* sector value should occupy bits 23:8 */
|
||||
mem_op_value = (sector_number << 8) & ALTERA_EPCQ_CONTROLLER_MEM_OP_SECTOR_VALUE_MASK;
|
||||
|
||||
/* sector erase commands 0b10 occupies lower 2 bits */
|
||||
mem_op_value |= ALTERA_EPCQ_CONTROLLER_MEM_OP_SECTOR_ERASE_CMD;
|
||||
|
||||
/* write sector erase command to EPCQ_MEM_OP register to erase sector "sector_number" */
|
||||
IOWR_ALTERA_EPCQ_CONTROLLER_MEM_OP(epcq_flash_info->csr_base, mem_op_value);
|
||||
|
||||
/* check whether erase triggered a illegal erase interrupt */
|
||||
if((IORD_ALTERA_EPCQ_CONTROLLER_ISR(epcq_flash_info->csr_base) &
|
||||
ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_ERASE_MASK) ==
|
||||
ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_ERASE_ACTIVE)
|
||||
{
|
||||
/* clear register */
|
||||
/* EPCQ_ISR access is write one to clear (W1C) */
|
||||
IOWR_ALTERA_EPCQ_CONTROLLER_ISR(epcq_flash_info->csr_base,
|
||||
ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_ERASE_MASK );
|
||||
return -EIO; /* erase failed, sector might be protected */
|
||||
}
|
||||
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* alt_epcq_controller_write_block
|
||||
*
|
||||
* This function writes one block/sector of data to flash. The length of the write can NOT
|
||||
* spill into the adjacent sector.
|
||||
*
|
||||
* It assumes that someone has already erased the appropriate sector(s).
|
||||
*
|
||||
* Arguments:
|
||||
* - *flash_info: Pointer to EPCQ flash device structure.
|
||||
* - block_offset: byte-addressed offset, from the start of flash, of the sector to written to
|
||||
* - data-offset: Byte offset (unaligned access) of write into flash memory.
|
||||
* For best performance, word(32 bits - aligned access) offset of write is recommended.
|
||||
* - *src_addr: source buffer
|
||||
* - length: size of writing
|
||||
*
|
||||
* Returns:
|
||||
* 0 -> success
|
||||
* -EINVAL -> Invalid arguments
|
||||
* -EIO -> write failed, sector might be protected
|
||||
**/
|
||||
int alt_epcq_controller_write_block
|
||||
(
|
||||
alt_flash_dev *flash_info, /** flash device info */
|
||||
int block_offset, /** sector/block offset in byte addressing */
|
||||
int data_offset, /** offset of write from base address */
|
||||
const void *data, /** data to be written */
|
||||
int length /** bytes of data to be written, >0 */
|
||||
)
|
||||
{
|
||||
alt_u32 buffer_offset = 0; /** offset into data buffer to get write data */
|
||||
alt_u32 remaining_length = length; /** length left to write */
|
||||
alt_u32 write_offset = data_offset; /** offset into flash to write too */
|
||||
|
||||
alt_epcq_controller_dev *epcq_flash_info = (alt_epcq_controller_dev*)flash_info;
|
||||
|
||||
/*
|
||||
* Sanity checks that data offset is not larger then a sector, that block offset is
|
||||
* sector aligned and within the valid flash memory range and a write doesn't spill into
|
||||
* the adjacent flash sector.
|
||||
*/
|
||||
if(block_offset < 0
|
||||
|| data_offset < 0
|
||||
|| NULL == flash_info
|
||||
|| NULL == data
|
||||
|| data_offset >= epcq_flash_info->size_in_bytes
|
||||
|| block_offset >= epcq_flash_info->size_in_bytes
|
||||
|| length > (epcq_flash_info->sector_size - (data_offset - block_offset))
|
||||
|| length < 0
|
||||
|| (block_offset & (epcq_flash_info->sector_size - 1)) != 0)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do writes one 32-bit word at a time.
|
||||
* We need to make sure that we pad the first few bytes so they're word aligned if they are
|
||||
* not already.
|
||||
*/
|
||||
while (remaining_length > 0)
|
||||
{
|
||||
alt_u32 word_to_write = 0xFFFFFFFF; /** initialize word to write to blank word */
|
||||
alt_u32 padding = 0; /** bytes to pad the next word that is written */
|
||||
alt_u32 bytes_to_copy = sizeof(alt_u32); /** number of bytes from source to copy */
|
||||
|
||||
/*
|
||||
* we need to make sure the write is word aligned
|
||||
* this should only be true at most 1 time
|
||||
*/
|
||||
if (0 != (write_offset & (sizeof(alt_u32) - 1)))
|
||||
{
|
||||
/*
|
||||
* data is not word aligned
|
||||
* calculate padding bytes need to add before start of a data offset
|
||||
*/
|
||||
padding = write_offset & (sizeof(alt_u32) - 1);
|
||||
|
||||
/* update variables to account for padding being added */
|
||||
bytes_to_copy -= padding;
|
||||
|
||||
if(bytes_to_copy > remaining_length)
|
||||
{
|
||||
bytes_to_copy = remaining_length;
|
||||
}
|
||||
|
||||
write_offset = write_offset - padding;
|
||||
if(0 != (write_offset & (sizeof(alt_u32) - 1)))
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(bytes_to_copy > remaining_length)
|
||||
{
|
||||
bytes_to_copy = remaining_length;
|
||||
}
|
||||
}
|
||||
|
||||
/* prepare the word to be written */
|
||||
memcpy((((void*)&word_to_write)) + padding, ((void*)data) + buffer_offset, bytes_to_copy);
|
||||
|
||||
/* update offset and length variables */
|
||||
buffer_offset += bytes_to_copy;
|
||||
remaining_length -= bytes_to_copy;
|
||||
|
||||
/* write to flash 32 bits at a time */
|
||||
IOWR_32DIRECT(epcq_flash_info->data_base, write_offset, word_to_write);
|
||||
|
||||
/* check whether write triggered a illegal write interrupt */
|
||||
if((IORD_ALTERA_EPCQ_CONTROLLER_ISR(epcq_flash_info->csr_base) &
|
||||
ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_WRITE_MASK) ==
|
||||
ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_WRITE_ACTIVE)
|
||||
{
|
||||
/* clear register */
|
||||
IOWR_ALTERA_EPCQ_CONTROLLER_ISR(epcq_flash_info->csr_base,
|
||||
ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_WRITE_MASK );
|
||||
return -EIO; /** write failed, sector might be protected */
|
||||
}
|
||||
|
||||
/* update current offset */
|
||||
write_offset = write_offset + sizeof(alt_u32);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* alt_epcq_controller_write
|
||||
*
|
||||
* Program the data into the flash at the selected address.
|
||||
*
|
||||
* The different between this function and alt_epcq_controller_write_block function
|
||||
* is that this function (alt_epcq_controller_write) will automatically erase a block as needed
|
||||
* Arguments:
|
||||
* - *flash_info: Pointer to EPCQ flash device structure.
|
||||
* - offset: Byte offset (unaligned access) of write to flash memory. For best performance,
|
||||
* word(32 bits - aligned access) offset of write is recommended.
|
||||
* - *src_addr: source buffer
|
||||
* - length: size of writing
|
||||
*
|
||||
* Returns:
|
||||
* 0 -> success
|
||||
* -EINVAL -> Invalid arguments
|
||||
* -EIO -> write failed, sector might be protected
|
||||
*
|
||||
**/
|
||||
int alt_epcq_controller_write(
|
||||
alt_flash_dev *flash_info, /** device info */
|
||||
int offset, /** offset of write from base address */
|
||||
const void *src_addr, /** source buffer */
|
||||
int length /** size of writing */
|
||||
)
|
||||
{
|
||||
alt_32 ret_code = 0;
|
||||
|
||||
alt_epcq_controller_dev *epcq_flash_info = NULL;
|
||||
|
||||
alt_u32 write_offset = offset; /** address of next byte to write */
|
||||
alt_u32 remaining_length = length; /** length of write data left to be written */
|
||||
alt_u32 buffer_offset = 0; /** offset into source buffer to get write data */
|
||||
alt_u32 i = 0;
|
||||
|
||||
/* return -EINVAL if flash_info and src_addr are NULL */
|
||||
if(NULL == flash_info || NULL == src_addr)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
epcq_flash_info = (alt_epcq_controller_dev*)flash_info;
|
||||
|
||||
/* make sure the write parameters are within the bounds of the flash */
|
||||
ret_code = alt_epcq_validate_read_write_arguments(epcq_flash_info, offset, length);
|
||||
|
||||
if(0 != ret_code)
|
||||
{
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
/*
|
||||
* This loop erases and writes data one sector at a time. We check for write completion
|
||||
* before starting the next sector.
|
||||
*/
|
||||
for(i = offset/epcq_flash_info->sector_size ; i < epcq_flash_info->number_of_sectors; i++)
|
||||
{
|
||||
alt_u32 block_offset = 0; /** block offset in byte addressing */
|
||||
alt_u32 offset_within_current_sector = 0; /** offset into current sector to write */
|
||||
alt_u32 length_to_write = 0; /** length to write to current sector */
|
||||
|
||||
if(0 >= remaining_length)
|
||||
{
|
||||
break; /* out of data to write */
|
||||
}
|
||||
|
||||
/* calculate current sector/block offset in byte addressing */
|
||||
block_offset = write_offset & ~(epcq_flash_info->sector_size - 1);
|
||||
|
||||
/* calculate offset into sector/block if there is one */
|
||||
if(block_offset != write_offset)
|
||||
{
|
||||
offset_within_current_sector = write_offset - block_offset;
|
||||
}
|
||||
|
||||
/* erase sector */
|
||||
ret_code = alt_epcq_controller_erase_block(flash_info, block_offset);
|
||||
|
||||
if(0 != ret_code)
|
||||
{
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
/* calculate the byte size of data to be written in a sector */
|
||||
length_to_write = MIN(epcq_flash_info->sector_size - offset_within_current_sector,
|
||||
remaining_length);
|
||||
|
||||
/* write data to erased block */
|
||||
ret_code = alt_epcq_controller_write_block(flash_info, block_offset, write_offset,
|
||||
src_addr + buffer_offset, length_to_write);
|
||||
|
||||
|
||||
if(0 != ret_code)
|
||||
{
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
/* update remaining length and buffer_offset pointer */
|
||||
remaining_length -= length_to_write;
|
||||
buffer_offset += length_to_write;
|
||||
write_offset += length_to_write;
|
||||
}
|
||||
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* alt_epcq_controller_read
|
||||
*
|
||||
* There's no real need to use this function as opposed to using memcpy directly. It does
|
||||
* do some sanity checks on the bounds of the read.
|
||||
*
|
||||
* Arguments:
|
||||
* - *flash_info: Pointer to general flash device structure.
|
||||
* - offset: offset read from flash memory.
|
||||
* - *dest_addr: destination buffer
|
||||
* - length: size of reading
|
||||
*
|
||||
* Returns:
|
||||
* 0 -> success
|
||||
* -EINVAL -> Invalid arguments
|
||||
**/
|
||||
int alt_epcq_controller_read
|
||||
(
|
||||
alt_flash_dev *flash_info, /** device info */
|
||||
int offset, /** offset of read from base address */
|
||||
void *dest_addr, /** destination buffer */
|
||||
int length /** size of read */
|
||||
)
|
||||
{
|
||||
alt_32 ret_code = 0;
|
||||
alt_epcq_controller_dev *epcq_flash_info = NULL;
|
||||
|
||||
/* return -EINVAL if flash_info and dest_addr are NULL */
|
||||
if(NULL == flash_info || NULL == dest_addr)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
epcq_flash_info = (alt_epcq_controller_dev*)flash_info;
|
||||
|
||||
/* validate arguments */
|
||||
ret_code = alt_epcq_validate_read_write_arguments(epcq_flash_info, offset, length);
|
||||
|
||||
/* copy data from flash to destination address */
|
||||
if(0 == ret_code)
|
||||
{
|
||||
memcpy(dest_addr, (alt_u8*)epcq_flash_info->data_base + offset, length);
|
||||
}
|
||||
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* altera_epcq_controller_init
|
||||
*
|
||||
* alt_sys_init.c will call this function automatically through macro
|
||||
*
|
||||
* Information in system.h is checked against expected values that are determined by the silicon_id.
|
||||
* If the information doesn't match then this system is configured incorrectly. Most likely the wrong
|
||||
* type of EPCS or EPCQ device was selected when instantiating the soft IP.
|
||||
*
|
||||
* Arguments:
|
||||
* - *flash: Pointer to EPCQ flash device structure.
|
||||
*
|
||||
* Returns:
|
||||
* 0 -> success
|
||||
* -EINVAL -> Invalid arguments.
|
||||
* -ENODEV -> System is configured incorrectly.
|
||||
**/
|
||||
alt_32 altera_epcq_controller_init(alt_epcq_controller_dev *flash)
|
||||
{
|
||||
alt_u32 silicon_id = 0;
|
||||
alt_u32 size_in_bytes = 0;
|
||||
alt_u32 number_of_sectors = 0;
|
||||
|
||||
/* return -EINVAL if flash is NULL */
|
||||
if(NULL == flash)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* return -ENODEV if CSR slave is not attached */
|
||||
if(NULL == (void *)flash->csr_base)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If flash is an EPCQ device, we read the EPCQ_RD_RDID register for the ID
|
||||
* If flash is an EPCS device, we read the EPCQ_RD_SID register for the ID
|
||||
*
|
||||
* Whether or not the flash is a EPCQ or EPCS is indicated in the system.h. The system.h gets
|
||||
* this value from the hw.tcl of the IP. If this value is set incorrectly, then things will go
|
||||
* badly.
|
||||
*
|
||||
* In both cases, we can determine the number of sectors, which we can use
|
||||
* to calculate a size. We compare that size to the system.h value to make sure
|
||||
* the EPCQ soft IP was configured correctly.
|
||||
*/
|
||||
if(0 == flash->is_epcs)
|
||||
{
|
||||
/* If we're an EPCQ, we read EPCQ_RD_RDID for the silicon ID */
|
||||
silicon_id = IORD_ALTERA_EPCQ_CONTROLLER_RDID(flash->csr_base);
|
||||
silicon_id &= ALTERA_EPCQ_CONTROLLER_RDID_MASK;
|
||||
|
||||
/* Determine which EPCQ device so we can figure out the number of sectors */
|
||||
/* EPCQ share the same ID for the same capacity*/
|
||||
switch(silicon_id)
|
||||
{
|
||||
case ALTERA_EPCQ_CONTROLLER_RDID_EPCQ16:
|
||||
{
|
||||
number_of_sectors = 32;
|
||||
break;
|
||||
}
|
||||
case ALTERA_EPCQ_CONTROLLER_RDID_EPCQ32:
|
||||
{
|
||||
number_of_sectors = 64;
|
||||
break;
|
||||
}
|
||||
case ALTERA_EPCQ_CONTROLLER_RDID_EPCQ64:
|
||||
{
|
||||
number_of_sectors = 128;
|
||||
break;
|
||||
}
|
||||
case ALTERA_EPCQ_CONTROLLER_RDID_EPCQ128:
|
||||
{
|
||||
number_of_sectors = 256;
|
||||
break;
|
||||
}
|
||||
case ALTERA_EPCQ_CONTROLLER_RDID_EPCQ256:
|
||||
{
|
||||
number_of_sectors = 512;
|
||||
break;
|
||||
}
|
||||
case ALTERA_EPCQ_CONTROLLER_RDID_EPCQ512:
|
||||
{
|
||||
number_of_sectors = 1024;
|
||||
break;
|
||||
}
|
||||
case ALTERA_EPCQ_CONTROLLER_RDID_EPCQ1024:
|
||||
{
|
||||
number_of_sectors = 2048;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* If we're an EPCS, we read EPCQ_RD_SID for the silicon ID */
|
||||
silicon_id = IORD_ALTERA_EPCQ_CONTROLLER_SID(flash->csr_base);
|
||||
silicon_id &= ALTERA_EPCQ_CONTROLLER_SID_MASK;
|
||||
|
||||
/* Determine which EPCS device so we can figure out various properties */
|
||||
switch(silicon_id)
|
||||
{
|
||||
case ALTERA_EPCQ_CONTROLLER_SID_EPCS16:
|
||||
{
|
||||
number_of_sectors = 32;
|
||||
break;
|
||||
}
|
||||
case ALTERA_EPCQ_CONTROLLER_SID_EPCS64:
|
||||
{
|
||||
number_of_sectors = 128;
|
||||
break;
|
||||
}
|
||||
case ALTERA_EPCQ_CONTROLLER_SID_EPCS128:
|
||||
{
|
||||
number_of_sectors = 256;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate size of flash based on number of sectors */
|
||||
size_in_bytes = number_of_sectors * flash->sector_size;
|
||||
|
||||
/*
|
||||
* Make sure calculated size is the same size given in system.h
|
||||
* Also check number of sectors is the same number given in system.h
|
||||
* Otherwise the EPCQ IP was not configured correctly
|
||||
*/
|
||||
if( size_in_bytes != flash->size_in_bytes ||
|
||||
number_of_sectors != flash->number_of_sectors)
|
||||
{
|
||||
flash->dev.number_of_regions = 0;
|
||||
return -ENODEV;
|
||||
}
|
||||
else
|
||||
{
|
||||
flash->silicon_id = silicon_id;
|
||||
flash->number_of_sectors = number_of_sectors;
|
||||
|
||||
/*
|
||||
* populate fields of region_info required to conform to HAL API
|
||||
* create 1 region that composed of "number_of_sectors" blocks
|
||||
*/
|
||||
flash->dev.number_of_regions = 1;
|
||||
flash->dev.region_info[0].offset = 0;
|
||||
flash->dev.region_info[0].region_size = size_in_bytes;
|
||||
flash->dev.region_info[0].number_of_blocks = number_of_sectors;
|
||||
flash->dev.region_info[0].block_size = flash->sector_size;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Register this device as a valid flash device type
|
||||
*
|
||||
* Only register the device if it's configured correctly.
|
||||
*/
|
||||
alt_flash_device_register(&(flash->dev));
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Private API
|
||||
*
|
||||
* Helper functions used by Public API functions.
|
||||
*
|
||||
* Arguments:
|
||||
* - *flash_info: Pointer to EPCQ flash device structure.
|
||||
* - offset: Offset of read/write from base address.
|
||||
* - length: Length of read/write in bytes.
|
||||
*
|
||||
* Returns:
|
||||
* 0 -> success
|
||||
* -EINVAL -> Invalid arguments
|
||||
*/
|
||||
/**
|
||||
* Used to check that arguments to a read or write are valid
|
||||
*/
|
||||
ALT_INLINE alt_32 static alt_epcq_validate_read_write_arguments
|
||||
(
|
||||
alt_epcq_controller_dev *flash_info, /** device info */
|
||||
alt_u32 offset, /** offset of read/write */
|
||||
alt_u32 length /** length of read/write */
|
||||
)
|
||||
{
|
||||
alt_epcq_controller_dev *epcq_flash_info = NULL;
|
||||
alt_u32 start_address = 0;
|
||||
alt_32 end_address = 0;
|
||||
|
||||
/* return -EINVAL if flash_info is NULL */
|
||||
if(NULL == flash_info)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
epcq_flash_info = (alt_epcq_controller_dev*)flash_info;
|
||||
|
||||
start_address = epcq_flash_info->data_base + offset; /** first address of read or write */
|
||||
end_address = start_address + length; /** last address of read or write (not inclusive) */
|
||||
|
||||
/* make sure start and end address is less then the end address of the flash */
|
||||
if(
|
||||
start_address >= epcq_flash_info->data_end ||
|
||||
end_address >= epcq_flash_info->data_end ||
|
||||
offset < 0 ||
|
||||
length < 0
|
||||
)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Private function that polls write in progress bit EPCQ_RD_STATUS.
|
||||
*
|
||||
* Write in progress will be set if any of the following operations are in progress:
|
||||
* -WRITE STATUS REGISTER
|
||||
* -WRITE NONVOLATILE CONFIGURATION REGISTER
|
||||
* -PROGRAM
|
||||
* -ERASE
|
||||
*
|
||||
* Assumes EPCQ was configured correctly.
|
||||
*
|
||||
* If ALTERA_EPCQ_CONTROLLER_1US_TIMEOUT_VALUE is set, the function will time out after
|
||||
* a period of time determined by that value.
|
||||
*
|
||||
* Arguments:
|
||||
* - *epcq_flash_info: Pointer to EPCQ flash device structure.
|
||||
*
|
||||
* Returns:
|
||||
* 0 -> success
|
||||
* -EINVAL -> Invalid arguments
|
||||
* -ETIME -> Time out and skipping the looping after 0.7 sec.
|
||||
*/
|
||||
alt_32 static alt_epcq_poll_for_write_in_progress(alt_epcq_controller_dev* epcq_flash_info)
|
||||
{
|
||||
/* we'll want to implement timeout if a timeout value is specified */
|
||||
#if ALTERA_EPCQ_CONTROLLER_1US_TIMEOUT_VALUE > 0
|
||||
alt_u32 timeout = ALTERA_EPCQ_CONTROLLER_1US_TIMEOUT_VALUE;
|
||||
alt_u16 counter = 0;
|
||||
#endif
|
||||
|
||||
/* return -EINVAL if epcq_flash_info is NULL */
|
||||
if(NULL == epcq_flash_info)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* while Write in Progress bit is set, we wait */
|
||||
while((IORD_ALTERA_EPCQ_CONTROLLER_STATUS(epcq_flash_info->csr_base) &
|
||||
ALTERA_EPCQ_CONTROLLER_STATUS_WIP_MASK) ==
|
||||
ALTERA_EPCQ_CONTROLLER_STATUS_WIP_BUSY)
|
||||
{
|
||||
alt_busy_sleep(1); /* delay 1us */
|
||||
#if ALTERA_EPCQ_CONTROLLER_1US_TIMEOUT_VALUE > 0
|
||||
if(timeout <= counter )
|
||||
{
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
counter++;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,611 @@
|
|||
// (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
// Your use of Altera Corporation's design tools, logic functions and other
|
||||
// software and tools, and its AMPP partner logic functions, and any output
|
||||
// files any of the foregoing (including device programming or simulation
|
||||
// files), and any associated documentation or information are expressly subject
|
||||
// to the terms and conditions of the Altera Program License Subscription
|
||||
// Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
// license agreement, including, without limitation, that your use is for the
|
||||
// sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
// Altera or its authorized distributors. Please refer to the applicable
|
||||
// agreement for further details.
|
||||
|
||||
|
||||
// (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
// Your use of Altera Corporation's design tools, logic functions and other
|
||||
// software and tools, and its AMPP partner logic functions, and any output
|
||||
// files any of the foregoing (including device programming or simulation
|
||||
// files), and any associated documentation or information are expressly subject
|
||||
// to the terms and conditions of the Altera Program License Subscription
|
||||
// Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
// license agreement, including, without limitation, that your use is for the
|
||||
// sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
// Altera or its authorized distributors. Please refer to the applicable
|
||||
// agreement for further details.
|
||||
|
||||
|
||||
|
||||
`timescale 1ps / 1ps
|
||||
|
||||
module altera_epcq_controller #(
|
||||
parameter CS_WIDTH = 1,
|
||||
parameter ENABLE_4BYTE_ADDR = 1,
|
||||
parameter ADDR_WIDTH = 22,
|
||||
parameter ASI_WIDTH = 1,
|
||||
parameter DEVICE_FAMILY = "CYCLONE V",
|
||||
parameter ASMI_ADDR_WIDTH = 22,
|
||||
parameter CHIP_SELS = 1
|
||||
)(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
// ports to access csr
|
||||
input wire avl_csr_write,
|
||||
input wire avl_csr_read,
|
||||
input wire [2:0] avl_csr_addr,
|
||||
input wire [31:0] avl_csr_wrdata,
|
||||
output reg [31:0] avl_csr_rddata,
|
||||
output reg avl_csr_rddata_valid,
|
||||
output reg avl_csr_waitrequest,
|
||||
|
||||
// ports to access memory
|
||||
input wire avl_mem_write,
|
||||
input wire avl_mem_read,
|
||||
input wire [ADDR_WIDTH-1:0] avl_mem_addr,
|
||||
input wire [31:0] avl_mem_wrdata,
|
||||
input wire [3:0] avl_mem_byteenable,
|
||||
input wire [6:0] avl_mem_burstcount,
|
||||
output wire [31:0] avl_mem_rddata,
|
||||
output reg avl_mem_rddata_valid,
|
||||
output reg avl_mem_waitrequest,
|
||||
|
||||
// interrupt signal
|
||||
output reg irq,
|
||||
|
||||
// Disable dedicated active serial interface
|
||||
input wire [ASI_WIDTH-1:0] epcq_dataout,
|
||||
output reg epcq_dclk,
|
||||
output reg [CS_WIDTH-1:0] epcq_scein,
|
||||
output reg [ASI_WIDTH-1:0] epcq_sdoin,
|
||||
output reg [ASI_WIDTH-1:0] epcq_dataoe,
|
||||
|
||||
// ASMI PARALLEL interface
|
||||
input wire [ASI_WIDTH-1:0] ddasi_dataoe,
|
||||
output reg [ASI_WIDTH-1:0] ddasi_dataout,
|
||||
input wire ddasi_dclk,
|
||||
input wire [CS_WIDTH-1:0] ddasi_scein,
|
||||
input reg [ASI_WIDTH-1:0] ddasi_sdoin,
|
||||
|
||||
input wire asmi_busy,
|
||||
input wire asmi_data_valid,
|
||||
input wire [7:0] asmi_dataout,
|
||||
output reg asmi_clkin,
|
||||
output reg asmi_reset,
|
||||
output reg [CS_WIDTH-1:0] asmi_sce,
|
||||
output reg [ASMI_ADDR_WIDTH-1:0] asmi_addr,
|
||||
output reg [7:0] asmi_datain,
|
||||
output reg asmi_fast_read,
|
||||
output wire asmi_rden,
|
||||
output reg asmi_shift_bytes,
|
||||
output reg asmi_en4b_addr,
|
||||
output wire asmi_wren,
|
||||
output reg asmi_write,
|
||||
|
||||
input wire asmi_illegal_erase,
|
||||
input wire asmi_illegal_write,
|
||||
input wire [7:0] asmi_rdid_out,
|
||||
input wire [7:0] asmi_status_out,
|
||||
input wire [7:0] asmi_epcs_id,
|
||||
output reg asmi_read_rdid,
|
||||
output reg asmi_read_status,
|
||||
output reg asmi_read_sid,
|
||||
output reg asmi_bulk_erase,
|
||||
output reg asmi_sector_erase,
|
||||
output reg asmi_sector_protect
|
||||
);
|
||||
localparam LOCAL_ADDR_WIDTH = ADDR_WIDTH+2;
|
||||
localparam CSR_DATA_WIDTH = 32;
|
||||
localparam LAST_ADDR_BIT = (ASMI_ADDR_WIDTH == 24) ? 15 :
|
||||
(ASMI_ADDR_WIDTH == 32) ? 23 : 15;
|
||||
|
||||
reg [8:0] wr_burstcount_cnt, rd_burstcount_cnt;
|
||||
reg [8:0] rd_mem_burstcount, wr_mem_burstcount;
|
||||
|
||||
wire last_wr_byte;
|
||||
wire access_csr_status, access_csr_sid, access_csr_rdid, access_csr_mem_op, access_isr, access_imr, access_sce;
|
||||
wire read_status_combi, read_sid_combi, read_rdid_combi, read_isr_combi, read_imr_combi, write_isr_combi, write_imr_combi, write_sce_combi;
|
||||
wire bulk_erase_combi, sector_erase_combi, sector_protect_combi;
|
||||
wire wren_combi, illegal_write_combi, illegal_erase_combi;
|
||||
wire m_illegal_write_combi, m_illegal_erase_combi;
|
||||
wire read_mem_combi, write_mem_combi;
|
||||
wire data_valid_combi, pending_wr_data;
|
||||
wire detect_addroffset;
|
||||
wire [8:0] wfifo_data_in_0, wfifo_data_in_1, wfifo_data_in_2, wfifo_data_in_3;
|
||||
wire [ADDR_WIDTH-1:0] temp_mem_addr;
|
||||
|
||||
reg reset_n_reg;
|
||||
reg wr_mem_waitrequest, local_waitrequest;
|
||||
reg illegal_write_reg, illegal_erase_reg, m_illegal_write_reg, m_illegal_erase_reg;
|
||||
reg read_status_valid, read_sid_valid, read_rdid_valid, read_isr_valid, read_imr_valid;
|
||||
reg read_status_en, read_sid_en, read_rdid_en;
|
||||
reg wren_internal;
|
||||
reg [LOCAL_ADDR_WIDTH-1:0] wr_mem_addr;
|
||||
reg [7:0] rd_data_reg [4];
|
||||
reg [3:0][8:0] wr_data_reg;
|
||||
reg [1:0] rd_cnt;
|
||||
reg [1:0] wr_cnt;
|
||||
reg [3:0] wr_data_reg_full;
|
||||
reg detect_addroffset_reg, asmi_busy_reg;
|
||||
reg [2:0] temp_sce;
|
||||
|
||||
// Direct connection
|
||||
assign asmi_clkin = clk;
|
||||
assign asmi_reset = ~reset_n;
|
||||
assign ddasi_dataout = epcq_dataout;
|
||||
assign epcq_dclk = ddasi_dclk;
|
||||
assign epcq_scein = ddasi_scein;
|
||||
assign epcq_sdoin = ddasi_sdoin;
|
||||
assign epcq_dataoe = ddasi_dataoe;
|
||||
|
||||
// chip select
|
||||
generate if (DEVICE_FAMILY == "Arria 10") begin
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (~reset_n) begin
|
||||
asmi_sce <= {CS_WIDTH{1'b0}};
|
||||
end
|
||||
// to pack the address space this is needed
|
||||
else if (write_mem_combi || read_mem_combi) begin
|
||||
if (CHIP_SELS == 1 )
|
||||
asmi_sce <= 3'b001;
|
||||
else if (CHIP_SELS == 2 && avl_mem_addr[ADDR_WIDTH-1] == 0)
|
||||
asmi_sce <= 3'b001;
|
||||
else if (CHIP_SELS == 2 && avl_mem_addr[ADDR_WIDTH-1] == 1)
|
||||
asmi_sce <= 3'b010;
|
||||
else if (CHIP_SELS == 3 && avl_mem_addr[ADDR_WIDTH-1] == 1)
|
||||
asmi_sce <= 3'b100;
|
||||
else if (CHIP_SELS == 3 && avl_mem_addr[ADDR_WIDTH-1:ADDR_WIDTH-2] == 0)
|
||||
asmi_sce <= 3'b001;
|
||||
else if (CHIP_SELS == 3 && avl_mem_addr[ADDR_WIDTH-1:ADDR_WIDTH-2] == 1)
|
||||
asmi_sce <= 3'b010;
|
||||
else
|
||||
asmi_sce <= {CS_WIDTH{1'b0}};
|
||||
end
|
||||
else if (write_sce_combi) begin
|
||||
asmi_sce <= avl_csr_wrdata[2:0];
|
||||
end
|
||||
else if (asmi_en4b_addr) begin
|
||||
asmi_sce <= temp_sce;
|
||||
end
|
||||
end
|
||||
// decoder ring if the CHIP_SEL is only 1 then avalon address is the temp address
|
||||
// if the chipsele is 2 then need to remove top address bit
|
||||
// if the chipelect is 3 then remove the top 2 address bits.
|
||||
assign temp_mem_addr = CHIP_SELS == 1 ? avl_mem_addr:( CHIP_SELS == 2 ? {1'b0,avl_mem_addr[ADDR_WIDTH-2:0]}:{2'b00,avl_mem_addr[ADDR_WIDTH-3:0]});
|
||||
end
|
||||
else begin
|
||||
always @(posedge clk) begin
|
||||
asmi_sce <= {CS_WIDTH{1'b0}};
|
||||
end
|
||||
assign temp_mem_addr = avl_mem_addr;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// wait_request generation logic
|
||||
assign avl_mem_waitrequest = (asmi_busy || asmi_busy_reg) ? 1'b1 : (local_waitrequest || wr_mem_waitrequest);
|
||||
assign avl_csr_waitrequest = (asmi_busy || asmi_busy_reg) ? 1'b1 : (local_waitrequest || wr_mem_waitrequest);
|
||||
|
||||
// access CSR decoding logic
|
||||
assign access_csr_status = (avl_csr_addr == 3'b000);
|
||||
assign access_csr_sid = (avl_csr_addr == 3'b001);
|
||||
assign access_csr_rdid = (avl_csr_addr == 3'b010);
|
||||
assign access_csr_mem_op = (avl_csr_addr == 3'b011);
|
||||
assign access_isr = (avl_csr_addr == 3'b100);
|
||||
assign access_imr = (avl_csr_addr == 3'b101);
|
||||
assign access_sce = (avl_csr_addr == 3'b110);
|
||||
|
||||
// read/write memory combi logic
|
||||
assign read_mem_combi = (avl_mem_read && ~avl_mem_waitrequest);
|
||||
assign write_mem_combi = (avl_mem_write && ~avl_mem_waitrequest);
|
||||
|
||||
// read csr logic
|
||||
assign read_status_combi = (avl_csr_read && access_csr_status && ~avl_csr_waitrequest);
|
||||
assign read_sid_combi = (avl_csr_read && access_csr_sid && ~avl_csr_waitrequest);
|
||||
assign read_rdid_combi = (avl_csr_read && access_csr_rdid && ~avl_csr_waitrequest);
|
||||
assign read_isr_combi = (avl_csr_read && access_isr && ~avl_csr_waitrequest);
|
||||
assign read_imr_combi = (avl_csr_read && access_imr && ~avl_csr_waitrequest);
|
||||
assign write_isr_combi = (avl_csr_write && access_isr && ~avl_csr_waitrequest);
|
||||
assign write_imr_combi = (avl_csr_write && access_imr && ~avl_csr_waitrequest);
|
||||
assign write_sce_combi = (avl_csr_write && access_sce && ~avl_csr_waitrequest);
|
||||
|
||||
// write csr logic
|
||||
assign bulk_erase_combi = (avl_csr_write && access_csr_mem_op && ~avl_csr_waitrequest && avl_csr_wrdata[1:0] == 2'b01);
|
||||
assign sector_erase_combi = (avl_csr_write && access_csr_mem_op && ~avl_csr_waitrequest && avl_csr_wrdata[1:0] == 2'b10);
|
||||
assign sector_protect_combi = (avl_csr_write && access_csr_mem_op && ~avl_csr_waitrequest && avl_csr_wrdata[1:0] == 2'b11);
|
||||
assign illegal_write_combi = (asmi_illegal_write) ? 1'b1 :
|
||||
(write_isr_combi && avl_csr_wrdata[1]) ? 1'b0 :
|
||||
illegal_write_reg;
|
||||
assign illegal_erase_combi = (asmi_illegal_erase) ? 1'b1 :
|
||||
(write_isr_combi && avl_csr_wrdata[0]) ? 1'b0 :
|
||||
illegal_erase_reg;
|
||||
assign m_illegal_write_combi= (write_imr_combi) ? avl_csr_wrdata[1] : m_illegal_write_reg;
|
||||
assign m_illegal_erase_combi= (write_imr_combi) ? avl_csr_wrdata[0] : m_illegal_erase_reg;
|
||||
assign wren_combi = (sector_protect_combi || sector_erase_combi || bulk_erase_combi);
|
||||
|
||||
assign asmi_rden = (rd_burstcount_cnt > 9'd0); // deasserted at the last 2 byte - refer to ASMI_PARALLEL UG
|
||||
|
||||
// interrupt signal
|
||||
assign irq = (illegal_write_reg && m_illegal_write_reg) || (illegal_erase_reg && m_illegal_erase_reg);
|
||||
|
||||
assign last_wr_byte = (wr_burstcount_cnt == wr_mem_burstcount - 9'd1) ? 1'b1 : 1'b0;
|
||||
|
||||
assign asmi_wren = wren_internal || asmi_en4b_addr || asmi_shift_bytes || asmi_write;
|
||||
|
||||
assign data_valid_combi = (rd_burstcount_cnt[1:0] == 2'b00) ? asmi_data_valid : 1'b0;
|
||||
|
||||
assign wfifo_data_in_0 = {avl_mem_byteenable[0], avl_mem_wrdata[7:0] };
|
||||
assign wfifo_data_in_1 = {avl_mem_byteenable[1], avl_mem_wrdata[15:8] };
|
||||
assign wfifo_data_in_2 = {avl_mem_byteenable[2], avl_mem_wrdata[23:16] };
|
||||
assign wfifo_data_in_3 = {avl_mem_byteenable[3], avl_mem_wrdata[31:24] };
|
||||
|
||||
assign avl_mem_rddata = {rd_data_reg[3], rd_data_reg[2], rd_data_reg[1], rd_data_reg[0]};
|
||||
assign pending_wr_data = (|wr_data_reg_full) ? 1'b1 : 1'b0;
|
||||
assign detect_addroffset = (pending_wr_data && wr_data_reg[wr_cnt][8]) ? 1'b1 :
|
||||
(wr_burstcount_cnt == {9{1'b0}}) ? 1'b0 : detect_addroffset_reg;
|
||||
|
||||
//-------------------------------- array to store write data -------------------------------------
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (~reset_n) begin
|
||||
wr_data_reg <= '{{9{1'b0}}, {9{1'b0}}, {9{1'b0}}, {9{1'b0}}};
|
||||
wr_data_reg_full <= {4{1'b0}};
|
||||
end
|
||||
else if (write_mem_combi) begin
|
||||
wr_data_reg <= {wfifo_data_in_3, wfifo_data_in_2, wfifo_data_in_1, wfifo_data_in_0};
|
||||
wr_data_reg_full <= {4{1'b1}};
|
||||
end
|
||||
else if (wr_data_reg_full > 4'b0000) begin
|
||||
wr_data_reg_full <= wr_data_reg_full << 1;
|
||||
end
|
||||
end
|
||||
|
||||
//-------------------------------- array to store read data -------------------------------------
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (~reset_n) begin
|
||||
rd_data_reg <= '{{8{1'b0}}, {8{1'b0}}, {8{1'b0}}, {8{1'b0}}};
|
||||
rd_cnt <= {2{1'b0}};
|
||||
end
|
||||
else if (asmi_data_valid) begin
|
||||
rd_data_reg[rd_cnt] <= asmi_dataout;
|
||||
rd_cnt <= rd_cnt + 2'b01;
|
||||
end
|
||||
end
|
||||
|
||||
//------------------------------- Enable 4-byte addressing out of reset ----------------------
|
||||
generate
|
||||
if (ENABLE_4BYTE_ADDR) begin
|
||||
typedef enum logic[1:0] {EN4B_CHIP1, EN4B_CHIP2, EN4B_CHIP3, IDLE} state_t;
|
||||
state_t state;
|
||||
|
||||
always @(posedge clk or negedge reset_n_reg) begin // use reset_n_reg because user is allow to send cmd to ASMI_PARALLEL 2 clock cycles after reset
|
||||
if (~reset_n_reg) begin
|
||||
state <= EN4B_CHIP1;
|
||||
asmi_en4b_addr <= 1'b1;
|
||||
temp_sce <= 3'b001;
|
||||
end
|
||||
else begin
|
||||
case (state)
|
||||
EN4B_CHIP1 : begin
|
||||
asmi_en4b_addr <= 1'b1;
|
||||
if (~asmi_busy) begin
|
||||
if (CHIP_SELS > 1) begin
|
||||
state <= EN4B_CHIP2;
|
||||
temp_sce <= 3'b010;
|
||||
end
|
||||
else begin
|
||||
state <= IDLE;
|
||||
temp_sce <= 3'b000;
|
||||
end
|
||||
end
|
||||
end
|
||||
EN4B_CHIP2 : begin
|
||||
asmi_en4b_addr <= 1'b1;
|
||||
if (~asmi_busy) begin
|
||||
if (CHIP_SELS > 2) begin
|
||||
state <= EN4B_CHIP3;
|
||||
temp_sce <= 3'b100;
|
||||
end
|
||||
else begin
|
||||
state <= IDLE;
|
||||
temp_sce <= 3'b000;
|
||||
end
|
||||
end
|
||||
end
|
||||
EN4B_CHIP3 : begin
|
||||
asmi_en4b_addr <= 1'b1;
|
||||
if (~asmi_busy) begin
|
||||
state <= IDLE;
|
||||
temp_sce <= 3'b000;
|
||||
end
|
||||
end
|
||||
IDLE : begin
|
||||
asmi_en4b_addr <= 1'b0;
|
||||
state <= IDLE;
|
||||
temp_sce <= 3'b000;
|
||||
end
|
||||
default : begin
|
||||
asmi_en4b_addr <= 1'b0;
|
||||
state <= IDLE;
|
||||
temp_sce <= 3'b000;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
else begin
|
||||
always @(posedge clk) begin
|
||||
asmi_en4b_addr <= 1'b0;
|
||||
temp_sce <= 3'b000;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
//--------------------------------------- Waitrequest logic ----------------------------------
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (~reset_n) begin
|
||||
wr_mem_waitrequest <= 1'b0;
|
||||
local_waitrequest <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
if (read_mem_combi || read_status_combi || read_sid_combi || read_rdid_combi || bulk_erase_combi || sector_erase_combi || sector_protect_combi || asmi_en4b_addr) begin // no back pressure during imr & isr access
|
||||
local_waitrequest <= 1'b1;
|
||||
end
|
||||
else if (asmi_busy_reg && ~asmi_busy) begin
|
||||
local_waitrequest <= 1'b0;
|
||||
end
|
||||
|
||||
if (write_mem_combi) begin
|
||||
wr_mem_waitrequest <= 1'b1;
|
||||
end
|
||||
else if ((~pending_wr_data && ~asmi_write) || asmi_busy_reg && ~asmi_busy) begin
|
||||
wr_mem_waitrequest <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// -------------------------------------- MEM ACCESS -----------------------------------------
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (~reset_n) begin
|
||||
rd_mem_burstcount <= {9{1'b0}};
|
||||
wr_mem_burstcount <= {9{1'b0}};
|
||||
wr_mem_addr <= {LOCAL_ADDR_WIDTH{1'b0}};
|
||||
end
|
||||
else begin
|
||||
if (read_mem_combi) begin
|
||||
rd_mem_burstcount <= {avl_mem_burstcount, 2'b00};
|
||||
end
|
||||
if (write_mem_combi && (wr_burstcount_cnt == {9{1'b0}})) begin
|
||||
wr_mem_addr <= {temp_mem_addr, 2'b00};
|
||||
wr_mem_burstcount <= {avl_mem_burstcount, 2'b00};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (~reset_n) begin
|
||||
wr_burstcount_cnt <= {9{1'b0}};
|
||||
end
|
||||
else begin
|
||||
if (pending_wr_data) begin
|
||||
wr_burstcount_cnt <= wr_burstcount_cnt + 9'd1;
|
||||
end
|
||||
else if (wr_burstcount_cnt == wr_mem_burstcount) begin
|
||||
wr_burstcount_cnt <= {9{1'b0}};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (~reset_n) begin
|
||||
rd_burstcount_cnt <= {9{1'b0}};
|
||||
end
|
||||
else begin
|
||||
if (read_mem_combi) begin
|
||||
rd_burstcount_cnt <= 9'd1;
|
||||
end
|
||||
else if (rd_burstcount_cnt == rd_mem_burstcount) begin // each rd 4 burst
|
||||
rd_burstcount_cnt <= {9{1'b0}};
|
||||
end
|
||||
else if (asmi_data_valid && rd_burstcount_cnt > 0) begin
|
||||
rd_burstcount_cnt <= rd_burstcount_cnt + 9'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (~reset_n) begin
|
||||
asmi_addr <= {ASMI_ADDR_WIDTH{1'b0}};
|
||||
end
|
||||
else begin
|
||||
if (sector_erase_combi) begin // set lower 16 bits to zero so that erase at starting address of each sector
|
||||
asmi_addr <= {avl_csr_wrdata[LAST_ADDR_BIT : 8], {16{1'b0}}};
|
||||
end
|
||||
if (read_mem_combi) begin
|
||||
asmi_addr <= {temp_mem_addr, 2'b00};
|
||||
end
|
||||
|
||||
if (detect_addroffset && ~detect_addroffset_reg) begin
|
||||
asmi_addr <= wr_mem_addr + {{LOCAL_ADDR_WIDTH-9{1'b0}}, wr_burstcount_cnt};
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (~reset_n) begin
|
||||
asmi_datain <= {8{1'b0}};
|
||||
wr_cnt <= {2{1'b0}};
|
||||
asmi_shift_bytes <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
if (sector_protect_combi) begin
|
||||
asmi_datain <= {{1{1'b0}}, avl_csr_wrdata[11], avl_csr_wrdata[12], avl_csr_wrdata[10:8], {2{1'b0}}}; // BP3, TB, BP2, BP1, BP0
|
||||
end
|
||||
if (pending_wr_data) begin
|
||||
asmi_datain <= wr_data_reg[wr_cnt][7:0];
|
||||
wr_cnt <= wr_cnt + 2'd1;
|
||||
end
|
||||
if (pending_wr_data && wr_data_reg[wr_cnt][8]) begin
|
||||
asmi_shift_bytes <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
asmi_shift_bytes <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (~reset_n) begin
|
||||
asmi_read_status <= 1'b0;
|
||||
asmi_read_sid <= 1'b0;
|
||||
asmi_read_rdid <= 1'b0;
|
||||
asmi_bulk_erase <= 1'b0;
|
||||
asmi_sector_erase <= 1'b0;
|
||||
asmi_sector_protect <= 1'b0;
|
||||
wren_internal <= 1'b0;
|
||||
asmi_write <= 1'b0;
|
||||
asmi_fast_read <= 1'b0;
|
||||
asmi_busy_reg <= 1'b0;
|
||||
avl_mem_rddata_valid <= 1'b0;
|
||||
detect_addroffset_reg <= 1'b0;
|
||||
reset_n_reg <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
asmi_read_status <= read_status_combi;
|
||||
asmi_read_sid <= read_sid_combi;
|
||||
asmi_read_rdid <= read_rdid_combi;
|
||||
asmi_bulk_erase <= bulk_erase_combi;
|
||||
asmi_sector_erase <= sector_erase_combi;
|
||||
asmi_sector_protect <= sector_protect_combi;
|
||||
wren_internal <= wren_combi;
|
||||
asmi_write <= last_wr_byte;
|
||||
asmi_fast_read <= read_mem_combi;
|
||||
asmi_busy_reg <= asmi_busy;
|
||||
avl_mem_rddata_valid <= data_valid_combi;
|
||||
detect_addroffset_reg <= detect_addroffset;
|
||||
reset_n_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// --------------------------------------------- CSR ACCESS -------------------------------------
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (~reset_n) begin
|
||||
illegal_write_reg <= 1'b0;
|
||||
illegal_erase_reg <= 1'b0;
|
||||
m_illegal_write_reg <= 1'b0;
|
||||
m_illegal_erase_reg <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
illegal_write_reg <= illegal_write_combi;
|
||||
illegal_erase_reg <= illegal_erase_combi;
|
||||
m_illegal_write_reg <= m_illegal_write_combi;
|
||||
m_illegal_erase_reg <= m_illegal_erase_combi;
|
||||
end
|
||||
end
|
||||
|
||||
// csr read only registers enable logic
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (~reset_n) begin
|
||||
read_status_en <= 1'b0;
|
||||
read_sid_en <= 1'b0;
|
||||
read_rdid_en <= 1'b0;
|
||||
end
|
||||
else if (asmi_read_status) begin
|
||||
read_status_en <= 1'b1;
|
||||
end
|
||||
else if (asmi_read_sid) begin
|
||||
read_sid_en <= 1'b1;
|
||||
end
|
||||
else if (asmi_read_rdid) begin
|
||||
read_rdid_en <= 1'b1;
|
||||
end
|
||||
else if (asmi_busy == 0) begin
|
||||
read_status_en <= 1'b0;
|
||||
read_sid_en <= 1'b0;
|
||||
read_rdid_en <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// generation logic for avl csr read data valid
|
||||
assign avl_csr_rddata_valid = read_status_valid || read_sid_valid || read_rdid_valid || read_isr_valid || read_imr_valid;
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (~reset_n) begin
|
||||
read_status_valid <= 1'b0;
|
||||
read_sid_valid <= 1'b0;
|
||||
read_rdid_valid <= 1'b0;
|
||||
read_isr_valid <= 1'b0;
|
||||
read_imr_valid <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
if (read_status_en && asmi_busy == 0) begin
|
||||
read_status_valid <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
read_status_valid <= 1'b0;
|
||||
end
|
||||
|
||||
if (read_sid_en && asmi_busy == 0) begin
|
||||
read_sid_valid <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
read_sid_valid <= 1'b0;
|
||||
end
|
||||
|
||||
if (read_rdid_en && asmi_busy == 0) begin
|
||||
read_rdid_valid <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
read_rdid_valid <= 1'b0;
|
||||
end
|
||||
|
||||
if (read_isr_combi) begin
|
||||
read_isr_valid <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
read_isr_valid <= 1'b0;
|
||||
end
|
||||
|
||||
if (read_imr_combi) begin
|
||||
read_imr_valid <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
read_imr_valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// generation logic for avl csr read data
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (~reset_n) begin
|
||||
avl_csr_rddata <= {CSR_DATA_WIDTH{1'b0}};
|
||||
end
|
||||
else begin
|
||||
if (read_status_en && asmi_busy == 0) begin
|
||||
avl_csr_rddata <= {{CSR_DATA_WIDTH-8{1'b0}}, asmi_status_out};
|
||||
end
|
||||
if (read_sid_en && asmi_busy == 0) begin
|
||||
avl_csr_rddata <= {{CSR_DATA_WIDTH-8{1'b0}}, asmi_epcs_id};
|
||||
end
|
||||
if (read_rdid_en && asmi_busy == 0) begin
|
||||
avl_csr_rddata <= {{CSR_DATA_WIDTH-8{1'b0}}, asmi_rdid_out};
|
||||
end
|
||||
if (read_isr_combi) begin
|
||||
avl_csr_rddata <= {{CSR_DATA_WIDTH-2{1'b0}}, illegal_write_reg, illegal_erase_reg};
|
||||
end
|
||||
if (read_imr_combi) begin
|
||||
avl_csr_rddata <= {{CSR_DATA_WIDTH-2{1'b0}}, m_illegal_write_reg, m_illegal_erase_reg};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,230 @@
|
|||
// (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
// Your use of Altera Corporation's design tools, logic functions and other
|
||||
// software and tools, and its AMPP partner logic functions, and any output
|
||||
// files any of the foregoing (including device programming or simulation
|
||||
// files), and any associated documentation or information are expressly subject
|
||||
// to the terms and conditions of the Altera Program License Subscription
|
||||
// Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
// license agreement, including, without limitation, that your use is for the
|
||||
// sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
// Altera or its authorized distributors. Please refer to the applicable
|
||||
// agreement for further details.
|
||||
|
||||
|
||||
// (C) 2001-2014 Altera Corporation. All rights reserved.
|
||||
// Your use of Altera Corporation's design tools, logic functions and other
|
||||
// software and tools, and its AMPP partner logic functions, and any output
|
||||
// files any of the foregoing (including device programming or simulation
|
||||
// files), and any associated documentation or information are expressly subject
|
||||
// to the terms and conditions of the Altera Program License Subscription
|
||||
// Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
// license agreement, including, without limitation, that your use is for the
|
||||
// sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
// Altera or its authorized distributors. Please refer to the applicable
|
||||
// agreement for further details.
|
||||
|
||||
`timescale 1ps / 1ps
|
||||
|
||||
module altera_epcq_controller_arb #(
|
||||
parameter CS_WIDTH = 1,
|
||||
parameter ENABLE_4BYTE_ADDR = 1,
|
||||
parameter ADDR_WIDTH = 22,
|
||||
parameter ASI_WIDTH = 1,
|
||||
parameter DEVICE_FAMILY = "CYCLONE V",
|
||||
parameter ASMI_ADDR_WIDTH = 22,
|
||||
parameter CHIP_SELS = 1
|
||||
)(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
// ports to access csr
|
||||
input wire avl_csr_write,
|
||||
input wire avl_csr_read,
|
||||
input wire [2:0] avl_csr_addr,
|
||||
input wire [31:0] avl_csr_wrdata,
|
||||
output reg [31:0] avl_csr_rddata,
|
||||
output reg avl_csr_rddata_valid,
|
||||
output reg avl_csr_waitrequest,
|
||||
|
||||
// ports to access memory
|
||||
input wire avl_mem_write,
|
||||
input wire avl_mem_read,
|
||||
input wire [ADDR_WIDTH-1:0] avl_mem_addr,
|
||||
input wire [31:0] avl_mem_wrdata,
|
||||
input wire [3:0] avl_mem_byteenable,
|
||||
input wire [6:0] avl_mem_burstcount,
|
||||
output wire [31:0] avl_mem_rddata,
|
||||
output reg avl_mem_rddata_valid,
|
||||
output reg avl_mem_waitrequest,
|
||||
|
||||
// interrupt signal
|
||||
output reg irq,
|
||||
|
||||
// Disable dedicated active serial interface
|
||||
input wire [ASI_WIDTH-1:0] epcq_dataout,
|
||||
output reg epcq_dclk,
|
||||
output reg [CS_WIDTH-1:0] epcq_scein,
|
||||
output reg [ASI_WIDTH-1:0] epcq_sdoin,
|
||||
output reg [ASI_WIDTH-1:0] epcq_dataoe,
|
||||
|
||||
// ASMI PARALLEL interface
|
||||
input wire [ASI_WIDTH-1:0] ddasi_dataoe,
|
||||
output reg [ASI_WIDTH-1:0] ddasi_dataout,
|
||||
input wire ddasi_dclk,
|
||||
input wire [CS_WIDTH-1:0] ddasi_scein,
|
||||
input reg [ASI_WIDTH-1:0] ddasi_sdoin,
|
||||
|
||||
input wire asmi_busy,
|
||||
input wire asmi_data_valid,
|
||||
input wire [7:0] asmi_dataout,
|
||||
output reg asmi_clkin,
|
||||
output reg asmi_reset,
|
||||
output reg [CS_WIDTH-1:0] asmi_sce,
|
||||
output reg [ASMI_ADDR_WIDTH-1:0] asmi_addr,
|
||||
output reg [7:0] asmi_datain,
|
||||
output reg asmi_fast_read,
|
||||
output wire asmi_rden,
|
||||
output reg asmi_shift_bytes,
|
||||
output reg asmi_en4b_addr,
|
||||
output wire asmi_wren,
|
||||
output reg asmi_write,
|
||||
|
||||
input wire asmi_illegal_erase,
|
||||
input wire asmi_illegal_write,
|
||||
input wire [7:0] asmi_rdid_out,
|
||||
input wire [7:0] asmi_status_out,
|
||||
input wire [7:0] asmi_epcs_id,
|
||||
output reg asmi_read_rdid,
|
||||
output reg asmi_read_status,
|
||||
output reg asmi_read_sid,
|
||||
output reg asmi_bulk_erase,
|
||||
output reg asmi_sector_erase,
|
||||
output reg asmi_sector_protect
|
||||
);
|
||||
|
||||
reg temp_mem_write, temp_mem_read, mem_write, mem_read, back_pressured_ctrl;
|
||||
reg [ADDR_WIDTH-1:0] temp_mem_addr, mem_addr;
|
||||
reg [31:0] temp_mem_wrdata, mem_wrdata;
|
||||
reg [3:0] temp_mem_byteenable, mem_byteenable;
|
||||
reg [6:0] temp_mem_burstcount, mem_burstcount;
|
||||
|
||||
wire back_pressured, temp_csr_waitrequest, temp_mem_waitrequest;
|
||||
|
||||
//-------------------- Arbitration logic between avalon csr and mem interface -----------
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (~reset_n) begin
|
||||
back_pressured_ctrl <= 1'b0;
|
||||
end
|
||||
else if (back_pressured) begin
|
||||
back_pressured_ctrl <= 1'b1;
|
||||
end
|
||||
else if (~temp_csr_waitrequest) begin
|
||||
back_pressured_ctrl <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (~reset_n) begin
|
||||
mem_write <= 1'b0;
|
||||
mem_read <= 1'b0;
|
||||
mem_addr <= {ADDR_WIDTH{1'b0}};
|
||||
mem_wrdata <= {32{1'b0}};
|
||||
mem_byteenable <= {4{1'b0}};
|
||||
mem_burstcount <= {7{1'b0}};
|
||||
end
|
||||
else if ((avl_csr_write || avl_csr_read) && ~avl_csr_waitrequest && (avl_mem_write || avl_mem_read) && ~avl_mem_waitrequest) begin
|
||||
// to back pressure master
|
||||
mem_write <= avl_mem_write;
|
||||
mem_read <= avl_mem_read;
|
||||
mem_addr <= avl_mem_addr;
|
||||
mem_wrdata <= avl_mem_wrdata;
|
||||
mem_byteenable <= avl_mem_byteenable;
|
||||
mem_burstcount <= avl_mem_burstcount;
|
||||
end
|
||||
end
|
||||
|
||||
assign back_pressured = ((avl_csr_write || avl_csr_read) && ~temp_csr_waitrequest && (avl_mem_write || avl_mem_read)) ? 1'b1 : 1'b0; // to back pressure controller
|
||||
assign avl_csr_waitrequest = (~avl_csr_write && ~avl_csr_read && back_pressured_ctrl) ? 1'b1 : temp_csr_waitrequest;
|
||||
assign avl_mem_waitrequest = (back_pressured_ctrl) ? 1'b1 : temp_mem_waitrequest;
|
||||
assign temp_mem_write = (back_pressured) ? 1'b0 :
|
||||
(back_pressured_ctrl) ? mem_write : avl_mem_write;
|
||||
assign temp_mem_read = (back_pressured) ? 1'b0 :
|
||||
(back_pressured_ctrl) ? mem_read : avl_mem_read;
|
||||
assign temp_mem_addr = (back_pressured) ? {ADDR_WIDTH{1'b0}} :
|
||||
(back_pressured_ctrl) ? mem_addr : avl_mem_addr;
|
||||
assign temp_mem_wrdata = (back_pressured) ? {32{1'b0}} :
|
||||
(back_pressured_ctrl) ? mem_wrdata : avl_mem_wrdata;
|
||||
assign temp_mem_byteenable = (back_pressured) ? {4{1'b0}} :
|
||||
(back_pressured_ctrl) ? mem_byteenable : avl_mem_byteenable;
|
||||
assign temp_mem_burstcount = (back_pressured) ? {7{1'b0}} :
|
||||
(back_pressured_ctrl) ? mem_burstcount : avl_mem_burstcount;
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------//
|
||||
|
||||
altera_epcq_controller #(
|
||||
.CS_WIDTH (CS_WIDTH),
|
||||
.DEVICE_FAMILY (DEVICE_FAMILY),
|
||||
.ADDR_WIDTH (ADDR_WIDTH),
|
||||
.ASMI_ADDR_WIDTH (ASMI_ADDR_WIDTH),
|
||||
.ASI_WIDTH (ASI_WIDTH),
|
||||
.CHIP_SELS (CHIP_SELS),
|
||||
.ENABLE_4BYTE_ADDR (ENABLE_4BYTE_ADDR)
|
||||
) controller (
|
||||
.clk (clk),
|
||||
.reset_n (reset_n),
|
||||
.avl_csr_read (avl_csr_read),
|
||||
.avl_csr_waitrequest (temp_csr_waitrequest),
|
||||
.avl_csr_write (avl_csr_write),
|
||||
.avl_csr_addr (avl_csr_addr),
|
||||
.avl_csr_wrdata (avl_csr_wrdata),
|
||||
.avl_csr_rddata (avl_csr_rddata),
|
||||
.avl_csr_rddata_valid (avl_csr_rddata_valid),
|
||||
.avl_mem_write (temp_mem_write),
|
||||
.avl_mem_burstcount (temp_mem_burstcount),
|
||||
.avl_mem_waitrequest (temp_mem_waitrequest),
|
||||
.avl_mem_read (temp_mem_read),
|
||||
.avl_mem_addr (temp_mem_addr),
|
||||
.avl_mem_wrdata (temp_mem_wrdata),
|
||||
.avl_mem_byteenable (temp_mem_byteenable),
|
||||
.avl_mem_rddata (avl_mem_rddata),
|
||||
.avl_mem_rddata_valid (avl_mem_rddata_valid),
|
||||
.asmi_status_out (asmi_status_out),
|
||||
.asmi_epcs_id (asmi_epcs_id),
|
||||
.asmi_illegal_erase (asmi_illegal_erase),
|
||||
.asmi_illegal_write (asmi_illegal_write),
|
||||
.ddasi_dataoe (ddasi_dataoe),
|
||||
.ddasi_dclk (ddasi_dclk),
|
||||
.ddasi_scein (ddasi_scein),
|
||||
.ddasi_sdoin (ddasi_sdoin),
|
||||
.asmi_busy (asmi_busy),
|
||||
.asmi_data_valid (asmi_data_valid),
|
||||
.asmi_dataout (asmi_dataout),
|
||||
.epcq_dataout (epcq_dataout),
|
||||
.ddasi_dataout (ddasi_dataout),
|
||||
.asmi_read_rdid (asmi_read_rdid),
|
||||
.asmi_read_status (asmi_read_status),
|
||||
.asmi_read_sid (asmi_read_sid),
|
||||
.asmi_bulk_erase (asmi_bulk_erase),
|
||||
.asmi_sector_erase (asmi_sector_erase),
|
||||
.asmi_sector_protect (asmi_sector_protect),
|
||||
.epcq_dclk (epcq_dclk),
|
||||
.epcq_scein (epcq_scein),
|
||||
.epcq_sdoin (epcq_sdoin),
|
||||
.epcq_dataoe (epcq_dataoe),
|
||||
.asmi_clkin (asmi_clkin),
|
||||
.asmi_reset (asmi_reset),
|
||||
.asmi_sce (asmi_sce),
|
||||
.asmi_addr (asmi_addr),
|
||||
.asmi_datain (asmi_datain),
|
||||
.asmi_fast_read (asmi_fast_read),
|
||||
.asmi_rden (asmi_rden),
|
||||
.asmi_shift_bytes (asmi_shift_bytes),
|
||||
.asmi_wren (asmi_wren),
|
||||
.asmi_write (asmi_write),
|
||||
.asmi_rdid_out (asmi_rdid_out),
|
||||
.asmi_en4b_addr (asmi_en4b_addr),
|
||||
.irq (irq)
|
||||
);
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,176 @@
|
|||
// (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
// Your use of Altera Corporation's design tools, logic functions and other
|
||||
// software and tools, and its AMPP partner logic functions, and any output
|
||||
// files any of the foregoing (including device programming or simulation
|
||||
// files), and any associated documentation or information are expressly subject
|
||||
// to the terms and conditions of the Altera Program License Subscription
|
||||
// Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
// license agreement, including, without limitation, that your use is for the
|
||||
// sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
// Altera or its authorized distributors. Please refer to the applicable
|
||||
// agreement for further details.
|
||||
|
||||
|
||||
// megafunction wizard: %FIFO%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: scfifo
|
||||
|
||||
// ============================================================
|
||||
// File Name: altera_epcq_controller_fifo.v
|
||||
// Megafunction Name(s):
|
||||
// scfifo
|
||||
//
|
||||
// Simulation Library Files(s):
|
||||
// altera_mf
|
||||
// ============================================================
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 14.1.0 Internal Build 64 05/14/2014 PN Full Version
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 1991-2014 Altera Corporation. All rights reserved.
|
||||
//Your use of Altera Corporation's design tools, logic functions
|
||||
//and other software and tools, and its AMPP partner logic
|
||||
//functions, and any output files from any of the foregoing
|
||||
//(including device programming or simulation files), and any
|
||||
//associated documentation or information are expressly subject
|
||||
//to the terms and conditions of the Altera Program License
|
||||
//Subscription Agreement, the Altera Quartus II License Agreement,
|
||||
//the Altera MegaCore Function License Agreement, or other
|
||||
//applicable license agreement, including, without limitation,
|
||||
//that your use is for the sole purpose of programming logic
|
||||
//devices manufactured by Altera and sold by Altera or its
|
||||
//authorized distributors. Please refer to the applicable
|
||||
//agreement for further details.
|
||||
|
||||
|
||||
// synopsys translate_off
|
||||
`timescale 1 ps / 1 ps
|
||||
// synopsys translate_on
|
||||
module altera_epcq_controller_fifo #(
|
||||
parameter DEVICE_FAMILY = "CYCLONE V",
|
||||
parameter MEMORY_TYPE = "RAM_BLOCK_TYPE=MLAB"
|
||||
)(
|
||||
clock,
|
||||
data,
|
||||
rdreq,
|
||||
wrreq,
|
||||
empty,
|
||||
full,
|
||||
q);
|
||||
|
||||
input clock;
|
||||
input [35:0] data;
|
||||
input rdreq;
|
||||
input wrreq;
|
||||
output empty;
|
||||
output full;
|
||||
output [35:0] q;
|
||||
|
||||
wire sub_wire0;
|
||||
wire sub_wire1;
|
||||
wire [35:0] sub_wire2;
|
||||
wire empty = sub_wire0;
|
||||
wire full = sub_wire1;
|
||||
wire [35:0] q = sub_wire2[35:0];
|
||||
|
||||
scfifo scfifo_component (
|
||||
.clock (clock),
|
||||
.data (data),
|
||||
.rdreq (rdreq),
|
||||
.wrreq (wrreq),
|
||||
.empty (sub_wire0),
|
||||
.full (sub_wire1),
|
||||
.q (sub_wire2),
|
||||
.aclr (),
|
||||
.almost_empty (),
|
||||
.almost_full (),
|
||||
.sclr (),
|
||||
.usedw ());
|
||||
defparam
|
||||
scfifo_component.add_ram_output_register = "OFF",
|
||||
scfifo_component.intended_device_family = DEVICE_FAMILY,
|
||||
scfifo_component.lpm_hint = MEMORY_TYPE,
|
||||
scfifo_component.lpm_numwords = 1024,
|
||||
scfifo_component.lpm_showahead = "ON",
|
||||
scfifo_component.lpm_type = "scfifo",
|
||||
scfifo_component.lpm_width = 36,
|
||||
scfifo_component.lpm_widthu = 10,
|
||||
scfifo_component.overflow_checking = "ON",
|
||||
scfifo_component.underflow_checking = "ON",
|
||||
scfifo_component.use_eab = "ON";
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================
|
||||
// CNX file retrieval info
|
||||
// ============================================================
|
||||
// Retrieval info: PRIVATE: AlmostEmpty NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "-1"
|
||||
// Retrieval info: PRIVATE: AlmostFull NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"
|
||||
// Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Clock NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Depth NUMERIC "1024"
|
||||
// Retrieval info: PRIVATE: Empty NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: Full NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV GX"
|
||||
// Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: LegacyRREQ NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Optimize NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "2"
|
||||
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
// Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: UsedW NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Width NUMERIC "8"
|
||||
// Retrieval info: PRIVATE: dc_aclr NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: diff_widths NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: msb_usedw NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: output_width NUMERIC "8"
|
||||
// Retrieval info: PRIVATE: rsEmpty NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: rsFull NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: rsUsedW NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: sc_aclr NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: sc_sclr NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: wsEmpty NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: wsFull NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: wsUsedW NUMERIC "0"
|
||||
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
// Retrieval info: CONSTANT: ADD_RAM_OUTPUT_REGISTER STRING "OFF"
|
||||
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV GX"
|
||||
// Retrieval info: CONSTANT: LPM_HINT STRING "RAM_BLOCK_TYPE=M9K"
|
||||
// Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "1024"
|
||||
// Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "ON"
|
||||
// Retrieval info: CONSTANT: LPM_TYPE STRING "scfifo"
|
||||
// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "8"
|
||||
// Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "10"
|
||||
// Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "ON"
|
||||
// Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "ON"
|
||||
// Retrieval info: CONSTANT: USE_EAB STRING "ON"
|
||||
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL "clock"
|
||||
// Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data[7..0]"
|
||||
// Retrieval info: USED_PORT: empty 0 0 0 0 OUTPUT NODEFVAL "empty"
|
||||
// Retrieval info: USED_PORT: full 0 0 0 0 OUTPUT NODEFVAL "full"
|
||||
// Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]"
|
||||
// Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL "rdreq"
|
||||
// Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL "wrreq"
|
||||
// Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0
|
||||
// Retrieval info: CONNECT: @data 0 0 8 0 data 0 0 8 0
|
||||
// Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0
|
||||
// Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0
|
||||
// Retrieval info: CONNECT: empty 0 0 0 0 @empty 0 0 0 0
|
||||
// Retrieval info: CONNECT: full 0 0 0 0 @full 0 0 0 0
|
||||
// Retrieval info: CONNECT: q 0 0 8 0 @q 0 0 8 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_bb.v FALSE
|
||||
// Retrieval info: LIB_FILE: altera_mf
|
|
@ -0,0 +1,453 @@
|
|||
# (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
# Your use of Altera Corporation's design tools, logic functions and other
|
||||
# software and tools, and its AMPP partner logic functions, and any output
|
||||
# files any of the foregoing (including device programming or simulation
|
||||
# files), and any associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License Subscription
|
||||
# Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
# license agreement, including, without limitation, that your use is for the
|
||||
# sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
# Altera or its authorized distributors. Please refer to the applicable
|
||||
# agreement for further details.
|
||||
|
||||
|
||||
# TCL File Generated by Component Editor 14.1
|
||||
# Fri May 09 18:08:10 MYT 2014
|
||||
# DO NOT MODIFY
|
||||
|
||||
|
||||
#
|
||||
# altera_epcq_controller_core "Altera EPCQ Serial Flash controller core" v14.1
|
||||
# Altera Coorperation 2014.05.23.15:01:29
|
||||
# This component is a serial flash controller which allows user to access Altera EPCQ devices
|
||||
#
|
||||
|
||||
#
|
||||
# request TCL package from ACDS 14.1
|
||||
#
|
||||
package require -exact qsys 14.1
|
||||
|
||||
|
||||
|
||||
#
|
||||
# module altera_epcq_controller
|
||||
#
|
||||
set_module_property DESCRIPTION "This component is a serial flash controller which allows user to access Altera EPCQ devices"
|
||||
set_module_property NAME altera_epcq_controller_core
|
||||
set_module_property VERSION 15.1
|
||||
set_module_property INTERNAL true
|
||||
set_module_property OPAQUE_ADDRESS_MAP true
|
||||
set_module_property AUTHOR "Altera Corporation"
|
||||
set_module_property DISPLAY_NAME "Altera EPCQ Serial Flash controller core"
|
||||
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
|
||||
set_module_property HIDE_FROM_QUARTUS true
|
||||
set_module_property EDITABLE true
|
||||
set_module_property REPORT_TO_TALKBACK false
|
||||
set_module_property ALLOW_GREYBOX_GENERATION false
|
||||
set_module_property REPORT_HIERARCHY false
|
||||
set_module_property VALIDATION_CALLBACK "validate"
|
||||
#
|
||||
# file sets
|
||||
#
|
||||
add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" ""
|
||||
set_fileset_property QUARTUS_SYNTH TOP_LEVEL altera_epcq_controller_arb
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
|
||||
add_fileset_file altera_epcq_controller_arb.sv SYSTEM_VERILOG PATH altera_epcq_controller_arb.sv TOP_LEVEL_FILE
|
||||
add_fileset_file altera_epcq_controller.sv SYSTEM_VERILOG PATH altera_epcq_controller.sv
|
||||
|
||||
add_fileset SIM_VERILOG SIM_VERILOG "" ""
|
||||
set_fileset_property SIM_VERILOG TOP_LEVEL altera_epcq_controller_arb
|
||||
set_fileset_property SIM_VERILOG ENABLE_RELATIVE_INCLUDE_PATHS false
|
||||
set_fileset_property SIM_VERILOG ENABLE_FILE_OVERWRITE_MODE true
|
||||
add_fileset_file altera_epcq_controller_arb.sv SYSTEM_VERILOG PATH altera_epcq_controller_arb.sv TOP_LEVEL_FILE
|
||||
add_fileset_file altera_epcq_controller.sv SYSTEM_VERILOG PATH altera_epcq_controller.sv
|
||||
|
||||
#
|
||||
# add system info parameter
|
||||
add_parameter deviceFeaturesSystemInfo STRING "None"
|
||||
set_parameter_property deviceFeaturesSystemInfo system_info "DEVICE_FEATURES"
|
||||
set_parameter_property deviceFeaturesSystemInfo VISIBLE false
|
||||
|
||||
#
|
||||
# parameters
|
||||
#
|
||||
add_parameter DEVICE_FAMILY STRING ""
|
||||
set_parameter_property DEVICE_FAMILY SYSTEM_INFO "DEVICE_FAMILY"
|
||||
set_parameter_property DEVICE_FAMILY HDL_PARAMETER true
|
||||
set_parameter_property DEVICE_FAMILY VISIBLE false
|
||||
|
||||
add_parameter ADDR_WIDTH INTEGER 19
|
||||
set_parameter_property ADDR_WIDTH DEFAULT_VALUE 19
|
||||
set_parameter_property ADDR_WIDTH DISPLAY_NAME ADDR_WIDTH
|
||||
set_parameter_property ADDR_WIDTH DERIVED true
|
||||
set_parameter_property ADDR_WIDTH TYPE INTEGER
|
||||
set_parameter_property ADDR_WIDTH VISIBLE false
|
||||
set_parameter_property ADDR_WIDTH UNITS None
|
||||
set_parameter_property ADDR_WIDTH ALLOWED_RANGES {19, 20, 21, 22, 23, 24, 25, 26, 27, 28}
|
||||
set_parameter_property ADDR_WIDTH HDL_PARAMETER true
|
||||
|
||||
add_parameter ASMI_ADDR_WIDTH INTEGER 24
|
||||
set_parameter_property ASMI_ADDR_WIDTH DEFAULT_VALUE 24
|
||||
set_parameter_property ASMI_ADDR_WIDTH DISPLAY_NAME ASMI_ADDR_WIDTH
|
||||
set_parameter_property ASMI_ADDR_WIDTH DERIVED true
|
||||
set_parameter_property ASMI_ADDR_WIDTH TYPE INTEGER
|
||||
set_parameter_property ASMI_ADDR_WIDTH VISIBLE false
|
||||
set_parameter_property ASMI_ADDR_WIDTH UNITS None
|
||||
set_parameter_property ASMI_ADDR_WIDTH ALLOWED_RANGES {24, 32}
|
||||
set_parameter_property ASMI_ADDR_WIDTH HDL_PARAMETER true
|
||||
|
||||
add_parameter ASI_WIDTH INTEGER 1
|
||||
set_parameter_property ASI_WIDTH DEFAULT_VALUE 1
|
||||
set_parameter_property ASI_WIDTH DISPLAY_NAME ASI_WIDTH
|
||||
set_parameter_property ASI_WIDTH DERIVED true
|
||||
set_parameter_property ASI_WIDTH TYPE INTEGER
|
||||
set_parameter_property ASI_WIDTH VISIBLE false
|
||||
set_parameter_property ASI_WIDTH UNITS None
|
||||
set_parameter_property ASI_WIDTH ALLOWED_RANGES {1, 4}
|
||||
set_parameter_property ASI_WIDTH HDL_PARAMETER true
|
||||
|
||||
add_parameter CS_WIDTH INTEGER 1
|
||||
set_parameter_property CS_WIDTH DEFAULT_VALUE 1
|
||||
set_parameter_property CS_WIDTH DISPLAY_NAME CS_WIDTH
|
||||
set_parameter_property CS_WIDTH DERIVED true
|
||||
set_parameter_property CS_WIDTH TYPE INTEGER
|
||||
set_parameter_property CS_WIDTH VISIBLE false
|
||||
set_parameter_property CS_WIDTH UNITS None
|
||||
set_parameter_property CS_WIDTH ALLOWED_RANGES {1, 3}
|
||||
set_parameter_property CS_WIDTH HDL_PARAMETER true
|
||||
|
||||
add_parameter CHIP_SELS INTEGER "1"
|
||||
set_parameter_property CHIP_SELS DISPLAY_NAME "Number of Chip Selects used"
|
||||
set_parameter_property CHIP_SELS ALLOWED_RANGES {1 2 3}
|
||||
set_parameter_property CHIP_SELS DESCRIPTION "Number of EPCQ(L) devices that are attached and need a CHIPSEL"
|
||||
set_parameter_property CHIP_SELS HDL_PARAMETER true
|
||||
set_parameter_property CHIP_SELS AFFECTS_GENERATION true
|
||||
|
||||
add_parameter DDASI INTEGER "0"
|
||||
set_parameter_property DDASI DISPLAY_NAME "Disable dedicated Active Serial interface"
|
||||
set_parameter_property DDASI DESCRIPTION "Check to route ASMIBLOCK signals to top level of design"
|
||||
set_parameter_property DDASI AFFECTS_GENERATION true
|
||||
set_parameter_property DDASI VISIBLE false
|
||||
set_parameter_property DDASI DERIVED false
|
||||
|
||||
add_parameter ENABLE_4BYTE_ADDR INTEGER "0"
|
||||
set_parameter_property ENABLE_4BYTE_ADDR DISPLAY_NAME "Enable 4-byte addressing mode"
|
||||
set_parameter_property ENABLE_4BYTE_ADDR DESCRIPTION "Check to enable 4-byte addressing mode for device larger than 128Mbyte"
|
||||
set_parameter_property ENABLE_4BYTE_ADDR AFFECTS_GENERATION true
|
||||
set_parameter_property ENABLE_4BYTE_ADDR VISIBLE false
|
||||
set_parameter_property ENABLE_4BYTE_ADDR HDL_PARAMETER true
|
||||
set_parameter_property ENABLE_4BYTE_ADDR DERIVED true
|
||||
|
||||
# SPI device selection
|
||||
add_parameter FLASH_TYPE STRING "EPCQ16"
|
||||
set_parameter_property FLASH_TYPE DISPLAY_NAME "Configuration device type"
|
||||
set_parameter_property FLASH_TYPE DESCRIPTION "Select targeted EPCS/EPCQ devices"
|
||||
set_parameter_property FLASH_TYPE AFFECTS_GENERATION true
|
||||
set_parameter_property FLASH_TYPE VISIBLE true
|
||||
set_parameter_property FLASH_TYPE DERIVED false
|
||||
|
||||
add_parameter IO_MODE STRING "STANDARD"
|
||||
set_parameter_property IO_MODE DISPLAY_NAME "Choose I/O mode"
|
||||
set_parameter_property IO_MODE ALLOWED_RANGES {"STANDARD" "QUAD"}
|
||||
set_parameter_property IO_MODE DESCRIPTION "Select extended data width when Fast Read operation is enabled"
|
||||
|
||||
#
|
||||
# display items
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# connection point clock_sink
|
||||
#
|
||||
add_interface clock_sink clock end
|
||||
set_interface_property clock_sink clockRate 0
|
||||
set_interface_property clock_sink ENABLED true
|
||||
set_interface_property clock_sink EXPORT_OF ""
|
||||
set_interface_property clock_sink PORT_NAME_MAP ""
|
||||
set_interface_property clock_sink CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property clock_sink SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port clock_sink clk clk Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point reset
|
||||
#
|
||||
add_interface reset reset end
|
||||
set_interface_property reset associatedClock clock_sink
|
||||
set_interface_property reset synchronousEdges DEASSERT
|
||||
set_interface_property reset ENABLED true
|
||||
set_interface_property reset EXPORT_OF ""
|
||||
set_interface_property reset PORT_NAME_MAP ""
|
||||
set_interface_property reset CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property reset SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port reset reset_n reset_n Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point avl_csr
|
||||
#
|
||||
add_interface avl_csr avalon end
|
||||
set_interface_property avl_csr addressUnits WORDS
|
||||
set_interface_property avl_csr associatedClock clock_sink
|
||||
set_interface_property avl_csr associatedReset reset
|
||||
set_interface_property avl_csr bitsPerSymbol 8
|
||||
set_interface_property avl_csr burstOnBurstBoundariesOnly false
|
||||
set_interface_property avl_csr burstcountUnits WORDS
|
||||
set_interface_property avl_csr explicitAddressSpan 0
|
||||
set_interface_property avl_csr holdTime 0
|
||||
set_interface_property avl_csr linewrapBursts false
|
||||
set_interface_property avl_csr maximumPendingReadTransactions 1
|
||||
set_interface_property avl_csr maximumPendingWriteTransactions 0
|
||||
set_interface_property avl_csr readLatency 0
|
||||
set_interface_property avl_csr readWaitTime 0
|
||||
set_interface_property avl_csr setupTime 0
|
||||
set_interface_property avl_csr timingUnits Cycles
|
||||
set_interface_property avl_csr writeWaitTime 0
|
||||
set_interface_property avl_csr ENABLED true
|
||||
set_interface_property avl_csr EXPORT_OF ""
|
||||
set_interface_property avl_csr PORT_NAME_MAP ""
|
||||
set_interface_property avl_csr CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property avl_csr SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port avl_csr avl_csr_read read Input 1
|
||||
add_interface_port avl_csr avl_csr_waitrequest waitrequest Output 1
|
||||
add_interface_port avl_csr avl_csr_write write Input 1
|
||||
add_interface_port avl_csr avl_csr_addr address Input 3
|
||||
add_interface_port avl_csr avl_csr_wrdata writedata Input 32
|
||||
add_interface_port avl_csr avl_csr_rddata readdata Output 32
|
||||
add_interface_port avl_csr avl_csr_rddata_valid readdatavalid Output 1
|
||||
|
||||
|
||||
#
|
||||
# connection point avl_mem
|
||||
#
|
||||
add_interface avl_mem avalon end
|
||||
set_interface_property avl_mem addressUnits WORDS
|
||||
set_interface_property avl_mem associatedClock clock_sink
|
||||
set_interface_property avl_mem associatedReset reset
|
||||
set_interface_property avl_mem bitsPerSymbol 8
|
||||
set_interface_property avl_mem burstOnBurstBoundariesOnly false
|
||||
set_interface_property avl_mem burstcountUnits WORDS
|
||||
set_interface_property avl_mem explicitAddressSpan 0
|
||||
set_interface_property avl_mem holdTime 0
|
||||
set_interface_property avl_mem linewrapBursts true
|
||||
set_interface_property avl_mem maximumPendingReadTransactions 1
|
||||
set_interface_property avl_mem maximumPendingWriteTransactions 0
|
||||
set_interface_property avl_mem constantBurstBehavior true
|
||||
set_interface_property avl_mem readLatency 0
|
||||
set_interface_property avl_mem readWaitTime 0
|
||||
set_interface_property avl_mem setupTime 0
|
||||
set_interface_property avl_mem timingUnits Cycles
|
||||
set_interface_property avl_mem writeWaitTime 0
|
||||
set_interface_property avl_mem ENABLED true
|
||||
set_interface_property avl_mem EXPORT_OF ""
|
||||
set_interface_property avl_mem PORT_NAME_MAP ""
|
||||
set_interface_property avl_mem CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property avl_mem SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port avl_mem avl_mem_write write Input 1
|
||||
add_interface_port avl_mem avl_mem_burstcount burstcount Input 7
|
||||
add_interface_port avl_mem avl_mem_waitrequest waitrequest Output 1
|
||||
add_interface_port avl_mem avl_mem_read read Input 1
|
||||
add_interface_port avl_mem avl_mem_addr address Input ADDR_WIDTH
|
||||
add_interface_port avl_mem avl_mem_wrdata writedata Input 32
|
||||
add_interface_port avl_mem avl_mem_rddata readdata Output 32
|
||||
add_interface_port avl_mem avl_mem_rddata_valid readdatavalid Output 1
|
||||
add_interface_port avl_mem avl_mem_byteenable byteenable Input 4
|
||||
|
||||
|
||||
#
|
||||
# connection point conduit_out
|
||||
#
|
||||
add_interface asmi_status_out conduit end
|
||||
add_interface_port asmi_status_out asmi_status_out conduit_status_out Input 8
|
||||
|
||||
add_interface asmi_epcs_id conduit end
|
||||
add_interface_port asmi_epcs_id asmi_epcs_id conduit_epcs_id Input 8
|
||||
|
||||
add_interface asmi_illegal_erase conduit end
|
||||
add_interface_port asmi_illegal_erase asmi_illegal_erase conduit_illegal_erase Input 1
|
||||
|
||||
add_interface asmi_illegal_write conduit end
|
||||
add_interface_port asmi_illegal_write asmi_illegal_write conduit_illegal_write Input 1
|
||||
|
||||
add_interface ddasi_dataoe conduit end
|
||||
add_interface_port ddasi_dataoe ddasi_dataoe conduit_ddasi_dataoe Input ASI_WIDTH
|
||||
|
||||
add_interface ddasi_dclk conduit end
|
||||
add_interface_port ddasi_dclk ddasi_dclk conduit_ddasi_dclk Input 1
|
||||
|
||||
add_interface ddasi_scein conduit end
|
||||
add_interface_port ddasi_scein ddasi_scein conduit_ddasi_scein Input CS_WIDTH
|
||||
|
||||
add_interface ddasi_sdoin conduit end
|
||||
add_interface_port ddasi_sdoin ddasi_sdoin conduit_ddasi_sdoin Input ASI_WIDTH
|
||||
|
||||
add_interface asmi_busy conduit end
|
||||
add_interface_port asmi_busy asmi_busy conduit_busy Input 1
|
||||
|
||||
add_interface asmi_data_valid conduit end
|
||||
add_interface_port asmi_data_valid asmi_data_valid conduit_data_valid Input 1
|
||||
|
||||
add_interface asmi_dataout conduit end
|
||||
add_interface_port asmi_dataout asmi_dataout conduit_dataout Input 8
|
||||
|
||||
add_interface epcq_dataout conduit end
|
||||
add_interface_port epcq_dataout epcq_dataout conduit_epcq_dataout Input ASI_WIDTH
|
||||
|
||||
add_interface ddasi_dataout conduit end
|
||||
add_interface_port ddasi_dataout ddasi_dataout conduit_ddasi_dataout Output ASI_WIDTH
|
||||
|
||||
add_interface asmi_read_rdid conduit end
|
||||
add_interface_port asmi_read_rdid asmi_read_rdid conduit_read_rdid Output 1
|
||||
|
||||
add_interface asmi_read_status conduit end
|
||||
add_interface_port asmi_read_status asmi_read_status conduit_read_status Output 1
|
||||
|
||||
add_interface asmi_read_sid conduit end
|
||||
add_interface_port asmi_read_sid asmi_read_sid conduit_read_sid Output 1
|
||||
|
||||
add_interface asmi_bulk_erase conduit end
|
||||
add_interface_port asmi_bulk_erase asmi_bulk_erase conduit_bulk_erase Output 1
|
||||
|
||||
add_interface asmi_sector_erase conduit end
|
||||
add_interface_port asmi_sector_erase asmi_sector_erase conduit_sector_erase Output 1
|
||||
|
||||
add_interface asmi_sector_protect conduit end
|
||||
add_interface_port asmi_sector_protect asmi_sector_protect conduit_sector_protect Output 1
|
||||
|
||||
add_interface epcq_dclk conduit end
|
||||
add_interface_port epcq_dclk epcq_dclk conduit_epcq_dclk Output 1
|
||||
|
||||
add_interface epcq_scein conduit end
|
||||
add_interface_port epcq_scein epcq_scein conduit_epcq_scein Output CS_WIDTH
|
||||
|
||||
add_interface epcq_sdoin conduit end
|
||||
add_interface_port epcq_sdoin epcq_sdoin conduit_epcq_sdoin Output ASI_WIDTH
|
||||
|
||||
add_interface epcq_dataoe conduit end
|
||||
add_interface_port epcq_dataoe epcq_dataoe conduit_epcq_dataoe Output ASI_WIDTH
|
||||
|
||||
add_interface asmi_clkin conduit end
|
||||
add_interface_port asmi_clkin asmi_clkin conduit_clkin Output 1
|
||||
|
||||
add_interface asmi_reset conduit end
|
||||
add_interface_port asmi_reset asmi_reset conduit_reset Output 1
|
||||
|
||||
add_interface asmi_sce conduit end
|
||||
add_interface_port asmi_sce asmi_sce conduit_asmi_sce Output CS_WIDTH
|
||||
|
||||
add_interface asmi_addr conduit end
|
||||
add_interface_port asmi_addr asmi_addr conduit_addr Output ASMI_ADDR_WIDTH
|
||||
|
||||
add_interface asmi_datain conduit end
|
||||
add_interface_port asmi_datain asmi_datain conduit_datain Output 8
|
||||
|
||||
add_interface asmi_fast_read conduit end
|
||||
add_interface_port asmi_fast_read asmi_fast_read conduit_fast_read Output 1
|
||||
|
||||
add_interface asmi_rden conduit end
|
||||
add_interface_port asmi_rden asmi_rden conduit_rden Output 1
|
||||
|
||||
add_interface asmi_shift_bytes conduit end
|
||||
add_interface_port asmi_shift_bytes asmi_shift_bytes conduit_shift_bytes Output 1
|
||||
|
||||
add_interface asmi_wren conduit end
|
||||
add_interface_port asmi_wren asmi_wren conduit_wren Output 1
|
||||
|
||||
add_interface asmi_write conduit end
|
||||
add_interface_port asmi_write asmi_write conduit_write Output 1
|
||||
|
||||
add_interface asmi_rdid_out conduit end
|
||||
add_interface_port asmi_rdid_out asmi_rdid_out conduit_rdid_out Input 8
|
||||
|
||||
add_interface asmi_en4b_addr conduit end
|
||||
add_interface_port asmi_en4b_addr asmi_en4b_addr conduit_en4b_addr Output 1
|
||||
|
||||
#
|
||||
# connection point interrupt_sender
|
||||
#
|
||||
add_interface interrupt_sender interrupt end
|
||||
set_interface_property interrupt_sender associatedAddressablePoint avl_csr
|
||||
set_interface_property interrupt_sender associatedClock clock_sink
|
||||
set_interface_property interrupt_sender associatedReset reset
|
||||
set_interface_property interrupt_sender bridgedReceiverOffset ""
|
||||
set_interface_property interrupt_sender bridgesToReceiver ""
|
||||
set_interface_property interrupt_sender ENABLED true
|
||||
set_interface_property interrupt_sender EXPORT_OF ""
|
||||
set_interface_property interrupt_sender PORT_NAME_MAP ""
|
||||
set_interface_property interrupt_sender CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property interrupt_sender SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port interrupt_sender irq irq Output 1
|
||||
|
||||
proc validate {} {
|
||||
set all_supported_SPI_list {"EPCS16" "EPCS64" "EPCS128" "EPCQ16" "EPCQ32" "EPCQ64" "EPCQ128" "EPCQ256" \
|
||||
"EPCQ512" "EPCQL256" "EPCQL512" "EPCQL1024"}
|
||||
|
||||
set_parameter_property FLASH_TYPE "ALLOWED_RANGES" $all_supported_SPI_list
|
||||
set DEVICE_FAMILY [ get_parameter_value DEVICE_FAMILY ]
|
||||
set CHIP_SELS [ get_parameter_value CHIP_SELS]
|
||||
set temp_addr_width [ proc_get_derive_addr_width [ get_parameter_value FLASH_TYPE ] ]
|
||||
set_parameter_value ENABLE_4BYTE_ADDR [ proc_get_derive_enable_2byte_addr [ get_parameter_value FLASH_TYPE ] ]
|
||||
|
||||
if { [ get_parameter_value ENABLE_4BYTE_ADDR ] } {
|
||||
set_parameter_value ASMI_ADDR_WIDTH 32
|
||||
} else {
|
||||
set_parameter_value ASMI_ADDR_WIDTH 24
|
||||
}
|
||||
|
||||
# check whether devices supporting multiple flash - only for Arria 10
|
||||
if {[check_device_family_equivalence $DEVICE_FAMILY "Arria 10"]} {
|
||||
set is_multi_flash_support "true"
|
||||
if {$CHIP_SELS eq 3 } {set_parameter_value ADDR_WIDTH [ expr $temp_addr_width + 2]}
|
||||
if {$CHIP_SELS eq 2 } {set_parameter_value ADDR_WIDTH [ expr $temp_addr_width + 1]}
|
||||
if {$CHIP_SELS eq 1 } {set_parameter_value ADDR_WIDTH $temp_addr_width }
|
||||
} else {
|
||||
set is_multi_flash_support "false"
|
||||
set_parameter_value ADDR_WIDTH $temp_addr_width
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
proc proc_get_derive_enable_2byte_addr {flash_type} {
|
||||
if { [ string match "*256*" "$flash_type" ] || [ string match "*512*" "$flash_type" ] || [ string match "*1024*" "$flash_type" ]} {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
proc proc_get_derive_addr_width {flash_type} {
|
||||
switch $flash_type {
|
||||
"EPCS16" - "EPCQ16" {
|
||||
return 19
|
||||
}
|
||||
"EPCS64" - "EPCQ64" {
|
||||
return 21
|
||||
}
|
||||
"EPCS128" - "EPCQ128" {
|
||||
return 22
|
||||
}
|
||||
"EPCQ32" {
|
||||
return 20
|
||||
}
|
||||
"EPCQ256" - "EPCQL256" {
|
||||
return 23
|
||||
}
|
||||
"EPCQ512" - "EPCQL512" {
|
||||
return 24
|
||||
}
|
||||
"EPCQL1024" {
|
||||
return 25
|
||||
}
|
||||
default {
|
||||
# Should never enter this function
|
||||
send_message error "$flash_type is not a valid flash type"
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
# (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
# Your use of Altera Corporation's design tools, logic functions and other
|
||||
# software and tools, and its AMPP partner logic functions, and any output
|
||||
# files any of the foregoing (including device programming or simulation
|
||||
# files), and any associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License Subscription
|
||||
# Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
# license agreement, including, without limitation, that your use is for the
|
||||
# sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
# Altera or its authorized distributors. Please refer to the applicable
|
||||
# agreement for further details.
|
||||
|
||||
|
||||
#
|
||||
# altera_epcq_controller_sw.tcl
|
||||
#
|
||||
|
||||
# Create a new driver
|
||||
create_driver altera_epcq_controller_mod_driver
|
||||
|
||||
# Associate it with some hardware known as "altera_epcq_controller"
|
||||
set_sw_property hw_class_name altera_epcq_controller_mod
|
||||
|
||||
# The version of this driver
|
||||
set_sw_property version 15.1
|
||||
|
||||
# This driver may be incompatible with versions of hardware less
|
||||
# than specified below. Updates to hardware and device drivers
|
||||
# rendering the driver incompatible with older versions of
|
||||
# hardware are noted with this property assignment.
|
||||
set_sw_property min_compatible_hw_version 14.1
|
||||
|
||||
# Initialize the driver in alt_sys_init()
|
||||
set_sw_property auto_initialize true
|
||||
|
||||
# This driver only works when the following combinations of interfaces
|
||||
# are enabled and connected as a group of CSR interfaces.
|
||||
set_sw_property csr_interfaces "avl_mem,avl_csr"
|
||||
|
||||
# The EPCQ interrupt has an interrupt but it is not used in the driver.
|
||||
# These assignments are still required by the Nios II SBT
|
||||
set_sw_property isr_preemption_supported true
|
||||
set_sw_property supported_interrupt_apis "legacy_interrupt_api enhanced_interrupt_api"
|
||||
|
||||
# Location in generated BSP that above sources will be copied into
|
||||
set_sw_property bsp_subdirectory drivers
|
||||
|
||||
# Header files
|
||||
add_sw_property include_source HAL/inc/altera_epcq_controller_mod.h
|
||||
add_sw_property include_source inc/altera_epcq_controller_mod_regs.h
|
||||
|
||||
# C/C++ source files
|
||||
add_sw_property c_source HAL/src/altera_epcq_controller_mod.c
|
||||
|
||||
|
||||
# This driver supports HAL & UCOSII BSP (OS) types
|
||||
add_sw_property supported_bsp_type HAL
|
||||
add_sw_property supported_bsp_type UCOSII
|
|
@ -0,0 +1,248 @@
|
|||
// (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
// Your use of Altera Corporation's design tools, logic functions and other
|
||||
// software and tools, and its AMPP partner logic functions, and any output
|
||||
// files any of the foregoing (including device programming or simulation
|
||||
// files), and any associated documentation or information are expressly subject
|
||||
// to the terms and conditions of the Altera Program License Subscription
|
||||
// Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
// license agreement, including, without limitation, that your use is for the
|
||||
// sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
// Altera or its authorized distributors. Please refer to the applicable
|
||||
// agreement for further details.
|
||||
|
||||
|
||||
|
||||
`timescale 1ps / 1ps
|
||||
|
||||
${MULTICHIP}
|
||||
${DDASI_ON}
|
||||
${SID_EN}
|
||||
${BULK_ERASE_EN}
|
||||
${4BYTE_ADDR_EN}
|
||||
|
||||
module altera_epcq_controller_wrapper #(
|
||||
parameter CS_WIDTH = 1,
|
||||
parameter DEVICE_FAMILY = "Arria V",
|
||||
parameter ADDR_WIDTH = 24,
|
||||
parameter ASI_WIDTH = 1,
|
||||
parameter ENABLE_4BYTE_ADDR = 1,
|
||||
parameter ASMI_ADDR_WIDTH = 22,
|
||||
parameter CHIP_SELS = 1
|
||||
)(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
// ports to access csr
|
||||
input wire avl_csr_write,
|
||||
input wire avl_csr_read,
|
||||
input wire [2:0] avl_csr_addr,
|
||||
input wire [31:0] avl_csr_wrdata,
|
||||
output wire [31:0] avl_csr_rddata,
|
||||
output wire avl_csr_rddata_valid,
|
||||
output wire avl_csr_waitrequest,
|
||||
|
||||
// ports to access memory
|
||||
input wire avl_mem_write,
|
||||
input wire avl_mem_read,
|
||||
input wire [ADDR_WIDTH-1:0] avl_mem_addr,
|
||||
input wire [31:0] avl_mem_wrdata,
|
||||
input wire [6:0] avl_mem_burstcount,
|
||||
input wire [3:0] avl_mem_byteenable,
|
||||
output wire [31:0] avl_mem_rddata,
|
||||
output wire avl_mem_rddata_valid,
|
||||
output wire avl_mem_waitrequest,
|
||||
|
||||
`ifdef DDASI_ON
|
||||
output wire [ASI_WIDTH-1:0] epcq_dataout,
|
||||
output wire epcq_dclk,
|
||||
output wire [CS_WIDTH-1:0] epcq_scein,
|
||||
output wire [ASI_WIDTH-1:0] epcq_sdoin,
|
||||
output wire [ASI_WIDTH-1:0] epcq_dataoe,
|
||||
`endif
|
||||
|
||||
// interrupt signal
|
||||
output reg irq
|
||||
);
|
||||
|
||||
`ifdef DDASI_ON
|
||||
wire [ASI_WIDTH-1:0] ddasi_dataoe;
|
||||
wire [ASI_WIDTH-1:0] ddasi_dataout;
|
||||
wire ddasi_dclk;
|
||||
wire [CS_WIDTH-1:0] ddasi_scein;
|
||||
wire [ASI_WIDTH-1:0] ddasi_sdoin;
|
||||
`endif
|
||||
wire asmi_busy;
|
||||
wire asmi_data_valid;
|
||||
wire [7:0] asmi_dataout;
|
||||
wire asmi_clkin;
|
||||
wire asmi_reset;
|
||||
`ifdef MULTICHIP
|
||||
wire [CS_WIDTH-1:0] asmi_sce;
|
||||
`endif
|
||||
wire [ASMI_ADDR_WIDTH-1:0] asmi_addr;
|
||||
wire [7:0] asmi_datain;
|
||||
wire asmi_fast_read;
|
||||
wire asmi_rden;
|
||||
wire asmi_shift_bytes;
|
||||
wire asmi_wren;
|
||||
wire asmi_write;
|
||||
|
||||
wire asmi_illegal_erase;
|
||||
wire asmi_illegal_write;
|
||||
wire [7:0] asmi_rdid_out;
|
||||
wire [7:0] asmi_status_out;
|
||||
`ifdef ENABLE_SID
|
||||
wire [7:0] asmi_epcs_id;
|
||||
`endif
|
||||
wire asmi_read_rdid;
|
||||
wire asmi_read_status;
|
||||
wire asmi_read_sid;
|
||||
`ifdef ENABLE_4BYTE_ADDR_CODE
|
||||
wire asmi_en4b_addr;
|
||||
`endif
|
||||
`ifdef ENABLE_BULK_ERASE
|
||||
wire asmi_bulk_erase;
|
||||
`endif
|
||||
wire asmi_sector_erase;
|
||||
wire asmi_sector_protect;
|
||||
|
||||
altera_epcq_controller_core #(
|
||||
.DEVICE_FAMILY (DEVICE_FAMILY),
|
||||
.ADDR_WIDTH (ADDR_WIDTH),
|
||||
.ASI_WIDTH (ASI_WIDTH),
|
||||
.ASMI_ADDR_WIDTH (ASMI_ADDR_WIDTH),
|
||||
.CS_WIDTH (CS_WIDTH),
|
||||
.ENABLE_4BYTE_ADDR (ENABLE_4BYTE_ADDR),
|
||||
.CHIP_SELS (CHIP_SELS)
|
||||
) epcq_controller_inst (
|
||||
.clk (clk ),
|
||||
.reset_n (reset_n ),
|
||||
.avl_csr_write (avl_csr_write ),
|
||||
.avl_csr_read (avl_csr_read ),
|
||||
.avl_csr_addr (avl_csr_addr ),
|
||||
.avl_csr_wrdata (avl_csr_wrdata ),
|
||||
.avl_csr_rddata (avl_csr_rddata ),
|
||||
.avl_csr_rddata_valid (avl_csr_rddata_valid ),
|
||||
.avl_csr_waitrequest (avl_csr_waitrequest ),
|
||||
.avl_mem_write (avl_mem_write ),
|
||||
.avl_mem_read (avl_mem_read ),
|
||||
.avl_mem_addr (avl_mem_addr ),
|
||||
.avl_mem_wrdata (avl_mem_wrdata ),
|
||||
.avl_mem_burstcount (avl_mem_burstcount ),
|
||||
.avl_mem_byteenable (avl_mem_byteenable ),
|
||||
.avl_mem_rddata (avl_mem_rddata ),
|
||||
.avl_mem_rddata_valid (avl_mem_rddata_valid ),
|
||||
.avl_mem_waitrequest (avl_mem_waitrequest ),
|
||||
.irq (irq ),
|
||||
`ifdef DDASI_ON
|
||||
.epcq_dataout (epcq_dataout ),
|
||||
.epcq_dclk (epcq_dclk ),
|
||||
.epcq_scein (epcq_scein ),
|
||||
.epcq_sdoin (epcq_sdoin ),
|
||||
.epcq_dataoe (epcq_dataoe ),
|
||||
.ddasi_dataoe (ddasi_dataoe ),
|
||||
.ddasi_dataout (ddasi_dataout ),
|
||||
.ddasi_dclk (ddasi_dclk ),
|
||||
.ddasi_scein (ddasi_scein ),
|
||||
.ddasi_sdoin (ddasi_sdoin ),
|
||||
`else
|
||||
.epcq_dataout ({ASI_WIDTH{1'b0}} ),
|
||||
.epcq_dclk ( ),
|
||||
.epcq_scein ( ),
|
||||
.epcq_sdoin ( ),
|
||||
.epcq_dataoe ( ),
|
||||
.ddasi_dataoe ({ASI_WIDTH{1'b0}} ),
|
||||
.ddasi_dataout ( ),
|
||||
.ddasi_dclk (1'b0 ),
|
||||
.ddasi_scein ({CS_WIDTH{1'b0}} ),
|
||||
.ddasi_sdoin ({ASI_WIDTH{1'b0}} ),
|
||||
`endif
|
||||
.asmi_busy (asmi_busy ),
|
||||
.asmi_data_valid (asmi_data_valid ),
|
||||
.asmi_dataout (asmi_dataout ),
|
||||
.asmi_clkin (asmi_clkin ),
|
||||
.asmi_reset (asmi_reset ),
|
||||
`ifdef MULTICHIP
|
||||
.asmi_sce (asmi_sce ),
|
||||
`else
|
||||
.asmi_sce ( ),
|
||||
`endif
|
||||
.asmi_addr (asmi_addr ),
|
||||
.asmi_datain (asmi_datain ),
|
||||
.asmi_fast_read (asmi_fast_read ),
|
||||
.asmi_rden (asmi_rden ),
|
||||
.asmi_shift_bytes (asmi_shift_bytes ),
|
||||
.asmi_wren (asmi_wren ),
|
||||
.asmi_write (asmi_write ),
|
||||
.asmi_illegal_erase (asmi_illegal_erase ),
|
||||
.asmi_illegal_write (asmi_illegal_write ),
|
||||
.asmi_rdid_out (asmi_rdid_out ),
|
||||
.asmi_status_out (asmi_status_out ),
|
||||
`ifdef ENABLE_SID
|
||||
.asmi_epcs_id (asmi_epcs_id ),
|
||||
.asmi_read_sid (asmi_read_sid ),
|
||||
`else
|
||||
.asmi_epcs_id ({8{1'b0}} ),
|
||||
.asmi_read_sid ( ),
|
||||
`endif
|
||||
.asmi_read_rdid (asmi_read_rdid ),
|
||||
.asmi_read_status (asmi_read_status ),
|
||||
`ifdef ENABLE_4BYTE_ADDR_CODE
|
||||
.asmi_en4b_addr (asmi_en4b_addr ),
|
||||
`else
|
||||
.asmi_en4b_addr ( ),
|
||||
`endif
|
||||
`ifdef ENABLE_BULK_ERASE
|
||||
.asmi_bulk_erase (asmi_bulk_erase ),
|
||||
`else
|
||||
.asmi_bulk_erase ( ),
|
||||
`endif
|
||||
.asmi_sector_erase (asmi_sector_erase ),
|
||||
.asmi_sector_protect (asmi_sector_protect )
|
||||
);
|
||||
|
||||
altera_asmi_parallel asmi_parallel_inst (
|
||||
.busy (asmi_busy ),
|
||||
.data_valid (asmi_data_valid ),
|
||||
.dataout (asmi_dataout ),
|
||||
.clkin (asmi_clkin ),
|
||||
.reset (asmi_reset ),
|
||||
`ifdef MULTICHIP
|
||||
.sce (asmi_sce ),
|
||||
`endif
|
||||
.addr (asmi_addr ),
|
||||
.datain (asmi_datain ),
|
||||
.fast_read (asmi_fast_read ),
|
||||
.rden (asmi_rden ),
|
||||
.shift_bytes (asmi_shift_bytes ),
|
||||
.wren (asmi_wren ),
|
||||
.write (asmi_write ),
|
||||
.illegal_erase (asmi_illegal_erase ),
|
||||
.illegal_write (asmi_illegal_write ),
|
||||
.rdid_out (asmi_rdid_out ),
|
||||
.status_out (asmi_status_out ),
|
||||
.read_dummyclk (1'b0),
|
||||
`ifdef ENABLE_SID
|
||||
.epcs_id (asmi_epcs_id ),
|
||||
.read_sid (asmi_read_sid ),
|
||||
`endif
|
||||
.read_rdid (asmi_read_rdid ),
|
||||
.read_status (asmi_read_status ),
|
||||
`ifdef ENABLE_4BYTE_ADDR_CODE
|
||||
.en4b_addr (asmi_en4b_addr ),
|
||||
`endif
|
||||
`ifdef ENABLE_BULK_ERASE
|
||||
.bulk_erase (asmi_bulk_erase ),
|
||||
`endif
|
||||
`ifdef DDASI_ON
|
||||
.asmi_dataoe (ddasi_dataoe ),
|
||||
.asmi_dataout (ddasi_dataout ),
|
||||
.asmi_dclk (ddasi_dclk ),
|
||||
.asmi_scein (ddasi_scein ),
|
||||
.asmi_sdoin (ddasi_sdoin )
|
||||
`endif
|
||||
.sector_erase (asmi_sector_erase ),
|
||||
.sector_protect (asmi_sector_protect )
|
||||
);
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,648 @@
|
|||
# (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
# Your use of Altera Corporation's design tools, logic functions and other
|
||||
# software and tools, and its AMPP partner logic functions, and any output
|
||||
# files any of the foregoing (including device programming or simulation
|
||||
# files), and any associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License Subscription
|
||||
# Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
# license agreement, including, without limitation, that your use is for the
|
||||
# sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
# Altera or its authorized distributors. Please refer to the applicable
|
||||
# agreement for further details.
|
||||
|
||||
|
||||
package require -exact qsys 14.1
|
||||
package require -exact altera_terp 1.0
|
||||
|
||||
|
||||
#
|
||||
# module altera_trace_wrapper
|
||||
#
|
||||
set_module_property DESCRIPTION "This component is a serial flash controller which allows user to access Altera EPCQ devices"
|
||||
set_module_property NAME altera_epcq_controller_mod
|
||||
set_module_property VERSION 15.1
|
||||
set_module_property INTERNAL false
|
||||
set_module_property OPAQUE_ADDRESS_MAP true
|
||||
set_module_property GROUP "Basic Functions/Configuration and Programming"
|
||||
set_module_property AUTHOR "Altera Corporation"
|
||||
set_module_property DISPLAY_NAME "Altera Serial Flash Controller"
|
||||
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
|
||||
set_module_property HIDE_FROM_QUARTUS true
|
||||
set_module_property EDITABLE true
|
||||
set_module_property ALLOW_GREYBOX_GENERATION false
|
||||
set_module_property REPORT_HIERARCHY false
|
||||
set_module_property ELABORATION_CALLBACK elaboration
|
||||
|
||||
add_fileset QUARTUS_SYNTH QUARTUS_SYNTH add_topwrapper_fileset_proc
|
||||
set_fileset_property QUARTUS_SYNTH TOP_LEVEL altera_epcq_controller_wrapper
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
|
||||
|
||||
add_fileset SIM_VERILOG SIM_VERILOG add_topwrapper_fileset_proc
|
||||
set_fileset_property SIM_VERILOG TOP_LEVEL altera_epcq_controller_wrapper
|
||||
set_fileset_property SIM_VERILOG ENABLE_RELATIVE_INCLUDE_PATHS false
|
||||
set_fileset_property SIM_VERILOG ENABLE_FILE_OVERWRITE_MODE true
|
||||
#
|
||||
# parameters
|
||||
#
|
||||
# +-----------------------------------
|
||||
# | device family info
|
||||
# +-----------------------------------
|
||||
set all_supported_device_families_list {"Arria 10" "Cyclone V" "Arria V GZ" "Arria V" "Stratix V" "Stratix IV" \
|
||||
"Cyclone IV GX" "Cyclone IV E" "Cyclone III GL" "Arria II GZ" "Arria II GX"}
|
||||
|
||||
proc check_device_ini {device_families_list} {
|
||||
|
||||
set enable_max10 [get_quartus_ini enable_max10_active_serial ENABLED]
|
||||
|
||||
if {$enable_max10 == 1} {
|
||||
lappend device_families_list "MAX 10 FPGA"
|
||||
}
|
||||
return $device_families_list
|
||||
}
|
||||
|
||||
set device_list [check_device_ini $all_supported_device_families_list]
|
||||
set_module_property SUPPORTED_DEVICE_FAMILIES $device_list
|
||||
|
||||
add_parameter DEVICE_FAMILY STRING
|
||||
set_parameter_property DEVICE_FAMILY SYSTEM_INFO {DEVICE_FAMILY}
|
||||
set_parameter_property DEVICE_FAMILY VISIBLE false
|
||||
set_parameter_property DEVICE_FAMILY HDL_PARAMETER true
|
||||
|
||||
add_parameter ASI_WIDTH INTEGER 1
|
||||
set_parameter_property ASI_WIDTH DEFAULT_VALUE 1
|
||||
set_parameter_property ASI_WIDTH DISPLAY_NAME ASI_WIDTH
|
||||
set_parameter_property ASI_WIDTH DERIVED true
|
||||
set_parameter_property ASI_WIDTH TYPE INTEGER
|
||||
set_parameter_property ASI_WIDTH VISIBLE false
|
||||
set_parameter_property ASI_WIDTH UNITS None
|
||||
set_parameter_property ASI_WIDTH ALLOWED_RANGES {1, 4}
|
||||
set_parameter_property ASI_WIDTH HDL_PARAMETER true
|
||||
|
||||
add_parameter CS_WIDTH INTEGER 1
|
||||
set_parameter_property CS_WIDTH DEFAULT_VALUE 1
|
||||
set_parameter_property CS_WIDTH DISPLAY_NAME CS_WIDTH
|
||||
set_parameter_property CS_WIDTH DERIVED true
|
||||
set_parameter_property CS_WIDTH TYPE INTEGER
|
||||
set_parameter_property CS_WIDTH VISIBLE false
|
||||
set_parameter_property CS_WIDTH UNITS None
|
||||
set_parameter_property CS_WIDTH ALLOWED_RANGES {1, 3}
|
||||
set_parameter_property CS_WIDTH HDL_PARAMETER true
|
||||
|
||||
add_parameter ADDR_WIDTH INTEGER 19
|
||||
set_parameter_property ADDR_WIDTH DEFAULT_VALUE 19
|
||||
set_parameter_property ADDR_WIDTH DISPLAY_NAME ADDR_WIDTH
|
||||
set_parameter_property ADDR_WIDTH DERIVED true
|
||||
set_parameter_property ADDR_WIDTH TYPE INTEGER
|
||||
set_parameter_property ADDR_WIDTH VISIBLE false
|
||||
set_parameter_property ADDR_WIDTH UNITS None
|
||||
# 16M-19bit, 32M-20bit, 64M-21bit, 128M-22bit, 256M-23bit, 512M-24bit, 1024M-25bit, 2048M-26bit...
|
||||
set_parameter_property ADDR_WIDTH ALLOWED_RANGES {19, 20, 21, 22, 23, 24, 25, 26, 27, 28}
|
||||
set_parameter_property ADDR_WIDTH HDL_PARAMETER true
|
||||
|
||||
add_parameter ASMI_ADDR_WIDTH INTEGER 24
|
||||
set_parameter_property ASMI_ADDR_WIDTH DEFAULT_VALUE 24
|
||||
set_parameter_property ASMI_ADDR_WIDTH DISPLAY_NAME ASMI_ADDR_WIDTH
|
||||
set_parameter_property ASMI_ADDR_WIDTH DERIVED true
|
||||
set_parameter_property ASMI_ADDR_WIDTH TYPE INTEGER
|
||||
set_parameter_property ASMI_ADDR_WIDTH VISIBLE false
|
||||
set_parameter_property ASMI_ADDR_WIDTH UNITS None
|
||||
set_parameter_property ASMI_ADDR_WIDTH ALLOWED_RANGES {24, 32}
|
||||
set_parameter_property ASMI_ADDR_WIDTH HDL_PARAMETER true
|
||||
|
||||
add_parameter ENABLE_4BYTE_ADDR INTEGER "0"
|
||||
set_parameter_property ENABLE_4BYTE_ADDR DISPLAY_NAME "Enable 4-byte addressing mode"
|
||||
set_parameter_property ENABLE_4BYTE_ADDR DESCRIPTION "Check to enable 4-byte addressing mode for device larger than 128Mbyte"
|
||||
set_parameter_property ENABLE_4BYTE_ADDR AFFECTS_GENERATION true
|
||||
set_parameter_property ENABLE_4BYTE_ADDR VISIBLE false
|
||||
set_parameter_property ENABLE_4BYTE_ADDR HDL_PARAMETER true
|
||||
set_parameter_property ENABLE_4BYTE_ADDR DERIVED true
|
||||
|
||||
# +-----------------------------------
|
||||
|
||||
# add system info parameter
|
||||
add_parameter deviceFeaturesSystemInfo STRING "None"
|
||||
set_parameter_property deviceFeaturesSystemInfo system_info "DEVICE_FEATURES"
|
||||
set_parameter_property deviceFeaturesSystemInfo VISIBLE false
|
||||
|
||||
add_parameter DDASI INTEGER "0"
|
||||
set_parameter_property DDASI DISPLAY_NAME "Disable dedicated Active Serial interface"
|
||||
set_parameter_property DDASI DESCRIPTION "Check to route ASMIBLOCK signals to top level of design"
|
||||
set_parameter_property DDASI AFFECTS_GENERATION true
|
||||
set_parameter_property DDASI VISIBLE false
|
||||
set_parameter_property DDASI DERIVED false
|
||||
|
||||
add_parameter clkFreq LONG
|
||||
set_parameter_property clkFreq DEFAULT_VALUE {0}
|
||||
set_parameter_property clkFreq DISPLAY_NAME {clkFreq}
|
||||
set_parameter_property clkFreq VISIBLE {0}
|
||||
set_parameter_property clkFreq AFFECTS_GENERATION {1}
|
||||
set_parameter_property clkFreq HDL_PARAMETER {0}
|
||||
set_parameter_property clkFreq SYSTEM_INFO {clock_rate clk}
|
||||
set_parameter_property clkFreq SYSTEM_INFO_TYPE {CLOCK_RATE}
|
||||
set_parameter_property clkFreq SYSTEM_INFO_ARG {clock_sink}
|
||||
|
||||
#
|
||||
# connection point clock_sink
|
||||
#
|
||||
add_interface clock_sink clock end
|
||||
set_interface_property clock_sink clockRate 0
|
||||
set_interface_property clock_sink ENABLED true
|
||||
set_interface_property clock_sink EXPORT_OF ""
|
||||
set_interface_property clock_sink PORT_NAME_MAP ""
|
||||
set_interface_property clock_sink CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property clock_sink SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port clock_sink clk clk Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point reset
|
||||
#
|
||||
add_interface reset reset end
|
||||
set_interface_property reset associatedClock clock_sink
|
||||
set_interface_property reset synchronousEdges DEASSERT
|
||||
set_interface_property reset ENABLED true
|
||||
set_interface_property reset EXPORT_OF ""
|
||||
set_interface_property reset PORT_NAME_MAP ""
|
||||
set_interface_property reset CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property reset SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port reset reset_n reset_n Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point avl_csr
|
||||
#
|
||||
add_interface avl_csr avalon end
|
||||
set_interface_property avl_csr addressUnits WORDS
|
||||
set_interface_property avl_csr associatedClock clock_sink
|
||||
set_interface_property avl_csr associatedReset reset
|
||||
set_interface_property avl_csr bitsPerSymbol 8
|
||||
set_interface_property avl_csr burstOnBurstBoundariesOnly false
|
||||
set_interface_property avl_csr burstcountUnits WORDS
|
||||
set_interface_property avl_csr explicitAddressSpan 0
|
||||
set_interface_property avl_csr holdTime 0
|
||||
set_interface_property avl_csr linewrapBursts false
|
||||
set_interface_property avl_csr maximumPendingReadTransactions 1
|
||||
set_interface_property avl_csr maximumPendingWriteTransactions 0
|
||||
set_interface_property avl_csr readLatency 0
|
||||
set_interface_property avl_csr readWaitTime 0
|
||||
set_interface_property avl_csr setupTime 0
|
||||
set_interface_property avl_csr timingUnits Cycles
|
||||
set_interface_property avl_csr writeWaitTime 0
|
||||
set_interface_property avl_csr ENABLED true
|
||||
set_interface_property avl_csr EXPORT_OF ""
|
||||
set_interface_property avl_csr PORT_NAME_MAP ""
|
||||
set_interface_property avl_csr CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property avl_csr SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port avl_csr avl_csr_read read Input 1
|
||||
add_interface_port avl_csr avl_csr_waitrequest waitrequest Output 1
|
||||
add_interface_port avl_csr avl_csr_write write Input 1
|
||||
add_interface_port avl_csr avl_csr_addr address Input 3
|
||||
add_interface_port avl_csr avl_csr_wrdata writedata Input 32
|
||||
add_interface_port avl_csr avl_csr_rddata readdata Output 32
|
||||
add_interface_port avl_csr avl_csr_rddata_valid readdatavalid Output 1
|
||||
|
||||
#
|
||||
# connection point avl_mem
|
||||
#
|
||||
add_interface avl_mem avalon end
|
||||
set_interface_property avl_mem addressUnits WORDS
|
||||
set_interface_property avl_mem associatedClock clock_sink
|
||||
set_interface_property avl_mem associatedReset reset
|
||||
set_interface_property avl_mem bitsPerSymbol 8
|
||||
set_interface_property avl_mem burstOnBurstBoundariesOnly false
|
||||
set_interface_property avl_mem burstcountUnits WORDS
|
||||
set_interface_property avl_mem explicitAddressSpan 0
|
||||
set_interface_property avl_mem holdTime 0
|
||||
set_interface_property avl_mem linewrapBursts true
|
||||
set_interface_property avl_mem maximumPendingReadTransactions 1
|
||||
set_interface_property avl_mem maximumPendingWriteTransactions 0
|
||||
set_interface_property avl_mem constantBurstBehavior true
|
||||
set_interface_property avl_mem readLatency 0
|
||||
set_interface_property avl_mem readWaitTime 0
|
||||
set_interface_property avl_mem setupTime 0
|
||||
set_interface_property avl_mem timingUnits Cycles
|
||||
set_interface_property avl_mem writeWaitTime 0
|
||||
set_interface_property avl_mem ENABLED true
|
||||
set_interface_property avl_mem EXPORT_OF ""
|
||||
set_interface_property avl_mem PORT_NAME_MAP ""
|
||||
set_interface_property avl_mem CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property avl_mem SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port avl_mem avl_mem_write write Input 1
|
||||
add_interface_port avl_mem avl_mem_burstcount burstcount Input 7
|
||||
add_interface_port avl_mem avl_mem_waitrequest waitrequest Output 1
|
||||
add_interface_port avl_mem avl_mem_read read Input 1
|
||||
add_interface_port avl_mem avl_mem_addr address Input ADDR_WIDTH
|
||||
add_interface_port avl_mem avl_mem_wrdata writedata Input 32
|
||||
add_interface_port avl_mem avl_mem_rddata readdata Output 32
|
||||
add_interface_port avl_mem avl_mem_rddata_valid readdatavalid Output 1
|
||||
add_interface_port avl_mem avl_mem_byteenable byteenable Input 4
|
||||
|
||||
#
|
||||
# connection point interrupt_sender
|
||||
#
|
||||
add_interface interrupt_sender interrupt end
|
||||
set_interface_property interrupt_sender associatedAddressablePoint avl_csr
|
||||
set_interface_property interrupt_sender associatedClock clock_sink
|
||||
set_interface_property interrupt_sender associatedReset reset
|
||||
set_interface_property interrupt_sender bridgedReceiverOffset ""
|
||||
set_interface_property interrupt_sender bridgesToReceiver ""
|
||||
set_interface_property interrupt_sender ENABLED true
|
||||
set_interface_property interrupt_sender EXPORT_OF ""
|
||||
set_interface_property interrupt_sender PORT_NAME_MAP ""
|
||||
set_interface_property interrupt_sender CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property interrupt_sender SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port interrupt_sender irq irq Output 1
|
||||
|
||||
proc proc_get_derive_addr_width {flash_type} {
|
||||
switch $flash_type {
|
||||
"EPCS16" - "EPCQ16" {
|
||||
return 19
|
||||
}
|
||||
"EPCS64" - "EPCQ64" {
|
||||
return 21
|
||||
}
|
||||
"EPCS128" - "EPCQ128" {
|
||||
return 22
|
||||
}
|
||||
"EPCQ32" {
|
||||
return 20
|
||||
}
|
||||
"EPCQ256" - "EPCQL256" {
|
||||
return 23
|
||||
}
|
||||
"EPCQ512" - "EPCQL512" {
|
||||
return 24
|
||||
}
|
||||
"EPCQL1024" {
|
||||
return 25
|
||||
}
|
||||
default {
|
||||
# Should never enter this function
|
||||
send_message error "$flash_type is not a valid flash type"
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
set all_supported_SPI_list {"EPCS16" "EPCS64" "EPCS128" "EPCQ16" "EPCQ32" "EPCQ64" "EPCQ128" "EPCQ256" \
|
||||
"EPCQ512" "EPCQL256" "EPCQL512" "EPCQL1024"}
|
||||
|
||||
# SPI device selection
|
||||
add_parameter FLASH_TYPE STRING "EPCQ16"
|
||||
set_parameter_property FLASH_TYPE DISPLAY_NAME "Configuration device type"
|
||||
set_parameter_property FLASH_TYPE ALLOWED_RANGES $all_supported_SPI_list
|
||||
set_parameter_property FLASH_TYPE DESCRIPTION "Select targeted EPCS/EPCQ devices"
|
||||
set_parameter_property FLASH_TYPE AFFECTS_GENERATION true
|
||||
set_parameter_property FLASH_TYPE VISIBLE true
|
||||
set_parameter_property FLASH_TYPE DERIVED false
|
||||
|
||||
add_parameter IO_MODE STRING "STANDARD"
|
||||
set_parameter_property IO_MODE DISPLAY_NAME "Choose I/O mode"
|
||||
set_parameter_property IO_MODE ALLOWED_RANGES {"STANDARD" "QUAD"}
|
||||
set_parameter_property IO_MODE DESCRIPTION "Select extended data width when Fast Read operation is enabled"
|
||||
|
||||
add_parameter CHIP_SELS INTEGER "1"
|
||||
set_parameter_property CHIP_SELS DISPLAY_NAME "Number of Chip Selects used"
|
||||
set_parameter_property CHIP_SELS ALLOWED_RANGES {1 2 3}
|
||||
set_parameter_property CHIP_SELS DESCRIPTION "Number of EPCQ(L) devices that are attached and need a CHIPSEL"
|
||||
set_parameter_property CHIP_SELS HDL_PARAMETER true
|
||||
set_parameter_property CHIP_SELS AFFECTS_GENERATION true
|
||||
#
|
||||
# Add instance
|
||||
#
|
||||
proc add_topwrapper_fileset_proc {altera_epcq_controller} {
|
||||
# QSPI that supported for 4-byte addressing - en4b_addr, ex4b_addr
|
||||
set supported_4byte_addr {"EPCQ256" "EPCQ512" "EPCQL256" "EPCQL512" "EPCQL1024" "N25Q512"}
|
||||
set DDASI [ get_parameter_value DDASI ]
|
||||
set DEVICE_FAMILY [ get_parameter_value DEVICE_FAMILY ]
|
||||
set FLASH_TYPE [ get_parameter_value FLASH_TYPE ]
|
||||
set ADDR_WIDTH [ get_parameter_value ADDR_WIDTH ]
|
||||
set is_4byte_addr_support "false"
|
||||
|
||||
# check whether devices supporting multiple flash - only for Arria 10
|
||||
if {[check_device_family_equivalence $DEVICE_FAMILY "Arria 10"]} {
|
||||
set MULTICHIP 1
|
||||
} else {
|
||||
set MULTICHIP 0
|
||||
}
|
||||
|
||||
if { $DDASI eq "1" } {
|
||||
set DDASI_ON 1
|
||||
} else {
|
||||
set DDASI_ON 0
|
||||
}
|
||||
|
||||
if { $FLASH_TYPE eq "EPCS16" || $FLASH_TYPE eq "EPCS64" } {
|
||||
set ENABLE_SID 1
|
||||
} else {
|
||||
set ENABLE_SID 0
|
||||
}
|
||||
|
||||
if { $FLASH_TYPE eq "EPCQL512" || $FLASH_TYPE eq "EPCQL1024" } {
|
||||
set ENABLE_BULK_ERASE 0
|
||||
} else {
|
||||
set ENABLE_BULK_ERASE 1
|
||||
}
|
||||
|
||||
# check whether SPI device support 4-byte addressing
|
||||
foreach re_spi_1 $supported_4byte_addr {
|
||||
if {$re_spi_1 eq $FLASH_TYPE} {
|
||||
set is_4byte_addr_support "true"
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if {$is_4byte_addr_support eq "true"} {
|
||||
set ENABLE_4BYTE_ADDR_CODE 1
|
||||
} else {
|
||||
set ENABLE_4BYTE_ADDR_CODE 0
|
||||
}
|
||||
|
||||
# ---------------------------------
|
||||
# Terp for top level wrapper
|
||||
# ---------------------------------
|
||||
#Do Terp
|
||||
set template_file [ file join "./" "altera_epcq_controller_wrapper.sv.terp" ]
|
||||
set template [ read [ open $template_file r ] ]
|
||||
|
||||
if {$DDASI_ON} {
|
||||
set params(DDASI_ON) "`define DDASI_ON"
|
||||
} else {
|
||||
set params(DDASI_ON) ""
|
||||
}
|
||||
|
||||
if {$MULTICHIP} {
|
||||
set params(MULTICHIP) "`define MULTICHIP"
|
||||
} else {
|
||||
set params(MULTICHIP) ""
|
||||
}
|
||||
|
||||
if {$ENABLE_SID} {
|
||||
set params(SID_EN) "`define ENABLE_SID"
|
||||
} else {
|
||||
set params(SID_EN) ""
|
||||
}
|
||||
|
||||
if {$ENABLE_BULK_ERASE} {
|
||||
set params(BULK_ERASE_EN) "`define ENABLE_BULK_ERASE"
|
||||
} else {
|
||||
set params(BULK_ERASE_EN) ""
|
||||
}
|
||||
|
||||
if {$ENABLE_4BYTE_ADDR_CODE} {
|
||||
set params(4BYTE_ADDR_EN) "`define ENABLE_4BYTE_ADDR_CODE"
|
||||
} else {
|
||||
set params(4BYTE_ADDR_EN) ""
|
||||
}
|
||||
|
||||
set result [ altera_terp $template params ]
|
||||
|
||||
#Add top wrapper file
|
||||
add_fileset_file ./altera_epcq_controller_wrapper.sv SYSTEM_VERILOG TEXT $result
|
||||
}
|
||||
|
||||
# This proc is called by elaboration proc to set embeddedsw C Macros assignments
|
||||
# used by downstream tools
|
||||
proc set_cmacros {is_qspi flash_type} {
|
||||
if {$is_qspi eq "true"} {
|
||||
set_module_assignment embeddedsw.CMacro.IS_EPCS 0
|
||||
} else {
|
||||
set_module_assignment embeddedsw.CMacro.IS_EPCS 1
|
||||
}
|
||||
|
||||
#string name of flash
|
||||
set_module_assignment embeddedsw.CMacro.FLASH_TYPE $flash_type
|
||||
|
||||
#page size in bytes
|
||||
set_module_assignment embeddedsw.CMacro.PAGE_SIZE 256
|
||||
|
||||
#sector and subsector size in bytes
|
||||
set_module_assignment embeddedsw.CMacro.SUBSECTOR_SIZE 4096
|
||||
set_module_assignment embeddedsw.CMacro.SECTOR_SIZE 65536
|
||||
|
||||
#set number of sectors
|
||||
switch $flash_type {
|
||||
"EPCS16" - "EPCQ16" {
|
||||
set_module_assignment embeddedsw.CMacro.NUMBER_OF_SECTORS 32
|
||||
}
|
||||
"EPCQ32" {
|
||||
set_module_assignment embeddedsw.CMacro.NUMBER_OF_SECTORS 64
|
||||
}
|
||||
"EPCS64" - "EPCQ64" {
|
||||
set_module_assignment embeddedsw.CMacro.NUMBER_OF_SECTORS 128
|
||||
}
|
||||
"EPCS128" - "EPCQ128" {
|
||||
set_module_assignment embeddedsw.CMacro.NUMBER_OF_SECTORS 256
|
||||
}
|
||||
"EPCQ256" - "EPCQL256" {
|
||||
set_module_assignment embeddedsw.CMacro.NUMBER_OF_SECTORS 512
|
||||
}
|
||||
"EPCQ512" - "EPCQL512" {
|
||||
set_module_assignment embeddedsw.CMacro.NUMBER_OF_SECTORS 1024
|
||||
}
|
||||
"EPCQL1024" {
|
||||
set_module_assignment embeddedsw.CMacro.NUMBER_OF_SECTORS 2048
|
||||
}
|
||||
default {
|
||||
# Should never enter this function
|
||||
send_message error "$flash_type is not a valid flash type"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc elaboration {} {
|
||||
# QSPI that supported for 4-byte addressing - en4b_addr, ex4b_addr
|
||||
set supported_4byte_addr {"EPCQ256" "EPCQ512" "EPCQL256" "EPCQL512" "EPCQL1024" "N25Q512"}
|
||||
set DDASI_ON [ get_parameter_value DDASI ]
|
||||
set FLASH_TYPE [ get_parameter_value FLASH_TYPE ]
|
||||
set IO_MODE [ get_parameter_value IO_MODE ]
|
||||
set DEVICE_FAMILY [ get_parameter_value DEVICE_FAMILY ]
|
||||
set ASI_WIDTH [ get_parameter_value ASI_WIDTH ]
|
||||
set CS_WIDTH [ get_parameter_value CS_WIDTH ]
|
||||
set ASMI_ADDR_WIDTH [ get_parameter_value ASMI_ADDR_WIDTH ]
|
||||
set CHIP_SELS [ get_parameter_value CHIP_SELS]
|
||||
set temp_addr_width [ proc_get_derive_addr_width [ get_parameter_value FLASH_TYPE ] ]
|
||||
set clkFreq [ get_parameter_value clkFreq ]
|
||||
set is_4byte_addr_support "false"
|
||||
set is_qspi "false"
|
||||
|
||||
# we're not using slow and expensive EPCS flash, thus higher frequency allowed
|
||||
if { $clkFreq > 50000000 } {
|
||||
send_message error "The maximum input clock frequency for Altera Serial Flash controller is 25Mhz."
|
||||
}
|
||||
|
||||
# check whether SPI device support 4-byte addressing
|
||||
foreach re_spi_1 $supported_4byte_addr {
|
||||
if {$re_spi_1 eq $FLASH_TYPE} {
|
||||
set is_4byte_addr_support "true"
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if {$is_4byte_addr_support eq "true"} {
|
||||
set_parameter_value ENABLE_4BYTE_ADDR "1"
|
||||
set_parameter_value ASMI_ADDR_WIDTH 32
|
||||
} else {
|
||||
set_parameter_value ENABLE_4BYTE_ADDR "0"
|
||||
set_parameter_value ASMI_ADDR_WIDTH 24
|
||||
}
|
||||
|
||||
# check whether devices supporting multiple flash - only for Arria 10
|
||||
if {[check_device_family_equivalence $DEVICE_FAMILY "Arria 10"]} {
|
||||
set is_multi_flash_support "true"
|
||||
if {$CHIP_SELS eq 3 } {set_parameter_value ADDR_WIDTH [ expr $temp_addr_width + 2]}
|
||||
if {$CHIP_SELS eq 2 } {set_parameter_value ADDR_WIDTH [ expr $temp_addr_width + 1]}
|
||||
if {$CHIP_SELS eq 1 } {set_parameter_value ADDR_WIDTH $temp_addr_width }
|
||||
} else {
|
||||
set is_multi_flash_support "false"
|
||||
set_parameter_value ADDR_WIDTH $temp_addr_width
|
||||
}
|
||||
|
||||
|
||||
set_instance_parameter_value altera_epcq_controller_core DDASI $DDASI_ON
|
||||
set_instance_parameter_value altera_epcq_controller_core FLASH_TYPE $FLASH_TYPE
|
||||
set_instance_parameter_value altera_epcq_controller_core IO_MODE $IO_MODE
|
||||
set_instance_parameter_value altera_epcq_controller_core ASI_WIDTH $ASI_WIDTH
|
||||
set_instance_parameter_value altera_epcq_controller_core CS_WIDTH $CS_WIDTH
|
||||
set_instance_parameter_value altera_epcq_controller_core CHIP_SELS $CHIP_SELS
|
||||
set_instance_parameter_value altera_epcq_controller_core ASMI_ADDR_WIDTH [ get_parameter_value ASMI_ADDR_WIDTH ]
|
||||
set_instance_parameter_value altera_epcq_controller_core ADDR_WIDTH [ get_parameter_value ADDR_WIDTH ]
|
||||
set_instance_parameter_value altera_epcq_controller_core ENABLE_4BYTE_ADDR [ get_parameter_value ENABLE_4BYTE_ADDR ]
|
||||
|
||||
set QSPI_list {"EPCQ16" "EPCQ32" "EPCQ64" "EPCQ128" "EPCQ256" "EPCQ512" "EPCQL256" "EPCQL512" "EPCQL1024" \
|
||||
"N25Q512" "S25FL127S"}
|
||||
|
||||
# devices that supported QSPI - Quad/Dual data width, asmi_dataout, asmi_sdoin, asmi_dataoe
|
||||
set supported_QSPI_devices_list {"Arria 10" "Cyclone V" "Arria V GZ" "Arria V" "Stratix V"}
|
||||
|
||||
# devices that supported simulation
|
||||
set supported_sim_devices_list {"Arria 10" "Cyclone V" "Arria V GZ" "Arria V" "Stratix V" "MAX 10 FPGA"}
|
||||
|
||||
# check whether is QSPI devices
|
||||
foreach re_spi_0 $QSPI_list {
|
||||
if {$re_spi_0 eq $FLASH_TYPE} {
|
||||
set is_qspi "true"
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if {[check_device_family_equivalence $DEVICE_FAMILY $supported_QSPI_devices_list]} {
|
||||
set is_qspi_devices_list "true"
|
||||
} else {
|
||||
set is_qspi_devices_list "false"
|
||||
}
|
||||
|
||||
if {[check_device_family_equivalence $DEVICE_FAMILY $supported_sim_devices_list]} {
|
||||
set is_sim_devices_list "true"
|
||||
} else {
|
||||
set is_sim_devices_list "false"
|
||||
}
|
||||
|
||||
if {$is_qspi_devices_list eq "true" && $is_qspi eq "true"} {
|
||||
set_parameter_property IO_MODE ENABLED true
|
||||
set_instance_parameter_value altera_asmi_parallel DATA_WIDTH $IO_MODE
|
||||
set_parameter_value ASI_WIDTH 4
|
||||
} else {
|
||||
set_parameter_property IO_MODE ENABLED false
|
||||
set_parameter_value ASI_WIDTH 1
|
||||
}
|
||||
|
||||
if { $FLASH_TYPE eq "EPCQL512" || $FLASH_TYPE eq "EPCQL1024" } {
|
||||
set_instance_parameter_value altera_asmi_parallel gui_bulk_erase false
|
||||
set ENABLE_BULK_ERASE 0
|
||||
} else {
|
||||
set_instance_parameter_value altera_asmi_parallel gui_bulk_erase true
|
||||
set ENABLE_BULK_ERASE 1
|
||||
}
|
||||
|
||||
if { $is_multi_flash_support eq "true"} {
|
||||
set_parameter_value CS_WIDTH 3
|
||||
set_parameter_property CHIP_SELS ENABLED true
|
||||
} else {
|
||||
set_parameter_value CS_WIDTH 1
|
||||
set_parameter_property CHIP_SELS ENABLED false
|
||||
}
|
||||
|
||||
set_instance_parameter_value altera_asmi_parallel EPCS_TYPE $FLASH_TYPE
|
||||
set_instance_parameter_value altera_asmi_parallel gui_fast_read true
|
||||
set_instance_parameter_value altera_asmi_parallel gui_page_write true
|
||||
|
||||
if { $FLASH_TYPE eq "EPCS16" || $FLASH_TYPE eq "EPCS64" } {
|
||||
set_instance_parameter_value altera_asmi_parallel gui_read_sid true
|
||||
} else {
|
||||
set_instance_parameter_value altera_asmi_parallel gui_read_sid false
|
||||
}
|
||||
|
||||
set_instance_parameter_value altera_asmi_parallel gui_read_rdid true
|
||||
set_instance_parameter_value altera_asmi_parallel gui_read_status true
|
||||
set_instance_parameter_value altera_asmi_parallel gui_sector_erase true
|
||||
set_instance_parameter_value altera_asmi_parallel gui_sector_protect true
|
||||
set_instance_parameter_value altera_asmi_parallel gui_wren true
|
||||
set_instance_parameter_value altera_asmi_parallel gui_write true
|
||||
set_instance_parameter_value altera_asmi_parallel gui_read_dummyclk true
|
||||
set_instance_parameter_value altera_asmi_parallel PAGE_SIZE 256
|
||||
set_instance_parameter_value altera_asmi_parallel gui_use_asmiblock $DDASI_ON
|
||||
|
||||
if {$is_sim_devices_list eq "true"} {
|
||||
set_instance_parameter_value altera_asmi_parallel ENABLE_SIM true
|
||||
} else {
|
||||
set_instance_parameter_value altera_asmi_parallel ENABLE_SIM false
|
||||
}
|
||||
|
||||
set_cmacros $is_qspi $FLASH_TYPE
|
||||
}
|
||||
|
||||
# add ASMI PARALLEL
|
||||
add_hdl_instance altera_asmi_parallel altera_asmi_parallel
|
||||
|
||||
# add EPCQ CONTROLLER
|
||||
add_hdl_instance altera_epcq_controller_core altera_epcq_controller_core
|
||||
|
||||
# +-------------------------------------
|
||||
# | Add settings needed by Nios tools
|
||||
# +-------------------------------------
|
||||
# Tells us component is a flash
|
||||
set_module_assignment embeddedsw.memoryInfo.IS_FLASH 1
|
||||
|
||||
# interface assignments for embedded software
|
||||
set_interface_assignment avl_mem embeddedsw.configuration.isFlash 1
|
||||
set_interface_assignment avl_mem embeddedsw.configuration.isMemoryDevice 1
|
||||
set_interface_assignment avl_mem embeddedsw.configuration.isNonVolatileStorage 1
|
||||
set_interface_assignment avl_mem embeddedsw.configuration.isPrintableDevice 0
|
||||
|
||||
# These assignments tells tools to create byte-addressed .hex files only
|
||||
set_module_assignment embeddedsw.memoryInfo.GENERATE_HEX 1
|
||||
set_module_assignment embeddedsw.memoryInfo.USE_BYTE_ADDRESSING_FOR_HEX 1
|
||||
set_module_assignment embeddedsw.memoryInfo.GENERATE_DAT_SYM 0
|
||||
set_module_assignment embeddedsw.memoryInfo.GENERATE_FLASH 0
|
||||
|
||||
# Width of memory
|
||||
set_module_assignment embeddedsw.memoryInfo.MEM_INIT_DATA_WIDTH 32
|
||||
|
||||
# Output directories for programming files
|
||||
#set_module_assignment embeddedsw.memoryInfo.DAT_SYM_INSTALL_DIR {SIM_DIR}
|
||||
#set_module_assignment embeddedsw.memoryInfo.FLASH_INSTALL_DIR {APP_DIR}
|
||||
set_module_assignment embeddedsw.memoryInfo.HEX_INSTALL_DIR {QPF_DIR}
|
||||
|
||||
# Module assignments related to names of simulation files
|
||||
#set_module_assignment postgeneration.simulation.init_file.param_name {INIT_FILENAME}
|
||||
#set_module_assignment postgeneration.simulation.init_file.type {MEM_INIT}
|
||||
|
||||
# +-------------------------------------
|
||||
# | Add settings needed by DTG tools
|
||||
# +-------------------------------------
|
||||
# add device tree properties
|
||||
set_module_assignment embeddedsw.dts.vendor "altr"
|
||||
set_module_assignment embeddedsw.dts.name "epcq"
|
||||
set_module_assignment embeddedsw.dts.group "epcq"
|
||||
set_module_assignment embeddedsw.dts.compatible "altr,epcq-1.0"
|
||||
|
||||
## Add documentation links for user guide and/or release notes
|
||||
add_documentation_link "User Guide" https://documentation.altera.com/#/link/sfo1400787952932/iga1431459459085
|
||||
add_documentation_link "Release Notes" https://documentation.altera.com/#/link/hco1421698042087/hco1421697689300
|
|
@ -0,0 +1,260 @@
|
|||
/******************************************************************************
|
||||
* *
|
||||
* License Agreement *
|
||||
* *
|
||||
* Copyright (c) 2014 Altera Corporation, San Jose, California, USA. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
* copy of this software and associated documentation files (the "Software"), *
|
||||
* to deal in the Software without restriction, including without limitation *
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
|
||||
* and/or sell copies of the Software, and to permit persons to whom the *
|
||||
* Software is furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in *
|
||||
* all copies or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
|
||||
* DEALINGS IN THE SOFTWARE. *
|
||||
* *
|
||||
* This agreement shall be governed in all respects by the laws of the State *
|
||||
* of California and by the laws of the United States of America. *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __ALTERA_EPCQ_CONTROLLER_REGS_H__
|
||||
#define __ALTERA_EPCQ_CONTROLLER_REGS_H__
|
||||
|
||||
#include <io.h>
|
||||
|
||||
/*
|
||||
* EPCQ_RD_STATUS register offset
|
||||
*
|
||||
* The EPCQ_RD_STATUS register contains information from the read status
|
||||
* register operation. A full description of the register can be found in the
|
||||
* data sheet,
|
||||
*
|
||||
*/
|
||||
#define ALTERA_EPCQ_CONTROLLER_STATUS_REG (0x0)
|
||||
|
||||
/*
|
||||
* EPCQ_RD_STATUS register access macros
|
||||
*/
|
||||
#define IOADDR_ALTERA_EPCQ_CONTROLLER_STATUS(base) \
|
||||
__IO_CALC_ADDRESS_DYNAMIC(base, ALTERA_EPCQ_CONTROLLER_STATUS_REG)
|
||||
|
||||
#define IORD_ALTERA_EPCQ_CONTROLLER_STATUS(base) \
|
||||
IORD_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_STATUS_REG)
|
||||
|
||||
#define IOWR_ALTERA_EPCQ_CONTROLLER_STATUS(base, data) \
|
||||
IOWR_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_STATUS_REG, data)
|
||||
|
||||
/*
|
||||
* EPCQ_RD_STATUS register description macros
|
||||
*/
|
||||
|
||||
/** Write in progress bit */
|
||||
#define ALTERA_EPCQ_CONTROLLER_STATUS_WIP_MASK (0x00000001)
|
||||
#define ALTERA_EPCQ_CONTROLLER_STATUS_WIP_AVAILABLE (0x00000000)
|
||||
#define ALTERA_EPCQ_CONTROLLER_STATUS_WIP_BUSY (0x00000001)
|
||||
/** When to time out a poll of the write in progress bit */
|
||||
/* 0.7 sec time out */
|
||||
#define ALTERA_EPCQ_CONTROLLER_1US_TIMEOUT_VALUE 700000
|
||||
|
||||
/*
|
||||
* EPCQ_RD_SID register offset
|
||||
*
|
||||
* The EPCQ_RD_SID register contains the information from the read silicon ID
|
||||
* operation and can be used to determine what type of EPCS device we have.
|
||||
* Only support in EPCS16 and EPCS64.
|
||||
*
|
||||
* This register is valid only if the device is an EPCS.
|
||||
*
|
||||
*/
|
||||
#define ALTERA_EPCQ_CONTROLLER_SID_REG (0x4)
|
||||
|
||||
/*
|
||||
* EPCQ_RD_SID register access macros
|
||||
*/
|
||||
#define IOADDR_ALTERA_EPCQ_CONTROLLER_SID(base) \
|
||||
__IO_CALC_ADDRESS_DYNAMIC(base, ALTERA_EPCQ_CONTROLLER_SID_REG)
|
||||
|
||||
#define IORD_ALTERA_EPCQ_CONTROLLER_SID(base) \
|
||||
IORD_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_SID_REG)
|
||||
|
||||
#define IOWR_ALTERA_EPCQ_CONTROLLER_SID(base, data) \
|
||||
IOWR_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_SID_REG, data)
|
||||
|
||||
/*
|
||||
* EPCQ_RD_SID register description macros
|
||||
*
|
||||
* Specific device values obtained from Table 14 of:
|
||||
* "Serial Configuration (EPCS) Devices Datasheet"
|
||||
*/
|
||||
#define ALTERA_EPCQ_CONTROLLER_SID_MASK (0x000000FF)
|
||||
#define ALTERA_EPCQ_CONTROLLER_SID_EPCS16 (0x00000014)
|
||||
#define ALTERA_EPCQ_CONTROLLER_SID_EPCS64 (0x00000016)
|
||||
#define ALTERA_EPCQ_CONTROLLER_SID_EPCS128 (0x00000018)
|
||||
|
||||
/*
|
||||
* EPCQ_RD_RDID register offset
|
||||
*
|
||||
* The EPCQ_RD_RDID register contains the information from the read memory
|
||||
* capacity operation and can be used to determine what type of EPCQ device
|
||||
* we have.
|
||||
*
|
||||
* This register is only valid if the device is an EPCQ.
|
||||
*
|
||||
*/
|
||||
#define ALTERA_EPCQ_CONTROLLER_RDID_REG (0x8)
|
||||
|
||||
/*
|
||||
* EPCQ_RD_RDID register access macros
|
||||
*/
|
||||
#define IOADDR_ALTERA_EPCQ_CONTROLLER_RDID(base) \
|
||||
__IO_CALC_ADDRESS_DYNAMIC(base, ALTERA_EPCQ_CONTROLLER_RDID_REG)
|
||||
|
||||
#define IORD_ALTERA_EPCQ_CONTROLLER_RDID(base) \
|
||||
IORD_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_RDID_REG)
|
||||
|
||||
#define IOWR_ALTERA_EPCQ_CONTROLLER_RDID(base, data) \
|
||||
IOWR_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_RDID_REG, data)
|
||||
|
||||
/*
|
||||
* EPCQ_RD_RDID register description macros
|
||||
*
|
||||
* Specific device values obtained from Table 28 of:
|
||||
* "Quad-Serial Configuration (EPCQ (www.altera.com/literature/hb/cfg/cfg_cf52012.pdf))
|
||||
* Devices Datasheet"
|
||||
*/
|
||||
#define ALTERA_EPCQ_CONTROLLER_RDID_MASK (0x000000FF)
|
||||
#define ALTERA_EPCQ_CONTROLLER_RDID_EPCQ16 (0x00000015)
|
||||
#define ALTERA_EPCQ_CONTROLLER_RDID_EPCQ32 (0x00000016)
|
||||
#define ALTERA_EPCQ_CONTROLLER_RDID_EPCQ64 (0x00000017)
|
||||
#define ALTERA_EPCQ_CONTROLLER_RDID_EPCQ128 (0x00000018)
|
||||
#define ALTERA_EPCQ_CONTROLLER_RDID_EPCQ256 (0x00000019)
|
||||
#define ALTERA_EPCQ_CONTROLLER_RDID_EPCQ512 (0x00000020)
|
||||
#define ALTERA_EPCQ_CONTROLLER_RDID_EPCQ1024 (0x00000021)
|
||||
|
||||
/*
|
||||
* EPCQ_MEM_OP register offset
|
||||
*
|
||||
* The EPCQ_MEM_OP register is used to do memory protect and erase operations
|
||||
*
|
||||
*/
|
||||
#define ALTERA_EPCQ_CONTROLLER_MEM_OP_REG (0xC)
|
||||
|
||||
/*
|
||||
* EPCQ_MEM_OP register access macros
|
||||
*/
|
||||
#define IOADDR_ALTERA_EPCQ_CONTROLLER_MEM_OP(base) \
|
||||
__IO_CALC_ADDRESS_DYNAMIC(base, ALTERA_EPCQ_CONTROLLER_MEM_OP_REG)
|
||||
|
||||
#define IORD_ALTERA_EPCQ_CONTROLLER_MEM_OP(base) \
|
||||
IORD_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_MEM_OP_REG)
|
||||
|
||||
#define IOWR_ALTERA_EPCQ_CONTROLLER_MEM_OP(base, data) \
|
||||
IOWR_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_MEM_OP_REG, data)
|
||||
|
||||
/*
|
||||
* EPCQ_MEM_OP register description macros
|
||||
*/
|
||||
#define ALTERA_EPCQ_CONTROLLER_MEM_OP_CMD_MASK (0x00000003)
|
||||
#define ALTERA_EPCQ_CONTROLLER_MEM_OP_BULK_ERASE_CMD (0x00000001)
|
||||
#define ALTERA_EPCQ_CONTROLLER_MEM_OP_SECTOR_ERASE_CMD (0x00000002)
|
||||
#define ALTERA_EPCQ_CONTROLLER_MEM_OP_SECTOR_PROTECT_CMD (0x00000003)
|
||||
|
||||
/** see datasheet for sector values */
|
||||
#define ALTERA_EPCQ_CONTROLLER_MEM_OP_SECTOR_VALUE_MASK (0x00FFFF00)
|
||||
|
||||
/*
|
||||
* EPCQ_ISR register offset
|
||||
*
|
||||
* The EPCQ_ISR register is used to determine whether an invalid write or erase
|
||||
* operation triggered an interrupt
|
||||
*
|
||||
*/
|
||||
#define ALTERA_EPCQ_CONTROLLER_ISR_REG (0x10)
|
||||
|
||||
/*
|
||||
* EPCQ_ISR register access macros
|
||||
*/
|
||||
#define IOADDR_ALTERA_EPCQ_CONTROLLER_ISR(base) \
|
||||
__IO_CALC_ADDRESS_DYNAMIC(base, ALTERA_EPCQ_CONTROLLER_ISR_REG)
|
||||
|
||||
#define IORD_ALTERA_EPCQ_CONTROLLER_ISR(base) \
|
||||
IORD_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_ISR_REG)
|
||||
|
||||
#define IOWR_ALTERA_EPCQ_CONTROLLER_ISR(base, data) \
|
||||
IOWR_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_ISR_REG, data)
|
||||
|
||||
/*
|
||||
* EPCQ_ISR register description macros
|
||||
*/
|
||||
#define ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_ERASE_MASK (0x00000001)
|
||||
#define ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_ERASE_ACTIVE (0x00000001)
|
||||
|
||||
#define ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_WRITE_MASK (0x00000002)
|
||||
#define ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_WRITE_ACTIVE (0x00000002)
|
||||
|
||||
|
||||
/*
|
||||
* EPCQ_IMR register offset
|
||||
*
|
||||
* The EPCQ_IMR register is used to mask the invalid erase or the invalid write
|
||||
* interrupts.
|
||||
*
|
||||
*/
|
||||
#define ALTERA_EPCQ_CONTROLLER_IMR_REG (0x14)
|
||||
|
||||
/*
|
||||
* EPCQ_IMR register access macros
|
||||
*/
|
||||
#define IOADDR_ALTERA_EPCQ_CONTROLLER_IMR(base) \
|
||||
__IO_CALC_ADDRESS_DYNAMIC(base, ALTERA_EPCQ_CONTROLLER_IMR_REG)
|
||||
|
||||
#define IORD_ALTERA_EPCQ_CONTROLLER_IMR(base) \
|
||||
IORD_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_IMR_REG)
|
||||
|
||||
#define IOWR_ALTERA_EPCQ_CONTROLLER_IMR(base, data) \
|
||||
IOWR_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_IMR_REG, data)
|
||||
|
||||
/*
|
||||
* EPCQ_IMR register description macros
|
||||
*/
|
||||
#define ALTERA_EPCQ_CONTROLLER_IMR_ILLEGAL_ERASE_MASK (0x00000001)
|
||||
#define ALTERA_EPCQ_CONTROLLER_IMR_ILLEGAL_ERASE_ENABLED (0x00000001)
|
||||
|
||||
#define ALTERA_EPCQ_CONTROLLER_IMR_ILLEGAL_WRITE_MASK (0x00000002)
|
||||
#define ALTERA_EPCQ_CONTROLLER_IMR_ILLEGAL_WRITE_ENABLED (0x00000002)
|
||||
|
||||
/*
|
||||
* EPCQ_CHIP_SELECT register offset
|
||||
*
|
||||
* The EPCQ_CHIP_SELECT register is used to issue chip select
|
||||
*/
|
||||
#define ALTERA_EPCQ_CHIP_SELECT_REG (0x18)
|
||||
|
||||
/*
|
||||
* EPCQ_CHIP_SELECT register access macros
|
||||
*/
|
||||
#define IOADDR_ALTERA_EPCQ_CHIP_SELECT(base) \
|
||||
__IO_CALC_ADDRESS_DYNAMIC(base, ALTERA_EPCQ_CHIP_SELECT_REG)
|
||||
|
||||
#define IOWR_ALTERA_EPCQ_CHIP_SELECT(base, data) \
|
||||
IOWR_32DIRECT(base, ALTERA_EPCQ_CHIP_SELECT_REG, data)
|
||||
|
||||
/*
|
||||
* EPCQ_CHIP_SELECT register description macros
|
||||
*/
|
||||
#define ALTERA_EPCQ_CHIP1_SELECT (0x00000001)
|
||||
#define ALTERA_EPCQ_CHIP2_SELECT (0x00000002)
|
||||
#define ALTERA_EPCQ_CHIP3_SELECT (0x00000003)
|
||||
|
||||
#endif /* __ALTERA_EPCQ_CONTROLLER_REGS_H__ */
|
|
@ -0,0 +1,56 @@
|
|||
// (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
// Your use of Altera Corporation's design tools, logic functions and other
|
||||
// software and tools, and its AMPP partner logic functions, and any output
|
||||
// files any of the foregoing (including device programming or simulation
|
||||
// files), and any associated documentation or information are expressly subject
|
||||
// to the terms and conditions of the Altera Program License Subscription
|
||||
// Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
// license agreement, including, without limitation, that your use is for the
|
||||
// sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
// Altera or its authorized distributors. Please refer to the applicable
|
||||
// agreement for further details.
|
||||
|
||||
|
||||
//Legal Notice: (C)2010 Altera Corporation. All rights reserved. Your
|
||||
//use of Altera Corporation's design tools, logic functions and other
|
||||
//software and tools, and its AMPP partner logic functions, and any
|
||||
//output files any of the foregoing (including device programming or
|
||||
//simulation files), and any associated documentation or information are
|
||||
//expressly subject to the terms and conditions of the Altera Program
|
||||
//License Subscription Agreement or other applicable license agreement,
|
||||
//including, without limitation, that your use is for the sole purpose
|
||||
//of programming logic devices manufactured by Altera and sold by Altera
|
||||
//or its authorized distributors. Please refer to the applicable
|
||||
//agreement for further details.
|
||||
|
||||
// synthesis translate_off
|
||||
`timescale 1ns / 1ps
|
||||
// synthesis translate_on
|
||||
|
||||
// turn off superfluous verilog processor warnings
|
||||
// altera message_level Level1
|
||||
// altera message_off 10034 10035 10036 10037 10230 10240 10030
|
||||
|
||||
module endianconverter_qsys (
|
||||
// inputs:
|
||||
dataa,
|
||||
datab,
|
||||
|
||||
// outputs:
|
||||
result
|
||||
)
|
||||
;
|
||||
|
||||
output [ 31: 0] result;
|
||||
input [ 31: 0] dataa;
|
||||
input [ 31: 0] datab;
|
||||
|
||||
wire [ 31: 0] result;
|
||||
//s1, which is an e_custom_instruction_slave
|
||||
assign result[7 : 0] = dataa[31 : 24];
|
||||
assign result[15 : 8] = dataa[23 : 16];
|
||||
assign result[23 : 16] = dataa[15 : 8];
|
||||
assign result[31 : 24] = dataa[7 : 0];
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
# (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
# Your use of Altera Corporation's design tools, logic functions and other
|
||||
# software and tools, and its AMPP partner logic functions, and any output
|
||||
# files any of the foregoing (including device programming or simulation
|
||||
# files), and any associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License Subscription
|
||||
# Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
# license agreement, including, without limitation, that your use is for the
|
||||
# sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
# Altera or its authorized distributors. Please refer to the applicable
|
||||
# agreement for further details.
|
||||
|
||||
|
||||
# TCL File Generated by Component Editor 10.1
|
||||
# Tue Aug 17 15:04:48 MYT 2010
|
||||
# DO NOT MODIFY
|
||||
|
||||
|
||||
# +-----------------------------------
|
||||
# |
|
||||
# |
|
||||
# | ./converter_0.v syn, sim
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
# +-----------------------------------
|
||||
# | request TCL package from ACDS 10.1
|
||||
# |
|
||||
package require -exact sopc 10.1
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
# +-----------------------------------
|
||||
# | module altera_nios_custom_instr_endian_converter
|
||||
# |
|
||||
set_module_property NAME altera_nios_custom_instr_endianconverter
|
||||
set_module_property VERSION "__VERSION_SHORT__"
|
||||
set_module_property INTERNAL false
|
||||
set_module_property GROUP "Custom Instruction Modules"
|
||||
set_module_property AUTHOR "Altera Corporation"
|
||||
set_module_property DISPLAY_NAME "Endian Converter"
|
||||
set_module_property HIDE_FROM_SOPC true
|
||||
set_module_property TOP_LEVEL_HDL_FILE endianconverter_qsys.v
|
||||
set_module_property TOP_LEVEL_HDL_MODULE endianconverter_qsys
|
||||
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
|
||||
set_module_property SIMULATION_MODEL_IN_VHDL true
|
||||
set_module_property EDITABLE false
|
||||
set_module_property ANALYZE_HDL FALSE
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
# +-----------------------------------
|
||||
# | files
|
||||
# |
|
||||
add_file endianconverter_qsys.v {SYNTHESIS SIMULATION}
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
# +-----------------------------------
|
||||
# | parameters
|
||||
# |
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
# +-----------------------------------
|
||||
# | display items
|
||||
# |
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
# +-----------------------------------
|
||||
# | connection point s1
|
||||
# |
|
||||
add_interface s1 nios_custom_instruction end
|
||||
set_interface_property s1 clockCycle 1
|
||||
set_interface_property s1 operands 1
|
||||
|
||||
set_interface_property s1 ENABLED true
|
||||
|
||||
add_interface_port s1 dataa dataa Input 32
|
||||
add_interface_port s1 datab datab Input 32
|
||||
add_interface_port s1 result result Output 32
|
||||
# |
|
||||
# +-----------------------------------
|
|
@ -0,0 +1,159 @@
|
|||
# (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
# Your use of Altera Corporation's design tools, logic functions and other
|
||||
# software and tools, and its AMPP partner logic functions, and any output
|
||||
# files any of the foregoing (including device programming or simulation
|
||||
# files), and any associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License Subscription
|
||||
# Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
# license agreement, including, without limitation, that your use is for the
|
||||
# sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
# Altera or its authorized distributors. Please refer to the applicable
|
||||
# agreement for further details.
|
||||
|
||||
|
||||
# TCL File Generated by Component Editor 8.0
|
||||
# Mon Dec 22 17:22:07 EST 2008
|
||||
# DO NOT MODIFY
|
||||
|
||||
set aup_version 15.1
|
||||
|
||||
|
||||
|
||||
# +-----------------------------------
|
||||
# |
|
||||
# | Altera_UP_SD_Card_Avalon_Interface "Altera_UP_SD_Card_Avalon_Interface" v1.0
|
||||
# | null 2008.12.22.17:22:07
|
||||
# | A module that allows communication with an SD Card
|
||||
# |
|
||||
# | ./hdl/Altera_UP_SD_Card_Avalon_Interface.vhd syn
|
||||
# | ./hdl/Altera_UP_SD_Card_48_bit_Command_Generator.vhd syn
|
||||
# | ./hdl/Altera_UP_SD_Card_Buffer.vhd syn
|
||||
# | ./hdl/Altera_UP_SD_Card_Clock.vhd syn
|
||||
# | ./hdl/Altera_UP_SD_Card_Control_FSM.vhd syn
|
||||
# | ./hdl/Altera_UP_SD_Card_Interface.vhd syn
|
||||
# | ./hdl/Altera_UP_SD_Card_Memory_Block.qip syn
|
||||
# | ./hdl/Altera_UP_SD_Card_Response_Receiver.vhd syn
|
||||
# | ./hdl/Altera_UP_SD_CRC16_Generator.vhd syn
|
||||
# | ./hdl/Altera_UP_SD_CRC7_Generator.vhd syn
|
||||
# | ./hdl/Altera_UP_SD_Signal_Trigger.vhd syn
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
|
||||
# +-----------------------------------
|
||||
# | module Altera_UP_SD_Card_Avalon_Interface
|
||||
# |
|
||||
set_module_property DESCRIPTION "A module that allows communication with an SD Card"
|
||||
set_module_property NAME Altera_UP_SD_Card_Avalon_Interface_mod
|
||||
set_module_property VERSION $aup_version
|
||||
set_module_property GROUP "Memory"
|
||||
set_module_property DISPLAY_NAME "SD Card Interface"
|
||||
set_module_property DATASHEET_URL "[pwd]/doc/SD_Card_Interface_for_SoPC_Builder.pdf"
|
||||
set_module_property LIBRARIES {ieee.std_logic_1164.all ieee.std_logic_arith.all ieee.std_logic_unsigned.all std.standard.all}
|
||||
set_module_property TOP_LEVEL_HDL_FILE "hdl/Altera_UP_SD_Card_Avalon_Interface.vhd"
|
||||
set_module_property TOP_LEVEL_HDL_MODULE Altera_UP_SD_Card_Avalon_Interface
|
||||
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
|
||||
set_module_property EDITABLE false
|
||||
#set_module_property ANALYZE_HDL false
|
||||
set_module_property SIMULATION_MODEL_IN_VERILOG false
|
||||
set_module_property SIMULATION_MODEL_IN_VHDL false
|
||||
set_module_property SIMULATION_MODEL_HAS_TULIPS false
|
||||
set_module_property SIMULATION_MODEL_IS_OBFUSCATED false
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
# +-----------------------------------
|
||||
# | files
|
||||
# |
|
||||
add_file hdl/Altera_UP_SD_Card_Avalon_Interface.vhd {SYNTHESIS}
|
||||
add_file hdl/Altera_UP_SD_Card_48_bit_Command_Generator.vhd {SYNTHESIS}
|
||||
add_file hdl/Altera_UP_SD_Card_Buffer.vhd {SYNTHESIS}
|
||||
add_file hdl/Altera_UP_SD_Card_Clock.vhd {SYNTHESIS}
|
||||
add_file hdl/Altera_UP_SD_Card_Control_FSM.vhd {SYNTHESIS}
|
||||
add_file hdl/Altera_UP_SD_Card_Interface.vhd {SYNTHESIS}
|
||||
add_file hdl/Altera_UP_SD_Card_Response_Receiver.vhd {SYNTHESIS}
|
||||
add_file hdl/Altera_UP_SD_CRC16_Generator.vhd {SYNTHESIS}
|
||||
add_file hdl/Altera_UP_SD_CRC7_Generator.vhd {SYNTHESIS}
|
||||
add_file hdl/Altera_UP_SD_Signal_Trigger.vhd {SYNTHESIS}
|
||||
add_file hdl/Altera_UP_SD_Card_Memory_Block.vhd {SYNTHESIS}
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
# +-----------------------------------
|
||||
# | parameters
|
||||
# |
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
# +-----------------------------------
|
||||
# | connection point avalon_sdcard_slave
|
||||
# |
|
||||
add_interface avalon_sdcard_slave avalon end
|
||||
set_interface_property avalon_sdcard_slave holdTime 0
|
||||
set_interface_property avalon_sdcard_slave linewrapBursts false
|
||||
set_interface_property avalon_sdcard_slave minimumUninterruptedRunLength 1
|
||||
set_interface_property avalon_sdcard_slave bridgesToMaster ""
|
||||
set_interface_property avalon_sdcard_slave isMemoryDevice false
|
||||
set_interface_property avalon_sdcard_slave burstOnBurstBoundariesOnly false
|
||||
set_interface_property avalon_sdcard_slave addressSpan 1024
|
||||
set_interface_property avalon_sdcard_slave timingUnits Cycles
|
||||
set_interface_property avalon_sdcard_slave setupTime 0
|
||||
set_interface_property avalon_sdcard_slave writeWaitTime 0
|
||||
set_interface_property avalon_sdcard_slave isNonVolatileStorage false
|
||||
set_interface_property avalon_sdcard_slave addressAlignment DYNAMIC
|
||||
set_interface_property avalon_sdcard_slave maximumPendingReadTransactions 0
|
||||
set_interface_property avalon_sdcard_slave readWaitTime 1
|
||||
set_interface_property avalon_sdcard_slave readLatency 0
|
||||
set_interface_property avalon_sdcard_slave printableDevice false
|
||||
|
||||
set_interface_property avalon_sdcard_slave associatedClock clk
|
||||
set_interface_property avalon_sdcard_slave associatedReset reset
|
||||
|
||||
add_interface_port avalon_sdcard_slave i_avalon_chip_select chipselect Input 1
|
||||
add_interface_port avalon_sdcard_slave i_avalon_address address Input 8
|
||||
add_interface_port avalon_sdcard_slave i_avalon_read read Input 1
|
||||
add_interface_port avalon_sdcard_slave i_avalon_write write Input 1
|
||||
add_interface_port avalon_sdcard_slave i_avalon_byteenable byteenable Input 4
|
||||
add_interface_port avalon_sdcard_slave i_avalon_writedata writedata Input 32
|
||||
add_interface_port avalon_sdcard_slave o_avalon_readdata readdata Output 32
|
||||
add_interface_port avalon_sdcard_slave o_avalon_waitrequest waitrequest Output 1
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
# +-----------------------------------
|
||||
# | connection point clk
|
||||
# |
|
||||
add_interface clk clock end
|
||||
set_interface_property clk enabled true
|
||||
|
||||
add_interface_port clk i_clock clk Input 1
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
# +-----------------------------------
|
||||
# | connection point reset
|
||||
# |
|
||||
add_interface reset reset end
|
||||
set_interface_property reset associatedClock clk
|
||||
set_interface_property reset enabled true
|
||||
set_interface_property reset synchronousEdges DEASSERT
|
||||
|
||||
add_interface_port reset i_reset_n reset_n Input 1
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
# +-----------------------------------
|
||||
# | connection point conduit_end
|
||||
# |
|
||||
add_interface conduit_end conduit end
|
||||
|
||||
add_interface_port conduit_end b_SD_cmd export Bidir 1
|
||||
add_interface_port conduit_end b_SD_dat export Bidir 1
|
||||
add_interface_port conduit_end b_SD_dat3 export Bidir 1
|
||||
add_interface_port conduit_end o_SD_clock export Output 1
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
## Add documentation links for user guide and/or release notes
|
||||
add_documentation_link "User Guide" file:///ip/altera/university_program/memory/altera_up_sd_card_avalon_interface/doc/SD_Card_Interface_for_SoPC_Builder.pdf
|
||||
add_documentation_link "Release Notes" https://documentation.altera.com/#/link/hco1421698042087/hco1421698013408
|
|
@ -0,0 +1,56 @@
|
|||
# (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
# Your use of Altera Corporation's design tools, logic functions and other
|
||||
# software and tools, and its AMPP partner logic functions, and any output
|
||||
# files any of the foregoing (including device programming or simulation
|
||||
# files), and any associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License Subscription
|
||||
# Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
# license agreement, including, without limitation, that your use is for the
|
||||
# sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
# Altera or its authorized distributors. Please refer to the applicable
|
||||
# agreement for further details.
|
||||
|
||||
|
||||
# TCL File Generated by Altera University Program
|
||||
# DO NOT MODIFY
|
||||
|
||||
set aup_version 15.1
|
||||
|
||||
# Create a new driver - this name must be different than the
|
||||
# hardware component name
|
||||
create_driver Altera_UP_SD_Card_Avalon_Interface_mod_driver
|
||||
|
||||
# Associate it with some hardware
|
||||
set_sw_property hw_class_name Altera_UP_SD_Card_Avalon_Interface_mod
|
||||
|
||||
# The version of this driver
|
||||
set_sw_property version $aup_version
|
||||
|
||||
# This driver is proclaimed to be compatible with 'component'
|
||||
# as old as version "1.0". The component hardware version is set in the
|
||||
# _hw.tcl file - If the hardware component version number is not equal
|
||||
# or greater than the min_compatable_hw_version number, the driver
|
||||
# source files will not be copied over to the BSP driver directory
|
||||
set_sw_property min_compatible_hw_version 15.1
|
||||
|
||||
# Initialize the driver in alt_sys_init()
|
||||
set_sw_property auto_initialize true
|
||||
|
||||
# Location in generated BSP that sources will be copied into
|
||||
set_sw_property bsp_subdirectory drivers
|
||||
|
||||
#
|
||||
# Source file listings...
|
||||
#
|
||||
|
||||
# C/C++ source files
|
||||
add_sw_property c_source HAL/src/Altera_UP_SD_Card_Avalon_Interface_mod.c
|
||||
|
||||
# Include files
|
||||
add_sw_property include_source HAL/inc/Altera_UP_SD_Card_Avalon_Interface_mod.h
|
||||
|
||||
# This driver supports HAL type
|
||||
add_sw_property supported_bsp_type HAL
|
||||
|
||||
# End of file
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
#ifndef __ALTERA_UP_SD_CARD_AVALON_INTERFACE_H__
|
||||
#define __ALTERA_UP_SD_CARD_AVALON_INTERFACE_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <alt_types.h>
|
||||
#include <sys/alt_dev.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define SD_RAW_IFACE
|
||||
|
||||
/*
|
||||
* Device structure definition. Each instance of the driver uses one
|
||||
* of these structures to hold its associated state.
|
||||
*/
|
||||
typedef struct alt_up_sd_card_dev {
|
||||
/// @brief character mode device structure
|
||||
/// @sa Developing Device Drivers for the HAL in Nios II Software Developer's Handbook
|
||||
alt_dev dev;
|
||||
/// @brief the base address of the device
|
||||
unsigned int base;
|
||||
|
||||
} alt_up_sd_card_dev;
|
||||
|
||||
#ifndef bool
|
||||
typedef enum e_bool { false = 0, true = 1 } bool;
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// HAL system functions
|
||||
|
||||
alt_up_sd_card_dev* alt_up_sd_card_open_dev(const char *name);
|
||||
/* Open an SD Card Interface if it is connected to the system. */
|
||||
|
||||
|
||||
bool alt_up_sd_card_is_Present(void);
|
||||
/* Check if there is an SD Card insterted into the SD Card socket.
|
||||
*/
|
||||
|
||||
#ifndef SD_RAW_IFACE
|
||||
bool alt_up_sd_card_is_FAT16(void);
|
||||
/* This function reads the SD card data in an effort to determine if the card is formated as a FAT16
|
||||
* volume. Please note that FAT12 has a similar format, but will not be supported by this driver.
|
||||
*/
|
||||
|
||||
|
||||
short int alt_up_sd_card_fopen(char *name, bool create);
|
||||
/* This function reads the SD card data in an effort to determine if the card is formated as a FAT16
|
||||
* volume. Please note that FAT12 has a similar format, but will not be supported by this driver.
|
||||
*
|
||||
* Inputs:
|
||||
* name - a file name including a directory, relative to the root directory
|
||||
* create - a flag set to true to create a file if it does not already exist
|
||||
* Output:
|
||||
* An index to the file record assigned to the specified file. -1 is returned if the file could not be opened.
|
||||
*/
|
||||
|
||||
|
||||
short int alt_up_sd_card_find_first(char *directory_to_search_through, char *file_name);
|
||||
/* This function sets up a search algorithm to go through a given directory looking for files.
|
||||
* If the search directory is valid, then the function searches for the first file it finds.
|
||||
* Inputs:
|
||||
* directory_to_search_through - name of the directory to search through
|
||||
* file_name - an array to store a name of the file found. Must be 13 bytes long (12 bytes for file name and 1 byte of NULL termination).
|
||||
* Outputs:
|
||||
* 0 - success
|
||||
* 1 - invalid directory
|
||||
* 2 - No card or incorrect card format.
|
||||
*
|
||||
* To specify a directory give the name in a format consistent with the following regular expression:
|
||||
* [{[valid_chars]+}/]*.
|
||||
*
|
||||
* In other words, give a path name starting at the root directory, where each directory name is followed by a '/'.
|
||||
* Then, append a '.' to the directory name. Examples:
|
||||
* "." - look through the root directory
|
||||
* "first/." - look through a directory named "first" that is located in the root directory.
|
||||
* "first/sub/." - look through a directory named "sub", that is located within the subdirectory named "first". "first" is located in the root directory.
|
||||
* Invalid examples include:
|
||||
* "/.", "/////." - this is not the root directory.
|
||||
* "/first/." - the first character may not be a '/'.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
short int alt_up_sd_card_find_next(char *file_name);
|
||||
/* This function searches for the next file in a given directory, as specified by the find_first function.
|
||||
* Inputs:
|
||||
* file_name - an array to store a name of the file found. Must be 13 bytes long (12 bytes for file name and 1 byte of NULL termination).
|
||||
* Outputs:
|
||||
* -1 - end of directory.
|
||||
* 0 - success
|
||||
* 2 - No card or incorrect card format.
|
||||
* 4 - find_first has not been called successfully.
|
||||
*/
|
||||
|
||||
void alt_up_sd_card_set_attributes(short int file_handle, short int attributes);
|
||||
/* Set file attributes as needed.
|
||||
*/
|
||||
|
||||
short int alt_up_sd_card_get_attributes(short int file_handle);
|
||||
/* Return file attributes, or -1 if the file_handle is invalid.
|
||||
*/
|
||||
|
||||
|
||||
short int alt_up_sd_card_read(short int file_handle);
|
||||
/* Read a single character from the given file. Return -1 if at the end of a file. Any other negative number
|
||||
* means that the file could not be read. A number between 0 and 255 is an ASCII character read from the SD Card. */
|
||||
|
||||
|
||||
bool alt_up_sd_card_write(short int file_handle, char byte_of_data);
|
||||
/* Write a single character to a given file. Return true if successful, and false otherwise. */
|
||||
|
||||
|
||||
bool alt_up_sd_card_fclose(short int file_handle);
|
||||
// This function closes an opened file and saves data to SD Card if necessary.
|
||||
|
||||
#else
|
||||
bool Write_Sector_Data(int sector_index, int partition_offset);
|
||||
bool Save_Modified_Sector();
|
||||
bool Read_Sector_Data(int sector_index, int partition_offset);
|
||||
#endif //SD_RAW_IFACE
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// file-like operation functions
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// direct operation functions
|
||||
|
||||
|
||||
/*
|
||||
* Macros used by alt_sys_init
|
||||
*/
|
||||
#define ALTERA_UP_SD_CARD_AVALON_INTERFACE_MOD_INSTANCE(name, device) \
|
||||
static alt_up_sd_card_dev device = \
|
||||
{ \
|
||||
{ \
|
||||
ALT_LLIST_ENTRY, \
|
||||
name##_NAME, \
|
||||
NULL , /* open */ \
|
||||
NULL , /* close */ \
|
||||
NULL, /* read */ \
|
||||
NULL, /* write */ \
|
||||
NULL , /* lseek */ \
|
||||
NULL , /* fstat */ \
|
||||
NULL , /* ioctl */ \
|
||||
}, \
|
||||
name##_BASE, \
|
||||
}
|
||||
|
||||
#define ALTERA_UP_SD_CARD_AVALON_INTERFACE_MOD_INIT(name, device) \
|
||||
{ \
|
||||
alt_dev_reg(&device.dev); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __ALTERA_UP_SD_CARD_AVALON_INTERFACE_H__ */
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -0,0 +1,79 @@
|
|||
-- (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
-- Your use of Altera Corporation's design tools, logic functions and other
|
||||
-- software and tools, and its AMPP partner logic functions, and any output
|
||||
-- files any of the foregoing (including device programming or simulation
|
||||
-- files), and any associated documentation or information are expressly subject
|
||||
-- to the terms and conditions of the Altera Program License Subscription
|
||||
-- Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
-- license agreement, including, without limitation, that your use is for the
|
||||
-- sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
-- Altera or its authorized distributors. Please refer to the applicable
|
||||
-- agreement for further details.
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
-- This generates the necessary 16-CRC for Command and Response
|
||||
-- Implementation: serial input/parallel output
|
||||
-- When input stream ends, the crcout output is the CRC checksum for them
|
||||
--
|
||||
-- NOTES/REVISIONS:
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity Altera_UP_SD_CRC16_Generator is
|
||||
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_enable : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
i_sync_reset : in std_logic;
|
||||
i_shift : in std_logic;
|
||||
i_datain : in std_logic;
|
||||
o_dataout : out std_logic;
|
||||
o_crcout : out std_logic_vector(15 downto 0)
|
||||
);
|
||||
|
||||
end entity;
|
||||
|
||||
architecture rtl of Altera_UP_SD_CRC16_Generator is
|
||||
|
||||
-- Local wires
|
||||
-- REGISTERED
|
||||
signal shift_register : std_logic_vector(15 downto 0);
|
||||
begin
|
||||
|
||||
process (i_clock, i_reset_n)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
shift_register <= (OTHERS => '0');
|
||||
else
|
||||
if (rising_edge(i_clock)) then
|
||||
if (i_sync_reset = '1') then
|
||||
shift_register <= (OTHERS => '0');
|
||||
elsif (i_enable = '1') then
|
||||
if (i_shift = '0') then
|
||||
shift_register(0) <= i_datain XOR shift_register(15);
|
||||
shift_register(4 downto 1) <= shift_register(3 downto 0);
|
||||
shift_register(5) <= shift_register(4) XOR i_datain XOR shift_register(15);
|
||||
shift_register(11 downto 6) <= shift_register(10 downto 5);
|
||||
shift_register(12) <= shift_register(11) XOR i_datain XOR shift_register(15);
|
||||
shift_register(15 downto 13) <= shift_register(14 downto 12);
|
||||
else -- shift CRC out (no more calculation now)
|
||||
shift_register(15 downto 1) <= shift_register(14 downto 0);
|
||||
shift_register(0) <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
o_dataout <= shift_register(15);
|
||||
o_crcout <= shift_register;
|
||||
end rtl;
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
-- (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
-- Your use of Altera Corporation's design tools, logic functions and other
|
||||
-- software and tools, and its AMPP partner logic functions, and any output
|
||||
-- files any of the foregoing (including device programming or simulation
|
||||
-- files), and any associated documentation or information are expressly subject
|
||||
-- to the terms and conditions of the Altera Program License Subscription
|
||||
-- Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
-- license agreement, including, without limitation, that your use is for the
|
||||
-- sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
-- Altera or its authorized distributors. Please refer to the applicable
|
||||
-- agreement for further details.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------------------
|
||||
-- This generates the necessary 7-CRC for Command and Response
|
||||
-- Implementation: serial input/parallel output
|
||||
--
|
||||
-- When input stream ends, the crcout output is the CRC checksum for the input stream.
|
||||
--
|
||||
-- NOTES/REVISIONS:
|
||||
---------------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity Altera_UP_SD_CRC7_Generator is
|
||||
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_enable : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
i_shift : in std_logic;
|
||||
i_datain : in std_logic;
|
||||
o_dataout : out std_logic;
|
||||
o_crcout : out std_logic_vector(6 downto 0)
|
||||
);
|
||||
|
||||
end entity;
|
||||
|
||||
architecture rtl of Altera_UP_SD_CRC7_Generator is
|
||||
|
||||
-- Local wires
|
||||
-- REGISTERED
|
||||
signal shift_register : std_logic_vector(6 downto 0);
|
||||
begin
|
||||
|
||||
process (i_clock, i_reset_n)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
shift_register <= (OTHERS => '0');
|
||||
else
|
||||
if (rising_edge(i_clock)) then
|
||||
if (i_enable = '1') then
|
||||
if (i_shift = '0') then
|
||||
shift_register(0) <= i_datain XOR shift_register(6);
|
||||
shift_register(1) <= shift_register(0);
|
||||
shift_register(2) <= shift_register(1);
|
||||
shift_register(3) <= shift_register(2) XOR i_datain XOR shift_register(6);
|
||||
shift_register(4) <= shift_register(3);
|
||||
shift_register(5) <= shift_register(4);
|
||||
shift_register(6) <= shift_register(5);
|
||||
else -- shift CRC out (no more calculation now)
|
||||
shift_register(0) <= '0';
|
||||
shift_register(6 downto 1) <= shift_register(5 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
o_dataout <= shift_register(6);
|
||||
o_crcout <= shift_register;
|
||||
end rtl;
|
||||
|
|
@ -0,0 +1,570 @@
|
|||
-- (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
-- Your use of Altera Corporation's design tools, logic functions and other
|
||||
-- software and tools, and its AMPP partner logic functions, and any output
|
||||
-- files any of the foregoing (including device programming or simulation
|
||||
-- files), and any associated documentation or information are expressly subject
|
||||
-- to the terms and conditions of the Altera Program License Subscription
|
||||
-- Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
-- license agreement, including, without limitation, that your use is for the
|
||||
-- sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
-- Altera or its authorized distributors. Please refer to the applicable
|
||||
-- agreement for further details.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------
|
||||
-- This module takes a command ID and data, and generates a 48-bit message for it.
|
||||
-- It will first check if the command is a valid 48-bit command and produce the
|
||||
-- following outputs:
|
||||
-- 1. o_dataout -> a single bit output that produces the message to be sent to the
|
||||
-- SD card one bit at a time. Every time the i_message_bit_out input
|
||||
-- is high and the i_clock has a positive edge, a new bit is produced.
|
||||
-- 2. o_message_done -> a signal that is asserted high when the entire message has been
|
||||
-- produced through the o_dataout output.
|
||||
-- 3. o_valid -> is a signal that is asserted high if the specified message is valid.
|
||||
-- 4. o_response_type -> indicates the command response type.
|
||||
-- 5. o_returning_ocr -> the response from the SD card will contain the OCR register
|
||||
-- 6. o_returning_cid -> the response from the SD card will contain the CID register
|
||||
-- 7. o_returning_rca -> the response from the SD card will contain the RCA register
|
||||
-- 8. o_returning_csd -> the response from the SD card will contain the CSD register
|
||||
-- 9. o_data_read -> asserted when the command being sent is a data read command.
|
||||
-- 10. o_data_write -> asserted when the command being sent is a data write command.
|
||||
-- 11. o_wait_cmd_busy -> is set high when the response to this command will be
|
||||
-- followed by a busy signal.
|
||||
--
|
||||
-- NOTES/REVISIONS:
|
||||
-------------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity Altera_UP_SD_Card_48_bit_Command_Generator is
|
||||
generic (
|
||||
-- Basic commands
|
||||
COMMAND_0_GO_IDLE : STD_LOGIC_VECTOR(5 downto 0) := "000000";
|
||||
COMMAND_2_ALL_SEND_CID : STD_LOGIC_VECTOR(5 downto 0) := "000010";
|
||||
COMMAND_3_SEND_RCA : STD_LOGIC_VECTOR(5 downto 0) := "000011";
|
||||
COMMAND_4_SET_DSR : STD_LOGIC_VECTOR(5 downto 0) := "000100";
|
||||
COMMAND_6_SWITCH_FUNCTION : STD_LOGIC_VECTOR(5 downto 0) := "000110";
|
||||
COMMAND_7_SELECT_CARD : STD_LOGIC_VECTOR(5 downto 0) := "000111";
|
||||
COMMAND_9_SEND_CSD : STD_LOGIC_VECTOR(5 downto 0) := "001001";
|
||||
COMMAND_10_SEND_CID : STD_LOGIC_VECTOR(5 downto 0) := "001010";
|
||||
COMMAND_12_STOP_TRANSMISSION : STD_LOGIC_VECTOR(5 downto 0) := "001100";
|
||||
COMMAND_13_SEND_STATUS : STD_LOGIC_VECTOR(5 downto 0) := "001101";
|
||||
COMMAND_15_GO_INACTIVE : STD_LOGIC_VECTOR(5 downto 0) := "001111";
|
||||
-- Block oriented read/write/lock commands
|
||||
COMMAND_16_SET_BLOCK_LENGTH : STD_LOGIC_VECTOR(5 downto 0) := "010000";
|
||||
-- Block oriented read commands
|
||||
COMMAND_17_READ_BLOCK : STD_LOGIC_VECTOR(5 downto 0) := "010001";
|
||||
COMMAND_18_READ_MULTIPLE_BLOCKS : STD_LOGIC_VECTOR(5 downto 0) := "010010";
|
||||
-- Block oriented write commands
|
||||
COMMAND_24_WRITE_BLOCK : STD_LOGIC_VECTOR(5 downto 0) := "011000";
|
||||
COMMAND_25_WRITE_MULTIPLE_BLOCKS : STD_LOGIC_VECTOR(5 downto 0) := "011001";
|
||||
COMMAND_27_PROGRAM_CSD : STD_LOGIC_VECTOR(5 downto 0) := "011011";
|
||||
-- Block oriented write-protection commands
|
||||
COMMAND_28_SET_WRITE_PROTECT : STD_LOGIC_VECTOR(5 downto 0) := "011100";
|
||||
COMMAND_29_CLEAR_WRITE_PROTECT : STD_LOGIC_VECTOR(5 downto 0) := "011101";
|
||||
COMMAND_30_SEND_PROTECTED_GROUPS : STD_LOGIC_VECTOR(5 downto 0) := "011110";
|
||||
-- Erase commands
|
||||
COMMAND_32_ERASE_BLOCK_START : STD_LOGIC_VECTOR(5 downto 0) := "100000";
|
||||
COMMAND_33_ERASE_BLOCK_END : STD_LOGIC_VECTOR(5 downto 0) := "100001";
|
||||
COMMAND_38_ERASE_SELECTED_GROUPS: STD_LOGIC_VECTOR(5 downto 0) := "100110";
|
||||
-- Block lock commands
|
||||
COMMAND_42_LOCK_UNLOCK : STD_LOGIC_VECTOR(5 downto 0) := "101010";
|
||||
-- Command Type Settings
|
||||
COMMAND_55_APP_CMD : STD_LOGIC_VECTOR(5 downto 0) := "110111";
|
||||
COMMAND_56_GEN_CMD : STD_LOGIC_VECTOR(5 downto 0) := "111000";
|
||||
-- Application Specific commands - must be preceeded with command 55.
|
||||
ACOMMAND_6_SET_BUS_WIDTH : STD_LOGIC_VECTOR(5 downto 0) := "000110";
|
||||
ACOMMAND_13_SD_STATUS : STD_LOGIC_VECTOR(5 downto 0) := "001101";
|
||||
ACOMMAND_22_SEND_NUM_WR_BLOCKS : STD_LOGIC_VECTOR(5 downto 0) := "010100";
|
||||
ACOMMAND_23_SET_BLK_ERASE_COUNT : STD_LOGIC_VECTOR(5 downto 0) := "010101";
|
||||
ACOMMAND_41_SEND_OP_CONDITION : STD_LOGIC_VECTOR(5 downto 0) := "101001";
|
||||
ACOMMAND_42_SET_CLR_CARD_DETECT : STD_LOGIC_VECTOR(5 downto 0) := "101010";
|
||||
ACOMMAND_51_SEND_SCR : STD_LOGIC_VECTOR(5 downto 0) := "110011";
|
||||
-- First custom_command
|
||||
FIRST_NON_PREDEFINED_COMMAND : STD_LOGIC_VECTOR(3 downto 0) := "1010"
|
||||
);
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
i_message_bit_out : in std_logic;
|
||||
i_command_ID : in std_logic_vector(5 downto 0);
|
||||
i_argument : in std_logic_vector(31 downto 0);
|
||||
i_predefined_message : in std_logic_vector(3 downto 0);
|
||||
i_generate : in std_logic;
|
||||
i_DSR : in std_logic_vector(15 downto 0);
|
||||
i_OCR : in std_logic_vector(31 downto 0);
|
||||
i_RCA : in std_logic_vector(15 downto 0);
|
||||
o_dataout : out std_logic;
|
||||
o_message_done : out std_logic;
|
||||
o_valid : out std_logic;
|
||||
o_returning_ocr : out std_logic;
|
||||
o_returning_cid : out std_logic;
|
||||
o_returning_rca : out std_logic;
|
||||
o_returning_csd : out std_logic;
|
||||
o_returning_status : out std_logic;
|
||||
o_data_read : out std_logic;
|
||||
o_data_write : out std_logic;
|
||||
o_wait_cmd_busy : out std_logic;
|
||||
o_last_cmd_was_55 : out std_logic;
|
||||
o_response_type : out std_logic_vector(2 downto 0)
|
||||
);
|
||||
|
||||
end entity;
|
||||
|
||||
architecture rtl of Altera_UP_SD_Card_48_bit_Command_Generator is
|
||||
|
||||
component Altera_UP_SD_CRC7_Generator
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_enable : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
i_shift : in std_logic;
|
||||
i_datain : in std_logic;
|
||||
o_dataout : out std_logic;
|
||||
o_crcout : out std_logic_vector(6 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
-- Local wires
|
||||
-- REGISTERED
|
||||
signal counter : std_logic_vector(6 downto 0);
|
||||
signal last_command_id : std_logic_vector(5 downto 0);
|
||||
signal message_bits : std_logic_vector(39 downto 0);
|
||||
signal last_command_sent_was_CMD55, valid : std_logic;
|
||||
signal bit_to_send, sending_CRC, command_valid : std_logic;
|
||||
signal returning_cid_reg, returning_rca_reg, returning_csd_reg, returning_dsr_reg, returning_ocr_reg, returning_status_reg : std_logic;
|
||||
-- UNREGISTERED
|
||||
signal temp_4_bits : std_logic_vector(3 downto 0);
|
||||
signal message_done, CRC_generator_out, produce_next_bit : std_logic;
|
||||
signal app_specific_valid, regular_command_valid : std_logic;
|
||||
signal response_type, response_type_reg : std_logic_vector(2 downto 0);
|
||||
signal cmd_argument : std_logic_vector(31 downto 0);
|
||||
begin
|
||||
-- This set of bits is necessary to allow the SD card to accept a VDD level for communication.
|
||||
temp_4_bits <= "1111" when ((i_OCR(23) = '1') or (i_OCR(22) = '1') or (i_OCR(21) = '1') or (i_OCR(20) = '1')) else "0000";
|
||||
-- Generate the bits to be sent to the SD card. These bits must pass through the CRC generator
|
||||
-- to produce error checking code. The error checking code will follow the message. The message terminates with
|
||||
-- a logic '1'. Total message length is 48 bits.
|
||||
message_data_generator: process(i_clock, i_reset_n)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
message_bits <= (OTHERS => '0');
|
||||
else
|
||||
if (rising_edge(i_clock)) then
|
||||
if (i_generate = '1') then
|
||||
-- Store type of a response.
|
||||
response_type_reg <= response_type;
|
||||
-- Generate a message. Please note that the predefined messages are used for initialization.
|
||||
-- If executed in sequence, they will initialize the SD card to work correctly. Only once these
|
||||
-- instructions are completed can the data transfer begin.
|
||||
case (i_predefined_message) is
|
||||
when "0000" =>
|
||||
-- Generate a predefined message - CMD0.
|
||||
message_bits <= ("01" & COMMAND_0_GO_IDLE & "00000000000000000000000000000000");
|
||||
when "0001" =>
|
||||
-- Generate a predefined message - CMD55.
|
||||
message_bits <= ("01" & COMMAND_55_APP_CMD & "0000000000000000" & "0000000000000000");
|
||||
when "0010" =>
|
||||
-- Generate a predefined message - ACMD41.
|
||||
message_bits <= ("01" & ACOMMAND_41_SEND_OP_CONDITION & "0000" & temp_4_bits & "000" & i_OCR(20) & "00000000000000000000");
|
||||
when "0011" =>
|
||||
-- Generate a predefined message - CMD2.
|
||||
message_bits <= ("01" & COMMAND_2_ALL_SEND_CID & "00000000000000000000000000000000");
|
||||
when "0100" =>
|
||||
-- Generate a predefined message - CMD3.
|
||||
message_bits <= ("01" & COMMAND_3_SEND_RCA & "00000000000000000000000000000000");
|
||||
when "0101" =>
|
||||
-- Generate a predefined message - CMD9.
|
||||
message_bits <= ("01" & COMMAND_9_SEND_CSD & i_RCA & "0000000000000000");
|
||||
when "0110" =>
|
||||
-- Generate a predefined message - CMD4.
|
||||
message_bits <= ("01" & COMMAND_4_SET_DSR & i_DSR & "0000000000000000");
|
||||
when "0111" =>
|
||||
-- Generate a predefined message - CMD16. Set block length to 512.
|
||||
message_bits <= ("01" & COMMAND_16_SET_BLOCK_LENGTH & "0000000000000000" & "0000001000000000" );
|
||||
when "1000" =>
|
||||
-- Generate a predefined message - CMD7. Select the card so we can access it's data.
|
||||
message_bits <= ("01" & COMMAND_7_SELECT_CARD & i_RCA & "0000001000000000" );
|
||||
when "1001" =>
|
||||
-- Generate a predefined message - CMD13. Send SD card status.
|
||||
message_bits <= ("01" & COMMAND_13_SEND_STATUS & i_RCA & "0000000000000000");
|
||||
|
||||
when others =>
|
||||
-- Generate a custom message
|
||||
message_bits <= ("01" & i_command_ID & cmd_argument);
|
||||
end case;
|
||||
else
|
||||
-- Shift bits out as needed
|
||||
if (produce_next_bit = '1') then
|
||||
-- Shift message bits.
|
||||
message_bits(39 downto 1) <= message_bits(38 downto 0);
|
||||
message_bits(0) <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Generate command argument based on the command_ID. For most commands, the argument is user specified.
|
||||
-- For some commands, it is necessary to send a particular SD Card register contents. Hence, these contents are
|
||||
-- sent instead of the user data.
|
||||
argument_generator: process (i_command_ID, last_command_sent_was_CMD55, i_generate, i_RCA, i_DSR, i_OCR, i_argument)
|
||||
begin
|
||||
cmd_argument <= i_argument;
|
||||
if (i_generate = '1') then
|
||||
case (i_command_ID) is
|
||||
when COMMAND_4_SET_DSR =>
|
||||
cmd_argument <= i_DSR & i_argument(15 downto 0);
|
||||
when COMMAND_7_SELECT_CARD =>
|
||||
cmd_argument <= i_RCA & i_argument(15 downto 0);
|
||||
when COMMAND_9_SEND_CSD =>
|
||||
cmd_argument <= i_RCA & i_argument(15 downto 0);
|
||||
when COMMAND_10_SEND_CID =>
|
||||
cmd_argument <= i_RCA & i_argument(15 downto 0);
|
||||
when COMMAND_13_SEND_STATUS =>
|
||||
cmd_argument <= i_RCA & i_argument(15 downto 0);
|
||||
when COMMAND_15_GO_INACTIVE =>
|
||||
cmd_argument <= i_RCA & i_argument(15 downto 0);
|
||||
when COMMAND_55_APP_CMD =>
|
||||
cmd_argument <= i_RCA & i_argument(15 downto 0);
|
||||
when ACOMMAND_41_SEND_OP_CONDITION =>
|
||||
if (last_command_sent_was_CMD55 = '1') then
|
||||
cmd_argument <= i_OCR;
|
||||
end if;
|
||||
when others =>
|
||||
cmd_argument <= i_argument;
|
||||
end case;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Validate the message ID before sending it out.
|
||||
command_validator: process(i_clock, i_reset_n)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
command_valid <= '0';
|
||||
else
|
||||
if (rising_edge(i_clock)) then
|
||||
if (i_generate = '1') then
|
||||
if (("0" & i_predefined_message) >= ("0" & FIRST_NON_PREDEFINED_COMMAND)) then
|
||||
-- Check the custom message
|
||||
if (last_command_sent_was_CMD55 = '1') then
|
||||
-- Check the application specific messages
|
||||
command_valid <= app_specific_valid;
|
||||
else
|
||||
-- Check the default messages.
|
||||
command_valid <= regular_command_valid;
|
||||
end if;
|
||||
else
|
||||
-- A command is valid if the message is predefined.
|
||||
command_valid <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Registers that indicate that the command sent will return contents of a control register.
|
||||
-- The contents of the response should therefore be stored in the appropriate register.
|
||||
responses_with_control_regs: process(i_clock, i_reset_n, last_command_sent_was_CMD55, last_command_id, message_done)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
returning_ocr_reg <= '0';
|
||||
returning_cid_reg <= '0';
|
||||
returning_rca_reg <= '0';
|
||||
returning_csd_reg <= '0';
|
||||
returning_status_reg <= '0';
|
||||
elsif (rising_edge(i_clock)) then
|
||||
if (i_generate = '1') then
|
||||
returning_ocr_reg <= '0';
|
||||
returning_cid_reg <= '0';
|
||||
returning_rca_reg <= '0';
|
||||
returning_csd_reg <= '0';
|
||||
returning_status_reg <= '0';
|
||||
elsif (message_done = '1') then
|
||||
-- OCR
|
||||
if ((last_command_sent_was_CMD55 = '1') and (last_command_id = ACOMMAND_41_SEND_OP_CONDITION)) then
|
||||
returning_ocr_reg <= '1';
|
||||
end if;
|
||||
-- CID
|
||||
if (last_command_id = COMMAND_2_ALL_SEND_CID) then
|
||||
returning_cid_reg <= '1';
|
||||
end if;
|
||||
-- RCA
|
||||
if (last_command_id = COMMAND_3_SEND_RCA) then
|
||||
returning_rca_reg <= '1';
|
||||
end if;
|
||||
-- CSD
|
||||
if (last_command_id = COMMAND_9_SEND_CSD) then
|
||||
returning_csd_reg <= '1';
|
||||
end if;
|
||||
-- Status
|
||||
if ((last_command_sent_was_CMD55 = '0') and (last_command_id = COMMAND_13_SEND_STATUS)) then
|
||||
returning_status_reg <= '1';
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Count the number of bits sent using a counter.
|
||||
sent_bit_counter: process(i_clock, i_reset_n, i_generate, produce_next_bit, counter)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
counter <= (OTHERS => '0');
|
||||
else
|
||||
if (rising_edge(i_clock)) then
|
||||
if (i_generate = '1') then
|
||||
-- Reset the counter indicating the number of bits produced.
|
||||
counter <= "0000000";
|
||||
else
|
||||
if (produce_next_bit = '1') then
|
||||
-- Update the number of message bits sent.
|
||||
counter <= counter + '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Select the source for the output data to be either the message data or the CRC bits.
|
||||
source_selector: process(i_clock, i_reset_n, i_generate)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
sending_CRC <= '0';
|
||||
else
|
||||
if (rising_edge(i_clock)) then
|
||||
if (i_generate = '1') then
|
||||
-- Set sending CRC flag to 0.
|
||||
sending_CRC <= '0';
|
||||
else
|
||||
-- If this is the last bit being sent, then bits that follow are the CRC bits.
|
||||
if (counter = "0101000") then
|
||||
sending_CRC <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- When the message is sent, store its ID. In a special case when CMD55 is sent, the next command can be an application
|
||||
-- specific command. We need to check those command IDs to verify the validity of the message.
|
||||
CMD55_recognizer: process(i_clock, i_reset_n, i_generate, produce_next_bit, counter, message_done, last_command_id)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
last_command_sent_was_CMD55 <= '0';
|
||||
else
|
||||
if (rising_edge(i_clock)) then
|
||||
if (i_generate = '0') then
|
||||
-- Store the ID of the current command.
|
||||
if (produce_next_bit = '1') then
|
||||
if (counter = "0000000") then
|
||||
last_command_id <= message_bits(37 downto 32);
|
||||
end if;
|
||||
end if;
|
||||
-- When message has been sent then check if it was CMD55.
|
||||
if (message_done = '1') then
|
||||
if (last_command_id = COMMAND_55_APP_CMD) then
|
||||
last_command_sent_was_CMD55 <= '1';
|
||||
else
|
||||
last_command_sent_was_CMD55 <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Instantiate a CRC7 generator. Message bits will pass through it to create the CRC code for the message.
|
||||
CRC7_Gen: Altera_UP_SD_CRC7_Generator PORT MAP
|
||||
(
|
||||
i_clock => i_clock,
|
||||
i_reset_n => i_reset_n,
|
||||
i_enable => i_message_bit_out,
|
||||
i_shift => sending_CRC,
|
||||
i_datain => message_bits(39),
|
||||
o_dataout => CRC_generator_out
|
||||
);
|
||||
|
||||
-- Define the source of the data produced by this module, depending on the counter value and the sending_CRC register state.
|
||||
data_bit_register: process(i_clock, i_reset_n, i_generate, produce_next_bit, counter)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
bit_to_send <= '1';
|
||||
else
|
||||
if (rising_edge(i_clock)) then
|
||||
if (i_generate = '1') then
|
||||
bit_to_send <= '1';
|
||||
elsif (produce_next_bit = '1') then
|
||||
-- Send data to output.
|
||||
if (sending_CRC = '0') then
|
||||
-- Send message bits
|
||||
bit_to_send <= message_bits(39);
|
||||
else
|
||||
-- Send CRC bits
|
||||
if ((counter = "0101111") or (counter = "0110000")) then
|
||||
-- At the end of CRC bits put a 1.
|
||||
bit_to_send <= '1';
|
||||
else
|
||||
bit_to_send <= CRC_generator_out;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Define conditions to produce the next message bit on the module output port o_dataout.
|
||||
produce_next_bit <= i_message_bit_out and (not message_done);
|
||||
-- Message is done when the last bit appears at the output.
|
||||
message_done <= '1' when (counter = "0110001") else '0';
|
||||
-- Check the application specific messages
|
||||
app_specific_valid <= '1' when (
|
||||
--(i_command_ID = COMMAND_0_GO_IDLE) or
|
||||
(i_command_ID = COMMAND_2_ALL_SEND_CID) or
|
||||
(i_command_ID = COMMAND_3_SEND_RCA) or
|
||||
(i_command_ID = COMMAND_4_SET_DSR) or
|
||||
--(i_command_ID = ACOMMAND_6_SET_BUS_WIDTH) or
|
||||
--(i_command_ID = COMMAND_7_SELECT_CARD) or
|
||||
(i_command_ID = COMMAND_9_SEND_CSD) or
|
||||
(i_command_ID = COMMAND_10_SEND_CID) or
|
||||
--(i_command_ID = COMMAND_12_STOP_TRANSMISSION) or
|
||||
(i_command_ID = ACOMMAND_13_SD_STATUS) or
|
||||
--(i_command_ID = COMMAND_15_GO_INACTIVE) or
|
||||
--(i_command_ID = COMMAND_16_SET_BLOCK_LENGTH) or
|
||||
(i_command_ID = COMMAND_17_READ_BLOCK) or
|
||||
--(i_command_ID = COMMAND_18_READ_MULTIPLE_BLOCKS) or
|
||||
(i_command_ID = ACOMMAND_22_SEND_NUM_WR_BLOCKS) or
|
||||
(i_command_ID = ACOMMAND_23_SET_BLK_ERASE_COUNT) or
|
||||
(i_command_ID = COMMAND_24_WRITE_BLOCK) or
|
||||
(i_command_ID = COMMAND_25_WRITE_MULTIPLE_BLOCKS) or
|
||||
(i_command_ID = COMMAND_27_PROGRAM_CSD) or
|
||||
(i_command_ID = COMMAND_28_SET_WRITE_PROTECT) or
|
||||
(i_command_ID = COMMAND_29_CLEAR_WRITE_PROTECT) or
|
||||
(i_command_ID = COMMAND_30_SEND_PROTECTED_GROUPS) or
|
||||
(i_command_ID = COMMAND_32_ERASE_BLOCK_START) or
|
||||
(i_command_ID = COMMAND_33_ERASE_BLOCK_END) or
|
||||
(i_command_ID = COMMAND_38_ERASE_SELECTED_GROUPS) or
|
||||
(i_command_ID = ACOMMAND_41_SEND_OP_CONDITION) or
|
||||
(i_command_ID = ACOMMAND_42_SET_CLR_CARD_DETECT) or
|
||||
(i_command_ID = ACOMMAND_51_SEND_SCR) or
|
||||
(i_command_ID = COMMAND_55_APP_CMD) or
|
||||
(i_command_ID = COMMAND_56_GEN_CMD)
|
||||
)
|
||||
else '0';
|
||||
-- Check the default messages.
|
||||
regular_command_valid <= '1' when (
|
||||
-------------------------------------------------------
|
||||
-- Disabled to prevent malfunction of the core
|
||||
-------------------------------------------------------
|
||||
--(i_command_ID = COMMAND_0_GO_IDLE) or
|
||||
--(i_command_ID = COMMAND_6_SWITCH_FUNCTION) or
|
||||
--(i_command_ID = COMMAND_7_SELECT_CARD) or
|
||||
--(i_command_ID = COMMAND_15_GO_INACTIVE) or
|
||||
--(i_command_ID = COMMAND_27_PROGRAM_CSD) or
|
||||
--(i_command_ID = COMMAND_30_SEND_PROTECTED_GROUPS) or
|
||||
--(i_command_ID = COMMAND_42_LOCK_UNLOCK) or
|
||||
-------------------------------------------------------
|
||||
(i_command_ID = COMMAND_2_ALL_SEND_CID) or
|
||||
(i_command_ID = COMMAND_3_SEND_RCA) or
|
||||
(i_command_ID = COMMAND_4_SET_DSR) or
|
||||
(i_command_ID = COMMAND_9_SEND_CSD) or
|
||||
(i_command_ID = COMMAND_10_SEND_CID) or
|
||||
(i_command_ID = COMMAND_13_SEND_STATUS) or
|
||||
-------------------------------------------------------
|
||||
-- Disabled to simplify the circuit
|
||||
-------------------------------------------------------
|
||||
--(i_command_ID = COMMAND_12_STOP_TRANSMISSION) or
|
||||
--(i_command_ID = COMMAND_16_SET_BLOCK_LENGTH) or
|
||||
--(i_command_ID = COMMAND_18_READ_MULTIPLE_BLOCKS) or
|
||||
--(i_command_ID = COMMAND_25_WRITE_MULTIPLE_BLOCKS) or
|
||||
-------------------------------------------------------
|
||||
(i_command_ID = COMMAND_17_READ_BLOCK) or
|
||||
(i_command_ID = COMMAND_24_WRITE_BLOCK) or
|
||||
(i_command_ID = COMMAND_28_SET_WRITE_PROTECT) or
|
||||
(i_command_ID = COMMAND_29_CLEAR_WRITE_PROTECT) or
|
||||
(i_command_ID = COMMAND_32_ERASE_BLOCK_START) or
|
||||
(i_command_ID = COMMAND_33_ERASE_BLOCK_END) or
|
||||
(i_command_ID = COMMAND_38_ERASE_SELECTED_GROUPS) or
|
||||
(i_command_ID = COMMAND_55_APP_CMD) or
|
||||
(i_command_ID = COMMAND_56_GEN_CMD)
|
||||
)
|
||||
else '0';
|
||||
|
||||
response_type <= "001" when -- Wait for type 1 response when
|
||||
(
|
||||
(i_predefined_message = "0001") or
|
||||
(i_predefined_message = "0111") or
|
||||
(i_predefined_message = "1000") or
|
||||
(i_predefined_message = "1001") or
|
||||
((i_predefined_message = FIRST_NON_PREDEFINED_COMMAND) and
|
||||
((i_command_ID = COMMAND_6_SWITCH_FUNCTION) or
|
||||
(i_command_ID = COMMAND_7_SELECT_CARD) or
|
||||
(i_command_ID = COMMAND_12_STOP_TRANSMISSION) or
|
||||
(i_command_ID = COMMAND_13_SEND_STATUS) or
|
||||
(i_command_ID = COMMAND_16_SET_BLOCK_LENGTH) or
|
||||
(i_command_ID = COMMAND_17_READ_BLOCK) or
|
||||
(i_command_ID = COMMAND_18_READ_MULTIPLE_BLOCKS) or
|
||||
(i_command_ID = COMMAND_24_WRITE_BLOCK) or
|
||||
(i_command_ID = COMMAND_25_WRITE_MULTIPLE_BLOCKS) or
|
||||
(i_command_ID = COMMAND_27_PROGRAM_CSD) or
|
||||
(i_command_ID = COMMAND_28_SET_WRITE_PROTECT) or
|
||||
(i_command_ID = COMMAND_29_CLEAR_WRITE_PROTECT) or
|
||||
(i_command_ID = COMMAND_30_SEND_PROTECTED_GROUPS) or
|
||||
(i_command_ID = COMMAND_32_ERASE_BLOCK_START) or
|
||||
(i_command_ID = COMMAND_33_ERASE_BLOCK_END) or
|
||||
(i_command_ID = COMMAND_38_ERASE_SELECTED_GROUPS) or
|
||||
(i_command_ID = COMMAND_42_LOCK_UNLOCK) or
|
||||
(i_command_ID = COMMAND_55_APP_CMD) or
|
||||
(i_command_ID = COMMAND_56_GEN_CMD) or
|
||||
((last_command_sent_was_CMD55 = '1') and
|
||||
((i_command_ID = ACOMMAND_6_SET_BUS_WIDTH) or
|
||||
(i_command_ID = ACOMMAND_13_SD_STATUS) or
|
||||
(i_command_ID = ACOMMAND_22_SEND_NUM_WR_BLOCKS) or
|
||||
(i_command_ID = ACOMMAND_23_SET_BLK_ERASE_COUNT) or
|
||||
(i_command_ID = ACOMMAND_42_SET_CLR_CARD_DETECT) or
|
||||
(i_command_ID = ACOMMAND_51_SEND_SCR)))))
|
||||
) else
|
||||
"010" when -- Wait for type 2 response when
|
||||
(
|
||||
((i_predefined_message = FIRST_NON_PREDEFINED_COMMAND) and
|
||||
((i_command_ID = COMMAND_2_ALL_SEND_CID) or
|
||||
(i_command_ID = COMMAND_9_SEND_CSD) or
|
||||
(i_command_ID = COMMAND_10_SEND_CID))) or
|
||||
(i_predefined_message = "0011") or
|
||||
(i_predefined_message = "0101")
|
||||
) else
|
||||
"011" when -- Wait for type 3 response when
|
||||
(
|
||||
((i_predefined_message = FIRST_NON_PREDEFINED_COMMAND) and (last_command_sent_was_CMD55 = '1') and (i_command_ID = ACOMMAND_41_SEND_OP_CONDITION)) or
|
||||
(i_predefined_message = "0010")
|
||||
) else
|
||||
"110" when -- Wait for type 6 response when
|
||||
(((i_predefined_message = FIRST_NON_PREDEFINED_COMMAND) and (i_command_ID = COMMAND_3_SEND_RCA)) or
|
||||
(i_predefined_message = "0100"))
|
||||
else "000"; -- Otherwise there is no response pending.
|
||||
|
||||
-- Define circuit outputs
|
||||
o_message_done <= message_done;
|
||||
o_response_type <= response_type_reg;
|
||||
o_valid <= command_valid;
|
||||
o_dataout <= bit_to_send;
|
||||
o_returning_ocr <= returning_ocr_reg;
|
||||
o_returning_cid <= returning_cid_reg;
|
||||
o_returning_rca <= returning_rca_reg;
|
||||
o_returning_csd <= returning_csd_reg;
|
||||
o_returning_status <= returning_status_reg;
|
||||
o_data_read <= '1' when (last_command_id = COMMAND_17_READ_BLOCK) else '0';
|
||||
o_data_write <= '1' when (last_command_id = COMMAND_24_WRITE_BLOCK) else '0';
|
||||
o_last_cmd_was_55 <= last_command_sent_was_CMD55;
|
||||
o_wait_cmd_busy <= '1' when (
|
||||
(last_command_id = COMMAND_7_SELECT_CARD) or
|
||||
(last_command_id = COMMAND_12_STOP_TRANSMISSION) or
|
||||
(last_command_id = COMMAND_28_SET_WRITE_PROTECT) or
|
||||
(last_command_id = COMMAND_29_CLEAR_WRITE_PROTECT) or
|
||||
(last_command_id = COMMAND_38_ERASE_SELECTED_GROUPS))
|
||||
else '0';
|
||||
end rtl;
|
|
@ -0,0 +1,518 @@
|
|||
-- (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
-- Your use of Altera Corporation's design tools, logic functions and other
|
||||
-- software and tools, and its AMPP partner logic functions, and any output
|
||||
-- files any of the foregoing (including device programming or simulation
|
||||
-- files), and any associated documentation or information are expressly subject
|
||||
-- to the terms and conditions of the Altera Program License Subscription
|
||||
-- Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
-- license agreement, including, without limitation, that your use is for the
|
||||
-- sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
-- Altera or its authorized distributors. Please refer to the applicable
|
||||
-- agreement for further details.
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------
|
||||
-- This is an FSM that allows access to the SD Card IP core via the Avalon Interconnect.
|
||||
--
|
||||
-- This module takes a range of addresses on the Avalon Interconnect. Specifically:
|
||||
-- - 0x00000000 to 0x000001ff
|
||||
-- word addressable buffer space. The data to be written to the SD card as well
|
||||
-- as data read from the SD card can be accessed here.
|
||||
--
|
||||
-- - 0x00000200 to 0x0000020f
|
||||
-- 128-bit containing the Card Identification Number. The meaning of each bit is described in the
|
||||
-- SD Card Physical Layer Specification Document.
|
||||
--
|
||||
-- - 0x00000210 to 0x0000021f
|
||||
-- 128-bit register containing Card Specific Data. The meaning of each bit is described in the
|
||||
-- SD Card Physical Layer Specification Document.
|
||||
--
|
||||
-- - 0x00000220 to 0x00000223
|
||||
-- 32-bit register containing Operating Conditions Register. The meaning of each bit is described
|
||||
-- in the SD Card Physical Layer Specification Document.
|
||||
--
|
||||
-- - 0x00000224 to 0x00000227
|
||||
-- 32-bit register containing the Status Register. The meaning of each bit is described
|
||||
-- in the SD Card Physical Layer Specification Document. However, if the card is not connected or the
|
||||
-- status register could not be read from the SD card, this register will contain invalid data. In such
|
||||
-- a case, wait for a card to be connected by checking the Auxiliary Status Register (UP Core Specific), and
|
||||
-- a command 13 (SEND_STATUS) to update the contents of this register when possible. If a card is connected then
|
||||
-- the Auxiliary Status Register can be polled until such a time that Status Register is valid, as the SD Card
|
||||
-- interface circuit updates the status register approximately every 0.1 of a second, and after every command
|
||||
-- is executed.
|
||||
--
|
||||
-- - 0x00000228 to 0x000000229
|
||||
-- 16-bit register containing the Relative Card Address. This address uniquely identifies a card
|
||||
-- connected to the SD Card slot.
|
||||
--
|
||||
-- - 0x0000022C to 0x00000022F
|
||||
-- 32-bit register used to set the argument for a command to be sent to the SD Card.
|
||||
--
|
||||
-- - 0x00000230 to 0x000000231
|
||||
-- 16-bit register used to send a command to an SD card. Once written, the interface will issue the
|
||||
-- specified command. The meaning of each bit in this register is as follows:
|
||||
-- - 0-5 - command index. This is a command index as per SD Card Physical Layer specification document.
|
||||
-- - 6 - use most recent RCA. If this bit is set, the command argument will be replaced with the contents of
|
||||
-- the Relative Card Address register, followed by 16 0s. For commands that require RCA to be sent as
|
||||
-- an argument, this bit should be set and users will not need to specify RCA themselves.
|
||||
-- - 7-15 - currently unused bits. They will be ignored.
|
||||
-- NOTE: If a specified command is determined to be invalid, or the card is not connected to the SD Card socket,
|
||||
-- then the SD Card interface circuit will not issue the command.
|
||||
--
|
||||
-- - 0x00000234 to 0x00000235
|
||||
-- 16-bit register with Auxiliary Status Register. This is the Altera UP SD Card Interface status. The meaning of
|
||||
-- the bits is as follows:
|
||||
-- - 0 - last command valid - Set to '1' if the most recently user issued command was valid.
|
||||
-- - 1 - card connected - Set to '1' if at present an SD card
|
||||
-- - 2 - execution in progress - Set to '1' if the command recently issued is currently being executed. If true,
|
||||
-- then the current state of SD Card registers should be ignored.
|
||||
-- - 3 - status register valid - Set to '1' if the status register is valid.
|
||||
-- - 4 - command timed out - Set to '1' if the last command timed out.
|
||||
-- - 5 - crc failed - Set to '1' if the last command failed a CRC check.
|
||||
-- - 6-15 - unused.
|
||||
--
|
||||
-- - 0x00000238 to 0x0000023B
|
||||
-- 32-bit register containing the 32-bit R1 response message. Use it to test validity of the response. This register
|
||||
-- will not store the response to SEND_STATUS command. Insteand, read the SD_status register at location 0x00000224.
|
||||
--
|
||||
-- Date: December 8, 2008
|
||||
-- NOTES/REVISIONS:
|
||||
-- December 17, 2008 - added R1 response register to the core. It is now available at 0x00000238.
|
||||
----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity Altera_UP_SD_Card_Avalon_Interface is
|
||||
generic (
|
||||
ADDRESS_BUFFER : std_logic_vector(7 downto 0) := "00000000";
|
||||
ADDRESS_CID : std_logic_vector(7 downto 0) := "10000000";
|
||||
ADDRESS_CSD : std_logic_vector(7 downto 0) := "10000100";
|
||||
ADDRESS_OCR : std_logic_vector(7 downto 0) := "10001000";
|
||||
ADDRESS_SR : std_logic_vector(7 downto 0) := "10001001";
|
||||
ADDRESS_RCA : std_logic_vector(7 downto 0) := "10001010";
|
||||
ADDRESS_ARGUMENT : std_logic_vector(7 downto 0) := "10001011";
|
||||
ADDRESS_COMMAND : std_logic_vector(7 downto 0) := "10001100";
|
||||
ADDRESS_ASR : std_logic_vector(7 downto 0) := "10001101";
|
||||
ADDRESS_R1 : std_logic_vector(7 downto 0) := "10001110"
|
||||
);
|
||||
port
|
||||
(
|
||||
-- Clock and Reset signals
|
||||
i_clock : in STD_LOGIC;
|
||||
i_reset_n : in STD_LOGIC; -- Asynchronous reset
|
||||
|
||||
-- Avalon Interconnect Signals
|
||||
i_avalon_address : in STD_LOGIC_VECTOR(7 downto 0);
|
||||
i_avalon_chip_select : in STD_LOGIC;
|
||||
i_avalon_read : in STD_LOGIC;
|
||||
i_avalon_write : in STD_LOGIC;
|
||||
i_avalon_byteenable : in STD_LOGIC_VECTOR(3 downto 0);
|
||||
i_avalon_writedata : in STD_LOGIC_VECTOR(31 downto 0);
|
||||
o_avalon_readdata : out STD_LOGIC_VECTOR(31 downto 0);
|
||||
o_avalon_waitrequest : out STD_LOGIC;
|
||||
|
||||
-- SD Card interface ports
|
||||
b_SD_cmd : inout STD_LOGIC;
|
||||
b_SD_dat : inout STD_LOGIC;
|
||||
b_SD_dat3 : inout STD_LOGIC;
|
||||
o_SD_clock : out STD_LOGIC
|
||||
);
|
||||
|
||||
end entity;
|
||||
|
||||
architecture rtl of Altera_UP_SD_Card_Avalon_Interface is
|
||||
|
||||
component Altera_UP_SD_Card_Interface is
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
|
||||
-- Command interface
|
||||
b_SD_cmd : inout std_logic;
|
||||
b_SD_dat : inout std_logic;
|
||||
b_SD_dat3 : inout std_logic;
|
||||
i_command_ID : in std_logic_vector(5 downto 0);
|
||||
i_argument : in std_logic_vector(31 downto 0);
|
||||
i_user_command_ready : in std_logic;
|
||||
|
||||
o_SD_clock : out std_logic;
|
||||
o_card_connected : out std_logic;
|
||||
o_command_completed : out std_logic;
|
||||
o_command_valid : out std_logic;
|
||||
o_command_timed_out : out std_logic;
|
||||
o_command_crc_failed : out std_logic;
|
||||
|
||||
-- Buffer access
|
||||
i_buffer_enable : in std_logic;
|
||||
i_buffer_address : in std_logic_vector(7 downto 0);
|
||||
i_buffer_write : in std_logic;
|
||||
i_buffer_data_in : in std_logic_vector(15 downto 0);
|
||||
o_buffer_data_out : out std_logic_vector(15 downto 0);
|
||||
|
||||
-- Show SD Card registers as outputs
|
||||
o_SD_REG_card_identification_number : out std_logic_vector(127 downto 0);
|
||||
o_SD_REG_relative_card_address : out std_logic_vector(15 downto 0);
|
||||
o_SD_REG_operating_conditions_register : out std_logic_vector(31 downto 0);
|
||||
o_SD_REG_card_specific_data : out std_logic_vector(127 downto 0);
|
||||
o_SD_REG_status_register : out std_logic_vector(31 downto 0);
|
||||
o_SD_REG_response_R1 : out std_logic_vector(31 downto 0);
|
||||
o_SD_REG_status_register_valid : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
-- Build an enumerated type for the state machine. On reset always reset the DE2 and read the state
|
||||
-- of the switches.
|
||||
type buffer_state_type is ( s_RESET, s_WAIT_REQUEST, s_READ_FIRST_WORD, s_READ_SECOND_WORD, s_RECEIVE_FIRST_WORD,
|
||||
s_RECEIVE_SECOND_WORD, s_WR_READ_FIRST_WORD, s_WR_READ_FIRST_WORD_DELAY, s_WRITE_FIRST_BYTE, s_WRITE_FIRST_WORD,
|
||||
s_WR_READ_SECOND_WORD, s_WR_READ_SECOND_WORD_DELAY, s_WRITE_SECOND_BYTE, s_WRITE_SECOND_WORD, s_WAIT_RELEASE);
|
||||
type command_state_type is (s_RESET_CMD, s_WAIT_COMMAND, s_WAIT_RESPONSE, s_UPDATE_AUX_SR);
|
||||
|
||||
-- Register to hold the current state
|
||||
signal current_state : buffer_state_type;
|
||||
signal next_state : buffer_state_type;
|
||||
signal current_cmd_state : command_state_type;
|
||||
signal next_cmd_state : command_state_type;
|
||||
|
||||
-------------------
|
||||
-- Local signals
|
||||
-------------------
|
||||
-- REGISTERED
|
||||
signal auxiliary_status_reg : std_logic_vector(5 downto 0);
|
||||
signal buffer_data_out_reg : std_logic_vector(31 downto 0);
|
||||
signal buffer_data_in_reg : std_logic_vector(31 downto 0);
|
||||
signal buffer_data_out : std_logic_vector(15 downto 0);
|
||||
signal command_ID_reg : std_logic_vector( 5 downto 0);
|
||||
signal argument_reg : std_logic_vector(31 downto 0);
|
||||
signal avalon_address : std_logic_vector(7 downto 0);
|
||||
signal avalon_byteenable : std_logic_vector(3 downto 0);
|
||||
-- UNREGISTERED
|
||||
signal buffer_address : std_logic_vector(7 downto 0);
|
||||
signal buffer_data_in : std_logic_vector(15 downto 0);
|
||||
signal SD_REG_card_identification_number : std_logic_vector(127 downto 0);
|
||||
signal SD_REG_relative_card_address : std_logic_vector(15 downto 0);
|
||||
signal SD_REG_operating_conditions_register : std_logic_vector(31 downto 0);
|
||||
signal SD_REG_card_specific_data : std_logic_vector(127 downto 0);
|
||||
signal SD_REG_status_register : std_logic_vector(31 downto 0);
|
||||
signal SD_REG_response_R1 : std_logic_vector(31 downto 0);
|
||||
signal command_ready, send_command_ready,
|
||||
command_valid, command_completed, card_connected : std_logic;
|
||||
signal status_reg_valid, argument_write : std_logic;
|
||||
signal read_buffer_request, write_buffer_request, buffer_enable, buffer_write : std_logic;
|
||||
signal command_timed_out, command_crc_failed : std_logic;
|
||||
|
||||
begin
|
||||
-- Define state transitions for buffer interface.
|
||||
state_transitions_buffer: process (current_state, read_buffer_request, write_buffer_request, i_avalon_byteenable, avalon_byteenable)
|
||||
begin
|
||||
case current_state is
|
||||
when s_RESET =>
|
||||
-- Reset local registers.
|
||||
next_state <= s_WAIT_REQUEST;
|
||||
|
||||
when s_WAIT_REQUEST =>
|
||||
-- Wait for a user command.
|
||||
if (read_buffer_request = '1') then
|
||||
next_state <= s_READ_FIRST_WORD;
|
||||
elsif (write_buffer_request = '1') then
|
||||
if ((i_avalon_byteenable(1) = '1') and (i_avalon_byteenable(0) = '1')) then
|
||||
next_state <= s_WRITE_FIRST_WORD;
|
||||
elsif ((i_avalon_byteenable(3) = '1') and (i_avalon_byteenable(2) = '1')) then
|
||||
next_state <= s_WRITE_SECOND_WORD;
|
||||
elsif ((i_avalon_byteenable(1) = '1') or (i_avalon_byteenable(0) = '1')) then
|
||||
next_state <= s_WR_READ_FIRST_WORD;
|
||||
elsif ((i_avalon_byteenable(3) = '1') or (i_avalon_byteenable(2) = '1')) then
|
||||
next_state <= s_WR_READ_SECOND_WORD;
|
||||
else
|
||||
next_state <= s_WAIT_REQUEST;
|
||||
end if;
|
||||
else
|
||||
next_state <= s_WAIT_REQUEST;
|
||||
end if;
|
||||
|
||||
when s_READ_FIRST_WORD =>
|
||||
-- Read first 16-bit word from the buffer
|
||||
next_state <= s_READ_SECOND_WORD;
|
||||
|
||||
when s_READ_SECOND_WORD =>
|
||||
-- Read second 16-bit word from the buffer
|
||||
next_state <= s_RECEIVE_FIRST_WORD;
|
||||
|
||||
when s_RECEIVE_FIRST_WORD =>
|
||||
-- Store first word read
|
||||
next_state <= s_RECEIVE_SECOND_WORD;
|
||||
|
||||
when s_RECEIVE_SECOND_WORD =>
|
||||
-- Store second word read
|
||||
next_state <= s_WAIT_RELEASE;
|
||||
|
||||
-- The following states control writing to the buffer. To write a single byte it is necessary to read a
|
||||
-- word and then write it back, changing only on of its bytes.
|
||||
when s_WR_READ_FIRST_WORD =>
|
||||
-- Read first 16-bit word from the buffer
|
||||
next_state <= s_WR_READ_FIRST_WORD_DELAY;
|
||||
|
||||
when s_WR_READ_FIRST_WORD_DELAY =>
|
||||
-- Wait a cycle
|
||||
next_state <= s_WRITE_FIRST_BYTE;
|
||||
|
||||
when s_WRITE_FIRST_BYTE =>
|
||||
-- Write one of the bytes in the given word into the memory.
|
||||
if ((avalon_byteenable(3) = '1') and (avalon_byteenable(2) = '1')) then
|
||||
next_state <= s_WRITE_SECOND_WORD;
|
||||
elsif ((avalon_byteenable(3) = '1') or (avalon_byteenable(2) = '1')) then
|
||||
next_state <= s_WR_READ_SECOND_WORD;
|
||||
else
|
||||
next_state <= s_WAIT_RELEASE;
|
||||
end if;
|
||||
|
||||
when s_WR_READ_SECOND_WORD =>
|
||||
-- Read second 16-bit word from the buffer
|
||||
next_state <= s_WR_READ_SECOND_WORD_DELAY;
|
||||
|
||||
when s_WR_READ_SECOND_WORD_DELAY =>
|
||||
-- Wait a cycle
|
||||
next_state <= s_WRITE_SECOND_BYTE;
|
||||
|
||||
when s_WRITE_SECOND_BYTE =>
|
||||
-- Write one of the bytes in the given word into the memory.
|
||||
next_state <= s_WAIT_RELEASE;
|
||||
|
||||
-- Full word writing can be done without reading the word in the first place.
|
||||
when s_WRITE_FIRST_WORD =>
|
||||
-- Write the first word into memory
|
||||
if ((avalon_byteenable(3) = '1') and (avalon_byteenable(2) = '1')) then
|
||||
next_state <= s_WRITE_SECOND_WORD;
|
||||
elsif ((avalon_byteenable(3) = '1') or (avalon_byteenable(2) = '1')) then
|
||||
next_state <= s_WR_READ_SECOND_WORD;
|
||||
else
|
||||
next_state <= s_WAIT_RELEASE;
|
||||
end if;
|
||||
|
||||
when s_WRITE_SECOND_WORD =>
|
||||
-- Write the second word into memory
|
||||
next_state <= s_WAIT_RELEASE;
|
||||
|
||||
when s_WAIT_RELEASE =>
|
||||
-- if ((read_buffer_request = '1') or (write_buffer_request = '1')) then
|
||||
-- next_state <= s_WAIT_RELEASE;
|
||||
-- else
|
||||
next_state <= s_WAIT_REQUEST;
|
||||
-- end if;
|
||||
|
||||
when others =>
|
||||
-- Make sure to start in the reset state if the circuit powers up in an odd state.
|
||||
next_state <= s_RESET;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
-- State Registers
|
||||
buffer_state_regs: process(i_clock, i_reset_n)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
current_state <= s_RESET;
|
||||
elsif(rising_edge(i_clock)) then
|
||||
current_state <= next_state;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
helper_regs: process(i_clock, i_reset_n)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
avalon_address <= (OTHERS => '0');
|
||||
buffer_data_out_reg <= (OTHERS => '0');
|
||||
buffer_data_in_reg <= (OTHERS => '0');
|
||||
avalon_byteenable <= (OTHERS => '0');
|
||||
elsif(rising_edge(i_clock)) then
|
||||
if (current_state = s_WAIT_REQUEST) then
|
||||
avalon_address <= i_avalon_address;
|
||||
buffer_data_in_reg <= i_avalon_writedata;
|
||||
avalon_byteenable <= i_avalon_byteenable;
|
||||
end if;
|
||||
if (current_state = s_RECEIVE_FIRST_WORD) then
|
||||
buffer_data_out_reg(15 downto 0) <= buffer_data_out;
|
||||
end if;
|
||||
if (current_state = s_RECEIVE_SECOND_WORD) then
|
||||
buffer_data_out_reg(31 downto 16) <= buffer_data_out;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- FSM outputs
|
||||
o_avalon_waitrequest <= (read_buffer_request or write_buffer_request) when (not (current_state = s_WAIT_RELEASE)) else '0';
|
||||
buffer_address(7 downto 1) <= avalon_address(6 downto 0);
|
||||
buffer_address(0) <= '1' when ( (current_state = s_READ_SECOND_WORD) or (current_state = s_WRITE_SECOND_WORD) or
|
||||
(current_state = s_WR_READ_SECOND_WORD) or (current_state = s_WRITE_SECOND_BYTE)) else
|
||||
'0';
|
||||
buffer_enable <= '1' when ( (current_state = s_READ_FIRST_WORD) or (current_state = s_WR_READ_FIRST_WORD) or
|
||||
(current_state = s_READ_SECOND_WORD) or (current_state = s_WR_READ_SECOND_WORD) or
|
||||
(current_state = s_WRITE_FIRST_WORD) or (current_state = s_WRITE_FIRST_BYTE) or
|
||||
(current_state = s_WRITE_SECOND_WORD) or (current_state = s_WRITE_SECOND_BYTE)) else
|
||||
'0';
|
||||
buffer_write <= '1' when ( (current_state = s_WRITE_FIRST_WORD) or (current_state = s_WRITE_FIRST_BYTE) or
|
||||
(current_state = s_WRITE_SECOND_WORD) or (current_state = s_WRITE_SECOND_BYTE)) else
|
||||
'0';
|
||||
buffer_data_in <= (buffer_data_out(15 downto 8) & buffer_data_in_reg(7 downto 0)) when ((current_state = s_WRITE_FIRST_BYTE) and (avalon_byteenable(1 downto 0) = "01")) else
|
||||
(buffer_data_in_reg(15 downto 8) & buffer_data_out(7 downto 0)) when ((current_state = s_WRITE_FIRST_BYTE) and (avalon_byteenable(1 downto 0) = "10")) else
|
||||
(buffer_data_out(15 downto 8) & buffer_data_in_reg(23 downto 16)) when ((current_state = s_WRITE_SECOND_BYTE) and (avalon_byteenable(3 downto 2) = "01")) else
|
||||
(buffer_data_in_reg(31 downto 24) & buffer_data_out(7 downto 0)) when ((current_state = s_WRITE_SECOND_BYTE) and (avalon_byteenable(3 downto 2) = "10")) else
|
||||
buffer_data_in_reg(15 downto 0) when (current_state = s_WRITE_FIRST_WORD) else
|
||||
buffer_data_in_reg(31 downto 16);
|
||||
-- Glue Logic
|
||||
read_buffer_request <= (not i_avalon_address(7)) and (i_avalon_chip_select) and (i_avalon_read);
|
||||
write_buffer_request <= (not i_avalon_address(7)) and (i_avalon_chip_select) and (i_avalon_write);
|
||||
|
||||
-- Define state transitions for command interface.
|
||||
state_transitions_cmd: process (current_cmd_state, command_completed, command_valid, command_ready)
|
||||
begin
|
||||
case current_cmd_state is
|
||||
when s_RESET_CMD =>
|
||||
-- Reset local registers.
|
||||
next_cmd_state <= s_WAIT_COMMAND;
|
||||
|
||||
when s_WAIT_COMMAND =>
|
||||
-- Wait for a user command.
|
||||
if (command_ready = '1') then
|
||||
next_cmd_state <= s_WAIT_RESPONSE;
|
||||
else
|
||||
next_cmd_state <= s_WAIT_COMMAND;
|
||||
end if;
|
||||
|
||||
when s_WAIT_RESPONSE =>
|
||||
-- Generate a predefined command to the SD card. This is the identification process for the SD card.
|
||||
if ((command_completed = '1') or (command_valid = '0')) then
|
||||
next_cmd_state <= s_UPDATE_AUX_SR;
|
||||
else
|
||||
next_cmd_state <= s_WAIT_RESPONSE;
|
||||
end if;
|
||||
|
||||
when s_UPDATE_AUX_SR =>
|
||||
-- Update the Auxiliary status register.
|
||||
if (command_ready = '1') then
|
||||
next_cmd_state <= s_UPDATE_AUX_SR;
|
||||
else
|
||||
next_cmd_state <= s_WAIT_COMMAND;
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
-- Make sure to start in the reset state if the circuit powers up in an odd state.
|
||||
next_cmd_state <= s_RESET_CMD;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
-- State registers
|
||||
cmd_state_regs: process(i_clock, i_reset_n)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
current_cmd_state <= s_RESET_CMD;
|
||||
elsif(rising_edge(i_clock)) then
|
||||
current_cmd_state <= next_cmd_state;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- FSM outputs
|
||||
send_command_ready <= '1' when ((current_cmd_state = s_WAIT_RESPONSE) or (current_cmd_state = s_UPDATE_AUX_SR)) else '0';
|
||||
|
||||
-- Glue logic
|
||||
command_ready <= '1' when ( (i_avalon_chip_select = '1') and (i_avalon_write = '1') and
|
||||
(i_avalon_address = ADDRESS_COMMAND)) else '0';
|
||||
argument_write <= '1' when ((i_avalon_chip_select = '1') and (i_avalon_write = '1') and
|
||||
(i_avalon_address = ADDRESS_ARGUMENT)) else '0';
|
||||
-- Local Registers
|
||||
local_regs: process(i_clock, i_reset_n, current_cmd_state, card_connected, command_valid, i_avalon_writedata, command_completed, command_ready)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
auxiliary_status_reg <= "000000";
|
||||
command_ID_reg <= (OTHERS => '0');
|
||||
elsif(rising_edge(i_clock)) then
|
||||
-- AUX Status Register
|
||||
if ((current_cmd_state = s_WAIT_RESPONSE) or (current_cmd_state = s_UPDATE_AUX_SR)) then
|
||||
auxiliary_status_reg(2) <= not command_completed;
|
||||
auxiliary_status_reg(4) <= command_timed_out;
|
||||
auxiliary_status_reg(5) <= command_crc_failed;
|
||||
end if;
|
||||
auxiliary_status_reg(0) <= command_valid;
|
||||
auxiliary_status_reg(1) <= card_connected;
|
||||
auxiliary_status_reg(3) <= status_reg_valid;
|
||||
-- Command
|
||||
if (command_ready = '1') then
|
||||
command_ID_reg <= i_avalon_writedata(5 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
argument_regs_processing: process(i_clock, i_reset_n, current_cmd_state, i_avalon_writedata, command_ready)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
argument_reg <= (OTHERS => '0');
|
||||
elsif(rising_edge(i_clock)) then
|
||||
-- Argument register
|
||||
if ((command_ready = '1') and ( i_avalon_writedata(6) = '1')) then
|
||||
argument_reg <= SD_REG_relative_card_address & "0000000000000000";
|
||||
elsif (argument_write = '1') then
|
||||
argument_reg <= i_avalon_writedata;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
o_avalon_readdata <= buffer_data_out_reg when (not (current_state = s_WAIT_REQUEST)) else
|
||||
SD_REG_card_identification_number(31 downto 0) when (i_avalon_address = ADDRESS_CID) else
|
||||
SD_REG_card_identification_number(63 downto 32) when (i_avalon_address = ADDRESS_CID(7 downto 2) & "01") else
|
||||
SD_REG_card_identification_number(95 downto 64) when (i_avalon_address = ADDRESS_CID(7 downto 2) & "10") else
|
||||
SD_REG_card_identification_number(127 downto 96) when (i_avalon_address = ADDRESS_CID(7 downto 2) & "11") else
|
||||
SD_REG_card_specific_data(31 downto 0) when (i_avalon_address = ADDRESS_CSD) else
|
||||
SD_REG_card_specific_data(63 downto 32) when (i_avalon_address = ADDRESS_CSD(7 downto 2) & "01") else
|
||||
SD_REG_card_specific_data(95 downto 64) when (i_avalon_address = ADDRESS_CSD(7 downto 2) & "10") else
|
||||
SD_REG_card_specific_data(127 downto 96) when (i_avalon_address = ADDRESS_CSD(7 downto 2) & "11") else
|
||||
SD_REG_operating_conditions_register when (i_avalon_address = ADDRESS_OCR) else
|
||||
SD_REG_status_register when (i_avalon_address = ADDRESS_SR) else
|
||||
("0000000000000000" & SD_REG_relative_card_address)when (i_avalon_address = ADDRESS_RCA) else
|
||||
argument_reg when (i_avalon_address = ADDRESS_ARGUMENT) else
|
||||
("00000000000000000000000000" & command_ID_reg) when (i_avalon_address = ADDRESS_COMMAND) else
|
||||
SD_REG_response_R1 when (i_avalon_address = ADDRESS_R1) else
|
||||
("00000000000000000000000000" & auxiliary_status_reg);
|
||||
|
||||
-- Instantiated Components
|
||||
SD_Card_Port: Altera_UP_SD_Card_Interface
|
||||
port map
|
||||
(
|
||||
i_clock => i_clock,
|
||||
i_reset_n => i_reset_n,
|
||||
|
||||
-- Command interface
|
||||
b_SD_cmd => b_SD_cmd,
|
||||
b_SD_dat => b_SD_dat,
|
||||
b_SD_dat3 => b_SD_dat3,
|
||||
i_command_ID => command_ID_reg,
|
||||
i_argument => argument_reg,
|
||||
i_user_command_ready => send_command_ready,
|
||||
|
||||
o_SD_clock => o_SD_clock,
|
||||
o_card_connected => card_connected,
|
||||
o_command_completed => command_completed,
|
||||
o_command_valid => command_valid,
|
||||
o_command_timed_out => command_timed_out,
|
||||
o_command_crc_failed => command_crc_failed,
|
||||
|
||||
-- Buffer access
|
||||
i_buffer_enable => buffer_enable,
|
||||
i_buffer_address => buffer_address,
|
||||
i_buffer_write => buffer_write,
|
||||
i_buffer_data_in => buffer_data_in,
|
||||
o_buffer_data_out => buffer_data_out,
|
||||
|
||||
-- Show SD Card registers as outputs
|
||||
o_SD_REG_card_identification_number => SD_REG_card_identification_number,
|
||||
o_SD_REG_relative_card_address => SD_REG_relative_card_address,
|
||||
o_SD_REG_operating_conditions_register => SD_REG_operating_conditions_register,
|
||||
o_SD_REG_card_specific_data => SD_REG_card_specific_data,
|
||||
o_SD_REG_status_register => SD_REG_status_register,
|
||||
o_SD_REG_response_R1 => SD_REG_response_R1,
|
||||
o_SD_REG_status_register_valid => status_reg_valid
|
||||
);
|
||||
|
||||
end rtl;
|
||||
|
|
@ -0,0 +1,382 @@
|
|||
-- (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
-- Your use of Altera Corporation's design tools, logic functions and other
|
||||
-- software and tools, and its AMPP partner logic functions, and any output
|
||||
-- files any of the foregoing (including device programming or simulation
|
||||
-- files), and any associated documentation or information are expressly subject
|
||||
-- to the terms and conditions of the Altera Program License Subscription
|
||||
-- Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
-- license agreement, including, without limitation, that your use is for the
|
||||
-- sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
-- Altera or its authorized distributors. Please refer to the applicable
|
||||
-- agreement for further details.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------
|
||||
-- This module is a dual port memory block. It has a 16-bit port and a 1-bit port.
|
||||
-- The 1-bit port is used to either send or receive data, while the 16-bit port is used
|
||||
-- by Avalon interconnet to store and retrieve data.
|
||||
--
|
||||
-- NOTES/REVISIONS:
|
||||
-------------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity Altera_UP_SD_Card_Buffer is
|
||||
generic (
|
||||
TIMEOUT : std_logic_vector(15 downto 0) := "1111111111111111";
|
||||
BUSY_WAIT : std_logic_vector(15 downto 0) := "0000001111110000"
|
||||
);
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
|
||||
-- 1 bit port to transmit and receive data on the data line.
|
||||
i_begin : in std_logic;
|
||||
i_sd_clock_pulse_trigger : in std_logic;
|
||||
i_transmit : in std_logic;
|
||||
i_1bit_data_in : in std_logic;
|
||||
o_1bit_data_out : out std_logic;
|
||||
o_operation_complete : out std_logic;
|
||||
o_crc_passed : out std_logic;
|
||||
o_timed_out : out std_logic;
|
||||
o_dat_direction : out std_logic; -- set to 1 to send data, set to 0 to receive it.
|
||||
|
||||
-- 16 bit port to be accessed by a user circuit.
|
||||
i_enable_16bit_port : in std_logic;
|
||||
i_address_16bit_port : in std_logic_vector(7 downto 0);
|
||||
i_write_16bit : in std_logic;
|
||||
i_16bit_data_in : in std_logic_vector(15 downto 0);
|
||||
o_16bit_data_out : out std_logic_vector(15 downto 0)
|
||||
);
|
||||
|
||||
end entity;
|
||||
|
||||
architecture rtl of Altera_UP_SD_Card_Buffer is
|
||||
|
||||
component Altera_UP_SD_CRC16_Generator
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_enable : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
i_sync_reset : in std_logic;
|
||||
i_shift : in std_logic;
|
||||
i_datain : in std_logic;
|
||||
o_dataout : out std_logic;
|
||||
o_crcout : out std_logic_vector(15 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component Altera_UP_SD_Card_Memory_Block
|
||||
PORT
|
||||
(
|
||||
address_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
|
||||
address_b : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
|
||||
clock_a : IN STD_LOGIC ;
|
||||
clock_b : IN STD_LOGIC ;
|
||||
data_a : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
|
||||
data_b : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
|
||||
enable_a : IN STD_LOGIC := '1';
|
||||
enable_b : IN STD_LOGIC := '1';
|
||||
wren_a : IN STD_LOGIC := '1';
|
||||
wren_b : IN STD_LOGIC := '1';
|
||||
q_a : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
|
||||
q_b : OUT STD_LOGIC_VECTOR (0 DOWNTO 0)
|
||||
);
|
||||
END component;
|
||||
|
||||
-- Build an enumerated type for the state machine. On reset always reset the DE2 and read the state
|
||||
-- of the switches.
|
||||
type state_type is (s_RESET, s_WAIT_REQUEST, s_SEND_START_BIT, s_SEND_DATA, s_SEND_CRC, s_SEND_STOP, s_WAIT_BUSY, s_WAIT_BUSY_END,
|
||||
s_WAIT_DATA_START, s_RECEIVING_LEADING_BITS, s_RECEIVING_DATA, s_RECEIVING_STOP_BIT, s_WAIT_DEASSERT);
|
||||
|
||||
-- Register to hold the current state
|
||||
signal current_state : state_type;
|
||||
signal next_state : state_type;
|
||||
-- Local wires
|
||||
-- REGISTERED
|
||||
signal crc_counter : std_logic_vector(3 downto 0);
|
||||
signal local_mode : std_logic;
|
||||
signal dataout_1bit : std_logic;
|
||||
signal bit_counter : std_logic_vector(2 downto 0);
|
||||
signal byte_counter : std_logic_vector(8 downto 0);
|
||||
signal shift_register : std_logic_vector(16 downto 0);
|
||||
signal timeout_register : std_logic_vector(15 downto 0);
|
||||
signal data_in_reg : std_logic;
|
||||
-- UNREGISTERED
|
||||
signal crc_out : std_logic_vector(15 downto 0);
|
||||
signal single_bit_conversion, single_bit_out : std_logic_vector( 0 downto 0);
|
||||
signal packet_mem_addr_b : std_logic_vector(11 downto 0);
|
||||
signal local_reset, to_crc_generator, from_crc_generator, from_mem_1_bit, shift_crc,
|
||||
recv_data, crc_generator_enable : std_logic;
|
||||
begin
|
||||
-- State transitions
|
||||
state_transitions: process( current_state, i_begin, i_sd_clock_pulse_trigger, i_transmit, byte_counter,
|
||||
bit_counter, crc_counter, i_1bit_data_in, timeout_register, data_in_reg)
|
||||
begin
|
||||
case (current_state) is
|
||||
when s_RESET =>
|
||||
-- Reset local registers and begin waiting for user input.
|
||||
next_state <= s_WAIT_REQUEST;
|
||||
|
||||
when s_WAIT_REQUEST =>
|
||||
-- Wait for i_begin to be high
|
||||
if ((i_begin = '1') and (i_sd_clock_pulse_trigger = '1')) then
|
||||
if (i_transmit = '1') then
|
||||
next_state <= s_SEND_START_BIT;
|
||||
else
|
||||
next_state <= s_WAIT_DATA_START;
|
||||
end if;
|
||||
else
|
||||
next_state <= s_WAIT_REQUEST;
|
||||
end if;
|
||||
|
||||
when s_SEND_START_BIT =>
|
||||
-- Send a 0 first, followed by 4096 bits of data, 16 CRC bits, and stop bit.
|
||||
if (i_sd_clock_pulse_trigger = '1') then
|
||||
next_state <= s_SEND_DATA;
|
||||
else
|
||||
next_state <= s_SEND_START_BIT;
|
||||
end if;
|
||||
|
||||
when s_SEND_DATA =>
|
||||
-- Send 4096 data bits
|
||||
if ((i_sd_clock_pulse_trigger = '1') and (bit_counter = "000") and (byte_counter = "111111111")) then
|
||||
next_state <= s_SEND_CRC;
|
||||
else
|
||||
next_state <= s_SEND_DATA;
|
||||
end if;
|
||||
|
||||
when s_SEND_CRC =>
|
||||
-- Send 16 CRC bits
|
||||
if ((i_sd_clock_pulse_trigger = '1') and (crc_counter = "1111")) then
|
||||
next_state <= s_SEND_STOP;
|
||||
else
|
||||
next_state <= s_SEND_CRC;
|
||||
end if;
|
||||
|
||||
when s_SEND_STOP =>
|
||||
-- Send stop bit.
|
||||
if (i_sd_clock_pulse_trigger = '1') then
|
||||
next_state <= s_WAIT_BUSY;
|
||||
else
|
||||
next_state <= s_SEND_STOP;
|
||||
end if;
|
||||
|
||||
when s_WAIT_BUSY =>
|
||||
-- After a write, wait for the busy signal. Do not return a done signal until you receive a busy signal.
|
||||
-- If you do not and a long time expires, then the data must have been rejected (due to CRC error maybe).
|
||||
-- In such a case return failure.
|
||||
if ((i_sd_clock_pulse_trigger = '1') and (data_in_reg = '0') and (timeout_register = "0000000000010000")) then
|
||||
next_state <= s_WAIT_BUSY_END;
|
||||
else
|
||||
if (timeout_register = BUSY_WAIT) then
|
||||
next_state <= s_WAIT_DEASSERT;
|
||||
else
|
||||
next_state <= s_WAIT_BUSY;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when s_WAIT_BUSY_END =>
|
||||
if (i_sd_clock_pulse_trigger = '1') then
|
||||
if (data_in_reg = '1') then
|
||||
next_state <= s_WAIT_DEASSERT;
|
||||
else
|
||||
next_state <= s_WAIT_BUSY_END;
|
||||
end if;
|
||||
else
|
||||
next_state <= s_WAIT_BUSY_END;
|
||||
end if;
|
||||
|
||||
when s_WAIT_DATA_START =>
|
||||
-- Wait for the start bit
|
||||
if ((i_sd_clock_pulse_trigger = '1') and (data_in_reg = '0')) then
|
||||
next_state <= s_RECEIVING_LEADING_BITS;
|
||||
else
|
||||
if (timeout_register = TIMEOUT) then
|
||||
next_state <= s_WAIT_DEASSERT;
|
||||
else
|
||||
next_state <= s_WAIT_DATA_START;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when s_RECEIVING_LEADING_BITS =>
|
||||
-- shift the start bit in as well as the next 16 bits. Once they are all in you can start putting data into memory.
|
||||
if ((i_sd_clock_pulse_trigger = '1') and (crc_counter = "1111")) then
|
||||
next_state <= s_RECEIVING_DATA;
|
||||
else
|
||||
next_state <= s_RECEIVING_LEADING_BITS;
|
||||
end if;
|
||||
|
||||
when s_RECEIVING_DATA =>
|
||||
-- Wait until all bits arrive.
|
||||
if ((i_sd_clock_pulse_trigger = '1') and (bit_counter = "000") and (byte_counter = "111111111")) then
|
||||
next_state <= s_RECEIVING_STOP_BIT;
|
||||
else
|
||||
next_state <= s_RECEIVING_DATA;
|
||||
end if;
|
||||
|
||||
when s_RECEIVING_STOP_BIT =>
|
||||
-- Wait until all bits arrive.
|
||||
if (i_sd_clock_pulse_trigger = '1')then
|
||||
next_state <= s_WAIT_DEASSERT;
|
||||
else
|
||||
next_state <= s_RECEIVING_STOP_BIT;
|
||||
end if;
|
||||
|
||||
when s_WAIT_DEASSERT =>
|
||||
if (i_begin = '1') then
|
||||
next_state <= s_WAIT_DEASSERT;
|
||||
else
|
||||
next_state <= s_WAIT_REQUEST;
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
next_state <= s_RESET;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
-- State registers
|
||||
state_regs: process(i_clock, i_reset_n, local_reset)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
current_state <= s_RESET;
|
||||
elsif (rising_edge(i_clock)) then
|
||||
current_state <= next_state;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- FSM outputs
|
||||
to_crc_generator <= shift_register(16) when (current_state = s_RECEIVING_DATA) else
|
||||
from_mem_1_bit when (current_state = s_SEND_DATA) else
|
||||
'0';
|
||||
shift_crc <= '1' when (current_state = s_SEND_CRC) else '0';
|
||||
local_reset <= '1' when ((current_state = s_RESET) or (current_state = s_WAIT_REQUEST)) else '0';
|
||||
recv_data <= '1' when (current_state = s_RECEIVING_DATA) else '0';
|
||||
single_bit_conversion(0) <= shift_register(15);
|
||||
crc_generator_enable <= '0' when (current_state = s_WAIT_DEASSERT) else i_sd_clock_pulse_trigger;
|
||||
o_operation_complete <= '1' when (current_state = s_WAIT_DEASSERT) else '0';
|
||||
o_dat_direction <= '1' when ( (current_state = s_SEND_START_BIT) or
|
||||
(current_state = s_SEND_DATA) or
|
||||
(current_state = s_SEND_CRC) or
|
||||
(current_state = s_SEND_STOP))
|
||||
else '0';
|
||||
o_1bit_data_out <= dataout_1bit;
|
||||
o_crc_passed <= '1' when ((crc_out = shift_register(16 downto 1)) and (shift_register(0) = '1')) else '0';
|
||||
o_timed_out <= '1' when (timeout_register = TIMEOUT) else '0';
|
||||
|
||||
-- Local components
|
||||
local_regs: process(i_clock, i_reset_n, local_reset)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
bit_counter <= (OTHERS => '1');
|
||||
byte_counter <= (OTHERS => '0');
|
||||
dataout_1bit <= '1';
|
||||
crc_counter <= (OTHERS => '0');
|
||||
shift_register <= (OTHERS => '0');
|
||||
elsif (rising_edge(i_clock)) then
|
||||
-- counters and serial output
|
||||
if (local_reset = '1') then
|
||||
bit_counter <= (OTHERS => '1');
|
||||
byte_counter <= (OTHERS => '0');
|
||||
dataout_1bit <= '1';
|
||||
data_in_reg <= '1';
|
||||
crc_counter <= (OTHERS => '0');
|
||||
shift_register <= (OTHERS => '0');
|
||||
elsif (i_sd_clock_pulse_trigger = '1') then
|
||||
if ((not (current_state = s_RECEIVING_LEADING_BITS)) and (not (current_state = s_SEND_CRC))) then
|
||||
crc_counter <= (OTHERS => '0');
|
||||
else
|
||||
if (not (crc_counter = "1111")) then
|
||||
crc_counter <= crc_counter + '1';
|
||||
end if;
|
||||
end if;
|
||||
if ((current_state = s_RECEIVING_DATA) or (current_state = s_SEND_DATA)) then
|
||||
if (not ((bit_counter = "000") and (byte_counter = "111111111"))) then
|
||||
if (bit_counter = "000") then
|
||||
byte_counter <= byte_counter + '1';
|
||||
bit_counter <= "111";
|
||||
else
|
||||
bit_counter <= bit_counter - '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
-- Output data bit.
|
||||
if (current_state = s_SEND_START_BIT) then
|
||||
dataout_1bit <= '0';
|
||||
elsif (current_state = s_SEND_DATA) then
|
||||
dataout_1bit <= from_mem_1_bit;
|
||||
elsif (current_state = s_SEND_CRC) then
|
||||
dataout_1bit <= from_crc_generator;
|
||||
else
|
||||
dataout_1bit <= '1'; -- Stop bit.
|
||||
end if;
|
||||
|
||||
-- Shift register to store the CRC bits once the message is received.
|
||||
if ((current_state = s_RECEIVING_DATA) or
|
||||
(current_state = s_RECEIVING_LEADING_BITS) or
|
||||
(current_state = s_RECEIVING_STOP_BIT)) then
|
||||
shift_register(16 downto 1) <= shift_register(15 downto 0);
|
||||
shift_register(0) <= data_in_reg;
|
||||
end if;
|
||||
data_in_reg <= i_1bit_data_in;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Register holding the timeout value for data transmission.
|
||||
timeout_reg: process(i_clock, i_reset_n, current_state, i_sd_clock_pulse_trigger)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
timeout_register <= (OTHERS => '0');
|
||||
elsif (rising_edge(i_clock)) then
|
||||
if ((current_state = s_SEND_STOP) or
|
||||
(current_state = s_WAIT_REQUEST)) then
|
||||
timeout_register <= (OTHERS => '0');
|
||||
elsif (i_sd_clock_pulse_trigger = '1') then
|
||||
-- Increment the timeout counter
|
||||
if (((current_state = s_WAIT_DATA_START) or
|
||||
(current_state = s_WAIT_BUSY)) and (not (timeout_register = TIMEOUT))) then
|
||||
timeout_register <= timeout_register + '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Instantiated components.
|
||||
crc16_checker: Altera_UP_SD_CRC16_Generator
|
||||
port map
|
||||
(
|
||||
i_clock => i_clock,
|
||||
i_reset_n => i_reset_n,
|
||||
i_sync_reset => local_reset,
|
||||
i_enable => crc_generator_enable,
|
||||
i_shift => shift_crc,
|
||||
i_datain => to_crc_generator,
|
||||
o_dataout => from_crc_generator,
|
||||
o_crcout => crc_out
|
||||
);
|
||||
|
||||
packet_memory: Altera_UP_SD_Card_Memory_Block
|
||||
PORT MAP
|
||||
(
|
||||
address_a => i_address_16bit_port,
|
||||
address_b => packet_mem_addr_b,
|
||||
clock_a => i_clock,
|
||||
clock_b => i_clock,
|
||||
data_a => i_16bit_data_in,
|
||||
data_b => single_bit_conversion,
|
||||
enable_a => i_enable_16bit_port,
|
||||
enable_b => '1',
|
||||
wren_a => i_write_16bit,
|
||||
wren_b => recv_data,
|
||||
q_a => o_16bit_data_out,
|
||||
q_b => single_bit_out
|
||||
);
|
||||
from_mem_1_bit <= single_bit_out(0);
|
||||
packet_mem_addr_b <= (byte_counter & bit_counter);
|
||||
|
||||
end rtl;
|
|
@ -0,0 +1,80 @@
|
|||
-- (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
-- Your use of Altera Corporation's design tools, logic functions and other
|
||||
-- software and tools, and its AMPP partner logic functions, and any output
|
||||
-- files any of the foregoing (including device programming or simulation
|
||||
-- files), and any associated documentation or information are expressly subject
|
||||
-- to the terms and conditions of the Altera Program License Subscription
|
||||
-- Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
-- license agreement, including, without limitation, that your use is for the
|
||||
-- sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
-- Altera or its authorized distributors. Please refer to the applicable
|
||||
-- agreement for further details.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------
|
||||
-- This module is a clock generator for the SD card interface. It takes a 50 MHz
|
||||
-- clock as input and produces a clock signal that depends on the mode in which the
|
||||
-- SD card interface is in. For a card identification mode a clock with a frequency of
|
||||
-- 390.625 kHz is generated. For the data transfer mode, a clock with a frequency of
|
||||
-- 12.5MHz is generated.
|
||||
--
|
||||
-- In addition, the generator produces a clock_mode value that identifies the frequency
|
||||
-- of the o_SD_clock that is currently being generated.
|
||||
--
|
||||
-- NOTES/REVISIONS:
|
||||
-------------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity Altera_UP_SD_Card_Clock is
|
||||
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
i_enable : in std_logic;
|
||||
i_mode : in std_logic; -- 0 for card identification mode, 1 for data transfer mode.
|
||||
o_SD_clock : out std_logic;
|
||||
o_clock_mode : out std_logic;
|
||||
o_trigger_receive : out std_logic;
|
||||
o_trigger_send : out std_logic
|
||||
);
|
||||
|
||||
end entity;
|
||||
|
||||
architecture rtl of Altera_UP_SD_Card_Clock is
|
||||
|
||||
-- Local wires
|
||||
-- REGISTERED
|
||||
signal counter : std_logic_vector(6 downto 0);
|
||||
signal local_mode : std_logic;
|
||||
-- UNREGISTERED
|
||||
begin
|
||||
process(i_clock, i_reset_n)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
counter <= (OTHERS => '0');
|
||||
local_mode <= '0';
|
||||
else
|
||||
if (rising_edge(i_clock)) then
|
||||
if (i_enable = '1') then
|
||||
counter <= counter + '1';
|
||||
end if;
|
||||
-- Change the clock pulse only when at the positive edge of the clock
|
||||
if (counter = "1000000") then
|
||||
local_mode <= i_mode;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
o_clock_mode <= local_mode;
|
||||
o_SD_clock <= counter(6) when (local_mode = '0') else counter(1);
|
||||
o_trigger_receive <= '1' when ((local_mode = '0') and (counter = "0111111")) else
|
||||
((not counter(1)) and (counter(0))) when (local_mode = '1') else '0';
|
||||
o_trigger_send <= '1' when ((local_mode = '0') and (counter = "0011111")) else
|
||||
((counter(1)) and (counter(0))) when (local_mode = '1') else '0';
|
||||
|
||||
end rtl;
|
|
@ -0,0 +1,347 @@
|
|||
-- (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
-- Your use of Altera Corporation's design tools, logic functions and other
|
||||
-- software and tools, and its AMPP partner logic functions, and any output
|
||||
-- files any of the foregoing (including device programming or simulation
|
||||
-- files), and any associated documentation or information are expressly subject
|
||||
-- to the terms and conditions of the Altera Program License Subscription
|
||||
-- Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
-- license agreement, including, without limitation, that your use is for the
|
||||
-- sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
-- Altera or its authorized distributors. Please refer to the applicable
|
||||
-- agreement for further details.
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------
|
||||
-- This is an FSM that controls the SD Card interface circuitry.
|
||||
--
|
||||
-- On reset, the FSM will initiate a predefined set of commands in an attempt to connect to the SD Card.
|
||||
-- When successful, it will allow commands to be issued to the SD Card, otherwise it will return a signal that
|
||||
-- no card is present in the SD Card slot.
|
||||
--
|
||||
-- NOTES/REVISIONS:
|
||||
----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity Altera_UP_SD_Card_Control_FSM is
|
||||
generic (
|
||||
PREDEFINED_COMMAND_GET_STATUS : STD_LOGIC_VECTOR(3 downto 0) := "1001"
|
||||
);
|
||||
port
|
||||
(
|
||||
-- Clock and Reset signals
|
||||
i_clock : in STD_LOGIC;
|
||||
i_reset_n : in STD_LOGIC;
|
||||
|
||||
-- FSM Inputs
|
||||
i_user_command_ready : in std_logic;
|
||||
i_response_received : in STD_LOGIC;
|
||||
i_response_timed_out : in STD_LOGIC;
|
||||
i_response_crc_passed : in STD_LOGIC;
|
||||
i_command_sent : in STD_LOGIC;
|
||||
i_powerup_busy_n : in STD_LOGIC;
|
||||
i_clocking_pulse_enable : in std_logic;
|
||||
i_current_clock_mode : in std_logic;
|
||||
i_user_message_valid : in std_logic;
|
||||
i_last_cmd_was_55 : in std_logic;
|
||||
i_allow_partial_rw : in std_logic;
|
||||
|
||||
-- FSM Outputs
|
||||
o_generate_command : out STD_LOGIC;
|
||||
o_predefined_command_ID : out STD_LOGIC_VECTOR(3 downto 0);
|
||||
o_receive_response : out STD_LOGIC;
|
||||
o_drive_CMD_line : out STD_LOGIC;
|
||||
o_SD_clock_mode : out STD_LOGIC; -- 0 means slow clock for card identification, 1 means fast clock for transfer mode.
|
||||
o_resetting : out std_logic;
|
||||
o_card_connected : out STD_LOGIC;
|
||||
o_command_completed : out std_logic;
|
||||
o_clear_response_register : out std_logic;
|
||||
o_enable_clock_generator : out std_logic
|
||||
);
|
||||
|
||||
end entity;
|
||||
|
||||
architecture rtl of Altera_UP_SD_Card_Control_FSM is
|
||||
|
||||
-- Build an enumerated type for the state machine. On reset always reset the DE2 and read the state
|
||||
-- of the switches.
|
||||
type state_type is (s_RESET, s_WAIT_74_CYCLES, s_GENERATE_PREDEFINED_COMMAND, s_WAIT_PREDEFINED_COMMAND_TRANSMITTED, s_WAIT_PREDEFINED_COMMAND_RESPONSE,
|
||||
s_GO_TO_NEXT_COMMAND, s_TOGGLE_CLOCK_FREQUENCY, s_AWAIT_USER_COMMAND, s_REACTIVATE_CLOCK,
|
||||
s_GENERATE_COMMAND, s_SEND_COMMAND, s_WAIT_RESPONSE, s_WAIT_FOR_CLOCK_EDGE_BEFORE_DISABLE, s_WAIT_DEASSERT,
|
||||
s_PERIODIC_STATUS_CHECK);
|
||||
|
||||
-- Register to hold the current state
|
||||
signal current_state : state_type;
|
||||
signal next_state : state_type;
|
||||
|
||||
-------------------
|
||||
-- Local signals
|
||||
-------------------
|
||||
-- REGISTERED
|
||||
signal SD_clock_mode, waiting_for_vdd_setup : std_logic;
|
||||
signal id_sequence_step_index : std_logic_vector(3 downto 0);
|
||||
signal delay_counter : std_logic_vector(6 downto 0);
|
||||
signal periodic_status_check : std_logic_vector(23 downto 0);
|
||||
-- UNREGISTERED
|
||||
|
||||
begin
|
||||
-- Define state transitions.
|
||||
state_transitions: process (current_state, i_command_sent, i_response_received, id_sequence_step_index,
|
||||
i_response_timed_out, i_response_crc_passed, delay_counter, waiting_for_vdd_setup,
|
||||
i_user_command_ready, i_clocking_pulse_enable, i_current_clock_mode,
|
||||
i_user_message_valid, i_last_cmd_was_55, periodic_status_check)
|
||||
begin
|
||||
case current_state is
|
||||
when s_RESET =>
|
||||
-- Reset local registers and begin identification process.
|
||||
next_state <= s_WAIT_74_CYCLES;
|
||||
|
||||
when s_WAIT_74_CYCLES =>
|
||||
-- Wait 74 cycles before the card can be sent commands to.
|
||||
if (delay_counter = "1001010") then
|
||||
next_state <= s_GENERATE_PREDEFINED_COMMAND;
|
||||
else
|
||||
next_state <= s_WAIT_74_CYCLES;
|
||||
end if;
|
||||
|
||||
when s_GENERATE_PREDEFINED_COMMAND =>
|
||||
-- Generate a predefined command to the SD card. This is the identification process for the SD card.
|
||||
next_state <= s_WAIT_PREDEFINED_COMMAND_TRANSMITTED;
|
||||
|
||||
when s_WAIT_PREDEFINED_COMMAND_TRANSMITTED =>
|
||||
-- Send a predefined command to the SD card. This is the identification process for the SD card.
|
||||
if (i_command_sent = '1') then
|
||||
next_state <= s_WAIT_PREDEFINED_COMMAND_RESPONSE;
|
||||
else
|
||||
next_state <= s_WAIT_PREDEFINED_COMMAND_TRANSMITTED;
|
||||
end if;
|
||||
|
||||
when s_WAIT_PREDEFINED_COMMAND_RESPONSE =>
|
||||
-- Wait for a response from SD card.
|
||||
if (i_response_received = '1') then
|
||||
if (i_response_timed_out = '1') then
|
||||
if (waiting_for_vdd_setup = '1') then
|
||||
next_state <= s_GO_TO_NEXT_COMMAND;
|
||||
else
|
||||
next_state <= s_RESET;
|
||||
end if;
|
||||
else
|
||||
if (i_response_crc_passed = '0') then
|
||||
next_state <= s_GENERATE_PREDEFINED_COMMAND;
|
||||
else
|
||||
next_state <= s_GO_TO_NEXT_COMMAND;
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
next_state <= s_WAIT_PREDEFINED_COMMAND_RESPONSE;
|
||||
end if;
|
||||
|
||||
when s_GO_TO_NEXT_COMMAND =>
|
||||
-- Process the next command in the ID sequence.
|
||||
if (id_sequence_step_index = PREDEFINED_COMMAND_GET_STATUS) then
|
||||
next_state <= s_TOGGLE_CLOCK_FREQUENCY;
|
||||
else
|
||||
next_state <= s_GENERATE_PREDEFINED_COMMAND;
|
||||
end if;
|
||||
|
||||
when s_TOGGLE_CLOCK_FREQUENCY =>
|
||||
-- Now that the card has been initialized, increase the SD card clock frequency to 25MHz.
|
||||
-- Wait for the clock generator to switch operating mode before proceeding further.
|
||||
if (i_current_clock_mode = '1') then
|
||||
next_state <= s_AWAIT_USER_COMMAND;
|
||||
else
|
||||
next_state <= s_TOGGLE_CLOCK_FREQUENCY;
|
||||
end if;
|
||||
|
||||
when s_AWAIT_USER_COMMAND =>
|
||||
-- Wait for the user to send a command to the SD card
|
||||
if (i_user_command_ready = '1') then
|
||||
next_state <= s_REACTIVATE_CLOCK;
|
||||
else
|
||||
-- Every 5 million cycles, or 0.1 of a second.
|
||||
if (periodic_status_check = "010011000100101101000000") then
|
||||
next_state <= s_PERIODIC_STATUS_CHECK;
|
||||
else
|
||||
next_state <= s_AWAIT_USER_COMMAND;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when s_PERIODIC_STATUS_CHECK =>
|
||||
-- Update status every now and then.
|
||||
next_state <= s_GENERATE_PREDEFINED_COMMAND;
|
||||
|
||||
when s_REACTIVATE_CLOCK =>
|
||||
-- Activate the clock signal and wait 8 clock cycles.
|
||||
if (delay_counter = "0001000") then
|
||||
next_state <= s_GENERATE_COMMAND;
|
||||
else
|
||||
next_state <= s_REACTIVATE_CLOCK;
|
||||
end if;
|
||||
|
||||
when s_GENERATE_COMMAND =>
|
||||
-- Generate user command. If valid, proceed further. Otherwise, indicate that the command is invalid.
|
||||
if (i_user_message_valid = '0') then
|
||||
next_state <= s_WAIT_DEASSERT;
|
||||
else
|
||||
next_state <= s_SEND_COMMAND;
|
||||
end if;
|
||||
|
||||
when s_SEND_COMMAND =>
|
||||
-- Wait for the command to be sent.
|
||||
if (i_command_sent = '1') then
|
||||
next_state <= s_WAIT_RESPONSE;
|
||||
else
|
||||
next_state <= s_SEND_COMMAND;
|
||||
end if;
|
||||
|
||||
when s_WAIT_RESPONSE =>
|
||||
-- Wait for the SD card to respond.
|
||||
if (i_response_received = '1') then
|
||||
if (i_response_timed_out = '1') then
|
||||
next_state <= s_WAIT_DEASSERT;
|
||||
else
|
||||
next_state <= s_WAIT_FOR_CLOCK_EDGE_BEFORE_DISABLE;
|
||||
end if;
|
||||
else
|
||||
next_state <= s_WAIT_RESPONSE;
|
||||
end if;
|
||||
|
||||
when s_WAIT_FOR_CLOCK_EDGE_BEFORE_DISABLE =>
|
||||
-- Wait for a positive clock edge before you disable the clock.
|
||||
if (i_clocking_pulse_enable = '1') then
|
||||
next_state <= s_WAIT_DEASSERT;
|
||||
else
|
||||
next_state <= s_WAIT_FOR_CLOCK_EDGE_BEFORE_DISABLE;
|
||||
end if;
|
||||
|
||||
when s_WAIT_DEASSERT =>
|
||||
-- wait for the user to release command generation request.
|
||||
if (i_user_command_ready = '1') then
|
||||
next_state <= s_WAIT_DEASSERT;
|
||||
else
|
||||
if (i_last_cmd_was_55 = '1') then
|
||||
next_state <= s_AWAIT_USER_COMMAND;
|
||||
else
|
||||
-- Send a get status command to obtain the result of sending the last command.
|
||||
next_state <= s_GENERATE_PREDEFINED_COMMAND;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
-- Make sure to start in the reset state if the circuit powers up in an odd state.
|
||||
next_state <= s_RESET;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
-- State registers.
|
||||
state_registers: process (i_clock, i_reset_n)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
current_state <= s_RESET;
|
||||
elsif (rising_edge(i_clock)) then
|
||||
current_state <= next_state;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Local FFs:
|
||||
local_ffs:process ( i_clock, i_reset_n, i_powerup_busy_n, current_state,
|
||||
id_sequence_step_index, i_response_received, i_response_timed_out,
|
||||
i_allow_partial_rw)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
SD_clock_mode <= '0';
|
||||
id_sequence_step_index <= (OTHERS => '0');
|
||||
periodic_status_check <= (OTHERS => '0');
|
||||
waiting_for_vdd_setup <= '0';
|
||||
elsif (rising_edge(i_clock)) then
|
||||
-- Set SD clock mode to 0 initially, thereby using a clock with frequency between 100 kHz and 400 kHz as
|
||||
-- per SD card specifications. When the card is initialized change the clock to run at 25 MHz.
|
||||
if (current_state = s_WAIT_DEASSERT) then
|
||||
periodic_status_check <= (OTHERS => '0');
|
||||
elsif (current_state = s_AWAIT_USER_COMMAND) then
|
||||
periodic_status_check <= periodic_status_check + '1';
|
||||
end if;
|
||||
|
||||
if (current_state = s_RESET) then
|
||||
SD_clock_mode <= '0';
|
||||
elsif (current_state = s_TOGGLE_CLOCK_FREQUENCY) then
|
||||
SD_clock_mode <= '1';
|
||||
end if;
|
||||
-- Update the ID sequence step as needed.
|
||||
if (current_state = s_RESET) then
|
||||
id_sequence_step_index <= (OTHERS => '0');
|
||||
elsif (current_state = s_GO_TO_NEXT_COMMAND) then
|
||||
if ((i_powerup_busy_n = '0') and (id_sequence_step_index = "0010")) then
|
||||
id_sequence_step_index <= "0001";
|
||||
else
|
||||
if (id_sequence_step_index = "0110") then
|
||||
if (i_allow_partial_rw = '0') then
|
||||
-- If partial read-write not allowed, then skip SET_BLK_LEN command - it will fail.
|
||||
id_sequence_step_index <= "1000";
|
||||
else
|
||||
id_sequence_step_index <= "0111";
|
||||
end if;
|
||||
else
|
||||
id_sequence_step_index <= id_sequence_step_index + '1';
|
||||
end if;
|
||||
end if;
|
||||
elsif (current_state = s_WAIT_DEASSERT) then
|
||||
if (i_last_cmd_was_55 = '0') then
|
||||
-- After each command execute a get status command.
|
||||
id_sequence_step_index <= PREDEFINED_COMMAND_GET_STATUS;
|
||||
end if;
|
||||
elsif (current_state = s_PERIODIC_STATUS_CHECK) then
|
||||
id_sequence_step_index <= PREDEFINED_COMMAND_GET_STATUS;
|
||||
end if;
|
||||
|
||||
-- Do not reset the card when SD card is having its VDD set up. Wait for it to respond, this may take some time.
|
||||
if (id_sequence_step_index = "0010") then
|
||||
waiting_for_vdd_setup <= '1';
|
||||
elsif ((id_sequence_step_index = "0011") or (current_state = s_RESET)) then
|
||||
waiting_for_vdd_setup <= '0';
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Counter that counts to 74 to delay any commands.
|
||||
initial_delay_counter: process(i_clock, i_reset_n, i_clocking_pulse_enable )
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
delay_counter <= (OTHERS => '0');
|
||||
elsif (rising_edge(i_clock)) then
|
||||
if ((current_state = s_RESET) or (current_state = s_AWAIT_USER_COMMAND))then
|
||||
delay_counter <= (OTHERS => '0');
|
||||
elsif (((current_state = s_WAIT_74_CYCLES) or (current_state = s_REACTIVATE_CLOCK)) and
|
||||
(i_clocking_pulse_enable = '1')) then
|
||||
delay_counter <= delay_counter + '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- FSM outputs.
|
||||
o_SD_clock_mode <= SD_clock_mode;
|
||||
o_generate_command <= '1' when ((current_state = s_GENERATE_PREDEFINED_COMMAND) or
|
||||
(current_state = s_GENERATE_COMMAND))
|
||||
else '0';
|
||||
o_receive_response <= '1' when ((current_state = s_WAIT_PREDEFINED_COMMAND_RESPONSE) or
|
||||
(current_state = s_WAIT_RESPONSE))
|
||||
else '0';
|
||||
o_drive_CMD_line <= '1' when ( (current_state = s_WAIT_PREDEFINED_COMMAND_TRANSMITTED) or
|
||||
(current_state = s_SEND_COMMAND)) else '0';
|
||||
o_predefined_command_ID <= id_sequence_step_index;
|
||||
o_card_connected <= '1' when (id_sequence_step_index(3) = '1') and (
|
||||
(id_sequence_step_index(2) = '1') or
|
||||
(id_sequence_step_index(1) = '1') or
|
||||
(id_sequence_step_index(0) = '1'))
|
||||
else '0';
|
||||
o_resetting <= '1' when (current_state = s_RESET) else '0';
|
||||
o_command_completed <= '1' when (current_state = s_WAIT_DEASSERT) else '0';
|
||||
o_enable_clock_generator <= '0' when (current_state = s_AWAIT_USER_COMMAND) else '1';
|
||||
o_clear_response_register <= '1' when (current_state = s_REACTIVATE_CLOCK) else '0';
|
||||
|
||||
end rtl;
|
||||
|
|
@ -0,0 +1,518 @@
|
|||
-- (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
-- Your use of Altera Corporation's design tools, logic functions and other
|
||||
-- software and tools, and its AMPP partner logic functions, and any output
|
||||
-- files any of the foregoing (including device programming or simulation
|
||||
-- files), and any associated documentation or information are expressly subject
|
||||
-- to the terms and conditions of the Altera Program License Subscription
|
||||
-- Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
-- license agreement, including, without limitation, that your use is for the
|
||||
-- sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
-- Altera or its authorized distributors. Please refer to the applicable
|
||||
-- agreement for further details.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------
|
||||
-- This module is an interface to the Secure Data Card. This module is intended to be
|
||||
-- used with the DE2 board.
|
||||
--
|
||||
-- This version of the interface supports only a 1-bit serial data transfer. This
|
||||
-- allows the interface to support a MultiMedia card as well.
|
||||
--
|
||||
-- NOTES/REVISIONS:
|
||||
-------------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity Altera_UP_SD_Card_Interface is
|
||||
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
|
||||
-- Command interface
|
||||
b_SD_cmd : inout std_logic;
|
||||
b_SD_dat : inout std_logic;
|
||||
b_SD_dat3 : inout std_logic;
|
||||
i_command_ID : in std_logic_vector(5 downto 0);
|
||||
i_argument : in std_logic_vector(31 downto 0);
|
||||
i_user_command_ready : in std_logic;
|
||||
|
||||
o_SD_clock : out std_logic;
|
||||
o_card_connected : out std_logic;
|
||||
o_command_completed : out std_logic;
|
||||
o_command_valid : out std_logic;
|
||||
o_command_timed_out : out std_logic;
|
||||
o_command_crc_failed : out std_logic;
|
||||
|
||||
-- Buffer access
|
||||
i_buffer_enable : in std_logic;
|
||||
i_buffer_address : in std_logic_vector(7 downto 0);
|
||||
i_buffer_write : in std_logic;
|
||||
i_buffer_data_in : in std_logic_vector(15 downto 0);
|
||||
o_buffer_data_out : out std_logic_vector(15 downto 0);
|
||||
|
||||
-- Show SD Card registers as outputs
|
||||
o_SD_REG_card_identification_number : out std_logic_vector(127 downto 0);
|
||||
o_SD_REG_relative_card_address : out std_logic_vector(15 downto 0);
|
||||
o_SD_REG_operating_conditions_register : out std_logic_vector(31 downto 0);
|
||||
o_SD_REG_card_specific_data : out std_logic_vector(127 downto 0);
|
||||
o_SD_REG_status_register : out std_logic_vector(31 downto 0);
|
||||
o_SD_REG_response_R1 : out std_logic_vector(31 downto 0);
|
||||
o_SD_REG_status_register_valid : out std_logic
|
||||
);
|
||||
|
||||
end entity;
|
||||
|
||||
architecture rtl of Altera_UP_SD_Card_Interface is
|
||||
|
||||
component Altera_UP_SD_Card_Clock
|
||||
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
i_enable : in std_logic;
|
||||
i_mode : in std_logic; -- 0 for card identification mode, 1 for data transfer mode.
|
||||
o_SD_clock : out std_logic;
|
||||
o_clock_mode : out std_logic;
|
||||
o_trigger_receive : out std_logic;
|
||||
o_trigger_send : out std_logic
|
||||
);
|
||||
|
||||
end component;
|
||||
|
||||
component Altera_UP_SD_CRC7_Generator
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_enable : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
i_shift : in std_logic;
|
||||
i_datain : in std_logic;
|
||||
o_dataout : out std_logic;
|
||||
o_crcout : out std_logic_vector(6 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component Altera_UP_SD_CRC16_Generator
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_enable : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
i_shift : in std_logic;
|
||||
i_datain : in std_logic;
|
||||
o_dataout : out std_logic;
|
||||
o_crcout : out std_logic_vector(15 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component Altera_UP_SD_Signal_Trigger
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
i_signal : in std_logic;
|
||||
o_trigger : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component Altera_UP_SD_Card_48_bit_Command_Generator
|
||||
generic (
|
||||
-- Basic commands
|
||||
COMMAND_0_GO_IDLE : STD_LOGIC_VECTOR(5 downto 0) := "000000";
|
||||
COMMAND_2_ALL_SEND_CID : STD_LOGIC_VECTOR(5 downto 0) := "000010";
|
||||
COMMAND_3_SEND_RCA : STD_LOGIC_VECTOR(5 downto 0) := "000011";
|
||||
COMMAND_4_SET_DSR : STD_LOGIC_VECTOR(5 downto 0) := "000100";
|
||||
COMMAND_6_SWITCH_FUNCTION : STD_LOGIC_VECTOR(5 downto 0) := "000110";
|
||||
COMMAND_7_SELECT_CARD : STD_LOGIC_VECTOR(5 downto 0) := "000111";
|
||||
COMMAND_9_SEND_CSD : STD_LOGIC_VECTOR(5 downto 0) := "001001";
|
||||
COMMAND_10_SEND_CID : STD_LOGIC_VECTOR(5 downto 0) := "001010";
|
||||
COMMAND_12_STOP_TRANSMISSION : STD_LOGIC_VECTOR(5 downto 0) := "001100";
|
||||
COMMAND_13_SEND_STATUS : STD_LOGIC_VECTOR(5 downto 0) := "001101";
|
||||
COMMAND_15_GO_INACTIVE : STD_LOGIC_VECTOR(5 downto 0) := "001111";
|
||||
-- Block oriented read/write/lock commands
|
||||
COMMAND_16_SET_BLOCK_LENGTH : STD_LOGIC_VECTOR(5 downto 0) := "010000";
|
||||
-- Block oriented read commands
|
||||
COMMAND_17_READ_BLOCK : STD_LOGIC_VECTOR(5 downto 0) := "010001";
|
||||
COMMAND_18_READ_MULTIPLE_BLOCKS : STD_LOGIC_VECTOR(5 downto 0) := "010010";
|
||||
-- Block oriented write commands
|
||||
COMMAND_24_WRITE_BLOCK : STD_LOGIC_VECTOR(5 downto 0) := "011000";
|
||||
COMMAND_25_WRITE_MULTIPLE_BLOCKS : STD_LOGIC_VECTOR(5 downto 0) := "011001";
|
||||
COMMAND_27_PROGRAM_CSD : STD_LOGIC_VECTOR(5 downto 0) := "011011";
|
||||
-- Block oriented write-protection commands
|
||||
COMMAND_28_SET_WRITE_PROTECT : STD_LOGIC_VECTOR(5 downto 0) := "011100";
|
||||
COMMAND_29_CLEAR_WRITE_PROTECT : STD_LOGIC_VECTOR(5 downto 0) := "011101";
|
||||
COMMAND_30_SEND_PROTECTED_GROUPS : STD_LOGIC_VECTOR(5 downto 0) := "011110";
|
||||
-- Erase commands
|
||||
COMMAND_32_ERASE_BLOCK_START : STD_LOGIC_VECTOR(5 downto 0) := "100000";
|
||||
COMMAND_33_ERASE_BLOCK_END : STD_LOGIC_VECTOR(5 downto 0) := "100001";
|
||||
COMMAND_38_ERASE_SELECTED_GROUPS : STD_LOGIC_VECTOR(5 downto 0) := "100110";
|
||||
-- Block lock commands
|
||||
COMMAND_42_LOCK_UNLOCK : STD_LOGIC_VECTOR(5 downto 0) := "101010";
|
||||
-- Command Type Settings
|
||||
COMMAND_55_APP_CMD : STD_LOGIC_VECTOR(5 downto 0) := "110111";
|
||||
COMMAND_56_GEN_CMD : STD_LOGIC_VECTOR(5 downto 0) := "111000";
|
||||
-- Application Specific commands - must be preceeded with command 55.
|
||||
ACOMMAND_6_SET_BUS_WIDTH : STD_LOGIC_VECTOR(5 downto 0) := "000110";
|
||||
ACOMMAND_13_SD_STATUS : STD_LOGIC_VECTOR(5 downto 0) := "001101";
|
||||
ACOMMAND_22_SEND_NUM_WR_BLOCKS : STD_LOGIC_VECTOR(5 downto 0) := "010100";
|
||||
ACOMMAND_23_SET_BLK_ERASE_COUNT : STD_LOGIC_VECTOR(5 downto 0) := "010101";
|
||||
ACOMMAND_41_SEND_OP_CONDITION : STD_LOGIC_VECTOR(5 downto 0) := "101001";
|
||||
ACOMMAND_42_SET_CLR_CARD_DETECT : STD_LOGIC_VECTOR(5 downto 0) := "101010";
|
||||
ACOMMAND_51_SEND_SCR : STD_LOGIC_VECTOR(5 downto 0) := "110011";
|
||||
-- First custom_command
|
||||
FIRST_NON_PREDEFINED_COMMAND : STD_LOGIC_VECTOR(3 downto 0) := "1010"
|
||||
);
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
i_message_bit_out : in std_logic;
|
||||
i_command_ID : in std_logic_vector(5 downto 0);
|
||||
i_argument : in std_logic_vector(31 downto 0);
|
||||
i_predefined_message : in std_logic_vector(3 downto 0);
|
||||
i_generate : in std_logic;
|
||||
i_DSR : in std_logic_vector(15 downto 0);
|
||||
i_OCR : in std_logic_vector(31 downto 0);
|
||||
i_RCA : in std_logic_vector(15 downto 0);
|
||||
o_dataout : out std_logic;
|
||||
o_message_done : out std_logic;
|
||||
o_valid : out std_logic;
|
||||
o_returning_ocr : out std_logic;
|
||||
o_returning_cid : out std_logic;
|
||||
o_returning_rca : out std_logic;
|
||||
o_returning_csd : out std_logic;
|
||||
o_returning_status : out std_logic;
|
||||
o_data_read : out std_logic;
|
||||
o_data_write : out std_logic;
|
||||
o_wait_cmd_busy : out std_logic;
|
||||
o_last_cmd_was_55 : out std_logic;
|
||||
o_response_type : out std_logic_vector(2 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component Altera_UP_SD_Card_Response_Receiver
|
||||
generic (
|
||||
TIMEOUT : std_logic_vector(7 downto 0) := "00111000";
|
||||
BUSY_WAIT : std_logic_vector(7 downto 0) := "00110000";
|
||||
PROCESSING_DELAY : std_logic_vector(7 downto 0) := "00001000"
|
||||
);
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
i_begin : in std_logic;
|
||||
i_scan_pulse : in std_logic;
|
||||
i_datain : in std_logic;
|
||||
i_wait_cmd_busy : in std_logic;
|
||||
i_response_type : in std_logic_vector(2 downto 0);
|
||||
o_data : out std_logic_vector(127 downto 0);
|
||||
o_CRC_passed : out std_logic;
|
||||
o_timeout : out std_logic;
|
||||
o_done : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component Altera_UP_SD_Card_Control_FSM
|
||||
generic (
|
||||
PREDEFINED_COMMAND_GET_STATUS : STD_LOGIC_VECTOR(3 downto 0) := "1001"
|
||||
);
|
||||
port
|
||||
(
|
||||
-- Clock and Reset signals
|
||||
i_clock : in STD_LOGIC;
|
||||
i_reset_n : in STD_LOGIC;
|
||||
|
||||
-- FSM Inputs
|
||||
i_user_command_ready : in std_logic;
|
||||
i_response_received : in STD_LOGIC;
|
||||
i_response_timed_out : in STD_LOGIC;
|
||||
i_response_crc_passed : in STD_LOGIC;
|
||||
i_command_sent : in STD_LOGIC;
|
||||
i_powerup_busy_n : in STD_LOGIC;
|
||||
i_clocking_pulse_enable : in std_logic;
|
||||
i_current_clock_mode : in std_logic;
|
||||
i_user_message_valid : in std_logic;
|
||||
i_last_cmd_was_55 : in std_logic;
|
||||
i_allow_partial_rw : in std_logic;
|
||||
|
||||
-- FSM Outputs
|
||||
o_generate_command : out STD_LOGIC;
|
||||
o_predefined_command_ID : out STD_LOGIC_VECTOR(3 downto 0);
|
||||
o_receive_response : out STD_LOGIC;
|
||||
o_drive_CMD_line : out STD_LOGIC;
|
||||
o_SD_clock_mode : out STD_LOGIC; -- 0 means slow clock for card identification, 1 means fast clock for transfer mode.
|
||||
o_resetting : out std_logic;
|
||||
o_card_connected : out STD_LOGIC;
|
||||
o_command_completed : out std_logic;
|
||||
o_clear_response_register : out std_logic;
|
||||
o_enable_clock_generator : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component Altera_UP_SD_Card_Buffer
|
||||
generic (
|
||||
TIMEOUT : std_logic_vector(15 downto 0) := "1111111111111111";
|
||||
BUSY_WAIT : std_logic_vector(15 downto 0) := "0000001111110000"
|
||||
);
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
|
||||
-- 1 bit port to transmit and receive data on the data line.
|
||||
i_begin : in std_logic;
|
||||
i_sd_clock_pulse_trigger : in std_logic;
|
||||
i_transmit : in std_logic;
|
||||
i_1bit_data_in : in std_logic;
|
||||
o_1bit_data_out : out std_logic;
|
||||
o_operation_complete : out std_logic;
|
||||
o_crc_passed : out std_logic;
|
||||
o_timed_out : out std_logic;
|
||||
o_dat_direction : out std_logic; -- set to 1 to send data, set to 0 to receive it.
|
||||
|
||||
-- 16 bit port to be accessed by a user circuit.
|
||||
i_enable_16bit_port : in std_logic;
|
||||
i_address_16bit_port : in std_logic_vector(7 downto 0);
|
||||
i_write_16bit : in std_logic;
|
||||
i_16bit_data_in : in std_logic_vector(15 downto 0);
|
||||
o_16bit_data_out : out std_logic_vector(15 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
-- Local wires
|
||||
-- REGISTERED
|
||||
signal sd_mode : std_logic;
|
||||
-- SD Card Registers:
|
||||
signal SD_REG_card_identification_number : std_logic_vector(127 downto 0);
|
||||
signal SD_REG_response_R1 : std_logic_vector(31 downto 0);
|
||||
signal SD_REG_relative_card_address : std_logic_vector(15 downto 0);
|
||||
signal SD_REG_driver_stage_register : std_logic_vector(15 downto 0);
|
||||
signal SD_REG_card_specific_data : std_logic_vector(127 downto 0);
|
||||
signal SD_REG_operating_conditions_register : std_logic_vector(31 downto 0);
|
||||
signal SD_REG_status_register : std_logic_vector(31 downto 0);
|
||||
signal SD_REG_status_register_valid : std_logic;
|
||||
-- UNREGISTERED
|
||||
signal data_from_buffer : std_logic_vector(15 downto 0);
|
||||
signal clock_generator_mode, enable_generator, SD_clock, create_message : std_logic;
|
||||
signal send_next_bit, receive_next_bit : std_logic;
|
||||
signal timed_out, response_done, passed_crc, begin_reading_response, resetting : std_logic;
|
||||
signal returning_cid, returning_rca, returning_csd, returning_ocr : std_logic;
|
||||
signal response_type : std_logic_vector(2 downto 0);
|
||||
signal message_valid, messange_sent, data_to_CMD_line, CMD_tristate_buffer_enable, message_sent : std_logic;
|
||||
signal predef_message_ID : std_logic_vector(3 downto 0);
|
||||
signal receive_data_out : std_logic_vector(127 downto 0);
|
||||
signal data_line_done, data_line_crc, data_line_timeout, data_line_direction, data_line_out : std_logic;
|
||||
signal data_read, data_write, wait_cmd_busy, clear_response_register : std_logic;
|
||||
signal response_done_combined : std_logic;
|
||||
signal timeout_combined : std_logic;
|
||||
signal crc_combined, allow_partial_rw : std_logic;
|
||||
signal begin_data_line_operations, last_cmd_was_55, message_sent_trigger, returning_status : std_logic;
|
||||
signal data_line_sd_clock_pulse_trigger : std_logic;
|
||||
begin
|
||||
-- Glue logic
|
||||
SD_REG_driver_stage_register <= (OTHERS => '0');
|
||||
response_done_combined <= (response_done and (not data_read) and (not data_write)) or
|
||||
(response_done and (data_read or data_write) and data_line_done);
|
||||
timeout_combined <= (timed_out and (not data_read) and (not data_write)) or
|
||||
(timed_out and (data_read or data_write) and data_line_timeout);
|
||||
crc_combined <= (passed_crc and (not data_read) and (not data_write)) or
|
||||
(passed_crc and (data_read or data_write) and data_line_crc);
|
||||
begin_data_line_operations <= (data_read and message_sent) or (data_write and response_done);
|
||||
|
||||
-- Partial read and write are only allowed when both bit 79 (partial read allowed) is high and
|
||||
-- bit 21 (partial write allowed) is high.
|
||||
allow_partial_rw <= SD_REG_card_specific_data(79) and SD_REG_card_specific_data(21);
|
||||
|
||||
-- SD Card control registers
|
||||
control_regs: process (i_clock, i_reset_n)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
SD_REG_operating_conditions_register <= (OTHERS => '0');
|
||||
SD_REG_card_identification_number <= (OTHERS => '0');
|
||||
SD_REG_relative_card_address <= (OTHERS => '0');
|
||||
SD_REG_card_specific_data <= (OTHERS => '0');
|
||||
SD_REG_status_register <= (OTHERS => '0');
|
||||
SD_REG_response_R1 <= (OTHERS => '1');
|
||||
SD_REG_status_register_valid <= '0';
|
||||
elsif (rising_edge(i_clock)) then
|
||||
if ((response_type = "001") and (response_done = '1') and (returning_status = '0') and (clear_response_register = '0')) then
|
||||
SD_REG_response_R1 <= receive_data_out(31 downto 0);
|
||||
elsif (clear_response_register = '1') then
|
||||
SD_REG_response_R1 <= (OTHERS => '1');
|
||||
end if;
|
||||
if (resetting = '1') then
|
||||
SD_REG_operating_conditions_register <= (OTHERS => '0');
|
||||
elsif ((returning_ocr = '1') and (passed_crc = '1') and (response_done = '1') and (timed_out = '0')) then
|
||||
SD_REG_operating_conditions_register <= receive_data_out(31 downto 0);
|
||||
end if;
|
||||
if ((returning_cid = '1') and (passed_crc = '1') and (response_done = '1') and (timed_out = '0')) then
|
||||
SD_REG_card_identification_number <= receive_data_out;
|
||||
end if;
|
||||
if ((returning_rca = '1') and (passed_crc = '1') and (response_done = '1') and (timed_out = '0')) then
|
||||
SD_REG_relative_card_address <= receive_data_out(31 downto 16);
|
||||
end if;
|
||||
if ((returning_csd = '1') and (passed_crc = '1') and (response_done = '1') and (timed_out = '0')) then
|
||||
SD_REG_card_specific_data <= receive_data_out;
|
||||
end if;
|
||||
if (message_sent_trigger = '1') then
|
||||
SD_REG_status_register_valid <= '0';
|
||||
elsif ((returning_status = '1') and (passed_crc = '1') and (response_done = '1') and (timed_out = '0')) then
|
||||
SD_REG_status_register <= receive_data_out(31 downto 0);
|
||||
SD_REG_status_register_valid <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Instantiated components
|
||||
command_generator: Altera_UP_SD_Card_48_bit_Command_Generator PORT MAP
|
||||
(
|
||||
i_clock => i_clock,
|
||||
i_reset_n => i_reset_n,
|
||||
i_message_bit_out => send_next_bit,
|
||||
i_command_ID => i_command_ID,
|
||||
i_argument => i_argument,
|
||||
i_predefined_message => predef_message_ID,
|
||||
i_generate => create_message,
|
||||
i_DSR => SD_REG_driver_stage_register,
|
||||
i_OCR => SD_REG_operating_conditions_register,
|
||||
i_RCA => SD_REG_relative_card_address,
|
||||
o_dataout => data_to_CMD_line,
|
||||
o_message_done => message_sent,
|
||||
o_valid => message_valid,
|
||||
o_returning_ocr => returning_ocr,
|
||||
o_returning_cid => returning_cid,
|
||||
o_returning_rca => returning_rca,
|
||||
o_returning_csd => returning_csd,
|
||||
o_returning_status => returning_status,
|
||||
o_data_read => data_read,
|
||||
o_data_write => data_write,
|
||||
o_wait_cmd_busy => wait_cmd_busy,
|
||||
o_last_cmd_was_55 => last_cmd_was_55,
|
||||
o_response_type => response_type
|
||||
);
|
||||
|
||||
response_receiver: Altera_UP_SD_Card_Response_Receiver PORT MAP
|
||||
(
|
||||
i_clock => i_clock,
|
||||
i_reset_n => i_reset_n,
|
||||
i_begin => begin_reading_response,
|
||||
i_scan_pulse => receive_next_bit,
|
||||
i_datain => b_SD_cmd,
|
||||
i_response_type => response_type,
|
||||
i_wait_cmd_busy => wait_cmd_busy,
|
||||
o_data => receive_data_out,
|
||||
o_CRC_passed => passed_crc,
|
||||
o_timeout => timed_out,
|
||||
o_done => response_done
|
||||
);
|
||||
|
||||
control_FSM: Altera_UP_SD_Card_Control_FSM PORT MAP
|
||||
(
|
||||
-- Clock and Reset signals
|
||||
i_clock => i_clock,
|
||||
i_reset_n => i_reset_n,
|
||||
|
||||
-- FSM Inputs
|
||||
i_user_command_ready => i_user_command_ready,
|
||||
i_clocking_pulse_enable => receive_next_bit,
|
||||
i_response_received => response_done_combined,
|
||||
i_response_timed_out => timeout_combined,
|
||||
i_response_crc_passed => crc_combined,
|
||||
i_command_sent => message_sent,
|
||||
i_powerup_busy_n => SD_REG_operating_conditions_register(31),
|
||||
i_current_clock_mode => clock_generator_mode,
|
||||
i_user_message_valid => message_valid,
|
||||
i_last_cmd_was_55 => last_cmd_was_55,
|
||||
i_allow_partial_rw => allow_partial_rw,
|
||||
|
||||
-- FSM Outputs
|
||||
o_generate_command => create_message,
|
||||
o_predefined_command_ID => predef_message_ID,
|
||||
o_receive_response => begin_reading_response,
|
||||
o_drive_CMD_line => CMD_tristate_buffer_enable,
|
||||
o_SD_clock_mode => sd_mode, -- 0 means slow clock for card identification, 1 means fast clock for transfer mode.
|
||||
o_card_connected => o_card_connected,
|
||||
o_command_completed => o_command_completed,
|
||||
o_resetting => resetting,
|
||||
o_clear_response_register => clear_response_register,
|
||||
o_enable_clock_generator => enable_generator
|
||||
);
|
||||
|
||||
clock_generator: Altera_UP_SD_Card_Clock PORT MAP
|
||||
(
|
||||
i_clock => i_clock,
|
||||
i_reset_n => i_reset_n,
|
||||
i_mode => sd_mode,
|
||||
i_enable => enable_generator,
|
||||
o_SD_clock => SD_clock,
|
||||
o_clock_mode => clock_generator_mode,
|
||||
o_trigger_receive => receive_next_bit,
|
||||
o_trigger_send => send_next_bit
|
||||
);
|
||||
|
||||
SD_clock_pulse_trigger: Altera_UP_SD_Signal_Trigger PORT MAP
|
||||
(
|
||||
i_clock => i_clock,
|
||||
i_reset_n => i_reset_n,
|
||||
i_signal => message_sent,
|
||||
o_trigger => message_sent_trigger
|
||||
);
|
||||
|
||||
data_line: Altera_UP_SD_Card_Buffer
|
||||
port map
|
||||
(
|
||||
i_clock => i_clock,
|
||||
i_reset_n => i_reset_n,
|
||||
|
||||
-- 1 bit port to transmit and receive data on the data line.
|
||||
i_begin => begin_data_line_operations,
|
||||
i_sd_clock_pulse_trigger => data_line_sd_clock_pulse_trigger,
|
||||
i_transmit => data_write,
|
||||
i_1bit_data_in => b_SD_dat,
|
||||
o_1bit_data_out => data_line_out,
|
||||
o_operation_complete => data_line_done,
|
||||
o_crc_passed => data_line_crc,
|
||||
o_timed_out => data_line_timeout,
|
||||
o_dat_direction => data_line_direction,
|
||||
|
||||
-- 16 bit port to be accessed by a user circuit.
|
||||
i_enable_16bit_port => i_buffer_enable,
|
||||
i_address_16bit_port => i_buffer_address,
|
||||
i_write_16bit => i_buffer_write,
|
||||
i_16bit_data_in => i_buffer_data_in,
|
||||
o_16bit_data_out => data_from_buffer
|
||||
);
|
||||
data_line_sd_clock_pulse_trigger <= (data_write and send_next_bit) or ((not data_write) and receive_next_bit);
|
||||
|
||||
-- Buffer output registers.
|
||||
buff_regs: process(i_clock, i_reset_n, data_from_buffer)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
o_buffer_data_out <= (OTHERS=> '0');
|
||||
elsif (rising_edge(i_clock)) then
|
||||
o_buffer_data_out <= data_from_buffer;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Circuit outputs.
|
||||
o_command_valid <= message_valid;
|
||||
o_command_timed_out <= timeout_combined;
|
||||
o_command_crc_failed <= not crc_combined;
|
||||
o_SD_clock <= SD_clock;
|
||||
b_SD_cmd <= data_to_CMD_line when (CMD_tristate_buffer_enable = '1') else 'Z';
|
||||
b_SD_dat <= data_line_out when (data_line_direction = '1') else 'Z';
|
||||
b_SD_dat3 <= 'Z'; -- Set SD card to SD mode.
|
||||
-- SD card registers
|
||||
o_SD_REG_card_identification_number <= SD_REG_card_identification_number;
|
||||
o_SD_REG_relative_card_address <= SD_REG_relative_card_address;
|
||||
o_SD_REG_operating_conditions_register <= SD_REG_operating_conditions_register;
|
||||
o_SD_REG_card_specific_data <= SD_REG_card_specific_data;
|
||||
o_SD_REG_status_register <= SD_REG_status_register;
|
||||
o_SD_REG_response_R1 <= SD_REG_response_R1;
|
||||
o_SD_REG_status_register_valid <= SD_REG_status_register_valid;
|
||||
|
||||
end rtl;
|
|
@ -0,0 +1,296 @@
|
|||
-- (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
-- Your use of Altera Corporation's design tools, logic functions and other
|
||||
-- software and tools, and its AMPP partner logic functions, and any output
|
||||
-- files any of the foregoing (including device programming or simulation
|
||||
-- files), and any associated documentation or information are expressly subject
|
||||
-- to the terms and conditions of the Altera Program License Subscription
|
||||
-- Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
-- license agreement, including, without limitation, that your use is for the
|
||||
-- sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
-- Altera or its authorized distributors. Please refer to the applicable
|
||||
-- agreement for further details.
|
||||
|
||||
|
||||
-- megafunction wizard: %RAM: 2-PORT%
|
||||
-- GENERATION: STANDARD
|
||||
-- VERSION: WM1.0
|
||||
-- MODULE: altsyncram
|
||||
|
||||
-- ============================================================
|
||||
-- File Name: Altera_UP_SD_Card_Memory_Block.vhd
|
||||
-- Megafunction Name(s):
|
||||
-- altsyncram
|
||||
--
|
||||
-- Simulation Library Files(s):
|
||||
-- altera_mf
|
||||
-- ============================================================
|
||||
-- ************************************************************
|
||||
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
--
|
||||
-- 8.0 Build 215 05/29/2008 SJ Full Version
|
||||
-- ************************************************************
|
||||
|
||||
|
||||
--Copyright (C) 1991-2013 Altera Corporation
|
||||
--Your use of Altera Corporation's design tools, logic functions
|
||||
--and other software and tools, and its AMPP partner logic
|
||||
--functions, and any output files from any of the foregoing
|
||||
--(including device programming or simulation files), and any
|
||||
--associated documentation or information are expressly subject
|
||||
--to the terms and conditions of the Altera Program License
|
||||
--Subscription Agreement, Altera MegaCore Function License
|
||||
--Agreement, or other applicable license agreement, including,
|
||||
--without limitation, that your use is for the sole purpose of
|
||||
--programming logic devices manufactured by Altera and sold by
|
||||
--Altera or its authorized distributors. Please refer to the
|
||||
--applicable agreement for further details.
|
||||
|
||||
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.all;
|
||||
|
||||
LIBRARY altera_mf;
|
||||
USE altera_mf.all;
|
||||
|
||||
ENTITY Altera_UP_SD_Card_Memory_Block IS
|
||||
PORT
|
||||
(
|
||||
address_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
|
||||
address_b : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
|
||||
clock_a : IN STD_LOGIC ;
|
||||
clock_b : IN STD_LOGIC ;
|
||||
data_a : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
|
||||
data_b : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
|
||||
enable_a : IN STD_LOGIC := '1';
|
||||
enable_b : IN STD_LOGIC := '1';
|
||||
wren_a : IN STD_LOGIC := '1';
|
||||
wren_b : IN STD_LOGIC := '1';
|
||||
q_a : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
|
||||
q_b : OUT STD_LOGIC_VECTOR (0 DOWNTO 0)
|
||||
);
|
||||
END Altera_UP_SD_Card_Memory_Block;
|
||||
|
||||
|
||||
ARCHITECTURE SYN OF altera_up_sd_card_memory_block IS
|
||||
|
||||
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (15 DOWNTO 0);
|
||||
SIGNAL sub_wire1 : STD_LOGIC_VECTOR (0 DOWNTO 0);
|
||||
|
||||
|
||||
|
||||
COMPONENT altsyncram
|
||||
GENERIC (
|
||||
address_reg_b : STRING;
|
||||
clock_enable_input_a : STRING;
|
||||
clock_enable_input_b : STRING;
|
||||
clock_enable_output_a : STRING;
|
||||
clock_enable_output_b : STRING;
|
||||
indata_reg_b : STRING;
|
||||
init_file : STRING;
|
||||
init_file_layout : STRING;
|
||||
intended_device_family : STRING;
|
||||
lpm_type : STRING;
|
||||
numwords_a : NATURAL;
|
||||
numwords_b : NATURAL;
|
||||
operation_mode : STRING;
|
||||
outdata_aclr_a : STRING;
|
||||
outdata_aclr_b : STRING;
|
||||
outdata_reg_a : STRING;
|
||||
outdata_reg_b : STRING;
|
||||
power_up_uninitialized : STRING;
|
||||
widthad_a : NATURAL;
|
||||
widthad_b : NATURAL;
|
||||
width_a : NATURAL;
|
||||
width_b : NATURAL;
|
||||
width_byteena_a : NATURAL;
|
||||
width_byteena_b : NATURAL;
|
||||
wrcontrol_wraddress_reg_b : STRING
|
||||
);
|
||||
PORT (
|
||||
clocken0 : IN STD_LOGIC ;
|
||||
clocken1 : IN STD_LOGIC ;
|
||||
wren_a : IN STD_LOGIC ;
|
||||
clock0 : IN STD_LOGIC ;
|
||||
wren_b : IN STD_LOGIC ;
|
||||
clock1 : IN STD_LOGIC ;
|
||||
address_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
|
||||
address_b : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
|
||||
q_a : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
|
||||
q_b : OUT STD_LOGIC_VECTOR (0 DOWNTO 0);
|
||||
data_a : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
|
||||
data_b : IN STD_LOGIC_VECTOR (0 DOWNTO 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
BEGIN
|
||||
q_a <= sub_wire0(15 DOWNTO 0);
|
||||
q_b <= sub_wire1(0 DOWNTO 0);
|
||||
|
||||
altsyncram_component : altsyncram
|
||||
GENERIC MAP (
|
||||
address_reg_b => "CLOCK1",
|
||||
clock_enable_input_a => "NORMAL",
|
||||
clock_enable_input_b => "NORMAL",
|
||||
clock_enable_output_a => "BYPASS",
|
||||
clock_enable_output_b => "BYPASS",
|
||||
indata_reg_b => "CLOCK1",
|
||||
init_file => "initial_data.mif",
|
||||
init_file_layout => "PORT_A",
|
||||
intended_device_family => "Cyclone II",
|
||||
lpm_type => "altsyncram",
|
||||
numwords_a => 256,
|
||||
numwords_b => 4096,
|
||||
operation_mode => "BIDIR_DUAL_PORT",
|
||||
outdata_aclr_a => "NONE",
|
||||
outdata_aclr_b => "NONE",
|
||||
outdata_reg_a => "UNREGISTERED",
|
||||
outdata_reg_b => "UNREGISTERED",
|
||||
power_up_uninitialized => "FALSE",
|
||||
widthad_a => 8,
|
||||
widthad_b => 12,
|
||||
width_a => 16,
|
||||
width_b => 1,
|
||||
width_byteena_a => 1,
|
||||
width_byteena_b => 1,
|
||||
wrcontrol_wraddress_reg_b => "CLOCK1"
|
||||
)
|
||||
PORT MAP (
|
||||
clocken0 => enable_a,
|
||||
clocken1 => enable_b,
|
||||
wren_a => wren_a,
|
||||
clock0 => clock_a,
|
||||
wren_b => wren_b,
|
||||
clock1 => clock_b,
|
||||
address_a => address_a,
|
||||
address_b => address_b,
|
||||
data_a => data_a,
|
||||
data_b => data_b,
|
||||
q_a => sub_wire0,
|
||||
q_b => sub_wire1
|
||||
);
|
||||
|
||||
|
||||
|
||||
END SYN;
|
||||
|
||||
-- ============================================================
|
||||
-- CNX file retrieval info
|
||||
-- ============================================================
|
||||
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
|
||||
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRdata NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRq NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRrren NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRwren NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: Clock NUMERIC "5"
|
||||
-- Retrieval info: PRIVATE: Clock_A NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: Clock_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: ECC NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
|
||||
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
|
||||
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
|
||||
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: MEMSIZE NUMERIC "4096"
|
||||
-- Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: MIFfilename STRING "initial_data.mif"
|
||||
-- Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "3"
|
||||
-- Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
|
||||
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
|
||||
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3"
|
||||
-- Retrieval info: PRIVATE: REGdata NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: REGq NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: REGrdaddress NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: REGrren NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: REGwren NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
-- Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: VarWidth NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "16"
|
||||
-- Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "16"
|
||||
-- Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: enable NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: rden NUMERIC "0"
|
||||
-- Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK1"
|
||||
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "NORMAL"
|
||||
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "NORMAL"
|
||||
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
|
||||
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
|
||||
-- Retrieval info: CONSTANT: INDATA_REG_B STRING "CLOCK1"
|
||||
-- Retrieval info: CONSTANT: INIT_FILE STRING "initial_data.mif"
|
||||
-- Retrieval info: CONSTANT: INIT_FILE_LAYOUT STRING "PORT_A"
|
||||
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
|
||||
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
|
||||
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "256"
|
||||
-- Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "4096"
|
||||
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "BIDIR_DUAL_PORT"
|
||||
-- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
|
||||
-- Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
|
||||
-- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
|
||||
-- Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED"
|
||||
-- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
|
||||
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "8"
|
||||
-- Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "12"
|
||||
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "16"
|
||||
-- Retrieval info: CONSTANT: WIDTH_B NUMERIC "1"
|
||||
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
|
||||
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_B NUMERIC "1"
|
||||
-- Retrieval info: CONSTANT: WRCONTROL_WRADDRESS_REG_B STRING "CLOCK1"
|
||||
-- Retrieval info: USED_PORT: address_a 0 0 8 0 INPUT NODEFVAL address_a[7..0]
|
||||
-- Retrieval info: USED_PORT: address_b 0 0 12 0 INPUT NODEFVAL address_b[11..0]
|
||||
-- Retrieval info: USED_PORT: clock_a 0 0 0 0 INPUT NODEFVAL clock_a
|
||||
-- Retrieval info: USED_PORT: clock_b 0 0 0 0 INPUT NODEFVAL clock_b
|
||||
-- Retrieval info: USED_PORT: data_a 0 0 16 0 INPUT NODEFVAL data_a[15..0]
|
||||
-- Retrieval info: USED_PORT: data_b 0 0 1 0 INPUT NODEFVAL data_b[0..0]
|
||||
-- Retrieval info: USED_PORT: enable_a 0 0 0 0 INPUT VCC enable_a
|
||||
-- Retrieval info: USED_PORT: enable_b 0 0 0 0 INPUT VCC enable_b
|
||||
-- Retrieval info: USED_PORT: q_a 0 0 16 0 OUTPUT NODEFVAL q_a[15..0]
|
||||
-- Retrieval info: USED_PORT: q_b 0 0 1 0 OUTPUT NODEFVAL q_b[0..0]
|
||||
-- Retrieval info: USED_PORT: wren_a 0 0 0 0 INPUT VCC wren_a
|
||||
-- Retrieval info: USED_PORT: wren_b 0 0 0 0 INPUT VCC wren_b
|
||||
-- Retrieval info: CONNECT: @data_a 0 0 16 0 data_a 0 0 16 0
|
||||
-- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren_a 0 0 0 0
|
||||
-- Retrieval info: CONNECT: q_a 0 0 16 0 @q_a 0 0 16 0
|
||||
-- Retrieval info: CONNECT: q_b 0 0 1 0 @q_b 0 0 1 0
|
||||
-- Retrieval info: CONNECT: @address_a 0 0 8 0 address_a 0 0 8 0
|
||||
-- Retrieval info: CONNECT: @data_b 0 0 1 0 data_b 0 0 1 0
|
||||
-- Retrieval info: CONNECT: @address_b 0 0 12 0 address_b 0 0 12 0
|
||||
-- Retrieval info: CONNECT: @wren_b 0 0 0 0 wren_b 0 0 0 0
|
||||
-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock_a 0 0 0 0
|
||||
-- Retrieval info: CONNECT: @clocken0 0 0 0 0 enable_a 0 0 0 0
|
||||
-- Retrieval info: CONNECT: @clock1 0 0 0 0 clock_b 0 0 0 0
|
||||
-- Retrieval info: CONNECT: @clocken1 0 0 0 0 enable_b 0 0 0 0
|
||||
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block.vhd TRUE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block.inc FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block.cmp TRUE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block.bsf TRUE FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block_inst.vhd FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block_waveforms.html TRUE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block_wave*.jpg FALSE
|
||||
-- Retrieval info: LIB_FILE: altera_mf
|
|
@ -0,0 +1,308 @@
|
|||
-- (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
-- Your use of Altera Corporation's design tools, logic functions and other
|
||||
-- software and tools, and its AMPP partner logic functions, and any output
|
||||
-- files any of the foregoing (including device programming or simulation
|
||||
-- files), and any associated documentation or information are expressly subject
|
||||
-- to the terms and conditions of the Altera Program License Subscription
|
||||
-- Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
-- license agreement, including, without limitation, that your use is for the
|
||||
-- sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
-- Altera or its authorized distributors. Please refer to the applicable
|
||||
-- agreement for further details.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------
|
||||
-- This module looks at the data on the CMD line and waits to receive a response.
|
||||
-- It begins examining the data lines when the i_begin signal is asserted. It then
|
||||
-- waits for a first '0'. It then proceeds to store as many bits as are required by
|
||||
-- the response packet. Each message bit passes through the CRC7 circuit so that
|
||||
-- the CRC check sum can be verified at the end of transmission. The circuit then produces
|
||||
-- the o_data and o_CRC_passed outputs to indicate the message received and if the CRC
|
||||
-- check passed.
|
||||
--
|
||||
-- If for some reason the requested response does not arrive within 56 clock cycles
|
||||
-- then the circuit will produce a '1' on the o_timeout output. In such a case the
|
||||
-- o_data should be ignored.
|
||||
--
|
||||
-- In case of a response that is not 001, 010, 011 or 110, the circuit expects
|
||||
-- no response.
|
||||
--
|
||||
-- A signal o_done is asserted when the circuit has completed response retrieval. In
|
||||
-- a case when a response is not expected, just wait for the CD Card to process the
|
||||
-- command. This is done by waiting 8 (=PROCESSING_DELAY) clock cycles.
|
||||
--
|
||||
-- NOTES/REVISIONS:
|
||||
-------------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity Altera_UP_SD_Card_Response_Receiver is
|
||||
generic (
|
||||
TIMEOUT : std_logic_vector(7 downto 0) := "00111000";
|
||||
BUSY_WAIT : std_logic_vector(7 downto 0) := "00110000";
|
||||
PROCESSING_DELAY : std_logic_vector(7 downto 0) := "00001000"
|
||||
);
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
i_begin : in std_logic;
|
||||
i_scan_pulse : in std_logic;
|
||||
i_datain : in std_logic;
|
||||
i_wait_cmd_busy : in std_logic;
|
||||
i_response_type : in std_logic_vector(2 downto 0);
|
||||
o_data : out std_logic_vector(127 downto 0);
|
||||
o_CRC_passed : out std_logic;
|
||||
o_timeout : out std_logic;
|
||||
o_done : out std_logic
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture rtl of Altera_UP_SD_Card_Response_Receiver is
|
||||
|
||||
component Altera_UP_SD_CRC7_Generator
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_enable : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
i_shift : in std_logic;
|
||||
i_datain : in std_logic;
|
||||
o_dataout : out std_logic;
|
||||
o_crcout : out std_logic_vector(6 downto 0)
|
||||
);
|
||||
end component;
|
||||
-- Build an enumerated type for the state machine. On reset always reset the DE2 and read the state
|
||||
-- of the switches.
|
||||
type state_type is (s_WAIT_BEGIN, s_WAIT_END, s_WAIT_PROCESSING_DELAY, s_WAIT_BUSY, s_WAIT_BUSY_END, s_WAIT_BEGIN_DEASSERT);
|
||||
|
||||
-- Register to hold the current state
|
||||
signal current_state : state_type;
|
||||
signal next_state : state_type;
|
||||
|
||||
-- Local wires
|
||||
-- REGISTERED
|
||||
signal registered_data_input : std_logic_vector(127 downto 0);
|
||||
signal response_incoming : std_logic;
|
||||
signal counter, timeout_counter : std_logic_vector(7 downto 0);
|
||||
signal crc_shift, keep_reading_bits, shift_crc_bits : std_logic;
|
||||
-- UNREGISTERED
|
||||
signal limit, limit_minus_1 : std_logic_vector(7 downto 0);
|
||||
signal check_crc : std_logic;
|
||||
signal CRC_bits : std_logic_vector(6 downto 0);
|
||||
signal start_reading_bits, operation_complete, enable_crc_unit : std_logic;
|
||||
begin
|
||||
-- Control FSM. Begin operation when i_begin is raised, then wait for the operation to end and i_begin to be deasserted.
|
||||
state_regs: process(i_clock, i_reset_n)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
current_state <= s_WAIT_BEGIN;
|
||||
elsif (rising_edge(i_clock)) then
|
||||
current_state <= next_state;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
state_transitions: process(current_state, i_begin, operation_complete, timeout_counter, i_wait_cmd_busy, i_scan_pulse, i_datain)
|
||||
begin
|
||||
case current_state is
|
||||
when s_WAIT_BEGIN =>
|
||||
if (i_begin = '1') then
|
||||
next_state <= s_WAIT_END;
|
||||
else
|
||||
next_state <= s_WAIT_BEGIN;
|
||||
end if;
|
||||
|
||||
when s_WAIT_END =>
|
||||
if (operation_complete = '1') then
|
||||
if (timeout_counter = TIMEOUT) then
|
||||
next_state <= s_WAIT_BEGIN_DEASSERT;
|
||||
else
|
||||
next_state <= s_WAIT_PROCESSING_DELAY;
|
||||
end if;
|
||||
|
||||
else
|
||||
next_state <= s_WAIT_END;
|
||||
end if;
|
||||
|
||||
when s_WAIT_PROCESSING_DELAY =>
|
||||
if (timeout_counter = PROCESSING_DELAY) then
|
||||
if (i_wait_cmd_busy = '1') then
|
||||
next_state <= s_WAIT_BUSY;
|
||||
else
|
||||
next_state <= s_WAIT_BEGIN_DEASSERT;
|
||||
end if;
|
||||
else
|
||||
next_state <= s_WAIT_PROCESSING_DELAY;
|
||||
end if;
|
||||
|
||||
when s_WAIT_BUSY =>
|
||||
if ((i_scan_pulse = '1') and (i_datain = '0')) then
|
||||
next_state <= s_WAIT_BUSY_END;
|
||||
else
|
||||
if (timeout_counter = BUSY_WAIT) then
|
||||
-- If the card did not become busy, then it would not have raised the optional busy signal.
|
||||
-- In such a case, proceeed further as the command has finished correctly.
|
||||
next_state <= s_WAIT_BEGIN_DEASSERT;
|
||||
else
|
||||
next_state <= s_WAIT_BUSY;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when s_WAIT_BUSY_END =>
|
||||
if ((i_scan_pulse = '1') and (i_datain = '1')) then
|
||||
next_state <= s_WAIT_BEGIN_DEASSERT;
|
||||
else
|
||||
next_state <= s_WAIT_BUSY_END;
|
||||
end if;
|
||||
|
||||
when s_WAIT_BEGIN_DEASSERT =>
|
||||
if (i_begin = '1') then
|
||||
next_state <= s_WAIT_BEGIN_DEASSERT;
|
||||
else
|
||||
next_state <= s_WAIT_BEGIN;
|
||||
end if;
|
||||
when others =>
|
||||
next_state <= s_WAIT_BEGIN;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
-- Store the response as it appears on the i_datain line.
|
||||
received_data_buffer: process (i_clock, i_reset_n)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
registered_data_input <= (OTHERS=>'0');
|
||||
elsif (rising_edge(i_clock)) then
|
||||
-- Only read new data and update the counter value when the scan pulse is high.
|
||||
if (i_scan_pulse = '1') then
|
||||
if ((start_reading_bits = '1') or (keep_reading_bits = '1')) then
|
||||
registered_data_input(127 downto 1) <= registered_data_input(126 downto 0);
|
||||
registered_data_input(0) <= i_datain;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Counter received bits
|
||||
data_read_counter: process (i_clock, i_reset_n)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
counter <= (OTHERS=>'0');
|
||||
elsif (rising_edge(i_clock)) then
|
||||
-- Reset he counter every time you being reading the response.
|
||||
if (current_state = s_WAIT_BEGIN) then
|
||||
counter <= (OTHERS => '0');
|
||||
end if;
|
||||
-- Update the counter value when the scan pulse is high.
|
||||
if (i_scan_pulse = '1') then
|
||||
if ((start_reading_bits = '1') or (keep_reading_bits = '1')) then
|
||||
counter <= counter + '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
operation_complete <= '1' when (((counter = limit) and (not (limit = "00000000"))) or
|
||||
(timeout_counter = TIMEOUT) or
|
||||
((timeout_counter = PROCESSING_DELAY) and (limit = "00000000"))) else '0';
|
||||
|
||||
-- Count the number of scan pulses before the response is received. If the counter
|
||||
-- exceeds TIMEOUT value, then an error must have occured when the SD card received a message.
|
||||
timeout_counter_control: process (i_clock, i_reset_n)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
timeout_counter <= (OTHERS=>'0');
|
||||
elsif (rising_edge(i_clock)) then
|
||||
-- Reset the counter every time you begin reading the response.
|
||||
if ((current_state = s_WAIT_BEGIN) or ((current_state = s_WAIT_END) and (operation_complete = '1') and (not (timeout_counter = TIMEOUT)))) then
|
||||
timeout_counter <= (OTHERS => '0');
|
||||
end if;
|
||||
-- Update the counter value when the scan pulse is high.
|
||||
if (i_scan_pulse = '1') then
|
||||
if (((start_reading_bits = '0') and (keep_reading_bits = '0') and (current_state = s_WAIT_END) and (not (timeout_counter = TIMEOUT))) or
|
||||
(current_state = s_WAIT_PROCESSING_DELAY) or (current_state = s_WAIT_BUSY)) then
|
||||
timeout_counter <= timeout_counter + '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Enable data storing only after you see the first 0.
|
||||
read_enable_logic: process (i_clock, i_reset_n)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
keep_reading_bits <= '0';
|
||||
elsif (rising_edge(i_clock)) then
|
||||
if (i_scan_pulse = '1') then
|
||||
if ((start_reading_bits = '1') or ((keep_reading_bits = '1') and (not (counter = limit_minus_1)))) then
|
||||
keep_reading_bits <= '1';
|
||||
else
|
||||
keep_reading_bits <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
start_reading_bits <= '1' when ((current_state = s_WAIT_END) and (i_datain = '0') and
|
||||
(counter = "00000000") and (not (limit = "00000000"))) else '0';
|
||||
|
||||
-- CRC7 checker.
|
||||
crc_checker: Altera_UP_SD_CRC7_Generator PORT MAP
|
||||
(
|
||||
i_clock => i_clock,
|
||||
i_reset_n => i_reset_n,
|
||||
i_enable => enable_crc_unit,
|
||||
i_shift => shift_crc_bits,
|
||||
i_datain => registered_data_input(7),
|
||||
o_crcout => CRC_bits
|
||||
);
|
||||
enable_crc_unit <= '1' when ((i_scan_pulse = '1') and (current_state = s_WAIT_END)) else '0';
|
||||
|
||||
-- Clear CRC7 registers before processing the response bits
|
||||
crc_control_register: process (i_clock, i_reset_n)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
shift_crc_bits <= '1';
|
||||
elsif (rising_edge(i_clock)) then
|
||||
-- Reset he counter every time you being reading the response.
|
||||
if (current_state = s_WAIT_BEGIN) then
|
||||
-- clear the CRC7 contents before you process the next message.
|
||||
shift_crc_bits <= '1';
|
||||
end if;
|
||||
-- Only read new data and update the counter value when the scan pulse is high.
|
||||
if (i_scan_pulse = '1') then
|
||||
if ((start_reading_bits = '1') or (keep_reading_bits = '1')) then
|
||||
if (counter = "00000111") then
|
||||
-- Once the 7-bits of the CRC checker have been cleared you can process the message and
|
||||
-- compute its CRC bits to verify the validity of the transmission.
|
||||
shift_crc_bits <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Indicate the number of bits to expect in the response packet.
|
||||
limit <= "00110000" when ((i_response_type = "001") or
|
||||
(i_response_type = "011") or
|
||||
(i_response_type = "110")) else
|
||||
"10001000" when (i_response_type = "010") else
|
||||
"00000000"; -- No response
|
||||
limit_minus_1 <=
|
||||
"00101111" when ((i_response_type = "001") or
|
||||
(i_response_type = "011") or
|
||||
(i_response_type = "110")) else
|
||||
"10000111" when (i_response_type = "010") else
|
||||
"00000000"; -- No response
|
||||
|
||||
check_crc <= '1' when ((i_response_type = "001") or (i_response_type = "110")) else '0';
|
||||
|
||||
-- Generate Circuit outputs
|
||||
o_data <= (registered_data_input(127 downto 1) & '1') when (i_response_type = "010") else
|
||||
(CONV_STD_LOGIC_VECTOR(0, 96) & registered_data_input(39 downto 8));
|
||||
|
||||
o_CRC_passed <= '1' when ((check_crc = '0') or
|
||||
((registered_data_input(0) = '1') and (CRC_bits = registered_data_input(7 downto 1)))) else '0';
|
||||
|
||||
o_timeout <= '1' when (timeout_counter = TIMEOUT) else '0';
|
||||
o_done <= '1' when (current_state = s_WAIT_BEGIN_DEASSERT) else '0';
|
||||
end rtl;
|
|
@ -0,0 +1,57 @@
|
|||
-- (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
-- Your use of Altera Corporation's design tools, logic functions and other
|
||||
-- software and tools, and its AMPP partner logic functions, and any output
|
||||
-- files any of the foregoing (including device programming or simulation
|
||||
-- files), and any associated documentation or information are expressly subject
|
||||
-- to the terms and conditions of the Altera Program License Subscription
|
||||
-- Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
-- license agreement, including, without limitation, that your use is for the
|
||||
-- sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
-- Altera or its authorized distributors. Please refer to the applicable
|
||||
-- agreement for further details.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------------------
|
||||
-- This module generates a trigger pulse every time it sees a transition
|
||||
-- from 0 to 1 on signal i_signal.
|
||||
--
|
||||
-- NOTES/REVISIONS:
|
||||
---------------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity Altera_UP_SD_Signal_Trigger is
|
||||
|
||||
port
|
||||
(
|
||||
i_clock : in std_logic;
|
||||
i_reset_n : in std_logic;
|
||||
i_signal : in std_logic;
|
||||
o_trigger : out std_logic
|
||||
);
|
||||
|
||||
end entity;
|
||||
|
||||
architecture rtl of Altera_UP_SD_Signal_Trigger is
|
||||
|
||||
-- Local wires
|
||||
-- REGISTERED
|
||||
signal local_reg : std_logic;
|
||||
begin
|
||||
|
||||
process (i_clock, i_reset_n)
|
||||
begin
|
||||
if (i_reset_n = '0') then
|
||||
local_reg <= '0';
|
||||
else
|
||||
if (rising_edge(i_clock)) then
|
||||
local_reg <= i_signal;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
o_trigger <= '1' when ((local_reg = '0') and (i_signal = '1'))
|
||||
else '0';
|
||||
end rtl;
|
|
@ -0,0 +1,99 @@
|
|||
/* these test were created to show how to use the opencores I2C along with a driver found in
|
||||
* the I2C_opencores component to talk to various components.
|
||||
* This test example uses a littel daughter board from microtronix
|
||||
* it has a I2c to parallel chip (PCA9554A) a EEPORM and real time clock.
|
||||
* I chose not to impliment the real time clock.
|
||||
* But you can see how the calls work
|
||||
* There are only 4 functions associalted with the I2C driver
|
||||
* I2C start - send start bit and address of the chip
|
||||
* I2C_read - read data
|
||||
* I2C_write. - write data
|
||||
* how and when each of these get used is based on the device you
|
||||
* are talking to.
|
||||
* See the driver code for details of each function.
|
||||
* */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "system.h"
|
||||
#include "i2c_opencores.h"
|
||||
int main()
|
||||
{
|
||||
int data;
|
||||
int i;
|
||||
// testing the PCA9554A paralle interface
|
||||
// this writes a 5 to the leds and read the position of the dip switches.
|
||||
printf(" tesing the PCA9554A interface the\n the LEDS should be at a 5 \n");
|
||||
// address 0x38
|
||||
// set the fequesncy that you want to run at
|
||||
// most devices work at 100Khz some faster
|
||||
I2C_init(I2CA_BASE,ALT_CPU_FREQ,100000);
|
||||
I2C_init(I2CA_BASE,ALT_CPU_FREQ,100000);
|
||||
// for the parallel io only the first 4 are output s
|
||||
|
||||
// the PCA9554A uses a command word right after the chip address word ( the start work)
|
||||
I2C_start(I2CA_BASE,0x38,0);// chip address in write mode
|
||||
I2C_write(I2CA_BASE,3,0); // write to register 3 command
|
||||
I2C_write(I2CA_BASE,0xf0,1); // set the bottom 4 bits to outputs for the LEDs set the stop
|
||||
|
||||
// now right to the leds
|
||||
I2C_start(I2CA_BASE,0x38,0); // address the chip in write mode
|
||||
I2C_write(I2CA_BASE,1,0); // set command to the pca9554 to be output register
|
||||
I2C_write(I2CA_BASE,5,1); // write the data to the output register and set the stop
|
||||
|
||||
//now read the dip switches
|
||||
// first set the command to 0
|
||||
I2C_start(I2CA_BASE,0x38,0); //address the chip in write mode
|
||||
data = I2C_write(I2CA_BASE,0,0); // set command to read input register.
|
||||
I2C_start(I2CA_BASE,0x38,1); //send start again but this time in read mode
|
||||
data = I2C_read(I2CA_BASE,1); // read the input register and send stop
|
||||
data = 0xff & (data >>4);
|
||||
printf("dip switch 0x%x\n",data);
|
||||
|
||||
printf("\nNow writing and reading from the EEPROM\n");
|
||||
//address 0x50-57
|
||||
I2C_start(I2CA_BASE,0x50,0); // chip address in write mode
|
||||
I2C_write(I2CA_BASE,0,0); // write to starting address of 0
|
||||
// now write the data
|
||||
for (i=0;i<7;i++) // can only write 8 bites at a time
|
||||
{
|
||||
I2C_write(I2CA_BASE,i,0); // writ the data
|
||||
}
|
||||
I2C_write(I2CA_BASE,i,1); // write last one with last flag
|
||||
|
||||
while ( I2C_start(I2CA_BASE,0x50,0)); // make sure the write is done be fore continuing.
|
||||
// can ony burst 8 at a time.
|
||||
|
||||
I2C_write(I2CA_BASE,8,0); // write to starting address of 8
|
||||
// now write the data
|
||||
for (i=0;i<7;i++) // write the next 8 bytes
|
||||
{
|
||||
I2C_write(I2CA_BASE,i+8,0); //
|
||||
}
|
||||
I2C_write(I2CA_BASE,i+8,1); // write last one with last flag
|
||||
|
||||
while ( I2C_start(I2CA_BASE,0x50,0)); // make sure the write is done be fore continuing.
|
||||
|
||||
//now read the values
|
||||
// first set the command to 0
|
||||
I2C_start(I2CA_BASE,0x50,0); //set chip address and set to write/
|
||||
I2C_write(I2CA_BASE,0,0); // set address to 0.
|
||||
I2C_start(I2CA_BASE,0x50,1); //set chip address in read mode
|
||||
for (i=0;i<15;i++)
|
||||
{
|
||||
data = I2C_read(I2CA_BASE,0); // memory array
|
||||
printf("\tdata = 0x%x\n",data);
|
||||
}
|
||||
|
||||
data = I2C_read(I2CA_BASE,1); // last memory read
|
||||
printf("\tdata = 0x%x\n",data);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
printf("Hello from Nios II!\n");
|
||||
|
||||
return 0;
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,33 @@
|
|||
#ifndef __I2C_OPENCORES_H__
|
||||
#define __I2C_OPENCORES_H__
|
||||
|
||||
|
||||
#include "alt_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
|
||||
|
||||
void I2C_init(alt_u32 base,alt_u32 clk,alt_u32 speed);
|
||||
int I2C_start(alt_u32 base, alt_u32 add, alt_u32 read);
|
||||
alt_u32 I2C_read(alt_u32 base,alt_u32 last);
|
||||
alt_u32 I2C_write(alt_u32 base,alt_u8 data, alt_u32 last);
|
||||
alt_u32 SPI_read(alt_u32 base);
|
||||
void SPI_write(alt_u32 base,alt_u8 data);
|
||||
#define I2C_OK (0)
|
||||
#define I2C_ACK (0)
|
||||
#define I2C_NOACK (1)
|
||||
#define I2C_ABITRATION_LOST (2)
|
||||
|
||||
#define I2C_OPENCORES_INSTANCE(name, dev) extern int alt_no_storage
|
||||
#define I2C_OPENCORES_INIT(name, dev) while (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __I2C_OPENCORES_H__ */
|
|
@ -0,0 +1,38 @@
|
|||
# *******************************************************************************
|
||||
# * *
|
||||
# * License Agreement *
|
||||
# * *
|
||||
# * Copyright (c) 2003 Altera Corporation, San Jose, California, USA. *
|
||||
# * All rights reserved. *
|
||||
# * *
|
||||
# * Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
# * copy of this software and associated documentation files (the "Software"), *
|
||||
# * to deal in the Software without restriction, including without limitation *
|
||||
# * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
|
||||
# * and/or sell copies of the Software, and to permit persons to whom the *
|
||||
# * Software is furnished to do so, subject to the following conditions: *
|
||||
# * *
|
||||
# * The above copyright notice and this permission notice shall be included in *
|
||||
# * all copies or substantial portions of the Software. *
|
||||
# * *
|
||||
# * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
|
||||
# * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
|
||||
# * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
||||
# * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
|
||||
# * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
|
||||
# * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
|
||||
# * DEALINGS IN THE SOFTWARE. *
|
||||
# * *
|
||||
# * This agreement shall be governed in all respects by the laws of the State *
|
||||
# * of California and by the laws of the United States of America. *
|
||||
# * *
|
||||
# * Altera does not recommend, suggest or require that this reference design *
|
||||
# * file be used in conjunction or combination with any other product. *
|
||||
# *******************************************************************************
|
||||
|
||||
# List all source files supplied by this component.
|
||||
|
||||
C_LIB_SRCS += i2c_opencores.c
|
||||
|
||||
ASM_LIB_SRCS +=
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
|
||||
#include "alt_types.h"
|
||||
#include "i2c_opencores_regs.h"
|
||||
#include "i2c_opencores.h"
|
||||
|
||||
// #define I2C_DEBUG
|
||||
//int I2C_init(alt_u32 base,alt_u32 clk, alt_u32 speed)
|
||||
//int I2C_start(alt_u32 base, alt_u32 add, alt_u32 write);
|
||||
//alt_u32 I2C_read(alt_u32 base);
|
||||
//int I2C_write(alt_u32 base, alt_u8 data);
|
||||
//int I2C_stop(alt_u32 base);
|
||||
|
||||
/* these functions are polled only. */
|
||||
/* all functions wait until the I2C is done before exiting */
|
||||
|
||||
|
||||
/****************************************************************
|
||||
int I2C_init
|
||||
This function inititlizes the prescalor for the scl
|
||||
and then enables the core. This must be run before
|
||||
any other i2c code is executed
|
||||
inputs
|
||||
base = the base address of the component
|
||||
clk = freuqency of the clock driving this component ( in Hz)
|
||||
speed = SCL speed ie 100K, 400K ... (in Hz)
|
||||
15-OCT-07 initial release
|
||||
*****************************************************************/
|
||||
void I2C_init(alt_u32 base,alt_u32 clk,alt_u32 speed)
|
||||
{
|
||||
alt_u32 prescale = (clk/( 5 * speed))-1;
|
||||
#ifdef I2C_DEBUG
|
||||
printf(" Initializing I2C at 0x%x, \n\twith clock speed 0x%x \n\tand SCL speed 0x%x \n\tand prescale 0x%x\n",base,clk,speed,prescale);
|
||||
#endif
|
||||
IOWR_I2C_OPENCORES_CTR(base, 0x00); /* turn off the core*/
|
||||
|
||||
IOWR_I2C_OPENCORES_CR(base, I2C_OPENCORES_CR_IACK_MSK); /* clearn any pening IRQ*/
|
||||
|
||||
IOWR_I2C_OPENCORES_PRERLO(base, (0xff & prescale)); /* load low presacle bit*/
|
||||
|
||||
IOWR_I2C_OPENCORES_PRERHI(base, (0xff & (prescale>>8))); /* load upper prescale bit */
|
||||
|
||||
IOWR_I2C_OPENCORES_CTR(base, I2C_OPENCORES_CTR_EN_MSK); /* turn on the core*/
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
int I2C_start
|
||||
Sets the start bit and then sends the first byte which
|
||||
is the address of the device + the write bit.
|
||||
inputs
|
||||
base = the base address of the component
|
||||
add = address of I2C device
|
||||
read = 1== read 0== write
|
||||
return value
|
||||
0 if address is acknowledged
|
||||
1 if address was not acknowledged
|
||||
15-OCT-07 initial release
|
||||
*****************************************************************/
|
||||
int I2C_start(alt_u32 base, alt_u32 add, alt_u32 read)
|
||||
{
|
||||
#ifdef I2C_DEBUG
|
||||
printf(" Start I2C at 0x%x, \n\twith address 0x%x \n\tand read 0x%x \n\tand prescale 0x%x\n",base,add,read);
|
||||
#endif
|
||||
|
||||
/* transmit the address shifted by one and the read/write bit*/
|
||||
IOWR_I2C_OPENCORES_TXR(base, ((add<<1) + (0x1 & read)));
|
||||
|
||||
/* set start and write bits which will start the transaction*/
|
||||
IOWR_I2C_OPENCORES_CR(base, I2C_OPENCORES_CR_STA_MSK | I2C_OPENCORES_CR_WR_MSK );
|
||||
|
||||
/* wait for the trnasaction to be over.*/
|
||||
while( IORD_I2C_OPENCORES_SR(base) & I2C_OPENCORES_SR_TIP_MSK);
|
||||
|
||||
/* now check to see if the address was acknowledged */
|
||||
if(IORD_I2C_OPENCORES_SR(base) & I2C_OPENCORES_SR_RXNACK_MSK)
|
||||
{
|
||||
#ifdef I2C_DEBUG
|
||||
printf("\tNOACK\n");
|
||||
#endif
|
||||
return (I2C_NOACK);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef I2C_DEBUG
|
||||
printf("\tACK\n");
|
||||
#endif
|
||||
return (I2C_ACK);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
int I2C_read
|
||||
assumes that any addressing and start
|
||||
has already been done.
|
||||
reads one byte of data from the slave. on the last read
|
||||
we don't acknowldge and set the stop bit.
|
||||
inputs
|
||||
base = the base address of the component
|
||||
last = on the last read there must not be a ack
|
||||
|
||||
return value
|
||||
byte read back.
|
||||
15-OCT-07 initial release
|
||||
*****************************************************************/
|
||||
alt_u32 I2C_read(alt_u32 base,alt_u32 last)
|
||||
{
|
||||
#ifdef I2C_DEBUG
|
||||
printf(" Read I2C at 0x%x, \n\twith last0x%x\n",base,last);
|
||||
#endif
|
||||
if( last)
|
||||
{
|
||||
/* start a read and no ack and stop bit*/
|
||||
IOWR_I2C_OPENCORES_CR(base, I2C_OPENCORES_CR_RD_MSK |
|
||||
I2C_OPENCORES_CR_NACK_MSK | I2C_OPENCORES_CR_STO_MSK);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* start read*/
|
||||
IOWR_I2C_OPENCORES_CR(base, I2C_OPENCORES_CR_RD_MSK );
|
||||
}
|
||||
/* wait for the trnasaction to be over.*/
|
||||
while( IORD_I2C_OPENCORES_SR(base) & I2C_OPENCORES_SR_TIP_MSK);
|
||||
|
||||
/* now read the data */
|
||||
return (IORD_I2C_OPENCORES_RXR(base));
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
int I2C_write
|
||||
assumes that any addressing and start
|
||||
has already been done.
|
||||
writes one byte of data from the slave.
|
||||
If last is set the stop bit set.
|
||||
inputs
|
||||
base = the base address of the component
|
||||
data = byte to write
|
||||
last = on the last read there must not be a ack
|
||||
|
||||
return value
|
||||
0 if address is acknowledged
|
||||
1 if address was not acknowledged
|
||||
15-OCT-07 initial release
|
||||
*****************************************************************/
|
||||
alt_u32 I2C_write(alt_u32 base,alt_u8 data, alt_u32 last)
|
||||
{
|
||||
#ifdef I2C_DEBUG
|
||||
printf(" Read I2C at 0x%x, \n\twith data 0x%x,\n\twith last0x%x\n",base,data,last);
|
||||
#endif
|
||||
/* transmit the data*/
|
||||
IOWR_I2C_OPENCORES_TXR(base, data);
|
||||
|
||||
if( last)
|
||||
{
|
||||
/* start a write with ack and stop bit*/
|
||||
IOWR_I2C_OPENCORES_CR(base, I2C_OPENCORES_CR_WR_MSK |
|
||||
I2C_OPENCORES_CR_STO_MSK);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* start write with ack */
|
||||
IOWR_I2C_OPENCORES_CR(base, I2C_OPENCORES_CR_WR_MSK );
|
||||
}
|
||||
/* wait for the trnasaction to be over.*/
|
||||
while( IORD_I2C_OPENCORES_SR(base) & I2C_OPENCORES_SR_TIP_MSK);
|
||||
|
||||
/* now check to see if the address was acknowledged */
|
||||
if(IORD_I2C_OPENCORES_SR(base) & I2C_OPENCORES_SR_RXNACK_MSK)
|
||||
{
|
||||
#ifdef I2C_DEBUG
|
||||
printf("\tNOACK\n");
|
||||
#endif
|
||||
return (I2C_NOACK);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef I2C_DEBUG
|
||||
printf("\tACK\n");
|
||||
#endif
|
||||
return (I2C_ACK);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
alt_u32 SPI_read(alt_u32 base)
|
||||
{
|
||||
/* start read*/
|
||||
IOWR_I2C_OPENCORES_CR(base, I2C_OPENCORES_CR_RD_MSK|I2C_OPENCORES_CR_NACK_MSK|I2C_OPENCORES_CR_SPIM_MSK );
|
||||
|
||||
/* wait for the trnasaction to be over.*/
|
||||
while( IORD_I2C_OPENCORES_SR(base) & I2C_OPENCORES_SR_TIP_MSK);
|
||||
|
||||
/* now read the data */
|
||||
return (IORD_I2C_OPENCORES_RXR(base));
|
||||
}
|
||||
|
||||
void SPI_write(alt_u32 base,alt_u8 data) {
|
||||
/* transmit the data*/
|
||||
IOWR_I2C_OPENCORES_TXR(base, data);
|
||||
|
||||
/* start write */
|
||||
IOWR_I2C_OPENCORES_CR(base, I2C_OPENCORES_CR_WR_MSK|I2C_OPENCORES_CR_NACK_MSK|I2C_OPENCORES_CR_SPIM_MSK );
|
||||
|
||||
/* wait for the trnasaction to be over.*/
|
||||
while( IORD_I2C_OPENCORES_SR(base) & I2C_OPENCORES_SR_TIP_MSK);
|
||||
}
|
|
@ -0,0 +1,621 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE rev.B2 compliant I2C Master bit-controller ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// www.asics.ws ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2001 Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: i2c_master_bit_ctrl.v,v 1.11 2004/05/07 11:02:26 rherveille Exp $
|
||||
//
|
||||
// $Date: 2004/05/07 11:02:26 $
|
||||
// $Revision: 1.11 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: i2c_master_bit_ctrl.v,v $
|
||||
// Revision 1.11 2004/05/07 11:02:26 rherveille
|
||||
// Fixed a bug where the core would signal an arbitration lost (AL bit set), when another master controls the bus and the other master generates a STOP bit.
|
||||
//
|
||||
// Revision 1.10 2003/08/09 07:01:33 rherveille
|
||||
// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
|
||||
// Fixed a potential bug in the byte controller's host-acknowledge generation.
|
||||
//
|
||||
// Revision 1.9 2003/03/10 14:26:37 rherveille
|
||||
// Fixed cmd_ack generation item (no bug).
|
||||
//
|
||||
// Revision 1.8 2003/02/05 00:06:10 rherveille
|
||||
// Fixed a bug where the core would trigger an erroneous 'arbitration lost' interrupt after being reset, when the reset pulse width < 3 clk cycles.
|
||||
//
|
||||
// Revision 1.7 2002/12/26 16:05:12 rherveille
|
||||
// Small code simplifications
|
||||
//
|
||||
// Revision 1.6 2002/12/26 15:02:32 rherveille
|
||||
// Core is now a Multimaster I2C controller
|
||||
//
|
||||
// Revision 1.5 2002/11/30 22:24:40 rherveille
|
||||
// Cleaned up code
|
||||
//
|
||||
// Revision 1.4 2002/10/30 18:10:07 rherveille
|
||||
// Fixed some reported minor start/stop generation timing issuess.
|
||||
//
|
||||
// Revision 1.3 2002/06/15 07:37:03 rherveille
|
||||
// Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment.
|
||||
//
|
||||
// Revision 1.2 2001/11/05 11:59:25 rherveille
|
||||
// Fixed wb_ack_o generation bug.
|
||||
// Fixed bug in the byte_controller statemachine.
|
||||
// Added headers.
|
||||
//
|
||||
|
||||
//
|
||||
/////////////////////////////////////
|
||||
// Bit controller section
|
||||
/////////////////////////////////////
|
||||
//
|
||||
// Translate simple commands into SCL/SDA transitions
|
||||
// Each command has 5 states, A/B/C/D/idle
|
||||
//
|
||||
// start: SCL ~~~~~~~~~~\____
|
||||
// SDA ~~~~~~~~\______
|
||||
// x | A | B | C | D | i
|
||||
//
|
||||
// repstart SCL ____/~~~~\___
|
||||
// SDA __/~~~\______
|
||||
// x | A | B | C | D | i
|
||||
//
|
||||
// stop SCL ____/~~~~~~~~
|
||||
// SDA ==\____/~~~~~
|
||||
// x | A | B | C | D | i
|
||||
//
|
||||
//- write SCL ____/~~~~\____
|
||||
// SDA ==X=========X=
|
||||
// x | A | B | C | D | i
|
||||
//
|
||||
//- read SCL ____/~~~~\____
|
||||
// SDA XXXX=====XXXX
|
||||
// x | A | B | C | D | i
|
||||
//
|
||||
|
||||
// Timing: Normal mode Fast mode
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Fscl 100KHz 400KHz
|
||||
// Th_scl 4.0us 0.6us High period of SCL
|
||||
// Tl_scl 4.7us 1.3us Low period of SCL
|
||||
// Tsu:sta 4.7us 0.6us setup time for a repeated start condition
|
||||
// Tsu:sto 4.0us 0.6us setup time for a stop conditon
|
||||
// Tbuf 4.7us 1.3us Bus free time between a stop and start condition
|
||||
//
|
||||
|
||||
// synopsys translate_off
|
||||
`include "timescale.v"
|
||||
// synopsys translate_on
|
||||
|
||||
`include "i2c_master_defines.v"
|
||||
|
||||
module i2c_master_bit_ctrl(
|
||||
clk, rst, nReset,
|
||||
clk_cnt, ena, cmd, cmd_ack, busy, al, din, dout,
|
||||
scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen
|
||||
);
|
||||
|
||||
//
|
||||
// inputs & outputs
|
||||
//
|
||||
input clk;
|
||||
input rst;
|
||||
input nReset;
|
||||
input ena; // core enable signal
|
||||
|
||||
input [15:0] clk_cnt; // clock prescale value
|
||||
|
||||
input [5:0] cmd;
|
||||
output cmd_ack; // command complete acknowledge
|
||||
reg cmd_ack;
|
||||
output busy; // i2c bus busy
|
||||
reg busy;
|
||||
output al; // i2c bus arbitration lost
|
||||
reg al;
|
||||
|
||||
input din;
|
||||
output dout;
|
||||
reg dout;
|
||||
|
||||
// I2C lines
|
||||
input scl_i; // i2c clock line input
|
||||
output scl_o; // i2c clock line output
|
||||
output scl_oen; // i2c clock line output enable (active low)
|
||||
reg scl_oen;
|
||||
input sda_i; // i2c data line input
|
||||
output sda_o; // i2c data line output
|
||||
output sda_oen; // i2c data line output enable (active low)
|
||||
reg sda_oen;
|
||||
|
||||
|
||||
//
|
||||
// variable declarations
|
||||
//
|
||||
|
||||
reg sSCL, sSDA; // synchronized SCL and SDA inputs
|
||||
reg dscl_oen; // delayed scl_oen
|
||||
reg sda_chk; // check SDA output (Multi-master arbitration)
|
||||
reg clk_en; // clock generation signals
|
||||
wire slave_wait;
|
||||
// reg [15:0] cnt = clk_cnt; // clock divider counter (simulation)
|
||||
reg [15:0] cnt; // clock divider counter (synthesis)
|
||||
|
||||
// state machine variable
|
||||
reg [24:0] c_state;
|
||||
|
||||
//
|
||||
// module body
|
||||
//
|
||||
|
||||
// whenever the slave is not ready it can delay the cycle by pulling SCL low
|
||||
// delay scl_oen
|
||||
always @(posedge clk)
|
||||
dscl_oen <= #1 scl_oen;
|
||||
|
||||
assign slave_wait = dscl_oen && !sSCL;
|
||||
|
||||
|
||||
// generate clk enable signal
|
||||
always @(posedge clk or negedge nReset)
|
||||
if(~nReset)
|
||||
begin
|
||||
cnt <= #1 16'h0;
|
||||
clk_en <= #1 1'b1;
|
||||
end
|
||||
else if (rst)
|
||||
begin
|
||||
cnt <= #1 16'h0;
|
||||
clk_en <= #1 1'b1;
|
||||
end
|
||||
else if ( ~|cnt || ~ena)
|
||||
if (~slave_wait)
|
||||
begin
|
||||
cnt <= #1 clk_cnt;
|
||||
clk_en <= #1 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
cnt <= #1 cnt;
|
||||
clk_en <= #1 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
cnt <= #1 cnt - 16'h1;
|
||||
clk_en <= #1 1'b0;
|
||||
end
|
||||
|
||||
|
||||
// generate bus status controller
|
||||
reg dSCL, dSDA;
|
||||
reg sta_condition;
|
||||
reg sto_condition;
|
||||
|
||||
// synchronize SCL and SDA inputs
|
||||
// reduce metastability risc
|
||||
always @(posedge clk or negedge nReset)
|
||||
if (~nReset)
|
||||
begin
|
||||
sSCL <= #1 1'b1;
|
||||
sSDA <= #1 1'b1;
|
||||
|
||||
dSCL <= #1 1'b1;
|
||||
dSDA <= #1 1'b1;
|
||||
end
|
||||
else if (rst)
|
||||
begin
|
||||
sSCL <= #1 1'b1;
|
||||
sSDA <= #1 1'b1;
|
||||
|
||||
dSCL <= #1 1'b1;
|
||||
dSDA <= #1 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
sSCL <= #1 scl_i;
|
||||
sSDA <= #1 sda_i;
|
||||
|
||||
dSCL <= #1 sSCL;
|
||||
dSDA <= #1 sSDA;
|
||||
end
|
||||
|
||||
// detect start condition => detect falling edge on SDA while SCL is high
|
||||
// detect stop condition => detect rising edge on SDA while SCL is high
|
||||
always @(posedge clk or negedge nReset)
|
||||
if (~nReset)
|
||||
begin
|
||||
sta_condition <= #1 1'b0;
|
||||
sto_condition <= #1 1'b0;
|
||||
end
|
||||
else if (rst)
|
||||
begin
|
||||
sta_condition <= #1 1'b0;
|
||||
sto_condition <= #1 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
sta_condition <= #1 ~sSDA & dSDA & sSCL;
|
||||
sto_condition <= #1 sSDA & ~dSDA & sSCL;
|
||||
end
|
||||
|
||||
// generate i2c bus busy signal
|
||||
always @(posedge clk or negedge nReset)
|
||||
if(!nReset)
|
||||
busy <= #1 1'b0;
|
||||
else if (rst)
|
||||
busy <= #1 1'b0;
|
||||
else
|
||||
busy <= #1 (sta_condition | busy) & ~sto_condition;
|
||||
|
||||
// generate arbitration lost signal
|
||||
// aribitration lost when:
|
||||
// 1) master drives SDA high, but the i2c bus is low
|
||||
// 2) stop detected while not requested
|
||||
reg cmd_stop;
|
||||
always @(posedge clk or negedge nReset)
|
||||
if (~nReset)
|
||||
cmd_stop <= #1 1'b0;
|
||||
else if (rst)
|
||||
cmd_stop <= #1 1'b0;
|
||||
else if (clk_en)
|
||||
cmd_stop <= #1 (cmd & (`I2C_CMD_STOP|`SPI_CMD_WRITE|`SPI_CMD_READ)) != 6'b000000;
|
||||
|
||||
always @(posedge clk or negedge nReset)
|
||||
if (~nReset)
|
||||
al <= #1 1'b0;
|
||||
else if (rst)
|
||||
al <= #1 1'b0;
|
||||
else
|
||||
al <= #1 (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop);
|
||||
|
||||
|
||||
// generate dout signal (store SDA on rising edge of SCL)
|
||||
always @(posedge clk)
|
||||
if(sSCL & ~dSCL)
|
||||
dout <= #1 sSDA;
|
||||
|
||||
// generate statemachine
|
||||
|
||||
// nxt_state decoder
|
||||
parameter [24:0] idle = 25'b0_0000_0000_0000_0000_0000_0000;
|
||||
parameter [24:0] start_a = 25'b0_0000_0000_0000_0000_0000_0001;
|
||||
parameter [24:0] start_b = 25'b0_0000_0000_0000_0000_0000_0010;
|
||||
parameter [24:0] start_c = 25'b0_0000_0000_0000_0000_0000_0100;
|
||||
parameter [24:0] start_d = 25'b0_0000_0000_0000_0000_0000_1000;
|
||||
parameter [24:0] start_e = 25'b0_0000_0000_0000_0000_0001_0000;
|
||||
parameter [24:0] stop_a = 25'b0_0000_0000_0000_0000_0010_0000;
|
||||
parameter [24:0] stop_b = 25'b0_0000_0000_0000_0000_0100_0000;
|
||||
parameter [24:0] stop_c = 25'b0_0000_0000_0000_0000_1000_0000;
|
||||
parameter [24:0] stop_d = 25'b0_0000_0000_0000_0001_0000_0000;
|
||||
parameter [24:0] rd_a = 25'b0_0000_0000_0000_0010_0000_0000;
|
||||
parameter [24:0] rd_b = 25'b0_0000_0000_0000_0100_0000_0000;
|
||||
parameter [24:0] rd_c = 25'b0_0000_0000_0000_1000_0000_0000;
|
||||
parameter [24:0] rd_d = 25'b0_0000_0000_0001_0000_0000_0000;
|
||||
parameter [24:0] wr_a = 25'b0_0000_0000_0010_0000_0000_0000;
|
||||
parameter [24:0] wr_b = 25'b0_0000_0000_0100_0000_0000_0000;
|
||||
parameter [24:0] wr_c = 25'b0_0000_0000_1000_0000_0000_0000;
|
||||
parameter [24:0] wr_d = 25'b0_0000_0001_0000_0000_0000_0000;
|
||||
|
||||
parameter [24:0] spi_rd_a = 25'b0_0000_0010_0000_0000_0000_0000;
|
||||
parameter [24:0] spi_rd_b = 25'b0_0000_0100_0000_0000_0000_0000;
|
||||
parameter [24:0] spi_rd_c = 25'b0_0000_1000_0000_0000_0000_0000;
|
||||
parameter [24:0] spi_rd_d = 25'b0_0001_0000_0000_0000_0000_0000;
|
||||
parameter [24:0] spi_wr_a = 25'b0_0010_0000_0000_0000_0000_0000;
|
||||
parameter [24:0] spi_wr_b = 25'b0_0100_0000_0000_0000_0000_0000;
|
||||
parameter [24:0] spi_wr_c = 25'b0_1000_0000_0000_0000_0000_0000;
|
||||
parameter [24:0] spi_wr_d = 25'b1_0000_0000_0000_0000_0000_0000;
|
||||
|
||||
always @(posedge clk or negedge nReset)
|
||||
if (!nReset)
|
||||
begin
|
||||
c_state <= #1 idle;
|
||||
cmd_ack <= #1 1'b0;
|
||||
scl_oen <= #1 1'b1;
|
||||
sda_oen <= #1 1'b1;
|
||||
sda_chk <= #1 1'b0;
|
||||
end
|
||||
else if (rst | al)
|
||||
begin
|
||||
c_state <= #1 idle;
|
||||
cmd_ack <= #1 1'b0;
|
||||
scl_oen <= #1 1'b1;
|
||||
sda_oen <= #1 1'b1;
|
||||
sda_chk <= #1 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
cmd_ack <= #1 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
|
||||
|
||||
if (clk_en)
|
||||
case (c_state)
|
||||
// idle state
|
||||
idle:
|
||||
begin
|
||||
case (cmd)
|
||||
`I2C_CMD_START:
|
||||
c_state <= #1 start_a;
|
||||
|
||||
`I2C_CMD_STOP:
|
||||
c_state <= #1 stop_a;
|
||||
|
||||
`I2C_CMD_WRITE:
|
||||
c_state <= #1 wr_a;
|
||||
|
||||
`I2C_CMD_READ:
|
||||
c_state <= #1 rd_a;
|
||||
|
||||
`SPI_CMD_WRITE:
|
||||
c_state <= #1 spi_wr_a;
|
||||
|
||||
`SPI_CMD_READ:
|
||||
c_state <= #1 spi_rd_a;
|
||||
|
||||
default:
|
||||
c_state <= #1 idle;
|
||||
endcase
|
||||
|
||||
scl_oen <= #1 scl_oen; // keep SCL in same state
|
||||
sda_oen <= #1 sda_oen; // keep SDA in same state
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
// start
|
||||
start_a:
|
||||
begin
|
||||
c_state <= #1 start_b;
|
||||
scl_oen <= #1 scl_oen; // keep SCL in same state
|
||||
sda_oen <= #1 1'b1; // set SDA high
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
start_b:
|
||||
begin
|
||||
c_state <= #1 start_c;
|
||||
scl_oen <= #1 1'b1; // set SCL high
|
||||
sda_oen <= #1 1'b1; // keep SDA high
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
start_c:
|
||||
begin
|
||||
c_state <= #1 start_d;
|
||||
scl_oen <= #1 1'b1; // keep SCL high
|
||||
sda_oen <= #1 1'b0; // set SDA low
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
start_d:
|
||||
begin
|
||||
c_state <= #1 start_e;
|
||||
scl_oen <= #1 1'b1; // keep SCL high
|
||||
sda_oen <= #1 1'b0; // keep SDA low
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
start_e:
|
||||
begin
|
||||
c_state <= #1 idle;
|
||||
cmd_ack <= #1 1'b1;
|
||||
scl_oen <= #1 1'b0; // set SCL low
|
||||
sda_oen <= #1 1'b0; // keep SDA low
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
// stop
|
||||
stop_a:
|
||||
begin
|
||||
c_state <= #1 stop_b;
|
||||
scl_oen <= #1 1'b0; // keep SCL low
|
||||
sda_oen <= #1 1'b0; // set SDA low
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
stop_b:
|
||||
begin
|
||||
c_state <= #1 stop_c;
|
||||
scl_oen <= #1 1'b1; // set SCL high
|
||||
sda_oen <= #1 1'b0; // keep SDA low
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
stop_c:
|
||||
begin
|
||||
c_state <= #1 stop_d;
|
||||
scl_oen <= #1 1'b1; // keep SCL high
|
||||
sda_oen <= #1 1'b0; // keep SDA low
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
stop_d:
|
||||
begin
|
||||
c_state <= #1 idle;
|
||||
cmd_ack <= #1 1'b1;
|
||||
scl_oen <= #1 1'b1; // keep SCL high
|
||||
sda_oen <= #1 1'b1; // set SDA high
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
// read
|
||||
rd_a:
|
||||
begin
|
||||
c_state <= #1 rd_b;
|
||||
scl_oen <= #1 1'b0; // keep SCL low
|
||||
sda_oen <= #1 1'b1; // tri-state SDA
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
rd_b:
|
||||
begin
|
||||
c_state <= #1 rd_c;
|
||||
scl_oen <= #1 1'b1; // set SCL high
|
||||
sda_oen <= #1 1'b1; // keep SDA tri-stated
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
rd_c:
|
||||
begin
|
||||
c_state <= #1 rd_d;
|
||||
scl_oen <= #1 1'b1; // keep SCL high
|
||||
sda_oen <= #1 1'b1; // keep SDA tri-stated
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
rd_d:
|
||||
begin
|
||||
c_state <= #1 idle;
|
||||
cmd_ack <= #1 1'b1;
|
||||
scl_oen <= #1 1'b0; // set SCL low
|
||||
sda_oen <= #1 1'b1; // keep SDA tri-stated
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
// write
|
||||
wr_a:
|
||||
begin
|
||||
c_state <= #1 wr_b;
|
||||
scl_oen <= #1 1'b0; // keep SCL low
|
||||
sda_oen <= #1 din; // set SDA
|
||||
sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
|
||||
end
|
||||
|
||||
wr_b:
|
||||
begin
|
||||
c_state <= #1 wr_c;
|
||||
scl_oen <= #1 1'b1; // set SCL high
|
||||
sda_oen <= #1 din; // keep SDA
|
||||
sda_chk <= #1 1'b1; // check SDA output
|
||||
end
|
||||
|
||||
wr_c:
|
||||
begin
|
||||
c_state <= #1 wr_d;
|
||||
scl_oen <= #1 1'b1; // keep SCL high
|
||||
sda_oen <= #1 din;
|
||||
sda_chk <= #1 1'b1; // check SDA output
|
||||
end
|
||||
|
||||
wr_d:
|
||||
begin
|
||||
c_state <= #1 idle;
|
||||
cmd_ack <= #1 1'b1;
|
||||
scl_oen <= #1 1'b0; // set SCL low
|
||||
sda_oen <= #1 din;
|
||||
sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
|
||||
end
|
||||
|
||||
// read (last SPI bit)
|
||||
spi_rd_a:
|
||||
begin
|
||||
c_state <= #1 spi_rd_b;
|
||||
scl_oen <= #1 1'b0; // set SCL low
|
||||
sda_oen <= #1 1'b1; // tri-state SDA
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
spi_rd_b:
|
||||
begin
|
||||
c_state <= #1 spi_rd_c;
|
||||
scl_oen <= #1 1'b0; // keep SCL low
|
||||
sda_oen <= #1 1'b1; // keep SDA tri-stated
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
spi_rd_c:
|
||||
begin
|
||||
c_state <= #1 spi_rd_d;
|
||||
scl_oen <= #1 1'b1; // set SCL high
|
||||
sda_oen <= #1 1'b1; // keep SDA tri-stated
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
spi_rd_d:
|
||||
begin
|
||||
c_state <= #1 idle;
|
||||
cmd_ack <= #1 1'b1;
|
||||
scl_oen <= #1 1'b1; // tri-state SCL
|
||||
sda_oen <= #1 1'b1; // keep SDA tri-stated
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
// write (last SPI bit)
|
||||
spi_wr_a:
|
||||
begin
|
||||
c_state <= #1 spi_wr_b;
|
||||
scl_oen <= #1 1'b0; // set SCL low
|
||||
sda_oen <= #1 1'b1; // keep SDA
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
spi_wr_b:
|
||||
begin
|
||||
c_state <= #1 spi_wr_c;
|
||||
scl_oen <= #1 1'b0; // keep SCL low
|
||||
sda_oen <= #1 din; // set SDA
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
spi_wr_c:
|
||||
begin
|
||||
c_state <= #1 spi_wr_d;
|
||||
scl_oen <= #1 1'b1; // keep SCL high
|
||||
sda_oen <= #1 din; // keep SDA
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
spi_wr_d:
|
||||
begin
|
||||
c_state <= #1 idle;
|
||||
cmd_ack <= #1 1'b1;
|
||||
scl_oen <= #1 1'b1; // tri-state SCL
|
||||
sda_oen <= #1 1'b1; // tri-state SDA
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
default:
|
||||
c_state <= #1 idle;
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// assign scl and sda output (always gnd)
|
||||
assign scl_o = 1'b0;
|
||||
assign sda_o = 1'b0;
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,382 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE rev.B2 compliant I2C Master byte-controller ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// www.asics.ws ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2001 Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: i2c_master_byte_ctrl.v,v 1.7 2004/02/18 11:40:46 rherveille Exp $
|
||||
//
|
||||
// $Date: 2004/02/18 11:40:46 $
|
||||
// $Revision: 1.7 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: i2c_master_byte_ctrl.v,v $
|
||||
// Revision 1.7 2004/02/18 11:40:46 rherveille
|
||||
// Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command.
|
||||
//
|
||||
// Revision 1.6 2003/08/09 07:01:33 rherveille
|
||||
// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
|
||||
// Fixed a potential bug in the byte controller's host-acknowledge generation.
|
||||
//
|
||||
// Revision 1.5 2002/12/26 15:02:32 rherveille
|
||||
// Core is now a Multimaster I2C controller
|
||||
//
|
||||
// Revision 1.4 2002/11/30 22:24:40 rherveille
|
||||
// Cleaned up code
|
||||
//
|
||||
// Revision 1.3 2001/11/05 11:59:25 rherveille
|
||||
// Fixed wb_ack_o generation bug.
|
||||
// Fixed bug in the byte_controller statemachine.
|
||||
// Added headers.
|
||||
//
|
||||
|
||||
// synopsys translate_off
|
||||
`include "timescale.v"
|
||||
// synopsys translate_on
|
||||
|
||||
`include "i2c_master_defines.v"
|
||||
|
||||
module i2c_master_byte_ctrl (
|
||||
clk, rst, nReset, ena, clk_cnt, start, stop, read, write, ack_in, spi_mode, din,
|
||||
cmd_ack, ack_out, dout, i2c_busy, i2c_al, scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen );
|
||||
|
||||
//
|
||||
// inputs & outputs
|
||||
//
|
||||
input clk; // master clock
|
||||
input rst; // synchronous active high reset
|
||||
input nReset; // asynchronous active low reset
|
||||
input ena; // core enable signal
|
||||
|
||||
input [15:0] clk_cnt; // 4x SCL
|
||||
|
||||
// control inputs
|
||||
input start;
|
||||
input stop;
|
||||
input read;
|
||||
input write;
|
||||
input ack_in;
|
||||
input spi_mode;
|
||||
input [7:0] din;
|
||||
|
||||
// status outputs
|
||||
output cmd_ack;
|
||||
reg cmd_ack;
|
||||
output ack_out;
|
||||
reg ack_out;
|
||||
output i2c_busy;
|
||||
output i2c_al;
|
||||
output [7:0] dout;
|
||||
|
||||
// I2C signals
|
||||
input scl_i;
|
||||
output scl_o;
|
||||
output scl_oen;
|
||||
input sda_i;
|
||||
output sda_o;
|
||||
output sda_oen;
|
||||
|
||||
|
||||
//
|
||||
// Variable declarations
|
||||
//
|
||||
|
||||
// statemachine
|
||||
parameter [6:0] ST_IDLE = 7'b000_0000;
|
||||
parameter [6:0] ST_START = 7'b000_0001;
|
||||
parameter [6:0] ST_READ = 7'b000_0010;
|
||||
parameter [6:0] ST_WRITE = 7'b000_0100;
|
||||
parameter [6:0] ST_ACK = 7'b000_1000;
|
||||
parameter [6:0] ST_STOP = 7'b001_0000;
|
||||
parameter [6:0] ST_SPI_READ = 7'b010_0000;
|
||||
parameter [6:0] ST_SPI_WRITE = 7'b100_0000;
|
||||
|
||||
|
||||
// signals for bit_controller
|
||||
reg [5:0] core_cmd;
|
||||
reg core_txd;
|
||||
wire core_ack, core_rxd;
|
||||
|
||||
// signals for shift register
|
||||
reg [7:0] sr; //8bit shift register
|
||||
reg shift, ld;
|
||||
|
||||
// signals for state machine
|
||||
wire go;
|
||||
reg [2:0] dcnt;
|
||||
wire cnt_done;
|
||||
|
||||
//
|
||||
// Module body
|
||||
//
|
||||
|
||||
// hookup bit_controller
|
||||
i2c_master_bit_ctrl bit_controller (
|
||||
.clk ( clk ),
|
||||
.rst ( rst ),
|
||||
.nReset ( nReset ),
|
||||
.ena ( ena ),
|
||||
.clk_cnt ( clk_cnt ),
|
||||
.cmd ( core_cmd ),
|
||||
.cmd_ack ( core_ack ),
|
||||
.busy ( i2c_busy ),
|
||||
.al ( i2c_al ),
|
||||
.din ( core_txd ),
|
||||
.dout ( core_rxd ),
|
||||
.scl_i ( scl_i ),
|
||||
.scl_o ( scl_o ),
|
||||
.scl_oen ( scl_oen ),
|
||||
.sda_i ( sda_i ),
|
||||
.sda_o ( sda_o ),
|
||||
.sda_oen ( sda_oen )
|
||||
);
|
||||
|
||||
// generate go-signal
|
||||
assign go = (read | write | stop) & ~cmd_ack;
|
||||
|
||||
// assign dout output to shift-register
|
||||
assign dout = sr;
|
||||
|
||||
// generate shift register
|
||||
always @(posedge clk or negedge nReset)
|
||||
if (!nReset)
|
||||
sr <= #1 8'h0;
|
||||
else if (rst)
|
||||
sr <= #1 8'h0;
|
||||
else if (ld)
|
||||
sr <= #1 din;
|
||||
else if (shift)
|
||||
sr <= #1 {sr[6:0], core_rxd};
|
||||
|
||||
// generate counter
|
||||
always @(posedge clk or negedge nReset)
|
||||
if (!nReset)
|
||||
dcnt <= #1 3'h0;
|
||||
else if (rst)
|
||||
dcnt <= #1 3'h0;
|
||||
else if (ld)
|
||||
dcnt <= #1 3'h7;
|
||||
else if (shift)
|
||||
dcnt <= #1 dcnt - 3'h1;
|
||||
|
||||
assign cnt_done = ~(|dcnt);
|
||||
|
||||
//
|
||||
// state machine
|
||||
//
|
||||
reg [6:0] c_state; // synopsis enum_state
|
||||
|
||||
always @(posedge clk or negedge nReset)
|
||||
if (!nReset)
|
||||
begin
|
||||
core_cmd <= #1 `I2C_CMD_NOP;
|
||||
core_txd <= #1 1'b0;
|
||||
shift <= #1 1'b0;
|
||||
ld <= #1 1'b0;
|
||||
cmd_ack <= #1 1'b0;
|
||||
c_state <= #1 ST_IDLE;
|
||||
ack_out <= #1 1'b0;
|
||||
end
|
||||
else if (rst | i2c_al)
|
||||
begin
|
||||
core_cmd <= #1 `I2C_CMD_NOP;
|
||||
core_txd <= #1 1'b0;
|
||||
shift <= #1 1'b0;
|
||||
ld <= #1 1'b0;
|
||||
cmd_ack <= #1 1'b0;
|
||||
c_state <= #1 ST_IDLE;
|
||||
ack_out <= #1 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// initially reset all signals
|
||||
core_txd <= #1 sr[7];
|
||||
shift <= #1 1'b0;
|
||||
ld <= #1 1'b0;
|
||||
cmd_ack <= #1 1'b0;
|
||||
|
||||
case (c_state) // synopsys full_case parallel_case
|
||||
ST_IDLE:
|
||||
if (go)
|
||||
begin
|
||||
if (start)
|
||||
begin
|
||||
c_state <= #1 ST_START;
|
||||
core_cmd <= #1 `I2C_CMD_START;
|
||||
end
|
||||
else if (read)
|
||||
begin
|
||||
c_state <= #1 spi_mode ? ST_SPI_READ : ST_READ;
|
||||
core_cmd <= #1 spi_mode ? `SPI_CMD_READ : `I2C_CMD_READ;
|
||||
end
|
||||
else if (write)
|
||||
begin
|
||||
c_state <= #1 spi_mode ? ST_SPI_WRITE : ST_WRITE;
|
||||
core_cmd <= #1 spi_mode ? `SPI_CMD_WRITE : `I2C_CMD_WRITE;
|
||||
end
|
||||
else // stop
|
||||
begin
|
||||
c_state <= #1 ST_STOP;
|
||||
core_cmd <= #1 `I2C_CMD_STOP;
|
||||
end
|
||||
|
||||
ld <= #1 1'b1;
|
||||
end
|
||||
|
||||
ST_START:
|
||||
if (core_ack)
|
||||
begin
|
||||
if (read)
|
||||
begin
|
||||
c_state <= #1 ST_READ;
|
||||
core_cmd <= #1 `I2C_CMD_READ;
|
||||
end
|
||||
else
|
||||
begin
|
||||
c_state <= #1 ST_WRITE;
|
||||
core_cmd <= #1 `I2C_CMD_WRITE;
|
||||
end
|
||||
|
||||
ld <= #1 1'b1;
|
||||
end
|
||||
|
||||
ST_WRITE:
|
||||
if (core_ack)
|
||||
if (cnt_done)
|
||||
begin
|
||||
c_state <= #1 ST_ACK;
|
||||
core_cmd <= #1 `I2C_CMD_READ;
|
||||
end
|
||||
else
|
||||
begin
|
||||
c_state <= #1 ST_WRITE; // stay in same state
|
||||
core_cmd <= #1 `I2C_CMD_WRITE; // write next bit
|
||||
shift <= #1 1'b1;
|
||||
end
|
||||
|
||||
ST_READ:
|
||||
if (core_ack)
|
||||
begin
|
||||
if (cnt_done)
|
||||
begin
|
||||
c_state <= #1 ST_ACK;
|
||||
core_cmd <= #1 `I2C_CMD_WRITE;
|
||||
end
|
||||
else
|
||||
begin
|
||||
c_state <= #1 ST_READ; // stay in same state
|
||||
core_cmd <= #1 `I2C_CMD_READ; // read next bit
|
||||
end
|
||||
|
||||
shift <= #1 1'b1;
|
||||
core_txd <= #1 ack_in;
|
||||
end
|
||||
|
||||
ST_ACK:
|
||||
if (core_ack)
|
||||
begin
|
||||
if (stop)
|
||||
begin
|
||||
c_state <= #1 ST_STOP;
|
||||
core_cmd <= #1 `I2C_CMD_STOP;
|
||||
end
|
||||
else
|
||||
begin
|
||||
c_state <= #1 ST_IDLE;
|
||||
core_cmd <= #1 `I2C_CMD_NOP;
|
||||
|
||||
// generate command acknowledge signal
|
||||
cmd_ack <= #1 1'b1;
|
||||
end
|
||||
|
||||
// assign ack_out output to bit_controller_rxd (contains last received bit)
|
||||
ack_out <= #1 core_rxd;
|
||||
|
||||
core_txd <= #1 1'b1;
|
||||
end
|
||||
else
|
||||
core_txd <= #1 ack_in;
|
||||
|
||||
ST_STOP:
|
||||
if (core_ack)
|
||||
begin
|
||||
c_state <= #1 ST_IDLE;
|
||||
core_cmd <= #1 `I2C_CMD_NOP;
|
||||
|
||||
// generate command acknowledge signal
|
||||
cmd_ack <= #1 1'b1;
|
||||
end
|
||||
|
||||
ST_SPI_WRITE:
|
||||
if (core_ack)
|
||||
if (cnt_done)
|
||||
begin
|
||||
c_state <= #1 ST_IDLE;
|
||||
core_cmd <= #1 `I2C_CMD_NOP;
|
||||
cmd_ack <= #1 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
c_state <= #1 ST_SPI_WRITE; // stay in same state
|
||||
core_cmd <= #1 `SPI_CMD_WRITE; // write next bit
|
||||
shift <= #1 1'b1;
|
||||
end
|
||||
|
||||
ST_SPI_READ:
|
||||
if (core_ack)
|
||||
begin
|
||||
if (cnt_done)
|
||||
begin
|
||||
c_state <= #1 ST_IDLE;
|
||||
core_cmd <= #1 `I2C_CMD_NOP;
|
||||
cmd_ack <= #1 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
c_state <= #1 ST_SPI_READ; // stay in same state
|
||||
core_cmd <= #1 `SPI_CMD_READ; // read next bit
|
||||
end
|
||||
|
||||
shift <= #1 1'b1;
|
||||
core_txd <= #1 ack_in;
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
endmodule
|
|
@ -0,0 +1,66 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE rev.B2 compliant I2C Master controller defines ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// www.asics.ws ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2001 Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: i2c_master_defines.v,v 1.3 2001/11/05 11:59:25 rherveille Exp $
|
||||
//
|
||||
// $Date: 2001/11/05 11:59:25 $
|
||||
// $Revision: 1.3 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: i2c_master_defines.v,v $
|
||||
// Revision 1.3 2001/11/05 11:59:25 rherveille
|
||||
// Fixed wb_ack_o generation bug.
|
||||
// Fixed bug in the byte_controller statemachine.
|
||||
// Added headers.
|
||||
//
|
||||
|
||||
|
||||
// I2C registers wishbone addresses
|
||||
|
||||
// bitcontroller states
|
||||
`define I2C_CMD_NOP 6'b000000
|
||||
`define I2C_CMD_START 6'b000001
|
||||
`define I2C_CMD_STOP 6'b000010
|
||||
`define I2C_CMD_WRITE 6'b000100
|
||||
`define I2C_CMD_READ 6'b001000
|
||||
`define SPI_CMD_WRITE 6'b010000
|
||||
`define SPI_CMD_READ 6'b100000
|
|
@ -0,0 +1,300 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE revB.2 compliant I2C Master controller Top-level ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// www.asics.ws ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2001 Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: i2c_master_top.v,v 1.10 2003/09/01 10:34:38 rherveille Exp $
|
||||
//
|
||||
// $Date: 2003/09/01 10:34:38 $
|
||||
// $Revision: 1.10 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: i2c_master_top.v,v $
|
||||
// Revision 1.10 2003/09/01 10:34:38 rherveille
|
||||
// Fix a blocking vs. non-blocking error in the wb_dat output mux.
|
||||
//
|
||||
// Revision 1.9 2003/01/09 16:44:45 rherveille
|
||||
// Fixed a bug in the Command Register declaration.
|
||||
//
|
||||
// Revision 1.8 2002/12/26 16:05:12 rherveille
|
||||
// Small code simplifications
|
||||
//
|
||||
// Revision 1.7 2002/12/26 15:02:32 rherveille
|
||||
// Core is now a Multimaster I2C controller
|
||||
//
|
||||
// Revision 1.6 2002/11/30 22:24:40 rherveille
|
||||
// Cleaned up code
|
||||
//
|
||||
// Revision 1.5 2001/11/10 10:52:55 rherveille
|
||||
// Changed PRER reset value from 0x0000 to 0xffff, conform specs.
|
||||
//
|
||||
|
||||
// synopsys translate_off
|
||||
`include "timescale.v"
|
||||
// synopsys translate_on
|
||||
|
||||
`include "i2c_master_defines.v"
|
||||
|
||||
module i2c_master_top(
|
||||
wb_clk_i, wb_rst_i, arst_i, wb_adr_i, wb_dat_i, wb_dat_o,
|
||||
wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_inta_o,
|
||||
scl_pad_i, scl_pad_o, scl_padoen_o, sda_pad_i, sda_pad_o, sda_padoen_o );
|
||||
|
||||
// parameters
|
||||
parameter ARST_LVL = 1'b0; // asynchronous reset level
|
||||
|
||||
//
|
||||
// inputs & outputs
|
||||
//
|
||||
|
||||
// wishbone signals
|
||||
input wb_clk_i; // master clock input
|
||||
input wb_rst_i; // synchronous active high reset
|
||||
input arst_i; // asynchronous reset
|
||||
input [2:0] wb_adr_i; // lower address bits
|
||||
input [7:0] wb_dat_i; // databus input
|
||||
output [7:0] wb_dat_o; // databus output
|
||||
input wb_we_i; // write enable input
|
||||
input wb_stb_i; // stobe/core select signal
|
||||
input wb_cyc_i; // valid bus cycle input
|
||||
output wb_ack_o; // bus cycle acknowledge output
|
||||
output wb_inta_o; // interrupt request signal output
|
||||
|
||||
reg [7:0] wb_dat_o;
|
||||
reg wb_ack_o;
|
||||
reg wb_inta_o;
|
||||
|
||||
// I2C signals
|
||||
// i2c clock line
|
||||
input scl_pad_i; // SCL-line input
|
||||
output scl_pad_o; // SCL-line output (always 1'b0)
|
||||
output scl_padoen_o; // SCL-line output enable (active low)
|
||||
|
||||
// i2c data line
|
||||
input sda_pad_i; // SDA-line input
|
||||
output sda_pad_o; // SDA-line output (always 1'b0)
|
||||
output sda_padoen_o; // SDA-line output enable (active low)
|
||||
|
||||
|
||||
//
|
||||
// variable declarations
|
||||
//
|
||||
|
||||
// registers
|
||||
reg [15:0] prer; // clock prescale register
|
||||
reg [ 7:0] ctr; // control register
|
||||
reg [ 7:0] txr; // transmit register
|
||||
wire [ 7:0] rxr; // receive register
|
||||
reg [ 7:0] cr; // command register
|
||||
wire [ 7:0] sr; // status register
|
||||
|
||||
// done signal: command completed, clear command register
|
||||
wire done;
|
||||
|
||||
// core enable signal
|
||||
wire core_en;
|
||||
wire ien;
|
||||
|
||||
// status register signals
|
||||
wire irxack;
|
||||
reg rxack; // received aknowledge from slave
|
||||
reg tip; // transfer in progress
|
||||
reg irq_flag; // interrupt pending flag
|
||||
wire i2c_busy; // bus busy (start signal detected)
|
||||
wire i2c_al; // i2c bus arbitration lost
|
||||
reg al; // status register arbitration lost bit
|
||||
|
||||
//
|
||||
// module body
|
||||
//
|
||||
|
||||
// generate internal reset
|
||||
wire rst_i = arst_i ^ ARST_LVL;
|
||||
|
||||
// generate wishbone signals
|
||||
wire wb_wacc = wb_cyc_i & wb_stb_i & wb_we_i;
|
||||
|
||||
// generate acknowledge output signal
|
||||
always @(posedge wb_clk_i)
|
||||
wb_ack_o <= #1 wb_cyc_i & wb_stb_i & ~wb_ack_o; // because timing is always honored
|
||||
|
||||
// assign DAT_O
|
||||
always @(posedge wb_clk_i)
|
||||
begin
|
||||
case (wb_adr_i) // synopsis full_case parallel_case
|
||||
3'b000: wb_dat_o <= #1 prer[ 7:0];
|
||||
3'b001: wb_dat_o <= #1 prer[15:8];
|
||||
3'b010: wb_dat_o <= #1 ctr;
|
||||
3'b011: wb_dat_o <= #1 rxr; // write is transmit register (txr)
|
||||
3'b100: wb_dat_o <= #1 sr; // write is command register (cr)
|
||||
3'b101: wb_dat_o <= #1 txr;
|
||||
3'b110: wb_dat_o <= #1 cr;
|
||||
3'b111: wb_dat_o <= #1 0; // reserved
|
||||
endcase
|
||||
end
|
||||
|
||||
// generate registers
|
||||
always @(posedge wb_clk_i or negedge rst_i)
|
||||
if (!rst_i)
|
||||
begin
|
||||
prer <= #1 16'hffff;
|
||||
ctr <= #1 8'h0;
|
||||
txr <= #1 8'h0;
|
||||
end
|
||||
else if (wb_rst_i)
|
||||
begin
|
||||
prer <= #1 16'hffff;
|
||||
ctr <= #1 8'h0;
|
||||
txr <= #1 8'h0;
|
||||
end
|
||||
else
|
||||
if (wb_wacc)
|
||||
case (wb_adr_i) // synopsis full_case parallel_case
|
||||
3'b000 : prer [ 7:0] <= #1 wb_dat_i;
|
||||
3'b001 : prer [15:8] <= #1 wb_dat_i;
|
||||
3'b010 : ctr <= #1 wb_dat_i;
|
||||
3'b011 : txr <= #1 wb_dat_i;
|
||||
endcase
|
||||
|
||||
// generate command register (special case)
|
||||
always @(posedge wb_clk_i or negedge rst_i)
|
||||
if (~rst_i)
|
||||
cr <= #1 8'h0;
|
||||
else if (wb_rst_i)
|
||||
cr <= #1 8'h0;
|
||||
else if (wb_wacc)
|
||||
begin
|
||||
if (core_en & (wb_adr_i == 3'b100) )
|
||||
cr <= #1 wb_dat_i;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (done | i2c_al)
|
||||
begin
|
||||
cr[7:4] <= #1 4'h0; // clear command bits when done
|
||||
cr[2] <= #1 1'b0; // or when aribitration lost
|
||||
end
|
||||
cr[1] <= #1 1'b0; // reserved bit
|
||||
cr[0] <= #1 1'b0; // clear IRQ_ACK bit
|
||||
end
|
||||
|
||||
|
||||
// decode command register
|
||||
wire sta = cr[7];
|
||||
wire sto = cr[6];
|
||||
wire rd = cr[5];
|
||||
wire wr = cr[4];
|
||||
wire ack = cr[3];
|
||||
wire spi = cr[2];
|
||||
wire iack = cr[0];
|
||||
|
||||
// decode control register
|
||||
assign core_en = ctr[7];
|
||||
assign ien = ctr[6];
|
||||
|
||||
// hookup byte controller block
|
||||
i2c_master_byte_ctrl byte_controller (
|
||||
.clk ( wb_clk_i ),
|
||||
.rst ( wb_rst_i ),
|
||||
.nReset ( rst_i ),
|
||||
.ena ( core_en ),
|
||||
.clk_cnt ( prer ),
|
||||
.start ( sta ),
|
||||
.stop ( sto ),
|
||||
.read ( rd ),
|
||||
.write ( wr ),
|
||||
.ack_in ( ack ),
|
||||
.spi_mode ( spi ),
|
||||
.din ( txr ),
|
||||
.cmd_ack ( done ),
|
||||
.ack_out ( irxack ),
|
||||
.dout ( rxr ),
|
||||
.i2c_busy ( i2c_busy ),
|
||||
.i2c_al ( i2c_al ),
|
||||
.scl_i ( scl_pad_i ),
|
||||
.scl_o ( scl_pad_o ),
|
||||
.scl_oen ( scl_padoen_o ),
|
||||
.sda_i ( sda_pad_i ),
|
||||
.sda_o ( sda_pad_o ),
|
||||
.sda_oen ( sda_padoen_o )
|
||||
);
|
||||
|
||||
// status register block + interrupt request signal
|
||||
always @(posedge wb_clk_i or negedge rst_i)
|
||||
if (!rst_i)
|
||||
begin
|
||||
al <= #1 1'b0;
|
||||
rxack <= #1 1'b0;
|
||||
tip <= #1 1'b0;
|
||||
irq_flag <= #1 1'b0;
|
||||
end
|
||||
else if (wb_rst_i)
|
||||
begin
|
||||
al <= #1 1'b0;
|
||||
rxack <= #1 1'b0;
|
||||
tip <= #1 1'b0;
|
||||
irq_flag <= #1 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
al <= #1 i2c_al | (al & ~sta);
|
||||
rxack <= #1 irxack;
|
||||
tip <= #1 (rd | wr);
|
||||
irq_flag <= #1 (done | i2c_al | irq_flag) & ~iack; // interrupt request flag is always generated
|
||||
end
|
||||
|
||||
// generate interrupt request signals
|
||||
always @(posedge wb_clk_i or negedge rst_i)
|
||||
if (!rst_i)
|
||||
wb_inta_o <= #1 1'b0;
|
||||
else if (wb_rst_i)
|
||||
wb_inta_o <= #1 1'b0;
|
||||
else
|
||||
wb_inta_o <= #1 irq_flag && ien; // interrupt signal is only generated when IEN (interrupt enable bit is set)
|
||||
|
||||
// assign status register bits
|
||||
assign sr[7] = rxack;
|
||||
assign sr[6] = i2c_busy;
|
||||
assign sr[5] = al;
|
||||
assign sr[4:2] = 3'h0; // reserved
|
||||
assign sr[1] = tip;
|
||||
assign sr[0] = irq_flag;
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,72 @@
|
|||
//
|
||||
// fixed for 9.1 jan 21 2010 cruben
|
||||
//
|
||||
`include "timescale.v"
|
||||
`include "i2c_master_defines.v"
|
||||
|
||||
module i2c_opencores
|
||||
(
|
||||
wb_clk_i, wb_rst_i, wb_adr_i, wb_dat_i, wb_dat_o,
|
||||
wb_we_i, wb_stb_i, /*wb_cyc_i,*/ wb_ack_o, wb_inta_o,
|
||||
scl_pad_io, sda_pad_io
|
||||
);
|
||||
|
||||
|
||||
// Common bus signals
|
||||
input wb_clk_i; // WISHBONE clock
|
||||
input wb_rst_i; // WISHBONE reset
|
||||
|
||||
// Slave signals
|
||||
input [2:0] wb_adr_i; // WISHBONE address input
|
||||
input [7:0] wb_dat_i; // WISHBONE data input
|
||||
output [7:0] wb_dat_o; // WISHBONE data output
|
||||
input wb_we_i; // WISHBONE write enable input
|
||||
input wb_stb_i; // WISHBONE strobe input
|
||||
//input wb_cyc_i; // WISHBONE cycle input
|
||||
output wb_ack_o; // WISHBONE acknowledge output
|
||||
output wb_inta_o; // WISHBONE interrupt output
|
||||
|
||||
// I2C signals
|
||||
inout scl_pad_io; // I2C clock io
|
||||
inout sda_pad_io; // I2C data io
|
||||
|
||||
wire wb_cyc_i; // WISHBONE cycle input
|
||||
// Wire tri-state scl/sda
|
||||
wire scl_pad_i;
|
||||
wire scl_pad_o;
|
||||
wire scl_pad_io;
|
||||
wire scl_padoen_o;
|
||||
|
||||
assign wb_cyc_i = wb_stb_i;
|
||||
assign scl_pad_i = scl_pad_io;
|
||||
assign scl_pad_io = scl_padoen_o ? 1'bZ : scl_pad_o;
|
||||
|
||||
wire sda_pad_i;
|
||||
wire sda_pad_o;
|
||||
wire sda_pad_io;
|
||||
wire sda_padoen_o;
|
||||
|
||||
assign sda_pad_i = sda_pad_io;
|
||||
assign sda_pad_io = sda_padoen_o ? 1'bZ : sda_pad_o;
|
||||
|
||||
// Avalon doesn't have an asynchronous reset
|
||||
// set it to be inactive and just use synchronous reset
|
||||
// reset level is a parameter, 0 is the default (active-low reset)
|
||||
wire arst_i;
|
||||
|
||||
assign arst_i = 1'b1;
|
||||
|
||||
// Connect the top level I2C core
|
||||
i2c_master_top i2c_master_top_inst
|
||||
(
|
||||
.wb_clk_i(wb_clk_i), .wb_rst_i(wb_rst_i), .arst_i(arst_i),
|
||||
|
||||
.wb_adr_i(wb_adr_i), .wb_dat_i(wb_dat_i), .wb_dat_o(wb_dat_o),
|
||||
.wb_we_i(wb_we_i), .wb_stb_i(wb_stb_i), .wb_cyc_i(wb_cyc_i),
|
||||
.wb_ack_o(wb_ack_o), .wb_inta_o(wb_inta_o),
|
||||
|
||||
.scl_pad_i(scl_pad_i), .scl_pad_o(scl_pad_o), .scl_padoen_o(scl_padoen_o),
|
||||
.sda_pad_i(sda_pad_i), .sda_pad_o(sda_pad_o), .sda_padoen_o(sda_padoen_o)
|
||||
);
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,166 @@
|
|||
# TCL File Generated by Component Editor 13.1
|
||||
# Sat May 17 17:29:02 EEST 2014
|
||||
# DO NOT MODIFY
|
||||
|
||||
|
||||
#
|
||||
# i2c_opencores "I2C Master (opencores.org)" v13.0
|
||||
# 2014.05.17.17:29:02
|
||||
# I2C Master Peripheral from opencores.org
|
||||
#
|
||||
|
||||
#
|
||||
# request TCL package from ACDS 13.1
|
||||
#
|
||||
package require -exact qsys 13.1
|
||||
|
||||
|
||||
#
|
||||
# module i2c_opencores
|
||||
#
|
||||
set_module_property DESCRIPTION "I2C Master Peripheral from opencores.org"
|
||||
set_module_property NAME i2c_opencores
|
||||
set_module_property VERSION 13.0
|
||||
set_module_property INTERNAL false
|
||||
set_module_property OPAQUE_ADDRESS_MAP true
|
||||
set_module_property GROUP "Interface Protocols/Serial"
|
||||
set_module_property AUTHOR ""
|
||||
set_module_property DISPLAY_NAME "I2C Master (opencores.org)"
|
||||
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
|
||||
set_module_property EDITABLE true
|
||||
set_module_property ANALYZE_HDL AUTO
|
||||
set_module_property REPORT_TO_TALKBACK false
|
||||
set_module_property ALLOW_GREYBOX_GENERATION false
|
||||
|
||||
|
||||
#
|
||||
# file sets
|
||||
#
|
||||
add_fileset quartus_synth QUARTUS_SYNTH "" "Quartus Synthesis"
|
||||
set_fileset_property quartus_synth TOP_LEVEL i2c_opencores
|
||||
set_fileset_property quartus_synth ENABLE_RELATIVE_INCLUDE_PATHS false
|
||||
add_fileset_file i2c_opencores.v VERILOG PATH i2c_opencores.v
|
||||
add_fileset_file i2c_master_top.v VERILOG PATH i2c_master_top.v
|
||||
add_fileset_file i2c_master_defines.v VERILOG PATH i2c_master_defines.v
|
||||
add_fileset_file i2c_master_byte_ctrl.v VERILOG PATH i2c_master_byte_ctrl.v
|
||||
add_fileset_file i2c_master_bit_ctrl.v VERILOG PATH i2c_master_bit_ctrl.v
|
||||
|
||||
add_fileset sim_verilog SIM_VERILOG "" "Verilog Simulation"
|
||||
set_fileset_property sim_verilog TOP_LEVEL i2c_opencores
|
||||
set_fileset_property sim_verilog ENABLE_RELATIVE_INCLUDE_PATHS false
|
||||
add_fileset_file i2c_opencores.v VERILOG PATH i2c_opencores.v
|
||||
add_fileset_file i2c_master_top.v VERILOG PATH i2c_master_top.v
|
||||
add_fileset_file i2c_master_defines.v VERILOG PATH i2c_master_defines.v
|
||||
add_fileset_file i2c_master_byte_ctrl.v VERILOG PATH i2c_master_byte_ctrl.v
|
||||
add_fileset_file i2c_master_bit_ctrl.v VERILOG PATH i2c_master_bit_ctrl.v
|
||||
add_fileset_file timescale.v VERILOG PATH timescale.v
|
||||
|
||||
|
||||
#
|
||||
# parameters
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# display items
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# connection point clock
|
||||
#
|
||||
add_interface clock clock end
|
||||
set_interface_property clock clockRate 0
|
||||
set_interface_property clock ENABLED true
|
||||
set_interface_property clock EXPORT_OF ""
|
||||
set_interface_property clock PORT_NAME_MAP ""
|
||||
set_interface_property clock CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property clock SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port clock wb_clk_i clk Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point clock_reset
|
||||
#
|
||||
add_interface clock_reset reset end
|
||||
set_interface_property clock_reset associatedClock clock
|
||||
set_interface_property clock_reset synchronousEdges DEASSERT
|
||||
set_interface_property clock_reset ENABLED true
|
||||
set_interface_property clock_reset EXPORT_OF ""
|
||||
set_interface_property clock_reset PORT_NAME_MAP ""
|
||||
set_interface_property clock_reset CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property clock_reset SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port clock_reset wb_rst_i reset Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point export
|
||||
#
|
||||
add_interface export conduit end
|
||||
set_interface_property export associatedClock ""
|
||||
set_interface_property export associatedReset ""
|
||||
set_interface_property export ENABLED true
|
||||
set_interface_property export EXPORT_OF ""
|
||||
set_interface_property export PORT_NAME_MAP ""
|
||||
set_interface_property export CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property export SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port export scl_pad_io export Bidir 1
|
||||
add_interface_port export sda_pad_io export Bidir 1
|
||||
|
||||
|
||||
#
|
||||
# connection point avalon_slave_0
|
||||
#
|
||||
add_interface avalon_slave_0 avalon end
|
||||
set_interface_property avalon_slave_0 addressAlignment NATIVE
|
||||
set_interface_property avalon_slave_0 addressUnits WORDS
|
||||
set_interface_property avalon_slave_0 associatedClock clock
|
||||
set_interface_property avalon_slave_0 associatedReset clock_reset
|
||||
set_interface_property avalon_slave_0 bitsPerSymbol 8
|
||||
set_interface_property avalon_slave_0 burstOnBurstBoundariesOnly false
|
||||
set_interface_property avalon_slave_0 burstcountUnits WORDS
|
||||
set_interface_property avalon_slave_0 explicitAddressSpan 0
|
||||
set_interface_property avalon_slave_0 holdTime 0
|
||||
set_interface_property avalon_slave_0 linewrapBursts false
|
||||
set_interface_property avalon_slave_0 maximumPendingReadTransactions 0
|
||||
set_interface_property avalon_slave_0 readLatency 0
|
||||
set_interface_property avalon_slave_0 readWaitTime 1
|
||||
set_interface_property avalon_slave_0 setupTime 0
|
||||
set_interface_property avalon_slave_0 timingUnits Cycles
|
||||
set_interface_property avalon_slave_0 writeWaitTime 0
|
||||
set_interface_property avalon_slave_0 ENABLED true
|
||||
set_interface_property avalon_slave_0 EXPORT_OF ""
|
||||
set_interface_property avalon_slave_0 PORT_NAME_MAP ""
|
||||
set_interface_property avalon_slave_0 CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property avalon_slave_0 SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port avalon_slave_0 wb_adr_i address Input 3
|
||||
add_interface_port avalon_slave_0 wb_dat_i writedata Input 8
|
||||
add_interface_port avalon_slave_0 wb_dat_o readdata Output 8
|
||||
add_interface_port avalon_slave_0 wb_we_i write Input 1
|
||||
add_interface_port avalon_slave_0 wb_stb_i chipselect Input 1
|
||||
add_interface_port avalon_slave_0 wb_ack_o waitrequest_n Output 1
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isFlash 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isMemoryDevice 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isNonVolatileStorage 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isPrintableDevice 0
|
||||
|
||||
|
||||
#
|
||||
# connection point interrupt_sender
|
||||
#
|
||||
add_interface interrupt_sender interrupt end
|
||||
set_interface_property interrupt_sender associatedAddressablePoint avalon_slave_0
|
||||
set_interface_property interrupt_sender associatedClock clock
|
||||
set_interface_property interrupt_sender associatedReset clock_reset
|
||||
set_interface_property interrupt_sender ENABLED true
|
||||
set_interface_property interrupt_sender EXPORT_OF ""
|
||||
set_interface_property interrupt_sender PORT_NAME_MAP ""
|
||||
set_interface_property interrupt_sender CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property interrupt_sender SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port interrupt_sender wb_inta_o irq Output 1
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
#
|
||||
# opencores_i2c_sw.tcl
|
||||
#
|
||||
|
||||
# Create a new driver
|
||||
create_driver i2c_opencores_driver
|
||||
|
||||
# Associate it with some hardware known as "opencores_i2c"
|
||||
set_sw_property hw_class_name i2c_opencores
|
||||
|
||||
# The version of this driver
|
||||
set_sw_property version 11.0
|
||||
|
||||
# This driver may be incompatible with versions of hardware less
|
||||
# than specified below. Updates to hardware and device drivers
|
||||
# rendering the driver incompatible with older versions of
|
||||
# hardware are noted with this property assignment.
|
||||
#
|
||||
# Multiple-Version compatibility was introduced in version 7.1;
|
||||
# prior versions are therefore excluded.
|
||||
set_sw_property min_compatible_hw_version 7.1
|
||||
|
||||
# Initialize the driver in alt_sys_init()
|
||||
set_sw_property auto_initialize true
|
||||
|
||||
# Location in generated BSP that above sources will be copied into
|
||||
set_sw_property bsp_subdirectory drivers
|
||||
|
||||
|
||||
# Interrupt properties:
|
||||
# This peripheral has an IRQ output but the driver doesn't currently
|
||||
# have any interrupt service routine. To ensure that the BSP tools
|
||||
# do not otherwise limit the BSP functionality for users of the
|
||||
# Nios II enhanced interrupt port, these settings advertise
|
||||
# compliance with both legacy and enhanced interrupt APIs, and to state
|
||||
# that any driver ISR supports preemption. If an interrupt handler
|
||||
# is added to this driver, these must be re-examined for validity.
|
||||
set_sw_property isr_preemption_supported true
|
||||
set_sw_property supported_interrupt_apis "legacy_interrupt_api enhanced_interrupt_api"
|
||||
|
||||
#
|
||||
# Source file listings...
|
||||
#
|
||||
|
||||
# C/C++ source files
|
||||
add_sw_property c_source HAL/src/i2c_opencores.c
|
||||
|
||||
# Include files
|
||||
add_sw_property include_source HAL/inc/i2c_opencores.h
|
||||
add_sw_property include_source inc/i2c_opencores_regs.h
|
||||
|
||||
# This driver supports HAL & UCOSII BSP (OS) types
|
||||
add_sw_property supported_bsp_type HAL
|
||||
add_sw_property supported_bsp_type UCOSII
|
||||
|
||||
# End of file
|
|
@ -0,0 +1,77 @@
|
|||
|
||||
|
||||
#ifndef __I2C_OPENCORES_REGS_H__
|
||||
#define __I2C_OPENCORES_REGS_H__
|
||||
|
||||
#include <io.h>
|
||||
/* prescal clock/(5*desired_SCL) */
|
||||
/* all registers are 8 bits wide but on 32 bit address boundaries.*/
|
||||
/* reg definitions take from i2c_specs.pdf in the docs folder */
|
||||
|
||||
#define IOADDR_I2C_OPENCORES_PRERLO(base) __IO_CALC_ADDRESS_NATIVE(base, 0)
|
||||
#define IORD_I2C_OPENCORES_PRERLO(base) IORD(base, 0)
|
||||
#define IOWR_I2C_OPENCORES_PRERLO(base, data) IOWR(base, 0, data)
|
||||
|
||||
|
||||
#define IOADDR_I2C_OPENCORES_PRERHI(base) __IO_CALC_ADDRESS_NATIVE(base, 0)
|
||||
#define IORD_I2C_OPENCORES_PRERHI(base) IORD(base, 1)
|
||||
#define IOWR_I2C_OPENCORES_PRERHI(base, data) IOWR(base, 1, data)
|
||||
|
||||
|
||||
#define IOADDR_I2C_OPENCORES_CTR(base) __IO_CALC_ADDRESS_NATIVE(base, 2)
|
||||
#define IORD_I2C_OPENCORES_CTR(base) IORD(base, 2)
|
||||
#define IOWR_I2C_OPENCORES_CTR(base, data) IOWR(base, 2, data)
|
||||
/* bit definitions*/
|
||||
#define I2C_OPENCORES_CTR_EN_MSK (0x80)
|
||||
#define I2C_OPENCORES_CTR_EN_OFST (7)
|
||||
#define I2C_OPENCORES_CTR_IEN_MSK (0x40)
|
||||
#define I2C_OPENCORES_CTR_IEN_OFST (6)
|
||||
|
||||
|
||||
#define IOADDR_I2C_OPENCORES_TXR(base) __IO_CALC_ADDRESS_NATIVE(base, 3)
|
||||
#define IOWR_I2C_OPENCORES_TXR(base, data) IOWR(base, 3, data)
|
||||
/* bit definitions*/
|
||||
#define I2C_OPENCORES_TXR_RD_MSK (0x1)
|
||||
#define I2C_OPENCORES_TXR_RD_OFST (0)
|
||||
#define I2C_OPENCORES_TXR_WR_MSK (0x0)
|
||||
#define I2C_OPENCORES_TXR_WR_OFST (0)
|
||||
|
||||
|
||||
#define IOADDR_I2C_OPENCORES_RXR(base) __IO_CALC_ADDRESS_NATIVE(base, 3)
|
||||
#define IORD_I2C_OPENCORES_RXR(base) IORD(base, 3)
|
||||
|
||||
|
||||
#define IOADDR_I2C_OPENCORES_CR(base) __IO_CALC_ADDRESS_NATIVE(base, 4)
|
||||
#define IOWR_I2C_OPENCORES_CR(base, data) IOWR(base, 4, data)
|
||||
/* bit definitions*/
|
||||
#define I2C_OPENCORES_CR_STA_MSK (0x80)
|
||||
#define I2C_OPENCORES_CR_STA_OFST (7)
|
||||
#define I2C_OPENCORES_CR_STO_MSK (0x40)
|
||||
#define I2C_OPENCORES_CR_STO_OFST (6)
|
||||
#define I2C_OPENCORES_CR_RD_MSK (0x20)
|
||||
#define I2C_OPENCORES_CR_RD_OFST (5)
|
||||
#define I2C_OPENCORES_CR_WR_MSK (0x10)
|
||||
#define I2C_OPENCORES_CR_WR_OFST (4)
|
||||
#define I2C_OPENCORES_CR_NACK_MSK (0x8)
|
||||
#define I2C_OPENCORES_CR_NACK_OFST (3)
|
||||
#define I2C_OPENCORES_CR_SPIM_MSK (0x4)
|
||||
#define I2C_OPENCORES_CR_SPIM_OFST (2)
|
||||
#define I2C_OPENCORES_CR_IACK_MSK (0x1)
|
||||
#define I2C_OPENCORES_CR_IACK_OFST (0)
|
||||
|
||||
|
||||
#define IOADDR_I2C_OPENCORES_SR(base) __IO_CALC_ADDRESS_NATIVE(base, 4)
|
||||
#define IORD_I2C_OPENCORES_SR(base) IORD(base, 4)
|
||||
/* bit definitions*/
|
||||
#define I2C_OPENCORES_SR_RXNACK_MSK (0x80)
|
||||
#define I2C_OPENCORES_SR_RXNACK_OFST (7)
|
||||
#define I2C_OPENCORES_SR_BUSY_MSK (0x40)
|
||||
#define I2C_OPENCORES_SR_BUSY_OFST (6)
|
||||
#define I2C_OPENCORES_SR_AL_MSK (0x20)
|
||||
#define I2C_OPENCORES_SR_AL_OFST (5)
|
||||
#define I2C_OPENCORES_SR_TIP_MSK (0x2)
|
||||
#define I2C_OPENCORES_SR_TIP_OFST (1)
|
||||
#define I2C_OPENCORES_SR_IF_MSK (0x1)
|
||||
#define I2C_OPENCORES_SR_IF_OFST (0)
|
||||
|
||||
#endif /* __I2C_OPENCORES_REGS_H__ */
|
|
@ -0,0 +1,2 @@
|
|||
`timescale 1ns / 10ps
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
/******************************************************************************
|
||||
* *
|
||||
* License Agreement *
|
||||
* *
|
||||
* Copyright (c) 2008 Altera Corporation, San Jose, California, USA. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
* copy of this software and associated documentation files (the "Software"), *
|
||||
* to deal in the Software without restriction, including without limitation *
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
|
||||
* and/or sell copies of the Software, and to permit persons to whom the *
|
||||
* Software is furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in *
|
||||
* all copies or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
|
||||
* DEALINGS IN THE SOFTWARE. *
|
||||
* *
|
||||
* This agreement shall be governed in all respects by the laws of the State *
|
||||
* of California and by the laws of the United States of America. *
|
||||
* Altera does not recommend, suggest or require that this reference design *
|
||||
* file be used in conjunction or combination with any other product. *
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Author - JCJB *
|
||||
* *
|
||||
* This design uses the following CRC-32 implementations: *
|
||||
* *
|
||||
* --> Software - Uses modulo 2 division to perform the remainder calculation. *
|
||||
* --> Optimized Software - Uses a lookup table of all possible division *
|
||||
* values. The calculation operates on 8 bit data. *
|
||||
* --> Custom Instruction - Uses a parallel hardware CRC circuit to calculate *
|
||||
* the remainder. The calculation operates on 8, *
|
||||
* 16, 24, or 32 bit data. *
|
||||
* *
|
||||
* The software implementations can be changed to CRC-16 or CRC-CCITT however *
|
||||
* the custom instruction must be modified as well to support the same *
|
||||
* standard. Simply use the values defined in crc.h to change the standard *
|
||||
* used (using the same values in the hardware parameterization) or define *
|
||||
* your own standard. *
|
||||
*******************************************************************************/
|
||||
|
||||
#include "system.h"
|
||||
#include "stdio.h"
|
||||
#include "crc.h"
|
||||
#include "ci_crc.h"
|
||||
#include "sys/alt_timestamp.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
|
||||
/* Modify these values to adjust the test being performed */
|
||||
#define NUMBER_OF_BUFFERS 32
|
||||
#define BUFFER_SIZE 256 /* in bytes */
|
||||
|
||||
/* Change the name of memory device according to what you are using
|
||||
* e.g.: DDR_SDRAM_0 ##_SPAN
|
||||
* SSRAM_0 ##_SPAN
|
||||
*/
|
||||
#define MEMORY_DEVICE_SIZE 32768
|
||||
|
||||
|
||||
/* Make sure there is room left for Nios II text, rodata, rwdata, stack,
|
||||
* and heap. This software and the buffer space must fit within the
|
||||
* size of memory device. A total of 1.5 MBytes is reserved. If BUFFER_SIZE
|
||||
* is a multiple of four then exactly 256kB will be left, otherwise is
|
||||
* amount will be less since the column dimension needs some padding to
|
||||
* stay 32 bit aligned
|
||||
*/
|
||||
#if ((BUFFER_SIZE * NUMBER_OF_BUFFERS) >= MEMORY_DEVICE_SIZE - 10000)
|
||||
#error Your buffer space has exceeded the maximum allowable space. Please\
|
||||
reduce the buffer space so that there is enough room to hold Nios II\
|
||||
code.
|
||||
#endif
|
||||
|
||||
|
||||
/* This will line up the data onto a 32 bit (or greater) boundary. A 2d array
|
||||
* is being used here for simplicity. The first dimension represents a byte
|
||||
* of data and the second dimension represents an individual buffer
|
||||
*/
|
||||
#if ((BUFFER_SIZE & 0x3) == 0)
|
||||
unsigned char data_buffer_region[NUMBER_OF_BUFFERS][BUFFER_SIZE] __attribute__ ((aligned(4)));
|
||||
#else /* need to allocate extra bytes so that all buffers start on a 32 bit
|
||||
boundaries by rounding up the column dimension to the next power of 4
|
||||
*/
|
||||
unsigned char data_buffer_region[NUMBER_OF_BUFFERS][BUFFER_SIZE + 4 - (BUFFER_SIZE&0x3)] __attribute__ ((aligned(4)));
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
unsigned long buffer_counter, data_counter;
|
||||
unsigned long sw_slow_results[NUMBER_OF_BUFFERS];
|
||||
unsigned long sw_fast_results[NUMBER_OF_BUFFERS];
|
||||
unsigned long ci_results[NUMBER_OF_BUFFERS];
|
||||
unsigned char random_data = 0x5A;
|
||||
//unsigned long sw_slow_timeA, sw_slow_timeB;
|
||||
// unsigned long sw_fast_timeA, sw_fast_timeB;
|
||||
// unsigned long ci_timeA, ci_timeB;
|
||||
|
||||
alt_u32 sw_slow_timeA, sw_slow_timeB;
|
||||
alt_u32 sw_fast_timeA, sw_fast_timeB;
|
||||
alt_u32 ci_timeA, ci_timeB;
|
||||
|
||||
|
||||
printf("+-----------------------------------------------------------+\n");
|
||||
printf("| Comparison between software and custom instruction CRC32 |\n");
|
||||
printf("+-----------------------------------------------------------+\n\n\n");
|
||||
|
||||
printf("System specification\n");
|
||||
printf("--------------------\n");
|
||||
|
||||
printf("System clock speed = %lu MHz\n", (unsigned long)ALT_CPU_FREQ /(unsigned long)1000000);
|
||||
printf("Number of buffer locations = %d\n", NUMBER_OF_BUFFERS);
|
||||
printf("Size of each buffer = %d bytes\n\n\n", BUFFER_SIZE);
|
||||
|
||||
|
||||
/* Initializing the data buffers */
|
||||
printf("Initializing all of the buffers with pseudo-random data\n");
|
||||
printf("-------------------------------------------------------\n");
|
||||
for(buffer_counter = 0; buffer_counter < NUMBER_OF_BUFFERS; buffer_counter++)
|
||||
{
|
||||
for(data_counter = 0; data_counter < BUFFER_SIZE; data_counter++)
|
||||
{
|
||||
data_buffer_region[buffer_counter][data_counter] = random_data;
|
||||
random_data = (random_data >> 4) + (random_data << 4) + (data_counter & 0xFF);
|
||||
}
|
||||
}
|
||||
printf("Initialization completed\n\n\n");
|
||||
|
||||
|
||||
if(alt_timestamp_start() < 0) // starts the timestamp timer
|
||||
{
|
||||
printf("Please add the high resolution timer to the timestamp timer setting in the syslib properties page.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* Slow software CRC based on a modulo 2 division implementation */
|
||||
printf("Running the software CRC\n");
|
||||
printf("------------------------\n");
|
||||
sw_slow_timeA = alt_timestamp();
|
||||
|
||||
for(buffer_counter = 0; buffer_counter < NUMBER_OF_BUFFERS; buffer_counter++)
|
||||
{
|
||||
sw_slow_results[buffer_counter] = crcSlow(data_buffer_region[buffer_counter], BUFFER_SIZE);
|
||||
}
|
||||
sw_slow_timeB = alt_timestamp();
|
||||
|
||||
printf("Completed\n\n\n");
|
||||
|
||||
|
||||
/* Fast software CRC based on a lookup table implementation */
|
||||
crcInit();
|
||||
printf("Running the optimized software CRC\n");
|
||||
printf("----------------------------------\n");
|
||||
sw_fast_timeA = alt_timestamp();
|
||||
for(buffer_counter = 0; buffer_counter < NUMBER_OF_BUFFERS; buffer_counter++)
|
||||
{
|
||||
sw_fast_results[buffer_counter] = crcFast(data_buffer_region[buffer_counter], BUFFER_SIZE);
|
||||
}
|
||||
sw_fast_timeB = alt_timestamp();
|
||||
printf("Completed\n\n\n");
|
||||
|
||||
|
||||
/* Custom instruction CRC */
|
||||
printf("Running the custom instruction CRC\n");
|
||||
printf("----------------------------------\n");
|
||||
ci_timeA = alt_timestamp();
|
||||
for(buffer_counter = 0; buffer_counter < NUMBER_OF_BUFFERS; buffer_counter++)
|
||||
{
|
||||
ci_results[buffer_counter] = crcCI(data_buffer_region[buffer_counter], BUFFER_SIZE);
|
||||
}
|
||||
ci_timeB = alt_timestamp();
|
||||
printf("Completed\n\n\n");
|
||||
|
||||
/* Validation of results */
|
||||
printf("Validating the CRC results from all implementations\n");
|
||||
printf("----------------------------------------------------\n");
|
||||
for(buffer_counter = 0; buffer_counter < NUMBER_OF_BUFFERS; buffer_counter++)
|
||||
{
|
||||
/* Test every combination of results to make sure they are consistant */
|
||||
if((sw_slow_results[buffer_counter] != ci_results[buffer_counter]) |
|
||||
(sw_fast_results[buffer_counter] != ci_results[buffer_counter]))
|
||||
{
|
||||
printf("FAILURE! Software CRC = 0x%lx, Optimized Software CRC = 0x%lx, Custom Instruction CRC = 0x%lx,\n",
|
||||
sw_slow_results[buffer_counter], sw_fast_results[buffer_counter], ci_results[buffer_counter]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
printf("All CRC implementations produced the same results\n\n\n");
|
||||
|
||||
|
||||
// Report processing times
|
||||
printf("Processing time for each implementation\n");
|
||||
printf("---------------------------------------\n");
|
||||
printf("Software CRC = %.2lu ms\n", 1000*((unsigned long)(sw_slow_timeB-sw_slow_timeA))/((unsigned long)alt_timestamp_freq()));
|
||||
printf("Optimized software CRC = %.2lu ms\n", 1000*((unsigned long)(sw_fast_timeB-sw_fast_timeA))/((unsigned long)alt_timestamp_freq()));
|
||||
printf("Custom instruction CRC = %.2lu ms\n\n\n", 1000*((unsigned long)(ci_timeB-ci_timeA))/((unsigned long)alt_timestamp_freq()));
|
||||
|
||||
printf("Processing throughput for each implementation\n"); // throughput = total bits / (time(s) * 1000000)
|
||||
printf("---------------------------------------------\n");
|
||||
printf("Software CRC = %.2lu Mbps\n", (8 * NUMBER_OF_BUFFERS * BUFFER_SIZE)/(1000000*(unsigned long)(sw_slow_timeB-sw_slow_timeA)/((unsigned long)alt_timestamp_freq())));
|
||||
printf("Optimized software CRC = %.2lu Mbps\n", (8 * NUMBER_OF_BUFFERS * BUFFER_SIZE)/(1000000*(unsigned long)(sw_fast_timeB-sw_fast_timeA)/((unsigned long)alt_timestamp_freq())));
|
||||
printf("Custom instruction CRC = %.2lu Mbps\n\n\n", (8 * NUMBER_OF_BUFFERS * BUFFER_SIZE)/(1000000*(unsigned long)(ci_timeB-ci_timeA)/((unsigned long)alt_timestamp_freq())));
|
||||
|
||||
printf("Speedup ratio\n");
|
||||
printf("-------------\n");
|
||||
printf("Custom instruction CRC vs software CRC = %lu\n", ((unsigned long)(sw_slow_timeB-sw_slow_timeA))/((unsigned long)(ci_timeB-ci_timeA)));
|
||||
printf("Custom instruction CRC vs optimized software CRC = %lu\n", ((unsigned long)(sw_fast_timeB-sw_fast_timeA))/((unsigned long)(ci_timeB-ci_timeA)));
|
||||
printf("Optimized software CRC vs software CRC= %lu\n", ((unsigned long)(sw_slow_timeB-sw_slow_timeA))/((unsigned long)(sw_fast_timeB-sw_fast_timeA)));
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/******************************************************************************
|
||||
* *
|
||||
* License Agreement *
|
||||
* *
|
||||
* Copyright (c) 2008 Altera Corporation, San Jose, California, USA. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
* copy of this software and associated documentation files (the "Software"), *
|
||||
* to deal in the Software without restriction, including without limitation *
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
|
||||
* and/or sell copies of the Software, and to permit persons to whom the *
|
||||
* Software is furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in *
|
||||
* all copies or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
|
||||
* DEALINGS IN THE SOFTWARE. *
|
||||
* *
|
||||
* This agreement shall be governed in all respects by the laws of the State *
|
||||
* of California and by the laws of the United States of America. *
|
||||
* Altera does not recommend, suggest or require that this reference design *
|
||||
* file be used in conjunction or combination with any other product. *
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#ifndef _CRCCI_H_
|
||||
#define _CRCCI_H_
|
||||
|
||||
unsigned long crcCI(unsigned char * input_data, unsigned long input_data_length, int do_initialize);
|
||||
|
||||
#endif //_CRCCI_H_
|
|
@ -0,0 +1,109 @@
|
|||
/******************************************************************************
|
||||
* *
|
||||
* License Agreement *
|
||||
* *
|
||||
* Copyright (c) 2008 Altera Corporation, San Jose, California, USA. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
* copy of this software and associated documentation files (the "Software"), *
|
||||
* to deal in the Software without restriction, including without limitation *
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
|
||||
* and/or sell copies of the Software, and to permit persons to whom the *
|
||||
* Software is furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in *
|
||||
* all copies or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
|
||||
* DEALINGS IN THE SOFTWARE. *
|
||||
* *
|
||||
* This agreement shall be governed in all respects by the laws of the State *
|
||||
* of California and by the laws of the United States of America. *
|
||||
* Altera does not recommend, suggest or require that this reference design *
|
||||
* file be used in conjunction or combination with any other product. *
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Filename: crc.h
|
||||
*
|
||||
* Description: A header file describing the various CRC standards.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2000 by Michael Barr. This software is placed into
|
||||
* the public domain and may be used for any purpose. However, this
|
||||
* notice must not be changed or removed and no warranty is either
|
||||
* expressed or implied by its publication or distribution.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef _crc_h
|
||||
#define _crc_h
|
||||
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE !FALSE
|
||||
|
||||
/*
|
||||
* Select the CRC standard from the list that follows.
|
||||
*/
|
||||
#define CRC32
|
||||
|
||||
|
||||
#if defined(CRC_CCITT)
|
||||
|
||||
typedef unsigned short crc;
|
||||
|
||||
#define CRC_NAME "CRC-CCITT"
|
||||
#define POLYNOMIAL 0x1021
|
||||
#define INITIAL_REMAINDER 0xFFFF
|
||||
#define FINAL_XOR_VALUE 0x0000
|
||||
#define REFLECT_DATA FALSE
|
||||
#define REFLECT_REMAINDER FALSE
|
||||
#define CHECK_VALUE 0x29B1
|
||||
|
||||
#elif defined(CRC16)
|
||||
|
||||
typedef unsigned short crc;
|
||||
|
||||
#define CRC_NAME "CRC-16"
|
||||
#define POLYNOMIAL 0x8005
|
||||
#define INITIAL_REMAINDER 0x0000
|
||||
#define FINAL_XOR_VALUE 0x0000
|
||||
#define REFLECT_DATA TRUE
|
||||
#define REFLECT_REMAINDER TRUE
|
||||
#define CHECK_VALUE 0xBB3D
|
||||
|
||||
#elif defined(CRC32)
|
||||
|
||||
typedef unsigned long crc;
|
||||
|
||||
#define CRC_NAME "CRC-32"
|
||||
#define POLYNOMIAL 0x04C11DB7
|
||||
#define INITIAL_REMAINDER 0xFFFFFFFF
|
||||
#define FINAL_XOR_VALUE 0xFFFFFFFF
|
||||
#define REFLECT_DATA TRUE
|
||||
#define REFLECT_REMAINDER TRUE
|
||||
#define CHECK_VALUE 0xCBF43926
|
||||
|
||||
#else
|
||||
|
||||
#error "One of CRC_CCITT, CRC16, or CRC32 must be #define'd."
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void crcInit(void);
|
||||
crc crcSlow(unsigned char const message[], int nBytes);
|
||||
crc crcFast(unsigned char const message[], int nBytes);
|
||||
|
||||
|
||||
#endif /* _crc_h */
|
|
@ -0,0 +1,97 @@
|
|||
/******************************************************************************
|
||||
* *
|
||||
* License Agreement *
|
||||
* *
|
||||
* Copyright (c) 2008 Altera Corporation, San Jose, California, USA. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
* copy of this software and associated documentation files (the "Software"), *
|
||||
* to deal in the Software without restriction, including without limitation *
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
|
||||
* and/or sell copies of the Software, and to permit persons to whom the *
|
||||
* Software is furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in *
|
||||
* all copies or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
|
||||
* DEALINGS IN THE SOFTWARE. *
|
||||
* *
|
||||
* This agreement shall be governed in all respects by the laws of the State *
|
||||
* of California and by the laws of the United States of America. *
|
||||
* Altera does not recommend, suggest or require that this reference design *
|
||||
* file be used in conjunction or combination with any other product. *
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Filename: ci_crc.c
|
||||
*
|
||||
* Description: Custom instruction implementations of the CRC.
|
||||
*
|
||||
* Notes: A macro is defined that is used to access the CRC custom
|
||||
* instruction.
|
||||
*********************************************************************/
|
||||
|
||||
#include "system.h"
|
||||
|
||||
/*The n values and their corresponding operation are as follow:
|
||||
* n = 0, Initialize the custom instruction to the initial remainder value
|
||||
* n = 1, Write 8 bits data to custom instruction
|
||||
* n = 2, Write 16 bits data to custom instruction
|
||||
* n = 3, Write 32 bits data to custom instruction
|
||||
* n = 4, Read 32 bits data from the custom instruction
|
||||
* n = 5, Read 64 bits data from the custom instruction
|
||||
* n = 6, Read 96 bits data from the custom instruction
|
||||
* n = 7, Read 128 bits data from the custom instruction*/
|
||||
#define CRC_CI_MACRO(n, A) __builtin_custom_ini(ALT_CI_NIOS2_HW_CRC32_0_N + (n & 0x7), (A))
|
||||
|
||||
unsigned long crcCI(unsigned char * input_data, unsigned long input_data_length, int do_initialize)
|
||||
{
|
||||
unsigned long index;
|
||||
/* copy of the data buffer pointer so that it can advance by different widths */
|
||||
void * input_data_copy = (void *)input_data;
|
||||
|
||||
/* The custom instruction CRC will initialize to the inital remainder value */
|
||||
if (do_initialize)
|
||||
CRC_CI_MACRO(0,0);
|
||||
|
||||
/* Write 32 bit data to the custom instruction. If the buffer does not end
|
||||
* on a 32 bit boundary then the remaining data will be sent to the custom
|
||||
* instruction in the 'if' statement below.
|
||||
*/
|
||||
for(index = 0; index < (input_data_length & 0xFFFFFFFC); index+=4)
|
||||
{
|
||||
CRC_CI_MACRO(3, *(unsigned long *)input_data_copy);
|
||||
input_data_copy += 4; /* void pointer, must move by 4 for each word */
|
||||
}
|
||||
|
||||
/* Write the remainder of the buffer if it does not end on a word boundary */
|
||||
if((input_data_length & 0x3) == 0x3) /* 3 bytes left */
|
||||
{
|
||||
CRC_CI_MACRO(2, *(unsigned short *)input_data_copy);
|
||||
input_data_copy += 2;
|
||||
CRC_CI_MACRO(1, *(unsigned char *)input_data_copy);
|
||||
}
|
||||
else if((input_data_length & 0x3) == 0x2) /* 2 bytes left */
|
||||
{
|
||||
CRC_CI_MACRO(2, *(unsigned short *)input_data_copy);
|
||||
}
|
||||
else if((input_data_length & 0x3) == 0x1) /* 1 byte left */
|
||||
{
|
||||
CRC_CI_MACRO(1, *(unsigned char *)input_data_copy);
|
||||
}
|
||||
|
||||
/* There are 4 registers in the CRC custom instruction. Since
|
||||
* this example uses CRC-32 only the first register must be read
|
||||
* in order to receive the full result.
|
||||
*/
|
||||
return CRC_CI_MACRO(4, 0);
|
||||
}
|
|
@ -0,0 +1,265 @@
|
|||
/******************************************************************************
|
||||
* *
|
||||
* License Agreement *
|
||||
* *
|
||||
* Copyright (c) 2008 Altera Corporation, San Jose, California, USA. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
* copy of this software and associated documentation files (the "Software"), *
|
||||
* to deal in the Software without restriction, including without limitation *
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
|
||||
* and/or sell copies of the Software, and to permit persons to whom the *
|
||||
* Software is furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in *
|
||||
* all copies or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
|
||||
* DEALINGS IN THE SOFTWARE. *
|
||||
* *
|
||||
* This agreement shall be governed in all respects by the laws of the State *
|
||||
* of California and by the laws of the United States of America. *
|
||||
* Altera does not recommend, suggest or require that this reference design *
|
||||
* file be used in conjunction or combination with any other product. *
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Filename: crc.c
|
||||
*
|
||||
* Description: Slow and fast implementations of the CRC standards.
|
||||
*
|
||||
* Notes: The parameters for each supported CRC standard are
|
||||
* defined in the header file crc.h. The implementations
|
||||
* here should stand up to further additions to that list.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2000 by Michael Barr. This software is placed into
|
||||
* the public domain and may be used for any purpose. However, this
|
||||
* notice must not be changed or removed and no warranty is either
|
||||
* expressed or implied by its publication or distribution.
|
||||
**********************************************************************/
|
||||
|
||||
#include "crc.h"
|
||||
|
||||
|
||||
/*
|
||||
* Derive parameters from the standard-specific parameters in crc.h.
|
||||
*/
|
||||
#define WIDTH (8 * sizeof(crc))
|
||||
#define TOPBIT (1 << (WIDTH - 1))
|
||||
|
||||
#if (REFLECT_DATA == TRUE)
|
||||
#undef REFLECT_DATA
|
||||
#define REFLECT_DATA(X) ((unsigned char) reflect((X), 8))
|
||||
#else
|
||||
#undef REFLECT_DATA
|
||||
#define REFLECT_DATA(X) (X)
|
||||
#endif
|
||||
|
||||
#if (REFLECT_REMAINDER == TRUE)
|
||||
#undef REFLECT_REMAINDER
|
||||
#define REFLECT_REMAINDER(X) ((crc) reflect((X), WIDTH))
|
||||
#else
|
||||
#undef REFLECT_REMAINDER
|
||||
#define REFLECT_REMAINDER(X) (X)
|
||||
#endif
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Function: reflect()
|
||||
*
|
||||
* Description: Reorder the bits of a binary sequence, by reflecting
|
||||
* them about the middle position.
|
||||
*
|
||||
* Notes: No checking is done that nBits <= 32.
|
||||
*
|
||||
* Returns: The reflection of the original data.
|
||||
*
|
||||
*********************************************************************/
|
||||
static unsigned long
|
||||
reflect(unsigned long data, unsigned char nBits)
|
||||
{
|
||||
unsigned long reflection = 0x00000000;
|
||||
unsigned char bit;
|
||||
|
||||
/*
|
||||
* Reflect the data about the center bit.
|
||||
*/
|
||||
for (bit = 0; bit < nBits; ++bit)
|
||||
{
|
||||
/*
|
||||
* If the LSB bit is set, set the reflection of it.
|
||||
*/
|
||||
if (data & 0x01)
|
||||
{
|
||||
reflection |= (1 << ((nBits - 1) - bit));
|
||||
}
|
||||
|
||||
data = (data >> 1);
|
||||
}
|
||||
|
||||
return (reflection);
|
||||
|
||||
} /* reflect() */
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Function: crcSlow()
|
||||
*
|
||||
* Description: Compute the CRC of a given message.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Returns: The CRC of the message.
|
||||
*
|
||||
*********************************************************************/
|
||||
crc
|
||||
crcSlow(unsigned char const message[], int nBytes)
|
||||
{
|
||||
crc remainder = INITIAL_REMAINDER;
|
||||
int byte;
|
||||
unsigned char bit;
|
||||
|
||||
|
||||
/*
|
||||
* Perform modulo-2 division, a byte at a time.
|
||||
*/
|
||||
for (byte = 0; byte < nBytes; ++byte)
|
||||
{
|
||||
/*
|
||||
* Bring the next byte into the remainder.
|
||||
*/
|
||||
remainder ^= (REFLECT_DATA(message[byte]) << (WIDTH - 8));
|
||||
|
||||
/*
|
||||
* Perform modulo-2 division, a bit at a time.
|
||||
*/
|
||||
for (bit = 8; bit > 0; --bit)
|
||||
{
|
||||
/*
|
||||
* Try to divide the current data bit.
|
||||
*/
|
||||
if (remainder & TOPBIT)
|
||||
{
|
||||
remainder = (remainder << 1) ^ POLYNOMIAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
remainder = (remainder << 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The final remainder is the CRC result.
|
||||
*/
|
||||
return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);
|
||||
|
||||
} /* crcSlow() */
|
||||
|
||||
|
||||
crc crcTable[256];
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Function: crcInit()
|
||||
*
|
||||
* Description: Populate the partial CRC lookup table.
|
||||
*
|
||||
* Notes: This function must be rerun any time the CRC standard
|
||||
* is changed. If desired, it can be run "offline" and
|
||||
* the table results stored in an embedded system's ROM.
|
||||
*
|
||||
* Returns: None defined.
|
||||
*
|
||||
*********************************************************************/
|
||||
void
|
||||
crcInit(void)
|
||||
{
|
||||
crc remainder;
|
||||
int dividend;
|
||||
unsigned char bit;
|
||||
|
||||
|
||||
/*
|
||||
* Compute the remainder of each possible dividend.
|
||||
*/
|
||||
for (dividend = 0; dividend < 256; ++dividend)
|
||||
{
|
||||
/*
|
||||
* Start with the dividend followed by zeros.
|
||||
*/
|
||||
remainder = dividend << (WIDTH - 8);
|
||||
|
||||
/*
|
||||
* Perform modulo-2 division, a bit at a time.
|
||||
*/
|
||||
for (bit = 8; bit > 0; --bit)
|
||||
{
|
||||
/*
|
||||
* Try to divide the current data bit.
|
||||
*/
|
||||
if (remainder & TOPBIT)
|
||||
{
|
||||
remainder = (remainder << 1) ^ POLYNOMIAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
remainder = (remainder << 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the result into the table.
|
||||
*/
|
||||
crcTable[dividend] = remainder;
|
||||
}
|
||||
|
||||
} /* crcInit() */
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Function: crcFast()
|
||||
*
|
||||
* Description: Compute the CRC of a given message.
|
||||
*
|
||||
* Notes: crcInit() must be called first.
|
||||
*
|
||||
* Returns: The CRC of the message.
|
||||
*
|
||||
*********************************************************************/
|
||||
crc
|
||||
crcFast(unsigned char const message[], int nBytes)
|
||||
{
|
||||
crc remainder = INITIAL_REMAINDER;
|
||||
unsigned char data;
|
||||
int byte;
|
||||
|
||||
|
||||
/*
|
||||
* Divide the message by the polynomial, a byte at a time.
|
||||
*/
|
||||
for (byte = 0; byte < nBytes; ++byte)
|
||||
{
|
||||
data = REFLECT_DATA(message[byte]) ^ (remainder >> (WIDTH - 8));
|
||||
remainder = crcTable[data] ^ (remainder << 8);
|
||||
}
|
||||
|
||||
/*
|
||||
* The final remainder is the CRC.
|
||||
*/
|
||||
return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);
|
||||
|
||||
} /* crcFast() */
|
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
Legal Notice: (C)2006 Altera Corporation. All rights reserved. Your
|
||||
use of Altera Corporation's design tools, logic functions and other
|
||||
software and tools, and its AMPP partner logic functions, and any
|
||||
output files any of the foregoing (including device programming or
|
||||
simulation files), and any associated documentation or information are
|
||||
expressly subject to the terms and conditions of the Altera Program
|
||||
License Subscription Agreement or other applicable license agreement,
|
||||
including, without limitation, that your use is for the sole purpose
|
||||
of programming logic devices manufactured by Altera and sold by Altera
|
||||
or its authorized distributors. Please refer to the applicable
|
||||
agreement for further details.
|
||||
*/
|
||||
|
||||
/*
|
||||
This component supports 8, 16, 24, and 32 bit little endian data
|
||||
and any CRC standard between 1 to 128 bits. Through parameterization
|
||||
you can change the CRC standard which will take effect after you
|
||||
regenerate your system in SOPC Builder.
|
||||
|
||||
Register Map:
|
||||
000 -> reset the CRC peripheral to the inital value (data and byte enables ignored)
|
||||
001 -> data write between 1-32 bits
|
||||
010 -> reserved
|
||||
011 -> reserved
|
||||
100 -> read bits 1-32 of the crc result
|
||||
101 -> read bits 33-64 of the crc result (where applicable)
|
||||
110 -> read bits 65-96 of the crc result (where applicable)
|
||||
111 -> read bits 97-128 of the crc result (where applicable)
|
||||
|
||||
Write latency = 0
|
||||
Read latency = 1
|
||||
|
||||
Note: This component uses four blocks of eight bits of data in cascade.
|
||||
To improve the timing of logic you can create seperate cascades
|
||||
for 8, 16, 24, and 32 bit data which will allow for smaller area
|
||||
and a shorter combinational depth. Since CRC logic consumes power
|
||||
even when not in use you can also add a logic disable feature using
|
||||
the chipselect signal. Even though the registered CRC value is
|
||||
held constant when the circuit is not in use the input data will
|
||||
change during this time and cause the CRC cascade logic to react.
|
||||
*/
|
||||
|
||||
|
||||
module CRC_Component (clk,
|
||||
reset,
|
||||
address,
|
||||
writedata,
|
||||
byteenable,
|
||||
write,
|
||||
read,
|
||||
chipselect,
|
||||
readdata);
|
||||
|
||||
/*
|
||||
Using these parameters you can create any CRC ranging from one bit (parity checker)
|
||||
up to 128 bits. The following list describes the function of each parameter:
|
||||
|
||||
crc_width:
|
||||
The width of the registered CRC result, this value is typically apart of
|
||||
the name of the standard (CRC32 is 32 bits wide). Adjusting this value
|
||||
will impact the logic resource usage.
|
||||
|
||||
polynomial_initial:
|
||||
The initial value set for the CRC result register. By writing any data to address 0
|
||||
this value will be stored in the result register thereby clearing any previously existing
|
||||
value. This value must be the same width as 'crc_width'
|
||||
|
||||
polynomial:
|
||||
This is the divisor value used on the input data. Typically shown in polynomial format
|
||||
the value symbolizes the placement of xor operation on the input data. In synthesis, the
|
||||
polynomial bits that are '1' will create a not gate, whereas the bits that are '0' will
|
||||
simply create a wire. Even with 32 stages of these operations cascaded, the simple logic
|
||||
will not become a significant factor on logic utilization or fmax. This value must be the
|
||||
same width as 'crc_width'
|
||||
|
||||
reflected_input:
|
||||
Some CRC standards require that all the input bits be reflected around the center point.
|
||||
This option is enabled with '1' and disabled with '0'. Typically this option is enabled
|
||||
or disabled with 'reflected_output'.
|
||||
|
||||
reflected_output:
|
||||
Some CRC standards require that all the output bits be reflected around the center point.
|
||||
This operation occurs before the final optional xor output step. This option is enabled
|
||||
with '1' and disabled with '0'. Typically this option is enabled or disabled with
|
||||
'reflected_input' (to undo the input reversal typically).
|
||||
|
||||
xor_output:
|
||||
This is the value used to bitwise xor the CRC result. Most standards use either all zeros
|
||||
or all ones for this value. When zeros are used the CRC result is passed directly and when
|
||||
ones are used the CRC result is inverted. Since it's no mandatory that this value be all
|
||||
ones or zeros, this operation occurs before the output reflection when applicable.
|
||||
*/
|
||||
|
||||
parameter crc_width = 32;
|
||||
parameter polynomial_inital = 32'hFFFFFFFF;
|
||||
parameter polynomial = 32'h04C11DB7;
|
||||
parameter reflected_input = 1;
|
||||
parameter reflected_output = 1;
|
||||
parameter xor_output = 32'hFFFFFFFF;
|
||||
|
||||
|
||||
input clk;
|
||||
input reset;
|
||||
input [2:0] address;
|
||||
input [31:0] writedata;
|
||||
input [3:0] byteenable;
|
||||
input write;
|
||||
input read;
|
||||
input chipselect;
|
||||
output [31:0] readdata;
|
||||
|
||||
reg [crc_width-1:0] crc_value;
|
||||
wire [crc_width-1:0] poly = polynomial;
|
||||
wire [crc_width-1:0] cascade [3:0];
|
||||
wire [7:0] block0_data, block1_data, block2_data, block3_data;
|
||||
wire [crc_width-1:0] result, result_xored;
|
||||
wire [31:0] mux_result;
|
||||
reg [31:0] readdata;
|
||||
|
||||
|
||||
/*
|
||||
Some standards like CRC16 and CRC32 require this bitreversal for serial
|
||||
devices like ethernet, uarts, usb, etc...
|
||||
*/
|
||||
genvar index;
|
||||
generate if (reflected_input == 1)
|
||||
begin
|
||||
for(index = 0; index < 8; index = index + 1)
|
||||
begin: input_reflection
|
||||
assign block0_data[index] = writedata[7-index];
|
||||
assign block1_data[index] = writedata[15-index];
|
||||
assign block2_data[index] = writedata[23-index];
|
||||
assign block3_data[index] = writedata[31-index];
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
assign block0_data = writedata[7:0];
|
||||
assign block1_data = writedata[15:8];
|
||||
assign block2_data = writedata[23:16];
|
||||
assign block3_data = writedata[31:24];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
/*
|
||||
Control for the registered events. It assumes that either 8, 16, 24, or 32
|
||||
bit data is being written using byte enables. It is important that the data
|
||||
be in little endian format and no gaps of byte enables be present (like
|
||||
1011 or 1101 for example)
|
||||
*/
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if(reset == 1)
|
||||
begin
|
||||
crc_value <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(write && chipselect && (address == 3'b000))
|
||||
begin
|
||||
crc_value <= polynomial_inital; // reset the crc to the initial value
|
||||
end
|
||||
else if(write && chipselect && (address == 3'b001))
|
||||
begin
|
||||
if(byteenable == 4'b0001) // 8 bit data input
|
||||
begin
|
||||
crc_value <= cascade[0];
|
||||
end
|
||||
else if(byteenable == 4'b0011) // 16 bit data input
|
||||
begin
|
||||
crc_value <= cascade[1];
|
||||
end
|
||||
else if(byteenable == 4'b0111) // 24 bit data input
|
||||
begin
|
||||
crc_value <= cascade[2];
|
||||
end
|
||||
else if(byteenable == 4'b1111) // 32 bit data input
|
||||
begin
|
||||
crc_value <= cascade[3];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
/* four stages of cascade blocks (each block is crc_width x 8 bits) */
|
||||
XOR_Shift_Block cascade_block0(.block_input(crc_value), .poly(poly), .data_input(block0_data), .block_output(cascade[0]));
|
||||
defparam cascade_block0.crc_width = crc_width;
|
||||
XOR_Shift_Block cascade_block1(.block_input(cascade[0]), .poly(poly), .data_input(block1_data), .block_output(cascade[1]));
|
||||
defparam cascade_block1.crc_width = crc_width;
|
||||
XOR_Shift_Block cascade_block2(.block_input(cascade[1]), .poly(poly), .data_input(block2_data), .block_output(cascade[2]));
|
||||
defparam cascade_block2.crc_width = crc_width;
|
||||
XOR_Shift_Block cascade_block3(.block_input(cascade[2]), .poly(poly), .data_input(block3_data), .block_output(cascade[3]));
|
||||
defparam cascade_block3.crc_width = crc_width;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Some standards like CRC16 and CRC32 require this bitreversal.
|
||||
This is to better support serial devices like uarts, ethernet, usb, etc...)
|
||||
*/
|
||||
generate if (reflected_output == 1)
|
||||
begin
|
||||
for(index = 0; index < crc_width; index = index + 1)
|
||||
begin: output_reflection32
|
||||
assign result[index] = crc_value[(crc_width-1)-index];
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
assign result = crc_value;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
/* This final xor operation occurs after the bit swap */
|
||||
assign result_xored = result ^ xor_output;
|
||||
|
||||
|
||||
/* Generates the appropriate MUX logic depending on the CRC width */
|
||||
generate if((crc_width > 32) && (crc_width < 65))
|
||||
begin
|
||||
assign mux_result = (address == 3'b100)? result_xored[31:0] : result_xored[crc_width-1:32];
|
||||
end
|
||||
else if((crc_width > 64) && (crc_width < 97))
|
||||
begin
|
||||
assign mux_result = (address == 3'b100)? result_xored[31:0] :
|
||||
((address == 3'b101)? result_xored[63:32] : result_xored[crc_width-1:64]);
|
||||
end
|
||||
else if((crc_width > 96) && (crc_width < 129))
|
||||
begin
|
||||
assign mux_result = (address == 3'b100)? result_xored[31:0] :
|
||||
((address == 3'b101)? result_xored[63:32] :
|
||||
((address == 3'b110)? result_xored[95:64] : result_xored[crc_width-1:96]));
|
||||
end
|
||||
else
|
||||
begin
|
||||
assign mux_result = result_xored;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
/* Registering the return path of the CRC data (32 bits of it) */
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if(reset == 1)
|
||||
begin
|
||||
readdata <= 0;
|
||||
end
|
||||
else if((read == 1) && (chipselect == 1))
|
||||
begin
|
||||
readdata <= mux_result;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
/* a single cascade block of width: crc_width and a length of eight input bits */
|
||||
module XOR_Shift_Block(block_input,
|
||||
poly,
|
||||
data_input,
|
||||
block_output);
|
||||
parameter crc_width = 32;
|
||||
|
||||
input [(crc_width-1):0] block_input;
|
||||
input [(crc_width-1):0] poly;
|
||||
input [7:0] data_input;
|
||||
output [(crc_width-1):0] block_output;
|
||||
|
||||
wire [(crc_width-1):0] cascade [7:0];
|
||||
|
||||
XOR_Shift bit_0(.stage_input(block_input), .poly(poly), .new_bit(data_input[7]), .stage_output(cascade[0]));
|
||||
defparam bit_0.crc_width = crc_width;
|
||||
XOR_Shift bit_1(.stage_input(cascade[0]), .poly(poly), .new_bit(data_input[6]), .stage_output(cascade[1]));
|
||||
defparam bit_1.crc_width = crc_width;
|
||||
XOR_Shift bit_2(.stage_input(cascade[1]), .poly(poly), .new_bit(data_input[5]), .stage_output(cascade[2]));
|
||||
defparam bit_2.crc_width = crc_width;
|
||||
XOR_Shift bit_3(.stage_input(cascade[2]), .poly(poly), .new_bit(data_input[4]), .stage_output(cascade[3]));
|
||||
defparam bit_3.crc_width = crc_width;
|
||||
XOR_Shift bit_4(.stage_input(cascade[3]), .poly(poly), .new_bit(data_input[3]), .stage_output(cascade[4]));
|
||||
defparam bit_4.crc_width = crc_width;
|
||||
XOR_Shift bit_5(.stage_input(cascade[4]), .poly(poly), .new_bit(data_input[2]), .stage_output(cascade[5]));
|
||||
defparam bit_5.crc_width = crc_width;
|
||||
XOR_Shift bit_6(.stage_input(cascade[5]), .poly(poly), .new_bit(data_input[1]), .stage_output(cascade[6]));
|
||||
defparam bit_6.crc_width = crc_width;
|
||||
XOR_Shift bit_7(.stage_input(cascade[6]), .poly(poly), .new_bit(data_input[0]), .stage_output(cascade[7]));
|
||||
defparam bit_7.crc_width = crc_width;
|
||||
|
||||
assign block_output = cascade[7];
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
/* performs the 'new_bit' stuffing, shifting, and XOR operations for a single input bit */
|
||||
module XOR_Shift (stage_input,
|
||||
poly,
|
||||
new_bit,
|
||||
stage_output);
|
||||
|
||||
parameter crc_width = 32;
|
||||
|
||||
input [crc_width-1:0] stage_input;
|
||||
input [crc_width-1:0] poly;
|
||||
input new_bit;
|
||||
output [crc_width-1:0] stage_output;
|
||||
|
||||
assign stage_output[0] = new_bit ^ stage_input[crc_width-1];
|
||||
assign stage_output[crc_width-1:1] = stage_input[crc_width-2:0] ^ ({crc_width-1{stage_output[0]}} & poly[crc_width-1:1]);
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
Legal Notice: (C)2006 Altera Corporation. All rights reserved. Your
|
||||
use of Altera Corporation's design tools, logic functions and other
|
||||
software and tools, and its AMPP partner logic functions, and any
|
||||
output files any of the foregoing (including device programming or
|
||||
simulation files), and any associated documentation or information are
|
||||
expressly subject to the terms and conditions of the Altera Program
|
||||
License Subscription Agreement or other applicable license agreement,
|
||||
including, without limitation, that your use is for the sole purpose
|
||||
of programming logic devices manufactured by Altera and sold by Altera
|
||||
or its authorized distributors. Please refer to the applicable
|
||||
agreement for further details.
|
||||
*/
|
||||
|
||||
/*
|
||||
This thin wrapper re-uses the CRC Avalon component as a Nios II
|
||||
custom instruction. The n port of custom instruction is used as
|
||||
control to the CRC Avalon component. Below are the values of n and
|
||||
the corresponding operations perform by the custom instruction:
|
||||
n = 0, Initialize the custom instruction to the initial remainder value
|
||||
n = 1, Write 8 bits data to custom instruction
|
||||
n = 2, Write 16 bits data to custom instruction
|
||||
n = 3, Write 32 bits data to custom instruction
|
||||
n = 4, Read 32 bits data from the custom instruction
|
||||
n = 5, Read 64 bits data from the custom instruction
|
||||
n = 6, Read 96 bits data from the custom instruction
|
||||
n = 7, Read 128 bits data from the custom instruction
|
||||
*/
|
||||
|
||||
|
||||
|
||||
module CRC_Custom_Instruction(clk,
|
||||
reset,
|
||||
dataa,
|
||||
n,
|
||||
clk_en,
|
||||
start,
|
||||
done,
|
||||
result);
|
||||
/*
|
||||
See the Avalon CRC component for details on the meaning of each
|
||||
parameter listed below.
|
||||
*/
|
||||
parameter crc_width = 32;
|
||||
parameter polynomial_inital = 32'hFFFFFFFF;
|
||||
parameter polynomial = 32'h04C11DB7;
|
||||
parameter reflected_input = 1;
|
||||
parameter reflected_output = 1;
|
||||
parameter xor_output = 32'hFFFFFFFF;
|
||||
|
||||
input clk;
|
||||
input reset;
|
||||
input [31:0] dataa;
|
||||
input [2:0] n;
|
||||
input clk_en;
|
||||
input start;
|
||||
output done;
|
||||
output [31:0] result;
|
||||
|
||||
wire [2:0] address;
|
||||
wire [3:0] byteenable;
|
||||
wire write;
|
||||
wire read;
|
||||
reg done_delay;
|
||||
|
||||
assign write = (n<4);
|
||||
assign read = (n>3);
|
||||
assign byteenable = (n==1)?4'b0001 : (n==2)?4'b0011 : (n==3)?4'b1111 : 4'b0000;
|
||||
assign address = (n==0)?3'b000 : ((n==1)|(n==2)|(n==3))?3'b001 : (n==4)?3'b100 : (n==5)?3'b101 : (n==6)?3'b110 : 3'b111;
|
||||
assign done = (n>3)? done_delay : start;
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset)
|
||||
done_delay <= 0;
|
||||
else
|
||||
done_delay <= start;
|
||||
end
|
||||
|
||||
/*
|
||||
Instantiating the Avalon CRC component and wiring it to be
|
||||
custom instruction compilant
|
||||
*/
|
||||
CRC_Component wrapper_wiring(.clk(clk),
|
||||
.reset(reset),
|
||||
.address(address),
|
||||
.writedata(dataa),
|
||||
.byteenable(byteenable),
|
||||
.write(write & start),
|
||||
.read(read),
|
||||
.chipselect(clk_en),
|
||||
.readdata(result));
|
||||
|
||||
defparam wrapper_wiring.crc_width = crc_width;
|
||||
defparam wrapper_wiring.polynomial_inital = polynomial_inital;
|
||||
defparam wrapper_wiring.polynomial = polynomial;
|
||||
defparam wrapper_wiring.reflected_input = reflected_input;
|
||||
defparam wrapper_wiring.reflected_output = reflected_output;
|
||||
defparam wrapper_wiring.xor_output = xor_output;
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,116 @@
|
|||
# TCL File Generated by Component Editor 15.1
|
||||
# Tue Dec 22 18:46:40 EET 2015
|
||||
# DO NOT MODIFY
|
||||
|
||||
|
||||
#
|
||||
# nios2_hw_crc32 "nios2_hw_crc32" v1.0
|
||||
# 2015.12.22.18:46:40
|
||||
#
|
||||
#
|
||||
|
||||
#
|
||||
# request TCL package from ACDS 15.1
|
||||
#
|
||||
package require -exact qsys 15.1
|
||||
|
||||
|
||||
#
|
||||
# module nios2_hw_crc32
|
||||
#
|
||||
set_module_property DESCRIPTION ""
|
||||
set_module_property NAME nios2_hw_crc32
|
||||
set_module_property VERSION 1.0
|
||||
set_module_property INTERNAL false
|
||||
set_module_property OPAQUE_ADDRESS_MAP true
|
||||
set_module_property GROUP "Custom Instruction Modules"
|
||||
set_module_property AUTHOR ""
|
||||
set_module_property DISPLAY_NAME nios2_hw_crc32
|
||||
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
|
||||
set_module_property EDITABLE true
|
||||
set_module_property REPORT_TO_TALKBACK false
|
||||
set_module_property ALLOW_GREYBOX_GENERATION false
|
||||
set_module_property REPORT_HIERARCHY false
|
||||
|
||||
|
||||
#
|
||||
# file sets
|
||||
#
|
||||
add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" ""
|
||||
set_fileset_property QUARTUS_SYNTH TOP_LEVEL CRC_Custom_Instruction
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
|
||||
add_fileset_file CRC_Component.v VERILOG PATH hdl/CRC_Component.v
|
||||
add_fileset_file CRC_Custom_Instruction.v VERILOG PATH hdl/CRC_Custom_Instruction.v TOP_LEVEL_FILE
|
||||
|
||||
|
||||
#
|
||||
# parameters
|
||||
#
|
||||
add_parameter crc_width INTEGER 32
|
||||
set_parameter_property crc_width DEFAULT_VALUE 32
|
||||
set_parameter_property crc_width DISPLAY_NAME crc_width
|
||||
set_parameter_property crc_width TYPE INTEGER
|
||||
set_parameter_property crc_width UNITS None
|
||||
set_parameter_property crc_width HDL_PARAMETER true
|
||||
add_parameter polynomial_inital STD_LOGIC_VECTOR 4294967295
|
||||
set_parameter_property polynomial_inital DEFAULT_VALUE 4294967295
|
||||
set_parameter_property polynomial_inital DISPLAY_NAME polynomial_inital
|
||||
set_parameter_property polynomial_inital TYPE STD_LOGIC_VECTOR
|
||||
set_parameter_property polynomial_inital UNITS None
|
||||
set_parameter_property polynomial_inital ALLOWED_RANGES 0:17179869183
|
||||
set_parameter_property polynomial_inital HDL_PARAMETER true
|
||||
add_parameter polynomial STD_LOGIC_VECTOR 79764919
|
||||
set_parameter_property polynomial DEFAULT_VALUE 79764919
|
||||
set_parameter_property polynomial DISPLAY_NAME polynomial
|
||||
set_parameter_property polynomial TYPE STD_LOGIC_VECTOR
|
||||
set_parameter_property polynomial UNITS None
|
||||
set_parameter_property polynomial ALLOWED_RANGES 0:17179869183
|
||||
set_parameter_property polynomial HDL_PARAMETER true
|
||||
add_parameter reflected_input INTEGER 1
|
||||
set_parameter_property reflected_input DEFAULT_VALUE 1
|
||||
set_parameter_property reflected_input DISPLAY_NAME reflected_input
|
||||
set_parameter_property reflected_input TYPE INTEGER
|
||||
set_parameter_property reflected_input UNITS None
|
||||
set_parameter_property reflected_input HDL_PARAMETER true
|
||||
add_parameter reflected_output INTEGER 1
|
||||
set_parameter_property reflected_output DEFAULT_VALUE 1
|
||||
set_parameter_property reflected_output DISPLAY_NAME reflected_output
|
||||
set_parameter_property reflected_output TYPE INTEGER
|
||||
set_parameter_property reflected_output UNITS None
|
||||
set_parameter_property reflected_output HDL_PARAMETER true
|
||||
add_parameter xor_output STD_LOGIC_VECTOR 4294967295
|
||||
set_parameter_property xor_output DEFAULT_VALUE 4294967295
|
||||
set_parameter_property xor_output DISPLAY_NAME xor_output
|
||||
set_parameter_property xor_output TYPE STD_LOGIC_VECTOR
|
||||
set_parameter_property xor_output UNITS None
|
||||
set_parameter_property xor_output ALLOWED_RANGES 0:17179869183
|
||||
set_parameter_property xor_output HDL_PARAMETER true
|
||||
|
||||
|
||||
#
|
||||
# display items
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# connection point nios_custom_instruction_slave
|
||||
#
|
||||
add_interface nios_custom_instruction_slave nios_custom_instruction end
|
||||
set_interface_property nios_custom_instruction_slave clockCycle 0
|
||||
set_interface_property nios_custom_instruction_slave operands 1
|
||||
set_interface_property nios_custom_instruction_slave ENABLED true
|
||||
set_interface_property nios_custom_instruction_slave EXPORT_OF ""
|
||||
set_interface_property nios_custom_instruction_slave PORT_NAME_MAP ""
|
||||
set_interface_property nios_custom_instruction_slave CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property nios_custom_instruction_slave SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port nios_custom_instruction_slave clk clk Input 1
|
||||
add_interface_port nios_custom_instruction_slave clk_en clk_en Input 1
|
||||
add_interface_port nios_custom_instruction_slave dataa dataa Input 32
|
||||
add_interface_port nios_custom_instruction_slave done done Output 1
|
||||
add_interface_port nios_custom_instruction_slave n n Input 3
|
||||
add_interface_port nios_custom_instruction_slave reset reset Input 1
|
||||
add_interface_port nios_custom_instruction_slave result result Output 32
|
||||
add_interface_port nios_custom_instruction_slave start start Input 1
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
# (C) 2001-2015 Altera Corporation. All rights reserved.
|
||||
# Your use of Altera Corporation's design tools, logic functions and other
|
||||
# software and tools, and its AMPP partner logic functions, and any output
|
||||
# files any of the foregoing (including device programming or simulation
|
||||
# files), and any associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License Subscription
|
||||
# Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||||
# license agreement, including, without limitation, that your use is for the
|
||||
# sole purpose of programming logic devices manufactured by Altera and sold by
|
||||
# Altera or its authorized distributors. Please refer to the applicable
|
||||
# agreement for further details.
|
||||
|
||||
|
||||
# TCL File Generated by Altera University Program
|
||||
# DO NOT MODIFY
|
||||
|
||||
set aup_version 15.1
|
||||
|
||||
# Create a new driver - this name must be different than the
|
||||
# hardware component name
|
||||
create_driver nios2_hw_crc32_driver
|
||||
|
||||
# Associate it with some hardware
|
||||
set_sw_property hw_class_name nios2_hw_crc32
|
||||
|
||||
# The version of this driver
|
||||
set_sw_property version $aup_version
|
||||
|
||||
# This driver is proclaimed to be compatible with 'component'
|
||||
# as old as version "1.0". The component hardware version is set in the
|
||||
# _hw.tcl file - If the hardware component version number is not equal
|
||||
# or greater than the min_compatable_hw_version number, the driver
|
||||
# source files will not be copied over to the BSP driver directory
|
||||
set_sw_property min_compatible_hw_version 1.0
|
||||
|
||||
# Initialize the driver in alt_sys_init()
|
||||
set_sw_property auto_initialize false
|
||||
|
||||
# Location in generated BSP that sources will be copied into
|
||||
set_sw_property bsp_subdirectory drivers
|
||||
|
||||
#
|
||||
# Source file listings...
|
||||
#
|
||||
|
||||
# C/C++ source files
|
||||
add_sw_property c_source HAL/src/ci_crc.c
|
||||
add_sw_property c_source HAL/src/crc.c
|
||||
|
||||
# Include files
|
||||
add_sw_property include_source HAL/inc/ci_crc.h
|
||||
add_sw_property include_source HAL/inc/crc.h
|
||||
|
||||
# This driver supports HAL type
|
||||
add_sw_property supported_bsp_type HAL
|
||||
|
||||
# End of file
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 1991-2013 Altera Corporation
|
||||
# Your use of Altera Corporation's design tools, logic functions
|
||||
# and other software and tools, and its AMPP partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License
|
||||
# Subscription Agreement, Altera MegaCore Function License
|
||||
# Agreement, or other applicable license agreement, including,
|
||||
# without limitation, that your use is for the sole purpose of
|
||||
# programming logic devices manufactured by Altera and sold by
|
||||
# Altera or its authorized distributors. Please refer to the
|
||||
# applicable agreement for further details.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus II 64-Bit
|
||||
# Version 13.1.0 Build 162 10/23/2013 SJ Web Edition
|
||||
# Date created = 17:27:03 May 17, 2014
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
QUARTUS_VERSION = "13.1"
|
||||
DATE = "17:27:03 May 17, 2014"
|
||||
|
||||
# Revisions
|
||||
|
||||
PROJECT_REVISION = "ossc"
|
|
@ -0,0 +1,235 @@
|
|||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 1991-2013 Altera Corporation
|
||||
# Your use of Altera Corporation's design tools, logic functions
|
||||
# and other software and tools, and its AMPP partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License
|
||||
# Subscription Agreement, Altera MegaCore Function License
|
||||
# Agreement, or other applicable license agreement, including,
|
||||
# without limitation, that your use is for the sole purpose of
|
||||
# programming logic devices manufactured by Altera and sold by
|
||||
# Altera or its authorized distributors. Please refer to the
|
||||
# applicable agreement for further details.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus II 64-Bit
|
||||
# Version 13.1.0 Build 162 10/23/2013 SJ Web Edition
|
||||
# Date created = 17:27:03 May 17, 2014
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
# 1) The default values for assignments are stored in the file:
|
||||
# ossc_assignment_defaults.qdf
|
||||
# If this file doesn't exist, see file:
|
||||
# assignment_defaults.qdf
|
||||
#
|
||||
# 2) Altera recommends that you do not modify this file. This
|
||||
# file is updated automatically by the Quartus II software
|
||||
# and any changes you make may be lost or overwritten.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
set_global_assignment -name FAMILY "Cyclone IV E"
|
||||
set_global_assignment -name DEVICE EP4CE15E22C8
|
||||
set_global_assignment -name TOP_LEVEL_ENTITY ossc
|
||||
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 13.1
|
||||
set_global_assignment -name PROJECT_CREATION_TIME_DATE "17:27:03 MAY 17, 2014"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION 15.1.0
|
||||
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
|
||||
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
|
||||
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
|
||||
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1
|
||||
set_global_assignment -name EDA_SIMULATION_TOOL "<None>"
|
||||
set_global_assignment -name EDA_OUTPUT_DATA_FORMAT NONE -section_id eda_simulation
|
||||
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "NO HEAT SINK WITH STILL AIR"
|
||||
set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
|
||||
set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"
|
||||
|
||||
|
||||
set_location_assignment PIN_25 -to clk27
|
||||
set_location_assignment PIN_99 -to reset_n
|
||||
set_location_assignment PIN_23 -to ir_rx
|
||||
|
||||
#============================================================
|
||||
# TVP7002
|
||||
#============================================================
|
||||
set_location_assignment PIN_52 -to R_in[0]
|
||||
set_location_assignment PIN_53 -to R_in[1]
|
||||
set_location_assignment PIN_54 -to R_in[2]
|
||||
set_location_assignment PIN_55 -to R_in[3]
|
||||
set_location_assignment PIN_58 -to R_in[4]
|
||||
set_location_assignment PIN_59 -to R_in[5]
|
||||
set_location_assignment PIN_60 -to R_in[6]
|
||||
set_location_assignment PIN_61 -to R_in[7]
|
||||
set_location_assignment PIN_88 -to B_in[7]
|
||||
set_location_assignment PIN_87 -to B_in[6]
|
||||
set_location_assignment PIN_86 -to B_in[5]
|
||||
set_location_assignment PIN_85 -to B_in[4]
|
||||
set_location_assignment PIN_83 -to B_in[3]
|
||||
set_location_assignment PIN_80 -to B_in[2]
|
||||
set_location_assignment PIN_77 -to B_in[1]
|
||||
set_location_assignment PIN_89 -to PCLK_in
|
||||
set_location_assignment PIN_76 -to B_in[0]
|
||||
set_location_assignment PIN_90 -to HSYNC_in
|
||||
set_location_assignment PIN_91 -to VSYNC_in
|
||||
set_location_assignment PIN_98 -to FID_in
|
||||
set_location_assignment PIN_72 -to G_in[7]
|
||||
set_location_assignment PIN_71 -to G_in[6]
|
||||
set_location_assignment PIN_69 -to G_in[5]
|
||||
set_location_assignment PIN_68 -to G_in[4]
|
||||
set_location_assignment PIN_67 -to G_in[3]
|
||||
set_location_assignment PIN_66 -to G_in[2]
|
||||
set_location_assignment PIN_65 -to G_in[1]
|
||||
set_location_assignment PIN_64 -to G_in[0]
|
||||
|
||||
#============================================================
|
||||
# HDMITX
|
||||
#============================================================
|
||||
set_location_assignment PIN_113 -to HDMI_TX_PCLK
|
||||
set_location_assignment PIN_111 -to HDMI_TX_BD[3]
|
||||
set_location_assignment PIN_112 -to HDMI_TX_BD[4]
|
||||
set_location_assignment PIN_110 -to HDMI_TX_BD[2]
|
||||
set_location_assignment PIN_106 -to HDMI_TX_BD[1]
|
||||
set_location_assignment PIN_105 -to HDMI_TX_BD[0]
|
||||
set_location_assignment PIN_104 -to HDMI_TX_DE
|
||||
set_location_assignment PIN_103 -to HDMI_TX_HS
|
||||
set_location_assignment PIN_101 -to HDMI_TX_VS
|
||||
set_location_assignment PIN_114 -to HDMI_TX_BD[5]
|
||||
set_location_assignment PIN_115 -to HDMI_TX_BD[6]
|
||||
set_location_assignment PIN_119 -to HDMI_TX_BD[7]
|
||||
set_location_assignment PIN_120 -to HDMI_TX_GD[0]
|
||||
set_location_assignment PIN_121 -to HDMI_TX_GD[1]
|
||||
set_location_assignment PIN_125 -to HDMI_TX_GD[2]
|
||||
set_location_assignment PIN_132 -to HDMI_TX_GD[3]
|
||||
set_location_assignment PIN_133 -to HDMI_TX_GD[4]
|
||||
set_location_assignment PIN_134 -to HDMI_TX_GD[5]
|
||||
set_location_assignment PIN_135 -to HDMI_TX_GD[6]
|
||||
set_location_assignment PIN_136 -to HDMI_TX_GD[7]
|
||||
set_location_assignment PIN_137 -to HDMI_TX_RD[0]
|
||||
set_location_assignment PIN_141 -to HDMI_TX_RD[1]
|
||||
set_location_assignment PIN_142 -to HDMI_TX_RD[2]
|
||||
set_location_assignment PIN_143 -to HDMI_TX_RD[3]
|
||||
set_location_assignment PIN_144 -to HDMI_TX_RD[4]
|
||||
set_location_assignment PIN_7 -to HDMI_TX_RD[5]
|
||||
set_location_assignment PIN_10 -to HDMI_TX_RD[6]
|
||||
set_location_assignment PIN_11 -to HDMI_TX_RD[7]
|
||||
set_location_assignment PIN_100 -to HDMI_TX_INT_N
|
||||
set_location_assignment PIN_127 -to HDMI_TX_MODE
|
||||
|
||||
#============================================================
|
||||
# SD card
|
||||
#============================================================
|
||||
set_location_assignment PIN_32 -to SD_CLK
|
||||
set_location_assignment PIN_31 -to SD_CMD
|
||||
set_location_assignment PIN_33 -to SD_DAT[0]
|
||||
set_location_assignment PIN_39 -to SD_DAT[1]
|
||||
set_location_assignment PIN_28 -to SD_DAT[2]
|
||||
set_location_assignment PIN_30 -to SD_DAT[3]
|
||||
|
||||
#============================================================
|
||||
# Leds
|
||||
#============================================================
|
||||
set_location_assignment PIN_44 -to LED_G
|
||||
set_location_assignment PIN_46 -to LED_R
|
||||
|
||||
#============================================================
|
||||
# I2C
|
||||
#============================================================
|
||||
set_location_assignment PIN_49 -to sda
|
||||
set_location_assignment PIN_50 -to scl
|
||||
|
||||
#============================================================
|
||||
# Char LCD
|
||||
#============================================================
|
||||
set_location_assignment PIN_42 -to LCD_RS
|
||||
set_location_assignment PIN_43 -to LCD_CS_N
|
||||
set_location_assignment PIN_51 -to LCD_BL
|
||||
|
||||
#============================================================
|
||||
# Buttons
|
||||
#============================================================
|
||||
set_location_assignment PIN_129 -to btn[1]
|
||||
set_location_assignment PIN_128 -to btn[0]
|
||||
|
||||
|
||||
set_instance_assignment -name PLL_COMPENSATE ON -to G_in
|
||||
set_instance_assignment -name PLL_COMPENSATE ON -to FID_in
|
||||
set_instance_assignment -name PLL_COMPENSATE ON -to HSYNC_in
|
||||
set_instance_assignment -name PLL_COMPENSATE ON -to R_in
|
||||
set_instance_assignment -name PLL_COMPENSATE ON -to VSYNC_in
|
||||
set_instance_assignment -name PLL_COMPENSATE ON -to B_in
|
||||
|
||||
|
||||
set_global_assignment -name USE_CONFIGURATION_DEVICE ON
|
||||
set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF
|
||||
set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall
|
||||
|
||||
|
||||
set_global_assignment -name SEARCH_PATH rtl
|
||||
set_global_assignment -name CYCLONEIII_CONFIGURATION_DEVICE EPCS16
|
||||
|
||||
set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005
|
||||
set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF
|
||||
|
||||
set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON
|
||||
set_global_assignment -name SMART_RECOMPILE OFF
|
||||
|
||||
set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT NORMAL
|
||||
|
||||
set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC OFF
|
||||
set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION OFF
|
||||
|
||||
set_global_assignment -name OPTIMIZATION_MODE BALANCED
|
||||
set_global_assignment -name ALLOW_REGISTER_RETIMING OFF
|
||||
|
||||
set_global_assignment -name ENABLE_OCT_DONE OFF
|
||||
set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||||
set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||||
set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||||
set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF
|
||||
set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF
|
||||
|
||||
set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||||
set_global_assignment -name GENERATE_RBF_FILE ON
|
||||
|
||||
set_global_assignment -name DEVICE_FILTER_PACKAGE "ANY QFP"
|
||||
set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144
|
||||
set_global_assignment -name POWER_DEFAULT_INPUT_IO_TOGGLE_RATE 50%
|
||||
|
||||
|
||||
|
||||
#set_location_assignment PLL_4 -to "scanconverter:scanconverter_inst|pll_3x:pll_linetriple|altpll:altpll_component|pll_3x_altpll:auto_generated|pll1"
|
||||
#set_location_assignment PLL_3 -to "scanconverter:scanconverter_inst|pll_3x_lowfreq:pll_linetriple_lowfreq|altpll:altpll_component|pll_3x_lowfreq_altpll:auto_generated|pll1"
|
||||
#set_location_assignment PLL_1 -to "scanconverter:scanconverter_inst|pll_2x:pll_linedouble|altpll:altpll_component|pll_2x_altpll:auto_generated|pll1"
|
||||
|
||||
|
||||
set_global_assignment -name VERILOG_FILE rtl/videogen.v
|
||||
set_global_assignment -name QIP_FILE software/sys_controller/mem_init/meminit.qip
|
||||
set_global_assignment -name VERILOG_FILE rtl/ir_rcv.v
|
||||
set_global_assignment -name SDC_FILE ossc.sdc
|
||||
set_global_assignment -name QSYS_FILE sys.qsys
|
||||
set_global_assignment -name VERILOG_FILE rtl/ossc.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/scanconverter.v
|
||||
set_global_assignment -name QIP_FILE rtl/linebuf.qip
|
||||
set_global_assignment -name QIP_FILE rtl/pll_2x.qip
|
||||
set_global_assignment -name QIP_FILE rtl/pll_3x.qip
|
||||
set_global_assignment -name QIP_FILE rtl/pll_3x_lowfreq.qip
|
||||
set_global_assignment -name CDF_FILE output_files/Chain1.cdf
|
||||
|
||||
|
||||
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
|
@ -0,0 +1,102 @@
|
|||
### CPU clock constraints ###
|
||||
|
||||
create_clock -period 27MHz -name clk27 [get_ports clk27]
|
||||
|
||||
set_input_delay -clock clk27 0 [get_ports {sda scl ir_rx HDMI_TX_INT_N SD_CMD SD_DAT* btn* *ALTERA_DATA0}]
|
||||
set_false_path -to {sys:sys_inst|sys_pio_1:pio_1|readdata*}
|
||||
|
||||
### Scanconverter clock constraints ###
|
||||
|
||||
create_clock -period 108MHz -name pclk_hdtv [get_ports PCLK_in]
|
||||
create_clock -period 27MHz -name pclk_ldtv_hs_M0 [get_ports PCLK_in] -add
|
||||
create_clock -period 20MHz -name pclk_ldtv_hs_M1 [get_ports PCLK_in] -add
|
||||
create_clock -period 13.5MHz -name pclk_sdtv [get_ports PCLK_in] -add
|
||||
create_clock -period 6.7MHz -name pclk_ldtv_M2 [get_ports PCLK_in] -add
|
||||
create_clock -period 5.4MHz -name pclk_ldtv_M3 [get_ports PCLK_in] -add
|
||||
|
||||
#derive_pll_clocks
|
||||
create_generated_clock -master_clock pclk_sdtv -source {scanconverter_inst|pll_linedouble|altpll_component|auto_generated|pll1|inclk[0]} -multiply_by 2 -duty_cycle 50.00 -name pclk_2x {scanconverter_inst|pll_linedouble|altpll_component|auto_generated|pll1|clk[0]}
|
||||
create_generated_clock -master_clock pclk_ldtv_hs_M0 -source {scanconverter_inst|pll_linetriple|altpll_component|auto_generated|pll1|inclk[0]} -multiply_by 3 -duty_cycle 50.00 -name pclk_3x_M0 {scanconverter_inst|pll_linetriple|altpll_component|auto_generated|pll1|clk[0]}
|
||||
create_generated_clock -master_clock pclk_ldtv_hs_M1 -source {scanconverter_inst|pll_linetriple|altpll_component|auto_generated|pll1|inclk[0]} -multiply_by 3 -duty_cycle 50.00 -name pclk_3x_M1 {scanconverter_inst|pll_linetriple|altpll_component|auto_generated|pll1|clk[0]} -add
|
||||
create_generated_clock -master_clock pclk_ldtv_hs_M1 -source {scanconverter_inst|pll_linetriple|altpll_component|auto_generated|pll1|inclk[0]} -multiply_by 4 -duty_cycle 50.00 -name pclk_4x_M1 {scanconverter_inst|pll_linetriple|altpll_component|auto_generated|pll1|clk[1]}
|
||||
create_generated_clock -master_clock pclk_ldtv_M2 -source {scanconverter_inst|pll_linetriple_lowfreq|altpll_component|auto_generated|pll1|inclk[0]} -multiply_by 3 -duty_cycle 50.00 -name pclk_3x_h1x_M2 {scanconverter_inst|pll_linetriple_lowfreq|altpll_component|auto_generated|pll1|clk[0]}
|
||||
create_generated_clock -master_clock pclk_ldtv_M2 -source {scanconverter_inst|pll_linetriple_lowfreq|altpll_component|auto_generated|pll1|inclk[0]} -multiply_by 12 -duty_cycle 50.00 -name pclk_3x_h4x_M2 {scanconverter_inst|pll_linetriple_lowfreq|altpll_component|auto_generated|pll1|clk[1]}
|
||||
create_generated_clock -master_clock pclk_ldtv_M3 -source {scanconverter_inst|pll_linetriple_lowfreq|altpll_component|auto_generated|pll1|inclk[0]} -multiply_by 3 -duty_cycle 50.00 -name pclk_3x_h1x_M3 {scanconverter_inst|pll_linetriple_lowfreq|altpll_component|auto_generated|pll1|clk[0]} -add
|
||||
create_generated_clock -master_clock pclk_ldtv_M3 -source {scanconverter_inst|pll_linetriple_lowfreq|altpll_component|auto_generated|pll1|inclk[0]} -multiply_by 15 -duty_cycle 50.00 -name pclk_3x_h5x_M3 {scanconverter_inst|pll_linetriple_lowfreq|altpll_component|auto_generated|pll1|clk[2]}
|
||||
|
||||
derive_clock_uncertainty
|
||||
|
||||
# input delay constraints
|
||||
set critinputs [get_ports {R_in* G_in* B_in* FID_in HSYNC_in VSYNC_in}]
|
||||
set_input_delay -clock pclk_sdtv -min 0 $critinputs
|
||||
set_input_delay -clock pclk_sdtv -max 1.5 $critinputs
|
||||
set_input_delay -clock pclk_hdtv -min 0 $critinputs -add_delay
|
||||
set_input_delay -clock pclk_hdtv -max 1.5 $critinputs -add_delay
|
||||
set_input_delay -clock pclk_ldtv_M2 -min 0 $critinputs -add_delay
|
||||
set_input_delay -clock pclk_ldtv_M2 -max 1.5 $critinputs -add_delay
|
||||
set_input_delay -clock pclk_ldtv_M3 -min 0 $critinputs -add_delay
|
||||
set_input_delay -clock pclk_ldtv_M3 -max 1.5 $critinputs -add_delay
|
||||
set_input_delay -clock pclk_ldtv_hs_M0 -min 0 $critinputs -add_delay
|
||||
set_input_delay -clock pclk_ldtv_hs_M0 -max 1.5 $critinputs -add_delay
|
||||
set_input_delay -clock pclk_ldtv_hs_M1 -min 0 $critinputs -add_delay
|
||||
set_input_delay -clock pclk_ldtv_hs_M1 -max 1.5 $critinputs -add_delay
|
||||
|
||||
# output delay constraints (TODO: add vsync)
|
||||
set critoutputs_hdmi {HDMI_TX_RD* HDMI_TX_GD* HDMI_TX_BD* HDMI_TX_DE HDMI_TX_HS}
|
||||
set_output_delay -reference_pin HDMI_TX_PCLK -clock pclk_hdtv 0 $critoutputs_hdmi
|
||||
set_output_delay -reference_pin HDMI_TX_PCLK -clock pclk_2x 0 $critoutputs_hdmi -add_delay
|
||||
set_output_delay -reference_pin HDMI_TX_PCLK -clock pclk_3x_M0 0 $critoutputs_hdmi -add_delay
|
||||
set_output_delay -reference_pin HDMI_TX_PCLK -clock pclk_4x_M1 0 $critoutputs_hdmi -add_delay
|
||||
set_output_delay -reference_pin HDMI_TX_PCLK -clock pclk_3x_h4x_M2 0 $critoutputs_hdmi -add_delay
|
||||
set_output_delay -reference_pin HDMI_TX_PCLK -clock pclk_3x_h5x_M3 0 $critoutputs_hdmi -add_delay
|
||||
set_false_path -to [remove_from_collection [all_outputs] $critoutputs_hdmi]
|
||||
|
||||
|
||||
### CPU/scanconverter clock relations ###
|
||||
|
||||
# Set pixel clocks as exclusive clocks
|
||||
set_clock_groups -exclusive \
|
||||
-group {pclk_hdtv} \
|
||||
-group {pclk_sdtv pclk_2x} \
|
||||
-group {pclk_ldtv_hs_M0 pclk_3x_M0} \
|
||||
-group {pclk_ldtv_hs_M1 pclk_3x_M1 pclk_4x_M1} \
|
||||
-group {pclk_ldtv_M2 pclk_3x_h1x_M2 pclk_3x_h4x_M2} \
|
||||
-group {pclk_ldtv_M3 pclk_3x_h1x_M3 pclk_3x_h5x_M3}
|
||||
|
||||
# Treat CPU clock asynchronous to pixel clocks
|
||||
set_clock_groups -asynchronous -group {clk27}
|
||||
|
||||
# Filter out impossible output mux combinations
|
||||
set clkmuxregs [get_cells {scanconverter:scanconverter_inst|R_out[*] scanconverter:scanconverter_inst|G_out[*] scanconverter:scanconverter_inst|B_out[*] scanconverter:scanconverter_inst|HSYNC_out scanconverter:scanconverter_inst|DATA_enable scanconverter:scanconverter_inst|*_pp1*}]
|
||||
set clkmuxnodes [get_pins {scanconverter_inst|linebuf_*|altsyncram_*|auto_generated|ram_*|portbaddr*}]
|
||||
set_false_path -from [get_clocks {pclk_ldtv* pclk_sdtv}] -through $clkmuxregs
|
||||
set_false_path -from pclk_3x_M1 -through [remove_from_collection $clkmuxregs {scanconverter:scanconverter_inst|DATA_enable_pp1* scanconverter:scanconverter_inst|HSYNC_pp1*}] -to pclk_4x_M1
|
||||
set_false_path -from pclk_3x_M1 -through $clkmuxnodes -to pclk_4x_M1
|
||||
|
||||
# Ignore paths from registers which are updated only at the end of vsync
|
||||
set_false_path -from [get_cells {scanconverter_inst|H_* scanconverter_inst|V_* scanconverter:scanconverter_inst|lines_*}]
|
||||
|
||||
# Ignore paths from registers which are updated only at the end of hsync
|
||||
set_false_path -from [get_cells {scanconverter:scanconverter_inst|vcnt_* scanconverter:scanconverter_inst|line_idx}]
|
||||
|
||||
# Ignore following clock transfers
|
||||
set_false_path -from [get_clocks pclk_2x] -to [get_clocks pclk_sdtv]
|
||||
set_false_path -from [get_clocks pclk_3x_M*] -to [get_clocks {pclk_ldtv_hs_M*}]
|
||||
set_false_path -from [get_clocks pclk_4x_M1] -to [get_clocks {pclk_ldtv_hs_M1 pclk_3x_M1}]
|
||||
set_false_path -from [get_clocks pclk_3x_h4x_M2] -to [get_clocks {pclk_ldtv_M2 pclk_3x_h1x_M2}]
|
||||
set_false_path -from [get_clocks pclk_3x_h5x_M3] -to [get_clocks {pclk_ldtv_M3 pclk_3x_h1x_M3}]
|
||||
set_false_path -from [get_clocks pclk_3x_h1x_M*] -to [get_clocks {pclk_ldtv_M*}]
|
||||
|
||||
|
||||
### JTAG Signal Constraints ###
|
||||
|
||||
#constrain the TCK port
|
||||
#create_clock -name tck -period "10MHz" [get_ports altera_reserved_tck]
|
||||
#cut all paths to and from tck
|
||||
set_clock_groups -exclusive -group [get_clocks altera_reserved_tck]
|
||||
#constrain the TDI port
|
||||
set_input_delay -clock altera_reserved_tck 20 [get_ports altera_reserved_tdi]
|
||||
#constrain the TMS port
|
||||
set_input_delay -clock altera_reserved_tck 20 [get_ports altera_reserved_tms]
|
||||
#constrain the TDO port
|
||||
#set_output_delay -clock altera_reserved_tck 20 [get_ports altera_reserved_tdo]
|
|
@ -0,0 +1,168 @@
|
|||
//
|
||||
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
`define STATE_IDLE 2'b00
|
||||
`define STATE_LEADVERIFY 2'b01
|
||||
`define STATE_DATARCV 2'b10
|
||||
|
||||
module ir_rcv (
|
||||
input clk27,
|
||||
input reset_n,
|
||||
input ir_rx,
|
||||
output reg [15:0] ir_code,
|
||||
output reg ir_code_ack
|
||||
);
|
||||
|
||||
// 20ns clock period
|
||||
|
||||
parameter LEADCODE_LO_THOLD = 124200; //4.60ms
|
||||
parameter LEADCODE_HI_THOLD = 113400; //4.20ms
|
||||
parameter LEADCODE_HI_RPT_THOLD = 56700; //2.1ms
|
||||
parameter RPT_RELEASE_THOLD = 3240000; //120ms
|
||||
parameter BIT_ONE_THOLD = 22410; //0.83ms
|
||||
parameter BIT_DETECT_THOLD = 10800; //0.4ms
|
||||
parameter IDLE_THOLD = 141557; //5.24ms
|
||||
|
||||
reg [1:0] state; // 3 states
|
||||
reg [31:0] databuf; // temp. buffer
|
||||
reg [5:0] bits_detected; // max. 63, effectively between 0 and 33
|
||||
reg [17:0] act_cnt; // max. 5.2ms
|
||||
reg [17:0] leadvrf_cnt; // max. 5.2ms
|
||||
reg [17:0] datarcv_cnt; // max. 5.2ms
|
||||
reg [22:0] rpt_cnt; // max. 166ms
|
||||
|
||||
// activity when signal is low
|
||||
always @(posedge clk27 or negedge reset_n)
|
||||
begin
|
||||
if (!reset_n)
|
||||
act_cnt <= 0;
|
||||
else
|
||||
begin
|
||||
if ((state == `STATE_IDLE) & (~ir_rx))
|
||||
act_cnt <= act_cnt + 1'b1;
|
||||
else
|
||||
act_cnt <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
// lead code verify counter
|
||||
always @(posedge clk27 or negedge reset_n)
|
||||
begin
|
||||
if (!reset_n)
|
||||
leadvrf_cnt <= 0;
|
||||
else
|
||||
begin
|
||||
if ((state == `STATE_LEADVERIFY) & ir_rx)
|
||||
leadvrf_cnt <= leadvrf_cnt + 1'b1;
|
||||
else
|
||||
leadvrf_cnt <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// '0' and '1' are differentiated by high phase duration preceded by constant length low phase
|
||||
always @(posedge clk27 or negedge reset_n)
|
||||
begin
|
||||
if (!reset_n)
|
||||
begin
|
||||
datarcv_cnt <= 0;
|
||||
bits_detected <= 0;
|
||||
databuf <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (state == `STATE_DATARCV)
|
||||
begin
|
||||
if (ir_rx)
|
||||
datarcv_cnt <= datarcv_cnt + 1'b1;
|
||||
else
|
||||
datarcv_cnt <= 0;
|
||||
|
||||
if (datarcv_cnt == BIT_DETECT_THOLD)
|
||||
bits_detected <= bits_detected + 1'b1;
|
||||
|
||||
if (datarcv_cnt == BIT_ONE_THOLD)
|
||||
databuf[32-bits_detected] <= 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
datarcv_cnt <= 0;
|
||||
bits_detected <= 0;
|
||||
databuf <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// read and validate data after 32 bits detected (last bit may change to '1' at any time)
|
||||
always @(posedge clk27 or negedge reset_n)
|
||||
begin
|
||||
if (!reset_n)
|
||||
begin
|
||||
ir_code_ack <= 1'b0;
|
||||
ir_code <= 16'h00000000;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if ((bits_detected == 32) & (databuf[31:24] == ~databuf[23:16]) & (databuf[15:8] == ~databuf[7:0]))
|
||||
begin
|
||||
ir_code <= {databuf[31:24], databuf[15:8]};
|
||||
ir_code_ack <= 1'b1;
|
||||
end
|
||||
else if (rpt_cnt >= RPT_RELEASE_THOLD)
|
||||
begin
|
||||
ir_code <= 16'h00000000;
|
||||
ir_code_ack <= 1'b0;
|
||||
end
|
||||
else
|
||||
ir_code_ack <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk27 or negedge reset_n)
|
||||
begin
|
||||
if (!reset_n)
|
||||
begin
|
||||
state <= `STATE_IDLE;
|
||||
rpt_cnt <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
rpt_cnt <= rpt_cnt + 1'b1;
|
||||
|
||||
case (state)
|
||||
`STATE_IDLE:
|
||||
if (act_cnt >= LEADCODE_LO_THOLD)
|
||||
state <= `STATE_LEADVERIFY;
|
||||
`STATE_LEADVERIFY:
|
||||
begin
|
||||
if (leadvrf_cnt == LEADCODE_HI_RPT_THOLD)
|
||||
rpt_cnt <= 0;
|
||||
if (leadvrf_cnt >= LEADCODE_HI_THOLD)
|
||||
state <= `STATE_DATARCV;
|
||||
end
|
||||
`STATE_DATARCV:
|
||||
if ((datarcv_cnt >= IDLE_THOLD) | (bits_detected >= 33))
|
||||
state <= `STATE_IDLE;
|
||||
default:
|
||||
state <= `STATE_IDLE;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,6 @@
|
|||
set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT"
|
||||
set_global_assignment -name IP_TOOL_VERSION "15.1"
|
||||
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "linebuf.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "linebuf_inst.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "linebuf_bb.v"]
|
|
@ -0,0 +1,216 @@
|
|||
// megafunction wizard: %RAM: 2-PORT%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: altsyncram
|
||||
|
||||
// ============================================================
|
||||
// File Name: linebuf.v
|
||||
// Megafunction Name(s):
|
||||
// altsyncram
|
||||
//
|
||||
// Simulation Library Files(s):
|
||||
// altera_mf
|
||||
// ============================================================
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 15.1.0 Build 185 10/21/2015 SJ Lite Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
|
||||
//Your use of Altera Corporation's design tools, logic functions
|
||||
//and other software and tools, and its AMPP partner logic
|
||||
//functions, and any output files from any of the foregoing
|
||||
//(including device programming or simulation files), and any
|
||||
//associated documentation or information are expressly subject
|
||||
//to the terms and conditions of the Altera Program License
|
||||
//Subscription Agreement, the Altera Quartus Prime License Agreement,
|
||||
//the Altera MegaCore Function License Agreement, or other
|
||||
//applicable license agreement, including, without limitation,
|
||||
//that your use is for the sole purpose of programming logic
|
||||
//devices manufactured by Altera and sold by Altera or its
|
||||
//authorized distributors. Please refer to the applicable
|
||||
//agreement for further details.
|
||||
|
||||
|
||||
// synopsys translate_off
|
||||
`timescale 1 ps / 1 ps
|
||||
// synopsys translate_on
|
||||
module linebuf (
|
||||
data,
|
||||
rdaddress,
|
||||
rdclock,
|
||||
wraddress,
|
||||
wrclock,
|
||||
wren,
|
||||
q);
|
||||
|
||||
input [23:0] data;
|
||||
input [11:0] rdaddress;
|
||||
input rdclock;
|
||||
input [11:0] wraddress;
|
||||
input wrclock;
|
||||
input wren;
|
||||
output [23:0] q;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_off
|
||||
`endif
|
||||
tri1 wrclock;
|
||||
tri0 wren;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_on
|
||||
`endif
|
||||
|
||||
wire [23:0] sub_wire0;
|
||||
wire [23:0] q = sub_wire0[23:0];
|
||||
|
||||
altsyncram altsyncram_component (
|
||||
.address_a (wraddress),
|
||||
.address_b (rdaddress),
|
||||
.clock0 (wrclock),
|
||||
.clock1 (rdclock),
|
||||
.data_a (data),
|
||||
.wren_a (wren),
|
||||
.q_b (sub_wire0),
|
||||
.aclr0 (1'b0),
|
||||
.aclr1 (1'b0),
|
||||
.addressstall_a (1'b0),
|
||||
.addressstall_b (1'b0),
|
||||
.byteena_a (1'b1),
|
||||
.byteena_b (1'b1),
|
||||
.clocken0 (1'b1),
|
||||
.clocken1 (1'b1),
|
||||
.clocken2 (1'b1),
|
||||
.clocken3 (1'b1),
|
||||
.data_b ({24{1'b1}}),
|
||||
.eccstatus (),
|
||||
.q_a (),
|
||||
.rden_a (1'b1),
|
||||
.rden_b (1'b1),
|
||||
.wren_b (1'b0));
|
||||
defparam
|
||||
altsyncram_component.address_aclr_b = "NONE",
|
||||
altsyncram_component.address_reg_b = "CLOCK1",
|
||||
altsyncram_component.clock_enable_input_a = "BYPASS",
|
||||
altsyncram_component.clock_enable_input_b = "BYPASS",
|
||||
altsyncram_component.clock_enable_output_b = "BYPASS",
|
||||
altsyncram_component.intended_device_family = "Cyclone IV E",
|
||||
altsyncram_component.lpm_type = "altsyncram",
|
||||
altsyncram_component.numwords_a = 4096,
|
||||
altsyncram_component.numwords_b = 4096,
|
||||
altsyncram_component.operation_mode = "DUAL_PORT",
|
||||
altsyncram_component.outdata_aclr_b = "NONE",
|
||||
altsyncram_component.outdata_reg_b = "CLOCK1",
|
||||
altsyncram_component.power_up_uninitialized = "FALSE",
|
||||
altsyncram_component.widthad_a = 12,
|
||||
altsyncram_component.widthad_b = 12,
|
||||
altsyncram_component.width_a = 24,
|
||||
altsyncram_component.width_b = 24,
|
||||
altsyncram_component.width_byteena_a = 1;
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================
|
||||
// CNX file retrieval info
|
||||
// ============================================================
|
||||
// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
|
||||
// Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRdata NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRq NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRrren NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRwren NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Clock NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: Clock_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Clock_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B"
|
||||
// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
|
||||
// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
|
||||
// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: MEMSIZE NUMERIC "98304"
|
||||
// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: MIFfilename STRING ""
|
||||
// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2"
|
||||
// Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
|
||||
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
|
||||
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3"
|
||||
// Retrieval info: PRIVATE: REGdata NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: REGq NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: REGrdaddress NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: REGrren NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: REGwren NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: VarWidth NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "24"
|
||||
// Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "24"
|
||||
// Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "24"
|
||||
// Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "24"
|
||||
// Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: enable NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: rden NUMERIC "0"
|
||||
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
// Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE"
|
||||
// Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK1"
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
|
||||
// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
|
||||
// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "4096"
|
||||
// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "4096"
|
||||
// Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT"
|
||||
// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
|
||||
// Retrieval info: CONSTANT: OUTDATA_REG_B STRING "CLOCK1"
|
||||
// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
|
||||
// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "12"
|
||||
// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "12"
|
||||
// Retrieval info: CONSTANT: WIDTH_A NUMERIC "24"
|
||||
// Retrieval info: CONSTANT: WIDTH_B NUMERIC "24"
|
||||
// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
|
||||
// Retrieval info: USED_PORT: data 0 0 24 0 INPUT NODEFVAL "data[23..0]"
|
||||
// Retrieval info: USED_PORT: q 0 0 24 0 OUTPUT NODEFVAL "q[23..0]"
|
||||
// Retrieval info: USED_PORT: rdaddress 0 0 12 0 INPUT NODEFVAL "rdaddress[11..0]"
|
||||
// Retrieval info: USED_PORT: rdclock 0 0 0 0 INPUT NODEFVAL "rdclock"
|
||||
// Retrieval info: USED_PORT: wraddress 0 0 12 0 INPUT NODEFVAL "wraddress[11..0]"
|
||||
// Retrieval info: USED_PORT: wrclock 0 0 0 0 INPUT VCC "wrclock"
|
||||
// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren"
|
||||
// Retrieval info: CONNECT: @address_a 0 0 12 0 wraddress 0 0 12 0
|
||||
// Retrieval info: CONNECT: @address_b 0 0 12 0 rdaddress 0 0 12 0
|
||||
// Retrieval info: CONNECT: @clock0 0 0 0 0 wrclock 0 0 0 0
|
||||
// Retrieval info: CONNECT: @clock1 0 0 0 0 rdclock 0 0 0 0
|
||||
// Retrieval info: CONNECT: @data_a 0 0 24 0 data 0 0 24 0
|
||||
// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
|
||||
// Retrieval info: CONNECT: q 0 0 24 0 @q_b 0 0 24 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL linebuf.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL linebuf.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL linebuf.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL linebuf.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL linebuf_inst.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL linebuf_bb.v TRUE
|
||||
// Retrieval info: LIB_FILE: altera_mf
|
|
@ -0,0 +1,197 @@
|
|||
//
|
||||
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
//`define DEBUG
|
||||
`define VIDEOGEN
|
||||
|
||||
module ossc (
|
||||
input clk27,
|
||||
input ir_rx,
|
||||
inout scl,
|
||||
inout sda,
|
||||
input [1:0] btn,
|
||||
input [7:0] R_in,
|
||||
input [7:0] G_in,
|
||||
input [7:0] B_in,
|
||||
input FID_in,
|
||||
input VSYNC_in,
|
||||
input HSYNC_in,
|
||||
input PCLK_in,
|
||||
output [7:0] HDMI_TX_RD,
|
||||
output [7:0] HDMI_TX_GD,
|
||||
output [7:0] HDMI_TX_BD,
|
||||
output HDMI_TX_DE,
|
||||
output HDMI_TX_HS,
|
||||
output HDMI_TX_VS,
|
||||
output HDMI_TX_PCLK,
|
||||
input HDMI_TX_INT_N,
|
||||
input HDMI_TX_MODE,
|
||||
output reset_n,
|
||||
output LED_G,
|
||||
output LED_R,
|
||||
output LCD_RS,
|
||||
output LCD_CS_N,
|
||||
output LCD_BL,
|
||||
output SD_CLK,
|
||||
inout SD_CMD,
|
||||
inout [3:0] SD_DAT
|
||||
);
|
||||
|
||||
wire cpu_reset_n;
|
||||
wire [7:0] sys_ctrl;
|
||||
wire h_unstable;
|
||||
wire [2:0] pclk_lock;
|
||||
wire [2:0] pll_lock_lost;
|
||||
wire [31:0] h_info;
|
||||
wire [31:0] v_info;
|
||||
wire [10:0] lines_out;
|
||||
wire [1:0] fpga_vsyncgen;
|
||||
|
||||
wire [15:0] ir_code;
|
||||
|
||||
wire [7:0] R_out, G_out, B_out;
|
||||
wire HSYNC_out;
|
||||
wire VSYNC_out;
|
||||
wire PCLK_out;
|
||||
wire DATA_enable;
|
||||
|
||||
wire [7:0] R_out_videogen, G_out_videogen, B_out_videogen;
|
||||
wire HSYNC_out_videogen;
|
||||
wire VSYNC_out_videogen;
|
||||
wire PCLK_out_videogen;
|
||||
wire DATA_enable_videogen;
|
||||
|
||||
wire [7:0] lcd_ctrl;
|
||||
|
||||
reg [3:0] reset_n_ctr;
|
||||
|
||||
`ifdef DEBUG
|
||||
assign LED_G = {clk27, PCLK_in};
|
||||
assign LED_R = {HSYNC_in, VSYNC_in};
|
||||
`else
|
||||
//assign LED_G = {(pclk_lock != 3'b000), (ir_code != 0)};
|
||||
//assign LED_R = {(pll_lock_lost != 3'b000), h_unstable};
|
||||
assign LED_G = (ir_code == 0);
|
||||
assign LED_R = (pll_lock_lost != 3'b000)|h_unstable;
|
||||
`endif
|
||||
|
||||
assign LCD_CS_N = lcd_ctrl[0];
|
||||
assign LCD_RS = lcd_ctrl[1];
|
||||
assign LCD_BL = sys_ctrl[1]; //reset_n in v1.2 PCB
|
||||
|
||||
assign reset_n = sys_ctrl[0]; //HDMI_TX_RST_N in v1.2 PCB
|
||||
|
||||
`ifdef VIDEOGEN
|
||||
wire videogen_sel;
|
||||
assign videogen_sel = ~sys_ctrl[2];
|
||||
assign HDMI_TX_RD = videogen_sel ? R_out_videogen : R_out;
|
||||
assign HDMI_TX_GD = videogen_sel ? G_out_videogen : G_out;
|
||||
assign HDMI_TX_BD = videogen_sel ? B_out_videogen : B_out;
|
||||
assign HDMI_TX_HS = videogen_sel ? HSYNC_out_videogen : HSYNC_out;
|
||||
assign HDMI_TX_VS = videogen_sel ? VSYNC_out_videogen : VSYNC_out;
|
||||
assign HDMI_TX_PCLK = videogen_sel ? PCLK_out_videogen : PCLK_out;
|
||||
assign HDMI_TX_DE = videogen_sel ? DATA_enable_videogen : DATA_enable;
|
||||
`else
|
||||
assign HDMI_TX_RD = R_out;
|
||||
assign HDMI_TX_GD = G_out;
|
||||
assign HDMI_TX_BD = B_out;
|
||||
assign HDMI_TX_HS = HSYNC_out;
|
||||
assign HDMI_TX_VS = VSYNC_out;
|
||||
assign HDMI_TX_PCLK = PCLK_out;
|
||||
assign HDMI_TX_DE = DATA_enable;
|
||||
`endif
|
||||
|
||||
always @(posedge clk27)
|
||||
begin
|
||||
if (reset_n_ctr == 4'b1000)
|
||||
reset_n_reg <= 1'b1;
|
||||
else
|
||||
reset_n_ctr <= reset_n_ctr + 1'b1;
|
||||
end
|
||||
|
||||
assign cpu_reset_n = reset_n_reg;
|
||||
|
||||
sys sys_inst(
|
||||
.clk_clk (clk27),
|
||||
.reset_reset_n (cpu_reset_n),
|
||||
.pio_0_sys_ctrl_out_export (sys_ctrl),
|
||||
.pio_1_controls_in_export ({13'b00000000000000, HDMI_TX_MODE, btn, ir_code}),
|
||||
.pio_2_horizontal_info_out_export (h_info),
|
||||
.pio_3_vertical_info_out_export (v_info),
|
||||
`ifdef DEBUG
|
||||
.pio_4_linecount_in_export ({8'h00, R_in, G_in, B_in}),
|
||||
`else
|
||||
.pio_4_linecount_in_export ({14'h0000, fpga_vsyncgen, 5'h00, lines_out}),
|
||||
`endif
|
||||
.pio_5_lcd_ctrl_out_export (lcd_ctrl),
|
||||
.i2c_opencores_0_export_scl_pad_io (scl),
|
||||
.i2c_opencores_0_export_sda_pad_io (sda),
|
||||
.sdcard_0_b_SD_cmd (SD_CMD),
|
||||
.sdcard_0_b_SD_dat (SD_DAT[0]),
|
||||
.sdcard_0_b_SD_dat3 (SD_DAT[3]),
|
||||
.sdcard_0_o_SD_clock (SD_CLK)
|
||||
);
|
||||
|
||||
scanconverter scanconverter_inst (
|
||||
.HSYNC_in (HSYNC_in),
|
||||
.VSYNC_in (VSYNC_in),
|
||||
.PCLK_in (PCLK_in),
|
||||
.FID_in (FID_in),
|
||||
.R_in (R_in),
|
||||
.G_in (G_in),
|
||||
.B_in (B_in),
|
||||
.h_info (h_info),
|
||||
.v_info (v_info),
|
||||
.R_out (R_out),
|
||||
.G_out (G_out),
|
||||
.B_out (B_out),
|
||||
.HSYNC_out (HSYNC_out),
|
||||
.VSYNC_out (VSYNC_out),
|
||||
.PCLK_out (PCLK_out),
|
||||
.DATA_enable (DATA_enable),
|
||||
.h_unstable (h_unstable),
|
||||
.fpga_vsyncgen (fpga_vsyncgen),
|
||||
.pclk_lock (pclk_lock),
|
||||
.pll_lock_lost (pll_lock_lost),
|
||||
.lines_out (lines_out)
|
||||
);
|
||||
|
||||
ir_rcv ir0 (
|
||||
.clk27 (clk27),
|
||||
.reset_n (reset_n_reg),
|
||||
.ir_rx (ir_rx),
|
||||
.ir_code (ir_code),
|
||||
.ir_code_ack ()
|
||||
);
|
||||
|
||||
`ifdef VIDEOGEN
|
||||
videogen vg0 (
|
||||
.clk27 (clk27),
|
||||
.reset_n (reset_n_reg & videogen_sel),
|
||||
.R_out (R_out_videogen),
|
||||
.G_out (G_out_videogen),
|
||||
.B_out (B_out_videogen),
|
||||
.HSYNC_out (HSYNC_out_videogen),
|
||||
.VSYNC_out (VSYNC_out_videogen),
|
||||
.PCLK_out (PCLK_out_videogen),
|
||||
.ENABLE_out (DATA_enable_videogen)
|
||||
);
|
||||
`endif
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE pinplan>
|
||||
<pinplan intended_family="Cyclone IV E" variation_name="pll_2x" megafunction_name="ALTPLL" specifies="all_ports">
|
||||
<global>
|
||||
<pin name="areset" direction="input" scope="external" />
|
||||
<pin name="inclk0" direction="input" scope="external" source="clock" />
|
||||
<pin name="c0" direction="output" scope="external" source="clock" />
|
||||
<pin name="locked" direction="output" scope="external" />
|
||||
|
||||
</global>
|
||||
</pinplan>
|
|
@ -0,0 +1,6 @@
|
|||
set_global_assignment -name IP_TOOL_NAME "ALTPLL"
|
||||
set_global_assignment -name IP_TOOL_VERSION "15.1"
|
||||
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll_2x.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_2x_bb.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_2x.ppf"]
|
|
@ -0,0 +1,320 @@
|
|||
// megafunction wizard: %ALTPLL%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: altpll
|
||||
|
||||
// ============================================================
|
||||
// File Name: pll_2x.v
|
||||
// Megafunction Name(s):
|
||||
// altpll
|
||||
//
|
||||
// Simulation Library Files(s):
|
||||
//
|
||||
// ============================================================
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 15.1.0 Build 185 10/21/2015 SJ Lite Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
|
||||
//Your use of Altera Corporation's design tools, logic functions
|
||||
//and other software and tools, and its AMPP partner logic
|
||||
//functions, and any output files from any of the foregoing
|
||||
//(including device programming or simulation files), and any
|
||||
//associated documentation or information are expressly subject
|
||||
//to the terms and conditions of the Altera Program License
|
||||
//Subscription Agreement, the Altera Quartus Prime License Agreement,
|
||||
//the Altera MegaCore Function License Agreement, or other
|
||||
//applicable license agreement, including, without limitation,
|
||||
//that your use is for the sole purpose of programming logic
|
||||
//devices manufactured by Altera and sold by Altera or its
|
||||
//authorized distributors. Please refer to the applicable
|
||||
//agreement for further details.
|
||||
|
||||
|
||||
// synopsys translate_off
|
||||
`timescale 1 ps / 1 ps
|
||||
// synopsys translate_on
|
||||
module pll_2x (
|
||||
areset,
|
||||
inclk0,
|
||||
c0,
|
||||
locked);
|
||||
|
||||
input areset;
|
||||
input inclk0;
|
||||
output c0;
|
||||
output locked;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_off
|
||||
`endif
|
||||
tri0 areset;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_on
|
||||
`endif
|
||||
|
||||
wire [4:0] sub_wire0;
|
||||
wire sub_wire2;
|
||||
wire [0:0] sub_wire5 = 1'h0;
|
||||
wire [0:0] sub_wire1 = sub_wire0[0:0];
|
||||
wire c0 = sub_wire1;
|
||||
wire locked = sub_wire2;
|
||||
wire sub_wire3 = inclk0;
|
||||
wire [1:0] sub_wire4 = {sub_wire5, sub_wire3};
|
||||
|
||||
altpll altpll_component (
|
||||
.areset (areset),
|
||||
.inclk (sub_wire4),
|
||||
.clk (sub_wire0),
|
||||
.locked (sub_wire2),
|
||||
.activeclock (),
|
||||
.clkbad (),
|
||||
.clkena ({6{1'b1}}),
|
||||
.clkloss (),
|
||||
.clkswitch (1'b0),
|
||||
.configupdate (1'b0),
|
||||
.enable0 (),
|
||||
.enable1 (),
|
||||
.extclk (),
|
||||
.extclkena ({4{1'b1}}),
|
||||
.fbin (1'b1),
|
||||
.fbmimicbidir (),
|
||||
.fbout (),
|
||||
.fref (),
|
||||
.icdrclk (),
|
||||
.pfdena (1'b1),
|
||||
.phasecounterselect ({4{1'b1}}),
|
||||
.phasedone (),
|
||||
.phasestep (1'b1),
|
||||
.phaseupdown (1'b1),
|
||||
.pllena (1'b1),
|
||||
.scanaclr (1'b0),
|
||||
.scanclk (1'b0),
|
||||
.scanclkena (1'b1),
|
||||
.scandata (1'b0),
|
||||
.scandataout (),
|
||||
.scandone (),
|
||||
.scanread (1'b0),
|
||||
.scanwrite (1'b0),
|
||||
.sclkout0 (),
|
||||
.sclkout1 (),
|
||||
.vcooverrange (),
|
||||
.vcounderrange ());
|
||||
defparam
|
||||
altpll_component.bandwidth_type = "LOW",
|
||||
altpll_component.clk0_divide_by = 1,
|
||||
altpll_component.clk0_duty_cycle = 50,
|
||||
altpll_component.clk0_multiply_by = 2,
|
||||
altpll_component.clk0_phase_shift = "0",
|
||||
altpll_component.compensate_clock = "CLK0",
|
||||
altpll_component.inclk0_input_frequency = 74074,
|
||||
altpll_component.intended_device_family = "Cyclone IV E",
|
||||
altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll_2x",
|
||||
altpll_component.lpm_type = "altpll",
|
||||
altpll_component.operation_mode = "SOURCE_SYNCHRONOUS",
|
||||
altpll_component.pll_type = "AUTO",
|
||||
altpll_component.port_activeclock = "PORT_UNUSED",
|
||||
altpll_component.port_areset = "PORT_USED",
|
||||
altpll_component.port_clkbad0 = "PORT_UNUSED",
|
||||
altpll_component.port_clkbad1 = "PORT_UNUSED",
|
||||
altpll_component.port_clkloss = "PORT_UNUSED",
|
||||
altpll_component.port_clkswitch = "PORT_UNUSED",
|
||||
altpll_component.port_configupdate = "PORT_UNUSED",
|
||||
altpll_component.port_fbin = "PORT_UNUSED",
|
||||
altpll_component.port_inclk0 = "PORT_USED",
|
||||
altpll_component.port_inclk1 = "PORT_UNUSED",
|
||||
altpll_component.port_locked = "PORT_USED",
|
||||
altpll_component.port_pfdena = "PORT_UNUSED",
|
||||
altpll_component.port_phasecounterselect = "PORT_UNUSED",
|
||||
altpll_component.port_phasedone = "PORT_UNUSED",
|
||||
altpll_component.port_phasestep = "PORT_UNUSED",
|
||||
altpll_component.port_phaseupdown = "PORT_UNUSED",
|
||||
altpll_component.port_pllena = "PORT_UNUSED",
|
||||
altpll_component.port_scanaclr = "PORT_UNUSED",
|
||||
altpll_component.port_scanclk = "PORT_UNUSED",
|
||||
altpll_component.port_scanclkena = "PORT_UNUSED",
|
||||
altpll_component.port_scandata = "PORT_UNUSED",
|
||||
altpll_component.port_scandataout = "PORT_UNUSED",
|
||||
altpll_component.port_scandone = "PORT_UNUSED",
|
||||
altpll_component.port_scanread = "PORT_UNUSED",
|
||||
altpll_component.port_scanwrite = "PORT_UNUSED",
|
||||
altpll_component.port_clk0 = "PORT_USED",
|
||||
altpll_component.port_clk1 = "PORT_UNUSED",
|
||||
altpll_component.port_clk2 = "PORT_UNUSED",
|
||||
altpll_component.port_clk3 = "PORT_UNUSED",
|
||||
altpll_component.port_clk4 = "PORT_UNUSED",
|
||||
altpll_component.port_clk5 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena0 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena1 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena2 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena3 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena4 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena5 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk0 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk1 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk2 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk3 = "PORT_UNUSED",
|
||||
altpll_component.self_reset_on_loss_lock = "OFF",
|
||||
altpll_component.width_clock = 5;
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================
|
||||
// CNX file retrieval info
|
||||
// ============================================================
|
||||
// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "0"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "1"
|
||||
// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
|
||||
// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
|
||||
// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "7"
|
||||
// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "27.000000"
|
||||
// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
|
||||
// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
|
||||
// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "13.500"
|
||||
// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
|
||||
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
|
||||
// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
|
||||
// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
|
||||
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "2"
|
||||
// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "100.00000000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
|
||||
// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
|
||||
// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll_2x.mif"
|
||||
// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
|
||||
// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
|
||||
// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
|
||||
// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
|
||||
// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
|
||||
// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
|
||||
// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
|
||||
// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
|
||||
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "LOW"
|
||||
// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "1"
|
||||
// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "2"
|
||||
// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
|
||||
// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
|
||||
// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "74074"
|
||||
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
|
||||
// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
|
||||
// Retrieval info: CONSTANT: OPERATION_MODE STRING "SOURCE_SYNCHRONOUS"
|
||||
// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
|
||||
// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF"
|
||||
// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5"
|
||||
// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]"
|
||||
// Retrieval info: USED_PORT: areset 0 0 0 0 INPUT GND "areset"
|
||||
// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
|
||||
// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
|
||||
// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
|
||||
// Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0
|
||||
// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
|
||||
// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
|
||||
// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
|
||||
// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x.ppf TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x_bb.v TRUE
|
||||
// Retrieval info: CBX_MODULE_PREFIX: ON
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE pinplan>
|
||||
<pinplan intended_family="Cyclone IV E" variation_name="pll_3x" megafunction_name="ALTPLL" specifies="all_ports">
|
||||
<global>
|
||||
<pin name="areset" direction="input" scope="external" />
|
||||
<pin name="inclk0" direction="input" scope="external" source="clock" />
|
||||
<pin name="c0" direction="output" scope="external" source="clock" />
|
||||
<pin name="c1" direction="output" scope="external" source="clock" />
|
||||
<pin name="locked" direction="output" scope="external" />
|
||||
|
||||
</global>
|
||||
</pinplan>
|
|
@ -0,0 +1,5 @@
|
|||
set_global_assignment -name IP_TOOL_NAME "ALTPLL"
|
||||
set_global_assignment -name IP_TOOL_VERSION "15.1"
|
||||
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll_3x.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_3x.ppf"]
|
|
@ -0,0 +1,348 @@
|
|||
// megafunction wizard: %ALTPLL%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: altpll
|
||||
|
||||
// ============================================================
|
||||
// File Name: pll_3x.v
|
||||
// Megafunction Name(s):
|
||||
// altpll
|
||||
//
|
||||
// Simulation Library Files(s):
|
||||
//
|
||||
// ============================================================
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 15.1.0 Build 185 10/21/2015 SJ Lite Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
|
||||
//Your use of Altera Corporation's design tools, logic functions
|
||||
//and other software and tools, and its AMPP partner logic
|
||||
//functions, and any output files from any of the foregoing
|
||||
//(including device programming or simulation files), and any
|
||||
//associated documentation or information are expressly subject
|
||||
//to the terms and conditions of the Altera Program License
|
||||
//Subscription Agreement, the Altera Quartus Prime License Agreement,
|
||||
//the Altera MegaCore Function License Agreement, or other
|
||||
//applicable license agreement, including, without limitation,
|
||||
//that your use is for the sole purpose of programming logic
|
||||
//devices manufactured by Altera and sold by Altera or its
|
||||
//authorized distributors. Please refer to the applicable
|
||||
//agreement for further details.
|
||||
|
||||
|
||||
// synopsys translate_off
|
||||
`timescale 1 ps / 1 ps
|
||||
// synopsys translate_on
|
||||
module pll_3x (
|
||||
areset,
|
||||
inclk0,
|
||||
c0,
|
||||
c1,
|
||||
locked);
|
||||
|
||||
input areset;
|
||||
input inclk0;
|
||||
output c0;
|
||||
output c1;
|
||||
output locked;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_off
|
||||
`endif
|
||||
tri0 areset;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_on
|
||||
`endif
|
||||
|
||||
wire [4:0] sub_wire0;
|
||||
wire sub_wire3;
|
||||
wire [0:0] sub_wire6 = 1'h0;
|
||||
wire [1:1] sub_wire2 = sub_wire0[1:1];
|
||||
wire [0:0] sub_wire1 = sub_wire0[0:0];
|
||||
wire c0 = sub_wire1;
|
||||
wire c1 = sub_wire2;
|
||||
wire locked = sub_wire3;
|
||||
wire sub_wire4 = inclk0;
|
||||
wire [1:0] sub_wire5 = {sub_wire6, sub_wire4};
|
||||
|
||||
altpll altpll_component (
|
||||
.areset (areset),
|
||||
.inclk (sub_wire5),
|
||||
.clk (sub_wire0),
|
||||
.locked (sub_wire3),
|
||||
.activeclock (),
|
||||
.clkbad (),
|
||||
.clkena ({6{1'b1}}),
|
||||
.clkloss (),
|
||||
.clkswitch (1'b0),
|
||||
.configupdate (1'b0),
|
||||
.enable0 (),
|
||||
.enable1 (),
|
||||
.extclk (),
|
||||
.extclkena ({4{1'b1}}),
|
||||
.fbin (1'b1),
|
||||
.fbmimicbidir (),
|
||||
.fbout (),
|
||||
.fref (),
|
||||
.icdrclk (),
|
||||
.pfdena (1'b1),
|
||||
.phasecounterselect ({4{1'b1}}),
|
||||
.phasedone (),
|
||||
.phasestep (1'b1),
|
||||
.phaseupdown (1'b1),
|
||||
.pllena (1'b1),
|
||||
.scanaclr (1'b0),
|
||||
.scanclk (1'b0),
|
||||
.scanclkena (1'b1),
|
||||
.scandata (1'b0),
|
||||
.scandataout (),
|
||||
.scandone (),
|
||||
.scanread (1'b0),
|
||||
.scanwrite (1'b0),
|
||||
.sclkout0 (),
|
||||
.sclkout1 (),
|
||||
.vcooverrange (),
|
||||
.vcounderrange ());
|
||||
defparam
|
||||
altpll_component.bandwidth_type = "LOW",
|
||||
altpll_component.clk0_divide_by = 1,
|
||||
altpll_component.clk0_duty_cycle = 50,
|
||||
altpll_component.clk0_multiply_by = 3,
|
||||
altpll_component.clk0_phase_shift = "0",
|
||||
altpll_component.clk1_divide_by = 1,
|
||||
altpll_component.clk1_duty_cycle = 50,
|
||||
altpll_component.clk1_multiply_by = 4,
|
||||
altpll_component.clk1_phase_shift = "0",
|
||||
altpll_component.compensate_clock = "CLK0",
|
||||
altpll_component.inclk0_input_frequency = 37037,
|
||||
altpll_component.intended_device_family = "Cyclone IV E",
|
||||
altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll_3x",
|
||||
altpll_component.lpm_type = "altpll",
|
||||
altpll_component.operation_mode = "SOURCE_SYNCHRONOUS",
|
||||
altpll_component.pll_type = "AUTO",
|
||||
altpll_component.port_activeclock = "PORT_UNUSED",
|
||||
altpll_component.port_areset = "PORT_USED",
|
||||
altpll_component.port_clkbad0 = "PORT_UNUSED",
|
||||
altpll_component.port_clkbad1 = "PORT_UNUSED",
|
||||
altpll_component.port_clkloss = "PORT_UNUSED",
|
||||
altpll_component.port_clkswitch = "PORT_UNUSED",
|
||||
altpll_component.port_configupdate = "PORT_UNUSED",
|
||||
altpll_component.port_fbin = "PORT_UNUSED",
|
||||
altpll_component.port_inclk0 = "PORT_USED",
|
||||
altpll_component.port_inclk1 = "PORT_UNUSED",
|
||||
altpll_component.port_locked = "PORT_USED",
|
||||
altpll_component.port_pfdena = "PORT_UNUSED",
|
||||
altpll_component.port_phasecounterselect = "PORT_UNUSED",
|
||||
altpll_component.port_phasedone = "PORT_UNUSED",
|
||||
altpll_component.port_phasestep = "PORT_UNUSED",
|
||||
altpll_component.port_phaseupdown = "PORT_UNUSED",
|
||||
altpll_component.port_pllena = "PORT_UNUSED",
|
||||
altpll_component.port_scanaclr = "PORT_UNUSED",
|
||||
altpll_component.port_scanclk = "PORT_UNUSED",
|
||||
altpll_component.port_scanclkena = "PORT_UNUSED",
|
||||
altpll_component.port_scandata = "PORT_UNUSED",
|
||||
altpll_component.port_scandataout = "PORT_UNUSED",
|
||||
altpll_component.port_scandone = "PORT_UNUSED",
|
||||
altpll_component.port_scanread = "PORT_UNUSED",
|
||||
altpll_component.port_scanwrite = "PORT_UNUSED",
|
||||
altpll_component.port_clk0 = "PORT_USED",
|
||||
altpll_component.port_clk1 = "PORT_USED",
|
||||
altpll_component.port_clk2 = "PORT_UNUSED",
|
||||
altpll_component.port_clk3 = "PORT_UNUSED",
|
||||
altpll_component.port_clk4 = "PORT_UNUSED",
|
||||
altpll_component.port_clk5 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena0 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena1 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena2 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena3 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena4 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena5 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk0 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk1 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk2 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk3 = "PORT_UNUSED",
|
||||
altpll_component.self_reset_on_loss_lock = "OFF",
|
||||
altpll_component.width_clock = 5;
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================
|
||||
// CNX file retrieval info
|
||||
// ============================================================
|
||||
// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "0"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "1"
|
||||
// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
|
||||
// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
|
||||
// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "7"
|
||||
// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "81.000000"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "108.000000"
|
||||
// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
|
||||
// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
|
||||
// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "27.000"
|
||||
// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
|
||||
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
|
||||
// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
|
||||
// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
|
||||
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "deg"
|
||||
// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "3"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "4"
|
||||
// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "100.00000000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "100.00000000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg"
|
||||
// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
|
||||
// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
|
||||
// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll_2x.mif"
|
||||
// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
|
||||
// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
|
||||
// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
|
||||
// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
|
||||
// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
|
||||
// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
|
||||
// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
|
||||
// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLK1 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
|
||||
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "LOW"
|
||||
// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "1"
|
||||
// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "3"
|
||||
// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
|
||||
// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "1"
|
||||
// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "4"
|
||||
// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0"
|
||||
// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
|
||||
// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037"
|
||||
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
|
||||
// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
|
||||
// Retrieval info: CONSTANT: OPERATION_MODE STRING "SOURCE_SYNCHRONOUS"
|
||||
// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
|
||||
// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF"
|
||||
// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5"
|
||||
// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]"
|
||||
// Retrieval info: USED_PORT: areset 0 0 0 0 INPUT GND "areset"
|
||||
// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
|
||||
// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1"
|
||||
// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
|
||||
// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
|
||||
// Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0
|
||||
// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
|
||||
// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
|
||||
// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
|
||||
// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1
|
||||
// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_3x.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_3x.ppf TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_3x.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_3x.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_3x.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_3x_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_3x_bb.v FALSE
|
||||
// Retrieval info: CBX_MODULE_PREFIX: ON
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE pinplan>
|
||||
<pinplan intended_family="Cyclone IV E" variation_name="pll_3x_lowfreq" megafunction_name="ALTPLL" specifies="all_ports">
|
||||
<global>
|
||||
<pin name="areset" direction="input" scope="external" />
|
||||
<pin name="inclk0" direction="input" scope="external" source="clock" />
|
||||
<pin name="c0" direction="output" scope="external" source="clock" />
|
||||
<pin name="c1" direction="output" scope="external" source="clock" />
|
||||
<pin name="c2" direction="output" scope="external" source="clock" />
|
||||
<pin name="locked" direction="output" scope="external" />
|
||||
|
||||
</global>
|
||||
</pinplan>
|
|
@ -0,0 +1,6 @@
|
|||
set_global_assignment -name IP_TOOL_NAME "ALTPLL"
|
||||
set_global_assignment -name IP_TOOL_VERSION "15.1"
|
||||
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll_3x_lowfreq.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_3x_lowfreq_bb.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_3x_lowfreq.ppf"]
|
|
@ -0,0 +1,376 @@
|
|||
// megafunction wizard: %ALTPLL%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: altpll
|
||||
|
||||
// ============================================================
|
||||
// File Name: pll_3x_lowfreq.v
|
||||
// Megafunction Name(s):
|
||||
// altpll
|
||||
//
|
||||
// Simulation Library Files(s):
|
||||
//
|
||||
// ============================================================
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 15.1.0 Build 185 10/21/2015 SJ Lite Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
|
||||
//Your use of Altera Corporation's design tools, logic functions
|
||||
//and other software and tools, and its AMPP partner logic
|
||||
//functions, and any output files from any of the foregoing
|
||||
//(including device programming or simulation files), and any
|
||||
//associated documentation or information are expressly subject
|
||||
//to the terms and conditions of the Altera Program License
|
||||
//Subscription Agreement, the Altera Quartus Prime License Agreement,
|
||||
//the Altera MegaCore Function License Agreement, or other
|
||||
//applicable license agreement, including, without limitation,
|
||||
//that your use is for the sole purpose of programming logic
|
||||
//devices manufactured by Altera and sold by Altera or its
|
||||
//authorized distributors. Please refer to the applicable
|
||||
//agreement for further details.
|
||||
|
||||
|
||||
// synopsys translate_off
|
||||
`timescale 1 ps / 1 ps
|
||||
// synopsys translate_on
|
||||
module pll_3x_lowfreq (
|
||||
areset,
|
||||
inclk0,
|
||||
c0,
|
||||
c1,
|
||||
c2,
|
||||
locked);
|
||||
|
||||
input areset;
|
||||
input inclk0;
|
||||
output c0;
|
||||
output c1;
|
||||
output c2;
|
||||
output locked;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_off
|
||||
`endif
|
||||
tri0 areset;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_on
|
||||
`endif
|
||||
|
||||
wire [4:0] sub_wire0;
|
||||
wire sub_wire4;
|
||||
wire [0:0] sub_wire7 = 1'h0;
|
||||
wire [2:2] sub_wire3 = sub_wire0[2:2];
|
||||
wire [1:1] sub_wire2 = sub_wire0[1:1];
|
||||
wire [0:0] sub_wire1 = sub_wire0[0:0];
|
||||
wire c0 = sub_wire1;
|
||||
wire c1 = sub_wire2;
|
||||
wire c2 = sub_wire3;
|
||||
wire locked = sub_wire4;
|
||||
wire sub_wire5 = inclk0;
|
||||
wire [1:0] sub_wire6 = {sub_wire7, sub_wire5};
|
||||
|
||||
altpll altpll_component (
|
||||
.areset (areset),
|
||||
.inclk (sub_wire6),
|
||||
.clk (sub_wire0),
|
||||
.locked (sub_wire4),
|
||||
.activeclock (),
|
||||
.clkbad (),
|
||||
.clkena ({6{1'b1}}),
|
||||
.clkloss (),
|
||||
.clkswitch (1'b0),
|
||||
.configupdate (1'b0),
|
||||
.enable0 (),
|
||||
.enable1 (),
|
||||
.extclk (),
|
||||
.extclkena ({4{1'b1}}),
|
||||
.fbin (1'b1),
|
||||
.fbmimicbidir (),
|
||||
.fbout (),
|
||||
.fref (),
|
||||
.icdrclk (),
|
||||
.pfdena (1'b1),
|
||||
.phasecounterselect ({4{1'b1}}),
|
||||
.phasedone (),
|
||||
.phasestep (1'b1),
|
||||
.phaseupdown (1'b1),
|
||||
.pllena (1'b1),
|
||||
.scanaclr (1'b0),
|
||||
.scanclk (1'b0),
|
||||
.scanclkena (1'b1),
|
||||
.scandata (1'b0),
|
||||
.scandataout (),
|
||||
.scandone (),
|
||||
.scanread (1'b0),
|
||||
.scanwrite (1'b0),
|
||||
.sclkout0 (),
|
||||
.sclkout1 (),
|
||||
.vcooverrange (),
|
||||
.vcounderrange ());
|
||||
defparam
|
||||
altpll_component.bandwidth_type = "LOW",
|
||||
altpll_component.clk0_divide_by = 1,
|
||||
altpll_component.clk0_duty_cycle = 50,
|
||||
altpll_component.clk0_multiply_by = 3,
|
||||
altpll_component.clk0_phase_shift = "0",
|
||||
altpll_component.clk1_divide_by = 1,
|
||||
altpll_component.clk1_duty_cycle = 50,
|
||||
altpll_component.clk1_multiply_by = 12,
|
||||
altpll_component.clk1_phase_shift = "0",
|
||||
altpll_component.clk2_divide_by = 1,
|
||||
altpll_component.clk2_duty_cycle = 50,
|
||||
altpll_component.clk2_multiply_by = 15,
|
||||
altpll_component.clk2_phase_shift = "0",
|
||||
altpll_component.compensate_clock = "CLK0",
|
||||
altpll_component.inclk0_input_frequency = 149253,
|
||||
altpll_component.intended_device_family = "Cyclone IV E",
|
||||
altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll_3x_lowfreq",
|
||||
altpll_component.lpm_type = "altpll",
|
||||
altpll_component.operation_mode = "SOURCE_SYNCHRONOUS",
|
||||
altpll_component.pll_type = "AUTO",
|
||||
altpll_component.port_activeclock = "PORT_UNUSED",
|
||||
altpll_component.port_areset = "PORT_USED",
|
||||
altpll_component.port_clkbad0 = "PORT_UNUSED",
|
||||
altpll_component.port_clkbad1 = "PORT_UNUSED",
|
||||
altpll_component.port_clkloss = "PORT_UNUSED",
|
||||
altpll_component.port_clkswitch = "PORT_UNUSED",
|
||||
altpll_component.port_configupdate = "PORT_UNUSED",
|
||||
altpll_component.port_fbin = "PORT_UNUSED",
|
||||
altpll_component.port_inclk0 = "PORT_USED",
|
||||
altpll_component.port_inclk1 = "PORT_UNUSED",
|
||||
altpll_component.port_locked = "PORT_USED",
|
||||
altpll_component.port_pfdena = "PORT_UNUSED",
|
||||
altpll_component.port_phasecounterselect = "PORT_UNUSED",
|
||||
altpll_component.port_phasedone = "PORT_UNUSED",
|
||||
altpll_component.port_phasestep = "PORT_UNUSED",
|
||||
altpll_component.port_phaseupdown = "PORT_UNUSED",
|
||||
altpll_component.port_pllena = "PORT_UNUSED",
|
||||
altpll_component.port_scanaclr = "PORT_UNUSED",
|
||||
altpll_component.port_scanclk = "PORT_UNUSED",
|
||||
altpll_component.port_scanclkena = "PORT_UNUSED",
|
||||
altpll_component.port_scandata = "PORT_UNUSED",
|
||||
altpll_component.port_scandataout = "PORT_UNUSED",
|
||||
altpll_component.port_scandone = "PORT_UNUSED",
|
||||
altpll_component.port_scanread = "PORT_UNUSED",
|
||||
altpll_component.port_scanwrite = "PORT_UNUSED",
|
||||
altpll_component.port_clk0 = "PORT_USED",
|
||||
altpll_component.port_clk1 = "PORT_USED",
|
||||
altpll_component.port_clk2 = "PORT_USED",
|
||||
altpll_component.port_clk3 = "PORT_UNUSED",
|
||||
altpll_component.port_clk4 = "PORT_UNUSED",
|
||||
altpll_component.port_clk5 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena0 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena1 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena2 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena3 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena4 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena5 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk0 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk1 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk2 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk3 = "PORT_UNUSED",
|
||||
altpll_component.self_reset_on_loss_lock = "OFF",
|
||||
altpll_component.width_clock = 5;
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================
|
||||
// CNX file retrieval info
|
||||
// ============================================================
|
||||
// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "0"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "1"
|
||||
// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
|
||||
// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
|
||||
// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "7"
|
||||
// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE2 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "20.100000"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "80.400002"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "100.500000"
|
||||
// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
|
||||
// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
|
||||
// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "6.700"
|
||||
// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
|
||||
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
|
||||
// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
|
||||
// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
|
||||
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "deg"
|
||||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT2 STRING "ps"
|
||||
// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK2 STRING "0"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "3"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "12"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "15"
|
||||
// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "100.00000000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "100.00000000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "100.00000000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "0"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT2 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT2 STRING "ps"
|
||||
// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
|
||||
// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
|
||||
// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll_2x.mif"
|
||||
// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
|
||||
// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
|
||||
// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
|
||||
// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
|
||||
// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
|
||||
// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
|
||||
// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK2 STRING "1"
|
||||
// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLK1 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLK2 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA2 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
|
||||
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "LOW"
|
||||
// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "1"
|
||||
// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "3"
|
||||
// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
|
||||
// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "1"
|
||||
// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "12"
|
||||
// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0"
|
||||
// Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "1"
|
||||
// Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "15"
|
||||
// Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "0"
|
||||
// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
|
||||
// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "149253"
|
||||
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
|
||||
// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
|
||||
// Retrieval info: CONSTANT: OPERATION_MODE STRING "SOURCE_SYNCHRONOUS"
|
||||
// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
|
||||
// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF"
|
||||
// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5"
|
||||
// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]"
|
||||
// Retrieval info: USED_PORT: areset 0 0 0 0 INPUT GND "areset"
|
||||
// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
|
||||
// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1"
|
||||
// Retrieval info: USED_PORT: c2 0 0 0 0 OUTPUT_CLK_EXT VCC "c2"
|
||||
// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
|
||||
// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
|
||||
// Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0
|
||||
// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
|
||||
// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
|
||||
// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
|
||||
// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1
|
||||
// Retrieval info: CONNECT: c2 0 0 0 0 @clk 0 0 1 2
|
||||
// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_3x_lowfreq.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_3x_lowfreq.ppf TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_3x_lowfreq.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_3x_lowfreq.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_3x_lowfreq.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_3x_lowfreq_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_3x_lowfreq_bb.v TRUE
|
||||
// Retrieval info: CBX_MODULE_PREFIX: ON
|
|
@ -0,0 +1,682 @@
|
|||
//
|
||||
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
`define TRUE 1'b1
|
||||
`define FALSE 1'b0
|
||||
`define HI 1'b1
|
||||
`define LO 1'b0
|
||||
|
||||
`define LINEMULT_DISABLE 2'h0
|
||||
`define LINEMULT_DOUBLE 2'h1
|
||||
`define LINEMULT_TRIPLE 2'h2
|
||||
|
||||
`define LINETRIPLE_M0 2'h0
|
||||
`define LINETRIPLE_M1 2'h1
|
||||
`define LINETRIPLE_M2 2'h2
|
||||
`define LINETRIPLE_M3 2'h3
|
||||
|
||||
`define VSYNCGEN_LEN 6
|
||||
`define VSYNCGEN_GENMID_BIT 0
|
||||
`define VSYNCGEN_CHOPMID_BIT 1
|
||||
|
||||
`define FID_EVEN 1'b0
|
||||
`define FID_ODD 1'b1
|
||||
|
||||
`define MIN_VALID_LINES 256 //power of 2 optimization -> ignore lower bits with comparison
|
||||
`define FALSE_FIELD (fpga_vsyncgen[`VSYNCGEN_CHOPMID_BIT] & (FID_in == `FID_ODD))
|
||||
|
||||
`define VSYNC_LEADING_EDGE ((prev_vs == `HI) & (VSYNC_in == `LO))
|
||||
`define VSYNC_TRAILING_EDGE ((prev_vs == `LO) & (VSYNC_in == `HI))
|
||||
|
||||
`define HSYNC_LEADING_EDGE ((prev_hs == `HI) & (HSYNC_in == `LO))
|
||||
`define HSYNC_TRAILING_EDGE ((prev_hs == `LO) & (HSYNC_in == `HI))
|
||||
|
||||
module scanconverter (
|
||||
input [7:0] R_in,
|
||||
input [7:0] G_in,
|
||||
input [7:0] B_in,
|
||||
input FID_in,
|
||||
input VSYNC_in,
|
||||
input HSYNC_in,
|
||||
input PCLK_in,
|
||||
input [31:0] h_info,
|
||||
input [31:0] v_info,
|
||||
output reg [7:0] R_out,
|
||||
output reg [7:0] G_out,
|
||||
output reg [7:0] B_out,
|
||||
output reg HSYNC_out,
|
||||
output reg VSYNC_out,
|
||||
output PCLK_out,
|
||||
output reg DATA_enable,
|
||||
output h_unstable,
|
||||
output reg [1:0] fpga_vsyncgen,
|
||||
output [2:0] pclk_lock,
|
||||
output [2:0] pll_lock_lost,
|
||||
output [10:0] lines_out
|
||||
);
|
||||
|
||||
wire pclk_1x, pclk_2x, pclk_3x, pclk_4x, pclk_3x_h1x, pclk_3x_h4x, pclk_3x_h5x;
|
||||
wire pclk_out_1x, pclk_out_2x, pclk_out_3x, pclk_out_4x, pclk_out_3x_h4x, pclk_out_3x_h5x;
|
||||
wire linebuf_rdclock;
|
||||
|
||||
wire pclk_act;
|
||||
wire [1:0] slid_act;
|
||||
|
||||
wire pclk_2x_lock, pclk_3x_lock, pclk_3x_lowfreq_lock;
|
||||
|
||||
wire HSYNC_act, VSYNC_act;
|
||||
reg HSYNC_1x, HSYNC_2x, HSYNC_3x, HSYNC_3x_h1x, HSYNC_pp1;
|
||||
reg VSYNC_1x, VSYNC_2x, VSYNC_pp1;
|
||||
|
||||
reg [11:0] HSYNC_start;
|
||||
|
||||
reg FID_prev;
|
||||
|
||||
wire DATA_enable_act;
|
||||
reg DATA_enable_pp1;
|
||||
|
||||
wire [11:0] linebuf_hoffset; //Offset for line (max. 2047 pixels), MSB indicates which line is read/written
|
||||
wire [11:0] hcnt_act;
|
||||
reg [11:0] hcnt_1x, hcnt_2x, hcnt_3x, hcnt_4x, hcnt_3x_h1x, hcnt_3x_h4x, hcnt_3x_h5x;
|
||||
|
||||
wire [10:0] vcnt_act;
|
||||
reg [10:0] vcnt_1x, vcnt_1x_tvp, vcnt_2x, lines_1x, lines_2x; //max. 2047
|
||||
reg [9:0] vcnt_3x, vcnt_3x_h1x, lines_3x, lines_3x_h1x; //max. 1023
|
||||
|
||||
reg h_enable_3x_prev4x, h_enable_3x_prev3x_h4x, h_enable_3x_prev3x_h5x;
|
||||
reg [1:0] hcnt_3x_h4x_ctr;
|
||||
reg [1:0] hcnt_3x_h5x_ctr;
|
||||
|
||||
reg pclk_1x_prev3x, pclk_1x_prev3x_h1x, pclk_1x_prev3x_h4x;
|
||||
reg [1:0] pclk_3x_cnt, pclk_3x_h1x_cnt;
|
||||
reg [3:0] pclk_3x_h4x_cnt;
|
||||
|
||||
// Data enable
|
||||
reg h_enable_1x, v_enable_1x;
|
||||
reg h_enable_2x, v_enable_2x;
|
||||
reg h_enable_3x, h_enable_3x_h1x, v_enable_3x, v_enable_3x_h1x;
|
||||
|
||||
reg prev_hs, prev_vs;
|
||||
reg [11:0] hmax[0:1];
|
||||
reg line_idx;
|
||||
|
||||
reg [23:0] warn_h_unstable, warn_pll_lock_lost, warn_pll_lock_lost_3x, warn_pll_lock_lost_3x_lowfreq;
|
||||
|
||||
reg [10:0] H_ACTIVE; //max. 2047
|
||||
reg [7:0] H_BACKPORCH; //max. 255
|
||||
reg [10:0] V_ACTIVE; //max. 2047
|
||||
reg [5:0] V_BACKPORCH; //max. 63
|
||||
reg V_SCANLINES;
|
||||
reg V_SCANLINEDIR;
|
||||
reg V_SCANLINEID;
|
||||
reg [7:0] V_SCANLINESTR;
|
||||
reg [5:0] V_MASK;
|
||||
reg [1:0] H_LINEMULT;
|
||||
reg [1:0] H_L3MODE;
|
||||
reg [5:0] H_MASK;
|
||||
|
||||
//8 bits per component -> 16.7M colors
|
||||
reg [7:0] R_1x, G_1x, B_1x, R_pp1, G_pp1, B_pp1;
|
||||
wire [7:0] R_lbuf, G_lbuf, B_lbuf;
|
||||
wire [7:0] R_act, G_act, B_act;
|
||||
|
||||
|
||||
assign pclk_1x = PCLK_in;
|
||||
assign pclk_lock = {pclk_2x_lock, pclk_3x_lock, pclk_3x_lowfreq_lock};
|
||||
|
||||
//Output sampled at the rising edge of active pclk
|
||||
assign pclk_out_1x = PCLK_in;
|
||||
assign pclk_out_2x = pclk_2x;
|
||||
assign pclk_out_3x = pclk_3x;
|
||||
assign pclk_out_4x = pclk_4x;
|
||||
assign pclk_out_3x_h4x = pclk_3x_h4x;
|
||||
assign pclk_out_3x_h5x = pclk_3x_h5x;
|
||||
|
||||
//Scanline generation
|
||||
function [8:0] apply_scanlines;
|
||||
input enable;
|
||||
input dir;
|
||||
input [8:0] data;
|
||||
input [8:0] str;
|
||||
input [1:0] actid;
|
||||
input [1:0] lineid;
|
||||
input pixid;
|
||||
begin
|
||||
if (enable & (dir == 1'b0) & (actid == lineid))
|
||||
apply_scanlines = (data > str) ? (data-str) : 8'h00;
|
||||
else if (enable & (dir == 1'b1) & (actid == pixid))
|
||||
apply_scanlines = (data > str) ? (data-str) : 8'h00;
|
||||
else
|
||||
apply_scanlines = data;
|
||||
end
|
||||
endfunction
|
||||
|
||||
//Border masking
|
||||
function [8:0] apply_mask;
|
||||
input enable;
|
||||
input [8:0] data;
|
||||
input [11:0] hoffset;
|
||||
input [11:0] hstart;
|
||||
input [11:0] hend;
|
||||
input [10:0] voffset;
|
||||
input [10:0] vstart;
|
||||
input [10:0] vend;
|
||||
begin
|
||||
if (enable & ((hoffset < hstart) | (hoffset >= hend) | (voffset < vstart) | (voffset >= vend)))
|
||||
apply_mask = 8'h00;
|
||||
else
|
||||
apply_mask = data;
|
||||
//apply_mask = (hoffset[0] ^ voffset[0]) ? 8'b11111111 : 8'b00000000;
|
||||
end
|
||||
endfunction
|
||||
|
||||
|
||||
//Mux for active data selection
|
||||
//
|
||||
//Possible clock transfers:
|
||||
//
|
||||
// L3_MODE1: pclk_3x -> pclk_4x
|
||||
// L3_MODE2: pclk_3x_h1x -> pclk_3x_h4x
|
||||
// L3_MODE3: pclk_3x_h1x -> pclk_3x_h5x
|
||||
//
|
||||
//List of critical signals:
|
||||
// DATA_enable_act, HSYNC_act
|
||||
//
|
||||
//Non-critical signals and inactive clock combinations filtered out in SDC
|
||||
always @(*)
|
||||
begin
|
||||
case (H_LINEMULT)
|
||||
`LINEMULT_DISABLE: begin
|
||||
R_act = R_1x;
|
||||
G_act = G_1x;
|
||||
B_act = B_1x;
|
||||
DATA_enable_act = (h_enable_1x & v_enable_1x);
|
||||
PCLK_out = pclk_out_1x;
|
||||
HSYNC_act = HSYNC_1x;
|
||||
VSYNC_act = VSYNC_1x;
|
||||
lines_out = lines_1x;
|
||||
linebuf_rdclock = 0;
|
||||
linebuf_hoffset = 0;
|
||||
pclk_act = pclk_1x;
|
||||
slid_act = {1'b0, vcnt_1x[0]};
|
||||
hcnt_act = hcnt_1x;
|
||||
vcnt_act = vcnt_1x;
|
||||
end
|
||||
`LINEMULT_DOUBLE: begin
|
||||
R_act = R_lbuf;
|
||||
G_act = G_lbuf;
|
||||
B_act = B_lbuf;
|
||||
DATA_enable_act = (h_enable_2x & v_enable_2x);
|
||||
PCLK_out = pclk_out_2x;
|
||||
HSYNC_act = HSYNC_2x;
|
||||
VSYNC_act = VSYNC_2x;
|
||||
lines_out = lines_2x;
|
||||
linebuf_rdclock = pclk_2x;
|
||||
linebuf_hoffset = hcnt_2x;
|
||||
pclk_act = pclk_2x;
|
||||
slid_act = {1'b0, vcnt_2x[0]};
|
||||
hcnt_act = hcnt_2x;
|
||||
vcnt_act = vcnt_2x>>1;
|
||||
end
|
||||
`LINEMULT_TRIPLE: begin
|
||||
R_act = R_lbuf;
|
||||
G_act = G_lbuf;
|
||||
B_act = B_lbuf;
|
||||
VSYNC_act = VSYNC_1x;
|
||||
case (H_L3MODE)
|
||||
`LINETRIPLE_M0: begin
|
||||
DATA_enable_act = (h_enable_3x & v_enable_3x);
|
||||
PCLK_out = pclk_out_3x;
|
||||
HSYNC_act = HSYNC_3x;
|
||||
lines_out = {1'b0, lines_3x};
|
||||
linebuf_rdclock = pclk_3x;
|
||||
linebuf_hoffset = hcnt_3x;
|
||||
pclk_act = pclk_3x;
|
||||
hcnt_act = hcnt_3x;
|
||||
vcnt_act = vcnt_3x/2'h3; //divider generated
|
||||
slid_act = (vcnt_3x % 2'h3);
|
||||
end
|
||||
`LINETRIPLE_M1: begin
|
||||
DATA_enable_act = (h_enable_3x & v_enable_3x);
|
||||
PCLK_out = pclk_out_4x;
|
||||
HSYNC_act = HSYNC_3x;
|
||||
lines_out = {1'b0, lines_3x};
|
||||
linebuf_rdclock = pclk_4x;
|
||||
linebuf_hoffset = hcnt_4x;
|
||||
pclk_act = pclk_4x;
|
||||
hcnt_act = hcnt_4x;
|
||||
vcnt_act = vcnt_3x/2'h3; //divider generated
|
||||
slid_act = (vcnt_3x % 2'h3);
|
||||
end
|
||||
`LINETRIPLE_M2: begin
|
||||
DATA_enable_act = (h_enable_3x_h1x & v_enable_3x_h1x);
|
||||
PCLK_out = pclk_out_3x_h4x;
|
||||
HSYNC_act = HSYNC_3x_h1x;
|
||||
lines_out = {1'b0, lines_3x_h1x};
|
||||
linebuf_rdclock = pclk_3x_h4x;
|
||||
linebuf_hoffset = hcnt_3x_h4x;
|
||||
pclk_act = pclk_3x_h4x;
|
||||
hcnt_act = hcnt_3x_h4x;
|
||||
vcnt_act = vcnt_3x_h1x/2'h3; //divider generated
|
||||
slid_act = (vcnt_3x_h1x % 2'h3);
|
||||
end
|
||||
`LINETRIPLE_M3: begin
|
||||
DATA_enable_act = (h_enable_3x_h1x & v_enable_3x_h1x);
|
||||
PCLK_out = pclk_out_3x_h5x;
|
||||
HSYNC_act = HSYNC_3x_h1x;
|
||||
lines_out = {1'b0, lines_3x_h1x};
|
||||
linebuf_rdclock = pclk_3x_h5x;
|
||||
linebuf_hoffset = hcnt_3x_h5x;
|
||||
pclk_act = pclk_3x_h5x;
|
||||
hcnt_act = hcnt_3x_h5x;
|
||||
vcnt_act = vcnt_3x_h1x/2'h3; //divider generated
|
||||
slid_act = (vcnt_3x_h1x % 2'h3);
|
||||
end
|
||||
endcase
|
||||
end
|
||||
default: begin
|
||||
R_act = 0;
|
||||
G_act = 0;
|
||||
B_act = 0;
|
||||
DATA_enable_act = 0;
|
||||
PCLK_out = 0;
|
||||
HSYNC_act = 0;
|
||||
VSYNC_act = VSYNC_1x;
|
||||
lines_out = 0;
|
||||
linebuf_rdclock = 0;
|
||||
linebuf_hoffset = 0;
|
||||
pclk_act = 0;
|
||||
slid_act = 0;
|
||||
hcnt_act = 0;
|
||||
vcnt_act = 0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
pll_2x pll_linedouble (
|
||||
.areset ( (H_LINEMULT != `LINEMULT_DOUBLE) ),
|
||||
.inclk0 ( PCLK_in ),
|
||||
.c0 ( pclk_2x ),
|
||||
.locked ( pclk_2x_lock )
|
||||
);
|
||||
|
||||
pll_3x pll_linetriple (
|
||||
.areset ( ((H_LINEMULT != `LINEMULT_TRIPLE) | H_L3MODE[1]) ),
|
||||
.inclk0 ( PCLK_in ),
|
||||
.c0 ( pclk_3x ), // sampling clock for 240p: 1280 or 960 samples & MODE0: 1280 output pixels from 1280 input samples (16:9)
|
||||
.c1 ( pclk_4x ), // MODE1: 1280 output pixels from 960 input samples (960 drawn -> 4:3 aspect)
|
||||
.locked ( pclk_3x_lock )
|
||||
);
|
||||
|
||||
pll_3x_lowfreq pll_linetriple_lowfreq (
|
||||
.areset ( (H_LINEMULT != `LINEMULT_TRIPLE) | ~H_L3MODE[1]),
|
||||
.inclk0 ( PCLK_in ),
|
||||
.c0 ( pclk_3x_h1x ), // sampling clock for 240p: 320 or 256 samples
|
||||
.c1 ( pclk_3x_h4x ), // MODE2: 1280 output pixels from 320 input samples (960 drawn -> 4:3 aspect)
|
||||
.c2 ( pclk_3x_h5x ), // MODE3: 1280 output pixels from 256 input samples (1024 drawn -> 5:4 aspect)
|
||||
.locked ( pclk_3x_lowfreq_lock )
|
||||
);
|
||||
|
||||
//TODO: add secondary buffers for interlaced signals with alternative field order
|
||||
linebuf linebuf_rgb (
|
||||
.data ( {R_1x, G_1x, B_1x} ), //or *_in?
|
||||
.rdaddress ( linebuf_hoffset + (~line_idx << 11) ),
|
||||
.rdclock ( linebuf_rdclock ),
|
||||
.wraddress ( hcnt_1x + (line_idx << 11) ),
|
||||
.wrclock ( pclk_1x ),
|
||||
.wren ( 1'b1 ),
|
||||
.q ( {R_lbuf, G_lbuf, B_lbuf} )
|
||||
);
|
||||
|
||||
//Postprocess pipeline
|
||||
always @(posedge pclk_act /*or negedge reset_n*/)
|
||||
begin
|
||||
/*if (!reset_n)
|
||||
begin
|
||||
end
|
||||
else*/
|
||||
begin
|
||||
R_pp1 <= apply_mask(1, R_act, hcnt_act, H_BACKPORCH+H_MASK, H_BACKPORCH+H_ACTIVE-H_MASK, vcnt_act, V_BACKPORCH+V_MASK, V_BACKPORCH+V_ACTIVE-V_MASK);
|
||||
G_pp1 <= apply_mask(1, G_act, hcnt_act, H_BACKPORCH+H_MASK, H_BACKPORCH+H_ACTIVE-H_MASK, vcnt_act, V_BACKPORCH+V_MASK, V_BACKPORCH+V_ACTIVE-V_MASK);
|
||||
B_pp1 <= apply_mask(1, B_act, hcnt_act, H_BACKPORCH+H_MASK, H_BACKPORCH+H_ACTIVE-H_MASK, vcnt_act, V_BACKPORCH+V_MASK, V_BACKPORCH+V_ACTIVE-V_MASK);
|
||||
HSYNC_pp1 <= HSYNC_act;
|
||||
VSYNC_pp1 <= VSYNC_act;
|
||||
DATA_enable_pp1 <= DATA_enable_act;
|
||||
|
||||
R_out <= apply_scanlines(V_SCANLINES, V_SCANLINEDIR, R_pp1, V_SCANLINESTR, {1'b0, V_SCANLINEID}, slid_act, hcnt_act[0]);
|
||||
G_out <= apply_scanlines(V_SCANLINES, V_SCANLINEDIR, G_pp1, V_SCANLINESTR, {1'b0, V_SCANLINEID}, slid_act, hcnt_act[0]);
|
||||
B_out <= apply_scanlines(V_SCANLINES, V_SCANLINEDIR, B_pp1, V_SCANLINESTR, {1'b0, V_SCANLINEID}, slid_act, hcnt_act[0]);
|
||||
HSYNC_out <= HSYNC_pp1;
|
||||
VSYNC_out <= VSYNC_pp1;
|
||||
DATA_enable <= DATA_enable_pp1;
|
||||
end
|
||||
end
|
||||
|
||||
//Generate a warning signal from horizontal instability or PLL sync loss
|
||||
always @(posedge pclk_1x /*or negedge reset_n*/)
|
||||
begin
|
||||
/*if (!reset_n)
|
||||
begin
|
||||
end
|
||||
else*/
|
||||
begin
|
||||
if (hmax[0] != hmax[1])
|
||||
warn_h_unstable <= 1;
|
||||
else if (warn_h_unstable != 0)
|
||||
warn_h_unstable <= warn_h_unstable + 1'b1;
|
||||
|
||||
if ((H_LINEMULT == `LINEMULT_DOUBLE) & ~pclk_2x_lock)
|
||||
warn_pll_lock_lost <= 1;
|
||||
else if (warn_pll_lock_lost != 0)
|
||||
warn_pll_lock_lost <= warn_pll_lock_lost + 1'b1;
|
||||
|
||||
if ((H_LINEMULT == `LINEMULT_TRIPLE) & ~H_L3MODE[1] & ~pclk_3x_lock)
|
||||
warn_pll_lock_lost_3x <= 1;
|
||||
else if (warn_pll_lock_lost_3x != 0)
|
||||
warn_pll_lock_lost_3x <= warn_pll_lock_lost_3x + 1'b1;
|
||||
|
||||
if ((H_LINEMULT == `LINEMULT_TRIPLE) & H_L3MODE[1] & ~pclk_3x_lowfreq_lock)
|
||||
warn_pll_lock_lost_3x_lowfreq <= 1;
|
||||
else if (warn_pll_lock_lost_3x_lowfreq != 0)
|
||||
warn_pll_lock_lost_3x_lowfreq <= warn_pll_lock_lost_3x_lowfreq + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
assign h_unstable = (warn_h_unstable != 0);
|
||||
assign pll_lock_lost = {(warn_pll_lock_lost != 0), (warn_pll_lock_lost_3x != 0), (warn_pll_lock_lost_3x_lowfreq != 0)};
|
||||
|
||||
//Buffer the inputs using input pixel clock and generate 1x signals
|
||||
always @(posedge pclk_1x /*or negedge reset_n*/)
|
||||
begin
|
||||
/*if (!reset_n)
|
||||
begin
|
||||
end
|
||||
else*/
|
||||
begin
|
||||
if (`HSYNC_TRAILING_EDGE)
|
||||
begin
|
||||
hcnt_1x <= 0;
|
||||
hmax[line_idx] <= hcnt_1x;
|
||||
line_idx <= line_idx ^ 1'b1;
|
||||
vcnt_1x <= vcnt_1x + 1'b1;
|
||||
vcnt_1x_tvp <= vcnt_1x_tvp + 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
hcnt_1x <= hcnt_1x + 1'b1;
|
||||
end
|
||||
|
||||
if (`VSYNC_TRAILING_EDGE) //should be checked at every pclk_1x?
|
||||
begin
|
||||
vcnt_1x_tvp <= 0;
|
||||
FID_prev <= FID_in;
|
||||
|
||||
// detect non-interlaced signal with odd-odd field signaling (TVP7002 detects it as interlaced with analog sync inputs).
|
||||
// FID is updated at leading edge of VSYNC, so trailing edge has the status of current field.
|
||||
if (FID_in == FID_prev)
|
||||
fpga_vsyncgen[`VSYNCGEN_CHOPMID_BIT] <= `FALSE;
|
||||
else if (FID_in == `FID_ODD) // TVP7002 falsely indicates field change with (vcnt < active_lines)
|
||||
fpga_vsyncgen[`VSYNCGEN_CHOPMID_BIT] <= (vcnt_1x_tvp < `MIN_VALID_LINES);
|
||||
|
||||
if (!(`FALSE_FIELD))
|
||||
begin
|
||||
vcnt_1x <= 0;
|
||||
lines_1x <= vcnt_1x;
|
||||
end
|
||||
|
||||
//Read configuration data from CPU
|
||||
H_ACTIVE <= h_info[26:16]; // Horizontal active length from by the CPU - 11bits (0...2047)
|
||||
H_BACKPORCH <= h_info[7:0]; // Horizontal backporch length from by the CPU - 8bits (0...255)
|
||||
H_LINEMULT <= h_info[31:30]; // Horizontal line multiply mode
|
||||
H_L3MODE <= h_info[29:28]; // Horizontal line triple mode
|
||||
H_MASK <= {h_info[11:8], 2'b00};
|
||||
V_ACTIVE <= v_info[23:13]; // Vertical active length from by the CPU, 11bits (0...2047)
|
||||
V_BACKPORCH <= v_info[5:0]; // Vertical backporch length from by the CPU, 6bits (0...64)
|
||||
V_SCANLINES <= v_info[29];
|
||||
V_SCANLINEDIR <= v_info[28];
|
||||
V_SCANLINEID <= v_info[27];
|
||||
V_SCANLINESTR <= ((v_info[26:24]+8'h01)<<5)-1'b1;
|
||||
V_MASK <= {v_info[9:6], 2'b00};
|
||||
end
|
||||
|
||||
prev_hs <= HSYNC_in;
|
||||
prev_vs <= VSYNC_in;
|
||||
|
||||
// record start position of HSYNC
|
||||
if (`HSYNC_LEADING_EDGE)
|
||||
HSYNC_start <= hcnt_1x;
|
||||
|
||||
R_1x <= R_in;
|
||||
G_1x <= G_in;
|
||||
B_1x <= B_in;
|
||||
HSYNC_1x <= HSYNC_in;
|
||||
|
||||
// Ignore possible invalid vsyncs generated by TVP7002
|
||||
if (vcnt_1x > V_ACTIVE)
|
||||
VSYNC_1x <= VSYNC_in;
|
||||
|
||||
// Check if extra vsync needed
|
||||
fpga_vsyncgen[`VSYNCGEN_GENMID_BIT] <= (lines_1x > ({1'b0, V_ACTIVE} << 1)) ? 1'b1 : 1'b0;
|
||||
|
||||
h_enable_1x <= ((hcnt_1x >= H_BACKPORCH) & (hcnt_1x < H_BACKPORCH + H_ACTIVE));
|
||||
v_enable_1x <= ((vcnt_1x >= V_BACKPORCH) & (vcnt_1x < V_BACKPORCH + V_ACTIVE)); //- FID_in ???
|
||||
|
||||
/*HSYNC_out_debug <= HSYNC_in;
|
||||
VSYNC_out_debug <= VSYNC_in;*/
|
||||
end
|
||||
end
|
||||
|
||||
//Generate 2x signals for linedouble
|
||||
always @(posedge pclk_2x /*or negedge reset_n*/)
|
||||
begin
|
||||
/*if (!reset_n)
|
||||
begin
|
||||
end
|
||||
else*/
|
||||
begin
|
||||
if ((pclk_1x == 1'b0) & `HSYNC_TRAILING_EDGE) //sync with posedge of pclk_1x
|
||||
hcnt_2x <= 0;
|
||||
else if (hcnt_2x == hmax[~line_idx]) //line_idx_prev?
|
||||
hcnt_2x <= 0;
|
||||
else
|
||||
hcnt_2x <= hcnt_2x + 1'b1;
|
||||
|
||||
if (hcnt_2x == 0)
|
||||
vcnt_2x <= vcnt_2x + 1'b1;
|
||||
|
||||
if ((pclk_1x == 1'b0) & (fpga_vsyncgen[`VSYNCGEN_GENMID_BIT] == 1'b1))
|
||||
begin
|
||||
if (`VSYNC_TRAILING_EDGE)
|
||||
vcnt_2x <= 0;
|
||||
else if (vcnt_2x == lines_1x)
|
||||
begin
|
||||
vcnt_2x <= 0;
|
||||
lines_2x <= vcnt_2x;
|
||||
end
|
||||
end
|
||||
else if ((pclk_1x == 1'b0) & `VSYNC_TRAILING_EDGE & !(`FALSE_FIELD)) //sync with posedge of pclk_1x
|
||||
begin
|
||||
vcnt_2x <= 0;
|
||||
lines_2x <= vcnt_2x;
|
||||
end
|
||||
|
||||
if (pclk_1x == 1'b0)
|
||||
begin
|
||||
if (fpga_vsyncgen[`VSYNCGEN_GENMID_BIT] == 1'b1)
|
||||
VSYNC_2x <= (vcnt_2x >= lines_1x - `VSYNCGEN_LEN) ? 1'b0 : 1'b1;
|
||||
else if (vcnt_1x > V_ACTIVE)
|
||||
VSYNC_2x <= VSYNC_in;
|
||||
end
|
||||
|
||||
HSYNC_2x <= ~(hcnt_2x >= HSYNC_start);
|
||||
//TODO: VSYNC_2x
|
||||
h_enable_2x <= ((hcnt_2x >= H_BACKPORCH) & (hcnt_2x < H_BACKPORCH + H_ACTIVE));
|
||||
v_enable_2x <= ((vcnt_2x >= (V_BACKPORCH<<1)) & (vcnt_2x < ((V_BACKPORCH + V_ACTIVE)<<1)));
|
||||
end
|
||||
end
|
||||
|
||||
//Generate 3x signals for linetriple M0
|
||||
always @(posedge pclk_3x /*or negedge reset_n*/)
|
||||
begin
|
||||
/*if (!reset_n)
|
||||
begin
|
||||
end
|
||||
else*/
|
||||
begin
|
||||
if ((pclk_3x_cnt == 0) & `HSYNC_TRAILING_EDGE) //sync with posedge of pclk_1x
|
||||
hcnt_3x <= 0;
|
||||
else if (hcnt_3x == hmax[~line_idx]) //line_idx_prev?
|
||||
hcnt_3x <= 0;
|
||||
else
|
||||
hcnt_3x <= hcnt_3x + 1'b1;
|
||||
|
||||
if (hcnt_3x == 0)
|
||||
vcnt_3x <= vcnt_3x + 1'b1;
|
||||
|
||||
if ((pclk_3x_cnt == 0) & `VSYNC_TRAILING_EDGE & !(`FALSE_FIELD)) //sync with posedge of pclk_1x
|
||||
begin
|
||||
vcnt_3x <= 0;
|
||||
lines_3x <= vcnt_3x;
|
||||
end
|
||||
|
||||
HSYNC_3x <= ~(hcnt_3x >= HSYNC_start);
|
||||
//TODO: VSYNC_3x
|
||||
h_enable_3x <= ((hcnt_3x >= H_BACKPORCH) & (hcnt_3x < H_BACKPORCH + H_ACTIVE));
|
||||
v_enable_3x <= ((vcnt_3x >= (3*V_BACKPORCH)) & (vcnt_3x < (3*(V_BACKPORCH + V_ACTIVE)))); //multiplier generated!!!
|
||||
|
||||
//read pclk_1x to examine when edges are synced (pclk_1x=1 @ 120deg & pclk_1x=0 @ 240deg)
|
||||
if (((pclk_1x_prev3x == 1'b1) & (pclk_1x == 1'b0)) | (pclk_3x_cnt == 2'h2))
|
||||
pclk_3x_cnt <= 0;
|
||||
else
|
||||
pclk_3x_cnt <= pclk_3x_cnt + 1'b1;
|
||||
|
||||
pclk_1x_prev3x <= pclk_1x;
|
||||
end
|
||||
end
|
||||
|
||||
//Generate 4x signals for linetriple M1
|
||||
always @(posedge pclk_4x /*or negedge reset_n*/)
|
||||
begin
|
||||
/*if (!reset_n)
|
||||
begin
|
||||
end
|
||||
else*/
|
||||
begin
|
||||
// Can we sync reliably to h_enable_3x???
|
||||
if ((h_enable_3x == 1) & (h_enable_3x_prev4x == 0))
|
||||
hcnt_4x <= hcnt_3x - 160;
|
||||
else
|
||||
hcnt_4x <= hcnt_4x + 1'b1;
|
||||
|
||||
h_enable_3x_prev4x <= h_enable_3x;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
//Generate 3x_h1x signals for linetriple M2 and M3
|
||||
always @(posedge pclk_3x_h1x /*or negedge reset_n*/)
|
||||
begin
|
||||
/*if (!reset_n)
|
||||
begin
|
||||
end
|
||||
else*/
|
||||
begin
|
||||
if ((pclk_3x_h1x_cnt == 0) & `HSYNC_TRAILING_EDGE) //sync with posedge of pclk_1x
|
||||
hcnt_3x_h1x <= 0;
|
||||
else if (hcnt_3x_h1x == hmax[~line_idx]) //line_idx_prev?
|
||||
hcnt_3x_h1x <= 0;
|
||||
else
|
||||
hcnt_3x_h1x <= hcnt_3x_h1x + 1'b1;
|
||||
|
||||
if (hcnt_3x_h1x == 0)
|
||||
vcnt_3x_h1x <= vcnt_3x_h1x + 1'b1;
|
||||
|
||||
if ((pclk_3x_h1x_cnt == 0) & `VSYNC_TRAILING_EDGE & !(`FALSE_FIELD)) //sync with posedge of pclk_1x
|
||||
begin
|
||||
vcnt_3x_h1x <= 0;
|
||||
lines_3x_h1x <= vcnt_3x_h1x;
|
||||
end
|
||||
|
||||
HSYNC_3x_h1x <= ~(hcnt_3x_h1x >= HSYNC_start);
|
||||
//TODO: VSYNC_3x_h1x
|
||||
h_enable_3x_h1x <= ((hcnt_3x_h1x >= H_BACKPORCH) & (hcnt_3x_h1x < H_BACKPORCH + H_ACTIVE));
|
||||
v_enable_3x_h1x <= ((vcnt_3x_h1x >= (3*V_BACKPORCH)) & (vcnt_3x_h1x < (3*(V_BACKPORCH + V_ACTIVE)))); //multiplier generated!!!
|
||||
|
||||
//read pclk_1x to examine when edges are synced (pclk_1x=1 @ 120deg & pclk_1x=0 @ 240deg)
|
||||
if (((pclk_1x_prev3x_h1x == 1'b1) & (pclk_1x == 1'b0)) | (pclk_3x_h1x_cnt == 2'h2))
|
||||
pclk_3x_h1x_cnt <= 0;
|
||||
else
|
||||
pclk_3x_h1x_cnt <= pclk_3x_h1x_cnt + 1'b1;
|
||||
|
||||
pclk_1x_prev3x_h1x <= pclk_1x;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
//Generate 3x_h4x signals for for linetriple M2
|
||||
always @(posedge pclk_3x_h4x /*or negedge reset_n*/)
|
||||
begin
|
||||
/*if (!reset_n)
|
||||
begin
|
||||
end
|
||||
else*/
|
||||
begin
|
||||
// Can we sync reliably to h_enable_3x???
|
||||
if ((h_enable_3x_h1x == 1) & (h_enable_3x_prev3x_h4x == 0))
|
||||
hcnt_3x_h4x <= hcnt_3x_h1x - (160/3);
|
||||
else if (hcnt_3x_h4x_ctr == 2'h0)
|
||||
hcnt_3x_h4x <= hcnt_3x_h4x + 1'b1;
|
||||
|
||||
if ((h_enable_3x_h1x == 1) & (h_enable_3x_prev3x_h4x == 0))
|
||||
hcnt_3x_h4x_ctr <= 2'h1;
|
||||
else if (hcnt_3x_h4x_ctr == 2'h2)
|
||||
hcnt_3x_h4x_ctr <= 2'h0;
|
||||
else
|
||||
hcnt_3x_h4x_ctr <= hcnt_3x_h4x_ctr + 1'b1;
|
||||
|
||||
h_enable_3x_prev3x_h4x <= h_enable_3x_h1x;
|
||||
end
|
||||
end
|
||||
|
||||
//Generate 3x_h5x signals for for linetriple M3
|
||||
always @(posedge pclk_3x_h5x /*or negedge reset_n*/)
|
||||
begin
|
||||
/*if (!reset_n)
|
||||
begin
|
||||
end
|
||||
else*/
|
||||
begin
|
||||
// Can we sync reliably to h_enable_3x???
|
||||
if ((h_enable_3x_h1x == 1) & (h_enable_3x_prev3x_h5x == 0))
|
||||
hcnt_3x_h5x <= hcnt_3x_h1x - (128/4);
|
||||
else if (hcnt_3x_h5x_ctr == 2'h0)
|
||||
hcnt_3x_h5x <= hcnt_3x_h5x + 1'b1;
|
||||
|
||||
if ((h_enable_3x_h1x == 1) & (h_enable_3x_prev3x_h5x == 0))
|
||||
hcnt_3x_h5x_ctr <= 2'h2;
|
||||
else
|
||||
hcnt_3x_h5x_ctr <= hcnt_3x_h5x_ctr + 1'b1;
|
||||
|
||||
h_enable_3x_prev3x_h5x <= h_enable_3x_h1x;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,2 @@
|
|||
`timescale 1ns / 10ps
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
//
|
||||
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
module videogen (
|
||||
input clk27,
|
||||
input reset_n,
|
||||
output [7:0] R_out,
|
||||
output [7:0] G_out,
|
||||
output [7:0] B_out,
|
||||
output reg HSYNC_out,
|
||||
output reg VSYNC_out,
|
||||
output PCLK_out,
|
||||
output reg ENABLE_out
|
||||
);
|
||||
|
||||
//Parameters for 720x480@60Hz (858dots x 525lines), dotclk 27MHz -> 59.94Hz
|
||||
parameter H_SYNCLEN = 62;
|
||||
parameter H_BACKPORCH = 60;
|
||||
parameter H_ACTIVE = 720;
|
||||
parameter H_FRONTPORCH = 16;
|
||||
parameter H_TOTAL = 858;
|
||||
|
||||
parameter V_SYNCLEN = 6;
|
||||
parameter V_BACKPORCH = 30;
|
||||
parameter V_ACTIVE = 480;
|
||||
parameter V_FRONTPORCH = 9;
|
||||
parameter V_TOTAL = 525;
|
||||
|
||||
parameter H_OVERSCAN = 40; //at both sides
|
||||
parameter V_OVERSCAN = 16; //top and bottom
|
||||
parameter H_AREA = 640;
|
||||
parameter V_AREA = 448;
|
||||
parameter H_BORDER = (H_AREA-512)/2;
|
||||
parameter V_BORDER = (V_AREA-256)/2;
|
||||
|
||||
parameter X_START = H_SYNCLEN + H_BACKPORCH;
|
||||
parameter Y_START = V_SYNCLEN + V_BACKPORCH;
|
||||
|
||||
//Counters
|
||||
reg [9:0] h_cnt; //max. 1024
|
||||
reg [9:0] v_cnt; //max. 1024
|
||||
|
||||
reg [9:0] xpos;
|
||||
reg [9:0] ypos;
|
||||
|
||||
assign PCLK_out = clk27;
|
||||
|
||||
//R, G and B should be 0 outside of active area
|
||||
assign R_out = ENABLE_out ? V_gen : 8'h00;
|
||||
assign G_out = ENABLE_out ? V_gen : 8'h00;
|
||||
assign B_out = ENABLE_out ? V_gen : 8'h00;
|
||||
|
||||
reg [7:0] V_gen;
|
||||
|
||||
|
||||
//HSYNC gen (negative polarity)
|
||||
always @(posedge clk27 or negedge reset_n)
|
||||
begin
|
||||
if (!reset_n)
|
||||
begin
|
||||
h_cnt <= 0;
|
||||
HSYNC_out <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
//Hsync counter
|
||||
if (h_cnt < H_TOTAL-1 )
|
||||
h_cnt <= h_cnt + 1;
|
||||
else
|
||||
h_cnt <= 0;
|
||||
|
||||
//Hsync signal
|
||||
HSYNC_out <= (h_cnt < H_SYNCLEN) ? 0 : 1;
|
||||
end
|
||||
end
|
||||
|
||||
//VSYNC gen (negative polarity)
|
||||
always @(posedge clk27 or negedge reset_n)
|
||||
begin
|
||||
if (!reset_n)
|
||||
begin
|
||||
v_cnt <= 0;
|
||||
VSYNC_out <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (h_cnt == 0)
|
||||
begin
|
||||
//Vsync counter
|
||||
if (v_cnt < V_TOTAL-1 )
|
||||
v_cnt <= v_cnt + 1;
|
||||
else
|
||||
v_cnt <= 0;
|
||||
|
||||
//Vsync signal
|
||||
VSYNC_out <= (v_cnt < V_SYNCLEN) ? 0 : 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//Data gen
|
||||
always @(posedge clk27 or negedge reset_n)
|
||||
begin
|
||||
if (!reset_n)
|
||||
begin
|
||||
V_gen <= 8'h00;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if ((h_cnt < X_START+H_OVERSCAN) || (h_cnt >= X_START+H_OVERSCAN+H_AREA) || (v_cnt < Y_START+V_OVERSCAN) || (v_cnt >= Y_START+V_OVERSCAN+V_AREA))
|
||||
V_gen <= (h_cnt[0] ^ v_cnt[0]) ? 8'hff : 8'h00;
|
||||
else if ((h_cnt < X_START+H_OVERSCAN+H_BORDER) || (h_cnt >= X_START+H_OVERSCAN+H_AREA-H_BORDER) || (v_cnt < Y_START+V_OVERSCAN+V_BORDER) || (v_cnt >= Y_START+V_OVERSCAN+V_AREA-V_BORDER))
|
||||
V_gen <= 8'h50;
|
||||
else
|
||||
V_gen <= (h_cnt - (X_START+H_OVERSCAN+H_BORDER)) >> 1;
|
||||
/*else
|
||||
V_gen <= 8'h00;*/
|
||||
end
|
||||
end
|
||||
|
||||
//Enable gen
|
||||
always @(posedge clk27 or negedge reset_n)
|
||||
begin
|
||||
if (!reset_n)
|
||||
begin
|
||||
ENABLE_out <= 8'h00;
|
||||
end
|
||||
else
|
||||
begin
|
||||
ENABLE_out <= (h_cnt >= X_START && h_cnt < X_START + H_ACTIVE && v_cnt >= Y_START && v_cnt < Y_START + V_ACTIVE);
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,196 @@
|
|||
#include "hdmitx.h"
|
||||
#include "edid.h"
|
||||
|
||||
#ifdef SUPPORT_EDID
|
||||
static SYS_STATUS EDIDCheckSum(BYTE *pEDID) ;
|
||||
|
||||
static SYS_STATUS
|
||||
EDIDCheckSum(BYTE *pEDID)
|
||||
{
|
||||
BYTE CheckSum ;
|
||||
int i ;
|
||||
|
||||
if( !pEDID )
|
||||
{
|
||||
return ER_FAIL ;
|
||||
}
|
||||
for( i = 0, CheckSum = 0 ; i < 128 ; i++ )
|
||||
{
|
||||
CheckSum += pEDID[i] ; CheckSum &= 0xFF ;
|
||||
}
|
||||
|
||||
return (CheckSum == 0)?ER_SUCCESS:ER_FAIL ;
|
||||
}
|
||||
|
||||
SYS_STATUS
|
||||
ParseVESAEDID(BYTE *pEDID)
|
||||
{
|
||||
if( ER_SUCCESS != EDIDCheckSum(pEDID) ) return ER_FAIL ;
|
||||
|
||||
if( pEDID[0] != 0 ||
|
||||
pEDID[7] != 0 ||
|
||||
pEDID[1] != 0xFF ||
|
||||
pEDID[2] != 0xFF ||
|
||||
pEDID[3] != 0xFF ||
|
||||
pEDID[4] != 0xFF ||
|
||||
pEDID[5] != 0xFF ||
|
||||
pEDID[6] != 0xFF )
|
||||
{
|
||||
return ER_FAIL ; // not a EDID 1.3 standard block.
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
// if need to parse EDID property , put here.
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
return ER_SUCCESS ;
|
||||
|
||||
}
|
||||
|
||||
SYS_STATUS
|
||||
ParseCEAEDID(BYTE *pCEAEDID, RX_CAP *pRxCap)
|
||||
{
|
||||
BYTE offset,End ;
|
||||
BYTE count ;
|
||||
BYTE tag ;
|
||||
int i ;
|
||||
|
||||
if( !pCEAEDID || !pRxCap ) return ER_FAIL ;
|
||||
|
||||
pRxCap->ValidCEA = FALSE ;
|
||||
|
||||
if( ER_SUCCESS != EDIDCheckSum(pCEAEDID) ) return ER_FAIL ;
|
||||
|
||||
if( pCEAEDID[0] != 0x02 || pCEAEDID[1] != 0x03 ) return ER_SUCCESS ; // not a CEA BLOCK.
|
||||
End = pCEAEDID[2] ; // CEA description.
|
||||
pRxCap->VideoMode = pCEAEDID[3] ;
|
||||
|
||||
if (pRxCap->VideoMode & CEA_SUPPORT_YUV444)
|
||||
OS_PRINTF("Support Color: YUV444\n");
|
||||
if (pRxCap->VideoMode & CEA_SUPPORT_YUV422)
|
||||
OS_PRINTF("Support Color: YUV422\n");
|
||||
|
||||
for( offset = 0 ; offset < 0x80 ; offset ++ )
|
||||
{
|
||||
if( (offset % 0x10) == 0 )
|
||||
{
|
||||
ErrorF("[%02X]", offset ) ;
|
||||
}
|
||||
else if((offset%0x10)==0x08)
|
||||
{
|
||||
ErrorF( " -" ) ;
|
||||
}
|
||||
ErrorF(" %02X",pCEAEDID[offset]) ;
|
||||
if((offset%0x10)==0x0f)
|
||||
{
|
||||
ErrorF("\n") ;
|
||||
}
|
||||
}
|
||||
|
||||
pRxCap->VDOModeCount = 0 ;
|
||||
pRxCap->idxNativeVDOMode = 0xff ;
|
||||
for( offset = 4 ; offset < End ; )
|
||||
{
|
||||
tag = pCEAEDID[offset] >> 5 ;
|
||||
count = pCEAEDID[offset] & 0x1f ;
|
||||
switch( tag )
|
||||
{
|
||||
case 0x01: // Audio Data Block ;
|
||||
pRxCap->AUDDesCount = count/3 ;
|
||||
offset++ ;
|
||||
for( i = 0 ; i < pRxCap->AUDDesCount ; i++ )
|
||||
{
|
||||
pRxCap->AUDDes[i].uc[0] = pCEAEDID[offset++] ;
|
||||
pRxCap->AUDDes[i].uc[1] = pCEAEDID[offset++] ;
|
||||
pRxCap->AUDDes[i].uc[2] = pCEAEDID[offset++] ;
|
||||
|
||||
}
|
||||
|
||||
break ;
|
||||
|
||||
case 0x02: // Video Data Block ;
|
||||
//pRxCap->VDOModeCount = 0 ;
|
||||
offset ++ ;
|
||||
for( i = 0,pRxCap->idxNativeVDOMode = 0xff ; i < count ; i++, offset++ )
|
||||
{
|
||||
BYTE VIC ;
|
||||
VIC = pCEAEDID[offset] & (~0x80) ;
|
||||
OS_PRINTF("HDMI Sink VIC(Video Identify Code)=%d\n", VIC);
|
||||
// if( FindModeTableEntryByVIC(VIC) != -1 )
|
||||
{
|
||||
pRxCap->VDOMode[pRxCap->VDOModeCount] = VIC ;
|
||||
if( pCEAEDID[offset] & 0x80 )
|
||||
{
|
||||
pRxCap->idxNativeVDOMode = (BYTE)pRxCap->VDOModeCount ;
|
||||
// iVideoModeSelect = pRxCap->VDOModeCount ;
|
||||
}
|
||||
|
||||
pRxCap->VDOModeCount++ ;
|
||||
}
|
||||
}
|
||||
break ;
|
||||
case 0x03: // Vendor Specific Data Block ;
|
||||
offset ++ ;
|
||||
pRxCap->IEEEOUI = (ULONG)pCEAEDID[offset+2] ;
|
||||
pRxCap->IEEEOUI <<= 8 ;
|
||||
pRxCap->IEEEOUI += (ULONG)pCEAEDID[offset+1] ;
|
||||
pRxCap->IEEEOUI <<= 8 ;
|
||||
pRxCap->IEEEOUI += (ULONG)pCEAEDID[offset] ;
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// For HDMI 1.3 extension handling.
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
pRxCap->dc.uc = 0 ;
|
||||
pRxCap->MaxTMDSClock = 0 ;
|
||||
pRxCap->lsupport.uc = 0 ;
|
||||
pRxCap->ValidHDMI = (pRxCap->IEEEOUI==HDMI_IEEEOUI)? TRUE:FALSE ;
|
||||
if( (pRxCap->ValidHDMI) && (count > 5 ))
|
||||
{
|
||||
// HDMI 1.3 extension
|
||||
pRxCap->dc.uc = pCEAEDID[offset+5] ;
|
||||
pRxCap->MaxTMDSClock = pCEAEDID[offset+6] ;
|
||||
pRxCap->lsupport.uc = pCEAEDID[offset+7] ;
|
||||
|
||||
if(pRxCap->lsupport.info.Latency_Present)
|
||||
{
|
||||
pRxCap->V_Latency = pCEAEDID[offset+9] ;
|
||||
pRxCap->A_Latency = pCEAEDID[offset+10] ;
|
||||
}
|
||||
|
||||
if(pRxCap->lsupport.info.I_Latency_Present)
|
||||
{
|
||||
pRxCap->V_I_Latency = pCEAEDID[offset+11] ;
|
||||
pRxCap->A_I_Latency = pCEAEDID[offset+12] ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
offset += count ; // ignore the remaind.
|
||||
break ;
|
||||
|
||||
case 0x04: // Speaker Data Block ;
|
||||
offset ++ ;
|
||||
pRxCap->SpeakerAllocBlk.uc[0] = pCEAEDID[offset] ;
|
||||
pRxCap->SpeakerAllocBlk.uc[1] = pCEAEDID[offset+1] ;
|
||||
pRxCap->SpeakerAllocBlk.uc[2] = pCEAEDID[offset+2] ;
|
||||
offset += 3 ;
|
||||
break ;
|
||||
case 0x05: // VESA Data Block ;
|
||||
offset += count+1 ;
|
||||
break ;
|
||||
case 0x07: // Extended Data Block ;
|
||||
offset += count+1 ; //ignore
|
||||
break ;
|
||||
default:
|
||||
offset += count+1 ; // ignore
|
||||
}
|
||||
}
|
||||
|
||||
pRxCap->ValidCEA = TRUE ;
|
||||
return ER_SUCCESS ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // SUPPORT_EDID
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef HDMI_COMMON_H_
|
||||
#define HDMI_COMMON_H_
|
||||
|
||||
typedef enum{
|
||||
COLOR_RGB444 = 0,
|
||||
COLOR_YUV422,
|
||||
COLOR_YUV444,
|
||||
COLOR_MODE_NUM
|
||||
}COLOR_TYPE;
|
||||
|
||||
#endif /*HDMI_COMMON_H_*/
|
|
@ -0,0 +1,314 @@
|
|||
//#include "terasic_includes.h"
|
||||
//#include "mcu.h"
|
||||
#include "it6613_sys.h"
|
||||
#include "hdmitx.h"
|
||||
#include "HDMI_TX.h"
|
||||
#include "edid.h"
|
||||
|
||||
|
||||
int TX_HDP = FALSE;
|
||||
extern BYTE bOutputColorMode;
|
||||
extern BYTE bInputColorMode;
|
||||
extern BOOL bChangeMode;
|
||||
extern RX_CAP RxCapability;
|
||||
extern BOOL bHDMIMode;
|
||||
extern BOOL bAudioEnable;
|
||||
BOOL ParseEDID();
|
||||
|
||||
INSTANCE InitInstanceData =
|
||||
{
|
||||
0,0, //I2C_DEV, I2C_ADDR
|
||||
0, //bIntType (TxCLK active, Push-Pull Mode, INT active low)
|
||||
0,/* | T_MODE_CCIR656 | T_MODE_SYNCEMB | T_MODE_INDDR */ // bInputVideoSignalType
|
||||
|
||||
B_AUDFMT_STD_I2S, // bOutputAudioMode, 0x00, standard i2s, rising edge to sample ws/i2s, not full packet mode REG[0xE1]
|
||||
|
||||
0,// bAudioChannelSwap
|
||||
B_AUD_EN_I2S0 | B_AUD_I2S | M_AUD_16BIT, // bAudioChannelEnable, 0x01, REG[0xE0], defined in it6613_drv.h
|
||||
AUDFS_48KHz, //0, //bAudFs,
|
||||
0, // TMDSClock
|
||||
TRUE,//bAuthenticated
|
||||
TRUE,// bHDMIMode
|
||||
FALSE,// bIntPOL
|
||||
FALSE // bHPD
|
||||
} ;
|
||||
|
||||
bool HDMITX_ChipVerify(void){
|
||||
bool bPass = FALSE;
|
||||
alt_u8 szID[4];
|
||||
int i;
|
||||
|
||||
|
||||
for(i=0;i<4;i++)
|
||||
szID[i] = HDMITX_ReadI2C_Byte(i);
|
||||
|
||||
// if (szID[0] == 0x00 && szID[1] == 0xCA && szID[1] == 0x13 && szID[1] == 0x06) szID[0] ???
|
||||
if ((szID[1] == 0xCA && szID[2] == 0x13 && szID[3] == 0x06) || (szID[1] == 0xCA && szID[2] == 0x13 && szID[3] == 0x16)){
|
||||
bPass = TRUE;
|
||||
printf("TX Chip Revision ID: %d\n", szID[0]);
|
||||
}else{
|
||||
printf("NG, Read TX Chip ID:%02X%02X%02X%02Xh (expected:00CA1306h)\n", szID[0], szID[1], szID[2], szID[3]);
|
||||
}
|
||||
|
||||
return bPass;
|
||||
}
|
||||
|
||||
bool HDMITX_Init(void){
|
||||
bool bSuccess = TRUE;
|
||||
HDMITX_Reset();
|
||||
usleep(500*1000);
|
||||
if (!HDMITX_ChipVerify()){
|
||||
OS_PRINTF("Failed to find IT6613 HDMI-TX Chip.\n");
|
||||
bSuccess = FALSE;
|
||||
//return 0;
|
||||
}
|
||||
|
||||
HDMITX_InitInstance(&InitInstanceData) ;
|
||||
InitIT6613() ;
|
||||
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
bool HDMITX_HPD(void){
|
||||
if (TX_HDP)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void HDMITX_SetAVIInfoFrame(alt_u8 VIC, alt_u8 OutputColorMode, bool b16x9, bool ITU709)
|
||||
{
|
||||
AVI_InfoFrame AviInfo;
|
||||
alt_u8 pixelrep = 0;
|
||||
|
||||
OS_PRINTF("HDMITX_SetAVIInfoFrame, VIC=%d, ColorMode=%d, Aspect-Ratio=%s, ITU709=%s\n",
|
||||
VIC, OutputColorMode, b16x9?"16:9":"4:3", ITU709?"Yes":"No");
|
||||
|
||||
AviInfo.pktbyte.AVI_HB[0] = AVI_INFOFRAME_TYPE|0x80 ;
|
||||
AviInfo.pktbyte.AVI_HB[1] = AVI_INFOFRAME_VER ;
|
||||
AviInfo.pktbyte.AVI_HB[2] = AVI_INFOFRAME_LEN ;
|
||||
|
||||
switch(OutputColorMode)
|
||||
{
|
||||
case F_MODE_YUV444:
|
||||
// AviInfo.info.ColorMode = 2 ;
|
||||
AviInfo.pktbyte.AVI_DB[0] = (2<<5)|(1<<4) ;
|
||||
break ;
|
||||
case F_MODE_YUV422:
|
||||
// AviInfo.info.ColorMode = 1 ;
|
||||
AviInfo.pktbyte.AVI_DB[0] = (1<<5)|(1<<4) ;
|
||||
break ;
|
||||
case F_MODE_RGB444:
|
||||
default:
|
||||
// AviInfo.info.ColorMode = 0 ;
|
||||
AviInfo.pktbyte.AVI_DB[0] = (0<<5)|(1<<4) ;
|
||||
break ;
|
||||
}
|
||||
AviInfo.pktbyte.AVI_DB[0] |= 2; // indicate "no overscan"
|
||||
AviInfo.pktbyte.AVI_DB[1] = 8 ;
|
||||
AviInfo.pktbyte.AVI_DB[1] |= (!b16x9)?(1<<4):(2<<4) ; // 4:3 or 16:9
|
||||
AviInfo.pktbyte.AVI_DB[1] |= (!ITU709)?(1<<6):(2<<6) ; // ITU709 or ITU601
|
||||
AviInfo.pktbyte.AVI_DB[2] = (1<<3) ; // indicate "full-range RGB"
|
||||
AviInfo.pktbyte.AVI_DB[3] = VIC ;
|
||||
AviInfo.pktbyte.AVI_DB[4] = pixelrep & 3 ;
|
||||
AviInfo.pktbyte.AVI_DB[5] = 0 ;
|
||||
AviInfo.pktbyte.AVI_DB[6] = 0 ;
|
||||
AviInfo.pktbyte.AVI_DB[7] = 0 ;
|
||||
AviInfo.pktbyte.AVI_DB[8] = 0 ;
|
||||
AviInfo.pktbyte.AVI_DB[9] = 0 ;
|
||||
AviInfo.pktbyte.AVI_DB[10] = 0 ;
|
||||
AviInfo.pktbyte.AVI_DB[11] = 0 ;
|
||||
AviInfo.pktbyte.AVI_DB[12] = 0 ;
|
||||
|
||||
EnableAVIInfoFrame(TRUE, (unsigned char *)&AviInfo) ;
|
||||
}
|
||||
|
||||
void HDMITX_ChangeVideoTiming(int VIC){
|
||||
int OutputVideoTiming = VIC;
|
||||
int HdmiColorMode;
|
||||
|
||||
switch(bOutputColorMode)
|
||||
{
|
||||
case F_MODE_YUV444:
|
||||
HdmiColorMode = HDMI_YUV444;
|
||||
break ;
|
||||
case F_MODE_YUV422:
|
||||
HdmiColorMode = HDMI_YUV422;
|
||||
break ;
|
||||
case F_MODE_RGB444:
|
||||
default:
|
||||
HdmiColorMode = HDMI_RGB444;
|
||||
break ;
|
||||
}
|
||||
|
||||
HDMITX_ChangeDisplayOption(OutputVideoTiming, HdmiColorMode); // just modify variable. Take effect when HDMITX_SetOutput is called in HDMITX_DevLoopProc
|
||||
}
|
||||
|
||||
void HDMITX_ChangeVideoTimingAndColor(int VIC, COLOR_TYPE Color){
|
||||
int OutputVideoTiming = VIC;
|
||||
int HdmiColorMode;
|
||||
|
||||
switch(Color)
|
||||
{
|
||||
case COLOR_YUV444:
|
||||
HdmiColorMode = HDMI_YUV444;
|
||||
break ;
|
||||
case COLOR_YUV422:
|
||||
HdmiColorMode = HDMI_YUV422;
|
||||
break ;
|
||||
case COLOR_RGB444:
|
||||
default:
|
||||
HdmiColorMode = HDMI_RGB444;
|
||||
break ;
|
||||
}
|
||||
HDMITX_ChangeDisplayOption(OutputVideoTiming, HdmiColorMode);
|
||||
}
|
||||
|
||||
void HDMITX_DisableVideoOutput(void){
|
||||
DisableVideoOutput();
|
||||
}
|
||||
|
||||
void HDMITX_EnableVideoOutput(void){
|
||||
HDMITX_SetOutput();
|
||||
}
|
||||
|
||||
void HDMITX_SetColorSpace(COLOR_TYPE InputColor, COLOR_TYPE OutputColor){
|
||||
// DisableVideoOutput();
|
||||
bInputColorMode = InputColor;
|
||||
bOutputColorMode = OutputColor;
|
||||
// HDMITX_SetOutput();
|
||||
}
|
||||
|
||||
bool HDMITX_IsSinkSupportYUV444(void){
|
||||
bool bSupport = FALSE;
|
||||
if (RxCapability.Valid && RxCapability.ValidHDMI && RxCapability.ValidCEA &&
|
||||
(RxCapability.VideoMode & CEA_SUPPORT_YUV444))
|
||||
bSupport = TRUE;
|
||||
return bSupport;
|
||||
}
|
||||
|
||||
bool HDMITX_IsSinkSupportYUV422(void){
|
||||
bool bSupport = FALSE;
|
||||
if (RxCapability.Valid && RxCapability.ValidHDMI && RxCapability.ValidCEA &&
|
||||
(RxCapability.VideoMode & CEA_SUPPORT_YUV422))
|
||||
bSupport = TRUE;
|
||||
return bSupport;
|
||||
}
|
||||
|
||||
bool HDMITX_IsSinkSupportColorDepth36(void){
|
||||
bool bSupport = FALSE;
|
||||
if (RxCapability.Valid && RxCapability.ValidHDMI && RxCapability.ValidCEA &&
|
||||
RxCapability.dc.info.DC_36Bit)
|
||||
bSupport = TRUE;
|
||||
return bSupport;
|
||||
}
|
||||
|
||||
|
||||
bool HDMITX_IsSinkSupportColorDepth30(void){
|
||||
bool bSupport = FALSE;
|
||||
if (RxCapability.Valid && RxCapability.ValidHDMI && RxCapability.ValidCEA &&
|
||||
RxCapability.dc.info.DC_30Bit)
|
||||
bSupport = TRUE;
|
||||
return bSupport;
|
||||
}
|
||||
|
||||
void HDMITX_SetOutputColorDepth(int ColorDepth){
|
||||
SetOutputColorDepthPhase(ColorDepth, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool HDMITX_DevLoopProc()
|
||||
{
|
||||
static BYTE PreHPDChange = 0;
|
||||
static BYTE PreHPD = 0;
|
||||
BYTE HPD, HPDChange ;
|
||||
|
||||
// Richard CheckHDMI(&HPD,&HPDChange) ;
|
||||
CheckHDMITX(&HPD,&HPDChange) ;
|
||||
|
||||
if (HPD == PreHPD && HPDChange) // richard add
|
||||
return FALSE;
|
||||
|
||||
TX_HDP = HPD;
|
||||
PreHPD = HPD;
|
||||
PreHPDChange = HPDChange;
|
||||
|
||||
if( HPDChange )
|
||||
{
|
||||
|
||||
|
||||
OS_PRINTF("HPDChange\n");
|
||||
if( HPD )
|
||||
{
|
||||
OS_PRINTF("HPD=ON\n");
|
||||
RxCapability.Valid = ParseEDID() ;
|
||||
//bOutputColorMode = F_MODE_YUV444; //F_MODE_RGB444; // richard node. users can change color space here according to HDMI sink
|
||||
|
||||
if( RxCapability.Valid && RxCapability.ValidHDMI )
|
||||
{
|
||||
OS_PRINTF("HDMI Display found\n");
|
||||
bHDMIMode = TRUE ;
|
||||
|
||||
if(RxCapability.VideoMode & (1<<6))
|
||||
{
|
||||
bAudioEnable = TRUE ;
|
||||
}
|
||||
|
||||
#if 0 // richard, don't care edid, the output always RGB444
|
||||
if( RxCapability.VideoMode & (1<<5))
|
||||
{
|
||||
bOutputColorMode &= ~F_MODE_CLRMOD_MASK ;
|
||||
bOutputColorMode |= F_MODE_YUV444;
|
||||
}
|
||||
else if (RxCapability.VideoMode & (1<<4))
|
||||
{
|
||||
bOutputColorMode &= ~F_MODE_CLRMOD_MASK ;
|
||||
bOutputColorMode |= F_MODE_YUV422 ;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (!RxCapability.Valid)
|
||||
{
|
||||
OS_PRINTF("Failed to read EDID\n");
|
||||
|
||||
// enable it when edid fail
|
||||
bHDMIMode = TRUE ;
|
||||
bAudioEnable = TRUE ;
|
||||
}
|
||||
else
|
||||
{
|
||||
OS_PRINTF("Invalid HDMI Display\n");
|
||||
bHDMIMode = FALSE ;
|
||||
bAudioEnable = FALSE ;
|
||||
}
|
||||
|
||||
OS_PRINTF("HDMITX_SetOutput\n");
|
||||
//HDMITX_SetOutput() ;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
OS_PRINTF("HPD=OFF\n");
|
||||
// unplug mode, ...
|
||||
OS_PRINTF("DisableVideoOutput\n");
|
||||
//DisableVideoOutput() ;
|
||||
RxCapability.Valid = FALSE; // richard add
|
||||
RxCapability.ValidHDMI = FALSE; // richard add
|
||||
RxCapability.ValidCEA = FALSE; // richard add
|
||||
}
|
||||
}
|
||||
else // no stable but need to process mode change procedure
|
||||
{
|
||||
if(bChangeMode && HPD)
|
||||
{
|
||||
OS_PRINTF("HDMITX_SetOutput\n");
|
||||
HDMITX_SetOutput() ;
|
||||
}
|
||||
}
|
||||
|
||||
return HPDChange;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef HDMI_TX_H_
|
||||
#define HDMI_TX_H_
|
||||
|
||||
#include "HDMI_COMMON.h"
|
||||
#include "alt_types.h"
|
||||
#include "hdmitx.h"
|
||||
|
||||
|
||||
|
||||
bool HDMITX_Init(void);
|
||||
bool HDMITX_ChipVerify(void);
|
||||
bool HDMITX_HPD(void);
|
||||
void HDMITX_ChangeVideoTiming(int VIC);
|
||||
void HDMITX_ChangeVideoTimingAndColor(int VIC, COLOR_TYPE Color);
|
||||
void HDMITX_SetAVIInfoFrame(alt_u8 VIC, alt_u8 OutputColorMode, bool b16x9, bool ITU709);
|
||||
|
||||
void HDMITX_DisableVideoOutput(void);
|
||||
void HDMITX_EnableVideoOutput(void);
|
||||
void HDMITX_SetColorSpace(COLOR_TYPE InputColor, COLOR_TYPE OutputColor);
|
||||
bool HDMITX_DevLoopProc(void);
|
||||
|
||||
bool HDMITX_IsSinkSupportYUV444(void);
|
||||
bool HDMITX_IsSinkSupportYUV422(void);
|
||||
|
||||
bool HDMITX_IsSinkSupportColorDepth36(void);
|
||||
bool HDMITX_IsSinkSupportColorDepth30(void);
|
||||
void HDMITX_SetOutputColorDepth(int ColorDepth);
|
||||
|
||||
#endif /*HDMI_TX_H_*/
|
|
@ -0,0 +1,129 @@
|
|||
#ifndef _EDID_H_
|
||||
#define _EDID_H_
|
||||
|
||||
#include "hdmitx.h"
|
||||
|
||||
#ifdef SUPPORT_EDID
|
||||
|
||||
/////////////////////////////////////////
|
||||
// RX Capability.
|
||||
/////////////////////////////////////////
|
||||
typedef struct {
|
||||
BYTE b16bit:1 ;
|
||||
BYTE b20bit:1 ;
|
||||
BYTE b24bit:1 ;
|
||||
BYTE Rsrv:5 ;
|
||||
} LPCM_BitWidth ;
|
||||
|
||||
typedef enum {
|
||||
AUD_RESERVED_0 = 0 ,
|
||||
AUD_LPCM,
|
||||
AUD_AC3,
|
||||
AUD_MPEG1,
|
||||
AUD_MP3,
|
||||
AUD_MPEG2,
|
||||
AUD_AAC,
|
||||
AUD_DTS,
|
||||
AUD_ATRAC,
|
||||
AUD_ONE_BIT_AUDIO,
|
||||
AUD_DOLBY_DIGITAL_PLUS,
|
||||
AUD_DTS_HD,
|
||||
AUD_MAT_MLP,
|
||||
AUD_DST,
|
||||
AUD_WMA_PRO,
|
||||
AUD_RESERVED_15
|
||||
} AUDIO_FORMAT_CODE ;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
BYTE channel:3 ;
|
||||
BYTE AudioFormatCode:4 ;
|
||||
BYTE Rsrv1:1 ;
|
||||
|
||||
BYTE b32KHz:1 ;
|
||||
BYTE b44_1KHz:1 ;
|
||||
BYTE b48KHz:1 ;
|
||||
BYTE b88_2KHz:1 ;
|
||||
BYTE b96KHz:1 ;
|
||||
BYTE b176_4KHz:1 ;
|
||||
BYTE b192KHz:1 ;
|
||||
BYTE Rsrv2:1 ;
|
||||
BYTE ucCode ;
|
||||
} s ;
|
||||
BYTE uc[3] ;
|
||||
|
||||
} AUDDESCRIPTOR ;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
BYTE FL_FR:1 ;
|
||||
BYTE LFE:1 ;
|
||||
BYTE FC:1 ;
|
||||
BYTE RL_RR:1 ;
|
||||
BYTE RC:1 ;
|
||||
BYTE FLC_FRC:1 ;
|
||||
BYTE RLC_RRC:1 ;
|
||||
BYTE Reserve:1 ;
|
||||
BYTE Unuse[2] ;
|
||||
} s ;
|
||||
BYTE uc[3] ;
|
||||
} SPK_ALLOC ;
|
||||
|
||||
#define CEA_SUPPORT_UNDERSCAN (1<<7)
|
||||
#define CEA_SUPPORT_AUDIO (1<<6)
|
||||
#define CEA_SUPPORT_YUV444 (1<<5)
|
||||
#define CEA_SUPPORT_YUV422 (1<<4)
|
||||
#define CEA_NATIVE_MASK 0xF
|
||||
|
||||
typedef union _tag_DCSUPPORT {
|
||||
struct {
|
||||
BYTE DVI_Dual:1 ;
|
||||
BYTE Rsvd:2 ;
|
||||
BYTE DC_Y444:1 ;
|
||||
BYTE DC_30Bit:1 ;
|
||||
BYTE DC_36Bit:1 ;
|
||||
BYTE DC_48Bit:1 ;
|
||||
BYTE SUPPORT_AI:1 ;
|
||||
} info ;
|
||||
BYTE uc ;
|
||||
} DCSUPPORT ; // Richard Note: Color Depth
|
||||
|
||||
typedef union _LATENCY_SUPPORT{
|
||||
struct {
|
||||
BYTE Rsvd:6 ;
|
||||
BYTE I_Latency_Present:1 ;
|
||||
BYTE Latency_Present:1 ;
|
||||
} info ;
|
||||
BYTE uc ;
|
||||
} LATENCY_SUPPORT ;
|
||||
|
||||
#define HDMI_IEEEOUI 0x0c03
|
||||
|
||||
typedef struct _RX_CAP{
|
||||
BYTE Valid; // richard add
|
||||
BYTE VideoMode ;
|
||||
BYTE VDOModeCount ;
|
||||
BYTE idxNativeVDOMode ;
|
||||
BYTE VDOMode[128] ;
|
||||
BYTE AUDDesCount ;
|
||||
AUDDESCRIPTOR AUDDes[32] ;
|
||||
ULONG IEEEOUI ;
|
||||
DCSUPPORT dc ;
|
||||
BYTE MaxTMDSClock ;
|
||||
LATENCY_SUPPORT lsupport ;
|
||||
BYTE V_Latency ;
|
||||
BYTE A_Latency ;
|
||||
BYTE V_I_Latency ;
|
||||
BYTE A_I_Latency ;
|
||||
SPK_ALLOC SpeakerAllocBlk ;
|
||||
BYTE ValidCEA:1 ;
|
||||
BYTE ValidHDMI:1 ;
|
||||
} RX_CAP ;
|
||||
|
||||
SYS_STATUS ParseVESAEDID(BYTE *pEDID) ;
|
||||
SYS_STATUS ParseCEAEDID(BYTE *pCEAEDID, RX_CAP *pRxCap) ;
|
||||
|
||||
|
||||
|
||||
#endif // SUPPORT_EDID
|
||||
#endif // _EDID_H_
|
|
@ -0,0 +1,119 @@
|
|||
#ifndef _HDMITX_H_
|
||||
#define _HDMITX_H_
|
||||
|
||||
#ifdef EXTERN_HDCPROM
|
||||
#pragma message("Defined EXTERN_HDCPROM")
|
||||
#endif // EXTERN_HDCPROM
|
||||
|
||||
#define SUPPORT_EDID
|
||||
//#define SUPPORT_HDCP
|
||||
#define SUPPORT_INPUTRGB
|
||||
//#define SUPPORT_INPUTYUV444
|
||||
//#define SUPPORT_INPUTYUV422
|
||||
//#define SUPPORT_SYNCEMBEDDED
|
||||
//#define SUPPORT_DEGEN
|
||||
//#define SUPPORT_INPUTYUV // richard add
|
||||
//#define INVERT_VID_LATCHEDGE //latch at falling edge
|
||||
|
||||
|
||||
#ifdef SUPPORT_SYNCEMBEDDED
|
||||
#pragma message("defined SUPPORT_SYNCEMBEDDED for Sync Embedded timing input or CCIR656 input.")
|
||||
#endif
|
||||
|
||||
#ifndef _MCU_ // DSSSHA need large computation data rather than 8051 supported.
|
||||
#define SUPPORT_DSSSHA
|
||||
#endif
|
||||
|
||||
#if defined(SUPPORT_INPUTYUV444) || defined(SUPPORT_INPUTYUV422)
|
||||
#define SUPPORT_INPUTYUV
|
||||
#endif
|
||||
|
||||
/*#ifdef _MCU_
|
||||
#include "mcu.h"
|
||||
#else // not MCU
|
||||
#include <windows.h>
|
||||
#include <winioctl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include "ioaccess.h"
|
||||
#include "install.h"
|
||||
#include "pc.h"
|
||||
#endif // MCU*/
|
||||
|
||||
#include "typedef.h"
|
||||
#include "HDMI_COMMON.h"
|
||||
/*typedef unsigned char BYTE;
|
||||
#define _CODE const
|
||||
#define SYS_STATUS unsigned int
|
||||
#define TRUE 1
|
||||
#define FALSE 0*/
|
||||
//#define NULL 0
|
||||
|
||||
//typedef unsigned char bool;
|
||||
#include "Altera_UP_SD_Card_Avalon_Interface_mod.h"
|
||||
#include "sysconfig.h"
|
||||
|
||||
// Hardwired to CPU reset
|
||||
#define HDMITX_Reset(x)
|
||||
|
||||
#ifndef SUPPORT_HDCP
|
||||
static SYS_STATUS
|
||||
HDCP_Authenticate()
|
||||
{
|
||||
return ER_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
HDCP_ResetAuth()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
HDCP_ResumeAuthentication()
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
//#include "edid.h"
|
||||
// #include "dss_sha.h"
|
||||
#include "it6613_drv.h"
|
||||
|
||||
#define HDMITX_INSTANCE_MAX 1
|
||||
|
||||
#define SIZEOF_CSCMTX 18
|
||||
#define SIZEOF_CSCGAIN 6
|
||||
#define SIZEOF_CSCOFFSET 3
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Output Mode Type
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define RES_ASPEC_4x3 0
|
||||
#define RES_ASPEC_16x9 1
|
||||
#define F_MODE_REPT_NO 0
|
||||
#define F_MODE_REPT_TWICE 1
|
||||
#define F_MODE_REPT_QUATRO 3
|
||||
#define F_MODE_CSC_ITU601 0
|
||||
#define F_MODE_CSC_ITU709 1
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// ROM OFFSET
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
#define ROMOFF_INT_TYPE 0
|
||||
#define ROMOFF_INPUT_VIDEO_TYPE 1
|
||||
#define ROMOFF_OUTPUT_AUDIO_MODE 8
|
||||
#define ROMOFF_AUDIO_CH_SWAP 9
|
||||
|
||||
|
||||
|
||||
#define TIMER_LOOP_LEN 10
|
||||
#define MS(x) (((x)+(TIMER_LOOP_LEN-1))/TIMER_LOOP_LEN) ; // for timer loop
|
||||
|
||||
|
||||
|
||||
#endif // _HDMITX_H_
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "system.h"
|
||||
#include "i2c_opencores.h"
|
||||
#include "hdmitx.h"
|
||||
#include "it6613.h"
|
||||
|
||||
inline alt_u32 read_it2(alt_u32 regaddr) {
|
||||
I2C_start(I2CA_BASE, IT_BASE, 0);
|
||||
I2C_write(I2CA_BASE, regaddr, 0);
|
||||
I2C_start(I2CA_BASE, IT_BASE, 1);
|
||||
return I2C_read(I2CA_BASE,1);
|
||||
}
|
||||
|
||||
inline void write_it2(alt_u32 regaddr, alt_u8 data) {
|
||||
I2C_start(I2CA_BASE, IT_BASE, 0);
|
||||
I2C_write(I2CA_BASE, regaddr, 0);
|
||||
I2C_write(I2CA_BASE, data, 1);
|
||||
}
|
||||
|
||||
BYTE I2C_Read_Byte(BYTE Addr,BYTE RegAddr) {
|
||||
I2C_start(I2CA_BASE, Addr, 0);
|
||||
I2C_write(I2CA_BASE, RegAddr, 0);
|
||||
I2C_start(I2CA_BASE, Addr, 1);
|
||||
return I2C_read(I2CA_BASE,1);
|
||||
}
|
||||
|
||||
SYS_STATUS I2C_Write_Byte(BYTE Addr,BYTE RegAddr,BYTE Data) {
|
||||
I2C_start(I2CA_BASE, Addr, 0);
|
||||
I2C_write(I2CA_BASE, RegAddr, 0);
|
||||
I2C_write(I2CA_BASE, Data, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_STATUS I2C_Read_ByteN(BYTE Addr,BYTE RegAddr,BYTE *pData,int N) {
|
||||
int i;
|
||||
|
||||
for (i=0; i<N; i++)
|
||||
pData[i] = I2C_Read_Byte(Addr, RegAddr+i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_STATUS I2C_Write_ByteN(BYTE Addr,BYTE RegAddr,BYTE *pData,int N) {
|
||||
int i;
|
||||
|
||||
for (i=0; i<N; i++)
|
||||
I2C_Write_Byte(Addr, RegAddr+i, pData[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BYTE HDMITX_ReadI2C_Byte(BYTE RegAddr) {
|
||||
return read_it2(RegAddr);
|
||||
}
|
||||
|
||||
SYS_STATUS HDMITX_WriteI2C_Byte(BYTE RegAddr,BYTE val) {
|
||||
write_it2(RegAddr, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_STATUS HDMITX_ReadI2C_ByteN(BYTE RegAddr,BYTE *pData,int N) {
|
||||
int i;
|
||||
|
||||
for (i=0; i<N; i++)
|
||||
pData[i] = HDMITX_ReadI2C_Byte(RegAddr+i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_STATUS HDMITX_WriteI2C_ByteN(BYTE RegAddr,BYTE *pData,int N) {
|
||||
int i;
|
||||
|
||||
for (i=0; i<N; i++)
|
||||
HDMITX_WriteI2C_Byte(RegAddr+i, pData[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DelayMS(unsigned int ms) {
|
||||
usleep(1000*ms);
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "system.h"
|
||||
#include "i2c_opencores.h"
|
||||
#include "it6613.h"
|
||||
|
||||
volatile alt_u8 cur_bank;
|
||||
|
||||
inline void select_bank_it(alt_u8 bank) {
|
||||
cur_bank = bank;
|
||||
I2C_start(I2CA_BASE, IT_BASE, 0);
|
||||
I2C_write(I2CA_BASE, IT_CURBANK, 0);
|
||||
I2C_write(I2CA_BASE, cur_bank, 1);
|
||||
}
|
||||
|
||||
inline alt_u32 read_it(alt_u32 regaddr) {
|
||||
if ((regaddr > 0xFF) && (cur_bank == 0))
|
||||
select_bank_it(1);
|
||||
else if ((regaddr <= 0xFF) && (cur_bank == 1))
|
||||
select_bank_it(0);
|
||||
|
||||
I2C_start(I2CA_BASE, IT_BASE, 0);
|
||||
I2C_write(I2CA_BASE, (regaddr & 0xFF), 1);
|
||||
I2C_start(I2CA_BASE, IT_BASE, 1);
|
||||
return I2C_read(I2CA_BASE,1);
|
||||
}
|
||||
|
||||
inline void write_it(alt_u32 regaddr, alt_u8 data) {
|
||||
if ((regaddr > 0xFF) && (cur_bank == 0))
|
||||
select_bank_it(1);
|
||||
else if ((regaddr <= 0xFF) && (cur_bank == 1))
|
||||
select_bank_it(0);
|
||||
|
||||
I2C_start(I2CA_BASE, IT_BASE, 0);
|
||||
I2C_write(I2CA_BASE, (regaddr & 0xFF), 0);
|
||||
I2C_write(I2CA_BASE, data, 1);
|
||||
}
|
||||
|
||||
/*inline void reset_it() {
|
||||
usleep(100000);
|
||||
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, 0x00);
|
||||
usleep(100000);
|
||||
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, 0x01);
|
||||
usleep(100000);
|
||||
}*/
|
||||
|
||||
int init_it() {
|
||||
alt_u32 vendor_id, device_id;
|
||||
alt_u32 i;
|
||||
|
||||
cur_bank = 0;
|
||||
select_bank_it(cur_bank);
|
||||
|
||||
vendor_id = read_it(IT_VENDORID);
|
||||
device_id = read_it(IT_DEVICEID);
|
||||
|
||||
printf("VEN: 0x%.2X, DEV: 0x%.2X\n", vendor_id, device_id);
|
||||
|
||||
if (!((vendor_id == IT6613_VENDORID) && (device_id == IT6613_DEVICEID)))
|
||||
return -1;
|
||||
|
||||
write_it(REG_TX_SW_RST,B_REF_RST|B_VID_RST|B_AUD_RST|B_AREF_RST|B_HDCP_RST) ;
|
||||
usleep(1000);
|
||||
write_it(REG_TX_SW_RST,B_VID_RST|B_AUD_RST|B_AREF_RST|B_HDCP_RST) ;
|
||||
|
||||
write_it(IT_DRIVECTRL, 0x10);
|
||||
|
||||
write_it(IT_HDMIMODE, 0);
|
||||
for (i=0xC1; i<=0xD0; i++)
|
||||
write_it(i, 0);
|
||||
|
||||
write_it(IT_OUTCOLOR, 0);
|
||||
|
||||
// enable video
|
||||
//HDMITX_WriteI2C_Byte(REG_TX_SW_RST,B_VID_RST|B_AUD_RST|B_AREF_RST|B_HDCP_RST) ;
|
||||
|
||||
write_it(REG_TX_SW_RST, B_AUD_RST|B_AREF_RST|B_HDCP_RST) ;
|
||||
usleep(1000);
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef IT6613_H_
|
||||
#define IT6613_H_
|
||||
|
||||
//#define I2C_DEBUG
|
||||
//#define I2CA_HDMI_BASE I2C_OPENCORES_1_BASE
|
||||
#define I2CA_BASE I2C_OPENCORES_0_BASE
|
||||
|
||||
#define IT6613_VENDORID 0xCA
|
||||
#define IT6613_DEVICEID 0x13
|
||||
|
||||
#define IT_BASE (0x98>>1)
|
||||
#define IT_VENDORID 0x01
|
||||
#define IT_DEVICEID 0x02
|
||||
#define IT_RESET 0x04
|
||||
#define IT_CURBANK 0x0F
|
||||
#define IT_DRIVECTRL 0x61
|
||||
#define IT_HDMIMODE 0xC0
|
||||
#define IT_OUTCOLOR 0x158
|
||||
|
||||
#define REG_TX_SW_RST 0x04
|
||||
#define B_ENTEST (1<<7)
|
||||
#define B_REF_RST (1<<5)
|
||||
#define B_AREF_RST (1<<4)
|
||||
#define B_VID_RST (1<<3)
|
||||
#define B_AUD_RST (1<<2)
|
||||
#define B_HDMI_RST (1<<1)
|
||||
#define B_HDCP_RST (1<<0)
|
||||
|
||||
#endif /* IT6613_H_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,844 @@
|
|||
#ifndef _IT6613_H_
|
||||
#define _IT6613_H_
|
||||
|
||||
//#define EXTERN_HDCPROM
|
||||
/////////////////////////////////////////
|
||||
// DDC Address
|
||||
/////////////////////////////////////////
|
||||
#define DDC_HDCP_ADDRESS 0x74
|
||||
#define DDC_EDID_ADDRESS 0xA0
|
||||
#define DDC_FIFO_MAXREQ 0x20
|
||||
|
||||
// I2C address
|
||||
|
||||
#define _80MHz 80000000
|
||||
#define HDMI_TX_I2C_SLAVE_ADDR 0x98 // PCADR is ground, if PCADR=1, address=0x9A
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Register offset
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#define REG_TX_VENDOR_ID0 0x00
|
||||
#define REG_TX_VENDOR_ID1 0x01
|
||||
#define REG_TX_DEVICE_ID0 0x02
|
||||
#define REG_TX_DEVICE_ID1 0x03
|
||||
|
||||
#define O_DEVID 0
|
||||
#define M_DEVID 0xF
|
||||
#define O_REVID 4
|
||||
#define M_REVID 0xF
|
||||
|
||||
#define REG_TX_SW_RST 0x04
|
||||
#define B_ENTEST (1<<7)
|
||||
#define B_REF_RST (1<<5)
|
||||
#define B_AREF_RST (1<<4)
|
||||
#define B_VID_RST (1<<3)
|
||||
#define B_AUD_RST (1<<2)
|
||||
#define B_HDMI_RST (1<<1)
|
||||
#define B_HDCP_RST (1<<0)
|
||||
|
||||
#define REG_TX_INT_CTRL 0x05
|
||||
#define B_INTPOL_ACTL 0
|
||||
#define B_INTPOL_ACTH (1<<7)
|
||||
#define B_INT_PUSHPULL 0
|
||||
#define B_INT_OPENDRAIN (1<<6)
|
||||
|
||||
#define REG_TX_INT_STAT1 0x06
|
||||
#define B_INT_AUD_OVERFLOW (1<<7)
|
||||
#define B_INT_ROMACQ_NOACK (1<<6)
|
||||
#define B_INT_RDDC_NOACK (1<<5)
|
||||
#define B_INT_DDCFIFO_ERR (1<<4)
|
||||
#define B_INT_ROMACQ_BUS_HANG (1<<3)
|
||||
#define B_INT_DDC_BUS_HANG (1<<2)
|
||||
#define B_INT_RX_SENSE (1<<1)
|
||||
#define B_INT_HPD_PLUG (1<<0)
|
||||
|
||||
#define REG_TX_INT_STAT2 0x07
|
||||
#define B_INT_HDCP_SYNC_DET_FAIL (1<<7)
|
||||
#define B_INT_VID_UNSTABLE (1<<6)
|
||||
#define B_INT_PKTACP (1<<5)
|
||||
#define B_INT_PKTNULL (1<<4)
|
||||
#define B_INT_PKTGENERAL (1<<3)
|
||||
#define B_INT_KSVLIST_CHK (1<<2)
|
||||
#define B_INT_AUTH_DONE (1<<1)
|
||||
#define B_INT_AUTH_FAIL (1<<0)
|
||||
|
||||
#define REG_TX_INT_STAT3 0x08
|
||||
#define B_INT_AUD_CTS (1<<6)
|
||||
#define B_INT_VSYNC (1<<5)
|
||||
#define B_INT_VIDSTABLE (1<<4)
|
||||
#define B_INT_PKTMPG (1<<3)
|
||||
#define B_INT_PKTSPD (1<<2)
|
||||
#define B_INT_PKTAUD (1<<1)
|
||||
#define B_INT_PKTAVI (1<<0)
|
||||
|
||||
#define REG_TX_INT_MASK1 0x09
|
||||
#define B_AUDIO_OVFLW_MASK (1<<7)
|
||||
#define B_DDC_NOACK_MASK (1<<5)
|
||||
#define B_DDC_FIFO_ERR_MASK (1<<4)
|
||||
#define B_DDC_BUS_HANG_MASK (1<<2)
|
||||
#define B_RXSEN_MASK (1<<1)
|
||||
#define B_HPD_MASK (1<<0)
|
||||
|
||||
#define REG_TX_INT_MASK2 0x0A
|
||||
#define B_PKT_AVI_MASK (1<<7)
|
||||
#define B_PKT_VID_UNSTABLE_MASK (1<<6)
|
||||
#define B_PKT_ACP_MASK (1<<5)
|
||||
#define B_PKT_NULL_MASK (1<<4)
|
||||
#define B_PKT_GEN_MASK (1<<3)
|
||||
#define B_KSVLISTCHK_MASK (1<<2)
|
||||
#define B_T_AUTH_DONE_MASK (1<<1)
|
||||
#define B_AUTH_FAIL_MASK (1<<0)
|
||||
|
||||
#define REG_TX_INT_MASK3 0x0B
|
||||
#define B_HDCP_SYNC_DET_FAIL_MASK (1<<6)
|
||||
#define B_AUDCTS_MASK (1<<5)
|
||||
#define B_VSYNC_MASK (1<<4)
|
||||
#define B_VIDSTABLE_MASK (1<<3)
|
||||
#define B_PKT_MPG_MASK (1<<2)
|
||||
#define B_PKT_SPD_MASK (1<<1)
|
||||
#define B_PKT_AUD_MASK (1<<0)
|
||||
|
||||
|
||||
#define REG_TX_INT_CLR0 0x0C
|
||||
#define B_CLR_PKTACP (1<<7)
|
||||
#define B_CLR_PKTNULL (1<<6)
|
||||
#define B_CLR_PKTGENERAL (1<<5)
|
||||
#define B_CLR_KSVLISTCHK (1<<4)
|
||||
#define B_CLR_AUTH_DONE (1<<3)
|
||||
#define B_CLR_AUTH_FAIL (1<<2)
|
||||
#define B_CLR_RXSENSE (1<<1)
|
||||
#define B_CLR_HPD (1<<0)
|
||||
|
||||
#define REG_TX_INT_CLR1 0x0D
|
||||
#define B_CLR_VSYNC (1<<7)
|
||||
#define B_CLR_VIDSTABLE (1<<6)
|
||||
#define B_CLR_PKTMPG (1<<5)
|
||||
#define B_CLR_PKTSPD (1<<4)
|
||||
#define B_CLR_PKTAUD (1<<3)
|
||||
#define B_CLR_PKTAVI (1<<2)
|
||||
#define B_CLR_HDCP_SYNC_DET_FAIL (1<<1)
|
||||
#define B_CLR_VID_UNSTABLE (1<<0)
|
||||
|
||||
#define REG_TX_SYS_STATUS 0x0E
|
||||
// readonly
|
||||
#define B_INT_ACTIVE (1<<7)
|
||||
#define B_HPDETECT (1<<6)
|
||||
#define B_RXSENDETECT (1<<5)
|
||||
#define B_TXVIDSTABLE (1<<4)
|
||||
// read/write
|
||||
#define O_CTSINTSTEP 2
|
||||
#define M_CTSINTSTEP (3<<2)
|
||||
#define B_CLR_AUD_CTS (1<<1)
|
||||
#define B_INTACTDONE (1<<0)
|
||||
|
||||
#define REG_TX_BANK_CTRL 0x0F
|
||||
#define B_BANK0 0
|
||||
#define B_BANK1 1
|
||||
|
||||
// DDC
|
||||
|
||||
#define REG_TX_DDC_MASTER_CTRL 0x10
|
||||
#define B_MASTERROM (1<<1)
|
||||
#define B_MASTERDDC (0<<1)
|
||||
#define B_MASTERHOST (1<<0)
|
||||
#define B_MASTERHDCP (0<<0)
|
||||
|
||||
#define REG_TX_DDC_HEADER 0x11
|
||||
#define REG_TX_DDC_REQOFF 0x12
|
||||
#define REG_TX_DDC_REQCOUNT 0x13
|
||||
#define REG_TX_DDC_EDIDSEG 0x14
|
||||
#define REG_TX_DDC_CMD 0x15
|
||||
#define CMD_DDC_SEQ_BURSTREAD 0
|
||||
#define CMD_LINK_CHKREAD 2
|
||||
#define CMD_EDID_READ 3
|
||||
#define CMD_FIFO_CLR 9
|
||||
#define CMD_GEN_SCLCLK 0xA
|
||||
#define CMD_DDC_ABORT 0xF
|
||||
|
||||
#define REG_TX_DDC_STATUS 0x16
|
||||
#define B_DDC_DONE (1<<7)
|
||||
#define B_DDC_ACT (1<<6)
|
||||
#define B_DDC_NOACK (1<<5)
|
||||
#define B_DDC_WAITBUS (1<<4)
|
||||
#define B_DDC_ARBILOSE (1<<3)
|
||||
#define B_DDC_ERROR (B_DDC_NOACK|B_DDC_WAITBUS|B_DDC_ARBILOSE)
|
||||
#define B_DDC_FIFOFULL (1<<2)
|
||||
#define B_DDC_FIFOEMPTY (1<<1)
|
||||
|
||||
#define REG_TX_DDC_READFIFO 0x17
|
||||
#define REG_TX_ROM_STARTADDR 0x18
|
||||
#define REG_TX_HDCP_HEADER 0x19
|
||||
#define REG_TX_ROM_HEADER 0x1A
|
||||
#define REG_TX_BUSHOLD_T 0x1B
|
||||
#define REG_TX_ROM_STAT 0x1C
|
||||
#define B_ROM_DONE (1<<7)
|
||||
#define B_ROM_ACTIVE (1<<6)
|
||||
#define B_ROM_NOACK (1<<5)
|
||||
#define B_ROM_WAITBUS (1<<4)
|
||||
#define B_ROM_ARBILOSE (1<<3)
|
||||
#define B_ROM_BUSHANG (1<<2)
|
||||
|
||||
// HDCP
|
||||
#define REG_TX_AN_GENERATE 0x1F
|
||||
#define B_START_CIPHER_GEN 1
|
||||
#define B_STOP_CIPHER_GEN 0
|
||||
|
||||
#define REG_TX_HDCP_DESIRE 0x20
|
||||
#define B_ENABLE_HDPC11 (1<<1)
|
||||
#define B_CPDESIRE (1<<0)
|
||||
|
||||
#define REG_TX_AUTHFIRE 0x21
|
||||
#define REG_TX_LISTCTRL 0x22
|
||||
#define B_LISTFAIL (1<<1)
|
||||
#define B_LISTDONE (1<<0)
|
||||
|
||||
#define REG_TX_AKSV 0x23
|
||||
#define REG_TX_AKSV0 0x23
|
||||
#define REG_TX_AKSV1 0x24
|
||||
#define REG_TX_AKSV2 0x25
|
||||
#define REG_TX_AKSV3 0x26
|
||||
#define REG_TX_AKSV4 0x27
|
||||
|
||||
#define REG_TX_AN 0x28
|
||||
#define REG_TX_AN_GEN 0x30
|
||||
#define REG_TX_ARI 0x38
|
||||
#define REG_TX_ARI0 0x38
|
||||
#define REG_TX_ARI1 0x39
|
||||
#define REG_TX_APJ 0x3A
|
||||
|
||||
#define REG_TX_BKSV 0x3B
|
||||
#define REG_TX_BRI 0x40
|
||||
#define REG_TX_BRI0 0x40
|
||||
#define REG_TX_BRI1 0x41
|
||||
#define REG_TX_BPJ 0x42
|
||||
#define REG_TX_BCAP 0x43
|
||||
#define B_CAP_HDMI_REPEATER (1<<6)
|
||||
#define B_CAP_KSV_FIFO_RDY (1<<5)
|
||||
#define B_CAP_HDMI_FAST_MODE (1<<4)
|
||||
#define B_CAP_HDCP_1p1 (1<<1)
|
||||
#define B_CAP_FAST_REAUTH (1<<0)
|
||||
#define REG_TX_BSTAT 0x44
|
||||
#define REG_TX_BSTAT0 0x44
|
||||
#define REG_TX_BSTAT1 0x45
|
||||
#define B_CAP_HDMI_MODE (1<<12)
|
||||
#define B_CAP_DVI_MODE (0<<12)
|
||||
#define B_MAX_CASCADE_EXCEEDED (1<<11)
|
||||
#define M_REPEATER_DEPTH (0x7<<8)
|
||||
#define O_REPEATER_DEPTH 8
|
||||
#define B_DOWNSTREAM_OVER (1<<7)
|
||||
#define M_DOWNSTREAM_COUNT 0x7F
|
||||
|
||||
#define REG_TX_AUTH_STAT 0x46
|
||||
#define B_T_AUTH_DONE (1<<7)
|
||||
#define REG_TX_CLK_CTRL0 0x58
|
||||
#define O_OSCLK_SEL 5
|
||||
#define M_OSCLK_SEL 3
|
||||
#define B_AUTO_OVER_SAMPLING_CLOCK (1<<4)
|
||||
#define O_EXT_MCLK_SEL 2
|
||||
#define M_EXT_MCLK_SEL (3<<O_EXT_MCLK_SEL)
|
||||
#define B_EXT_128FS (0<<O_EXT_MCLK_SEL)
|
||||
#define B_EXT_256FS (1<<O_EXT_MCLK_SEL)
|
||||
#define B_EXT_512FS (2<<O_EXT_MCLK_SEL)
|
||||
#define B_EXT_1024FS (3<<O_EXT_MCLK_SEL)
|
||||
|
||||
#define REG_TX_SHA_SEL 0x50
|
||||
#define REG_TX_SHA_RD_BYTE1 0x51
|
||||
#define REG_TX_SHA_RD_BYTE2 0x52
|
||||
#define REG_TX_SHA_RD_BYTE3 0x53
|
||||
#define REG_TX_SHA_RD_BYTE4 0x54
|
||||
#define REG_TX_AKSV_RD_BYTE5 0x55
|
||||
|
||||
|
||||
#define REG_TX_CLK_CTRL1 0x59
|
||||
#define B_EN_TXCLK_COUNT (1<<5)
|
||||
#define B_VDO_LATCH_EDGE (1<<3)
|
||||
#define M_AUD_DIV 3
|
||||
#define B_AUD_NODIV 0
|
||||
#define B_AUD_DIV2 1
|
||||
#define B_AUD_DIV4 3
|
||||
#define B_AUD_NODEF 2
|
||||
#define REG_TX_CLK_STATUS1 0x5E
|
||||
#define REG_TX_CLK_STATUS2 0x5F
|
||||
#define B_IP_LOCK (1<<7)
|
||||
#define B_XP_LOCK (1<<6)
|
||||
#define B_OSF_LOCK (1<<5)
|
||||
|
||||
|
||||
#define REG_TX_AFE_DRV_CTRL 0x61
|
||||
|
||||
#define B_AFE_DRV_PWD (1<<5)
|
||||
#define B_AFE_DRV_RST (1<<4)
|
||||
#define B_AFE_DRV_PDRXDET (1<<2)
|
||||
#define B_AFE_DRV_TERMON (1<<1)
|
||||
#define B_AFE_DRV_ENCAL (1<<0)
|
||||
|
||||
#define REG_TX_AFE_XP_CTRL 0x62
|
||||
#define B_AFE_XP_GAINBIT (1<<7)
|
||||
#define B_AFE_XP_PWDPLL (1<<6)
|
||||
#define B_AFE_XP_ENI (1<<5)
|
||||
#define B_AFE_XP_ER0 (1<<4)
|
||||
#define B_AFE_XP_RESETB (1<<3)
|
||||
#define B_AFE_XP_PWDI (1<<2)
|
||||
#define B_AFE_XP_DEI (1<<1)
|
||||
#define B_AFE_XP_DER (1<<0)
|
||||
|
||||
#define REG_TX_AFE_ISW_CTRL 0x63
|
||||
#define B_AFE_RTERM_SEL (1<<7)
|
||||
#define B_AFE_IP_BYPASS (1<<6)
|
||||
#define M_AFE_DRV_ISW (7<<3)
|
||||
#define O_AFE_DRV_ISW 3
|
||||
#define B_AFE_DRV_ISWK 7
|
||||
|
||||
#define REG_TX_AFE_IP_CTRL 0x64
|
||||
|
||||
#define B_AFE_IP_GAINBIT (1<<7)
|
||||
#define B_AFE_IP_PWDPLL (1<<6)
|
||||
#define M_AFE_IP_CKSEL (3<<4)
|
||||
#define O_AFE_IP_CKSEL 4
|
||||
#define B_AFE_IP_ER0 (1<<3)
|
||||
#define B_AFE_IP_RESETB (1<<2)
|
||||
#define B_AFE_IP_ENC (1<<1)
|
||||
#define B_AFE_IP_EC1 (1<<0)
|
||||
|
||||
#define REG_TX_AFE_RING 0x65
|
||||
#define B_AFE_CAL_UPDATE (1<<7)
|
||||
#define B_AFE_CAL_MANUAL (1<<6)
|
||||
#define M_AFE_CAL_CLK_MODE (3<<4)
|
||||
#define O_AFE_CAL_CLK_MODE 4
|
||||
#define O_AFE_DRV_VSW 2
|
||||
#define M_AFE_DRV_VSW (3<<2)
|
||||
#define B_AFE_RING_SLOW (1<<1)
|
||||
#define B_AFE_RING_FAST (1<<0)
|
||||
#define REG_TX_AFE_TEST 0x66
|
||||
#define B_AFE_AFE_ENTEST (1<<6)
|
||||
#define B_AFE_AFE_ENBIST (1<<5)
|
||||
#define M_AFE_CAL_RTERM_MANUAL 0x1F
|
||||
#define REG_TX_AFE_LFSR 0x67
|
||||
#define B_AFE_AFELFSR_VAL (1<<7)
|
||||
#define B_AFE_DIS_AFELFSR (1<<6)
|
||||
#define M_AFE_RTERM_VAOUE 0xF
|
||||
|
||||
//
|
||||
//#define REG_TX_AFE_DRV_CTRL 0x61
|
||||
// #define M_AFE_DRV_SR (3<<2)
|
||||
// #define O_AFE_DRV_SR 2
|
||||
// #define B_AFE_DRV_RST (1<<4)
|
||||
// #define B_AFE_DRV_PWD (1<<5)
|
||||
// #define B_AFE_DRV_ENBIST (1<<6)
|
||||
//
|
||||
//#define REG_TX_AFE_XP_CTRL1 0x62
|
||||
// #define B_AFE_XP_GAINBIT (1<<7)
|
||||
// #define B_AFE_XP_PWDPLL (1<<6)
|
||||
// #define B_AFE_XP_ENI (1<<5)
|
||||
// #define B_AFE_XP_ER0 (1<<4)
|
||||
// #define B_AFE_XP_RESETB (1<<3)
|
||||
// #define B_AFE_XP_PWDI (1<<2)
|
||||
// #define B_AFE_XP_DEI (1<<1)
|
||||
// #define B_AFE_XP_BYPASS (1<<0)
|
||||
//
|
||||
//#define REG_TX_AFE_XP_CTRL2 0x63
|
||||
// #define B_XP_ENCLKX5 (1<<3)
|
||||
// #define M_XP_CLKSEL 3
|
||||
// #define B_XP_CLKSEL_HALF_PCLKHV 0
|
||||
// #define B_XP_CLKSEL_1_PCLKHV 1
|
||||
// #define B_XP_CLKSEL_2_PCLKHV 2
|
||||
// #define B_XP_CLKSEL_4_PCLKHV 3
|
||||
//
|
||||
//
|
||||
//#define REG_TX_AFE_IP_CTRL 0x64
|
||||
// #define B_AFE_IP_GAINBIT (1<<6)
|
||||
// #define B_AFE_IP_PWDPLL (1<<5)
|
||||
// #define B_AFE_IP_SEDB (1<<4)
|
||||
// #define B_AFE_IP_ER0 (1<<3)
|
||||
// #define B_AFE_IP_RESETB (1<<2)
|
||||
// #define B_AFE_IP_PDIV1 (1<<1)
|
||||
// #define B_AFE_IP_ENCB (1<<0)
|
||||
//
|
||||
//#define REG_TX_AFE_RING 0x65
|
||||
// #define B_AFE_RING_FAST (1<<0)
|
||||
// #define B_AFE_RING_SLOW (1<<1)
|
||||
// #define M_AFE_DRV_VSW (3<<2)
|
||||
// #define B_AFE_VSW_NOENH 0
|
||||
// #define B_AFE_VSW_12ENH (1<<2)
|
||||
// #define B_AFE_VSW_24ENH (2<<2)
|
||||
// #define B_AFE_VSW_35ENH (3<<2)
|
||||
|
||||
// Input Data Format Register
|
||||
#define REG_TX_INPUT_MODE 0x70
|
||||
#define O_INCLKDLY 0
|
||||
#define M_INCLKDLY 3
|
||||
#define B_INDDR (1<<2)
|
||||
#define B_SYNCEMB (1<<3)
|
||||
#define B_2X656CLK (1<<4)
|
||||
#define B_PCLKDIV2 (1<<5)
|
||||
#define M_INCOLMOD (3<<6)
|
||||
#define B_IN_RGB 0
|
||||
#define B_IN_YUV422 (1<<6)
|
||||
#define B_IN_YUV444 (2<<6)
|
||||
|
||||
#define REG_TX_TXFIFO_RST 0x71
|
||||
#define B_ENAVMUTERST 1
|
||||
#define B_TXFFRST (1<<1)
|
||||
|
||||
#define REG_TX_CSC_CTRL 0x72
|
||||
#define B_CSC_BYPASS 0
|
||||
#define B_CSC_RGB2YUV 2
|
||||
#define B_CSC_YUV2RGB 3
|
||||
#define M_CSC_SEL 3
|
||||
#define B_TX_EN_DITHER (1<<7)
|
||||
#define B_TX_EN_UDFILTER (1<<6)
|
||||
#define B_TX_DNFREE_GO (1<<5)
|
||||
|
||||
#define REG_TX_CSC_YOFF 0x73
|
||||
#define REG_TX_CSC_COFF 0x74
|
||||
#define REG_TX_CSC_RGBOFF 0x75
|
||||
|
||||
#define REG_TX_CSC_MTX11_L 0x76
|
||||
#define REG_TX_CSC_MTX11_H 0x77
|
||||
#define REG_TX_CSC_MTX12_L 0x78
|
||||
#define REG_TX_CSC_MTX12_H 0x79
|
||||
#define REG_TX_CSC_MTX13_L 0x7A
|
||||
#define REG_TX_CSC_MTX13_H 0x7B
|
||||
#define REG_TX_CSC_MTX21_L 0x7C
|
||||
#define REG_TX_CSC_MTX21_H 0x7D
|
||||
#define REG_TX_CSC_MTX22_L 0x7E
|
||||
#define REG_TX_CSC_MTX22_H 0x7F
|
||||
#define REG_TX_CSC_MTX23_L 0x80
|
||||
#define REG_TX_CSC_MTX23_H 0x81
|
||||
#define REG_TX_CSC_MTX31_L 0x82
|
||||
#define REG_TX_CSC_MTX31_H 0x83
|
||||
#define REG_TX_CSC_MTX32_L 0x84
|
||||
#define REG_TX_CSC_MTX32_H 0x85
|
||||
#define REG_TX_CSC_MTX33_L 0x86
|
||||
#define REG_TX_CSC_MTX33_H 0x87
|
||||
|
||||
#define REG_TX_CSC_GAIN1V_L 0x88
|
||||
#define REG_TX_CSC_GAIN1V_H 0x89
|
||||
#define REG_TX_CSC_GAIN2V_L 0x8A
|
||||
#define REG_TX_CSC_GAIN2V_H 0x8B
|
||||
#define REG_TX_CSC_GAIN3V_L 0x8C
|
||||
#define REG_TX_CSC_GAIN3V_H 0x8D
|
||||
|
||||
#define REG_TX_HVPol 0x90
|
||||
#define REG_TX_HfPixel 0x91
|
||||
#define REG_TX_HSSL 0x95
|
||||
#define REG_TX_HSEL 0x96
|
||||
#define REG_TX_HSH 0x97
|
||||
#define REG_TX_VSS1 0xA0
|
||||
#define REG_TX_VSE1 0xA1
|
||||
#define REG_TX_VSS2 0xA2
|
||||
#define REG_TX_VSE2 0xA3
|
||||
|
||||
// HDMI General Control Registers
|
||||
|
||||
#define REG_TX_HDMI_MODE 0xC0
|
||||
#define B_TX_HDMI_MODE 1
|
||||
#define B_TX_DVI_MODE 0
|
||||
#define REG_TX_AV_MUTE 0xC1
|
||||
#define REG_TX_GCP 0xC1
|
||||
#define B_CLR_AVMUTE 0
|
||||
#define B_SET_AVMUTE 1
|
||||
#define B_TX_SETAVMUTE (1<<0)
|
||||
#define B_BLUE_SCR_MUTE (1<<1)
|
||||
#define B_NODEF_PHASE (1<<2)
|
||||
#define B_PHASE_RESYNC (1<<3)
|
||||
|
||||
#define O_COLOR_DEPTH 4
|
||||
#define M_COLOR_DEPTH 7
|
||||
#define B_COLOR_DEPTH_MASK (M_COLOR_DEPTH<<O_COLOR_DEPTH)
|
||||
#define B_CD_NODEF 0
|
||||
#define B_CD_24 (4<<4)
|
||||
#define B_CD_30 (5<<4)
|
||||
#define B_CD_36 (6<<4)
|
||||
#define B_CD_48 (7<<4)
|
||||
|
||||
#define REG_TX_OESS_CYCLE 0xC3
|
||||
#define REG_TX_ENCRYPTION 0xC4
|
||||
#define B_DISABLE_ENCRYPTION 1
|
||||
#define B_ENABLE_ENCRYPTION 0
|
||||
#define REG_TX_PKT_SINGLE_CTRL 0xC5
|
||||
#define B_SINGLE_PKT 1
|
||||
#define B_BURST_PKT
|
||||
#define B_SW_CTS (1<<1)
|
||||
#define REG_TX_PKT_GENERAL_CTRL 0xC6
|
||||
|
||||
#define REG_TX_NULL_CTRL 0xC9
|
||||
#define REG_TX_ACP_CTRL 0xCA
|
||||
#define REG_TX_ISRC1_CTRL 0xCB
|
||||
#define REG_TX_ISRC2_CTRL 0xCC
|
||||
#define REG_TX_AVI_INFOFRM_CTRL 0xCD
|
||||
#define REG_TX_AUD_INFOFRM_CTRL 0xCE
|
||||
#define REG_TX_SPD_INFOFRM_CTRL 0xCF
|
||||
#define REG_TX_MPG_INFOFRM_CTRL 0xD0
|
||||
#define B_ENABLE_PKT 1
|
||||
#define B_REPEAT_PKT (1<<1)
|
||||
|
||||
|
||||
// Audio Channel Control
|
||||
#define REG_TX_AUDIO_CTRL0 0xE0
|
||||
#define M_AUD_SWL (3<<6)
|
||||
#define M_AUD_16BIT (0<<6)
|
||||
#define M_AUD_18BIT (1<<6)
|
||||
#define M_AUD_20BIT (2<<6)
|
||||
#define M_AUD_24BIT (3<<6)
|
||||
|
||||
#define B_SPDIFTC (1<<5)
|
||||
|
||||
#define B_AUD_SPDIF (1<<4)
|
||||
#define B_AUD_I2S (0<<4)
|
||||
#define B_AUD_EN_I2S3 (1<<3)
|
||||
#define B_AUD_EN_I2S2 (1<<2)
|
||||
#define B_AUD_EN_I2S1 (1<<1)
|
||||
#define B_AUD_EN_I2S0 (1<<0)
|
||||
|
||||
#define REG_TX_AUDIO_CTRL1 0xE1
|
||||
#define B_AUD_FULLPKT (1<<6)
|
||||
|
||||
#define B_AUDFMT_STD_I2S (0<<0)
|
||||
#define B_AUDFMT_32BIT_I2S (1<<0)
|
||||
#define B_AUDFMT_LEFT_JUSTIFY (0<<1)
|
||||
#define B_AUDFMT_RIGHT_JUSTIFY (1<<1)
|
||||
#define B_AUDFMT_DELAY_1T_TO_WS (0<<2)
|
||||
#define B_AUDFMT_NO_DELAY_TO_WS (1<<2)
|
||||
#define B_AUDFMT_WS0_LEFT (0<<3)
|
||||
#define B_AUDFMT_WS0_RIGHT (1<<3)
|
||||
#define B_AUDFMT_MSB_SHIFT_FIRST (0<<4)
|
||||
#define B_AUDFMT_LSB_SHIFT_FIRST (1<<4)
|
||||
#define B_AUDFMT_RISE_EDGE_SAMPLE_WS (0<<5)
|
||||
#define B_AUDFMT_FALL_EDGE_SAMPLE_WS (0<<5)
|
||||
|
||||
#define REG_TX_AUDIO_FIFOMAP 0xE2
|
||||
#define O_FIFO3SEL 6
|
||||
#define O_FIFO2SEL 4
|
||||
#define O_FIFO1SEL 2
|
||||
#define O_FIFO0SEL 0
|
||||
#define B_SELSRC3 3
|
||||
#define B_SELSRC2 2
|
||||
#define B_SELSRC1 1
|
||||
#define B_SELSRC0 0
|
||||
|
||||
#define REG_TX_AUDIO_CTRL3 0xE3
|
||||
#define B_AUD_MULCH (1<<7)
|
||||
#define B_EN_ZERO_CTS (1<<6)
|
||||
#define B_CHSTSEL (1<<4)
|
||||
#define B_S3RLCHG (1<<3)
|
||||
#define B_S2RLCHG (1<<2)
|
||||
#define B_S1RLCHG (1<<1)
|
||||
#define B_S0RLCHG (1<<0)
|
||||
|
||||
#define REG_TX_AUD_SRCVALID_FLAT 0xE4
|
||||
#define B_AUD_SPXFLAT_SRC3 (1<<7)
|
||||
#define B_AUD_SPXFLAT_SRC2 (1<<6)
|
||||
#define B_AUD_SPXFLAT_SRC1 (1<<5)
|
||||
#define B_AUD_SPXFLAT_SRC0 (1<<4)
|
||||
#define B_AUD_ERR2FLAT (1<<3)
|
||||
#define B_AUD_S3VALID (1<<2)
|
||||
#define B_AUD_S2VALID (1<<1)
|
||||
#define B_AUD_S1VALID (1<<0)
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Bank 1
|
||||
//////////////////////////////////////////
|
||||
|
||||
#define REGPktAudCTS0 0x30 // 7:0
|
||||
#define REGPktAudCTS1 0x31 // 15:8
|
||||
#define REGPktAudCTS2 0x32 // 19:16
|
||||
#define REGPktAudN0 0x33 // 7:0
|
||||
#define REGPktAudN1 0x34 // 15:8
|
||||
#define REGPktAudN2 0x35 // 19:16
|
||||
#define REGPktAudCTSCnt0 0xA0 // 7:0
|
||||
#define REGPktAudCTSCnt1 0xA1 // 15:8
|
||||
#define REGPktAudCTSCnt2 0xA2 // 19:16
|
||||
|
||||
//////////////////////////////////////////
|
||||
// COMMON PACKET for NULL,ISRC1,ISRC2,SPD
|
||||
//////////////////////////////////////////
|
||||
|
||||
#define REG_TX_PKT_HB00 0x38
|
||||
#define REG_TX_PKT_HB01 0x39
|
||||
#define REG_TX_PKT_HB02 0x3A
|
||||
|
||||
#define REG_TX_PKT_PB00 0x3B
|
||||
#define REG_TX_PKT_PB01 0x3C
|
||||
#define REG_TX_PKT_PB02 0x3D
|
||||
#define REG_TX_PKT_PB03 0x3E
|
||||
#define REG_TX_PKT_PB04 0x3F
|
||||
#define REG_TX_PKT_PB05 0x40
|
||||
#define REG_TX_PKT_PB06 0x41
|
||||
#define REG_TX_PKT_PB07 0x42
|
||||
#define REG_TX_PKT_PB08 0x43
|
||||
#define REG_TX_PKT_PB09 0x44
|
||||
#define REG_TX_PKT_PB10 0x45
|
||||
#define REG_TX_PKT_PB11 0x46
|
||||
#define REG_TX_PKT_PB12 0x47
|
||||
#define REG_TX_PKT_PB13 0x48
|
||||
#define REG_TX_PKT_PB14 0x49
|
||||
#define REG_TX_PKT_PB15 0x4A
|
||||
#define REG_TX_PKT_PB16 0x4B
|
||||
#define REG_TX_PKT_PB17 0x4C
|
||||
#define REG_TX_PKT_PB18 0x4D
|
||||
#define REG_TX_PKT_PB19 0x4E
|
||||
#define REG_TX_PKT_PB20 0x4F
|
||||
#define REG_TX_PKT_PB21 0x50
|
||||
#define REG_TX_PKT_PB22 0x51
|
||||
#define REG_TX_PKT_PB23 0x52
|
||||
#define REG_TX_PKT_PB24 0x53
|
||||
#define REG_TX_PKT_PB25 0x54
|
||||
#define REG_TX_PKT_PB26 0x55
|
||||
#define REG_TX_PKT_PB27 0x56
|
||||
|
||||
#define REG_TX_AVIINFO_DB1 0x58
|
||||
#define REG_TX_AVIINFO_DB2 0x59
|
||||
#define REG_TX_AVIINFO_DB3 0x5A
|
||||
#define REG_TX_AVIINFO_DB4 0x5B
|
||||
#define REG_TX_AVIINFO_DB5 0x5C
|
||||
#define REG_TX_AVIINFO_DB6 0x5E
|
||||
#define REG_TX_AVIINFO_DB7 0x5F
|
||||
#define REG_TX_AVIINFO_DB8 0x60
|
||||
#define REG_TX_AVIINFO_DB9 0x61
|
||||
#define REG_TX_AVIINFO_DB10 0x62
|
||||
#define REG_TX_AVIINFO_DB11 0x63
|
||||
#define REG_TX_AVIINFO_DB12 0x64
|
||||
#define REG_TX_AVIINFO_DB13 0x65
|
||||
#define REG_TX_AVIINFO_SUM 0x5D
|
||||
|
||||
#define REG_TX_PKT_AUDINFO_CC 0x68 // [2:0]
|
||||
#define REG_TX_PKT_AUDINFO_SF 0x69 // [4:2]
|
||||
#define REG_TX_PKT_AUDINFO_CA 0x6B // [7:0]
|
||||
|
||||
#define REG_TX_PKT_AUDINFO_DM_LSV 0x6C // [7][6:3]
|
||||
#define REG_TX_PKT_AUDINFO_SUM 0x6D // [7:0]
|
||||
|
||||
// Source Product Description Info Frame
|
||||
#define REG_TX_PKT_SPDINFO_SUM 0x70
|
||||
#define REG_TX_PKT_SPDINFO_PB1 0x71
|
||||
#define REG_TX_PKT_SPDINFO_PB2 0x72
|
||||
#define REG_TX_PKT_SPDINFO_PB3 0x73
|
||||
#define REG_TX_PKT_SPDINFO_PB4 0x74
|
||||
#define REG_TX_PKT_SPDINFO_PB5 0x75
|
||||
#define REG_TX_PKT_SPDINFO_PB6 0x76
|
||||
#define REG_TX_PKT_SPDINFO_PB7 0x77
|
||||
#define REG_TX_PKT_SPDINFO_PB8 0x78
|
||||
#define REG_TX_PKT_SPDINFO_PB9 0x79
|
||||
#define REG_TX_PKT_SPDINFO_PB10 0x7A
|
||||
#define REG_TX_PKT_SPDINFO_PB11 0x7B
|
||||
#define REG_TX_PKT_SPDINFO_PB12 0x7C
|
||||
#define REG_TX_PKT_SPDINFO_PB13 0x7D
|
||||
#define REG_TX_PKT_SPDINFO_PB14 0x7E
|
||||
#define REG_TX_PKT_SPDINFO_PB15 0x7F
|
||||
#define REG_TX_PKT_SPDINFO_PB16 0x80
|
||||
#define REG_TX_PKT_SPDINFO_PB17 0x81
|
||||
#define REG_TX_PKT_SPDINFO_PB18 0x82
|
||||
#define REG_TX_PKT_SPDINFO_PB19 0x83
|
||||
#define REG_TX_PKT_SPDINFO_PB20 0x84
|
||||
#define REG_TX_PKT_SPDINFO_PB21 0x85
|
||||
#define REG_TX_PKT_SPDINFO_PB22 0x86
|
||||
#define REG_TX_PKT_SPDINFO_PB23 0x87
|
||||
#define REG_TX_PKT_SPDINFO_PB24 0x88
|
||||
#define REG_TX_PKT_SPDINFO_PB25 0x89
|
||||
|
||||
#define REG_TX_PKT_MPGINFO_FMT 0x8A
|
||||
#define B_MPG_FR 1
|
||||
#define B_MPG_MF_I (1<<1)
|
||||
#define B_MPG_MF_B (2<<1)
|
||||
#define B_MPG_MF_P (3<<1)
|
||||
#define B_MPG_MF_MASK (3<<1)
|
||||
#define REG_TX_PKG_MPGINFO_DB0 0x8B
|
||||
#define REG_TX_PKG_MPGINFO_DB1 0x8C
|
||||
#define REG_TX_PKG_MPGINFO_DB2 0x8D
|
||||
#define REG_TX_PKG_MPGINFO_DB3 0x8E
|
||||
#define REG_TX_PKG_MPGINFO_SUM 0x8F
|
||||
|
||||
#define REG_TX_AUDCHST_MODE 0x91 // 191 REG_TX_AUD_CHSTD[2:0] 6:4
|
||||
// REG_TX_AUD_CHSTC 3
|
||||
// REG_TX_AUD_NLPCM 2
|
||||
// REG_TX_AUD_MONO 0
|
||||
#define REG_TX_AUDCHST_CAT 0x92 // 192 REG_TX_AUD_CHSTCAT 7:0
|
||||
#define REG_TX_AUDCHST_SRCNUM 0x93 // 193 REG_TX_AUD_CHSTSRC 3:0
|
||||
#define REG_TX_AUD0CHST_CHTNUM 0x94 // 194 REG_TX_AUD0_CHSTCHR 7:4
|
||||
// REG_TX_AUD0_CHSTCHL 3:0
|
||||
#define REG_TX_AUD1CHST_CHTNUM 0x95 // 195 REG_TX_AUD1_CHSTCHR 7:4
|
||||
// REG_TX_AUD1_CHSTCHL 3:0
|
||||
#define REG_TX_AUD2CHST_CHTNUM 0x96 // 196 REG_TX_AUD2_CHSTCHR 7:4
|
||||
// REG_TX_AUD2_CHSTCHL 3:0
|
||||
#define REG_TX_AUD3CHST_CHTNUM 0x97 // 197 REG_TX_AUD3_CHSTCHR 7:4
|
||||
// REG_TX_AUD3_CHSTCHL 3:0
|
||||
#define REG_TX_AUDCHST_CA_FS 0x98 // 198 REG_TX_AUD_CHSTCA 5:4
|
||||
// REG_TX_AUD_CHSTFS 3:0
|
||||
#define REG_TX_AUDCHST_OFS_WL 0x99 // 199 REG_TX_AUD_CHSTOFS 7:4
|
||||
// REG_TX_AUD_CHSTWL 3:0
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Macro
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define Switch_HDMITX_Bank(x) HDMITX_WriteI2C_Byte(0x0f,(x)&1)
|
||||
|
||||
#define HDMI_OrREG_TX_Byte(reg,ormask) HDMITX_WriteI2C_Byte(reg,(HDMITX_ReadI2C_Byte(reg) | (ormask)))
|
||||
#define HDMI_AndREG_TX_Byte(reg,andmask) HDMITX_WriteI2C_Byte(reg,(HDMITX_ReadI2C_Byte(reg) & (andmask)))
|
||||
#define HDMI_SetREG_TX_Byte(reg,andmask,ormask) HDMITX_WriteI2C_Byte(reg,((HDMITX_ReadI2C_Byte(reg) & (andmask))|(ormask)))
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// data structure
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
typedef struct _INSTANCE_STRUCT {
|
||||
|
||||
BYTE I2C_DEV ;
|
||||
BYTE I2C_ADDR ;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Interrupt Type
|
||||
/////////////////////////////////////////////////
|
||||
BYTE bIntType ; // = 0 ;
|
||||
/////////////////////////////////////////////////
|
||||
// Video Property
|
||||
/////////////////////////////////////////////////
|
||||
BYTE bInputVideoSignalType ; // for Sync Embedded,CCIR656,InputDDR
|
||||
/////////////////////////////////////////////////
|
||||
// Audio Property
|
||||
/////////////////////////////////////////////////
|
||||
BYTE bOutputAudioMode ; // = 0 ;
|
||||
BYTE bAudioChannelSwap ; // = 0 ;
|
||||
BYTE bAudioChannelEnable ;
|
||||
BYTE bAudFs ;
|
||||
unsigned long TMDSClock ;
|
||||
BYTE bAuthenticated:1 ;
|
||||
BYTE bHDMIMode: 1;
|
||||
BYTE bIntPOL:1 ; // 0 = Low Active
|
||||
BYTE bHPD:1 ;
|
||||
|
||||
} INSTANCE ;
|
||||
|
||||
|
||||
// 2008/02/27 added by jj_tseng@chipadvanced.com
|
||||
typedef enum _mode_id {
|
||||
UNKNOWN_MODE=0,
|
||||
CEA_640x480p60,
|
||||
CEA_720x480p60,
|
||||
CEA_1280x720p60,
|
||||
CEA_1920x1080i60,
|
||||
CEA_720x480i60,
|
||||
CEA_720x240p60,
|
||||
CEA_1440x480i60,
|
||||
CEA_1440x240p60,
|
||||
CEA_2880x480i60,
|
||||
CEA_2880x240p60,
|
||||
CEA_1440x480p60,
|
||||
CEA_1920x1080p60,
|
||||
CEA_720x576p50,
|
||||
CEA_1280x720p50,
|
||||
CEA_1920x1080i50,
|
||||
CEA_720x576i50,
|
||||
CEA_1440x576i50,
|
||||
CEA_720x288p50,
|
||||
CEA_1440x288p50,
|
||||
CEA_2880x576i50,
|
||||
CEA_2880x288p50,
|
||||
CEA_1440x576p50,
|
||||
CEA_1920x1080p50,
|
||||
CEA_1920x1080p24,
|
||||
CEA_1920x1080p25,
|
||||
CEA_1920x1080p30,
|
||||
VESA_640x350p85,
|
||||
VESA_640x400p85,
|
||||
VESA_720x400p85,
|
||||
VESA_640x480p60,
|
||||
VESA_640x480p72,
|
||||
VESA_640x480p75,
|
||||
VESA_640x480p85,
|
||||
VESA_800x600p56,
|
||||
VESA_800x600p60,
|
||||
VESA_800x600p72,
|
||||
VESA_800x600p75,
|
||||
VESA_800X600p85,
|
||||
VESA_840X480p60,
|
||||
VESA_1024x768p60,
|
||||
VESA_1024x768p70,
|
||||
VESA_1024x768p75,
|
||||
VESA_1024x768p85,
|
||||
VESA_1152x864p75,
|
||||
VESA_1280x768p60R,
|
||||
VESA_1280x768p60,
|
||||
VESA_1280x768p75,
|
||||
VESA_1280x768p85,
|
||||
VESA_1280x960p60,
|
||||
VESA_1280x960p85,
|
||||
VESA_1280x1024p60,
|
||||
VESA_1280x1024p75,
|
||||
VESA_1280X1024p85,
|
||||
VESA_1360X768p60,
|
||||
VESA_1400x768p60R,
|
||||
VESA_1400x768p60,
|
||||
VESA_1400x1050p75,
|
||||
VESA_1400x1050p85,
|
||||
VESA_1440x900p60R,
|
||||
VESA_1440x900p60,
|
||||
VESA_1440x900p75,
|
||||
VESA_1440x900p85,
|
||||
VESA_1600x1200p60,
|
||||
VESA_1600x1200p65,
|
||||
VESA_1600x1200p70,
|
||||
VESA_1600x1200p75,
|
||||
VESA_1600x1200p85,
|
||||
VESA_1680x1050p60R,
|
||||
VESA_1680x1050p60,
|
||||
VESA_1680x1050p75,
|
||||
VESA_1680x1050p85,
|
||||
VESA_1792x1344p60,
|
||||
VESA_1792x1344p75,
|
||||
VESA_1856x1392p60,
|
||||
VESA_1856x1392p75,
|
||||
VESA_1920x1200p60R,
|
||||
VESA_1920x1200p60,
|
||||
VESA_1920x1200p75,
|
||||
VESA_1920x1200p85,
|
||||
VESA_1920x1440p60,
|
||||
VESA_1920x1440p75,
|
||||
} MODE_ID ;
|
||||
|
||||
//~jj_tseng@chipadvanced.com
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// External Interface
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
void InitIT6613();
|
||||
void HDMITX_InitInstance(INSTANCE *pInstance) ;
|
||||
BOOL EnableVideoOutput(VIDEOPCLKLEVEL level,BYTE inputColorMode,BYTE outputColorMode,BYTE bHDMI) ;
|
||||
BOOL SetupVideoInputSignal(BYTE inputSignalType) ;
|
||||
|
||||
#ifdef SUPPORT_DEGEN
|
||||
BOOL ProgramDEGenModeByID(MODE_ID id,BYTE bInputSignalType) ;
|
||||
#endif // SUPPORT_DEGEN
|
||||
#ifdef SUPPORT_SYNCEMBEDDED
|
||||
BOOL ProgramSyncEmbeddedVideoMode(BYTE VIC,BYTE bInputType) ;
|
||||
#endif
|
||||
BOOL EnableAudioOutput(unsigned long VideoPixelClock,BYTE bAudioSampleFreq,BYTE ChannelNumber,BYTE bAudSWL,BYTE bSPDIF) ;
|
||||
void DisableIT6613() ;
|
||||
void DisableVideoOutput() ;
|
||||
void DisableAudioOutput() ;
|
||||
BOOL GetEDIDData(int EDIDBlockID,BYTE *pEDIDData);
|
||||
BOOL CheckHDMITX(BYTE *pHPD,BYTE *pHPDChange) ;
|
||||
BOOL EnableHDCP(BYTE bEnable) ;
|
||||
BOOL EnableAVIInfoFrame(BYTE bEnable,BYTE *pAVIInfoFrame);
|
||||
BOOL EnableAudioInfoFrame(BYTE bEnable,BYTE *pAudioInfoFrame);
|
||||
// BOOL EnableVideoOutputIndirect(BYTE xCnt,BYTE inputColorMode,BYTE outputColorMode,BYTE bHDMI) ;
|
||||
void SetAVMute(BYTE bEnable) ;
|
||||
void SetOutputColorDepthPhase(BYTE ColorDepth,BYTE bPhase) ;
|
||||
void Get6613Reg(BYTE *pReg) ;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Required Interfance
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BYTE I2C_Read_Byte(BYTE Addr,BYTE RegAddr);
|
||||
SYS_STATUS I2C_Write_Byte(BYTE Addr,BYTE RegAddr,BYTE Data);
|
||||
SYS_STATUS I2C_Read_ByteN(BYTE Addr,BYTE RegAddr,BYTE *pData,int N) ;
|
||||
SYS_STATUS I2C_Write_ByteN(BYTE Addr,BYTE RegAddr,BYTE *pData,int N) ;
|
||||
|
||||
BYTE HDMITX_ReadI2C_Byte(BYTE RegAddr);
|
||||
SYS_STATUS HDMITX_WriteI2C_Byte(BYTE RegAddr,BYTE val);
|
||||
SYS_STATUS HDMITX_ReadI2C_ByteN(BYTE RegAddr,BYTE *pData,int N);
|
||||
SYS_STATUS HDMITX_WriteI2C_ByteN(BYTE RegAddr,BYTE *pData,int N);
|
||||
|
||||
#endif // _IT6613_H_
|
|
@ -0,0 +1,550 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// This is the sample program for CAT6611 driver usage.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "hdmitx.h"
|
||||
#include "it6613_sys.h" // richard add
|
||||
#include "edid.h" // richard add
|
||||
|
||||
extern int TX_HDP; // richard add
|
||||
int gEnableColorDepth = 1; //richard add
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// EDID
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static _XDATA unsigned char EDID_Buf[128] ;
|
||||
// richard static RX_CAP _XDATA RxCapability ;
|
||||
RX_CAP _XDATA RxCapability ;
|
||||
// richard static BOOL bChangeMode = FALSE ;
|
||||
BOOL bChangeMode = FALSE ;
|
||||
_XDATA AVI_InfoFrame AviInfo;
|
||||
_XDATA Audio_InfoFrame AudioInfo ;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Program utility.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// move to .h BOOL ParseEDID() ;
|
||||
// richard static BOOL ParseCEAEDID(BYTE *pCEAEDID) ;
|
||||
void ConfigAVIInfoFrame(BYTE VIC, BYTE pixelrep) ;
|
||||
void ConfigAudioInfoFrm() ;
|
||||
|
||||
|
||||
#ifndef SUPPORT_SYNCEMB
|
||||
_IDATA BYTE bInputColorMode = F_MODE_RGB444; //F_MODE_RGB444;
|
||||
_IDATA BYTE bInputSignalType = 0 ;
|
||||
// BYTE bInputSignalType = T_MODE_INDDR ; // for DDR mode input
|
||||
#else
|
||||
// BYTE bInputSignalType = T_MODE_SYNCEMB ; // for 16 bit sync embedded
|
||||
_IDATA BYTE bInputColorMode = F_MODE_YUV422 ;
|
||||
_IDATA BYTE bInputSignalType = T_MODE_SYNCEMB | T_MODE_CCIR656 ; // for 16 bit sync embedded
|
||||
#endif // SUPPORT_SYNCEMB
|
||||
|
||||
_IDATA BYTE iVideoModeSelect=0 ;
|
||||
|
||||
_IDATA BYTE bOutputColorMode = F_MODE_RGB444; //F_MODE_RGB444 ;
|
||||
_XDATA ULONG VideoPixelClock ;
|
||||
_XDATA BYTE VIC ; // 480p60
|
||||
_XDATA BYTE pixelrep ; // no pixelrepeating
|
||||
_XDATA HDMI_Aspec aspec ;
|
||||
_XDATA HDMI_Colorimetry Colorimetry ;
|
||||
|
||||
BOOL bHDMIMode, bAudioEnable ;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Function Body.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//richard, move to .h void HDMITX_ChangeDisplayOption(HDMI_Video_Type VideoMode, HDMI_OutputColorMode OutputColorMode) ;
|
||||
//richard, move to .hvoid HDMITX_SetOutput() ;
|
||||
//richard richard, move to .h void HDMITX_DevLoopProc() ;
|
||||
|
||||
void
|
||||
HDMITX_SetOutput()
|
||||
{
|
||||
VIDEOPCLKLEVEL level ;
|
||||
unsigned long TMDSClock = VideoPixelClock*(pixelrep+1);
|
||||
|
||||
#ifdef SUPPORT_SYNCEMB
|
||||
ProgramSyncEmbeddedVideoMode(VIC, bInputSignalType) ; // inf CCIR656 input
|
||||
#endif
|
||||
|
||||
//TMDSClock = 745000000; //????? richard
|
||||
if( TMDSClock>80000000 )
|
||||
{
|
||||
level = PCLK_HIGH ;
|
||||
}
|
||||
else if(TMDSClock>20000000)
|
||||
{
|
||||
level = PCLK_MEDIUM ;
|
||||
}
|
||||
else
|
||||
{
|
||||
level = PCLK_LOW ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//BOOL EnableVideoOutput(VIDEOPCLKLEVEL level,BYTE inputColorMode,BYTE outputColorMode,BYTE bHDMI) ;
|
||||
//EnableVideoOutput(level,bInputColorMode, bInputSignalType, bOutputColorMode,bHDMIMode) ;
|
||||
EnableVideoOutput(level,bInputColorMode, bOutputColorMode,bHDMIMode) ; // richard modify
|
||||
|
||||
if( bHDMIMode )
|
||||
{
|
||||
OS_PRINTF("ConfigAVIInfoFrame, VIC=%d\n", VIC);
|
||||
ConfigAVIInfoFrame(VIC, pixelrep) ;
|
||||
|
||||
EnableHDCP(TRUE) ;
|
||||
if( bAudioEnable )
|
||||
{
|
||||
//BOOL EnableAudioOutput(ULONG VideoPixelClock,BYTE bAudioSampleFreq,BYTE ChannelNumber,BYTE bAudSWL,BYTE bSPDIF)
|
||||
//EnableAudioOutput(TMDSClock,48000, 2, FALSE);
|
||||
bool bSPDIF = FALSE;
|
||||
EnableAudioOutput(TMDSClock,AUDFS_48KHz, 2, 16, bSPDIF); // richard modify
|
||||
ConfigAudioInfoFrm() ;
|
||||
}
|
||||
}
|
||||
SetAVMute(FALSE) ;
|
||||
bChangeMode = FALSE ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
HDMITX_ChangeDisplayOption(HDMI_Video_Type OutputVideoTiming, HDMI_OutputColorMode OutputColorMode)
|
||||
{
|
||||
//HDMI_Video_Type t=HDMI_480i60_16x9;
|
||||
switch(OutputVideoTiming)
|
||||
{
|
||||
case HDMI_640x480p60:
|
||||
VIC = 1 ;
|
||||
VideoPixelClock = 25000000 ;
|
||||
pixelrep = 0 ;
|
||||
aspec = HDMI_4x3 ;
|
||||
Colorimetry = HDMI_ITU601 ;
|
||||
break ;
|
||||
case HDMI_480p60:
|
||||
VIC = 2 ;
|
||||
VideoPixelClock = 27000000 ;
|
||||
pixelrep = 0 ;
|
||||
aspec = HDMI_4x3 ;
|
||||
Colorimetry = HDMI_ITU601 ;
|
||||
break ;
|
||||
case HDMI_480p60_16x9:
|
||||
VIC = 3 ;
|
||||
VideoPixelClock = 27000000 ;
|
||||
pixelrep = 0 ;
|
||||
aspec = HDMI_16x9 ;
|
||||
Colorimetry = HDMI_ITU601 ;
|
||||
break ;
|
||||
case HDMI_720p60:
|
||||
VIC = 4 ;
|
||||
VideoPixelClock = 74250000 ;
|
||||
pixelrep = 0 ;
|
||||
aspec = HDMI_16x9 ;
|
||||
Colorimetry = HDMI_ITU709 ;
|
||||
break ;
|
||||
case HDMI_1080i60:
|
||||
VIC = 5 ;
|
||||
VideoPixelClock = 74250000 ;
|
||||
pixelrep = 0 ;
|
||||
aspec = HDMI_16x9 ;
|
||||
Colorimetry = HDMI_ITU709 ;
|
||||
break ;
|
||||
case HDMI_480i60:
|
||||
VIC = 6 ;
|
||||
VideoPixelClock = 13500000 ;
|
||||
pixelrep = 1 ;
|
||||
aspec = HDMI_4x3 ;
|
||||
Colorimetry = HDMI_ITU601 ;
|
||||
break ;
|
||||
case HDMI_480i60_16x9:
|
||||
VIC = 7 ;
|
||||
VideoPixelClock = 13500000 ;
|
||||
pixelrep = 1 ;
|
||||
aspec = HDMI_16x9 ;
|
||||
Colorimetry = HDMI_ITU601 ;
|
||||
break ;
|
||||
case HDMI_1080p60:
|
||||
VIC = 16 ;
|
||||
VideoPixelClock = 148500000 ;
|
||||
pixelrep = 0 ;
|
||||
aspec = HDMI_16x9 ;
|
||||
Colorimetry = HDMI_ITU709 ;
|
||||
break ;
|
||||
case HDMI_576p50:
|
||||
VIC = 17 ;
|
||||
VideoPixelClock = 27000000 ;
|
||||
pixelrep = 0 ;
|
||||
aspec = HDMI_4x3 ;
|
||||
Colorimetry = HDMI_ITU601 ;
|
||||
break ;
|
||||
case HDMI_576p50_16x9:
|
||||
VIC = 18 ;
|
||||
VideoPixelClock = 27000000 ;
|
||||
pixelrep = 0 ;
|
||||
aspec = HDMI_16x9 ;
|
||||
Colorimetry = HDMI_ITU601 ;
|
||||
break ;
|
||||
case HDMI_720p50:
|
||||
VIC = 19 ;
|
||||
VideoPixelClock = 74250000 ;
|
||||
pixelrep = 0 ;
|
||||
aspec = HDMI_16x9 ;
|
||||
Colorimetry = HDMI_ITU709 ;
|
||||
break ;
|
||||
case HDMI_1080i50:
|
||||
VIC = 20 ;
|
||||
VideoPixelClock = 74250000 ;
|
||||
pixelrep = 0 ;
|
||||
aspec = HDMI_16x9 ;
|
||||
Colorimetry = HDMI_ITU709 ;
|
||||
break ;
|
||||
case HDMI_576i50:
|
||||
VIC = 21 ;
|
||||
VideoPixelClock = 13500000 ;
|
||||
pixelrep = 1 ;
|
||||
aspec = HDMI_4x3 ;
|
||||
Colorimetry = HDMI_ITU601 ;
|
||||
break ;
|
||||
case HDMI_576i50_16x9:
|
||||
VIC = 22 ;
|
||||
VideoPixelClock = 13500000 ;
|
||||
pixelrep = 1 ;
|
||||
aspec = HDMI_16x9 ;
|
||||
Colorimetry = HDMI_ITU601 ;
|
||||
break ;
|
||||
case HDMI_1080p50:
|
||||
VIC = 31 ;
|
||||
VideoPixelClock = 148500000 ;
|
||||
pixelrep = 0 ;
|
||||
aspec = HDMI_16x9 ;
|
||||
Colorimetry = HDMI_ITU709 ;
|
||||
break ;
|
||||
case HDMI_1080p24:
|
||||
VIC = 32 ;
|
||||
VideoPixelClock = 74250000 ;
|
||||
pixelrep = 0 ;
|
||||
aspec = HDMI_16x9 ;
|
||||
Colorimetry = HDMI_ITU709 ;
|
||||
break ;
|
||||
case HDMI_1080p25:
|
||||
VIC = 33 ;
|
||||
VideoPixelClock = 74250000 ;
|
||||
pixelrep = 0 ;
|
||||
aspec = HDMI_16x9 ;
|
||||
Colorimetry = HDMI_ITU709 ;
|
||||
break ;
|
||||
case HDMI_1080p30:
|
||||
VIC = 34 ;
|
||||
VideoPixelClock = 74250000 ;
|
||||
pixelrep = 0 ;
|
||||
aspec = HDMI_16x9 ;
|
||||
Colorimetry = HDMI_ITU709 ;
|
||||
break ;
|
||||
case HDMI_1080i120:// richard add
|
||||
VIC = 46 ;
|
||||
VideoPixelClock = 148500000 ;
|
||||
pixelrep = 0 ;
|
||||
aspec = HDMI_16x9 ;
|
||||
Colorimetry = HDMI_ITU601 ;
|
||||
break ;
|
||||
|
||||
|
||||
default:
|
||||
VIC = 0; // richard add
|
||||
bChangeMode = FALSE ;
|
||||
return ;
|
||||
}
|
||||
|
||||
switch(OutputColorMode)
|
||||
{
|
||||
case HDMI_YUV444:
|
||||
bOutputColorMode = F_MODE_YUV444 ;
|
||||
break ;
|
||||
case HDMI_YUV422:
|
||||
bOutputColorMode = F_MODE_YUV422 ;
|
||||
break ;
|
||||
case HDMI_RGB444:
|
||||
default:
|
||||
bOutputColorMode = F_MODE_RGB444 ;
|
||||
break ;
|
||||
}
|
||||
|
||||
if( Colorimetry == HDMI_ITU709 )
|
||||
{
|
||||
bInputColorMode |= F_VIDMODE_ITU709 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
bInputColorMode &= ~F_VIDMODE_ITU709 ;
|
||||
}
|
||||
|
||||
if( Colorimetry != HDMI_640x480p60)
|
||||
{
|
||||
bInputColorMode |= F_VIDMODE_16_235 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
bInputColorMode &= ~F_VIDMODE_16_235 ;
|
||||
}
|
||||
|
||||
bChangeMode = TRUE ;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ConfigAVIInfoFrame(BYTE VIC, BYTE pixelrep)
|
||||
{
|
||||
// AVI_InfoFrame AviInfo;
|
||||
|
||||
AviInfo.pktbyte.AVI_HB[0] = AVI_INFOFRAME_TYPE|0x80 ;
|
||||
AviInfo.pktbyte.AVI_HB[1] = AVI_INFOFRAME_VER ;
|
||||
AviInfo.pktbyte.AVI_HB[2] = AVI_INFOFRAME_LEN ;
|
||||
|
||||
switch(bOutputColorMode)
|
||||
{
|
||||
case F_MODE_YUV444:
|
||||
// AviInfo.info.ColorMode = 2 ;
|
||||
AviInfo.pktbyte.AVI_DB[0] = (2<<5)|(1<<4) ;
|
||||
break ;
|
||||
case F_MODE_YUV422:
|
||||
// AviInfo.info.ColorMode = 1 ;
|
||||
AviInfo.pktbyte.AVI_DB[0] = (1<<5)|(1<<4) ;
|
||||
break ;
|
||||
case F_MODE_RGB444:
|
||||
default:
|
||||
// AviInfo.info.ColorMode = 0 ;
|
||||
AviInfo.pktbyte.AVI_DB[0] = (0<<5)|(1<<4) ;
|
||||
break ;
|
||||
}
|
||||
AviInfo.pktbyte.AVI_DB[1] = 8 ;
|
||||
AviInfo.pktbyte.AVI_DB[1] |= (aspec != HDMI_16x9)?(1<<4):(2<<4) ; // 4:3 or 16:9
|
||||
AviInfo.pktbyte.AVI_DB[1] |= (Colorimetry != HDMI_ITU709)?(1<<6):(2<<6) ; // 4:3 or 16:9
|
||||
AviInfo.pktbyte.AVI_DB[2] = 0 ;
|
||||
AviInfo.pktbyte.AVI_DB[3] = VIC ;
|
||||
AviInfo.pktbyte.AVI_DB[4] = pixelrep & 3 ;
|
||||
AviInfo.pktbyte.AVI_DB[5] = 0 ;
|
||||
AviInfo.pktbyte.AVI_DB[6] = 0 ;
|
||||
AviInfo.pktbyte.AVI_DB[7] = 0 ;
|
||||
AviInfo.pktbyte.AVI_DB[8] = 0 ;
|
||||
AviInfo.pktbyte.AVI_DB[9] = 0 ;
|
||||
AviInfo.pktbyte.AVI_DB[10] = 0 ;
|
||||
AviInfo.pktbyte.AVI_DB[11] = 0 ;
|
||||
AviInfo.pktbyte.AVI_DB[12] = 0 ;
|
||||
|
||||
EnableAVIInfoFrame(TRUE, (unsigned char *)&AviInfo) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Function: ConfigAudioInfoFrm
|
||||
// Parameter: NumChannel, number from 1 to 8
|
||||
// Return: ER_SUCCESS for successfull.
|
||||
// Remark: Evaluate. The speakerplacement is only for reference.
|
||||
// For production, the caller of SetAudioInfoFrame should program
|
||||
// Speaker placement by actual status.
|
||||
// Side-Effect:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
ConfigAudioInfoFrm()
|
||||
{
|
||||
int i ;
|
||||
ErrorF("ConfigAudioInfoFrm(%d)\n",2) ;
|
||||
|
||||
AudioInfo.pktbyte.AUD_HB[0] = AUDIO_INFOFRAME_TYPE ;
|
||||
AudioInfo.pktbyte.AUD_HB[1] = 1 ;
|
||||
AudioInfo.pktbyte.AUD_HB[2] = AUDIO_INFOFRAME_LEN ;
|
||||
AudioInfo.pktbyte.AUD_DB[0] = 1 ;
|
||||
for( i = 1 ;i < AUDIO_INFOFRAME_LEN ; i++ )
|
||||
{
|
||||
AudioInfo.pktbyte.AUD_DB[i] = 0 ;
|
||||
}
|
||||
EnableAudioInfoFrame(TRUE, (unsigned char *)&AudioInfo) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// ParseEDID()
|
||||
// Check EDID check sum and EDID 1.3 extended segment.
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOL
|
||||
ParseEDID()
|
||||
{
|
||||
// collect the EDID ucdata of segment 0
|
||||
BYTE CheckSum ;
|
||||
BYTE BlockCount ;
|
||||
BOOL err ;
|
||||
BOOL bValidCEA = FALSE ;
|
||||
int i ;
|
||||
|
||||
RxCapability.ValidCEA = FALSE ;
|
||||
|
||||
// richard GetEDIDData(0, EDID_Buf);
|
||||
if (!GetEDIDData(0, EDID_Buf))
|
||||
return FALSE;
|
||||
|
||||
|
||||
for( i = 0, CheckSum = 0 ; i < 128 ; i++ )
|
||||
{
|
||||
CheckSum += EDID_Buf[i] ; CheckSum &= 0xFF ;
|
||||
}
|
||||
|
||||
//Eep_Write(0x80, 0x80, EDID_Buf) ;
|
||||
if( CheckSum != 0 ) // 128-byte EDID sum shall equal zero
|
||||
{
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
// check EDID Header
|
||||
if( EDID_Buf[0] != 0x00 ||
|
||||
EDID_Buf[1] != 0xFF ||
|
||||
EDID_Buf[2] != 0xFF ||
|
||||
EDID_Buf[3] != 0xFF ||
|
||||
EDID_Buf[4] != 0xFF ||
|
||||
EDID_Buf[5] != 0xFF ||
|
||||
EDID_Buf[6] != 0xFF ||
|
||||
EDID_Buf[7] != 0x00)
|
||||
{
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
|
||||
BlockCount = EDID_Buf[0x7E] ; // Extention Flash: Number of 128-byte EDID extesion blocks to follow
|
||||
|
||||
if( BlockCount == 0 )
|
||||
{
|
||||
return TRUE ; // do nothing.
|
||||
}
|
||||
else if ( BlockCount > 4 )
|
||||
{
|
||||
BlockCount = 4 ;
|
||||
}
|
||||
|
||||
// read all segment for test
|
||||
for( i = 1 ; i <= BlockCount ; i++ )
|
||||
{
|
||||
err = GetEDIDData(i, EDID_Buf) ;
|
||||
|
||||
if( err )
|
||||
{
|
||||
if( !bValidCEA && EDID_Buf[0] == 0x2 && EDID_Buf[1] == 0x3 ) //EDID_Buf[0] == 0x2 ==> Additional timing data type 2
|
||||
{
|
||||
// richard change
|
||||
//err = ParseCEAEDID(EDID_Buf) ;
|
||||
err = ParseCEAEDID(EDID_Buf, &RxCapability);
|
||||
if( err )
|
||||
{
|
||||
|
||||
if(RxCapability.IEEEOUI==0x0c03)
|
||||
{
|
||||
RxCapability.ValidHDMI = TRUE ;
|
||||
bValidCEA = TRUE ;
|
||||
}
|
||||
else
|
||||
{
|
||||
RxCapability.ValidHDMI = FALSE ;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err?FALSE:TRUE ; // richard modify
|
||||
|
||||
}
|
||||
|
||||
/* richard: use the one defined edid.c
|
||||
static BOOL
|
||||
ParseCEAEDID(BYTE *pCEAEDID)
|
||||
{
|
||||
BYTE offset,End ;
|
||||
BYTE count ;
|
||||
BYTE tag ;
|
||||
int i ;
|
||||
|
||||
// richard if( pCEAEDID[0] != 0x02 || pCEAEDID[1] != 0x03 ) return ER_SUCCESS ; // not a CEA BLOCK.
|
||||
if( pCEAEDID[0] != 0x02 || pCEAEDID[1] != 0x03 ) // not a CEA BLOCK.
|
||||
return FALSE;
|
||||
End = pCEAEDID[2] ; // CEA description.
|
||||
RxCapability.VideoMode = pCEAEDID[3] ;
|
||||
|
||||
RxCapability.VDOModeCount = 0 ;
|
||||
RxCapability.idxNativeVDOMode = 0xff ;
|
||||
|
||||
for( offset = 4 ; offset < End ; )
|
||||
{
|
||||
tag = pCEAEDID[offset] >> 5 ;
|
||||
count = pCEAEDID[offset] & 0x1f ;
|
||||
switch( tag )
|
||||
{
|
||||
case 0x01: // Audio Data Block ;
|
||||
RxCapability.AUDDesCount = count/3 ;
|
||||
offset++ ;
|
||||
for( i = 0 ; i < RxCapability.AUDDesCount ; i++ )
|
||||
{
|
||||
RxCapability.AUDDes[i].uc[0] = pCEAEDID[offset++] ;
|
||||
RxCapability.AUDDes[i].uc[1] = pCEAEDID[offset++] ;
|
||||
RxCapability.AUDDes[i].uc[2] = pCEAEDID[offset++] ;
|
||||
}
|
||||
|
||||
break ;
|
||||
|
||||
case 0x02: // Video Data Block ;
|
||||
//RxCapability.VDOModeCount = 0 ;
|
||||
offset ++ ;
|
||||
for( i = 0,RxCapability.idxNativeVDOMode = 0xff ; i < count ; i++, offset++ )
|
||||
{
|
||||
BYTE VIC ;
|
||||
VIC = pCEAEDID[offset] & (~0x80) ;
|
||||
// if( FindModeTableEntryByVIC(VIC) != -1 )
|
||||
{
|
||||
RxCapability.VDOMode[RxCapability.VDOModeCount] = VIC ;
|
||||
if( pCEAEDID[offset] & 0x80 )
|
||||
{
|
||||
RxCapability.idxNativeVDOMode = (BYTE)RxCapability.VDOModeCount ;
|
||||
iVideoModeSelect = RxCapability.VDOModeCount ;
|
||||
}
|
||||
|
||||
RxCapability.VDOModeCount++ ;
|
||||
}
|
||||
}
|
||||
break ;
|
||||
|
||||
case 0x03: // Vendor Specific Data Block ;
|
||||
offset ++ ;
|
||||
RxCapability.IEEEOUI = (ULONG)pCEAEDID[offset+2] ;
|
||||
RxCapability.IEEEOUI <<= 8 ;
|
||||
RxCapability.IEEEOUI += (ULONG)pCEAEDID[offset+1] ;
|
||||
RxCapability.IEEEOUI <<= 8 ;
|
||||
RxCapability.IEEEOUI += (ULONG)pCEAEDID[offset] ;
|
||||
offset += count ; // ignore the remaind.
|
||||
|
||||
break ;
|
||||
|
||||
case 0x04: // Speaker Data Block ;
|
||||
offset ++ ;
|
||||
RxCapability.SpeakerAllocBlk.uc[0] = pCEAEDID[offset] ;
|
||||
RxCapability.SpeakerAllocBlk.uc[1] = pCEAEDID[offset+1] ;
|
||||
RxCapability.SpeakerAllocBlk.uc[2] = pCEAEDID[offset+2] ;
|
||||
offset += 3 ;
|
||||
break ;
|
||||
case 0x05: // VESA Data Block ;
|
||||
offset += count+1 ;
|
||||
break ;
|
||||
case 0x07: // Extended Data Block ;
|
||||
offset += count+1 ; //ignore
|
||||
break ;
|
||||
default:
|
||||
offset += count+1 ; // ignore
|
||||
}
|
||||
}
|
||||
RxCapability.ValidCEA = TRUE ;
|
||||
return TRUE ;
|
||||
}
|
||||
*/
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
#ifndef _CAT6611_SYS_H_
|
||||
#define _CAT6611_SYS_H_
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Internal Data Type
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef enum tagHDMI_Video_Type {
|
||||
HDMI_Unkown = 0 ,
|
||||
HDMI_640x480p60 = 1 ,
|
||||
HDMI_480p60,
|
||||
HDMI_480p60_16x9,
|
||||
HDMI_720p60,
|
||||
HDMI_1080i60,
|
||||
HDMI_480i60,
|
||||
HDMI_480i60_16x9,
|
||||
HDMI_1080p60 = 16,
|
||||
HDMI_576p50,
|
||||
HDMI_576p50_16x9,
|
||||
HDMI_720p50 = 19,
|
||||
HDMI_1080i50,
|
||||
HDMI_576i50,
|
||||
HDMI_576i50_16x9,
|
||||
HDMI_1080p50 = 31,
|
||||
HDMI_1080p24,
|
||||
HDMI_1080p25,
|
||||
HDMI_1080p30,
|
||||
HDMI_1080i120 = 46, // richard add
|
||||
} HDMI_Video_Type ;
|
||||
|
||||
typedef enum tagHDMI_Aspec {
|
||||
HDMI_4x3 ,
|
||||
HDMI_16x9
|
||||
} HDMI_Aspec;
|
||||
|
||||
typedef enum tagHDMI_OutputColorMode {
|
||||
HDMI_RGB444,
|
||||
HDMI_YUV444,
|
||||
HDMI_YUV422
|
||||
} HDMI_OutputColorMode ;
|
||||
|
||||
typedef enum tagHDMI_Colorimetry {
|
||||
HDMI_ITU601,
|
||||
HDMI_ITU709
|
||||
} HDMI_Colorimetry ;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Output Mode Type
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define RES_ASPEC_4x3 0
|
||||
#define RES_ASPEC_16x9 1
|
||||
#define F_MODE_REPT_NO 0
|
||||
#define F_MODE_REPT_TWICE 1
|
||||
#define F_MODE_REPT_QUATRO 3
|
||||
#define F_MODE_CSC_ITU601 0
|
||||
#define F_MODE_CSC_ITU709 1
|
||||
|
||||
void HDMITX_ChangeDisplayOption(HDMI_Video_Type VideoMode, HDMI_OutputColorMode OutputColorMode);
|
||||
void HDMITX_SetOutput();
|
||||
|
||||
|
||||
|
||||
#endif // _CAT6611_SYS_H_
|
|
@ -0,0 +1,329 @@
|
|||
#ifndef _TYPEDEF_H_
|
||||
#define _TYPEDEF_H_
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// data type
|
||||
//////////////////////////////////////////////////
|
||||
#ifdef _MCU_
|
||||
typedef bit BOOL ;
|
||||
#define _CODE //richard code
|
||||
#define _IDATA //richard idata
|
||||
#define _XDATA //richard xdata
|
||||
#else
|
||||
typedef int BOOL ;
|
||||
#define _CODE
|
||||
#define _IDATA
|
||||
#define _XDATA
|
||||
#endif // _MCU_
|
||||
|
||||
|
||||
|
||||
typedef char CHAR,*PCHAR ;
|
||||
typedef unsigned char uchar,*puchar ;
|
||||
typedef unsigned char UCHAR,*PUCHAR ;
|
||||
typedef unsigned char byte,*pbyte ;
|
||||
typedef unsigned char BYTE,*PBYTE ;
|
||||
|
||||
typedef short SHORT,*PSHORT ;
|
||||
typedef unsigned short ushort,*pushort ;
|
||||
typedef unsigned short USHORT,*PUSHORT ;
|
||||
typedef unsigned short word,*pword ;
|
||||
typedef unsigned short WORD,*PWORD ;
|
||||
|
||||
typedef long LONG,*PLONG ;
|
||||
typedef unsigned long ulong,*pulong ;
|
||||
typedef unsigned long ULONG,*PULONG ;
|
||||
typedef unsigned long dword,*pdword ;
|
||||
typedef unsigned long DWORD,*PDWORD ;
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define SUCCESS 0
|
||||
#define FAIL -1
|
||||
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
|
||||
typedef enum _SYS_STATUS {
|
||||
ER_SUCCESS = 0,
|
||||
ER_FAIL,
|
||||
ER_RESERVED
|
||||
} SYS_STATUS ;
|
||||
|
||||
#define abs(x) (((x)>=0)?(x):(-(x)))
|
||||
|
||||
|
||||
typedef enum _Video_State_Type {
|
||||
VSTATE_PwrOff = 0,
|
||||
VSTATE_SyncWait ,
|
||||
VSTATE_SWReset,
|
||||
VSTATE_SyncChecking,
|
||||
VSTATE_HDCPSet,
|
||||
VSTATE_HDCP_Reset,
|
||||
VSTATE_ModeDetecting,
|
||||
VSTATE_VideoOn,
|
||||
VSTATE_Reserved
|
||||
} Video_State_Type ;
|
||||
|
||||
|
||||
typedef enum _Audio_State_Type {
|
||||
ASTATE_AudioOff = 0,
|
||||
ASTATE_RequestAudio ,
|
||||
ASTATE_ResetAudio,
|
||||
ASTATE_WaitForReady,
|
||||
ASTATE_AudioOn ,
|
||||
ASTATE_Reserved
|
||||
} Audio_State_Type ;
|
||||
|
||||
typedef enum _TXVideo_State_Type {
|
||||
TXVSTATE_Unplug = 0,
|
||||
TXVSTATE_HPD,
|
||||
TXVSTATE_WaitForMode,
|
||||
TXVSTATE_WaitForVStable,
|
||||
TXVSTATE_VideoInit,
|
||||
TXVSTATE_VideoSetup,
|
||||
TXVSTATE_VideoOn,
|
||||
TXVSTATE_Reserved
|
||||
} TXVideo_State_Type ;
|
||||
|
||||
|
||||
typedef enum _TXAudio_State_Type {
|
||||
TXASTATE_AudioOff = 0,
|
||||
TXASTATE_AudioPrepare,
|
||||
TXASTATE_AudioOn,
|
||||
TXASTATE_AudioFIFOFail,
|
||||
TXASTATE_Reserved
|
||||
} TXAudio_State_Type ;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
PCLK_LOW = 0 ,
|
||||
PCLK_MEDIUM,
|
||||
PCLK_HIGH
|
||||
} VIDEOPCLKLEVEL ;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Video Data Type
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
#define F_MODE_RGB24 0
|
||||
#define F_MODE_RGB444 0
|
||||
#define F_MODE_YUV422 1
|
||||
#define F_MODE_YUV444 2
|
||||
#define F_MODE_CLRMOD_MASK 3
|
||||
|
||||
|
||||
#define F_MODE_INTERLACE 1
|
||||
|
||||
#define F_MODE_ITU709 (1<<4)
|
||||
#define F_MODE_ITU601 0
|
||||
|
||||
#define F_MODE_0_255 0
|
||||
#define F_MODE_16_235 (1<<5)
|
||||
|
||||
#define F_MODE_EN_UDFILT (1<<6) // output mode only,and loaded from EEPROM
|
||||
#define F_MODE_EN_DITHER (1<<7) // output mode only,and loaded from EEPROM
|
||||
|
||||
#define F_VIDMODE_ITU709 F_MODE_ITU709 // richard add
|
||||
#define F_VIDMODE_16_235 F_MODE_16_235 // richard add
|
||||
|
||||
|
||||
typedef union _VideoFormatCode
|
||||
{
|
||||
struct _VFC
|
||||
{
|
||||
BYTE colorfmt:2 ;
|
||||
BYTE interlace:1 ;
|
||||
BYTE Colorimetry:1 ;
|
||||
BYTE Quantization:1 ;
|
||||
BYTE UpDownFilter:1 ;
|
||||
BYTE Dither:1 ;
|
||||
} VFCCode ;
|
||||
unsigned char VFCByte ;
|
||||
} VideoFormatCode ;
|
||||
|
||||
#define T_MODE_CCIR656 (1<<0)
|
||||
#define T_MODE_SYNCEMB (1<<1)
|
||||
#define T_MODE_INDDR (1<<2)
|
||||
#define T_MODE_PCLKDIV2 (1<<3)
|
||||
#define T_MODE_DEGEN (1<<4)
|
||||
#define T_MODE_SYNCGEN (1<<5)
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Audio relate definition and macro.
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// for sample clock
|
||||
#define AUDFS_22p05KHz 4
|
||||
#define AUDFS_44p1KHz 0
|
||||
#define AUDFS_88p2KHz 8
|
||||
#define AUDFS_176p4KHz 12
|
||||
|
||||
#define AUDFS_24KHz 6
|
||||
#define AUDFS_48KHz 2
|
||||
#define AUDFS_96KHz 10
|
||||
#define AUDFS_192KHz 14
|
||||
|
||||
#define AUDFS_32KHz 3
|
||||
#define AUDFS_OTHER 1
|
||||
|
||||
// Audio Enable
|
||||
#define ENABLE_SPDIF (1<<4)
|
||||
#define ENABLE_I2S_SRC3 (1<<3)
|
||||
#define ENABLE_I2S_SRC2 (1<<2)
|
||||
#define ENABLE_I2S_SRC1 (1<<1)
|
||||
#define ENABLE_I2S_SRC0 (1<<0)
|
||||
|
||||
#define AUD_SWL_NOINDICATE 0x0
|
||||
#define AUD_SWL_16 0x2
|
||||
#define AUD_SWL_17 0xC
|
||||
#define AUD_SWL_18 0x4
|
||||
#define AUD_SWL_20 0xA // for maximum 20 bit
|
||||
#define AUD_SWL_21 0xD
|
||||
#define AUD_SWL_22 0x5
|
||||
#define AUD_SWL_23 0x9
|
||||
#define AUD_SWL_24 0xB
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Packet and Info Frame definition and datastructure.
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define VENDORSPEC_INFOFRAME_TYPE 0x01
|
||||
#define AVI_INFOFRAME_TYPE 0x02
|
||||
#define SPD_INFOFRAME_TYPE 0x03
|
||||
#define AUDIO_INFOFRAME_TYPE 0x04
|
||||
#define MPEG_INFOFRAME_TYPE 0x05
|
||||
|
||||
#define VENDORSPEC_INFOFRAME_VER 0x01
|
||||
#define AVI_INFOFRAME_VER 0x02
|
||||
#define SPD_INFOFRAME_VER 0x01
|
||||
#define AUDIO_INFOFRAME_VER 0x01
|
||||
#define MPEG_INFOFRAME_VER 0x01
|
||||
|
||||
#define VENDORSPEC_INFOFRAME_LEN 8
|
||||
#define AVI_INFOFRAME_LEN 13
|
||||
#define SPD_INFOFRAME_LEN 25
|
||||
#define AUDIO_INFOFRAME_LEN 10
|
||||
#define MPEG_INFOFRAME_LEN 10
|
||||
|
||||
#define ACP_PKT_LEN 9
|
||||
#define ISRC1_PKT_LEN 16
|
||||
#define ISRC2_PKT_LEN 16
|
||||
|
||||
typedef union _AVI_InfoFrame
|
||||
{
|
||||
struct {
|
||||
BYTE Type ;
|
||||
BYTE Ver ;
|
||||
BYTE Len ;
|
||||
|
||||
BYTE Scan:2 ;
|
||||
BYTE BarInfo:2 ;
|
||||
BYTE ActiveFmtInfoPresent:1 ;
|
||||
BYTE ColorMode:2 ;
|
||||
BYTE FU1:1 ;
|
||||
|
||||
BYTE ActiveFormatAspectRatio:4 ;
|
||||
BYTE PictureAspectRatio:2 ;
|
||||
BYTE Colorimetry:2 ;
|
||||
|
||||
BYTE Scaling:2 ;
|
||||
BYTE FU2:6 ;
|
||||
|
||||
BYTE VIC:7 ;
|
||||
BYTE FU3:1 ;
|
||||
|
||||
BYTE PixelRepetition:4 ;
|
||||
BYTE FU4:4 ;
|
||||
|
||||
SHORT Ln_End_Top ;
|
||||
SHORT Ln_Start_Bottom ;
|
||||
SHORT Pix_End_Left ;
|
||||
SHORT Pix_Start_Right ;
|
||||
} info ;
|
||||
struct {
|
||||
BYTE AVI_HB[3] ;
|
||||
BYTE AVI_DB[AVI_INFOFRAME_LEN] ;
|
||||
} pktbyte ;
|
||||
} AVI_InfoFrame ;
|
||||
|
||||
typedef union _Audio_InfoFrame {
|
||||
|
||||
struct {
|
||||
BYTE Type ;
|
||||
BYTE Ver ;
|
||||
BYTE Len ;
|
||||
|
||||
BYTE AudioChannelCount:3 ;
|
||||
BYTE RSVD1:1 ;
|
||||
BYTE AudioCodingType:4 ;
|
||||
|
||||
BYTE SampleSize:2 ;
|
||||
BYTE SampleFreq:3 ;
|
||||
BYTE Rsvd2:3 ;
|
||||
|
||||
BYTE FmtCoding ;
|
||||
|
||||
BYTE SpeakerPlacement ;
|
||||
|
||||
BYTE Rsvd3:3 ;
|
||||
BYTE LevelShiftValue:4 ;
|
||||
BYTE DM_INH:1 ;
|
||||
} info ;
|
||||
|
||||
struct {
|
||||
BYTE AUD_HB[3] ;
|
||||
BYTE AUD_DB[AUDIO_INFOFRAME_LEN] ;
|
||||
} pktbyte ;
|
||||
|
||||
} Audio_InfoFrame ;
|
||||
|
||||
typedef union _MPEG_InfoFrame {
|
||||
struct {
|
||||
BYTE Type ;
|
||||
BYTE Ver ;
|
||||
BYTE Len ;
|
||||
|
||||
ULONG MpegBitRate ;
|
||||
|
||||
BYTE MpegFrame:2 ;
|
||||
BYTE Rvsd1:2 ;
|
||||
BYTE FieldRepeat:1 ;
|
||||
BYTE Rvsd2:3 ;
|
||||
} info ;
|
||||
struct {
|
||||
BYTE MPG_HB[3] ;
|
||||
BYTE MPG_DB[MPEG_INFOFRAME_LEN] ;
|
||||
} pktbyte ;
|
||||
} MPEG_InfoFrame ;
|
||||
|
||||
// Source Product Description
|
||||
typedef union _SPD_InfoFrame {
|
||||
struct {
|
||||
BYTE Type ;
|
||||
BYTE Ver ;
|
||||
BYTE Len ;
|
||||
|
||||
char VN[8] ; // vendor name character in 7bit ascii characters
|
||||
char PD[16] ; // product description character in 7bit ascii characters
|
||||
BYTE SourceDeviceInfomation ;
|
||||
} info ;
|
||||
struct {
|
||||
BYTE SPD_HB[3] ;
|
||||
BYTE SPD_DB[SPD_INFOFRAME_LEN] ;
|
||||
} pktbyte ;
|
||||
} SPD_InfoFrame ;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Using for interface.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct VideoTiming {
|
||||
ULONG VideoPixelClock ;
|
||||
BYTE VIC ;
|
||||
BYTE pixelrep ;
|
||||
BYTE outputVideoMode ;
|
||||
} ;
|
||||
|
||||
#endif // _TYPEDEF_H_
|
|
@ -0,0 +1 @@
|
|||
:00000001FF
|
|
@ -0,0 +1 @@
|
|||
set_global_assignment -name SEARCH_PATH $::quartus(qip_path)
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simPackage>
|
||||
<file path="hdl_sim/sys_onchip_memory2_0.dat" type="DAT" initParamName="INIT_FILE" memoryPath="onchip_memory2_0" />
|
||||
<file path="epcq_controller_0.hex" type="HEX" memoryPath="epcq_controller_0" />
|
||||
<file path="sys_onchip_memory2_0.hex" type="HEX" initParamName="INIT_FILE" memoryPath="onchip_memory2_0" />
|
||||
</simPackage>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,108 @@
|
|||
//
|
||||
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include "lcd.h"
|
||||
#include "alt_types.h"
|
||||
#include "altera_avalon_pio_regs.h"
|
||||
|
||||
#define LCD_CMD 0x00
|
||||
#define LCD_DATA 0x40
|
||||
|
||||
#define WRDELAY 20
|
||||
#define CLEARDELAY 800
|
||||
|
||||
void lcd_init() {
|
||||
alt_u8 lcd_ctrl = 0x00;
|
||||
IOWR_ALTERA_AVALON_PIO_DATA(PIO_5_BASE, lcd_ctrl);
|
||||
usleep(WRDELAY);
|
||||
|
||||
SPI_write(I2CA_BASE, 0x38); // function set
|
||||
usleep(WRDELAY);
|
||||
SPI_write(I2CA_BASE, 0x39); // function set, select extended table (IS=1)
|
||||
usleep(WRDELAY);
|
||||
SPI_write(I2CA_BASE, 0x14); // osc freq
|
||||
usleep(WRDELAY);
|
||||
SPI_write(I2CA_BASE, 0x71); // contrast set
|
||||
usleep(WRDELAY);
|
||||
SPI_write(I2CA_BASE, 0x5E); // power/icon/cont
|
||||
usleep(WRDELAY);
|
||||
SPI_write(I2CA_BASE, 0x6D); // follower control
|
||||
usleep(WRDELAY);
|
||||
SPI_write(I2CA_BASE, 0x0C); // display on
|
||||
usleep(WRDELAY);
|
||||
SPI_write(I2CA_BASE, 0x01); // clear display
|
||||
usleep(CLEARDELAY);
|
||||
SPI_write(I2CA_BASE, 0x06); // entry mode set
|
||||
usleep(WRDELAY);
|
||||
SPI_write(I2CA_BASE, 0x02); // return home
|
||||
usleep(CLEARDELAY);
|
||||
|
||||
lcd_ctrl |= LCD_CS_N;
|
||||
IOWR_ALTERA_AVALON_PIO_DATA(PIO_5_BASE, lcd_ctrl);
|
||||
}
|
||||
|
||||
void lcd_write(char *row1, char *row2) {
|
||||
alt_u8 i, rowlen;
|
||||
alt_u8 lcd_ctrl = 0x00;
|
||||
|
||||
IOWR_ALTERA_AVALON_PIO_DATA(PIO_5_BASE, lcd_ctrl);
|
||||
|
||||
SPI_write(I2CA_BASE, 0x01); // clear display
|
||||
usleep(CLEARDELAY);
|
||||
|
||||
// Set RS to enter data write mode
|
||||
lcd_ctrl |= LCD_RS;
|
||||
IOWR_ALTERA_AVALON_PIO_DATA(PIO_5_BASE, lcd_ctrl);
|
||||
|
||||
//ensure no empty row
|
||||
rowlen = strnlen(row1, LCD_ROW_LEN);
|
||||
if (rowlen == 0) {
|
||||
strncpy(row1, " ", LCD_ROW_LEN+1);
|
||||
rowlen++;
|
||||
}
|
||||
|
||||
for (i=0; i<rowlen; i++) {
|
||||
SPI_write(I2CA_BASE, row1[i]);
|
||||
usleep(WRDELAY);
|
||||
}
|
||||
|
||||
// second row
|
||||
lcd_ctrl &= ~LCD_RS;
|
||||
IOWR_ALTERA_AVALON_PIO_DATA(PIO_5_BASE, lcd_ctrl);
|
||||
SPI_write(I2CA_BASE, (1<<7)|0x40);
|
||||
usleep(WRDELAY);
|
||||
|
||||
lcd_ctrl |= LCD_RS;
|
||||
IOWR_ALTERA_AVALON_PIO_DATA(PIO_5_BASE, lcd_ctrl);
|
||||
|
||||
//ensure no empty row
|
||||
rowlen = strnlen(row2, LCD_ROW_LEN);
|
||||
if (rowlen == 0) {
|
||||
strncpy(row2, " ", LCD_ROW_LEN+1);
|
||||
rowlen++;
|
||||
}
|
||||
|
||||
for (i=0; i<rowlen; i++) {
|
||||
SPI_write(I2CA_BASE, row2[i]);
|
||||
usleep(WRDELAY);
|
||||
}
|
||||
|
||||
lcd_ctrl |= LCD_CS_N;
|
||||
IOWR_ALTERA_AVALON_PIO_DATA(PIO_5_BASE, lcd_ctrl);
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
//
|
||||
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#ifndef LCD_H_
|
||||
#define LCD_H_
|
||||
|
||||
#include "system.h"
|
||||
#include <stdio.h>
|
||||
#include "sysconfig.h"
|
||||
|
||||
#define LCD_ROW_LEN 16
|
||||
|
||||
//#define I2C_DEBUG
|
||||
#define I2CA_BASE I2C_OPENCORES_0_BASE
|
||||
|
||||
#define LCD_CS_N (1<<0)
|
||||
#define LCD_RS (1<<1)
|
||||
|
||||
void lcd_init();
|
||||
|
||||
void lcd_write(char *row1, char *row2);
|
||||
|
||||
#endif /* LCD_H_ */
|
|
@ -0,0 +1,34 @@
|
|||
//
|
||||
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#ifndef SYSCONFIG_H_
|
||||
#define SYSCONFIG_H_
|
||||
|
||||
#ifndef DEBUG
|
||||
#define OS_PRINTF(...)
|
||||
#define ErrorF(...)
|
||||
#define printf(...)
|
||||
#else
|
||||
#define OS_PRINTF printf
|
||||
#define ErrorF printf
|
||||
// use reduced printf
|
||||
//#define printf alt_printf
|
||||
#endif
|
||||
|
||||
#endif /* SYSCONFIG_H_ */
|
|
@ -0,0 +1,81 @@
|
|||
//
|
||||
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "system.h"
|
||||
#include "altera_avalon_pio_regs.h"
|
||||
#include "i2c_opencores.h"
|
||||
#include "ths7353.h"
|
||||
|
||||
inline alt_u32 ths_readreg(alt_u8 channel) {
|
||||
//Phase 1
|
||||
I2C_start(I2CA_BASE, THS_BASE, 0);
|
||||
I2C_write(I2CA_BASE, channel, 1);
|
||||
|
||||
//Phase 2
|
||||
I2C_start(I2CA_BASE, THS_BASE, 1);
|
||||
return I2C_read(I2CA_BASE,1);
|
||||
}
|
||||
|
||||
inline void ths_writereg(alt_u8 channel, alt_u8 data) {
|
||||
I2C_start(I2CA_BASE, THS_BASE, 0);
|
||||
I2C_write(I2CA_BASE, channel, 0);
|
||||
I2C_write(I2CA_BASE, data, 1);
|
||||
}
|
||||
|
||||
int ths_init() {
|
||||
//Avoid random FIFO state (see datasheet p.37)
|
||||
I2C_write(I2CA_BASE, 0x00, 0);
|
||||
usleep(10);
|
||||
|
||||
//Initialize all channels
|
||||
ths_writereg(THS_CH1, (THS_LPF_DEFAULT<<THS_LPF_OFFS));
|
||||
ths_writereg(THS_CH2, (THS_LPF_DEFAULT<<THS_LPF_OFFS));
|
||||
ths_writereg(THS_CH3, (THS_LPF_DEFAULT<<THS_LPF_OFFS));
|
||||
|
||||
return (ths_readreg(THS_CH1) == (THS_LPF_DEFAULT<<THS_LPF_OFFS));
|
||||
}
|
||||
|
||||
void ths_set_lpf(alt_u8 val) {
|
||||
alt_u8 status = ths_readreg(THS_CH1) & ~THS_LPF_MASK;
|
||||
status |= (val<<THS_LPF_OFFS);
|
||||
|
||||
ths_writereg(THS_CH1, status);
|
||||
ths_writereg(THS_CH2, status);
|
||||
ths_writereg(THS_CH3, status);
|
||||
printf("THS LPF value set to 0x%x\n", val);
|
||||
}
|
||||
|
||||
void ths_source_sel(ths_input_t input, alt_u8 lpf) {
|
||||
alt_u8 status = ths_readreg(THS_CH1) & ~(THS_SRC_MASK|THS_MODE_MASK);
|
||||
//alt_u8 status = 0x00;
|
||||
|
||||
if (input == THS_STANDBY)
|
||||
status |= (THS_MODE_AVMUTE<<THS_MODE_OFFS);
|
||||
else
|
||||
status |= (THS_MODE_AC_BIAS | (input<<THS_SRC_OFFS));
|
||||
|
||||
//status |= (lpf<<THS_LPF_OFFS);
|
||||
|
||||
ths_writereg(THS_CH1, status);
|
||||
ths_writereg(THS_CH2, status);
|
||||
ths_writereg(THS_CH3, status);
|
||||
printf("THS source set to %u\n", input);
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
//
|
||||
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#ifndef THS7353_H_
|
||||
#define THS7353_H_
|
||||
|
||||
#include "sysconfig.h"
|
||||
|
||||
#define THS_BASE (0x58>>1)
|
||||
|
||||
#define THS_CH1 0x01
|
||||
#define THS_CH2 0x02
|
||||
#define THS_CH3 0x03
|
||||
|
||||
typedef enum {
|
||||
THS_INPUT_A = 0,
|
||||
THS_INPUT_B = 1,
|
||||
THS_STANDBY = 2
|
||||
} ths_input_t;
|
||||
|
||||
#define THS_LPF_DEFAULT 0x3
|
||||
#define THS_LPF_MASK 0x18
|
||||
#define THS_LPF_OFFS 3
|
||||
|
||||
#define THS_SRC_MASK 0x20
|
||||
#define THS_SRC_OFFS 5
|
||||
|
||||
#define THS_MODE_MASK 0x7
|
||||
#define THS_MODE_OFFS 0
|
||||
|
||||
#define THS_MODE_DISABLE 0
|
||||
#define THS_MODE_AVMUTE 1
|
||||
#define THS_MODE_AC_BIAS 4
|
||||
#define THS_MODE_STC 6 //mid bias
|
||||
|
||||
#define THS_LPF_BYPASS 0x03
|
||||
|
||||
//#define I2C_DEBUG
|
||||
#define I2CA_BASE I2C_OPENCORES_0_BASE
|
||||
|
||||
int ths_init();
|
||||
|
||||
void ths_set_lpf(alt_u8 val);
|
||||
|
||||
void ths_source_sel(ths_input_t input, alt_u8 lpf);
|
||||
|
||||
#endif /* THS7353_H_ */
|
|
@ -0,0 +1,401 @@
|
|||
//
|
||||
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "system.h"
|
||||
#include "altera_avalon_pio_regs.h"
|
||||
#include "i2c_opencores.h"
|
||||
#include "tvp7002.h"
|
||||
|
||||
//#define SYNCBYPASS // Bypass VGA syncs (for debug - needed for interlace?)
|
||||
//#define EXTADCCLK // Use external ADC clock (external osc)
|
||||
//#define ADCPOWERDOWN // Power-down ADCs
|
||||
//#define PLLPOSTDIV // Double-rate PLL with div-by-2 (decrease jitter?)
|
||||
|
||||
/* Y'Pb'Pr' to R'G'B' CSC coefficients.
|
||||
*
|
||||
* Coefficients from "Colour Space Conversions" (http://www.poynton.com/PDFs/coloureq.pdf).
|
||||
*/
|
||||
const ypbpr_to_rgb_csc_t csc_coeffs[] = {
|
||||
{ "Rec. 601", 0x2000, 0x0000, 0x2CE5, 0x2000, 0xF4FD, 0xE926, 0x2000, 0x38BC, 0x0000 }, // eq. 101
|
||||
{ "Rec. 709", 0x2000, 0x0000, 0x323E, 0x2000, 0xFA04, 0xF113, 0x2000, 0x3B61, 0x0000 }, // eq. 105
|
||||
};
|
||||
|
||||
extern mode_data_t video_modes[];
|
||||
|
||||
static inline void tvp_set_hpllcoast(alt_u8 pre, alt_u8 post) {
|
||||
tvp_writereg(TVP_HPLLPRECOAST, pre);
|
||||
tvp_writereg(TVP_HPLLPOSTCOAST, post);
|
||||
}
|
||||
|
||||
static inline void tvp_set_ssthold(alt_u8 vsdetect_thold) {
|
||||
tvp_writereg(TVP_SSTHOLD, vsdetect_thold);
|
||||
}
|
||||
|
||||
static void tvp_set_clamp(video_format fmt) {
|
||||
switch (fmt) {
|
||||
case FORMAT_RGBS:
|
||||
case FORMAT_RGBHV:
|
||||
case FORMAT_RGsB:
|
||||
//select bottom clamp (RGB)
|
||||
tvp_writereg(TVP_SOGTHOLD, 0x58);
|
||||
break;
|
||||
case FORMAT_YPbPr:
|
||||
//select mid clamp for Pb & Pr
|
||||
tvp_writereg(TVP_SOGTHOLD, 0x5D);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void tvp_set_clamp_position(video_type type) {
|
||||
switch (type) {
|
||||
case VIDEO_LDTV:
|
||||
tvp_writereg(TVP_CLAMPSTART, 0x2);
|
||||
tvp_writereg(TVP_CLAMPWIDTH, 0x6);
|
||||
break;
|
||||
case VIDEO_SDTV:
|
||||
case VIDEO_EDTV:
|
||||
case VIDEO_PC:
|
||||
tvp_writereg(TVP_CLAMPSTART, 0x6);
|
||||
tvp_writereg(TVP_CLAMPWIDTH, 0x10);
|
||||
break;
|
||||
case VIDEO_HDTV:
|
||||
tvp_writereg(TVP_CLAMPSTART, 0x32);
|
||||
tvp_writereg(TVP_CLAMPWIDTH, 0x20);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void tvp_set_alc(video_type type) {
|
||||
//disable ALC
|
||||
//tvp_writereg(TVP_ALCEN, 0x00);
|
||||
//tvp_writereg(TVP_ALCEN, 0x80);
|
||||
|
||||
//set analog (coarse) gain to max recommended value (-> 91% of the ADC range with 0.7Vpp input)
|
||||
tvp_writereg(TVP_BG_CGAIN, 0x88);
|
||||
tvp_writereg(TVP_R_CGAIN, 0x08);
|
||||
|
||||
//set rest of the gain digitally (fine) to utilize 100% of the range at the output (0.91*(1+(26/256)) = 1)
|
||||
tvp_writereg(TVP_R_FGAIN, 26);
|
||||
tvp_writereg(TVP_G_FGAIN, 26);
|
||||
tvp_writereg(TVP_B_FGAIN, 26);
|
||||
|
||||
//select ALC placement
|
||||
switch (type) {
|
||||
case VIDEO_LDTV:
|
||||
tvp_writereg(TVP_ALCPLACE, 0x9);
|
||||
break;
|
||||
case VIDEO_SDTV:
|
||||
case VIDEO_EDTV:
|
||||
case VIDEO_PC:
|
||||
tvp_writereg(TVP_ALCPLACE, 0x18);
|
||||
break;
|
||||
case VIDEO_HDTV:
|
||||
tvp_writereg(TVP_ALCPLACE, 0x5A);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline alt_u32 tvp_readreg(alt_u32 regaddr) {
|
||||
I2C_start(I2CA_BASE, TVP_BASE, 0);
|
||||
I2C_write(I2CA_BASE, regaddr, 1); //don't use repeated start as it seems unreliable at 400kHz
|
||||
I2C_start(I2CA_BASE, TVP_BASE, 1);
|
||||
return I2C_read(I2CA_BASE,1);
|
||||
}
|
||||
|
||||
inline void tvp_writereg(alt_u32 regaddr, alt_u8 data) {
|
||||
I2C_start(I2CA_BASE, TVP_BASE, 0);
|
||||
I2C_write(I2CA_BASE, regaddr, 0);
|
||||
I2C_write(I2CA_BASE, data, 1);
|
||||
}
|
||||
|
||||
inline void tvp_reset() {
|
||||
usleep(10000);
|
||||
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, 0x00);
|
||||
usleep(10000);
|
||||
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, 0x01);
|
||||
usleep(10000);
|
||||
}
|
||||
|
||||
inline void tvp_disable_output() {
|
||||
usleep(10000);
|
||||
tvp_writereg(TVP_MISCCTRL1, 0x13);
|
||||
usleep(10000);
|
||||
tvp_writereg(TVP_MISCCTRL2, 0x03);
|
||||
usleep(10000);
|
||||
}
|
||||
|
||||
inline void tvp_enable_output() {
|
||||
usleep(10000);
|
||||
tvp_writereg(TVP_MISCCTRL1, 0x11);
|
||||
usleep(10000);
|
||||
tvp_writereg(TVP_MISCCTRL2, 0x02);
|
||||
usleep(10000);
|
||||
}
|
||||
|
||||
void tvp_init() {
|
||||
// disable output
|
||||
tvp_disable_output();
|
||||
|
||||
//Set global defaults
|
||||
|
||||
// Hsync input->output delay (horizontal shift)
|
||||
// Default is 13, which maintains alignment of RGB and hsync at output
|
||||
//tvp_writereg(TVP_HSOUTSTART, 0);
|
||||
|
||||
// Hsync edge->Vsync edge delay
|
||||
tvp_writereg(TVP_VSOUTALIGN, 0);
|
||||
|
||||
// Set default CSC coeffs.
|
||||
tvp_sel_csc(&csc_coeffs[0]);
|
||||
|
||||
// Set default phase
|
||||
tvp_set_hpll_phase(0x10);
|
||||
|
||||
// Set min LPF
|
||||
tvp_set_lpf(0);
|
||||
tvp_set_sync_lpf(0);
|
||||
|
||||
// Increase line length tolerance
|
||||
tvp_writereg(TVP_LINELENTOL, 0x06);
|
||||
|
||||
// Common sync separator threshold
|
||||
// Some arcade games need more that the default 0x40
|
||||
tvp_set_ssthold(0x44);
|
||||
}
|
||||
|
||||
// Configure H-PLL (sampling rate, VCO gain and charge pump current)
|
||||
void tvp_setup_hpll(alt_u16 h_samplerate, alt_u16 v_lines, alt_u8 hz, alt_u8 plldivby2) {
|
||||
alt_u32 pclk_est;
|
||||
alt_u8 vco_range;
|
||||
alt_u8 cp_current;
|
||||
|
||||
alt_u8 status = tvp_readreg(TVP_HPLLPHASE) & 0xF8;
|
||||
|
||||
// Enable PLL post-div-by-2 with double samplerate
|
||||
if (plldivby2) {
|
||||
tvp_writereg(TVP_HPLLPHASE, status|1);
|
||||
h_samplerate = 2*h_samplerate;
|
||||
} else {
|
||||
tvp_writereg(TVP_HPLLPHASE, status);
|
||||
}
|
||||
|
||||
tvp_writereg(TVP_HPLLDIV_MSB, (h_samplerate >> 4));
|
||||
tvp_writereg(TVP_HPLLDIV_LSB, ((h_samplerate & 0xf) << 4));
|
||||
|
||||
printf("Horizontal samplerate set to %u\n", h_samplerate);
|
||||
|
||||
pclk_est = ((alt_u32)h_samplerate * v_lines * hz) / 1000; //in kHz
|
||||
|
||||
printf("Estimated PCLK: %u.%.3u MHz\n", pclk_est/1000, pclk_est%1000);
|
||||
|
||||
if (pclk_est < 36000) {
|
||||
vco_range = 0;
|
||||
} else if (pclk_est < 70000) {
|
||||
vco_range = 1;
|
||||
} else if (pclk_est < 135000) {
|
||||
vco_range = 2;
|
||||
} else {
|
||||
vco_range = 3;
|
||||
}
|
||||
|
||||
cp_current = (40*Kvco[vco_range]+h_samplerate/2) / h_samplerate; //"+h_samplerate/2" for fast rounding
|
||||
|
||||
printf("VCO range: %s\nCPC: %u\n", Kvco_str[vco_range], cp_current);
|
||||
tvp_writereg(TVP_HPLLCTRL, ((vco_range << 6) | (cp_current << 3)));
|
||||
}
|
||||
|
||||
void tvp_sel_clk(alt_u8 refclk) {
|
||||
alt_u8 status = tvp_readreg(TVP_INPMUX2) & 0xFA;
|
||||
|
||||
//TODO: set SOG and CLP LPF based on mode
|
||||
if (refclk == REFCLK_INTCLK) {
|
||||
tvp_writereg(TVP_INPMUX2, status|0x2);
|
||||
} else {
|
||||
#ifdef EXTADCCLK
|
||||
tvp_writereg(TVP_INPMUX2, status|0x8);
|
||||
#else
|
||||
tvp_writereg(TVP_INPMUX2, status|0xA);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void tvp_sel_csc(ypbpr_to_rgb_csc_t *csc) {
|
||||
tvp_writereg(TVP_CSC1HI, (csc->G_Y >> 8));
|
||||
tvp_writereg(TVP_CSC1LO, (csc->G_Y & 0xff));
|
||||
tvp_writereg(TVP_CSC2HI, (csc->G_Pb >> 8));
|
||||
tvp_writereg(TVP_CSC2LO, (csc->G_Pb & 0xff));
|
||||
tvp_writereg(TVP_CSC3HI, (csc->G_Pr >> 8));
|
||||
tvp_writereg(TVP_CSC3LO, (csc->G_Pr & 0xff));
|
||||
|
||||
tvp_writereg(TVP_CSC4HI, (csc->R_Y >> 8));
|
||||
tvp_writereg(TVP_CSC4LO, (csc->R_Y & 0xff));
|
||||
tvp_writereg(TVP_CSC5HI, (csc->R_Pb >> 8));
|
||||
tvp_writereg(TVP_CSC5LO, (csc->R_Pb & 0xff));
|
||||
tvp_writereg(TVP_CSC6HI, (csc->R_Pr >> 8));
|
||||
tvp_writereg(TVP_CSC6LO, (csc->R_Pr & 0xff));
|
||||
|
||||
tvp_writereg(TVP_CSC7HI, (csc->B_Y >> 8));
|
||||
tvp_writereg(TVP_CSC7LO, (csc->B_Y & 0xff));
|
||||
tvp_writereg(TVP_CSC8HI, (csc->B_Pb >> 8));
|
||||
tvp_writereg(TVP_CSC8LO, (csc->B_Pb & 0xff));
|
||||
tvp_writereg(TVP_CSC9HI, (csc->B_Pr >> 8));
|
||||
tvp_writereg(TVP_CSC9LO, (csc->B_Pr & 0xff));
|
||||
}
|
||||
|
||||
void tvp_set_lpf(alt_u8 val) {
|
||||
alt_u8 status = tvp_readreg(TVP_VIDEOBWLIM) & 0xF0;
|
||||
tvp_writereg(TVP_VIDEOBWLIM, status|val);
|
||||
printf("TVP LPF value set to 0x%x\n", val);
|
||||
}
|
||||
|
||||
void tvp_set_sync_lpf(alt_u8 val) {
|
||||
alt_u8 status = tvp_readreg(TVP_INPMUX2) & 0x3F;
|
||||
tvp_writereg(TVP_INPMUX2, status|((3-val)<<6));
|
||||
printf("Sync LPF value set to 0x%x\n", (3-val));
|
||||
}
|
||||
|
||||
void tvp_set_hpll_phase(alt_u8 val) {
|
||||
alt_u8 status = tvp_readreg(TVP_HPLLPHASE) & 0x07;
|
||||
tvp_writereg(TVP_HPLLPHASE, (val<<3)|status);
|
||||
printf("Phase value set to 0x%x\n", val);
|
||||
}
|
||||
|
||||
void tvp_source_setup(alt_8 modeid, video_type type, alt_u32 vlines, alt_u8 hz, alt_u8 refclk) {
|
||||
// Configure clock settings
|
||||
tvp_sel_clk(refclk);
|
||||
|
||||
// Clamp position and ALC
|
||||
tvp_set_clamp_position(type);
|
||||
tvp_set_alc(type);
|
||||
|
||||
// Macrovision enable/disable, coast disable for RGBHV.
|
||||
// Coast needs to be enabled when HSYNC is missing during VSYNC. Valid only for RGBHV?
|
||||
// Macrovision should be enabled when serration pulses etc. present, so disable only for RGBHV.
|
||||
switch (type) {
|
||||
case VIDEO_PC:
|
||||
//tvp_writereg(TVP_MISCCTRL4, 0x04);
|
||||
tvp_writereg(TVP_MISCCTRL4, 0x0C);
|
||||
tvp_writereg(TVP_MVSWIDTH, 0x03);
|
||||
break;
|
||||
case VIDEO_HDTV:
|
||||
tvp_writereg(TVP_MISCCTRL4, 0x08);
|
||||
tvp_writereg(TVP_MVSWIDTH, 0x0E);
|
||||
break;
|
||||
case VIDEO_LDTV:
|
||||
case VIDEO_SDTV:
|
||||
case VIDEO_EDTV:
|
||||
tvp_writereg(TVP_MISCCTRL4, 0x08);
|
||||
tvp_writereg(TVP_MVSWIDTH, 0x88); // TODO: check mode
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
tvp_setup_hpll(video_modes[modeid].h_total, vlines, hz, !!(video_modes[modeid].flags & MODE_PLLDIVBY2));
|
||||
|
||||
//Long coast may lead to PLL frequency drift and sync loss (e.g. SNES)
|
||||
/*if (video_modes[modeid].v_active < 720)
|
||||
tvp_set_hpllcoast(3, 3);
|
||||
else*/
|
||||
tvp_set_hpllcoast(1, 0);
|
||||
|
||||
// Hsync output width
|
||||
tvp_writereg(TVP_HSOUTWIDTH, video_modes[modeid].h_synclen);
|
||||
}
|
||||
|
||||
void tvp_source_sel(tvp_input_t input, video_format fmt, alt_u8 refclk) {
|
||||
alt_u8 sync_status;
|
||||
alt_u8 sog_ch;
|
||||
|
||||
if ((fmt == FORMAT_RGsB) || (fmt == FORMAT_YPbPr))
|
||||
sog_ch = (input == TVP_INPUT3) ? 2 : 0;
|
||||
else if ((input == TVP_INPUT1) && (fmt == FORMAT_RGBS))
|
||||
sog_ch = 1;
|
||||
else
|
||||
sog_ch = 2;
|
||||
|
||||
// RGB+SOG input select
|
||||
tvp_writereg(TVP_INPMUX1, (sog_ch<<6) | (input<<4) | (input<<2) | input);
|
||||
|
||||
// Configure clock settings
|
||||
tvp_sel_clk(refclk);
|
||||
|
||||
// Clamp setup
|
||||
tvp_set_clamp(fmt);
|
||||
|
||||
// HV/SOG sync select
|
||||
if ((input == TVP_INPUT3) && (fmt != FORMAT_RGsB)) {
|
||||
if (fmt == FORMAT_RGBHV)
|
||||
tvp_writereg(TVP_SYNCCTRL1, 0x52);
|
||||
else // RGBS
|
||||
tvp_writereg(TVP_SYNCCTRL1, 0x53);
|
||||
|
||||
sync_status = tvp_readreg(TVP_SYNCSTAT);
|
||||
if (sync_status & (1<<7))
|
||||
printf("%s detected, %s polarity\n", (sync_status & (1<<3)) ? "Csync" : "Hsync", (sync_status & (1<<5)) ? "pos" : "neg");
|
||||
if (sync_status & (1<<4))
|
||||
printf("Vsync detected, %s polarity\n", (sync_status & (1<<2)) ? "pos" : "neg");
|
||||
} else {
|
||||
tvp_writereg(TVP_SYNCCTRL1, 0x5B);
|
||||
sync_status = tvp_readreg(TVP_SYNCSTAT);
|
||||
if (sync_status & (1<<1))
|
||||
printf("SOG detected\n");
|
||||
else
|
||||
printf("SOG not detected\n");
|
||||
}
|
||||
|
||||
// Enable CSC for YPbPr
|
||||
if (fmt == FORMAT_YPbPr)
|
||||
tvp_writereg(TVP_MISCCTRL3, 0x10);
|
||||
else
|
||||
tvp_writereg(TVP_MISCCTRL3, 0x00);
|
||||
|
||||
#ifdef SYNCBYPASS
|
||||
tvp_writereg(TVP_SYNCBYPASS, 0x03);
|
||||
#else
|
||||
tvp_writereg(TVP_SYNCBYPASS, 0x00);
|
||||
#endif
|
||||
|
||||
//TODO:
|
||||
//clamps
|
||||
//TVP_ADCSETUP
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
alt_u8 tvp_check_sync(tvp_input_t input) {
|
||||
alt_u8 sync_status;
|
||||
|
||||
sync_status = tvp_readreg(TVP_SYNCSTAT);
|
||||
|
||||
if (input == TVP_INPUT3)
|
||||
return !!((sync_status & 0x98) > 0x80);
|
||||
//return !!((sync_status & 0x90) == 0x90);
|
||||
else
|
||||
return !!(sync_status & (1<<1));
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
//
|
||||
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#ifndef TVP7002_H_
|
||||
#define TVP7002_H_
|
||||
|
||||
#include "tvp7002_regs.h"
|
||||
#include "video_modes.h"
|
||||
#include "sysconfig.h"
|
||||
|
||||
//#define I2C_DEBUG
|
||||
#define I2CA_BASE I2C_OPENCORES_0_BASE
|
||||
|
||||
typedef enum {
|
||||
TVP_INPUT1 = 0,
|
||||
TVP_INPUT2 = 1,
|
||||
TVP_INPUT3 = 2
|
||||
} tvp_input_t;
|
||||
|
||||
static const alt_u8 Kvco[] = {75, 85, 150, 200};
|
||||
static const char *Kvco_str[] = { "Ultra low", "Low", "Medium", "High" };
|
||||
|
||||
typedef enum {
|
||||
REFCLK_EXT27 = 0,
|
||||
REFCLK_INTCLK = 1
|
||||
} tvp_refclk_t;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
alt_u16 R_Y;
|
||||
alt_u16 R_Pb;
|
||||
alt_u16 R_Pr;
|
||||
alt_u16 G_Y;
|
||||
alt_u16 G_Pb;
|
||||
alt_u16 G_Pr;
|
||||
alt_u16 B_Y;
|
||||
alt_u16 B_Pb;
|
||||
alt_u16 B_Pr;
|
||||
} ypbpr_to_rgb_csc_t;
|
||||
|
||||
static const alt_u32 clkrate[] = {27000000, 6500000}; //in MHz
|
||||
|
||||
|
||||
inline alt_u32 tvp_readreg(alt_u32 regaddr);
|
||||
|
||||
inline void tvp_writereg(alt_u32 regaddr, alt_u8 data);
|
||||
|
||||
inline void tvp_reset();
|
||||
|
||||
inline void tvp_disable_output();
|
||||
|
||||
inline void tvp_enable_output();
|
||||
|
||||
void tvp_init();
|
||||
|
||||
void tvp_setup_hpll(alt_u16 h_samplerate, alt_u16 v_lines, alt_u8 hz, alt_u8 plldivby2);
|
||||
|
||||
void tvp_sel_clk(alt_u8 refclk);
|
||||
|
||||
void tvp_sel_csc(ypbpr_to_rgb_csc_t *csc);
|
||||
|
||||
void tvp_set_lpf(alt_u8 val);
|
||||
|
||||
void tvp_set_sync_lpf(alt_u8 val);
|
||||
|
||||
void tvp_set_hpll_phase(alt_u8 val);
|
||||
|
||||
void tvp_source_setup(alt_8 modeid, video_type type, alt_u32 vlines, alt_u8 hz, alt_u8 refclk);
|
||||
|
||||
void tvp_source_sel(tvp_input_t input, video_format fmt, alt_u8 refclk);
|
||||
|
||||
alt_u8 tvp_check_sync(tvp_input_t input);
|
||||
|
||||
#endif /* TVP7002_H_ */
|
|
@ -0,0 +1,117 @@
|
|||
//
|
||||
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#ifndef TVP7002_REGS_H_
|
||||
#define TVP7002_REGS_H_
|
||||
|
||||
#define TVP_BASE (0xB8>>1)
|
||||
|
||||
#define TVP_CHIPREV 0x00
|
||||
#define TVP_HPLLDIV_MSB 0x01
|
||||
#define TVP_HPLLDIV_LSB 0x02
|
||||
#define TVP_HPLLCTRL 0x03
|
||||
#define TVP_HPLLPHASE 0x04
|
||||
#define TVP_CLAMPSTART 0x05
|
||||
#define TVP_CLAMPWIDTH 0x06
|
||||
#define TVP_HSOUTWIDTH 0x07
|
||||
#define TVP_B_FGAIN 0x08
|
||||
#define TVP_G_FGAIN 0x09
|
||||
#define TVP_R_FGAIN 0x0A
|
||||
#define TVP_B_FOFFSET_MSB 0x0B
|
||||
#define TVP_G_FOFFSET_MSB 0x0C
|
||||
#define TVP_R_FOFFSET_MSB 0x0D
|
||||
#define TVP_SYNCCTRL1 0x0E
|
||||
#define TVP_HPLLCTRL2 0x0F
|
||||
|
||||
#define TVP_SOGTHOLD 0x10
|
||||
#define TVP_SSTHOLD 0x11
|
||||
#define TVP_HPLLPRECOAST 0x12
|
||||
#define TVP_HPLLPOSTCOAST 0x13
|
||||
#define TVP_SYNCSTAT 0x14
|
||||
#define TVP_OUTFORMAT 0x15
|
||||
#define TVP_MISCCTRL1 0x16
|
||||
#define TVP_MISCCTRL2 0x17
|
||||
#define TVP_MISCCTRL3 0x18
|
||||
#define TVP_INPMUX1 0x19
|
||||
#define TVP_INPMUX2 0x1A
|
||||
#define TVP_BG_CGAIN 0x1B
|
||||
#define TVP_R_CGAIN 0x1C
|
||||
#define TVP_FOFFSET_LSB 0x1D
|
||||
#define TVP_B_COFFSET 0x1E
|
||||
#define TVP_G_COFFSET 0x1F
|
||||
|
||||
#define TVP_R_COFFSET 0x20
|
||||
#define TVP_HSOUTSTART 0x21
|
||||
#define TVP_MISCCTRL4 0x22
|
||||
#define TVP_B_ALCOUT_LSB 0x23
|
||||
#define TVP_G_ALCOUT_LSB 0x24
|
||||
#define TVP_R_ALCOUT_LSB 0x25
|
||||
#define TVP_ALCEN 0x26
|
||||
#define TVP_ALCOUT_MSB 0x27
|
||||
#define TVP_ALCFILT 0x28
|
||||
#define TVP_FCLAMPCTRL 0x2A
|
||||
#define TVP_POWERCTRL 0x2B
|
||||
#define TVP_ADCSETUP 0x2C
|
||||
#define TVP_CCLAMPCTRL 0x2D
|
||||
#define TVP_SOGCLAMP 0x2E
|
||||
#define TVP_RGBCCLAMPCTRL 0x2F
|
||||
|
||||
#define TVP_SOGCCLAMPCTRL 0x30
|
||||
#define TVP_ALCPLACE 0x31
|
||||
#define TVP_MVSWIDTH 0x34
|
||||
#define TVP_VSOUTALIGN 0x35
|
||||
#define TVP_SYNCBYPASS 0x36
|
||||
#define TVP_LINECNT1 0x37
|
||||
#define TVP_LINECNT2 0x38
|
||||
#define TVP_CLKCNT1 0x39
|
||||
#define TVP_CLKCNT2 0x3A
|
||||
#define TVP_HSINWIDTH 0x3B
|
||||
#define TVP_VSINWIDTH 0x3C
|
||||
#define TVP_LINELENTOL 0x3D
|
||||
#define TVP_VIDEOBWLIM 0x3F
|
||||
|
||||
#define TVP_AVIDSTART1 0x40
|
||||
#define TVP_AVIDSTART2 0x41
|
||||
#define TVP_AVIDSTOP1 0x42
|
||||
#define TVP_AVIDSTOP2 0x43
|
||||
#define TVP_VB0OFF 0x44
|
||||
#define TVP_VB1OFF 0x45
|
||||
#define TVP_VB0DUR 0x46
|
||||
#define TVP_VB1DUR 0x47
|
||||
#define TVP_CSC1LO 0x4A
|
||||
#define TVP_CSC1HI 0x4B
|
||||
#define TVP_CSC2LO 0x4C
|
||||
#define TVP_CSC2HI 0x4D
|
||||
#define TVP_CSC3LO 0x4E
|
||||
#define TVP_CSC3HI 0x4F
|
||||
|
||||
#define TVP_CSC4LO 0x50
|
||||
#define TVP_CSC4HI 0x51
|
||||
#define TVP_CSC5LO 0x52
|
||||
#define TVP_CSC5HI 0x53
|
||||
#define TVP_CSC6LO 0x54
|
||||
#define TVP_CSC6HI 0x55
|
||||
#define TVP_CSC7LO 0x56
|
||||
#define TVP_CSC7HI 0x57
|
||||
#define TVP_CSC8LO 0x58
|
||||
#define TVP_CSC8HI 0x59
|
||||
#define TVP_CSC9LO 0x5A
|
||||
#define TVP_CSC9HI 0x5B
|
||||
|
||||
#endif /* TVP7002_REGS_H_ */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue