aboutsummaryrefslogtreecommitdiffstats
path: root/boards/addons/gdisp
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2013-10-28 20:04:03 +1000
committerinmarket <andrewh@inmarket.com.au>2013-10-28 20:04:03 +1000
commit555257933af6e7e3b106ac3589520b5dad45061b (patch)
treeb2c2cd148855bc20ebb476e62e0fa39ed1efbab0 /boards/addons/gdisp
parentdc2d5be60625dc03f0982d61a55dd3ccf844fff5 (diff)
downloaduGFX-555257933af6e7e3b106ac3589520b5dad45061b.tar.gz
uGFX-555257933af6e7e3b106ac3589520b5dad45061b.tar.bz2
uGFX-555257933af6e7e3b106ac3589520b5dad45061b.zip
Clean up the driver directory structure by moving all board specific files into the boards sub-structure.
Diffstat (limited to 'boards/addons/gdisp')
-rw-r--r--boards/addons/gdisp/ED060SC4_example_schematics.pngbin0 -> 305333 bytes
-rw-r--r--boards/addons/gdisp/board_ED060SC4_example.h143
-rw-r--r--boards/addons/gdisp/board_HX8347D_stm32f4discovery.h160
-rw-r--r--boards/addons/gdisp/board_ILI9320_olimex_pic32mx_lcd.h126
-rw-r--r--boards/addons/gdisp/board_ILI9320_olimex_stm32_lcd.h100
-rw-r--r--boards/addons/gdisp/board_ILI9325_hy_stm32_100p.h112
-rw-r--r--boards/addons/gdisp/board_ILI9481_firebullstm32f103.h107
-rw-r--r--boards/addons/gdisp/board_RA8875_marlin.h113
-rw-r--r--boards/addons/gdisp/board_S6D1121_olimex_e407.h91
-rw-r--r--boards/addons/gdisp/board_SSD1289_firebullstm32f103.h108
-rw-r--r--boards/addons/gdisp/board_SSD1289_stm32f4discovery.h172
-rw-r--r--boards/addons/gdisp/board_SSD1306_i2c.h129
-rw-r--r--boards/addons/gdisp/board_SSD1306_spi.h132
-rw-r--r--boards/addons/gdisp/board_SSD1963_fsmc.h105
-rw-r--r--boards/addons/gdisp/board_SSD1963_gpio.h102
-rw-r--r--boards/addons/gdisp/board_SSD2119_embest_dmstf4bb.h173
16 files changed, 1873 insertions, 0 deletions
diff --git a/boards/addons/gdisp/ED060SC4_example_schematics.png b/boards/addons/gdisp/ED060SC4_example_schematics.png
new file mode 100644
index 00000000..0d9d095f
--- /dev/null
+++ b/boards/addons/gdisp/ED060SC4_example_schematics.png
Binary files differ
diff --git a/boards/addons/gdisp/board_ED060SC4_example.h b/boards/addons/gdisp/board_ED060SC4_example.h
new file mode 100644
index 00000000..cb5a92b8
--- /dev/null
+++ b/boards/addons/gdisp/board_ED060SC4_example.h
@@ -0,0 +1,143 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/* Board interface definitions for ED060SC4 PrimeView E-ink panel.
+ *
+ * This file corresponds to the connections shown in example_schematics.png,
+ * and is designed to interface with ChibiOS/RT.
+ *
+ * Please note that this file has never been tested in exactly this pin
+ * configuration, because the actual boards I have are slightly different.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+#include <hal.h>
+
+/*
+ * IO pins assignments.
+ */
+#define GPIOB_EINK_VDD 0
+#define GPIOB_EINK_GMODE 1
+#define GPIOB_EINK_SPV 2
+#define GPIOB_EINK_CKV 3
+#define GPIOB_EINK_CL 4
+#define GPIOB_EINK_LE 5
+#define GPIOB_EINK_OE 6
+#define GPIOB_EINK_SPH 7
+#define GPIOB_EINK_D0 8
+#define GPIOB_EINK_D1 9
+#define GPIOB_EINK_D2 10
+#define GPIOB_EINK_D3 11
+#define GPIOB_EINK_D4 12
+#define GPIOB_EINK_D5 13
+#define GPIOB_EINK_D6 14
+#define GPIOB_EINK_D7 15
+
+#define GPIOC_SMPS_CTRL 13
+#define GPIOC_VPOS_CTRL 14
+#define GPIOC_VNEG_CTRL 15
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ /* Main SMPS power control, active low
+ * (open collector so that MOSFET gate can be pulled up to Vbat) */
+ palWritePad(GPIOC, GPIOC_SMPS_CTRL, true);
+ palSetPadMode(GPIOC, GPIOC_SMPS_CTRL, PAL_MODE_OUTPUT_OPENDRAIN);
+
+ /* Power control for the positive & negative side */
+ palWritePad(GPIOC, GPIOC_VPOS_CTRL, false);
+ palSetPadMode(GPIOC, GPIOC_VPOS_CTRL, PAL_MODE_OUTPUT_PUSHPULL);
+ palWritePad(GPIOC, GPIOC_VNEG_CTRL, false);
+ palSetPadMode(GPIOC, GPIOC_VNEG_CTRL, PAL_MODE_OUTPUT_PUSHPULL);
+
+ /* Main data bus */
+ palWritePort(GPIOB, 0);
+ palSetGroupMode(GPIOB, 0xFFFF, 0, PAL_MODE_OUTPUT_PUSHPULL);
+ break;
+ }
+}
+
+/* Delay for display waveforms. Should be an accurate microsecond delay. */
+static void eink_delay(int us) {
+ halPolledDelay(US2RTT(us));
+}
+
+/* Turn the E-ink panel Vdd supply (+3.3V) on or off. */
+static inline void setpower_vdd(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOB, GPIOB_SMPS_CTRL, !on);
+ palWritePad(GPIOA, GPIOA_EINK_VDD, on);
+}
+
+/* Turn the E-ink panel negative supplies (-15V, -20V) on or off. */
+static inline void setpower_vneg(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOA, GPIOA_VNEG_CTRL, on);
+}
+
+/* Turn the E-ink panel positive supplies (-15V, -20V) on or off. */
+static inline void setpower_vpos(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOA, GPIOA_VPOS_CTRL, on);
+}
+
+/* Set the state of the LE (source driver Latch Enable) pin. */
+static inline void setpin_le(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOB, GPIOB_EINK_LE, on);
+}
+
+/* Set the state of the OE (source driver Output Enable) pin. */
+static inline void setpin_oe(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOB, GPIOB_EINK_OE, on);
+}
+
+/* Set the state of the CL (source driver Clock) pin. */
+static inline void setpin_cl(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOB, GPIOB_EINK_CL, on);
+}
+
+/* Set the state of the SPH (source driver Start Pulse Horizontal) pin. */
+static inline void setpin_sph(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOB, GPIOB_EINK_SPH, on);
+}
+
+/* Set the state of the D0-D7 (source driver Data) pins. */
+static inline void setpins_data(GDisplay *g, uint8_t value) {
+ (void) g;
+ palWriteGroup(GPIOB, 0xFF, GPIOB_EINK_D0, value);
+}
+
+/* Set the state of the CKV (gate driver Clock Vertical) pin. */
+static inline void setpin_ckv(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOB, GPIOB_EINK_CKV, on);
+}
+
+/* Set the state of the GMODE (gate driver Gate Mode) pin. */
+static inline void setpin_gmode(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOC, GPIOC_EINK_GMODE, on);
+}
+
+/* Set the state of the SPV (gate driver Start Pulse Vertical) pin. */
+static inline void setpin_spv(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOB, GPIOB_EINK_SPV, on);
+}
+
+#endif
diff --git a/boards/addons/gdisp/board_HX8347D_stm32f4discovery.h b/boards/addons/gdisp/board_HX8347D_stm32f4discovery.h
new file mode 100644
index 00000000..df287477
--- /dev/null
+++ b/boards/addons/gdisp/board_HX8347D_stm32f4discovery.h
@@ -0,0 +1,160 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/HX8347D/board_HX8347D_stm32f4discovery.h
+ * @brief GDISP Graphic Driver subsystem board SPI interface for the HX8347D display.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+
+/* Pin assignments */
+#define SET_RST palSetPad(GPIOB, 8)
+#define CLR_RST palClearPad(GPIOB, 8)
+#define SET_DATA palSetPad(GPIOB, 9)
+#define CLR_DATA palClearPad(GPIOB, 9)
+#define SET_CS palSetPad(GPIOA, 4)
+#define CLR_CS palClearPad(GPIOA, 4)
+
+/* PWM configuration structure. We use timer 4 channel 2 (orange LED on board). */
+static const PWMConfig pwmcfg = {
+ 1000000, /* 1 MHz PWM clock frequency. */
+ 100, /* PWM period is 100 cycles. */
+ NULL,
+ {
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL}
+ },
+ 0
+};
+
+/*
+ * SPI1 configuration structure.
+ * Speed 42MHz, CPHA=0, CPOL=0, 8bits frames, MSb transmitted first.
+ * The slave select line is the pin 4 on the port GPIOA.
+ */
+static const SPIConfig spi1cfg_8bit = {
+ NULL,
+ /* HW dependent part.*/
+ GPIOA,
+ 4,
+ 0 //SPI_CR1_BR_0
+};
+
+/*
+ * SPI1 configuration structure.
+ * Speed 42MHz, CPHA=0, CPOL=0, 16bits frames, MSb transmitted first.
+ * The slave select line is the pin 4 on the port GPIOA.
+ */
+static const SPIConfig spi1cfg_16bit = {
+ NULL,
+ /* HW dependent part.*/
+ GPIOA,
+ 4,
+ SPI_CR1_DFF //SPI_CR1_BR_0
+};
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ /* Display backlight control */
+ /* TIM4 is an alternate function 2 (AF2) */
+ pwmStart(&PWMD4, &pwmcfg);
+ palSetPadMode(GPIOD, 13, PAL_MODE_ALTERNATE(2));
+ pwmEnableChannel(&PWMD4, 1, 100);
+
+ palSetPadMode(GPIOB, 8, PAL_MODE_OUTPUT_PUSHPULL|PAL_STM32_OSPEED_HIGHEST); /* RST */
+ palSetPadMode(GPIOB, 9, PAL_MODE_OUTPUT_PUSHPULL|PAL_STM32_OSPEED_HIGHEST); /* RS */
+ /*
+ * Initializes the SPI driver 1. The SPI1 signals are routed as follow:
+ * PB12 - NSS.
+ * PB13 - SCK.
+ * PB14 - MISO.
+ * PB15 - MOSI.
+ */
+ SET_CS; SET_DATA;
+ spiStart(&SPID1, &spi1cfg_8bit);
+ palSetPadMode(GPIOA, 4, PAL_MODE_OUTPUT_PUSHPULL|PAL_STM32_OSPEED_HIGHEST); /* NSS. */
+ palSetPadMode(GPIOA, 5, PAL_MODE_ALTERNATE(5)|PAL_STM32_OSPEED_HIGHEST); /* SCK. */
+ palSetPadMode(GPIOA, 6, PAL_MODE_ALTERNATE(5)); /* MISO. */
+ palSetPadMode(GPIOA, 7, PAL_MODE_ALTERNATE(5)|PAL_STM32_OSPEED_HIGHEST); /* MOSI. */
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ if (state) {
+ CLR_RST;
+ } else {
+ SET_RST;
+ }
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ pwmEnableChannel(&PWMD4, 1, percent);
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+ spiAcquireBus(&SPID1);
+ while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0)); // Safety
+ CLR_CS;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+ SET_CS;
+ spiReleaseBus(&SPID1);
+}
+
+static inline void busmode16(GDisplay *g) {
+ (void) g;
+ spiStart(&SPID1, &spi1cfg_16bit);
+}
+
+static inline void busmode8(GDisplay *g) {
+ (void) g;
+ spiStart(&SPID1, &spi1cfg_8bit);
+}
+
+static inline void write_index(GDisplay *g, uint8_t index) {
+ (void) g;
+ CLR_DATA;
+ SPI1->DR = index;
+ while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0));
+ SET_DATA;
+}
+
+static inline void write_data(GDisplay *g, uint8_t data) {
+ (void) g;
+ SPI1->DR = data;
+ while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0));
+}
+
+static inline void write_ram16(GDisplay *g, uint16_t data) {
+ (void) g;
+ SPI1->DR = data;
+ while((SPI1->SR & SPI_SR_TXE) == 0);
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
diff --git a/boards/addons/gdisp/board_ILI9320_olimex_pic32mx_lcd.h b/boards/addons/gdisp/board_ILI9320_olimex_pic32mx_lcd.h
new file mode 100644
index 00000000..5315127b
--- /dev/null
+++ b/boards/addons/gdisp/board_ILI9320_olimex_pic32mx_lcd.h
@@ -0,0 +1,126 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ILI9320/board_ILI9320_olimex_pic32mx_lcd.h
+ * @brief GDISP Graphic Driver subsystem board interface for the ILI9325 display.
+ */
+
+#ifndef GDISP_LLD_BOARD_H
+#define GDISP_LLD_BOARD_H
+
+#ifndef noinline
+#define noinline __attribute__((noinline))
+#endif
+
+static void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ // RST
+ palSetPadMode(IOPORTA, 7, PAL_MODE_OUTPUT);
+ palClearPad(IOPORTA, 7);
+
+ // RS
+ palSetPadMode(IOPORTA, 10, PAL_MODE_OUTPUT);
+ palSetPad(IOPORTA, 10);
+
+ // CS
+ palSetPadMode(IOPORTA, 9, PAL_MODE_OUTPUT);
+ palClearPad(IOPORTA, 9);
+
+ // Backlight
+ palSetPadMode(IOPORTD, 3, PAL_MODE_OUTPUT);
+ palSetPad(IOPORTD, 3);
+
+ // PMP setup
+ PMMODE = 0;
+ PMAEN = 0;
+ PMCON = 0;
+ PMMODEbits.MODE = 2;
+ PMMODEbits.WAITB = 0;
+ PMMODEbits.WAITM = 1;
+ PMMODEbits.WAITE = 0;
+ PMCONbits.CSF = 0;
+ PMCONbits.PTRDEN = 1;
+ PMCONbits.PTWREN = 1;
+ PMMODEbits.MODE16 = 1;
+ PMCONbits.PMPEN = 1;
+
+ palClearPad(IOPORTA, 9);
+ break;
+ }
+}
+
+#define PmpWaitBusy() do {} while (PMMODEbits.BUSY)
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static noinline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ if (state)
+ palClearPad(IOPORTA, 7);
+ else
+ palSetPad(IOPORTA, 7);
+}
+
+static void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ if (percentage)
+ palClearPad(IOPORTD, 3);
+ else
+ palSetPad(IOPORTD, 3);
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static noinline void write_index(GDisplay *g, uint16_t index) {
+ volatile uint16_t dummy;
+ (void) g;
+
+ PmpWaitBusy();
+ palClearPad(IOPORTA, 10);
+ PMDIN = index;
+ PmpWaitBusy();
+ palSetPad(IOPORTA, 10);
+
+ dummy = PMDIN;
+ (void)dummy;
+}
+
+static noinline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ PMDIN = data;
+ PmpWaitBusy();
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+static noinline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ PmpWaitBusy();
+ return PMDIN;
+}
+
+#endif /* GDISP_LLD_BOARD_H */
diff --git a/boards/addons/gdisp/board_ILI9320_olimex_stm32_lcd.h b/boards/addons/gdisp/board_ILI9320_olimex_stm32_lcd.h
new file mode 100644
index 00000000..bca5caf8
--- /dev/null
+++ b/boards/addons/gdisp/board_ILI9320_olimex_stm32_lcd.h
@@ -0,0 +1,100 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ILI9320/board_ILI9320_olimex_stm32_lcd.h
+ * @brief GDISP Graphic Driver subsystem board interface for the ILI9320 display.
+ */
+
+#ifndef GDISP_LLD_BOARD_H
+#define GDISP_LLD_BOARD_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */
+#define GDISP_RAM (*((volatile uint16_t *) 0x60100000)) /* RS = 1 */
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ /* FSMC setup for F1 */
+ rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
+
+ /* set pin modes */
+ IOBus busD = {GPIOD, PAL_WHOLE_PORT, 0};
+ IOBus busE = {GPIOE, PAL_WHOLE_PORT, 0};
+ palSetBusMode(&busD, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
+ palSetBusMode(&busE, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
+ palSetPadMode(GPIOE, GPIOE_TFT_RST, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, GPIOD_TFT_LIGHT, PAL_MODE_OUTPUT_PUSHPULL);
+
+ /* FSMC timing */
+ FSMC_Bank1->BTCR[0+1] = (6) | (10 << 8) | (10 << 16);
+
+ /* Bank1 NOR/SRAM control register configuration
+ * This is actually not needed as already set by default after reset */
+ FSMC_Bank1->BTCR[0] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ if(state)
+ palClearPad(GPIOE, GPIOE_TFT_RST);
+ else
+ palSetPad(GPIOE, GPIOE_TFT_RST);
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ if(percent)
+ palClearPad(GPIOD, GPIOD_TFT_LIGHT);
+ else
+ palSetPad(GPIOD, GPIOD_TFT_LIGHT);
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ GDISP_REG = index;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ GDISP_RAM = data;
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ return GDISP_RAM;
+}
+
+#endif /* GDISP_LLD_BOARD_H */
diff --git a/boards/addons/gdisp/board_ILI9325_hy_stm32_100p.h b/boards/addons/gdisp/board_ILI9325_hy_stm32_100p.h
new file mode 100644
index 00000000..60508c1a
--- /dev/null
+++ b/boards/addons/gdisp/board_ILI9325_hy_stm32_100p.h
@@ -0,0 +1,112 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/*
+ driver quickly hacked together from a chinese sourcecode that came
+ with the board and existing ili9320 code by Chris van Dongen (sjaak)
+ (sjaak2002 at msn.com)
+
+ Also added rotation for 180 and 270 degrees and minor tweaks to
+ setcursor
+
+ Added code comes without warranty and free bugs. Feel free to use
+ or misuse the added code :D
+*/
+
+
+/**
+ * @file drivers/gdisp/ILI9325/board_ILI9325_hy_stm32_100p.h
+ * @brief GDISP Graphic Driver subsystem board interface for the ILI9325 display.
+ */
+
+#ifndef GDISP_LLD_BOARD_H
+#define GDISP_LLD_BOARD_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */
+#define GDISP_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ /* FSMC setup for F1 */
+ rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
+
+ /* set pin modes */
+ /* IOBus busD = {GPIOD, PAL_WHOLE_PORT, 0};
+ IOBus busE = {GPIOE, PAL_WHOLE_PORT, 0};
+ palSetBusMode(&busD, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
+ palSetBusMode(&busE, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
+ palSetPadMode(GPIOE, GPIOE_TFT_RST, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, GPIOD_TFT_LIGHT, PAL_MODE_OUTPUT_PUSHPULL); */
+
+ const unsigned char FSMC_Bank = 0;
+
+ /* FSMC timing */
+ FSMC_Bank1->BTCR[FSMC_Bank+1] = (6) | (10 << 8) | (10 << 16);
+
+ /* Bank1 NOR/SRAM control register configuration
+ * This is actually not needed as already set by default after reset */
+ FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ if(state)
+ palClearPad(GPIOE, GPIOE_TFT_RST);
+ else
+ palSetPad(GPIOE, GPIOE_TFT_RST);
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void)percent;
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ GDISP_REG = index;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ GDISP_RAM = data;
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ return GDISP_RAM;
+}
+
+#endif /* GDISP_LLD_BOARD_H */
diff --git a/boards/addons/gdisp/board_ILI9481_firebullstm32f103.h b/boards/addons/gdisp/board_ILI9481_firebullstm32f103.h
new file mode 100644
index 00000000..17bc554d
--- /dev/null
+++ b/boards/addons/gdisp/board_ILI9481_firebullstm32f103.h
@@ -0,0 +1,107 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ILI9481/board_ILI9481_firebullstm32f103.h
+ * @brief GDISP Graphics Driver subsystem low level driver source for
+ * the ILI9481 and compatible HVGA display
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define SET_CS palSetPad(GPIOD, 12);
+#define CLR_CS palClearPad(GPIOD, 12);
+#define SET_RS palSetPad(GPIOD, 13);
+#define CLR_RS palClearPad(GPIOD, 13);
+#define SET_WR palSetPad(GPIOD, 14);
+#define CLR_WR palClearPad(GPIOD, 14);
+#define SET_RD palSetPad(GPIOD, 15);
+#define CLR_RD palClearPad(GPIOD, 15);
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, 12, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, 13, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, 14, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, 15, PAL_MODE_OUTPUT_PUSHPULL);
+
+ // Configure the pins to a well know state
+ SET_RS;
+ SET_RD;
+ SET_WR;
+ CLR_CS;
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void) percent;
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ palWritePort(GPIOE, index);
+ CLR_RS; CLR_WR; SET_WR; SET_RS;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ palWritePort(GPIOE, data);
+ CLR_WR; SET_WR;
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+ // change pin mode to digital input
+ palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_INPUT);
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+ // change pin mode back to digital output
+ palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
+}
+
+static inline uint16_t read_data(GDisplay *g) {
+ uint16_t value;
+ (void) g;
+
+ CLR_RD;
+ value = palReadPort(GPIOE);
+ SET_RD;
+
+ return value;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
diff --git a/boards/addons/gdisp/board_RA8875_marlin.h b/boards/addons/gdisp/board_RA8875_marlin.h
new file mode 100644
index 00000000..b1d55a92
--- /dev/null
+++ b/boards/addons/gdisp/board_RA8875_marlin.h
@@ -0,0 +1,113 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/RA8875/board_RA8875_marlin.h
+ * @brief GDISP Graphic Driver subsystem board interface for the RA8875 display.
+ */
+
+#ifndef _BOARD_RA8875_H
+#define _BOARD_RA8875_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define GDISP_RAM (*((volatile uint16_t *) 0x68000000)) /* RS = 0 */
+#define GDISP_REG (*((volatile uint16_t *) 0x68020000)) /* RS = 1 */
+#define FSMC_BANK 4
+
+
+static inline void init_board(GDisplay *g) {
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ // setup for display 0
+ case 0: {
+
+ // enable the FSMC peripheral
+ rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
+
+ // setup the pin modes for FSMC
+ IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 8) |
+ (1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0};
+
+ IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
+ (1 << 13) | (1 << 14) | (1 << 15), 0};
+
+ IOBus busG = {GPIOG, (1 << 10), 0};
+
+ palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
+ palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
+ palSetBusMode(&busG, PAL_MODE_ALTERNATE(12));
+
+ // FSMC timing
+ FSMC_Bank1->BTCR[FSMC_BANK+1] = (FSMC_BTR1_ADDSET_1 | FSMC_BTR1_ADDSET_3) \
+ | (FSMC_BTR1_DATAST_1 | FSMC_BTR1_DATAST_3) \
+ | (FSMC_BTR1_BUSTURN_1 | FSMC_BTR1_BUSTURN_3) ;
+
+ // Bank1 NOR/SRAM control register configuration
+ // This is actually not needed as already set by default after reset
+ FSMC_Bank1->BTCR[FSMC_BANK] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
+
+ break;
+ }
+
+ // marlin does not have any secondary display so far
+ default:
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+
+ // FSMC delay reduced as the controller now runs at full speed
+ FSMC_Bank1->BTCR[2+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0 ;
+ FSMC_Bank1->BTCR[2] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+
+ GDISP_REG = index;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+
+ GDISP_RAM = data;
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+
+ return GDISP_RAM;
+}
+
+#endif /* _BOARD_RA8875_H */
+
diff --git a/boards/addons/gdisp/board_S6D1121_olimex_e407.h b/boards/addons/gdisp/board_S6D1121_olimex_e407.h
new file mode 100644
index 00000000..e0bb8e26
--- /dev/null
+++ b/boards/addons/gdisp/board_S6D1121_olimex_e407.h
@@ -0,0 +1,91 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/S6D1121/board_S6D1121_olimex_e407.h
+ * @brief GDISP Graphic Driver subsystem board interface for the S6D1121 display
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */
+#define GDISP_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ /* STM32F4 FSMC init */
+ rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
+
+ /* set pins to FSMC mode */
+ IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) |
+ (1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0};
+
+ IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
+ (1 << 13) | (1 << 14) | (1 << 15), 0};
+
+ palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
+ palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
+
+ /* FSMC timing */
+ FSMC_Bank1->BTCR[0+1] = (6) | (10 << 8) | (10 << 16);
+
+ /* Bank1 NOR/SRAM control register configuration */
+ FSMC_Bank1->BTCR[0] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
+ break;
+ }
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void) percent;
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ GDISP_REG = index;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ GDISP_RAM = data;
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ return GDISP_RAM;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
diff --git a/boards/addons/gdisp/board_SSD1289_firebullstm32f103.h b/boards/addons/gdisp/board_SSD1289_firebullstm32f103.h
new file mode 100644
index 00000000..99d37299
--- /dev/null
+++ b/boards/addons/gdisp/board_SSD1289_firebullstm32f103.h
@@ -0,0 +1,108 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1289/board_SSD1289_firebullstm32f103.h
+ * @brief GDISP Graphic Driver subsystem board interface for the SSD1289 display.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define SET_CS palSetPad(GPIOD, 12);
+#define CLR_CS palClearPad(GPIOD, 12);
+#define SET_RS palSetPad(GPIOD, 13);
+#define CLR_RS palClearPad(GPIOD, 13);
+#define SET_WR palSetPad(GPIOD, 14);
+#define CLR_WR palClearPad(GPIOD, 14);
+#define SET_RD palSetPad(GPIOD, 15);
+#define CLR_RD palClearPad(GPIOD, 15);
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, 12, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, 13, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, 14, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, 15, PAL_MODE_OUTPUT_PUSHPULL);
+
+ // Configure the pins to a well know state
+ SET_RS;
+ SET_RD;
+ SET_WR;
+ CLR_CS;
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+ /* Nothing to do here - reset pin tied to Vcc */
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void) percent;
+ /* Nothing to do here - Backlight always on */
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ palWritePort(GPIOE, index);
+ CLR_RS; CLR_WR; SET_WR; SET_RS;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ palWritePort(GPIOE, data);
+ CLR_WR; SET_WR;
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+ // change pin mode to digital input
+ palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_INPUT);
+ CLR_RD;
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+ // change pin mode back to digital output
+ SET_RD;
+ palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
+}
+
+static inline uint16_t read_data(GDisplay *g) {
+ return palReadPort(GPIOE);
+}
+
+#if defined(GDISP_USE_DMA)
+ #error "GDISP - SSD1289: The GPIO interface does not support DMA"
+#endif
+
+#endif /* _GDISP_LLD_BOARD_H */
+
diff --git a/boards/addons/gdisp/board_SSD1289_stm32f4discovery.h b/boards/addons/gdisp/board_SSD1289_stm32f4discovery.h
new file mode 100644
index 00000000..866311dc
--- /dev/null
+++ b/boards/addons/gdisp/board_SSD1289_stm32f4discovery.h
@@ -0,0 +1,172 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1289/board_SSD1289_stm32f4discovery.h
+ * @brief GDISP Graphic Driver subsystem board interface for the SSD1289 display.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define GDISP_REG ((volatile uint16_t *) 0x60000000)[0] /* RS = 0 */
+#define GDISP_RAM ((volatile uint16_t *) 0x60020000)[0] /* RS = 1 */
+#define GDISP_DMA_STREAM STM32_DMA2_STREAM6
+#define FSMC_BANK 0
+
+/* PWM configuration structure. We use timer 3 channel 3 */
+static const PWMConfig pwmcfg = {
+ 100000, /* 100 kHz PWM clock frequency. */
+ 100, /* PWM period is 100 cycles. */
+ NULL,
+ {
+ {PWM_OUTPUT_DISABLED, NULL},
+ {PWM_OUTPUT_DISABLED, NULL},
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
+ {PWM_OUTPUT_DISABLED, NULL}
+ },
+ 0
+};
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ /**
+ * Performs the following functions:
+ * 1. initialise the io port used by the display
+ * 2. initialise the reset pin (initial state not-in-reset)
+ * 3. initialise the chip select pin (initial state not-active)
+ * 4. initialise the backlight pin (initial state back-light off)
+ */
+
+ #if defined(STM32F1XX) || defined(STM32F3XX)
+ /* FSMC setup for F1/F3 */
+ rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
+
+ #if defined(GDISP_USE_DMA)
+ #error "GDISP: SSD1289 - DMA not implemented for F1/F3 Devices"
+ #endif
+ #elif defined(STM32F4XX) || defined(STM32F2XX)
+ /* STM32F2-F4 FSMC init */
+ rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
+
+ #if defined(GDISP_USE_DMA)
+ if (dmaStreamAllocate(GDISP_DMA_STREAM, 0, NULL, NULL)) gfxExit();
+ dmaStreamSetMemory0(GDISP_DMA_STREAM, &GDISP_RAM);
+ dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
+ #else
+ #warning "GDISP: SSD1289 - DMA is supported for F2/F4 Devices. Define GDISP_USE_DMA in your gfxconf.h to turn this on for better performance."
+ #endif
+ #else
+ #error "GDISP: SSD1289 - FSMC not implemented for this device"
+ #endif
+
+ /* set pins to FSMC mode */
+ IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) |
+ (1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0};
+
+ IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
+ (1 << 13) | (1 << 14) | (1 << 15), 0};
+
+ palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
+ palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
+
+ /* FSMC timing */
+ FSMC_Bank1->BTCR[FSMC_BANK+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0 ;
+
+ /* Bank1 NOR/SRAM control register configuration
+ * This is actually not needed as already set by default after reset */
+ FSMC_Bank1->BTCR[FSMC_BANK] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
+
+ /* Display backlight control */
+ /* TIM3 is an alternate function 2 (AF2) */
+ pwmStart(&PWMD3, &pwmcfg);
+ palSetPadMode(GPIOB, 0, PAL_MODE_ALTERNATE(2));
+ pwmEnableChannel(&PWMD3, 2, 100);
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ pwmEnableChannel(&PWMD3, 2, percent);
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ GDISP_REG = index;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ GDISP_RAM = data;
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+ FSMC_Bank1->BTCR[FSMC_BANK+1] = FSMC_BTR1_ADDSET_3 | FSMC_BTR1_DATAST_3 | FSMC_BTR1_BUSTURN_0; /* FSMC timing */
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+ FSMC_Bank1->BTCR[FSMC_BANK+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0; /* FSMC timing */
+}
+
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ return GDISP_RAM;
+}
+
+#if defined(GDISP_USE_DMA) || defined(__DOXYGEN__)
+ static inline void dma_with_noinc(GDisplay *g, color_t *buffer, int area) {
+ (void) g;
+ dmaStreamSetPeripheral(GDISP_DMA_STREAM, buffer);
+ dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
+ for (; area > 0; area -= 65535) {
+ dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area > 65535 ? 65535 : area);
+ dmaStreamEnable(GDISP_DMA_STREAM);
+ dmaWaitCompletion(GDISP_DMA_STREAM);
+ }
+ }
+
+ static inline void dma_with_inc(GDisplay *g, color_t *buffer, int area) {
+ (void) g;
+ dmaStreamSetPeripheral(GDISP_DMA_STREAM, buffer);
+ dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PINC | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
+ for (; area > 0; area -= 65535) {
+ dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area > 65535 ? 65535 : area);
+ dmaStreamEnable(GDISP_DMA_STREAM);
+ dmaWaitCompletion(GDISP_DMA_STREAM);
+ }
+ }
+#endif
+
+#endif /* _GDISP_LLD_BOARD_H */
+
diff --git a/boards/addons/gdisp/board_SSD1306_i2c.h b/boards/addons/gdisp/board_SSD1306_i2c.h
new file mode 100644
index 00000000..449d47ba
--- /dev/null
+++ b/boards/addons/gdisp/board_SSD1306_i2c.h
@@ -0,0 +1,129 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1306/board_SSD1306_i2c.h
+ * @brief GDISP Graphic Driver subsystem board interface for the SSD1306 display.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+// The command byte to put on the front of each page line
+#define SSD1306_PAGE_PREFIX 0x40 // Co = 0, D/C = 1
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define SSD1306_RESET_PORT GPIOB
+#define SSD1306_RESET_PIN 5
+
+/**
+ * The default slave address is 0x3D, (talking about
+ * only the real address part here) and the slave
+ * address can be changed to 0x3C by soldering the
+ * SA0 pads on the bottom side of the module.
+ *
+ * b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0
+ * --------------------------------------
+ * 0 | 1 | 1 | 1 | 1 | 0 |SA0 | R/W
+ */
+#define SSD1306_I2C_ADDRESS 0x3D
+#define SSD1306_SDA_PORT GPIOB
+#define SSD1306_SDA_PIN 7
+#define SSD1306_SCL_PORT GPIOB
+#define SSD1306_SCL_PIN 6
+#define SET_RST palSetPad(SSD1306_RESET_PORT, SSD1306_RESET_PIN);
+#define CLR_RST palClearPad(SSD1306_RESET_PORT, SSD1306_RESET_PIN);
+
+// I2C configuration structure.
+static I2CConfig i2cconfig;
+
+#if GFX_USE_OS_CHIBIOS
+ static int32_t thdPriority = 0;
+#endif
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ // RESET pin.
+ palSetPadMode(SSD1306_RESET_PORT, SSD1306_RESET_PIN, PAL_MODE_OUTPUT_PUSHPULL);
+
+
+ /*
+ * Initializes the I2C driver 1. The I2C1 signals are routed as follows:
+ * PB6 - SCL.
+ * PB7 - SDA.
+ * Timing value comes from ST I2C config tool (xls):
+ * 0x00901D2B; // 100kHz Standard Mode
+ * 0x00300444; // 100kHz Fast Mode
+ * 0x0030020A; // 400kHz Fast Mode
+ * 0x00100002; // 800kHz Fast Mode +
+ */
+ palSetPadMode(SSD1306_SCL_PORT, SSD1306_SCL_PIN, PAL_MODE_ALTERNATE(1));
+ palSetPadMode(SSD1306_SDA_PORT, SSD1306_SDA_PIN, PAL_MODE_ALTERNATE(1));
+ i2cconfig.timingr = 0x00100002; // 800kHz Fast Mode+
+ i2cInit();
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ if(state)
+ CLR_RST
+ else
+ SET_RST
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+ #if GFX_USE_OS_CHIBIOS
+ thdPriority = (int32_t)chThdGetPriority();
+ chThdSetPriority(HIGHPRIO);
+ #endif
+ i2cAcquireBus(&I2CD1);
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+ #if GFX_USE_OS_CHIBIOS
+ chThdSetPriority(thdPriority);
+ #endif
+ i2cReleaseBus(&I2CD1);
+}
+
+static inline void write_cmd(GDisplay *g, uint8_t cmd) {
+ uint8_t command[2];
+ (void) g;
+
+ command[0] = 0x00; // Co = 0, D/C = 0
+ command[1] = cmd;
+
+ i2cStart(&I2CD1, &i2cconfig);
+ i2cMasterTransmitTimeout(&I2CD1, SSD1306_I2C_ADDRESS, command, 2, NULL, 0, MS2ST(10));
+ i2cStop(&I2CD1);
+}
+
+static inline void write_data(GDisplay *g, uint8_t* data, uint16_t length) {
+ (void) g;
+
+ i2cStart(&I2CD1, &i2cconfig);
+ i2cMasterTransmitTimeout(&I2CD1, SSD1306_I2C_ADDRESS, data, length, NULL, 0, MS2ST(10));
+ i2cStop(&I2CD1);
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
+
+
diff --git a/boards/addons/gdisp/board_SSD1306_spi.h b/boards/addons/gdisp/board_SSD1306_spi.h
new file mode 100644
index 00000000..5b481630
--- /dev/null
+++ b/boards/addons/gdisp/board_SSD1306_spi.h
@@ -0,0 +1,132 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1306/board_SSD1306_spi.h
+ * @brief GDISP Graphic Driver subsystem board interface for the SSD1306 display.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+// The command byte to put on the front of each page line
+#define SSD1306_PAGE_PREFIX 0x40 // Co = 0, D/C = 1
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define SSD1306_RESET_PORT GPIOB
+#define SSD1306_RESET_PIN 5
+#define SSD1306_MISO_PORT GPIOB
+#define SSD1306_MISO_PIN 8
+#define SSD1306_MOSI_PORT GPIOB
+#define SSD1306_MOSI_PIN 7
+#define SSD1306_SCK_PORT GPIOB
+#define SSD1306_SCK_PIN 6
+#define SSD1306_CS_PORT GPIOB
+#define SSD1306_CS_PIN 5
+#define SET_RST palSetPad(SSD1306_RESET_PORT, SSD1306_RESET_PIN);
+#define CLR_RST palClearPad(SSD1306_RESET_PORT, SSD1306_RESET_PIN);
+
+/*
+ * SPI1 configuration structure.
+ * Speed 42MHz, CPHA=0, CPOL=0, 8bits frames, MSb transmitted first.
+ * The slave select line is the pin 4 on the port GPIOA.
+ */
+static const SPIConfig spi1config = {
+ NULL,
+ /* HW dependent part.*/
+ SSD1306_MISO_PORT,
+ SSD1306_MISO_PIN,
+ 0
+ //SPI_CR1_BR_0
+};
+
+#if GFX_USE_OS_CHIBIOS
+ static int32_t thdPriority = 0;
+#endif
+
+static inline void init_board(GDisplay *g) {
+ unsigned i;
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ // RESET pin.
+ palSetPadMode(SSD1306_RESET_PORT, SSD1306_RESET_PIN, PAL_MODE_OUTPUT_PUSHPULL);
+
+ palSetPadMode(SSD1306_MISO_PORT, SSD1306_MISO_PIN, PAL_MODE_ALTERNATE(1)|
+ PAL_STM32_OSPEED_HIGHEST);
+ palSetPadMode(SSD1306_MOSI_PORT, SSD1306_MOSI_PIN, PAL_MODE_ALTERNATE(1)|
+ PAL_STM32_OSPEED_HIGHEST);
+ palSetPadMode(SSD1306_SCK_PORT, SSD1306_SCK_PIN, PAL_MODE_ALTERNATE(1)|
+ PAL_STM32_OSPEED_HIGHEST);
+ palSetPad(SSD1306_CS_PORT, SSD1306_CS_PIN);
+ palSetPadMode(SSD1306_CS_PORT, SSD1306_CS_PIN, PAL_MODE_ALTERNATE(1)|
+ PAL_STM32_OSPEED_HIGHEST);
+ spiInit();
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ if(state)
+ CLR_RST
+ else
+ SET_RST
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+ #if GFX_USE_OS_CHIBIOS
+ thdPriority = (int32_t)chThdGetPriority();
+ chThdSetPriority(HIGHPRIO);
+ #endif
+ spiAcquireBus(&SPID1);
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+ #if GFX_USE_OS_CHIBIOS
+ chThdSetPriority(thdPriority);
+ #endif
+ spiReleaseBus(&SPID1);
+}
+
+static inline void write_cmd(GDisplay *g, uint8_t cmd) {
+ uint8_t command[2];
+
+ command[0] = 0x00; // Co = 0, D/C = 0
+ command[1] = cmd;
+
+ spiStart(&SPID1, &spi1config);
+ spiSelect(&SPID1);
+ spiStartSend(&SPID1, 2, command);
+ spiUnselect(&SPID1);
+ spiStop(&SPID1);
+}
+
+static inline void write_data(GDisplay *g, uint8_t* data, uint16_t length) {
+ (void) g;
+
+ spiStart(&SPID1, &spi1config);
+ spiSelect(&SPID1);
+ spiStartSend(&SPID1, length, data);
+ spiUnselect(&SPID1);
+ spiStop(&SPID1);
+}
+
+
+#endif /* _GDISP_LLD_BOARD_H */
+
diff --git a/boards/addons/gdisp/board_SSD1963_fsmc.h b/boards/addons/gdisp/board_SSD1963_fsmc.h
new file mode 100644
index 00000000..6c7119a4
--- /dev/null
+++ b/boards/addons/gdisp/board_SSD1963_fsmc.h
@@ -0,0 +1,105 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://chibios-gfx.com/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1963/board_SSD1963_fsmc.h
+ * @brief GDISP Graphic Driver subsystem board interface for the SSD1963 display.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+static const LCD_Parameters DisplayTimings[] = {
+ // You need one of these array elements per display
+ {
+ 480, 272, // Panel width and height
+ 2, 2, 41, // Horizontal Timings (back porch, front porch, pulse)
+ CALC_PERIOD(480,2,2,41), // Total Horizontal Period (calculated from above line)
+ 2, 2, 10, // Vertical Timings (back porch, front porch, pulse)
+ CALC_PERIOD(272,2,2,10), // Total Vertical Period (calculated from above line)
+ CALC_FPR(480,272,2,2,41,2,2,10,60ULL) // FPR - the 60ULL is the frames per second. Note the ULL!
+ },
+};
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+
+/* Using FSMC A16 as RS */
+#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */
+#define GDISP_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ #if defined(STM32F1XX) || defined(STM32F3XX)
+ /* FSMC setup for F1/F3 */
+ rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
+ #elif defined(STM32F4XX) || defined(STM32F2XX)
+ /* STM32F2-F4 FSMC init */
+ rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
+ #else
+ #error "FSMC not implemented for this device"
+ #endif
+
+ /* set pins to FSMC mode */
+ IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) |
+ (1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0};
+
+ IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
+ (1 << 13) | (1 << 14) | (1 << 15), 0};
+
+ palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
+ palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
+
+ /* FSMC timing */
+ FSMC_Bank1->BTCR[0+1] = (FSMC_BTR1_ADDSET_1 | FSMC_BTR1_ADDSET_3) \
+ | (FSMC_BTR1_DATAST_1 | FSMC_BTR1_DATAST_3) \
+ | (FSMC_BTR1_BUSTURN_1 | FSMC_BTR1_BUSTURN_3) ;
+
+ /* Bank1 NOR/SRAM control register configuration
+ * This is actually not needed as already set by default after reset */
+ FSMC_Bank1->BTCR[0] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+ /* FSMC delay reduced as the controller now runs at full speed */
+ FSMC_Bank1->BTCR[0+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0 ;
+ FSMC_Bank1->BTCR[0] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ GDISP_REG = index;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ GDISP_RAM = data;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
+
diff --git a/boards/addons/gdisp/board_SSD1963_gpio.h b/boards/addons/gdisp/board_SSD1963_gpio.h
new file mode 100644
index 00000000..0b9c0135
--- /dev/null
+++ b/boards/addons/gdisp/board_SSD1963_gpio.h
@@ -0,0 +1,102 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://chibios-gfx.com/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1963/board_SSD1963_gpio.h
+ * @brief GDISP Graphic Driver subsystem board interface for the SSD1963 display.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+static const LCD_Parameters DisplayTimings[] = {
+ // You need one of these array elements per display
+ {
+ 480, 272, // Panel width and height
+ 2, 2, 41, // Horizontal Timings (back porch, front porch, pulse)
+ CALC_PERIOD(480,2,2,41), // Total Horizontal Period (calculated from above line)
+ 2, 2, 10, // Vertical Timings (back porch, front porch, pulse)
+ CALC_PERIOD(272,2,2,10), // Total Vertical Period (calculated from above line)
+ CALC_FPR(480,272,2,2,41,2,2,10,60ULL) // FPR - the 60ULL is the frames per second. Note the ULL!
+ },
+};
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+
+/**
+ * @brief The GPIO pin config
+ *
+ * @details This block of defines tell your driver how you wired your display
+ * controller to your MCU. Please change them accordingly.
+ */
+#define GDISP_CMD_PORT GPIOC
+#define GDISP_DATA_PORT GPIOD
+#define GDISP_CS 0
+#define GDISP_RS 1
+#define GDISP_WR 2
+#define GDISP_RD 3
+
+#define Set_CS palSetPad(GDISP_CMD_PORT, GDISP_CS);
+#define Clr_CS palClearPad(GDISP_CMD_PORT, GDISP_CS);
+#define Set_RS palSetPad(GDISP_CMD_PORT, GDISP_RS);
+#define Clr_RS palClearPad(GDISP_CMD_PORT, GDISP_RS);
+#define Set_WR palSetPad(GDISP_CMD_PORT, GDISP_WR);
+#define Clr_WR palClearPad(GDISP_CMD_PORT, GDISP_WR);
+#define Set_RD palSetPad(GDISP_CMD_PORT, GDISP_RD);
+#define Clr_RD palClearPad(GDISP_CMD_PORT, GDISP_RD);
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ IOBus busCMD = {GDISP_CMD_PORT, (1 << GDISP_CS) | (1 << GDISP_RS) | (1 << GDISP_WR) | (1 << GDISP_RD), 0};
+ IOBus busDATA = {GDISP_CMD_PORT, 0xFFFFF, 0};
+ palSetBusMode(&busCMD, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetBusMode(&busDATA, PAL_MODE_OUTPUT_PUSHPULL);
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+ Set_CS;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+ Clr_CS;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ Set_RS; Clr_RD; Set_WR;
+ palWritePort(GDISP_DATA_PORT, index);
+ Clr_WR;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ Clr_RS; Clr_RD; Set_WR;
+ palWritePort(GDISP_DATA_PORT, data);
+ Clr_WR;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
+
diff --git a/boards/addons/gdisp/board_SSD2119_embest_dmstf4bb.h b/boards/addons/gdisp/board_SSD2119_embest_dmstf4bb.h
new file mode 100644
index 00000000..927e93a4
--- /dev/null
+++ b/boards/addons/gdisp/board_SSD2119_embest_dmstf4bb.h
@@ -0,0 +1,173 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD2119/board_SSD2119_embest_dmstf4bb.h
+ * @brief GDISP Graphic Driver subsystem board FSMC interface for the SSD2119 display.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+
+/* Using FSMC A19 (PE3) as DC */
+#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* DC = 0 */
+#define GDISP_RAM (*((volatile uint16_t *) 0x60100000)) /* DC = 1 */
+#define GDISP_DMA_STREAM STM32_DMA2_STREAM6
+
+#define SET_RST palSetPad(GPIOD, 3);
+#define CLR_RST palClearPad(GPIOD, 3);
+
+/*
+ * PWM configuration structure. We use timer 4 channel 2 (orange LED on board).
+ * The reason for so high clock is that with any lower, onboard coil is squeaking.
+ * The major disadvantage of this clock is a lack of linearity between PWM duty
+ * cycle width and brightness. In fact only with low preset one sees any change
+ * (eg. duty cycle between 1-20). Feel free to adjust this, maybe only my board
+ * behaves like this. According to the G5126 datesheet (backlight LED driver)
+ * the PWM frequency should be somewhere between 200 Hz to 200 kHz.
+ */
+static const PWMConfig pwmcfg = {
+ 1000000, /* 1 MHz PWM clock frequency. */
+ 100, /* PWM period is 100 cycles. */
+ NULL,
+ {
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL}
+ },
+ 0
+};
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ #if defined(STM32F4XX) || defined(STM32F2XX)
+ /* STM32F4 FSMC init */
+ rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
+
+ #if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
+ if (dmaStreamAllocate(GDISP_DMA_STREAM, 0, NULL, NULL))
+ gfxExit();
+ dmaStreamSetMemory0(GDISP_DMA_STREAM, &GDISP_RAM);
+ dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
+ #endif
+ #else
+ #error "FSMC not implemented for this device"
+ #endif
+
+ /* Group pins */
+ IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) |
+ (1 << 9) | (1 << 10) | (1 << 14) | (1 << 15), 0};
+
+ IOBus busE = {GPIOE, (1 << 3) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
+ (1 << 13) | (1 << 14) | (1 << 15), 0};
+
+ /* FSMC is an alternate function 12 (AF12) */
+ palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
+ palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
+
+ /* FSMC timing register configuration */
+ FSMC_Bank1->BTCR[0 + 1] = (FSMC_BTR1_ADDSET_2 | FSMC_BTR1_ADDSET_1) \
+ | (FSMC_BTR1_DATAST_2 | FSMC_BTR1_DATAST_1) \
+ | FSMC_BTR1_BUSTURN_0;
+
+ /* Bank1 NOR/PSRAM control register configuration
+ * Write enable, memory databus width set to 16 bit, memory bank enable */
+ FSMC_Bank1->BTCR[0] = FSMC_BCR1_WREN | FSMC_BCR1_MWID_0 | FSMC_BCR1_MBKEN;
+
+ /* Display backlight control */
+ /* TIM4 is an alternate function 2 (AF2) */
+ pwmStart(&PWMD4, &pwmcfg);
+ palSetPadMode(GPIOD, 13, PAL_MODE_ALTERNATE(2));
+ pwmEnableChannel(&PWMD4, 1, 100);
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ if (state) {
+ CLR_RST;
+ } else {
+ SET_RST;
+ }
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ pwmEnableChannel(&PWMD4, 1, percent);
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ GDISP_REG = index;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ GDISP_RAM = data;
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ return GDISP_RAM;
+}
+
+#if defined(GDISP_USE_DMA)
+ static inline void dma_with_noinc(GDisplay *g, color_t *buffer, int area) {
+ (void) g;
+ dmaStreamSetPeripheral(GDISP_DMA_STREAM, buffer);
+ dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
+ for (; area > 0; area -= 65535) {
+ dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area > 65535 ? 65535 : area);
+ dmaStreamEnable(GDISP_DMA_STREAM);
+ dmaWaitCompletion(GDISP_DMA_STREAM);
+ }
+ }
+
+ static inline void dma_with_inc(GDisplay *g, color_t *buffer, int area) {
+ (void) g;
+ dmaStreamSetPeripheral(GDISP_DMA_STREAM, buffer);
+ dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PINC | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
+ for (; area > 0; area -= 65535) {
+ dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area > 65535 ? 65535 : area);
+ dmaStreamEnable(GDISP_DMA_STREAM);
+ dmaWaitCompletion(GDISP_DMA_STREAM);
+ }
+ }
+#endif
+
+#endif /* _GDISP_LLD_BOARD_H */
+