1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

* import from old firekernel repository

This commit is contained in:
Kaspar Schleiser 2010-09-22 15:10:42 +02:00
commit 91ae1eb6fd
284 changed files with 24839 additions and 0 deletions

72
Jamfile Normal file
View File

@ -0,0 +1,72 @@
# ******************************************************************************
# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
#
# These sources were developed at the Freie Universitaet Berlin, Computer
# Systems and Telematics group (http://cst.mi.fu-berlin.de).
# ------------------------------------------------------------------------------
# This file is part of FeuerWare.
#
# 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.
#
# FeuerWare 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/ .
# ------------------------------------------------------------------------------
# For further information and questions please use the web site
# http://scatterweb.mi.fu-berlin.de
# and the mailinglist (subscription via web site)
# scatterweb@lists.spline.inf.fu-berlin.de
# ******************************************************************************
# $Id$
SubDir TOP ;
#
# Target directory: bin directory located in BUILD_ROOT
#
TARGET_DIR ?= [ FPath $(BUILD_ROOT) bin $(BOARD) $(PROJECT) ] ;
LOCATE_TARGET = $(TARGET_DIR) ;
ALL_LOCATE_TARGET = $(TARGET_DIR) ;
echo "Building project '$(PROJECT)' for '$(BOARD)' board." ;
#
# Buil utility targets
#
Help ? ; # display usage from manual
Help help ;
Help usage ;
Help targets ;
Cleanall cleanall ; # clean all binaries
#
# Main target
#
Main $(TARGET) ;
Depends all : $(TARGET:S=.hex) ; # always build a hex-file
LOCATE on $(TARGET) = bin ;
LOCATE on $(TARGET:S=.hex) = bin ;
#
# Utility targets
#
Doc doc ; # build the documentation
Flash flash : $(TARGET:S=.hex) ;
Reset reset ;
Debug debug : $(TARGET) ;
ListModules listmodules ;
ShowFlags showflags : $(TARGET) ;
SubInclude TOP projects $(PROJECT) ;
SubInclude TOP sys ;
SubInclude TOP core ;
SubInclude TOP drivers ;
SubInclude TOP board ;

74
Jamrules Normal file
View File

@ -0,0 +1,74 @@
# ******************************************************************************
# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
#
# These sources were developed at the Freie Universitaet Berlin, Computer
# Systems and Telematics group (http://cst.mi.fu-berlin.de).
# ------------------------------------------------------------------------------
# This file is part of FeuerWare.
#
# 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.
#
# FeuerWare 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/ .
# ------------------------------------------------------------------------------
# For further information and questions please use the web site
# http://scatterweb.mi.fu-berlin.de
# and the mailinglist (subscription via web site)
# scatterweb@lists.spline.inf.fu-berlin.de
# ******************************************************************************
# $Id$
#
# Include build system functionality
#
include $(TOP)$(SLASH)Jamrules.common ;
#
# Setup FeuerWare build system configuration (default values for common options)
#
PROJECT = $(PROJECT:E=hello-world) ;
BOARD = $(BOARD:E=msba2) ;
SUFFIX ?= "" ; # must be at least "" !!!
TARGET = "$(BOARD)-$(PROJECT)$(SUFFIX)$(SUFEXE)" ; # main target binary
OPENOCD_IF ?= olimex-jtag-tiny-a ;
if $(NT) || $(OS) = CYGWIN {
PORT = $(PORT:E=1) ;
} else {
PORT = $(PORT:E=/dev/ttyUSB0) ;
}
CCFLAGS += -DBOARD=BOARD_$(BOARD:U) ;
#
# core source directories
HDRS += $(TOP) ;
HDRS += [ FPath $(TOP) core include ] ;
HDRS += [ FPath $(TOP) hal include ] ;
HDRS += [ FPath $(TOP) sys include ] [ FPath $(TOP) sys config ] [ FPath $(TOP) sys drivers include ] [ FPath $(TOP) sys drivers cc110x ] [ FPath $(TOP) sys drivers nanopan5375 ] ;
HDRS += [ FPath $(TOP) sys net ] ;
HDRS += [ FPath $(TOP) sys lib ] [ FPath $(TOP) sys lib fat include ] ;
HDRS += [ FPath $(TOP) sys lib gps ] [ FPath $(TOP) sys lib gps drivers ] [ FPath $(TOP) sys lib gps geo ] ;
HDRS += [ FPath $(TOP) sys net phy ] [ FPath $(TOP) sys net mm ] ;
# Include board files
include [ FPath $(TOP) board $(BOARD) Jamrules.$(BOARD) ] ;
# Include cpu files
include [ FPath $(TOP) cpu $(CPU) Jamrules.$(CPU) ] ;
#
# standard target source directories
HDRS += [ FPath $(TOP) board $(BOARD) include ] ;
HDRS += [ FPath $(TOP) cpu $(CPU) include ] ;
HDRS += [ FPath $(TOP) projects $(PROJECT) ] ;
# drivers
HDRS += [ FPath $(TOP) drivers include ] ;
HDRS += [ FPath $(TOP) drivers cc110x ] ;

342
Jamrules.common Normal file
View File

@ -0,0 +1,342 @@
# ******************************************************************************
# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
#
# These sources were developed at the Freie Universitaet Berlin, Computer
# Systems and Telematics group (http://cst.mi.fu-berlin.de).
# ------------------------------------------------------------------------------
# This file is part of FeuerWare.
#
# 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.
#
# FeuerWare 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/ .
# ------------------------------------------------------------------------------
# For further information and questions please use the web site
# http://scatterweb.mi.fu-berlin.de
# and the mailinglist (subscription via web site)
# scatterweb@lists.spline.inf.fu-berlin.de
# ******************************************************************************
# $Id$
#
# OS specifics
#
if $(NT) {
POSIXSHELL = sh ;
NULLDEV = NUL ;
CAT = type ;
NOARSCAN = true ;
# redefine build rules for gcc on NT
SUFOBJ = .o ;
SUFLIB = .a ;
actions As
{
$(AS) $(ASFLAGS) $(ASHDRS) -o $(<) $(>)
}
actions Cc
{
$(CC) -c -o $(<) $(CCFLAGS) -D$(MODULE_DEFINES) $(CCDEFS) $(CCHDRS) $(>)
}
rule FDefines { return -D$(<) ; }
rule FIncludes { return -I$(<) ; }
} else {
NULLDEV = /dev/null ;
CAT = cat ;
RM = rm -rf ;
# use english language output for gcc
actions Cc
{
LANG=C $(CC) -c -o $(<) $(CCFLAGS) -D$(MODULE_DEFINES) $(CCDEFS) $(CCHDRS) $(>)
}
switch $(OS) {
case CYGWIN :
# archive scanning does not work on cygwin, so leave object files
NOARSCAN = true ;
}
}
#
# Plausbility checks and defaults
#
SUFEXE = .elf ;
#
# Rules and Actions
#
#
# Concatenates path-segments into a OS specific path string
# Usage: PATH = [ FPath path-segments ] ;
rule FPath
{
return $(<:J=$(SLASH)) ;
}
#
# Generate object archive
actions updated together piecemeal Archive
{
$(AR) $(ARFLAGS) $(<) $(>)
}
#
# Link target
rule Link
{
# add map file
Clean clean : $(<:S=.map) ;
# generation of hex file
Hexfile $(<:S=.hex) : $(<) ;
}
actions Link bind NEEDLIBS
{
echo "Old firmware size:"
$(TOOLCHAIN)size $(<) 2> $(NULLDEV) || echo " No old binary for size comparison..."
$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) -Wl,--start-group $(NEEDLIBS) $(LINKLIBS) -lm -Wl,--end-group -Wl,-Map=$(<:S=.map) || $(RM) -f $(<) $(<:S=.map) $(<:S=.hex)
echo "New firmware size:"
$(TOOLCHAIN)size $(<)
}
#
# Clean binaries
actions piecemeal together existing Clean
{
# remove all jam targets
$(RM) $(>)
}
#
# Clean binaries regardless of project and board
rule Cleanall { }
actions Cleanall
{
echo "> Cleaning binaries"
$(RM) bin$(SLASH)*
make -C $(TOP)$(SLASH)doc clean
}
#
# Display usage text from manual
rule Help { }
actions Help
{
$(CAT) $(TOP)$(SLASH)doc$(SLASH)src$(SLASH)manual$(SLASH)examples$(SLASH)jam-usage.txt
}
#
# Compile documentation
rule Doc { }
actions Doc
{
make -C $(TOP)$(SLASH)doc all
}
#
# Generate hex-file from binary
rule Hexfile
{
MakeLocate $(<) : $(LOCATE_TARGET) ;
Depends $(<) : $(>) ;
SEARCH on $(>) = $(LOCATE_TARGET) ;
Clean clean : $(<) ;
}
actions Hexfile
{
$(OBJCOPY) -O ihex $(>) $(<)
}
#
# Program binary to target device
rule Flash
{
Depends $(<) : $(>) ;
}
actions Flash
{
$(FLASHER) $(FLASHFLAGS) $(>)
}
# Reset connected sensor node
actions Reset
{
$(RESET) > /dev/null 2>&1
}
#
# Run debug server
rule Debug
{
Depends $(<) : $(>) ;
}
actions Debug
{
$(GDB) $(GDBFLAGS) $(>)
}
#
# Rules for convenient module building & dependency tracking
rule Module
{
local _m = $(<:S=$(SUFLIB)) ;
# echo Module Name: $(<) Files: $(>) Dependencies: $(3) ;
DEFINED_MODULES += $(_m) ;
ModuleFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
ObjectsNoDep $(>) ;
ModuleDepends $(_m) : $(3) ;
if $(_m) in $(USE_MODULES) {
UseModule $(_m) ;
}
}
# Add a pre-built library as module
# Syntax: BinModule <Module Name = $(<)> ;
rule BinModule
{
local _m = $(<:S=$(SUFLIB)) ;
DEFINED_MODULES += $(_m) ;
BINARY_MODULES += $(_m) ;
ModuleDepends $(_m) : $(3) ;
if $(_m) in $(USE_MODULES) {
UseModule $(_m) ;
}
}
rule ModuleDepends
{
local _m = $(<:S=$(SUFLIB)) ;
local _d = $(>:S=$(SUFLIB)) ;
# for DEP in $(_d) {
Depends $(_m) : $(_d) ;
DEPENDS.$(_m) += $(_d) ;
# }
}
rule UseModule
{
local _m = $(<:S=$(SUFLIB)) ;
if $(_m) in $(BINARY_MODULES) {
local _l _s ;
_l = $(<:S=$(SUFLIB)) ; # name of the library file
_s = [ FGristFiles $(_l) ] ; # source
MakeLocate $(_l) : $(LOCATE_TARGET) ; # locate to bin directory
File $(TARGET_DIR)/$(_l) : $(_s) ;
}
# echo UseModule $(<) ;
if ! $(_m) in $(DEFINED_MODULES) {
# echo Module not defined yet. ;
USE_MODULES += $(_m) ;
} else {
LinkLibraries $(TARGET) : $(<) ;
local _mdefine = MODULE_$(_m:S=:U) ;
if ! $(_mdefine) in $(MODULE_DEFINES) {
MODULE_DEFINES += $(_mdefine) ;
}
# echo Dependencies of $(_m): $(DEPENDS.$(_m)) ;
for DEP in $(DEPENDS.$(_m)) {
UseModule $(DEP) ;
}
}
}
# (slightly modified version of LibraryFromObjects)
rule ModuleFromObjects
{
local _i _l _s ;
# Add grist to file names
_s = [ FGristFiles $(>) ] ;
_l = $(<:S=$(SUFLIB)) ;
# Set LOCATE for the library and its contents. The bound
# value shows up as $(NEEDLIBS) on the Link actions.
# For compatibility, we only do this if the library doesn't
# already have a path.
if ! $(_l:D)
{
MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;
}
if $(NOARSCAN)
{
# If we can't scan the library to timestamp its contents,
# we have to just make the library depend directly on the
# on-disk object files.
Depends $(_l) : $(_s) ;
}
else
{
# If we can scan the library, we make the library depend
# on its members and each member depend on the on-disk
# object file.
Depends $(_l) : $(_l)($(_s:BS)) ;
for _i in $(_s)
{
Depends $(_l)($(_i:BS)) : $(_i) ;
}
}
Clean clean : $(_l) ;
if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }
Archive $(_l) : $(_s) ;
if $(RANLIB) { Ranlib $(_l) ; }
# If we can't scan the library, we have to leave the .o's around.
if ! ( $(NOARSCAN) || $(NOARUPDATE) ) { RmTemps $(_l) : $(_s) ; }
}
#
# Like Objects, but doesn't set dependencies on obj pѕeudotarget.
rule ObjectsNoDep
{
local _i ;
for _i in [ FGristFiles $(<) ]
{
Object $(_i:S=$(SUFOBJ)) : $(_i) ;
}
}
actions ListModules {
echo $(MODULE_DEFINES) | tr ' ' '\n' | sort
}
actions ShowFlags {
echo "CCFLAGS: "
echo $(CCFLAGS) $(CCDEFS) -D$(MODULE_DEFINES) | tr ' ' '\n ' | sort
echo "" | $(CC) -E -dD -
}

674
LICENSE Normal file
View File

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

9
README Normal file
View File

@ -0,0 +1,9 @@
License
=======
* All sources and binaries that have been developed at Freie Universität Berlin are
licensed under the GNU General Public License version 3 as published by the
Free Software Foundation.
* Some external sources, especially files developed by SICS are published under
a separate license.
All code files contain licensing information.

3
board/Jamfile Normal file
View File

@ -0,0 +1,3 @@
SubDir TOP board ;
SubInclude TOP board $(BOARD) ;

View File

@ -0,0 +1,10 @@
SubDir TOP board eZ430-Chronos ;
HDRS += $(TOP)/board/$(CPU)/include ;
Module board : debug_uart.c board_init.c ;
UseModule board ;
SubInclude TOP board $(BOARD) drivers ;
SubInclude TOP cpu $(CPU) ;

View File

@ -0,0 +1,12 @@
# ******************************************************************************
# Copyright 2010, Freie Universitaet Berlin (FUB). All rights reserved.
# ******************************************************************************
# $Id$
BOARD = eZ430-Chronos ;
CPU = msp430 ;
MCU = cc430x6137 ;
FLASHER ?= mspdebug ;
FLASHFLAGS ?= rf2500 ;

View File

@ -0,0 +1,2 @@
void board_init() {
}

View File

@ -0,0 +1,21 @@
#include <stdio.h>
#include "board.h"
#define UART1_TX TXBUF1
#define UART1_WAIT_TXDONE() while( (UTCTL1 & TXEPT) == 0 ) { _NOP(); }
int putchar(int c)
{
// UART1_TX = c;
// UART1_WAIT_TXDONE();
//
// if (c == 10) {
// UART1_TX = 13;
// UART1_WAIT_TXDONE();
// }
return c;
}

View File

@ -0,0 +1,5 @@
SubDir TOP board eZ430-Chronos drivers ;
UseModule board_common ;
Module board_common : display.c display1.c ;

View File

@ -0,0 +1,519 @@
// *************************************************************************************************
//
// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
//
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// *************************************************************************************************
// Display functions.
// *************************************************************************************************
// *************************************************************************************************
// Include section
// system
#include <string.h>
// driver
#include "cc430x613x.h"
#include "display.h"
// *************************************************************************************************
// Prototypes section
void write_lcd_mem(uint8_t * lcdmem, uint8_t bits, uint8_t bitmask, uint8_t state);
void clear_line(uint8_t line);
void display_symbol(uint8_t symbol, uint8_t mode);
void display_char(uint8_t segment, uint8_t chr, uint8_t mode);
void display_chars(uint8_t segments, uint8_t * str, uint8_t mode);
// *************************************************************************************************
// Defines section
// *************************************************************************************************
// Global Variable section
// Display flags
volatile s_display_flags display;
// Global return string for itoa function
uint8_t itoa_str[8];
// *************************************************************************************************
// @fn lcd_init
// @brief Erase LCD memory. Init LCD peripheral.
// @param none
// @return none
// *************************************************************************************************
void lcd_init(void)
{
// Clear entire display memory
LCDBMEMCTL |= LCDCLRBM + LCDCLRM;
// LCD_FREQ = ACLK/16/8 = 256Hz
// Frame frequency = 256Hz/4 = 64Hz, LCD mux 4, LCD on
LCDBCTL0 = (LCDDIV0 + LCDDIV1 + LCDDIV2 + LCDDIV3) | (LCDPRE0 + LCDPRE1) | LCD4MUX | LCDON;
// LCB_BLK_FREQ = ACLK/8/4096 = 1Hz
LCDBBLKCTL = LCDBLKPRE0 | LCDBLKPRE1 | LCDBLKDIV0 | LCDBLKDIV1 | LCDBLKDIV2 | LCDBLKMOD0;
// I/O to COM outputs
P5SEL |= (BIT5 | BIT6 | BIT7);
P5DIR |= (BIT5 | BIT6 | BIT7);
// Activate LCD output
LCDBPCTL0 = 0xFFFF; // Select LCD segments S0-S15
LCDBPCTL1 = 0x00FF; // Select LCD segments S16-S22
#ifdef USE_LCD_CHARGE_PUMP
// Charge pump voltage generated internally, internal bias (V2-V4) generation
LCDBVCTL = LCDCPEN | VLCD_2_72;
#endif
}
// *************************************************************************************************
// @fn clear_display_all
// @brief Erase LINE1 and LINE2 segments. Clear also function-specific content.
// @param none
// @return none
// *************************************************************************************************
void clear_display_all(void)
{
// Clear generic content
clear_line(LINE1);
clear_line(LINE2);
}
// *************************************************************************************************
// @fn clear_display
// @brief Erase LINE1 and LINE2 segments. Keep icons.
// @param none
// @return none
// *************************************************************************************************
void clear_display(void)
{
clear_line(LINE1);
clear_line(LINE2);
}
// *************************************************************************************************
// @fn clear_line
// @brief Erase segments of a given line.
// @param uint8_t line LINE1, LINE2
// @return none
// *************************************************************************************************
void clear_line(uint8_t line)
{
display_chars(switch_seg(line, LCD_SEG_L1_3_0, LCD_SEG_L2_5_0), NULL, SEG_OFF);
if (line == LINE1)
{
display_symbol(LCD_SEG_L1_DP1, SEG_OFF);
display_symbol(LCD_SEG_L1_DP0, SEG_OFF);
display_symbol(LCD_SEG_L1_COL, SEG_OFF);
}
else // line == LINE2
{
display_symbol(LCD_SEG_L2_DP, SEG_OFF);
display_symbol(LCD_SEG_L2_COL1, SEG_OFF);
display_symbol(LCD_SEG_L2_COL0, SEG_OFF);
}
}
// *************************************************************************************************
// @fn write_segment
// @brief Write to one or multiple LCD segments
// @param lcdmem Pointer to LCD byte memory
// bits Segments to address
// bitmask Bitmask for particular display item
// mode On, off or blink segments
// @return
// *************************************************************************************************
void write_lcd_mem(uint8_t * lcdmem, uint8_t bits, uint8_t bitmask, uint8_t state)
{
if (state == SEG_ON)
{
// Clear segments before writing
*lcdmem = (uint8_t)(*lcdmem & ~bitmask);
// Set visible segments
*lcdmem = (uint8_t)(*lcdmem | bits);
}
else if (state == SEG_OFF)
{
// Clear segments
*lcdmem = (uint8_t)(*lcdmem & ~bitmask);
}
else if (state == SEG_ON_BLINK_ON)
{
// Clear visible / blink segments before writing
*lcdmem = (uint8_t)(*lcdmem & ~bitmask);
*(lcdmem+0x20) = (uint8_t)(*(lcdmem+0x20) & ~bitmask);
// Set visible / blink segments
*lcdmem = (uint8_t)(*lcdmem | bits);
*(lcdmem+0x20) = (uint8_t)(*(lcdmem+0x20) | bits);
}
else if (state == SEG_ON_BLINK_OFF)
{
// Clear visible segments before writing
*lcdmem = (uint8_t)(*lcdmem & ~bitmask);
// Set visible segments
*lcdmem = (uint8_t)(*lcdmem | bits);
// Clear blink segments
*(lcdmem+0x20) = (uint8_t)(*(lcdmem+0x20) & ~bitmask);
}
else if (state == SEG_OFF_BLINK_OFF)
{
// Clear segments
*lcdmem = (uint8_t)(*lcdmem & ~bitmask);
// Clear blink segments
*(lcdmem+0x20) = (uint8_t)(*(lcdmem+0x20) & ~bitmask);
}
}
// *************************************************************************************************
// @fn itoa
// @brief Generic integer to array routine. Converts integer n to string.
// Default conversion result has leading zeros, e.g. "00123"
// Option to convert leading '0' into whitespace (blanks)
// @param uint32_t n integer to convert
// uint8_t digits number of digits
// uint8_t blanks fill up result string with number of whitespaces instead of leading zeros
// @return uint8_t string
// *************************************************************************************************
uint8_t * itoa(uint32_t n, uint8_t digits, uint8_t blanks)
{
uint8_t i;
uint8_t digits1 = digits;
// Preset result string
memcpy(itoa_str, "0000000", 7);
// Return empty string if number of digits is invalid (valid range for digits: 1-7)
if ((digits == 0) || (digits > 7)) return (itoa_str);
// Numbers 0 .. 180 can be copied from itoa_conversion_table without conversion
if (n <= 180)
{
if (digits >= 3)
{
memcpy(itoa_str+(digits-3), itoa_conversion_table[n], 3);
}
else // digits == 1 || 2
{
memcpy(itoa_str, itoa_conversion_table[n]+(3-digits), digits);
}
}
else // For n > 180 need to calculate string content
{
// Calculate digits from least to most significant number
do
{
itoa_str[digits-1] = n % 10 + '0';
n /= 10;
} while (--digits > 0);
}
// Remove specified number of leading '0', always keep last one
i = 0;
while ((itoa_str[i] == '0') && (i < digits1-1))
{
if (blanks > 0)
{
// Convert only specified number of leading '0'
itoa_str[i]=' ';
blanks--;
}
i++;
}
return (itoa_str);
}
// *************************************************************************************************
// @fn display_value1
// @brief Generic decimal display routine. Used exclusively by set_value function.
// @param uint8_t segments LCD segments where value is displayed
// uint32_t value Integer value to be displayed
// uint8_t digits Number of digits to convert
// uint8_t blanks Number of leadings blanks in itoa result string
// @return none
// *************************************************************************************************
void display_value1(uint8_t segments, uint32_t value, uint8_t digits, uint8_t blanks, uint8_t disp_mode)
{
uint8_t * str;
str = itoa(value, digits, blanks);
// Display string in blink mode
display_chars(segments, str, disp_mode);
}
// *************************************************************************************************
// @fn display_symbol
// @brief Switch symbol on or off on LCD.
// @param uint8_t symbol A valid LCD symbol (index 0..42)
// uint8_t state SEG_ON, SEG_OFF, SEG_BLINK
// @return none
// *************************************************************************************************
void display_symbol(uint8_t symbol, uint8_t mode)
{
uint8_t * lcdmem;
uint8_t bits;
uint8_t bitmask;
if (symbol <= LCD_SEG_L2_DP)
{
// Get LCD memory address for symbol from table
lcdmem = (uint8_t *)segments_lcdmem[symbol];
// Get bits for symbol from table
bits = segments_bitmask[symbol];
// Bitmask for symbols equals bits
bitmask = bits;
// Write LCD memory
write_lcd_mem(lcdmem, bits, bitmask, mode);
}
}
// *************************************************************************************************
// @fn display_char
// @brief Write to 7-segment characters.
// @param uint8_t segment A valid LCD segment
// uint8_t chr Character to display
// uint8_t mode SEG_ON, SEG_OFF, SEG_BLINK
// @return none
// *************************************************************************************************
void display_char(uint8_t segment, uint8_t chr, uint8_t mode)
{
uint8_t * lcdmem; // Pointer to LCD memory
uint8_t bitmask; // Bitmask for character
uint8_t bits, bits1; // Bits to write
// Write to single 7-segment character
if ((segment >= LCD_SEG_L1_3) && (segment <= LCD_SEG_L2_DP))
{
// Get LCD memory address for segment from table
lcdmem = (uint8_t *)segments_lcdmem[segment];
// Get bitmask for character from table
bitmask = segments_bitmask[segment];
// Get bits from font set
if ((chr >= 0x30) && (chr <= 0x5A))
{
// Use font set
bits = lcd_font[chr-0x30];
}
else if (chr == 0x2D)
{
// '-' not in font set
bits = BIT1;
}
else
{
// Other characters map to ' ' (blank)
bits = 0;
}
// When addressing LINE2 7-segment characters need to swap high- and low-nibble,
// because LCD COM/SEG assignment is mirrored against LINE1
if (segment >= LCD_SEG_L2_5)
{
bits1 = ((bits << 4) & 0xF0) | ((bits >> 4) & 0x0F);
bits = bits1;
// When addressing LCD_SEG_L2_5, need to convert ASCII '1' and 'L' to 1 bit,
// because LCD COM/SEG assignment is special for this incomplete character
if (segment == LCD_SEG_L2_5)
{
if ((chr == '1') || (chr == 'L')) bits = BIT7;
}
}
// Physically write to LCD memory
write_lcd_mem(lcdmem, bits, bitmask, mode);
}
}
// *************************************************************************************************
// @fn display_chars
// @brief Write to consecutive 7-segment characters.
// @param uint8_t segments LCD segment array
// uint8_t * str Pointer to a string
// uint8_t mode SEG_ON, SEG_OFF, SEG_BLINK
// @return none
// *************************************************************************************************
void display_chars(uint8_t segments, uint8_t * str, uint8_t mode)
{
uint8_t i;
uint8_t length = 0; // Write length
uint8_t char_start = 0; // Starting point for consecutive write
switch (segments)
{
// LINE1
case LCD_SEG_L1_3_0: length=4; char_start=LCD_SEG_L1_3; break;
case LCD_SEG_L1_2_0: length=3; char_start=LCD_SEG_L1_2; break;
case LCD_SEG_L1_1_0: length=2; char_start=LCD_SEG_L1_1; break;
case LCD_SEG_L1_3_1: length=3; char_start=LCD_SEG_L1_3; break;
case LCD_SEG_L1_3_2: length=2; char_start=LCD_SEG_L1_3; break;
// LINE2
case LCD_SEG_L2_5_0: length=6; char_start=LCD_SEG_L2_5; break;
case LCD_SEG_L2_4_0: length=5; char_start=LCD_SEG_L2_4; break;
case LCD_SEG_L2_3_0: length=4; char_start=LCD_SEG_L2_3; break;
case LCD_SEG_L2_2_0: length=3; char_start=LCD_SEG_L2_2; break;
case LCD_SEG_L2_1_0: length=2; char_start=LCD_SEG_L2_1; break;
case LCD_SEG_L2_5_4: length=2; char_start=LCD_SEG_L2_5; break;
case LCD_SEG_L2_5_2: length=4; char_start=LCD_SEG_L2_5; break;
case LCD_SEG_L2_3_2: length=2; char_start=LCD_SEG_L2_3; break;
case LCD_SEG_L2_4_2: length=3; char_start=LCD_SEG_L2_4; break;
}
// Write to consecutive digits
for(i=0; i<length; i++)
{
// Use single character routine to write display memory
display_char(char_start+i, *(str+i), mode);
}
}
// *************************************************************************************************
// @fn switch_seg
// @brief Returns index of 7-segment character. Required for display routines that can draw
// information on both lines.
// @param uint8_t line LINE1, LINE2
// uint8_t index1 Index of LINE1
// uint8_t index2 Index of LINE2
// @return uint8
// *************************************************************************************************
uint8_t switch_seg(uint8_t line, uint8_t index1, uint8_t index2)
{
if (line == LINE1)
{
return index1;
}
else // line == LINE2
{
return index2;
}
}
// *************************************************************************************************
// @fn start_blink
// @brief Start blinking.
// @param none
// @return none
// *************************************************************************************************
void start_blink(void)
{
LCDBBLKCTL |= LCDBLKMOD0;
}
// *************************************************************************************************
// @fn stop_blink
// @brief Stop blinking.
// @param none
// @return none
// *************************************************************************************************
void stop_blink(void)
{
LCDBBLKCTL &= ~LCDBLKMOD0;
}
// *************************************************************************************************
// @fn stop_blink
// @brief Clear blinking memory.
// @param none
// @return none
// *************************************************************************************************
void clear_blink_mem(void)
{
LCDBMEMCTL |= LCDCLRBM;
}
// *************************************************************************************************
// @fn set_blink_rate
// @brief Set blink rate register bits.
// @param none
// @return none
// *************************************************************************************************
void set_blink_rate(uint8_t bits)
{
LCDBBLKCTL &= ~(BIT7 | BIT6 | BIT5);
LCDBBLKCTL |= bits;
}
// *************************************************************************************************
// @fn display_all_off
// @brief Sets everything of on the display
// @param none
// @return none
// *************************************************************************************************
void display_all_off(void)
{
uint8_t * lcdptr = (uint8_t*)0x0A20;
uint8_t i;
for (i=1; i<=12; i++)
{
*lcdptr = 0x00;
lcdptr++;
}
}

