Initial commit with software from sam7utils-0.2.1-bm.tar.bz2
This commit is contained in:
commit
74f53c1444
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) 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
|
||||
this service 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 make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. 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.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
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
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the 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 a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE 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.
|
||||
|
||||
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
|
||||
convey 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 2 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, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision 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, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This 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 Library General
|
||||
Public License instead of this License.
|
|
@ -0,0 +1,74 @@
|
|||
2006-09-15 erik gilling <konkers@konkers.net>
|
||||
* version 0.2.1
|
||||
|
||||
2006-09-15 erik gilling <konkers@konkers.net>
|
||||
* include io_libusb in dist
|
||||
|
||||
2006-09-06 erik gilling <konkers@konkers.net>
|
||||
* version 0.2.0
|
||||
|
||||
2007-02-09 erik gilling <konkers@konkers.net>
|
||||
* add libusb support and make superceed posix as the default
|
||||
* update README
|
||||
|
||||
2007-02-04 erik gilling <konkers@konkers.net>
|
||||
* add version.h include to linux driver
|
||||
|
||||
2006-09-28 erik gilling <konkers@konkers.net>
|
||||
* fixed -h argument (thanks Dean)
|
||||
|
||||
2006-09-06 erik gilling <konkers@konkers.net>
|
||||
* version 0.1.1
|
||||
|
||||
2006-09-06 erik gilling <konkers@konkers.net>
|
||||
* update help on a few commands
|
||||
* add linux driver fix for kernels > 2.6.14 (thanks Michael Shiloh)
|
||||
* add curses check to configure.in for FC4 (thanks Russ Nelson)
|
||||
|
||||
2006-07-07 erik gilling <konkers@konkers.net>
|
||||
* version 0.1.0
|
||||
|
||||
2006-07-07 erik gilling <konkers@konkers.net>
|
||||
* add boot_from_flash command from Liam
|
||||
|
||||
2006-06-16 erik gilling <konkers@konkers.net>
|
||||
* unlock_regions uses nvpsize not sramsiz
|
||||
|
||||
2006-06-16 erik gilling <konkers@konkers.net>
|
||||
* fix lock bit detection
|
||||
|
||||
2006-06-16 erik gilling <konkers@konkers.net>
|
||||
* fix configure.in to set OS options before looking for headers
|
||||
* add read and read_manual commands
|
||||
* add detection for number of lock bits
|
||||
* fix unlock_regions for devices other than the S64
|
||||
* remove exraneous debugging info
|
||||
* add --exec command line for scriptability
|
||||
|
||||
2006-06-15 erik gilling <konkers@konkers.net>
|
||||
* add win32 support (cygwin only for now)
|
||||
|
||||
2006-06-14 erik gilling <konkers@konkers.net>
|
||||
* integrate loaders into sam7 binary
|
||||
|
||||
2006-06-14 erik gilling <konkers@konkers.net>
|
||||
* remove endian swapping from write_half_word and write_word
|
||||
|
||||
2006-06-13 erik gilling <konkers@konkers.net>
|
||||
* rename samba_flash to flash
|
||||
* add support for 256 byte pages using flash command
|
||||
|
||||
2006-06-13 erik gilling <konkers@konkers.net>
|
||||
* add loader code (tested on sam7s64)
|
||||
|
||||
2006-06-09 erik gilling <konkers@konkers.net>
|
||||
* correct type matching for sam7x
|
||||
* first stab at endianness correction (untested)
|
||||
|
||||
2006-06-08 erik gilling <konkers@konkers.net>
|
||||
* read cpuid and size flash page
|
||||
* print out chip info on init
|
||||
|
||||
2005-12-30 erik gilling <konkers@konkers.net>
|
||||
* increment version to 0.0.2
|
||||
* add manual_upload command which does not use samba.bin
|
|
@ -0,0 +1,13 @@
|
|||
AM_CFLAGS = -Wall -Werror
|
||||
|
||||
AUTOMAKE_OPTIONS = gnu
|
||||
|
||||
bin_PROGRAMS = sam7
|
||||
|
||||
sam7_SOURCES = main.c io_@IOTYPE@.c samba.c cmd.c
|
||||
noinst_HEADERS = io.h samba.h cmd.h loader128_data.h loader256_data.h
|
||||
|
||||
EXTRA_DIST = driver/Makefile driver/at91.c \
|
||||
io_win32.c io_posix.c io_iokit.c io_libusb.c\
|
||||
loader/Makefile loader/at91.h loader/bin2c.c loader/crt0.S \
|
||||
loader/loader.c loader/loader.lds
|
|
@ -0,0 +1,14 @@
|
|||
> ./sam7
|
||||
response = 0d0a
|
||||
it begins
|
||||
sam7> set_clock
|
||||
sam7> unlock_regions
|
||||
unlocking page 0: done
|
||||
unlocking page 1: done
|
||||
|
||||
|
||||
sam7> flash test.bin
|
||||
>
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,682 @@
|
|||
/*
|
||||
* cmd.c
|
||||
*
|
||||
* Copyright (C) 2005 Erik Gilling, all rights reserved.
|
||||
*
|
||||
* 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, version 2.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "samba.h"
|
||||
#include "cmd.h"
|
||||
|
||||
#include "loader128_data.h"
|
||||
#include "loader256_data.h"
|
||||
|
||||
#define MANUAL_FLASH
|
||||
|
||||
static int cmd_help( int argc, char *argv[] );
|
||||
static int cmd_version( int argc, char *argv[] );
|
||||
static int cmd_write_mem( int argc, char *argv[] );
|
||||
static int cmd_read_mem( int argc, char *argv[] );
|
||||
static int cmd_send_file( int argc, char *argv[] );
|
||||
static int cmd_set_clock( int argc, char *argv[] );
|
||||
static int cmd_locked_regions( int argc, char *argv[] );
|
||||
static int cmd_unlock_regions( int argc, char *argv[] );
|
||||
static int cmd_boot_from_flash( int argc, char *argv[] );
|
||||
static int cmd_flash( int argc, char *argv[] );
|
||||
static int cmd_read( int argc, char *argv[] );
|
||||
static int cmd_manual_flash( int argc, char *argv[] );
|
||||
static int cmd_manual_read( int argc, char *argv[] );
|
||||
|
||||
static cmd_t cmds[] = {
|
||||
{cmd_write_mem, "wb",
|
||||
"wb <addr> <byte>", "write <byte> to <addr>"},
|
||||
|
||||
{cmd_read_mem, "rb",
|
||||
"rb <addr>", "read byte from <addr>"},
|
||||
|
||||
{cmd_write_mem, "ws",
|
||||
"ws <addr> <short>", "write <short> to <addr>"},
|
||||
|
||||
{cmd_read_mem, "rs",
|
||||
"rs <addr>", "read short from <addr>"},
|
||||
|
||||
{cmd_write_mem, "ww",
|
||||
"ww <addr> <word>", "write <word> to <addr>"},
|
||||
|
||||
{cmd_read_mem, "rw",
|
||||
"rw <addr>", "read word from <addr>"},
|
||||
|
||||
{cmd_send_file, "sf",
|
||||
"sf <addr> <file> <offset> <len>",
|
||||
"send len bytes of file starting at offset"},
|
||||
|
||||
{cmd_set_clock, "set_clock",
|
||||
"set_clock", "set clock as SAM-BA does"},
|
||||
{cmd_locked_regions, "locked_regions",
|
||||
"locked_regions", "display locked regions"},
|
||||
{cmd_unlock_regions, "unlock_regions",
|
||||
"unlock_regions", "unlock all lock regions"},
|
||||
{cmd_boot_from_flash, "boot_from_flash",
|
||||
"boot_from_flash", "set the SAM7X to boot from flash"},
|
||||
{cmd_flash, "flash",
|
||||
"flash <file>", "upload <file> to flash using the loader"},
|
||||
{cmd_read, "read",
|
||||
"read <file> <addr> <len>", "read <len> bytes at <addr> to <file> using R commands"},
|
||||
{cmd_manual_flash, "manual_flash",
|
||||
"manual_flash <file>", "upload <file> to flash using ww commands"},
|
||||
{cmd_manual_read, "manual_read",
|
||||
"manual_read <file> <addr> <len>", "write <len> bytes at <addr> to <file> using rw commands"},
|
||||
{cmd_version, "version",
|
||||
"version", "get boot program version"},
|
||||
{cmd_help, "help",
|
||||
"help", "display help screen"}
|
||||
};
|
||||
|
||||
cmd_t *cmd_find( char *name )
|
||||
{
|
||||
int i;
|
||||
for( i=0 ; i<(sizeof(cmds)/
|
||||
sizeof(*cmds)); i++ ) {
|
||||
if( !strcmp( name, cmds[i].name ) ) {
|
||||
return &cmds[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int cmd_help( int argc, char *argv[] )
|
||||
{
|
||||
int i;
|
||||
for( i=0 ; i<(sizeof(cmds)/
|
||||
sizeof(*cmds)); i++ ) {
|
||||
printf( "%-30s%s\n", cmds[i].invo, cmds[i].help );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_write_mem( int argc, char *argv[] )
|
||||
{
|
||||
unsigned long int addr;
|
||||
unsigned long int val;
|
||||
char *endp;
|
||||
|
||||
if( argc != 3 ) {
|
||||
return CMD_E_WRONG_NUM_ARGS;
|
||||
}
|
||||
|
||||
addr = strtoul( argv[1], &endp, 0 );
|
||||
if( endp == argv[1] ||
|
||||
*endp != '\0' ) {
|
||||
return CMD_E_INVAL_ARG;
|
||||
}
|
||||
|
||||
val = strtoul( argv[2], &endp, 0 );
|
||||
if( endp == argv[1] ||
|
||||
*endp != '\0' ) {
|
||||
return CMD_E_INVAL_ARG;
|
||||
}
|
||||
|
||||
|
||||
switch( argv[0][1] ) {
|
||||
case 'b':
|
||||
if( samba_write_byte( addr, (uint8_t) val ) < 0 ) {
|
||||
return CMD_E_IO_FAILURE;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
if( samba_write_half_word( addr, (uint16_t) val ) < 0 ) {
|
||||
return CMD_E_IO_FAILURE;
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
if( samba_write_word( addr, (uint32_t) val ) < 0 ) {
|
||||
return CMD_E_IO_FAILURE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return CMD_E_OK;
|
||||
}
|
||||
|
||||
static int cmd_read_mem( int argc, char *argv[] )
|
||||
{
|
||||
unsigned long int addr;
|
||||
char *endp;
|
||||
|
||||
if( argc != 2 ) {
|
||||
return CMD_E_WRONG_NUM_ARGS;
|
||||
}
|
||||
|
||||
addr = strtoul( argv[1], &endp, 0 );
|
||||
if( endp == argv[1] ||
|
||||
*endp != '\0' ) {
|
||||
return CMD_E_INVAL_ARG;
|
||||
}
|
||||
|
||||
switch( argv[0][1] ) {
|
||||
case 'b':
|
||||
{
|
||||
uint8_t val;
|
||||
if( samba_read_byte( addr, &val ) < 0 ) {
|
||||
return CMD_E_IO_FAILURE;
|
||||
}
|
||||
printf( "%02X\n", val );
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
{
|
||||
uint16_t val;
|
||||
|
||||
if( samba_read_half_word( addr, &val ) < 0 ) {
|
||||
return CMD_E_IO_FAILURE;
|
||||
}
|
||||
printf( "%04X\n", val );
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
{
|
||||
uint32_t val;
|
||||
if( samba_read_word( addr, &val ) < 0 ) {
|
||||
return CMD_E_IO_FAILURE;
|
||||
}
|
||||
printf( "%08X\n", (unsigned int) val );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return CMD_E_OK;
|
||||
}
|
||||
|
||||
static int cmd_send_file( int argc, char *argv[] )
|
||||
{
|
||||
unsigned long int offset;
|
||||
unsigned long int len;
|
||||
unsigned long int addr;
|
||||
char *endp;
|
||||
uint8_t *data;
|
||||
int fd;
|
||||
|
||||
if( argc != 5 ) {
|
||||
return CMD_E_WRONG_NUM_ARGS;
|
||||
}
|
||||
|
||||
addr = strtoul( argv[1], &endp, 0 );
|
||||
if( endp == argv[1] ||
|
||||
*endp != '\0' ) {
|
||||
return CMD_E_INVAL_ARG;
|
||||
}
|
||||
|
||||
offset = strtoul( argv[3], &endp, 0 );
|
||||
if( endp == argv[1] ||
|
||||
*endp != '\0' ) {
|
||||
return CMD_E_INVAL_ARG;
|
||||
}
|
||||
|
||||
len = strtoul( argv[4], &endp, 0 );
|
||||
if( endp == argv[1] ||
|
||||
*endp != '\0' ) {
|
||||
return CMD_E_INVAL_ARG;
|
||||
}
|
||||
|
||||
if( (data = (uint8_t *) malloc( len )) == NULL ) {
|
||||
printf( "can't allocate %d bytes\n", (int)len );
|
||||
return CMD_E_NO_MEM;
|
||||
}
|
||||
|
||||
if( (fd = open( argv[2], O_RDONLY )) < 0 ) {
|
||||
printf( "can't open file \"%s\": %s\n", argv[2],
|
||||
strerror( errno ) );
|
||||
return CMD_E_BAD_FILE;
|
||||
}
|
||||
|
||||
lseek( fd, offset, SEEK_SET );
|
||||
len = read( fd, data, len );
|
||||
|
||||
if( samba_send_file( 0x202000, data, len ) < 0 ) {
|
||||
return CMD_E_IO_FAILURE;
|
||||
}
|
||||
|
||||
return CMD_E_OK;
|
||||
}
|
||||
|
||||
static int cmd_version( int argc, char *argv[] )
|
||||
{
|
||||
char buff[256];
|
||||
|
||||
if( samba_get_version( buff, 256 ) < 0 ) {
|
||||
return CMD_E_IO_FAILURE;
|
||||
}
|
||||
|
||||
printf( "%s\n", buff );
|
||||
|
||||
return CMD_E_OK;
|
||||
}
|
||||
|
||||
static int cmd_set_clock( int argc, char *argv[] )
|
||||
{
|
||||
uint32_t val;
|
||||
uint8_t val8;
|
||||
|
||||
/* set clock to main clock / 2 */
|
||||
if( samba_write_word( 0xFFFFFC30, 0x5 ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
if( samba_read_word( 0xFFFFFC68, &val ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
} while( val != 0xD );
|
||||
|
||||
/* set clock to pll clock / 2 */
|
||||
if( samba_write_word( 0xFFFFFC30, 0x7 ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
if( samba_read_word( 0xFFFFFC68, &val ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
} while( val != 0xD );
|
||||
|
||||
|
||||
/* read 0x200000 two times because SAM-BA does it */
|
||||
if( samba_read_byte( 0x00200000, &val8 ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
if( val8 != 0x13 ) {
|
||||
printf( "warning: magic read 0x00200000 != 0x13\n" );
|
||||
}
|
||||
|
||||
if( samba_read_byte( 0x00200000, &val8 ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
if( val8 != 0x13 ) {
|
||||
printf( "warning: magic read 0x00200000 != 0x13\n" );
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_locked_regions( int argc, char *argv[] )
|
||||
{
|
||||
uint32_t val;
|
||||
int i;
|
||||
|
||||
if( samba_read_word( 0xffffff68, &val ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
printf( "Locked Regions:" );
|
||||
|
||||
for( i=0 ; i<16 ; i++ ) {
|
||||
if( val & 0x00010000 ) {
|
||||
printf( " %i", i );
|
||||
}
|
||||
val >>= 1;
|
||||
}
|
||||
|
||||
printf( "\n" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_unlock_regions( int argc, char *argv[] )
|
||||
{
|
||||
uint32_t val;
|
||||
int i;
|
||||
|
||||
if( samba_read_word( 0xffffff68, &val ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if( val & 0xffff0000 ) {
|
||||
/* set up MCLKS to some odd value... hey SAM-BA does it */
|
||||
if( samba_write_word( 0xffffff60, 0x00050100 ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for( i=0 ; i<samba_chip_info.lock_bits; i++ ) {
|
||||
if( val & 0x00010000 ) {
|
||||
int page = (samba_chip_info.nvpsiz / samba_chip_info.page_size /
|
||||
samba_chip_info.lock_bits) * i;
|
||||
|
||||
printf( "unlocking region %i:", i );
|
||||
|
||||
|
||||
if( samba_write_word( 0xffffff64,
|
||||
0x5a000004 | (page << 8) ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf( " done\n" );
|
||||
}
|
||||
val >>= 1;
|
||||
}
|
||||
|
||||
|
||||
/* set up MCLKS back to a sane value */
|
||||
if( samba_write_word( 0xffffff60, 0x00480100 ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
printf( "\n" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* contributed by Liam Staskawicz */
|
||||
static int cmd_boot_from_flash( int argc, char *argv[] )
|
||||
{
|
||||
/*
|
||||
* word: 5A is key to send any message,
|
||||
* 02 is GPNVM2 to boot from Flash,
|
||||
* 0B is "set this bit"
|
||||
*/
|
||||
uint32_t val;
|
||||
|
||||
|
||||
do {
|
||||
if( samba_read_word( 0xffffff68, &val ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
} while( !val & 0x1 );
|
||||
|
||||
if( samba_write_word( 0xFFFFFF64, 0x5A00020B ) < 0 ) {
|
||||
printf( "Couldn't flip the bit to boot from Flash.\n" );
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_flash( int argc, char *argv[] )
|
||||
{
|
||||
struct stat stbuf;
|
||||
size_t loader_len;
|
||||
size_t file_len;
|
||||
size_t i;
|
||||
uint8_t *buff;
|
||||
int file_fd;
|
||||
int read_len;
|
||||
int ps = samba_chip_info.page_size;
|
||||
uint8_t *loader_data;
|
||||
|
||||
if( argc != 2 ) {
|
||||
return CMD_E_WRONG_NUM_ARGS;
|
||||
}
|
||||
|
||||
if( ps == 128 ) {
|
||||
loader_data = loader128_data;
|
||||
loader_len = sizeof( loader128_data );
|
||||
} else if( ps == 256 ) {
|
||||
loader_data = loader256_data;
|
||||
loader_len = sizeof( loader256_data );
|
||||
} else {
|
||||
printf( "no loader for %d byte pages\n", ps );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( stat( argv[1], &stbuf ) < 0 ) {
|
||||
printf( "%s not found\n", argv[1] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
file_len = stbuf.st_size;
|
||||
|
||||
if( (buff = (uint8_t *) malloc( ps ) ) == NULL ) {
|
||||
printf( "can't alocate buffer of size 0x%x\n", ps );
|
||||
goto error0;
|
||||
}
|
||||
|
||||
if( samba_send_file( 0x00201600, loader_data, loader_len ) < 0 ) {
|
||||
printf( "could not upload samba.bin\n" );
|
||||
goto error1;
|
||||
}
|
||||
|
||||
if( (file_fd = open( argv[1], O_RDONLY )) < 0 ) {
|
||||
printf( "can't open %s\n", argv[1] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
for( i=0 ; i<file_len ; i+=ps ) {
|
||||
/* set page # */
|
||||
if( samba_write_word( 0x00201400+ps, i/ps ) < 0 ) {
|
||||
printf( "could not write page %d address\n", (int) i/ps );
|
||||
goto error2;
|
||||
}
|
||||
|
||||
read_len = (file_len-i < ps)?file_len-i:ps;
|
||||
/* XXX need to implement safe read */
|
||||
if( read( file_fd, buff, read_len ) < read_len ) {
|
||||
printf( "could not read 0x%x bytes from file\n", read_len );
|
||||
goto error2;
|
||||
}
|
||||
|
||||
if( samba_send_file( 0x00201400, buff, ps ) < 0 ) {
|
||||
printf( "could not send page %d\n", (int) i/ps );
|
||||
goto error2;
|
||||
}
|
||||
|
||||
if( samba_go( 0x00201600 ) < 0 ) {
|
||||
printf( "could not send go command for page %d\n", (int) i/ps );
|
||||
goto error2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
free( buff );
|
||||
close( file_fd );
|
||||
|
||||
return 0;
|
||||
|
||||
error2:
|
||||
close( file_fd );
|
||||
|
||||
error1:
|
||||
free( buff );
|
||||
|
||||
error0:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cmd_manual_flash( int argc, char *argv[] )
|
||||
{
|
||||
struct stat stbuf;
|
||||
size_t file_len;
|
||||
size_t i,j;
|
||||
char *buff;
|
||||
int file_fd;
|
||||
int read_len;
|
||||
uint32_t val;
|
||||
int ps = samba_chip_info.page_size;
|
||||
|
||||
if( argc != 2 ) {
|
||||
return CMD_E_WRONG_NUM_ARGS;
|
||||
}
|
||||
|
||||
if( stat( argv[1], &stbuf ) < 0 ) {
|
||||
printf( "%s not found\n", argv[1] );
|
||||
return -1;
|
||||
}
|
||||
file_len = stbuf.st_size;
|
||||
|
||||
|
||||
if( (buff = (char *) malloc( ps )) == NULL ) {
|
||||
printf( "can't alocate buffer of size 128\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if( (file_fd = open( argv[1], O_RDONLY )) < 0 ) {
|
||||
printf( "can't open %s\n", argv[1] );
|
||||
goto error0;
|
||||
}
|
||||
|
||||
for( i=0 ; i<file_len ; i+=ps ) {
|
||||
/* wait for flash to become ready */
|
||||
do {
|
||||
if( samba_read_word( 0xffffff68, &val ) < 0 ) {
|
||||
goto error1;
|
||||
}
|
||||
} while( !val & 0x1 );
|
||||
|
||||
read_len = (file_len-i < ps)?file_len-i:ps;
|
||||
/* XXX need to implement safe read */
|
||||
if( read( file_fd, buff, read_len ) < read_len ) {
|
||||
printf( "could not read 0x%x bytes from file\n", read_len );
|
||||
goto error1;
|
||||
}
|
||||
|
||||
for( j=0 ; j<ps ; j+=4 ) {
|
||||
if( samba_write_word( 0x00100000 + i + j, *((uint32_t*)(buff+j))) < 0 ) {
|
||||
printf( "could not write byte 0x%x\n", (unsigned int)( 0x00100000 + i + j) );
|
||||
}
|
||||
}
|
||||
|
||||
/* send write command */
|
||||
if( samba_write_word( 0xFFFFFF64, 0x5A000001 | ((i/ps) << 8) ) < 0 ) {
|
||||
printf( "could not send write command for page %d\n", (int) i/ps );
|
||||
goto error1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
free( buff );
|
||||
close( file_fd );
|
||||
|
||||
return 0;
|
||||
|
||||
error1:
|
||||
close( file_fd );
|
||||
|
||||
error0:
|
||||
free( buff );
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cmd_manual_read( int argc, char *argv[] )
|
||||
{
|
||||
unsigned long int addr;
|
||||
unsigned long int len;
|
||||
int fd;
|
||||
int i;
|
||||
uint32_t val;
|
||||
char *endp;
|
||||
|
||||
if( argc != 4 ) {
|
||||
printf( "wrong number of args\n" );
|
||||
return CMD_E_WRONG_NUM_ARGS;
|
||||
}
|
||||
|
||||
addr = strtoul( argv[2], &endp, 0 );
|
||||
if( endp == argv[2] ||
|
||||
*endp != '\0' ) {
|
||||
printf("%s not a vaild number\n", argv[2]);
|
||||
return CMD_E_INVAL_ARG;
|
||||
}
|
||||
|
||||
len = strtoul( argv[3], &endp, 0 );
|
||||
if( endp == argv[3] ||
|
||||
*endp != '\0' ) {
|
||||
printf("%s not a vaild number\n", argv[3]);
|
||||
return CMD_E_INVAL_ARG;
|
||||
}
|
||||
|
||||
if( (fd = open( argv[1], O_RDWR | O_CREAT, 0666 )) < 0 ) {
|
||||
printf( "can't open file \"%s\": %s\n", argv[1],
|
||||
strerror( errno ) );
|
||||
return CMD_E_BAD_FILE;
|
||||
}
|
||||
|
||||
for( i=0; i<len ; i+=4 ) {
|
||||
if( samba_read_word( addr + i, &val ) < 0 ) {
|
||||
printf( "io error\n" );
|
||||
return CMD_E_IO_FAILURE;
|
||||
}
|
||||
|
||||
if( write( fd, &val, 4 ) < 4 ) {
|
||||
printf("write error\n" );
|
||||
return CMD_E_IO_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
close( fd );
|
||||
|
||||
return CMD_E_OK;
|
||||
}
|
||||
|
||||
static int cmd_read( int argc, char *argv[] )
|
||||
{
|
||||
unsigned long int addr;
|
||||
unsigned long int len;
|
||||
int fd;
|
||||
int i;
|
||||
char *endp;
|
||||
int read_len;
|
||||
uint8_t buff[0x80];
|
||||
|
||||
if( argc != 4 ) {
|
||||
printf( "wrong number of args\n");
|
||||
return CMD_E_WRONG_NUM_ARGS;
|
||||
}
|
||||
|
||||
addr = strtoul( argv[2], &endp, 0 );
|
||||
if( endp == argv[2] ||
|
||||
*endp != '\0' ) {
|
||||
printf("%s not a vaild number\n", argv[2]);
|
||||
return CMD_E_INVAL_ARG;
|
||||
}
|
||||
|
||||
len = strtoul( argv[3], &endp, 0 );
|
||||
if( endp == argv[3] ||
|
||||
*endp != '\0' ) {
|
||||
printf("%s not a vaild number\n", argv[3]);
|
||||
return CMD_E_INVAL_ARG;
|
||||
}
|
||||
|
||||
if( (fd = open( argv[1], O_RDWR | O_CREAT, 0666 )) < 0 ) {
|
||||
printf( "can't open file \"%s\": %s\n", argv[1],
|
||||
strerror( errno ) );
|
||||
return CMD_E_BAD_FILE;
|
||||
}
|
||||
|
||||
for( i=0; i<len ; i+=0x80 ) {
|
||||
read_len = len-i < 0x80 ? len-i : 0x80;
|
||||
if( samba_recv_file( addr + i, buff, read_len ) < 0 ) {
|
||||
printf( "io error\n" );
|
||||
return CMD_E_IO_FAILURE;
|
||||
}
|
||||
|
||||
if( write( fd, buff, read_len ) < read_len ) {
|
||||
printf("write error\n" );
|
||||
return CMD_E_IO_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
close( fd );
|
||||
|
||||
return CMD_E_OK;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* cmd.h
|
||||
*
|
||||
* Copyright (C) 2005 Erik Gilling, all rights reserved
|
||||
*
|
||||
* 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, version 2.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __cmd_h__
|
||||
#define __cmd_h__
|
||||
|
||||
typedef struct {
|
||||
int (* func)( int argc, char *argv[] );
|
||||
char *name;
|
||||
char *invo;
|
||||
char *help;
|
||||
} cmd_t;
|
||||
|
||||
|
||||
#define CMD_E_OK 0
|
||||
#define CMD_E_WRONG_NUM_ARGS -1
|
||||
#define CMD_E_INVAL_ARG -2
|
||||
#define CMD_E_IO_FAILURE -3
|
||||
#define CMD_E_UNIMP -4
|
||||
#define CMD_E_BAD_FILE -5
|
||||
#define CMD_E_NO_MEM -6
|
||||
|
||||
cmd_t *cmd_find( char *name );
|
||||
|
||||
#endif /* __cmd_h__ */
|
|
@ -0,0 +1,44 @@
|
|||
AC_INIT([sam7utils], [0.2.1], [konkers@konkers.net])
|
||||
|
||||
AC_CANONICAL_BUILD
|
||||
AC_CANONICAL_HOST
|
||||
AC_CANONICAL_TARGET
|
||||
|
||||
AM_INIT_AUTOMAKE(sam7utils,0.2.1)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_MAKE_SET
|
||||
|
||||
case "${host}" in
|
||||
*-*-darwin* )
|
||||
LIBS="$LIBS -framework IOKIT -framework CoreFoundation"
|
||||
IOTYPE="iokit"
|
||||
;;
|
||||
*-*-cygwin* )
|
||||
LIBS="$LIBS -lsetupapi"
|
||||
IOTYPE="win32"
|
||||
;;
|
||||
* )
|
||||
AC_CHECK_LIB(usb,usb_init,IOTYPE="libusb";LIBS="$LIBS -lusb",IOTYPE="posix")
|
||||
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
AC_HEADER_STDC
|
||||
|
||||
AC_CHECK_LIB(readline, readline,,AC_MSG_ERROR(readline not found))
|
||||
AC_CHECK_LIB(curses, tgoto,,AC_MSG_ERROR(curses not found))
|
||||
AC_CHECK_HEADERS(stdint.h,,AC_MSG_WARN(can't find stdint.h))
|
||||
AC_CHECK_HEADERS(ctype.h,,)
|
||||
AC_CHECK_HEADERS(endian.h,,)
|
||||
|
||||
|
||||
|
||||
|
||||
AC_SUBST(IOTYPE)
|
||||
|
||||
AC_OUTPUT(Makefile)
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* io.h
|
||||
*
|
||||
* Copyright (C) 2005 Erik Gilling, all rights reserved
|
||||
*
|
||||
* 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, version 2.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __io_h__
|
||||
#define __io_h__
|
||||
|
||||
|
||||
#include <string.h> // for strlen
|
||||
#include <unistd.h> // for usleep
|
||||
|
||||
#define USB_VID_ATMEL 0x03eb
|
||||
#define USB_PID_SAMBA 0x6124
|
||||
|
||||
|
||||
int io_init( char *dev );
|
||||
int io_cleanup( void );
|
||||
int io_write( void *buff, int len );
|
||||
int io_read( void *buff, int len );
|
||||
int io_read_response( char *buff, int len );
|
||||
|
||||
|
||||
static inline int io_send_cmd( char *cmd, void *response, int response_len )
|
||||
{
|
||||
|
||||
if( io_write( cmd, strlen( cmd ) ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
usleep( 2000 );
|
||||
|
||||
if( response_len == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( io_read( response, response_len ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
usleep( 2000 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __io_h__ */
|
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
* io.c
|
||||
*
|
||||
* Copyright (C) 2005 Erik Gilling, all rights reserved
|
||||
*
|
||||
* 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, version 2.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
|
||||
#include <CoreFoundation/CFNumber.h>
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOKit/IOCFPlugIn.h>
|
||||
#include <IOKit/usb/IOUSBLib.h>
|
||||
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "io.h"
|
||||
#include "samba.h"
|
||||
|
||||
|
||||
static mach_port_t masterPort = 0;
|
||||
static IOUSBDeviceInterface **usbDev = NULL;
|
||||
static IOUSBInterfaceInterface **intf = NULL;
|
||||
static UInt8 inPipeRef = 0;
|
||||
static UInt8 outPipeRef = 0;
|
||||
|
||||
#undef DEBUG_IO
|
||||
|
||||
|
||||
int do_intf(io_service_t usbInterfaceRef)
|
||||
{
|
||||
IOReturn err;
|
||||
IOCFPlugInInterface **iodev;
|
||||
SInt32 score;
|
||||
UInt8 numPipes;
|
||||
int i;
|
||||
UInt8 direction, number, transferType, interval;
|
||||
UInt16 maxPacketSize;
|
||||
|
||||
err = IOCreatePlugInInterfaceForService(usbInterfaceRef,
|
||||
kIOUSBInterfaceUserClientTypeID,
|
||||
kIOCFPlugInInterfaceID,
|
||||
&iodev, &score);
|
||||
if( err || !iodev ) {
|
||||
printf("unable to create plugin. ret = %08x, iodev = %p\n", err, iodev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = (*iodev)->QueryInterface(iodev,
|
||||
CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID),
|
||||
(LPVOID)&intf);
|
||||
IODestroyPlugInInterface(iodev);
|
||||
|
||||
if (err || !intf) {
|
||||
printf("unable to create a device interface. ret = %08x, intf = %p\n",
|
||||
err, intf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = (*intf)->USBInterfaceOpen(intf);
|
||||
if (err) {
|
||||
printf("unable to open interface. ret = %08x\n", err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = (*intf)->GetNumEndpoints(intf, &numPipes);
|
||||
if (err) {
|
||||
printf("unable to get number of endpoints. ret = %08x\n", err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (numPipes) {
|
||||
for (i=1; i <= numPipes; i++) {
|
||||
|
||||
err = (*intf)->GetPipeProperties(intf, i, &direction,
|
||||
&number, &transferType,
|
||||
&maxPacketSize, &interval);
|
||||
if (err) {
|
||||
printf("unable to get pipe properties for pipe %d, err = %08x\n",
|
||||
i, err);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (transferType != kUSBBulk) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((direction == kUSBIn) && !inPipeRef) {
|
||||
inPipeRef = i;
|
||||
}
|
||||
if ((direction == kUSBOut) && !outPipeRef) {
|
||||
outPipeRef = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !inPipeRef || !outPipeRef ) {
|
||||
(*intf)->USBInterfaceClose(intf);
|
||||
(*intf)->Release(intf);
|
||||
intf = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int do_dev( io_service_t usbDeviceRef )
|
||||
{
|
||||
IOReturn err;
|
||||
IOCFPlugInInterface **iodev; // requires <IOKit/IOCFPlugIn.h>
|
||||
SInt32 score;
|
||||
UInt8 numConf;
|
||||
IOUSBConfigurationDescriptorPtr confDesc;
|
||||
IOUSBFindInterfaceRequest interfaceRequest;
|
||||
io_iterator_t iterator;
|
||||
io_service_t usbInterfaceRef;
|
||||
|
||||
err = IOCreatePlugInInterfaceForService(usbDeviceRef,
|
||||
kIOUSBDeviceUserClientTypeID,
|
||||
kIOCFPlugInInterfaceID, &iodev, &score);
|
||||
if (err || !iodev) {
|
||||
printf("unable to create plugin. ret = %08x, iodev = %p\n",
|
||||
err, iodev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = (*iodev)->QueryInterface(iodev,
|
||||
CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
|
||||
(LPVOID)&usbDev);
|
||||
IODestroyPlugInInterface(iodev); // done with this
|
||||
|
||||
if (err || !usbDev) {
|
||||
printf("unable to create a device interface. ret = %08x, dev = %p\n",
|
||||
err, usbDev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = (*usbDev)->USBDeviceOpen(usbDev);
|
||||
if (err) {
|
||||
printf("unable to open device. ret = %08x\n", err);
|
||||
return -1;
|
||||
}
|
||||
err = (*usbDev)->GetNumberOfConfigurations(usbDev, &numConf);
|
||||
if (err || !numConf) {
|
||||
printf("unable to obtain the number of configurations. ret = %08x\n", err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = (*usbDev)->GetConfigurationDescriptorPtr(usbDev, 0, &confDesc); // get the first config desc (index 0)
|
||||
if (err) {
|
||||
printf("unable to get config descriptor for index 0\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
err = (*usbDev)->SetConfiguration(usbDev, confDesc->bConfigurationValue);
|
||||
if (err) {
|
||||
printf("unable to set the configuration\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// requested class
|
||||
interfaceRequest.bInterfaceClass = kIOUSBFindInterfaceDontCare;
|
||||
// requested subclass
|
||||
interfaceRequest.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
|
||||
// requested protocol
|
||||
interfaceRequest.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
|
||||
// requested alt setting
|
||||
interfaceRequest.bAlternateSetting = kIOUSBFindInterfaceDontCare;
|
||||
|
||||
err = (*usbDev)->CreateInterfaceIterator(usbDev, &interfaceRequest, &iterator);
|
||||
if (err) {
|
||||
printf("unable to create interface iterator\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while( (usbInterfaceRef = IOIteratorNext(iterator)) ) {
|
||||
if( do_intf( usbInterfaceRef ) == 0 ) {
|
||||
IOObjectRelease(iterator);
|
||||
iterator = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IOObjectRelease(iterator);
|
||||
iterator = 0;
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int io_init( char *dev __attribute__((unused)) )
|
||||
{
|
||||
|
||||
kern_return_t err;
|
||||
CFMutableDictionaryRef matchingDictionary = 0;
|
||||
CFNumberRef numberRef;
|
||||
SInt32 idVendor = USB_VID_ATMEL;
|
||||
SInt32 idProduct = USB_PID_SAMBA;
|
||||
io_iterator_t iterator = 0;
|
||||
io_service_t usbDeviceRef;
|
||||
|
||||
|
||||
if( (err = IOMasterPort( MACH_PORT_NULL, &masterPort )) ) {
|
||||
printf( "could not create master port, err = %08x\n", err );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( !(matchingDictionary = IOServiceMatching(kIOUSBDeviceClassName)) ) {
|
||||
printf( "could not create matching dictionary\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( !(numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type,
|
||||
&idVendor)) ) {
|
||||
printf( "could not create CFNumberRef for vendor\n" );
|
||||
return -1;
|
||||
}
|
||||
CFDictionaryAddValue( matchingDictionary, CFSTR(kUSBVendorID), numberRef);
|
||||
CFRelease( numberRef );
|
||||
numberRef = 0;
|
||||
|
||||
if( !(numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type,
|
||||
&idProduct)) ) {
|
||||
printf( "could not create CFNumberRef for product\n" );
|
||||
return -1;
|
||||
}
|
||||
CFDictionaryAddValue( matchingDictionary, CFSTR(kUSBProductID), numberRef);
|
||||
CFRelease( numberRef );
|
||||
numberRef = 0;
|
||||
|
||||
err = IOServiceGetMatchingServices( masterPort, matchingDictionary, &iterator );
|
||||
matchingDictionary = 0; // consumed by the above call
|
||||
|
||||
|
||||
|
||||
if( (usbDeviceRef = IOIteratorNext( iterator )) ) {
|
||||
printf( "found boot agent\n" );
|
||||
|
||||
do_dev( usbDeviceRef );
|
||||
} else {
|
||||
printf( "can not find boot agent\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
IOObjectRelease(usbDeviceRef);
|
||||
|
||||
IOObjectRelease(iterator);
|
||||
|
||||
|
||||
return samba_init();
|
||||
|
||||
|
||||
IOObjectRelease(usbDeviceRef);
|
||||
|
||||
IOObjectRelease(iterator);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int io_cleanup( void )
|
||||
{
|
||||
if( intf ) {
|
||||
(*intf)->USBInterfaceClose(intf);
|
||||
(*intf)->Release(intf);
|
||||
intf = NULL;
|
||||
}
|
||||
|
||||
if( usbDev ) {
|
||||
(*usbDev)->USBDeviceClose(usbDev);
|
||||
(*usbDev)->Release(usbDev);
|
||||
usbDev = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int io_write( void *buff, int len )
|
||||
{
|
||||
if( (*intf)->WritePipe( intf, outPipeRef, buff, (UInt32) len ) !=
|
||||
kIOReturnSuccess ) {
|
||||
printf( "write error\n");
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int io_read( void *buff, int len )
|
||||
{
|
||||
|
||||
UInt32 size = len;
|
||||
|
||||
if( (*intf)->ReadPipe( intf, inPipeRef, buff, &size ) !=
|
||||
kIOReturnSuccess ) {
|
||||
printf( "read error\n");
|
||||
}
|
||||
|
||||
|
||||
return (int) size;
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
#include "config.h"
|
||||
|
||||
#include <usb.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include "io.h"
|
||||
#include "samba.h"
|
||||
|
||||
static usb_dev_handle *io_handle;
|
||||
|
||||
int io_init( char *dev )
|
||||
{
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *usbdev;
|
||||
|
||||
usb_init(); /* initialize the library */
|
||||
usb_find_busses(); /* find all busses */
|
||||
usb_find_devices(); /* find all connected devices */
|
||||
|
||||
for(bus = usb_get_busses(); bus; bus = bus->next) {
|
||||
for(usbdev = bus->devices; usbdev; usbdev = usbdev->next) {
|
||||
if(usbdev->descriptor.idVendor == USB_VID_ATMEL
|
||||
&& usbdev->descriptor.idProduct == USB_PID_SAMBA) {
|
||||
|
||||
|
||||
if( (io_handle = usb_open(usbdev)) ) {
|
||||
if( usb_set_configuration( io_handle, 1 ) < 0 ){
|
||||
usb_close(io_handle);
|
||||
continue;
|
||||
}
|
||||
if( usb_claim_interface( io_handle, 1 ) < 0 ){
|
||||
usb_close(io_handle);
|
||||
continue;
|
||||
}
|
||||
return samba_init();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int io_cleanup( void )
|
||||
{
|
||||
usb_release_interface(io_handle, 1);
|
||||
usb_close(io_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int io_write( void *buff, int len )
|
||||
{
|
||||
int ret = usb_bulk_write(io_handle, 0x1, buff, len, 5000);
|
||||
if( ret < 0 ) {
|
||||
printf("error: %s\n", usb_strerror());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int io_read( void *buff, int len )
|
||||
{
|
||||
int ret = usb_bulk_read(io_handle, 0x82, buff, len, 5000);
|
||||
if( ret < 0 ) {
|
||||
printf("error: %s\n", usb_strerror());
|
||||
}
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* io.c
|
||||
*
|
||||
* Copyright (C) 2005 Erik Gilling, all rights reserved
|
||||
*
|
||||
* 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, version 2.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "io.h"
|
||||
#include "samba.h"
|
||||
|
||||
static int io_fd;
|
||||
|
||||
#define SAM7_TTY "/dev/at91_0"
|
||||
|
||||
#undef DEBUG_IO
|
||||
|
||||
int io_init( char *dev )
|
||||
{
|
||||
if( dev == NULL ) {
|
||||
dev = SAM7_TTY;
|
||||
}
|
||||
// char buff[16];
|
||||
|
||||
if( (io_fd = open( dev, O_RDWR )) < 0 ) {
|
||||
printf( "can't open \"%s\": %s\n", dev, strerror( errno ) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return samba_init();
|
||||
}
|
||||
|
||||
int io_cleanup( void )
|
||||
{
|
||||
close( io_fd );
|
||||
|
||||
return 0;
|
||||
}
|
||||
int io_write( void *buff, int len )
|
||||
{
|
||||
int write_len = 0;
|
||||
int ret;
|
||||
|
||||
#ifdef DEBUG_IO
|
||||
write( STDOUT_FILENO, ">", 1 );
|
||||
write( STDOUT_FILENO, buff, len );
|
||||
write( STDOUT_FILENO, "\n", 1 );
|
||||
|
||||
#endif
|
||||
while( write_len < len ) {
|
||||
if( (ret = write( io_fd, buff + write_len, len - write_len )) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
write_len += ret;
|
||||
}
|
||||
|
||||
return write_len;
|
||||
}
|
||||
|
||||
int io_read( void *buff, int len )
|
||||
{
|
||||
#ifdef DEBUG_IO
|
||||
int i;
|
||||
char outbuff[16];
|
||||
len = read( io_fd, buff, len );
|
||||
write( STDOUT_FILENO, "<", 1 );
|
||||
for( i=0 ; i<len ; i++ ) {
|
||||
snprintf( outbuff, 16, " %02X", ((char*)buff)[i] & 0xff );
|
||||
write( STDOUT_FILENO, outbuff, strlen(outbuff) );
|
||||
}
|
||||
write( STDOUT_FILENO, "\n", 1 );
|
||||
|
||||
return len;
|
||||
#else
|
||||
return read( io_fd, buff, len );
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
int io_read_response( char *buff, int len )
|
||||
{
|
||||
int read_len = 0;
|
||||
struct timeval tv;
|
||||
fd_set fds;
|
||||
int ret;
|
||||
|
||||
while( read_len < len ) {
|
||||
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
FD_ZERO( &fds );
|
||||
FD_SET( io_fd, &fds );
|
||||
|
||||
if( (ret = select( io_fd + 1, &fds, NULL, NULL, &tv )) < 0 ) {
|
||||
if( errno == EINTR ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( ret == 0 ) {
|
||||
buff[read_len] = '\0';
|
||||
printf( "timeout '%s'\n", buff);
|
||||
return -read_len;
|
||||
}
|
||||
|
||||
if( (ret = read( io_fd, buff + read_len, len - read_len )) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
read_len += ret;
|
||||
|
||||
if( (read_len > 0) &&
|
||||
buff[ read_len - 1 ] == '>' ) {
|
||||
if( (read_len > 2) &&
|
||||
buff[ read_len - 2 ] == '\r' &&
|
||||
buff[ read_len - 3 ] == '\n' ) {
|
||||
return buff[read_len - 3] = '\0' ;
|
||||
return read_len-3 ;
|
||||
} else {
|
||||
return buff[read_len - 1] = '\0' ;
|
||||
return read_len-1 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return read_len;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* io_win32.c
|
||||
*
|
||||
* Copyright (C) 2005 Erik Gilling, all rights reserved
|
||||
*
|
||||
* 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, version 2.
|
||||
*
|
||||
*
|
||||
* USB device enumeration modeled from http://www.delcom-eng.com/downloads/USBPRGMNL.pdf
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define WINVER 0x0500
|
||||
#define INITGUID
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
#include <basetyps.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "io.h"
|
||||
#include "samba.h"
|
||||
|
||||
|
||||
// {E6EF7DCD-1795-4a08-9FBF-AA78423C26F0}
|
||||
DEFINE_GUID(USBIODS_GUID,
|
||||
0xe6ef7dcd, 0x1795, 0x4a08, 0x9f, 0xbf, 0xaa, 0x78, 0x42, 0x3c, 0x26, 0xf0);
|
||||
|
||||
HANDLE io_pipe_in, io_pipe_out;
|
||||
|
||||
int io_init( char *dev )
|
||||
{
|
||||
char *devname;
|
||||
|
||||
// char buff[16];
|
||||
|
||||
HDEVINFO hInfo = SetupDiGetClassDevs(&USBIODS_GUID, NULL,
|
||||
NULL, DIGCF_PRESENT |
|
||||
DIGCF_INTERFACEDEVICE);
|
||||
|
||||
SP_INTERFACE_DEVICE_DATA Interface_Info;
|
||||
Interface_Info.cbSize = sizeof(Interface_Info);
|
||||
// Enumerate device
|
||||
if( !SetupDiEnumDeviceInterfaces(hInfo, NULL, (LPGUID)
|
||||
&USBIODS_GUID,0, &Interface_Info ) ) {
|
||||
printf( "can't find boot agent\n");
|
||||
goto error0;
|
||||
}
|
||||
|
||||
DWORD needed; // get the required lenght
|
||||
SetupDiGetInterfaceDeviceDetail(hInfo, &Interface_Info,
|
||||
NULL, 0, &needed, NULL);
|
||||
PSP_INTERFACE_DEVICE_DETAIL_DATA detail =
|
||||
(PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc(needed);
|
||||
if( !detail ) {
|
||||
printf( "can't find boot agent\n");
|
||||
goto error0;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
// fill the device details
|
||||
detail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
|
||||
|
||||
if( !SetupDiGetInterfaceDeviceDetail( hInfo,
|
||||
&Interface_Info,detail,
|
||||
needed,NULL, NULL )) {
|
||||
printf( "can't find boot agent\n");
|
||||
goto error1;
|
||||
}
|
||||
|
||||
devname = (char *) malloc( strlen( detail->DevicePath ) + 7 );
|
||||
|
||||
strcpy( devname, detail->DevicePath );
|
||||
strcat( devname, "\\PIPE00" );
|
||||
printf( "%s\n", devname );
|
||||
|
||||
// open out
|
||||
|
||||
io_pipe_out = CreateFile( devname, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||
0, NULL );
|
||||
|
||||
if( io_pipe_out == INVALID_HANDLE_VALUE ) {
|
||||
printf( "can't open output pipe\n" );
|
||||
goto error2;
|
||||
}
|
||||
|
||||
strcpy( devname, detail->DevicePath );
|
||||
strcat( devname, "\\PIPE01" );
|
||||
|
||||
// open in
|
||||
|
||||
io_pipe_in = CreateFile( devname, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||
0, NULL );
|
||||
|
||||
if( io_pipe_in == INVALID_HANDLE_VALUE ) {
|
||||
printf( "can't open input pipe\n" );
|
||||
goto error3;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
free((PVOID) detail);
|
||||
free( devname );
|
||||
|
||||
|
||||
|
||||
return samba_init();
|
||||
|
||||
return 0;
|
||||
// return samba_init();
|
||||
|
||||
error3:
|
||||
CloseHandle( io_pipe_out );
|
||||
|
||||
error2:
|
||||
free( devname );
|
||||
|
||||
error1:
|
||||
free((PVOID) detail);
|
||||
|
||||
error0:
|
||||
SetupDiDestroyDeviceInfoList(hInfo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int io_cleanup( void )
|
||||
{
|
||||
CloseHandle( io_pipe_out );
|
||||
CloseHandle( io_pipe_in );
|
||||
|
||||
return 0;
|
||||
}
|
||||
int io_write( void *buff, int len )
|
||||
{
|
||||
int write_len = 0;
|
||||
DWORD bytes_written;
|
||||
|
||||
while( write_len < len ) {
|
||||
|
||||
if( !WriteFile( io_pipe_out, buff + write_len,
|
||||
len - write_len, &bytes_written, NULL ) ) {
|
||||
return -1;
|
||||
}
|
||||
write_len += bytes_written;
|
||||
}
|
||||
|
||||
return write_len;
|
||||
}
|
||||
|
||||
int io_read( void *buff, int len )
|
||||
{
|
||||
int read_len = 0;
|
||||
DWORD bytes_read;
|
||||
|
||||
while( read_len < len ) {
|
||||
|
||||
if( !ReadFile( io_pipe_in, buff + read_len,
|
||||
len - read_len, &bytes_read, NULL ) ) {
|
||||
return -1;
|
||||
}
|
||||
read_len += bytes_read;
|
||||
}
|
||||
|
||||
return read_len;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
uint8_t loader128_data[] = {
|
||||
0x0c, 0xd0, 0x9f, 0xe5, 0x00, 0x40, 0x2d, 0xe9,
|
||||
0x02, 0x00, 0x00, 0xeb, 0x01, 0x00, 0xbd, 0xe8,
|
||||
0x10, 0xff, 0x2f, 0xe1, 0x00, 0x1c, 0x20, 0x00,
|
||||
0x30, 0x40, 0x2d, 0xe9, 0x02, 0xe6, 0xa0, 0xe3,
|
||||
0x05, 0xeb, 0x8e, 0xe2, 0x80, 0x50, 0x9e, 0xe5,
|
||||
0x4c, 0x40, 0x9f, 0xe5, 0x85, 0x02, 0xa0, 0xe1,
|
||||
0x68, 0x30, 0x94, 0xe5, 0x01, 0x00, 0x13, 0xe3,
|
||||
0xfc, 0xff, 0xff, 0x0a, 0x00, 0x10, 0xa0, 0xe3,
|
||||
0x01, 0xc6, 0xa0, 0xe3, 0x01, 0x20, 0x80, 0xe0,
|
||||
0x01, 0x31, 0x9e, 0xe7, 0x01, 0x10, 0x81, 0xe2,
|
||||
0x1f, 0x00, 0x51, 0xe3, 0x02, 0x31, 0x8c, 0xe7,
|
||||
0xf9, 0xff, 0xff, 0xda, 0x05, 0x3b, 0xa0, 0xe1,
|
||||
0x23, 0x3b, 0xa0, 0xe1, 0x03, 0x34, 0xa0, 0xe1,
|
||||
0x5a, 0x34, 0x83, 0xe3, 0x01, 0x30, 0x83, 0xe3,
|
||||
0x00, 0x00, 0xa0, 0xe3, 0x64, 0x30, 0x84, 0xe5,
|
||||
0x30, 0x80, 0xbd, 0xe8, 0x00, 0xff, 0xff, 0xff
|
||||
};
|
|
@ -0,0 +1,18 @@
|
|||
uint8_t loader256_data[] = {
|
||||
0x0c, 0xd0, 0x9f, 0xe5, 0x00, 0x40, 0x2d, 0xe9,
|
||||
0x02, 0x00, 0x00, 0xeb, 0x01, 0x00, 0xbd, 0xe8,
|
||||
0x10, 0xff, 0x2f, 0xe1, 0x00, 0x1c, 0x20, 0x00,
|
||||
0x30, 0x40, 0x2d, 0xe9, 0x02, 0xe6, 0xa0, 0xe3,
|
||||
0x05, 0xeb, 0x8e, 0xe2, 0x00, 0x51, 0x9e, 0xe5,
|
||||
0x4c, 0x40, 0x9f, 0xe5, 0x05, 0x03, 0xa0, 0xe1,
|
||||
0x68, 0x30, 0x94, 0xe5, 0x01, 0x00, 0x13, 0xe3,
|
||||
0xfc, 0xff, 0xff, 0x0a, 0x00, 0x10, 0xa0, 0xe3,
|
||||
0x01, 0xc6, 0xa0, 0xe3, 0x01, 0x20, 0x80, 0xe0,
|
||||
0x01, 0x31, 0x9e, 0xe7, 0x01, 0x10, 0x81, 0xe2,
|
||||
0x3f, 0x00, 0x51, 0xe3, 0x02, 0x31, 0x8c, 0xe7,
|
||||
0xf9, 0xff, 0xff, 0xda, 0x05, 0x3b, 0xa0, 0xe1,
|
||||
0x23, 0x3b, 0xa0, 0xe1, 0x03, 0x34, 0xa0, 0xe1,
|
||||
0x5a, 0x34, 0x83, 0xe3, 0x01, 0x30, 0x83, 0xe3,
|
||||
0x00, 0x00, 0xa0, 0xe3, 0x64, 0x30, 0x84, 0xe5,
|
||||
0x30, 0x80, 0xbd, 0xe8, 0x00, 0xff, 0xff, 0xff
|
||||
};
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* main.c
|
||||
*
|
||||
* Copyright (C) 2005 Erik Gilling, all rights reserved
|
||||
*
|
||||
* 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, version 2.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_CTYPE_H
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#include "io.h"
|
||||
#include "samba.h"
|
||||
#include "cmd.h"
|
||||
|
||||
#define SAM7_TTY "/dev/at91_0"
|
||||
|
||||
|
||||
static int sam7_parse_line( char *line, char *argv[] );
|
||||
static int sam7_handle_line( char *line );
|
||||
static void usage( void );
|
||||
|
||||
#define MAX_CMDS 32
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
char *cmdline;
|
||||
char *line = NULL;
|
||||
char *cmds[MAX_CMDS];
|
||||
int n_cmds=0;
|
||||
int c,i;
|
||||
|
||||
|
||||
while( 1 ) {
|
||||
int option_index;
|
||||
static struct option long_options[] = {
|
||||
{ "line", 1, 0, 'l' },
|
||||
{ "exec", 1, 0, 'e' },
|
||||
{ "help", 0, 0, 'h' }
|
||||
};
|
||||
|
||||
c = getopt_long( argc, argv, "l:e:h", long_options, &option_index );
|
||||
|
||||
if( c == -1 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch( c ) {
|
||||
case 'l':
|
||||
line = optarg;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
if( n_cmds >= MAX_CMDS ) {
|
||||
printf( "to many commands, increase MAX_CMDS\n" );
|
||||
return 1;
|
||||
}
|
||||
cmds[n_cmds] = optarg;
|
||||
n_cmds++;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
usage();
|
||||
return 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf( "unknown option\n" );
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( io_init( line ) < 0 ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( n_cmds > 0 ) {
|
||||
for( i=0 ; i<n_cmds ; i++ ) {
|
||||
sam7_handle_line( cmds[i] );
|
||||
}
|
||||
|
||||
} else {
|
||||
while( (cmdline = readline( "sam7> " )) ) {
|
||||
add_history( cmdline );
|
||||
sam7_handle_line( cmdline );
|
||||
}
|
||||
}
|
||||
|
||||
io_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usage( void )
|
||||
{
|
||||
printf( "usage: sam7 [options]\n" );
|
||||
printf( " -e|--exec <cmd> execute cmd instead of entering interactive mode.\n");
|
||||
printf( " -l|--line <line> specifies the line/tty which the boot agent resides.\n");
|
||||
printf( " only used for posix IO.\n" );
|
||||
printf( " -h|--help dislay this message and exit.\n");
|
||||
}
|
||||
|
||||
static int sam7_parse_line( char *line, char *argv[] )
|
||||
{
|
||||
char *p = line;
|
||||
int argc = 0;
|
||||
|
||||
|
||||
while( *p ) {
|
||||
// eat white space
|
||||
while( *p && isspace( *p ) ) { p++; }
|
||||
if( ! *p ) {
|
||||
break;
|
||||
}
|
||||
|
||||
argv[argc++] = p;
|
||||
|
||||
while( *p && !isspace( *p ) ) { p++; }
|
||||
if( *p ) {
|
||||
*p++ = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return argc;
|
||||
}
|
||||
|
||||
static int sam7_handle_line( char *line )
|
||||
{
|
||||
int argc;
|
||||
char buff[256];
|
||||
char *argv[32];
|
||||
cmd_t *cmd;
|
||||
|
||||
strncpy( buff, line, 255 );
|
||||
buff[255] = '\0';
|
||||
|
||||
argc = sam7_parse_line( buff, argv );
|
||||
|
||||
if( argc > 0 ) {
|
||||
if( (cmd = cmd_find( argv[0] )) != NULL ) {
|
||||
return cmd->func( argc, argv );
|
||||
}
|
||||
printf( "command %s not found\n", argv[0] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,399 @@
|
|||
/*
|
||||
* samba.c
|
||||
*
|
||||
* Copyright (C) 2005,2006 Erik Gilling, all rights reserved
|
||||
*
|
||||
* 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, version 2.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LOCALENDIAN_H
|
||||
#include <localendian.h>
|
||||
#endif
|
||||
|
||||
#include "io.h"
|
||||
#include "samba.h"
|
||||
|
||||
|
||||
#ifndef __BYTE_ORDER
|
||||
# define __LITTLE_ENDIAN 4321
|
||||
# define __BIG_ENDIAN 1234
|
||||
# ifdef __LITTLE_ENDIAN__
|
||||
# define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
# endif
|
||||
# ifdef __BIG_ENDIAN__
|
||||
# define __BYTE_ORDER __BIG_ENDIAN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined( __BYTE_ORDER )
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define le2hl(x) (x)
|
||||
# define le2hs(x) (x)
|
||||
# endif
|
||||
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
|
||||
# define le2hl(x) \
|
||||
((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
|
||||
(((unsigned long int)(x) & 0x0000ff00U) << 8) | \
|
||||
(((unsigned long int)(x) & 0x00ff0000U) >> 8) | \
|
||||
(((unsigned long int)(x) & 0xff000000U) >> 24)))
|
||||
|
||||
# define le2hs(x) \
|
||||
((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
|
||||
(((unsigned short int)(x) & 0xff00) >> 8)))
|
||||
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define hl2le(x) le2hl(x)
|
||||
#define hs2le(x) le2hs(x)
|
||||
|
||||
static const char *eprocs[] = {
|
||||
/* 000 */ "",
|
||||
/* 001 */ "ARM946E-S",
|
||||
/* 010 */ "ARM7TDMI",
|
||||
/* 011 */ "",
|
||||
/* 100 */ "ARM920T",
|
||||
/* 101 */ "ARM926EJ-S",
|
||||
/* 110 */ "",
|
||||
/* 111 */ ""
|
||||
};
|
||||
|
||||
|
||||
#define K 1024
|
||||
|
||||
static const int nvpsizs[] = {
|
||||
/* 0000 */ 0,
|
||||
/* 0001 */ 8 * K,
|
||||
/* 0010 */ 16 * K,
|
||||
/* 0011 */ 32 * K,
|
||||
/* 0100 */ -1,
|
||||
/* 0101 */ 64 * K,
|
||||
/* 0110 */ -1,
|
||||
/* 0111 */ 128 * K,
|
||||
/* 1000 */ -1,
|
||||
/* 1001 */ 256 * K,
|
||||
/* 1010 */ 512 * K,
|
||||
/* 1011 */ -1,
|
||||
/* 1100 */ 1024 * K,
|
||||
/* 1101 */ -1,
|
||||
/* 1110 */ 2048 * K,
|
||||
/* 1111 */ -1
|
||||
};
|
||||
|
||||
static const int sramsizs[] = {
|
||||
/* 0000 */ -1,
|
||||
/* 0001 */ 1 * K,
|
||||
/* 0010 */ 2 * K,
|
||||
/* 0011 */ -1,
|
||||
/* 0100 */ 112 * K,
|
||||
/* 0101 */ 4 * K,
|
||||
/* 0110 */ 80 * K,
|
||||
/* 0111 */ 160 * K,
|
||||
/* 1000 */ 8 * K,
|
||||
/* 1001 */ 16 * K,
|
||||
/* 1010 */ 32 * K,
|
||||
/* 1011 */ 64 * K,
|
||||
/* 1100 */ 128 * K,
|
||||
/* 1101 */ 256 * K,
|
||||
/* 1110 */ 96 * K,
|
||||
/* 1111 */ 512 * K
|
||||
};
|
||||
|
||||
static const struct { unsigned id; const char *name; } archs[] = {
|
||||
{AT91_ARCH_AT75Cxx, "AT75Cxx"},
|
||||
{AT91_ARCH_AT91x40, "AT91x40"},
|
||||
{AT91_ARCH_AT91x63, "AT91x63"},
|
||||
{AT91_ARCH_AT91x55, "AT91x55"},
|
||||
{AT91_ARCH_AT91x42, "AT91x42"},
|
||||
{AT91_ARCH_AT91x92, "AT91x92"},
|
||||
{AT91_ARCH_AT91x34, "AT91x34"},
|
||||
{AT91_ARCH_AT91SAM7Axx, "AT91SAM7Axx"},
|
||||
{AT91_ARCH_AT91SAM7Sxx, "AT91SAM7Sxx"},
|
||||
{AT91_ARCH_AT91SAM7XC, "AT91SAM7XC"},
|
||||
{AT91_ARCH_AT91SAM7SExx, "AT91SAM7SExx"},
|
||||
{AT91_ARCH_AT91SAM7Lxx, "AT91SAM7Lxx"},
|
||||
{AT91_ARCH_AT91SAM7Xxx, "AT91SAM7Xxx"},
|
||||
{AT91_ARCH_AT91SAM9xx, "AT91SAM9xx"}
|
||||
};
|
||||
|
||||
const char *at91_arch_str( int id ) {
|
||||
int i;
|
||||
for( i=0 ; i<(sizeof(archs)/sizeof(*archs)) ; i++ ) {
|
||||
if( archs[i].id == id ) {
|
||||
return archs[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
at91_chip_info_t samba_chip_info;
|
||||
|
||||
int samba_init( void )
|
||||
{
|
||||
uint32_t chipid;
|
||||
uint16_t response;
|
||||
|
||||
if( io_send_cmd( "N#", &response, sizeof( response ) ) < 0 ) {
|
||||
printf( "can't init boot program: %s\n", strerror( errno ) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( samba_read_word( 0xfffff240, &chipid ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
samba_chip_info.version = AT91_CHIPID_VERSION( chipid );
|
||||
samba_chip_info.eproc = AT91_CHIPID_EPROC( chipid );
|
||||
samba_chip_info.nvpsiz = nvpsizs[AT91_CHIPID_NVPSIZ( chipid )];
|
||||
samba_chip_info.nvpsiz2 = nvpsizs[AT91_CHIPID_NVPSIZ2( chipid )];
|
||||
samba_chip_info.sramsiz = sramsizs[AT91_CHIPID_SRAMSIZ( chipid )];
|
||||
samba_chip_info.arch = AT91_CHIPID_ARCH( chipid );
|
||||
|
||||
if( samba_chip_info.arch == AT91_ARCH_AT91SAM7Sxx ) {
|
||||
switch( samba_chip_info.nvpsiz) {
|
||||
case 32*K:
|
||||
samba_chip_info.page_size = 128;
|
||||
samba_chip_info.lock_bits = 8;
|
||||
break;
|
||||
|
||||
case 64*K:
|
||||
samba_chip_info.page_size = 128;
|
||||
samba_chip_info.lock_bits = 16;
|
||||
break;
|
||||
|
||||
case 128*K:
|
||||
samba_chip_info.page_size = 256;
|
||||
samba_chip_info.lock_bits = 8;
|
||||
break;
|
||||
|
||||
case 256*K:
|
||||
samba_chip_info.page_size = 256;
|
||||
samba_chip_info.lock_bits = 16;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf( "unknown sam7s flash size %d\n", samba_chip_info.nvpsiz );
|
||||
return -1;
|
||||
}
|
||||
} else if( samba_chip_info.arch == AT91_ARCH_AT91SAM7SExx ) {
|
||||
|
||||
switch( samba_chip_info.nvpsiz) {
|
||||
case 32*K:
|
||||
samba_chip_info.page_size = 128;
|
||||
samba_chip_info.lock_bits = 8;
|
||||
break;
|
||||
|
||||
case 64*K:
|
||||
samba_chip_info.page_size = 128;
|
||||
samba_chip_info.lock_bits = 16;
|
||||
break;
|
||||
|
||||
case 128*K:
|
||||
samba_chip_info.page_size = 256;
|
||||
samba_chip_info.lock_bits = 8;
|
||||
break;
|
||||
|
||||
case 256*K:
|
||||
samba_chip_info.page_size = 256;
|
||||
samba_chip_info.lock_bits = 16;
|
||||
break;
|
||||
|
||||
case 512*K:
|
||||
samba_chip_info.page_size = 256;
|
||||
samba_chip_info.lock_bits = 32;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf( "unknown sam7se flash size %d\n", samba_chip_info.nvpsiz );
|
||||
return -1;
|
||||
}
|
||||
} else if( samba_chip_info.arch == AT91_ARCH_AT91SAM7Xxx ) {
|
||||
|
||||
switch( samba_chip_info.nvpsiz ) {
|
||||
case 128*K:
|
||||
samba_chip_info.page_size = 256;
|
||||
samba_chip_info.lock_bits = 8;
|
||||
break;
|
||||
|
||||
case 256*K:
|
||||
samba_chip_info.page_size = 256;
|
||||
samba_chip_info.lock_bits = 16;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf( "unknown sam7x srflashsize %d\n", samba_chip_info.nvpsiz );
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
printf( "Page size info of %s not known\n",
|
||||
at91_arch_str( samba_chip_info.arch ) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Chip Version: %d\n", samba_chip_info.version );
|
||||
printf("Embedded Processor: %s\n", eprocs[samba_chip_info.eproc] );
|
||||
printf("NVRAM Region 1 Size: %d K\n", samba_chip_info.nvpsiz / K );
|
||||
printf("NVRAM Region 2 Size: %d K\n", samba_chip_info.nvpsiz2 / K );
|
||||
printf("SRAM Size: %d K\n", samba_chip_info.sramsiz / K );
|
||||
printf("Series: %s\n", at91_arch_str( samba_chip_info.arch ) );
|
||||
printf("Page Size: %d bytes\n", samba_chip_info.page_size );
|
||||
printf("Lock Regions: %d\n", samba_chip_info.lock_bits );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int samba_write_byte( uint32_t addr, uint8_t value )
|
||||
{
|
||||
char cmd[64];
|
||||
|
||||
snprintf( cmd, 64, "O%08X,%02X#", (unsigned int) addr,
|
||||
(unsigned int) value );
|
||||
|
||||
return io_send_cmd( cmd, NULL, 0 );
|
||||
}
|
||||
|
||||
int samba_read_byte( uint32_t addr, uint8_t *value )
|
||||
{
|
||||
char cmd[64];
|
||||
|
||||
snprintf( cmd, 64, "o%08X,1#", (unsigned int) addr );
|
||||
|
||||
return io_send_cmd( cmd, value, 1 );
|
||||
}
|
||||
|
||||
int samba_write_half_word( uint32_t addr, uint16_t value )
|
||||
{
|
||||
char cmd[64];
|
||||
|
||||
snprintf( cmd, 64, "H%08X,%04X#", (unsigned int) addr,
|
||||
(unsigned int) value );
|
||||
|
||||
|
||||
return io_send_cmd( cmd, NULL, 0 );
|
||||
}
|
||||
|
||||
int samba_read_half_word( uint32_t addr, uint16_t *value )
|
||||
{
|
||||
char cmd[64];
|
||||
int err;
|
||||
|
||||
snprintf( cmd, 64, "h%X,2#", (unsigned int) addr );
|
||||
|
||||
err = io_send_cmd( cmd, value, 2 );
|
||||
*value = le2hs( *value );
|
||||
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
int samba_write_word( uint32_t addr, uint32_t value )
|
||||
{
|
||||
char cmd[64];
|
||||
|
||||
snprintf( cmd, 64, "W%08X,%08X#", (unsigned int) addr,
|
||||
(unsigned int) value );
|
||||
|
||||
return io_send_cmd( cmd, NULL, 0 );
|
||||
}
|
||||
|
||||
int samba_read_word( uint32_t addr, uint32_t *value )
|
||||
{
|
||||
char cmd[64];
|
||||
int err;
|
||||
|
||||
snprintf( cmd, 64, "w%08X,4#", (unsigned int) addr );
|
||||
|
||||
err = io_send_cmd( cmd, value, 4 );
|
||||
*value = le2hl( *value );
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int samba_send_file( uint32_t addr, uint8_t *buff, int len )
|
||||
{
|
||||
char cmd[64];
|
||||
int i=0;
|
||||
|
||||
snprintf( cmd, 64, "S%X,%X#", (unsigned int) addr, (unsigned int) len );
|
||||
|
||||
if( io_write( cmd, strlen( cmd ) ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
usleep( 2000 );
|
||||
|
||||
for( i=0 ; i<len ; i+=64 ) {
|
||||
if( io_write( buff+i, (len-i < 64)? len-i : 64 ) < 0 ){
|
||||
return -1;
|
||||
}
|
||||
usleep( 2000 );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int samba_recv_file( uint32_t addr, uint8_t *buff, int len )
|
||||
{
|
||||
char cmd[64];
|
||||
int i=0;
|
||||
|
||||
snprintf( cmd, 64, "R%X,%X#", (unsigned int) addr, (unsigned int) len );
|
||||
|
||||
if( io_write( cmd, strlen( cmd ) ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
usleep( 2000 );
|
||||
|
||||
for( i=0 ; i<len ; i+=64 ) {
|
||||
if( io_read( buff+i, (len-i < 64)? len-i : 64 ) < 0 ){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int samba_go( uint32_t addr )
|
||||
{
|
||||
char cmd[64];
|
||||
snprintf( cmd, 64, "G%08X#", (unsigned int) addr );
|
||||
|
||||
return io_send_cmd( cmd, NULL, 0 );
|
||||
}
|
||||
|
||||
int samba_get_version( char *version, int len )
|
||||
{
|
||||
#if 0
|
||||
if( io_send_cmd( "V#", version, len ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
/* don't know the new form of V# */
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* samba.h
|
||||
*
|
||||
* Copyright (C) 2005 Erik Gilling, all rights reserved
|
||||
*
|
||||
* 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, version 2.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __samba_h__
|
||||
#define __samba_h__
|
||||
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#define AT91_CHIPID_VERSION( chipid ) (((chipid)>>0)&0x1f)
|
||||
#define AT91_CHIPID_EPROC( chipid ) (((chipid)>>5)&0x7)
|
||||
#define AT91_CHIPID_NVPSIZ( chipid ) (((chipid)>>8)&0xf)
|
||||
#define AT91_CHIPID_NVPSIZ2( chipid ) (((chipid)>>12)&0xf)
|
||||
#define AT91_CHIPID_SRAMSIZ( chipid ) (((chipid)>>16)&0xf)
|
||||
#define AT91_CHIPID_ARCH( chipid ) (((chipid)>>20)&0xff)
|
||||
#define AT91_CHIPID_NVPTYP( chipid ) (((chipid)>>28)&0x7)
|
||||
#define AT91_CHIPID_EXT( chipid ) (((chipid)>>31)&0x1)
|
||||
|
||||
#define AT91_ARCH_AT75Cxx 0xF0
|
||||
#define AT91_ARCH_AT91x40 0x40
|
||||
#define AT91_ARCH_AT91x63 0x63
|
||||
#define AT91_ARCH_AT91x55 0x55
|
||||
#define AT91_ARCH_AT91x42 0x42
|
||||
#define AT91_ARCH_AT91x92 0x92
|
||||
#define AT91_ARCH_AT91x34 0x34
|
||||
#define AT91_ARCH_AT91SAM7Axx 0x60
|
||||
#define AT91_ARCH_AT91SAM7Sxx 0x70
|
||||
#define AT91_ARCH_AT91SAM7XC 0x71
|
||||
#define AT91_ARCH_AT91SAM7SExx 0x72
|
||||
#define AT91_ARCH_AT91SAM7Lxx 0x73
|
||||
#define AT91_ARCH_AT91SAM7Xxx 0x75
|
||||
#define AT91_ARCH_AT91SAM9xx 0x19
|
||||
|
||||
typedef struct {
|
||||
int version;
|
||||
int eproc;
|
||||
int nvpsiz;
|
||||
int nvpsiz2;
|
||||
int sramsiz;
|
||||
int arch;
|
||||
int page_size;
|
||||
int lock_bits;
|
||||
} at91_chip_info_t;
|
||||
|
||||
extern at91_chip_info_t samba_chip_info;
|
||||
|
||||
int samba_init( void );
|
||||
int samba_write_byte( uint32_t addr, uint8_t value );
|
||||
int samba_read_byte( uint32_t addr, uint8_t *value );
|
||||
int samba_write_half_word( uint32_t addr, uint16_t value );
|
||||
int samba_read_half_word( uint32_t addr, uint16_t *value );
|
||||
int samba_write_word( uint32_t addr, uint32_t value );
|
||||
int samba_read_word( uint32_t addr, uint32_t *value );
|
||||
int samba_send_file( uint32_t addr, uint8_t *buff, int len );
|
||||
int samba_recv_file( uint32_t addr, uint8_t *buff, int len );
|
||||
int samba_go( uint32_t addr );
|
||||
int samba_get_version( char *version, int len );
|
||||
|
||||
#endif /* __samba_h__ */
|
Reference in New Issue