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/lcd3310/main.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 apps/lcd3310/main.c (limited to 'apps/lcd3310/main.c') 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; +} -- cgit v1.2.3