View File

@ -0,0 +1,360 @@
// *************************************************************************************************
//
// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
//
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// *************************************************************************************************
#ifndef __DISPLAY_H
#define __DISPLAY_H
// *************************************************************************************************
// Include section
/*
* Set some options at compile time for how the time is displayed
* The options are, in order of code space used-
* OPTION_TIME_DISPLAY == CLOCK_24HR
* OPTION_TIME_DISPLAY == CLOCK_AM_PM
* OPTION_TIME_DISPLAY == CLOCK_DISPLAY_SELECT
*/
#define CLOCK_24HR 0
#define CLOCK_AM_PM 1
#define CLOCK_DISPLAY_SELECT 2
// *************************************************************************************************
// Extern section
// *************************************************************************************************
// Global Variable section
// Set of display flags
typedef union
{
struct
{
// Line1 + Line2 + Icons
uint16_t full_update : 1; // 1 = Redraw all content
uint16_t partial_update : 1; // 1 = Update changes
// Line only
uint16_t line1_full_update : 1; // 1 = Redraw Line1 content
uint16_t line2_full_update : 1; // 1 = Redraw Line2 content
// Logic module data update flags
uint16_t update_time : 1; // 1 = Time was updated
uint16_t update_stopwatch : 1; // 1 = Stopwatch was updated
uint16_t update_temperature : 1; // 1 = Temperature was updated
uint16_t update_battery_voltage : 1; // 1 = Battery voltage was updated
uint16_t update_date : 1; // 1 = Date was updated
uint16_t update_alarm : 1; // 1 = Alarm time was updated
uint16_t update_acceleration : 1; // 1 = Acceleration data was updated
} flag;
uint16_t all_flags; // Shortcut to all display flags (for reset)
} s_display_flags;
extern volatile s_display_flags display;
// Constants defined in library
extern const uint8_t lcd_font[];
extern const uint8_t * segments_lcdmem[];
extern const uint8_t segments_bitmask[];
extern const uint8_t itoa_conversion_table[][3];
// *************************************************************************************************
// Defines section
// Display function modes
#define DISPLAY_LINE_UPDATE_FULL (BIT0)
#define DISPLAY_LINE_UPDATE_PARTIAL (BIT1)
#define DISPLAY_LINE_CLEAR (BIT2)
// Definitions for line view style
#define DISPLAY_DEFAULT_VIEW (0u)
#define DISPLAY_ALTERNATIVE_VIEW (1u)
#define DISPLAY_ALTERNATIVE2_VIEW (2u)
// Definitions for line access
#define LINE1 (1u)
#define LINE2 (2u)
// LCD display modes
#define SEG_OFF (0u)
#define SEG_ON (1u)
#define SEG_ON_BLINK_ON (2u)
#define SEG_ON_BLINK_OFF (3u)
#define SEG_OFF_BLINK_OFF (4u)
// 7-segment character bit assignments
#define SEG_A (BIT4)
#define SEG_B (BIT5)
#define SEG_C (BIT6)
#define SEG_D (BIT7)
#define SEG_E (BIT2)
#define SEG_F (BIT0)
#define SEG_G (BIT1)
// ------------------------------------------
// LCD symbols for easier access
//
// xxx_SEG_xxx = Seven-segment character (sequence 5-4-3-2-1-0)
// xxx_SYMB_xxx = Display symbol, e.g. "AM" for ante meridiem
// xxx_UNIT_xxx = Display unit, e.g. "km/h" for kilometers per hour
// xxx_ICON_xxx = Display icon, e.g. heart to indicate reception of heart rate data
// xxx_L1_xxx = Item is part of Line1 information
// xxx_L2_xxx = Item is part of Line2 information
// Symbols for Line1
#define LCD_SYMB_AM 0
#define LCD_SYMB_PM 1
#define LCD_SYMB_ARROW_UP 2
#define LCD_SYMB_ARROW_DOWN 3
#define LCD_SYMB_PERCENT 4
// Symbols for Line2
#define LCD_SYMB_TOTAL 5
#define LCD_SYMB_AVERAGE 6
#define LCD_SYMB_MAX 7
#define LCD_SYMB_BATTERY 8
// Units for Line1
#define LCD_UNIT_L1_FT 9
#define LCD_UNIT_L1_K 10
#define LCD_UNIT_L1_M 11
#define LCD_UNIT_L1_I 12
#define LCD_UNIT_L1_PER_S 13
#define LCD_UNIT_L1_PER_H 14
#define LCD_UNIT_L1_DEGREE 15
// Units for Line2
#define LCD_UNIT_L2_KCAL 16
#define LCD_UNIT_L2_KM 17
#define LCD_UNIT_L2_MI 18
// Icons
#define LCD_ICON_HEART 19
#define LCD_ICON_STOPWATCH 20
#define LCD_ICON_RECORD 21
#define LCD_ICON_ALARM 22
#define LCD_ICON_BEEPER1 23
#define LCD_ICON_BEEPER2 24
#define LCD_ICON_BEEPER3 25
// Line1 7-segments
#define LCD_SEG_L1_3 26
#define LCD_SEG_L1_2 27
#define LCD_SEG_L1_1 28
#define LCD_SEG_L1_0 29
#define LCD_SEG_L1_COL 30
#define LCD_SEG_L1_DP1 31
#define LCD_SEG_L1_DP0 32
// Line2 7-segments
#define LCD_SEG_L2_5 33
#define LCD_SEG_L2_4 34
#define LCD_SEG_L2_3 35
#define LCD_SEG_L2_2 36
#define LCD_SEG_L2_1 37
#define LCD_SEG_L2_0 38
#define LCD_SEG_L2_COL1 39
#define LCD_SEG_L2_COL0 40
#define LCD_SEG_L2_DP 41
// Line1 7-segment arrays
#define LCD_SEG_L1_3_0 70
#define LCD_SEG_L1_2_0 71
#define LCD_SEG_L1_1_0 72
#define LCD_SEG_L1_3_1 73
#define LCD_SEG_L1_3_2 74
// Line2 7-segment arrays
#define LCD_SEG_L2_5_0 90
#define LCD_SEG_L2_4_0 91
#define LCD_SEG_L2_3_0 92
#define LCD_SEG_L2_2_0 93
#define LCD_SEG_L2_1_0 94
#define LCD_SEG_L2_5_2 95
#define LCD_SEG_L2_3_2 96
#define LCD_SEG_L2_5_4 97
#define LCD_SEG_L2_4_2 98
// LCD controller memory map
#define LCD_MEM_1 ((uint8_t*)0x0A20)
#define LCD_MEM_2 ((uint8_t*)0x0A21)
#define LCD_MEM_3 ((uint8_t*)0x0A22)
#define LCD_MEM_4 ((uint8_t*)0x0A23)
#define LCD_MEM_5 ((uint8_t*)0x0A24)
#define LCD_MEM_6 ((uint8_t*)0x0A25)
#define LCD_MEM_7 ((uint8_t*)0x0A26)
#define LCD_MEM_8 ((uint8_t*)0x0A27)
#define LCD_MEM_9 ((uint8_t*)0x0A28)
#define LCD_MEM_10 ((uint8_t*)0x0A29)
#define LCD_MEM_11 ((uint8_t*)0x0A2A)
#define LCD_MEM_12 ((uint8_t*)0x0A2B)
// Memory assignment
#define LCD_SEG_L1_0_MEM (LCD_MEM_6)
#define LCD_SEG_L1_1_MEM (LCD_MEM_4)
#define LCD_SEG_L1_2_MEM (LCD_MEM_3)
#define LCD_SEG_L1_3_MEM (LCD_MEM_2)
#define LCD_SEG_L1_COL_MEM (LCD_MEM_1)
#define LCD_SEG_L1_DP1_MEM (LCD_MEM_1)
#define LCD_SEG_L1_DP0_MEM (LCD_MEM_5)
#define LCD_SEG_L2_0_MEM (LCD_MEM_8)
#define LCD_SEG_L2_1_MEM (LCD_MEM_9)
#define LCD_SEG_L2_2_MEM (LCD_MEM_10)
#define LCD_SEG_L2_3_MEM (LCD_MEM_11)
#define LCD_SEG_L2_4_MEM (LCD_MEM_12)
#define LCD_SEG_L2_5_MEM (LCD_MEM_12)
#define LCD_SEG_L2_COL1_MEM (LCD_MEM_1)
#define LCD_SEG_L2_COL0_MEM (LCD_MEM_5)
#define LCD_SEG_L2_DP_MEM (LCD_MEM_9)
#define LCD_SYMB_AM_MEM (LCD_MEM_1)
#define LCD_SYMB_PM_MEM (LCD_MEM_1)
#define LCD_SYMB_ARROW_UP_MEM (LCD_MEM_1)
#define LCD_SYMB_ARROW_DOWN_MEM (LCD_MEM_1)
#define LCD_SYMB_PERCENT_MEM (LCD_MEM_5)
#define LCD_SYMB_TOTAL_MEM (LCD_MEM_11)
#define LCD_SYMB_AVERAGE_MEM (LCD_MEM_10)
#define LCD_SYMB_MAX_MEM (LCD_MEM_8)
#define LCD_SYMB_BATTERY_MEM (LCD_MEM_7)
#define LCD_UNIT_L1_FT_MEM (LCD_MEM_5)
#define LCD_UNIT_L1_K_MEM (LCD_MEM_5)
#define LCD_UNIT_L1_M_MEM (LCD_MEM_7)
#define LCD_UNIT_L1_I_MEM (LCD_MEM_7)
#define LCD_UNIT_L1_PER_S_MEM (LCD_MEM_5)
#define LCD_UNIT_L1_PER_H_MEM (LCD_MEM_7)
#define LCD_UNIT_L1_DEGREE_MEM (LCD_MEM_5)
#define LCD_UNIT_L2_KCAL_MEM (LCD_MEM_7)
#define LCD_UNIT_L2_KM_MEM (LCD_MEM_7)
#define LCD_UNIT_L2_MI_MEM (LCD_MEM_7)
#define LCD_ICON_HEART_MEM (LCD_MEM_2)
#define LCD_ICON_STOPWATCH_MEM (LCD_MEM_3)
#define LCD_ICON_RECORD_MEM (LCD_MEM_1)
#define LCD_ICON_ALARM_MEM (LCD_MEM_4)
#define LCD_ICON_BEEPER1_MEM (LCD_MEM_5)
#define LCD_ICON_BEEPER2_MEM (LCD_MEM_6)
#define LCD_ICON_BEEPER3_MEM (LCD_MEM_7)
// Bit masks for write access
#define LCD_SEG_L1_0_MASK (BIT2+BIT1+BIT0+BIT7+BIT6+BIT5+BIT4)
#define LCD_SEG_L1_1_MASK (BIT2+BIT1+BIT0+BIT7+BIT6+BIT5+BIT4)
#define LCD_SEG_L1_2_MASK (BIT2+BIT1+BIT0+BIT7+BIT6+BIT5+BIT4)
#define LCD_SEG_L1_3_MASK (BIT2+BIT1+BIT0+BIT7+BIT6+BIT5+BIT4)
#define LCD_SEG_L1_COL_MASK (BIT5)
#define LCD_SEG_L1_DP1_MASK (BIT6)
#define LCD_SEG_L1_DP0_MASK (BIT2)
#define LCD_SEG_L2_0_MASK (BIT3+BIT2+BIT1+BIT0+BIT6+BIT5+BIT4)
#define LCD_SEG_L2_1_MASK (BIT3+BIT2+BIT1+BIT0+BIT6+BIT5+BIT4)
#define LCD_SEG_L2_2_MASK (BIT3+BIT2+BIT1+BIT0+BIT6+BIT5+BIT4)
#define LCD_SEG_L2_3_MASK (BIT3+BIT2+BIT1+BIT0+BIT6+BIT5+BIT4)
#define LCD_SEG_L2_4_MASK (BIT3+BIT2+BIT1+BIT0+BIT6+BIT5+BIT4)
#define LCD_SEG_L2_5_MASK (BIT7)
#define LCD_SEG_L2_COL1_MASK (BIT4)
#define LCD_SEG_L2_COL0_MASK (BIT0)
#define LCD_SEG_L2_DP_MASK (BIT7)
#define LCD_SYMB_AM_MASK (BIT1+BIT0)
#define LCD_SYMB_PM_MASK (BIT0)
#define LCD_SYMB_ARROW_UP_MASK (BIT2)
#define LCD_SYMB_ARROW_DOWN_MASK (BIT3)
#define LCD_SYMB_PERCENT_MASK (BIT4)
#define LCD_SYMB_TOTAL_MASK (BIT7)
#define LCD_SYMB_AVERAGE_MASK (BIT7)
#define LCD_SYMB_MAX_MASK (BIT7)
#define LCD_SYMB_BATTERY_MASK (BIT7)
#define LCD_UNIT_L1_FT_MASK (BIT5)
#define LCD_UNIT_L1_K_MASK (BIT6)
#define LCD_UNIT_L1_M_MASK (BIT1)
#define LCD_UNIT_L1_I_MASK (BIT0)
#define LCD_UNIT_L1_PER_S_MASK (BIT7)
#define LCD_UNIT_L1_PER_H_MASK (BIT2)
#define LCD_UNIT_L1_DEGREE_MASK (BIT1)
#define LCD_UNIT_L2_KCAL_MASK (BIT4)
#define LCD_UNIT_L2_KM_MASK (BIT5)
#define LCD_UNIT_L2_MI_MASK (BIT6)
#define LCD_ICON_HEART_MASK (BIT3)
#define LCD_ICON_STOPWATCH_MASK (BIT3)
#define LCD_ICON_RECORD_MASK (BIT7)
#define LCD_ICON_ALARM_MASK (BIT3)
#define LCD_ICON_BEEPER1_MASK (BIT3)
#define LCD_ICON_BEEPER2_MASK (BIT3)
#define LCD_ICON_BEEPER3_MASK (BIT3)
// *************************************************************************************************
// API section
// Physical LCD memory write
void write_lcd_mem(uint8_t * lcdmem, uint8_t bits, uint8_t bitmask, uint8_t state);
// Display init / clear
void lcd_init(void);
void clear_display(void);
void clear_display_all(void);
void clear_line(uint8_t line);
// Blinking function
void start_blink(void);
void stop_blink(void);
void clear_blink_mem(void);
void set_blink_rate(uint8_t bits);
// Character / symbol draw functions
void display_char(uint8_t segment, uint8_t chr, uint8_t mode);
void display_chars(uint8_t segments, uint8_t * str, uint8_t mode);
void display_symbol(uint8_t symbol, uint8_t mode);
// Time display function
void DisplayTime(uint8_t updateMode);
void display_am_pm_symbol(uint8_t timeAM);
// Set_value display functions
void display_value1(uint8_t segments, uint32_t value, uint8_t digits, uint8_t blanks, uint8_t disp_mode);
void display_hours_12_or_24(uint8_t segments, uint32_t value, uint8_t digits, uint8_t blanks, uint8_t disp_mode);
// Integer to string conversion
uint8_t * itoa(uint32_t n, uint8_t digits, uint8_t blanks);
// Segment index helper function
uint8_t switch_seg(uint8_t line, uint8_t index1, uint8_t index2);
void display_all_off(void);
#endif // __DISPLAY_

View File

@ -0,0 +1,226 @@
// *************************************************************************************************
//
// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
//
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// *************************************************************************************************
// Basic display functions.
// *************************************************************************************************
// *************************************************************************************************
// Include section
#include "cc430x613x.h"
// driver
#include "display.h"
// *************************************************************************************************
// Prototypes section
// *************************************************************************************************
// Defines section
// *************************************************************************************************
// Global Variable section
// Table with memory bit assignment for digits "0" to "9" and characters "A" to "Z"
// A
// F B
// G
// E C
// D
const uint8_t lcd_font[] =
{
SEG_A+SEG_B+SEG_C+SEG_D+SEG_E+SEG_F, // Displays "0"
SEG_B+SEG_C, // Displays "1"
SEG_A+SEG_B+ SEG_D+SEG_E+ SEG_G, // Displays "2"
SEG_A+SEG_B+SEG_C+SEG_D+ SEG_G, // Displays "3"
SEG_B+SEG_C+ SEG_F+SEG_G, // Displays "4"
SEG_A+ SEG_C+SEG_D+ SEG_F+SEG_G, // Displays "5"
SEG_A+ SEG_C+SEG_D+SEG_E+SEG_F+SEG_G, // Displays "6"
SEG_A+SEG_B+SEG_C, // Displays "7"
SEG_A+SEG_B+SEG_C+SEG_D+SEG_E+SEG_F+SEG_G, // Displays "8"
SEG_A+SEG_B+SEG_C+SEG_D+ SEG_F+SEG_G, // Displays "9"
0 , // Displays " " (:)
0 , // Displays " " (;)
SEG_A+ SEG_F+SEG_G, // Displays "<" as high c
SEG_D+ SEG_G, // Displays "="
0 , // Displays " " (>)
SEG_A+SEG_B+ SEG_E+ SEG_G, // Displays "?"
0 , // Displays " " (@)
SEG_A+SEG_B+SEG_C+ SEG_E+SEG_F+SEG_G, // Displays "A"
SEG_C+SEG_D+SEG_E+SEG_F+SEG_G, // Displays "b"
SEG_D+SEG_E+ SEG_G, // Displays "c"
SEG_B+SEG_C+SEG_D+SEG_E+ SEG_G, // Displays "d"
SEG_A+ +SEG_D+SEG_E+SEG_F+SEG_G, // Displays "E"
SEG_A+ SEG_E+SEG_F+SEG_G, // Displays "f"
SEG_A+SEG_B+SEG_C+SEG_D+ SEG_F+SEG_G, // Displays "g" same as 9
SEG_C+ SEG_E+SEG_F+SEG_G, // Displays "h"
SEG_E , // Displays "i"
SEG_A+SEG_B+SEG_C+SEG_D , // Displays "J"
SEG_D+ SEG_F+SEG_G, // Displays "k"
SEG_D+SEG_E+SEG_F , // Displays "L"
SEG_A+SEG_B+SEG_C+ SEG_E+SEG_F , // Displays "M"
SEG_C+ SEG_E+ SEG_G, // Displays "n"
SEG_C+SEG_D+SEG_E+ SEG_G, // Displays "o"
SEG_A+SEG_B+ SEG_E+SEG_F+SEG_G, // Displays "P"
SEG_A+SEG_B+SEG_C+ SEG_F+SEG_G, // Displays "q"
SEG_E+ SEG_G, // Displays "r"
SEG_A+ SEG_C+SEG_D+ SEG_F+SEG_G, // Displays "S" same as 5
SEG_D+SEG_E+SEG_F+SEG_G, // Displays "t"
SEG_C+SEG_D+SEG_E , // Displays "u"
SEG_C+SEG_D+SEG_E , // Displays "v" same as u
SEG_B+SEG_C+SEG_D+SEG_E+SEG_F+SEG_G, // Displays "W"
SEG_B+SEG_C+ +SEG_E+SEG_F+SEG_G, // Displays "X" as H
SEG_B+SEG_C+SEG_D+ SEG_F+SEG_G, // Displays "Y"
SEG_A+SEG_B+ SEG_D+SEG_E+ SEG_G, // Displays "Z" same as 2
};
// Table with memory address for each display element
const uint8_t * segments_lcdmem[] =
{
LCD_SYMB_AM_MEM,
LCD_SYMB_PM_MEM,
LCD_SYMB_ARROW_UP_MEM,
LCD_SYMB_ARROW_DOWN_MEM,
LCD_SYMB_PERCENT_MEM,
LCD_SYMB_TOTAL_MEM,
LCD_SYMB_AVERAGE_MEM,
LCD_SYMB_MAX_MEM,
LCD_SYMB_BATTERY_MEM,
LCD_UNIT_L1_FT_MEM,
LCD_UNIT_L1_K_MEM,
LCD_UNIT_L1_M_MEM,
LCD_UNIT_L1_I_MEM,
LCD_UNIT_L1_PER_S_MEM,
LCD_UNIT_L1_PER_H_MEM,
LCD_UNIT_L1_DEGREE_MEM,
LCD_UNIT_L2_KCAL_MEM,
LCD_UNIT_L2_KM_MEM,
LCD_UNIT_L2_MI_MEM,
LCD_ICON_HEART_MEM,
LCD_ICON_STOPWATCH_MEM,
LCD_ICON_RECORD_MEM,
LCD_ICON_ALARM_MEM,
LCD_ICON_BEEPER1_MEM,
LCD_ICON_BEEPER2_MEM,
LCD_ICON_BEEPER3_MEM,
LCD_SEG_L1_3_MEM,
LCD_SEG_L1_2_MEM,
LCD_SEG_L1_1_MEM,
LCD_SEG_L1_0_MEM,
LCD_SEG_L1_COL_MEM,
LCD_SEG_L1_DP1_MEM,
LCD_SEG_L1_DP0_MEM,
LCD_SEG_L2_5_MEM,
LCD_SEG_L2_4_MEM,
LCD_SEG_L2_3_MEM,
LCD_SEG_L2_2_MEM,
LCD_SEG_L2_1_MEM,
LCD_SEG_L2_0_MEM,
LCD_SEG_L2_COL1_MEM,
LCD_SEG_L2_COL0_MEM,
LCD_SEG_L2_DP_MEM,
};
// Table with bit mask for each display element
const uint8_t segments_bitmask[] =
{
LCD_SYMB_AM_MASK,
LCD_SYMB_PM_MASK,
LCD_SYMB_ARROW_UP_MASK,
LCD_SYMB_ARROW_DOWN_MASK,
LCD_SYMB_PERCENT_MASK,
LCD_SYMB_TOTAL_MASK,
LCD_SYMB_AVERAGE_MASK,
LCD_SYMB_MAX_MASK,
LCD_SYMB_BATTERY_MASK,
LCD_UNIT_L1_FT_MASK,
LCD_UNIT_L1_K_MASK,
LCD_UNIT_L1_M_MASK,
LCD_UNIT_L1_I_MASK,
LCD_UNIT_L1_PER_S_MASK,
LCD_UNIT_L1_PER_H_MASK,
LCD_UNIT_L1_DEGREE_MASK,
LCD_UNIT_L2_KCAL_MASK,
LCD_UNIT_L2_KM_MASK,
LCD_UNIT_L2_MI_MASK,
LCD_ICON_HEART_MASK,
LCD_ICON_STOPWATCH_MASK,
LCD_ICON_RECORD_MASK,
LCD_ICON_ALARM_MASK,
LCD_ICON_BEEPER1_MASK,
LCD_ICON_BEEPER2_MASK,
LCD_ICON_BEEPER3_MASK,
LCD_SEG_L1_3_MASK,
LCD_SEG_L1_2_MASK,
LCD_SEG_L1_1_MASK,
LCD_SEG_L1_0_MASK,
LCD_SEG_L1_COL_MASK,
LCD_SEG_L1_DP1_MASK,
LCD_SEG_L1_DP0_MASK,
LCD_SEG_L2_5_MASK,
LCD_SEG_L2_4_MASK,
LCD_SEG_L2_3_MASK,
LCD_SEG_L2_2_MASK,
LCD_SEG_L2_1_MASK,
LCD_SEG_L2_0_MASK,
LCD_SEG_L2_COL1_MASK,
LCD_SEG_L2_COL0_MASK,
LCD_SEG_L2_DP_MASK,
};
// Quick integer to array conversion table for most common integer values
const uint8_t itoa_conversion_table[][3] =
{
"000", "001", "002", "003", "004", "005", "006", "007", "008", "009", "010", "011", "012", "013", "014", "015",
"016", "017", "018", "019", "020", "021", "022", "023", "024", "025", "026", "027", "028", "029", "030", "031",
"032", "033", "034", "035", "036", "037", "038", "039", "040", "041", "042", "043", "044", "045", "046", "047",
"048", "049", "050", "051", "052", "053", "054", "055", "056", "057", "058", "059", "060", "061", "062", "063",
"064", "065", "066", "067", "068", "069", "070", "071", "072", "073", "074", "075", "076", "077", "078", "079",
"080", "081", "082", "083", "084", "085", "086", "087", "088", "089", "090", "091", "092", "093", "094", "095",
"096", "097", "098", "099", "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", "110", "111",
"112", "113", "114", "115", "116", "117", "118", "119", "120", "121", "122", "123", "124", "125", "126", "127",
"128", "129", "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "140", "141", "142", "143",
"144", "145", "146", "147", "148", "149", "150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
"160", "161", "162", "163", "164", "165", "166", "167", "168", "169", "170", "171", "172", "173", "174", "175",
"176", "177", "178", "179", "180",
};

View File

@ -0,0 +1,10 @@
#ifndef _MSB_BOARD_H
#define _MSB_BOARD_H
#include <cc430x613x.h>
#define MSP430_INITIAL_CPU_SPEED 7372800uL
#define MSP430_HAS_DCOR 1
#define MSP430_HAS_EXTERNAL_CRYSTAL 1
#endif // _MSB_BOARD_H

35
board/msb-430h/Jamfile Normal file
View File

@ -0,0 +1,35 @@
# ******************************************************************************
# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
#
# These sources were developed at the Freie Universitaet Berlin, Computer
# Systems and Telematics group (http://cst.mi.fu-berlin.de).
# ------------------------------------------------------------------------------
# This file is part of FeuerWare.
#
# 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.
#
# FeuerWare 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/ .
# ------------------------------------------------------------------------------
# For further information and questions please use the web site
# http://scatterweb.mi.fu-berlin.de
# and the mailinglist (subscription via web site)
# scatterweb@lists.spline.inf.fu-berlin.de
# ******************************************************************************
# $Id$
SubDir TOP board msb-430h ;
Module board : board_init.c debug_uart.c ;
UseModule board ;
Module board_cc1100 : driver_cc1100.c ;
SubInclude TOP cpu $(CPU) ;

View File

@ -0,0 +1,37 @@
# ******************************************************************************
# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
#
# These sources were developed at the Freie Universitaet Berlin, Computer
# Systems and Telematics group (http://cst.mi.fu-berlin.de).
# ------------------------------------------------------------------------------
# This file is part of FeuerWare.
#
# 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.
#
# FeuerWare 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/ .
# ------------------------------------------------------------------------------
# For further information and questions please use the web site
# http://scatterweb.mi.fu-berlin.de
# and the mailinglist (subscription via web site)
# scatterweb@lists.spline.inf.fu-berlin.de
# ******************************************************************************
# $Id$
BOARD = msb-430h ;
CPU = msp430 ;
MCU = msp430x1612 ;
FLASH_PORT ?= /dev/ttyUSB0 ;
FLASHER ?= mspdebug ;
FLASHFLAGS ?= -d $(FLASH_PORT) -j uif ;
RESET ?= $(FLASHER) $(FLASHFLAGS) reset ;

207
board/msb-430h/board_init.c Normal file
View File

