diff --git a/boards/addons/gdisp/board_SSD1306_spi.h b/boards/addons/gdisp/board_SSD1306_spi.h index 5b647578..56e1abae 100644 --- a/boards/addons/gdisp/board_SSD1306_spi.h +++ b/boards/addons/gdisp/board_SSD1306_spi.h @@ -16,60 +16,65 @@ #ifndef _GDISP_LLD_BOARD_H #define _GDISP_LLD_BOARD_H -// Pin & SPI setup +// The command byte to put on the front of each page line +#define SSD1306_PAGE_PREFIX 0x40 // Co = 0, D/C = 1 -#define SPI_DRIVER (&SPID2) -#define SPI_PORT GPIOB -#define SCK_PAD 13 -#define MISO_PAD 14 -#define MOSI_PAD 15 +// 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); -#define CS_PORT GPIOC -#define RESET_PORT GPIOC -#define DNC_PORT GPIOC -#define CS_PAD 7 // 0 = chip selected -#define RESET_PAD 8 // 0 = reset -#define DNC_PAD 9 // control=0, data=1 +/* + * 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 = { + 0, + /* HW dependent part.*/ + SSD1306_MISO_PORT, + SSD1306_MISO_PIN, + 0 + //SPI_CR1_BR_0 +}; -static SPIConfig spi_cfg = { NULL, CS_PORT, CS_PAD, 0 }; +#if GFX_USE_OS_CHIBIOS + static int32_t thdPriority = 0; +#endif static inline void init_board(GDisplay *g) { - (void) g; - g->board = 0; - // Maximum speed of SSD1306 is 10Mhz, so set SPI speed less or = to that. - // - // STM32 specific setup - // STM32_PCLK1 is APB1 frequence in hertz. - // STM32_PCLK2 is APB2 frequence in hertz. - // See manual clock diagram to determine APB1 or APB2 for spi in use. - // SPI2 uses APB1 clock on stm32151 - // BR bits divide PCLK as follows - // 000 /2 = 16 MHz - // 001 /4 = 8 MHz - // 010 /8 = 4 MHz - // 011 /16 = 2 MHz - // 100 /32 = 1 MHz - // 101 /64 = 500 kHz - // 110 /128 = 250 kHz - // 111 /256 = 125 kHz - unsigned long spi_clk = STM32_PCLK1 / 2; - unsigned code = 0; - while (spi_clk > 10000000) { - code++; - spi_clk /= 2; - } - spi_cfg.cr1 |= (code << 3); - - if (g->controllerdisplay == 0) { - palSetPadMode(SPI_PORT, SCK_PAD, PAL_MODE_ALTERNATE(5)|PAL_STM32_OTYPE_PUSHPULL|PAL_STM32_OSPEED_MID2); - palSetPadMode(SPI_PORT, MOSI_PAD, PAL_MODE_ALTERNATE(5)|PAL_STM32_OTYPE_PUSHPULL|PAL_STM32_OSPEED_MID2); - palSetPadMode(SPI_PORT, MISO_PAD, PAL_MODE_ALTERNATE(5)); - palSetPadMode(RESET_PORT, RESET_PAD, PAL_MODE_OUTPUT_PUSHPULL); - palSetPadMode(CS_PORT, CS_PAD, PAL_MODE_OUTPUT_PUSHPULL); - palSetPadMode(DNC_PORT, DNC_PAD, PAL_MODE_OUTPUT_PUSHPULL); - palSetPad(CS_PORT, CS_PAD); - palSetPad(RESET_PORT, RESET_PAD); - palClearPad(DNC_PORT, DNC_PAD); + 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; } } @@ -77,39 +82,55 @@ static inline void post_init_board(GDisplay *g) { (void) g; } - static inline void setpin_reset(GDisplay *g, bool_t state) { (void) g; - palWritePad(RESET_PORT, RESET_PAD, !state); + if(state) + CLR_RST + else + SET_RST } static inline void acquire_bus(GDisplay *g) { (void) g; - spiAcquireBus(SPI_DRIVER); - spiStart(SPI_DRIVER, &spi_cfg); - spiSelect(SPI_DRIVER); + #if GFX_USE_OS_CHIBIOS + thdPriority = (int32_t)chThdGetPriority(); + chThdSetPriority(HIGHPRIO); + #endif + spiAcquireBus(&SPID1); } static inline void release_bus(GDisplay *g) { (void) g; - spiUnselect(SPI_DRIVER); - spiStop(SPI_DRIVER); - spiReleaseBus(SPI_DRIVER); + #if GFX_USE_OS_CHIBIOS + chThdSetPriority(thdPriority); + #endif + spiReleaseBus(&SPID1); } static inline void write_cmd(GDisplay *g, uint8_t cmd) { - (void) g; - static uint8_t buf; - palClearPad(DNC_PORT, DNC_PAD); - buf = cmd; - spiSend(SPI_DRIVER, 1, &buf); + uint8_t command[2]; + (void) g; + + 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; - palSetPad(DNC_PORT, DNC_PAD); - spiSend(SPI_DRIVER, length, data); + + 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_SSD1306_spi2.h b/boards/addons/gdisp/board_SSD1306_spi2.h new file mode 100644 index 00000000..5b647578 --- /dev/null +++ b/boards/addons/gdisp/board_SSD1306_spi2.h @@ -0,0 +1,115 @@ +/* + * 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 boards/addons/gdisp/board_SSD1306_spi.h + * @brief GDISP Graphic Driver subsystem board interface for the SSD1306 display. + * + * @note This file contains a mix of hardware specific and operating system specific + * code. You will need to change it for your CPU and/or operating system. + */ + +#ifndef _GDISP_LLD_BOARD_H +#define _GDISP_LLD_BOARD_H + +// Pin & SPI setup + +#define SPI_DRIVER (&SPID2) +#define SPI_PORT GPIOB +#define SCK_PAD 13 +#define MISO_PAD 14 +#define MOSI_PAD 15 + +#define CS_PORT GPIOC +#define RESET_PORT GPIOC +#define DNC_PORT GPIOC +#define CS_PAD 7 // 0 = chip selected +#define RESET_PAD 8 // 0 = reset +#define DNC_PAD 9 // control=0, data=1 + +static SPIConfig spi_cfg = { NULL, CS_PORT, CS_PAD, 0 }; + +static inline void init_board(GDisplay *g) { + (void) g; + g->board = 0; + // Maximum speed of SSD1306 is 10Mhz, so set SPI speed less or = to that. + // + // STM32 specific setup + // STM32_PCLK1 is APB1 frequence in hertz. + // STM32_PCLK2 is APB2 frequence in hertz. + // See manual clock diagram to determine APB1 or APB2 for spi in use. + // SPI2 uses APB1 clock on stm32151 + // BR bits divide PCLK as follows + // 000 /2 = 16 MHz + // 001 /4 = 8 MHz + // 010 /8 = 4 MHz + // 011 /16 = 2 MHz + // 100 /32 = 1 MHz + // 101 /64 = 500 kHz + // 110 /128 = 250 kHz + // 111 /256 = 125 kHz + unsigned long spi_clk = STM32_PCLK1 / 2; + unsigned code = 0; + while (spi_clk > 10000000) { + code++; + spi_clk /= 2; + } + spi_cfg.cr1 |= (code << 3); + + if (g->controllerdisplay == 0) { + palSetPadMode(SPI_PORT, SCK_PAD, PAL_MODE_ALTERNATE(5)|PAL_STM32_OTYPE_PUSHPULL|PAL_STM32_OSPEED_MID2); + palSetPadMode(SPI_PORT, MOSI_PAD, PAL_MODE_ALTERNATE(5)|PAL_STM32_OTYPE_PUSHPULL|PAL_STM32_OSPEED_MID2); + palSetPadMode(SPI_PORT, MISO_PAD, PAL_MODE_ALTERNATE(5)); + palSetPadMode(RESET_PORT, RESET_PAD, PAL_MODE_OUTPUT_PUSHPULL); + palSetPadMode(CS_PORT, CS_PAD, PAL_MODE_OUTPUT_PUSHPULL); + palSetPadMode(DNC_PORT, DNC_PAD, PAL_MODE_OUTPUT_PUSHPULL); + palSetPad(CS_PORT, CS_PAD); + palSetPad(RESET_PORT, RESET_PAD); + palClearPad(DNC_PORT, DNC_PAD); + } +} + +static inline void post_init_board(GDisplay *g) { + (void) g; +} + + +static inline void setpin_reset(GDisplay *g, bool_t state) { + (void) g; + palWritePad(RESET_PORT, RESET_PAD, !state); +} + +static inline void acquire_bus(GDisplay *g) { + (void) g; + spiAcquireBus(SPI_DRIVER); + spiStart(SPI_DRIVER, &spi_cfg); + spiSelect(SPI_DRIVER); +} + +static inline void release_bus(GDisplay *g) { + (void) g; + spiUnselect(SPI_DRIVER); + spiStop(SPI_DRIVER); + spiReleaseBus(SPI_DRIVER); +} + +static inline void write_cmd(GDisplay *g, uint8_t cmd) { + (void) g; + static uint8_t buf; + palClearPad(DNC_PORT, DNC_PAD); + buf = cmd; + spiSend(SPI_DRIVER, 1, &buf); +} + +static inline void write_data(GDisplay *g, uint8_t* data, uint16_t length) { + (void) g; + palSetPad(DNC_PORT, DNC_PAD); + spiSend(SPI_DRIVER, length, data); +} + + +#endif /* _GDISP_LLD_BOARD_H */ diff --git a/boards/base/Embest-STM32-DMSTF4BB/board_SSD2119.h b/boards/base/Embest-STM32-DMSTF4BB/board_SSD2119.h index 2b1aa27d..a8b42239 100644 --- a/boards/base/Embest-STM32-DMSTF4BB/board_SSD2119.h +++ b/boards/base/Embest-STM32-DMSTF4BB/board_SSD2119.h @@ -29,8 +29,8 @@ * 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. */ + 20000, /* 20 KHz PWM clock frequency. */ + 100, /* PWM period is 100 cycles. */ 0, { {PWM_OUTPUT_ACTIVE_HIGH, 0}, @@ -75,8 +75,11 @@ static inline void init_board(GDisplay *g) { 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_Bank1->BTCR[0 + 1] = (FSMC_BTR1_ADDSET_2 | FSMC_BTR1_ADDSET_1) \ +// | (FSMC_BTR1_DATAST_2 | FSMC_BTR1_DATAST_1) \ +// | FSMC_BTR1_BUSTURN_0; + FSMC_Bank1->BTCR[0 + 1] = (FSMC_BTR1_ADDSET_3 | FSMC_BTR1_ADDSET_0) \ + | (FSMC_BTR1_DATAST_3 | FSMC_BTR1_DATAST_0) \ | FSMC_BTR1_BUSTURN_0; /* Bank1 NOR/PSRAM control register configuration diff --git a/boards/base/Embest-STM32-DMSTF4BB/gmouse_lld_STMPE811_board.h b/boards/base/Embest-STM32-DMSTF4BB/gmouse_lld_STMPE811_board.h index bbb17010..43a8ad18 100644 --- a/boards/base/Embest-STM32-DMSTF4BB/gmouse_lld_STMPE811_board.h +++ b/boards/base/Embest-STM32-DMSTF4BB/gmouse_lld_STMPE811_board.h @@ -39,7 +39,7 @@ static const I2CConfig i2ccfg = { OPMODE_I2C, - 400000, + 200000, // Conservative please FAST_DUTY_CYCLE_2, }; diff --git a/drivers/gdisp/SSD2119/gdisp_lld_SSD2119.c b/drivers/gdisp/SSD2119/gdisp_lld_SSD2119.c index 08cddf96..36deeb90 100644 --- a/drivers/gdisp/SSD2119/gdisp_lld_SSD2119.c +++ b/drivers/gdisp/SSD2119/gdisp_lld_SSD2119.c @@ -152,7 +152,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay* g) { gfxSleepMicroseconds(5); // Configure pixel color format and MCU interface parameters. - write_reg(g, SSD2119_REG_ENTRY_MODE, 0x6830); // ENTRY_MODE_DEFAULT + write_reg(g, SSD2119_REG_ENTRY_MODE, 0x6838); // ENTRY_MODE_DEFAULT gfxSleepMicroseconds(5); // Set analog parameters. @@ -267,7 +267,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay* g) { #if GDISP_HARDWARE_FILLS && defined(GDISP_USE_DMA) LLDSPEC void gdisp_lld_fill_area(GDisplay* g) { - uint16_t c; + LLDCOLOR_TYPE c; c = gdispColor2Native(g->p.color); acquire_bus(g); @@ -285,7 +285,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay* g) { LLDSPEC void gdisp_lld_blit_area(GDisplay* g) { pixel_t* buffer; - coord_t ynct; + coord_t ycnt; buffer = (pixel_t*)g->p.ptr + g->p.x1 + g->p.y1 * g->p.x2; @@ -355,8 +355,8 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay* g) { switch((orientation_t)g->p.ptr) { case GDISP_ROTATE_0: acquire_bus(g); - /* ID = 11 AM = 0 */ - write_reg(g, SSD2119_REG_ENTRY_MODE, 0x6830); + /* ID = 11 AM = 1 */ + write_reg(g, SSD2119_REG_ENTRY_MODE, 0x6838); release_bus(g); g->g.Height = GDISP_SCREEN_HEIGHT; g->g.Width = GDISP_SCREEN_WIDTH; diff --git a/src/gos/gos_chibios.h b/src/gos/gos_chibios.h index 2580b88e..a3aba712 100644 --- a/src/gos/gos_chibios.h +++ b/src/gos/gos_chibios.h @@ -29,7 +29,7 @@ */ #if CH_KERNEL_MAJOR == 3 - typedef bool bool_t; + typedef char bool_t; #endif typedef systime_t delaytime_t;