diff --git a/.travis.yml b/.travis.yml index 1131bf2b..b842fcde 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,6 @@ language: c compiler: -- clang - gcc sudo: false @@ -17,20 +16,20 @@ matrix: include: - compiler: gcc env: GRADLE="installLibPcieDriver collectRpms" DEPLOY="yes" - - compiler: clang - env: GRADLE="installLibPcieDriver assemble" addons: apt: packages: - uuid-dev sonarqube: + organization: lnls-dig token: secure: "AXQyy5C9NUv1aeIeVuLClBtLDkZsR4MDTFpIkzgrZX5fOVtVjyukeXfxk91GOtR76lGS5aX0WZLz+yMxsjFcGb49wigPSArZ91VE/UUPMZEIenjzObFdlz23a4GcfBtzTqzlChLNj3AaD80Jt9jUWXlLxTg+1p3FjWmmPS4Nu/VmtL9Nk5XdUwWNnptWWgmf0oL1n9ACRtpEhlBWd8HqzgxfGcT+WPo99TqFm/RZkngSMfgy9u4n1EBixxT7xVe0YVx1pke9hKCpHBMypLuARide/ZAcUf9OeuSgRlpa2+cY/Fn1P6MNfPGIaDbCZQ7PjN8CSJFjsGq+WpT3kNEw96+FHGU4z43eih1Cgo4q6XfezVkk5eLq7QQQVPGDN72VIj2oBAvXoWLxqpY5mA95Nw/rWWahsRScYap+gMHIDGpEwd54RvUMbZSgYTxLc74x6VCMW71JwB0UwUPt9UczVvUQirvPP7JtS4Th0WbFMAXPdOJE0l2F5/mBHbJyWPfD9PA5R/EYIpVkEG5kaZeYcBi0yqIXhW+yAlL6oiPNM28b0RNRkg8bsM0JZL7Vz/+b7+4rU4Ac4b47pCRWgnK6CpWL4C8FY9i0hzAyGq4SCoZPUEHY+Q8zMaGWnqcUePGsk/5bIAtu/Ot7OZcdF9HU3Pg0yeqDyXuyP4sG2q5Er3I=" branches: - master - devel - sonarqube-integration + - sonarqube-gradle before_install: - git submodule update --init --recursive @@ -38,9 +37,10 @@ before_install: # Build and check this project script: - ./ci_build.sh -- sonar-scanner +- ./ci_scanner.sh cache: + ccache: true directories: - '$HOME/.sonar/cache' diff --git a/Makefile b/Makefile index 77f2e3ba..82d12bf0 100644 --- a/Makefile +++ b/Makefile @@ -225,6 +225,7 @@ boards_INCLUDE_DIRS = -Icommon/include/boards/$(BOARD) # Include directories INCLUDE_DIRS = $(boards_INCLUDE_DIRS) \ -Icore/common/include \ + -Icore/revision/include \ -Icore/sm_io/include \ -Icore/sm_io_table/include \ -Iforeign/libsdbfs/include \ @@ -252,8 +253,8 @@ dev_mngr_OBJS += $(dev_mngr_core_OBJS) $(debug_OBJS) \ $(ll_io_utils_OBJS) $(dev_io_core_utils_OBJS) common_app_OBJS = $(dev_io_core_OBJS) $(ll_io_OBJS) \ - $(sm_io_OBJS) $(msg_OBJS) $(board_OBJS) \ - $(board_common_OBJS) + $(sm_io_OBJS) $(sm_io_table_OBJS) $(msg_OBJS) \ + $(board_OBJS) $(board_common_OBJS) apps_OBJS = $(foreach app_obj,$(APPS),$($(app_obj)_all_OBJS)) @@ -268,6 +269,7 @@ GIT_USER_EMAIL = $(shell git config --get user.email) OBJS_all = $(ll_io_OBJS) \ $(sm_io_OBJS) \ + $(sm_io_table_OBJS) \ $(msg_OBJS) \ $(dev_mngr_OBJS) \ $(common_app_OBJS) \ diff --git a/apps/halcsd/build.gradle b/apps/halcsd/build.gradle index 919311d7..29839f59 100644 --- a/apps/halcsd/build.gradle +++ b/apps/halcsd/build.gradle @@ -43,6 +43,7 @@ model { lib project: ':core:boards:afcv3', library: 'afcv3' lib project: ':core:boards:afcv3_1', library: 'afcv3_1' lib project: ':core:boards:ml605', library: 'ml605' + lib project: ':core:revision', library: 'revision' lib project: ':core:sm_io_table', library: 'sm_io_table' lib project: ':core:common', library: 'common' lib project: ':core:dev_io', library: 'dev_io' diff --git a/apps/halcsd/src/halcsd/c/halcsd.c b/apps/halcsd/src/halcsd/c/halcsd.c index a460be4c..3470fe2b 100644 --- a/apps/halcsd/src/halcsd/c/halcsd.c +++ b/apps/halcsd/src/halcsd/c/halcsd.c @@ -473,11 +473,8 @@ int main (int argc, char *argv[]) broker_endp, verbose, devio_log_filename); ASSERT_ALLOC (devio, err_devio_alloc); - /* We don't need it anymore */ - free (dev_entry); - dev_entry = NULL; - - /* Print SDB devices */ + /* Print SDB devices. FIXME. This must be called before zactor_new, + * as it access LLIO layer unsafely */ devio_print_info (devio); /* Start DEVIO loop */ @@ -497,12 +494,6 @@ int main (int argc, char *argv[]) goto err_server; } - /* TODO: Implement and Send SPAWN messages to spawn SMIOs */ - - /* Spawn associated DEVIOs */ - free (broker_endp); - broker_endp = NULL; - /* Spawn platform SMIOSs */ err = _spawn_platform_smios (server, devio_type, fe_smio_id, devio_hints, dev_id); @@ -511,6 +502,54 @@ int main (int argc, char *argv[]) goto err_plat_devio; } + /* FIXME. Currently we have an issue with some SMIOs + * initialization. + * + * If the SMIOs are somewhat dependant, we might need + * to reconfigure them again once they are all up and ready. + * That's because the default configuration of some of them + * (called in smio_config_defaults) might depend on another + * SMIO initialization. + * + * Even worse, in FPGAs, some SMIOs might need an stable clock + * to be able to configure themselves, but some projects + * employ a dynamic clock configured on-thr-fly by the SMIO. + * So, some SMIOs might not even be able to initialize before + * this other SMIO configure the FPGA clock. + * + * Using a more brute-force solution we used to do the following: + * + * 1) We reset the endpoint here (not done here as most of + * our endpoints need to recreate its SMCH instances to be + * able to communicate and we don't do that on reconfigure, + * only on create) + * 2) Tell the SMIOs to reconfigure themselves + * + * But this posed complications as we could reset the endpoint + * without re-creating the SMIOs. So, to simplify this we just + * destroy the DEVIO and recreate it. + * + * */ + + /* Wait until all SMIO configuration is executed */ + while (true) { + char *message = zstr_recv (server); + if (message == NULL) { + DBE_DEBUG (DBG_DEV_IO | DBG_LVL_TRACE, "[halcsd] Interrupted while waiting for $SMIO_CFG_DONE\n"); + goto smio_cfg_done_err; + } + + if (streq (message, "$SMIO_CFG_DONE")) { + free (message); + break; + } + free (message); + } + + /* Now that everything is ready spawn INIT SMIO so clients can + * be sure HALCS is ready to go */ + devio_register_sm (server, 0xdc64e778, 0, 0); + /* Accept and print any message back from server */ while (true) { char *message = zstr_recv (server); @@ -524,6 +563,7 @@ int main (int argc, char *argv[]) } } +smio_cfg_done_err: err_plat_devio: zactor_destroy (&server); err_server: @@ -616,8 +656,8 @@ static devio_err_e _spawn_platform_smios (void *pipe, devio_type_e devio_type, uint32_t smio_inst_id, zhashx_t *hints, uint32_t dev_id) { assert (pipe); -UNUSED(hints); -UNUSED(dev_id); + UNUSED(hints); + UNUSED(dev_id); devio_err_e err = DEVIO_SUCCESS; diff --git a/apps/halcsd/src/systemd/sysfiles/etc/systemd/system/halcs-be@.service b/apps/halcsd/src/systemd/sysfiles/etc/systemd/system/halcs-be@.service index 25b9884d..fb12b287 100644 --- a/apps/halcsd/src/systemd/sysfiles/etc/systemd/system/halcs-be@.service +++ b/apps/halcsd/src/systemd/sysfiles/etc/systemd/system/halcs-be@.service @@ -6,8 +6,9 @@ PartOf=halcs@%i.target [Service] EnvironmentFile=/etc/sysconfig/halcs-board -ExecStartPre=/bin/mkdir -p /media/remote_logs -ExecStart=/usr/local/bin/halcsd -f /usr/local/etc/halcs/halcs.cfg -n be -t pcie -i %i -b ipc:///tmp/malamute -l /media/remote_logs +Environment=HALCS_LOG_DIR=/var/log/halcs +ExecStartPre=/bin/mkdir -p ${HALCS_LOG_DIR} +ExecStart=/usr/local/bin/halcsd -f /usr/local/etc/halcs/halcs.cfg -n be -t pcie -i %i -b ipc:///tmp/malamute -l ${HALCS_LOG_DIR} WorkingDirectory=/usr/local/bin TimeoutStopSec=2 diff --git a/apps/halcsd/src/systemd/sysfiles/etc/systemd/system/halcs-fe@.service b/apps/halcsd/src/systemd/sysfiles/etc/systemd/system/halcs-fe@.service index 1cd08625..9a7227fa 100644 --- a/apps/halcsd/src/systemd/sysfiles/etc/systemd/system/halcs-fe@.service +++ b/apps/halcsd/src/systemd/sysfiles/etc/systemd/system/halcs-fe@.service @@ -6,8 +6,9 @@ PartOf=halcs@%i.target [Service] EnvironmentFile=/etc/sysconfig/halcs-board -ExecStartPre=/bin/mkdir -p /media/remote_logs -ExecStart=/usr/local/bin/halcsd -f /usr/local/etc/halcs/halcs.cfg -n fe -t eth -i %i -b ipc:///tmp/malamute -l /media/remote_logs +Environment=HALCS_LOG_DIR=/var/log/halcs +ExecStartPre=/bin/mkdir -p ${HALCS_LOG_DIR} +ExecStart=/usr/local/bin/halcsd -f /usr/local/etc/halcs/halcs.cfg -n fe -t eth -i %i -b ipc:///tmp/malamute -l ${HALCS_LOG_DIR} WorkingDirectory=/usr/local/bin TimeoutStopSec=2 diff --git a/apps/halcsd/src/systemd/sysfiles/usr/local/share/halcs/scripts/generate-board-halcs-idx.sh b/apps/halcsd/src/systemd/sysfiles/usr/local/share/halcs/scripts/generate-board-halcs-idx.sh new file mode 100755 index 00000000..1e37484c --- /dev/null +++ b/apps/halcsd/src/systemd/sysfiles/usr/local/share/halcs/scripts/generate-board-halcs-idx.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +INPUT=$1 + +INSTANCE_IDX=$(echo ${INPUT} | sed 's|.*-||g') +BOARD_IDX=$(expr ${INSTANCE_IDX} / 2 + ${INSTANCE_IDX} % 2) +HALCS_IDX=$(expr 1 - ${INSTANCE_IDX} % 2) + +# Output space-separated indexes +echo ${INSTANCE_IDX} ${BOARD_IDX} ${HALCS_IDX} diff --git a/build.gradle b/build.gradle index 881778d8..3a3f0093 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,15 @@ +buildscript { + repositories { + maven { + url "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.3" + classpath "org.ajoberstar:gradle-git:1.7.1" + } +} + allprojects { apply plugin: 'c' apply plugin: 'br.lnls.dig.gradle.assemblevarianttask' @@ -5,6 +17,29 @@ allprojects { apply plugin: br.lnls.dig.gradle.currentplatform.CurrentPlatformPlugin apply plugin: 'br.lnls.dig.gradle.sanec' + /* We only want to apply the sonarqube plugin if we are running standalone (vs as a subproject) */ + if (rootProject == project) { + apply plugin: 'org.sonarqube' + } + + sonarqube { + properties { + property "sonar.projectKey", "br.com.lnls.dig.halcs" + property "sonar.projectName", "HALCS Hardware Abstraction Layer for Control Systems" + property "sonar.projectVersion", "v0.5" + + property "sonar.links.homepage", "https://github.com/lnls-dig/halcs" + property "sonar.links.ci", "https://travis-ci.org/lnls-dig/halcs" + property "sonar.links.scm", "https://github.com/lnls-dig/halcs" + property "sonar.links.issue", "https://github.com/lnls-dig/halcs/issues" + + property "sonar.branch", "devel" + + property "sonar.cfamily.build-wrapper-output", "bw-output" + property "sonar.cfamily.gcov.reportsPath", "." + } + } + model { buildTypes { debug diff --git a/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/Command.groovy b/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/Command.groovy new file mode 100644 index 00000000..ee0e7a39 --- /dev/null +++ b/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/Command.groovy @@ -0,0 +1,5 @@ +package br.lnls.dig.gradle.sedtask + +interface Command { + void apply(StringBuffer buffer, CommandCursor commandPosition) +} diff --git a/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/CommandCursor.groovy b/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/CommandCursor.groovy new file mode 100644 index 00000000..184a0178 --- /dev/null +++ b/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/CommandCursor.groovy @@ -0,0 +1,26 @@ +package br.lnls.dig.gradle.sedtask + +class CommandCursor { + private ArrayList commands + private int commandIndex = 0 + + CommandCursor(ArrayList commands) { + this.commands = commands + } + + void next() { + commandIndex += 1 + } + + void advance(int count) { + commandIndex += count + } + + Command getCurrentCommand() { + return commands.get(commandIndex) + } + + boolean finished() { + return commandIndex == commands.size() + } +} diff --git a/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/ConditionalCommand.groovy b/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/ConditionalCommand.groovy new file mode 100644 index 00000000..8b93308e --- /dev/null +++ b/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/ConditionalCommand.groovy @@ -0,0 +1,14 @@ +package br.lnls.dig.gradle.sedtask + +abstract class ConditionalCommand implements Command { + int commandCount = 0 + + public void apply(StringBuffer buffer, CommandCursor commandPosition) { + if (conditionResult(buffer) != true) + commandPosition.advance(commandCount) + + commandPosition.next() + } + + protected abstract boolean conditionResult(StringBuffer buffer) +} diff --git a/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/ReplaceCommand.groovy b/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/ReplaceCommand.groovy new file mode 100644 index 00000000..b26f8018 --- /dev/null +++ b/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/ReplaceCommand.groovy @@ -0,0 +1,23 @@ +package br.lnls.dig.gradle.sedtask + +import java.util.regex.Pattern + +class ReplaceCommand implements Command { + private Pattern pattern + private String replacement + + ReplaceCommand(Pattern pattern, String replacement) { + this.pattern = pattern + this.replacement = replacement + } + + void apply(StringBuffer buffer, CommandCursor commandPosition) { + String line = buffer.toString() + String updatedLine = pattern.matcher(line).replaceFirst(replacement) + + buffer.delete(0, buffer.length()) + buffer.append(updatedLine) + + commandPosition.next() + } +} diff --git a/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/SedCommands.groovy b/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/SedCommands.groovy new file mode 100644 index 00000000..a27316b1 --- /dev/null +++ b/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/SedCommands.groovy @@ -0,0 +1,31 @@ +package br.lnls.dig.gradle.sedtask + +import java.util.regex.Pattern + +class SedCommands { + private List commands + + SedCommands(List commands) { + this.commands = commands + } + + void when(Pattern pattern, Closure commandBlock) { + WhenCommand command = new WhenCommand(pattern) + int commandBlockStart = commands.size() + 1 + + commands.add(command) + + commandBlock.resolveStrategy = Closure.DELEGATE_FIRST + commandBlock.delegate = this + commandBlock() + + int commandBlockEnd = commands.size() + int commandBlockSize = commandBlockEnd - commandBlockStart + + command.commandCount = commandBlockSize + } + + void replace(Pattern pattern, String replacement) { + commands.add(new ReplaceCommand(pattern, replacement)) + } +} diff --git a/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/SedTask.groovy b/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/SedTask.groovy new file mode 100644 index 00000000..f5a0edad --- /dev/null +++ b/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/SedTask.groovy @@ -0,0 +1,58 @@ +package br.lnls.dig.gradle.sedtask + +import java.util.regex.Pattern + +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.TaskAction + +public class SedTask extends DefaultTask { + private ArrayList commandList = new ArrayList() + private SedCommands commands = new SedCommands(commandList) + + File file + + void file(File file) { + this.file = file + } + + void when(Pattern pattern, Closure commandBlock) { + commands.when(pattern, commandBlock) + } + + void replace(Pattern pattern, String replacement) { + commands.replace(pattern, replacement) + } + + @TaskAction + void run() { + if (file == null) { + def message = "File to edit must be configured for SedTask $name" + throw new IllegalArgumentException(message) + } + + List updatedLines = new ArrayList() + + file.eachLine { line -> + String updatedLine = runCommands(line) + + updatedLines.add(updatedLine) + } + + file.withPrintWriter { writer -> + updatedLines.each { line -> writer.println(line) } + } + } + + String runCommands(String line) { + StringBuffer buffer = new StringBuffer(line) + CommandCursor cursor = new CommandCursor(commandList) + + while (!cursor.finished()) { + Command command = cursor.currentCommand + + command.apply(buffer, cursor) + } + + return buffer.toString() + } +} diff --git a/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/WhenCommand.groovy b/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/WhenCommand.groovy new file mode 100644 index 00000000..acd661fa --- /dev/null +++ b/buildSrc/src/main/groovy/br/lnls/dig/gradle/sedtask/WhenCommand.groovy @@ -0,0 +1,15 @@ +package br.lnls.dig.gradle.sedtask + +import java.util.regex.Pattern + +class WhenCommand extends ConditionalCommand { + private Pattern pattern + + public WhenCommand(Pattern pattern) { + this.pattern = pattern + } + + protected boolean conditionResult(StringBuffer buffer) { + return pattern.matcher(buffer.toString()).find() + } +} diff --git a/buildSrc/src/main/groovy/br/lnls/dig/gradle/updatesemvermacrostask/UpdateSemVerMacrosTask.groovy b/buildSrc/src/main/groovy/br/lnls/dig/gradle/updatesemvermacrostask/UpdateSemVerMacrosTask.groovy new file mode 100644 index 00000000..5d2a0aa6 --- /dev/null +++ b/buildSrc/src/main/groovy/br/lnls/dig/gradle/updatesemvermacrostask/UpdateSemVerMacrosTask.groovy @@ -0,0 +1,32 @@ +package br.lnls.dig.gradle.updatesemvermacrostask + +import br.lnls.dig.gradle.sedtask.SedTask + +public class UpdateSemVerMacrosTask extends SedTask { + void macroPrefix(String macroPrefix) { + def semVerNums = semVerNumbers + def major = semVerNums[0] + def minor = semVerNums[1] + def patch = semVerNums[2] + + when(~"#define ${macroPrefix}MAJOR [0-9]*") { + replace ~/[0-9]*$/, major + } + + when(~"#define ${macroPrefix}MINOR [0-9]*") { + replace ~/[0-9]*$/, minor + } + + when(~"#define ${macroPrefix}PATCH [0-9]*") { + replace ~/[0-9]*$/, patch + } + } + + String getSemVerSummary() { + return project.version.toString().split('-')[0] + } + + String[] getSemVerNumbers() { + return semVerSummary.split('[.]') + } +} diff --git a/ci_build.sh b/ci_build.sh index 1b7367b9..b835271b 100755 --- a/ci_build.sh +++ b/ci_build.sh @@ -2,13 +2,78 @@ # help debug set -x +set -e +set -o + +# Environment setup +LANG=C +LC_ALL=C +export LANG LC_ALL + +if [ -d "./tmp" ]; then + rm -rf ./tmp +fi + +mkdir -p tmp +mkdir -p tmp/etc # Build and local install repositories -mkdir tmp -mkdir tmp/etc BUILD_PREFIX=$PWD/tmp SCRIPTS_PREFIX=$PWD/tmp/etc +# CCache setup +PATH="`echo "$PATH" | sed -e 's,^/usr/lib/ccache/?:,,' -e 's,:/usr/lib/ccache/?:,,' -e 's,:/usr/lib/ccache/?$,,' -e 's,^/usr/lib/ccache/?$,,'2`" +CCACHE_PATH="$PATH" +CCACHE_DIR="${HOME}/.ccache" +export CCACHE_PATH CCACHE_DIR PATH +HAVE_CCACHE=no + +if which ccache && ls -la /usr/lib/ccache ; then + HAVE_CCACHE=yes +fi + +# Get CCache statistics +if [ "$HAVE_CCACHE" = yes ] && [ -d "$CCACHE_DIR" ]; then + echo "CCache stats before build:" + ccache -s || true +fi + +mkdir -p "${HOME}/.ccache" + +# Compiler detection +is_gnucc() { + if [ -n "$1" ] && "$1" --version 2>&1 | grep 'Free Software Foundation' > /dev/null ; then true ; else false ; fi +} + +COMPILER_FAMILY="" +if [ -n "$CC" -a -n "$CXX" ]; then + if is_gnucc "$CC" && is_gnucc "$CXX" ; then + COMPILER_FAMILY="GCC" + export CC CXX + fi +else + if is_gnucc "gcc" && is_gnucc "g++" ; then + # Autoconf would pick this by default + COMPILER_FAMILY="GCC" + [ -n "$CC" ] || CC=gcc + [ -n "$CXX" ] || CXX=g++ + export CC CXX + elif is_gnucc "cc" && is_gnucc "c++" ; then + COMPILER_FAMILY="GCC" + [ -n "$CC" ] || CC=cc + [ -n "$CXX" ] || CXX=c++ + export CC CXX + fi +fi + +if [ -n "$CPP" ] ; then + [ -x "$CPP" ] && export CPP +else + if is_gnucc "cpp" ; then + CPP=cpp && export CPP + fi +fi + LIBSODIUM_VER=1.0.3 LIBZMQ_VER=v4.2.1 LIBCZMQ_VER=v4.0.2 @@ -21,7 +86,7 @@ CONFIG_FLAGS+=("CXXFLAGS=-I${BUILD_PREFIX}/include") CONFIG_FLAGS+=("LDFLAGS=-L${BUILD_PREFIX}/lib") KERNEL_FLAGS=() -KERNEL_FLAGS+=("INSTALLDIR=${BUILD_PREFIX}/lib/modules/$(shell uname -r)/extra") +KERNEL_FLAGS+=("INSTALLDIR=${BUILD_PREFIX}/lib/modules/$(uname -r)/extra") KERNEL_FLAGS+=("INSTALLHDRDIR=${BUILD_PREFIX}/include/pciDriver/driver") HALCS_OPTS=() @@ -34,30 +99,218 @@ CONFIG_OPTS=() CONFIG_OPTS+=(${CONFIG_FLAGS[@]}) CONFIG_OPTS+=("PKG_CONFIG_PATH=${BUILD_PREFIX}/lib/pkgconfig") CONFIG_OPTS+=("--prefix=${BUILD_PREFIX}") +CONFIG_OPTS+=("--with-docs=no") + +# CCache CCACHE_PATH setup +if [ "$HAVE_CCACHE" = yes ] && [ "${COMPILER_FAMILY}" = GCC ]; then + PATH="/usr/lib/ccache:$PATH" + export PATH + + if [ -n "$CC" ] && [ -x "/usr/lib/ccache/`basename "$CC"`" ]; then + case "$CC" in + *ccache*) + ;; + */*) + DIR_CC="`dirname "$CC"`" && [ -n "$DIR_CC" ] && \ + DIR_CC="`cd "$DIR_CC" && pwd `" && [ -n "$DIR_CC" ] && \ + [ -d "$DIR_CC" ] || DIR_CC="" + + [ -z "$CCACHE_PATH" ] && CCACHE_PATH="$DIR_CC" || \ + if echo "$CCACHE_PATH" | egrep '(^'"$DIR_CC"':.*|^'"$DIR_CC"'$|:'"$DIR_CC"':|:'"$DIR_CC"'$)' ; then + CCACHE_PATH="$DIR_CC:$CCACHE_PATH" + fi + ;; + esac + CC="/usr/lib/ccache/`basename "$CC"`" + else + : # CC="ccache $CC" + fi + if [ -n "$CXX" ] && [ -x "/usr/lib/ccache/`basename "$CXX"`" ]; then + case "$CXX" in + *ccache*) + ;; + */*) + DIR_CXX="`dirname "$CXX"`" && [ -n "$DIR_CXX" ] && \ + DIR_CXX="`cd "$DIR_CXX" && pwd `" && [ -n "$DIR_CXX" ] && \ + [ -d "$DIR_CXX" ] || DIR_CXX="" + + [ -z "$CCACHE_PATH" ] && CCACHE_PATH="$DIR_CXX" || \ + if echo "$CCACHE_PATH" | egrep '(^'"$DIR_CXX"':.*|^'"$DIR_CXX"'$|:'"$DIR_CXX"':|:'"$DIR_CXX"'$)' ; then + CCACHE_PATH="$DIR_CXX:$CCACHE_PATH" + fi + ;; + esac + CXX="/usr/lib/ccache/`basename "$CXX"`" + else + : # CXX="ccache $CXX" + fi + if [ -n "$CPP" ] && [ -x "/usr/lib/ccache/`basename "$CPP"`" ]; then + case "$CPP" in + *ccache*) + ;; + */*) + DIR_CPP="`dirname "$CPP"`" && [ -n "$DIR_CPP" ] && \ + DIR_CPP="`cd "$DIR_CPP" && pwd `" && [ -n "$DIR_CPP" ] && \ + [ -d "$DIR_CPP" ] || DIR_CPP="" + + [ -z "$CCACHE_PATH" ] && CCACHE_PATH="$DIR_CPP" || \ + if echo "$CCACHE_PATH" | egrep '(^'"$DIR_CPP"':.*|^'"$DIR_CPP"'$|:'"$DIR_CPP"':|:'"$DIR_CPP"'$)' ; then + CCACHE_PATH="$DIR_CPP:$CCACHE_PATH" + fi + ;; + esac + CPP="/usr/lib/ccache/`basename "$CPP"`" + else + : # CPP="ccache $CPP" + fi + + CONFIG_OPTS+=("CC=${CC}") + CONFIG_OPTS+=("CXX=${CXX}") + CONFIG_OPTS+=("CPP=${CPP}") +fi + +########### libsodium +echo "" +BASE_PWD=${PWD} +echo "`date`: INFO: Building prerequisite 'libsodium' from Git repository..." >&2 +git clone --branch=${LIBSODIUM_VER} git://github.com/jedisct1/libsodium.git +cd libsodium -# libsodium -git clone --branch=${LIBSODIUM_VER} git://github.com/jedisct1/libsodium.git && -( cd libsodium; ./autogen.sh && ./configure --prefix=$BUILD_PREFIX && - make check && make install ) || exit 1 +# CCache directory +CCACHE_BASEDIR=${PWD} +export CCACHE_BASEDIR -# libzmq -git clone --branch=${LIBZMQ_VER} git://github.com/zeromq/libzmq.git && -( cd libzmq; ./autogen.sh && ./configure "${CONFIG_OPTS[@]}" && - make check && make install ) || exit 1 +git --no-pager log --oneline -n1o -# CZMQ -git clone --branch=${LIBCZMQ_VER} git://github.com/zeromq/czmq.git && -( cd czmq; ./autogen.sh && ./configure "${CONFIG_OPTS[@]}" && - make check && make install ) || exit 1 +# Build/Install +if [ -e autogen.sh ]; then + ./autogen.sh 2> /dev/null +fi +if [ -e buildconf ]; then + ./buildconf 2> /dev/null +fi +if [ ! -e autogen.sh ] && [ ! -e buildconf ] && [ ! -e ./configure ] && [ -s ./configure.ac ]; then + libtoolize --copy --force && \ + aclocal -I . && \ + autoheader && \ + automake --add-missing --copy && \ + autoconf || \ + autoreconf -fiv +fi +./configure "${CONFIG_OPTS[@]}" +make -j4 +make install +cd "${BASE_PWD}" + +########### libzmq +echo "" +BASE_PWD=${PWD} +echo "`date`: INFO: Building prerequisite 'libzmq' from Git repository..." >&2 +git clone --branch=${LIBZMQ_VER} git://github.com/zeromq/libzmq.git +cd libzmq -# Malamute -git clone --branch=${MALAMUTE_VER} git://github.com/lnls-dig/malamute.git && -( cd malamute; ./autogen.sh && ./configure "${CONFIG_OPTS[@]}" && - make check && make install ) || exit 1 +# CCache directory +CCACHE_BASEDIR=${PWD} +export CCACHE_BASEDIR +git --no-pager log --oneline -n1o + +# Build/Install +if [ -e autogen.sh ]; then + ./autogen.sh 2> /dev/null +fi +if [ -e buildconf ]; then + ./buildconf 2> /dev/null +fi +if [ ! -e autogen.sh ] && [ ! -e buildconf ] && [ ! -e ./configure ] && [ -s ./configure.ac ]; then + libtoolize --copy --force && \ + aclocal -I . && \ + autoheader && \ + automake --add-missing --copy && \ + autoconf || \ + autoreconf -fiv +fi +./configure "${CONFIG_OPTS[@]}" +make -j4 +make install +cd "${BASE_PWD}" + +########### CZMQ +echo "" +BASE_PWD=${PWD} +echo "`date`: INFO: Building prerequisite 'czmq' from Git repository..." >&2 +git clone --branch=${LIBCZMQ_VER} git://github.com/zeromq/czmq.git +cd czmq + +# CCache directory +CCACHE_BASEDIR=${PWD} +export CCACHE_BASEDIR + +git --no-pager log --oneline -n1o + +# Build/Install +if [ -e autogen.sh ]; then + ./autogen.sh 2> /dev/null +fi +if [ -e buildconf ]; then + ./buildconf 2> /dev/null +fi +if [ ! -e autogen.sh ] && [ ! -e buildconf ] && [ ! -e ./configure ] && [ -s ./configure.ac ]; then + libtoolize --copy --force && \ + aclocal -I . && \ + autoheader && \ + automake --add-missing --copy && \ + autoconf || \ + autoreconf -fiv +fi +./configure "${CONFIG_OPTS[@]}" +make -j4 +make install +cd "${BASE_PWD}" + +########### Malamute +echo "" +BASE_PWD=${PWD} +echo "`date`: INFO: Building prerequisite 'malamute' from Git repository..." >&2 +git clone --branch=${MALAMUTE_VER} git://github.com/lnls-dig/malamute.git +cd malamute + +# CCache directory +CCACHE_BASEDIR=${PWD} +export CCACHE_BASEDIR + +git --no-pager log --oneline -n1o + +# Build/Install +if [ -e autogen.sh ]; then + ./autogen.sh 2> /dev/null +fi +if [ -e buildconf ]; then + ./buildconf 2> /dev/null +fi +if [ ! -e autogen.sh ] && [ ! -e buildconf ] && [ ! -e ./configure ] && [ -s ./configure.ac ]; then + libtoolize --copy --force && \ + aclocal -I . && \ + autoheader && \ + automake --add-missing --copy && \ + autoconf || \ + autoreconf -fiv +fi +./configure "${CONFIG_OPTS[@]}" +make -j4 +make install +cd "${BASE_PWD}" + +########## HALCS if [ -z "$GRADLE" ]; then -build-wrapper-linux-x86-64 --out-dir bw-output ./compile.sh -b $BOARD -a "${APP}" -e $EXAMPLES -l $SYSTEM_INTEGRATION -x "${HALCS_OPTS[*]}" + build-wrapper-linux-x86-64 --out-dir bw-output ./compile.sh -b $BOARD -a "${APP}" -e $EXAMPLES -l $SYSTEM_INTEGRATION -x "${HALCS_OPTS[*]}" else export ${CONFIG_FLAGS[@]} ./gradlew $GRADLE -Prelease.stage=ci_release fi + +# Get CCache statistics +if [ "$HAVE_CCACHE" = yes ]; then + echo "CCache stats after build:" + ccache -s +fi diff --git a/ci_scanner.sh b/ci_scanner.sh new file mode 100755 index 00000000..ecb07584 --- /dev/null +++ b/ci_scanner.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +# help debug +set -x + +if [ -z "$GRADLE" ]; then + sonar-scanner +fi diff --git a/core/boards/afcv3/build.gradle b/core/boards/afcv3/build.gradle index f7c6a5ef..fb89dbb9 100644 --- a/core/boards/afcv3/build.gradle +++ b/core/boards/afcv3/build.gradle @@ -4,6 +4,7 @@ model { sources { c { lib project: ':core:common', library: 'common' + lib project: ':core:revision', library: 'revision' lib project: ':core:sm_io', library: 'sm_io', linkage: 'api' lib project: ':core:sm_io_table', library: 'sm_io_table' lib project: ':foreign:libbsmp', library: 'bsmp' diff --git a/core/boards/afcv3_1/build.gradle b/core/boards/afcv3_1/build.gradle index 7040d9d0..9f07c75d 100644 --- a/core/boards/afcv3_1/build.gradle +++ b/core/boards/afcv3_1/build.gradle @@ -4,6 +4,7 @@ model { sources { c { lib project: ':core:common', library: 'common' + lib project: ':core:revision', library: 'revision' lib project: ':core:sm_io', library: 'sm_io', linkage: 'api' lib project: ':core:sm_io_table', library: 'sm_io_table' lib project: ':foreign:libbsmp', library: 'bsmp' diff --git a/core/boards/common/build.gradle b/core/boards/common/build.gradle index 390f0874..6c7ff039 100644 --- a/core/boards/common/build.gradle +++ b/core/boards/common/build.gradle @@ -4,6 +4,7 @@ model { sources { c { lib project: ':core:common', library: 'common' + lib project: ':core:revision', library: 'revision' lib project: ':core:sm_io', library: 'sm_io', linkage: 'api' lib project: ':core:sm_io_table', library: 'sm_io_table' lib project: ':foreign:libbsmp', library: 'bsmp' diff --git a/core/boards/ml605/build.gradle b/core/boards/ml605/build.gradle index 3e632809..e47ea640 100644 --- a/core/boards/ml605/build.gradle +++ b/core/boards/ml605/build.gradle @@ -4,6 +4,7 @@ model { sources { c { lib project: ':core:common', library: 'common' + lib project: ':core:revision', library: 'revision' lib project: ':core:sm_io', library: 'sm_io', linkage: 'api' lib project: ':core:sm_io_table', library: 'sm_io_table' lib project: ':foreign:libbsmp', library: 'bsmp' diff --git a/core/common/build.gradle b/core/common/build.gradle index cdfa0c6f..b89835e2 100644 --- a/core/common/build.gradle +++ b/core/common/build.gradle @@ -1,3 +1,6 @@ +apply plugin: 'org.ajoberstar.grgit' +apply plugin: 'org.ajoberstar.release-opinion' + model { components { common(NativeLibrarySpec) { @@ -5,6 +8,7 @@ model { c { exportedHeaders.srcDir 'include' + lib project: ':core:revision', library: 'revision', linkage: 'api' lib project: ':core:sm_io', library: 'sm_io' lib project: ':libs:llio', library: 'llio' lib project: ':libs:sdbutils', library: 'sdbutils' diff --git a/core/common/include/dev_io_core.h b/core/common/include/dev_io_core.h index 57f83327..3d82967f 100644 --- a/core/common/include/dev_io_core.h +++ b/core/common/include/dev_io_core.h @@ -74,6 +74,12 @@ devio_err_e devio_register_sm_by_id (void *pipe, uint32_t smio_id); devio_err_e devio_register_all_sm (void *pipe); devio_err_e devio_unregister_sm (void *pipe, const char *smio_key); devio_err_e devio_unregister_all_sm (void *pipe); +/* Reconfigure SMIOs by calling registered callbacks */ +devio_err_e devio_reconfigure_sm (void *pipe, const char *smio_key); +devio_err_e devio_reconfigure_all_sm (void *pipe); +/* Reset associated LLIO*/ +devio_err_e devio_reset_llio (void *pipe); + /* Poll all PIPE sockets */ void devio_loop (zsock_t *pipe, void *args); /* Router for all the opcodes registered for this dev_io */ diff --git a/core/common/include/halcs_server_classes.h b/core/common/include/halcs_server_classes.h index e98d77fd..36e28019 100644 --- a/core/common/include/halcs_server_classes.h +++ b/core/common/include/halcs_server_classes.h @@ -33,17 +33,6 @@ #include "acq_chan_gen_defs.h" #include "ddr3_map_structs.h" -/* HALCS version macros for compile-time API detection */ - -#define HALCS_VERSION_MAJOR 0 -#define HALCS_VERSION_MINOR 1 -#define HALCS_VERSION_PATCH 0 - -#define HALCS_MAKE_VERSION(major, minor, patch) \ - ((major) * 10000 + (minor) * 100 + (patch)) -#define HALCS_VERSION \ - HALCS_MAKE_VERSION(HALCS_VERSION_MAJOR, HALCS_VERSION_MINOR, HALCS_VERSION_PATCH) - #if defined (__WINDOWS__) # if defined LIBHALCS_STATIC # define HALCS_EXPORT @@ -106,6 +95,8 @@ typedef struct _smio_mod_dispatch_t smio_mod_dispatch_t; typedef enum _smio_err_e smio_err_e; /* Opaque smio_t structure */ typedef struct _smio_t smio_t; +/* Opaque smio_cfg_t structure */ +typedef struct _smio_cfg_t smio_cfg_t; /* Forward msg_err_e declaration enumeration */ typedef enum _msg_err_e msg_err_e; @@ -166,6 +157,7 @@ typedef struct _zmq_server_args_t zmq_server_args_t; #include "sm_io_bootstrap.h" #include "sm_io_mod_dispatch.h" #include "sm_io.h" +#include "sm_io_cfg.h" /* MSG */ #include "msg_macros.h" diff --git a/core/common/include/sm_ch_isla216p.h b/core/common/include/sm_ch_isla216p.h index 1808acb6..ea16ca3d 100644 --- a/core/common/include/sm_ch_isla216p.h +++ b/core/common/include/sm_ch_isla216p.h @@ -40,6 +40,8 @@ smch_err_e smch_isla216p_get_rst (smch_isla216p_t *self, uint8_t *rst_operation) smch_err_e smch_isla216p_set_portconfig (smch_isla216p_t *self, uint8_t config); /* Read temperature code */ smch_err_e smch_isla216p_get_temp (smch_isla216p_t *self, uint16_t *temp); +/* Read calibration status */ +smch_err_e smch_isla216p_get_cal_status (smch_isla216p_t *self, uint8_t *cal_status); #ifdef __cplusplus } diff --git a/core/common/include/sm_io.h b/core/common/include/sm_io.h index d3a703ae..0b2631e1 100644 --- a/core/common/include/sm_io.h +++ b/core/common/include/sm_io.h @@ -42,7 +42,7 @@ extern "C" { SMIO_DISPATCH_FUNC_WRAPPER_GEN(func_name, smio_mod_handler, self, ## __VA_ARGS__) /* Attach an instance of sm_io to dev_io function pointer */ -typedef smio_err_e (*attach_fp)(smio_t *self, devio_t *parent); +typedef smio_err_e (*attach_fp)(smio_t *self, void *args); /* Deattach an instance of sm_io to dev_io function pointer */ typedef smio_err_e (*deattach_fp)(smio_t *self); /* Export (register) sm_io to handle operations function pointer */ @@ -107,7 +107,7 @@ typedef struct { /* Thread boot args structure */ typedef struct { - struct _devio_t *parent; /* Pointer back to devo parent */ + void *args; /* Generic arguments for SMIO */ volatile const smio_mod_dispatch_t *smio_handler; /* SMIO table handler */ zsock_t *pipe_msg; /* Message PIPE to actor */ char *broker; /* Endpoint to connect to broker */ @@ -130,7 +130,7 @@ smio_err_e smio_loop (smio_t *self); smio_err_e smio_register_sm (smio_t *self, uint32_t smio_id, uint64_t base, uint32_t inst_id); /* Send MGMT message */ -smio_err_e smio_send_mgmt_msg (smio_t *self, uint32_t dest_smio_id, +smio_err_e smio_send_mgmt_msg (smio_t *self, uint32_t dest_smio_id, uint32_t dest_smio_inst, char *msg); smio_err_e smio_init_exp_ops (smio_t *self, disp_op_t** smio_exp_ops, @@ -176,13 +176,15 @@ mlm_client_t *smio_get_worker (smio_t *self); zsock_t *smio_get_pipe_msg (smio_t *self); /* Get SMIO PIPE Management */ zsock_t *smio_get_pipe_mgmt (smio_t *self); +/* Get poller */ +zpoller_t *smio_get_poller (smio_t *self); /************************************************************/ /**************** Smio OPS generic methods API **************/ /************************************************************/ /* Attach an instance of sm_io to dev_io function pointer */ -smio_err_e smio_attach (smio_t *self, struct _devio_t *parent); +smio_err_e smio_attach (smio_t *self, void *args); /* Deattach an instance of sm_io to dev_io function pointer */ smio_err_e smio_deattach (smio_t *self); /* Export (Register) sm_io to handle specific operations */ diff --git a/core/common/include/sm_io_bootstrap.h b/core/common/include/sm_io_bootstrap.h index 5b633fc6..beebcbf7 100644 --- a/core/common/include/sm_io_bootstrap.h +++ b/core/common/include/sm_io_bootstrap.h @@ -29,15 +29,6 @@ typedef struct { smio_config_defaults_fp config_defaults; } smio_bootstrap_ops_t; -/* Config thread args structure */ -typedef struct { - volatile const smio_mod_dispatch_t *smio_handler; /* SMIO table handler */ - uint32_t inst_id; /* SMIO instance ID */ - char *broker; /* Endpoint to connect to broker */ - char *service; /* Full name of the exported service */ - char *log_file; /* Thread log file */ -} th_config_args_t; - /************************************************************/ /************************ Our methods ***********************/ /************************************************************/ diff --git a/core/common/include/sm_io_cfg.h b/core/common/include/sm_io_cfg.h new file mode 100644 index 00000000..12e7d308 --- /dev/null +++ b/core/common/include/sm_io_cfg.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2017 LNLS (www.lnls.br) + * Author: Lucas Russo + * + * Released according to the GNU GPL, version 3 or any later version. + */ + +#ifndef _SM_IO_CFG_H_ +#define _SM_IO_CFG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Config thread args structure */ +typedef struct { + volatile const smio_mod_dispatch_t *smio_handler; /* SMIO table handler */ + uint32_t inst_id; /* SMIO instance ID */ + char *broker; /* Endpoint to connect to broker */ + char *service; /* Full name of the exported service */ + char *log_file; /* Thread log file */ +} th_config_args_t; + +/***************** Our methods *****************/ + +/* Creates new instance of smio_cfg */ +smio_cfg_t *smio_cfg_new (th_config_args_t *config_args, + volatile const smio_mod_dispatch_t *smio_mod_dispatch, + zsock_t *pipe, char *service, char *inst_id_str); +/* Destroys instance of smio_cfg */ +smio_err_e smio_cfg_destroy (smio_cfg_t **self_p); +/* Loop through all interface sockets executing registered callbacks on them */ +smio_err_e smio_cfg_loop (smio_cfg_t *self); + +/************************************************************/ +/********************* Accessor methods *********************/ +/************************************************************/ + +/* Get SMIO service */ +const char *smio_cfg_get_service (smio_cfg_t *self); +/* Clone SMIO service */ +char *smio_cfg_clone_service (smio_cfg_t *self); +/* Get pipe socket */ +zsock_t *smio_cfg_get_pipe (smio_cfg_t *self); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/common/include/smio_thsafe_zmq_server.h b/core/common/include/smio_thsafe_zmq_server.h index a3121d39..0b18ac9c 100644 --- a/core/common/include/smio_thsafe_zmq_server.h +++ b/core/common/include/smio_thsafe_zmq_server.h @@ -15,12 +15,13 @@ extern "C" { /* Somewhat arbitrary maximum block size for read_block funtions */ #define ZMQ_SERVER_BLOCK_SIZE (1 * (1 << 20)) +/* We want a flexible array member but we can't do it*/ typedef struct { - /* This field is not used */ - uint32_t valid_bytes_dummy; - uint8_t data[]; + uint8_t data[1]; } zmq_server_data_block_t; +#define ZMQ_SERVER_DATA_BLOCK_DATA_SIZE 1 + /* For use by smio_t general structure */ extern const disp_op_t *smio_thsafe_zmq_server_ops []; diff --git a/core/dev_io/build.gradle b/core/dev_io/build.gradle index 919b9d45..28fa3f3d 100644 --- a/core/dev_io/build.gradle +++ b/core/dev_io/build.gradle @@ -5,6 +5,7 @@ model { c { lib project: ':core:common', library: 'common' lib project: ':core:msg', library: 'msg' + lib project: ':core:revision', library: 'revision' lib project: ':core:sm_io', library: 'sm_io' lib project: ':core:sm_io_table', library: 'sm_io_table' lib project: ':foreign:libbsmp', library: 'bsmp' diff --git a/core/dev_io/src/dev_io/c/dev_io_core.c b/core/dev_io/src/dev_io/c/dev_io_core.c index 660e4ee5..0e76bc9d 100644 --- a/core/dev_io/src/dev_io/c/dev_io_core.c +++ b/core/dev_io/src/dev_io/c/dev_io_core.c @@ -56,7 +56,6 @@ struct _devio_t { char *log_file; /* Log filename for tracing and debugging */ char *endpoint_broker; /* Broker location to connect to */ int verbose; /* Print activity to stdout */ - int timer_id; /* Timer ID */ struct sdbfs *sdbfs; /* SDB information */ /* General management operations */ @@ -100,6 +99,7 @@ static char *_devio_gen_smio_key_auto (devio_t *self, /* Do the SMIO operation */ static devio_err_e _devio_do_smio_op (devio_t *self, void *msg); static devio_err_e _devio_destroy_actor (devio_t *self, zactor_t **actor); +static devio_err_e _devio_reconfigure_actor (devio_t *self, zactor_t **actor); static devio_err_e _devio_destroy_smio (devio_t *self, zhashx_t *smio_h, const char *smio_key); static devio_err_e _devio_destroy_smio_all (devio_t *self, zhashx_t *smio_h); @@ -114,7 +114,6 @@ static volatile const smio_mod_dispatch_t *_devio_search_sm_by_id (devio_t *self uint32_t smio_id); static devio_err_e _devio_engine_handle_socket (devio_t *devio, void *sock, zloop_reader_fn handler); -static int _devio_handle_timer (zloop_t *loop, int timer_id, void *arg); static int _devio_handle_pipe_backend (zloop_t *loop, zsock_t *reader, void *args); static devio_err_e _devio_register_sm_raw (devio_t *self, uint32_t smio_id, uint64_t base, @@ -126,6 +125,10 @@ static devio_err_e _devio_register_sm_by_id_raw (devio_t *self, uint32_t smio_id static devio_err_e _devio_register_all_sm_raw (devio_t *self); static devio_err_e _devio_unregister_sm_raw (devio_t *self, const char *smio_key); static devio_err_e _devio_unregister_all_sm_raw (devio_t *self); +static devio_err_e _devio_reconfigure_sm_raw (devio_t *self, const char *smio_key); +static devio_err_e _devio_reconfigure_all_sm_raw (devio_t *self); +static devio_err_e _devio_reset_llio_raw (devio_t *self); +static devio_err_e _devio_check_send_cfg_done (devio_t *self); /* FIXME: Only valid for PCIe devices */ static int _devio_read_llio_block (struct sdbfs *fs, int offset, void *buf, @@ -212,12 +215,6 @@ devio_t * devio_new (char *name, uint32_t id, char *endpoint_dev, self->loop = zloop_new (); ASSERT_ALLOC(self->loop, err_loop_alloc); - /* Set loop timeout. This is needed to ensure zloop will - * frequently check for rebuilding its poll set */ - self->timer_id = zloop_timer (self->loop, DEVIO_POLLER_TIMEOUT, DEVIO_POLLER_NTIMES, - _devio_handle_timer, NULL); - ASSERT_TEST(self->timer_id != -1, "Could not create zloop timer", err_timer_alloc); - /* Set-up backend handler for forcing interrupting the zloop and rebuild * the poll set. This avoids having to setup a short timer to periodically * interrupting the loop to check for rebuilds */ @@ -356,8 +353,6 @@ devio_t * devio_new (char *name, uint32_t id, char *endpoint_dev, err_endp_broker_alloc: free (self->name); err_name_alloc: - zloop_timer_end (self->loop, self->timer_id); -err_timer_alloc: zloop_destroy (&self->loop); err_loop_alloc: zsock_destroy (&self->pipe_backend); @@ -436,7 +431,6 @@ devio_err_e devio_destroy (devio_t **self_p) free (self->name); DBE_DEBUG (DBG_DEV_IO | DBG_LVL_INFO, "[dev_io_core:destroy] Destroying loop\n"); - zloop_timer_end (self->loop, self->timer_id); zloop_destroy (&self->loop); DBE_DEBUG (DBG_DEV_IO | DBG_LVL_INFO, @@ -564,16 +558,6 @@ static devio_err_e _devio_engine_handle_socket (devio_t *devio, void *sock, /********************** zloop handlers **********************/ /************************************************************/ -/* zloop handler for timer */ -static int _devio_handle_timer (zloop_t *loop, int timer_id, void *arg) -{ - UNUSED(loop); - UNUSED(timer_id); - UNUSED(arg); - - return 0; -} - /* zloop handler for MSG PIPE */ static int _devio_handle_pipe_msg (zloop_t *loop, zsock_t *reader, void *args) { @@ -705,6 +689,9 @@ static int _devio_handle_pipe_cfg (zloop_t *loop, zsock_t *reader, void *args) service_id = NULL; zmsg_destroy (&recv_msg); + /* Check if all registered config actors are done */ + err = _devio_check_send_cfg_done (devio); + /* TODO. Do we really need to exit on error? */ if (err != 0) { return err; @@ -724,12 +711,14 @@ static int _devio_handle_pipe (zloop_t *loop, zsock_t *reader, void *args) uint32_t smio_id; uint64_t base; uint32_t inst_id; + char *smio_key = NULL; /* This command expects one of the following */ /* Command: (string) $REGISTER_SMIO * Arg1: (uint32_t) smio_id * Arg2: (uint64_t) base * Arg3: (uint32_t) inst_id + * Arg4: (string) smio_key * * Command: (string) $TERM * @@ -738,7 +727,8 @@ static int _devio_handle_pipe (zloop_t *loop, zsock_t *reader, void *args) * additional pointers are zeroed. * */ - int zerr = zsock_recv (reader, "s484", &command, &smio_id, &base, &inst_id); + int zerr = zsock_recv (reader, "s484s", &command, &smio_id, &base, &inst_id, + &smio_key); if (zerr == -1) { return 0; /* Malformed message */ } @@ -764,11 +754,21 @@ static int _devio_handle_pipe (zloop_t *loop, zsock_t *reader, void *args) /* Unregister all SMIOs */ _devio_unregister_all_sm_raw (devio); } - /* FIXME: Will not work, as the second parameter is a string and we expect - * something different */ else if (streq (command, "$UNREGISTER_SMIO")) { /* Unregister SMIO */ - _devio_unregister_sm_raw (devio, NULL); + _devio_unregister_sm_raw (devio, smio_key); + } + else if (streq (command, "$RECONFIGURE_SMIO_ALL")) { + /* Reconfigure all SMIOs */ + _devio_reconfigure_all_sm_raw (devio); + } + else if (streq (command, "$RECONFIGURE_SMIO")) { + /* Reconfigure SMIO */ + _devio_reconfigure_sm_raw (devio, smio_key); + } + else if (streq (command, "$RESET_LLIO")) { + /* Reset LLIO */ + _devio_reset_llio_raw (devio); } else { /* Invalid message received. Discard message and continue normally */ @@ -777,6 +777,7 @@ static int _devio_handle_pipe (zloop_t *loop, zsock_t *reader, void *args) } free (command); + free (smio_key); return 0; } @@ -903,8 +904,13 @@ static devio_err_e _devio_register_sm_raw (devio_t *self, uint32_t smio_id, uint /* Search for the SMIO */ smio_mod_handler = _devio_search_sm_by_id (self, smio_id); - ASSERT_TEST (smio_mod_handler != NULL, "Could not find specified SMIO", - err_search_smio); + if (smio_mod_handler == NULL) { + DBE_DEBUG (DBG_DEV_IO | DBG_LVL_INFO, + "[dev_io_core:register_sm] Could not find specified SMIO with id = %u\n", + smio_id); + err = DEVIO_ERR_ALLOC; + goto err_search_smio; + } /* Found! Call bootstrap code and insert in * hash table */ @@ -945,7 +951,7 @@ static devio_err_e _devio_register_sm_raw (devio_t *self, uint32_t smio_id, uint * to clear this structure after using it! */ th_boot_args_t *th_args = zmalloc (sizeof *th_args); ASSERT_ALLOC (th_args, err_th_args_alloc); - th_args->parent = self; + th_args->args = NULL; th_args->smio_handler = smio_mod_handler; th_args->pipe_msg = pipe_msg_backend; th_args->broker = self->endpoint_broker; @@ -1102,6 +1108,44 @@ static devio_err_e _devio_register_all_sm_raw (devio_t *self) smio_full_base_addr, 0, true); } +#if 0 + /* FIXME. Currently we have an issue with some SMIOs + * initialization. + * + * If the SMIOs are somewhat dependant, we might need + * to reconfigure them again once they are all up and ready. + * That's because the default configuration of some of them + * (called in smio_config_defaults) might depend on another + * SMIO initialization. + * + * Even worse, in FPGAs, some SMIOs might need an stable clock + * to be able to configure themselves, but some projects + * employ a dynamic clock configured on-thr-fly by the SMIO. + * So, some SMIOs might not even be able to initialize before + * this other SMIO configure the FPGA clock. + * + * Using a more brute-force solution we do the following: + * + * 1) We reset the endpoint here (not done here as most of + * our endpoints need to recreate its SMCH instances to be + * able to communicate and we don't do that on reconfigure, + * only on create) + * 2) Tell the SMIOs to reconfigure themselves + * */ + err = _devio_reset_llio_raw (self); + ASSERT_TEST (err == DEVIO_SUCCESS, "Could not reset LLIO endpoint", + err_reset_llio); + err = _devio_reconfigure_all_sm_raw (self); + ASSERT_TEST (err == DEVIO_SUCCESS, "Could reconfigure registered SMIOs", + err_reconfigure_smios); +#endif + + return err; + +#if 0 +err_reconfigure_smios: +err_reset_llio: +#endif err_sdb_not_supp: return err; } @@ -1137,7 +1181,8 @@ devio_err_e devio_unregister_sm (void *pipe, const char *smio_key) assert (pipe); devio_err_e err = DEVIO_SUCCESS; - int zerr = zsock_send (pipe, "ss", "$UNREGISTER_SMIO", smio_key); + /* The 484 picture is unused for this command. So, we put 0s */ + int zerr = zsock_send (pipe, "s484s", "$UNREGISTER_SMIO", 0, 0, 0, smio_key); ASSERT_TEST(zerr == 0, "Could not unregister SMIOs", err_unregister_sm, DEVIO_ERR_INV_SOCKET /* TODO: improve error handling? */); @@ -1172,6 +1217,125 @@ devio_err_e devio_unregister_all_sm (void *pipe) return err; } +devio_err_e devio_reconfigure_sm (void *pipe, const char *smio_key) +{ + assert (pipe); + devio_err_e err = DEVIO_SUCCESS; + + int zerr = zsock_send (pipe, "s484s", "$RECONFIGURE_SMIO", 0, 0, 0, + smio_key); + ASSERT_TEST(zerr == 0, "Could not reconfigure SMIO", err_reconfigure_sm, + DEVIO_ERR_INV_SOCKET /* TODO: improve error handling? */); + +err_reconfigure_sm: + return err; +} + +static devio_err_e _devio_reconfigure_sm_raw (devio_t *self, const char *smio_key) +{ + assert (self); + + devio_err_e err = DEVIO_SUCCESS; + /* Lookup SMIO reference in hash table */ + zactor_t **actor = (zactor_t **) zhashx_lookup (self->sm_io_cfg_h, smio_key); + ASSERT_TEST (actor != NULL, "Could not find SMIO CFG registered with this ID", + err_hash_lookup, DEVIO_ERR_SMIO_DESTROY); + + err = _devio_reconfigure_actor (self, actor); + ASSERT_TEST (err == DEVIO_SUCCESS, "Could not send self-destruct message to " + "PIPE management", err_send_msg, DEVIO_ERR_SMIO_DESTROY); + +err_send_msg: +err_hash_lookup: + return err; +} + +devio_err_e devio_reconfigure_all_sm (void *pipe) +{ + assert (pipe); + devio_err_e err = DEVIO_SUCCESS; + + int zerr = zsock_send (pipe, "s", "$RECONFIGURE_SMIO_ALL"); + ASSERT_TEST(zerr == 0, "Could not reconfigure all SMIOs", err_reconfigure_sm_all, + DEVIO_ERR_INV_SOCKET /* TODO: improve error handling? */); + +err_reconfigure_sm_all: + return err; +} + +static devio_err_e _devio_reconfigure_all_sm_raw (devio_t *self) +{ + assert (self); + devio_err_e err = DEVIO_SUCCESS; + + /* Get all hash keys */ + zlistx_t *hash_keys = zhashx_keys (self->sm_io_cfg_h); + ASSERT_ALLOC (hash_keys, err_hash_keys_alloc, DEVIO_ERR_ALLOC); + char *hash_item = zlistx_first (hash_keys); + + /* Iterate over all keys removing each of one */ + for (; hash_item != NULL; hash_item = zlistx_next (hash_keys)) { + err = _devio_reconfigure_sm_raw (self, hash_item); + ASSERT_TEST (err == DEVIO_SUCCESS, "Could not destroy SMIO " + "instance", err_smio_destroy, DEVIO_ERR_SMIO_DESTROY); + } + +err_smio_destroy: + zlistx_destroy (&hash_keys); +err_hash_keys_alloc: + return err; +} + +devio_err_e devio_reset_llio (void *pipe) +{ + assert (pipe); + devio_err_e err = DEVIO_SUCCESS; + + int zerr = zsock_send (pipe, "s", "$RESET_LLIO"); + ASSERT_TEST(zerr == 0, "Could not reset LLIO", err_reset_llio, + DEVIO_ERR_INV_SOCKET /* TODO: improve error handling? */); + +err_reset_llio: + return err; +} + +static devio_err_e _devio_reset_llio_raw (devio_t *self) +{ + assert (self); + devio_err_e err = DEVIO_SUCCESS; + + llio_err_e lerr = llio_reset (self->llio); + if (lerr != LLIO_SUCCESS) { + err = DEVIO_ERR_MOD_LLIO; + goto err_llio_reset; + } + + return err; +err_llio_reset: + return err; +} + +static devio_err_e _devio_check_send_cfg_done (devio_t *self) +{ + assert (self); + devio_err_e err = DEVIO_SUCCESS; + int zerr = 0; + + /* When all CFG actors exits send message to PIPE telling this */ + if (zhashx_size (self->sm_io_cfg_h) == 0) { + DBE_DEBUG (DBG_SM_IO | DBG_LVL_INFO, "[dev_io_core:_devio_check_send_cfg_done] " + "Sending $SMIO_CFG_DONE over PIPE to DEVIO loop\n"); + zerr = zstr_sendx (self->pipe, "$SMIO_CFG_DONE", NULL); + ASSERT_TEST (zerr == 0, "Could not send $SMIO_CFG_DONE over PIPE", + err_send_smio_cfg_done); + } + + return err; + +err_send_smio_cfg_done: + return err; +} + /* Main devio loop implemented as actor */ void devio_loop (zsock_t *pipe, void *args) { @@ -1435,6 +1599,23 @@ static char *_devio_gen_smio_key_auto (devio_t *self, return key; } +static devio_err_e _devio_reconfigure_actor (devio_t *self, zactor_t **actor) +{ + assert (self); + assert (actor); + assert (*actor); + + devio_err_e err = DEVIO_SUCCESS; + DBE_DEBUG (DBG_DEV_IO | DBG_LVL_INFO, "[dev_io_core] Reconfiguring actor %p\n", *actor); + + /* Resolve actor into sock_t */ + zsock_t *sock = zactor_sock (*actor); + /* Send message to actor */ + zstr_sendx (sock, "RECONFIGURE SMIO", NULL); + + return err; +} + static devio_err_e _devio_do_smio_op (devio_t *self, void *msg) { assert (self); diff --git a/core/dev_mngr/build.gradle b/core/dev_mngr/build.gradle index 75231232..9b19fdd6 100644 --- a/core/dev_mngr/build.gradle +++ b/core/dev_mngr/build.gradle @@ -4,6 +4,7 @@ model { sources { c { lib project: ':core:common', library: 'common' + lib project: ':core:revision', library: 'revision' lib project: ':core:sm_io', library: 'sm_io' lib project: ':core:sm_io_table', library: 'sm_io_table' lib project: ':foreign:libbsmp', library: 'bsmp' diff --git a/core/msg/build.gradle b/core/msg/build.gradle index abdcbe39..3b4eed7a 100644 --- a/core/msg/build.gradle +++ b/core/msg/build.gradle @@ -9,6 +9,7 @@ model { } lib project: ':core:common', library: 'common' + lib project: ':core:revision', library: 'revision' lib project: ':core:sm_io', library: 'sm_io' lib project: ':core:sm_io_table', library: 'sm_io_table' lib project: ':foreign:libbsmp', library: 'bsmp' diff --git a/core/msg/src/msg/c/msg.c b/core/msg/src/msg/c/msg.c index 675ef91a..025d755b 100644 --- a/core/msg/src/msg/c/msg.c +++ b/core/msg/src/msg/c/msg.c @@ -186,7 +186,8 @@ msg_err_e msg_check_gen_zmq_args (const disp_op_t *disp_op, zmsg_t *zmq_msg) GEN_MSG_ZMQ_ARG_SIZE(zmq_arg) != DISP_GET_ASIZE(*args_it))) { DBE_DEBUG (DBG_MSG | DBG_LVL_ERR, "[msg] Invalid size of argument #%u" - " received for function \"%s\"\n", i, disp_op->name); + " received for function \"%s\". Expected %u, got %zu\n", + i, disp_op->name, DISP_GET_ASIZE(*args_it), GEN_MSG_ZMQ_ARG_SIZE(zmq_arg)); err = MSG_ERR_INV_SIZE_ARG; goto err_inv_size_args; } diff --git a/core/msg/src/msg/c/smio_thsafe_ops/smio_thsafe_zmq_client.c b/core/msg/src/msg/c/smio_thsafe_ops/smio_thsafe_zmq_client.c index 146e121b..ad7e07c9 100644 --- a/core/msg/src/msg/c/smio_thsafe_ops/smio_thsafe_zmq_client.c +++ b/core/msg/src/msg/c/smio_thsafe_ops/smio_thsafe_zmq_client.c @@ -30,6 +30,8 @@ CHECK_HAL_ERR(err, MSG, "[smio_thsafe_client:zmq]", \ msg_err_str (err_type)) +#define SMIO_THSAFE_MSG_POLLER_TIMEOUT 5000 /* ms */ + static zmsg_t *_thsafe_zmq_client_recv_confirmation (smio_t *self); int _thsafe_zmq_client_open_release (smio_t *self, llio_endpoint_t *endpoint, uint32_t opcode); static ssize_t _thsafe_zmq_client_read_generic (smio_t *self, uint64_t offs, uint8_t *data, @@ -448,11 +450,19 @@ static zmsg_t *_thsafe_zmq_client_recv_confirmation (smio_t *self) DBE_DEBUG (DBG_MSG | DBG_LVL_TRACE, "[smio_thsafe_client:zmq] Calling _thsafe_zmq_client_recv_confirmation\n"); assert (self); - zsock_t *pipe_msg = smio_get_pipe_msg (self); - ASSERT_TEST(pipe_msg != NULL, "Could not get SMIO PIPE MSG", - err_get_pipe_msg); + zpoller_t *poller = smio_get_poller (self); + ASSERT_TEST(poller != NULL, "Could not get SMIO Poller", + err_get_poller); + /* Wait for response */ - zmsg_t *recv_msg = zmsg_recv (pipe_msg); + void *sock = zpoller_wait (poller, SMIO_THSAFE_MSG_POLLER_TIMEOUT); + ASSERT_TEST(sock != NULL, "Could not wait on SMIO poller. Interrupted or expired", + err_poller_wait); + + /* With activiy on socker, just receive the message */ + zmsg_t *recv_msg = zmsg_recv (sock); + ASSERT_TEST(recv_msg != NULL, "Could not receive PIPE message. Interrupted", + err_get_recv_msg); /* Do not pop the message, just set a cursor to it */ zframe_t *reply_frame = zmsg_first (recv_msg); @@ -486,7 +496,9 @@ static zmsg_t *_thsafe_zmq_client_recv_confirmation (smio_t *self) err_null_raw_data: err_recv_data: zmsg_destroy (&recv_msg); -err_get_pipe_msg: +err_get_recv_msg: +err_poller_wait: +err_get_poller: return NULL; } diff --git a/core/msg/src/msg/c/smio_thsafe_ops/smio_thsafe_zmq_server.c b/core/msg/src/msg/c/smio_thsafe_ops/smio_thsafe_zmq_server.c index d7bc67a9..acf960a3 100644 --- a/core/msg/src/msg/c/smio_thsafe_ops/smio_thsafe_zmq_server.c +++ b/core/msg/src/msg/c/smio_thsafe_ops/smio_thsafe_zmq_server.c @@ -318,7 +318,7 @@ disp_op_t thsafe_zmq_server_read_block_exp = { .name = THSAFE_NAME_READ_BLOCK, .opcode = THSAFE_OPCODE_READ_BLOCK, .func_fp = _thsafe_zmq_server_read_block, - .retval = DISP_ARG_ENCODE_RAW(DISP_ATYPE_STRUCT, + .retval = DISP_ARG_ENCODE_RAW(DISP_ATYPE_VAR, sizeof(zmq_server_data_block_t) + ZMQ_SERVER_BLOCK_SIZE), .retval_owner = DISP_OWNER_OTHER, .args = { @@ -343,7 +343,7 @@ disp_op_t thsafe_zmq_server_write_block_exp = { .retval_owner = DISP_OWNER_OTHER, .args = { DISP_ARG_ENCODE(DISP_ATYPE_UINT64, uint64_t), - DISP_ARG_ENCODE_RAW(DISP_ATYPE_STRUCT, + DISP_ARG_ENCODE_RAW(DISP_ATYPE_VAR, sizeof(zmq_server_data_block_t) + ZMQ_SERVER_BLOCK_SIZE), DISP_ARG_END } @@ -360,7 +360,7 @@ disp_op_t thsafe_zmq_server_read_dma_exp = { .name = THSAFE_NAME_READ_DMA, .opcode = THSAFE_OPCODE_READ_DMA, .func_fp = _thsafe_zmq_server_read_dma, - .retval = DISP_ARG_ENCODE_RAW(DISP_ATYPE_STRUCT, + .retval = DISP_ARG_ENCODE_RAW(DISP_ATYPE_VAR, sizeof(zmq_server_data_block_t) + ZMQ_SERVER_BLOCK_SIZE), .retval_owner = DISP_OWNER_OTHER, .args = { @@ -385,7 +385,7 @@ disp_op_t thsafe_zmq_server_write_dma_exp = { .retval_owner = DISP_OWNER_OTHER, .args = { DISP_ARG_ENCODE(DISP_ATYPE_UINT64, uint64_t), - DISP_ARG_ENCODE_RAW(DISP_ATYPE_STRUCT, + DISP_ARG_ENCODE_RAW(DISP_ATYPE_VAR, sizeof(zmq_server_data_block_t) + ZMQ_SERVER_BLOCK_SIZE), DISP_ARG_END } diff --git a/core/revision/build.gradle b/core/revision/build.gradle index 109e5fad..839687b6 100644 --- a/core/revision/build.gradle +++ b/core/revision/build.gradle @@ -1,10 +1,11 @@ import org.ajoberstar.gradle.git.release.opinion.Strategies -plugins { - id 'org.ajoberstar.grgit' version '1.6.0' - id 'org.ajoberstar.release-opinion' version '1.6.0' -} +import br.lnls.dig.gradle.updatesemvermacrostask.UpdateSemVerMacrosTask +apply plugin: 'org.ajoberstar.grgit' +apply plugin: 'org.ajoberstar.release-opinion' +apply plugin: br.lnls.dig.gradle.nativedistribution.plugins.NativeDistributionPlugin +apply plugin: 'br.lnls.dig.gradle.nativerelease' apply plugin: com.janitovff.grgit.config.GitConfigPlugin model { @@ -12,6 +13,8 @@ model { revision(NativeLibrarySpec) { sources { c { + exportedHeaders.srcDir 'include' + lib project: ':libs:convc', library: 'convc' lib project: ':libs:errhand', library: 'errhand' lib project: ':libs:hutils', library: 'hutils' @@ -34,3 +37,8 @@ release { allowDirtyRepo: true ) } + +task updateVersionMacros(type: UpdateSemVerMacrosTask) { + macroPrefix 'HALCS_VERSION_' + file project.file('include/revision.h') +} diff --git a/core/common/include/revision.h b/core/revision/include/revision.h similarity index 79% rename from core/common/include/revision.h rename to core/revision/include/revision.h index 3796b6f1..57fc366f 100644 --- a/core/common/include/revision.h +++ b/core/revision/include/revision.h @@ -1,12 +1,27 @@ /* - * Copyright (C) 2015 LNLS (www.lnls.br) - * Author: Lucas Russo + * Copyright (C) 2017 LNLS (www.lnls.br) + * Authors: Lucas Russo + * Janito Vaqueiro Ferreira Filho * * Released according to the GNU GPL, version 3 or any later version. */ -#ifndef _REVISION_ -#define _REVISION_ +#ifndef _REVISION_H_ +#define _REVISION_H_ + +#include + +/* HALCS version macros for compile-time API detection */ + +#define HALCS_VERSION_MAJOR 0 +#define HALCS_VERSION_MINOR 5 +#define HALCS_VERSION_PATCH 1 + +#define HALCS_MAKE_VERSION(major, minor, patch) \ + ((major) * 10000 + (minor) * 100 + (patch)) +#define HALCS_VERSION \ + HALCS_MAKE_VERSION(HALCS_VERSION_MAJOR, HALCS_VERSION_MINOR, \ + HALCS_VERSION_PATCH) #ifdef __cplusplus extern "C" { diff --git a/core/revision/src/revision/c/revision.c b/core/revision/src/revision/c/revision.c index 669461c5..d60f5bd9 100644 --- a/core/revision/src/revision/c/revision.c +++ b/core/revision/src/revision/c/revision.c @@ -5,6 +5,7 @@ * Released according to the GNU GPL, version 3 or any later version. */ +#include "revision.h" #include "hutils.h" #define HALCS_VERSION_MAJOR_STR STRINGIFY(HALCS_VERSION_MAJOR) diff --git a/core/sm_io/build.gradle b/core/sm_io/build.gradle index cd670f17..70318f2e 100644 --- a/core/sm_io/build.gradle +++ b/core/sm_io/build.gradle @@ -21,6 +21,7 @@ model { lib project: ':core:boards:afcv3_1', library: 'afcv3_1' lib project: ':core:boards:ml605', library: 'ml605' lib project: ':core:common', library: 'common', linkage: 'api' + lib project: ':core:revision', library: 'revision' lib project: ':core:sm_io_table', library: 'sm_io_table' lib project: ':foreign:libbsmp', library: 'bsmp' lib project: ':foreign:libsdbfs', library: 'sdbfs' diff --git a/core/sm_io/include/sm_io_fmc250m_4ch_codes.h b/core/sm_io/include/sm_io_fmc250m_4ch_codes.h index b9e6ea5b..d331bd8a 100644 --- a/core/sm_io/include/sm_io_fmc250m_4ch_codes.h +++ b/core/sm_io/include/sm_io_fmc250m_4ch_codes.h @@ -78,7 +78,9 @@ #define FMC250M_4CH_NAME_REG "fmc250m_4ch_reg" #define FMC250M_4CH_OPCODE_TEMP 52 #define FMC250M_4CH_NAME_TEMP "fmc250m_4ch_temp" -#define FMC250M_4CH_OPCODE_END 53 +#define FMC250M_4CH_OPCODE_CAL_STATUS 53 +#define FMC250M_4CH_NAME_CAL_STATUS "fmc250m_4ch_cal_status" +#define FMC250M_4CH_OPCODE_END 54 /* Messaging Reply OPCODES */ #define FMC250M_4CH_REPLY_TYPE uint32_t diff --git a/core/sm_io/include/sm_io_fmc_active_clk_codes.h b/core/sm_io/include/sm_io_fmc_active_clk_codes.h index ba6fcb4b..792ac661 100644 --- a/core/sm_io/include/sm_io_fmc_active_clk_codes.h +++ b/core/sm_io/include/sm_io_fmc_active_clk_codes.h @@ -46,9 +46,11 @@ #define FMC_ACTIVE_CLK_NAME_SI571_GET_DEFAULTS "fmc_active_clk_si571_get_defaults" #define FMC_ACTIVE_CLK_OPCODE_RST_ISLA216P 16 #define FMC_ACTIVE_CLK_NAME_RST_ISLA216P "fmc_active_clk_rst_isla216p" -#define FMC_ACTIVE_CLK_OPCODE_AD9510_DATA 17 +#define FMC_ACTIVE_CLK_OPCODE_RST_SWAP 17 +#define FMC_ACTIVE_CLK_NAME_RST_SWAP "fmc_active_clk_rst_swap" +#define FMC_ACTIVE_CLK_OPCODE_AD9510_DATA 18 #define FMC_ACTIVE_CLK_NAME_AD9510_DATA "fmc130m_4ch_ad9510_data" -#define FMC_ACTIVE_CLK_OPCODE_END 18 +#define FMC_ACTIVE_CLK_OPCODE_END 19 /* Messaging Reply OPCODES */ #define FMC_ACTIVE_CLK_REPLY_TYPE uint32_t diff --git a/core/sm_io/include/sm_io_init_codes.h b/core/sm_io/include/sm_io_init_codes.h new file mode 100644 index 00000000..d8ab1106 --- /dev/null +++ b/core/sm_io/include/sm_io_init_codes.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2017 LNLS (www.lnls.br) + * Author: Lucas Russo + * + * Released according to the GNU GPL, version 3 or any later version. + */ + +#ifndef _SM_IO_INIT_CODES_H_ +#define _SM_IO_INIT_CODES_H_ + +/* Messaging OPCODES */ +#define INIT_OPCODE_TYPE uint32_t +#define INIT_OPCODE_SIZE (sizeof (INIT_OPCODE_TYPE)) + +#define INIT_OPCODE_SET_GET_CHECK 0 +#define INIT_NAME_SET_GET_CHECK "check" +#define INIT_OPCODE_END 1 + +/* Messaging Reply OPCODES */ +#define INIT_REPLY_TYPE uint32_t +#define INIT_REPLY_SIZE (sizeof (INIT_REPLY_TYPE)) + +#define INIT_OK 0 /* Operation was successful */ +#define INIT_ERR 1 /* Generic error */ + +#endif diff --git a/core/sm_io/sm_io.mk b/core/sm_io/sm_io.mk index 464a34e9..ddc83c8c 100644 --- a/core/sm_io/sm_io.mk +++ b/core/sm_io/sm_io.mk @@ -6,6 +6,7 @@ include $(sm_io_DIR)/protocols/protocols.mk include $(sm_io_DIR)/chips/chips.mk sm_io_OBJS = $(sm_io_DIR)/sm_io.o \ + $(sm_io_DIR)/sm_io_cfg.o \ $(sm_io_DIR)/sm_io_bootstrap.o \ $(sm_io_DIR)/sm_io_err.o \ $(sm_io_modules_OBJS) \ diff --git a/core/sm_io/src/sm_io/c/chips/sm_ch_isla216p.c b/core/sm_io/src/sm_io/c/chips/sm_ch_isla216p.c index 8351c290..62b6a9ae 100644 --- a/core/sm_io/src/sm_io/c/chips/sm_ch_isla216p.c +++ b/core/sm_io/src/sm_io/c/chips/sm_ch_isla216p.c @@ -164,6 +164,24 @@ smch_err_e smch_isla216p_get_chipver (smch_isla216p_t *self, uint8_t *chipver) return err; } +smch_err_e smch_isla216p_get_cal_status (smch_isla216p_t *self, uint8_t *cal_status) +{ + uint8_t __cal_status = 0; + smch_err_e err = SMCH_SUCCESS; + ssize_t rw_err = -1; + + rw_err = _smch_isla216p_read_8 (self, ISLA216P_REG_CALSTATUS, &__cal_status); + ASSERT_TEST(rw_err == sizeof(uint8_t), "Could not read from CAL_STATUS register", + err_smpr_read, SMCH_ERR_RW_SMPR); + + SMCH_ISLA216P_WAIT_DFLT; + + *cal_status = __cal_status & ISLA216P_CALCSTATUS_CALCDONE; + +err_smpr_read: + return err; +} + smch_err_e smch_isla216p_set_rst (smch_isla216p_t *self, uint8_t rst_operation) { smch_err_e err = SMCH_SUCCESS; @@ -222,16 +240,14 @@ smch_err_e smch_isla216p_get_temp (smch_isla216p_t *self, uint16_t *temp) ssize_t rw_err = -1; uint8_t data = 0; - /* Reset counter */ -#if 0 - data = ISLA216P_TEMP_CTL_RESET; - rw_err = _smch_isla216p_write_8 (self, ISLA216P_REG_TEMP_CTL, &data); - ASSERT_TEST(rw_err == sizeof(uint8_t), "Could not reset temperature counter", - err_smpr_write, SMCH_ERR_RW_SMPR); -#endif - uint32_t i = 0; for (i = 0; i < SMCH_ISLA216P_WAIT_TRIES; ++i) { + + data = ISLA216P_TEMP_CTL_RESET; + rw_err = _smch_isla216p_write_8 (self, ISLA216P_REG_TEMP_CTL, &data); + ASSERT_TEST(rw_err == sizeof(uint8_t), "Could not reset temperature counter", + err_smpr_write, SMCH_ERR_RW_SMPR); + /* As per ISLA216P25 datasheet, page 28 */ data = (ISLA216P_TEMP_CTL_PTAT_MODE_EN | ISLA216P_TEMP_CTL_ENABLE | @@ -263,8 +279,10 @@ smch_err_e smch_isla216p_get_temp (smch_isla216p_t *self, uint16_t *temp) } } - ASSERT_TEST((i < SMCH_ISLA216P_WAIT_TRIES), "Could not read valid temperature counter", - err_smpr_write, SMCH_ERR_RW_SMPR); + if (i >= SMCH_ISLA216P_WAIT_TRIES) { + err = SMCH_ERR_RW_SMPR; + goto err_smpr_write; + } /* Power-down temperature counter again, as per ISLA216P datahsheet */ data = ISLA216P_TEMP_CTL_PD; diff --git a/core/sm_io/src/sm_io/c/chips/sm_ch_si57x.c b/core/sm_io/src/sm_io/c/chips/sm_ch_si57x.c index b64638f0..6cac68c2 100644 --- a/core/sm_io/src/sm_io/c/chips/sm_ch_si57x.c +++ b/core/sm_io/src/sm_io/c/chips/sm_ch_si57x.c @@ -169,7 +169,7 @@ smch_err_e smch_si57x_set_freq (smch_si57x_t *self, double *freq) smch_err_e err = SMCH_SUCCESS; double frequency = *freq; - ASSERT_TEST(frequency > 0, "Invalid frequency (0 Hz)", err_exit); + ASSERT_TEST(frequency > 1.0, "Invalid frequency (<= 1 Hz)", err_exit); DBE_DEBUG (DBG_SM_CH | DBG_LVL_TRACE, "[sm_ch:si57x_set_freq] Configuring " "frequency to %f Hz\n", frequency); diff --git a/core/sm_io/src/sm_io/c/modules/acq/sm_io_acq_core.c b/core/sm_io/src/sm_io/c/modules/acq/sm_io_acq_core.c index 3c3f895d..6a8d326b 100644 --- a/core/sm_io/src/sm_io/c/modules/acq/sm_io_acq_core.c +++ b/core/sm_io/src/sm_io/c/modules/acq/sm_io_acq_core.c @@ -78,6 +78,11 @@ smio_acq_t * smio_acq_new (smio_t *parent, uint32_t num_samples_pre, ACQ_CORE_CHAN_DESC_OFFSET, i, MULT_BIT_PARAM, atom_width, NO_FMT_FUNC); + ASSERT_TEST(int_ch_width > 0, "Invalid int_ch_width property", err_int_ch_width); + ASSERT_TEST(num_coalesce > 0, "Invalid num_coalesce property", err_num_coalesce); + ASSERT_TEST(num_atoms > 0, "Invalid num_atoms property", err_num_atoms); + ASSERT_TEST(atom_width > 0, "Invalid atom_width property", err_atom_width); + /* These are exported to clients so they know how to split the array */ UNUSED(num_atoms); UNUSED(atom_width); @@ -131,7 +136,11 @@ smio_acq_t * smio_acq_new (smio_t *parent, uint32_t num_samples_pre, return self; +err_atom_width: +err_num_atoms: +err_num_coalesce: err_acq_buf_alloc: +err_int_ch_width: free (self); err_self_alloc: return NULL; diff --git a/core/sm_io/src/sm_io/c/modules/acq/sm_io_acq_exp.c b/core/sm_io/src/sm_io/c/modules/acq/sm_io_acq_exp.c index 6ff688ce..552f8dce 100644 --- a/core/sm_io/src/sm_io/c/modules/acq/sm_io_acq_exp.c +++ b/core/sm_io/src/sm_io/c/modules/acq/sm_io_acq_exp.c @@ -62,7 +62,7 @@ static int _acq_get_trigger_type (SMIO_OWNER_TYPE *self, uint32_t *trigger_type) static uint64_t _acq_get_start_address (uint64_t acq_core_trig_addr, uint64_t acq_size_bytes, uint64_t start_mem_space_addr, uint64_t end_mem_space_addr); -static uint64_t _acq_get_read_block_addr (uint64_t start_addr, uint64_t offset, +static uint64_t _acq_get_read_block_addr_start (uint64_t start_addr, uint64_t offset, uint64_t channel_start_addr, uint64_t end_mem_space_addr); /************************************************************/ @@ -161,14 +161,16 @@ static int _acq_data_acquire (void *owner, void *args, void *ret) /* FIXME FPGA Firmware requires number of samples to be divisible by * acquisition channel sample size */ + uint32_t channel_sample_size = acq->acq_buf[chan].sample_size; uint32_t samples_alignment = - DDR3_PAYLOAD_SIZE/acq->acq_buf[chan].sample_size; + DDR3_PAYLOAD_SIZE/channel_sample_size; uint32_t num_samples_pre_aligned = hutils_align_value (num_samples_pre, samples_alignment); /* FIXME. Curently, the FPGA gateware does not support triggered acquisitions with - * post_samples = 0. See github lnls-bpm/bpm-gw#62 */ + * post_samples = 0. There must be at more than DDR3_PAYLOAD_SIZE bytes in post_samples. + * See github lnls-bpm/bpm-gw#62 */ uint32_t num_samples_post_aligned = (num_samples_post == 0 && trigger_type != TYPE_ACQ_CORE_SKIP) ? - samples_alignment : hutils_align_value (num_samples_post, samples_alignment); + samples_alignment*channel_sample_size + 1 : hutils_align_value (num_samples_post, samples_alignment); /* Set the parameters: number of samples of this channel */ acq->acq_params[chan].num_samples_pre = num_samples_pre_aligned; @@ -299,10 +301,11 @@ static int _acq_get_data_block (void *owner, void *args, void *ret) DBE_DEBUG (DBG_SM_IO | DBG_LVL_TRACE, "[sm_io:acq] " "Calling _acq_get_data_block\n"); + int err = -ACQ_OK; SMIO_OWNER_TYPE *self = SMIO_EXP_OWNER(owner); smio_acq_t *acq = smio_get_handler (self); ASSERT_TEST(acq != NULL, "Could not get SMIO ACQ handler", - err_get_acq_handler); + err_get_acq_handler, -ACQ_ERR); /* Message is: * frame 0: channel @@ -384,17 +387,17 @@ static int _acq_get_data_block (void *owner, void *args, void *ret) return -ACQ_BLOCK_OOR; } /* Last valid data conditions check done */ - uint32_t reply_size; + uint32_t reply_size_full; if (block_n == block_n_valid && over_samples > 0){ - reply_size = over_samples*channel_sample_size; + reply_size_full = over_samples*channel_sample_size; } else { /* if block_n < block_n_valid */ - reply_size = BLOCK_SIZE; + reply_size_full = BLOCK_SIZE; } DBE_DEBUG (DBG_SM_IO | DBG_LVL_TRACE, "[sm_io:acq] get_data_block: " "Reading block %u of channel %u with %u valid samples\n", - block_n, chan, reply_size); + block_n, chan, reply_size_full); /* For all modes the start valid address is given by: * start_addr = trigger_addr - @@ -421,7 +424,7 @@ static int _acq_get_data_block (void *owner, void *args, void *ret) /* Forth step is to calculate the offset from the start_addr, taking care * for wraps in the end of the current memory space */ - uint64_t addr_i = _acq_get_read_block_addr (start_addr, block_n * BLOCK_SIZE, + uint64_t addr_i = _acq_get_read_block_addr_start (start_addr, block_n * BLOCK_SIZE, channel_start_addr, end_mem_space_addr); DBE_DEBUG (DBG_SM_IO | DBG_LVL_TRACE, "[sm_io:acq] get_data_block:\n" "\tBlock %u of channel %u:\n" @@ -439,33 +442,58 @@ static int _acq_get_data_block (void *owner, void *args, void *ret) smio_acq_data_block_t *data_block = (smio_acq_data_block_t *) ret; - /* Here we must use the "raw" version, as we can't have - * LARGE_MEM_ADDR mangled with the bas address of this SMIO */ - ssize_t valid_bytes = smio_thsafe_raw_client_read_dma (self, LARGE_MEM_ADDR | addr_i, - reply_size, (uint32_t *) data_block->data); - /* Try reading block-by-block if DMA fails for some reason */ - if (valid_bytes < 0) { - valid_bytes = smio_thsafe_raw_client_read_block (self, LARGE_MEM_ADDR | addr_i, - reply_size, (uint32_t *) data_block->data); + uint32_t num_bytes_read = 0; + ssize_t valid_bytes = 0; + uint64_t addr_start = addr_i; + uint64_t rem_mem_space = end_mem_space_addr - addr_start; + for ( ; + num_bytes_read < reply_size_full; + num_bytes_read += valid_bytes) { + uint32_t bytes_to_read = (reply_size_full-num_bytes_read > rem_mem_space)? + rem_mem_space : reply_size_full-num_bytes_read; + + DBE_DEBUG (DBG_SM_IO | DBG_LVL_TRACE, "[sm_io:acq] get_data_block: " + "Reading %u bytes from address 0x%"PRIx64"\n" + "\twith remaining memory space 0x%"PRIx64"\n" + "\twith end memory space 0x%08X\n", + bytes_to_read, addr_start, + rem_mem_space, + end_mem_space_addr); + + /* Here we must use the "raw" version, as we can't have + * LARGE_MEM_ADDR mangled with the bas address of this SMIO */ + valid_bytes = smio_thsafe_raw_client_read_dma (self, LARGE_MEM_ADDR | addr_start, + bytes_to_read, (uint32_t *)((uint8_t *) data_block->data + num_bytes_read)); + /* Try reading block-by-block if DMA fails for some reason */ + if (valid_bytes < 0) { + valid_bytes = smio_thsafe_raw_client_read_block (self, LARGE_MEM_ADDR | addr_start, + bytes_to_read, (uint32_t *)((uint8_t *) data_block->data + num_bytes_read)); + } + + ASSERT_TEST(valid_bytes == bytes_to_read, "Could not read data block completely", + err_read_data_block, -ACQ_COULD_NOT_READ); + addr_start += valid_bytes; + if (addr_start >= end_mem_space_addr) { + addr_start = channel_start_addr; + } + + rem_mem_space = end_mem_space_addr - addr_start; } + DBE_DEBUG (DBG_SM_IO | DBG_LVL_TRACE, "[sm_io:acq] get_data_block: " - "%zd bytes read\n", valid_bytes); + "%u bytes read\n", num_bytes_read); /* Check if we could read successfully */ int retf = 0; - if (valid_bytes >= 0) { - data_block->valid_bytes = (uint32_t) valid_bytes; - retf = valid_bytes + (ssize_t) sizeof (data_block->valid_bytes); - } - else { - data_block->valid_bytes = 0; - retf = -ACQ_COULD_NOT_READ; - } + data_block->valid_bytes = (uint32_t) num_bytes_read; + retf = num_bytes_read + (ssize_t) sizeof (data_block->valid_bytes); return retf; +err_read_data_block: + data_block->valid_bytes = 0; err_get_acq_handler: - return -ACQ_ERR; + return err; } static uint64_t _acq_get_start_address (uint64_t acq_core_trig_addr, @@ -487,7 +515,7 @@ static uint64_t _acq_get_start_address (uint64_t acq_core_trig_addr, return addr; } -static uint64_t _acq_get_read_block_addr (uint64_t start_addr, uint64_t offset, +static uint64_t _acq_get_read_block_addr_start (uint64_t start_addr, uint64_t offset, uint64_t channel_start_addr, uint64_t end_mem_space_addr) { uint64_t addr = 0; @@ -867,10 +895,10 @@ const disp_table_func_fp acq_exp_fp [] = { static smio_err_e _acq_do_op (void *owner, void *msg); /* Attach an instance of sm_io to dev_io function pointer */ -smio_err_e acq_attach (smio_t *self, devio_t *parent) +smio_err_e acq_attach (smio_t *self, void *args) { UNUSED(self); - UNUSED(parent); + UNUSED(args); return SMIO_ERR_FUNC_NOT_IMPL; } diff --git a/core/sm_io/src/sm_io/c/modules/acq_pm/sm_io_acq_pm_exp.c b/core/sm_io/src/sm_io/c/modules/acq_pm/sm_io_acq_pm_exp.c index b765a711..2ca0ee2d 100644 --- a/core/sm_io/src/sm_io/c/modules/acq_pm/sm_io_acq_pm_exp.c +++ b/core/sm_io/src/sm_io/c/modules/acq_pm/sm_io_acq_pm_exp.c @@ -51,10 +51,10 @@ const disp_table_func_fp acq_pm_exp_fp [] = { static smio_err_e _acq_pm_do_op (void *owner, void *msg); /* Attach an instance of sm_io to dev_io function pointer */ -smio_err_e acq_pm_attach (smio_t *self, devio_t *parent) +smio_err_e acq_pm_attach (smio_t *self, void *args) { UNUSED(self); - UNUSED(parent); + UNUSED(args); return SMIO_ERR_FUNC_NOT_IMPL; } diff --git a/core/sm_io/src/sm_io/c/modules/afc_diag/sm_io_afc_diag_exp.c b/core/sm_io/src/sm_io/c/modules/afc_diag/sm_io_afc_diag_exp.c index 2fcce8a6..ee989f1a 100644 --- a/core/sm_io/src/sm_io/c/modules/afc_diag/sm_io_afc_diag_exp.c +++ b/core/sm_io/src/sm_io/c/modules/afc_diag/sm_io_afc_diag_exp.c @@ -148,10 +148,10 @@ const disp_table_func_fp afc_diag_exp_fp [] = { static smio_err_e _afc_diag_do_op (void *owner, void *msg); /* Attach an instance of sm_io to dev_io function pointer */ -smio_err_e afc_diag_attach (smio_t *self, devio_t *parent) +smio_err_e afc_diag_attach (smio_t *self, void *args) { UNUSED(self); - UNUSED(parent); + UNUSED(args); return SMIO_ERR_FUNC_NOT_IMPL; } diff --git a/core/sm_io/src/sm_io/c/modules/afc_timing/sm_io_afc_timing_exp.c b/core/sm_io/src/sm_io/c/modules/afc_timing/sm_io_afc_timing_exp.c index d3dc5889..6f89c876 100644 --- a/core/sm_io/src/sm_io/c/modules/afc_timing/sm_io_afc_timing_exp.c +++ b/core/sm_io/src/sm_io/c/modules/afc_timing/sm_io_afc_timing_exp.c @@ -386,10 +386,10 @@ const disp_table_func_fp afc_timing_exp_fp [] = { static smio_err_e _afc_timing_do_op (void *owner, void *msg); /* Attach an instance of sm_io to dev_io function pointer */ -smio_err_e afc_timing_attach (smio_t *self, devio_t *parent) +smio_err_e afc_timing_attach (smio_t *self, void *args) { UNUSED(self); - UNUSED(parent); + UNUSED(args); return SMIO_ERR_FUNC_NOT_IMPL; } diff --git a/core/sm_io/src/sm_io/c/modules/dsp/sm_io_dsp_exp.c b/core/sm_io/src/sm_io/c/modules/dsp/sm_io_dsp_exp.c index f503d3b3..d01e5f10 100644 --- a/core/sm_io/src/sm_io/c/modules/dsp/sm_io_dsp_exp.c +++ b/core/sm_io/src/sm_io/c/modules/dsp/sm_io_dsp_exp.c @@ -209,10 +209,10 @@ const disp_table_func_fp dsp_exp_fp [] = { static smio_err_e _dsp_do_op (void *owner, void *msg); /* Attach an instance of sm_io to dev_io function pointer */ -smio_err_e dsp_attach (smio_t *self, devio_t *parent) +smio_err_e dsp_attach (smio_t *self, void *args) { UNUSED(self); - UNUSED(parent); + UNUSED(args); return SMIO_ERR_FUNC_NOT_IMPL; } diff --git a/core/sm_io/src/sm_io/c/modules/fmc130m_4ch/sm_io_fmc130m_4ch_exp.c b/core/sm_io/src/sm_io/c/modules/fmc130m_4ch/sm_io_fmc130m_4ch_exp.c index 54930864..e72a5a88 100644 --- a/core/sm_io/src/sm_io/c/modules/fmc130m_4ch/sm_io_fmc130m_4ch_exp.c +++ b/core/sm_io/src/sm_io/c/modules/fmc130m_4ch/sm_io_fmc130m_4ch_exp.c @@ -506,10 +506,10 @@ const disp_table_func_fp fmc130m_4ch_exp_fp [] = { static smio_err_e _fmc130m_4ch_do_op (void *owner, void *msg); /* Attach an instance of sm_io to dev_io function pointer */ -smio_err_e fmc130m_4ch_attach (smio_t *self, devio_t *parent) +smio_err_e fmc130m_4ch_attach (smio_t *self, void *args) { UNUSED(self); - UNUSED(parent); + UNUSED(args); return SMIO_ERR_FUNC_NOT_IMPL; } diff --git a/core/sm_io/src/sm_io/c/modules/fmc250m_4ch/sm_io_fmc250m_4ch_defaults.c b/core/sm_io/src/sm_io/c/modules/fmc250m_4ch/sm_io_fmc250m_4ch_defaults.c index bff00d19..a647344e 100644 --- a/core/sm_io/src/sm_io/c/modules/fmc250m_4ch/sm_io_fmc250m_4ch_defaults.c +++ b/core/sm_io/src/sm_io/c/modules/fmc250m_4ch/sm_io_fmc250m_4ch_defaults.c @@ -72,6 +72,13 @@ smio_err_e fmc250m_4ch_config_defaults (char *broker_endp, char *service, log_file_name, SMIO_FMC250M_4CH_LIBHALCSCLIENT_LOG_MODE); ASSERT_ALLOC(config_client, err_alloc_client); + uint32_t i = 0; + for (i = 0; i < NUM_FMC250M_4CH_ISLA216P; ++i) { + client_err = halcs_set_rst_modes_adc (config_client, service, i, FMC250M_4CH_PINCTRL_RST_MODE_ADC); + ASSERT_TEST(client_err == HALCS_CLIENT_SUCCESS, "Could not set ADCs to PIN Control", + err_param_set, SMIO_ERR_CONFIG_DFLT); + } + client_err = halcs_set_rst_adcs (config_client, service, FMC250M_4CH_DFLT_RST_ADCS); ASSERT_TEST(client_err == HALCS_CLIENT_SUCCESS, "Could not reset ADCs", err_param_set, SMIO_ERR_CONFIG_DFLT); @@ -88,10 +95,13 @@ smio_err_e fmc250m_4ch_config_defaults (char *broker_endp, char *service, * After resetting the ADCs with halcs_set_rst_adcs (), all of its functions are * reset, even SPI mode. So, we need to restore the 4-wire mode with halcs_set_portconfig_adc () */ - uint32_t i = 0; for (i = 0; i < NUM_FMC250M_4CH_ISLA216P; ++i) { client_err = halcs_set_rst_modes_adc (config_client, service, i, FMC250M_4CH_DFLT_RST_MODE_ADC); client_err |= halcs_set_portconfig_adc (config_client, service, i, FMC250M_4CH_DFLT_PORTCONFIG_ADC); + usleep (1000); + client_err |= halcs_set_portconfig_adc (config_client, service, i, FMC250M_4CH_DFLT_RESET_ADC); + usleep (1000); + client_err |= halcs_set_portconfig_adc (config_client, service, i, FMC250M_4CH_DFLT_PORTCONFIG_ADC); ASSERT_TEST(client_err == HALCS_CLIENT_SUCCESS, "Could set ADCs to default parameters", err_param_set, SMIO_ERR_CONFIG_DFLT); } diff --git a/core/sm_io/src/sm_io/c/modules/fmc250m_4ch/sm_io_fmc250m_4ch_defaults.h b/core/sm_io/src/sm_io/c/modules/fmc250m_4ch/sm_io_fmc250m_4ch_defaults.h index f14a7498..68b862b8 100644 --- a/core/sm_io/src/sm_io/c/modules/fmc250m_4ch/sm_io_fmc250m_4ch_defaults.h +++ b/core/sm_io/src/sm_io/c/modules/fmc250m_4ch/sm_io_fmc250m_4ch_defaults.h @@ -19,6 +19,7 @@ #define FMC250M_4CH_DFLT_RST_MODE_ADC (ISLA216P_NAPSLP_NORMAL_OPERATION) #define FMC250M_4CH_PINCTRL_RST_MODE_ADC (ISLA216P_NAPSLP_PIN_CONTROL) #define FMC250M_4CH_DFLT_PORTCONFIG_ADC (ISLA216P_PORTCONFIG_SDO_ACTIVE) +#define FMC250M_4CH_DFLT_RESET_ADC (ISLA216P_PORTCONFIG_SDO_ACTIVE | ISLA216P_PORTCONFIG_SOFT_RESET) smio_err_e fmc250m_4ch_config_defaults (char *broker_endp, char *service, const char *log_file_name); diff --git a/core/sm_io/src/sm_io/c/modules/fmc250m_4ch/sm_io_fmc250m_4ch_exp.c b/core/sm_io/src/sm_io/c/modules/fmc250m_4ch/sm_io_fmc250m_4ch_exp.c index 0e202ba7..32ce466e 100644 --- a/core/sm_io/src/sm_io/c/modules/fmc250m_4ch/sm_io_fmc250m_4ch_exp.c +++ b/core/sm_io/src/sm_io/c/modules/fmc250m_4ch/sm_io_fmc250m_4ch_exp.c @@ -664,6 +664,19 @@ FMC250M_4CH_ISLA216P_FUNC_NAME_HEADER(temp) "Could not set/get temperature"); } +static smch_err_e smch_isla216p_cal_status_compat (smch_isla216p_t *self, + uint32_t *cal_status_arg) +{ + uint8_t *cal_status_code = (uint8_t *) cal_status_arg; + return smch_isla216p_get_cal_status (self, cal_status_code); +} + +FMC250M_4CH_ISLA216P_FUNC_NAME_HEADER(cal_status) +{ + FMC250M_4CH_ISLA216P_FUNC_BODY(owner, args, ret, HALCS_FMC250M_4CH_ISLA216P_MAX_CHANNEL, + smch_isla216p_cal_status_compat, /* No write function */, + "Could not set/get cal_statuserature"); +} /* Exported function pointers */ const disp_table_func_fp fmc250m_4ch_exp_fp [] = { @@ -699,6 +712,7 @@ const disp_table_func_fp fmc250m_4ch_exp_fp [] = { FMC250M_4CH_ISLA216P_FUNC_NAME(portconfig), FMC250M_4CH_ISLA216P_FUNC_NAME(reg), FMC250M_4CH_ISLA216P_FUNC_NAME(temp), + FMC250M_4CH_ISLA216P_FUNC_NAME(cal_status), NULL }; @@ -709,10 +723,10 @@ const disp_table_func_fp fmc250m_4ch_exp_fp [] = { static smio_err_e _fmc250m_4ch_do_op (void *owner, void *msg); /* Attach an instance of sm_io to dev_io function pointer */ -smio_err_e fmc250m_4ch_attach (smio_t *self, devio_t *parent) +smio_err_e fmc250m_4ch_attach (smio_t *self, void *args) { UNUSED(self); - UNUSED(parent); + UNUSED(args); return SMIO_ERR_FUNC_NOT_IMPL; } @@ -797,7 +811,7 @@ smio_err_e _fmc250m_4ch_do_mgmt_op (void *owner, void *msg) smch_isla216p_t *smch_isla216p = SMIO_ISLA216P_HANDLER(fmc250m, i); smch_isla216p_set_rst (smch_isla216p, FMC250M_4CH_PINCTRL_RST_MODE_ADC); } - + SET_PARAM(self, fmc250m_4ch, 0x0, WB_FMC_250M_4CH_CSR, ADC_CTL, RST_ADCS, SINGLE_BIT_PARAM, FMC250M_4CH_DFLT_RST_ADCS, /* min */, /* max */, NO_CHK_FUNC, SET_FIELD); @@ -807,12 +821,17 @@ smio_err_e _fmc250m_4ch_do_mgmt_op (void *owner, void *msg) SET_PARAM(self, fmc250m_4ch, 0x0, WB_FMC_250M_4CH_CSR, ADC_CTL, SLEEP_ADCS, SINGLE_BIT_PARAM, FMC250M_4CH_DFLT_SLEEP_ADCS, /* min */, /* max */, NO_CHK_FUNC, SET_FIELD); - + for (i = 0; i < NUM_FMC250M_4CH_ISLA216P; ++i) { smch_isla216p_t *smch_isla216p = SMIO_ISLA216P_HANDLER(fmc250m, i); smch_isla216p_set_rst (smch_isla216p, FMC250M_4CH_DFLT_RST_MODE_ADC); smch_isla216p_set_portconfig (smch_isla216p, FMC250M_4CH_DFLT_PORTCONFIG_ADC); - + usleep (1000); + smch_isla216p_set_portconfig (smch_isla216p, FMC250M_4CH_DFLT_RESET_ADC); + usleep (1000); + smch_isla216p_set_portconfig (smch_isla216p, FMC250M_4CH_DFLT_PORTCONFIG_ADC); + usleep (1000); + /* Check if we can read ADC temperature code. If the code is 0x7FF it means the ADC * was not reset properly. Most likely due to ADC input clock not present */ uint16_t temp_code = FMC250M_4CH_ISLA216P_INV_TEMP_CODE; @@ -835,7 +854,7 @@ smio_err_e _fmc250m_4ch_do_mgmt_op (void *owner, void *msg) DBE_DEBUG (DBG_SM_IO | DBG_LVL_WARN, "[sm_io:_fmc250m_4ch_do_mgmt_op] Exceeded maximum ADC reset tryouts. " "Some ADCs might not be reliable. Reset it manually!\n"); err = SMIO_ERR_CONFIG_DFLT; - + } } else { diff --git a/core/sm_io/src/sm_io/c/modules/fmc_active_clk/sm_io_fmc_active_clk_defaults.c b/core/sm_io/src/sm_io/c/modules/fmc_active_clk/sm_io_fmc_active_clk_defaults.c index 7326c22d..ef9a4978 100644 --- a/core/sm_io/src/sm_io/c/modules/fmc_active_clk/sm_io_fmc_active_clk_defaults.c +++ b/core/sm_io/src/sm_io/c/modules/fmc_active_clk/sm_io_fmc_active_clk_defaults.c @@ -76,14 +76,16 @@ smio_err_e fmc_active_clk_config_defaults (char *broker_endp, char *service, err_param_set, SMIO_ERR_CONFIG_DFLT); client_err = halcs_ad9510_cfg_defaults (config_client, service, 0); - ASSERT_TEST(client_err == HALCS_CLIENT_SUCCESS || - client_err == HALCS_CLIENT_ERR_AGAIN, "Could not configure AD9510", + ASSERT_TEST(client_err == HALCS_CLIENT_SUCCESS, "Could not configure AD9510", err_param_set, SMIO_ERR_CONFIG_DFLT); /* After everything is complete. Send message telling FMC250 to initialize */ client_err = halcs_set_rst_isla216p (config_client, service, FMC_ACTIVE_CLK_DFLT_RST_ISLA216P); ASSERT_TEST(client_err == HALCS_CLIENT_SUCCESS, "Could not reset FMC250M_4CH", err_param_set, SMIO_ERR_CONFIG_DFLT); + client_err = halcs_set_rst_swap (config_client, service, FMC_ACTIVE_CLK_DFLT_RST_ISLA216P); + ASSERT_TEST(client_err == HALCS_CLIENT_SUCCESS, "Could not reset SWAP", + err_param_set, SMIO_ERR_CONFIG_DFLT); err_param_set: halcs_client_destroy (&config_client); diff --git a/core/sm_io/src/sm_io/c/modules/fmc_active_clk/sm_io_fmc_active_clk_defaults.h b/core/sm_io/src/sm_io/c/modules/fmc_active_clk/sm_io_fmc_active_clk_defaults.h index 497844d1..f616ef35 100644 --- a/core/sm_io/src/sm_io/c/modules/fmc_active_clk/sm_io_fmc_active_clk_defaults.h +++ b/core/sm_io/src/sm_io/c/modules/fmc_active_clk/sm_io_fmc_active_clk_defaults.h @@ -18,6 +18,7 @@ #define FMC_ACTIVE_CLK_DFLT_SI57X_FOUT_FACTORY SI57X_FOUT_FACTORY_DFLT #define FMC_ACTIVE_CLK_DFLT_SI57X_FOUT 113040445 /* 113.040445 MHz default */ #define FMC_ACTIVE_CLK_DFLT_RST_ISLA216P 0x1 +#define FMC_ACTIVE_CLK_DFLT_RST_SWAP 0x1 smio_err_e fmc_active_clk_config_defaults (char *broker_endp, char *service, const char *log_file_name); diff --git a/core/sm_io/src/sm_io/c/modules/fmc_active_clk/sm_io_fmc_active_clk_exp.c b/core/sm_io/src/sm_io/c/modules/fmc_active_clk/sm_io_fmc_active_clk_exp.c index 5ae1d7fd..592e568e 100644 --- a/core/sm_io/src/sm_io/c/modules/fmc_active_clk/sm_io_fmc_active_clk_exp.c +++ b/core/sm_io/src/sm_io/c/modules/fmc_active_clk/sm_io_fmc_active_clk_exp.c @@ -349,6 +349,35 @@ static int _fmc_active_clk_rst_isla216p (void *owner, void *args, void *ret) return err; } +static int _fmc_active_clk_rst_swap (void *owner, void *args, void *ret) +{ + UNUSED(ret); + assert (owner); + assert (args); + int err = -FMC_ACTIVE_CLK_OK; + smio_err_e serr = SMIO_SUCCESS; + SMIO_OWNER_TYPE *self = SMIO_EXP_OWNER(owner); + uint32_t inst_id = smio_get_inst_id (self); + + uint32_t rw = *(uint32_t *) EXP_MSG_ZMQ_FIRST_ARG(args); + UNUSED(rw); + + uint32_t value = *(uint32_t *) EXP_MSG_ZMQ_NEXT_ARG(args); + + DBE_DEBUG (DBG_SM_IO | DBG_LVL_TRACE, "[sm_io:fmc_active_clk] " + "Calling _fmc_active_clk_rst_swap\n"); + + /* Tell FMC250M_4CH that we have initialized */ + if (value == 0x1) { + serr = smio_send_mgmt_msg (self, 0x12897592, inst_id, "INIT_OK"); + ASSERT_TEST(serr == SMIO_SUCCESS, "Could not send MGMT message to SWAP", err_send_mgmt_msg, + -FMC_ACTIVE_CLK_ERR); + } + +err_send_mgmt_msg: + return err; +} + /* Macros to avoid repetition of the function body AD9510 */ typedef smch_err_e (*smch_ad9510_func_fp2) (smch_ad9510_t *self, uint32_t *addr, uint32_t *param); @@ -471,6 +500,7 @@ const disp_table_func_fp fmc_active_clk_exp_fp [] = { FMC_ACTIVE_CLK_SI571_FUNC_NAME(freq), FMC_ACTIVE_CLK_SI571_FUNC_NAME(get_defaults), _fmc_active_clk_rst_isla216p, + _fmc_active_clk_rst_swap, FMC_ACTIVE_CLK_AD9510_FUNC_NAME(data), NULL }; @@ -482,10 +512,10 @@ const disp_table_func_fp fmc_active_clk_exp_fp [] = { static smio_err_e _fmc_active_clk_do_op (void *owner, void *msg); /* Attach an instance of sm_io to dev_io function pointer */ -smio_err_e fmc_active_clk_attach (smio_t *self, devio_t *parent) +smio_err_e fmc_active_clk_attach (smio_t *self, void *args) { UNUSED(self); - UNUSED(parent); + UNUSED(args); return SMIO_ERR_FUNC_NOT_IMPL; } diff --git a/core/sm_io/src/sm_io/c/modules/fmc_adc_common/sm_io_fmc_adc_common_exp.c b/core/sm_io/src/sm_io/c/modules/fmc_adc_common/sm_io_fmc_adc_common_exp.c index 28a4b57d..6363a5e0 100644 --- a/core/sm_io/src/sm_io/c/modules/fmc_adc_common/sm_io_fmc_adc_common_exp.c +++ b/core/sm_io/src/sm_io/c/modules/fmc_adc_common/sm_io_fmc_adc_common_exp.c @@ -113,10 +113,10 @@ const disp_table_func_fp fmc_adc_common_exp_fp [] = { static smio_err_e _fmc_adc_common_do_op (void *owner, void *msg); /* Attach an instance of sm_io to dev_io function pointer */ -smio_err_e fmc_adc_common_attach (smio_t *self, devio_t *parent) +smio_err_e fmc_adc_common_attach (smio_t *self, void *args) { UNUSED(self); - UNUSED(parent); + UNUSED(args); return SMIO_ERR_FUNC_NOT_IMPL; } diff --git a/core/sm_io/src/sm_io/c/modules/fmcpico1m_4ch/sm_io_fmcpico1m_4ch_exp.c b/core/sm_io/src/sm_io/c/modules/fmcpico1m_4ch/sm_io_fmcpico1m_4ch_exp.c index 07eec6f4..b0e4ace5 100644 --- a/core/sm_io/src/sm_io/c/modules/fmcpico1m_4ch/sm_io_fmcpico1m_4ch_exp.c +++ b/core/sm_io/src/sm_io/c/modules/fmcpico1m_4ch/sm_io_fmcpico1m_4ch_exp.c @@ -147,10 +147,10 @@ const disp_table_func_fp fmcpico1m_4ch_exp_fp [] = { static smio_err_e _fmcpico1m_4ch_do_op (void *owner, void *msg); /* Attach an instance of sm_io to dev_io function pointer */ -smio_err_e fmcpico1m_4ch_attach (smio_t *self, devio_t *parent) +smio_err_e fmcpico1m_4ch_attach (smio_t *self, void *args) { UNUSED(self); - UNUSED(parent); + UNUSED(args); return SMIO_ERR_FUNC_NOT_IMPL; } diff --git a/core/sm_io/src/sm_io/c/modules/init/init.mk b/core/sm_io/src/sm_io/c/modules/init/init.mk new file mode 100644 index 00000000..d74fc7c7 --- /dev/null +++ b/core/sm_io/src/sm_io/c/modules/init/init.mk @@ -0,0 +1,4 @@ +sm_io_init_DIR = $(sm_io_modules_DIR)/init + +sm_io_init_OBJS = $(sm_io_init_DIR)/sm_io_init_core.o \ + $(sm_io_init_DIR)/sm_io_init_exp.o diff --git a/core/sm_io/src/sm_io/c/modules/init/sm_io_init_core.c b/core/sm_io/src/sm_io/c/modules/init/sm_io_init_core.c new file mode 100644 index 00000000..6f17893a --- /dev/null +++ b/core/sm_io/src/sm_io/c/modules/init/sm_io_init_core.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2017 LNLS (www.lnls.br) + * Author: Lucas Russo + * + * Released according to the GNU GPL, version 3 or any later version. + */ + +#include "halcs_server.h" +/* Private headers */ +#include "sm_io_init_core.h" + +/* Undef ASSERT_ALLOC to avoid conflicting with other ASSERT_ALLOC */ +#ifdef ASSERT_TEST +#undef ASSERT_TEST +#endif +#define ASSERT_TEST(test_boolean, err_str, err_goto_label, /* err_core */ ...) \ + ASSERT_HAL_TEST(test_boolean, SM_IO, "[sm_io_init_core]", \ + err_str, err_goto_label, /* err_core */ __VA_ARGS__) + +#ifdef ASSERT_ALLOC +#undef ASSERT_ALLOC +#endif +#define ASSERT_ALLOC(ptr, err_goto_label, /* err_core */ ...) \ + ASSERT_HAL_ALLOC(ptr, SM_IO, "[sm_io_init_core]", \ + smio_err_str(SMIO_ERR_ALLOC), \ + err_goto_label, /* err_core */ __VA_ARGS__) + +#ifdef CHECK_ERR +#undef CHECK_ERR +#endif +#define CHECK_ERR(err, err_type) \ + CHECK_HAL_ERR(err, SM_IO, "[sm_io_init_core]", \ + smio_err_str (err_type)) + +/* Creates a new instance of Device Information */ +smio_init_t * smio_init_new (smio_t *parent) +{ + UNUSED(parent); + + smio_init_t *self = (smio_init_t *) zmalloc (sizeof *self); + ASSERT_ALLOC(self, err_self_alloc); + + return self; + +err_self_alloc: + return NULL; +} + +/* Destroy an instance of the Device Information */ +smio_err_e smio_init_destroy (smio_init_t **self_p) +{ + assert (self_p); + + if (*self_p) { + smio_init_t *self = *self_p; + + free (self); + *self_p = NULL; + } + + return SMIO_SUCCESS; +} + diff --git a/core/sm_io/src/sm_io/c/modules/init/sm_io_init_core.h b/core/sm_io/src/sm_io/c/modules/init/sm_io_init_core.h new file mode 100644 index 00000000..d86f16ff --- /dev/null +++ b/core/sm_io/src/sm_io/c/modules/init/sm_io_init_core.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2017 LNLS (www.lnls.br) + * Author: Lucas Russo + * + * Released according to the GNU GPL, version 3 or any later version. +*/ + +#ifndef _SM_IO_INIT_CORE_H_ +#define _SM_IO_INIT_CORE_H_ + +typedef struct { + const uint32_t example; +} smio_init_t; + +/***************** Our methods *****************/ + +/* Creates a new instance of the smio realization */ +smio_init_t * smio_init_new (smio_t *parent); +/* Destroys the smio realizationn */ +smio_err_e smio_init_destroy (smio_init_t **self_p); + +#endif diff --git a/core/sm_io/src/sm_io/c/modules/init/sm_io_init_exp.c b/core/sm_io/src/sm_io/c/modules/init/sm_io_init_exp.c new file mode 100644 index 00000000..5a0bdb33 --- /dev/null +++ b/core/sm_io/src/sm_io/c/modules/init/sm_io_init_exp.c @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2017 LNLS (www.lnls.br) + * Author: Lucas Russo + * + * Released according to the GNU GPL, version 3 or any later version. + */ + +#include "halcs_server.h" +/* Private headers */ +#include "sm_io_init_codes.h" +#include "sm_io_init_exports.h" +#include "sm_io_init_core.h" +#include "sm_io_init_exp.h" + +/* Undef ASSERT_ALLOC to avoid conflicting with other ASSERT_ALLOC */ +#ifdef ASSERT_TEST +#undef ASSERT_TEST +#endif +#define ASSERT_TEST(test_boolean, err_str, err_goto_label, /* err_core */ ...) \ + ASSERT_HAL_TEST(test_boolean, SM_IO, "[sm_io:init_exp]", \ + err_str, err_goto_label, /* err_core */ __VA_ARGS__) + +#ifdef ASSERT_ALLOC +#undef ASSERT_ALLOC +#endif +#define ASSERT_ALLOC(ptr, err_goto_label, /* err_core */ ...) \ + ASSERT_HAL_ALLOC(ptr, SM_IO, "[sm_io:init_exp]", \ + smio_err_str(SMIO_ERR_ALLOC), \ + err_goto_label, /* err_core */ __VA_ARGS__) + +#ifdef CHECK_ERR +#undef CHECK_ERR +#endif +#define CHECK_ERR(err, err_type) \ + CHECK_HAL_ERR(err, SM_IO, "[sm_io:init_exp]", \ + smio_err_str (err_type)) + +/************************************************************/ +/***************** Specific INIT Operations *****************/ +/************************************************************/ + +static int _init_check (void *owner, void *args, void *ret) +{ + assert (owner); + assert (args); + int err = -INIT_OK; + + DBE_DEBUG (DBG_SM_IO | DBG_LVL_TRACE, "[sm_io:init] " + "Calling _init_check\n"); + SMIO_OWNER_TYPE *self = SMIO_EXP_OWNER(owner); + smio_init_t *init = smio_get_handler (self); + ASSERT_TEST(init != NULL, "Could not get SMIO INIT handler", + err_get_init_handler, -INIT_ERR); + + /* Message is: + * frame 0: operation code + * frame 1: rw + * frame 2: arg (unused) + */ + uint32_t rw = *(uint32_t *) EXP_MSG_ZMQ_FIRST_ARG(args); + uint32_t arg = *(uint32_t *) EXP_MSG_ZMQ_NEXT_ARG(args); + UNUSED(rw); + UNUSED(arg); + + /* Return value to caller */ + uint32_t arg_ret = 0x1; + *((uint32_t *) ret) = arg_ret; + err = sizeof (arg_ret); + DBE_DEBUG (DBG_SM_IO | DBG_LVL_TRACE, "[sm_io:init] " + "Init = 0x%08X\n", arg_ret); + + return err; + +err_get_init_handler: + return err; +} + +/* Exported function pointers */ +const disp_table_func_fp init_exp_fp [] = { + _init_check, + NULL +}; + +/************************************************************/ +/***************** Export methods functions *****************/ +/************************************************************/ + +static smio_err_e _init_do_op (void *owner, void *msg); + +/* Attach an instance of sm_io to dev_io function pointer */ +smio_err_e init_attach (smio_t *self, void *args) +{ + UNUSED(self); + UNUSED(args); + return SMIO_ERR_FUNC_NOT_IMPL; +} + +/* Deattach an instance of sm_io to dev_io function pointer */ +smio_err_e init_deattach (smio_t *self) +{ + UNUSED(self); + return SMIO_ERR_FUNC_NOT_IMPL; +} + +/* Export (register) sm_io to handle operations function pointer */ +smio_err_e init_export_ops (smio_t *self, + const disp_op_t **smio_exp_ops) +{ + UNUSED(self); + UNUSED(smio_exp_ops); + return SMIO_ERR_FUNC_NOT_IMPL; +} + +/* Unexport (unregister) sm_io to handle operations function pointer */ +smio_err_e init_unexport_ops (smio_t *self) +{ + UNUSED(self); + return SMIO_ERR_FUNC_NOT_IMPL; +} + +/* Generic wrapper for receiving opcodes and arguments to specific funtions function pointer */ +/* FIXME: Code repetition! _devio_do_smio_op () function does almost the same!!! */ +smio_err_e _init_do_op (void *owner, void *msg) +{ + UNUSED(owner); + UNUSED(msg); + return SMIO_ERR_FUNC_NOT_IMPL; +} + +smio_err_e init_do_op (void *self, void *msg) +{ + return _init_do_op (self, msg); +} + +const smio_ops_t init_ops = { + .attach = &init_attach, /* Attach sm_io instance to dev_io */ + .deattach = &init_deattach, /* Deattach sm_io instance to dev_io */ + .export_ops = &init_export_ops, /* Export sm_io operations to dev_io */ + .unexport_ops = &init_unexport_ops, /* Unexport sm_io operations to dev_io */ + .do_op = &init_do_op /* Generic wrapper for handling specific operations */ +}; + +/************************************************************/ +/****************** Bootstrap Operations ********************/ +/************************************************************/ + +smio_err_e init_init (smio_t * self) +{ + DBE_DEBUG (DBG_SM_IO | DBG_LVL_TRACE, "[sm_io:init_exp] Initializing init\n"); + + smio_err_e err = SMIO_SUCCESS; + + err = smio_set_id (self, INIT_SDB_DEVID); + ASSERT_TEST(err == SMIO_SUCCESS, "Could not set SMIO id", err_set_id); + err = smio_set_name (self, INIT_SDB_NAME); + ASSERT_TEST(err == SMIO_SUCCESS, "Could not set SMIO name", err_set_name); + + /* Set SMIO ops pointers */ + err = smio_set_ops (self, &init_ops); + ASSERT_TEST(err == SMIO_SUCCESS, "Could not set SMIO operations", + err_smio_set_ops); + err = smio_set_thsafe_client_ops (self, &smio_thsafe_client_zmq_ops); + ASSERT_TEST(err == SMIO_SUCCESS, "Could not set SMIO thsafe operations", + err_smio_set_thsafe_ops); + + /* disp_op_t structure is const and all of the functions performing on it + * obviously receives a const argument, but here (and only on the SMIO + * initialization) we need to make an exception if we want to keep the + * functions' description and the function pointers separate */ + err = smio_init_exp_ops (self, (disp_op_t **) init_exp_ops, init_exp_fp); + ASSERT_TEST(err == SMIO_SUCCESS, "Could not fill SMIO " + "function descriptors with the callbacks", err_fill_desc); + + err = smio_set_exp_ops (self, init_exp_ops); + ASSERT_TEST(err == SMIO_SUCCESS, "Could not set SMIO exported operations", + err_smio_set_exp_ops); + + /* Initialize specific structure */ + smio_init_t *smio_handler = smio_init_new (self); + ASSERT_ALLOC(smio_handler, err_smio_handler_alloc, SMIO_ERR_ALLOC); + err = smio_set_handler (self, smio_handler); + ASSERT_TEST(err == SMIO_SUCCESS, "Could not set SMIO handler", + err_smio_set_handler); + + return err; + +err_smio_set_handler: + smio_init_destroy (&smio_handler); +err_smio_handler_alloc: + smio_set_exp_ops (self, NULL); +err_smio_set_exp_ops: +err_fill_desc: + smio_set_thsafe_client_ops (self, NULL); +err_smio_set_thsafe_ops: + smio_set_ops (self, NULL); +err_smio_set_ops: +err_set_name: +err_set_id: + return err; +} + +/* Destroy sm_io instance of init */ +smio_err_e init_shutdown (smio_t *self) +{ + DBE_DEBUG (DBG_SM_IO | DBG_LVL_TRACE, "[sm_io:init_exp] Shutting down init\n"); + + smio_err_e err = SMIO_SUCCESS; + smio_init_t *init = smio_get_handler (self); + ASSERT_TEST(init != NULL, "Could not get INIT handler", + err_init_handler, SMIO_ERR_ALLOC /* FIXME: improve return code */); + + /* Destroy SMIO instance */ + smio_init_destroy (&init); + /* Nullify operation pointers */ + smio_set_exp_ops (self, NULL); + smio_set_thsafe_client_ops (self, NULL); + smio_set_ops (self, NULL); + +err_init_handler: + return err; +} + +const smio_bootstrap_ops_t init_bootstrap_ops = { + .init = &init_init, + .shutdown = &init_shutdown, + .config_defaults = NULL +}; + +SMIO_MOD_DECLARE(INIT_SDB_DEVID, INIT_SDB_NAME, init_bootstrap_ops) diff --git a/core/sm_io/src/sm_io/c/modules/init/sm_io_init_exp.h b/core/sm_io/src/sm_io/c/modules/init/sm_io_init_exp.h new file mode 100644 index 00000000..a2b7edbc --- /dev/null +++ b/core/sm_io/src/sm_io/c/modules/init/sm_io_init_exp.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2017 LNLS (www.lnls.br) + * Author: Lucas Russo + * + * Released according to the GNU GPL, version 3 or any later version. + */ + +#ifndef _INIT_H_ +#define _INIT_H_ + +/* Known modules IDs (from SDB records defined in FPGA) */ +#define INIT_SDB_DEVID 0xdc64e778 +#define INIT_SDB_NAME "INIT" + +extern const smio_bootstrap_ops_t init_bootstrap_ops; + +#endif + diff --git a/core/sm_io/src/sm_io/c/modules/modules.mk b/core/sm_io/src/sm_io/c/modules/modules.mk index c8a343f0..940baab8 100644 --- a/core/sm_io/src/sm_io/c/modules/modules.mk +++ b/core/sm_io/src/sm_io/c/modules/modules.mk @@ -12,7 +12,8 @@ include $(sm_io_modules_DIR)/fmc130m_4ch/fmc130m_4ch.mk \ $(sm_io_modules_DIR)/afc_diag/afc_diag.mk \ $(sm_io_modules_DIR)/trigger_iface/trigger_iface.mk \ $(sm_io_modules_DIR)/trigger_mux/trigger_mux.mk \ - $(sm_io_modules_DIR)/afc_timing/afc_timing.mk + $(sm_io_modules_DIR)/afc_timing/afc_timing.mk \ + $(sm_io_modules_DIR)/init/init.mk sm_io_modules_OBJS = $(sm_io_fmc130m_4ch_OBJS) \ $(sm_io_fmc250m_4ch_OBJS) \ @@ -26,4 +27,5 @@ sm_io_modules_OBJS = $(sm_io_fmc130m_4ch_OBJS) \ $(sm_io_afc_diag_OBJS) \ $(sm_io_trigger_iface_OBJS) \ $(sm_io_trigger_mux_OBJS) \ - $(sm_io_afc_timing_OBJS) + $(sm_io_afc_timing_OBJS) \ + $(sm_io_init_OBJS) diff --git a/core/sm_io/src/sm_io/c/modules/rffe/sm_io_rffe_exp.c b/core/sm_io/src/sm_io/c/modules/rffe/sm_io_rffe_exp.c index dad3101c..e0d23468 100644 --- a/core/sm_io/src/sm_io/c/modules/rffe/sm_io_rffe_exp.c +++ b/core/sm_io/src/sm_io/c/modules/rffe/sm_io_rffe_exp.c @@ -260,10 +260,10 @@ const disp_table_func_fp rffe_exp_fp [] = { static smio_err_e _rffe_do_op (void *owner, void *msg); /* Attach an instance of sm_io to dev_io function pointer */ -smio_err_e rffe_attach (smio_t *self, devio_t *parent) +smio_err_e rffe_attach (smio_t *self, void *args) { UNUSED(self); - UNUSED(parent); + UNUSED(args); return SMIO_ERR_FUNC_NOT_IMPL; } diff --git a/core/sm_io/src/sm_io/c/modules/swap/sm_io_swap_defaults.h b/core/sm_io/src/sm_io/c/modules/swap/sm_io_swap_defaults.h index 204cbc49..85daad01 100644 --- a/core/sm_io/src/sm_io/c/modules/swap/sm_io_swap_defaults.h +++ b/core/sm_io/src/sm_io/c/modules/swap/sm_io_swap_defaults.h @@ -9,17 +9,11 @@ #define _SWAP_DEFAULTS_H_ /******************** Switching Clock Default Values **************************/ -#define SWAP_DFLT_SW 1 /* 1 is switching in direct state +#define SWAP_DFLT_SW 3 /* 1 is switching in direct state No switching */ -#define SWAP_DFLT_SW_DLY 21 /* in ADC counts */ - -#define _SWAP_DFLT_DIV_CLK 980 /* in ADC counts */ - -/* This parameter was not supposed to be like this. We need to divide by 2, - * because the RFFE uses the FPGA switching clock as a trigger to regenerate - * it internally */ -#define SWAP_DFLT_DIV_CLK (_SWAP_DFLT_DIV_CLK/2) /* in ADC counts */ +#define SWAP_DFLT_SW_DLY 30 /* in ADC counts */ +#define SWAP_DFLT_DIV_CLK 980 /* in ADC counts */ /************************** Gain Default Values ******************************/ diff --git a/core/sm_io/src/sm_io/c/modules/swap/sm_io_swap_exp.c b/core/sm_io/src/sm_io/c/modules/swap/sm_io_swap_exp.c index 095f65ae..f89ae646 100644 --- a/core/sm_io/src/sm_io/c/modules/swap/sm_io_swap_exp.c +++ b/core/sm_io/src/sm_io/c/modules/swap/sm_io_swap_exp.c @@ -83,10 +83,10 @@ const disp_table_func_fp swap_exp_fp [] = { static smio_err_e _swap_do_op (void *owner, void *msg); /* Attach an instance of sm_io to dev_io function pointer */ -smio_err_e swap_attach (smio_t *self, devio_t *parent) +smio_err_e swap_attach (smio_t *self, void *args) { UNUSED(self); - UNUSED(parent); + UNUSED(args); return SMIO_ERR_FUNC_NOT_IMPL; } @@ -113,6 +113,63 @@ smio_err_e swap_unexport_ops (smio_t *self) return SMIO_ERR_FUNC_NOT_IMPL; } +smio_err_e _swap_do_mgmt_op (void *owner, void *msg) +{ + assert (owner); + assert (msg); + + smio_err_e err = SMIO_SUCCESS; + SMIO_OWNER_TYPE *self = SMIO_EXP_OWNER(owner); + GEN_MSG_ZMQ_TYPE *recv_msg = GEN_MSG_ZMQ(msg); + uint32_t my_inst_id = smio_get_inst_id (self); + + /* We expect the following */ + /* + * Arg1: (uint32_t) smio_id + * Arg2: (uint64_t) base + * Arg3: (uint32_t) inst_id + * Arg4: (uint32_t) dest_smio_id + * Arg5: (uint32_t) dest_inst_id + * Arg6: (string) message + * */ + STR_MSG_ZMQ_TYPE *smio_id_str = STR_MSG_ZMQ_FIRST_ARG(recv_msg); + STR_MSG_ZMQ_TYPE *base_str = STR_MSG_ZMQ_NEXT_ARG(recv_msg); + STR_MSG_ZMQ_TYPE *inst_id_str = STR_MSG_ZMQ_NEXT_ARG(recv_msg); + STR_MSG_ZMQ_TYPE *dest_smio_id_str = STR_MSG_ZMQ_NEXT_ARG(recv_msg); + STR_MSG_ZMQ_TYPE * dest_inst_id_str = STR_MSG_ZMQ_NEXT_ARG(recv_msg); + STR_MSG_ZMQ_TYPE *mgmt_msg_zmq_str = STR_MSG_ZMQ_NEXT_ARG(recv_msg); + + /* Conversions */ + uint32_t inst_id = strtol(inst_id_str, NULL, 10); + + /* Check if FMC_ACTIVE_CLK SMIO sent this message */ + if (inst_id == my_inst_id && streq (mgmt_msg_zmq_str, "INIT_OK")) { + DBE_DEBUG (DBG_SM_IO | DBG_LVL_TRACE, "[sm_io:_swap_do_mgmt_op] Resetting module\n"); + SET_PARAM(self, swap, 0x0, BPM_SWAP, CTRL, + SWAP_DIV_F, MULT_BIT_PARAM, SWAP_DFLT_DIV_CLK, /* min */, /* max */, + NO_CHK_FUNC, SET_FIELD); + SET_PARAM(self, swap, 0x0, BPM_SWAP, CTRL, + MODE, MULT_BIT_PARAM, SWAP_DFLT_SW, /* min */, /* max */, + NO_CHK_FUNC, SET_FIELD); + SET_PARAM(self, swap, 0x0, BPM_SWAP, DLY, + DESWAP, MULT_BIT_PARAM, SWAP_DFLT_SW_DLY, /* min */, /* max */, + NO_CHK_FUNC, SET_FIELD); + } + else { + DBE_DEBUG (DBG_SM_IO | DBG_LVL_WARN, "[sm_io:_swap_do_mgmt_op] Unexpected message received\n"); + } + + /* Clenup strings */ + STR_MSG_ZMQ_CLENUP_ARG(smio_id_str); + STR_MSG_ZMQ_CLENUP_ARG(base_str); + STR_MSG_ZMQ_CLENUP_ARG(inst_id_str); + STR_MSG_ZMQ_CLENUP_ARG(dest_smio_id_str); + STR_MSG_ZMQ_CLENUP_ARG(dest_inst_id_str); + STR_MSG_ZMQ_CLENUP_ARG(mgmt_msg_zmq_str); + + return err; +} + /* Generic wrapper for receiving opcodes and arguments to specific funtions function pointer */ /* FIXME: Code repetition! _devio_do_smio_op () function does almost the same!!! */ smio_err_e _swap_do_op (void *owner, void *msg) @@ -127,12 +184,18 @@ smio_err_e swap_do_op (void *self, void *msg) return _swap_do_op (self, msg); } +smio_err_e swap_do_mgmt_op (void *self, void *msg) +{ + return _swap_do_mgmt_op (self, msg); +} + const smio_ops_t swap_ops = { .attach = &swap_attach, /* Attach sm_io instance to dev_io */ .deattach = &swap_deattach, /* Deattach sm_io instance to dev_io */ .export_ops = &swap_export_ops, /* Export sm_io operations to dev_io */ .unexport_ops = &swap_unexport_ops, /* Unexport sm_io operations to dev_io */ - .do_op = &swap_do_op /* Generic wrapper for handling specific operations */ + .do_op = &swap_do_op, /* Generic wrapper for handling specific operations */ + .do_mgmt_op = &swap_do_mgmt_op /* Generic wrapper for handling internal SMIO operations */ }; /************************************************************/ diff --git a/core/sm_io/src/sm_io/c/modules/trigger_iface/sm_io_trigger_iface_exp.c b/core/sm_io/src/sm_io/c/modules/trigger_iface/sm_io_trigger_iface_exp.c index 9c47503a..aab0fb61 100644 --- a/core/sm_io/src/sm_io/c/modules/trigger_iface/sm_io_trigger_iface_exp.c +++ b/core/sm_io/src/sm_io/c/modules/trigger_iface/sm_io_trigger_iface_exp.c @@ -133,10 +133,10 @@ const disp_table_func_fp trigger_iface_exp_fp [] = { static smio_err_e _trigger_iface_do_op (void *owner, void *msg); /* Attach an instance of sm_io to dev_io function pointer */ -smio_err_e trigger_iface_attach (smio_t *self, devio_t *parent) +smio_err_e trigger_iface_attach (smio_t *self, void *args) { UNUSED(self); - UNUSED(parent); + UNUSED(args); return SMIO_ERR_FUNC_NOT_IMPL; } diff --git a/core/sm_io/src/sm_io/c/modules/trigger_mux/sm_io_trigger_mux_exp.c b/core/sm_io/src/sm_io/c/modules/trigger_mux/sm_io_trigger_mux_exp.c index 483ad43b..6a6938e7 100644 --- a/core/sm_io/src/sm_io/c/modules/trigger_mux/sm_io_trigger_mux_exp.c +++ b/core/sm_io/src/sm_io/c/modules/trigger_mux/sm_io_trigger_mux_exp.c @@ -97,10 +97,10 @@ const disp_table_func_fp trigger_mux_exp_fp [] = { static smio_err_e _trigger_mux_do_op (void *owner, void *msg); /* Attach an instance of sm_io to dev_io function pointer */ -smio_err_e trigger_mux_attach (smio_t *self, devio_t *parent) +smio_err_e trigger_mux_attach (smio_t *self, void *args) { UNUSED(self); - UNUSED(parent); + UNUSED(args); return SMIO_ERR_FUNC_NOT_IMPL; } diff --git a/core/sm_io/src/sm_io/c/sm_io.c b/core/sm_io/src/sm_io/c/sm_io.c index 24d70a63..5744dbaa 100644 --- a/core/sm_io/src/sm_io/c/sm_io.c +++ b/core/sm_io/src/sm_io/c/sm_io.c @@ -44,7 +44,6 @@ struct _smio_t { char *service; /* Exported service name */ /* int verbose; */ /* Print activity to stdout */ mlm_client_t *worker; /* zeroMQ Malamute client (worker) */ - devio_t *parent; /* Pointer back to parent dev_io */ void *smio_handler; /* Generic pointer to a device handler. This must be cast to a specific type by the devices functions */ @@ -54,6 +53,7 @@ struct _smio_t { zsock_t *pipe_frontend; /* Force zloop to interrupt and rebuild poll set. This is used to send messages */ zsock_t *pipe_backend; /* Force zloop to interrupt and rebuild poll set. This is used to receive messages */ int timer_id; /* Timer ID */ + zpoller_t *poller; /* Poller for internal DEVIO <-> SMIO sockets */ /* Specific SMIO operations dispatch table for exported operations */ disp_table_t *exp_ops_dtable; @@ -129,6 +129,10 @@ smio_t *smio_new (th_boot_args_t *args, zsock_t *pipe_mgmt, * interrupting the loop to check for rebuilds */ _smio_engine_handle_socket (self, self->pipe_backend, _smio_handle_pipe_backend); + /* Set-up poller for internal DEVIO <-> SMIO sockets */ + self->poller = zpoller_new (self->pipe_msg, NULL); + ASSERT_TEST(self->poller != NULL, "Could not create zpoller", err_poller_alloc); + /* Initialize SMIO base address */ self->base = args->base; @@ -147,6 +151,8 @@ smio_t *smio_new (th_boot_args_t *args, zsock_t *pipe_mgmt, err_mlm_connect: mlm_client_destroy (&self->worker); err_worker_alloc: + zpoller_destroy (&self->poller); +err_poller_alloc: zloop_timer_end (self->loop, self->timer_id); err_timer_alloc: zloop_destroy (&self->loop); @@ -172,6 +178,7 @@ smio_err_e smio_destroy (smio_t **self_p) smio_t *self = *self_p; mlm_client_destroy (&self->worker); + zpoller_destroy (&self->poller); zloop_timer_end (self->loop, self->timer_id); zloop_destroy (&self->loop); zsock_destroy (&self->pipe_backend); @@ -185,7 +192,6 @@ smio_err_e smio_destroy (smio_t **self_p) disp_table_destroy (&self->exp_ops_dtable); self->thsafe_client_ops = NULL; self->ops = NULL; - self->parent = NULL; free (self->service); free (self->name); @@ -299,6 +305,7 @@ static int _smio_handle_pipe_mgmt (zloop_t *loop, zsock_t *reader, void *args) /* Invalid message received. Discard message and continue normally */ DBE_DEBUG (DBG_SM_IO | DBG_LVL_WARN, "[sm_io:_smio_handle_pipe_mgmt] PIPE " "received an invalid command\n"); + free (command); zmsg_destroy (&recv_msg); return 0; } @@ -371,6 +378,7 @@ static int _smio_handle_pipe_backend (zloop_t *loop, zsock_t *reader, void *args "received an invalid command\n"); } + free (command); zmsg_destroy (&recv_msg); return 0; } @@ -455,13 +463,12 @@ const disp_table_ops_t smio_disp_table_ops = { /************************************************************/ /* Attach an instance of sm_io to dev_io function pointer */ -smio_err_e smio_attach (smio_t *self, devio_t *parent) +smio_err_e smio_attach (smio_t *self, void *args) { assert (self); smio_err_e err = SMIO_SUCCESS; - self->parent = parent; - err = SMIO_FUNC_OPS_NOFAIL_WRAPPER(err, attach, parent); + err = SMIO_FUNC_OPS_NOFAIL_WRAPPER(err, attach, args); ASSERT_TEST(err == SMIO_SUCCESS, "Registered SMIO \"attach\" function error", err_func); @@ -474,7 +481,6 @@ smio_err_e smio_deattach (smio_t *self) { assert (self); smio_err_e err = SMIO_SUCCESS; - self->parent = NULL; err = SMIO_FUNC_OPS_NOFAIL_WRAPPER(err, deattach); ASSERT_TEST(err == SMIO_SUCCESS, "Registered SMIO \"deattach\" function error", @@ -666,6 +672,12 @@ const smio_thsafe_client_ops_t *smio_get_thsafe_client_ops (smio_t *self) return self->thsafe_client_ops; } +zpoller_t *smio_get_poller (smio_t *self) +{ + assert (self); + return self->poller; +} + /**************** Static Functions ***************/ static smio_err_e _smio_do_op (void *owner, void *msg) diff --git a/core/sm_io/src/sm_io/c/sm_io_bootstrap.c b/core/sm_io/src/sm_io/c/sm_io_bootstrap.c index 0231fb02..f4d6e1d3 100644 --- a/core/sm_io/src/sm_io/c/sm_io_bootstrap.c +++ b/core/sm_io/src/sm_io/c/sm_io_bootstrap.c @@ -44,9 +44,6 @@ void smio_startup (zsock_t *pipe, void *args) zsock_t *pipe_msg = th_args->pipe_msg; volatile const smio_mod_dispatch_t *smio_mod_dispatch = th_args->smio_handler; - /* Signal parent we are ready */ - zsock_signal (pipe_mgmt, 0); - /* We must export our service as the combination of the * devio name (coming from devio parent) and our own name ID * followed by an optional parameter coming from priv pointer */ @@ -64,8 +61,17 @@ void smio_startup (zsock_t *pipe, void *args) smio_t *self = smio_new (th_args, pipe_mgmt, pipe_msg, smio_service); ASSERT_ALLOC(self, err_self_alloc); + /* Signal parent we are ready. It's important to signal the parent only + * after we have register to the broker, as we must expire a possible + * existing client with the same address before the config_defaults + * actor send the messages to the old client reference. + * However, we can't signal the parent after SMIO init function, as + * it probably send messages to DEVIO/LLIO and we won't be able to poll + * them if we are waiting here. */ + zsock_signal (pipe_mgmt, 0); + /* Atach this SMIO instance to its parent */ - smio_err_e err = smio_attach (self, th_args->parent); + smio_err_e err = smio_attach (self, th_args->args); ASSERT_TEST(err == SMIO_SUCCESS, "Could not attach SMIO", err_call_attach); /* Call SMIO init function to finish initializing its internal strucutres */ @@ -139,51 +145,21 @@ void smio_config_defaults (zsock_t *pipe, void *args) DBE_DEBUG (DBG_SM_IO | DBG_LVL_INFO, "[sm_io_bootstrap] Config Thread %s " "allocating resources ...\n", smio_service); - SMIO_DISPATCH_FUNC_WRAPPER_GEN(config_defaults, smio_mod_dispatch, - th_args->broker, smio_service, th_args->log_file); - - /* We've finished configuring the SMIO. Tell DEVIO we are done */ - char *smio_service_suffix = hutils_concat_strings_no_sep ( - smio_mod_dispatch->name, inst_id_str); - ASSERT_ALLOC(smio_service_suffix, err_smio_service_suffix_alloc); + smio_cfg_t *self = smio_cfg_new (th_args, smio_mod_dispatch, pipe, + smio_service, inst_id_str); + ASSERT_ALLOC(self, err_self_alloc); - DBE_DEBUG (DBG_SM_IO | DBG_LVL_INFO, "[sm_io_bootstrap] Sending CONFIG DONE message over PIPE\n"); - int zerr = zstr_sendx (pipe, smio_service_suffix, "CONFIG DONE", NULL); - ASSERT_TEST (zerr >= 0, "Config thread could not send CONFIG DONE message " - "over PIPE. Destroying ourselves", err_send_config_done); - DBE_DEBUG (DBG_SM_IO | DBG_LVL_INFO, "[sm_io_bootstrap] Config Thread %s " - "sent CONFIG DONE over PIPE\n", smio_service); - - /* Wait for $TERM message from DEVIO to end */ - bool terminated = false; - while (!terminated) { - zmsg_t *msg = zmsg_recv (pipe); - if (msg == NULL) { - break; /* Interrupted */ - } - - char *command = zmsg_popstr (msg); - if (streq (command, "$TERM")) { - terminated = true; - } - /* Invalid message received. Log the error, but continue normally */ - else { - DBE_DEBUG (DBG_SM_IO | DBG_LVL_WARN, "[sm_io_bootstrap] Config Thread %s " - "received an invalid command over PIPE\n", smio_service); - goto err_pipe_mgmt_bad_msg; - } - -err_pipe_mgmt_bad_msg: - free (command); - zmsg_destroy (&msg); - } + /* Main loop request-action */ + smio_err_e err = smio_cfg_loop (self); + ASSERT_TEST (err == SMIO_SUCCESS, "Could not loop the SMIO CFG messages", + err_smio_cfg_loop); DBE_DEBUG (DBG_SM_IO | DBG_LVL_INFO, "[sm_io_bootstrap] Config Thread %s " - "terminating with %s\n", smio_service, (terminated)? "success" : "error"); + "terminating with success\n", smio_service); -err_smio_service_suffix_alloc: - free (smio_service_suffix); -err_send_config_done: +err_smio_cfg_loop: + smio_cfg_destroy (&self); +err_self_alloc: free (smio_service); err_smio_service_alloc: free (inst_id_str); diff --git a/core/sm_io/src/sm_io/c/sm_io_cfg.c b/core/sm_io/src/sm_io/c/sm_io_cfg.c new file mode 100644 index 00000000..e2779c2a --- /dev/null +++ b/core/sm_io/src/sm_io/c/sm_io_cfg.c @@ -0,0 +1,309 @@ +/* + * Copyright (C) 2017 LNLS (www.lnls.br) + * Author: Lucas Russo + * + * Released according to the GNU GPL, version 3 or any later version. + */ + +#include "halcs_server.h" + +/* Undef ASSERT_ALLOC to avoid conflicting with other ASSERT_ALLOC */ +#ifdef ASSERT_TEST +#undef ASSERT_TEST +#endif +#define ASSERT_TEST(test_boolean, err_str, err_goto_label, /* err_core */ ...) \ + ASSERT_HAL_TEST(test_boolean, SM_IO, "[sm_io_cfg_defaults]", \ + err_str, err_goto_label, /* err_core */ __VA_ARGS__) + +#ifdef ASSERT_ALLOC +#undef ASSERT_ALLOC +#endif +#define ASSERT_ALLOC(ptr, err_goto_label, /* err_core */ ...) \ + ASSERT_HAL_ALLOC(ptr, SM_IO, "[sm_io_cfg_defaults]", \ + smio_err_str(SMIO_ERR_ALLOC), \ + err_goto_label, /* err_core */ __VA_ARGS__) + +#ifdef CHECK_ERR +#undef CHECK_ERR +#endif +#define CHECK_ERR(err, err_type) \ + CHECK_HAL_ERR(err, SM_IO, "[sm_io_cfg_defaults]", \ + smio_err_str (err_type)) + +#define SMIO_CFG_DEFAULTS_POLLER_TIMEOUT 100 /* in msec */ +#define SMIO_CFG_DEFAULTS_POLLER_NTIMES 1 /* execute and exit */ + +/* Main class object that every sm_io_cfg_defaults must implement */ +struct _smio_cfg_t { + char *service; /* Exported service name */ + char *inst_id_str; /* Instance ID string */ + zloop_t *loop; /* Reactor for server sockets */ + zsock_t *pipe; /* Pipe back to parent to exchange Management messages */ + int timer_id; /* Timer ID */ + char *broker; /* Broker endpoint */ + char *log_file; /* Logfile */ + volatile const smio_mod_dispatch_t + *smio_mod_dispatch; /* SMIO handler table entry */ +}; + +static const char *_smio_cfg_get_service (smio_cfg_t *self); +static char *_smio_cfg_clone_service (smio_cfg_t *self); + +static smio_err_e _smio_cfg_engine_handle_socket (smio_cfg_t *smio_cfg, void *sock, + zloop_reader_fn handler); +static int _smio_cfg_handle_timer (zloop_t *loop, int timer_id, void *arg); +static int _smio_cfg_handle_pipe (zloop_t *loop, zsock_t *reader, void *args); + +/* Boot new SMIO instance. Better used as a thread (CZMQ actor) init function */ +smio_cfg_t *smio_cfg_new (th_config_args_t *args, + volatile const smio_mod_dispatch_t *smio_mod_dispatch, + zsock_t *pipe, char *service, char *inst_id_str) +{ + DBE_DEBUG (DBG_SM_IO | DBG_LVL_TRACE, "[sm_io_cfg_defaults_bootstrap] " + "Initializing CFG SMIO\n"); + smio_cfg_t *self = (smio_cfg_t *) zmalloc (sizeof *self); + ASSERT_ALLOC(self, err_self_alloc); + + /* Setup exported service name */ + self->service = strdup (service); + ASSERT_ALLOC(self->service, err_service_alloc); + self->inst_id_str = strdup (inst_id_str); + ASSERT_ALLOC(self->inst_id_str, err_inst_id_str_alloc); + self->broker = strdup (args->broker); + ASSERT_ALLOC(self->broker, err_broker_alloc); + self->log_file = strdup (args->log_file); + ASSERT_ALLOC(self->log_file, err_log_file_alloc); + + self->smio_mod_dispatch = smio_mod_dispatch; + self->pipe = pipe; + + /* Setup loop */ + self->loop = zloop_new (); + ASSERT_ALLOC(self->loop, err_loop_alloc); + + /* Execute config defaults once on constructor */ + SMIO_DISPATCH_FUNC_WRAPPER_GEN(config_defaults, self->smio_mod_dispatch, + self->broker, self->service, self->log_file); + + /* Set loop timeout. We exit the config_defaults actor if no message + * incomes before the timer expires */ + self->timer_id = zloop_timer (self->loop, SMIO_CFG_DEFAULTS_POLLER_TIMEOUT, + SMIO_CFG_DEFAULTS_POLLER_NTIMES, _smio_cfg_handle_timer, self); + ASSERT_TEST(self->timer_id != -1, "Could not create zloop timer", err_timer_alloc); + + return self; + +err_timer_alloc: + zloop_destroy (&self->loop); +err_loop_alloc: + free (self->log_file); +err_log_file_alloc: + free (self->broker); +err_broker_alloc: + free (self->inst_id_str); +err_inst_id_str_alloc: + free (self->service); +err_service_alloc: + free (self); +err_self_alloc: + return NULL; +} + +smio_err_e smio_cfg_destroy (smio_cfg_t **self_p) +{ + assert (self_p); + + if (*self_p) { + smio_cfg_t *self = *self_p; + + zloop_timer_end (self->loop, self->timer_id); + zloop_destroy (&self->loop); + /* Don't destroy pipe as this is taken care of by the + * zactor infrastructure, s_thread_shim (void *args) on CZMQ + * 3.0.2 src/zactor.c + * zsock_destroy (&self->pipe); + */ + free (self->log_file); + free (self->broker); + free (self->inst_id_str); + free (self->service); + + free (self); + *self_p = NULL; + } + + return SMIO_SUCCESS; +} + +/* From Malamute https://github.com/zeromq/malamute/blob/master/src/mlm_server_engine.inc + * + * Poll actor or zsock for activity, invoke handler on any received + * message. Handler must be a CZMQ zloop_fn function; receives server + * as arg. */ + +static smio_err_e _smio_cfg_engine_handle_socket (smio_cfg_t *smio_cfg, void *sock, + zloop_reader_fn handler) +{ + smio_err_e err = SMIO_SUCCESS; + + if (smio_cfg) { + smio_cfg_t *self = (smio_cfg_t *) smio_cfg; + + /* Resolve zactor_t -> zsock_t */ + if (zactor_is (sock)) { + sock = zactor_sock ((zactor_t *) sock); + } + else { + /* Socket reference must be of type zsock */ + ASSERT_TEST(zsock_is (sock), "Invalid socket reference", + err_zsock_is, SMIO_ERR_INV_SOCKET); + } + + if (handler != NULL) { + /* Register handler "handler "to socket "sock" and pass argument + * "self" to the handler */ + int rc = zloop_reader (self->loop, (zsock_t *) sock, handler, self); + ASSERT_TEST(rc == 0, "Could not register zloop_reader", + err_zloop_reader, SMIO_ERR_ALLOC); + zloop_reader_set_tolerant (self->loop, (zsock_t *) sock); + } + else { + zloop_reader_end (self->loop, (zsock_t *) sock); + } + } + +err_zloop_reader: +err_zsock_is: + return err; +} + +/* zloop handler for timer when it expires */ +static int _smio_cfg_handle_timer (zloop_t *loop, int timer_id, void *arg) +{ + UNUSED(loop); + UNUSED(timer_id); + + /* We expect a smio instance as reference */ + smio_cfg_t *smio_cfg = (smio_cfg_t *) arg; + + /* No activity on socket means we have finished configuring and + * no one wants to reconfigure the SMIO. Tell DEVIO we are done */ + char *smio_service_suffix = hutils_concat_strings_no_sep ( + smio_cfg->smio_mod_dispatch->name, smio_cfg->inst_id_str); + ASSERT_ALLOC(smio_service_suffix, err_smio_service_suffix_alloc); + + DBE_DEBUG (DBG_SM_IO | DBG_LVL_INFO, "[sm_io_bootstrap] Sending CONFIG DONE " + "message over PIPE due to socket inactivity\n"); + + int zerr = zstr_sendx (smio_cfg->pipe, smio_service_suffix, "CONFIG DONE", NULL); + ASSERT_TEST (zerr >= 0, "Config thread could not send CONFIG DONE message " + "over PIPE. Destroying ourselves", err_send_config_done); + DBE_DEBUG (DBG_SM_IO | DBG_LVL_INFO, "[sm_io_bootstrap] Config Thread %s " + "sent CONFIG DONE over PIPE\n", smio_cfg->service); + +err_send_config_done: + free (smio_service_suffix); +err_smio_service_suffix_alloc: + return 0; +} + +/* zloop handler for PIPE */ +static int _smio_cfg_handle_pipe (zloop_t *loop, zsock_t *reader, void *args) +{ + UNUSED(loop); + + /* Arguments for command */ + char *command = NULL; + + /* We expect a smio instance as reference */ + smio_cfg_t *smio_cfg = (smio_cfg_t *) args; + + /* Receive message */ + zmsg_t *recv_msg = zmsg_recv (reader); + if (recv_msg == NULL) { + return -1; /* Interrupted */ + } + + command = zmsg_popstr (recv_msg); + if (streq (command, "$TERM")) { + /* Shutdown the engine */ + free (command); + zmsg_destroy (&recv_msg); + return -1; + } + else if (streq (command, "RECONFIGURE SMIO")) { + DBE_DEBUG (DBG_SM_IO | DBG_LVL_INFO, "[sm_io_bootstrap] " + "Reconfiguring SMIO %s as it was requested by command " + "\"RECONFIGURE SMIO\"\n", smio_cfg->service); + SMIO_DISPATCH_FUNC_WRAPPER_GEN(config_defaults, smio_cfg->smio_mod_dispatch, + smio_cfg->broker, smio_cfg->service, smio_cfg->log_file); + } + /* Invalid message received. Log the error, but continue normally */ + else { + DBE_DEBUG (DBG_SM_IO | DBG_LVL_WARN, "[sm_io_bootstrap] Config Thread %s " + "received an invalid command over PIPE\n", smio_cfg->service); + } + + free (command); + zmsg_destroy (&recv_msg); + return 0; +} + +smio_err_e smio_cfg_loop (smio_cfg_t *self) +{ + assert (self); + smio_err_e err = SMIO_SUCCESS; + + /* Set-up server register commands handler */ + _smio_cfg_engine_handle_socket (self, self->pipe, _smio_cfg_handle_pipe); + + /* Run reactor until there's a termination signal */ + zloop_start (self->loop); + + return err; +} + +/************************************************************/ +/********************* Accessor methods *********************/ +/************************************************************/ + +/* Get SMIO service */ +const char *smio_cfg_get_service (smio_cfg_t *self) +{ + assert (self); + return _smio_cfg_get_service (self); +} + +/* Clone SMIO service */ +char *smio_cfg_clone_service (smio_cfg_t *self) +{ + assert (self); + return _smio_cfg_clone_service (self); +} + +zsock_t *smio_cfg_get_pipe (smio_cfg_t *self) +{ + return self->pipe; +} + +/**************** Static Functions ***************/ + +/* Get SMIO service */ +static const char *_smio_cfg_get_service (smio_cfg_t *self) +{ + assert (self); + return self->service; +} + +/* Clone SMIO service */ +static char *_smio_cfg_clone_service (smio_cfg_t *self) +{ + assert (self); + + char *service = strdup (self->service); + ASSERT_ALLOC(service, err_alloc); + +err_alloc: + return service; +} + diff --git a/core/sm_io_table/include/sm_io_codes.h b/core/sm_io_table/include/sm_io_codes.h index 0b29c9a9..37b312d2 100644 --- a/core/sm_io_table/include/sm_io_codes.h +++ b/core/sm_io_table/include/sm_io_codes.h @@ -36,6 +36,7 @@ typedef struct _smio_rffe_version_t smio_rffe_version_t; #include "sm_io_trigger_mux_codes.h" #include "sm_io_afc_timing_codes.h" #include "sm_io_acq_pm_codes.h" +#include "sm_io_init_codes.h" /* Include all function descriptors */ #include "sm_io_fmc130m_4ch_exports.h" @@ -52,6 +53,7 @@ typedef struct _smio_rffe_version_t smio_rffe_version_t; #include "sm_io_trigger_mux_exports.h" #include "sm_io_afc_timing_exports.h" #include "sm_io_acq_pm_exports.h" +#include "sm_io_init_exports.h" /* Merge all function descriptors in a single structure */ extern const disp_op_t **smio_exp_ops []; diff --git a/core/sm_io_table/include/sm_io_fmc250m_4ch_exports.h b/core/sm_io_table/include/sm_io_fmc250m_4ch_exports.h index 1c7330f0..e7d35b90 100644 --- a/core/sm_io_table/include/sm_io_fmc250m_4ch_exports.h +++ b/core/sm_io_table/include/sm_io_fmc250m_4ch_exports.h @@ -42,6 +42,7 @@ extern disp_op_t fmc250m_4ch_rst_exp; extern disp_op_t fmc250m_4ch_portconfig_exp; extern disp_op_t fmc250m_4ch_reg_exp; extern disp_op_t fmc250m_4ch_temp_exp; +extern disp_op_t fmc250m_4ch_cal_status_exp; extern const disp_op_t *fmc250m_4ch_exp_ops []; diff --git a/core/sm_io_table/include/sm_io_fmc_active_clk_exports.h b/core/sm_io_table/include/sm_io_fmc_active_clk_exports.h index 9b8eee0c..26d0833a 100644 --- a/core/sm_io_table/include/sm_io_fmc_active_clk_exports.h +++ b/core/sm_io_table/include/sm_io_fmc_active_clk_exports.h @@ -27,6 +27,7 @@ extern disp_op_t fmc_active_clk_ad9510_pll_clk_sel_exp; extern disp_op_t fmc_active_clk_si571_freq_exp; extern disp_op_t fmc_active_clk_si571_get_defaults_exp; extern disp_op_t fmc_active_clk_rst_isla216p_exp; +extern disp_op_t fmc_active_clk_rst_swap_exp; extern disp_op_t fmc_active_clk_ad9510_data_exp; extern const disp_op_t *fmc_active_clk_exp_ops []; diff --git a/core/sm_io_table/include/sm_io_init_exports.h b/core/sm_io_table/include/sm_io_init_exports.h new file mode 100644 index 00000000..8999a911 --- /dev/null +++ b/core/sm_io_table/include/sm_io_init_exports.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2017 LNLS (www.lnls.br) + * Author: Lucas Russo + * + * Released according to the GNU GPL, version 3 or any later version. + */ + +#ifndef _SM_IO_INIT_EXPORTS_H_ +#define _SM_IO_INIT_EXPORTS_H_ + +#include "disptable.h" + +extern disp_op_t init_set_get_check_exp; + +extern const disp_op_t *init_exp_ops []; + +#endif + diff --git a/core/sm_io_table/src/sm_io_table/c/modules/fmc250m_4ch/sm_io_fmc250m_4ch_exports.c b/core/sm_io_table/src/sm_io_table/c/modules/fmc250m_4ch/sm_io_fmc250m_4ch_exports.c index 05fcb92c..da96703e 100644 --- a/core/sm_io_table/src/sm_io_table/c/modules/fmc250m_4ch/sm_io_fmc250m_4ch_exports.c +++ b/core/sm_io_table/src/sm_io_table/c/modules/fmc250m_4ch/sm_io_fmc250m_4ch_exports.c @@ -401,6 +401,19 @@ disp_op_t fmc250m_4ch_temp_exp = { } }; +disp_op_t fmc250m_4ch_cal_status_exp = { + .name = FMC250M_4CH_NAME_CAL_STATUS, + .opcode = FMC250M_4CH_OPCODE_CAL_STATUS, + .retval = DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + .retval_owner = DISP_OWNER_OTHER, + .args = { + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_END + } +}; + /* Exported function description */ const disp_op_t *fmc250m_4ch_exp_ops [] = { &fmc250m_4ch_adc_data0_exp, @@ -435,6 +448,7 @@ const disp_op_t *fmc250m_4ch_exp_ops [] = { &fmc250m_4ch_portconfig_exp, &fmc250m_4ch_reg_exp, &fmc250m_4ch_temp_exp, + &fmc250m_4ch_cal_status_exp, NULL }; diff --git a/core/sm_io_table/src/sm_io_table/c/modules/fmc_active_clk/sm_io_fmc_active_clk_exports.c b/core/sm_io_table/src/sm_io_table/c/modules/fmc_active_clk/sm_io_fmc_active_clk_exports.c index 276f76ff..f854e1ed 100644 --- a/core/sm_io_table/src/sm_io_table/c/modules/fmc_active_clk/sm_io_fmc_active_clk_exports.c +++ b/core/sm_io_table/src/sm_io_table/c/modules/fmc_active_clk/sm_io_fmc_active_clk_exports.c @@ -214,6 +214,18 @@ disp_op_t fmc_active_clk_rst_isla216p_exp = { } }; +disp_op_t fmc_active_clk_rst_swap_exp = { + .name = FMC_ACTIVE_CLK_NAME_RST_SWAP, + .opcode = FMC_ACTIVE_CLK_OPCODE_RST_SWAP, + .retval = DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + .retval_owner = DISP_OWNER_OTHER, + .args = { + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_END + } +}; + disp_op_t fmc_active_clk_ad9510_data_exp = { .name = FMC_ACTIVE_CLK_NAME_AD9510_DATA, .opcode = FMC_ACTIVE_CLK_OPCODE_AD9510_DATA, @@ -246,6 +258,7 @@ const disp_op_t *fmc_active_clk_exp_ops [] = { &fmc_active_clk_si571_freq_exp, &fmc_active_clk_si571_get_defaults_exp, &fmc_active_clk_rst_isla216p_exp, + &fmc_active_clk_rst_swap_exp, &fmc_active_clk_ad9510_data_exp, NULL }; diff --git a/core/sm_io_table/src/sm_io_table/c/modules/init/init.mk b/core/sm_io_table/src/sm_io_table/c/modules/init/init.mk new file mode 100644 index 00000000..12172a3e --- /dev/null +++ b/core/sm_io_table/src/sm_io_table/c/modules/init/init.mk @@ -0,0 +1,3 @@ +sm_io_table_init_DIR = $(sm_io_table_modules_DIR)/init + +sm_io_table_init_OBJS = $(sm_io_table_init_DIR)/sm_io_init_exports.o diff --git a/core/sm_io_table/src/sm_io_table/c/modules/init/sm_io_init_exports.c b/core/sm_io_table/src/sm_io_table/c/modules/init/sm_io_init_exports.c new file mode 100644 index 00000000..e0a1bd71 --- /dev/null +++ b/core/sm_io_table/src/sm_io_table/c/modules/init/sm_io_init_exports.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2017 LNLS (www.lnls.br) + * Author: Lucas Russo + * + * Released according to the GNU GPL, version 3 or any later version. + */ + +#include "sm_io_exports_helper.h" +#include "sm_io_codes.h" + +/* Description SMIO INIT functions */ + +disp_op_t init_set_get_check_exp = { + .name = INIT_NAME_SET_GET_CHECK, + .opcode = INIT_OPCODE_SET_GET_CHECK, + .retval = DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + .retval_owner = DISP_OWNER_OTHER, + .args = { + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_END + } +}; + +/* Exported function description */ +const disp_op_t *init_exp_ops [] = { + &init_set_get_check_exp, + NULL +}; + diff --git a/core/sm_io_table/src/sm_io_table/c/modules/modules.mk b/core/sm_io_table/src/sm_io_table/c/modules/modules.mk index f68d239e..ed8e1328 100644 --- a/core/sm_io_table/src/sm_io_table/c/modules/modules.mk +++ b/core/sm_io_table/src/sm_io_table/c/modules/modules.mk @@ -12,7 +12,8 @@ include $(sm_io_table_modules_DIR)/fmc130m_4ch/fmc130m_4ch.mk \ $(sm_io_table_modules_DIR)/afc_diag/afc_diag.mk \ $(sm_io_table_modules_DIR)/trigger_iface/trigger_iface.mk \ $(sm_io_table_modules_DIR)/trigger_mux/trigger_mux.mk \ - $(sm_io_table_modules_DIR)/afc_timing/afc_timing.mk + $(sm_io_table_modules_DIR)/afc_timing/afc_timing.mk \ + $(sm_io_table_modules_DIR)/init/init.mk sm_io_table_modules_OBJS = $(sm_io_table_modules_DIR)/sm_io_codes.o \ $(sm_io_table_fmc130m_4ch_OBJS) \ @@ -27,4 +28,5 @@ sm_io_table_modules_OBJS = $(sm_io_table_modules_DIR)/sm_io_codes.o \ $(sm_io_table_afc_diag_OBJS) \ $(sm_io_table_trigger_iface_OBJS) \ $(sm_io_table_trigger_mux_OBJS) \ - $(sm_io_table_afc_timing_OBJS) + $(sm_io_table_afc_timing_OBJS) \ + $(sm_io_table_init_OBJS) diff --git a/core/sm_io_table/src/sm_io_table/c/modules/sm_io_codes.c b/core/sm_io_table/src/sm_io_table/c/modules/sm_io_codes.c index 47b3a724..7733ce32 100644 --- a/core/sm_io_table/src/sm_io_table/c/modules/sm_io_codes.c +++ b/core/sm_io_table/src/sm_io_table/c/modules/sm_io_codes.c @@ -14,12 +14,14 @@ const disp_op_t **smio_exp_ops [] = { fmc250m_4ch_exp_ops, fmc_adc_common_exp_ops, fmc_active_clk_exp_ops, + fmcpico1m_4ch_exp_ops, swap_exp_ops, rffe_exp_ops, afc_diag_exp_ops, trigger_iface_exp_ops, trigger_mux_exp_ops, afc_timing_exp_ops, + init_exp_ops, acq_pm_exp_ops, NULL }; diff --git a/examples/src/dsp_swap/c/dsp_swap.c b/examples/src/dsp_swap/c/dsp_swap.c index 71cfc048..118be94c 100644 --- a/examples/src/dsp_swap/c/dsp_swap.c +++ b/examples/src/dsp_swap/c/dsp_swap.c @@ -231,6 +231,14 @@ int main (int argc, char *argv []) fprintf (stdout, "[client:swap]: halcs_set_sw_dly was successfully executed\n"); } + uint32_t arg = 0; + halcs_get_sw (halcs_client, service_swap, &arg); + fprintf (stdout, "[client:swap]: halcs_get_sw: %u\n", arg); + halcs_get_div_clk (halcs_client, service_swap, &arg); + fprintf (stdout, "[client:swap]: halcs_get_div_clk: %u\n", arg); + halcs_get_sw_dly (halcs_client, service_swap, &arg); + fprintf (stdout, "[client:swap]: halcs_get_sw_dly: %u\n", arg); + err_halcs_client_new: err_halcs_exit: err_halcs_get: diff --git a/examples/src/fpga_info/c/fpga_info.c b/examples/src/fpga_info/c/fpga_info.c index 03907d90..f8a5ddef 100644 --- a/examples/src/fpga_info/c/fpga_info.c +++ b/examples/src/fpga_info/c/fpga_info.c @@ -152,6 +152,13 @@ int main (int argc, char *argv []) } fprintf (stdout, "[client:afc_diag]: Build user email: %s\n", (char *) rev_data.data); + err = halcs_get_afc_diag_build_revision (halcs_client, service_afc_diag, &rev_data); + if (err != HALCS_CLIENT_SUCCESS){ + fprintf (stderr, "[client:afc_diag]: halcs_get_afc_diag_build_revision failed\n"); + goto err_halcs_get; + } + fprintf (stdout, "[client:afc_diag]: Build revision: %s\n", (char *) rev_data.data); + err_halcs_client_new: err_halcs_get: halcs_client_destroy (&halcs_client); diff --git a/examples/src/trigger/c/trigger.c b/examples/src/trigger/c/trigger.c index 79067d07..ddde5578 100644 --- a/examples/src/trigger/c/trigger.c +++ b/examples/src/trigger/c/trigger.c @@ -343,6 +343,25 @@ int main (int argc, char *argv []) goto err_halcs_set; } } + + /* Read all parameters from this channel */ + uint32_t arg = 0; + halcs_get_trigger_rcv_src (halcs_client, service_mux, chan, &arg); + fprintf (stderr, "[client:trigger]: halcs_get_trigger_rcv_src: %u\n", arg); + halcs_get_trigger_rcv_in_sel (halcs_client, service_mux, chan, &arg); + fprintf (stderr, "[client:trigger]: halcs_get_trigger_rcv_in_sel: %u\n", arg); + halcs_get_trigger_transm_src (halcs_client, service_mux, chan, &arg); + fprintf (stderr, "[client:trigger]: halcs_get_trigger_transm_src: %u\n", arg); + halcs_get_trigger_transm_out_sel (halcs_client, service_mux, chan, &arg); + fprintf (stderr, "[client:trigger]: halcs_get_trigger_transm_out_sel: %u\n", arg); + halcs_get_trigger_rcv_len (halcs_client, service_iface, chan, &arg); + fprintf (stderr, "[client:trigger]: halcs_get_trigger_rcv_len: %u\n", arg); + halcs_get_trigger_transm_len (halcs_client, service_iface, chan, &arg); + fprintf (stderr, "[client:trigger]: halcs_get_trigger_transm_len: %u\n", arg); + halcs_get_trigger_dir (halcs_client, service_iface, chan, &arg); + fprintf (stderr, "[client:trigger]: halcs_get_trigger_dir: %u\n", arg); + halcs_get_trigger_dir_pol (halcs_client, service_iface, chan, &arg); + fprintf (stderr, "[client:trigger]: halcs_get_trigger_dir_pol: %u\n", arg); } err_halcs_set: diff --git a/foreign/libsdbfs/.gitignore b/foreign/libsdbfs/.gitignore new file mode 100644 index 00000000..546f233c --- /dev/null +++ b/foreign/libsdbfs/.gitignore @@ -0,0 +1,5 @@ +# generated binaries +gensdbfs +sdb-extract +sdb-read +sdb-read-lnls diff --git a/foreign/libsdbfs/Makefile b/foreign/libsdbfs/Makefile index 13fe0bcc..6e1f8097 100644 --- a/foreign/libsdbfs/Makefile +++ b/foreign/libsdbfs/Makefile @@ -15,32 +15,57 @@ NM = $(CROSS_COMPILE)nm STRIP = $(CROSS_COMPILE)strip OBJCOPY = $(CROSS_COMPILE)objcopy OBJDUMP = $(CROSS_COMPILE)objdump +MAKE = make + +CMDSEP = ; + +# install prefix +PREFIX ?= /usr # calculate endianness at compile time ENDIAN := $(shell ./check-endian $(CC)) override CFLAGS += -Wall -ggdb -O2 -override CFLAGS += -I../../core/common/include # for override CFLAGS += -Iinclude +override CFLAGS += -Iinclude/linux # for override CFLAGS += -ffunction-sections -fdata-sections override CFLAGS += -Wno-pointer-sign override CFLAGS += $(ENDIAN) $(LINUXINCLUDE) +.PHONY: tools tools_clean tools_install tools_uninstall LIB = libsdbfs.a OBJS = src/sdbfs/c/glue.o src/sdbfs/c/access.o -all: $(LIB) +all: $(LIB) tools $(OBJS): $(wildcard include/*.h) $(wildcard include/linux/*.h) $(LIB): $(OBJS) $(AR) r $@ $(OBJS) -clean: +tools: + $(MAKE) -C tools + +clean: tools_clean rm -f $(OBJS) $(LIB) *~ core +tools_clean: + $(MAKE) -C tools clean + mrproper: clean +install: tools_install + $(foreach lib,$(LIB),install -m 755 $(lib) $(PREFIX)/lib/ $(CMDSEP)) + +uninstall: tools_uninstall + $(foreach lib,$(LIB),rm -f $(PREFIX)/lib/$(lib) $(CMDSEP)) + +tools_install: + $(MAKE) -C tools install + +tools_uninstall: + $(MAKE) -C tools uninstall + # add the other unused targets, so the rule in ../Makefile works -modules install uninstall modules_install: +modules modules_install: diff --git a/foreign/libsdbfs/tools/Makefile b/foreign/libsdbfs/tools/Makefile index 1e573430..cb799f8a 100644 --- a/foreign/libsdbfs/tools/Makefile +++ b/foreign/libsdbfs/tools/Makefile @@ -9,15 +9,20 @@ STRIP = $(CROSS_COMPILE)strip OBJCOPY = $(CROSS_COMPILE)objcopy OBJDUMP = $(CROSS_COMPILE)objdump +CMDSEP = ; + +# install prefix +PREFIX ?= /usr + ERRHAND_DBG ?= y ERRHAND_MIN_LEVEL ?= DBG_LVL_ERR ERRHAND_SUBSYS_ON ?= "(DBG_DEV_MNGR | DBG_DEV_IO | DBG_SM_IO | DBG_LIB_CLIENT | DBG_SM_PR | DBG_SM_CH | DBG_LL_IO | DBG_HAL_UTILS)" -CFLAGS = -Wall -ggdb -CFLAGS += -I.. -I../../../include +override CFLAGS += -Wall -ggdb +override CFLAGS += -I.. -I../include -I../include/linux CFLAGS_LNLS = -DERRHAND_DBG=$(ERRHAND_DBG) -DERRHAND_MIN_LEVEL=$(ERRHAND_MIN_LEVEL) \ -DERRHAND_SUBSYS_ON=$(ERRHAND_SUBSYS_ON) -LDFLAGS = -L.. -lsdbfs +override LDFLAGS += -L.. -lsdbfs LDFLAGS_LNLS = -lllio -lerrhand -lconvc -lczmq -lpcidriver PROG = gensdbfs sdb-read sdb-read-lnls sdb-extract @@ -35,5 +40,11 @@ $(PROG): ../libsdbfs.a clean: rm -f $(PROG) *.o *~ core +install: + $(foreach prog,$(PROG),install -m 755 $(prog) $(PREFIX)/bin/ $(CMDSEP)) + +uninstall: + $(foreach prog,$(PROG),rm -f $(PREFIX)/bin/$(prog) $(CMDSEP)) + # add the other unused targets, so the rule in ../Makefile works -modules install modules_install: +modules modules_install: diff --git a/foreign/pcie-driver b/foreign/pcie-driver index d4623476..c363b700 160000 --- a/foreign/pcie-driver +++ b/foreign/pcie-driver @@ -1 +1 @@ -Subproject commit d4623476b72d29e4f59be6002cc5f777dd135ac0 +Subproject commit c363b700ba8b555fcffa044d56498e2bced338d7 diff --git a/libs/acqclient/build.gradle b/libs/acqclient/build.gradle index a14812a9..865dff0d 100644 --- a/libs/acqclient/build.gradle +++ b/libs/acqclient/build.gradle @@ -1,10 +1,9 @@ import org.ajoberstar.gradle.git.release.opinion.Strategies -plugins { - id 'org.ajoberstar.grgit' version '1.6.0' - id 'org.ajoberstar.release-opinion' version '1.6.0' -} +import br.lnls.dig.gradle.updatesemvermacrostask.UpdateSemVerMacrosTask +apply plugin: 'org.ajoberstar.grgit' +apply plugin: 'org.ajoberstar.release-opinion' apply plugin: br.lnls.dig.gradle.nativedistribution.plugins.NativeDistributionPlugin apply plugin: 'br.lnls.dig.gradle.nativerelease' apply plugin: com.janitovff.grgit.config.GitConfigPlugin @@ -46,3 +45,8 @@ release { allowDirtyRepo: true ) } + +task updateVersionMacros(type: UpdateSemVerMacrosTask) { + macroPrefix 'ACQ_CLIENT_VERSION_' + file project.file('include/acq_client_classes.h') +} diff --git a/libs/acqclient/include/acq_client_classes.h b/libs/acqclient/include/acq_client_classes.h index d20a3c90..bc2f3418 100644 --- a/libs/acqclient/include/acq_client_classes.h +++ b/libs/acqclient/include/acq_client_classes.h @@ -25,8 +25,8 @@ /* version macros for compile-time API detection */ #define ACQ_CLIENT_VERSION_MAJOR 0 -#define ACQ_CLIENT_VERSION_MINOR 1 -#define ACQ_CLIENT_VERSION_PATCH 0 +#define ACQ_CLIENT_VERSION_MINOR 5 +#define ACQ_CLIENT_VERSION_PATCH 1 #define ACQ_CLIENT_MAKE_VERSION(major, minor, patch) \ ((major) * 10000 + (minor) * 100 + (patch)) diff --git a/libs/bpmclient/build.gradle b/libs/bpmclient/build.gradle index 2038af08..ba3e4ca1 100644 --- a/libs/bpmclient/build.gradle +++ b/libs/bpmclient/build.gradle @@ -1,10 +1,9 @@ import org.ajoberstar.gradle.git.release.opinion.Strategies -plugins { - id 'org.ajoberstar.grgit' version '1.6.0' - id 'org.ajoberstar.release-opinion' version '1.6.0' -} +import br.lnls.dig.gradle.updatesemvermacrostask.UpdateSemVerMacrosTask +apply plugin: 'org.ajoberstar.grgit' +apply plugin: 'org.ajoberstar.release-opinion' apply plugin: br.lnls.dig.gradle.nativedistribution.plugins.NativeDistributionPlugin apply plugin: 'br.lnls.dig.gradle.nativerelease' apply plugin: com.janitovff.grgit.config.GitConfigPlugin @@ -47,3 +46,8 @@ release { allowDirtyRepo: true ) } + +task updateVersionMacros(type: UpdateSemVerMacrosTask) { + macroPrefix 'BPM_CLIENT_VERSION_' + file project.file('include/bpm_client_classes.h') +} diff --git a/libs/bpmclient/include/bpm_client_classes.h b/libs/bpmclient/include/bpm_client_classes.h index b7dcc601..473285ed 100644 --- a/libs/bpmclient/include/bpm_client_classes.h +++ b/libs/bpmclient/include/bpm_client_classes.h @@ -22,8 +22,8 @@ /* version macros for compile-time API detection */ #define BPM_CLIENT_VERSION_MAJOR 0 -#define BPM_CLIENT_VERSION_MINOR 1 -#define BPM_CLIENT_VERSION_PATCH 0 +#define BPM_CLIENT_VERSION_MINOR 5 +#define BPM_CLIENT_VERSION_PATCH 1 #define BPM_CLIENT_MAKE_VERSION(major, minor, patch) \ ((major) * 10000 + (minor) * 100 + (patch)) diff --git a/libs/convc/build.gradle b/libs/convc/build.gradle index 0fdcb994..7959ab44 100644 --- a/libs/convc/build.gradle +++ b/libs/convc/build.gradle @@ -1,3 +1,5 @@ +import br.lnls.dig.gradle.updatesemvermacrostask.UpdateSemVerMacrosTask + apply plugin: 'br.lnls.dig.gradle.nativedistribution' apply plugin: 'br.lnls.dig.gradle.nativerelease' @@ -14,3 +16,8 @@ model { } } } + +task updateVersionMacros(type: UpdateSemVerMacrosTask) { + macroPrefix 'CONVC_VERSION_' + file project.file('include/convc_classes.h') +} diff --git a/libs/convc/include/convc_classes.h b/libs/convc/include/convc_classes.h index 366d87b9..99c70e2e 100644 --- a/libs/convc/include/convc_classes.h +++ b/libs/convc/include/convc_classes.h @@ -18,8 +18,8 @@ /* version macros for compile-time API detection */ #define CONVC_VERSION_MAJOR 0 -#define CONVC_VERSION_MINOR 1 -#define CONVC_VERSION_PATCH 0 +#define CONVC_VERSION_MINOR 5 +#define CONVC_VERSION_PATCH 1 #define CONVC_MAKE_VERSION(major, minor, patch) \ ((major) * 10000 + (minor) * 100 + (patch)) diff --git a/libs/disptable/build.gradle b/libs/disptable/build.gradle index d34e3085..f48d7d9b 100644 --- a/libs/disptable/build.gradle +++ b/libs/disptable/build.gradle @@ -1,3 +1,5 @@ +import br.lnls.dig.gradle.updatesemvermacrostask.UpdateSemVerMacrosTask + apply plugin: br.lnls.dig.gradle.nativedistribution.plugins.NativeDistributionPlugin apply plugin: 'br.lnls.dig.gradle.nativerelease' @@ -16,3 +18,8 @@ model { } } } + +task updateVersionMacros(type: UpdateSemVerMacrosTask) { + macroPrefix 'DISPTABLE_VERSION_' + file project.file('include/disptable_classes.h') +} diff --git a/libs/disptable/include/disptable_classes.h b/libs/disptable/include/disptable_classes.h index 4c304b2e..c0e60755 100644 --- a/libs/disptable/include/disptable_classes.h +++ b/libs/disptable/include/disptable_classes.h @@ -21,8 +21,8 @@ /* version macros for compile-time API detection */ #define DISPTABLE_VERSION_MAJOR 0 -#define DISPTABLE_VERSION_MINOR 1 -#define DISPTABLE_VERSION_PATCH 0 +#define DISPTABLE_VERSION_MINOR 5 +#define DISPTABLE_VERSION_PATCH 1 #define DISPTABLE_MAKE_VERSION(major, minor, patch) \ ((major) * 10000 + (minor) * 100 + (patch)) diff --git a/libs/errhand/build.gradle b/libs/errhand/build.gradle index a5d76366..5b72258d 100644 --- a/libs/errhand/build.gradle +++ b/libs/errhand/build.gradle @@ -1,3 +1,5 @@ +import br.lnls.dig.gradle.updatesemvermacrostask.UpdateSemVerMacrosTask + apply plugin: br.lnls.dig.gradle.nativedistribution.plugins.NativeDistributionPlugin apply plugin: 'br.lnls.dig.gradle.nativerelease' @@ -12,3 +14,8 @@ model { } } } + +task updateVersionMacros(type: UpdateSemVerMacrosTask) { + macroPrefix 'ERRHAND_VERSION_' + file project.file('include/errhand_classes.h') +} diff --git a/libs/errhand/include/errhand_classes.h b/libs/errhand/include/errhand_classes.h index c7338d0b..3c947d6e 100644 --- a/libs/errhand/include/errhand_classes.h +++ b/libs/errhand/include/errhand_classes.h @@ -20,8 +20,8 @@ /* version macros for compile-time API detection */ #define ERRHAND_VERSION_MAJOR 0 -#define ERRHAND_VERSION_MINOR 1 -#define ERRHAND_VERSION_PATCH 0 +#define ERRHAND_VERSION_MINOR 5 +#define ERRHAND_VERSION_PATCH 1 #define ERRHAND_MAKE_VERSION(major, minor, patch) \ ((major) * 10000 + (minor) * 100 + (patch)) diff --git a/libs/halcsclient/Makefile b/libs/halcsclient/Makefile index d356d392..319a0a4e 100644 --- a/libs/halcsclient/Makefile +++ b/libs/halcsclient/Makefile @@ -115,7 +115,8 @@ OBJS_EXTERNAL = $(SMIO_TABLE_SRC_DIR)/modules/sm_io_codes.o \ $(SMIO_TABLE_SRC_DIR)/modules/trigger_iface/sm_io_trigger_iface_exports.o \ $(SMIO_TABLE_SRC_DIR)/modules/trigger_mux/sm_io_trigger_mux_exports.o \ $(SMIO_TABLE_SRC_DIR)/modules/afc_timing/sm_io_afc_timing_exports.o \ - $(SMIO_TABLE_SRC_DIR)/modules/acq_pm/sm_io_acq_pm_exports.o + $(SMIO_TABLE_SRC_DIR)/modules/acq_pm/sm_io_acq_pm_exports.o \ + $(SMIO_TABLE_SRC_DIR)/modules/init/sm_io_init_exports.o # Project boards boards_INCLUDE_DIRS = -I../../../include/boards/$(BOARD) @@ -124,8 +125,8 @@ boards_INCLUDE_DIRS = -I../../../include/boards/$(BOARD) INCLUDE_DIRS = -I. -Iinclude \ $(boards_INCLUDE_DIRS) \ -I../../../include \ - -I../../core/common/include \ - -I$(SMIO_DIR)/include \ + -I../../core/common/include \ + -I$(SMIO_DIR)/include \ -I$(SMIO_SRC_DIR)/modules \ -I$(SMIO_SRC_DIR)/modules/fmc130m_4ch \ -I$(SMIO_SRC_DIR)/modules/fmc250m_4ch \ @@ -140,8 +141,9 @@ INCLUDE_DIRS = -I. -Iinclude \ -I$(SMIO_SRC_DIR)/modules/trigger_iface \ -I$(SMIO_SRC_DIR)/modules/trigger_mux \ -I$(SMIO_SRC_DIR)/modules/afc_timing \ - -I$(SMIO_SRC_DIR)/modules/acq_pm \ - -I$(SMIO_TABLE_DIR)/include \ + -I$(SMIO_SRC_DIR)/modules/acq_pm \ + -I$(SMIO_SRC_DIR)/modules/init \ + -I$(SMIO_TABLE_DIR)/include \ -I$(SMIO_TABLE_SRC_DIR)/modules \ -I$(SMIO_TABLE_SRC_DIR)/modules/fmc130m_4ch \ -I$(SMIO_TABLE_SRC_DIR)/modules/fmc250m_4ch \ @@ -156,7 +158,8 @@ INCLUDE_DIRS = -I. -Iinclude \ -I$(SMIO_TABLE_SRC_DIR)/modules/trigger_iface \ -I$(SMIO_TABLE_SRC_DIR)/modules/trigger_mux \ -I$(SMIO_TABLE_SRC_DIR)/modules/afc_timing \ - -I$(SMIO_TABLE_SRC_DIR)/modules/acq_pm \ + -I$(SMIO_TABLE_SRC_DIR)/modules/acq_pm \ + -I$(SMIO_TABLE_SRC_DIR)/modules/init \ -I${PREFIX}/include # Merge all flags. We expect tghese variables to be appended to the possible @@ -194,7 +197,8 @@ $(LIBNAME)_SMIO_CODES = $(SMIO_DIR)/include/sm_io_fmc130m_4ch_codes.h \ $(SMIO_DIR)/include/sm_io_trigger_iface_codes.h \ $(SMIO_DIR)/include/sm_io_trigger_mux_codes.h \ $(SMIO_DIR)/include/sm_io_afc_timing_codes.h \ - $(SMIO_DIR)/include/sm_io_acq_pm_codes.h \ + $(SMIO_DIR)/include/sm_io_acq_pm_codes.h \ + $(SMIO_DIR)/include/sm_io_init_codes.h \ $(SMIO_TABLE_DIR)/include/sm_io_codes.h $(LIBNAME)_SMIO_EXPORTS = $(SMIO_TABLE_DIR)/include/sm_io_fmc130m_4ch_exports.h \ @@ -209,7 +213,8 @@ $(LIBNAME)_SMIO_EXPORTS = $(SMIO_TABLE_DIR)/include/sm_io_fmc130m_4ch_exports.h $(SMIO_TABLE_DIR)/include/sm_io_afc_diag_exports.h \ $(SMIO_TABLE_DIR)/include/sm_io_trigger_iface_exports.h \ $(SMIO_TABLE_DIR)/include/sm_io_trigger_mux_exports.h \ - $(SMIO_TABLE_DIR)/include/sm_io_acq_pm_exports.h \ + $(SMIO_TABLE_DIR)/include/sm_io_acq_pm_exports.h \ + $(SMIO_TABLE_DIR)/include/sm_io_init_exports.h \ $(SMIO_TABLE_DIR)/include/sm_io_afc_timing_exports.h # Copy specific acq_chan.h defintions according to the BOARD MACRO diff --git a/libs/halcsclient/build.gradle b/libs/halcsclient/build.gradle index 010d9fab..8ced98e0 100644 --- a/libs/halcsclient/build.gradle +++ b/libs/halcsclient/build.gradle @@ -1,10 +1,8 @@ import org.ajoberstar.gradle.git.release.opinion.Strategies +import br.lnls.dig.gradle.updatesemvermacrostask.UpdateSemVerMacrosTask -plugins { - id 'org.ajoberstar.grgit' version '1.6.0' - id 'org.ajoberstar.release-opinion' version '1.6.0' -} - +apply plugin: 'org.ajoberstar.grgit' +apply plugin: 'org.ajoberstar.release-opinion' apply plugin: br.lnls.dig.gradle.nativedistribution.plugins.NativeDistributionPlugin apply plugin: 'br.lnls.dig.gradle.nativerelease' apply plugin: com.janitovff.grgit.config.GitConfigPlugin @@ -44,3 +42,8 @@ release { allowDirtyRepo: true ) } + +task updateVersionMacros(type: UpdateSemVerMacrosTask) { + macroPrefix 'HALCS_CLIENT_VERSION_' + file project.file('include/halcs_client_classes.h') +} diff --git a/libs/halcsclient/include/halcs_client_classes.h b/libs/halcsclient/include/halcs_client_classes.h index 683e1c56..d08c7bd6 100644 --- a/libs/halcsclient/include/halcs_client_classes.h +++ b/libs/halcsclient/include/halcs_client_classes.h @@ -25,8 +25,8 @@ /* HALCS version macros for compile-time API detection */ #define HALCS_CLIENT_VERSION_MAJOR 0 -#define HALCS_CLIENT_VERSION_MINOR 1 -#define HALCS_CLIENT_VERSION_PATCH 0 +#define HALCS_CLIENT_VERSION_MINOR 5 +#define HALCS_CLIENT_VERSION_PATCH 1 #define HALCS_CLIENT_MAKE_VERSION(major, minor, patch) \ ((major) * 10000 + (minor) * 100 + (patch)) diff --git a/libs/halcsclient/include/halcs_client_core.h b/libs/halcsclient/include/halcs_client_core.h index 4c958003..00ada360 100644 --- a/libs/halcsclient/include/halcs_client_core.h +++ b/libs/halcsclient/include/halcs_client_core.h @@ -144,6 +144,15 @@ halcs_client_err_e halcs_get_fmc_clk_sel (halcs_client_t *self, char *service, halcs_client_err_e halcs_set_rst_isla216p (halcs_client_t *self, char *service, uint32_t rst_isla216p); +/* RST SWAP Functions. Set the SWAP module to reset itself + * 0: nothing + * 1: reset SWAP module + * + * Returns HALCS_CLIENT_SUCCESS if ok and HALCS_CLIIENT_ERR_SERVER if + * if server could not complete the request */ +halcs_client_err_e halcs_set_rst_swap (halcs_client_t *self, char *service, + uint32_t rst_swap); + /* ADC LTC2208 Control */ /* These set of functions read (get) or write (set) some ADC LTC2208 * functionalities. Check LTC2208 datasheet for details. @@ -560,6 +569,10 @@ halcs_client_err_e halcs_get_reg_adc (halcs_client_t *self, char *service, halcs_client_err_e halcs_get_temp_adc (halcs_client_t *self, char *service, uint32_t chan, uint32_t *temp); +/* get ISLA216P calibration status */ +halcs_client_err_e halcs_get_cal_status_adc (halcs_client_t *self, char *service, + uint32_t chan, uint32_t *cal_status); + /********************** FMCPICO1M_4CH Functions ********************/ /* FMC board LEDs Control */ @@ -1259,6 +1272,17 @@ halcs_client_err_e afc_timing_set_afc_hs_div (halcs_client_t *self, char *servic halcs_client_err_e afc_timing_get_afc_hs_div (halcs_client_t *self, char *service, uint32_t *afc_hs_div); +/********************** INIT Functions ********************/ + +/* Init Check function */ +/* This function is used so a client can be sure everything is initialized properly + * and a HALCS is ready go. The functions returns + * HALCS_CLIENT_SUCCESS if the parameter was correctly set or error + * (see halcs_client_err.h for all possible errors)*/ + +halcs_client_err_e halcs_get_init_check (halcs_client_t *self, char *service, + uint32_t *init_check_out); + #ifdef __cplusplus } #endif diff --git a/libs/halcsclient/include/halcs_client_rw_param.h b/libs/halcsclient/include/halcs_client_rw_param.h index 635238c7..d14fae5b 100644 --- a/libs/halcsclient/include/halcs_client_rw_param.h +++ b/libs/halcsclient/include/halcs_client_rw_param.h @@ -143,7 +143,7 @@ halcs_client_err_e param_client_write_read_double (halcs_client_t *self, char *s uint32_t operation, double param1, double *param_out); /* Utility functions */ -zmsg_t *param_client_recv_timeout (halcs_client_t *self); +zmsg_t *param_client_recv_timeout (halcs_client_t *self, char *service); #ifdef __cplusplus } diff --git a/libs/halcsclient/src/halcsclient/c/halcs_client_core.c b/libs/halcsclient/src/halcsclient/c/halcs_client_core.c index a096d22d..50bac004 100644 --- a/libs/halcsclient/src/halcsclient/c/halcs_client_core.c +++ b/libs/halcsclient/src/halcsclient/c/halcs_client_core.c @@ -36,8 +36,8 @@ halcs_client_err_str (err_type)) #define HALCSCLIENT_DFLT_LOG_MODE "w" -#define HALCSCLIENT_MLM_CONNECT_TIMEOUT 1000 /* in ms */ -#define HALCSCLIENT_DFLT_TIMEOUT 1000 /* in ms */ +#define HALCSCLIENT_MLM_CONNECT_TIMEOUT 5000 /* in ms */ +#define HALCSCLIENT_DFLT_TIMEOUT 5000 /* in ms */ /* Our structure */ struct _halcs_client_t { @@ -132,12 +132,15 @@ static halcs_client_t *_halcs_client_new (char *broker_endp, int verbose, * We accept NULL as a parameter, meaning to suppress all messages */ errhand_log_new (log_file_name, log_mode); - DBE_DEBUG (DBG_LIB_CLIENT | DBG_LVL_INFO, "[libclient] Spawing LIBHALCSCLIENT" + /* No CZMQ logs by default */ + zsys_set_logstream (NULL); + + DBE_DEBUG (DBG_LIB_CLIENT | DBG_LVL_TRACE, "[libclient] Spawing LIBHALCSCLIENT" " with broker address %s, with logfile on %s ...\n", broker_endp, (log_file_name == NULL) ? "NULL" : log_file_name); /* Print Software info */ - DBE_DEBUG (DBG_LIB_CLIENT | DBG_LVL_INFO, "[libclient] HALCS Client version %s," + DBE_DEBUG (DBG_LIB_CLIENT | DBG_LVL_TRACE, "[libclient] HALCS Client version %s," " Build by: %s, %s\n", revision_get_build_version (), revision_get_build_user_name (), @@ -224,7 +227,7 @@ halcs_client_err_e halcs_func_exec_size (halcs_client_t *self, const disp_op_t * mlm_client_sendto (self->mlm_client, service, NULL, NULL, 0, &msg); /* Receive report */ - zmsg_t *report = param_client_recv_timeout (self); + zmsg_t *report = param_client_recv_timeout (self, service); ASSERT_TEST(report != NULL, "Report received is NULL", err_msg); /* Message is: @@ -424,6 +427,12 @@ PARAM_FUNC_CLIENT_WRITE(rst_isla216p) rst_isla216p); } +PARAM_FUNC_CLIENT_WRITE(rst_swap) +{ + return param_client_write (self, service, FMC_ACTIVE_CLK_OPCODE_RST_SWAP, + rst_swap); +} + PARAM_FUNC_CLIENT_WRITE(si571_oe) { return param_client_write (self, service, FMC_ACTIVE_CLK_OPCODE_SI571_OE, si571_oe); @@ -948,6 +957,13 @@ PARAM_FUNC_CLIENT_WRITE_READ(temp_adc, chan, temp) chan, temp); } +/* ISLA216P calibration status */ +PARAM_FUNC_CLIENT_WRITE_READ(cal_status_adc, chan, cal_status) +{ + return param_client_write_read (self, service, FMC250M_4CH_OPCODE_CAL_STATUS, + chan, cal_status); +} + /****************** FMC250M Delay Value Functions ****************/ /* ADC delay value 0 */ @@ -1735,8 +1751,9 @@ halcs_client_err_e halcs_get_afc_diag_build_revision (halcs_client_t *self, char struct _smio_afc_diag_revision_data_t *revision_data) { uint32_t rw = READ_MODE; + uint32_t dummy = 0; return param_client_read_gen (self, service, AFC_DIAG_OPCODE_GET_BUILD_REVISION, - rw, revision_data, sizeof (*revision_data), NULL, 0, NULL, 0, + rw, &dummy, sizeof (dummy), NULL, 0, NULL, 0, revision_data, sizeof (*revision_data)); } @@ -1745,8 +1762,9 @@ halcs_client_err_e halcs_get_afc_diag_build_date (halcs_client_t *self, char *se struct _smio_afc_diag_revision_data_t *revision_data) { uint32_t rw = READ_MODE; + uint32_t dummy = 0; return param_client_read_gen (self, service, AFC_DIAG_OPCODE_GET_BUILD_DATE, - rw, revision_data, sizeof (*revision_data), NULL, 0, NULL, 0, + rw, &dummy, sizeof (dummy), NULL, 0, NULL, 0, revision_data, sizeof (*revision_data)); } @@ -1755,8 +1773,9 @@ halcs_client_err_e halcs_get_afc_diag_build_user_name (halcs_client_t *self, cha struct _smio_afc_diag_revision_data_t *revision_data) { uint32_t rw = READ_MODE; + uint32_t dummy = 0; return param_client_read_gen (self, service, AFC_DIAG_OPCODE_GET_BUILD_USER_NAME, - rw, revision_data, sizeof (*revision_data), NULL, 0, NULL, 0, + rw, &dummy, sizeof (dummy), NULL, 0, NULL, 0, revision_data, sizeof (*revision_data)); } @@ -1765,8 +1784,9 @@ halcs_client_err_e halcs_get_afc_diag_build_user_email (halcs_client_t *self, ch struct _smio_afc_diag_revision_data_t *revision_data) { uint32_t rw = READ_MODE; + uint32_t dummy = 0; return param_client_read_gen (self, service, AFC_DIAG_OPCODE_GET_BUILD_USER_EMAIL, - rw, revision_data, sizeof (*revision_data), NULL, 0, NULL, 0, + rw, &dummy, sizeof (dummy), NULL, 0, NULL, 0, revision_data, sizeof (*revision_data)); } @@ -2388,3 +2408,11 @@ PARAM_FUNC_CLIENT_READ_MOD(afc_timing, afc_hs_div) return param_client_read (self, service, AFC_TIMING_OPCODE_SET_GET_AFC_HS_DIV, afc_hs_div); } +/**************** INIT SMIO Functions ****************/ + +/* Init function */ +PARAM_FUNC_CLIENT_READ(init_check) +{ + return param_client_read (self, service, INIT_OPCODE_SET_GET_CHECK, init_check); +} + diff --git a/libs/halcsclient/src/halcsclient/c/halcs_client_rw_param.c b/libs/halcsclient/src/halcsclient/c/halcs_client_rw_param.c index d86e4c51..757a7101 100644 --- a/libs/halcsclient/src/halcsclient/c/halcs_client_rw_param.c +++ b/libs/halcsclient/src/halcsclient/c/halcs_client_rw_param.c @@ -85,7 +85,7 @@ halcs_client_err_e param_client_recv_rw (halcs_client_t *self, char *service, mlm_client_t *client = halcs_get_mlm_client (self); ASSERT_TEST(client != NULL, "Could not get HALCS client handler", err_get_handler, HALCS_CLIENT_ERR_SERVER); - *report = param_client_recv_timeout (self); + *report = param_client_recv_timeout (self, service); ASSERT_TEST(*report != NULL, "Could not receive message", err_null_msg, HALCS_CLIENT_ERR_SERVER); @@ -115,6 +115,10 @@ halcs_client_err_e param_client_write_gen (halcs_client_t *self, char *service, /* Handling malformed messages */ size_t msg_size = zmsg_size (report); + if (msg_size != MSG_ERR_CODE_SIZE) { + DBE_DEBUG (DBG_LIB_CLIENT | DBG_LVL_FATAL, "[libclient] " + "param_client_write_gen: msg_size = %zu != %u\n", msg_size, MSG_ERR_CODE_SIZE); + } ASSERT_TEST(msg_size == MSG_ERR_CODE_SIZE, "Unexpected message received", err_msg); /* Get message contents */ @@ -221,6 +225,11 @@ halcs_client_err_e param_client_read_gen (halcs_client_t *self, char *service, /* Handling malformed messages */ size_t msg_size = zmsg_size (report); + if (msg_size != MSG_ERR_CODE_SIZE && msg_size != MSG_FULL_SIZE) { + DBE_DEBUG (DBG_LIB_CLIENT | DBG_LVL_FATAL, "[libclient] " + "param_client_read_gen: msg_size = %zu != %u and != %u\n", + msg_size, MSG_ERR_CODE_SIZE, MSG_FULL_SIZE); + } ASSERT_TEST(msg_size == MSG_ERR_CODE_SIZE || msg_size == MSG_FULL_SIZE, "Unexpected message received", err_msg); @@ -325,7 +334,7 @@ halcs_client_err_e param_client_write_read_double (halcs_client_t *self, char *s /********************* Utility functions ************************************/ /* Wait for message to arrive up to timeout msecs */ -zmsg_t *param_client_recv_timeout (halcs_client_t *self) +zmsg_t *param_client_recv_timeout (halcs_client_t *self, char *service) { zmsg_t *msg = NULL; @@ -350,7 +359,27 @@ zmsg_t *param_client_recv_timeout (halcs_client_t *self) /* Check for activity socket */ if (which == msgpipe) { - msg = mlm_client_recv (halcs_get_mlm_client (self)); + mlm_client_t *mlm_client = halcs_get_mlm_client (self); + msg = mlm_client_recv (mlm_client); + const char *mlm_sender = mlm_client_sender (mlm_client); + + /* Check if the message is for the service we are expecting. + * This can happen, for instance, if the same client is used to + * talk to more than 1 service. Depending on the server load, + * we can expect a message for a service 1, but receive the message + * for the service 2. One workaround to this is to use a single + * instance of the library per service */ + if (!streq (mlm_sender, service)) { + /* free received message and warn caller */ + zmsg_destroy (&msg); + DBE_DEBUG (DBG_LIB_CLIENT | DBG_LVL_FATAL, "[libclient] " + "param_client_recv_timeout: Unexpected sender %s, waiting for %s\n", + mlm_sender, service); + } + } + else { + DBE_DEBUG (DBG_LIB_CLIENT | DBG_LVL_FATAL, "[libclient] " + "param_client_recv_timeout: poller returned invalid socket to recv ()\n"); } err_poller_invalid: diff --git a/libs/hutils/build.gradle b/libs/hutils/build.gradle index 1066e74d..7b0459ea 100644 --- a/libs/hutils/build.gradle +++ b/libs/hutils/build.gradle @@ -1,3 +1,5 @@ +import br.lnls.dig.gradle.updatesemvermacrostask.UpdateSemVerMacrosTask + apply plugin: br.lnls.dig.gradle.nativedistribution.plugins.NativeDistributionPlugin apply plugin: 'br.lnls.dig.gradle.nativerelease' @@ -15,3 +17,8 @@ model { } } } + +task updateVersionMacros(type: UpdateSemVerMacrosTask) { + macroPrefix 'HUTILS_VERSION_' + file project.file('include/hutils_classes.h') +} diff --git a/libs/hutils/include/hutils_classes.h b/libs/hutils/include/hutils_classes.h index d92f71f1..303d67fb 100644 --- a/libs/hutils/include/hutils_classes.h +++ b/libs/hutils/include/hutils_classes.h @@ -18,8 +18,8 @@ /* version macros for compile-time API detection */ #define HUTILS_VERSION_MAJOR 0 -#define HUTILS_VERSION_MINOR 1 -#define HUTILS_VERSION_PATCH 0 +#define HUTILS_VERSION_MINOR 5 +#define HUTILS_VERSION_PATCH 1 #define HUTILS_MAKE_VERSION(major, minor, patch) \ ((major) * 10000 + (minor) * 100 + (patch)) diff --git a/libs/llio/build.gradle b/libs/llio/build.gradle index 1e767fbb..5abb16e3 100644 --- a/libs/llio/build.gradle +++ b/libs/llio/build.gradle @@ -1,3 +1,5 @@ +import br.lnls.dig.gradle.updatesemvermacrostask.UpdateSemVerMacrosTask + apply plugin: br.lnls.dig.gradle.nativedistribution.plugins.NativeDistributionPlugin apply plugin: 'br.lnls.dig.gradle.nativerelease' @@ -19,3 +21,8 @@ model { } } } + +task updateVersionMacros(type: UpdateSemVerMacrosTask) { + macroPrefix 'LL_IO_VERSION_' + file project.file('include/ll_io_classes.h') +} diff --git a/libs/llio/include/hw/pcie_regs.h b/libs/llio/include/hw/pcie_regs.h index 20e73157..a05967e1 100644 --- a/libs/llio/include/hw/pcie_regs.h +++ b/libs/llio/include/hw/pcie_regs.h @@ -186,7 +186,7 @@ #define PCIE_CFG_DMA_CTRL_AINC WBGEN2_PCIE_GEN_MASK(PCIE_CFG_DMA_CTRL_AINC_SHIFT, \ PCIE_CFG_DMA_CTRL_AINC_SIZE) -#define PCIE_CFG_DMA_CTRL_BAR_SIZE 2 +#define PCIE_CFG_DMA_CTRL_BAR_SIZE 3 #define PCIE_CFG_DMA_CTRL_BAR_SHIFT 16 #define PCIE_CFG_DMA_CTRL_BAR_MASK WBGEN2_PCIE_GEN_MASK(PCIE_CFG_DMA_CTRL_BAR_SHIFT, \ PCIE_CFG_DMA_CTRL_BAR_SIZE) diff --git a/libs/llio/include/ll_io_classes.h b/libs/llio/include/ll_io_classes.h index 948ccc9b..4878f749 100644 --- a/libs/llio/include/ll_io_classes.h +++ b/libs/llio/include/ll_io_classes.h @@ -19,8 +19,8 @@ /* HALCS version macros for compile-time API detection */ #define LL_IO_VERSION_MAJOR 0 -#define LL_IO_VERSION_MINOR 1 -#define LL_IO_VERSION_PATCH 0 +#define LL_IO_VERSION_MINOR 5 +#define LL_IO_VERSION_PATCH 1 #define LL_IO_MAKE_VERSION(major, minor, patch) \ ((major) * 10000 + (minor) * 100 + (patch)) diff --git a/libs/llio/include/ll_io_core.h b/libs/llio/include/ll_io_core.h index 3601f444..592af434 100644 --- a/libs/llio/include/ll_io_core.h +++ b/libs/llio/include/ll_io_core.h @@ -14,6 +14,8 @@ extern "C" { /* Open device function pointer */ typedef int (*open_fp)(llio_t *self, llio_endpoint_t *endpoint); +/* Reset device function pointer */ +typedef int (*reset_fp)(llio_t *self); /* Release device function pointer */ typedef int (*release_fp)(llio_t *self, llio_endpoint_t *endpoint); /* Read data from device function pointers */ @@ -40,6 +42,7 @@ typedef struct { /* Operations */ open_fp open; /* Open device */ + reset_fp reset; /* Reset device */ release_fp release; /* Release device */ read_16_fp read_16; /* Read 16-bit data */ read_32_fp read_32; /* Read 32-bit data */ @@ -98,6 +101,8 @@ uint64_t llio_get_sdb_prefix_addr (llio_t *self); /* Open device */ int llio_open (llio_t *self, llio_endpoint_t *endpoint); +/* Reset device */ +int llio_reset (llio_t *self); /* Release device */ int llio_release (llio_t *self, llio_endpoint_t *endpoint); /* Read data from device */ diff --git a/libs/llio/src/llio/c/ll_io_core.c b/libs/llio/src/llio/c/ll_io_core.c index caa15531..fff2f58e 100644 --- a/libs/llio/src/llio/c/ll_io_core.c +++ b/libs/llio/src/llio/c/ll_io_core.c @@ -265,6 +265,10 @@ static llio_err_e _llio_unregister_ops (const llio_ops_t **ops) int llio_open (llio_t *self, llio_endpoint_t *endpoint) LLIO_FUNC_WRAPPER (open, endpoint) +/**** Reset device ****/ +int llio_reset (llio_t *self) + LLIO_FUNC_WRAPPER (reset) + /**** Release device ****/ int llio_release (llio_t *self, llio_endpoint_t *endpoint) LLIO_FUNC_WRAPPER (release, endpoint) diff --git a/libs/llio/src/llio/c/ops/ll_io_eth.c b/libs/llio/src/llio/c/ops/ll_io_eth.c index 52d2bea2..a4508561 100644 --- a/libs/llio/src/llio/c/ops/ll_io_eth.c +++ b/libs/llio/src/llio/c/ops/ll_io_eth.c @@ -45,6 +45,10 @@ #define LLIO_ETH_REGEX_ADDR_HIT 2 #define LLIO_ETH_REGEX_PORT_HIT 3 +#define LLIO_ETH_MAX_RECONNECT_TRIES 1 +#define LLIO_ETH_SECS_BEFORE_RECONNECT 1 +#define LLIO_ETH_SECS_BEFORE_RECV_TIMEOUT 1 + /* Device endpoint */ typedef struct { llio_eth_type_e type; @@ -59,9 +63,9 @@ static void *_get_in_addr(struct sockaddr *sa); static ssize_t _eth_sendall (int fd, uint8_t *buf, size_t len); static ssize_t _eth_recvall (int fd, uint8_t *buf, size_t len); static ssize_t _eth_read_generic (llio_t *self, uint64_t offs, uint32_t *data, - size_t size); + size_t size, bool auto_reconnect); static ssize_t _eth_write_generic (llio_t *self, uint64_t offs, const uint32_t *data, - size_t size); + size_t size, bool auto_reconnect); /************ Our methods implementation **********/ @@ -236,6 +240,7 @@ static int eth_release (llio_t *self, llio_endpoint_t *endpoint) * is initialized on eth_open (), so the proper place to * destroy it is here, not on llio_dev_eth_destroy () */ close (dev_eth->fd); + dev_eth->fd = -1; /* Deattach specific device handler to generic one */ lerr = llio_dev_eth_destroy (&dev_eth); @@ -260,81 +265,139 @@ static int eth_release (llio_t *self, llio_endpoint_t *endpoint) static ssize_t eth_read_16 (llio_t *self, uint64_t offs, uint16_t *data) { return _eth_read_generic (self, offs, (uint32_t *) data, - sizeof (*data)); + sizeof (*data), true); } static ssize_t eth_read_32 (llio_t *self, uint64_t offs, uint32_t *data) { return _eth_read_generic (self, offs, (uint32_t *) data, - sizeof (*data)); + sizeof (*data), true); } static ssize_t eth_read_64 (llio_t *self, uint64_t offs, uint64_t *data) { return _eth_read_generic (self, offs, (uint32_t *) data, - sizeof (*data)); + sizeof (*data), true); } /* Write data to Eth device */ static ssize_t eth_write_16 (llio_t *self, uint64_t offs, const uint16_t *data) { return _eth_write_generic (self, offs, (const uint32_t *) data, - sizeof (*data)); + sizeof (*data), true); } static ssize_t eth_write_32 (llio_t *self, uint64_t offs, const uint32_t *data) { return _eth_write_generic (self, offs, (const uint32_t *) data, - sizeof (*data)); + sizeof (*data), true); } static ssize_t eth_write_64 (llio_t *self, uint64_t offs, const uint64_t *data) { return _eth_write_generic (self, offs, (const uint32_t *) data, - sizeof (*data)); + sizeof (*data), true); } /* Read data block from Eth device, size in bytes */ static ssize_t eth_read_block (llio_t *self, uint64_t offs, size_t size, uint32_t *data) { - return _eth_read_generic (self, offs, data, size); + return _eth_read_generic (self, offs, data, size, true); } /* Write data block to Eth device, size in bytes */ ssize_t eth_write_block (llio_t *self, uint64_t offs, size_t size, uint32_t *data) { - return _eth_write_generic (self, offs, data, size); + return _eth_write_generic (self, offs, data, size, true); } /******************************* Static Functions *****************************/ static ssize_t _eth_read_generic (llio_t *self, uint64_t offs, uint32_t *data, - size_t size) + size_t size, bool auto_reconnect) { UNUSED(offs); ssize_t err = 0; + size_t retries = (auto_reconnect) ? LLIO_ETH_MAX_RECONNECT_TRIES : 0; llio_dev_eth_t *dev_eth = llio_get_dev_handler (self); ASSERT_TEST(dev_eth != NULL, "Could not get ETH handler", err_dev_eth_handler, -1); err = _eth_recvall (dev_eth->fd, (uint8_t *) data, size); + /* If we got an error, try reconnecting and try up to + * LLIO_ETH_MAX_RECONNECT_TRIES or forever if retries == -1*/ + while (err < 0) { + if (retries == 0) { + break; + } + + /* Only decrement if we are in finite waiting mode */ + if (retries > 0) { + retries--; + } + + /* cleanup and try again */ + close (dev_eth->fd); + dev_eth->fd = -1; + err = _llio_eth_conn (&dev_eth->fd, dev_eth->type, + dev_eth->hostname, dev_eth->port); + /* keep retrying */ + if (err < 0) { + DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE, + "[ll_io_eth] Error connecting to endpoint during recv (). " + "Retrying in %u seconds\n", + LLIO_ETH_SECS_BEFORE_RECONNECT); + continue; + } + + err = _eth_recvall (dev_eth->fd, (uint8_t *) data, size); + } err_dev_eth_handler: return err; } static ssize_t _eth_write_generic (llio_t *self, uint64_t offs, const uint32_t *data, - size_t size) + size_t size, bool auto_reconnect) { UNUSED(offs); ssize_t err = 0; + size_t retries = (auto_reconnect) ? LLIO_ETH_MAX_RECONNECT_TRIES : 0; llio_dev_eth_t *dev_eth = llio_get_dev_handler (self); ASSERT_TEST(dev_eth != NULL, "Could not get ETH handler", err_dev_eth_handler, -1); err = _eth_sendall (dev_eth->fd, (uint8_t *) data, size); + /* If we got an error, try reconnecting and try up to + * LLIO_ETH_MAX_RECONNECT_TRIES or forever if retries == -1*/ + while (err < 0) { + if (retries == 0) { + break; + } + + /* Only decrement if we are in finite waiting mode */ + if (retries > 0) { + retries--; + } + + /* cleanup and try again */ + close (dev_eth->fd); + dev_eth->fd = -1; + err = _llio_eth_conn (&dev_eth->fd, dev_eth->type, + dev_eth->hostname, dev_eth->port); + /* keep retrying */ + if (err < 0) { + DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE, + "[ll_io_eth] Error connecting to endpoint during send (). " + "Retrying in %u seconds\n", + LLIO_ETH_SECS_BEFORE_RECONNECT); + continue; + } + + err = _eth_sendall (dev_eth->fd, (uint8_t *) data, size); + } err_dev_eth_handler: return err; @@ -349,6 +412,11 @@ static int _llio_eth_conn (int *fd, llio_eth_type_e type, char *hostname, struct addrinfo hints, *servinfo, *p; int rv; char s[INET6_ADDRSTRLEN]; + long arg; + fd_set myset; + struct timeval tv; + int valopt; + socklen_t lon; int yes = 1; /* Ignored for now */ @@ -382,11 +450,60 @@ static int _llio_eth_conn (int *fd, llio_eth_type_e type, char *hostname, ASSERT_TEST (rv == 0, "Could not set endpoint options", err_setsockopt, -1); - if (connect(*fd, p->ai_addr, p->ai_addrlen) == -1) { - DBE_DEBUG (DBG_LL_IO | DBG_LVL_ERR, - "[ll_io_eth] Error executing connect: %s\n", strerror(errno)); - close(*fd); - continue; + /* Set non-blocking connection. Based on + * http://developerweb.net/viewtopic.php?id=3196 */ + arg = fcntl (*fd, F_GETFL, NULL); + ASSERT_TEST (arg >= 0, "Could not get socket FD options", + err_get_fcntl, -1); + arg |= O_NONBLOCK; + rv = fcntl (*fd, F_SETFL, arg); + ASSERT_TEST (rv >= 0, "Could not set socket FD options", + err_set_fcntl, -1); + + /* Trying to connect with timeout */ + rv = connect(*fd, p->ai_addr, p->ai_addrlen); + if (rv < 0) { + if (errno != EINPROGRESS) { + DBE_DEBUG (DBG_LL_IO | DBG_LVL_FATAL, + "[ll_io_eth] Error connecting is not EINPROGRESS: %d - %s\n", errno, strerror(errno)); + close (*fd); + *fd = -1; + continue; + } + + DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE, + "[ll_io_eth] EINPROGRESS in connect() - selecting\n"); + tv.tv_sec = LLIO_ETH_SECS_BEFORE_RECONNECT; + tv.tv_usec = 0; + FD_ZERO (&myset); + FD_SET (*fd, &myset); + + rv = select (*fd+1, NULL, &myset, NULL, &tv); + if (rv < 0) { + DBE_DEBUG (DBG_LL_IO | DBG_LVL_FATAL, + "[ll_io_eth] Error connecting: %d - %s\n", errno, strerror(errno)); + err = -1; + goto err_select1; + } + + if (rv == 0) { + DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE, + "[ll_io_eth] Timeout in connecting\n"); + err = -1; + goto err_select2; + } + + /* Check if socket is opened succesfully */ + lon = sizeof(int); + rv = getsockopt (*fd, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon); + ASSERT_TEST (rv >= 0, "Could not get socket options", + err_getsockopt, -1); + if (valopt) { + DBE_DEBUG (DBG_LL_IO | DBG_LVL_FATAL, + "[ll_io_eth] Error in delayed connection:%d - %s\n", valopt, strerror(valopt)); + err = -1; + goto err_valopt; + } } break; @@ -394,6 +511,15 @@ static int _llio_eth_conn (int *fd, llio_eth_type_e type, char *hostname, ASSERT_TEST (p != NULL, "Could not connect", err_connect, -1); + /* Set sock to blocking-mode again */ + arg = fcntl (*fd, F_GETFL, NULL); + ASSERT_TEST (arg >= 0, "Could not get socket FD options", + err_get_fcntl2, -1); + arg &= (~O_NONBLOCK); + rv = fcntl (*fd, F_SETFL, arg); + ASSERT_TEST (rv >= 0, "Could not set socket FD options", + err_set_fcntl2, -1); + inet_ntop(p->ai_family, _get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof s); DBE_DEBUG (DBG_LL_IO | DBG_LVL_INFO, @@ -403,9 +529,18 @@ static int _llio_eth_conn (int *fd, llio_eth_type_e type, char *hostname, return err; +err_set_fcntl2: +err_get_fcntl2: err_connect: - close (*fd); +err_valopt: +err_getsockopt: +err_select2: +err_select1: +err_set_fcntl: +err_get_fcntl: err_setsockopt: + close (*fd); + *fd = -1; err_getaddrinfo: err_unsup: return err; @@ -450,10 +585,31 @@ static ssize_t _eth_recvall (int fd, uint8_t *buf, size_t len) size_t total = 0; /* how many bytes we've recv */ size_t bytesleft = len; /* how many we have left to recv */ ssize_t n; + fd_set myset; + struct timeval tv; + int rv = 0; DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE, "[ll_io_eth] Receiving %zu bytes\n", len); while (total < len) { + tv.tv_sec = LLIO_ETH_SECS_BEFORE_RECV_TIMEOUT; + tv.tv_usec = 0; + FD_ZERO (&myset); + FD_SET (fd, &myset); + + rv = select (fd+1, &myset, NULL, NULL, &tv); + if (rv < 0) { + DBE_DEBUG (DBG_LL_IO | DBG_LVL_FATAL, + "[ll_io_eth] Error on recv select (): %d - %s\n", errno, strerror(errno)); + return -1; + } + + if (rv == 0) { + DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE, + "[ll_io_eth] Timeout on recv (). Aborting...\n"); + return -1; + } + n = recv (fd, (char *) buf+total, bytesleft, 0); DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE, "[ll_io_eth] Received %zd bytes\n", n); diff --git a/libs/llio/src/llio/c/ops/ll_io_pcie.c b/libs/llio/src/llio/c/ops/ll_io_pcie.c index 534fb9a9..188eace2 100644 --- a/libs/llio/src/llio/c/ops/ll_io_pcie.c +++ b/libs/llio/src/llio/c/ops/ll_io_pcie.c @@ -238,6 +238,24 @@ static int pcie_open (llio_t *self, llio_endpoint_t *endpoint) return err; } +/* Open PCIe device */ +static int pcie_reset (llio_t *self) +{ + int err = 0; + ASSERT_TEST(llio_get_endpoint_open (self), "Could not reset LLIO. Device is not opened", + err_endp_open, -1); + + /* Reset FPGA */ + _pcie_reset_fpga (self); + /* Reset PCIe Timeout */ + _pcie_timeout_reset (self); + + return err; + +err_endp_open: + return err; +} + /* Release PCIe device */ static int pcie_release (llio_t *self, llio_endpoint_t *endpoint) { @@ -780,7 +798,7 @@ static int _pcie_reset_dma (llio_t *self, pcie_dev_dma_type_e dma_type) uint64_t dma_base_addr = BAR0_ADDR | _pcie_dma_base_addr (self, dma_type); uint64_t offs = dma_base_addr + PCIE_CFG_REG_DMA_CTRL; /* We must write the reset pattern + the valid bit */ - uint32_t data = PCIE_CFG_DMA_CTRL_VALID_SHIFT | PCIE_CFG_TX_CTRL_CHANNEL_RST; + uint32_t data = PCIE_CFG_DMA_CTRL_VALID | PCIE_CFG_TX_CTRL_CHANNEL_RST; return (_pcie_rw_32 (self, offs, &data, WRITE_TO_BAR) == sizeof (uint32_t) ? 0 : 1); } @@ -950,6 +968,7 @@ static int _pcie_reset_fpga (llio_t *self) const llio_ops_t llio_ops_pcie = { .name = "PCIE", /* Operations name */ .open = pcie_open, /* Open device */ + .reset = pcie_reset, /* Reset device */ .release = pcie_release, /* Release device */ .read_16 = NULL, /* Read 16-bit data */ .read_32 = pcie_read_32, /* Read 32-bit data */ diff --git a/libs/sdbutils/build.gradle b/libs/sdbutils/build.gradle index 7dd2fd97..44bc8407 100644 --- a/libs/sdbutils/build.gradle +++ b/libs/sdbutils/build.gradle @@ -1,3 +1,5 @@ +import br.lnls.dig.gradle.updatesemvermacrostask.UpdateSemVerMacrosTask + apply plugin: br.lnls.dig.gradle.nativedistribution.plugins.NativeDistributionPlugin apply plugin: 'br.lnls.dig.gradle.nativerelease' @@ -15,3 +17,8 @@ model { } } } + +task updateVersionMacros(type: UpdateSemVerMacrosTask) { + macroPrefix 'SDBUTILS_VERSION_' + file project.file('include/sdbutils_classes.h') +} diff --git a/libs/sdbutils/include/sdbutils_classes.h b/libs/sdbutils/include/sdbutils_classes.h index 0bb81b05..8613ccf1 100644 --- a/libs/sdbutils/include/sdbutils_classes.h +++ b/libs/sdbutils/include/sdbutils_classes.h @@ -16,8 +16,8 @@ /* version macros for compile-time API detection */ #define SDBUTILS_VERSION_MAJOR 0 -#define SDBUTILS_VERSION_MINOR 1 -#define SDBUTILS_VERSION_PATCH 0 +#define SDBUTILS_VERSION_MINOR 5 +#define SDBUTILS_VERSION_PATCH 1 #define SDBUTILS_MAKE_VERSION(major, minor, patch) \ ((major) * 10000 + (minor) * 100 + (patch)) diff --git a/scripts/test-acq.sh b/scripts/test-acq.sh new file mode 100755 index 00000000..045af222 --- /dev/null +++ b/scripts/test-acq.sh @@ -0,0 +1,16 @@ +#!/bin/env bash + +set -a +set -e +set -u + +BOARD_INIT=$1 +BOARD_END=$2 + +for i in `seq ${BOARD_INIT} ${BOARD_END}`; do + for j in `seq 0 1`; do + echo "acq $i $j: "; + /root/postinstall/apps/bpm-app/halcs/examples/build/exe/acq/production/afcv3_1/acq -b \ + ipc:///tmp/malamute -o $i -s $j -c 0 -n 10 -f 0; + done; +done diff --git a/sonar-project.properties b/sonar-project.properties index cd4662a1..73d7a3c7 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,6 +1,6 @@ sonar.projectKey=br.com.lnls.dig.halcs sonar.projectName=HALCS Hardware Abstraction Layer for Control Systems -sonar.projectVersion=v0.4 +sonar.projectVersion=v0.5 # ===================================================== # Meta-data for the project @@ -15,10 +15,9 @@ sonar.links.issue=https://github.com/lnls-dig/halcs/issues # Properties that will be shared amongst all modules # ===================================================== -sonar.branch=master, devel, sonarqube-integration - # SQ standard properties sonar.sources=apps, core, doc, examples, foreign/libsdbfs, libs, linker, scripts, tests +sonar.branch=devel # Properties specific to the C/C++ analyzer: sonar.cfamily.build-wrapper-output=bw-output