@ -0,0 +1,207 @@
#include "cpu.h"
#include "board.h"
#include "kernel_intern.h"
#include "msp430.h"
#include "debug.h"
volatile static uint32_t __msp430_cpu_speed = MSP430_INITIAL_CPU_SPEED;
/*---------------------------------------------------------------------------*/
static uint8_t calc_umctl(uint16_t br) {
// from TI slaa049
register uint8_t CMOD = 256 * br - 256 * (br + 1) / 2;
register uint8_t c = 0;
register int i = 0;
register uint8_t a = CMOD;
a <<= 1;
do {
if( a & 0x80 ) { // Overflow to integer?
a = a - 128 + CMOD; // Yes, subtract 1.000000
c |= 0x80;
} else {
a += CMOD; // No, add fraction
}
if( i == 7 )
return c;
i++;
c >>= 1;
} while(1);
}
static void msb_ports_init(void)
{
// Port 1: Free port, for energy saving all outputs are set to zero.
P1SEL = 0x00; // Port1 Zweitfunktion
P1OUT = 0x00; // Port1 Ausgangsregister: 00000000 = 0x00
P1DIR = 0xFF; // Port1 Direction: 11111111 = 0xFF
P2SEL = 0x20; // Port2 Zweitfunktion
P2OUT = 0x00; // Port2 Ausgangsregister: 00000000 = 0x00
P2DIR = 0x1C; // Port2 Direction: 00011010 = 0x1C
// 0 - P2.0 [IN ] -
// 0 - P2.1 [OUT] -
// 1 - P2.2 [IN ] -
// 1 - P2.3 [OUT] -
// 1 - P2.4 [OUT] -
// 0 - P2.5 [IN ] -
// 0 - P2.6 [IN ] - SD-KARTE Protect
// 0 - P2.7 [IN ] - SD-KARTE Detect
P3SEL = 0xC0; // Port3 Zweitfunktion
P3OUT = 0x09; // Port3 Ausgangsregister: 00001001 = 0x09
P3DIR = 0x2B; // Port3 Direction
// 1 - P3.0
// 1 - P3.1
// 0 - P3.2
// 1 - P3.3
// 0 - P3.4 [IN ] - SHT 11 DATA (OUT/IN)
// 1 - P3.5 [OUT] - SHT 11 CLK
// 0 - P3.6 [2-Funktion] - RS232_RxD
// 0 - P3.7 [2-Funktion] - RS232_TxD
// Port 4: Free port, for energy saving all outputs are set to zero.
P4SEL = 0x00; // Port4 Zweitfunktion
P4OUT = 0x00; // Port4 Ausgangsregister: 00000000 = 0x00
P4DIR = 0xFF; // Port4 Direction: 11111111 = 0xFF
// 1 - P4.0 [OUT] - unused
// 1 - P4.1 [OUT] - unused
// 1 - P4.2 [OUT] - unused
// 1 - P4.3 [OUT] - unused
// 1 - P4.4 [OUT] - unused
// 1 - P4.5 [OUT] - unused
// 1 - P4.6 [OUT] - unused
// 1 - P4.7 [OUT] - unused
P5SEL = 0x00; // Port5 Zweitfunktion: 00000000 = 0x00
P5OUT = 0x80; // Port5 Ausgangsregister: 00001001 = 0x09
P5DIR = 0xFF; // Port5 Direction: 11111011 = 0xFB
// 1 - P5.0 [OUT] - SD-KARTE /CS
// 1 - P5.1 [OUT] - SD-KARTE DI
// 0 - P5.2 [IN ] - SD-KARTE DO
// 1 - P5.3 [OUT] - SD-KARTE DCLK
// 1 - P5.4 [OUT] - MMA GS1
// 1 - P5.5 [OUT] - MMA GS2
// 1 - P5.6 [OUT] - MMA /SLEEP
// 1 - P5.7 [OUT] - LED_ROT 0-an, 1-aus
P6SEL = 0x00; // Port6 Zweitfunktion = 0x07
P6OUT = 0x00; // Port6 Ausgangsregister: 00000000 = 0x00
P6DIR = 0xFF; // Port6 Direction: 11111000 = 0xF8
// 0 - P6.0 [AD-IN] - MMA X-Achse
// 0 - P6.1 [AD-IN] - MMA Y-Achse
// 0 - P6.2 [AD-IN] - MMA Z-Achse
// 1 - P6.3 [OUT] - unused
// 1 - P6.4 [OUT] - unused
// 1 - P6.5 [OUT] - unused
// 1 - P6.6 [OUT] - unused
// 1 - P6.7 [OUT] - unused
}
void msp430_set_cpu_speed(uint32_t speed)
{
dint();
__msp430_cpu_speed = speed;
msp430_init_dco();
uint16_t br;
UCTL1 = SWRST | CHAR; // 8-bit character
UTCTL1 |= SSEL1 | URXSE; // UCLK = MCLK
// activate
U1ME |= UTXE1 | URXE1; // Enable USART1 TXD/RXD
br = (uint16_t)(__msp430_cpu_speed / 115200uL);
UBR01 = br; // set baudrate
UBR11 = br>>8;
UMCTL1 = calc_umctl(br); // set modulation
UCTL1 &= ~SWRST;
//clock_init();
eint();
}
/*---------------------------------------------------------------------------*/
void
msp430_init_dco()
{
#if MSP430_HAS_EXTERNAL_CRYSTAL
/*------------------ use external oszillator -----------------------*/
uint16_t i;
// Stop watchdog
WDTCTL = WDTPW + WDTHOLD;
//Init crystal for mclk
//XT2 = HF XTAL
BCSCTL1 = RSEL2;
// Wait for xtal to stabilize
do {
IFG1 &= ~OFIFG; // Clear oscillator fault flag
for (i = 0xFF; i > 0; i--); // Time for flag to set
}
while ((IFG1 & OFIFG) != 0); // Oscillator fault flag still set?
BCSCTL2 = SELM_2 + SELS; // MCLK und SMCLK = XT2 (safe)
#else
/* Thdeltais code taken from the FU Berlin sources and reformatted. */
int delta = __msp430_cpu_speed >> 12;
//#define DELTA 600
unsigned int compare, oldcapture = 0;
unsigned int i;
BCSCTL1 = 0xa4; /* ACLK is devided by 4. RSEL=6 no division for MCLK
and SSMCLK. XT2 is off. */
// Init FLL to desired frequency using the 32762Hz crystal
#if MSP430_HAS_DCOR
BCSCTL2 = 0x01;
#else
BCSCTL2 = 0x00;
#endif
WDTCTL = WDTPW + WDTHOLD; /* Stop WDT */
BCSCTL1 |= DIVA1 + DIVA0; /* ACLK = LFXT1CLK/8 */
for(i = 0xffff; i > 0; i--); /* Delay for XTAL to settle */
CCTL2 = CCIS0 + CM0 + CAP; // Define CCR2, CAP, ACLK
TACTL = TASSEL1 + TACLR + MC1; // SMCLK, continous mode
while(1) {
while((CCTL2 & CCIFG) != CCIFG); /* Wait until capture occured! */
CCTL2 &= ~CCIFG; /* Capture occured, clear flag */
compare = CCR2; /* Get current captured SMCLK */
compare = compare - oldcapture; /* SMCLK difference */
oldcapture = CCR2; /* Save current captured SMCLK */
if(delta == compare) {
break; /* if equal, leave "while(1)" */
} else if(delta < compare) { /* DCO is too fast, slow it down */
DCOCTL--;
if(DCOCTL == 0xFF) { /* Did DCO role under? */
BCSCTL1--;
}
} else { /* -> Select next lower RSEL */
DCOCTL++;
if(DCOCTL == 0x00) { /* Did DCO role over? */
BCSCTL1++;
}
/* -> Select next higher RSEL */
}
}
CCTL2 = 0; /* Stop CCR2 function */
TACTL = 0; /* Stop Timer_A */
BCSCTL1 &= ~(DIVA1 + DIVA0); /* remove /8 divisor from ACLK again */
#endif
}
void board_init() {
msp430_cpu_init();
msb_ports_init();
RED_ON;
msp430_set_cpu_speed(7372800uL);
}

View File

@ -0,0 +1,21 @@
#include "board.h"
#define UART1_TX TXBUF1
#define UART1_WAIT_TXDONE() while( (UTCTL1 & TXEPT) == 0 ) { _NOP(); }
#include <stdio.h>
int putchar(int c)
{
UART1_TX = c;
UART1_WAIT_TXDONE();
if (c == 10) {
UART1_TX = 13;
UART1_WAIT_TXDONE();
}
return c;
}

View File

@ -0,0 +1,343 @@
/* Copyright (C) 2005, 2006, 2007, 2008 by Thomas Hillebrandt and Heiko Will
This file is part of the Micro-mesh SensorWeb Firmware.
Micro-Mesh 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, or (at your option)
any later version.
Micro-Mesh 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 Micro-Mesh; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <stdio.h>
#include <board.h>
#include <cpu.h>
#include <irq.h>
#include <cc1100.h>
#include <arch_cc1100.h>
#define CC1100_GDO0 (P2IN & 0x02) // read serial I/O (GDO0)
#define CC1100_GDO1 (P3IN & 0x04) // read serial I/O (GDO1)
#define CC1100_GDO2 (P2IN & 0x01) // read serial I/O (GDO2)
#define CC1100_CS_LOW (P3OUT &= ~0x01)
#define CC1100_CS_HIGH (P3OUT |= 0x01)
#define CC1100_GDO1_LOW_COUNT (2700) // loop count (timeout ~ 500 us) to wait
#define CC1100_GDO1_LOW_RETRY (100) // max. retries for GDO1 to go low
volatile int abort_count;
volatile int retry_count = 0;
void cc1100_gdo0_enable(void)
{
P2IFG &= ~0x02; /* Clear IFG for GDO0 */
P2IE |= 0x02; /* Enable interrupt for GDO0 */
}
void cc1100_gdo0_disable(void)
{
P2IE &= ~0x02; /* Disable interrupt for GDO0 */
P2IFG &= ~0x02; /* Clear IFG for GDO0 */
}
void cc1100_gdo2_enable(void)
{
P2IFG &= ~0x01; /* Clear IFG for GDO2 */
P2IE |= 0x01; /* Enable interrupt for GDO2 */
}
void cc1100_gdo2_disable(void)
{
P2IE &= ~0x01; /* Disable interrupt for GDO2 */
P2IFG &= ~0x01; /* Clear IFG for GDO2 */
}
void cc1100_before_send(void)
{
// Disable GDO2 interrupt before sending packet
cc1100_gdo2_disable();
}
void cc1100_after_send(void)
{
// Enable GDO2 interrupt after sending packet
cc1100_gdo2_enable();
}
int cc1100_get_gdo0(void) {
return CC1100_GDO0;
}
int cc1100_get_gdo1(void) {
return CC1100_GDO1;
}
int cc1100_get_gdo2(void) {
return CC1100_GDO2;
}
void cc1100_spi_cs(void)
{
CC1100_CS_LOW;
}
uint8_t cc1100_txrx(uint8_t data)
{
/* Ensure TX Buf is empty */
long c = 0;
IFG1 &= ~UTXIFG0;
IFG1 &= ~URXIFG0;
TXBUF0 = data;
while(!(IFG1 & UTXIFG0))
{
if (c++ == 1000000)
puts("cc1100_txrx alarm()");
}
/* Wait for Byte received */
c = 0;
while(!(IFG1 & URXIFG0))
{
if (c++ == 1000000)
puts("cc1100_txrx alarm()");
}
return RXBUF0;
}
void cc1100_spi_select(void)
{
// Switch to GDO mode
P3SEL &= ~0x04;
P3DIR &= ~0x04;
cs_low:
// CS to low
abort_count = 0;
CC1100_CS_LOW;
// Wait for SO to go low (voltage regulator
// has stabilized and the crystal is running)
loop:
// asm volatile ("nop");
if (CC1100_GDO1) {
abort_count++;
if (abort_count > CC1100_GDO1_LOW_COUNT) {
retry_count++;
if (retry_count > CC1100_GDO1_LOW_RETRY) {
puts("[CC1100 SPI] fatal error\n");
goto final;
}
CC1100_CS_HIGH;
goto cs_low; // try again
}
goto loop;
}
final:
/* Switch to SPI mode */
P3SEL |= 0x04;
}
void cc1100_spi_unselect(void) {
CC1100_CS_HIGH;
}
void cc1100_init_interrupts(void)
{
unsigned int state = disableIRQ(); /* Disable all interrupts */
P2SEL = 0x00; /* must be <> 1 to use interrupts */
P2IES |= 0x01; /* Enables external interrupt on low edge (for GDO2) */
P2IE |= 0x01; /* Enable interrupt */
P2IFG &= ~0x01; /* Clears the interrupt flag */
P2IE &= ~0x02; /* Disable interrupt for GDO0 */
P2IFG &= ~0x02; /* Clear IFG for GDO0 */
restoreIRQ(state); /* Enable all interrupts */
}
void cc1100_spi_init(uint8_t clockrate)
{
// Switch off async UART
while(!(UTCTL0 & TXEPT)); // Wait for empty UxTXBUF register
IE1 &= ~(URXIE0 + UTXIE0); // Disable USART0 receive&transmit interrupt
ME1 &= ~(UTXE0 + URXE0);
P3SEL |= 0x0E; // Set pin as SPI
// Keep peripheral in reset state
UCTL0 = SWRST;
// 8-bit SPI Master 3-pin mode, with SMCLK as clock source
// CKPL works also, but not CKPH+CKPL or none of them!!
UCTL0 |= CHAR + SYNC + MM;
UTCTL0 = CKPH + SSEL1 + SSEL0 + STC;
// Ignore clockrate argument for now, just use clock source/2
// SMCLK = 7,3728 MHz
UBR00 = 0x02; // Ensure baud rate >= 2
UBR10 = 0x00;
UMCTL0 = 0x00; // No modulation
URCTL0 = 0x00; // Reset Receive Control Register
// Enable SPI mode
ME1 |= USPIE0;
// Release for operation
UCTL0 &= ~SWRST;
}
// #include <msp430x16x.h>
// #include <signal.h>
// #include "type.h"
// #include "cc1100_defines.h"
// #include "driver_cc1100.h"
// #include "driver_system.h"
// #include "spi0.h"
//
// static callback_t _paket_cb;
// static callback_t _cs_cb;
//
// //-------------------------------------------------------------------------------------------------------
// // Public CC1100 communication functions (SPI)
// //-------------------------------------------------------------------------------------------------------
//
// //-------------------------------------------------------------------------------------------------------
// // void spiInitTrx(void)
// //
// // DESCRIPTION:
// // This function puts the cc1100 into spi mode. You have to call this bevore every spi transaction.
// //
// //-------------------------------------------------------------------------------------------------------
//
//
// void drivercc1100_spiwriteburstreg(uint8_t addr, unsigned char *buffer, uint8_t count)
// {
// uint8_t i;
// long c;
// drivercc1100_spiinittrx();
// drivercc1100_trxspi(addr | CC1100_WRITE_BURST);
// for (i = 0; i < count; i++)
// {
// c = 0;
// IFG1 &= ~UTXIFG0;
// IFG1 &= ~URXIFG0;
// TXBUF0 = buffer[i];
// /* Wait for TX to finish */
// while(!(IFG1 & UTXIFG0))
// {
// if (c++ == 1000000)
// alarm();
// }
// }
// /* Wait for Byte received */
// c = 0;
// while(!(IFG1 & URXIFG0))
// {
// if (c++ == 1000000)
// alarm();
// }
// CC1100_CS_HIGH;
// }
//
// void drivercc1100_spireadburstreg(uint8_t addr, char *buffer, uint8_t count)
// {
// uint8_t i;
// drivercc1100_spiinittrx();
// drivercc1100_trxspi(addr | CC1100_READ_BURST);
// for (i = 0; i < count; i++)
// {
// long c = 0;
// IFG1 &= ~UTXIFG0;
// IFG1 &= ~URXIFG0;
// TXBUF0 = NOBYTE;
// while(!(IFG1 & UTXIFG0))
// {
// if (c++ == 1000000)
// alarm();
// }
// /* Wait for Byte received */
// c = 0;
// while(!(IFG1 & URXIFG0))
// {
// if (c++ == 1000000)
// alarm();
// }
// buffer[i] = RXBUF0;
// }
// CC1100_CS_HIGH;
// }
//
// void drivercc1100_load(callback_t cs_cb,callback_t paket_cb)
// {
// _paket_cb = paket_cb;
// _cs_cb = cs_cb;
// spi0_init(0);
// }
//
// void drivercc1100_aftersend(void)
// {
// CLEAR(P2IFG, 0x01);
// SET(P2IE, 0x01); /* Enable interrupts on port 2 pin 0 */
// CLEAR(P4OUT, 0x08); /* Turn off Sending Led*/
// }
//
// void drivercc1100_initinterrupts(void)
// {
// _DINT(); /* Disable all interrupts */
// P2SEL = 0x00; /* must be <> 1 to use interrupts */
// SET(P2IES, 0x01); /* Enables external interrupt on low edge (for GDO2) */
// SET(P2IE, 0x01); /* Enable interrupt */
// CLEAR(P2IFG, 0x01); /* Clears the interrupt flag */
// CLEAR(P2IE, 0x02); /* Disable interrupt for GDO0 */
// CLEAR(P2IFG, 0x02); /* Clear IFG for GDO0 */
// _EINT(); /* Enable all interrupts */
// }
//
// void drivercc1100_beforesend(void)
// {
// /* Turn on Led while sending paket for debug reasons */
// SET(P4OUT, 0x08);
// /* Disable interrupts on port 2 pin 0 */
// CLEAR(P2IE, 0x01);
// }
//
//
// /*
// * Private functions
// */
//
//
/*
* CC1100 receive interrupt
*/
interrupt (PORT2_VECTOR) __attribute__ ((naked)) cc1100_isr(void){
__enter_isr();
puts("cc1100_isr()");
// if (system_state.POWERDOWN) SPI_INIT; /* Initialize SPI after wakeup */
/* Check IFG */
if ((P2IFG & 0x01) != 0) {
P2IFG &= ~0x01;
cc1100_gdo2_irq();
}
else if ((P2IFG & 0x02) != 0) {
cc1100_gdo0_irq();
P2IE &= ~0x02; // Disable interrupt for GDO0
P2IFG &= ~0x02; // Clear IFG for GDO0
} else {
puts("cc1100_isr(): unexpected IFG!");
/* Should not occur - only Port 2 Pin 0 interrupts are enabled */
// CLEAR(P2IFG, 0xFF); /* Clear all flags */
}
// if (system_state.POWERDOWN != 0) END_LPM3;
__exit_isr();
}

View File

@ -0,0 +1,69 @@
/******************************************************************************
Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
These sources were developed at the Freie Universitaet Berlin, Computer Systems
and Telematics group (http://cst.mi.fu-berlin.de).
-------------------------------------------------------------------------------
This file is part of FeuerWare.
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.
FeuerWare 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/ .
--------------------------------------------------------------------------------
For further information and questions please use the web site
http://scatterweb.mi.fu-berlin.de
and the mailinglist (subscription via web site)
scatterweb@lists.spline.inf.fu-berlin.de
*******************************************************************************/
#ifndef _MSB_BOARD_H
#define _MSB_BOARD_H
/**
* @defgroup msb_430h ScatterWeb MSB-430H
* @ingroup msp430
*
<h2>Compontents</h2>
\li MSP430
\li CC1100
* @{
*/
/**
* @file
* @brief MSB-430H Board
*
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
* @version $Revision$
*
* @note $Id$
*/
//MSB430 core
#define MSP430_INITIAL_CPU_SPEED 7372800uL
#define MSP430_HAS_DCOR 1
#define MSP430_HAS_EXTERNAL_CRYSTAL 1
/* LEDs ports MSB430 */
#define LEDS_PxDIR P5DIR
#define LEDS_PxOUT P5OUT
#define LEDS_CONF_RED 0x80
#define LEDS_CONF_GREEN 0x00
#define LEDS_CONF_YELLOW 0x00
#define RED_ON LEDS_PxOUT &=~LEDS_CONF_RED
#define RED_OFF LEDS_PxOUT |= LEDS_CONF_RED
#include <msp430x16x.h>
/** @} */
#endif // _MSB_BOARD_H

35
board/msba2/Jamfile Normal file
View File

@ -0,0 +1,35 @@
# ******************************************************************************
# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
#
# These sources were developed at the Freie Universitaet Berlin, Computer
# Systems and Telematics group (http://cst.mi.fu-berlin.de).
# ------------------------------------------------------------------------------
# This file is part of FeuerWare.
#
# 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.
#
# FeuerWare 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/ .
# ------------------------------------------------------------------------------
# For further information and questions please use the web site
# http://scatterweb.mi.fu-berlin.de
# and the mailinglist (subscription via web site)
# scatterweb@lists.spline.inf.fu-berlin.de
# ******************************************************************************
# $Id$
SubDir TOP board msba2 ;
Module board : board_init.c ;
UseModule board ;
UseModule board_common ;
SubInclude TOP board $(BOARD) drivers ;
SubInclude TOP cpu $(CPU) ;

31
board/msba2/Jamfile.msba2 Normal file
View File

@ -0,0 +1,31 @@
# ******************************************************************************
# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
#
# These sources were developed at the Freie Universitaet Berlin, Computer
# Systems and Telematics group (http://cst.mi.fu-berlin.de).
# ------------------------------------------------------------------------------
# This file is part of FeuerWare.
#
# 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.
#
# FeuerWare 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/ .
# ------------------------------------------------------------------------------
# For further information and questions please use the web site
# http://scatterweb.mi.fu-berlin.de
# and the mailinglist (subscription via web site)
# scatterweb@lists.spline.inf.fu-berlin.de
# ******************************************************************************
# $Id$
#LinkLibraries $(BOARD).elf : sys-drivers.a net_mm.a sys-lib.a fat-lib.a
# cpu_drivers.a board_drivers.a cc110x.a hal.a hal_drivers.a lpc2387_hal.a ;
include [ FPath $(TOP) cpu arm_common Jamfile.arm_common ] ;

View File

@ -0,0 +1,33 @@
# ******************************************************************************
# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
#
# These sources were developed at the Freie Universitaet Berlin, Computer
# Systems and Telematics group (http://cst.mi.fu-berlin.de).
# ------------------------------------------------------------------------------
# This file is part of FeuerWare.
#
# 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.
#
# FeuerWare 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/ .
# ------------------------------------------------------------------------------
# For further information and questions please use the web site
# http://scatterweb.mi.fu-berlin.de
# and the mailinglist (subscription via web site)
# scatterweb@lists.spline.inf.fu-berlin.de
# ******************************************************************************
# $Id$
CPU = lpc2387 ;
HDRS += [ FPath $(TOP) board $(BOARD) drivers include ] ;
FLASHER = $(POSIXSHELL) $(TOP)/board/msba2/tools/flashutil.sh ;
FLASHFLAGS = --basedir $(TOP)/board/msba2/tools --id "MSB-A2" --ports "$(PORT)" ;

156
board/msba2/board_init.c Normal file
View File

@ -0,0 +1,156 @@
/******************************************************************************
Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved.
These sources were developed at the Freie Universitaet Berlin, Computer Systems
and Telematics group (http://cst.mi.fu-berlin.de).
-------------------------------------------------------------------------------
This file is part of FeuerWare.
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.
FeuerWare 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/ .
--------------------------------------------------------------------------------
For further information and questions please use the web site
http://scatterweb.mi.fu-berlin.de
and the mailinglist (subscription via web site)
scatterweb@lists.spline.inf.fu-berlin.de
*******************************************************************************/
/**
* @ingroup pttu
* @{
*/
/**
* @file
* @brief MSB-A2 board initialization
*
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
* @author Heiko Will
* @author Kaspar Schleiser
* @author Michael Baar <baar@inf.fu-berlin.de>
*
* @note $Id$
*/
#include <board.h>
#include <lpc23xx.h>
#include "VIC.h"
#include "cpu.h"
#define PCRTC BIT9
#define CL_CPU_DIV 4
/*---------------------------------------------------------------------------*/
/**
* @brief Enabling MAM and setting number of clocks used for Flash memory fetch
* @internal
*/
static void
init_mam(void)
{
MAMCR = 0x0000;
MAMTIM = 0x0003;
MAMCR = 0x0002;
}
/*---------------------------------------------------------------------------*/
static inline void
pllfeed(void)
{
PLLFEED = 0xAA;
PLLFEED = 0x55;
}
/*---------------------------------------------------------------------------*/
void init_clks1(void)
{
// Disconnect PLL
PLLCON &= ~0x0002;
pllfeed();
// Disable PLL
PLLCON &= ~0x0001;
pllfeed();
SCS |= 0x20; // Enable main OSC
while( !(SCS & 0x40) ); // Wait until main OSC is usable
/* select main OSC, 16MHz, as the PLL clock source */
CLKSRCSEL = 0x0001;
// Setting Multiplier and Divider values
PLLCFG = 0x0008; // M=9 N=1 Fcco = 288 MHz
pllfeed();
// Enabling the PLL */
PLLCON = 0x0001;
pllfeed();
/* Set clock divider to 4 (value+1) */
CCLKCFG = CL_CPU_DIV - 1; // Fcpu = 72 MHz
#if USE_USB
USBCLKCFG = USBCLKDivValue; /* usbclk = 288 MHz/6 = 48 MHz */
#endif
}
void init_clks2(void){
// Wait for the PLL to lock to set frequency
while(!(PLLSTAT & BIT26));
// Connect the PLL as the clock source
PLLCON = 0x0003;
pllfeed();
/* Check connect bit status */
while (!(PLLSTAT & BIT25));
}
void bl_init_clks(void)
{
PCONP = PCRTC; // switch off everything except RTC
init_clks1();
init_clks2();
init_mam();
}
void bl_init_ports(void)
{
SCS |= BIT0; // Set IO Ports to fast switching mode
/* UART0 */
PINSEL0 |= BIT4 + BIT6; // RxD0 and TxD0
PINSEL0 &= ~(BIT5 + BIT7);
/* LEDS */
FIO3DIR |= LED_RED_PIN;
FIO3DIR |= LED_GREEN_PIN;
LED_RED_OFF;
LED_GREEN_OFF;
}
void loop_delay(void) {
volatile uint16_t i, j;
for (i = 1; i < 30; i++) {
for (j = 1; j != 0; j++) {
asm volatile (" nop ");
}
}
}
void bl_blink(void) {
LED_RED_ON;
LED_GREEN_ON;
loop_delay();
LED_RED_OFF;
LED_GREEN_OFF;
}

View File

@ -0,0 +1,6 @@
SubDir TOP board msba2 drivers ;
Module board_cc1100 : msba2-cc1100.c ;
Module board_hal : msba2-hal.c ;
Module board_ltc4150 : msba2-ltc4150.c : gpioint ;
Module board_common : msba2-uart0.c ;

View File

@ -0,0 +1,68 @@
/******************************************************************************
Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved.
These sources were developed at the Freie Universitaet Berlin, Computer Systems
and Telematics group (http://cst.mi.fu-berlin.de).
-------------------------------------------------------------------------------
This file is part of FeuerWare.
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.
FeuerWare 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/ .
--------------------------------------------------------------------------------
For further information and questions please use the web site
http://scatterweb.mi.fu-berlin.de
and the mailinglist (subscription via web site)
scatterweb@lists.spline.inf.fu-berlin.de
*******************************************************************************/
#ifndef HALPLATFORM_H_
#define HALPLATFORM_H_
/**
* @ingroup msba2
* @{
*/
/**
* @file
* @brief
*
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
* @author baar
* @version $Revision$
*
* @note $Id$
*/
#include "vdevice.h"
#include "device-gpio.h"
#include "device-rs232.h"
#include "device-serial.h"
VDEVICE_NAME(vdevice_gpio, gpio_led_green);
VDEVICE_NAME(vdevice_gpio, gpio_led_red);
VDEVICE_NAME(vdevice_gpio, gpio_led_usb);
/**
* @var tty0
* @brief RS232 TTY0 device on UART0
*/
VDEVICE_NAME(vdevice_rs232, tty0);
/**
* @var console0
* @brief console device on tty0
*/
VDEVICE_NAME(vdevice_serial, console0);
/** @} */
#endif /* HALPLATFORM_H_ */

