From ffa14762a506c39d897fd63f028b39904cf22a5f Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sat, 16 Jul 2016 07:57:28 +0200 Subject: 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. o Adding start of a app for playing with MOD-LCD3310 which is a PCD8544 connected through SPI. --- apps/CMakeLists.txt | 3 + apps/accel/CMakeLists.txt | 3 + apps/lcd3310/CMakeLists.txt | 7 ++ apps/lcd3310/bits.h | 21 ++++ apps/lcd3310/main.c | 190 ++++++++++++++++++++++++++++++++ cmake/intel-quark-d2000.toolchain.cmake | 63 +++-------- cmake/intel/qmsi.cmake | 27 +++++ 7 files changed, 265 insertions(+), 49 deletions(-) create mode 100644 apps/lcd3310/CMakeLists.txt create mode 100644 apps/lcd3310/bits.h create mode 100644 apps/lcd3310/main.c create mode 100644 cmake/intel/qmsi.cmake 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 +#include +#include +#include +#include +#include +#include +#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 "$") add_compile_options("$<$:-O${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() -- cgit v1.2.3