summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2016-07-16 07:57:28 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2016-07-16 10:37:06 +0200
commitffa14762a506c39d897fd63f028b39904cf22a5f (patch)
tree361c863c7851f4c41797b5ec4fa8aa9c9213c4aa
parent8fdcf6b00313829230a61da4dfe210e5f82b371e (diff)
downloadintel-quark-d2000-playground-ffa14762a506c39d897fd63f028b39904cf22a5f.tar.gz
intel-quark-d2000-playground-ffa14762a506c39d897fd63f028b39904cf22a5f.tar.bz2
intel-quark-d2000-playground-ffa14762a506c39d897fd63f028b39904cf22a5f.tar.xz
intel-quark-d2000-playground-ffa14762a506c39d897fd63f028b39904cf22a5f.zip
o Changing how the toolchain create the qmsi libraries etc. Replace the hardcoded library with a function that the user can use to create its own special target. This target can be further customized by normal CMake methods by setting properties.HEADmaster
o Adding start of a app for playing with MOD-LCD3310 which is a PCD8544 connected through SPI.
-rw-r--r--apps/CMakeLists.txt3
-rw-r--r--apps/accel/CMakeLists.txt3
-rw-r--r--apps/lcd3310/CMakeLists.txt7
-rw-r--r--apps/lcd3310/bits.h21
-rw-r--r--apps/lcd3310/main.c190
-rw-r--r--cmake/intel-quark-d2000.toolchain.cmake63
-rw-r--r--cmake/intel/qmsi.cmake27
7 files changed, 265 insertions, 49 deletions
diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt
index 973af05..1b220e2 100644
--- a/apps/CMakeLists.txt
+++ b/apps/CMakeLists.txt
@@ -1,2 +1,5 @@
+qmsi_create(stdout)
+
add_subdirectory(accel)
+add_subdirectory(lcd3310)
#add_subdirectory(magneto)
diff --git a/apps/accel/CMakeLists.txt b/apps/accel/CMakeLists.txt
index 35948ae..2f342f7 100644
--- a/apps/accel/CMakeLists.txt
+++ b/apps/accel/CMakeLists.txt
@@ -1,4 +1,7 @@
add_executable(accel main.c)
+target_link_libraries(accel PUBLIC qmsi_stdout)
+target_link_libraries(accel PUBLIC qmsi_bmc_stdout)
+
set_target_properties(accel PROPERTIES CHIP QUARK_D2000)
toolchain_target(accel)
add_extra_commands(accel)
diff --git a/apps/lcd3310/CMakeLists.txt b/apps/lcd3310/CMakeLists.txt
new file mode 100644
index 0000000..4d77f22
--- /dev/null
+++ b/apps/lcd3310/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_executable(lcd3310 main.c bits.h)
+target_include_directories(lcd3310 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+target_link_libraries(lcd3310 PUBLIC qmsi_stdout)
+
+set_target_properties(lcd3310 PROPERTIES CHIP QUARK_D2000)
+toolchain_target(lcd3310)
+add_extra_commands(lcd3310)
diff --git a/apps/lcd3310/bits.h b/apps/lcd3310/bits.h
new file mode 100644
index 0000000..434c390
--- /dev/null
+++ b/apps/lcd3310/bits.h
@@ -0,0 +1,21 @@
+#pragma once
+
+/*
+http://stackoverflow.com/a/5048661/245614
+*/
+/*
+NUM_ARGS(...) evaluates to the literal number of the passed-in arguments.
+*/
+#define _NUM_ARGS2(X, X64, X63, X62, X61, X60, X59, X58, X57, X56, X55, X54, X53, X52, X51, X50, X49, X48, X47, X46, X45, X44, X43, X42, X41, X40, X39, X38, X37, X36, X35, X34, X33, X32, X31, X30, X29, X28, X27, X26, X25, X24, X23, X22, X21, X20, X19, X18, X17, X16, X15, X14, X13, X12, X11, X10, X9, X8, X7, X6, X5, X4, X3, X2, X1, N, ...) N
+#define NUM_ARGS(...) _NUM_ARGS2(0, __VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
+
+#define BIT_MASK_1(a) (1 << a)
+#define BIT_MASK_2(a, b) (BIT_MASK_1(a) | BIT_MASK_1(b))
+#define BIT_MASK_3(a, b, c) (BIT_MASK_2(a, b) | BIT_MASK_1(c))
+#define BIT_MASK_4(a, b, c, d) (BIT_MASK_3(a, b, c) | BIT_MASK_1(d))
+#define BIT_MASK_5(a, b, c, d, e) (BIT_MASK_4(a, b, c, d) | BIT_MASK_1(e))
+#define BIT_MASK_6(a, b, c, d, e, f) (BIT_MASK_5(a, b, c, d, e) | BIT_MASK_1(f))
+
+#define _BIT_MASK_3(N, ...) BIT_MASK_ ## N(__VA_ARGS__)
+#define _BIT_MASK_2(N, ...) _BIT_MASK_3(N, __VA_ARGS__)
+#define BIT_MASK(...) _BIT_MASK_2(NUM_ARGS(__VA_ARGS__), __VA_ARGS__)
diff --git a/apps/lcd3310/main.c b/apps/lcd3310/main.c
new file mode 100644
index 0000000..602a804
--- /dev/null
+++ b/apps/lcd3310/main.c
@@ -0,0 +1,190 @@
+/*
+https://yogiken.files.wordpress.com/2010/02/c-register-access.pdf
+ */
+
+#include <qm_soc_regs.h>
+#include <qm_spi.h>
+#include <qm_gpio.h>
+#include <stddef.h>
+#include <assert.h>
+#include <qm_scss.h>
+#include <qm_pinmux.h>
+#include "bits.h"
+
+struct spi {
+ qm_spi_t id;
+};
+
+struct gpio_pin {
+ qm_gpio_t port;
+ uint8_t pin;
+};
+
+struct pcd8544 {
+ struct spi *spi;
+ /* 1 = data, 0 = command */
+ struct gpio_pin *pin_dc;
+ struct gpio_pin *pin_res;
+};
+
+void spi_new(struct spi *spi, qm_spi_t id) {
+ clk_periph_enable(CLK_PERIPH_SPI_M0);
+ spi->id = id;
+
+ qm_pmux_select(QM_PIN_ID_16, QM_PMUX_FN_2); /* SCL */
+ qm_pmux_select(QM_PIN_ID_17, QM_PMUX_FN_2); /* TXD */
+ qm_pmux_input_en(QM_PIN_ID_18, true);
+}
+
+void spi_enable(struct spi *spi) {
+ qm_spi_config_t cfg = {
+ .frame_size = QM_SPI_FRAME_SIZE_8_BIT,
+ .transfer_mode = QM_SPI_TMOD_TX_RX,
+ .bus_mode = QM_SPI_BMODE_0,
+ .clk_divider = 2
+ };
+ qm_spi_set_config(spi->id, &cfg);
+}
+
+void spi_delete(struct spi const *const spi) {
+}
+
+void spi_exchange(struct spi const *const spi, uint8_t *tx, size_t tx_len, uint8_t *rx, size_t rx_len) {
+ qm_spi_transfer_t transfer = {
+ .tx = tx,
+ .tx_len = tx_len,
+ .rx = rx,
+ .rx_len = rx_len
+ };
+ qm_spi_transfer(spi->id, &transfer);
+}
+
+void spi_tx(struct spi const *const spi, uint8_t *tx, size_t tx_len) {
+ qm_spi_config_t cfg = {
+ .frame_size = QM_SPI_FRAME_SIZE_8_BIT,
+ .transfer_mode = QM_SPI_TMOD_TX,
+ .bus_mode = QM_SPI_BMODE_0,
+ .clk_divider = 32 /* 8 == 4MHz */
+ };
+ qm_spi_set_config(spi->id, &cfg);
+
+ qm_spi_transfer_t transfer = {
+ .tx = tx,
+ .tx_len = tx_len,
+ .rx = 0,
+ .rx_len = 0
+ };
+ qm_spi_transfer(spi->id, &transfer);
+}
+
+void gpio_pin_new(struct gpio_pin *gp, int port, uint8_t pin) {
+ assert(port == 0);
+
+ gp->port = QM_GPIO_0;
+ gp->pin = pin;
+
+ qm_gpio_port_config_t cfg = {
+ .direction = (uint32_t) BIT_MASK(pin),
+ .int_en = 0,
+ .int_type = 0,
+ .int_polarity = 0,
+ .int_debounce = 0,
+ .int_bothedge = 0,
+ .callback = NULL
+ };
+ qm_gpio_set_config(gp->port, &cfg);
+}
+
+void gpio_pin_set(struct gpio_pin *gp) {
+ qm_gpio_set_pin(gp->port, gp->pin);
+}
+
+void gpio_pin_reset(struct gpio_pin *gp) {
+}
+
+uint8_t pcd8544_cmd_function(bool power_down, bool vertical_mode, bool extended_instruction_set) {
+ return (uint8_t) ((power_down & BIT_MASK_1(2)) |
+ (vertical_mode & BIT_MASK_1(1)) |
+ (extended_instruction_set & BIT_MASK_1(0)));
+}
+
+uint8_t pcd8544_cmd_display_function(bool d, bool e) {
+ return (uint8_t) (BIT_MASK_1(3) |
+ (d & BIT_MASK_1(2)) |
+ (e & BIT_MASK_1(0)));
+}
+
+uint8_t pcd8544_cmd_x_address(int address) {
+ return (uint8_t) (BIT_MASK_1(6) | (address & BIT_MASK_3(2, 1, 0)));
+}
+
+uint8_t pcd8544_cmd_y_address(int address) {
+ return (uint8_t) (BIT_MASK_1(7) | (address & BIT_MASK(5, 4, 3, 2, 1, 0)));
+}
+
+void pcd8544_new(struct pcd8544 *pcd8544, struct spi *spi, struct gpio_pin *pin_dc, struct gpio_pin *pin_res) {
+ pcd8544->spi = spi;
+ pcd8544->pin_dc = pin_dc;
+ pcd8544->pin_res = pin_res;
+}
+
+void pcd8544_delete(struct pcd8544 *pcd8544) {
+}
+
+void pcd8544_reset(struct pcd8544 *pcd8544) {
+ gpio_pin_reset(pcd8544->pin_res);
+ clk_sys_udelay(10 * 1000);
+ gpio_pin_set(pcd8544->pin_res);
+
+ gpio_pin_reset(pcd8544->pin_dc);
+
+ uint8_t tx[] = {
+ pcd8544_cmd_function(false, false, false),
+ pcd8544_cmd_y_address(0),
+ pcd8544_cmd_x_address(0)
+ };
+ uint8_t rx[] = {
+ 0,
+ 0,
+ 0
+ };
+
+ spi_exchange(pcd8544->spi, tx, sizeof(tx), rx, sizeof(rx));
+
+ gpio_pin_set(pcd8544->pin_dc);
+}
+
+void pcd8544_fun(struct pcd8544 *pcd8544) {
+ uint8_t tx[] = {
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ };
+
+ spi_tx(pcd8544->spi, tx, sizeof(tx));
+}
+
+struct spi spi;
+struct pcd8544 pcd8544;
+struct gpio_pin pin_dc, pin_res;
+
+int main() {
+ clk_periph_enable(CLK_PERIPH_CLK);
+
+ spi_new(&spi, QM_SPI_MST_0);
+ spi_enable(&spi);
+
+ gpio_pin_new(&pin_dc, 0, 3);
+ gpio_pin_new(&pin_res, 0, 4);
+
+ pcd8544_new(&pcd8544, &spi, &pin_dc, &pin_res);
+ pcd8544_reset(&pcd8544);
+ pcd8544_fun(&pcd8544);
+ pcd8544_delete(&pcd8544);
+
+ spi_delete(&spi);
+ return 0;
+}
diff --git a/cmake/intel-quark-d2000.toolchain.cmake b/cmake/intel-quark-d2000.toolchain.cmake
index 3537551..03925a7 100644
--- a/cmake/intel-quark-d2000.toolchain.cmake
+++ b/cmake/intel-quark-d2000.toolchain.cmake
@@ -32,28 +32,9 @@ 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")
+#list(APPEND includes "${ISSM_DIR}/firmware/bsp/1.0/include")
+#list(APPEND includes "${ISSM_DIR}/firmware/bsp/1.0/board/drivers")
if (INTEL_QUARK_CHIP STREQUAL D2000)
include("${toolchain_dir}/intel/d2000.cmake")
@@ -64,27 +45,13 @@ if (INTEL_QUARK_CHIP STREQUAL D2000)
include("${toolchain_dir}/intel/gdb.cmake")
gdb_init()
+
+ include("${toolchain_dir}/intel/qmsi.cmake")
+ qmsi_init()
elseif (INTEL_QUARK_CHIP STREQUAL SE)
- list(APPEND includes "${ISSM_DIR}/firmware/bsp/1.0/soc/quark_se/include")
+# 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)
@@ -136,7 +103,7 @@ set(o_level "$<TARGET_PROPERTY:O_LEVEL>")
add_compile_options("$<$<BOOL:${o_level}>:-O${o_level}>$<$<NOT:$<BOOL:${o_level}>>:-O3>")
unset(o_level)
-include_directories("${includes}")
+#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")
@@ -154,6 +121,7 @@ set(CMAKE_EXE_LINKER_FLAGS "${linker_flags}" CACHE STRING "linker flags" FORCE)
#unset(linker_flags)
set(GCC "${ISSM_DIR}/tools/compiler/bin/${TRIPLE}-gcc")
+#set(GCC "/usr/bin/clang++-3.9")
if (NOT EXISTS "${GCC}")
message(FATAL_ERROR "Could not find ${TRIPLE}-gcc. Is $ISSM_DIR set correctly?")
@@ -167,6 +135,7 @@ endif ()
# cmake_force_cxx_compiler("${GXX}" GNU)
cmake_force_c_compiler("${GCC}" GNU)
+#cmake_force_c_compiler("${GCC}" LLVM)
# search for programs in the build elfinfo directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
@@ -176,16 +145,12 @@ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
function(toolchain_target TARGET)
add_dependencies("${TARGET}" elfinfo)
- 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_link_libraries("${TARGET}" PUBLIC ipp)
+ target_link_libraries("${TARGET}" PUBLIC softfp)
+ target_link_libraries("${TARGET}" PUBLIC c)
+ target_link_libraries("${TARGET}" PUBLIC g)
target_compile_definitions("${TARGET}" PUBLIC -D__IPP_ENABLED__)
- target_link_libraries("${TARGET}" "-Xlinker" "-T${ld_file}")
+ target_link_libraries("${TARGET}" PUBLIC "-Xlinker" "-T${ld_file}")
endfunction()
# elfinfo tools
diff --git a/cmake/intel/qmsi.cmake b/cmake/intel/qmsi.cmake
new file mode 100644
index 0000000..0cffa5e
--- /dev/null
+++ b/cmake/intel/qmsi.cmake
@@ -0,0 +1,27 @@
+function(qmsi_init)
+endfunction()
+
+function(qmsi_create TARGET_SUFFIX)
+ set(qmsi qmsi_${TARGET_SUFFIX})
+ set(bmc qmsi_bmc_${TARGET_SUFFIX})
+ message("Creating QMSI targets ${qmsi} and ${bmc}")
+
+ file(GLOB_RECURSE qmsi_sources
+ ${ISSM_DIR}/firmware/bsp/1.0/drivers/*.c
+ ${ISSM_DIR}/firmware/bsp/1.0/sys/*.c)
+ add_library(${qmsi} STATIC ${qmsi_sources})
+ target_include_directories(${qmsi} PUBLIC "${ISSM_DIR}/firmware/bsp/1.0/include")
+ target_include_directories(${qmsi} PUBLIC "${ISSM_DIR}/firmware/bsp/1.0/drivers/include")
+
+ message("INTEL_QUARK_CHIP=${INTEL_QUARK_CHIP}")
+ if (INTEL_QUARK_CHIP STREQUAL D2000)
+ target_include_directories(${qmsi} PUBLIC "${ISSM_DIR}/firmware/bsp/1.0/soc/quark_d2000/include")
+ elseif (INTEL_QUARK_CHIP STREQUAL SE)
+ target_include_directories(${qmsi} PUBLIC "${ISSM_DIR}/firmware/bsp/1.0/soc/quark_se/include")
+ endif ()
+
+ 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} PUBLIC ${qmsi})
+ target_include_directories(${bmc} PUBLIC "${ISSM_DIR}/firmware/bsp/1.0/board/drivers")
+endfunction()