--- /dev/null
+[submodule "submodule/pxmc"]
+ path = submodule/pxmc
+ url = http://www.pikron.com/pxmc/git/pxmc.git
+[submodule "submodule/ulut"]
+ path = submodule/ulut
+ url = git://git.code.sf.net/p/ulan/ulut
--- /dev/null
+_build
+_compiled
+config.omk-default
--- /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 = libs4c system_opt app
+
--- /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, 2013 by Michal Sojka - Czech Technical University, FEE, DCE
+#
+# Homepage: http://rtime.felk.cvut.cz/omk/
+# Version: 0.2-161-g098e555
+#
+# The OMK build system is distributed under the GNU General Public
+# License. See file COPYING for details.
+#
+#
+# Version for Linux/RTLinux builds. #OMK:linux.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 ...
+# wvtest_SCRIPTS .. list of scripts producing wvtest output #OMK:wvtest.omk
+# wvtest_PROGRAMS .. list of the testing programs producing wvtest output
+# LN_HEADERS .. if "y", header files are symbolicaly linked instead of copied. #OMK:include.omk
+# input variables #OMK:linux.omk
+# lib_LIBRARIES .. list of the user-space libraries
+# shared_LIBRARIES .. list of the user-space shared libraries
+# include_HEADERS .. list of the user-space public header files
+# nobase_include_HEADERS .. public headers copied even with directory part
+# renamed_include_HEADERS .. public headers copied to the different target name
+# bin_PROGRAMS .. list of the require binary programs
+# utils_PROGRAMS .. list of the development utility programs
+# test_PROGRAMS .. list of the testing programs
+# bin_SCRIPTS .. list of scripts to be copied to _compiled/bin
+# xxx_SOURCES .. list of specific target sources
+# xxx_GEN_SOURCES .. list of specific target sources that are generated in the build directory
+# xxx_LIBS .. list of specific target libraries (-l prefix is automatically added)
+# xxx_LDFLAGS .. list of specific target LDFLAGS
+# lib_LOADLIBES .. list of libraries linked to each executable
+# INCLUDES .. additional include directories and defines for user-space
+#
+# OMK_CFLAGS .. C compiler flags
+# OMK_CXXFLAGS .. C++ compiler flags
+# OMK_CPPFLAGS .. C preprocessor flags
+# LDFLAGS .. linker flags for programs linking
+# kernel_LIBRARIES .. list of the kernel-space libraries #OMK:linux-kernel.omk
+# rtlinux_LIBRARIES.. list of the RT-Linux kernel-space libraries
+# kernel_HEADERS .. list of the kernel-space public header files
+# rtlinux_HEADERS .. list of the RT-Linux kernel-space public header files
+# kernel_MODULES .. list of the kernel side modules/applications
+# rtlinux_MODULES .. list of RT-Linux the kernel side modules/applications
+# kernel_INCLUDES .. additional include directories and defines for kernel-space
+# rtlinux_INCLUDES .. additional include directories and defines for RT-Linux
+# OMIT_KERNEL_PASSES if defined, all kernel passes are omited
+# LINUX_DIR .. location of Linux kernel sources
+# RTL_DIR .. location of RT-Linux sources
+# cmetric_include_HEADERS .. generate header file with offsets and sizes of structure fields #OMK:cmetric.omk
+# xxx_CMETRIC_SOURCES .. the source cmetric generation
+# 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.
+# QT_PROJECTS .. list of QT .pro file to use for compilation #OMK:qt.omk
+# QT_SUBDIRS .. subdirectories where to build QT applications using qmake (depricated)
+# QTDIR .. where QT resides
+OMK_RULES_TYPE=linux #OMK:Makefile.rules.linux@
+ #OMK:base.omk@Makefile.rules.linux
+# 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)
+ifneq ($(pass),clean)
+$(pass)-local: $($(pass)_HOOKS)
+endif
+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" && ! cmp -s Makefile "$${d}/Makefile"; then \
+ rm -f "$${d}/Makefile"; \
+ cp -v Makefile "$${d}/Makefile"; \
+ fi \
+ done
+ #OMK:wvtest.omk@Makefile.rules.linux
+ifndef WVTEST_LIBRARY
+WVTEST_LIBRARY = wvtest
+endif
+
+# Documentation: wvtest_PROGRAMS is amost equivalent to test_PROGRAMS.
+# The two differences are that the program is automatically linked
+# with $(WVTEST_LIBRARY) and it is run during "make wvtest".
+test_PROGRAMS += $(wvtest_PROGRAMS)
+
+# Documentation: If your project uses wvtest, it is recomended to put
+# the "test: wvtest" rule to config.target.
+wvtest:
+ $(Q)$(MAKERULES_DIR)/wvtestrun $(MAKE) wvtest-pass
+
+.PHONY: wvtest
+
+$(eval $(call omk_pass_template,wvtest-pass,$$(LOCAL_BUILD_DIR),,$(wvtest_SCRIPTS)$(wvtest_PROGRAMS)))
+
+# Usage: $(call wvtest_template,<shell command>)
+define wvtest_template
+wvtest-pass-local: wvtest-run-$(1)
+.PHONY: wvtest-run-$(1)
+wvtest-run-$(1):
+ $(Q)echo "Testing \"Run $(1)\" in Makefile.rules:"
+ $(Q)mkdir -p $(1).wvtest
+ $(Q)cd $(1).wvtest && \
+ PATH=$$(USER_BIN_DIR):$$$$PATH LD_LIBRARY_PATH=$$(USER_LIB_DIR):$$$$LD_LIBRARY_PATH \
+ $(1)
+$(notdir $(1))_LIBS += $$(WVTEST_LIBRARY)
+endef
+
+# Documentation: Write the test so, that it can be run from arbitrary
+# directory, i.e. in case of a script ensure that the wvtest library
+# is sourced like this:
+#
+# . $(dirname $0)/wvtest.sh
+
+$(foreach script,$(wvtest_SCRIPTS),$(eval $(call wvtest_template,$(SOURCES_DIR)/$(script))))
+# Hack!!!
+USER_TESTS_DIR := $(OUTPUT_DIR)/_compiled/bin-tests
+$(foreach prog,$(wvtest_PROGRAMS),$(eval $(call wvtest_template,$(USER_TESTS_DIR)/$(prog))))
+ifeq ($(OMK_VERBOSE),1) #OMK:include.omk@Makefile.rules.linux
+CPHEADER_FLAGS += -v
+LNHEADER_FLAGS += -v
+endif
+
+ifneq ($(LN_HEADERS),y)
+define cp_cmd
+if ! cmp -s $(1) $(2); then \
+ echo " CP $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; \
+ install -d $(CPHEADER_FLAGS) `dirname $(2)` && \
+ install $(CPHEADER_FLAGS) $(1) $(2) || exit 1; \
+fi
+endef
+else
+define cp_cmd
+if ! cmp -s $(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:linux.omk@Makefile.rules.linux
+BUILD_DIR_NAME = _build
+COMPILED_DIR_NAME = _compiled
+ifndef GROUP_DIR_NAME
+GROUP_DIR_NAME = nogroup
+endif
+
+USER_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include
+USER_LIB_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib
+USER_UTILS_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-utils
+USER_TESTS_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-tests
+USER_BIN_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin
+USER_BUILD_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/user
+
+ifeq ($(BUILD_OS),)
+ # Check for target
+ ifeq ($(OS),Windows_NT)
+ BUILD_OS := win32
+ else
+ BUILD_OS := $(shell uname | tr '[A-Z]' '[a-z]' )
+ #$(warning BUILD_OS=$(BUILD_OS))
+ endif
+endif
+
+ifeq ($(TARGET_OS),)
+ TARGET_OS := $(BUILD_OS)
+endif
+
+export TARGET_OS
+export BUILD_OS
+
+LOCAL_BUILD_DIR = $(USER_OBJS_DIR)
+
+# Assign default values to CFLAGS variable. If the variable is defined
+# earlier (i.g. in config.omk), it is not overriden here.
+CFLAGS ?= -O2 -Wall
+CXXFLAGS ?= -O2 -Wall
+
+
+CPPFLAGS += -I $(USER_INCLUDE_DIR)
+
+LOADLIBES += -L$(USER_LIB_DIR)
+
+LOADLIBES += $(lib_LOADLIBES:%=-l%)
+
+LIB_CPPFLAGS += $(CPPFLAGS)
+LIB_CFLAGS += $(CFLAGS)
+
+ifeq ($(TARGET_OS),win32)
+ EXE_SUFFIX = .exe
+ SOLIB_EXT = dll
+else
+ SOLIB_EXT = so
+ SOLIB_PICFLAGS += -fpic
+endif
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+USER_OBJS_DIR = $(USER_BUILD_DIR)/$(RELATIVE_DIR)
+OMK_WORK_DIR = $(USER_OBJS_DIR)
+
+.PHONY: dep subdirs clean clean-custom cleandepend check-dir
+
+# Some support to serialize some targets for parallel make
+ifneq ($(OMK_SERIALIZE_INCLUDED),y)
+include-pass: check-dir
+library-pass: include-pass
+link-pseudo-pass: library-pass
+binary-pass: link-pseudo-pass
+
+override OMK_SERIALIZE_INCLUDED = y
+MAKEOVERRIDES := $(filter-out OMK_SERIALIZE_INCLUDED=n,$(MAKEOVERRIDES))
+endif
+
+#=====================================================================
+# User-space rules and templates to compile programs, libraries etc.
+
+ifdef USER_RULE_TEMPLATES
+
+c_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(OMK_CPPFLAGS) \
+ $(CPPFLAGS) $(OMK_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+cc_o_COMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(OMK_CPPFLAGS) \
+ $(CPPFLAGS) $(OMK_CFLAGS) $(CFLAGS) $(OMK_CXXFLAGS) $(CXXFLAGS) -DOMK_FOR_USER
+
+S_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(OMK_CPPFLAGS) \
+ $(CPPFLAGS) $(OMK_CFLAGS) $(CFLAGS) $(ASFLAGS) -DOMK_FOR_USER
+
+idl_COMPILE = $(IDL_COMPILER)
+
+# 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
+
+
+# Syntax: $(call COMPILE_c_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_c_o_template
+ifeq ($$($(2)_C_TARGET),)
+$(2)_C_TARGET=1
+$(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
+endif
+endef
+
+
+# Syntax: $(call COMPILE_cc_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_cc_o_template
+ifeq ($$($(2)_CC_TARGET),)
+$(2)_CC_TARGET=1
+$(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
+endif
+endef
+
+
+# Syntax: $(call COMPILE_S_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_S_o_template
+ifeq ($$($(2)_S_TARGET),)
+$(2)_S_TARGET=1
+$(2): $(1) $$(GEN_HEADERS)
+ @$(QUIET_CMD_ECHO) " AS $$@"
+ $(Q) if $$(S_o_COMPILE) -D__ASSEMBLY__ $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endif
+endef
+
+# Syntax: $(call COMPILE_s_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_s_o_template
+ifeq ($$($(2)_s_TARGET),)
+$(2)_s_TARGET=1
+$(2): $(1) $$(GEN_HEADERS)
+ @$(QUIET_CMD_ECHO) " AS $$@"
+ $(Q)$$(S_o_COMPILE) $(3) -o $$@ -c $$<
+endif
+endef
+
+# Syntax: $(call COMPILE_idl_template,</path/to/src.idl>,<basename>)
+define COMPILE_idl_template
+
+ifeq ($$($(2)_IDL_TARGET),)
+$(2)_IDL_TARGET=1
+GEN_HEADERS+=$(filter %.h,$(notdir $(1:%.idl=%.h))) # Do we need this global variable?
+
+$(2).c $(2)-stubs.c $(2)-skels.c $(2)-common.c $(2).h: $(1) $$(wildcard $$(firstword $$(idl_COMPILE)))
+ @$(QUIET_CMD_ECHO) " IDL $$@"
+ $(Q) $$(idl_COMPILE) $$($(2)_IDLFLAGS) $(1)
+endif
+endef
+
+# GCC recognizes files matching this pattern as C++
+CXX_PATTERN = %.cc %.cp %.cxx %.cpp %.CPP %.c++ %.C
+
+# Syntax: $(call COMPILE_templates,<sources_abs>,<suffix>,<obj-prefix>)
+# Note: The newlines after $(call ) are IMPORTANT!!!
+define COMPILE_templates
+$(foreach src,$(filter %.c,$(1)),$(call COMPILE_c_o_template,$(src),$(3)$(notdir $(src:%.c=%$(2))),)
+)
+$(foreach src,$(filter $(CXX_PATTERN),$(1)),$(call COMPILE_cc_o_template,$(src),$(3)$(notdir $(basename $(src))$(2)),)
+)
+$(foreach src,$(filter %.S,$(1)),$(call COMPILE_S_o_template,$(src),$(3)$(notdir $(basename $(src))$(2)),)
+)
+$(foreach src,$(filter %.s,$(1)),$(call COMPILE_s_o_template,$(src),$(3)$(notdir $(basename $(src))$(2)),)
+)
+endef
+
+TARGET_IDL_SOURCES = $(filter %.c,$($(1)_SERVER_IDL:%.idl=%-skels.c)) \
+ $(filter %.c,$($(1)_SERVER_IDL:%.idl=%-common.c)) \
+ $(filter %.c,$($(1)_CLIENT_IDL:%.idl=%-stubs.c)) \
+ $(filter %.c,$($(1)_CLIENT_IDL:%.idl=%-common.c)) \
+ $(filter %.c,$($(1)_IDL:%.idl=%.c))
+TARGET_SOURCES = $($(1)_SOURCES) $($(1)_GEN_SOURCES) $(TARGET_IDL_SOURCES)
+TARGET_SOURCES_ABS = $($(1)_SOURCES:%=$(SOURCES_DIR)/%) $($(1)_GEN_SOURCES) $(TARGET_IDL_SOURCES)
+TARGET_OBJ_PREFIX = $(if $($(1)_CFLAGS)$($(1)_CXXFLAGS)$($(1)_CPPFLAGS),$(1)-,)
+TARGET_OBJS = $(sort $(addprefix $(TARGET_OBJ_PREFIX),$(addsuffix .o,$(basename $(notdir $(TARGET_SOURCES))))))
+TARGET_LOBJS = $(sort $(addprefix $(TARGET_OBJ_PREFIX),$(addsuffix .lo,$(basename $(notdir $(TARGET_SOURCES))))))
+TARGET_IDLS = $($(1)_SERVER_IDL) $($(1)_CLIENT_IDL) $($(1)_IDL)
+TARGET_CFLAGS = $(if $($(1)_CFLAGS),$($(1)_CFLAGS),$(OMK_CFLAGS))
+TARGET_CXXFLAGS = $(if $($(1)_CXXFLAGS),$($(1)_CXXFLAGS),$(OMK_CXXFLAGS))
+TARGET_CPPFLAGS = $(if $($(1)_CPPFLAGS),$($(1)_CPPFLAGS),$(OMK_CPPFLAGS))
+
+# Syntax: $(call PROGRAM_template,<executable-name>,<dir>,<executable-suffix>,<linker-sript>)
+define PROGRAM_template
+$(foreach idl,$(TARGET_IDLS),$(call COMPILE_idl_template,$(SOURCES_DIR)/$(idl),$(idl:%.idl=%)))
+
+$(call COMPILE_templates,$(TARGET_SOURCES_ABS),.o,$(TARGET_OBJ_PREFIX))
+
+$(2)/$(1)$(3): OMK_CFLAGS=$(TARGET_CFLAGS)
+$(2)/$(1)$(3): OMK_CXXFLAGS=$(TARGET_CXXFLAGS)
+$(2)/$(1)$(3): OMK_CPPFLAGS=$(TARGET_CPPFLAGS)
+$(2)/$(1)$(3): $(TARGET_OBJS)
+ @$(QUIET_CMD_ECHO) " LINK $$@"
+ $(Q) $(if $(filter $(CXX_PATTERN),$(TARGET_SOURCES)),$$(CXX),$$(CC)) \
+ $(TARGET_OBJS) $$($(1)_LIBS:%=-l%) $$(LOADLIBES) $$(OMK_LDFLAGS) $$(LDFLAGS) $$($(1)_LDFLAGS) -Wl,-rpath-link,$(USER_LIB_DIR) -Wl,-Map,$(USER_OBJS_DIR)/$(1).exe.map -o $$@
+ @echo "$(2)/$(1)$(3): \\" >$(USER_OBJS_DIR)/$(1).exe.d
+ @$(SED4OMK) -n -e 's|^LOAD \(.*\)$$$$| \1 \&|p' $(USER_OBJS_DIR)/$(1).exe.map|tr '&' '\134' >>$(USER_OBJS_DIR)/$(1).exe.d
+ @echo >>$(USER_OBJS_DIR)/$(1).exe.d
+
+binary-pass-local: $(2)/$(1)$(3)
+endef
+
+# Usage: $(call SCRIPT_template,<target-directory>,<script-name>)
+define SCRIPT_template
+$(2)/$(1): $$(SOURCES_DIR)/$(1)
+ @$(QUIET_CMD_ECHO) " CP $$@"
+ $(Q)cp $$^ $$@
+
+binary-pass-local: $(2)/$(1)
+endef
+
+
+# Syntax: $(call LIBRARY_template,<library-name>)
+define LIBRARY_template
+
+$(foreach idl,$(TARGET_IDLS),$(call COMPILE_idl_template,$(SOURCES_DIR)/$(idl),$(idl:%.idl=%)))
+
+$(call COMPILE_templates,$(TARGET_SOURCES_ABS),.o,$(TARGET_OBJ_PREFIX))
+
+$(USER_LIB_DIR)/lib$(1).a: OMK_CFLAGS=$(TARGET_CFLAGS)
+$(USER_LIB_DIR)/lib$(1).a: OMK_CXXFLAGS=$(TARGET_CXXFLAGS)
+$(USER_LIB_DIR)/lib$(1).a: OMK_CPPFLAGS=$(TARGET_CPPFLAGS)
+$(USER_LIB_DIR)/lib$(1).a: $(TARGET_OBJS)
+ @$(QUIET_CMD_ECHO) " AR $$@"
+ $(Q) $(AR) rcs $$@ $$^
+
+library-pass-local: $(USER_LIB_DIR)/lib$(1).a
+endef
+
+
+# Syntax: $(call SOLIB_template,<library-name>)
+define SOLIB_template
+
+$(foreach idl,$(TARGET_IDLS),$(call COMPILE_idl_template,$(SOURCES_DIR)/$(idl),$(idl:%.idl=%)))
+
+$(call COMPILE_templates,$(TARGET_SOURCES_ABS),.lo,$(TARGET_OBJ_PREFIX))
+
+.PHONY: $(OMK_WORK_DIR)/lib$(1).$(SOLIB_EXT).omkvar
+$(2)/$(1)$(3): OMK_CFLAGS=$(TARGET_CFLAGS)
+$(2)/$(1)$(3): OMK_CXXFLAGS=$(TARGET_CXXFLAGS)
+$(2)/$(1)$(3): OMK_CPPFLAGS=$(TARGET_CPPFLAGS)
+$(OMK_WORK_DIR)/lib$(1).$(SOLIB_EXT).omkvar: OMK_CFLAGS = $(TARGET_CFLAGS) $(SOLIB_PICFLAGS)
+$(OMK_WORK_DIR)/lib$(1).$(SOLIB_EXT).omkvar: OMK_CXXFLAGS = $(TARGET_CXXFLAGS) $(SOLIB_PICFLAGS)
+$(OMK_WORK_DIR)/lib$(1).$(SOLIB_EXT).omkvar: OMK_CPPFLAGS = $(TARGET_CPPFLAGS)
+$(OMK_WORK_DIR)/lib$(1).$(SOLIB_EXT).omkvar: $(TARGET_LOBJS)
+ $(Q)echo '$(1)_objslo += $$$$(addprefix $(USER_OBJS_DIR)/,$$^)' > $$@.tmp; \
+ echo '$(1)_libs += $$($(1)_LIBS) $$(lib_LOADLIBES)' >> $$@.tmp; \
+ echo '$(1)_ldflags += $$($(1)_LDFLAGS) $$(lib_LDFLAGS)' >> $$@.tmp; \
+ echo 'shared_libs := $$$$(sort $(1) $$$$(shared_libs))' >> $$@.tmp; \
+ if cmp -s $$@.tmp $$@; then rm $$@.tmp; else mv $$@.tmp $$@; fi
+
+library-pass-local: $(OMK_WORK_DIR)/lib$(1).$(SOLIB_EXT).omkvar
+endef
+
+# Generate rules for compilation of programs and libraries
+
+$(foreach prog,$(utils_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_UTILS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(test_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_TESTS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(bin_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_BIN_DIR),$(EXE_SUFFIX))))
+
+$(foreach script,$(bin_SCRIPTS),$(eval $(call SCRIPT_template,$(script),$(USER_BIN_DIR))))
+
+
+# $(foreach lib,$(lib_LIBRARIES),$(info $(call LIBRARY_template,$(lib))))
+$(foreach lib,$(lib_LIBRARIES),$(eval $(call LIBRARY_template,$(lib))))
+
+$(foreach lib,$(shared_LIBRARIES),$(eval $(call SOLIB_template,$(lib))))
+
+-include $(USER_OBJS_DIR)/*.d
+#FIXME: This doesn't include dependencies of source files from
+#subdirectories (i.s. *_SOURCES=dir/file.c. I'm currently not sure,
+#how to handle this.
+
+endif # USER_RULE_TEMPLATES
+
+.PHONY: link-pseudo-pass
+link-pseudo-pass:
+ $(Q)$(MAKE) $(NO_PRINT_DIRECTORY) -C $(USER_BUILD_DIR) -f $(SOURCESDIR_MAKEFILE) link-shared-libs
+
+ifeq ($(MAKECMDGOALS),link-shared-libs)
+
+
+
+# Syntax: $(call solib_link_template,<library-name>)
+define solib_link_template
+$(1)_shared_libs = $$(patsubst %,$(USER_LIB_DIR)/lib%.$(SOLIB_EXT),$$(filter $$(shared_libs),$$($(1)_libs)))
+#$$(warning $(1)_shared_libs = $$($(1)_shared_libs))
+$(USER_LIB_DIR)/lib$(1).$(SOLIB_EXT): $$($(1)_shared_libs) $$($(1)_objslo)
+ @$(QUIET_CMD_ECHO) " LINK $$@"
+ $(Q)$(CC) --shared -Xlinker -soname=lib$(1).$(SOLIB_EXT) -Wl,-Map,$(USER_OBJS_DIR)/lib$(1).$(SOLIB_EXT).map -o $$@ $$($(1)_objslo) $$(LOADLIBES) $$($(1)_libs:%=-l%) $$(lib_ldflags) $$($(1)_ldflags)
+endef
+
+-include $(shell true; find $(USER_BUILD_DIR) -name 'lib*.omkvar') # `true' is a hack for MinGW
+#$(warning $(shared_libs))
+$(foreach lib,$(shared_libs),$(eval $(call solib_link_template,$(lib))))
+
+.PHONY: link-shared-libs
+link-shared-libs: $(shared_libs:%=$(USER_LIB_DIR)/lib%.$(SOLIB_EXT))
+endif # link-shared-libs
+
+$(eval $(call omk_pass_template, library-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(lib_LIBRARIES)$(shared_LIBRARIES)$(cmetric_include_HEADERS)))
+$(eval $(call omk_pass_template, binary-pass, $(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(bin_PROGRAMS)$(utils_PROGRAMS)$(test_PROGRAMS)$(bin_SCRIPTS)))
+
+$(eval $(call omk_pass_template,clean,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,install,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,include-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,always))
+
+check-dir::
+ @$(call mkdir_def,$(USER_BUILD_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))
+
+install-local: # TODO
+
+$(eval $(call include-pass-template,$(USER_INCLUDE_DIR),include))
+
+clean-local::
+ @echo Cleaning in $(USER_OBJS_DIR)
+ @rm -f $(USER_OBJS_DIR)/*.[och] \
+ $(USER_OBJS_DIR)/*.lo \
+ $(USER_OBJS_DIR)/*.d \
+ $(USER_OBJS_DIR)/*.map \
+ $(LOCAL_CONFIG_H:%=$(USER_OBJS_DIR)/%)
+
+include-pass-submakes: extra-rules-subdirs
+
+# We must go to EXTRA_RULES_SUBDIRS before going to any other
+# directory, since the executables compiled in EXTRA_RULES_SUBDIRS
+# might be needed there.
+include-pass-this-dir $(foreach subdir,$(SUBDIRS),include-pass-$(subdir)-subdir): extra-rules-subdirs
+
+default: include-pass library-pass binary-pass
+ #OMK:linux-kernel.omk@Makefile.rules.linux
+KERN_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include-kern
+KERN_LIB_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib-kern
+KERN_MODULES_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/modules
+KERN_BUILD_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern
+KERN_MODPOST_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern-modpost
+
+ifndef LINUX_VERSION
+LINUX_VERSION=$(shell uname -r)
+endif
+ifndef LINUX_DIR
+LINUX_DIR=/lib/modules/$(LINUX_VERSION)/build
+endif
+
+KERN_OBJS_DIR = $(KERN_BUILD_DIR)/$(RELATIVE_DIR)
+
+kernel-lib-pass: include-pass
+kernel-mod-pass: kernel-lib-pass
+kernel-modpost-pass: kernel-mod-pass
+kernel-pass: kernel-mod-pass kernel-modpost-pass
+
+#=====================================================================
+# Kernel-space rules and templates to compile modules, libraries etc.
+
+ifdef KERN_RULE_TEMPLATES
+
+$(KERN_LIB_DIR)/kernel.mk: $(LINUX_DIR)/.config $(MAKERULES_DIR)/kernelcfg2mk
+ @$(QUIET_CMD_ECHO) " KCFG2MK $@"
+ $(Q) $(MAKERULES_DIR)/kernelcfg2mk $(LINUX_DIR) $(KERN_LIB_DIR)
+
+ifeq ($(CONFIG_RTLINUX),y)
+include $(RTL_DIR)/rtl.mk
+
+KERN_CC = $(CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(CC) -print-search-dirs | $(SED4OMK) -n -e 's/^install: \(.*\)$$/\1/p' )
+INCLUDES := -I $(KERN_INCLUDE_DIR) $(INCLUDE) $(rtlinux_INCLUDES) $(kernel_INCLUDES)
+#-DEXPORT_NO_SYMBOLS
+c_o_kern_COMPILE = $(KERN_CC) -idirafter $(kern_GCCLIB_DIR)/include $(INCLUDES) $(CFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(CXX) $(INCLUDES) $(CXXFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+KERN_EXE_SUFFIX := .o
+KERN_ARCH = $(ARCH)
+KERN_LD = $(LD)
+KERN_AR = $(AR)
+
+else # CONFIG_RTLINUX
+
+include $(KERN_LIB_DIR)/kernel.mk
+
+ifeq ($(LINUX_SRC),)
+LINUX_SRC = $(LINUX_DIR)
+endif
+kernel_INCLUDES += -I $(KERN_INCLUDE_DIR) -I $(LINUX_DIR) -idirafter $(LINUX_SRC)/include/linux
+
+ifdef LINUX_CC
+KERN_CC = $(LINUX_CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(LINUX_CC) -print-search-dirs | $(SED4OMK) -n -e 's/^install: \(.*\)$$/\1/p' )
+else
+KERN_CC = echo KERN_CC not defined - compilation skipped
+endif
+c_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+S_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_AFLAGS) $(LINUX_AFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+KERN_EXE_SUFFIX := $(LINUX_MODULE_EXT)
+KERN_LDFLAGS = $(LINUX_LDFLAGS) $(LINUX_LDFLAGS_MODULE)
+ifdef LINUX_ARCH
+KERN_ARCH = $(LINUX_ARCH)
+else
+KERN_ARCH = echo KERN_ARCH not defined - skipped
+endif
+ifdef LINUX_LD
+KERN_LD = $(LINUX_LD)
+else
+KERN_LD = echo KERN_LD not defined - skipped
+endif
+ifneq ($(LINUX_AR),)
+KERN_AR = $(LINUX_AR)
+else
+KERN_AR = $(AR)
+endif
+ifeq ($(LINUX_QUOTE_MODNAME),y)
+KERN_MQ=\"
+KERN_KBUILD_MODNAME=-D"KBUILD_MODNAME=((THIS_MODULE)!=NULL?(THIS_MODULE)->name:NULL)"
+endif
+endif # CONFIG_RTLINUX
+
+KERN_LOADLIBES += -L$(KERN_LIB_DIR)
+
+KERN_LOADLIBES += $(rtlinux_LOADLIBES:%=-l%)
+KERN_LOADLIBES += $(kernel_LOADLIBES:%=-l%)
+
+
+
+# Check GCC version for kernel part of build
+ifndef kern_CC_MAJOR_VERSION
+kern_CC_MAJOR_VERSION := $(shell $(KERN_CC) -dumpversion | $(SED4OMK) -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(kern_CC_MAJOR_VERSION),2)
+kern_CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+kern_CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+ifeq ($(KERN_EXE_SUFFIX),.ko)
+ifeq ($(wildcard $(LINUX_DIR)/scripts/mod/modpost),)
+KERN_MODPOST = $(LINUX_DIR)/scripts/modpost
+else
+KERN_MODPOST = $(LINUX_DIR)/scripts/mod/modpost
+endif
+KERN_MODULES_LINK_DIR = $(KERN_MODPOST_DIR)
+KERN_LINK_SUFFIX = .o
+else
+KERN_MODULES_LINK_DIR = $(KERN_MODULES_DIR)
+KERN_LINK_SUFFIX = $(KERN_EXE_SUFFIX)
+endif
+
+ifeq ($(LINUX_CONFIG_MODVERSIONS),y)
+MODPOST_OPTS += -m
+MODPOST_OPTS += -i $(LINUX_DIR)/Module.symvers
+ifneq ($(LINUX_BUILDHOST),) # this is not correct point, it should look for 2.6.17 kernel
+MODPOST_OPTS += -I $(KERN_LIB_DIR)/Module.symvers
+endif
+MODPOST_OPTS += -o $(KERN_LIB_DIR)/Module.symvers
+endif
+
+ifeq ($(LINUX_CONFIG_DEBUG_SECTION_MISMATCH),y)
+MODPOST_OPTS += -S
+endif
+
+ifeq ($(LINUX_CONFIG_MARKERS),y)
+MODPOST_OPTS += -K $(LINUX_DIR)/Module.markers
+MODPOST_OPTS += -M $(KERN_LIB_DIR)/Module.markers
+endif
+
+ifeq ($(LINUX_KBUILD_MODPOST_WARN),y)
+MODPOST_OPTS += -w
+endif
+
+ifneq ($(LINUX_BUILDHOST),)
+ifneq ($(LINUX_BUILDHOST),$(LINUX_ARCH))
+MODPOST_OPTS += -c
+endif
+endif
+
+define COMPILE_c_o_kern_template
+
+$(2): $(1)
+ @$(QUIET_CMD_ECHO) " CC [K] $$@"
+ $(Q) if $$(c_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+ -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+ -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+
+define COMPILE_cc_o_kern_template
+
+$(2): $(1)
+ @$(QUIET_CMD_ECHO) " CXX [K] $$@"
+ $(Q) if $$(cc_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+ -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+ -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+
+define COMPILE_S_o_kern_template
+
+$(2): $(1)
+ @$(QUIET_CMD_ECHO) " AS [K] $$@"
+ $(Q) if $$(S_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+ -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+ -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+
+define MODULE_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cpp=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+# this is hack to build "__this_module" structure for 2.6.x kernels
+# modpost is used for that purpose now
+
+#$(1).mod.c:
+# echo "\
+# #include <linux/version.h>@\
+# #include <linux/module.h>@\
+# #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,5))@\
+# #include <linux/vermagic.h>@\
+# #include <linux/compiler.h>@\
+# @\
+# MODULE_INFO(vermagic, VERMAGIC_STRING);@\
+# @\
+# #undef unix@\
+# struct module __this_module@\
+# __attribute__((section(\".gnu.linkonce.this_module\"))) = {@\
+# .name = __stringify(KBUILD_MODNAME),@\
+# .init = init_module,@\
+# #ifdef CONFIG_MODULE_UNLOAD@\
+# .exit = cleanup_module,@\
+# #endif@\
+# };@\
+# #endif@\
+# " | tr @ \\n >$$@
+
+
+#$(eval $(call COMPILE_c_o_kern_template,$(1).mod.c,$(1).mod.o,-DKBUILD_MODNAME=$(1)))
+
+$(2)/$(1)$(KERN_LINK_SUFFIX): $$($(1)_OBJS)
+ @$(QUIET_CMD_ECHO) " LD [K] $$@"
+ $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) -r $$($(1)_OBJS) -L$$(kern_GCCLIB_DIR) $$($(1)_LIBS:%=-l%) $$(KERN_LOADLIBES) -Map $(KERN_OBJS_DIR)/$(1).mod.map -o $$@
+ @echo "$(2)/$(1)$(KERN_LINK_SUFFIX): \\" >$(KERN_OBJS_DIR)/$(1).mod.d
+ @$(SED4OMK) -n -e 's/^LOAD \(.*\)$$$$/ \1 \\/p' $(KERN_OBJS_DIR)/$(1).mod.map >>$(KERN_OBJS_DIR)/$(1).mod.d
+ @echo >>$(KERN_OBJS_DIR)/$(1).mod.d
+ @if [ "$(KERN_EXE_SUFFIX)" = ".ko" ] ; then \
+ echo $(1) >>$(KERN_MODPOST_DIR)/module-changes ; \
+ echo $(1) >$(KERN_MODPOST_DIR)/$(1).mod.stamp ; \
+ fi
+
+endef
+
+
+
+define LIBRARY_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cpp=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+$(KERN_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+ @$(QUIET_CMD_ECHO) " AR [K] $$@"
+ $(Q) $(KERN_AR) rcs $$@ $$^
+endef
+
+
+ifdef LINUX_DIR
+
+kernel-lib-pass-local: $(kernel_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+kernel-mod-pass-local: $(kernel_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+$(foreach module,$(kernel_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(kernel_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+
+ifeq ($(CONFIG_RTLINUX),y)
+
+kernel-mod-pass-local: $(rtlinux_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+kernel-lib-pass-local: $(rtlinux_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+$(foreach module,$(rtlinux_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(rtlinux_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+ifeq ($(KERN_MODPOST_PASS),y)
+
+MODULES_LIST := $(wildcard *.mod.stamp)
+MODULES_LIST := $(MODULES_LIST:%.mod.stamp=%)
+
+define MODPOST_kern_template
+$(2) : $(1)$(KERN_LINK_SUFFIX) $(1).mod.c
+ @$(QUIET_CMD_ECHO) " LD [M] $$@"
+ $(Q) $$(c_o_kern_COMPILE) -D"KBUILD_BASENAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+ -D"KBUILD_MODNAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+ -o $(1).mod.o -c $(1).mod.c
+ $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) $(1)$(KERN_LINK_SUFFIX) $(1).mod.o -r -o $$@
+endef
+
+kernel-modpost-versions: $(wildcard $(LINUX_DIR)/Module.symvers)
+ @$(QUIET_CMD_ECHO) " MODPOST $(KERN_MODPOST_DIR)"
+ @echo >$(KERN_MODPOST_DIR)/modpost-running
+ @rm -f $(KERN_MODPOST_DIR)/module-changes
+ $(Q) $(KERN_MODPOST) $(MODPOST_OPTS) $(MODULES_LIST:%=%$(KERN_LINK_SUFFIX))
+
+$(MODULES_LIST:%=%.mod.c) : kernel-modpost-versions
+
+kernel-modpost-pass-local: $(MODULES_LIST:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX))
+ @rm -f $(KERN_MODPOST_DIR)/modpost-running
+
+$(foreach module,$(MODULES_LIST),$(eval $(call MODPOST_kern_template,$(module),$(module:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX)))))
+
+endif
+
+-include $(KERN_OBJS_DIR)/*.d
+
+endif
+
+#=====================================================================
+
+# Kernel requires its own set of configuration header-files
+ifneq ($(kernel_LIBRARIES)$(rtlinux_LIBRARIES)$(kernel_MODULES)$(rtlinux_MODULES)$(kernel_HEADERS)$(rtlinux_HEADERS)$(kernel_HEADERS)$(rtlinux_HEADERS)$(nobase_kernel_HEADERS)$(nobase_rtlinux_HEADERS)$(renamed_kernel_HEADERS)$(renamed_rtlinux_HEADERS),)
+KERN_CONFIG_HEADERS_REQUIRED = y
+endif
+
+$(eval $(call omk_pass_template, kernel-lib-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_LIBRARIES)$(rtlinux_LIBRARIES)))
+$(eval $(call omk_pass_template, kernel-mod-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_MODULES)$(rtlinux_MODULES)))
+
+kernel-modpost-pass:
+ +@if [ -e "$(KERN_MODPOST_DIR)/module-changes" -o -e "$(KERN_MODPOST_DIR)/modpost-running" ] ; \
+ then \
+ $(MAKE) --no-print-directory -C $(KERN_MODPOST_DIR) \
+ -f $(SOURCES_DIR)/Makefile KERN_RULE_TEMPLATES=y KERN_MODPOST_PASS=y $(@:%=%-local) ; \
+ fi
+
+check-dir::
+ @$(call mkdir_def,$(KERN_BUILD_DIR))
+ @$(call mkdir_def,$(KERN_INCLUDE_DIR))
+ @$(call mkdir_def,$(KERN_LIB_DIR))
+ @$(call mkdir_def,$(KERN_MODULES_DIR))
+ @$(call mkdir_def,$(KERN_MODPOST_DIR))
+
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),kernel))
+ifeq ($(CONFIG_RTLINUX),y)
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),rtlinux))
+endif
+
+ifdef KERN_RULE_TEMPLATES
+
+KERN_SOURCES := $(sort $(KERN_SOURCES))
+
+#$(warning KERN_SOURCES = $(KERN_SOURCES))
+
+$(foreach src,$(filter %.c,$(KERN_SOURCES)),$(eval $(call COMPILE_c_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.cpp,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cpp=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+endif
+
+clean-local::
+ @echo Cleaning in $(KERN_OBJS_DIR)
+ @rm -f $(KERN_OBJS_DIR)/*.o \
+ $(KERN_OBJS_DIR)/*.d \
+ $(KERN_OBJS_DIR)/*.map \
+ $(KERN_OBJS_DIR)/*.mod.c \
+ $(kernel_MODULES:%=$(KERN_MODPOST_DIR)/%.*) \
+ $(LOCAL_CONFIG_H:%=$(KERN_OBJS_DIR)/%)
+ @if [ -e $(KERN_LIB_DIR)/kernel.mk ] ; then \
+ touch -t 200001010101 $(KERN_LIB_DIR)/kernel.mk ; \
+ fi
+
+ifndef OMIT_KERNEL_PASSES
+# Also make kernel passes if not disabled
+default: kernel-lib-pass kernel-pass
+endif
+ #OMK:cmetric.omk@Makefile.rules.linux
+NM ?= nm
+
+# 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
+
+library-pass-local: $(addprefix $(USER_INCLUDE_DIR)/,$(cmetric_include_HEADERS))
+
+# 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)/%)
+ #OMK:config_h.omk@Makefile.rules.linux
+# 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 -s "$(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::
+ @$(foreach confh,$(config_h_stamp_files) $(kern_config_h_stamp_files),\
+ if [ -e $(confh) ] ; then rm $(confh) ; fi ; \
+ )
+ #OMK:qt.omk@Makefile.rules.linux
+ifneq ($(QT_SUBDIRS)$(QT_PROJECTS),)
+
+# Usage: $(call qt_project_template,<.pro_file relative to SOURCES_DIR>)
+define qt_project_template
+
+.PHONY: qt-subpass-$(1) clean-qt-$(dir $(1))
+
+# FIXME: Handle multiple .pro files correctly
+$(LOCAL_BUILD_DIR)/$(dir $(1))Makefile: $(SOURCES_DIR)/$(1)
+ $(Q)mkdir -p $$(dir $$(@)) && cd $$(dir $$(@)) && \
+ $(if $(QMAKE),$(QMAKE),$(QTDIR:%=%/bin/)qmake) \
+ TOP_DIR=$(OUTPUT_DIR) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir $(1)) \
+ $(QTDIR:%=QTDIR=%) CC=$(CC) CXX=$(CXX) \
+ LIBS+="-L$(USER_LIB_DIR)" DESTDIR=$(USER_BIN_DIR) \
+ INCLUDEPATH+="$(USER_INCLUDE_DIR)" \
+ DEPENDPATH+="$(USER_INCLUDE_DIR)" \
+ QMAKE_LFLAGS="-Wl,-rpath-link,$(USER_LIB_DIR) $$(QMAKE_LFLAGS)" \
+ $(SOURCES_DIR)/$(1)
+
+# This horrible substitution is here to properly escape
+# -Wl,-rpath,$ORIGIN flags. It includes escaping for make, shell,
+# qmake and again make and shell run on qmake generated makefile.
+QMAKE_LFLAGS = $$(subst $$$$,\\\\\\$$$$\$$$$,$$(LDFLAGS))
+
+# Hook to binary pass
+binary-pass-submakes: qt-subpass-$(1)
+qt-subpass-$(1): $(LOCAL_BUILD_DIR)/$(dir $(1))Makefile
+ $(Q)$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir $(1)) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir $(1)) -C $(LOCAL_BUILD_DIR)/$(dir $(1)) || exit 1 ;
+
+# Hook to clean pass
+clean-local:: $(LOCAL_BUILD_DIR)/$(dir $(1))Makefile
+ @$(QUIET_CMD_ECHO) " QT CLEAN $(dir $(1))"
+ $(Q)$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir $(1)) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir $(1)) \
+ -C $(LOCAL_BUILD_DIR)/$(dir $(1)) clean
+ $(Q)rm $(LOCAL_BUILD_DIR)/$(dir $(1))Makefile
+endef
+
+$(foreach pro,$(QT_PROJECTS), $(eval $(call qt_project_template,$(pro))))
+$(foreach pro,$(foreach dir,$(QT_SUBDIRS), $(wildcard $(SOURCES_DIR)/$(dir)/*.pro)), $(eval $(call qt_project_template,$(pro:$(SOURCES_DIR)/%=%))))
+
+endif
+ #OMK:sources-list.omk@Makefile.rules.linux
+# 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)
--- /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 = rpi-pmsm-test1
+
--- /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_APP_RPI_PMSM_T1=x
+#default_CONFIG += CONFIG_OC_MWENGINE=x
+default_CONFIG += CONFIG_APP_RPI_PMSM_T1_WITH_ULAN=x
+default_CONFIG += CONFIG_APP_RPI_PMSM_T1_WITH_SUITK=x
+default_CONFIG += CONFIG_APP_RPI_PMSM_T1_WITH_SIM_POSIX=x
+default_CONFIG += CONFIG_OC_CMDPROC=x CONFIG_PXMC=x CONFIG_PXMC_COORDMV=x
+
+ifeq ($(CONFIG_APP_RPI_PMSM_T1),y)
+
+LOCAL_CONFIG_H = appl_config.h
+
+#INCLUDES += -I$(USER_INCLUDE_DIR)/ul_lib -I.
+
+INCLUDES += -I.
+
+bin_PROGRAMS = rpi_pmsm_t1
+
+rpi_pmsm_t1_SOURCES = appl_main.c
+
+rpi_pmsm_t1_SOURCES += appl_utils.c
+
+rpi_pmsm_t1_SOURCES += rpi_gpio.c
+rpi_pmsm_t1_SOURCES += rpi_gpclk.c
+rpi_pmsm_t1_SOURCES += rpi_spi.c
+
+ifeq ($(CONFIG_OC_CMDPROC),y)
+rpi_pmsm_t1_SOURCES += appl_cmdproc.c
+#rpi_pmsm_t1_SOURCES += appl_cmds.c
+#rpi_pmsm_t1_SOURCES += appl_tests.c
+#rpi_pmsm_t1_SOURCES += appl_dprint.c
+#rpi_pmsm_t1_SOURCES += cmd_uartcon.c
+endif
+
+ifeq ($(CONFIG_PXMC),y)
+ifeq ($(CONFIG_PXMC_COORDMV),y)
+rpi_pmsm_t1_SOURCES += appl_coordmv.c math_sqrtll.c
+lib_LOADLIBES += pxmc_coordmv
+endif
+rpi_pmsm_t1_SOURCES += appl_pxmc.c
+#rpi_pmsm_t1_SOURCES += appl_pxmccmds.c
+lib_LOADLIBES += pxmc
+#lib_LOADLIBES += pxmcbsp
+endif
+
+ifeq ($(CONFIG_OC_CMDPROC),y)
+lib_LOADLIBES += cmdproc misc
+endif
+
+ifeq ($(CONFIG_OC_ULUT),y)
+lib_LOADLIBES += ulut
+endif
+
+lib_LOADLIBES += rt
+lib_LOADLIBES += pthread
+lib_LOADLIBES += m
+
+#link_VARIANTS = app sdram
+
+endif #CONFIG_APP_RPI_PMSM_T1
--- /dev/null
+#include <system_def.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <cmd_proc.h>
+
+#include "appl_defs.h"
+
+typedef struct cmdproc_ready_check_state_t {
+ unsigned long axes_rq_mask;
+ int global_rq;
+ cmd_io_t* peer_cmd_io;
+} cmdproc_ready_check_state_t;
+
+extern cmd_io_t cmd_io_std_line;
+
+cmdproc_ready_check_state_t cmdproc_ready_check_state_std_line = {
+ .peer_cmd_io = &cmd_io_std_line,
+};
+
+cmdproc_ready_check_state_t *const cmdproc_ready_check_state_arr[] = {
+ &cmdproc_ready_check_state_std_line,
+ NULL
+};
+
+extern cmd_des_t const *cmd_pxmc_base[];
+extern cmd_des_t const *cmd_appl_tests[];
+extern cmd_des_t const *cmd_pxmc_ptable[];
+extern cmd_des_t const *cmd_pxmc_coordmv[];
+extern cmd_des_t const *cmd_appl_specific[];
+extern cmd_des_t const *cmd_appl_pxmc[];
+
+extern cmd_des_t const cmd_des_dprint;
+
+cmd_des_t const **cmd_list;
+
+cmd_des_t const cmd_des_help =
+{
+ 0, 0,
+ "help", "prints help for commands",
+ cmd_do_help,
+ {
+ (char *) &cmd_list
+ }
+};
+
+cmdproc_ready_check_state_t *cmdproc_ready_state4cmd_io(cmd_io_t *cmd_io)
+{
+ cmdproc_ready_check_state_t * const *ppckst = cmdproc_ready_check_state_arr;
+ while (*ppckst) {
+ if ((*ppckst)->peer_cmd_io == cmd_io)
+ return *ppckst;
+ ppckst++;
+ }
+ return NULL;
+}
+
+int cmd_do_r_one(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ unsigned chan;
+ unsigned long val;
+ cmdproc_ready_check_state_t *ckst;
+
+ if (*param[2] != ':') return -CMDERR_OPCHAR;
+ chan = *param[1] - 'A';
+ if(chan >= 31) return -CMDERR_BADREG;
+
+ ckst = cmdproc_ready_state4cmd_io(cmd_io);
+ if (ckst == NULL)
+ return -CMDERR_BADDIO;
+
+ ckst->axes_rq_mask |= 1l << chan;
+ return 0;
+}
+
+int cmd_do_r_all(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ cmdproc_ready_check_state_t *ckst;
+
+ if(*param[2] != ':') return -CMDERR_OPCHAR;
+
+ ckst = cmdproc_ready_state4cmd_io(cmd_io);
+ if (ckst == NULL)
+ return -CMDERR_BADDIO;
+
+ ckst->global_rq = 1;
+ return 0;
+}
+
+cmd_des_t const cmd_des_r_one={0, CDESM_OPCHR,
+ "R?","send R?! or FAIL?! at axis finish",cmd_do_r_one,{}};
+
+cmd_des_t const cmd_des_r_all={0, CDESM_OPCHR,
+ "R","send R! or FAIL! at finish",cmd_do_r_all,{}};
+
+cmd_des_t const *cmd_list_main[] =
+{
+ &cmd_des_help,
+ //CMD_DES_INCLUDE_SUBLIST(cmd_appl_tests),
+#ifdef CONFIG_PXMC
+ CMD_DES_INCLUDE_SUBLIST(cmd_pxmc_base),
+ CMD_DES_INCLUDE_SUBLIST(cmd_pxmc_ptable),
+#endif
+ &cmd_des_r_one,
+ &cmd_des_r_all,
+ CMD_DES_INCLUDE_SUBLIST(cmd_pxmc_coordmv),
+ //CMD_DES_INCLUDE_SUBLIST(cmd_appl_specific),
+ //CMD_DES_INCLUDE_SUBLIST(cmd_appl_pxmc),
+ //&cmd_des_dprint,
+ NULL
+};
+
+cmd_des_t const **cmd_list = cmd_list_main;
+
+int cmdproc_process_ready(cmd_io_t* cmd_io,
+ cmdproc_ready_check_state_t *ckst,
+ unsigned long busy_bits, unsigned long error_bits)
+{
+ unsigned int chan;
+ unsigned long send_bits = ckst->axes_rq_mask &
+ (error_bits | ~busy_bits);
+ int send_global = ckst->global_rq && (error_bits || !busy_bits);
+
+ if (cmd_io->priv.ed_line.out->inbuf || (!send_bits && !send_global))
+ return 0;
+
+ if (send_bits) {
+ chan = ffsl(send_bits) - 1;
+ ckst->axes_rq_mask &= ~(1l << chan);
+ if (error_bits & (1l << chan))
+ cmd_io_write(cmd_io,"FAIL",4);
+ else
+ cmd_io_write(cmd_io,"R",1);
+ cmd_io_putc(cmd_io,chan+'A');
+ cmd_io_putc(cmd_io,'!');
+ cmd_io_putc(cmd_io,'\r');
+ cmd_io_putc(cmd_io,'\n');
+ return 1;
+ }
+
+ ckst->global_rq = 0;
+ if (error_bits)
+ cmd_io_write(cmd_io,"FAIL",4);
+ else
+ cmd_io_write(cmd_io,"R",1);
+ cmd_io_putc(cmd_io,'!');
+ cmd_io_putc(cmd_io,'\r');
+ cmd_io_putc(cmd_io,'\n');
+ return 1;
+}
+
+int cmdproc_poll(void)
+{
+/* static typeof(actual_msec) dbg_prt_last_msec;
+ static typeof(actual_msec) old_check_time;
+ typeof(actual_msec) new_check_time;
+*/
+ int ret = 0;
+ unsigned long busy_bits, error_bits;
+
+/*
+ lt_mstime_update();
+
+ new_check_time = actual_msec;
+ if (new_check_time != old_check_time) {
+ cmdproc_ready_check_state_t * const *ppckst;
+ old_check_time = new_check_time;
+ pxmc_process_state_check(&busy_bits, &error_bits);
+ for (ppckst = cmdproc_ready_check_state_arr; *ppckst; ppckst++)
+ ret |= cmdproc_process_ready((*ppckst)->peer_cmd_io, *ppckst,
+ busy_bits, error_bits);
+ }
+*/
+
+ ret |= cmd_processor_run(&cmd_io_std_line, cmd_list_main);
+
+ return ret;
+}
--- /dev/null
+/*******************************************************************
+ Motion and Robotic System (MARS) aplication components
+
+ appl_coordmv.c - application specific coordinated
+ motions control support
+
+ Copyright (C) 2001-2014 by Pavel Pisa - originator
+ pisa@cmp.felk.cvut.cz
+ (C) 2001-2014 by PiKRON Ltd. - originator
+ http://www.pikron.com
+
+ This file can be used and copied according to next
+ license alternatives
+ - GPL - GNU Public License
+ - other license provided by project originators
+
+ *******************************************************************/
+
+#include <cpu_def.h>
+#include <system_def.h>
+#include <pxmc.h>
+#include <pxmc_coordmv.h>
+#include <cmd_proc.h>
+#include <pxmc_cmds.h>
+#include <utils.h>
+
+#include "appl_defs.h"
+
+int pxmc_coordmv_process(void)
+{
+ /* coordinator bottom handling */
+ if (pxmc_coordmv_state.mcs_flg & MCS_BOTT_m){
+ pxmc_coordmv_bottom(&pxmc_coordmv_state);
+ }
+
+ return 0;
+}
+
+int cmd_do_coordmv(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ pxmc_coordmv_state_t *mcs_state = &pxmc_coordmv_state;
+ int con_cnt = mcs_state->mcs_con_cnt;
+ int i;
+ long final[con_cnt], val;
+ long mintim = 0;
+ char *s;
+ pxmc_state_t *mcs;
+ if(*param[2]!=':') return -CMDERR_OPCHAR;
+ s = param[3];
+ if ((long)(des->info[1]) & 1) { /* coordinated movement with time */
+ if (si_long(&s, &mintim, 10) <0 ) return -CMDERR_BADPAR;
+ if (mintim < 0) return -CMDERR_BADPAR;
+ if (si_fndsep(&s,",") <=0 ) return -CMDERR_BADSEP;
+ }
+ if (!con_cnt) return -CMDERR_BADCFG;
+ i = 0;
+ while (1) {
+ if(si_long(&s, &val, 10) <0 ) return -CMDERR_BADPAR;
+ mcs = pxmc_coordmv_indx2mcs(mcs_state, i);
+ if(!mcs) return -CMDERR_BADREG;
+ final[i] = val << PXMC_SUBDIV(mcs);
+ if(++i >= con_cnt) break;
+ if(si_fndsep(&s, ",") <= 0) return -CMDERR_BADSEP;
+ }
+ si_skspace(&s);
+ if(*s) return -CMDERR_GARBAG;
+
+ if ((long)(des->info[1]) & 2){
+ if (pxmc_coordmv_relmv(mcs_state, con_cnt, final, mintim)<0)
+ return -1;
+ } else {
+ if (pxmc_coordmv_absmv(mcs_state, con_cnt, final, mintim)<0)
+ return -1;
+ }
+ return 0;
+}
+
+
+int cmd_do_coordspline(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ pxmc_coordmv_state_t *mcs_state = &pxmc_coordmv_state;
+ int con_cnt = mcs_state->mcs_con_cnt;
+ long spline_param[con_cnt * PXMC_SPLINE_ORDER_MAX];
+ int i;
+ int o;
+ int a;
+ long val;
+ long mintim=0;
+ long order;
+ char *s;
+ pxmc_state_t *mcs;
+ if (*param[2] != ':') return -CMDERR_OPCHAR;
+ s = param[3];
+ if ((long)(des->info[1]) & 1) { /* coordinated movement with time */
+ if (si_long(&s,&mintim, 10)<0) return -CMDERR_BADPAR;
+ if (mintim<0) return -CMDERR_BADPAR;
+ if (si_fndsep(&s, ",")<=0) return -CMDERR_BADSEP;
+ }
+ if (!con_cnt) return -CMDERR_BADCFG;
+
+ if (si_long(&s,&order, 10) <0 ) return -CMDERR_BADPAR;
+ if (mintim <0 ) return -CMDERR_BADPAR;
+ if (si_fndsep(&s, ",") <= 0) return -CMDERR_BADSEP;
+
+ if ((order <= 0) || (order > PXMC_SPLINE_ORDER_MAX))
+ return -CMDERR_BADPAR;
+
+ i=0; o=0; a=0;
+ while (1) {
+ if (si_long(&s, &val, 10) < 0) return -CMDERR_BADPAR;
+ mcs = pxmc_coordmv_indx2mcs(mcs_state, a);
+ if (!mcs) return -CMDERR_BADREG;
+ spline_param[i] = val << PXMC_SUBDIV(mcs);;
+ i++;
+ if (++o >= order) {
+ o = 0;
+ if (++a >= con_cnt) break;
+ }
+ if (si_fndsep(&s, ",") <= 0) return -CMDERR_BADSEP;
+ }
+ si_skspace(&s);
+ if(*s) return -CMDERR_GARBAG;
+
+ if (pxmc_coordmv_spline(mcs_state, i, spline_param, order, mintim) < 0)
+ return -1;
+ return 0;
+}
+
+
+int cmd_do_coordgrp(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ pxmc_coordmv_state_t *mcs_state = &pxmc_coordmv_state;
+ pxmc_state_list_t *reg_list = mcs_state->mcs_con_list;
+ int reg_max = reg_list->pxml_cnt;
+ int ret;
+ unsigned chan;
+ int con_indx[reg_max];
+ int con_cnt=0;
+ char *s;
+ if (*param[2] != ':') return -CMDERR_OPCHAR;
+ s = param[3];
+ do{
+ si_skspace(&s);
+ if (!*s) break;
+ chan = *(s++) - 'A';
+ if (chan >= reg_max) return -CMDERR_BADREG;
+ con_indx[con_cnt] = chan;
+ con_cnt++;
+ if ((ret = si_fndsep(&s, ",")) < 0) return -CMDERR_BADSEP;
+ if (ret == 0) break;
+ } while (1);
+
+ return pxmc_coordmv_grp(mcs_state, con_cnt, con_indx);
+}
+
+cmd_des_t const cmd_des_coordmv={0, CDESM_OPCHR|CDESM_WR,
+ "COORDMV","initiate coordinated movement to point f1,f2,...",cmd_do_coordmv,
+ {0,0}};
+cmd_des_t const cmd_des_coordmvt={0, CDESM_OPCHR|CDESM_WR,
+ "COORDMVT","coord. movement with time to point mintime,f1,f2,...",cmd_do_coordmv,
+ {0,(char*)1}};
+cmd_des_t const cmd_des_coordrelmvt={0, CDESM_OPCHR|CDESM_WR,
+ "COORDRELMVT","coord. relative movement with time to point mintime,f1,f2,...",
+ cmd_do_coordmv,
+ {0,(char*)3}};
+cmd_des_t const cmd_des_coordsplinet={0, CDESM_OPCHR|CDESM_WR,
+ "COORDSPLINET","coord. spline movement with time to point mintime,order,a11,a12,...,a21,..",
+ cmd_do_coordspline,
+ {0,(char*)1}};
+cmd_des_t const cmd_des_coordgrp={0, CDESM_OPCHR|CDESM_WR,
+ "COORDGRP","group axes for COORDMV, for ex. C,D,F",cmd_do_coordgrp,
+ {0,0}};
+cmd_des_t const cmd_des_coorddiscont={0, CDESM_OPCHR|CDESM_RW,
+ "COORDDISCONT","max relative discontinuity between segs",cmd_do_rw_long,
+ {(char*)&pxmc_coordmv_state.mcs_disca,
+ 0}};
+
+cmd_des_t const *const cmd_pxmc_coordmv[]={
+ &cmd_des_coordmv,
+ &cmd_des_coordmvt,
+ &cmd_des_coordrelmvt,
+ &cmd_des_coordsplinet,
+ &cmd_des_coordgrp,
+ &cmd_des_coorddiscont,
+ NULL
+};
--- /dev/null
+#ifndef _TEST_LPC_H
+#define _TEST_LPC_H
+
+#ifdef __cplusplus
+/*extern "C" {*/
+#endif
+
+#include "appl_config.h"
+
+#include <stdint.h>
+
+/*
+#define APPL_RUN_AT_MAIN_LOOP do { \
+ pxmc_coordmv_process(); \
+ } while(0)
+*/
+
+int pxmc_initialize(void);
+
+int pxmc_done(void);
+
+#ifdef __cplusplus
+/*}*/ /* extern "C"*/
+#endif
+
+#endif /* _TEST_LPC_H */
+
--- /dev/null
+#include <system_def.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "appl_defs.h"
+#include "appl_utils.h"
+#include "rpi_gpio.h"
+#include "rpi_gpclk.h"
+
+void appl_stop(void)
+{
+ pxmc_done();
+ fprintf(stderr, "Application abnormal termination\n");
+ sleep(1);
+}
+
+/***********************************/
+int main(int argc, char *argv[])
+{
+ appl_setup_environment(argv[0]);
+
+ /* initialize 50 Mhz clock output on gpio 4 */
+ if (rpi_peripheral_registers_map() < 0) {
+ fprintf(stderr, "%s: rpi_peripheral_registers_map failed\n", argv[0]);
+ return -1;
+ }
+
+ if (rpi_gpclk_setup(0, RPI_GPCLK_PLLD_500_MHZ, 10, 0) < 0) {
+ fprintf(stderr, "%s: rpi_gpclk_setup failed\n", argv[0]);
+ return -1;
+ }
+
+ if (rpi_gpio_alt_fnc(4 /*gpio*/, 0/*alt_fnc*/) < 0) {
+ fprintf(stderr, "%s: rpi_gpio_alt_fnc failed\n", argv[0]);
+ return -1;
+ }
+
+ pxmc_initialize();
+
+ do {
+ cmdproc_poll();
+ } while(1);
+
+ return 0;
+}
+
--- /dev/null
+/*******************************************************************
+ Motion and Robotic System (MARS) aplication components.
+
+ appl_pxmc.c - SPI connected motor control board specific
+ extensionsposition
+
+ Copyright (C) 2001-2015 by Pavel Pisa - originator
+ pisa@cmp.felk.cvut.cz
+ (C) 2001-2015 by PiKRON Ltd. - originator
+ http://www.pikron.com
+
+ This file can be used and copied according to next
+ license alternatives
+ - GPL - GNU Public License
+ - other license provided by project originators
+
+ *******************************************************************/
+
+#include <cpu_def.h>
+#include <system_def.h>
+#include <pxmc.h>
+#include <pxmc_internal.h>
+#include <pxmc_inp_common.h>
+#include <pxmc_gen_info.h>
+#include <pxmc_dq_trans.h>
+#include <pxmc_sin_fixed.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if !defined(clzl) && !defined(HAVE_CLZL)
+#define clzl __builtin_clzl
+#endif
+
+#include "appl_defs.h"
+#include "appl_pxmc.h"
+#include "appl_utils.h"
+
+#include "pxmc_spimc.h"
+
+pthread_t pxmc_base_thread_id;
+
+int pxmc_ptofs_from_index(pxmc_state_t *mcs, unsigned long irc,
+ unsigned long index_irc, int diff2err);
+
+#define PXML_MAIN_CNT 1
+
+#undef PXMC_WITH_PT_ZIC
+#define PXMC_PT_ZIC_MASK 0x8000
+
+#define HAL_ERR_SENSITIVITY 20
+#define HAL_ERR_MAX_COUNT 5
+
+#define PXMC_LXPWR_PWM_CYCLE 2048
+
+unsigned pxmc_spimc_pwm_magnitude = PXMC_LXPWR_PWM_CYCLE;
+
+unsigned pxmc_spimc_mark_filt[PXML_MAIN_CNT];
+unsigned pxmc_spimc_lxpwr_chips = 0;
+int appl_errstop_mode = 0;
+
+static inline
+pxmc_spimc_state_t *pxmc_state2spimc_state(pxmc_state_t *mcs)
+{
+ pxmc_spimc_state_t *mcsrc;
+ #ifdef UL_CONTAINEROF
+ mcsrc = UL_CONTAINEROF(mcs, pxmc_spimc_state_t, base);
+ #else /*UL_CONTAINEROF*/
+ mcsrc = (pxmc_spimc_state_t*)((char*)mcs - __builtin_offsetof(pxmc_spimc_state_t, base));
+ #endif /*UL_CONTAINEROF*/
+ return mcsrc;
+}
+
+const uint8_t onesin10bits[1024]={
+ 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
+ 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
+ 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
+ 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
+ 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
+ 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
+ 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
+ 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
+ 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
+ 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,
+ 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
+ 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
+ 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
+ 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
+ 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
+ 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
+ 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
+ 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,
+ 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
+ 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,
+ 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,
+ 5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10
+};
+
+int
+pxmc_inp_spimc_inp(struct pxmc_state *mcs)
+{
+ pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
+ int chan=mcs->pxms_inp_info;
+ long irc;
+ long pos;
+
+ /* read position from hardware */
+ irc = mcsrc->spimc_state->act_pos;
+ irc += mcsrc->spimc_state->pos_offset;
+ pos = irc << PXMC_SUBDIV(mcs);
+ mcs->pxms_as = pos - mcs->pxms_ap;
+ mcs->pxms_ap = pos;
+
+ /* Running of the motor commutator */
+ if (mcs->pxms_flg & PXMS_PTI_m)
+ pxmc_irc_16bit_commindx(mcs, irc);
+
+ return 0;
+}
+
+int
+pxmc_inp_spimc_ap2hw(struct pxmc_state *mcs)
+{
+ pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
+ int chan=mcs->pxms_inp_info;
+ long irc;
+ long pos_diff;
+
+ irc = mcsrc->spimc_state->act_pos;
+ pos_diff = mcs->pxms_ap - (irc << PXMC_SUBDIV(mcs));
+
+ irc = pos_diff >> PXMC_SUBDIV(mcs);
+
+ /* Adjust phase table alignemt to modified IRC readout */
+ mcs->pxms_ptofs += irc - mcsrc->spimc_state->pos_offset;
+
+ mcsrc->spimc_state->pos_offset = irc;
+ return 0;
+}
+
+inline unsigned
+pxmc_spimc_bldc_hal_rd(pxmc_state_t *mcs)
+{
+ pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
+ unsigned h = 0;
+ int chan = mcs->pxms_out_info;
+
+ h = mcsrc->spimc_state->hal_sensors;
+
+ /* return 3 bits corresponding to the HAL senzor input */
+ return h;
+}
+
+#if 1
+const unsigned char pxmc_lpc_bdc_hal_pos_table[8] =
+{
+ [0] = 0xff,
+ [7] = 0xff,
+ [1] = 0, /*0*/
+ [5] = 1, /*1*/
+ [4] = 2, /*2*/
+ [6] = 3, /*3*/
+ [2] = 4, /*4*/
+ [3] = 5, /*5*/
+};
+#else
+const unsigned char pxmc_lpc_bdc_hal_pos_table[8] =
+{
+ [0] = 0xff,
+ [7] = 0xff,
+ [1] = 0, /*0*/
+ [5] = 5, /*1*/
+ [4] = 4, /*2*/
+ [6] = 3, /*3*/
+ [2] = 2, /*4*/
+ [3] = 1, /*5*/
+};
+#endif
+
+int pxmc_spimc_pwm_direct_wr(unsigned chan, unsigned pwm, int en)
+{
+
+ return 0;
+}
+
+/**
+ * pxmc_spimc_pwm3ph_wr - Output of the 3-phase PWM to the hardware
+ * @mcs: Motion controller state information
+ */
+/*static*/ inline void
+pxmc_spimc_pwm3ph_wr(pxmc_state_t *mcs, uint32_t pwm1, uint32_t pwm2, uint32_t pwm3)
+{
+ pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
+ int chan = mcs->pxms_out_info;
+
+ mcsrc->spimc_state->pwm[0] = pwm1;
+ mcsrc->spimc_state->pwm[1] = pwm2;
+ mcsrc->spimc_state->pwm[2] = pwm3;
+}
+
+static inline void
+pxmc_spimc_process_hal_error(struct pxmc_state *mcs)
+{
+ if (mcs->pxms_halerc >= HAL_ERR_SENSITIVITY * HAL_ERR_MAX_COUNT)
+ {
+ pxmc_set_errno(mcs, PXMS_E_HAL);
+ mcs->pxms_ene = 0;
+ mcs->pxms_halerc--;
+ }
+ else
+ mcs->pxms_halerc += HAL_ERR_SENSITIVITY;
+}
+
+pxmc_inp_spimc_ptofs_from_index_poll(struct pxmc_state *mcs, int diff2err)
+{
+ pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
+ int chan=mcs->pxms_inp_info;
+ long irc;
+ long index_irc;
+
+ if (1)
+ return 0;
+
+ irc = mcsrc->spimc_state->act_pos + mcsrc->spimc_state->pos_offset;
+ index_irc = mcsrc->spimc_state->index_pos + mcsrc->spimc_state->pos_offset;
+
+ return pxmc_ptofs_from_index(mcs, irc, index_irc, diff2err);
+}
+
+/**
+ * pxmc_spimc_pwm3ph_out - Phase output for brush-less 3-phase motor
+ * @mcs: Motion controller state information
+ */
+int
+pxmc_spimc_pwm3ph_out(pxmc_state_t *mcs)
+{
+ pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
+ typeof(mcs->pxms_ptvang) ptvang;
+ int sync_mode = 0;
+ unsigned char hal_pos;
+ uint32_t pta;
+ int32_t sin_val, cos_val;
+ int32_t pwm_d, pwm_q;
+ int32_t pwm_alp, pwm_bet;
+ uint32_t pwm1, pwm2, pwm3;
+ short ene;
+ int wind_current[4];
+
+ if (!(mcs->pxms_flg & PXMS_PTI_m) || !(mcs->pxms_flg & PXMS_PHA_m) ||
+ (mcs->pxms_flg & PXMS_PRA_m))
+ {
+ short ptindx;
+ short ptirc = mcs->pxms_ptirc;
+ short divisor = mcs->pxms_ptper * 6;
+
+ hal_pos = pxmc_lpc_bdc_hal_pos_table[pxmc_spimc_bldc_hal_rd(mcs)];
+
+ if (hal_pos == 0xff)
+ {
+ if (mcs->pxms_ene)
+ pxmc_spimc_process_hal_error(mcs);
+ }
+ else
+ {
+ if (mcs->pxms_halerc)
+ mcs->pxms_halerc--;
+
+ ptindx = (hal_pos * ptirc + divisor / 2) / divisor;
+
+ if (!(mcs->pxms_flg & PXMS_PTI_m) || (mcs->pxms_flg & PXMS_PRA_m))
+ {
+ if (((hal_pos != mcs->pxms_hal) && (mcs->pxms_hal != 0x40)) && 1)
+ {
+ short ptindx_prev = (mcs->pxms_hal * ptirc + divisor / 2) / divisor;;
+
+ if ((ptindx > ptindx_prev + ptirc / 2) ||
+ (ptindx_prev > ptindx + ptirc / 2))
+ {
+ ptindx = (ptindx_prev + ptindx - ptirc) / 2;
+
+ if (ptindx < 0)
+ ptindx += ptirc;
+ }
+ else
+ {
+ ptindx = (ptindx_prev + ptindx) / 2;
+ }
+
+ mcs->pxms_ptindx = ptindx;
+
+ mcs->pxms_ptofs = (mcs->pxms_ap >> PXMC_SUBDIV(mcs)) + mcs->pxms_ptshift - ptindx;
+
+ pxmc_set_flag(mcs, PXMS_PTI_b);
+ pxmc_clear_flag(mcs, PXMS_PRA_b);
+ }
+ else
+ {
+ if (!(mcs->pxms_flg & PXMS_PTI_m))
+ mcs->pxms_ptindx = ptindx;
+ }
+ } else {
+ /* if phase table position to mask is know do fine phase table alignment */
+ if (mcs->pxms_cfg & PXMS_CFG_I2PT_m) {
+ int res;
+ res = pxmc_inp_spimc_ptofs_from_index_poll(mcs, 0);
+ if (res < 0) {
+ pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
+ } else if (res) {
+ pxmc_set_flag(mcs, PXMS_PTI_b);
+ pxmc_set_flag(mcs, PXMS_PHA_b);
+ }
+ }
+ }
+ mcs->pxms_hal = hal_pos;
+ }
+ }
+
+ {
+ /*wind_current[0]=(ADC->ADDR0 & 0xFFF0)>>4;*/
+ /* FIXME - check winding current against limit */
+ /* pxmc_set_errno(mcs, PXMS_E_WINDCURRENT); */
+ }
+
+ if (!sync_mode) {
+ ptvang = mcs->pxms_ptvang;
+ pwm_d = 0;
+ pwm_q = mcs->pxms_ene;
+ } else {
+ ptvang = 0;
+ pwm_d = mcs->pxms_flg & PXMS_BSY_m? mcs->pxms_me: 0;
+ pwm_q = 0;
+ }
+
+ if (pwm_d || pwm_q) {
+ int32_t indx;
+ uint32_t ptscale_mult = mcs->pxms_ptscale_mult |
+ (mcs->pxms_ptscale_shift << 16);
+
+ indx = mcs->pxms_ptindx;
+
+ if (indx < 0)
+ pta = indx + mcs->pxms_ptirc;
+ else
+ pta = indx;
+
+ pta *= ptscale_mult;
+
+ pta -= PXMC_SIN_FIX_2PI3;
+
+ pxmc_sincos_fixed_inline(&sin_val, &cos_val, pta, 16);
+ pxmc_dq2alpbet(&pwm_alp, &pwm_bet, pwm_d, pwm_q, sin_val, cos_val);
+ pxmc_alpbet2pwm3ph(&pwm1, &pwm2, &pwm3, pwm_alp, pwm_bet);
+
+ /*printf("pwm d %4d q %4d alp %4d bet %4d a %4d b %4d c %4d\n",
+ pwm_d, pwm_q, pwm_alp >> 16, pwm_bet >> 16, pwm1, pwm2, pwm3);*/
+
+
+#ifdef PXMC_WITH_PT_ZIC
+ if (labs(mcs->pxms_as) < (10 << PXMC_SUBDIV(mcs)))
+ {
+ }
+#endif /*PXMC_WITH_PT_ZIC*/
+
+ /* Default phase-table amplitude is 0x7fff, ene max is 0x7fff */
+ /* Initialized CTM4 PWM period is 0x200 => divide by value about 2097024 */
+ {
+ unsigned long pwm_mag = pxmc_spimc_pwm_magnitude;
+ if (0)
+ pwm1 = SPIMC_PWM_SHUTDOWN;
+ else
+ pwm1 = (((unsigned long long)pwm1 * pwm_mag) >> 15) | SPIMC_PWM_ENABLE;
+ if (0)
+ pwm2 = SPIMC_PWM_SHUTDOWN;
+ else
+ pwm2 = (((unsigned long long)pwm2 * pwm_mag) >> 15) | SPIMC_PWM_ENABLE;
+ if (0)
+ pwm3 = SPIMC_PWM_SHUTDOWN;
+ else
+ pwm3 = (((unsigned long long)pwm3 * pwm_mag) >> 15) | SPIMC_PWM_ENABLE;
+ }
+ pxmc_spimc_pwm3ph_wr(mcs, pwm1, pwm2, pwm3);
+
+ }
+ else
+ {
+ pxmc_spimc_pwm3ph_wr(mcs, 0, 0, 0);
+ }
+
+ /*printf("hal_pos %d pwm %4d %4d %4d\n", hal_pos, pwm1 & 0xffff,
+ pwm2 & 0xffff, pwm3 & 0xffff);*/
+
+ return 0;
+}
+
+/**
+ * pxmc_spimc_pwm_dc_out - DC motor CW and CCW PWM output
+ * @mcs: Motion controller state information
+ */
+int
+pxmc_spimc_pwm_dc_out(pxmc_state_t *mcs)
+{
+ int chan = mcs->pxms_out_info;
+ int ene = mcs->pxms_ene;
+
+
+ if (ene < 0) {
+ ene = -ene;
+ if (ene > 0x7fff)
+ ene = 0x7fff;
+ ene = (ene * (pxmc_spimc_pwm_magnitude + 5)) >> 15;
+ /**pwm_reg_a = 0;*/
+ /**pwm_reg_b = ene | 0x4000;*/
+ } else {
+ if (ene > 0x7fff)
+ ene = 0x7fff;
+ ene = (ene * (pxmc_spimc_pwm_magnitude + 5)) >> 15;
+ /**pwm_reg_b = 0;*/
+ /**pwm_reg_a = ene | 0x4000;*/
+ }
+
+ return 0;
+}
+
+int pxmc_ptofs_from_index(pxmc_state_t *mcs, unsigned long irc,
+ unsigned long index_irc, int diff2err)
+{
+ long ofsl;
+ short ofs;
+
+ ofs = ofsl = index_irc - mcs->pxms_ptmark;
+
+ if (diff2err) {
+ short diff;
+ diff = (unsigned short)ofs - (unsigned short)mcs->pxms_ptofs;
+ if (diff >= mcs->pxms_ptirc / 2)
+ diff -= mcs->pxms_ptirc;
+ if (diff <= -mcs->pxms_ptirc / 2)
+ diff += mcs->pxms_ptirc;
+ if (diff < 0)
+ diff = -diff;
+ if(diff >= mcs->pxms_ptirc / 6) {
+ return -1;
+ }
+ } else {
+ long diff;
+ diff = (unsigned long)ofsl - irc;
+ ofs = ofsl - (diff / mcs->pxms_ptirc) * mcs->pxms_ptirc;
+ }
+
+ mcs->pxms_ptofs = ofs;
+
+ return 1;
+}
+
+/**
+ * pxmc_dummy_con - Dummy controller for synchronous BLDC/PMSM/steper drive
+ * @mcs: Motion controller state information
+ */
+int
+pxmc_dummy_con(pxmc_state_t *mcs)
+{
+ return 0;
+}
+
+pxmc_call_t *pxmc_get_hh_gi_4axis(pxmc_state_t *mcs)
+{
+ return NULL;
+}
+
+int pxmc_fill_ptscale_for_sin_fixed(pxmc_state_t *mcs)
+{
+ unsigned long ptirc = mcs->pxms_ptirc;
+ unsigned long ptper = mcs->pxms_ptper;
+ unsigned long scale_mult;
+ unsigned long scale_shift;
+ int shift;
+
+ shift = clzl(ptper);
+ ptper <<= shift;
+
+ scale_mult = (ptper + ptirc / 2) / ptirc;
+ if (shift < 32)
+ scale_mult <<= 32 - shift;
+ if (shift > 32)
+ scale_mult >>= shift - 32;
+
+ mcs->pxms_ptscale_mult = scale_mult & 0xffff;
+ mcs->pxms_ptscale_shift = scale_mult >> 16;
+
+ return 0;
+}
+
+spimc_state_t spimc_state0 = {
+ .spi_dev = "/dev/spidev0.1",
+};
+
+pxmc_spimc_state_t mcs0 =
+{
+.base = {
+.pxms_flg =
+ PXMS_ENI_m,
+.pxms_do_inp =
+ pxmc_inp_spimc_inp,
+.pxms_do_con =
+ pxmc_pid_con /*pxmc_dummy_con*/,
+.pxms_do_out =
+ pxmc_spimc_pwm3ph_out /*pxmc_spimc_pwm_dc_out*/,
+ .pxms_do_deb = 0,
+ .pxms_do_gen = 0,
+.pxms_do_ap2hw =
+ pxmc_inp_spimc_ap2hw,
+ .pxms_ap = 0, .pxms_as = 0,
+ .pxms_rp = 55 * 256, .pxms_rs = 0,
+ #ifndef PXMC_WITH_FIXED_SUBDIV
+ .pxms_subdiv = 8,
+ #endif /*PXMC_WITH_FIXED_SUBDIV*/
+ .pxms_md = 800 << 8, .pxms_ms = 500, .pxms_ma = 10,
+ .pxms_inp_info = 0,
+ .pxms_out_info = 0,
+ .pxms_ene = 0, .pxms_erc = 0,
+ .pxms_p = 80, .pxms_i = 10, .pxms_d = 200, .pxms_s1 = 200, .pxms_s2 = 0,
+ .pxms_me = 0x7e00/*0x7fff*/,
+.pxms_cfg =
+ PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
+ PXMS_CFG_HRI_m * 0 | PXMS_CFG_HDIR_m * 0 |
+ PXMS_CFG_I2PT_m * 0 | 0x2,
+
+ .pxms_ptper = 1,
+ .pxms_ptirc = 1000,
+ .pxms_ptmark = 1180,
+ /*.pxms_ptamp = 0x7fff,*/
+
+ .pxms_hal = 0x40,
+},
+ .spimc_state = &spimc_state0,
+ .cur_d_p = 150,
+ .cur_d_i = 6000,
+ .cur_q_p = 150,
+ .cur_q_i = 6000,
+ .cur_hold = 200,
+};
+
+
+pxmc_state_t *pxmc_main_arr[PXML_MAIN_CNT] = {&mcs0.base};
+
+
+pxmc_state_list_t pxmc_main_list =
+{
+.pxml_arr =
+ pxmc_main_arr,
+ .pxml_cnt = 0
+};
+
+
+static inline void pxmc_sfi_input(void)
+{
+ int var;
+ pxmc_state_t *mcs;
+ pxmc_for_each_mcs(var, mcs)
+ {
+ /* PXMS_ENI_m - check if input (IRC) update is enabled */
+ if (mcs->pxms_flg & PXMS_ENI_m)
+ {
+ pxmc_call(mcs, mcs->pxms_do_inp);
+ }
+ }
+}
+
+static inline void pxmc_sfi_controller_and_output(void)
+{
+ int var;
+ pxmc_state_t *mcs;
+ pxmc_for_each_mcs(var, mcs)
+ {
+ /* PXMS_ENR_m - check if controller is enabled */
+ if (mcs->pxms_flg & PXMS_ENR_m || mcs->pxms_flg & PXMS_ENO_m)
+ {
+
+ /* If output only is enabled, we skip the controller */
+ if (mcs->pxms_flg & PXMS_ENR_m)
+ {
+
+ pxmc_call(mcs, mcs->pxms_do_con);
+
+ /* PXMS_ERR_m - if axis in error state */
+ if (mcs->pxms_flg & PXMS_ERR_m)
+ mcs->pxms_ene = 0;
+ }
+
+ /* for bushless motors, it is necessary to call do_out
+ even if the controller is not enabled and PWM should be provided. */
+ pxmc_call(mcs, mcs->pxms_do_out);
+ }
+ }
+}
+
+static inline void pxmc_sfi_generator(void)
+{
+ int var;
+ pxmc_state_t *mcs;
+ pxmc_for_each_mcs(var, mcs)
+ {
+ /* PXMS_ENG_m - check if requested value (position) generator is enabled */
+ if (mcs->pxms_flg & PXMS_ENG_m)
+ {
+ pxmc_call(mcs, mcs->pxms_do_gen);
+ }
+ }
+}
+
+static inline void pxmc_sfi_dbg(void)
+{
+ int var;
+ pxmc_state_t *mcs;
+ pxmc_for_each_mcs(var, mcs)
+ {
+ if (mcs->pxms_flg & PXMS_DBG_m)
+ {
+ pxmc_call(mcs, mcs->pxms_do_deb);
+ }
+ }
+}
+
+static inline void pxmc_spimc_rq_transfer(void)
+{
+ int var;
+ pxmc_state_t *mcs;
+ pxmc_spimc_state_t *mcsrc;
+
+ pxmc_for_each_mcs(var, mcs)
+ {
+ mcsrc = pxmc_state2spimc_state(mcs);
+ spimc_transfer(mcsrc->spimc_state);
+ }
+}
+
+void pxmc_samplig_period(void)
+{
+ pxmc_sfi_input();
+ pxmc_sfi_controller_and_output();
+ pxmc_spimc_rq_transfer();
+ pxmc_sfi_generator();
+ pxmc_sfi_dbg();
+
+ do_pxmc_coordmv();
+}
+
+void *pxmc_base_thread(void *arg)
+{
+ sample_period_t sample_period;
+ sample_period_setup(&sample_period, 1000 * 1000);
+
+ do {
+ pxmc_samplig_period();
+ sample_period_wait_next(&sample_period);
+ } while(1);
+}
+
+int pxmc_clear_power_stop(void)
+{
+ return 0;
+}
+
+int pxmc_process_state_check(unsigned long *pbusy_bits,
+ unsigned long *perror_bits)
+{
+ unsigned short flg;
+ unsigned short chan;
+ unsigned long busy_bits = 0;
+ unsigned long error_bits = 0;
+ pxmc_state_t *mcs;
+ flg=0;
+ pxmc_for_each_mcs(chan, mcs) {
+ if(mcs) {
+ flg |= mcs->pxms_flg;
+ if (mcs->pxms_flg & PXMS_BSY_m)
+ busy_bits |= 1 << chan;
+ if (mcs->pxms_flg & PXMS_ERR_m)
+ error_bits |= 1 << chan;
+ }
+ }
+ if (appl_errstop_mode) {
+ if((flg & PXMS_ENG_m) && (flg & PXMS_ERR_m)) {
+ pxmc_for_each_mcs(chan, mcs) {
+ if(mcs&&(mcs->pxms_flg & PXMS_ENG_m)) {
+ pxmc_stop(mcs, 0);
+ }
+ }
+ }
+ }
+
+ if (pbusy_bits != NULL)
+ *pbusy_bits = busy_bits;
+ if (error_bits != NULL)
+ *perror_bits = error_bits;
+
+ return flg;
+}
+
+/**
+ * pxmc_axis_mode - Sets axis mode.[extern API]
+ * @mcs: Motion controller state information
+ * @mode: 0 .. previous mode, 1 .. stepper motor mode,
+ * 2 .. stepper motor with IRC feedback and PWM ,
+ * 3 .. stepper motor with PWM control
+ * 4 .. DC motor with IRC feedback and PWM
+ *
+ */
+int
+pxmc_axis_mode(pxmc_state_t *mcs, int mode)
+{
+ return 0;
+}
+
+int pxmc_done(void)
+{
+ int var;
+ pxmc_state_t *mcs;
+
+ if (!pxmc_main_list.pxml_cnt)
+ return 0;
+
+ pxmc_for_each_mcs(var, mcs)
+ {
+ pxmc_axis_release(mcs);
+ }
+
+ pxmc_main_list.pxml_cnt = 0;
+ __memory_barrier();
+
+ return 0;
+}
+
+int pxmc_initialize(void)
+{
+ int res;
+
+ pxmc_main_list.pxml_cnt = 0;
+ pxmc_dbg_hist = NULL;
+
+ if (spimc_init(mcs0.spimc_state) < 0)
+ return -1;
+
+ pxmc_fill_ptscale_for_sin_fixed(pxmc_main_list.pxml_arr[0]);
+
+ __memory_barrier();
+ pxmc_main_list.pxml_cnt = PXML_MAIN_CNT;
+
+ if (create_rt_task(&pxmc_base_thread_id, 60, pxmc_base_thread, NULL) < 0)
+ return -1;
+
+ return 0;
+}
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ appl_pxmc.h - SPI connected motor control board specific
+ extensions
+
+ (C) 2001-2015 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002-2015 by PiKRON Ltd. http://www.pikron.com
+
+ This file can be used and copied according to next
+ license alternatives
+ - GPL - GNU Public License
+ - other license provided by project originators
+
+ *******************************************************************/
+
+#ifndef _APPL_PXMC_H_
+#define _APPL_PXMC_H_
+
+#include <stdint.h>
+#include <pxmc.h>
+
+struct spimc_state_t;
+
+typedef struct pxmc_spimc_state_t {
+ pxmc_state_t base;
+ struct spimc_state_t *spimc_state;
+ uint32_t steps_pos_prev;
+ uint32_t cur_d_cum_prev;
+ uint32_t cur_q_cum_prev;
+ int32_t cur_d_err_sum;
+ int32_t cur_q_err_sum;
+ short cur_d_p;
+ short cur_d_i;
+ short cur_q_p;
+ short cur_q_i;
+ short cur_hold;
+} pxmc_spimc_state_t;
+
+#define pxmc_spimc_state_offs(_fld) \
+ (((size_t)&((pxmc_spimc_state_t *)0L)->_fld) - \
+ ((size_t)&((pxmc_spimc_state_t *)0L)->base))
+
+extern int appl_errstop_mode;
+extern int appl_idlerel_time;
+int pxmc_process_state_check(unsigned long *pbusy_bits,
+ unsigned long *perror_bits);
+
+int pxmc_spimc_pwm_direct_wr(unsigned chan, unsigned pwm, int en);
+
+int pxmc_spimc_wait_rx_done(void);
+
+#endif /*_APPL_PXMC_H_*/
--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <sys/mman.h> /* this provides mlockall() */
+#include <pthread.h>
+#include <signal.h>
+#include <time.h>
+
+#include "appl_utils.h"
+
+int appl_base_task_prio;
+
+int create_rt_task(pthread_t *thread, int prio, void *(*start_routine) (void *), void *arg)
+{
+ int ret ;
+
+ pthread_attr_t attr;
+ struct sched_param schparam;
+
+ if (pthread_attr_init(&attr) != 0) {
+ fprintf(stderr, "pthread_attr_init failed\n");
+ return -1;
+ }
+
+ if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) != 0) {
+ fprintf(stderr, "pthread_attr_setinheritsched failed\n");
+ return -1;
+ }
+
+ if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO) != 0) {
+ fprintf(stderr, "pthread_attr_setschedpolicy SCHED_FIFO failed\n");
+ return -1;
+ }
+
+ schparam.sched_priority = prio;
+
+ if (pthread_attr_setschedparam(&attr, &schparam) != 0) {
+ fprintf(stderr, "pthread_attr_setschedparam failed\n");
+ return -1;
+ }
+
+ ret = pthread_create(thread, &attr, start_routine, arg);
+
+ pthread_attr_destroy(&attr);
+
+ return ret;
+}
+
+int sample_period_setup(sample_period_t *sper, unsigned long pernsec)
+{
+ sper->period_nsec = pernsec;
+ clock_gettime(CLOCK_MONOTONIC, &sper->period_time);
+ return 0;
+}
+
+int sample_period_wait_next(sample_period_t *sper)
+{
+ sper->period_time.tv_nsec += sper->period_nsec;
+ if (sper->period_time.tv_nsec > 1000*1000*1000) {
+ sper->period_time.tv_nsec -= 1000*1000*1000;
+ sper->period_time.tv_sec += 1;
+ }
+ return clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &sper->period_time, NULL);
+}
+
+void appl_sig_handler(int sig)
+{
+ appl_stop();
+ exit(1);
+}
+
+int appl_setup_environment(const char *argv0)
+{
+ struct sigaction sigact;
+ int fifo_min_prio = sched_get_priority_min(SCHED_FIFO);
+ int fifo_max_prio = sched_get_priority_max(SCHED_FIFO);
+
+ appl_base_task_prio = fifo_max_prio - 20;
+ if (appl_base_task_prio < fifo_min_prio)
+ appl_base_task_prio = fifo_min_prio;
+
+
+ if (mlockall(MCL_FUTURE | MCL_CURRENT) < 0) {
+ fprintf(stderr, "%s: mlockall failed - cannot lock application in memory\n", argv0);
+ exit(1);
+ }
+
+ atexit(appl_stop);
+
+ memset(&sigact, 0, sizeof(sigact));
+ sigact.sa_handler = appl_sig_handler;
+ sigaction(SIGINT, &sigact, NULL);
+ sigaction(SIGTERM, &sigact, NULL);
+
+ return 0;
+}
--- /dev/null
+#ifndef _APPL_UTILS_H
+#define _APPL_UTILS_H
+
+#include <pthread.h>
+#include <time.h>
+
+extern int appl_base_task_prio;
+
+typedef struct sample_period_t {
+ unsigned long period_nsec;
+ struct timespec period_time;
+} sample_period_t;
+
+int sample_period_setup(sample_period_t *sper, unsigned long pernsec);
+
+int sample_period_wait_next(sample_period_t *sper);
+
+int create_rt_task(pthread_t *thread, int prio, void *(*start_routine) (void *), void *arg);
+
+extern void appl_stop(void);
+
+int appl_setup_environment(const char *argv0);
+
+#endif /*_APPL_UTILS_H*/
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+
+# ps Hxaww --sort rtprio -o pid,policy,rtprio,state,tname,time,command
+
+SPI_PIDS=$(ps Hxa -o command,pid | \
+ sed -n -e 's/^\[\(irq\/80-bcm2708_\|bcm2708_spi\.0\)\][ \t]*\([0-9]*\)$/\2/p')
+
+for P in $SPI_PIDS ; do
+ schedtool -F -p 95 $P
+done
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ math_sqrtll.c - fast routine for 64-bit unsigned square root
+
+ Copyright (C) 2001-2014 by Pavel Pisa - originator
+ pisa@cmp.felk.cvut.cz
+ (C) 2001-2014 by PiKRON Ltd. - originator
+ http://www.pikron.com
+
+ This file can be used and copied according to next
+ license alternatives
+ - GPL - GNU Public License
+ - other license provided by project originators
+
+ *******************************************************************/
+
+#define _GNU_SOURCE
+
+#include <string.h>
+#include <stdint.h>
+
+/*
+ y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits
+
+ y := (y+x/y)/2 ... almost 17 sig. bits
+ y := (y+x/y)/2 ... almost 35 sig. bits
+*/
+
+#ifdef __GNUC__
+uint32_t __attribute__((unused))
+#else
+uint32_t
+#endif
+ sqrtll_T1[64]={
+ 2147418619,2146907255,2145906284,2144436844,
+ 2142518597,2140169865,2137407758,2134248281,
+ 2130706432,2126796288,2122531084,2117923281,
+ 2112984627,2107726213,2102158525,2096291488,
+ 2090134507,2083696503,2076985953,2070010911,
+ 2062779045,2055297659,2047573718,2039613867,
+ 2031424454,2023011548,2014380954,2005538230,
+ 1996488704,1987237480,1977789459,1968149347,
+ 1970116061,1983291585,1995774699,2007595298,
+ 2018781187,2029358280,2039350771,2048781297,
+ 2057671066,2066039988,2073906780,2081289063,
+ 2088203452,2094665633,2100690434,2106291892,
+ 2111483306,2116277295,2120685844,2124720346,
+ 2128391644,2131710068,2134685466,2137327238,
+ 2139644360,2141645415,2143338612,2144731814,
+ 2145832551,2146648046,2147185228,2147450751
+};
+
+#if 1
+
+unsigned long sqrtll(unsigned long long x)
+{
+ uint32_t y,t1,t2;
+ uint32_t x0 = x, x1 = x >> 32;
+
+ #ifndef __GNUC__
+
+ if (x1) { /* x[32:63] != 0 */
+ if (x1 & 0xffff0000){ /* x[48:63] != 0 */
+ t1 = x1;
+ if (x1 >= 0xfffffffe) /* exception bypass */
+ return 0xffffffff;
+ t2 = 63;
+ } else { /* x[48:63] == 0 */
+ t1 = x0 >> 16 | x1 << 16;
+ t2 = 47;
+ }
+ } else { /* x[32:64] == 0 */
+ if (!x0) return 0;
+ if (x0 & 0xffff0000){ /* x[16:31] != 0 */
+ t1 = x0;
+ t2 = 31;
+ } else { /* x[16:31] == 0 */
+ t1 = x0 << 16;
+ t2 = 15;
+ }
+ }
+
+ while (!(t1 & 0x80000000)) {
+ t1 <<= 1;
+ t2--;
+ }
+ #else /*__GNUC__*/
+ if (x1) { /* x[32:63] != 0 */
+ if (x1 >= 0xfffffffe) /* exception bypass */
+ return 0xffffffff;
+ t2 = __builtin_clz(x1);
+ t1 = (x1 << t2) | ((x0 >> (32 - t2)));
+ t2 = 63 - t2;
+ } else {
+ if (!x0)
+ return 0;
+ t2 = __builtin_clz(x0);
+ t1 = x0 << t2;
+ t2 = 31 - t2;
+ }
+ #endif /*__GNUC__*/
+
+ if (t2 & 1){
+ t1 |= 0x80000000;
+ } else {
+ t1 &= ~0x80000000;
+ }
+ t2 >>= 1;
+
+ y = t1;
+ t1 >>= 32 - 6;
+ y >>= 1;
+ y += sqrtll_T1[t1];
+ if (t2 != 31) {
+ y >>= 31 - t2 - 1;
+ y = (y >> 1) + (y & 1);
+ }
+ #if 1
+ if (!x1) {
+ y= (y + x0 / y + 1) / 2;
+ y= (y + x0 / y + 1) / 2;
+ } else if (x1 < 0x00010000) {
+ uint32_t y0, y1, y2, xt, r;
+
+ xt = (x1 << 16) | (x0 >> 16);
+ y2 = xt / y;
+ r = xt % y;
+ xt = (r << 8);
+ y1 = xt / y;
+ r = xt % y;
+ xt = (r << 8) + (x0 & 0xffff);
+ y0 = (xt / y) + (y1 << 8) + (y2 << 16);
+ y = (y + y0 + 1) / 2;
+
+ xt = (x1 << 16) | (x0 >> 16);
+ y2 = xt / y;
+ r = xt % y;
+ xt = (r << 8);
+ y1 = xt / y;
+ r = xt % y;
+ xt = (r << 8) + (x0 & 0xffff);
+ y0 = (xt / y) + (y1 << 8) + (y2 << 16);
+ y = (y + y0 + 1) / 2;
+
+ } else
+ #endif
+ {
+ y = (y + x / y + 1) / 2;
+ y = (y + x / y + 1) / 2;
+ }
+ return y;
+}
+
+#ifdef __GNUC__
+
+unsigned long sqrtll_approx(unsigned long long x)
+{
+ unsigned int r;
+ uint32_t x1 = x >> 32;
+ if (x1 < 0x00010000)
+ return sqrtll(x);
+
+ r = __builtin_clz(x1);
+ r = (17 - r) / 2;
+ x1 = sqrtll(x >> (r * 2));
+
+ return x1 << r;
+}
+
+#endif /*__GNUC__*/
+
+#else
+
+unsigned long sqrtll(unsigned long long x)
+{
+ unsigned long y,t1,t2,t3;
+ unsigned long x0=x, x1=x>>32;
+ __asm__ (
+ " movel %2,%3\n"
+ " beqs 2f\n"
+ " swap %3\n"
+ " tstw %3\n"
+ " beqs 1f\n"
+ " movel %2,%3\n" /* x[48:64] != 0 */
+ " movql #63,%4\n"
+ " cmpl #0xfffffffe,%3\n"
+ " bcss 4f\n"
+ " movl #0xffffffff,%0\n"
+ " bras 9f\n"
+
+ "1: movel %1,%4\n" /* x[48:64] == 0 */
+ " swap %4\n"
+ " orw %4,%3\n"
+ " movql #47,%4\n"
+ " bras 4f\n"
+
+ "2: movel %1,%3\n" /* x[32:64] == 0 */
+ " bnes 3f\n"
+ " clrl %0\n" /* x==0 */
+ " bras 9f\n"
+ "3: swap %3\n"
+ " movql #15,%4\n"
+ " tstw %3\n"
+ " beqs 4f\n"
+ " movel %1,%3\n" /* x[16:31] != 0 */
+ " movql #31,%4\n"
+ "4: lsll #1,%3\n" /* %3 .. normalized */
+ " dbcs %4,4b\n" /* %4 .. exponent bit order */
+ " lsrl #1,%4\n"
+ " roxrl #1,%3\n" /* exp%2 -> %4.31, exp/=2 */
+ " movel %3,%0\n"
+ " roll #6,%3\n" /* 6 MSB bits of %4 index to table */
+ " andw #63,%3\n"
+ " lsrl #1,%0\n"
+ " addl @(sqrtll_T1,%3:w:4),%0\n" /* lin. approximated table */
+ " movql #31,%3\n"
+ " subl %4,%3\n"
+ " lsrl %3,%0\n" /* denormalize result */
+
+ " clrl %5\n"
+ " addxl %5,%0\n"
+ " movel %1,%3\n"
+ " movel %2,%4\n"
+ " divul %0,%4,%3\n" /* y := (y+x/y)/2 */
+ " bvcs 5f\n"
+ " subl %0,%4\n" /* divission overflow */
+ " divul %0,%4,%3\n"
+ " addl %3,%0\n"
+ " movql #-1,%3\n"
+ "5: addl %3,%0\n" /* regular path without ov */
+ " roxrl #1,%0\n"
+ " addxl %5,%0\n"
+ "6: movel %1,%3\n"
+ " movel %2,%4\n"
+ " divul %0,%4,%3\n" /* y := (y+x/y)/2 */
+ " addl %3,%0\n"
+ " roxrl #1,%0\n"
+ " addxl %5,%0\n"
+ "9:\n"
+
+ :"=d"(y),"=d"(x0),"=d"(x1),"=d"(t1),"=d"(t2),"=d"(t3)
+ :"1"(x0),"2"(x1)
+ :"cc"
+ );
+
+ return y;
+}
+
+#endif
+
--- /dev/null
+#ifndef _PXMC_SPIMC_H
+#define _PXMC_SPIMC_H
+
+#include <stdint.h>
+
+#define SPIMC_TRANSFER_SIZE 16
+#define SPIMC_CHAN_COUNT 3
+
+#define SPIMC_PWM_VALUE_m 0x0ffff
+#define SPIMC_PWM_ENABLE 0x10000
+#define SPIMC_PWM_SHUTDOWN 0x20000
+
+typedef struct spimc_state_t {
+ char *spi_dev;
+ int spi_fd;
+ uint32_t pwm[SPIMC_CHAN_COUNT];
+ uint32_t act_pos;
+ uint32_t index_pos;
+ uint32_t pos_offset;
+ int32_t curadc_val[SPIMC_CHAN_COUNT];
+ int32_t curadc_offs[SPIMC_CHAN_COUNT];
+ uint8_t hal_sensors;
+ uint16_t curadc_sqn;
+ uint16_t curadc_sqn_last;
+ uint32_t curadc_cumsum[SPIMC_CHAN_COUNT];
+ uint32_t curadc_cumsum_last[SPIMC_CHAN_COUNT];
+ uint8_t tx_buf[SPIMC_TRANSFER_SIZE];
+ uint8_t rx_buf[SPIMC_TRANSFER_SIZE];
+} spimc_state_t;
+
+int spimc_init(spimc_state_t *spimcst);
+
+int spimc_transfer(spimc_state_t *spimcst);
+
+#endif /*_PXMC_SPIMC_H*/
\ No newline at end of file
--- /dev/null
+/**
+ * (C) 2015 by Martin Prudek prudemar@fel.cvut.cz
+ * (C) 2015 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ *
+ * Configuration of the General Purpose Clocks outputs
+ * Inspired by wiringPi written by Gordon Henderson.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <poll.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <sys/time.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+
+#include "rpi_gpio.h"
+#include "rpi_gpclk.h"
+
+#define CLK_GPx_CTL(chan) \
+ (rpi_registers_mapping.clk_base[28 + 2 * (chan)])
+
+#define CLK_GPx_DIV(chan) \
+ (rpi_registers_mapping.clk_base[29 + 2 * (chan)])
+
+#define CLK_CTL_SRC_OSC 1 /* 19.2 MHz */
+#define CLK_CTL_SRC_PLLC 5 /* 1000 MHz */
+#define CLK_CTL_SRC_PLLD 6 /* 500 MHz */
+#define CLK_CTL_SRC_HDMI 7 /* 216 MHz */
+
+#define CLK_PASSWD (0x5A<<24)
+#define CLK_CTL_MASH(x)((x)<<9)
+#define CLK_CTL_BUSY (1 <<7)
+#define CLK_CTL_KILL (1 <<5)
+#define CLK_CTL_ENAB (1 <<4)
+#define CLK_CTL_SRC(x) ((x)<<0)
+
+#define CLK_DIV_DIVI(x) ((x)<<12)
+#define CLK_DIV_DIVF(x) ((x)<< 0)
+
+uint32_t rpi_gpclk_src_to_reg[] = {
+ [RPI_GPCLK_PLLD_500_MHZ] = CLK_CTL_SRC_PLLD,
+ [RPI_GPCLK_OSC_19_MHZ_2] = CLK_CTL_SRC_OSC,
+ [RPI_GPCLK_HDMI_216_MHZ] = CLK_CTL_SRC_HDMI,
+ [RPI_GPCLK_PLLC_1000_MHZ] = CLK_CTL_SRC_PLLD,
+};
+
+int rpi_gpclk_setup(int chan, int source, int div_int, int div_frac)
+{
+ int MASH = 0;
+ uint32_t clksrc;
+
+ if (!rpi_registers_mapping.mapping_initialized)
+ return -1;
+
+ if ((source < 0) || (source > sizeof(rpi_gpclk_src_to_reg) /
+ sizeof(*rpi_gpclk_src_to_reg) ))
+ return -2;
+
+ if ((div_int < 2) || (div_int > 4095))
+ return -3;
+
+ if ((div_frac < 0) || (div_frac > 4095))
+ return -4;
+
+ if ((MASH < 0) || (MASH > 3))
+ return -5;
+
+ clksrc = rpi_gpclk_src_to_reg[source];
+
+ CLK_GPx_CTL(chan) = CLK_PASSWD | CLK_CTL_KILL;
+
+ while (CLK_GPx_CTL(chan) & CLK_CTL_BUSY){
+ usleep(10);
+ }
+
+ CLK_GPx_DIV(chan) = (CLK_PASSWD | CLK_DIV_DIVI(div_int) | CLK_DIV_DIVF(div_frac));
+
+ usleep(10);
+
+ CLK_GPx_CTL(chan) = (CLK_PASSWD | CLK_CTL_MASH(MASH) | CLK_CTL_SRC(clksrc));
+
+ usleep(10);
+
+ CLK_GPx_CTL(chan) |= (CLK_PASSWD | CLK_CTL_ENAB);
+
+ return 0;
+}
--- /dev/null
+#ifndef _RPI_GPCLK_H
+#define _RPI_GPCLK_H
+
+#define RPI_GPCLK_PLLD_500_MHZ 0 /*500 MHz*/
+#define RPI_GPCLK_OSC_19_MHZ_2 1 /*19.2 MHz*/
+#define RPI_GPCLK_HDMI_216_MHZ 2 /*216 MHz*/
+#define RPI_GPCLK_PLLC_1000_MHZ 3 /*1000 MHz, changes with overclock*/
+
+int rpi_gpclk_setup(int chan, int source, int div_int, int div_frac);
+
+#endif /*_RPI_GPCLK_H*/
\ No newline at end of file
--- /dev/null
+/*
+ * Bidirectional pwm_base on Raspberry Pi module
+ *
+ * Copyright (C) 2014 Pavel Pisa <pisa@cmp.felk.cvut.cz>
+ * Copyright (C) 2014 Radek Meciar
+ *
+ * Department of Control Engineering
+ * Faculty of Electrical Engineering
+ * Czech Technical University in Prague (CTU)
+ *
+ * Next exception is granted in addition to GPL.
+ * Instantiating or linking compiled version of this code
+ * 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 S-function files is required
+ * although.
+ */
+
+#include "rpi_gpio.h"
+
+/*Based on bachelor thesis work Meciar Radek: Motor control with Raspberry Pi board and Linux*/
+
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdint.h>
+
+#define BASE 0x20000000 /* registers common base address */
+#define GPIO_BASE (BASE + 0x200000) /* gpio_base registers base address */
+#define PWM_BASE (BASE + 0x20C000) /* pwm_base registers base address */
+#define CLK_BASE (BASE + 0x101000) /* clk_base register base address */
+
+#define PAGE_SIZE (4*1024)
+#define BLOCK_SIZE (4*1024)
+
+rpi_registers_mapping_t rpi_registers_mapping;
+
+/* Based on infromation from: http://elinux.org/RPi_Low-level_peripherals */
+
+static int rpi_gpio_fnc_setup(unsigned gpio, unsigned fnc)
+{
+ volatile unsigned *reg;
+ unsigned mask;
+
+ if (gpio >= 32)
+ return -1;
+
+ mask = 7 << ((gpio % 10) * 3);
+ fnc = fnc << ((gpio % 10) * 3);
+ fnc &= mask;
+ reg = rpi_registers_mapping.gpio_base + (gpio /10);
+
+ if ((*reg & mask) != fnc) {
+ *reg &= ~mask;
+ *reg |= fnc;
+ }
+ return 0;
+}
+
+/* Configure gpio_base pin for input */
+int rpi_gpio_direction_input(unsigned gpio)
+{
+ return rpi_gpio_fnc_setup(gpio, 0);
+}
+
+/* Configure gpio_base pin for output */
+int rpi_gpio_direction_output(unsigned gpio, int value)
+{
+ if (gpio >= 32)
+ return -1;
+
+ rpi_gpio_set_value(gpio, value);
+ if (rpi_gpio_fnc_setup(gpio, 1) < 0)
+ return -1;
+ rpi_gpio_set_value(gpio, value);
+ return 0;
+}
+
+/* Configure gpio_base pin for alternate function */
+int rpi_gpio_alt_fnc(unsigned gpio, int alt_fnc)
+{
+ return rpi_gpio_fnc_setup(gpio, alt_fnc <= 3? alt_fnc + 4: alt_fnc == 4? 3: 2);
+}
+
+/*
+peripheral_registers_map:
+
+Maps registers into virtual address space and sets *gpio_base, *pwm_base, *clk_base poiners
+*/
+int rpi_peripheral_registers_map(void)
+{
+ rpi_registers_mapping_t *rrmap = &rpi_registers_mapping;
+ if (rrmap->mapping_initialized)
+ return rrmap->mapping_initialized;
+
+ rrmap->mapping_initialized = -1;
+
+ if ((rrmap->mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
+ return -1;
+ }
+
+ rrmap->gpio_map = mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, rrmap->mem_fd, GPIO_BASE);
+
+ if (rrmap->gpio_map == MAP_FAILED) {
+ return -1;
+ }
+
+ rrmap->gpio_base = (volatile unsigned *)rrmap->gpio_map;
+
+ rrmap->pwm_map = mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, rrmap->mem_fd, PWM_BASE);
+
+ if (rrmap->pwm_map == MAP_FAILED) {
+ return -1;
+ }
+
+ rrmap->pwm_base = (volatile unsigned *)rrmap->pwm_map;
+
+ rrmap->clk_map = mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, rrmap->mem_fd, CLK_BASE);
+
+ if (rrmap->clk_map == MAP_FAILED) {
+ return -1;
+ }
+
+ rrmap->clk_base = (volatile unsigned *)rrmap->clk_map;
+
+ close(rrmap->mem_fd);
+
+ rrmap->mapping_initialized = 1;
+
+ return rrmap->mapping_initialized;
+} /* peripheral_registers_map */
--- /dev/null
+#ifndef _RPI_GPIO_H
+#define _RPI_GPIO_H
+
+typedef struct rpi_registers_mapping_t {
+ int mapping_initialized;
+ int mem_fd;
+ void *gpio_map;
+ void *pwm_map;
+ void *clk_map;
+ volatile unsigned *gpio_base;
+ volatile unsigned *pwm_base;
+ volatile unsigned *clk_base;
+} rpi_registers_mapping_t;
+
+extern rpi_registers_mapping_t rpi_registers_mapping;
+
+#define GPIO_SET (*(rpi_registers_mapping.gpio_base+7))
+#define GPIO_CLR (*(rpi_registers_mapping.gpio_base+10))
+#define GPIO_INP (*(rpi_registers_mapping.gpio_base+13))
+
+static inline int rpi_gpio_get_value(unsigned gpio)
+{
+ return GPIO_INP & (1 << gpio)? 1: 0;
+}
+
+/* Set gpio pin output set to specifies level */
+static inline void rpi_gpio_set_value(unsigned gpio, int value)
+{
+ if (value)
+ GPIO_SET = 1 << gpio;
+ else
+ GPIO_CLR = 1 << gpio;
+}
+
+/* Configure gpio_base pin for input */
+int rpi_gpio_direction_input(unsigned gpio);
+
+/* Configure gpio_base pin for output */
+int rpi_gpio_direction_output(unsigned gpio, int value);
+
+/* Configure gpio_base pin for alternate function */
+int rpi_gpio_alt_fnc(unsigned gpio, int alt_fnc);
+
+int rpi_peripheral_registers_map(void);
+
+#endif /*_RPI_BIDIRPWM_H*/
--- /dev/null
+/*
+ Communication with Raspberry Pi equipped by 3-phase
+ motor driver and RPI-MI-1 FPGA board designed
+ by Petr Porazil for PiKRON company.
+ The VHDL design by Martin Prudek.
+
+ (C) 2015 by Martin Prudek prudemar@fel.cvut.cz
+ (C) 2015 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ */
+
+#include <stdint.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/types.h>
+#include <linux/spi/spidev.h>
+
+#include "pxmc_spimc.h"
+
+static uint8_t spimc_mode = 0;
+static uint8_t spimc_bits = 8;
+static uint32_t spimc_speed = 500000;
+static uint16_t spimc_delay = 0;
+
+static void pabort(const char *s)
+{
+ perror(s);
+ abort();
+}
+
+int spimc_transfer(spimc_state_t *spimcst)
+{
+ uint8_t *tx = spimcst->tx_buf;
+ uint8_t *rx = spimcst->rx_buf;
+ int ret;
+ uint16_t tmp;
+ uint32_t pwm1, pwm2, pwm3;
+
+ memset(tx, 0, SPIMC_TRANSFER_SIZE);
+ memset(rx, 0, SPIMC_TRANSFER_SIZE);
+
+ /*Data format:
+ * rx[0] - bity 127 downto 120 the first income bit..127
+ * rx[1] - bity 119 downto 112
+ * rx[2] - bity 111 downto 104
+ * rx[3] - bity 103 downto 96
+ * tx[4] - bity 95 downto 88
+ * tx[5] - bity 87 downto 80
+ * tx[6] - bity 79 downto 72
+ * tx[7] - bity 71 downto 64
+ * tx[8] - bity 63 downto 56
+ * tx[9] - bity 55 downto 48
+ * tx[10] - bity 47 downto 40
+ * tx[11] - bity 39 downto 32
+ * tx[12] - bity 31 downto 24
+ * tx[13] - bity 23 downto 16
+ * tx[14] - bity 15 downto 8
+ * tx[15] - bity 7 downto 0
+ *
+ * bit 127 - ADC reset
+ * bit 126 - enable PWM1
+ * bit 125 - enable PWM2
+ * bit 124 - enable PWM3
+ * bit 123 - shutdown1
+ * bit 122 - shutdown2
+ * bit 121 - shutdown3
+ * .
+ * .
+ * .
+ * bits 66 .. 56 - match PWM1
+ * bits 55 .. 45 - match PWM2
+ * bit 11,12 - Unused
+ * bits 42 .. 32 - match PWM3
+ */
+
+ pwm1 = spimcst->pwm[0];
+ pwm2 = spimcst->pwm[1];
+ pwm3 = spimcst->pwm[2];
+
+ tx[0] = 0;
+ if (pwm1 & SPIMC_PWM_ENABLE)
+ tx[0] |= 1 << 6;
+ if (pwm1 & SPIMC_PWM_SHUTDOWN)
+ tx[0] |= 1 << 3;
+ if (pwm2 & SPIMC_PWM_ENABLE)
+ tx[0] |= 1 << 5;
+ if (pwm2 & SPIMC_PWM_SHUTDOWN)
+ tx[0] |= 1 << 2;
+ if (pwm3 & SPIMC_PWM_ENABLE)
+ tx[0] |= 1 << 4;
+ if (pwm3 & SPIMC_PWM_SHUTDOWN)
+ tx[0] |= 1 << 1;
+
+ pwm1 &= SPIMC_PWM_VALUE_m;
+ pwm2 &= SPIMC_PWM_VALUE_m;
+ pwm3 &= SPIMC_PWM_VALUE_m;
+
+ /* keep the cap*/
+ if (pwm1 > 2047) pwm1 = 2047;
+ if (pwm2 > 2047) pwm2 = 2047;
+ if (pwm3 > 2047) pwm3 = 2047;
+
+ /*pwm1*/
+ tx[7]=(tx[7] & 0xF8) | (0x07 & ((uint8_t*)&pwm1)[1]); /*MSB*/
+ tx[8]=((uint8_t*)&pwm1)[0]; /*LSB*/
+
+ /*pwm2*/
+ tmp=pwm2;
+ tmp<<=5;
+ tx[9]=((uint8_t*)&tmp)[1]; /*MSB*/
+ tx[10]=(tx[10] & 0x1F) | (0xE0 & ((uint8_t*)&tmp)[0]); /*LSB*/
+
+ /*pwm3*/
+ tx[10]=(tx[10] & 0xF8) | (0x07 & ((uint8_t*)&pwm3)[1]); /*MSB*/
+ tx[11]=((uint8_t*)&pwm3)[0]; /*LSB*/
+
+ struct spi_ioc_transfer tr = {
+ .tx_buf = (uintptr_t)tx,
+ .rx_buf = (uintptr_t)rx,
+ .len = SPIMC_TRANSFER_SIZE,
+ .delay_usecs = spimc_delay,
+ .speed_hz = spimc_speed,
+ .bits_per_word = spimc_bits,
+ };
+
+ ret = ioctl(spimcst->spi_fd, SPI_IOC_MESSAGE(1), &tr);
+ if (ret < 1)
+ return -1;
+
+ /*prichozi data:
+ * rx[0] - bity 127 downto 120 the first income bit..127
+ * rx[1] - bity 119 downto 112
+ * rx[2] - bity 111 downto 104
+ * rx[3] - bity 103 downto 96
+ * rx[4] - bity 95 downto 88
+ * rx[5] - bity 87 downto 80
+ * rx[6] - bity 79 downto 72
+ * rx[7] - bity 71 downto 64
+ * rx[8] - bity 63 downto 56
+ * rx[9] - bity 55 downto 48
+ * rx[10] - bity 47 downto 40
+ * rx[11] - bity 39 downto 32
+ * rx[12] - bity 31 downto 24
+ * rx[13] - bity 23 downto 16
+ * rx[14] - bity 15 downto 8
+ * rx[15] - bity 7 downto 0 the last income bit..0
+ */
+
+ /* position from IRC counter */
+ spimcst->act_pos = ((uint32_t)rx[0] << 24) |
+ ((uint32_t)rx[1] << 16) |
+ ((uint32_t)rx[2] << 8) |
+ ((uint32_t)rx[3] << 0);
+
+ /*halove sondy
+ * hal1 - bit95
+ * hal2 - bit94
+ * hal3 - bit93
+ */
+ spimcst->hal_sensors = ((0x80 & rx[4]) >> 7) |
+ ((0x40 & rx[4]) >> 5) |
+ ((0x20 & rx[4]) >> 3);
+
+ /* index position
+ * bits 92 downto 81
+ * 92..88 in rx[4] last 5 bits (from left)
+ * 87..81 in rx[5] first 7 bits (from left)
+ */
+ spimcst->index_pos = 0x1F & rx[4];
+ spimcst->index_pos <<= 8;
+ spimcst->index_pos |= 0xFE & rx[5];
+ spimcst->index_pos >>= 1;
+
+ /* current measurments count
+ * bits 80 downto 72
+ * bit 80 in rx[5]
+ * bits 79..72 in rx[6]
+ */
+
+ spimcst->curadc_sqn = 0x01 & rx[5];
+ spimcst->curadc_sqn <<= 8;
+ spimcst->curadc_sqn |= rx[6];
+
+
+ /** currents
+ * ch2 - bits 71 downto 48
+ * 71..64 in rx[7] - all byte
+ * 63..56 in rx[8] - all byte
+ * 55..48 in rx[9] - all byte
+ * ch0 - bits 47 downto 24
+ * 47..40 in rx[10] - all byte
+ * 39..32 in rx[11] - all byte
+ * 31..24 in rx[12] - all byte
+ * ch1 - bits 23 downto 0
+ * 23..16 in rx[13] - all byte
+ * 15..8 in rx[14] - all byte
+ * 7..0 in rx[15] - all byte
+ */
+
+ spimcst->curadc_cumsum[2] = rx[7];
+ spimcst->curadc_cumsum[2] <<= 8;
+ spimcst->curadc_cumsum[2] |= rx[8];
+ spimcst->curadc_cumsum[2] <<= 8;
+ spimcst->curadc_cumsum[2] |= rx[9];
+
+ spimcst->curadc_cumsum[0] = rx[10];
+ spimcst->curadc_cumsum[0] <<= 8;
+ spimcst->curadc_cumsum[0] |= rx[11];
+ spimcst->curadc_cumsum[0] <<= 8;
+ spimcst->curadc_cumsum[0] |=rx [12];
+
+ spimcst->curadc_cumsum[1] = rx[13];
+ spimcst->curadc_cumsum[1] <<= 8;
+ spimcst->curadc_cumsum[1] |= rx[14];
+ spimcst->curadc_cumsum[1] <<= 8;
+ spimcst->curadc_cumsum[1] |= rx[15];
+
+ return 0;
+}
+
+int spimc_init(spimc_state_t *spimcst)
+{
+ int ret = 0;
+ int fd;
+
+ spimcst->spi_fd = -1;
+
+ fd = open(spimcst->spi_dev, O_RDWR);
+ if (fd < 0) {
+ pabort("can't open device");
+ }
+ printf("device open\n");
+ /*
+ * spi spimc_mode
+ */
+ ret = ioctl(fd, SPI_IOC_WR_MODE, &spimc_mode);
+ if (ret == -1)
+ pabort("can't set spi mode");
+
+ ret = ioctl(fd, SPI_IOC_RD_MODE, &spimc_mode);
+ if (ret == -1)
+ pabort("can't get spi mode");
+
+ /*
+ * bits per word
+ */
+ ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &spimc_bits);
+ if (ret == -1)
+ pabort("can't set bits per word");
+
+ ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &spimc_bits);
+ if (ret == -1)
+ pabort("can't get bits per word");
+
+ /*
+ * max spimc_speed hz
+ */
+ ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &spimc_speed);
+ if (ret == -1)
+ pabort("can't set max speed hz");
+
+ ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &spimc_speed);
+ if (ret == -1)
+ pabort("can't get max speed hz");
+
+ printf("spi spimc_mode: %d\n", spimc_mode);
+ printf("bits per word: %d\n", spimc_bits);
+ printf("delay: %d\n", spimc_delay);
+ printf("max spimc_speed: %d Hz (%d KHz)\n", spimc_speed, spimc_speed/1000);
+
+ spimcst->spi_fd = fd;
+
+ return ret;
+}
--- /dev/null
+LN_HEADERS=y
+OMIT_KERNEL_PASSES=y
+
+#LINUX_DIR=/home/cvs/ocera/ocera-pc104/kernel/linux
+#RTL_DIR=/home/cvs/ocera/ocera-pc104/kernel/rtlinux
+CONFIG_RTLINUX=n
+CONFIG_RTL_OC_DYNMEM=n
+
+LINUX_DIR=/home/pi/projects/rpi/linux/_build/arm-rpi-3.18-rt
+CC=arm-rpi-linux-gnueabihf-gcc
+CXX=arm-rpi-linux-gnueabihf-g++
+AR=arm-rpi-linux-gnueabihf-ar
+LD=arm-rpi-linux-gnueabihf-ld
+
+#CONFIG_OC_SOLIBS=y
+#LDFLAGS += '-Wl,-rpath,$$ORIGIN/../lib' --enable-new-dtags
+
+#CFLAGS+=-ansi
+#CFLAGS+=-std=c89
+#CFLAGS+=-pedantic
+CFLAGS+=-O2
+CFLAGS+=-Wall
+CFLAGS+=-Wstrict-aliasing=2
+CFLAGS+=-fpic
+#CFLAGS+=-pg
+#CFLAGS+=-static
+#LDFLAGS+=-static
+
+CFLAGS += -ggdb
+
+#CFLAGS += -D CONFIG_OD_GSA
+
+#LDFLAGS+=-pg
+
+CONFIG_OC_CMDPROC=y
+
+CONFIG_PXMC=y
+CONFIG_PXMC_WITH_PTABLE=y
+CONFIG_PXMC_BSP=sim_posix
+CONFIG_PXMC_COORDMV=y
+
+CONFIG_APP_RPI_PMSM_T1=y
+
--- /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 = ulut pxmc cmdproc misc
+
+#nobase_include_HEADERS =
+
+#lib_LIBRARIES =
+#shared_LIBRARIES =
+#include_HEADERS =
+#xxx_SOURCES =
+#lib_LOADLIBES =
+#bin_PROGRAMS =
+#utils_PROGRAMS =
+
--- /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
+default_CONFIG = CONFIG_OC_CMDPROC=y CONFIG_OC_CMDPROC_TEST=x
+
+ifeq ($(CONFIG_OC_CMDPROC),y)
+
+lib_LIBRARIES = cmdproc
+cmdproc_SOURCES = cmd_proc.c cmd_proc_run.c cmd_io.c cmd_io_line.c cmdio_std.c cmdio_std_line.c \
+ cmdio_std_file.c
+
+include_HEADERS = cmd_proc.h
+
+ifeq ($(CONFIG_OC_CMDPROC_TEST),y)
+bin_PROGRAMS = cmdproc_test
+cmdproc_test_SOURCES = cmdproc_test.c
+cmdproc_test_LIBS = cmdproc misc
+endif
+endif
--- /dev/null
+Platform independent files for command processor.
+
+Besides the main library, you can find here also the definition of
+cmdio which uses standard input/output and an example application,
+which shows almost all features of the command processor.
+
+Platform dependent cmdios should be placed in cmdprocio library.
--- /dev/null
+#ifndef CMD_BTH_H
+#define CMD_BTH_H
+
+/* Bluetooth specific */
+
+cmd_des_t const **cmd_bth;
+
+extern cmd_io_t cmd_io_bth;
+
+int cmd_bth_line_out(cmd_io_t *cmd_io);
+
+int cmd_bth_line_in(cmd_io_t *cmd_io);
+
+char *cmd_bth_rdline(cmd_io_t *cmd_io, int mode);
+
+int cmd_bth_processor_run(void);
+
+#endif
--- /dev/null
+#include <cmd_proc.h>
+#include <string.h>
+#include <stdint.h>
+
+/**
+ * Blocking call to print a string.
+ *
+ * @param cmd_io cmd_io structure.
+ * @param str Zero terminated string to print.
+ *
+ * @return Upon successful completion, puts() shall return a
+ * non-negative number. In case of error, negative number is returned.
+ */
+int cmd_io_puts(cmd_io_t *cmd_io, const char *str)
+{
+ int ret;
+ unsigned len;
+ if (!str) return 0;
+ len = strlen(str);
+ do {
+ ret = cmd_io_write(cmd_io, str, len);
+ if (ret > 0) {
+ str+=ret;
+ len-=ret;
+ }
+ } while (ret>=0 && len>0);
+ return ret;
+}
+
+int cmd_io_write_bychar(cmd_io_t *cmd_io,const void *buf,int count)
+{
+ int cn=0;
+ uint8_t* p=(uint8_t*)buf;
+ while(count--&&(*cmd_io->putc)(cmd_io,*p++)>=0){
+ cn++;
+ }
+ return cn;
+}
+
+int cmd_io_read_bychar(cmd_io_t *cmd_io,void *buf,int count)
+{
+ int cn=0;
+ int ch;
+ uint8_t* p=(uint8_t*)buf;
+ while(count--&&(ch=(*cmd_io->getc)(cmd_io))>=0){
+ *p++=ch;
+ cn++;
+ }
+ return cn;
+}
+
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ cmd_proc.h - text line command processor
+ designed for instruments control and setup
+ over RS-232 line
+
+ Copyright (C) 2001 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002 by PiKRON Ltd. http://www.pikron.com
+ (C) 2007 by Michal Sojka <sojkam1@fel.cvut.cz>
+
+ This file can be used and copied according to next
+ license alternatives
+ - MPL - Mozilla Public License
+ - GPL - GNU Public License
+ - other license provided by project originators
+ *******************************************************************/
+
+#include <cmd_proc.h>
+#include "cmd_proc_priv.h"
+#include <string.h>
+
+/* cmd_io line editor */
+
+/**
+ * Adds new characters to an edit line buffer.
+ *
+ * @param elb Edit line buffer.
+ * @param ch character to add.
+ *
+ * @return 1 in case of end of line, 0 otherwise.
+ */
+int cmd_ed_line_buf(ed_line_buf_t *elb, int ch)
+{
+ int lastch=elb->lastch;
+ if (elb->flg&FL_ELB_INSEND)
+ return -1;
+ elb->lastch=ch;
+ if(!lastch){
+ elb->inbuf=0; /* Start new line */
+ }
+ if((!(elb->flg&FL_ELB_NOCRLF))&&((ch=='\n')||(ch=='\r'))){
+ if((lastch=='\n')&&(ch=='\r')) /* Empty line, ignore it. */
+ return 0;
+ elb->lastch=0; /* End the string */
+ elb->buf[elb->inbuf]=0;
+ return 1;
+ }
+ if(elb->inbuf>=elb->alloc-1){
+ /* try to reallocate buffer len not implemented */
+ return 0;
+ }
+ elb->buf[elb->inbuf++]=ch;
+ return 0;
+}
+
+int cmd_io_line_putc(cmd_io_t *cmd_io,int ch)
+{
+ return cmd_ed_line_buf(cmd_io->priv.ed_line.out,ch);
+}
+
+/* Process pending output */
+int cmd_io_line_out(cmd_io_t *cmd_io)
+{
+ cmd_io_t* io_stack=cmd_io->priv.ed_line.io_stack;
+ ed_line_buf_t* ed_line_out=cmd_io->priv.ed_line.out;
+
+ if(!ed_line_out->inbuf) return 0;
+ if(!io_stack)
+ return -1;
+
+ if(!(ed_line_out->flg&FL_ELB_INSEND)){
+ ed_line_out->flg|=FL_ELB_INSEND;
+ ed_line_out->lastch=0;
+ }
+ while(cmd_io_putc(io_stack, ed_line_out->buf[ed_line_out->lastch])>=0){
+ if(++ed_line_out->lastch >= ed_line_out->inbuf){
+ ed_line_out->lastch=0;
+ ed_line_out->inbuf=0;
+ ed_line_out->flg&=~FL_ELB_INSEND;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/* process input */
+int cmd_io_line_in(cmd_io_t *cmd_io)
+{
+ int ch;
+ cmd_io_t* io_stack = cmd_io->priv.ed_line.io_stack;
+ ed_line_buf_t *ed_line_in = cmd_io->priv.ed_line.in;
+
+ if(!io_stack)
+ return -1;
+
+ while((ch=cmd_io_getc(io_stack))>=0){
+// DPRINT("Added %c (%d)\n", ch, ch);
+ int eol = cmd_ed_line_buf(ed_line_in,ch);
+ if(eol){
+ if(ed_line_in->flg&FL_ELB_ECHO){
+ while(cmd_io_putc(io_stack,'\r')<0);
+ while(cmd_io_putc(io_stack,'\n')<0);
+ }
+ return 1;
+ }
+ else
+ if(ed_line_in->flg&FL_ELB_ECHO) {
+ while(cmd_io_putc(io_stack,ch)<0);
+ }
+ }
+ return 0;
+}
+
+/* The possibly blocking read of one line, should be used only
+ when other options fails */
+char *cmd_io_line_rdline(cmd_io_t *cmd_io, int mode)
+{
+ int ret;
+ while((ret=cmd_io_line_in(cmd_io))==0)
+ if(!mode) break;
+ if(ret<=0) return NULL;
+ return cmd_io->priv.ed_line.in->buf;
+}
+
+/* Local Variables: */
+/* c-basic-offset: 2 */
+/* End */
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ cmd_proc.c - text command processor
+ enables to define multilevel tables of commands
+ which can be received from more inputs and send reply
+ to respective I/O stream output
+
+ Copyright (C) 2001-2009 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002-2009 by PiKRON Ltd. http://www.pikron.com
+ (C) 2007 by Michal Sojka <sojkam1@fel.cvut.cz>
+
+ This file can be used and copied according to next
+ license alternatives
+ - MPL - Mozilla Public License
+ - GPL - GNU Public License
+ - other license provided by project originators
+ *******************************************************************/
+
+#include <stdint.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include <i2str.h>
+#include <cmd_proc.h>
+#include "cmd_proc_priv.h"
+
+/* cmd_line processing */
+
+char *skip_white(char *p)
+{
+ while(isspace((uint8_t)*p)) p++;
+ return p;
+}
+
+/**
+ *
+ * @return Zero if no command was given in line, -CMDERR_BADCMD if
+ * command is not known or has no function assigned to it. If a
+ * command is executed, then the return value of the command function
+ * is returned.
+ */
+int proc_cmd_line(cmd_io_t *cmd_io, cmd_des_t const **des_arr, char *line)
+{
+ char *p=line, *r, *var;
+ const cmd_des_t *des;
+ cmd_des_t const **arr_stack[CMD_ARR_STACK_SIZE];
+ int arr_stack_sp=0;
+ char *param[10];
+ short cmd_len;
+ int res, i, parcnt;
+ param[0]=p=skip_white(p);
+ if(!*p) return 0;
+ /* Determine the name of the command */
+ if(!isalnum((uint8_t)*p)){
+ cmd_len=1;
+ p++;
+ }else{
+ while(isalnum((uint8_t)*p)) p++;
+ cmd_len=p-param[0];
+ }
+ param[1]=param[2]=skip_white(p);
+
+ /* Find the command in des_arr */
+ while(1){
+ des=*(des_arr++);
+ if(!des){
+ if(!arr_stack_sp) break;
+ des_arr=arr_stack[--arr_stack_sp];
+ continue;
+ }
+ if(des==CMD_DES_CONTINUE_AT_ID){
+ /* list continues at new address */
+ des_arr=(const cmd_des_t **)*des_arr;continue;
+ }
+ if(des==CMD_DES_INCLUDE_SUBLIST_ID){
+ /* list includes commands from sublists */
+ if(arr_stack_sp>=CMD_ARR_STACK_SIZE){
+ des_arr++;
+ }else{
+ arr_stack[arr_stack_sp++]=des_arr+1;
+ des_arr=(const cmd_des_t **)*des_arr;
+ continue;
+ }
+ }
+ p=param[0];
+ if(!(r=des->name))continue;
+ i=cmd_len;
+ var=NULL;
+ while(*r){
+ while((*p==*r)&&i){i--;r++;p++;};
+ if((i==0)&&!*r) break; /* We've found the command */
+ if((*r=='?')&&i){
+ if(!var) var=p;
+ p++; r++; i--;
+ continue;
+ }
+ if((*r=='#')&&i&&isdigit((uint8_t)*p)){
+ if(!var) var=p;
+ p++; r++; i--;
+ continue;
+ }
+ if(*r=='*'){
+ if(!var) var=p;
+ i=0;
+ break;
+ }
+ i=1;
+ break;
+ }
+ if(i!=0) continue; /* Try next command */
+ if(des->mode&CDESM_OPCHR){
+ if(!param[2])continue;
+ if(!*param[2])continue;
+ param[3]=skip_white(param[2]+1);
+ param[1]=var;
+ parcnt=4;
+ }else{
+ parcnt=1;
+ if(var){param[1]=var;parcnt++;}
+ if(param[parcnt])
+ if(*param[parcnt]) parcnt++;
+ }
+ param[parcnt]=0;
+ if(!des->fnc) return -CMDERR_BADCMD;
+ res=des->fnc(cmd_io,des,param);
+ return res;
+ }
+ return -CMDERR_BADCMD;
+}
+
+/**
+ * Checks whether the the command allows the operation specified by
+ * opchar.
+ *
+ * @return opchar if perimssions allow this operations, -CMDERR_WRPERM
+ * or -CMDERR_RDPERM if the operation is not allows, -CMDERR_OPCHAR,
+ * if the opchar is not ':' or '?'.
+ */
+int cmd_opchar_check(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ int opchar=*param[2];
+ if(opchar==':'){
+ if(!(des->mode&CDESM_WR)){
+ return -CMDERR_WRPERM;
+ }
+ }else if(opchar=='?'){
+ if(!(des->mode&CDESM_RD)){
+ return -CMDERR_RDPERM;
+ }
+ }
+ else return -CMDERR_OPCHAR;
+ return opchar;
+}
+
+int cmd_num_suffix(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[], unsigned *pval)
+{
+ unsigned val=0;
+ unsigned x;
+ char *p;
+ p=param[1];
+ if(!p) return -CMDERR_BADSUF;
+
+ do{
+ x=*p-'0';
+ if((unsigned)x>9)
+ return -CMDERR_BADSUF;
+ val*=10;
+ val+=x;
+ p++;
+ }while(*p && !strchr(" :?=",*p));
+ *pval=val;
+ return 0;
+}
+
+
+int cmd_do_stamp(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ if(*param[2]!=':') return -CMDERR_OPCHAR;
+ cmd_io_write(cmd_io,param[0],param[2]-param[0]);
+ cmd_io_putc(cmd_io,'=');
+ cmd_io_write(cmd_io,param[3],strlen(param[3]));
+ return 0;
+}
+
+/**
+ * Implementation of a command that reads or writes short pointed by des->info[0].
+ */
+int cmd_do_rw_short(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ short val;
+ short *ptr;
+ int opchar;
+
+ if((opchar=cmd_opchar_check(cmd_io,des,param))<0) return opchar;
+ ptr=(short*)(des->info[0]);
+ if(opchar==':'){
+ val=atoi(param[3]);
+ *ptr=val;
+ }else{
+ return cmd_opchar_replong(cmd_io, param, (long)*ptr, 0, 0);
+ }
+ return 0;
+}
+
+/**
+ * Implementation of a command that reads or writes int pointed by des->info[0].
+ */
+int cmd_do_rw_int(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ int val;
+ int *ptr;
+ int opchar;
+
+ if((opchar=cmd_opchar_check(cmd_io,des,param))<0) return opchar;
+ ptr=(int*)(des->info[0]);
+ if(opchar==':'){
+ val=atoi(param[3]);
+ *ptr=val;
+ }else{
+ return cmd_opchar_replong(cmd_io, param, (long)*ptr, 0, 0);
+ }
+ return 0;
+}
+
+
+/**
+ * Implementation of a command that reads or writes long pointed by des->info[0].
+ */
+int cmd_do_rw_long(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ long val;
+ long *ptr;
+ int opchar;
+
+ if((opchar=cmd_opchar_check(cmd_io,des,param))<0) return opchar;
+ ptr=(long*)(des->info[0]);
+ if(opchar==':'){
+ val=atol(param[3]);
+ *ptr=val;
+ }else{
+ return cmd_opchar_replong(cmd_io, param, (long)*ptr, 0, 0);
+ }
+ return 0;
+}
+
+/**
+ * Prints name of the command followed by '=' and the value of val.
+ */
+int cmd_opchar_replong(cmd_io_t *cmd_io, char *param[], long val,int len,int form)
+{
+ char str[20];
+ cmd_io_write(cmd_io,param[0],param[2]-param[0]);
+ cmd_io_putc(cmd_io,'=');
+ i2str(str,val,len,form);
+ cmd_io_write(cmd_io,str,strlen(str));
+ return 0;
+}
+
+#if 0
+
+int cmd_do_rw_bitflag(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ unsigned val,mask,*pval;
+ int opchar;
+
+ if((opchar=cmd_opchar_check(cmd_io,des,param))<0) return opchar;
+ pval=(unsigned*)(des->info[0]);
+ mask=(unsigned)(des->info[1]);
+ if(opchar==':'){
+ val=*param[3];
+ if(val=='0')
+ atomic_clear_mask(mask,pval);
+ else if(val=='1')
+ atomic_set_mask(mask,pval);
+ else return -CMDERR_BADPAR;
+ }else{
+ cmd_io_write(cmd_io,param[0],param[2]-param[0]);
+ cmd_io_putc(cmd_io,'=');
+ cmd_io_putc(cmd_io,*pval&mask?'1':'0');
+ }
+
+ return 0;
+}
+
+#endif
+
+/**
+ * Implementation of help command
+ */
+int cmd_do_help(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ char *help;
+ char *filt=param[1];
+ const cmd_des_t **des_arr=*(const cmd_des_t ***)des->info[0];
+ cmd_des_t const **arr_stack[CMD_ARR_STACK_SIZE];
+ int arr_stack_sp=0;
+
+ /* FIXME: This should not be there unconditional */
+ if (cmd_io->priv.ed_line.io_stack)
+ cmd_io = cmd_io->priv.ed_line.io_stack;
+
+ if(filt) {
+ filt=skip_white(filt);
+ if(!*filt) filt=NULL;
+ }
+ cmd_io_puts(cmd_io,"Help for commands\n");
+ while(1){
+ des=*(des_arr++);
+ if(!des){
+ if(!arr_stack_sp) break;
+ des_arr=arr_stack[--arr_stack_sp];
+ continue;
+ }
+ if(des==CMD_DES_CONTINUE_AT_ID){
+ /* list continues at new address */
+ des_arr=(const cmd_des_t **)*des_arr;
+ continue;
+ }
+ if(des==CMD_DES_INCLUDE_SUBLIST_ID){
+ /* list includes commands from sublists */
+ if(arr_stack_sp>=CMD_ARR_STACK_SIZE){
+ des_arr++;
+ }else{
+ arr_stack[arr_stack_sp++]=des_arr+1;
+ des_arr=(const cmd_des_t **)*des_arr;
+ continue;
+ }
+ }
+ if(des->name){
+ if(!filt || !strncmp(des->name,filt,strlen(filt))) {
+ help=des->help;
+ if(!help) help="?";
+ cmd_io_puts(cmd_io,des->name);
+ cmd_io_puts(cmd_io," - ");
+ cmd_io_puts(cmd_io,help);
+ cmd_io_puts(cmd_io, "\r\n");
+ }
+ }
+ }
+ return 0;
+}
+
+/* Local Variables: */
+/* c-basic-offset: 2 */
+/* End */
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ cmd_proc.h - text line command processor
+ designed for instruments control and setup
+ over RS-232 line
+
+ Copyright (C) 2001-2009 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002-2009 by PiKRON Ltd. http://www.pikron.com
+ (C) 2007 by Michal Sojka <sojkam1@fel.cvut.cz>
+
+ This file can be used and copied according to next
+ license alternatives
+ - MPL - Mozilla Public License
+ - GPL - GNU Public License
+ - other license provided by project originators
+ *******************************************************************/
+
+#ifndef _CMD_PROC_H_
+#define _CMD_PROC_H_
+
+#define CMD_PROC_WITH_FILE
+
+#ifdef CMD_PROC_WITH_FILE
+#include <stdio.h>
+#endif
+
+#define FL_ELB_ECHO 0x10 /* Read characters are echoed back */
+#define FL_ELB_INSEND 0x20 /* The line is currently being sent */
+#define FL_ELB_NOCRLF 0x40 /* CR and/or LF will not start the new line */
+#define CMD_DES_CONTINUE_AT_ID ((cmd_des_t*)1)
+#define CMD_DES_INCLUDE_SUBLIST_ID ((cmd_des_t*)2)
+#define CMD_DES_CONTINUE_AT(list) CMD_DES_CONTINUE_AT_ID,((cmd_des_t*)list)
+#define CMD_DES_INCLUDE_SUBLIST(list) CMD_DES_INCLUDE_SUBLIST_ID,((cmd_des_t*)list)
+
+/* generic cmd_io structure */
+
+/* buffer for in/out line collection */
+typedef struct{
+ int flg; /* FL_ELB_xxx */
+ int inbuf; /* Index to store new characters */
+ int alloc; /* Size of the buffer pointed by buf */
+ int maxlen;
+ int lastch; /* Last characted added to the buffer.
+ * If FL_ELB_INSEND is set, lastch is
+ * index of last sent char. */
+ char *buf;
+} ed_line_buf_t;
+
+/* Structure for character input output. It is used either for direct
+ * access to IO device or for buffered IO. In the later case,
+ * priv.edline is used to store buffer information. */
+typedef struct cmd_io{
+ int (*putc)(struct cmd_io *cmd_io,int ch);
+ int (*getc)(struct cmd_io *cmd_io);
+ int (*write)(struct cmd_io *cmd_io,const void *buf,int count);
+ int (*read)(struct cmd_io *cmd_io,void *buf,int count);
+ union {
+ struct {
+ ed_line_buf_t *in;
+ ed_line_buf_t *out;
+ struct cmd_io *io_stack;
+ } ed_line;
+ struct {
+ long pos;
+ void *ptr;
+ } device;
+#ifdef CMD_PROC_WITH_FILE
+ struct {
+ FILE *in;
+ FILE *out;
+ } file;
+#endif /*CMD_PROC_WITH_FILE*/
+ struct {
+ int uartch;
+ } uart;
+ } priv;
+} cmd_io_t;
+
+static inline int cmd_io_putc(struct cmd_io *cmd_io,int ch)
+{ if(!cmd_io->putc) return -1;
+ return (*cmd_io->putc)(cmd_io,ch);
+}
+
+static inline int cmd_io_getc(struct cmd_io *cmd_io)
+{ if(!cmd_io->getc) return -1;
+ return (*cmd_io->getc)(cmd_io);
+}
+
+static inline int cmd_io_write(struct cmd_io *cmd_io,const void *buf,int count)
+{ if(!cmd_io->write) return -1;
+ return (*cmd_io->write)(cmd_io,buf,count);
+}
+
+static inline int cmd_io_read(struct cmd_io *cmd_io,void *buf,int count)
+{ if(!cmd_io->read) return -1;
+ return (*cmd_io->read)(cmd_io,buf,count);
+}
+
+int cmd_io_puts(cmd_io_t *cmd_io, const char *str);
+
+int cmd_io_line_putc(cmd_io_t *cmd_io,int ch);
+
+int cmd_io_write_bychar(cmd_io_t *cmd_io,const void *buf,int count);
+
+int cmd_io_read_bychar(cmd_io_t *cmd_io,void *buf,int count);
+
+/* command descriptions */
+
+#define CDESM_OPCHR 0x10 /* Command uses operation character */
+#define CDESM_RD 0x01 /* Value read is possible */
+#define CDESM_WR 0x02 /* Value write is possible */
+#define CDESM_RW (CDESM_RD|CDESM_WR) /* Both */
+
+typedef struct cmd_des{
+ int code;
+ int mode;
+ char *name;
+ char *help;
+ int (*fnc)(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]);
+ char *info[];
+} cmd_des_t;
+
+#define CMDERR_BADCMD 2
+#define CMDERR_OPCHAR 10
+#define CMDERR_WRPERM 11
+#define CMDERR_RDPERM 12
+#define CMDERR_GARBAG 13
+#define CMDERR_BADSEP 14
+#define CMDERR_BADCFG 15
+#define CMDERR_NOMEM 16
+#define CMDERR_BADSUF 17
+#define CMDERR_BADPAR 20
+#define CMDERR_VALOOR 21
+#define CMDERR_BADREG 40
+#define CMDERR_BSYREG 41
+#define CMDERR_BADDIO 50
+#define CMDERR_NODEV 60
+#define CMDERR_TIMEOUT 61
+#define CMDERR_EIO 62
+
+int cmd_opchar_check(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]);
+
+int cmd_num_suffix(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[], unsigned *val);
+
+int proc_cmd_line(cmd_io_t *cmd_io, cmd_des_t const **des_arr, char *line);
+
+int i2str(char *s,long val,int len,int form);
+
+int cmd_do_stamp(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]);
+
+int cmd_do_help(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]);
+
+int cmd_do_rw_short(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]);
+
+int cmd_do_rw_int(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]);
+
+int cmd_do_rw_long(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]);
+
+int cmd_do_rw_bitflag(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]);
+
+int cmd_opchar_replong(cmd_io_t *cmd_io, char *param[], long val,int len,int form);
+
+int cmd_processor_run(cmd_io_t *cmd_io, cmd_des_t const **commands);
+
+#endif /* _CMD_PROC_H_ */
+
+/* Local Variables: */
+/* c-basic-offset: 2 */
+/* End */
--- /dev/null
+#ifndef CMD_PROC_PRIV_H
+#define CMD_PROC_PRIV_H
+
+/* The maximal depth of command arrays nesting (see CMD_DES_INCLUDE_SUBLIST). */
+#define CMD_ARR_STACK_SIZE 4
+
+char *skip_white(char *p);
+int cmd_io_line_out(cmd_io_t *cmd_io);
+int cmd_io_line_in(cmd_io_t *cmd_io);
+
+#include <stdio.h>
+#define DPRINT(...) fprintf(stderr, __VA_ARGS__)
+
+#endif
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ cmd_proc.c - text command processor
+ enables to define multilevel tables of commands
+ which can be received from more inputs and send reply
+ to respective I/O stream output
+
+ Copyright (C) 2001-2009 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002-2009 by PiKRON Ltd. http://www.pikron.com
+ (C) 2007 by Michal Sojka <sojkam1@fel.cvut.cz>
+
+ This file can be used and copied according to next
+ license alternatives
+ - MPL - Mozilla Public License
+ - GPL - GNU Public License
+ - other license provided by project originators
+ *******************************************************************/
+
+#include <cmd_proc.h>
+#include "cmd_proc_priv.h"
+
+/**
+ * Executes command processor. This function is usually called from
+ * application's main loop.
+ */
+int cmd_processor_run(cmd_io_t *cmd_io, cmd_des_t const **commands)
+{
+ int val;
+
+ if(cmd_io_line_out(cmd_io))
+ return 1; /* Not all the output has been sent. */
+
+ if(cmd_io_line_in(cmd_io)<=0)
+ return 0; /* Input line not finished or error. */
+
+ if(commands){
+ val=proc_cmd_line(cmd_io, commands, cmd_io->priv.ed_line.in->buf);
+ }else{
+ val=-CMDERR_BADCMD;
+ }
+
+ if(cmd_io->priv.ed_line.out->inbuf){
+ cmd_io_putc(cmd_io,'\r');
+ cmd_io_putc(cmd_io,'\n');
+ }else if(val<0){
+ char s[20];
+ cmd_io_puts(cmd_io,"ERROR ");
+ i2str(s,-val,0,0);
+ cmd_io_puts(cmd_io,s);
+ cmd_io_putc(cmd_io,'\r');
+ cmd_io_putc(cmd_io,'\n');
+ }
+ return 1; /* Command line processed */
+}
+
+
+/* Local Variables: */
+/* c-basic-offset: 2 */
+/* End */
--- /dev/null
+/* Definitions of IOs */
+#include <unistd.h>
+#include <cmd_proc.h>
+#include <stdio.h>
+
+static int std_putc(cmd_io_t *cmd_io, int ch) {
+ int r=putchar(ch);
+ fflush(stdout);
+ return r;
+}
+
+//int _getkey_nb(void);
+static int std_getc(cmd_io_t *cmd_io) {
+ return getchar(); /* On UNIX, we don't use non-blocking
+ * variant. */
+ //return _getkey_nb();
+}
+static int std_write(cmd_io_t *cmd_io, const void *buf, int count) {
+ return write(1, buf, count);
+}
+static int std_read(cmd_io_t *cmd_io, void *buf, int count) {
+ return read(0, buf, count);
+}
+
+cmd_io_t cmd_io_std={
+ putc:std_putc,
+ getc:std_getc,
+ write:std_write,
+ read:std_read
+};
+
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ cmdio_std_file.c - interconnection of text command processor
+ with generic file interface
+
+ Copyright (C) 2001-2009 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002-2009 by PiKRON Ltd. http://www.pikron.com
+ (C) 2007 by Michal Sojka <sojkam1@fel.cvut.cz>
+
+ This file can be used and copied according to next
+ license alternatives
+ - MPL - Mozilla Public License
+ - GPL - GNU Public License
+ - other license provided by project originators
+
+ *******************************************************************/
+
+#include <ctype.h>
+#include <malloc.h>
+#include <string.h>
+#include <cmd_proc.h>
+#include <stdio.h>
+
+cmd_des_t const **cmd_forshell;
+
+static int cmd_io_putc_forfile(struct cmd_io *cmd_io,int ch)
+{
+ int res=fputc(ch,cmd_io->priv.file.out);
+ res=(res==EOF)?-1:0;
+ return res;
+}
+
+static int cmd_io_getc_forfile(struct cmd_io *cmd_io)
+{
+ int ch=fgetc(cmd_io->priv.file.in);
+ if(ch==EOF) ch=-1;
+ return ch;
+}
+
+static int cmd_io_write_forfile(struct cmd_io *cmd_io,const void *buf,int count)
+{
+ int res=fwrite(buf, 1, count, cmd_io->priv.file.out);
+ return res;
+}
+
+static int cmd_io_read_forfile(struct cmd_io *cmd_io,void *buf,int count)
+{
+ int res=fread(buf, 1, count, cmd_io->priv.file.in);
+ return res;
+}
+
+int cmd_proc_forfile(FILE * in,FILE * out, cmd_des_t const **des_arr, char *line)
+{
+ cmd_io_t cmd_io;
+
+ cmd_io.putc=cmd_io_putc_forfile;
+ cmd_io.getc=cmd_io_getc_forfile;
+ cmd_io.write=cmd_io_write_forfile;
+ cmd_io.read=cmd_io_read_forfile;
+ cmd_io.priv.file.in=in;
+ cmd_io.priv.file.out=out;
+
+ return proc_cmd_line(&cmd_io, des_arr, line);
+}
+
+int cmd_proc_forshell (int argc, char **argv)
+{
+ int i;
+ int res;
+ size_t len;
+ char *line, *p;
+
+ if(argc<2){
+ cmd_proc_forfile(stdin, stdout, cmd_forshell, "help");
+ printf("\n");
+ return 1;
+ }
+
+ for(len=0, i=1; i<argc; i++)
+ len+=strlen(argv[i])+1;
+
+ line=malloc(len);
+ if(!line)
+ return 3;
+
+ for(p=line, i=1; i<argc; i++) {
+ len=strlen(argv[i]);
+ memcpy(p,argv[i],len);
+ p+=len;
+ *(p++)=' ';
+ }
+ *(--p)=0;
+
+ res=cmd_proc_forfile(stdin, stdout, cmd_forshell, line);
+ printf("\n");
+
+ if(res<0) {
+ printf("cmdproc \"%s\" failed with error %d\n",line,res);
+ res=2;
+ } else res=0;
+
+ free(line);
+
+ return res;
+
+}
--- /dev/null
+#include <cmd_proc.h>
+#include <string.h>
+
+#define ED_LINE_CHARS 80
+
+char ed_line_in_std[ED_LINE_CHARS+1];
+char ed_line_out_std[ED_LINE_CHARS+1];
+
+
+ed_line_buf_t ed_line_buf_in_std={
+// flg:FL_ELB_ECHO,
+ inbuf:0,
+ alloc:sizeof(ed_line_in_std),
+ maxlen:0,
+ lastch:0,
+ buf:ed_line_in_std
+};
+
+ed_line_buf_t ed_line_buf_out_std={
+ flg:FL_ELB_NOCRLF,
+ inbuf:0,
+ alloc:sizeof(ed_line_out_std),
+ maxlen:0,
+ lastch:0,
+ buf:ed_line_out_std
+};
+
+extern cmd_io_t cmd_io_std;
+const cmd_io_t cmd_io_std_line={
+ putc:cmd_io_line_putc,
+ getc:NULL,
+ write:cmd_io_write_bychar,
+ read:NULL,
+ priv:{
+ ed_line:{
+ in: &ed_line_buf_in_std,
+ out:&ed_line_buf_out_std,
+ io_stack:&cmd_io_std
+ }
+ }
+};
--- /dev/null
+#include <cmd_proc.h>
+#include <stdio.h>
+
+int cmd_do_testopchar(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ int opchar;
+
+ opchar=cmd_opchar_check(cmd_io,des,param);
+ if(opchar<0) return opchar;
+
+ printf(
+ "cmd_do_testopchar called\n"
+ "param[0]=%s\n"
+ "param[1]=%s\n"
+ "param[2]=%s\n"
+ "param[3]=%s\n"
+ "opchar=%c\n",
+ param[0], param[1], param[2], param[3], opchar);
+
+ return 0;
+}
+
+int cmd_do_testparam(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ printf(
+ "cmd_do_testparam called\n"
+ "param[0]=%s\n"
+ "param[1]=%s\n"
+ "param[2]=%s\n",
+ param[0], param[1], param[2]);
+
+ return 0;
+}
+
+int cmd_do_testerror(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ return -1234;
+}
+
+int cmd_do_test(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ printf("This is the simplest command\n");
+ return 0;
+}
+
+int cmd_do_testcmdio(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ cmd_io_puts(cmd_io, "The first line of text\n");
+ cmd_io_puts(cmd_io, "The second line of text\n");
+ /* Only ED_LINE_CHARS character can be sent. */
+ return 0;
+}
+
+cmd_des_t const **cmd_list;
+
+cmd_des_t const cmd_des_help={
+ 0, 0,
+ "HELP","prints help for commands",
+ cmd_do_help,{(char*)&cmd_list}};
+
+int val;
+cmd_des_t const cmd_des_val={
+ 0, CDESM_OPCHR|CDESM_RW,
+ "VAL","use ':' or '?' to store/read value of an integer variable",
+ cmd_do_rw_int, {(char*)&val}};
+
+cmd_des_t const cmd_des_valro={
+ 0, CDESM_OPCHR|CDESM_RD,
+ "VALRO","read only access to an integer variable",
+ cmd_do_rw_int, {(char*)&val}};
+
+cmd_des_t const cmd_des_valwo={
+ 0, CDESM_OPCHR|CDESM_WR,
+ "VALWO","write only access to an integer variable",
+ cmd_do_rw_int, {(char*)&val}};
+
+cmd_des_t const cmd_des_opchar_test={
+ 0, CDESM_OPCHR|CDESM_RW,
+ "OPCHAR","opchar test (use ':' or '?' as suffix)",
+ cmd_do_testopchar};
+
+cmd_des_t const cmd_des_opchar_testro={
+ 0, CDESM_OPCHR|CDESM_RD,
+ "OPCHARRO","opchar test (only '?' is allowed)",
+ cmd_do_testopchar};
+
+cmd_des_t const cmd_des_test={
+ 0, 0,
+ "TEST","the simplest command",
+ cmd_do_test};
+
+cmd_des_t const cmd_des_testio={
+ 0, 0,
+ "TESTIO","test of cmd_io inside functions (universal way to print results)",
+ cmd_do_testcmdio};
+
+cmd_des_t const cmd_des_param={
+ 0, 0,
+ "PARAM","test of parameters",
+ cmd_do_testparam};
+
+cmd_des_t const cmd_des_prefix={
+ 0, 0,
+ "PREFIX*","suffix of the command is supplied as a parametr",
+ cmd_do_testparam};
+
+cmd_des_t const cmd_des_num={
+ 0, 0,
+ "NUM##","suffix of the command (two digits) is supplied as a parametr",
+ cmd_do_testparam};
+
+cmd_des_t const cmd_des_char={
+ 0, 0,
+ "CHAR?","suffix of the command (one character) is supplied as a parametr",
+ cmd_do_testparam};
+
+cmd_des_t const cmd_des_charmid={
+ 0, 0,
+ "CHAR?MID","middle character of the command is supplied as a parametr",
+ cmd_do_testparam};
+
+cmd_des_t const cmd_des_hiddedn={
+ 0, 0,
+ "HIDDEN","should not be available",
+ cmd_do_test};
+
+cmd_des_t const cmd_des_error={
+ 0, 0,
+ "TESTERROR","should produce an error",
+ cmd_do_testerror};
+
+/* Command lists */
+
+cmd_des_t const *cmd_list_1[]={
+ &cmd_des_val,
+ &cmd_des_valro,
+ &cmd_des_valwo,
+ &cmd_des_opchar_test,
+ &cmd_des_opchar_testro,
+ NULL
+ };
+
+cmd_des_t const *cmd_list_2[]={
+ &cmd_des_test,
+ &cmd_des_testio,
+ &cmd_des_param,
+ &cmd_des_prefix,
+ &cmd_des_num,
+ &cmd_des_char,
+ &cmd_des_charmid,
+ NULL
+ };
+
+cmd_des_t const *cmd_list_main[]={
+ &cmd_des_help,
+ &cmd_des_error,
+ CMD_DES_INCLUDE_SUBLIST(cmd_list_1),
+ CMD_DES_CONTINUE_AT(cmd_list_2),
+ &cmd_des_hiddedn,
+ NULL
+};
+
+cmd_des_t const **cmd_list = cmd_list_main;
+
+cmd_io_t cmd_io_std_line;
+
+int main()
+{
+ while (1) {
+ cmd_processor_run(&cmd_io_std_line, cmd_list_main);
+ }
+}
--- /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
+default_CONFIG = CONFIG_MISC_LIBRARY=y
+
+ifeq ($(CONFIG_MISC_LIBRARY),y)
+
+lib_LIBRARIES = misc
+
+#shared_LIBRARIES =
+
+#include_HEADERS = usb.h usb_spec.h usbdebug.h usb_stdreq.h
+
+include_HEADERS = utils.h i2str.h
+
+misc_SOURCES = utils.c utils_arr.c i2str.c
+endif
\ No newline at end of file
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ cmd_i2str.c - formated text to string conversion
+ without need to pull in whole stdio support
+
+ Copyright (C) 2001-2010 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002-2010 by PiKRON Ltd. http://www.pikron.com
+ (C) 2007 by Michal Sojka <sojkam1@fel.cvut.cz>
+
+ This file can be used and copied according to next
+ license alternatives
+ - MPL - Mozilla Public License
+ - GPL - GNU Public License
+ - other license provided by project originators
+ *******************************************************************/
+
+#include <i2str.h>
+
+/**
+ * Converts integer to string.
+ * @param s Buffer to store the result.
+ * @param val Value to convert.
+ * @param len Minimal width of the converted strign (padded by ' ').
+ * @param form Unused.
+ * @return 0
+ */
+int i2str(char *s,long val,int len,int form)
+{
+ int sig;
+ int dig=1;
+ int padd=0;
+ unsigned base=form&0xff;
+ unsigned long u;
+ unsigned long mag;
+ unsigned long num;
+ if(!base) base=10;
+ if((sig=(val<0)&&(base==10))) num=-val;
+ else num=val;
+
+ mag=1;
+ u=base*mag;
+ while(num>=u){
+ dig++;
+ mag=u;
+ if(mag>(unsigned long)(~(unsigned long)0)/base) break;
+ u*=base;
+ }
+
+ if(len){
+ padd=len-dig;
+ if(sig) padd--;
+ }
+ if(padd<0) padd=0;
+
+
+ if(form&I2STR_PAD_0) {
+ if(sig) *(s++)='-';
+ while(padd){
+ *(s++)='0';
+ padd--;
+ }
+ }else{
+ while(padd){
+ *(s++)=' ';
+ padd--;
+ }
+ if(sig) *(s++)='-';
+ }
+
+ while(dig--){
+ u=num/mag;
+ if(u>9) *(s++)='A'-10+u;
+ else *(s++)='0'+u;
+ num=num%mag;
+ mag/=base;
+ }
+ *s=0;
+ return 0;
+}
+
--- /dev/null
+#define I2STR_PAD_0 0x100
+#define I2STR_LONG 0x200
+#define I2STR_NUMBER 0x400
+
+int i2str(char *s,long val,int len,int form);
--- /dev/null
+/*******************************************************************
+ Components for embedded applications builded for
+ laboratory and medical instruments firmware
+
+ utils.c - utilities for reading numbers and parsing of text line
+
+ Copyright (C) 2001 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002 by PiKRON Ltd. http://www.pikron.com
+
+ *******************************************************************/
+
+#include <stdint.h>
+//#include <system_def.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+/* string parse and input routines */
+
+/**
+ * si_skspace - Skip space and blank characters
+ * @ps: Pointer to character poiter into parsed string
+ *
+ * Functions checks character **@ps by isspace() category and
+ * moves *@ps pointer after last blank character. If there is at least one
+ * blank character, returns 1, else returns 0.
+ */
+int si_skspace(char **ps)
+{
+ char *p=*ps;
+ if (!isspace((uint8_t)*(p++))) return 0;
+ while(isspace((uint8_t)*(p++)));
+ *ps=p-1;
+ return 1;
+}
+
+/**
+ * si_fndsep - Finds field separator character
+ * @ps: Pointer to character pointer into parsed string
+ * @sepchrs: String of possible separator characters.
+ *
+ * Function skips blanks, then checks, if next character belongs
+ * to @sepchrs list. If character belongs, function returns found
+ * character and *@ps points after separator else returns -1.
+ */
+int si_fndsep(char **ps,char *sepchrs)
+{
+ char c;
+ si_skspace(ps);
+ c=**ps;
+ if(!c) return 0;
+ if(!strchr(sepchrs,c)) return -1;
+ (*ps)++;
+ return c;
+}
+
+/**
+ * si_alnumn - Reads alphanumeric value
+ * @ps: Pointer to character pointer into parsed string
+ * @pout: Pointer to read value buffer
+ * @n: Maximal number of read characters.
+ *
+ * Function reads alphanumeric characters and stores them in @pout,
+ * if there is no more alphanumeric characters or @n is reached,
+ * it returns count of stored characters.
+ */
+int si_alnumn(char **ps,char *pout,int n)
+{
+ char *p=*ps;
+ char c;
+ int ret=0;
+ while(isalnum((uint8_t)(c=*p))||(*p=='_')) {
+ p++;
+ *(pout++)=c;
+ if(++ret==n) break;
+ }
+ *pout=0;
+ *ps=p;
+ return ret;
+}
+
+/**
+ * si_alphan - Reads alphabetic value
+ * @ps: Pointer to character pointer into parsed string
+ * @pout: Pointer to read value buffer
+ * @n: Maximal number of read characters.
+ *
+ * Function reads alphabetic characters and stores them in @pout,
+ * if there is no more alphabetic characters or @n is reached,
+ * it returns count of stored characters.
+ */
+int si_alphan(char **ps,char *pout,int n)
+{
+ char *p=*ps;
+ char c;
+ int ret=0;
+ while(isalpha((uint8_t)(c=*p))) {
+ p++;
+ *(pout++)=c;
+ if(++ret==n) break;
+ }
+ *pout=0;
+ *ps=p;
+ return ret;
+}
+
+/**
+ * si_long - Reads numeric value
+ * @ps: Pointer to character pointer into parsed string
+ * @val: Pointer to long integer value buffer
+ * @base: Base of converted number, 0 means select by C rules
+ *
+ * Function reads digits and converts them to longint value.
+ * It stops at end of the string or if non digit character is reached.
+ * Returns 1 for successful conversion or -1 if no character can be
+ * converted. Pointer *@ps paints after last character belonging to
+ * numeric input.
+ */
+int si_long(char **ps,long *val,int base)
+{
+ char *p;
+ *val=strtol(*ps,&p,base);
+ if(*ps==p) return -1;
+ *ps=p;
+ return 1;
+}
+
+/**
+ * si_ulong - Reads unsigned numeric value
+ * @ps: Pointer to character pointer into parsed string
+ * @val: Pointer to long integer value buffer
+ * @base: Base of converted number, 0 means select by C rules
+ *
+ * Function reads digits and converts them to longint value.
+ * It stops at end of the string or if non digit character is reached.
+ * Returns 1 for successful conversion or -1 if no character can be
+ * converted. Pointer *@ps paints after last character belonging to
+ * numeric input.
+ */
+int si_ulong(char **ps,long *val,int base)
+{
+ char *p;
+ *val=strtoul(*ps,&p,base);
+ if(*ps==p) return -1;
+ *ps=p;
+ return 1;
+}
+
--- /dev/null
+#ifndef _UTILS_DEF_H_
+#define _UTILS_DEF_H_
+
+
+/* skip space/blank characters, return 0 if no space found */
+int si_skspace(char **ps);
+
+/* skip spaces and checks for <sepchars>, */
+/* if no such char return -1, else char is returned */
+int si_fndsep(char **ps,char *sepchrs);
+
+/* reads max <n> letters and digits to <pout> */
+/* returns number of readed chars */
+int si_alnumn(char **ps,char *pout,int n);
+
+/* same as above, but only letters are read */
+int si_alphan(char **ps,char *pout,int n);
+
+/* reads long number, if no digit found return -1 */
+int si_long(char **ps,long *val,int base);
+
+/* reads unsigned long number, if no digit found return -1 */
+int si_ulong(char **ps,long *val,int base);
+
+/* reads numbers into array, size of element representation is selected by blen */
+int si_add_to_arr(char **ps, void **pdata,int *plen, int base, int elsize, char *stop_chars);
+
+/* concatenate C main style arguments into one line */
+int concat_args2line(char **pline, int argc, char **argv);
+
+#endif /* _UTILS_DEF_H_ */
+
--- /dev/null
+/**
+ * si_add_to_arr - adds elements to the dynamically growing array
+ * @ps: Pointer to character pointer into parsed string
+ * @pdata: Pointer to the data array pointer location pointer
+ * @plen: Pointer to location, where length of already accumulated
+ * in bytes is held
+ * @base: Base of converted number, 0 means select by C rules
+ * @elsize: Size of one array element
+ *
+ * Function reads digits and converts them to longint values.
+ * It stops at end of the string or if some of stop charracters is reached.
+ * Returns 1 for successful conversion or -1 if no character can be
+ * converted. Pointer *@ps paints after last character belonging to
+ * numeric input.
+ */
+
+#include <string.h>
+#include <malloc.h>
+#include "utils.h"
+
+int si_add_to_arr(char **ps, void **pdata,int *plen,int base, int elsize, char *stop_chars)
+{
+ char *s=*ps;
+ long val;
+ unsigned char *p;
+ int i;
+ int elements=0;
+ const int endian_chk=1;
+ if(!stop_chars)
+ stop_chars="";
+
+ if(!elsize)
+ elsize=1;
+ if(elsize>sizeof(long))
+ return -1;
+
+ do{
+ while(1){
+ if(!*s || strchr(stop_chars,*s)){
+ *ps=s;
+ return elements;
+ }
+ if(!strchr(", \t:;",*s))
+ break;
+ s++;
+ }
+ if(si_long(&s,&val,base)<0){
+ *ps=s;
+ return -1;
+ }
+ if(*pdata==NULL){
+ *plen=0;
+ *pdata=p=malloc(elsize);
+ }else{
+ p=realloc(*pdata,*plen+elsize);
+ if(p==NULL) return -1;
+ *pdata=p;
+ }
+
+ p+=*plen;
+ if(*(char*)&endian_chk){
+ for(i=elsize;i--;){
+ *(p++)=val;
+ val>>=8;
+ }
+ }else{
+ p+=elsize;
+ for(i=elsize;i--;){
+ *(--p)=val;
+ val>>=8;
+ }
+ }
+ (*plen)+=elsize;
+ elements++;
+ } while(1);
+}
--- /dev/null
+../../submodule/pxmc/libs4c
\ No newline at end of file
--- /dev/null
+../../submodule/ulut
\ 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
+include_HEADERS = cpu_def.h system_def.h
+
+
--- /dev/null
+#ifndef _GENPOSIX_CPU_DEF_H
+#define _GENPOSIX_CPU_DEF_H
+
+#ifndef CODE
+ #define CODE
+#endif
+
+#ifndef XDATA
+ #define XDATA
+#endif
+
+#ifndef DATA
+ #define DATA
+#endif
+
+#define set_bit(nr,v) (__sync_fetch_and_or(v,(1<<(nr))))
+#define clear_bit(nr,v) (__sync_fetch_and_and(v,~(1<<(nr))))
+#define test_and_set_bit(nr,v) \
+ ({ typeof(*(v)) __bitmsk = 1<<(nr); \
+ __sync_fetch_and_or(v,__bitmsk)&__bitmsk?1:0; \
+ })
+
+#define atomic_clear_mask_b1(mask, v) __sync_fetch_and_and(v,~(mask))
+#define atomic_set_mask_b1(mask, v) __sync_fetch_and_or(v,(mask))
+
+#define atomic_clear_mask_w1(mask, v) __sync_fetch_and_and(v,~(mask))
+#define atomic_set_mask_w1(mask, v) __sync_fetch_and_or(v,(mask))
+
+#define atomic_clear_mask_w(mask, v) __sync_fetch_and_and(v,~(mask))
+#define atomic_set_mask_w(mask, v) __sync_fetch_and_or(v,(mask))
+
+#define atomic_clear_mask(mask, v) __sync_fetch_and_and(v,~(mask))
+#define atomic_set_mask(mask, v) __sync_fetch_and_or(v,(mask))
+
+/* Arithmetic functions */
+#define sat_add_slsl(__x,__y) \
+ do { \
+ typeof(__x) tmp; \
+ tmp = (__x) + (__y); \
+ if ((__x) > 0 && (__y) > 0 && tmp < 0) \
+ tmp = +0x7fffffff; \
+ else if ((__x) < 0 && (__y) < 0 && tmp >= 0) \
+ tmp = -0x80000000; \
+ (__x) = tmp; \
+ } while (0)
+
+#ifndef __memory_barrier
+#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)))
+
+#endif /* _GENPOSIX_CPU_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-2015 by Pavel Pisa pisa@cmp.felk.cvut.cz
+ (C) 2002-2015 by PiKRON Ltd. http://www.pikron.com
+
+ *******************************************************************/
+
+#ifndef _SYSTEM_DEF_H_
+#define _SYSTEM_DEF_H_
+
+#include <stdint.h>
+
+#define WITH_SFI_SEL
+
+#ifndef VER_CODE
+#define VER_CODE(major,minor,patch) (major*0x10000+minor*0x100+patch)
+#endif
+/* Software version */
+#define SW_VER_ID "RPi_PMSM_TEST"
+#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 "RPi"
+#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 "RPi_MC"
+#define MECH_VER_MAJOR 1
+#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)
+
+/*volatile unsigned msec_time;*/ /* system time in msec units */
+
+#endif /* _SYSTEM_DEF_H_ */
--- /dev/null
+Subproject commit 002bf91c0907845b45bb7d5a8221edd57ce722da
--- /dev/null
+Subproject commit be75f4de44ddce9b990bde83d52307ac092a9d78