View File

@ -0,0 +1,63 @@
/******************************************************************************
Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
These sources were developed at the Freie Universitaet Berlin, Computer Systems
and Telematics group (http://cst.mi.fu-berlin.de).
-------------------------------------------------------------------------------
This file is part of FeuerWare.
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.
FeuerWare 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/ .
--------------------------------------------------------------------------------
For further information and questions please use the web site
http://scatterweb.mi.fu-berlin.de
and the mailinglist (subscription via web site)
scatterweb@lists.spline.inf.fu-berlin.de
*******************************************************************************/
#ifndef SHT11BOARD_H_
#define SHT11BOARD_H_
/**
* @ingroup lpc2387
* @{
*/
/**
* @file
* @brief LPC2387 SHT11 Device Driver
*
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
* @version $Revision$
*
* @note $Id$
*/
#include <lpc23xx.h>
#include <board.h>
#define SHT11_SCK_LOW FIO1CLR = BIT25; // serial clock line low
#define SHT11_SCK_HIGH FIO1SET = BIT25; // serial clock line high
#define SHT11_DATA ((FIO1PIN & BIT26) != 0) // read serial I/O
#define SHT11_DATA_LOW (FIO1CLR = BIT26); // serial I/O line low
#define SHT11_DATA_HIGH (FIO1SET = BIT26); // serial I/O line high
#define SHT11_DATA_IN (FIO1DIR &= ~BIT26) // serial I/O as input
#define SHT11_DATA_OUT (FIO1DIR |= BIT26) // serial I/O as output
#define SHT11_INIT FIO1DIR |= BIT25; PINSEL3 &= ~(BIT14|BIT15 | BIT16|BIT17);
/* time to wait after toggling the data line */
#define SHT11_DATA_WAIT (50)
/* time to wait after toggling the clock line */
#define SHT11_CLK_WAIT (10)
/** @} */
#endif /* SHT11BOARD_H_ */

View File

@ -0,0 +1,243 @@
/******************************************************************************
Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved.
These sources were developed at the Freie Universitaet Berlin, Computer Systems
and Telematics group (http://cst.mi.fu-berlin.de).
-------------------------------------------------------------------------------
This file is part of FeuerWare.
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.
FeuerWare 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/ .
--------------------------------------------------------------------------------
For further information and questions please use the web site
http://scatterweb.mi.fu-berlin.de
and the mailinglist (subscription via web site)
scatterweb@lists.spline.inf.fu-berlin.de
*******************************************************************************/
/**
* @file
* @ingroup LPC2387
* @brief CC1100 LPC2387 dependend functions
*
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
* @author Heiko Will <hwill@inf.fu-berlin.de>
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
* @version $Revision: 1781 $
*
* @note $Id: msba2-cc1100.c 1781 2010-01-26 13:39:36Z hillebra $
*/
#include <stdio.h>
#include <stddef.h>
// core
#include <cpu.h>
#include <irq.h>
// sys
#include "cc1100.h"
#include "arch_cc1100.h"
#include "cc1100_spi.h"
#include "gpioint.h"
#define CC1100_GDO0 (FIO0PIN & BIT27) // read serial I/O (GDO0)
#define CC1100_GDO1 (FIO1PIN & BIT23) // read serial I/O (GDO1)
#define CC1100_GDO2 (FIO0PIN & BIT28) // read serial I/O (GDO2)
#define SPI_TX_EMPTY (SSP0SR & SSPSR_TFE)
#define SPI_BUSY (SSP0SR & SSPSR_BSY)
#define SPI_RX_AVAIL (SSP0SR & SSPSR_RNE)
#define CC1100_GDO1_LOW_RETRY (100) // max. retries for GDO1 to go low
#define CC1100_GDO1_LOW_COUNT (2700) // loop count (timeout ~ 500 us) to wait
// for GDO1 to go low when CS low
//#define DEBUG
#ifdef DEBUG
#include "stdio.h"
static unsigned long time_value;
static void set_time(void) {
time_value = 0;
}
static int test_time(int code) {
time_value++;
if (time_value > 10000000) {
printf("CC1100 SPI alarm: %u!\n", code);
time_value = 0;
return 1;
}
return 0;
}
#endif
int cc1100_get_gdo0(void) {
return CC1100_GDO0;
}
int cc1100_get_gdo1(void) {
return CC1100_GDO1;
}
int cc1100_get_gdo2(void) {
return CC1100_GDO2;
}
void cc1100_spi_init(void)
{
// configure chip-select
FIO1DIR |= BIT21;
FIO1SET = BIT21;
// Power
PCONP |= PCSSP0; // Enable power for SSP0 (default is on)
// PIN Setup
PINSEL3 |= BIT8 + BIT9; // Set CLK function to SPI
PINSEL3 |= BIT14 + BIT15; // Set MISO function to SPI
PINSEL3 |= BIT16 + BIT17; // Set MOSI function to SPI
// Interface Setup
SSP0CR0 = 7;
// Clock Setup
uint32_t pclksel;
uint32_t cpsr;
lpc2387_pclk_scale(F_CPU/1000, 6000, &pclksel, &cpsr);
PCLKSEL1 &= ~(BIT10|BIT11); // CCLK to PCLK divider
PCLKSEL1 |= pclksel << 10;
SSP0CPSR = cpsr;
// Enable
SSP0CR1 |= BIT1; // SSP-Enable
int dummy;
// Clear RxFIFO:
while( SPI_RX_AVAIL ) { // while RNE (Receive FIFO Not Empty)...
dummy = SSP0DR; // read data
}
}
uint8_t
cc1100_txrx(uint8_t c) {
uint8_t result;
SSP0DR = c;
#ifdef DEBUG
set_time();
#endif
while (!SPI_TX_EMPTY) {
#ifdef DEBUG
test_time(0);
#endif
}
#ifdef DEBUG
set_time();
#endif
while (SPI_BUSY) {
#ifdef DEBUG
test_time(1);
#endif
}
#ifdef DEBUG
set_time();
#endif
while (!SPI_RX_AVAIL) {
#ifdef DEBUG
test_time(2);
#endif
}
result = (uint8_t)SSP0DR;
return result;
}
void cc1100_spi_cs(void)
{
FIO1CLR = BIT21;
}
void
cc1100_spi_select(void)
{
volatile int retry_count = 0;
volatile int abort_count;
// Switch to GDO mode input
PINSEL3 &= ~(BIT14 + BIT15);// Set MISO function to GPIO
FIO1DIR &= ~BIT23;
cs_low:
// CS to low
abort_count = 0;
FIO1CLR = BIT21;
// Wait for SO to go low (voltage regulator
// has stabilized and the crystal is running)
loop:
asm volatile ("nop");
if (CC1100_GDO1) {
abort_count++;
if (abort_count > CC1100_GDO1_LOW_COUNT) {
retry_count++;
if (retry_count > CC1100_GDO1_LOW_RETRY) {
puts("[CC1100 SPI] fatal error\n");
goto final;
}
FIO1SET = BIT21; // CS to high
goto cs_low; // try again
}
goto loop;
}
final:
// Switch to SPI mode
PINSEL3 |= (BIT14 + BIT15); // Set MISO function to SPI
}
void
cc1100_spi_unselect(void)
{
FIO1SET = BIT21;
}
void cc1100_before_send(void)
{
// Disable GDO2 interrupt before sending packet
cc1100_gdo2_disable();
}
void cc1100_after_send(void)
{
// Enable GDO2 interrupt after sending packet
cc1100_gdo2_enable();
}
void cc1100_gdo0_enable(void) {
gpioint_set(0, BIT27, GPIOINT_RISING_EDGE, &cc1100_gdo0_irq);
}
void cc1100_gdo0_disable(void) {
gpioint_set(0, BIT27, GPIOINT_DISABLE, NULL);
}
void cc1100_gdo2_disable(void) {
gpioint_set(0, BIT28, GPIOINT_DISABLE, NULL);
}
void cc1100_gdo2_enable(void) {
gpioint_set(0, BIT28, GPIOINT_FALLING_EDGE, &cc1100_gdo2_irq);
}
void cc1100_init_interrupts(void)
{
// Enable external interrupt on low edge (for GDO2)
FIO0DIR &= ~BIT28;
cc1100_gdo2_enable();
// Enable external interrupt on low edge (for GDO0)
FIO0DIR &= ~BIT27;
}

View File

@ -0,0 +1,65 @@
/******************************************************************************
Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved.
These sources were developed at the Freie Universitaet Berlin, Computer Systems
and Telematics group (http://cst.mi.fu-berlin.de).
-------------------------------------------------------------------------------
This file is part of FeuerWare.
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.
FeuerWare 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/ .
--------------------------------------------------------------------------------
For further information and questions please use the web site
http://scatterweb.mi.fu-berlin.de
and the mailinglist (subscription via web site)
scatterweb@lists.spline.inf.fu-berlin.de
*******************************************************************************/
/**
* @ingroup msba2
* @ingroup ltc4150
* @{
*/
/**
* @file
* @brief LTC4150 MSB-A2 specific implemetation
*
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
* @author Heiko Will
* @author Michael Baar
* @author Kaspar Schleiser <kaspar.schleiser@fu-berlin.de>
*/
#include <stdio.h>
#include "lpc2387.h"
#include "ltc4150_arch.h"
#include "gpioint.h"
void ltc4150_disable_int(void) {
gpioint_set(0, BIT4, GPIOINT_DISABLE, NULL);
}
void ltc4150_enable_int(void) {
gpioint_set(0, BIT4, GPIOINT_FALLING_EDGE, &ltc4150_interrupt);
}
void ltc4150_sync_blocking(void) {
while(!(FIO0PIN & BIT4)) {};
}
void ltc4150_arch_init() {
FIO0DIR |= BIT5;
FIO0SET = BIT5;
}
/** @} */

View File

@ -0,0 +1,205 @@
/******************************************************************************
Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved.
These sources were developed at the Freie Universitaet Berlin, Computer Systems
and Telematics group (http://cst.mi.fu-berlin.de).
-------------------------------------------------------------------------------
This file is part of FeuerWare.
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.
FeuerWare 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/ .
--------------------------------------------------------------------------------
For further information and questions please use the web site
http://scatterweb.mi.fu-berlin.de
and the mailinglist (subscription via web site)
scatterweb@lists.spline.inf.fu-berlin.de
*******************************************************************************/
/*
* debug_uart.c: provides initial serial debug output
*
* Copyright (C) 2008, 2009 Kaspar Schleiser <kaspar@schleiser.de>
* Heiko Will <hwill@inf.fu-berlin.de>
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "lpc23xx.h"
#include "VIC.h"
/**
* @file
* @ingroup lpc2387
*
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
* @version $Revision$
*
* @note $Id$
*/
typedef struct toprint {
unsigned int len;
char content[];
}toprint;
#define QUEUESIZE 255
static volatile toprint* queue[QUEUESIZE];
static volatile unsigned char queue_head = 0;
static volatile unsigned char queue_tail = 0;
static volatile unsigned char queue_items = 0;
static volatile unsigned int actual_pos = 0;
static volatile unsigned int running = 0;
static volatile unsigned int fifo = 0;
static volatile toprint* actual = NULL;
void (*uart0_callback)(int);
static inline void enqueue(void) {
queue_items++;
queue_tail++;
}
static inline void dequeue(void) {
actual = (queue[queue_head]);
queue_items--;
queue_head++;
}
static void push_queue(void) {
running = 1;
start:
if (!actual) {
if (queue_items) {
dequeue();
} else {
running = 0;
if (!fifo)
while(!(U0LSR & BIT6)){};
return;
}
}
while ((actual_pos < actual->len) && (fifo++ < 16)){
U0THR = actual->content[actual_pos++];
}
if (actual_pos == actual->len) {
free((void*)actual);
actual = NULL;
actual_pos = 0;
goto start;
}
}
int uart_active(void){
return (running || fifo);
}
static inline void receive(int c)
{
if (uart0_callback != NULL) uart0_callback(c);
}
void stdio_flush(void)
{
U0IER &= ~BIT1; // disable THRE interrupt
while(running) {
while(!(U0LSR & (BIT5|BIT6))){}; // transmit fifo
fifo=0;
push_queue(); // dequeue to fifo
}
U0IER |= BIT1; // enable THRE interrupt
}
void UART0_IRQHandler(void) __attribute__((interrupt("IRQ")));
void UART0_IRQHandler(void)
{
int iir;
iir = U0IIR;
switch(iir & UIIR_ID_MASK) {
case UIIR_THRE_INT: // Transmit Holding Register Empty
fifo=0;
push_queue();
break;
case UIIR_CTI_INT: // Character Timeout Indicator
case UIIR_RDA_INT: // Receive Data Available
do {
int c = U0RBR;
receive(c);
} while (U0LSR & ULSR_RDR);
break;
default:
U0LSR;
U0RBR;
break;
} // switch
VICVectAddr = 0; // Acknowledge Interrupt
}
static inline int uart0_puts(char *astring,int length)
{
while (queue_items == (QUEUESIZE-1)) {} ;
U0IER = 0;
queue[queue_tail] = malloc(length+sizeof(unsigned int));
queue[queue_tail]->len = length;
memcpy(&queue[queue_tail]->content,astring,length);
enqueue();
if (!running)
push_queue();
U0IER |= BIT0 | BIT1; // enable RX irq
/* alternative without queue:
int i;
for (i=0;i<length;i++) {
while (!(U0LSR & BIT5));
U0THR = astring[i];
}
*/
return length;
}
int fw_puts(char *astring,int length)
{
return uart0_puts(astring, length);
}
int
bl_uart_init(void)
{
PCONP |= PCUART0; // power on
// UART0 clock divider is CCLK/8
PCLKSEL0 |= BIT6 + BIT7;
U0LCR = 0x83; // 8 bits, no Parity, 1 Stop bit
// TODO: UART Baudrate calculation using uart->config->speed
/*
* Baudrate calculation
* BR = PCLK (9 MHz) / (16 x 256 x DLM + DLL) x (1/(DIVADDVAL/MULVAL))
*/
U0FDR = 0x92; // DIVADDVAL = 0010 = 2, MULVAL = 1001 = 9
U0DLM = 0x00;
U0DLL = 0x04;
U0LCR = 0x03; // DLAB = 0
U0FCR = 0x07; // Enable and reset TX and RX FIFO
/* irq */
install_irq(UART0_INT, UART0_IRQHandler, 6);
U0IER |= BIT0 | BIT1; // enable RX+TX irq
return 1;
}

View File

@ -0,0 +1,68 @@
/******************************************************************************
Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved.
These sources were developed at the Freie Universitaet Berlin, Computer Systems
and Telematics group (http://cst.mi.fu-berlin.de).
-------------------------------------------------------------------------------
This file is part of FeuerWare.
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.
FeuerWare 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/ .
--------------------------------------------------------------------------------
For further information and questions please use the web site
http://scatterweb.mi.fu-berlin.de
and the mailinglist (subscription via web site)
scatterweb@lists.spline.inf.fu-berlin.de
*******************************************************************************/
#ifndef BOARDCONF_H_
#define BOARDCONF_H_
/**
* @ingroup conf
* @ingroup msba2
*
* @{
*/
/**
* @file
* @brief MSB-A2 board configuration
*
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
* @author baar
* @version $Revision$
*
* @note $Id$
*/
#define FEUERWARE_CONF_BOARD_NAME "FU Berlin MSB-A2"
#ifdef MODULE_CC110X
#define FEUERWARE_CONF_NUM_RADIOS 1
#else
#define FEUERWARE_CONF_NUM_RADIOS 0
#endif
// if FAT is enabled this board supports files
#define FEUERWARE_CONF_CORE_SUPPORTS_FILES defined(MODULE_FAT)
#ifdef MODULE_FAT
#define CFG_CONF_MEM_SIZE 0x7FFFFFFF
#define SYSLOG_CONF_NUM_INTERFACES 2
#else
#define SYSLOG_CONF_NUM_INTERFACES 1
#endif
/** @} */
#endif /* BOARDCONF_H_ */

View File

@ -0,0 +1,62 @@
/******************************************************************************
Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved.
These sources were developed at the Freie Universitaet Berlin, Computer Systems
and Telematics group (http://cst.mi.fu-berlin.de).
-------------------------------------------------------------------------------
This file is part of FeuerWare.
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.
FeuerWare 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/ .
--------------------------------------------------------------------------------
For further information and questions please use the web site
http://scatterweb.mi.fu-berlin.de
and the mailinglist (subscription via web site)
scatterweb@lists.spline.inf.fu-berlin.de
*******************************************************************************/
#ifndef __BOARD_H
#define __BOARD_H
/**
* @ingroup msb_a2
* @{
*/
/**
* @file
* @brief MSB-A2 Board
*
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
* @author Kaspar Schleiser <kaspar@schleiser.de>
* @version $Revision$
*
* @note $Id$
*/
#include <lpc2387.h>
#define VICIntEnClear VICIntEnClr
#define LED_RED_PIN (BIT25)
#define LED_GREEN_PIN (BIT26)
#define LED_GREEN_OFF (FIO3SET = LED_GREEN_PIN)
#define LED_GREEN_ON (FIO3CLR = LED_GREEN_PIN)
#define LED_GREEN_TOGGLE (FIO3PIN ^= LED_GREEN_PIN)
#define LED_RED_OFF (FIO3SET = LED_RED_PIN)
#define LED_RED_ON (FIO3CLR = LED_RED_PIN)
#define LED_RED_TOGGLE (FIO3PIN ^= LED_RED_PIN)
/** @} */
#endif // __BOARD_H

View File

@ -0,0 +1,37 @@
/*
* lpc2387_timer0.c
*
* Created on: 13.01.2009
* Author: heiko
*/
#include <stdint.h>
#include <stdio.h>
#include "lpc2387.h"
#include "benchmark.h"
void benchmark_init(void)
{
PCLKSEL1 = (PCLKSEL1 & ~(BIT14|BIT15)) | (1 << 14); // CCLK to PCLK divider
PCONP |= PCTIM3;
T3TCR = 0; // disable timer
T3MCR = 0; // disable interrupt
T3CCR = 0; // capture is disabled.
T3EMR = 0; // no external match output.
T3PR = 0; // set prescaler
T3TC = 0; // reset counter
}
void benchmark_reset_start(void)
{
T3TCR = 0; // disable timer
T3TC = 0; // reset counter
T3TCR = BIT0;
}
unsigned int benchmark_read_stop(void)
{
T3TCR = 0; // disable timer
return T3TC;
}

23
board/msba2/tools/CHANGES Normal file
View File

@ -0,0 +1,23 @@
(heavily hacked by Heiko Will & Kaspar Schleiser since then)
1.05 (9-Apr-2007)
-----------------
Added boot jump code specific to 2378 (and similar chips) to
disable the PLL before jumping to the user's code.
1.04 (19-Dec-2006)
------------------
Added 2364, 2366, 2368, 2378 & 2468 to list. Untested.
1.03 (2-Jun-2006)
-----------------
Added 2103 chip to chip list. ID numbers for 2101 and 2102 unknown
1.02 (31-Jul-2005)
------------------
Added support for other chips
Added soft boot code
Added user configurable crystal value (for baud sync protocol)

339
board/msba2/tools/COPYING Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, 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
Appendix: 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) 19yy <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., 675 Mass Ave, Cambridge, MA 02139, 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) 19yy 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.

View File

@ -0,0 +1,43 @@
CFLAGS = -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)"
CC = gcc
all: lpc2k_pgm pseudoterm
SRC = lpc2k_pgm.c download.c uuencode.c ihex.c serial.c chipinfo.c boot_2xxx.c boot_23xx.c control_2xxx.c
OBJS = ${addprefix obj/,${patsubst %.c,%.o,$(SRC)}}
PSEUDOTERM_SRC = pseudoterm.c serial.c control_2xxx.c
PSEUDOTERM_OBJS = ${addprefix obj/,${patsubst %.c,%.o,$(PSEUDOTERM_SRC)}}
TARGETDIR = bin
lpc2k_pgm: $(OBJS)
$(CC) -o $(TARGETDIR)/lpc2k_pgm $(OBJS)
pseudoterm: $(PSEUDOTERM_OBJS)
$(CC) -lpthread -o $(TARGETDIR)/pseudoterm $(PSEUDOTERM_OBJS)
chipinfo.o: boot_2xxx.h boot_23xx.h
static: $(OBJS) mkstaticlist
$(CC) -o $(TARGETDIR)/lpc2k_pgm $(OBJS) `./mkstaticlist`
obj/%.o : src/%.c
$(CC) $(CFLAGS) -c $< -o $@
cksum_test: cksum_test.c uuencode.o cksum_test.o
$(CC) $(CFLAGS) -o $(TARGETDIR)/cksum_test obj/cksum_test.o obj/uuencode.o
boot_2xxx.c boot_2xxx.h: boot_2xxx.armasm mkbootc
arm-elf-as -o boot_2xxx.armobj boot_2xxx.armasm
arm-elf-objdump -d boot_2xxx.armobj | ./mkbootc boot_2xxx
boot_23xx.c boot_23xx.h: src/boot_23xx.armasm mkbootc
arm-elf-as -o obj/boot_23xx.armobj src/boot_23xx.armasm
arm-elf-objdump -d obj/boot_23xx.armobj | ./mkbootc boot_23xx
clean:
rm -f bin/lpc2k_pgm cksum_test obj/*.o core core.* obj/*.armobj bin/pseudoterm
obj/gui.o: src/gui.c
$(CC) $(CFLAGS) `gtk-config --cflags` -c src/gui.c -o obj/gui.o

View File

@ -0,0 +1,144 @@
This utility downloads code to Philip LPC 2000 series chips, using the
bootloader communication protocol documented in the LPC2106/2105/2104
User Manual, Sept 2003 revision, pages 177 to 192. This code has also
been tested with LPC2131 and LPC2138 chips (thanks to New Micros for
providing eval boards). It may work with other Philips ARM LPC parts.
Usage:
-----
When you start the program, it's small control window appears, and a
xterm terminal window is launched. The Xterm window allows you to
simply leave lpc2k_pgm running and interface with the LPC uart using
that window. Most people configure "printf" on in their code to print
to UART0, which will appear in this window.
This program has 4 settings:
Firmware: The intel-hex file with your LPC firmware to program.
Port: Which serial device to use.
Baud: The baud rate to communicate.
Crystal: The speed of the crystal on your LPC board.
Once you have set up these values, simply press the "Program Now"
button to write your firmware to the LPC flash memory, and automatically
run it. If your firmware communicates on UART0, its messages will appear
in the xterm window, and anything you type in that window will be
transmitted to your board.
The "Reboot" button may be used to reboot your code (assuming you have
connected DTR appropriately). The "Bootloader" button may be used to
stop your code by rebooting into the bootloader, rather than your program.
Hardware Requirements:
---------------------
You must have a compatible Philips LPC chip with its UART0 interfaced
to a serial port on your PC.
You must be able to reset the chip and cause it to enter bootloader mode.
Normally, this is done by connecting the (TTL level translated) DTR signal
to the LPC reset, so that when DTR is high (the TTL version is low), the
Philips chip is in reset mode. Alternately, a pushbutton may be used,
but you will need to manually press the button every time you want to get
back into bootloader mode (while this program attempts to sync baud rates),
rather than letting DTR do it automatically. A few minutes spent wiring
up your circuit so DTR can reset the board will save you much trouble as
you develop code.
P0.14 must be connected low shortly after reset. Normally, this pin
is just shorted to ground using a jumper. Starting with version 1.02,
you can simply leave this shorted to ground. If your design needs to
use this pin, you may also build a simple circuit that forces this pin
to ground when RTS is high.
Software Requirements:
---------------------
You must have a Linux-based system running X Windows. This code has
been tested with Linux kernel 2.4.20 and 2.6.8, and should work with
almost any linux system.
You must have the "xterm" program installed. Nearly all linux
distrubtions provide this, and it is often installed by default. If
you do not have it, simply install from your linux distribution.
Your serial port device file (usually /dev/ttyS0 or /dev/ttyS1) must
allow permission for you to use the serial port.
GTK 1.2 is used for the GUI. Many newer systems only have GTK version
2 (or higher). If you have one of these systems, perhaps you can
install GTK 1.2 (including the development libraries) to allow you to
compile this code. Alternately, you may be able to use the semi-static
build, which includes a copy of this code built into the program.
Building and Installation:
-------------------------
This software is only provided semi-static binary and source code form.
To use the semi-static binary, simply copy it to a location where you
can run it, and change the permissions if necessary:
cp lpc2k_pgm /usr/local/bin
chmod 755 /usr/local/bin/lpc2k_pgm
The semi-static binary has all of the GTK and X11 libraries statically
linked into it, for maximum compatibility with all linux distributions.
The only disadvantage is, of course, that this uses an extra 1.4 megs
of RAM, with (might) otherwise be shared with other programs. If you
simply want to run this program with minimal work, using the semi-static
binary may be the easiest way.
If you compile from the source code, the result should be a small
binary that is optimal for your system.
To build from source, you must have GTK+ 1.2 development libraries
and GCC properly installed. Nearly all linux distributions provide
these as packages, but you may need to install them before you can
compile the code.
TODO: specific instructions for Debian stable
TODO: specific instructions for Debian testing/unstable
TODO: specific instructions for Fedora
TODO: specific instructions for Suse
Simply type "make" to build the code. The resulting "lpc2k_pgm"
program can be run from any location. Simply copy to /usr/local/bin,
or where ever you like.
Contact Info:
------------
Paul Stoffregen
paul@pjrc.com
http://www.pjrc.com/arm/lpc2k_pgm
If you discover a bug, you want to request a new feature, or you have
a new Philips LPC chip which is not recognized, please attempt to
provide COMPLETE information in your message.
If you have problems building from source, please contact me with ALL
of the following:
1: Complete copy of all messages during the build.
2: Output of "gtk-config --version"
3: Output of "gtk-config --libs"
4: Output of "gtk-config --cflags"
5: Output of "uname -a"
6: Other info... which linux distribution, version, other software
If you get "Command not found" when trying to run "gtk-config", this
is a sure sign that you do not have GTK+ 1.2 installed.

View File

@ -0,0 +1,15 @@
This directory contains flash & terminal-utilities for use with
the msb_av2 platform used by the FeuerWhere-Project.
Usage:
Running "./pseudoterm /dev/ttyUSB1" will start the terminal-emulator,
open the specified port and reset the connected msb_av2-board.
If it receives a SIGUSR2, the terminal closes the port an waits.
On reception of a SIGUSR1, it reopens the port and resets the ARM.
"./lpc2k_pgm /dev/ttyUSB1 /path/to/firmware.ihex" will do what you
expect, but it will additionally run "killall -SIGUSR2 pseudoterm" before
anѕ "killall -SIGUSR1 pseudoterm" after flashing.
Together, the tools enable you to have a terminal connected to the board
at all times, but let you flash whenever you feel like.

2
board/msba2/tools/flash.cmd Executable file
View File

@ -0,0 +1,2 @@
fm.exe "COM(%1, 230400) DEVICE(LPC2387, 16.000000) HARDWARE(BOOTEXEC, 50, 100) HIGHSPEED(0, 230400) ERASEUSED(%2, PROTECTISP) HEXFILE(%2, NOCHECKSUMS, NOFILL, PROTECTISP) RESET"
sleep 2

113
board/msba2/tools/flashutil.sh Executable file
View File

@ -0,0 +1,113 @@
#/bin/bash
linux_checkid() {
udevinfo -a -n ${1} | grep -q "ATTRS{product}==\"${2}\""
}
windows_flash_fm() {
echo "Checking FTDI device on COM${1}"
PORTINFO=`${BASEDIR}/../../../tools/windows/ftdiinfo/bin/Debug/ftdiinfo.exe /l COM${1}`
PORTCHECK=`echo ${PORTINFO} | awk '{ print $1 }'`
BOARDCHECK=`echo ${PORTINFO} | awk '{ print $3 }'`
SERIAL=`echo ${PORTINFO} | awk '{ print $2 }'`
if [ "${PORTCHECK}" != "COM${1}" ]; then
echo " port mismatch / ftdiinfo failed"
exit 1
fi
if [ "${BOARDCHECK}" != "\"${FTDI_ID}\"" ]; then
echo " target mismatch: target board is \"${FTDI_ID}\", connected is ${BOARDCHECK}"
exit 1
fi
echo "Flashing ${HEXFILE} to COM${1} (${BOARDCHECK} serial ${SERIAL})"
# Using FlashMagic on Windows (in separate window)
cmd /C start "FlashMagic ${HEXFILE} to ${BOARDCHECK} on COM${1}" fm.exe "COM(${1}, 230400) DEVICE(LPC2387, 16.000000) HARDWARE(BOOTEXEC, 50, 100) HIGHSPEED(0, 230400) ERASEUSED(${HEXFILE}, PROTECTISP) HEXFILE(${HEXFILE}, NOCHECKSUMS, NOFILL, PROTECTISP) RESET"
}
windows_flash_openocd() {
echo "Flashing ${HEXFILE} through JTAG"
# Using OpenOcd on Windows
#cmd /C start "OpenOCD ${HEXFILE} to ${BOARDCHECK}"
bash -x ${OPENOCD} ${OPENOCD_IF} "mt_flash ${HEXFILE}; reset run; shutdown"
}
TEMP=`getopt -a -o b:i:p:f:: --long basedir:,id:,ports:,file:,openocd:,openocd-if:,xxx:: \
-n 'flashutil.sh' -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"
while true ; do
echo $1: $2
case "$1" in
-b|--basedir) BASEDIR=$2 ; shift 2 ;;
-i|--id) FTDI_ID=$2; shift 2 ;;
-p|--ports) PORTS=`echo $2 | sed -e 's:,: :g'`; shift 2 ;;
--openocd) OPENOCD=$2; shift 2 ;;
--openocd-if) OPENOCD_IF=$2; shift 2 ;;
--) HEXFILE=$2 ; shift ; break ;;
*) echo "Internal error!" ; exit 1 ;;
esac
done
if [ "${OS}" = "Windows_NT" ]; then
WINDOWS=1
fi
FLASHUTIL_SHELL=${FLASHUTIL_SHELL:-"xterm -e"}
if [ "x${WINDOWS}x" = "xx" ]; then
echo Pausing terminal
${BASEDIR}/termctrl.sh pause
else
HEXFILE=`echo ${HEXFILE} | sed -e 's:/:\\\\:g'`
BASEDIRWIN=`echo ${BASEDIR} | sed -e 's:/:\\\\:g'`
fi
pids=""
#
# for OpenOCD let the user verify, that the correct board is connected
#
if [ ${PORTS} = "openocd" ]; then
[ "$OPENOCD" != "" ] || exit 1
[ "$OPENOCD_IF" != "" ] || exit 1
# echo -n "Is the board connected to the JTAG a '${FTDI_ID}' (y/n)? "
# read REPLY
# [ "$REPLY" = "y" ] || exit 1
fi
#
# start a flasher for each port
#
for PORT in $PORTS; do
if [ "x${WINDOWS}x" != "xx" ]; then
if [ "${PORT}" = "openocd" ]; then
windows_flash_openocd
else
windows_flash_fm ${PORT}
fi
else
if [ "${PORT}" = "openocd" ]; then
${OPENOCD} ${OPENOCD_IF} "mt_flash ${HEXFILE}; reset run; shutdown"
else
echo Flashing ${HEXFILE} to ${PORT}
# using homemade lpc2k_pgm else
${FLASHUTIL_SHELL} "${BASEDIR}/bin/lpc2k_pgm ${PORT} ${HEXFILE}; sleep 2" &
pids="${pids} $!"
fi
fi
done
### wait for all flasher processes to finish
echo Waiting until all devices have been programmed...
for pid in "${pids}"; do
wait ${pid}
done
if [ "x${WINDOWS}x" = "xx" ]; then
echo Resuming terminal
${BASEDIR}/termctrl.sh continue
fi

28
board/msba2/tools/mkbootc Normal file
View File

@ -0,0 +1,28 @@
#! /usr/bin/perl
$h = '[0-9A-Fa-f]';
$n = 1;
while (<stdin>) {
next unless /^\s*$h+:\s+($h{8})/;
$data[$n++] = "0x$1";
}
$data[0] = $n;
#$size = $ARGV[0];
#$size =~ tr/a-z/A-Z/;
#$size .= '_SIZE';
open H, ">$ARGV[0].h" or die "unable to write boot.h\n";
print H "/* automatically generated from $ARGV[0].armasm */\n";
#print H "#define $size $n\n";
print H "extern const unsigned int ${ARGV[0]}[];\n";
close H;
open C, ">$ARGV[0].c" or die "unable to write boot.c\n";
print C "/* automatically generated from $ARGV[0].armasm */\n";
print C "#include \"$ARGV[0].h\"\n";
print C "const unsigned int ${ARGV[0]}[] = {\n";
print C "\t", join(', ', @data), "\n";
print C "};\n";
close C;

