diff options
author | Trygve Laugstøl <trygvis@inamo.no> | 2016-07-16 07:57:28 +0200 |
---|---|---|
committer | Trygve Laugstøl <trygvis@inamo.no> | 2016-07-16 10:37:06 +0200 |
commit | ffa14762a506c39d897fd63f028b39904cf22a5f (patch) | |
tree | 361c863c7851f4c41797b5ec4fa8aa9c9213c4aa /apps | |
parent | 8fdcf6b00313829230a61da4dfe210e5f82b371e (diff) | |
download | intel-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.
Diffstat (limited to 'apps')
-rw-r--r-- | apps/CMakeLists.txt | 3 | ||||
-rw-r--r-- | apps/accel/CMakeLists.txt | 3 | ||||
-rw-r--r-- | apps/lcd3310/CMakeLists.txt | 7 | ||||
-rw-r--r-- | apps/lcd3310/bits.h | 21 | ||||
-rw-r--r-- | apps/lcd3310/main.c | 190 |
5 files changed, 224 insertions, 0 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; +} |