]> rtime.felk.cvut.cz Git - fpga/rpi-motor-control-pxmc.git/commitdiff
Raspberry Pi 3-phase motor control educational system based on PXMC.
authorPavel Pisa <pisa@cmp.felk.cvut.cz>
Sun, 26 Apr 2015 13:10:20 +0000 (15:10 +0200)
committerPavel Pisa <pisa@cmp.felk.cvut.cz>
Sun, 26 Apr 2015 13:10:20 +0000 (15:10 +0200)
The project support 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.

The uses on PXMC control system libraries,
public and internal applications developed
by PiKRON company.

  http://pxmc.org/
  http://pikron.com/pages/products/motion_control.html

Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
57 files changed:
.gitmodules [new file with mode: 0644]
src/.gitignore [new file with mode: 0644]
src/Makefile [new file with mode: 0644]
src/Makefile.omk [new file with mode: 0644]
src/Makefile.rules [new file with mode: 0644]
src/app/Makefile [new file with mode: 0644]
src/app/Makefile.omk [new file with mode: 0644]
src/app/rpi-pmsm-test1/Makefile [new file with mode: 0644]
src/app/rpi-pmsm-test1/Makefile.omk [new file with mode: 0644]
src/app/rpi-pmsm-test1/appl_cmdproc.c [new file with mode: 0644]
src/app/rpi-pmsm-test1/appl_coordmv.c [new file with mode: 0644]
src/app/rpi-pmsm-test1/appl_defs.h [new file with mode: 0644]
src/app/rpi-pmsm-test1/appl_main.c [new file with mode: 0644]
src/app/rpi-pmsm-test1/appl_pxmc.c [new file with mode: 0644]
src/app/rpi-pmsm-test1/appl_pxmc.h [new file with mode: 0644]
src/app/rpi-pmsm-test1/appl_utils.c [new file with mode: 0644]
src/app/rpi-pmsm-test1/appl_utils.h [new file with mode: 0644]
src/app/rpi-pmsm-test1/boost_prio.sh [new file with mode: 0755]
src/app/rpi-pmsm-test1/math_sqrtll.c [new file with mode: 0644]
src/app/rpi-pmsm-test1/pxmc_spimc.h [new file with mode: 0644]
src/app/rpi-pmsm-test1/rpi_gpclk.c [new file with mode: 0644]
src/app/rpi-pmsm-test1/rpi_gpclk.h [new file with mode: 0644]
src/app/rpi-pmsm-test1/rpi_gpio.c [new file with mode: 0644]
src/app/rpi-pmsm-test1/rpi_gpio.h [new file with mode: 0644]
src/app/rpi-pmsm-test1/rpi_spi.c [new file with mode: 0644]
src/config.omk [new file with mode: 0644]
src/libs4c/Makefile [new file with mode: 0644]
src/libs4c/Makefile.omk [new file with mode: 0644]
src/libs4c/cmdproc/Makefile [new file with mode: 0644]
src/libs4c/cmdproc/Makefile.omk [new file with mode: 0644]
src/libs4c/cmdproc/README [new file with mode: 0644]
src/libs4c/cmdproc/cmd_bth.h [new file with mode: 0644]
src/libs4c/cmdproc/cmd_io.c [new file with mode: 0644]
src/libs4c/cmdproc/cmd_io_line.c [new file with mode: 0644]
src/libs4c/cmdproc/cmd_proc.c [new file with mode: 0644]
src/libs4c/cmdproc/cmd_proc.h [new file with mode: 0644]
src/libs4c/cmdproc/cmd_proc_priv.h [new file with mode: 0644]
src/libs4c/cmdproc/cmd_proc_run.c [new file with mode: 0644]
src/libs4c/cmdproc/cmdio_std.c [new file with mode: 0644]
src/libs4c/cmdproc/cmdio_std_file.c [new file with mode: 0644]
src/libs4c/cmdproc/cmdio_std_line.c [new file with mode: 0644]
src/libs4c/cmdproc/cmdproc_test.c [new file with mode: 0644]
src/libs4c/misc/Makefile [new file with mode: 0644]
src/libs4c/misc/Makefile.omk [new file with mode: 0644]
src/libs4c/misc/i2str.c [new file with mode: 0644]
src/libs4c/misc/i2str.h [new file with mode: 0644]
src/libs4c/misc/utils.c [new file with mode: 0644]
src/libs4c/misc/utils.h [new file with mode: 0644]
src/libs4c/misc/utils_arr.c [new file with mode: 0644]
src/libs4c/pxmc [new symlink]
src/libs4c/ulut [new symlink]
src/system_opt/Makefile [new file with mode: 0644]
src/system_opt/Makefile.omk [new file with mode: 0644]
src/system_opt/cpu_def.h [new file with mode: 0644]
src/system_opt/system_def.h [new file with mode: 0644]
submodule/pxmc [new submodule]
submodule/ulut [new submodule]

diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..b8c1ec7
--- /dev/null
@@ -0,0 +1,6 @@
+[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
diff --git a/src/.gitignore b/src/.gitignore
new file mode 100644 (file)
index 0000000..331b789
--- /dev/null
@@ -0,0 +1,3 @@
+_build
+_compiled
+config.omk-default
diff --git a/src/Makefile b/src/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# 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
+
diff --git a/src/Makefile.omk b/src/Makefile.omk
new file mode 100644 (file)
index 0000000..1ef9b0f
--- /dev/null
@@ -0,0 +1,2 @@
+SUBDIRS = libs4c system_opt app
+
diff --git a/src/Makefile.rules b/src/Makefile.rules
new file mode 100644 (file)
index 0000000..7c86107
--- /dev/null
@@ -0,0 +1,1407 @@
+#  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)
diff --git a/src/app/Makefile b/src/app/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# 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
+
diff --git a/src/app/Makefile.omk b/src/app/Makefile.omk
new file mode 100644 (file)
index 0000000..acdea9b
--- /dev/null
@@ -0,0 +1,4 @@
+# -*- makefile -*-
+
+SUBDIRS = rpi-pmsm-test1
+
diff --git a/src/app/rpi-pmsm-test1/Makefile b/src/app/rpi-pmsm-test1/Makefile
new file mode 100644 (file)
index 0000000..76b56fd
--- /dev/null
@@ -0,0 +1,14 @@
+# 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
+
diff --git a/src/app/rpi-pmsm-test1/Makefile.omk b/src/app/rpi-pmsm-test1/Makefile.omk
new file mode 100644 (file)
index 0000000..a9b20d1
--- /dev/null
@@ -0,0 +1,61 @@
+# -*- 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
diff --git a/src/app/rpi-pmsm-test1/appl_cmdproc.c b/src/app/rpi-pmsm-test1/appl_cmdproc.c
new file mode 100644 (file)
index 0000000..f446620
--- /dev/null
@@ -0,0 +1,178 @@
+#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;
+}
diff --git a/src/app/rpi-pmsm-test1/appl_coordmv.c b/src/app/rpi-pmsm-test1/appl_coordmv.c
new file mode 100644 (file)
index 0000000..5adced3
--- /dev/null
@@ -0,0 +1,186 @@
+/*******************************************************************
+  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
+};
diff --git a/src/app/rpi-pmsm-test1/appl_defs.h b/src/app/rpi-pmsm-test1/appl_defs.h
new file mode 100644 (file)
index 0000000..f5b3fcf
--- /dev/null
@@ -0,0 +1,27 @@
+#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 */
+
diff --git a/src/app/rpi-pmsm-test1/appl_main.c b/src/app/rpi-pmsm-test1/appl_main.c
new file mode 100644 (file)
index 0000000..9a45fd7
--- /dev/null
@@ -0,0 +1,46 @@
+#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;
+}
+
diff --git a/src/app/rpi-pmsm-test1/appl_pxmc.c b/src/app/rpi-pmsm-test1/appl_pxmc.c
new file mode 100644 (file)
index 0000000..54e3b58
--- /dev/null
@@ -0,0 +1,762 @@
+/*******************************************************************
+  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;
+}
diff --git a/src/app/rpi-pmsm-test1/appl_pxmc.h b/src/app/rpi-pmsm-test1/appl_pxmc.h
new file mode 100644 (file)
index 0000000..f8443fa
--- /dev/null
@@ -0,0 +1,54 @@
+/*******************************************************************
+  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_*/
diff --git a/src/app/rpi-pmsm-test1/appl_utils.c b/src/app/rpi-pmsm-test1/appl_utils.c
new file mode 100644 (file)
index 0000000..1fd9563
--- /dev/null
@@ -0,0 +1,101 @@
+#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;
+}
diff --git a/src/app/rpi-pmsm-test1/appl_utils.h b/src/app/rpi-pmsm-test1/appl_utils.h
new file mode 100644 (file)
index 0000000..9f7524a
--- /dev/null
@@ -0,0 +1,24 @@
+#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
diff --git a/src/app/rpi-pmsm-test1/boost_prio.sh b/src/app/rpi-pmsm-test1/boost_prio.sh
new file mode 100755 (executable)
index 0000000..df51a08
--- /dev/null
@@ -0,0 +1,10 @@
+#!/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
diff --git a/src/app/rpi-pmsm-test1/math_sqrtll.c b/src/app/rpi-pmsm-test1/math_sqrtll.c
new file mode 100644 (file)
index 0000000..b05123a
--- /dev/null
@@ -0,0 +1,252 @@
+/*******************************************************************
+  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
+
diff --git a/src/app/rpi-pmsm-test1/pxmc_spimc.h b/src/app/rpi-pmsm-test1/pxmc_spimc.h
new file mode 100644 (file)
index 0000000..1bc4e40
--- /dev/null
@@ -0,0 +1,35 @@
+#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
diff --git a/src/app/rpi-pmsm-test1/rpi_gpclk.c b/src/app/rpi-pmsm-test1/rpi_gpclk.c
new file mode 100644 (file)
index 0000000..5eb6682
--- /dev/null
@@ -0,0 +1,98 @@
+/**
+ * (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;
+}
diff --git a/src/app/rpi-pmsm-test1/rpi_gpclk.h b/src/app/rpi-pmsm-test1/rpi_gpclk.h
new file mode 100644 (file)
index 0000000..b04d04e
--- /dev/null
@@ -0,0 +1,11 @@
+#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
diff --git a/src/app/rpi-pmsm-test1/rpi_gpio.c b/src/app/rpi-pmsm-test1/rpi_gpio.c
new file mode 100644 (file)
index 0000000..cc9eeed
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * 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 */
diff --git a/src/app/rpi-pmsm-test1/rpi_gpio.h b/src/app/rpi-pmsm-test1/rpi_gpio.h
new file mode 100644 (file)
index 0000000..68e8cdf
--- /dev/null
@@ -0,0 +1,46 @@
+#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*/
diff --git a/src/app/rpi-pmsm-test1/rpi_spi.c b/src/app/rpi-pmsm-test1/rpi_spi.c
new file mode 100644 (file)
index 0000000..1976449
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+  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;
+}
diff --git a/src/config.omk b/src/config.omk
new file mode 100644 (file)
index 0000000..a9b9711
--- /dev/null
@@ -0,0 +1,43 @@
+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
+
diff --git a/src/libs4c/Makefile b/src/libs4c/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# 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
+
diff --git a/src/libs4c/Makefile.omk b/src/libs4c/Makefile.omk
new file mode 100644 (file)
index 0000000..63bf25f
--- /dev/null
@@ -0,0 +1,12 @@
+SUBDIRS = ulut pxmc cmdproc misc
+
+#nobase_include_HEADERS = 
+
+#lib_LIBRARIES =
+#shared_LIBRARIES =
+#include_HEADERS  = 
+#xxx_SOURCES =
+#lib_LOADLIBES =
+#bin_PROGRAMS = 
+#utils_PROGRAMS = 
+
diff --git a/src/libs4c/cmdproc/Makefile b/src/libs4c/cmdproc/Makefile
new file mode 100644 (file)
index 0000000..76b56fd
--- /dev/null
@@ -0,0 +1,14 @@
+# 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
+
diff --git a/src/libs4c/cmdproc/Makefile.omk b/src/libs4c/cmdproc/Makefile.omk
new file mode 100644 (file)
index 0000000..1754436
--- /dev/null
@@ -0,0 +1,16 @@
+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
diff --git a/src/libs4c/cmdproc/README b/src/libs4c/cmdproc/README
new file mode 100644 (file)
index 0000000..acba9a4
--- /dev/null
@@ -0,0 +1,7 @@
+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.
diff --git a/src/libs4c/cmdproc/cmd_bth.h b/src/libs4c/cmdproc/cmd_bth.h
new file mode 100644 (file)
index 0000000..9df4d62
--- /dev/null
@@ -0,0 +1,18 @@
+#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
diff --git a/src/libs4c/cmdproc/cmd_io.c b/src/libs4c/cmdproc/cmd_io.c
new file mode 100644 (file)
index 0000000..fe9f7ce
--- /dev/null
@@ -0,0 +1,51 @@
+#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;
+}
+
diff --git a/src/libs4c/cmdproc/cmd_io_line.c b/src/libs4c/cmdproc/cmd_io_line.c
new file mode 100644 (file)
index 0000000..a7fdf23
--- /dev/null
@@ -0,0 +1,129 @@
+/*******************************************************************
+  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 */
diff --git a/src/libs4c/cmdproc/cmd_proc.c b/src/libs4c/cmdproc/cmd_proc.c
new file mode 100644 (file)
index 0000000..c6de7e9
--- /dev/null
@@ -0,0 +1,347 @@
+/*******************************************************************
+  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 */
diff --git a/src/libs4c/cmdproc/cmd_proc.h b/src/libs4c/cmdproc/cmd_proc.h
new file mode 100644 (file)
index 0000000..64af4df
--- /dev/null
@@ -0,0 +1,171 @@
+/*******************************************************************
+  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 */
diff --git a/src/libs4c/cmdproc/cmd_proc_priv.h b/src/libs4c/cmdproc/cmd_proc_priv.h
new file mode 100644 (file)
index 0000000..699c127
--- /dev/null
@@ -0,0 +1,14 @@
+#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
diff --git a/src/libs4c/cmdproc/cmd_proc_run.c b/src/libs4c/cmdproc/cmd_proc_run.c
new file mode 100644 (file)
index 0000000..6c16b7e
--- /dev/null
@@ -0,0 +1,61 @@
+/*******************************************************************
+  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 */
diff --git a/src/libs4c/cmdproc/cmdio_std.c b/src/libs4c/cmdproc/cmdio_std.c
new file mode 100644 (file)
index 0000000..e1c2b52
--- /dev/null
@@ -0,0 +1,31 @@
+/* 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
+};
+
diff --git a/src/libs4c/cmdproc/cmdio_std_file.c b/src/libs4c/cmdproc/cmdio_std_file.c
new file mode 100644 (file)
index 0000000..70408dc
--- /dev/null
@@ -0,0 +1,108 @@
+/*******************************************************************
+  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;
+
+}
diff --git a/src/libs4c/cmdproc/cmdio_std_line.c b/src/libs4c/cmdproc/cmdio_std_line.c
new file mode 100644 (file)
index 0000000..48f1d54
--- /dev/null
@@ -0,0 +1,41 @@
+#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
+        }
+    }
+};
diff --git a/src/libs4c/cmdproc/cmdproc_test.c b/src/libs4c/cmdproc/cmdproc_test.c
new file mode 100644 (file)
index 0000000..0db4bd0
--- /dev/null
@@ -0,0 +1,172 @@
+#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);
+    }
+}
diff --git a/src/libs4c/misc/Makefile b/src/libs4c/misc/Makefile
new file mode 100644 (file)
index 0000000..76b56fd
--- /dev/null
@@ -0,0 +1,14 @@
+# 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
+
diff --git a/src/libs4c/misc/Makefile.omk b/src/libs4c/misc/Makefile.omk
new file mode 100644 (file)
index 0000000..9eefbba
--- /dev/null
@@ -0,0 +1,14 @@
+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
diff --git a/src/libs4c/misc/i2str.c b/src/libs4c/misc/i2str.c
new file mode 100644 (file)
index 0000000..3ee0b26
--- /dev/null
@@ -0,0 +1,82 @@
+/*******************************************************************
+  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;
+}
+
diff --git a/src/libs4c/misc/i2str.h b/src/libs4c/misc/i2str.h
new file mode 100644 (file)
index 0000000..14696ef
--- /dev/null
@@ -0,0 +1,5 @@
+#define I2STR_PAD_0  0x100
+#define I2STR_LONG   0x200
+#define I2STR_NUMBER 0x400
+
+int i2str(char *s,long val,int len,int form);
diff --git a/src/libs4c/misc/utils.c b/src/libs4c/misc/utils.c
new file mode 100644 (file)
index 0000000..9abb8e0
--- /dev/null
@@ -0,0 +1,149 @@
+/*******************************************************************
+  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;
+}
+
diff --git a/src/libs4c/misc/utils.h b/src/libs4c/misc/utils.h
new file mode 100644 (file)
index 0000000..9e51129
--- /dev/null
@@ -0,0 +1,32 @@
+#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_ */
+
diff --git a/src/libs4c/misc/utils_arr.c b/src/libs4c/misc/utils_arr.c
new file mode 100644 (file)
index 0000000..a8b4d1e
--- /dev/null
@@ -0,0 +1,76 @@
+/**
+ * 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);
+}
diff --git a/src/libs4c/pxmc b/src/libs4c/pxmc
new file mode 120000 (symlink)
index 0000000..237f7eb
--- /dev/null
@@ -0,0 +1 @@
+../../submodule/pxmc/libs4c
\ No newline at end of file
diff --git a/src/libs4c/ulut b/src/libs4c/ulut
new file mode 120000 (symlink)
index 0000000..31b2cf7
--- /dev/null
@@ -0,0 +1 @@
+../../submodule/ulut
\ No newline at end of file
diff --git a/src/system_opt/Makefile b/src/system_opt/Makefile
new file mode 100644 (file)
index 0000000..76b56fd
--- /dev/null
@@ -0,0 +1,14 @@
+# 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
+
diff --git a/src/system_opt/Makefile.omk b/src/system_opt/Makefile.omk
new file mode 100644 (file)
index 0000000..83edd81
--- /dev/null
@@ -0,0 +1,3 @@
+include_HEADERS = cpu_def.h system_def.h
+
+
diff --git a/src/system_opt/cpu_def.h b/src/system_opt/cpu_def.h
new file mode 100644 (file)
index 0000000..38b3572
--- /dev/null
@@ -0,0 +1,56 @@
+#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 */
diff --git a/src/system_opt/system_def.h b/src/system_opt/system_def.h
new file mode 100644 (file)
index 0000000..2def659
--- /dev/null
@@ -0,0 +1,45 @@
+/*******************************************************************
+  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_ */
diff --git a/submodule/pxmc b/submodule/pxmc
new file mode 160000 (submodule)
index 0000000..002bf91
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit 002bf91c0907845b45bb7d5a8221edd57ce722da
diff --git a/submodule/ulut b/submodule/ulut
new file mode 160000 (submodule)
index 0000000..be75f4d
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit be75f4de44ddce9b990bde83d52307ac092a9d78