View File

@ -0,0 +1,47 @@
#! /usr/bin/perl
@arg = split(/\s+/, `gtk-config --libs`);
%liblist = (
'libgtk.a', '/usr/lib/libgtk.a',
'libgdk.a', '/usr/lib/libgdk.a',
'libgmodule.a', '/usr/lib/libgmodule.a',
'libglib.a', '/usr/lib/libglib.a',
'libXi.a', '/usr/X11R6/lib/libXi.a',
'libXext.a', '/usr/X11R6/lib/libXext.a',
'libX11.a', '/usr/X11R6/lib/libX11.a'
);
for ($i=0; $i<@arg; $i++) {
$a = $arg[$i];
next if $a eq '-rdynamic'; # always delete -rdynamic
if (($a eq '-lm') || ($a eq '-ldl') || ($a =~ /^-L/)) {
# a few things we never change
print "$a ";
next;
}
if ($a =~ /^-l/) {
$lib = $';
$lib = 'lib' . $lib . '.a';
# first check if it's in the known location
if (-f $liblist{$lib}) {
print $liblist{$lib}, " ";
next;
}
# resort to trying whereis to find it
@source = split(/\s+/, `whereis $lib`);
undef($static);
for ($j=0; $j<@source; $j++) {
$static = $source[$j] if $source[$j] =~ /$lib$/;
}
# if we found a static lib, use it.
if ($static) {
print $static, " ";
} else {
print $a, " ";
}
}
}
print "\n";

View File

@ -0,0 +1,3 @@
obj/boot_23xx.d obj/boot_23xx.o: src/boot_23xx.c src/boot_23xx.h
src/boot_23xx.h:

View File

@ -0,0 +1,3 @@
obj/boot_2xxx.d obj/boot_2xxx.o: src/boot_2xxx.c src/boot_2xxx.h
src/boot_2xxx.h:

View File

@ -0,0 +1,8 @@
obj/chipinfo.d obj/chipinfo.o: src/chipinfo.c src/chipinfo.h \
src/boot_2xxx.h src/boot_23xx.h
src/chipinfo.h:
src/boot_2xxx.h:
src/boot_23xx.h:

View File

@ -0,0 +1,6 @@
obj/control_2xxx.d obj/control_2xxx.o: src/control_2xxx.c \
src/control_2xxx.h src/serial.h
src/control_2xxx.h:
src/serial.h:

View File

@ -0,0 +1,19 @@
obj/download.d obj/download.o: src/download.c src/lpc2k_pgm.h \
src/download.h src/serial.h src/ihex.h src/uuencode.h src/chipinfo.h \
src/boot.h src/control_2xxx.h
src/lpc2k_pgm.h:
src/download.h:
src/serial.h:
src/ihex.h:
src/uuencode.h:
src/chipinfo.h:
src/boot.h:
src/control_2xxx.h:

View File

@ -0,0 +1,3 @@
obj/ihex.d obj/ihex.o: src/ihex.c src/ihex.h
src/ihex.h:

View File

@ -0,0 +1,8 @@
obj/lpc2k_pgm.d obj/lpc2k_pgm.o: src/lpc2k_pgm.c src/lpc2k_pgm.h \
src/serial.h src/download.h
src/lpc2k_pgm.h:
src/serial.h:
src/download.h:

View File

@ -0,0 +1,6 @@
obj/pseudoterm.d obj/pseudoterm.o: src/pseudoterm.c src/serial.h \
src/download.h
src/serial.h:
src/download.h:

View File

@ -0,0 +1,3 @@
obj/serial.d obj/serial.o: src/serial.c src/serial.h
src/serial.h:

View File

@ -0,0 +1,3 @@
obj/uuencode.d obj/uuencode.o: src/uuencode.c src/uuencode.h
src/uuencode.h:

View File

@ -0,0 +1,9 @@
Library liblpc2k : download.c uuencode.c ihex.c serial.c chipinfo.c boot_2xxx.c boot_23xx.c control_2xxx.c ;
LinkLibraries lpc2k_pgm : liblpc2k ;
LinkLibraries pseudoterm : liblpc2k ;
LINKFLAGS on pseudoterm = -lrt ;
Main lpc2k_pgm : lpc2k_pgm.c ;
Main pseudoterm : pseudoterm.c ;

View File

@ -0,0 +1,9 @@
typedef struct {
int size;
const int *prog;
} boot_t;

View File

