--- /dev/null
+SOURCE_DIRS="embedded/app embedded/arch embedded/board embedded/libs4c"
+OMK_RULES_DIR=omk/rules/sysless
+BUILD_DIR=embedded-build/can-usb1
+OMK_CONFIG=embedded/board/arm/ul_usb1/config/config.usbcan
+
+SOURCE_PATHS="$SOURCE_PATHS $SOURCE_DIRS $(echo $OMK_RULES_DIR/*)"
+
+TOP_RELATIVE="$( echo "$BUILD_DIR" | sed -n -e 's#[^/]*/[^/]*#../#pg' ).."
+
+echo "SOURCE_PATHS=$SOURCE_PATHS"
+echo "TOP_RELATIVE=$TOP_RELATIVE"
+
+mkdir -p "$BUILD_DIR" || exit 1
+
+for i in $SOURCE_PATHS ; do
+ b="$(basename $i)"
+ if [ ! -e "$BUILD_DIR/$b" ] ; then
+ echo "$BUILD_DIR : ln -s $TOP_RELATIVE/$i $b"
+ ( cd "$BUILD_DIR" && ln -s "$TOP_RELATIVE/$i" "$b" ) || exit 1
+ fi
+done
+
+for i in $SOURCE_DIRS ; do
+ b="$(basename $i)"
+ if ! grep -s "\<$b\>" "$BUILD_DIR/Makefile.omk" ; then
+ echo "SUBDIRS += $b" >>"$BUILD_DIR/Makefile.omk" || exit 1
+ fi
+done
+
+if [ ! -e "$BUILD_DIR/Makefile" ] ; then
+ m=$OMK_RULES_DIR
+ if [ ! -e "$m/Makefile" ] ; then m="$(dirname $m)" ; fi
+ if [ ! -e "$m/Makefile" ] ; then m="$(dirname $m)" ; fi
+ if [ -e "$m/Makefile" ] ; then
+ cp -v "$m/Makefile" "$BUILD_DIR/Makefile"
+ fi
+fi
+
+if [ ! -e "$BUILD_DIR/config.omk" ] ; then
+ ( cd "$BUILD_DIR" && ln -s "$TOP_RELATIVE/$OMK_CONFIG" config.omk )
+fi
+
+( cd "$BUILD_DIR" && make default-config ) || exit 1
+
+( cd "$BUILD_DIR" && make ) || exit 1
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+SUBDIRS = app arch board libs4c
+
+-include $(SOURCES_DIR)/Makefile.omk-additional
+
--- /dev/null
+uLan embedded source tree v 0.5
+===============================
+
+This is highly experimental code, look for latest
+version on the project related pages
+
+ http://ulan.sourceforge.net/
+ http://sourceforge.net/projects/ulan
+ http://cmp.felk.cvut.cz/~pisa#ulan
+
+To build code you need to have SDCC 2.5.3-CVS.
+The snapshot past Sep 3 2005 are OK.
+The GNU make program 3.81beta3 or better is required.
+The full build has been tested on Linux based hosts only
+for now. The uLan protocol code has been successfully build
+by Keil compiler under Windows in the past.
+
+The archive has to be unpacked with symbolic links
+for now. We are thinking about rearrangement
+of the code to make it more portable and drop
+link requirements.
+
+The MCS51 is only port provided in this version.
+
+To build do
+
+ cd ul_embedded-x.y/mcs51
+ make defaul-config
+ make
+
+You should find resulting binaries in the "_compiled/bin"
+directory. The board and application is selected by used
+"config.omk" file. Example files can be found in the "configs"
+directory.
+
+The next boards and applications are supported
+
+Device: MCS51 TI MSC-1210
+ Board: ULAD-21 - AD converter and uLan2USB converter
+ Applications:
+ config.mscboot-ulad21 - uLan enabled remote boot-loader and boot-block
+ config.u2u-ulad21 - uLan to USB converter
+
+ Board: HISC - Home Information System Controller
+ config.mscboot-hisc - boot block for distributed HISC system
+ config.blinder - blinder controller
+ config.kswtimer - kettle switch timer
+
+Device: MCS51 Atmel AT89C51RD2
+ config.u2u-ps1 - AT89C51RD2 based uLan2USB converter
+
+
+The procedure to write boot-block into ULAD-21 MSC1210 based board
+requires next steps
+
+ FLASHMSC_TTY=/dev/ttyS1
+ flashmsc -d $FLASHMSC_TTY -E 0x807f
+ flashmsc -d $FLASHMSC_TTY -E 0x7fff
+ flashmsc -d $FLASHMSC_TTY -X 18432000 ulad21-hcr.hex
+ flashmsc -d $FLASHMSC_TTY -X 18432000 ulad21-boot.hex
+
+The "flashmsc" sources can be found at page
+ http://cmp.felk.cvut.cz/~pisa/#mcuutils
+
+To replace application in the converter or other uLan node
+over uLan communication protocol, next steps are required
+
+ echo Reset application if running
+ ul_sendhex -g 0 -m 0
+ echo Waiting to target to go into boot block
+ echo If application blocks, reset device at this time
+ echo to activate boot block now
+ ul_sendhex -o 0 -m 0
+ echo Found devices
+ ul_sendhex -p 64
+ echo Erasing flash
+ ul_sendhex -m 62 -t 5 -e -s 0x2000 -l 0x6000
+ sleep 2
+ echo Loading application
+ ul_sendhex -m 62 -t 5 application.hex
+
+Look for uLan driver for host side (Linux, Windows, DOS)
+uLan protocol driver. The uLan2USB converter requires
+at least version ul_drv-0.7 release.
+
+The code authors
+
+ (C) Copyright 1996-2005 by Pavel Pisa
+ http://cmp.felk.cvut.cz/~pisa
+ (C) Copyright 1996-2005 PiKRON Ltd.
+ http://www.pikron.com
+ (C) Copyright 2002-2005 Petr Smolik
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+SUBDIRS = usbcan
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+default_CONFIG = CONFIG_APP_USBCAN=n
+
+ifeq ($(CONFIG_APP_USBCAN),y)
+
+#ULAN_ID=usbtest
+
+#default_CONFIG += CONFIG_ULOI_LT=x
+#default_CONFIG += CONFIG_ULAN_DY=x
+default_CONFIG += MACH=$(MACH)
+#default_CONFIG += ULAN_ID=$(ULAN_ID)
+default_CONFIG += CONFIG_MISC_VECT=x
+default_CONFIG += CONFIG_OC_LINCAN_CARD_ul_usb1=x
+default_CONFIG += CONFIG_OC_LINCAN_CARD_can_lmc1=x
+
+
+LOCAL_CONFIG_H = local_config.h
+
+INCLUDES += -I.
+
+#include_HEADERS = ul_idstr.h
+
+bin_PROGRAMS = usbcan
+usbcan_SOURCES = main.c can_queue.c sja1000p.c devcommon.c setup.c finish.c
+usbcan_SOURCES += usb_vend.c can_quesysless.c sysdep_sysless.c
+ifeq ($(CONFIG_OC_LINCAN_CARD_can_lmc1),y)
+usbcan_SOURCES += lpc17xx_can.c
+endif
+ifeq ($(CONFIG_OC_LINCAN_CARD_ul_usb1),y)
+usbcan_SOURCES += can_lpcbusemu.c ul_usb1.c
+endif
+
+#usbtest_SOURCES += ul_idstr.c
+#lib_LOADLIBES = bspbase ul_drv lpciap keyval lpciap_kvpb mach_hal uldy
+lib_LOADLIBES = bspbase usbbase usbmore lpcusb mach_hal
+usbcan_MOREOBJS = $(USER_LIB_DIR)/system_stub.o
+nobase_include_HEADERS = usb/usb_defs.h
+
+ifeq ($(MACH),lpc21xx)
+link_VARIANTS = app boot
+usbcan_MOREOBJS += $(USER_LIB_DIR)/ivt.o
+endif
+
+endif #CONFIG_ULBOOT
--- /dev/null
+#ifndef SJA1000_CAN_H
+#define SJA1000_CAN_H
+
+#include <stdio.h>
+#include <string.h>
+#include <cpu_def.h>
+#include <system_def.h>
+#include <lt_timer.h>
+#include <local_config.h>
+#include <usb/usbdebug.h>
+#include <usb/usb.h>
+#include <usb/lpc.h>
+#include <usb/usb_srq.h>
+#include <mem_loc.h>
+#include <hal_machperiph.h>
+
+
+#include "main.h"
+#include "sja1000p.h"
+/* can.h
+ * Header file for the Linux CAN-bus driver.
+ * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
+ * Rewritten for new CAN queues by Pavel Pisa - OCERA team member
+ * email:pisa@cmp.felk.cvut.cz
+ * This software is released under the GPL-License.
+ * Version lincan-0.3 17 Jun 2004
+ */
+
+ /*
+ Delay for synchronization with peripheral (SJA1000)
+ */
+ #define SJA1000_CLK (24000000) /* XTAL frequency */
+ #define SJA1000_PRESC (2) /* embedded prescaler */
+ #define SJA1000_CCLK (SJA1000_CLK/SJA1000_PRESC) /* SJA core frequency */
+ #define SJA1000_SCLK (PCLK/SJA1000_CCLK) /* Clock count to synchronize with LPC */
+
+ #define SJA1000_DELAY(void) \
+ ({ \
+ volatile int delay; \
+ for (delay=0;delay<SJA1000_SCLK;delay++) \
+ IO0SET=0; \
+ })
+ #define SJA1000_INIT_DELAY(void) \
+ ({ \
+ volatile int delay; \
+ for (delay=0;delay<20*SJA1000_SCLK;delay++) \
+ IO0SET=0; \
+ })
+
+/**
+ * struct can_baudparams_t - datatype for calling CONF_BAUDPARAMS IOCTL
+ * @flags: reserved for additional flags for chip configuration, should be written -1 or 0
+ * @baudrate: baud rate in Hz
+ * @sjw: synchronization jump width (0-3) prescaled clock cycles
+ * @sampl_pt: sample point in % (0-100) sets (TSEG1+1)/(TSEG1+TSEG2+2) ratio
+ *
+ * The structure is used to configure new set of parameters into CAN controller chip.
+ * If default value of some field should be preserved, fill field by value -1.
+ */
+struct can_baudparams_t {
+ long flags;
+ long baudrate;
+ long sjw;
+ long sample_pt;
+};
+
+extern int can_init();
+extern uint8_t can_read(uint8_t address);
+extern void can_write(uint8_t data, uint8_t address);
+
+#endif /* SJA1000_CAN_H */
--- /dev/null
+#ifndef _CAN_BITTIMING_H
+#define _CAN_BITTIMING_H
+
+#include "./can_sysdep.h"
+
+/*
+ * CAN harware-dependent bit-timing constant
+ *
+ * Used for calculating and checking bit-timing parameters
+ */
+
+struct can_bittiming_const {
+ char name[16]; /* Name of the CAN controller hardware */
+ uint32_t tseg1_min; /* Time segement 1 = prop_seg + phase_seg1 */
+ uint32_t tseg1_max;
+ uint32_t tseg2_min; /* Time segement 2 = phase_seg2 */
+ uint32_t tseg2_max;
+ uint32_t sjw_max; /* Synchronisation jump width */
+ uint32_t brp_min; /* Bit-rate prescaler */
+ uint32_t brp_max;
+ uint32_t brp_inc;
+};
+
+#endif /*_CAN_BITTIMING_H*/
--- /dev/null
+/**************************************************************************/
+/* File: can_queue.h - CAN queues and message passing infrastructure */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+#ifndef _CAN_QUEUE_H
+#define _CAN_QUEUE_H
+
+#include "./canmsg.h"
+#include "./constants.h"
+#include "./can_sysdep.h"
+
+/**
+ * struct canque_slot_t - one CAN message slot in the CAN FIFO queue
+ * @next: pointer to the next/younger slot
+ * @slot_flags: space for flags and optional command describing action
+ * associated with slot data
+ * @msg: space for one CAN message
+ *
+ * This structure is used to store CAN messages in the CAN FIFO queue.
+ */
+ struct canque_slot_t {
+ struct canque_slot_t *next;
+ unsigned long slot_flags;
+ struct canmsg_t msg;
+};
+
+#define CAN_SLOTF_CMD 0x00ff /* */
+
+/**
+ * struct canque_fifo_t - CAN FIFO queue representation
+ * @fifo_flags: this field holds global flags describing state of the FIFO.
+ * %CAN_FIFOF_ERROR is set when some error condition occurs.
+ * %CAN_FIFOF_ERR2BLOCK defines, that error should lead to the FIFO block state.
+ * %CAN_FIFOF_BLOCK state blocks insertion of the next messages.
+ * %CAN_FIFOF_OVERRUN attempt to acquire new slot, when FIFO is full.
+ * %CAN_FIFOF_FULL indicates FIFO full state.
+ * %CAN_FIFOF_EMPTY indicates no allocated slot in the FIFO.
+ * %CAN_FIFOF_DEAD condition indication. Used when FIFO is beeing destroyed.
+ * @error_code: futher description of error condition
+ * @head: pointer to the FIFO head, oldest slot
+ * @tail: pointer to the location, where pointer to newly inserted slot
+ * should be added
+ * @flist: pointer to list of the free slots associated with queue
+ * @entry: pointer to the memory allocated for the list slots.
+ * @fifo_lock: the lock to ensure atomicity of slot manipulation operations.
+ * @slotsnr: number of allocated slots
+ *
+ * This structure represents CAN FIFO queue. It is implemented as
+ * a single linked list of slots prepared for processing. The empty slots
+ * are stored in single linked list (@flist).
+ */
+struct canque_fifo_t {
+ unsigned long fifo_flags;
+ unsigned long error_code;
+ struct canque_slot_t *head; /* points to the oldest entry */
+ struct canque_slot_t **tail; /* points to NULL pointer for chaining */
+ struct canque_slot_t *flist; /* points the first entry in the free list */
+ struct canque_slot_t *entry; /* points to first allocated entry */
+ can_spinlock_t fifo_lock; /* can_spin_lock_irqsave / can_spin_unlock_irqrestore */
+ int slotsnr;
+};
+
+#define CAN_FIFOF_DESTROY_b 15
+#define CAN_FIFOF_ERROR_b 14
+#define CAN_FIFOF_ERR2BLOCK_b 13
+#define CAN_FIFOF_BLOCK_b 12
+#define CAN_FIFOF_OVERRUN_b 11
+#define CAN_FIFOF_FULL_b 10
+#define CAN_FIFOF_EMPTY_b 9
+#define CAN_FIFOF_DEAD_b 8
+#define CAN_FIFOF_INACTIVE_b 7
+#define CAN_FIFOF_FREEONEMPTY_b 6
+#define CAN_FIFOF_READY_b 5
+#define CAN_FIFOF_NOTIFYPEND_b 4
+#define CAN_FIFOF_RTL_MEM_b 3
+
+#define CAN_FIFOF_DESTROY (1<<CAN_FIFOF_DESTROY_b)
+#define CAN_FIFOF_ERROR (1<<CAN_FIFOF_ERROR_b)
+#define CAN_FIFOF_ERR2BLOCK (1<<CAN_FIFOF_ERR2BLOCK_b)
+#define CAN_FIFOF_BLOCK (1<<CAN_FIFOF_BLOCK_b)
+#define CAN_FIFOF_OVERRUN (1<<CAN_FIFOF_OVERRUN_b)
+#define CAN_FIFOF_FULL (1<<CAN_FIFOF_FULL_b)
+#define CAN_FIFOF_EMPTY (1<<CAN_FIFOF_EMPTY_b)
+#define CAN_FIFOF_DEAD (1<<CAN_FIFOF_DEAD_b)
+#define CAN_FIFOF_INACTIVE (1<<CAN_FIFOF_INACTIVE_b)
+#define CAN_FIFOF_FREEONEMPTY (1<<CAN_FIFOF_FREEONEMPTY_b)
+#define CAN_FIFOF_READY (1<<CAN_FIFOF_READY_b)
+#define CAN_FIFOF_NOTIFYPEND (1<<CAN_FIFOF_NOTIFYPEND_b)
+#define CAN_FIFOF_RTL_MEM (1<<CAN_FIFOF_RTL_MEM_b)
+
+#define canque_fifo_test_fl(fifo,fifo_fl) \
+ test_bit(CAN_FIFOF_##fifo_fl##_b,&(fifo)->fifo_flags)
+#define canque_fifo_set_fl(fifo,fifo_fl) \
+ set_bit(CAN_FIFOF_##fifo_fl##_b,&(fifo)->fifo_flags)
+#define canque_fifo_clear_fl(fifo,fifo_fl) \
+ clear_bit(CAN_FIFOF_##fifo_fl##_b,&(fifo)->fifo_flags)
+#define canque_fifo_test_and_set_fl(fifo,fifo_fl) \
+ test_and_set_bit(CAN_FIFOF_##fifo_fl##_b,&(fifo)->fifo_flags)
+#define canque_fifo_test_and_clear_fl(fifo,fifo_fl) \
+ test_and_clear_bit(CAN_FIFOF_##fifo_fl##_b,&(fifo)->fifo_flags)
+
+
+/**
+ * canque_fifo_get_inslot - allocate slot for the input of one CAN message
+ * @fifo: pointer to the FIFO structure
+ * @slotp: pointer to location to store pointer to the allocated slot.
+ * @cmd: optional command associated with allocated slot.
+ *
+ * Return Value: The function returns negative value if there is no
+ * free slot in the FIFO queue.
+ */
+static inline
+int canque_fifo_get_inslot(struct canque_fifo_t *fifo, struct canque_slot_t **slotp, int cmd)
+{
+ can_spin_irqflags_t flags;
+ struct canque_slot_t *slot;
+ can_spin_lock_irqsave(&fifo->fifo_lock, flags);
+ /* get the first free slot slot from flist */
+ if(!(slot=fifo->flist)) {
+ canque_fifo_set_fl(fifo,OVERRUN);
+ canque_fifo_set_fl(fifo,FULL);
+ can_spin_unlock_irqrestore(&fifo->fifo_lock, flags);
+ *slotp=NULL;
+ return -1;
+ }
+ /* adjust free slot list */
+ if(!(fifo->flist=slot->next))
+ canque_fifo_set_fl(fifo,FULL);
+ can_spin_unlock_irqrestore(&fifo->fifo_lock, flags);
+ *slotp=slot;
+ slot->slot_flags=cmd&CAN_SLOTF_CMD;
+ return 1;
+}
+
+/**
+ * canque_fifo_put_inslot - releases slot to further processing
+ * @fifo: pointer to the FIFO structure
+ * @slot: pointer to the slot previously acquired by canque_fifo_get_inslot().
+ *
+ * Return Value: The nonzero return value indicates, that the queue was empty
+ * before call to the function. The caller should wake-up output side of the queue.
+ */
+static inline
+int canque_fifo_put_inslot(struct canque_fifo_t *fifo, struct canque_slot_t *slot)
+{
+ int ret;
+ can_spin_irqflags_t flags;
+ slot->next=NULL;
+ can_spin_lock_irqsave(&fifo->fifo_lock, flags);
+ if(*fifo->tail) can_printk(KERN_CRIT "canque_fifo_put_inslot: fifo->tail != NULL\n");
+ *fifo->tail=slot;
+ fifo->tail=&slot->next;
+ ret=0;
+ if(canque_fifo_test_and_clear_fl(fifo,EMPTY))
+ ret=CAN_FIFOF_EMPTY; /* Fifo has been empty before put */
+ if(canque_fifo_test_and_clear_fl(fifo,INACTIVE))
+ ret=CAN_FIFOF_INACTIVE; /* Fifo has been empty before put */
+ can_spin_unlock_irqrestore(&fifo->fifo_lock, flags);
+ return ret;
+}
+
+/**
+ * canque_fifo_abort_inslot - release and abort slot
+ * @fifo: pointer to the FIFO structure
+ * @slot: pointer to the slot previously acquired by canque_fifo_get_inslot().
+ *
+ * Return Value: The nonzero value indicates, that fifo was full
+ */
+static inline
+int canque_fifo_abort_inslot(struct canque_fifo_t *fifo, struct canque_slot_t *slot)
+{
+ int ret=0;
+ can_spin_irqflags_t flags;
+ can_spin_lock_irqsave(&fifo->fifo_lock, flags);
+ slot->next=fifo->flist;
+ fifo->flist=slot;
+ if(canque_fifo_test_and_clear_fl(fifo,FULL))
+ ret=CAN_FIFOF_FULL;
+ can_spin_unlock_irqrestore(&fifo->fifo_lock, flags);
+ return ret;
+}
+
+/**
+ * canque_fifo_test_outslot - test and get ready slot from the FIFO
+ * @fifo: pointer to the FIFO structure
+ * @slotp: pointer to location to store pointer to the oldest slot from the FIFO.
+ *
+ * Return Value: The negative value indicates, that queue is empty.
+ * The positive or zero value represents command stored into slot by
+ * the call to the function canque_fifo_get_inslot().
+ * The successfully acquired FIFO output slot has to be released by
+ * the call canque_fifo_free_outslot() or canque_fifo_again_outslot().
+ */
+static inline
+int canque_fifo_test_outslot(struct canque_fifo_t *fifo, struct canque_slot_t **slotp)
+{
+ can_spin_irqflags_t flags;
+ int cmd;
+ struct canque_slot_t *slot;
+ can_spin_lock_irqsave(&fifo->fifo_lock, flags);
+ if(!(slot=fifo->head)){;
+ canque_fifo_set_fl(fifo,EMPTY);
+ can_spin_unlock_irqrestore(&fifo->fifo_lock, flags);
+ *slotp=NULL;
+ return -1;
+ }
+ if(!(fifo->head=slot->next))
+ fifo->tail=&fifo->head;
+ can_spin_unlock_irqrestore(&fifo->fifo_lock, flags);
+
+ *slotp=slot;
+ cmd=slot->slot_flags;
+ return cmd&CAN_SLOTF_CMD;
+}
+
+
+/**
+ * canque_fifo_free_outslot - free processed FIFO slot
+ * @fifo: pointer to the FIFO structure
+ * @slot: pointer to the slot previously acquired by canque_fifo_test_outslot().
+ *
+ * Return Value: The returned value informs about FIFO state change.
+ * The mask %CAN_FIFOF_FULL indicates, that the FIFO was full before
+ * the function call. The mask %CAN_FIFOF_EMPTY informs, that last ready slot
+ * has been processed.
+ */
+static inline
+int canque_fifo_free_outslot(struct canque_fifo_t *fifo, struct canque_slot_t *slot)
+{
+ int ret=0;
+ can_spin_irqflags_t flags;
+ can_spin_lock_irqsave(&fifo->fifo_lock, flags);
+ slot->next=fifo->flist;
+ fifo->flist=slot;
+ if(canque_fifo_test_and_clear_fl(fifo,FULL))
+ ret=CAN_FIFOF_FULL;
+ if(!(fifo->head)){
+ canque_fifo_set_fl(fifo,EMPTY);
+ ret|=CAN_FIFOF_EMPTY;
+ }
+ can_spin_unlock_irqrestore(&fifo->fifo_lock, flags);
+ return ret;
+}
+
+/**
+ * canque_fifo_again_outslot - interrupt and postpone processing of the slot
+ * @fifo: pointer to the FIFO structure
+ * @slot: pointer to the slot previously acquired by canque_fifo_test_outslot().
+ *
+ * Return Value: The function cannot fail..
+ */
+static inline
+int canque_fifo_again_outslot(struct canque_fifo_t *fifo, struct canque_slot_t *slot)
+{
+ can_spin_irqflags_t flags;
+ can_spin_lock_irqsave(&fifo->fifo_lock, flags);
+ if(!(slot->next=fifo->head))
+ fifo->tail=&slot->next;
+ fifo->head=slot;
+ can_spin_unlock_irqrestore(&fifo->fifo_lock, flags);
+ return 1;
+}
+
+int canque_fifo_flush_slots(struct canque_fifo_t *fifo);
+
+int canque_fifo_init_slots(struct canque_fifo_t *fifo);
+
+#define CANQUEUE_PRIO_NR 3
+
+/* Forward declarations for external types */
+struct msgobj_t;
+struct canchip_t;
+
+/**
+ * struct canque_edge_t - CAN message delivery subsystem graph edge
+ * @fifo: place where primitive @struct canque_fifo_t FIFO is located.
+ * @filtid: the possible CAN message identifiers filter.
+ * @filtmask: the filter mask, the comparison considers only
+ * @filtid bits corresponding to set bits in the @filtmask field.
+ * @inpeers: the lists of all peers FIFOs connected by their
+ * input side (@inends) to the same terminal (@struct canque_ends_t).
+ * @outpeers: the lists of all peers FIFOs connected by their
+ * output side (@outends) to the same terminal (@struct canque_ends_t).
+ * @activepeers: the lists of peers FIFOs connected by their
+ * output side (@outends) to the same terminal (@struct canque_ends_t)
+ * with same priority and active state.
+ * @inends: the pointer to the FIFO input side terminal (@struct canque_ends_t).
+ * @outends: the pointer to the FIFO output side terminal (@struct canque_ends_t).
+ * @edge_used: the atomic usage counter, mainly used for safe destruction of the edge.
+ * @edge_prio: the assigned queue priority from the range 0 to %CANQUEUE_PRIO_NR-1
+ * @edge_num: edge sequential number intended for debugging purposes only
+ * @pending_peers: edges with pending delayed events (RTL->Linux calls)
+ * @pending_inops: bitmask of pending operations
+ * @pending_outops: bitmask of pending operations
+ *
+ * This structure represents one direction connection from messages source
+ * (@inends) to message consumer (@outends) fifo ends hub. The edge contains
+ * &struct canque_fifo_t for message fifo implementation.
+ */
+struct canque_edge_t {
+ struct canque_fifo_t fifo;
+ unsigned long filtid;
+ unsigned long filtmask;
+ struct list_head inpeers;
+ struct list_head outpeers;
+ struct list_head activepeers;
+ struct canque_ends_t *inends;
+ struct canque_ends_t *outends;
+ atomic_t edge_used;
+ int edge_prio;
+ int edge_num;
+ #ifdef CAN_WITH_RTL
+ struct list_head pending_peers;
+ unsigned long pending_inops;
+ unsigned long pending_outops;
+ #endif /*CAN_WITH_RTL*/
+};
+
+/**
+ * struct canque_ends_t - CAN message delivery subsystem graph vertex (FIFO ends)
+ * @ends_flags: this field holds flags describing state of the ENDS structure.
+ * @active: the array of the lists of active edges directed to the ends structure
+ * with ready messages. The array is indexed by the edges priorities.
+ * @idle: the list of the edges directed to the ends structure with empty FIFOs.
+ * @inlist: the list of outgoing edges input sides.
+ * @outlist: the list of all incoming edges output sides. Each of there edges
+ * is listed on one of @active or @idle lists.
+ * @ends_lock: the lock synchronizing operations between threads accessing
+ * same ends structure.
+ * @notify: pointer to notify procedure. The next state changes are notified.
+ * %CANQUEUE_NOTIFY_EMPTY (out->in call) - all slots are processed by FIFO out side.
+ * %CANQUEUE_NOTIFY_SPACE (out->in call) - full state negated => there is space for new message.
+ * %CANQUEUE_NOTIFY_PROC (in->out call) - empty state negated => out side is requested to process slots.
+ * %CANQUEUE_NOTIFY_NOUSR (both) - notify, that the last user has released the edge usage
+ * called with some lock to prevent edge disappear.
+ * %CANQUEUE_NOTIFY_DEAD (both) - edge is in progress of deletion.
+ * %CANQUEUE_NOTIFY_ATACH (both) - new edge has been attached to end.
+ * %CANQUEUE_NOTIFY_FILTCH (out->in call) - edge filter rules changed
+ * %CANQUEUE_NOTIFY_ERROR (out->in call) - error in messages processing.
+ * @context: space to store ends user specific information
+ * @endinfo: space to store some other ends usage specific informations
+ * mainly for waking-up by the notify calls.
+ * @dead_peers: used to chain ends wanting for postponed destruction
+ *
+ * Structure represents place to connect edges to for CAN communication entity.
+ * The zero, one or more incoming and outgoing edges can be connected to
+ * this structure.
+ */
+struct canque_ends_t {
+ unsigned long ends_flags;
+ struct list_head active[CANQUEUE_PRIO_NR];
+ struct list_head idle;
+ struct list_head inlist;
+ struct list_head outlist;
+ can_spinlock_t ends_lock; /* can_spin_lock_irqsave / can_spin_unlock_irqrestore */
+ void (*notify)(struct canque_ends_t *qends, struct canque_edge_t *qedge, int what);
+ void *context;
+ union {
+ struct {
+ wait_queue_head_t readq;
+ wait_queue_head_t writeq;
+ wait_queue_head_t emptyq;
+ #ifdef CAN_ENABLE_KERN_FASYNC
+ struct fasync_struct *fasync;
+ #endif /*CAN_ENABLE_KERN_FASYNC*/
+ } fileinfo;
+ #ifdef CAN_WITH_RTL
+ struct {
+ rtl_spinlock_t rtl_lock;
+ rtl_wait_t rtl_readq;
+ atomic_t rtl_readq_age;
+ rtl_wait_t rtl_writeq;
+ atomic_t rtl_writeq_age;
+ rtl_wait_t rtl_emptyq;
+ atomic_t rtl_emptyq_age;
+ unsigned long pend_flags;
+ } rtlinfo;
+ #endif /*CAN_WITH_RTL*/
+ struct {
+ struct msgobj_t *msgobj;
+ struct canchip_t *chip;
+ #ifndef CAN_WITH_RTL
+ wait_queue_head_t daemonq;
+ #else /*CAN_WITH_RTL*/
+ pthread_t worker_thread;
+ #endif /*CAN_WITH_RTL*/
+ } chipinfo;
+ } endinfo;
+ struct list_head dead_peers;
+};
+
+#define CANQUEUE_NOTIFY_EMPTY 1 /* out -> in - all slots are processed by FIFO out side */
+#define CANQUEUE_NOTIFY_SPACE 2 /* out -> in - full state negated => there is space for new message */
+#define CANQUEUE_NOTIFY_PROC 3 /* in -> out - empty state negated => out side is requested to process slots */
+#define CANQUEUE_NOTIFY_NOUSR 4 /* called with some lock to prevent edge disappear */
+#define CANQUEUE_NOTIFY_DEAD 5 /* */
+#define CANQUEUE_NOTIFY_DEAD_WANTED 6 /* */
+#define CANQUEUE_NOTIFY_ATTACH 7 /* */
+#define CANQUEUE_NOTIFY_FILTCH 8 /* filter changed */
+#define CANQUEUE_NOTIFY_ERROR 0x10000 /* error notifiers */
+#define CANQUEUE_NOTIFY_ERRTX_PREP 0x11001 /* tx preparation error */
+#define CANQUEUE_NOTIFY_ERRTX_SEND 0x11002 /* tx send error */
+#define CANQUEUE_NOTIFY_ERRTX_BUS 0x11003 /* tx bus error */
+
+#define CAN_ENDSF_DEAD (1<<0)
+#define CAN_ENDSF_MEM_RTL (1<<1)
+
+/**
+ * canque_notify_inends - request to send notification to the input ends
+ * @qedge: pointer to the edge structure
+ * @what: notification type
+ */
+static inline
+void canque_notify_inends(struct canque_edge_t *qedge, int what)
+{
+ if(qedge->inends)
+ if(qedge->inends->notify)
+ qedge->inends->notify(qedge->inends,qedge,what);
+}
+
+/**
+ * canque_notify_outends - request to send notification to the output ends
+ * @qedge: pointer to the edge structure
+ * @what: notification type
+ */
+static inline
+void canque_notify_outends(struct canque_edge_t *qedge, int what)
+{
+ if(qedge->outends)
+ if(qedge->outends->notify)
+ qedge->outends->notify(qedge->outends,qedge,what);
+}
+
+/**
+ * canque_notify_bothends - request to send notification to the both ends
+ * @qedge: pointer to the edge structure
+ * @what: notification type
+ */
+static inline
+void canque_notify_bothends(struct canque_edge_t *qedge, int what)
+{
+ canque_notify_inends(qedge, what);
+ canque_notify_outends(qedge, what);
+}
+
+/**
+ * canque_activate_edge - mark output end of the edge as active
+ * @qedge: pointer to the edge structure
+ * @inends: input side of the edge
+ *
+ * Function call moves output side of the edge from idle onto active edges
+ * list. This function has to be called with edge reference count held.
+ * that is same as for most of other edge functions.
+ */
+static inline
+void canque_activate_edge(struct canque_ends_t *inends, struct canque_edge_t *qedge)
+{
+ can_spin_irqflags_t flags;
+ struct canque_ends_t *outends;
+ if(qedge->edge_prio>=CANQUEUE_PRIO_NR)
+ qedge->edge_prio=CANQUEUE_PRIO_NR-1;
+ if((outends=qedge->outends)){
+ can_spin_lock_irqsave(&outends->ends_lock, flags);
+ can_spin_lock(&qedge->fifo.fifo_lock);
+ if(!canque_fifo_test_fl(&qedge->fifo,EMPTY)){
+ list_del(&qedge->activepeers);
+ list_add_tail(&qedge->activepeers,&outends->active[qedge->edge_prio]);
+ }
+ can_spin_unlock(&qedge->fifo.fifo_lock);
+ can_spin_unlock_irqrestore(&outends->ends_lock, flags);
+ }
+}
+
+/**
+ * canque_filtid2internal - converts message ID and filter flags into internal format
+ * @id: CAN message 11 or 29 bit identifier
+ * @filtflags: CAN message flags
+ *
+ * This function maps message ID and %MSG_RTR, %MSG_EXT and %MSG_LOCAL into one 32 bit number
+ */
+static inline
+unsigned int canque_filtid2internal(unsigned long id, int filtflags)
+{
+ filtflags &= MSG_RTR|MSG_EXT|MSG_LOCAL;
+ filtflags += filtflags&MSG_RTR;
+ return (id&MSG_ID_MASK) | (filtflags<<28);
+}
+
+int canque_get_inslot(struct canque_ends_t *qends,
+ struct canque_edge_t **qedgep, struct canque_slot_t **slotp, int cmd);
+
+int canque_get_inslot4id(struct canque_ends_t *qends,
+ struct canque_edge_t **qedgep, struct canque_slot_t **slotp,
+ int cmd, unsigned long id, int prio);
+
+int canque_put_inslot(struct canque_ends_t *qends,
+ struct canque_edge_t *qedge, struct canque_slot_t *slot);
+
+int canque_abort_inslot(struct canque_ends_t *qends,
+ struct canque_edge_t *qedge, struct canque_slot_t *slot);
+
+int canque_filter_msg2edges(struct canque_ends_t *qends, struct canmsg_t *msg);
+
+int canque_test_outslot(struct canque_ends_t *qends,
+ struct canque_edge_t **qedgep, struct canque_slot_t **slotp);
+
+int canque_free_outslot(struct canque_ends_t *qends,
+ struct canque_edge_t *qedge, struct canque_slot_t *slot);
+
+int canque_again_outslot(struct canque_ends_t *qends,
+ struct canque_edge_t *qedge, struct canque_slot_t *slot);
+
+int canque_set_filt(struct canque_edge_t *qedge,
+ unsigned long filtid, unsigned long filtmask, int flags);
+
+int canque_flush(struct canque_edge_t *qedge);
+
+int canqueue_disconnect_edge(struct canque_edge_t *qedge);
+
+int canqueue_connect_edge(struct canque_edge_t *qedge, struct canque_ends_t *inends, struct canque_ends_t *outends);
+
+int canqueue_ends_init_gen(struct canque_ends_t *qends);
+
+void canqueue_block_inlist(struct canque_ends_t *qends);
+
+void canqueue_block_outlist(struct canque_ends_t *qends);
+
+int canqueue_ends_kill_inlist(struct canque_ends_t *qends, int send_rest);
+
+int canqueue_ends_kill_outlist(struct canque_ends_t *qends);
+
+int canqueue_ends_filt_conjuction(struct canque_ends_t *qends, struct canfilt_t *filt);
+
+int canqueue_ends_flush_inlist(struct canque_ends_t *qends);
+
+int canqueue_ends_flush_outlist(struct canque_ends_t *qends);
+
+/* edge reference and traversal functions */
+
+void canque_edge_do_dead(struct canque_edge_t *edge);
+
+/**
+ * canque_edge_incref - increments edge reference count
+ * @edge: pointer to the edge structure
+ */
+static inline
+void canque_edge_incref(struct canque_edge_t *edge)
+{
+ atomic_inc(&edge->edge_used);
+}
+
+static inline
+can_spin_irqflags_t canque_edge_lock_both_ends(struct canque_ends_t *inends, struct canque_ends_t *outends)
+{
+ can_spin_irqflags_t flags;
+ if(inends<outends) {
+ can_spin_lock_irqsave(&inends->ends_lock, flags);
+ can_spin_lock(&outends->ends_lock);
+ }else{
+ can_spin_lock_irqsave(&outends->ends_lock, flags);
+ if(outends!=inends) can_spin_lock(&inends->ends_lock);
+ }
+ return flags;
+}
+
+static inline
+void canque_edge_unlock_both_ends(struct canque_ends_t *inends, struct canque_ends_t *outends, can_spin_irqflags_t flags)
+{
+ if(outends!=inends) can_spin_unlock(&outends->ends_lock);
+ can_spin_unlock_irqrestore(&inends->ends_lock, flags);
+}
+
+/* Non-inlined version of edge reference decrement */
+void __canque_edge_decref(struct canque_edge_t *edge);
+
+static inline
+void __canque_edge_decref_body(struct canque_edge_t *edge)
+{
+ can_spin_irqflags_t flags;
+ int dead_fl=0;
+ struct canque_ends_t *inends=edge->inends;
+ struct canque_ends_t *outends=edge->outends;
+
+ flags=canque_edge_lock_both_ends(inends, outends);
+ if(atomic_dec_and_test(&edge->edge_used)) {
+ dead_fl=!canque_fifo_test_and_set_fl(&edge->fifo,DEAD);
+ /* Because of former evolution of edge references
+ management notify of CANQUEUE_NOTIFY_NOUSR could
+ be moved to canque_edge_do_dead :-) */
+ }
+ canque_edge_unlock_both_ends(inends, outends, flags);
+ if(dead_fl) canque_edge_do_dead(edge);
+}
+
+#ifndef CAN_HAVE_ARCH_CMPXCHG
+/**
+ * canque_edge_decref - decrements edge reference count
+ * @edge: pointer to the edge structure
+ *
+ * This function has to be called without lock held for both ends of edge.
+ * If reference count drops to 0, function canque_edge_do_dead()
+ * is called.
+ */
+static inline
+void canque_edge_decref(struct canque_edge_t *edge)
+{
+ __canque_edge_decref_body(edge);
+}
+#else
+static inline
+void canque_edge_decref(struct canque_edge_t *edge)
+{
+ int x, y;
+
+ x = atomic_read(&edge->edge_used);
+ do{
+ if(x<=1)
+ return __canque_edge_decref(edge);
+ y=x;
+ #ifdef CAN_HAVE_ATOMIC_CMPXCHG
+ atomic_cmpxchg(&edge->edge_used, x, x-1);
+ #else /* workaround for case that atomic_cmpxchg is not defined */
+ /* This code strongly depends on the definition of atomic_t !!!! */
+ x=__cmpxchg(&edge->edge_used, x, x-1, sizeof(atomic_t));
+ /* If even this does not help, comment out CAN_HAVE_ARCH_CMPXCHG in can_sysdep.h */
+ #endif
+ } while(x!=y);
+}
+#endif
+
+static inline
+struct canque_edge_t *canque_first_inedge(struct canque_ends_t *qends)
+{
+ can_spin_irqflags_t flags;
+ struct list_head *entry;
+ struct canque_edge_t *edge;
+
+ can_spin_lock_irqsave(&qends->ends_lock, flags);
+ entry=qends->inlist.next;
+ skip_dead:
+ if(entry != &qends->inlist) {
+ edge=list_entry(entry,struct canque_edge_t,inpeers);
+ if(canque_fifo_test_fl(&edge->fifo,DEAD)) {
+ entry=entry->next;
+ goto skip_dead;
+ }
+ canque_edge_incref(edge);
+ } else {
+ edge=NULL;
+ }
+ can_spin_unlock_irqrestore(&qends->ends_lock, flags);
+ return edge;
+}
+
+
+static inline
+struct canque_edge_t *canque_next_inedge(struct canque_ends_t *qends, struct canque_edge_t *edge)
+{
+ can_spin_irqflags_t flags;
+ struct list_head *entry;
+ struct canque_edge_t *next;
+
+ can_spin_lock_irqsave(&qends->ends_lock, flags);
+ entry=edge->inpeers.next;
+ skip_dead:
+ if(entry != &qends->inlist) {
+ next=list_entry(entry,struct canque_edge_t,inpeers);
+ if(canque_fifo_test_fl(&edge->fifo,DEAD)) {
+ entry=entry->next;
+ goto skip_dead;
+ }
+ canque_edge_incref(next);
+ } else {
+ next=NULL;
+ }
+ can_spin_unlock_irqrestore(&qends->ends_lock, flags);
+ canque_edge_decref(edge);
+ return next;
+}
+
+#define canque_for_each_inedge(qends, edge) \
+ for(edge=canque_first_inedge(qends);edge;edge=canque_next_inedge(qends, edge))
+
+static inline
+struct canque_edge_t *canque_first_outedge(struct canque_ends_t *qends)
+{
+ can_spin_irqflags_t flags;
+ struct list_head *entry;
+ struct canque_edge_t *edge;
+
+ can_spin_lock_irqsave(&qends->ends_lock, flags);
+ entry=qends->outlist.next;
+ skip_dead:
+ if(entry != &qends->outlist) {
+ edge=list_entry(entry,struct canque_edge_t,outpeers);
+ if(canque_fifo_test_fl(&edge->fifo,DEAD)) {
+ entry=entry->next;
+ goto skip_dead;
+ }
+ canque_edge_incref(edge);
+ } else {
+ edge=NULL;
+ }
+ can_spin_unlock_irqrestore(&qends->ends_lock, flags);
+ return edge;
+}
+
+
+static inline
+struct canque_edge_t *canque_next_outedge(struct canque_ends_t *qends, struct canque_edge_t *edge)
+{
+ can_spin_irqflags_t flags;
+ struct list_head *entry;
+ struct canque_edge_t *next;
+
+ can_spin_lock_irqsave(&qends->ends_lock, flags);
+ entry=edge->outpeers.next;
+ skip_dead:
+ if(entry != &qends->outlist) {
+ next=list_entry(entry,struct canque_edge_t,outpeers);
+ if(canque_fifo_test_fl(&edge->fifo,DEAD)) {
+ entry=entry->next;
+ goto skip_dead;
+ }
+ canque_edge_incref(next);
+ } else {
+ next=NULL;
+ }
+ can_spin_unlock_irqrestore(&qends->ends_lock, flags);
+ canque_edge_decref(edge);
+ return next;
+}
+
+#define canque_for_each_outedge(qends, edge) \
+ for(edge=canque_first_outedge(qends);edge;edge=canque_next_outedge(qends, edge))
+
+/* Linux kernel specific functions */
+
+int canque_fifo_init_kern(struct canque_fifo_t *fifo, int slotsnr);
+
+int canque_fifo_done_kern(struct canque_fifo_t *fifo);
+
+struct canque_edge_t *canque_new_edge_kern(int slotsnr);
+
+int canque_get_inslot4id_wait_kern(struct canque_ends_t *qends,
+ struct canque_edge_t **qedgep, struct canque_slot_t **slotp,
+ int cmd, unsigned long id, int prio);
+
+int canque_get_outslot_wait_kern(struct canque_ends_t *qends,
+ struct canque_edge_t **qedgep, struct canque_slot_t **slotp);
+
+int canque_sync_wait_kern(struct canque_ends_t *qends, struct canque_edge_t *qedge);
+
+int canqueue_ends_init_kern(struct canque_ends_t *qends);
+
+int canqueue_ends_dispose_kern(struct canque_ends_t *qends, int sync);
+
+void canqueue_ends_dispose_postpone(struct canque_ends_t *qends);
+
+void canqueue_kern_initialize(void);
+
+#ifdef CAN_WITH_RTL
+
+extern struct tasklet_struct canque_dead_tl; /*publication required only for RTL*/
+
+/* RT-Linux specific functions and variables */
+
+extern int canqueue_rtl_irq;
+
+extern unsigned long canqueue_rtl2lin_pend;
+
+#define CAN_RTL2LIN_PEND_DEAD_b 0
+
+void canqueue_rtl_initialize(void);
+void canqueue_rtl_done(void);
+
+int canqueue_rtl2lin_check_and_pend(struct canque_ends_t *qends,
+ struct canque_edge_t *qedge, int what);
+
+struct canque_edge_t *canque_new_edge_rtl(int slotsnr);
+
+void canque_dispose_edge_rtl(struct canque_edge_t *qedge);
+
+int canque_get_inslot4id_wait_rtl(struct canque_ends_t *qends,
+ struct canque_edge_t **qedgep, struct canque_slot_t **slotp,
+ int cmd, unsigned long id, int prio);
+
+int canque_get_outslot_wait_rtl(struct canque_ends_t *qends,
+ struct canque_edge_t **qedgep, struct canque_slot_t **slotp);
+
+int canque_sync_wait_rtl(struct canque_ends_t *qends, struct canque_edge_t *qedge);
+
+void canque_ends_free_rtl(struct canque_ends_t *qends);
+
+int canqueue_ends_init_rtl(struct canque_ends_t *qends);
+
+int canqueue_ends_dispose_rtl(struct canque_ends_t *qends, int sync);
+
+#else /*CAN_WITH_RTL*/
+
+static inline int canqueue_rtl2lin_check_and_pend(struct canque_ends_t *qends,
+ struct canque_edge_t *qedge, int what) { return 0; }
+
+#endif /*CAN_WITH_RTL*/
+
+
+#endif /*_CAN_QUEUE_H*/
--- /dev/null
+#include "can_sysless.h"
--- /dev/null
+/**************************************************************************/
+/* File: can_sysless.h - provides can_sysdep.h definitions to hide */
+/* between Linux kernel and embedded target build */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+#ifndef _CAN_SYSDEP_H
+#define _CAN_SYSDEP_H
+
+
+#include <cpu_def.h>
+#include <malloc.h>
+
+// typedef unsigned long atomic_t;
+typedef struct { volatile int counter; } atomic_t;
+
+#define mb() __memory_barrier()
+
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+
+
+#define wait_queue_head_t struct wait_queue *
+#define wait_queue_t struct wait_queue
+#define init_waitqueue_head(queue_head) (*queue_head=NULL)
+#define init_waitqueue_entry(qentry,qtask) \
+ (qentry->next=NULL,qentry->task=qtask)
+#define DECLARE_WAIT_QUEUE_HEAD(name) \
+ struct wait_queue * name=NULL
+#define DECLARE_WAITQUEUE(wait, current) \
+ struct wait_queue wait = { current, NULL }
+
+typedef irqreturn_t can_irqreturn_t;
+#define CAN_IRQ_NONE IRQ_NONE
+#define CAN_IRQ_HANDLED IRQ_HANDLED
+#define CAN_IRQ_RETVAL IRQ_RETVAL
+
+#define CAN_IRQ_HANDLER_ARGS(irq_number, dev_id) \
+ int irq_number, void *dev_id
+#define can_synchronize_irq(irqnum) do {} while(0)
+
+typedef unsigned long can_ioptr_t;
+#define can_ioptr2ulong(ioaddr) ((unsigned long)(ioaddr))
+#define can_ulong2ioptr(addr) ((unsigned long)(addr))
+#define can_inb(ioaddr) inb(ioaddr)
+#define can_outb(data,ioaddr) outb(data,ioaddr)
+#define can_inw(ioaddr) inb(ioaddr)
+#define can_outw(data,ioaddr) outb(data,ioaddr)
+#define can_inl(ioaddr) inb(ioaddr)
+#define can_outl(data,ioaddr) outb(data,ioaddr)
+
+#define can_readb readb
+#define can_writeb writeb
+#define can_readw readw
+#define can_writew writew
+#define can_readl readl
+#define can_writel writel
+
+#define can_ioport2ioptr can_ulong2ioptr
+
+#ifdef __HAVE_ARCH_CMPXCHG
+ #define CAN_HAVE_ARCH_CMPXCHG
+#endif
+
+#define can_spinlock_t long
+#define can_spin_irqflags_t unsigned long
+/* Only one CPU is supposed on sys-less embedded target => no need for spinloks */
+#define can_spin_lock(lock) do { } while (0)
+#define can_spin_unlock(lock) do { } while (0)
+/* Only one CPU is supposed on sys-less embedded target => no need for spinloks */
+#define can_spin_lock_irqsave(lock,flags) save_and_cli(flags)
+#define can_spin_unlock_irqrestore(lock,flags) restore_flags(flags)
+#define can_spin_lock_init can_splck_init
+
+#define CAN_DEFINE_SPINLOCK(x) can_spinlock_t x = 0
+
+static inline
+void can_splck_init(can_spinlock_t *x)
+{
+ *x=0;
+}
+
+#define can_preempt_disable() do { } while (0)
+#define can_preempt_enable() do { } while (0)
+
+#if 1
+#define can_enable_irq(var) do { } while (0)
+#define can_disable_irq(var) do { } while (0)
+#else
+#define can_enable_irq enable_irq
+#define can_disable_irq disable_irq
+#endif
+
+#define can_printk printf
+#define KERN_CRIT
+#define KERN_ERR
+
+/// LINUX src: include/asm-arm/bitops.h
+
+#define set_bit ____atomic_set_bit
+#define clear_bit ____atomic_clear_bit
+#define change_bit ____atomic_change_bit
+#define test_and_set_bit ____atomic_test_and_set_bit
+#define test_and_clear_bit ____atomic_test_and_clear_bit
+#define test_and_change_bit ____atomic_test_and_change_bit
+#define raw_local_irq_save(flags) save_and_cli(flags);
+#define raw_local_irq_restore(flags) restore_flags(flags);
+
+/*
+ * These functions are the basis of our bit ops.
+ *
+ * First, the atomic bitops. These use native endian.
+ */
+static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ raw_local_irq_save(flags);
+ *p |= mask;
+ raw_local_irq_restore(flags);
+}
+
+static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ raw_local_irq_save(flags);
+ *p &= ~mask;
+ raw_local_irq_restore(flags);
+}
+
+static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ raw_local_irq_save(flags);
+ *p ^= mask;
+ raw_local_irq_restore(flags);
+}
+
+static inline int
+____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned int res;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ raw_local_irq_save(flags);
+ res = *p;
+ *p = res | mask;
+ raw_local_irq_restore(flags);
+
+ return res & mask;
+}
+
+static inline int
+____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned int res;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ raw_local_irq_save(flags);
+ res = *p;
+ *p = res & ~mask;
+ raw_local_irq_restore(flags);
+
+ return res & mask;
+}
+
+static inline int
+____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned int res;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ raw_local_irq_save(flags);
+ res = *p;
+ *p = res ^ mask;
+ raw_local_irq_restore(flags);
+
+ return res & mask;
+}
+
+/// LINUX src: include/asm-arm/atomic.h
+
+#define atomic_read(v) ((v)->counter)
+
+#define atomic_set(v,i) (((v)->counter) = (i))
+
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+ unsigned long flags;
+ int val;
+
+ raw_local_irq_save(flags);
+ val = v->counter;
+ v->counter = val += i;
+ raw_local_irq_restore(flags);
+
+ return val;
+}
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+ unsigned long flags;
+ int val;
+
+ raw_local_irq_save(flags);
+ val = v->counter;
+ v->counter = val -= i;
+ raw_local_irq_restore(flags);
+
+ return val;
+}
+
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+ int ret;
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
+ ret = v->counter;
+ if (ret == old)
+ v->counter = new;
+ raw_local_irq_restore(flags);
+
+ return ret;
+}
+
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+
+ c = atomic_read(v);
+ while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c)
+ c = old;
+ return c != u;
+}
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
+#define atomic_add(i, v) (void) atomic_add_return(i, v)
+#define atomic_inc(v) (void) atomic_add_return(1, v)
+#define atomic_sub(i, v) (void) atomic_sub_return(i, v)
+#define atomic_dec(v) (void) atomic_sub_return(1, v)
+
+#define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
+#define atomic_inc_return(v) (atomic_add_return(1, v))
+#define atomic_dec_return(v) (atomic_sub_return(1, v))
+#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
+
+#define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0)
+
+/* Atomic operations are already serializing on ARM */
+#define smp_mb__before_atomic_dec() barrier()
+#define smp_mb__after_atomic_dec() barrier()
+#define smp_mb__before_atomic_inc() barrier()
+#define smp_mb__after_atomic_inc() barrier()
+
+/// LINUX src: include/linux/interrupt.h
+
+#define ATOMIC_INIT(i) { (i) }
+
+/* Tasklets --- multithreaded analogue of BHs.
+
+ Main feature differing them of generic softirqs: tasklet
+ is running only on one CPU simultaneously.
+
+ Main feature differing them of BHs: different tasklets
+ may be run simultaneously on different CPUs.
+
+ Properties:
+ * If tasklet_schedule() is called, then tasklet is guaranteed
+ to be executed on some cpu at least once after this.
+ * If the tasklet is already scheduled, but its excecution is still not
+ started, it will be executed only once.
+ * If this tasklet is already running on another CPU (or schedule is called
+ from tasklet itself), it is rescheduled for later.
+ * Tasklet is strictly serialized wrt itself, but not
+ wrt another tasklets. If client needs some intertask synchronization,
+ he makes it with spinlocks.
+ */
+
+struct tasklet_struct
+{
+ struct tasklet_struct *next;
+ unsigned long state;
+ atomic_t count;
+ void (*func)(unsigned long);
+ unsigned long data;
+};
+
+#define DECLARE_TASKLET(name, func, data) \
+struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(0), func, data }
+
+#define DECLARE_TASKLET_DISABLED(name, func, data) \
+struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(1), func, data }
+
+/* CAN message timestamp source, it is called from interrupt context */
+//#define can_gettimeofday do_gettimeofday
+
+/// from linux/timer.h
+
+struct tvec_t_base_s;
+
+struct timer_list {
+ struct list_head entry;
+ unsigned long expires;
+
+ void (*function)(unsigned long);
+ unsigned long data;
+
+ struct tvec_t_base_s *base;
+#ifdef CONFIG_TIMER_STATS
+ void *start_site;
+ char start_comm[16];
+ int start_pid;
+#endif
+};
+
+void udelay(long time);
+
+#endif /*_CAN_SYSDEP_H*/
--- /dev/null
+/**************************************************************************/
+/* File: canmsg.h - common kernel-space and user-space CAN message struct */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+#ifndef _CANMSG_T_H
+#define _CANMSG_T_H
+
+#ifdef __KERNEL__
+
+#include <linux/time.h>
+#include <linux/types.h>
+
+#else /* __KERNEL__ */
+
+#include <sys/time.h>
+#include <sys/types.h>
+
+#endif /* __KERNEL__ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * CAN_MSG_VERSION_2 enables new canmsg_t layout compatible with
+ * can4linux project from http://www.port.de/
+ *
+ */
+#define CAN_MSG_VERSION_2
+
+/* Number of data bytes in one CAN message */
+#define CAN_MSG_LENGTH 8
+
+#ifdef CAN_MSG_VERSION_2
+
+typedef struct timeval canmsg_tstamp_t ;
+
+typedef unsigned long canmsg_id_t;
+
+/**
+ * struct canmsg_t - structure representing CAN message
+ * @flags: message flags
+ * %MSG_RTR .. message is Remote Transmission Request,
+ * %MSG_EXT .. message with extended ID,
+ * %MSG_OVR .. indication of queue overflow condition,
+ * %MSG_LOCAL .. message originates from this node.
+ * @cob: communication object number (not used)
+ * @id: ID of CAN message
+ * @timestamp: not used
+ * @length: length of used data
+ * @data: data bytes buffer
+ *
+ * Header: canmsg.h
+ */
+struct canmsg_t {
+ int flags;
+ int cob;
+ canmsg_id_t id;
+ canmsg_tstamp_t timestamp;
+ unsigned short length;
+ unsigned char data[CAN_MSG_LENGTH];
+};
+
+#else /*CAN_MSG_VERSION_2*/
+#ifndef PACKED
+#define PACKED __attribute__((packed))
+#endif
+/* Old, deprecated version of canmsg_t structure */
+struct canmsg_t {
+ short flags;
+ int cob;
+ canmsg_id_t id;
+ unsigned long timestamp;
+ unsigned int length;
+ unsigned char data[CAN_MSG_LENGTH];
+} PACKED;
+#endif /*CAN_MSG_VERSION_2*/
+
+typedef struct canmsg_t canmsg_t;
+
+/**
+ * struct canfilt_t - structure for acceptance filter setup
+ * @flags: message flags
+ * %MSG_RTR .. message is Remote Transmission Request,
+ * %MSG_EXT .. message with extended ID,
+ * %MSG_OVR .. indication of queue overflow condition,
+ * %MSG_LOCAL .. message originates from this node.
+ * there are corresponding mask bits
+ * %MSG_RTR_MASK, %MSG_EXT_MASK, %MSG_LOCAL_MASK.
+ * %MSG_PROCESSLOCAL enables local messages processing in the
+ * combination with global setting
+ * @queid: CAN queue identification in the case of the multiple
+ * queues per one user (open instance)
+ * @cob: communication object number (not used)
+ * @id: selected required value of cared ID id bits
+ * @mask: select bits significand for the comparation;
+ * 1 .. take care about corresponding ID bit, 0 .. don't care
+ *
+ * Header: canmsg.h
+ */
+struct canfilt_t {
+ int flags;
+ int queid;
+ int cob;
+ canmsg_id_t id;
+ canmsg_id_t mask;
+};
+
+typedef struct canfilt_t canfilt_t;
+
+/* Definitions to use for canmsg_t and canfilt_t flags */
+#define MSG_RTR (1<<0)
+#define MSG_OVR (1<<1)
+#define MSG_EXT (1<<2)
+#define MSG_LOCAL (1<<3)
+/* If you change above lines, check canque_filtid2internal function */
+
+/* Additional definitions used for canfilt_t only */
+#define MSG_FILT_MASK_SHIFT 8
+#define MSG_RTR_MASK (MSG_RTR<<MSG_FILT_MASK_SHIFT)
+#define MSG_EXT_MASK (MSG_EXT<<MSG_FILT_MASK_SHIFT)
+#define MSG_LOCAL_MASK (MSG_LOCAL<<MSG_FILT_MASK_SHIFT)
+#define MSG_PROCESSLOCAL (MSG_OVR<<MSG_FILT_MASK_SHIFT)
+
+/* Can message ID mask */
+#define MSG_ID_MASK ((1l<<29)-1)
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif /*_CANMSG_T_H*/
--- /dev/null
+/**************************************************************************/
+/* File: constants.h - driver build time constant parameters */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+#ifndef __CONSTANTS_H__
+#define __CONSTANTS_H__
+
+/* Device name as it will appear in /proc/devices */
+#define DEVICE_NAME "can"
+
+/* Branch of the driver */
+#define CAN_DRV_BRANCH (('L'<<24)|('I'<<16)|('N'<<8)|'C')
+
+/* Version of the driver */
+#define CAN_DRV_VER_MAJOR 0
+#define CAN_DRV_VER_MINOR 3
+#define CAN_DRV_VER_PATCH 4
+#define CAN_DRV_VER ((CAN_DRV_VER_MAJOR<<16) | (CAN_DRV_VER_MINOR<<8) | CAN_DRV_VER_PATCH)
+
+/* Default driver major number, see /usr/src/linux/Documentation/devices.txt */
+#define CAN_MAJOR 91
+
+/* Definition of the maximum number of concurrent supported hardware boards,
+ * chips per board, total number of chips, interrupts and message objects.
+ * Obviously there are no 32 different interrupts, but each chip can have its
+ * own interrupt so we have to check for it MAX_IRQ == MAX_TOT_CHIPS times.
+ */
+#define MAX_HW_CARDS 8
+#define MAX_HW_CHIPS 4
+#define MAX_TOT_CHIPS (MAX_HW_CHIPS*MAX_HW_CARDS)
+#define MAX_TOT_CHIPS_STR 32 /* must be explicit for MODULE_PARM */
+#define MAX_IRQ 32
+#define MAX_MSGOBJS 32
+#define MAX_TOT_MSGOBJS (MAX_TOT_CHIPS*MAX_MSGOBJS)
+#define MAX_BUF_LENGTH 64
+//#define MAX_BUF_LENGTH 4
+
+
+/* These flags can be used for the msgobj_t structure flags data entry */
+#define MSGOBJ_OPENED_b 0
+#define MSGOBJ_TX_REQUEST_b 1
+#define MSGOBJ_TX_LOCK_b 2
+#define MSGOBJ_IRQ_REQUEST_b 3
+#define MSGOBJ_WORKER_WAKE_b 4
+#define MSGOBJ_FILTCH_REQUEST_b 5
+#define MSGOBJ_RX_MODE_b 6
+#define MSGOBJ_RX_MODE_EXT_b 7
+#define MSGOBJ_TX_PENDING_b 8
+
+#define MSGOBJ_OPENED (1<<MSGOBJ_OPENED_b)
+#define MSGOBJ_TX_REQUEST (1<<MSGOBJ_TX_REQUEST_b)
+#define MSGOBJ_TX_LOCK (1<<MSGOBJ_TX_LOCK_b)
+#define MSGOBJ_IRQ_REQUEST (1<<MSGOBJ_IRQ_REQUEST_b)
+#define MSGOBJ_WORKER_WAKE (1<<MSGOBJ_WORKER_WAKE_b)
+#define MSGOBJ_FILTCH_REQUEST (1<<MSGOBJ_FILTCH_REQUEST_b)
+#define MSGOBJ_RX_MODE (1<<MSGOBJ_RX_MODE_b)
+#define MSGOBJ_RX_MODE_EXT (1<<MSGOBJ_RX_MODE_EXT_b)
+#define MSGOBJ_TX_PENDING (1<<MSGOBJ_TX_PENDING_b)
+
+#define can_msgobj_test_fl(obj,obj_fl) \
+ test_bit(MSGOBJ_##obj_fl##_b,&(obj)->obj_flags)
+#define can_msgobj_set_fl(obj,obj_fl) \
+ set_bit(MSGOBJ_##obj_fl##_b,&(obj)->obj_flags)
+#define can_msgobj_clear_fl(obj,obj_fl) \
+ clear_bit(MSGOBJ_##obj_fl##_b,&(obj)->obj_flags)
+#define can_msgobj_test_and_set_fl(obj,obj_fl) \
+ test_and_set_bit(MSGOBJ_##obj_fl##_b,&(obj)->obj_flags)
+#define can_msgobj_test_and_clear_fl(obj,obj_fl) \
+ test_and_clear_bit(MSGOBJ_##obj_fl##_b,&(obj)->obj_flags)
+
+
+/* These flags can be used for the canchip_t structure flags data entry */
+#define CHIP_ATTACHED (1<<0) /* chip is attached to HW, release_chip() has to be called */
+#define CHIP_CONFIGURED (1<<1) /* chip is configured and prepared for communication */
+#define CHIP_SEGMENTED (1<<2) /* segmented access, ex: i82527 with 16 byte window*/
+#define CHIP_IRQ_SETUP (1<<3) /* IRQ handler has been set */
+#define CHIP_IRQ_PCI (1<<4) /* chip is on PCI board and uses PCI interrupt */
+#define CHIP_IRQ_VME (1<<5) /* interrupt is VME bus and requires VME bridge */
+#define CHIP_IRQ_CUSTOM (1<<6) /* custom interrupt provided by board or chip code */
+#define CHIP_IRQ_FAST (1<<7) /* interrupt handler only schedules postponed processing */
+#define CHIP_KEEP_DATA (1<<8) /* let the hotplug device free its chip_data structure itself */
+
+#define CHIP_MAX_IRQLOOP 1000
+
+/* System independent defines of IRQ handled state */
+#define CANCHIP_IRQ_NONE 0
+#define CANCHIP_IRQ_HANDLED 1
+#define CANCHIP_IRQ_ACCEPTED 2
+#define CANCHIP_IRQ_STUCK 3
+
+/* These flags can be used for the candevices_t structure flags data entry */
+#define CANDEV_PROGRAMMABLE_IRQ (1<<0)
+#define CANDEV_IO_RESERVED (1<<1)
+
+/* Next flags are specific for struct canuser_t applications connection */
+#define CANUSER_RTL_CLIENT (1<<0)
+#define CANUSER_RTL_MEM (1<<1)
+#define CANUSER_DIRECT (1<<2)
+
+
+enum timing_BTR1 {
+ MAX_TSEG1 = 15,
+ MAX_TSEG2 = 7
+};
+
+/* Flags for baud_rate function */
+#define BTR1_SAM (1<<1)
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* File: devcommon.h - common device code */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+#include "./canmsg.h"
+#include "./can_sysdep.h"
+#include "./constants.h"
+#include "./can_queue.h"
+
+int canqueue_ends_init_chip(struct canque_ends_t *qends, struct canchip_t *chip, struct msgobj_t *obj);
+int canqueue_ends_done_chip(struct canque_ends_t *qends);
--- /dev/null
+#ifndef _ASM_GENERIC_ERRNO_BASE_H
+#define _ASM_GENERIC_ERRNO_BASE_H
+
+#define EPERM 1 /* Operation not permitted */
+#define ENOENT 2 /* No such file or directory */
+#define ESRCH 3 /* No such process */
+#define EINTR 4 /* Interrupted system call */
+#define EIO 5 /* I/O error */
+#define ENXIO 6 /* No such device or address */
+#define E2BIG 7 /* Argument list too long */
+#define ENOEXEC 8 /* Exec format error */
+#define EBADF 9 /* Bad file number */
+#define ECHILD 10 /* No child processes */
+#define EAGAIN 11 /* Try again */
+#define ENOMEM 12 /* Out of memory */
+#define EACCES 13 /* Permission denied */
+#define EFAULT 14 /* Bad address */
+#define ENOTBLK 15 /* Block device required */
+#define EBUSY 16 /* Device or resource busy */
+#define EEXIST 17 /* File exists */
+#define EXDEV 18 /* Cross-device link */
+#define ENODEV 19 /* No such device */
+#define ENOTDIR 20 /* Not a directory */
+#define EISDIR 21 /* Is a directory */
+#define EINVAL 22 /* Invalid argument */
+#define ENFILE 23 /* File table overflow */
+#define EMFILE 24 /* Too many open files */
+#define ENOTTY 25 /* Not a typewriter */
+#define ETXTBSY 26 /* Text file busy */
+#define EFBIG 27 /* File too large */
+#define ENOSPC 28 /* No space left on device */
+#define ESPIPE 29 /* Illegal seek */
+#define EROFS 30 /* Read-only file system */
+#define EMLINK 31 /* Too many links */
+#define EPIPE 32 /* Broken pipe */
+#define EDOM 33 /* Math argument out of domain of func */
+#define ERANGE 34 /* Math result not representable */
+
+#endif
--- /dev/null
+#ifndef _ASM_GENERIC_ERRNO_H
+#define _ASM_GENERIC_ERRNO_H
+
+#include "./errno-base.h"
+
+#define EDEADLK 35 /* Resource deadlock would occur */
+#define ENAMETOOLONG 36 /* File name too long */
+#define ENOLCK 37 /* No record locks available */
+#define ENOSYS 38 /* Function not implemented */
+#define ENOTEMPTY 39 /* Directory not empty */
+#define ELOOP 40 /* Too many symbolic links encountered */
+#define EWOULDBLOCK EAGAIN /* Operation would block */
+#define ENOMSG 42 /* No message of desired type */
+#define EIDRM 43 /* Identifier removed */
+#define ECHRNG 44 /* Channel number out of range */
+#define EL2NSYNC 45 /* Level 2 not synchronized */
+#define EL3HLT 46 /* Level 3 halted */
+#define EL3RST 47 /* Level 3 reset */
+#define ELNRNG 48 /* Link number out of range */
+#define EUNATCH 49 /* Protocol driver not attached */
+#define ENOCSI 50 /* No CSI structure available */
+#define EL2HLT 51 /* Level 2 halted */
+#define EBADE 52 /* Invalid exchange */
+#define EBADR 53 /* Invalid request descriptor */
+#define EXFULL 54 /* Exchange full */
+#define ENOANO 55 /* No anode */
+#define EBADRQC 56 /* Invalid request code */
+#define EBADSLT 57 /* Invalid slot */
+
+#define EDEADLOCK EDEADLK
+
+#define EBFONT 59 /* Bad font file format */
+#define ENOSTR 60 /* Device not a stream */
+#define ENODATA 61 /* No data available */
+#define ETIME 62 /* Timer expired */
+#define ENOSR 63 /* Out of streams resources */
+#define ENONET 64 /* Machine is not on the network */
+#define ENOPKG 65 /* Package not installed */
+#define EREMOTE 66 /* Object is remote */
+#define ENOLINK 67 /* Link has been severed */
+#define EADV 68 /* Advertise error */
+#define ESRMNT 69 /* Srmount error */
+#define ECOMM 70 /* Communication error on send */
+#define EPROTO 71 /* Protocol error */
+#define EMULTIHOP 72 /* Multihop attempted */
+#define EDOTDOT 73 /* RFS specific error */
+#define EBADMSG 74 /* Not a data message */
+#define EOVERFLOW 75 /* Value too large for defined data type */
+#define ENOTUNIQ 76 /* Name not unique on network */
+#define EBADFD 77 /* File descriptor in bad state */
+#define EREMCHG 78 /* Remote address changed */
+#define ELIBACC 79 /* Can not access a needed shared library */
+#define ELIBBAD 80 /* Accessing a corrupted shared library */
+#define ELIBSCN 81 /* .lib section in a.out corrupted */
+#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
+#define ELIBEXEC 83 /* Cannot exec a shared library directly */
+#define EILSEQ 84 /* Illegal byte sequence */
+#define ERESTART 85 /* Interrupted system call should be restarted */
+#define ESTRPIPE 86 /* Streams pipe error */
+#define EUSERS 87 /* Too many users */
+#define ENOTSOCK 88 /* Socket operation on non-socket */
+#define EDESTADDRREQ 89 /* Destination address required */
+#define EMSGSIZE 90 /* Message too long */
+#define EPROTOTYPE 91 /* Protocol wrong type for socket */
+#define ENOPROTOOPT 92 /* Protocol not available */
+#define EPROTONOSUPPORT 93 /* Protocol not supported */
+#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
+#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
+#define EPFNOSUPPORT 96 /* Protocol family not supported */
+#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
+#define EADDRINUSE 98 /* Address already in use */
+#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
+#define ENETDOWN 100 /* Network is down */
+#define ENETUNREACH 101 /* Network is unreachable */
+#define ENETRESET 102 /* Network dropped connection because of reset */
+#define ECONNABORTED 103 /* Software caused connection abort */
+#define ECONNRESET 104 /* Connection reset by peer */
+#define ENOBUFS 105 /* No buffer space available */
+#define EISCONN 106 /* Transport endpoint is already connected */
+#define ENOTCONN 107 /* Transport endpoint is not connected */
+#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
+#define ETOOMANYREFS 109 /* Too many references: cannot splice */
+#define ETIMEDOUT 110 /* Connection timed out */
+#define ECONNREFUSED 111 /* Connection refused */
+#define EHOSTDOWN 112 /* Host is down */
+#define EHOSTUNREACH 113 /* No route to host */
+#define EALREADY 114 /* Operation already in progress */
+#define EINPROGRESS 115 /* Operation now in progress */
+#define ESTALE 116 /* Stale NFS file handle */
+#define EUCLEAN 117 /* Structure needs cleaning */
+#define ENOTNAM 118 /* Not a XENIX named type file */
+#define ENAVAIL 119 /* No XENIX semaphores available */
+#define EISNAM 120 /* Is a named type file */
+#define EREMOTEIO 121 /* Remote I/O error */
+#define EDQUOT 122 /* Quota exceeded */
+
+#define ENOMEDIUM 123 /* No medium found */
+#define EMEDIUMTYPE 124 /* Wrong medium type */
+#define ECANCELED 125 /* Operation Canceled */
+#define ENOKEY 126 /* Required key not available */
+#define EKEYEXPIRED 127 /* Key has expired */
+#define EKEYREVOKED 128 /* Key has been revoked */
+#define EKEYREJECTED 129 /* Key was rejected by service */
+
+/* for robust mutexes */
+#define EOWNERDEAD 130 /* Owner died */
+#define ENOTRECOVERABLE 131 /* State not recoverable */
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* File: finish.h - finalization of the driver operations */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+void msgobj_done(struct msgobj_t *obj);
+void canchip_done(struct canchip_t *chip);
+void candevice_done(struct candevice_t *candev);
+void canhardware_done(struct canhardware_t *candev);
--- /dev/null
+/**************************************************************************/
+/* File: i82527.h - Intel i82527 CAN controller support */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+int i82527_enable_configuration(struct canchip_t *chip);
+int i82527_disable_configuration(struct canchip_t *chip);
+int i82527_chip_config(struct canchip_t *chip);
+int i82527_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
+ int sampl_pt, int flags);
+int i82527_standard_mask(struct canchip_t *chip, unsigned short code,
+ unsigned short mask);
+int i82527_extended_mask(struct canchip_t *chip, unsigned long code,
+ unsigned long mask);
+int i82527_message15_mask(struct canchip_t *chip, unsigned long code,
+ unsigned long mask);
+int i82527_clear_objects(struct canchip_t *chip);
+int i82527_config_irqs(struct canchip_t *chip, short irqs);
+int i82527_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj);
+int i82527_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
+ struct canmsg_t *msg);
+int i82527_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
+ struct canmsg_t *msg);
+int i82527_remote_request(struct canchip_t *chip, struct msgobj_t *obj);
+int i82527_set_btregs(struct canchip_t *chip, unsigned short btr0,
+ unsigned short btr1);
+int i82527_start_chip(struct canchip_t *chip);
+int i82527_stop_chip(struct canchip_t *chip);
+int i82527_check_tx_stat(struct canchip_t *chip);
+int i82527_irq_handler(int irq, struct canchip_t *chip);
+int i82527_fill_chipspecops(struct canchip_t *chip);
+
+
+#define MSG_OFFSET(object) ((object)*0x10)
+
+#define iCTL 0x00 // Control Register
+#define iSTAT 0x01 // Status Register
+#define iCPU 0x02 // CPU Interface Register
+#define iHSR 0x04 // High Speed Read
+#define iSGM0 0x06 // Standard Global Mask byte 0
+#define iSGM1 0x07
+#define iEGM0 0x08 // Extended Global Mask byte 0
+#define iEGM1 0x09
+#define iEGM2 0x0a
+#define iEGM3 0x0b
+#define i15M0 0x0c // Message 15 Mask byte 0
+#define i15M1 0x0d
+#define i15M2 0x0e
+#define i15M3 0x0f
+#define iCLK 0x1f // Clock Out Register
+#define iBUS 0x2f // Bus Configuration Register
+#define iBT0 0x3f // Bit Timing Register byte 0
+#define iBT1 0x4f
+#define iIRQ 0x5f // Interrupt Register
+#define iP1C 0x9f // Port 1 Register
+#define iP2C 0xaf // Port 2 Register
+#define iP1I 0xbf // Port 1 Data In Register
+#define iP2I 0xcf // Port 2 Data In Register
+#define iP1O 0xdf // Port 1 Data Out Register
+#define iP2O 0xef // Port 2 Data Out Register
+#define iSRA 0xff // Serial Reset Address
+
+#define iMSGCTL0 0x00 /* First Control register */
+#define iMSGCTL1 0x01 /* Second Control register */
+#define iMSGID0 0x02 /* First Byte of Message ID */
+#define iMSGID1 0x03
+#define iMSGID2 0x04
+#define iMSGID3 0x05
+#define iMSGCFG 0x06 /* Message Configuration */
+#define iMSGDAT0 0x07 /* First Data Byte */
+#define iMSGDAT1 0x08
+#define iMSGDAT2 0x09
+#define iMSGDAT3 0x0a
+#define iMSGDAT4 0x0b
+#define iMSGDAT5 0x0c
+#define iMSGDAT6 0x0d
+#define iMSGDAT7 0x0e
+
+/* Control Register (0x00) */
+enum i82527_iCTL {
+ iCTL_INI = 1, // Initialization
+ iCTL_IE = 1<<1, // Interrupt Enable
+ iCTL_SIE = 1<<2, // Status Interrupt Enable
+ iCTL_EIE = 1<<3, // Error Interrupt Enable
+ iCTL_CCE = 1<<6 // Change Configuration Enable
+};
+
+/* Status Register (0x01) */
+enum i82527_iSTAT {
+ iSTAT_TXOK = 1<<3, // Transmit Message Successfully
+ iSTAT_RXOK = 1<<4, // Receive Message Successfully
+ iSTAT_WAKE = 1<<5, // Wake Up Status
+ iSTAT_WARN = 1<<6, // Warning Status
+ iSTAT_BOFF = 1<<7 // Bus Off Status
+};
+
+/* CPU Interface Register (0x02) */
+enum i82527_iCPU {
+ iCPU_CEN = 1, // Clock Out Enable
+ iCPU_MUX = 1<<2, // Multiplex
+ iCPU_SLP = 1<<3, // Sleep
+ iCPU_PWD = 1<<4, // Power Down Mode
+ iCPU_DMC = 1<<5, // Divide Memory Clock
+ iCPU_DSC = 1<<6, // Divide System Clock
+ iCPU_RST = 1<<7 // Hardware Reset Status
+};
+
+/* Clock Out Register (0x1f) */
+enum i82527_iCLK {
+ iCLK_CD0 = 1, // Clock Divider bit 0
+ iCLK_CD1 = 1<<1,
+ iCLK_CD2 = 1<<2,
+ iCLK_CD3 = 1<<3,
+ iCLK_SL0 = 1<<4, // Slew Rate bit 0
+ iCLK_SL1 = 1<<5
+};
+
+/* Bus Configuration Register (0x2f) */
+enum i82527_iBUS {
+ iBUS_DR0 = 1, // Disconnect RX0 Input
+ iBUS_DR1 = 1<<1, // Disconnect RX1 Input
+ iBUS_DT1 = 1<<3, // Disconnect TX1 Output
+ iBUS_POL = 1<<5, // Polarity
+ iBUS_CBY = 1<<6 // Comparator Bypass
+};
+
+#define RESET 1 // Bit Pair Reset Status
+#define SET 2 // Bit Pair Set Status
+#define UNCHANGED 3 // Bit Pair Unchanged
+
+/* Message Control Register 0 (Base Address + 0x0) */
+enum i82527_iMSGCTL0 {
+ INTPD_SET = SET, // Interrupt pending
+ INTPD_RES = RESET, // No Interrupt pending
+ INTPD_UNC = UNCHANGED,
+ RXIE_SET = SET<<2, // Receive Interrupt Enable
+ RXIE_RES = RESET<<2, // Receive Interrupt Disable
+ RXIE_UNC = UNCHANGED<<2,
+ TXIE_SET = SET<<4, // Transmit Interrupt Enable
+ TXIE_RES = RESET<<4, // Transmit Interrupt Disable
+ TXIE_UNC = UNCHANGED<<4,
+ MVAL_SET = SET<<6, // Message Valid
+ MVAL_RES = RESET<<6, // Message Invalid
+ MVAL_UNC = UNCHANGED<<6
+};
+
+/* Message Control Register 1 (Base Address + 0x01) */
+enum i82527_iMSGCTL1 {
+ NEWD_SET = SET, // New Data
+ NEWD_RES = RESET, // No New Data
+ NEWD_UNC = UNCHANGED,
+ MLST_SET = SET<<2, // Message Lost
+ MLST_RES = RESET<<2, // No Message Lost
+ MLST_UNC = UNCHANGED<<2,
+ CPUU_SET = SET<<2, // CPU Updating
+ CPUU_RES = RESET<<2, // No CPU Updating
+ CPUU_UNC = UNCHANGED<<2,
+ TXRQ_SET = SET<<4, // Transmission Request
+ TXRQ_RES = RESET<<4, // No Transmission Request
+ TXRQ_UNC = UNCHANGED<<4,
+ RMPD_SET = SET<<6, // Remote Request Pending
+ RMPD_RES = RESET<<6, // No Remote Request Pending
+ RMPD_UNC = UNCHANGED<<6
+};
+
+/* Message Configuration Register (Base Address + 0x06) */
+enum i82527_iMSGCFG {
+ MCFG_XTD = 1<<2, // Extended Identifier
+ MCFG_DIR = 1<<3 // Direction is Transmit
+};
+
+void i82527_seg_write_reg(const struct canchip_t *chip, unsigned char data, unsigned address);
+unsigned i82527_seg_read_reg(const struct canchip_t *chip, unsigned address);
--- /dev/null
+#ifndef LPC17XX_CAN_H_
+#define LPC17XX_CAN_H_
+
+#include "LPC17xx.h"
+#include "hal_machperiph.h"
+#include "cpu_def.h"
+#include "system_def.h"
+
+#include "can/can.h"
+#include "can/canmsg.h"
+#include "can/can_bittiming.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+// CAN1, CAN2 and CAN Acceptance filter base addresses
+#define CAN1_REGS_BASE 0x40044000UL
+#define CAN2_REGS_BASE 0x40048000UL
+#define CANAF_REGS_BASE 0x4003C000UL
+
+// offset of CAN registers
+#define CAN_MOD_o 0x0000
+#define CAN_CMR_o 0x0004
+#define CAN_GSR_o 0x0008
+#define CAN_ICR_o 0x000C
+#define CAN_IER_o 0x0010
+#define CAN_BTR_o 0x0014
+#define CAN_EWL_o 0x0018
+#define CAN_SR_o 0x001C
+#define CAN_RFS_o 0x0020
+#define CAN_RID_o 0x0024
+#define CAN_RDA_o 0x0028
+#define CAN_RDB_o 0x002C
+#define CAN_TFI1_o 0x0030
+#define CAN_TID1_o 0x0034
+#define CAN_TDA1_o 0x0038
+#define CAN_TDB1_o 0x003C
+#define CAN_TFI2_o 0x0040
+#define CAN_TID2_o 0x0044
+#define CAN_TDA2_o 0x0048
+#define CAN_TDB2_o 0x004C
+#define CAN_TFI3_o 0x0050
+#define CAN_TID3_o 0x0054
+#define CAN_TDA3_o 0x0058
+#define CAN_TDB3_o 0x005C
+
+// offset of CAN Acceptance filter registers
+#define CANAF_AFMR_o 0x0000
+#define CANAF_SFF_sa_o 0x0004
+#define CANAF_SFF_GRP_sa_o 0x0008
+#define CANAF_EFF_sa_o 0x000C
+#define CANAF_EFF_GRP_sa_o 0x0010
+#define CANAF_ENDofTable_o 0x0014
+#define CANAF_LUTerrAd_o 0x0018
+#define CANAF_LUTerr_o 0x001C
+
+//----------------------------------
+
+#define CAN1MOD (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_MOD_o))
+#define CAN1CMR (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_CMR_o))
+#define CAN1GSR (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_GSR_o))
+#define CAN1ICR (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_ICR_o))
+#define CAN1IER (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_IER_o))
+#define CAN1BTR (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_BTR_o))
+#define CAN1EWL (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_EWL_o))
+#define CAN1SR (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_SR_o))
+#define CAN1RFS (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_RFS_o))
+#define CAN1RID (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_RID_o))
+#define CAN1RDA (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_RDA_o))
+#define CAN1RDB (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_RDB_o))
+#define CAN1TFI1 (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_TFI1_o))
+#define CAN1TID1 (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_TID1_o))
+#define CAN1TDA1 (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_TDA1_o))
+#define CAN1TDB1 (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_TDB1_o))
+#define CAN1TFI2 (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_TFI2_o))
+#define CAN1TID2 (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_TID2_o))
+#define CAN1TDA2 (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_TDA2_o))
+#define CAN1TDB2 (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_TDB2_o))
+#define CAN1TFI3 (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_TFI3_o))
+#define CAN1TID3 (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_TID3_o))
+#define CAN1TDA3 (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_TDA3_o))
+#define CAN1TDB3 (*(volatile uint32_t*)(CAN1_REGS_BASE+CAN_TDB3_o))
+
+
+
+#define CANAF_AFMR (*(volatile uint32_t*)(CANAF_REGS_BASE+CANAF_AFMR_o))
+#define CANAF_SFF_sa (*(volatile uint32_t*)(CANAF_REGS_BASE+CANAF_SFF_sa_o))
+#define CANAF_SFF_GRP_sa (*(volatile uint32_t*)(CANAF_REGS_BASE+CANAF_SFF_GRP_sa_o))
+#define CANAF_EFF_sa (*(volatile uint32_t*)(CANAF_REGS_BASE+CANAF_EFF_sa_o))
+#define CANAF_EFF_GRP_sa (*(volatile uint32_t*)(CANAF_REGS_BASE+CANAF_EFF_GRP_sa_o))
+#define CANAF_ENDofTable (*(volatile uint32_t*)(CANAF_REGS_BASE+CANAF_ENDofTable_o))
+#define CANAF_LUTerrAd (*(volatile uint32_t*)(CANAF_REGS_BASE+CANAF_LUTerrAd_o))
+#define CANAF_LUTerr (*(volatile uint32_t*)(CANAF_REGS_BASE+CANAF_LUTerr_o))
+
+//----------------------------------
+
+//CAN Global Status Register
+#define CAN_GSR_BS (1<<7)
+
+//CAN Interrupt and Capture Register bits
+#define CAN_ICR_RI (1<<0)
+#define CAN_ICR_TI1 (1<<1)
+#define CAN_ICR_DOI (1<<3)
+#define CAN_ICR_IDI (1<<8)
+
+//CAN Status Register bits
+#define CAN_SR_RBS (1<<0)
+#define CAN_SR_DOS (1<<1)
+#define CAN_SR_TBS1 (1<<2)
+#define CAN_SR_TCS1 (1<<3)
+
+//CAN Command Register bits
+#define CAN_CMR_TR (1<<0)
+#define CAN_CMR_AT (1<<1)
+#define CAN_CMR_RRB (1<<2)
+#define CAN_CMR_CDO (1<<3)
+#define CAN_CMR_STB1 (1<<5)
+
+//CAN Transmit Frame Information register 1 bits
+#define CAN_TFI1_RTR (1<<30)
+#define CAN_TFI1_EXT (1<<31)
+
+//CAN Receive Frame Status register
+#define CAN_RFS_RTR (1<<30)
+#define CAN_RFS_EXT (1<<31)
+
+//CAN Interrupt Enable Register bits
+#define CAN_IER_RIE (1<<0)
+#define CAN_IER_TIE1 (1<<1)
+#define CAN_IER_DOIE (1<<3)
+#define CAN_IER_IDIE (1<<8)
+
+
+//----------------------------------
+
+
+#define PCCAN1 (1<<13) // CAN Controller 1 power/clock control bit.
+#define PCCAN2 (1<<14) // CAN Controller 2 power/clock control bit.
+
+#define PCLK_CAN1_MASK ((1<<27)|(1<<26))
+#define PCLK_CAN2_MASK ((1<<29)|(1<<28))
+#define PCLK_ACF_MASK ((1<<31)|(1<<30))
+
+#define CAN1_RX_MASK ((1<<1)|(1<<0))
+#define CAN1_TX_MASK ((1<<3)|(1<<2))
+
+// CAN1_RX_BIT a CAN1_TX_BIT jiz definovany v system_def.h
+
+//----------------------------------
+
+#define MAX_TRANSMIT_WAIT_LOOPS 10000
+
+void CAN_init(struct canchip_t *chip);
+void CAN_send(struct canchip_t *chip, canmsg_t* msg);
+void CAN_recv(struct canchip_t *chip, canmsg_t* msg);
+
+struct can_lmc1_chip_data
+{
+ int flags;
+};
+
+
+// board can-lmc1 specific functions:
+int can_lmc1_register(struct hwspecops_t *hwspecops);
+int can_lmc1_init_hw_data(struct candevice_t *candev);
+int can_lmc1_init_chip_data(struct candevice_t *candev, int chipnr);
+int can_lmc1_init_obj_data(struct canchip_t *chip, int objnr);
+void can_lmc1_write_register(unsigned data, unsigned long address);
+unsigned can_lmc1_read_register(unsigned long address);
+int can_lmc1_request_io(struct candevice_t *candev);
+int can_lmc1_reset(struct candevice_t *candev);
+int can_lmc1_program_irq(struct candevice_t *candev);
+
+// lpc17xx can chip specific functions:
+int lpc17xx_chip_config(struct canchip_t *chip);
+int lpc17xx_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
+ struct canmsg_t *msg);
+int lpc17xx_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
+ struct canmsg_t *msg);
+int lpc17xx_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj);
+int lpc17xx_irq_handler(int irq, struct canchip_t *chip);
+void lpc17xx_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj);
+int lpc17xx_fill_chipspecops(struct canchip_t *chip);
+int lpc17xx_register(struct chipspecops_t *chipspecops);
+int lpc17xx_attach_to_chip(struct canchip_t *chip);
+int lpc17xx_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj);
+void lpc17xx_read(struct canchip_t *chip, struct msgobj_t *obj);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LPC17XX_CAN_H_
--- /dev/null
+/**************************************************************************/
+/* File: main.h - the CAN driver basic data structures and functions */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+#ifndef _CAN_MAIN_H
+#define _CAN_MAIN_H
+
+#include "./can.h"
+#include "./constants.h"
+#include "./ul_listbase.h"
+#include "./can_sysdep.h"
+#include "./can_queue.h"
+#include "./can_bittiming.h"
+#include "./errno.h"
+
+#ifdef CAN_DEBUG
+ #define DEBUGMSG(fmt,args...) can_printk(KERN_ERR "USBCAN(debug): " fmt,\
+ ##args)
+#else
+ #define DEBUGMSG(fmt,args...)
+#endif
+
+#define CANMSG(fmt,args...) can_printk(KERN_ERR "USBCAN: " fmt,##args)
+
+
+extern can_spinlock_t canuser_manipulation_lock;
+
+/**
+ * struct canhardware_t - structure representing pointers to all CAN boards
+ * @nr_boards: number of present boards
+ * @rtr_queue: RTR - remote transmission request queue (expect some changes there)
+ * @rtr_lock: locking for RTR queue
+ * @candevice: array of pointers to CAN devices/boards
+ */
+struct canhardware_t {
+ int nr_boards;
+ struct rtr_id *rtr_queue;
+ can_spinlock_t rtr_lock;
+ struct candevice_t *candevice[MAX_HW_CARDS];
+};
+
+/**
+ * struct candevice_t - CAN device/board structure
+ * @hwname: text string with board type
+ * @candev_idx: board index in canhardware_t.candevice[]
+ * @io_addr: IO/physical MEM address
+ * @res_addr: optional reset register port
+ * @dev_base_addr: CPU translated IO/virtual MEM address
+ * @flags: board flags: %PROGRAMMABLE_IRQ .. interrupt number
+ * can be programmed into board
+ * @nr_all_chips: number of chips present on the board
+ * @nr_82527_chips: number of Intel 8257 chips
+ * @nr_sja1000_chips: number of Philips SJA100 chips
+ * @chip: array of pointers to the chip structures
+ * @hwspecops: pointer to board specific operations
+ * @hosthardware_p: pointer to the root hardware structure
+ * @sysdevptr: union reserved for pointer to bus specific
+ * device structure (case @pcidev is used for PCI devices)
+ *
+ * The structure represent configuration and state of associated board.
+ * The driver infrastructure prepares this structure and calls
+ * board type specific board_register() function. The board support provided
+ * register function fills right function pointers in @hwspecops structure.
+ * Then driver setup calls functions init_hw_data(), init_chip_data(),
+ * init_chip_data(), init_obj_data() and program_irq(). Function init_hw_data()
+ * and init_chip_data() have to specify number and types of connected chips
+ * or objects respectively.
+ * The use of @nr_all_chips is preferred over use of fields @nr_82527_chips
+ * and @nr_sja1000_chips in the board non-specific functions.
+ * The @io_addr and @dev_base_addr is filled from module parameters
+ * to the same value. The request_io function can fix-up @dev_base_addr
+ * field if virtual address is different than bus address.
+ */
+struct candevice_t {
+ char *hwname; /* text board type */
+ int candev_idx; /* board index in canhardware_t.candevice[] */
+ unsigned long io_addr; /* IO/physical MEM address */
+ unsigned long res_addr; /* optional reset register port */
+ can_ioptr_t dev_base_addr; /* CPU translated IO/virtual MEM address */
+ can_ioptr_t aux_base_addr; /* CPU translated IO/virtual MEM address */
+ unsigned int flags;
+ int nr_all_chips;
+ int nr_82527_chips;
+ int nr_sja1000_chips;
+ can_spinlock_t device_lock;
+ struct canchip_t *chip[MAX_HW_CHIPS];
+
+ struct hwspecops_t *hwspecops;
+
+ struct canhardware_t *hosthardware_p;
+
+ union {
+ void *anydev;
+ #ifdef CAN_ENABLE_PCI_SUPPORT
+ struct pci_dev *pcidev;
+ #endif /*CAN_ENABLE_PCI_SUPPORT*/
+ } sysdevptr;
+
+};
+
+/**
+ * struct canchip_t - CAN chip state and type information
+ * @chip_type: text string describing chip type
+ * @chip_idx: index of the chip in candevice_t.chip[] array
+ * @chip_irq: chip interrupt number if any
+ * @chip_base_addr: chip base address in the CPU IO or virtual memory space
+ * @flags: chip flags: %CHIP_CONFIGURED .. chip is configured,
+ * %CHIP_SEGMENTED .. access to the chip is segmented (mainly for i82527 chips)
+ * @clock: chip base clock frequency in Hz
+ * @baudrate: selected chip baudrate in Hz
+ * @write_register: write chip register function copy
+ * @read_register: read chip register function copy
+ * @chip_data: pointer for optional chip specific data extension
+ * @sja_cdr_reg: SJA specific register -
+ * holds hardware specific options for the Clock Divider
+ * register. Options defined in the sja1000.h file:
+ * %CDR_CLKOUT_MASK, %CDR_CLK_OFF, %CDR_RXINPEN, %CDR_CBP, %CDR_PELICAN
+ * @sja_ocr_reg: SJA specific register -
+ * hold hardware specific options for the Output Control
+ * register. Options defined in the sja1000.h file:
+ * %OCR_MODE_BIPHASE, %OCR_MODE_TEST, %OCR_MODE_NORMAL, %OCR_MODE_CLOCK,
+ * %OCR_TX0_LH, %OCR_TX1_ZZ.
+ * @int_cpu_reg: Intel specific register -
+ * holds hardware specific options for the CPU Interface
+ * register. Options defined in the i82527.h file:
+ * %iCPU_CEN, %iCPU_MUX, %iCPU_SLP, %iCPU_PWD, %iCPU_DMC, %iCPU_DSC, %iCPU_RST.
+ * @int_clk_reg: Intel specific register -
+ * holds hardware specific options for the Clock Out
+ * register. Options defined in the i82527.h file:
+ * %iCLK_CD0, %iCLK_CD1, %iCLK_CD2, %iCLK_CD3, %iCLK_SL0, %iCLK_SL1.
+ * @int_bus_reg: Intel specific register -
+ * holds hardware specific options for the Bus Configuration
+ * register. Options defined in the i82527.h file:
+ * %iBUS_DR0, %iBUS_DR1, %iBUS_DT1, %iBUS_POL, %iBUS_CBY.
+ * @msgobj: array of pointers to individual communication objects
+ * @chipspecops: pointer to the set of chip specific object filled by init_chip_data() function
+ * @hostdevice: pointer to chip hosting board
+ * @max_objects: maximal number of communication objects connected to this chip
+ * @chip_lock: reserved for synchronization of the chip supporting routines
+ * (not used in the current driver version)
+ * @worker_thread: chip worker thread ID (RT-Linux specific field)
+ * @pend_flags: holds information about pending interrupt and tx_wake() operations
+ * (RT-Linux specific field). Masks values:
+ * %MSGOBJ_TX_REQUEST .. some of the message objects requires tx_wake() call,
+ * %MSGOBJ_IRQ_REQUEST .. chip interrupt processing required
+ * %MSGOBJ_WORKER_WAKE .. marks, that worker thread should be waked
+ * for some of above reasons
+ *
+ * The fields @write_register and @read_register are copied from
+ * corresponding fields from @hwspecops structure
+ * (chip->hostdevice->hwspecops->write_register and
+ * chip->hostdevice->hwspecops->read_register)
+ * to speedup can_write_reg() and can_read_reg() functions.
+ */
+struct canchip_t {
+ char *chip_type;
+ int chip_idx; /* chip index in candevice_t.chip[] */
+ int chip_irq;
+ can_ioptr_t chip_base_addr;
+ unsigned int flags;
+ long clock; /* Chip clock in Hz */
+ long baudrate;
+
+ void (*write_register)(unsigned data, can_ioptr_t address);
+ unsigned (*read_register)(can_ioptr_t address);
+
+ void *chip_data;
+
+ unsigned short sja_cdr_reg; /* sja1000 only! */
+ unsigned short sja_ocr_reg; /* sja1000 only! */
+ unsigned short int_cpu_reg; /* intel 82527 only! */
+ unsigned short int_clk_reg; /* intel 82527 only! */
+ unsigned short int_bus_reg; /* intel 82527 only! */
+
+ struct msgobj_t *msgobj[MAX_MSGOBJS];
+
+ struct chipspecops_t *chipspecops;
+
+ struct candevice_t *hostdevice;
+
+ int max_objects; /* 1 for sja1000, 15 for i82527 */
+
+ can_spinlock_t chip_lock;
+
+ #ifdef CAN_WITH_RTL
+ pthread_t worker_thread;
+ unsigned long pend_flags;
+ #endif /*CAN_WITH_RTL*/
+};
+
+/**
+ * struct msgobj_t - structure holding communication object state
+ * @obj_base_addr:
+ * @minor: associated device minor number
+ * @object: object number in canchip_t structure +1
+ * @flags: message object flags
+ * @ret: field holding status of the last Tx operation
+ * @qends: pointer to message object corresponding ends structure
+ * @tx_qedge: edge corresponding to transmitted message
+ * @tx_slot: slot holding transmitted message, slot is taken from
+ * canque_test_outslot() call and is freed by canque_free_outslot()
+ * or rescheduled canque_again_outslot()
+ * @tx_retry_cnt: transmission attempt counter
+ * @tx_timeout: can be used by chip driver to check for the transmission timeout
+ * @rx_msg: temporary storage to hold received messages before
+ * calling to canque_filter_msg2edges()
+ * @hostchip: pointer to the &canchip_t structure this object belongs to
+ * @obj_used: counter of users (associated file structures for Linux
+ * userspace clients) of this object
+ * @obj_users: list of user structures of type &canuser_t.
+ * @obj_flags: message object specific flags. Masks values:
+ * %MSGOBJ_TX_REQUEST .. the message object requests TX activation
+ * %MSGOBJ_TX_LOCK .. some IRQ routine or callback on some CPU
+ * is running inside TX activation processing code
+ * @rx_preconfig_id: place to store RX message identifier for some chip types
+ * that reuse same object for TX
+ */
+struct msgobj_t {
+ can_ioptr_t obj_base_addr;
+ unsigned int minor; /* associated device minor number */
+ unsigned int object; /* object number in canchip_t +1 for debug printk */
+ unsigned long obj_flags;
+ int ret;
+
+ struct canque_ends_t *qends;
+
+ struct canque_edge_t *tx_qedge;
+ struct canque_slot_t *tx_slot;
+ int tx_retry_cnt;
+ struct timer_list tx_timeout;
+
+ struct canmsg_t rx_msg;
+
+ struct canchip_t *hostchip;
+
+ unsigned long rx_preconfig_id;
+
+ atomic_t obj_used;
+ struct list_head obj_users;
+};
+
+#define CAN_USER_MAGIC 0x05402033
+
+/**
+ * struct canuser_t - structure holding CAN user/client state
+ * @flags: used to distinguish Linux/RT-Linux type
+ * @peers: for connection into list of object users
+ * @qends: pointer to the ends structure corresponding for this user
+ * @msgobj: communication object the user is connected to
+ * @rx_edge0: default receive queue for filter IOCTL
+ * @userinfo: stores user context specific information.
+ * The field @fileinfo.file holds pointer to open device file state structure
+ * for the Linux user-space client applications
+ * @magic: magic number to check consistency when pointer is retrieved
+ * from file private field
+ */
+struct canuser_t {
+ unsigned long flags;
+ struct list_head peers;
+ struct canque_ends_t *qends;
+ struct msgobj_t *msgobj;
+ struct canque_edge_t *rx_edge0; /* simplifies IOCTL */
+ union {
+ struct {
+ struct file *file; /* back ptr to file */
+ } fileinfo;
+ #ifdef CAN_WITH_RTL
+ struct {
+ struct rtl_file *file;
+ } rtlinfo;
+ #endif /*CAN_WITH_RTL*/
+ } userinfo;
+ int magic;
+};
+
+/**
+ * struct hwspecops_t - hardware/board specific operations
+ * @request_io: reserve io or memory range for can board
+ * @release_io: free reserved io memory range
+ * @reset: hardware reset routine
+ * @init_hw_data: called to initialize &candevice_t structure, mainly
+ * @res_add, @nr_all_chips, @nr_82527_chips, @nr_sja1000_chips
+ * and @flags fields
+ * @init_chip_data: called initialize each &canchip_t structure, mainly
+ * @chip_type, @chip_base_addr, @clock and chip specific registers.
+ * It is responsible to setup &canchip_t->@chipspecops functions
+ * for non-standard chip types (type other than "i82527", "sja1000" or "sja1000p")
+ * @init_obj_data: called initialize each &msgobj_t structure,
+ * mainly @obj_base_addr field.
+ * @program_irq: program interrupt generation hardware of the board
+ * if flag %PROGRAMMABLE_IRQ is present for specified device/board
+ * @write_register: low level write register routine
+ * @read_register: low level read register routine
+ */
+struct hwspecops_t {
+ int (*request_io)(struct candevice_t *candev);
+ int (*release_io)(struct candevice_t *candev);
+ int (*reset)(struct candevice_t *candev);
+ int (*init_hw_data)(struct candevice_t *candev);
+ void (*done_hw_data)(struct candevice_t *candev);
+ int (*init_chip_data)(struct candevice_t *candev, int chipnr);
+ int (*init_obj_data)(struct canchip_t *chip, int objnr);
+ int (*program_irq)(struct candevice_t *candev);
+ void (*write_register)(unsigned data, can_ioptr_t address);
+ unsigned (*read_register)(can_ioptr_t address);
+};
+
+/**
+ * struct chipspecops_t - can controller chip specific operations
+ * @chip_config: CAN chip configuration
+ * @baud_rate: set communication parameters
+ * @standard_mask: setup of mask for message filtering
+ * @extended_mask: setup of extended mask for message filtering
+ * @message15_mask: set mask of i82527 message object 15
+ * @clear_objects: clears state of all message object residing in chip
+ * @config_irqs: tunes chip hardware interrupt delivery
+ * @pre_read_config: prepares message object for message reception
+ * @pre_write_config: prepares message object for message transmission
+ * @send_msg: initiate message transmission
+ * @remote_request: configures message object and asks for RTR message
+ * @check_tx_stat: checks state of transmission engine
+ * @wakeup_tx: wakeup TX processing
+ * @filtch_rq: optional routine for propagation of outgoing edges filters to HW
+ * @enable_configuration: enable chip configuration mode
+ * @disable_configuration: disable chip configuration mode
+ * @set_btregs: configures bitrate registers
+ * @attach_to_chip: attaches to the chip, setups registers and possibly state informations
+ * @release_chip: called before chip structure removal if %CHIP_ATTACHED is set
+ * @start_chip: starts chip message processing
+ * @stop_chip: stops chip message processing
+ * @irq_handler: interrupt service routine
+ * @irq_accept: optional fast irq accept routine responsible for blocking further interrupts
+ *
+ * @set_bittiming: set bittiming parameters
+ * @get_bittiming_const: get chip specific constants for bittiming computation
+ */
+struct chipspecops_t {
+ int (*chip_config)(struct canchip_t *chip);
+ int (*baud_rate)(struct canchip_t *chip, int rate, int clock, int sjw,
+ int sampl_pt, int flags);
+ int (*standard_mask)(struct canchip_t *chip, unsigned short code,
+ unsigned short mask);
+ int (*extended_mask)(struct canchip_t *chip, unsigned long code,
+ unsigned long mask);
+ int (*message15_mask)(struct canchip_t *chip, unsigned long code,
+ unsigned long mask);
+ int (*clear_objects)(struct canchip_t *chip);
+ int (*config_irqs)(struct canchip_t *chip, short irqs);
+ int (*pre_read_config)(struct canchip_t *chip, struct msgobj_t *obj);
+ int (*pre_write_config)(struct canchip_t *chip, struct msgobj_t *obj,
+ struct canmsg_t *msg);
+ int (*send_msg)(struct canchip_t *chip, struct msgobj_t *obj,
+ struct canmsg_t *msg);
+ int (*remote_request)(struct canchip_t *chip, struct msgobj_t *obj);
+ int (*check_tx_stat)(struct canchip_t *chip);
+ int (*wakeup_tx)(struct canchip_t *chip, struct msgobj_t *obj);
+ int (*filtch_rq)(struct canchip_t *chip, struct msgobj_t *obj);
+ int (*enable_configuration)(struct canchip_t *chip);
+ int (*disable_configuration)(struct canchip_t *chip);
+ int (*set_btregs)(struct canchip_t *chip, unsigned short btr0,
+ unsigned short btr1);
+ int (*attach_to_chip)(struct canchip_t *chip);
+ int (*release_chip)(struct canchip_t *chip);
+ int (*start_chip)(struct canchip_t *chip);
+ int (*stop_chip)(struct canchip_t *chip);
+ int (*irq_handler)(int irq, struct canchip_t *chip);
+ int (*irq_accept)(int irq, struct canchip_t *chip);
+
+ int (*set_bittiming)(struct canchip_t *chip, int brp, int sjw, int tseg1, int tseg2);
+ int (*get_bittiming_const)(struct canchip_t *chip, struct can_bittiming_const *btc);
+};
+
+struct mem_addr {
+ void *address;
+ struct mem_addr *next;
+ size_t size;
+};
+
+/* Structure for the RTR queue */
+struct rtr_id {
+ unsigned long id;
+ struct canmsg_t *rtr_message;
+ wait_queue_head_t rtr_wq;
+ struct rtr_id *next;
+};
+
+extern int major;
+extern int minor[MAX_TOT_CHIPS];
+extern int extended;
+extern int baudrate[MAX_TOT_CHIPS];
+extern int irq[MAX_IRQ];
+extern char *hw[MAX_HW_CARDS];
+extern unsigned long io[MAX_HW_CARDS];
+extern long clockfreq[MAX_HW_CARDS];
+extern int processlocal;
+
+extern struct canhardware_t *hardware_p;
+extern struct canchip_t *chips_p[MAX_TOT_CHIPS];
+extern struct msgobj_t *objects_p[MAX_TOT_MSGOBJS];
+
+extern struct mem_addr *mem_head;
+
+
+#if defined(CONFIG_OC_LINCAN_PORTIO_ONLY)
+extern inline void can_write_reg(const struct canchip_t *chip, unsigned data, unsigned reg_offs)
+{
+ can_outb(data, chip->chip_base_addr+reg_offs);
+}
+extern inline unsigned can_read_reg(const struct canchip_t *chip, unsigned reg_offs)
+{
+ return can_inb(chip->chip_base_addr+reg_offs);
+}
+extern inline void canobj_write_reg(const struct canchip_t *chip, const struct msgobj_t *obj,
+ unsigned data, unsigned reg_offs)
+{
+ can_outb(data, obj->obj_base_addr+reg_offs);
+}
+extern inline unsigned canobj_read_reg(const struct canchip_t *chip, const struct msgobj_t *obj,
+ unsigned reg_offs)
+{
+ return can_inb(obj->obj_base_addr+reg_offs);
+}
+
+#elif defined(CONFIG_OC_LINCAN_MEMIO_ONLY)
+extern inline void can_write_reg(const struct canchip_t *chip, unsigned data, unsigned reg_offs)
+{
+ can_writeb(data, chip->chip_base_addr+reg_offs);
+}
+extern inline unsigned can_read_reg(const struct canchip_t *chip, unsigned reg_offs)
+{
+ return can_readb(chip->chip_base_addr+reg_offs);
+}
+extern inline void canobj_write_reg(const struct canchip_t *chip, const struct msgobj_t *obj,
+ unsigned data, unsigned reg_offs)
+{
+ can_writeb(data, obj->obj_base_addr+reg_offs);
+}
+extern inline unsigned canobj_read_reg(const struct canchip_t *chip, const struct msgobj_t *obj,
+ unsigned reg_offs)
+{
+ return can_readb(obj->obj_base_addr+reg_offs);
+}
+
+#else /*CONFIG_OC_LINCAN_DYNAMICIO*/
+#ifndef CONFIG_OC_LINCAN_DYNAMICIO
+#define CONFIG_OC_LINCAN_DYNAMICIO
+#endif
+
+/* Inline function to write to the hardware registers. The argument reg_offs is
+ * relative to the memory map of the chip and not the absolute memory reg_offs.
+ */
+extern inline void can_write_reg(const struct canchip_t *chip, unsigned data, unsigned reg_offs)
+{
+ can_ioptr_t address_to_write;
+ address_to_write = chip->chip_base_addr+reg_offs;
+ chip->write_register(data, address_to_write);
+}
+
+extern inline unsigned can_read_reg(const struct canchip_t *chip, unsigned reg_offs)
+{
+ can_ioptr_t address_to_read;
+ address_to_read = chip->chip_base_addr+reg_offs;
+ return chip->read_register(address_to_read);
+}
+
+extern inline void canobj_write_reg(const struct canchip_t *chip, const struct msgobj_t *obj,
+ unsigned data, unsigned reg_offs)
+{
+ can_ioptr_t address_to_write;
+ address_to_write = obj->obj_base_addr+reg_offs;
+ chip->write_register(data, address_to_write);
+}
+
+extern inline unsigned canobj_read_reg(const struct canchip_t *chip, const struct msgobj_t *obj,
+ unsigned reg_offs)
+{
+ can_ioptr_t address_to_read;
+ address_to_read = obj->obj_base_addr+reg_offs;
+ return chip->read_register(address_to_read);
+}
+
+#endif /*CONFIG_OC_LINCAN_DYNAMICIO*/
+
+int can_base_addr_fixup(struct candevice_t *candev, can_ioptr_t new_base);
+int can_request_io_region(unsigned long start, unsigned long n, const char *name);
+void can_release_io_region(unsigned long start, unsigned long n);
+int can_request_mem_region(unsigned long start, unsigned long n, const char *name);
+void can_release_mem_region(unsigned long start, unsigned long n);
+
+#ifdef CAN_ENABLE_PCI_SUPPORT
+struct pci_dev *can_pci_get_next_untaken_device(unsigned int vendor, unsigned int device);
+struct pci_dev *can_pci_get_next_untaken_subsyst(unsigned int vendor, unsigned int device,
+ unsigned int ss_vendor, unsigned int ss_device);
+#endif /*CAN_ENABLE_PCI_SUPPORT*/
+
+struct boardtype_t {
+ const char *boardtype;
+ int (*board_register)(struct hwspecops_t *hwspecops);
+ int irqnum;
+};
+
+const struct boardtype_t* boardtype_find(const char *str);
+
+int can_check_dev_taken(void *anydev);
+
+#if defined(can_gettimeofday) && defined(CAN_MSG_VERSION_2) && 1
+static inline
+void can_filltimestamp(canmsg_tstamp_t *ptimestamp)
+{
+ can_gettimeofday(ptimestamp);
+}
+#else /* No timestamp support, set field to zero */
+static inline
+void can_filltimestamp(canmsg_tstamp_t *ptimestamp)
+{
+ #ifdef CAN_MSG_VERSION_2
+ ptimestamp->tv_sec = 0;
+ ptimestamp->tv_usec = 0;
+ #else /* CAN_MSG_VERSION_2 */
+ *ptimestamp = 0;
+ #endif /* CAN_MSG_VERSION_2 */
+
+}
+#endif /* End of timestamp source selection */
+
+#ifdef CAN_WITH_RTL
+extern int can_rtl_priority;
+#endif /*CAN_WITH_RTL*/
+
+extern struct candevice_t* register_hotplug_dev(const char *hwname,int (*chipdataregfnc)(struct canchip_t *chip,void *data),void *devdata);
+extern void deregister_hotplug_dev(struct candevice_t *dev);
+extern void cleanup_hotplug_dev(struct candevice_t *dev);
+
+#endif /* _CAN_MAIN_H */
+
--- /dev/null
+/**************************************************************************/
+/* File: modparms.h - driver module parameters parsing */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+int parse_mod_parms(void);
--- /dev/null
+/**************************************************************************/
+/* File: setup.h - CAN driver and chips setup code */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+int init_hw_struct(void);
+int init_new_hw_struct(int devnr);
+int list_hw(void);
+void *can_checked_malloc(size_t size);
+int can_checked_free(void *address_p);
+int can_del_mem_list(void);
+int can_chip_setup_irq(struct canchip_t *chip);
+void can_chip_free_irq(struct canchip_t *chip);
--- /dev/null
+/**************************************************************************/
+/* File: sja1000p.h - Philips/NXP SJA1000 chip PeliCanCAN mode support */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Copyright (C) 2004-2005 Tomasz Motylewski (BFAD GmbH) */
+/* Funded by OCERA and FRESCOR IST projects */
+/* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+#ifndef _CAN_SJA1000P_H
+#define _CAN_SJA1000P_H
+
+int sja1000p_chip_config(struct canchip_t *chip);
+int sja1000p_extended_mask(struct canchip_t *chip, unsigned long code, unsigned long mask);
+int sja1000p_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
+ int sampl_pt, int flags);
+int sja1000p_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj);
+int sja1000p_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
+ struct canmsg_t *msg);
+int sja1000p_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
+ struct canmsg_t *msg);
+int sja1000p_fill_chipspecops(struct canchip_t *chip);
+int sja1000p_irq_handler(int irq, struct canchip_t *chip);
+
+
+/* PeliCAN mode */
+enum SJA1000_PeliCAN_regs {
+ SJAMOD = 0x00,
+/// Command register
+ SJACMR = 0x01,
+/// Status register
+ SJASR = 0x02,
+/// Interrupt register
+ SJAIR = 0x03,
+/// Interrupt Enable
+ SJAIER = 0x04,
+/// Bus Timing register 0
+ SJABTR0 = 0x06,
+/// Bus Timing register 1
+ SJABTR1 = 0x07,
+/// Output Control register
+ SJAOCR = 0x08,
+/// Arbitration Lost Capture
+ SJAALC = 0x0b,
+/// Error Code Capture
+ SJAECC = 0x0c,
+/// Error Warning Limit
+ SJAEWLR = 0x0d,
+/// RX Error Counter
+ SJARXERR = 0x0e,
+/// TX Error Counter
+ SJATXERR0 = 0x0e,
+ SJATXERR1 = 0x0f,
+/// Rx Message Counter (number of msgs. in RX FIFO
+ SJARMC = 0x1d,
+/// Rx Buffer Start Addr. (address of current MSG)
+ SJARBSA = 0x1e,
+/// Transmit Buffer (write) Receive Buffer (read) Frame Information
+ SJAFRM = 0x10,
+/// ID bytes (11 bits in 0 and 1 or 16 bits in 0,1 and 13 bits in 2,3 (extended))
+ SJAID0 = 0x11, SJAID1 = 0x12,
+/// ID cont. for extended frames
+ SJAID2 = 0x13, SJAID3 = 0x14,
+/// Data start standard frame
+ SJADATS = 0x13,
+/// Data start extended frame
+ SJADATE = 0x15,
+/// Acceptance Code (4 bytes) in RESET mode
+ SJAACR0 = 0x10,
+/// Acceptance Mask (4 bytes) in RESET mode
+ SJAAMR0 = 0x14,
+/// 4 bytes
+ SJA_PeliCAN_AC_LEN = 4,
+/// Clock Divider
+ SJACDR = 0x1f
+};
+
+/** Mode Register 0x00 */
+enum sja1000_PeliCAN_MOD {
+ sjaMOD_SM = 1<<4, // Sleep Mode (writable only in OPERATING mode)
+ sjaMOD_AFM= 1<<3, // Acceptance Filter Mode (writable only in RESET)
+ sjaMOD_STM= 1<<2, // Self Test Mode (writable only in RESET)
+ sjaMOD_LOM= 1<<1, // Listen Only Mode (writable only in RESET)
+ sjaMOD_RM = 1 // Reset Mode
+};
+
+/** Command Register 0x01 */
+enum sja1000_PeliCAN_CMR {
+ sjaCMR_SRR= 1<<4, // Self Reception Request (GoToSleep in BASIC mode)
+ sjaCMR_CDO= 1<<3, // Clear Data Overrun
+ sjaCMR_RRB= 1<<2, // Release Receive Buffer
+ sjaCMR_AT = 1<<1, // Abort Transmission
+ sjaCMR_TR = 1 }; // Transmission Request
+
+/** Status Register 0x02 */
+enum sja1000_SR {
+ sjaSR_BS = 1<<7, // Bus Status
+ sjaSR_ES = 1<<6, // Error Status
+ sjaSR_TS = 1<<5, // Transmit Status
+ sjaSR_RS = 1<<4, // Receive Status
+ sjaSR_TCS = 1<<3, // Transmission Complete Status
+ sjaSR_TBS = 1<<2, // Transmit Buffer Status
+ sjaSR_DOS = 1<<1, // Data Overrun Status
+ sjaSR_RBS = 1 }; // Receive Buffer Status
+
+/** Interrupt Enable Register 0x04 */
+enum sja1000_PeliCAN_IER {
+ sjaIER_BEIE= 1<<7, // Bus Error Interrupt Enable
+ sjaIER_ALIE= 1<<6, // Arbitration Lost Interrupt Enable
+ sjaIER_EPIE= 1<<5, // Error Passive Interrupt Enable
+ sjaIER_WUIE= 1<<4, // Wake-Up Interrupt Enable
+ sjaIER_DOIE= 1<<3, // Data Overrun Interrupt Enable
+ sjaIER_EIE = 1<<2, // Error Warning Interrupt Enable
+ sjaIER_TIE = 1<<1, // Transmit Interrupt Enable
+ sjaIER_RIE = 1, // Receive Interrupt Enable
+ sjaENABLE_INTERRUPTS = sjaIER_BEIE|sjaIER_EPIE|sjaIER_DOIE|sjaIER_EIE|sjaIER_TIE|sjaIER_RIE,
+ sjaDISABLE_INTERRUPTS = 0
+// WARNING: the chip automatically enters RESET (bus off) mode when
+ // error counter > 255
+};
+
+/** Arbitration Lost Capture Register 0x0b.
+ * Counting starts from 0 (bit1 of ID). Bits 5-7 reserved*/
+enum sja1000_PeliCAN_ALC {
+ sjaALC_SRTR = 0x0b,// Arbitration lost in bit SRTR
+ sjaALC_IDE = 0x1c, // Arbitration lost in bit IDE
+ sjaALC_RTR = 0x1f, // Arbitration lost in RTR
+};
+
+/** Error Code Capture Register 0x0c*/
+enum sja1000_PeliCAN_ECC {
+ sjaECC_ERCC1 = 1<<7,
+ sjaECC_ERCC0 = 1<<6,
+ sjaECC_BIT = 0,
+ sjaECC_FORM = sjaECC_ERCC0,
+ sjaECC_STUFF = sjaECC_ERCC1,
+ sjaECC_OTHER = sjaECC_ERCC0 | sjaECC_ERCC1,
+ sjaECC_DIR = 1<<5, // 1 == RX, 0 == TX
+ sjaECC_SEG_M = (1<<5) -1 // Segment mask, see page 37 of SJA1000 Data Sheet
+};
+
+/** Frame format information 0x10 */
+enum sja1000_PeliCAN_FRM {
+ sjaFRM_FF = 1<<7, // Frame Format 1 == extended, 0 == standard
+ sjaFRM_RTR = 1<<6, // Remote request
+ sjaFRM_DLC_M = (1<<4)-1 // Length Mask
+};
+
+
+/** Interrupt (status) Register 0x03 */
+enum sja1000_PeliCAN_IR {
+ sjaIR_BEI = 1<<7, // Bus Error Interrupt
+ sjaIR_ALI = 1<<6, // Arbitration Lost Interrupt
+ sjaIR_EPI = 1<<5, // Error Passive Interrupt (entered error passive state or error active state)
+ sjaIR_WUI = 1<<4, // Wake-Up Interrupt
+ sjaIR_DOI = 1<<3, // Data Overrun Interrupt
+ sjaIR_EI = 1<<2, // Error Interrupt
+ sjaIR_TI = 1<<1, // Transmit Interrupt
+ sjaIR_RI = 1 // Receive Interrupt
+};
+
+/** Bus Timing 1 Register 0x07 */
+enum sja1000_BTR1 {
+ sjaMAX_TSEG1 = 15,
+ sjaMAX_TSEG2 = 7
+};
+
+/** Output Control Register 0x08 */
+enum sja1000_OCR {
+ sjaOCR_MODE_BIPHASE = 0,
+ sjaOCR_MODE_TEST = 1,
+ sjaOCR_MODE_NORMAL = 2,
+ sjaOCR_MODE_CLOCK = 3,
+/// TX0 push-pull not inverted
+ sjaOCR_TX0_LH = 0x18,
+/// TX1 floating (off)
+ sjaOCR_TX1_ZZ = 0
+};
+
+/** Clock Divider register 0x1f */
+enum sja1000_CDR {
+ sjaCDR_PELICAN = 1<<7,
+/// bypass input comparator
+ sjaCDR_CBP = 1<<6,
+/// switch TX1 to generate RX INT
+ sjaCDR_RXINPEN = 1<<5,
+ sjaCDR_CLK_OFF = 1<<3,
+/// f_out = f_osc/(2*(CDR[2:0]+1)) or f_osc if CDR[2:0]==7
+ sjaCDR_CLKOUT_DIV1 = 7,
+ sjaCDR_CLKOUT_DIV2 = 0,
+ sjaCDR_CLKOUT_DIV4 = 1,
+ sjaCDR_CLKOUT_DIV6 = 2,
+ sjaCDR_CLKOUT_DIV8 = 3,
+ sjaCDR_CLKOUT_DIV10 = 4,
+ sjaCDR_CLKOUT_DIV12 = 5,
+ sjaCDR_CLKOUT_DIV14 = 6,
+ sjaCDR_CLKOUT_MASK = 7
+};
+
+/** flags for sja1000_baud_rate */
+#define BTR1_SAM (1<<1)
+
+#endif /* _CAN_SJA1000P_H */
--- /dev/null
+#ifndef _UL_LISTBASE_H
+#define _UL_LISTBASE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __KERNEL__
+
+#define LIST_POISON1 ((void *) 0)
+#define LIST_POISON2 ((void *) 0)
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+#define INIT_LIST_HEAD(ptr) do { \
+ (ptr)->next = (ptr); (ptr)->prev = (ptr); \
+} while (0)
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_add(struct list_head *new,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+ prev->next = new;
+}
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head, head->next);
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+static inline void list_del(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ entry->next = LIST_POISON1;
+ entry->prev = LIST_POISON2;
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static inline void list_del_init(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(struct list_head *list,
+ struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add_tail(list, head);
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(struct list_head *head)
+{
+ return head->next == head;
+}
+
+static inline void __list_splice(struct list_head *list,
+ struct list_head *head)
+{
+ struct list_head *first = list->next;
+ struct list_head *last = list->prev;
+ struct list_head *where = head->next;
+
+ first->prev = head;
+ head->next = first;
+
+ last->next = where;
+ where->prev = last;
+}
+
+/**
+ * list_splice - join two lists
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice(struct list_head *list, struct list_head *head)
+{
+ if (!list_empty(list))
+ __list_splice(list, head);
+}
+
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list)) {
+ __list_splice(list, head);
+ INIT_LIST_HEAD(list);
+ }
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr: the &struct list_head pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+/**
+ * list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop counter.
+ * @head: the head for your list.
+ */
+#define list_for_each(pos, head) \
+ for (pos = (head)->next, prefetch(pos->next); pos != (head); \
+ pos = pos->next, prefetch(pos->next))
+
+/**
+ * __list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop counter.
+ * @head: the head for your list.
+ *
+ * This variant differs from list_for_each() in that it's the
+ * simplest possible list iteration code, no prefetching is done.
+ * Use this for code that knows the list to be very short (empty
+ * or 1 entry) most of the time.
+ */
+#define __list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_prev - iterate over a list backwards
+ * @pos: the &struct list_head to use as a loop counter.
+ * @head: the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+ for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \
+ pos = pos->prev, prefetch(pos->prev))
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop counter.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+/**
+ * list_for_each_entry - iterate over list of given type
+ * @pos: the type * to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ prefetch(pos->member.next); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member), \
+ prefetch(pos->member.next))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos: the type * to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member), \
+ prefetch(pos->member.prev); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.prev, typeof(*pos), member), \
+ prefetch(pos->member.prev))
+
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos: the type * to use as a loop counter.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+#else /*__KERNEL__*/
+
+#include <linux/list.h>
+
+#endif /*__KERNEL__*/
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif /* _UL_LISTBASE_H */
--- /dev/null
+#ifndef UL_USB1_H
+#define UL_USB1_H
+
+/* ul_usb1.h
+ * Header file for the Linux CAN-bus driver.
+ * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
+ * Rewritten for new CAN queues by Pavel Pisa - OCERA team member
+ * email:pisa@cmp.felk.cvut.cz
+ * This software is released under the GPL-License.
+ * Version lincan-0.3 17 Jun 2004
+ */
+
+struct ul_usb1_chip_data
+{
+ int flags;
+};
+
+#define UL_USB1_CHIP_MASK_SET (1<<0)
+#define UL_USB1_CHIP_BAUD_SET (1<<1)
+
+int ul_usb1_init(void);
+void ul_usb1_exit(void);
+
+extern int ul_usb1_register(struct hwspecops_t *hwspecops);
+
+#endif /* UL_USB1_H */
--- /dev/null
+/**
+can.c
+
+Routines for sending and receiving messages for configuration and/or
+communication over CAN network using a SJA1000 transceiver.
+For use in UL_USB1 module, it runs in Intel mode.
+See documentation for details.
+
+*/
+
+
+#include "can/can.h"
+
+
+/***********************************************************************
+ * Microsecond delay routine
+ ***********************************************************************/
+void udelay(long time)
+{
+ volatile long ticks=(time * CCLK) / 2000000;
+ do{
+ ticks--;
+ } while(ticks>0);
+}
+
+
+inline void can_data_pins_dir_output(void)
+{
+ IO1DIR|=P1_SJA1000_DATA_PINS; // Port as output to send data
+}
+
+inline void can_data_pins_dir_input(void)
+{
+ IO1DIR&=~P1_SJA1000_DATA_PINS; // Sets port as input
+}
+
+inline void can_data_pins_set_value(uint8_t data)
+{
+ uint32_t val = __val2mfld(P1_SJA1000_DATA_PINS,data);
+ /*
+ * Clear only that pins, which need that, lower transition
+ * frequency and eliminate spikes
+ */
+ IO1CLR= val ^ P1_SJA1000_DATA_PINS;
+ IO1SET= val;
+}
+
+inline uint8_t can_data_pins_get_value(void)
+{
+ return __mfld2val(P1_SJA1000_DATA_PINS,IO1PIN);
+}
+
+
+void can_comm_init()
+{
+ //CANMSG("Start can_comm_init\n");
+ IO1DIR |= P1_OUT_PORT_CS_PIN|P1_SJA1000_RST_PIN;
+ // Due to change in design there is CS_PIN connected with ALE_PIN and ALE_PIN connection to LPC is interrupted
+ // We don't use ALE_PIN
+ //IO0DIR|=P0_SJA1000_ALE_PIN|P0_SJA1000_CS_PIN|P0_SJA1000_RD_PIN|P0_SJA1000_WR_PIN;
+ IO0DIR|=P0_SJA1000_CS_PIN|P0_SJA1000_RD_PIN|P0_SJA1000_WR_PIN;
+ IO0DIR&=~(P0_SJA1000_INT_PIN);
+
+ SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
+ CLR_OUT_PIN(IO1,P1_SJA1000_RST_PIN);
+ SJA1000_INIT_DELAY();
+ SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
+ // Due to change in design there is CS_PIN connected with ALE_PIN and ALE_PIN connection to LPC is interrupted
+ // CLR_OUT_PIN(IO0,P0_SJA1000_ALE_PIN);
+ SET_OUT_PIN(IO1,P1_SJA1000_RST_PIN);
+ SJA1000_INIT_DELAY();
+}
+
+void can_write(uint8_t data, uint8_t address)
+{
+ can_data_pins_dir_output();
+ // Set memory address
+ can_data_pins_set_value(address);
+ // Init
+ SET_OUT_PIN(IO0,P0_SJA1000_RD_PIN); // Stays high on write
+ SET_OUT_PIN(IO0,P0_SJA1000_WR_PIN); // Stays high on address write
+ SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN); // Sets output buffers to third state
+ //SJA1000_DELAY();
+ //SET_OUT_PIN(IO0,P0_SJA1000_ALE_PIN); // Start command
+
+ //SJA1000_DELAY();
+ //CLR_OUT_PIN(IO0,P0_SJA1000_ALE_PIN); // Makes address active
+ CLR_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
+ //SJA1000_DELAY();
+
+ // Setting data
+ can_data_pins_set_value(data);
+
+ CLR_OUT_PIN(IO0,P0_SJA1000_WR_PIN);
+ CLR_OUT_PIN(IO0,P0_SJA1000_WR_PIN);
+ //SJA1000_DELAY();
+ SET_OUT_PIN(IO0,P0_SJA1000_WR_PIN); // Data should be accepted by now
+ SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
+ //SJA1000_DELAY();
+}
+
+uint8_t can_read(const uint8_t address)
+{
+ uint8_t data;
+
+ can_data_pins_dir_output();
+ // Set memory address
+ can_data_pins_set_value(address);
+ // Init
+ SET_OUT_PIN(IO0,P0_SJA1000_WR_PIN); // Stays high on read
+ SET_OUT_PIN(IO0,P0_SJA1000_RD_PIN); // Stays high while entering address
+ SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
+ //SJA1000_DELAY();
+ //SET_OUT_PIN(IO0,P0_SJA1000_ALE_PIN);
+
+ //SJA1000_DELAY();
+ //CLR_OUT_PIN(IO0,P0_SJA1000_ALE_PIN);
+ CLR_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
+
+ // Get data
+
+ can_data_pins_dir_input();
+ CLR_OUT_PIN(IO0,P0_SJA1000_RD_PIN);
+ CLR_OUT_PIN(IO0,P0_SJA1000_RD_PIN);
+ //SJA1000_DELAY();
+ data = can_data_pins_get_value();
+ SET_OUT_PIN(IO0,P0_SJA1000_RD_PIN);
+ SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
+ //SJA1000_DELAY();
+
+ return data;
+}
+
+int can_init(){
+ uint8_t data=0,count=0;
+ do {
+ can_comm_init();
+ data = can_read(SJAMOD);
+ if (count++ > 50)
+ return -1;
+ } while (!(data&sjaMOD_RM));
+
+ data=sjaCDR_CLKOUT_DIV1|sjaCDR_CLK_OFF|sjaCDR_CBP|sjaCDR_PELICAN;
+ can_write(data, SJACDR);
+
+ // Single acceptance filter, reset mode
+ data=sjaMOD_AFM|sjaMOD_RM;
+ can_write(data, SJAMOD);
+
+ // Enabling all interrupt sources
+ data=sjaENABLE_INTERRUPTS;
+ can_write(data, SJAIER);
+
+ // Accept all messages
+ data=0xFF;
+ can_write(data, SJAAMR0);
+ can_write(data, SJAAMR0+1);
+ can_write(data, SJAAMR0+2);
+ can_write(data, SJAAMR0+3);
+
+ data=sjaCMR_CDO;
+ can_write(data, SJACMR);
+
+ return 0;
+}
--- /dev/null
+/**************************************************************************/
+/* File: can_quesysless.c - CAN queue functions for embedded target */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+#include "./can/can.h"
+#include "./can/can_sysdep.h"
+#include "./can/can_queue.h"
+
+// #define CAN_DEBUG
+
+extern atomic_t edge_num_cnt;
+
+#ifdef CAN_DEBUG
+ #define DEBUGQUE(fmt,args...) can_printk(KERN_ERR "can_quesysless (debug): " fmt,\
+ ##args)
+
+#else
+ #define DEBUGQUE(fmt,args...)
+#endif
+
+#define ERRMSGQUE(fmt,args...) can_printk(KERN_ERR "can_quesysless: " fmt,\
+ ##args)
+
+
+/*
+ * Modifies Tx message processing
+ * 0 .. local message processing disabled
+ * 1 .. local messages disabled by default but can be enabled by canque_set_filt
+ * 2 .. local messages enabled by default, can be disabled by canque_set_filt
+ */
+extern int processlocal;
+
+void canque_dead_func(unsigned long data);
+
+/* Support for dead ends structures left after client close */
+can_spinlock_t canque_dead_func_lock;
+LIST_HEAD(canque_dead_ends);
+/* retrieved by list_entry(canque_dead_ends.next,struct canque_ends_t,dead_peers) */
+LIST_HEAD(canque_dead_edges);
+/* retrieved by list_entry(canque_dead_edges.next,struct canque_edge_t,inpeers) */
+// DECLARE_TASKLET(canque_dead_tl, canque_dead_func, 0);
+/* activated by tasklet_schedule(&canque_dead_tl) */
+
+
+static inline
+struct canque_edge_t *canque_dead_edges_cut_first(void)
+{
+ can_spin_irqflags_t flags;
+ struct canque_edge_t *edge;
+ can_spin_lock_irqsave(&canque_dead_func_lock, flags);
+ if(list_empty(&canque_dead_edges))
+ edge=NULL;
+ else{
+ edge=list_entry(canque_dead_edges.next,struct canque_edge_t,inpeers);
+ list_del(&edge->inpeers);
+ }
+ can_spin_unlock_irqrestore(&canque_dead_func_lock, flags);
+ return edge;
+}
+
+void canque_dead_func(unsigned long data)
+{
+ can_spin_irqflags_t flags;
+ struct canque_edge_t *qedge;
+ struct canque_ends_t *qends;
+ struct list_head *entry;
+
+ while((qedge=canque_dead_edges_cut_first())){
+ DEBUGQUE("edge %d disposed\n",qedge->edge_num);
+ #ifdef CAN_WITH_RTL
+ if(canque_fifo_test_fl(&qedge->fifo,RTL_MEM)){
+ canque_dispose_edge_rtl(qedge);
+ continue;
+ }
+ #endif /*CAN_WITH_RTL*/
+ canque_fifo_done_kern(&qedge->fifo);
+ free(qedge);
+ }
+
+ can_spin_lock_irqsave(&canque_dead_func_lock, flags);
+ entry=canque_dead_ends.next;
+ while(entry!=&canque_dead_ends){
+ qends=list_entry(entry,struct canque_ends_t,dead_peers);
+ entry=entry->next;
+ if(!list_empty(&qends->inlist))
+ continue;
+ if(!list_empty(&qends->outlist))
+ continue;
+ can_spin_lock_irqsave(&canque_dead_func_lock, flags);
+ list_del(&qends->dead_peers);
+ can_spin_unlock_irqrestore(&canque_dead_func_lock,flags);
+ DEBUGQUE("ends structure disposed\n");
+ #ifdef CAN_WITH_RTL
+ if(qends->ends_flags&CAN_ENDSF_MEM_RTL){
+ canque_ends_free_rtl(qends);
+ continue;
+ }
+ #endif /*CAN_WITH_RTL*/
+ free(qends);
+ }
+ can_spin_unlock_irqrestore(&canque_dead_func_lock,flags);
+}
+
+// static inline void canque_dead_tasklet_schedule(void)
+// {
+// #ifdef CAN_WITH_RTL
+// if(!rtl_rt_system_is_idle()){
+// set_bit(CAN_RTL2LIN_PEND_DEAD_b,&canqueue_rtl2lin_pend);
+// rtl_global_pend_irq (canqueue_rtl_irq);
+// return;
+// }
+// #endif /*CAN_WITH_RTL*/
+//
+// tasklet_schedule(&canque_dead_tl);
+// }
+
+
+void canque_edge_do_dead(struct canque_edge_t *edge)
+{
+ can_spin_irqflags_t flags;
+
+ canque_notify_bothends(edge,CANQUEUE_NOTIFY_NOUSR);
+ #ifdef CAN_WITH_RTL
+ /* The problem of the above call is, that in RT-Linux to Linux notify
+ case is edge scheduled for delayed notify delivery, this needs
+ to be reflected there */
+ if(atomic_read(&edge->edge_used)>0){
+ can_spin_lock_irqsave(&edge->inends->ends_lock, flags);
+ can_spin_lock(&edge->outends->ends_lock);
+ if(atomic_read(&edge->edge_used)>0){
+ /* left edge to live for a while, banshee comes again in a while */
+ canque_fifo_clear_fl(&edge->fifo,DEAD);
+ can_spin_unlock(&edge->outends->ends_lock);
+ can_spin_unlock_irqrestore(&edge->inends->ends_lock, flags);
+ can_printk(KERN_ERR "can_quertl (debug): canque_edge_do_dead postponed\n");
+ return;
+ }
+ can_spin_unlock(&edge->outends->ends_lock);
+ can_spin_unlock_irqrestore(&edge->inends->ends_lock, flags);
+ }
+ #endif /*CAN_WITH_RTL*/
+
+ if(canqueue_disconnect_edge(edge)<0){
+ ERRMSGQUE("canque_edge_do_dead: canqueue_disconnect_edge failed !!!\n");
+ return;
+ }
+
+ can_spin_lock_irqsave(&canque_dead_func_lock, flags);
+ list_add(&edge->inpeers,&canque_dead_edges);
+ can_spin_unlock_irqrestore(&canque_dead_func_lock, flags);
+// canque_dead_tasklet_schedule();
+ canque_dead_func(0);
+}
+
+
+
+/*if(qends->ends_flags & CAN_ENDSF_DEAD){
+ can_spin_lock_irqsave(&canque_dead_func_lock, flags);
+ list_del(&qends->dead_peers);
+ list_add(&qends->dead_peers,&canque_dead_ends);
+ can_spin_unlock_irqrestore(&canque_dead_func_lock, flags);
+ tasklet_schedule(&canque_dead_tl);
+}*/
+
+
+/**
+ * canqueue_notify_kern - notification callback handler for Linux userspace clients
+ * @qends: pointer to the callback side ends structure
+ * @qedge: edge which invoked notification
+ * @what: notification type
+ *
+ * The notification event is handled directly by call of this function except case,
+ * when called from RT-Linux context in mixed mode Linux/RT-Linux compilation.
+ * It is not possible to directly call Linux kernel synchronization primitives
+ * in such case. The notification request is postponed and signaled by @pending_inops flags
+ * by call canqueue_rtl2lin_check_and_pend() function.
+ * The edge reference count is increased until until all pending notifications are processed.
+ */
+void canqueue_notify_kern(struct canque_ends_t *qends, struct canque_edge_t *qedge, int what)
+{
+ DEBUGQUE("canqueue_notify_kern for edge %d, use %d and event %d\n",
+ qedge->edge_num,(int)atomic_read(&qedge->edge_used),what);
+
+ /* delay event delivery for RT-Linux -> kernel notifications */
+ if(canqueue_rtl2lin_check_and_pend(qends,qedge,what)){
+ DEBUGQUE("canqueue_notify_kern postponed\n");
+ return;
+ }
+
+ switch(what){
+ case CANQUEUE_NOTIFY_EMPTY:
+// wake_up(&qends->endinfo.fileinfo.emptyq);
+ if(canque_fifo_test_and_clear_fl(&qedge->fifo, FREEONEMPTY))
+ canque_edge_decref(qedge);
+ break;
+ case CANQUEUE_NOTIFY_SPACE:
+// wake_up(&qends->endinfo.fileinfo.writeq);
+ #ifdef CAN_ENABLE_KERN_FASYNC
+ /* Asynchronous I/O processing */
+ kill_fasync(&qends->endinfo.fileinfo.fasync, SIGIO, POLL_OUT);
+ #endif /*CAN_ENABLE_KERN_FASYNC*/
+ break;
+ case CANQUEUE_NOTIFY_PROC:
+// wake_up(&qends->endinfo.fileinfo.readq);
+ #ifdef CAN_ENABLE_KERN_FASYNC
+ /* Asynchronous I/O processing */
+ kill_fasync(&qends->endinfo.fileinfo.fasync, SIGIO, POLL_IN);
+ #endif /*CAN_ENABLE_KERN_FASYNC*/
+ break;
+ case CANQUEUE_NOTIFY_NOUSR:
+// wake_up(&qends->endinfo.fileinfo.readq);
+// wake_up(&qends->endinfo.fileinfo.writeq);
+// wake_up(&qends->endinfo.fileinfo.emptyq);
+ break;
+ case CANQUEUE_NOTIFY_DEAD_WANTED:
+ case CANQUEUE_NOTIFY_DEAD:
+ if(canque_fifo_test_and_clear_fl(&qedge->fifo, READY))
+ canque_edge_decref(qedge);
+ break;
+ case CANQUEUE_NOTIFY_ATTACH:
+ break;
+ }
+}
+
+/**
+ * canqueue_ends_init_kern - Linux userspace clients specific ends initialization
+ * @qends: pointer to the callback side ends structure
+ */
+int canqueue_ends_init_kern(struct canque_ends_t *qends)
+{
+ canqueue_ends_init_gen(qends);
+ qends->context=NULL;
+ init_waitqueue_head(&qends->endinfo.fileinfo.readq);
+ init_waitqueue_head(&qends->endinfo.fileinfo.writeq);
+ init_waitqueue_head(&qends->endinfo.fileinfo.emptyq);
+ #ifdef CAN_ENABLE_KERN_FASYNC
+ qends->endinfo.fileinfo.fasync=NULL;
+ #endif /*CAN_ENABLE_KERN_FASYNC*/
+
+ qends->notify=canqueue_notify_kern;
+ DEBUGQUE("canqueue_ends_init_kern\n");
+ return 0;
+}
+
+
+/**
+ * canque_get_inslot4id_wait_kern - find or wait for best outgoing edge and slot for given ID
+ * @qends: ends structure belonging to calling communication object
+ * @qedgep: place to store pointer to found edge
+ * @slotp: place to store pointer to allocated slot
+ * @cmd: command type for slot
+ * @id: communication ID of message to send into edge
+ * @prio: optional priority of message
+ *
+ * Same as canque_get_inslot4id(), except, that it waits for free slot
+ * in case, that queue is full. Function is specific for Linux userspace clients.
+ * Return Value: If there is no usable edge negative value is returned.
+ */
+// int canque_get_inslot4id_wait_kern(struct canque_ends_t *qends,
+// struct canque_edge_t **qedgep, struct canque_slot_t **slotp,
+// int cmd, unsigned long id, int prio)
+// {
+// int ret=-1;
+// DEBUGQUE("canque_get_inslot4id_wait_kern for cmd %d, id %ld, prio %d\n",cmd,id,prio);
+// wait_event_interruptible((qends->endinfo.fileinfo.writeq),
+// (ret=canque_get_inslot4id(qends,qedgep,slotp,cmd,id,prio))!=-1);
+// return ret;
+// }
+
+/**
+ * canque_get_outslot_wait_kern - receive or wait for ready slot for given ends
+ * @qends: ends structure belonging to calling communication object
+ * @qedgep: place to store pointer to found edge
+ * @slotp: place to store pointer to received slot
+ *
+ * The same as canque_test_outslot(), except it waits in the case, that there is
+ * no ready slot for given ends. Function is specific for Linux userspace clients.
+ * Return Value: Negative value informs, that there is no ready output
+ * slot for given ends. Positive value is equal to the command
+ * slot has been allocated by the input side.
+ */
+// int canque_get_outslot_wait_kern(struct canque_ends_t *qends,
+// struct canque_edge_t **qedgep, struct canque_slot_t **slotp)
+// {
+// int ret=-1;
+// DEBUGQUE("canque_get_outslot_wait_kern\n");
+// wait_event_interruptible((qends->endinfo.fileinfo.readq),
+// (ret=canque_test_outslot(qends,qedgep,slotp))!=-1);
+// return ret;
+// }
+
+/**
+ * canque_sync_wait_kern - wait for all slots processing
+ * @qends: ends structure belonging to calling communication object
+ * @qedge: pointer to edge
+ *
+ * Functions waits for ends transition into empty state.
+ * Return Value: Positive value indicates, that edge empty state has been reached.
+ * Negative or zero value informs about interrupted wait or other problem.
+ */
+// int canque_sync_wait_kern(struct canque_ends_t *qends, struct canque_edge_t *qedge)
+// {
+// int ret=-1;
+// DEBUGQUE("canque_sync_wait_kern\n");
+// wait_event_interruptible((qends->endinfo.fileinfo.emptyq),
+// (ret=canque_fifo_test_fl(&qedge->fifo,EMPTY)?1:0));
+// return ret;
+// }
+
+
+/**
+ * canque_fifo_init_kern - initialize one CAN FIFO
+ * @fifo: pointer to the FIFO structure
+ * @slotsnr: number of requested slots
+ *
+ * Return Value: The negative value indicates, that there is no memory
+ * to allocate space for the requested number of the slots.
+ */
+int canque_fifo_init_kern(struct canque_fifo_t *fifo, int slotsnr)
+{
+ int size;
+ if(!slotsnr) slotsnr=MAX_BUF_LENGTH;
+ size=sizeof(struct canque_slot_t)*slotsnr;
+ fifo->entry=malloc(size);
+ if(!fifo->entry) return -1;
+ fifo->slotsnr=slotsnr;
+ return canque_fifo_init_slots(fifo);
+}
+
+/**
+ * canque_fifo_done_kern - frees slots allocated for CAN FIFO
+ * @fifo: pointer to the FIFO structure
+ */
+int canque_fifo_done_kern(struct canque_fifo_t *fifo)
+{
+ if(fifo->entry)
+ free(fifo->entry);
+ fifo->entry=NULL;
+ return 1;
+}
+
+
+/**
+ * canque_new_edge_kern - allocate new edge structure in the Linux kernel context
+ * @slotsnr: required number of slots in the newly allocated edge structure
+ *
+ * Return Value: Returns pointer to allocated slot structure or %NULL if
+ * there is not enough memory to process operation.
+ */
+struct canque_edge_t *canque_new_edge_kern(int slotsnr)
+{
+ struct canque_edge_t *qedge;
+ qedge = (struct canque_edge_t *)malloc(sizeof(struct canque_edge_t));
+ if(qedge == NULL) return NULL;
+
+ memset(qedge,0,sizeof(struct canque_edge_t));
+ can_spin_lock_init(&qedge->fifo.fifo_lock);
+ if(canque_fifo_init_kern(&qedge->fifo, slotsnr)<0){
+ free(qedge);
+ DEBUGQUE("canque_new_edge_kern failed\n");
+ return NULL;
+ }
+ atomic_set(&qedge->edge_used,1);
+ qedge->filtid = 0;
+ qedge->filtmask = canque_filtid2internal(0l, (processlocal<2)? MSG_LOCAL:0);
+ qedge->edge_prio = 0;
+ #ifdef CAN_DEBUG
+ /* not exactly clean, but enough for debugging */
+ atomic_inc(&edge_num_cnt);
+ qedge->edge_num=atomic_read(&edge_num_cnt);
+ #endif /* CAN_DEBUG */
+ DEBUGQUE("canque_new_edge_kern %d\n",qedge->edge_num);
+ return qedge;
+}
+
+#ifdef USE_SYNC_DISCONNECT_EDGE_KERN
+
+/*not included in doc
+ * canqueue_disconnect_edge_kern - disconnect edge from communicating entities with wait
+ * @qends: ends structure belonging to calling communication object
+ * @qedge: pointer to edge
+ *
+ * Same as canqueue_disconnect_edge(), but tries to wait for state with zero
+ * use counter.
+ * Return Value: Negative value means, that edge is used and cannot
+ * be disconnected yet. Operation has to be delayed.
+ */
+int canqueue_disconnect_edge_kern(struct canque_ends_t *qends, struct canque_edge_t *qedge)
+{
+ canque_fifo_set_fl(&qedge->fifo,BLOCK);
+ DEBUGQUE("canqueue_disconnect_edge_kern %d called\n",qedge->edge_num);
+ if(!canque_fifo_test_and_set_fl(&qedge->fifo,DEAD)){
+ canque_notify_bothends(qedge, CANQUEUE_NOTIFY_DEAD);
+
+ if(atomic_read(&qedge->edge_used)>0)
+ atomic_dec(&qedge->edge_used);
+
+ DEBUGQUE("canqueue_disconnect_edge_kern %d waiting\n",qedge->edge_num);
+ wait_event((qends->endinfo.fileinfo.emptyq),
+ (canqueue_disconnect_edge(qedge)>=0));
+
+ /*set_current_state(TASK_UNINTERRUPTIBLE);*/
+ /*schedule_timeout(HZ);*/
+ return 0;
+ } else {
+ DEBUGQUE("canqueue_disconnect_edge_kern cannot set DEAD\n");
+ return -1;
+ }
+}
+
+
+int canqueue_disconnect_list_kern(struct canque_ends_t *qends, struct list_head *list)
+{
+ struct canque_edge_t *edge;
+ can_spin_irqflags_t flags;
+ for(;;){
+ can_spin_lock_irqsave(&qends->ends_lock,flags);
+ if(list_empty(list)){
+ can_spin_unlock_irqrestore(&qends->ends_lock,flags);
+ return 0;
+ }
+ if(list == &qends->inlist)
+ edge=list_entry(list->next,struct canque_edge_t,inpeers);
+ else
+ edge=list_entry(list->next,struct canque_edge_t,outpeers);
+ atomic_inc(&edge->edge_used);
+ can_spin_unlock_irqrestore(&qends->ends_lock,flags);
+ if(canqueue_disconnect_edge_kern(qends, edge)>=0) {
+ /* Free edge memory */
+ canque_fifo_done_kern(&edge->fifo);
+ free(edge);
+ }else{
+ canque_notify_bothends(edge, CANQUEUE_NOTIFY_DEAD_WANTED);
+ canque_edge_decref(edge);
+ DEBUGQUE("canqueue_disconnect_list_kern in troubles\n");
+ DEBUGQUE("the edge %d has usage count %d and flags %ld\n",edge->edge_num,atomic_read(&edge->edge_used),edge->fifo.fifo_flags);
+ return -1;
+ }
+ }
+}
+
+#endif /*USE_SYNC_DISCONNECT_EDGE_KERN*/
+
+
+// int canqueue_ends_sync_all_kern(struct canque_ends_t *qends)
+// {
+// struct canque_edge_t *qedge;
+//
+// canque_for_each_inedge(qends, qedge){
+// DEBUGQUE("canque_sync_wait_kern called for edge %d\n",qedge->edge_num);
+// canque_sync_wait_kern(qends, qedge);
+// }
+// return 0;
+// }
+
+
+void canqueue_ends_dispose_postpone(struct canque_ends_t *qends)
+{
+ can_spin_irqflags_t flags;
+
+ can_spin_lock_irqsave(&canque_dead_func_lock, flags);
+ qends->ends_flags |= CAN_ENDSF_DEAD;
+ list_add(&qends->dead_peers,&canque_dead_ends);
+ can_spin_unlock_irqrestore(&canque_dead_func_lock, flags);
+ canque_dead_func(0);
+// canque_dead_tasklet_schedule();
+}
+
+
+/**
+ * canqueue_ends_dispose_kern - finalizing of the ends structure for Linux kernel clients
+ * @qends: pointer to ends structure
+ * @sync: flag indicating, that user wants to wait for processing of all remaining
+ * messages
+ *
+ * Return Value: Function should be designed such way to not fail.
+ */
+// int canqueue_ends_dispose_kern(struct canque_ends_t *qends, int sync)
+// {
+// int delayed;
+//
+// DEBUGQUE("canqueue_ends_dispose_kern\n");
+// canqueue_block_inlist(qends);
+// canqueue_block_outlist(qends);
+//
+// /*Wait for sending of all pending messages in the output FIFOs*/
+// if(sync)
+// canqueue_ends_sync_all_kern(qends);
+//
+// /* Finish or kill all outgoing edges listed in inends */
+// delayed=canqueue_ends_kill_inlist(qends, 1);
+// /* Kill all incoming edges listed in outends */
+// delayed|=canqueue_ends_kill_outlist(qends);
+//
+// // wake_up(&qends->endinfo.fileinfo.readq);
+// // wake_up(&qends->endinfo.fileinfo.writeq);
+// // wake_up(&qends->endinfo.fileinfo.emptyq);
+//
+// if(delayed){
+// canqueue_ends_dispose_postpone(qends);
+//
+// DEBUGQUE("canqueue_ends_dispose_kern delayed\n");
+// return 1;
+// }
+//
+// free(qends);
+// DEBUGQUE("canqueue_ends_dispose_kern finished\n");
+// return 0;
+// }
+
+void canqueue_kern_initialize()
+{
+ can_spin_lock_init(&canque_dead_func_lock);
+}
--- /dev/null
+/**************************************************************************/
+/* File: can_queue.c - CAN message queues */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+#include "./can/can.h"
+#include "./can/can_sysdep.h"
+#include "./can/can_queue.h"
+
+/*
+ * Modifies Tx message processing
+ * 0 .. local message processing disabled
+ * 1 .. local messages disabled by default but can be enabled by canque_set_filt
+ * 2 .. local messages enabled by default, can be disabled by canque_set_filt
+ */
+extern int processlocal;
+
+atomic_t edge_num_cnt;
+
+//#define CAN_DEBUG
+#undef CAN_DEBUG
+
+#ifdef CAN_DEBUG
+ #define DEBUGQUE(fmt,args...) can_printk(KERN_ERR "can_queue (debug): " fmt,\
+ ##args)
+
+#else
+ #define DEBUGQUE(fmt,args...)
+#endif
+
+#define CANQUE_ROUNDROB 1
+
+
+/**
+ * canque_fifo_flush_slots - free all ready slots from the FIFO
+ * @fifo: pointer to the FIFO structure
+ *
+ * The caller should be prepared to handle situations, when some
+ * slots are held by input or output side slots processing.
+ * These slots cannot be flushed or their processing interrupted.
+ *
+ * Return Value: The nonzero value indicates, that queue has not been
+ * empty before the function call.
+ */
+int canque_fifo_flush_slots(struct canque_fifo_t *fifo)
+{
+ int ret;
+ can_spin_irqflags_t flags;
+ struct canque_slot_t *slot;
+ can_spin_lock_irqsave(&fifo->fifo_lock, flags);
+ slot=fifo->head;
+ if(slot){
+ *fifo->tail=fifo->flist;
+ fifo->flist=slot;
+ fifo->head=NULL;
+ fifo->tail=&fifo->head;
+ }
+ canque_fifo_clear_fl(fifo,FULL);
+ ret=canque_fifo_test_and_set_fl(fifo,EMPTY)?0:1;
+ can_spin_unlock_irqrestore(&fifo->fifo_lock, flags);
+ return ret;
+}
+
+
+/**
+ * canque_fifo_init_slots - initializes slot chain of one CAN FIFO
+ * @fifo: pointer to the FIFO structure
+ *
+ * Return Value: The negative value indicates, that there is no memory
+ * to allocate space for the requested number of the slots.
+ */
+int canque_fifo_init_slots(struct canque_fifo_t *fifo)
+{
+ struct canque_slot_t *slot;
+ int slotsnr=fifo->slotsnr;
+ if(!fifo->entry || !slotsnr) return -1;
+ slot=fifo->entry;
+ fifo->flist=slot;
+ while(--slotsnr){
+ slot->next=slot+1;
+ slot++;
+ }
+ slot->next=NULL;
+ fifo->head=NULL;
+ fifo->tail=&fifo->head;
+ canque_fifo_set_fl(fifo,EMPTY);
+ return 1;
+}
+
+/* atomic_dec_and_test(&qedge->edge_used);
+ void atomic_inc(&qedge->edge_used);
+ list_add_tail(struct list_head *new, struct list_head *head)
+ list_for_each(edge,qends->inlist);
+ list_entry(ptr, type, member)
+*/
+
+void __canque_edge_decref(struct canque_edge_t *edge)
+{
+ __canque_edge_decref_body(edge);
+}
+
+/**
+ * canque_get_inslot - finds one outgoing edge and allocates slot from it
+ * @qends: ends structure belonging to calling communication object
+ * @qedgep: place to store pointer to found edge
+ * @slotp: place to store pointer to allocated slot
+ * @cmd: command type for slot
+ *
+ * Function looks for the first non-blocked outgoing edge in @qends structure
+ * and tries to allocate slot from it.
+ * Return Value: If there is no usable edge or there is no free slot in edge
+ * negative value is returned.
+ */
+int canque_get_inslot(struct canque_ends_t *qends,
+ struct canque_edge_t **qedgep, struct canque_slot_t **slotp, int cmd)
+{
+ int ret=-2;
+ struct canque_edge_t *edge;
+
+ edge=canque_first_inedge(qends);
+ if(edge){
+ if(!canque_fifo_test_fl(&edge->fifo,BLOCK)){
+ ret=canque_fifo_get_inslot(&edge->fifo, slotp, cmd);
+ if(ret>0){
+ *qedgep=edge;
+ DEBUGQUE("canque_get_inslot cmd=%d found edge %d\n",cmd,edge->edge_num);
+ return ret;
+
+ }
+ }
+ canque_edge_decref(edge);
+ }
+ *qedgep=NULL;
+ DEBUGQUE("canque_get_inslot cmd=%d failed\n",cmd);
+ return ret;
+}
+
+/**
+ * canque_get_inslot4id - finds best outgoing edge and slot for given ID
+ * @qends: ends structure belonging to calling communication object
+ * @qedgep: place to store pointer to found edge
+ * @slotp: place to store pointer to allocated slot
+ * @cmd: command type for slot
+ * @id: communication ID of message to send into edge
+ * @prio: optional priority of message
+ *
+ * Function looks for the non-blocked outgoing edge accepting messages
+ * with given ID. If edge is found, slot is allocated from that edge.
+ * The edges with non-zero mask are preferred over edges open to all messages.
+ * If more edges with mask accepts given message ID, the edge with
+ * highest priority below or equal to required priority is selected.
+ * Return Value: If there is no usable edge or there is no free slot in edge
+ * negative value is returned.
+ */
+int canque_get_inslot4id(struct canque_ends_t *qends,
+ struct canque_edge_t **qedgep, struct canque_slot_t **slotp,
+ int cmd, unsigned long id, int prio)
+{
+ int ret=-2;
+ struct canque_edge_t *edge, *bestedge=NULL;
+
+ canque_for_each_inedge(qends, edge){
+ if(canque_fifo_test_fl(&edge->fifo,BLOCK))
+ continue;
+ if((id^edge->filtid)&edge->filtmask)
+ continue;
+ if(bestedge){
+ if(bestedge->filtmask){
+ if (!edge->filtmask) continue;
+ } else {
+ if(edge->filtmask){
+ canque_edge_decref(bestedge);
+ bestedge=edge;
+ canque_edge_incref(bestedge);
+ continue;
+ }
+ }
+ if(bestedge->edge_prio<edge->edge_prio){
+ if(edge->edge_prio>prio) continue;
+ } else {
+ if(bestedge->edge_prio<=prio) continue;
+ }
+ canque_edge_decref(bestedge);
+ }
+ bestedge=edge;
+ canque_edge_incref(bestedge);
+ }
+ if((edge=bestedge)!=NULL){
+ ret=canque_fifo_get_inslot(&edge->fifo, slotp, cmd);
+ if(ret>0){
+ *qedgep=edge;
+ DEBUGQUE("canque_get_inslot4id cmd=%d id=%ld prio=%d found edge %d\n",cmd,id,prio,edge->edge_num);
+ return ret;
+ }
+ canque_edge_decref(bestedge);
+ }
+ *qedgep=NULL;
+ DEBUGQUE("canque_get_inslot4id cmd=%d id=%ld prio=%d failed\n",cmd,id,prio);
+ return ret;
+}
+
+
+/**
+ * canque_put_inslot - schedules filled slot for processing
+ * @qends: ends structure belonging to calling communication object
+ * @qedge: edge slot belong to
+ * @slot: pointer to the prepared slot
+ *
+ * Puts slot previously acquired by canque_get_inslot() or canque_get_inslot4id()
+ * function call into FIFO queue and activates edge processing if needed.
+ * Return Value: Positive value informs, that activation of output end
+ * has been necessary
+ */
+int canque_put_inslot(struct canque_ends_t *qends,
+ struct canque_edge_t *qedge, struct canque_slot_t *slot)
+{
+ int ret;
+ ret=canque_fifo_put_inslot(&qedge->fifo,slot);
+ if(ret) {
+ canque_activate_edge(qends,qedge);
+ canque_notify_outends(qedge,CANQUEUE_NOTIFY_PROC);
+ }
+ canque_edge_decref(qedge);
+ DEBUGQUE("canque_put_inslot for edge %d returned %d\n",qedge->edge_num,ret);
+ return ret;
+}
+
+/**
+ * canque_abort_inslot - aborts preparation of the message in the slot
+ * @qends: ends structure belonging to calling communication object
+ * @qedge: edge slot belong to
+ * @slot: pointer to the previously allocated slot
+ *
+ * Frees slot previously acquired by canque_get_inslot() or canque_get_inslot4id()
+ * function call. Used when message copying into slot fails.
+ * Return Value: Positive value informs, that queue full state has been negated.
+ */
+int canque_abort_inslot(struct canque_ends_t *qends,
+ struct canque_edge_t *qedge, struct canque_slot_t *slot)
+{
+ int ret;
+ ret=canque_fifo_abort_inslot(&qedge->fifo,slot);
+ if(ret) {
+ canque_notify_outends(qedge,CANQUEUE_NOTIFY_SPACE);
+ }
+ canque_edge_decref(qedge);
+ DEBUGQUE("canque_abort_inslot for edge %d returned %d\n",qedge->edge_num,ret);
+ return ret;
+}
+
+/**
+ * canque_filter_msg2edges - sends message into all edges which accept its ID
+ * @qends: ends structure belonging to calling communication object
+ * @msg: pointer to CAN message
+ *
+ * Sends message to all outgoing edges connected to the given ends, which accepts
+ * message communication ID.
+ * Return Value: Returns number of edges message has been send to
+ */
+int canque_filter_msg2edges(struct canque_ends_t *qends, struct canmsg_t *msg)
+{
+ int destnr=0;
+ int ret;
+ unsigned long msgid;
+ struct canque_edge_t *edge;
+ struct canque_slot_t *slot;
+
+ DEBUGQUE("canque_filter_msg2edges for msg ID 0x%08lx and flags 0x%02x\n",
+ msg->id, msg->flags);
+ msgid = canque_filtid2internal(msg->id, msg->flags);
+
+ canque_for_each_inedge(qends, edge) {
+ if(canque_fifo_test_fl(&edge->fifo,BLOCK))
+ continue;
+ if((msgid^edge->filtid)&edge->filtmask)
+ continue;
+ ret=canque_fifo_get_inslot(&edge->fifo, &slot, 0);
+ if(ret>0){
+ slot->msg=*msg;
+ destnr++;
+ ret=canque_fifo_put_inslot(&edge->fifo,slot);
+ if(ret) {
+ canque_activate_edge(qends,edge);
+ canque_notify_outends(edge,CANQUEUE_NOTIFY_PROC);
+ }
+
+ }
+ }
+ DEBUGQUE("canque_filter_msg2edges sent msg ID %ld to %d edges\n",msg->id,destnr);
+ return destnr;
+}
+
+/**
+ * canque_test_outslot - test and retrieve ready slot for given ends
+ * @qends: ends structure belonging to calling communication object
+ * @qedgep: place to store pointer to found edge
+ * @slotp: place to store pointer to received slot
+ *
+ * Function takes highest priority active incoming edge and retrieves
+ * oldest ready slot from it.
+ * Return Value: Negative value informs, that there is no ready output
+ * slot for given ends. Positive value is equal to the command
+ * slot has been allocated by the input side.
+ */
+int canque_test_outslot(struct canque_ends_t *qends,
+ struct canque_edge_t **qedgep, struct canque_slot_t **slotp)
+{
+ can_spin_irqflags_t flags;
+ int prio;
+ struct canque_edge_t *edge;
+ int ret;
+
+ can_spin_lock_irqsave(&qends->ends_lock, flags);
+ for(prio=CANQUEUE_PRIO_NR;--prio>=0;){
+ while(!list_empty(&qends->active[prio])){
+ edge=list_entry(qends->active[prio].next,struct canque_edge_t,activepeers);
+ if(!canque_fifo_test_fl(&edge->fifo,DEAD)) {
+ /* The first test on unlocked FIFO */
+ if(canque_fifo_test_fl(&edge->fifo,EMPTY)) {
+ can_spin_lock(&edge->fifo.fifo_lock);
+ /* Test has to be repeated to ensure that EMPTY
+ state has not been nagated when locking FIFO */
+ if(canque_fifo_test_fl(&edge->fifo,EMPTY)) {
+ canque_fifo_set_fl(&edge->fifo,INACTIVE);
+ list_del(&edge->activepeers);
+ list_add(&edge->activepeers,&qends->idle);
+ can_spin_unlock(&edge->fifo.fifo_lock);
+ continue;
+ }
+ can_spin_unlock(&edge->fifo.fifo_lock);
+ }
+ canque_edge_incref(edge);
+ can_spin_unlock_irqrestore(&qends->ends_lock, flags);
+ *qedgep=edge;
+ DEBUGQUE("canque_test_outslot found edge %d\n",edge->edge_num);
+ ret=canque_fifo_test_outslot(&edge->fifo, slotp);
+ if(ret>=0)
+ return ret;
+
+ canque_edge_decref(edge);
+ can_spin_lock_irqsave(&qends->ends_lock, flags);
+ } else {
+ can_spin_lock(&edge->fifo.fifo_lock);
+ canque_fifo_set_fl(&edge->fifo,INACTIVE);
+ list_del(&edge->activepeers);
+ list_add(&edge->activepeers,&qends->idle);
+ can_spin_unlock(&edge->fifo.fifo_lock);
+ }
+ }
+ }
+ can_spin_unlock_irqrestore(&qends->ends_lock, flags);
+ *qedgep=NULL;
+// DEBUGQUE("canque_test_outslot no ready slot\n");
+ return -1;
+}
+
+/**
+ * canque_free_outslot - frees processed output slot
+ * @qends: ends structure belonging to calling communication object
+ * @qedge: edge slot belong to
+ * @slot: pointer to the processed slot
+ *
+ * Function releases processed slot previously acquired by canque_test_outslot()
+ * function call.
+ * Return Value: Return value informs if input side has been notified
+ * to know about change of edge state
+ */
+int canque_free_outslot(struct canque_ends_t *qends,
+ struct canque_edge_t *qedge, struct canque_slot_t *slot)
+{
+ int ret;
+ can_spin_irqflags_t flags;
+ ret=canque_fifo_free_outslot(&qedge->fifo, slot);
+ if(ret&CAN_FIFOF_EMPTY){
+ canque_notify_inends(qedge,CANQUEUE_NOTIFY_EMPTY);
+ }
+ if(ret&CAN_FIFOF_FULL)
+ canque_notify_inends(qedge,CANQUEUE_NOTIFY_SPACE);
+ can_spin_lock_irqsave(&qends->ends_lock, flags);
+ if((ret&CAN_FIFOF_EMPTY) || CANQUE_ROUNDROB ){
+ can_spin_lock(&qedge->fifo.fifo_lock);
+ if(canque_fifo_test_fl(&qedge->fifo,EMPTY)){
+ canque_fifo_set_fl(&qedge->fifo,INACTIVE);
+ list_del(&qedge->activepeers);
+ list_add(&qedge->activepeers,&qends->idle);
+ } else{
+ list_del(&qedge->activepeers);
+ list_add_tail(&qedge->activepeers,&qends->active[qedge->edge_prio]);
+ }
+ can_spin_unlock(&qedge->fifo.fifo_lock);
+ }
+ can_spin_unlock_irqrestore(&qends->ends_lock, flags);
+ canque_edge_decref(qedge);
+ DEBUGQUE("canque_free_outslot for edge %d returned %d\n",qedge->edge_num,ret);
+ return ret;
+}
+
+/**
+ * canque_again_outslot - reschedule output slot to process it again later
+ * @qends: ends structure belonging to calling communication object
+ * @qedge: edge slot belong to
+ * @slot: pointer to the slot for re-processing
+ *
+ * Function reschedules slot previously acquired by canque_test_outslot()
+ * function call for second time processing.
+ * Return Value: Function cannot fail.
+ */
+int canque_again_outslot(struct canque_ends_t *qends,
+ struct canque_edge_t *qedge, struct canque_slot_t *slot)
+{
+ int ret;
+ ret=canque_fifo_again_outslot(&qedge->fifo, slot);
+ canque_edge_decref(qedge);
+ DEBUGQUE("canque_again_outslot for edge %d returned %d\n",qedge->edge_num,ret);
+ return ret;
+}
+
+/**
+ * canque_set_filt - sets filter for specified edge
+ * @qedge: pointer to the edge
+ * @filtid: ID to set for the edge
+ * @filtmask: mask used for ID match check
+ * @filtflags: required filer flags
+ *
+ * Return Value: Negative value is returned if edge is in the process of delete.
+ */
+int canque_set_filt(struct canque_edge_t *qedge,
+ unsigned long filtid, unsigned long filtmask, int filtflags)
+{
+ int ret;
+ can_spin_irqflags_t flags;
+
+ can_spin_lock_irqsave(&qedge->fifo.fifo_lock,flags);
+
+ if(!(filtflags&MSG_PROCESSLOCAL) && (processlocal<2))
+ filtflags |= MSG_LOCAL_MASK;
+
+ qedge->filtid=canque_filtid2internal(filtid, filtflags);
+ qedge->filtmask=canque_filtid2internal(filtmask, filtflags>>MSG_FILT_MASK_SHIFT);
+
+ if(canque_fifo_test_fl(&qedge->fifo,DEAD)) ret=-1;
+ else ret=canque_fifo_test_and_set_fl(&qedge->fifo,BLOCK)?1:0;
+
+ can_spin_unlock_irqrestore(&qedge->fifo.fifo_lock,flags);
+ if(ret>=0){
+ canque_notify_bothends(qedge,CANQUEUE_NOTIFY_FILTCH);
+ }
+ can_spin_lock_irqsave(&qedge->fifo.fifo_lock,flags);
+ if(!ret) canque_fifo_clear_fl(&qedge->fifo,BLOCK);
+ can_spin_unlock_irqrestore(&qedge->fifo.fifo_lock,flags);
+
+ DEBUGQUE("canque_set_filt for edge %d, ID %ld, mask %ld, flags %d returned %d\n",
+ qedge->edge_num,filtid,filtmask,filtflags,ret);
+ return ret;
+}
+
+/**
+ * canque_flush - fluesh all ready slots in the edge
+ * @qedge: pointer to the edge
+ *
+ * Tries to flush all allocated slots from the edge, but there could
+ * exist some slots associated to edge which are processed by input
+ * or output side and cannot be flushed at this moment.
+ * Return Value: The nonzero value indicates, that queue has not been
+ * empty before the function call.
+ */
+int canque_flush(struct canque_edge_t *qedge)
+{
+ int ret;
+ can_spin_irqflags_t flags;
+
+ ret=canque_fifo_flush_slots(&qedge->fifo);
+ if(ret){
+ canque_notify_inends(qedge,CANQUEUE_NOTIFY_EMPTY);
+ canque_notify_inends(qedge,CANQUEUE_NOTIFY_SPACE);
+ can_spin_lock_irqsave(&qedge->outends->ends_lock, flags);
+ can_spin_lock(&qedge->fifo.fifo_lock);
+ if(canque_fifo_test_fl(&qedge->fifo,EMPTY)){
+ list_del(&qedge->activepeers);
+ list_add(&qedge->activepeers,&qedge->outends->idle);
+ }
+ can_spin_unlock(&qedge->fifo.fifo_lock);
+ can_spin_unlock_irqrestore(&qedge->outends->ends_lock, flags);
+ }
+ DEBUGQUE("canque_flush for edge %d returned %d\n",qedge->edge_num,ret);
+ return ret;
+}
+
+/**
+ * canqueue_ends_init_gen - subsystem independent routine to initialize ends state
+ * @qends: pointer to the ends structure
+ *
+ * Return Value: Cannot fail.
+ */
+int canqueue_ends_init_gen(struct canque_ends_t *qends)
+{
+ int i;
+ qends->ends_flags=0;
+ for(i=CANQUEUE_PRIO_NR;--i>=0;){
+ INIT_LIST_HEAD(&qends->active[i]);
+ }
+ INIT_LIST_HEAD(&qends->idle);
+ INIT_LIST_HEAD(&qends->inlist);
+ INIT_LIST_HEAD(&qends->outlist);
+ can_spin_lock_init(&qends->ends_lock);
+ return 0;
+}
+
+
+/**
+ * canqueue_connect_edge - connect edge between two communication entities
+ * @qedge: pointer to edge
+ * @inends: pointer to ends the input of the edge should be connected to
+ * @outends: pointer to ends the output of the edge should be connected to
+ *
+ * Return Value: Negative value informs about failed operation.
+ */
+int canqueue_connect_edge(struct canque_edge_t *qedge, struct canque_ends_t *inends, struct canque_ends_t *outends)
+{
+ can_spin_irqflags_t flags;
+ if(qedge == NULL) return -1;
+ DEBUGQUE("canqueue_connect_edge %d\n",qedge->edge_num);
+ canque_edge_incref(qedge);
+ flags=canque_edge_lock_both_ends(inends, outends);
+ can_spin_lock(&qedge->fifo.fifo_lock);
+ qedge->inends=inends;
+ list_add(&qedge->inpeers,&inends->inlist);
+ qedge->outends=outends;
+ list_add(&qedge->outpeers,&outends->outlist);
+ list_add(&qedge->activepeers,&outends->idle);
+ can_spin_unlock(&qedge->fifo.fifo_lock);
+ canque_edge_unlock_both_ends(inends, outends, flags);
+ canque_notify_bothends(qedge, CANQUEUE_NOTIFY_ATTACH);
+
+ if(canque_fifo_test_and_set_fl(&qedge->fifo, READY))
+ canque_edge_decref(qedge);
+ return 0;
+}
+
+/**
+ * canqueue_disconnect_edge - disconnect edge from communicating entities
+ * @qedge: pointer to edge
+ *
+ * Return Value: Negative value means, that edge is used by somebody
+ * other and cannot be disconnected. Operation has to be delayed.
+ */
+int canqueue_disconnect_edge(struct canque_edge_t *qedge)
+{
+ int ret;
+ can_spin_irqflags_t flags;
+ struct canque_ends_t *inends, *outends;
+
+ inends=qedge->inends;
+ outends=qedge->outends;
+
+ if(inends && outends) {
+ flags=canque_edge_lock_both_ends(inends, outends);
+ } else {
+ DEBUGQUE("canqueue_disconnect_edge called with not fully connected edge");
+ if(inends) can_spin_lock_irqsave(&inends->ends_lock,flags);
+ else if(outends) can_spin_lock_irqsave(&outends->ends_lock,flags);
+ else flags=0;
+ }
+
+ can_spin_lock(&qedge->fifo.fifo_lock);
+ if(atomic_read(&qedge->edge_used)==0) {
+ if(qedge->outends){
+ list_del(&qedge->activepeers);
+ mb(); /* memory barrier for list_empty use in canque_dead_func */
+ list_del(&qedge->outpeers);
+ qedge->outends=NULL;
+ }
+ if(qedge->inends){
+ list_del(&qedge->inpeers);
+ qedge->inends=NULL;
+ }
+ ret=1;
+ } else ret=-1;
+ can_spin_unlock(&qedge->fifo.fifo_lock);
+
+ if(inends && outends) {
+ canque_edge_unlock_both_ends(inends, outends, flags);
+ } else {
+ if(inends) can_spin_unlock_irqrestore(&inends->ends_lock,flags);
+ else if(outends) can_spin_unlock_irqrestore(&outends->ends_lock,flags);
+ }
+
+ DEBUGQUE("canqueue_disconnect_edge %d returned %d\n",qedge->edge_num,ret);
+ return ret;
+}
+
+
+/**
+ * canqueue_block_inlist - block slot allocation of all outgoing edges of specified ends
+ * @qends: pointer to ends structure
+ */
+void canqueue_block_inlist(struct canque_ends_t *qends)
+{
+ struct canque_edge_t *edge;
+
+ canque_for_each_inedge(qends, edge) {
+ canque_fifo_set_fl(&edge->fifo,BLOCK);
+ }
+}
+
+
+/**
+ * canqueue_block_outlist - block slot allocation of all incoming edges of specified ends
+ * @qends: pointer to ends structure
+ */
+void canqueue_block_outlist(struct canque_ends_t *qends)
+{
+ struct canque_edge_t *edge;
+
+ canque_for_each_outedge(qends, edge) {
+ canque_fifo_set_fl(&edge->fifo,BLOCK);
+ }
+}
+
+
+/**
+ * canqueue_ends_kill_inlist - sends request to die to all outgoing edges
+ * @qends: pointer to ends structure
+ * @send_rest: select, whether already allocated slots should be processed
+ * by FIFO output side
+ *
+ * Return Value: Non-zero value means, that not all edges could be immediately
+ * disconnected and that ends structure memory release has to be delayed
+ */
+int canqueue_ends_kill_inlist(struct canque_ends_t *qends, int send_rest)
+{
+ struct canque_edge_t *edge;
+
+ canque_for_each_inedge(qends, edge){
+ canque_notify_bothends(edge, CANQUEUE_NOTIFY_DEAD_WANTED);
+ if(send_rest){
+ canque_edge_incref(edge);
+ if(!canque_fifo_test_and_set_fl(&edge->fifo, FREEONEMPTY)){
+ if(!canque_fifo_test_fl(&edge->fifo, EMPTY))
+ continue;
+ if(!canque_fifo_test_and_clear_fl(&edge->fifo, FREEONEMPTY))
+ continue;
+ }
+ canque_edge_decref(edge);
+ }
+ }
+ return list_empty(&qends->inlist)?0:1;
+}
+
+
+/**
+ * canqueue_ends_kill_outlist - sends request to die to all incoming edges
+ * @qends: pointer to ends structure
+ *
+ * Return Value: Non-zero value means, that not all edges could be immediately
+ * disconnected and that ends structure memory release has to be delayed
+ */
+int canqueue_ends_kill_outlist(struct canque_ends_t *qends)
+{
+ struct canque_edge_t *edge;
+
+ canque_for_each_outedge(qends, edge){
+ canque_notify_bothends(edge, CANQUEUE_NOTIFY_DEAD_WANTED);
+ }
+ return list_empty(&qends->outlist)?0:1;
+}
+
+
+/**
+ * canqueue_ends_filt_conjuction - computes conjunction of incoming edges filters filters
+ * @qends: pointer to ends structure
+ * @filt: pointer the filter structure filled by computed filters conjunction
+ *
+ * Return Value: Number of incoming edges
+ */
+int canqueue_ends_filt_conjuction(struct canque_ends_t *qends, struct canfilt_t *filt)
+{
+ struct canque_edge_t *edge;
+ int cnt=0;
+ unsigned long filtid=0;
+ unsigned long filtmask=~0;
+ unsigned long local_only=canque_filtid2internal(0,MSG_LOCAL);
+
+ canque_for_each_inedge(qends, edge){
+ /* skip edges processing only local messages */
+ if(edge->filtid & edge->filtmask & local_only)
+ continue;
+
+ if(!cnt++)
+ filtid = edge->filtid;
+ else
+ filtmask &= ~(filtid ^ edge->filtid);
+
+ filtmask &= edge->filtmask;
+ }
+
+ filt->id = filtid & MSG_ID_MASK;
+ filt->mask = filtmask & MSG_ID_MASK;
+ filtid >>= 28;
+ filtmask >>= 28;
+ filt->flags = filtid & MSG_EXT;
+ if(filtmask & (MSG_EXT))
+ filt->flags |= MSG_EXT_MASK;
+ if(filtid & (MSG_RTR<<1))
+ filt->flags |= MSG_RTR<<1;
+ if(filtmask & (MSG_RTR<<1))
+ filt->flags |= MSG_RTR_MASK;
+ return cnt;
+}
+
+
+/**
+ * canqueue_ends_flush_inlist - flushes all messages in incoming edges
+ * @qends: pointer to ends structure
+ *
+ * Return Value: Negative value informs about unsuccessful result
+ */
+int canqueue_ends_flush_inlist(struct canque_ends_t *qends)
+{
+ struct canque_edge_t *edge;
+
+ canque_for_each_inedge(qends, edge){
+ canque_flush(edge);
+ }
+ return 0;
+}
+
+
+/**
+ * canqueue_ends_flush_outlist - flushes all messages in outgoing edges
+ * @qends: pointer to ends structure
+ *
+ * Return Value: Negative value informs about unsuccessful result
+ */
+int canqueue_ends_flush_outlist(struct canque_ends_t *qends)
+{
+ struct canque_edge_t *edge;
+
+ canque_for_each_outedge(qends, edge){
+ canque_flush(edge);
+ }
+ return 0;
+}
+
+
+
+
--- /dev/null
+/**************************************************************************/
+/* File: devcommon.c - common device code */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+#include "./can/can.h"
+#include "./can/can_sysdep.h"
+#include "./can/can_queue.h"
+#include "./can/main.h"
+#include "./can/devcommon.h"
+
+#ifdef CAN_WITH_RTL
+static inline
+void canqueue_wake_chip_worker(struct canque_ends_t *qends, struct canchip_t *chip, struct msgobj_t *obj)
+{
+ if(qends->endinfo.chipinfo.worker_thread){
+ can_msgobj_set_fl(obj,WORKER_WAKE);
+ pthread_kill(qends->endinfo.chipinfo.worker_thread,RTL_SIGNAL_WAKEUP);
+ rtl_schedule();
+ } else {
+ set_bit(MSGOBJ_TX_REQUEST_b,&chip->pend_flags);
+ if(chip->worker_thread) {
+ set_bit(MSGOBJ_WORKER_WAKE_b,&chip->pend_flags);
+ pthread_kill(chip->worker_thread,RTL_SIGNAL_WAKEUP);
+ rtl_schedule();
+ }
+ }
+}
+
+#endif /*CAN_WITH_RTL*/
+
+
+/**
+ * canqueue_notify_chip - notification callback handler for CAN chips ends of queues
+ * @qends: pointer to the callback side ends structure
+ * @qedge: edge which invoked notification
+ * @what: notification type
+ *
+ * This function has to deal with more possible cases. It can be called from
+ * the kernel or interrupt context for Linux only compilation of driver.
+ * The function can be called from kernel context or RT-Linux thread context
+ * for mixed mode Linux/RT-Linux compilation.
+ */
+void canqueue_notify_chip(struct canque_ends_t *qends, struct canque_edge_t *qedge, int what)
+{
+ struct canchip_t *chip=qends->endinfo.chipinfo.chip;
+ struct msgobj_t *obj=qends->endinfo.chipinfo.msgobj;
+
+ DEBUGMSG("canqueue_notify_chip for edge %d and event %d\n",qedge->edge_num,what);
+ switch(what){
+ /*case CANQUEUE_NOTIFY_EMPTY:*/
+ /*case CANQUEUE_NOTIFY_SPACE:*/
+ /*case CANQUEUE_NOTIFY_NOUSR:
+ wake_up(&qends->endinfo.chipinfo.daemonq);
+ break;*/
+ case CANQUEUE_NOTIFY_PROC:
+ #ifndef CAN_WITH_RTL
+ /*wake_up(&qends->endinfo.chipinfo.daemonq);*/
+ if(canque_fifo_test_fl(&qedge->fifo, READY)){
+ if ((chip) && (chip->flags & CHIP_ATTACHED))
+ chip->chipspecops->wakeup_tx(chip, obj);
+ }
+ #else /*CAN_WITH_RTL*/
+ can_msgobj_set_fl(obj,TX_REQUEST);
+ canqueue_wake_chip_worker(qends, chip, obj);
+ #endif /*CAN_WITH_RTL*/
+ break;
+ case CANQUEUE_NOTIFY_DEAD_WANTED:
+ case CANQUEUE_NOTIFY_DEAD:
+ if(canque_fifo_test_and_clear_fl(&qedge->fifo, READY))
+ canque_edge_decref(qedge);
+ break;
+ case CANQUEUE_NOTIFY_ATTACH:
+ break;
+ case CANQUEUE_NOTIFY_FILTCH:
+ if(!chip->chipspecops->filtch_rq)
+ break;
+ #ifndef CAN_WITH_RTL
+ chip->chipspecops->filtch_rq(chip, obj);
+ #else /*CAN_WITH_RTL*/
+ can_msgobj_set_fl(obj,FILTCH_REQUEST);
+ canqueue_wake_chip_worker(qends, chip, obj);
+ #endif /*CAN_WITH_RTL*/
+
+ break;
+ }
+}
+
+
+/**
+ * canqueue_ends_init_chip - CAN chip specific ends initialization
+ * @qends: pointer to the ends structure
+ * @chip: pointer to the corresponding CAN chip structure
+ * @obj: pointer to the corresponding message object structure
+ */
+int canqueue_ends_init_chip(struct canque_ends_t *qends, struct canchip_t *chip, struct msgobj_t *obj)
+{
+ int ret;
+ ret=canqueue_ends_init_gen(qends);
+ if(ret<0) return ret;
+
+ qends->context=NULL;
+ #ifndef CAN_WITH_RTL
+ init_waitqueue_head(&qends->endinfo.chipinfo.daemonq);
+ #endif /*CAN_WITH_RTL*/
+ qends->endinfo.chipinfo.chip=chip;
+ qends->endinfo.chipinfo.msgobj=obj;
+ qends->notify=canqueue_notify_chip;
+
+ DEBUGMSG("canqueue_ends_init_chip\n");
+ return 0;
+}
+
+
+/**
+ * canqueue_ends_done_chip - finalizing of the ends structure for CAN chips
+ * @qends: pointer to ends structure
+ *
+ * Return Value: Function should be designed such way to not fail.
+ */
+int canqueue_ends_done_chip(struct canque_ends_t *qends)
+{
+ int delayed;
+
+ /* Finish or kill all outgoing edges listed in inends */
+ delayed=canqueue_ends_kill_inlist(qends, 1);
+ /* Kill all incoming edges listed in outends */
+ delayed|=canqueue_ends_kill_outlist(qends);
+
+ return delayed;
+}
--- /dev/null
+/**************************************************************************/
+/* File: finish.c - finalization of the driver operations */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+#include "./can/can.h"
+#include "./can/can_sysdep.h"
+#include "./can/main.h"
+#include "./can/devcommon.h"
+#include "./can/finish.h"
+#include "./can/setup.h"
+
+
+/**
+ * msgobj_done - destroys one CAN message object
+ * @obj: pointer to CAN message object structure
+ */
+void msgobj_done(struct msgobj_t *obj)
+{
+ int delayed=0;
+ if(obj->qends) {
+ delayed=canqueue_ends_done_chip(obj->qends);
+ if(delayed < 0)
+ CANMSG("msgobj_done: problem with chip queue ends\n");
+ }
+
+ if((obj->hostchip) && (obj->object>0)) {
+ if(obj->hostchip->msgobj[obj->object-1] == obj)
+ obj->hostchip->msgobj[obj->object-1]=NULL;
+ else
+ CANMSG("msgobj_done: not registered in the canchip_t\n");
+ obj->hostchip=NULL;
+ }
+
+ if((obj->minor>=0)) {
+ if(objects_p[obj->minor] == obj)
+ objects_p[obj->minor] = NULL;
+ else
+ CANMSG("msgobj_done: not registered as minor\n");
+ }
+
+// del_timer_sync(&obj->tx_timeout);
+
+ if(obj->qends) {
+ /*delayed free could be required there in the future,
+ actual use patter cannot generate such situation*/
+ if(!delayed) {
+ free(obj->qends);
+ }
+ }
+ obj->qends=NULL;
+}
+
+
+/**
+ * canchip_done - destroys one CAN chip representation
+ * @chip: pointer to CAN chip structure
+ */
+void canchip_done(struct canchip_t *chip)
+{
+
+ int i;
+ struct msgobj_t *obj;
+
+ if(chip->flags & CHIP_ATTACHED)
+ chip->chipspecops->release_chip(chip);
+
+ if((chip->hostdevice) && (chip->chip_idx>=0)) {
+ if(chip->hostdevice->chip[chip->chip_idx] == chip)
+ chip->hostdevice->chip[chip->chip_idx] = NULL;
+ else
+ CANMSG("canchip_done: not registered in hostdevice\n");
+ }
+
+// Not using interrupts
+// can_chip_free_irq(chip);
+
+// can_synchronize_irq(chip->chip_irq);
+
+ for(i=0; i<chip->max_objects; i++){
+ if((obj=chip->msgobj[i])==NULL)
+ continue;
+ msgobj_done(obj);
+ free(obj);
+ }
+
+ free(chip->chipspecops);
+ chip->chipspecops=NULL;
+
+}
+
+/**
+ * candevice_done - destroys representation of one CAN device/board
+ * @candev: pointer to CAN device/board structure
+ */
+void candevice_done(struct candevice_t *candev)
+{
+ int i;
+ struct canchip_t *chip;
+
+ for(i=0; i<candev->nr_all_chips; i++){
+ if((chip=candev->chip[i])==NULL)
+ continue;
+ canchip_done(chip);
+ free(chip);
+
+ }
+ if(candev->flags & CANDEV_IO_RESERVED) {
+ candev->hwspecops->release_io(candev);
+ candev->flags &= ~CANDEV_IO_RESERVED;
+ }
+ free(candev->hwspecops);
+ candev->hwspecops=NULL;
+}
+
+/**
+ * candevice_done - destroys representation of all CAN devices/boards
+ * @canhw: pointer to the root of all CAN hardware representation
+ */
+void canhardware_done(struct canhardware_t *canhw)
+{
+ int i;
+ struct candevice_t *candev;
+
+ for(i=0; i<canhw->nr_boards; i++){
+ if((candev=canhw->candevice[i])==NULL)
+ continue;
+ candevice_done(candev);
+ free(candev);
+ }
+
+}
--- /dev/null
+#include "can/lpc17xx_can.h"
+
+static void CAN_configPin();
+
+
+// board can-lmc1 specific functions:
+
+int can_lmc1_register(struct hwspecops_t *hwspecops){
+
+ hwspecops->request_io = can_lmc1_request_io;
+ hwspecops->reset = can_lmc1_reset;
+ hwspecops->init_hw_data = can_lmc1_init_hw_data;
+ hwspecops->init_chip_data = can_lmc1_init_chip_data;
+ hwspecops->init_obj_data = can_lmc1_init_obj_data;
+ hwspecops->write_register = can_lmc1_write_register;
+ hwspecops->read_register = can_lmc1_read_register;
+ hwspecops->program_irq = can_lmc1_program_irq;
+
+ return 0;
+}
+
+int can_lmc1_init_hw_data(struct candevice_t *candev){
+
+ candev->res_addr=0;
+ candev->nr_82527_chips=0;
+ candev->nr_sja1000_chips=0;
+ candev->nr_all_chips=1;
+ candev->flags = 0;
+
+ return 0;
+}
+
+int can_lmc1_init_chip_data(struct candevice_t *candev, int chipnr){
+
+ struct can_lmc1_chip_data *chip_data;
+
+ // used CAN1 peripherial -> CAN1 registers base
+ candev->chip[chipnr]->chip_base_addr = CAN1_REGS_BASE;
+ // clock for CAN
+ candev->chip[chipnr]->clock = system_frequency / 4;
+
+ lpc17xx_fill_chipspecops(candev->chip[chipnr]);
+
+ candev->chip[chipnr]->chip_data=(void *)malloc(sizeof(struct can_lmc1_chip_data));
+ if (candev->chip[chipnr]->chip_data==NULL)
+ return -ENOMEM;
+
+
+ chip_data = (struct can_lmc1_chip_data*) candev->chip[chipnr]->chip_data;
+ chip_data->flags = 0;
+
+ return 0;
+}
+
+int can_lmc1_init_obj_data(struct canchip_t *chip, int objnr){
+
+ return 0;
+}
+
+void can_lmc1_write_register(unsigned data, unsigned long address){
+ (*(volatile uint32_t*)(address)) = data;
+}
+
+unsigned can_lmc1_read_register(unsigned long address){
+ return (*(volatile uint32_t*)(address));
+}
+
+int can_lmc1_request_io(struct candevice_t *candev)
+{
+ return 0;
+}
+
+int can_lmc1_reset(struct candevice_t *candev)
+{
+ return 0;
+}
+
+int can_lmc1_program_irq(struct candevice_t *candev)
+{
+ return 0;
+}
+
+//---------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------
+
+
+// lpc17xx can chip specific functions:
+
+/*
+ * lpc17xx_baud_rate: - set communication parameters.
+ * @chip: pointer to chip state structure
+ * @rate: baud rate in Hz
+ * @clock: frequency of CAN clock in Hz
+ * @sjw: synchronization jump width (0-3) prescaled clock cycles
+ * @sampl_pt: sample point in % (0-100) sets (TSEG1+1)/(TSEG1+TSEG2+2) ratio
+ */
+int lpc17xx_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
+ int sampl_pt, int flags)
+{
+ int best_error = 1000000000, error;
+ int best_tseg=0, best_brp=0, best_rate=0, brp=0;
+ int tseg=0, tseg1=0, tseg2=0;
+
+ struct can_bittiming_const btc_buff;
+ struct can_bittiming_const *btc = &btc_buff;
+
+ chip->chipspecops->get_bittiming_const(chip, btc);
+
+ /* tseg even = round down, odd = round up */
+ for (tseg=(0+0+2)*2; tseg<=(btc->tseg2_max+btc->tseg1_max+2)*2+1; tseg++) {
+ brp = clock/((1+tseg/2)*rate)+tseg%2;
+ if (brp == 0 || brp > 64)
+ continue;
+ error = rate - clock/(brp*(1+tseg/2));
+ if (error < 0)
+ error = -error;
+ if (error <= best_error) {
+ best_error = error;
+ best_tseg = tseg/2;
+ best_brp = brp-1;
+ best_rate = clock/(brp*(1+tseg/2));
+ }
+ }
+ if (best_error && (rate/best_error < 10)) {
+ CANMSG("baud rate %d is not possible with %d Hz clock\n",
+ rate, clock);
+ CANMSG("%d bps. brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d\n",
+ best_rate, best_brp, best_tseg, tseg1, tseg2);
+ return -EINVAL;
+ }
+ tseg2 = best_tseg-(sampl_pt*(best_tseg+1))/100;
+ if (tseg2 < 0)
+ tseg2 = 0;
+ if (tseg2 > btc->tseg2_max)
+ tseg2 = btc->tseg2_max;
+ tseg1 = best_tseg-tseg2-2;
+ if (tseg1>btc->tseg1_max) {
+ tseg1 = btc->tseg1_max;
+ tseg2 = best_tseg-tseg1-2;
+ }
+
+ DEBUGMSG("Setting %d bps.\n", best_rate);
+ DEBUGMSG("brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d, sampl_pt=%d\n",
+ best_brp, best_tseg, tseg1, tseg2,
+ (100*(best_tseg-tseg2)/(best_tseg+1)));
+
+
+ if(chip->chipspecops->set_bittiming(chip, ++best_brp, ++sjw, ++tseg1, ++tseg2) < 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+
+
+int lpc17xx_chip_config(struct canchip_t *chip){
+
+ CAN_init(chip);
+
+ if (!chip->baudrate)
+ chip->baudrate=1000000;
+
+ if (lpc17xx_baud_rate(chip,chip->baudrate,chip->clock,0,75,0))
+ return -ENODEV;
+
+ return 0;
+}
+
+int lpc17xx_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
+ struct canmsg_t *msg)
+{
+ uint32_t i=0;
+
+ // check status of TB1
+ while (!(can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1)){
+ if(i++<MAX_TRANSMIT_WAIT_LOOPS)
+ continue;
+
+ // request command to abort transmission request
+ can_write_reg(chip, CAN_CMR_AT, CAN_CMR_o);
+ return 0;
+ }
+
+ CAN_send(chip, msg);
+
+ return 0;
+}
+
+int lpc17xx_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
+ struct canmsg_t *msg)
+{
+ uint32_t i=0;
+
+ // write transmission request
+ can_write_reg(chip, (CAN_CMR_TR | CAN_CMR_STB1), CAN_CMR_o);
+
+ // check transmission complete status
+ while (!(can_read_reg(chip, CAN_SR_o) & CAN_SR_TCS1)){
+ if(i++<MAX_TRANSMIT_WAIT_LOOPS)
+ continue;
+
+ CANMSG("Abort transmission request\n");
+
+ // request command to abort transmission request
+ can_write_reg(chip, CAN_CMR_AT, CAN_CMR_o);
+ break;
+ }
+
+ return 0;
+}
+
+int lpc17xx_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
+{
+
+ can_preempt_disable();
+
+ can_msgobj_set_fl(obj,TX_PENDING);
+ can_msgobj_set_fl(obj,TX_REQUEST);
+
+ while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
+ can_msgobj_clear_fl(obj,TX_REQUEST);
+
+ if (can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1){
+ obj->tx_retry_cnt=0;
+ lpc17xx_irq_write_handler(chip, obj);
+ }
+
+ can_msgobj_clear_fl(obj,TX_LOCK);
+ if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
+
+ }
+
+ can_preempt_enable();
+
+ return 0;
+}
+
+int lpc17xx_irq_handler(int irq, struct canchip_t *chip)
+{
+
+ uint32_t i;
+ struct msgobj_t *obj;
+ obj = chip->msgobj[0];
+
+ i = can_read_reg(chip, CAN_ICR_o);
+
+ if(i & (CAN_ICR_TI1 | CAN_ICR_RI)){
+
+ if(can_read_reg(chip, CAN_SR_o) & CAN_SR_RBS) {
+ lpc17xx_read(chip,obj);
+ obj->ret = 0;
+ }
+
+
+ if ((can_msgobj_test_fl(obj,TX_PENDING)) || (can_msgobj_test_fl(obj,TX_REQUEST))) {
+
+ can_msgobj_set_fl(obj,TX_REQUEST);
+
+ while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
+
+ obj->ret=0;
+ can_msgobj_clear_fl(obj,TX_REQUEST);
+
+ if (can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1){
+ obj->tx_retry_cnt=0;
+ lpc17xx_irq_write_handler(chip, obj);
+ }
+
+ can_msgobj_clear_fl(obj,TX_LOCK);
+ if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
+
+ }
+ }
+
+ }
+ if(i & CAN_ICR_DOI)
+ can_write_reg(chip, CAN_CMR_CDO, CAN_CMR_o); // clear data overrun
+
+
+ return CANCHIP_IRQ_HANDLED;
+
+}
+
+void lpc17xx_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
+{
+ int cmd;
+
+
+ if(obj->tx_slot){
+ /* Do local transmitted message distribution if enabled */
+ if (processlocal){
+ /* fill CAN message timestamp */
+ can_filltimestamp(&obj->tx_slot->msg.timestamp);
+
+ obj->tx_slot->msg.flags |= MSG_LOCAL;
+ canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
+ }
+ /* Free transmitted slot */
+ canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
+ obj->tx_slot=NULL;
+ }
+
+ can_msgobj_clear_fl(obj,TX_PENDING);
+ cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
+ if(cmd<0)
+ return;
+ can_msgobj_set_fl(obj,TX_PENDING);
+
+ if (chip->chipspecops->pre_write_config(chip, obj, &obj->tx_slot->msg)) {
+ obj->ret = -1;
+ canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_PREP);
+ canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
+ obj->tx_slot=NULL;
+ return;
+ }
+ if (chip->chipspecops->send_msg(chip, obj, &obj->tx_slot->msg)) {
+ obj->ret = -1;
+ canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_SEND);
+ canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
+ obj->tx_slot=NULL;
+ return;
+ }
+
+}
+
+void lpc17xx_read(struct canchip_t *chip, struct msgobj_t *obj) {
+
+
+ CAN_recv(chip, &obj->rx_msg);
+
+ // fill CAN message timestamp
+ can_filltimestamp(&obj->rx_msg.timestamp);
+
+ canque_filter_msg2edges(obj->qends, &obj->rx_msg);
+
+ // release Receive buffer
+ can_write_reg(chip, CAN_CMR_RRB, CAN_CMR_o);
+
+}
+
+int lpc17xx_set_bittiming(struct canchip_t *chip, int brp, int sjw, int tseg1, int tseg2){
+
+ uint8_t SAM = 0; // 0 = the bus is sampled once
+
+ if((--brp)<0)
+ return -EINVAL;
+
+ if((--sjw)<0)
+ return -EINVAL;
+
+ if((--tseg1)<0)
+ return -EINVAL;
+
+ if((--tseg2)<0)
+ return -EINVAL;
+
+
+ //debug print
+ CANMSG("BRP: %d, SJW: %d, TSEG1: %d, TSEG2: %d \n", brp+1, sjw+1, tseg1+1, tseg2+1);
+
+ can_disable_irq(chip->chip_irq);
+
+ // enter reset mode
+ can_write_reg(chip, 1, CAN_MOD_o);
+
+ // set bittiming register
+ can_write_reg(chip, ((SAM<<23)|(tseg2<<20)|(tseg1<<16)|(sjw<<14)|(brp<<0)), CAN_BTR_o);
+
+ // return to normal operating
+ can_write_reg(chip, 0, CAN_MOD_o);
+
+ can_enable_irq(chip->chip_irq);
+
+ return 0;
+}
+
+int lpc17xx_get_bittiming_const(struct canchip_t *chip, struct can_bittiming_const *btc) {
+ btc->tseg1_min = 1;
+ btc->tseg1_max = 16;
+ btc->tseg2_min = 1;
+ btc->tseg2_max = 8;
+ btc->sjw_max = 4;
+ btc->brp_min = 1;
+ btc->brp_max = 1024;
+ btc->brp_inc = 1;
+
+ return 0;
+}
+
+
+int lpc17xx_fill_chipspecops(struct canchip_t *chip){
+
+ chip->max_objects=1;
+ chip->chip_irq = CAN_IRQn;
+
+ lpc17xx_register(chip->chipspecops);
+
+ return 0;
+}
+
+int lpc17xx_register(struct chipspecops_t *chipspecops){
+
+ CANMSG("initializing lpc17xx can chip operations\n");
+
+ chipspecops->attach_to_chip = lpc17xx_attach_to_chip;
+ chipspecops->pre_read_config = lpc17xx_pre_read_config;
+ chipspecops->chip_config = lpc17xx_chip_config;
+ chipspecops->pre_write_config = lpc17xx_pre_write_config;
+ chipspecops->send_msg = lpc17xx_send_msg;
+ chipspecops->wakeup_tx = lpc17xx_wakeup_tx;
+ chipspecops->irq_handler = lpc17xx_irq_handler;
+
+ chipspecops->set_bittiming = lpc17xx_set_bittiming;
+ chipspecops->get_bittiming_const = lpc17xx_get_bittiming_const;
+
+ return 0;
+
+}
+
+
+int lpc17xx_attach_to_chip(struct canchip_t *chip){
+
+ return 0;
+}
+
+int lpc17xx_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj){
+
+ return 1;
+}
+
+
+
+//---------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------
+
+
+static void CAN_configPin(){
+
+// CAN1 - select P0.0 as RD1. P0.1 as TD1
+
+ uint32_t pinsel0;
+ uint32_t pinmode0;
+ uint32_t pinmode_od0;
+ uint8_t pinsel0_val = 1;
+ uint8_t pinmode0_val = 0;
+ uint8_t pinmode_od0_val = 0;
+
+
+ pinsel0 = PINCON->PINSEL0;
+ pinsel0 &= ~CAN1_RX_MASK;
+ pinsel0 &= ~CAN1_TX_MASK;
+ pinsel0 |= __val2mfld(CAN1_RX_MASK, pinsel0_val);
+ pinsel0 |= __val2mfld(CAN1_TX_MASK, pinsel0_val);
+ PINCON->PINSEL0 = pinsel0;
+
+ pinmode0 = PINCON->PINMODE0;
+ pinmode0 &= ~CAN1_RX_MASK;
+ pinmode0 &= ~CAN1_TX_MASK;
+ pinmode0 |= __val2mfld(CAN1_RX_MASK, pinmode0_val);
+ pinmode0 |= __val2mfld(CAN1_TX_MASK, pinmode0_val);
+ PINCON->PINMODE0 = pinmode0;
+
+ pinmode_od0 = PINCON->PINMODE_OD0;
+ if (pinmode_od0_val){
+ pinmode_od0 |= CAN1_RX_BIT;
+ pinmode_od0 |= CAN1_TX_BIT;
+ }
+ else{
+ pinmode_od0 &= ~CAN1_RX_BIT;
+ pinmode_od0 &= ~CAN1_TX_BIT;
+ }
+ PINCON->PINMODE_OD0 = pinmode_od0;
+
+
+}
+
+void CAN_recv(struct canchip_t *chip, canmsg_t* msg){
+
+ volatile uint32_t data;
+ uint32_t i;
+
+ // read data lenght
+ msg->length = (can_read_reg(chip, CAN_RFS_o)>>16) & 0xF;
+
+ // read identifier
+ msg->id = can_read_reg(chip, CAN_RID_o);
+
+ // EXT frame
+ if(can_read_reg(chip, CAN_RFS_o) & CAN_RFS_EXT)
+ msg->flags |= MSG_EXT;
+ else
+ msg->flags &= ~MSG_EXT;
+
+
+ // RTR frame
+ if(can_read_reg(chip, CAN_RFS_o) & CAN_RFS_RTR)
+ msg->flags |= MSG_RTR;
+ else
+ msg->flags &= ~MSG_RTR;
+
+
+ // read data
+ data = can_read_reg(chip, CAN_RDA_o);
+ for(i=0; i<4; i++)
+ msg->data[i] = (data>>(i*8)) & 0xFF;
+
+ data = can_read_reg(chip, CAN_RDB_o);
+ for(i=4; i<8; i++)
+ msg->data[i] = (data>>((i-4)*8)) & 0xFF;
+
+}
+
+
+void CAN_send(struct canchip_t *chip, canmsg_t* msg){
+
+ volatile uint32_t data;
+ volatile uint32_t can_tfi1;
+ uint32_t i=0;
+
+ can_tfi1 = can_read_reg(chip, CAN_TFI1_o);
+
+ can_tfi1 &= ~0x000F0000;
+ can_tfi1 |= (msg->length)<<16;
+
+ // EXT frame
+ if(msg->flags & MSG_EXT)
+ can_tfi1 |= CAN_TFI1_EXT;
+ else
+ can_tfi1 &= ~CAN_TFI1_EXT;
+
+ // RTR frame
+ if(msg->flags & MSG_RTR)
+ can_tfi1 |= CAN_TFI1_RTR;
+ else
+ can_tfi1 &= ~CAN_TFI1_RTR;
+
+ can_write_reg(chip, can_tfi1, CAN_TFI1_o);
+
+
+ // write CAN ID
+ can_write_reg(chip, msg->id, CAN_TID1_o);
+
+
+ // write first 4 data bytes
+ data=0;
+ for(i=0; i<4; i++)
+ data |= (msg->data[i])<<(i*8);
+
+ can_write_reg(chip, data, CAN_TDA1_o);
+
+ // write second 4 data bytes
+ data=0;
+ for(i=4; i<8; i++)
+ data |= (msg->data[i])<<((i-4)*8);
+
+ can_write_reg(chip, data, CAN_TDB1_o);
+
+}
+
+void CAN_init(struct canchip_t *chip){
+
+ uint32_t tmp;
+ uint32_t pclksel0;
+ uint32_t val;
+ uint32_t i;
+
+ // configure CAN1 pins
+ CAN_configPin();
+
+ // turn on power and clock for CAN1
+ SC->PCONP |= PCCAN1;
+
+ // set clock divide for CAN1
+
+ val = 0x00; // 00 PCLK_peripheral = CCLK/4
+ pclksel0 = SC->PCLKSEL0;
+ pclksel0 &= ~PCLK_CAN1_MASK;
+ pclksel0 &= ~PCLK_CAN2_MASK;
+ pclksel0 &= ~PCLK_ACF_MASK;
+ pclksel0 |= __val2mfld(PCLK_CAN1_MASK, val);
+ pclksel0 |= __val2mfld(PCLK_CAN2_MASK, val);
+ pclksel0 |= __val2mfld(PCLK_ACF_MASK, val);
+ SC->PCLKSEL0 = pclksel0;
+
+ // enter reset mode
+ can_write_reg(chip, 1, CAN_MOD_o);
+
+ // disable all CAN interrupts
+ can_write_reg(chip, 0, CAN_IER_o);
+
+ // reset value of Global Status Register (global controller status and error counters)
+ can_write_reg(chip, 0x3C, CAN_GSR_o);
+
+ // request command to release Rx, Tx buffer and clear data overrun
+ can_write_reg(chip, (CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO), CAN_CMR_o);
+
+ // read to clear interrupt pending in Interrupt Capture Register
+ tmp = can_read_reg(chip, CAN_ICR_o);
+
+ // return to normal operating
+ can_write_reg(chip, 0, CAN_MOD_o);
+
+
+ //--------------------------
+
+ // Acceptance Filter Off Mode
+ CANAF_AFMR = 0x01;
+
+ // clear RAM masks
+ for (i = 0; i < 512; i++) {
+ CANAF_RAM->mask[i] = 0x00;
+ }
+
+ CANAF_SFF_sa = 0x00;
+ CANAF_SFF_GRP_sa = 0x00;
+ CANAF_EFF_sa = 0x00;
+ CANAF_EFF_GRP_sa = 0x00;
+ CANAF_ENDofTable = 0x00;
+
+ // Acceptance Filter Bypass Mode - all messages accepted
+ CANAF_AFMR = 0x02;
+
+ //--------------------------
+
+
+ // enable interrupt after transmit
+ // enable receive interrupt
+ // enable data overrun interrupt
+ can_write_reg(chip, (CAN_IER_TIE1 | CAN_IER_RIE | CAN_IER_DOIE), CAN_IER_o);
+
+
+}
+
--- /dev/null
+/**************************************************************************/
+/* File: main.c - setup and main loop of USB<->CAN converter */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2011 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2008 Jan Kriz email:johen@post.cz */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <cpu_def.h>
+#include <system_def.h>
+#include <lt_timer.h>
+#include <local_config.h>
+#include <usb/usbdebug.h>
+#include <usb/usb.h>
+#include <usb/lpc.h>
+#include <usb/usb_srq.h>
+#include <mem_loc.h>
+#include <keyval_id.h>
+#include <hal_machperiph.h>
+#include <keyval_loc.h>
+#include <lpciap.h>
+#include <lpciap_kvpb.h>
+
+#include <endian.h>
+#if __BYTE_ORDER == __BIG_ENDIAN
+ #include <byteswap.h>
+#endif
+
+#include "./can/can.h"
+#include "./can/sja1000p.h"
+#include "./can/main.h"
+
+// #include "./can/can_sysdep.h"
+#include "./can/modparms.h"
+#include "./can/devcommon.h"
+
+//#include "./can/ul_usb1.h"
+
+#include "./can/setup.h"
+
+#include "./usb/usb_defs.h"
+#include "./usb/usb_vend.h"
+
+extern int can_lmc1_register(struct hwspecops_t *hwspecops);
+extern int ul_usb1_register(struct hwspecops_t *hwspecops);
+
+#define MASK_EP1RX 0x01
+#define MASK_EP1TX 0x02
+
+#define CAN_OP_MASK 0x80
+#define CAN_OP_READ 0x80
+#define CAN_OP_WRITE 0x00
+
+#ifdef USB_MAX_PACKET
+ #undef USB_MAX_PACKET
+ #define USB_MAX_PACKET 16
+#endif
+/***********************************************************************
+ * Note:
+ * Comparing to LinCAN, there is no need to sleep for processes
+ * because the degree of filling of fifo from the client side
+ * is solved in main cycle (no new messages are accepted when full)
+ * and on the server side by speed of USB interface. FIFO in edge
+ * from SJA chip to USB interface should never be filled.
+ ***********************************************************************/
+
+/***********************************************************************
+ * Note:
+ * Code is wittingly complex in order to ease future changes in hardware
+ *Â configuration and to make it as much similar as the code of LinCAN
+ ***********************************************************************/
+
+LT_TIMER_DEC(lt_10msec)
+LT_TIMER_IMP(lt_10msec)
+LT_TIMER_DEC(lt_100msec)
+LT_TIMER_IMP(lt_100msec)
+LT_TIMER_DEC(lt_2sec)
+LT_TIMER_IMP(lt_2sec)
+
+typedef void (*FNC)(); //function ptr
+
+/***********************************************************************
+ * global variables
+ ***********************************************************************/
+
+usb_device_t usb_device;
+
+usb_ep_t eps[NUM_ENDPOINTS];
+unsigned char ep1_rx_buff[USB_MAX_PACKET];
+unsigned char ep1_tx_buff[USB_MAX_PACKET];
+uint8_t timer_str,timer_rx_off,timer_tx_off,timer_configured;
+volatile uint8_t bootloader_run;
+
+uint8_t vendor_ret;
+
+int processlocal;
+
+int baudrate[MAX_TOT_CHIPS];
+struct canhardware_t canhardware;
+struct canhardware_t *hardware_p=&canhardware;
+struct canchip_t *chips_p[MAX_TOT_CHIPS];
+struct msgobj_t *objects_p[MAX_TOT_MSGOBJS];
+
+struct canuser_t *canuser;
+
+extern int init_chip_struct(struct candevice_t *candev, int chipnr, int irq, long baudrate);
+extern int register_chip_struct(struct canchip_t *chip, int minorbase);
+extern int register_obj_struct(struct msgobj_t *obj, int minorbase);
+
+/***********************************************************************
+ * IF SOMETHING BAD HAPPENED
+ ***********************************************************************/
+
+int sys_err(){
+
+ unsigned char i=0;
+
+ while(1) {
+ if (lt_100msec_expired(100)) {
+ i++;
+ if (i&1) {
+ SET_OUT_PIN(LED_PORT,LED_ERR);
+ } else {
+ CLR_OUT_PIN(LED_PORT,LED_ERR);
+ }
+ #ifdef WATCHDOG_ENABLED
+ watchdog_feed();
+ #endif /* WATCHDOG_ENABLED */
+ }
+ }
+}
+
+/***********************************************************************
+ * Routine for visible LED blinking (on USB transmission)
+ ***********************************************************************/
+
+void timer_10ms(void)
+{
+ if (timer_tx_off!=0) timer_tx_off--;
+ else SET_OUT_PIN(LED_PORT,LED1_BIT);
+ if (timer_rx_off!=0) timer_rx_off--;
+ else SET_OUT_PIN(LED_PORT,LED2_BIT);
+
+/* if (timer_configured!=0) timer_configured--;
+ else {
+ timer_configured=20;
+ CLR_OUT_PIN(LED_PORT,LED1_BIT);
+ CLR_OUT_PIN(LED_PORT,LED2_BIT);
+ timer_rx_off=timer_tx_off=5;
+ }*/
+}
+
+/***********************************************************************
+ * Main routine
+ ***********************************************************************/
+
+int main(void)
+{
+ struct candevice_t *candev;
+ struct canchip_t *chip=NULL;
+ struct msgobj_t *obj;
+ struct canque_ends_t *qends;
+ struct canque_edge_t *edge,*qedge;
+ struct canque_slot_t *slot;
+ struct canmsg_t canmsg;
+ can_spin_irqflags_t iflags;
+
+ int chipnr,bd;
+ int i,size,m=0;
+
+ CANMSG("Starting USBCAN module firmware...\n");
+
+// volatile int i=0;
+ bootloader_run=0;
+ /***********************************/
+
+ lt_10msec_init();
+ lt_100msec_init();
+ lt_2sec_init();
+
+ // DEBUG
+ //SET_OUT_PIN(LED_PORT,LED_ERR);
+ //CLR_OUT_PIN(LED_PORT,LED_GP);
+
+ if (USB_MAX_PACKET<16){
+ CANMSG("Maximum packet size less than 16B (is %dB)\n",USB_MAX_PACKET);
+ sys_err();
+ }
+
+
+ // ***********************************************************************
+ // * CAN device initialization - device side (adapted from LinCAN setup.c)
+ // ***********************************************************************
+
+ DEBUGMSG("Initiating CAN device initialization\n");
+ baudrate[0]=1000;
+
+ canqueue_kern_initialize();
+
+ hardware_p->nr_boards=1;
+
+ candev=(struct candevice_t *)malloc(sizeof(struct candevice_t));
+ if (!candev){
+ CANMSG("No space left in memory\n");
+ sys_err();
+ }
+ memset(candev, 0, sizeof(struct candevice_t));
+
+ hardware_p->candevice[0]=candev;
+ candev->candev_idx=0;
+ candev->io_addr=0;
+ candev->dev_base_addr=0;
+
+ candev->hwspecops=(struct hwspecops_t *)malloc(sizeof(struct hwspecops_t));
+ if (!candev->hwspecops){
+ CANMSG("No space left in memory\n");
+ sys_err();
+ }
+ memset(candev->hwspecops, 0, sizeof(struct hwspecops_t));
+
+
+
+#ifdef CONFIG_OC_LINCAN_CARD_ul_usb1
+ ul_usb1_register(candev->hwspecops);
+#endif
+#ifdef CONFIG_OC_LINCAN_CARD_can_lmc1
+ can_lmc1_register(candev->hwspecops);
+#endif
+
+ bd=baudrate[0];
+ if (candev->hwspecops->init_hw_data(candev)){
+ CANMSG("HW data could not be initialized\n");
+ sys_err();
+ }
+
+ // Alocate and initialize the chip structures
+ for (chipnr=0; chipnr < candev->nr_all_chips; chipnr++) {
+// if(chipnr<irqnum)
+// irqsig=irq[*irq_param_idx_p+chipnr];
+ if (init_chip_struct(candev, chipnr, 0, bd*1000)){
+ CANMSG("Chip structure could not be initialized\n");
+ sys_err();
+ }
+ }
+
+
+
+ for (chipnr=0; chipnr < candev->nr_all_chips; chipnr++) {
+ struct canchip_t *chip=candev->chip[chipnr];
+ int objnr;
+
+ register_chip_struct(chip, m);
+
+ for (objnr=0; objnr<chip->max_objects; objnr++) {
+ register_obj_struct(chip->msgobj[objnr], m);
+ if(m>=0) m++;
+ }
+ }
+
+
+ if (candev->hwspecops->request_io(candev)) {
+ CANMSG("Error to request IO\n");
+ sys_err();
+ }
+ candev->flags|=CANDEV_IO_RESERVED;
+
+
+ if (candev->hwspecops->reset(candev)) {
+ CANMSG("Error to reset chip\n");
+ sys_err();
+ }
+
+
+ for(chipnr=0; chipnr<candev->nr_all_chips; chipnr++) {
+ if((chip=candev->chip[chipnr])==NULL)
+ continue;
+
+ if(chip->chipspecops->attach_to_chip(chip)<0) {
+// CANMSG("Initial attach to the chip HW failed\n");
+ sys_err();
+ }
+
+ chip->flags |= CHIP_ATTACHED;
+
+ // used with lpc17xx:
+ if(can_chip_setup_irq(chip)<0) {
+ CANMSG("Error to setup chip IRQ\n");
+ sys_err();
+ }
+
+ }
+
+ if (candev->flags & CANDEV_PROGRAMMABLE_IRQ)
+ if (candev->hwspecops->program_irq(candev)){
+// CANMSG("Error to program board interrupt\n");
+ sys_err();
+ }
+
+ //***********************************************************************
+ // * CAN device initialization - client side (adapted from LinCAN open.c)
+ // ***********************************************************************
+
+
+ chip=candev->chip[0];
+ obj=chip->msgobj[0];
+ atomic_inc(&obj->obj_used);
+ can_msgobj_set_fl(obj,OPENED);
+
+ if (chip->flags & CHIP_CONFIGURED)
+ DEBUGMSG("Device is already configured.\n");
+ else {
+ if (chip->chipspecops->chip_config(chip))
+ CANMSG("Error configuring chip.\n");
+ else
+ chip->flags |= CHIP_CONFIGURED;
+
+ if (chip->chipspecops->pre_read_config(chip,obj)<0)
+ CANMSG("Error initializing chip for receiving\n");
+
+ } // End of chip configuration
+
+
+ canuser = (struct canuser_t *)malloc(sizeof(struct canuser_t));
+ if(canuser == NULL) sys_err();
+ canuser->flags=0;
+// canuser->userinfo.fileinfo.file = file;
+ canuser->msgobj = obj;
+// canuser->magic = CAN_USER_MAGIC;
+// file->private_data = canuser;
+
+ qends = (struct canque_ends_t *)malloc(sizeof(struct canque_ends_t));
+ if(qends == NULL) sys_err();
+ canqueue_ends_init_kern(qends);
+ canuser->qends = qends;
+
+ //required to synchronize with RT-Linux context
+ can_spin_lock_irqsave(&canuser_manipulation_lock, iflags);
+ list_add(&canuser->peers, &obj->obj_users);
+ can_spin_unlock_irqrestore(&canuser_manipulation_lock, iflags);
+
+ if(canqueue_connect_edge(edge=canque_new_edge_kern(MAX_BUF_LENGTH),
+ canuser->qends, obj->qends)<0) sys_err();
+
+ if(canqueue_connect_edge(canuser->rx_edge0=canque_new_edge_kern(MAX_BUF_LENGTH),
+ obj->qends, canuser->qends)<0) sys_err();
+ //FIXME: more generic model should be used there
+ canque_edge_decref(canuser->rx_edge0);
+ canque_edge_decref(edge);
+
+
+
+ /***********************************************************************
+ * USB Init
+ ***********************************************************************/
+
+ memset( &usb_device, 0, sizeof( usb_device));
+ usb_device.id = 1;
+ usb_device.devdes_table = &usb_devdes_table;
+ usb_device.init = usb_lpc_init;
+ usb_debug_set_level(DEBUG_LEVEL_NONE);
+ usb_device.cntep = NUM_ENDPOINTS;
+ usb_device.ep = eps;
+
+ eps[0].max_packet_size = USB_MAX_PACKET;
+ eps[1].max_packet_size = USB_MAX_PACKET;
+ eps[0].epnum = 0x01;
+ eps[1].epnum = 0x81;
+ eps[0].event_mask = 0x04;
+ eps[1].event_mask = 0x08;
+ eps[0].udev = &usb_device;
+ eps[1].udev = &usb_device;
+
+ usb_device.vendor_fnc=usbcan_vendor;
+
+ usb_init(&usb_device);
+ usb_connect(&usb_device);
+ usb_device.ep_events |= MASK_EP1TX;
+
+ /***********************************************************************
+ * Start
+ ***********************************************************************/
+
+ timer_rx_off=timer_tx_off=timer_str=timer_configured=0;
+
+
+ printf("Main loop\n");
+
+ while (1) {
+
+ usb_check_events(&usb_device);
+ usb_control_response(&usb_device);
+
+#ifdef CONFIG_OC_LINCAN_CARD_ul_usb1
+ /* polled IRQ mode for ul_usb1 board*/
+ if (!(IO0PIN&P0_SJA1000_INT_PIN)) /* INT PIN is inverted */
+ chip->chipspecops->irq_handler(0,chip);
+#endif
+
+ if (usb_device.ep_events & MASK_EP1RX) { //EP1RX - data waiting to receive
+
+ if (canque_get_inslot(qends, &qedge, &slot, 0)>=0){ //Free slot obtained
+
+ size=usb_udev_read_endpoint(&eps[0],ep1_rx_buff,16);
+ if (size==16){
+ uint16_t msgflags;
+ uint32_t msgid;
+ canmsg.cob=0;
+ canmsg.length=*(uint8_t *)(ep1_rx_buff+1);
+ if (canmsg.length > CAN_MSG_LENGTH)
+ canmsg.length=CAN_MSG_LENGTH;
+ msgflags=*(uint16_t *)(ep1_rx_buff+2);
+ msgid=*(uint32_t *)(ep1_rx_buff+4);
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ msgflags = bswap_16( msgflags);
+ msgid = bswap_32( msgid);
+ #endif
+ canmsg.flags=msgflags;
+ canmsg.id=msgid;
+
+ for (i=0;i<canmsg.length;i++){
+ canmsg.data[i]=*(unsigned char*)(ep1_rx_buff+8+i);
+ }
+ for (;i<CAN_MSG_LENGTH;i++){
+ canmsg.data[i]=0;
+ }
+ /* Automatic selection of extended format if ID>2047 */
+ if (canmsg.id & ~0x7ffl & MSG_ID_MASK ) canmsg.flags |= MSG_EXT;
+ /* has been dependent on "extended" option */
+
+ slot->msg=canmsg;
+ canque_put_inslot(qends, qedge, slot);
+
+ }
+ else
+ canque_abort_inslot(qends,qedge,slot);
+
+
+ timer_rx_off=50; //rosviceni diody pri prijmu
+ CLR_OUT_PIN(LED_PORT,LED2_BIT);
+ usb_device.ep_events &= ~MASK_EP1RX;
+
+
+ }
+
+
+/* if (size==2){
+ uint8_t val;
+ if ((data[0]&CAN_OP_MASK)==CAN_OP_READ){ // Get data from CAN device and return to caller
+ val = can_read(data[0] & ~CAN_OP_MASK);
+ *(data+1)=val;
+ usb_udev_write_endpoint(&eps[1],(unsigned char *)data,size);
+ timer_rx_off=50; //rosviceni diody pri prijmu
+ CLR_OUT_PIN(LED_PORT,LED2_BIT);
+ usb_can_send=0;
+ }
+ if ((data[0]&CAN_OP_MASK)==CAN_OP_WRITE){ // Save data to CAN device
+ can_write(data[1], data[0] & ~CAN_OP_MASK);
+ timer_tx_off=50; //rozsviceni diod pri vysilani
+ CLR_OUT_PIN(LED_PORT,LED1_BIT);
+ }
+ }*/
+ }
+
+
+ if(usb_device.ep_events & MASK_EP1TX){ //EP1TX - data transmitted
+ if(canque_test_outslot(qends, &qedge, &slot)>=0){
+ DEBUGMSG("CAN message ready to send over usb\n");
+ uint16_t msgflags;
+ uint32_t msgid;
+
+ *(uint8_t *)(ep1_tx_buff)=0;
+ *(uint8_t *)(ep1_tx_buff+1)=slot->msg.length;
+
+ msgflags=slot->msg.flags;
+ msgid=slot->msg.id;
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ msgflags = bswap_16( msgflags);
+ msgid = bswap_32( msgid);
+ #endif
+
+ *(uint16_t *)(ep1_tx_buff+2)=msgflags;
+ *(uint32_t *)(ep1_tx_buff+4)=msgid;
+ for (i=0;i<slot->msg.length;i++){
+ *(uint8_t *)(ep1_tx_buff+8+i)=slot->msg.data[i];
+ }
+ for (;i<CAN_MSG_LENGTH;i++){
+ *(uint8_t *)(ep1_tx_buff+8+i)=0;
+ }
+ usb_udev_write_endpoint(&eps[1],ep1_tx_buff,16);
+
+ canque_free_outslot(qends, qedge, slot);
+ timer_tx_off=50; //rozsviceni diod pri vysilani
+ CLR_OUT_PIN(LED_PORT,LED1_BIT);
+ usb_device.ep_events &= ~MASK_EP1TX;
+
+ }
+
+
+ }
+
+
+ //if (usb_can_send && )
+
+#ifdef WATCHDOG_ENABLED
+ watchdog_feed();
+#endif /* WATCHDOG_ENABLED */
+
+ /* 10ms timer */
+ if (lt_10msec_expired(10))
+ timer_10ms();
+ }
+
+ SET_OUT_PIN(LED_PORT,LED_GP);
+ SET_OUT_PIN(LED_PORT,LED_ERR);
+
+ /* unreachable code */
+#ifdef SDCC
+ vec_jmp(0x0); /* need to call a function from misc to correct linking */
+#endif
+ return 0;
+}
--- /dev/null
+/**************************************************************************/
+/* File: setup.c - CAN driver and chips setup code */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+#include "./can/can.h"
+#include "./can/can_sysdep.h"
+#include "./can/main.h"
+#include "./can/devcommon.h"
+#include "./can/setup.h"
+//#include "./can/finish.h"
+
+int init_hwspecops(struct candevice_t *candev, int *irqnum_p);
+int init_device_struct(int card, int *chan_param_idx_p, int *irq_param_idx_p);
+int init_chip_struct(struct candevice_t *candev, int chipnr, int irq, long baudrate, long clock);
+int init_obj_struct(struct candevice_t *candev, struct canchip_t *hostchip, int objnr);
+
+/**
+ * can_base_addr_fixup - relocates board physical memory addresses to the CPU accessible ones
+ * @candev: pointer to the previously filled device/board, chips and message objects structures
+ * @new_base: @candev new base address
+ *
+ * This function adapts base addresses of all structures of one board
+ * to the new board base address.
+ * It is required for translation between physical and virtual address mappings.
+ * This function is prepared to simplify board specific xxx_request_io() function
+ * for memory mapped devices.
+ */
+int can_base_addr_fixup(struct candevice_t *candev, can_ioptr_t new_base)
+{
+ long offs;
+ int i, j;
+
+ offs=new_base-candev->dev_base_addr;
+ candev->dev_base_addr=new_base;
+ for(i=0;i<candev->nr_all_chips;i++){
+ candev->chip[i]->chip_base_addr += offs;
+ for(j=0;j<candev->chip[i]->max_objects;j++)
+ candev->chip[i]->msgobj[j]->obj_base_addr += offs;
+ }
+ return 0;
+}
+
+/**
+ * can_check_dev_taken - checks if bus device description is already taken by driver
+ * @anydev: pointer to bus specific Linux device description
+ *
+ * Returns: Returns 1 if device is already used by LinCAN driver, 0 otherwise.
+ */
+int can_check_dev_taken(void *anydev)
+{
+ int board_nr;
+ struct candevice_t *candev;
+ void *boarddev;
+
+ for (board_nr=hardware_p->nr_boards; board_nr--; ) {
+ if((candev=hardware_p->candevice[board_nr])==NULL)
+ continue;
+ boarddev=candev->sysdevptr.anydev;
+ if(boarddev == anydev)
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/**
+ * register_obj_struct - registers message object into global array
+ * @obj: the initialized message object being registered
+ * @minorbase: wanted minor number, if (-1) automatically selected
+ *
+ * Return Value: returns negative number in the case of fail
+ */
+int register_obj_struct(struct msgobj_t *obj, int minorbase)
+{
+ static int next_minor=0;
+ int i;
+
+ if(minorbase>=0)
+ next_minor=minorbase;
+ if(next_minor>=MAX_TOT_MSGOBJS)
+ next_minor=0;
+ i=next_minor;
+ do{
+ if(objects_p[i]==NULL){
+ objects_p[i]=obj;
+ obj->minor=i;
+ next_minor=i+1;
+ return 0;
+ }
+ if(++i >= MAX_TOT_MSGOBJS) i=0;
+ }while(i!=next_minor);
+ obj->minor=-1;
+ return -1;
+}
+
+
+/**
+ * register_chip_struct - registers chip into global array
+ * @chip: the initialized chip structure being registered
+ * @minorbase: wanted minor number base, if (-1) automatically selected
+ *
+ * Return Value: returns negative number in the case of fail
+ */
+int register_chip_struct(struct canchip_t *chip, int minorbase)
+{
+ static int next_chip_slot=0;
+ int i;
+
+ if(next_chip_slot>=MAX_TOT_CHIPS)
+ next_chip_slot=0;
+ i=next_chip_slot;
+ do{
+ if(chips_p[i]==NULL){
+ chips_p[i]=chip;
+
+ next_chip_slot=i+1;
+ return 0;
+ }
+ if(++i >= MAX_TOT_CHIPS) i=0;
+ }while(i!=next_chip_slot);
+ return -1;
+}
+
+
+
+/**
+ * init_hw_struct - initializes driver hardware description structures
+ *
+ * The function init_hw_struct() is used to initialize the hardware structure.
+ *
+ * Return Value: returns negative number in the case of fail
+ */
+// int init_hw_struct(void)
+// {
+// int i=0;
+// int irq_param_idx=0;
+// int chan_param_idx=0;
+//
+// hardware_p->nr_boards=0;
+// while ( (hw[i] != NULL) & (i < MAX_HW_CARDS) ) {
+// hardware_p->nr_boards++;
+//
+// if (init_device_struct(i, &chan_param_idx, &irq_param_idx)) {
+// CANMSG("Error initializing candevice_t structures.\n");
+// return -ENODEV;
+// }
+// i++;
+// }
+//
+// return 0;
+// }
+
+/**
+ * init_device_struct - initializes single CAN device/board
+ * @card: index into @hardware_p HW description
+ * @chan_param_idx_p: pointer to the index into arrays of the CAN channel parameters
+ * @irq_param_idx_p: pointer to the index into arrays of the per CAN channel IRQ parameters
+ *
+ * The function builds representation of the one board from parameters provided
+ * in the module parameters arrays:
+ * @hw[card] .. hardware type,
+ * @io[card] .. base IO address,
+ * @baudrate[chan_param_idx] .. per channel baudrate,
+ * @minor[chan_param_idx] .. optional specification of requested channel minor base,
+ * @irq[irq_param_idx] .. one or more board/chips IRQ parameters.
+ * The indexes are advanced after consumed parameters if the registration is successful.
+ *
+ * The hardware specific operations of the device/board are initialized by call to
+ * init_hwspecops() function. Then board data are initialized by board specific
+ * init_hw_data() function. Then chips and objects representation is build by
+ * init_chip_struct() function. If all above steps are successful, chips and
+ * message objects are registered into global arrays.
+ *
+ * Return Value: returns negative number in the case of fail
+ */
+// int init_device_struct(int card, int *chan_param_idx_p, int *irq_param_idx_p)
+// {
+// struct candevice_t *candev;
+// int ret;
+// int irqnum;
+// int chipnr;
+// long bd;
+// int irqsig=-1;
+//
+// candev=(struct candevice_t *)malloc(sizeof(struct candevice_t));
+// if (candev==NULL)
+// return -ENOMEM;
+//
+// memset(candev, 0, sizeof(struct candevice_t));
+//
+// hardware_p->candevice[card]=candev;
+// candev->candev_idx=card;
+//
+// candev=candev;
+//
+// candev->hwname=hw[card];
+// candev->io_addr=io[card];
+// candev->dev_base_addr=io[card];
+//
+// candev->hwspecops=(struct hwspecops_t *)malloc(sizeof(struct hwspecops_t));
+// if (candev->hwspecops==NULL)
+// goto error_nomem;
+//
+// memset(candev->hwspecops, 0, sizeof(struct hwspecops_t));
+//
+// if (init_hwspecops(candev, &irqnum))
+// goto error_nodev;
+//
+// if (candev->hwspecops->init_hw_data(candev))
+// goto error_nodev;
+//
+// /* Alocate and initialize the chip structures */
+// for (chipnr=0; chipnr < candev->nr_all_chips; chipnr++) {
+//
+// if(chipnr<irqnum)
+// irqsig=irq[*irq_param_idx_p+chipnr];
+//
+// bd=baudrate[*chan_param_idx_p+chipnr];
+// if(!bd) bd=baudrate[0];
+//
+// if ((ret=init_chip_struct(candev, chipnr, irqsig, bd*1000)))
+// goto error_chip;
+// }
+//
+//
+//
+// for (chipnr=0; chipnr < candev->nr_all_chips; chipnr++) {
+// int m=minor[*chan_param_idx_p+chipnr];
+// struct canchip_t *chip=candev->chip[chipnr];
+// int objnr;
+//
+// register_chip_struct(chip, m);
+//
+// for (objnr=0; objnr<chip->max_objects; objnr++) {
+// register_obj_struct(chip->msgobj[objnr], m);
+// if(m>=0) m++;
+// }
+// }
+//
+// *irq_param_idx_p += irqnum;
+// *chan_param_idx_p += candev->nr_all_chips;
+//
+// return 0;
+//
+// error_nodev:
+// ret=-ENODEV;
+// error_chip:
+// candevice_done(candev);
+// goto error_both;
+//
+// error_nomem:
+// ret=-ENOMEM;
+//
+// error_both:
+// hardware_p->candevice[card]=NULL;
+// free(candev);
+// return ret;
+//
+// }
+
+/**
+ * init_chip_struct - initializes one CAN chip structure
+ * @candev: pointer to the corresponding CAN device/board
+ * @chipnr: index of the chip in the corresponding device/board structure
+ * @irq: chip IRQ number or (-1) if not appropriate
+ * @baudrate: baudrate in the units of 1Bd
+ * @clock: optional chip base clock frequency in 1Hz step
+ *
+ * Chip structure is allocated and chip specific operations are filled by
+ * call to board specific init_chip_data() which calls chip specific
+ * fill_chipspecops(). The message objects are generated by
+ * calls to init_obj_struct() function.
+ *
+ * Return Value: returns negative number in the case of fail
+ */
+int init_chip_struct(struct candevice_t *candev, int chipnr, int irq, long baudrate, long clock)
+{
+ struct canchip_t *chip;
+ int objnr;
+ int ret;
+
+ candev->chip[chipnr]=(struct canchip_t *)malloc(sizeof(struct canchip_t));
+ if ((chip=candev->chip[chipnr])==NULL)
+ return -ENOMEM;
+
+ memset(chip, 0, sizeof(struct canchip_t));
+
+ chip->write_register=candev->hwspecops->write_register;
+ chip->read_register=candev->hwspecops->read_register;
+
+ chip->chipspecops=malloc(sizeof(struct chipspecops_t));
+ if (chip->chipspecops==NULL)
+ return -ENOMEM;
+ memset(chip->chipspecops,0,sizeof(struct chipspecops_t));
+
+ chip->chip_idx=chipnr;
+ chip->hostdevice=candev;
+ chip->chip_irq=irq;
+ chip->baudrate=baudrate;
+ chip->clock=clock;
+ chip->flags=0x0;
+
+ if(candev->hwspecops->init_chip_data(candev,chipnr)<0)
+ return -ENODEV;
+
+ for (objnr=0; objnr<chip->max_objects; objnr++) {
+ ret=init_obj_struct(candev, chip, objnr);
+ if(ret<0) return ret;
+ }
+
+ return 0;
+}
+
+
+/**
+ * init_obj_struct - initializes one CAN message object structure
+ * @candev: pointer to the corresponding CAN device/board
+ * @hostchip: pointer to the chip containing this object
+ * @objnr: index of the builded object in the chip structure
+ *
+ * The function initializes message object structure and allocates and initializes
+ * CAN queue chip ends structure.
+ *
+ * Return Value: returns negative number in the case of fail
+ */
+int init_obj_struct(struct candevice_t *candev, struct canchip_t *hostchip, int objnr)
+{
+ struct canque_ends_t *qends;
+ struct msgobj_t *obj;
+ int ret;
+
+ obj=(struct msgobj_t *)malloc(sizeof(struct msgobj_t));
+ hostchip->msgobj[objnr]=obj;
+ if (obj == NULL)
+ return -ENOMEM;
+
+ memset(obj, 0, sizeof(struct msgobj_t));
+ obj->minor=-1;
+
+ atomic_set(&obj->obj_used,0);
+ INIT_LIST_HEAD(&obj->obj_users);
+// init_timer(&obj->tx_timeout);
+
+ qends = (struct canque_ends_t *)malloc(sizeof(struct canque_ends_t));
+ if(qends == NULL) return -ENOMEM;
+ memset(qends, 0, sizeof(struct canque_ends_t));
+ obj->hostchip=hostchip;
+ obj->object=objnr+1;
+ obj->qends=qends;
+ obj->tx_qedge=NULL;
+ obj->tx_slot=NULL;
+ obj->obj_flags = 0x0;
+
+ ret=canqueue_ends_init_chip(qends, hostchip, obj);
+ if(ret<0) return ret;
+
+ ret=candev->hwspecops->init_obj_data(hostchip,objnr);
+ if(ret<0) return ret;
+
+ return 0;
+}
+
+
+/**
+ * init_hwspecops - finds and initializes board/device specific operations
+ * @candev: pointer to the corresponding CAN device/board
+ * @irqnum_p: optional pointer to the number of interrupts required by board
+ *
+ * The function searches board @hwname in the list of supported boards types.
+ * The board type specific board_register() function is used to initialize
+ * @hwspecops operations.
+ *
+ * Return Value: returns negative number in the case of fail
+ */
+// int init_hwspecops(struct candevice_t *candev, int *irqnum_p)
+// {
+// const struct boardtype_t *brp;
+//
+// brp = boardtype_find(candev->hwname);
+//
+// if(!brp) {
+// CANMSG("Sorry, hardware \"%s\" is currently not supported.\n",candev->hwname);
+// return -EINVAL;
+// }
+//
+// if(irqnum_p)
+// *irqnum_p=brp->irqnum;
+// brp->board_register(candev->hwspecops);
+//
+// return 0;
+// }
--- /dev/null
+/**************************************************************************/
+/* File: sja1000p.c - Philips/NXP SJA1000 chip PeliCanCAN mode support */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Copyright (C) 2004-2005 Tomasz Motylewski (BFAD GmbH) */
+/* Funded by OCERA and FRESCOR IST projects */
+/* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+#include "./can/can.h"
+#include "./can/can_sysdep.h"
+#include "./can/main.h"
+#include "./can/sja1000p.h"
+
+#ifdef CONFIG_OC_LINCAN_DETAILED_ERRORS
+
+static const char *sja1000_ecc_errc_str[]={
+ "bit error",
+ "form error",
+ "stuff error",
+ "other type of error"
+};
+
+static const char *sja1000_ecc_seg_str[]={
+ "?0?",
+ "?1?",
+ "ID.28 to ID.21",
+ "start of frame",
+ "bit SRTR",
+ "bit IDE",
+ "ID.20 to ID.18",
+ "ID.17 to ID.13",
+ "CRC sequence",
+ "reserved bit 0",
+ "data field",
+ "data length code",
+ "bit RTR",
+ "reserved bit 1",
+ "ID.4 to ID.0",
+ "ID.12 to ID.5",
+ "?16?"
+ "active error flag",
+ "intermission",
+ "tolerate dominant bits",
+ "?20?",
+ "?21?",
+ "passive error flag",
+ "error delimiter",
+ "CRC delimiter",
+ "acknowledge slot",
+ "end of frame",
+ "acknowledge delimiter",
+ "overload flag",
+ "?29?",
+ "?30?",
+ "?31?"
+};
+
+#endif /*CONFIG_OC_LINCAN_DETAILED_ERRORS*/
+
+static int sja1000_report_error_limit_counter;
+
+static void sja1000_report_error(struct canchip_t *chip,
+ unsigned sr, unsigned ir, unsigned ecc)
+{
+ if(sja1000_report_error_limit_counter>=100)
+ return;
+
+ CANMSG("Error: status register: 0x%x irq_register: 0x%02x error: 0x%02x\n",
+ sr, ir, ecc);
+
+ sja1000_report_error_limit_counter+=10;
+
+ if(sja1000_report_error_limit_counter>=100){
+ sja1000_report_error_limit_counter+=10;
+ CANMSG("Error: too many errors, reporting disabled\n");
+ return;
+ }
+
+#ifdef CONFIG_OC_LINCAN_DETAILED_ERRORS
+ CANMSG("SR: BS=%c ES=%c TS=%c RS=%c TCS=%c TBS=%c DOS=%c RBS=%c\n",
+ sr&sjaSR_BS?'1':'0',sr&sjaSR_ES?'1':'0',
+ sr&sjaSR_TS?'1':'0',sr&sjaSR_RS?'1':'0',
+ sr&sjaSR_TCS?'1':'0',sr&sjaSR_TBS?'1':'0',
+ sr&sjaSR_DOS?'1':'0',sr&sjaSR_RBS?'1':'0');
+ CANMSG("IR: BEI=%c ALI=%c EPI=%c WUI=%c DOI=%c EI=%c TI=%c RI=%c\n",
+ sr&sjaIR_BEI?'1':'0',sr&sjaIR_ALI?'1':'0',
+ sr&sjaIR_EPI?'1':'0',sr&sjaIR_WUI?'1':'0',
+ sr&sjaIR_DOI?'1':'0',sr&sjaIR_EI?'1':'0',
+ sr&sjaIR_TI?'1':'0',sr&sjaIR_RI?'1':'0');
+ if((sr&sjaIR_EI) || 1){
+ CANMSG("EI: %s %s %s\n",
+ sja1000_ecc_errc_str[(ecc&(sjaECC_ERCC1|sjaECC_ERCC0))/sjaECC_ERCC0],
+ ecc&sjaECC_DIR?"RX":"TX",
+ sja1000_ecc_seg_str[ecc&sjaECC_SEG_M]
+ );
+ }
+#endif /*CONFIG_OC_LINCAN_DETAILED_ERRORS*/
+}
+
+
+/**
+ * sja1000p_enable_configuration - enable chip configuration mode
+ * @chip: pointer to chip state structure
+ */
+int sja1000p_enable_configuration(struct canchip_t *chip)
+{
+ int i=0;
+ enum sja1000_PeliCAN_MOD flags;
+
+ can_disable_irq(chip->chip_irq);
+
+ flags=can_read_reg(chip,SJAMOD);
+
+ while ((!(flags & sjaMOD_RM)) && (i<=10)) {
+ can_write_reg(chip, sjaMOD_RM, SJAMOD);
+// TODO: configurable sjaMOD_AFM (32/16 bit acceptance filter)
+// config sjaMOD_LOM (listen only)
+ udelay(100);
+ i++;
+ flags=can_read_reg(chip, SJAMOD);
+ }
+ if (i>=10) {
+ CANMSG("Reset error\n");
+ can_enable_irq(chip->chip_irq);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+/**
+ * sja1000p_disable_configuration - disable chip configuration mode
+ * @chip: pointer to chip state structure
+ */
+int sja1000p_disable_configuration(struct canchip_t *chip)
+{
+ int i=0;
+ enum sja1000_PeliCAN_MOD flags;
+
+ flags=can_read_reg(chip,SJAMOD);
+
+ while ( (flags & sjaMOD_RM) && (i<=50) ) {
+// could be as long as 11*128 bit times after buss-off
+ can_write_reg(chip, 0, SJAMOD);
+// TODO: configurable sjaMOD_AFM (32/16 bit acceptance filter)
+// config sjaMOD_LOM (listen only)
+ udelay(100);
+ i++;
+ flags=can_read_reg(chip, SJAMOD);
+ }
+ if (i>=10) {
+ CANMSG("Error leaving reset status\n");
+ return -ENODEV;
+ }
+
+ can_enable_irq(chip->chip_irq);
+
+ return 0;
+}
+
+/**
+ * sja1000p_chip_config: - can chip configuration
+ * @chip: pointer to chip state structure
+ *
+ * This function configures chip and prepares it for message
+ * transmission and reception. The function resets chip,
+ * resets mask for acceptance of all messages by call to
+ * sja1000p_extended_mask() function and then
+ * computes and sets baudrate with use of function sja1000p_baud_rate().
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_chip_config(struct canchip_t *chip)
+{
+ int i;
+ unsigned char n, r;
+
+ if (sja1000p_enable_configuration(chip))
+ return -ENODEV;
+
+ /* Set mode, clock out, comparator */
+ can_write_reg(chip,sjaCDR_PELICAN|chip->sja_cdr_reg,SJACDR);
+
+ /* Ensure, that interrupts are disabled even on the chip level now */
+ can_write_reg(chip, sjaDISABLE_INTERRUPTS, SJAIER);
+
+ /* Set driver output configuration */
+ can_write_reg(chip,chip->sja_ocr_reg,SJAOCR);
+
+ /* Simple check for chip presence */
+ for (i=0, n=0x5a; i<8; i++, n+=0xf) {
+ can_write_reg(chip,n,SJAACR0+i);
+ }
+ for (i=0, n=0x5a; i<8; i++, n+=0xf) {
+ r = n^can_read_reg(chip,SJAACR0+i);
+ if (r) {
+ CANMSG("sja1000p_chip_config: chip connection broken,"
+ " readback differ 0x%02x\n", r);
+ return -ENODEV;
+ }
+ }
+
+
+ if (sja1000p_extended_mask(chip,0x00000000, 0xffffffff))
+ return -ENODEV;
+
+ if (!chip->baudrate)
+ chip->baudrate=1000000;
+ if (sja1000p_baud_rate(chip,chip->baudrate,chip->clock,0,75,0))
+ return -ENODEV;
+
+ /* Enable hardware interrupts */
+ can_write_reg(chip, sjaENABLE_INTERRUPTS, SJAIER);
+
+ sja1000p_disable_configuration(chip);
+
+ return 0;
+}
+
+/**
+ * sja1000p_extended_mask: - setup of extended mask for message filtering
+ * @chip: pointer to chip state structure
+ * @code: can message acceptance code
+ * @mask: can message acceptance mask
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_extended_mask(struct canchip_t *chip, unsigned long code, unsigned long mask)
+{
+ int i;
+
+ if (sja1000p_enable_configuration(chip))
+ return -ENODEV;
+
+// LSB to +3, MSB to +0
+ for(i=SJA_PeliCAN_AC_LEN; --i>=0;) {
+ can_write_reg(chip,code&0xff,SJAACR0+i);
+ can_write_reg(chip,mask&0xff,SJAAMR0+i);
+ code >>= 8;
+ mask >>= 8;
+ }
+
+ DEBUGMSG("Setting acceptance code to 0x%lx\n",(unsigned long)code);
+ DEBUGMSG("Setting acceptance mask to 0x%lx\n",(unsigned long)mask);
+
+ sja1000p_disable_configuration(chip);
+
+ return 0;
+}
+
+/**
+ * sja1000p_baud_rate: - set communication parameters.
+ * @chip: pointer to chip state structure
+ * @rate: baud rate in Hz
+ * @clock: frequency of sja1000 clock in Hz (ISA osc is 14318000)
+ * @sjw: synchronization jump width (0-3) prescaled clock cycles
+ * @sampl_pt: sample point in % (0-100) sets (TSEG1+1)/(TSEG1+TSEG2+2) ratio
+ * @flags: fields %BTR1_SAM, %OCMODE, %OCPOL, %OCTP, %OCTN, %CLK_OFF, %CBP
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
+ int sampl_pt, int flags)
+{
+ int best_error = 1000000000, error;
+ int best_tseg=0, best_brp=0, best_rate=0, brp=0;
+ int tseg=0, tseg1=0, tseg2=0;
+
+ if (sja1000p_enable_configuration(chip))
+ return -ENODEV;
+
+ clock /=2;
+
+ /* tseg even = round down, odd = round up */
+ for (tseg=(0+0+2)*2; tseg<=(sjaMAX_TSEG2+sjaMAX_TSEG1+2)*2+1; tseg++) {
+ brp = clock/((1+tseg/2)*rate)+tseg%2;
+ if (brp == 0 || brp > 64)
+ continue;
+ error = rate - clock/(brp*(1+tseg/2));
+ if (error < 0)
+ error = -error;
+ if (error <= best_error) {
+ best_error = error;
+ best_tseg = tseg/2;
+ best_brp = brp-1;
+ best_rate = clock/(brp*(1+tseg/2));
+ }
+ }
+ if (best_error && (rate/best_error < 10)) {
+ CANMSG("baud rate %d is not possible with %d Hz clock\n",
+ rate, 2*clock);
+ CANMSG("%d bps. brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d\n",
+ best_rate, best_brp, best_tseg, tseg1, tseg2);
+ return -EINVAL;
+ }
+ tseg2 = best_tseg-(sampl_pt*(best_tseg+1))/100;
+ if (tseg2 < 0)
+ tseg2 = 0;
+ if (tseg2 > sjaMAX_TSEG2)
+ tseg2 = sjaMAX_TSEG2;
+ tseg1 = best_tseg-tseg2-2;
+ if (tseg1>sjaMAX_TSEG1) {
+ tseg1 = sjaMAX_TSEG1;
+ tseg2 = best_tseg-tseg1-2;
+ }
+
+ DEBUGMSG("Setting %d bps.\n", best_rate);
+ DEBUGMSG("brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d, sampl_pt=%d\n",
+ best_brp, best_tseg, tseg1, tseg2,
+ (100*(best_tseg-tseg2)/(best_tseg+1)));
+
+
+ can_write_reg(chip, sjw<<6 | best_brp, SJABTR0);
+ can_write_reg(chip, ((flags & BTR1_SAM) != 0)<<7 | (tseg2<<4)
+ | tseg1, SJABTR1);
+
+ sja1000p_disable_configuration(chip);
+
+ return 0;
+}
+
+
+/**
+ * sja1000p_set_bittiming: - set bittiming according to already computed parameters.
+ * @chip: pointer to chip state structure
+ * @bpr: baud rate prescaler
+ * @sjw: synchronization jump width in bittime quanta
+ * @tseg1: length of the segment 1 in bittime quanta
+ * @tseg2: length of the segment 2 in bittime quanta
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_set_bittiming(struct canchip_t *chip, int brp, int sjw, int tseg1, int tseg2)
+{
+ uint8_t sam3times = 0; /* 0 = the bus is sampled once */
+
+ if((--brp)<0)
+ return -EINVAL;
+
+ if((--sjw)<0)
+ return -EINVAL;
+
+ if((--tseg1)<0)
+ return -EINVAL;
+
+ if((--tseg2)<0)
+ return -EINVAL;
+
+
+
+ if (sja1000p_enable_configuration(chip))
+ return -ENODEV;
+
+ can_write_reg(chip, sjw<<6 | brp, SJABTR0);
+ can_write_reg(chip, (sam3times<<7) | (tseg2<<4) | tseg1, SJABTR1);
+
+ sja1000p_disable_configuration(chip);
+
+ return 0;
+}
+
+/**
+ * sja1000p_get_bittiming_const: - obtain description of chip bittiming calculation.
+ * @chip: pointer to chip state structure
+ * @btc: pointer to the structure filled by data
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_get_bittiming_const(struct canchip_t *chip, struct can_bittiming_const *btc)
+{
+ btc->tseg1_min = 1;
+ btc->tseg1_max = 16; /* sjaMAX_TSEG1+1 */
+ btc->tseg2_min = 1;
+ btc->tseg2_max = 8; /* sjaMAX_TSEG2+1 */
+ btc->sjw_max = 4;
+ btc->brp_min = 1;
+ btc->brp_max = 64;
+ btc->brp_inc = 1;
+
+ return 0;
+}
+
+
+/**
+ * sja1000p_read: - reads and distributes one or more received messages
+ * @chip: pointer to chip state structure
+ * @obj: pinter to CAN message queue information
+ *
+ * File: src/sja1000p.c
+ */
+void sja1000p_read(struct canchip_t *chip, struct msgobj_t *obj) {
+ int i, flags, len, datastart;
+ do {
+ flags = can_read_reg(chip,SJAFRM);
+ if(flags&sjaFRM_FF) {
+ obj->rx_msg.id =
+ (can_read_reg(chip,SJAID0)<<21) +
+ (can_read_reg(chip,SJAID1)<<13) +
+ (can_read_reg(chip,SJAID2)<<5) +
+ (can_read_reg(chip,SJAID3)>>3);
+ datastart = SJADATE;
+ } else {
+ obj->rx_msg.id =
+ (can_read_reg(chip,SJAID0)<<3) +
+ (can_read_reg(chip,SJAID1)>>5);
+ datastart = SJADATS;
+ }
+ obj->rx_msg.flags =
+ ((flags & sjaFRM_RTR) ? MSG_RTR : 0) |
+ ((flags & sjaFRM_FF) ? MSG_EXT : 0);
+ len = flags & sjaFRM_DLC_M;
+ obj->rx_msg.length = len;
+ if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
+ for(i=0; i< len; i++) {
+ obj->rx_msg.data[i]=can_read_reg(chip,datastart+i);
+ }
+
+ /* fill CAN message timestamp */
+ can_filltimestamp(&obj->rx_msg.timestamp);
+
+ canque_filter_msg2edges(obj->qends, &obj->rx_msg);
+
+ can_write_reg(chip, sjaCMR_RRB, SJACMR);
+
+ } while (can_read_reg(chip, SJASR) & sjaSR_RBS);
+}
+
+/**
+ * sja1000p_pre_read_config: - prepares message object for message reception
+ * @chip: pointer to chip state structure
+ * @obj: pointer to message object state structure
+ *
+ * Return Value: negative value reports error.
+ * Positive value indicates immediate reception of message.
+ * File: src/sja1000p.c
+ */
+int sja1000p_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj)
+{
+ int status;
+ status=can_read_reg(chip,SJASR);
+
+ if(status & sjaSR_BS) {
+ /* Try to recover from error condition */
+ DEBUGMSG("sja1000p_pre_read_config bus-off recover 0x%x\n",status);
+ sja1000p_enable_configuration(chip);
+ can_write_reg(chip, 0, SJARXERR);
+ can_write_reg(chip, 0, SJATXERR1);
+ can_read_reg(chip, SJAECC);
+ sja1000p_disable_configuration(chip);
+ }
+
+ if (!(status&sjaSR_RBS)) {
+ return 0;
+ }
+
+ can_write_reg(chip, sjaDISABLE_INTERRUPTS, SJAIER); //disable interrupts for a moment
+ sja1000p_read(chip, obj);
+ can_write_reg(chip, sjaENABLE_INTERRUPTS, SJAIER); //enable interrupts
+ return 1;
+}
+
+#define MAX_TRANSMIT_WAIT_LOOPS 10
+/**
+ * sja1000p_pre_write_config: - prepares message object for message transmission
+ * @chip: pointer to chip state structure
+ * @obj: pointer to message object state structure
+ * @msg: pointer to CAN message
+ *
+ * This function prepares selected message object for future initiation
+ * of message transmission by sja1000p_send_msg() function.
+ * The CAN message data and message ID are transfered from @msg slot
+ * into chip buffer in this function.
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
+ struct canmsg_t *msg)
+{
+ int i=0;
+ unsigned int id;
+ int status;
+ int len;
+
+ /* Wait until Transmit Buffer Status is released */
+ while ( !((status=can_read_reg(chip, SJASR)) & sjaSR_TBS) &&
+ i++<MAX_TRANSMIT_WAIT_LOOPS) {
+ udelay(i);
+ }
+
+ if(status & sjaSR_BS) {
+ /* Try to recover from error condition */
+ DEBUGMSG("sja1000p_pre_write_config bus-off recover 0x%x\n",status);
+ sja1000p_enable_configuration(chip);
+ can_write_reg(chip, 0, SJARXERR);
+ can_write_reg(chip, 0, SJATXERR1);
+ can_read_reg(chip, SJAECC);
+ sja1000p_disable_configuration(chip);
+ }
+ if (!(can_read_reg(chip, SJASR) & sjaSR_TBS)) {
+ CANMSG("Transmit timed out, cancelling\n");
+// here we should check if there is no write/select waiting for this
+// transmit. If so, set error ret and wake up.
+// CHECKME: if we do not disable sjaIER_TIE (TX IRQ) here we get interrupt
+// immediately
+ can_write_reg(chip, sjaCMR_AT, SJACMR);
+ i=0;
+ while ( !(can_read_reg(chip, SJASR) & sjaSR_TBS) &&
+ i++<MAX_TRANSMIT_WAIT_LOOPS) {
+ udelay(i);
+ }
+ if (!(can_read_reg(chip, SJASR) & sjaSR_TBS)) {
+ CANMSG("Could not cancel, please reset\n");
+ return -EIO;
+ }
+ }
+ len = msg->length;
+ if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
+ /* len &= sjaFRM_DLC_M; ensured by above condition already */
+ can_write_reg(chip, ((msg->flags&MSG_EXT)?sjaFRM_FF:0) |
+ ((msg->flags & MSG_RTR) ? sjaFRM_RTR : 0) | len, SJAFRM);
+ if(msg->flags&MSG_EXT) {
+ id=msg->id<<3;
+ can_write_reg(chip, id & 0xff, SJAID3);
+ id >>= 8;
+ can_write_reg(chip, id & 0xff, SJAID2);
+ id >>= 8;
+ can_write_reg(chip, id & 0xff, SJAID1);
+ id >>= 8;
+ can_write_reg(chip, id, SJAID0);
+ for(i=0; i < len; i++) {
+ can_write_reg(chip, msg->data[i], SJADATE+i);
+ }
+ } else {
+ id=msg->id<<5;
+ can_write_reg(chip, (id >> 8) & 0xff, SJAID0);
+ can_write_reg(chip, id & 0xff, SJAID1);
+ for(i=0; i < len; i++) {
+ can_write_reg(chip, msg->data[i], SJADATS+i);
+ }
+ }
+ return 0;
+}
+
+/**
+ * sja1000p_send_msg: - initiate message transmission
+ * @chip: pointer to chip state structure
+ * @obj: pointer to message object state structure
+ * @msg: pointer to CAN message
+ *
+ * This function is called after sja1000p_pre_write_config() function,
+ * which prepares data in chip buffer.
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
+ struct canmsg_t *msg)
+{
+ can_write_reg(chip, sjaCMR_TR, SJACMR);
+
+ return 0;
+}
+
+/**
+ * sja1000p_check_tx_stat: - checks state of transmission engine
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * Positive return value indicates transmission under way status.
+ * Zero value indicates finishing of all issued transmission requests.
+ * File: src/sja1000p.c
+ */
+int sja1000p_check_tx_stat(struct canchip_t *chip)
+{
+ if (can_read_reg(chip,SJASR) & sjaSR_TCS)
+ return 0;
+ else
+ return 1;
+}
+
+/**
+ * sja1000p_set_btregs: - configures bitrate registers
+ * @chip: pointer to chip state structure
+ * @btr0: bitrate register 0
+ * @btr1: bitrate register 1
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_set_btregs(struct canchip_t *chip, unsigned short btr0,
+ unsigned short btr1)
+{
+ if (sja1000p_enable_configuration(chip))
+ return -ENODEV;
+
+ can_write_reg(chip, btr0, SJABTR0);
+ can_write_reg(chip, btr1, SJABTR1);
+
+ sja1000p_disable_configuration(chip);
+
+ return 0;
+}
+
+/**
+ * sja1000p_start_chip: - starts chip message processing
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_start_chip(struct canchip_t *chip)
+{
+ enum sja1000_PeliCAN_MOD flags;
+
+ flags = can_read_reg(chip, SJAMOD) & (sjaMOD_LOM|sjaMOD_STM|sjaMOD_AFM|sjaMOD_SM);
+ can_write_reg(chip, flags, SJAMOD);
+
+ sja1000_report_error_limit_counter=0;
+
+ return 0;
+}
+
+/**
+ * sja1000p_stop_chip: - stops chip message processing
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_stop_chip(struct canchip_t *chip)
+{
+ enum sja1000_PeliCAN_MOD flags;
+
+ flags = can_read_reg(chip, SJAMOD) & (sjaMOD_LOM|sjaMOD_STM|sjaMOD_AFM|sjaMOD_SM);
+ can_write_reg(chip, flags|sjaMOD_RM, SJAMOD);
+
+ return 0;
+}
+
+/**
+ * sja1000p_attach_to_chip: - attaches to the chip, setups registers and state
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_attach_to_chip(struct canchip_t *chip)
+{
+ return 0;
+}
+
+/**
+ * sja1000p_release_chip: - called before chip structure removal if %CHIP_ATTACHED is set
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_release_chip(struct canchip_t *chip)
+{
+ sja1000p_stop_chip(chip);
+ can_write_reg(chip, sjaDISABLE_INTERRUPTS, SJAIER);
+
+ return 0;
+}
+
+/**
+ * sja1000p_remote_request: - configures message object and asks for RTR message
+ * @chip: pointer to chip state structure
+ * @obj: pointer to message object structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_remote_request(struct canchip_t *chip, struct msgobj_t *obj)
+{
+ CANMSG("sja1000p_remote_request not implemented\n");
+ return -ENOSYS;
+}
+
+/**
+ * sja1000p_standard_mask: - setup of mask for message filtering
+ * @chip: pointer to chip state structure
+ * @code: can message acceptance code
+ * @mask: can message acceptance mask
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_standard_mask(struct canchip_t *chip, unsigned short code,
+ unsigned short mask)
+{
+ CANMSG("sja1000p_standard_mask not implemented\n");
+ return -ENOSYS;
+}
+
+/**
+ * sja1000p_clear_objects: - clears state of all message object residing in chip
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_clear_objects(struct canchip_t *chip)
+{
+ CANMSG("sja1000p_clear_objects not implemented\n");
+ return -ENOSYS;
+}
+
+/**
+ * sja1000p_config_irqs: - tunes chip hardware interrupt delivery
+ * @chip: pointer to chip state structure
+ * @irqs: requested chip IRQ configuration
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_config_irqs(struct canchip_t *chip, short irqs)
+{
+ CANMSG("sja1000p_config_irqs not implemented\n");
+ return -ENOSYS;
+}
+
+/**
+ * sja1000p_irq_write_handler: - part of ISR code responsible for transmit events
+ * @chip: pointer to chip state structure
+ * @obj: pointer to attached queue description
+ *
+ * The main purpose of this function is to read message from attached queues
+ * and transfer message contents into CAN controller chip.
+ * This subroutine is called by
+ * sja1000p_irq_write_handler() for transmit events.
+ * File: src/sja1000p.c
+ */
+void sja1000p_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
+{
+ int cmd;
+
+ if(obj->tx_slot){
+ /* Do local transmitted message distribution if enabled */
+ if (processlocal){
+ /* fill CAN message timestamp */
+ can_filltimestamp(&obj->tx_slot->msg.timestamp);
+
+ obj->tx_slot->msg.flags |= MSG_LOCAL;
+ canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
+ }
+ /* Free transmitted slot */
+ canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
+ obj->tx_slot=NULL;
+ }
+
+ can_msgobj_clear_fl(obj,TX_PENDING);
+ cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
+ if(cmd<0)
+ return;
+ can_msgobj_set_fl(obj,TX_PENDING);
+
+ if (chip->chipspecops->pre_write_config(chip, obj, &obj->tx_slot->msg)) {
+ obj->ret = -1;
+ canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_PREP);
+ canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
+ obj->tx_slot=NULL;
+ return;
+ }
+ if (chip->chipspecops->send_msg(chip, obj, &obj->tx_slot->msg)) {
+ obj->ret = -1;
+ canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_SEND);
+ canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
+ obj->tx_slot=NULL;
+ return;
+ }
+
+}
+
+#define MAX_RETR 10
+
+/**
+ * sja1000p_irq_handler: - interrupt service routine
+ * @irq: interrupt vector number, this value is system specific
+ * @chip: pointer to chip state structure
+ *
+ * Interrupt handler is activated when state of CAN controller chip changes,
+ * there is message to be read or there is more space for new messages or
+ * error occurs. The receive events results in reading of the message from
+ * CAN controller chip and distribution of message through attached
+ * message queues.
+ * File: src/sja1000p.c
+ */
+int sja1000p_irq_handler(int irq, struct canchip_t *chip)
+{
+ int irq_register, status, error_code;
+ struct msgobj_t *obj=chip->msgobj[0];
+ int loop_cnt=CHIP_MAX_IRQLOOP;
+
+ irq_register=can_read_reg(chip,SJAIR);
+// DEBUGMSG("sja1000_irq_handler: SJAIR:%02x\n",irq_register);
+// DEBUGMSG("sja1000_irq_handler: SJASR:%02x\n",
+// can_read_reg(chip,SJASR));
+
+ if ((irq_register & (sjaIR_BEI|sjaIR_EPI|sjaIR_DOI|sjaIR_EI|sjaIR_TI|sjaIR_RI)) == 0)
+ return CANCHIP_IRQ_NONE;
+
+ if(!(chip->flags&CHIP_CONFIGURED)) {
+ CANMSG("sja1000p_irq_handler: called for non-configured device, irq_register 0x%02x\n", irq_register);
+ return CANCHIP_IRQ_NONE;
+ }
+
+ status=can_read_reg(chip,SJASR);
+
+ do {
+
+ if(!loop_cnt--) {
+ CANMSG("sja1000p_irq_handler IRQ %d stuck\n",irq);
+ return CANCHIP_IRQ_STUCK;
+ }
+
+ /* (irq_register & sjaIR_RI) */
+ /* old variant using SJAIR, collides with intended use with irq_accept */
+ if (status & sjaSR_RBS) {
+ DEBUGMSG("sja1000_irq_handler: RI or RBS\n");
+ sja1000p_read(chip,obj);
+ obj->ret = 0;
+ }
+
+ /* (irq_register & sjaIR_TI) */
+ /* old variant using SJAIR, collides with intended use with irq_accept */
+ if (((status & sjaSR_TBS) && can_msgobj_test_fl(obj,TX_PENDING))||
+ (can_msgobj_test_fl(obj,TX_REQUEST))) {
+ DEBUGMSG("sja1000_irq_handler: TI or TX_PENDING and TBS\n");
+ obj->ret = 0;
+ can_msgobj_set_fl(obj,TX_REQUEST);
+ while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
+ can_msgobj_clear_fl(obj,TX_REQUEST);
+
+ if (can_read_reg(chip, SJASR) & sjaSR_TBS)
+ sja1000p_irq_write_handler(chip, obj);
+
+ can_msgobj_clear_fl(obj,TX_LOCK);
+ if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
+ DEBUGMSG("TX looping in sja1000_irq_handler\n");
+ }
+ }
+ if ((irq_register & (sjaIR_EI|sjaIR_BEI|sjaIR_EPI|sjaIR_DOI)) != 0) {
+ // Some error happened
+ error_code=can_read_reg(chip,SJAECC);
+ sja1000_report_error(chip, status, irq_register, error_code);
+// FIXME: chip should be brought to usable state. Transmission cancelled if in progress.
+// Reset flag set to 0 if chip is already off the bus. Full state report
+ obj->ret=-1;
+
+ if(error_code == 0xd9) {
+ obj->ret= -ENXIO;
+ /* no such device or address - no ACK received */
+ }
+ if(obj->tx_retry_cnt++>MAX_RETR) {
+ can_write_reg(chip, sjaCMR_AT, SJACMR); // cancel any transmition
+ obj->tx_retry_cnt = 0;
+ }
+ if(status&sjaSR_BS) {
+ CANMSG("bus-off, resetting sja1000p\n");
+ can_write_reg(chip, 0, SJAMOD);
+ }
+
+ if(obj->tx_slot){
+ canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_BUS);
+ /*canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
+ obj->tx_slot=NULL;*/
+ }
+
+ } else {
+ if(sja1000_report_error_limit_counter)
+ sja1000_report_error_limit_counter--;
+ obj->tx_retry_cnt=0;
+ }
+
+ irq_register=can_read_reg(chip,SJAIR);
+
+ status=can_read_reg(chip,SJASR);
+
+ if(((status & sjaSR_TBS) && can_msgobj_test_fl(obj,TX_PENDING)) ||
+ (irq_register & sjaIR_TI))
+ can_msgobj_set_fl(obj,TX_REQUEST);
+
+ } while((irq_register & (sjaIR_BEI|sjaIR_EPI|sjaIR_DOI|sjaIR_EI|sjaIR_RI)) ||
+ (can_msgobj_test_fl(obj,TX_REQUEST) && !can_msgobj_test_fl(obj,TX_LOCK)) ||
+ (status & sjaSR_RBS));
+
+ return CANCHIP_IRQ_HANDLED;
+}
+
+/**
+ * sja1000p_wakeup_tx: - wakeups TX processing
+ * @chip: pointer to chip state structure
+ * @obj: pointer to message object structure
+ *
+ * Function is responsible for initiating message transmition.
+ * It is responsible for clearing of object TX_REQUEST flag
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
+{
+
+ can_preempt_disable();
+
+ can_msgobj_set_fl(obj,TX_PENDING);
+ can_msgobj_set_fl(obj,TX_REQUEST);
+ while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
+ can_msgobj_clear_fl(obj,TX_REQUEST);
+
+ if (can_read_reg(chip, SJASR) & sjaSR_TBS){
+ obj->tx_retry_cnt=0;
+ sja1000p_irq_write_handler(chip, obj);
+ }
+
+ can_msgobj_clear_fl(obj,TX_LOCK);
+ if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
+ DEBUGMSG("TX looping in sja1000p_wakeup_tx\n");
+ }
+
+ can_preempt_enable();
+ return 0;
+}
+
+int sja1000p_register(struct chipspecops_t *chipspecops)
+{
+ CANMSG("initializing sja1000p chip operations\n");
+ chipspecops->chip_config=sja1000p_chip_config;
+ chipspecops->baud_rate=sja1000p_baud_rate;
+ chipspecops->standard_mask=sja1000p_standard_mask;
+ chipspecops->extended_mask=sja1000p_extended_mask;
+ chipspecops->message15_mask=sja1000p_extended_mask;
+ chipspecops->clear_objects=sja1000p_clear_objects;
+ chipspecops->config_irqs=sja1000p_config_irqs;
+ chipspecops->pre_read_config=sja1000p_pre_read_config;
+ chipspecops->pre_write_config=sja1000p_pre_write_config;
+ chipspecops->send_msg=sja1000p_send_msg;
+ chipspecops->check_tx_stat=sja1000p_check_tx_stat;
+ chipspecops->wakeup_tx=sja1000p_wakeup_tx;
+ chipspecops->remote_request=sja1000p_remote_request;
+ chipspecops->enable_configuration=sja1000p_enable_configuration;
+ chipspecops->disable_configuration=sja1000p_disable_configuration;
+ chipspecops->attach_to_chip=sja1000p_attach_to_chip;
+ chipspecops->release_chip=sja1000p_release_chip;
+ chipspecops->set_btregs=sja1000p_set_btregs;
+ chipspecops->start_chip=sja1000p_start_chip;
+ chipspecops->stop_chip=sja1000p_stop_chip;
+ chipspecops->irq_handler=sja1000p_irq_handler;
+ chipspecops->irq_accept=NULL;
+ chipspecops->set_bittiming=sja1000p_set_bittiming;
+ chipspecops->get_bittiming_const=sja1000p_get_bittiming_const;
+ return 0;
+}
+
+/**
+ * sja1000p_fill_chipspecops - fills chip specific operations
+ * @chip: pointer to chip representation structure
+ *
+ * The function fills chip specific operations for sja1000 (PeliCAN) chip.
+ *
+ * Return Value: returns negative number in the case of fail
+ */
+int sja1000p_fill_chipspecops(struct canchip_t *chip)
+{
+ chip->chip_type="sja1000p";
+ chip->max_objects=1;
+ sja1000p_register(chip->chipspecops);
+ return 0;
+}
--- /dev/null
+/**************************************************************************/
+/* File: sysdep_sysless.c - System-less support routines */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+#include <cpu_def.h>
+#include <system_def.h>
+#include "./can/can.h"
+#include "./can/can_sysdep.h"
+#include "./can/main.h"
+#include "./can/devcommon.h"
+#include "./can/setup.h"
+#include "./can/finish.h"
+
+#ifndef IRQF_SHARED
+#define IRQF_SHARED 0
+#endif /*IRQF_SHARED*/
+
+IRQ_HANDLER_FNC(can_default_irq_dispatch);
+
+/**
+ * can_request_io_region - request IO space region
+ * @start: the first IO port address
+ * @n: number of the consecutive IO port addresses
+ * @name: name/label for the requested region
+ *
+ * The function hides system specific implementation of the feature.
+ *
+ * Return Value: returns positive value (1) in the case, that region could
+ * be reserved for the driver. Returns zero (0) if there is collision with
+ * other driver or region cannot be taken for some other reason.
+ */
+int can_request_io_region(unsigned long start, unsigned long n, const char *name)
+{
+ return 1;
+}
+
+/**
+ * can_release_io_region - release IO space region
+ * @start: the first IO port address
+ * @n: number of the consecutive IO port addresses
+ */
+void can_release_io_region(unsigned long start, unsigned long n)
+{
+}
+
+/**
+ * can_request_mem_region - request memory space region
+ * @start: the first memory port physical address
+ * @n: number of the consecutive memory port addresses
+ * @name: name/label for the requested region
+ *
+ * The function hides system specific implementation of the feature.
+ *
+ * Return Value: returns positive value (1) in the case, that region could
+ * be reserved for the driver. Returns zero (0) if there is collision with
+ * other driver or region cannot be taken for some other reason.
+ */
+int can_request_mem_region(unsigned long start, unsigned long n, const char *name)
+{
+ return 1;
+}
+
+/**
+ * can_release_mem_region - release memory space region
+ * @start: the first memory port physical address
+ * @n: number of the consecutive memory port addresses
+ */
+void can_release_mem_region(unsigned long start, unsigned long n)
+{
+ return;
+}
+
+
+/**
+ * can_default_irq_dispatch - the first level interrupt dispatch handler
+ * @irq: interrupt vector number, this value is system specific
+ * @dev_id: driver private pointer registered at time of request_irq() call.
+ * The CAN driver uses this pointer to store relationship of interrupt
+ * to chip state structure - @struct canchip_t
+ * @regs: system dependent value pointing to registers stored in exception frame
+ *
+ * File: src/setup.c
+ */
+IRQ_HANDLER_FNC(can_default_irq_dispatch)
+{
+ int retval;
+ struct canchip_t *chip;
+
+ chip = (struct canchip_t*)irq_handler_get_context();
+
+ retval=chip->chipspecops->irq_handler(0, chip);
+ return CAN_IRQ_RETVAL(retval);
+}
+
+/**
+ * can_chip_setup_irq - attaches chip to the system interrupt processing
+ * @chip: pointer to CAN chip structure
+ *
+ * Return Value: returns negative number in the case of fail
+ */
+int can_chip_setup_irq(struct canchip_t *chip)
+{
+ if(chip==NULL)
+ return -1;
+ if(!chip->chipspecops->irq_handler)
+ return 0;
+ if(chip->flags & CHIP_IRQ_CUSTOM)
+ return 1;
+
+ if (request_irq(chip->chip_irq,can_default_irq_dispatch,IRQF_SHARED,DEVICE_NAME,chip))
+ return -1;
+ else {
+ DEBUGMSG("Registered interrupt %d\n",chip->chip_irq);
+ chip->flags |= CHIP_IRQ_SETUP;
+ }
+ return 1;
+}
+
+
+/**
+ * can_chip_free_irq - unregisters chip interrupt handler from the system
+ * @chip: pointer to CAN chip structure
+ */
+void can_chip_free_irq(struct canchip_t *chip)
+{
+ if((chip->flags & CHIP_IRQ_SETUP) && (chip->chip_irq>=0)) {
+ if(chip->flags & CHIP_IRQ_CUSTOM)
+ return;
+
+ free_irq(chip->chip_irq, chip);
+ chip->flags &= ~CHIP_IRQ_SETUP;
+ }
+}
+
--- /dev/null
+/**************************************************************************/
+/* File: ul_usb1.c - UL_USB1 board specific part of USB<->CAN converter */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2011 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2008 Jan Kriz email:johen@post.cz */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
+#include "./can/can.h"
+#include "./can/can_sysdep.h"
+#include "./can/main.h"
+#include "./can/devcommon.h"
+#include "./can/setup.h"
+// #include "./can/finish.h"
+#include "./can/i82527.h"
+//#include "../include/sja1000.h"
+#include "./can/sja1000p.h"
+
+#include "./can/errno.h"
+
+#include "./can/ul_usb1.h"
+
+/* Get a minor range for your devices from the usb maintainer */
+#define USB_SKEL_MINOR_BASE 192
+
+#define CAN_OP_MASK 0x80
+#define CAN_OP_READ 0x80
+#define CAN_OP_WRITE 0x00
+
+
+ /* our private defines. if this grows any larger, use your own .h file */
+#define MAX_TRANSFER (PAGE_SIZE - 512)
+/* MAX_TRANSFER is chosen so that the VM is not stressed by
+ allocations > PAGE_SIZE and the number of packets in a page
+ is an integer 512 is the largest possible packet on EHCI */
+#define WRITES_IN_FLIGHT 8
+/* arbitrarily chosen */
+
+/* Define these values to match your devices */
+#define USB_SKEL_VENDOR_ID 0xDEAD
+#define USB_SKEL_PRODUCT_ID 0x1001
+
+
+/*
+ * IO_RANGE is the io-memory range that gets reserved, please adjust according
+ * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
+ * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
+ */
+#define IO_RANGE 0x100
+
+/** ul_usb1_request_io
+ * ul_usb1_request_io: - reserve io or memory range for can board
+ * @candev: pointer to candevice/board which asks for io. Field @io_addr
+ * of @candev is used in most cases to define start of the range
+ *
+ * The function ul_usb1_request_io() is used to reserve the io-memory. If your
+ * hardware uses a dedicated memory range as hardware control registers you
+ * will have to add the code to reserve this memory as well.
+ * %IO_RANGE is the io-memory range that gets reserved, please adjust according
+ * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
+ * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
+ * Return Value: The function returns zero on success or %-ENODEV on failure
+ * File: src/ul_usb1.c
+ */
+int ul_usb1_request_io(struct candevice_t *candev)
+{
+ return 0;
+}
+
+/** ul_usb1_release_io
+ * ul_usb1_release_io - free reserved io memory range
+ * @candev: pointer to candevice/board which releases io
+ *
+ * The function ul_usb1_release_io() is used to free reserved io-memory.
+ * In case you have reserved more io memory, don't forget to free it here.
+ * IO_RANGE is the io-memory range that gets released, please adjust according
+ * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
+ * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
+ * Return Value: The function always returns zero
+ * File: src/ul_usb1.c
+ */
+int ul_usb1_release_io(struct candevice_t *candev)
+{
+ return 0;
+}
+
+/** ul_usb1_reset
+ * ul_usb1_reset - hardware reset routine
+ * @candev: Pointer to candevice/board structure
+ *
+ * The function ul_usb1_reset() is used to give a hardware reset. This is
+ * rather hardware specific so I haven't included example code. Don't forget to
+ * check the reset status of the chip before returning.
+ * Return Value: The function returns zero on success or %-ENODEV on failure
+ * File: src/ul_usb1.c
+ */
+int ul_usb1_reset(struct candevice_t *candev)
+{
+ return can_init();
+}
+
+#define RESET_ADDR 0x0
+#define NR_82527 0
+#define NR_SJA1000 1
+
+/** ul_usb1_init_hw_data
+ * ul_usb1_init_hw_data - Initialize hardware cards
+ * @candev: Pointer to candevice/board structure
+ *
+ * The function ul_usb1_init_hw_data() is used to initialize the hardware
+ * structure containing information about the installed CAN-board.
+ * %RESET_ADDR represents the io-address of the hardware reset register.
+ * %NR_82527 represents the number of Intel 82527 chips on the board.
+ * %NR_SJA1000 represents the number of Philips sja1000 chips on the board.
+ * The flags entry can currently only be %CANDEV_PROGRAMMABLE_IRQ to indicate that
+ * the hardware uses programmable interrupts.
+ * Return Value: The function always returns zero
+ * File: src/ul_usb1.c
+ */
+int ul_usb1_init_hw_data(struct candevice_t *candev)
+{
+ candev->res_addr=RESET_ADDR;
+ candev->nr_82527_chips=NR_82527;
+ candev->nr_sja1000_chips=NR_SJA1000;
+ candev->nr_all_chips=NR_82527+NR_SJA1000;
+ candev->flags |= CANDEV_PROGRAMMABLE_IRQ*0;
+
+ return 0;
+}
+
+/** ul_usb1_init_chip_data
+ * ul_usb1_init_chip_data - Initialize chips
+ * @candev: Pointer to candevice/board structure
+ * @chipnr: Number of the CAN chip on the hardware card
+ *
+ * The function ul_usb1_init_chip_data() is used to initialize the hardware
+ * structure containing information about the CAN chips.
+ * %CHIP_TYPE represents the type of CAN chip. %CHIP_TYPE can be "i82527" or
+ * "sja1000".
+ * The @chip_base_addr entry represents the start of the 'official' memory map
+ * of the installed chip. It's likely that this is the same as the @io_addr
+ * argument supplied at module loading time.
+ * The @clock entry holds the chip clock value in Hz.
+ * The entry @sja_cdr_reg holds hardware specific options for the Clock Divider
+ * register. Options defined in the %sja1000.h file:
+ * %sjaCDR_CLKOUT_MASK, %sjaCDR_CLK_OFF, %sjaCDR_RXINPEN, %sjaCDR_CBP, %sjaCDR_PELICAN
+ * The entry @sja_ocr_reg holds hardware specific options for the Output Control
+ * register. Options defined in the %sja1000.h file:
+ * %sjaOCR_MODE_BIPHASE, %sjaOCR_MODE_TEST, %sjaOCR_MODE_NORMAL, %sjaOCR_MODE_CLOCK,
+ * %sjaOCR_TX0_LH, %sjaOCR_TX1_ZZ.
+ * The entry @int_clk_reg holds hardware specific options for the Clock Out
+ * register. Options defined in the %i82527.h file:
+ * %iCLK_CD0, %iCLK_CD1, %iCLK_CD2, %iCLK_CD3, %iCLK_SL0, %iCLK_SL1.
+ * The entry @int_bus_reg holds hardware specific options for the Bus
+ * Configuration register. Options defined in the %i82527.h file:
+ * %iBUS_DR0, %iBUS_DR1, %iBUS_DT1, %iBUS_POL, %iBUS_CBY.
+ * The entry @int_cpu_reg holds hardware specific options for the cpu interface
+ * register. Options defined in the %i82527.h file:
+ * %iCPU_CEN, %iCPU_MUX, %iCPU_SLP, %iCPU_PWD, %iCPU_DMC, %iCPU_DSC, %iCPU_RST.
+ * Return Value: The function always returns zero
+ * File: src/ul_usb1.c
+ */
+int ul_usb1_init_chip_data(struct candevice_t *candev, int chipnr)
+{
+ /*i82527_fill_chipspecops(candev->chip[chipnr]);*/
+ /*sja1000_fill_chipspecops(candev->chip[chipnr]);*/
+ sja1000p_fill_chipspecops(candev->chip[chipnr]);
+
+ candev->chip[chipnr]->flags|= CHIP_IRQ_CUSTOM;
+
+ candev->chip[chipnr]->chip_base_addr=0;
+ candev->chip[chipnr]->clock = 24000000;
+ candev->chip[chipnr]->int_cpu_reg = iCPU_DSC;
+ candev->chip[chipnr]->int_clk_reg = iCLK_SL1;
+ candev->chip[chipnr]->int_bus_reg = iBUS_CBY;
+ candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF;
+ candev->chip[chipnr]->sja_ocr_reg = sjaOCR_MODE_NORMAL |
+ sjaOCR_TX0_LH;
+
+ candev->chip[chipnr]->chip_data=(void *)malloc(sizeof(struct ul_usb1_chip_data));
+ if (candev->chip[chipnr]->chip_data==NULL)
+ return -ENOMEM;
+ return 0;
+}
+
+/** ul_usb1_init_obj_data
+ * ul_usb1_init_obj_data - Initialize message buffers
+ * @chip: Pointer to chip specific structure
+ * @objnr: Number of the message buffer
+ *
+ * The function ul_usb1_init_obj_data() is used to initialize the hardware
+ * structure containing information about the different message objects on the
+ * CAN chip. In case of the sja1000 there's only one message object but on the
+ * i82527 chip there are 15.
+ * The code below is for a i82527 chip and initializes the object base addresses
+ * The entry @obj_base_addr represents the first memory address of the message
+ * object. In case of the sja1000 @obj_base_addr is taken the same as the chips
+ * base address.
+ * Unless the hardware uses a segmented memory map, flags can be set zero.
+ * Return Value: The function always returns zero
+ * File: src/ul_usb1.c
+ */
+int ul_usb1_init_obj_data(struct canchip_t *chip, int objnr)
+{
+ chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr+(objnr+1)*0x10;
+
+ return 0;
+}
+
+/** ul_usb1_program_irq
+ * ul_usb1_program_irq - program interrupts
+ * @candev: Pointer to candevice/board structure
+ *
+ * The function ul_usb1_program_irq() is used for hardware that uses
+ * programmable interrupts. If your hardware doesn't use programmable interrupts
+ * you should not set the @candevices_t->flags entry to %CANDEV_PROGRAMMABLE_IRQ and
+ * leave this function unedited. Again this function is hardware specific so
+ * there's no example code.
+ * Return value: The function returns zero on success or %-ENODEV on failure
+ * File: src/ul_usb1.c
+ */
+int ul_usb1_program_irq(struct candevice_t *candev)
+{
+ return 0;
+}
+
+/** ul_usb1_write_register
+ * ul_usb1_write_register - Low level write register routine
+ * @data: data to be written
+ * @address: memory address to write to
+ *
+ * The function ul_usb1_write_register() is used to write to hardware registers
+ * on the CAN chip. You should only have to edit this function if your hardware
+ * uses some specific write process.
+ * Return Value: The function does not return a value
+ * File: src/ul_usb1.c
+ */
+void ul_usb1_write_register(unsigned data, unsigned long address)
+{
+ can_write(data, address & 0xFF);
+}
+
+/** ul_usb1_read_register
+ * ul_usb1_read_register - Low level read register routine
+ * @address: memory address to read from
+ *
+ * The function ul_usb1_read_register() is used to read from hardware registers
+ * on the CAN chip. You should only have to edit this function if your hardware
+ * uses some specific read process.
+ * Return Value: The function returns the value stored in @address
+ * File: src/ul_usb1.c
+ */
+unsigned ul_usb1_read_register(unsigned long address)
+{
+ uint8_t data;
+ data = can_read(address & 0xFF);
+ return data;
+}
+
+/* !!! Don't change this function !!! */
+int ul_usb1_register(struct hwspecops_t *hwspecops)
+{
+ hwspecops->request_io = ul_usb1_request_io;
+ hwspecops->release_io = ul_usb1_release_io;
+ hwspecops->reset = ul_usb1_reset;
+ hwspecops->init_hw_data = ul_usb1_init_hw_data;
+ hwspecops->init_chip_data = ul_usb1_init_chip_data;
+ hwspecops->init_obj_data = ul_usb1_init_obj_data;
+ hwspecops->write_register = ul_usb1_write_register;
+ hwspecops->read_register = ul_usb1_read_register;
+ hwspecops->program_irq = ul_usb1_program_irq;
+ return 0;
+}
+
--- /dev/null
+
+#ifndef USB_DEFS_MODULE
+ #define USB_DEFS_MODULE
+
+ #include <usb/usb_spec.h>
+// #include <usb/pdiusb.h>
+ #include <usb/lpcusb.h>
+ #include <endian.h>
+ #include <cpu_def.h>
+
+ #include <endian.h>
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ #include <byteswap.h>
+ #define SWAP(x) ((((x) & 0xFF) << 8) | (((x) >> 8) & 0xFF))
+ #else /*__LITTLE_ENDIAN*/
+ #define SWAP(x) (x)
+ #endif
+
+ #ifndef CODE
+ #define CODE
+ #endif
+
+ #ifdef USB_MAX_PACKET
+ #undef USB_MAX_PACKET
+ #endif
+ #define USB_MAX_PACKET 16
+
+/*****************************************************/
+/*** Static data structures for device descriptors ***/
+/*****************************************************/
+#ifndef USB_VENDOR_ID
+ #define USB_VENDOR_ID 0x1669 /* PiKRON.com registered number */
+#endif
+#ifndef USB_PRODUCT_ID
+ #define USB_PRODUCT_ID 0x1011 /* test code for ULAD21 */
+#endif
+ #define USB_RELEASE_VER 0x0010
+
+/*** Class codes for device description ***/
+ #define USB_CLASS_CODE 0xFF
+ #define USB_SUBCLASS_CODE 0x00
+ #define USB_PROTOCOL_CODE 0x00
+
+
+ #define NUM_ENDPOINTS 2
+ #define CONFIG_DESCRIPTOR_LENGTH sizeof( USB_CONFIGURATION_DESCRIPTOR) \
+ + sizeof( USB_INTERFACE_DESCRIPTOR) \
+ + ( NUM_ENDPOINTS * sizeof( USB_ENDPOINT_DESCRIPTOR))
+
+/*** Device descriptor ***/
+ CODE const USB_DEVICE_DESCRIPTOR DeviceDescription = {
+ sizeof( USB_DEVICE_DESCRIPTOR),
+ USB_DESCRIPTOR_TYPE_DEVICE,
+ SWAP( 0x0100),
+ USB_CLASS_CODE,
+ USB_SUBCLASS_CODE,
+ USB_PROTOCOL_CODE,
+ USB_MAX_PACKET0,
+ SWAP( USB_VENDOR_ID),
+ SWAP( USB_PRODUCT_ID),
+ SWAP( USB_RELEASE_VER),
+ 1, /* manufacturer string ID */
+ 2, /* product string ID */
+ 3, /* serial number string ID */
+ 1
+ };
+
+/*** All In Configuration 0 ***/
+ CODE const struct {
+ USB_CONFIGURATION_DESCRIPTOR configuration;
+ USB_INTERFACE_DESCRIPTOR interface;
+ USB_ENDPOINT_DESCRIPTOR endpoint_tx;
+ USB_ENDPOINT_DESCRIPTOR endpoint_rx;
+ } ConfigDescription = {
+ /*** Configuration descriptor ***/
+ {
+ sizeof( USB_CONFIGURATION_DESCRIPTOR),
+ USB_DESCRIPTOR_TYPE_CONFIGURATION,
+ SWAP( CONFIG_DESCRIPTOR_LENGTH),
+ 1, /* cnt of interfaces */
+ 1, /* this configuration ID */
+ 4, /* config.name string ID*/
+ 0x80, /* cfg, in spec is, taha bit 7 must be set to one -> 0xe0 , orig 0x60*/
+ 0x32 /* device power current from host 100mA */
+ },
+ /*** Interface Descriptor ***/
+ {
+ sizeof( USB_INTERFACE_DESCRIPTOR),
+ USB_DESCRIPTOR_TYPE_INTERFACE,
+ 0, /* index of this interface for SetInterface request */
+ 0, /* ID alternate interface */
+ NUM_ENDPOINTS,
+ USB_CLASS_CODE,
+ USB_SUBCLASS_CODE,
+ USB_PROTOCOL_CODE,
+ 5
+ },
+ /*** Endpoint 1 - Tx,Bulk ***/
+ {
+ sizeof( USB_ENDPOINT_DESCRIPTOR),
+ USB_DESCRIPTOR_TYPE_ENDPOINT,
+ 0x01,
+ USB_ENDPOINT_TYPE_BULK,
+ SWAP( USB_MAX_PACKET),
+ 0
+ },
+ /*** Endpoint 1 - Rx,Bulk ***/
+ {
+ sizeof( USB_ENDPOINT_DESCRIPTOR),
+ USB_DESCRIPTOR_TYPE_ENDPOINT,
+ 0x81,
+ USB_ENDPOINT_TYPE_BULK,
+ SWAP( USB_MAX_PACKET),
+ 0
+ }
+ };
+ /*** Strings - in unicode ***/
+ CODE const char Str0Desc[] = { /* supported languages of strings */
+ 4, 0x03, /* 2+2*N , N is count of supported languages */
+ 0x09,0x04 /* english 0x0409 */
+ };
+
+ CODE const char Str1Desc[] = { /* 1 = manufacturer */
+ 44,0x03,
+ 'K',0,
+ 'r',0,
+ 'i',0,
+ 'z',0,
+ ',',0,
+ 'B',0,
+ 'a',0,
+ 'r',0,
+ 't',0,
+ 'o',0,
+ 's',0,
+ 'i',0,
+ 'n',0,
+ 's',0,
+ 'k',0,
+ 'i',0,
+ ',',0,
+ 'P',0,
+ 'i',0,
+ 's',0,
+ 'a',0
+ };
+
+ CODE const char Str2Desc[] = { /* 2 = product */
+ 42, 0x03,
+ 'C',0,
+ 'A',0,
+ 'N',0,
+ ' ',0,
+ 't',0,
+ 'o',0,
+ ' ',0,
+ 'U',0,
+ 'S',0,
+ 'B',0,
+ ' ',0,
+ 'c',0,
+ 'o',0,
+ 'n',0,
+ 'v',0,
+ 'e',0,
+ 'r',0,
+ 't',0,
+ 'o',0,
+ 'r',0
+ };
+
+
+ CODE const char Str3Desc[] = { /* 3 = version */
+ 26, 0x03,
+ '1',0,
+ '.',0,
+ '1',0,
+ ' ',0,
+ '0',0,
+ '8',0,
+ '-',0,
+ '1',0,
+ '1',0,
+ '-',0,
+ '2',0,
+ '3',0
+ };
+ CODE const char Str4Desc[] = { /* 4 = configuration */
+ 34, 0x03,
+ 'C',0,
+ 'o',0,
+ 'n',0,
+ 'f',0,
+ 'i',0,
+ 'g',0,
+ 'u',0,
+ 'r',0,
+ 'a',0,
+ 't',0,
+ 'i',0,
+ 'o',0,
+ 'n',0,
+ ' ',0,
+ '#',0,
+ '1',0
+ };
+ CODE const char Str5Desc[] = { /* 5 = interface */
+ 38,0x03,
+ 'I',0,
+ 'n',0,
+ 't',0,
+ 'e',0,
+ 'r',0,
+ 'f',0,
+ 'a',0,
+ 'c',0,
+ 'e',0,
+ ' ',0,
+ '#',0,
+ '0',0,
+ ' ',0,
+ '-',0,
+ ' ',0,
+ 'C',0,
+ 'A',0,
+ 'N',0
+ };
+
+ CODE const char Str6Desc[] = { /* EP1 OUT descriptor */
+ 48,0x03,
+ 'E',0,
+ 'P',0,
+ '1',0,
+ 'O',0,
+ 'U',0,
+ 'T',0,
+ '-',0,
+ 's',0,
+ 'e',0,
+ 'n',0,
+ 'd',0,
+ ' ',0,
+ 'C',0,
+ 'A',0,
+ 'N',0,
+ ' ',0,
+ 'm',0,
+ 'e',0,
+ 's',0,
+ 's',0,
+ 'a',0,
+ 'g',0,
+ 'e',0
+ };
+
+ CODE const char Str7Desc[] = { /* EP1 IN descriptor */
+ 52,0x03,
+ 'E',0,
+ 'P',0,
+ '1',0,
+ 'I',0,
+ 'N',0,
+ '-',0,
+ 'r',0,
+ 'e',0,
+ 'c',0,
+ 'e',0,
+ 'i',0,
+ 'v',0,
+ 'e',0,
+ ' ',0,
+ 'C',0,
+ 'A',0,
+ 'N',0,
+ ' ',0,
+ 'm',0,
+ 'e',0,
+ 's',0,
+ 's',0,
+ 'a',0,
+ 'g',0,
+ 'e',0
+ };
+
+ /* all strings in pointers array */
+ CODE const PUSB_STRING_DESCRIPTOR StringDescriptors[] = {
+ (PUSB_STRING_DESCRIPTOR) Str0Desc,
+ (PUSB_STRING_DESCRIPTOR) Str1Desc,
+ (PUSB_STRING_DESCRIPTOR) Str2Desc,
+ (PUSB_STRING_DESCRIPTOR) Str3Desc,
+ (PUSB_STRING_DESCRIPTOR) Str4Desc,
+ (PUSB_STRING_DESCRIPTOR) Str5Desc,
+ (PUSB_STRING_DESCRIPTOR) Str6Desc,
+ (PUSB_STRING_DESCRIPTOR) Str7Desc,
+ };
+
+ #define CNT_STRINGS (sizeof(StringDescriptors)/sizeof(StringDescriptors[0]))
+
+ CODE const USB_DEVICE_CONFIGURATION_ENTRY usb_devdes_configurations[] = {
+ {
+ .pConfigDescription = &ConfigDescription.configuration,
+ .iConfigTotalLength = CONFIG_DESCRIPTOR_LENGTH
+ }
+ };
+
+ CODE const USB_INTERFACE_DESCRIPTOR *usb_devdes_interfaces[] = {
+ &ConfigDescription.interface
+ };
+
+ CODE const USB_DEVICE_DESCRIPTORS_TABLE usb_devdes_table = {
+ .pDeviceDescription = &DeviceDescription,
+ .pConfigurations = usb_devdes_configurations,
+ .pInterfaceDescriptors = usb_devdes_interfaces,
+ .pStrings = StringDescriptors,
+ .iNumStrings = CNT_STRINGS,
+ .bNumEndpoints = NUM_ENDPOINTS,
+ .bNumConfigurations = 1,
+ .bNumInterfaces = 1
+ };
+
+#endif /* USB_DEFS_MODULE */
--- /dev/null
+#ifndef USBCAN_VENDOR
+#define USBCAN_VENDOR
+
+#include <usb/usb.h>
+
+#define USBCAN_VENDOR_BAUD_RATE_SET (1)
+#define USBCAN_VENDOR_BAUD_RATE_STATUS (2)
+#define USBCAN_VENDOR_SET_BTREGS (3)
+#define USBCAN_VENDOR_CHECK_TX_STAT (4)
+#define USBCAN_VENDOR_START_CHIP (5)
+#define USBCAN_VENDOR_STOP_CHIP (6)
+#define USBCAN_VENDOR_EXT_MASK_SET (7)
+#define USBCAN_VENDOR_EXT_MASK_STATUS (8)
+
+#define USBCAN_VENDOR_SET_BITTIMING (9)
+#define USBCAN_VENDOR_GET_BITTIMING_CONST (10)
+
+#define USBCAN_BITTIMING_SIZE 16
+#define USBCAN_BITTIMING_CONST_SIZE 36
+
+int usbcan_vendor(usb_device_t *udev);
+
+int set_ext_mask_complete_fnc(struct usb_ep_t *ep, int status);
+
+#endif /* USBCAN_VENDOR */
--- /dev/null
+// #define CAN_DEBUG
+
+#include <stdio.h>
+#include <system_def.h>
+//#include <hal_intr.h>
+#include "./can/can.h"
+#include "./can/can_sysdep.h"
+#include "./can/main.h"
+#include "./can/devcommon.h"
+#include "./usb/usb_vend.h"
+#include "./can/ul_usb1.h"
+#include <endian.h>
+#if __BYTE_ORDER == __BIG_ENDIAN
+ #include <byteswap.h>
+#endif
+
+#include "./can/can_bittiming.h"
+
+extern struct canuser_t *canuser;
+extern uint8_t vendor_ret;
+
+int set_ext_mask_complete_fnc(struct usb_ep_t *ep, int status){
+ int dest_chip;
+
+ unsigned long code;
+ unsigned long mask;
+
+ struct ul_usb1_chip_data *chip_data=NULL;
+
+ usb_device_t *udev=ep->udev;
+ unsigned char *data=ep->ptr - ep->actual;
+
+ if (udev->request.bRequest==USBCAN_VENDOR_EXT_MASK_SET){
+ dest_chip=(udev->request.wIndex);
+ if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
+ goto error;
+ if (!chips_p[dest_chip])
+ goto error;
+ if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
+ goto nodata;
+
+ mask=*(uint32_t *)(data);
+ code=*(uint32_t *)(data+4);
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ mask = bswap_32( mask);
+ code = bswap_32( code);
+ #endif
+
+
+ if (chips_p[dest_chip]->chipspecops->extended_mask(chips_p[dest_chip], code, mask)<0)
+ goto error;
+ chip_data->flags |= UL_USB1_CHIP_MASK_SET;
+ }
+ return 0;
+error:
+ chip_data->flags &= ~UL_USB1_CHIP_MASK_SET;
+nodata:
+ return -1;
+}
+
+int set_baud_rate_complete_fnc(struct usb_ep_t *ep, int status){
+ int dest_chip;
+
+ int32_t rate,sjw,sampl_pt,flags;
+
+ struct ul_usb1_chip_data *chip_data=NULL;
+
+ usb_device_t *udev=ep->udev;
+ unsigned char *data=ep->ptr - ep->actual;
+
+ if (udev->request.bRequest==USBCAN_VENDOR_BAUD_RATE_SET){
+ dest_chip=(udev->request.wIndex);
+ if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
+ goto error;
+ if (!chips_p[dest_chip])
+ goto error;
+ if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
+ goto nodata;
+
+ rate=*(int32_t *)(data);
+ sjw=*(int32_t *)(data+4);
+ sampl_pt=*(int32_t *)(data+8);
+ flags=*(int32_t *)(data+12);
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ rate = bswap_32( rate);
+ sjw = bswap_32( sjw);
+ sampl_pt = bswap_32( sampl_pt);
+ flags = bswap_32( flags);
+ #endif
+
+ if (chips_p[dest_chip]->chipspecops->baud_rate(chips_p[dest_chip], rate, chips_p[dest_chip]->clock, sjw, sampl_pt, flags)<0)
+ goto error;
+ chip_data->flags |= UL_USB1_CHIP_BAUD_SET;
+ }
+ return 0;
+error:
+ chip_data->flags &= ~UL_USB1_CHIP_BAUD_SET;
+nodata:
+ return -1;
+}
+
+
+
+int set_bittiming_complete_fnc(struct usb_ep_t *ep, int status){
+ int dest_chip;
+
+ int32_t brp, sjw, tseg1, tseg2;
+
+ usb_device_t *udev=ep->udev;
+ unsigned char *data=ep->ptr - ep->actual;
+
+ if(ep->actual != USBCAN_BITTIMING_SIZE)
+ goto error;
+
+ if (udev->request.bRequest==USBCAN_VENDOR_SET_BITTIMING){
+ dest_chip=(udev->request.wIndex);
+ if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
+ goto error;
+ if (!chips_p[dest_chip])
+ goto error;
+
+ brp=*(int32_t *)(data);
+ sjw=*(int32_t *)(data+4);
+ tseg1=*(int32_t *)(data+8);
+ tseg2=*(int32_t *)(data+12);
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ brp = bswap_32(brp);
+ sjw = bswap_32(sjw);
+ tseg1 = bswap_32(tseg1);
+ tseg2 = bswap_32(tseg2);
+ #endif
+
+
+ if (chips_p[dest_chip]->chipspecops->set_bittiming(chips_p[dest_chip], brp, sjw, tseg1, tseg2)<0)
+ goto error;
+ }
+ return 0;
+
+error:
+ return -1;
+}
+
+int usbcan_get_bittiming_const_reply(usb_device_t *udev){
+ int dest_chip;
+ struct canchip_t *chip;
+
+ struct can_bittiming_const btc_buff;
+ struct can_bittiming_const *btc = &btc_buff;
+
+ uint8_t buffer[USBCAN_BITTIMING_CONST_SIZE];
+ uint32_t *ptr;
+
+ if (udev->request.bRequest==USBCAN_VENDOR_GET_BITTIMING_CONST){
+
+ dest_chip=(udev->request.wIndex);
+ if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
+ goto error;
+ if ((chip = chips_p[dest_chip]) == NULL)
+ goto error;
+ if (chip->chipspecops->get_bittiming_const == NULL){
+ goto error;
+ }
+
+ chip->chipspecops->get_bittiming_const(chip, btc);
+ ptr = (uint32_t*) buffer;
+
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ *(ptr++) = bswap_32(chips_p[dest_chip]->clock);
+ *(ptr++) = bswap_32(btc->tseg1_min);
+ *(ptr++) = bswap_32(btc->tseg1_max);
+ *(ptr++) = bswap_32(btc->tseg2_min);
+ *(ptr++) = bswap_32(btc->tseg2_max);
+ *(ptr++) = bswap_32(btc->sjw_max);
+ *(ptr++) = bswap_32(btc->brp_min);
+ *(ptr++) = bswap_32(btc->brp_max);
+ *(ptr) = bswap_32(btc->brp_inc);
+ #else
+ *(ptr++) = chips_p[dest_chip]->clock;
+ *(ptr++) = btc->tseg1_min;
+ *(ptr++) = btc->tseg1_max;
+ *(ptr++) = btc->tseg2_min;
+ *(ptr++) = btc->tseg2_max;
+ *(ptr++) = btc->sjw_max;
+ *(ptr++) = btc->brp_min;
+ *(ptr++) = btc->brp_max;
+ *(ptr) = btc->brp_inc;
+ #endif
+
+ usb_send_control_data(udev, buffer, USBCAN_BITTIMING_CONST_SIZE);
+
+
+ }
+ return 0;
+
+error:
+ return -1;
+}
+
+int usbcan_vendor(usb_device_t *udev)
+{
+ // wIndex, wValue, bRequest, wLength
+ int dest_chip;
+ struct ul_usb1_chip_data *chip_data;
+
+ dest_chip=(udev->request.wIndex);
+ if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
+ return -1; // Should look like ok (0) or stall (-1)?
+ if (!chips_p[dest_chip])
+ return -1; // Should look like ok (0) or stall (-1)?
+
+ switch ( udev->request.bRequest) {
+
+ //lpc17xx
+ case USBCAN_VENDOR_SET_BITTIMING:
+ udev->ep0.complete_fnc=set_bittiming_complete_fnc;
+ return 1;
+
+ case USBCAN_VENDOR_GET_BITTIMING_CONST:
+ usbcan_get_bittiming_const_reply(udev);
+ return 1;
+ //lpc17xx - end
+
+ case USBCAN_VENDOR_EXT_MASK_SET:
+ udev->ep0.complete_fnc=set_ext_mask_complete_fnc;
+ return 1;
+ case USBCAN_VENDOR_EXT_MASK_STATUS:
+ vendor_ret=-1;
+ if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
+ usb_send_control_data(udev,&vendor_ret,1);
+ else{
+ vendor_ret=(chip_data->flags & UL_USB1_CHIP_MASK_SET)?1:0;
+ usb_send_control_data(udev,&vendor_ret,1);
+ }
+ chip_data->flags &= ~UL_USB1_CHIP_MASK_SET;
+ return 1;
+
+ case USBCAN_VENDOR_BAUD_RATE_SET:
+ udev->ep0.complete_fnc=set_baud_rate_complete_fnc;
+ return 1;
+ case USBCAN_VENDOR_BAUD_RATE_STATUS:
+ vendor_ret=-1;
+ if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
+ usb_send_control_data(udev,&vendor_ret,1);
+ else{
+ vendor_ret=(chip_data->flags & UL_USB1_CHIP_BAUD_SET)?1:0;
+ usb_send_control_data(udev,&vendor_ret,1);
+ }
+ chip_data->flags &= ~UL_USB1_CHIP_BAUD_SET;
+ return 1;
+
+ case USBCAN_VENDOR_SET_BTREGS:
+ {
+ uint16_t value=udev->request.wValue;
+ vendor_ret=1;
+ if (chips_p[dest_chip]->chipspecops->set_btregs(chips_p[dest_chip],value&0xFF,(value>>8)&0xFF)<0)
+ vendor_ret=0;
+ usb_send_control_data(udev,&vendor_ret,1);
+ }
+ return 1;
+
+ case USBCAN_VENDOR_CHECK_TX_STAT:
+ {
+ struct canque_edge_t *qedge;
+ struct canque_slot_t *slot;
+ vendor_ret=0;
+ if (canque_get_inslot(canuser->qends, &qedge, &slot, 0)>=0){
+ canque_abort_inslot(canuser->qends, qedge, slot);
+ DEBUGMSG("USBCAN_VENDOR_CHECK_TX_STAT - Free slot found\r\n");
+ vendor_ret=1;
+ }
+ DEBUGMSG("USBCAN_VENDOR_CHECK_TX_STAT - Sending %d\r\n",vendor_ret);
+ usb_send_control_data(udev,&vendor_ret,1);
+ return 1;
+ }
+
+ case USBCAN_VENDOR_START_CHIP:
+ vendor_ret=1;
+ if (chips_p[dest_chip]->chipspecops->start_chip(chips_p[dest_chip])<0)
+ vendor_ret=0;
+ usb_send_control_data(udev,&vendor_ret,1);
+ return 1;
+ case USBCAN_VENDOR_STOP_CHIP:
+ vendor_ret=1;
+ if (chips_p[dest_chip]->chipspecops->stop_chip(chips_p[dest_chip])<0)
+ vendor_ret=0;
+ usb_send_control_data(udev,&vendor_ret,1);
+ return 1;
+ }
+
+ return 0;
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+SUBDIRS = generic $(ARCH)
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+SUBDIRS = generic mach-$(MACH)
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+SUBDIRS = defines libs
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+#include_HEADERS = $(notdir $(wildcard $(SOURCES_DIR)/*.h))
+
+include_HEADERS = cpu_def.h hal_intr.h types.h bbconf_info.h
--- /dev/null
+#ifndef _BBCONF_INFO_H_
+#define _BBCONF_INFO_H_
+
+#if 1 /* Provide FLASH start directly */
+
+/*FIXME: should not be provided directly*/
+#ifndef BBCONF_FLASH_START
+#define BBCONF_FLASH_START 0x00000000
+#endif
+
+#else /* FLASH start taken from ldscript */
+
+#ifndef __ASSEMBLY__
+extern char __flash_base;
+#define BBCONF_FLASH_START ((unsigned long)(&__flash_base))
+#else /*__ASSEMBLY__*/
+.global __flash_base
+#define BBCONF_FLASH_START __flash_base
+#endif /*__ASSEMBLY__*/
+
+#endif /* decission about flash start */
+
+#define BBCONF_MAGIC_VAL 0xd1ab46d6
+
+#define BBCONF_MAGIC_ADDR (BBCONF_FLASH_START+0x40)
+#define BBCONF_PTPTR_ADDR (BBCONF_FLASH_START+0x44)
+
+#define BBCONF_PTTAG_END 0x00
+#define BBCONF_PTTAG_BBVER 0x01
+#define BBCONF_PTTAG_KVPB_START 0x12
+#define BBCONF_PTTAG_KVPB_BYCFI 0x13
+#define BBCONF_PTTAG_KVPB_SIZE 0x14
+#define BBCONF_PTTAG_WITH_BATPACK 0x15
+
+#define BBCONF_PT_MAX_CNT 0x80
+
+
+#ifndef __ASSEMBLY__
+
+int bbconf_get_param(unsigned long tag, unsigned long *pval);
+
+#endif /*__ASSEMBLY__*/
+
+#endif /*_BBCONF_INFO_H_*/
--- /dev/null
+#ifndef _ARM_CPU_DEF_H
+#define _ARM_CPU_DEF_H
+
+#ifndef CODE
+ #define CODE
+#endif
+
+#ifndef XDATA
+ #define XDATA
+#endif
+
+#ifndef DATA
+ #define DATA
+#endif
+
+struct pt_regs {
+ long uregs[18];
+};
+
+#define ARM_cpsr uregs[16]
+#define ARM_pc uregs[15]
+#define ARM_lr uregs[14]
+#define ARM_sp uregs[13]
+#define ARM_ip uregs[12]
+#define ARM_fp uregs[11]
+#define ARM_r10 uregs[10]
+#define ARM_r9 uregs[9]
+#define ARM_r8 uregs[8]
+#define ARM_r7 uregs[7]
+#define ARM_r6 uregs[6]
+#define ARM_r5 uregs[5]
+#define ARM_r4 uregs[4]
+#define ARM_r3 uregs[3]
+#define ARM_r2 uregs[2]
+#define ARM_r1 uregs[1]
+#define ARM_r0 uregs[0]
+#define ARM_ORIG_r0 uregs[17]
+
+struct undef_hook {
+ struct undef_hook *next;
+ unsigned long instr_mask;
+ unsigned long instr_val;
+ unsigned long cpsr_mask;
+ unsigned long cpsr_val;
+ int (*fn)(struct pt_regs *regs, unsigned int instr);
+};
+
+int register_undef_hook(struct undef_hook *hook);
+
+/* Low level CPU specific IRQ handling code */
+
+#if !defined(__thumb__)
+/* Regular 32-bit ARM architecture */
+
+#define WITH_IRQ_HANDLER_ARGS
+
+#define sti() \
+ ({ \
+ unsigned long temp; \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ sti\n" \
+" bic %0, %0, #128\n" \
+" msr cpsr_c, %0" \
+ : "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+#define cli() \
+ ({ \
+ unsigned long temp; \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ cli\n" \
+" orr %0, %0, #128\n" \
+" msr cpsr_c, %0" \
+ : "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+#define save_and_cli(flags) \
+ ({ \
+ unsigned long temp; \
+ (void) (&temp == &flags); \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ save_and_cli\n" \
+" orr %1, %0, #128\n" \
+" msr cpsr_c, %1" \
+ : "=r" (flags), "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+#define save_flags(flags) \
+ ({ \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ save_flags\n" \
+ : "=r" (flags) \
+ : \
+ : "memory", "cc"); \
+ })
+
+#define restore_flags(flags) \
+ __asm__ __volatile__( \
+ "msr cpsr_c, %0 @ restore_flags\n" \
+ : \
+ : "r" (flags) \
+ : "memory", "cc")
+
+
+/* FIQ handling code */
+
+#define fiq_sti() \
+ ({ \
+ unsigned long temp; \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ sti\n" \
+" bic %0, %0, #64\n" \
+" msr cpsr_c, %0" \
+ : "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+#define fiq_cli() \
+ ({ \
+ unsigned long temp; \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ cli\n" \
+" orr %0, %0, #64\n" \
+" msr cpsr_c, %0" \
+ : "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+#define fiq_save_and_cli(flags) \
+ ({ \
+ unsigned long temp; \
+ (void) (&temp == &flags); \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ save_and_cli\n" \
+" orr %1, %0, #192\n" \
+" msr cpsr_c, %1" \
+ : "=r" (flags), "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+#elif defined(__thumb2__) || defined (__ARM_ARCH_6M__)
+/* ARM Cortex-M3 architecture */
+
+/* The interrupts are not delivered with argument,
+ it is retrieved independent way - irq_arch_get_irqidx */
+#undef WITH_IRQ_HANDLER_ARGS
+
+/* Offset between first interrupt source and exception table base */
+#define IRQ_IRQIDX_OFFSET 16
+
+#define sti() \
+ ({ \
+ __asm__ __volatile__( \
+ "cpsie i @ sti\n" \
+ : : : "memory", "cc"); \
+ })
+
+#define cli() \
+ ({ \
+ __asm__ __volatile__( \
+ "cpsid i @ cli\n" \
+ : : : "memory", "cc"); \
+ })
+
+#define save_and_cli(flags) \
+ ({ \
+ unsigned long temp; \
+ (void) (&temp == &flags); \
+ __asm__ __volatile__( \
+ "mrs %0, primask @ save_and_cli\n" \
+" cpsid i\n" \
+ : "=r" (flags) \
+ : \
+ : "memory", "cc"); \
+ })
+
+#define save_flags(flags) \
+ ({ \
+ unsigned long temp; \
+ (void) (&temp == &flags); \
+ __asm__ __volatile__( \
+ "mrs %0, primask @ save_flags\n" \
+ : "=r" (flags) \
+ : \
+ : "memory", "cc"); \
+ })
+
+#define restore_flags(flags) \
+ ({ \
+ __asm__ __volatile__( \
+ "msr primask, %0 @ restore_flags\n" \
+ : \
+ : "r" (flags) \
+ : "memory", "cc"); \
+ })
+
+#define irq_arch_get_irqidx() \
+ ({ \
+ unsigned long ipsr; \
+ __asm__ __volatile__( \
+ "mrs %0, ipsr @ get irqidx\n" \
+ : "=r" (ipsr) ); \
+ ipsr; \
+ })
+
+#else /*defined(__thumb__)*/
+
+#define WITH_IRQ_HANDLER_ARGS
+/* Regular ARM architecture in THUMB mode */
+
+void irq_fnc_sti(void);
+#define sti irq_fnc_sti
+void irq_fnc_cli(void);
+#define cli irq_fnc_cli
+unsigned long irq_fnc_save_and_cli(void);
+#define save_and_cli(_flags) ((_flags)=irq_fnc_save_and_cli())
+unsigned long irq_fnc_save_flags(void);
+#define save_flags(_flags) ((_flags)=irq_fnc_save_flags())
+void irq_fnc_restore_flags(unsigned long flags);
+#define restore_flags irq_fnc_restore_flags
+
+#endif /*defined(__thumb__)*/
+
+void __cpu_coherent_range(unsigned long start, unsigned long end);
+
+static inline void flush_icache_range(unsigned long start, unsigned long end)
+{
+ __cpu_coherent_range(start, end);
+}
+
+/* atomic access routines */
+
+//typedef unsigned long atomic_t;
+
+static inline void atomic_clear_mask(unsigned long mask, volatile unsigned long *addr)
+{
+ unsigned long flags;
+
+ save_and_cli(flags);
+ *addr &= ~mask;
+ restore_flags(flags);
+}
+
+static inline void atomic_set_mask(unsigned long mask, volatile unsigned long *addr)
+{
+ unsigned long flags;
+
+ save_and_cli(flags);
+ *addr |= mask;
+ restore_flags(flags);
+}
+
+static inline void set_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long flags;
+
+ save_and_cli(flags);
+ *addr |= 1<<nr;
+ restore_flags(flags);
+}
+
+static inline void clear_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long flags;
+
+ save_and_cli(flags);
+ *addr &= ~(1<<nr);
+ restore_flags(flags);
+}
+
+static inline int test_bit(int nr, volatile unsigned long *addr)
+{
+ return ((*addr) & (1<<nr))?1:0;
+}
+
+static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long flags;
+ long m=(1<<nr);
+ long r;
+
+ save_and_cli(flags);
+ r=*addr;
+ *addr=r|m;
+ restore_flags(flags);
+ return r&m?1:0;
+}
+
+#if defined(__thumb2__) || defined (__ARM_ARCH_6M__)
+
+/* DMB, DSB, ISB */
+
+#define __memory_barrier() \
+ __asm__ __volatile__("dmb": : : "memory")
+
+#else /* old plain ARM architecture */
+
+#define __memory_barrier() \
+ __asm__ __volatile__("": : : "memory")
+
+#endif
+
+/*masked fields macros*/
+
+#define __val2mfld(mask,val) (((mask)&~((mask)<<1))*(val)&(mask))
+#define __mfld2val(mask,val) (((val)&(mask))/((mask)&~((mask)<<1)))
+
+static inline void outb(unsigned int port, int val) {
+ *(volatile unsigned char *)(port)=val;
+}
+
+static inline unsigned char inb(unsigned int port) {
+ return *(volatile unsigned char *)(port);
+}
+
+#define _WITHIN_CPU_DEF_H
+#include <irq_generic.h>
+#undef _WITHIN_CPU_DEF_H
+
+extern void **irq_context_table;
+extern irq_handler_t **irq_handler_table;
+extern unsigned int irq_table_size;
+
+/* Arithmetic functions */
+#if 0
+/* ARM v5E architecture - DSP extension */
+
+#define sat_add_slsl(__x,__y) \
+ __asm__ (" qadd %0,%0,%2\n" \
+ : "=r"(__x) \
+ : "0" ((long)__x), "r" ((long)__y) : "cc"); \
+
+#define sat_sub_slsl(__x,__y) \
+ __asm__ (" qsub %0,%0,%2\n" \
+ : "=r"(__x) \
+ : "0" ((long)__x), "r" ((long)__y) : "cc"); \
+
+#elif !defined(__thumb__)
+/* Regular 32-bit ARM architecture */
+
+#define sat_add_slsl(__x,__y) \
+ __asm__ (" adds %0,%2\n" \
+ " eorvs %0,%2,#0x80000000\n" \
+ " sbcvs %0,%0,%2\n" \
+ : "=r"(__x) \
+ : "0" ((long)__x), "r" ((long)__y) : "cc"); \
+
+#define sat_sub_slsl(__x,__y) \
+ __asm__ (" subs %0,%2\n" \
+ " eorvs %0,%2,#0x80000000\n" \
+ " sbcvs %0,%0,%2\n" \
+ : "=r"(__x) \
+ : "0" ((long)__x), "r" ((long)__y) : "cc"); \
+
+#elif defined(__thumb2__) || defined (__ARM_ARCH_6M__)
+
+#define sat_add_slsl(__x,__y) \
+ __asm__ (" adds %0,%2\n" \
+ " itt vs\n" \
+ " eorsvs %0,%3,%2\n" \
+ " sbcsvs %0,%0,%2\n" \
+ : "=r"(__x) \
+ : "0" ((long)__x), "r" ((long)__y), "r" (0x80000000): "cc"); \
+
+#define sat_sub_slsl(__x,__y) \
+ __asm__ (" subs %0,%2\n" \
+ " itt vs\n" \
+ " eorsvs %0,%3,%2\n" \
+ " sbcsvs %0,%0,%2\n" \
+ : "=r"(__x) \
+ : "0" ((long)__x), "r" ((long)__y), "r" (0x80000000) : "cc"); \
+
+#endif
+
+#endif /* _ARM_CPU_DEF_H */
--- /dev/null
+#ifndef HAL_INTR_H
+#define HAL_INTR_H
+
+#include <hal_ints.h>
+
+//--------------------------------------------------------------------------
+// Static data used by HAL
+// ISR tables
+extern uint32_t hal_interrupt_handlers[HAL_ISR_COUNT];
+extern uint32_t hal_interrupt_data[HAL_ISR_COUNT];
+
+//--------------------------------------------------------------------------
+// Default ISR
+// The #define is used to test whether this routine exists, and to allow
+// code outside the HAL to call it.
+
+typedef void (*hal_isr)(int vector, uint32_t data); //function ptr
+extern uint32_t hal_default_isr(int vector, uint32_t data);
+#define HAL_DEFAULT_ISR hal_default_isr
+
+//--------------------------------------------------------------------------
+// Vector translation.
+
+#ifndef HAL_TRANSLATE_VECTOR
+#define HAL_TRANSLATE_VECTOR(_vector_,_index_) \
+ (_index_) = (_vector_)
+#endif
+
+//--------------------------------------------------------------------------
+// Interrupt and VSR attachment macros
+
+#define HAL_INTERRUPT_IN_USE( _vector_, _state_) \
+ { \
+ uint32_t _index_; \
+ HAL_TRANSLATE_VECTOR ((_vector_), _index_); \
+ \
+ if( hal_interrupt_handlers[_index_] == (uint32_t)hal_default_isr ) \
+ (_state_) = 0; \
+ else \
+ (_state_) = 1; \
+ }
+
+#define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_) \
+ { \
+ if( hal_interrupt_handlers[_vector_] == (uint32_t)hal_default_isr ) \
+ { \
+ hal_interrupt_handlers[_vector_] = (uint32_t)_isr_; \
+ hal_interrupt_data[_vector_] = (uint32_t) _data_; \
+ } \
+ }
+
+#define HAL_INTERRUPT_DETACH( _vector_, _isr_ ) \
+ { \
+ if( (hal_interrupt_handlers[_vector_] == (uint32_t)_isr_) || !(_isr_) ) \
+ { \
+ hal_interrupt_handlers[_vector_] = (uint32_t)hal_default_isr; \
+ hal_interrupt_data[_vector_] = 0; \
+ } \
+ }
+
+
+//--------------------------------------------------------------------------
+// Interrupt controller access
+
+extern void hal_interrupt_mask(int);
+extern void hal_interrupt_unmask(int);
+extern void hal_interrupt_acknowledge(int);
+extern void hal_interrupt_configure(int, int, int);
+extern void hal_interrupt_set_level(int, int);
+
+#define HAL_INTERRUPT_MASK( _vector_ ) \
+ hal_interrupt_mask( _vector_ )
+#define HAL_INTERRUPT_UNMASK( _vector_ ) \
+ hal_interrupt_unmask( _vector_ )
+#define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ ) \
+ hal_interrupt_acknowledge( _vector_ )
+#define HAL_INTERRUPT_CONFIGURE( _vector_, _level_, _up_ ) \
+ hal_interrupt_configure( _vector_, _level_, _up_ )
+#define HAL_INTERRUPT_SET_LEVEL( _vector_, _level_ ) \
+ hal_interrupt_set_level( _vector_, _level_ )
+
+#endif /* HAL_DEFAULT_ISR */
--- /dev/null
+#ifndef __ASM_ARM_TYPES_H
+#define __ASM_ARM_TYPES_H
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#ifndef __BIT_TYPES_DEFINED__
+#define __BIT_TYPES_DEFINED__
+
+typedef __u8 uint8_t;
+typedef __s8 int8_t;
+typedef __u16 uint16_t;
+typedef __s16 int16_t;
+typedef __u32 uint32_t;
+typedef __s32 int32_t;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __s64 int64_t;
+typedef __u64 uint64_t;
+#endif
+
+#endif /* !(__BIT_TYPES_DEFINED__) */
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+#define BITS_PER_LONG 32
+
+#ifndef __ASSEMBLY__
+
+typedef __s8 s8;
+typedef __u8 u8;
+
+typedef __s16 s16;
+typedef __u16 u16;
+
+typedef __s32 s32;
+typedef __u32 u32;
+
+typedef __s64 s64;
+typedef __s64 u64;
+
+/* Dma addresses are 32-bits wide. */
+
+typedef u32 dma_addr_t;
+typedef u32 dma64_addr_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+/* Types for `void *' pointers. */
+#if __WORDSIZE == 64
+# ifndef __intptr_t_defined
+typedef long int intptr_t;
+# define __intptr_t_defined
+# endif
+typedef unsigned long int uintptr_t;
+#else
+# ifndef __intptr_t_defined
+typedef int intptr_t;
+# define __intptr_t_defined
+# endif
+typedef unsigned int uintptr_t;
+#endif
+
+#endif
+
--- /dev/null
+#ifndef _IRQ_ARCH_H
+#define _IRQ_ARCH_H
+
+
+#endif /*_IRQ_ARCH_H*/
\ No newline at end of file
--- /dev/null
+#include <inttypes.h>
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+SUBDIRS = misc iap_kvpb
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+ifeq ($(CONFIG_KEYVAL),y)
+include_HEADERS = lpciap_kvpb.h
+lib_LIBRARIES = lpciap_kvpb
+lpciap_kvpb_SOURCES = iap_kvpb.c
+endif
--- /dev/null
+#include <string.h>
+#include <keyvalpb.h>
+#include <lpciap.h>
+
+unsigned long lpciap_buff[ISP_RAM2FLASH_BLOCK_SIZE/4];
+char *lpciap_addr_base=NULL;
+
+#define ISP_RAM2FLASH_BLOCK_SIZE_MASK (ISP_RAM2FLASH_BLOCK_SIZE-1)
+
+int lpcisp_kvpb_erase(struct kvpb_block *store, void *base,int size)
+{
+ return lpcisp_erase(base, size);
+}
+
+int lpcisp_kvpb_flush(struct kvpb_block *store)
+{
+ if (lpciap_addr_base==NULL) return -1;
+ lpcisp_write(lpciap_addr_base,lpciap_buff,ISP_RAM2FLASH_BLOCK_SIZE);
+ lpciap_addr_base=NULL;
+ return 0;
+}
+
+int lpcisp_kvpb_copy(struct kvpb_block *store,void *des, const void *src, int len)
+{
+ char *addr_base,*addr_src=(char*)src;
+ int cp_len;
+
+ while(len) {
+ addr_base=(char*)((unsigned long)des&~ISP_RAM2FLASH_BLOCK_SIZE_MASK);
+ cp_len=ISP_RAM2FLASH_BLOCK_SIZE-((unsigned long)des&ISP_RAM2FLASH_BLOCK_SIZE_MASK);
+ if (len<cp_len) cp_len=len;
+ if (lpciap_addr_base) {
+ if (lpciap_addr_base!=addr_base) {
+ lpcisp_kvpb_flush(store);
+ memcpy(lpciap_buff,addr_base,ISP_RAM2FLASH_BLOCK_SIZE);
+ lpciap_addr_base=addr_base;
+ }
+ } else {
+ memcpy(lpciap_buff,addr_base,ISP_RAM2FLASH_BLOCK_SIZE);
+ lpciap_addr_base=addr_base;
+ }
+ memcpy((char*)lpciap_buff+((unsigned long)des&ISP_RAM2FLASH_BLOCK_SIZE_MASK),addr_src,cp_len);
+ des=(char*)des+cp_len;
+ addr_src+=cp_len;
+ len-=cp_len;
+ if (((unsigned long)des&ISP_RAM2FLASH_BLOCK_SIZE_MASK)==0x00)
+ lpcisp_kvpb_flush(store);
+ }
+ return 1;
+}
--- /dev/null
+#ifndef _LPCIAP_KVPB_H
+#define _LPCIAP_KVPB_H
+
+#include <system_def.h>
+
+extern unsigned long lpciap_buff[ISP_RAM2FLASH_BLOCK_SIZE/4];
+
+int lpcisp_kvpb_erase(struct kvpb_block *store, void *base,int size);
+int lpcisp_kvpb_flush(struct kvpb_block *store);
+int lpcisp_kvpb_copy(struct kvpb_block *store,void *des, const void *src, int len);
+
+#endif /* _LPCIAP_KVPB_ */
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+include_HEADERS = system_stub.h
+
+lib_LIBRARIES = arch
+
+arch_SOURCES = bbconf_info.c
+
+lib_obj_SOURCES = system_stub.c
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ bbconf_info.c - boot block config parameters retrieval
+
+ Copyright (C) 2001 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002 by PiKRON Ltd. http://www.pikron.com
+
+ *******************************************************************/
+
+#include <string.h>
+#include <bbconf_info.h>
+
+int bbconf_get_param(unsigned long tag, unsigned long *pval)
+{
+ unsigned long *magic = (unsigned long *)BBCONF_MAGIC_ADDR;
+ unsigned long *pt_ptr = (unsigned long *)BBCONF_PTPTR_ADDR;
+ unsigned long *pt;
+ int cnt;
+
+ if(*magic != BBCONF_MAGIC_VAL)
+ return -2;
+
+ if(!(*pt_ptr) || !(*pt_ptr+1))
+ return -2;
+
+ pt = (unsigned long *)*pt_ptr;
+
+ for(cnt = 0; (cnt < BBCONF_PT_MAX_CNT) &&
+ (pt[0] != BBCONF_PTTAG_END); cnt++, pt += 2) {
+ if(pt[0] == tag) {
+ *pval=pt[1];
+ return 1;
+ }
+ }
+ return -1;
+}
--- /dev/null
+/* Support files for GNU libc. Files in the system namespace go here.
+ Files in the C namespace (ie those that do not start with an
+ underscore) go in .c. */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <stdio.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <errno.h>
+#include <reent.h>
+#include <system_def.h>
+#include "system_stub.h"
+
+/* Register name faking - works in collusion with the linker. */
+register char * stack_ptr asm ("sp");
+
+system_stub_ops_t system_stub_ops;
+
+int _read(int file, char *ptr, int len);
+int
+_read (int file,
+ char * ptr,
+ int len)
+{
+ if(!system_stub_ops.read)
+ return -1;
+ return system_stub_ops.read(file,ptr,len);
+}
+
+int _write(int file, const char *ptr, int len);
+int
+_write (int file,
+ const char * ptr,
+ int len)
+{
+ if(!system_stub_ops.write)
+ return len;
+ return system_stub_ops.write(file,ptr,len);
+}
+
+
+int
+_lseek (int file,
+ int pos,
+ int dir)
+{
+ if(!system_stub_ops.lseek)
+ return -1;
+ return system_stub_ops.lseek(file,pos,dir);
+}
+
+int _open(const char *path, int flags, ...);
+int
+_open (const char * path,
+ int flags,
+ ...)
+{
+ if(!system_stub_ops.open)
+ return -1;
+ return system_stub_ops.open(path,flags,0);
+}
+
+int _close(int file);
+int
+_close (int file)
+{
+ if(!system_stub_ops.close)
+ return -1;
+ return system_stub_ops.close(file);
+}
+
+typedef int (local_call_t)(void);
+
+void _exit(int n);
+void
+_exit (int n)
+{
+ ((local_call_t*)0)();
+ while(1);
+}
+
+void abort(void);
+void abort(void)
+{
+ ((local_call_t*)0)();
+ while(1);
+}
+
+int _kill(int n, int m);
+int
+_kill (int n, int m)
+{
+ return -1;
+}
+
+int _getpid(void);
+int
+_getpid (void)
+{
+ return 1;
+}
+
+
+void *_sbrk(ptrdiff_t incr);
+void *
+_sbrk (ptrdiff_t incr)
+{
+ extern char end asm ("end"); /* Defined by the linker. */
+ static char *heap_end;
+ char * prev_heap_end;
+
+ incr=(incr+3) & ~3;
+
+ if (heap_end == NULL)
+ heap_end = & end;
+
+ prev_heap_end = heap_end;
+
+ if (heap_end + incr > stack_ptr)
+ {
+ /* Some of the libstdc++-v3 tests rely upon detecting
+ out of memory errors, so do not abort here. */
+#if 0
+ extern void abort (void);
+
+ _write (1, "_sbrk: Heap and stack collision\n", 32);
+
+ abort ();
+#else
+ errno = ENOMEM;
+ return (caddr_t) -1;
+#endif
+ }
+
+ heap_end += incr;
+
+ return /*(caddr_t)*/ prev_heap_end;
+}
+
+int _fstat(int file, struct stat *st);
+int
+_fstat (int file, struct stat * st)
+{
+ return -1;
+}
+
+int _stat (const char *fname, struct stat *st);
+int _stat (const char *fname, struct stat *st)
+{
+ return -1;
+}
+
+int _link(const char *path1, const char *path2);
+int
+_link (const char *path1,
+ const char *path2)
+{
+ return -1;
+}
+
+int _unlink(const char *path);
+int
+_unlink (const char *path)
+{
+ return -1;
+}
+
+void _raise(void);
+void
+_raise (void)
+{
+ return;
+}
+
+int _gettimeofday(struct timeval *tp, struct timezone *tzp);
+int
+_gettimeofday (struct timeval *tp,
+ struct timezone *tzp)
+{
+
+ if(tp)
+ {
+ tp->tv_sec = 0;
+ tp->tv_usec = 0;
+ }
+ /* Return fixed data for the timezone. */
+ if (tzp)
+ {
+ tzp->tz_minuteswest = 0;
+ tzp->tz_dsttime = 0;
+ }
+
+ return 0;
+}
+
+/* Return a clock that ticks at 100Hz. */
+clock_t _times(struct tms *tp);
+clock_t
+_times (struct tms * tp)
+{
+ clock_t timeval = 0;
+
+ if (tp)
+ {
+ tp->tms_utime = timeval; /* user time */
+ tp->tms_stime = 0; /* system time */
+ tp->tms_cutime = 0; /* user time, children */
+ tp->tms_cstime = 0; /* system time, children */
+ }
+
+ return timeval;
+};
+
+
+int isatty(int fd);
+int
+isatty (int fd)
+{
+ return 1;
+}
+
+int _system(const char *s);
+int
+_system (const char *s)
+{
+ return -1;
+}
+
+int _rename(const char *oldpath, const char *newpath);
+int
+_rename (const char * oldpath, const char * newpath)
+{
+ return -1;
+}
+
+/* extern (.*) ([^ ]*) _PARAMS \(\(struct _reent \*(,*)(.*)\)\); */
+/* \1 \2 (struct _reent *\3\4) { return \2(\4);} */
+
+struct _reent;
+
+int _close_r(struct _reent *reent, int file)
+{ return _close(file);}
+/*
+ int _fcntl_r(struct _reent *, int, int, int)
+ { return _fcntl( int, int, int);}
+*/
+int _fstat_r(struct _reent *reent, int file, struct stat *st);
+int _fstat_r(struct _reent *reent, int file, struct stat *st)
+{ return _fstat(file, st);}
+
+int _getpid_r(struct _reent *reent);
+int _getpid_r(struct _reent *reent)
+{ return _getpid();}
+
+int _kill_r(struct _reent *reent, int n, int m);
+int _kill_r(struct _reent *reent, int n, int m)
+{ return _kill(n, m);}
+
+int _link_r(struct _reent *reent, const char *path1, const char *path2);
+int _link_r(struct _reent *reent, const char *path1, const char *path2)
+{ return _link(path1, path2);}
+
+_off_t _lseek_r(struct _reent *reent, int file, _off_t pos, int dir);
+_off_t _lseek_r(struct _reent *reent, int file, _off_t pos, int dir)
+{ return _lseek(file, pos, dir);}
+
+int _open_r(struct _reent *reent, const char *path, int flags, int opts);
+int _open_r(struct _reent *reent, const char *path, int flags, int opts)
+{ return _open(path, flags, opts);}
+
+_ssize_t _read_r(struct _reent *reent, int file, void *ptr, size_t len);
+_ssize_t _read_r(struct _reent *reent, int file, void *ptr, size_t len)
+{ return _read(file, ptr, len);}
+
+void *_sbrk_r(struct _reent *reent, ptrdiff_t incr);
+void *_sbrk_r(struct _reent *reent, ptrdiff_t incr)
+{ return _sbrk(incr);}
+
+int _stat_r(struct _reent *reent, const char *path, struct stat *st);
+int _stat_r(struct _reent *reent, const char *path, struct stat *st)
+{ return _stat(path, st);}
+
+int _unlink_r(struct _reent *reent, const char *path);
+int _unlink_r(struct _reent *reent, const char *path)
+{ return _unlink(path);}
+
+_ssize_t _write_r(struct _reent *reent, int file, const void *ptr, size_t len);
+_ssize_t _write_r(struct _reent *reent, int file, const void *ptr, size_t len)
+{ return _write(file, ptr, len);}
+
+/* FIXME: TDK added dummy functions. Need to implement. */
+int _isatty(int fd);
+int _isatty(int fd)
+{
+ return -1;
+}
+
+int _swistat(int fd, struct stat *st);
+int _swistat(int fd, struct stat *st)
+{
+ return -1;
+}
+
+/* Return a clock that ticks at 100Hz. */
+clock_t _clock(void);
+clock_t _clock(void)
+{
+ clock_t timeval=0;
+ return timeval;
+}
+
+int _swiclose(int fh);
+int _swiclose(int fh)
+{
+ return -1;
+}
+
+int _swiopen(const char *path, int flags);
+int _swiopen(const char *path, int flags)
+{
+ return -1;
+}
+
+int _swiwrite(int fh, char *ptr, int len);
+int _swiwrite(int fh, char *ptr, int len)
+{
+ return -1;
+}
+
+int _swilseek(int fd, int ptr, int dir);
+int _swilseek(int fd, int ptr, int dir)
+{
+ return -1;
+}
+
+int _swiread(int fh, char *ptr, int len);
+int _swiread(int fh, char *ptr, int len)
+{
+ return -1;
+}
+
+void initialise_monitor_handles(void);
+void initialise_monitor_handles(void)
+{
+}
--- /dev/null
+#ifndef _SYSTEM_STUB_H_
+#define _SYSTEM_STUB_H_
+
+#include <types.h>
+
+typedef struct system_stub_ops_t {
+ int (*open)(const char * path, int flags, ...);
+ int (*close)(int file);
+ int (*read)(int file, char * ptr, int len);
+ int (*write)(int file, const char * ptr, int len);
+ int (*lseek)(int file, int ptr, int dir);
+} system_stub_ops_t;
+
+extern system_stub_ops_t system_stub_ops;
+
+#endif /* _SYSTEM_DEF_H_ */
--- /dev/null
+#include <cpu_def.h>
+#include <irq_def.h>
+
+static int undef_initialized = 0;
+
+static unsigned long cpu_undef_stack[256];
+
+struct undef_hook *undef_hook_chain = NULL;
+
+static void undef_exception_handler(int excptnum, struct pt_regs *regs)
+{
+ /*unsigned int correction = thumb_mode(regs) ? 2 : 4;*/
+ unsigned int correction = 0;
+ struct undef_hook *hook;
+ void *pc;
+ unsigned long instr;
+
+ regs->ARM_pc -= correction;
+
+ pc = (void *)regs->ARM_pc;
+
+ instr = *(unsigned long *)pc;
+
+ for(hook = undef_hook_chain; hook; hook = hook->next) {
+ if (((instr & hook->instr_mask) == hook->instr_val) &&
+ ((regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val)) {
+ if (hook->fn(regs, instr) == 0) {
+ return;
+ }
+ }
+ }
+
+ for(;;){
+ /* Fatal error */
+ }
+}
+
+int register_undef_hook(struct undef_hook *hook)
+{
+ unsigned long flags;
+
+ save_and_cli(flags);
+
+ if(!undef_initialized) {
+ set_cpu_exception_handler(ARM_EXCEPTION_UNDEF, (long)undef_exception_handler);
+ set_cpu_exception_stack(ARM_EXCEPTION_UNDEF, (long)((char*)cpu_undef_stack+sizeof(cpu_undef_stack)-8));
+ undef_initialized = 1;
+ }
+
+ hook->next = undef_hook_chain;
+ undef_hook_chain = hook;
+ restore_flags(flags);
+
+ return 0;
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+SUBDIRS = defines libs
--- /dev/null
+/****************************************************************************//**
+ * @file : LPC17xx.h
+ * @brief : CMSIS Cortex-M3 Core Peripheral Access Layer Header File for
+ * NXP LPC17xx Device Series
+ * @version : V1.1
+ * @date : 14th May 2009
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2008 ARM Limited. All rights reserved.
+ *
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M3
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+
+#ifndef __LPC17xx_H__
+#define __LPC17xx_H__
+
+///////////////////////////////////////////////////////////////////////////////
+// Keyval
+#define KVPB_CHUNK_SIZE 16
+
+///////////////////////////////////////////////////////////////////////////////
+// ISP_RAM2FLASH_BLOCK_SIZE for 17xx CPU
+#ifndef ISP_RAM2FLASH_BLOCK_SIZE
+ #define ISP_RAM2FLASH_BLOCK_SIZE 256
+#endif /* ISP_RAM2FLASH_BLOCK_SIZE */
+
+/** @addtogroup CMSIS_Configuration
+ * @{
+ */
+
+/*
+ * ==========================================================================
+ * ---------- Interrupt Number Definition -----------------------------------
+ * ==========================================================================
+ */
+
+/**
+ * @brief Interrupt Number Type Definition
+ */
+typedef enum IRQn
+{
+/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
+ NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
+ MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */
+ BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
+ UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */
+ SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */
+ DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */
+ PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */
+ SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */
+
+/****** LPC17xx Specific Interrupt Numbers *******************************************************/
+ WDT_IRQn = 0, /*!< Watchdog Timer Interrupt */
+ TIMER0_IRQn = 1, /*!< Timer0 Interrupt */
+ TIMER1_IRQn = 2, /*!< Timer1 Interrupt */
+ TIMER2_IRQn = 3, /*!< Timer2 Interrupt */
+ TIMER3_IRQn = 4, /*!< Timer3 Interrupt */
+ UART0_IRQn = 5, /*!< UART0 Interrupt */
+ UART1_IRQn = 6, /*!< UART1 Interrupt */
+ UART2_IRQn = 7, /*!< UART2 Interrupt */
+ UART3_IRQn = 8, /*!< UART3 Interrupt */
+ PWM1_IRQn = 9, /*!< PWM1 Interrupt */
+ I2C0_IRQn = 10, /*!< I2C0 Interrupt */
+ I2C1_IRQn = 11, /*!< I2C1 Interrupt */
+ I2C2_IRQn = 12, /*!< I2C2 Interrupt */
+ SPI_IRQn = 13, /*!< SPI Interrupt */
+ SSP0_IRQn = 14, /*!< SSP0 Interrupt */
+ SSP1_IRQn = 15, /*!< SSP1 Interrupt */
+ PLL0_IRQn = 16, /*!< PLL0 Lock (Main PLL) Interrupt */
+ RTC_IRQn = 17, /*!< Real Time Clock Interrupt */
+ EINT0_IRQn = 18, /*!< External Interrupt 0 Interrupt */
+ EINT1_IRQn = 19, /*!< External Interrupt 1 Interrupt */
+ EINT2_IRQn = 20, /*!< External Interrupt 2 Interrupt */
+ EINT3_IRQn = 21, /*!< External Interrupt 3 Interrupt */
+ ADC_IRQn = 22, /*!< A/D Converter Interrupt */
+ BOD_IRQn = 23, /*!< Brown-Out Detect Interrupt */
+ USB_IRQn = 24, /*!< USB Interrupt */
+ CAN_IRQn = 25, /*!< CAN Interrupt */
+ DMA_IRQn = 26, /*!< General Purpose DMA Interrupt */
+ I2S_IRQn = 27, /*!< I2S Interrupt */
+ ENET_IRQn = 28, /*!< Ethernet Interrupt */
+ RIT_IRQn = 29, /*!< Repetitive Interrupt Timer Interrupt */
+ MCPWM_IRQn = 30, /*!< Motor Control PWM Interrupt */
+ QEI_IRQn = 31, /*!< Quadrature Encoder Interface Interrupt */
+ PLL1_IRQn = 32, /*!< PLL1 Lock (USB PLL) Interrupt */
+} IRQn_Type;
+
+
+/*
+ * ==========================================================================
+ * ----------- Processor and Core Peripheral Section ------------------------
+ * ==========================================================================
+ */
+
+/* Configuration of the Cortex-M3 Processor and Core Peripherals */
+#define __MPU_PRESENT 1 /*!< MPU present or not */
+#define __NVIC_PRIO_BITS 5 /*!< Number of Bits used for Priority Levels */
+#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
+
+/**
+ * @}
+ */
+
+#include "core_cm3.h" /* Cortex-M3 processor and core peripherals */
+
+
+
+/**
+ * Initialize the system clock
+ *
+ * @param none
+ * @return none
+ *
+ * @brief Setup the microcontroller system.
+ * Initialize the System and update the SystemFrequency variable.
+ */
+extern void SystemInit (void);
+
+
+/** @addtogroup Peripheral_register_structures
+ * @{
+ */
+
+/******************************************************************************/
+/* Device Specific Peripheral registers structures */
+/******************************************************************************/
+
+//#ifndef __IAR_SYSTEMS_ICC__
+//#pragma anon_unions
+//#endif
+
+
+/*------------- System Control (SC) ------------------------------------------*/
+/**
+ * @brief System Control Structure Type Definition
+ */
+typedef struct
+{
+ __IO uint32_t FLASHCFG; /* Flash Accelerator Module */
+ uint32_t RESERVED0[31];
+ __IO uint32_t PLL0CON; /* Clocking and Power Control */
+ __IO uint32_t PLL0CFG;
+ __I uint32_t PLL0STAT;
+ __O uint32_t PLL0FEED;
+ uint32_t RESERVED1[4];
+ __IO uint32_t PLL1CON;
+ __IO uint32_t PLL1CFG;
+ __I uint32_t PLL1STAT;
+ __O uint32_t PLL1FEED;
+ uint32_t RESERVED2[4];
+ __IO uint32_t PCON;
+ __IO uint32_t PCONP;
+ uint32_t RESERVED3[15];
+ __IO uint32_t CCLKCFG;
+ __IO uint32_t USBCLKCFG;
+ __IO uint32_t CLKSRCSEL;
+ uint32_t RESERVED4[12];
+ __IO uint32_t EXTINT; /* External Interrupts */
+ uint32_t RESERVED5;
+ __IO uint32_t EXTMODE;
+ __IO uint32_t EXTPOLAR;
+ uint32_t RESERVED6[12];
+ __IO uint32_t RSID; /* Reset */
+ uint32_t RESERVED7[7];
+ __IO uint32_t SCS; /* Syscon Miscellaneous Registers */
+ __IO uint32_t IRCTRIM; /* Clock Dividers */
+ __IO uint32_t PCLKSEL0;
+ __IO uint32_t PCLKSEL1;
+ uint32_t RESERVED8[4];
+ __IO uint32_t USBIntSt; /* USB Device/OTG Interrupt Register */
+ uint32_t RESERVED9;
+ __IO uint32_t CLKOUTCFG; /* Clock Output Configuration */
+ } SC_TypeDef;
+
+/*------------- Pin Connect Block (PINCON) -----------------------------------*/
+/**
+ * @brief Pin Connect (Select) Structure Type Definition
+ */
+typedef struct
+{
+ __IO uint32_t PINSEL0;
+ __IO uint32_t PINSEL1;
+ __IO uint32_t PINSEL2;
+ __IO uint32_t PINSEL3;
+ __IO uint32_t PINSEL4;
+ __IO uint32_t PINSEL5;
+ __IO uint32_t PINSEL6;
+ __IO uint32_t PINSEL7;
+ __IO uint32_t PINSEL8;
+ __IO uint32_t PINSEL9;
+ __IO uint32_t PINSEL10;
+ uint32_t RESERVED0[5];
+ __IO uint32_t PINMODE0;
+ __IO uint32_t PINMODE1;
+ __IO uint32_t PINMODE2;
+ __IO uint32_t PINMODE3;
+ __IO uint32_t PINMODE4;
+ __IO uint32_t PINMODE5;
+ __IO uint32_t PINMODE6;
+ __IO uint32_t PINMODE7;
+ __IO uint32_t PINMODE8;
+ __IO uint32_t PINMODE9;
+ __IO uint32_t PINMODE_OD0;
+ __IO uint32_t PINMODE_OD1;
+ __IO uint32_t PINMODE_OD2;
+ __IO uint32_t PINMODE_OD3;
+ __IO uint32_t PINMODE_OD4;
+ __IO uint32_t I2CPADCFG;
+} PINCON_TypeDef;
+
+
+/*------------- General Purpose Input/Output (GPIO) --------------------------*/
+/**
+ * @brief GPIO Structure Type Definition
+ */
+typedef struct
+{
+ __IO uint32_t FIODIR;
+ uint32_t RESERVED0[3];
+ __IO uint32_t FIOMASK;
+ __IO uint32_t FIOPIN;
+ __IO uint32_t FIOSET;
+ __O uint32_t FIOCLR;
+} GPIO_TypeDef;
+
+/**
+ * @brief GPIO Interrupt Structure Type Definition
+ */
+typedef struct
+{
+ __I uint32_t IntStatus;
+ __I uint32_t IO0IntStatR;
+ __I uint32_t IO0IntStatF;
+ __O uint32_t IO0IntClr;
+ __IO uint32_t IO0IntEnR;
+ __IO uint32_t IO0IntEnF;
+ uint32_t RESERVED0[3];
+ __I uint32_t IO2IntStatR;
+ __I uint32_t IO2IntStatF;
+ __O uint32_t IO2IntClr;
+ __IO uint32_t IO2IntEnR;
+ __IO uint32_t IO2IntEnF;
+} GPIOINT_TypeDef;
+
+/*------------- Timer (TIM) --------------------------------------------------*/
+/**
+ * @brief Timer Structure Type Definition
+ */
+typedef struct
+{
+ __IO uint32_t IR;
+ __IO uint32_t TCR;
+ __IO uint32_t TC;
+ __IO uint32_t PR;
+ __IO uint32_t PC;
+ __IO uint32_t MCR;
+ __IO uint32_t MR0;
+ __IO uint32_t MR1;
+ __IO uint32_t MR2;
+ __IO uint32_t MR3;
+ __IO uint32_t CCR;
+ __I uint32_t CR0;
+ __I uint32_t CR1;
+ uint32_t RESERVED0[2];
+ __IO uint32_t EMR;
+ uint32_t RESERVED1[24];
+ __IO uint32_t CTCR;
+} TIM_TypeDef;
+
+/*------------- Pulse-Width Modulation (PWM) ---------------------------------*/
+/**
+ * @brief Pulse Width ModulationStructure Type Definition
+ */
+typedef struct
+{
+ __IO uint32_t IR;
+ __IO uint32_t TCR;
+ __IO uint32_t TC;
+ __IO uint32_t PR;
+ __IO uint32_t PC;
+ __IO uint32_t MCR;
+ __IO uint32_t MR0;
+ __IO uint32_t MR1;
+ __IO uint32_t MR2;
+ __IO uint32_t MR3;
+ __IO uint32_t CCR;
+ __I uint32_t CR0;
+ __I uint32_t CR1;
+ __I uint32_t CR2;
+ __I uint32_t CR3;
+ uint32_t RESERVED0;
+ __IO uint32_t MR4;
+ __IO uint32_t MR5;
+ __IO uint32_t MR6;
+ __IO uint32_t PCR;
+ __IO uint32_t LER;
+ uint32_t RESERVED1[7];
+ __IO uint32_t CTCR;
+} PWM_TypeDef;
+
+/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/
+/**
+ * @brief Universal Asynchronous Receiver Transmitter 0/2/3 Structure Type Definition
+ */
+typedef struct
+{
+ union {
+ __I uint8_t RBR;
+ __O uint8_t THR;
+ __IO uint8_t DLL;
+ uint32_t RESERVED0;
+ };
+
+ union {
+ __IO uint8_t DLM;
+ __IO uint32_t IER;
+ };
+
+ union {
+ __I uint32_t IIR;
+ __O uint8_t FCR;
+ };
+
+ __IO uint8_t LCR;
+ uint8_t RESERVED1[7];
+ __I uint8_t LSR;
+ uint8_t RESERVED2[7];
+ __IO uint8_t SCR;
+ uint8_t RESERVED3[3];
+ __IO uint32_t ACR;
+ __IO uint32_t ICR;
+ __IO uint32_t FDR;
+ uint32_t RESERVED4;
+ __IO uint8_t TER;
+ uint8_t RESERVED5[39];
+ __I uint32_t FIFOLVL;
+} UART_TypeDef;
+
+/**
+ * @brief Universal Asynchronous Receiver Transmitter 1 Structure Type Definition
+ */
+typedef struct
+{
+ union {
+ __I uint8_t RBR;
+ __O uint8_t THR;
+ __IO uint8_t DLL;
+ uint32_t RESERVED0;
+ };
+ union {
+ __IO uint8_t DLM;
+ __IO uint32_t IER;
+ };
+ union {
+ __I uint32_t IIR;
+ __O uint8_t FCR;
+ };
+ __IO uint8_t LCR;
+ uint8_t RESERVED1[3];
+ __IO uint8_t MCR;
+ uint8_t RESERVED2[3];
+ __IO uint8_t LSR;
+ uint8_t RESERVED3[3];
+ __IO uint8_t MSR;
+ uint8_t RESERVED4[3];
+ __IO uint8_t SCR;
+ uint8_t RESERVED5[3];
+ __IO uint32_t ACR;
+ uint32_t RESERVED6;
+ __IO uint32_t FDR;
+ uint32_t RESERVED7;
+ __IO uint8_t TER;
+ uint8_t RESERVED8[27];
+ __IO uint8_t RS485CTRL;
+ uint8_t RESERVED9[3];
+ __IO uint8_t ADRMATCH;
+ uint8_t RESERVED10[3];
+ __IO uint8_t RS485DLY;
+ uint8_t RESERVED11[3];
+ __IO uint32_t FIFOLVL;
+} UART1_TypeDef;
+
+
+/*------------- Serial Peripheral Interface (SPI) ----------------------------*/
+/**
+ * @brief Serial Peripheral InterfaceStructure Type Definition
+ */
+typedef struct
+{
+ __IO uint32_t SPCR;
+ __I uint32_t SPSR;
+ __IO uint32_t SPDR;
+ __IO uint32_t SPCCR;
+ uint32_t RESERVED0[3];
+ __IO uint32_t SPINT;
+} SPI_TypeDef;
+
+/*------------- Synchronous Serial Communication (SSP) -----------------------*/
+/**
+ * @brief Synchronous Serial Communication Structure Type Definition
+ */
+typedef struct
+{
+ __IO uint32_t CR0;
+ __IO uint32_t CR1;
+ __IO uint32_t DR;
+ __I uint32_t SR;
+ __IO uint32_t CPSR;
+ __IO uint32_t IMSC;
+ __IO uint32_t RIS;
+ __IO uint32_t MIS;
+ __IO uint32_t ICR;
+ __IO uint32_t DMACR;
+} SSP_TypeDef;
+
+/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/
+/**
+ * @brief Inter-Intergrated Circuit Structure Type Definition
+ */
+typedef struct
+{
+ __IO uint32_t I2CONSET;
+ __I uint32_t I2STAT;
+ __IO uint32_t I2DAT;
+ __IO uint32_t I2ADR0;
+ __IO uint32_t I2SCLH;
+ __IO uint32_t I2SCLL;
+ __O uint32_t I2CONCLR;
+ __IO uint32_t MMCTRL;
+ __IO uint32_t I2ADR1;
+ __IO uint32_t I2ADR2;
+ __IO uint32_t I2ADR3;
+ __I uint32_t I2DATA_BUFFER;
+ __IO uint32_t I2MASK0;
+ __IO uint32_t I2MASK1;
+ __IO uint32_t I2MASK2;
+ __IO uint32_t I2MASK3;
+} I2C_TypeDef;
+
+/*------------- Inter IC Sound (I2S) -----------------------------------------*/
+/**
+ * @brief Inter IC Sound Structure Type Definition
+ */
+typedef struct
+{
+ __IO uint32_t I2SDAO;
+ __IO uint32_t I2SDAI;
+ __O uint32_t I2STXFIFO;
+ __I uint32_t I2SRXFIFO;
+ __I uint32_t I2SSTATE;
+ __IO uint32_t I2SDMA1;
+ __IO uint32_t I2SDMA2;
+ __IO uint32_t I2SIRQ;
+ __IO uint32_t I2STXRATE;
+ __IO uint32_t I2SRXRATE;
+ __IO uint32_t I2STXBITRATE;
+ __IO uint32_t I2SRXBITRATE;
+ __IO uint32_t I2STXMODE;
+ __IO uint32_t I2SRXMODE;
+} I2S_TypeDef;
+
+/*------------- Repetitive Interrupt Timer (RIT) -----------------------------*/
+/**
+ * @brief Repetitive Interrupt Timer Structure Type Definition
+ */
+typedef struct
+{
+ __IO uint32_t RICOMPVAL;
+ __IO uint32_t RIMASK;
+ __IO uint8_t RICTRL;
+ uint8_t RESERVED0[3];
+ __IO uint32_t RICOUNTER;
+} RIT_TypeDef;
+
+/*------------- Real-Time Clock (RTC) ----------------------------------------*/
+/**
+ * @brief Real Time Clock Structure Type Definition
+ */
+typedef struct
+{
+ __IO uint8_t ILR;
+ uint8_t RESERVED0[7];
+ __IO uint8_t CCR;
+ uint8_t RESERVED1[3];
+ __IO uint8_t CIIR;
+ uint8_t RESERVED2[3];
+ __IO uint8_t AMR;
+ uint8_t RESERVED3[3];
+ __I uint32_t CTIME0;
+ __I uint32_t CTIME1;
+ __I uint32_t CTIME2;
+ __IO uint8_t SEC;
+ uint8_t RESERVED4[3];
+ __IO uint8_t MIN;
+ uint8_t RESERVED5[3];
+ __IO uint8_t HOUR;
+ uint8_t RESERVED6[3];
+ __IO uint8_t DOM;
+ uint8_t RESERVED7[3];
+ __IO uint8_t DOW;
+ uint8_t RESERVED8[3];
+ __IO uint16_t DOY;
+ uint16_t RESERVED9;
+ __IO uint8_t MONTH;
+ uint8_t RESERVED10[3];
+ __IO uint16_t YEAR;
+ uint16_t RESERVED11;
+ __IO uint32_t CALIBRATION;
+ __IO uint32_t GPREG0;
+ __IO uint32_t GPREG1;
+ __IO uint32_t GPREG2;
+ __IO uint32_t GPREG3;
+ __IO uint32_t GPREG4;
+ __IO uint8_t WAKEUPDIS;
+ uint8_t RESERVED12[3];
+ __IO uint8_t PWRCTRL;
+ uint8_t RESERVED13[3];
+ __IO uint8_t ALSEC;
+ uint8_t RESERVED14[3];
+ __IO uint8_t ALMIN;
+ uint8_t RESERVED15[3];
+ __IO uint8_t ALHOUR;
+ uint8_t RESERVED16[3];
+ __IO uint8_t ALDOM;
+ uint8_t RESERVED17[3];
+ __IO uint8_t ALDOW;
+ uint8_t RESERVED18[3];
+ __IO uint16_t ALDOY;
+ uint16_t RESERVED19;
+ __IO uint8_t ALMON;
+ uint8_t RESERVED20[3];
+ __IO uint16_t ALYEAR;
+ uint16_t RESERVED21;
+} RTC_TypeDef;
+
+
+/*------------- Watchdog Timer (WDT) -----------------------------------------*/
+/**
+ * @brief Watchdog Timer Structure Type Definition
+ */
+typedef struct
+{
+ __IO uint8_t WDMOD;
+ uint8_t RESERVED0[3];
+ __IO uint32_t WDTC;
+ __O uint8_t WDFEED;
+ uint8_t RESERVED1[3];
+ __I uint32_t WDTV;
+ __IO uint32_t WDCLKSEL;
+} WDT_TypeDef;
+
+/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/
+/**
+ * @brief Analog to Digital Structure Type Definition
+ */
+typedef struct
+{
+ __IO uint32_t ADCR;
+ __IO uint32_t ADGDR;
+#ifndef __LPC17XX_REV00
+ uint32_t RESERVED0;
+#endif
+ __IO uint32_t ADINTEN;
+ __I uint32_t ADDR0;
+ __I uint32_t ADDR1;
+ __I uint32_t ADDR2;
+ __I uint32_t ADDR3;
+ __I uint32_t ADDR4;
+ __I uint32_t ADDR5;
+ __I uint32_t ADDR6;
+ __I uint32_t ADDR7;
+ __I uint32_t ADSTAT;
+ __IO uint32_t ADTRM;
+} ADC_TypeDef;
+
+
+/*------------- Digital-to-Analog Converter (DAC) ----------------------------*/
+/**
+ * @brief Digital to Analog Structure Type Definition
+ */
+typedef struct
+{
+ __IO uint32_t DACR;
+ __IO uint32_t DACCTRL;
+ __IO uint16_t DACCNTVAL;
+} DAC_TypeDef;
+
+/*------------- Motor Control Pulse-Width Modulation (MCPWM) -----------------*/
+/**
+ * @brief Motor Control Pulse Width Modulation Structure Type Definition
+ */
+typedef struct
+{
+ __I uint32_t MCCON;
+ __O uint32_t MCCON_SET;
+ __O uint32_t MCCON_CLR;
+ __I uint32_t MCCAPCON;
+ __O uint32_t MCCAPCON_SET;
+ __O uint32_t MCCAPCON_CLR;
+ __IO uint32_t MCTIM0;
+ __IO uint32_t MCTIM1;
+ __IO uint32_t MCTIM2;
+ __IO uint32_t MCPER0;
+ __IO uint32_t MCPER1;
+ __IO uint32_t MCPER2;
+ __IO uint32_t MCPW0;
+ __IO uint32_t MCPW1;
+ __IO uint32_t MCPW2;
+ __IO uint32_t MCDEADTIME;
+ __IO uint32_t MCCCP;
+ __IO uint32_t MCCR0;
+ __IO uint32_t MCCR1;
+ __IO uint32_t MCCR2;
+ __I uint32_t MCINTEN;
+ __O uint32_t MCINTEN_SET;
+ __O uint32_t MCINTEN_CLR;
+ __I uint32_t MCCNTCON;
+ __O uint32_t MCCNTCON_SET;
+ __O uint32_t MCCNTCON_CLR;
+ __I uint32_t MCINTFLAG;
+ __O uint32_t MCINTFLAG_SET;
+ __O uint32_t MCINTFLAG_CLR;
+ __O uint32_t MCCAP_CLR;
+} MCPWM_TypeDef;
+
+/*------------- Quadrature Encoder Interface (QEI) ---------------------------*/
+/**
+ * @brief Quadrature Encoder Interface Structure Type Definition
+ */
+typedef struct
+{
+ __O uint32_t QEICON;
+ __I uint32_t QEISTAT;
+ __IO uint32_t QEICONF;
+ __I uint32_t QEIPOS;
+ __IO uint32_t QEIMAXPOS;
+ __IO uint32_t CMPOS0;
+ __IO uint32_t CMPOS1;
+ __IO uint32_t CMPOS2;
+ __I uint32_t INXCNT;
+ __IO uint32_t INXCMP;
+ __IO uint32_t QEILOAD;
+ __I uint32_t QEITIME;
+ __I uint32_t QEIVEL;
+ __I uint32_t QEICAP;
+ __IO uint32_t VELCOMP;
+ __IO uint32_t FILTER;
+ uint32_t RESERVED0[998];
+ __O uint32_t QEIIEC;
+ __O uint32_t QEIIES;
+ __I uint32_t QEIINTSTAT;
+ __I uint32_t QEIIE;
+ __O uint32_t QEICLR;
+ __O uint32_t QEISET;
+} QEI_TypeDef;
+
+/*------------- Controller Area Network (CAN) --------------------------------*/
+/**
+ * @brief Control Area Network Structure Type Definition
+ */
+typedef struct
+{
+ __IO uint32_t mask[512]; /* ID Masks */
+} CANAF_RAM_TypeDef;
+
+/**
+ * @brief Acceptance Filter Structure Type Definition
+ */
+typedef struct /* Acceptance Filter Registers */
+{
+ __IO uint32_t AFMR;
+ __IO uint32_t SFF_sa;
+ __IO uint32_t SFF_GRP_sa;
+ __IO uint32_t EFF_sa;
+ __IO uint32_t EFF_GRP_sa;
+ __IO uint32_t ENDofTable;
+ __I uint32_t LUTerrAd;
+ __I uint32_t LUTerr;
+ __IO uint32_t FCANIE;
+ __I uint32_t FCANIC0;
+ __I uint32_t FCANIC1;
+} CANAF_TypeDef;
+
+/**
+ * @brief CAN Central Structure Type Definition
+ */
+typedef struct /* Central Registers */
+{
+ __I uint32_t CANTxSR;
+ __I uint32_t CANRxSR;
+ __I uint32_t CANMSR;
+} CANCR_TypeDef;
+
+/**
+ * @brief CAN Controller Structure Type Definition
+ */
+typedef struct /* Controller Registers */
+{
+ __IO uint32_t MOD;
+ __O uint32_t CMR;
+ __IO uint32_t GSR;
+ __I uint32_t ICR;
+ __IO uint32_t IER;
+ __IO uint32_t BTR;
+ __IO uint32_t EWL;
+ __I uint32_t SR;
+ __IO uint32_t RFS;
+ __IO uint32_t RID;
+ __IO uint32_t RDA;
+ __IO uint32_t RDB;
+ __IO uint32_t TFI1;
+ __IO uint32_t TID1;
+ __IO uint32_t TDA1;
+ __IO uint32_t TDB1;
+ __IO uint32_t TFI2;
+ __IO uint32_t TID2;
+ __IO uint32_t TDA2;
+ __IO uint32_t TDB2;
+ __IO uint32_t TFI3;
+ __IO uint32_t TID3;
+ __IO uint32_t TDA3;
+ __IO uint32_t TDB3;
+} CAN_TypeDef;
+
+/*------------- General Purpose Direct Memory Access (GPDMA) -----------------*/
+/**
+ * @brief General Purpose Direct Memory Access Structure Type Definition
+ */
+typedef struct /* Common Registers */
+{
+ __I uint32_t DMACIntStat;
+ __I uint32_t DMACIntTCStat;
+ __O uint32_t DMACIntTCClear;
+ __I uint32_t DMACIntErrStat;
+ __O uint32_t DMACIntErrClr;
+ __I uint32_t DMACRawIntTCStat;
+ __I uint32_t DMACRawIntErrStat;
+ __I uint32_t DMACEnbldChns;
+ __IO uint32_t DMACSoftBReq;
+ __IO uint32_t DMACSoftSReq;
+ __IO uint32_t DMACSoftLBReq;
+ __IO uint32_t DMACSoftLSReq;
+ __IO uint32_t DMACConfig;
+ __IO uint32_t DMACSync;
+} GPDMA_TypeDef;
+
+/**
+ * @brief GPDMA Channel Structure Type Definition
+ */
+typedef struct /* Channel Registers */
+{
+ __IO uint32_t DMACCSrcAddr;
+ __IO uint32_t DMACCDestAddr;
+ __IO uint32_t DMACCLLI;
+ __IO uint32_t DMACCControl;
+ __IO uint32_t DMACCConfig;
+} GPDMACH_TypeDef;
+
+
+/*------------- Universal Serial Bus (USB) -----------------------------------*/
+/**
+ * @brief Universal Serial Bus Structure Type Definition
+ */
+typedef struct
+{
+ __I uint32_t HcRevision; /* USB Host Registers */
+ __IO uint32_t HcControl;
+ __IO uint32_t HcCommandStatus;
+ __IO uint32_t HcInterruptStatus;
+ __IO uint32_t HcInterruptEnable;
+ __IO uint32_t HcInterruptDisable;
+ __IO uint32_t HcHCCA;
+ __I uint32_t HcPeriodCurrentED;
+ __IO uint32_t HcControlHeadED;
+ __IO uint32_t HcControlCurrentED;
+ __IO uint32_t HcBulkHeadED;
+ __IO uint32_t HcBulkCurrentED;
+ __I uint32_t HcDoneHead;
+ __IO uint32_t HcFmInterval;
+ __I uint32_t HcFmRemaining;
+ __I uint32_t HcFmNumber;
+ __IO uint32_t HcPeriodicStart;
+ __IO uint32_t HcLSTreshold;
+ __IO uint32_t HcRhDescriptorA;
+ __IO uint32_t HcRhDescriptorB;
+ __IO uint32_t HcRhStatus;
+ __IO uint32_t HcRhPortStatus1;
+ __IO uint32_t HcRhPortStatus2;
+ uint32_t RESERVED0[40];
+ __I uint32_t Module_ID;
+
+ __I uint32_t OTGIntSt; /* USB On-The-Go Registers */
+ __IO uint32_t OTGIntEn;
+ __O uint32_t OTGIntSet;
+ __O uint32_t OTGIntClr;
+ __IO uint32_t OTGStCtrl;
+ __IO uint32_t OTGTmr;
+ uint32_t RESERVED1[58];
+
+ __I uint32_t USBDevIntSt; /* USB Device Interrupt Registers */
+ __IO uint32_t USBDevIntEn;
+ __O uint32_t USBDevIntClr;
+ __O uint32_t USBDevIntSet;
+
+ __O uint32_t USBCmdCode; /* USB Device SIE Command Registers */
+ __I uint32_t USBCmdData;
+
+ __I uint32_t USBRxData; /* USB Device Transfer Registers */
+ __O uint32_t USBTxData;
+ __I uint32_t USBRxPLen;
+ __O uint32_t USBTxPLen;
+ __IO uint32_t USBCtrl;
+ __O uint32_t USBDevIntPri;
+
+ __I uint32_t USBEpIntSt; /* USB Device Endpoint Interrupt Regs */
+ __IO uint32_t USBEpIntEn;
+ __O uint32_t USBEpIntClr;
+ __O uint32_t USBEpIntSet;
+ __O uint32_t USBEpIntPri;
+
+ __IO uint32_t USBReEp; /* USB Device Endpoint Realization Reg*/
+ __O uint32_t USBEpInd;
+ __IO uint32_t USBMaxPSize;
+
+ __I uint32_t USBDMARSt; /* USB Device DMA Registers */
+ __O uint32_t USBDMARClr;
+ __O uint32_t USBDMARSet;
+ uint32_t RESERVED2[9];
+ __IO uint32_t USBUDCAH;
+ __I uint32_t USBEpDMASt;
+ __O uint32_t USBEpDMAEn;
+ __O uint32_t USBEpDMADis;
+ __I uint32_t USBDMAIntSt;
+ __IO uint32_t USBDMAIntEn;
+ uint32_t RESERVED3[2];
+ __I uint32_t USBEoTIntSt;
+ __O uint32_t USBEoTIntClr;
+ __O uint32_t USBEoTIntSet;
+ __I uint32_t USBNDDRIntSt;
+ __O uint32_t USBNDDRIntClr;
+ __O uint32_t USBNDDRIntSet;
+ __I uint32_t USBSysErrIntSt;
+ __O uint32_t USBSysErrIntClr;
+ __O uint32_t USBSysErrIntSet;
+ uint32_t RESERVED4[15];
+
+ __I uint32_t I2C_RX; /* USB OTG I2C Registers */
+ __O uint32_t I2C_WO;
+ __I uint32_t I2C_STS;
+ __IO uint32_t I2C_CTL;
+ __IO uint32_t I2C_CLKHI;
+ __O uint32_t I2C_CLKLO;
+ uint32_t RESERVED5[823];
+
+ union {
+ __IO uint32_t USBClkCtrl; /* USB Clock Control Registers */
+ __IO uint32_t OTGClkCtrl;
+ };
+ union {
+ __I uint32_t USBClkSt;
+ __I uint32_t OTGClkSt;
+ };
+} USB_TypeDef;
+
+/*------------- Ethernet Media Access Controller (EMAC) ----------------------*/
+/**
+ * @brief Ethernet Media Access Controller Structure Type Definition
+ */
+typedef struct
+{
+ __IO uint32_t MAC1; /* MAC Registers */
+ __IO uint32_t MAC2;
+ __IO uint32_t IPGT;
+ __IO uint32_t IPGR;
+ __IO uint32_t CLRT;
+ __IO uint32_t MAXF;
+ __IO uint32_t SUPP;
+ __IO uint32_t TEST;
+ __IO uint32_t MCFG;
+ __IO uint32_t MCMD;
+ __IO uint32_t MADR;
+ __O uint32_t MWTD;
+ __I uint32_t MRDD;
+ __I uint32_t MIND;
+ uint32_t RESERVED0[2];
+ __IO uint32_t SA0;
+ __IO uint32_t SA1;
+ __IO uint32_t SA2;
+ uint32_t RESERVED1[45];
+ __IO uint32_t Command; /* Control Registers */
+ __I uint32_t Status;
+ __IO uint32_t RxDescriptor;
+ __IO uint32_t RxStatus;
+ __IO uint32_t RxDescriptorNumber;
+ __I uint32_t RxProduceIndex;
+ __IO uint32_t RxConsumeIndex;
+ __IO uint32_t TxDescriptor;
+ __IO uint32_t TxStatus;
+ __IO uint32_t TxDescriptorNumber;
+ __IO uint32_t TxProduceIndex;
+ __I uint32_t TxConsumeIndex;
+ uint32_t RESERVED2[10];
+ __I uint32_t TSV0;
+ __I uint32_t TSV1;
+ __I uint32_t RSV;
+ uint32_t RESERVED3[3];
+ __IO uint32_t FlowControlCounter;
+ __I uint32_t FlowControlStatus;
+ uint32_t RESERVED4[34];
+ __IO uint32_t RxFilterCtrl; /* Rx Filter Registers */
+ __IO uint32_t RxFilterWoLStatus;
+ __IO uint32_t RxFilterWoLClear;
+ uint32_t RESERVED5;
+ __IO uint32_t HashFilterL;
+ __IO uint32_t HashFilterH;
+ uint32_t RESERVED6[882];
+ __I uint32_t IntStatus; /* Module Control Registers */
+ __IO uint32_t IntEnable;
+ __O uint32_t IntClear;
+ __O uint32_t IntSet;
+ uint32_t RESERVED7;
+ __IO uint32_t PowerDown;
+ uint32_t RESERVED8;
+ __IO uint32_t Module_ID;
+} EMAC_TypeDef;
+
+//#ifndef __IAR_SYSTEMS_ICC__
+//#pragma no_anon_unions
+//#endif
+
+/**
+ * @}
+ */
+
+
+/** @addtogroup Peripheral_memory_map
+ * @{
+ */
+
+/******************************************************************************/
+/* Peripheral memory map */
+/******************************************************************************/
+/* Base addresses */
+#define FLASH_BASE (0x00000000UL)
+#define RAM_BASE (0x10000000UL)
+#ifdef __LPC17XX_REV00
+#define AHBRAM0_BASE (0x20000000UL)
+#define AHBRAM1_BASE (0x20004000UL)
+#else
+#define AHBRAM0_BASE (0x2007C000UL)
+#define AHBRAM1_BASE (0x20080000UL)
+#define GPIO_BASE (0x2009C000UL)
+#endif
+#define APB0_BASE (0x40000000UL)
+#define APB1_BASE (0x40080000UL)
+#define AHB_BASE (0x50000000UL)
+#define CM3_BASE (0xE0000000UL)
+
+#ifdef __LPC17XX_REV00
+#define GPIO_BASE (AHB_BASE + 0x14000)
+#endif
+
+/* APB0 peripherals */
+#define WDT_BASE (APB0_BASE + 0x00000)
+#define TIM0_BASE (APB0_BASE + 0x04000)
+#define TIM1_BASE (APB0_BASE + 0x08000)
+#define UART0_BASE (APB0_BASE + 0x0C000)
+#define UART1_BASE (APB0_BASE + 0x10000)
+#define PWM1_BASE (APB0_BASE + 0x18000)
+#define I2C0_BASE (APB0_BASE + 0x1C000)
+#define SPI_BASE (APB0_BASE + 0x20000)
+#define RTC_BASE (APB0_BASE + 0x24000)
+#define GPIOINT_BASE (APB0_BASE + 0x28080)
+#define PINCON_BASE (APB0_BASE + 0x2C000)
+#define SSP1_BASE (APB0_BASE + 0x30000)
+#define ADC_BASE (APB0_BASE + 0x34000)
+#define CANAF_RAM_BASE (APB0_BASE + 0x38000)
+#define CANAF_BASE (APB0_BASE + 0x3C000)
+#define CANCR_BASE (APB0_BASE + 0x40000)
+#define CAN1_BASE (APB0_BASE + 0x44000)
+#define CAN2_BASE (APB0_BASE + 0x48000)
+#define I2C1_BASE (APB0_BASE + 0x5C000)
+
+/* APB1 peripherals */
+#define SSP0_BASE (APB1_BASE + 0x08000)
+#define DAC_BASE (APB1_BASE + 0x0C000)
+#define TIM2_BASE (APB1_BASE + 0x10000)
+#define TIM3_BASE (APB1_BASE + 0x14000)
+#define UART2_BASE (APB1_BASE + 0x18000)
+#define UART3_BASE (APB1_BASE + 0x1C000)
+#define I2C2_BASE (APB1_BASE + 0x20000)
+#define I2S_BASE (APB1_BASE + 0x28000)
+#define RIT_BASE (APB1_BASE + 0x30000)
+#define MCPWM_BASE (APB1_BASE + 0x38000)
+#define QEI_BASE (APB1_BASE + 0x3C000)
+#define SC_BASE (APB1_BASE + 0x7C000)
+
+/* AHB peripherals */
+#define EMAC_BASE (AHB_BASE + 0x00000)
+#define GPDMA_BASE (AHB_BASE + 0x04000)
+#define GPDMACH0_BASE (AHB_BASE + 0x04100)
+#define GPDMACH1_BASE (AHB_BASE + 0x04120)
+#define GPDMACH2_BASE (AHB_BASE + 0x04140)
+#define GPDMACH3_BASE (AHB_BASE + 0x04160)
+#define GPDMACH4_BASE (AHB_BASE + 0x04180)
+#define GPDMACH5_BASE (AHB_BASE + 0x041A0)
+#define GPDMACH6_BASE (AHB_BASE + 0x041C0)
+#define GPDMACH7_BASE (AHB_BASE + 0x041E0)
+#define USB_BASE (AHB_BASE + 0x0C000)
+
+/* GPIOs */
+#define GPIO0_BASE (GPIO_BASE + 0x00000)
+#define GPIO1_BASE (GPIO_BASE + 0x00020)
+#define GPIO2_BASE (GPIO_BASE + 0x00040)
+#define GPIO3_BASE (GPIO_BASE + 0x00060)
+#define GPIO4_BASE (GPIO_BASE + 0x00080)
+
+/**
+ * @}
+ */
+
+
+/** @addtogroup Peripheral_declaration
+ * @{
+ */
+
+/******************************************************************************/
+/* Peripheral declaration */
+/******************************************************************************/
+#define SC (( SC_TypeDef *) SC_BASE)
+#define GPIO0 (( GPIO_TypeDef *) GPIO0_BASE)
+#define GPIO1 (( GPIO_TypeDef *) GPIO1_BASE)
+#define GPIO2 (( GPIO_TypeDef *) GPIO2_BASE)
+#define GPIO3 (( GPIO_TypeDef *) GPIO3_BASE)
+#define GPIO4 (( GPIO_TypeDef *) GPIO4_BASE)
+#define WDT (( WDT_TypeDef *) WDT_BASE)
+#define TIM0 (( TIM_TypeDef *) TIM0_BASE)
+#define TIM1 (( TIM_TypeDef *) TIM1_BASE)
+#define TIM2 (( TIM_TypeDef *) TIM2_BASE)
+#define TIM3 (( TIM_TypeDef *) TIM3_BASE)
+#define RIT (( RIT_TypeDef *) RIT_BASE)
+#define UART0 (( UART_TypeDef *) UART0_BASE)
+#define UART1 (( UART1_TypeDef *) UART1_BASE)
+#define UART2 (( UART_TypeDef *) UART2_BASE)
+#define UART3 (( UART_TypeDef *) UART3_BASE)
+#define PWM1 (( PWM_TypeDef *) PWM1_BASE)
+#define I2C0 (( I2C_TypeDef *) I2C0_BASE)
+#define I2C1 (( I2C_TypeDef *) I2C1_BASE)
+#define I2C2 (( I2C_TypeDef *) I2C2_BASE)
+#define I2S (( I2S_TypeDef *) I2S_BASE)
+#define SPI (( SPI_TypeDef *) SPI_BASE)
+#define RTC (( RTC_TypeDef *) RTC_BASE)
+#define GPIOINT ((GPIOINT_TypeDef *) GPIOINT_BASE)
+#define PINCON (( PINCON_TypeDef *) PINCON_BASE)
+#define SSP0 (( SSP_TypeDef *) SSP0_BASE)
+#define SSP1 (( SSP_TypeDef *) SSP1_BASE)
+#define ADC (( ADC_TypeDef *) ADC_BASE)
+#define DAC (( DAC_TypeDef *) DAC_BASE)
+#define CANAF_RAM ((CANAF_RAM_TypeDef *)CANAF_RAM_BASE)
+#define CANAF (( CANAF_TypeDef *) CANAF_BASE)
+#define CANCR (( CANCR_TypeDef *) CANCR_BASE)
+#define CAN1 (( CAN_TypeDef *) CAN1_BASE)
+#define CAN2 (( CAN_TypeDef *) CAN2_BASE)
+#define MCPWM (( MCPWM_TypeDef *) MCPWM_BASE)
+#define QEI (( QEI_TypeDef *) QEI_BASE)
+#define EMAC (( EMAC_TypeDef *) EMAC_BASE)
+#define GPDMA (( GPDMA_TypeDef *) GPDMA_BASE)
+#define DMAREQSEL (*(__IO uint32_t *) ( 0x4000C1C4))
+#define GPDMACH0 ((GPDMACH_TypeDef *) GPDMACH0_BASE)
+#define GPDMACH1 ((GPDMACH_TypeDef *) GPDMACH1_BASE)
+#define GPDMACH2 ((GPDMACH_TypeDef *) GPDMACH2_BASE)
+#define GPDMACH3 ((GPDMACH_TypeDef *) GPDMACH3_BASE)
+#define GPDMACH4 ((GPDMACH_TypeDef *) GPDMACH4_BASE)
+#define GPDMACH5 ((GPDMACH_TypeDef *) GPDMACH5_BASE)
+#define GPDMACH6 ((GPDMACH_TypeDef *) GPDMACH6_BASE)
+#define GPDMACH7 ((GPDMACH_TypeDef *) GPDMACH7_BASE)
+#define USB (( USB_TypeDef *) USB_BASE)
+
+/**
+ * @}
+ */
+
+#endif // __LPC17xx_H__
+
+/* End Of File ---------------------------------------------------------------- */
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+include_HEADERS = LPC17xx.h core_cm3.h lpcUSB.h
--- /dev/null
+/****************************************************************************//**
+ * @file : core_cm3.h
+ * @brief : CMSIS Cortex-M3 Core Peripheral Access Layer Header File
+ * @version : V1.20 simplified for GCC only
+ * @date : 31. March 2010
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2009 ARM Limited. All rights reserved.
+ *
+ * ARM Limited (ARM) is supplying this software for use with Cortex-Mx
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+#ifndef __CM3_CORE_H__
+#define __CM3_CORE_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define __CM3_CMSIS_VERSION_MAIN (0x01) /*!< [31:16] CMSIS HAL main version */
+#define __CM3_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */
+#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x03) /*!< Cortex core */
+
+/**
+ * Lint configuration \n
+ * ----------------------- \n
+ *
+ * The following Lint messages will be suppressed and not shown: \n
+ * \n
+ * --- Error 10: --- \n
+ * register uint32_t __regBasePri __asm("basepri"); \n
+ * Error 10: Expecting ';' \n
+ * \n
+ * --- Error 530: --- \n
+ * return(__regBasePri); \n
+ * Warning 530: Symbol '__regBasePri' (line 264) not initialized \n
+ * \n
+ * --- Error 550: --- \n
+ * __regBasePri = (basePri & 0x1ff); \n
+ * } \n
+ * Warning 550: Symbol '__regBasePri' (line 271) not accessed \n
+ * \n
+ * --- Error 754: --- \n
+ * uint32_t RESERVED0[24]; \n
+ * Info 754: local structure member '<some, not used in the HAL>' (line 109, file ./cm3_core.h) not referenced \n
+ * \n
+ * --- Error 750: --- \n
+ * #define __CM3_CORE_H__ \n
+ * Info 750: local macro '__CM3_CORE_H__' (line 43, file./cm3_core.h) not referenced \n
+ * \n
+ * --- Error 528: --- \n
+ * static __INLINE void NVIC_DisableIRQ(uint32_t IRQn) \n
+ * Warning 528: Symbol 'NVIC_DisableIRQ(unsigned int)' (line 419, file ./cm3_core.h) not referenced \n
+ * \n
+ * --- Error 751: --- \n
+ * } InterruptType_Type; \n
+ * Info 751: local typedef 'InterruptType_Type' (line 170, file ./cm3_core.h) not referenced \n
+ * \n
+ * \n
+ * Note: To re-enable a Message, insert a space before 'lint' * \n
+ *
+ */
+
+/*lint -save */
+/*lint -e10 */
+/*lint -e530 */
+/*lint -e550 */
+/*lint -e754 */
+/*lint -e750 */
+/*lint -e528 */
+/*lint -e751 */
+
+
+#include <stdint.h> /* Include standard types */
+
+#ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 4 /*!< standard definition for NVIC Priority Bits */
+#endif
+
+
+
+
+/**
+ * IO definitions
+ *
+ * define access restrictions to peripheral registers
+ */
+
+#ifdef __cplusplus
+#define __I volatile /*!< defines 'read only' permissions */
+#else
+#define __I volatile const /*!< defines 'read only' permissions */
+#endif
+#define __O volatile /*!< defines 'write only' permissions */
+#define __IO volatile /*!< defines 'read / write' permissions */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ ******************************************************************************/
+
+
+/* System Reset */
+#define NVIC_VECTRESET 0 /*!< Vector Reset Bit */
+#define NVIC_SYSRESETREQ 2 /*!< System Reset Request */
+#define NVIC_AIRCR_VECTKEY (0x5FA << 16) /*!< AIRCR Key for write access */
+#define NVIC_AIRCR_ENDIANESS 15 /*!< Endianess */
+
+/* Core Debug */
+#define CoreDebug_DEMCR_TRCENA (1 << 24) /*!< DEMCR TRCENA enable */
+#define ITM_TCR_ITMENA 1 /*!< ITM enable */
+
+
+
+
+/* memory mapping struct for Nested Vectored Interrupt Controller (NVIC) */
+typedef struct
+{
+ __IO uint32_t ISER[8]; /*!< Interrupt Set Enable Register */
+ uint32_t RESERVED0[24];
+ __IO uint32_t ICER[8]; /*!< Interrupt Clear Enable Register */
+ uint32_t RSERVED1[24];
+ __IO uint32_t ISPR[8]; /*!< Interrupt Set Pending Register */
+ uint32_t RESERVED2[24];
+ __IO uint32_t ICPR[8]; /*!< Interrupt Clear Pending Register */
+ uint32_t RESERVED3[24];
+ __IO uint32_t IABR[8]; /*!< Interrupt Active bit Register */
+ uint32_t RESERVED4[56];
+ __IO uint8_t IP[240]; /*!< Interrupt Priority Register, 8Bit wide */
+ uint32_t RESERVED5[644];
+ __O uint32_t STIR; /*!< Software Trigger Interrupt Register */
+} NVIC_Type;
+
+
+/* memory mapping struct for System Control Block */
+typedef struct
+{
+ __I uint32_t CPUID; /*!< CPU ID Base Register */
+ __IO uint32_t ICSR; /*!< Interrupt Control State Register */
+ __IO uint32_t VTOR; /*!< Vector Table Offset Register */
+ __IO uint32_t AIRCR; /*!< Application Interrupt / Reset Control Register */
+ __IO uint32_t SCR; /*!< System Control Register */
+ __IO uint32_t CCR; /*!< Configuration Control Register */
+ __IO uint8_t SHP[12]; /*!< System Handlers Priority Registers (4-7, 8-11, 12-15) */
+ __IO uint32_t SHCSR; /*!< System Handler Control and State Register */
+ __IO uint32_t CFSR; /*!< Configurable Fault Status Register */
+ __IO uint32_t HFSR; /*!< Hard Fault Status Register */
+ __IO uint32_t DFSR; /*!< Debug Fault Status Register */
+ __IO uint32_t MMFAR; /*!< Mem Manage Address Register */
+ __IO uint32_t BFAR; /*!< Bus Fault Address Register */
+ __IO uint32_t AFSR; /*!< Auxiliary Fault Status Register */
+ __I uint32_t PFR[2]; /*!< Processor Feature Register */
+ __I uint32_t DFR; /*!< Debug Feature Register */
+ __I uint32_t ADR; /*!< Auxiliary Feature Register */
+ __I uint32_t MMFR[4]; /*!< Memory Model Feature Register */
+ __I uint32_t ISAR[5]; /*!< ISA Feature Register */
+} SCB_Type;
+
+
+/* memory mapping struct for SysTick */
+typedef struct
+{
+ __IO uint32_t CTRL; /*!< SysTick Control and Status Register */
+ __IO uint32_t LOAD; /*!< SysTick Reload Value Register */
+ __IO uint32_t VAL; /*!< SysTick Current Value Register */
+ __I uint32_t CALIB; /*!< SysTick Calibration Register */
+} SysTick_Type;
+
+
+/* memory mapping structur for ITM */
+typedef struct
+{
+ __O union
+ {
+ __O uint8_t u8; /*!< ITM Stimulus Port 8-bit */
+ __O uint16_t u16; /*!< ITM Stimulus Port 16-bit */
+ __O uint32_t u32; /*!< ITM Stimulus Port 32-bit */
+ } PORT [32]; /*!< ITM Stimulus Port Registers */
+ uint32_t RESERVED0[864];
+ __IO uint32_t TER; /*!< ITM Trace Enable Register */
+ uint32_t RESERVED1[15];
+ __IO uint32_t TPR; /*!< ITM Trace Privilege Register */
+ uint32_t RESERVED2[15];
+ __IO uint32_t TCR; /*!< ITM Trace Control Register */
+ uint32_t RESERVED3[29];
+ __IO uint32_t IWR; /*!< ITM Integration Write Register */
+ __IO uint32_t IRR; /*!< ITM Integration Read Register */
+ __IO uint32_t IMCR; /*!< ITM Integration Mode Control Register */
+ uint32_t RESERVED4[43];
+ __IO uint32_t LAR; /*!< ITM Lock Access Register */
+ __IO uint32_t LSR; /*!< ITM Lock Status Register */
+ uint32_t RESERVED5[6];
+ __I uint32_t PID4; /*!< ITM Product ID Registers */
+ __I uint32_t PID5;
+ __I uint32_t PID6;
+ __I uint32_t PID7;
+ __I uint32_t PID0;
+ __I uint32_t PID1;
+ __I uint32_t PID2;
+ __I uint32_t PID3;
+ __I uint32_t CID0;
+ __I uint32_t CID1;
+ __I uint32_t CID2;
+ __I uint32_t CID3;
+} ITM_Type;
+
+
+/* memory mapped struct for Interrupt Type */
+typedef struct
+{
+ uint32_t RESERVED0;
+ __I uint32_t ICTR; /*!< Interrupt Control Type Register */
+#if ((defined __CM3_REV) && (__CM3_REV >= 0x200))
+ __IO uint32_t ACTLR; /*!< Auxiliary Control Register */
+#else
+ uint32_t RESERVED1;
+#endif
+} InterruptType_Type;
+
+
+/* Memory Protection Unit */
+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)
+typedef struct
+{
+ __I uint32_t TYPE; /*!< MPU Type Register */
+ __IO uint32_t CTRL; /*!< MPU Control Register */
+ __IO uint32_t RNR; /*!< MPU Region RNRber Register */
+ __IO uint32_t RBAR; /*!< MPU Region Base Address Register */
+ __IO uint32_t RASR; /*!< MPU Region Attribute and Size Register */
+ __IO uint32_t RBAR_A1; /*!< MPU Alias 1 Region Base Address Register */
+ __IO uint32_t RASR_A1; /*!< MPU Alias 1 Region Attribute and Size Register */
+ __IO uint32_t RBAR_A2; /*!< MPU Alias 2 Region Base Address Register */
+ __IO uint32_t RASR_A2; /*!< MPU Alias 2 Region Attribute and Size Register */
+ __IO uint32_t RBAR_A3; /*!< MPU Alias 3 Region Base Address Register */
+ __IO uint32_t RASR_A3; /*!< MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+#endif
+
+
+/* Core Debug Register */
+typedef struct
+{
+ __IO uint32_t DHCSR; /*!< Debug Halting Control and Status Register */
+ __O uint32_t DCRSR; /*!< Debug Core Register Selector Register */
+ __IO uint32_t DCRDR; /*!< Debug Core Register Data Register */
+ __IO uint32_t DEMCR; /*!< Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+
+/* Memory mapping of Cortex-M3 Hardware */
+#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */
+#define ITM_BASE (0xE0000000) /*!< ITM Base Address */
+#define CoreDebug_BASE (0xE000EDF0) /*!< Core Debug Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00) /*!< System Control Block Base Address */
+
+#define InterruptType ((InterruptType_Type *) SCS_BASE) /*!< Interrupt Type Register */
+#define SCB ((SCB_Type *) SCB_BASE) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE) /*!< NVIC configuration struct */
+#define ITM ((ITM_Type *) ITM_BASE) /*!< ITM configuration struct */
+#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */
+
+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)
+ #define MPU_BASE (SCS_BASE + 0x0D90) /*!< Memory Protection Unit */
+ #define MPU ((MPU_Type*) MPU_BASE) /*!< Memory Protection Unit */
+#endif
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ ******************************************************************************/
+
+
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+
+/* ################### Compiler specific Intrinsics ########################### */
+
+/* GNU gcc specific functions */
+
+static __INLINE void __enable_irq() { __ASM volatile ("cpsie i"); }
+static __INLINE void __disable_irq() { __ASM volatile ("cpsid i"); }
+
+static __INLINE void __enable_fault_irq() { __ASM volatile ("cpsie f"); }
+static __INLINE void __disable_fault_irq() { __ASM volatile ("cpsid f"); }
+
+static __INLINE void __NOP() { __ASM volatile ("nop"); }
+static __INLINE void __WFI() { __ASM volatile ("wfi"); }
+static __INLINE void __WFE() { __ASM volatile ("wfe"); }
+static __INLINE void __SEV() { __ASM volatile ("sev"); }
+static __INLINE void __ISB() { __ASM volatile ("isb"); }
+static __INLINE void __DSB() { __ASM volatile ("dsb"); }
+static __INLINE void __DMB() { __ASM volatile ("dmb"); }
+static __INLINE void __CLREX() { __ASM volatile ("clrex"); }
+
+
+/**
+ * @brief Return the Process Stack Pointer
+ *
+ * @param none
+ * @return uint32_t ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+static __INLINE uint32_t __get_PSP(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, psp" : "=r" (result) );
+ return(result);
+}
+
+/**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param uint32_t Process Stack Pointer
+ * @return none
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+static __INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+ __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) );
+}
+
+/**
+ * @brief Return the Main Stack Pointer
+ *
+ * @param none
+ * @return uint32_t Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+static __INLINE uint32_t __get_MSP(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, msp" : "=r" (result) );
+ return(result);
+}
+
+/**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param uint32_t Main Stack Pointer
+ * @return none
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+static __INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+ __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) );
+}
+
+/**
+ * @brief Return the Base Priority value
+ *
+ * @param none
+ * @return uint32_t BasePriority
+ *
+ * Return the content of the base priority register
+ */
+static __INLINE uint32_t __get_BASEPRI(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ * @brief Set the Base Priority value
+ *
+ * @param uint32_t BasePriority
+ * @return none
+ *
+ * Set the base priority register
+ */
+static __INLINE void __set_BASEPRI(uint32_t value)
+{
+ __ASM volatile ("MSR basepri, %0" : : "r" (value) );
+}
+
+/**
+ * @brief Return the Priority Mask value
+ *
+ * @param none
+ * @return uint32_t PriMask
+ *
+ * Return the state of the priority mask bit from the priority mask
+ * register
+ */
+static __INLINE uint32_t __get_PRIMASK(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, primask" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ * @brief Set the Priority Mask value
+ *
+ * @param uint32_t PriMask
+ * @return none
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+static __INLINE void __set_PRIMASK(uint32_t priMask)
+{
+ __ASM volatile ("MSR primask, %0" : : "r" (priMask) );
+}
+
+
+/**
+ * @brief Return the Fault Mask value
+ *
+ * @param none
+ * @return uint32_t FaultMask
+ *
+ * Return the content of the fault mask register
+ */
+static __INLINE uint32_t __get_FAULTMASK(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ * @brief Set the Fault Mask value
+ *
+ * @param uint32_t faultMask value
+ * @return none
+ *
+ * Set the fault mask register
+ */
+static __INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+ __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
+}
+
+/**
+ * @brief Return the Control Register value
+*
+* @param none
+* @return uint32_t Control value
+ *
+ * Return the content of the control register
+ */
+static __INLINE uint32_t __get_CONTROL(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, control" : "=r" (result) );
+ return(result);
+}
+
+/**
+ * @brief Set the Control Register value
+ *
+ * @param uint32_t Control value
+ * @return none
+ *
+ * Set the control register
+ */
+static __INLINE void __set_CONTROL(uint32_t control)
+{
+ __ASM volatile ("MSR control, %0" : : "r" (control) );
+}
+
+/**
+ * @brief Reverse byte order in integer value
+ *
+ * @param uint32_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in integer value
+ */
+static __INLINE uint32_t __REV(uint32_t value)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param uint16_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+static __INLINE uint32_t __REV16(uint16_t value)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+/**
+ * Reverse byte order in signed short value with sign extension to integer
+ *
+ * @param int16_t value to reverse
+ * @return int32_t reversed value
+ *
+ * @brief Reverse byte order in signed short value with sign extension to integer
+ */
+static __INLINE int32_t __REVSH(int16_t value)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief Reverse bit order of value
+ *
+ * @param uint32_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse bit order of value
+ */
+static __INLINE uint32_t __RBIT(uint32_t value)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief LDR Exclusive
+ *
+ * @param uint8_t* address
+ * @return uint8_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+static __INLINE uint8_t __LDREXB(uint8_t *addr)
+{
+ uint8_t result=0;
+
+ __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
+ return(result);
+}
+
+/**
+ * @brief LDR Exclusive
+ *
+ * @param uint16_t* address
+ * @return uint16_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+static __INLINE uint16_t __LDREXH(uint16_t *addr)
+{
+ uint16_t result=0;
+
+ __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
+ return(result);
+}
+
+/**
+ * @brief LDR Exclusive
+ *
+ * @param uint32_t* address
+ * @return uint32_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+static __INLINE uint32_t __LDREXW(uint32_t *addr)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
+ return(result);
+}
+
+/**
+ * @brief STR Exclusive
+ *
+ * @param uint8_t *address
+ * @param uint8_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+static __INLINE uint32_t __STREXB(uint8_t value, uint8_t *addr)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief STR Exclusive
+ *
+ * @param uint16_t *address
+ * @param uint16_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+static __INLINE uint32_t __STREXH(uint16_t value, uint16_t *addr)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief STR Exclusive
+ *
+ * @param uint32_t *address
+ * @param uint32_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+static __INLINE uint32_t __STREXW(uint32_t value, uint32_t *addr)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
+ return(result);
+}
+
+
+/* ########################## NVIC functions #################################### */
+
+
+/**
+ * @brief Set the Priority Grouping in NVIC Interrupt Controller
+ *
+ * @param uint32_t priority_grouping is priority grouping field
+ * @return none
+ *
+ * Set the priority grouping field using the required unlock sequence.
+ * The parameter priority_grouping is assigned to the field
+ * SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used.
+ * In case of a conflict between priority grouping and available
+ * priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+ */
+static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+ uint32_t reg_value;
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+
+ reg_value = SCB->AIRCR; /* read old register configuration */
+ reg_value &= ~((0xFFFFU << 16) | (0x0F << 8)); /* clear bits to change */
+ reg_value = ((reg_value | NVIC_AIRCR_VECTKEY | (PriorityGroupTmp << 8))); /* Insert write key and priorty group */
+ SCB->AIRCR = reg_value;
+}
+
+/**
+ * @brief Get the Priority Grouping from NVIC Interrupt Controller
+ *
+ * @param none
+ * @return uint32_t priority grouping field
+ *
+ * Get the priority grouping from NVIC Interrupt Controller.
+ * priority grouping is SCB->AIRCR [10:8] PRIGROUP field.
+ */
+static __INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+ return ((SCB->AIRCR >> 8) & 0x07); /* read priority grouping field */
+}
+
+/**
+ * @brief Enable Interrupt in NVIC Interrupt Controller
+ *
+ * @param IRQn_Type IRQn specifies the interrupt number
+ * @return none
+ *
+ * Enable a device specific interupt in the NVIC interrupt controller.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
+}
+
+/**
+ * @brief Disable the interrupt line for external interrupt specified
+ *
+ * @param IRQn_Type IRQn is the positive number of the external interrupt
+ * @return none
+ *
+ * Disable a device specific interupt in the NVIC interrupt controller.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */
+}
+
+/**
+ * @brief Read the interrupt pending bit for a device specific interrupt source
+ *
+ * @param IRQn_Type IRQn is the number of the device specifc interrupt
+ * @return uint32_t 1 if pending interrupt else 0
+ *
+ * Read the pending register in NVIC and return 1 if its status is pending,
+ * otherwise it returns 0
+ */
+static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */
+}
+
+/**
+ * @brief Set the pending bit for an external interrupt
+ *
+ * @param IRQn_Type IRQn is the Number of the interrupt
+ * @return none
+ *
+ * Set the pending bit for the specified interrupt.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */
+}
+
+/**
+ * @brief Clear the pending bit for an external interrupt
+ *
+ * @param IRQn_Type IRQn is the Number of the interrupt
+ * @return none
+ *
+ * Clear the pending bit for the specified interrupt.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+/**
+ * @brief Read the active bit for an external interrupt
+ *
+ * @param IRQn_Type IRQn is the Number of the interrupt
+ * @return uint32_t 1 if active else 0
+ *
+ * Read the active register in NVIC and returns 1 if its status is active,
+ * otherwise it returns 0.
+ */
+static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+ return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */
+}
+
+/**
+ * @brief Set the priority for an interrupt
+ *
+ * @param IRQn_Type IRQn is the Number of the interrupt
+ * @param priority is the priority for the interrupt
+ * @return none
+ *
+ * Set the priority for the specified interrupt. The interrupt
+ * number can be positive to specify an external (device specific)
+ * interrupt, or negative to specify an internal (core) interrupt. \n
+ *
+ * Note: The priority cannot be set for every core interrupt.
+ */
+static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if(IRQn < 0) {
+ SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
+ else {
+ NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */
+}
+
+/**
+ * @brief Read the priority for an interrupt
+ *
+ * @param IRQn_Type IRQn is the Number of the interrupt
+ * @return uint32_t priority is the priority for the interrupt
+ *
+ * Read the priority for the specified interrupt. The interrupt
+ * number can be positive to specify an external (device specific)
+ * interrupt, or negative to specify an internal (core) interrupt.
+ *
+ * The returned priority value is automatically aligned to the implemented
+ * priority bits of the microcontroller.
+ *
+ * Note: The priority cannot be set for every core interrupt.
+ */
+static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if(IRQn < 0) {
+ return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M3 system interrupts */
+ else {
+ return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
+}
+
+
+/**
+ * @brief Encode the priority for an interrupt
+ *
+ * @param uint32_t PriorityGroup is the used priority group
+ * @param uint32_t PreemptPriority is the preemptive priority value (starting from 0)
+ * @param uint32_t SubPriority is the sub priority value (starting from 0)
+ * @return uint32_t the priority for the interrupt
+ *
+ * Encode the priority for an interrupt with the given priority group,
+ * preemptive priority value and sub priority value.
+ * In case of a conflict between priority grouping and available
+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+ *
+ * The returned priority value can be used for NVIC_SetPriority(...) function
+ */
+static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+ return (
+ ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
+ ((SubPriority & ((1 << (SubPriorityBits )) - 1)))
+ );
+}
+
+
+/**
+ * @brief Decode the priority of an interrupt
+ *
+ * @param uint32_t Priority the priority for the interrupt
+ * @param uint32_t PrioGroup is the used priority group
+ * @param uint32_t* pPreemptPrio is the preemptive priority value (starting from 0)
+ * @param uint32_t* pSubPrio is the sub priority value (starting from 0)
+ * @return none
+ *
+ * Decode an interrupt priority value with the given priority group to
+ * preemptive priority value and sub priority value.
+ * In case of a conflict between priority grouping and available
+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+ *
+ * The priority value can be retrieved with NVIC_GetPriority(...) function
+ */
+static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+ *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);
+ *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1);
+}
+
+
+
+/* ################################## SysTick function ############################################ */
+
+#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0)
+
+/* SysTick constants */
+#define SYSTICK_ENABLE 0 /* Config-Bit to start or stop the SysTick Timer */
+#define SYSTICK_TICKINT 1 /* Config-Bit to enable or disable the SysTick interrupt */
+#define SYSTICK_CLKSOURCE 2 /* Clocksource has the offset 2 in SysTick Control and Status Register */
+#define SYSTICK_MAXCOUNT ((1<<24) -1) /* SysTick MaxCount */
+
+/**
+ * @brief Initialize and start the SysTick counter and its interrupt.
+ *
+ * @param uint32_t ticks is the number of ticks between two interrupts
+ * @return none
+ *
+ * Initialise the system tick timer and its interrupt and start the
+ * system tick timer / counter in free running mode to generate
+ * periodical interrupts.
+ */
+static __INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if (ticks > SYSTICK_MAXCOUNT) return (1); /* Reload value impossible */
+
+ SysTick->LOAD = (ticks & SYSTICK_MAXCOUNT) - 1; /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
+ SysTick->VAL = (0x00); /* Load the SysTick Counter Value */
+ SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | (1<<SYSTICK_ENABLE) | (1<<SYSTICK_TICKINT); /* Enable SysTick IRQ and SysTick Timer */
+ return (0); /* Function successful */
+}
+
+#endif
+
+
+
+
+
+/* ################################## Reset function ############################################ */
+
+/**
+ * @brief Initiate a system reset request.
+ *
+ * @param none
+ * @return none
+ *
+ * Initialize a system reset request to reset the MCU
+ */
+static __INLINE void NVIC_SystemReset(void)
+{
+ SCB->AIRCR = (NVIC_AIRCR_VECTKEY | (SCB->AIRCR & (0x700)) | (1<<NVIC_SYSRESETREQ)); /* Keep priority group unchanged */
+ __DSB(); /* Ensure completion of memory access */
+ while(1); /* wait until reset */
+}
+
+
+/* ################################## Debug Output function ############################################ */
+
+
+/**
+ * @brief Outputs a character via the ITM channel 0
+ *
+ * @param uint32_t character to output
+ * @return uint32_t input character
+ *
+ * The function outputs a character via the ITM channel 0.
+ * The function returns when no debugger is connected that has booked the output.
+ * It is blocking when a debugger is connected, but the previous character send is not transmitted.
+ */
+static __INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+ if (ch == '\n') ITM_SendChar('\r');
+
+ if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA) &&
+ (ITM->TCR & ITM_TCR_ITMENA) &&
+ (ITM->TER & (1UL << 0)) )
+ {
+ while (ITM->PORT[0].u32 == 0);
+ ITM->PORT[0].u8 = (uint8_t) ch;
+ }
+ return (ch);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CM3_CORE_H__ */
+
+/*lint -restore */
--- /dev/null
+#!/bin/sh
+
+#pdftotext -nopgbrk user.manual.lpc17xx.pdf lpc17xx-um.txt
+
+# 10.1.1 USB Clock Control register (USBClkCtrl - 0x5000 CFF4)
+# #define USBDevIntSt_o 0x0000 /* USB Device Interrupt Status (RO) */
+# #define USBDevIntSt (*(REG32*)(USB_REGS_BASE+USBDevIntSt_o))
+
+cat lpc17xx-um.txt | \
+ sed -n -e 's/^[0-9.]* \+\([^(]*\) \+(\([^ ]*\) - 0x5000 C\([^)]*\)).*$/\3@#define \2_o\t0x0\3\t\/* \1 *\/\nx\3@#define \2\t(*(REG32*)(USB_REGS_BASE+\2_o))/p' | \
+ sort -u | sed -e 's/^.*@\(.*\)$/\1/'
+
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * Header file for Philips LPC17xx USB enabled ARM Processors
+ * Copyright 2006-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz>
+ * Based on same author code for LPC214x
+ *
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact or GPL license is applied.
+ *
+ *****************************************************************************/
+
+#ifndef _lpcUSB_H
+#define _lpcUSB_H
+
+#if !defined(REG_8) || !defined(REG16) || !defined(REG32)
+#define REG_8 volatile unsigned char
+#define REG16 volatile unsigned short
+#define REG32 volatile unsigned long
+#endif
+
+/* USBIntSt - USB Interrupt Status (R/W) */
+#define USB_INT_REQ_LP (1<<0) /*Low priority interrupt line status (RO) */
+#define USB_INT_REQ_HP (1<<1) /*High priority interrupt line status. (RO) */
+#define USB_INT_REQ_DMA (1<<2) /*DMA interrupt line status. This bit is read only. (LPC2146/8 only) */
+#define USB_need_clock (1<<8) /*USB need clock indicator*/
+#define USB_EN_USB_INTS (1<<31) /*Enable all USB interrupts*/
+
+/* USB Host Controller Registers */
+#define HcControlHeadED_o 0x0020 /* PADDR of 1st EP desc. of control list (R/W) */
+#define HcControlCurrentED_o 0x0024 /* PADDR of curr. EP desc. of control list (R/W) */
+#define HcBulkHeadED_o 0x0028 /* PADDR of 1st EP desc. of bulk list (R/W) */
+#define HcBulkCurrentED_o 0x002C /* PADDR of curr. EP desc. of bulk list (R/W) */
+#define HcDoneHead_o 0x0030 /* PADDR of the last desct added to Done q. (R) */
+#define HcFmInterval_o 0x0034 /* full speed max frame time (R/W) */
+#define HcFmRemaining_o 0x0038 /* 14-bit counter of remaining in curr. frame (R) */
+#define HcFmNumber_o 0x003C /* 16-bit HC and HDC timing counter (R) */
+#define HcPeriodicStart_o 0x0040 /* 14-bit earliest time to start HC periodic list (R/W) */
+#define HcLSThreshold_o 0x0044 /* 11-bit HC timer for 8-byte LS packet before EOF (R/W) */
+#define HcRhDescriptorA_o 0x0048 /* Characteristics of the root hub - 1st part (R/W) */
+#define HcRhDescriptorB_o 0x004C /* Characteristics of the root hub - 2nd part (R/W) */
+#define HcRhStatus_o 0x0050 /* D-word hub info (low - status, high change) (R/W) */
+#define USB_MODULE_ID_o 0x00FC /* USB Module ID 0x3505yyzz - yy .. ver, zz .. rev (R) */
+
+/* USB On-The-Go Registers */
+#define OTGIntSt_o 0x0100 /* OTG Interrupt Status (RO) */
+#define OTGIntEn_o 0x0104 /* OTG Interrupt Enable (R/W) */
+#define OTGIntSet_o 0x0108 /* OTG Interrupt Clear (WO) */
+#define OTGIntClr_o 0x010C /* OTG Interrupt Clear (WO) */
+#define OTGStCtrl_o 0x0110 /* OTG Status and Control (R/W) */
+#define OTGTmr_o 0x0114 /* OTG Timer (R/W) */
+
+/* Device interrupt registers */
+#define USBDevIntSt_o 0x0200 /* USB Device Interrupt Status(R0) */
+#define USBDevIntEn_o 0x0204 /* USB Device Interrupt Enable (R/W) */
+#define USBDevIntClr_o 0x0208 /* USB Device Interrupt Clear (WO) */
+#define USBDevIntSet_o 0x020C /* USB Device Interrupt Set (WO) */
+#define USBDevInt_FRAME (1<<0) /*Frame interrupt @1kHz for ISO transfers*/
+#define USBDevInt_EP_FAST (1<<1) /*Fast interrupt transfer for the endpoint*/
+#define USBDevInt_EP_SLOW (1<<2) /*Slow interrupt transfer for the endpoint*/
+#define USBDevInt_DEV_STAT (1<<3) /*USB Bus reset, USB suspend change or Connect occured*/
+#define USBDevInt_CCEMTY (1<<4) /*Command code register is empty/ready for CMD*/
+#define USBDevInt_CDFULL (1<<5) /*Command data register is full/data available*/
+#define USBDevInt_RxENDPKT (1<<6) /*Current packet in the FIFO is transferred to the CPU*/
+#define USBDevInt_TxENDPKT (1<<7) /*TxPacket bytes written to FIFO*/
+#define USBDevInt_EP_RLZED (1<<8) /*Endpoints realized after Maxpacket size update*/
+#define USBDevInt_ERR_INT (1<<9) /*Error Interrupt - Use Read Error Status Command 0xFB*/
+#define USBDevIntPri_o 0x022C /* USB Device Interrupt Priority (WO) */
+#define USBDevIntPri_FRAME (1<<0) /*0/1 FRAME int routed to the low/high priority interrupt line*/
+#define USBDevIntPri_EP_FAST (1<<1) /*0/1 EP_FAST int routed to the low/high priority line*/
+
+/* Endpoint interrupt registers - bits corresponds to EP0 to EP31 */
+#define USBEpIntSt_o 0x0230 /* USB Endpoint Interrupt Status (R0) */
+#define USBEpIntEn_o 0x0234 /* USB Endpoint Interrupt Enable (R/W) */
+#define USBEpIntClr_o 0x0238 /* USB Endpoint Interrupt Clear (WO) */
+#define USBEpIntSet_o 0x023C /* USB Endpoint Interrupt Set (WO) */
+#define USBEpIntPri_o 0x0240 /* USB Endpoint Interrupt Priority (WO) */
+/* Endpoint realization registers */
+#define USBReEp_o 0x0244 /* USB Realize Endpoint (R/W) */
+#define USBEpInd_o 0x0248 /* USB Endpoint Index (RO) */
+#define USBEpInd_Ind 0x001F /* Index for subsequent USBMaxPSize (WO) */
+#define USBMaxPSize_o 0x024C /* USB MaxPacketSize (R/W) */
+#define USBMaxPSize_Size 0x03FF /* The maximum packet size value */
+/* USB transfer registers */
+#define USBRxData_o 0x0218 /* USB Receive Data (RO) */
+#define USBRxPLen_o 0x0220 /* USB Receive Packet Length (RO) */
+#define USBRxPLen_PKT_LNGTH (0x03FF) /*Remaining amount of bytes to be read from RAM*/
+#define USBRxPLen_DV (1<<10) /*Data valid. 0 only for error ISO packet*/
+#define USBRxPLen_PKT_RDY (1<<11) /*Packet length valid and packet is ready for reading*/
+#define USBTxData_o 0x021C /* USB Transmit Data (WO) */
+#define USBTxPLen_o 0x0224 /* USB Transmit Packet Length (WO) */
+#define USBTxPLen_PKT_LNGTH (0x03FF) /*Remaining amount of bytes to be written to the EP_RAM*/
+#define USBCtrl_o 0x0228 /* USB Control (R/W) */
+#define USBCtrl_RD_EN (1<<0) /*Read mode control*/
+#define USBCtrl_WR_EN (1<<1) /*Write mode control*/
+#define USBCtrl_LOG_ENDPOINT 0x003C /*Logical Endpoint number*/
+/* Command registers */
+#define USBCmdCode_o 0x0210 /* USB Command Code (WO) */
+#define USBCmdCode_CMD_PHASE 0x0000FF00 /*The command phase*/
+#define USBCmdCode_CMD_CODE 0x00FF0000 /*The code for the command*/
+#define USBCmdData_o 0x0214 /* USB Command Data (RO) */
+/* DMA registers (LPC2146/8 and LPC17xx only) */
+#define USBDMARSt_o 0x0250 /* USB DMA Request Status (RO) */
+#define USBDMARClr_o 0x0254 /* USB DMA Request Clear (WO) */
+#define USBDMARSet_o 0x0258 /* USB DMA Request Set (WO) */
+#define USBUDCAH_o 0x0280 /* USB UDCA Head (R/W) has to be aligned to 128 bytes */
+#define USBEpDMASt_o 0x0284 /* USB Endpoint DMA Status (RO) */
+#define USBEpDMAEn_o 0x0288 /* USB Endpoint DMA Enable (WO) */
+#define USBEpDMADis_o 0x028C /* USB Endpoint DMA Disable (WO) */
+#define USBDMAIntSt_o 0x0290 /* USB DMA Interrupt Status (RO) */
+#define USBDMAIntEn_o 0x0294 /* USB DMA Interrupt Enable (R/W) */
+#define USBDMAInt_EoT (1<<0) /*End of Transfer Interrupt bit, 1 if USBEoTIntSt != 0*/
+#define USBDMAInt_New_DD_Rq (1<<1) /* New DD Request Interrupt bit, 1 if USBNDDRIntSt != 0*/
+#define USBDMAInt_SysError (1<<2) /*System Error Interrupt bit, 1 if USBSysErrIntSt != 0*/
+#define USBEoTIntSt_o 0x02A0 /* USB End of Transfer Interrupt Status (RO) */
+#define USBEoTIntClr_o 0x02A4 /* USB End of Transfer Interrupt Clear (WO) */
+#define USBEoTIntSet_o 0x02A8 /* USB End of Transfer Interrupt Set (WO) */
+#define USBNDDRIntSt_o 0x02AC /* USB New DD Request Interrupt Status (RO) */
+#define USBNDDRIntClr_o 0x02B0 /* USB New DD Request Interrupt Clear (WO) */
+#define USBNDDRIntSet_o 0x02B4 /* USB New DD Request Interrupt Set (WO) */
+#define USBSysErrIntSt_o 0x02B8 /* USB System Error Interrupt Status (RO) */
+#define USBSysErrIntClr_o 0x02BC /* USB System Error Interrupt Clear (WO) */
+#define USBSysErrIntSet_o 0x02C0 /* USB System Error Interrupt Set (WO) */
+
+/* USB I2C registers */
+#define USB_I2C_RX_o 0x0300 /* I2C Receive (RO) */
+#define USB_I2C_TX_o 0x0300 /* I2C Transmit (WO) */
+#define USB_I2C_STS_o 0x0304 /* I2C Status (RO) */
+#define USB_I2C_CTL_o 0x0308 /* I2C Control (R/W) */
+#define USB_I2C_CLKHI_o 0x030C /* I2C Clock High (R/W) */
+#define USB_I2C_CLKLO_o 0x0310 /* I2C Clock Low (WO) */
+
+/* Clock control registers */
+#define OTGClkCtrl_o 0x0FF4 /* OTG Clock Control (R/W) */
+#define USBClkCtrl_o 0x0FF4 /* USB Clock Control (R/W) */
+#define OTGClkSt_o 0x0FF8 /* OTG Clock Status (RO) */
+#define USBClkSt_o 0x0FF8 /* USB Clock Status (RO) */
+
+/* Command Codes */
+#define USB_CMD_SET_ADDR 0x00D00500
+#define USB_CMD_CFG_DEV 0x00D80500
+#define USB_CMD_SET_MODE 0x00F30500
+#define USB_CMD_RD_FRAME 0x00F50500
+#define USB_DAT_RD_FRAME 0x00F50200
+#define USB_CMD_RD_TEST 0x00FD0500
+#define USB_DAT_RD_TEST 0x00FD0200
+#define USB_CMD_SET_DEV_STAT 0x00FE0500
+#define USB_CMD_GET_DEV_STAT 0x00FE0500
+#define USB_DAT_GET_DEV_STAT 0x00FE0200
+#define USB_CMD_GET_ERR_CODE 0x00FF0500
+#define USB_DAT_GET_ERR_CODE 0x00FF0200
+#define USB_CMD_RD_ERR_STAT 0x00FB0500
+#define USB_DAT_RD_ERR_STAT 0x00FB0200
+#define USB_DAT_WR_BYTE(x) (0x00000100 | ((x) << 16))
+#define USB_CMD_SEL_EP(x) (0x00000500 | ((x) << 16))
+#define USB_DAT_SEL_EP(x) (0x00000200 | ((x) << 16))
+#define USB_CMD_SEL_EP_CLRI(x) (0x00400500 | ((x) << 16))
+#define USB_DAT_SEL_EP_CLRI(x) (0x00400200 | ((x) << 16))
+#define USB_CMD_SET_EP_STAT(x) (0x00400500 | ((x) << 16))
+#define USB_CMD_CLR_BUF 0x00F20500
+#define USB_DAT_CLR_BUF 0x00F20200
+#define USB_CMD_VALID_BUF 0x00FA0500
+
+/* Device Address Register Definitions */
+#define USBC_DEV_ADDR_MASK 0x7F
+#define USBC_DEV_EN 0x80
+
+/* Device Configure Register Definitions */
+#define USBC_CONF_DEVICE 0x01
+
+/* Device Mode Register Definitions */
+#define USBC_AP_CLK 0x01
+#define USBC_INAK_CI 0x02
+#define USBC_INAK_CO 0x04
+#define USBC_INAK_II 0x08
+#define USBC_INAK_IO 0x10
+#define USBC_INAK_BI 0x20
+#define USBC_INAK_BO 0x40
+
+/* Device Status Register Definitions */
+#define USBC_DEV_CON 0x01
+#define USBC_DEV_CON_CH 0x02
+#define USBC_DEV_SUS 0x04
+#define USBC_DEV_SUS_CH 0x08
+#define USBC_DEV_RST 0x10
+
+/* Error Code Register Definitions */
+#define USBC_ERR_EC_MASK 0x0F
+#define USBC_ERR_EA 0x10
+
+/* Error Status Register Definitions */
+#define USBC_ERR_PID 0x01
+#define USBC_ERR_UEPKT 0x02
+#define USBC_ERR_DCRC 0x04
+#define USBC_ERR_TIMOUT 0x08
+#define USBC_ERR_EOP 0x10
+#define USBC_ERR_B_OVRN 0x20
+#define USBC_ERR_BTSTF 0x40
+#define USBC_ERR_TGL 0x80
+
+/* Endpoint Select Register Definitions */
+#define USBC_EP_SEL_F 0x01
+#define USBC_EP_SEL_ST 0x02
+#define USBC_EP_SEL_STP 0x04
+#define USBC_EP_SEL_PO 0x08
+#define USBC_EP_SEL_EPN 0x10
+#define USBC_EP_SEL_B_1_FULL 0x20
+#define USBC_EP_SEL_B_2_FULL 0x40
+
+/* Endpoint Status Register Definitions */
+#define USBC_EP_STAT_ST 0x01
+#define USBC_EP_STAT_DA 0x20
+#define USBC_EP_STAT_RF_MO 0x40
+#define USBC_EP_STAT_CND_ST 0x80
+
+/* Clear Buffer Register Definitions */
+#define USBC_CLR_BUF_PO 0x01
+
+typedef struct
+{
+ REG32 _padA[0x200];
+/* Device interrupt registers */
+ REG32 DevIntSt; /* USB Device Interrupt Status (RO) 0000 */
+ REG32 DevIntEn; /* USB Device Interrupt Enable (R/W) 0004 */
+ REG32 DevIntClr; /* USB Device Interrupt Clear (WO) 0008 */
+ REG32 DevIntSet; /* USB Device Interrupt Set (WO) 000C */
+/* Command registers */
+ REG32 CmdCode; /* USB Command Code (WO) 0010 */
+ REG32 CmdData; /* USB Command Data (RO) 0014 */
+/* USB transfer registers */
+ REG32 RxData; /* USB Receive Data (RO) 0018 */
+ REG32 TxData; /* USB Transmit Data (WO) 001C */
+ REG32 RxPLen; /* USB Receive Packet Length (RO) 0020 */
+ REG32 TxPLen; /* USB Transmit Packet Length (WO) 0024 */
+ REG32 Ctrl; /* USB Control (R/W) 0028 */
+/* Device interrupt priority register */
+ REG_8 USBDevIntPri; /* USB Device Interrupt Priority (WO) 002C */
+ REG_8 _pad0[3];
+/* Endpoint interrupt registers */
+ REG32 EpIntSt; /* USB Endpoint Interrupt Status (RO) 0030 */
+ REG32 EpIntEn; /* USB Endpoint Interrupt Enable (R/W) 0034 */
+ REG32 EpIntClr; /* USB Endpoint Interrupt Clear (WO) 0038 */
+ REG32 EpIntSet; /* USB Endpoint Interrupt Set (WO) 003C */
+ REG32 EpIntPri; /* USB Endpoint Priority (WO) 0040 */
+/* Endpoint realization registers */
+ REG32 ReEp; /* USB Realize Endpoint (R/W) 0044 */
+ REG32 EpInd; /* USB Endpoint Index (WO) 0048 */
+ REG32 MaxPSize; /* USB MaxPacketSize (R/W) 004C */
+/* DMA registers (LPC2146/8 only) */
+ REG32 DMARSt; /* USB DMA Request Status (RO) 0050 */
+ REG32 DMARClr; /* USB DMA Request Clear (WO) 0054 */
+ REG32 DMARSet; /* USB DMA Request Set (WO) 0058 */
+ REG32 _pad1[9];
+ REG32 UDCAH; /* USB UDCA Head (R/W) 0080 */
+ REG32 EpDMASt; /* USB Endpoint DMA Status (RO) 0084 */
+ REG32 EpDMAEn; /* USB Endpoint DMA Enable (WO) 0088 */
+ REG32 EpDMADis; /* USB Endpoint DMA Disable (WO) 008C */
+ REG32 DMAIntSt; /* USB DMA Interrupt Status (RO) 0090 */
+ REG32 DMAIntEn; /* USB DMA Interrupt Enable (R/W) 0094 */
+ REG32 _pad2[2];
+ REG32 EoTIntSt; /* USB End of Transfer Interrupt Status (RO) 00A0 */
+ REG32 EoTIntClr; /* USB End of Transfer Interrupt Clear (WO) 00A4 */
+ REG32 EoTIntSet; /* USB End of Transfer Interrupt Set (WO) 00A8 */
+ REG32 NDDRIntSt; /* USB New DD Request Interrupt Status (RO) 00AC */
+ REG32 NDDRIntClr; /* USB New DD Request Interrupt Clear (WO) 00B0 */
+ REG32 NDDRIntSet; /* USB New DD Request Interrupt Set (WO) 00B4 */
+ REG32 SysErrIntSt; /* USB System Error Interrupt Status (RO) 00B8 */
+ REG32 SysErrIntClr; /* USB System Error Interrupt Clear (WO) 00BC */
+ REG32 SysErrIntSet; /* USB System Error Interrupt Set (WO) 00C0 */
+} usbRegs_t;
+
+#define USBIntSt (*(REG32*)0x400FC10) /* USB Interrupt Status (R/W) */
+
+#define USB_REGS_BASE 0x5000C000UL
+
+#define HcControlHeadED_o 0x0020 /* PADDR of 1st EP desc. of control list (R/W) */
+#define HcControlCurrentED_o 0x0024 /* PADDR of curr. EP desc. of control list (R/W) */
+#define HcBulkHeadED_o 0x0028 /* PADDR of 1st EP desc. of bulk list (R/W) */
+#define HcBulkCurrentED_o 0x002C /* PADDR of curr. EP desc. of bulk list (R/W) */
+#define HcDoneHead_o 0x0030 /* PADDR of the last desct added to Done q. (R) */
+#define HcFmInterval_o 0x0034 /* full speed max frame time (R/W) */
+#define HcFmRemaining_o 0x0038 /* 14-bit counter of remaining in curr. frame (R) */
+#define HcFmNumber_o 0x003C /* 16-bit HC and HDC timing counter (R) */
+#define HcPeriodicStart_o 0x0040 /* 14-bit earliest time to start HC periodic list (R/W) */
+#define HcLSThreshold_o 0x0044 /* 11-bit HC timer for 8-byte LS packet before EOF (R/W) */
+#define HcRhDescriptorA_o 0x0048 /* Characteristics of the root hub - 1st part (R/W) */
+#define HcRhDescriptorB_o 0x004C /* Characteristics of the root hub - 2nd part (R/W) */
+#define HcRhStatus_o 0x0050 /* D-word hub info (low - status, high change) (R/W) */
+
+#define HcControlHeadED (*(REG32*)(USB_REGS_BASE+HcControlHeadED_o))
+#define HcControlCurrentED (*(REG32*)(USB_REGS_BASE+HcControlCurrentED_o))
+#define HcBulkHeadED (*(REG32*)(USB_REGS_BASE+HcBulkHeadED_o))
+#define HcBulkCurrentED (*(REG32*)(USB_REGS_BASE+HcBulkCurrentED_o))
+#define HcDoneHead (*(REG32*)(USB_REGS_BASE+HcDoneHead_o))
+#define HcFmInterval (*(REG32*)(USB_REGS_BASE+HcFmInterval_o))
+#define HcFmRemaining (*(REG32*)(USB_REGS_BASE+HcFmRemaining_o))
+#define HcFmNumber (*(REG32*)(USB_REGS_BASE+HcFmNumber_o))
+#define HcPeriodicStart (*(REG32*)(USB_REGS_BASE+HcPeriodicStart_o))
+#define HcLSThreshold (*(REG32*)(USB_REGS_BASE+HcLSThreshold_o))
+#define HcRhDescriptorA (*(REG32*)(USB_REGS_BASE+HcRhDescriptorA_o))
+#define HcRhDescriptorB (*(REG32*)(USB_REGS_BASE+HcRhDescriptorB_o))
+#define HcRhStatus (*(REG32*)(USB_REGS_BASE+HcRhStatus_o))
+
+#define USB_MODULE_ID (*(REG32*)(USB_REGS_BASE+USB_MODULE_ID_o))
+
+#define OTGIntSt (*(REG32*)(USB_REGS_BASE+OTGIntSt_o))
+#define OTGIntEn (*(REG32*)(USB_REGS_BASE+OTGIntEn_o))
+#define OTGIntClr (*(REG32*)(USB_REGS_BASE+OTGIntClr_o))
+#define OTGIntSet (*(REG32*)(USB_REGS_BASE+OTGIntSet_o))
+#define OTGStCtrl (*(REG32*)(USB_REGS_BASE+OTGStCtrl_o))
+#define OTGTmr (*(REG32*)(USB_REGS_BASE+OTGTmr_o))
+
+#define USBDevIntSt (*(REG32*)(USB_REGS_BASE+USBDevIntSt_o))
+#define USBDevIntEn (*(REG32*)(USB_REGS_BASE+USBDevIntEn_o))
+#define USBDevIntClr (*(REG32*)(USB_REGS_BASE+USBDevIntClr_o))
+#define USBDevIntSet (*(REG32*)(USB_REGS_BASE+USBDevIntSet_o))
+#define USBDevIntPri (*(REG32*)(USB_REGS_BASE+USBDevIntPri_o))
+#define USBEpIntSt (*(REG32*)(USB_REGS_BASE+USBEpIntSt_o))
+#define USBEpIntEn (*(REG32*)(USB_REGS_BASE+USBEpIntEn_o))
+#define USBEpIntClr (*(REG32*)(USB_REGS_BASE+USBEpIntClr_o))
+#define USBEpIntSet (*(REG32*)(USB_REGS_BASE+USBEpIntSet_o))
+#define USBEpIntPri (*(REG32*)(USB_REGS_BASE+USBEpIntPri_o))
+#define USBReEp (*(REG32*)(USB_REGS_BASE+USBReEp_o))
+#define USBEpInd (*(REG32*)(USB_REGS_BASE+USBEpInd_o))
+#define USBMaxPSize (*(REG32*)(USB_REGS_BASE+USBMaxPSize_o))
+#define USBRxData (*(REG32*)(USB_REGS_BASE+USBRxData_o))
+#define USBRxPLen (*(REG32*)(USB_REGS_BASE+USBRxPLen_o))
+#define USBTxData (*(REG32*)(USB_REGS_BASE+USBTxData_o))
+#define USBTxPLen (*(REG32*)(USB_REGS_BASE+USBTxPLen_o))
+#define USBCtrl (*(REG32*)(USB_REGS_BASE+USBCtrl_o))
+#define USBCmdCode (*(REG32*)(USB_REGS_BASE+USBCmdCode_o))
+#define USBCmdData (*(REG32*)(USB_REGS_BASE+USBCmdData_o))
+#define USBDMARSt (*(REG32*)(USB_REGS_BASE+USBDMARSt_o))
+#define USBDMARClr (*(REG32*)(USB_REGS_BASE+USBDMARClr_o))
+#define USBDMARSet (*(REG32*)(USB_REGS_BASE+USBDMARSet_o))
+#define USBUDCAH (*(REG32*)(USB_REGS_BASE+USBUDCAH_o))
+#define USBEpDMASt (*(REG32*)(USB_REGS_BASE+USBEpDMASt_o))
+#define USBEpDMAEn (*(REG32*)(USB_REGS_BASE+USBEpDMAEn_o))
+#define USBEpDMADis (*(REG32*)(USB_REGS_BASE+USBEpDMADis_o))
+#define USBDMAIntSt (*(REG32*)(USB_REGS_BASE+USBDMAIntSt_o))
+#define USBDMAIntEn (*(REG32*)(USB_REGS_BASE+USBDMAIntEn_o))
+#define USBEoTIntSt (*(REG32*)(USB_REGS_BASE+USBEoTIntSt_o))
+#define USBEoTIntClr (*(REG32*)(USB_REGS_BASE+USBEoTIntClr_o))
+#define USBEoTIntSet (*(REG32*)(USB_REGS_BASE+USBEoTIntSet_o))
+#define USBNDDRIntSt (*(REG32*)(USB_REGS_BASE+USBNDDRIntSt_o))
+#define USBNDDRIntClr (*(REG32*)(USB_REGS_BASE+USBNDDRIntClr_o))
+#define USBNDDRIntSet (*(REG32*)(USB_REGS_BASE+USBNDDRIntSet_o))
+#define USBSysErrIntSt (*(REG32*)(USB_REGS_BASE+USBSysErrIntSt_o))
+#define USBSysErrIntClr (*(REG32*)(USB_REGS_BASE+USBSysErrIntClr_o))
+#define USBSysErrIntSet (*(REG32*)(USB_REGS_BASE+USBSysErrIntSet_o))
+
+#define USB_I2C_RX (*(REG32*)(USB_REGS_BASE+I2C_RX_o))
+#define USB_I2C_TX (*(REG32*)(USB_REGS_BASE+I2C_TX_o))
+#define USB_I2C_STS (*(REG32*)(USB_REGS_BASE+I2C_STS_o))
+#define USB_I2C_CTL (*(REG32*)(USB_REGS_BASE+I2C_CTL_o))
+#define USB_I2C_CLKHI (*(REG32*)(USB_REGS_BASE+I2C_CLKHI_o))
+#define USB_I2C_CLKLO (*(REG32*)(USB_REGS_BASE+I2C_CLKLO_o))
+#define OTGClkCtrl (*(REG32*)(USB_REGS_BASE+OTGClkCtrl_o))
+#define USBClkCtrl (*(REG32*)(USB_REGS_BASE+USBClkCtrl_o))
+#define OTGClkSt (*(REG32*)(USB_REGS_BASE+OTGClkSt_o))
+#define USBClkSt (*(REG32*)(USB_REGS_BASE+USBClkSt_o))
+
+#endif /*_lpcUSB_H*/
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+SUBDIRS = hal iap
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+lib_LIBRARIES = mach_hal
+
+include_HEADERS = hal_machperiph.h hal_gpio.h hal_gpio_def.h
+
+mach_hal_SOURCES = hal.c startup.c hal_machperiph.c hal_reserve_usb_ram.c hal_gpio.c
+
+
+
--- /dev/null
+#include <stdio.h>
+#include <cpu_def.h>
+#include <LPC17xx.h>
+
+#define IRQ_TABLE_SIZE (16+33)
+
+__attribute__ ((section(".irqarea")))
+irq_handler_t *irq_handler_table_start[IRQ_TABLE_SIZE];
+void *irq_context_table_start[IRQ_TABLE_SIZE];
+
+void **irq_context_table = irq_context_table_start;
+irq_handler_t **irq_handler_table = irq_handler_table_start;
+unsigned int irq_table_size = IRQ_TABLE_SIZE;
+
+void disable_irq(unsigned int irqnum)
+{
+ NVIC_DisableIRQ(irqnum);
+ __memory_barrier();
+}
+void enable_irq(unsigned int irqnum)
+{
+ __memory_barrier();
+ NVIC_EnableIRQ(irqnum);
+}
+
+int
+request_irq(unsigned int irqnum, irq_handler_t *handler, unsigned long flags,
+ const char *name, void *context)
+{
+ unsigned int irqidx=irq_irqnum2irqidx(irqnum);
+
+ if (irqidx>=irq_table_size)
+ return -1;
+
+ disable_irq(irqnum);
+ irq_handler_table[irqidx]=handler;
+ irq_context_table[irqidx]=context;
+ enable_irq(irqnum);
+
+ return 0;
+}
+
+void free_irq(unsigned int irqnum, void *context)
+{
+ unsigned int irqidx=irq_irqnum2irqidx(irqnum);
+
+ if (irqidx>=irq_table_size)
+ return;
+
+ disable_irq(irqnum);
+ irq_handler_table[irqidx]=NULL;
+ irq_context_table[irqidx]=NULL;
+}
\ No newline at end of file
--- /dev/null
+#include <cpu_def.h>
+#include <LPC17xx.h>
+
+#include <hal_gpio.h>
+
+int hal_pin_conf_fnc(unsigned gpio, int fnc)
+{
+ __IO uint32_t *p = &(PINCON->PINSEL0);
+ uint32_t mask;
+
+ if(fnc & PORT_CONF_FNC_MASK)
+ fnc = __mfld2val(PORT_CONF_FNC_MASK, fnc);
+
+ p += hal_gpio_get_port_num(gpio)*2;
+ if(gpio & 0x10)
+ p++;
+ gpio &= 0x0f;
+ gpio *= 2;
+ mask = 3 << gpio;
+
+ *p = (*p & ~mask) | ((fnc << gpio) & mask);
+
+ return 0;
+}
+
+int hal_pin_conf_mode(unsigned gpio, int mode)
+{
+ __IO uint32_t *p = &(PINCON->PINMODE0);
+ uint32_t mask;
+
+ if(mode & PORT_CONF_MODE_MASK)
+ mode = __mfld2val(PORT_CONF_MODE_MASK, mode);
+
+ p += hal_gpio_get_port_num(gpio)*2;
+ if(gpio & 0x10)
+ p++;
+ gpio &= 0x0f;
+ gpio *= 2;
+ mask = 3 << gpio;
+
+ *p = (*p & ~mask) | ((mode << gpio) & mask);
+
+ return 0;
+}
+
+int hal_pin_conf_od(unsigned gpio, int od)
+{
+ uint32_t mask = 1 << (gpio & 0x1f);
+
+ if(od)
+ (&(PINCON->PINMODE_OD0))[hal_gpio_get_port_num(gpio)] |= mask;
+ else
+ (&(PINCON->PINMODE_OD0))[hal_gpio_get_port_num(gpio)] &= ~mask;
+
+ return 0;
+}
+
+int hal_pin_conf_set(unsigned gpio, int conf)
+{
+ gpio &= ~PORT_CONF_MASK;
+ hal_pin_conf_mode(gpio, conf & PORT_CONF_MODE_MASK);
+ hal_pin_conf_od(gpio, conf & PORT_CONF_OD_MASK);
+ if(conf & PORT_CONF_SET_DIR) {
+ if((conf & PORT_CONF_DIR_MASK) == (PORT_CONF_DIR_IN & PORT_CONF_DIR_MASK))
+ hal_gpio_direction_input(gpio);
+ else
+ hal_gpio_direction_output(gpio, conf & PORT_CONF_INIT_HIGH);
+ }
+ hal_pin_conf_fnc(gpio, conf & PORT_CONF_FNC_MASK);
+
+ return 0;
+}
--- /dev/null
+#ifndef _HAL_GPIO_H_
+#define _HAL_GPIO_H_
+
+#include <cpu_def.h>
+#include <LPC17xx.h>
+#include <hal_gpio_def.h>
+
+#define HAL_GPIO_PORT_BITS 3
+
+static inline
+GPIO_TypeDef *hal_gpio_get_port_base(unsigned port)
+{
+ char *p = (char*)GPIO0_BASE;
+ p += ((char*)GPIO1_BASE - (char*)GPIO0_BASE) * port;
+ return (GPIO_TypeDef *)p;
+}
+
+static inline
+unsigned hal_gpio_get_port_num(unsigned gpio)
+{
+ gpio >>= PORT_SHIFT;
+ return gpio & ((1 << HAL_GPIO_PORT_BITS) - 1);
+}
+
+static inline
+GPIO_TypeDef *hal_gpio_get_base(unsigned gpio)
+{
+ return hal_gpio_get_port_base(hal_gpio_get_port_num(gpio));
+}
+
+static inline
+int hal_gpio_get_value(unsigned gpio)
+{
+ return ((hal_gpio_get_base(gpio)->FIOPIN) >> (gpio & 0x1f)) & 1;
+}
+
+static inline
+void hal_gpio_set_value(unsigned gpio, int value)
+{
+ if(value)
+ hal_gpio_get_base(gpio)->FIOSET = 1 << (gpio & 0x1f);
+ else
+ hal_gpio_get_base(gpio)->FIOCLR = 1 << (gpio & 0x1f);
+}
+
+static inline
+int hal_gpio_direction_input(unsigned gpio)
+{
+ hal_gpio_get_base(gpio)->FIODIR &= ~(1 << (gpio & 0x1f));
+ return 0;
+}
+
+static inline
+int hal_gpio_direction_output(unsigned gpio, int value)
+{
+ hal_gpio_set_value(gpio, value);
+ hal_gpio_get_base(gpio)->FIODIR |= (1 << (gpio & 0x1f));
+ return 0;
+}
+
+int hal_pin_conf_fnc(unsigned gpio, int fnc);
+
+int hal_pin_conf_mode(unsigned gpio, int mode);
+
+int hal_pin_conf_od(unsigned gpio, int od);
+
+int hal_pin_conf_set(unsigned gpio, int conf);
+
+static inline
+int hal_pin_conf(unsigned gpio)
+{
+ return hal_pin_conf_set(gpio, gpio);
+}
+
+#endif /*_HAL_GPIO_H_*/
--- /dev/null
+#ifndef _HAL_GPIO_DEF_H_
+#define _HAL_GPIO_DEF_H_
+
+#ifndef PORT_SHIFT
+#define PORT_SHIFT 5
+#endif
+#ifndef PORT_PIN
+#define PORT_PIN(p,n,conf) (((p)<<PORT_SHIFT) | (n) | (conf))
+#define PORT_CONF_MASK 0xff000000
+#endif
+
+#define PORT_CONF_DIR_MASK 0x01000000
+#define PORT_CONF_DIR_IN (0x00000000 | PORT_CONF_SET_DIR)
+#define PORT_CONF_DIR_OUT (0x01000000 | PORT_CONF_SET_DIR)
+
+#define PORT_CONF_INIT_MASK 0x02000000
+#define PORT_CONF_INIT_LOW 0x00000000
+#define PORT_CONF_INIT_HIGH 0x02000000
+
+#define PORT_CONF_OD_MASK 0x04000000
+#define PORT_CONF_OD_OFF 0x00000000
+#define PORT_CONF_OD_ON 0x04000000
+
+#define PORT_CONF_SET_DIR 0x08000000
+
+#define PORT_CONF_MODE_MASK 0x30000000
+#define PORT_CONF_MODE_PU 0x00000000
+#define PORT_CONF_MODE_REP 0x10000000
+#define PORT_CONF_MODE_NORM 0x20000000
+#define PORT_CONF_MODE_PD 0x30000000
+
+#define PORT_CONF_FNC_MASK 0xc0000000
+#define PORT_CONF_FNC_GPIO 0x00000000
+#define PORT_CONF_FNC_0 0x00000000
+#define PORT_CONF_FNC_1 0x40000000
+#define PORT_CONF_FNC_2 0x80000000
+#define PORT_CONF_FNC_3 0xc0000000
+
+#define PORT_CONF_GPIO_IN (PORT_CONF_DIR_IN | PORT_CONF_FNC_GPIO | PORT_CONF_MODE_NORM)
+#define PORT_CONF_GPIO_IN_PU (PORT_CONF_DIR_IN | PORT_CONF_FNC_GPIO | PORT_CONF_MODE_PU)
+#define PORT_CONF_GPIO_IN_PD (PORT_CONF_DIR_IN | PORT_CONF_FNC_GPIO | PORT_CONF_MODE_PD)
+#define PORT_CONF_GPIO_IN_REP (PORT_CONF_DIR_IN | PORT_CONF_FNC_GPIO | PORT_CONF_MODE_REP)
+
+#define PORT_CONF_GPIO_OUT_LO (PORT_CONF_DIR_OUT | PORT_CONF_FNC_GPIO | PORT_CONF_INIT_LOW)
+#define PORT_CONF_GPIO_OUT_HI (PORT_CONF_DIR_OUT | PORT_CONF_FNC_GPIO | PORT_CONF_INIT_HIGH)
+#define PORT_CONF_GPIO_OUT_LO_OD (PORT_CONF_GPIO_OUT_LO | PORT_CONF_OD_ON)
+#define PORT_CONF_GPIO_OUT_HI_OD (PORT_CONF_GPIO_OUT_LO | PORT_CONF_OD_ON)
+
+#define PORT_CONF_OUT_LO_NORM (PORT_CONF_DIR_OUT | PORT_CONF_INIT_LOW | PORT_CONF_MODE_NORM)
+#define PORT_CONF_IN_PU (PORT_CONF_DIR_IN | PORT_CONF_MODE_PU)
+
+
+#endif /*_HAL_GPIO_H_*/
--- /dev/null
+
+#include <system_def.h>
+#include <cpu_def.h>
+#include <hal_machperiph.h>
+
+
+/*----------------------------------------------------------------------------
+ Check the register settings
+ *----------------------------------------------------------------------------*/
+#define CHECK_RANGE(val, min, max) ((val < min) || (val > max))
+#define CHECK_RSVD(val, mask) (val & mask)
+
+/* Clock Configuration -------------------------------------------------------*/
+#if (CHECK_RSVD((SCS_Val), ~0x00000030))
+ #error "SCS: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RANGE((CLKSRCSEL_Val), 0, 2))
+ #error "CLKSRCSEL: Value out of range!"
+#endif
+
+#if (CHECK_RSVD((PLL0CFG_Val), ~0x00FF7FFF))
+ #error "PLL0CFG: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RSVD((PLL1CFG_Val), ~0x0000007F))
+ #error "PLL1CFG: Invalid values of reserved bits!"
+#endif
+
+#if ((CCLKCFG_Val != 0) && (((CCLKCFG_Val - 1) % 2)))
+ #error "CCLKCFG: CCLKSEL field does not contain only odd values or 0!"
+#endif
+
+#if (CHECK_RSVD((USBCLKCFG_Val), ~0x0000000F))
+ #error "USBCLKCFG: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RSVD((PCLKSEL0_Val), 0x000C0C00))
+ #error "PCLKSEL0: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RSVD((PCLKSEL1_Val), 0x03000300))
+ #error "PCLKSEL1: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RSVD((PCONP_Val), 0x10100821))
+ #error "PCONP: Invalid values of reserved bits!"
+#endif
+
+/* Flash Accelerator Configuration -------------------------------------------*/
+#if (CHECK_RSVD((FLASHCFG_Val), ~0x0000F07F))
+ #error "FLASHCFG: Invalid values of reserved bits!"
+#endif
+
+/*----------------------------------------------------------------------------
+ Clock Variable definitions
+ *----------------------------------------------------------------------------*/
+unsigned int system_frequency = IRC_OSC; /*!< System Clock Frequency (Core Clock) */
+
+void system_clock_init(void)
+{
+#if (CLOCK_SETUP) /* Clock Setup */
+ SC->SCS = SCS_Val;
+ if (SCS_Val & (1 << 5)) { /* If Main Oscillator is enabled */
+ while ((SC->SCS & (1 << 6)) == 0); /* Wait for Oscillator to be ready */
+ }
+
+#if (PLL0_SETUP)
+ SC->CLKSRCSEL = CLKSRCSEL_Val; /* Select Clock Source for PLL0 */
+ SC->PLL0CFG = PLL0CFG_Val;
+ SC->PLL0CON = 0x01; /* PLL0 Enable */
+ SC->PLL0FEED = 0xAA;
+ SC->PLL0FEED = 0x55;
+ while (!(SC->PLL0STAT & (1 << 26))); /* Wait for PLOCK0 */
+ SC->CCLKCFG = CCLKCFG_Val; /* Setup Clock Divider */
+
+ SC->PLL0CON = 0x03; /* PLL0 Enable & Connect */
+ SC->PLL0FEED = 0xAA;
+ SC->PLL0FEED = 0x55;
+#endif
+
+#if (PLL1_SETUP)
+ SC->PLL1CFG = PLL1CFG_Val;
+ SC->PLL1CON = 0x01; /* PLL1 Enable */
+ SC->PLL1FEED = 0xAA;
+ SC->PLL1FEED = 0x55;
+ while (!(SC->PLL1STAT & (1 << 10))); /* Wait for PLOCK1 */
+
+ SC->PLL1CON = 0x03; /* PLL1 Enable & Connect */
+ SC->PLL1FEED = 0xAA;
+ SC->PLL1FEED = 0x55;
+#endif
+
+#ifdef USBCLKCFG_Val
+#if USBCLKCFG_Val != 0
+ SC->USBCLKCFG = USBCLKCFG_Val;
+#endif
+#endif
+
+#endif
+
+ /* Determine clock frequency according to clock register values */
+ if (((SC->PLL0STAT >> 24) & 3) == 3) {/* If PLL0 enabled and connected */
+ switch (SC->CLKSRCSEL & 0x03) {
+ case 0: /* Internal RC oscillator => PLL0 */
+ case 3: /* Reserved, default to Internal RC */
+ system_frequency = (IRC_OSC *
+ (((2 * ((SC->PLL0STAT & 0x7FFF) + 1))) /
+ (((SC->PLL0STAT >> 16) & 0xFF) + 1)) /
+ ((SC->CCLKCFG & 0xFF)+ 1));
+ break;
+ case 1: /* Main oscillator => PLL0 */
+ system_frequency = (OSC_CLK *
+ (((2 * ((SC->PLL0STAT & 0x7FFF) + 1))) /
+ (((SC->PLL0STAT >> 16) & 0xFF) + 1)) /
+ ((SC->CCLKCFG & 0xFF)+ 1));
+ break;
+ case 2: /* RTC oscillator => PLL0 */
+ system_frequency = (RTC_CLK *
+ (((2 * ((SC->PLL0STAT & 0x7FFF) + 1))) /
+ (((SC->PLL0STAT >> 16) & 0xFF) + 1)) /
+ ((SC->CCLKCFG & 0xFF)+ 1));
+ break;
+ }
+ } else {
+ switch (SC->CLKSRCSEL & 0x03) {
+ case 0: /* Internal RC oscillator => PLL0 */
+ case 3: /* Reserved, default to Internal RC */
+ system_frequency = IRC_OSC / ((SC->CCLKCFG & 0xFF)+ 1);
+ break;
+ case 1: /* Main oscillator => PLL0 */
+ system_frequency = OSC_CLK / ((SC->CCLKCFG & 0xFF)+ 1);
+ break;
+ case 2: /* RTC oscillator => PLL0 */
+ system_frequency = RTC_CLK / ((SC->CCLKCFG & 0xFF)+ 1);
+ break;
+ }
+ }
+
+#if (FLASH_SETUP == 1) /* Flash Accelerator Setup */
+ SC->FLASHCFG = FLASHCFG_Val;
+#endif
+}
+
+void lpc_watchdog_feed()
+{
+ unsigned long flags;
+
+ save_and_cli(flags);
+ WDT->WDFEED = 0xAA;
+ WDT->WDFEED = 0x55;
+ restore_flags(flags);
+}
+
+void lpc_watchdog_init(int on,int timeout_ms)
+{
+ if (!on) return;
+ WDT->WDCLKSEL = 1;
+ WDT->WDTC = (PCLK/4)/(1000/timeout_ms);
+ WDT->WDMOD = 0x03; /* Enable watchdog timer and reset */
+}
--- /dev/null
+#ifndef _HAL_MACHPERIPH_H
+#define _HAL_MACHPERIPH_H
+
+extern unsigned int system_frequency;
+#define PCLK ((system_frequency+2)/4)
+
+void system_clock_init(void);
+
+void lpc_watchdog_init(int on,int timeout_ms);
+void lpc_watchdog_feed();
+void *lpc_reserve_usb_ram(unsigned long size);
+
+#endif /* _HAL_MACHPERIPH_H */
+
--- /dev/null
+#include <stdint.h>
+#include <string.h>
+#include <hal_machperiph.h>
+
+extern char _eusbram;
+
+void *lpc_reserve_usb_ram(unsigned long size)
+{
+ static char *usb_ram_avail=&_eusbram;
+ char *prev_avail;
+
+ /*printf("usb reserve %lu at 0x%lx\n",size,(unsigned long)usb_ram_avail);*/
+
+ if(!usb_ram_avail)
+ return NULL;
+
+ prev_avail=(char *)(((uintptr_t)usb_ram_avail+3)&~3);
+ usb_ram_avail=prev_avail+size;
+
+ return prev_avail;
+}
\ No newline at end of file
--- /dev/null
+/****************************************************************************//**
+ * @file : startup_LPC17xx.c
+ * @brief : CMSIS Cortex-M3 Core Device Startup File
+ * @version : V1.01
+ * @date : 4. Feb. 2009
+ *
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2009 ARM Limited. All rights reserved.
+ *
+ * ARM Limited (ARM) is supplying this software for use with Cortex-Mx
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+// Mod by nio for the .fastcode part
+
+#include "cpu_def.h"
+#include "LPC17xx.h"
+
+#define WEAK __attribute__ ((weak))
+//*****************************************************************************
+//
+// Forward declaration of the default fault handlers.
+//
+//*****************************************************************************
+/* System exception vector handler */
+void WEAK Reset_Handler(void); /* Reset Handler */
+void WEAK NMI_Handler(void); /* NMI Handler */
+void WEAK HardFault_Handler(void); /* Hard Fault Handler */
+void WEAK MemManage_Handler(void); /* MPU Fault Handler */
+void WEAK BusFault_Handler(void); /* Bus Fault Handler */
+void WEAK UsageFault_Handler(void); /* Usage Fault Handler */
+void WEAK SVC_Handler(void); /* SVCall Handler */
+void WEAK DebugMon_Handler(void); /* Debug Monitor Handler */
+void WEAK PendSV_Handler(void); /* PendSV Handler */
+void WEAK SysTick_Handler(void); /* SysTick Handler */
+
+/* External interrupt vector handler */
+void WEAK WDT_IRQHandler(void); /* Watchdog Timer */
+void WEAK TIMER0_IRQHandler(void); /* Timer0 */
+void WEAK TIMER1_IRQHandler(void); /* Timer1 */
+void WEAK TIMER2_IRQHandler(void); /* Timer2 */
+void WEAK TIMER3_IRQHandler(void); /* Timer3 */
+void WEAK UART0_IRQHandler(void); /* UART0 */
+void WEAK UART1_IRQHandler(void); /* UART1 */
+void WEAK UART2_IRQHandler(void); /* UART2 */
+void WEAK UART3_IRQHandler(void); /* UART3 */
+void WEAK PWM1_IRQHandler(void); /* PWM1 */
+void WEAK I2C0_IRQHandler(void); /* I2C0 */
+void WEAK I2C1_IRQHandler(void); /* I2C1 */
+void WEAK I2C2_IRQHandler(void); /* I2C2 */
+void WEAK SPI_IRQHandler(void); /* SPI */
+void WEAK SSP0_IRQHandler(void); /* SSP0 */
+void WEAK SSP1_IRQHandler(void); /* SSP1 */
+void WEAK PLL0_IRQHandler(void); /* PLL0 (Main PLL) */
+void WEAK RTC_IRQHandler(void); /* Real Time Clock */
+void WEAK EINT0_IRQHandler(void); /* External Interrupt 0 */
+void WEAK EINT1_IRQHandler(void); /* External Interrupt 1 */
+void WEAK EINT2_IRQHandler(void); /* External Interrupt 2 */
+void WEAK EINT3_IRQHandler(void); /* External Interrupt 3 */
+void WEAK ADC_IRQHandler(void); /* A/D Converter */
+void WEAK BOD_IRQHandler(void); /* Brown Out Detect */
+void WEAK USB_IRQHandler(void); /* USB */
+void WEAK CAN_IRQHandler(void); /* CAN */
+void WEAK DMA_IRQHandler(void); /* GP DMA */
+void WEAK I2S_IRQHandler(void); /* I2S */
+void WEAK ENET_IRQHandler(void); /* Ethernet */
+void WEAK RIT_IRQHandler(void); /* Repetitive Interrupt Timer */
+void WEAK MCPWM_IRQHandler(void); /* Motor Control PWM */
+void WEAK QEI_IRQHandler(void); /* Quadrature Encoder Interface */
+void WEAK PLL1_IRQHandler(void); /* PLL1 (USB PLL) */
+
+
+
+/* Exported types --------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+extern unsigned long _etext;
+extern unsigned long _sidata; /* start address for the initialization values of the .data section. defined in linker script */
+extern unsigned long _sdata; /* start address for the .data section. defined in linker script */
+extern unsigned long _edata; /* end address for the .data section. defined in linker script */
+
+extern unsigned long _sifastcode; /* start address for the initialization values of the .fastcode section. defined in linker script */
+extern unsigned long _sfastcode; /* start address for the .fastcode section. defined in linker script */
+extern unsigned long _efastcode; /* end address for the .fastcode section. defined in linker script */
+
+extern unsigned long _sbss; /* start address for the .bss section. defined in linker script */
+extern unsigned long _ebss; /* end address for the .bss section. defined in linker script */
+
+extern void _estack; /* init value for the stack pointer. defined in linker script */
+
+extern void (_setup_board)(void); /* setup_board adress function */
+extern unsigned long _mem_app_start;
+
+
+
+/* Private typedef -----------------------------------------------------------*/
+/* function prototypes ------------------------------------------------------*/
+void Reset_Handler(void) __attribute__((__interrupt__));
+extern int main(void);
+
+typedef void (*FNC)(void);
+FNC fnc_entry;
+
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+
+extern unsigned long _stack;
+
+__attribute__ ((section(".isr_vector")))
+void (* const g_pfnVectors[])(void) =
+{
+ (void (*)(void))&_stack, /* The initial stack pointer */
+ Reset_Handler, /* Reset Handler */
+ NMI_Handler, /* NMI Handler */
+ HardFault_Handler, /* Hard Fault Handler */
+ MemManage_Handler, /* MPU Fault Handler */
+ BusFault_Handler, /* Bus Fault Handler */
+ UsageFault_Handler, /* Usage Fault Handler */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ SVC_Handler, /* SVCall Handler */
+ DebugMon_Handler, /* Debug Monitor Handler */
+ 0, /* Reserved */
+ PendSV_Handler, /* PendSV Handler */
+ SysTick_Handler, /* SysTick Handler */
+
+ // External Interrupts
+ WDT_IRQHandler, /* Watchdog Timer */
+ TIMER0_IRQHandler, /* Timer0 */
+ TIMER1_IRQHandler, /* Timer1 */
+ TIMER2_IRQHandler, /* Timer2 */
+ TIMER3_IRQHandler, /* Timer3 */
+ UART0_IRQHandler, /* UART0 */
+ UART1_IRQHandler, /* UART1 */
+ UART2_IRQHandler, /* UART2 */
+ UART3_IRQHandler, /* UART3 */
+ PWM1_IRQHandler, /* PWM1 */
+ I2C0_IRQHandler, /* I2C0 */
+ I2C1_IRQHandler, /* I2C1 */
+ I2C2_IRQHandler, /* I2C2 */
+ SPI_IRQHandler, /* SPI */
+ SSP0_IRQHandler, /* SSP0 */
+ SSP1_IRQHandler, /* SSP1 */
+ PLL0_IRQHandler, /* PLL0 (Main PLL) */
+ RTC_IRQHandler, /* Real Time Clock */
+ EINT0_IRQHandler, /* External Interrupt 0 */
+ EINT1_IRQHandler, /* External Interrupt 1 */
+ EINT2_IRQHandler, /* External Interrupt 2 */
+ EINT3_IRQHandler, /* External Interrupt 3 */
+ ADC_IRQHandler, /* A/D Converter */
+ BOD_IRQHandler, /* Brown Out Detect */
+ USB_IRQHandler, /* USB */
+ CAN_IRQHandler, /* CAN */
+ DMA_IRQHandler, /* GP DMA */
+ I2S_IRQHandler, /* I2S */
+ ENET_IRQHandler, /* Ethernet */
+ RIT_IRQHandler, /* Repetitive Interrupt Timer */
+ MCPWM_IRQHandler, /* Motor Control PWM */
+ QEI_IRQHandler, /* Quadrature Encoder Interface */
+ PLL1_IRQHandler, /* PLL1 (USB PLL) */
+};
+
+/*******************************************************************************
+* Function Name : Reset_Handler
+* Description : This is the code that gets called when the processor first starts execution
+* following a reset event. Only the absolutely necessary set is performed,
+* after which the application supplied main() routine is called.
+* Input :
+* Output :
+* Return :
+*******************************************************************************/
+
+void Reset_Handler(void)
+{
+ unsigned long *pulDest;
+ unsigned long *pulSrc;
+
+ //
+ // Copy the data segment initializers from flash to SRAM in ROM mode
+ //
+
+ if (&_sidata != &_sdata) { // only if needed
+ pulSrc = &_sidata;
+ for(pulDest = &_sdata; pulDest < &_edata; ) {
+ *(pulDest++) = *(pulSrc++);
+ }
+ }
+
+ // Copy the .fastcode code from ROM to SRAM
+
+ if (&_sifastcode != &_sfastcode) { // only if needed
+ pulSrc = &_sifastcode;
+ for(pulDest = &_sfastcode; pulDest < &_efastcode; ) {
+ *(pulDest++) = *(pulSrc++);
+ }
+ }
+
+ //
+ // Zero fill the bss segment.
+ //
+ for(pulDest = &_sbss; pulDest < &_ebss; )
+ {
+ *(pulDest++) = 0;
+ }
+
+ // copy initial values and set irq table
+ if(irq_handler_table && irq_table_size) {
+ int i;
+ pulSrc = (unsigned long*)g_pfnVectors;
+ pulDest = (unsigned long*)irq_handler_table;
+ for(i = irq_table_size; i--; ) {
+ *(pulDest++) = *(pulSrc++);
+ }
+ /*SCB->VTOR=0x10000000;*/
+ SCB->VTOR=(uint32_t)irq_handler_table;
+ }
+
+ //if (_setup_board!=0)
+ _setup_board();
+
+ //
+ // Call the application's entry point.
+ //
+ main();
+
+ /* disable interrupts */
+ NVIC->ICER[0] = 0xffffffff;
+ NVIC->ICER[1] = 0x00000007;
+ __set_MSP(*(unsigned long *)(&_mem_app_start)); /* Stack pointer */
+ fnc_entry = (FNC)*(unsigned long *)(&_mem_app_start+1); /* Reset handler */
+ fnc_entry();
+}
+
+//*****************************************************************************
+//
+// Provide weak aliases for each Exception handler to the Default_Handler.
+// As they are weak aliases, any function with the same name will override
+// this definition.
+//
+//*****************************************************************************
+#pragma weak MemManage_Handler = Default_Handler /* MPU Fault Handler */
+#pragma weak BusFault_Handler = Default_Handler /* Bus Fault Handler */
+#pragma weak UsageFault_Handler = Default_Handler /* Usage Fault Handler */
+#pragma weak SVC_Handler = Default_Handler /* SVCall Handler */
+#pragma weak DebugMon_Handler = Default_Handler /* Debug Monitor Handler */
+#pragma weak PendSV_Handler = Default_Handler /* PendSV Handler */
+#pragma weak SysTick_Handler = Default_Handler /* SysTick Handler */
+
+/* External interrupt vector handler */
+#pragma weak WDT_IRQHandler = Default_Handler /* Watchdog Timer */
+#pragma weak TIMER0_IRQHandler = Default_Handler /* Timer0 */
+#pragma weak TIMER1_IRQHandler = Default_Handler /* Timer1 */
+#pragma weak TIMER2_IRQHandler = Default_Handler /* Timer2 */
+#pragma weak TIMER3_IRQHandler = Default_Handler /* Timer3 */
+#pragma weak UART0_IRQHandler = Default_Handler /* UART0 */
+#pragma weak UART1_IRQHandler = Default_Handler /* UART1 */
+#pragma weak UART2_IRQHandler = Default_Handler /* UART2 */
+#pragma weak UART3_IRQHandler = Default_Handler /* UART3 */
+#pragma weak PWM1_IRQHandler = Default_Handler /* PWM1 */
+#pragma weak I2C0_IRQHandler = Default_Handler /* I2C0 */
+#pragma weak I2C1_IRQHandler = Default_Handler /* I2C1 */
+#pragma weak I2C2_IRQHandler = Default_Handler /* I2C2 */
+#pragma weak SPI_IRQHandler = Default_Handler /* SPI */
+#pragma weak SSP0_IRQHandler = Default_Handler /* SSP0 */
+#pragma weak SSP1_IRQHandler = Default_Handler /* SSP1 */
+#pragma weak PLL0_IRQHandler = Default_Handler /* PLL0 (Main PLL) */
+#pragma weak RTC_IRQHandler = Default_Handler /* Real Time Clock */
+#pragma weak EINT0_IRQHandler = Default_Handler /* External Interrupt 0 */
+#pragma weak EINT1_IRQHandler = Default_Handler /* External Interrupt 1 */
+#pragma weak EINT2_IRQHandler = Default_Handler /* External Interrupt 2 */
+#pragma weak EINT3_IRQHandler = Default_Handler /* External Interrupt 3 */
+#pragma weak ADC_IRQHandler = Default_Handler /* A/D Converter */
+#pragma weak BOD_IRQHandler = Default_Handler /* Brown Out Detect */
+#pragma weak USB_IRQHandler = Default_Handler /* USB */
+#pragma weak CAN_IRQHandler = Default_Handler /* CAN */
+#pragma weak DMA_IRQHandler = Default_Handler /* GP DMA */
+#pragma weak I2S_IRQHandler = Default_Handler /* I2S */
+#pragma weak ENET_IRQHandler = Default_Handler /* Ethernet */
+#pragma weak RIT_IRQHandler = Default_Handler /* Repetitive Interrupt Timer */
+#pragma weak MCPWM_IRQHandler = Default_Handler /* Motor Control PWM */
+#pragma weak QEI_IRQHandler = Default_Handler /* Quadrature Encoder Interface */
+#pragma weak PLL1_IRQHandler = Default_Handler /* PLL1 (USB PLL) */
+
+//*****************************************************************************
+//
+// This is the code that gets called when the processor receives an unexpected
+// interrupt. This simply enters an infinite loop, preserving the system state
+// for examination by a debugger.
+//
+//*****************************************************************************
+void Default_Handler(void) {
+ // Go into an infinite loop.
+ //
+ while (1) {
+ }
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+include_HEADERS = lpciap.h
+lib_LIBRARIES = lpciap
+lpciap_SOURCES = iap.c
+
--- /dev/null
+#include <system_def.h>
+#include <cpu_def.h>
+#include <hal_machperiph.h>
+
+#define CMD_SUCCESS 0
+#define BUSY 11
+
+#define IAP_CMD_PREPARE 50
+#define IAP_CMD_WRITE 51
+#define IAP_CMD_ERASE 52
+#define IAP_CMD_READ_PARTID 54
+
+unsigned int command[5];
+unsigned int result[5];
+
+#define IAP_LOCATION 0x1FFF1FF1
+
+typedef void (*IAP)(unsigned int [],unsigned int[]);
+IAP iap_entry = (IAP) IAP_LOCATION;
+
+static inline int addr2sec(unsigned long addr)
+{
+ if (addr<0x10000) {
+ return (addr>>12);
+ } else {
+ addr-=0x10000;
+ return (addr>>15)+16;
+ }
+}
+
+int lpcisp_read_partid()
+{
+ command[0] = IAP_CMD_READ_PARTID;
+ iap_entry(command, result);
+ return result[1];
+}
+
+int lpcisp_prepare_sectors(unsigned char start, unsigned char end)
+{
+ command[0] = IAP_CMD_PREPARE;
+ command[1] = start;
+ command[2] = end;
+
+ iap_entry(command, result);
+
+ return (CMD_SUCCESS == *result);
+}
+
+int lpcisp_erase_sectors(unsigned char start, unsigned char end)
+{
+ command[0] = IAP_CMD_ERASE;
+ command[1] = start;
+ command[2] = end;
+ command[3] = system_frequency/1000;
+
+ iap_entry(command, result);
+
+ return (CMD_SUCCESS == *result);
+}
+
+int lpcisp_erase(void *addr, int len)
+{
+ int start,end;
+ unsigned long flags;
+
+ start=addr2sec((unsigned long)addr);
+ end=addr2sec((unsigned long)addr+len-1);
+
+ if (end<start) return 0;
+
+ save_and_cli(flags);
+
+ lpcisp_prepare_sectors(start,end);
+ if (CMD_SUCCESS != *result) return 0;
+
+ lpcisp_erase_sectors(start,end);
+
+ restore_flags(flags);
+
+ return (CMD_SUCCESS == *result);
+}
+
+int lpcisp_write(void *addr_des, const void *addr_src, int len)
+{
+ int start,end;
+ unsigned long flags;
+
+ start=addr2sec((unsigned long)addr_des);
+ end=start;
+
+ save_and_cli(flags);
+
+ lpcisp_prepare_sectors(start,end);
+ if (CMD_SUCCESS != *result) return 0;
+
+ command[0] = IAP_CMD_WRITE;
+ command[1] = (unsigned int)addr_des;
+ command[2] = (unsigned int)addr_src;
+ command[3] = len;
+ command[4] = system_frequency/1000;
+
+ iap_entry(command, result);
+
+ restore_flags(flags);
+
+ return (CMD_SUCCESS == *result);
+}
+
+
--- /dev/null
+#ifndef _LPCIAP_H
+#define _LPCIAP_H
+
+int lpcisp_read_partid();
+int lpcisp_erase(void *addr, int len);
+int lpcisp_write(void *addr_des, const void *addr_src, int len);
+
+#endif /* _LPCIAP_H */
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+SUBDIRS = defines libs
--- /dev/null
+#ifndef INC_LPC210x_H
+#define INC_LPC210x_H
+
+#include "LPC21xx.h"
+
+#endif
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * Header file for Philips LPC214x ARM Processors
+ * Copyright 2006 Pavel Pisa <pisa@cmp.felk.cvut.cz>
+ *
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact or GPL license is applied.
+ *
+ *****************************************************************************/
+
+#ifndef INC_LPC214x_H
+#define INC_LPC214x_H
+
+///////////////////////////////////////////////////////////////////////////////
+// ISP_RAM2FLASH_BLOCK_SIZE for 210x CPU
+#ifndef ISP_RAM2FLASH_BLOCK_SIZE
+ #define ISP_RAM2FLASH_BLOCK_SIZE 256
+#endif /* ISP_RAM2FLASH_BLOCK_SIZE */
+
+#include "LPC21xx.h"
+
+#include "lpcUSB.h"
+#include "lpcADC-214x.h"
+
+// USB Phase Locked Loop Registers (PLL48)
+#define PLLCON48 SCB->pll48.con /* Control Register */
+#define PLLCFG48 SCB->pll48.cfg /* Configuration Register */
+#define PLLSTAT48 SCB->pll48.stat /* Status Register */
+#define PLLFEED48 SCB->pll48.feed /* Feed Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// USB Device
+
+#define USBIntSt (*(REG32*)0xE01FC1C0) /* USB Interrupt Status (R/W) */
+
+#if 1
+
+#define USB ((usbRegs_t *)0xE0090000)
+
+#define USBDevIntSt USB->DevIntSt
+#define USBDevIntEn USB->DevIntEn
+#define USBDevIntClr USB->DevIntClr
+#define USBDevIntSet USB->DevIntSet
+#define USBDevIntPri USB->DevIntPri
+#define USBEpIntSt USB->EpIntSt
+#define USBEpIntEn USB->EpIntEn
+#define USBEpIntClr USB->EpIntClr
+#define USBEpIntSet USB->EpIntSet
+#define USBEpIntPri USB->EpIntPri
+#define USBReEp USB->ReEp
+#define USBEpInd USB->EpInd
+#define USBMaxPSize USB->MaxPSize
+#define USBRxData USB->RxData
+#define USBRxPLen USB->RxPLen
+#define USBTxData USB->TxData
+#define USBTxPLen USB->TxPLen
+#define USBCtrl USB->Ctrl
+#define USBCmdCode USB->CmdCode
+#define USBCmdData USB->CmdData
+#define USBDMARSt USB->DMARSt
+#define USBDMARClr USB->DMARClr
+#define USBDMARSet USB->DMARSet
+#define USBUDCAH USB->UDCAH
+#define USBEpDMASt USB->EpDMASt
+#define USBEpDMAEn USB->EpDMAEn
+#define USBEpDMADis USB->EpDMADis
+#define USBDMAIntSt USB->DMAIntSt
+#define USBDMAIntEn USB->DMAIntEn
+#define USBEoTIntSt USB->EoTIntSt
+#define USBEoTIntClr USB->EoTIntClr
+#define USBEoTIntSet USB->EoTIntSet
+#define USBNDDRIntSt USB->NDDRIntSt
+#define USBNDDRIntClr USB->NDDRIntClr
+#define USBNDDRIntSet USB->NDDRIntSet
+#define USBSysErrIntSt USB->SysErrIntSt
+#define USBSysErrIntClr USB->SysErrIntClr
+#define USBSysErrIntSet USB->SysErrIntSet
+#define USB_MODULE_ID USB->MODULE_ID
+# else
+
+#define USB_REGS_BASE 0xE0090000
+
+#define USBDevIntSt (*(REG32*)(USB_REGS_BASE+USBDevIntSt_o))
+#define USBDevIntEn (*(REG32*)(USB_REGS_BASE+USBDevIntEn_o))
+#define USBDevIntClr (*(REG32*)(USB_REGS_BASE+USBDevIntClr_o))
+#define USBDevIntSet (*(REG32*)(USB_REGS_BASE+USBDevIntSet_o))
+#define USBDevIntPri (*(REG_8*)(USB_REGS_BASE+USBDevIntPri_o))
+#define USBEpIntSt (*(REG32*)(USB_REGS_BASE+USBEpIntSt_o))
+#define USBEpIntEn (*(REG32*)(USB_REGS_BASE+USBEpIntEn_o))
+#define USBEpIntClr (*(REG32*)(USB_REGS_BASE+USBEpIntClr_o))
+#define USBEpIntSet (*(REG32*)(USB_REGS_BASE+USBEpIntSet_o))
+#define USBEpIntPri (*(REG32*)(USB_REGS_BASE+USBEpIntPri_o))
+#define USBReEp (*(REG32*)(USB_REGS_BASE+USBReEp_o))
+#define USBEpInd (*(REG32*)(USB_REGS_BASE+USBEpInd_o))
+#define USBMaxPSize (*(REG32*)(USB_REGS_BASE+USBMaxPSize_o))
+#define USBRxData (*(REG32*)(USB_REGS_BASE+USBRxData_o))
+#define USBRxPLen (*(REG32*)(USB_REGS_BASE+USBRxPLen_o))
+#define USBTxData (*(REG32*)(USB_REGS_BASE+USBTxData_o))
+#define USBTxPLen (*(REG32*)(USB_REGS_BASE+USBTxPLen_o))
+#define USBCtrl (*(REG32*)(USB_REGS_BASE+USBCtrl_o))
+#define USBCmdCode (*(REG32*)(USB_REGS_BASE+USBCmdCode_o))
+#define USBCmdData (*(REG32*)(USB_REGS_BASE+USBCmdData_o))
+#define USBDMARSt (*(REG32*)(USB_REGS_BASE+USBDMARSt_o))
+#define USBDMARClr (*(REG32*)(USB_REGS_BASE+USBDMARClr_o))
+#define USBDMARSet (*(REG32*)(USB_REGS_BASE+USBDMARSet_o))
+#define USBUDCAH (*(REG32*)(USB_REGS_BASE+USBUDCAH_o))
+#define USBEpDMASt (*(REG32*)(USB_REGS_BASE+USBEpDMASt_o))
+#define USBEpDMAEn (*(REG32*)(USB_REGS_BASE+USBEpDMAEn_o))
+#define USBEpDMADis (*(REG32*)(USB_REGS_BASE+USBEpDMADis_o))
+#define USBDMAIntSt (*(REG32*)(USB_REGS_BASE+USBDMAIntSt_o))
+#define USBDMAIntEn (*(REG32*)(USB_REGS_BASE+USBDMAIntEn_o))
+#define USBEoTIntSt (*(REG32*)(USB_REGS_BASE+USBEoTIntSt_o))
+#define USBEoTIntClr (*(REG32*)(USB_REGS_BASE+USBEoTIntClr_o))
+#define USBEoTIntSet (*(REG32*)(USB_REGS_BASE+USBEoTIntSet_o))
+#define USBNDDRIntSt (*(REG32*)(USB_REGS_BASE+USBNDDRIntSt_o))
+#define USBNDDRIntClr (*(REG32*)(USB_REGS_BASE+USBNDDRIntClr_o))
+#define USBNDDRIntSet (*(REG32*)(USB_REGS_BASE+USBNDDRIntSet_o))
+#define USBSysErrIntSt (*(REG32*)(USB_REGS_BASE+USBSysErrIntSt_o))
+#define USBSysErrIntClr (*(REG32*)(USB_REGS_BASE+USBSysErrIntClr_o))
+#define USBSysErrIntSet (*(REG32*)(USB_REGS_BASE+USBSysErrIntSet_o))
+#define USB_MODULE_ID (*(REG32*)(USB_REGS_BASE+USB_MODULE_ID_o))
+
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////
+// A/D Converter
+#define ADC0 ((adc214xRegs_t *)0xE0034000)
+
+#define AD0CR ADC0->cr // Control Register
+#define AD0GDR ADC0->gdr // Global Data Register
+#define AD0GSR ADC0->gsr // Global Start Register
+#define AD0INTEN ADC0->inten // Interrupt Enable Register
+#define AD0DR0 ADC0->dr0 // Channel 0 Data Register
+#define AD0DR1 ADC0->dr1 // Channel 1 Data Register
+#define AD0DR2 ADC0->dr2 // Channel 2 Data Register
+#define AD0DR3 ADC0->dr3 // Channel 3 Data Register
+#define AD0DR4 ADC0->dr4 // Channel 4 Data Register
+#define AD0DR5 ADC0->dr5 // Channel 5 Data Register
+#define AD0DR6 ADC0->dr6 // Channel 6 Data Register
+#define AD0DR7 ADC0->dr7 // Channel 7 Data Register
+#define AD0STAT ADC0->stat // Status Register
+
+#define ADC1 ((adc214xRegs_t *)0xE0060000)
+
+#define AD1CR ADC1->cr // Control Register
+#define AD1GDR ADC1->gdr // Global Data Register
+#define AD1GSR ADC1->gsr // Global Start Register
+#define AD1INTEN ADC1->inten // Interrupt Enable Register
+#define AD1DR0 ADC1->dr0 // Channel 0 Data Register
+#define AD1DR1 ADC1->dr1 // Channel 1 Data Register
+#define AD1DR2 ADC1->dr2 // Channel 2 Data Register
+#define AD1DR3 ADC1->dr3 // Channel 3 Data Register
+#define AD1DR4 ADC1->dr4 // Channel 4 Data Register
+#define AD1DR5 ADC1->dr5 // Channel 5 Data Register
+#define AD1DR6 ADC1->dr6 // Channel 6 Data Register
+#define AD1DR7 ADC1->dr7 // Channel 7 Data Register
+#define AD1STAT ADC1->stat // Status Register
+
+
+#endif /*INC_LPC21xx_H*/
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * Header file for Philips LPC21xx ARM Processors
+ * Copyright 2004 R O SoftWare
+ *
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ *****************************************************************************/
+#ifndef INC_LPC21xx_H
+#define INC_LPC21xx_H
+
+#define REG_8 volatile unsigned char
+#define REG16 volatile unsigned short
+#define REG32 volatile unsigned long
+
+#include "lpcWD.h"
+#include "lpcTMR.h"
+#include "lpcUART.h"
+#include "lpcI2C.h"
+#include "lpcSPI.h"
+#include "lpcRTC.h"
+#include "lpcGPIO.h"
+#include "lpcPIN.h"
+#include "lpcADC.h"
+#include "lpcSCB.h"
+#include "lpcVIC.h"
+
+///////////////////////////////////////////////////////////////////////////////
+// Keyval
+#define KVPB_CHUNK_SIZE 16
+
+///////////////////////////////////////////////////////////////////////////////
+// ISP_RAM2FLASH_BLOCK_SIZE for CPU - minimal is 512, can be smaller for some CPU
+#ifndef ISP_RAM2FLASH_BLOCK_SIZE
+ #define ISP_RAM2FLASH_BLOCK_SIZE 512
+#endif /* ISP_RAM2FLASH_BLOCK_SIZE */
+
+///////////////////////////////////////////////////////////////////////////////
+// Watchdog
+#define WD ((wdRegs_t *)0xE0000000)
+
+// Watchdog Registers
+#define WDMOD WD->mod /* Watchdog Mode Register */
+#define WDTC WD->tc /* Watchdog Time Constant Register */
+#define WDFEED WD->feed /* Watchdog Feed Register */
+#define WDTV WD->tv /* Watchdog Time Value Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Timer 0
+#define TMR0 ((pwmTmrRegs_t *)0xE0004000)
+
+// Timer 0 Registers
+#define T0IR TMR0->ir /* Interrupt Register */
+#define T0TCR TMR0->tcr /* Timer Control Register */
+#define T0TC TMR0->tc /* Timer Counter */
+#define T0PR TMR0->pr /* Prescale Register */
+#define T0PC TMR0->pc /* Prescale Counter Register */
+#define T0MCR TMR0->mcr /* Match Control Register */
+#define T0MR0 TMR0->mr0 /* Match Register 0 */
+#define T0MR1 TMR0->mr1 /* Match Register 1 */
+#define T0MR2 TMR0->mr2 /* Match Register 2 */
+#define T0MR3 TMR0->mr3 /* Match Register 3 */
+#define T0CCR TMR0->ccr /* Capture Control Register */
+#define T0CR0 TMR0->cr0 /* Capture Register 0 */
+#define T0CR1 TMR0->cr1 /* Capture Register 1 */
+#define T0CR2 TMR0->cr2 /* Capture Register 2 */
+#define T0CR3 TMR0->cr3 /* Capture Register 3 */
+#define T0EMR TMR0->emr /* External Match Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Timer 1
+#define TMR1 ((pwmTmrRegs_t *)0xE0008000)
+
+// Timer 1 Registers
+#define T1IR TMR1->ir /* Interrupt Register */
+#define T1TCR TMR1->tcr /* Timer Control Register */
+#define T1TC TMR1->tc /* Timer Counter */
+#define T1PR TMR1->pr /* Prescale Register */
+#define T1PC TMR1->pc /* Prescale Counter Register */
+#define T1MCR TMR1->mcr /* Match Control Register */
+#define T1MR0 TMR1->mr0 /* Match Register 0 */
+#define T1MR1 TMR1->mr1 /* Match Register 1 */
+#define T1MR2 TMR1->mr2 /* Match Register 2 */
+#define T1MR3 TMR1->mr3 /* Match Register 3 */
+#define T1CCR TMR1->ccr /* Capture Control Register */
+#define T1CR0 TMR1->cr0 /* Capture Register 0 */
+#define T1CR1 TMR1->cr1 /* Capture Register 1 */
+#define T1CR2 TMR1->cr2 /* Capture Register 2 */
+#define T1CR3 TMR1->cr3 /* Capture Register 3 */
+#define T1EMR TMR1->emr /* External Match Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Pulse Width Modulator (PWM)
+#define PWM ((pwmTmrRegs_t *)0xE0014000)
+
+// PWM Registers
+#define PWMIR PWM->ir /* Interrupt Register */
+#define PWMTCR PWM->tcr /* Timer Control Register */
+#define PWMTC PWM->tc /* Timer Counter */
+#define PWMPR PWM->pr /* Prescale Register */
+#define PWMPC PWM->pc /* Prescale Counter Register */
+#define PWMMCR PWM->mcr /* Match Control Register */
+#define PWMMR0 PWM->mr0 /* Match Register 0 */
+#define PWMMR1 PWM->mr1 /* Match Register 1 */
+#define PWMMR2 PWM->mr2 /* Match Register 2 */
+#define PWMMR3 PWM->mr3 /* Match Register 3 */
+#define PWMMR4 PWM->mr4 /* Match Register 4 */
+#define PWMMR5 PWM->mr5 /* Match Register 5 */
+#define PWMMR6 PWM->mr6 /* Match Register 6 */
+#define PWMPCR PWM->pcr /* Control Register */
+#define PWMLER PWM->ler /* Latch Enable Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Universal Asynchronous Receiver Transmitter 0 (UART0)
+#define UART0 ((uartRegs_t *)0xE000C000)
+#define U0_PINSEL (0x00000005) /* PINSEL0 Value for UART0 */
+#define U0_PINMASK (0x0000000F) /* PINSEL0 Mask for UART0 */
+
+// UART0 Registers
+#define U0RBR UART0->rbr /* Receive Buffer Register */
+#define U0THR UART0->thr /* Transmit Holding Register */
+#define U0IER UART0->ier /* Interrupt Enable Register */
+#define U0IIR UART0->iir /* Interrupt ID Register */
+#define U0FCR UART0->fcr /* FIFO Control Register */
+#define U0LCR UART0->lcr /* Line Control Register */
+#define U0LSR UART0->lsr /* Line Status Register */
+#define U0SCR UART0->scr /* Scratch Pad Register */
+#define U0DLL UART0->dll /* Divisor Latch Register (LSB) */
+#define U0DLM UART0->dlm /* Divisor Latch Register (MSB) */
+
+///////////////////////////////////////////////////////////////////////////////
+// Universal Asynchronous Receiver Transmitter 1 (UART1)
+#define UART1 ((uartRegs_t *)0xE0010000)
+#define U1_PINSEL (0x00050000) /* PINSEL0 Value for UART1 */
+#define U1_PINMASK (0x000F0000) /* PINSEL0 Mask for UART1 */
+
+// UART1 Registers
+#define U1RBR UART1->rbr /* Receive Buffer Register */
+#define U1THR UART1->thr /* Transmit Holding Register */
+#define U1IER UART1->ier /* Interrupt Enable Register */
+#define U1IIR UART1->iir /* Interrupt ID Register */
+#define U1FCR UART1->fcr /* FIFO Control Register */
+#define U1LCR UART1->lcr /* Line Control Register */
+#define U1MCR UART1->mcr /* MODEM Control Register */
+#define U1LSR UART1->lsr /* Line Status Register */
+#define U1MSR UART1->msr /* MODEM Status Register */
+#define U1SCR UART1->scr /* Scratch Pad Register */
+#define U1DLL UART1->dll /* Divisor Latch Register (LSB) */
+#define U1DLM UART1->dlm /* Divisor Latch Register (MSB) */
+
+///////////////////////////////////////////////////////////////////////////////
+// I2C Interface
+#define I2C0_BASE_ADDR 0xE001C000
+#define I2C ((i2cRegs_t *)I2C0_BASE_ADDR)
+
+// I2C Registers
+#define I2CONSET I2C->conset /* Control Set Register */
+#define I2STAT I2C->stat /* Status Register */
+#define I2DAT I2C->dat /* Data Register */
+#define I2ADR I2C->adr /* Slave Address Register */
+#define I2SCLH I2C->sclh /* SCL Duty Cycle Register (high half word) */
+#define I2SCLL I2C->scll /* SCL Duty Cycle Register (low half word) */
+#define I2CONCLR I2C->conclr /* Control Clear Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Serial Peripheral Interface 0 (SPI0)
+#define SPI0_BASE_ADDR 0xE0020000
+#define SPI0 ((spiRegs_t *)0xE0020000)
+
+// SPI0 Registers
+#define S0SPCR SPI0->cr /* Control Register */
+#define S0SPSR SPI0->sr /* Status Register */
+#define S0SPDR SPI0->dr /* Data Register */
+#define S0SPCCR SPI0->ccr /* Clock Counter Register */
+#define S0SPINT SPI0->flag /* Interrupt Flag Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Serial Peripheral Interface 1 (SPI1)
+#define SPI1 ((spiRegs_t *)0xE0030000)
+
+// SPI1 Registers
+#define S1SPCR SPI1->cr /* Control Register */
+#define S1SPSR SPI1->sr /* Status Register */
+#define S1SPDR SPI1->dr /* Data Register */
+#define S1SPCCR SPI1->ccr /* Clock Counter Register */
+#define S1SPINT SPI1->flag /* Interrupt Flag Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Real Time Clock
+#define RTC ((rtcRegs_t *)0xE0024000)
+
+// RTC Registers
+#define RTCILR RTC->ilr /* Interrupt Location Register */
+#define RTCCTC RTC->ctc /* Clock Tick Counter */
+#define RTCCCR RTC->ccr /* Clock Control Register */
+#define RTCCIIR RTC->ciir /* Counter Increment Interrupt Register */
+#define RTCAMR RTC->amr /* Alarm Mask Register */
+#define RTCCTIME0 RTC->ctime0 /* Consolidated Time Register 0 */
+#define RTCCTIME1 RTC->ctime1 /* Consolidated Time Register 1 */
+#define RTCCTIME2 RTC->ctime2 /* Consolidated Time Register 2 */
+#define RTCSEC RTC->sec /* Seconds Register */
+#define RTCMIN RTC->min /* Minutes Register */
+#define RTCHOUR RTC->hour /* Hours Register */
+#define RTCDOM RTC->dom /* Day Of Month Register */
+#define RTCDOW RTC->dow /* Day Of Week Register */
+#define RTCDOY RTC->doy /* Day Of Year Register */
+#define RTCMONTH RTC->month /* Months Register */
+#define RTCYEAR RTC->year /* Years Register */
+#define RTCALSEC RTC->alsec /* Alarm Seconds Register */
+#define RTCALMIN RTC->almin /* Alarm Minutes Register */
+#define RTCALHOUR RTC->alhour /* Alarm Hours Register */
+#define RTCALDOM RTC->aldom /* Alarm Day Of Month Register */
+#define RTCALDOW RTC->aldow /* Alarm Day Of Week Register */
+#define RTCALDOY RTC->aldoy /* Alarm Day Of Year Register */
+#define RTCALMON RTC->almon /* Alarm Months Register */
+#define RTCALYEAR RTC->alyear /* Alarm Years Register */
+#define RTCPREINT RTC->preint /* Prescale Value Register (integer) */
+#define RTCPREFRAC RTC->prefrac /* Prescale Value Register (fraction) */
+
+///////////////////////////////////////////////////////////////////////////////
+// General Purpose Input/Output
+#define GPIO ((gpioRegs_t *)0xE0028000)
+
+// GPIO Registers
+#define IO0PIN GPIO->in0 /* P0 Pin Value Register */
+#define IO0SET GPIO->set0 /* P0 Pin Output Set Register */
+#define IO0DIR GPIO->dir0 /* P0 Pin Direction Register */
+#define IO0CLR GPIO->clr0 /* P0 Pin Output Clear Register */
+#define IO1PIN GPIO->in1 /* P1 Pin Value Register */
+#define IO1SET GPIO->set1 /* P1 Pin Output Set Register */
+#define IO1DIR GPIO->dir1 /* P1 Pin Direction Register */
+#define IO1CLR GPIO->clr1 /* P1 Pin Output Clear Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Pin Connect Block
+#define PINSEL ((pinRegs_t *)0xE002C000)
+
+// Pin Connect Block Registers
+#define PINSEL0 PINSEL->sel0 /* Pin Function Select Register 0 */
+#define PINSEL1 PINSEL->sel1 /* Pin Function Select Register 1 */
+#define PINSEL2 PINSEL->sel2 /* Pin Function Select Register 2 */
+
+///////////////////////////////////////////////////////////////////////////////
+// A/D Converter
+#define ADC ((adcRegs_t *)0xE0034000)
+
+// A/D Converter Registers
+#define ADCR ADC->cr /* Control Register */
+#define ADDR ADC->dr /* Data Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// System Contol Block
+#define SCB ((scbRegs_t *)0xE01FC000)
+
+// Memory Accelerator Module Registers (MAM)
+#define MAMCR SCB->mam.cr /* Control Register */
+#define MAMTIM SCB->mam.tim /* Timing Control Register */
+
+// Memory Mapping Control Register
+#define MEMMAP SCB->memmap
+
+// Phase Locked Loop Registers (PLL)
+#define PLLCON SCB->pll.con /* Control Register */
+#define PLLCFG SCB->pll.cfg /* Configuration Register */
+#define PLLSTAT SCB->pll.stat /* Status Register */
+#define PLLFEED SCB->pll.feed /* Feed Register */
+
+// Power Control Registers
+#define PCON SCB->p.con /* Control Register */
+#define PCONP SCB->p.conp /* Peripherals Register */
+
+// VPB Divider Register
+#define VPBDIV SCB->vpbdiv
+
+// External Interrupt Registers
+#define EXTINT SCB->ext.flag /* Flag Register */
+#define EXTWAKE SCB->ext.wake /* Wakeup Register */
+#define EXTMODE SCB->ext.mode /* Mode Register */
+#define EXTPOLAR SCB->ext.polar /* Polarity Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Vectored Interrupt Controller
+#define VIC ((vicRegs_t *)0xFFFFF000)
+
+// Vectored Interrupt Controller Registers
+#define VICIRQStatus VIC->irqStatus /* IRQ Status Register */
+#define VICFIQStatus VIC->fiqStatus /* FIQ Status Register */
+#define VICRawIntr VIC->rawIntr /* Raw Interrupt Status Register */
+#define VICIntSelect VIC->intSelect /* Interrupt Select Register */
+#define VICIntEnable VIC->intEnable /* Interrupt Enable Register */
+#define VICIntEnClear VIC->intEnClear /* Interrupt Enable Clear Register */
+#define VICSoftInt VIC->softInt /* Software Interrupt Register */
+#define VICSoftIntClear VIC->softIntClear /* Software Interrupt Clear Register */
+#define VICProtection VIC->protection /* Protection Enable Register */
+#define VICVectAddr VIC->vectAddr /* Vector Address Register */
+#define VICDefVectAddr VIC->defVectAddr /* Default Vector Address Register */
+#define VICVectAddr0 VIC->vectAddr0 /* Vector Address 0 Register */
+#define VICVectAddr1 VIC->vectAddr1 /* Vector Address 1 Register */
+#define VICVectAddr2 VIC->vectAddr2 /* Vector Address 2 Register */
+#define VICVectAddr3 VIC->vectAddr3 /* Vector Address 3 Register */
+#define VICVectAddr4 VIC->vectAddr4 /* Vector Address 4 Register */
+#define VICVectAddr5 VIC->vectAddr5 /* Vector Address 5 Register */
+#define VICVectAddr6 VIC->vectAddr6 /* Vector Address 6 Register */
+#define VICVectAddr7 VIC->vectAddr7 /* Vector Address 7 Register */
+#define VICVectAddr8 VIC->vectAddr8 /* Vector Address 8 Register */
+#define VICVectAddr9 VIC->vectAddr9 /* Vector Address 9 Register */
+#define VICVectAddr10 VIC->vectAddr10 /* Vector Address 10 Register */
+#define VICVectAddr11 VIC->vectAddr11 /* Vector Address 11 Register */
+#define VICVectAddr12 VIC->vectAddr12 /* Vector Address 12 Register */
+#define VICVectAddr13 VIC->vectAddr13 /* Vector Address 13 Register */
+#define VICVectAddr14 VIC->vectAddr14 /* Vector Address 14 Register */
+#define VICVectAddr15 VIC->vectAddr15 /* Vector Address 15 Register */
+#define VICVectCntl0 VIC->vectCntl0 /* Vector Control 0 Register */
+#define VICVectCntl1 VIC->vectCntl1 /* Vector Control 1 Register */
+#define VICVectCntl2 VIC->vectCntl2 /* Vector Control 2 Register */
+#define VICVectCntl3 VIC->vectCntl3 /* Vector Control 3 Register */
+#define VICVectCntl4 VIC->vectCntl4 /* Vector Control 4 Register */
+#define VICVectCntl5 VIC->vectCntl5 /* Vector Control 5 Register */
+#define VICVectCntl6 VIC->vectCntl6 /* Vector Control 6 Register */
+#define VICVectCntl7 VIC->vectCntl7 /* Vector Control 7 Register */
+#define VICVectCntl8 VIC->vectCntl8 /* Vector Control 8 Register */
+#define VICVectCntl9 VIC->vectCntl9 /* Vector Control 9 Register */
+#define VICVectCntl10 VIC->vectCntl10 /* Vector Control 10 Register */
+#define VICVectCntl11 VIC->vectCntl11 /* Vector Control 11 Register */
+#define VICVectCntl12 VIC->vectCntl12 /* Vector Control 12 Register */
+#define VICVectCntl13 VIC->vectCntl13 /* Vector Control 13 Register */
+#define VICVectCntl14 VIC->vectCntl14 /* Vector Control 14 Register */
+#define VICVectCntl15 VIC->vectCntl15 /* Vector Control 15 Register */
+
+#endif
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * Header file for Philips LPC22xx ARM Processors
+ * Copyright 2004 R O SoftWare
+ *
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ *****************************************************************************/
+#ifndef INC_LPC22xx_H
+#define INC_LPC22xx_H
+
+#define REG_8 volatile unsigned char
+#define REG16 volatile unsigned short
+#define REG32 volatile unsigned long
+
+#include "lpcWD.h"
+#include "lpcTMR.h"
+#include "lpcUART.h"
+#include "lpcI2C.h"
+#include "lpcSPI.h"
+#include "lpcRTC.h"
+#include "lpcGPIO.h"
+#include "lpcPIN.h"
+#include "lpcADC.h"
+#include "lpcSCB.h"
+#include "lpcEMC.h"
+#include "lpcVIC.h"
+
+///////////////////////////////////////////////////////////////////////////////
+// Watchdog
+#define WD ((wdRegs_t *)0xE0000000)
+
+// Watchdog Registers
+#define WDMOD WD->mod /* Watchdog Mode Register */
+#define WDTC WD->tc /* Watchdog Time Constant Register */
+#define WDFEED WD->feed /* Watchdog Feed Register */
+#define WDTV WD->tv /* Watchdog Time Value Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Timer 0
+#define TMR0 ((pwmTmrRegs_t *)0xE0004000)
+
+// Timer 0 Registers
+#define T0IR TMR0->ir /* Interrupt Register */
+#define T0TCR TMR0->tcr /* Timer Control Register */
+#define T0TC TMR0->tc /* Timer Counter */
+#define T0PR TMR0->pr /* Prescale Register */
+#define T0PC TMR0->pc /* Prescale Counter Register */
+#define T0MCR TMR0->mcr /* Match Control Register */
+#define T0MR0 TMR0->mr0 /* Match Register 0 */
+#define T0MR1 TMR0->mr1 /* Match Register 1 */
+#define T0MR2 TMR0->mr2 /* Match Register 2 */
+#define T0MR3 TMR0->mr3 /* Match Register 3 */
+#define T0CCR TMR0->ccr /* Capture Control Register */
+#define T0CR0 TMR0->cr0 /* Capture Register 0 */
+#define T0CR1 TMR0->cr1 /* Capture Register 1 */
+#define T0CR2 TMR0->cr2 /* Capture Register 2 */
+#define T0CR3 TMR0->cr3 /* Capture Register 3 */
+#define T0EMR TMR0->emr /* External Match Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Timer 1
+#define TMR1 ((pwmTmrRegs_t *)0xE0008000)
+
+// Timer 1 Registers
+#define T1IR TMR1->ir /* Interrupt Register */
+#define T1TCR TMR1->tcr /* Timer Control Register */
+#define T1TC TMR1->tc /* Timer Counter */
+#define T1PR TMR1->pr /* Prescale Register */
+#define T1PC TMR1->pc /* Prescale Counter Register */
+#define T1MCR TMR1->mcr /* Match Control Register */
+#define T1MR0 TMR1->mr0 /* Match Register 0 */
+#define T1MR1 TMR1->mr1 /* Match Register 1 */
+#define T1MR2 TMR1->mr2 /* Match Register 2 */
+#define T1MR3 TMR1->mr3 /* Match Register 3 */
+#define T1CCR TMR1->ccr /* Capture Control Register */
+#define T1CR0 TMR1->cr0 /* Capture Register 0 */
+#define T1CR1 TMR1->cr1 /* Capture Register 1 */
+#define T1CR2 TMR1->cr2 /* Capture Register 2 */
+#define T1CR3 TMR1->cr3 /* Capture Register 3 */
+#define T1EMR TMR1->emr /* External Match Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Pulse Width Modulator (PWM)
+#define PWM ((pwmTmrRegs_t *)0xE0014000)
+
+// PWM Registers
+#define PWMIR PWM->ir /* Interrupt Register */
+#define PWMTCR PWM->tcr /* Timer Control Register */
+#define PWMTC PWM->tc /* Timer Counter */
+#define PWMPR PWM->pr /* Prescale Register */
+#define PWMPC PWM->pc /* Prescale Counter Register */
+#define PWMMCR PWM->mcr /* Match Control Register */
+#define PWMMR0 PWM->mr0 /* Match Register 0 */
+#define PWMMR1 PWM->mr1 /* Match Register 1 */
+#define PWMMR2 PWM->mr2 /* Match Register 2 */
+#define PWMMR3 PWM->mr3 /* Match Register 3 */
+#define PWMMR4 PWM->mr4 /* Match Register 4 */
+#define PWMMR5 PWM->mr5 /* Match Register 5 */
+#define PWMMR6 PWM->mr6 /* Match Register 6 */
+#define PWMPCR PWM->pcr /* Control Register */
+#define PWMLER PWM->ler /* Latch Enable Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Universal Asynchronous Receiver Transmitter 0 (UART0)
+#define UART0 ((uartRegs_t *)0xE000C000)
+#define U0_PINSEL (0x00000005) /* PINSEL0 Value for UART0 */
+#define U0_PINMASK (0x0000000F) /* PINSEL0 Mask for UART0 */
+
+// UART0 Registers
+#define U0RBR UART0->rbr /* Receive Buffer Register */
+#define U0THR UART0->thr /* Transmit Holding Register */
+#define U0IER UART0->ier /* Interrupt Enable Register */
+#define U0IIR UART0->iir /* Interrupt ID Register */
+#define U0FCR UART0->fcr /* FIFO Control Register */
+#define U0LCR UART0->lcr /* Line Control Register */
+#define U0LSR UART0->lsr /* Line Status Register */
+#define U0SCR UART0->scr /* Scratch Pad Register */
+#define U0DLL UART0->dll /* Divisor Latch Register (LSB) */
+#define U0DLM UART0->dlm /* Divisor Latch Register (MSB) */
+
+///////////////////////////////////////////////////////////////////////////////
+// Universal Asynchronous Receiver Transmitter 1 (UART1)
+#define UART1 ((uartRegs_t *)0xE0010000)
+#define U1_PINSEL (0x00050000) /* PINSEL0 Value for UART1 */
+#define U1_PINMASK (0x000F0000) /* PINSEL0 Mask for UART1 */
+
+// UART1 Registers
+#define U1RBR UART1->rbr /* Receive Buffer Register */
+#define U1THR UART1->thr /* Transmit Holding Register */
+#define U1IER UART1->ier /* Interrupt Enable Register */
+#define U1IIR UART1->iir /* Interrupt ID Register */
+#define U1FCR UART1->fcr /* FIFO Control Register */
+#define U1LCR UART1->lcr /* Line Control Register */
+#define U1MCR UART1->mcr /* MODEM Control Register */
+#define U1LSR UART1->lsr /* Line Status Register */
+#define U1MSR UART1->msr /* MODEM Status Register */
+#define U1SCR UART1->scr /* Scratch Pad Register */
+#define U1DLL UART1->dll /* Divisor Latch Register (LSB) */
+#define U1DLM UART1->dlm /* Divisor Latch Register (MSB) */
+
+///////////////////////////////////////////////////////////////////////////////
+// I2C Interface
+#define I2C ((i2cRegs_t *)0xE001C000)
+
+// I2C Registers
+#define I2CONSET I2C->conset /* Control Set Register */
+#define I2STAT I2C->stat /* Status Register */
+#define I2DAT I2C->dat /* Data Register */
+#define I2ADR I2C->adr /* Slave Address Register */
+#define I2SCLH I2C->sclh /* SCL Duty Cycle Register (high half word) */
+#define I2SCLL I2C->scll /* SCL Duty Cycle Register (low half word) */
+#define I2CONCLR I2C->conclr /* Control Clear Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Serial Peripheral Interface 0 (SPI0)
+#define SPI0 ((spiRegs_t *)0xE0020000)
+
+// SPI0 Registers
+#define S0SPCR SPI0->cr /* Control Register */
+#define S0SPSR SPI0->sr /* Status Register */
+#define S0SPDR SPI0->dr /* Data Register */
+#define S0SPCCR SPI0->ccr /* Clock Counter Register */
+#define S0SPINT SPI0->flag /* Interrupt Flag Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Serial Peripheral Interface 1 (SPI1)
+#define SPI1 ((spiRegs_t *)0xE0030000)
+
+// SPI1 Registers
+#define S1SPCR SPI1->cr /* Control Register */
+#define S1SPSR SPI1->sr /* Status Register */
+#define S1SPDR SPI1->dr /* Data Register */
+#define S1SPCCR SPI1->ccr /* Clock Counter Register */
+#define S1SPINT SPI1->flag /* Interrupt Flag Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Real Time Clock
+#define RTC ((rtcRegs_t *)0xE0024000)
+
+// RTC Registers
+#define RTCILR RTC->ilr /* Interrupt Location Register */
+#define RTCCTC RTC->ctc /* Clock Tick Counter */
+#define RTCCCR RTC->ccr /* Clock Control Register */
+#define RTCCIIR RTC->ciir /* Counter Increment Interrupt Register */
+#define RTCAMR RTC->amr /* Alarm Mask Register */
+#define RTCCTIME0 RTC->ctime0 /* Consolidated Time Register 0 */
+#define RTCCTIME1 RTC->ctime1 /* Consolidated Time Register 1 */
+#define RTCCTIME2 RTC->ctime2 /* Consolidated Time Register 2 */
+#define RTCSEC RTC->sec /* Seconds Register */
+#define RTCMIN RTC->min /* Minutes Register */
+#define RTCHOUR RTC->hour /* Hours Register */
+#define RTCDOM RTC->dom /* Day Of Month Register */
+#define RTCDOW RTC->dow /* Day Of Week Register */
+#define RTCDOY RTC->doy /* Day Of Year Register */
+#define RTCMONTH RTC->month /* Months Register */
+#define RTCYEAR RTC->year /* Years Register */
+#define RTCALSEC RTC->alsec /* Alarm Seconds Register */
+#define RTCALMIN RTC->almin /* Alarm Minutes Register */
+#define RTCALHOUR RTC->alhour /* Alarm Hours Register */
+#define RTCALDOM RTC->aldom /* Alarm Day Of Month Register */
+#define RTCALDOW RTC->aldow /* Alarm Day Of Week Register */
+#define RTCALDOY RTC->aldoy /* Alarm Day Of Year Register */
+#define RTCALMON RTC->almon /* Alarm Months Register */
+#define RTCALYEAR RTC->alyear /* Alarm Years Register */
+#define RTCPREINT RTC->preint /* Prescale Value Register (integer) */
+#define RTCPREFRAC RTC->prefrac /* Prescale Value Register (fraction) */
+
+///////////////////////////////////////////////////////////////////////////////
+// General Purpose Input/Output
+#define GPIO ((gpioRegs_t *)0xE0028000)
+
+// GPIO Registers
+#define IO0PIN GPIO->in0 /* P0 Pin Value Register */
+#define IO0SET GPIO->set0 /* P0 Pin Output Set Register */
+#define IO0DIR GPIO->dir0 /* P0 Pin Direction Register */
+#define IO0CLR GPIO->clr0 /* P0 Pin Output Clear Register */
+#define IO1PIN GPIO->in1 /* P1 Pin Value Register */
+#define IO1SET GPIO->set1 /* P1 Pin Output Set Register */
+#define IO1DIR GPIO->dir1 /* P1 Pin Direction Register */
+#define IO1CLR GPIO->clr1 /* P1 Pin Output Clear Register */
+#define IO2PIN GPIO->in2 /* P2 Pin Value Register */
+#define IO2SET GPIO->set2 /* P2 Pin Output Set Register */
+#define IO2DIR GPIO->dir2 /* P2 Pin Direction Register */
+#define IO2CLR GPIO->clr2 /* P2 Pin Output Clear Register */
+#define IO3PIN GPIO->in3 /* P3 Pin Value Register */
+#define IO3SET GPIO->set3 /* P3 Pin Output Set Register */
+#define IO3DIR GPIO->dir3 /* P3 Pin Direction Register */
+#define IO3CLR GPIO->clr3 /* P3 Pin Output Clear Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Pin Connect Block
+#define PINSEL ((pinRegs_t *)0xE002C000)
+
+// Pin Connect Block Registers
+#define PINSEL0 PINSEL->sel0 /* Pin Function Select Register 0 */
+#define PINSEL1 PINSEL->sel1 /* Pin Function Select Register 1 */
+#define PINSEL2 PINSEL->sel2 /* Pin Function Select Register 2 */
+
+///////////////////////////////////////////////////////////////////////////////
+// A/D Converter
+#define ADC ((adcRegs_t *)0xE0034000)
+
+// A/D Converter Registers
+#define ADCR ADC->cr /* Control Register */
+#define ADDR ADC->dr /* Data Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// System Contol Block
+#define SCB ((scbRegs_t *)0xE01FC000)
+
+// Memory Accelerator Module Registers (MAM)
+#define MAMCR SCB->mam.cr /* Control Register */
+#define MAMTIM SCB->mam.tim /* Timing Control Register */
+
+// Memory Mapping Control Register
+#define MEMMAP SCB->memmap
+
+// Phase Locked Loop Registers (PLL)
+#define PLLCON SCB->pll.con /* Control Register */
+#define PLLCFG SCB->pll.cfg /* Configuration Register */
+#define PLLSTAT SCB->pll.stat /* Status Register */
+#define PLLFEED SCB->pll.feed /* Feed Register */
+
+// Power Control Registers
+#define PCON SCB->p.con /* Control Register */
+#define PCONP SCB->p.conp /* Peripherals Register */
+
+// VPB Divider Register
+#define VPBDIV SCB->vpbdiv
+
+// External Interrupt Registers
+#define EXTINT SCB->ext.flag /* Flag Register */
+#define EXTWAKE SCB->ext.wake /* Wakeup Register */
+#define EXTMODE SCB->ext.mode /* Mode Register */
+#define EXTPOLAR SCB->ext.polar /* Polarity Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// External Memory Controller (EMC)
+#define EMC ((volatile emcRegs_t *)0xFFE00000)
+
+// External Memory Controller Registers
+#define BCFG0 EMC->bcfg0 /* Bank 0 Configuration Register */
+#define BCFG1 EMC->bcfg1 /* Bank 1 Configuration Register */
+#define BCFG2 EMC->bcfg2 /* Bank 2 Configuration Register */
+#define BCFG3 EMC->bcfg3 /* Bank 3 Configuration Register */
+
+///////////////////////////////////////////////////////////////////////////////
+// Vectored Interrupt Controller
+#define VIC ((vicRegs_t *)0xFFFFF000)
+
+// Vectored Interrupt Controller Registers
+#define VICIRQStatus VIC->irqStatus /* IRQ Status Register */
+#define VICFIQStatus VIC->fiqStatus /* FIQ Status Register */
+#define VICRawIntr VIC->rawIntr /* Raw Interrupt Status Register */
+#define VICIntSelect VIC->intSelect /* Interrupt Select Register */
+#define VICIntEnable VIC->intEnable /* Interrupt Enable Register */
+#define VICIntEnClear VIC->intEnClear /* Interrupt Enable Clear Register */
+#define VICSoftInt VIC->softInt /* Software Interrupt Register */
+#define VICSoftIntClear VIC->softIntClear /* Software Interrupt Clear Register */
+#define VICProtection VIC->protection /* Protection Enable Register */
+#define VICVectAddr VIC->vectAddr /* Vector Address Register */
+#define VICDefVectAddr VIC->defVectAddr /* Default Vector Address Register */
+#define VICVectAddr0 VIC->vectAddr0 /* Vector Address 0 Register */
+#define VICVectAddr1 VIC->vectAddr1 /* Vector Address 1 Register */
+#define VICVectAddr2 VIC->vectAddr2 /* Vector Address 2 Register */
+#define VICVectAddr3 VIC->vectAddr3 /* Vector Address 3 Register */
+#define VICVectAddr4 VIC->vectAddr4 /* Vector Address 4 Register */
+#define VICVectAddr5 VIC->vectAddr5 /* Vector Address 5 Register */
+#define VICVectAddr6 VIC->vectAddr6 /* Vector Address 6 Register */
+#define VICVectAddr7 VIC->vectAddr7 /* Vector Address 7 Register */
+#define VICVectAddr8 VIC->vectAddr8 /* Vector Address 8 Register */
+#define VICVectAddr9 VIC->vectAddr9 /* Vector Address 9 Register */
+#define VICVectAddr10 VIC->vectAddr10 /* Vector Address 10 Register */
+#define VICVectAddr11 VIC->vectAddr11 /* Vector Address 11 Register */
+#define VICVectAddr12 VIC->vectAddr12 /* Vector Address 12 Register */
+#define VICVectAddr13 VIC->vectAddr13 /* Vector Address 13 Register */
+#define VICVectAddr14 VIC->vectAddr14 /* Vector Address 14 Register */
+#define VICVectAddr15 VIC->vectAddr15 /* Vector Address 15 Register */
+#define VICVectCntl0 VIC->vectCntl0 /* Vector Control 0 Register */
+#define VICVectCntl1 VIC->vectCntl1 /* Vector Control 1 Register */
+#define VICVectCntl2 VIC->vectCntl2 /* Vector Control 2 Register */
+#define VICVectCntl3 VIC->vectCntl3 /* Vector Control 3 Register */
+#define VICVectCntl4 VIC->vectCntl4 /* Vector Control 4 Register */
+#define VICVectCntl5 VIC->vectCntl5 /* Vector Control 5 Register */
+#define VICVectCntl6 VIC->vectCntl6 /* Vector Control 6 Register */
+#define VICVectCntl7 VIC->vectCntl7 /* Vector Control 7 Register */
+#define VICVectCntl8 VIC->vectCntl8 /* Vector Control 8 Register */
+#define VICVectCntl9 VIC->vectCntl9 /* Vector Control 9 Register */
+#define VICVectCntl10 VIC->vectCntl10 /* Vector Control 10 Register */
+#define VICVectCntl11 VIC->vectCntl11 /* Vector Control 11 Register */
+#define VICVectCntl12 VIC->vectCntl12 /* Vector Control 12 Register */
+#define VICVectCntl13 VIC->vectCntl13 /* Vector Control 13 Register */
+#define VICVectCntl14 VIC->vectCntl14 /* Vector Control 14 Register */
+#define VICVectCntl15 VIC->vectCntl15 /* Vector Control 15 Register */
+
+#endif
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+include_HEADERS = $(notdir $(wildcard $(SOURCES_DIR)/*.h))
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * This module provides the interface definitions for setting up and
+ * controlling the various interrupt modes present on the ARM processor.
+ * Copyright 2004, R O SoftWare
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ *****************************************************************************/
+#ifndef INC_ARM_VIC_H
+#define INC_ARM_VIC_H
+
+/******************************************************************************
+ *
+ * MACRO Name: ISR_ENTRY()
+ *
+ * Description:
+ * This MACRO is used upon entry to an ISR. The current version of
+ * the gcc compiler for ARM does not produce correct code for
+ * interrupt routines to operate properly with THUMB code. The MACRO
+ * performs the following steps:
+ *
+ * 1 - Adjust address at which execution should resume after servicing
+ * ISR to compensate for IRQ entry
+ * 2 - Save the non-banked registers r0-r12 and lr onto the IRQ stack.
+ * 3 - Get the status of the interrupted program is in SPSR.
+ * 4 - Push it onto the IRQ stack as well.
+ *
+ *****************************************************************************/
+#define ISR_ENTRY() asm volatile(" sub lr, lr,#4\n" \
+ " stmfd sp!,{r0-r12,lr}\n" \
+ " mrs r1, spsr\n" \
+ " stmfd sp!,{r1}")
+
+/******************************************************************************
+ *
+ * MACRO Name: ISR_EXIT()
+ *
+ * Description:
+ * This MACRO is used to exit an ISR. The current version of the gcc
+ * compiler for ARM does not produce correct code for interrupt
+ * routines to operate properly with THUMB code. The MACRO performs
+ * the following steps:
+ *
+ * 1 - Recover SPSR value from stack
+ * 2 - and restore its value
+ * 3 - Pop the return address & the saved general registers from
+ * the IRQ stack & return
+ *
+ *****************************************************************************/
+#define ISR_EXIT() asm volatile(" ldmfd sp!,{r1}\n" \
+ " msr spsr_c,r1\n" \
+ " ldmfd sp!,{r0-r12,pc}^")
+
+/******************************************************************************
+ *
+ * Function Name: disableIRQ()
+ *
+ * Description:
+ * This function sets the IRQ disable bit in the status register
+ *
+ * Calling Sequence:
+ * void
+ *
+ * Returns:
+ * previous value of CPSR
+ *
+ *****************************************************************************/
+unsigned disableIRQ(void);
+
+/******************************************************************************
+ *
+ * Function Name: enableIRQ()
+ *
+ * Description:
+ * This function clears the IRQ disable bit in the status register
+ *
+ * Calling Sequence:
+ * void
+ *
+ * Returns:
+ * previous value of CPSR
+ *
+ *****************************************************************************/
+unsigned enableIRQ(void);
+
+/******************************************************************************
+ *
+ * Function Name: restoreIRQ()
+ *
+ * Description:
+ * This function restores the IRQ disable bit in the status register
+ * to the value contained within passed oldCPSR
+ *
+ * Calling Sequence:
+ * void
+ *
+ * Returns:
+ * previous value of CPSR
+ *
+ *****************************************************************************/
+unsigned restoreIRQ(unsigned oldCPSR);
+
+/******************************************************************************
+ *
+ * Function Name: disableFIQ()
+ *
+ * Description:
+ * This function sets the FIQ disable bit in the status register
+ *
+ * Calling Sequence:
+ * void
+ *
+ * Returns:
+ * previous value of CPSR
+ *
+ *****************************************************************************/
+unsigned disableFIQ(void);
+
+/******************************************************************************
+ *
+ * Function Name: enableFIQ()
+ *
+ * Description:
+ * This function clears the FIQ disable bit in the status register
+ *
+ * Calling Sequence:
+ * void
+ *
+ * Returns:
+ * previous value of CPSR
+ *
+ *****************************************************************************/
+unsigned enableFIQ(void);
+
+/******************************************************************************
+ *
+ * Function Name: restoreIRQ()
+ *
+ * Description:
+ * This function restores the FIQ disable bit in the status register
+ * to the value contained within passed oldCPSR
+ *
+ * Calling Sequence:
+ * void
+ *
+ * Returns:
+ * previous value of CPSR
+ *
+ *****************************************************************************/
+unsigned restoreFIQ(unsigned oldCPSR);
+
+#endif
--- /dev/null
+#ifndef INC_LPC_ADC_214x_H
+#define INC_LPC_ADC_214x_H
+
+// A/D Converter Registers
+typedef struct
+{
+ REG32 cr; // Control Register
+ REG32 gdr; // Global Data Register
+ REG32 gsr; // Global Start Register
+ REG32 inten; // Interrupt Enable Register
+ REG32 dr0; // Channel 0 Data Register
+ REG32 dr1; // Channel 1 Data Register
+ REG32 dr2; // Channel 2 Data Register
+ REG32 dr3; // Channel 3 Data Register
+ REG32 dr4; // Channel 4 Data Register
+ REG32 dr5; // Channel 5 Data Register
+ REG32 dr6; // Channel 6 Data Register
+ REG32 dr7; // Channel 7 Data Register
+ REG32 stat; // Status Register
+} adc214xRegs_t;
+
+#define ADCR_SEL 0x000000FF
+#define ADCR_CLKDIV 0x0000FF00
+#define ADCR_BURST 0x00010000
+#define ADCR_CLKS 0x000E0000
+#define ADCR_PDN 0x00200000
+#define ADCR_START 0x07000000
+#define ADCR_EDGE 0x08000000
+
+#define ADGDR_RESULT 0x0000FFC0
+#define ADGDR_CHN 0x07000000
+#define ADGDR_OVERRUN 0x40000000
+#define ADGDR_DONE 0x80000000
+
+#define ADGSR_BURST 0x00010000
+#define ADGSR_START 0x07000000
+#define ADGSR_EDGE 0x08000000
+
+#define ADSTAT_DONE 0x000000FF
+#define ADSTAT_DONE0 0x00000001
+#define ADSTAT_DONE1 0x00000002
+#define ADSTAT_DONE2 0x00000004
+#define ADSTAT_DONE3 0x00000008
+#define ADSTAT_DONE4 0x00000010
+#define ADSTAT_DONE5 0x00000020
+#define ADSTAT_DONE6 0x00000040
+#define ADSTAT_DONE7 0x00000080
+#define ADSTAT_OVERRUN 0x0000FF00
+#define ADSTAT_OVERRUN0 0x00000100
+#define ADSTAT_OVERRUN1 0x00000200
+#define ADSTAT_OVERRUN2 0x00000400
+#define ADSTAT_OVERRUN3 0x00000800
+#define ADSTAT_OVERRUN4 0x00001000
+#define ADSTAT_OVERRUN5 0x00002000
+#define ADSTAT_OVERRUN6 0x00004000
+#define ADSTAT_OVERRUN7 0x00008000
+#define ADSTAT_ADINT 0x00010000
+
+#define ADINTEN_INTEN 0x000000FF
+#define ADINTEN_INTEN0 0x00000001
+#define ADINTEN_INTEN1 0x00000002
+#define ADINTEN_INTEN2 0x00000004
+#define ADINTEN_INTEN3 0x00000008
+#define ADINTEN_INTEN4 0x00000010
+#define ADINTEN_INTEN5 0x00000020
+#define ADINTEN_INTEN6 0x00000040
+#define ADINTEN_INTEN7 0x00000080
+#define ADINTEN_GINTEN 0x00000100
+
+#define ADDR_RESULT 0x0000FFC0
+#define ADDR_OVERRUN 0x40000000
+#define ADDR_DONE 0x80000000
+
+#endif
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * Header file for Philips LPC ARM Processors.
+ * Copyright 2004 R O SoftWare
+ *
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ *****************************************************************************/
+#ifndef INC_LPC_ADC_H
+#define INC_LPC_ADC_H
+
+// A/D Converter Registers
+typedef struct
+{
+ REG32 cr; // Control Register
+ REG32 dr; // Data Register
+} adcRegs_t;
+
+#endif
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * Header file for Philips LPC ARM Processors.
+ * Copyright 2004 R O SoftWare
+ *
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ *****************************************************************************/
+#ifndef INC_LPC_EMC_H
+#define INC_LPC_EMC_H
+
+// External Memory Controller Registers
+typedef struct
+{
+ REG32 bcfg0; // Bank 0 Configuration Register
+ REG32 bcfg1; // Bank 1 Configuration Register
+ REG32 bcfg2; // Bank 2 Configuration Register
+ REG32 bcfg3; // Bank 3 Configuration Register
+} emcRegs_t;
+
+#endif
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * Header file for Philips LPC ARM Processors.
+ * Copyright 2004 R O SoftWare
+ *
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ *****************************************************************************/
+#ifndef INC_LPC_GPIO_H
+#define INC_LPC_GPIO_H
+
+// General Purpose Input/Output Registers (GPIO)
+typedef struct
+{
+ REG32 in0; // P0 Pin Value Register
+ REG32 set0; // P0 Pin Output Set Register
+ REG32 dir0; // P0 Pin Direction Register
+ REG32 clr0; // P0 Pin Output Clear Register
+ REG32 in1; // P1 Pin Value Register
+ REG32 set1; // P1 Pin Output Set Register
+ REG32 dir1; // P1 Pin Direction Register
+ REG32 clr1; // P1 Pin Output Clear Register
+ REG32 in2; // P2 Pin Value Register
+ REG32 set2; // P2 Pin Output Set Register
+ REG32 dir2; // P2 Pin Direction Register
+ REG32 clr2; // P2 Pin Output Clear Register
+ REG32 in3; // P3 Pin Value Register
+ REG32 set3; // P3 Pin Output Set Register
+ REG32 dir3; // P3 Pin Direction Register
+ REG32 clr3; // P3 Pin Output Clear Register
+} gpioRegs_t;
+
+#endif
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * Header file for Philips LPC ARM Processors.
+ * Copyright 2004 R O SoftWare
+ *
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ *****************************************************************************/
+#ifndef INC_LPC_I2C_H
+#define INC_LPC_I2C_H
+
+// I2C Interface Registers
+typedef struct
+{
+ REG_8 conset; // Control Set Register
+ REG_8 _pad0[3];
+ REG_8 stat; // Status Register
+ REG_8 _pad1[3];
+ REG_8 dat; // Data Register
+ REG_8 _pad2[3];
+ REG_8 adr; // Slave Address Register
+ REG_8 _pad3[3];
+ REG16 sclh; // SCL Duty Cycle Register (high half word)
+ REG16 _pad4;
+ REG16 scll; // SCL Duty Cycle Register (low half word)
+ REG16 _pad5;
+ REG_8 conclr; // Control Clear Register
+ REG_8 _pad6[3];
+} i2cRegs_t;
+
+#endif
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * Header file for Philips LPC ARM Processors.
+ * Copyright 2004 R O SoftWare
+ *
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ *****************************************************************************/
+#ifndef INC_LPC_PIN_H
+#define INC_LPC_PIN_H
+
+// Pin Connect Block Registers
+typedef struct
+{
+ REG32 sel0; // Pin Function Select Register 0
+ REG32 sel1; // Pin Function Select Register 1
+ REG32 _pad[3];
+ REG32 sel2; // Pin Function Select Register 2
+} pinRegs_t;
+
+#endif
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * Header file for Philips LPC ARM Processors.
+ * Copyright 2004 R O SoftWare
+ *
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ *****************************************************************************/
+#ifndef INC_LPC_RTC_H
+#define INC_LPC_RTC_H
+
+typedef struct
+{
+ REG_8 ilr; // Interrupt Location Register
+ REG_8 _pad0[3];
+ REG16 ctc; // Clock Tick Counter
+ REG16 _pad1;
+ REG_8 ccr; // Clock Control Register
+ REG_8 _pad2[3];
+ REG_8 ciir; // Counter Increment Interrupt Register
+ REG_8 _pad3[3];
+ REG_8 amr; // Alarm Mask Register
+ REG_8 _pad4[3];
+ REG32 ctime0; // Consolidated Time Register 0
+ REG32 ctime1; // Consolidated Time Register 1
+ REG32 ctime2; // Consolidated Time Register 2
+ REG_8 sec; // Seconds Register
+ REG_8 _pad5[3];
+ REG_8 min; // Minutes Register
+ REG_8 _pad6[3];
+ REG_8 hour; // Hours Register
+ REG_8 _pad7[3];
+ REG_8 dom; // Day Of Month Register
+ REG_8 _pad8[3];
+ REG_8 dow; // Day Of Week Register
+ REG_8 _pad9[3];
+ REG16 doy; // Day Of Year Register
+ REG16 _pad10;
+ REG_8 month; // Months Register
+ REG_8 _pad11[3];
+ REG16 year; // Years Register
+ REG32 _pad12[8];
+ REG_8 alsec; // Alarm Seconds Register
+ REG_8 _pad13[3];
+ REG_8 almin; // Alarm Minutes Register
+ REG_8 _pad14[3];
+ REG_8 alhour; // Alarm Hours Register
+ REG_8 _pad15[3];
+ REG_8 aldom; // Alarm Day Of Month Register
+ REG_8 _pad16[3];
+ REG_8 aldow; // Alarm Day Of Week Register
+ REG_8 _pad17[3];
+ REG16 aldoy; // Alarm Day Of Year Register
+ REG16 _pad18;
+ REG_8 almon; // Alarm Months Register
+ REG_8 _pad19[3];
+ REG16 alyear; // Alarm Years Register
+ REG16 _pad20;
+ REG16 preint; // Prescale Value Register (integer)
+ REG16 _pad21;
+ REG16 prefrac; // Prescale Value Register (fraction)
+ REG16 _pad22;
+} rtcRegs_t;
+
+#endif
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * Header file for Philips LPC ARM Processors.
+ * Copyright 2004 R O SoftWare
+ *
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ *****************************************************************************/
+#ifndef INC_LPC_SCB_H
+#define INC_LPC_SCB_H
+
+// System Control Block Registers
+typedef struct
+{
+ // Memory Accelerator Module Registers (MAM)
+ struct
+ {
+ REG_8 cr; // Control Register
+ REG_8 _pad0[3];
+ REG_8 tim; // Timing Control Register
+ REG32 _pad1[14];
+ } mam;
+
+ // Memory Mapping Control Register
+ REG_8 memmap;
+ REG32 _pad0[15];
+
+ // Phase Locked Loop Registers (PLL)
+ struct
+ {
+ REG_8 con; // Control Register
+ REG_8 _pad0[3];
+ REG_8 cfg; // Configuration Register
+ REG_8 _pad1[3];
+ REG16 stat; // Status Register
+ REG16 _pad2;
+ REG_8 feed; // Feed Register
+ REG_8 _pad3[3];
+ REG32 _pad4[4];
+ } pll;
+
+ struct
+ {
+ REG_8 con; // Control Register
+ REG_8 _pad0[3];
+ REG_8 cfg; // Configuration Register
+ REG_8 _pad1[3];
+ REG16 stat; // Status Register
+ REG16 _pad2;
+ REG_8 feed; // Feed Register
+ REG_8 _pad3[3];
+ REG32 _pad4[4];
+ } pll48;
+
+ // Power Control Registers
+ struct
+ {
+ REG_8 con; // Control Register
+ REG_8 _pad0[3];
+ REG32 conp; // Peripherals Register
+ REG32 _pad1[14];
+ } p;
+
+ // VPB Divider Register
+ REG_8 vpbdiv;
+ REG32 _pad1[15];
+
+ // External Interrupt Registers
+ struct
+ {
+ REG_8 flag; // Flag Register
+ REG_8 _pad0[3];
+ REG_8 wake; // Wakeup Register
+ REG_8 _pad1[3];
+ REG_8 mode; // Mode Register
+ REG_8 _pad2[3];
+ REG_8 polar; // Polarity Register
+ REG32 _pad3[12];
+ } ext;
+} scbRegs_t;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// MAM defines
+#define MAMCR_OFF 0
+#define MAMCR_PART 1
+#define MAMCR_FULL 2
+
+#define MAMTIM_CYCLES (((CCLK) + 19999999) / 20000000)
+
+///////////////////////////////////////////////////////////////////////////////
+// MEMMAP defines
+#define MEMMAP_BBLK 0 // Interrupt Vectors in Boot Block
+#define MEMMAP_FLASH 1 // Interrupt Vectors in Flash
+#define MEMMAP_SRAM 2 // Interrupt Vectors in SRAM
+
+///////////////////////////////////////////////////////////////////////////////
+// PLL defines & computations
+// Compute the value of PLL_DIV and test range validity
+// FOSC & PLL_MUL should be defined in project configuration file (config.h)
+#ifndef CCLK
+#define CCLK (FOSC * PLL_MUL) // CPU Clock Freq.
+#endif
+
+#define FCCO_MAX (320000000) // Max CC Osc Freq.
+#define PLL_DIV (FCCO_MAX / (2 * CCLK)) // PLL Divider
+#define FCCO (FOSC * PLL_MUL * 2 * PLL_DIV) // CC Osc. Freq.
+
+// PLLCON Register Bit Definitions
+#define PLLCON_PLLE (1 << 0) // PLL Enable
+#define PLLCON_PLLC (1 << 1) // PLL Connect
+
+// PLLCFG Register Bit Definitions
+#define PLLCFG_MSEL ((PLL_MUL - 1) << 0) // PLL Multiplier
+#define PLLCFG_PSEL ((PLL_DIV - 1) << 5) // PLL Divider
+
+// PLLSTAT Register Bit Definitions
+#define PLLSTAT_LOCK (1 << 10) // PLL Lock Status Bit
+
+///////////////////////////////////////////////////////////////////////////////
+// VPBDIV defines & computations
+#define VPBDIV_VALUE (PBSD & 0x03) // VPBDIV value
+
+#endif
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * Header file for Philips LPC ARM Processors.
+ * Copyright 2004 R O SoftWare
+ *
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ *****************************************************************************/
+#ifndef INC_LPC_SPI_H
+#define INC_LPC_SPI_H
+
+// Serial Peripheral Interface Registers (SPI)
+typedef struct
+{
+ REG_8 cr; // Control Register
+ REG_8 _pad0[3];
+ REG_8 sr; // Status Register
+ REG_8 _pad1[3];
+ REG_8 dr; // Data Register
+ REG_8 _pad2[3];
+ REG_8 ccr; // Clock Counter Register
+ REG_8 _pad3[3];
+ REG_8 tcr; // Test Control Register
+ REG_8 _pad4[3];
+ REG_8 tsr; // Test Status Register
+ REG_8 _pad5[3];
+ REG_8 tor; // Test Observe Register
+ REG_8 _pad6[3];
+ REG_8 flag; // Interrupt Flag Register
+ REG_8 _pad7[3];
+} spiRegs_t;
+
+
+// SPI Control Register
+#define SPCR_BE (1 << 2) // BitEnable : If set the SPI controller
+ // sends and receives the number of bits
+ // selected by bits 11:8.
+#define SPCR_CPHA (1 << 3) // Clock phase control
+#define SPCR_CPOL (1 << 4) // Clock polarity control.
+#define SPCR_MSTR (1 << 5) // Master mode select.
+#define SPCR_LSBF (1 << 6) // LSB First controls
+#define SPCR_SPIE (1 << 7) // Serial peripheral interrupt enable.
+#define SPCR_BITS (0xF << 8) // When bit 2 of this register is 1,
+ // this field controls the number of
+ // bits per transfer
+ // 1000 : 8 bits per transfer
+ // 1001 : 9 bits per transfer
+ // 1010 : 10 bits per transfer
+ // 1011 : 11 bits per transfer
+ // 1100 : 12 bits per transfer
+ // 1101 : 13 bits per transfer
+ // 1110 : 14 bits per transfer
+ // 1111 : 15 bits per transfer
+ // 0000 : 16 bits per transfer
+
+//SPI Status Register
+#define SPSR_ABRT (1 << 3) // Slave abort.
+#define SPSR_MODF (1 << 4) // Mode fault.
+#define SPSR_ROVR (1 << 5) // Read overrun.
+#define SPSR_WCOL (1 << 6) // Write collision.
+#define SPSR_SPIF (1 << 7) // SPI transfer complete flag.
+
+//SPI Interrupt register
+#define SPINT_IF (1 << 0) // SPI interrupt flag.
+
+
+#endif
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * Header file for Philips LPC ARM Processors.
+ * Copyright 2004 R O SoftWare
+ *
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ *****************************************************************************/
+#ifndef INC_LPC_TMR_H
+#define INC_LPC_TMR_H
+
+// Timer & PWM Registers
+typedef struct
+{
+ REG32 ir; // Interrupt Register
+ REG32 tcr; // Timer Control Register
+ REG32 tc; // Timer Counter
+ REG32 pr; // Prescale Register
+ REG32 pc; // Prescale Counter Register
+ REG32 mcr; // Match Control Register
+ REG32 mr0; // Match Register 0
+ REG32 mr1; // Match Register 1
+ REG32 mr2; // Match Register 2
+ REG32 mr3; // Match Register 3
+ REG32 ccr; // Capture Control Register
+ REG32 cr0; // Capture Register 0
+ REG32 cr1; // Capture Register 1
+ REG32 cr2; // Capture Register 2
+ REG32 cr3; // Capture Register 3
+ REG32 emr; // External Match Register
+ REG32 mr4; // Match Register 4
+ REG32 mr5; // Match Register 5
+ REG32 mr6; // Match Register 6
+ REG32 pcr; // Control Register
+ REG32 ler; // Latch Enable Register
+} pwmTmrRegs_t;
+
+// Timer Interrupt Register Bit Definitions
+#define TIR_MR0I (1 << 0) // Interrupt flag for match channel 0
+#define TIR_MR1I (1 << 1) // Interrupt flag for match channel 1
+#define TIR_MR2I (1 << 2) // Interrupt flag for match channel 2
+#define TIR_MR3I (1 << 3) // Interrupt flag for match channel 3
+#define TIR_CR0I (1 << 4) // Interrupt flag for capture channel 0 event
+#define TIR_CR1I (1 << 5) // Interrupt flag for capture channel 1 event
+#define TIR_CR2I (1 << 6) // Interrupt flag for capture channel 2 event
+#define TIR_CR3I (1 << 7) // Interrupt flag for capture channel 3 event
+
+// PWM Interrupt Register Bit Definitions
+#define PWMIR_MR0I (1 << 0) // Interrupt flag for match channel 0
+#define PWMIR_MR1I (1 << 1) // Interrupt flag for match channel 1
+#define PWMIR_MR2I (1 << 2) // Interrupt flag for match channel 2
+#define PWMIR_MR3I (1 << 3) // Interrupt flag for match channel 3
+#define PWMIR_MR4I (1 << 8) // Interrupt flag for match channel 4
+#define PWMIR_MR5I (1 << 9) // Interrupt flag for match channel 5
+#define PWMIR_MR6I (1 << 10) // Interrupt flag for match channel 6
+#define PWMIR_MASK (0x070F)
+
+// Timer Control Register Bit Definitions
+#define TCR_ENABLE (1 << 0)
+#define TCR_RESET (1 << 1)
+
+// PWM Control Register Bit Definitions
+#define PWMCR_ENABLE (1 << 0)
+#define PWMCR_RESET (1 << 1)
+
+// PWM Latch Enable Register Bit Definitions
+#define PWMLER_PWML0E (1<<0)
+#define PWMLER_PWML1E (1<<1)
+#define PWMLER_PWML2E (1<<2)
+#define PWMLER_PWML3E (1<<3)
+#define PWMLER_PWML4E (1<<4)
+#define PWMLER_PWML5E (1<<5)
+#define PWMLER_PWML6E (1<<6)
+
+// Timer Match Control Register Bit Definitions
+#define TMCR_MR0_I (1 << 0) // Enable Interrupt when MR0 matches TC
+#define TMCR_MR0_R (1 << 1) // Enable Reset of TC upon MR0 match
+#define TMCR_MR0_S (1 << 2) // Enable Stop of TC upon MR0 match
+#define TMCR_MR1_I (1 << 3) // Enable Interrupt when MR1 matches TC
+#define TMCR_MR1_R (1 << 4) // Enable Reset of TC upon MR1 match
+#define TMCR_MR1_S (1 << 5) // Enable Stop of TC upon MR1 match
+#define TMCR_MR2_I (1 << 6) // Enable Interrupt when MR2 matches TC
+#define TMCR_MR2_R (1 << 7) // Enable Reset of TC upon MR2 match
+#define TMCR_MR2_S (1 << 8) // Enable Stop of TC upon MR2 match
+#define TMCR_MR3_I (1 << 9) // Enable Interrupt when MR3 matches TC
+#define TMCR_MR3_R (1 << 10) // Enable Reset of TC upon MR3 match
+#define TMCR_MR3_S (1 << 11) // Enable Stop of TC upon MR3 match
+
+// Timer Capture Control Register Bit Definitions
+#define TCCR_CR0_R (1 << 0) // Enable Rising edge on CAPn.0 will load TC to CR0
+#define TCCR_CR0_F (1 << 1) // Enable Falling edge on CAPn.0 will load TC to CR0
+#define TCCR_CR0_I (1 << 2) // Enable Interrupt on load of CR0
+#define TCCR_CR1_R (1 << 3) // Enable Rising edge on CAPn.1 will load TC to CR1
+#define TCCR_CR1_F (1 << 4) // Enable Falling edge on CAPn.1 will load TC to CR1
+#define TCCR_CR1_I (1 << 5) // Enable Interrupt on load of CR1
+#define TCCR_CR2_R (1 << 6) // Enable Rising edge on CAPn.2 will load TC to CR2
+#define TCCR_CR2_F (1 << 7) // Enable Falling edge on CAPn.2 will load TC to CR2
+#define TCCR_CR2_I (1 << 8) // Enable Interrupt on load of CR2
+#define TCCR_CR3_R (1 << 9) // Enable Rising edge on CAPn.3 will load TC to CR3
+#define TCCR_CR3_F (1 << 10) // Enable Falling edge on CAPn.3 will load TC to CR3
+#define TCCR_CR3_I (1 << 11) // Enable Interrupt on load of CR3
+
+#endif
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * Header file for Philips LPC ARM Processors.
+ * Copyright 2004 R O SoftWare
+ *
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ *****************************************************************************/
+#ifndef INC_LPC_UART_H
+#define INC_LPC_UART_H
+
+// Universal Asynchronous Receiver Transmitter Registers
+typedef struct
+{
+ union
+ {
+ REG_8 rbr; // Receive Buffer Register
+ REG_8 thr; // Transmit Holding Register
+ REG_8 dll; // Divisor Latch Register (LSB)
+ REG_8 _pad0[4];
+ };
+
+ union
+ {
+ REG_8 ier; // Interrupt Enable Register
+ REG_8 dlm; // Divisor Latch Register (MSB)
+ REG_8 _pad1[4];
+ };
+
+ union
+ {
+ REG_8 iir; // Interrupt ID Register
+ REG_8 fcr; // FIFO Control Register
+ REG_8 _pad2[4];
+ };
+
+ REG_8 lcr; // Line Control Registe
+ REG_8 _pad3[3];
+ REG_8 mcr; // MODEM Control Register
+ REG_8 _pad4[3];
+ REG_8 lsr; // Line Status Register
+ REG_8 _pad5[3];
+ REG_8 msr; // MODEM Status Register
+ REG_8 _pad6[3];
+ REG_8 scr; // Scratch Pad Register
+ REG_8 _pad7[3];
+} uartRegs_t;
+
+///////////////////////////////////////////////////////////////////////////////
+// UART defines
+
+// Interrupt Enable Register bit definitions
+#define UIER_ERBFI (1 << 0) // Enable Receive Data Available Interrupt
+#define UIER_ETBEI (1 << 1) // Enable Transmit Holding Register Empty Interrupt
+#define UIER_ELSI (1 << 2) // Enable Receive Line Status Interrupt
+#define UIER_EDSSI (1 << 3) // Enable MODEM Status Interrupt
+
+// Interrupt ID Register bit definitions
+#define UIIR_NO_INT (1 << 0) // NO INTERRUPTS PENDING
+#define UIIR_MS_INT (0 << 1) // MODEM Status
+#define UIIR_THRE_INT (1 << 1) // Transmit Holding Register Empty
+#define UIIR_RDA_INT (2 << 1) // Receive Data Available
+#define UIIR_RLS_INT (3 << 1) // Receive Line Status
+#define UIIR_CTI_INT (6 << 1) // Character Timeout Indicator
+#define UIIR_ID_MASK 0x0E
+
+// FIFO Control Register bit definitions
+#define UFCR_FIFO_ENABLE (1 << 0) // FIFO Enable
+#define UFCR_RX_FIFO_RESET (1 << 1) // Reset Receive FIFO
+#define UFCR_TX_FIFO_RESET (1 << 2) // Reset Transmit FIFO
+#define UFCR_FIFO_TRIG1 (0 << 6) // Trigger @ 1 character in FIFO
+#define UFCR_FIFO_TRIG4 (1 << 6) // Trigger @ 4 characters in FIFO
+#define UFCR_FIFO_TRIG8 (2 << 6) // Trigger @ 8 characters in FIFO
+#define UFCR_FIFO_TRIG14 (3 << 6) // Trigger @ 14 characters in FIFO
+
+// Line Control Register bit definitions
+#define ULCR_CHAR_5 (0 << 0) // 5-bit character length
+#define ULCR_CHAR_6 (1 << 0) // 6-bit character length
+#define ULCR_CHAR_7 (2 << 0) // 7-bit character length
+#define ULCR_CHAR_8 (3 << 0) // 8-bit character length
+#define ULCR_STOP_1 (0 << 2) // 1 stop bit
+#define ULCR_STOP_2 (1 << 2) // 2 stop bits
+#define ULCR_PAR_NO (0 << 3) // No Parity
+#define ULCR_PAR_ODD (1 << 3) // Odd Parity
+#define ULCR_PAR_EVEN (3 << 3) // Even Parity
+#define ULCR_PAR_MARK (5 << 3) // MARK "1" Parity
+#define ULCR_PAR_SPACE (7 << 3) // SPACE "0" Paruty
+#define ULCR_BREAK_ENABLE (1 << 6) // Output BREAK line condition
+#define ULCR_DLAB_ENABLE (1 << 7) // Enable Divisor Latch Access
+
+// Modem Control Register bit definitions
+#define UMCR_DTR (1 << 0) // Data Terminal Ready
+#define UMCR_RTS (1 << 1) // Request To Send
+#define UMCR_LB (1 << 4) // Loopback
+
+// Line Status Register bit definitions
+#define ULSR_RDR (1 << 0) // Receive Data Ready
+#define ULSR_OE (1 << 1) // Overrun Error
+#define ULSR_PE (1 << 2) // Parity Error
+#define ULSR_FE (1 << 3) // Framing Error
+#define ULSR_BI (1 << 4) // Break Interrupt
+#define ULSR_THRE (1 << 5) // Transmit Holding Register Empty
+#define ULSR_TEMT (1 << 6) // Transmitter Empty
+#define ULSR_RXFE (1 << 7) // Error in Receive FIFO
+#define ULSR_ERR_MASK 0x1E
+
+// Modem Status Register bit definitions
+#define UMSR_DCTS (1 << 0) // Delta Clear To Send
+#define UMSR_DDSR (1 << 1) // Delta Data Set Ready
+#define UMSR_TERI (1 << 2) // Trailing Edge Ring Indicator
+#define UMSR_DDCD (1 << 3) // Delta Data Carrier Detect
+#define UMSR_CTS (1 << 4) // Clear To Send
+#define UMSR_DSR (1 << 5) // Data Set Ready
+#define UMSR_RI (1 << 6) // Ring Indicator
+#define UMSR_DCD (1 << 7) // Data Carrier Detect
+
+#endif
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * Header file for Philips LPC214x USB enabled ARM Processors
+ * Copyright 2006 Pavel Pisa <pisa@cmp.felk.cvut.cz>
+ *
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact or GPL license is applied.
+ *
+ *****************************************************************************/
+
+#ifndef _lpcUSB_H
+#define _lpcUSB_H
+
+/* USBIntSt - USB Interrupt Status (R/W) */
+#define USB_INT_REQ_LP (1<<0) /*Low priority interrupt line status (RO) */
+#define USB_INT_REQ_HP (1<<1) /*High priority interrupt line status. (RO) */
+#define USB_INT_REQ_DMA (1<<2) /*DMA interrupt line status. This bit is read only. (LPC2146/8 only) 0*/
+#define USB_need_clock (1<<8) /*USB need clock indicator*/
+#define USB_EN_USB_INTS (1<<31) /*Enable all USB interrupts*/
+
+/* Device interrupt registers */
+#define USBDevIntSt_o 0x0000 /* USB Device Interrupt Status (RO) */
+#define USBDevIntEn_o 0x0004 /* USB Device Interrupt Enable (R/W) */
+#define USBDevIntClr_o 0x0008 /* USB Device Interrupt Clear (WO) */
+#define USBDevIntSet_o 0x000C /* USB Device Interrupt Set (WO) */
+#define USBDevInt_FRAME (1<<0) /*Frame interrupt @1kHz for ISO transfers*/
+#define USBDevInt_EP_FAST (1<<1) /*Fast interrupt transfer for the endpoint*/
+#define USBDevInt_EP_SLOW (1<<2) /*Slow interrupt transfer for the endpoint*/
+#define USBDevInt_DEV_STAT (1<<3) /*USB Bus reset, USB suspend change or Connect occured*/
+#define USBDevInt_CCEMTY (1<<4) /*Command code register is empty/ready for CMD*/
+#define USBDevInt_CDFULL (1<<5) /*Command data register is full/data available*/
+#define USBDevInt_RxENDPKT (1<<6) /*Current packet in the FIFO is transferred to the CPU*/
+#define USBDevInt_TxENDPKT (1<<7) /*TxPacket bytes written to FIFO*/
+#define USBDevInt_EP_RLZED (1<<8) /*Endpoints realized after Maxpacket size update*/
+#define USBDevInt_ERR_INT (1<<9) /*Error Interrupt - Use Read Error Status Command 0xFB*/
+
+#define USBDevIntPri_o 0x002C /* USB Device Interrupt Priority (WO) */
+#define USBDevIntPri_FRAME (1<<0) /*0/1 FRAME int routed to the low/high priority interrupt line*/
+#define USBDevIntPri_EP_FAST (1<<1) /*0/1 EP_FAST int routed to the low/high priority line*/
+
+/* Endpoint interrupt registers - bits corresponds to EP0 to EP31 */
+#define USBEpIntSt_o 0x0030 /* USB Endpoint Interrupt Status (RO) */
+#define USBEpIntEn_o 0x0034 /* USB Endpoint Interrupt Enable (R/W) */
+#define USBEpIntClr_o 0x0038 /* USB Endpoint Interrupt Clear (WO) */
+#define USBEpIntSet_o 0x003C /* USB Endpoint Interrupt Set (WO) */
+#define USBEpIntPri_o 0x0040 /* USB Endpoint Priority (WO) */
+/* Endpoint realization registers */
+#define USBReEp_o 0x0044 /* USB Realize Endpoint (R/W) */
+#define USBEpInd_o 0x0048 /* USB Endpoint Index (WO) */
+#define USBEpInd_Ind 0x001F /* Index for subsequent USBMaxPSize (WO) */
+#define USBMaxPSize_o 0x004C /* USB MaxPacketSize (R/W) */
+#define USBMaxPSize_Size 0x03FF /* The maximum packet size value */
+/* USB transfer registers */
+#define USBRxData_o 0x0018 /* USB Receive Data (RO) */
+#define USBRxPLen_o 0x0020 /* USB Receive Packet Length (RO) */
+#define USBRxPLen_PKT_LNGTH (0x03FF) /*Remaining amount of bytes to be read from RAM*/
+#define USBRxPLen_DV (1<<10) /*Data valid. 0 only for error ISO packet*/
+#define USBRxPLen_PKT_RDY (1<<11) /*Packet length valid and packet is ready for reading*/
+#define USBTxData_o 0x001C /* USB Transmit Data (WO) */
+#define USBTxPLen_o 0x0024 /* USB Transmit Packet Length (WO) */
+#define USBTxPLen_PKT_LNGTH (0x03FF) /*Remaining amount of bytes to be written to the EP_RAM*/
+#define USBCtrl_o 0x0028 /* USB Control (R/W) */
+#define USBCtrl_RD_EN (1<<0) /*Read mode control*/
+#define USBCtrl_WR_EN (1<<1) /*Write mode control*/
+#define USBCtrl_LOG_ENDPOINT 0x003C /*Logical Endpoint number*/
+/* Command registers */
+#define USBCmdCode_o 0x0010 /* USB Command Code (WO) */
+#define USBCmdCode_CMD_PHASE 0x0000FF00 /*The command phase*/
+#define USBCmdCode_CMD_CODE 0x00FF0000 /*The code for the command*/
+#define USBCmdData_o 0x0014 /* USB Command Data (RO) */
+/* DMA registers (LPC2146/8 only) */
+#define USBDMARSt_o 0x0050 /* USB DMA Request Status (RO) */
+#define USBDMARClr_o 0x0054 /* USB DMA Request Clear (WO) */
+#define USBDMARSet_o 0x0058 /* USB DMA Request Set (WO) */
+#define USBUDCAH_o 0x0080 /* USB UDCA Head (R/W) has to be aligned to 128 bytes */
+#define USBEpDMASt_o 0x0084 /* USB Endpoint DMA Status (RO) */
+#define USBEpDMAEn_o 0x0088 /* USB Endpoint DMA Enable (WO) */
+#define USBEpDMADis_o 0x008C /* USB Endpoint DMA Disable (WO) */
+#define USBDMAIntSt_o 0x0090 /* USB DMA Interrupt Status (RO) */
+#define USBDMAIntEn_o 0x0094 /* USB DMA Interrupt Enable (R/W) */
+#define USBDMAInt_EoT (1<<0) /*End of Transfer Interrupt bit, 1 if USBEoTIntSt != 0*/
+#define USBDMAInt_New_DD_Rq (1<<1) /* New DD Request Interrupt bit, 1 if USBNDDRIntSt != 0*/
+#define USBDMAInt_SysError (1<<2) /*System Error Interrupt bit, 1 if USBSysErrIntSt != 0*/
+#define USBEoTIntSt_o 0x00A0 /* USB End of Transfer Interrupt Status (RO) */
+#define USBEoTIntClr_o 0x00A4 /* USB End of Transfer Interrupt Clear (WO) */
+#define USBEoTIntSet_o 0x00A8 /* USB End of Transfer Interrupt Set (WO) */
+#define USBNDDRIntSt_o 0x00AC /* USB New DD Request Interrupt Status (RO) */
+#define USBNDDRIntClr_o 0x00B0 /* USB New DD Request Interrupt Clear (WO) */
+#define USBNDDRIntSet_o 0x00B4 /* USB New DD Request Interrupt Set (WO) */
+#define USBSysErrIntSt_o 0x00B8 /* USB System Error Interrupt Status (RO) */
+#define USBSysErrIntClr_o 0x00BC /* USB System Error Interrupt Clear (WO) */
+#define USBSysErrIntSet_o 0x00C0 /* USB System Error Interrupt Set (WO) */
+#define USB_MODULE_ID_o 0x00FC /* USB Module ID */
+
+/* Command Codes */
+#define USB_CMD_SET_ADDR 0x00D00500
+#define USB_CMD_CFG_DEV 0x00D80500
+#define USB_CMD_SET_MODE 0x00F30500
+#define USB_CMD_RD_FRAME 0x00F50500
+#define USB_DAT_RD_FRAME 0x00F50200
+#define USB_CMD_RD_TEST 0x00FD0500
+#define USB_DAT_RD_TEST 0x00FD0200
+#define USB_CMD_SET_DEV_STAT 0x00FE0500
+#define USB_CMD_GET_DEV_STAT 0x00FE0500
+#define USB_DAT_GET_DEV_STAT 0x00FE0200
+#define USB_CMD_GET_ERR_CODE 0x00FF0500
+#define USB_DAT_GET_ERR_CODE 0x00FF0200
+#define USB_CMD_RD_ERR_STAT 0x00FB0500
+#define USB_DAT_RD_ERR_STAT 0x00FB0200
+#define USB_DAT_WR_BYTE(x) (0x00000100 | ((x) << 16))
+#define USB_CMD_SEL_EP(x) (0x00000500 | ((x) << 16))
+#define USB_DAT_SEL_EP(x) (0x00000200 | ((x) << 16))
+#define USB_CMD_SEL_EP_CLRI(x) (0x00400500 | ((x) << 16))
+#define USB_DAT_SEL_EP_CLRI(x) (0x00400200 | ((x) << 16))
+#define USB_CMD_SET_EP_STAT(x) (0x00400500 | ((x) << 16))
+#define USB_CMD_CLR_BUF 0x00F20500
+#define USB_DAT_CLR_BUF 0x00F20200
+#define USB_CMD_VALID_BUF 0x00FA0500
+
+/* Device Address Register Definitions */
+#define USBC_DEV_ADDR_MASK 0x7F
+#define USBC_DEV_EN 0x80
+
+/* Device Configure Register Definitions */
+#define USBC_CONF_DEVICE 0x01
+
+/* Device Mode Register Definitions */
+#define USBC_AP_CLK 0x01
+#define USBC_INAK_CI 0x02
+#define USBC_INAK_CO 0x04
+#define USBC_INAK_II 0x08
+#define USBC_INAK_IO 0x10
+#define USBC_INAK_BI 0x20
+#define USBC_INAK_BO 0x40
+
+/* Device Status Register Definitions */
+#define USBC_DEV_CON 0x01
+#define USBC_DEV_CON_CH 0x02
+#define USBC_DEV_SUS 0x04
+#define USBC_DEV_SUS_CH 0x08
+#define USBC_DEV_RST 0x10
+
+/* Error Code Register Definitions */
+#define USBC_ERR_EC_MASK 0x0F
+#define USBC_ERR_EA 0x10
+
+/* Error Status Register Definitions */
+#define USBC_ERR_PID 0x01
+#define USBC_ERR_UEPKT 0x02
+#define USBC_ERR_DCRC 0x04
+#define USBC_ERR_TIMOUT 0x08
+#define USBC_ERR_EOP 0x10
+#define USBC_ERR_B_OVRN 0x20
+#define USBC_ERR_BTSTF 0x40
+#define USBC_ERR_TGL 0x80
+
+/* Endpoint Select Register Definitions */
+#define USBC_EP_SEL_F 0x01
+#define USBC_EP_SEL_ST 0x02
+#define USBC_EP_SEL_STP 0x04
+#define USBC_EP_SEL_PO 0x08
+#define USBC_EP_SEL_EPN 0x10
+#define USBC_EP_SEL_B_1_FULL 0x20
+#define USBC_EP_SEL_B_2_FULL 0x40
+
+/* Endpoint Status Register Definitions */
+#define USBC_EP_STAT_ST 0x01
+#define USBC_EP_STAT_DA 0x20
+#define USBC_EP_STAT_RF_MO 0x40
+#define USBC_EP_STAT_CND_ST 0x80
+
+/* Clear Buffer Register Definitions */
+#define USBC_CLR_BUF_PO 0x01
+
+typedef struct
+{
+/* Device interrupt registers */
+ REG32 DevIntSt; /* USB Device Interrupt Status (RO) 0000 */
+ REG32 DevIntEn; /* USB Device Interrupt Enable (R/W) 0004 */
+ REG32 DevIntClr; /* USB Device Interrupt Clear (WO) 0008 */
+ REG32 DevIntSet; /* USB Device Interrupt Set (WO) 000C */
+/* Command registers */
+ REG32 CmdCode; /* USB Command Code (WO) 0010 */
+ REG32 CmdData; /* USB Command Data (RO) 0014 */
+/* USB transfer registers */
+ REG32 RxData; /* USB Receive Data (RO) 0018 */
+ REG32 TxData; /* USB Transmit Data (WO) 001C */
+ REG32 RxPLen; /* USB Receive Packet Length (RO) 0020 */
+ REG32 TxPLen; /* USB Transmit Packet Length (WO) 0024 */
+ REG32 Ctrl; /* USB Control (R/W) 0028 */
+/* Device interrupt priority register */
+ REG_8 USBDevIntPri; /* USB Device Interrupt Priority (WO) 002C */
+ REG_8 _pad0[3];
+/* Endpoint interrupt registers */
+ REG32 EpIntSt; /* USB Endpoint Interrupt Status (RO) 0030 */
+ REG32 EpIntEn; /* USB Endpoint Interrupt Enable (R/W) 0034 */
+ REG32 EpIntClr; /* USB Endpoint Interrupt Clear (WO) 0038 */
+ REG32 EpIntSet; /* USB Endpoint Interrupt Set (WO) 003C */
+ REG32 EpIntPri; /* USB Endpoint Priority (WO) 0040 */
+/* Endpoint realization registers */
+ REG32 ReEp; /* USB Realize Endpoint (R/W) 0044 */
+ REG32 EpInd; /* USB Endpoint Index (WO) 0048 */
+ REG32 MaxPSize; /* USB MaxPacketSize (R/W) 004C */
+/* DMA registers (LPC2146/8 only) */
+ REG32 DMARSt; /* USB DMA Request Status (RO) 0050 */
+ REG32 DMARClr; /* USB DMA Request Clear (WO) 0054 */
+ REG32 DMARSet; /* USB DMA Request Set (WO) 0058 */
+ REG32 _pad1[9];
+ REG32 UDCAH; /* USB UDCA Head (R/W) 0080 */
+ REG32 EpDMASt; /* USB Endpoint DMA Status (RO) 0084 */
+ REG32 EpDMAEn; /* USB Endpoint DMA Enable (WO) 0088 */
+ REG32 EpDMADis; /* USB Endpoint DMA Disable (WO) 008C */
+ REG32 DMAIntSt; /* USB DMA Interrupt Status (RO) 0090 */
+ REG32 DMAIntEn; /* USB DMA Interrupt Enable (R/W) 0094 */
+ REG32 _pad2[2];
+ REG32 EoTIntSt; /* USB End of Transfer Interrupt Status (RO) 00A0 */
+ REG32 EoTIntClr; /* USB End of Transfer Interrupt Clear (WO) 00A4 */
+ REG32 EoTIntSet; /* USB End of Transfer Interrupt Set (WO) 00A8 */
+ REG32 NDDRIntSt; /* USB New DD Request Interrupt Status (RO) 00AC */
+ REG32 NDDRIntClr; /* USB New DD Request Interrupt Clear (WO) 00B0 */
+ REG32 NDDRIntSet; /* USB New DD Request Interrupt Set (WO) 00B4 */
+ REG32 SysErrIntSt; /* USB System Error Interrupt Status (RO) 00B8 */
+ REG32 SysErrIntClr; /* USB System Error Interrupt Clear (WO) 00BC */
+ REG32 SysErrIntSet; /* USB System Error Interrupt Set (WO) 00C0 */
+ REG32 _pad3[0xE];
+ REG32 MODULE_ID; /* Module ID (RO) 00FC */
+} usbRegs_t;
+
+#endif /*_lpcUSB_H*/
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * Header file for Philips LPC ARM Processors.
+ * Copyright 2004 R O SoftWare
+ *
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ *****************************************************************************/
+#ifndef INC_LPC_VIC_H
+#define INC_LPC_VIC_H
+
+// Vectored Interrupt Controller Registers (VIC)
+typedef struct
+{
+ REG32 irqStatus; // IRQ Status Register
+ REG32 fiqStatus; // FIQ Status Register
+ REG32 rawIntr; // Raw Interrupt Status Register
+ REG32 intSelect; // Interrupt Select Register
+ REG32 intEnable; // Interrupt Enable Register
+ REG32 intEnClear; // Interrupt Enable Clear Register
+ REG32 softInt; // Software Interrupt Register
+ REG32 softIntClear; // Software Interrupt Clear Register
+ REG32 protection; // Protection Enable Register
+ REG32 _pad0[3];
+ REG32 vectAddr; // Vector Address Register
+ REG32 defVectAddr; // Default Vector Address Register
+ REG32 _pad1[50];
+ REG32 vectAddr0; // Vector Address 0 Register
+ REG32 vectAddr1; // Vector Address 1 Register
+ REG32 vectAddr2; // Vector Address 2 Register
+ REG32 vectAddr3; // Vector Address 3 Register
+ REG32 vectAddr4; // Vector Address 4 Register
+ REG32 vectAddr5; // Vector Address 5 Register
+ REG32 vectAddr6; // Vector Address 6 Register
+ REG32 vectAddr7; // Vector Address 7 Register
+ REG32 vectAddr8; // Vector Address 8 Register
+ REG32 vectAddr9; // Vector Address 9 Register
+ REG32 vectAddr10; // Vector Address 10 Register
+ REG32 vectAddr11; // Vector Address 11 Register
+ REG32 vectAddr12; // Vector Address 12 Register
+ REG32 vectAddr13; // Vector Address 13 Register
+ REG32 vectAddr14; // Vector Address 14 Register
+ REG32 vectAddr15; // Vector Address 15 Register
+ REG32 _pad2[48];
+ REG32 vectCntl0; // Vector Control 0 Register
+ REG32 vectCntl1; // Vector Control 1 Register
+ REG32 vectCntl2; // Vector Control 2 Register
+ REG32 vectCntl3; // Vector Control 3 Register
+ REG32 vectCntl4; // Vector Control 4 Register
+ REG32 vectCntl5; // Vector Control 5 Register
+ REG32 vectCntl6; // Vector Control 6 Register
+ REG32 vectCntl7; // Vector Control 7 Register
+ REG32 vectCntl8; // Vector Control 8 Register
+ REG32 vectCntl9; // Vector Control 9 Register
+ REG32 vectCntl10; // Vector Control 10 Register
+ REG32 vectCntl11; // Vector Control 11 Register
+ REG32 vectCntl12; // Vector Control 12 Register
+ REG32 vectCntl13; // Vector Control 13 Register
+ REG32 vectCntl14; // Vector Control 14 Register
+ REG32 vectCntl15; // Vector Control 15 Register
+} vicRegs_t;
+
+// VIC Channel Assignments
+#define VIC_WDT 0
+#define VIC_TIMER0 4
+#define VIC_TIMER1 5
+#define VIC_UART0 6
+#define VIC_UART1 7
+#define VIC_PWM 8
+#define VIC_PWM0 8
+#define VIC_I2C 9
+#define VIC_SPI 10
+#define VIC_SPI0 10
+#define VIC_SPI1 11
+#define VIC_PLL 12
+#define VIC_RTC 13
+#define VIC_EINT0 14
+#define VIC_EINT1 15
+#define VIC_EINT2 16
+#define VIC_EINT3 17
+#define VIC_ADC 18
+
+// Vector Control Register bit definitions
+#define VIC_ENABLE (1 << 5)
+
+// Convert Channel Number to Bit Value
+#define VIC_BIT(chan) (1 << (chan))
+
+#endif
+
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * Header file for Philips LPC ARM Processors.
+ * Copyright 2004 R O SoftWare
+ *
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ *****************************************************************************/
+#ifndef INC_LPC_WD_H
+#define INC_LPC_WD_H
+
+// Watchdog Registers
+typedef struct
+{
+ REG_8 mod; // Watchdog Mode Register
+ REG_8 _pad0[3];
+ REG32 tc; // Watchdog Time Constant Register
+ REG_8 feed; // Watchdog Feed Register
+ REG32 tv; // Watchdog Time Value Register
+} wdRegs_t;
+
+#endif
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+SUBDIRS = hal iap
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+lib_obj_SOURCES = startup.S ivt.S
+
+lib_LIBRARIES = mach_hal
+
+include_HEADERS = hal_ints.h hal_machperiph.h
+
+mach_hal_SOURCES = hal.c hal_machperiph.c irq_fnc_compat.S
+
+
+
--- /dev/null
+#include <system_def.h>
+#include <cpu_def.h>
+#include <hal_ints.h>
+#include <hal_intr.h>
+#include <types.h>
+
+// -------------------------------------------------------------------------
+// Hardware init
+
+// Return value of VPBDIV register. According to errata doc
+// we need to read twice consecutively to get correct value
+uint32_t lpc_get_vpbdiv(void)
+{
+ uint32_t vpbdiv_reg;
+
+ vpbdiv_reg=VPBDIV;
+ vpbdiv_reg=VPBDIV;
+
+ return (vpbdiv_reg);
+}
+
+
+// -------------------------------------------------------------------------
+// This routine is called to respond to a hardware interrupt (IRQ). It
+// should interrogate the hardware and return the IRQ vector number.
+int hal_IRQ_handler(void)
+{
+ uint32_t irq_num, irq_stat;
+
+ irq_stat=VICIRQStatus;
+ for (irq_num = 0; irq_num < 32; irq_num++)
+ if (irq_stat & (1 << irq_num))
+ break;
+
+ // If not a valid interrrupt source, treat as spurious interrupt
+ if (irq_num < HAL_ISR_MIN || irq_num > HAL_ISR_MAX)
+ irq_num = HAL_INTERRUPT_NONE;
+
+ return (irq_num);
+}
+
+
+// -------------------------------------------------------------------------
+// Interrupt control
+//
+
+// Block the the interrupt associated with the vector
+void hal_interrupt_mask(int vector)
+{
+ VICIntEnClear = 1 << vector;
+}
+
+// Unblock the the interrupt associated with the vector
+void hal_interrupt_unmask(int vector)
+{
+ VICIntEnable = 1 << vector;
+}
+
+// Acknowledge the the interrupt associated with the vector. This
+// clears the interrupt but may result in another interrupt being
+// delivered
+void hal_interrupt_acknowledge(int vector)
+{
+
+ // External interrupts have to be cleared from the EXTINT register
+ if (vector >= HAL_INTERRUPT_EINT0 &&
+ vector <= HAL_INTERRUPT_EINT3)
+ {
+ // Map int vector to corresponding bit (0..3)
+ vector = 1 << (vector - HAL_INTERRUPT_EINT0);
+
+ // Clear the external interrupt
+ EXTINT=vector;
+ }
+
+ // Acknowledge interrupt in the VIC
+ VICVectAddr=0;
+}
+
+// This provides control over how an interrupt signal is detected.
+// Options are between level or edge sensitive (level) and high/low
+// level or rising/falling edge triggered (up).
+//
+// This should be simple, but unfortunately on some processor revisions,
+// it trips up on two errata issues (for the LPC2294 Rev.A these are
+// EXTINT.1 and VPBDIV.1) and so on these devices a somewhat convoluted
+// sequence in order to work properly. There is nothing in the errata
+// sequence that won't work on a processor without these issues.
+void hal_interrupt_configure(int vector, int level, int up)
+{
+ uint32_t regval;
+#ifdef HAL_ARM_LPC2XXX_EXTINT_ERRATA
+ uint32_t saved_vpbdiv;
+#endif
+
+ // Map int vector to corresponding bit (0..3)
+ vector = 1 << (vector - HAL_INTERRUPT_EINT0);
+
+#ifdef HAL_ARM_LPC2XXX_EXTINT_ERRATA
+ // From discussions with the Philips applications engineers on the
+ // Yahoo LPC2000 forum, it appears that in order up change both
+ // EXTMODE and EXTPOLAR, the operations have to be performed in
+ // two passes as follows:
+ // old=VPBDIV (x2),
+ // VPBDIV=0, EXTMODE=n, VPBDIV=n, VPBDIV=0, EXTPOLAR=y, VPBDIV=y
+ // VPCDIV=old
+
+ // Save current VPBDIV register settings
+ saved_vpbdiv = lpc_get_vpbdiv();
+
+ // Clear VPBDIV register
+ VPBDIV=0;
+
+ // Read current mode and update for level (0) or edge detection (1)
+ regval=EXTMODE;
+ if (level)
+ regval &= ~vector;
+ else
+ regval |= vector;
+ EXTMODE=regval;
+
+ // Set VPBDIV register to same value as mode
+ VPBDIV=regval;
+
+ // Clear VPBDIV register
+ VPBDIV=0;
+
+ // Read current polarity and update for trigger level or edge
+ // level: high (1), low (0) edge: rising (1), falling (0)
+ regval=EXTPOLAR;
+ if (up)
+ regval |= vector;
+ else
+ regval &= ~vector;
+ EXTPOLAR=regval;
+
+
+ // Set VPBDIV register to same value as mode
+ VPBDIV=regval;
+
+ // Restore saved VPBDIV register
+ VPBDIV=saved_vpbdiv;
+#else
+ // Read current mode and update for level (0) or edge detection (1)
+ regval=EXTMODE;
+ if (level)
+ regval &= ~vector;
+ else
+ regval |= vector;
+ EXTMODE=regval;
+
+ // Read current polarity and update for trigger level or edge
+ // level: high (1), low (0) edge: rising (1), falling (0)
+ regval=EXTPOLAR;
+ if (up)
+ regval |= vector;
+ else
+ regval &= ~vector;
+ EXTPOLAR=regval;
+#endif
+ // Clear any spurious interrupt that might have been generated
+ EXTINT=vector;
+}
+
+// Change interrupt level. This is a non-operation on the LPC2XXX
+void hal_interrupt_set_level(int vector, int level)
+{
+}
+
+uint32_t hal_default_isr(int vector, uint32_t data)
+{
+ return 0;
+}
+
+uint32_t hal_interrupt_handlers[HAL_ISR_COUNT]={[0 ... HAL_ISR_COUNT-1]=(uint32_t)hal_default_isr};
+uint32_t hal_interrupt_data[HAL_ISR_COUNT];
+
+#if !defined(__thumb__)
+void irq_handler_resolver(void) __attribute__ ((interrupt));
+#endif
+void irq_handler_resolver(void)
+{
+ int v;
+ uint32_t f,d;
+
+ v=hal_IRQ_handler();
+ if (v==HAL_INTERRUPT_NONE) return;
+ f=hal_interrupt_handlers[v];
+ d=hal_interrupt_data[v];
+ ((hal_isr)f)(v,d);
+ hal_interrupt_acknowledge(v);
+}
+
+int request_irq(unsigned int irqnum, irq_handler_t handler, unsigned long flags,
+ const char *name, void *context)
+{
+ HAL_INTERRUPT_ATTACH(irqnum, handler, context);
+ HAL_INTERRUPT_UNMASK(irqnum);
+ return irqnum;
+}
+
+void free_irq(unsigned int irqnum,void *ctx)
+{
+ HAL_INTERRUPT_MASK(irqnum);
+ HAL_INTERRUPT_DETACH(irqnum, NULL);
+}
--- /dev/null
+#ifndef HAL_INTS_H
+#define HAL_INTS_H
+
+#define HAL_INTERRUPT_NONE -1
+
+#define HAL_INTERRUPT_WD 0
+#define HAL_INTERRUPT_SOFT 1
+#define HAL_INTERRUPT_DCC_RX 2
+#define HAL_INTERRUPT_DCC_TX 3
+#define HAL_INTERRUPT_TIMER0 4
+#define HAL_INTERRUPT_TIMER1 5
+#define HAL_INTERRUPT_UART0 6
+#define HAL_INTERRUPT_UART1 7
+#define HAL_INTERRUPT_PWM0 8
+#define HAL_INTERRUPT_I2C0 9
+#define HAL_INTERRUPT_SPI0 10
+#define HAL_INTERRUPT_SPI1 11
+#define HAL_INTERRUPT_PLL 12
+#define HAL_INTERRUPT_RTCDEV 13
+#define HAL_INTERRUPT_EINT0 14
+#define HAL_INTERRUPT_EINT1 15
+#define HAL_INTERRUPT_EINT2 16
+#define HAL_INTERRUPT_EINT3 17
+#define HAL_INTERRUPT_AD 18
+#define HAL_INTERRUPT_I2C1 19
+#define HAL_INTERRUPT_AD1 21
+
+#define HAL_ISR_MIN 0
+#define HAL_ISR_MAX (31)
+
+#define HAL_ISR_COUNT (HAL_ISR_MAX+1)
+
+//The vector used by the Real time clock
+#define HAL_INTERRUPT_RTC HAL_INTERRUPT_TIMER0
+
+#endif /* HAL_INTS_H */
--- /dev/null
+#include <system_def.h>
+#include <cpu_def.h>
+#include <hal_machperiph.h>
+
+unsigned int system_frequency = FOSC; /*!< System Clock Frequency (Core Clock) */
+
+void system_clock_init(void)
+{
+ // set PLL multiplier & divisor.
+ // values computed from config.h
+ PLLCFG = PLLCFG_MSEL | PLLCFG_PSEL;
+
+ // enable PLL
+ PLLCON = PLLCON_PLLE;
+ PLLFEED = 0xAA; // Make it happen. These two updates
+ PLLFEED = 0x55; // MUST occur in sequence.
+
+ // wait for PLL lock
+ while (!(PLLSTAT & PLLSTAT_LOCK))
+ continue;
+
+ // enable & connect PLL
+ PLLCON = PLLCON_PLLE | PLLCON_PLLC;
+ PLLFEED = 0xAA; // Make it happen. These two updates
+ PLLFEED = 0x55; // MUST occur in sequence.
+
+ system_frequency=CCLK;
+
+ // setup & enable the MAM
+ MAMCR = 0;
+ MAMTIM = MAMTIM_CYCLES;
+ MAMCR = MAMCR_FULL;
+
+ // set the peripheral bus speed
+ // value computed from config.h
+ VPBDIV = VPBDIV_VALUE; // set the peripheral bus clock speed
+}
+
+void lpc_watchdog_feed()
+{
+ unsigned long flags;
+
+ save_and_cli(flags);
+ WDFEED = 0xAA;
+ WDFEED = 0x55;
+ restore_flags(flags);
+}
+
+void lpc_watchdog_init(int on,int timeout_ms)
+{
+ if (!on) return;
+ WDTC = PCLK/(1000/timeout_ms);
+ WDMOD = 0x03; /* Enable watchdog timer and reset */
+}
--- /dev/null
+#ifndef _HAL_MACHPERIPH_H
+#define _HAL_MACHPERIPH_H
+
+extern unsigned int system_frequency; /*!< System Clock Frequency (Core Clock) */
+
+void system_clock_init(void);
+
+void lpc_watchdog_init(int on,int timeout_ms);
+void lpc_watchdog_feed();
+
+#endif /* _HAL_MACHPERIPH_H */
+
--- /dev/null
+.macro code32_fnc_header fncname
+ .global \fncname
+#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
+ .code 16
+ .align 0
+ .thumb_func
+ .type \fncname, %function
+\fncname:
+ bx pc
+ nop
+ .code 32
+ .type _code_32_\fncname, %function
+_code_32_\fncname:
+#else
+ .code 32
+ .align 0
+ .type \fncname, %function
+\fncname:
+#endif
+
+.endm
+
+ .text
+
+ code32_fnc_header irq_fnc_sti
+ mrs r0, cpsr
+ bic r0, r0, #128
+ msr cpsr_c, r0
+ bx lr
+
+ code32_fnc_header irq_fnc_cli
+ mrs r0, cpsr
+ orr r0, r0, #128
+ msr cpsr_c, r0
+ bx lr
+
+ code32_fnc_header irq_fnc_save_and_cli
+ mrs r0, cpsr
+ orr r1, r0, #128
+ msr cpsr_c, r1
+ bx lr
+
+ code32_fnc_header irq_fnc_save_flags
+ mrs r0, cpsr
+ bx lr
+
+ code32_fnc_header irq_fnc_restore_flags
+ msr cpsr_c, r0
+ bx lr
--- /dev/null
+/* Setup vector table. Note that undf, pabt, dabt, fiq just execute
+a null loop. */
+
+#include <bbconf_info.h>
+
+.global __bbconf_magic_addr
+.global __bbconf_ptptr_addr
+.global __bbconf_pt_addr
+
+.section .ivt,"ax"
+ .code 32
+ .align 0
+
+ .global hal_vectors
+
+hal_vectors: LDR PC, Reset_Addr
+ LDR PC, Undef_Addr
+ LDR PC, SWI_Addr
+ LDR PC, PAbt_Addr
+ LDR PC, DAbt_Addr
+ NOP /* Reserved Vector */
+#if !defined(__thumb__)
+ LDR PC, IRQ_Addr
+#else
+ B IRQ_Trampoline
+#endif
+ LDR PC, FIQ_Addr
+
+Reset_Addr: .word reset_handler
+Undef_Addr: .word Undef_Handler
+SWI_Addr: .word SWI_Handler
+PAbt_Addr: .word PAbt_Handler
+DAbt_Addr: .word DAbt_Handler
+ .word 0 /* Reserved Address */
+IRQ_Addr: .word irq_handler_resolver
+FIQ_Addr: .word FIQ_Handler
+
+__bbconf_magic_addr:
+ .word BBCONF_MAGIC_VAL
+__bbconf_ptptr_addr:
+ .word __bbconf_pt_addr
+
+Undef_Handler: B Undef_Handler
+SWI_Handler: B SWI_Handler
+PAbt_Handler: B PAbt_Handler
+DAbt_Handler: B DAbt_Handler
+FIQ_Handler: B FIQ_Handler
+
+#if defined(__thumb__)
+IRQ_Trampoline:
+ sub lr, lr, #4
+ push {r0, r1, r2, r3, r4, ip, lr}
+ ldr r1, IRQ_Addr
+ adr lr, IRQ_Trampoline_ret
+ tst r1,#1
+ adrne lr, IRQ_Trampoline_ret_thumb+1
+ bx r1
+IRQ_Trampoline_ret_thumb:
+ .code 16
+ bx pc
+ nop
+ .code 32
+IRQ_Trampoline_ret:
+ ldm sp!, {r0, r1, r2, r3, r4, ip, pc}^
+#endif
+
+ .end
--- /dev/null
+#/***********************************************************************/
+#/* Startup file for LPC21xx MCU applications */
+#/* Partially inspired by KEIL ELEKTRONIK startup code */
+#/***********************************************************************/
+
+
+# *** Startup Code (executed after Reset) ***
+
+# Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
+ .set MODE_USR, 0x10 // User Mode
+ .set MODE_FIQ, 0x11 // FIQ Mode
+ .set MODE_IRQ, 0x12 // IRQ Mode
+ .set MODE_SVC, 0x13 // Supervisor Mode
+ .set MODE_ABT, 0x17 // Abort Mode
+ .set MODE_UND, 0x1B // Undefined Mode
+ .set MODE_SYS, 0x1F // System Mode
+
+ .equ I_BIT, 0x80 // when I bit is set, IRQ is disabled
+ .equ F_BIT, 0x40 // when F bit is set, FIQ is disabled
+
+ .set UND_STACK_SIZE, 0x00000004
+ .set ABT_STACK_SIZE, 0x00000004
+ .set FIQ_STACK_SIZE, 0x00000004
+ .set IRQ_STACK_SIZE, 0X00000400
+ .set SVC_STACK_SIZE, 0x00000004
+
+# Starupt Code must be linked first at Address at which it expects to run.
+
+ .text
+ .code 32
+
+ .global _stack // top of stack
+ .global _startup
+ .global reset_handler
+ .func _startup
+_startup:
+
+reset_handler:
+
+# Memory Mapping (when Interrupt Vectors are in RAM)
+ .equ MEMMAP, 0xE01FC040 /* Memory Mapping Control */
+
+ MOV R1, #1
+ LDR R0, =hal_vectors
+ CMP R0, #0
+ BEQ mam_sram
+ MOV R1, #2
+mam_sram:
+ LDR R0, =MEMMAP
+ STR R1, [R0]
+
+# Initialize Interrupt System
+# - Set stack location for each mode
+# - Leave in System Mode with Interrupts Disabled
+# -----------------------------------------------
+ ldr r0,=_stack
+ msr CPSR_c,#MODE_UND|I_BIT|F_BIT // Undefined Instruction Mode
+ mov sp,r0
+ sub r0,r0,#UND_STACK_SIZE
+ msr CPSR_c,#MODE_ABT|I_BIT|F_BIT // Abort Mode
+ mov sp,r0
+ sub r0,r0,#ABT_STACK_SIZE
+ msr CPSR_c,#MODE_FIQ|I_BIT|F_BIT // FIQ Mode
+ mov sp,r0
+ sub r0,r0,#FIQ_STACK_SIZE
+ msr CPSR_c,#MODE_IRQ|I_BIT|F_BIT // IRQ Mode
+ mov sp,r0
+ sub r0,r0,#IRQ_STACK_SIZE
+ msr CPSR_c,#MODE_SVC|I_BIT|F_BIT // Supervisor Mode
+ mov sp,r0
+ sub r0,r0,#SVC_STACK_SIZE
+ msr CPSR_c,#MODE_SYS|I_BIT|F_BIT // System Mode
+ mov sp,r0
+
+# Disable interrupt from VIC
+ .equ VICINTENABLE, 0xFFFFF010
+ .equ VICINTENCLR, 0xFFFFF014
+ .equ VICSOFTINT, 0xFFFFF018
+ .equ VICSOFTINTCLEAR, 0xFFFFF01C
+ LDR R0, =VICINTENABLE
+ MOV R1, #0
+ STR R1, [R0]
+ MOV R1, #0xFFFFFFFF
+ STR R1, [R0,#VICINTENCLR-VICINTENABLE]
+ STR R1, [R0,#VICSOFTINTCLEAR-VICINTENABLE]
+
+# Enable interrupts and return back into supervisor mode
+ msr CPSR_c,#MODE_SVC // Supervisor Mode
+
+# Relocate .data section (Copy from ROM to RAM)
+ LDR R1, =_etext
+ LDR R2, =_data
+ LDR R3, =_edata
+ CMP R1, R2
+ BEQ ZI
+LoopRel:CMP R2, R3
+ LDRLO R0, [R1], #4
+ STRLO R0, [R2], #4
+ BLO LoopRel
+
+ZI:
+# Clear .bss section (Zero init)
+ MOV R0, #0
+ LDR R1, =__bss_start__
+ LDR R2, =__bss_end__
+LoopZI: CMP R1, R2
+ STRLO R0, [R1], #4
+ BLO LoopZI
+
+
+# Enter the C _setup_board code
+ LDR R0, =_setup_board
+ CMP R0, #0
+ BEQ __main_start
+ ADR LR, __main_start
+#if defined(__thumb__)
+ TST R0,#1
+ ADRNE LR, __main_start_from_thumb
+ BX R0
+ .code 16
+__main_start_from_thumb:
+ BX PC
+ NOP
+ .code 32
+#else
+ BX R0
+#endif
+__main_start:
+
+ LDR R0, =main
+ ADR LR, __main_exit
+#if defined(__thumb__)
+ TST R0,#1
+ ADRNE LR, __main_exit_from_thumb
+ BX R0
+ .code 16
+__main_exit_from_thumb:
+ BX PC
+ NOP
+ .code 32
+#else
+ BX R0
+#endif
+__main_exit:
+ LDR R0, =_mem_app_start
+ CMP R0, #0
+ BEQ __main_loop
+ BX R0
+
+__main_loop: B __main_loop
+
+ .size _start, . - _start
+ .endfunc
+
+ .end
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+include_HEADERS = lpciap.h
+lib_LIBRARIES = lpciap
+lpciap_SOURCES = iap.c iap_asm.S
--- /dev/null
+#include <system_def.h>
+#include <cpu_def.h>
+#include <hal_machperiph.h>
+
+#define CMD_SUCCESS 0
+#define BUSY 11
+
+#define IAP_CMD_PREPARE 50
+#define IAP_CMD_WRITE 51
+#define IAP_CMD_ERASE 52
+#define IAP_CMD_READ_PARTID 54
+
+unsigned int command[5];
+unsigned int result[2];
+
+extern void iap_asm_entry (unsigned int *,unsigned int *);
+#define iap_entry iap_asm_entry
+
+#ifdef INC_LPC210x_H
+inline int addr2sec(unsigned long addr)
+{
+ return addr/0x2000;
+}
+#elif defined INC_LPC214x_H || defined INC_LPC2348_H
+inline int addr2sec(unsigned long addr)
+{
+ if (addr<0x8000) return (addr>>12);
+ else if (addr<0x78000) return (addr>>15)+7;
+ else return 22+((addr&0x7fff)>>12);
+}
+#else
+#error "Undefined type of CPU for function addr2sec!"
+#endif
+
+int lpcisp_read_partid()
+{
+ command[0] = IAP_CMD_READ_PARTID;
+ iap_entry(command, result);
+ return result[1];
+}
+
+int lpcisp_prepare_sectors(unsigned char start, unsigned char end)
+{
+ command[0] = IAP_CMD_PREPARE;
+ command[1] = start;
+ command[2] = end;
+ command[3] = system_frequency/1000;
+
+ iap_entry(command, result);
+
+ return (CMD_SUCCESS == *result);
+}
+
+int lpcisp_erase_sectors(unsigned char start, unsigned char end)
+{
+ command[0] = IAP_CMD_ERASE;
+ command[1] = start;
+ command[2] = end;
+ command[3] = system_frequency/1000;
+
+ iap_entry(command, result);
+
+ return (CMD_SUCCESS == *result);
+}
+
+int lpcisp_erase(void *addr, int len)
+{
+ int start,end;
+ unsigned long flags;
+
+ start=addr2sec((unsigned long)addr);
+ end=addr2sec((unsigned long)addr+len-1);
+
+ if (end<start) return 0;
+
+ save_and_cli(flags);
+
+ lpcisp_prepare_sectors(start,end);
+ if (CMD_SUCCESS != *result) return 0;
+
+ lpcisp_erase_sectors(start,end);
+
+ restore_flags(flags);
+
+ return (CMD_SUCCESS == *result);
+}
+
+int lpcisp_write(void *addr_des, const void *addr_src, int len)
+{
+ int start,end;
+ unsigned long flags;
+
+ start=addr2sec((unsigned long)addr_des);
+ end=start;
+
+ save_and_cli(flags);
+
+ lpcisp_prepare_sectors(start,end);
+ if (CMD_SUCCESS != *result) return 0;
+
+ command[0] = IAP_CMD_WRITE;
+ command[1] = (unsigned int)addr_des;
+ command[2] = (unsigned int)addr_src;
+ command[3] = len;
+ command[4] = system_frequency/1000;
+
+ iap_entry(command, result);
+
+ restore_flags(flags);
+
+ return (CMD_SUCCESS == *result);
+}
+
+
--- /dev/null
+.global iap_asm_entry
+.func iap_asm_entry
+
+#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
+ .code 16
+ .align 0
+ .thumb_func
+ .type iap_asm_entry, %function
+iap_asm_entry:
+ bx pc
+ nop
+ .code 32
+#else
+ .code 32
+ .type iap_asm_entry, %function
+iap_asm_entry:
+#endif
+ stmfd sp!,{r1, r2, lr}
+ adr lr,iap_asm_exit
+ ldr r2,=0x7FFFFFF1
+ bx r2
+
+iap_asm_exit:
+ ldmfd sp!,{r1, r2, lr}
+ bx lr
+.endfunc
+.end
--- /dev/null
+#ifndef _LPCIAP_H
+#define _LPCIAP_H
+
+int lpcisp_read_partid();
+int lpcisp_erase(void *addr, int len);
+int lpcisp_write(void *addr_des, const void *addr_src, int len);
+
+#endif /* _LPCIAP_H */
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+SUBDIRS = defines
\ No newline at end of file
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+include_HEADERS += byteswap.h endian.h lt_timer.h lt_timer_types.h keyval_id_his.h ads1x46.h irq_generic.h
+#include_HEADERS = $(notdir $(wildcard $(SOURCES_DIR)/*.h))
--- /dev/null
+#ifndef _ADS1X46_H
+#define _ADS1X46_H
+
+#define ADS_REG_BCS 0x00
+#define RBCS1 (1<<7)
+#define RBCS0 (1<<6)
+
+#define ADS_REG_VBIAS 0x01
+#define RVBIAS1 (1<<1)
+#define RVBIAS0 (1<<0)
+
+#define ADS_REG_MUX1 0x02
+#define RCLKSTAT (1<<7)
+#define RMUXCAL2 (1<<2)
+#define RMUXCAL1 (1<<1)
+#define RMUXCAL0 (1<<0)
+
+#define ADS_REG_SYS0 0x03
+#define RPGA2 (1<<6)
+#define RPGA1 (1<<5)
+#define RPGA0 (1<<4)
+#define RDR3 (1<<3)
+#define RDR2 (1<<2)
+#define RDR1 (1<<1)
+#define RDR0 (1<<0)
+
+#define ADS_REG_OFC0 0x04
+#define ADS_REG_OFC1 0x05
+#define ADS_REG_OFC2 0x06
+#define ADS_REG_FSC0 0x07
+#define ADS_REG_FSC1 0x08
+#define ADS_REG_FSC2 0x09
+#define ADS_REG_ID 0x0A
+#define RDRDY_MODE (1<<3)
+
+#define ADS_CMD_WAKEUP 0x00
+#define ADS_CMD_SLEEP 0x02
+#define ADS_CMD_SYNC 0x04
+#define ADS_CMD_RESET 0x06
+#define ADS_CMD_PO_INIT 0x0E
+#define ADS_CMD_NOP 0xFF
+
+#define ADS_CMD_RDATA 0x12
+#define ADS_CMD_RDATAC 0x14
+#define ADS_CMD_SDATAC 0x16
+
+#define ADS_CMD_RREG 0x20
+#define ADS_CMD_WREG 0x40
+
+#define ADS_CMD_SYSOCAL 0x60
+#define ADS_CMD_SYSGCAL 0x61
+#define ADS_CMD_SELFCAL 0x62
+
+
+#endif /* _ADS1X46_H */
+
--- /dev/null
+#ifndef _BYTESWAP_H
+#define _BYTESWAP_H 1
+
+#if defined(__KEIL__)
+#define __bswap_16(x) ( (((x) << 8) & 0xFF00) | (((x) >> 8) & 0x00FF) )
+#else
+#define __bswap_16(x) ({unsigned short __x=(x); \
+ (((__x>>8)&0xff)|((__x&0xff)<<8)); })
+#endif
+
+#if defined(__KEIL__)
+ //todo
+#else
+#define __bswap_32(x) ({unsigned long __y=(x); \
+ (__bswap_16(__y>>16)|__bswap_16(__y)<<16); })
+#endif
+
+#define bswap_16(x) __bswap_16 (x)
+
+#define bswap_32(x) __bswap_32 (x)
+
+#endif /* byteswap.h */
--- /dev/null
+#ifndef _ENDIAN_H
+#define _ENDIAN_H 1
+
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+#define __PDP_ENDIAN 3412
+
+#if defined(__i386__) || defined(SDCC) || defined (__ARMEL__)
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
+
+#if defined(__H8300__) || defined(__H8500__) || defined (__H8300H__) || defined(__W65__) || defined (__H8300S__) || defined (__m68k__) || defined (__ARMEB__) || defined(__KEIL__)
+#define __BYTE_ORDER __BIG_ENDIAN
+#endif
+
+#endif /* endian.h */
--- /dev/null
+#ifndef _IRQ_GENERIC_H
+#define _IRQ_GENERIC_H
+
+#ifndef _WITHIN_CPU_DEF_H
+#error irq_generic.h cannot be included directly, use cpu_def.h
+#endif /*_WITHIN_CPU_DEF_H*/
+
+#ifdef WITH_IRQ_RETVAL
+
+typedef int irqreturn_t;
+#define IRQ_NONE 0
+#define IRQ_HANDLED 1
+#define IRQ_RETVAL(x) ((x)!=IRQ_NONE?IRQ_HANDLED:IRQ_NONE)
+
+#else /*WITH_IRQ_RETVAL*/
+
+typedef void irqreturn_t;
+#define IRQ_NONE ((void)0)
+#define IRQ_HANDLED ((void)1)
+#define IRQ_RETVAL(x) (IRQ_HANDLED)
+
+#endif /*WITH_IRQ_RETVAL*/
+
+
+#ifndef IRQ_HANDLER_FNC
+#ifdef WITH_IRQ_HANDLER_ARGS
+
+typedef irqreturn_t (irq_handler_t)(int, void *);
+#define IRQ_HANDLER_FNC(M_fnc_name) \
+ irqreturn_t M_fnc_name(int __irq_handler_irqidx, void *__irq_handler_context)
+
+#define irq_handler_get_irqidx() (__irq_handler_irqidx)
+#define irq_handler_get_context() (__irq_handler_context)
+
+#else /*WITH_IRQ_HANDLER_ARGS*/
+
+typedef irqreturn_t (irq_handler_t)(void);
+#define IRQ_HANDLER_FNC(M_fnc_name) \
+ irqreturn_t M_fnc_name(void)
+
+/* irq_handler_get_* have to be CPU specific */
+
+/* Typical interrupt processing when context and irqidx
+ are not resolved by assembler/C IRQ routine for
+ common to all vectors/irqidx */
+
+#define irq_handler_get_irqidx() \
+ irq_arch_get_irqidx()
+#define irq_handler_get_context() \
+ (irq_context_table[irq_handler_get_irqidx()])
+
+#endif /*WITH_IRQ_HANDLER_ARGS*/
+#endif /*IRQ_HANDLER_FNC*/
+
+#ifndef irq_irqidx2irqnum
+
+#ifndef IRQ_IRQIDX_OFFSET
+#define IRQ_IRQIDX_OFFSET 0
+#endif /*IRQ_IRQIDX_OFFSET*/
+
+#define irq_irqnum2irqidx(x) ((x) + IRQ_IRQIDX_OFFSET)
+#define irq_irqidx2irqnum(x) ((x) - IRQ_IRQIDX_OFFSET)
+
+#endif /*irq_irqidx2irqnum*/
+
+#ifndef irq_handler_get_irqnum
+#define irq_handler_get_irqnum() irq_irqidx2irqnum(irq_handler_get_irqidx())
+#endif /*irq_handler_get_irqnum*/
+
+/* for compatabilty with Linux kernel naming */
+#define irq_handler_get_dev() irq_handler_get_context()
+
+
+/*
+Next variables are typically defined by CPU support
+
+extern void **irq_context_table;
+extern irq_handler_t **irq_handler_table;
+extern int irq_table_size;
+*/
+
+#define IRQF_TRIGGER_NONE 0x00000000
+#define IRQF_TRIGGER_RISING 0x00000001
+#define IRQF_TRIGGER_FALLING 0x00000002
+#define IRQF_TRIGGER_HIGH 0x00000004
+#define IRQF_TRIGGER_LOW 0x00000008
+#define IRQF_TRIGGER_MASK (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW | \
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)
+
+extern int
+request_irq(unsigned int irqnum, irq_handler_t *handler, unsigned long flags,
+ const char *name, void *context);
+
+extern void free_irq(unsigned int irqnum, void *context);
+
+extern void disable_irq(unsigned int irqnum);
+extern void enable_irq(unsigned int irqnum);
+extern int set_irq_type(unsigned int irqnum, unsigned int type);
+extern int set_irq_priority(int irqnum, int level);
+
+#endif /*_IRQ_GENERIC_H*/
--- /dev/null
+#ifndef _KEYVAL_ID_HIS_H_
+#define _KEYVAL_ID_HISC_H_
+
+#include "keyvalpb.h"
+
+#define KVPB_KEYID_BLINDER_POSSITION 0x20
+#define KVPB_KEYID_BLINDER_OPENTIME 0x21
+#define KVPB_KEYID_BLP_UP 0x22
+#define KVPB_KEYID_BLP_DOWN 0x23
+#define KVPB_KEYID_HOMEBELL_ADDR 0x30
+
+#endif /* _KEYVAL_ID_HIS_H_ */
+
--- /dev/null
+#ifndef _LT_TIMER_H
+#define _LT_TIMER_H
+
+#include <types.h>
+#include <lt_timer_types.h>
+
+#include <cpu_def.h>
+#include <system_def.h>
+
+//timers
+
+#ifndef LT_TIMER_VAR_LOC
+#define LT_TIMER_VAR_LOC
+#endif
+
+static lt_ticks_t LT_TIMER_VAR_LOC last_ticks;
+static lt_mstime_t LT_TIMER_VAR_LOC actual_msec;
+
+/* Declaration of ulan light timers */
+
+#define lt_get_msbase() (1000/SYS_TIMER_HZ) /* in ms */
+#define lt_get_ticks() (get_sys_timer_ticks())
+
+static inline void
+lt_mstime_update()
+{
+ lt_ticks_t LT_TIMER_VAR_LOC act_ticks;
+ lt_mstime_t LT_TIMER_VAR_LOC msec_diff;
+
+ act_ticks=lt_get_ticks();
+ msec_diff=((lt_tidiff_t)(act_ticks-last_ticks))*lt_get_msbase();
+ last_ticks=act_ticks;
+
+ actual_msec+=msec_diff;
+}
+
+
+#define LT_TIMER_DEC(cust_prefix) \
+\
+extern lt_mstime_t LT_TIMER_VAR_LOC cust_prefix##_last_expired; \
+static inline void \
+cust_prefix##_init() \
+{\
+ lt_mstime_update();\
+ cust_prefix##_last_expired=actual_msec;\
+}\
+static inline int \
+cust_prefix##_expired(lt_mstime_t expiration) \
+{\
+ lt_mstime_update();\
+ \
+ if ((lt_msdiff_t)(actual_msec-cust_prefix##_last_expired)>=expiration) {\
+ cust_prefix##_last_expired=actual_msec;\
+ return 1;\
+ }\
+ \
+ return 0;\
+}
+
+#define LT_TIMER_IMP(cust_prefix) \
+\
+lt_mstime_t LT_TIMER_VAR_LOC cust_prefix##_last_expired; \
+
+
+#endif /* _LT_TIMER_H */
--- /dev/null
+#ifndef _LT_TIMER_TYPES_H
+#define _LT_TIMER_TYPES_H
+
+//timers
+
+#ifdef SDCC
+typedef unsigned char lt_ticks_t;
+typedef char lt_tidiff_t;
+typedef unsigned int lt_mstime_t;
+typedef int lt_msdiff_t;
+#define LT_TIMER_VAR_LOC DATA
+#else
+typedef unsigned int lt_ticks_t;
+typedef int lt_tidiff_t;
+typedef unsigned long lt_mstime_t;
+typedef signed long lt_msdiff_t;
+#endif
+
+#endif /* _LT_TIMER_TYPES_H */
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+SUBDIRS = $(ARCH)
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+ifneq ($(wildcard $(SOURCES_DIR)/$(BOARD)),)
+SUBDIRS = $(BOARD)
+endif
\ No newline at end of file
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+SUBDIRS = defines libs
--- /dev/null
+# -*- makefile -*-
+
+ARCH=arm
+MACH=lpc17xx
+BOARD=lpc17xx-common
+LD_SCRIPT=lpc1768
+
+CONFIG_BOARD_VARIANT=lmc1
+
+link_VARIANTS ?= app
+
+CONFIG_OC_UL_DRV_SYSLESS=y
+CONFIG_OC_UL_DRV_U450_VARPINS=y
+CONFIG_OC_UL_DRV_U450_VARPINS_MSRSWAP=n
+CONFIG_OC_UL_DRV_U450_VARPINS_DIRNEG=n
+CONFIG_OC_UL_DRV_U450_LOOPBACK=y
+CONFIG_KEYVAL=y
+CONFIG_ULAN_DY=y
+
+#CONFIG_STDIO_COM_PORT=y
+
+CROSS_COMPILE = arm-elf-
+TARGET_ARCH = -mthumb -mcpu=cortex-m3
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+DEBUG ?= -ggdb
+#OPTIMIZE ?= -O2
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+#DEBUG ?= -g
+OPTIMIZE ?= -Os -ffunction-sections -fdata-sections -Wl,--gc-section
+LDFLAGS += -Wl,--cref
+LDFLAGS += -Wl,--gc-section
+
+LPC21ISP=lpc21isp-179
+LPC_BAUD = 38400
+LPC_TTY = /dev/ttyUSB0
+CPU_SYS_KHZ=12000
+
+LOAD_CMD-boot = load() { $(LPC21ISP) -bin $$1 $(LPC_TTY) $(LPC_BAUD) $(CPU_SYS_KHZ); }; load
+
+PROG_BASE=0x09000
+PROG_SIZE=0x37000
+
+
+OUTPUT_FORMATS = bin
+
+LOAD_EXTENSION-app = .bin
+
+ifeq ($(USB),)
+
+UL_SENDHEX ?= ul_sendhex
+MOD ?= 3
+
+LOAD_CMD-app = \
+ $(UL_SENDHEX) -m $(MOD) -r -o 0 ; \
+ $(UL_SENDHEX) -m $(MOD) -o 0 -t 0x101 -s $(PROG_BASE) -l $(PROG_SIZE) -e; \
+ $(UL_SENDHEX) -m $(MOD) -o 0 -t 0x101 -b 256 -s $(PROG_BASE) -f binary
+
+RUN_CMD-app = \
+ $(UL_SENDHEX) -m $(MOD) -r
+
+else
+
+USB_SENDHEX ?= usb_sendhex
+USB_APP_VID ?= 0x1669
+USB_APP_PID ?= 0x1001
+USB_BOOT_VID ?= 0xdead
+USB_BOOT_PID ?= 0x2263
+
+LOAD_CMD-app = \
+ $(USB_SENDHEX) -d $(USB_APP_VID):$(USB_APP_PID) -r ; \
+ $(USB_SENDHEX) -w -d $(USB_BOOT_VID):$(USB_BOOT_PID) -s $(PROG_BASE) -l $(PROG_SIZE) -e; sleep 2 ; \
+ $(USB_SENDHEX) -d $(USB_BOOT_VID):$(USB_BOOT_PID) -s $(PROG_BASE) -f binary
+
+RUN_CMD-app = \
+ $(USB_SENDHEX) -d $(USB_BOOT_VID):$(USB_BOOT_PID) -r
+
+endif
+
+
--- /dev/null
+# -*- makefile -*-
+
+ARCH=arm
+MACH=lpc17xx
+BOARD=lpc17xx-common
+
+CONFIG_BOARD_VARIANT=mpx-uu-pc
+
+ULAN_ID = mpx-bu
+
+CONFIG_APP_U2U_V2=y
+CONFIG_APP_U2U_V2_WITH_KEYVAL=y
+
+CONFIG_OC_UL_DRV_SYSLESS=y
+CONFIG_OC_UL_DRV_U450_VARPINS=y
+CONFIG_OC_UL_DRV_U450_VARPINS_MSRSWAP=n
+CONFIG_OC_UL_DRV_U450_VARPINS_DIRNEG=n
+CONFIG_OC_UL_DRV_U450_LOOPBACK=y
+CONFIG_KEYVAL=y
+CONFIG_USB_BASE=y
+CONFIG_USB_LPCUSB=y
+CONFIG_USB_MORE=y
+
+#CONFIG_STDIO_COM_PORT=y
+
+CROSS_COMPILE = arm-elf-
+TARGET_ARCH = -mthumb -mcpu=cortex-m3
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+DEBUG ?= -g
+OPTIMIZE ?= -O2
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+#DEBUG ?= -g
+#OPTIMIZE ?= -Os -ffunction-sections -fdata-sections -Wl,--gc-section
+#LDFLAGS += -Wl,--cref
+#LDFLAGS += -Wl,--gc-section
+
+# This selects linker script
+LD_SCRIPT=lpc1758
+
+LPC21ISP=~/projects/cf/lpc21isp_v179/lpc21isp
+LPC_BAUD = 38400
+LPC_TTY = /dev/ttyUSB0
+CPU_SYS_KHZ=12000
+
+LOAD_CMD-boot = load() { $(LPC21ISP) -bin $$1 $(LPC_TTY) $(LPC_BAUD) $(CPU_SYS_KHZ); }; load
+
+PROG_BASE=0x09000
+PROG_SIZE=0x77000
+
+
+OUTPUT_FORMATS = bin
+
+LOAD_EXTENSION-app = .bin
+
+ifeq ($(USB),)
+
+UL_SENDHEX ?= ul_sendhex
+MOD ?= 3
+
+LOAD_CMD-app = \
+ $(UL_SENDHEX) -m $(MOD) -r -o 0 ; \
+ $(UL_SENDHEX) -m $(MOD) -o 0 -t 0x101 -s $(PROG_BASE) -l $(PROG_SIZE) -e; \
+ $(UL_SENDHEX) -m $(MOD) -o 0 -t 0x101 -b 256 -s $(PROG_BASE) -f binary
+
+RUN_CMD-app = \
+ $(UL_SENDHEX) -m $(MOD) -r
+
+else
+
+USB_SENDHEX ?= usb_sendhex
+USB_APP_VID ?= 0xdead
+USB_APP_PID ?= 0x2263
+USB_BOOT_VID ?= 0xdead
+USB_BOOT_PID ?= 0x2263
+
+LOAD_CMD-app = \
+ $(USB_SENDHEX) -d $(USB_APP_VID):$(USB_APP_PID) -r ; \
+ $(USB_SENDHEX) -w -d $(USB_BOOT_VID):$(USB_BOOT_PID) -s $(PROG_BASE) -l $(PROG_SIZE) -e; sleep 2 ; \
+ $(USB_SENDHEX) -d $(USB_BOOT_VID):$(USB_BOOT_PID) -s $(PROG_BASE) -f binary
+
+RUN_CMD-app = \
+ $(USB_SENDHEX) -d $(USB_BOOT_VID):$(USB_BOOT_PID) -r
+
+endif
--- /dev/null
+# -*- makefile -*-
+
+ARCH=arm
+MACH=lpc17xx
+BOARD=lpc17xx-common
+
+CONFIG_BOARD_VARIANT=ulmi
+
+CONFIG_ULBOOT=y
+
+CONFIG_OC_UL_DRV_SYSLESS=y
+CONFIG_OC_UL_DRV_U450_VARPINS=y
+CONFIG_OC_UL_DRV_U450_VARPINS_MSRSWAP=y
+CONFIG_OC_UL_DRV_U450_VARPINS_DIRNEG=y
+CONFIG_OC_UL_DRV_U450_LOOPBACK=y
+CONFIG_KEYVAL=y
+CONFIG_ULAN_DY=y
+
+#CONFIG_STDIO_COM_PORT=y
+
+CROSS_COMPILE = arm-elf-
+TARGET_ARCH = -mthumb -mcpu=cortex-m3
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+DEBUG ?= -g
+OPTIMIZE ?= -O2
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+#DEBUG ?= -g
+#OPTIMIZE ?= -Os -ffunction-sections -fdata-sections -Wl,--gc-section
+#LDFLAGS += -Wl,--cref
+#LDFLAGS += -Wl,--gc-section
+
+TOHIT=~/projects/cf/lpc21isp_v179/lpc21isp
+LPC_BAUD = 38400
+LPC_TTY = /dev/ttyUSB0
+CPU_SYS_KHZ=14745
+
+LOAD_CMD-boot = load() { $(TOHIT) -bin $$1 $(LPC_TTY) $(LPC_BAUD) $(CPU_SYS_KHZ); }; load
+
+# This selects linker script
+LD_SCRIPT=lpc1754
+
+OUTPUT_FORMATS = bin
+
--- /dev/null
+# -*- makefile -*-
+
+ARCH=arm
+MACH=lpc17xx
+BOARD=lpc17xx-common
+
+CONFIG_BOARD_VARIANT=mpx-uu-pc
+
+CONFIG_ULBOOT=y
+
+CONFIG_OC_UL_DRV_SYSLESS=y
+CONFIG_OC_UL_DRV_U450_VARPINS=y
+CONFIG_OC_UL_DRV_U450_VARPINS_MSRSWAP=n
+CONFIG_OC_UL_DRV_U450_VARPINS_DIRNEG=n
+CONFIG_OC_UL_DRV_U450_LOOPBACK=y
+CONFIG_KEYVAL=y
+CONFIG_ULAN_DY=y
+
+#CONFIG_STDIO_COM_PORT=y
+
+CROSS_COMPILE = arm-elf-
+TARGET_ARCH = -mthumb -mcpu=cortex-m3
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+DEBUG ?= -g
+OPTIMIZE ?= -O2
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+#DEBUG ?= -g
+#OPTIMIZE ?= -Os -ffunction-sections -fdata-sections -Wl,--gc-section
+#LDFLAGS += -Wl,--cref
+#LDFLAGS += -Wl,--gc-section
+
+TOHIT=~/projects/cf/lpc21isp_v179/lpc21isp
+LPC_BAUD = 38400
+LPC_TTY = /dev/ttyUSB0
+CPU_SYS_KHZ=14745
+
+LOAD_CMD-boot = load() { $(TOHIT) -bin $$1 $(LPC_TTY) $(LPC_BAUD) $(CPU_SYS_KHZ); }; load
+
+# This selects linker script
+LD_SCRIPT=lpc1758
+
+OUTPUT_FORMATS = bin
+
--- /dev/null
+# -*- makefile -*-
+
+LN_HEADERS=y
+
+ARCH=arm
+MACH=lpc17xx
+BOARD=lpc17xx-common
+LD_SCRIPT=lpc1768
+
+CONFIG_BOARD_VARIANT=lmc1
+
+link_VARIANTS ?= app
+
+CONFIG_KEYVAL=y
+CONFIG_USB_BASE=y
+CONFIG_USB_MORE=y
+CONFIG_USB_LPCUSB=y
+
+CONFIG_APP_USBCAN=y
+#CONFIG_APP_USBLED=y
+CONFIG_OC_LINCAN_CARD_can_lmc1=y
+
+
+CONFIG_OC_UL_DRV_SYSLESS=n
+CONFIG_ULAN_DY=n
+CONFIG_ULOI_LT=n
+#CONFIG_APP_USBBOOT=y
+#CONFIG_ULBOOT=y
+
+CONFIG_STDIO_COM_PORT=0
+
+CROSS_COMPILE = arm-elf-
+TARGET_ARCH = -mthumb -mcpu=cortex-m3
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+DEBUG ?= -ggdb
+#OPTIMIZE ?= -O2
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+#DEBUG ?= -g
+OPTIMIZE ?= -Os -ffunction-sections -fdata-sections -Wl,--gc-section
+LDFLAGS += -Wl,--cref
+LDFLAGS += -Wl,--gc-section
+
+LPC21ISP=lpc21isp-179
+LPC_BAUD = 38400
+LPC_TTY = /dev/ttyUSB0
+CPU_SYS_KHZ=12000
+
+LOAD_CMD-boot = load() { $(LPC21ISP) -bin $$1 $(LPC_TTY) $(LPC_BAUD) $(CPU_SYS_KHZ); }; load
+
+PROG_BASE=0x09000
+PROG_SIZE=0x37000
+
+OUTPUT_FORMATS = bin
+
+LOAD_EXTENSION-app = .bin
+
+USB_SENDHEX ?= usb_sendhex
+USB_APP_VID ?= 0x1669
+USB_APP_PID ?= 0x1001
+USB_BOOT_VID ?= 0xdead
+USB_BOOT_PID ?= 0x2263
+
+LOAD_CMD-app = \
+ $(USB_SENDHEX) -d $(USB_APP_VID):$(USB_APP_PID) -r ; \
+ $(USB_SENDHEX) -w -d $(USB_BOOT_VID):$(USB_BOOT_PID) -s $(PROG_BASE) -l $(PROG_SIZE) -e; sleep 2 ; \
+ $(USB_SENDHEX) -d $(USB_BOOT_VID):$(USB_BOOT_PID) -s $(PROG_BASE) -f binary
+
+RUN_CMD-app = \
+ $(USB_SENDHEX) -d $(USB_BOOT_VID):$(USB_BOOT_PID) -r
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+default_CONFIG = CONFIG_BOARD_VARIANT=x
+
+#include_HEADERS = $(notdir $(wildcard $(SOURCES_DIR)/*.h))
+
+ifneq ($(CONFIG_BOARD_VARIANT),)
+
+renamed_include_HEADERS = system_def-$(CONFIG_BOARD_VARIANT).h->system_def.h
+
+else
+
+include_HEADERS = system_def.h
+
+endif # CONFIG_BOARD_VARIANT
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ system_def.h - common cover for definition of hardware adresses,
+ registers, timing and other hardware dependant
+ parts of embedded hardware
+
+ Copyright (C) 2001 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002 by PiKRON Ltd. http://www.pikron.com
+
+ *******************************************************************/
+
+#ifndef _SYSTEM_DEF_H_
+#define _SYSTEM_DEF_H_
+
+#include <types.h>
+#include <system_stub.h>
+#include <LPC17xx.h>
+#include <bspbase.h>
+#include <hal_gpio_def.h>
+
+#ifndef MACH_LPC17XX
+#define MACH_LPC17XX
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define VER_CODE(major,minor,patch) (major*0x10000+minor*0x100+patch)
+/* Software version */
+#define SW_VER_ID "LMC1"
+#define SW_VER_MAJOR 0
+#define SW_VER_MINOR 1
+#define SW_VER_PATCH 0
+#define SW_VER_CODE VER_CODE(SW_VER_MAJOR,SW_VER_MINOR,SW_VER_PATCH)
+/* Hardware version */
+#define HW_VER_ID "LMC1"
+#define HW_VER_MAJOR 1
+#define HW_VER_MINOR 0
+#define HW_VER_PATCH 0
+#define HW_VER_CODE VER_CODE(HW_VER_MAJOR,HW_VER_MINOR,HW_VER_PATCH)
+/* Version of mechanical */
+#define MECH_VER_ID "LMC1"
+#define MECH_VER_MAJOR 0
+#define MECH_VER_MINOR 0
+#define MECH_VER_PATCH 0
+#define MECH_VER_CODE VER_CODE(MECH_VER_MAJOR,MECH_VER_MINOR,MECH_VER_PATCH)
+
+
+/*--------------------- Clock Configuration ----------------------------------
+//
+// <e> Clock Configuration
+// <h> System Controls and Status Register (SCS)
+// <o1.4> OSCRANGE: Main Oscillator Range Select
+// <0=> 1 MHz to 20 MHz
+// <1=> 15 MHz to 24 MHz
+// <e1.5> OSCEN: Main Oscillator Enable
+// </e>
+// </h>
+//
+// <h> Clock Source Select Register (CLKSRCSEL)
+// <o2.0..1> CLKSRC: PLL Clock Source Selection
+// <0=> Internal RC oscillator
+// <1=> Main oscillator
+// <2=> RTC oscillator
+// </h>
+//
+// <e3> PLL0 Configuration (Main PLL)
+// <h> PLL0 Configuration Register (PLL0CFG)
+// <i> F_cco0 = (2 * M * F_in) / N
+// <i> F_in must be in the range of 32 kHz to 50 MHz
+// <i> F_cco0 must be in the range of 275 MHz to 550 MHz
+// <o4.0..14> MSEL: PLL Multiplier Selection
+// <6-32768><#-1>
+// <i> M Value
+// <o4.16..23> NSEL: PLL Divider Selection
+// <1-256><#-1>
+// <i> N Value
+// </h>
+// </e>
+//
+// <e5> PLL1 Configuration (USB PLL)
+// <h> PLL1 Configuration Register (PLL1CFG)
+// <i> F_usb = M * F_osc or F_usb = F_cco1 / (2 * P)
+// <i> F_cco1 = F_osc * M * 2 * P
+// <i> F_cco1 must be in the range of 156 MHz to 320 MHz
+// <o6.0..4> MSEL: PLL Multiplier Selection
+// <1-32><#-1>
+// <i> M Value (for USB maximum value is 4)
+// <o6.5..6> PSEL: PLL Divider Selection
+// <0=> 1
+// <1=> 2
+// <2=> 4
+// <3=> 8
+// <i> P Value
+// </h>
+// </e>
+//
+// <h> CPU Clock Configuration Register (CCLKCFG)
+// <o7.0..7> CCLKSEL: Divide Value for CPU Clock from PLL0
+// <2-256:2><#-1>
+// </h>
+//
+// <h> USB Clock Configuration Register (USBCLKCFG)
+// <o8.0..3> USBSEL: Divide Value for USB Clock from PLL1
+// <0-15>
+// <i> Divide is USBSEL + 1
+// </h>
+//
+// <h> Peripheral Clock Selection Register 0 (PCLKSEL0)
+// <o9.0..1> PCLK_WDT: Peripheral Clock Selection for WDT
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.2..3> PCLK_TIMER0: Peripheral Clock Selection for TIMER0
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.4..5> PCLK_TIMER1: Peripheral Clock Selection for TIMER1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.6..7> PCLK_UART0: Peripheral Clock Selection for UART0
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.8..9> PCLK_UART1: Peripheral Clock Selection for UART1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.12..13> PCLK_PWM1: Peripheral Clock Selection for PWM1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.14..15> PCLK_I2C0: Peripheral Clock Selection for I2C0
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.16..17> PCLK_SPI: Peripheral Clock Selection for SPI
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.20..21> PCLK_SSP1: Peripheral Clock Selection for SSP1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.22..23> PCLK_DAC: Peripheral Clock Selection for DAC
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.24..25> PCLK_ADC: Peripheral Clock Selection for ADC
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.26..27> PCLK_CAN1: Peripheral Clock Selection for CAN1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 6
+// <o9.28..29> PCLK_CAN2: Peripheral Clock Selection for CAN2
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 6
+// <o9.30..31> PCLK_ACF: Peripheral Clock Selection for ACF
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 6
+// </h>
+//
+// <h> Peripheral Clock Selection Register 1 (PCLKSEL1)
+// <o10.0..1> PCLK_QEI: Peripheral Clock Selection for the Quadrature Encoder Interface
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.2..3> PCLK_GPIO: Peripheral Clock Selection for GPIOs
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.4..5> PCLK_PCB: Peripheral Clock Selection for the Pin Connect Block
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.6..7> PCLK_I2C1: Peripheral Clock Selection for I2C1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.10..11> PCLK_SSP0: Peripheral Clock Selection for SSP0
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.12..13> PCLK_TIMER2: Peripheral Clock Selection for TIMER2
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.14..15> PCLK_TIMER3: Peripheral Clock Selection for TIMER3
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.16..17> PCLK_UART2: Peripheral Clock Selection for UART2
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.18..19> PCLK_UART3: Peripheral Clock Selection for UART3
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.20..21> PCLK_I2C2: Peripheral Clock Selection for I2C2
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.22..23> PCLK_I2S: Peripheral Clock Selection for I2S
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.26..27> PCLK_RIT: Peripheral Clock Selection for the Repetitive Interrupt Timer
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.28..29> PCLK_SYSCON: Peripheral Clock Selection for the System Control Block
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.30..31> PCLK_MC: Peripheral Clock Selection for the Motor Control PWM
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// </h>
+//
+// <h> Power Control for Peripherals Register (PCONP)
+// <o11.1> PCTIM0: Timer/Counter 0 power/clock enable
+// <o11.2> PCTIM1: Timer/Counter 1 power/clock enable
+// <o11.3> PCUART0: UART 0 power/clock enable
+// <o11.4> PCUART1: UART 1 power/clock enable
+// <o11.6> PCPWM1: PWM 1 power/clock enable
+// <o11.7> PCI2C0: I2C interface 0 power/clock enable
+// <o11.8> PCSPI: SPI interface power/clock enable
+// <o11.9> PCRTC: RTC power/clock enable
+// <o11.10> PCSSP1: SSP interface 1 power/clock enable
+// <o11.12> PCAD: A/D converter power/clock enable
+// <o11.13> PCCAN1: CAN controller 1 power/clock enable
+// <o11.14> PCCAN2: CAN controller 2 power/clock enable
+// <o11.15> PCGPIO: GPIOs power/clock enable
+// <o11.16> PCRIT: Repetitive interrupt timer power/clock enable
+// <o11.17> PCMC: Motor control PWM power/clock enable
+// <o11.18> PCQEI: Quadrature encoder interface power/clock enable
+// <o11.19> PCI2C1: I2C interface 1 power/clock enable
+// <o11.21> PCSSP0: SSP interface 0 power/clock enable
+// <o11.22> PCTIM2: Timer 2 power/clock enable
+// <o11.23> PCTIM3: Timer 3 power/clock enable
+// <o11.24> PCUART2: UART 2 power/clock enable
+// <o11.25> PCUART3: UART 3 power/clock enable
+// <o11.26> PCI2C2: I2C interface 2 power/clock enable
+// <o11.27> PCI2S: I2S interface power/clock enable
+// <o11.29> PCGPDMA: GP DMA function power/clock enable
+// <o11.30> PCENET: Ethernet block power/clock enable
+// <o11.31> PCUSB: USB interface power/clock enable
+// </h>
+// </e>
+*/
+
+#define CLOCK_SETUP 1
+
+#define SCS_Val 0x00000020 /* OSCEN */
+#define CLKSRCSEL_Val 0x00000001 /* XTAL */
+
+#define PLL0_SETUP 1
+#define PLL0CFG_Val 0x0000000B /* 288000000Hz - must be in the range 275HMz-550MHz */
+
+#define PLL1_SETUP 0
+#define PLL1CFG_Val 0x00000023
+
+#define CCLKCFG_Val 0x00000003 /* ppl0clk/(CCLKCFG_Val+1)=72000000Hz */
+#define USBCLKCFG_Val 0x00000005 /* divide ppl0clk by 6 to 48MHz */
+
+//#define PCLKSEL0_Val 0x00000000 /* all peripherial sysclk/4 */
+//#define PCLKSEL1_Val 0x00000000
+//#define PCONP_Val 0x042887DE
+
+#define PCONP_CLK_DIV(x) ((x)==0?4:((x)==1?1:((x)==2?2:8)))
+
+/*--------------------- Flash Accelerator Configuration ----------------------
+//
+// <e> Flash Accelerator Configuration
+// <o1.0..1> FETCHCFG: Fetch Configuration
+// <0=> Instruction fetches from flash are not buffered
+// <1=> One buffer is used for all instruction fetch buffering
+// <2=> All buffers may be used for instruction fetch buffering
+// <3=> Reserved (do not use this setting)
+// <o1.2..3> DATACFG: Data Configuration
+// <0=> Data accesses from flash are not buffered
+// <1=> One buffer is used for all data access buffering
+// <2=> All buffers may be used for data access buffering
+// <3=> Reserved (do not use this setting)
+// <o1.4> ACCEL: Acceleration Enable
+// <o1.5> PREFEN: Prefetch Enable
+// <o1.6> PREFOVR: Prefetch Override
+// <o1.12..15> FLASHTIM: Flash Access Time
+// <0=> 1 CPU clock (for CPU clock up to 20 MHz)
+// <1=> 2 CPU clocks (for CPU clock up to 40 MHz)
+// <2=> 3 CPU clocks (for CPU clock up to 60 MHz)
+// <3=> 4 CPU clocks (for CPU clock up to 80 MHz)
+// <4=> 5 CPU clocks (for CPU clock up to 100 MHz)
+// <5=> 6 CPU clocks (for any CPU clock)
+// </e>
+*/
+#define FLASH_SETUP 1
+#define FLASHCFG_Val 0x0000403A
+
+/*----------------------------------------------------------------------------
+ Define clocks
+ *----------------------------------------------------------------------------*/
+#define XTAL (12000000UL) /* Oscillator frequency */
+#define OSC_CLK ( XTAL) /* Main oscillator frequency */
+#define RTC_CLK ( 32000UL) /* RTC oscillator frequency */
+#define IRC_OSC ( 4000000UL) /* Internal RC oscillator frequency */
+
+#define SYS_TIMER_HZ 1000
+
+#ifndef BIT
+#define BIT(n) (1 << (n))
+#endif
+
+// Port Bit Definitions & Macros: Description - initial conditions
+#define CAN1_RX_BIT BIT(0) // CAN1 RX
+#define CAN1_TX_BIT BIT(1) // CAN1 TX
+#define TXD0_BIT BIT(2) // used by UART0
+#define RXD0_BIT BIT(3) // used by UART0
+#define CAN2_RX_BIT BIT(4) // CAN2 RX
+#define CAN2_TX_BIT BIT(5) // CAN2 TX
+#define LED2_BIT BIT(6) // active low/SSEL1
+#define LED2_PIN PORT_PIN(0,6,PORT_CONF_GPIO_OUT_LO)
+#define SSP1_CS0_BIT BIT(6) // active low/ LMC_GRAD CS
+#define SSP1_CS0_PIN PORT_PIN(0,6,PORT_CONF_GPIO_OUT_HI)
+#define SCK1_BIT BIT(7) // clock SSP1 to gradient valves
+#define SCK1_PIN PORT_PIN(0,7,PORT_CONF_FNC_2|PORT_CONF_OUT_LO_NORM)
+#define MISO1_BIT BIT(8) // master input
+#define MISO1_PIN PORT_PIN(0,8,PORT_CONF_FNC_2|PORT_CONF_IN_PU)
+#define MOSI1_BIT BIT(9) // master output
+#define MOSI1_PIN PORT_PIN(0,9,PORT_CONF_FNC_2|PORT_CONF_OUT_LO_NORM)
+#define P0_10_UNUSED_BIT BIT(10) // P0.10 unused (SDA2/TXD2)
+#define P0_11_UNUSED_BIT BIT(11) // P0.11 unused (SCL2/RXD2)
+#define SCK0_BIT BIT(15) // clock SSP0 to display panel
+#define SCK0_PIN PORT_PIN(0,15,PORT_CONF_FNC_2|PORT_CONF_OUT_LO_NORM)
+#define SSEL0_BIT BIT(16) // slave select SSP0
+#define SSP0_CS0_BIT BIT(16) // slave select SSP0 / display chip select
+#define SSP0_CS0_PIN PORT_PIN(0,16,PORT_CONF_GPIO_OUT_HI)
+#define MISO0_BIT BIT(17) // master input SSP0
+#define MISO0_PIN PORT_PIN(0,17,PORT_CONF_FNC_2|PORT_CONF_IN_PU)
+#define MOSI0_BIT BIT(18) // master output SSP0
+#define MOSI0_PIN PORT_PIN(0,18,PORT_CONF_FNC_2|PORT_CONF_OUT_LO_NORM)
+#define SDA1_BIT BIT(19) // I2C data - memory/connector
+#define SCL1_BIT BIT(20) // I2C clock
+#define SSP0_CS1_BIT BIT(21) // chip select 1 SSP0/ A/D for display
+#define SSP0_CS1_PIN PORT_PIN(0,21,PORT_CONF_GPIO_OUT_HI)
+#define SSP0_CS2_BIT BIT(22) // chip select 2 SSP0 for keyboard and LED
+#define SSP0_CS2_PIN PORT_PIN(0,22,PORT_CONF_GPIO_OUT_HI)
+#define ADC0_BIT BIT(23) // ADC motor current
+#define ADC0_PIN PORT_PIN(0,23,PORT_CONF_FNC_1|PORT_CONF_DIR_IN)
+#define ADC1_BIT BIT(24) // ADC motor current
+#define ADC1_PIN PORT_PIN(0,24,PORT_CONF_FNC_1|PORT_CONF_DIR_IN)
+#define ADC2_BIT BIT(25) // ADC motor current
+#define ADC2_PIN PORT_PIN(0,25,PORT_CONF_FNC_1|PORT_CONF_DIR_IN)
+#define ADC3_BIT BIT(26) // ADC motor current
+#define ADC3_PIN PORT_PIN(0,26,PORT_CONF_FNC_1|PORT_CONF_DIR_IN)
+#define P0_27_UNUSED_BIT BIT(27) // P0.27 unused
+#define P0_28_UNUSED_BIT BIT(28) // P0.28 unused
+#define USBDPLUS_BIT BIT(29) // P0.29 USBD+
+#define USBDMINUS_BIT BIT(30) // P0.30 USBD-
+
+
+// Port Bit Definitions & Macros: Description - initial conditions
+
+#define P1_ETH_BITS (BIT(0)|BIT(1)|BIT(4)|BIT(8)|BIT(9)|\
+ BIT(10)|BIT(14)|BIT(15)|BIT(16)|BIT(17))
+
+#define P1_0_UNUSED_BIT BIT(0) // P1.0 unused - low output
+#define P1_1_UNUSED_BIT BIT(1) // P1.1 unused - low output
+#define P1_4_UNUSED_BIT BIT(4) // P1.4 unused - low output
+#define P1_8_UNUSED_BIT BIT(8) // P1.8 unused - low output
+#define P1_9_UNUSED_BIT BIT(9) // P1.9 unused - low output
+#define P1_10_UNUSED_BIT BIT(10) // P1.10 unused - low output
+#define P1_14_UNUSED_BIT BIT(14) // P1.14 unused - low output
+#define P1_15_UNUSED_BIT BIT(15) // P1.15 unused - low output
+#define PWM1_BIT BIT(18) // motor pwm 0 / ADC0
+#define PWM1_PIN PORT_PIN(1,18,PORT_CONF_FNC_2|PORT_CONF_OUT_LO_NORM)
+#define BLDC_HAL_A_BIT BIT(19) // motor HAL input A
+#define BLDC_HAL_A_PIN PORT_PIN(1,19,PORT_CONF_GPIO_IN_PU)
+#define IRC_A_BIT BIT(20) // motor IRC channel A (MCI0)
+#define IRC_M_BIT BIT(21) // motor IRC channel mark (GPIO)
+#define IRC_M_PIN PORT_PIN(1,21,PORT_CONF_FNC_1|PORT_CONF_IN_PU)
+#define BLDC_HAL_B_BIT BIT(22) // motor HAL input B
+#define BLDC_HAL_B_PIN PORT_PIN(1,22,PORT_CONF_GPIO_IN_PU)
+#define IRC_B_BIT BIT(23) // motor IRC channel B (MCI1)
+#define IRC_I_BIT BIT(24) // motor IRC index (MCI2)
+#define BLDC_HAL_C_BIT BIT(25) // motor HAL input C
+#define BLDC_HAL_C_PIN PORT_PIN(1,25,PORT_CONF_GPIO_IN_PU)
+#define PWM1_EN_BIT BIT(26) // motor pwm 0 enable
+#define PWM1_EN_PIN PORT_PIN(1,26,PORT_CONF_GPIO_OUT_LO)
+#define PWM2_EN_BIT BIT(27) // motor pwm 1 enable
+#define PWM2_EN_PIN PORT_PIN(1,27,PORT_CONF_GPIO_OUT_LO)
+#define PWM4_EN_BIT BIT(28) // motor pwm 2 enable
+#define PWM4_EN_PIN PORT_PIN(1,28,PORT_CONF_GPIO_OUT_LO)
+#define PWM6_EN_BIT BIT(29) // motor pwm 3 enable
+#define PWM6_EN_PIN PORT_PIN(1,29,PORT_CONF_GPIO_OUT_LO)
+#define ADC4_BIT BIT(30) // ADC4 tensometer
+#define ADC4_PIN PORT_PIN(1,30,PORT_CONF_FNC_3|PORT_CONF_DIR_IN)
+#define ADC5_BIT BIT(31) // ADC5 external input
+#define ADC5_PIN PORT_PIN(1,31,PORT_CONF_FNC_3|PORT_CONF_DIR_IN)
+
+// Port Bit Definitions & Macros: Description - initial conditions
+#define TXD1_BIT BIT(0) // P2.0 TXD
+#define RXD1_BIT BIT(1) // P2.1 RXD
+#define CTS1_BIT BIT(2) // P2.2 CTS connected to RXD1
+#define PWM4_BIT BIT(3) // P2.3 motor pwm 2 / ADC2
+#define PWM4_PIN PORT_PIN(2,3,PORT_CONF_FNC_1|PORT_CONF_OUT_LO_NORM)
+#define DSR1_BIT BIT(4) // P2.4 DSR connected to TXD1
+#define PWM6_BIT BIT(5) // P2.5 motor pwm 3 / ADC3
+#define PWM6_PIN PORT_PIN(2,5,PORT_CONF_FNC_1|PORT_CONF_OUT_LO_NORM)
+#define LED1_BIT BIT(6) // P2.6 LED1 - error
+#define LED1_PIN PORT_PIN(2,6,PORT_CONF_GPIO_OUT_LO)
+#define RTS1_BIT BIT(7) // P2.7 RTS1 used as DIR1
+#define AUX_OUT2_BIT BIT(8) // P2.8 auxual TLL port
+#define AUX_OUT2_PIN PORT_PIN(2,8,PORT_CONF_GPIO_OUT_HI)
+#define USB_CONNECT_BIT BIT(9) // P2.9 USB output for soft connect
+#define BOOT_BIT BIT(10) // P2.10 Boot input
+#define AUX_IN2_BIT BIT(11) // P2.11 auxual TLL port
+#define AUX_IN2_PIN PORT_PIN(2,11,PORT_CONF_GPIO_IN_PU)
+#define AUX_OUT4_BIT BIT(12) // P2.12 auxual TLL port
+#define AUX_OUT4_PIN PORT_PIN(2,12,PORT_CONF_GPIO_OUT_HI)
+#define ETH_PD_IRQ_BIT BIT(13) // P2.13 power down/int
+
+// Port Bit Definitions & Macros: Description - initial conditions
+#define PWM2_BIT BIT(25) // P3.25 motor pwm 1 / ADC1
+#define PWM2_PIN PORT_PIN(3,25,PORT_CONF_FNC_3|PORT_CONF_OUT_LO_NORM)
+#define AUX_OUT1_BIT BIT(26) // P3.26 auxual TLL port
+#define AUX_OUT1_PIN PORT_PIN(3,26,PORT_CONF_GPIO_OUT_HI)
+
+// Port Bit Definitions & Macros: Description - initial conditions
+#define AUX_OUT3_BIT BIT(28) // P4.28 auxual TLL port / TXD3
+#define AUX_OUT3_PIN PORT_PIN(4,28,PORT_CONF_GPIO_OUT_HI)
+#define AUX_IN1_BIT BIT(29) // P4.29 auxual TLL port / RXD3
+#define AUX_IN1_PIN PORT_PIN(4,29,PORT_CONF_GPIO_IN_PU)
+
+#define P0IO_INPUT_BITS (uint32_t) ( \
+ CAN1_RX_BIT | \
+ RXD0_BIT | \
+ CAN2_RX_BIT | \
+ MISO1_BIT | \
+ P0_10_UNUSED_BIT | \
+ P0_11_UNUSED_BIT | \
+ MISO0_BIT | \
+ SDA1_BIT | \
+ SCL1_BIT | \
+ ADC0_BIT | \
+ ADC1_BIT | \
+ ADC2_BIT | \
+ ADC3_BIT | \
+ USBDPLUS_BIT | \
+ USBDMINUS_BIT | \
+ 0 )
+
+#define P1IO_INPUT_BITS (uint32_t) ( \
+ P1_ETH_BITS | \
+ BLDC_HAL_A_BIT | \
+ IRC_A_BIT | \
+ IRC_M_BIT | \
+ BLDC_HAL_B_BIT | \
+ IRC_B_BIT | \
+ IRC_I_BIT | \
+ BLDC_HAL_C_BIT | \
+ ADC4_BIT | \
+ ADC5_BIT | \
+ 0 )
+
+#define P2IO_INPUT_BITS (uint32_t) ( \
+ RXD1_BIT | \
+ CTS1_BIT | \
+ DSR1_BIT | \
+ BOOT_BIT | \
+ AUX_IN2_BIT | \
+ ETH_PD_IRQ_BIT | \
+ 0 )
+
+#define P3IO_INPUT_BITS (uint32_t) ( \
+ 0 )
+
+#define P4IO_INPUT_BITS (uint32_t) ( \
+ AUX_IN1_BIT | \
+ 0 )
+
+#define P0IO_ZERO_BITS (uint32_t) ( \
+ P0_27_UNUSED_BIT | \
+ P0_28_UNUSED_BIT | \
+ 0 )
+
+#define P1IO_ZERO_BITS (uint32_t) ( \
+ PWM1_BIT | \
+ PWM1_EN_BIT | \
+ PWM2_EN_BIT | \
+ PWM4_EN_BIT | \
+ PWM6_EN_BIT | \
+ 0 )
+
+#define P2IO_ZERO_BITS (uint32_t) ( \
+ PWM4_BIT | \
+ PWM6_BIT | \
+ 0 )
+
+#define P3IO_ZERO_BITS (uint32_t) ( \
+ PWM2_BIT | \
+ 0 )
+
+#define P4IO_ZERO_BITS (uint32_t) ( \
+ 0 )
+
+#define P0IO_ONE_BITS (uint32_t) ( \
+ CAN1_TX_BIT | \
+ TXD0_BIT | \
+ CAN2_TX_BIT | \
+ LED2_BIT | \
+ SCK1_BIT | \
+ MOSI1_BIT | \
+ SCK0_BIT | \
+ SSEL0_BIT | \
+ MOSI0_BIT | \
+ SSP0_CS0_BIT | \
+ SSP0_CS1_BIT | \
+ 0 )
+
+#define P1IO_ONE_BITS (uint32_t) ( \
+ 0 )
+
+#define P2IO_ONE_BITS (uint32_t) ( \
+ TXD1_BIT | \
+ LED1_BIT | \
+ RTS1_BIT | \
+ AUX_OUT2_BIT | \
+ USB_CONNECT_BIT | \
+ AUX_OUT4_BIT | \
+ 0 )
+
+#define P3IO_ONE_BITS (uint32_t) ( \
+ AUX_OUT1_BIT | \
+ 0 )
+
+#define P4IO_ONE_BITS (uint32_t) ( \
+ AUX_OUT3_BIT | \
+ 0 )
+
+#define P0IO_OUTPUT_BITS (uint32_t) ( \
+ P0IO_ZERO_BITS | \
+ P0IO_ONE_BITS )
+
+#define P1IO_OUTPUT_BITS (uint32_t) ( \
+ P1IO_ZERO_BITS | \
+ P1IO_ONE_BITS )
+
+#define P2IO_OUTPUT_BITS (uint32_t) ( \
+ P2IO_ZERO_BITS | \
+ P2IO_ONE_BITS )
+
+#define P3IO_OUTPUT_BITS (uint32_t) ( \
+ P3IO_ZERO_BITS | \
+ P3IO_ONE_BITS )
+
+#define P4IO_OUTPUT_BITS (uint32_t) ( \
+ P4IO_ZERO_BITS | \
+ P4IO_ONE_BITS )
+
+
+
+/***************************************************************************/
+/* io functions */
+#define LED_GP LED2_BIT /* GENREAL PURPOSE LED */
+#define LED_ERR LED1_BIT
+
+/***************************************************************************/
+/* io functions */
+#define IN_PORT GPIO0->FIO
+#define OUT_PORT GPIO1->FIO
+#define LED_PORT GPIO2->FIO
+
+#define CREATE_PORT_NAME_PIN(port) port##PIN
+#define CREATE_PORT_NAME_CLR(port) port##CLR
+#define CREATE_PORT_NAME_SET(port) port##SET
+
+#define GET_IN_PIN(port,in) ((CREATE_PORT_NAME_PIN(port) & in)?1:0)
+#define GET_IN_PORT(port) (CREATE_PORT_NAME_PIN(port))
+#define SET_OUT_PIN(port,out) (CREATE_PORT_NAME_SET(port)=out)
+#define CLR_OUT_PIN(port,out) (CREATE_PORT_NAME_CLR(port)=out)
+
+/***************************************************************************/
+/* watchdog */
+#define WATCHDOG_ENABLED
+#define WATCHDOG_TIMEOUT_MS 1000
+
+/***************************************************************************/
+/* uLan configuration */
+
+#ifdef UL_LOG_ENABLE
+ #undef UL_LOG_ENABLE
+#endif
+
+#ifdef ULD_DEFAULT_BUFFER_SIZE
+ #undef ULD_DEFAULT_BUFFER_SIZE
+ #define ULD_DEFAULT_BUFFER_SIZE 0x2000
+#endif
+
+#define UL_DRV_SYSLESS_PORT UART1_BASE
+#define UL_DRV_SYSLESS_BAUD 19200
+#define UL_DRV_SYSLESS_IRQ UART1_IRQn
+#define UL_DRV_SYSLESS_MY_ADR_DEFAULT 1
+
+#define watchdog_feed lpc_watchdog_feed
+#define kvpb_erase lpcisp_kvpb_erase
+#define kvpb_copy lpcisp_kvpb_copy
+#define kvpb_flush lpcisp_kvpb_flush
+#define KVPB_DEFAULT_FLAGS KVPB_DESC_DOUBLE|KVPB_DESC_CHUNKWO
+
+/***************************************************************************/
+/* USB configuration */
+#define USB_WITH_UDEV_FNC
+#define USB_EP_NUM 32
+#define USB_MAX_PACKET0 64
+#define USB_MAX_PACKET 8
+#define USB_DMA_EP 0x00000000
+
+#define USB_VBUS_PIN_USED 0
+
+/***************************************************************************/
+/* I2C1 configuration */
+#define I2C_DRV_SYSLESS_IRQ I2C1_IRQn
+#define I2C_DRV_SYSLESS_PORT I2C1_BASE
+#define I2C_DRV_SYSLESS_BITRATE 10000
+#define I2C_DRV_SYSLESS_SLADR 0
+
+#endif /* _SYSTEM_DEF_H_ */
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ system_def.h - common cover for definition of hardware adresses,
+ registers, timing and other hardware dependant
+ parts of embedded hardware
+
+ Copyright (C) 2001 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002 by PiKRON Ltd. http://www.pikron.com
+
+ *******************************************************************/
+
+#ifndef _SYSTEM_DEF_H_
+#define _SYSTEM_DEF_H_
+
+#include <types.h>
+#include <system_stub.h>
+#include <LPC17xx.h>
+#include <bspbase.h>
+
+#ifndef MACH_LPC17XX
+#define MACH_LPC17XX
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define VER_CODE(major,minor,patch) (major*0x10000+minor*0x100+patch)
+/* Software version */
+#define SW_VER_ID "MPX-UU-PC"
+#define SW_VER_MAJOR 0
+#define SW_VER_MINOR 2
+#define SW_VER_PATCH 0
+#define SW_VER_CODE VER_CODE(SW_VER_MAJOR,SW_VER_MINOR,SW_VER_PATCH)
+/* Hardware version */
+#define HW_VER_ID "MPX-UU-PC"
+#define HW_VER_MAJOR 1
+#define HW_VER_MINOR 0
+#define HW_VER_PATCH 0
+#define HW_VER_CODE VER_CODE(HW_VER_MAJOR,HW_VER_MINOR,HW_VER_PATCH)
+/* Version of mechanical */
+#define MECH_VER_ID "MPX-UU-PC"
+#define MECH_VER_MAJOR 0
+#define MECH_VER_MINOR 0
+#define MECH_VER_PATCH 0
+#define MECH_VER_CODE VER_CODE(MECH_VER_MAJOR,MECH_VER_MINOR,MECH_VER_PATCH)
+
+
+/*--------------------- Clock Configuration ----------------------------------
+//
+// <e> Clock Configuration
+// <h> System Controls and Status Register (SCS)
+// <o1.4> OSCRANGE: Main Oscillator Range Select
+// <0=> 1 MHz to 20 MHz
+// <1=> 15 MHz to 24 MHz
+// <e1.5> OSCEN: Main Oscillator Enable
+// </e>
+// </h>
+//
+// <h> Clock Source Select Register (CLKSRCSEL)
+// <o2.0..1> CLKSRC: PLL Clock Source Selection
+// <0=> Internal RC oscillator
+// <1=> Main oscillator
+// <2=> RTC oscillator
+// </h>
+//
+// <e3> PLL0 Configuration (Main PLL)
+// <h> PLL0 Configuration Register (PLL0CFG)
+// <i> F_cco0 = (2 * M * F_in) / N
+// <i> F_in must be in the range of 32 kHz to 50 MHz
+// <i> F_cco0 must be in the range of 275 MHz to 550 MHz
+// <o4.0..14> MSEL: PLL Multiplier Selection
+// <6-32768><#-1>
+// <i> M Value
+// <o4.16..23> NSEL: PLL Divider Selection
+// <1-256><#-1>
+// <i> N Value
+// </h>
+// </e>
+//
+// <e5> PLL1 Configuration (USB PLL)
+// <h> PLL1 Configuration Register (PLL1CFG)
+// <i> F_usb = M * F_osc or F_usb = F_cco1 / (2 * P)
+// <i> F_cco1 = F_osc * M * 2 * P
+// <i> F_cco1 must be in the range of 156 MHz to 320 MHz
+// <o6.0..4> MSEL: PLL Multiplier Selection
+// <1-32><#-1>
+// <i> M Value (for USB maximum value is 4)
+// <o6.5..6> PSEL: PLL Divider Selection
+// <0=> 1
+// <1=> 2
+// <2=> 4
+// <3=> 8
+// <i> P Value
+// </h>
+// </e>
+//
+// <h> CPU Clock Configuration Register (CCLKCFG)
+// <o7.0..7> CCLKSEL: Divide Value for CPU Clock from PLL0
+// <2-256:2><#-1>
+// </h>
+//
+// <h> USB Clock Configuration Register (USBCLKCFG)
+// <o8.0..3> USBSEL: Divide Value for USB Clock from PLL1
+// <0-15>
+// <i> Divide is USBSEL + 1
+// </h>
+//
+// <h> Peripheral Clock Selection Register 0 (PCLKSEL0)
+// <o9.0..1> PCLK_WDT: Peripheral Clock Selection for WDT
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.2..3> PCLK_TIMER0: Peripheral Clock Selection for TIMER0
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.4..5> PCLK_TIMER1: Peripheral Clock Selection for TIMER1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.6..7> PCLK_UART0: Peripheral Clock Selection for UART0
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.8..9> PCLK_UART1: Peripheral Clock Selection for UART1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.12..13> PCLK_PWM1: Peripheral Clock Selection for PWM1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.14..15> PCLK_I2C0: Peripheral Clock Selection for I2C0
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.16..17> PCLK_SPI: Peripheral Clock Selection for SPI
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.20..21> PCLK_SSP1: Peripheral Clock Selection for SSP1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.22..23> PCLK_DAC: Peripheral Clock Selection for DAC
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.24..25> PCLK_ADC: Peripheral Clock Selection for ADC
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.26..27> PCLK_CAN1: Peripheral Clock Selection for CAN1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 6
+// <o9.28..29> PCLK_CAN2: Peripheral Clock Selection for CAN2
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 6
+// <o9.30..31> PCLK_ACF: Peripheral Clock Selection for ACF
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 6
+// </h>
+//
+// <h> Peripheral Clock Selection Register 1 (PCLKSEL1)
+// <o10.0..1> PCLK_QEI: Peripheral Clock Selection for the Quadrature Encoder Interface
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.2..3> PCLK_GPIO: Peripheral Clock Selection for GPIOs
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.4..5> PCLK_PCB: Peripheral Clock Selection for the Pin Connect Block
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.6..7> PCLK_I2C1: Peripheral Clock Selection for I2C1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.10..11> PCLK_SSP0: Peripheral Clock Selection for SSP0
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.12..13> PCLK_TIMER2: Peripheral Clock Selection for TIMER2
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.14..15> PCLK_TIMER3: Peripheral Clock Selection for TIMER3
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.16..17> PCLK_UART2: Peripheral Clock Selection for UART2
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.18..19> PCLK_UART3: Peripheral Clock Selection for UART3
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.20..21> PCLK_I2C2: Peripheral Clock Selection for I2C2
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.22..23> PCLK_I2S: Peripheral Clock Selection for I2S
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.26..27> PCLK_RIT: Peripheral Clock Selection for the Repetitive Interrupt Timer
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.28..29> PCLK_SYSCON: Peripheral Clock Selection for the System Control Block
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.30..31> PCLK_MC: Peripheral Clock Selection for the Motor Control PWM
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// </h>
+//
+// <h> Power Control for Peripherals Register (PCONP)
+// <o11.1> PCTIM0: Timer/Counter 0 power/clock enable
+// <o11.2> PCTIM1: Timer/Counter 1 power/clock enable
+// <o11.3> PCUART0: UART 0 power/clock enable
+// <o11.4> PCUART1: UART 1 power/clock enable
+// <o11.6> PCPWM1: PWM 1 power/clock enable
+// <o11.7> PCI2C0: I2C interface 0 power/clock enable
+// <o11.8> PCSPI: SPI interface power/clock enable
+// <o11.9> PCRTC: RTC power/clock enable
+// <o11.10> PCSSP1: SSP interface 1 power/clock enable
+// <o11.12> PCAD: A/D converter power/clock enable
+// <o11.13> PCCAN1: CAN controller 1 power/clock enable
+// <o11.14> PCCAN2: CAN controller 2 power/clock enable
+// <o11.15> PCGPIO: GPIOs power/clock enable
+// <o11.16> PCRIT: Repetitive interrupt timer power/clock enable
+// <o11.17> PCMC: Motor control PWM power/clock enable
+// <o11.18> PCQEI: Quadrature encoder interface power/clock enable
+// <o11.19> PCI2C1: I2C interface 1 power/clock enable
+// <o11.21> PCSSP0: SSP interface 0 power/clock enable
+// <o11.22> PCTIM2: Timer 2 power/clock enable
+// <o11.23> PCTIM3: Timer 3 power/clock enable
+// <o11.24> PCUART2: UART 2 power/clock enable
+// <o11.25> PCUART3: UART 3 power/clock enable
+// <o11.26> PCI2C2: I2C interface 2 power/clock enable
+// <o11.27> PCI2S: I2S interface power/clock enable
+// <o11.29> PCGPDMA: GP DMA function power/clock enable
+// <o11.30> PCENET: Ethernet block power/clock enable
+// <o11.31> PCUSB: USB interface power/clock enable
+// </h>
+// </e>
+*/
+
+#define CLOCK_SETUP 1
+
+#define SCS_Val 0x00000020 /* OSCEN */
+#define CLKSRCSEL_Val 0x00000001 /* XTAL */
+
+#define PLL0_SETUP 1
+#define PLL0CFG_Val 0x0000000B /* 324403200Hz - must be in the range 275HMz-550MHz */
+
+#define PLL1_SETUP 0
+#define PLL1CFG_Val 0x00000023
+
+#define CCLKCFG_Val 0x00000003 /* pplclk/(CCLKCFG_Val+1)=81100800Hz */
+#define USBCLKCFG_Val 0x00000005
+
+//#define PCLKSEL0_Val 0x00000000 /* all peripherial sysclk/4 */
+//#define PCLKSEL1_Val 0x00000000
+//#define PCONP_Val 0x042887DE
+
+#define PCONP_CLK_DIV(x) ((x)==0?4:((x)==1?1:((x)==2?2:8)))
+
+/*--------------------- Flash Accelerator Configuration ----------------------
+//
+// <e> Flash Accelerator Configuration
+// <o1.0..1> FETCHCFG: Fetch Configuration
+// <0=> Instruction fetches from flash are not buffered
+// <1=> One buffer is used for all instruction fetch buffering
+// <2=> All buffers may be used for instruction fetch buffering
+// <3=> Reserved (do not use this setting)
+// <o1.2..3> DATACFG: Data Configuration
+// <0=> Data accesses from flash are not buffered
+// <1=> One buffer is used for all data access buffering
+// <2=> All buffers may be used for data access buffering
+// <3=> Reserved (do not use this setting)
+// <o1.4> ACCEL: Acceleration Enable
+// <o1.5> PREFEN: Prefetch Enable
+// <o1.6> PREFOVR: Prefetch Override
+// <o1.12..15> FLASHTIM: Flash Access Time
+// <0=> 1 CPU clock (for CPU clock up to 20 MHz)
+// <1=> 2 CPU clocks (for CPU clock up to 40 MHz)
+// <2=> 3 CPU clocks (for CPU clock up to 60 MHz)
+// <3=> 4 CPU clocks (for CPU clock up to 80 MHz)
+// <4=> 5 CPU clocks (for CPU clock up to 100 MHz)
+// <5=> 6 CPU clocks (for any CPU clock)
+// </e>
+*/
+#define FLASH_SETUP 1
+#define FLASHCFG_Val 0x0000403A
+
+/*----------------------------------------------------------------------------
+ Define clocks
+ *----------------------------------------------------------------------------*/
+#define XTAL (12000000UL) /* Oscillator frequency */
+#define OSC_CLK ( XTAL) /* Main oscillator frequency */
+#define RTC_CLK ( 32000UL) /* RTC oscillator frequency */
+#define IRC_OSC ( 4000000UL) /* Internal RC oscillator frequency */
+
+
+
+
+#define SYS_TIMER_HZ 1000
+
+#ifndef BIT
+#define BIT(n) (1 << (n))
+#endif
+
+// Port Bit Definitions & Macros: Description - initial conditions
+#define P0_0_UNUSED_BIT BIT(0) // P0.0 unused - low output
+#define P0_1_UNUSED_BIT BIT(1) // P0.1 unused - low output
+#define TXD0_BIT BIT(2) // used by UART0
+#define RXD0_BIT BIT(3) // used by UART0
+#define P0_6_UNUSED_BIT BIT(6) // P0.6 unused - low output
+#define P0_7_UNUSED_BIT BIT(7) // P0.7 unused - low output
+#define P0_8_UNUSED_BIT BIT(8) // P0.8 unused - low output
+#define P0_9_UNUSED_BIT BIT(9) // P0.9 unused - low output
+#define P0_10_UNUSED_BIT BIT(10) // P0.10 unused - low output
+#define P0_11_UNUSED_BIT BIT(11) // P0.11 unused - low output
+#define P0_15_UNUSED_BIT BIT(15) // P0.15 unused - low output
+#define P0_16_UNUSED_BIT BIT(16) // P0.16 unused - low output
+#define LED1_BIT BIT(17) // P0.17 LED1
+#define LED2_BIT BIT(18) // P0.18 LED2
+#define P0_22_UNUSED_BIT BIT(22) // P0.22 unused - low output
+#define P0_25_UNUSED_BIT BIT(25) // P0.25 unused - low output
+#define P0_26_UNUSED_BIT BIT(26) // P0.26 unused - low output
+#define USBDPLUS_BIT BIT(29) // P0.29 USBD+
+#define USBDMINUS_BIT BIT(30) // P0.30 USBD-
+
+
+// Port Bit Definitions & Macros: Description - initial conditions
+#define P1_0_UNUSED_BIT BIT(0) // P1.0 unused - low output
+#define P1_1_UNUSED_BIT BIT(1) // P1.1 unused - low output
+#define P1_4_UNUSED_BIT BIT(4) // P1.4 unused - low output
+#define P1_8_UNUSED_BIT BIT(8) // P1.8 unused - low output
+#define P1_9_UNUSED_BIT BIT(9) // P1.9 unused - low output
+#define P1_10_UNUSED_BIT BIT(10) // P1.10 unused - low output
+#define P1_14_UNUSED_BIT BIT(14) // P1.14 unused - low output
+#define P1_15_UNUSED_BIT BIT(15) // P1.15 unused - low output
+#define P1_18_UNUSED_BIT BIT(18) // P1.18 unused - low output
+#define WDT_BIT BIT(19) // P1.19 WDT
+#define P1_20_UNUSED_BIT BIT(20) // P1.20 unused - low output
+#define P1_22_UNUSED_BIT BIT(22) // P1.22 unused - low output
+#define P1_23_UNUSED_BIT BIT(23) // P1.23 unused - low output
+#define P1_24_UNUSED_BIT BIT(24) // P1.24 unused - low output
+#define P1_25_UNUSED_BIT BIT(25) // P1.25 unused - low output
+#define P1_26_UNUSED_BIT BIT(26) // P1.26 unused - low output
+#define P1_28_UNUSED_BIT BIT(28) // P1.28 unused - low output
+#define P1_29_UNUSED_BIT BIT(29) // P1.29 unused - low output
+#define VBUS_BIT BIT(30) // P1.30
+#define P1_31_UNUSED_BIT BIT(31) // P1.31 unused - low output
+
+// Port Bit Definitions & Macros: Description - initial conditions
+#define TXD1_BIT BIT(0) // P2.0 TXD
+#define RXD1_BIT BIT(1) // P2.1 RXD
+#define CTS1_BIT BIT(2) // P2.2 CTS connected to RXD1
+#define P2_3_UNUSED_BIT BIT(3) // P2.3 unused - low output
+#define DSR1_BIT BIT(4) // P2.4 DSR connected to TXD1
+#define P2_5_UNUSED_BIT BIT(5) // P2.5 unused - low output
+#define P2_6_UNUSED_BIT BIT(6) // P2.6 unused - low output
+#define RTS1_BIT BIT(7) // P2.7 RTS1 used as DIR1
+#define P2_8_UNUSED_BIT BIT(8) // P2.8 unused - low output
+#define USB_CONNECT_BIT BIT(9) // P2.9 USB output for soft connect
+#define BOOT_BIT BIT(10) // P2.10 Boot input
+
+#define P4_28_UNUSED_BIT BIT(28) // P4.28 unused - low output
+#define P4_29_UNUSED_BIT BIT(29) // P4.29 unused - low output
+
+#define P0IO_INPUT_BITS (uint32_t) ( \
+ RXD0_BIT | \
+ USBDPLUS_BIT | \
+ USBDMINUS_BIT | \
+ 0 )
+
+#define P1IO_INPUT_BITS (uint32_t) ( \
+ VBUS_BIT | \
+ 0 )
+
+#define P2IO_INPUT_BITS (uint32_t) ( \
+ RXD1_BIT | \
+ CTS1_BIT | \
+ DSR1_BIT | \
+ BOOT_BIT | \
+ 0 )
+
+#define P3IO_INPUT_BITS (uint32_t) ( \
+ 0 )
+
+#define P4IO_INPUT_BITS (uint32_t) ( \
+ 0 )
+
+#define P0IO_ZERO_BITS (uint32_t) ( \
+ P0_0_UNUSED_BIT | \
+ P0_1_UNUSED_BIT | \
+ P0_6_UNUSED_BIT | \
+ P0_7_UNUSED_BIT | \
+ P0_8_UNUSED_BIT | \
+ P0_9_UNUSED_BIT | \
+ P0_10_UNUSED_BIT | \
+ P0_11_UNUSED_BIT | \
+ P0_15_UNUSED_BIT | \
+ P0_16_UNUSED_BIT | \
+ P0_22_UNUSED_BIT | \
+ P0_25_UNUSED_BIT | \
+ P0_26_UNUSED_BIT | \
+ 0 )
+
+#define P1IO_ZERO_BITS (uint32_t) ( \
+ P1_0_UNUSED_BIT | \
+ P1_1_UNUSED_BIT | \
+ P1_4_UNUSED_BIT | \
+ P1_8_UNUSED_BIT | \
+ P1_9_UNUSED_BIT | \
+ P1_10_UNUSED_BIT | \
+ P1_14_UNUSED_BIT | \
+ P1_15_UNUSED_BIT | \
+ P1_18_UNUSED_BIT | \
+ P1_20_UNUSED_BIT | \
+ P1_22_UNUSED_BIT | \
+ P1_23_UNUSED_BIT | \
+ P1_24_UNUSED_BIT | \
+ P1_25_UNUSED_BIT | \
+ P1_26_UNUSED_BIT | \
+ P1_28_UNUSED_BIT | \
+ P1_29_UNUSED_BIT | \
+ P1_31_UNUSED_BIT | \
+ 0 )
+
+#define P2IO_ZERO_BITS (uint32_t) ( \
+ P2_3_UNUSED_BIT | \
+ P2_5_UNUSED_BIT | \
+ P2_6_UNUSED_BIT | \
+ P2_8_UNUSED_BIT | \
+ 0 )
+
+#define P3IO_ZERO_BITS (uint32_t) ( \
+ 0 )
+
+#define P4IO_ZERO_BITS (uint32_t) ( \
+ P4_28_UNUSED_BIT | \
+ P4_29_UNUSED_BIT | \
+ 0 )
+
+#define P0IO_ONE_BITS (uint32_t) ( \
+ TXD0_BIT | \
+ LED1_BIT | \
+ LED2_BIT | \
+ 0 )
+
+#define P1IO_ONE_BITS (uint32_t) ( \
+ WDT_BIT | \
+ 0 )
+
+#define P2IO_ONE_BITS (uint32_t) ( \
+ TXD1_BIT | \
+ RTS1_BIT | \
+ USB_CONNECT_BIT | \
+ 0 )
+
+#define P3IO_ONE_BITS (uint32_t) ( \
+ 0 )
+
+#define P4IO_ONE_BITS (uint32_t) ( \
+ 0 )
+
+#define P0IO_OUTPUT_BITS (uint32_t) ( \
+ P0IO_ZERO_BITS | \
+ P0IO_ONE_BITS )
+
+#define P1IO_OUTPUT_BITS (uint32_t) ( \
+ P1IO_ZERO_BITS | \
+ P1IO_ONE_BITS )
+
+#define P2IO_OUTPUT_BITS (uint32_t) ( \
+ P2IO_ZERO_BITS | \
+ P2IO_ONE_BITS )
+
+#define P3IO_OUTPUT_BITS (uint32_t) ( \
+ P3IO_ZERO_BITS | \
+ P3IO_ONE_BITS )
+
+#define P4IO_OUTPUT_BITS (uint32_t) ( \
+ P4IO_ZERO_BITS | \
+ P4IO_ONE_BITS )
+
+
+
+/***************************************************************************/
+/* io functions */
+#define LED_GP LED1_BIT /* GENREAL PURPOSE LED */
+#define LED_ERR LED2_BIT
+
+/***************************************************************************/
+/* io functions */
+#define LED_PORT GPIO0->FIO
+#define OUT_PORT GPIO1->FIO
+
+#define CREATE_PORT_NAME_PIN(port) port##PIN
+#define CREATE_PORT_NAME_CLR(port) port##CLR
+#define CREATE_PORT_NAME_SET(port) port##SET
+
+#define GET_IN_PIN(port,in) ((CREATE_PORT_NAME_PIN(port) & in)?1:0)
+#define GET_IN_PORT(port) (CREATE_PORT_NAME_PIN(port))
+#define SET_OUT_PIN(port,out) (CREATE_PORT_NAME_SET(port)=out)
+#define CLR_OUT_PIN(port,out) (CREATE_PORT_NAME_CLR(port)=out)
+
+/***************************************************************************/
+/* watchdog */
+#define WATCHDOG_ENABLED
+#define WATCHDOG_TIMEOUT_MS 1000
+
+/***************************************************************************/
+/* uLan configuration */
+
+#ifdef UL_LOG_ENABLE
+ #undef UL_LOG_ENABLE
+#endif
+
+#ifdef ULD_DEFAULT_BUFFER_SIZE
+ #undef ULD_DEFAULT_BUFFER_SIZE
+ #define ULD_DEFAULT_BUFFER_SIZE 0x2000
+#endif
+
+#define UL_DRV_SYSLESS_PORT UART1_BASE
+#define UL_DRV_SYSLESS_BAUD 19200
+#define UL_DRV_SYSLESS_IRQ UART1_IRQn
+#define UL_DRV_SYSLESS_MY_ADR_DEFAULT 1
+
+#define watchdog_feed lpc_watchdog_feed
+#define kvpb_erase lpcisp_kvpb_erase
+#define kvpb_copy lpcisp_kvpb_copy
+#define kvpb_flush lpcisp_kvpb_flush
+#define KVPB_DEFAULT_FLAGS KVPB_DESC_DOUBLE|KVPB_DESC_CHUNKWO
+
+/***************************************************************************/
+/* USB configuration */
+#define USB_WITH_UDEV_FNC
+#define USB_EP_NUM 32
+#define USB_MAX_PACKET0 64
+#define USB_MAX_PACKET 8
+#define USB_DMA_EP 0x00000000
+
+#define USB_VBUS_PIN_USED 1
+
+
+#endif /* _SYSTEM_DEF_H_ */
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ system_def.h - common cover for definition of hardware adresses,
+ registers, timing and other hardware dependant
+ parts of embedded hardware
+
+ Copyright (C) 2001 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002 by PiKRON Ltd. http://www.pikron.com
+
+ *******************************************************************/
+
+#ifndef _SYSTEM_DEF_H_
+#define _SYSTEM_DEF_H_
+
+#include <types.h>
+#include <system_stub.h>
+#include <LPC17xx.h>
+#include <bspbase.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define VER_CODE(major,minor,patch) (major*0x10000+minor*0x100+patch)
+/* Software version */
+#define SW_VER_ID "ULMO_1M1I"
+#define SW_VER_MAJOR 0
+#define SW_VER_MINOR 2
+#define SW_VER_PATCH 0
+#define SW_VER_CODE VER_CODE(SW_VER_MAJOR,SW_VER_MINOR,SW_VER_PATCH)
+/* Hardware version */
+#define HW_VER_ID "ULMO_1M1I"
+#define HW_VER_MAJOR 1
+#define HW_VER_MINOR 0
+#define HW_VER_PATCH 0
+#define HW_VER_CODE VER_CODE(HW_VER_MAJOR,HW_VER_MINOR,HW_VER_PATCH)
+/* Version of mechanical */
+#define MECH_VER_ID "ULMO_1M1I"
+#define MECH_VER_MAJOR 0
+#define MECH_VER_MINOR 0
+#define MECH_VER_PATCH 0
+#define MECH_VER_CODE VER_CODE(MECH_VER_MAJOR,MECH_VER_MINOR,MECH_VER_PATCH)
+
+
+/*--------------------- Clock Configuration ----------------------------------
+//
+// <e> Clock Configuration
+// <h> System Controls and Status Register (SCS)
+// <o1.4> OSCRANGE: Main Oscillator Range Select
+// <0=> 1 MHz to 20 MHz
+// <1=> 15 MHz to 24 MHz
+// <e1.5> OSCEN: Main Oscillator Enable
+// </e>
+// </h>
+//
+// <h> Clock Source Select Register (CLKSRCSEL)
+// <o2.0..1> CLKSRC: PLL Clock Source Selection
+// <0=> Internal RC oscillator
+// <1=> Main oscillator
+// <2=> RTC oscillator
+// </h>
+//
+// <e3> PLL0 Configuration (Main PLL)
+// <h> PLL0 Configuration Register (PLL0CFG)
+// <i> F_cco0 = (2 * M * F_in) / N
+// <i> F_in must be in the range of 32 kHz to 50 MHz
+// <i> F_cco0 must be in the range of 275 MHz to 550 MHz
+// <o4.0..14> MSEL: PLL Multiplier Selection
+// <6-32768><#-1>
+// <i> M Value
+// <o4.16..23> NSEL: PLL Divider Selection
+// <1-256><#-1>
+// <i> N Value
+// </h>
+// </e>
+//
+// <e5> PLL1 Configuration (USB PLL)
+// <h> PLL1 Configuration Register (PLL1CFG)
+// <i> F_usb = M * F_osc or F_usb = F_cco1 / (2 * P)
+// <i> F_cco1 = F_osc * M * 2 * P
+// <i> F_cco1 must be in the range of 156 MHz to 320 MHz
+// <o6.0..4> MSEL: PLL Multiplier Selection
+// <1-32><#-1>
+// <i> M Value (for USB maximum value is 4)
+// <o6.5..6> PSEL: PLL Divider Selection
+// <0=> 1
+// <1=> 2
+// <2=> 4
+// <3=> 8
+// <i> P Value
+// </h>
+// </e>
+//
+// <h> CPU Clock Configuration Register (CCLKCFG)
+// <o7.0..7> CCLKSEL: Divide Value for CPU Clock from PLL0
+// <2-256:2><#-1>
+// </h>
+//
+// <h> USB Clock Configuration Register (USBCLKCFG)
+// <o8.0..3> USBSEL: Divide Value for USB Clock from PLL1
+// <0-15>
+// <i> Divide is USBSEL + 1
+// </h>
+//
+// <h> Peripheral Clock Selection Register 0 (PCLKSEL0)
+// <o9.0..1> PCLK_WDT: Peripheral Clock Selection for WDT
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.2..3> PCLK_TIMER0: Peripheral Clock Selection for TIMER0
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.4..5> PCLK_TIMER1: Peripheral Clock Selection for TIMER1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.6..7> PCLK_UART0: Peripheral Clock Selection for UART0
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.8..9> PCLK_UART1: Peripheral Clock Selection for UART1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.12..13> PCLK_PWM1: Peripheral Clock Selection for PWM1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.14..15> PCLK_I2C0: Peripheral Clock Selection for I2C0
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.16..17> PCLK_SPI: Peripheral Clock Selection for SPI
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.20..21> PCLK_SSP1: Peripheral Clock Selection for SSP1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.22..23> PCLK_DAC: Peripheral Clock Selection for DAC
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.24..25> PCLK_ADC: Peripheral Clock Selection for ADC
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o9.26..27> PCLK_CAN1: Peripheral Clock Selection for CAN1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 6
+// <o9.28..29> PCLK_CAN2: Peripheral Clock Selection for CAN2
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 6
+// <o9.30..31> PCLK_ACF: Peripheral Clock Selection for ACF
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 6
+// </h>
+//
+// <h> Peripheral Clock Selection Register 1 (PCLKSEL1)
+// <o10.0..1> PCLK_QEI: Peripheral Clock Selection for the Quadrature Encoder Interface
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.2..3> PCLK_GPIO: Peripheral Clock Selection for GPIOs
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.4..5> PCLK_PCB: Peripheral Clock Selection for the Pin Connect Block
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.6..7> PCLK_I2C1: Peripheral Clock Selection for I2C1
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.10..11> PCLK_SSP0: Peripheral Clock Selection for SSP0
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.12..13> PCLK_TIMER2: Peripheral Clock Selection for TIMER2
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.14..15> PCLK_TIMER3: Peripheral Clock Selection for TIMER3
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.16..17> PCLK_UART2: Peripheral Clock Selection for UART2
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.18..19> PCLK_UART3: Peripheral Clock Selection for UART3
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.20..21> PCLK_I2C2: Peripheral Clock Selection for I2C2
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.22..23> PCLK_I2S: Peripheral Clock Selection for I2S
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.26..27> PCLK_RIT: Peripheral Clock Selection for the Repetitive Interrupt Timer
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.28..29> PCLK_SYSCON: Peripheral Clock Selection for the System Control Block
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// <o10.30..31> PCLK_MC: Peripheral Clock Selection for the Motor Control PWM
+// <0=> Pclk = Cclk / 4
+// <1=> Pclk = Cclk
+// <2=> Pclk = Cclk / 2
+// <3=> Pclk = Hclk / 8
+// </h>
+//
+// <h> Power Control for Peripherals Register (PCONP)
+// <o11.1> PCTIM0: Timer/Counter 0 power/clock enable
+// <o11.2> PCTIM1: Timer/Counter 1 power/clock enable
+// <o11.3> PCUART0: UART 0 power/clock enable
+// <o11.4> PCUART1: UART 1 power/clock enable
+// <o11.6> PCPWM1: PWM 1 power/clock enable
+// <o11.7> PCI2C0: I2C interface 0 power/clock enable
+// <o11.8> PCSPI: SPI interface power/clock enable
+// <o11.9> PCRTC: RTC power/clock enable
+// <o11.10> PCSSP1: SSP interface 1 power/clock enable
+// <o11.12> PCAD: A/D converter power/clock enable
+// <o11.13> PCCAN1: CAN controller 1 power/clock enable
+// <o11.14> PCCAN2: CAN controller 2 power/clock enable
+// <o11.15> PCGPIO: GPIOs power/clock enable
+// <o11.16> PCRIT: Repetitive interrupt timer power/clock enable
+// <o11.17> PCMC: Motor control PWM power/clock enable
+// <o11.18> PCQEI: Quadrature encoder interface power/clock enable
+// <o11.19> PCI2C1: I2C interface 1 power/clock enable
+// <o11.21> PCSSP0: SSP interface 0 power/clock enable
+// <o11.22> PCTIM2: Timer 2 power/clock enable
+// <o11.23> PCTIM3: Timer 3 power/clock enable
+// <o11.24> PCUART2: UART 2 power/clock enable
+// <o11.25> PCUART3: UART 3 power/clock enable
+// <o11.26> PCI2C2: I2C interface 2 power/clock enable
+// <o11.27> PCI2S: I2S interface power/clock enable
+// <o11.29> PCGPDMA: GP DMA function power/clock enable
+// <o11.30> PCENET: Ethernet block power/clock enable
+// <o11.31> PCUSB: USB interface power/clock enable
+// </h>
+// </e>
+*/
+
+#define CLOCK_SETUP 1
+
+#define SCS_Val 0x00000020 /* OSCEN */
+#define CLKSRCSEL_Val 0x00000001 /* XTAL */
+
+#define PLL0_SETUP 1
+#define PLL0CFG_Val 0x0000000B /* 324403200Hz - must be in the range 275HMz-550MHz */
+
+#define PLL1_SETUP 0
+#define PLL1CFG_Val 0x00000023
+
+#define CCLKCFG_Val 0x00000003 /* pplclk/(CCLKCFG_Val+1)=81100800Hz */
+#define USBCLKCFG_Val 0x00000000
+
+//#define PCLKSEL0_Val 0x00000000 /* all peripherial sysclk/4 */
+//#define PCLKSEL1_Val 0x00000000
+//#define PCONP_Val 0x042887DE
+
+#define PCONP_CLK_DIV(x) ((x)==0?4:((x)==1?1:((x)==2?2:8)))
+
+/*--------------------- Flash Accelerator Configuration ----------------------
+//
+// <e> Flash Accelerator Configuration
+// <o1.0..1> FETCHCFG: Fetch Configuration
+// <0=> Instruction fetches from flash are not buffered
+// <1=> One buffer is used for all instruction fetch buffering
+// <2=> All buffers may be used for instruction fetch buffering
+// <3=> Reserved (do not use this setting)
+// <o1.2..3> DATACFG: Data Configuration
+// <0=> Data accesses from flash are not buffered
+// <1=> One buffer is used for all data access buffering
+// <2=> All buffers may be used for data access buffering
+// <3=> Reserved (do not use this setting)
+// <o1.4> ACCEL: Acceleration Enable
+// <o1.5> PREFEN: Prefetch Enable
+// <o1.6> PREFOVR: Prefetch Override
+// <o1.12..15> FLASHTIM: Flash Access Time
+// <0=> 1 CPU clock (for CPU clock up to 20 MHz)
+// <1=> 2 CPU clocks (for CPU clock up to 40 MHz)
+// <2=> 3 CPU clocks (for CPU clock up to 60 MHz)
+// <3=> 4 CPU clocks (for CPU clock up to 80 MHz)
+// <4=> 5 CPU clocks (for CPU clock up to 100 MHz)
+// <5=> 6 CPU clocks (for any CPU clock)
+// </e>
+*/
+#define FLASH_SETUP 1
+#define FLASHCFG_Val 0x0000403A
+
+/*----------------------------------------------------------------------------
+ Define clocks
+ *----------------------------------------------------------------------------*/
+#define XTAL (14745600UL) /* Oscillator frequency */
+#define OSC_CLK ( XTAL) /* Main oscillator frequency */
+#define RTC_CLK ( 32000UL) /* RTC oscillator frequency */
+#define IRC_OSC ( 4000000UL) /* Internal RC oscillator frequency */
+
+
+
+
+#define SYS_TIMER_HZ 1000
+
+#ifndef BIT
+#define BIT(n) (1 << (n))
+#endif
+
+// Port Bit Definitions & Macros: Description - initial conditions
+#define P0_0_UNUSED_BIT BIT(0) // P0.0 unused - low output
+#define P0_1_UNUSED_BIT BIT(1) // P0.1 unused - low output
+#define TXD0_BIT BIT(2) // used by UART0
+#define RXD0_BIT BIT(3) // used by UART0
+#define OVER_LOAD_BIT BIT(6) // OVER_LOAD
+#define P0_7_UNUSED_BIT BIT(7) // P0.7 unused - low output
+#define P0_8_UNUSED_BIT BIT(8) // P0.8 unused - low output
+#define P0_9_UNUSED_BIT BIT(9) // P0.9 unused - low output
+#define P0_10_UNUSED_BIT BIT(10) // P0.10 unused - low output
+#define P0_11_UNUSED_BIT BIT(11) // P0.11 unused - low output
+#define IN2_BIT BIT(15) // P0.15 input 2
+#define IN1_BIT BIT(16) // P0.16 input 1
+#define IN3_BIT BIT(17) // P0.17 input 3
+#define IN4_BIT BIT(18) // P0.18 input 4
+#define RTS1_BIT BIT(22) // P0.22 uDIR
+#define EXT_TEMP_SENS_BIT BIT(25) // P0.25
+#define EXT_TEMP_TYPE_BIT BIT(26) // P0.26
+#define USBDPLUS_BIT BIT(29) // P0.29 USBD+
+#define USBDMINUS_BIT BIT(30) // P0.30 USBD-
+
+
+// Port Bit Definitions & Macros: Description - initial conditions
+#define P1_0_UNUSED_BIT BIT(0) // P1.0 unused - low output
+#define P1_1_UNUSED_BIT BIT(1) // P1.1 unused - low output
+#define P1_4_UNUSED_BIT BIT(4) // P1.4 unused - low output
+#define P1_8_UNUSED_BIT BIT(8) // P1.8 unused - low output
+#define P1_9_UNUSED_BIT BIT(9) // P1.9 unused - low output
+#define P1_10_UNUSED_BIT BIT(10) // P1.10 unused - low output
+#define P1_14_UNUSED_BIT BIT(14) // P1.14 unused - low output
+#define P1_15_UNUSED_BIT BIT(15) // P1.15 unused - low output
+#define P1_18_UNUSED_BIT BIT(18) // P1.18 unused - low output
+#define P1_19_UNUSED_BIT BIT(19) // P1.19 unused - low output
+#define P1_20_UNUSED_BIT BIT(20) // P1.20 unused - low output
+#define P1_22_UNUSED_BIT BIT(22) // P1.22 unused - low output
+#define OUT1_BIT BIT(23) // Output 1
+#define OUT2_BIT BIT(24) // Output 2
+#define P1_25_UNUSED_BIT BIT(25) // P1.25 unused - low output
+#define P1_26_UNUSED_BIT BIT(26) // P1.26 unused - low output
+#define P1_28_UNUSED_BIT BIT(28) // P1.28 unused - low output
+#define P1_29_UNUSED_BIT BIT(29) // P1.29 unused - low output
+#define EXT_TEMP_SW_BIT BIT(30) // P1.30
+#define P1_31_UNUSED_BIT BIT(31) // P1.31 unused - low output
+
+// Port Bit Definitions & Macros: Description - initial conditions
+#define TXD1_BIT BIT(0) // P2.0 TXD
+#define RXD1_BIT BIT(1) // P2.1 RXD
+#define P2_2_UNUSED_BIT BIT(2) // P2.2 unused - low output
+#define P2_3_UNUSED_BIT BIT(3) // P2.3 unused - low output
+#define DSR1_BIT BIT(4) // P2.4 DSR
+#define LED1_BIT BIT(5) // P2.5 LED1
+#define LED2_BIT BIT(6) // P2.6 LED2
+#define LED3_BIT BIT(7) // P2.7 LED3
+#define LED4_BIT BIT(8) // P2.8 LED4
+#define P2_9_UNUSED_BIT BIT(9) // P2.9 unused - low output
+#define BOOT_BIT BIT(10) // P2.10 Boot input
+
+#define P4_28_UNUSED_BIT BIT(28) // P4.28 unused - low output
+#define P4_29_UNUSED_BIT BIT(29) // P4.29 unused - low output
+
+#define P0IO_INPUT_BITS (uint32_t) ( \
+ RXD0_BIT | \
+ OVER_LOAD_BIT | \
+ IN2_BIT | \
+ IN1_BIT | \
+ IN3_BIT | \
+ IN4_BIT | \
+ EXT_TEMP_SENS_BIT | \
+ USBDPLUS_BIT | \
+ USBDMINUS_BIT | \
+ 0 )
+
+#define P1IO_INPUT_BITS (uint32_t) ( \
+ 0 )
+
+#define P2IO_INPUT_BITS (uint32_t) ( \
+ RXD1_BIT | \
+ DSR1_BIT | \
+ BOOT_BIT | \
+ 0 )
+
+#define P3IO_INPUT_BITS (uint32_t) ( \
+ 0 )
+
+#define P4IO_INPUT_BITS (uint32_t) ( \
+ 0 )
+
+#define P0IO_ZERO_BITS (uint32_t) ( \
+ P0_0_UNUSED_BIT | \
+ P0_1_UNUSED_BIT | \
+ P0_7_UNUSED_BIT | \
+ P0_8_UNUSED_BIT | \
+ P0_9_UNUSED_BIT | \
+ P0_10_UNUSED_BIT | \
+ P0_11_UNUSED_BIT | \
+ RTS1_BIT | \
+ 0 )
+
+#define P1IO_ZERO_BITS (uint32_t) ( \
+ P1_0_UNUSED_BIT | \
+ P1_1_UNUSED_BIT | \
+ P1_4_UNUSED_BIT | \
+ P1_8_UNUSED_BIT | \
+ P1_9_UNUSED_BIT | \
+ P1_10_UNUSED_BIT | \
+ P1_14_UNUSED_BIT | \
+ P1_15_UNUSED_BIT | \
+ P1_18_UNUSED_BIT | \
+ P1_19_UNUSED_BIT | \
+ P1_20_UNUSED_BIT | \
+ P1_22_UNUSED_BIT | \
+ P1_25_UNUSED_BIT | \
+ P1_26_UNUSED_BIT | \
+ P1_28_UNUSED_BIT | \
+ P1_29_UNUSED_BIT | \
+ P1_31_UNUSED_BIT | \
+ 0 )
+
+#define P2IO_ZERO_BITS (uint32_t) ( \
+ P2_2_UNUSED_BIT | \
+ P2_3_UNUSED_BIT | \
+ P2_9_UNUSED_BIT | \
+ 0 )
+
+#define P3IO_ZERO_BITS (uint32_t) ( \
+ 0 )
+
+#define P4IO_ZERO_BITS (uint32_t) ( \
+ P4_28_UNUSED_BIT | \
+ P4_29_UNUSED_BIT | \
+ 0 )
+
+#define P0IO_ONE_BITS (uint32_t) ( \
+ TXD0_BIT | \
+ EXT_TEMP_TYPE_BIT | \
+ 0 )
+
+#define P1IO_ONE_BITS (uint32_t) ( \
+ OUT1_BIT | \
+ OUT2_BIT | \
+ EXT_TEMP_SW_BIT | \
+ 0 )
+
+#define P2IO_ONE_BITS (uint32_t) ( \
+ TXD1_BIT | \
+ LED1_BIT | \
+ LED2_BIT | \
+ LED3_BIT | \
+ LED4_BIT | \
+ 0 )
+
+#define P3IO_ONE_BITS (uint32_t) ( \
+ 0 )
+
+#define P4IO_ONE_BITS (uint32_t) ( \
+ 0 )
+
+#define P0IO_OUTPUT_BITS (uint32_t) ( \
+ P0IO_ZERO_BITS | \
+ P0IO_ONE_BITS )
+
+#define P1IO_OUTPUT_BITS (uint32_t) ( \
+ P1IO_ZERO_BITS | \
+ P1IO_ONE_BITS )
+
+#define P2IO_OUTPUT_BITS (uint32_t) ( \
+ P2IO_ZERO_BITS | \
+ P2IO_ONE_BITS )
+
+#define P3IO_OUTPUT_BITS (uint32_t) ( \
+ P3IO_ZERO_BITS | \
+ P3IO_ONE_BITS )
+
+#define P4IO_OUTPUT_BITS (uint32_t) ( \
+ P4IO_ZERO_BITS | \
+ P4IO_ONE_BITS )
+
+
+
+/***************************************************************************/
+/* io functions */
+#define LED_GP LED2_BIT /* GENREAL PURPOSE LED */
+#define LED_ERR LED3_BIT
+
+/***************************************************************************/
+/* io functions */
+#define IN_PORT GPIO0->FIO
+#define OUT_PORT GPIO1->FIO
+#define LED_PORT GPIO2->FIO
+
+#define CREATE_PORT_NAME_PIN(port) port##PIN
+#define CREATE_PORT_NAME_CLR(port) port##CLR
+#define CREATE_PORT_NAME_SET(port) port##SET
+
+#define GET_IN_PIN(port,in) ((CREATE_PORT_NAME_PIN(port) & in)?1:0)
+#define GET_IN_PORT(port) (CREATE_PORT_NAME_PIN(port))
+#define SET_OUT_PIN(port,out) (CREATE_PORT_NAME_SET(port)=out)
+#define CLR_OUT_PIN(port,out) (CREATE_PORT_NAME_CLR(port)=out)
+
+/***************************************************************************/
+/* watchdog */
+#define WATCHDOG_ENABLED
+#define WATCHDOG_TIMEOUT_MS 1000
+
+/***************************************************************************/
+/* uLan configuration */
+
+#ifdef UL_LOG_ENABLE
+ #undef UL_LOG_ENABLE
+#endif
+
+#ifdef ULD_DEFAULT_BUFFER_SIZE
+ #undef ULD_DEFAULT_BUFFER_SIZE
+ #define ULD_DEFAULT_BUFFER_SIZE 0x0800
+#endif
+
+#define UL_DRV_SYSLESS_PORT UART1_BASE
+#define UL_DRV_SYSLESS_BAUD 19200
+#define UL_DRV_SYSLESS_IRQ UART1_IRQn
+#define UL_DRV_SYSLESS_MY_ADR_DEFAULT 1
+
+#define watchdog_feed lpc_watchdog_feed
+#define kvpb_erase lpcisp_kvpb_erase
+#define kvpb_copy lpcisp_kvpb_copy
+#define kvpb_flush lpcisp_kvpb_flush
+#define KVPB_DEFAULT_FLAGS KVPB_DESC_DOUBLE|KVPB_DESC_CHUNKWO
+
+
+
+
+
+
+
+
+#endif /* _SYSTEM_DEF_H_ */
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+SUBDIRS = bspbase ldscripts
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+default_CONFIG += CONFIG_OC_UL_DRV_SYSLESS=x
+default_CONFIG += CONFIG_KEYVAL=x
+default_CONFIG += CONFIG_STDIO_COM_PORT=x
+default_CONFIG += CONFIG_OC_UL_DRV_U450_VARPINS=x
+default_CONFIG += CONFIG_OC_UL_DRV_U450_VARPINS_MSRSWAP=x
+default_CONFIG += CONFIG_OC_UL_DRV_U450_VARPINS_DIRNEG=x
+default_CONFIG += CONFIG_OC_I2C_DRV_SYSLESS=x
+
+LOCAL_CONFIG_H = local_config.h
+
+INCLUDES += -I .
+
+include_HEADERS = bspbase.h
+
+lib_LIBRARIES = bspbase
+
+bspbase_SOURCES = bsp0hwinit.c
+
+ifneq ($(CONFIG_STDIO_COM_PORT),)
+bspbase_SOURCES += uart.c
+endif #CONFIG_STDIO_COM_PORT
--- /dev/null
+#include "local_config.h"
+#include <system_def.h>
+#include <cpu_def.h>
+#include <lt_timer_types.h>
+#include <hal_machperiph.h>
+#ifdef CONFIG_KEYVAL
+ #include <keyvalpb.h>
+ #include <lpciap.h>
+ #include <lpciap_kvpb.h>
+#endif /* CONFIG_KEYVAL */
+#ifdef CONFIG_STDIO_COM_PORT
+ #include <uart.h>
+#endif
+#ifdef CONFIG_OC_UL_DRV_SYSLESS
+ #include <ul_lib/ulan.h>
+ #include <string.h>
+ #include <ul_drv_init.h>
+ #include <ul_drv_iac.h>
+ #include <ul_lib/ul_drvdef.h>
+ extern long int uld_jiffies;
+#endif /* CONFIG_OC_UL_DRV_SYSLESS */
+#ifdef CONFIG_OC_I2C_DRV_SYSLESS
+ #include <i2c_drv.h>
+#endif /* CONFIG_OC_I2C_DRV_SYSLESS */
+
+
+/* timers */
+volatile lt_ticks_t sys_timer_ticks;
+void (*timer0_isr_appl_call)(void);
+
+#ifdef CONFIG_OC_I2C_DRV_SYSLESS
+#define I2C_DRV_NA_MSTIMEOUT 10
+i2c_drv_t i2c_drv;
+int i2c_drv_na_timer=0;
+#endif /* CONFIG_OC_I2C_DRV_SYSLESS */
+
+static void sysInit(void)
+{
+
+ //lpc_pll_off();
+ //lpc_pll_on();
+ system_clock_init();
+
+ // setup the parallel port pin
+ GPIO0->FIOCLR = P0IO_ZERO_BITS; // clear the ZEROs output
+ GPIO0->FIOSET = P0IO_ONE_BITS; // set the ONEs output
+ GPIO0->FIODIR = P0IO_OUTPUT_BITS; // set the output bit direction
+
+ GPIO1->FIOCLR = P1IO_ZERO_BITS; // clear the ZEROs output
+ GPIO1->FIOSET = P1IO_ONE_BITS; // set the ONEs output
+ GPIO1->FIODIR = P1IO_OUTPUT_BITS; // set the output bit direction
+
+ GPIO2->FIOCLR = P2IO_ZERO_BITS; // clear the ZEROs output
+ GPIO2->FIOSET = P2IO_ONE_BITS; // set the ONEs output
+ GPIO2->FIODIR = P2IO_OUTPUT_BITS; // set the output bit direction
+
+ GPIO3->FIOCLR = P3IO_ZERO_BITS; // clear the ZEROs output
+ GPIO3->FIOSET = P3IO_ONE_BITS; // set the ONEs output
+ GPIO3->FIODIR = P3IO_OUTPUT_BITS; // set the output bit direction
+
+ GPIO4->FIOCLR = P4IO_ZERO_BITS; // clear the ZEROs output
+ GPIO4->FIOSET = P4IO_ONE_BITS; // set the ONEs output
+ GPIO4->FIODIR = P4IO_OUTPUT_BITS; // set the output bit direction
+}
+
+IRQ_HANDLER_FNC(timer0_isr)
+{
+ unsigned int ir;
+
+ ir=TIM0->IR;
+ if (ir&0x01) {
+ do {
+ if(timer0_isr_appl_call!=NULL)
+ timer0_isr_appl_call();
+ TIM0->MR0 += PCLK / SYS_TIMER_HZ;
+ TIM0->IR=0x01; // Clear match0 interrupt
+ #ifdef CONFIG_OC_UL_DRV_SYSLESS
+ uld_jiffies++;
+ #endif
+ #ifdef CONFIG_OC_I2C_DRV_SYSLESS
+ if (i2c_drv.flags&I2C_DRV_MS_INPR) {
+ if (i2c_drv.flags&I2C_DRV_NA) {
+ i2c_drv_na_timer++;
+ if (i2c_drv_na_timer>I2C_DRV_NA_MSTIMEOUT) {
+ if (i2c_drv.stroke_fnc)
+ i2c_drv.stroke_fnc(&i2c_drv);
+ i2c_drv_na_timer=0;
+ }
+ } else {
+ i2c_drv_na_timer=0;
+ }
+ i2c_drv.flags|=I2C_DRV_NA;
+ }
+ #endif
+ sys_timer_ticks++;
+ } while (((int32_t)(TIM0->MR0-TIM0->TC))<0);
+ }
+ return IRQ_HANDLED;
+}
+
+void timerInit(void)
+{
+ sys_timer_ticks=0;
+
+ request_irq(TIMER0_IRQn, timer0_isr, 0, NULL,NULL);
+ enable_irq(TIMER0_IRQn);
+
+ TIM0->TC=0;
+ TIM0->MCR=0;
+
+ TIM0->MR0= PCLK / SYS_TIMER_HZ;
+ TIM0->MCR|=1; /* TMCR_MR0_I; */
+
+ TIM0->TCR = 1; /* Run timer 0*/
+}
+
+#ifdef CONFIG_STDIO_COM_PORT
+
+int uartcon_write(int file, const char * ptr, int len)
+{
+ int cnt;
+ unsigned char ch;
+ for(cnt=0;cnt<len;cnt++,ptr++){
+ ch=*ptr;
+ if(ch==0xa)
+ uart0Putch(0xd);
+ uart0Putch(ch);
+ }
+ return cnt;
+}
+
+void init_system_stub(void) {
+ system_stub_ops.write=uartcon_write;
+}
+
+#endif /* CONFIG_STDIO_COM_PORT */
+
+#ifdef CONFIG_OC_UL_DRV_SYSLESS
+
+extern unsigned uld_debug_flg; /* Left application set defaults */
+
+#ifndef CONFIG_KEYVAL
+unsigned long lpciap_buff[ISP_RAM2FLASH_BLOCK_SIZE/4];
+#endif /* CONFIG_KEYVAL */
+
+#define UL_MTYPE_START32BIT 0x100
+
+static inline int ul_iac_mem_head_rd(uint8_t *buf, int len,
+ uint32_t* pmtype, uint32_t* pstart, uint32_t* plen)
+{
+ uint32_t val, mtype;
+ if (len<6) return -1;
+ mtype=*(buf++); /* memory type */
+ mtype+=*(buf++)<<8;
+ val=*(buf++); /* start address */
+ val+=*(buf++)<<8;
+ if(mtype&UL_MTYPE_START32BIT){
+ if (len<8) return -1;
+ val+=(uint32_t)*(buf++)<<16;
+ val+=(uint32_t)*(buf++)<<24;
+ }
+ *pstart=val;
+ val=*(buf++); /* length */
+ val+=*(buf++)<<8;
+ if(mtype&UL_MTYPE_START32BIT){
+ if (len==10) {
+ val+=(uint32_t)*(buf++)<<16;
+ val+=(uint32_t)*(buf++)<<24;
+ }
+ }
+ *plen=val;
+ mtype&=~UL_MTYPE_START32BIT; /* 32-bit start address */
+ *pmtype=mtype;
+ return 0;
+}
+
+int ul_iac_call_rdm(struct ul_drv *udrv,ul_msginfo *msginfo,char *ibuff,ul_iac_data *data)
+{
+ uint32_t mtype,start,len;
+
+ data->len=0;
+
+ if(ul_iac_mem_head_rd((uint8_t *)ibuff, msginfo->len,&mtype,&start,&len))
+ return UL_IAC_RC_PROC;
+
+ if (mtype==0x00) {
+ data->len=len;
+ data->buff=(char*)start;
+ return UL_IAC_RC_FREEMSG;
+ }
+ return UL_IAC_RC_PROC;
+}
+
+int ul_iac_call_erm(struct ul_drv *udrv,ul_msginfo *msginfo,char *ibuff,ul_iac_data *data)
+{
+ uint32_t mtype,start,len;
+
+ data->len=0;
+
+ if(ul_iac_mem_head_rd((uint8_t *)ibuff, msginfo->len,&mtype,&start,&len))
+ return UL_IAC_RC_PROC;
+
+ #ifdef CONFIG_KEYVAL
+ if (mtype==0x01) {
+ lpcisp_erase((void*)start,len);
+ data->len=0;
+ return UL_IAC_RC_FREEMSG;
+ }
+ #endif /* CONFIG_KEYVAL */
+ return UL_IAC_RC_PROC;
+}
+
+int ul_iac_call_wrm(struct ul_drv *udrv,ul_msginfo *msginfo,char *ibuff,ul_iac_data *data)
+{
+ uint32_t mtype,start,len;
+
+ data->len=0;
+
+ if(ul_iac_mem_head_rd((uint8_t *)ibuff, msginfo->len,&mtype,&start,&len))
+ return UL_IAC_RC_PROC;
+
+ if (mtype==0x00) {
+ memcpy((void*)start,data->buff,data->len);
+ return UL_IAC_RC_FREEMSG;
+ }
+ #ifdef CONFIG_KEYVAL
+ if (mtype==0x01) {
+ lpcisp_write((char*)start, data->buff, ISP_RAM2FLASH_BLOCK_SIZE);
+ return UL_IAC_RC_FREEMSG;
+ }
+ #endif /* CONFIG_KEYVAL */
+ return UL_IAC_RC_PROC;
+}
+
+
+int ul_iac_call_deb(struct ul_drv *udrv,ul_msginfo *msginfo,char *ibuff,ul_iac_data *data)
+{
+ uint32_t debcmd,mtype,start;
+ uint8_t *p=(uint8_t*)ibuff;
+
+ if (msginfo->len<1) return UL_IAC_RC_PROC;
+ debcmd=*(p++);
+ switch (debcmd) {
+ case 0x10: /* goto */
+ data->len=0;
+ if (msginfo->len<5) return UL_IAC_RC_PROC;
+ mtype=*(p++);
+ mtype+=*(p++)<<8;
+ start=*(p++);
+ start+=*(p++)<<8;
+ if(mtype&UL_MTYPE_START32BIT){
+ mtype&=~UL_MTYPE_START32BIT;
+ if (msginfo->len<7) return UL_IAC_RC_PROC;
+ start+=(uint32_t)*(p++)<<16;
+ start+=(uint32_t)*(p++)<<24;
+ }
+ if (mtype==0x00)
+ ((void (*)())start)();
+ default:break;
+ }
+ return UL_IAC_RC_PROC;
+}
+
+int ul_iac_call_res(struct ul_drv *udrv,ul_msginfo *msginfo,char *ibuff,ul_iac_data *data)
+{
+ uint32_t rescmd,pass;
+ uint8_t *p=(uint8_t*)ibuff;
+
+ if (msginfo->len<1) return UL_IAC_RC_PROC;
+ rescmd=*(p++);
+ switch (rescmd) {
+ case ULRES_CPU: /* CPU */
+ data->len=0;
+ if (msginfo->len<3) return UL_IAC_RC_PROC;
+ pass=*(p++);
+ pass+=*(p++)<<8;
+ if (pass==0xaa55) {
+// MEMMAP=MEMMAP_FLASH;
+ lpc_watchdog_init(1,10); /* 10ms */
+ lpc_watchdog_feed();
+ while(1);
+ }
+ default:break;
+ }
+ return UL_IAC_RC_PROC;
+}
+
+int uLanInit()
+{
+ struct ul_drv *udrv;
+ unsigned int pinsel1_mask = 0;
+ unsigned int pinsel1_set = 0;
+ unsigned int pinsel4_mask = 0;
+ unsigned int pinsel4_set = 0;
+
+ /* set rs485 mode for UART1 */
+ #if TXD1_BIT == BIT(15)
+ PINCON->PINSEL0 = (PINCON->PINSEL0 & ~0xC0000000) | 0x40000000; /* rxd on P0.15 */
+ #elif TXD1_BIT == BIT(0)
+ pinsel4_mask |= 3 << (0*2);
+ pinsel4_set |= 2 << (0*2);
+ #else
+ #error TXD1_BIT is not set or valid
+ #endif
+
+ #if RXD1_BIT == BIT(16)
+ pinsel1_mask |= 3 << ((16-16)*2);
+ pinsel1_set |= 1 << ((16-16)*2);
+ #elif RXD1_BIT == BIT(1)
+ pinsel4_mask |= 3 << (1*2);
+ pinsel4_set |= 2 << (1*2);
+ #else
+ #error RXD1_BIT is not set or valid
+ #endif
+
+ #ifdef CTS1_BIT
+ #if CTS1_BIT == BIT(17)
+ pinsel1_mask |= 3 << ((17-16)*2);
+ pinsel1_set |= 1 << ((17-16)*2);
+ #elif CTS1_BIT == BIT(2)
+ pinsel4_mask |= 3 << (2*2);
+ pinsel4_set |= 2 << (2*2);
+ #else
+ #error CTS1_BIT is not valid
+ #endif
+ #endif
+
+ #ifdef DSR1_BIT
+ #if DSR1_BIT == BIT(19)
+ pinsel1_mask |= 3 << ((19-16)*2);
+ pinsel1_set |= 1 << ((19-16)*2);
+ #elif DSR1_BIT == BIT(4)
+ pinsel4_mask |= 3 << (4*2);
+ pinsel4_set |= 2 << (4*2);
+ #else
+ #error CTS1_BIT is not valid
+ #endif
+ #endif
+
+ #if RTS1_BIT == BIT(22)
+ pinsel1_mask |= 3 << ((22-16)*2);
+ pinsel1_set |= 1 << ((22-16)*2);
+ #elif RTS1_BIT == BIT(7)
+ pinsel4_mask |= 3 << (7*2);
+ pinsel4_set |= 2 << (7*2);
+ #else
+ #error RTS1_BIT is not set or valid
+ #endif
+
+ /* port 0 .. 0x00003000; 0x00001000; rts(uDIR) */
+ PINCON->PINSEL1 = (PINCON->PINSEL1 & ~pinsel1_mask) | pinsel1_set;
+ /* port 2 .. 0x00000C0F; 0x0000080A; dsr(rxd), rxd, txd */
+ PINCON->PINSEL4 = (PINCON->PINSEL4 & ~pinsel4_mask) | pinsel4_set;
+
+ udrv=ul_drv_new(UL_DRV_SYSLESS_PORT, /* port */
+ UL_DRV_SYSLESS_IRQ, /* irq */
+ UL_DRV_SYSLESS_BAUD, /* baud */
+ UL_DRV_SYSLESS_MY_ADR_DEFAULT, /* my adr */
+ #ifdef CONFIG_OC_UL_DRV_U450_VARPINS
+ #if defined(CONFIG_OC_UL_DRV_U450_VARPINS_DIRNEG) && defined(CONFIG_OC_UL_DRV_U450_VARPINS_MSRSWAP)
+ "16450-dirneg-msrswap", /* chip name */
+ #elif defined(CONFIG_OC_UL_DRV_U450_VARPINS_MSRSWAP)
+ "16450-msrswap", /* chip name */
+ #elif defined(CONFIG_OC_UL_DRV_U450_VARPINS_DIRNEG)
+ "16450-dirneg", /* chip name */
+ #else
+ "16450", /* chip name */
+ #endif
+ #else /*CONFIG_OC_UL_DRV_U450_VARPINS*/
+ "16450", /* chip name */
+ #endif /*CONFIG_OC_UL_DRV_U450_VARPINS*/
+ 0); /* baud base - default */
+
+ if (udrv==NULL)
+ return -1;
+
+ ul_drv_add_iac(udrv,UL_CMD_RDM,UL_IAC_OP_SND,ul_iac_call_rdm,NULL,0,0,NULL,0);
+ ul_drv_add_iac(udrv,UL_CMD_ERM,UL_IAC_OP_CALLBACK,ul_iac_call_erm,NULL,0,UL_IAC_BFL_CB_OFFLT,NULL,0);
+ ul_drv_add_iac(udrv,UL_CMD_WRM,UL_IAC_OP_REC,ul_iac_call_wrm,(char*)lpciap_buff,0,UL_IAC_BFL_CB_OFFLT,NULL,0);
+ ul_drv_add_iac(udrv,UL_CMD_DEB,UL_IAC_OP_CALLBACK,ul_iac_call_deb,NULL,0,UL_IAC_BFL_CB_OFFLT,NULL,0);
+ ul_drv_add_iac(udrv,UL_CMD_RES,UL_IAC_OP_CALLBACK,ul_iac_call_res,NULL,0,UL_IAC_BFL_CB_OFFLT,NULL,0);
+
+ return ul_drv_add_dev(udrv);
+}
+#endif /* CONFIG_OC_UL_DRV_SYSLESS */
+
+#ifdef CONFIG_OC_I2C_DRV_SYSLESS
+
+int
+i2cInit(void)
+{
+ #if I2C_DRV_SYSLESS_PORT == I2C0_BASE
+ SC->PCONP |= (1 << 7); /*PI2C0*/
+ /* SDA0 P0.27, SCL0 P0.28 */
+ PINCON->PINSEL1 = (PINCON->PINSEL0 & ~0x03c00000) | 0x01400000;
+
+ #elif I2C_DRV_SYSLESS_PORT == I2C1_BASE
+ SC->PCONP |= (1 << 19); /*PI2C1*/
+ #if SCL1_BIT == BIT(1)
+ /* SDA1 P0.0, SCL1 P0.1 */
+ PINCON->PINSEL0 |= 0x0000000f;
+ PINCON->PINMODE0 = (PINCON->PINMODE0 & ~0x0000000f) | 0x0000000A;
+ PINCON->PINMODE_OD0 |= 0x00000003;
+ #elif SCL1_BIT == BIT(20)
+ /* SDA1 P0.19, SCL1 P0.20 */
+ PINCON->PINSEL1 |= 0x000003c0;
+ PINCON->PINMODE1 = (PINCON->PINMODE1 & ~0x000003c0) | 0x00000280;
+ PINCON->PINMODE_OD0 |= 0x00180000;
+ #else
+ #error Unknown SCL1_BIT pin position
+ #endif
+
+ #elif I2C_DRV_SYSLESS_PORT == I2C2_BASE
+ SC->PCONP |= (1 << 26); /*PI2C2*/
+ /* SDA2 P0.10, SCL2 P0.11 */
+ PINCON->PINSEL0 = (PINCON->PINSEL0 & ~0x00f00000) | 0x00A00000;
+ PINCON->PINMODE0 = (PINCON->PINMODE0 & ~0x00f00000) | 0x00A00000;
+ PINCON->PINMODE_OD0 |= 0x00000c00;
+ #else
+ #error unknown I2C_DRV_SYSLESS_PORT address
+ #endif
+
+ if (i2c_drv_init(&i2c_drv,
+ I2C_DRV_SYSLESS_PORT,
+ I2C_DRV_SYSLESS_IRQ,
+ I2C_DRV_SYSLESS_BITRATE,
+ I2C_DRV_SYSLESS_SLADR)<0) return -1;
+
+ return 1;
+}
+
+#endif /*CONFIG_OC_I2C_DRV_SYSLESS*/
+
+
+void _setup_board()
+{
+
+ // initialize the system
+ sysInit();
+
+ #ifdef WATCHDOG_ENABLED
+ lpc_watchdog_init(1,WATCHDOG_TIMEOUT_MS);
+ lpc_watchdog_feed();
+ #endif /* WATCHDOG_ENABLED */
+
+ #ifdef CONFIG_STDIO_COM_PORT
+ uart0Init( B57600 , UART_8N1, UART_FIFO_8);
+ init_system_stub();
+ #endif /* CONFIG_STDIO_COM_PORT */
+
+ // initialize the system timer
+ timerInit();
+
+ #ifdef CONFIG_OC_UL_DRV_SYSLESS
+// uld_debug_flg=0x3ff;
+ uLanInit();
+ #endif /* CONFIG_OC_UL_DRV_SYSLESS */
+
+ #ifdef CONFIG_OC_I2C_DRV_SYSLESS
+ i2cInit();
+ #endif /* CONFIG_OC_I2C_DRV_SYSLESS */
+
+}
--- /dev/null
+#ifndef _BSPBASE_H
+#define _BSPBASE_H
+
+#include <types.h>
+#include <lt_timer_types.h>
+
+extern volatile lt_ticks_t sys_timer_ticks;
+
+#define get_sys_timer_ticks() sys_timer_ticks
+
+#endif /* _BSPBASE_H */
--- /dev/null
+/*
+ * include/linux/serial_reg.h
+ *
+ * Copyright (C) 1992, 1994 by Theodore Ts'o.
+ *
+ * Redistribution of this file is permitted under the terms of the GNU
+ * Public License (GPL)
+ *
+ * These are the UART port assignments, expressed as offsets from the base
+ * register. These assignments should hold for any serial port based on
+ * a 8250, 16450, or 16550(A).
+ */
+
+#ifndef _LINUX_SERIAL_REG_H
+#define _LINUX_SERIAL_REG_H
+
+#define UART_RX 0 /* In: Receive buffer (DLAB=0) */
+#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */
+#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */
+#define UART_TRG 0 /* (LCR=BF) FCTR bit 7 selects Rx or Tx
+ * In: Fifo count
+ * Out: Fifo custom trigger levels
+ * XR16C85x only */
+
+#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */
+#define UART_IER 1 /* Out: Interrupt Enable Register */
+#define UART_FCTR 1 /* (LCR=BF) Feature Control Register
+ * XR16C85x only */
+
+#define UART_IIR 2 /* In: Interrupt ID Register */
+#define UART_FCR 2 /* Out: FIFO Control Register */
+#define UART_EFR 2 /* I/O: Extended Features Register */
+ /* (DLAB=1, 16C660 only) */
+
+#define UART_LCR 3 /* Out: Line Control Register */
+#define UART_MCR 4 /* Out: Modem Control Register */
+#define UART_LSR 5 /* In: Line Status Register */
+#define UART_MSR 6 /* In: Modem Status Register */
+#define UART_SCR 7 /* I/O: Scratch Register */
+#define UART_EMSR 7 /* (LCR=BF) Extended Mode Select Register
+ * FCTR bit 6 selects SCR or EMSR
+ * XR16c85x only */
+
+/*
+ * These are the definitions for the FIFO Control Register
+ * (16650 only)
+ */
+#define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */
+#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */
+#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */
+#define UART_FCR_DMA_SELECT 0x08 /* For DMA applications */
+#define UART_FCR_TRIGGER_MASK 0xC0 /* Mask for the FIFO trigger range */
+#define UART_FCR_TRIGGER_1 0x00 /* Mask for trigger set at 1 */
+#define UART_FCR_TRIGGER_4 0x40 /* Mask for trigger set at 4 */
+#define UART_FCR_TRIGGER_8 0x80 /* Mask for trigger set at 8 */
+#define UART_FCR_TRIGGER_14 0xC0 /* Mask for trigger set at 14 */
+/* 16650 redefinitions */
+#define UART_FCR6_R_TRIGGER_8 0x00 /* Mask for receive trigger set at 1 */
+#define UART_FCR6_R_TRIGGER_16 0x40 /* Mask for receive trigger set at 4 */
+#define UART_FCR6_R_TRIGGER_24 0x80 /* Mask for receive trigger set at 8 */
+#define UART_FCR6_R_TRIGGER_28 0xC0 /* Mask for receive trigger set at 14 */
+#define UART_FCR6_T_TRIGGER_16 0x00 /* Mask for transmit trigger set at 16 */
+#define UART_FCR6_T_TRIGGER_8 0x10 /* Mask for transmit trigger set at 8 */
+#define UART_FCR6_T_TRIGGER_24 0x20 /* Mask for transmit trigger set at 24 */
+#define UART_FCR6_T_TRIGGER_30 0x30 /* Mask for transmit trigger set at 30 */
+/* TI 16750 definitions */
+#define UART_FCR7_64BYTE 0x20 /* Go into 64 byte mode */
+
+/*
+ * These are the definitions for the Line Control Register
+ *
+ * Note: if the word length is 5 bits (UART_LCR_WLEN5), then setting
+ * UART_LCR_STOP will select 1.5 stop bits, not 2 stop bits.
+ */
+#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
+#define UART_LCR_SBC 0x40 /* Set break control */
+#define UART_LCR_SPAR 0x20 /* Stick parity (?) */
+#define UART_LCR_EPAR 0x10 /* Even parity select */
+#define UART_LCR_PARITY 0x08 /* Parity Enable */
+#define UART_LCR_STOP 0x04 /* Stop bits: 0=1 stop bit, 1= 2 stop bits */
+#define UART_LCR_WLEN5 0x00 /* Wordlength: 5 bits */
+#define UART_LCR_WLEN6 0x01 /* Wordlength: 6 bits */
+#define UART_LCR_WLEN7 0x02 /* Wordlength: 7 bits */
+#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */
+
+/*
+ * These are the definitions for the Line Status Register
+ */
+#define UART_LSR_TEMT 0x40 /* Transmitter empty */
+#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
+#define UART_LSR_BI 0x10 /* Break interrupt indicator */
+#define UART_LSR_FE 0x08 /* Frame error indicator */
+#define UART_LSR_PE 0x04 /* Parity error indicator */
+#define UART_LSR_OE 0x02 /* Overrun error indicator */
+#define UART_LSR_DR 0x01 /* Receiver data ready */
+
+/*
+ * These are the definitions for the Interrupt Identification Register
+ */
+#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
+#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
+
+#define UART_IIR_MSI 0x00 /* Modem status interrupt */
+#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
+#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
+#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
+
+/*
+ * These are the definitions for the Interrupt Enable Register
+ */
+#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
+#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
+#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
+#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
+/*
+ * Sleep mode for ST16650 and TI16750.
+ * Note that for 16650, EFR-bit 4 must be selected as well.
+ */
+#define UART_IERX_SLEEP 0x10 /* Enable sleep mode */
+
+/*
+ * These are the definitions for the Modem Control Register
+ */
+#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
+#define UART_MCR_OUT2 0x08 /* Out2 complement */
+#define UART_MCR_OUT1 0x04 /* Out1 complement */
+#define UART_MCR_RTS 0x02 /* RTS complement */
+#define UART_MCR_DTR 0x01 /* DTR complement */
+
+/*
+ * These are the definitions for the Modem Status Register
+ */
+#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
+#define UART_MSR_RI 0x40 /* Ring Indicator */
+#define UART_MSR_DSR 0x20 /* Data Set Ready */
+#define UART_MSR_CTS 0x10 /* Clear to Send */
+#define UART_MSR_DDCD 0x08 /* Delta DCD */
+#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
+#define UART_MSR_DDSR 0x02 /* Delta DSR */
+#define UART_MSR_DCTS 0x01 /* Delta CTS */
+#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */
+
+/*
+ * These are the definitions for the Extended Features Register
+ * (StarTech 16C660 only, when DLAB=1)
+ */
+#define UART_EFR_CTS 0x80 /* CTS flow control */
+#define UART_EFR_RTS 0x40 /* RTS flow control */
+#define UART_EFR_SCD 0x20 /* Special character detect */
+#define UART_EFR_ECB 0x10 /* Enhanced control bit */
+/*
+ * the low four bits control software flow control
+ */
+
+/*
+ * These register definitions are for the 16C950
+ */
+#define UART_ASR 0x01 /* Additional Status Register */
+#define UART_RFL 0x03 /* Transmitter FIFO level */
+#define UART_TFL 0x04 /* Receiver FIFO level */
+#define UART_ICR 0x05 /* Index Control Register */
+
+/* The 16950 ICR registers */
+#define UART_ACR 0x00 /* Additional Control Register */
+#define UART_CPR 0x01 /* Clock Prescalar Register */
+#define UART_TCR 0x02 /* Times Clock Register */
+#define UART_CKS 0x03 /* Clock Select Register */
+#define UART_TTL 0x04 /* Transmitter Interrupt Trigger Level */
+#define UART_RTL 0x05 /* Receiver Interrupt Trigger Level */
+#define UART_FCL 0x06 /* Flow Control Level Lower */
+#define UART_FCH 0x07 /* Flow Control Level Higher */
+#define UART_ID1 0x08 /* ID #1 */
+#define UART_ID2 0x09 /* ID #2 */
+#define UART_ID3 0x0A /* ID #3 */
+#define UART_REV 0x0B /* Revision */
+#define UART_CSR 0x0C /* Channel Software Reset */
+#define UART_NMR 0x0D /* Nine-bit Mode Register */
+#define UART_CTR 0xFF
+
+/*
+ * The 16C950 Additional Control Reigster
+ */
+#define UART_ACR_RXDIS 0x01 /* Receiver disable */
+#define UART_ACR_TXDIS 0x02 /* Receiver disable */
+#define UART_ACR_DSRFC 0x04 /* DSR Flow Control */
+#define UART_ACR_TLENB 0x20 /* 950 trigger levels enable */
+#define UART_ACR_ICRRD 0x40 /* ICR Read enable */
+#define UART_ACR_ASREN 0x80 /* Additional status enable */
+
+/*
+ * These are the definitions for the Feature Control Register
+ * (XR16C85x only, when LCR=bf; doubles with the Interrupt Enable
+ * Register, UART register #1)
+ */
+#define UART_FCTR_RTS_NODELAY 0x00 /* RTS flow control delay */
+#define UART_FCTR_RTS_4DELAY 0x01
+#define UART_FCTR_RTS_6DELAY 0x02
+#define UART_FCTR_RTS_8DELAY 0x03
+#define UART_FCTR_IRDA 0x04 /* IrDa data encode select */
+#define UART_FCTR_TX_INT 0x08 /* Tx interrupt type select */
+#define UART_FCTR_TRGA 0x00 /* Tx/Rx 550 trigger table select */
+#define UART_FCTR_TRGB 0x10 /* Tx/Rx 650 trigger table select */
+#define UART_FCTR_TRGC 0x20 /* Tx/Rx 654 trigger table select */
+#define UART_FCTR_TRGD 0x30 /* Tx/Rx 850 programmable trigger select */
+#define UART_FCTR_SCR_SWAP 0x40 /* Scratch pad register swap */
+#define UART_FCTR_RX 0x00 /* Programmable trigger mode select */
+#define UART_FCTR_TX 0x80 /* Programmable trigger mode select */
+
+/*
+ * These are the definitions for the Enhanced Mode Select Register
+ * (XR16C85x only, when LCR=bf and FCTR bit 6=1; doubles with the
+ * Scratch register, UART register #7)
+ */
+#define UART_EMSR_FIFO_COUNT 0x01 /* Rx/Tx select */
+#define UART_EMSR_ALT_COUNT 0x02 /* Alternating count select */
+
+/*
+ * These are the definitions for the Programmable Trigger
+ * Register (XR16C85x only, when LCR=bf; doubles with the UART RX/TX
+ * register, UART register #0)
+ */
+#define UART_TRG_1 0x01
+#define UART_TRG_4 0x04
+#define UART_TRG_8 0x08
+#define UART_TRG_16 0x10
+#define UART_TRG_32 0x20
+#define UART_TRG_64 0x40
+#define UART_TRG_96 0x60
+#define UART_TRG_120 0x78
+#define UART_TRG_128 0x80
+
+/*
+ * These definitions are for the RSA-DV II/S card, from
+ *
+ * Kiyokazu SUTO <suto@ks-and-ks.ne.jp>
+ */
+
+#define UART_RSA_BASE (-8)
+
+#define UART_RSA_MSR ((UART_RSA_BASE) + 0) /* I/O: Mode Select Register */
+
+#define UART_RSA_MSR_SWAP (1 << 0) /* Swap low/high 8 bytes in I/O port addr */
+#define UART_RSA_MSR_FIFO (1 << 2) /* Enable the external FIFO */
+#define UART_RSA_MSR_FLOW (1 << 3) /* Enable the auto RTS/CTS flow control */
+#define UART_RSA_MSR_ITYP (1 << 4) /* Level (1) / Edge triger (0) */
+
+#define UART_RSA_IER ((UART_RSA_BASE) + 1) /* I/O: Interrupt Enable Register */
+
+#define UART_RSA_IER_Rx_FIFO_H (1 << 0) /* Enable Rx FIFO half full int. */
+#define UART_RSA_IER_Tx_FIFO_H (1 << 1) /* Enable Tx FIFO half full int. */
+#define UART_RSA_IER_Tx_FIFO_E (1 << 2) /* Enable Tx FIFO empty int. */
+#define UART_RSA_IER_Rx_TOUT (1 << 3) /* Enable char receive timeout int */
+#define UART_RSA_IER_TIMER (1 << 4) /* Enable timer interrupt */
+
+#define UART_RSA_SRR ((UART_RSA_BASE) + 2) /* IN: Status Read Register */
+
+#define UART_RSA_SRR_Tx_FIFO_NEMP (1 << 0) /* Tx FIFO is not empty (1) */
+#define UART_RSA_SRR_Tx_FIFO_NHFL (1 << 1) /* Tx FIFO is not half full (1) */
+#define UART_RSA_SRR_Tx_FIFO_NFUL (1 << 2) /* Tx FIFO is not full (1) */
+#define UART_RSA_SRR_Rx_FIFO_NEMP (1 << 3) /* Rx FIFO is not empty (1) */
+#define UART_RSA_SRR_Rx_FIFO_NHFL (1 << 4) /* Rx FIFO is not half full (1) */
+#define UART_RSA_SRR_Rx_FIFO_NFUL (1 << 5) /* Rx FIFO is not full (1) */
+#define UART_RSA_SRR_Rx_TOUT (1 << 6) /* Character reception timeout occured (1) */
+#define UART_RSA_SRR_TIMER (1 << 7) /* Timer interrupt occured */
+
+#define UART_RSA_FRR ((UART_RSA_BASE) + 2) /* OUT: FIFO Reset Register */
+
+#define UART_RSA_TIVSR ((UART_RSA_BASE) + 3) /* I/O: Timer Interval Value Set Register */
+
+#define UART_RSA_TCR ((UART_RSA_BASE) + 4) /* OUT: Timer Control Register */
+
+#define UART_RSA_TCR_SWITCH (1 << 0) /* Timer on */
+
+/*
+ * The RSA DSV/II board has two fixed clock frequencies. One is the
+ * standard rate, and the other is 8 times faster.
+ */
+#define SERIAL_RSA_BAUD_BASE (921600)
+#define SERIAL_RSA_BAUD_BASE_LO (SERIAL_RSA_BAUD_BASE / 8)
+
+#endif /* _LINUX_SERIAL_REG_H */
+
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * This module provides interface routines to the LPC ARM UARTs.
+ * Copyright 2004, R O SoftWare
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ * reduced to see what has to be done for minimum UART-support by mthomas
+ *****************************************************************************/
+
+// #warning "this is a reduced version of the R O Software code"
+
+#include <hal_machperiph.h>
+#include "uart.h"
+#include "serial_reg.h"
+
+/* on LPC17xx: UART0 TX-Pin=P0.2, RX-Pin=P0.3
+ PINSEL0 has to be set to "UART-Function" = Function "01"
+ for Pin 0.2 and 0.3 */
+
+#define PINSEL_BIT_TXD0 (2*2)
+#define PINSEL_BIT_RXD0 (3*2)
+#define PINSEL_FIRST_ALT_FUNC 1
+#define PINSEL_SECOND_ALT_FUNC 2
+
+// Values of Bits 4-7 in PINSEL to activate UART0
+#define UART0_PINSEL ((PINSEL_FIRST_ALT_FUNC<<PINSEL_BIT_TXD0)|(PINSEL_FIRST_ALT_FUNC<<PINSEL_BIT_RXD0))
+// Mask of Bits 4-7
+#define UART0_PINMASK ((3<<PINSEL_BIT_TXD0)|(3<<PINSEL_BIT_RXD0))
+
+// U0_LCR devisor latch bit
+#define UART0_LCR_DLAB 7
+
+/* baudrate divisor - use UART_BAUD macro
+ * mode - see typical modes (uart.h)
+ * fmode - see typical fmodes (uart.h)
+ * NOTE: uart0Init(UART_BAUD(9600), UART_8N1, UART_FIFO_8);
+ */
+void uart0Init(uint32_t baud, uint8_t mode, uint8_t fmode)
+{
+ volatile int i;
+ uint32_t baud_div;
+
+ // setup Pin Function Select Register (Pin Connect Block)
+ // make sure old values of Bits 0-4 are masked out and
+ // set them according to UART0-Pin-Selection
+ PINCON->PINSEL0 = (PINCON->PINSEL0 & ~UART0_PINMASK) | UART0_PINSEL;
+
+ UART0->IER = 0x00; // disable all interrupts
+ //UART0->IIR = 0x00; // clear interrupt ID register
+ //UART0->LSR = 0x00; // clear line status register
+
+ baud *= 16;
+ baud_div = (PCLK + baud / 4) / baud;
+
+ // set the baudrate - DLAB must be set to access DLL/DLM
+ UART0->LCR = (1<<UART0_LCR_DLAB); // set divisor latches (DLAB)
+ UART0->DLL = (uint8_t)baud_div; // set for baud low byte
+ UART0->DLM = (uint8_t)(baud_div >> 8); // set for baud high byte
+
+ // set the number of characters and other
+ // user specified operating parameters
+ // Databits, Parity, Stopbits - Settings in Line Control Register
+ UART0->LCR = (mode & ~(1<<UART0_LCR_DLAB)); // clear DLAB "on-the-fly"
+ // setup FIFO Control Register (fifo-enabled + xx trig)
+ UART0->FCR = fmode;
+
+ for(i=0;i<65000;i++);
+}
+
+int uart0Putch(int ch)
+{
+ while (!(UART0->LSR & UART_LSR_THRE)) // wait for TX buffer to empty
+ continue; // also either WDOG() or swap()
+
+ UART0->THR = (uint8_t)ch; // put char to Transmit Holding Register
+ return (uint8_t)ch; // return char ("stdio-compatible"?)
+}
+
+int uart0PutchNW(int ch)
+{
+ if (!(UART0->LSR & UART_LSR_THRE)) // wait for TX buffer to empty
+ return -1; // also either WDOG() or swap()
+
+ UART0->THR = (uint8_t)ch; // put char to Transmit Holding Register
+ return (uint8_t)ch; // return char ("stdio-compatible"?)
+}
+
+const char *uart0Puts(const char *string)
+{
+ char ch;
+
+ while ((ch = *string)) {
+ if (uart0Putch(ch)<0) break;
+ string++;
+ }
+
+ return string;
+}
+
+int uart0TxEmpty(void)
+{
+ return (UART0->LSR & (UART_LSR_THRE | UART_LSR_TEMT)) == (UART_LSR_THRE | UART_LSR_TEMT);
+}
+
+void uart0TxFlush(void)
+{
+ UART0->FCR |= UART_FCR_CLEAR_XMIT; // clear the TX fifo
+}
+
+
+/* Returns: character on success, -1 if no character is available */
+int uart0Getch(void)
+{
+ if (UART0->LSR & UART_LSR_DR) // check if character is available
+ return UART0->RBR; // return character
+
+ return -1;
+}
+
+/* Returns: character on success, waits */
+int uart0GetchW(void)
+{
+ while ( !(UART0->LSR & UART_LSR_DR) ); // wait for character
+ return UART0->RBR; // return character
+}
+
--- /dev/null
+/******************************************************************************
+ * based on software from:
+ * Copyright 2004, R O SoftWare
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ * reduced to learn what has to be done to enable and use UART0
+ *****************************************************************************/
+#ifndef INC_UART_H
+#define INC_UART_H
+
+#include <system_def.h>
+#include "serial_reg.h"
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Prehistoric solutions slect baudrates according to some magic constants
+// Use SI defined Hz/Baud units for selection of baudrate directly for
+// uart0Init() and uart1Init()
+#define UART_BAUD(baud) (baud)
+
+///////////////////////////////////////////////////////////////////////////////
+// Definitions for typical UART 'baud' settings
+#define B1200 UART_BAUD(1200)
+#define B9600 UART_BAUD(9600)
+#define B19200 UART_BAUD(19200)
+#define B38400 UART_BAUD(38400)
+#define B57600 UART_BAUD(57600)
+#define B115200 UART_BAUD(115200)
+
+///////////////////////////////////////////////////////////////////////////////
+// Definitions for typical UART 'mode' settings
+#define UART_8N1 (uint8_t)(UART_LCR_WLEN8 )
+#define UART_7N1 (uint8_t)(UART_LCR_WLEN7 )
+#define UART_8N2 (uint8_t)(UART_LCR_WLEN8 | UART_LCR_STOP)
+#define UART_7N2 (uint8_t)(UART_LCR_WLEN7 | UART_LCR_STOP)
+#define UART_8E1 (uint8_t)(UART_LCR_WLEN8 | UART_LCR_PARITY | UART_LCR_EPAR)
+#define UART_7E1 (uint8_t)(UART_LCR_WLEN7 | UART_LCR_PARITY | UART_LCR_EPAR)
+#define UART_8E2 (uint8_t)(UART_LCR_WLEN8 | UART_LCR_PARITY | UART_LCR_EPAR | UART_LCR_STOP)
+#define UART_7E2 (uint8_t)(UART_LCR_WLEN7 | UART_LCR_PARITY | UART_LCR_EPAR | UART_LCR_STOP)
+#define UART_8O1 (uint8_t)(UART_LCR_WLEN8 | UART_LCR_PARITY )
+#define UART_7O1 (uint8_t)(UART_LCR_WLEN7 | UART_LCR_PARITY )
+#define UART_8O2 (uint8_t)(UART_LCR_WLEN8 | UART_LCR_PARITY | UART_LCR_STOP)
+#define UART_7O2 (uint8_t)(UART_LCR_WLEN7 | UART_LCR_PARITY | UART_LCR_STOP)
+
+///////////////////////////////////////////////////////////////////////////////
+// Definitions for typical UART 'fmode' settings
+#define UART_FIFO_OFF (0x00)
+#define UART_FIFO_1 (uint8_t)(UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1)
+#define UART_FIFO_4 (uint8_t)(UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_4)
+#define UART_FIFO_8 (uint8_t)(UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8)
+#define UART_FIFO_14 (uint8_t)(UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_14)
+
+void uart0Init(uint32_t baud, uint8_t mode, uint8_t fmode);
+int uart0Putch(int ch);
+uint16_t uart0Space(void);
+const char *uart0Puts(const char *string);
+int uart0TxEmpty(void);
+void uart0TxFlush(void);
+int uart0Getch(void);
+int uart0GetchW(void);
+
+#endif
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+lib_LDSCRIPTS = $(notdir $(wildcard $(SOURCES_DIR)/*.ld*))
+
+include_HEADERS = mem_loc.h keyval_loc.h
--- /dev/null
+#ifndef _KEYVAL_LOC_H
+#define _KEYVAL_LOC_H
+
+extern int _keyval_start;
+extern int _keyval_page_len;
+
+#define KEYVAL_START ((unsigned int)&_keyval_start)
+#define KEYVAL_PAGE_LEN ((unsigned int)&_keyval_page_len)
+
+#endif /* _KVPB_LOC */
--- /dev/null
+/***********************************************************************/
+/* */
+/* ROM.ld: Linker Script File */
+/* */
+/***********************************************************************/
+
+INCLUDE "lpc1754.ld-cfg"
+
+INCLUDE "lpc17xx-base.ld-app"
+
--- /dev/null
+/***********************************************************************/
+/* */
+/* ROM.ld: Linker Script File */
+/* */
+/***********************************************************************/
+
+INCLUDE "lpc1754.ld-cfg"
+
+INCLUDE "lpc17xx-base.ld-boot"
--- /dev/null
+
+KEYVAL_PAGE_LEN = 0x00001000;
+
+PROVIDE( __bbconf_pt_addr = 0 );
+
+MEMORY
+{
+ /* LPC1754 : 128k ROM + 32k SRAM */
+ /*------------------------------ */
+
+
+ /* Main ROM region - 128k for LPC1754 */
+ FLASHBOOT (rx) : ORIGIN = 0x00000000, LENGTH = 0x00007000
+ KEYVAL (rx) : ORIGIN = 0x00007000, LENGTH = 0x00002000
+ FLASHAPP (rx) : ORIGIN = 0x00009000, LENGTH = 0x00017000
+
+ /* local static RAM - 16k for LPC1754 */
+ IRAM0 (rwx) : ORIGIN = 0x10000000, LENGTH = 16k
+
+ /* stack location */
+ STACK (rw) : ORIGIN = 0x10000000 + 0x00003FE0 - 4, LENGTH = 4
+
+ /* AHB SRAM - 16k for LPC1756 - often used for USB */
+ IRAM1 (rwx) : ORIGIN = 0x2007C000, LENGTH = 16k
+}
+
--- /dev/null
+/***********************************************************************/
+/* */
+/* ROM.ld: Linker Script File */
+/* */
+/***********************************************************************/
+
+INCLUDE "lpc1758.ld-cfg"
+
+INCLUDE "lpc17xx-base.ld-app"
+
--- /dev/null
+/***********************************************************************/
+/* */
+/* ROM.ld: Linker Script File */
+/* */
+/***********************************************************************/
+
+INCLUDE "lpc1758.ld-cfg"
+
+INCLUDE "lpc17xx-base.ld-boot"
--- /dev/null
+
+KEYVAL_PAGE_LEN = 0x00001000;
+
+PROVIDE( __bbconf_pt_addr = 0 );
+
+MEMORY
+{
+ /* LPC1758 : 512k ROM + 64k SRAM */
+ /*------------------------------ */
+
+
+ /* Main ROM region - 512k for LPC1758 */
+ FLASHBOOT (rx) : ORIGIN = 0x00000000, LENGTH = 0x00007000
+ KEYVAL (rx) : ORIGIN = 0x00007000, LENGTH = 0x00002000
+ FLASHAPP (rx) : ORIGIN = 0x00009000, LENGTH = 0x00077000
+
+ /* local static RAM - 32k for LPC1758 */
+ IRAM0 (rwx) : ORIGIN = 0x10000000, LENGTH = 32k
+
+ /* stack location */
+ STACK (rw) : ORIGIN = 0x10000000 + 0x00007FE0 - 4, LENGTH = 4
+
+ /* AHB SRAM - 16k for LPC1758 - often used for USB */
+ IRAM1 (rwx) : ORIGIN = 0x2007C000, LENGTH = 16k
+
+ /* AHB SRAM - 16k for LPC1758 */
+ IRAM2 (rwx) : ORIGIN = 0x20080000, LENGTH = 16k
+
+}
+
--- /dev/null
+/***********************************************************************/
+/* */
+/* ROM.ld: Linker Script File */
+/* */
+/***********************************************************************/
+
+INCLUDE "lpc1766.ld-cfg"
+
+INCLUDE "lpc17xx-base.ld-app"
+
--- /dev/null
+/***********************************************************************/
+/* */
+/* ROM.ld: Linker Script File */
+/* */
+/***********************************************************************/
+
+INCLUDE "lpc1766.ld-cfg"
+
+INCLUDE "lpc17xx-base.ld-boot"
--- /dev/null
+
+KEYVAL_PAGE_LEN = 0x00001000;
+
+PROVIDE( __bbconf_pt_addr = 0 );
+
+MEMORY
+{
+ /* LPC1768 : 512 ROM + 32k SRAM + 16k SRAM + 16k SRAM */
+ /*--------------------------------------------------- */
+
+
+ /* Main ROM region - 256k for LPC1766 */
+ FLASHBOOT (rx) : ORIGIN = 0x00000000, LENGTH = 0x00007000
+ KEYVAL (rx) : ORIGIN = 0x00007000, LENGTH = 0x00002000
+ FLASHAPP (rx) : ORIGIN = 0x00009000, LENGTH = 0x00037000
+
+ /* local static RAM - 32k for LPC1766 */
+ IRAM0 (rwx) : ORIGIN = 0x10000000, LENGTH = 32k
+
+ /* stack location */
+ STACK (rw) : ORIGIN = 0x10000000 + 0x00007FE0 - 4, LENGTH = 4
+
+ /* AHB SRAM - 16k for LPC1768 - often used for USB */
+ IRAM1 (rwx) : ORIGIN = 0x2007C000, LENGTH = 32k
+}
+
--- /dev/null
+/***********************************************************************/
+/* */
+/* ROM.ld: Linker Script File */
+/* */
+/***********************************************************************/
+
+INCLUDE "lpc1768.ld-cfg"
+
+INCLUDE "lpc17xx-base.ld-app"
+
--- /dev/null
+/***********************************************************************/
+/* */
+/* ROM.ld: Linker Script File */
+/* */
+/***********************************************************************/
+
+INCLUDE "lpc1768.ld-cfg"
+
+INCLUDE "lpc17xx-base.ld-boot"
--- /dev/null
+
+KEYVAL_PAGE_LEN = 0x00001000;
+
+PROVIDE( __bbconf_pt_addr = 0 );
+
+MEMORY
+{
+ /* LPC1768 : 512 ROM + 32k SRAM + 16k SRAM + 16k SRAM */
+ /*--------------------------------------------------- */
+
+
+ /* Main ROM region - 512k for LPC1768 */
+ FLASHBOOT (rx) : ORIGIN = 0x00000000, LENGTH = 0x00007000
+ KEYVAL (rx) : ORIGIN = 0x00007000, LENGTH = 0x00002000
+ FLASHAPP (rx) : ORIGIN = 0x00009000, LENGTH = 0x00077000
+
+ /* local static RAM - 32k for LPC1768 */
+ IRAM0 (rwx) : ORIGIN = 0x10000000, LENGTH = 32k
+
+ /* stack location */
+ STACK (rw) : ORIGIN = 0x10000000 + 0x00007FE0 - 4, LENGTH = 4
+
+ /* AHB SRAM - 16k for LPC1768 - often used for USB */
+ IRAM1 (rwx) : ORIGIN = 0x2007C000, LENGTH = 32k
+}
+
--- /dev/null
+/***********************************************************************/
+/* */
+/* ROM.ld: Linker Script File */
+/* */
+/***********************************************************************/
+
+ENTRY(g_pfnVectors)
+
+PROVIDE (_setup_board = 0);
+
+/* SECTION command : Define mapping of input sections */
+/* into output sections. */
+
+SECTIONS
+{
+ /******************************************/
+ /* code section */
+
+ /* "normal" code */
+
+ .text :
+ {
+ KEEP(*(.isr_vector .isr_vector.*))
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.gcc_except_table)
+ *(.rodata .rodata*)
+ *(.gnu.linkonce.r.*)
+ } >FLASHAPP
+
+ /******************************************/
+ /* .ctors .dtors are used for c++ constructors/destructors */
+ .ctors :
+ {
+ . = ALIGN(4);
+ PROVIDE(__ctors_start = .);
+ KEEP(*(SORT(.ctors.*)))
+ KEEP(*(.ctors))
+ PROVIDE(__ctors_end = .);
+ } >FLASHAPP
+
+ .dtors :
+ {
+ . = ALIGN(4);
+ PROVIDE(__dtors_start = .);
+ KEEP(*(SORT(.dtors.*)))
+ KEEP(*(.dtors))
+ PROVIDE(__dtors_end = .);
+
+ . = ALIGN(4);
+ /* End Of .text section */
+ _etext = .;
+ _sifastcode = .;
+ } >FLASHAPP
+
+
+ .keyval :
+ {
+ PROVIDE (_keyval_start = .);
+ PROVIDE (_keyval_page_len = KEYVAL_PAGE_LEN );
+ }> KEYVAL
+
+ .app :
+ {
+ PROVIDE (_mem_app_start = . );
+ } > FLASHAPP
+
+ .irqarea (NOLOAD):
+ {
+ . = ALIGN (256);
+ *(.irqarea .irqarea.*)
+
+ } >IRAM0
+
+ /**************************************************/
+ /* fastcode - copied at startup & executed in RAM */
+
+ .fastcode :
+ {
+ . = ALIGN (4);
+ _sfastcode = . ;
+
+ *(.glue_7t) *(.glue_7)
+ *(.fastcode)
+
+ /* add other modules here ... */
+
+ . = ALIGN (4);
+ _efastcode = . ;
+ _sidata = .;
+ } >IRAM0 AT>FLASHAPP
+
+ /******************************************/
+ /* This used for USB RAM section */
+ .usbram (NOLOAD):
+ {
+ _usbram = . ;
+ *(.usbram)
+ . = ALIGN(4);
+ _eusbram = . ;
+ _usbram_end = . ;
+ } > IRAM1
+
+ /******************************************/
+ /* data section */
+ .data :
+ {
+ _sidata = LOADADDR (.data);
+ . = ALIGN(4);
+ _sdata = .;
+
+ *(vtable vtable.*)
+ *(.data .data.*)
+ *(.gnu.linkonce.d*)
+
+ . = ALIGN(4);
+ _edata = . ;
+ } >IRAM0 AT>FLASHAPP
+
+ /******************************************/
+ /* For no-init variables section */
+ .bss (NOLOAD) :
+ {
+ . = ALIGN(4);
+ _sbss = . ;
+
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = . ;
+
+ . = ALIGN(4);
+ _end = . ;
+ PROVIDE (end = .);
+ } >IRAM0
+
+ .stack :
+ {
+ _stack = .;
+ } >STACK
+
+
+ /******************************************/
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ /* .comment 0 : { *(.comment) } */
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+}
--- /dev/null
+/***********************************************************************/
+/* */
+/* ROM.ld: Linker Script File */
+/* */
+/***********************************************************************/
+
+ENTRY(g_pfnVectors)
+
+PROVIDE (_setup_board = 0);
+
+/* SECTION command : Define mapping of input sections */
+/* into output sections. */
+
+SECTIONS
+{
+ /******************************************/
+ /* code section */
+
+ /* "normal" code */
+
+ .text :
+ {
+ KEEP(*(.isr_vector .isr_vector.*))
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.gcc_except_table)
+ *(.rodata .rodata*)
+ *(.gnu.linkonce.r.*)
+ } >FLASHBOOT
+
+ /******************************************/
+ /* .ctors .dtors are used for c++ constructors/destructors */
+ .ctors :
+ {
+ . = ALIGN(4);
+ PROVIDE(__ctors_start = .);
+ KEEP(*(SORT(.ctors.*)))
+ KEEP(*(.ctors))
+ PROVIDE(__ctors_end = .);
+ } >FLASHBOOT
+
+ .dtors :
+ {
+ . = ALIGN(4);
+ PROVIDE(__dtors_start = .);
+ KEEP(*(SORT(.dtors.*)))
+ KEEP(*(.dtors))
+ PROVIDE(__dtors_end = .);
+
+ . = ALIGN(4);
+ /* End Of .text section */
+ _etext = .;
+ _sifastcode = .;
+ } >FLASHBOOT
+
+
+ .keyval :
+ {
+ PROVIDE (_keyval_start = .);
+ PROVIDE (_keyval_page_len = KEYVAL_PAGE_LEN );
+ }> KEYVAL
+
+ .app :
+ {
+ PROVIDE (_mem_app_start = . );
+ } > FLASHAPP
+
+ .irqarea (NOLOAD):
+ {
+ . = ALIGN (256);
+ *(.irqarea .irqarea.*)
+
+ } >IRAM0
+
+ /**************************************************/
+ /* fastcode - copied at startup & executed in RAM */
+
+ .fastcode :
+ {
+ . = ALIGN (4);
+ _sfastcode = . ;
+
+ *(.glue_7t) *(.glue_7)
+ *(.fastcode)
+
+ /* add other modules here ... */
+
+ . = ALIGN (4);
+ _efastcode = . ;
+ _sidata = .;
+ } >IRAM0 AT>FLASHBOOT
+
+ /******************************************/
+ /* This used for USB RAM section */
+ .usbram (NOLOAD):
+ {
+ _usbram = . ;
+ *(.usbram)
+ . = ALIGN(4);
+ _eusbram = . ;
+ _usbram_end = . ;
+ } > IRAM1
+
+ /******************************************/
+ /* data section */
+ .data :
+ {
+ _sidata = LOADADDR (.data);
+ . = ALIGN(4);
+ _sdata = .;
+
+ *(vtable vtable.*)
+ *(.data .data.*)
+ *(.gnu.linkonce.d*)
+
+ . = ALIGN(4);
+ _edata = . ;
+ } >IRAM0 AT>FLASHBOOT
+
+ /******************************************/
+ /* For no-init variables section */
+ .bss (NOLOAD) :
+ {
+ . = ALIGN(4);
+ _sbss = . ;
+
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = . ;
+
+ . = ALIGN(4);
+ _end = . ;
+ PROVIDE (end = .);
+ } >IRAM0
+
+ .stack :
+ {
+ _stack = .;
+ } >STACK
+
+
+ /******************************************/
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ /* .comment 0 : { *(.comment) } */
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+}
--- /dev/null
+#ifndef _MEM_LOC_H
+#define _MEM_LOC_H
+
+extern int _mem_app_start;
+
+#define MEM_APP_START ((unsigned int)&_mem_app_start)
+
+#endif /* _MEM_LOC */
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+SUBDIRS = defines libs
--- /dev/null
+# -*- makefile -*-
+
+ARCH=arm
+MACH=lpc21xx
+BOARD=ul_usb1
+CONFIG_BOARD_VARIANT=hisc-keypad
+
+CONFIG_APP_HISC_BELL_KEYPAD=y
+CONFIG_OC_UL_DRV_SYSLESS=y
+CONFIG_OC_UL_DRV_U450_TMELATE=y
+CONFIG_ULAN_DY=y
+CONFIG_ULOI_LT=y
+CONFIG_KEYVAL=y
+CONFIG_KBD=y
+
+#CONFIG_STDIO_COM_PORT=0
+
+CROSS_COMPILE = arm-elf-
+TARGET_ARCH = -mcpu=arm7tdmi
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+DEBUG ?= -g
+OPTIMIZE ?= -O2
+
+LPC_BAUD = 38400
+TOLPC = tolpc --baud $(LPC_BAUD) --sdev /dev/ttyS0
+LOAD_CMD-ramisp = $(TOLPC) -v -q 7372 -L -f
+LOAD_CMD-boot = lpc21isp -bin /dev/ttyS0 $(LPC_BAUD) 12000
+
+# This selects linker script
+LD_SCRIPT=lpc2148
+#DEFAULT_LD_SCRIPT_VARIANT=boot
+
+#OUTPUT_FORMATS = bin hex srec
+
+OUTPUT_FORMATS = bin
+
+PROG_BASE=0x20000
+PROG_SIZE=0x20000
+
+UL_SENDHEX ?= ul_sendhex
+MOD ?= 62
+
+LOAD_CMD-app = \
+ $(UL_SENDHEX) -m $(MOD) -r -o 0 ; \
+ $(UL_SENDHEX) -m $(MOD) -o 0 -t 0x101 -s $(PROG_BASE) -l $(PROG_SIZE) -e; \
+ $(UL_SENDHEX) -m $(MOD) -o 0 -t 0x101 -b 256 -s $(PROG_BASE) -f binary
+
+RUN_CMD-app = \
+ $(UL_SENDHEX) -m $(MOD) -r
--- /dev/null
+# -*- makefile -*-
+
+ARCH=arm
+MACH=lpc21xx
+BOARD=ul_usb1
+CONFIG_BOARD_VARIANT=hisc-garage-gate
+
+CONFIG_APP_HISC_GARAGE_GATE=y
+CONFIG_OC_UL_DRV_SYSLESS=y
+CONFIG_OC_UL_DRV_U450_TMELATE=y
+CONFIG_ULAN_DY=y
+CONFIG_ULOI_LT=y
+CONFIG_KEYVAL=y
+
+#CONFIG_STDIO_COM_PORT=0
+
+CROSS_COMPILE = arm-elf-
+TARGET_ARCH = -mcpu=arm7tdmi
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+DEBUG ?= -g
+OPTIMIZE ?= -O2
+
+LPC_BAUD = 38400
+TOLPC = tolpc --baud $(LPC_BAUD) --sdev /dev/ttyS0
+LOAD_CMD-ramisp = $(TOLPC) -v -q 7372 -L -f
+LOAD_CMD-boot = lpc21isp -bin /dev/ttyS0 $(LPC_BAUD) 12000
+
+# This selects linker script
+LD_SCRIPT=lpc2148
+#DEFAULT_LD_SCRIPT_VARIANT=boot
+
+#OUTPUT_FORMATS = bin hex srec
+
+OUTPUT_FORMATS = bin
+
+PROG_BASE=0x20000
+PROG_SIZE=0x20000
+
+UL_SENDHEX ?= ul_sendhex
+MOD ?= 62
+
+LOAD_CMD-app = \
+ $(UL_SENDHEX) -m $(MOD) -r -o 0 ; \
+ $(UL_SENDHEX) -m $(MOD) -o 0 -t 0x101 -s $(PROG_BASE) -l $(PROG_SIZE) -e; \
+ $(UL_SENDHEX) -m $(MOD) -o 0 -t 0x101 -b 256 -s $(PROG_BASE) -f binary
+
+RUN_CMD-app = \
+ $(UL_SENDHEX) -m $(MOD) -r
--- /dev/null
+# -*- makefile -*-
+
+ARCH=arm
+MACH=lpc21xx
+BOARD=ul_usb1
+CONFIG_BOARD_VARIANT=ha-switch
+
+CONFIG_HA_LIGHT_SWITCH=y
+
+CONFIG_OC_UL_DRV_SYSLESS=y
+CONFIG_OC_UL_DRV_U450_VARPINS=y
+CONFIG_OC_UL_DRV_U450_VARPINS_DIRNEG=y
+CONFIG_OC_UL_DRV_U450_LOOPBACK=y
+CONFIG_ULAN_DY=y
+CONFIG_ULOI_LT=y
+CONFIG_KEYVAL=y
+
+# CONFIG_STDIO_COM_PORT=0
+
+CROSS_COMPILE = arm-elf-
+TARGET_ARCH = -mcpu=arm7tdmi
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+DEBUG ?= -g
+OPTIMIZE ?= -O2
+
+# This selects linker script
+LD_SCRIPT=lpc2105
+#DEFAULT_LD_SCRIPT_VARIANT=boot
+
+#OUTPUT_FORMATS = bin hex srec
+
+OUTPUT_FORMATS = bin
+
+PROG_BASE=0xA000
+PROG_SIZE=0x10000
+
+UL_SENDHEX ?= ul_sendhex
+MOD ?= 62
+
+LOAD_CMD-app = \
+ $(UL_SENDHEX) -m $(MOD) -r -o 0 ; \
+ $(UL_SENDHEX) -m $(MOD) -o 0 -t 0x101 -s $(PROG_BASE) -l $(PROG_SIZE) -e; \
+ $(UL_SENDHEX) -m $(MOD) -o 0 -t 0x101 -b 512 -s $(PROG_BASE) -f binary
+
+RUN_CMD-app = \
+ $(UL_SENDHEX) -m $(MOD) -r
--- /dev/null
+# -*- makefile -*-
+
+ARCH=arm
+MACH=lpc21xx
+BOARD=ul_usb1
+CONFIG_BOARD_VARIANT=ha-switch
+
+CONFIG_ULBOOT=y
+
+CONFIG_OC_UL_DRV_SYSLESS=y
+CONFIG_OC_UL_DRV_U450_VARPINS=y
+CONFIG_OC_UL_DRV_U450_VARPINS_DIRNEG=y
+CONFIG_OC_UL_DRV_U450_LOOPBACK=y
+CONFIG_KEYVAL=y
+CONFIG_ULAN_DY=y
+
+# CONFIG_STDIO_COM_PORT=0
+
+CROSS_COMPILE = arm-elf-
+TARGET_ARCH = -mcpu=arm7tdmi
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+DEBUG ?= -g
+OPTIMIZE ?= -O2
+
+# This selects linker script
+LD_SCRIPT=lpc2105
+#DEFAULT_LD_SCRIPT_VARIANT=boot
+
+#OUTPUT_FORMATS = bin hex srec
+
+OUTPUT_FORMATS = hex bin
+
+TOHIT=lpc21isp
+DEV=/dev/ttyUSB0
+CPU_SYS_KHZ=14745
+BAUD=57600
+
+LOAD_CMD-boot = \
+ $(TOHIT) $(DEV) $(BAUD) $(CPU_SYS_KHZ)
--- /dev/null
+# -*- makefile -*-
+
+ARCH=arm
+MACH=lpc21xx
+BOARD=ul_usb1
+
+CONFIG_OC_UL_DRV_SYSLESS=y
+CONFIG_OC_UL_DRV_U450_VARPINS=y
+CONFIG_OC_UL_DRV_U450_VARPINS_MSRSWAP=y
+CONFIG_OC_UL_DRV_U450_TMELATE=y
+#CONFIG_ULAN_DY=y
+#CONFIG_ULOI_LT=y
+#CONFIG_ULOI_GENOBJIDTAG=y
+#CONFIG_KEYVAL=y
+CONFIG_USB_BASE=y
+CONFIG_USB_LPCUSB=y
+CONFIG_USB_MORE=y
+CONFIG_APP_U2U_V2=y
+
+#CONFIG_APP_TEST_LPC=y
+#CONFIG_APP_ULAD31=y
+#CONFIG_ULBOOT=y
+
+CONFIG_STDIO_COM_PORT=0
+
+CROSS_COMPILE = arm-elf-
+TARGET_ARCH = -mcpu=arm7tdmi
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+DEBUG ?= -g
+OPTIMIZE ?= -O2
+
+LPC_BAUD = 38400
+TOLPC = tolpc --baud $(LPC_BAUD) --sdev /dev/ttyS0
+LOAD_CMD-ramisp = $(TOLPC) -v -q 7372 -L -f
+LOAD_CMD-boot = lpc21isp -bin /dev/ttyUSB0 $(LPC_BAUD) 12000
+
+# This selects linker script
+LD_SCRIPT=lpc2148
+#DEFAULT_LD_SCRIPT_VARIANT=boot
+
+#OUTPUT_FORMATS = bin hex srec
+
+OUTPUT_FORMATS = bin
+
+PROG_BASE=0x20000
+PROG_SIZE=0x20000
+
+UL_SENDHEX ?= ul_sendhex
+MOD ?= 3
+
+LOAD_CMD-app = \
+ $(UL_SENDHEX) -m $(MOD) -r -o 0 ; \
+ $(UL_SENDHEX) -m $(MOD) -o 0 -t 0x101 -s $(PROG_BASE) -l $(PROG_SIZE) -e; \
+ $(UL_SENDHEX) -m $(MOD) -o 0 -t 0x101 -b 256 -s $(PROG_BASE) -f binary
+
+RUN_CMD-app = \
+ $(UL_SENDHEX) -m $(MOD) -g $(PROG_BASE)
--- /dev/null
+# -*- makefile -*-
+
+ARCH=arm
+MACH=lpc21xx
+BOARD=ul_usb1
+
+#CONFIG_BOARD_VARIANT=aa_rch
+CONFIG_OC_UL_DRV_SYSLESS=y
+CONFIG_OC_UL_DRV_U450_VARPINS=y
+CONFIG_OC_UL_DRV_U450_VARPINS_MSRSWAP=y
+CONFIG_OC_UL_DRV_U450_TMELATE=y
+CONFIG_ULAN_DY=y
+CONFIG_ULOI_LT=y
+CONFIG_ULOI_GENOBJIDTAG=y
+CONFIG_KEYVAL=y
+CONFIG_APP_TEST_LPC=y
+CONFIG_APP_ULAD31=y
+CONFIG_ULBOOT=y
+
+CONFIG_STDIO_COM_PORT=0
+
+CROSS_COMPILE = arm-elf-
+TARGET_ARCH = -mcpu=arm7tdmi
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+DEBUG ?= -g
+OPTIMIZE ?= -O2
+
+LPC_BAUD = 38400
+TOLPC = tolpc --baud $(LPC_BAUD) --sdev /dev/ttyS0
+LOAD_CMD-ramisp = $(TOLPC) -v -q 7372 -L -f
+LOAD_CMD-boot = lpc21isp -bin /dev/ttyS0 $(LPC_BAUD) 12000
+
+# This selects linker script
+LD_SCRIPT=lpc2148
+#DEFAULT_LD_SCRIPT_VARIANT=boot
+
+#OUTPUT_FORMATS = bin hex srec
+
+OUTPUT_FORMATS = bin
+
+PROG_BASE=0x20000
+PROG_SIZE=0x20000
+
+UL_SENDHEX ?= ul_sendhex
+MOD ?= 3
+
+LOAD_CMD-app = \
+ $(UL_SENDHEX) -m $(MOD) -r -o 0 ; \
+ $(UL_SENDHEX) -m $(MOD) -o 0 -t 0x101 -s $(PROG_BASE) -l $(PROG_SIZE) -e; \
+ $(UL_SENDHEX) -m $(MOD) -o 0 -t 0x101 -b 256 -s $(PROG_BASE) -f binary
+
+RUN_CMD-app = \
+ $(UL_SENDHEX) -m $(MOD) -g $(PROG_BASE)
--- /dev/null
+# -*- makefile -*-
+
+ARCH=arm
+MACH=lpc21xx
+BOARD=ul_usb1
+
+CONFIG_ULBOOT=y
+CONFIG_ULBOOT_WITH_USB=y
+
+CONFIG_OC_UL_DRV_SYSLESS=y
+CONFIG_OC_UL_DRV_U450_VARPINS=y
+CONFIG_OC_UL_DRV_U450_VARPINS_MSRSWAP=y
+CONFIG_OC_UL_DRV_U450_TMELATE=y
+CONFIG_KEYVAL=y
+CONFIG_ULAN_DY=y
+
+CONFIG_USB_BASE=y
+CONFIG_USB_LPCUSB=y
+CONFIG_USB_MORE=y
+
+# CONFIG_STDIO_COM_PORT=0
+
+CROSS_COMPILE = arm-elf-
+TARGET_ARCH = -mcpu=arm7tdmi
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+DEBUG ?= -g
+OPTIMIZE ?= -O2
+
+# This selects linker script
+LD_SCRIPT=lpc2148
+#DEFAULT_LD_SCRIPT_VARIANT=boot
+
+#OUTPUT_FORMATS = bin hex srec
+
+OUTPUT_FORMATS = hex bin
+
+TOHIT=lpc21isp
+DEV=/dev/ttyUSB0
+CPU_SYS_KHZ=12000
+BAUD=38400
+
+LOAD_CMD-boot = \
+ $(TOHIT) $(DEV) $(BAUD) $(CPU_SYS_KHZ)
--- /dev/null
+# -*- makefile -*-
+
+ARCH=arm
+MACH=lpc21xx
+BOARD=ul_usb1
+
+#CONFIG_BOARD_VARIANT=aa_rch
+#CONFIG_OC_UL_DRV_SYSLESS=y
+#CONFIG_OC_UL_DRV_U450_VARPINS=y
+#CONFIG_OC_UL_DRV_U450_VARPINS_MSRSWAP=y
+#CONFIG_ULAN_DY=y
+#CONFIG_ULOI_LT=y
+#CONFIG_ULOI_GENOBJIDTAG=y
+CONFIG_KEYVAL=y
+#CONFIG_APP_TEST_LPC=y
+#CONFIG_APP_ULAD31=y
+#CONFIG_APP_TEST=y
+#CONFIG_APP_USBTEST=y
+#CONFIG_APP_U2U=y
+#CONFIG_APP_U2U_V2=y
+CONFIG_USB_BASE=y
+CONFIG_USB_MORE=y
+CONFIG_USB_LPCUSB=y
+CONFIG_APP_USBCAN=y
+CONFIG_OC_LINCAN_CARD_ul_usb1=y
+#CONFIG_APP_USBBOOT=y
+#CONFIG_ULBOOT=y
+
+
+CONFIG_STDIO_COM_PORT=0
+
+CROSS_COMPILE = arm-elf-
+TARGET_ARCH = -mcpu=arm7tdmi
+
+# Set default C flags. If theese are set elsewhere (e.g. on a command
+# line), these default flags are not used.
+DEBUG ?= -g
+OPTIMIZE ?= -O2
+
+LPC_BAUD = 38400
+TOLPC = tolpc --baud $(LPC_BAUD) --sdev /dev/ttyUSB0
+LOAD_CMD-ramisp = $(TOLPC) -v -q 7372 -L -f
+LOAD_CMD-boot = lpc21isp -bin /dev/ttyUSB0 $(LPC_BAUD) 12000
+
+# This selects linker script
+LD_SCRIPT=lpc2148
+#DEFAULT_LD_SCRIPT_VARIANT=boot
+
+#OUTPUT_FORMATS = bin hex srec
+
+OUTPUT_FORMATS = bin
+
+PROG_BASE=0x20000
+PROG_SIZE=0x20000
+
+UL_SENDHEX ?= ul_sendhex
+MOD ?= 3
+
+LOAD_CMD-app-ulan = \
+ $(UL_SENDHEX) -m $(MOD) -r -o 0 ; \
+ $(UL_SENDHEX) -m $(MOD) -o 0 -t 0x101 -s $(PROG_BASE) -l $(PROG_SIZE) -e; \
+ $(UL_SENDHEX) -m $(MOD) -o 0 -t 0x101 -b 256 -s $(PROG_BASE) -f binary
+
+RUN_CMD-app-ulan = \
+ $(UL_SENDHEX) -m $(MOD) -g $(PROG_BASE)
+
+USB_SENDHEX ?= usb_sendhex
+USB_APP_VID ?= 0x1669
+USB_APP_PID ?= 0x1011
+USB_BOOT_VID ?= 0xdead
+USB_BOOT_PID ?= 0x2263
+
+LOAD_CMD-app = \
+ $(USB_SENDHEX) -d $(USB_APP_VID):$(USB_APP_PID) -r ; \
+ $(USB_SENDHEX) -w -d $(USB_BOOT_VID):$(USB_BOOT_PID) -s $(PROG_BASE) -l $(PROG_SIZE) -e; sleep 2 ; \
+ $(USB_SENDHEX) -d $(USB_BOOT_VID):$(USB_BOOT_PID) -s $(PROG_BASE) -f binary
+
+RUN_CMD-app = \
+ $(USB_SENDHEX) -d $(USB_BOOT_VID):$(USB_BOOT_PID) -r
+
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+default_CONFIG = CONFIG_BOARD_VARIANT=x
+
+#include_HEADERS = $(notdir $(wildcard $(SOURCES_DIR)/*.h))
+
+ifneq ($(CONFIG_BOARD_VARIANT),)
+
+renamed_include_HEADERS = system_def-$(CONFIG_BOARD_VARIANT).h->system_def.h
+
+else
+
+include_HEADERS = system_def.h
+
+endif # CONFIG_BOARD_VARIANT
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ system_def.h - common cover for definition of hardware adresses,
+ registers, timing and other hardware dependant
+ parts of embedded hardware
+
+ Copyright (C) 2001 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002 by PiKRON Ltd. http://www.pikron.com
+
+ *******************************************************************/
+
+#ifndef _SYSTEM_DEF_H_
+#define _SYSTEM_DEF_H_
+
+#include <types.h>
+#include <system_stub.h>
+#include <LPC210x.h>
+#include <bspbase.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define WITH_SFI_SEL
+
+#define VER_CODE(major,minor,patch) (major*0x10000+minor*0x100+patch)
+/* Software version */
+#define SW_VER_ID "UL_HA_2X_RELAY_ACTUATOR"
+#define SW_VER_MAJOR 0
+#define SW_VER_MINOR 2
+#define SW_VER_PATCH 0
+#define SW_VER_CODE VER_CODE(SW_VER_MAJOR,SW_VER_MINOR,SW_VER_PATCH)
+/* Hardware version */
+#define HW_VER_ID "UL_HA_2X_RELAY_ACTUATOR"
+#define HW_VER_MAJOR 1
+#define HW_VER_MINOR 0
+#define HW_VER_PATCH 0
+#define HW_VER_CODE VER_CODE(HW_VER_MAJOR,HW_VER_MINOR,HW_VER_PATCH)
+/* Version of mechanical */
+#define MECH_VER_ID "UL_HA_2X_RELAY_ACTUATOR"
+#define MECH_VER_MAJOR 0
+#define MECH_VER_MINOR 0
+#define MECH_VER_PATCH 0
+#define MECH_VER_CODE VER_CODE(MECH_VER_MAJOR,MECH_VER_MINOR,MECH_VER_PATCH)
+
+
+// PLL setup values are computed within the LPC include file
+// It relies upon the following defines
+#define FOSC (14745600) // Master Oscillator Freq.
+#define PLL_MUL (4) // PLL Multiplier
+#define CCLK (FOSC * PLL_MUL) // CPU Clock Freq.
+
+// Pheripheral Bus Speed Divider
+#define PBSD 1 // MUST BE 1, 2, or 4
+#define PCLK (CCLK / PBSD) // Pheripheal Bus Clock Freq.
+
+#define SYS_TIMER_HZ 1000
+
+#ifndef BIT
+#define BIT(n) (1 << (n))
+#endif
+
+// Port Bit Definitions & Macros: Description - initial conditions
+#define RE2_BIT BIT(0) // used by UART0
+#define RE1_BIT BIT(1) // used by UART0
+#define LED5_BIT BIT(2)
+#define LED4_BIT BIT(3)
+#define LED3_BIT BIT(4)
+#define LED2_BIT BIT(5)
+#define LED1_BIT BIT(6)
+#define P0_07_UNUSED_BIT BIT(7)
+#define TXD1_BIT BIT(8)
+#define RXD1_BIT BIT(9) // used by UART1
+#define RTS1_BIT BIT(10) // used by UART1
+#define CTS1_BIT BIT(11) // used by UART1
+#define DSR1_BIT BIT(12) // used by UART1
+#define P0_13_UNUSED_BIT BIT(13)
+#define BOOT_BIT BIT(14)
+#define IN1_BIT BIT(15)
+#define IN2_BIT BIT(16)
+#define P0_17_UNUSED_BIT BIT(17)
+#define P0_18_UNUSED_BIT BIT(18)
+#define AC_IN_BIT BIT(19)
+#define P0_20_UNUSED_BIT BIT(20)
+#define P0_21_UNUSED_BIT BIT(21)
+#define P0_22_UNUSED_BIT BIT(22)
+#define P0_23_UNUSED_BIT BIT(23)
+#define P0_24_UNUSED_BIT BIT(24)
+#define TEMP_BIT BIT(25)
+#define P0_26_UNUSED_BIT BIT(26)
+#define P0_27_UNUSED_BIT BIT(27)
+#define P0_28_UNUSED_BIT BIT(28)
+#define P0_29_UNUSED_BIT BIT(29)
+#define P0_30_UNUSED_BIT BIT(30)
+#define BUTTON_BIT BIT(31)
+
+
+#define P0IO_INPUT_BITS (uint32_t) ( \
+ BOOT_BIT | \
+ IN1_BIT | \
+ IN2_BIT | \
+ TEMP_BIT | \
+ BUTTON_BIT | \
+ AC_IN_BIT | \
+ 0 )
+
+#define P0IO_ZERO_BITS (uint32_t) ( \
+ RE2_BIT | \
+ RE1_BIT | \
+ LED1_BIT | \
+ LED2_BIT | \
+ LED3_BIT | \
+ LED4_BIT | \
+ LED5_BIT | \
+ P0_07_UNUSED_BIT | \
+ P0_13_UNUSED_BIT | \
+ P0_17_UNUSED_BIT | \
+ P0_18_UNUSED_BIT | \
+ P0_20_UNUSED_BIT | \
+ P0_21_UNUSED_BIT | \
+ P0_22_UNUSED_BIT | \
+ P0_23_UNUSED_BIT | \
+ P0_24_UNUSED_BIT | \
+ P0_26_UNUSED_BIT | \
+ P0_27_UNUSED_BIT | \
+ P0_28_UNUSED_BIT | \
+ P0_29_UNUSED_BIT | \
+ P0_30_UNUSED_BIT | \
+ 0 )
+
+
+
+#define P0IO_ONE_BITS (uint32_t) ( \
+ BOOT_BIT | \
+ 0 )
+
+#define P0IO_OUTPUT_BITS (uint32_t) ( \
+ P0IO_ZERO_BITS | \
+ P0IO_ONE_BITS )
+
+
+/***************************************************************************/
+/* io functions */
+#define LED_GP LED1_BIT /* GENREAL PURPOSE LED */
+#define LED_ERR LED2_BIT
+
+/***************************************************************************/
+/* io functions */
+#define IN_PORT IO0
+#define OUT_PORT IO0
+#define LED_PORT IO0
+
+#define CREATE_PORT_NAME_PIN(port) port##PIN
+#define CREATE_PORT_NAME_CLR(port) port##CLR
+#define CREATE_PORT_NAME_SET(port) port##SET
+
+#define GET_IN_PIN(port,in) ((CREATE_PORT_NAME_PIN(port) & in)?1:0)
+#define SET_OUT_PIN(port,out) (CREATE_PORT_NAME_SET(port)=out)
+#define CLR_OUT_PIN(port,out) (CREATE_PORT_NAME_CLR(port)=out)
+
+/***************************************************************************/
+/* watchdog */
+#define WATCHDOG_ENABLED
+#define WATCHDOG_TIMEOUT_MS 1000
+
+/***************************************************************************/
+/* uLan configuration */
+#ifdef UL_LOG_ENABLE
+ #undef UL_LOG_ENABLE
+#endif
+
+#ifdef ULD_DEFAULT_BUFFER_SIZE
+ #undef ULD_DEFAULT_BUFFER_SIZE
+ #define ULD_DEFAULT_BUFFER_SIZE 0x0400
+#endif
+
+#define UL_DRV_SYSLESS_PORT 0xE0010000
+#define UL_DRV_SYSLESS_BAUD 19200
+#define UL_DRV_SYSLESS_IRQ HAL_INTERRUPT_UART1
+#define UL_DRV_SYSLESS_MY_ADR_DEFAULT 1
+
+
+#define watchdog_feed lpc_watchdog_feed
+#define kvpb_erase lpcisp_kvpb_erase
+#define kvpb_copy lpcisp_kvpb_copy
+#define kvpb_flush lpcisp_kvpb_flush
+#define KVPB_DEFAULT_FLAGS KVPB_DESC_DOUBLE|KVPB_DESC_CHUNKWO
+
+#define HAL_ARM_LPC2XXX_EXTINT_ERRATA
+
+#endif /* _SYSTEM_DEF_H_ */
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ system_def.h - common cover for definition of hardware adresses,
+ registers, timing and other hardware dependant
+ parts of embedded hardware
+
+ Copyright (C) 2001 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002 by PiKRON Ltd. http://www.pikron.com
+
+ *******************************************************************/
+
+#ifndef _SYSTEM_DEF_H_
+#define _SYSTEM_DEF_H_
+
+#include <types.h>
+#include <system_stub.h>
+#include <LPC210x.h>
+#include <bspbase.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define WITH_SFI_SEL
+
+#define VER_CODE(major,minor,patch) (major*0x10000+minor*0x100+patch)
+/* Software version */
+#define SW_VER_ID "UL_HA_SWITCH"
+#define SW_VER_MAJOR 0
+#define SW_VER_MINOR 2
+#define SW_VER_PATCH 0
+#define SW_VER_CODE VER_CODE(SW_VER_MAJOR,SW_VER_MINOR,SW_VER_PATCH)
+/* Hardware version */
+#define HW_VER_ID "UL_HA_SWITCH"
+#define HW_VER_MAJOR 1
+#define HW_VER_MINOR 0
+#define HW_VER_PATCH 0
+#define HW_VER_CODE VER_CODE(HW_VER_MAJOR,HW_VER_MINOR,HW_VER_PATCH)
+/* Version of mechanical */
+#define MECH_VER_ID "UL_HA_SWITCH"
+#define MECH_VER_MAJOR 0
+#define MECH_VER_MINOR 0
+#define MECH_VER_PATCH 0
+#define MECH_VER_CODE VER_CODE(MECH_VER_MAJOR,MECH_VER_MINOR,MECH_VER_PATCH)
+
+
+// PLL setup values are computed within the LPC include file
+// It relies upon the following defines
+#define FOSC (14745600) // Master Oscillator Freq.
+#define PLL_MUL (4) // PLL Multiplier
+#define CCLK (FOSC * PLL_MUL) // CPU Clock Freq.
+
+// Pheripheral Bus Speed Divider
+#define PBSD 1 // MUST BE 1, 2, or 4
+#define PCLK (CCLK / PBSD) // Pheripheal Bus Clock Freq.
+
+#define SYS_TIMER_HZ 1000
+
+#ifndef BIT
+#define BIT(n) (1 << (n))
+#endif
+
+// Port Bit Definitions & Macros: Description - initial conditions
+#define TXD0_BIT BIT(0) // used by UART0
+#define RXD0_BIT BIT(1) // used by UART0
+#define P0_02_UNUSED_BIT BIT(2) // P0.02 unused - low output
+#define OUT2_BIT BIT(3) // P0.03 unused - low output
+#define P0_04_UNUSED_BIT BIT(4) // P0.04 unused - low output
+#define OUT1_BIT BIT(5) // P0.05 unused - low output
+#define IR_BIT BIT(6) // P0.06 unused - low output
+#define SPK_P_BIT BIT(7) // P0.07 unused - low output
+#define TXD1_BIT BIT(8) // used by UART1
+#define RXD1_BIT BIT(9) // used by UART1
+#define RTS1_BIT BIT(10) // used by UART1
+#define CTS1_BIT BIT(11) // used by UART1
+#define DSR1_BIT BIT(12) // used by UART1
+#define LED3_BIT BIT(13) // used by LED
+#define BOOT_BIT BIT(14) // SWITCH
+#define IN1_BIT BIT(15) // P0.15 unused - low output
+#define IN2_BIT BIT(16) // P0.16 unused - low output
+#define P0_17_UNUSED_BIT BIT(17) // P0.17 unused - low output
+#define P0_18_UNUSED_BIT BIT(18) // P0.18 unused - low output
+#define LED4_BIT BIT(19) // used by LED
+#define LED1_BIT BIT(20) // used by LED
+#define LED2_BIT BIT(21) // used by LED
+#define USENSE_BIT BIT(22) // P0.22 unused - low output
+#define SW1_BIT BIT(23) // P0.23 unused - low output
+#define SW3_BIT BIT(24) // P0.24 unused - low output
+#define SW2_BIT BIT(25) // P0.25 unused - low output
+#define SW4_BIT BIT(26) // P0.26 unused - low output
+#define P0_27_UNUSED_BIT BIT(27) // P0.27 unused - low output
+#define P0_28_UNUSED_BIT BIT(28) // P0.28 unused - low output
+#define P0_29_UNUSED_BIT BIT(29) // P0.29 unused - low output
+#define LED5_BIT BIT(30) // P0.30 unused - low output
+#define P0_31_UNUSED_BIT BIT(31) // P0.31 unused - low output
+
+
+#define P0IO_INPUT_BITS (uint32_t) ( \
+ BOOT_BIT | \
+ IR_BIT | \
+ IN1_BIT | \
+ IN2_BIT | \
+ SW1_BIT | \
+ SW2_BIT | \
+ SW3_BIT | \
+ SW4_BIT | \
+ UNSENSE_BIT | \
+ 0 )
+
+#define P0IO_ZERO_BITS (uint32_t) ( \
+ SPK_P_BIT | \
+ OUT1_BIT | \
+ OUT2_BIT | \
+ LED1_BIT | \
+ LED2_BIT | \
+ LED3_BIT | \
+ LED4_BIT | \
+ LED5_BIT | \
+ P0_02_UNUSED_BIT | \
+ P0_04_UNUSED_BIT | \
+ P0_17_UNUSED_BIT | \
+ P0_18_UNUSED_BIT | \
+ P0_27_UNUSED_BIT | \
+ P0_28_UNUSED_BIT | \
+ P0_29_UNUSED_BIT | \
+ P0_31_UNUSED_BIT | \
+ 0 )
+
+
+
+#define P0IO_ONE_BITS (uint32_t) ( \
+ BOOT_BIT | \
+ 0 )
+
+#define P0IO_OUTPUT_BITS (uint32_t) ( \
+ P0IO_ZERO_BITS | \
+ P0IO_ONE_BITS )
+
+
+/***************************************************************************/
+/* io functions */
+#define LED_GP LED1_BIT /* GENREAL PURPOSE LED */
+#define LED_ERR LED2_BIT
+
+/***************************************************************************/
+/* io functions */
+#define IN_PORT IO0
+#define OUT_PORT IO0
+#define LED_PORT IO0
+
+#define CREATE_PORT_NAME_PIN(port) port##PIN
+#define CREATE_PORT_NAME_CLR(port) port##CLR
+#define CREATE_PORT_NAME_SET(port) port##SET
+
+#define GET_IN_PIN(port,in) ((CREATE_PORT_NAME_PIN(port) & in)?1:0)
+#define SET_OUT_PIN(port,out) (CREATE_PORT_NAME_SET(port)=out)
+#define CLR_OUT_PIN(port,out) (CREATE_PORT_NAME_CLR(port)=out)
+
+/***************************************************************************/
+/* watchdog */
+#define WATCHDOG_ENABLED
+#define WATCHDOG_TIMEOUT_MS 1000
+
+/***************************************************************************/
+/* uLan configuration */
+#ifdef UL_LOG_ENABLE
+ #undef UL_LOG_ENABLE
+#endif
+
+#ifdef ULD_DEFAULT_BUFFER_SIZE
+ #undef ULD_DEFAULT_BUFFER_SIZE
+ #define ULD_DEFAULT_BUFFER_SIZE 0x0400
+#endif
+
+#define UL_DRV_SYSLESS_PORT 0xE0010000
+#define UL_DRV_SYSLESS_BAUD 19200
+#define UL_DRV_SYSLESS_IRQ HAL_INTERRUPT_UART1
+#define UL_DRV_SYSLESS_MY_ADR_DEFAULT 1
+
+
+#define watchdog_feed lpc_watchdog_feed
+#define kvpb_erase lpcisp_kvpb_erase
+#define kvpb_copy lpcisp_kvpb_copy
+#define kvpb_flush lpcisp_kvpb_flush
+#define KVPB_DEFAULT_FLAGS KVPB_DESC_DOUBLE|KVPB_DESC_CHUNKWO
+
+#define HAL_ARM_LPC2XXX_EXTINT_ERRATA
+
+/***************************************************************************/
+/* PBMaster configuration */
+#define PBM_8250_PORT 0xE0010000
+#define PBM_8250_BAUD 19200
+#define PBM_8250_IRQ HAL_INTERRUPT_UART1
+
+#endif /* _SYSTEM_DEF_H_ */
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ system_def.h - common cover for definition of hardware adresses,
+ registers, timing and other hardware dependant
+ parts of embedded hardware
+
+ Copyright (C) 2001 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002 by PiKRON Ltd. http://www.pikron.com
+
+ *******************************************************************/
+
+#ifndef _SYSTEM_DEF_H_
+#define _SYSTEM_DEF_H_
+
+#include <types.h>
+#include <system_stub.h>
+#include <LPC214x.h>
+#include <bspbase.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define WITH_SFI_SEL
+
+#define VER_CODE(major,minor,patch) (major*0x10000+minor*0x100+patch)
+/* Software version */
+#define SW_VER_ID "UL_USB"
+#define SW_VER_MAJOR 0
+#define SW_VER_MINOR 2
+#define SW_VER_PATCH 0
+#define SW_VER_CODE VER_CODE(SW_VER_MAJOR,SW_VER_MINOR,SW_VER_PATCH)
+/* Hardware version */
+#define HW_VER_ID "UL_USB"
+#define HW_VER_MAJOR 1
+#define HW_VER_MINOR 0
+#define HW_VER_PATCH 0
+#define HW_VER_CODE VER_CODE(HW_VER_MAJOR,HW_VER_MINOR,HW_VER_PATCH)
+/* Version of mechanical */
+#define MECH_VER_ID "UL_USB"
+#define MECH_VER_MAJOR 0
+#define MECH_VER_MINOR 0
+#define MECH_VER_PATCH 0
+#define MECH_VER_CODE VER_CODE(MECH_VER_MAJOR,MECH_VER_MINOR,MECH_VER_PATCH)
+
+
+// PLL setup values are computed within the LPC include file
+// It relies upon the following defines
+#define FOSC (14745600) // Master Oscillator Freq.
+#define PLL_MUL (4) // PLL Multiplier
+#define CCLK (FOSC * PLL_MUL) // CPU Clock Freq.
+
+// Pheripheral Bus Speed Divider
+#define PBSD 1 // MUST BE 1, 2, or 4
+#define PCLK (CCLK / PBSD) // Pheripheal Bus Clock Freq.
+
+#define SYS_TIMER_HZ 1000
+
+#ifndef BIT
+#define BIT(n) (1 << (n))
+#endif
+
+// Port Bit Definitions & Macros: Description - initial conditions
+#define TXD0_BIT BIT(0) // used by UART0
+#define RXD0_BIT BIT(1) // used by UART0
+#define P0_02_UNUSED_BIT BIT(2) // P0.02 unused - low output
+#define P0_03_UNUSED_BIT BIT(3) // P0.03 unused - low output
+#define P0_04_UNUSED_BIT BIT(4) // P0.04 unused - low output
+#define P0_05_UNUSED_BIT BIT(5) // P0.05 unused - low output
+#define P0_06_UNUSED_BIT BIT(6) // P0.06 unused - low output
+#define P0_07_UNUSED_BIT BIT(7) // P0.07 unused - low output
+#define TXD1_BIT BIT(8) // used by UART1
+#define RXD1_BIT BIT(9) // used by UART1
+#define RTS1_BIT BIT(10) // used by UART1
+#define CTS1_BIT BIT(11) // used by UART1
+#define DSR1_BIT BIT(12) // used by UART1
+#define P0_13_UNUSED_BIT BIT(13) // P0.13 unused - low output
+#define BOOT_BIT BIT(14) // SWITCH
+#define P0_15_UNUSED_BIT BIT(15) // P0.15 unused - low output
+#define P0_16_UNUSED_BIT BIT(16) // P0.16 unused - low output
+#define P0_17_UNUSED_BIT BIT(17) // P0.17 unused - low output
+#define P0_18_UNUSED_BIT BIT(18) // P0.18 unused - low output
+#define P0_19_UNUSED_BIT BIT(19) // P0.19 unused - low output
+#define P0_20_UNUSED_BIT BIT(20) // P0.20 unused - low output
+#define LED1_BIT BIT(21) // used by LED
+#define LED2_BIT BIT(22) // used by LED
+#define P0_23_UNUSED_BIT BIT(23) // P0.23 unused - low output
+#define P0_24_UNUSED_BIT BIT(24) // P0.24 unused - low output
+#define P0_25_UNUSED_BIT BIT(25) // P0.25 unused - low output
+#define P0_26_UNUSED_BIT BIT(26) // P0.26 unused - low output
+#define P0_27_UNUSED_BIT BIT(27) // P0.27 unused - low output
+#define P0_28_UNUSED_BIT BIT(28) // P0.28 unused - low output
+#define P0_29_UNUSED_BIT BIT(29) // P0.29 unused - low output
+#define P0_30_UNUSED_BIT BIT(30) // P0.30 unused - low output
+#define P0_31_UNUSED_BIT BIT(31) // P0.31 unused - low output
+
+
+#define P1_16_UNUSED_BIT BIT(16) // P1.16 unused - low output
+#define P1_17_UNUSED_BIT BIT(17) // P1.17 unused - low output
+#define P1_18_UNUSED_BIT BIT(18) // P1.18 unused - low output
+#define P1_19_UNUSED_BIT BIT(19) // P1.19 unused - low output
+#define P1_20_UNUSED_BIT BIT(20) // P1.20 unused - low output
+#define P1_21_UNUSED_BIT BIT(21) // P1.21 unused - low output
+#define P1_22_UNUSED_BIT BIT(22) // P1.22 unused - low output
+#define P1_23_UNUSED_BIT BIT(23) // P1.23 unused - low output
+#define P1_24_UNUSED_BIT BIT(24) // P1.24 unused - low output
+#define P1_25_UNUSED_BIT BIT(25) // P1.25 unused - low output
+#define P1_26_GATE BIT(26) // used by JTAG
+#define P1_27_UNUSED_BIT BIT(27) // used by JTAG
+#define P1_28_UNUSED_BIT BIT(28) // used by JTAG
+#define P1_29_UNUSED_BIT BIT(29) // used by JTAG
+#define P1_30_DOOR_CLOSE BIT(30) // used by JTAG
+#define P1_31_DOOR_OPEN BIT(31) // used by JTAG
+
+#define P0IO_INPUT_BITS (uint32_t) ( \
+ BOOT_BIT | \
+ 0 )
+
+#define P1IO_INPUT_BITS (uint32_t) ( \
+ P1_30_DOOR_OPEN | \
+ P1_31_DOOR_CLOSE | \
+ 0 )
+
+#define P0IO_ZERO_BITS (uint32_t) ( \
+ P0_02_UNUSED_BIT | \
+ P0_03_UNUSED_BIT | \
+ P0_04_UNUSED_BIT | \
+ P0_05_UNUSED_BIT | \
+ P0_06_UNUSED_BIT | \
+ P0_07_UNUSED_BIT | \
+ P0_13_UNUSED_BIT | \
+ P0_15_UNUSED_BIT | \
+ P0_16_UNUSED_BIT | \
+ P0_17_UNUSED_BIT | \
+ P0_18_UNUSED_BIT | \
+ P0_19_UNUSED_BIT | \
+ P0_20_UNUSED_BIT | \
+ P0_23_UNUSED_BIT | \
+ P0_24_UNUSED_BIT | \
+ P0_25_UNUSED_BIT | \
+ P0_26_UNUSED_BIT | \
+ P0_27_UNUSED_BIT | \
+ P0_28_UNUSED_BIT | \
+ P0_29_UNUSED_BIT | \
+ P0_30_UNUSED_BIT | \
+ P0_31_UNUSED_BIT | \
+ 0 )
+
+#define P1IO_ZERO_BITS (uint32_t) ( \
+ P1_16_UNUSED_BIT | \
+ P1_17_UNUSED_BIT | \
+ P1_18_UNUSED_BIT | \
+ P1_19_UNUSED_BIT | \
+ P1_20_UNUSED_BIT | \
+ P1_21_UNUSED_BIT | \
+ P1_22_UNUSED_BIT | \
+ P1_23_UNUSED_BIT | \
+ P1_24_UNUSED_BIT | \
+ P1_25_UNUSED_BIT | \
+ P1_27_UNUSED_BIT | \
+ P1_28_UNUSED_BIT | \
+ P1_29_UNUSED_BIT | \
+ 0 )
+
+
+#define P0IO_ONE_BITS (uint32_t) ( \
+ LED1_BIT | \
+ BOOT_BIT | \
+ LED2_BIT | \
+ 0 )
+
+#define P1IO_ONE_BITS (uint32_t) ( \
+ P1_26_GATE | \
+ 0 )
+
+#define P0IO_OUTPUT_BITS (uint32_t) ( \
+ P0IO_ZERO_BITS | \
+ P0IO_ONE_BITS )
+
+#define P1IO_OUTPUT_BITS (uint32_t) ( \
+ P1IO_ZERO_BITS | \
+ P1IO_ONE_BITS )
+
+
+/***************************************************************************/
+/* io functions */
+#define LED_GP LED1_BIT /* GENREAL PURPOSE LED */
+#define LED_ERR LED2_BIT
+
+#define LED_YELLOW LED1_BIT
+#define LED_RED LED2_BIT
+
+/***************************************************************************/
+/* io functions */
+#define KBD_PORT IO1
+#define IN_PORT IO0
+#define LED_PORT IO0
+#define OUT_PORT IO1
+
+#define CREATE_PORT_NAME_PIN(port) port##PIN
+#define CREATE_PORT_NAME_CLR(port) port##CLR
+#define CREATE_PORT_NAME_SET(port) port##SET
+
+#define GET_IN_PIN(port,in) ((CREATE_PORT_NAME_PIN(port) & in)?1:0)
+#define SET_OUT_PIN(port,out) (CREATE_PORT_NAME_SET(port)=out)
+#define CLR_OUT_PIN(port,out) (CREATE_PORT_NAME_CLR(port)=out)
+
+/***************************************************************************/
+/* watchdog */
+#define WATCHDOG_ENABLED
+#define WATCHDOG_TIMEOUT_MS 1000
+
+/***************************************************************************/
+/* uLan configuration */
+#ifdef UL_LOG_ENABLE
+ #undef UL_LOG_ENABLE
+#endif
+
+#ifdef ULD_DEFAULT_BUFFER_SIZE
+ #undef ULD_DEFAULT_BUFFER_SIZE
+ #define ULD_DEFAULT_BUFFER_SIZE 0x0800
+#endif
+
+#define UL_DRV_SYSLESS_PORT 0xE0010000
+#define UL_DRV_SYSLESS_BAUD 19200
+#define UL_DRV_SYSLESS_IRQ HAL_INTERRUPT_UART1
+#define UL_DRV_SYSLESS_MY_ADR_DEFAULT 1
+
+#define watchdog_feed lpc_watchdog_feed
+#define kvpb_erase lpcisp_kvpb_erase
+#define kvpb_copy lpcisp_kvpb_copy
+#define kvpb_flush lpcisp_kvpb_flush
+#define KVPB_DEFAULT_FLAGS KVPB_DESC_DOUBLE|KVPB_DESC_CHUNKWO
+
+#define HAL_ARM_LPC2XXX_EXTINT_ERRATA
+
+#endif /* _SYSTEM_DEF_H_ */
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ system_def.h - common cover for definition of hardware adresses,
+ registers, timing and other hardware dependant
+ parts of embedded hardware
+
+ Copyright (C) 2001 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002 by PiKRON Ltd. http://www.pikron.com
+
+ *******************************************************************/
+
+#ifndef _SYSTEM_DEF_H_
+#define _SYSTEM_DEF_H_
+
+#include <types.h>
+#include <system_stub.h>
+#include <LPC214x.h>
+#include <bspbase.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define WITH_SFI_SEL
+
+#define VER_CODE(major,minor,patch) (major*0x10000+minor*0x100+patch)
+/* Software version */
+#define SW_VER_ID "UL_USB"
+#define SW_VER_MAJOR 0
+#define SW_VER_MINOR 2
+#define SW_VER_PATCH 0
+#define SW_VER_CODE VER_CODE(SW_VER_MAJOR,SW_VER_MINOR,SW_VER_PATCH)
+/* Hardware version */
+#define HW_VER_ID "UL_USB"
+#define HW_VER_MAJOR 1
+#define HW_VER_MINOR 0
+#define HW_VER_PATCH 0
+#define HW_VER_CODE VER_CODE(HW_VER_MAJOR,HW_VER_MINOR,HW_VER_PATCH)
+/* Version of mechanical */
+#define MECH_VER_ID "UL_USB"
+#define MECH_VER_MAJOR 0
+#define MECH_VER_MINOR 0
+#define MECH_VER_PATCH 0
+#define MECH_VER_CODE VER_CODE(MECH_VER_MAJOR,MECH_VER_MINOR,MECH_VER_PATCH)
+
+
+// PLL setup values are computed within the LPC include file
+// It relies upon the following defines
+#define FOSC (14745600) // Master Oscillator Freq.
+#define PLL_MUL (4) // PLL Multiplier
+#define CCLK (FOSC * PLL_MUL) // CPU Clock Freq.
+
+// Pheripheral Bus Speed Divider
+#define PBSD 1 // MUST BE 1, 2, or 4
+#define PCLK (CCLK / PBSD) // Pheripheal Bus Clock Freq.
+
+#define SYS_TIMER_HZ 1000
+
+#ifndef BIT
+#define BIT(n) (1 << (n))
+#endif
+
+// Port Bit Definitions & Macros: Description - initial conditions
+#define TXD0_BIT BIT(0) // used by UART0
+#define RXD0_BIT BIT(1) // used by UART0
+#define P0_02_UNUSED_BIT BIT(2) // P0.02 unused - low output
+#define P0_03_UNUSED_BIT BIT(3) // P0.03 unused - low output
+#define P0_04_UNUSED_BIT BIT(4) // P0.04 unused - low output
+#define P0_05_UNUSED_BIT BIT(5) // P0.05 unused - low output
+#define IP1_BIT BIT(6) // P0.06 unused - low output
+#define IP2_BIT BIT(7) // P0.07 unused - low output
+#define TXD1_BIT BIT(8) // used by UART1
+#define RXD1_BIT BIT(9) // used by UART1
+#define RTS1_BIT BIT(10) // used by UART1
+#define CTS1_BIT BIT(11) // used by UART1
+#define DSR1_BIT BIT(12) // used by UART1
+#define P0_13_UNUSED_BIT BIT(13) // P0.13 unused - low output
+#define BOOT_BIT BIT(14) // SWITCH
+#define P0_15_UNUSED_BIT BIT(15) // P0.15 unused - low output
+#define P0_16_UNUSED_BIT BIT(16) // P0.16 unused - low output
+#define P0_17_UNUSED_BIT BIT(17) // P0.17 unused - low output
+#define P0_18_UNUSED_BIT BIT(18) // P0.18 unused - low output
+#define P0_19_UNUSED_BIT BIT(19) // P0.19 unused - low output
+#define P0_20_UNUSED_BIT BIT(20) // P0.20 unused - low output
+#define LED1_BIT BIT(21) // used by LED
+#define LED2_BIT BIT(22) // used by LED
+#define P0_23_UNUSED_BIT BIT(23) // P0.23 unused - low output
+#define P0_24_UNUSED_BIT BIT(24) // P0.24 unused - low output
+#define P0_25_UNUSED_BIT BIT(25) // P0.25 unused - low output
+#define P0_26_UNUSED_BIT BIT(26) // P0.26 unused - low output
+#define P0_27_UNUSED_BIT BIT(27) // P0.27 unused - low output
+#define P0_28_UNUSED_BIT BIT(28) // P0.28 unused - low output
+#define P0_29_SOUND BIT(29) // P0.29 unused - low output
+#define P0_30_LED_R BIT(30) // P0.30 unused - low output
+#define P0_31_LED_G BIT(31) // P0.31 unused - low output
+
+
+#define P1_16_RELE BIT(16) // P1.16 unused - low output
+#define P1_17_UNUSED_BIT BIT(17) // P1.17 unused - low output
+#define P1_18_UNUSED_BIT BIT(18) // P1.18 unused - low output
+#define P1_19_UNUSED_BIT BIT(19) // P1.19 unused - low output
+#define P1_20_UNUSED_BIT BIT(20) // P1.20 unused - low output
+#define P1_21_UNUSED_BIT BIT(21) // P1.21 unused - low output
+#define P1_22_UNUSED_BIT BIT(22) // P1.22 unused - low output
+#define P1_23_UNUSED_BIT BIT(23) // P1.23 unused - low output
+#define P1_24_COL369H BIT(24) // P1.24 unused - low output
+#define P1_25_COL2580 BIT(25) // P1.25 unused - low output
+#define P1_26_COL147S BIT(26) // used by JTAG
+#define P1_27_ROW123 BIT(27) // used by JTAG
+#define P1_28_ROW456 BIT(28) // used by JTAG
+#define P1_29_ROW789 BIT(29) // used by JTAG
+#define P1_30_ROWS0H BIT(30) // used by JTAG
+#define P1_31_RING BIT(31) // used by JTAG
+
+#define P0IO_INPUT_BITS (uint32_t) ( \
+ BOOT_BIT | \
+ IP1_BIT | \
+ IP2_BIT | \
+ 0 )
+
+#define P1IO_INPUT_BITS (uint32_t) ( \
+ P1_27_ROW123 | \
+ P1_28_ROW456 | \
+ P1_29_ROW789 | \
+ P1_30_ROWS0H | \
+ P1_31_RING | \
+ 0 )
+
+#define P0IO_ZERO_BITS (uint32_t) ( \
+ P0_02_UNUSED_BIT | \
+ P0_03_UNUSED_BIT | \
+ P0_04_UNUSED_BIT | \
+ P0_05_UNUSED_BIT | \
+ P0_13_UNUSED_BIT | \
+ P0_15_UNUSED_BIT | \
+ P0_16_UNUSED_BIT | \
+ P0_17_UNUSED_BIT | \
+ P0_18_UNUSED_BIT | \
+ P0_19_UNUSED_BIT | \
+ P0_20_UNUSED_BIT | \
+ P0_23_UNUSED_BIT | \
+ P0_24_UNUSED_BIT | \
+ P0_25_UNUSED_BIT | \
+ P0_26_UNUSED_BIT | \
+ P0_27_UNUSED_BIT | \
+ P0_28_UNUSED_BIT | \
+ P0_29_SOUND | \
+ 0 )
+
+#define P1IO_ZERO_BITS (uint32_t) ( \
+ P1_16_RELE | \
+ P1_17_UNUSED_BIT | \
+ P1_18_UNUSED_BIT | \
+ P1_19_UNUSED_BIT | \
+ P1_20_UNUSED_BIT | \
+ P1_21_UNUSED_BIT | \
+ P1_22_UNUSED_BIT | \
+ P1_23_UNUSED_BIT | \
+ 0 )
+
+
+#define P0IO_ONE_BITS (uint32_t) ( \
+ LED1_BIT | \
+ BOOT_BIT | \
+ LED2_BIT | \
+ P0_30_LED_R | \
+ P0_31_LED_G | \
+ 0 )
+
+#define P1IO_ONE_BITS (uint32_t) ( \
+ P1_24_COL369H | \
+ P1_25_COL2580 | \
+ P1_26_COL147S | \
+ 0 )
+
+#define P0IO_OUTPUT_BITS (uint32_t) ( \
+ P0IO_ZERO_BITS | \
+ P0IO_ONE_BITS )
+
+#define P1IO_OUTPUT_BITS (uint32_t) ( \
+ P1IO_ZERO_BITS | \
+ P1IO_ONE_BITS )
+
+
+/***************************************************************************/
+/* io functions */
+#define LED_GP LED1_BIT /* GENREAL PURPOSE LED */
+#define LED_ERR LED2_BIT
+
+#define LED_YELLOW LED1_BIT
+#define LED_RED LED2_BIT
+#define LED_KEYPAD_RED P0_30_LED_R
+#define LED_KEYPAD_YELLOW P0_31_LED_G
+
+/***************************************************************************/
+/* io functions */
+#define KBD_PORT IO1
+#define IN_PORT IO0
+#define LED_PORT IO0
+#define OUT_PORT IO1
+
+#define CREATE_PORT_NAME_PIN(port) port##PIN
+#define CREATE_PORT_NAME_CLR(port) port##CLR
+#define CREATE_PORT_NAME_SET(port) port##SET
+
+#define GET_IN_PIN(port,in) ((CREATE_PORT_NAME_PIN(port) & in)?1:0)
+#define SET_OUT_PIN(port,out) (CREATE_PORT_NAME_SET(port)=out)
+#define CLR_OUT_PIN(port,out) (CREATE_PORT_NAME_CLR(port)=out)
+
+/***************************************************************************/
+/* watchdog */
+#define WATCHDOG_ENABLED
+#define WATCHDOG_TIMEOUT_MS 1000
+
+/***************************************************************************/
+/* uLan configuration */
+#ifdef UL_LOG_ENABLE
+ #undef UL_LOG_ENABLE
+#endif
+
+#ifdef ULD_DEFAULT_BUFFER_SIZE
+ #undef ULD_DEFAULT_BUFFER_SIZE
+ #define ULD_DEFAULT_BUFFER_SIZE 0x0800
+#endif
+
+#define UL_DRV_SYSLESS_PORT 0xE0010000
+#define UL_DRV_SYSLESS_BAUD 19200
+#define UL_DRV_SYSLESS_IRQ HAL_INTERRUPT_UART1
+#define UL_DRV_SYSLESS_MY_ADR_DEFAULT 1
+
+#define watchdog_feed lpc_watchdog_feed
+#define kvpb_erase lpcisp_kvpb_erase
+#define kvpb_copy lpcisp_kvpb_copy
+#define kvpb_flush lpcisp_kvpb_flush
+#define KVPB_DEFAULT_FLAGS KVPB_DESC_DOUBLE|KVPB_DESC_CHUNKWO
+
+#define HAL_ARM_LPC2XXX_EXTINT_ERRATA
+
+/***************************************************************************/
+/* kbd */
+#define KEY_TIMER sys_timer_ticks
+#define KBDDEVICE void
+
+typedef unsigned short kbd_key_t;
+typedef unsigned int kbd_keymod_t;
+typedef long kbd_interval_t;
+typedef unsigned short kbd_scan_code_t;
+
+#define KEY_DEFAULT_TIMES
+#define KEY_PUSH_T 70
+#define KEY_RELEASE_T 50
+#define KEY_REPFIRST_T 60000
+#define KEY_REPNEXT_T 300
+
+#define KBD_DR _reg_PTD_DR
+#define KBD_SSR IO1PIN
+#define KBD_DDIR _reg_PTD_DDIR
+#define KBD_PUEN _reg_PTD_PUEN
+
+typedef unsigned long kbdisr_lock_level_t;
+#define kbdisr_lock save_and_cli
+#define kbdisr_unlock restore_flags
+
+#define KBD_SCAN_CNT 3
+#define KBD_SCAN_BIT0 24
+#define KBD_RET_CNT 5
+#define KBD_RET_BIT0 27
+
+#define KBD_SCAN_MASK (((1<<KBD_SCAN_CNT)-1)<<KBD_SCAN_BIT0)
+#define KBD_RET_MASK (((1<<KBD_RET_CNT)-1)<<KBD_RET_BIT0)
+
+#define KBD_USE_IO_SETCLR_OPS
+
+#endif /* _SYSTEM_DEF_H_ */
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ system_def.h - common cover for definition of hardware adresses,
+ registers, timing and other hardware dependant
+ parts of embedded hardware
+
+ Copyright (C) 2001 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002 by PiKRON Ltd. http://www.pikron.com
+
+ *******************************************************************/
+
+#ifndef _SYSTEM_DEF_H_
+#define _SYSTEM_DEF_H_
+
+#include <types.h>
+#include <system_stub.h>
+#include <LPC214x.h>
+#include <bspbase.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define WITH_SFI_SEL
+
+#define VER_CODE(major,minor,patch) (major*0x10000+minor*0x100+patch)
+/* Software version */
+#define SW_VER_ID "UL_USB"
+#define SW_VER_MAJOR 0
+#define SW_VER_MINOR 2
+#define SW_VER_PATCH 0
+#define SW_VER_CODE VER_CODE(SW_VER_MAJOR,SW_VER_MINOR,SW_VER_PATCH)
+/* Hardware version */
+#define HW_VER_ID "UL_USB"
+#define HW_VER_MAJOR 1
+#define HW_VER_MINOR 0
+#define HW_VER_PATCH 0
+#define HW_VER_CODE VER_CODE(HW_VER_MAJOR,HW_VER_MINOR,HW_VER_PATCH)
+/* Version of mechanical */
+#define MECH_VER_ID "UL_USB"
+#define MECH_VER_MAJOR 0
+#define MECH_VER_MINOR 0
+#define MECH_VER_PATCH 0
+#define MECH_VER_CODE VER_CODE(MECH_VER_MAJOR,MECH_VER_MINOR,MECH_VER_PATCH)
+
+
+// PLL setup values are computed within the LPC include file
+// It relies upon the following defines
+//#define FOSC (11059200) // Master Oscillator Freq.
+#define FOSC (12000000) // Master Oscillator Freq.
+#define PLL_MUL (4) // PLL Multiplier
+#define CCLK (FOSC * PLL_MUL) // CPU Clock Freq.
+
+// Pheripheral Bus Speed Divider
+#define PBSD 1 // MUST BE 1, 2, or 4
+#define PCLK (CCLK / PBSD) // Pheripheal Bus Clock Freq.
+
+#define SYS_TIMER_HZ 1000
+
+#ifndef BIT
+#define BIT(n) (1 << (n))
+#endif
+
+// Port Bit Definitions & Macros: Description - initial conditions
+#define TXD0_BIT BIT(0) // used by UART0
+#define RXD0_BIT BIT(1) // used by UART0
+#define P0_SCL0_PIN BIT(2) // I2C 0 SCL
+#define P0_SDA0_PIN BIT(3) // I2C 0 SDA
+#define P0_SCK0_PIN BIT(4) // SPI0 clocks
+#define P0_MISO0_PIN BIT(5) // SPI0 master input
+#define P0_MOSI0_PIN BIT(6) // SPI0 master output
+#define P0_SSEL0_PIN BIT(7) // SPI0 external select/ADS1218 DRDY
+#define TXD1_BIT BIT(8) // used by UART1
+#define RXD1_BIT BIT(9) // used by UART1
+#define RTS1_BIT BIT(10) // used by UART1
+#define CTS1_BIT BIT(11) // used by UART1
+#define DSR1_BIT BIT(12) // used by UART1
+#define LED2_BIT BIT(13) // used by LED
+#define BOOT_BIT BIT(14) // SWITCH
+#define LED1_BIT BIT(15) // used by LED
+#define P0_SWITCH1_PIN BIT(16) // pin connected to the switch 1
+#define P0_SCK1_PIN BIT(17) // SPI1 clocks
+#define P0_MISO1_PIN BIT(18) // SPI1 master input
+#define P0_MOSI1_PIN BIT(19) // SPI1 master output
+#define P0_SSEL1_PIN BIT(20) // SPI1 slave select/25VF016 chipselect
+#define P0_21_UNUSED_BIT BIT(21) // P0.21 unused - low output
+#define P0_22_UNUSED_BIT BIT(22) // P0.22 unused - low output
+#define P0_SJA1000_ALE_PIN BIT(23) // SJA1000 ALE
+#define P0_24_UNUSED_BIT BIT(24) // P0.24 unused - low output
+#define P0_SJA1000_CS_PIN BIT(25) // SJA1000 CS
+#define P0_26_UNUSED_BIT BIT(26) // P0.26 unused - low output
+#define P0_27_UNUSED_BIT BIT(27) // P0.27 unused - low output
+#define P0_SJA1000_RD_PIN BIT(28) // SJA1000 RD
+#define P0_SJA1000_WR_PIN BIT(29) // SJA1000 WR
+#define P0_SJA1000_INT_PIN BIT(30) // SJA1000 INT
+#define P0_USB_CONNECT_PIN BIT(31) // USB Connect Control
+
+#define P1_SJA1000_D0_PIN BIT(16) // SJA1000 D0
+#define P1_SJA1000_D1_PIN BIT(17) // SJA1000 D1
+#define P1_SJA1000_D2_PIN BIT(18) // SJA1000 D2
+#define P1_SJA1000_D3_PIN BIT(19) // SJA1000 D3
+#define P1_SJA1000_D4_PIN BIT(20) // SJA1000 D4
+#define P1_SJA1000_D5_PIN BIT(21) // SJA1000 D5
+#define P1_SJA1000_D6_PIN BIT(22) // SJA1000 D6
+#define P1_SJA1000_D7_PIN BIT(23) // SJA1000 D7
+#define P1_OUT_PORT_CS_PIN BIT(24) // Chip select for 74HC574 chip
+#define P1_SJA1000_RST_PIN BIT(25) // SJA1000 RST
+#define P1_26_UNUSED_BIT BIT(26) // used by JTAG
+#define P1_27_UNUSED_BIT BIT(27) // used by JTAG
+#define P1_28_UNUSED_BIT BIT(28) // used by JTAG
+#define P1_29_UNUSED_BIT BIT(29) // used by JTAG
+#define P1_30_UNUSED_BIT BIT(30) // used by JTAG
+#define P1_31_UNUSED_BIT BIT(31) // used by JTAG
+
+#define P1_SJA1000_DATA_PINS (uint32_t) ( \
+ P1_SJA1000_D0_PIN | \
+ P1_SJA1000_D1_PIN | \
+ P1_SJA1000_D2_PIN | \
+ P1_SJA1000_D3_PIN | \
+ P1_SJA1000_D4_PIN | \
+ P1_SJA1000_D5_PIN | \
+ P1_SJA1000_D6_PIN | \
+ P1_SJA1000_D7_PIN | \
+ 0 )
+
+#define P0IO_INPUT_BITS (uint32_t) ( \
+ P0_SCL0_PIN | \
+ P0_SDA0_PIN | \
+ P0_MISO0_PIN | \
+ P0_SSEL0_PIN | \
+ P0_MISO1_PIN | \
+ BOOT_BIT | \
+ P0_SWITCH1_PIN | \
+ P0_SJA1000_INT_PIN | \
+ 0 )
+
+#define P1IO_INPUT_BITS (uint32_t) ( \
+ P1_26_UNUSED_BIT | \
+ P1_27_UNUSED_BIT | \
+ P1_28_UNUSED_BIT | \
+ P1_29_UNUSED_BIT | \
+ P1_30_UNUSED_BIT | \
+ P1_31_UNUSED_BIT | \
+ 0 )
+
+#define P0IO_ZERO_BITS (uint32_t) ( \
+ P0_21_UNUSED_BIT | \
+ P0_22_UNUSED_BIT | \
+ P0_24_UNUSED_BIT | \
+ P0_26_UNUSED_BIT | \
+ P0_27_UNUSED_BIT | \
+ P0_USB_CONNECT_PIN | \
+ 0 )
+
+#define P1IO_ZERO_BITS (uint32_t) ( \
+ P1_SJA1000_DATA_PINS | \
+ P1_SJA1000_RST_PIN | \
+ 0 )
+
+
+#define P0IO_ONE_BITS (uint32_t) ( \
+ P0_SCK0_PIN | \
+ P0_MOSI0_PIN | \
+ LED1_BIT | \
+ BOOT_BIT | \
+ LED2_BIT | \
+ P0_SCK1_PIN | \
+ P0_MOSI1_PIN | \
+ P0_SSEL1_PIN | \
+ P0_SJA1000_ALE_PIN | \
+ P0_SJA1000_CS_PIN | \
+ P0_SJA1000_RD_PIN | \
+ P0_SJA1000_WR_PIN | \
+ 0 )
+
+#define P1IO_ONE_BITS (uint32_t) ( \
+ P1_OUT_PORT_CS_PIN | \
+ 0 )
+
+#define P0IO_OUTPUT_BITS (uint32_t) ( \
+ P0IO_ZERO_BITS | \
+ P0IO_ONE_BITS )
+
+#define P1IO_OUTPUT_BITS (uint32_t) ( \
+ P1IO_ZERO_BITS | \
+ P1IO_ONE_BITS )
+
+/***************************************************************************/
+/* io functions */
+#define LED_GP LED1_BIT /* GENREAL PURPOSE LED */
+#define LED_ERR LED2_BIT
+
+#define LED_YELLOW LED1_BIT
+#define LED_RED LED2_BIT
+
+/***************************************************************************/
+/* io functions */
+#define IN_PORT IO0
+#define LED_PORT IO0
+#define OUT_PORT IO1
+
+#define CREATE_PORT_NAME_PIN(port) port##PIN
+#define CREATE_PORT_NAME_CLR(port) port##CLR
+#define CREATE_PORT_NAME_SET(port) port##SET
+
+#define GET_IN_PIN(port,in) ((CREATE_PORT_NAME_PIN(port) & in)?1:0)
+#define SET_OUT_PIN(port,out) (CREATE_PORT_NAME_SET(port)=out)
+#define CLR_OUT_PIN(port,out) (CREATE_PORT_NAME_CLR(port)=out)
+
+/***************************************************************************/
+/* watchdog */
+//#define WATCHDOG_ENABLED
+#define WATCHDOG_TIMEOUT_MS 1000
+
+/***************************************************************************/
+/* uLan configuration */
+
+#ifdef UL_LOG_ENABLE
+ #undef UL_LOG_ENABLE
+#endif
+
+#ifdef ULD_DEFAULT_BUFFER_SIZE
+ #undef ULD_DEFAULT_BUFFER_SIZE
+ #define ULD_DEFAULT_BUFFER_SIZE 0x0800
+#endif
+
+#define UL_DRV_SYSLESS_PORT 0xE0010000
+#define UL_DRV_SYSLESS_BAUD 19200
+#define UL_DRV_SYSLESS_IRQ HAL_INTERRUPT_UART1
+#define UL_DRV_SYSLESS_MY_ADR_DEFAULT 1
+
+#define watchdog_feed lpc_watchdog_feed
+#define kvpb_erase lpcisp_kvpb_erase
+#define kvpb_copy lpcisp_kvpb_copy
+#define kvpb_flush lpcisp_kvpb_flush
+#define KVPB_DEFAULT_FLAGS KVPB_DESC_DOUBLE|KVPB_DESC_CHUNKWO
+
+/***************************************************************************/
+/* USB configuration */
+#define USB_WITH_UDEV_FNC
+#define USB_EP_NUM 32
+#define USB_MAX_PACKET0 64
+#define USB_MAX_PACKET 8
+#define USB_DMA_EP 0x00000000
+
+/***************************************************************************/
+/* i2c0 configuration */
+#define I2C_DRV_SYSLESS_IRQ HAL_INTERRUPT_I2C0
+#define I2C_DRV_SYSLESS_PORT 0xE001C000
+#define I2C_DRV_SYSLESS_BITRATE 100000
+#define I2C_DRV_SYSLESS_SLADR 0
+
+/***************************************************************************/
+/* Constants for JTAG and supply control port pins: */
+#define JTAGIN (IO0PIN) // Control ports are on P5.x
+#define JTAGSET (IO0SET)
+#define JTAGCLR (IO0CLR)
+#define JTAGDIR (IO0DIR)
+#define JTAGOUT_RDBACK (IO0PIN) // used to read actual TCLK output value
+#undef JTAGSEL
+#define TMS_PIN (1<<20) // P0.20 JTAG TMS input pin
+#define TDI_PIN (1<<19) // P0.19 JTAG TDI input pin (SIMO1 if SPI mode)
+#define TDO_PIN (1<<18) // P0.18 JTAG TDO output pin (SOMI1 if SPI mode)
+#define TCK_PIN (1<<17) // P0.17 JTAG TCK input pin (UCLK1 if SPI mode)
+#define TDICTRL2_PIN 0 // Px.x switch TDO to TDI
+#define TDICTRL1_PIN 0 // Px.x connects TDI
+#define TEST_PIN 0 // Px.x TEST pin (20 & 28-pin devices only)
+#define VCCTGT_PIN 0 // Px.x Supply voltage of target board
+#define TCLK_PIN TDI_PIN // P7.3 TDI (former XOUT) receives TCLK
+
+#define ClrTMS() do {(JTAGCLR) |= (TMS_PIN);} while(0);
+#define SetTMS() do {(JTAGSET) |= (TMS_PIN);} while(0);
+#define ClrTDI() do {(JTAGCLR) |= (TDI_PIN);} while(0);
+#define SetTDI() do {(JTAGSET) |= (TDI_PIN);} while(0);
+#define ClrTCK() do {(JTAGCLR) |= (TCK_PIN);} while(0);
+#define SetTCK() do {(JTAGSET) |= (TCK_PIN);} while(0);
+#define ClrTCLK() do {(JTAGCLR) |= (TCLK_PIN);} while(0);
+#define SetTCLK() do {(JTAGSET) |= (TCLK_PIN);} while(0);
+#define StoreTCLK() ((JTAGOUT_RDBACK & TCLK_PIN) ? 1:0)
+#define RestoreTCLK(x) (x == 0 ? (JTAGCLR |= TCLK_PIN) : (JTAGSET |= TCLK_PIN))
+#define ScanTDO() ((JTAGIN & TDO_PIN)) // assumes TDO to be bit0
+
+#define JTAG_IODELAY() __asm__ __volatile__ ("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n": : )
+
+/****************************************************************************/
+/* Define section for user, related to the controller used (here MSP430F149)*/
+/****************************************************************************/
+
+// Constants for Error LED control port:
+#define JTAGLEDSET (IO0SET) // LED ports are P0.x
+#define JTAGLEDCLR (IO0CLR) // LED ports are P0.x
+#define JTAGLEDDIR (IO0DIR)
+#undef JTAGLEDSEL /*P1SEL*/
+#define JTAGLEDRED (1<<13) // P0.13 Red LED (ERROR)
+#define JTAGLEDGREEN (1<<15) // P0.15 Green LED (OK)
+
+/***************************************************************************/
+/* PBMaster configuration */
+#define PBM_8250_PORT 0xE0010000
+#define PBM_8250_BAUD 19200
+#define PBM_8250_IRQ HAL_INTERRUPT_UART1
+
+#endif /* _SYSTEM_DEF_H_ */
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+SUBDIRS = bspbase ldscripts
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+default_CONFIG += CONFIG_OC_UL_DRV_SYSLESS=x
+default_CONFIG += CONFIG_OC_IC_DRV_SYSLESS=x
+default_CONFIG += CONFIG_KEYVAL=x
+default_CONFIG += CONFIG_STDIO_COM_PORT=x
+default_CONFIG += CONFIG_OC_UL_DRV_U450_VARPINS=x
+default_CONFIG += CONFIG_OC_UL_DRV_U450_VARPINS_MSRSWAP=x
+default_CONFIG += CONFIG_OC_UL_DRV_U450_VARPINS_DIRNEG=x
+default_CONFIG += CONFIG_OC_I2C_DRV_SYSLESS=x
+default_CONFIG += CONFIG_OC_PBM_DRV=x
+
+LOCAL_CONFIG_H = local_config.h
+
+INCLUDES += -I .
+
+include_HEADERS = bspbase.h
+
+lib_LIBRARIES = bspbase
+
+bspbase_SOURCES = bsp0hwinit.c
+
+ifneq ($(CONFIG_STDIO_COM_PORT),)
+bspbase_SOURCES += uart.c
+endif #CONFIG_STDIO_COM_PORT
+
+ifeq ($(CONFIG_KBD),y)
+bspbase_SOURCES += kbd_io_hisc.c
+endif #CONFIG_KBD
\ No newline at end of file
--- /dev/null
+#include "local_config.h"
+#include <system_def.h>
+#ifdef CONFIG_KEYVAL
+ #include <keyvalpb.h>
+ #include <lpciap.h>
+ #include <lpciap_kvpb.h>
+#endif /* CONFIG_KEYVAL */
+#ifdef CONFIG_STDIO_COM_PORT
+ #include <uart.h>
+#endif
+#ifdef CONFIG_OC_UL_DRV_SYSLESS
+ #include <ul_lib/ulan.h>
+ #include <string.h>
+ #include <ul_drv_init.h>
+ #include <ul_drv_iac.h>
+ #include <ul_lib/ul_drvdef.h>
+ extern long int uld_jiffies;
+#endif /* CONFIG_OC_UL_DRV_SYSLESS */
+#ifdef CONFIG_OC_I2C_DRV_SYSLESS
+ #include <i2c_drv.h>
+#endif /* CONFIG_OC_I2C_DRV_SYSLESS */
+#ifdef CONFIG_OC_PBM_DRV
+ #include <pbmcore.h>
+ #include <pbm_8250.h>
+ #include <pbm_drv_init.h>
+#endif /* CONFIG_OC_PBM_DRV */
+#include <hal_machperiph.h>
+#include <hal_intr.h>
+
+/* timers */
+volatile lt_ticks_t sys_timer_ticks;
+
+#ifdef CONFIG_OC_I2C_DRV_SYSLESS
+#define I2C_DRV_NA_MSTIMEOUT 10
+i2c_drv_t i2c_drv;
+int i2c_drv_na_timer=0;
+#endif /* CONFIG_OC_I2C_DRV_SYSLESS */
+
+static void sysInit(void)
+{
+
+ system_clock_init();
+
+ // setup the parallel port pin
+ IO0CLR = P0IO_ZERO_BITS; // clear the ZEROs output
+ IO0SET = P0IO_ONE_BITS; // set the ONEs output
+ IO0DIR = P0IO_OUTPUT_BITS; // set the output bit direction
+
+ #ifdef P1IO_OUTPUT_BITS
+ IO1CLR = P1IO_ZERO_BITS; // clear the ZEROs output
+ IO1SET = P1IO_ONE_BITS; // set the ONEs output
+ IO1DIR = P1IO_OUTPUT_BITS; // set the output bit direction
+ #endif
+
+ PINSEL1 = (PINSEL1 & 0x3FFFFFFF);
+
+ IO0CLR = LED1_BIT; // Indicate functional state on the LED1
+}
+
+void timer0_isr(void)
+{
+ unsigned int ir;
+ ir=T0IR;
+ if (ir&TIR_MR0I) {
+ do {
+ T0MR0+=PCLK/SYS_TIMER_HZ;
+ T0IR=TIR_MR0I; // Clear match0 interrupt
+ #ifdef CONFIG_OC_UL_DRV_SYSLESS
+ uld_jiffies++;
+ #endif
+ #ifdef CONFIG_OC_PBM_DRV
+ pbm_jiffies++;
+ #endif
+ #ifdef CONFIG_OC_I2C_DRV_SYSLESS
+ if (i2c_drv.flags&I2C_DRV_MS_INPR) {
+ if (i2c_drv.flags&I2C_DRV_NA) {
+ i2c_drv_na_timer++;
+ if (i2c_drv_na_timer>I2C_DRV_NA_MSTIMEOUT) {
+ if (i2c_drv.stroke_fnc)
+ i2c_drv.stroke_fnc(&i2c_drv);
+ i2c_drv_na_timer=0;
+ }
+ } else {
+ i2c_drv_na_timer=0;
+ }
+ i2c_drv.flags|=I2C_DRV_NA;
+ }
+ #endif
+ sys_timer_ticks++;
+ } while (((int32_t)(T0MR0-T0TC))<0);
+ }
+}
+
+void timerInit(void)
+{
+ sys_timer_ticks=0;
+
+ HAL_INTERRUPT_ATTACH(HAL_INTERRUPT_TIMER0,timer0_isr,0);
+ HAL_INTERRUPT_UNMASK(HAL_INTERRUPT_TIMER0);
+
+ T0TC=0;
+ T0MCR=0;
+
+ T0MR0=PCLK/SYS_TIMER_HZ; /* ms tics */
+ T0MCR|=TMCR_MR0_I;
+
+ T0TCR = TCR_ENABLE; //Run timer 0
+}
+
+#ifdef CONFIG_STDIO_COM_PORT
+
+int uartcon_write(int file, const char * ptr, int len)
+{
+ int cnt;
+ unsigned char ch;
+ for(cnt=0;cnt<len;cnt++,ptr++){
+ ch=*ptr;
+ if(ch==0xa)
+ uart0Putch(0xd);
+ uart0Putch(ch);
+ }
+ return cnt;
+}
+
+void init_system_stub(void) {
+ system_stub_ops.write=uartcon_write;
+}
+
+#endif /* CONFIG_STDIO_COM_PORT */
+
+#ifdef CONFIG_OC_UL_DRV_SYSLESS
+
+extern unsigned uld_debug_flg; /* Left application set defaults */
+
+#ifndef CONFIG_KEYVAL
+unsigned long lpciap_buff[ISP_RAM2FLASH_BLOCK_SIZE/4];
+#endif /* CONFIG_KEYVAL */
+
+#define UL_MTYPE_START32BIT 0x100
+
+static inline int ul_iac_mem_head_rd(uint8_t *buf, int len,
+ uint32_t* pmtype, uint32_t* pstart, uint32_t* plen)
+{
+ uint32_t val, mtype;
+ if (len<6) return -1;
+ mtype=*(buf++); /* memory type */
+ mtype+=*(buf++)<<8;
+ val=*(buf++); /* start address */
+ val+=*(buf++)<<8;
+ if(mtype&UL_MTYPE_START32BIT){
+ if (len<8) return -1;
+ val+=(uint32_t)*(buf++)<<16;
+ val+=(uint32_t)*(buf++)<<24;
+ }
+ *pstart=val;
+ val=*(buf++); /* length */
+ val+=*(buf++)<<8;
+ if(mtype&UL_MTYPE_START32BIT){
+ if (len==10) {
+ val+=(uint32_t)*(buf++)<<16;
+ val+=(uint32_t)*(buf++)<<24;
+ }
+ }
+ *plen=val;
+ mtype&=~UL_MTYPE_START32BIT; /* 32-bit start address */
+ *pmtype=mtype;
+ return 0;
+}
+
+int ul_iac_call_rdm(struct ul_drv *udrv,ul_msginfo *msginfo,char *ibuff,ul_iac_data *data)
+{
+ uint32_t mtype,start,len;
+
+ data->len=0;
+
+ if(ul_iac_mem_head_rd((uint8_t *)ibuff, msginfo->len,&mtype,&start,&len))
+ return UL_IAC_RC_PROC;
+
+ if (mtype==0x00) {
+ data->len=len;
+ data->buff=(char*)start;
+ return UL_IAC_RC_FREEMSG;
+ }
+ return UL_IAC_RC_PROC;
+}
+
+int ul_iac_call_erm(struct ul_drv *udrv,ul_msginfo *msginfo,char *ibuff,ul_iac_data *data)
+{
+ uint32_t mtype,start,len;
+
+ data->len=0;
+
+ if(ul_iac_mem_head_rd((uint8_t *)ibuff, msginfo->len,&mtype,&start,&len))
+ return UL_IAC_RC_PROC;
+
+ #ifdef CONFIG_KEYVAL
+ if (mtype==0x01) {
+ lpcisp_erase((void*)start,len);
+ data->len=0;
+ return UL_IAC_RC_FREEMSG;
+ }
+ #endif /* CONFIG_KEYVAL */
+ return UL_IAC_RC_PROC;
+}
+
+int ul_iac_call_wrm(struct ul_drv *udrv,ul_msginfo *msginfo,char *ibuff,ul_iac_data *data)
+{
+ uint32_t mtype,start,len;
+
+ data->len=0;
+
+ if(ul_iac_mem_head_rd((uint8_t *)ibuff, msginfo->len,&mtype,&start,&len))
+ return UL_IAC_RC_PROC;
+
+ if (mtype==0x00) {
+ memcpy((void*)start,data->buff,data->len);
+ return UL_IAC_RC_FREEMSG;
+ }
+ #ifdef CONFIG_KEYVAL
+ if (mtype==0x01) {
+ lpcisp_write((char*)start, data->buff, ISP_RAM2FLASH_BLOCK_SIZE);
+ return UL_IAC_RC_FREEMSG;
+ }
+ #endif /* CONFIG_KEYVAL */
+ return UL_IAC_RC_PROC;
+}
+
+
+int ul_iac_call_deb(struct ul_drv *udrv,ul_msginfo *msginfo,char *ibuff,ul_iac_data *data)
+{
+ uint32_t debcmd,mtype,start;
+ uint8_t *p=(uint8_t*)ibuff;
+
+ if (msginfo->len<1) return UL_IAC_RC_PROC;
+ debcmd=*(p++);
+ switch (debcmd) {
+ case 0x10: /* goto */
+ data->len=0;
+ if (msginfo->len<5) return UL_IAC_RC_PROC;
+ mtype=*(p++);
+ mtype+=*(p++)<<8;
+ start=*(p++);
+ start+=*(p++)<<8;
+ if(mtype&UL_MTYPE_START32BIT){
+ mtype&=~UL_MTYPE_START32BIT;
+ if (msginfo->len<7) return UL_IAC_RC_PROC;
+ start+=(uint32_t)*(p++)<<16;
+ start+=(uint32_t)*(p++)<<24;
+ }
+ if (mtype==0x00)
+ ((void (*)())start)();
+ default:break;
+ }
+ return UL_IAC_RC_PROC;
+}
+
+int ul_iac_call_res(struct ul_drv *udrv,ul_msginfo *msginfo,char *ibuff,ul_iac_data *data)
+{
+ uint32_t rescmd,pass;
+ uint8_t *p=(uint8_t*)ibuff;
+
+ if (msginfo->len<1) return UL_IAC_RC_PROC;
+ rescmd=*(p++);
+ switch (rescmd) {
+ case ULRES_CPU: /* CPU */
+ data->len=0;
+ if (msginfo->len<3) return UL_IAC_RC_PROC;
+ pass=*(p++);
+ pass+=*(p++)<<8;
+ if (pass==0xaa55) {
+ MEMMAP=MEMMAP_FLASH;
+ lpc_watchdog_init(1,10); /* 10ms */
+ lpc_watchdog_feed();
+ while(1);
+ }
+ default:break;
+ }
+ return UL_IAC_RC_PROC;
+}
+
+int uLanInit()
+{
+ struct ul_drv *udrv;
+
+ /* set rs485 mode for UART1 */
+ PINSEL0 = (PINSEL0 & ~0xFFFF0000) | 0x01550000; /* dsr(txd), cts(rxd), rts(rs485_dir), rxd, txd */
+
+ udrv=ul_drv_new(UL_DRV_SYSLESS_PORT, /* port */
+ UL_DRV_SYSLESS_IRQ, /* irq */
+ UL_DRV_SYSLESS_BAUD, /* baud */
+ UL_DRV_SYSLESS_MY_ADR_DEFAULT, /* my adr */
+ #ifdef CONFIG_OC_UL_DRV_U450_VARPINS
+ #if defined(CONFIG_OC_UL_DRV_U450_VARPINS_DIRNEG) && defined(CONFIG_OC_UL_DRV_U450_VARPINS_MSRSWAP)
+ "16450-dirneg-msrswap", /* chip name */
+ #elif defined(CONFIG_OC_UL_DRV_U450_VARPINS_MSRSWAP)
+ "16450-msrswap", /* chip name */
+ #elif defined(CONFIG_OC_UL_DRV_U450_VARPINS_DIRNEG)
+ "16450-dirneg", /* chip name */
+ #else
+ "16450", /* chip name */
+ #endif
+ #else /*CONFIG_OC_UL_DRV_U450_VARPINS*/
+ "16450", /* chip name */
+ #endif /*CONFIG_OC_UL_DRV_U450_VARPINS*/
+ 0); /* baud base - default */
+
+ if (udrv==NULL)
+ return -1;
+
+ ul_drv_add_iac(udrv,UL_CMD_RDM,UL_IAC_OP_SND,ul_iac_call_rdm,NULL,0,0,NULL,0);
+ ul_drv_add_iac(udrv,UL_CMD_ERM,UL_IAC_OP_CALLBACK,ul_iac_call_erm,NULL,0,UL_IAC_BFL_CB_OFFLT,NULL,0);
+ ul_drv_add_iac(udrv,UL_CMD_WRM,UL_IAC_OP_REC,ul_iac_call_wrm,(char*)lpciap_buff,0,UL_IAC_BFL_CB_OFFLT,NULL,0);
+ ul_drv_add_iac(udrv,UL_CMD_DEB,UL_IAC_OP_CALLBACK,ul_iac_call_deb,NULL,0,UL_IAC_BFL_CB_OFFLT,NULL,0);
+ ul_drv_add_iac(udrv,UL_CMD_RES,UL_IAC_OP_CALLBACK,ul_iac_call_res,NULL,0,UL_IAC_BFL_CB_OFFLT,NULL,0);
+
+ return ul_drv_add_dev(udrv);
+}
+#endif /* CONFIG_OC_UL_DRV_SYSLESS */
+
+#ifdef CONFIG_OC_I2C_DRV_SYSLESS
+
+int
+i2cInit(void)
+{
+
+ /* set io pins */
+ #if (I2C_DRV_SYSLESS_IRQ==9)
+ PINSEL0 = (PINSEL0 & ~0x000000F0) | 0x00000050; /* I2C0 - SCL0, SDA0 */
+ #elif (I2C_DRV_SYSLESS_IRQ==19)
+ PINSEL0 = (PINSEL0 & ~0x30C00000) | 0x30C00000; /* I2C1 - SCL1, SDA1 */
+ #else
+ #error "wrong I2C pin maping!"
+ #endif
+
+ if (i2c_drv_init(&i2c_drv,
+ I2C_DRV_SYSLESS_PORT,
+ I2C_DRV_SYSLESS_IRQ,
+ I2C_DRV_SYSLESS_BITRATE,
+ I2C_DRV_SYSLESS_SLADR)<0) return -1;
+
+ return 1;
+}
+
+#endif /*CONFIG_OC_I2C_DRV_SYSLESS*/
+
+#ifdef CONFIG_OC_PBM_DRV
+
+void pbm_drv_init()
+{
+ int rv = 0;
+
+ /* set rs485 mode for UART1 */
+ /* dsr(txd), cts(rxd), rts(rs485_dir), rxd, txd */
+ PINSEL0 = (PINSEL0 & ~0xFFFF0000) | 0x01550000;
+
+ PBMCHIP_INFO(PBMCHIP_DRV_DESCRIPTION ", "
+ PBMCHIP_DRV_VERSION ", "
+ PBMCHIP_DRV_COPYRIGHT "\n");
+
+ pbm_dev = pbm_alloc_dev(PBM_UART);
+ if (!pbm_dev)
+ PBM_PRINT("unable to allocate device\n");
+
+ PBM_LOCK_INIT(&pbm_dev->lock);
+ PBM_LOCK_INIT(&pbm_dev->irq_lock);
+
+ pbm_dev->node_res = &pbm_8250_res;
+ pbm_8250_res.ioport = PBM_8250_PORT;
+ pbm_8250_res.irq = PBM_8250_IRQ;
+ PBMCHIP_INFO("port=0x%04x irq=%d\n",
+ pbm_8250_res.ioport, pbm_8250_res.irq);
+
+ /* disable all interrupts */
+ pbm_outb(pbm_dev, UART_IER, 0x00);
+
+ /* get default parameters*/
+ pbm_8250_get_params(pbm_dev, 0);
+ /* chip operations and registering to pbmcore */
+ pbm_dev->chops = chops;
+ rv = pbm_register_chip(pbm_dev);
+ if (rv)
+ PBM_PRINT("unable to register chip\n");
+
+ rv = request_irq(pbm_8250_res.irq, pbm_8250_intr, 0, "pbm_8250", pbm_dev);
+
+ pbm_8250_int_off_all(pbm_dev);
+ pbm_8250_int_on_all(pbm_dev);
+
+ /* a hack to generate THRE interrupt on LPC2148 */
+ pbm_outb(pbm_dev, UART_TX, 0x00);
+}
+
+#endif /* CONFIG_OC_PBM_DRV */
+
+void _setup_board()
+{
+ // initialize the system
+ sysInit();
+
+ #ifdef WATCHDOG_ENABLED
+ lpc_watchdog_init(1,WATCHDOG_TIMEOUT_MS);
+ lpc_watchdog_feed();
+ #endif /* WATCHDOG_ENABLED */
+
+ // initialize the system timer
+ timerInit();
+
+ #ifdef CONFIG_STDIO_COM_PORT
+ uart0Init( B57600 , UART_8N1, UART_FIFO_8);
+ init_system_stub();
+ #endif /* CONFIG_STDIO_COM_PORT */
+
+ #ifdef CONFIG_OC_UL_DRV_SYSLESS
+// uld_debug_flg=0x3ff;
+ uLanInit();
+ #endif /* CONFIG_OC_UL_DRV_SYSLESS */
+
+ #ifdef CONFIG_OC_I2C_DRV_SYSLESS
+ i2cInit();
+ #endif /* CONFIG_OC_I2C_DRV_SYSLESS */
+
+ #ifdef CONFIG_OC_PBM_DRV
+ pbm_drv_init();
+ #endif /* CONFIG_OC_PBM_DRV */
+
+}
--- /dev/null
+#ifndef _BSPBASE_H
+#define _BSPBASE_H
+
+#include <types.h>
+#include <lt_timer_types.h>
+
+extern volatile lt_ticks_t sys_timer_ticks;
+
+#define get_sys_timer_ticks() sys_timer_ticks
+
+#endif /* _BSPBASE_H */
--- /dev/null
+#include <cpu_def.h>
+#include "kbd.h"
+
+unsigned char kbd_onerow(unsigned char scan)
+{
+ kbdisr_lock_level_t level;
+ unsigned int scan_mask=KBD_SCAN_MASK;
+ unsigned int scan_val;
+ unsigned int ret;
+ int delay=10;
+
+ kbdisr_lock(level);
+
+ #ifdef KBD_USE_IO_SETCLR_OPS
+ scan_val=(scan<<KBD_SCAN_BIT0) & scan_mask;
+ SET_OUT_PIN(KBD_PORT,scan_mask);
+ CLR_OUT_PIN(KBD_PORT,scan_val);
+ #else
+ scan_val=(~scan<<KBD_SCAN_BIT0) & scan_mask;
+ KBD_DR|=scan_val;
+ KBD_DR&=scan_val|~scan_mask;
+ #endif /* KBD_USE_IO_SETCLR_OPS */
+ kbdisr_unlock(level);
+
+ while(delay--)
+ ret=KBD_SSR;
+ ret=KBD_SSR;
+
+ kbdisr_lock(level);
+ #ifdef KBD_USE_IO_SETCLR_OPS
+ SET_OUT_PIN(KBD_PORT,scan_mask);
+ #else
+ KBD_DR |= scan_mask;
+ #endif /* KBD_USE_IO_SETCLR_OPS */
+ kbdisr_unlock(level);
+
+ return (~ret>>KBD_RET_BIT0)&((1<<KBD_RET_CNT)-1);
+}
+
+void kbd_setio(void)
+{
+ kbdisr_lock_level_t level;
+ unsigned int scan_mask=KBD_SCAN_MASK;
+ #ifndef KBD_USE_IO_SETCLR_OPS
+ unsigned int ret_mask=KBD_RET_MASK;
+ #endif /* KBD_USE_IO_SETCLR_OPS */
+
+ kbdisr_lock(level);
+
+ #ifdef KBD_USE_IO_SETCLR_OPS
+ SET_OUT_PIN(KBD_PORT,scan_mask);
+ #else
+ KBD_DR|=scan_mask;
+ KBD_DDIR|=scan_mask;
+ KBD_DDIR&=~ret_mask;
+ KBD_PUEN|=ret_mask;
+ #endif /* KBD_USE_IO_SETCLR_OPS */
+
+ kbdisr_unlock(level);
+}
+
+const scan2key_t kbd_scan2key_hisc_keypad[]={
+ [0x00]={0,0},
+ [0x01]={'3',0},
+ [0x02]={'6',0},
+ [0x03]={'9',0},
+ [0x04]={'\r',0},
+ [0x05]={'A',0},
+ [0x06]={'2',0},
+ [0x07]={'5',0},
+ [0x08]={'8',0},
+ [0x09]={'0',0},
+ [0x0a]={'B',0},
+ [0x0b]={'1',0},
+ [0x0c]={'4',0},
+ [0x0d]={'7',0},
+ [0x0e]={'*',0},
+ [0x0f]={'C',0},
+};
+
+const scan2mod_t kbd_scan2mod_hisc_keypad[]={
+ {0,0,0,0}
+};
+
+scan2key_t *kbd_scan2key_tab=(scan2key_t*)kbd_scan2key_hisc_keypad;
+scan2mod_t *kbd_scan2mod_tab=(scan2mod_t*)kbd_scan2mod_hisc_keypad;
+
+
--- /dev/null
+/******************************************************************************
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * This module provides interface routines to the LPC ARM UARTs.
+ * Copyright 2004, R O SoftWare
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ * reduced to see what has to be done for minimum UART-support by mthomas
+ *****************************************************************************/
+
+// #warning "this is a reduced version of the R O Software code"
+
+#include "uart.h"
+
+/* on LPC210x: UART0 TX-Pin=P0.2, RX-Pin=P0.1
+ PINSEL0 has to be set to "UART-Function" = Function "01"
+ for Pin 0.0 and 0.1 */
+
+#define PINSEL_BITPIN0 0
+#define PINSEL_BITPIN1 2
+#define PINSEL_BITPIN2 4
+#define PINSEL_FIRST_ALT_FUNC 1
+#define PINSEL_SECOND_ALT_FUNC 2
+
+// Values of Bits 0-3 in PINSEL to activate UART0
+#define UART0_PINSEL ((PINSEL_FIRST_ALT_FUNC<<PINSEL_BITPIN0)|(PINSEL_FIRST_ALT_FUNC<<PINSEL_BITPIN1))
+// Mask of Bits 0-4
+#define UART0_PINMASK (0x0000000F) /* PINSEL0 Mask for UART0 */
+
+// U0_LCR devisor latch bit
+#define UART0_LCR_DLAB 7
+
+/* baudrate divisor - use UART_BAUD macro
+ * mode - see typical modes (uart.h)
+ * fmode - see typical fmodes (uart.h)
+ * NOTE: uart0Init(UART_BAUD(9600), UART_8N1, UART_FIFO_8);
+ */
+void uart0Init(uint16_t baud, uint8_t mode, uint8_t fmode)
+{
+ volatile int i;
+
+ // setup Pin Function Select Register (Pin Connect Block)
+ // make sure old values of Bits 0-4 are masked out and
+ // set them according to UART0-Pin-Selection
+ PINSEL0 = (PINSEL0 & ~UART0_PINMASK) | UART0_PINSEL;
+
+ U0IER = 0x00; // disable all interrupts
+ U0IIR = 0x00; // clear interrupt ID register
+ U0LSR = 0x00; // clear line status register
+
+ // set the baudrate - DLAB must be set to access DLL/DLM
+ U0LCR = (1<<UART0_LCR_DLAB); // set divisor latches (DLAB)
+ U0DLL = (uint8_t)baud; // set for baud low byte
+ U0DLM = (uint8_t)(baud >> 8); // set for baud high byte
+
+ // set the number of characters and other
+ // user specified operating parameters
+ // Databits, Parity, Stopbits - Settings in Line Control Register
+ U0LCR = (mode & ~(1<<UART0_LCR_DLAB)); // clear DLAB "on-the-fly"
+ // setup FIFO Control Register (fifo-enabled + xx trig)
+ U0FCR = fmode;
+
+ for(i=0;i<65000;i++);
+}
+
+int uart0Putch(int ch)
+{
+ while (!(U0LSR & ULSR_THRE)) // wait for TX buffer to empty
+ continue; // also either WDOG() or swap()
+
+ U0THR = (uint8_t)ch; // put char to Transmit Holding Register
+ return (uint8_t)ch; // return char ("stdio-compatible"?)
+}
+
+const char *uart0Puts(const char *string)
+{
+ char ch;
+
+ while ((ch = *string)) {
+ if (uart0Putch(ch)<0) break;
+ string++;
+ }
+
+ return string;
+}
+
+int uart0TxEmpty(void)
+{
+ return (U0LSR & (ULSR_THRE | ULSR_TEMT)) == (ULSR_THRE | ULSR_TEMT);
+}
+
+void uart0TxFlush(void)
+{
+ U0FCR |= UFCR_TX_FIFO_RESET; // clear the TX fifo
+}
+
+
+/* Returns: character on success, -1 if no character is available */
+int uart0Getch(void)
+{
+ if (U0LSR & ULSR_RDR) // check if character is available
+ return U0RBR; // return character
+
+ return -1;
+}
+
+/* Returns: character on success, waits */
+int uart0GetchW(void)
+{
+ while ( !(U0LSR & ULSR_RDR) ); // wait for character
+ return U0RBR; // return character
+}
+
--- /dev/null
+/******************************************************************************
+ * based on software from:
+ * Copyright 2004, R O SoftWare
+ * No guarantees, warrantees, or promises, implied or otherwise.
+ * May be used for hobby or commercial purposes provided copyright
+ * notice remains intact.
+ *
+ * reduced to learn what has to be done to enable and use UART0
+ *****************************************************************************/
+#ifndef INC_UART_H
+#define INC_UART_H
+
+#include <system_def.h>
+
+///////////////////////////////////////////////////////////////////////////////
+// use the following macros to determine the 'baud' parameter values
+// for uart0Init() and uart1Init()
+// CAUTION - 'baud' SHOULD ALWAYS BE A CONSTANT or
+// a lot of code will be generated.
+// Baud-Rate is calculated based on pclk (VPB-clock)
+// the devisor must be 16 times the desired baudrate
+#define UART_BAUD(baud) (uint16_t)((PCLK / ((baud) * 16.0)) + 0.5)
+
+///////////////////////////////////////////////////////////////////////////////
+// Definitions for typical UART 'baud' settings
+#define B1200 UART_BAUD(1200)
+#define B9600 UART_BAUD(9600)
+#define B19200 UART_BAUD(19200)
+#define B38400 UART_BAUD(38400)
+#define B57600 UART_BAUD(57600)
+#define B115200 UART_BAUD(115200)
+
+///////////////////////////////////////////////////////////////////////////////
+// Definitions for typical UART 'mode' settings
+#define UART_8N1 (uint8_t)(ULCR_CHAR_8 + ULCR_PAR_NO + ULCR_STOP_1)
+#define UART_7N1 (uint8_t)(ULCR_CHAR_7 + ULCR_PAR_NO + ULCR_STOP_1)
+#define UART_8N2 (uint8_t)(ULCR_CHAR_8 + ULCR_PAR_NO + ULCR_STOP_2)
+#define UART_7N2 (uint8_t)(ULCR_CHAR_7 + ULCR_PAR_NO + ULCR_STOP_2)
+#define UART_8E1 (uint8_t)(ULCR_CHAR_8 + ULCR_PAR_EVEN + ULCR_STOP_1)
+#define UART_7E1 (uint8_t)(ULCR_CHAR_7 + ULCR_PAR_EVEN + ULCR_STOP_1)
+#define UART_8E2 (uint8_t)(ULCR_CHAR_8 + ULCR_PAR_EVEN + ULCR_STOP_2)
+#define UART_7E2 (uint8_t)(ULCR_CHAR_7 + ULCR_PAR_EVEN + ULCR_STOP_2)
+#define UART_8O1 (uint8_t)(ULCR_CHAR_8 + ULCR_PAR_ODD + ULCR_STOP_1)
+#define UART_7O1 (uint8_t)(ULCR_CHAR_7 + ULCR_PAR_ODD + ULCR_STOP_1)
+#define UART_8O2 (uint8_t)(ULCR_CHAR_8 + ULCR_PAR_ODD + ULCR_STOP_2)
+#define UART_7O2 (uint8_t)(ULCR_CHAR_7 + ULCR_PAR_ODD + ULCR_STOP_2)
+
+///////////////////////////////////////////////////////////////////////////////
+// Definitions for typical UART 'fmode' settings
+#define UART_FIFO_OFF (0x00)
+#define UART_FIFO_1 (uint8_t)(UFCR_FIFO_ENABLE + UFCR_FIFO_TRIG1)
+#define UART_FIFO_4 (uint8_t)(UFCR_FIFO_ENABLE + UFCR_FIFO_TRIG4)
+#define UART_FIFO_8 (uint8_t)(UFCR_FIFO_ENABLE + UFCR_FIFO_TRIG8)
+#define UART_FIFO_14 (uint8_t)(UFCR_FIFO_ENABLE + UFCR_FIFO_TRIG14)
+
+void uart0Init(uint16_t baud, uint8_t mode, uint8_t fmode);
+int uart0Putch(int ch);
+uint16_t uart0Space(void);
+const char *uart0Puts(const char *string);
+int uart0TxEmpty(void);
+void uart0TxFlush(void);
+int uart0Getch(void);
+int uart0GetchW(void);
+
+#endif
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+lib_LDSCRIPTS = $(notdir $(wildcard $(SOURCES_DIR)/*.ld*))
+
+include_HEADERS = mem_loc.h keyval_loc.h
--- /dev/null
+#ifndef _KEYVAL_LOC_H
+#define _KEYVAL_LOC_H
+
+extern int _keyval_start;
+extern int _keyval_page_len;
+
+#define KEYVAL_START ((unsigned int)&_keyval_start)
+#define KEYVAL_PAGE_LEN ((unsigned int)&_keyval_page_len)
+
+#endif /* _KVPB_LOC */
--- /dev/null
+PROVIDE( __bbconf_pt_addr = 0 );
+
+/* Memory Definitions */
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00008000
+ RAM (rw) : ORIGIN = 0x40000000, LENGTH = 0x00001FE0
+ STACK (rw) : ORIGIN = 0x40000000 + 0x00001FE0 - 4, LENGTH = 4
+
+ FLASHVEC (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000020
+ RAMVEC (w) : ORIGIN = 0x40000000, LENGTH = 0x00000020
+}
+
--- /dev/null
+/***********************************************************************/
+/* */
+/* ROM.ld: Linker Script File */
+/* */
+/***********************************************************************/
+ENTRY(_startup)
+
+INCLUDE "lpc2103.ld-cfg"
+
+STARTUP(startup.o)
+
+PROVIDE (_setup_board = 0);
+PROVIDE (_mem_app_start = 0);
+
+/* Section Definitions */
+SECTIONS
+{
+
+ /* first section is .text which is used for code */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.ivt)
+ *(.text .stub .text.* .gnu.linkonce.t.*) /* code */
+ *(.rodata .rodata.* .gnu.linkonce.r.*) /* read-only data */
+ *(.rodata*)
+ *(.glue_7)
+ *(.glue_7t)
+ . = ALIGN( 4 ) ;
+ _etext = . ;
+ } > FLASH
+
+ /* .data section which is used for initialized data */
+/* .data : AT (_etext)\r*/
+ .data :
+ AT ( ADDR( .text ) + SIZEOF( .text ) )
+ {
+ . = ALIGN(4);
+ _data = .;
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN( 4 ) ;
+ _edata = . ;
+ } > RAM
+
+ /* .bss section which is used for uninitialized data */
+ .bss (NOLOAD) :
+ {
+ . = ALIGN(4);
+ __bss_start = . ;
+ __bss_start__ = . ;
+ *(.bss .bss.*)
+ *(COMMON)
+ . = ALIGN( 4 ) ;
+ __bss_end__ = . ;
+ end = . ;
+ _end = . ;
+ } > RAM
+
+ .stack :
+ {
+ _stack = .;
+ } > STACK
+
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+}
--- /dev/null
+/***********************************************************************/
+/* */
+/* ROM.ld: Linker Script File */
+/* */
+/***********************************************************************/
+ENTRY(_startup)
+
+INCLUDE "lpc2105.ld-cfg"
+
+STARTUP(startup.o)
+
+PROVIDE (_setup_board = 0);
+PROVIDE (_mem_app_start = 0);
+
+/* Section Definitions */
+SECTIONS
+{
+
+ /* first section is .text which is used for code */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text) /* main code */
+ *(.stub .text.* .gnu.linkonce.t.*) /* remaining code */
+ *(.rodata .rodata.* .gnu.linkonce.r.*) /* read-only data */
+ *(.rodata*)
+ *(.glue_7t)
+ *(.glue_7)
+ *(.vfp11_veneer)
+ *(.v4_bx)
+ . = ALIGN( 4 ) ;
+ _etext = . ;
+ } > FLASHAPP
+
+ .keyval :
+ {
+ PROVIDE (_keyval_start = .);
+ PROVIDE (_keyval_page_len = KEYVAL_PAGE_LEN );
+ }> KEYVAL
+
+ /* .data section which is used for initialized data */
+/* .data : AT (_etext)
+*/
+ .data :
+ AT ( ADDR( .text ) + SIZEOF( .text ) )
+ {
+ . = ALIGN(4);
+ _data = .;
+ KEEP( *(.ivt) )
+ KEEP( *(.ivt.stub) )
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN( 4 ) ;
+ _edata = . ;
+ } > RAM
+
+ /* .bss section which is used for uninitialized data */
+ .bss (NOLOAD) :
+ {
+ . = ALIGN(4);
+ __bss_start = . ;
+ __bss_start__ = . ;
+ *(.bss .bss.*)
+ *(COMMON)
+ . = ALIGN( 4 ) ;
+ __bss_end__ = . ;
+ end = . ;
+ _end = . ;
+ } > RAM
+
+ .stack :
+ {
+ _stack = .;
+ } > STACK
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+}
--- /dev/null
+/***********************************************************************/
+/* */
+/* ROM.ld: Linker Script File */
+/* */
+/***********************************************************************/
+ENTRY(_startup)
+
+INCLUDE "lpc2105.ld-cfg"
+
+STARTUP(startup.o)
+
+PROVIDE (_setup_board = 0);
+
+/* Section Definitions */
+SECTIONS
+{
+
+ /* first section is .text which is used for code */
+ .ivt :
+ {
+ . = ALIGN(4);
+ KEEP( *(.ivt) )
+ } > FLASHBOOT
+
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text .stub .text.* .gnu.linkonce.t.*) /* code */
+ *(.rodata .rodata.* .gnu.linkonce.r.*) /* read-only data */
+ *(.rodata*)
+ *(.glue_7t)
+ *(.glue_7)
+ *(.vfp11_veneer)
+ *(.v4_bx)
+ . = ALIGN( 4 ) ;
+ _etext = . ;
+ } > FLASHBOOT
+
+ .app :
+ {
+ PROVIDE (_mem_app_start = . );
+ } > FLASHAPP
+
+ .keyval :
+ {
+ PROVIDE (_keyval_start = .);
+ PROVIDE (_keyval_page_len = KEYVAL_PAGE_LEN );
+ }> KEYVAL
+
+ /* .data section which is used for initialized data */
+/* .data : AT (_etext)
+*/
+ .data :
+ AT ( ADDR( .text ) + SIZEOF( .text ) )
+ {
+ . = ALIGN(4);
+ _data = .;
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN( 4 ) ;
+ _edata = . ;
+ } > RAM
+
+ /* .bss section which is used for uninitialized data */
+ .bss (NOLOAD) :
+ {
+ . = ALIGN(4);
+ __bss_start = . ;
+ __bss_start__ = . ;
+ *(.bss .bss.*)
+ *(COMMON)
+ . = ALIGN( 4 ) ;
+ __bss_end__ = . ;
+ end = . ;
+ _end = . ;
+ } > RAM
+
+ .stack :
+ {
+ _stack = .;
+ } > STACK
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+}
--- /dev/null
+
+KEYVAL_PAGE_LEN = 0x00002000;
+
+PROVIDE( __bbconf_pt_addr = 0 );
+
+/* Memory Definitions */
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00020000
+ RAM (rw) : ORIGIN = 0x40000000, LENGTH = 0x00007FE0
+ STACK (rw) : ORIGIN = 0x40000000 + 0x00007FE0 - 4, LENGTH = 4
+
+ FLASHVEC (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000020
+ FLASHBOOT (rx) : ORIGIN = 0x0000000, LENGTH = 0x0000A000
+ FLASHAPP (rx) : ORIGIN = 0x0000A000, LENGTH = 0x0001A000
+ KEYVAL (rx) : ORIGIN = 0x00001A000, LENGTH = 0x00004000
+
+ RAMVEC (w) : ORIGIN = 0x40000000, LENGTH = 0x00000020
+}
+
--- /dev/null
+/***********************************************************************/
+/* */
+/* ROM.ld: Linker Script File */
+/* */
+/***********************************************************************/
+ENTRY(_startup)
+
+INCLUDE "lpc2105.ld-cfg"
+
+STARTUP(startup.o)
+
+PROVIDE (_setup_board = 0);
+PROVIDE (_mem_app_start = 0);
+
+/* Section Definitions */
+SECTIONS
+{
+
+ /* first section is .text which is used for code */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.ivt)
+ *(.text .stub .text.* .gnu.linkonce.t.*) /* code */
+ *(.rodata .rodata.* .gnu.linkonce.r.*) /* read-only data */
+ *(.rodata*)
+ *(.glue_7)
+ *(.glue_7t)
+ . = ALIGN( 4 ) ;
+ _etext = . ;
+ } > FLASH
+
+ /* .data section which is used for initialized data */
+/* .data : AT (_etext)\r*/
+ .data :
+ AT ( ADDR( .text ) + SIZEOF( .text ) )
+ {
+ . = ALIGN(4);
+ _data = .;
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN( 4 ) ;
+ _edata = . ;
+ } > RAM
+
+ /* .bss section which is used for uninitialized data */
+ .bss (NOLOAD) :
+ {
+ . = ALIGN(4);
+ __bss_start = . ;
+ __bss_start__ = . ;
+ *(.bss .bss.*)
+ *(COMMON)
+ . = ALIGN( 4 ) ;
+ __bss_end__ = . ;
+ end = . ;
+ _end = . ;
+ } > RAM
+
+ .stack :
+ {
+ _stack = .;
+ } > STACK
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+}
--- /dev/null
+/***********************************************************************/
+/* */
+/* ROM.ld: Linker Script File */
+/* */
+/***********************************************************************/
+ENTRY(_startup)
+
+INCLUDE "lpc2148.ld-cfg"
+
+STARTUP(startup.o)
+
+PROVIDE (_setup_board = 0);
+PROVIDE (_mem_app_start = 0);
+
+/* Section Definitions */
+SECTIONS
+{
+
+ /* first section is .text which is used for code */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text) /* main code */
+ *(.stub .text.* .gnu.linkonce.t.*) /* remaining code */
+ *(.rodata .rodata.* .gnu.linkonce.r.*) /* read-only data */
+ *(.rodata*)
+ *(.glue_7t)
+ *(.glue_7)
+ *(.vfp11_veneer)
+ *(.v4_bx)
+ . = ALIGN( 4 ) ;
+ _etext = . ;
+ } > FLASHAPP
+
+ .keyval :
+ {
+ PROVIDE (_keyval_start = .);
+ PROVIDE (_keyval_page_len = KEYVAL_PAGE_LEN );
+ }> KEYVAL
+
+ /* .data section which is used for initialized data */
+/* .data : AT (_etext)\r*/
+ .data :
+ AT ( ADDR( .text ) + SIZEOF( .text ) )
+ {
+ . = ALIGN(4);
+ _data = .;
+ KEEP( *(.ivt) )
+ KEEP( *(.ivt.stub) )
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN( 4 ) ;
+ _edata = . ;
+ } > RAM
+
+ /* .bss section which is used for uninitialized data */
+ .bss (NOLOAD) :
+ {
+ . = ALIGN(4);
+ __bss_start = . ;
+ __bss_start__ = . ;
+ *(.bss .bss.*)
+ *(COMMON)
+ . = ALIGN( 4 ) ;
+ __bss_end__ = . ;
+ end = . ;
+ _end = . ;
+ } > RAM
+
+ .stack :
+ {
+ _stack = .;
+ } > STACK
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+}
--- /dev/null
+/***********************************************************************/
+/* */
+/* ROM.ld: Linker Script File */
+/* */
+/***********************************************************************/
+ENTRY(_startup)
+
+INCLUDE "lpc2148.ld-cfg"
+
+STARTUP(startup.o)
+
+PROVIDE (_setup_board = 0);
+
+/* Section Definitions */
+SECTIONS
+{
+
+ /* first section is .text which is used for code */
+ .ivt :
+ {
+ . = ALIGN(4);
+ KEEP( *(.ivt) )
+ } > FLASHBOOT
+
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text .stub .text.* .gnu.linkonce.t.*) /* code */
+ *(.rodata .rodata.* .gnu.linkonce.r.*) /* read-only data */
+ *(.rodata*)
+ *(.glue_7t)
+ *(.glue_7)
+ *(.vfp11_veneer)
+ *(.v4_bx)
+ . = ALIGN( 4 ) ;
+ _etext = . ;
+ } > FLASHBOOT
+
+ .app :
+ {
+ PROVIDE (_mem_app_start = . );
+ } > FLASHAPP
+
+ .keyval :
+ {
+ PROVIDE (_keyval_start = .);
+ PROVIDE (_keyval_page_len = KEYVAL_PAGE_LEN );
+ }> KEYVAL
+
+ /* .data section which is used for initialized data */
+/* .data : AT (_etext)\r*/
+ .data :
+ AT ( ADDR( .text ) + SIZEOF( .text ) )
+ {
+ . = ALIGN(4);
+ _data = .;
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN( 4 ) ;
+ _edata = . ;
+ } > RAM
+
+ /* .bss section which is used for uninitialized data */
+ .bss (NOLOAD) :
+ {
+ . = ALIGN(4);
+ __bss_start = . ;
+ __bss_start__ = . ;
+ *(.bss .bss.*)
+ *(COMMON)
+ . = ALIGN( 4 ) ;
+ __bss_end__ = . ;
+ end = . ;
+ _end = . ;
+ } > RAM
+
+ .stack :
+ {
+ _stack = .;
+ } > STACK
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+}
--- /dev/null
+
+KEYVAL_PAGE_LEN = 0x00001000;
+
+PROVIDE( __bbconf_pt_addr = 0 );
+
+/* Memory Definitions */
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000
+ RAM (rw) : ORIGIN = 0x40000000, LENGTH = 0x00007FE0
+ STACK (rw) : ORIGIN = 0x40000000 + 0x00007FE0 - 4, LENGTH = 4
+
+ FLASHVEC (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000020
+ FLASHBOOT (rx) : ORIGIN = 0x0000000, LENGTH = 0x00020000
+ FLASHAPP (rx) : ORIGIN = 0x00020000, LENGTH = 0x00058000
+ KEYVAL (rx) : ORIGIN = 0x000078000, LENGTH = 0x00002000
+
+ RAMVEC (w) : ORIGIN = 0x40000000, LENGTH = 0x00000020
+}
+
--- /dev/null
+#ifndef _MEM_LOC_H
+#define _MEM_LOC_H
+
+extern int _mem_app_start;
+
+#define MEM_APP_START ((unsigned int)&_mem_app_start)
+
+#endif /* _MEM_LOC */
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+SUBDIRS = keyval usb kbd i2c
\ No newline at end of file
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+default_CONFIG = CONFIG_OC_I2C_DRV_SYSLESS=n
+default_CONFIG += CONFIG_OC_I2C_CHIP_C552=y
+
+LOCAL_CONFIG_H = i2c_drv_config.h
+
+INCLUDES += -I .
+
+ifeq ($(CONFIG_OC_I2C_DRV_SYSLESS),y)
+lib_LIBRARIES = i2c_drv
+include_HEADERS += i2c_drv.h
+i2c_drv_SOURCES += i2c_drv.c
+
+ifeq ($(CONFIG_OC_I2C_CHIP_C552),y)
+i2c_drv_SOURCES += i2c_c552.c
+endif #CONFIG_OC_I2C_CHIP_C552
+
+endif #CONFIG_OC_I2C_DRV_SYSLESS
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ i2c_mx1.c - I2C communication automata for M9328 MX1 microcontroller
+
+ Copyright holders and project originators
+ (C) 2001-2008 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002-2008 by PiKRON Ltd. http://www.pikron.com
+ (C) 2007-2008 by Petr Smolik
+
+ The COLAMI components can be used and copied under next licenses
+ - MPL - Mozilla Public License
+ - GPL - GNU Public License
+ - LGPL - Lesser GNU Public License
+ - and other licenses added by project originators
+ Code can be modified and re-distributed under any combination
+ of the above listed licenses. If contributor does not agree with
+ some of the licenses, he can delete appropriate line.
+ Warning, if you delete all lines, you are not allowed to
+ distribute code or build project.
+ *******************************************************************/
+
+
+#include <system_def.h>
+#include <cpu_def.h>
+#include <hal_machperiph.h> /* for PCLK on LPC17xx */
+#include "i2c_drv_config.h"
+#include "i2c_drv.h"
+
+int c552_poll(i2c_drv_t *drv);
+IRQ_HANDLER_FNC(c552_irq_handler);
+static int c552_ctrl_fnc(struct i2c_drv *drv, int ctrl, void *p);
+int c552_stroke(i2c_drv_t *drv);
+
+// I2C Registers
+
+#ifdef __LPC17xx_H__
+
+#define C552_CONSET(port) (((I2C_TypeDef *)(port))->I2CONSET) /* Control Set Register */
+#define C552_STAT(port) (((I2C_TypeDef *)(port))->I2STAT) /* Status Register */
+#define C552_DAT(port) (((I2C_TypeDef *)(port))->I2DAT) /* Data Register */
+#define C552_ADR(port) (((I2C_TypeDef *)(port))->I2ADR0) /* Slave Address Register */
+#define C552_SCLH(port) (((I2C_TypeDef *)(port))->I2SCLH) /* SCL Duty Cycle Register (high half word) */
+#define C552_SCLL(port) (((I2C_TypeDef *)(port))->I2SCLL) /* SCL Duty Cycle Register (low half word) */
+#define C552_CONCLR(port) (((I2C_TypeDef *)(port))->I2CONCLR) /* Control Clear Register */
+#define C552_MMCTRL(port) (((I2C_TypeDef *)(port))->MMCTRL) /* Monitor Mode Control */
+
+#else /*__LPC17xx_H__*/
+
+#define C552_CONSET(port) (((i2cRegs_t *)(port))->conset) /* Control Set Register */
+#define C552_STAT(port) (((i2cRegs_t *)(port))->stat) /* Status Register */
+#define C552_DAT(port) (((i2cRegs_t *)(port))->dat) /* Data Register */
+#define C552_ADR(port) (((i2cRegs_t *)(port))->adr) /* Slave Address Register */
+#define C552_SCLH(port) (((i2cRegs_t *)(port))->sclh) /* SCL Duty Cycle Register (high half word) */
+#define C552_SCLL(port) (((i2cRegs_t *)(port))->scll) /* SCL Duty Cycle Register (low half word) */
+#define C552_CONCLR(port) (((i2cRegs_t *)(port))->conclr) /* Control Clear Register */
+
+#endif /*__LPC17xx_H__*/
+
+#define C552CON_AA (1 << 2)
+#define C552CON_SI (1 << 3)
+#define C552CON_STO (1 << 4)
+#define C552CON_STA (1 << 5)
+#define C552CON_EN (1 << 6)
+
+#define C552CON_AAC (1 << 2)
+#define C552CON_SIC (1 << 3)
+#define C552CON_STAC (1 << 5)
+#define C552CON_ENC (1 << 6)
+
+/***************************************************************************/
+int c552_init_start(struct i2c_drv *drv, int port, int irq, int bitrate, int sladr)
+{
+ unsigned long clock_base;
+
+ clock_base=PCLK/2;
+
+ C552_ADR(port)=sladr;
+ C552_SCLH(port)=clock_base/bitrate; //minimal value
+ C552_SCLL(port)=clock_base/bitrate;
+ drv->irq=irq;
+ drv->port=port;
+ drv->sfnc_act=NULL;
+ drv->ctrl_fnc=c552_ctrl_fnc;
+ drv->poll_fnc=c552_poll;
+ drv->stroke_fnc=c552_stroke;
+ drv->flags=I2C_DRV_ON; /* todo - use atomic operation */
+ C552_CONCLR(port)=0x6C; /* clearing all flags */
+ C552_CONSET(port)=C552CON_EN;
+ request_irq(irq, c552_irq_handler, 0, "i2c", drv);
+ return 0;
+}
+
+static int c552_sfnc_ms_end(struct i2c_drv *drv);
+static inline i2c_msg_head_t *c552_sfnc_sl_prep(struct i2c_drv *drv, int cmd, int rxtx);
+
+/***************************************************************************/
+static int c552_sfnc_ms_end(struct i2c_drv *drv)
+{
+ i2c_msg_head_t *msg=drv->msg_act;
+
+ if(msg) {
+ if(msg->flags&I2C_MSG_REPEAT){
+ drv->master_queue=msg->next;
+ }else{
+ i2c_drv_queue_msg(msg->flags&I2C_MSG_NOPROC?NULL:&drv->proc_queue,msg);
+ }
+ msg->flags|=I2C_MSG_FINISHED;
+ if((msg->flags&I2C_MSG_CB_END) && (msg->callback))
+ msg->callback(drv,I2C_MSG_CB_END,msg);
+ }
+
+ if(drv->master_queue) {
+ /* there is some more work for master*/
+ /* We need to request start of the next transfer somewhere */
+ C552_CONSET(drv->port)=C552CON_STA;
+ } else {
+ drv->flags&=~I2C_DRV_MS_INPR;
+ }
+
+ drv->msg_act = NULL;
+ return 0;
+}
+
+static inline
+i2c_msg_head_t *c552_sfnc_sl_prep(struct i2c_drv *drv, int cmd, int rxtx)
+{
+ i2c_msg_head_t *msg=drv->slave_queue;
+ if(!msg) do {
+ if((msg->flags&rxtx) && !((cmd^msg->sl_cmd)&msg->sl_msk)){
+ drv->slave_queue=msg;
+ if((msg->flags&I2C_MSG_CB_START) && (msg->callback))
+ msg->callback(drv,I2C_MSG_CB_START|rxtx,msg);
+ return msg;
+ }
+ } while((msg=msg->next)!=drv->slave_queue);
+ return NULL;
+}
+
+/***************************************************************************/
+static int c552_ctrl_fnc(struct i2c_drv *drv, int ctrl, void *p)
+{
+ unsigned long saveif;
+ switch(ctrl){
+ case I2C_CTRL_MS_RQ:
+ if(!(drv->flags&I2C_DRV_ON))
+ return -1;
+ if(!drv->master_queue)
+ return 0;
+ save_and_cli(saveif);
+ if(!(drv->flags&I2C_DRV_MS_INPR)) {
+ drv->flags|=I2C_DRV_MS_INPR;
+ drv->flags&=~I2C_DRV_NA;
+ C552_CONSET(drv->port)=C552CON_STA;
+ }
+ restore_flags(saveif);
+ return 0;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+/***************************************************************************/
+int c552_poll(i2c_drv_t *drv)
+{
+ i2c_msg_head_t *msg;
+
+ if((msg=drv->proc_queue)!=NULL){
+ i2c_drv_queue_msg(NULL,msg);
+ if((msg->flags&I2C_MSG_CB_PROC) && (msg->callback))
+ msg->callback(drv,I2C_MSG_CB_PROC,msg);
+ }
+ return 0;
+}
+
+int c552_stroke(i2c_drv_t *drv)
+{
+ int port;
+ volatile int d;
+ port=drv->port;
+
+ C552_CONSET(port)=C552CON_STO;
+ C552_CONSET(port)=C552CON_STA;
+ for(d=0;d<10;d++);
+ C552_CONSET(port)=C552CON_STA;
+ return 0;
+}
+
+
+int i2c_irq_seq_num=0;
+
+/***************************************************************************/
+IRQ_HANDLER_FNC(c552_irq_handler)
+{
+ i2c_drv_t *drv;
+ i2c_msg_head_t *msg;
+ int port;
+ int stat;
+
+ drv=(i2c_drv_t*)irq_handler_get_context();
+ if(drv->magic!=I2C_DRV_MAGIC)
+ {
+ #ifdef FOR_LINUX_KERNEL
+ panic("i2c_irq_handler : BAD drv magic !!!");
+ #elif defined(_WIN32)
+ I2C_PRINTF("i2c_irq_handler : BAD drv magic !!!\n");
+ return FALSE;
+ #elif defined(__DJGPP__)||defined(CONFIG_OC_I2C_DRV_SYSLESS)
+ I2C_PRINTF("i2c_irq_handler : BAD drv magic !!!\n");
+ return;
+ #else
+ error("i2c_irq_handler : BAD drv magic !!!");
+ #endif
+ }
+ drv->flags&=~I2C_DRV_NA;
+
+ port=drv->port;
+ msg=drv->msg_act;
+
+ stat=C552_STAT(port);
+
+ switch(stat) {
+ case 0x00:
+ /* Bus Error has occured */
+ drv->msg_act=NULL;
+ C552_CONSET(port)=C552CON_STO;
+ if(drv->master_queue) {
+ /* there is some work for master*/
+ C552_CONSET(port)=C552CON_STA;
+ }
+ break;
+ case 0x08: /* MS_STA */
+ /* the initial start condition has been sent */
+ if(!drv->master_queue) {
+ C552_CONCLR(port)=C552CON_STAC;
+ C552_CONSET(port)=C552CON_STO;
+ drv->msg_act=NULL;
+ break;
+ }
+ C552_CONCLR(port)=C552CON_STAC;
+ C552_CONSET(port)=C552CON_AA;
+
+ msg=drv->master_queue;
+ drv->msg_act=msg;
+ msg->tx_len=msg->rx_len=0;
+
+ if((msg->flags&I2C_MSG_CB_START) && (msg->callback))
+ msg->callback(drv,I2C_MSG_CB_START,msg);
+
+ if (msg->flags&I2C_MSG_MS_TX) {
+ /* proceed Tx request first */
+ C552_DAT(port) = msg->addr&~1;
+ break;
+ }
+ /* if there is no request for transmit, continue by Rx immediately */
+ case 0x10: /* MS_REPS */
+ /* the repeated start has been successfully sent, continue by Rx */
+ C552_CONCLR(port)=C552CON_STAC;
+ C552_CONSET(port)=C552CON_AA;
+ C552_DAT(port) = msg->addr|1;
+ if (!msg || !(msg->flags&I2C_MSG_MS_RX)) {
+ /* there are no data to be received */
+ C552_CONSET(port)=C552CON_STO;
+ c552_sfnc_ms_end(drv);
+ } else {
+ msg->rx_len=0;
+ }
+ break;
+ case 0x18:
+ /* sent SLA W received ACK */
+ case 0x28:
+ /* sent DATA received ACK */
+ if (msg->tx_len<msg->tx_rq) {
+ C552_DAT(port) = msg->tx_buf[msg->tx_len];
+ msg->tx_len++;
+ break;
+ }
+ /* all data has been sent */
+ if (!(msg->flags&I2C_MSG_MS_RX)) {
+ C552_CONSET(port)=C552CON_STO;
+ c552_sfnc_ms_end(drv);
+ } else {
+ C552_CONSET(port)=C552CON_STA;
+ }
+ break;
+ case 0x30:
+ /* sent DATA received NACK */
+ case 0x48:
+ /* sent SLA R received ACK */
+ case 0x20:
+ /* vyslano SLA W prijato NACK */
+ C552_CONSET(port)=C552CON_STO;
+ msg->flags|=I2C_MSG_FAIL;
+ c552_sfnc_ms_end(drv);
+ break;
+ case 0x38:
+ /* arbitration lost during Tx */
+ C552_CONSET(port)=C552CON_STA;
+ break;
+ case 0x40:
+ /* sent SLA R received ACK */
+ if (msg->rx_rq==1)
+ C552_CONCLR(port)=C552CON_AAC;
+ break;
+ case 0x50:
+ /* received DATA sent ACK */
+ msg->rx_buf[msg->rx_len]= C552_DAT(port);
+ msg->rx_len++;
+ if (msg->rx_len+1>=msg->rx_rq)
+ C552_CONCLR(port)=C552CON_AAC;
+ break;
+ case 0x58:
+ /* received DATA sent NACK */
+ msg->rx_buf[msg->rx_len]= C552_DAT(port);
+ msg->rx_len++;
+ C552_CONSET(port)=C552CON_STO;
+ c552_sfnc_ms_end(drv);
+ break;
+
+ /*** slave mode ***/
+
+ case 0x68:
+ /* received own SLA W sent ACK after arbitration lost */
+
+ case 0x78:
+ /* received Generall CALL sent ACK after arbitration lost */
+ C552_CONSET(port)=C552CON_STA;
+
+ case 0x60:
+ /* received own SLA W sent ACK */
+
+ case 0x70:
+ /* received Generall CALL sent ACK */
+ if(!drv->slave_queue) {
+ C552_CONCLR(port)=C552CON_AAC;
+ break;
+ }
+ C552_CONSET(port)=C552CON_AA;
+ drv->flags|=I2C_DRV_SL_CEXP|I2C_DRV_SL_INRX;
+ break;
+
+ case 0x80:
+ /* SLA W : received DATA sent ACK */
+
+ case 0x90:
+ /* GCall : received DATA sent ACK */
+
+ if(drv->flags&I2C_DRV_SL_CEXP){
+ drv->flags&=~I2C_DRV_SL_CEXP;
+ drv->sl_last_cmd=C552_DAT(port);
+ msg=c552_sfnc_sl_prep(drv, drv->sl_last_cmd, I2C_MSG_SL_RX);
+ drv->msg_act=msg;
+ }
+ if(!msg || (msg->rx_len>=msg->rx_rq)){
+ C552_CONCLR(port)=C552CON_AAC;
+ break;
+ }
+ msg->rx_buf[msg->rx_len]= C552_DAT(port);
+ msg->rx_len++;
+ break;
+
+ case 0x88:
+ /* SLA W : received DATA sent NACK */
+ /* may it be, the handling should fall into A0 state */
+
+ case 0x98:
+ /* GCall : received DATA sent NACK */
+ /* may it be, the handling should fall into A0 state */
+
+ C552_CONSET(port)=C552CON_AA;
+ break;
+
+ case 0xA0:
+ /* Slave : Repeated START or STOP */
+ if(msg && (msg->flags&I2C_MSG_CB_END) && (msg->callback)) {
+ int cbcode;
+ if(drv->flags&I2C_DRV_SL_INRX)
+ cbcode=I2C_MSG_CB_END|I2C_MSG_SL_RX;
+ else
+ cbcode=I2C_MSG_CB_END|I2C_MSG_SL_TX;
+ msg->callback(drv,cbcode,msg);
+ }
+ C552_CONSET(port)=C552CON_AA;
+ break;
+
+ case 0xB0:
+ /* received own SLA R sent ACK after arbitration lost */
+ C552_CONSET(port)=C552CON_STA;
+
+ case 0xA8:
+ /* received own SLA R sent ACK */
+ drv->flags&=~I2C_DRV_SL_INRX;
+ msg=c552_sfnc_sl_prep(drv, drv->sl_last_cmd, I2C_MSG_SL_RX);
+ drv->msg_act=msg;
+ if(!msg) {
+ C552_CONCLR(port)=C552CON_AAC;
+ break;
+ }
+ C552_CONSET(port)=C552CON_AA;
+
+ case 0xB8:
+ /* SLA R : sent DATA received ACK */
+ if(!msg || (msg->tx_len>=msg->tx_rq)){
+ C552_DAT(port) = 0xff;
+ break;
+ }
+ C552_DAT(port) = msg->tx_buf[msg->tx_len];
+ msg->tx_len++;
+ break;
+
+ case 0xC0:
+ /* SLA R : sent DATA received NACK */
+ /* the A0 state is not enerred most probably */
+
+ case 0xC8:
+ /* SLA R : last data sent, DATA (AA=0) received ACK */
+ /* the A0 state is not enerred most probably */
+ C552_CONSET(port)=C552CON_AA;
+
+ if(msg && (msg->flags&I2C_MSG_CB_END) && (msg->callback)) {
+ msg->callback(drv,I2C_MSG_CB_END|I2C_MSG_SL_TX,msg);
+ }
+ break;
+
+ default: break;
+ }
+
+ /* vymaz SI bit */
+ C552_CONCLR(port)=C552CON_SIC;
+}
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ i2c_mx1.c - I2C communication automata for M9328 MX1 microcontroller
+
+ Copyright holders and project originators
+ (C) 2001-2004 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002-2004 by PiKRON Ltd. http://www.pikron.com
+ (C) 2007-2008 by Petr Smolik
+
+ The COLAMI components can be used and copied under next licenses
+ - MPL - Mozilla Public License
+ - GPL - GNU Public License
+ - LGPL - Lesser GNU Public License
+ - and other licenses added by project originators
+ Code can be modified and re-distributed under any combination
+ of the above listed licenses. If contributor does not agree with
+ some of the licenses, he can delete appropriate line.
+ Warning, if you delete all lines, you are not allowed to
+ distribute code or build project.
+ *******************************************************************/
+
+
+#include <system_def.h>
+#include <string.h>
+#include "i2c_drv_config.h"
+#include "i2c_drv.h"
+
+/***************************************************************************/
+int
+i2c_drv_init(i2c_drv_t *drv, int port, int irq, int bitrate,int sladr)
+{
+ int r=-1;
+ memset(drv,0,sizeof(i2c_drv_t));
+ drv->magic=I2C_DRV_MAGIC;
+ #ifdef CONFIG_OC_I2C_CHIP_C552
+ r=c552_init_start(drv,port,irq,bitrate,sladr);
+ #endif /* CONFIG_OC_I2C_CHIP_C552 */
+ if (r<0) return r;
+ return 0;
+}
+
+/********************************************************************/
+/* Generic I2C functions */
+
+void i2c_drv_queue_msg(i2c_msg_head_t **queue, i2c_msg_head_t *msg)
+{
+ I2C_IRQ_LOCK_FINI
+ i2c_msg_head_t *prev, *next;
+ I2C_IRQ_LOCK;
+ if(msg->on_queue){
+ if(msg->next==msg){
+ if(*msg->on_queue==msg)
+ *msg->on_queue=NULL;
+ }else{
+ msg->next->prev=msg->prev;
+ msg->prev->next=msg->next;
+ if(*msg->on_queue==msg)
+ *msg->on_queue=msg->next;
+ }
+ }
+ if((msg->on_queue=queue)!=NULL){
+ if((next=*queue)!=NULL){
+ msg->prev=prev=next->prev;
+ msg->next=next;
+ next->prev=msg;
+ prev->next=msg;
+ }else{
+ *queue=msg->prev=msg->next=msg;
+ }
+ }
+ I2C_IRQ_UNLOCK;
+ return;
+}
+
+int i2c_drv_master_msg_ins(i2c_drv_t *drv, i2c_msg_head_t *msg)
+{
+ if(!drv) return -1;
+ if(!(drv->flags&I2C_DRV_ON)) return -1;
+ if(!msg->tx_buf) msg->flags&=~I2C_MSG_MS_TX;
+ if(!msg->rx_buf) msg->flags&=~I2C_MSG_MS_RX;
+ i2c_drv_queue_msg(&drv->master_queue,msg);
+ drv->ctrl_fnc(drv,I2C_CTRL_MS_RQ,NULL);
+ return 0;
+}
+
+int i2c_drv_master_msg_rem(i2c_drv_t *drv, i2c_msg_head_t *msg)
+{
+ int act;
+ I2C_IRQ_LOCK_FINI
+ do {
+ i2c_drv_queue_msg(NULL,msg);
+ I2C_IRQ_LOCK;
+ act = (msg==drv->msg_act);
+ if(act) {
+ drv->msg_act=NULL;
+ }
+ I2C_IRQ_UNLOCK;
+ } while(msg->on_queue || act);
+ return 0;
+}
+
+int i2c_drv_flush_all(i2c_drv_t *drv)
+{
+ I2C_IRQ_LOCK_FINI
+ i2c_msg_head_t *msg, *next;
+ i2c_msg_head_t *queue[3];
+ int quenum;
+
+ I2C_IRQ_LOCK;
+ queue[0]=drv->master_queue;
+ queue[1]=drv->slave_queue;
+ queue[2]=drv->proc_queue;
+ drv->master_queue=NULL;
+ drv->slave_queue=NULL;
+ drv->proc_queue=NULL;
+ drv->msg_act=NULL;
+ I2C_IRQ_UNLOCK;
+ for(quenum=0;quenum<3;quenum++){
+ msg=queue[quenum];
+ if(!msg) continue;
+ msg->prev->next=NULL;
+ for(;msg;msg=next){
+ next=msg->next;
+ msg->flags|=I2C_MSG_FAIL;
+ msg->on_queue=NULL;
+ if((msg->flags&I2C_MSG_CB_PROC) && (msg->callback))
+ msg->callback(drv,I2C_MSG_CB_PROC,msg);
+ }
+ }
+ return 0;
+}
+
+int i2c_drv_master_transfer_callback(struct i2c_drv *drv, int code, struct i2c_msg_head *msg)
+{
+ if(code!=I2C_MSG_CB_PROC) return 0;
+ set_bit(0,&(msg->private));
+ return 0;
+}
+
+
+int i2c_drv_master_transfer(i2c_drv_t *drv, int addr, int tx_rq, int rx_rq,
+ void *tx_buf, void *rx_buf, int *ptx_len, int *prx_len)
+{
+ i2c_msg_head_t msg;
+
+ msg.flags = I2C_MSG_CB_PROC;
+ msg.addr = addr;
+ msg.tx_rq = tx_rq;
+ msg.rx_rq = rx_rq;
+ msg.tx_buf = tx_buf;
+ msg.rx_buf = rx_buf;
+ msg.on_queue = NULL;
+ msg.callback = i2c_drv_master_transfer_callback;
+ msg.private = 0;
+
+ if(msg.tx_buf)
+ msg.flags |= I2C_MSG_MS_TX;
+
+ if(msg.rx_buf && (msg.rx_rq>=1))
+ msg.flags |= I2C_MSG_MS_RX;
+
+ if(!(msg.flags & (I2C_MSG_MS_TX | I2C_MSG_MS_RX)))
+ return 0;
+
+ if(i2c_drv_master_msg_ins(drv, &msg)<0)
+ return -1;
+
+ /* wait for message process */
+ while(test_bit(0,&(msg.private))==0)
+ drv->poll_fnc(drv);
+
+ if(ptx_len) *ptx_len = msg.tx_len;
+ if(prx_len) *prx_len = msg.rx_len;
+
+ if(msg.flags & I2C_MSG_FAIL)
+ return -1;
+
+ return msg.tx_len+msg.rx_len;
+}
+
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ i2c_drv.h - I2C communication automat interface
+
+ Copyright holders and project originators
+ (C) 2001-2008 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002-2008 by PiKRON Ltd. http://www.pikron.com
+ (C) 2007-2008 by Petr Smolik
+
+ The COLAMI components can be used and copied under next licenses
+ - MPL - Mozilla Public License
+ - GPL - GNU Public License
+ - LGPL - Lesser GNU Public License
+ - and other licenses added by project originators
+ Code can be modified and re-distributed under any combination
+ of the above listed licenses. If contributor does not agree with
+ some of the licenses, he can delete appropriate line.
+ Warning, if you delete all lines, you are not allowed to
+ distribute code or build project.
+ *******************************************************************/
+
+#ifndef _I2C_DRV_H_
+#define _I2C_DRV_H_
+
+#include <types.h>
+#include <cpu_def.h>
+
+#if defined(CONFIG_OC_I2C_DRV_SYSLESS)
+ #define I2C_IRQ_LOCK_FINI unsigned long i2c_irq_lock_flags=0;
+ #define I2C_IRQ_LOCK \
+ {save_flags(i2c_irq_lock_flags);cli();}
+ #define I2C_IRQ_UNLOCK \
+ {restore_flags(i2c_irq_lock_flags);}
+ #define I2C_MB() {asm volatile ("":::"memory");}
+#endif
+
+struct i2c_drv;
+
+#define I2C_MSG_TX 0x001
+#define I2C_MSG_RX 0x002
+#define I2C_MSG_MS_TX I2C_MSG_TX
+#define I2C_MSG_MS_RX I2C_MSG_RX
+#define I2C_MSG_SL_TX I2C_MSG_TX
+#define I2C_MSG_SL_RX I2C_MSG_RX
+#define I2C_MSG_SLAVE 0x004
+#define I2C_MSG_FAIL 0x008
+#define I2C_MSG_REPEAT 0x010
+#define I2C_MSG_NOPROC 0x020
+#define I2C_MSG_FINISHED 0x040
+#define I2C_MSG_CB_START 0x100
+#define I2C_MSG_CB_END 0x200
+#define I2C_MSG_CB_PROC 0x400
+
+typedef struct i2c_msg_head {
+ unsigned long flags;/* message flags */
+ uint8_t sl_cmd; /* command for slave queue lookup */
+ uint8_t sl_msk; /* sl_cmd match mask */
+ uint16_t addr; /* message destination address */
+ uint16_t tx_rq; /* requested TX transfer length */
+ uint16_t rx_rq; /* requested RX transfer length */
+ uint16_t tx_len; /* finished TX transfer length */
+ uint16_t rx_len; /* finished RX transfer length */
+ uint8_t *tx_buf; /* pointer to TX data */
+ uint8_t *rx_buf; /* pointer to RX data */
+ struct i2c_msg_head *prev;
+ struct i2c_msg_head *next;
+ struct i2c_msg_head **on_queue;
+ int (*callback)(struct i2c_drv *ifc, int code, struct i2c_msg_head *msg);
+ unsigned long private;
+ } i2c_msg_head_t;
+
+typedef int (i2c_sfnc_t)(struct i2c_drv *drv, int code);
+typedef int (i2c_ctrl_fnc_t)(struct i2c_drv *drv, int ctrl, void *p);
+typedef int (i2c_stroke_fnc_t)(struct i2c_drv *drv);
+
+#define I2C_DRV_ON 1 /* flag indicating that driver is ready to operate */
+#define I2C_DRV_MS_INPR 2 /* master request in in progress */
+#define I2C_DRV_NA 4 /* driver is not active for some period */
+#define I2C_DRV_SL_CEXP 8 /* slave expect receive of the first byte */
+#define I2C_DRV_SL_INRX 0x10 /* slave in mode */
+
+#define I2C_DRV_MAGIC 0x12345432
+
+typedef struct i2c_drv {
+ int magic; /* magic number */
+ int irq; /* irq number */
+ long port; /* base port number */
+ uint8_t flags;
+ uint16_t self_addr;
+ i2c_msg_head_t *master_queue;
+ i2c_msg_head_t *slave_queue;
+ i2c_msg_head_t *proc_queue;
+ i2c_msg_head_t *msg_act;
+ i2c_sfnc_t *sfnc_act;
+ void *failed;
+ i2c_ctrl_fnc_t *ctrl_fnc;
+ int (*poll_fnc)(struct i2c_drv *drv);
+ i2c_stroke_fnc_t *stroke_fnc;
+ uint8_t sl_last_cmd; /* last received slave command */
+ } i2c_drv_t;
+
+#define I2C_CTRL_MS_RQ 1
+
+#ifdef CONFIG_OC_I2C_CHIP_C552
+int c552_init_start(struct i2c_drv *drv, int port, int irq, int bitrate, int sladr);
+#endif /* CONFIG_OC_I2C_CHIP_C552 */
+
+void i2c_drv_queue_msg(i2c_msg_head_t **queue, i2c_msg_head_t *msg);
+int i2c_drv_init(i2c_drv_t *drv, int port, int irq, int bitrate,int sladr);
+int i2c_drv_master_msg_ins(i2c_drv_t *drv, i2c_msg_head_t *msg);
+int i2c_drv_master_msg_rem(i2c_drv_t *drv, i2c_msg_head_t *msg);
+int i2c_drv_flush_all(i2c_drv_t *drv);
+int i2c_drv_master_transfer(i2c_drv_t *drv, int addr, int tx_rq, int rx_rq,
+ void *tx_buf, void *rx_buf, int *ptx_len, int *prx_len);
+
+#ifdef I2C_LOG_ENABLE
+ /* todo */
+#else
+ #define I2C_PRINTF(x,args...)
+#endif
+
+#endif /* _I2C_DRV_H_ */
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+default_CONFIG = CONFIG_KBD=n
+
+ifeq ($(CONFIG_KBD),y)
+lib_LIBRARIES = kbd
+include_HEADERS += kbd.h
+kbd_SOURCES += kbd_base.c kbd_dev_ops.c
+endif #CONFIG_KBD
--- /dev/null
+#include <system_def.h>
+
+#ifndef KEY_DEFAULT_TIMES
+ #define KEY_PUSH_T 20
+ #define KEY_RELEASE_T 10
+ #define KEY_REPFIRST_T 800
+ #define KEY_REPNEXT_T 300
+#endif /* KEY_DEFAULT_TIMES */
+
+typedef struct {
+ kbd_key_t bc;
+ kbd_key_t sc;
+} scan2key_t;
+
+typedef struct {
+ int scan;
+ int flag;
+ kbd_keymod_t is_mod;
+ kbd_keymod_t set_mod;
+ kbd_keymod_t xor_mod;
+} scan2mod_t;
+
+#define KBDMOD_SGM_SC 0x8000
+#define KBDMOD_SGM_RELEASE 0x0080
+
+extern int key_last_changed;
+extern kbd_keymod_t key_mod;
+extern unsigned char key_hit;
+extern short key_use_timer;
+extern unsigned char key_down_arr[KBD_SCAN_CNT];
+
+unsigned char kbd_onerow(unsigned char scan);
+void kbd_setio(void);
+
+int kbd_scan();
+void kbd_scan2mod(int scan_code);
+int kbd_down();
+kbd_key_t kbd_scan2key(int scan);
+
+int kbd_Open(KBDDEVICE *pkd);
+void kbd_Close(void);
+void kbd_GetModifierInfo(kbd_keymod_t *modifiers, kbd_keymod_t *curmodifiers);
+int kbd_Read(kbd_key_t *buf, kbd_keymod_t *modifiers, kbd_scan_code_t *scancode);
+int kbd_Poll(void);
+
--- /dev/null
+#include "kbd.h"
+
+extern scan2key_t *kbd_scan2key_tab;
+extern scan2mod_t *kbd_scan2mod_tab;
+
+/* State of keyboard matrix and key press reporting */
+
+unsigned char key_down_arr[KBD_SCAN_CNT];
+unsigned char key_chng_arr[KBD_SCAN_CNT];
+unsigned char key_hit;
+
+kbd_keymod_t key_mod;
+
+int key_last_changed;
+
+/* Internal state for repeat processing */
+
+short key_use_timer;
+short key_state;
+kbd_interval_t key_time;
+
+#define KEY_STATE_IDLE 0
+#define KEY_STATE_PUSH 1
+#define KEY_STATE_RELEASE 2
+#define KEY_STATE_REPEAT 4
+#define KEY_STATE_NOISE 8
+#define KEY_STATE_BUSY (KEY_STATE_PUSH|KEY_STATE_RELEASE)
+
+
+/**
+ * kbd_scan - Scan keyboard matrix and report requests for state change
+ *
+ * Scans keyboard matrix connected row by row by calling function
+ * mx1_kbd_onerow(). Number of scanned output lines is defined
+ * by %KBD_SCAN_CNT. Checks read keyboard state against @key_down_arr
+ * and updates @key_change_arr array. The @key_down_arr state is
+ * left unchanged. It is changed later by kbd_down() function.
+ * Returns 0, if no keyboard activity is found. Returns 1
+ * if at least one key is pressed. Returns 2 or 3 in case
+ * of detected change.
+ */
+int
+kbd_scan()
+{
+ int i, ret=0;
+ unsigned char mask, val, chng;
+ for(i=0,mask=1;i<KBD_SCAN_CNT;i++,mask<<=1) {
+ val=kbd_onerow(mask);
+ chng=val^key_down_arr[i];
+ key_chng_arr[i]=chng;
+ if(val) ret|=1;
+ if(chng) ret|=2;
+ }
+ /* mx1_kbd_onerow(~0); */
+ return ret;
+}
+
+
+/**
+ * kbd_scan2mod - Propagate keyboard matrix changes between modifiers
+ * @scan_code: Scan code of last detected key change
+ *
+ * Functions check keyboard matrix state in @key_down_arr.
+ * It updates @key_mod according to @key_down_arr and
+ * modifiers transformations table @kbd_scan2mwmod_tab.
+ */
+void
+kbd_scan2mod(int scan_code)
+{
+ unsigned char val, chng;
+ int s;
+ scan2mod_t *mt=kbd_scan2mod_tab;
+
+ for(;(s=mt->scan);mt++) {
+ chng=(s==scan_code);
+ s--;
+ val=key_down_arr[s/KBD_RET_CNT]&(1<<(s%KBD_RET_CNT));
+ if(val) {
+ key_mod|=mt->set_mod;
+ if(chng){
+ key_mod^=mt->xor_mod;
+ }
+ } else {
+ key_mod&=~mt->set_mod;
+ }
+ }
+}
+
+/**
+ * kbd_down - Detects changed key scancode and applies changes to matrix state
+ *
+ * Functions check @key_chng_arr and process changes.
+ * It updates its internal state @key_state, does
+ * noise cancellation and repeat timing, then updates
+ * @key_down_arr, stores detected scancode to @key_last_changed
+ * and calls modifiers processing kbd_scan2mod().
+ * Return value is zero if no change is detected.
+ * In other case evaluated scancode is returned.
+ * Variable @key_hit signals by value 1 pressed key, by value
+ * 2 key release.
+ */
+int
+kbd_down()
+{
+ int i, j=0;
+ unsigned char val;
+
+ if(!(key_state&KEY_STATE_BUSY)){
+ for(i=0;i<KBD_SCAN_CNT;i++) {
+ if(!(val=key_chng_arr[i])) continue;
+ for(j=0;!(val&1);j++) val>>=1;
+ key_last_changed=i*KBD_RET_CNT+j+1;
+ if(key_down_arr[i]&(1<<j)){
+ key_time=KEY_TIMER+KEY_PUSH_T;
+ key_state=KEY_STATE_RELEASE;
+ }else{
+ key_time=KEY_TIMER+KEY_RELEASE_T;
+ key_state=KEY_STATE_PUSH;
+ }
+ break;
+ }
+ if(key_state==KEY_STATE_IDLE)
+ return 0;
+ } else {
+ if(!key_last_changed){
+ key_state=KEY_STATE_IDLE;
+ return 0;
+ }
+ i=(key_last_changed-1)/KBD_RET_CNT;
+ j=(key_last_changed-1)%KBD_RET_CNT;
+ if(!(key_chng_arr[i]&(1<<j))){
+ /* Noise detected */
+ if(!(key_state&KEY_STATE_NOISE)){
+ key_time=KEY_TIMER+KEY_RELEASE_T;
+ key_state|=KEY_STATE_NOISE;
+ }
+ }
+ }
+
+ if(!key_use_timer){
+ if(KEY_TIMER) key_use_timer=1;
+ if(key_state&KEY_STATE_REPEAT) return 0;
+ }else{
+ if((long)(KEY_TIMER-key_time)<0) return 0;
+ }
+
+ if(key_state==KEY_STATE_PUSH) {
+ key_down_arr[i]|=1<<j;
+ kbd_scan2mod(key_last_changed);
+ key_state=KEY_STATE_REPEAT;
+ key_time=KEY_TIMER+KEY_REPFIRST_T;
+ key_hit=1;
+ return key_last_changed;
+ } else if(key_state==KEY_STATE_REPEAT) {
+ key_time=KEY_TIMER+KEY_REPNEXT_T;
+ key_hit=1;
+ return key_last_changed;
+ } else if(key_state==KEY_STATE_RELEASE) {
+ key_down_arr[i]&=~(1<<j);
+ kbd_scan2mod(key_last_changed);
+ key_state=KEY_STATE_IDLE;
+ key_hit=2;
+ return key_last_changed;
+ }
+ key_state=KEY_STATE_IDLE;
+ return 0;
+}
+
+/**
+ * kbd_scan2key - Converts scancode to kbd_key_t keyboard values
+ * @scan: Detected scancode
+ *
+ * Computes kbd_key_t value for detected scancode.
+ * Uses @kbd_scan2key_tab transformation table
+ * and @key_mod modifiers information.
+ */
+kbd_key_t kbd_scan2key(int scan)
+{
+ if((key_mod&KBDMOD_SGM_SC)&&kbd_scan2key_tab[scan].sc)
+ return kbd_scan2key_tab[scan].sc;
+ return kbd_scan2key_tab[scan].bc;
+}
+
--- /dev/null
+#include <string.h>
+#include "kbd.h"
+
+#ifdef _DEVICE_H
+/* create the microwindows keyboard device */
+
+KBDDEVICE kbddev = {
+ kbd_Open,
+ kbd_Close,
+ kbd_GetModifierInfo,
+ kbd_Read,
+ kbd_Poll
+};
+#endif /* _DEVICE_H */
+
+/**
+ * kbd_Open - Open the keyboard
+ * @pkd: Pointer to keyboard device
+ */
+int
+kbd_Open(KBDDEVICE *pkd)
+{
+ key_last_changed=0;
+ key_mod=0;
+ key_hit=0;
+ key_use_timer=0;
+ memset(key_down_arr,0,sizeof(key_down_arr));
+ kbd_setio();
+ return 1;
+}
+
+/**
+ * mx1_kbd_Close - Closes keyboard
+ */
+void
+kbd_Close(void)
+{
+}
+
+/**
+ * mx1_kbd_Poll - Polls for keyboard events
+ *
+ * Returns non-zero value if change is detected.
+ */
+int
+kbd_Poll(void)
+{
+ if(key_hit)
+ return 1;
+ if(kbd_scan())
+ kbd_down();
+ return key_hit?1:0;
+}
+
+/**
+ * kbd_GetModifierInfo - Returns the possible modifiers for the keyboard
+ * @modifiers: If non-NULL, ones in defined modifiers bits are returned.
+ * @curmodifiers: If non-NULL, ones in actually active modifiers
+ * bits are returned.
+ */
+void
+kbd_GetModifierInfo(kbd_keymod_t *modifiers, kbd_keymod_t *curmodifiers)
+{
+ if (modifiers)
+ *modifiers = 0; /* no modifiers available */
+ if (curmodifiers)
+ *curmodifiers = key_mod&~KBDMOD_SGM_SC;
+}
+
+/**
+ * mx1_kbd_Read - Reads resolved MWKEY value, modifiers and scancode
+ * @buf: If non-NULL, resolved MWKEY is stored here
+ * @modifiers: If non-NULL, ones in actually active modifiers
+ * bits are returned
+ * @scancode: If non-NULL, scancode of resolved key is stored
+ * here
+ *
+ * This function reads one keystroke from the keyboard, and the current state
+ * of the modifier keys (ALT, SHIFT, etc). Returns -1 on error, 0 if no data
+ * is ready, 1 on a keypress, and 2 on keyrelease.
+ * This is a non-blocking call.
+ */
+int
+kbd_Read(kbd_key_t *buf, kbd_keymod_t *modifiers, kbd_scan_code_t *scancode)
+{
+ int ret;
+ if(!key_hit) {
+ if(kbd_scan()){
+ kbd_down();
+ }
+ }
+ if(modifiers)
+ *modifiers = key_mod&~KBDMOD_SGM_SC;
+ if(!key_hit)
+ return 0;
+ if(scancode)
+ *scancode = key_last_changed;
+ if(buf)
+ *buf = kbd_scan2key(key_last_changed);
+ ret=key_hit;
+ key_hit=0;
+ return ret;
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+default_CONFIG = CONFIG_KEYVAL=n
+
+ifeq ($(CONFIG_KEYVAL),y)
+lib_LIBRARIES = keyval
+include_HEADERS += keyvalpb.h keyval_id.h
+keyval_SOURCES += keyvalpb.c
+
+include_HEADERS += keyval_mem_store.h
+keyval_SOURCES += keyval_mem_store.c
+
+endif #CONFIG_KEYVAL
--- /dev/null
+#ifndef _KEYVAL_ID_H_
+#define _KEYVAL_ID_H_
+
+#include "keyvalpb.h"
+
+#define KVPB_KEYID_ULAN_ADDR 0x10
+#define KVPB_KEYID_ULAN_SN 0x11
+
+#define KVPB_KEYID_ULAN_PICO 0x15
+#define KVPB_KEYID_ULAN_POCO 0x16
+#define KVPB_KEYID_ULAN_PIOM 0x17
+#define KVPB_KEYID_ULAN_PEV2C 0x18
+
+#define KVPB_KEYID_HIS_ACCESS_CODE 0x20
+
+#endif /* _KEYVAL_ID_H_ */
+
--- /dev/null
+/******************************************************************************/
+/* Key Value block in RAM */
+
+#include <malloc.h>
+#include <string.h>
+#include <keyvalpb.h>
+#include <keyval_mem_store.h>
+
+int kvpb_mem_erase(kvpb_block_t *store, void *base,int size)
+{
+ memset(base,0xff,size);
+ return 0;
+}
+
+int kvpb_mem_copy(kvpb_block_t *store, void *dst,const void *src,int len)
+{
+ memcpy(dst,src,len);
+ return 0;
+}
+
+#ifndef KVPB_MINIMALIZED
+kvpb_block_t *kvpb_store_create_ram(int size)
+{
+ kvpb_block_t *store;
+ int res;
+
+ if(!size)
+ size=0x4000;
+
+ store = malloc(sizeof(*store));
+ if(store == NULL)
+ return NULL;
+
+ memset(store, 0, sizeof(*store));
+
+ store->base = malloc(size*2);
+ if(store->base == NULL)
+ goto error_ret;
+
+ store->size = size;
+ store->flags = KVPB_DESC_DOUBLE;
+ #ifndef KVPB_MINIMALIZED
+ store->erase = kvpb_mem_erase,
+ store->copy = kvpb_mem_copy;
+ #endif /* KVPB_MINIMALIZED */
+
+ kvpb_block_erase(store, store->base,store->size);
+ if(store->flags & KVPB_DESC_DOUBLE)
+ kvpb_block_erase(store, (uint8_t*)store->base+store->size,store->size);
+
+ res=kvpb_check(store,3);
+
+ if(res<0)
+ goto error_ret;
+
+ return store;
+
+ error_ret:
+ if(store)
+ free(store);
+ return NULL;
+}
+#endif /* KVPB_MINIMALIZED */
--- /dev/null
+#ifndef _KEYVAL_MEM_STORE_H
+#define _KEYVAL_MEM_STORE_H
+
+#include <keyvalpb.h>
+
+int kvpb_mem_erase(kvpb_block_t *store, void *base,int size);
+int kvpb_mem_copy(kvpb_block_t *store, void *dst,const void *src,int len);
+kvpb_block_t *kvpb_store_create_ram(int size);
+
+#endif /*_KEYVAL_MEM_STORE_H*/
--- /dev/null
+/*******************************************************************
+ Key Value Persistent Storage
+
+ keyvalpb.c - key value parameters block
+
+ (C) Copyright 2003-2005 by Pavel Pisa - Originator
+ (C) Copyright 2004-2005 by Petr Smolik - Originator
+
+ The uLan utilities library can be used, copied and modified under
+ next licenses
+ - GPL - GNU General Public License
+ - LGPL - GNU Lesser General Public License
+ - MPL - Mozilla Public License
+ - and other licenses added by project originators
+ Code can be modified and re-distributed under any combination
+ of the above listed licenses. If contributor does not agree with
+ some of the licenses, he/she can delete appropriate line.
+ Warning, if you delete all lines, you are not allowed to
+ distribute source code and/or binaries utilizing code.
+
+ See files COPYING and README for details.
+
+ *******************************************************************/
+
+#include <string.h>
+#include "keyvalpb.h"
+
+/*
+ * kvpb_memsum - Compute checksum of given memory area
+ * @base: Pointer to the base of of the region
+ * @size: Size of utilized part of the region
+ *
+ * Return Value: Computed checksum value
+ * File: keyvalpb.c
+ */
+kvpb_sum_t kvpb_memsum(KVPB_DPTRTYPE uint8_t *base, kvpb_size_t size)
+{
+ KVPB_LOCALDATA kvpb_sum_t sum=0;
+ KVPB_DPTRTYPE uint16_t *p=(KVPB_DPTRTYPE uint16_t *)base;
+ size=(size+1)>>1;
+ while(size--){
+ sum+=*(p++);
+ }
+ sum&=KVPB_SUM_MASK;
+ sum|=KVPB_SUM_OKVAL;
+ return sum;
+}
+
+#ifndef KVPB_WITHOUT_HADLE
+/*
+ * kvpb_get_psum - Get pointer to the region check sum
+ * @kvpb_block: Pointer to the KVPB access information/state structure
+ * @base: Pointer to the base of of the region
+ * @size: Size of one data block region
+ *
+ * Return Value: Pointer to the actual region check sum placement
+ * File: keyvalpb.c
+ */
+KVPB_DPTRTYPE kvpb_sum_t *kvpb_get_psum(kvpb_block_t *kvpb_block,
+ KVPB_DPTRTYPE uint8_t *base, kvpb_size_t size)
+#else
+KVPB_DPTRTYPE kvpb_sum_t *__kvpb_get_psum(
+ KVPB_DPTRTYPE uint8_t *base, kvpb_size_t size)
+#endif
+{
+ KVPB_DPTRTYPE kvpb_sum_t *psum;
+ psum=kvpb_psum_align(kvpb_block,(KVPB_DPTRTYPE kvpb_sum_t*)(base+size)-1);
+ while((KVPB_DPTRTYPE uint8_t*)psum>=base) {
+ if (*kvpb_psum_valid_loc(kvpb_block,psum)!=0)
+ return psum;
+ psum=kvpb_psum_align(kvpb_block,psum-1);
+ }
+ return NULL;
+}
+
+#ifndef KVPB_WITHOUT_HADLE
+/*
+ * kvpb_get_cfk - Get space where to place new key-value pair
+ * @kvpb_block: Pointer to the KVPB access information/state structure
+ * @mode: 0 .. work on active/valid data region;
+ * 1 .. work on the first copy/region, 2 .. work on the second copy/region
+ * @size: Size of required space for stored value
+ *
+ * Return Value: Pointer where next pair should be stored or %NULL
+ * File: keyvalpb.c
+ */
+KVPB_DPTRTYPE kvpb_key_t *kvpb_get_cfk(kvpb_block_t *kvpb_block,uint8_t mode,int size)
+#else
+KVPB_DPTRTYPE kvpb_key_t *__kvpb_get_cfk(uint8_t mode,int size)
+#endif
+{
+ KVPB_DPTRTYPE kvpb_sum_t *psum;
+ KVPB_DPTRTYPE uint8_t *p;
+ KVPB_DPTRTYPE uint8_t *r;
+ p=kvpb_region_base(kvpb_block,0);
+ size=kvpb_chunk_align(kvpb_block,size+sizeof(kvpb_key_t))+
+ (kvpb_block->flags&KVPB_DESC_CHUNKWO?kvpb_chunk_size(kvpb_block):0);
+ psum=kvpb_block->psum1;
+ if((!mode && (kvpb_block->flags & KVPB_DESC_USE2ND))||(mode==2)) {
+ if(!(kvpb_block->flags&KVPB_DESC_DOUBLE))
+ return NULL;
+ p=kvpb_region_base(kvpb_block,1);
+ psum=kvpb_block->psum2;
+ }
+ do {
+ kvpb_size_t ksize=((KVPB_DPTRTYPE kvpb_key_t *)p)->size;
+ if(ksize==KVPB_EMPTY)
+ break;
+ if(((uint8_t*)psum-(uint8_t*)p)<ksize)
+ return NULL;
+ p+=kvpb_chunk_align(kvpb_block,ksize+sizeof(kvpb_key_t))+
+ (kvpb_block->flags&KVPB_DESC_CHUNKWO?kvpb_chunk_size(kvpb_block):0);
+ } while(1);
+ r=(KVPB_DPTRTYPE uint8_t*)p+size+sizeof(kvpb_key_t);
+ if(r<p)
+ return NULL;
+ if ((uint8_t*)kvpb_psum_align(kvpb_block,psum-1)<r) {
+ return NULL;
+ }
+ return (KVPB_DPTRTYPE kvpb_key_t*)p;
+}
+
+
+#ifndef KVPB_WITHOUT_HADLE
+/**
+ * kvpb_check - Check data consistency of the KVPB storage
+ * @kvpb_block: Pointer to the KVPB access information/state structure
+ * @mode: if mode is nonzero, try to restore valid state or erase all data
+ *
+ * Return Value: 0 .. all regions are correct, 1 .. the first region is valid, the second
+ * region is invalid or has been updated if @mode has been set, 2 .. the second region
+ * is valid, the first is invalid or has been updated if @mode has been set, 3 .. both
+ * regions has been erased and emptied, -1 .. the state is inconsistent and no valid
+ * region has been found and state has not be corrected
+ * File: keyvalpb.c
+ */
+int kvpb_check(kvpb_block_t *kvpb_block, uint8_t mode)
+#else
+int __kvpb_check(uint8_t mode)
+#endif
+{
+ KVPB_DPTRTYPE uint8_t *p;
+ KVPB_LOCALDATA int ret=-1;
+ KVPB_LOCALDATA kvpb_sum_t sum;
+
+ kvpb_block->flags&=~KVPB_DESC_USE2ND;
+
+ p=kvpb_region_base(kvpb_block,0);
+ kvpb_block->psum1=kvpb_get_psum(kvpb_block,p,kvpb_block->size);
+ if (kvpb_block->psum1) {
+ sum=kvpb_memsum(p,(KVPB_DPTRTYPE uint8_t*)kvpb_block->psum1-p);
+ if(*kvpb_block->psum1==sum){
+ ret=1;
+ }
+ }
+
+ if(kvpb_block->flags&KVPB_DESC_DOUBLE){
+ p=kvpb_region_base(kvpb_block,1);
+ kvpb_block->psum2=kvpb_get_psum(kvpb_block,p,kvpb_block->size);
+ if (kvpb_block->psum2) {
+ sum=kvpb_memsum(p,(KVPB_DPTRTYPE uint8_t*)kvpb_block->psum2-p);
+ if(*kvpb_block->psum2==sum) {
+ if(ret>=0){
+ ret=0;
+ } else {
+ ret=2;
+ kvpb_block->flags|=KVPB_DESC_USE2ND;
+ }
+ }
+ }
+ } else {
+ if(ret>=0)
+ ret=0;
+ }
+
+ if(ret){
+ if(!mode) {
+ kvpb_block->flags|=KVPB_DESC_RO;
+ } else {
+ /* correct for FLASH */
+ if(ret<0){
+ p=kvpb_region_base(kvpb_block,0);
+ kvpb_block_erase(kvpb_block,p,kvpb_block->size);
+ kvpb_block->psum1=kvpb_psum_align(kvpb_block,(KVPB_DPTRTYPE kvpb_sum_t*)(p+kvpb_block->size)-1);
+ sum=kvpb_memsum(p,(KVPB_DPTRTYPE uint8_t*)kvpb_block->psum1-p);
+ kvpb_block_copy(kvpb_block,kvpb_block->psum1,&sum,sizeof(kvpb_sum_t));
+ if(kvpb_block->flags&KVPB_DESC_DOUBLE){
+ p=kvpb_region_base(kvpb_block,1);
+ kvpb_block_erase(kvpb_block,p,kvpb_block->size);
+ kvpb_block->psum2=kvpb_psum_align(kvpb_block,(KVPB_DPTRTYPE kvpb_sum_t*)(p+kvpb_block->size)-1);
+ sum=kvpb_memsum(p,(KVPB_DPTRTYPE uint8_t*)kvpb_block->psum2-p);
+ kvpb_block_copy(kvpb_block,kvpb_block->psum2,&sum,sizeof(kvpb_sum_t));
+ }
+ ret=3;
+ }else{
+ if(ret==1){
+ kvpb_block_erase(kvpb_block,kvpb_region_base(kvpb_block,1),kvpb_block->size);
+ kvpb_block_copy(kvpb_block,kvpb_region_base(kvpb_block,1),
+ kvpb_region_base(kvpb_block,0),kvpb_block->size);
+
+ }else{
+ kvpb_block_erase(kvpb_block,kvpb_region_base(kvpb_block,0),kvpb_block->size);
+ kvpb_block_copy(kvpb_block,kvpb_region_base(kvpb_block,0),
+ kvpb_region_base(kvpb_block,1),kvpb_block->size);
+ }
+ }
+ kvpb_block->flags&=~KVPB_DESC_RO;
+ }
+ }
+ kvpb_block_flush(kvpb_block);
+ if(ret>=0) kvpb_block->flags|=KVPB_DESC_VALID;
+ return ret;
+}
+
+#ifndef KVPB_WITHOUT_HADLE
+/**
+ * kvpb_first - Get pointer to the first key-value pair in the KVPB storage
+ * @kvpb_block: Pointer to the KVPB access information/state structure
+ * @mode: 0 .. iterate over active/valid data region;
+ * 1 .. iterate over first copy/region, 2 .. iterate over second copy/region
+ *
+ * Return Value: Pointer to the first key-value pair
+ * or %NULL if no pair exist.
+ * File: keyvalpb.c
+ */
+KVPB_DPTRTYPE kvpb_key_t *kvpb_first(kvpb_block_t *kvpb_block, uint8_t mode)
+#else
+KVPB_DPTRTYPE kvpb_key_t *__kvpb_first(uint8_t mode)
+#endif
+{
+ KVPB_DPTRTYPE kvpb_key_t *key=(KVPB_DPTRTYPE kvpb_key_t *)kvpb_region_base(kvpb_block,0);
+ if((!mode && (kvpb_block->flags & KVPB_DESC_USE2ND))||(mode==2)) {
+ if(!(kvpb_block->flags&KVPB_DESC_DOUBLE))
+ return NULL;
+ key=(KVPB_DPTRTYPE kvpb_key_t *)kvpb_region_base(kvpb_block,1);
+ }
+ while(*kvpb_keyid_valid(kvpb_block,key)==KVPB_KEYID_INVALID) {
+ key=kvpb_next(kvpb_block,key);
+ if (!key)
+ return NULL;
+ }
+ return key->size!=KVPB_EMPTY?key:NULL;
+}
+
+#ifndef KVPB_WITHOUT_HADLE
+/**
+ * kvpb_next - Iterate to the next consecutive key-value pair
+ * @kvpb_block: Pointer to the KVPB access information/state structure
+ * @key: Pointer to the previous key-value pair
+ *
+ * Return Value: Pointer to the next key-value pair
+ * or %NULL if no/no-more pairs exist.
+ * File: keyvalpb.c
+ */
+KVPB_DPTRTYPE kvpb_key_t *kvpb_next(kvpb_block_t *kvpb_block, KVPB_DPTRTYPE kvpb_key_t *key)
+#else
+KVPB_DPTRTYPE kvpb_key_t *__kvpb_next(KVPB_DPTRTYPE kvpb_key_t *key)
+#endif
+{
+ do {
+ key=(KVPB_DPTRTYPE kvpb_key_t *)((KVPB_DPTRTYPE uint8_t *)key+
+ kvpb_chunk_align(kvpb_block,key->size+sizeof(kvpb_key_t))+
+ (kvpb_block->flags&KVPB_DESC_CHUNKWO?kvpb_chunk_size(kvpb_block):0));
+ if (key->size==KVPB_EMPTY) return NULL;
+ } while(*kvpb_keyid_valid(kvpb_block,key)==KVPB_KEYID_INVALID);
+ return key;
+}
+
+#ifndef KVPB_WITHOUT_HADLE
+/**
+ * kvpb_find - Find first of occurrence of given key ID
+ * @kvpb_block: Pointer to the KVPB access information/state structure
+ * @keyid: Ordinal value representing key ID
+ * @mode: iteration mode modifier: 0 .. search in the active/valid data region;
+ * 1 .. search in the first copy/region, 2 .. search in the second copy/region
+ * @key: Previous key occurrence pointer or %NULL value to find first key ID named key-value pair
+ *
+ * Return Value: Pointer to the first on subsequent occurrence of key-value pair addressed by given key ID
+ * or %NULL if no/no-more occurrences exists.
+ * File: keyvalpb.c
+ */
+KVPB_DPTRTYPE kvpb_key_t *kvpb_find(kvpb_block_t *kvpb_block, kvpb_keyid_t keyid, uint8_t mode, KVPB_DPTRTYPE kvpb_key_t *key)
+#else
+KVPB_DPTRTYPE kvpb_key_t *__kvpb_find(kvpb_keyid_t keyid, uint8_t mode, KVPB_DPTRTYPE kvpb_key_t *key)
+#endif
+{
+ if(!(kvpb_block->flags&KVPB_DESC_VALID))
+ return NULL;
+ if (key) {
+ key=kvpb_next(kvpb_block, key);
+ } else {
+ key=kvpb_first(kvpb_block, mode);
+ }
+ while(key) {
+ if((key->keyid==keyid) || (keyid==0))
+ return key;
+ key=kvpb_next(kvpb_block, key);
+ }
+ return key;
+}
+
+#ifndef KVPB_WITHOUT_HADLE
+/**
+ * kvpb_compact_region - Compact one KVPB data block/region
+ * @kvpb_block: Pointer to the KVPB access information/state structure
+ * @keyid: Key ID which should be omitted from compacted data
+ * @mode: 0 .. compact active/valid data region;
+ * 1 .. compact the first data copy, 2 .. compact the second copy
+ *
+ * Return Value: Operation cannot be finished.
+ * File: keyvalpb.c
+ */
+int kvpb_compact_region(kvpb_block_t *kvpb_block, uint8_t mode, kvpb_keyid_t keyid)
+#else
+int __kvpb_compact_region(uint8_t mode, kvpb_keyid_t keyid)
+#endif
+{
+ KVPB_DPTRTYPE uint8_t *p;
+ KVPB_DPTRTYPE kvpb_key_t *des,*src;
+
+ p=kvpb_region_base(kvpb_block,0);
+ des=(KVPB_DPTRTYPE kvpb_key_t*)p;
+ if(kvpb_block->flags&KVPB_DESC_DOUBLE)
+ src=(KVPB_DPTRTYPE kvpb_key_t*)kvpb_region_base(kvpb_block,1);
+ else
+ src=(KVPB_DPTRTYPE kvpb_key_t*)p;
+
+ if((!mode && (kvpb_block->flags & KVPB_DESC_USE2ND))||(mode==2)) {
+ if(!(kvpb_block->flags&KVPB_DESC_DOUBLE))
+ return -1;
+ des=src;
+ src=(KVPB_DPTRTYPE kvpb_key_t*)p;
+ p=(KVPB_DPTRTYPE uint8_t *)des;
+ kvpb_block->psum2=kvpb_psum_align(kvpb_block,
+ (KVPB_DPTRTYPE kvpb_sum_t*)(p+kvpb_block->size)-1);
+ } else {
+ kvpb_block->psum1=kvpb_psum_align(kvpb_block,
+ (KVPB_DPTRTYPE kvpb_sum_t*)(p+kvpb_block->size)-1);
+ }
+ kvpb_block_flush(kvpb_block);
+ kvpb_block_erase(kvpb_block,des,kvpb_block->size);
+ while(src) {
+ int s=kvpb_chunk_align(kvpb_block,src->size+sizeof(kvpb_key_t));
+ if((*kvpb_keyid_valid(kvpb_block,src)!=KVPB_KEYID_INVALID) && (src->keyid!=keyid)) {
+ if(src!=des)
+ kvpb_block_copy(kvpb_block,des,src,s);
+ if (kvpb_block->flags&KVPB_DESC_CHUNKWO) s+=kvpb_chunk_size(kvpb_block);
+ des=(KVPB_DPTRTYPE kvpb_key_t*)((uint8_t*)des+s);
+ }
+ src=kvpb_next(kvpb_block, src);
+ }
+ kvpb_block_flush(kvpb_block);
+ return 0;
+}
+
+#ifndef KVPB_WITHOUT_HADLE
+/**
+ * kvpb_get_key - Get value for given key ID
+ * @kvpb_block: Pointer to the KVPB access information/state structure
+ * @keyid: Ordinal value representing key ID
+ * @size: The size of the buffer provided to store data into
+ * @buf: Pointer to the buffer, where retrieved data should be copied
+ *
+ * Return Value: Number of retrieved value bytes if operation is successful
+ * or -1 if there is no such key ID or operation fails for other reason.
+ * File: keyvalpb.c
+ */
+int kvpb_get_key(kvpb_block_t *kvpb_block, kvpb_keyid_t keyid, kvpb_size_t size, void *buf)
+#else
+int __kvpb_get_key(kvpb_keyid_t keyid, kvpb_size_t size, void *buf)
+#endif
+{
+ KVPB_DPTRTYPE kvpb_key_t *key;
+ key=kvpb_find(kvpb_block,keyid,0,NULL);
+ if(!key) return -1;
+ if(size && buf){
+ if(key->size<size)
+ size=key->size;
+ memcpy(buf,key+1,size);
+ }
+ return key->size;
+}
+
+
+#ifndef KVPB_WITHOUT_HADLE
+/**
+ * kvpb_set_key - Set new value or define new key-value pair
+ * @kvpb_block: Pointer to the KVPB access information/state structure
+ * @keyid: Ordinal value representing key ID, if or-red with %KVPB_KEYID_DUPLIC,
+ * the key ID can be defined/inserted multiple times
+ * @size: Stored value size in bytes
+ * @buf: Pointer to the stored value data
+ *
+ * Return Value: Number of stored bytes (equal to @size) if operation is successful
+ * or -1 if operation fails.
+ * File: keyvalpb.c
+ */
+int kvpb_set_key(kvpb_block_t *kvpb_block, kvpb_keyid_t keyid, kvpb_size_t size, const void *buf)
+#else
+int __kvpb_set_key(kvpb_keyid_t keyid, kvpb_size_t size, const void *buf)
+#endif
+{
+ KVPB_LOCALDATA kvpb_sum_t sum;
+ KVPB_DPTRTYPE kvpb_sum_t *psum;
+ KVPB_DPTRTYPE kvpb_key_t *key;
+ KVPB_DPTRTYPE uint8_t *p;
+
+ if(!(kvpb_block->flags&KVPB_DESC_VALID))
+ return -1;
+ if(kvpb_block->flags&KVPB_DESC_RO)
+ return -1;
+
+ /*first region*/
+ psum=kvpb_psum_align(kvpb_block,kvpb_block->psum1);
+ sum=0;
+ kvpb_block_copy(kvpb_block,kvpb_psum_valid_loc(kvpb_block,psum),&sum,sizeof(kvpb_sum_t));
+ kvpb_block->psum1=kvpb_psum_align(kvpb_block,kvpb_block->psum1-1);
+ if (!(keyid&KVPB_KEYID_DUPLIC) || !buf) {
+ kvpb_each_from(kvpb_block,keyid,1,key) {
+ kvpb_keyid_t dkeyid=KVPB_KEYID_INVALID;
+ kvpb_block_copy(kvpb_block,kvpb_keyid_valid(kvpb_block,key),&dkeyid,sizeof(kvpb_keyid_t));
+ }
+ }
+ key=kvpb_get_cfk(kvpb_block,1,size);
+ if (!key) {
+ kvpb_compact_region(kvpb_block,1,(keyid&KVPB_KEYID_DUPLIC)?0:keyid);
+ key=kvpb_get_cfk(kvpb_block,1,size);
+ }
+ if (keyid && key && buf) {
+ kvpb_block_copy(kvpb_block,&key->size,&size,sizeof(kvpb_size_t));
+ kvpb_block_copy(kvpb_block,&key->keyid,&keyid,sizeof(kvpb_keyid_t));
+ kvpb_block_copy(kvpb_block,(uint8_t*)(key+1),buf,/*align???*/ size);
+ }
+ /* need flush data to count correct value of new check sum */
+ kvpb_block_flush(kvpb_block);
+
+ p=kvpb_region_base(kvpb_block,0);
+ sum=kvpb_memsum(p,(KVPB_DPTRTYPE uint8_t*)kvpb_block->psum1-p);
+ kvpb_block_copy(kvpb_block,kvpb_block->psum1,&sum,sizeof(kvpb_sum_t));
+ kvpb_block_flush(kvpb_block);
+ if(!(kvpb_block->flags&KVPB_DESC_DOUBLE))
+ return key?size:-1;
+
+ /*Write in the first region failed, switching to backup region */
+ if(kvpb_block->flags&KVPB_DESC_RO){
+ kvpb_block->flags|=KVPB_DESC_USE2ND;
+ return -1;
+ }
+
+ /*second region*/
+ psum=kvpb_psum_align(kvpb_block,kvpb_block->psum2);
+ sum=0;
+ kvpb_block_copy(kvpb_block,kvpb_psum_valid_loc(kvpb_block,psum),&sum,sizeof(kvpb_sum_t));
+ kvpb_block->psum2=kvpb_psum_align(kvpb_block,kvpb_block->psum2-1);
+ if (!(keyid&KVPB_KEYID_DUPLIC) || !buf) {
+ kvpb_each_from(kvpb_block,keyid,2,key) {
+ kvpb_keyid_t dkeyid=KVPB_KEYID_INVALID;
+ kvpb_block_copy(kvpb_block,kvpb_keyid_valid(kvpb_block,key),&dkeyid,sizeof(kvpb_keyid_t));
+ }
+ }
+ key=kvpb_get_cfk(kvpb_block,2,size);
+ if (!key) {
+ kvpb_compact_region(kvpb_block,2,(keyid&KVPB_KEYID_DUPLIC)?0:keyid);
+ key=kvpb_get_cfk(kvpb_block,2,size);
+ }
+ if (keyid && key && buf) {
+ kvpb_block_copy(kvpb_block,&key->size,&size,sizeof(kvpb_size_t));
+ kvpb_block_copy(kvpb_block,&key->keyid,&keyid,sizeof(kvpb_keyid_t));
+ kvpb_block_copy(kvpb_block,(uint8_t*)(key+1),buf,/*align???*/ size);
+ }
+ kvpb_block_flush(kvpb_block);
+
+ p=kvpb_region_base(kvpb_block,1);
+ sum=kvpb_memsum(p,(KVPB_DPTRTYPE uint8_t*)kvpb_block->psum2-p);
+ kvpb_block_copy(kvpb_block,kvpb_block->psum2,&sum,sizeof(kvpb_sum_t));
+ kvpb_block_flush(kvpb_block);
+ /*Write in the second region failed, switching to the first region */
+ if(kvpb_block->flags&KVPB_DESC_RO){
+ kvpb_block->flags&=~KVPB_DESC_USE2ND;
+ return -1;
+ }
+
+ return key?size:-1;
+}
+
+#ifndef KVPB_MINIMALIZED
+/**
+ * kvpb_err_keys - Erase/delete key-value pair
+ * @kvpb_block: Pointer to the KVPB access information/state structure
+ * @keyid: Ordinal value representing key ID
+ *
+ * Return Value: Positive or zero value informs about successful operation,
+ * -1 if operation fails.
+ * File: keyvalpb.c
+ */
+int kvpb_err_keys(kvpb_block_t *kvpb_block, kvpb_keyid_t keyid)
+{
+ return kvpb_set_key(kvpb_block,keyid,0,NULL);
+}
+#endif /*KVPB_MINIMALIZED*/
+
--- /dev/null
+/*******************************************************************
+ Key Value Persistent Storage
+
+ keyvalpb.h - key value parameters block
+
+ (C) Copyright 2003-2005 by Pavel Pisa - Originator
+ (C) Copyright 2004-2005 by Petr Smolik - Originator
+
+ The uLan utilities library can be used, copied and modified under
+ next licenses
+ - GPL - GNU General Public License
+ - LGPL - GNU Lesser General Public License
+ - MPL - Mozilla Public License
+ - and other licenses added by project originators
+ Code can be modified and re-distributed under any combination
+ of the above listed licenses. If contributor does not agree with
+ some of the licenses, he/she can delete appropriate line.
+ Warning, if you delete all lines, you are not allowed to
+ distribute source code and/or binaries utilizing code.
+
+ See files COPYING and README for details.
+
+ *******************************************************************/
+
+#ifndef _KEYVALPB_H_
+#define _KEYVALPB_H_
+
+//#include <inttypes.h>
+#include <types.h>
+#include <system_def.h>
+#include <cpu_def.h>
+
+#ifdef KVPB_MINIMALIZED
+#define KVPB_WITHOUT_HADLE
+#define KVPB_DPTRTYPE CODE
+#define KVPB_LOCALDATA DATA
+#endif /*KVPB_MINIMALIZED*/
+
+#ifndef KVPB_DPTRTYPE
+#define KVPB_DPTRTYPE
+#endif /*KVPB_DPTRTYPE*/
+
+#ifndef KVPB_LOCALDATA
+#define KVPB_LOCALDATA
+#endif /*KVPB_DPTRTYPE*/
+
+#ifndef KVPB_BLOCK_LOC
+#define KVPB_BLOCK_LOC
+#endif /*KVPB_BLOCK_LOC*/
+
+#define KVPB_EMPTY ((kvpb_size_t)~0)
+
+#define KVPB_KEYID_INVALID 0
+#define KVPB_KEYID_DUPLIC ((((kvpb_keyid_t)~0)>>1)+1)
+#define KBPB_KEYID_INVALID_BIT (KVPB_KEYID_DUPLIC>>1)
+
+#define KVPB_SUM_MASK (((kvpb_sum_t)~0)>>2)
+#define KVPB_SUM_OKVAL (KVPB_SUM_MASK+1)
+
+#define KVPB_DESC_DOUBLE 0x01
+#define KVPB_DESC_USE2ND 0x02
+#define KVPB_DESC_VALID 0x04
+#define KVPB_DESC_RO 0x08
+#define KVPB_DESC_CHUNKWO 0x10
+#define KVPB_DESC_ALIGN4 0x40
+#define KVPB_DESC_FLASH 0x80
+
+#ifdef KVPB_MINIMALIZED
+typedef uint16_t kvpb_sum_t;
+typedef uint16_t kvpb_size_t;
+typedef uint8_t kvpb_keyid_t;
+#else /*KVPB_MINIMALIZED*/
+typedef uint32_t kvpb_sum_t;
+typedef uint32_t kvpb_size_t;
+typedef uint32_t kvpb_keyid_t;
+#endif /*KVPB_MINIMALIZED*/
+
+/**
+ * struct kvpb_block - Key-value parameter block access information
+ * @base: Pointer to the start of physically mapped key-value block data
+ * @size: Size of one region (one data copy) of parameter block
+ * @flags: Block state flags:
+ * %KVPB_DESC_DOUBLE - the information is stored in two consecutive redundant copies/regions;
+ * %KVPB_DESC_USE2ND - data will be read from the second copy because first one is damaged;
+ * %KVPB_DESC_VALID - at least one region is valid;
+ * %KVPB_DESC_RO - because of some problems, only read access is allowed
+ * %KVPB_DESC_CHUNKWO - chunk can be written only once between erase operations
+ * %KVPB_DESC_ALIGN4 - data has to be aligned to four bytes
+ * %KVPB_DESC_FLASH - flash memory is used for data storage
+ * @psum1: Pointer to the control checksum of the first data region
+ * @psum2: Pointer to the control checksum of the second data region
+ * @erase: Function to erase some range of the storage region
+ * @copy: Function to copy data into or between storage regions
+ * @flush: Function to finish pending copy operations
+ * @chunk_size: Minimal store chunk size which can be independently modified
+ *
+ * File: keyvalpb.h
+ */
+typedef struct kvpb_block {
+ KVPB_DPTRTYPE uint8_t *base;
+ kvpb_size_t size;
+ short flags;
+ KVPB_DPTRTYPE kvpb_sum_t *psum1;
+ KVPB_DPTRTYPE kvpb_sum_t *psum2;
+ #ifndef KVPB_MINIMALIZED
+ int (*erase)(struct kvpb_block *store, void *base,int size);
+ int (*copy)(struct kvpb_block *store, void *des,const void *src,int len);
+ int (*flush)(struct kvpb_block *store);
+ unsigned chunk_size;
+ #endif /* KVPB_MINIMALIZED */
+} kvpb_block_t;
+
+
+#define kvpb_region_base(block,regidx) \
+ ((((KVPB_DPTRTYPE uint8_t *)(block)->base)+(regidx*(block)->size)))
+
+#ifndef KVPB_MINIMALIZED
+ #ifndef kvpb_chunk_size
+ #define kvpb_chunk_size(store) ((store)->chunk_size<4?4:(store)->chunk_size)
+ #endif /*kvpb_chunk_size*/
+ #define kvpb_chunk_size_mask(store) (kvpb_chunk_size(store)-1)
+
+/**
+ * kvpb_chunk_align - Round up KVPB size to minimal store chunk size multiple
+ * @store: Pointer to the KVPB access information/state structure
+ * @size: Unaligned size
+ *
+ * Return Value: Minimal aligned size to hold unaligned size.
+ * File: keyvalpb.h
+ */
+ static inline unsigned kvpb_chunk_align(struct kvpb_block *store, unsigned size)
+ {
+ return ((size)+kvpb_chunk_size_mask(store))&~kvpb_chunk_size_mask(store);
+ }
+
+/**
+ * kvpb_psum_align - Round up KVPB size to minimal store chunk size multiple
+ * @store: Pointer to the KVPB access information/state structure
+ * @psum: Pointer to proposed location of next check sum location
+ *
+ * Return Value: Pointer to next check sum location rounded down to next slot.
+ * File: keyvalpb.h
+ */
+ static inline kvpb_sum_t* kvpb_psum_align(struct kvpb_block *store, kvpb_sum_t *psum)
+ {
+ unsigned long mask=~kvpb_chunk_size_mask(store);
+ if(store->flags&KVPB_DESC_CHUNKWO)
+ mask<<=1;
+ return (kvpb_sum_t*)(((unsigned long)(psum))&mask);
+ }
+
+/**
+ * kvpb_psum_valid_loc - Return pointer to check sum validity info location
+ * @store: Pointer to the KVPB access information/state structure
+ * @psum: Pointer to corectly aligned check sum location
+ *
+ * Return Value: Pointer to location which indicates by zero value, that check sum
+ * is invalidated.
+ * File: keyvalpb.h
+ */
+ static inline kvpb_sum_t* kvpb_psum_valid_loc(struct kvpb_block *store, kvpb_sum_t *psum)
+ {
+ if(!(store->flags&KVPB_DESC_CHUNKWO))
+ return psum;
+ else
+ return (kvpb_sum_t*)(((char *)(psum))+kvpb_chunk_size(store));
+ }
+
+/**
+ * kvpb_block_erase - Wrapper function to call KVPB specific data erase function
+ * @store: Pointer to the KVPB access information/state structure
+ * @base: Base address of erased region inside parameter block data region
+ * @size: Number of bytes to erase
+ *
+ * The KVPB mechanism is intended for FLASH type memories and it expect
+ * that only whole data region can be erased at time. The expected erase state
+ * is all bits set to the ones.
+ *
+ * Return Value: Negative value indicates operation fault.
+ * File: keyvalpb.h
+ */
+ static inline int kvpb_block_erase(struct kvpb_block *store, void *base,int size)
+ {
+ return store->erase(store, base,size) ;
+ }
+
+/**
+ * kvpb_block_copy - Wrapper function to call KVPB specific data copy function
+ * @store: Pointer to the KVPB access information/state structure
+ * @des: Address of data destination pointing inside mapped parameter block data region
+ * @src: Address of data source pointing inside mapped parameter block data or RAM memory
+ * @len: Number of bytes to transfer
+ *
+ * Return Value: Negative value indicates operation fault.
+ * File: keyvalpb.h
+ */
+ static inline int kvpb_block_copy(struct kvpb_block *store, void *des,const void *src,int len)
+ {
+ return store->copy(store, des, src, len);
+ }
+
+/**
+ * kvpb_block_flush - Wrapper function to call KVPB specific flush function
+ * @store: Pointer to the KVPB access information/state structure
+ *
+ * Return Value: Negative value indicates operation fault.
+ * File: keyvalpb.h
+ */
+ static inline int kvpb_block_flush(struct kvpb_block *store)
+ {
+ if(!(store->flush)) return 0;
+ return store->flush(store);
+ }
+
+#else /* KVPB_MINIMALIZED */
+ #ifndef kvpb_chunk_size
+ #define kvpb_chunk_size(store) 1
+ #endif /*kvpb_chunk_size*/
+ #define kvpb_chunk_size_mask(store) (kvpb_chunk_size(store)-1)
+ #define kvpb_chunk_align(store,x) \
+ (((x)+kvpb_chunk_size_mask(store))&~kvpb_chunk_size_mask(store))
+ #define kvpb_psum_align(store,x) \
+ ((KVPB_DPTRTYPE kvpb_sum_t*)((unsigned)(x)&~kvpb_chunk_size_mask(store)))
+ #define kvpb_psum_valid_loc(store,x) \
+ ((kvpb_sum_t*)((char*)(x)+0*kvpb_chunk_size(store)))
+#ifndef kvpb_block_copy
+ #define kvpb_block_erase(store, base, size) flash_erase(base, size)
+ #define kvpb_block_copy(store, des, src, len) flash_copy(des, src, len)
+ #define kvpb_block_flush(store) flash_flush()
+
+ /* forward declarations for external procedures */
+ int flash_erase(void *base,int size);
+ int flash_copy(void *des,const void *src,int len);
+#ifndef flash_flush
+ int flash_flush(void);
+#endif /* flash_flush */
+#endif /* kvpb_block_copy */
+#endif /* KVPB_MINIMALIZED */
+
+/**
+ * struct kvpb_key - Header of stored key value pair and structure for iteration over KVPB
+ * @size: Non-aligned byte size of the stored value
+ * @keyid: Ordinal value representing stored data key
+ *
+ * The header structure is followed by @size data bytes in the KVPB storage block.
+ * Because only word aligned write accesses are possible on some architectures
+ * and memory types the whole size of space occupied by one key-value pair is
+ * sum of rounded-up data size kvpb_chunk_align(@size) and size of header sizeof(kvpb_key_t).
+ */
+typedef struct kvpb_key {
+ kvpb_size_t size;
+ kvpb_keyid_t keyid;
+} kvpb_key_t;
+
+#ifndef KVPB_WITHOUT_HADLE
+ static inline kvpb_keyid_t* kvpb_keyid_valid(struct kvpb_block *store, kvpb_key_t *key)
+ {
+ if(store->flags&KVPB_DESC_CHUNKWO)
+ return (kvpb_keyid_t*)((uint8_t*)key+(kvpb_chunk_align(store,key->size+sizeof(kvpb_key_t))));
+ return &(key->keyid);
+ }
+#else
+ #define kvpb_keyid_valid(store,key) (&((key)->keyid))
+#endif /*KVPB_WITHOUT_HADLE*/
+
+
+#ifndef KVPB_WITHOUT_HADLE
+KVPB_DPTRTYPE kvpb_key_t *kvpb_first(kvpb_block_t *block, uint8_t mode);
+KVPB_DPTRTYPE kvpb_key_t *kvpb_next(kvpb_block_t *block, KVPB_DPTRTYPE kvpb_key_t *key);
+KVPB_DPTRTYPE kvpb_key_t *kvpb_find(kvpb_block_t *block, kvpb_keyid_t keyid, uint8_t mode, KVPB_DPTRTYPE kvpb_key_t *key);
+int kvpb_get_key(kvpb_block_t *kvpb_block, kvpb_keyid_t keyid, kvpb_size_t size, void *buf);
+int kvpb_set_key(kvpb_block_t *kvpb_block, kvpb_keyid_t keyid, kvpb_size_t size, const void *buf);
+int kvpb_err_keys(kvpb_block_t *kvpb_block, kvpb_keyid_t keyid);
+int kvpb_check(kvpb_block_t *kvpb_block, uint8_t mode);
+#else
+extern KVPB_BLOCK_LOC kvpb_block_t kvpb_block_global;
+#define kvpb_block (&kvpb_block_global)
+KVPB_DPTRTYPE kvpb_sum_t *__kvpb_get_psum(KVPB_DPTRTYPE uint8_t *base, kvpb_size_t size);
+KVPB_DPTRTYPE kvpb_key_t *__kvpb_first(uint8_t mode);
+KVPB_DPTRTYPE kvpb_key_t *__kvpb_next(KVPB_DPTRTYPE kvpb_key_t *key);
+KVPB_DPTRTYPE kvpb_key_t *__kvpb_find(kvpb_keyid_t keyid, uint8_t mode, KVPB_DPTRTYPE kvpb_key_t *key);
+int __kvpb_get_key(kvpb_keyid_t keyid, kvpb_size_t size, void *buf);
+int __kvpb_set_key(kvpb_keyid_t keyid, kvpb_size_t size, const void *buf);
+int __kvpb_check(uint8_t mode);
+#define kvpb_get_psum(block, base, size) __kvpb_get_psum(base, size)
+#define kvpb_first(block, mode) __kvpb_first(mode)
+#define kvpb_next(block, key) __kvpb_next(key)
+#define kvpb_find(block, keyid, mode, key) __kvpb_find(keyid, mode, key)
+#define kvpb_get_key(block, keyid, size, buf) __kvpb_get_key(keyid, size, buf)
+#define kvpb_set_key(block, keyid, size, buf) __kvpb_set_key(keyid, size, buf)
+#define kvpb_err_keys(block,keyid) kvpb_set_key(block,keyid,0,NULL)
+#define kvpb_check(block, mode) __kvpb_check(mode)
+#define kvpb_compact_region(block, mode, keyid) __kvpb_compact_region(mode, keyid)
+#define kvpb_get_cfk(block,mode,size) __kvpb_get_cfk(mode,size)
+#endif
+
+/**
+ * kvpb_for_each - Iterate over all key value pairs
+ * @root: Pointer to the KVPB access information/state structure
+ * @key: Iterator of kvpb_key_t* type
+ * @mode: iteration mode modifier: 0 .. iterate over active/valid data region;
+ * 1 .. iterate over first copy, 2 .. iterate over second copy
+ *
+ * File: keyvalpb.h
+ */
+#define kvpb_for_each(root, key,mode) \
+ for(key=kvpb_first(root,mode);key;\
+ key=kvpb_next(root, key))
+
+/**
+ * kvpb_for_each - Iterate over all key value pairs matching given key ID
+ * @root: Pointer to the KVPB access information/state structure
+ * @keyid: Ordinal value representing key ID
+ * @key: Iterator of kvpb_key_t* type
+ * @mode: iteration mode modifier: 0 .. iterate over active/valid data region;
+ * 1 .. iterate over first copy, 2 .. iterate over second copy
+ *
+ * File: keyvalpb.h
+ */
+#define kvpb_each_from(root, keyid, mode, key) \
+ for(key=kvpb_find(root,keyid,mode,NULL);key;\
+ key=kvpb_find(root,keyid,mode,key))
+
+#ifdef KVPB_MINIMALIZED
+#define kvpb_key2data(key) ((void*)(key+1))
+#else /*KVPB_MINIMALIZED*/
+static inline void* kvpb_key2data(kvpb_key_t *key) { return key+1; }
+#endif /*KVPB_MINIMALIZED*/
+
+#endif /* _KEYVALPB_H_ */
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+SUBDIRS = base pdiusb more lpcusb
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+default_CONFIG = CONFIG_USB_BASE=x
+
+ifeq ($(CONFIG_USB_BASE),y)
+lib_LIBRARIES = usbbase
+
+#shared_LIBRARIES =
+
+#include_HEADERS =
+
+nobase_include_HEADERS = usb/usb.h usb/usb_spec.h usb/usb_srq.h usb/usbdebug.h usb/usb_devdes.h
+
+usbbase_SOURCES = usb.c usbdebug.c usbstdresp.c
+
+#lib_LOADLIBES =
+#bin_PROGRAMS =
+endif #CONFIG_USB_BASE
+
+
+
--- /dev/null
+/*****************************************************/
+/*** Module : USB module ***/
+/*** Author : Roman Bartosinski (C) 28.04.2002 ***/
+/*** Modify : 08.08.2002, 16.04.2003 ***/
+/*****************************************************/
+
+//#include "hal.h"
+#include <stdio.h>
+#include <string.h>
+#include <system_def.h>
+#include <endian.h>
+#if __BYTE_ORDER == __BIG_ENDIAN
+ #include <byteswap.h>
+#endif
+
+//#include <usb/pdiusb.h> /* to by tu pak nemelo bejt vubec ... */
+#include <usb/usb.h>
+#include <usb/usbdebug.h>
+
+/* ep0 buffer */
+ __xdata unsigned char ep0_buffer[ MAX_CONTROL_XFER_DATA_SIZE];
+
+
+/* usb initialize */
+ int usb_init( usb_device_t *udev) {
+ int ret = 0;
+ usb_debug_print( DEBUG_LEVEL_LOW, ("init_usb\r\n"));
+ /* create dynamic fields - endpoints */
+
+ udev->ep_events = 0;
+ udev->flags = 0;
+ udev->configuration = 0;
+ //udev->altinterface = 0;
+ udev->ep0.udev = udev;
+ udev->ep0.flags = USB_STATE_IDLE;
+ udev->ep0.epnum = 0;
+
+// usb_init_stdreq_fnc( udev);
+
+ if ( usb_udev_is_fnc(udev,init)) {
+ ret = usb_udev_init( udev);
+ }
+ return ret;
+ }
+
+
+// connecting to USB by SoftConnect
+ int usb_connect( usb_device_t *udev) {
+ int ret = 0;
+ usb_debug_print( DEBUG_LEVEL_LOW,("USB:ON\n"));
+
+ udev->ep_events = 0;
+ udev->flags = 0;
+ udev->configuration = 0;
+ //udev->altinterface = 0;
+ udev->ep0.flags &= ~USB_STATE_MASK; //state = USB_STATE_IDLE;
+
+ if ( usb_udev_is_fnc(udev,connect)) {
+ ret = usb_udev_connect( udev);
+ }
+ return ret;
+ }
+
+
+ int usb_disconnect( usb_device_t *udev) {
+ int ret = 0;
+ usb_debug_print( DEBUG_LEVEL_LOW,("USB:OFF\n"));
+
+ udev->flags &= ~USB_FLAG_CONFIGURED;
+ udev->configuration = 0;
+ udev->ep_events = 0;
+ //udev->altinterface = 0;
+ udev->ep0.flags &= ~USB_STATE_MASK; //state = USB_STATE_IDLE;
+
+ if ( usb_udev_is_fnc(udev,disconnect)) {
+ ret = usb_udev_disconnect( udev);
+ }
+ return ret;
+ }
+
+
+ void usb_stall( usb_ep_t *ep) {
+ usb_debug_print( DEBUG_LEVEL_HIGH, ("USB:STALL %1d\n", ep->epnum));
+ if ( usb_udev_is_fnc(ep->udev,stall)) {
+ usb_udev_stall( ep);
+ }
+ }
+
+
+ int usb_check_events( usb_device_t *udev)
+ {
+ int ret = 0;
+ if ( usb_udev_is_fnc( udev, check_events)) {
+ ret = usb_udev_check_events( udev);
+ }
+ return ret;
+ }
+
+
+// ************************************
+// *** Control transfer functions ***
+// ************************************
+
+ void usb_complete_control_transfer(usb_ep_t *ep0, int status) {
+ usb_debug_print( DEBUG_LEVEL_HIGH, ( "CCT:st=%d", status));
+ #ifdef USB_WITH_CB_FNC
+ if ( ep0->complete_fnc )
+ ep0->complete_fnc( ep0, status);
+ ep0->next_pkt_fnc = NULL;
+ ep0->complete_fnc = NULL;
+ #endif /*USB_WITH_CB_FNC*/
+ ep0->flags &= ~USB_STATE_MASK; //state = USB_STATE_IDLE;
+ }
+
+/* Send any data in the data phase of the control transfer */
+ void usb_send_control_data( usb_device_t *udev, unsigned char *pData, unsigned short len) {
+ usb_ep_t *ep0 = &(udev->ep0);
+ usb_debug_print( DEBUG_LEVEL_HIGH, ( "SCD:ptr=%p,s=%d\n", pData, len));
+ ep0->efnc = NULL;
+ ep0->ptr = pData;
+ ep0->actual = 0;
+ if ( ep0->size > len) ep0->size = len;
+
+ /* Schedule TX processing for later execution */
+ ep0->flags = (ep0->flags & ~USB_STATE_MASK) | USB_STATE_TRANSMIT;
+ udev->flags |= USB_FLAG_EVENT_TX0;
+ }
+
+ void usb_set_control_endfnc( usb_device_t *udev, endfnc_t *efnc) { //REENTRANT_SIGN {
+ udev->ep0.efnc = efnc;
+ }
+
+ void usb_ack_setup( usb_ep_t *ep) {
+ usb_udev_ack_setup(ep->udev);
+ }
+
+
+/*************************************************************
+ *** Control endpoint0 responses
+ *************************************************************/
+ int usb_control_response( usb_device_t *udev) {
+ int ret = 0;
+ usb_ep_t *ep0 = &(udev->ep0);
+
+/* response to interrupt BusReset */
+ if ( udev->flags & USB_FLAG_BUS_RESET) {
+ udev->flags &= ~(USB_FLAG_BUS_RESET | USB_FLAG_SUSPEND); // usb_flags.bus_reset = 0; usb_flags.configured = 0;
+ usb_debug_print( DEBUG_LEVEL_MEDIUM, ( "USBreset\n"));
+ ret = 1;
+ }
+/* response to interrupt Suspend */
+ if ( udev->flags & USB_FLAG_SUSPEND) {
+ udev->flags &= ~(USB_FLAG_SUSPEND); //usb_flags.suspend = 0;
+ usb_debug_print( DEBUG_LEVEL_MEDIUM, ( "USBsuspend\n"));
+ ret = 1;
+ }
+
+
+/* response to interrupt SetupPacket execute response to standard device request or vendor request */
+ if ( udev->flags & USB_FLAG_SETUP) {
+ unsigned char type;
+ USB_DEVICE_REQUEST *preq = &(udev->request);
+
+ ep0->ptr = NULL;
+ ep0->size = 0;
+ ep0->actual = 0;
+ ep0->efnc = NULL;
+ ep0->flags &= ~USB_STATE_MASK; //state = USB_STATE_IDLE;
+ udev->flags &= ~USB_FLAG_SETUP; // usb_flags.setup_packet = 0;
+ #ifdef USB_WITH_CB_FNC
+ ep0->next_pkt_fnc = NULL;
+ ep0->complete_fnc = NULL;
+ #endif /*USB_WITH_CB_FNC*/
+
+ if ( usb_udev_read_endpoint(ep0, preq, sizeof( USB_DEVICE_REQUEST))
+ != sizeof( USB_DEVICE_REQUEST)) {
+ usb_udev_stall( ep0);
+ return -1;
+ }
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ preq->wValue = bswap_16( preq->wValue);
+ preq->wIndex = bswap_16( preq->wIndex);
+ preq->wLength = bswap_16( preq->wLength);
+ #endif
+ usb_debug_print( DEBUG_LEVEL_MEDIUM,( "SePa:x%02X,x%02X,x%04X,x%04X,x%04X\n", preq->bmRequestType, preq->bRequest, preq->wValue, preq->wIndex, preq->wLength));
+
+ // acknowledge setup here
+ if(usb_udev_is_fnc( udev, ack_control_setup)) {
+ usb_udev_ack_control_setup(udev);
+ }
+
+ ep0->size = preq->wLength;
+ if ((( preq->bmRequestType & USB_DATA_DIR_MASK) == USB_DATA_DIR_FROM_HOST) && preq->wLength) {
+ ep0->ptr = ep0_buffer;
+ ep0->flags = (ep0->flags & ~USB_STATE_MASK) | USB_STATE_RECEIVE;
+ }
+
+ type = preq->bmRequestType & USB_REQUEST_TYPE_MASK;
+ if ( type == USB_STANDARD_REQUEST) {
+ int ret = -1;
+ #ifdef USB_WITH_CB_FNC
+ if ( udev->standard_fnc != NULL)
+ ret = udev->standard_fnc( udev);
+ else
+ #endif /*USB_WITH_CB_FNC*/
+ ret = usb_standard_control_response( udev);
+ if (ret<0)
+ usb_udev_stall( ep0);
+ } else {
+ if ( type == USB_VENDOR_REQUEST) {
+ #ifdef USB_WITH_CB_FNC
+ int ret = -1;
+ if ( udev->vendor_fnc != NULL)
+ ret = udev->vendor_fnc( udev);
+ if ( ret < 0)
+ usb_udev_stall( ep0);
+ #endif /*USB_WITH_CB_FNC*/
+ } else if ( type == USB_CLASS_REQUEST) {
+ #ifdef USB_WITH_CB_FNC
+ int ret = -1;
+ if( udev->class_fnc != NULL)
+ ret = udev->class_fnc( udev);
+ if( ret < 0)
+ usb_udev_stall( ep0);
+ #endif /*USB_WITH_CB_FNC*/
+ } else
+ usb_udev_stall( ep0);
+ }
+ ret = 1;
+ }
+
+/* response to interrupt Ep0RxInt - receive data */
+ if ( udev->flags & USB_FLAG_EVENT_RX0) {
+ int i;
+ udev->flags &= ~USB_FLAG_EVENT_RX0;
+ usb_debug_print( DEBUG_LEVEL_MEDIUM, ( "Ep0Rx\n"));
+ if (( ep0->flags & USB_STATE_MASK) == USB_STATE_RECEIVE) {
+ usb_debug_print( DEBUG_LEVEL_HIGH, ( "RCV:p=%04lX,s=%d\n", (unsigned long)ep0->ptr, ep0->size));
+
+ i = usb_udev_read_endpoint(ep0, ep0->ptr, ep0->max_packet_size);
+ ep0->actual += i;
+ ep0->ptr +=i;
+
+ #ifdef USB_WITH_CB_FNC
+ if ( ep0->next_pkt_fnc ) {
+ if( ep0->next_pkt_fnc( ep0, i, USB_NEXT_PKT_REC) < 0) {
+ usb_udev_stall( ep0);
+ return -1;
+ }
+ }
+ #endif /*USB_WITH_CB_FNC*/
+
+ if (( i != ep0->max_packet_size) || ( ep0->actual >= ep0->size)) {
+ usb_complete_control_transfer( ep0, USB_COMPLETE_OK );
+ if ( ep0->efnc) {
+ ep0->efnc(ep0);
+ }
+ }
+ } else {
+ ep0->flags &= ~USB_STATE_MASK; //state = USB_STATE_IDLE;
+ }
+ }
+
+/* response to interrupt Ep0TxInt */
+ if ( udev->flags & USB_FLAG_EVENT_TX0) {
+ short i = ep0->size - ep0->actual;
+ udev->flags &= ~USB_FLAG_EVENT_TX0;
+//usb_debug_print( DEBUG_LEVEL_LOW, ("0S-%d(%d){%d}\n", ep0->state, ep0->size, ep0->max_packet_size));
+ usb_debug_print( DEBUG_LEVEL_MEDIUM, ( "EP0Tx:i=%d\n", i));
+
+ if (( ep0->flags & USB_STATE_MASK) == USB_STATE_TRANSMIT) {
+
+ if(i > ep0->max_packet_size) i = ep0->max_packet_size;
+
+ if ( i > 0 ) {
+ #ifdef USB_WITH_CB_FNC
+ if ( ep0->next_pkt_fnc) {
+ if( ep0->next_pkt_fnc( ep0, i, USB_NEXT_PKT_SEND) < 0) {
+ usb_udev_stall( ep0);
+ return -1;
+ }
+ }
+ #endif /*USB_WITH_CB_FNC*/
+ usb_debug_print( DEBUG_LEVEL_HIGH, ("Wr(%d)\n",i));
+ usb_udev_write_endpoint( ep0, ep0->ptr, i);
+ ep0->actual += i;
+ ep0->ptr +=i;
+
+ if( i != ep0->max_packet_size) {
+ /* last packed without full size has been sent, state can change to idle */
+ usb_complete_control_transfer( ep0, USB_COMPLETE_OK );
+ }
+ } else {
+ usb_udev_ack_setup( udev); // Send zero packet at the end ???
+ usb_complete_control_transfer( ep0, USB_COMPLETE_OK );
+ }
+ }
+ ret = 1;
+ }
+
+ return ret;
+ }
+
+
--- /dev/null
+/**************************************************************/
+/*** Module : USB module - header file ***/
+/*** Author : Roman Bartosinski (C) 28.04.2002 ***/
+/*** Modify : 08.08.2002 ***/
+/*** Rewrite: 05.09.2002 ***/
+/**************************************************************/
+
+#ifndef _USB_MODULE_
+ #define _USB_MODULE_
+
+ #include "usb_spec.h"
+ #include "usb_devdes.h"
+
+#if defined(SDCC) || defined(__KEIL__) || defined(__C51__)
+ /*8051 special handling*/
+ #define REENTRANT_SIGN __reentrant
+#else
+ #define __xdata /*nothing*/
+ #define REENTRANT_SIGN /*nothing*/
+#endif
+
+#define USB_WITH_CB_FNC
+//#define USB_WITH_UDEV_FNC
+
+#ifdef USB_WITH_UDEV_FNC
+ #define USB_UDEV_REENTRANT_SIGN REENTRANT_SIGN
+#else /*USB_WITH_UDEV_FNC*/
+ #define USB_UDEV_REENTRANT_SIGN /*nothing*/
+#endif /*USB_WITH_UDEV_FNC*/
+
+/* control endpoint */
+ #define MAX_CONTROL_XFER_DATA_SIZE 8
+
+ struct usb_ep_t;
+
+ typedef void endfnc_t( struct usb_ep_t *ep) REENTRANT_SIGN;
+
+ #define USB_NEXT_PKT_SEND 0
+ #define USB_NEXT_PKT_REC 1
+
+ #define USB_COMPLETE_OK 0
+ #define USB_COMPLETE_FAIL -1
+
+ typedef struct usb_ep_t {
+ struct usb_device_t *udev; /* pointer to parent device */
+ unsigned short max_packet_size; /* max. size of endpoint package, e.g. PDI_EP0_PACKET_SIZE */
+ unsigned char *ptr; /* pointer to current transmitted data */
+ unsigned int size; /* full size of current transmitted data */
+ unsigned int actual; /* transmitted data size */
+ endfnc_t *efnc; /* ??? */
+ unsigned char flags; /* endpoint flags & state - idle,receiving, transmitting ??? HERE ??? */
+ unsigned char epnum; /* endpoint number (index) - endpoint0 must be set to 0 */
+ unsigned short event_mask; /* event(interrupt) mask for this endpoint, e.g. PDI_INT_EP1_IN for pdiusbd1x */
+ #ifdef USB_WITH_CB_FNC
+ int (*next_pkt_fnc)(struct usb_ep_t *ep, int len, int codeval) REENTRANT_SIGN;
+ int (*complete_fnc)(struct usb_ep_t *ep, int status) REENTRANT_SIGN;
+ long user_data;
+ #endif /*USB_WITH_CB_FNC*/
+ } usb_ep_t;
+
+/* USB device */
+ typedef struct usb_device_t {
+ unsigned char id; /* device ID ??? */
+ unsigned char flags; /* usb device flags + endpoint0 events */
+ unsigned char ep_events; /* one bit for each endpoint (without ep0) event,(bit0 for udev->ep[0], bit1 for udev->ep[1], ...)*/
+ unsigned char configuration; /* current configuration */
+// unsigned char interface; /* current interface */
+// unsigned char altinterface; /* current alternative interface */
+
+ int (*vendor_fnc)( struct usb_device_t *udev) REENTRANT_SIGN; /* pointer to vendor request processing function */
+ int (*class_fnc)( struct usb_device_t *udev) REENTRANT_SIGN; /* pointer to class request processing function */
+ int (*standard_fnc)( struct usb_device_t *udev) REENTRANT_SIGN; /* pointer to standard request processing function */
+
+ //int (stdreq[13])( struct usb_device_t *udev) REENTRANT_SIGN; /* pointer to array of standard request processing functions - not used in actual implementation */
+
+ const USB_DEVICE_DESCRIPTORS_TABLE *devdes_table;
+
+ #ifdef USB_WITH_UDEV_FNC
+ int (*init)( struct usb_device_t *udev) REENTRANT_SIGN; /* function for hw specific part of initialize usb device */
+ int (*set_addr)( struct usb_device_t *udev, unsigned char addr) REENTRANT_SIGN; /* set device address */
+ int (*set_configuration)( struct usb_device_t *udev, unsigned char iCfg) REENTRANT_SIGN; /* set device configuration */
+ int (*connect)( struct usb_device_t *udev) REENTRANT_SIGN; /* function for hw specific part of connecting device to usb */
+ int (*disconnect)( struct usb_device_t *udev) REENTRANT_SIGN; /* function for hw specific part of disconnecting device to usb */
+ void (*ack_setup)( struct usb_device_t *udev) REENTRANT_SIGN; /* function for hw specific part of control response acknowledge */
+ void (*ack_control_setup)( struct usb_device_t *udev) REENTRANT_SIGN; /* function for hw specific part of control response acknowledge */
+ int (*check_events)( struct usb_device_t *udev) REENTRANT_SIGN; /* hw specific part of function for checking events */
+ void (*stall)( usb_ep_t *ep) REENTRANT_SIGN; /* hw specific function to stall endpoint */
+ void (*unstall)( usb_ep_t *ep) REENTRANT_SIGN; /* hw specific function to unstall endpoint */
+ int (*read_endpoint)( usb_ep_t *ep, void *ptr, int size) REENTRANT_SIGN;
+ int (*write_endpoint)( usb_ep_t *ep, const void *ptr, int size) REENTRANT_SIGN;
+ #endif /*USB_WITH_UDEV_FNC*/
+
+// USB_DEVICE_REQUEST *request; /* current usb request - only if there is a valid usb request in processing */
+ USB_DEVICE_REQUEST request; /* usb device request */
+
+ unsigned char cntep; /* number of device endpoints in ep array without EP0 */
+ usb_ep_t ep0; /* endpoint 0 */
+ usb_ep_t *ep; /* others endpoints in array */
+ } usb_device_t;
+
+
+/* endpoint flags */
+ /* endpoint state */
+ #define USB_STATE_IDLE 0x00
+ #define USB_STATE_TRANSMIT 0x01
+ #define USB_STATE_RECEIVE 0x02
+ #define USB_STATE_MASK 0x03
+
+/* usb_device flags */
+ #define USB_FLAG_CONFIGURED 0x01
+ #define USB_FLAG_BUS_RESET 0x02
+ #define USB_FLAG_SUSPEND 0x04
+ #define USB_FLAG_SETUP 0x08 // setup_packet
+ #define USB_FLAG_REMOTE_WAKE 0x10
+
+ #define USB_FLAG_EVENT_RX0 0x40
+ #define USB_FLAG_EVENT_TX0 0x80
+
+
+
+/* device functions - inline ??? */
+ int usb_init( usb_device_t *udev);
+ int usb_connect( usb_device_t *udev);
+ int usb_disconnect( usb_device_t *udev);
+ void usb_stall( usb_ep_t *ep);
+ void usb_unstall( usb_ep_t *ep);
+
+ #define usb_stall_ep0( udev) \
+ do { \
+ usb_stall( &(udev->ep0)); \
+ } while(0)
+
+/* check usb events(interrupts) */
+ int usb_check_events( usb_device_t *udev);
+/* response to standard constrol requests */
+ int usb_control_response( usb_device_t *udev);
+/* send control data */
+ void usb_send_control_data( usb_device_t *udev, unsigned char *pData, unsigned short len);
+ void usb_set_control_endfnc( usb_device_t *udev, endfnc_t *efnc);// REENTRANT_SIGN;
+ void usb_ack_setup( usb_ep_t *ep);
+
+
+/* Standard requests functions */
+// typedef int (*usb_stdreq_fnc_t)( usb_device_t *udev) REENTRANT_SIGN;
+// extern xdata usb_stdreq_fnc_t usb_standard_requests[13];
+
+int usb_standard_control_response(usb_device_t *udev) REENTRANT_SIGN;
+
+#ifdef USB_WITH_UDEV_FNC
+
+ #define usb_udev_is_fnc(_M_udev, _M_fnc) (_M_udev->_M_fnc)
+
+ #define usb_udev_init(_M_udev) (_M_udev->init(_M_udev))
+ #define usb_udev_set_addr(_M_udev, _M_addr) (_M_udev->set_addr(_M_udev, _M_addr))
+ #define usb_udev_set_configuration(_M_udev, _M_iCfg) (_M_udev->set_configuration(_M_udev, _M_iCfg))
+ #define usb_udev_connect(_M_udev) (_M_udev->connect(_M_udev))
+ #define usb_udev_disconnect(_M_udev) (_M_udev->disconnect(_M_udev))
+ #define usb_udev_ack_setup(_M_udev) (_M_udev->ack_setup(_M_udev))
+ #define usb_udev_ack_control_setup(_M_udev) (_M_udev->ack_control_setup(_M_udev))
+ #define usb_udev_check_events(_M_udev) (_M_udev->check_events(_M_udev))
+
+ #define usb_udev_stall(_M_ep) ((_M_ep)->udev->stall(_M_ep))
+ #define usb_udev_unstall(_M_ep) ((_M_ep)->udev->unstall(_M_ep))
+
+ #define usb_udev_read_endpoint(_M_ep, _M_ptr, _M_size) \
+ ((_M_ep)->udev->read_endpoint(_M_ep, _M_ptr, _M_size))
+
+ #define usb_udev_write_endpoint(_M_ep, _M_ptr, _M_size) \
+ ((_M_ep)->udev->write_endpoint(_M_ep, _M_ptr, _M_size))
+
+#else /*USB_WITH_UDEV_FNC*/
+
+ #define USB_PDI_DIRECT_FNC
+ #include "usb/pdi.h"
+
+#endif /*USB_WITH_UDEV_FNC*/
+
+#endif
--- /dev/null
+/*************************************************/
+/*** Module : USB device descriptor table ***/
+/*** Author : Roman Bartosinski, Pavel Pisa ***/
+/*** Modify : 10.11.2008 ***/
+/*************************************************/
+
+#ifndef _USB_DEVICE_DESCRIPTOR_TABLE
+ #define _USB_DEVICE_DESCRIPTOR_TABLE
+
+ #include "usb_spec.h"
+
+ struct _tag_usb_device_configuration_entry {
+ const USB_CONFIGURATION_DESCRIPTOR *pConfigDescription;
+ int iConfigTotalLength;
+ };
+ typedef struct _tag_usb_device_configuration_entry
+ USB_DEVICE_CONFIGURATION_ENTRY, *PUSB_DEVICE_CONFIGURATION_ENTRY;
+
+ struct _tag_usb_device_descriptors_table {
+ const USB_DEVICE_DESCRIPTOR *pDeviceDescription;
+ const USB_DEVICE_CONFIGURATION_ENTRY *pConfigurations;
+ const USB_INTERFACE_DESCRIPTOR **pInterfaceDescriptors;
+ const PUSB_STRING_DESCRIPTOR *pStrings;
+ int iNumStrings;
+ uint8_t bNumEndpoints;
+ uint8_t bNumConfigurations;
+ uint8_t bNumInterfaces;
+ };
+ typedef struct _tag_usb_device_descriptors_table
+ USB_DEVICE_DESCRIPTORS_TABLE, *PUSB_DEVICE_DESCRIPTOR_TABLE;
+
+
+#endif /*_USB_DEVICE_DESCRIPTOR_TABLE*/
+
--- /dev/null
+/*************************************************/
+/*** Module : USB specification ***/
+/*** Author : Roman Bartosinski 29.07.2002 ***/
+/*** Modify : 08.08.2002, 14.01.2003 ***/
+/*************************************************/
+
+#ifndef _USB_SPECIFICATIONS_AND_DEFINITIONS_MODULE
+ #define _USB_SPECIFICATIONS_AND_DEFINITIONS_MODULE
+
+/*#include <inttypes.h>*/
+#include <types.h>
+
+#ifndef PACKED
+ #ifdef __GNUC__
+ #define PACKED __attribute__((packed))
+ #else /*__GNUC__*/
+ #define PACKED /*nothing*/
+ #endif /*__GNUC__*/
+#endif
+
+/* this section is from __USB100.H__ and __CHAP9.H__ and define USB constants and structs */
+
+/* *** USB Device Request *** (spec. 9.3) */
+ typedef struct _tag_usb_device_request {
+ uint8_t bmRequestType;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+ } USB_DEVICE_REQUEST;
+
+/****************************************************************************************/
+/*** definitions for USB tranfer standard packets described in USB secif. - chapter 9 ***/
+/****************************************************************************************/
+ #define DEVICE_ADDRESS_MASK 0x7F
+
+/* bmRequestType D7 - Data transfer direction */
+ #define USB_DATA_DIR_MASK (uint8_t)0x80
+ #define USB_DATA_DIR_FROM_HOST (uint8_t)0x00
+ #define USB_DATA_DIR_TO_HOST (uint8_t)0x80
+/* bmRequestType D4..D0 - Recipient */
+ #define USB_RECIPIENT (uint8_t)0x1F
+ #define USB_RECIPIENT_DEVICE (uint8_t)0x00
+ #define USB_RECIPIENT_INTERFACE (uint8_t)0x01
+ #define USB_RECIPIENT_ENDPOINT (uint8_t)0x02
+ #define USB_RECIPIENT_OTHER (uint8_t)0x03
+/* bmRequestType D6..D5 - Type */
+ #define USB_REQUEST_TYPE_MASK (uint8_t)0x60
+ #define USB_STANDARD_REQUEST (uint8_t)0x00
+ #define USB_CLASS_REQUEST (uint8_t)0x20
+ #define USB_VENDOR_REQUEST (uint8_t)0x40
+/* Standard request codes (spec. 9.4) */
+ #define USB_REQUEST_MASK (uint8_t)0x0F
+ #define USB_REQUEST_GET_STATUS 0x00
+ #define USB_REQUEST_CLEAR_FEATURE 0x01
+ #define USB_REQUEST_SET_FEATURE 0x03
+ #define USB_REQUEST_SET_ADDRESS 0x05
+ #define USB_REQUEST_GET_DESCRIPTOR 0x06
+ #define USB_REQUEST_SET_DESCRIPTOR 0x07
+ #define USB_REQUEST_GET_CONFIGURATION 0x08
+ #define USB_REQUEST_SET_CONFIGURATION 0x09
+ #define USB_REQUEST_GET_INTERFACE 0x0A
+ #define USB_REQUEST_SET_INTERFACE 0x0B
+ #define USB_REQUEST_SYNC_FRAME 0x0C
+/* Descriptor types (spec. 9.4) */
+ #define USB_DESCRIPTOR_TYPE_DEVICE 0x01
+ #define USB_DESCRIPTOR_TYPE_CONFIGURATION 0x02
+ #define USB_DESCRIPTOR_TYPE_STRING 0x03
+ #define USB_DESCRIPTOR_TYPE_INTERFACE 0x04
+ #define USB_DESCRIPTOR_TYPE_ENDPOINT 0x05
+ #define USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER 0x06
+ #define USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION 0x07
+ #define USB_DESCRIPTOR_TYPE_POWER 0x08
+
+/* values for the bits returned by the USB GET_STATUS command (spec. 9.4.5) */
+ #define USB_GETSTATUS_SELF_POWERED 0x01
+ #define USB_GETSTATUS_REMOTE_WAKEUP_ENABLED 0x02
+
+/* values for standard request Clear Feature */
+ #define USB_FEATURE_ENDPOINT_STALL 0x0000
+ #define USB_FEATURE_REMOTE_WAKEUP 0x0001
+
+
+/*******************************************************/
+/*** Standard USB Descriptor Definitions (spec. 9.6) ***/
+/*******************************************************/
+
+/* *** DEVICE *** (spec. 9.6.1) */
+ struct _tag_usb_device_descriptor {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdUSB;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t bcdDevice;
+ uint8_t iManufacturer;
+ uint8_t iProduct;
+ uint8_t iSerialNumber;
+ uint8_t bNumConfigurations;
+ } PACKED;
+ typedef struct _tag_usb_device_descriptor
+ USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
+
+/* *** DEVICE_QUALIFIER *** (spec. 9.6.2) */
+ struct _tag_usb_device_qualifier_descriptor {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdUSB;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
+ uint8_t bNumConfigurations;
+ uint8_t bReserved;
+ } PACKED;
+ typedef struct _tag_usb_device_qualifier_descriptor
+ USB_DEVICE_QUALIFIER_DESCRIPTOR, *PUSB_DEVICE_QUALIFIER_DESCRIPTOR;
+
+/* *** CONFIGURATION *** (spec. 9.6.3) */
+ struct _tag_usb_configuration_descriptor {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t wTotalLength;
+ uint8_t bNumInterfaces;
+ uint8_t bConfigurationValue;
+ uint8_t iConfiguration;
+ uint8_t bmAttributes;
+ uint8_t MaxPower;
+ } PACKED;
+ typedef struct _tag_usb_configuration_descriptor
+ USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;
+/* definitions for bits in the bmAttributes field of a configuration descriptor. (spec. 9.6.3) */
+ #define USB_CONFIG_POWERED_MASK 0xc0
+ #define USB_CONFIG_BUS_POWERED 0x80
+ #define USB_CONFIG_SELF_POWERED 0x40
+ #define USB_CONFIG_REMOTE_WAKEUP 0x20
+ #define BUS_POWERED 0x80
+ #define SELF_POWERED 0x40
+ #define REMOTE_WAKEUP 0x20
+
+/* *** OTHER_SPEED_CONFIGURATION *** (spec. 9.6.4) */
+ struct _tag_usb_other_speed_configuration {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t wTotalLength;
+ uint8_t bNumInterfaces;
+ uint8_t bConfigurationValue;
+ uint8_t iConfiguration;
+ uint8_t bmAttributes;
+ uint8_t bMaxPower;
+ } PACKED;
+ typedef struct _tag_usb_other_speed_configuration
+ USB_OTHER_SPEED_CONFIGURATION_DESCRIPTOR, *PUSB_OTHER_SPEED_CONFIGURATION_DESCRIPTOR;
+
+/* *** INTERFACE *** (spec. 9.6.5) */
+ struct _tag_usb_interface_descriptor {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bInterfaceNumber;
+ uint8_t bAlternateSetting;
+ uint8_t bNumEndpoints;
+ uint8_t bInterfaceClass;
+ uint8_t bInterfaceSubClass;
+ uint8_t bInterfaceProtocol;
+ uint8_t iInterface;
+ } PACKED;
+ typedef struct _tag_usb_interface_descriptor
+ USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR;
+
+/* *** ENDPOINT *** (spec. 9.6.6) */
+ struct _tag_usb_endpoint_descriptor {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bEndpointAddress;
+ uint8_t bmAttributes;
+ uint16_t wMaxPacketSize;
+ uint8_t bInterval;
+ } PACKED;
+ typedef struct _tag_usb_endpoint_descriptor
+ USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR;
+
+/* Endpoint direction bit, stored in address (spec. 9.6.6) */
+ #define USB_ENDPOINT_DIRECTION_MASK 0x80
+/* test direction bit in the bEndpointAddress field of an endpoint descriptor. */
+ #define USB_ENDPOINT_DIRECTION_OUT(addr) (!((addr) & USB_ENDPOINT_DIRECTION_MASK))
+ #define USB_ENDPOINT_DIRECTION_IN(addr) ((addr) & USB_ENDPOINT_DIRECTION_MASK)
+/* Values for bmAttributes field of an endpoint descriptor (spec. 9.6.6) */
+ #define USB_ENDPOINT_TYPE_MASK 0x03
+ #define USB_ENDPOINT_TYPE_CONTROL 0x00
+ #define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
+ #define USB_ENDPOINT_TYPE_BULK 0x02
+ #define USB_ENDPOINT_TYPE_INTERRUPT 0x03
+
+/* *** STRING *** (spec. 9.6.7) */
+ struct _tag_usb_string_descriptor {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bString[];
+ } PACKED;
+ typedef struct _tag_usb_string_descriptor
+ USB_STRING_DESCRIPTOR, *PUSB_STRING_DESCRIPTOR;
+
+
+/*******************************************/
+/*** USB_IF - Defined USB device classes ***/
+/*******************************************/
+ #define USB_DEVICE_CLASS_RESERVED 0x00
+ #define USB_DEVICE_CLASS_AUDIO 0x01
+ #define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
+ #define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
+ #define USB_DEVICE_CLASS_MONITOR 0x04
+ #define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05
+ #define USB_DEVICE_CLASS_POWER 0x06
+ #define USB_DEVICE_CLASS_PRINTER 0x07
+ #define USB_DEVICE_CLASS_STORAGE 0x08
+ #define USB_DEVICE_CLASS_HUB 0x09
+ #define USB_DEVICE_CLASS_APPLICATION_SPECIFIC 0xFE
+ #define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF
+
+ /* define application specific device class subclasses */
+ #define USB_APPL_SUBCLASS_FIRMWARE_UPDATE 0x01
+ #define USB_APPL_SUBCLASS_IRDA_USB_BRIDGE 0x02
+
+#endif
--- /dev/null
+#ifndef _USB_STDREQ_MODULE_
+ #define _USB_STDREQ_MODULE_
+
+ int usb_stdreq_get_status( usb_device_t *udev);
+
+ int usb_stdreq_clear_feature( usb_device_t *udev);
+
+ int usb_stdreq_set_feature( usb_device_t *udev);
+
+ int usb_stdreq_set_address( usb_device_t *udev);
+
+ int usb_stdreq_get_configuration( usb_device_t *udev);
+
+ int usb_stdreq_set_configuration( usb_device_t *udev);
+
+ int usb_stdreq_get_interface( usb_device_t *udev);
+
+ int usb_stdreq_set_interface( usb_device_t *udev);
+
+ int usb_stdreq_get_descriptor( usb_device_t *udev);
+
+#endif /*_USB_STDREQ_MODULE_*/
+
--- /dev/null
+/* Global debug macros, variables, functions - header file */
+/* R.B. - 23.4.2003 */
+
+#ifndef _USB_DEBUG_H_
+#define _USB_DEBUG_H_
+
+#if 1
+ #include <stdio.h>
+ #define usb_printf printf
+#else
+ int simple_printf(const char *f, ...);
+ #define usb_printf simple_printf
+#endif
+
+/* Debug levels */
+#define DEBUG_LEVEL_NONE 0
+#define DEBUG_LEVEL_LOW 1
+#define DEBUG_LEVEL_MEDIUM 2
+#define DEBUG_LEVEL_HIGH 3
+#define DEBUG_LEVEL_VERBOSE 4
+
+#ifndef DEBUG_STATIC_LEVEL
+/* Global static debug level */
+#define DEBUG_STATIC_LEVEL DEBUG_LEVEL_NONE
+#endif
+
+/* If it is defined, current global debug level is
+ in 'global_debug_level' variable. Otherwise will
+ be used 'DEBUG_STATIC_LEVEL' as current global
+ debug level
+*/
+/*#define DEBUG_USE_DYNAMIC_LEVEL*/
+
+/* #define DEBUG */
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
+
+#ifdef DEBUG
+
+/* use static or dynamic global debug level */
+#if defined(DEBUG_USE_DYNAMIC_LEVEL) /* use dynamic debug level */
+ extern unsigned char usb_debug_level;
+#else /* use only static debug level */
+ #define usb_debug_level DEBUG_STATIC_LEVEL
+#endif
+
+
+/* usb_debug_print( level, printargs) print debug info in printargs if
+ level is lower or equal to 'global_debug_level'/'DEBUG_STATIC_LEVEL'.
+ 'printargs' is with parenthesis.
+ usage : usb_debug_print( DEBUG_LEVEL_MEDIUM,("i=%d",i));
+*/
+#define usb_debug_print( _lvl_, _prnargs_) \
+ do { \
+ if ( usb_debug_level >= _lvl_) { \
+ usb_printf _prnargs_; \
+ } \
+ } while(0)
+
+/* usb_debug_info( printargs) print debug info always
+ usage : usb_debug_info( "debug info");
+*/
+#define usb_debug_info usb_printf /* FIXME: this is not correct */
+
+#else /* DEBUG */
+ #define usb_debug_print( _lvl_, _prnargs_)
+ #define usb_debug_info(...)
+#endif /* DEBUG */
+
+
+ void usb_debug_set_level(int level);
+
+ char *usb_debug_get_req_recipient( char rqt);
+ char *usb_debug_get_req_type( char rqt);
+ char *usb_debug_get_std_request( char req);
+ char *usb_debug_get_std_descriptor( unsigned char desc);
+
+
+#endif /* _GLOBAL_DEBUG_H_ */
--- /dev/null
+/* Global debug macros, variables, functions - header file */
+/* R.B. - 23.4.2003 */
+
+#include <usb/usbdebug.h>
+#include <usb/usb_spec.h>
+
+#ifdef DEBUG
+
+/* debug can be enabled in run-time */
+#if defined(DEBUG_USE_DYNAMIC_LEVEL) /* use dynamic debug level */
+ unsigned char usb_debug_level = DEBUG_LEVEL_NONE;
+#endif
+
+/*************************************************************
+ *** Debug infos
+ *************************************************************/
+
+ void usb_debug_set_level(int level) {
+ #if defined(DEBUG_USE_DYNAMIC_LEVEL) /* use dynamic debug level */
+ usb_debug_level = level;
+ #endif
+ }
+
+
+ char *usb_debug_get_req_recipient( char rqt) {
+ switch ( rqt & USB_RECIPIENT) {
+ case USB_RECIPIENT_DEVICE: return "DEVICE";
+ case USB_RECIPIENT_INTERFACE: return "INTERFACE";
+ case USB_RECIPIENT_ENDPOINT: return "ENDPOINT";
+ }
+ return "OTHER";
+ }
+ char *usb_debug_get_req_type( char rqt) {
+ switch ( rqt & USB_REQUEST_TYPE_MASK) {
+ case USB_STANDARD_REQUEST: return "STANDARD";
+ case USB_CLASS_REQUEST: return "CLASS";
+ case USB_VENDOR_REQUEST: return "VENDOR";
+ }
+ return "RESERVED";
+ }
+ char *usb_debug_get_std_request( char req) {
+ switch ( req & USB_REQUEST_MASK) {
+ case USB_REQUEST_GET_STATUS: return "GET STATUS";
+ case USB_REQUEST_CLEAR_FEATURE: return "CLEAR FEATURE";
+ case USB_REQUEST_SET_FEATURE: return "SET FEATURE";
+ case USB_REQUEST_SET_ADDRESS: return "SET ADDRESS";
+
+ case USB_REQUEST_GET_DESCRIPTOR: return "GET DESCRIPTOR";
+ case USB_REQUEST_SET_DESCRIPTOR: return "SET DESCRIPTOR";
+ case USB_REQUEST_GET_CONFIGURATION: return "GET CONFIGURATION";
+ case USB_REQUEST_SET_CONFIGURATION: return "SET CONFIGURATION";
+ case USB_REQUEST_GET_INTERFACE: return "GET INTERFACE";
+ case USB_REQUEST_SET_INTERFACE: return "SET INTERFACE";
+ case USB_REQUEST_SYNC_FRAME: return "SYNC FRAME";
+ }
+ return "UNKNOWN";
+ }
+ char *usb_debug_get_std_descriptor( unsigned char desc) {
+
+ switch ( desc) {
+ case USB_DESCRIPTOR_TYPE_DEVICE: return "DEVICE";
+ case USB_DESCRIPTOR_TYPE_CONFIGURATION: return "CONFIGURATION";
+ case USB_DESCRIPTOR_TYPE_STRING: return "STRING";
+ case USB_DESCRIPTOR_TYPE_INTERFACE: return "INTERFACE";
+ case USB_DESCRIPTOR_TYPE_ENDPOINT: return "ENDPOINT";
+ case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER: return "DEVICE_QUALIFIER";
+ case USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION: return "OTHER_SPEED_CONFIG";
+ case USB_DESCRIPTOR_TYPE_POWER: return "POWER";
+ }
+ return "UNKNOWN";
+ }
+
+#else /*DEBUG*/
+ void usb_debug_set_level(int level) {
+ }
+#endif /* DEBUG */
--- /dev/null
+/**************************************************************/
+/*** Module : USB module - header file ***/
+/*** Author : Roman Bartosinski (C) 28.04.2002 ***/
+/*** Modify : 08.08.2002 ***/
+/*** Rewrite: 05.10.2009 ***/
+/**************************************************************/
+
+#include <system_def.h>
+
+#include <usb/usb.h>
+#include <usb/usbdebug.h>
+
+#include <usb/usb_srq.h> /* standard control request responses */
+
+/*************************************************************
+ *** Common standard control endpoint0 responses
+ *************************************************************/
+ int usb_standard_control_response(usb_device_t *udev) REENTRANT_SIGN
+ {
+ unsigned char req;
+ int ret = -1;
+ USB_DEVICE_REQUEST *preq = &(udev->request);
+
+ req = preq->bRequest & USB_REQUEST_MASK;
+ usb_debug_print( DEBUG_LEVEL_HIGH, ( "StdReq-%d\n", req));
+/*
+ if ( (udev->stdreq[ req]) != NULL) {
+ ret = udev->stdreq[ req]( udev);
+ }
+ if( ret < 0)
+ udev->ack_setup( udev);
+*/
+ switch( req) {
+ case USB_REQUEST_GET_STATUS: ret=usb_stdreq_get_status( udev); break;
+ case USB_REQUEST_CLEAR_FEATURE: ret=usb_stdreq_clear_feature( udev); break;
+ case USB_REQUEST_SET_FEATURE: ret=usb_stdreq_set_feature( udev); break;
+ case USB_REQUEST_SET_ADDRESS: ret=usb_stdreq_set_address( udev); break;
+ case USB_REQUEST_GET_DESCRIPTOR: ret=usb_stdreq_get_descriptor( udev); break;
+// case USB_REQUEST_SET_DESCRIPTOR: break;
+ case USB_REQUEST_GET_CONFIGURATION: ret=usb_stdreq_get_configuration( udev); break;
+ case USB_REQUEST_SET_CONFIGURATION: ret=usb_stdreq_set_configuration( udev); break;
+ case USB_REQUEST_GET_INTERFACE: ret=usb_stdreq_get_interface( udev); break;
+ case USB_REQUEST_SET_INTERFACE: ret=usb_stdreq_set_interface( udev); break;
+// case USB_REQUEST_SYNC_FRAME: break;
+// default: ret=-1; break;
+ }
+ return ret;
+ }
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+default_CONFIG = CONFIG_USB_LPCUSB=x
+
+ifeq ($(CONFIG_USB_LPCUSB),y)
+lib_LIBRARIES = lpcusb
+
+nobase_include_HEADERS = usb/lpcusb.h usb/lpc.h
+
+lpcusb_SOURCES = lpcusb.c lpc.c
+endif #CONFIG_USB_LPCUSB
--- /dev/null
+/*****************************************************/
+/*** Module : USB PDI ***/
+/*** Author : Roman Bartosinski (C) 28.04.2002 ***/
+/*** Modify : 08.08.2002, 16.04.2003 ***/
+/*****************************************************/
+
+#include <system_def.h>
+#include <usb/usb.h>
+#include <usb/lpcusb.h>
+
+#ifdef MACH_LPC17XX
+#include <lpcUSB.h>
+#endif
+
+/* set device address */
+int usb_lpc_set_addr( usb_device_t *udev, unsigned char addr) {
+ lpc_usb_set_addr(addr);
+ return 0;
+}
+
+int usb_lpc_set_configuration( usb_device_t *udev, unsigned char iCfg) {
+ lpc_usb_config_device(iCfg);
+ if ( iCfg) {
+ int i;
+ for(i = 0; i < udev->cntep; i++) {
+ lpc_usb_configEP(udev->ep[i].epnum, udev->ep[i].max_packet_size);
+ }
+ }
+ return 0;
+}
+
+/* connect usb */
+int usb_lpc_connect( usb_device_t *udev) {
+ lpc_write_cmd_data(USB_CMD_SET_DEV_STAT,USB_DAT_WR_BYTE(USBC_DEV_CON));
+ return 0;
+}
+
+/* disconnect usb */
+int usb_lpc_disconnect( usb_device_t *udev) {
+ lpc_write_cmd_data(USB_CMD_SET_DEV_STAT,USB_DAT_WR_BYTE(0));
+ return 0;
+}
+
+/* acknowledge control transfer */
+void usb_lpc_ack_setup( usb_device_t *udev) {
+ lpc_usb_write_endpoint(0x80|0x00, NULL, 0);
+}
+
+/* stall endpoint X */
+void usb_lpc_stall( usb_ep_t *ep) {
+ if (!ep->epnum)
+ lpc_usb_setstallEP(0x80|ep->epnum);
+ lpc_usb_setstallEP(ep->epnum);
+}
+
+/* unstall endpoint X */
+void usb_lpc_unstall( usb_ep_t *ep) {
+ if (!ep->epnum)
+ lpc_usb_clrstallEP(0x80|ep->epnum);
+ lpc_usb_clrstallEP(ep->epnum);
+}
+
+/**
+ * usb_lpc_check events
+ * function reads interrupt register and sets event flags
+ * function returns 1 if there is some new event.
+ * function returns 0 if there isn't new event but all is OK
+ * function returns -1 if there is any error
+*/
+int usb_lpc_check_events( usb_device_t *udev)
+{
+ unsigned int disr,val,last_int;
+ int ret=0,n,m,i;
+
+ disr=USBDevIntSt;
+
+ /* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */
+ if (disr & USBDevInt_DEV_STAT) {
+ USBDevIntClr = USBDevInt_DEV_STAT;
+ disr&=~USBDevInt_DEV_STAT;
+ lpc_write_cmd(USB_CMD_GET_DEV_STAT);
+ val=lpc_read_cmd_data(USB_DAT_GET_DEV_STAT);
+ if (val & USBC_DEV_RST) { /* Reset */
+ lpc_usb_reset();
+ udev->flags |= USB_FLAG_BUS_RESET;
+ ret = 1;
+ }
+ if (val & USBC_DEV_SUS_CH) { /* Suspend/Resume */
+ if (val & USBC_DEV_SUS) { /* Suspend */
+ udev->flags |= USB_FLAG_SUSPEND;
+ ret = 1;
+ } else { /* Resume */
+ /* todo */
+ }
+ }
+ }
+
+ /* Endpoint's Slow Interrupt */
+ if (disr & USBDevInt_EP_SLOW) {
+ USBDevIntClr = USBDevInt_EP_SLOW;
+ disr&=~USBDevInt_EP_SLOW;
+
+ last_int = USBEpIntSt;
+
+ /* EP0_OUT */
+ if (last_int & (1 << 0)) {
+ last_int &= ~(1 << 0);
+ USBEpIntClr = 1 << 0;
+ lpc_wait4devint(USBDevInt_CDFULL);
+ val = USBCmdData;
+ /* Setup Packet */
+ if (val & USBC_EP_SEL_STP)
+ udev->flags |= USB_FLAG_SETUP;
+ else
+ udev->flags |= USB_FLAG_EVENT_RX0;
+ ret = 1;
+ }
+
+ /* EP0_IN */
+ if (last_int & (1 << 1)) {
+ last_int &= ~(1 << 1);
+ USBEpIntClr = 1 << 1;
+ lpc_wait4devint(USBDevInt_CDFULL);
+ val = USBCmdData;
+ udev->flags |= USB_FLAG_EVENT_TX0;
+ ret = 1;
+ }
+
+ /* user endpoints */
+ for( i=0; i<udev->cntep; i++) {
+ if ( last_int & (udev->ep+i)->event_mask) {
+ last_int &= ~((udev->ep+i)->event_mask);
+ USBEpIntClr = (udev->ep+i)->event_mask;
+ lpc_wait4devint(USBDevInt_CDFULL);
+ val = USBCmdData;
+ udev->ep_events |= 1<<i;
+ ret = 1;
+ }
+ }
+
+ while (last_int) { /* Endpoint Interrupt Status */
+ for (n = 0; n < USB_EP_NUM; n++) { /* Check All Endpoints */
+ if (last_int & (1 << n)) {
+ last_int &= ~(1 << n);
+ USBEpIntClr = 1 << n;
+ m = n >> 1;
+ if (n&1) m|=0x80;
+ lpc_wait4devint(USBDevInt_CDFULL);
+ val = USBCmdData;
+ lpc_usb_setstallEP(m);
+ }
+ }
+ }
+ }
+ if (!disr)
+ USBDevIntClr = disr;
+ return ret;
+}
+
+int usb_lpc_read_endpoint( usb_ep_t *ep, void *ptr, int size)
+{
+ return lpc_usb_read_endpoint(ep->epnum, ptr, size);
+}
+
+int usb_lpc_write_endpoint( usb_ep_t *ep, const void *ptr, int size)
+{
+ return lpc_usb_write_endpoint(0x80|ep->epnum, ptr, size);
+}
+
+
+/* init usb structures and chip */
+int usb_lpc_init( usb_device_t *udev) {
+
+ udev->connect = usb_lpc_connect;
+ udev->set_addr = usb_lpc_set_addr;
+ udev->set_configuration = usb_lpc_set_configuration;
+ udev->disconnect = usb_lpc_disconnect;
+ udev->ack_setup = usb_lpc_ack_setup;
+ udev->ack_control_setup = NULL;
+ udev->stall = usb_lpc_stall;
+ udev->unstall = usb_lpc_unstall;
+ udev->check_events = usb_lpc_check_events;
+ udev->read_endpoint = usb_lpc_read_endpoint;
+ udev->write_endpoint = usb_lpc_write_endpoint;
+
+ udev->ep0.max_packet_size = USB_MAX_PACKET0;
+
+ lpc_usb_hw_init();
+ return 0;
+}
--- /dev/null
+/*****************************************************/
+/*** Module : USB PDI ***/
+/*** Author : Roman Bartosinski (C) 28.04.2002 ***/
+/*** Modify : 08.08.2002, 16.04.2003 ***/
+/*****************************************************/
+
+#include <system_def.h>
+#include <usb/usb.h>
+#include <usb/lpcusb.h>
+
+#ifdef MACH_LPC17XX
+ #include <LPC17xx.h>
+ #include <lpcUSB.h>
+ #ifndef PINSEL1
+ #define PINSEL1 (PINCON->PINSEL1)
+ #define PINSEL3 (PINCON->PINSEL3)
+ #define PINSEL4 (PINCON->PINSEL4)
+ #endif
+ #ifndef PCONP
+ #define PCONP (SC->PCONP)
+ #endif
+#endif
+
+#ifndef USB_VBUS_PIN_USED
+#define USB_VBUS_PIN_USED 1
+#endif
+
+unsigned int lpc_ep2addr(unsigned int ep_num)
+{
+ unsigned int val;
+ val = (ep_num & 0x0F) << 1;
+ if (ep_num & 0x80)
+ val += 1;
+ return val;
+}
+
+void lpc_wait4devint(unsigned int intrs)
+{
+ while ((USBDevIntSt & intrs) != intrs);
+ USBDevIntClr = intrs;
+}
+
+
+void lpc_write_cmd(unsigned int cmd)
+{
+ USBDevIntClr = USBDevInt_CCEMTY | USBDevInt_CDFULL;
+ USBCmdCode = cmd;
+ lpc_wait4devint(USBDevInt_CCEMTY);
+}
+
+void lpc_write_cmd_data (unsigned int cmd, unsigned int val)
+{
+ lpc_write_cmd(cmd);
+ USBCmdCode = val;
+ lpc_wait4devint(USBDevInt_CCEMTY);
+}
+
+unsigned int lpc_read_cmd_data (unsigned int cmd)
+{
+ lpc_write_cmd(cmd);
+ lpc_wait4devint(USBDevInt_CDFULL);
+ return USBCmdData;
+}
+
+void lpc_usb_realizeEP(unsigned int idx,unsigned int wmaxpsize)
+{
+ USBReEp |= (1 << idx);
+ USBEpInd = idx;
+ USBMaxPSize = wmaxpsize;
+ lpc_wait4devint(USBDevInt_EP_RLZED);
+}
+
+void lpc_usb_configEP(unsigned int ep_num,unsigned int wmaxpsize)
+{
+ lpc_usb_realizeEP(lpc_ep2addr(ep_num),wmaxpsize);
+ lpc_usb_enableEP(ep_num);
+}
+
+void lpc_usb_setstallEP(unsigned int ep_num)
+{
+ lpc_write_cmd_data(USB_CMD_SET_EP_STAT(lpc_ep2addr(ep_num)),USB_DAT_WR_BYTE(USBC_EP_STAT_ST));
+}
+
+void lpc_usb_clrstallEP(unsigned int ep_num)
+{
+ lpc_write_cmd_data(USB_CMD_SET_EP_STAT(lpc_ep2addr(ep_num)),USB_DAT_WR_BYTE(0));
+}
+
+void lpc_usb_enableEP(unsigned int ep_num)
+{
+ lpc_write_cmd_data(USB_CMD_SET_EP_STAT(lpc_ep2addr(ep_num)),USB_DAT_WR_BYTE(0));
+}
+
+void lpc_usb_disableEP(unsigned int ep_num)
+{
+ lpc_write_cmd_data(USB_CMD_SET_EP_STAT(lpc_ep2addr(ep_num)),USB_DAT_WR_BYTE(USBC_EP_STAT_DA));
+}
+
+void lpc_usb_set_addr(unsigned int adr)
+{
+ lpc_write_cmd_data(USB_CMD_SET_ADDR,USB_DAT_WR_BYTE(USBC_DEV_EN | adr)); /* Setup Status Phase */
+}
+
+void lpc_usb_config_device(int fConfigured)
+{
+ lpc_write_cmd_data(USB_CMD_CFG_DEV,USB_DAT_WR_BYTE(fConfigured ? USBC_CONF_DEVICE : 0)); /* Setup Status Phase */
+}
+
+void lpc_usb_reset(void)
+{
+ USBEpIntClr = 0xFFFFFFFF;
+ USBEpIntEn = 0xFFFFFFFF ^ USB_DMA_EP;
+ USBDevIntClr = 0xFFFFFFFF;
+ USBDevIntEn = USBDevInt_DEV_STAT | USBDevInt_EP_SLOW;
+
+ lpc_usb_configEP(0x00, USB_MAX_PACKET0);
+ lpc_usb_configEP(0x80, USB_MAX_PACKET0);
+}
+
+void lpc_usb_hw_init (void)
+{
+
+#if defined(INC_LPC214x_H) || defined(MACH_LPC21XX)
+ PINSEL1 &= ~0xC000C000;
+// PINSEL1 |= 0x40004000; /* Select USB Link, VBUS */
+ PINSEL1 |= 0x80000000; /* Select USB Link, VBUS */
+
+ PCONP |= 0x80000000; /* Turn On USB PCLK */
+
+ /* Configure 48MHz USB Clock; FOsc = 12MHz, M = 4, P = 2 */
+ PLLCFG48 = 0x23; /* M = 4, P = 2 */
+ PLLCON48 = PLLCON_PLLE; /* PLL Enable */
+ PLLFEED48 = 0xAA; /* Feed Sequence 1 */
+ PLLFEED48 = 0x55; /* Feed Sequence 2 */
+
+ while ((PLLSTAT48 & PLLSTAT_LOCK) == 0); /* Wait for PLL Lock */
+
+ PLLCON48 = PLLCON_PLLE | PLLCON_PLLC; /* PLL Enable & Connect */
+ PLLFEED48 = 0xAA; /* Feed Sequence 1 */
+ PLLFEED48 = 0x55; /* Feed Sequence 2 */
+
+ USBDevIntEn = USBDevInt_DEV_STAT; /* Enable Device Status Interrupt */
+#endif /* MACH_LPC21XX */
+
+#if defined(MACH_LPC23XX) || defined(MACH_LPC17XX)
+ /**
+ ** ** ATTENTION **
+ ** USB clock (48MHz) should be set up externally before calling this fn
+ ** by setting USBCLKCFG (eg. USBCLKCFG = 5 for f_cco=288MHz).
+ ** If some of the pins shared with USB device are to be used for
+ ** different purpose, following PINSELs must be changed after retutn
+ ** from this fn.
+ **/
+
+ /* set up USB pins */
+ PINSEL1 = (PINSEL1 & ~(0x3<<26)) | (0x1<<26); /* USB_D+,- @ P0.29,30 */
+ PINSEL4 = (PINSEL4 & ~(0x3<<18)) | (0x1<<18); /* USB_CONNECT @ P2.9 */
+#if USB_VBUS_PIN_USED
+ PINSEL3 = (PINSEL3 & ~(0x3<<28)) | (0x2<<28); /* Vbus @ P1.30 */
+#endif
+ /* switch USB power on */
+ PCONP |= 1<<31;
+ /* switch USB internal clock switch on */
+ USBClkCtrl = 0x12;
+ while ((USBClkSt & 0x12) != 0x12);
+
+#endif /* MACH_LPC23XX */
+
+ /* Partial Manual Reset since Automatic Bus Reset is not working */
+ lpc_usb_reset();
+ lpc_usb_set_addr(0);
+}
+
+/*
+ * lpc_usb_read_endpoint: Read USB Endpoint Data
+ * @EPNum: Endpoint Number - EPNum.0..3: Address, EPNum.7: Dir
+ * @ptr: Pointer to Data Buffer
+ * @size:
+ * Return Value: Number of bytes read
+ */
+int lpc_usb_read_endpoint( unsigned int ep_num, void *ptr, int size)
+{
+ unsigned int cnt,i,dwData;
+ unsigned char *p=ptr;
+
+ USBCtrl = ((ep_num & 0x0F) << 2) | USBCtrl_RD_EN;
+ do {
+ cnt = USBRxPLen;
+ } while ((cnt & USBRxPLen_PKT_RDY) == 0);
+ cnt &= USBRxPLen_PKT_LNGTH;
+
+ // get data
+ while (USBCtrl & USBCtrl_RD_EN) {
+ dwData = USBRxData;
+ if (p != NULL) {
+ for (i = 0; (i < 4) && size; i++) {
+ size--;
+ *p = dwData & 0xFF;
+ p++;
+ dwData >>= 8;
+ }
+ }
+ }
+
+ lpc_write_cmd(USB_CMD_SEL_EP(lpc_ep2addr(ep_num)));
+ lpc_write_cmd(USB_CMD_CLR_BUF);
+
+ return cnt;
+}
+
+/*
+ * lpc_usb_write_endpoint: Write USB Endpoint Data
+ * @ep_num: Endpoint Number - ep_num.0..3: Address, ep_num.7: Dir
+ * @ptr: Pointer to Data Buffer
+ * @size: Number of bytes to write
+ * Return Value: Number of bytes written
+ */
+int lpc_usb_write_endpoint( unsigned int ep_num, const void *ptr, int size)
+{
+ unsigned int n;
+ const unsigned char *p=ptr;
+
+ USBCtrl = ((ep_num & 0x0F) << 2) | USBCtrl_WR_EN;
+ USBTxPLen = size;
+
+ for (n = 0; n < (size + 3) / 4; n++) {
+ USBTxData = (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
+ p += 4;
+ }
+
+ USBCtrl=0;
+
+ lpc_write_cmd(USB_CMD_SEL_EP(lpc_ep2addr(ep_num)));
+ lpc_write_cmd(USB_CMD_VALID_BUF);
+
+ return size;
+}
--- /dev/null
+#ifndef _USB_LPC_SUBMODULE_HEADER_FILE_
+#define _USB_LPC_SUBMODULE_HEADER_FILE_
+
+#include <usb/usb.h>
+
+int usb_lpc_init( usb_device_t *udev);
+
+#endif /* _USB_LPC_SUBMODULE_HEADER_FILE_ */
+
--- /dev/null
+#ifndef _LPCUSB_BASE_MODULE
+#define _PLCUSB_BASE_MODULE
+
+/*********************************************************/
+// Function prototypes
+//
+// LPCUSB common commands
+
+unsigned int lpc_ep2addr(unsigned int ep_num);
+void lpc_wait4devint(unsigned int intrs);
+void lpc_write_cmd(unsigned int cmd);
+void lpc_write_cmd_data (unsigned int cmd, unsigned int val);
+unsigned int lpc_read_cmd_data (unsigned int cmd);
+void lpc_usb_realizeEP(unsigned int idx,unsigned int wmaxpsize);
+void lpc_usb_configEP(unsigned int ep_num,unsigned int wmaxpsize);
+void lpc_usb_setstallEP (unsigned int ep_num);
+void lpc_usb_clrstallEP (unsigned int ep_num);
+void lpc_usb_enableEP(unsigned int ep_num);
+void lpc_usb_disableEP(unsigned int ep_num);
+void lpc_usb_config_device(int fConfigured);
+void lpc_usb_reset(void);
+void lpc_usb_set_addr(unsigned int adr);
+void lpc_usb_hw_init (void);
+int lpc_usb_read_endpoint( unsigned int ep_num, void *ptr, int size);
+int lpc_usb_write_endpoint( unsigned int ep_num, const void *ptr, int size);
+
+#endif // from _LPC_BASE_MODULE
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+default_CONFIG = CONFIG_USB_MORE=x
+
+ifeq ($(CONFIG_USB_MORE),y)
+lib_LIBRARIES = usbmore
+
+nobase_include_HEADERS = usb/usb_loader.h
+
+#shared_LIBRARIES =
+
+#include_HEADERS =
+
+usbmore_SOURCES = usb_srq.c
+
+#lib_LOADLIBES =
+#bin_PROGRAMS =
+
+endif #CONFIG_USB_MORE
+
--- /dev/null
+#ifndef _MSC_LOADER_H
+#define _MSC_LOADER_H
+
+#include <usb/usb_loader.h>
+
+int usb_msc1210_loader(usb_device_t *udev);
+
+#endif /*_MSC_LOADER_H*/
--- /dev/null
+
+#ifndef _USB_COM_H
+ #define _USB_COM_H
+
+/* Queued USB Module */
+ extern int usb_tm_snd;
+ extern int usb_tm_snded;
+ extern int usb_tm_rcv;
+
+ int usb_com_init( void);
+ void usb_com_start_send( void);
+
+ int usb_com_sendch(int c);
+ int usb_com_recch();
+ int usb_com_sendstr(const char *s);
+
+#endif /* _USB_COM_H */
--- /dev/null
+#include <usb/usb.h>
+
+#ifndef _USB_LOADER_H
+#define _USB_LOADER_H
+
+#define USB_VENDOR_GET_CAPABILITIES 0x00 // get capabilities
+#define USB_VENDOR_RESET_DEVICE 0x08
+// #define USB_VENDOR_SET_BYTE 0x10
+// #define USB_VENDOR_SET_WORD 0x20
+#define USB_VENDOR_GET_SET_MEMORY 0x30
+#define USB_VENDOR_ERASE_MEMORY 0x40 // erase memory for 1 Byte
+#define USB_VENDOR_ERASE_1KB_MEMORY 0x48 // erase memory for 1 KB
+#define USB_VENDOR_MASS_ERASE 0x50 // erase all device memory
+#define USB_VENDOR_GOTO 0x60
+#define USB_VENDOR_CALL 0x70
+#define USB_VENDOR_GET_STATUS 0xF0
+#define USB_VENDOR_MASK 0xF8 // mask for vendor commands
+
+#define USB_VENDOR_MEMORY_BY_BULK 0x80
+
+/* COMMON */
+#define USB_VENDOR_TARGET_RAM 0x01
+#define USB_VENDOR_TARGET_FLASH 0x02
+/* MSP430 */
+#define USB_VENDOR_TARGET_ADAPTER 0x01
+#define USB_VENDOR_TARGET_MSP430 0x02
+/* MSC1210 */
+#define USB_VENDOR_TARGET_DATA 0x01
+#define USB_VENDOR_TARGET_XDATA 0x02
+
+#define USB_VENDOR_TARGET_MASK 0x07
+
+/* bRequest - type of request */
+/* wValue - lower address word */
+/* wIndex - higher address word */
+/* wLength - data or length of data */
+
+#endif /*_USB_LOADER_H*/
--- /dev/null
+/*********************************************************/
+/*** Module : USB communication ***/
+/*** Author : Roman Bartosinski (bartosr@centrum.cz) ***/
+/*** Modify : 14.01.2003 ***/
+/*********************************************************/
+
+#include <cpu_def.h>
+#include <system_def.h>
+#include <stdio.h>
+#include "pdiusb.h"
+#include <h8s2633h.h>
+/*#include <usb/usb_spec.h>*/
+#include "usb_defs.h"
+#include <usb/usb.h>
+#include <usb/usb_com.h>
+
+
+/* Queued USB Module */
+typedef volatile struct{
+ unsigned char *first;
+ unsigned char *last;
+ unsigned char *begin;
+ unsigned char *end;
+} usb_com_que_t;
+
+#define USB_COM_BUF_LEN 80 //(80*8)
+
+usb_com_que_t usb_com_que_in; /* input queue */
+unsigned char usb_com_buf_in[USB_COM_BUF_LEN];
+usb_com_que_t usb_com_que_out; /* output queue */
+unsigned char usb_com_buf_out[USB_COM_BUF_LEN];
+
+int usb_com_init( void);
+int usb_com_put(usb_com_que_t *q, int c);
+int usb_com_get(usb_com_que_t *q);
+
+usb_vendor_extension_fnc_t *usb_vendor_extension=0;
+
+#ifdef PDIUSB_WITH_ADD_IRQ_HANDLER
+/* usb irq handler struct */
+irq_handler_t usb_irq_handler;
+#elif defined(PDIUSB_WITH_EXCPTVECT_SET)
+void usb_isr(void) __attribute__ ((interrupt_handler));
+#endif /*PDIUSB_WITH_EXCPTVECT_SET*/
+
+int usb_irq_cnt;
+
+/* common external function for pdiusb module */
+ void pdiSendCommand( unsigned char byCmd) {
+ writeb( byCmd, PDIUSB_COMMAND_ADDR);
+ }
+ unsigned char pdiReadData( unsigned char byCount, unsigned char *pbyData) {
+ unsigned char out = byCount;
+
+ while (byCount--) {
+ *pbyData = readb( PDIUSB_READ_DATA_ADDR);
+ pbyData++;
+ }
+
+ return out;
+ }
+ void pdiWriteData( unsigned char byCount, unsigned char *pbyData) {
+ while (byCount--) {
+ writeb( *pbyData++, PDIUSB_WRITE_DATA_ADDR);
+ }
+ }
+
+
+/* usb communication module */
+ /* data */
+ usb_flags_t usb_flags;
+ unsigned char usb_address;
+ unsigned char usb_interface;
+ usb_control_ep_t usb_rxtx_control;
+ usb_bulk_ep_t usb_rx_bulk, usb_tx_bulk;
+
+ volatile unsigned int usb_last_irq;
+ // internal buffer for data from/to control req. - must be global
+ unsigned char ctrl_data[PDI_EP0_PACKET_SIZE];
+
+ typeof(msec_time) usb_start = 0, usb_stop = 0;
+
+
+
+/* functions */
+ int usb_run( void) {
+ int ret = 0;
+ if ( usb_flags.running) {
+#ifdef USE_USB_WITH_IRQ
+ if (!usb_flags.bits.was_int) return ret;
+ usb_flags.was_int = 0;
+#else
+ ret = usb_test_interrupt();
+ if ( usb_flags.request == 1) {
+ usb_answer_to_request();
+ }
+ if ( usb_flags.request == 2) { // request is set in usb_answer_to_request()
+ if (( usb_rxtx_control.dreq.bmRequestType & USB_DATA_DIR_MASK)==USB_DATA_DIR_TO_HOST) {
+ unsigned int now = usb_rxtx_control.bytes;
+ if ( now > PDI_EP0_PACKET_SIZE) now = PDI_EP0_PACKET_SIZE;
+ if ( usb_rxtx_control.next_pkt_fnc )
+ if( usb_rxtx_control.next_pkt_fnc(&usb_rxtx_control, now, USB_NEXT_PKT_SEND) ) {
+ usb_stall_ep0();
+ return -1;
+ }
+ debugPrint( DBG_HIGH, ("CNTR send 1.data (%d)\n", now));
+ pdiWriteEndpoint( PDI_EP0_TX, now, usb_rxtx_control.data);
+ usb_rxtx_control.data += now;
+ if ( !(usb_rxtx_control.bytes -= now)) {
+ usb_flags.request = 3;
+ }
+ }
+ }
+ if ( usb_flags.request == 3) {
+ if ( !usb_rxtx_control.dreq.wLength ||
+ (usb_rxtx_control.dreq.bmRequestType & USB_DATA_DIR_MASK)==USB_DATA_DIR_FROM_HOST) {
+ pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
+ if ( usb_rxtx_control.complete_fnc )
+ usb_rxtx_control.complete_fnc(&usb_rxtx_control, USB_COMPLETE_OK);
+ usb_rxtx_control.next_pkt_fnc = NULL;
+ usb_rxtx_control.complete_fnc = NULL;
+ }
+ }
+#endif
+ }
+ return ret;
+ }
+
+ int usb_test_interrupt( void) { //_naked {
+ unsigned char usb_last_status;
+ int ret = 0;
+// INTERRUPT_PRE(0);
+// LEDr = 1;
+// EA=0;
+ usb_last_irq = pdiGetInterrupt();
+ if ( usb_last_irq) {
+ ret = 1;
+ debugPrint( DBG_MEDIUM, ("USB Interrupt 0x%X\n",usb_last_irq));
+ if ( usb_last_irq & PDI_INT_BUSRESET) { // D12 - Bus reset reached
+ usb_flags.configured = 0;
+ if ( usb_flags.running && usb_flags.stop_request) {
+ usb_flags.running = 0;
+ usb_flags.stop_request = 0;
+ }
+ debugPrint( DBG_HIGH, ("Bus Reset\n"));
+ } else {
+ if ( usb_last_irq & PDI_INT_SUSPEND) { // D12 - Suspend flag changed
+ debugPrint( DBG_HIGH, ("Suspend Changed\n"));
+ }
+ // it must be first b/c tx and rx can be sended all together
+ if ( usb_last_irq & PDI_INT_EP0_IN) { // D12 - Ep0TxDone - data in EP0 was sended
+ usb_last_status = pdiGetLastTransStatus( PDI_EP0_TX);
+ debugPrint( DBG_HIGH, ("Ep0-Tx LTS=0x%X\n", usb_last_status));
+ if (( usb_last_status & PDI_LTSTAT_RXTX_OK) && usb_flags.request > 1) {
+ if ( usb_flags.request == 2) {
+ unsigned int now = usb_rxtx_control.bytes;
+ if ( now > PDI_EP0_PACKET_SIZE) now = PDI_EP0_PACKET_SIZE;
+
+ if ( usb_rxtx_control.next_pkt_fnc )
+ if( usb_rxtx_control.next_pkt_fnc(&usb_rxtx_control, now, USB_NEXT_PKT_SEND) ) {
+ usb_stall_ep0();
+ return -1;
+ }
+
+ debugPrint( DBG_HIGH, ("CNTR data\n"));
+ pdiWriteEndpoint( PDI_EP0_TX, now, usb_rxtx_control.data);
+ usb_rxtx_control.data += now;
+ if ( !(usb_rxtx_control.bytes -= now)) {
+ usb_flags.request = 3;
+ }
+ } else if ( usb_flags.request == 3) {
+ debugPrint( DBG_HIGH, ("CNTR ack\n"));
+ usb_flags.request = 0;
+
+ if ( usb_rxtx_control.complete_fnc )
+ usb_rxtx_control.complete_fnc(&usb_rxtx_control, USB_COMPLETE_OK);
+ usb_rxtx_control.next_pkt_fnc = NULL;
+ usb_rxtx_control.complete_fnc = NULL;
+
+ } else {
+ debugPrint( DBG_LOW, ("tx ... ???\n"));
+ }
+ }
+ }
+
+ if ( usb_last_irq & PDI_INT_EP0_OUT) { // D12 - Ep0RxDone - some data was received in EP0
+ usb_last_status = pdiGetLastTransStatus( PDI_EP0_RX);
+ debugPrint( DBG_HIGH, ("Ep0-Rx LTS=0x%X\n", usb_last_status));
+ if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
+ if ( usb_last_status & PDI_LTSTAT_SETUP) {
+ if ( usb_flags.request) {
+ debugPrint( DBG_HIGH, ("!!! New setup, but last not ack ...\n"));
+ }
+ usb_flags.request = 1; // Standard_requests();
+ if ( usb_rxtx_control.complete_fnc )
+ usb_rxtx_control.complete_fnc(&usb_rxtx_control, USB_COMPLETE_FAIL);
+ usb_rxtx_control.next_pkt_fnc = NULL;
+ usb_rxtx_control.complete_fnc = NULL;
+ } else {
+ if ( usb_flags.request == 2) {
+ unsigned int now = usb_rxtx_control.bytes;
+ if ( now > PDI_EP0_PACKET_SIZE) now = PDI_EP0_PACKET_SIZE;
+ debugPrint( DBG_HIGH, ("CNTR data\n"));
+ ret = pdiReadEndpoint( PDI_EP0_RX, now, usb_rxtx_control.data);
+
+ if(ret>usb_rxtx_control.bytes)
+ ret = usb_rxtx_control.bytes;
+
+ usb_rxtx_control.data += ret;
+
+ if ( usb_rxtx_control.next_pkt_fnc ) {
+ if( usb_rxtx_control.next_pkt_fnc(&usb_rxtx_control, ret, USB_NEXT_PKT_REC) ) {
+ usb_stall_ep0();
+ return -1;
+ }
+ }
+
+ if (!(usb_rxtx_control.bytes -= ret)) {
+ usb_rxtx_control.data -= usb_rxtx_control.dreq.wLength;
+ usb_flags.request = 3;
+ }
+ } else if ( usb_flags.request == 3) {
+ debugPrint( DBG_HIGH, ("CNTR ack\n"));
+ usb_flags.request = 0;
+ pdiReadEndpoint( PDI_EP0_RX, 0, 0);
+ if ( usb_rxtx_control.complete_fnc )
+ usb_rxtx_control.complete_fnc(&usb_rxtx_control, USB_COMPLETE_OK);
+ usb_rxtx_control.next_pkt_fnc = NULL;
+ usb_rxtx_control.complete_fnc = NULL;
+ } else {
+ pdiReadEndpoint( PDI_EP0_RX, 0, 0);
+ }
+ }
+ }
+ }
+ if ( usb_last_irq & PDI_INT_EP1_OUT) { // D12 - Ep1RxDone - some data was received in EP1
+ usb_last_status = pdiGetLastTransStatus( PDI_EP1_RX);
+ debugPrint( DBG_HIGH, ("Ep1-Rx LTS=0x%X\n", usb_last_status));
+ if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
+ pdiSetEpStatus( PDI_EP1_OUT, PDI_SET_EP_STALLED);
+ }
+ }
+ if ( usb_last_irq & PDI_INT_EP1_IN) { // D12 - Ep1TxDone - data in EP1 was sended
+ usb_last_status = pdiGetLastTransStatus( PDI_EP1_TX);
+ debugPrint( DBG_HIGH, ("Ep1-Tx LTS=0x%X\n", usb_last_status));
+ if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
+ pdiSetEpStatus( PDI_EP1_IN, PDI_SET_EP_STALLED);
+ }
+ }
+
+ if ( usb_last_irq & PDI_INT_EP2_OUT) { // D12 - Ep2RxDone - some data was received in EP2
+ usb_last_status = pdiGetLastTransStatus( PDI_EP2_RX);
+ debugPrint( DBG_HIGH, ("Ep2-Rx LTS=0x%X\n", usb_last_status));
+ if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
+ if ( usb_flags.terminal_mode) {
+ unsigned char hlpbfr[PDI_EP2_PACKET_SIZE], now = PDI_EP2_PACKET_SIZE, i;
+ MoreRead:
+ now = pdiReadEndpoint( PDI_EP2_RX, now, hlpbfr);
+ for(i=0;i<now;i++) {
+ usb_tm_rcv++;
+ if (usb_com_put( &usb_com_que_in, hlpbfr[i])<0) { /* nevkladat dalsi */
+ break;
+ }
+ }
+ if(now==PDI_EP2_PACKET_SIZE) goto MoreRead;
+ } else {
+ unsigned long now = usb_rx_bulk.remain;
+ if ( now > PDI_EP2_PACKET_SIZE) now = PDI_EP2_PACKET_SIZE;
+
+ if ( !usb_flags.bits.bulk_rx_data) {
+ usb_flags.bulk_rx_data = 1;
+ usb_start = msec_time;
+ }
+
+ ReadAgain:
+ ret = pdiReadEndpoint( PDI_EP2_RX, now, usb_rx_bulk.data);
+ usb_rx_bulk.data += now;
+ if ( !( usb_rx_bulk.remain -= now)) {
+ //usb_rx_bulk.data -= usb_rx_bulk.bytes; /* read again */
+ usb_stop = msec_time;
+ usb_flags.bulk_rx_data = 0;
+ // complete_func or set flag(event)
+ }
+ if ( usb_rx_bulk.remain > 0 && usb_rx_bulk.remain <= PDI_EP2_PACKET_SIZE)
+ goto ReadAgain;
+ }
+ }
+ }
+ if ( usb_last_irq & PDI_INT_EP2_IN) { // D12 - Ep2TxDone - data in EP2 was sended
+ usb_last_status = pdiGetLastTransStatus( PDI_EP2_TX);
+ debugPrint( DBG_HIGH, ("Ep2-Tx LTS=0x%X\n", usb_last_status));
+ if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
+ if ( usb_flags.terminal_mode) {
+ int ch = usb_com_get( &usb_com_que_out);
+ usb_tm_snded++;
+ if ( ch < 0) {
+ usb_flags.bulk_tx_data = 0;
+ } else {
+ unsigned char uchr = ch;
+ usb_flags.bulk_tx_data = 1;
+ pdiWriteEndpoint( PDI_EP2_TX, 1, &uchr);
+ }
+ } else {
+ if ( usb_tx_bulk.remain) {
+ unsigned int now = usb_tx_bulk.remain;
+ if ( now > PDI_EP2_PACKET_SIZE) now = PDI_EP2_PACKET_SIZE;
+ pdiWriteEndpoint( PDI_EP2_TX, now, usb_tx_bulk.data);
+ usb_tx_bulk.data += now;
+ if (!(usb_tx_bulk.remain -= now)) {
+ // complete_func or set flag(event)
+ }
+ }
+ }
+ }
+ }
+ ret = 0;
+ }
+ }
+// EA=1;
+// LEDr = 0;
+// INTERRUPT_POST();
+ return ret;
+ }
+
+
+// ************************************
+ void usb_init( void) {
+ usb_last_irq = 0; usb_address = 0; usb_interface = 0;
+ usb_flags.word = 0;
+
+ usb_com_init();
+
+#ifdef USE_USB_WITH_IRQ
+ usb_irq_cnt=0;
+ #ifdef PDIUSB_WITH_ADD_IRQ_HANDLER
+ if( test_irq_handler( ISR_USB_INTV, &usb_irq_handler)==0)
+ add_irq_handler( ISR_USB_INTV, &usb_irq_handler);
+ #elif defined(PDIUSB_WITH_EXCPTVECT_SET)
+ excptvec_set(ISR_USB_INTV,&usb_isr);
+ #endif /*PDIUSB_WITH_ADD_IRQ_HANDLER*/
+ //*((char*)0xfffa1f) |= 0x04; /* It must be here for pull-up INT signal in usb_isr function */
+#endif
+ debugPrint(DBG_MEDIUM,("# Usb Inited\n"));
+ }
+
+ void usb_connect_bus( void) {
+ debugPrint(DBG_MEDIUM,("Usb connect to bus\n"));
+ usb_flags.running = 1;
+ usb_last_irq = 0;
+ pdiSetDMA( PDI_DMA_EP4_INT | PDI_DMA_EP5_INT); // ???
+ pdiSetMode( PDI_MODE_NO_LAZY_CLOCK | PDI_MODE_CLOCK_RUNNING | PDI_MODE_SOFT_CONNECT | PDI_CLOCK_SET_TO_ONE | PDI_CLOCK_4M);
+ }
+ void usb_disconnect_bus( void) {
+ debugPrint(DBG_MEDIUM,("Usb disconnect from bus\n"));
+ pdiSetMode( PDI_MODE_NO_LAZY_CLOCK | PDI_MODE_CLOCK_RUNNING | PDI_CLOCK_SET_TO_ONE | PDI_CLOCK_4M);
+ usb_flags.configured = 0;
+ usb_flags.stop_request = 1;
+ }
+
+ void usb_stall_ep0( void) {
+ pdiSetEpStatus( PDI_EP0_TX, PDI_SET_EP_STALLED); pdiSetEpStatus( PDI_EP0_RX, PDI_SET_EP_STALLED);
+ }
+
+
+// ************************************
+// *** Common send/receive fncs ***
+// ************************************
+/*
+ void usb_send_to_usb( unsigned char idx, unsigned char maxb) {
+ debugPrint( DBG_HIGH,("USB Send EP#%d (max=%d) <- buff 0x%lX, cnt %d\n",usb_ep[idx].ep, maxb, (unsigned long)usb_ep[idx].buff,usb_ep[idx].bytes));
+ if ( !usb_ep[idx].bytes) pdiWriteEndpoint( usb_ep[idx].ep, 0, 0);
+ else {
+ if ( usb_ep[idx].bytes > maxb) {
+ pdiWriteEndpoint( usb_ep[idx].ep, maxb, usb_ep[idx].buff);
+ usb_ep[idx].bytes -= maxb;
+ usb_ep[idx].buff += maxb;
+ } else {
+ pdiWriteEndpoint( usb_ep[idx].ep, usb_ep[idx].bytes, usb_ep[idx].buff);
+ usb_ep[idx].buff += usb_ep[idx].bytes;
+ usb_ep[idx].bytes = 0;
+// if ( usending) usending = 0;
+ }
+ }
+ }
+
+ unsigned char usb_receive_from_usb( unsigned char idx, unsigned char maxb) {
+ unsigned char ret = 0;
+
+ ret = (unsigned char)usb_ep[idx].bytes;
+ if ( !ret || ret > maxb) ret = maxb;
+ debugPrint( DBG_HIGH,("USB Receive EP#%d ->buff 0x%lX,cnt %d,(max %d)\n",usb_ep[idx].ep,(unsigned long)usb_ep[idx].buff,usb_ep[idx].bytes,ret));
+ if ( !usb_ep[idx].bytes) {
+// ureceiving = 0;
+ pdiReadEndpoint( usb_ep[idx].ep, 0, 0);
+ return 0xff; // too_small_buffer error
+ }
+ do {
+ ret = pdiReadEndpoint( usb_ep[idx].ep, ret, usb_ep[idx].buff);
+ debugPrint( DBG_HIGH,(" - really readed %d\n", ret));
+ usb_ep[idx].buff += ret;
+ usb_ep[idx].bytes -= ret;
+ } while (( ret == maxb) && usb_ep[idx].bytes);
+ return ret;
+ }
+*/
+
+
+#ifdef DEBUG
+ char *ReqRecipient( char rqt) {
+ switch ( rqt & USB_RECIPIENT) {
+ case USB_RECIPIENT_DEVICE: return "DEVICE";
+ case USB_RECIPIENT_INTERFACE: return "INTERFACE";
+ case USB_RECIPIENT_ENDPOINT: return "ENDPOINT";
+ }
+ return "OTHER";
+ }
+ char *ReqType( char rqt) {
+ switch ( rqt & USB_REQUEST_TYPE_MASK) {
+ case USB_STANDARD_REQUEST: return "STANDARD";
+ case USB_CLASS_REQUEST: return "CLASS";
+ case USB_VENDOR_REQUEST: return "VENDOR";
+ }
+ return "RESERVED";
+ }
+ char *ReqName( char req) {
+ switch ( req & USB_REQUEST_MASK) {
+ case USB_REQUEST_GET_STATUS: return "GET STATUS";
+ case USB_REQUEST_CLEAR_FEATURE: return "CLEAR FEATURE";
+ case USB_REQUEST_SET_FEATURE: return "SET FEATURE";
+ case USB_REQUEST_SET_ADDRESS: return "SET ADDRESS";
+ case USB_REQUEST_GET_DESCRIPTOR: return "GET DESCRIPTOR";
+ case USB_REQUEST_SET_DESCRIPTOR: return "SET DESCRIPTOR";
+ case USB_REQUEST_GET_CONFIGURATION: return "GET CONFIGURATION";
+ case USB_REQUEST_SET_CONFIGURATION: return "SET CONFIGURATION";
+ case USB_REQUEST_GET_INTERFACE: return "GET INTERFACE";
+ case USB_REQUEST_SET_INTERFACE: return "SET INTERFACE";
+ case USB_REQUEST_SYNC_FRAME: return "SYNC FRAME";
+ }
+ return "UNKNOWN";
+ }
+#endif
+
+
+ void usb_set_control_data(usb_control_ep_t *ep, void *buff, int size)
+ {
+ ep->data = (unsigned char *) buff;
+ ep->bytes = size;
+ usb_flags.request = 2;
+ debugPrint( DBG_HIGH,("usb_set_control_data buff=0x%lx, len=%d\n", (long)buff, size));
+ }
+
+ void usb_set_control_ack(usb_control_ep_t *ep)
+ {
+ ep->data = NULL;
+ ep->bytes = 0;
+ usb_flags.request = 3;
+ debugPrint( DBG_HIGH,("usb_set_control_ack\n"));
+ }
+
+
+ /*
+ ***********************************
+ *** Execute device requests ***
+ ***********************************
+ */
+ void usb_answer_to_request( void) {
+ USB_DEVICE_REQUEST *pdreq = &usb_rxtx_control.dreq;
+
+ debugPrint( DBG_MEDIUM,("Process usb setup packet\n"));
+ usb_rxtx_control.req_size=pdiReadEndpoint( PDI_EP0_RX, 255, (unsigned char *)pdreq);
+ if ( usb_rxtx_control.req_size == 0xff) {
+ /*LEDr = 1; SetLeds( hlp[0]);*/
+ debugPrint( DBG_LOW,("! BIG Setup packet\n"));
+ usb_stall_ep0();
+ return;
+ }
+ pdiAckSetupControl();
+ /* !!! it must be here !!! */
+ pdreq->wValue = SWAP( pdreq->wValue);
+ pdreq->wIndex = SWAP( pdreq->wIndex);
+ pdreq->wLength = SWAP( pdreq->wLength);
+
+ usb_rxtx_control.next_pkt_fnc = NULL;
+ usb_rxtx_control.complete_fnc = NULL;
+
+ ctrl_data[0] = ctrl_data[1] = 0; // we need only 2 bytes
+
+ #ifdef DEBUG
+ debugPrint( DBG_HIGH, ("Receive (0x%X) %s req. for %s , data %s host\n",
+ pdreq->bmRequestType, ReqType( pdreq->bmRequestType),
+ ReqRecipient(pdreq->bmRequestType),
+ ((pdreq->bmRequestType & USB_DATA_DIR_MASK) ? "TO":"FROM")));
+ debugPrint( DBG_HIGH, (" Request (0x%X) %s\n", pdreq->bRequest,
+ ((!(pdreq->bmRequestType&USB_REQUEST_TYPE_MASK))? ReqName( pdreq->bRequest):"UNKNOWN")));
+ #endif
+
+ switch( pdreq->bmRequestType & USB_RECIPIENT) {
+ case USB_RECIPIENT_DEVICE:
+ switch( pdreq->bmRequestType & USB_REQUEST_TYPE_MASK) {
+ case USB_STANDARD_REQUEST:
+ switch( pdreq->bRequest) {
+ case USB_REQUEST_GET_STATUS:
+ #ifdef USB_MY_SELF_POWER
+ ctrl_data[0]=1;
+ #else
+ ctrl_data[0]=0;
+ #endif
+ USB_SET_CONTROL_DATA( &ctrl_data, 2);
+ //pdiWriteEndpoint( PDI_EP0_TX, 2, hlp);
+ break;
+ case USB_REQUEST_SET_ADDRESS:
+ usb_address = ( unsigned char)( pdreq->wValue & DEVICE_ADDRESS_MASK);
+ pdiSetAddressEnable( usb_address | PDI_ENAD_ENABLE);
+ USB_SET_CONTROL_ACK;
+ //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
+ break;
+ case USB_REQUEST_GET_DESCRIPTOR:
+ usb_get_descriptor();
+ break;
+ case USB_REQUEST_GET_CONFIGURATION:
+ if ( usb_flags.configured) ctrl_data[0] = 1;
+ USB_SET_CONTROL_DATA( &ctrl_data, 1);
+ //pdiWriteEndpoint( PDI_EP0_TX, 1, hlp);
+ break;
+ case USB_REQUEST_SET_CONFIGURATION:
+ if (LSB( pdreq->wValue) < 2) {
+ if ( LSB( pdreq->wValue)) {
+ pdiSetEndpointEnable( usb_flags.configured=1);
+ } else {
+ pdiSetEndpointEnable( usb_flags.configured=0);
+ }
+ USB_SET_CONTROL_ACK;
+ //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
+ } else
+ usb_stall_ep0();
+ break;
+ default:
+ usb_stall_ep0();
+ break;
+ }
+
+ break;
+ case USB_VENDOR_REQUEST:
+ if(usb_vendor_extension) {
+ int ret;
+ ret = usb_vendor_extension(&usb_rxtx_control, pdreq);
+ if (ret<0) {
+ usb_stall_ep0();
+ break;
+ }
+ if (ret>0) {
+ break;
+ }
+ }
+
+ switch ( pdreq->bRequest) {
+ case USB_VENDOR_START_TRANSFER:
+ {
+ unsigned long max = ((long)pdreq->wIndex << 16)+pdreq->wValue;
+ usb_rx_bulk.remain = ( usb_rx_bulk.bytes < max) ? usb_rx_bulk.bytes : max;
+ }
+ USB_SET_CONTROL_ACK;
+ break;
+ case USB_VENDOR_CONTROL_TERMINAL_MODE:
+ if ( pdreq->wValue == 1) usb_flags.terminal_mode = 1;
+ else usb_flags.terminal_mode = 0;
+ USB_SET_CONTROL_ACK;
+ break;
+ default:
+ USB_SET_CONTROL_ACK;
+ //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
+ break;
+ }
+ break;
+ case USB_CLASS_REQUEST:
+ usb_stall_ep0();
+ default:
+ usb_stall_ep0();
+ break;
+ }
+ break;
+ case USB_RECIPIENT_INTERFACE:
+ if (( pdreq->bmRequestType & USB_REQUEST_TYPE_MASK) == USB_STANDARD_REQUEST) {
+ switch( pdreq->bRequest) {
+ case USB_REQUEST_GET_STATUS:
+ USB_SET_CONTROL_DATA( &ctrl_data, 2);
+ //pdiWriteEndpoint( PDI_EP0_TX, 2, hlp);
+ break;
+ case USB_REQUEST_GET_INTERFACE:
+ debugPrint( DBG_HIGH,("ReqIfc=%d Now ifc=%d\n", pdreq->wIndex, usb_interface));
+ USB_SET_CONTROL_DATA( &ctrl_data, 1); // alternate interface
+ //pdiWriteEndpoint( PDI_EP0_TX, 1, hlp);
+ break;
+ case USB_REQUEST_SET_INTERFACE:
+ //if (( dreq.wValue == 0) && ( dreq.wIndex == 0))
+ if ( pdreq->wIndex < 1) { // mame jen 2 pokusne interface
+ usb_interface = (unsigned char) pdreq->wIndex;
+ USB_SET_CONTROL_ACK;
+ //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
+ } else
+ usb_stall_ep0();
+ break;
+ default:
+ usb_stall_ep0();
+ }
+ } else
+ usb_stall_ep0();
+ break;
+ case USB_RECIPIENT_ENDPOINT:
+ if (( pdreq->bmRequestType & USB_REQUEST_TYPE_MASK) == USB_STANDARD_REQUEST) {
+ switch( pdreq->bRequest) {
+ case USB_REQUEST_GET_STATUS:
+ case USB_REQUEST_CLEAR_FEATURE:
+ case USB_REQUEST_SET_FEATURE:
+ {
+ ctrl_data[0] = ( unsigned char)(( pdreq->wIndex & PDI_CNT_EP)<<1);
+ if ( pdreq->wIndex & ( unsigned char) USB_ENDPOINT_DIRECTION_MASK)
+ ctrl_data[0]++;
+ if ( pdreq->bRequest == USB_REQUEST_GET_STATUS) {
+ ctrl_data[0] = pdiSelectEp( ctrl_data[0]); // endpoint in
+ ctrl_data[0] = (( ctrl_data[0] & PDI_SELEP_STALL) == PDI_SELEP_STALL);
+ USB_SET_CONTROL_DATA( &ctrl_data, 2);
+ //pdiWriteEndpoint( PDI_EP0_TX, 2, hlp);
+ } else {
+ if ( pdreq->bRequest == USB_REQUEST_CLEAR_FEATURE) {
+ pdiSetEpStatus( ctrl_data[0], 0);
+ //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
+ } else {
+ pdiSetEpStatus( ctrl_data[0], 1);
+ //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
+ }
+ USB_SET_CONTROL_ACK;
+ }
+ }
+ break;
+ default:
+ usb_stall_ep0();
+ }
+ } else
+ usb_stall_ep0();
+ break;
+// case USB_RECIPIENT_OTHER:
+ default:
+ usb_stall_ep0();
+ break;
+ }
+// usb_flags.command = 0; // ??? data or ack stage ???
+
+#ifdef USE_USB_WITH_IRQ
+// send data if it is needed
+ if ( usb_flags.request == 2) { // request is set to data stage
+ if (( usb_rxtx_control.dreq.bmRequestType & USB_DATA_DIR_MASK)==USB_DATA_DIR_TO_HOST) {
+ unsigned int now = usb_rxtx_control.bytes;
+ if ( now > PDI_EP0_PACKET_SIZE) now = PDI_EP0_PACKET_SIZE;
+ if ( usb_rxtx_control.next_pkt_fnc )
+ if( usb_rxtx_control.next_pkt_fnc(&usb_rxtx_control, now, USB_NEXT_PKT_SEND) ) {
+ usb_stall_ep0();
+ return;
+ }
+ debugPrint( DBG_HIGH, ("CNTR send 1.data (%d)\n", now));
+ pdiWriteEndpoint( PDI_EP0_TX, now, usb_rxtx_control.data);
+ usb_rxtx_control.data += now;
+ if ( !(usb_rxtx_control.bytes -= now)) {
+ usb_flags.request = 3;
+ }
+ }
+ }
+ if ( usb_flags.request == 3) {
+ if ( !usb_rxtx_control.dreq.wLength ||
+ (usb_rxtx_control.dreq.bmRequestType & USB_DATA_DIR_MASK)==USB_DATA_DIR_FROM_HOST) {
+ pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
+ if ( usb_rxtx_control.complete_fnc )
+ usb_rxtx_control.complete_fnc(&usb_rxtx_control, USB_COMPLETE_OK);
+ usb_rxtx_control.next_pkt_fnc = NULL;
+ usb_rxtx_control.complete_fnc = NULL;
+ }
+ }
+#endif
+ }
+
+#ifdef DEBUG
+ char *DescType( unsigned char desc) {
+ switch ( desc) {
+ case USB_DESCRIPTOR_TYPE_DEVICE: return"DEVICE";
+ case USB_DESCRIPTOR_TYPE_CONFIGURATION: return"CONFIGURATION";
+ case USB_DESCRIPTOR_TYPE_STRING: return"STRING";
+ case USB_DESCRIPTOR_TYPE_INTERFACE: return"INTERFACE";
+ case USB_DESCRIPTOR_TYPE_ENDPOINT: return"ENDPOINT";
+ case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER: return"DEVICE_QUALIFIER";
+ case USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION: return"OTHER_SPEED_CONFIG";
+ case USB_DESCRIPTOR_TYPE_POWER: return"POWER";
+ }
+ return "UNKNOWN";
+ }
+#endif
+
+ void usb_get_descriptor( void) {
+ unsigned int size;
+ unsigned short wVal = usb_rxtx_control.dreq.wValue;
+ debugPrint( DBG_MEDIUM, (" - %s descriptor\n", DescType(MSB( wVal))));
+ switch ( MSB( wVal)) {
+ case USB_DESCRIPTOR_TYPE_DEVICE:
+ usb_rxtx_control.data = (unsigned char *) &usb_device_descriptor;
+ size = sizeof( USB_DEVICE_DESCRIPTOR);
+ break;
+ case USB_DESCRIPTOR_TYPE_CONFIGURATION:
+ usb_rxtx_control.data = (unsigned char *) &usb_config_0;
+ size = CONFIG_0_DESCRIPTOR_LENGTH;
+ break;
+ case USB_DESCRIPTOR_TYPE_STRING:
+ if ( LSB( wVal) < USB_CNT_STRINGS) {
+ usb_rxtx_control.data = (unsigned char *) StringDescriptors[ LSB( wVal)];
+ size = *usb_rxtx_control.data;
+ } else {
+ usb_stall_ep0();
+ return;
+ }
+ break;
+ default:
+ usb_stall_ep0();
+ return;
+ }
+ usb_rxtx_control.bytes = ( usb_rxtx_control.dreq.wLength < size) ? usb_rxtx_control.dreq.wLength : size;
+ usb_flags.request = 2;
+ //usb_send_to_usb( SEND_EP0, PDI_EP0_PACKET_SIZE);
+ }
+
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
+/*** ***/
+/*** USB with IRQ ***/
+/*** ***/
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
+
+ #ifdef PDIUSB_WITH_EXCPTVECT_SET
+ void usb_isr(void)
+ #else /*PDIUSB_WITH_EXCPTVECT_SET*/
+ void usb_isr(int intno, void *dev_id, struct pt_regs *regs)
+ #endif /*PDIUSB_WITH_EXCPTVECT_SET*/
+ {
+ unsigned char usb_last_status;
+
+ usb_irq_cnt++;
+ usb_last_irq = pdiGetInterrupt();
+ if ( usb_last_irq) {
+ usb_flags.was_int = 1;
+
+ debugPrint( DBG_INT, ("USB Interrupt 0x%X\n",usb_last_irq));
+ if ( usb_last_irq & PDI_INT_BUSRESET) { // D12 - Bus reset reached
+ usb_flags.configured = 0;
+ if ( usb_flags.running && usb_flags.stop_request) {
+ usb_flags.running = 0;
+ usb_flags.stop_request = 0;
+ }
+ debugPrint( DBG_INT, ("Bus Reset\n"));
+ } else {
+ if ( usb_last_irq & PDI_INT_SUSPEND) { // D12 - Suspend flag changed
+ debugPrint( DBG_INT, ("Suspend Changed\n"));
+ }
+ // it must be first b/c tx and rx can be sended all together
+ if ( usb_last_irq & PDI_INT_EP0_IN) { // D12 - Ep0TxDone - data in EP0 was sended
+ usb_last_status = pdiGetLastTransStatus( PDI_EP0_TX);
+ debugPrint( DBG_INT, ("Ep0-Tx LTS=0x%X\n", usb_last_status));
+ if (( usb_last_status & PDI_LTSTAT_RXTX_OK) && usb_flags.request > 1) {
+ if ( usb_flags.request == 2) {
+ unsigned int now = usb_rxtx_control.bytes;
+ if ( now > PDI_EP0_PACKET_SIZE) now = PDI_EP0_PACKET_SIZE;
+ debugPrint( DBG_INT, ("CNTR data\n"));
+ pdiWriteEndpoint( PDI_EP0_TX, now, usb_rxtx_control.data);
+ usb_rxtx_control.data += now;
+ if ( !(usb_rxtx_control.bytes -= now)) {
+ usb_flags.request = 3;
+ }
+ } else if ( usb_flags.request == 3) {
+ debugPrint( DBG_INT, ("CNTR ack\n"));
+ usb_flags.request = 0;
+ } else {
+ debugPrint( DBG_INT, ("tx 0 ... ???\n"));
+ }
+ }
+ }
+
+ if ( usb_last_irq & PDI_INT_EP0_OUT) { // D12 - Ep0RxDone - some data was received in EP0
+ usb_last_status = pdiGetLastTransStatus( PDI_EP0_RX);
+ debugPrint( DBG_INT, ("Ep0-Rx LTS=0x%X\n", usb_last_status));
+ if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
+ if ( usb_last_status & PDI_LTSTAT_SETUP) {
+ if ( usb_flags.request) {
+ debugPrint( DBG_INT, ("!!! New setup, but last not ack ...\n"));
+ }
+ usb_flags.request = 1; // Standard_requests();
+ usb_answer_to_request();
+ } else {
+ if ( usb_flags.request == 2) {
+ unsigned int now = usb_rxtx_control.bytes, ret;
+ if ( now > PDI_EP0_PACKET_SIZE) now = PDI_EP0_PACKET_SIZE;
+ debugPrint( DBG_INT, ("CNTR data\n"));
+ ret = pdiReadEndpoint( PDI_EP0_RX, now, usb_rxtx_control.data);
+
+ if(ret>usb_rxtx_control.bytes)
+ ret = usb_rxtx_control.bytes;
+
+ usb_rxtx_control.data += ret;
+
+ if ( usb_rxtx_control.next_pkt_fnc ) {
+ if( usb_rxtx_control.next_pkt_fnc(&usb_rxtx_control, ret, USB_NEXT_PKT_REC) ) {
+ usb_stall_ep0();
+ }
+ }
+
+ if (!(usb_rxtx_control.bytes -= ret)) {
+ usb_rxtx_control.data -= usb_rxtx_control.dreq.wLength;
+ usb_flags.request = 3;
+ }
+ } else if ( usb_flags.request == 3) {
+ debugPrint( DBG_INT, ("CNTR ack\n"));
+ usb_flags.request = 0;
+ pdiReadEndpoint( PDI_EP0_RX, 0, 0);
+ if ( usb_rxtx_control.complete_fnc )
+ usb_rxtx_control.complete_fnc(&usb_rxtx_control, USB_COMPLETE_OK);
+ usb_rxtx_control.next_pkt_fnc = NULL;
+ usb_rxtx_control.complete_fnc = NULL;
+ } else {
+ pdiReadEndpoint( PDI_EP0_RX, 0, 0);
+ }
+ }
+ }
+ }
+ if ( usb_last_irq & PDI_INT_EP1_OUT) { // D12 - Ep1RxDone - some data was received in EP1
+ usb_last_status = pdiGetLastTransStatus( PDI_EP1_RX);
+ debugPrint( DBG_INT, ("Ep1-Rx LTS=0x%X\n", usb_last_status));
+ if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
+ pdiSetEpStatus( PDI_EP1_OUT, PDI_SET_EP_STALLED);
+ }
+ }
+ if ( usb_last_irq & PDI_INT_EP1_IN) { // D12 - Ep1TxDone - data in EP1 was sended
+ usb_last_status = pdiGetLastTransStatus( PDI_EP1_TX);
+ debugPrint( DBG_INT, ("Ep1-Tx LTS=0x%X\n", usb_last_status));
+ if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
+ pdiSetEpStatus( PDI_EP1_IN, PDI_SET_EP_STALLED);
+ }
+ }
+
+ if ( usb_last_irq & PDI_INT_EP2_OUT) { // D12 - Ep2RxDone - some data was received in EP2
+ usb_last_status = pdiGetLastTransStatus( PDI_EP2_RX);
+ debugPrint( DBG_INT, ("Ep2-Rx LTS=0x%X\n", usb_last_status));
+ if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
+ if ( usb_flags.terminal_mode) {
+ unsigned char hlpbfr[PDI_EP2_PACKET_SIZE], now = PDI_EP2_PACKET_SIZE, i;
+ MoreRead:
+ now = pdiReadEndpoint( PDI_EP2_RX, now, hlpbfr);
+ for(i=0;i<now;i++) {
+ usb_tm_rcv++;
+ if (usb_com_put( &usb_com_que_in, hlpbfr[i])<0) { /* nevkladat dalsi */
+ break;
+ }
+ }
+ if(now==PDI_EP2_PACKET_SIZE) goto MoreRead;
+ } else {
+ unsigned char now = (usb_rx_bulk.remain > (unsigned long)PDI_EP2_PACKET_SIZE)?PDI_EP2_PACKET_SIZE:(unsigned char)usb_rx_bulk.remain;
+ // unsigned char hlp[2];
+
+ if ( !usb_flags.bits.bulk_rx_data) {
+ usb_flags.bulk_rx_data = 1;
+ usb_start = msec_time;
+ }
+ // if ( now > PDI_EP2_PACKET_SIZE) now = PDI_EP2_PACKET_SIZE;
+ ReadAgain:
+ now = pdiReadEndpoint( PDI_EP2_RX, now, usb_rx_bulk.data);
+ usb_rx_bulk.data += now;
+ if ( !( usb_rx_bulk.remain -= now)) {
+ usb_stop = msec_time;
+ usb_flags.bulk_rx_data = 0;
+ // complete_func or set flag(event)
+ }
+ if ( usb_rx_bulk.remain > 0 && usb_rx_bulk.remain <= PDI_EP2_PACKET_SIZE)
+ goto ReadAgain;
+ }
+ }
+ }
+ if ( usb_last_irq & PDI_INT_EP2_IN) { // D12 - Ep2TxDone - data in EP2 was sended
+ usb_last_status = pdiGetLastTransStatus( PDI_EP2_TX);
+ debugPrint( DBG_INT, ("Ep2-Tx LTS=0x%X\n", usb_last_status));
+ if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
+ if ( usb_flags.terminal_mode) {
+ int ch;
+ usb_tm_snded++;
+ ch = usb_com_get( &usb_com_que_out);
+ if ( ch < 0) {
+ usb_flags.bulk_tx_data = 0;
+ } else {
+ unsigned char uchr = ch;
+ usb_flags.bulk_tx_data = 1;
+ pdiWriteEndpoint( PDI_EP2_TX, 1, &uchr);
+ }
+ } else {
+ if ( usb_tx_bulk.remain) {
+ unsigned int now = usb_tx_bulk.remain;
+ if ( now > PDI_EP2_PACKET_SIZE) now = PDI_EP2_PACKET_SIZE;
+ pdiWriteEndpoint( PDI_EP2_TX, now, usb_tx_bulk.data);
+ usb_tx_bulk.data += now;
+ if (!(usb_tx_bulk.remain -= now)) {
+ // complete_func or set flag(event)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+#ifdef PDIUSB_WITH_ADD_IRQ_HANDLER
+ irq_handler_t usb_irq_handler = {
+ handler: usb_isr,
+ flags: 0,
+ dev_id: 0,
+ devname: "usb",
+ next: 0
+ };
+#endif /*PDIUSB_WITH_ADD_IRQ_HANDLER*/
+
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
+/*** ***/
+/*** USB COM Emulator Module ***/
+/*** ***/
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
+ int usb_tm_snd;
+ int usb_tm_snded;
+ int usb_tm_rcv;
+
+ int usb_com_init( void) {
+ usb_tm_snd = 0;
+ usb_tm_snded = 0;
+ usb_tm_rcv = 0;
+
+ usb_com_que_in.begin=usb_com_buf_in;
+ usb_com_que_in.end=usb_com_que_in.begin+sizeof(usb_com_buf_in);
+ usb_com_que_in.first=usb_com_que_in.begin;
+ usb_com_que_in.last=usb_com_que_in.begin;
+
+ usb_com_que_out.begin=usb_com_buf_out;
+ usb_com_que_out.end=usb_com_que_out.begin+sizeof(usb_com_buf_out);
+ usb_com_que_out.first=usb_com_que_out.begin;
+ usb_com_que_out.last=usb_com_que_out.begin;
+
+ return 1;
+ }
+
+ /* put character c into queue, if full return -1 */
+ int usb_com_put(usb_com_que_t *q, int c)
+ {
+ unsigned char *p=q->last;
+ *(p++)=(unsigned char)c;
+ if (p==q->end) p=q->begin;
+ if (p==q->first) return -1;
+ q->last=p;
+ return c;
+ }
+ /* get character from queue, if empty return -1 */
+ int usb_com_get(usb_com_que_t *q)
+ {
+ unsigned char *p;
+ int c;
+ p=q->first;
+ if(p==q->last) return -1;
+ c=*(p++);
+ if(p==q->end) p=q->begin;
+ q->first=p;
+ return c;
+ }
+
+/*
+ int usb_com_sendch(int c) {
+ if ( usb_flags.terminal_mode) {
+ usb_tm_snd++;
+ if ( !usb_flags.bits.bulk_tx_data) { // hned poslat - atomicke nastaveni flagu ...
+ unsigned char byte = c;
+ pdiWriteEndpoint( PDI_EP2_TX, 1, (unsigned char *)&byte);
+ usb_flags.bulk_tx_data = 1;
+ } else {
+ if( usb_com_put(&usb_com_que_out,c)<0){ // nevejde se
+#ifdef USE_USB_WITH_IRQ
+ while( usb_com_que_out.last == usb_com_que_out.first-1); // Wait if buffer is full !@#$%^&*
+ if( usb_com_put(&usb_com_que_out,c)<0) // case (last==end and first==begin) not respected
+#endif
+ c=-1;
+ }
+ }
+ }
+ return c;
+ }
+*/
+ void usb_com_start_send( void) {
+ if ( !usb_flags.bits.bulk_tx_data &&
+ usb_com_que_out.first != usb_com_que_out.last) {
+ int ch;
+ ch = usb_com_get( &usb_com_que_out);
+ if ( ch >= 0) {
+ unsigned char byte = ch;
+ usb_flags.bulk_tx_data = 1;
+ pdiWriteEndpoint( PDI_EP2_TX, 1, &byte);
+ }
+ }
+ }
+
+ int usb_com_sendch(int c) {
+ if ( usb_flags.terminal_mode) {
+ usb_tm_snd++;
+#ifndef USE_USB_WITH_IRQ
+ if( !usb_flags.bits.bulk_tx_data) {
+ unsigned char byte = c;
+ usb_flags.bulk_tx_data = 1;
+ pdiWriteEndpoint( PDI_EP2_TX, 1, &byte);
+ return c;
+ }
+#endif
+ if( usb_com_put(&usb_com_que_out,c)<0){ /* nevejde se */
+
+#ifdef USE_USB_WITH_IRQ
+ if ( !usb_flags.bits.bulk_tx_data) {
+ usb_com_start_send();
+ } else {
+ while( usb_com_que_out.last == usb_com_que_out.first-1); /* Wait if buffer is full !@#$%^&* */
+ }
+ if( usb_com_put(&usb_com_que_out,c)<0) /* case (last==end and first==begin) isn't respected */
+#endif
+ c=-1;
+ }
+ }
+ return c;
+ }
+
+
+
+ int usb_com_recch() {
+ int val;
+ if ( !usb_flags.bits.terminal_mode) return -1;
+ val=usb_com_get(&usb_com_que_in);
+ return val;
+ }
+
+ int usb_com_sendstr(const char *s) {
+ int cnt=0;
+ while(*s)
+ {
+ if(usb_com_sendch((unsigned char)(*(s++)))<0) break;
+ cnt++;
+ }
+ return cnt;
+ }
+
--- /dev/null
+/*****************************************************/
+/*** Module : USB module ***/
+/*** Author : Roman Bartosinski (C) 28.04.2002 ***/
+/*** Modify : 08.08.2002, 16.04.2003 ***/
+/*****************************************************/
+
+#include <string.h>
+#include <cpu_def.h>
+#include <system_def.h>
+#include <usb/usb.h>
+#include <usb/usb_spec.h>
+#include <usb/usbdebug.h>
+#include <usb/usb_srq.h>
+
+ // ****************************
+ int usb_stdreq_get_status( usb_device_t *udev)
+ {
+ unsigned char c, buf[2] = { 0, 0};
+ unsigned char epid = (unsigned char) udev->request.wIndex;
+ usb_ep_t *ep0 = &(udev->ep0);
+
+ usb_debug_print( DEBUG_LEVEL_HIGH, ("GetStatus\n"));
+ switch( udev->request.bmRequestType & USB_RECIPIENT) {
+ case USB_RECIPIENT_DEVICE:
+ if ( udev->flags & USB_FLAG_REMOTE_WAKE) //.remote_wake_up == 1)
+ buf[0] = USB_GETSTATUS_REMOTE_WAKEUP_ENABLED | USB_GETSTATUS_SELF_POWERED;
+ else
+ buf[0] = USB_GETSTATUS_SELF_POWERED;
+ break;
+ case USB_RECIPIENT_INTERFACE:
+ break;
+ case USB_RECIPIENT_ENDPOINT:
+ #if 0
+ if ( epid & USB_ENDPOINT_DIRECTION_MASK)
+ c = pdiSelectEp(pdiEp2Idx(epid)); // endpoint in
+ else
+ c = pdiSelectEp(pdiEp2Idx(epid)); // endpoint Out
+ #ifdef PDIUSBD12
+ buf[0] = (( c & PDI_SELEP_STALL) == PDI_SELEP_STALL);
+ #else
+ buf[0] = 0;
+ #endif
+ #endif
+ #warning usb_stdreq_get_status is DUMMY
+ break;
+ default:
+ return USB_COMPLETE_FAIL;
+ }
+ usb_udev_write_endpoint( ep0, buf, 2);
+ return USB_COMPLETE_OK;
+ }
+
+ int usb_stdreq_clear_feature( usb_device_t *udev)
+ {
+ usb_ep_t *ep = NULL;
+ USB_DEVICE_REQUEST *dreq = &(udev->request);
+ unsigned char epid = (unsigned char) dreq->wIndex;
+
+ usb_debug_print( DEBUG_LEVEL_HIGH, ("ClearFeature\n"));
+ switch( dreq->bmRequestType & USB_RECIPIENT) {
+ case USB_RECIPIENT_DEVICE:
+ if ( dreq->wValue == USB_FEATURE_REMOTE_WAKEUP) {
+ udev->flags &= ~USB_FLAG_REMOTE_WAKE; //.remote_wake_up = 0;
+ usb_udev_ack_setup( udev);
+ return USB_COMPLETE_OK;
+ }
+ break;
+ case USB_RECIPIENT_ENDPOINT:
+ if(!epid) {
+ ep = &udev->ep0;
+ } else {
+ unsigned char i;
+ for(i = 0; i < udev->cntep; i++) {
+ if(udev->ep[i].epnum == epid) {
+ ep = &udev->ep[i];
+ }
+ }
+ if(!ep)
+ break;
+ }
+ if ( dreq->wValue == USB_FEATURE_ENDPOINT_STALL) {
+ usb_udev_unstall(ep);
+ usb_udev_ack_setup( udev);
+ return USB_COMPLETE_OK;
+ }
+ break;
+ }
+ return USB_COMPLETE_FAIL;
+ }
+
+ int usb_stdreq_set_feature( usb_device_t *udev)
+ {
+ usb_ep_t *ep = NULL;
+ USB_DEVICE_REQUEST *dreq = &(udev->request);
+ unsigned char epid = (unsigned char) dreq->wIndex;
+
+ usb_debug_print( DEBUG_LEVEL_HIGH, ("SetFeature\n"));
+ switch( dreq->bmRequestType & USB_RECIPIENT) {
+ case USB_RECIPIENT_DEVICE:
+ if ( dreq->wValue == USB_FEATURE_REMOTE_WAKEUP) {
+ udev->flags |= USB_FLAG_REMOTE_WAKE; //.remote_wake_up = 1;
+ usb_udev_ack_setup( udev);
+ return USB_COMPLETE_OK;
+ }
+ break;
+ case USB_RECIPIENT_ENDPOINT:
+ if(!epid) {
+ ep = &udev->ep0;
+ } else {
+ unsigned char i;
+ for(i = 0; i < udev->cntep; i++) {
+ if(udev->ep[i].epnum == epid) {
+ ep = &udev->ep[i];
+ }
+ }
+ if(!ep)
+ break;
+ }
+ if ( dreq->wValue == USB_FEATURE_ENDPOINT_STALL) {
+ usb_udev_stall(ep);
+ usb_udev_ack_setup( udev);
+ return USB_COMPLETE_OK;
+ }
+ break;
+ }
+ return USB_COMPLETE_FAIL;
+ }
+
+ int usb_stdreq_set_address( usb_device_t *udev)
+ {
+ int adr;
+ USB_DEVICE_REQUEST *dreq = &(udev->request);
+ adr=dreq->wValue & DEVICE_ADDRESS_MASK;
+ usb_debug_print( DEBUG_LEVEL_HIGH, ("SetAddr-%d\n",adr));
+ usb_udev_ack_setup( udev);
+ usb_udev_set_addr( udev, adr);
+ return USB_COMPLETE_OK;
+ }
+
+ int usb_stdreq_get_configuration( usb_device_t *udev)
+ {
+ unsigned char buf = udev->configuration; //usb_flags.configured;
+ usb_ep_t *ep0 = &(udev->ep0);
+ usb_debug_print( DEBUG_LEVEL_HIGH, ("GetConfig\n"));
+ usb_udev_write_endpoint( ep0, &buf, 1);
+ return USB_COMPLETE_OK;
+ }
+
+ int usb_stdreq_set_configuration( usb_device_t *udev)
+ {
+ USB_DEVICE_REQUEST *dreq = &(udev->request);
+ unsigned char iCfg = dreq->wValue & 0xff;
+ usb_debug_print( DEBUG_LEVEL_HIGH, ("SetConfig\n"));
+ while (1) { // put device in unconfigured state or set configuration 1 ( no else)
+ const USB_DEVICE_CONFIGURATION_ENTRY *pcd = udev->devdes_table->pConfigurations;
+ if(iCfg) {
+ unsigned char i = udev->devdes_table->bNumConfigurations;
+ for(; i && (pcd->pConfigDescription->bConfigurationValue != iCfg); i--, pcd++);
+ if(!i)
+ break;
+ }
+
+ udev->flags &= ~USB_FLAG_CONFIGURED;
+
+ usb_udev_ack_setup( udev);
+
+ usb_udev_set_configuration( udev, iCfg);
+
+ udev->configuration = iCfg; //usb_flags.configured = iCfg;
+
+ if(iCfg)
+ udev->flags |= USB_FLAG_CONFIGURED;
+
+ return USB_COMPLETE_OK;
+ }
+ return USB_COMPLETE_FAIL;
+ }
+
+ int usb_stdreq_get_interface( usb_device_t *udev)
+ {
+ unsigned char buf = 0; /// udev->interface
+ usb_ep_t *ep0 = &(udev->ep0);
+ usb_debug_print( DEBUG_LEVEL_HIGH, ("GetIface\n"));
+ usb_udev_write_endpoint( ep0, &buf, 1);
+ return USB_COMPLETE_OK;
+ }
+
+ int usb_stdreq_set_interface( usb_device_t *udev)
+ {
+ USB_DEVICE_REQUEST *dreq = &(udev->request);
+
+ usb_debug_print( DEBUG_LEVEL_HIGH, ("SetIface\n"));
+ if (( dreq->wValue == 0) && ( dreq->wIndex == 0)) {
+ usb_udev_ack_setup( udev);
+ return USB_COMPLETE_OK;
+ } else {
+ return USB_COMPLETE_FAIL;
+ }
+ }
+
+ int usb_stdreq_get_descriptor( usb_device_t *udev)
+ {
+ unsigned char confidx;
+ unsigned char *pDesc;
+ unsigned short Len = 0;
+ USB_DEVICE_REQUEST *dreq = &(udev->request);
+ const USB_DEVICE_CONFIGURATION_ENTRY *pconfent;
+ int i;
+
+ i = (dreq->wValue >> 8) & 0xff; /* MSB part of wValue */
+ usb_debug_print( DEBUG_LEVEL_HIGH, ("GetDesc\n"));
+ usb_debug_print( DEBUG_LEVEL_VERBOSE, ( " - %s desc.\n", /*(unsigned int)*/ usb_debug_get_std_descriptor(i)));
+
+ switch (i) {
+ case USB_DESCRIPTOR_TYPE_DEVICE:
+ pDesc = (unsigned char *)udev->devdes_table->pDeviceDescription;
+ Len = sizeof( USB_DEVICE_DESCRIPTOR);
+ break;
+ case USB_DESCRIPTOR_TYPE_CONFIGURATION:
+ /* FIXME confidx = udev->configuration; */
+ confidx = 0;
+ pconfent = &udev->devdes_table->pConfigurations[confidx];
+ pDesc = (unsigned char *)pconfent->pConfigDescription;
+ Len = pconfent->iConfigTotalLength;
+ break;
+ case USB_DESCRIPTOR_TYPE_INTERFACE:
+ /* FIXME multiple interfaces */
+ pDesc = (unsigned char *)udev->devdes_table->pInterfaceDescriptors[0];
+ Len = sizeof( USB_INTERFACE_DESCRIPTOR);
+ break;
+ case USB_DESCRIPTOR_TYPE_STRING:
+ i = dreq->wValue & 0xff; /* LSB part of wValue */
+ /*printf("Get descriptor indx=0x%02x\n", i);*/
+ if ( i < udev->devdes_table->iNumStrings) {
+ pDesc = (unsigned char *) udev->devdes_table->pStrings[i];
+ Len = *pDesc;
+ /*usb_debug_print(0,("indx=0x%02x ptr=%p len=%d : '%c'\n", i, pDesc, Len, pDesc[2]));*/
+ } else {
+ return USB_COMPLETE_FAIL;
+ }
+ break;
+ default:
+ return USB_COMPLETE_FAIL;
+ }
+ if ( dreq->wLength < Len) Len = dreq->wLength;
+ usb_send_control_data( udev, pDesc, Len);
+ return USB_COMPLETE_OK;
+ }
+
+
+/*
+ void usb_init_stdreq_fnc( usb_device_t *udev)
+ {
+ // memset( udev->stdreq, 0, sizeof(udev->stdreq));
+
+ udev->stdreq[USB_REQUEST_GET_STATUS] = usb_stdreq_get_status;
+ udev->stdreq[USB_REQUEST_CLEAR_FEATURE] = usb_stdreq_clear_feature;
+ udev->stdreq[USB_REQUEST_SET_FEATURE] = usb_stdreq_set_feature;
+ udev->stdreq[USB_REQUEST_SET_ADDRESS] = usb_stdreq_set_address;
+ udev->stdreq[USB_REQUEST_GET_DESCRIPTOR] = usb_stdreq_get_descriptor;
+ udev->stdreq[USB_REQUEST_GET_CONFIGURATION] = usb_stdreq_get_configuration;
+ udev->stdreq[USB_REQUEST_SET_CONFIGURATION] = usb_stdreq_set_configuration;
+ udev->stdreq[USB_REQUEST_GET_INTERFACE] = usb_stdreq_get_interface;
+ udev->stdreq[USB_REQUEST_SET_INTERFACE] = usb_stdreq_set_interface;
+ }
+*/
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+default_CONFIG = CONFIG_USB_PDIUSB=x
+
+ifeq ($(CONFIG_USB_PDIUSB),y)
+lib_LIBRARIES = usbpdi
+
+nobase_include_HEADERS = usb/pdi.h usb/pdiusb.h
+
+usbpdi_SOURCES = pdi.c pdiusb.c
+#usbpdi_SOURCES += pdi4rtems.c
+endif #CONFIG_USB_PDIUSB
--- /dev/null
+/*****************************************************/
+/*** Module : USB PDI ***/
+/*** Author : Roman Bartosinski (C) 28.04.2002 ***/
+/*** Modify : 08.08.2002, 16.04.2003 ***/
+/*****************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <system_def.h>
+
+#define USB_PDI_EXPORT_FNC
+
+#include <usb/pdiusb.h>
+#include <usb/pdi.h>
+#include <usb/usbdebug.h>
+
+
+/* init chip state */
+ void pdiInitChipState( void) {
+ #ifdef PDIUSBD11
+ pdiSetHUBAddressEnable( 0, 0);
+ #endif /*PDIUSBD11*/
+ pdiSetAddressEnable( PDI_ENAD_ENABLE);
+ pdiSetEndpointEnable( PDI_EPEN_ENABLE);
+ }
+
+#ifdef PDIUSBD11
+
+ #define PDI_MODE_BASE_VALUE (PDI_MODE_MUSTBEONE | \
+ PDI_MODE_REMOTE_WAKEUP | PDI_MODE_NO_LAZY_CLOCK | \
+ PDI_MODE_CLOCK_RUNNING | PDI_CLOCK_4M)
+
+#else /*PDIUSBD11*/
+
+ #define PDI_MODE_BASE_VALUE (PDI_CLOCK_SET_TO_ONE | \
+ PDI_MODE_NO_LAZY_CLOCK | PDI_MODE_CLOCK_RUNNING | \
+ PDI_CLOCK_4M)
+
+#endif /*PDIUSBD11*/
+
+ int usb_pdi_set_addr( usb_device_t *udev, unsigned char addr) {
+ #if !defined(PDIUSBH11A_MULTIPLE) // D11,D12,H11,H11A_S(emb.fnc)
+ pdiSetAddressEnable(addr | PDI_ENAD_ENABLE);
+ #else
+ /*void pdiSetEmbFncAddressEnable( unsigned char byFnc, unsigned char byAddress, unsigned char byEnable);*/
+ #error usb_pdi_set_addr not implemented for PDIUSBH11A_MULTIPLE
+ #endif
+ return 0;
+ }
+
+ int usb_pdi_set_configuration( usb_device_t *udev, unsigned char iCfg) USB_UDEV_REENTRANT_SIGN
+ {
+ pdiSetEndpointEnable( 0); // USBInitUnconfig();
+ if ( iCfg) {
+ pdiSetEndpointEnable( PDI_EPEN_ENABLE); //USBInitConfig();
+ }
+ return 0;
+ }
+
+/* connect usb */
+ int usb_pdi_connect( usb_device_t *udev) {
+ pdiSetMode( PDI_MODE_BASE_VALUE | PDI_MODE_SOFT_CONNECT );
+ return 0;
+ }
+
+/* disconnect usb */
+ int usb_pdi_disconnect( usb_device_t *udev) {
+ pdiSetMode( PDI_MODE_BASE_VALUE & ~PDI_MODE_SOFT_CONNECT );
+ return 0;
+ }
+
+/* acknowledge control transfer */
+ void usb_pdi_ack_setup( usb_device_t *udev) {
+ pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
+ }
+
+
+/* acknowledge control transfer */
+ void usb_pdi_ack_control_setup( usb_device_t *udev) {
+ pdiAckSetupControl();
+ }
+
+
+/**
+ * usb_pdi_check events
+ * function reads interrupt register and sets event flags
+ * function returns 1 if there is some new event.
+ * function returns 0 if there isn't new event but all is OK
+ * function returns -1 if there is any error
+*/
+ int usb_pdi_check_events( usb_device_t *udev) {
+ volatile unsigned char LastTrans = 0;
+ volatile unsigned int LastInt;
+ int ret = 0, i;
+
+ LastInt = pdiGetInterrupt();
+if ( LastInt) {
+ usb_debug_print( DEBUG_LEVEL_LOW, ("PI=0x%04X\n", LastInt));
+}
+ usb_debug_print( DEBUG_LEVEL_HIGH, ("PDI Int=0x%04X\n", LastInt));
+
+ if ( LastInt & PDI_INT_BUSRESET) { // D12 - Bus reset reached
+ pdiInitChipState();
+ udev->flags |= USB_FLAG_BUS_RESET;
+ ret = 1;
+ } else {
+ #ifdef PDIUSBD12
+ if ( LastInt & PDI_INT_SUSPEND) { // D12 - Suspend flag changed
+ udev->flags |= USB_FLAG_SUSPEND;
+ ret = 1;
+ }
+ #endif
+
+
+ if ( LastInt & PDI_INT_EP0_OUT) { // D12 - Ep0RxDone - some data was received in EP0
+ LastTrans = pdiGetLastTransStatus( PDI_EP0_RX);
+ if ( LastTrans & PDI_LTSTAT_SETUP) { // setup packet
+ udev->flags |= USB_FLAG_SETUP;
+ } else {
+ udev->flags |= USB_FLAG_EVENT_RX0;
+ }
+ ret = 1;
+ }
+ if ( LastInt & PDI_INT_EP0_IN) { // D12 - Ep0TxDone - data in EP0 was sended
+ LastTrans = pdiGetLastTransStatus( PDI_EP0_TX);
+ udev->flags |= USB_FLAG_EVENT_TX0;
+ ret = 1;
+ }
+
+
+ for( i=0; i<udev->cntep; i++) {
+ if ( LastInt & (udev->ep+i)->event_mask) {
+ LastTrans = pdiGetLastTransStatus( (udev->ep+i)->epnum);
+ udev->ep_events |= 1<<i;
+ LastInt &= ~((udev->ep+i)->event_mask);
+ ret = 1;
+ }
+ }
+
+ /* check unsupported endpoints */
+ if ( LastInt & PDI_INT_EP1_OUT) { // D12 - Ep1RxDone - some data was received in EP1
+ LastTrans = pdiGetLastTransStatus( PDI_EP1_RX);
+ pdiSetEpStatus( PDI_EP1_RX, PDI_SET_EP_STALLED);
+ }
+ if ( LastInt & PDI_INT_EP1_IN) { // D12 - Ep1TxDone - data in EP1 was sended
+ LastTrans = pdiGetLastTransStatus( PDI_EP1_TX);
+ pdiSetEpStatus( PDI_EP1_TX, PDI_SET_EP_STALLED);
+ }
+ if ( LastInt & PDI_INT_EP2_OUT) { // D12 - Ep2RxDone - some data was received in EP2
+ LastTrans = pdiGetLastTransStatus( PDI_EP2_RX);
+ pdiSetEpStatus( PDI_EP2_RX, PDI_SET_EP_STALLED);
+ }
+ if ( LastInt & PDI_INT_EP2_IN) { // D12 - Ep2TxDone - data in EP2 was sended
+ LastTrans = pdiGetLastTransStatus( PDI_EP2_TX);
+ pdiSetEpStatus( PDI_EP2_TX, PDI_SET_EP_STALLED);
+ }
+ #if defined(PDIUSBD11) || defined(PDIUSBH11A_SINGLE) // D11,H11_S
+ if ( LastInt & PDI_INT_EP3_OUT) { // D11 - Ep3RxDone - some data was received in EP3
+ LastTrans = pdiGetLastTransStatus( PDI_EP3_RX);
+ pdiSetEpStatus( PDI_EP3_RX, PDI_SET_EP_STALLED);
+ }
+ if ( LastInt & PDI_INT_EP3_IN) { // D11 - Ep3TxDone - data in EP3 was sended
+ LastTrans = pdiGetLastTransStatus( PDI_EP3_TX);
+ pdiSetEpStatus( PDI_EP3_TX, PDI_SET_EP_STALLED);
+ }
+ #endif /* D11,H11_S */
+ }
+ return ret;
+ }
+
+
+/* stall endpoint X */
+ void usb_pdi_stall( usb_ep_t *ep) {
+ if ( ep->epnum) {
+ pdiSetEpStatus( ep->epnum, PDI_SET_EP_STALLED);
+ } else { // endpoint0
+ pdiSetEpStatus( PDI_EP0_TX, PDI_SET_EP_STALLED);
+ pdiSetEpStatus( PDI_EP0_RX, PDI_SET_EP_STALLED);
+ }
+ }
+
+/* stall endpoint X */
+ void usb_pdi_unstall( usb_ep_t *ep) {
+ if ( ep->epnum) {
+ pdiSetEpStatus( ep->epnum, 0);
+ } else { // endpoint0
+ pdiSetEpStatus( PDI_EP0_TX, 0);
+ pdiSetEpStatus( PDI_EP0_RX, 0);
+ }
+ }
+
+ int usb_pdi_read_endpoint( usb_ep_t *ep, void *ptr, int size) USB_UDEV_REENTRANT_SIGN
+ {
+ if(!ep->epnum)
+ return pdiReadEndpoint( PDI_EP0_RX, size, ptr);
+ else
+ return pdiReadEndpoint( ep->epnum, size, ptr);
+ }
+
+ int usb_pdi_write_endpoint( usb_ep_t *ep, const void *ptr, int size) USB_UDEV_REENTRANT_SIGN
+ {
+ if(!ep->epnum)
+ pdiWriteEndpoint( PDI_EP0_TX, size, ptr);
+ else
+ pdiWriteEndpoint( ep->epnum, size, ptr);
+ return size;
+ }
+
+
+/* init usb structures and chip */
+ int usb_pdi_init( usb_device_t *udev) {
+
+ #ifndef USB_PDI_DIRECT_FNC
+ udev->connect = usb_pdi_connect;
+ udev->set_addr = usb_pdi_set_addr;
+ udev->set_configuration = usb_pdi_set_configuration;
+ udev->disconnect = usb_pdi_disconnect;
+ udev->ack_setup = usb_pdi_ack_setup;
+ udev->ack_control_setup = usb_pdi_ack_control_setup;
+ udev->stall = usb_pdi_stall;
+ udev->unstall = usb_pdi_unstall;
+ udev->check_events = usb_pdi_check_events;
+ udev->read_endpoint = usb_pdi_read_endpoint;
+ udev->write_endpoint = usb_pdi_write_endpoint;
+ #endif /*USB_PDI_DIRECT_FNC*/
+
+ udev->ep0.max_packet_size = PDI_EP0_PACKET_SIZE;
+
+ pdiInitChipState();
+ pdiSetMode( PDI_MODE_BASE_VALUE);
+ return 0;
+ }
--- /dev/null
+/*********************************************************/
+/*** Module : PDIUSB D11,H11,H11A,D12 - implement. ***/
+/*** Author : Roman Bartosinski (C) 03.10.2002 ***/
+/*** Description : Integrate common functions for ***/
+/*** PDIUSBD11,PDIUSBD12,PDIUSBH11(old) ***/
+/*** PDIUSBH11A in Single/Multiple mode ***/
+/*** to one common file. ***/
+/*** Modify : 10.10.2002 - add H11 ***/
+/*** 13.10.2002 - add spec.fnc for 'using' ***/
+/*********************************************************/
+
+#include <system_def.h>
+#include <endian.h>
+#if __BYTE_ORDER == __BIG_ENDIAN
+ #include <byteswap.h>
+#endif
+#include <usb/pdiusb.h>
+#include <usb/usb_spec.h>
+
+ #ifdef PDI_CMD_RWD_INTERNAL
+ #ifndef PDIUSBD12
+ #include <periph/i2c.h>
+ #endif
+ #endif
+
+ #ifndef SDCC
+ #define xdata
+ #endif
+
+
+/*********************************************************/
+// Function for read and write from/into chip
+
+ #if defined(PDI_CMD_RWD_INTERNAL)
+ #if defined(PDIUSBD12) // parallel interface
+
+ void pdiSendCommand( unsigned char byCmd) {
+ *((volatile xdata unsigned char *) PDIUSB_COMMAND_ADDR) = byCmd;
+ }
+ unsigned char pdiReadData( unsigned char byCount, void *pbyData) {
+ unsigned char out = byCount;
+ while (byCount) {
+ byCount--;
+ *(unsigned char*)pbyData++ = *((volatile xdata unsigned char *) PDIUSB_READ_DATA_ADDR);
+ }
+ return out;
+ }
+ void pdiWriteData( unsigned char byCount, const void *pbyData) {
+ while (byCount) {
+ byCount--;
+ *((volatile xdata unsigned char *) PDIUSB_WRITE_DATA_ADDR) = *(unsigned char*)pbyData++;
+ }
+ }
+
+ #if defined(PDI_USE_USING)
+ unsigned short pdiIntCmdReadData( unsigned char byCmd, unsigned char byShort) _PDI_USING {
+ unsigned char i[2];
+ *((volatile xdata unsigned char *) PDIUSB_COMMAND_ADDR) = byCmd;
+ i[0] = *((volatile xdata unsigned char *) PDIUSB_READ_DATA_ADDR);
+ if ( !byShort) {
+ i[1] = 0;
+ return i[0];
+ }
+ i[1] = *((volatile xdata unsigned char *) PDIUSB_READ_DATA_ADDR);
+ return (((unsigned short) i[1]) << 8) + i[0];
+ }
+ #endif
+
+ #else // serial interface iic
+ #ifndef D11_REG_CMD
+ #define D11_REG_CMD PDIUSB_COMMAND_ADDR
+ #endif
+ #ifndef D11_REG_DATA_WRITE
+ #define D11_REG_DATA_WRITE PDIUSB_WRITE_DATA_ADDR
+ #endif
+ #ifndef D11_REG_DATA_READ
+ #define D11_REG_DATA_READ PDIUSB_READ_DATA_ADDR
+ #endif
+
+ void pdiSendCommand( unsigned char byCmd) {
+ I2C_Write( D11_REG_CMD, &byCmd, 1);
+ }
+ unsigned char pdiReadData( unsigned char byCount, void *pbyData) {
+ I2C_Read( D11_REG_DATA_READ, pbyData, byCount);
+ return byCount;
+ }
+ void pdiWriteData( unsigned char byCount, const void *pbyData) {
+ I2C_Write( D11_REG_DATA_WRITE, pbyData, byCount);
+ }
+ #if defined(PDI_USE_USING)
+ unsigned short pdiIntCmdReadData( unsigned char byCmd, unsigned char byShort) _PDI_USING {
+ }
+ #endif
+
+ #endif
+ #endif
+
+
+/*********************************************************/
+/*********************************************************/
+// PDIUSB common commands
+
+#if defined(PDIUSBH11) || defined(PDIUSBH11A) || defined(PDIUSBD11)
+
+ /*********************************************************/
+ // pdiSetHUBAddressEnable
+ // enable HUB function and set address (byAddress is 0-0x7F, byEnable is 0 or 1)
+ void pdiSetHUBAddressEnable( unsigned char byAddress, unsigned char byEnable) {
+// usb_debug_print( DEBUG_LEVEL_HIGH, ("H "));
+ byAddress = (byAddress & 0x7F) | (byEnable << 7);
+ pdiSendCommand( PDI_CMD_HUB_ENB_ADDR);
+ pdiWriteData( 1, &byAddress);
+ }
+
+#endif
+#if !defined(PDIUSBH11A_MULTPLE) // D11,D12,H11,H11A_S(emb.fnc)
+
+ /*********************************************************/
+ // pdiSetAddressEnable
+ // Enable function and set address (byAddress is 0-0x7F, byEnable is 0 or 1)
+ void pdiSetAddressEnable( unsigned char byAddr_Enb) {
+// usb_debug_print( DEBUG_LEVEL_HIGH, ("A "));
+ pdiSendCommand( PDI_CMD_FNC_ENB_ADDR);
+ pdiWriteData( 1, &byAddr_Enb);
+ }
+
+#else
+
+ /*********************************************************/
+ // pdiSetEmbFncAddressEnable
+ // Enable Embedded function and set address (byAddress is 0-0x7F, byEnable is 0 or 1)
+ // byFnc - function index (zero based) 0-3
+ void pdiSetEmbFncAddressEnable( unsigned char byFnc, unsigned char byAddress, unsigned char byEnable) {
+ byAddress = (byAddress & 0x7F) | (byEnable << 7);
+ pdiSendCommand( PDI_CMD_FNC1_ENB_ADDR + byFnc);
+ pdiWriteData( 1, &byAddress);
+ }
+
+#endif
+
+
+
+ /*********************************************************/
+ // pdiSetEndpointEnable
+ // enable/disable endpoints (PDI_EPEN_xxx)
+ void pdiSetEndpointEnable( unsigned char byEnable) {
+// usb_debug_print( DEBUG_LEVEL_HIGH, ("E "));
+ pdiSendCommand( PDI_CMD_EPEN);
+ pdiWriteData( 1, &byEnable);
+ }
+
+
+#if !defined(PDIUSBH11) // H11 has not it
+
+ /*********************************************************/
+ // pdiSetMode
+ // set chip mode (PDI_MODE_xxx) and clock division factor (PDI_CLOCK_xxx)
+ void pdiSetMode( unsigned short wMode_Clock) {
+ unsigned char sm[2];
+// usb_debug_print( DEBUG_LEVEL_HIGH, ("M%04X ",wMode_Clock));
+ sm[0] = (unsigned char) (wMode_Clock & 0xff);
+ sm[1] = (unsigned char) (wMode_Clock >> 8);
+ pdiSendCommand( PDI_CMD_SET_MODE);
+ pdiWriteData( 2, sm);
+ }
+
+#endif
+
+ #if defined(PDIUSBD12)
+
+ /*********************************************************/
+ // pdiSetDMA
+ // set DMA mode (PDI_DMA_xxx)
+ void pdiSetDMA( unsigned char byDma) {
+ pdiSendCommand( PDI_CMD_SET_DMA);
+ pdiWriteData( 1, &byDma);
+ }
+
+ /*********************************************************/
+ // pdiGetDMA
+ // get current DMA mode
+ unsigned char pdiGetDMA( void) {
+ unsigned char dma;
+ pdiSendCommand( PDI_CMD_GET_DMA);
+ pdiReadData( 1, &dma);
+ return dma;
+ }
+
+ #endif
+
+
+ #if defined(PDIUSBH11)
+
+ /*********************************************************/
+
+ // pdiGetInterrupt - H11 return only one byte
+ // get interrupt register (PDI_INT_xxx)
+ unsigned char pdiGetInterrupt( void) _PDI_USING {
+ unsigned char gin;
+#if defined(PDI_USE_USING)
+ return pdiIntCmdReadData( PDI_CMD_GET_INT_REG, 0);
+#else
+ pdiSendCommand( PDI_CMD_GET_INT_REG);
+ pdiReadData( 1, &gin);
+ return gin;
+#endif
+ }
+
+ #else
+
+ /*********************************************************/
+ // pdiGetInterrupt
+ // get interrupt register (PDI_INT_xxx)
+ unsigned short pdiGetInterrupt( void) _PDI_USING {
+ unsigned short gin;
+#if defined(PDI_USE_USING)
+ return pdiIntCmdReadData( PDI_CMD_GET_INT_REG, 1);
+#else
+ pdiSendCommand( PDI_CMD_GET_INT_REG);
+ pdiReadData( 2, &gin);
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ gin=bswap_16(gin);
+ #endif
+ return gin; //pdiData[0] + (((unsigned short)pdiData[1])<<8);
+#endif
+ }
+
+ #endif
+
+ /*********************************************************/
+ // pdiSelectEp
+ // set internal buffer pointer to selected endpoint (zero based) (PDI_SELEP_xxx)
+ unsigned char pdiSelectEp( unsigned char byEpIdx) {
+ unsigned char sep;
+// usb_debug_print( DEBUG_LEVEL_HIGH, ("e%1d ",byEpIdx));
+ pdiSendCommand( PDI_CMD_SELECT_EP + byEpIdx);
+ pdiReadData( 1, &sep);
+ return sep;
+ }
+
+ /*********************************************************/
+ // pdiGetLastTransStatus
+ // get Last transaction status (PDI_LTSTAT_xxx and PDI_ERR_xxx)
+ unsigned char pdiGetLastTransStatus( unsigned char byEpIdx) _PDI_USING {
+ unsigned char lts;
+// usb_debug_print( DEBUG_LEVEL_HIGH, ("L "));
+#if defined(PDI_USE_USING)
+ return pdiIntCmdReadData( PDI_CMD_GET_LAST_STAT + byEpIdx, 0);
+#else
+ pdiSendCommand( PDI_CMD_GET_LAST_STAT + byEpIdx);
+ pdiReadData( 1, <s);
+ return lts;
+#endif
+ }
+
+
+ #if defined(PDIUSBD11) || defined(PDIUSBH11) || defined(PDIUSBH11A)
+
+ /*********************************************************/
+ // pdiGetEpStatus
+ // get Endpoint Status (PDI_EPSTAT_xxx)
+ unsigned char pdiGetEpStatus( unsigned char byEpIdx) {
+ unsigned char ges;
+// usb_debug_print( DEBUG_LEVEL_HIGH, ("G "));
+ pdiSendCommand( PDI_CMD_GET_EP_STAT + byEpIdx);
+ pdiReadData( 1, &ges);
+ return ges;
+ }
+
+ #endif
+
+ /*********************************************************/
+ // pdiReadFromEpBuffer - raw reading
+ // read data from selected internal chip buffer
+ // if byLength < length of buffer data, so we read only byLength data)
+ unsigned char pdiReadFromEpBuffer( unsigned char byLength, unsigned char *pToBuff) {
+ unsigned char rdep[2];
+// usb_debug_print( DEBUG_LEVEL_HIGH, ("R "));
+ pdiSendCommand( PDI_CMD_READ_BUFFER);
+ pdiReadData( 2, rdep);
+ if ( rdep[1]) { // there is some data
+ if ( byLength < rdep[1]) // we need less data then is received
+ rdep[1] = byLength;
+ pdiReadData( rdep[1], pToBuff);
+ }
+ return rdep[1];
+ }
+
+ /*********************************************************/
+ // pdiWriteToEpBuffer - raw writing
+ // write data to selected internal chip buffer
+ void pdiWriteToEpBuffer( unsigned char byLength, const unsigned char *pFromBuff) {
+ unsigned char hd[2];
+// usb_debug_print( DEBUG_LEVEL_HIGH, ("W "));
+ pdiSendCommand( PDI_CMD_WRITE_BUFFER);
+ hd[0] = 0; hd[1] = byLength;
+ pdiWriteData( 2, hd);
+ if ( byLength) {
+ pdiWriteData( byLength, pFromBuff);
+ }
+ }
+
+ /*********************************************************/
+ // pdiSetEpStatus
+ // set endpoint stall flag
+ void pdiSetEpStatus( unsigned char byEpIdx, unsigned char byStatus) {
+// usb_debug_print( DEBUG_LEVEL_HIGH, ("T "));
+ pdiSendCommand( PDI_CMD_SET_EP_STAT + byEpIdx);
+ pdiWriteData( 1, &byStatus);
+ }
+
+ /*********************************************************/
+ // pdiAcknowledgeSetup
+ // chip disable fncs Validate and Clear after SETUP packet,
+ // this cmd re-enable these fncs
+ void pdiAcknowledgeSetup( void) {
+// usb_debug_print( DEBUG_LEVEL_HIGH, ("C "));
+ pdiSendCommand( PDI_CMD_ACK_SETUP);
+ }
+
+ /*********************************************************/
+ // pdiClearBuffer
+ // set endpoint flag 'empty' and next data can be receive
+ void pdiClearBuffer( void) {
+// usb_debug_print( DEBUG_LEVEL_HIGH, ("B "));
+ pdiSendCommand( PDI_CMD_CLEAR_BUFFER);
+ }
+
+
+ /*********************************************************/
+ // pdiValidateBuffer
+ // set endpoint flag 'full' and data can be send
+ void pdiValidateBuffer( void) {
+// usb_debug_print( DEBUG_LEVEL_HIGH, ("V "));
+ pdiSendCommand( PDI_CMD_VALID_BUFFER);
+ }
+
+ /*********************************************************/
+ // pdiSendResume
+ // send an upstream resume signal for 10ms
+ void pdiSendResume( void) {
+// usb_debug_print( DEBUG_LEVEL_HIGH, ("M "));
+ pdiSendCommand( PDI_CMD_SEND_RESUME);
+ }
+
+ /*********************************************************/
+ // pdiGetFrameNumber
+ // return frame number of last successfully received SOF
+ unsigned short pdiGetFrameNumber( void) {
+ unsigned short gfn;
+ pdiSendCommand( PDI_CMD_GET_FRAME);
+ pdiReadData( 2, &gfn);
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ gfn=bswap_16(gfn);
+ #endif
+ return gfn; //pdiData[0] + (((unsigned short)pdiData[1])<<8);
+ }
+
+ /*********************************************************/
+ // pdiGetChipID - this function is undocumented
+ // read chip ID (not documented function) ( LSB is maybe type of chip in hex (0x12,0x11))
+ unsigned short pdiGetChipID( void) {
+ unsigned short gid;
+ pdiSendCommand( PDI_CMD_GET_CHIP_ID);
+ pdiReadData( 2, &gid);
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ gid=bswap_16(gid);
+ #endif
+ return gid; //pdiData[0] + (((unsigned short)pdiData[1])<<8);
+ }
+
+
+ /*********************************************************/
+ /*********************************************************/
+ // HUB command
+#if defined(PDIUSBH11) || defined(PDIUSBH11A)
+ /*********************************************************/
+ // pdiClearPortFeature
+ // clear feature 'byFeature' in downstream port 2-5 'byEpIdx' (zero based)
+ void pdiClearPortFeature( unsigned char byEpIdx, unsigned char byFeature) {
+ pdiSendCommand( PDI_CMD_P2_CLR_FEATURE + byEpIdx);
+ pdiWriteData( 1, &byFeature);
+ }
+
+ /*********************************************************/
+ // pdiSetPortFeature
+ // set feature 'byFeature' in downstream port 2-5 'byEpIdx' (zero based)
+ void pdiSetPortFeature( unsigned char byEpIdx, unsigned char byFeature) {
+ pdiSendCommand( PDI_CMD_P2_SET_FEATURE + byEpIdx);
+ pdiWriteData( 1, &byFeature);
+ }
+
+ /*********************************************************/
+ // pdiGetPortFeature
+ // get port status (port status byte and port status change byte)
+ unsigned short pdiGetPortFeature( unsigned char byEpIdx) {
+ unsigned short gpf;
+ pdiSendCommand( PDI_CMD_P2_GET_STATUS + byEpIdx);
+ pdiReadData( 2, &gpf);
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ gpf=bswap_16(gpf);
+ #endif
+ return gpf; //pdiData[0] + (((unsigned short)pdiData[1])<<8);
+ }
+
+ /*********************************************************/
+ // pdiSetStatusChangeBits
+ // set local power change bits status
+ void pdiSetStatusChangeBits( unsigned char byBits) {
+ pdiSendCommand( PDI_CMD_SET_CHNG_BITS);
+ pdiWriteData( 1, &byBits);
+ }
+
+#endif
+
+
+
+/*********************************************************/
+/*********************************************************/
+// PDIUSB other commands
+
+ // complex function for select endpoint, write data and validate data in endpoint buffer
+ void pdiWriteEndpoint( unsigned char byEpIdx, unsigned char byLength, const unsigned char *pbyData) {
+ pdiSelectEp( byEpIdx);
+ pdiWriteToEpBuffer( byLength, pbyData);
+ pdiValidateBuffer();
+ }
+
+ // complex function for select endpoint, read data and clear endpoint buffer
+ // byMaxLength means how many bytes will be maximally read.
+ unsigned char pdiReadEndpoint( unsigned char byEpIdx, unsigned char byMaxLength, unsigned char *pbyData) {
+ unsigned char cnt = 0, sep;
+ sep = pdiSelectEp( byEpIdx);
+ if ( sep & PDI_SELEP_FULL) {
+ cnt = pdiReadFromEpBuffer( byMaxLength, pbyData);
+ pdiClearBuffer();
+ }
+ return cnt;
+ }
+
+ // complex universal function for select command and read/write data to/from PDIUSB
+ unsigned char pdiCmdData( unsigned char byCmd, unsigned char *pbyData,
+ unsigned char byCount, unsigned char byRead) {
+ pdiSendCommand( byCmd);
+ if ( byCount) {
+ if( byRead) byCount = pdiReadData( byCount, pbyData); // Read Data
+ else pdiWriteData( byCount, pbyData); // Write Data
+ }
+ return byCount;
+ }
+
+#if !defined(PDIUSBH11A_MULTIPLE)
+ // complex function for acknowledge control endpoint
+ void pdiAckSetupControl( void) {
+ pdiSendCommand( PDI_CMD_SELECT_EP + PDI_EP0_RX);
+ pdiSendCommand( PDI_CMD_ACK_SETUP);
+ pdiSendCommand( PDI_CMD_CLEAR_BUFFER);
+ pdiSendCommand( PDI_CMD_SELECT_EP + PDI_EP0_TX);
+ pdiSendCommand( PDI_CMD_ACK_SETUP);
+ }
+#else
+ // complex function for acknowledge control endpoint ( for one emb.fnc. 1,6,7) (zero-based 0,1,2)
+ void pdiAckSetupFncControl( unsigned char Fnc) {
+ unsigned char FncTab[3] = { PDI_F1_EP0_RX, PDI_F6_EP0_RX, PDI_F7_EP0_RX};
+ pdiSendCommand( PDI_CMD_SELECT_EP + FncTab[Fnc]);
+ pdiSendCommand( PDI_CMD_ACK_SETUP);
+ pdiSendCommand( PDI_CMD_CLEAR_BUFFER);
+ pdiSendCommand( PDI_CMD_SELECT_EP + FncTab[Fnc] + 1);
+ pdiSendCommand( PDI_CMD_ACK_SETUP);
+ }
+#endif
+
+#if defined(PDIUSBD12) // parallel interface
+ void pdiInit( void) {
+ pdiSetAddressEnable( PDI_ENAD_ENABLE);
+ pdiSetEndpointEnable( PDI_EPEN_ENABLE);
+ pdiSetDMA( PDI_DMA_EP4_INT | PDI_DMA_EP5_INT);
+ pdiSetMode( PDI_MODE_NO_LAZY_CLOCK | PDI_MODE_CLOCK_RUNNING |
+ PDI_MODE_SOFT_CONNECT | PDI_CLOCK_12M);
+ }
+#endif
+
+#if defined(PDIUSBH11A_SINGLE) // serial interface
+ void pdiInit( void) {
+ pdiSetHUBAddressEnable( 0, 0); // disable HUB
+ pdiSetAddressEnable( PDI_ENAD_ENABLE); // enable emb.function
+ pdiSetEndpointEnable( PDI_EPEN_FNC_ENB);
+ pdiSetMode( PDI_MODE_REMOTE_WAKEUP | PDI_MODE_NO_LAZY_CLOCK | PDI_MODE_CLOCK_RUNNING |
+ PDI_MODE_SOFT_CONNECT | PDI_MODE_SINGLE_FNC | PDI_CLOCK_12M);
+ }
+#endif
+
+/*********************************************************/
+
+ static const unsigned char epin2idx[]={
+ PDI_EP0_IN,
+ PDI_EP1_IN,
+ #if PDI_CNT_EP > 1
+ PDI_EP2_IN,
+ #if PDI_CNT_EP > 2
+ PDI_EP3_IN,
+ #endif
+ #endif
+ };
+
+ static const unsigned char epout2idx[]={
+ PDI_EP0_OUT,
+ PDI_EP1_OUT,
+ #if PDI_CNT_EP > 1
+ PDI_EP2_OUT,
+ #if PDI_CNT_EP > 2
+ PDI_EP3_OUT,
+ #endif
+ #endif
+ };
+
+ // pdiEp2Idx
+ // convert endpoint number to pdi index number
+ unsigned char pdiEp2Idx(unsigned char ep) {
+ if(ep & USB_ENDPOINT_DIRECTION_MASK)
+ return epin2idx[ep & 0xf];
+ else
+ return epout2idx[ep & 0xf];
+ }
+
+ /*********************************************************/
+ /*********************************************************/
--- /dev/null
+/*****************************************************/
+/*** Module : USB PDI - header file ***/
+/*** Author : Roman Bartosinski (C) 28.04.2002 ***/
+/*** Modify : 08.08.2002, 16.04.2003 ***/
+/*****************************************************/
+
+#ifndef _USB_PDI_SUBMODULE_HEADER_FILE_
+ #define _USB_PDI_SUBMODULE_HEADER_FILE_
+
+ #include <usb/usb.h>
+
+// int usb_pdi_init( usb_device_t *udev) REENTRANT_SIGN;
+ int usb_pdi_init( usb_device_t *udev);
+
+ #ifdef USB_PDI_DIRECT_FNC
+ #define USB_PDI_EXPORT_FNC
+
+ #define usb_udev_is_fnc(_M_udev, _M_fnc) (1)
+
+ #define usb_udev_init usb_pdi_init
+ #define usb_udev_set_addr usb_pdi_set_addr
+ #define usb_udev_set_configuration usb_pdi_set_configuration
+ #define usb_udev_connect usb_pdi_connect
+ #define usb_udev_disconnect usb_pdi_disconnect
+ #define usb_udev_ack_setup usb_pdi_ack_setup
+ #define usb_udev_ack_control_setup usb_pdi_ack_control_setup
+ #define usb_udev_check_events usb_pdi_check_events
+
+ #define usb_udev_stall usb_pdi_stall
+ #define usb_udev_unstall usb_pdi_unstall
+ #define usb_udev_read_endpoint usb_pdi_read_endpoint
+ #define usb_udev_write_endpoint usb_pdi_write_endpoint
+
+ #endif /*USB_PDI_DIRECT_FNC*/
+
+ #ifdef USB_PDI_EXPORT_FNC
+
+ int usb_pdi_init( usb_device_t *udev);
+ int usb_pdi_set_addr( usb_device_t *udev, unsigned char addr);
+ int usb_pdi_set_configuration( usb_device_t *udev, unsigned char iCfg);
+ int usb_pdi_connect( usb_device_t *udev);
+ int usb_pdi_disconnect( usb_device_t *udev);
+ void usb_pdi_ack_setup( usb_device_t *udev);
+ void usb_pdi_ack_control_setup( usb_device_t *udev);
+ int usb_pdi_check_events( usb_device_t *udev);
+
+ void usb_pdi_stall( usb_ep_t *ep);
+ void usb_pdi_unstall( usb_ep_t *ep);
+ int usb_pdi_read_endpoint( usb_ep_t *ep, void *ptr, int size) USB_UDEV_REENTRANT_SIGN;
+ int usb_pdi_write_endpoint( usb_ep_t *ep, const void *ptr, int size) USB_UDEV_REENTRANT_SIGN;
+
+ #endif /*USB_PDI_EXPORT_FNC*/
+
+#endif /* _USB_PDI_SUBMODULE_HEADER_FILE_ */
+
--- /dev/null
+/*********************************************************/
+/*** Module : PDIUSB D11,H11,H11A,D12 - header file ***/
+/*** Author : Roman Bartosinski (C) 03.10.2002 ***/
+/*** Description : Integrate common functions for ***/
+/*** PDIUSBD11,PDIUSBD12,PDIUSBH11(old) ***/
+/*** PDIUSBH11A in Single/Multiple mode ***/
+/*** to one common file. ***/
+/*** Modify : 10.10.2002 - add H11 ***/
+/*** 13.10.2002 - add spec.fnc for 'using' ***/
+/*** 22.12.2002 - rebuild for smaller out ***/
+/*********************************************************/
+
+#ifndef _PDIUSB_BASE_MODULE
+ #define _PDIUSB_BASE_MODULE
+
+/*********************************************************/
+// Comments - !!! Please, read this section !!!
+//
+//
+// If you can use included functions for read and write
+// byte from/to PDIUSB, please uncomment defined PDI_CMD_RWD_INTERNAL
+// and check defined addresses for communication with PDIUSB.
+// Else you must uncomment defined PDI_CMD_RWD_EXTERNAL and declare
+// and implement next functions :
+// void pdiSendCommand( unsigned char byCmd);
+// unsigned char pdiReadData( unsigned char byCount, void *pbyData);
+// void pdiWriteData( unsigned char byCount, const void *pbyData);
+// - if you want use 'using' (see below), you must implement next function(on i51 is NEEDED).
+// unsigned short pdiIntCmdReadData( unsigned char byCmd, unsigned char byShort) _PDI_USING;
+// -- all in section 'External functions'
+//
+//
+// Next you must select type of chip.(uncomment line with defined type)
+// -- in section 'Type of PDIUSB'
+//
+//
+// If you want use functions 'pdiGetInterrupt' and 'pdiGetLastTransStatus'
+// with keyword 'using' (for i51 it means using spec.reg.bank), uncomment
+// define 'USING'. Only these two functions need pdiIntCmdReadData.
+// -- in section 'Use using in interrupt functions'
+//
+// *** External choice ***
+// Or you can make all previous choises externally before including this file
+// by defining one of PDIUSBD11,PDIUSBD12,PDIUSBH11,PDIUSBH11A_SINGLE,PDIUSBH11A_MULTIPLE
+//
+// defining one of PDI_CMD_RWD_INTERNAL,PDI_CMD_RWD_EXTERNAL
+// (you can define externally PDIUSB_COMMAND_ADDR, PDIUSB_READ_DATA_ADDR, PDIUSB_WRITE_DATA_ADDR)
+//
+// and defining one of PDI_USE_USING,PDI_DONTUSE_USING
+// (you can define externally _PDI_USING_NUMBER)
+
+
+
+/*********************************************************/
+// Type of PDIUSB
+
+
+//
+// PDIUSBD11 - USB device with serial interface
+// PDIUSBH11 - USB hub with one embedded fnc and serial interface
+// PDIUSBH11A_SINGLE - USB hub with one embedded fnc, serial interface and additional functions
+// PDIUSBH11A_MULTIPLE - USB hub with multiple(3) embedded fncs, serial interface and add.fncs
+// - H11A_SINGLE and H11A_MULTIPLE is divided by pdiusb command SetMode (bit is set automatically)
+// PDIUSBD12 - USB device with parallel interface
+//
+
+// uncomment right chip type below
+
+#define PDIUSBD11
+//#define PDIUSBH11
+//#define PDIUSBH11A_SINGLE
+//#define PDIUSBH11A_MULTIPLE
+//#define PDIUSBD12
+
+
+/*********************************************************/
+// Create common type PDIUSBH11A for SINGLE and MULTIPLE
+// for mux H11A_S & H11A_M
+#if defined(PDIUSBH11A_SINGLE) || defined(PDIUSBH11A_MULTIPLE)
+ #define PDIUSBH11A
+#else
+ #undef PDIUSBH11A
+#endif
+
+
+
+/*********************************************************/
+// Use using in interrupt functions
+
+ // If you want use keyword 'using' in function
+ // 'pdiGetInterrupt' and 'pdiGetLastTransStatus',
+ // uncomment next line.(and check and correct number in _PDI_USING_NUMBER)
+//#define PDI_USE_USING
+ // If you don't want use keyword 'using',
+ // uncomment next line.
+#define PDI_DONTUSE_USING
+
+ #if defined(PDI_USE_USING)
+ #if !defined(_PDI_USING_NUMBER)
+ #define _PDI_USING_NUMBER 2
+ #endif
+ #define _PDI_USING using _PDI_USING_NUMBER
+ #else
+ #define _PDI_USING
+ #endif
+
+
+/*********************************************************/
+// External functions
+
+ // If you want use internal functions, uncomment next line.
+//#define PDI_CMD_RWD_INTERNAL
+ // If you want use your own external functions, uncomment next line.
+//#define PDI_CMD_RWD_EXTERNAL
+
+// this is automatically selected by your choice
+
+ #if defined(PDI_CMD_RWD_INTERNAL)
+ #if !defined(PDIUSB_COMMAND_ADDR) // if not defined address for select command
+ #if defined(PDIUSBD12)
+ #define PDIUSB_COMMAND_ADDR 0x7001 // sel.cmd address for D12 (this is address for my application)
+ #else
+ #define PDIUSB_COMMAND_ADDR 0x36 // sel.cmd address for all other
+ #endif
+ #endif
+ #if !defined(PDIUSB_READ_DATA_ADDR) // if not defined address for read data from chip
+ #if defined(PDIUSBD12)
+ #define PDIUSB_READ_DATA_ADDR 0x7000 // read data address for D12
+ #else
+ #define PDIUSB_READ_DATA_ADDR 0x35 // read data address for all other
+ #endif
+ #endif
+ #if !defined(PDIUSB_WRITE_DATA_ADDR) // if not defined address for write data to chip
+ #if defined(PDIUSBD12)
+ #define PDIUSB_WRITE_DATA_ADDR 0x7000 // write data address for D12
+ #else
+ #define PDIUSB_WRITE_DATA_ADDR 0x34 // write data address for all other
+ #endif
+ #endif
+
+ #endif
+
+/* Build internal version of functions, but do not define addresses */
+#define PDI_CMD_RWD_INTERNAL
+
+ extern void pdiSendCommand( unsigned char byCmd);
+ extern unsigned char pdiReadData( unsigned char byCount, void *pbyData);
+ extern void pdiWriteData( unsigned char byCount, const void *pbyData);
+#if defined(PDI_USE_USING)
+ extern unsigned short pdiIntCmdReadData( unsigned char byCmd, unsigned char byShort) _PDI_USING;
+#endif
+
+
+/*********************************************************/
+// Check chip selection, int/ext rw functions, using
+
+#if !defined(PDIUSBD11) && !defined(PDIUSBH11) && !defined(PDIUSBH11A) && !defined(PDIUSBD12)
+ #define _PDI_ERROR_NO_CONTINUE
+ #error "!!! Any type of PDIUSB wasn't selected !!!"
+ #error "Please select one of PDIUSB in file pdiusb.h in section 'Type of PDIUSB'."
+#endif
+#if !defined(PDI_CMD_RWD_INTERNAL) && !defined(PDI_CMD_RWD_EXTERNAL)
+ #define _PDI_ERROR_NO_CONTINUE
+ #error "!!! You must select if you want use internal or external basic fncs for PDIUSB !!!"
+ #error "Please select your choice in file pdiusb.h in section 'External functions'."
+#endif
+#if !defined(PDI_USE_USING) && !defined(PDI_DONTUSE_USING)
+ #define _PDI_ERROR_NO_CONTINUE
+ #error "!!! You must choose if you want keyword 'using' !!!"
+ #error "Please see into file pdiusb.h in section 'Use using in interrupt functions'."
+#endif
+
+#if defined(_PDI_ERROR_NO_CONTINUE)
+ #error " For help ... read in file pdiusb.h section 'Comments'."
+#endif
+
+
+/*********************************************************/
+/*********************************************************/
+#if !defined(_PDI_ERROR_NO_CONTINUE)
+
+/*********************************************************/
+// Endpoints - size and index defines
+
+ // PDI_CNT_EP - number of endpoints without control endpoints
+#if defined(PDIUSBD11) || defined(PDIUSBH11A_SINGLE) // D11, H11A_S
+ #define PDI_CNT_EP 0x03
+#elif defined(PDIUSBH11) || defined(PDIUSBH11A_MULTIPLE) // H11, H11A_M
+ #define PDI_CNT_EP 0x01
+#elif defined(PDIUSBD12) // D12
+ #define PDI_CNT_EP 0x02
+#endif
+
+ // PDI_EPx_yyyy_SIZE - max packet size for endpoint x
+#if defined(PDIUSBH11) || defined(PDIUSBH11A) // H11, H11A
+ #define PDI_HUB_TX_SIZE 8
+ #define PDI_HUB_RX_SIZE 8
+ #define PDI_HUB_PACKET_SIZE 8
+ #if defined(PDIUSBH11)
+ #define PDI_HUB_INT_SIZE 1
+ #endif
+#endif
+
+
+#if !defined(PDIUSBD12) // D11,H11,H11A
+ #define PDI_EP0_TX_SIZE 8
+ #define PDI_EP0_RX_SIZE 8
+ #define PDI_EP0_PACKET_SIZE 8
+ #define PDI_EP1_TX_SIZE 8
+ #define PDI_EP1_RX_SIZE 8
+ #define PDI_EP1_PACKET_SIZE 8
+ #if defined(PDIUSBD11) || defined(PDIUSBH11A_SINGLE)
+ #define PDI_EP2_TX_SIZE 8
+ #define PDI_EP2_RX_SIZE 8
+ #define PDI_EP2_PACKET_SIZE 8
+ #define PDI_EP3_TX_SIZE 8
+ #define PDI_EP3_RX_SIZE 8
+ #define PDI_EP3_PACKET_SIZE 8
+ #endif
+#else // D12
+ #define PDI_EP0_TX_SIZE 16
+ #define PDI_EP0_RX_SIZE 16
+ #define PDI_EP0_PACKET_SIZE 16
+ #define PDI_EP1_TX_SIZE 16
+ #define PDI_EP1_RX_SIZE 16
+ #define PDI_EP1_PACKET_SIZE 16
+ #define PDI_EP2_TX_SIZE 64
+ #define PDI_EP2_RX_SIZE 64
+ #define PDI_EP2_PACKET_SIZE 64
+#endif
+
+ // PDI_EPx_TX, PDI_EPx_RX - index for endpoint x (write/read)
+#if defined(PDIUSBH11) || defined(PDIUSBH11A) // H11
+ #define PDI_HUB_EP0_RX 0
+ #define PDI_HUB_EP0_TX 1
+ // another index names
+ #define PDI_HUB_EP0_OUT PDI_HUB_EP0_RX
+ #define PDI_HUB_EP0_IN PDI_HUB_EP0_TX
+#endif
+
+#if defined(PDIUSBH11)
+ #define PDI_EP0_RX 2
+ #define PDI_EP0_TX 3
+ #define PDI_EP1_TX 4
+ // another index names
+ #define PDI_EP0_OUT PDI_EP0_RX
+ #define PDI_EP0_IN PDI_EP0_TX
+ #define PDI_EP1_IN PDI_EP1_TX
+#elif defined(PDIUSBD11) || defined(PDIUSBH11A_SINGLE) // D11,H11A_S
+ #define PDI_EP0_RX 2
+ #define PDI_EP0_TX 3
+ #define PDI_EP1_RX 5
+ #define PDI_EP1_TX 4
+ #define PDI_EP2_RX 6
+ #define PDI_EP2_TX 7
+ #define PDI_EP3_RX 8
+ #define PDI_EP3_TX 9
+ // another index names
+ #define PDI_EP0_OUT PDI_EP0_RX
+ #define PDI_EP0_IN PDI_EP0_TX
+ #define PDI_EP1_OUT PDI_EP1_RX
+ #define PDI_EP1_IN PDI_EP1_TX
+ #define PDI_EP2_OUT PDI_EP2_RX
+ #define PDI_EP2_IN PDI_EP2_TX
+ #define PDI_EP3_OUT PDI_EP3_RX
+ #define PDI_EP3_IN PDI_EP3_TX
+#elif defined(PDIUSBH11A_MULTIPLE) // H11_M
+ #define PDI_F1_EP0_RX 2
+ #define PDI_F1_EP0_TX 3
+ #define PDI_F1_EP1_RX 5
+ #define PDI_F1_EP1_TX 4
+ #define PDI_F6_EP0_RX 10
+ #define PDI_F6_EP0_TX 11
+ #define PDI_F6_EP1_RX 6
+ #define PDI_F6_EP1_TX 7
+ #define PDI_F7_EP0_RX 12
+ #define PDI_F7_EP0_TX 13
+ #define PDI_F7_EP1_RX 8
+ #define PDI_F7_EP1_TX 9
+ // another index names
+ #define PDI_F1_EP0_OUT PDI_F1_EP0_RX
+ #define PDI_F1_EP0_IN PDI_F1_EP0_TX
+ #define PDI_F1_EP1_OUT PDI_F1_EP1_RX
+ #define PDI_F1_EP1_IN PDI_F1_EP1_TX
+ #define PDI_F6_EP0_OUT PDI_F6_EP0_RX
+ #define PDI_F6_EP0_IN PDI_F6_EP0_TX
+ #define PDI_F6_EP1_OUT PDI_F6_EP1_RX
+ #define PDI_F6_EP1_IN PDI_F6_EP1_TX
+ #define PDI_F7_EP0_OUT PDI_F7_EP0_RX
+ #define PDI_F7_EP0_IN PDI_F7_EP0_TX
+ #define PDI_F7_EP1_OUT PDI_F7_EP1_RX
+ #define PDI_F7_EP1_IN PDI_F7_EP1_TX
+#elif defined(PDIUSBD12) // D12
+ #define PDI_EP0_RX 0
+ #define PDI_EP0_TX 1
+ #define PDI_EP1_RX 2
+ #define PDI_EP1_TX 3
+ #define PDI_EP2_RX 4
+ #define PDI_EP2_TX 5
+ // another index names
+ #define PDI_EP0_OUT PDI_EP0_RX
+ #define PDI_EP0_IN PDI_EP0_TX
+ #define PDI_EP1_OUT PDI_EP1_RX
+ #define PDI_EP1_IN PDI_EP1_TX
+ #define PDI_EP2_OUT PDI_EP2_RX
+ #define PDI_EP2_IN PDI_EP2_TX
+#endif
+
+/*********************************************************/
+// Commands - index and bits, description
+
+ // Set Address/Enable
+#if defined(PDIUSBH11) || defined(PDIUSBH11A) || defined(PDIUSBD11) // only H11 or H11A
+ #define PDI_CMD_HUB_ENB_ADDR 0x00D0
+ #if defined(PDIUSBH11) || defined(PDIUSBH11A_SINGLE) // for H11 and H11A_SINGLE
+ #define PDI_CMD_FNC_ENB_ADDR 0x00D1
+ #else // for H11A_MULTIPLE
+ #define PDI_CMD_FNC1_ENB_ADDR 0x00D1
+ #define PDI_CMD_FNC6_ENB_ADDR 0x00D2
+ #define PDI_CMD_FNC7_ENB_ADDR 0x00D3
+// for compatible with H11A_SINGLE and other
+ #define PDI_CMD_FNC_ENB_ADDR PDI_CMD_FNC1_ENB_ADDR
+ #endif
+#elif defined(PDIUSBD11) // for D11
+ #define PDI_CMD_FNC_ENB_ADDR 0x00D1
+#elif defined(PDIUSBD12) // for D12
+ #define PDI_CMD_FNC_ENB_ADDR 0x00D0
+#endif
+ // set address/enable bits - for all
+ #define PDI_ENAD_ENABLE 0x0080
+ #define PDI_ENAD_ADDRMASK 0x007F
+
+ // Set Endpoint enable
+ #define PDI_CMD_EPEN 0x00D8
+ // set endpoint enable bits
+ #if defined(PDIUSBD12) // D12 - generic ep
+ #define PDI_EPEN_ENABLE 0x0001
+ #elif defined(PDIUSBD11) // D11 - generic ep
+ #define PDI_EPEN_ENABLE 0x0002
+ #elif defined(PDIUSBH11A) || defined(PDIUSBH11) // H11,H11A
+ #define PDI_EPEN_HUB_ENB 0x0001
+ #if defined(PDIUSBH11A_MULTIPLE) // H11A_M
+ #define PDI_EPEN_FNC1_ENB 0x0002
+ #define PDI_EPEN_FNC6_ENB 0x0004
+ #define PDI_EPEN_FNC7_ENB 0x0008
+ #else // H11,H11A_S
+ #define PDI_EPEN_FNC_ENB 0x0002
+ #endif
+ #endif
+
+ #if !defined(PDIUSBH11)
+ // Set Mode
+ #define PDI_CMD_SET_MODE 0x00F3
+ // set mode bits - configuration
+ #if !defined(PDIUSBD12)
+ #define PDI_MODE_REMOTE_WAKEUP 0x0001 // D11,H11A
+ #endif
+ #define PDI_MODE_NO_LAZY_CLOCK 0x0002 // all
+ #define PDI_MODE_CLOCK_RUNNING 0x0004 // all
+ #if defined(PDIUSBD12)
+ #define PDI_MODE_INTERRUPT_MODE 0x0008 // D12
+ #else
+ #define PDI_MODE_DEBUG_MODE 0x0008 // D11,H11A
+ #endif
+ #define PDI_MODE_SOFT_CONNECT 0x0010 // all
+ #if defined(PDIUSBH11A)
+ #define PDI_MODE_DWN_RESISTORS 0x0020 // H11A
+ #define PDI_MODE_NONBLINK_LED 0x0040 // H11A
+ #define PDI_MODE_SINGLE_FNC 0x0080 // H11A
+ #elif defined(PDIUSBD11)
+ #define PDI_MODE_MUSTBEONE 0x0080 // D11
+ #else
+ #define PDI_MODE_EP_NONISO 0x0000 // D12
+ #define PDI_MODE_EP_ISOOUT 0x0040
+ #define PDI_MODE_EP_ISOIN 0x0080
+ #define PDI_MODE_EP_ISOIO 0x00C0
+
+ #endif
+ // set mode bits - clock div factor [48Mhz/(N+1)]
+ #if defined(PDIUSBH11A)
+ #define PDI_CLOCK_CRYSTAL_12M 0x3000 // for 12Mhz crystal
+ #define PDI_CLOCK_CRYSTAL_48M 0x0000 // for 48Mhz crystal
+ #endif
+ #if defined(PDIUSBD12) // D12
+ #define PDI_CLOCK_48M 0x0000 // 48 Mhz
+ #endif // all
+ #define PDI_CLOCK_24M 0x0100 // 24 Mhz
+ #define PDI_CLOCK_16M 0x0200 // 16 Mhz
+ #define PDI_CLOCK_12M 0x0300 // 12 Mhz
+ #define PDI_CLOCK_9M6 0x0400 // 9.6 Mhz
+ #define PDI_CLOCK_8M 0x0500 // 8 Mhz
+ #define PDI_CLOCK_6M8 0x0600 // 6.857142857 Mhz
+ #define PDI_CLOCK_6M 0x0700 // 6 Mhz
+ #define PDI_CLOCK_5M3 0x0800 // 5.333333333 Mhz
+ #define PDI_CLOCK_4M8 0x0900 // 4.8 Mhz
+ #define PDI_CLOCK_4M3 0x0A00 // 4.363636364 Mhz
+ #define PDI_CLOCK_4M 0x0B00 // 4 Mhz
+ #if defined(PDIUSBD12) // D12
+ #define PDI_CLOCK_SET_TO_ONE 0x4000
+ #define PDI_CLOCK_SOF_ONLY 0x8000
+ #endif
+ #endif
+
+ // Set DMA
+ #if defined(PDIUSBD12)
+ #define PDI_CMD_SET_DMA 0x00FB
+ #define PDI_CMD_GET_DMA 0x00FB
+ // set dma bits
+ #define PDI_DMA_SINGLE_DMA 0x0000
+ #define PDI_DMA_BURST_4 0x0001
+ #define PDI_DMA_BURST_8 0x0002
+ #define PDI_DMA_BURST_16 0x0003
+ #define PDI_DMA_ENABLE 0x0004
+ #define PDI_DMA_DIRECTION 0x0008
+ #define PDI_DMA_AUTOLOAD 0x0010
+ #define PDI_DMA_INT_SOF 0x0020
+ #define PDI_DMA_EP4_INT 0x0040
+ #define PDI_DMA_EP5_INT 0x0080
+ #endif
+
+ // Read Interrupt Register
+ // be careful with PDIUSBH11 - you must read only 1 byte
+ #define PDI_CMD_GET_INT_REG 0x00F4
+ // read interrupt register bits
+ #if defined(PDIUSBD11) || defined(PDIUSBH11) || defined(PDIUSBH11A) // D11,H11,H11A
+ #if defined(PDIUSBH11) || defined(PDIUSBH11A)
+ #define PDI_INT_HUB_OUT 0x0001
+ #define PDI_INT_HUB_IN 0x0002
+ #endif
+ #if defined(PDIUSBH11)
+ #define PDI_INT_EP0_OUT 0x0004
+ #define PDI_INT_EP0_IN 0x0008
+ #define PDI_INT_EP1_IN 0x0010
+ #elif defined(PDIUSBD11) || defined(PDIUSBH11A_SINGLE) // D11,H11_S
+ #define PDI_INT_EP0_OUT 0x0004
+ #define PDI_INT_EP0_IN 0x0008
+ #define PDI_INT_EP1_OUT 0x0020
+ #define PDI_INT_EP1_IN 0x0010
+ #define PDI_INT_EP2_OUT 0x0040
+ #define PDI_INT_EP2_IN 0x0080
+ #define PDI_INT_EP3_OUT 0x0100
+ #define PDI_INT_EP3_IN 0x0200
+ #else // H11_M
+ #define PDI_INT_F1_EP0_OUT 0x0004
+ #define PDI_INT_F1_EP0_IN 0x0008
+ #define PDI_INT_F1_EP1_OUT 0x0020
+ #define PDI_INT_F1_EP1_IN 0x0010
+ #define PDI_INT_F6_EP0_OUT 0x0400
+ #define PDI_INT_F6_EP0_IN 0x0800
+
+ #define PDI_INT_F6_EP1_OUT 0x0040
+ #define PDI_INT_F6_EP1_IN 0x0080
+ #define PDI_INT_F7_EP0_OUT 0x1000
+ #define PDI_INT_F7_EP0_IN 0x2000
+ #define PDI_INT_F7_EP1_OUT 0x0100
+ #define PDI_INT_F7_EP1_IN 0x0200
+ #endif
+ #define PDI_INT_BUSRESET 0x4000
+ #elif defined(PDIUSBD12)
+ #define PDI_INT_EP0_OUT 0x0001
+ #define PDI_INT_EP0_IN 0x0002
+ #define PDI_INT_EP1_OUT 0x0004
+ #define PDI_INT_EP1_IN 0x0008
+ #define PDI_INT_EP2_OUT 0x0010
+ #define PDI_INT_EP2_IN 0x0020
+ #define PDI_INT_BUSRESET 0x0040
+ #define PDI_INT_SUSPEND 0x0080
+ #define PDI_INT_DMA_EOT 0x0100
+ #endif
+
+ // Select Endpoint
+ #define PDI_CMD_SELECT_EP 0x0000 // base index for select endpoint
+ // select endpoint bits
+ #define PDI_SELEP_FULL 0x0001
+ #if defined(PDIUSBD12)
+ #define PDI_SELEP_STALL 0x0002
+ #endif
+
+ // Read Last Transaction Status Register
+ #define PDI_CMD_GET_LAST_STAT 0x0040 // base index for read last transaction
+ // read last transaction bits and errors
+ #define PDI_LTSTAT_RXTX_OK 0x0001
+ #define PDI_LTSTAT_ERR_MASK 0x001E
+ #define PDI_LTSTAT_SETUP 0x0020
+ #define PDI_LTSTAT_DATA1 0x0040
+ #define PDI_LTSTAT_PREV_NRD 0x0080
+ // error codes
+ #define PDI_ERR_NO_ERROR 0x0000
+ #define PDI_ERR_PID_ENCODING 0x0001
+ #define PDI_ERR_PID_UNKNOWN 0x0002
+ #define PDI_ERR_UNEXPECT_PKT 0x0003
+
+ #define PDI_ERR_TOKEN_CRC 0x0004
+ #define PDI_ERR_DATA_CRC 0x0005
+ #define PDI_ERR_TIME_OUT 0x0006
+ #define PDI_ERR_NEVER_HAPPENS 0x0007
+ #define PDI_ERR_UNEXPECT_EOP 0x0008
+ #define PDI_ERR_NAK 0x0009
+ #define PDI_ERR_STALL 0x000A
+ #define PDI_ERR_OVERFLOW 0x000B
+ #define PDI_ERR_BITSTUFF 0x000D
+ #define PDI_ERR_DATA_PID 0x000F
+
+ // Read Endpoint Status
+ #if defined(PDIUSBD11) || defined(PDIUSBH11) || defined(PDIUSBH11A)
+ #define PDI_CMD_GET_EP_STAT 0x0080 // base index for read ep status
+ // read ep status bits
+ #define PDI_EPSTAT_SETUP 0x0004
+ #define PDI_EPSTAT_STALL 0x0008
+ #define PDI_EPSTAT_DATA1 0x0010
+ #define PDI_EPSTAT_FULL 0x0020
+ #endif
+
+ // Read Buffer
+ #define PDI_CMD_READ_BUFFER 0x00F0
+
+ // Write Buffer
+ #define PDI_CMD_WRITE_BUFFER 0x00F0
+
+ // Clear Buffer
+ #define PDI_CMD_CLEAR_BUFFER 0x00F2
+
+ // Validate Buffer
+ #define PDI_CMD_VALID_BUFFER 0x00FA
+
+
+ // Set Endpoint Status
+ #define PDI_CMD_SET_EP_STAT 0x0040 // base index for endpoint status
+ // set endpoint status bits
+ #define PDI_SET_EP_STALLED 0x0001
+
+ // Acknowledge Setup
+ #define PDI_CMD_ACK_SETUP 0x00F1
+
+ // Send Resume
+ #define PDI_CMD_SEND_RESUME 0x00F6
+
+ // Read Current Frame Number
+ #define PDI_CMD_GET_FRAME 0x00F5
+
+ // Get Chip ID
+ #define PDI_CMD_GET_CHIP_ID 0x00FD
+
+// HUB commands
+#if defined(PDIUSBH11) || defined(PDIUSBH11A)
+ // Clear Port Feature
+ #define PDI_CMD_P2_CLR_FEATURE 0x00E0
+ #define PDI_CMD_P3_CLR_FEATURE 0x00E1
+ #define PDI_CMD_P4_CLR_FEATURE 0x00E2
+ #define PDI_CMD_P5_CLR_FEATURE 0x00E3
+ // Set Port Feature
+ #define PDI_CMD_P2_SET_FEATURE 0x00E8
+ #define PDI_CMD_P3_SET_FEATURE 0x00E9
+ #define PDI_CMD_P4_SET_FEATURE 0x00EA
+ #define PDI_CMD_P5_SET_FEATURE 0x00EB
+ // Feature code
+ #define PDI_F_PORT_ENABLE 0
+ #define PDI_F_PORT_SUSPEND 1
+ #define PDI_FC_PORT_RESET 2
+ #define PDI_F_PORT_POWER 3
+ #define PDI_C_PORT_CONNECTION 4
+ #define PDI_C_PORT_ENABLE 5
+ #define PDI_C_PORT_SUSPEND 6
+ #define PDI_C_PORT_OVERCURRENT 7
+
+ // Get Port Status
+ #define PDI_CMD_P2_GET_STATUS 0x00E0
+ #define PDI_CMD_P3_GET_STATUS 0x00E1
+ #define PDI_CMD_P4_GET_STATUS 0x00E2
+ #define PDI_CMD_P5_GET_STATUS 0x00E3
+ // get port status bits - port status byte
+ #define PDI_PSTAT_CONNECT 0x0001
+ #define PDI_PSTAT_ENABLED 0x0002
+ #define PDI_PSTAT_SUSPEND 0x0004
+ #define PDI_PSTAT_OVERCUR 0x0008
+ #define PDI_PSTAT_RESET 0x0010
+ #define PDI_PSTAT_POWER 0x0020
+ #define PDI_PSTAT_LOWSPEED 0x0040
+ // get port status bits - port status change byte
+ #define PDI_PSTAT_CHANGE_CONNECT 0x0100
+ #define PDI_PSTAT_CHANGE_ENABLED 0x0200
+ #define PDI_PSTAT_CHANGE_SUSPEND 0x0400
+ #define PDI_PSTAT_CHANGE_OVERCUR 0x0800
+ #define PDI_PSTAT_CHANGE_RESET 0x1000
+ // Set Status Change Bits
+ #define PDI_CMD_SET_CHNG_BITS 0x00F7
+ // set status change bits - bits
+ #define PDI_SCHB_LOCAL_POWER 0x0001
+ #define PDI_SCHB_FNC1 0x0002
+ #if !defined(PDIUSBH11) && !defined(PDIUSBH11A_SINGLE)
+ #define PDI_SCHB_FNC6 0x0004
+ #define PDI_SCHB_FNC7 0x0008
+ #endif
+#endif
+
+
+/*********************************************************/
+// Function prototypes
+//
+// PDIUSB common commands
+
+ #if defined(PDIUSBH11) || defined(PDIUSBH11A) || defined(PDIUSBD11)
+ void pdiSetHUBAddressEnable( unsigned char byAddress, unsigned char byEnable);
+ #endif
+
+ #if !defined(PDIUSBH11A_MULTIPLE) // D11,D12,H11,H11A_S(emb.fnc)
+ void pdiSetAddressEnable( unsigned char byAddr_Enb);
+// void pdiSetAddressEnable( unsigned char byAddress, unsigned char byEnable);
+ #else
+ void pdiSetEmbFncAddressEnable( unsigned char byFnc, unsigned char byAddress, unsigned char byEnable);
+ #endif
+
+ void pdiSetEndpointEnable( unsigned char byEnable);
+
+ #if !defined(PDIUSBH11) // H11 has not it ( !!! is great - try give single quote mark into comments ;-)
+ void pdiSetMode( unsigned short wMode_Clock);
+ #endif
+
+ #if defined(PDIUSBD12)
+ void pdiSetDMA( unsigned char byDma);
+ unsigned char pdiGetDMA( void);
+ #endif
+
+ #if defined(PDIUSBH11)
+ unsigned char pdiGetInterrupt( void) _PDI_USING;
+ #else
+ unsigned short pdiGetInterrupt( void) _PDI_USING;
+ #endif
+
+ unsigned char pdiSelectEp( unsigned char byEpIdx);
+ unsigned char pdiGetLastTransStatus( unsigned char byEpIdx) _PDI_USING;
+
+ #if defined(PDIUSBD11) || defined(PDIUSBH11) || defined(PDIUSBH11A)
+ unsigned char pdiGetEpStatus( unsigned char byEpIdx);
+ #endif
+
+ unsigned char pdiReadFromEpBuffer( unsigned char byLength, unsigned char *pToBuff);
+ void pdiWriteToEpBuffer( unsigned char byLength, const unsigned char *pFromBuff);
+ void pdiSetEpStatus( unsigned char byEpIdx, unsigned char byStatus);
+ void pdiAcknowledgeSetup( void);
+ void pdiClearBuffer( void);
+ void pdiValidateBuffer( void);
+
+ void pdiSendResume( void);
+ unsigned short pdiGetFrameNumber( void);
+ unsigned short pdiGetChipID( void); // this function is undocumented
+
+ // HUB command
+ #if defined(PDIUSBH11) || defined(PDIUSBH11A)
+ void pdiClearPortFeature( unsigned char byEpIdx, unsigned char byFeature);
+ void pdiSetPortFeature( unsigned char byEpIdx, unsigned char byFeature);
+ unsigned short pdiGetPortFeature( unsigned char byEpIdx);
+ void pdiSetStatusChangeBits( unsigned char byBits);
+ #endif
+
+// PDIUSB other commands
+ void pdiWriteEndpoint( unsigned char byEpIdx, unsigned char byLength, const unsigned char *pbyData);
+ unsigned char pdiReadEndpoint( unsigned char byEpIdx, unsigned char byMaxLength, unsigned char *pbyData);
+
+ unsigned char pdiCmdData( unsigned char byCmd, unsigned char *pbyData,
+ unsigned char byCount, unsigned char byRead);
+ void pdiInit( void);
+#if !defined(PDIUSBH11A_MULTIPLE)
+ void pdiAckSetupControl( void);
+#else
+ void pdiAckSetupFncControl( unsigned char Fnc);
+#endif
+
+unsigned char pdiEp2Idx(unsigned char ep);
+
+/*********************************************************/
+#endif // from _PDI_ERROR_NO_CONTINUE
+/*********************************************************/
+#endif // from _PDI_BASE_MODULE
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/time.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
+ #include <linux/kref.h>
+#endif
#include <asm/errno.h>
#include <asm/io.h>
#endif /*CAN_WITH_RTL*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4))
+ #include <linux/kthread.h>
+ #define can_kthread_create kthread_create
+ #define can_kthread_run kthread_run
+ #define can_kthread_bind kthread_bind
+ #define can_kthread_stop kthread_stop
+ #define can_kthread_should_stop kthread_should_stop
+#else
+ #define can_kthread_create
+ #define can_kthread_run
+ #define can_kthread_bind
+ #define can_kthread_stop
+ #define can_kthread_should_stop
+#endif
+
+
#endif /*_CAN_SYSDEP_H*/
#define CHIP_IRQ_VME (1<<5) /* interrupt is VME bus and requires VME bridge */
#define CHIP_IRQ_CUSTOM (1<<6) /* custom interrupt provided by board or chip code */
#define CHIP_IRQ_FAST (1<<7) /* interrupt handler only schedules postponed processing */
+#define CHIP_KEEP_DATA (1<<8) /* let the hotplug device free its chip_data structure itself */
#define CHIP_MAX_IRQLOOP 1000
struct canhardware_t *hosthardware_p;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
+ struct kref refcount;
+#endif
+
union {
void *anydev;
#ifdef CAN_ENABLE_PCI_SUPPORT
int chip_idx; /* chip index in candevice_t.chip[] */
int chip_irq;
can_ioptr_t chip_base_addr;
- unsigned int flags;
+ uint16_t flags;
long clock; /* Chip clock in Hz */
long baudrate;
int (*program_irq)(struct candevice_t *candev);
void (*write_register)(unsigned data, can_ioptr_t address);
unsigned (*read_register)(can_ioptr_t address);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
+ void (*release_device)(struct kref *refcount);
+#endif
+
};
/**
#if defined(CONFIG_OC_LINCAN_PORTIO_ONLY)
-extern inline void can_write_reg(const struct canchip_t *chip, unsigned char data, unsigned reg_offs)
+extern inline void can_write_reg(const struct canchip_t *chip, unsigned data, unsigned reg_offs)
{
can_outb(data, chip->chip_base_addr+reg_offs);
}
return can_inb(chip->chip_base_addr+reg_offs);
}
extern inline void canobj_write_reg(const struct canchip_t *chip, const struct msgobj_t *obj,
- unsigned char data, unsigned reg_offs)
+ unsigned data, unsigned reg_offs)
{
can_outb(data, obj->obj_base_addr+reg_offs);
}
}
#elif defined(CONFIG_OC_LINCAN_MEMIO_ONLY)
-extern inline void can_write_reg(const struct canchip_t *chip, unsigned char data, unsigned reg_offs)
+extern inline void can_write_reg(const struct canchip_t *chip, unsigned data, unsigned reg_offs)
{
can_writeb(data, chip->chip_base_addr+reg_offs);
}
return can_readb(chip->chip_base_addr+reg_offs);
}
extern inline void canobj_write_reg(const struct canchip_t *chip, const struct msgobj_t *obj,
- unsigned char data, unsigned reg_offs)
+ unsigned data, unsigned reg_offs)
{
can_writeb(data, obj->obj_base_addr+reg_offs);
}
/* Inline function to write to the hardware registers. The argument reg_offs is
* relative to the memory map of the chip and not the absolute memory reg_offs.
*/
-extern inline void can_write_reg(const struct canchip_t *chip, unsigned char data, unsigned reg_offs)
+extern inline void can_write_reg(const struct canchip_t *chip, unsigned data, unsigned reg_offs)
{
can_ioptr_t address_to_write;
address_to_write = chip->chip_base_addr+reg_offs;
}
extern inline void canobj_write_reg(const struct canchip_t *chip, const struct msgobj_t *obj,
- unsigned char data, unsigned reg_offs)
+ unsigned data, unsigned reg_offs)
{
can_ioptr_t address_to_write;
address_to_write = obj->obj_base_addr+reg_offs;
#ifdef CAN_WITH_RTL
extern int can_rtl_priority;
#endif /*CAN_WITH_RTL*/
+
+extern struct candevice_t* register_hotplug_dev(const char *hwname,int (*chipdataregfnc)(struct canchip_t *chip,void *data),void *devdata);
+extern void deregister_hotplug_dev(struct candevice_t *dev);
+extern void cleanup_hotplug_dev(struct candevice_t *dev);
#include "./constants.h"
int can_init_procdir(void);
+int can_init_procentry(int board);
int can_delete_procdir(void);
+int can_delete_procentry(struct candevice_t *candev);
struct canproc_t {
struct proc_dir_entry *can_proc_entry;
/**************************************************************************/
int init_hw_struct(void);
+int init_new_hw_struct(int devnr);
int list_hw(void);
void *can_checked_malloc(size_t size);
int can_checked_free(void *address_p);
+/* usbcan.h
+ * Header file for the Linux CAN-bus driver.
+ * Written by Jan Kriz email:johen@post.cz
+ * This software is released under the GPL-License.
+ * Version lincan-0.3 17 Jul 2008
+ */
+
+#ifndef USBCAN_H
+#define USBCAN_H
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/kref.h>
+#include <asm/uaccess.h>
+#include <linux/usb.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+
+#include "../include/kthread.h"
+
+/* our private defines. if this grows any larger, use your own .h file */
+#define MAX_TRANSFER (PAGE_SIZE - 512)
+/* MAX_TRANSFER is chosen so that the VM is not stressed by
+ allocations > PAGE_SIZE and the number of packets in a page
+ is an integer 512 is the largest possible packet on EHCI */
+#define WRITES_IN_FLIGHT 8
+/* arbitrarily chosen */
+
+/* Define these values to match your devices */
+#define USBCAN_VENDOR_ID 0x1669
+#define USBCAN_PRODUCT_ID 0x1011
+
+#define RESET_ADDR 0x0
+
+/*
+ * IO_RANGE is the io-memory range that gets reserved, please adjust according
+ * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
+ * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
+ */
+#define IO_RANGE 0x100
+
+
+int usbcan_request_io(struct candevice_t *candev);
+int usbcan_release_io(struct candevice_t *candev);
+int usbcan_reset(struct candevice_t *candev);
+int usbcan_init_hw_data(struct candevice_t *candev);
+int usbcan_init_chip_data(struct candevice_t *candev, int chipnr);
+int usbcan_init_obj_data(struct canchip_t *chip, int objnr);
+void usbcan_write_register(unsigned data, unsigned long address);
+unsigned usbcan_read_register(unsigned long address);
+int usbcan_program_irq(struct candevice_t *candev);
+int usbcan_register(struct hwspecops_t *hwspecops);
+
+int usbcan_chip_config(struct canchip_t *chip);
+int usbcan_extended_mask(struct canchip_t *chip, unsigned long code, unsigned long mask);
+int usbcan_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
+ int sampl_pt, int flags);
+int usbcan_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj);
+int usbcan_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
+ struct canmsg_t *msg);
+int usbcan_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
+ struct canmsg_t *msg);
+int usbcan_fill_chipspecops(struct canchip_t *chip);
+int usbcan_irq_handler(int irq, struct canchip_t *chip);
+
+int usbcan_init(void);
+void usbcan_exit(void);
+
+int usbcan_kthread(void *data);
+int usbcan_chip_queue_status(struct canchip_t *chip);
+
+#ifdef CONFIG_OC_LINCAN_DETAILED_ERRORS
+
+// static const char *sja1000_ecc_errc_str[]={
+// "bit error",
+// "form error",
+// "stuff error",
+// "other type of error"
+// };
+//
+// static const char *sja1000_ecc_seg_str[]={
+// "?0?",
+// "?1?",
+// "ID.28 to ID.21",
+// "start of frame",
+// "bit SRTR",
+// "bit IDE",
+// "ID.20 to ID.18",
+// "ID.17 to ID.13",
+// "CRC sequence",
+// "reserved bit 0",
+// "data field",
+// "data length code",
+// "bit RTR",
+// "reserved bit 1",
+// "ID.4 to ID.0",
+// "ID.12 to ID.5",
+// "?16?"
+// "active error flag",
+// "intermission",
+// "tolerate dominant bits",
+// "?20?",
+// "?21?",
+// "passive error flag",
+// "error delimiter",
+// "CRC delimiter",
+// "acknowledge slot",
+// "end of frame",
+// "acknowledge delimiter",
+// "overload flag",
+// "?29?",
+// "?30?",
+// "?31?"
+// };
+
+#endif /*CONFIG_OC_LINCAN_DETAILED_ERRORS*/
+
+struct usbcan_usb;
+
+#define USBCAN_TOT_RX_URBS 8
+#define USBCAN_TOT_TX_URBS 8
+
+#define USBCAN_TRANSFER_SIZE 16
+
+struct usbcan_message {
+ struct urb *u;
+ struct usbcan_usb *dev;
+ u8 msg[USBCAN_TRANSFER_SIZE];
+ struct canque_edge_t *qedge;
+ struct canque_slot_t *slot;
+ struct list_head list_node;
+ volatile long flags;
+};
+
+#define USBCAN_MESSAGE_TERMINATE (1)
+#define USBCAN_MESSAGE_ERROR (2)
+#define USBCAN_MESSAGE_DATA_OK (3)
+
+/* Structure to hold all of our device specific stuff */
+struct usbcan_usb {
+ struct usb_device *udev; /* the usb device for this device */
+ struct usb_interface *interface; /* the interface for this device */
+ unsigned char *bulk_in_buffer; /* the buffer to receive data */
+ size_t bulk_in_size; /* the size of the receive buffer */
+ u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
+ u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */
+ struct mutex io_mutex; /* synchronize I/O with disconnect */
+
+ struct list_head rx_pend_list; /* URBs waiting for data receive */
+ struct list_head rx_ready_list; /* URBs with valid received data */
+ struct list_head tx_idle_list; /* URBs prepared to hold Tx messages */
+ struct list_head tx_pend_list; /* URBs holding Tx messages in progress */
+ struct list_head tx_ready_list; /* URBs with yet confirmed Tx messages */
+
+ spinlock_t list_lock; /* list lock */
+
+ struct task_struct *comthread; /* usb communication kernel thread */
+ wait_queue_head_t queue;
+
+ struct canchip_t *chip;
+ volatile long flags;
+};
+
+#define USBCAN_DATA_OK (1)
+#define USBCAN_DATA_RX (2)
+#define USBCAN_DATA_TX (3)
+#define USBCAN_TERMINATE (4)
+#define USBCAN_ERROR (5)
+#define USBCAN_TX_PENDING (6)
+#define USBCAN_THREAD_RUNNING (7)
+#define USBCAN_FREE_TX_URB (8)
+
+#define USBCAN_VENDOR_BAUD_RATE_SET (1)
+#define USBCAN_VENDOR_BAUD_RATE_STATUS (2)
+#define USBCAN_VENDOR_SET_BTREGS (3)
+#define USBCAN_VENDOR_CHECK_TX_STAT (4)
+#define USBCAN_VENDOR_START_CHIP (5)
+#define USBCAN_VENDOR_STOP_CHIP (6)
+#define USBCAN_VENDOR_EXT_MASK_SET (7)
+#define USBCAN_VENDOR_EXT_MASK_STATUS (8)
+
+struct usbcan_devs {
+ struct usbcan_usb **devs;
+ int count;
+ struct candevice_t *candev;
+ struct usb_device *udev;
+};
+
+
+#endif /*USBCAN_H*/
lincan_cards_NAMES = pip pccan smartcan nsi cc_can104 ems_cpcpci \
pc_i03 pcm3680 aim104 m437 pcccan ssv bfadcan gensja1000io gensja1000mm pcisja1000mm eb8245 \
- kv_pcican msmcan oscar adlink7841 pcan_pci esdpci200 unican virtual template
+ kv_pcican msmcan oscar adlink7841 pcan_pci esdpci200 unican usbcan virtual template
lincan_morecards_NAMES = esdpci266 hms30c7202_can ns_dev_can ipci165 pimx1 tscan1 ts7kv nsi_canpci sh7760 mpc5200
endif
ifeq ($(CONFIG_OC_LINCAN_CARD_ipci165),y)
-lincan_cards_SOURCES += ipci165_fw.c kthread.c
+lincan_cards_SOURCES += ipci165_fw.c
+lincan_need_kthread=y
endif
ifeq ($(CONFIG_OC_LINCAN_CARD_sh7760),y)
lincan_cards_SOURCES += sh7760.c
endif
+ifeq ($(CONFIG_OC_LINCAN_CARD_usbcan),y)
+lincan_need_kthread=y
+endif
+
+ifeq ($(lincan_need_kthread),y)
+#lincan_cards_SOURCES += kthread.c
+endif
+
ifneq ($(filter hms30c7202_can ns_dev_can,$(lincan_cards_SELECTED)),)
$(warning Not finished C_CAN support requested)
lincan_cards_SOURCES += c_can.c c_can_irq.c
int can_close(struct inode *inode, struct file *file)
{
struct canuser_t *canuser = (struct canuser_t*)(file->private_data);
+ struct canchip_t *chip;
struct canque_ends_t *qends;
struct msgobj_t *obj;
can_spin_irqflags_t iflags;
CANMSG("can_close: bad canuser magic\n");
return -ENODEV;
}
+ if ((chip=objects_p[MINOR_NR]->hostchip) == NULL) {
+ CANMSG("There is no hardware support for the device file with minor nr.: %d\n",MINOR_NR);
+ return -ENODEV;
+ }
obj = canuser->msgobj;
qends = canuser->qends;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,50))
MOD_DEC_USE_COUNT;
#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
+ if (chip->hostdevice->hwspecops->release_device)
+ kref_put(&chip->hostdevice->refcount,chip->hostdevice->hwspecops->release_device);
+#endif
return 0;
}
#include "../include/finish.h"
#include "../include/setup.h"
-
+extern int next_minor;
/**
* msgobj_done - destroys one CAN message object
* @obj: pointer to CAN message object structure
}
if((obj->minor>=0)) {
- if(objects_p[obj->minor] == obj)
+ if(objects_p[obj->minor] == obj){
objects_p[obj->minor] = NULL;
+ if (--next_minor<0)
+ next_minor=0;
+ }
else
CANMSG("msgobj_done: not registered as minor\n");
}
}
can_checked_free(chip->chipspecops);
+
+ if(~chip->flags & CHIP_KEEP_DATA)
+ can_checked_free(chip->chip_data);
+ chip->chip_data = NULL;
chip->chipspecops=NULL;
}
int i;
struct candevice_t *candev;
- for(i=0; i<canhw->nr_boards; i++){
+ for(i=0; i<MAX_HW_CARDS; i++){
if((candev=canhw->candevice[i])==NULL)
continue;
candevice_done(candev);
/* HCAN2 uses oposite logic for LAFM: 1-ignore bit, 0-use bit as mask */
+#if myDEBUG
DEBUGMSG("CNT: %d ID: 0x%08x MASK: 0x%08x\n", num, (uint32_t) (filter.id) & 0x1fffffff, (uint32_t) (~filter.mask) & 0x1fffffff);
+#endif
if (filter.flags & MSG_EXT) /* Extended ID */
return hcan2_extended_mask(chip, filter.id, ~filter.mask);
#include "../include/can_iortl.h"
#endif /*CAN_WITH_RTL*/
+#if defined(CONFIG_OC_LINCAN_CARD_usbcan)
+ #include "../include/usbcan.h"
+#endif
+
can_spinlock_t canuser_manipulation_lock;
int major=CAN_MAJOR;
}
}
#endif
+
+#if defined(CONFIG_OC_LINCAN_CARD_usbcan)
+ res = usbcan_init();
+ if (res){
+ CANMSG("usb_register for usbcan failed. Error number %d.\n", res);
+ goto memory_error;
+ }
+#endif
+
return 0;
#ifdef CONFIG_PROC_FS
return -ENODEV;
}
+
+
+
+struct candevice_t* register_hotplug_dev(const char *hwname,int (*chipdataregfnc)(struct canchip_t *ch,void *data),void *devdata){
+ int i=0, j, board=0;
+ struct candevice_t *candev;
+ struct canchip_t *chip;
+ struct boardtype_t *brp;
+
+ while ( (hw[board] != NULL) && (board < MAX_HW_CARDS) )
+ board++;
+ if (board>=MAX_HW_CARDS){
+ CANMSG("Maximum number of devices has been reached, no space for new device");
+ return NULL;
+ }
+ brp = boardtype_find(hwname);
+ if(!brp) {
+ CANMSG("Sorry, hardware \"%s\" is currently not supported.\n",hwname);
+ return NULL;
+ }
+ if (board==MAX_HW_CARDS){
+ CANMSG("Device \"%s\" could not be registered due to internal limits.\n",hwname);
+ return NULL;
+ }
+ hw[board]=brp->boardtype;
+
+ if (init_new_hw_struct(board)){
+ CANMSG("HW struct creation failed.\n");
+ return NULL;
+ }
+
+ #ifdef CAN_DEBUG
+ list_hw();
+ #endif
+
+ candev=hardware_p->candevice[board];
+
+ /* Adding link to usb device structure into can device */
+ candev->sysdevptr.anydev=devdata;
+
+ if (candev->hwspecops->request_io(candev))
+ goto request_io_error;
+ candev->flags|=CANDEV_IO_RESERVED;
+
+ if (candev->hwspecops->reset(candev))
+ goto reset_error;
+
+ for(j=0; j<candev->nr_all_chips; j++) {
+ if((chip=candev->chip[j])==NULL)
+ continue;
+
+ if (chipdataregfnc && devdata){
+ if (chipdataregfnc(chip,devdata))
+ goto interrupt_error;
+ }
+
+ if(chip->chipspecops->attach_to_chip(chip)<0) {
+ CANMSG("Initial attach to the chip HW failed\n");
+ goto interrupt_error;
+ }
+
+ chip->flags |= CHIP_ATTACHED;
+
+ if(can_chip_setup_irq(chip)<0) {
+ CANMSG("Error to setup chip IRQ\n");
+ goto interrupt_error;
+ }
+ }
+
+ if (candev->flags & CANDEV_PROGRAMMABLE_IRQ)
+ if (candev->hwspecops->program_irq(candev)){
+ CANMSG("Error to program board interrupt\n");
+ goto interrupt_error;
+ }
+ CANMSG("Registering /proc entry\n");
+#ifdef CONFIG_PROC_FS
+ if (can_init_procentry(board))
+ goto proc_error;
+#endif
+
+#if defined(CONFIG_DEVFS_FS) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+ {
+ #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0))
+ char dev_name[32];
+ #else
+ struct class_device *this_dev;
+ #endif
+ int dev_minor;
+ for(i=0;i<MAX_TOT_MSGOBJS;i++) {
+ if(!objects_p[i]) continue;
+ if(objects_p[i]->hostchip->hostdevice != candev) continue;
+
+ dev_minor=objects_p[i]->minor;
+ #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0))
+ sprintf (dev_name, "can%d", dev_minor);
+ devfs_handles[i]=devfs_register(NULL, dev_name,
+ DEVFS_FL_DEFAULT, major, dev_minor,
+ S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+ &can_fops, (void*)objects_p[i]);
+ #else
+ #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,14))
+ this_dev=class_device_create(can_class, MKDEV(major, dev_minor), NULL, "can%d", dev_minor);
+ #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,25) /* >= 2.6.15 */
+ this_dev=class_device_create(can_class, NULL, MKDEV(major, dev_minor), NULL, "can%d", dev_minor);
+ #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27)
+ this_dev=device_create_drvdata(can_class, NULL, MKDEV(major, dev_minor), objects_p[i], "can%d", dev_minor);
+ #else /* >= 2.6.28 */
+ this_dev=device_create(can_class, NULL, MKDEV(major, dev_minor), objects_p[i], "can%d", dev_minor);
+ #endif /* >= 2.6.28 */
+ if(IS_ERR(this_dev)){
+ CANMSG("problem to create device \"can%d\" in the class \"can\"\n", dev_minor);
+ #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,25)
+ }else{
+ /*this_dev->class_data=objects_p[i];*/
+ class_set_devdata(this_dev,objects_p[i]);
+ #endif /* <= 2.6.25 */
+ }
+ #ifdef CONFIG_DEVFS_FS
+ devfs_mk_cdev(MKDEV(major, dev_minor), S_IFCHR | S_IRUGO | S_IWUGO, "can%d", dev_minor);
+ #endif
+ #endif
+ }
+ }
+#endif
+ return candev;
+
+#ifdef CONFIG_PROC_FS
+ proc_error: ;
+ CANMSG("Error registering /proc entry.\n");
+ goto memory_error;
+#endif
+
+ interrupt_error: ;
+ goto memory_error;
+
+ reset_error: ;
+ CANMSG("Error resetting device.\n");
+ goto memory_error;
+
+ request_io_error: ;
+ CANMSG("Error to request IO resources for device.\n");
+ goto memory_error;
+
+ memory_error: ;
+
+ #ifdef CAN_WITH_RTL
+ rtldev_error:
+ #endif /*CAN_WITH_RTL*/
+
+// register_error:
+// if ( can_del_mem_list() )
+// CANMSG("Error deallocating memory\n");
+
+ return NULL;
+}
+
+void deregister_hotplug_dev(struct candevice_t *dev)
+{
+ int i=0;
+ int dev_minor;
+
+ if (!dev)
+ return;
+ DEBUGMSG("Deregistering hotplug device.\n");
+
+#ifdef CONFIG_PROC_FS
+ if (can_delete_procentry(dev))
+ CANMSG("Error unregistering /proc/can entry.\n");
+#endif
+
+#if defined(CONFIG_DEVFS_FS) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+ for(i=0;i<MAX_TOT_MSGOBJS;i++) {
+ if(!objects_p[i]) continue;
+ if(objects_p[i]->hostchip->hostdevice != dev) continue;
+ #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0))
+ if(devfs_handles[i])
+ devfs_unregister(devfs_handles[i]);
+ #else
+ dev_minor=objects_p[i]->minor;
+ if(dev_minor>=0){
+ #ifdef CONFIG_DEVFS_FS
+ devfs_remove("can%d", dev_minor);
+ #endif
+ #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,25)
+ class_device_destroy(can_class, MKDEV(major, dev_minor));
+ #else /* >= 2.6.26 */
+ device_destroy(can_class, MKDEV(major, dev_minor));
+ #endif /* >= 2.6.26 */
+ }
+ #endif
+ }
+#endif
+
+}
+
+
+void cleanup_hotplug_dev(struct candevice_t *dev)
+{
+ int i=0;
+ int dev_minor;
+
+ if (!dev)
+ return;
+ DEBUGMSG("Cleaning up hotplug device.\n");
+
+ for(i=0;i<MAX_TOT_CHIPS;i++){
+ if(!chips_p[i]) continue;
+ if(chips_p[i]->hostdevice != dev) continue;
+ chips_p[i]=NULL;
+ }
+
+ hardware_p->candevice[dev->candev_idx]=NULL;
+ hardware_p->nr_boards--;
+ hw[dev->candev_idx]=NULL;
+
+ candevice_done(dev);
+ can_checked_free(dev);
+}
+
+
+
+
void cleanup_module(void)
{
#if defined(CONFIG_DEVFS_FS) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
int i=0;
#endif
+#if defined(CONFIG_OC_LINCAN_CARD_usbcan)
+ DEBUGMSG("Unregistering usbcan.\n");
+ usbcan_exit();
+#endif
+
+ DEBUGMSG("Continuing with coldplug cleanup.\n");
#ifdef CONFIG_PROC_FS
if (can_delete_procdir())
CANMSG("Error unregistering /proc/can entry.\n");
canqueue_rtl_done();
#endif /*CAN_WITH_RTL*/
+ DEBUGMSG("Can hardware cleanup done, freeing memory.\n");
+
if ( can_del_mem_list() )
CANMSG("Error deallocating memory\n");
const struct boardtype_t *brp;
if ( (hw[0] == NULL) | (io[0] == -1) ) {
- CANMSG("You must supply your type of hardware, interrupt numbers and io address.\n");
+ //CANMSG("You must supply your type of hardware, interrupt numbers and io address.\n");
+ CANMSG("Autodetection works only for USB devices, supply your type of hardware for PCI devices \n");
CANMSG("Example: # insmod lincan.ko hw=pip5 irq=4 io=0x8000\n");
- return -ENODEV;
+ //return -ENODEV;
}
while ( (hw[i] != NULL) && (i < MAX_HW_CARDS) ) {
CANMSG("Error initializing chip for receiving\n");
}
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
+ if (chip->hostdevice->hwspecops->release_device)
+ kref_get(&chip->hostdevice->refcount);
+#endif
canuser = (struct canuser_t *)kmalloc(sizeof(struct canuser_t), GFP_KERNEL);
if(canuser == NULL) goto no_canuser;
#define __NO_VERSION__
#include <linux/module.h>
+#include <linux/mutex.h>
int add_channel_to_procdir(struct candevice_t *candev);
-int remove_channel_from_procdir(void);
+int remove_channels_from_procdir(void);
+int remove_channel_from_procdir(struct candevice_t *candev);
int add_object_to_procdir(int chip_nr);
int remove_object_from_procdir(int chip_nr);
static struct canproc_t can_proc_base;
static struct canproc_t *base=&can_proc_base;
+DEFINE_MUTEX(proc_mutex); /* synchronize access to canproc_t array */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
{
int board;
struct candevice_t *candev;
+
+ mutex_init(&proc_mutex);
+
base->can_proc_entry = can_proc_mkdir_mode("can", S_IFDIR | S_IRUGO |
S_IXUGO, CAN_PROC_ROOT);
if (base->can_proc_entry == NULL)
return 0;
}
+/* can_init_procentry registers entry of a new board in CAN directory tree at
+ * the proc system.
+ */
+int can_init_procentry(int board)
+{
+ struct candevice_t *candev;
+ candev=hardware_p->candevice[board];
+ if(candev)
+ return add_channel_to_procdir(candev);
+ return -ENODEV;
+}
+
/* can_delete_procdir removes the entire CAN tree from the proc system */
int can_delete_procdir(void)
{
- if (remove_channel_from_procdir())
+ if (remove_channels_from_procdir())
return -ENODEV;
/* name: "can" */
if (can_proc_remove(base->can_proc_entry))
return 0;
}
+/* can_delete_procentry removes device entries from CAN tree in the proc system */
+int can_delete_procentry(struct candevice_t *candev)
+{
+ if (remove_channel_from_procdir(candev))
+ return -ENODEV;
+
+ return 0;
+}
+
static int can_chip_procinfo_show(can_proc_seq_file_t *sqf, void *data)
{
struct canchip_t *chip=can_seq_data(sqf);
{
int i=0;
- for (i=0; i < candev->nr_all_chips; i++) {
+ mutex_lock(&proc_mutex);
+ for (i=0; i < MAX_TOT_CHIPS; i++){
+ if (!chips_p[i]) continue;
+ if (chips_p[i]->hostdevice != candev) continue;
- base->channel[cc] = (struct channelproc_t *)
+ base->channel[i] = (struct channelproc_t *)
can_checked_malloc(sizeof(struct channelproc_t));
- if (base->channel[cc] == NULL)
+ if (base->channel[i] == NULL){
+ mutex_unlock(&proc_mutex);
return -ENOMEM;
+ }
- sprintf(base->channel[cc]->ch_name, "channel%d",cc);
+ sprintf(base->channel[i]->ch_name, "channel%d",i);
- base->channel[cc]->ch_entry = can_proc_mkdir_mode(
- base->channel[cc]->ch_name,
+ base->channel[i]->ch_entry = can_proc_mkdir_mode(
+ base->channel[i]->ch_name,
S_IFDIR | S_IRUGO |S_IXUGO,
base->can_proc_entry);
- if (base->channel[cc]->ch_entry == NULL)
+ if (base->channel[i]->ch_entry == NULL){
+ mutex_unlock(&proc_mutex);
return -ENODEV;
+ }
- add_object_to_procdir(cc);
+ add_object_to_procdir(i);
can_create_proc_read_entry("chip_info", /* proc entry name */
0, /* protection mask, 0->default */
- base->channel[cc]->ch_entry, /* parent dir, NULL->/proc */
+ base->channel[i]->ch_entry, /* parent dir, NULL->/proc */
&can_chip_procinfo_ops,
- candev->chip[i]);
-
+ chips_p[i]);
cc++;
}
+ mutex_unlock(&proc_mutex);
return 0;
}
-int remove_channel_from_procdir(void)
+int remove_channels_from_procdir(void)
{
+ int i=0;
+
+ mutex_lock(&proc_mutex);
+ for (i=0; i < MAX_TOT_CHIPS; i++){
+ if (!chips_p[i]) continue;
- while (cc != 0) {
cc--;
- if(!base->channel[cc]) continue;
+ if(!base->channel[i]) continue;
- remove_proc_entry("chip_info", base->channel[cc]->ch_entry);
+ remove_proc_entry("chip_info", base->channel[i]->ch_entry);
- if (remove_object_from_procdir(cc))
+ if (remove_object_from_procdir(i)){
+ mutex_unlock(&proc_mutex);
return -ENODEV;
+ }
/* name: base->channel[cc]->ch_name */
- if (can_proc_remove(base->channel[cc]->ch_entry))
+ if (can_proc_remove(base->channel[i]->ch_entry)){
+ mutex_unlock(&proc_mutex);
return -ENODEV;
+ }
- can_checked_free(base->channel[cc]);
- base->channel[cc] = NULL;
+ can_checked_free(base->channel[i]);
+ base->channel[i] = NULL;
+ }
+ mutex_unlock(&proc_mutex);
+
+ return 0;
+}
+
+int remove_channel_from_procdir(struct candevice_t *candev)
+{
+ int i=0,j=0;
+
+ mutex_lock(&proc_mutex);
+ for (i=0; i < MAX_TOT_CHIPS; i++){
+ if (!chips_p[i]) continue;
+ if (chips_p[i]->hostdevice != candev) continue;
+ if (!base->channel[i]) continue;
+
+ remove_proc_entry("chip_info", base->channel[i]->ch_entry);
+
+ if (remove_object_from_procdir(i)){
+ mutex_unlock(&proc_mutex);
+ return -ENODEV;
+ }
+
+ /* name: base->channel[cc]->ch_name */
+ if (can_proc_remove(base->channel[i]->ch_entry)){
+ mutex_unlock(&proc_mutex);
+ return -ENODEV;
+ }
+
+ can_checked_free(base->channel[i]);
+ base->channel[i] = NULL;
+
+ cc--;
}
+ mutex_unlock(&proc_mutex);
return 0;
}
int init_chip_struct(struct candevice_t *candev, int chipnr, int irq, long baudrate, long clock);
int init_obj_struct(struct candevice_t *candev, struct canchip_t *hostchip, int objnr);
+int next_minor=0;
+
/**
* can_base_addr_fixup - relocates board physical memory addresses to the CPU accessible ones
* @candev: pointer to the previously filled device/board, chips and message objects structures
*/
int register_obj_struct(struct msgobj_t *obj, int minorbase)
{
- static int next_minor=0;
int i;
if(minorbase>=0)
return 0;
}
+/**
+ * init_new_hw_struct - initializes driver description structures for new hardware
+ *
+ * The function init_new_hw_struct() is used to initialize the hardware structure.
+ *
+ * Return Value: returns negative number in the case of fail
+ */
+int init_new_hw_struct(int devnr)
+{
+ int irq_param_idx=0;
+ int chan_param_idx=0;
+
+ if ( (hw[devnr] != NULL) & (devnr < MAX_HW_CARDS) ) {
+ hardware_p->nr_boards++;
+
+ if (init_device_struct(devnr, &chan_param_idx, &irq_param_idx)) {
+ CANMSG("Error initializing candevice_t structures.\n");
+ return -ENODEV;
+ }
+ }
+
+ return 0;
+}
+
/**
* init_device_struct - initializes single CAN device/board
* @card: index into @hardware_p HW description
candev->dev_base_addr=io[card];
clock=clockfreq[card];
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
+ kref_init(&candev->refcount);
+#endif
+
candev->hwspecops=(struct hwspecops_t *)can_checked_malloc(sizeof(struct hwspecops_t));
if (candev->hwspecops==NULL)
goto error_nomem;
+/* usbcan.h
+ * Header file for the Linux CAN-bus driver.
+ * Written by Jan Kriz email:johen@post.cz
+ * This software is released under the GPL-License.
+ * Version lincan-0.3 17 Jul 2008
+ */
+
+#include "../include/can.h"
+#include "../include/can_sysdep.h"
+#include "../include/main.h"
+#include "../include/devcommon.h"
+#include "../include/setup.h"
+#include "../include/usbcan.h"
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+ #include <linux/freezer.h>
+#endif
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+ #include <linux/smp_lock.h>
+#endif
+#include <linux/module.h>
+
+static int usbcan_probe(struct usb_interface *interface, const struct usb_device_id *id);
+static void usbcan_disconnect(struct usb_interface *interface);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
+void release_device(struct kref *refcount);
+#else
+void release_device(struct candevice_t *candev);
+#endif
+
+volatile int usbcan_chip_count=0;
+
+/* table of devices that work with this driver */
+static struct usb_device_id usbcan_table [] = {
+ { USB_DEVICE(USBCAN_VENDOR_ID, USBCAN_PRODUCT_ID) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, usbcan_table);
+
+static struct usb_driver usbcan_driver = {
+ .name = "usbcan",
+ .id_table = usbcan_table,
+ .probe = usbcan_probe,
+ .disconnect = usbcan_disconnect,
+};
+
+/**
+ * usbcan_request_io: - reserve io or memory range for can board
+ * @candev: pointer to candevice/board which asks for io. Field @io_addr
+ * of @candev is used in most cases to define start of the range
+ *
+ * The function usbcan_request_io() is used to reserve the io-memory. If your
+ * hardware uses a dedicated memory range as hardware control registers you
+ * will have to add the code to reserve this memory as well.
+ * %IO_RANGE is the io-memory range that gets reserved, please adjust according
+ * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
+ * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
+ * Return Value: The function returns zero on success or %-ENODEV on failure
+ * File: src/usbcan.c
+ */
+int usbcan_request_io(struct candevice_t *candev)
+{
+ struct usbcan_devs *usbdevs = (struct usbcan_devs *)candev->sysdevptr.anydev;
+
+ if (!usbdevs){
+ CANMSG("USBCAN_REQUEST_IO: Cannot register usbcan while usb device is not present.\n");
+ CANMSG("USBCAN_REQUEST_IO: Usbcan registers automatically on device insertion.\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+/**
+ * usbcan_release_io - free reserved io memory range
+ * @candev: pointer to candevice/board which releases io
+ *
+ * The function usbcan_release_io() is used to free reserved io-memory.
+ * In case you have reserved more io memory, don't forget to free it here.
+ * IO_RANGE is the io-memory range that gets released, please adjust according
+ * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
+ * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
+ * Return Value: The function always returns zero
+ * File: src/usbcan.c
+ */
+int usbcan_release_io(struct candevice_t *candev)
+{
+ return 0;
+}
+
+/**
+ * usbcan_reset - hardware reset routine
+ * @candev: Pointer to candevice/board structure
+ *
+ * The function usbcan_reset() is used to give a hardware reset. This is
+ * rather hardware specific so I haven't included example code. Don't forget to
+ * check the reset status of the chip before returning.
+ * Return Value: The function returns zero on success or %-ENODEV on failure
+ * File: src/usbcan.c
+ */
+int usbcan_reset(struct candevice_t *candev)
+{
+ return 0;
+}
+
+/**
+ * usbcan_init_hw_data - Initialize hardware cards
+ * @candev: Pointer to candevice/board structure
+ *
+ * The function usbcan_init_hw_data() is used to initialize the hardware
+ * structure containing information about the installed CAN-board.
+ * %RESET_ADDR represents the io-address of the hardware reset register.
+ * %NR_82527 represents the number of Intel 82527 chips on the board.
+ * %NR_SJA1000 represents the number of Philips sja1000 chips on the board.
+ * The flags entry can currently only be %CANDEV_PROGRAMMABLE_IRQ to indicate that
+ * the hardware uses programmable interrupts.
+ * Return Value: The function always returns zero
+ * File: src/usbcan.c
+ */
+int usbcan_init_hw_data(struct candevice_t *candev)
+{
+ candev->res_addr=RESET_ADDR;
+ candev->nr_82527_chips=0;
+ candev->nr_sja1000_chips=0;
+ candev->nr_all_chips=usbcan_chip_count;
+ candev->flags |= CANDEV_PROGRAMMABLE_IRQ*0;
+
+ return 0;
+}
+
+/**
+ * usbcan_init_obj_data - Initialize message buffers
+ * @chip: Pointer to chip specific structure
+ * @objnr: Number of the message buffer
+ *
+ * The function usbcan_init_obj_data() is used to initialize the hardware
+ * structure containing information about the different message objects on the
+ * CAN chip. In case of the sja1000 there's only one message object but on the
+ * i82527 chip there are 15.
+ * The code below is for a i82527 chip and initializes the object base addresses
+ * The entry @obj_base_addr represents the first memory address of the message
+ * object. In case of the sja1000 @obj_base_addr is taken the same as the chips
+ * base address.
+ * Unless the hardware uses a segmented memory map, flags can be set zero.
+ * Return Value: The function always returns zero
+ * File: src/usbcan.c
+ */
+int usbcan_init_obj_data(struct canchip_t *chip, int objnr)
+{
+ chip->msgobj[objnr]->obj_base_addr=0;
+
+ return 0;
+}
+
+/**
+ * usbcan_program_irq - program interrupts
+ * @candev: Pointer to candevice/board structure
+ *
+ * The function usbcan_program_irq() is used for hardware that uses
+ * programmable interrupts. If your hardware doesn't use programmable interrupts
+ * you should not set the @candevices_t->flags entry to %CANDEV_PROGRAMMABLE_IRQ and
+ * leave this function unedited. Again this function is hardware specific so
+ * there's no example code.
+ * Return value: The function returns zero on success or %-ENODEV on failure
+ * File: src/usbcan.c
+ */
+int usbcan_program_irq(struct candevice_t *candev)
+{
+ return 0;
+}
+
+int usbcan_register(struct hwspecops_t *hwspecops)
+{
+ hwspecops->request_io = usbcan_request_io;
+ hwspecops->release_io = usbcan_release_io;
+ hwspecops->reset = usbcan_reset;
+ hwspecops->init_hw_data = usbcan_init_hw_data;
+ hwspecops->init_chip_data = usbcan_init_chip_data;
+ hwspecops->init_obj_data = usbcan_init_obj_data;
+ hwspecops->write_register = NULL;
+ hwspecops->read_register = NULL;
+ hwspecops->program_irq = usbcan_program_irq;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
+ hwspecops->release_device = release_device;
+#endif
+ return 0;
+}
+
+// static int sja1000_report_error_limit_counter;
+
+static void usbcan_report_error(struct canchip_t *chip,
+ unsigned sr, unsigned ir, unsigned ecc)
+{
+ /*TODO : Error reporting from device */
+
+#if 0
+ if(sja1000_report_error_limit_counter>=100)
+ return;
+
+ CANMSG("Error: status register: 0x%x irq_register: 0x%02x error: 0x%02x\n",
+ sr, ir, ecc);
+
+ sja1000_report_error_limit_counter+=10;
+
+ if(sja1000_report_error_limit_counter>=100){
+ sja1000_report_error_limit_counter+=10;
+ CANMSG("Error: too many errors, reporting disabled\n");
+ return;
+ }
+
+#ifdef CONFIG_OC_LINCAN_DETAILED_ERRORS
+ CANMSG("SR: BS=%c ES=%c TS=%c RS=%c TCS=%c TBS=%c DOS=%c RBS=%c\n",
+ sr&sjaSR_BS?'1':'0',sr&sjaSR_ES?'1':'0',
+ sr&sjaSR_TS?'1':'0',sr&sjaSR_RS?'1':'0',
+ sr&sjaSR_TCS?'1':'0',sr&sjaSR_TBS?'1':'0',
+ sr&sjaSR_DOS?'1':'0',sr&sjaSR_RBS?'1':'0');
+ CANMSG("IR: BEI=%c ALI=%c EPI=%c WUI=%c DOI=%c EI=%c TI=%c RI=%c\n",
+ sr&sjaIR_BEI?'1':'0',sr&sjaIR_ALI?'1':'0',
+ sr&sjaIR_EPI?'1':'0',sr&sjaIR_WUI?'1':'0',
+ sr&sjaIR_DOI?'1':'0',sr&sjaIR_EI?'1':'0',
+ sr&sjaIR_TI?'1':'0',sr&sjaIR_RI?'1':'0');
+ if((sr&sjaIR_EI) || 1){
+ CANMSG("EI: %s %s %s\n",
+ sja1000_ecc_errc_str[(ecc&(sjaECC_ERCC1|sjaECC_ERCC0))/sjaECC_ERCC0],
+ ecc&sjaECC_DIR?"RX":"TX",
+ sja1000_ecc_seg_str[ecc&sjaECC_SEG_M]
+ );
+ }
+#endif /*CONFIG_OC_LINCAN_DETAILED_ERRORS*/
+#endif
+}
+
+
+/**
+ * usbcan_enable_configuration - enable chip configuration mode
+ * @chip: pointer to chip state structure
+ */
+int usbcan_enable_configuration(struct canchip_t *chip)
+{
+ return 0;
+}
+
+/**
+ * usbcan_disable_configuration - disable chip configuration mode
+ * @chip: pointer to chip state structure
+ */
+int usbcan_disable_configuration(struct canchip_t *chip)
+{
+ return 0;
+}
+
+/**
+ * usbcan_chip_config: - can chip configuration
+ * @chip: pointer to chip state structure
+ *
+ * This function configures chip and prepares it for message
+ * transmission and reception. The function resets chip,
+ * resets mask for acceptance of all messages by call to
+ * usbcan_extended_mask() function and then
+ * computes and sets baudrate with use of function usbcan_baud_rate().
+ * Return Value: negative value reports error.
+ * File: src/usbcan.c
+ */
+int usbcan_chip_config(struct canchip_t *chip)
+{
+ return 0;
+}
+
+/**
+ * usbcan_extended_mask: - setup of extended mask for message filtering
+ * @chip: pointer to chip state structure
+ * @code: can message acceptance code
+ * @mask: can message acceptance mask
+ *
+ * Return Value: negative value reports error.
+ * File: src/usbcan.c
+ */
+int usbcan_extended_mask(struct canchip_t *chip, unsigned long code, unsigned long mask)
+{
+ int retval;
+ struct usbcan_usb *dev=(struct usbcan_usb*)chip->chip_data;
+
+ u8 usbbuf[USBCAN_TRANSFER_SIZE];
+
+ if (!dev)
+ return -ENODEV;
+
+ *(uint32_t *)(usbbuf)=cpu_to_le32(mask);
+ *(uint32_t *)(usbbuf+4)=cpu_to_le32(code);
+
+ retval=usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ USBCAN_VENDOR_EXT_MASK_SET,
+ USB_TYPE_VENDOR,
+ cpu_to_le16(0), cpu_to_le16(chip->chip_idx),
+ &usbbuf, USBCAN_TRANSFER_SIZE,
+ 10000);
+ if (retval<0)
+ return -ENODEV;
+
+ retval = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ USBCAN_VENDOR_EXT_MASK_STATUS,
+ USB_TYPE_VENDOR,
+ cpu_to_le16(0), cpu_to_le16(chip->chip_idx),
+ &usbbuf, USBCAN_TRANSFER_SIZE,
+ 10000);
+
+ if (retval==1){
+ if(usbbuf[0]==1){
+ DEBUGMSG("Setting acceptance code to 0x%lx\n",(unsigned long)code);
+ DEBUGMSG("Setting acceptance mask to 0x%lx\n",(unsigned long)mask);
+ return 0;
+ }
+ }
+
+ CANMSG("Setting extended mask failed\n");
+ return -EINVAL;
+}
+
+/**
+ * usbcan_baud_rate: - set communication parameters.
+ * @chip: pointer to chip state structure
+ * @rate: baud rate in Hz
+ * @clock: frequency of sja1000 clock in Hz (ISA osc is 14318000)
+ * @sjw: synchronization jump width (0-3) prescaled clock cycles
+ * @sampl_pt: sample point in % (0-100) sets (TSEG1+1)/(TSEG1+TSEG2+2) ratio
+ * @flags: fields %BTR1_SAM, %OCMODE, %OCPOL, %OCTP, %OCTN, %CLK_OFF, %CBP
+ *
+ * Return Value: negative value reports error.
+ * File: src/usbcan.c
+ */
+int usbcan_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
+ int sampl_pt, int flags)
+{
+ int retval;
+ struct usbcan_usb *dev=(struct usbcan_usb*)chip->chip_data;
+
+ u8 usbbuf[USBCAN_TRANSFER_SIZE];
+
+ if (!dev)
+ return -ENODEV;
+
+ *(int32_t *)(usbbuf)=cpu_to_le32(rate);
+ *(int32_t *)(usbbuf+4)=cpu_to_le32(sjw);
+ *(int32_t *)(usbbuf+8)=cpu_to_le32(sampl_pt);
+ *(int32_t *)(usbbuf+12)=cpu_to_le32(flags);
+
+ retval=usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ USBCAN_VENDOR_BAUD_RATE_SET,
+ USB_TYPE_VENDOR,
+ cpu_to_le16(0), cpu_to_le16(chip->chip_idx),
+ &usbbuf, USBCAN_TRANSFER_SIZE,
+ 10000);
+ if (retval<0)
+ return -ENODEV;
+
+ retval = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ USBCAN_VENDOR_BAUD_RATE_STATUS,
+ USB_TYPE_VENDOR,
+ cpu_to_le16(0), cpu_to_le16(chip->chip_idx),
+ usbbuf, USBCAN_TRANSFER_SIZE,
+ 10000);
+
+ if (retval==1){
+ if(usbbuf[0]==1)
+ return 0;
+ }
+
+ CANMSG("baud rate %d is not possible to set\n",
+ rate);
+ return -EINVAL;
+}
+
+/**
+ * usbcan_pre_read_config: - prepares message object for message reception
+ * @chip: pointer to chip state structure
+ * @obj: pointer to message object state structure
+ *
+ * Return Value: negative value reports error.
+ * Positive value indicates immediate reception of message.
+ * File: src/usbcan.c
+ */
+int usbcan_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj)
+{
+ return 0;
+}
+
+#define MAX_TRANSMIT_WAIT_LOOPS 10
+/**
+ * usbcan_pre_write_config: - prepares message object for message transmission
+ * @chip: pointer to chip state structure
+ * @obj: pointer to message object state structure
+ * @msg: pointer to CAN message
+ *
+ * This function prepares selected message object for future initiation
+ * of message transmission by usbcan_send_msg() function.
+ * The CAN message data and message ID are transfered from @msg slot
+ * into chip buffer in this function.
+ * Return Value: negative value reports error.
+ * File: src/usbcan.c
+ */
+int usbcan_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
+ struct canmsg_t *msg)
+{
+ return 0;
+}
+
+/**
+ * usbcan_send_msg: - initiate message transmission
+ * @chip: pointer to chip state structure
+ * @obj: pointer to message object state structure
+ * @msg: pointer to CAN message
+ *
+ * This function is called after usbcan_pre_write_config() function,
+ * which prepares data in chip buffer.
+ * Return Value: negative value reports error.
+ * File: src/usbcan.c
+ */
+int usbcan_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
+ struct canmsg_t *msg)
+{
+ return 0;
+}
+
+/**
+ * usbcan_check_tx_stat: - checks state of transmission engine
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * Positive return value indicates transmission under way status.
+ * Zero value indicates finishing of all issued transmission requests.
+ * File: src/usbcan.c
+ */
+int usbcan_check_tx_stat(struct canchip_t *chip)
+{
+ struct usbcan_usb *dev=(struct usbcan_usb*)chip->chip_data;
+ if (!dev)
+ return 0;
+ if (test_bit(USBCAN_TX_PENDING,&dev->flags))
+ return 1;
+ return 0;
+}
+
+/**
+ * usbcan_set_btregs: - configures bitrate registers
+ * @chip: pointer to chip state structure
+ * @btr0: bitrate register 0
+ * @btr1: bitrate register 1
+ *
+ * Return Value: negative value reports error.
+ * File: src/usbcan.c
+ */
+int usbcan_set_btregs(struct canchip_t *chip, unsigned short btr0,
+ unsigned short btr1)
+{
+ int retval;
+ u8 buf[USBCAN_TRANSFER_SIZE];
+ struct usbcan_usb *dev=(struct usbcan_usb*)chip->chip_data;
+ uint16_t value=(btr1&0xFF)<<8 | (btr0&0xFF);
+
+ if (!dev)
+ return -ENODEV;
+
+ retval = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ USBCAN_VENDOR_SET_BTREGS,
+ USB_TYPE_VENDOR,
+ cpu_to_le16(value), cpu_to_le16(chip->chip_idx),
+ &buf, USBCAN_TRANSFER_SIZE,
+ 10000);
+
+ if (retval==1){
+ if(buf[0]==1)
+ return 0;
+ }
+ return -ENODEV;
+}
+
+/**
+ * usbcan_start_chip: - starts chip message processing
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/usbcan.c
+ */
+int usbcan_start_chip(struct canchip_t *chip)
+{
+ int retval;
+ u8 buf[USBCAN_TRANSFER_SIZE];
+ struct usbcan_usb *dev=(struct usbcan_usb*)chip->chip_data;
+
+ if (!dev)
+ return -ENODEV;
+
+ retval = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ USBCAN_VENDOR_START_CHIP,
+ USB_TYPE_VENDOR,
+ cpu_to_le16(0), cpu_to_le16(chip->chip_idx),
+ &buf, USBCAN_TRANSFER_SIZE,
+ 10000);
+
+ if (retval==1){
+ if(buf[0]==1)
+ return 0;
+ }
+ return -ENODEV;
+}
+
+/**
+ * usbcan_chip_queue_status: - gets queue status from usb device
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * 0 means queue is not full
+ * 1 means queue is full
+ * File: src/usbcan.c
+ */
+int usbcan_chip_queue_status(struct canchip_t *chip)
+{
+ int retval;
+ u8 buf[USBCAN_TRANSFER_SIZE];
+ struct usbcan_usb *dev=(struct usbcan_usb*)chip->chip_data;
+
+ if (!dev)
+ return -ENODEV;
+ retval = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ USBCAN_VENDOR_CHECK_TX_STAT,
+ USB_TYPE_VENDOR,
+ cpu_to_le16(0), cpu_to_le16(chip->chip_idx),
+ &buf, USBCAN_TRANSFER_SIZE,
+ 10000);
+
+ if (retval==1){
+ DEBUGMSG("Chip_queue_status: %d\n",buf[0]);
+ if(buf[0]==1)
+ return 0;
+ if(buf[0]==0)
+ return 1;
+ }
+ CANMSG("Chip_queue_status error: %d\n",retval);
+ return -ENODEV;
+}
+
+/**
+ * usbcan_stop_chip: - stops chip message processing
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/usbcan.c
+ */
+int usbcan_stop_chip(struct canchip_t *chip)
+{
+ int retval;
+ u8 buf[USBCAN_TRANSFER_SIZE];
+ struct usbcan_usb *dev=(struct usbcan_usb*)chip->chip_data;
+
+ if (!dev)
+ return -ENODEV;
+
+ retval = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ USBCAN_VENDOR_STOP_CHIP,
+ USB_TYPE_VENDOR,
+ cpu_to_le16(0), cpu_to_le16(chip->chip_idx),
+ &buf, USBCAN_TRANSFER_SIZE,
+ 10000);
+
+ if (retval==1){
+ if(buf[0]==1)
+ return 0;
+ }
+ return -ENODEV;
+}
+
+/**
+ * usbcan_register_devs: - attaches usb device data to the chip structure
+ * @chip: pointer to chip state structure
+ * @data: usb device data
+ *
+ * File: src/usbcan.c
+ */
+int usbcan_register_devs(struct canchip_t *chip,void *data){
+ struct usbcan_devs *usbdevs=(struct usbcan_devs *)data;
+ if (!usbdevs){
+ CANMSG("Bad structure given\n");
+ return -1;
+ }
+ if (chip->chip_idx>=usbdevs->count) {
+ CANMSG("Requested chip number is bigger than chip count\n");
+ return -1;
+ }
+
+ usbdevs->devs[chip->chip_idx]->chip=chip;
+ chip->chip_data=(void *)usbdevs->devs[chip->chip_idx];
+ return 0;
+}
+
+/**
+ * usbcan_attach_to_chip: - attaches to the chip, setups registers and state
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/usbcan.c
+ */
+int usbcan_attach_to_chip(struct canchip_t *chip)
+{
+ struct usbcan_usb *dev = (struct usbcan_usb *)chip->chip_data;
+
+ /* start kernel thread */
+ dev->comthread=can_kthread_run(usbcan_kthread, (void *)dev, "usbcan_%d",chip->chip_idx);
+
+ return 0;
+}
+
+/**
+ * usbcan_release_chip: - called before chip structure removal if %CHIP_ATTACHED is set
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/usbcan.c
+ */
+int usbcan_release_chip(struct canchip_t *chip)
+{
+ struct usbcan_usb *dev = (struct usbcan_usb *)chip->chip_data;
+
+ usbcan_stop_chip(chip);
+
+ /* terminate the kernel thread */
+ set_bit(USBCAN_TERMINATE,&dev->flags);
+// wake_up_process(dev->comthread);
+ can_kthread_stop(dev->comthread);
+
+ return 0;
+}
+
+/**
+ * usbcan_remote_request: - configures message object and asks for RTR message
+ * @chip: pointer to chip state structure
+ * @obj: pointer to message object structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/usbcan.c
+ */
+int usbcan_remote_request(struct canchip_t *chip, struct msgobj_t *obj)
+{
+ CANMSG("usbcan_remote_request not implemented\n");
+ return -ENOSYS;
+}
+
+/**
+ * usbcan_standard_mask: - setup of mask for message filtering
+ * @chip: pointer to chip state structure
+ * @code: can message acceptance code
+ * @mask: can message acceptance mask
+ *
+ * Return Value: negative value reports error.
+ * File: src/usbcan.c
+ */
+int usbcan_standard_mask(struct canchip_t *chip, unsigned short code,
+ unsigned short mask)
+{
+ CANMSG("usbcan_standard_mask not implemented\n");
+ return -ENOSYS;
+}
+
+/**
+ * usbcan_clear_objects: - clears state of all message object residing in chip
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/usbcan.c
+ */
+int usbcan_clear_objects(struct canchip_t *chip)
+{
+ CANMSG("usbcan_clear_objects not implemented\n");
+ return -ENOSYS;
+}
+
+/**
+ * usbcan_config_irqs: - tunes chip hardware interrupt delivery
+ * @chip: pointer to chip state structure
+ * @irqs: requested chip IRQ configuration
+ *
+ * Return Value: negative value reports error.
+ * File: src/usbcan.c
+ */
+int usbcan_config_irqs(struct canchip_t *chip, short irqs)
+{
+ CANMSG("usbcan_config_irqs not implemented\n");
+ return -ENOSYS;
+}
+
+
+static void usbcan_usb_message_move_list(struct usbcan_usb *dev,
+ struct usbcan_message *m, struct list_head *head)
+{
+ can_spin_irqflags_t flags;
+ can_spin_lock_irqsave(&dev->list_lock, flags);
+ list_del(&m->list_node);
+ list_add_tail(&m->list_node, head);
+ can_spin_unlock_irqrestore(&dev->list_lock, flags);
+}
+
+
+/**
+ * usbcan_kthread_read_handler: - part of kthread code responsible for receive completed events
+ * @dev: pointer to usb device related structure
+ * @obj: pointer to attached message object description
+ *
+ * The main purpose of this function is to read message from usb urb
+ * and transfer message contents to CAN queue ends.
+ * This subroutine is called by
+ * usbcan_kthread().
+ * File: src/usbcan.c
+ */
+void usbcan_kthread_read_handler(struct usbcan_usb *dev, struct usbcan_message *m,
+ struct msgobj_t *obj)
+{
+ int i, len, retval;
+ u8 *ptr;
+
+ DEBUGMSG("USBCAN RX handler\n");
+
+ if (!test_and_clear_bit(USBCAN_MESSAGE_DATA_OK,&m->flags)) {
+ CANMSG("Strange, Rx handler USBCAN_MESSAGE_DATA_OK not set\n");
+ goto skip_msg;
+ }
+
+ if (!(dev->chip)||!(dev->chip->flags & CHIP_CONFIGURED)) {
+ CANMSG("Destination chip not found\n");
+ goto skip_msg;
+ }
+
+
+ DEBUGMSG("USBCAN Thread has received a message\n");
+
+ len=*(u8 *)(m->msg+1);
+ if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
+ obj->rx_msg.length = len;
+
+ obj->rx_msg.flags=le16_to_cpu(*(u16 *)(m->msg+2));
+ obj->rx_msg.id=le32_to_cpu((*(u32 *)(m->msg+4)));
+
+ for(ptr=m->msg+8,i=0; i < len; ptr++,i++) {
+ obj->rx_msg.data[i]=*ptr;
+ }
+
+ // fill CAN message timestamp
+ can_filltimestamp(&obj->rx_msg.timestamp);
+ canque_filter_msg2edges(obj->qends, &obj->rx_msg);
+
+skip_msg:
+ DEBUGMSG("Renewing RX urb\n");
+
+ usbcan_usb_message_move_list(dev, m, &dev->rx_pend_list);
+ retval = usb_submit_urb (m->u, GFP_KERNEL);
+ if (retval<0) {
+ CANMSG("URB error %d\n", retval);
+ set_bit(USBCAN_ERROR,&dev->flags);
+ }
+}
+
+/**
+ * usbcan_kthread_write_handler: - part of kthread code responsible for transmit done events
+ * @dev: pointer to usb device related structure
+ * @obj: pointer to attached message object description
+ *
+ * The main purpose of this function is to free allocated resources on transmit done event
+ * This subroutine is called by
+ * usbcan_kthread().
+ * File: src/usbcan.c
+ */
+void usbcan_kthread_write_handler(struct usbcan_usb *dev, struct usbcan_message *m,
+ struct msgobj_t *obj)
+{
+ if (!test_and_clear_bit(USBCAN_MESSAGE_DATA_OK,&m->flags)) {
+ CANMSG("Strange, Tx handler USBCAN_MESSAGE_DATA_OK not set\n");
+ goto skip_msg;
+ }
+
+ DEBUGMSG("USBCAN Message successfully sent\n");
+
+ if(m->slot){
+ // Do local transmitted message distribution if enabled
+ if (processlocal){
+ // fill CAN message timestamp
+ can_filltimestamp(&m->slot->msg.timestamp);
+
+ m->slot->msg.flags |= MSG_LOCAL;
+ canque_filter_msg2edges(obj->qends, &m->slot->msg);
+ }
+ // Free transmitted slot
+ canque_free_outslot(obj->qends, m->qedge, m->slot);
+ m->slot=NULL;
+ }
+
+ /*FIXME - why there*/
+ can_msgobj_clear_fl(obj,TX_PENDING);
+
+skip_msg:
+ set_bit(USBCAN_FREE_TX_URB,&dev->flags);
+
+ set_bit(USBCAN_TX_PENDING,&dev->flags);
+
+ usbcan_usb_message_move_list(dev, m, &dev->tx_idle_list);
+}
+
+/**
+ * usbcan_kthread_write_request_handler: - part of kthread code responsible for sending transmit urbs
+ * @dev: pointer to usb device related structure
+ * @obj: pointer to attached message object description
+ *
+ * The main purpose of this function is to create a usb transmit safe object
+ * and send it via free transmit usb urb
+ * This subroutine is called by
+ * usbcan_kthread().
+ * File: src/usbcan.c
+ */
+void usbcan_kthread_write_request_handler(struct usbcan_usb *dev, struct msgobj_t *obj){
+ int i, cmd, len, retval;
+ u8 *ptr;
+ struct usbcan_message *m;
+
+ if(list_empty(&dev->tx_idle_list)) {
+ clear_bit(USBCAN_FREE_TX_URB,&dev->flags);
+ return;
+ }
+
+ m = list_first_entry(&dev->tx_idle_list, typeof(*m), list_node);
+
+ cmd=canque_test_outslot(obj->qends, &m->qedge, &m->slot);
+ if(cmd>=0){
+ DEBUGMSG("USBCAN Sending a message\n");
+
+ can_msgobj_set_fl(obj,TX_PENDING);
+ clear_bit(USBCAN_FREE_TX_URB,&dev->flags);
+
+ *(u8 *)(m->msg)=0;
+ len = m->slot->msg.length;
+ if(len > CAN_MSG_LENGTH)
+ len = CAN_MSG_LENGTH;
+ *(u8 *)(m->msg+1)=len & 0xFF;
+ *(u16 *)(m->msg+2)=cpu_to_le16(m->slot->msg.flags);
+ *(u32 *)(m->msg+4)=cpu_to_le32(m->slot->msg.id);
+
+ for(ptr=m->msg+8, i=0; i < len; ptr++,i++) {
+ *ptr=m->slot->msg.data[i] & 0xFF;
+ }
+ for(; i < 8; ptr++,i++) {
+ *ptr=0;
+ }
+
+
+ usbcan_usb_message_move_list(dev, m, &dev->tx_pend_list);
+
+ retval = usb_submit_urb (m->u, GFP_KERNEL);
+ if (retval){
+ CANMSG("%d. URB error %d\n",i,retval);
+ set_bit(USBCAN_FREE_TX_URB,&dev->flags);
+ obj->ret = -1;
+ canque_notify_inends(m->qedge, CANQUEUE_NOTIFY_ERRTX_SEND);
+ canque_free_outslot(obj->qends, m->qedge, m->slot);
+ m->slot=NULL;
+ usbcan_usb_message_move_list(dev, m, &dev->tx_idle_list);
+ } else {
+ set_bit(USBCAN_TX_PENDING,&dev->flags);
+ }
+ } else {
+ set_bit(USBCAN_FREE_TX_URB,&dev->flags);
+ }
+}
+
+#define MAX_RETR 10
+
+/**
+ * usbcan_irq_handler: - interrupt service routine
+ * @irq: interrupt vector number, this value is system specific
+ * @chip: pointer to chip state structure
+ *
+ * Interrupt handler is activated when state of CAN controller chip changes,
+ * there is message to be read or there is more space for new messages or
+ * error occurs. The receive events results in reading of the message from
+ * CAN controller chip and distribution of message through attached
+ * message queues.
+ * File: src/usbcan.c
+ */
+int usbcan_irq_handler(int irq, struct canchip_t *chip)
+{
+ return CANCHIP_IRQ_HANDLED;
+}
+
+/**
+ * usbcan_wakeup_tx: - wakeups TX processing
+ * @chip: pointer to chip state structure
+ * @obj: pointer to message object structure
+ *
+ * Function is responsible for initiating message transmition.
+ * It is responsible for clearing of object TX_REQUEST flag
+ *
+ * Return Value: negative value reports error.
+ * File: src/usbcan.c
+ */
+int usbcan_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
+{
+ struct usbcan_usb *dev=(struct usbcan_usb *)chip->chip_data;
+
+ DEBUGMSG("Trying to send message\n");
+ can_preempt_disable();
+
+ can_msgobj_set_fl(obj,TX_PENDING);
+ can_msgobj_set_fl(obj,TX_REQUEST);
+ while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
+ can_msgobj_clear_fl(obj,TX_REQUEST);
+
+ if (test_and_clear_bit(USBCAN_FREE_TX_URB,&dev->flags)){
+ obj->tx_retry_cnt=0;
+ set_bit(USBCAN_TX_PENDING,&dev->flags);
+ if (test_bit(USBCAN_THREAD_RUNNING,&dev->flags))
+ wake_up_process(dev->comthread);
+ }
+
+ can_msgobj_clear_fl(obj,TX_LOCK);
+ if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
+ CANMSG("TX looping in usbcan_wakeup_tx\n");
+ }
+
+ can_preempt_enable();
+ return 0;
+}
+
+int usbcan_chipregister(struct chipspecops_t *chipspecops)
+{
+ CANMSG("initializing usbcan chip operations\n");
+ chipspecops->chip_config=usbcan_chip_config;
+ chipspecops->baud_rate=usbcan_baud_rate;
+ chipspecops->standard_mask=usbcan_standard_mask;
+ chipspecops->extended_mask=usbcan_extended_mask;
+ chipspecops->message15_mask=usbcan_extended_mask;
+ chipspecops->clear_objects=usbcan_clear_objects;
+ chipspecops->config_irqs=usbcan_config_irqs;
+ chipspecops->pre_read_config=usbcan_pre_read_config;
+ chipspecops->pre_write_config=usbcan_pre_write_config;
+ chipspecops->send_msg=usbcan_send_msg;
+ chipspecops->check_tx_stat=usbcan_check_tx_stat;
+ chipspecops->wakeup_tx=usbcan_wakeup_tx;
+ chipspecops->remote_request=usbcan_remote_request;
+ chipspecops->enable_configuration=usbcan_enable_configuration;
+ chipspecops->disable_configuration=usbcan_disable_configuration;
+ chipspecops->attach_to_chip=usbcan_attach_to_chip;
+ chipspecops->release_chip=usbcan_release_chip;
+ chipspecops->set_btregs=usbcan_set_btregs;
+ chipspecops->start_chip=usbcan_start_chip;
+ chipspecops->stop_chip=usbcan_stop_chip;
+ chipspecops->irq_handler=usbcan_irq_handler;
+ chipspecops->irq_accept=NULL;
+ return 0;
+}
+
+/**
+ * usbcan_fill_chipspecops - fills chip specific operations
+ * @chip: pointer to chip representation structure
+ *
+ * The function fills chip specific operations for sja1000 (PeliCAN) chip.
+ *
+ * Return Value: returns negative number in the case of fail
+ */
+int usbcan_fill_chipspecops(struct canchip_t *chip)
+{
+ chip->chip_type="usbcan";
+ chip->max_objects=1;
+ usbcan_chipregister(chip->chipspecops);
+ return 0;
+}
+
+/**
+ * usbcan_init_chip_data - Initialize chips
+ * @candev: Pointer to candevice/board structure
+ * @chipnr: Number of the CAN chip on the hardware card
+ *
+ * The function usbcan_init_chip_data() is used to initialize the hardware
+ * structure containing information about the CAN chips.
+ * %CHIP_TYPE represents the type of CAN chip. %CHIP_TYPE can be "i82527" or
+ * "sja1000".
+ * The @chip_base_addr entry represents the start of the 'official' memory map
+ * of the installed chip. It's likely that this is the same as the @io_addr
+ * argument supplied at module loading time.
+ * The @clock entry holds the chip clock value in Hz.
+ * The entry @sja_cdr_reg holds hardware specific options for the Clock Divider
+ * register. Options defined in the %sja1000.h file:
+ * %sjaCDR_CLKOUT_MASK, %sjaCDR_CLK_OFF, %sjaCDR_RXINPEN, %sjaCDR_CBP, %sjaCDR_PELICAN
+ * The entry @sja_ocr_reg holds hardware specific options for the Output Control
+ * register. Options defined in the %sja1000.h file:
+ * %sjaOCR_MODE_BIPHASE, %sjaOCR_MODE_TEST, %sjaOCR_MODE_NORMAL, %sjaOCR_MODE_CLOCK,
+ * %sjaOCR_TX0_LH, %sjaOCR_TX1_ZZ.
+ * The entry @int_clk_reg holds hardware specific options for the Clock Out
+ * register. Options defined in the %i82527.h file:
+ * %iCLK_CD0, %iCLK_CD1, %iCLK_CD2, %iCLK_CD3, %iCLK_SL0, %iCLK_SL1.
+ * The entry @int_bus_reg holds hardware specific options for the Bus
+ * Configuration register. Options defined in the %i82527.h file:
+ * %iBUS_DR0, %iBUS_DR1, %iBUS_DT1, %iBUS_POL, %iBUS_CBY.
+ * The entry @int_cpu_reg holds hardware specific options for the cpu interface
+ * register. Options defined in the %i82527.h file:
+ * %iCPU_CEN, %iCPU_MUX, %iCPU_SLP, %iCPU_PWD, %iCPU_DMC, %iCPU_DSC, %iCPU_RST.
+ * Return Value: The function always returns zero
+ * File: src/usbcan.c
+ */
+int usbcan_init_chip_data(struct candevice_t *candev, int chipnr)
+{
+ struct canchip_t *chip=candev->chip[chipnr];
+
+ usbcan_fill_chipspecops(chip);
+
+ candev->chip[chipnr]->flags|=CHIP_IRQ_CUSTOM|CHIP_KEEP_DATA;
+ candev->chip[chipnr]->chip_base_addr=0;
+ candev->chip[chipnr]->clock = 0;
+
+ return 0;
+}
+
+
+/** *********************************
+ * USB related functions
+ * ********************************* */
+
+static int usbcan_sleep_thread(struct usbcan_usb *dev)
+{
+ int rc = 0;
+
+ /* Wait until a signal arrives or we are woken up */
+ for (;;) {
+ try_to_freeze();
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (signal_pending(current)) {
+ rc = -EINTR;
+ break;
+ }
+ if (
+ can_kthread_should_stop() ||
+ test_bit(USBCAN_DATA_OK,&dev->flags) ||
+ test_bit(USBCAN_TX_PENDING,&dev->flags) ||
+ test_bit(USBCAN_TERMINATE,&dev->flags) ||
+ test_bit(USBCAN_ERROR,&dev->flags)
+ )
+ break;
+ schedule();
+ }
+ __set_current_state(TASK_RUNNING);
+ return rc;
+}
+
+static void usbcan_tx_callback(struct urb *urb)
+{
+ struct usbcan_message *m = urb->context;
+ int retval;
+
+ if (!test_bit(USBCAN_THREAD_RUNNING,&m->dev->flags))
+ return;
+ if (test_bit(USBCAN_MESSAGE_TERMINATE,&m->flags))
+ return;
+
+ switch (urb->status) {
+ case 0:
+ /* success */
+ DEBUGMSG("%s > Message OK\n", __FUNCTION__);
+ set_bit(USBCAN_DATA_OK,&m->dev->flags);
+ set_bit(USBCAN_MESSAGE_DATA_OK,&m->flags);
+ DEBUGMSG("%s > TX flag set\n", __FUNCTION__);
+ set_bit(USBCAN_DATA_TX,&m->dev->flags);
+ usbcan_usb_message_move_list(m->dev, m, &m->dev->tx_ready_list);
+ if (test_bit(USBCAN_THREAD_RUNNING,&m->dev->flags))
+ wake_up_process(m->dev->comthread);
+ else
+ CANMSG("%s > USBCAN thread not running\n", __FUNCTION__);
+ return;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ CANMSG("%s > Urb shutting down with status: %d\n", __FUNCTION__, urb->status);
+// set_bit(USBCAN_TERMINATE,&m->dev->flags);
+ set_bit(USBCAN_MESSAGE_TERMINATE,&m->flags);
+ return;
+ default:
+ //CANMSG("%s > Nonzero status received: %d\n", __FUNCTION__, urb->status);
+ break;
+ }
+
+ // Try to send urb again on non significant errors
+ retval = usb_submit_urb (urb, GFP_ATOMIC);
+ if (retval<0){
+ CANMSG("%s > Retrying urb failed with result %d\n", __FUNCTION__, retval);
+ set_bit(USBCAN_ERROR,&m->dev->flags);
+ usbcan_usb_message_move_list(m->dev, m, &m->dev->tx_ready_list);
+ if (test_bit(USBCAN_THREAD_RUNNING,&m->dev->flags))
+ wake_up_process(m->dev->comthread);
+ }
+}
+
+static void usbcan_rx_callback(struct urb *urb)
+{
+ struct usbcan_message *m = urb->context;
+ int retval;
+
+ if (!test_bit(USBCAN_THREAD_RUNNING,&m->dev->flags))
+ return;
+ if (test_bit(USBCAN_MESSAGE_TERMINATE,&m->flags))
+ return;
+
+ switch (urb->status) {
+ case 0:
+ /* success */
+ DEBUGMSG("%s > Message OK\n", __FUNCTION__);
+ set_bit(USBCAN_DATA_OK,&m->dev->flags);
+ set_bit(USBCAN_MESSAGE_DATA_OK,&m->flags);
+ DEBUGMSG("%s > RX flag set\n", __FUNCTION__);
+ set_bit(USBCAN_DATA_RX,&m->dev->flags);
+ usbcan_usb_message_move_list(m->dev, m, &m->dev->rx_ready_list);
+ if (test_bit(USBCAN_THREAD_RUNNING,&m->dev->flags))
+ wake_up_process(m->dev->comthread);
+ else
+ CANMSG("%s > USBCAN thread not running\n", __FUNCTION__);
+ return;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ CANMSG("%s > Urb shutting down with status: %d\n", __FUNCTION__, urb->status);
+// set_bit(USBCAN_TERMINATE,&m->dev->flags);
+ set_bit(USBCAN_MESSAGE_TERMINATE,&m->flags);
+ return;
+ default:
+ //CANMSG("%s > Nonzero status received: %d\n", __FUNCTION__, urb->status);
+ break;
+ }
+
+ // Try to send urb again on non significant errors
+ retval = usb_submit_urb (urb, GFP_ATOMIC);
+ if (retval<0){
+ CANMSG("%s > Retrying urb failed with result %d\n", __FUNCTION__, retval);
+ set_bit(USBCAN_ERROR,&m->dev->flags);
+ usbcan_usb_message_move_list(m->dev, m, &m->dev->rx_ready_list);
+ if (test_bit(USBCAN_THREAD_RUNNING,&m->dev->flags))
+ wake_up_process(m->dev->comthread);
+ }
+}
+
+
+static void usbcan_kthread_free_urbs(struct usbcan_usb *dev)
+{
+ while(!list_empty(&dev->rx_pend_list)) {
+ struct usbcan_message *m;
+ m = list_first_entry(&dev->rx_pend_list, typeof(*m), list_node);
+ set_bit(USBCAN_MESSAGE_TERMINATE,&m->flags);
+ usb_kill_urb(m->u);
+ usbcan_usb_message_move_list(dev, m, &dev->rx_ready_list);
+ }
+
+ while(!list_empty(&dev->tx_pend_list)) {
+ struct usbcan_message *m;
+ m = list_first_entry(&dev->tx_pend_list, typeof(*m), list_node);
+ set_bit(USBCAN_MESSAGE_TERMINATE,&m->flags);
+ usb_kill_urb(m->u);
+ usbcan_usb_message_move_list(dev, m, &dev->tx_idle_list);
+ }
+
+ while(!list_empty(&dev->rx_ready_list)) {
+ struct usbcan_message *m;
+ m = list_first_entry(&dev->rx_ready_list, typeof(*m), list_node);
+ list_del(&m->list_node);
+ usb_free_urb(m->u);
+ kfree(m);
+ }
+
+ while(!list_empty(&dev->tx_ready_list)) {
+ struct usbcan_message *m;
+ m = list_first_entry(&dev->tx_ready_list, typeof(*m), list_node);
+ list_del(&m->list_node);
+ usb_free_urb(m->u);
+ kfree(m);
+ }
+
+ while(!list_empty(&dev->tx_idle_list)) {
+ struct usbcan_message *m;
+ m = list_first_entry(&dev->tx_idle_list, typeof(*m), list_node);
+ list_del(&m->list_node);
+ usb_free_urb(m->u);
+ kfree(m);
+ }
+
+}
+
+int usbcan_kthread(void *data)
+{
+ int i,retval=0;
+ struct usbcan_usb *dev=(struct usbcan_usb *)data;
+ struct msgobj_t *obj;
+
+ CANMSG("Usbcan thread started...\n");
+
+ if (!dev->chip)
+ goto error;
+ obj=dev->chip->msgobj[0];
+
+ INIT_LIST_HEAD(&dev->rx_pend_list);
+ INIT_LIST_HEAD(&dev->rx_ready_list);
+ INIT_LIST_HEAD(&dev->tx_idle_list);
+ INIT_LIST_HEAD(&dev->tx_pend_list);
+ INIT_LIST_HEAD(&dev->tx_ready_list);
+
+ if (1) {
+ struct sched_param param = { .sched_priority = 1 };
+ sched_setscheduler(current, SCHED_FIFO, ¶m);
+ }
+
+
+ /* Prepare receive urbs */
+ for (i=0;i<USBCAN_TOT_RX_URBS;i++){
+ struct usbcan_message *m;
+ struct urb *u = usb_alloc_urb(0, GFP_KERNEL);
+ if (!u){
+ CANMSG("Error allocating %d. usb receive urb\n",i);
+ goto error;
+ }
+ m = kzalloc(sizeof(struct usbcan_message), GFP_KERNEL);
+ if(!m) {
+ usb_free_urb(u);
+ CANMSG("Error allocating %d. receive usbcan_message\n",i);
+ goto error;
+ }
+ m->u = u;
+ u->dev = dev->udev;
+ m->dev = dev;
+ usb_fill_bulk_urb(u, dev->udev,
+ usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
+ m->msg, USBCAN_TRANSFER_SIZE, usbcan_rx_callback, m);
+
+ list_add_tail(&m->list_node, &dev->rx_ready_list);
+ }
+
+ /* Prepare transmit urbs */
+ for (i=0;i<USBCAN_TOT_TX_URBS;i++){
+ struct usbcan_message *m;
+ struct urb *u = usb_alloc_urb(0, GFP_KERNEL);
+ if (!u){
+ CANMSG("Error allocating %d. usb transmit urb\n",i);
+ goto error;
+ }
+ m = kzalloc(sizeof(struct usbcan_message), GFP_KERNEL);
+ if(!m) {
+ usb_free_urb(u);
+ CANMSG("Error allocating %d. transmit usbcan_message\n",i);
+ goto error;
+ }
+ m->u = u;
+ u->dev = dev->udev;
+ m->dev = dev;
+ usb_fill_bulk_urb(u, dev->udev,
+ usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
+ m->msg, USBCAN_TRANSFER_SIZE, usbcan_tx_callback, m);
+
+ list_add_tail(&m->list_node, &dev->tx_idle_list);
+
+ }
+
+ set_bit(USBCAN_THREAD_RUNNING,&dev->flags);
+ set_bit(USBCAN_FREE_TX_URB,&dev->flags);
+
+ for (i=0;i<USBCAN_TOT_RX_URBS;i++){
+ struct usbcan_message *m;
+ m = list_first_entry(&dev->rx_ready_list, typeof(*m), list_node);
+ usbcan_usb_message_move_list(dev, m, &dev->rx_pend_list);
+
+ retval=usb_submit_urb(m->u, GFP_KERNEL);
+ if (retval){
+ CANMSG("%d. URB error %d\n",i,retval);
+ set_bit(USBCAN_ERROR,&dev->flags);
+ usbcan_usb_message_move_list(dev, m, &dev->rx_ready_list);
+ goto exit;
+ }
+ }
+ /* an endless loop in which we are doing our work */
+ for(;;)
+ {
+ /* We need to do a memory barrier here to be sure that
+ the flags are visible on all CPUs. */
+ mb();
+ /* fall asleep */
+ if (!can_kthread_should_stop() && !test_bit(USBCAN_TERMINATE,&dev->flags) && (usbcan_sleep_thread(dev)<0)){
+ break;
+ }
+ /* We need to do a memory barrier here to be sure that the flags are visible on all CPUs. */
+ mb();
+
+ if (can_kthread_should_stop() || test_bit(USBCAN_TERMINATE,&dev->flags)){
+ break;
+ }
+
+ clear_bit(USBCAN_DATA_OK,&dev->flags);
+
+ mb();
+
+ while(!list_empty(&dev->rx_ready_list)) {
+ struct usbcan_message *m;
+ m = list_first_entry(&dev->rx_ready_list, typeof(*m), list_node);
+ usbcan_kthread_read_handler(dev, m, obj);
+ }
+
+ while(!list_empty(&dev->tx_ready_list)) {
+ struct usbcan_message *m;
+ m = list_first_entry(&dev->tx_ready_list, typeof(*m), list_node);
+ usbcan_kthread_write_handler(dev, m, obj);
+ }
+
+ if (test_and_clear_bit(USBCAN_TX_PENDING,&dev->flags)) {
+ usbcan_kthread_write_request_handler(dev, obj);
+ }
+ }
+
+ set_bit(USBCAN_TERMINATE,&dev->flags);
+exit:
+
+ usbcan_kthread_free_urbs(dev);
+ clear_bit(USBCAN_THREAD_RUNNING,&dev->flags);
+
+ CANMSG ("usbcan thread finished!\n");
+ return 0;
+error:
+ /* cleanup the thread, leave */
+ usbcan_kthread_free_urbs(dev);
+
+ CANMSG ("kernel thread terminated!\n");
+ return -ENOMEM;
+}
+
+static int usbcan_probe(struct usb_interface *interface, const struct usb_device_id *id)
+{
+ struct usbcan_devs *usbdevs=NULL;
+ struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ size_t buffer_size;
+ int i,j,k;
+ int retval = -ENOMEM;
+
+ iface_desc = interface->cur_altsetting;
+ if (iface_desc->desc.bNumEndpoints % 2){
+ CANMSG("Endpoint count must be even");
+ goto noalloc;
+ }
+
+ usbcan_chip_count = iface_desc->desc.bNumEndpoints / 2;
+
+ usbdevs = (struct usbcan_devs *) can_checked_malloc(sizeof(struct usbcan_devs));
+ if (!usbdevs) {
+ goto noalloc;
+ }
+ memset(usbdevs, 0, sizeof(struct usbcan_devs));
+
+ usbdevs->count = usbcan_chip_count;
+ usbdevs->udev = interface_to_usbdev(interface);
+
+ usbdevs->devs = (struct usbcan_usb **) can_checked_malloc(usbcan_chip_count * sizeof(struct usbcan_usb *));
+ if (!usbdevs->devs) {
+ goto error;
+ }
+ memset(usbdevs->devs, 0, usbcan_chip_count * sizeof(struct usbcan_usb *));
+
+ for (j=0;j<usbcan_chip_count;j++){
+ struct usbcan_usb *dev;
+ int epnum=-1,was;
+
+ /* allocate memory for our device state and initialize it */
+ usbdevs->devs[j] = (struct usbcan_usb *) can_checked_malloc(sizeof(struct usbcan_usb));
+ if (!usbdevs->devs[j]) {
+ goto error;
+ }
+ memset(usbdevs->devs[j], 0, sizeof(struct usbcan_usb));
+ dev=usbdevs->devs[j];
+ spin_lock_init(&dev->list_lock);
+
+ mutex_init(&dev->io_mutex);
+ init_waitqueue_head(&dev->queue);
+ dev->udev = usbdevs->udev;
+ dev->interface = interface;
+
+ /* set up the endpoint information */
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+ endpoint = &iface_desc->endpoint[i].desc;
+
+ if (epnum==-1){
+ was=0;
+ for (k=0;k<j;k++){
+ if ((usbdevs->devs[k]->bulk_in_endpointAddr & USB_ENDPOINT_NUMBER_MASK) == (endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK))
+ was=1;
+ }
+ if (was) continue;
+ epnum=endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+ }
+
+ if (!dev->bulk_in_endpointAddr &&
+ usb_endpoint_is_bulk_in(endpoint)) {
+ if (epnum == (endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)){
+ /* we found a bulk in endpoint */
+ buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
+ dev->bulk_in_size = buffer_size;
+ dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
+ dev->bulk_in_buffer = can_checked_malloc(buffer_size);
+ if (!dev->bulk_in_buffer) {
+ CANMSG("Could not allocate bulk_in_buffer");
+ goto error;
+ }
+ }
+ }
+
+ if (!dev->bulk_out_endpointAddr &&
+ usb_endpoint_is_bulk_out(endpoint)) {
+ if (epnum == (endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)){
+ /* we found a bulk out endpoint */
+ dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
+ }
+ }
+
+ }
+ if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
+ CANMSG("Could not find all bulk-in and bulk-out endpoints for chip %d",j);
+ goto error;
+ }
+ }
+
+ usb_get_dev(usbdevs->udev);
+
+ /* save our data pointer in this interface device */
+ usb_set_intfdata(interface, usbdevs);
+
+ usbdevs->candev=register_hotplug_dev("usbcan", usbcan_register_devs,(void *) usbdevs);
+ if (!(usbdevs->candev)){
+ CANMSG("register_hotplug_dev() failed\n");
+ goto register_error;
+ }
+
+ /* let the user know what node this device is now attached to */
+ CANMSG("USBCAN device now attached\n");
+ return 0;
+
+register_error:
+// cleanup_hotplug_dev(usbdevs->candev);
+ usb_put_dev(usbdevs->udev);
+error:
+ if (usbdevs){
+ if (usbdevs->devs){
+ for (j=0;j<usbdevs->count;j++){
+ if (!usbdevs->devs[j]) continue;
+
+ if (usbdevs->devs[j]->bulk_in_buffer)
+ can_checked_free(usbdevs->devs[j]->bulk_in_buffer);
+ if (usbdevs->devs[j]->chip){
+ usbdevs->devs[j]->chip->chip_data=NULL;
+ }
+ can_checked_free(usbdevs->devs[j]);
+ }
+ can_checked_free(usbdevs->devs);
+ }
+ can_checked_free(usbdevs);
+ }
+noalloc:
+ return retval;
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
+void release_device(struct kref *refcount){
+ struct candevice_t *candev = container_of(refcount,struct candevice_t,refcount);
+#else
+void release_device(struct candevice_t *candev){
+#endif
+ struct usbcan_devs *usbdevs = (struct usbcan_devs *)candev->sysdevptr.anydev;
+ int j;
+
+ if (!usbdevs)
+ return;
+
+ cleanup_hotplug_dev(usbdevs->candev);
+
+ if (usbdevs->devs){
+ /* Finally, release all structures in USB subsystem */
+ if (!usbdevs->udev)
+ panic("udev is already null on device release");
+ usb_put_dev(usbdevs->udev);
+
+ for (j=0;j<usbdevs->count;j++){
+ if (!usbdevs->devs[j]) continue;
+
+ if (usbdevs->devs[j]->bulk_in_buffer)
+ can_checked_free(usbdevs->devs[j]->bulk_in_buffer);
+ can_checked_free(usbdevs->devs[j]);
+ usbdevs->devs[j]=NULL;
+ }
+ can_checked_free(usbdevs->devs);
+ }
+ can_checked_free(usbdevs);
+
+ CANMSG("USBCAN now disconnected\n");
+}
+
+// Physically disconnected device
+static void usbcan_disconnect(struct usb_interface *interface)
+{
+ struct usbcan_devs *usbdevs;
+ int j;
+
+ /* prevent more I/O from starting */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+ lock_kernel();
+#endif
+
+ usbdevs = usb_get_intfdata(interface);
+ if (usbdevs==NULL){
+ CANMSG("USBCAN device seems to be already removed\n");
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+ unlock_kernel();
+#endif
+ return;
+ }
+ usb_set_intfdata(interface, NULL);
+ deregister_hotplug_dev(usbdevs->candev);
+
+ for (j=0;j<usbdevs->count;j++){
+ if (!usbdevs->devs[j]) continue;
+ mutex_lock(&usbdevs->devs[j]->io_mutex);
+ usbdevs->devs[j]->interface = NULL;
+ mutex_unlock(&usbdevs->devs[j]->io_mutex);
+ }
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+ unlock_kernel();
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
+ kref_put(&usbdevs->candev->refcount,release_device);
+#else
+ release_device(&usbdevs->candev);
+#endif
+}
+
+int usbcan_init(void){
+ return usb_register(&usbcan_driver);
+}
+
+void usbcan_exit(void){
+ usb_deregister(&usbcan_driver);
+}
--- /dev/null
+# Makefile.rules - OCERA make framework common project rules -*- makefile-gmake -*- #OMK:base.omk
+#
+# (C) Copyright 2003, 2006, 2007, 2008, 2009 by Pavel Pisa - OCERA team member
+# (C) Copyright 2006, 2007, 2008, 2009, 2010, 2011 by Michal Sojka - Czech Technical University, FEE, DCE
+#
+# Homepage: http://rtime.felk.cvut.cz/omk/
+# Version: 0.2-97-g532aeb1
+#
+# The OMK build system is distributed under the GNU General Public
+# License. See file COPYING for details.
+#
+#
+# Version for system-less builds. #OMK:sysless.omk
+#
+#
+# input variables #OMK:base.omk
+# V .. if set to 1, full command text is shown else short form is used
+# W .. whole tree - if set to 1, make is always called from the top-level directory
+# SUBDIRS .. list of subdirectories intended for make from actual directory
+# default_CONFIG .. list of default config assignments CONFIG_XXX=y/n ...
+# LN_HEADERS .. if "y", header files are symbolicaly linked instead of copied. #OMK:include.omk
+# bin_PROGRAMS .. list of the require binary programs #OMK:sysless.omk
+# test_PROGRAMS .. list of the test programs
+# include_HEADERS .. list of the user-space public header files
+# lib_LIBRARIES .. list of the user-space libraries
+# lib_LDSCRIPTS .. list of LD scripts that should be copied to the lib direcotry
+# lib_obj_SOURCES .. list of source files which should be compiled and
+# the produced object file placed to the lib directory (e.g. crt0.S)
+# shared_LIBRARIES .. list of the user-space shared libraries
+# nobase_include_HEADERS .. public headers copied even with directory part
+# renamed_include_HEADERS .. public headers copied to the different target name (xxx.h->yyy.h)
+# utils_PROGRAMS .. list of the development utility programs (compiled for host computer, this might change in future)
+# xxx_SOURCES .. list of specific target sources
+# xxx_LIBS .. list of specific target libraries
+# INCLUDES .. additional include directories and defines for user-space
+# lib_LOADLIBES .. list of libraries linked to each executable
+# link_VARIANTS .. list of ld script suffixes (after hypen `-') that
+# should be used for linking (e.g. ram flash). If this is not
+# specified, then the value of DEFAULT_LD_SCRIPT_VARIANT from config.target is used.
+# PREFIX_DIR .. Prefix to directories in _compiled and _build. Used in config.omk.
+# TARGET_STDSTARTFILES .. if left unset or set to `n', startup file provided
+# by compiler is supressed
+# LOCAL_CONFIG_H .. name of local config.h file generated from values #OMK:config_h.omk
+# of options defined in the current directory
+# config_include_HEADERS .. names of global config files (possibly
+# with subdirectories)
+# xxx_DEFINES .. list of config directives to be included in
+# config header file of the name <somedir>/xxx.h
+# DOXYGEN .. if non-empty, generated headers includes Doxygen's @file
+# command, so it is possible to document config
+# variables.
+# local_EVALUATE .. Makefile hook, which is executed at the end of #OMK:localeval.omk
+# the Makefile.rules. Used only for dirty hacks.
+OMK_RULES_TYPE=sysless #OMK:Makefile.rules.sysless@
+ #OMK:base.omk@Makefile.rules.sysless
+# If we are not called by OMK leaf Makefile...
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(abspath $(dir $(filter %Makefile.rules,$(MAKEFILE_LIST))))
+endif
+
+# The $(SED4OMK) command for BSD based systems requires -E option to allow
+# extended regular expressions
+
+SED4OMK ?= sed
+ifneq ($(shell ( echo A | $(SED4OMK) -n -e 's/A\|B/y/p' )),y)
+ SED4OMK := $(SED4OMK) -E
+ ifneq ($(shell ( echo A | $(SED4OMK) -n -e 's/A\|B/y/p' )),y)
+ SED4OMK := gsed
+ endif
+ ifneq ($(shell ( echo A | $(SED4OMK) -n -e 's/A\|B/y/p' )),y)
+ SED4OMK := gsed -E
+ endif
+ ifneq ($(shell ( echo A | $(SED4OMK) -n -e 's/A\|B/y/p' )),y)
+ $(error No SED program suitable for OMK found)
+ endif
+endif
+
+# OUTPUT_DIR is the place where _compiled, _build and possible other
+# files/directories are created. By default is the same as
+# $(MAKERULES_DIR).
+ifndef OUTPUT_DIR
+OUTPUT_DIR := $(MAKERULES_DIR)
+endif
+
+# We need to ensure definition of sources directory first
+ifndef SOURCES_DIR
+# Only shell built-in pwd understands -L
+SOURCES_DIR := $(shell ( pwd -L ) )
+INVOCATION_DIR := $(SOURCES_DIR:$(OUTPUT_DIR)%=%)
+INVOCATION_DIR := $(INVOCATION_DIR:/%=%)
+INVOCATION_DIR := $(INVOCATION_DIR:\\%=%)
+endif
+
+.PHONY: all default check-make-ver print-hints omkize
+
+ifdef W
+ ifeq ("$(origin W)", "command line")
+ OMK_WHOLE_TREE:=$(W)
+ endif
+endif
+ifndef OMK_WHOLE_TREE
+ OMK_WHOLE_TREE:=0
+endif
+
+ifneq ($(OMK_WHOLE_TREE),1)
+all: check-make-ver print-hints default
+ @echo "Compilation finished"
+else
+# Run make in the top-level directory
+all:
+ @$(MAKE) -C $(MAKERULES_DIR) OMK_SERIALIZE_INCLUDED=n SOURCES_DIR=$(MAKERULES_DIR) RELATIVE_DIR="" $(MAKECMDGOALS) W=0
+endif
+
+# omk-get-var target allows external scripts/programs to determine the
+# values of OMK variables such as RELATIVE_DIR etc.
+.PHONY: omk-get-var
+omk-get-var:
+ @$(foreach var,$(VAR),echo $(var)=$($(var));)
+
+#=========================
+# Include the config file
+
+ifndef CONFIG_FILE
+CONFIG_FILE := $(OUTPUT_DIR)/config.omk
+endif
+
+$(CONFIG_FILE)-default:
+ $(MAKE) default-config
+
+ifeq ($(MAKECMDGOALS),default-config)
+export DEFAULT_CONFIG_PASS=1
+endif
+
+ifneq ($(DEFAULT_CONFIG_PASS),1)
+include $(CONFIG_FILE)-default
+endif
+
+-include $(OUTPUT_DIR)/config.target
+
+ifneq ($(wildcard $(CONFIG_FILE)),)
+-include $(CONFIG_FILE)
+endif
+
+
+CONFIG_FILES ?= $(wildcard $(CONFIG_FILE)-default) $(wildcard $(OUTPUT_DIR)/config.target) $(wildcard $(CONFIG_FILE))
+
+
+export SED4OMK SOURCES_DIR MAKERULES_DIR RELATIVE_DIR INVOCATION_DIR
+export CONFIG_FILE CONFIG_FILES OMK_SERIALIZE_INCLUDED OMK_VERBOSE OMK_SILENT
+# OMK_SERIALIZE_INCLUDED has to be exported to submakes because passes
+# must to be serialized only in the toplevel make.
+
+ifndef RELATIVE_DIR
+RELATIVE_DIR := $(SOURCES_DIR:$(OUTPUT_DIR)%=%)
+endif
+#$(warning === RELATIVE_DIR = "$(RELATIVE_DIR)" ===)
+override RELATIVE_DIR := $(RELATIVE_DIR:/%=%)
+override RELATIVE_DIR := $(RELATIVE_DIR:\\%=%)
+#$(warning RELATIVE_DIR = "$(RELATIVE_DIR)")
+#override BACK2TOP_DIR := $(shell echo $(RELATIVE_DIR)/ | $(SED4OMK) -e 's_//_/_g' -e 's_/\./_/_g' -e 's_^\./__g' -e 's_\([^/][^/]*\)_.._g' -e 's_/$$__')
+#$(warning BACK2TOP_DIR = "$(BACK2TOP_DIR)")
+
+#$(warning SOURCES_DIR = "$(SOURCES_DIR)")
+#$(warning MAKERULES_DIR = "$(OUTPUT_DIR)")
+#$(warning RELATIVE_DIR = "$(RELATIVE_DIR)")
+
+# We have to use RELATIVE_PREFIX because of mingw
+override RELATIVE_PREFIX := $(RELATIVE_DIR)/
+override RELATIVE_PREFIX := $(RELATIVE_PREFIX:/%=%)
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+# Define srcdir for Automake compatibility
+srcdir = $(SOURCES_DIR)
+
+# Defines for quiet compilation
+ifdef V
+ ifeq ("$(origin V)", "command line")
+ OMK_VERBOSE = $(V)
+ endif
+endif
+ifndef OMK_VERBOSE
+ OMK_VERBOSE = 0
+endif
+ifneq ($(OMK_VERBOSE),0)
+ Q =
+else
+ Q = @
+endif
+ifneq ($(findstring s,$(MAKEFLAGS)),)
+ QUIET_CMD_ECHO = true
+ OMK_SILENT = 1
+else
+ QUIET_CMD_ECHO = echo
+endif
+
+MAKEFILE_OMK=Makefile.omk
+# All subdirectories (even linked ones) containing Makefile.omk
+# Usage in Makefile.omk: SUBDIRS = $(ALL_OMK_SUBDIRS)
+ALL_OMK_SUBDIRS = $(patsubst %/$(MAKEFILE_OMK),%,$(patsubst $(SOURCES_DIR)/%,%,$(wildcard $(SOURCES_DIR)/*/$(MAKEFILE_OMK))))
+
+# ===================================================================
+# We have set up all important variables, so we can check and include
+# real OCERA style Makefile.omk now
+ifndef OMK_INCLUDED
+include $(SOURCES_DIR)/$(MAKEFILE_OMK)
+ifeq ($(AUTOMATIC_SUBDIRS),y)
+SUBDIRS?=$(ALL_OMK_SUBDIRS)
+endif
+OMK_INCLUDED := 1
+endif
+
+print-hints:
+ @echo 'Use "make V=1" to see the verbose compile lines.'
+
+check-make-ver:
+ @GOOD_MAKE_VERSION=`echo $(MAKE_VERSION) | $(SED4OMK) -n -e 's/^[4-9]\..*\|^3\.9[0-9].*\|^3\.8[1-9].*/y/p'` ; \
+ if [ x$$GOOD_MAKE_VERSION != xy ] ; then \
+ echo "Your make program version ($(MAKE_VERSION)) is too old and does not support OMK system." ; \
+ echo "Please update to make program 3.81beta1 or newer." ; exit 1 ; \
+ fi
+
+distclean dist-clean:
+ @$(QUIET_CMD_ECHO) " RM $(COMPILED_DIR_NAME) $(BUILD_DIR_NAME)"
+ @rm -fr $(OUTPUT_DIR)/$(COMPILED_DIR_NAME) $(OUTPUT_DIR)/$(BUILD_DIR_NAME)
+
+# Common OMK templates
+# ====================
+
+# Syntax: $(call mkdir,<dir name>)
+define mkdir_def
+ [ -d $(1) ] || mkdir -p $(1) || exit 1
+endef
+
+ifneq ($(OMK_VERBOSE),2)
+NO_PRINT_DIRECTORY := --no-print-directory
+endif
+
+ifeq ($(USE_LEAF_MAKEFILES),n)
+export USE_LEAF_MAKEFILES
+SUBDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+SOURCESDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+else
+SUBDIR_MAKEFILE=$(SOURCES_DIR)/$(3)/Makefile
+SOURCESDIR_MAKEFILE=$(SOURCES_DIR)/Makefile
+endif
+
+pass = $(strip $(1))
+
+unexport SUBDIRS
+
+# Call a pass in a subdirectory
+# Usage: $(call omk_pass_subdir_template,<pass name>,<build dir>,<subdir>)
+define omk_pass_subdir_template
+.PHONY: $(pass)-$(3)-subdir
+$(pass)-submakes: $(pass)-$(3)-subdir
+$(pass)-$(3)-subdir: MAKEOVERRIDES:=$(filter-out SUBDIRS=%,$(MAKEOVERRIDES))
+$(pass)-$(3)-subdir:
+ @$(call mkdir_def,$(2)/$(3))
+ +@$(MAKE) --no-builtin-rules SOURCES_DIR=$(SOURCES_DIR)/$(3) $(NO_PRINT_DIRECTORY) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(3) -C $(2)/$(3) \
+ -f $(SUBDIR_MAKEFILE) $(pass)-submakes
+# In subdirectories we can call submakes directly since passes are
+# already serialized on the toplevel make.
+endef
+
+ifdef OMK_TESTSROOT
+check-target = $(1:%=%-check)
+endif
+
+# Call a pass in a subdirectory
+# Usage: $(call extra_rules_subdir_template,<subdir>)
+define extra_rules_subdir_template
+extra-rules-subdirs: extra-rules-$(1)
+extra-rules-$(1):
+ +@$(MAKE) OMK_SERIALIZE_INCLUDED=n MAKERULES_DIR=$(SOURCES_DIR)/$(1) OUTPUT_DIR=$(OUTPUT_DIR) \
+ SOURCES_DIR=$(SOURCES_DIR)/$(1) RELATIVE_DIR=$(RELATIVE_PREFIX)$(1) -C $(SOURCES_DIR)/$(1)
+endef
+
+.PHONY: extra-rules-subdirs
+extra-rules-subdirs:
+
+$(foreach subdir,$(EXTRA_RULES_SUBDIRS),$(eval $(call extra_rules_subdir_template,$(subdir))))
+
+# Usage: $(call omk_pass_template,<pass name>,<build dir>,[<local make flags>],[<local enable condition>])
+define omk_pass_template
+.PHONY: $(pass) $(pass)-local $(pass)-check $(pass)-submakes
+$(foreach subdir,$(SUBDIRS),$(eval $(call omk_pass_subdir_template,$(pass),$(2),$(subdir))))
+$(pass):
+# Submakes have to be called this way and not as dependecies for pass
+# serialization to work
+ +@$(MAKE) --no-builtin-rules SOURCES_DIR=$(SOURCES_DIR) $(NO_PRINT_DIRECTORY) \
+ RELATIVE_DIR=$(RELATIVE_DIR) \
+ -f $(SOURCESDIR_MAKEFILE) $(pass)-submakes
+$(pass)-submakes:
+ @true # Do not emit "nothing to be done" messages
+
+ifneq ($(4)$($(pass)_HOOKS),)
+$(pass)-submakes: $(pass)-this-dir
+$(pass)-this-dir: $(foreach subdir,$(SUBDIRS),$(pass)-$(subdir)-subdir)
+ +@echo "make[omk]: $(pass) in $(RELATIVE_DIR)"
+ @$(call mkdir_def,$(2))
+ +@$(MAKE) --no-builtin-rules $(NO_PRINT_DIRECTORY) SOURCES_DIR=$(SOURCES_DIR) RELATIVE_DIR=$(RELATIVE_DIR) -C $(2) \
+ -f $(SOURCESDIR_MAKEFILE) $(3) $(check-target) $(1:%=%-local)
+$(pass)-local: $($(pass)_HOOKS)
+endif
+endef
+
+# =======================
+# DEFAULT CONFIG PASS
+
+default-config:
+ @echo "# Start of OMK config file" > "$(CONFIG_FILE)-default"
+ @echo "# This file should not be altered manually" >> "$(CONFIG_FILE)-default"
+ @echo "# Overrides should be stored in file $(notdir $(CONFIG_FILE))" >> "$(CONFIG_FILE)-default"
+ @echo >> "$(CONFIG_FILE)-default"
+ @$(MAKE) $(NO_PRINT_DIRECTORY) -C $(OUTPUT_DIR) \
+ RELATIVE_DIR="" SOURCES_DIR=$(OUTPUT_DIR) \
+ -f $(OUTPUT_DIR)/Makefile default-config-pass
+
+$(eval $(call omk_pass_template,default-config-pass,$$(LOCAL_BUILD_DIR),,always))
+
+default-config-pass-local:
+# @echo Default config for $(RELATIVE_DIR)
+ @echo "# Config for $(RELATIVE_DIR)" >> "$(CONFIG_FILE)-default"
+ @$(foreach x, $(default_CONFIG), echo '$(x)' | \
+ $(SED4OMK) -e 's/^[^=]*=x$$/#\0/' >> "$(CONFIG_FILE)-default" ; )
+
+
+omkize:
+ $(Q)if ! grep -q MAKERULES_DIR Makefile; then \
+ echo "Makefile is not OMK leaf makefile!" >&2; exit 1; \
+ fi
+ $(Q)for i in `find -L . -name Makefile.omk` ; do \
+ d=`dirname $${i}`; \
+ if ! test -f "$${d}/Makefile.rules" && ( test -f "$${d}/Makefile" && ! cmp --silent Makefile "$${d}/Makefile" ); then \
+ rm -f "$${d}/Makefile"; \
+ cp -v Makefile "$${d}/Makefile"; \
+ fi \
+ done
+ #OMK:gcc.omk@Makefile.rules.sysless
+# Rules for compilation of C, C++ and assembler sources using GNU
+# toolchain.
+
+# Interface to other rules:
+
+# Input variables:
+# LIB_DIR - directory where compiled libraries are stored
+# OBJS_DIR - directory where intermediate files (.o, .map, ...) are stored
+# INCLUDE_DIR - where includes can be found
+# from config.omk or Makefile.omk
+# CROSS_COMPILE -
+# TARGET_ARCH, DEBUG, OPTIMIZE, DEFS - forms CFLAGS
+# from base: SOURCES_DIR
+# from Makefile.omk: lib_LOADLIBES
+
+# Output variables:
+# SOURCES - all the source files that needs to be compiled (except for shared library sources)
+# SOLIB_SOURCES - all the source files that needs to be compiled for a shared library
+# OBJ_EXT - extension of object files
+# LIB_EXT - extension of library files
+# LIB_PREF - prefix for library files
+# ASM_EXT - extension of assembler sources
+
+# Templates:
+# COMPILER_DEFS_template - definitions that should be defined before
+# the following templates can be used. The input variables needs to be
+# defined before evaluating this template
+
+# COMPILE_c_o_template, COMPILE_cc_o_template, COMPILE_S_o_template -
+# templates that create rules for compilation of sources
+
+# CMETRIC_o_h_template - FIXME
+
+# PROGRAM_template, LIBRARY_template, SOLIB_template - templates that
+# create rules for compilation of a program, library and shared
+# library. The rules can use rules produced by COMPILE_xxx_template.
+
+define COMPILER_DEFS_template
+OBJ_EXT = .o
+LIB_EXT = .a
+LIB_PREF = lib
+ASM_EXT = .S
+
+CC = $(CROSS_COMPILE)gcc
+LINK = $(CROSS_COMPILE)ld
+AR = $(CROSS_COMPILE)ar
+OBJCOPY = $(CROSS_COMPILE)objcopy
+NM = $(CROSS_COMPILE)nm
+
+CFLAGS += $(TARGET_ARCH) $(DEBUG) $(OPTIMIZE)
+CFLAGS += -Wall
+CFLAGS += -I$(SOURCES_DIR)
+CFLAGS += -I$(INCLUDE_DIR)
+
+LOADLIBES += -L$(LIB_DIR)
+LOADLIBES += $(lib_LOADLIBES:%=-l%)
+
+
+-include $(OBJS_DIR)/*.d
+
+SOURCES2OBJS = .o/.c .o/.cc .o/.cxx .o/.S .o/.o
+
+SOURCES2OBJSLO = .lo/.c .lo/.cc .lo/.cxx .lo/.S .lo/.lo
+
+#%.lo: %.c
+# $(CC) -o $@ $(LCFLAGS) -c $<
+
+c_o_COMPILE = $$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $$(CFLAGS)
+
+cc_o_COMPILE = $$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $$(CFLAGS)
+
+S_o_COMPILE = $$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(CPPFLAGS) $(AM_CFLAGS) $$(CFLAGS) $(ASFLAGS)
+
+
+# Check GCC version for user build
+ifndef CC_MAJOR_VERSION
+CC_MAJOR_VERSION = $$(shell $$(CC) -dumpversion | $(SED4OMK) -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($$(CC_MAJOR_VERSION),2)
+CC_DEPFLAGS = -Wp,-MD,"$$@.d.tmp"
+else
+CC_DEPFLAGS = -MT $$@ -MD -MP -MF "$$@.d.tmp"
+endif
+
+endef # COMPILER_DEFS_template
+
+
+# Syntax: $(call COMPILE_c_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_c_o_template
+$(2): $(1) $$(GEN_HEADERS)
+ @$(QUIET_CMD_ECHO) " CC $$@"
+ $(Q) if $$(c_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+
+# Syntax: $(call COMPILE_cc_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_cc_o_template
+$(2): $(1) $$(GEN_HEADERS)
+ @$(QUIET_CMD_ECHO) " CXX $$@"
+ $(Q) if $$(cc_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+# Syntax: $(call COMPILE_S_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_S_o_template
+$(2): $(1) $$(GEN_HEADERS)
+ @$(QUIET_CMD_ECHO) " AS $$@"
+ $(Q) if $$(S_o_COMPILE) -D__ASSEMBLY__ $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+ then if [ -e "$$@.d.tmp" ] ; then mv -f "$$@.d.tmp" "$$@.d" ; fi ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+# Syntax: $(call CMETRIC_o_h_template,<object_file>,<target_header>)
+define CMETRIC_o_h_template
+$(2): $(1)
+ @$(QUIET_CMD_ECHO) " CMETRIC $$@"
+ $(Q)if [ -n `dirname $$@` ] ; then \
+ if [ ! -e `dirname $$@` ] ; then \
+ mkdir -p `dirname $$@` ; fi ; fi
+ $(Q)echo >$$@.tmp '/* Automatically generated from $$< */'
+ $(Q)echo >>$$@.tmp '/* Conditionals to control compilation */'
+# Bellow, the tricks with redirection are for shells without set -o pipefail
+# (see http://www.mail-archive.com/dash@vger.kernel.org/msg00149.html)
+ $(Q)exec 3>&1; status=`exec 4>&1 >&3; { $(NM) $$<; echo $$$$? >&4; }\
+ | $(SED4OMK) -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2cond_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+ | sort >>$$@.tmp` && exit $$$$status
+ $(Q)echo >>$$@.tmp '/* Defines from the values defined to symbols in hexadecimal format */'
+ $(Q)exec 3>&1; status=`exec 4>&1 >&3; { $(NM) $$<; echo $$$$? >&4; }\
+ | $(SED4OMK) -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2def_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+ | sort >>$$@.tmp` && exit $$$$status
+ $(Q)echo >>$$@.tmp '/* Defines from the values defined to symbols in decimal format */'
+ $(Q)exec 3>&1; status=`exec 4>&1 >&3; { $(NM) -td $$<; echo $$$$? >&4; }\
+ | $(SED4OMK) -n 's/^ *0*\(0\|[1-9][0-9]*\) *A *_cmetric2defdec_\([A-Za-z_0-9]*\) */#define \2 \1/p' \
+ | sort >>$$@.tmp` && exit $$$$status
+ $(Q)mv $$@.tmp $$@
+endef
+
+# Syntax: $(call PROGRAM_template,<executable-name>,<dir>,<link-variant>)
+define PROGRAM_template
+
+GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+ $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+SOURCES += $$($(1)_SOURCES)
+
+ifneq ($(LD_SCRIPT),)
+$(1)$(3:%=-%)_LDFLAGS = -Wl,-T,$(LD_SCRIPT).ld$(3:%=-%)
+endif
+
+$(2)/$(1)$(3:%=-%): $$($(1)_OBJS)
+ @$(QUIET_CMD_ECHO) " LINK $$@"
+ $(Q) $$(shell if [ -z "$$(filter %.cc,$$($(1)_SOURCES))" ] ; \
+ then echo $$(CC) $$(CPPFLAGS) $$(AM_CPPFLAGS) $$(AM_CFLAGS) $$(CFLAGS) ; \
+ else echo $$(CXX) $$(CPPFLAGS) $$(AM_CPPFLAGS) $$(AM_CXXFLAGS) $$(CXXFLAGS) ; fi) \
+ $$(AM_LDFLAGS) $$(LDFLAGS) $$($(1)$(3:%=-%)_LDFLAGS) -Wl,-Map,$(1)$(3:%=-%).map \
+ $$($(1)_OBJS) $$($(1)_MOREOBJS) $$(LOADLIBES) $$($(1)_LIBS:%=-l%) \
+ -o $$@
+ @echo "$(2)/$(1)$(3:%=-%): \\" >$(OBJS_DIR)/$(1)$(3:%=-%).exe.d
+ @if [ -n "$(LD_SCRIPT)" ]; then \
+ echo " $(LIB_DIR)/$(LD_SCRIPT).ld$(3:%=-%) \\" >>$(OBJS_DIR)/$(1)$(3:%=-%).exe.d; fi
+ @$(SED4OMK) -n -e 's|^LOAD \(.*\)$$$$| \1 \&|p' $(OBJS_DIR)/$(1)$(3:%=-%).map|tr '&' '\134' >>$(OBJS_DIR)/$(1)$(3:%=-%).exe.d
+ @echo >>$(OBJS_DIR)/$(1).exe.d
+endef
+
+# Rules for other output formats (can be specified by OUTPUT_FORMATS)
+%.bin: %
+ @$(QUIET_CMD_ECHO) " OBJCOPY $@"
+ $(Q) $(OBJCOPY) --output-target=binary -S $< $@
+
+%.hex: %
+ @$(QUIET_CMD_ECHO) " OBJCOPY $@"
+ $(Q) $(OBJCOPY) --output-target=ihex -S $< $@
+
+%.srec: %
+ @$(QUIET_CMD_ECHO) " OBJCOPY $@"
+ $(Q) $(OBJCOPY) --output-target=srec -S $< $@
+
+# Syntax: $(call LIBRARY_template,<library-name>)
+define LIBRARY_template
+
+GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+ $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+SOURCES += $$($(1)_SOURCES)
+
+$(LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+ @$(QUIET_CMD_ECHO) " AR $$@"
+ $(Q) $(AR) rcs $$@ $$^
+endef
+
+
+# Syntax: $(call SOLIB_template,<library-name>)
+define SOLIB_template
+
+SOLIB_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(SOURCES2OBJSLO),
+$(1)_OBJSLO += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+ $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJSLO := $$(sort $$($(1)_OBJSLO:%/=%))
+
+SOLIB_OBJS += $$($(1)_OBJSLO)
+SOLIB_SOURCES += $$($(1)_SOURCES)
+
+$(LIB_DIR)/lib$(1).so: $$($(1)_OBJSLO)
+ @$(QUIET_CMD_ECHO) " LINK $$@"
+ $(Q) $(LD) --shared --soname=lib$(1).so -o $$@ $$^
+endef
+ifeq ($(OMK_VERBOSE),1) #OMK:include.omk@Makefile.rules.sysless
+CPHEADER_FLAGS += -v
+LNHEADER_FLAGS += -v
+endif
+
+ifneq ($(LN_HEADERS),y)
+define cp_cmd
+if ! cmp --quiet $(1) $(2); then \
+ echo " CP $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; \
+ install -D $(CPHEADER_FLAGS) $(1) $(2) || exit 1; \
+fi
+endef
+else
+define cp_cmd
+if ! cmp --quiet $(1) $(2); then \
+ echo " LN $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; \
+ if [ -f $(1) ]; then d=$(2); mkdir -p $${d%/*} && ln -sf $(LNHEADER_FLAGS) $(1) $(2) || exit 1; else exit 1; fi; \
+fi
+endef
+endif
+
+# TODO: Check modification date of changed header files. If it is
+# newer that in source dir, show a warning.
+
+# Syntax: $(call include-pass-template,<include dir>,<keyword>)
+define include-pass-template
+include-pass-local: include-pass-local-$(2)
+include-pass-local-$(2): $$($(2)_GEN_HEADERS) $$(foreach f,$$(renamed_$(2)_GEN_HEADERS),$$(shell f='$$(f)'; echo $$$${f%->*}))
+ @$$(foreach f, $$($(2)_HEADERS),$$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(notdir $$(f))); )
+# FIXME: Use correct build dir, then document it (in the line bellow)
+ @$$(foreach f, $$($(2)_GEN_HEADERS),$$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$(f),$(1)/$$(notdir $$(f))); )
+ @$$(foreach f, $$(nobase_$(2)_HEADERS), $$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(f)); )
+ @$$(foreach f, $$(renamed_$(2)_HEADERS), \
+ f='$$(f)'; srcfname=$$$${f%->*}; destfname=$$$${f#*->}; \
+ $$(call cp_cmd,$$(SOURCES_DIR)/$$$${srcfname},$(1)/$$$${destfname}); )
+ @$$(foreach f, $$(renamed_$(2)_GEN_HEADERS), \
+ f='$$(f)'; srcfname=$$$${f%->*}; destfname=$$$${f#*->}; \
+ $$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$$${srcfname},$(1)/$$$${destfname}); )
+# Suppress "Nothing to be done for `include-pass-local'" message if no headers are defined in Makefile.omk
+ @$$(if $$($(2)_HEADERS)$$($(2)_GEN_HEADERS)$$(nobase_$(2)_HEADERS)$$(renamed_$(2)_HEADERS)$$(renamed_$(2)_GEN_HEADERS),,true)
+endef
+ #OMK:sysless.omk@Makefile.rules.sysless
+BUILD_DIR_NAME = _build$(addprefix /,$(PREFIX_DIR))
+COMPILED_DIR_NAME = _compiled$(addprefix /,$(PREFIX_DIR))
+
+LOCAL_BUILD_DIR=$(MAKERULES_DIR)/$(BUILD_DIR_NAME)/$(RELATIVE_DIR)
+#$(warning LOCAL_BUILD_DIR = $(LOCAL_BUILD_DIR))
+
+#=====================================================================
+# Common utility rules
+
+link_VARIANTS ?= $(DEFAULT_LD_SCRIPT_VARIANT)
+
+
+#=====================================================================
+# Include correct rules for just running pass
+
+USER_COMPILED_DIR_NAME=$(MAKERULES_DIR)/$(COMPILED_DIR_NAME)
+
+USER_INCLUDE_DIR = $(USER_COMPILED_DIR_NAME)/include
+USER_LIB_DIR = $(USER_COMPILED_DIR_NAME)/lib
+USER_UTILS_DIR = $(USER_COMPILED_DIR_NAME)/bin-utils
+USER_TESTS_DIR = $(USER_COMPILED_DIR_NAME)/bin-tests
+USER_BIN_DIR = $(USER_COMPILED_DIR_NAME)/bin
+USER_OBJS_DIR = $(LOCAL_BUILD_DIR)
+
+.PHONY: check-dir
+
+# Some support to serialize some targets for parallel make
+ifneq ($(OMK_SERIALIZE_INCLUDED),y)
+include-pass: check-dir
+library-pass: include-pass
+binary-pass utils-pass: library-pass
+
+override OMK_SERIALIZE_INCLUDED = y
+MAKEOVERRIDES := $(filter-out OMK_SERIALIZE_INCLUDED=n,$(MAKEOVERRIDES))
+endif
+
+# -------------------------------------
+# Rules for compilation for target
+ifdef TARGET_RULE_TEMPLATES
+
+ifeq ($(TARGET_STDSTARTFILES),)
+TARGET_STDSTARTFILES=n
+endif
+
+ifneq ($(TARGET_STDSTARTFILES),y)
+LDFLAGS += -nostartfiles
+ifneq ($(TARGET_STDSTARTFILES),n)
+LDFLAGS += $(TARGET_STDSTARTFILES)
+endif
+endif
+
+# FIXME: These are not used. What they are good for?
+LIB_CPPFLAGS += $(CPPFLAGS)
+LIB_CFLAGS += $(CFLAGS)
+
+SOLIB_PICFLAGS += -shared -fpic
+
+CFLAGS += -DOMK_FOR_TARGET
+
+INCLUDE_DIR := $(USER_INCLUDE_DIR)
+LIB_DIR := $(USER_LIB_DIR)
+OBJS_DIR := $(USER_OBJS_DIR)
+
+$(eval $(COMPILER_DEFS_template))
+
+# Special rules for CMETRIC generated headers
+
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call COMPILE_c_o_template,\
+ $(SOURCES_DIR)/$($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES),\
+ $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),)))
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call CMETRIC_o_h_template,\
+ $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),\
+ $(addprefix $(USER_INCLUDE_DIR)/,$(cmetrh)))))
+
+GEN_HEADERS+=$(cmetric_include_HEADERS:%=$(USER_INCLUDE_DIR)/%)
+
+# Generate rules for compilation of programs and libraries
+ifneq ($(link_VARIANTS),)
+$(foreach prog,$(bin_PROGRAMS),$(foreach link,$(link_VARIANTS),$(eval $(call PROGRAM_template,$(prog),$(USER_BIN_DIR),$(link)))))
+$(foreach prog,$(test_PROGRAMS),$(foreach link,$(link_VARIANTS),$(eval $(call PROGRAM_template,$(prog),$(USER_TESTS_DIR),$(link)))))
+else
+$(foreach prog,$(bin_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_BIN_DIR))))
+$(foreach prog,$(test_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_TESTS_DIR))))
+endif
+
+$(foreach lib,$(lib_LIBRARIES),$(eval $(call LIBRARY_template,$(lib))))
+$(foreach src,$(lib_obj_SOURCES),$(eval $(call LIBOBJ_template,$(addsuffix $(OBJ_EXT),$(basename $(src))))))
+$(foreach lib,$(shared_LIBRARIES),$(eval $(call SOLIB_template,$(lib))))
+
+
+# lib_obj_SOURCES handling
+lib_OBJS = $(addsuffix $(OBJ_EXT),$(basename $(lib_obj_SOURCES)))
+#$(warning lib_OBJS = $(lib_OBJS))
+SOURCES += $(filter-out %$(OBJ_EXT),$(lib_obj_SOURCES))
+
+$(LIB_DIR)/%$(OBJ_EXT): %$(OBJ_EXT)
+ @echo " CP $(^:$(MAKERULES_DIR)/%=%) -> $(@:$(MAKERULES_DIR)/%=%)"
+ $(Q)cp $(CP_FLAGS) $< $@
+
+
+# User-space static libraries and applications object files
+SOURCES := $(sort $(SOURCES))
+#$(warning SOURCES = $(SOURCES))
+GEN_SOURCES := $(sort $(GEN_SOURCES))
+
+# User-space shared libraries object files
+SOLIB_SOURCES := $(sort $(SOLIB_SOURCES))
+#$(warning SOLIB_SOURCES = $(SOLIB_SOURCES))
+SOLIB_GEN_SOURCES := $(sort $(SOLIB_GEN_SOURCES))
+
+# Create _build directories for sources in subdirectories i.e. *_SOURCES=dir/file.c
+_dirs_to_create=$(filter-out ./,$(sort $(dir $(SOURCES) $(SOLIB_SOURCES))))
+ifneq ($(_dirs_to_create),)
+$(shell mkdir -p $(addprefix $(LOCAL_BUILD_DIR)/,$(_dirs_to_create)))
+endif
+
+# The above generated rules produced $(SOURCES) and $(SOLIB_SOURCES)
+# variables. Now generate rules for compilation of theese sources
+$(foreach src,$(filter %.c,$(SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%$(OBJ_EXT)),)))
+$(foreach src,$(filter %.cc,$(SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%$(OBJ_EXT)),)))
+$(foreach src,$(filter %.cxx,$(SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%$(OBJ_EXT)),)))
+$(foreach src,$(filter %$(ASM_EXT),$(SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%$(ASM_EXT)=%$(OBJ_EXT)),)))
+$(foreach src,$(filter %.c,$(GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.c,$(SOLIB_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+$(foreach src,$(filter %.cc,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.lo),$(SOLIB_PICFLAGS))))
+$(foreach src,$(filter %.cxx,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.lo),$(SOLIB_PICFLAGS))))
+$(foreach src,$(filter %$(ASM_EXT),$(SOLIB_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%$(ASM_EXT)=%.lo),$(SOLIB_PICFLAGS))))
+$(foreach src,$(filter %.c,$(SOLIB_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+library-pass-local: $(addprefix $(USER_INCLUDE_DIR)/,$(cmetric_include_HEADERS)) \
+ $(lib_LIBRARIES:%=$(LIB_DIR)/$(LIB_PREF)%$(LIB_EXT)) $(shared_LIBRARIES:%=$(LIB_DIR)/$(LIB_PREF)%.so) \
+ $(addprefix $(LIB_DIR)/,$(lib_OBJS))
+
+ifneq ($(link_VARIANTS),)
+binary-pass-local: $(foreach link,$(link_VARIANTS),$(bin_PROGRAMS:%=$(USER_BIN_DIR)/%-$(link)) $(test_PROGRAMS:%=$(USER_TESTS_DIR)/%-$(link)) \
+ $(foreach of,$(OUTPUT_FORMATS),$(bin_PROGRAMS:%=$(USER_BIN_DIR)/%-$(link).$(of)) $(test_PROGRAMS:%=$(USER_TESTS_DIR)/%-$(link).$(of))))
+else
+binary-pass-local: $(bin_PROGRAMS:%=$(USER_BIN_DIR)/%) $(test_PROGRAMS:%=$(USER_TESTS_DIR)/%) \
+ $(foreach of,$(OUTPUT_FORMATS),$(bin_PROGRAMS:%=$(USER_BIN_DIR)/%.$(of)) $(test_PROGRAMS:%=$(USER_TESTS_DIR)/%.$(of)))
+endif
+
+endif # TARGET_RULE_TEMPLATES
+
+
+# -------------------------------------
+# Rules for compilation utilities for host (user space)
+ifdef HOST_RULE_TEMPLATES
+
+CROSS_COMPILE =
+TARGET_ARCH =
+
+SOLIB_PICFLAGS += -shared -fpic
+
+# For host compilation, we don't use a specfic ld script
+LD_SCRIPT =
+
+# TODO: It is probably better to use different directories for host
+# includes, libraries and objects
+INCLUDE_DIR := $(USER_INCLUDE_DIR)
+LIB_DIR := $(USER_LIB_DIR)
+OBJS_DIR := $(USER_OBJS_DIR)
+
+$(eval $(COMPILER_DEFS_template))
+
+ #User-space static libraries and applications object files
+#SOURCES := $(sort $(SOURCES))
+#$(warning SOURCES = $(SOURCES))
+
+# Generate rules for compilation of utility programs
+$(foreach prog,$(utils_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_UTILS_DIR),)))
+
+# The above generated rule produced $(SOURCES) variable. Now generate
+# rules for compilation of theese sources
+$(foreach src,$(filter %.c,$(SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%$(OBJ_EXT)),)))
+$(foreach src,$(filter %.cc,$(SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%$(OBJ_EXT)),)))
+$(foreach src,$(filter %.cxx,$(SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%$(OBJ_EXT)),)))
+$(foreach src,$(filter %$(ASM_EXT),$(SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%$(ASM_EXT)=%$(OBJ_EXT)),)))
+
+utils-pass-local: $(utils_PROGRAMS:%=$(USER_UTILS_DIR)/%)
+
+endif # HOST_RULE_TEMPLATES
+
+#=====================================================================
+# Automatic loading of compiled program by issuing "make load"
+
+ifneq ($(OUTPUT_FORMATS),)
+# Select a file extension (e.g. .bin) for "make load" command to load.
+LOAD_EXTENSION = .$(firstword $(OUTPUT_FORMATS))
+endif
+
+# Syntax: $(call LOAD_PROGRAM_template,<executable-name>,<dir>,<link-variant>)
+# Used to load program to the target hardware
+define LOAD_PROGRAM_template
+.PHONY: load-$(1)$(3:%=-%)
+load-$(1)$(3:%=-%): $(2)/$(1)$(3:%=-%)$(if $(LOAD_EXTENSION-$(3)),$(LOAD_EXTENSION-$(3)),$(LOAD_EXTENSION))
+ @$(QUIET_CMD_ECHO) " LOAD $$<"
+ @if [ -z '$$(LOAD_CMD$(3:%=-%))' ]; then echo "No command for loading applications to '$(3)' is specified."; exit 1; fi
+ $(Q) $$(LOAD_CMD$(3:%=-%)) $$<
+endef
+
+# Syntax: $(call LOAD__RUN_VARIANT_template,<link-variant>)
+# Used to load and/or run non-default variant of the default program
+define LOAD_RUN_VARIANT_template
+.PHONY: load-$(1) run-$(1)
+
+load-$(1): load-$(firstword $(bin_PROGRAMS) $(test_PROGRAMS))-$(1)
+
+run-$(1):
+ @$(QUIET_CMD_ECHO) " RUN $(1)"
+ @if [ -z "$(RUN_CMD-$(1))" ]; then echo "No command for running '$(1)' variant is specified."; exit 1; fi
+ $(Q) $(RUN_CMD-$(1))
+
+endef
+
+$(foreach link,$(link_VARIANTS),$(foreach prog,$(bin_PROGRAMS),$(eval $(call LOAD_PROGRAM_template,$(prog),$(USER_BIN_DIR),$(link)))))
+$(foreach link,$(link_VARIANTS),$(foreach prog,$(test_PROGRAMS),$(eval $(call LOAD_PROGRAM_template,$(prog),$(USER_TESTS_DIR),$(link)))))
+$(foreach link,$(link_VARIANTS),$(eval $(call LOAD_RUN_VARIANT_template,$(link))))
+
+.PHONY: load run
+load: $(addprefix load-,$(firstword $(bin_PROGRAMS) $(test_PROGRAMS))-$(firstword $(link_VARIANTS)))
+
+run: run-$(firstword $(link_VARIANTS))
+
+
+
+#=====================================================================
+# Generate pass rules from generic templates
+
+$(eval $(call omk_pass_template, include-pass, $(LOCAL_BUILD_DIR),,$(include_HEADERS)$(nobase_include_HEADERS)$(renamed_include_HEADERS)$(lib_LDSCRIPTS)$(config_include_HEADERS)$(LOCAL_CONFIG_H)))
+$(eval $(call omk_pass_template, library-pass, $(LOCAL_BUILD_DIR),TARGET_RULE_TEMPLATES=y,$(lib_LIBRARIES)$(shared_LIBRARIES)$(lib_obj_SOURCES)))
+$(eval $(call omk_pass_template, binary-pass, $(LOCAL_BUILD_DIR),TARGET_RULE_TEMPLATES=y,$(bin_PROGRAMS) $(test_PROGRAMS)))
+$(eval $(call omk_pass_template, utils-pass, $(LOCAL_BUILD_DIR),HOST_RULE_TEMPLATES=y,$(utils_PROGRAMS)))
+$(eval $(call omk_pass_template, dep, $(LOCAL_BUILD_DIR),,always))
+$(eval $(call omk_pass_template, clean, $(LOCAL_BUILD_DIR),,always))
+$(eval $(call omk_pass_template, install,$(LOCAL_BUILD_DIR),,always))
+
+
+dep-local:
+
+install-local:
+
+$(eval $(call include-pass-template,$(USER_INCLUDE_DIR),include))
+
+include-pass-local:
+ @$(foreach f, $(lib_LDSCRIPTS), cmp --quiet $(SOURCES_DIR)/$(f) $(USER_LIB_DIR)/$(notdir $(f)) \
+ || $(call cp_cmd,$(SOURCES_DIR)/$(f),$(USER_LIB_DIR)/$(notdir $(f))) || exit 1 ; )
+
+
+.PHONY: clean-custom
+clean-local: clean-custom
+ $(Q)rm -f $(USER_OBJS_DIR)/*.o $(USER_OBJS_DIR)/*.lo \
+ $(USER_OBJS_DIR)/*.d \
+ $(USER_OBJS_DIR)/*.map \
+ $(LOCAL_CONFIG_H:%=$(USER_OBJS_DIR)/%)
+
+check-dir::
+ @$(call mkdir_def,$(USER_INCLUDE_DIR))
+ @$(call mkdir_def,$(USER_LIB_DIR))
+ @$(call mkdir_def,$(USER_BIN_DIR))
+ @$(call mkdir_def,$(USER_UTILS_DIR))
+ @$(call mkdir_def,$(USER_TESTS_DIR))
+
+include-pass-submakes: extra-rules-subdirs
+# Which passes to pass
+default: include-pass library-pass binary-pass utils-pass
+ #OMK:config_h.omk@Makefile.rules.sysless
+# Syntax: $(call BUILD_CONFIG_H_template,<stamp_dir>,<header_file_path>,<list_of_options_to_export>,<header_barrier>)
+define BUILD_CONFIG_H_template
+
+$(addprefix $(1)/,$(notdir $(addsuffix .stamp,$(2)))) : $(CONFIG_FILES)
+ @$(QUIET_CMD_ECHO) " CONFGEN $(notdir $(2))"
+ @if [ ! -d `dirname $(2).tmp` ] ; then \
+ mkdir -p `dirname $(2).tmp` ; fi
+ @echo "/* Automatically generated from */" > "$(2).tmp"
+ @echo "/* config files: $$(^:$(OUTPUT_DIR)/%=%) */" >> "$(2).tmp"
+ $(if $(DOXYGEN),@echo "/** @file */" >> "$(2).tmp")
+ @echo "#ifndef $(4)" >> "$(2).tmp"
+ @echo "#define $(4)" >> "$(2).tmp"
+ @( $(foreach x, $(shell echo '$($(3))' | tr 'x\t ' 'x\n\n' | $(SED4OMK) -e 's/^\([^ =]*\)\(=[^ ]\+\|\)$$/\1/' ), \
+ echo '$(x).$($(x))' ; ) echo ; ) | \
+ $(SED4OMK) -e '/^[^.]*\.n$$$$/d' -e '/^[^.]*\.$$$$/d' -e 's/^\([^.]*\)\.[ym]$$$$/\1.1/' | \
+ $(SED4OMK) -n -e 's/^\([^.]*\)\.\(.*\)$$$$/#define \1 \2/p' \
+ >> "$(2).tmp"
+ @echo "#endif /*$(4)*/" >> "$(2).tmp"
+ @touch "$$@"
+ @if cmp --quiet "$(2).tmp" "$(2)" ; then rm "$(2).tmp"; \
+ else mv "$(2).tmp" "$(2)" ; \
+ echo "Updated configuration $(2)" ; fi
+
+endef
+
+ifdef LOCAL_CONFIG_H
+
+# This must be declared after the default cflags are assigned!
+# Override is used to override command line assignemnt.
+override CFLAGS += -I $(USER_OBJS_DIR)
+override kernel_INCLUDES += -I $(KERN_OBJS_DIR)
+$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(USER_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+
+endif
+
+# Special rules for configuration exported headers
+
+#FIXME: The directory for headers should not be specified here.
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(addprefix $(USER_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+config_h_stamp_files = $(addprefix $(USER_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(config_h_stamp_files)
+
+ifneq ($(KERN_CONFIG_HEADERS_REQUIRED),)
+
+ifdef LOCAL_CONFIG_H
+$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(KERN_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+endif
+
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(addprefix $(KERN_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+kern_config_h_stamp_files = $(addprefix $(KERN_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(kern_config_h_stamp_files)
+
+endif
+
+clean-local: clean-local-config-h
+
+clean-local-config-h:
+ @$(foreach confh,$(config_h_stamp_files) $(kern_config_h_stamp_files),\
+ if [ -e $(confh) ] ; then rm $(confh) ; fi ; \
+ )
+ #OMK:sources-list.omk@Makefile.rules.sysless
+# Rules that creates the list of files which are used during
+# compilation. The list reflects conditional compilation depending on
+# config.omk and other variables.
+
+SOURCES_LIST_FN=sources.txt
+ifndef SOURCES_LIST
+SOURCES_LIST_DIR:=$(RELATIVE_DIR)
+SOURCES_LIST:=$(OUTPUT_DIR)/$(SOURCES_LIST_DIR)/$(SOURCES_LIST_FN)
+SOURCES_LIST_D := $(LOCAL_BUILD_DIR)/$(SOURCES_LIST_FN).d
+export SOURCES_LIST SOURCES_LIST_DIR SOURCES_LIST_D
+endif
+
+ifneq ($(filter sources-list TAGS tags cscope,$(MAKECMDGOALS)),)
+NEED_SOURCES_LIST=y
+endif
+
+ifeq ($(NEED_SOURCES_LIST),y) # avoid execution of find command bellow if it is not useful
+.PHONY: sources-list
+sources-list: $(SOURCES_LIST)
+
+$(SOURCES_LIST): $(CONFIG_FILES) $(shell find -name $(MAKEFILE_OMK))
+ @$(call mkdir_def,$(dir $(SOURCES_LIST_D)))
+ @echo -n "" > "$(SOURCES_LIST).tmp"
+ @echo -n "" > "$(SOURCES_LIST_D).tmp"
+ @$(MAKE) --no-print-directory sources-list-pass
+ @echo "# Automatically generated list of files in '$(RELATIVE_DIR)' that are used during OMK compilation" > "$(SOURCES_LIST).tmp2"
+ @cat "$(SOURCES_LIST).tmp"|sort|uniq >> "$(SOURCES_LIST).tmp2"
+ @rm "$(SOURCES_LIST).tmp"
+ @mv "$(SOURCES_LIST).tmp2" "$(SOURCES_LIST)"
+ @echo "$(SOURCES_LIST): \\" > "$(SOURCES_LIST_D).tmp2"
+ @cat "$(SOURCES_LIST_D).tmp"|grep -v "$(SOURCES_LIST_D).tmp"|sort|uniq|\
+ $(SED4OMK) -e 's/$$/\\/' >> "$(SOURCES_LIST_D).tmp2"
+ @rm "$(SOURCES_LIST_D).tmp"
+ @mv "$(SOURCES_LIST_D).tmp2" "$(SOURCES_LIST_D)"
+endif
+
+$(eval $(call omk_pass_template,sources-list-pass,$$(LOCAL_BUILD_DIR),,always))
+
+sources-list-pass-local:
+ @$(foreach m,$(MAKEFILE_LIST),echo ' $(m)' >> "$(SOURCES_LIST_D).tmp";)
+ @$(foreach h,$(include_HEADERS) $(nobase_include_HEADERS) $(kernel_HEADERS),\
+ echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(h)" >> "$(SOURCES_LIST).tmp";)
+ @$(foreach ch,$(config_include_HEADERS), \
+ echo "$(USER_INCLUDE_DIR:$(OUTPUT_DIR)/$(addsuffix /,$(SOURCES_LIST_DIR))%=%)/$(ch)" >> "$(SOURCES_LIST).tmp";)
+ @$(foreach h,$(renamed_include_HEADERS),echo '$(h)'|$(SED4OMK) -e 's|\(.*\)->.*|$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))\1|' >> "$(SOURCES_LIST).tmp";)
+ @$(foreach bin,$(lib_LIBRARIES) $(shared_LIBRARIES) $(bin_PROGRAMS) $(test_PROGRAMS) $(utils_PROGRAMS) \
+ $(kernel_LIBRARIES) $(rtlinux_LIBRARIES) $(kernel_MODULES),\
+ $(foreach src,$(filter-out %.o,$($(bin)_SOURCES)),echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(src)" >> "$(SOURCES_LIST).tmp";))
+
+############ TAGS ###########
+
+ifeq ($(MAKECMDGOALS),TAGS)
+ETAGS=etags
+TAGS_CMD = $(ETAGS)
+TAGS: $(SOURCES_LIST)
+ @$(MAKE) --no-print-directory do-tags
+endif
+ifeq ($(MAKECMDGOALS),tags)
+CTAGS=ctags -N
+TAGS_CMD = $(CTAGS)
+tags: $(SOURCES_LIST)
+ @$(MAKE) --no-print-directory do-tags
+endif
+export TAGS_CMD
+
+ifeq ($(MAKECMDGOALS),do-tags)
+.PHONY: do-tags
+do-tags: $(shell $(SED4OMK) -e '/^\#/d' $(SOURCES_LIST))
+ @$(QUIET_CMD_ECHO) " TAGS $(SOURCES_LIST_FN)"
+ $(Q)$(TAGS_CMD) $^
+endif
+
+############ CSCOPE ###########
+
+cscope: $(SOURCES_LIST)
+ @$(QUIET_CMD_ECHO) " CSCOPE < $(SOURCES_LIST_FN)"
+ $(Q)$(SED4OMK) -e '/^#/d' $(SOURCES_LIST) > cscope.files
+ $(Q)cscope -b -icscope.files
+#FIXME: see doc to -i in cscope(1)
+ #OMK:localeval.omk@Makefile.rules.sysless
+ifneq ($(local_EVALUATE),)
+#$(warning $(local_EVALUATE))
+$(eval $(local_EVALUATE))
+endif