From 3bf71c66f63f33471b172570a3a20710d6fe6b72 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Fri, 1 Jul 2016 09:21:18 +0200 Subject: o Initial commit. --- .gitignore | 5 + CMakeLists.txt | 8 ++ NOTES.md | 26 +++++ apps/CMakeLists.txt | 2 + apps/accel/CMakeLists.txt | 3 + apps/accel/main.c | 107 +++++++++++++++++++ apps/magneto/CMakeLists.txt | 4 + apps/magneto/main.c | 146 ++++++++++++++++++++++++++ cmake/intel-quark-d2000.toolchain.cmake | 176 ++++++++++++++++++++++++++++++++ setup-env.sh | 21 ++++ 10 files changed, 498 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 NOTES.md create mode 100644 apps/CMakeLists.txt create mode 100644 apps/accel/CMakeLists.txt create mode 100644 apps/accel/main.c create mode 100644 apps/magneto/CMakeLists.txt create mode 100644 apps/magneto/main.c create mode 100644 cmake/intel-quark-d2000.toolchain.cmake create mode 100644 setup-env.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1f934ca --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/build +/build-* +/.idea +.gdb_history +*.tmp.* diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f6b6147 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.5) + +set(INTEL_QUARK_CHIP D2000) +set(CMAKE_TOOLCHAIN_FILE "${CMAKE_SOURCE_DIR}/cmake/intel-quark-d2000.toolchain.cmake") + +project(intel_quark_d2000_playground C) + +add_subdirectory(apps) diff --git a/NOTES.md b/NOTES.md new file mode 100644 index 0000000..8e8a329 --- /dev/null +++ b/NOTES.md @@ -0,0 +1,26 @@ +# Uploading + +From https://software.intel.com/en-us/node/604844: + + target remote localhost:3333 + monitor gdb_breakpoint_override hard + set remotetimeout 30 + monitor clk32M + file ISSM_BSP_ROOT/examples/accel/debug/quark_d2000/obj/accel.elf + load + monitor reset halt + flushregs + tb main + c + +A useful openocd launch command: + + openocd -s $ISSM/tools/debugger/openocd/scripts -f board/quark_d2000_onboard.cfg + +A useful gdb launch command: + + gdb-ia -ex "target remote localhost:3333" \ + -ex "monitor gdb_breakpoint_override hard" \ + -ex "set remotetimeout 30" \ + -ex "monitor clk32M" \ + -ex "monitor reset halt" diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt new file mode 100644 index 0000000..973af05 --- /dev/null +++ b/apps/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(accel) +#add_subdirectory(magneto) diff --git a/apps/accel/CMakeLists.txt b/apps/accel/CMakeLists.txt new file mode 100644 index 0000000..91f1497 --- /dev/null +++ b/apps/accel/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(accel main.c) +set_target_properties(accel PROPERTIES CHIP QUARK_D2000) +toolchain_target(accel) diff --git a/apps/accel/main.c b/apps/accel/main.c new file mode 100644 index 0000000..b27b2b4 --- /dev/null +++ b/apps/accel/main.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2015, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#if (__IPP_ENABLED__) +#include "dsp.h" +#endif + +#include "qm_interrupt.h" +#include "qm_rtc.h" + +#include "bmc150/bmc150.h" + +#define ALARM (QM_RTC_ALARM_SECOND >> 3) + +#if (__IPP_ENABLED__) +#define SAMPLES_SIZE 15 + +static float32_t samples[SAMPLES_SIZE]; + +static void print_axis_stats(int16_t value) +{ + static uint16_t index = 0; + static uint16_t count = 0; + float32_t mean, var, rms; + + samples[index] = value; + index = (index + 1) % SAMPLES_SIZE; + + count = count == SAMPLES_SIZE ? SAMPLES_SIZE : count + 1; + + ippsq_rms_f32(samples, count, &rms); + ippsq_var_f32(samples, count, &var); + ippsq_mean_f32(samples, count, &mean); + + QM_PRINTF("rms %d var %d mean %d\n", (int) rms, (int) var, (int) mean); +} +#endif + +static void print_accel_callback(void) +{ + bmc150_accel_t accel = {0}; + qm_rc_t rc; + + (void) rc; + + rc = bmc150_read_accel(&accel); + QM_PRINTF("rc %d x %d y %d z %d\n", rc, accel.x, accel.y, accel.z); + +#if (__IPP_ENABLED__) + print_axis_stats(accel.z); +#endif + + qm_rtc_set_alarm(QM_RTC_0, (QM_RTC[QM_RTC_0].rtc_ccvr + ALARM)); +} + +int main(void) +{ + qm_rtc_config_t rtc; + + QM_PUTS("Accelerometer example app\n"); + + rtc.init_val = 0; + rtc.alarm_en = true; + rtc.alarm_val = ALARM; + rtc.callback = print_accel_callback; + + qm_irq_request(QM_IRQ_RTC_0, qm_rtc_isr_0); + + clk_periph_enable(CLK_PERIPH_RTC_REGISTER | CLK_PERIPH_CLK); + + bmc150_init(BMC150_J14_POS_0); + + bmc150_set_accel_mode(BMC150_MODE_2G); + bmc150_set_bandwidth(BMC150_BANDWIDTH_64MS); + + qm_rtc_set_config(QM_RTC_0, &rtc); + + return 0; +} diff --git a/apps/magneto/CMakeLists.txt b/apps/magneto/CMakeLists.txt new file mode 100644 index 0000000..e1ae3d1 --- /dev/null +++ b/apps/magneto/CMakeLists.txt @@ -0,0 +1,4 @@ +add_executable(magneto main.c) +set_target_properties(magneto PROPERTIES CHIP QUARK_D2000) + +#target_compile_definitions(magneto -D__IPP__) diff --git a/apps/magneto/main.c b/apps/magneto/main.c new file mode 100644 index 0000000..df19ae1 --- /dev/null +++ b/apps/magneto/main.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2016, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include "qm_interrupt.h" +#include "qm_rtc.h" +#include "qm_uart.h" + +#include "bmx1xx/bmx1xx.h" + +#define ALARM (QM_RTC_ALARM_SECOND >> 3) + +#define M_PI 3.14159265358979323846 + +#if (QUARK_D2000) + +#define SAMPLING_DURATION 500 +static uint16_t cb_count = 0; + +static const char *degrees_to_direction(unsigned int deg) +{ + if (deg >= 360) { + deg %= 360; + } + + if (deg >= 338 || deg < 23) { + return "N"; + } else if (deg < 68) { + return "NE"; + } else if (deg < 113) { + return "E"; + } else if (deg < 158) { + return "SE"; + } else if (deg < 203) { + return "S"; + } else if (deg < 248) { + return "SW"; + } else if (deg < 293) { + return "W"; + } else { + return "NW"; + } +} + +static void print_magneto_callback(void *data) +{ + bmx1xx_mag_t mag = {0}; + double heading; + int deg; + + bmx1xx_read_mag(&mag); + + heading = atan2(mag.y, mag.x); + + if (heading < 0) { + heading += 2 * M_PI; + } + + deg = (int)(heading * 180 / M_PI); + + QM_PRINTF("mag x %d y %d z %d deg %d direction %s\n", mag.x, mag.y, + mag.z, deg, degrees_to_direction(deg)); + + if (cb_count < SAMPLING_DURATION) { + qm_rtc_set_alarm(QM_RTC_0, (QM_RTC[QM_RTC_0].rtc_ccvr + ALARM)); + cb_count++; + } else { + QM_PUTS("Finished: Magnetometer example app\n"); + } +} +#endif + +int main(void) +{ +#if (QUARK_D2000) + bmx1xx_setup_config_t cfg; + qm_rtc_config_t rtc; +#endif + int rc = 0; + + QM_PUTS("Starting: Magnetometer example app\n"); + +#if (QUARK_D2000) + rtc.init_val = 0; + rtc.alarm_en = true; + rtc.alarm_val = ALARM; + rtc.callback = print_magneto_callback; + rtc.callback_data = NULL; + + qm_irq_request(QM_IRQ_RTC_0, qm_rtc_isr_0); + + clk_periph_enable(CLK_PERIPH_RTC_REGISTER | CLK_PERIPH_CLK); + + cfg.pos = BMC150_J14_POS_0; + + rc = bmx1xx_init(cfg); + if (rc != 0) { + return rc; + } + + rc = bmx1xx_mag_set_power(BMX1XX_MAG_POWER_ACTIVE); + if (rc != 0) { + return rc; + } + + rc = bmx1xx_mag_set_preset(BMX1XX_MAG_PRESET_HIGH_ACCURACY); + if (rc != 0) { + return rc; + } + + qm_rtc_set_config(QM_RTC_0, &rtc); + +#else + QM_PUTS("Mag sensor app not available for Quark SE dev board\n"); + QM_PUTS("Finished: Magnetometer example app\n"); +#endif + return rc; +} diff --git a/cmake/intel-quark-d2000.toolchain.cmake b/cmake/intel-quark-d2000.toolchain.cmake new file mode 100644 index 0000000..3e15792 --- /dev/null +++ b/cmake/intel-quark-d2000.toolchain.cmake @@ -0,0 +1,176 @@ +if (${INTEL_QUARK_TOOLCHAIN_LOADED}) + return() +endif() +set(INTEL_QUARK_TOOLCHAIN_LOADED TRUE) + +include(CMakeForceCompiler) + +set(TRIPLE "i586-intel-elfiamcu") + +if (NOT IS_DIRECTORY "${ISSM_DIR}") + message(FATAL_ERROR "ISSM_DIR has to be set to a directory:" ${ISSM_DIR}) + set(ISSM_DIR CACHE PATH "The path to Intes ISSM") +endif() + +if (NOT INTEL_QUARK_CHIP) + set(INTEL_QUARK_CHIP CACHE STRING "The Intel Quark chip to build for") + message(FATAL_ERROR "INTEL_QUARK_CHIP has to be set before including the toolchain file") +endif() + +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR intel) +set(CMAKE_CROSSCOMPILING 1) + +set(TARGET_FLAGS "-march=lakemont -mtune=lakemont -miamcu -msoft-float") +set(BASE_FLAGS "-std=c90 -Wall -Wextra -Werror -Wno-unused-parameter") + +set(INCLUDES "") + +if(IS_DIRECTORY "${QMSI_DIR}") + message("Using QMSI_DIR: ${QMSI_DIR}") +else() + message("Detecting QMSI_DIR..") + + find_path(QMSI_DIR qm_common.h + HINTS "${ISSM_DIR}/firmware/bsp/1.0/include" + NO_DEFAULT_PATH) + + if(IS_DIRECTORY "${QMSI_DIR}") + message("Found QMSI_DIR: ${QMSI_DIR}") + else() + message(FATAL_ERROR "Could not find QMSI directory") + endif() + +endif() + +# TODO: these directories should be validated +list(APPEND includes "${ISSM_DIR}/firmware/bsp/1.0/include") +list(APPEND includes "${ISSM_DIR}/firmware/bsp/1.0/board/drivers") +#list(APPEND includes "${ISSM_DIR}/firmware/bsp/1.0/drivers/include") +list(APPEND includes "${ISSM_DIR}/firmware/bsp/1.0/drivers/bmc150") + +if (INTEL_QUARK_CHIP STREQUAL D2000) + list(APPEND includes "${ISSM_DIR}/firmware/bsp/1.0/soc/quark_d2000/include") + set(ld_file "${ISSM_DIR}/firmware/bsp/1.0/soc/quark_d2000/quark_d2000.ld") +elseif (INTEL_QUARK_CHIP STREQUAL SE) + list(APPEND includes "${ISSM_DIR}/firmware/bsp/1.0/soc/quark_se/include") +endif() + +# QMSI Library +file(GLOB_RECURSE qmsi_sources ${ISSM_DIR}/firmware/bsp/1.0/drivers/*.c) +add_library(qmsi STATIC ${qmsi_sources}) +target_include_directories(qmsi PUBLIC "${ISSM_DIR}/firmware/bsp/1.0/drivers/include") + +# SYS Library - dunno if this really is the best name +file(GLOB_RECURSE intel_sys ${ISSM_DIR}/firmware/bsp/1.0/sys/*.c) +add_library(intel_sys STATIC ${intel_sys}) +#target_include_directories(intel_sys PUBLIC "${ISSM_DIR}/firmware/bsp/1.0/drivers/include") +target_link_libraries(intel_sys PRIVATE qmsi) + +# BMC Library +file(GLOB_RECURSE bmc_sources ${ISSM_DIR}/firmware/bsp/1.0/board/drivers/bmc150/*.c) +add_library(bmc STATIC ${bmc_sources}) +target_link_libraries(bmc PRIVATE qmsi) +target_include_directories(bmc PUBLIC "${ISSM_DIR}/firmware/bsp/1.0/board/drivers/bmc150") + +# IPP Library +#file(GLOB_RECURSE ipp_sources ${ISSM_DIR}/firmware/lib/ipp/1.0.0/*.c) +add_library(ipp STATIC IMPORTED) +set_property(TARGET ipp PROPERTY IMPORTED_LOCATION "${ISSM_DIR}/firmware/lib/ipp/1.0.0/lib/libippsq.a") +#target_include_directories(ipp PUBLIC "${ISSM_DIR}/firmware/lib/ipp/1.0.0/include") +set_property(TARGET ipp APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${ISSM_DIR}/firmware/lib/ipp/1.0.0/include") +#target_compile_definitions(ipp PUBLIC -D__IPP_ENABLED__) +#target_compile_options(ipp PUBLIC -Wno-empty-body) +#target_link_libraries(ipp INTERFACE qmsi) + +# Compilation +# -O0 +# -g +# -DDEBUG +# -fmessage-length=0 +# -I../include +# -fno-asynchronous-unwind-tables +# -I../drivers +# -I../drivers/include +# +# -DSPI_IRQ_MST +# -I../soc/quark_d2000/include +# -c +# -o ../drivers/debug/quark_d2000/obj/qm_i2c.o +# ../drivers/qm_i2c.c + +# Linking +# i586-intel-elfiamcu-gcc +# -nostdlib +# -L./bsp/build/debug/quark_d2000/libqmsi/lib +# -Xlinker -T./bsp/soc/quark_d2000/quark_d2000.ld +# -Xlinker -A +# -Xlinker --oformat +# -Xlinker -Map=./debug/quark_d2000/obj/accel_test.map +# -o ./debug/quark_d2000/obj/accel_test.elf +# ./debug/quark_d2000/obj/main.o +# ./bsp/sys/debug/quark_d2000/obj/app_entry.o +# ./bsp/sys/debug/quark_d2000/obj/newlib-syscalls.o +# ./bsp/board/drivers/debug/quark_d2000/obj/bmc150.o +# -L/home/trygvis/intel/issm_2016.0.019/firmware/lib/ipp/1.0.0/lib +# -lippsq +# -lc +# -lnosys +# -lsoftfp +# -lgcc +# -lqmsi + +set(o_level "$") +add_compile_options("$<$:-O${o_level}>$<$>:-O3>") +unset(o_level) + +include_directories("${includes}") +set(CMAKE_C_FLAGS "${BASE_FLAGS} ${TARGET_FLAGS} " CACHE STRING "c flags") +set(CMAKE_CXX_FLAGS "${BASE_FLAGS} ${TARGET_FLAGS} -fno-exceptions -fno-rtti -felide-constructors -std=c++14" CACHE STRING "c++ flags") + +# ${CMAKE_C_FLAGS} is prepended to this string +set(LD_FILE ) +set(linker_flags "") +set(linker_flags "${linker_flags} -nostdlib") +set(linker_flags "${linker_flags} -Xlinker -A") +set(linker_flags "${linker_flags} -Xlinker --oformat") + +#set(LINKER_LIBS "-larm_cortexM4l_math -lm") + +# http://stackoverflow.com/questions/16588097/cmake-separate-linker-and-compiler-flags +set(CMAKE_EXE_LINKER_FLAGS "${linker_flags}" CACHE STRING "linker flags" FORCE) +#unset(linker_flags) + +set(GCC "${ISSM_DIR}/tools/compiler/bin/${TRIPLE}-gcc") + +if(NOT EXISTS "${GCC}") + message(FATAL_ERROR "Could not find ${TRIPLE}-gcc. Is $ISSM_DIR set correctly?") +endif() + +# No C++ support for D2000 +# set(GXX "${ISSM_DIR}/tools/compiler/bin/${TRIPLE}-g++") +# if(NOT EXISTS "${GXX}") +# message(FATAL_ERROR "Could not find ${TRIPLE}-g++. Is $ISSM_DIR set correctly?") +# endif() +# cmake_force_cxx_compiler("${GXX}" GNU) + +cmake_force_c_compiler("${GCC}" GNU) + +# search for programs in the build host directories +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +# for libraries and headers in the target directories +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +function(toolchain_target TARGET) + target_link_libraries("${TARGET}" intel_sys) + target_link_libraries("${TARGET}" qmsi) + target_link_libraries("${TARGET}" ipp) + target_link_libraries("${TARGET}" bmc) + target_link_libraries("${TARGET}" softfp) + target_link_libraries("${TARGET}" c) + target_link_libraries("${TARGET}" g) +# target_link_libraries("${TARGET}" gcc) + target_compile_definitions("${TARGET}" PUBLIC -D__IPP_ENABLED__) + target_link_libraries("${TARGET}" "-Xlinker" "-T${ld_file}") +endfunction() diff --git a/setup-env.sh b/setup-env.sh new file mode 100644 index 0000000..da4abf6 --- /dev/null +++ b/setup-env.sh @@ -0,0 +1,21 @@ +ISSM_COMPLETE=$HOME/intel/issm_2016.0.019/ +ISSM_TOOLCHAIN=$HOME/tmp/intel-quark/issm-toolchain-linux-2016-05-12 +ISSM=$ISSM_TOOLCHAIN +export ISSM + +PATH=$ISSM/tools/debugger/gdb:$PATH +PATH=$ISSM/tools/debugger/gdb-ia/bin:$PATH +PATH=$ISSM/tools/debugger/openocd/bin:$PATH +PATH=$ISSM/tools/compiler/bin:$PATH + +PYTHONHOME=$ISSM/tools/python +export PYTHONHOME + +IPP_LIBRARY_PATH=$ISSM_COMPLETE/firmware/lib/ipp/1.0.0 +export IPP_LIBRARY_PATH + +IAMCU_TOOLCHAIN_DIR=$ISSM_COMPLETE/~/intel/firmware/bsp/1.0 +export IAMCU_TOOLCHAIN_DIR + +# This is required for my Debian installation +SWT_GTK3=0 -- cgit v1.2.3