@ -0,0 +1,32 @@
/* ARM code to run user code */
/* on the LPC23xx chips, the bootloader defaults to using the RC */
/* osciallator and it activates the PLL to create 14.78 MHz, even */
/* if there is no crystal. However, when we use try to jump to */
/* the user's code, their startup routine may (incorrectly) assume */
/* the PLL is not enabled and crash if it is. So in addition to */
/* remapping the reset vector to flash, we have to shut off the */
/* PLL so the user's startup code sees the same conditions as it */
/* would following a hard reset */
begin:
adr r0, const
ldr r1, [r0] /* r1 points to MEMMAP register */
ldr r2, [r0,#4] /* r2 points to PLLCON */
ldr r3, [r0,#8] /* r3 points to PLLFEED */
mov r0, #1
str r0, [r1] /* remap interrupt vectors to flash */
mov r4, #0xAA
mov r5, #0x55
str r0, [r2] /* disconnect the PLL, PLLCON = 1 */
str r4, [r3]
str r5, [r3]
mov r0, #0
str r0, [r2] /* disable the PLL, PLLCON = 0 */
str r4, [r3]
str r5, [r3]
mov pc, #0 /* and then jump to the user's code */
const:
.int 0xE01FC040 /* MEMMAP register */
.int 0xE01FC080 /* PLLCON */
.int 0xE01FC08C /* PLLFEED */

View File

@ -0,0 +1,5 @@
/* automatically generated from boot_23xx.armasm */
#include "boot_23xx.h"
const unsigned int boot_23xx[] = {
20, 0xe28f0038, 0xe5901000, 0xe5902004, 0xe5903008, 0xe3a00001, 0xe5810000, 0xe3a040aa, 0xe3a05055, 0xe5820000, 0xe5834000, 0xe5835000, 0xe3a00000, 0xe5820000, 0xe5834000, 0xe5835000, 0xe3a0f000, 0xe01fc040, 0xe01fc080, 0xe01fc08c
};

View File

@ -0,0 +1,2 @@
/* automatically generated from boot_23xx.armasm */
extern const unsigned int boot_23xx[];

View File

@ -0,0 +1,15 @@
/* ARM code to run user code */
/* This allows us to jump to the user's code in flash. We have */
/* to remap the flash before jumping. */
begin:
adr r0, const
ldr r1, [r0] /* r1 points to MEMMAP register */
mov r0, #1
str r0, [r1] /* remap interrupt vectors to flash */
mov pc, #0 /* and then jump to the user's code */
const:
.int 0xE01FC040 /* MEMMAP register */

View File

@ -0,0 +1,5 @@
/* automatically generated from boot_2xxx.armasm */
#include "boot_2xxx.h"
const unsigned int boot_2xxx[] = {
7, 0xe28f000c, 0xe5901000, 0xe3a00001, 0xe5810000, 0xe3a0f000, 0xe01fc040
};

View File

@ -0,0 +1,2 @@
/* automatically generated from boot_2xxx.armasm */
extern const unsigned int boot_2xxx[];

View File

@ -0,0 +1,159 @@
/*
* LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
* Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
*
* 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.
*
* 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.
*
*/
#include <stdio.h>
#include "chipinfo.h"
#include "boot_2xxx.h"
#include "boot_23xx.h"
struct sector_info_struct lpc2106_layout[] = {
{0x00000000, 0x2000},
{0x00002000, 0x2000},
{0x00004000, 0x2000},
{0x00006000, 0x2000},
{0x00008000, 0x2000},
{0x0000A000, 0x2000},
{0x0000C000, 0x2000},
{0x0000E000, 0x2000},
{0x00010000, 0x2000},
{0x00012000, 0x2000},
{0x00014000, 0x2000},
{0x00016000, 0x2000},
{0x00018000, 0x2000},
{0x0001A000, 0x2000},
{0x0001C000, 0x2000}
};
struct sector_info_struct lpc2214_layout[] = {
{0x00000000, 0x2000},
{0x00002000, 0x2000},
{0x00004000, 0x2000},
{0x00006000, 0x2000},
{0x00008000, 0x2000},
{0x0000A000, 0x2000},
{0x0000C000, 0x2000},
{0x0000E000, 0x2000},
{0x00010000, 0x10000},
{0x00020000, 0x10000},
{0x00030000, 0x2000},
{0x00032000, 0x2000},
{0x00034000, 0x2000},
{0x00036000, 0x2000},
{0x00038000, 0x2000},
{0x0003A000, 0x2000},
{0x0003C000, 0x2000}
};
struct sector_info_struct lpc2138_layout[] = {
{0x00000000, 0x1000},
{0x00001000, 0x1000},
{0x00002000, 0x1000},
{0x00003000, 0x1000},
{0x00004000, 0x1000},
{0x00005000, 0x1000},
{0x00006000, 0x1000},
{0x00007000, 0x1000},
{0x00008000, 0x8000},
{0x00010000, 0x8000},
{0x00018000, 0x8000},
{0x00020000, 0x8000},
{0x00028000, 0x8000},
{0x00030000, 0x8000},
{0x00038000, 0x8000},
{0x00040000, 0x8000},
{0x00048000, 0x8000},
{0x00050000, 0x8000},
{0x00058000, 0x8000},
{0x00060000, 0x8000},
{0x00068000, 0x8000},
{0x00070000, 0x8000},
{0x00078000, 0x1000},
{0x00079000, 0x1000},
{0x0007A000, 0x1000},
{0x0007B000, 0x1000},
{0x0007C000, 0x1000}
};
// chunk_size is the number of bytes that will be sent with each
// "C" (Copy RAM to Flash) command. This must be one of the sizes
// supported by that command. Beware that different chips support
// different sets of sizes, so check the user manual specific to
// the chip. You must choose a chunk_size which is an an integer
// multiple of all the sector sizes, and it must be able to fit
// entirely within the RAM (allowing for the bootloader memory and
// stack usage). Currently, all available chunk sizes meet these
// requirements, but who knows what Philips will do in the future?
//
// ram_addr is the location in RAM where the chunks are sent by the
// "W" (Write to RAM) command.
struct chip_info_struct chip_info[] = {
// chunk num
//part_number id_string ram_addr _size sec sector layout boot code
{"LPC2104 (120k)", "4293984018", 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx},
{"LPC2105 (120k)", "4293984034", 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx},
{"LPC2106 (120k)", "4293984050", 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx},
{"LPC2114 (120k)", "16908050", 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx},
{"LPC2119 (120k)", "33685266", 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx},
{"LPC2124 (120k)", "16908051", 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx},
{"LPC2129 (248k)", "33685267", 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx},
{"LPC2131 (32k)", "196353", 0x40000200, 0x1000, 8, lpc2138_layout, boot_2xxx},
{"LPC2132 (64k)", "196369", 0x40000200, 0x1000, 9, lpc2138_layout, boot_2xxx},
{"LPC2134 (128k)", "196370", 0x40000200, 0x1000, 11, lpc2138_layout, boot_2xxx},
{"LPC2136 (256k)", "196387", 0x40000200, 0x1000, 15, lpc2138_layout, boot_2xxx},
{"LPC2138 (500k)", "196389", 0x40000200, 0x1000, 27, lpc2138_layout, boot_2xxx},
{"LPC2141 (32k)", "67305217", 0x40000200, 0x1000, 8, lpc2138_layout, boot_2xxx},
{"LPC2142 (64k)", "67305233", 0x40000200, 0x1000, 9, lpc2138_layout, boot_2xxx},
{"LPC2144 (128k)", "67305234", 0x40000200, 0x1000, 11, lpc2138_layout, boot_2xxx},
{"LPC2146 (256k)", "67305251", 0x40000200, 0x1000, 15, lpc2138_layout, boot_2xxx},
{"LPC2148 (500k)", "67305253", 0x40000200, 0x1000, 27, lpc2138_layout, boot_2xxx},
{"LPC2194 (248k)", "50462483", 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx},
{"LPC2212 (248k)", "67239698", 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx},
{"LPC2214 (248k)", "100794131", 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx},
{"LPC2292 (248k)", "67239699", 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx},
{"LPC2294 (248k)", "84016915", 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx},
//{"LPC2101 (8k)", "??????", 0x40000200, 0x1000, 2, lpc2138_layout, boot_2xxx},
//{"LPC2102 (16k)", "??????", 0x40000200, 0x1000, 4, lpc2138_layout, boot_2xxx},
{"LPC2103 (32k)", "327441", 0x40000200, 0x1000, 8, lpc2138_layout, boot_2xxx},
{"LPC2364 (128k)", "100924162", 0x40000200, 0x1000, 11, lpc2138_layout, boot_23xx},
{"LPC2366 (256k)", "100924195", 0x40000200, 0x1000, 15, lpc2138_layout, boot_23xx},
{"LPC2368 (500k)", "100924197", 0x40000200, 0x1000, 27, lpc2138_layout, boot_23xx},
{"LPC2378 (500k)", "117702437", 0x40000200, 0x1000, 27, lpc2138_layout, boot_23xx},
{"LPC2387 (500k)", "402716981", 0x40000200, 0x1000, 27, lpc2138_layout, boot_23xx},
{"LPC2387 (500k)", "385941301", 0x40000200, 0x1000, 27, lpc2138_layout, boot_23xx},
{"LPC2468 (500k)", "100925237", 0x40000200, 0x1000, 27, lpc2138_layout, boot_23xx},
{NULL, NULL, 0, 0, 0, NULL}
};
char *lpc_return_strings[] = {
"CMD_SUCCESS", "INVALID_COMMAND", "SRC_ADDR_ERROR", "DST_ADDR_ERROR",
"SRC_ADDR_NOT_MAPPED", "DST_ADDR_NOT_MAPPED", "COUNT_ERROR", "INVALID_SECTOR",
"SECTOR_NOT_BLANK", "SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION", "COMPARE_ERROR",
"BUSY", "PARAM_ERROR", "ADDR_ERROR", "ADDR_NOT_MAPPED", "CMD_LOCKED",
"INVALID_CODE", "INVALID_BAUD_RATE", "INVALID_STOP_BIT",
"CODE_READ_PROTECTION_ENABLED"
};

View File

@ -0,0 +1,20 @@
extern char *lpc_return_strings[];
struct sector_info_struct { // an array of
int address; // where each sector is located
int size; // and how big it is
};
struct chip_info_struct {
char *part_number; // human readable part number
char *id_string; // id string sent by "J" command
unsigned int ram_addr; // where to download into RAM
int chunk_size; // download to ram chunk size
int num_sector; // number of flash sectors
struct sector_info_struct *layout; // layout of sectors
const unsigned int *bootprog; // code that boots into user program (NULL = DTR/RTS only)
};
extern struct chip_info_struct chip_info[];

View File

@ -0,0 +1,76 @@
/*
* LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
* Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
*
* 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.
*
* 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.
*
*/
/* If this code fails to build, please provide at least the following
* information when requesting (free) technical support.
*
* 1: Complete copy of all messages during the build.
* 2: Output of "gtk-config --version"
* 3: Output of "gtk-config --libs"
* 4: Output of "gtk-config --cflags"
* 5: Output of "uname -a"
* 6: Version of GTK installed... eg, type: ls -l /lib/libgtk*
* 7: Other info... which linux distribution, version, other software
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "uuencode.h"
unsigned int sum=0;
void cksum(const char *str)
{
int num, i;
unsigned char data[256];
if (str == NULL) return;
num = uudecode(str, data, sizeof(data));
for (i=0; i<num; i++) {
sum += data[i];
}
}
int main()
{
char buf[4096];
while (!feof(stdin)) {
fgets(buf, sizeof(buf), stdin);
if (strcmp(buf, "\n") == 0) break;
cksum(buf);
}
printf("sum = %u\n", sum);
return 0;
}

View File

@ -0,0 +1,31 @@
#include "control_2xxx.h"
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include "serial.h"
void hard_reset_to_bootloader(void)
{
printf("Reset CPU (into bootloader)\r\n");
set_rts(1); // RTS (ttl level) connects to P0.14
set_dtr(1); // DTR (ttl level) connects to RST
send_break_signal(); // or break detect circuit to RST
usleep(75000);
set_dtr(0); // allow the CPU to run
set_baud(baud_rate);
set_rts(1); // set RTS again (as it has been reset by set_baudrate)
usleep(40000);
}
void hard_reset_to_user_code(void)
{
printf("Reset CPU (into user code)\r\n");
set_rts(0); // RTS (ttl level) connects to P0.14
set_dtr(1); // DTR (ttl level) connects to RST
send_break_signal(); // or break detect circuit to RST
usleep(75000);
set_dtr(0); // allow the CPU to run
usleep(40000);
}

View File

@ -0,0 +1,8 @@
#ifndef CONTROL_2XXXX_H
#define CONTROL_2XXXX_H
void hard_reset_to_bootloader(void);
void hard_reset_to_user_code(void);
#endif // ..._H

View File

@ -0,0 +1,972 @@
/*
* LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
* Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
*
* 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.
*
* 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.
*
*/
/* If this code fails to build, please provide at least the following
* information when requesting (free) technical support.
*
* 1: Complete copy of all messages during the build.
* 2: Output of "gtk-config --version"
* 3: Output of "gtk-config --libs"
* 4: Output of "gtk-config --cflags"
* 5: Output of "uname -a"
* 6: Version of GTK installed... eg, type: ls -l /lib/libgtk*
* 7: Other info... which linux distribution, version, other software
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include "lpc2k_pgm.h"
#include "download.h"
#include "serial.h"
#include "ihex.h"
#include "uuencode.h"
//#include "gui.h"
#include "chipinfo.h"
#include "boot.h"
#include "control_2xxx.h"
// This will cause all bytes send and received to be printed as hex.
// It's a LOT of extra output, but useful for difficult debugging
// of what's _really_ being sent and received.
//#define PRINT_TX_RX_BYTES
static void download_main(int event);
static void xmit_cmd(const char *cmd, int max_time);
static void mk_valid_code_vector(void);
static unsigned int sum(unsigned char *data, int num);
static int state=0;
static int reboot_only=0;
static char expected_echo_buf[4096];
static char *expected_echo_ptr=NULL;
static char parsed_response_buf[4096];
static char *parsed_response_ptr=NULL;
static int response_timer=0;
extern int programming_done;
extern int done_program(int);
char* port_name = "/dev/ttyUSB1";
char* file_name = "";
char* crystal = "16";
/****************************************************************/
/* */
/* Main Download Section */
/* */
/****************************************************************/
// possible states
#define SYNC_1 1
#define SYNC_2 2
#define SYNC_3 3
#define CHIP_ID 4
#define UNLOCK 5
#define BLANK_CHECK_SECTOR 6
#define ERASE_PREPARE 7
#define ERASE_SECTOR 8
#define DOWNLOAD_CODE 9
#define XMIT_DATA 10
#define XMIT_CKSUM 11
#define WRITE_PREPARE 12
#define WRITE_SECTOR 13
#define BOOT_HARD 14
#define BOOT_SOFT 15
#define BOOT_XMIT_DATA 16
#define BOOT_XMIT_CKSUM 17
#define BOOT_RUN_CODE 18
// possible input values for "event"
#define BEGIN 1
#define RESPONSE 2
#define TIMEOUT 3
#define RETRY 4
int download_begin(char* file)
{
int r;
file_name = file;
printf("\r\nEntering Bootloader Mode\r\n");
hard_reset_to_bootloader();
printf("Read \"%s\"", file_name);
r = read_intel_hex(file_name);
if (r < 0) {
/* abort on ioerror */
return 0;
}
printf(": %d bytes\r\n", r);
mk_valid_code_vector();
state = SYNC_1;
reboot_only = 0;
download_main(BEGIN);
return 1;
}
void soft_reboot_begin(void)
{
printf("\r\nEntering Bootloader Mode\r\n");
hard_reset_to_bootloader();
state = SYNC_1;
reboot_only = 1;
download_main(BEGIN);
}
static void mk_valid_code_vector(void)
{
unsigned char b[4];
unsigned int sum=0;
int addr;
for (addr=0; addr<0x20; addr+=4) {
if (addr != 0x14) {
get_ihex_data(addr, 4, b);
sum += (b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24));
}
}
sum ^= 0xFFFFFFFF;
sum++;
b[0] = (sum >> 0) & 255;
b[1] = (sum >> 8) & 255;
b[2] = (sum >> 16) & 255;
b[3] = (sum >> 24) & 255;
put_ihex_data(0x14, 4, b);
}
static unsigned int sum(unsigned char *data, int num)
{
unsigned int sum=0;
while (num > 0) {
sum += *data++;
num--;
}
return sum;
}
static int num_lines(const char *buf)
{
const char *p;
int count=0;
p = buf;
while (p != NULL) {
p = strstr(p, "\r\n");
if (p != NULL) {
count++;
p += 2;
}
}
return count;
}
void trim_crlf(char *str)
{
char *p;
p = strstr(str, "\r\n");
if (p != NULL) *p = '\0';
}
void copy_boot_code_to_memory(struct chip_info_struct *chip)
{
int i;
unsigned char c[4];
for (i=0; i < chip->bootprog[0]; i++) {
c[3] = (chip->bootprog[i+1] >> 24) & 255;
c[2] = (chip->bootprog[i+1] >> 16) & 255;
c[1] = (chip->bootprog[i+1] >> 8) & 255;
c[0] = (chip->bootprog[i+1]) & 255;
put_ihex_data(i * 4, 4, c);
}
}
#define NO_SYNC_ERR "\r\n\
ERROR: Unable to sync to baud rate.\r\n\
This probably means the LPC2xxx chip is not connected\r\n\
or it is not being reset, or P0.14 is not low after\r\n\
reset to cause it to enter the bootloader mode.\r\n\r\n\
Please check the serial port connection, make sure\r\n\
pin P0.14 is low (or tied to RTS via RS-232 level\r\n\
translator), and the chip has been reset (or reset\r\n\
is tied to DTR via RS-232 level translator).\r\n"
#define UNKNOWN_CHIP_ERROR "\r\n\
Unknown chip ID: \"%s\".\r\n\r\n\
Perhaps you have a new Philips LPC chip which does not\r\n\
have its ID string and sector map defined in this program?\r\n\
Please contact paul@pjrc.com. Please include an exact copy\r\n\
of this message and any info about the chip and other\r\n\
hardware you may be using. Thanks :-)\r\n"
static void download_main(int event)
{
char buf[4096];
unsigned char bytes[256];
double xtal;
int n;
static unsigned int cksum;
static int retry=0;
static int sector; // current sector we're doing
static int sector_offset;
static struct chip_info_struct *chip; // which chip
static int current_addr, num_to_xmit, linecount;
while (1) {
switch (state) {
case SYNC_1:
switch (event) {
case BEGIN:
printf("Attempting baud sync");
retry = 0;
case RETRY:
printf(".");
fflush(stdout);
xmit_cmd("?", 2);
return;
case RESPONSE:
if (strcmp(parsed_response_buf, "Synchronized\r\n") == 0) {
//printf("response: sync'd\n");
state = SYNC_2;
event = BEGIN;
break;
}
if (strcmp(parsed_response_buf, "?") == 0) {
//printf("response: echo only\n");
retry++;
if (retry > 150) {
download_cancel(NO_SYNC_ERR); return;
}
event = RETRY;
usleep(30000);
break;
}
snprintf(buf, sizeof(buf), "Unexpected response to sync, \"%s\"",
parsed_response_buf);
download_cancel(buf); return;
case TIMEOUT:
if (retry < 100) {
retry++;
event = RETRY;
break;
}
download_cancel(NO_SYNC_ERR);
return;
}
break;
case SYNC_2:
switch(event) {
case BEGIN:
xmit_cmd("Synchronized\r\n", 3);
return;
case RESPONSE:
if (num_lines(parsed_response_buf) != 1) return;
if (strcmp(parsed_response_buf, "OK\r\n") == 0) {
state = SYNC_3;
event = BEGIN;
break;
} else {
snprintf(buf, sizeof(buf), "Unable to complete baud sync, %s",
parsed_response_buf);
download_cancel(buf); return;
}
return;
case TIMEOUT:
download_cancel("No response to complete baud sync"); return;
}
break;
case SYNC_3:
switch(event) {
case BEGIN:
if (sscanf(crystal, "%lf", &xtal) != 1) {
printf("\r\n");
download_cancel("Crystal frequency is required for 3rd step of baud rate sync");
return;
}
if (xtal < 10.0 || xtal > 25.0) {
printf("\r\n");
printf("Warning: crystal frequency out of range (10.0 to 25.0), continuing anyway! (hope you know what you're doing)\r\n");
}
snprintf(buf, sizeof(buf), "%d\r\n", (int)(xtal * 1000.0 + 0.5));
xmit_cmd(buf, 3);
return;
case RESPONSE:
if (num_lines(parsed_response_buf) != 1) return;
if (strcmp(parsed_response_buf, "OK\r\n") == 0) {
printf("Baud sync sucessful\r\n");
state = CHIP_ID;
event = BEGIN;
break;
} else {
snprintf(buf, sizeof(buf), "wrong response to crystal: %s",
parsed_response_buf);
download_cancel(buf); return;
}
return;
case TIMEOUT:
download_cancel("No response to crystal speed"); return;
}
break;
case CHIP_ID:
switch(event) {
case BEGIN:
xmit_cmd("J\r\n", 3);
return;
case RESPONSE:
if (num_lines(parsed_response_buf) < 2) return;
if (strncmp(parsed_response_buf, "0\r\n", 3) == 0) {
trim_crlf(parsed_response_buf+3);
for (chip=chip_info; chip->part_number != NULL; chip++) {
if (strcmp(parsed_response_buf+3, chip->id_string) == 0)
break;
}
if (chip->part_number == NULL) {
snprintf(buf, sizeof(buf), UNKNOWN_CHIP_ERROR,
parsed_response_buf+3);
download_cancel(buf);
break;
}
printf("Found chip: \"%s\"\r\n", chip->part_number);
//download_cancel("stop here, remove this later");
state = UNLOCK;
event = BEGIN;
break;
} else {
snprintf(buf, sizeof(buf), "wrong response to ID: %s",
parsed_response_buf);
download_cancel(buf); return;
}
return;
case TIMEOUT:
download_cancel("No response to unlock command"); return;
}
break;
case UNLOCK:
switch(event) {
case BEGIN:
xmit_cmd("U 23130\r\n", 3);
return;
case RESPONSE:
if (num_lines(parsed_response_buf) != 1) return;
if (strcmp(parsed_response_buf, "0\r\n") == 0) {
printf("Device Unlocked\r\n");
if (reboot_only) {
state = BOOT_SOFT;
} else {
state = BLANK_CHECK_SECTOR;
printf("Erasing....\r\n");
sector = 0;
}
event = BEGIN;
break;
} else {
snprintf(buf, sizeof(buf), "wrong response unlock: %s",
parsed_response_buf);
download_cancel(buf); return;
}
return;
case TIMEOUT:
download_cancel("No response to unlock command"); return;
}
break;
case BLANK_CHECK_SECTOR:
switch(event) {
case BEGIN:
if (sector >= chip->num_sector) {
printf("Programming....\r\n");
state = DOWNLOAD_CODE;
sector = sector_offset = 0;
event = BEGIN;
break;
}
printf(" Sector %2d: ", sector);
fflush(stdout);
if (!bytes_within_range(chip->layout[sector].address,
chip->layout[sector].address + chip->layout[sector].size - 1)) {
printf("not used\r\n");
sector++;
break;
}
if (sector == 0) {
// can't blank check sector 0, so always erase it
state = ERASE_PREPARE;
break;
}
snprintf(buf, sizeof(buf), "I %d %d\r\n", sector, sector);
xmit_cmd(buf, 5);
return;
case RESPONSE:
if (num_lines(parsed_response_buf) == 1 &&
strcmp(parsed_response_buf, "0\r\n") == 0) {
printf("already blank\r\n");
sector++;
event = BEGIN;
break;
} else {
if (num_lines(parsed_response_buf) < 3) return;
state = ERASE_PREPARE;
event = BEGIN;
break;
}
case TIMEOUT:
download_cancel("No response to blank check"); return;
}
break;
case ERASE_PREPARE:
switch(event) {
case BEGIN:
printf("prep, ");
fflush(stdout);
snprintf(buf, sizeof(buf), "P %d %d\r\n", sector, sector);
xmit_cmd(buf, 8);
return;
case RESPONSE:
if (num_lines(parsed_response_buf) != 1) return;
if (strcmp(parsed_response_buf, "0\r\n") == 0) {
state = ERASE_SECTOR;
event = BEGIN;
break;
} else {
download_cancel("Unable to prep for write"); return;
}
case TIMEOUT:
download_cancel("No response"); return;
}
break;
case ERASE_SECTOR:
switch(event) {
case BEGIN:
printf("erase... ");
fflush(stdout);
snprintf(buf, sizeof(buf), "E %d %d\r\n", sector, sector);
xmit_cmd(buf, 25);
return;
case RESPONSE:
if (num_lines(parsed_response_buf) < 1) return;
if (strcmp(parsed_response_buf, "0\r\n") == 0) {
printf("Ok\r\n");
sector++;
state = BLANK_CHECK_SECTOR;
event = BEGIN;
break;
} else {
printf("Error\r\n");
download_cancel("Unable to erase flash"); return;
}
case TIMEOUT:
download_cancel("No response"); return;
}
break;
case DOWNLOAD_CODE:
switch(event) {
case BEGIN:
if (sector >= chip->num_sector) {
state = BOOT_HARD;
sector = 0;
event = BEGIN;
break;
}
printf(" Sector %2d (0x%08X-0x%08X): ", sector,
chip->layout[sector].address + sector_offset,
chip->layout[sector].address + sector_offset + chip->chunk_size - 1);
fflush(stdout);
if (!bytes_within_range(chip->layout[sector].address + sector_offset,
chip->layout[sector].address + sector_offset + chip->chunk_size - 1)) {
printf("not used\r\n");
sector_offset += chip->chunk_size;
if (sector_offset >= chip->layout[sector].size) {
sector_offset = 0;
sector++;
}
break;
}
snprintf(buf, sizeof(buf), "W %d %d\r\n", chip->ram_addr, chip->chunk_size);
xmit_cmd(buf, 4);
return;
case RESPONSE:
if (num_lines(parsed_response_buf) != 1) return;
if (strcmp(parsed_response_buf, "0\r\n") == 0) {
state = XMIT_DATA;
printf("xmit");
current_addr = chip->layout[sector].address + sector_offset;
num_to_xmit = chip->chunk_size;
linecount = 0;
cksum = 0;
event = BEGIN;
break;
} else {
download_cancel("can't xmit to ram"); return;
}
case TIMEOUT:
download_cancel("No response"); return;
}
break;
case XMIT_DATA:
switch(event) {
case BEGIN:
n = num_to_xmit;
if (n > 45) n = 45;
get_ihex_data(current_addr, n, bytes);
cksum += sum(bytes, n);
uuencode(buf, bytes, n);
current_addr += n;
num_to_xmit -= n;
linecount++;
xmit_cmd(buf, 5);
write_serial_port("\r\n", 2);
return;
case RESPONSE:
if (num_lines(parsed_response_buf) != 1) return;
if (strcmp(parsed_response_buf, "\r\n") == 0) {
if (linecount >= 20 || num_to_xmit <= 0) {
state = XMIT_CKSUM;
}
event = BEGIN;
break;
} else {
download_cancel("data xmit did not echo"); return;
}
case TIMEOUT:
download_cancel("No response"); return;
}
break;
case XMIT_CKSUM:
switch(event) {
case BEGIN:
snprintf(buf, sizeof(buf), "%d\r\n", cksum);
xmit_cmd(buf, 3);
return;
case RESPONSE:
if (num_lines(parsed_response_buf) != 1) return;
if (strcmp(parsed_response_buf, "OK\r\n") == 0) {
if (num_to_xmit > 0) {
printf(".");
fflush(stdout);
state = XMIT_DATA;
event = BEGIN;
linecount = 0;
cksum = 0;
break;
}
state = WRITE_PREPARE;
event = BEGIN;
break;
} else {
download_cancel("bad checksum"); return;
}
case TIMEOUT:
download_cancel("No response"); return;
}
break;
case WRITE_PREPARE:
switch(event) {
case BEGIN:
printf("prep, ");
fflush(stdout);
snprintf(buf, sizeof(buf), "P %d %d\r\n", sector, sector);
xmit_cmd(buf, 5);
return;
case RESPONSE:
if (num_lines(parsed_response_buf) != 1) return;
if (strcmp(parsed_response_buf, "0\r\n") == 0) {
state = WRITE_SECTOR;
event = BEGIN;
break;
} else {
download_cancel("Unable to prep for write"); return;
}
case TIMEOUT:
download_cancel("No response"); return;
}
break;
case WRITE_SECTOR:
switch(event) {
case BEGIN:
printf("write, ");
fflush(stdout);
snprintf(buf, sizeof(buf), "C %d %d %d\r\n",
chip->layout[sector].address + sector_offset,
chip->ram_addr, chip->chunk_size);
xmit_cmd(buf, 5);
return;
case RESPONSE:
if (num_lines(parsed_response_buf) != 1) return;
if (strcmp(parsed_response_buf, "0\r\n") == 0) {
printf("Ok\r\n");
sector_offset += chip->chunk_size;
if (sector_offset >= chip->layout[sector].size) {
sector_offset = 0;
sector++;
}
state = DOWNLOAD_CODE;
event = BEGIN;
} else {
download_cancel("Unable to prep for write"); return;
}
break;
case TIMEOUT:
download_cancel("No response"); return;
}
break;
case BOOT_HARD:
// if (chip->bootprog) {
// state = BOOT_SOFT;
// break;
// } else {
printf("Booting (hardware reset)...\r\n\r\n");
hard_reset_to_user_code();
done_program(0);
return;
// }
case BOOT_SOFT:
switch(event) {
case BEGIN:
printf("Booting (soft jump)...\r\n");
printf("loading jump code\r\n");
// would be nice if we could simply jump to the user's code, but
// Philips didn't think of that. The interrupt vector table stays
// mapped to the bootloader, so jumping to zero only runs the
// bootloader again. Intead, we need to download a tiny ARM
// program that reconfigures the hardware and then jumps to zero.
//snprintf(buf, sizeof(buf), "G %d A\r\n", 0);
snprintf(buf, sizeof(buf), "W %d %d\r\n", chip->ram_addr, chip->bootprog[0] * 4);
xmit_cmd(buf, 4);
return;
case RESPONSE:
if (num_lines(parsed_response_buf) < 1) return;
if (strcmp(parsed_response_buf, "0\r\n") == 0) {
current_addr = 0;
num_to_xmit = chip->bootprog[0] * 4;
copy_boot_code_to_memory(chip);
linecount = 0;
cksum = 0;
state = BOOT_XMIT_DATA;
event = BEGIN;
} else {
download_cancel("can't xmit to ram"); return;
}
break;
case TIMEOUT:
download_cancel("No response"); return;
}
break;
case BOOT_XMIT_DATA:
switch(event) {
case BEGIN:
n = num_to_xmit;
if (n > 45) n = 45;
get_ihex_data(current_addr, n, bytes);
cksum += sum(bytes, n);
uuencode(buf, bytes, n);
current_addr += n;
num_to_xmit -= n;
linecount++;
//printf("send: %s\r\n", buf);
xmit_cmd(buf, 5);
write_serial_port("\r\n", 2);
return;
case RESPONSE:
if (num_lines(parsed_response_buf) != 1) return;
if (strcmp(parsed_response_buf, "\r\n") == 0) {
if (linecount >= 20 || num_to_xmit <= 0) {
state = BOOT_XMIT_CKSUM;
}
event = BEGIN;
break;
} else {
download_cancel("data xmit did not echo"); return;
}
case TIMEOUT:
download_cancel("No response"); return;
}
break;
case BOOT_XMIT_CKSUM:
switch(event) {
case BEGIN:
snprintf(buf, sizeof(buf), "%d\r\n", cksum);
//printf("send: %s", buf);
xmit_cmd(buf, 3);
return;
case RESPONSE:
if (num_lines(parsed_response_buf) != 1) return;
if (strcmp(parsed_response_buf, "OK\r\n") == 0) {
if (num_to_xmit > 0) {
printf(".");
fflush(stdout);
state = BOOT_XMIT_DATA;
event = BEGIN;
linecount = 0;
cksum = 0;
break;
}
state = BOOT_RUN_CODE;
event = BEGIN;
break;
} else {
download_cancel("bad checksum"); return;
}
case TIMEOUT:
download_cancel("No response"); return;
}
break;
case BOOT_RUN_CODE:
switch(event) {
case BEGIN:
printf("jumping now!\r\n");
snprintf(buf, sizeof(buf), "G %d A\r\n", chip->ram_addr);
xmit_cmd(buf, 4);
return;
case RESPONSE:
if (num_lines(parsed_response_buf) < 1) return;
if (strcmp(parsed_response_buf, "0\r\n") == 0) {
done_program(0);
return;
} else {
printf("response = %s", parsed_response_buf);
download_cancel("couldn't run program"); return;
}
break;
case TIMEOUT:
done_program(0);
return;
// Philips user name says it responds, but it does not.
// It seems to just immediately jump to the code without
// any "0" response.
//download_cancel("No response"); return;
}
break;
default:
snprintf(buf, sizeof(buf), "unknown state %d\r\n", state);
download_cancel(buf);
return;
}
}
}
void download_cancel(const char *mesg)
{
printf("\r\nDownload Canceled");
if (mesg && *mesg) printf(": %s", mesg);
printf("\r\n");
// need to do some cleanup for various states???
done_program(1);
}
/****************************************************************/
/* */
/* Transmit Commands to Bootloader */
/* */
/****************************************************************/
static void xmit_cmd(const char *cmd, int max_time)
{
int len;
if (cmd == NULL || *cmd == '\0') return;
len = strlen(cmd);
#ifdef PRINT_TX_RX_BYTES
printf("tx %d bytes: %s\n", len, cmd);
#endif
input_flush_serial_port();
write_serial_port(cmd, len);
snprintf(expected_echo_buf, sizeof(expected_echo_buf), "%s", cmd);
if (state == SYNC_1) {
// special case, baud sync doesn't echo
expected_echo_buf[0] = '\0';
}
expected_echo_ptr = expected_echo_buf;
parsed_response_ptr = parsed_response_buf;
response_timer = max_time;
}
/****************************************************************/
/* */
/* Handlers that respond to input */
/* */
/****************************************************************/
/*
Whenever the main gtk event loop detects more input has arrived from the
serial port, and we're in the process of a download, it calls here to
hand off the data. We're supposed to match it up to the echo buffer,
and then store it into the parsed response buffer and if it looks like
this might be a complete response, call download_main with a response
event.
*/
void download_rx_port(const unsigned char *buf, int num)
{
int i=0;
if (num <= 0) return;
// echo the data
//write(term_fd, buf, num);
#ifdef PRINT_TX_RX_BYTES
printf("rx %d bytes:", num);
for (i=0; i<num; i++) {
printf(" %02X", *(buf + i));
}
printf("\r\n");
#endif
// ignore extra incoming garbage we didn't expect
if (expected_echo_ptr == NULL) return;
// special case, echo of '?' during unsuccessful sync
if (state == SYNC_1 && num == 1 && buf[0] == '?') {
*parsed_response_ptr++ = '?';
*parsed_response_ptr = '\0';
response_timer = 0;
download_main(RESPONSE);
return;
}
// parse it
for (i=0; i<num; i++) {
// if we're still expecting the echo, gobble it up
if (*expected_echo_ptr) {
if (buf[i] != *expected_echo_ptr) {
#ifdef PRINT_TX_RX_BYTES
printf(" <echo_err> ");
#endif
// ignore incorrect echo (will timeout)
expected_echo_ptr = NULL;
return;
}
expected_echo_ptr++;
continue;
}
// store this into a parsed response buffer
*parsed_response_ptr++ = buf[i];
}
// if the last two characters of the response are "\r\n",
// then it's likely we've got a complete response.
*parsed_response_ptr = '\0';
if (parsed_response_ptr > parsed_response_buf + 1
&& *(parsed_response_ptr - 2) == '\r'
&& *(parsed_response_ptr - 1) == '\n') {
//response_timer = 0;
download_main(RESPONSE);
}
}
/*
During a download, this is supposed to get called at 100 Hz. Whenever
something is transmitted and we expect a response, the response_timer
is initialized to the maximum time we will wait.
*/
void download_timer(void)
{
if (response_timer > 0) {
response_timer--;
if (response_timer == 0) {
expected_echo_ptr = NULL;
download_main(TIMEOUT);
}
}
}
/*
During a download, all input the user types into the terminal is sent
to this function, instead of passing it to xterm for display
*/
void download_rx_term(const unsigned char *buf, int num)
{
// discard anything the user types into the terminal
// while we are in the middle of downloading. Maybe
// we should look for CTRL-C and abort??
}

View File

@ -0,0 +1,8 @@
extern int download_begin(char* file);
extern void soft_reboot_begin(void);
extern void hard_reset_to_bootloader(void);
extern void hard_reset_to_user_code(void);
extern void download_cancel(const char *mesg);
extern void download_rx_term(const unsigned char *buf, int num);
extern void download_rx_port(const unsigned char *buf, int num);
extern void download_timer(void);

387
board/msba2/tools/src/gui.c Normal file
View File

@ -0,0 +1,387 @@
/*
* LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
* Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
*
* 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.
*
* 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.
*
*/
/* If this code fails to build, please provide at least the following
* information when requesting (free) technical support.
*
* 1: Complete copy of all messages during the build.
* 2: Output of "gtk-config --version"
* 3: Output of "gtk-config --libs"
* 4: Output of "gtk-config --cflags"
* 5: Output of "uname -a"
* 6: Version of GTK installed... eg, type: ls -l /lib/libgtk*
* 7: Other info... which linux distribution, version, other software
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <gtk/gtk.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "gui.h"
#include "settings.h"
#include "serial.h"
#include "lpc2k_pgm.h"
#include "download.h"
static GtkWidget *firmware_label, *firmware_entry, *program_button;
static GtkWidget *port_label, *port_entry, *baud_label, *baud_combo;
static GtkWidget *crystal_label, *crystal_entry, *mhz_label;
static GtkWidget *reboot_button, *bootloader_button, *quit_button;
static GtkWidget *line1_hbox, *line2_hbox, *line3_hbox, *line4_hbox;
static GtkWidget *main_vbox, *main_window;
static int port_timeout=0;
static int baud_timeout=0;
static int download_in_progress=0;
gint do_quit(GtkWidget *widget, gpointer *data)
{
gtk_main_quit();
return FALSE;
}
gint do_program(GtkWidget *widget, gpointer *data)
{
if (download_in_progress) {
// error... not supposed to get here
gtk_widget_set_sensitive(program_button, FALSE);
return FALSE;
}
download_in_progress = 1;
gtk_widget_set_sensitive(program_button, FALSE);
gtk_widget_set_sensitive(reboot_button, FALSE);
gtk_widget_set_sensitive(bootloader_button, TRUE);
download_begin();
return FALSE;
}
int file_exists(const char *filename)
{
struct stat file_stats;
int r;
r = stat(filename, &file_stats);
if (r != 0) return 0;
if (!S_ISREG(file_stats.st_mode)) return 0;
return 1;
}
void done_program(int still_in_bootloader)
{
download_in_progress = 0;
if (file_exists(gtk_entry_get_text(GTK_ENTRY(firmware_entry)))) {
gtk_widget_set_sensitive(program_button, TRUE);
} else {
gtk_widget_set_sensitive(program_button, FALSE);
}
gtk_widget_set_sensitive(bootloader_button, TRUE);
gtk_widget_set_sensitive(reboot_button, TRUE);
}
gint do_reboot(GtkWidget *widget, gpointer *data)
{
if (download_in_progress) {
download_cancel(NULL);
gtk_widget_set_sensitive(program_button, FALSE);
gtk_widget_set_sensitive(reboot_button, FALSE);
gtk_widget_set_sensitive(bootloader_button, FALSE);
}
gtk_widget_set_sensitive(program_button, FALSE);
gtk_widget_set_sensitive(reboot_button, FALSE);
gtk_widget_set_sensitive(bootloader_button, FALSE);
hard_reset_to_user_code();
#if 0
download_in_progress = 1;
soft_reboot_begin();
#endif
if (file_exists(gtk_entry_get_text(GTK_ENTRY(firmware_entry)))) {
gtk_widget_set_sensitive(program_button, TRUE);
} else {
gtk_widget_set_sensitive(program_button, FALSE);
}
gtk_widget_set_sensitive(bootloader_button, TRUE);
return FALSE;
}
gint do_bootloader(GtkWidget *widget, gpointer *data)
{
if (download_in_progress) {
download_cancel(NULL);
gtk_widget_set_sensitive(program_button, FALSE);
gtk_widget_set_sensitive(reboot_button, FALSE);
gtk_widget_set_sensitive(bootloader_button, FALSE);
}
hard_reset_to_bootloader();
if (file_exists(gtk_entry_get_text(GTK_ENTRY(firmware_entry)))) {
gtk_widget_set_sensitive(program_button, TRUE);
} else {
gtk_widget_set_sensitive(program_button, FALSE);
}
gtk_widget_set_sensitive(reboot_button, TRUE);
gtk_widget_set_sensitive(bootloader_button, TRUE);
return FALSE;
}
gint do_new_port(GtkWidget *widget, gpointer *data)
{
port_timeout = 12;
return FALSE;
}
gint do_new_baud(GtkWidget *widget, gpointer *data)
{
baud_timeout = 7;
return FALSE;
}
gint do_new_file(GtkWidget *widget, gpointer *data)
{
const char *filename;
filename = gtk_entry_get_text(GTK_ENTRY(firmware_entry));
if (file_exists(filename)) {
new_file_setting(filename);
if (download_in_progress) {
gtk_widget_set_sensitive(program_button, FALSE);
} else {
gtk_widget_set_sensitive(program_button, TRUE);
}
} else {
gtk_widget_set_sensitive(program_button, FALSE);
}
return FALSE;
}
gint do_new_crystal(GtkWidget *widget, gpointer *data)
{
const char *xtal;
xtal = gtk_entry_get_text(GTK_ENTRY(crystal_entry));
new_crystal_setting(xtal);
return FALSE;
}
gint do_timer(gpointer data)
{
if (port_timeout && --port_timeout == 0) {
open_serial_port(gtk_entry_get_text(GTK_ENTRY(port_entry)));
}
if (baud_timeout && --baud_timeout == 0) {
change_baud(gtk_entry_get_text(GTK_ENTRY(
GTK_COMBO(baud_combo)->entry)));
}
if (download_in_progress) {
download_timer();
}
return TRUE;
}
void do_term_input(gpointer data, int fd, GdkInputCondition cond)
{
char buf[256];
int num, flags;
flags = fcntl(term_fd, F_GETFL);
fcntl(term_fd, F_SETFL, flags | O_NONBLOCK);
num = read(term_fd, buf, sizeof(buf));
fcntl(term_fd, F_SETFL, flags);
if (num > 0) {
if (download_in_progress) {
download_rx_term(buf, num);
} else {
write_serial_port(buf, num);
}
}
}
void do_port_input(gpointer data, int fd, GdkInputCondition cond)
{
char buf[256];
int num;
num = read_serial_port_nb((unsigned char *)buf, sizeof(buf));
if (num > 0) {
if (download_in_progress) {
download_rx_port(buf, num);
} else {
write(term_fd, buf, num);
}
}
}
void run_gui(void)
{
gtk_signal_connect(GTK_OBJECT(main_window), "delete_event",
GTK_SIGNAL_FUNC(do_quit), NULL);
gtk_signal_connect(GTK_OBJECT(quit_button), "pressed",
GTK_SIGNAL_FUNC(do_quit), NULL);
gtk_signal_connect(GTK_OBJECT(port_entry), "changed",
GTK_SIGNAL_FUNC(do_new_port), NULL);
gtk_signal_connect(GTK_OBJECT(GTK_COMBO(baud_combo)->entry), "changed",
GTK_SIGNAL_FUNC(do_new_baud), NULL);
gtk_signal_connect(GTK_OBJECT(firmware_entry), "changed",
GTK_SIGNAL_FUNC(do_new_file), NULL);
gtk_signal_connect(GTK_OBJECT(crystal_entry), "changed",
GTK_SIGNAL_FUNC(do_new_crystal), NULL);
gtk_signal_connect(GTK_OBJECT(program_button), "pressed",
GTK_SIGNAL_FUNC(do_program), NULL);
gtk_signal_connect(GTK_OBJECT(reboot_button), "pressed",
GTK_SIGNAL_FUNC(do_reboot), NULL);
gtk_signal_connect(GTK_OBJECT(bootloader_button), "pressed",
GTK_SIGNAL_FUNC(do_bootloader), NULL);
gtk_timeout_add(100, do_timer, NULL);
gdk_input_add(term_fd, GDK_INPUT_READ, do_term_input, NULL);
gdk_input_add(serial_port_fd(), GDK_INPUT_READ, do_port_input, NULL);
gtk_main();
}
void create_window(int *argc, char ***argv)
{
GList *gtk_baud_list=NULL;
int i;
gtk_init(argc, argv);
firmware_label = gtk_label_new("Firmware:");
gtk_label_set_justify(GTK_LABEL(firmware_label), GTK_JUSTIFY_RIGHT);
gtk_widget_show(firmware_label);
firmware_entry = gtk_entry_new();
gtk_widget_set_usize(firmware_entry, 110, 0);
gtk_entry_set_text(GTK_ENTRY(firmware_entry), file_setting());
gtk_widget_show(firmware_entry);
program_button = gtk_button_new_with_label("Program Now");
if (file_exists(file_setting())) {
gtk_widget_set_sensitive(program_button, TRUE);
} else {
gtk_widget_set_sensitive(program_button, FALSE);
}
gtk_widget_show(program_button);
line1_hbox = gtk_hbox_new(FALSE, 2);
gtk_box_pack_start(GTK_BOX(line1_hbox), firmware_label, FALSE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(line1_hbox), firmware_entry, TRUE, TRUE, 2);
gtk_box_pack_start(GTK_BOX(line1_hbox), program_button, FALSE, FALSE, 2);
gtk_widget_show(line1_hbox);
port_label = gtk_label_new("Port:");
gtk_label_set_justify(GTK_LABEL(port_label), GTK_JUSTIFY_RIGHT);
gtk_widget_show(port_label);
port_entry = gtk_entry_new();
gtk_widget_set_usize(port_entry, 80, 0);
gtk_entry_set_text(GTK_ENTRY(port_entry), port_setting());
open_serial_port(port_setting());
gtk_widget_show(port_entry);
baud_label = gtk_label_new("Baud:");
gtk_label_set_justify(GTK_LABEL(baud_label), GTK_JUSTIFY_RIGHT);
gtk_widget_show(baud_label);
baud_combo = gtk_combo_new();
for (i=0; baud_list[i] != NULL; i++) {
gtk_baud_list = g_list_append(gtk_baud_list, baud_list[i]);
}
gtk_combo_set_popdown_strings(GTK_COMBO(baud_combo), gtk_baud_list);
gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(baud_combo)->entry), FALSE);
gtk_widget_set_usize(baud_combo, 75, 0);
for (i=0; baud_list[i] != NULL; i++) {
if (strcmp(baud_list[i], baud_setting()) == 0) {
gtk_list_select_item(GTK_LIST(GTK_COMBO(baud_combo)->list), i);
break;
}
}
gtk_widget_show(baud_combo);
line2_hbox = gtk_hbox_new(FALSE, 2);
gtk_box_pack_start(GTK_BOX(line2_hbox), port_label, FALSE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(line2_hbox), port_entry, TRUE, TRUE, 2);
gtk_box_pack_start(GTK_BOX(line2_hbox), baud_label, FALSE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(line2_hbox), baud_combo, FALSE, FALSE, 2);
gtk_widget_show(line2_hbox);
crystal_label = gtk_label_new("Crystal:");
gtk_label_set_justify(GTK_LABEL(crystal_label), GTK_JUSTIFY_RIGHT);
gtk_widget_show(crystal_label);
crystal_entry = gtk_entry_new();
gtk_widget_set_usize(crystal_entry, 80, 0);
gtk_entry_set_text(GTK_ENTRY(crystal_entry), crystal_setting());
gtk_widget_show(crystal_entry);
mhz_label = gtk_label_new("(MHz)");
gtk_label_set_justify(GTK_LABEL(mhz_label), GTK_JUSTIFY_LEFT);
gtk_widget_show(mhz_label);
line3_hbox = gtk_hbox_new(FALSE, 2);
gtk_box_pack_start(GTK_BOX(line3_hbox), crystal_label, FALSE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(line3_hbox), crystal_entry, TRUE, TRUE, 2);
gtk_box_pack_start(GTK_BOX(line3_hbox), mhz_label, FALSE, FALSE, 2);
gtk_widget_show(line3_hbox);
reboot_button = gtk_button_new_with_label("Reboot");
gtk_widget_set_sensitive(reboot_button, TRUE);
gtk_widget_show(reboot_button);
bootloader_button = gtk_button_new_with_label("Booloader");
gtk_widget_show(bootloader_button);
quit_button = gtk_button_new_with_label("Quit");
gtk_widget_show(quit_button);
line4_hbox = gtk_hbox_new(TRUE, 2);
gtk_box_pack_start(GTK_BOX(line4_hbox), reboot_button, TRUE, TRUE, 2);
gtk_box_pack_start(GTK_BOX(line4_hbox), bootloader_button, TRUE, TRUE, 2);
gtk_box_pack_start(GTK_BOX(line4_hbox), quit_button, TRUE, TRUE, 2);
gtk_widget_show(line4_hbox);
main_vbox = gtk_vbox_new(FALSE, 2);
gtk_box_pack_start(GTK_BOX(main_vbox), line1_hbox, TRUE, TRUE, 2);
gtk_box_pack_start(GTK_BOX(main_vbox), line2_hbox, TRUE, TRUE, 2);
gtk_box_pack_start(GTK_BOX(main_vbox), line3_hbox, TRUE, TRUE, 2);
gtk_box_pack_start(GTK_BOX(main_vbox), line4_hbox, TRUE, TRUE, 2);
gtk_widget_show(main_vbox);
main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_container_add(GTK_CONTAINER(main_window), main_vbox);
gtk_widget_show(main_window);
}

View File

@ -0,0 +1,3 @@
extern void create_window(int *argc, char ***argv);
extern void run_gui(void);
extern void done_program(int still_in_bootloader);

View File

@ -0,0 +1,229 @@
/*
* LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
* Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
*
* 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.
*
* 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.
*
*/
/* If this code fails to build, please provide at least the following
* information when requesting (free) technical support.
*
* 1: Complete copy of all messages during the build.
* 2: Output of "gtk-config --version"
* 3: Output of "gtk-config --libs"
* 4: Output of "gtk-config --cflags"
* 5: Output of "uname -a"
* 6: Version of GTK installed... eg, type: ls -l /lib/libgtk*
* 7: Other info... which linux distribution, version, other software
*/
#include <stdio.h>
#include <string.h>
// the maximum flash image size we can support
// chips with larger memory may be used, but only this
// much intel-hex data can be loaded into memory!
#define MAX_MEMORY_SIZE 0x80000
#include "ihex.h"
static unsigned char firmware_image[MAX_MEMORY_SIZE];
static unsigned char firmware_mask[MAX_MEMORY_SIZE];
static int end_record_seen=0;
static int byte_count;
static unsigned int extended_addr = 0;
static int parse_hex_line(char *line);
/****************************************************************/
/* */
/* Read Intel Hex File */
/* */
/****************************************************************/
int read_intel_hex(const char *filename)
{
FILE *fp;
int i, lineno=0;
char buf[1024];
byte_count = 0;
end_record_seen = 0;
for (i=0; i<MAX_MEMORY_SIZE; i++) {
firmware_image[i] = 0xFF;
firmware_mask[i] = 0;
}
extended_addr = 0;
fp = fopen(filename, "r");
if (fp == NULL) {
printf("Unable to read file %s\n", filename);
return -1;
}
while (!feof(fp)) {
*buf = '\0';
fgets(buf, sizeof(buf), fp);
lineno++;
if (*buf) {
if (parse_hex_line(buf) == 0) {
printf("Warning, parse error line %d\n", lineno);
return -2;
}
}
if (end_record_seen) break;
if (feof(stdin)) break;
}
fclose(fp);
return byte_count;
}
/* from ihex.c, at http://www.pjrc.com/tech/8051/pm2_docs/intel-hex.html */
/* parses a line of intel hex code, stores the data in bytes[] */
/* and the beginning address in addr, and returns a 1 if the */
/* line was valid, or a 0 if an error occured. The variable */
/* num gets the number of bytes that were stored into bytes[] */
int
parse_hex_line(char *line)
{
int addr, code, num;
int sum, len, cksum, i;
char *ptr;
num = 0;
if (line[0] != ':') return 0;
if (strlen(line) < 11) return 0;
ptr = line+1;
if (!sscanf(ptr, "%02x", &len)) return 0;
ptr += 2;
if (strlen(line) < (11 + (len * 2)) ) return 0;
if (!sscanf(ptr, "%04x", &addr)) return 0;
ptr += 4;
/* printf("Line: length=%d Addr=%d\n", len, addr); */
if (!sscanf(ptr, "%02x", &code)) return 0;
if (addr + extended_addr + len >= MAX_MEMORY_SIZE) return 0;
ptr += 2;
sum = (len & 255) + ((addr >> 8) & 255) + (addr & 255) + (code & 255);
if (code != 0) {
if (code == 1) {
end_record_seen = 1;
return 1;
}
if (code == 2 && len == 2) {
if (!sscanf(ptr, "%04x", &i)) return 1;
ptr += 4;
sum += ((i >> 8) & 255) + (i & 255);
if (!sscanf(ptr, "%02x", &cksum)) return 1;
if (((sum & 255) + (cksum & 255)) & 255) return 1;
extended_addr = i << 4;
//printf("ext addr = %05X\n", extended_addr);
}
if (code == 4 && len == 2) {
if (!sscanf(ptr, "%04x", &i)) return 1;
ptr += 4;
sum += ((i >> 8) & 255) + (i & 255);
if (!sscanf(ptr, "%02x", &cksum)) return 1;
if (((sum & 255) + (cksum & 255)) & 255) return 1;
extended_addr = i << 16;
//printf("ext addr = %08X\n", extended_addr);
}
return 1; // non-data line
}
byte_count += len;
while (num != len) {
if (sscanf(ptr, "%02x", &i) != 1) return 0;
i &= 255;
firmware_image[addr + extended_addr + num] = i;
firmware_mask[addr + extended_addr + num] = 1;
ptr += 2;
sum += i;
(num)++;
if (num >= 256) return 0;
}
if (!sscanf(ptr, "%02x", &cksum)) return 0;
if (((sum & 255) + (cksum & 255)) & 255) return 0; /* checksum error */
return 1;
}
int bytes_within_range(int begin, int end)
{
int i;
if (begin < 0 || begin >= MAX_MEMORY_SIZE ||
end < 0 || end >= MAX_MEMORY_SIZE) {
return 0;
}
for (i=begin; i<=end; i++) {
if (firmware_mask[i]) return 1;
}
return 0;
}
void get_ihex_data(int addr, int len, unsigned char *bytes)
{
int i;
if (addr < 0 || len < 0 || addr + len >= MAX_MEMORY_SIZE) {
for (i=0; i<len; i++) {
bytes[i] = 255;
}
return;
}
for (i=0; i<len; i++) {
if (firmware_mask[addr]) {
bytes[i] = firmware_image[addr];
} else {
bytes[i] = 255;
}
addr++;
}
}
void put_ihex_data(int addr, int len, const unsigned char *bytes)
{
int i;
if (addr < 0 || len < 0 || addr + len >= MAX_MEMORY_SIZE) {
return;
}
for (i=0; i<len; i++) {
firmware_image[addr] = bytes[i];
firmware_mask[addr] = 1;
addr++;
}
}

View File

@ -0,0 +1,7 @@
extern int read_intel_hex(const char *filename);
extern int bytes_within_range(int begin, int end);
extern void get_ihex_data(int addr, int len, unsigned char *bytes);
extern void put_ihex_data(int addr, int len, const unsigned char *bytes);

View File

@ -0,0 +1,98 @@
/*
* LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
* Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
*
* 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.
*
* 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.
*
*/
/* If this code fails to build, please provide at least the following
* information when requesting (free) technical support.
*
* 1: Complete copy of all messages during the build.
* 2: Output of "gtk-config --version"
* 3: Output of "gtk-config --libs"
* 4: Output of "gtk-config --cflags"
* 5: Output of "uname -a"
* 6: Version of GTK installed... eg, type: ls -l /lib/libgtk*
* 7: Other info... which linux distribution, version, other software
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/ioctl.h>
#include "lpc2k_pgm.h"
#include "serial.h"
#include "download.h"
int programming_done = 0;
int done_program(int i) {
printf("Programming done.\n");
programming_done = 1;
return 0;
}
void handle_port_input() {
unsigned char buf[256];
int num;
num = read_serial_port(buf, sizeof(buf));
if (num > 0) {
download_rx_port(buf, num);
}
}
void usage() {
printf("usage: lpc2k_pgm <port> <ihex-file>\n");
}
int main(int argc, char **argv)
{
if (argc < 3 ) {
usage();
exit(1);
}
char* port_name = argv[1];
char* file_name = argv[2];
sleep(1);
if (open_serial_port(port_name) < 0) {
return(1);
}
if (!download_begin(file_name)) {
return 1;
}
while (!programming_done) {
handle_port_input();
}
close_serial_port();
return 0;
}

View File

@ -0,0 +1,12 @@
#ifndef LPC2K_PGM
#define LPC2K_PGM
/* gets a name like "115200", sets baudrate accordingly. */
void change_baud(const char *baud_name);
/* called before/after using serial device, used to have terminal
* close the device.
*/
void signal_terminal();
#endif // LPC2K_PGM

View File

@ -0,0 +1,135 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <signal.h>
#include "serial.h"
#include "pthread.h"
#include "download.h"
int tty_fd;
int stopped = 0;
char* port_name = "/dev/ttyUSB1";
pthread_t serial_reader;
void* serial_reader_func(void* arg) {
unsigned char buf[255];
while(1) {
int n = read_serial_port(buf, sizeof(buf));
if (n > 0) {
write(tty_fd, buf, n);
}
}
}
int init() {
int result = open_serial_port(port_name);
pthread_create(&serial_reader, NULL, serial_reader_func, NULL);
hard_reset_to_user_code();
return result;
}
void sig_handler(int signal) {
if (signal == SIGUSR1) {
if (stopped) {
stopped = 0;
printf("\nSignal received, opening port.\r\n");
if (init() < 0) {
printf("Cannot open port.\r\n");
exit(1);
}
}
} else if (signal == SIGUSR2) {
if (!stopped) {
stopped = 1;
printf("\nSignal received, closing port. \r\n");
pthread_cancel(serial_reader);
close_serial_port();
}
}
}
int open_tty(void)
{
int r, fd;
struct termios term_setting;
fd = open("/dev/tty", O_RDWR);
if (fd < 0) return -1;
r = tcgetattr(fd, &term_setting);
if (r != 0) return -2;
term_setting.c_oflag |= ( ONLRET );
term_setting.c_iflag |= (IGNBRK | IGNPAR);
term_setting.c_iflag &= ~(ISTRIP | BRKINT);
term_setting.c_lflag &= ~(ICANON | ISIG | ECHO);
term_setting.c_cflag |= CREAD;
term_setting.c_cc[VMIN] = 1;
term_setting.c_cc[VTIME] = 1;
r = tcsetattr(fd, TCSANOW, &term_setting);
if (r != 0) return -3;
return fd;
}
void install_sighandler() {
struct sigaction action;
sigemptyset (&action.sa_mask);
sigaddset( &action.sa_mask, SIGUSR1 );
sigaddset( &action.sa_mask, SIGUSR2 );
action.sa_flags = 0;
action.sa_handler = sig_handler;
sigaction(SIGUSR1, &action, NULL);
sigaction(SIGUSR2, &action, NULL);
}
int main(int argc, char** argv) {
if (argc == 2) {
port_name = argv[1];
}
printf("Using %s as serial device.\n", port_name);
char ttybuf[255];
tty_fd = open_tty();
if (tty_fd < 0) {
printf("Error opening terminal.\n");
return(1);
}
install_sighandler();
if (init() < 0) {
printf("Cannot open port.\r\n");
exit(1);
}
while (1) {
int n = read(tty_fd, ttybuf, sizeof(ttybuf));
int i;
/* check for 0x3 (ctrl-c), clean exit */
for (i = 0; i < n; i++) {
if (ttybuf[i] == 0x3) {
if (i > 0) {
write_serial_port(ttybuf, i);
}
close_serial_port();
system("tset -c");
return 0;
}
}
write_serial_port(ttybuf,n);
}
close_serial_port();
return 0;
}

View File

@ -0,0 +1,350 @@
/*
* LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
* Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
*
* 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.
*
* 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.
*
*/
/* If this code fails to build, please provide at least the following
* information when requesting (free) technical support.
*
* 1: Complete copy of all messages during the build.
* 2: Output of "gtk-config --version"
* 3: Output of "gtk-config --libs"
* 4: Output of "gtk-config --cflags"
* 5: Output of "uname -a"
* 6: Version of GTK installed... eg, type: ls -l /lib/libgtk*
* 7: Other info... which linux distribution, version, other software
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/ioctl.h>
#ifdef LINUX
#include <linux/serial.h>
#endif
#include "serial.h"
static int port_fd=-1;
static tcflag_t baud_name_to_flags(const char *baud_name);
static void report_open_error(const char *filename, int err);
char* baud_rate = "115200";
int open_serial_port(const char *port_name)
{
int r;
if (port_fd >= 0) {
close(port_fd);
}
port_fd = open(port_name, O_RDWR);
if (port_fd < 0) {
report_open_error(port_name, errno);
return -1;
}
r = set_baud(baud_rate);
if (r == 0) {
printf("Port \"%s\" opened at %s baud\r\n",
port_name, baud_rate);
} else {
printf("Port \"%s\" opened, unable to set baud to %s\r\n",
port_name, baud_rate);
}
#ifdef LINUX
{
struct serial_struct kernel_serial_settings;
/* attempt to set low latency mode, but don't worry if we can't */
r = ioctl(port_fd, TIOCGSERIAL, &kernel_serial_settings);
if (r < 0) return 0;
kernel_serial_settings.flags |= ASYNC_LOW_LATENCY;
ioctl(port_fd, TIOCSSERIAL, &kernel_serial_settings);
}
#endif
return 0;
}
/* if the port can't be opened, try to print as much info as
* possible, so the problem can be resolved (usually permissions)
*/
static void report_open_error(const char *filename, int err)
{
struct stat info;
uid_t my_uid;
gid_t my_gid;
char my_uname[64], my_gname[64], file_uname[64], file_gname[64];
struct passwd *p;
struct group *g;
mode_t perm;
int r, perm_ok=0;
printf("\r\n");
printf("Unable to open \"%s\"\r\n", filename);
if (err == EACCES) {
printf("You don't have permission to access %s\r\n", filename);
}
//printf("Attemping to find more information about %s....\r\n", filename);
r = stat(filename, &info);
if (r < 0) {
if (errno == ENOENT) {
printf("file %s does not exist\r\n", filename);
} else if (errno == ELOOP) {
printf("too many symbolic links\r\n");
} else if (errno == EACCES) {
printf("permission denied to get file status\r\n");
} else {
printf("Unable to get file status, err%d\r\n", errno);
}
return;
}
my_uid = getuid();
my_gid = getgid();
p = getpwuid(my_uid);
if (p) {
snprintf(my_uname, sizeof(my_uname),
"\"%s\" (gid=%d)", p->pw_name, (int)my_uid);
} else {
snprintf(my_uname, sizeof(my_uname),
"(gid=%d)", (int)my_uid);
}
p = getpwuid(info.st_uid);
if (p) {
snprintf(file_uname, sizeof(file_uname),
"\"%s\" (uid=%d)", p->pw_name, (int)info.st_uid);
} else {
snprintf(file_uname, sizeof(file_uname),
"(uid=%d)", (int)info.st_uid);
}
g = getgrgid(my_gid);
if (g) {
snprintf(my_gname, sizeof(my_gname),
"\"%s\" (gid=%d)", g->gr_name, (int)my_gid);
} else {
snprintf(my_gname, sizeof(my_gname),
"(gid=%d)", (int)my_gid);
}
g = getgrgid(info.st_gid);
if (g) {
snprintf(file_gname, sizeof(file_gname),
"\"%s\" (uid=%d)", g->gr_name, (int)info.st_gid);
} else {
snprintf(file_gname, sizeof(file_gname),
"(uid=%d)", (int)info.st_gid);
}
/* printf("%s is owned by: user %s, group %s\r\n",
filename, file_uname, file_gname); */
perm = info.st_mode;
if ((perm & S_IROTH) && (perm & S_IWOTH)) {
printf("%s has read/write permission for everybody\r\n",
filename);
} else {
printf("%s is not read/write for everybody, so\r\n", filename);
printf(" you must match either user or group permission\r\n");
if ((perm & S_IRUSR) && (perm & S_IWUSR)) {
printf("%s has read/write permission for user %s\r\n",
filename, file_uname);
perm_ok = 1;
}
if ((perm & S_IRGRP) && (perm & S_IWGRP)) {
printf("%s has read/write permission for group %s\r\n",
filename, file_gname);
perm_ok = 1;
}
if (perm_ok == 0) {
printf("%s does not read/write permission for user or group!\r\n",
filename);
} else {
printf("Your access privs: user %s, group %s\r\n",
my_uname, my_gname);
}
}
printf("\r\n");
}
int write_serial_port(const void *buf, int num)
{
return(write(port_fd, buf, num));
}
void input_flush_serial_port(void)
{
tcflush(port_fd, TCIFLUSH);
}
int read_serial_port_nb(unsigned char *buf, int bufsize)
{
int num, flags;
flags = fcntl(port_fd, F_GETFL);
fcntl(port_fd, F_SETFL, flags | O_NONBLOCK);
num = read(port_fd, buf, bufsize);
fcntl(port_fd, F_SETFL, flags);
return num;
}
int read_serial_port(unsigned char *buf, int bufsize)
{
int num;
num = read(port_fd, buf, bufsize);
return num;
}
void send_break_signal(void)
{
tcsendbreak(port_fd, 0);
}
void close_serial_port(void)
{
if (port_fd >= 0) {
close(port_fd);
port_fd = -1;
}
}
tcflag_t baud_name_to_flags(const char *baud_name)
{
if (strcmp(baud_name, "230400") == 0) return B230400;
if (strcmp(baud_name, "115200") == 0) return B115200;
if (strcmp(baud_name, "57600") == 0) return B57600;
if (strcmp(baud_name, "38400") == 0) return B38400;
if (strcmp(baud_name, "19200") == 0) return B19200;
if (strcmp(baud_name, "9600") == 0) return B9600;
if (strcmp(baud_name, "4800") == 0) return B4800;
if (strcmp(baud_name, "2400") == 0) return B2400;
if (strcmp(baud_name, "1200") == 0) return B1200;
if (strcmp(baud_name, "300") == 0) return B300;
return B0;
}
int set_baud(const char *baud_name)
{
struct termios port_setting;
tcflag_t baud;
int r;
if (port_fd < 0) return -1;
baud = baud_name_to_flags(baud_name);
if (baud == B0) return -2;
r = tcgetattr(port_fd, &port_setting);
if (r != 0) return -3;
//port_setting.c_iflag = IGNBRK | IGNPAR | IXANY | IXON;
port_setting.c_iflag = IGNBRK | IGNPAR;
port_setting.c_cflag = baud | CS8 | CREAD | HUPCL | CLOCAL;
port_setting.c_oflag = 0;
port_setting.c_lflag = 0;
r = tcsetattr(port_fd, TCSAFLUSH, &port_setting);
if (r != 0) return -4;
return 0;
}
// Normally this should never be used... except to pass the port
// file descriptor to the GTK event monitoring loop. All other
// use of the serial port is supposed to happen in the file.
int serial_port_fd(void)
{
return port_fd;
}
void set_rts(int val)
{
int flags;
int result;
result = ioctl(port_fd, TIOCMGET, &flags);
if( result == -1 ) {
printf("Error %i while reading port io flags\n", errno);
return;
}
if (val) {
flags |= TIOCM_RTS;
} else {
flags &= ~(TIOCM_RTS);
}
result = ioctl(port_fd, TIOCMSET, &flags);
if( result == -1 )
printf("Error %i while setting port io flags\n", errno);
}
void set_dtr(int val)
{
int flags;
int result;
result = ioctl(port_fd, TIOCMGET, &flags);
if( result == -1 ) {
printf("Error %i while reading port io flags\n", errno);
return;
}
if (val) {
flags |= TIOCM_DTR;
} else {
flags &= ~(TIOCM_DTR);
}
result = ioctl(port_fd, TIOCMSET, &flags);
if( result == -1 )
printf("Error %i while setting port io flags\n", errno);
}

View File

@ -0,0 +1,19 @@
#ifndef SERIAL_H
#define SERIAL_H
extern char* baud_rate;
int open_serial_port(const char *port_name);
int write_serial_port(const void *buf, int num);
void input_flush_serial_port(void);
int read_serial_port_nb(unsigned char *buf, int bufsize);
int read_serial_port(unsigned char *buf, int bufsize);
void close_serial_port(void);
void send_break_signal(void);
int set_baud(const char *baud_name);
int serial_port_fd(void);
void set_rts(int val);
void set_dtr(int val);
void change_baud(const char *baud_name);
#endif // SERIAL_H

View File

@ -0,0 +1,172 @@
/*
* LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
* Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
*
* 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.
*
* 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.
*
*/
/* If this code fails to build, please provide at least the following
* information when requesting (free) technical support.
*
* 1: Complete copy of all messages during the build.
* 2: Output of "gtk-config --version"
* 3: Output of "gtk-config --libs"
* 4: Output of "gtk-config --cflags"
* 5: Output of "uname -a"
* 6: Version of GTK installed... eg, type: ls -l /lib/libgtk*
* 7: Other info... which linux distribution, version, other software
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "settings.h"
#define DEFAULT_FILE ""
#define DEFAULT_PORT "/dev/ttyS0"
#define DEFAULT_BAUD "115200"
#define DEFAULT_CRYSTAL "16"
char *baud_list[]={"115200", "57600", "38400",
"19200", "9600", "4800", "2400", "1200", "300", NULL};
static char file[128]={DEFAULT_FILE};
static char port[64]={DEFAULT_PORT};
static char baud[64]={DEFAULT_BAUD};
static char crystal[64]={DEFAULT_CRYSTAL};
static char settings_file[256]={'\0'};
void init_settings(void)
{
const char *home_dir;
FILE *fp;
char buf[1024], *p, *q;
home_dir = getenv("HOME");
if (home_dir && *home_dir) {
snprintf(settings_file, sizeof(settings_file),
"%s/.lpc2k_pgm", home_dir);
fp = fopen(settings_file, "r");
if (fp == NULL) return;
while (!feof(fp)) {
buf[0] = '\0';
fgets(buf, sizeof(buf), fp);
if (strncmp(buf, "file:", 5) == 0) {
for (p=buf+5; isspace(*p); p++) ;
q = rindex(p, '\n'); if (q) *q = '\0';
q = rindex(p, '\r'); if (q) *q = '\0';
snprintf(file, sizeof(file), "%s", p);
}
if (strncmp(buf, "port:", 5) == 0) {
for (p=buf+5; isspace(*p); p++) ;
q = rindex(p, '\n'); if (q) *q = '\0';
q = rindex(p, '\r'); if (q) *q = '\0';
snprintf(port, sizeof(port), "%s", p);
}
if (strncmp(buf, "baud:", 5) == 0) {
for (p=buf+5; isspace(*p); p++) ;
q = rindex(p, '\n'); if (q) *q = '\0';
q = rindex(p, '\r'); if (q) *q = '\0';
snprintf(baud, sizeof(baud), "%s", p);
}
if (strncmp(buf, "xtal:", 5) == 0) {
for (p=buf+5; isspace(*p); p++) ;
q = rindex(p, '\n'); if (q) *q = '\0';
q = rindex(p, '\r'); if (q) *q = '\0';
snprintf(crystal, sizeof(crystal), "%s", p);
}
}
fclose(fp);
}
}
void write_settings_file(void)
{
FILE *fp;
if (settings_file[0] == '\0') return;
fp = fopen(settings_file, "w");
if (fp == NULL) return;
fprintf(fp, "file: %s\n", file);
fprintf(fp, "port: %s\n", port);
fprintf(fp, "baud: %s\n", baud);
fprintf(fp, "xtal: %s\n", crystal);
fflush(fp);
fclose(fp);
}
const char * file_setting(void)
{
return file;
}
const char * port_setting(void)
{
return port;
}
const char * baud_setting(void)
{
return baud;
}
const char * crystal_setting(void)
{
return crystal;
}
void new_file_setting(const char *new_file)
{
if (strcmp(file, new_file)) {
snprintf(file, sizeof(file), "%s", new_file);
write_settings_file();
}
}
void new_port_setting(const char *new_port)
{
if (strcmp(port, new_port)) {
snprintf(port, sizeof(port), "%s", new_port);
write_settings_file();
}
}
void new_baud_setting(const char *new_baud)
{
if (strcmp(baud, new_baud)) {
snprintf(baud, sizeof(baud), "%s", new_baud);
write_settings_file();
}
}
void new_crystal_setting(const char *new_xtal)
{
if (strcmp(crystal, new_xtal)) {
snprintf(crystal, sizeof(crystal), "%s", new_xtal);
write_settings_file();
}
}

View File

@ -0,0 +1,12 @@
extern void init_settings(void);
extern const char * file_setting(void);
extern const char * port_setting(void);
extern const char * baud_setting(void);
extern const char * crystal_setting(void);
extern void new_file_setting(const char *new_file);
extern void new_port_setting(const char *new_port);
extern void new_baud_setting(const char *new_baud);
extern void new_crystal_setting(const char *new_xtal);
extern char *baud_list[];

View File

@ -0,0 +1,98 @@
/*
* LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
* Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
*
* 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.
*
* 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.
*
*/
/* If this code fails to build, please provide at least the following
* information when requesting (free) technical support.
*
* 1: Complete copy of all messages during the build.
* 2: Output of "gtk-config --version"
* 3: Output of "gtk-config --libs"
* 4: Output of "gtk-config --cflags"
* 5: Output of "uname -a"
* 6: Version of GTK installed... eg, type: ls -l /lib/libgtk*
* 7: Other info... which linux distribution, version, other software
*/
#include "uuencode.h"
static char uuchar(unsigned int val);
void uuencode(char *str, const unsigned char *data, int num)
{
int i, n;
unsigned int val;
*str++ = uuchar(num);
n = (num + 2) / 3;
for (i=0; i<n; i++) {
val = ((data[0] & 0xFF) << 16)
| ((data[1] & 0xFF) << 8)
| ((data[2] & 0xFF) << 0);
*str++ = uuchar(val >> 18);
*str++ = uuchar(val >> 12);
*str++ = uuchar(val >> 6);
*str++ = uuchar(val >> 0);
data += 3;
}
*str = '\0';
}
int uudecode(const char *str, unsigned char *data, int max)
{
int num=0;
int i, n;
unsigned int val;
if (*str == '\0') return 0;
num = *str++ - 32;
if (num < 1 || num > 45) return 0;
n = (num + 2) / 3;
for (i=0; i<n; i++) {
if (str[0] < 32 || str[0] > 96) return 0;
if (str[1] < 32 || str[1] > 96) return 0;
if (str[2] < 32 || str[2] > 96) return 0;
if (str[3] < 32 || str[3] > 96) return 0;
val = (((str[0] - 32) & 0x3F) << 18)
| (((str[1] - 32) & 0x3F) << 12)
| (((str[2] - 32) & 0x3F) << 6)
| (((str[3] - 32) & 0x3F) << 0);
*data++ = (val >> 16) & 0xFF;
*data++ = (val >> 8) & 0xFF;
*data++ = (val >> 0) & 0xFF;
str += 4;
}
return num;
}
static char uuchar(unsigned int val)
{
val &= 0x3F;
val += 0x20;
if (val == 0x20) val = 0x60;
return val;
}

View File

@ -0,0 +1,3 @@
extern void uuencode(char *str, const unsigned char *data, int num);
extern int uudecode(const char *str, unsigned char *data, int max);

22
board/msba2/tools/termctrl.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/sh
pid=`pgrep pseudoterm`
if test "$pid" = "" ; then
echo " Pseudoterm not running."
else
if test "$1" = "continue" ; then
kill -s USR1 $pid;
elif test "$1" = "pause" ; then
kill -s USR2 $pid ;
elif test "$1" = "stop" ; then
kill $pid ;
else
echo "Usage:";
echo "termctrl.sh continue/pause/stop";
fi
fi

View File

@ -0,0 +1,10 @@
SubDir TOP board olimex_lpc2148 ;
CPU = lpc214x ;
HDRS += $(TOP)/board/olimex_lpc2148/include ;
Module board : board_init.c debug_uart.c rs232.c ;
UseModule board ;
SubInclude TOP cpu lpc214x ;

View File

@ -0,0 +1,4 @@
##################
include $(TOP)/Jamfile.arm_common ;

View File

@ -0,0 +1,9 @@
############################
BOARD = olimex_lpc2148 ;
CPU = lpc214x ;
GDB = arm-elf-gdb ;
GDBFLAGS = -x board/olimex_lpc2148/tools/lpc2148_flash.gdb ;
include $(TOP)/Jamrules.arm_common ;

View File

@ -0,0 +1,88 @@
/*
* bl_board_init.c
*
* Created on: 19.08.2008
* Author: heiko, kaspar
*/
#include "cpu.h"
#include "bits.h"
#include "VIC.h"
#define PLOCK 0x400
static void feed(void)
{
PLL0FEED = 0xAA;
PLL0FEED = 0x55;
}
void bl_init_clks(void)
{
// Setting the Phased Lock Loop (PLL)
// ----------------------------------
//
// Olimex LPC-P2148 has a 12.0000 mhz crystal
//
// We'd like the LPC2148 to run at 60 mhz (has to be an even multiple of crystal)
//
// According to the Philips LPC2148 manual: M = cclk / Fosc where: M = PLL multiplier (bits 0-4 of PLLCFG)
// cclk = 60000000 hz
// Fosc = 12000000 hz
//
// Solving: M = 60000000 / 12000000 = 5
//
// Note: M - 1 must be entered into bits 0-4 of PLLCFG (assign 4 to these bits)
//
//
// The Current Controlled Oscilator (CCO) must operate in the range 156 mhz to 320 mhz
//
// According to the Philips LPC2148 manual: Fcco = cclk * 2 * P where: Fcco = CCO frequency
// cclk = 60000000 hz
// P = PLL divisor (bits 5-6 of PLLCFG)
//
// Solving: Fcco = 60000000 * 2 * P
// P = 2 (trial value)
// Fcco = 60000000 * 2 * 2
// Fcc0 = 240000000 hz (good choice for P since it's within the 156 mhz to 320 mhz range)
//
// From Table 22 (page 34) of Philips LPC2148 manual P = 2, PLLCFG bits 5-6 = 1 (assign 1 to these bits)
//
// Finally: PLLCFG = 0 01 00100 = 0x24
//
// Final note: to load PLLCFG register, we must use the 0xAA followed 0x55 write sequence to the PLLFEED register
// this is done in the short function feed() below
//
// Setting Multiplier and Divider values
PLL0CFG = 0x24;
feed();
// Enabling the PLL */
PLL0CON = 0x1;
feed();
// Wait for the PLL to lock to set frequency
while(!(PLL0STAT & PLOCK)) ;
// Connect the PLL as the clock source
PLL0CON = 0x3;
feed();
// Enabling MAM and setting number of clocks used for Flash memory fetch
MAMTIM = 0x3;
MAMCR = 0x2;
// Setting peripheral Clock (pclk) to 1/2 System Clock (cclk)
VPBDIV = PCLK_DIV;
}
void bl_init_ports(void)
{
}

View File

@ -0,0 +1,14 @@
#include "lpc214x.h"
#include "bits.h"
#include "rs232.h"
void debug_putchar(int character)
{
UART1WriteChar(character);
}
void bl_uart_init(void)
{
UART1Initialize(115200U);
}

View File

@ -0,0 +1 @@
#include <lpc2148.h>

View File

@ -0,0 +1,40 @@
//rs232.h
//#include <iolpc2138.h>
#include "lpc214x.h"
//#define OSCILLATOR_CLOCK_FREQUENCY 14745600 //in MHz
#define OSCILLATOR_CLOCK_FREQUENCY 12000000 //in MHz
//get real processor clock frequency
unsigned int processorClockFrequency(void);
//get peripheral clock frequency
unsigned int peripheralClockFrequency(void);
/**** UART0 ****/
//initialize UART0 interface
void UART0Initialize(unsigned int baud);
//write char to UART0 (RS232);
void UART0WriteChar(int ch0);
//read char from RS232
unsigned char UART0ReadChar(void);
//this function read/write char from RS232,
//but they not wait to read/write
unsigned char UART0ReadChar_nostop(void);
void UART0WriteChar_nostop(unsigned char ch0);
/**** UART1 ****/
//initialize UART0 interface
void UART1Initialize(unsigned int baud);
//write char to UART0 (RS232);
void UART1WriteChar(int ch0);
//read char from RS232
unsigned char UART0ReadChar(void);
//this function read/write char from RS232,
//but they not wait to read/write
unsigned char UART1ReadChar_nostop(void);
void UART1WriteChar_nostop(unsigned char ch0);

View File

@ -0,0 +1,65 @@
//rs232.c
#include "rs232.h"
unsigned int processorClockFrequency(void)
{
//return real processor clock speed
return OSCILLATOR_CLOCK_FREQUENCY * (PLL0CON & 1 ? (PLL0CFG & 0xF) + 1 : 1);
}
unsigned int peripheralClockFrequency(void)
{
//VPBDIV - determines the relationship between the processor clock (cclk)
//and the clock used by peripheral devices (pclk).
unsigned int divider = 0;
switch (VPBDIV & 3)
{
case 0: divider = 4; break;
case 1: divider = 1; break;
case 2: divider = 2; break;
}
return processorClockFrequency() / divider;
}
/**** UART0 ****/
void UART1Initialize(unsigned int baud)
{
unsigned int divisor = peripheralClockFrequency() / (16 * baud);
//set Line Control Register (8 bit, 1 stop bit, no parity, enable DLAB)
// U0LCR_bit.WLS = 0x3; //8 bit
// U0LCR_bit.SBS = 0x0; //1 stop bit
// U0LCR_bit.PE = 0x0; //no parity
// U0LCR_bit.DLAB = 0x1; //enable DLAB
//with one row
U1LCR = 0x83;
//devisor
U1DLL = divisor & 0xFF;
U1DLM = (divisor >> 8) & 0xFF;
U1LCR &= ~0x80;
//set functionalite to pins: port0.0 -> TX0, port0.1 -> RXD0
// PINSEL0_bit.P0_0 = 0x1;
// PINSEL0_bit.P0_1 = 0x1;
//with one row
PINSEL0 |= BIT16;
PINSEL0 &= ~BIT17;
}
void UART1WriteChar(int ch0)
{
while (!(U1LSR & BIT5));
U1THR = ch0;
}
unsigned char UART0ReadChar(void)
{
//when U0LSR_bit.DR is 1 - U0RBR contains valid data
// while (U0LSR_bit.DR == 0);
return U0RBR;
}

View File

@ -0,0 +1,63 @@
/* Copyright (C) 2005, 2006, 2007, 2008 by Thomas Hillebrandt and Heiko Will
This file is part of the Micro-mesh SensorWeb Firmware.
Micro-Mesh 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, or (at your option)
any later version.
Micro-Mesh 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 Micro-Mesh; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "lpc214x.h"
#include "bits.h"
//#include "tick.h"
#include "minimal_dbg_console.h"
#include "VIC.h"
void Timer0_IRQHandler (void) __attribute__((interrupt("IRQ")));
extern void eINT();
extern void dINT();
void driver_timer_load(void)
{
T0TCR = 0; // Disable timer 0.
T0PR = 3000; // Prescaler is set to relevant pclk , counter is incremented every T0PR tact.
T0CCR = 0; // Capture is disabled.
T0EMR = 0; // No external match output.
T0TC= 0;
T0MR0= 1000;
T0MCR|= BIT0 + BIT1;
T0TCR = BIT0; // Enable timer 0.
dINT(); // Disable all interrupts
VICIntEnable = BIT4; // Enable Interrupthandling for Timer0
VICVectCntl3 = 4 + BIT5; // Assign Timer0 to IRQ Slot 3
VICVectAddr3 = (unsigned int)Timer0_IRQHandler; // Assign Isr Address
eINT();
}
int counter = 0;
void Timer0_IRQHandler (void)
{
extern unsigned int fk_context_switch_request;
counter++;
T0IR |= 0xff; // reset timer1 interrupt flag
sl_printf("#");
fk_context_switch_request = 1;
VICVectAddr = 0; // acknowledge interrupt (if using VIC IRQ)
}

View File

@ -0,0 +1,22 @@
#winheight regs 11
set history save on
set history size 1000
target remote localhost:3333
monitor reset
monitor sleep 100
monitor halt
monitor poll
#monitor arm7_9 sw_bkpts disable
#monitor arm7_9 force_hw_bkpts enable
monitor mww 0xE01FC040 0x0001
monitor mdw 0xE01FC040
monitor flash erase_sector 0 0 14
#monitor flash auto_erase on
monitor flash erase_check 0
#monitor flash write_image /home/kaspar/FeuerWhere/src/x/bin/arm.elf
set remote hardware-watchpoint-limit 2
load
break bootloader
mon soft_reset_halt
continue
d b 1

35
board/pttu/Jamfile Normal file
View File

@ -0,0 +1,35 @@
# ******************************************************************************
# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
#
# These sources were developed at the Freie Universitaet Berlin, Computer
# Systems and Telematics group (http://cst.mi.fu-berlin.de).
# ------------------------------------------------------------------------------
# This file is part of FeuerWare.
#
# 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.
#
# FeuerWare 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/ .
# ------------------------------------------------------------------------------
# For further information and questions please use the web site
# http://scatterweb.mi.fu-berlin.de
# and the mailinglist (subscription via web site)
# scatterweb@lists.spline.inf.fu-berlin.de
# ******************************************************************************
# $Id: Jamfile 922 2009-03-26 12:52:27Z baar $
SubDir TOP board pttu ;
Module board : board_init.c ;
UseModule board ;
UseModule board_common ;
SubInclude TOP board $(BOARD) drivers ;
SubInclude TOP cpu $(CPU) ;

28
board/pttu/Jamfile.pttu Normal file
View File

@ -0,0 +1,28 @@
# ******************************************************************************
# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
#
# These sources were developed at the Freie Universitaet Berlin, Computer
# Systems and Telematics group (http://cst.mi.fu-berlin.de).
# ------------------------------------------------------------------------------
# This file is part of FeuerWare.
#
# 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.
#
# FeuerWare 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/ .
# ------------------------------------------------------------------------------
# For further information and questions please use the web site
# http://scatterweb.mi.fu-berlin.de
# and the mailinglist (subscription via web site)
# scatterweb@lists.spline.inf.fu-berlin.de
# ******************************************************************************
# $Id: Jamfile.msba2 832 2009-03-13 16:45:41Z kaspar $
include [ FPath $(TOP) cpu arm_common Jamfile.arm_common ] ;

37
board/pttu/Jamrules.pttu Normal file
View File

@ -0,0 +1,37 @@
# ******************************************************************************
# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
#
# These sources were developed at the Freie Universitaet Berlin, Computer
# Systems and Telematics group (http://cst.mi.fu-berlin.de).
# ------------------------------------------------------------------------------
# This file is part of FeuerWare.
#
# 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.
#
# FeuerWare 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/ .
# ------------------------------------------------------------------------------
# For further information and questions please use the web site
# http://scatterweb.mi.fu-berlin.de
# and the mailinglist (subscription via web site)
# scatterweb@lists.spline.inf.fu-berlin.de
# ******************************************************************************
# $Id: Jamrules.msba2 881 2009-03-20 12:24:58Z kaspar $
CPU = lpc2387 ;
HDRS += [ FPath $(TOP) board $(BOARD) drivers include ] ;
FLASHER = $(POSIXSHELL) $(TOP)/board/msba2/tools/flashutil.sh ;
FLASHFLAGS = --basedir $(TOP)/board/msba2/tools --id PTTU --ports "$(PORT)" --openocd $(TOP)/board/pttu/tools/openocd-pttu.sh --openocd-if $(OPENOCD_IF) ;
GDB = arm-elf-gdb ;
GDBFLAGS = -x board/pttu/tools/pttu_debug.gdb ;

239
board/pttu/board_init.c Normal file
View File

@ -0,0 +1,239 @@
/******************************************************************************
Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved.
These sources were developed at the Freie Universitaet Berlin, Computer Systems
and Telematics group (http://cst.mi.fu-berlin.de).
-------------------------------------------------------------------------------
This file is part of FeuerWare.
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.
FeuerWare 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/ .
--------------------------------------------------------------------------------
For further information and questions please use the web site
http://scatterweb.mi.fu-berlin.de
and the mailinglist (subscription via web site)
scatterweb@lists.spline.inf.fu-berlin.de
*******************************************************************************/
/**
* @ingroup pttu
* @{
*/
/**
* @file
* @brief PTTU board initialization
*
* @author Freie Universit<EFBFBD>t Berlin, Computer Systems & Telematics, FeuerWhere project
* @author Heiko Will
* @author Kaspar Schleise
* @author Michael Baar <baar@inf.fu-berlin.de>
*
* @note $Id: cmdengine-out.c 971 2009-04-07 13:41:36Z baar $
*/
#include "lpc23xx.h"
#include "VIC.h"
#include "cpu.h"
#define PCRTC BIT9
#define CL_CPU_DIV 4
/*---------------------------------------------------------------------------*/
/**
* @brief Enabling MAM and setting number of clocks used for Flash memory fetch
* @internal
*/
void
init_mam(void)
{
MAMCR = 0x0000;
MAMTIM = 0x0003;
MAMCR = 0x0002;
}
/*---------------------------------------------------------------------------*/
static inline void
pllfeed(void)
{
PLLFEED = 0xAA;
PLLFEED = 0x55;
}
/*---------------------------------------------------------------------------*/
void init_clks1(void)
{
// Disconnect PLL
PLLCON &= ~0x0002;
pllfeed();
// Disable PLL
PLLCON &= ~0x0001;
pllfeed();
SCS |= 0x20; // Enable main OSC
while( !(SCS & 0x40) ); // Wait until main OSC is usable
/* select main OSC, 16MHz, as the PLL clock source */
CLKSRCSEL = 0x0001;
// Setting Multiplier and Divider values
PLLCFG = 0x0008; // M=9 N=1 Fcco = 288 MHz
pllfeed();
// Enabling the PLL */
PLLCON = 0x0001;
pllfeed();
/* Set clock divider to 4 (value+1) */
CCLKCFG = CL_CPU_DIV - 1; // Fcpu = 72 MHz
#if USE_USB
USBCLKCFG = USBCLKDivValue; /* usbclk = 288 MHz/6 = 48 MHz */
#endif
}
void init_clks2(void){
// Wait for the PLL to lock to set frequency
while(!(PLLSTAT & BIT26));
// Connect the PLL as the clock source
PLLCON = 0x0003;
pllfeed();
/* Check connect bit status */
while (!(PLLSTAT & BIT25));
}
void bl_init_clks(void)
{
PCONP = PCRTC; // switch off everything except RTC
init_clks1();
init_clks2();
init_mam();
}
// Michael, Do not change anything here! even not the redundant parts!
void bl_init_ports(void)
{
SCS |= BIT0; // Set IO Ports to fast switching mode
/* UART0 */
PINSEL0 |= BIT4 + BIT6; // RxD0 and TxD0
PINSEL0 &= ~(BIT5 + BIT7);
/*Turn Board on*/
PINMODE0 |= BIT1;
FIO0DIR |= BIT27;
FIO0CLR = BIT27;
/* 5V*/
FIO1DIR |= BIT28; // Synch
FIO1SET = BIT28; // No Powersave
FIO1DIR |= BIT27; // 5V off
FIO1CLR = BIT27;
/* Disable Resistors on Buttons */
PINMODE4 |= BIT9 + BIT11;
/* Disable Resistors on LED - and Ports to output*/
PINMODE7 |= BIT19 + BIT21;
PINMODE2 |= BIT1;
FIO1DIR |= BIT0;
FIO3DIR |= BIT25 + BIT26;
FIO1SET = BIT0;
FIO3SET = BIT25 + BIT26;
// Config and Disable PA
FIO1DIR |= BIT25 + BIT26 + BIT22;
FIO1SET = BIT26;
FIO1CLR = BIT25;
FIO1CLR = BIT22; // PA /Shutdown
FIO0DIR |= BIT26; // ** // Important: First put this Port as DA 2.0V and then turn on PA!!
FIO0SET = BIT26; // **
// Configure GPS
PINMODE3 |= BIT3 + BIT7; // No Pullup on 1.17 & 1.19
PINMODE9 |= BIT27 + BIT25; // No Pullup for Uart
FIO1DIR |= BIT17;
FIO1CLR = BIT17; // Turn off GPS
FIO1DIR |= BIT19;
FIO1CLR = BIT19; // Hold in Reset
PINSEL9 |= BIT24 + BIT25 + BIT26 + BIT27; //4.28 & 4.29 as Uart3
// Nanotron
FIO2DIR &= ~BIT8; // nanotron uC IRQ as input
FIO1DIR |= BIT15; // nanotron power on reset
FIO1DIR &= ~BIT14; // nanotron uC RESET as input
FIO1DIR &= ~BIT10; // nanotron uC Vcc as input
FIO1DIR |= BIT9; // nanotron ENABLE as output
FIO1DIR &= ~BIT4; // nanotron Rx/Tx as input
FIO1CLR = BIT15;
FIO1CLR = BIT9; // Enable power
PINMODE1 |= BIT1; // No Pullup for CS
FIO0DIR |= BIT16; // CS as output
FIO0SET = BIT16; // drive cs inactive
FIO0DIR |= BIT18 + BIT15; // SPi Output
// RFID
FIO1DIR |= BIT1; // RFID Power
FIO1CLR = BIT1; //
FIO0DIR |= BIT1; // RFID Reset
FIO0SET = BIT1; // Hold in Reset
FIO0DIR &= ~BIT10; // LED as INPUT
FIO0DIR &= ~BIT11; // DATA as INPUT
PINMODE0 |= BIT19 + BIT21; // No Pullups
// LTC4150 ARM
FIO0DIR |= BIT5;
FIO0CLR = BIT5;
// LTC4150 System
FIO0DIR |= BIT24;
FIO0CLR = BIT24;
// Battery Voltage (AD)
PINMODE1 |= BIT19;
PINSEL1 &= ~BIT19;
PINSEL1 |= BIT18;
//cc1100
FIO0DIR |= BIT6 + BIT7 + BIT9;
FIO0SET = BIT6;
FIO0SET = BIT7 + BIT9;
//SD
FIO2DIR |= BIT12 + BIT13 + BIT11;
FIO0DIR |= BIT20 + BIT22 + BIT21;
//Tetra
FIO2DIR |= BIT0 + BIT7;
// No Pullups on any port
int nopullup = BIT1 + BIT3 + BIT5 + BIT7 + BIT9 + BIT11 + BIT13 + BIT15 + BIT17 + BIT19 + BIT21 + BIT23 + BIT25 + BIT27 + BIT29 + BIT31;
PINMODE0 = nopullup - BIT13 - BIT15 - BIT17 - BIT19;
PINMODE1 = BIT1 + BIT3 + BIT5 + BIT7 + BIT9 + BIT11 + BIT13 + BIT15 + BIT17 + BIT19 + BIT21;
PINMODE2 = nopullup;
PINMODE3 = nopullup;
PINMODE4 = nopullup;
PINMODE5 = nopullup;
PINMODE6 = nopullup;
PINMODE7 = nopullup;
PINMODE8 = nopullup;
PINMODE9 = nopullup;
}
/** @} */

View File

@ -0,0 +1,4 @@
SubDir TOP board pttu drivers ;
Module board_common : pttu-uart0.c ;

View File

@ -0,0 +1,204 @@
/******************************************************************************
Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved.
These sources were developed at the Freie Universitaet Berlin, Computer Systems
and Telematics group (http://cst.mi.fu-berlin.de).
-------------------------------------------------------------------------------
This file is part of FeuerWare.
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.
FeuerWare 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/ .
--------------------------------------------------------------------------------
For further information and questions please use the web site
http://scatterweb.mi.fu-berlin.de
and the mailinglist (subscription via web site)
scatterweb@lists.spline.inf.fu-berlin.de
*******************************************************************************/
/*
* debug_uart.c: provides initial serial debug output
*
* Copyright (C) 2008, 2009 Kaspar Schleiser <kaspar@schleiser.de>
* Heiko Will <hwill@inf.fu-berlin.de>
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "lpc23xx.h"
#include "VIC.h"
/**
* @file
* @ingroup lpc2387
*
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
* @version $Revision$
*
* @note $Id$
*/
typedef struct toprint {
unsigned int len;
char content[];
}toprint;
#define QUEUESIZE 255
static volatile toprint* queue[QUEUESIZE];
static volatile unsigned char queue_head = 0;
static volatile unsigned char queue_tail = 0;
static volatile unsigned char queue_items = 0;
static volatile unsigned int actual_pos = 0;
static volatile unsigned int running = 0;
static volatile unsigned int fifo = 0;
static volatile toprint* actual = NULL;
void (*uart0_callback)(int);
static inline void enqueue(void) {
queue_items++;
queue_tail++;
}
static inline void dequeue(void) {
actual = (queue[queue_head]);
queue_items--;
queue_head++;
}
static void push_queue(void) {
running = 1;
start:
if (!actual) {
if (queue_items) {
dequeue();
} else {
running = 0;
if (!fifo)
while(!(U0LSR & BIT6)){};
return;
}
}
while ((actual_pos < actual->len) && (fifo++ < 16)){
U0THR = actual->content[actual_pos++];
}
if (actual_pos == actual->len) {
free((void*)actual);
actual = NULL;
actual_pos = 0;
goto start;
}
}
int uart_active(void){
return (running || fifo);
}
static inline void receive(int c)
{
if (uart0_callback != NULL) uart0_callback(c);
}
void stdio_flush(void)
{
U0IER &= ~BIT1; // disable THRE interrupt
while(running) {
while(!(U0LSR & (BIT5|BIT6))){}; // transmit fifo
fifo=0;
push_queue(); // dequeue to fifo
}
U0IER |= BIT1; // enable THRE interrupt
}
void UART0_IRQHandler(void) __attribute__((interrupt("IRQ")));
void UART0_IRQHandler(void)
{
int iir;
iir = U0IIR;
switch(iir & UIIR_ID_MASK) {
case UIIR_THRE_INT: // Transmit Holding Register Empty
fifo=0;
push_queue();
break;
case UIIR_CTI_INT: // Character Timeout Indicator
case UIIR_RDA_INT: // Receive Data Available
do {
int c = U0RBR;
receive(c);
} while (U0LSR & ULSR_RDR);
break;
default:
U0LSR;
U0RBR;
break;
} // switch
VICVectAddr = 0; // Acknowledge Interrupt
}
static inline int uart0_puts(char *astring,int length)
{
while (queue_items == (QUEUESIZE-1)) {} ;
U0IER = 0;
queue[queue_tail] = malloc(length+sizeof(unsigned int));
queue[queue_tail]->len = length;
memcpy(&queue[queue_tail]->content,astring,length);
enqueue();
if (!running)
push_queue();
U0IER |= BIT0 | BIT1; // enable RX irq
// alternative without queue:
// int i;
// for (i=0;i<length;i++) {
// while (!(U0LSR & BIT5));
// U0THR = astring[i];
// }
return length;
}
int fw_puts(char *astring,int length)
{
return uart0_puts(astring, length);
}
int
bl_uart_init(void)
{
PCONP |= PCUART0; // power on
// UART0 clock divider is CCLK/8
PCLKSEL0 |= BIT6 + BIT7;
U0LCR = 0x83; // 8 bits, no Parity, 1 Stop bit
// TODO: UART Baudrate calculation using uart->config->speed
/*
* Baudrate calculation
* BR = PCLK (9 MHz) / (16 x 256 x DLM + DLL) x (1/(DIVADDVAL/MULVAL))
*/
U0FDR = 0x92; // DIVADDVAL = 0010 = 2, MULVAL = 1001 = 9
U0DLM = 0x00;
U0DLL = 0x04;
U0LCR = 0x03; // DLAB = 0
U0FCR = 0x07; // Enable and reset TX and RX FIFO
/* irq */
install_irq(UART0_INT, UART0_IRQHandler, 6);
U0IER |= BIT0 | BIT1; // enable RX+TX irq
return 1;
}

View File

@ -0,0 +1,56 @@
/******************************************************************************
Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved.
These sources were developed at the Freie Universitaet Berlin, Computer Systems
and Telematics group (http://cst.mi.fu-berlin.de).
-------------------------------------------------------------------------------
This file is part of FeuerWare.
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.
FeuerWare 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/ .
--------------------------------------------------------------------------------
For further information and questions please use the web site
http://scatterweb.mi.fu-berlin.de
and the mailinglist (subscription via web site)
scatterweb@lists.spline.inf.fu-berlin.de
*******************************************************************************/
#ifndef __BOARD_H
#define __BOARD_H
/**
* @ingroup pttu
* @{
*/
/**
* @file
* @brief PTTU Board
*
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
* @author Kaspar Schleiser <kaspar@schleiser.de>
* @version $Revision$
*
* @note $Id: board.h 664 2009-02-19 10:54:44Z baar $
*/
#include <lpc2387.h>
#include <cpu-conf.h>
#define VICIntEnClear VICIntEnClr
void init_clks1(void);
void init_clks2(void);
void bl_init_clks(void);
/** @} */
#endif // __BOARD_H

14
board/pttu/tools/jtag.txt Normal file
View File

@ -0,0 +1,14 @@
compile openocd release v0.1:
[extract to somewhere]
./configure --prefix=CHANGEMEtowhatever --enable-ft2232_libftdi
make
make install
to flash run from within board/pttu/tools:
./openocd-pttu.sh olimex-usb-jtag-tiny-a "mt_flash CHANGEME/absolute/path/to/hexfile/pttu.hex;shutdown"
to debug, first start the following from within board/pttu/tools:
./openocd-pttu.sh olimex-usb-jtag-tiny-a
then just run "jam debug". this will flash bin/pttu.hex, run it and stop at the bootloader.

Some files were not shown because too many files have changed in this diff Show More