diff options
| author | inmarket <andrewh@inmarket.com.au> | 2014-12-15 18:32:45 +1000 | 
|---|---|---|
| committer | inmarket <andrewh@inmarket.com.au> | 2014-12-15 18:32:45 +1000 | 
| commit | 17b921204cfaf09d31c16daff00c69360883c83e (patch) | |
| tree | 40d9ba808a68fa72cd8a48d7a1feceab0c5a04dd | |
| parent | 3936c630612c9aff74f3bc21984e486f81d3f7da (diff) | |
| parent | 262db6484498ec31baa8b9888aadb48e4f4984f3 (diff) | |
| download | uGFX-17b921204cfaf09d31c16daff00c69360883c83e.tar.gz uGFX-17b921204cfaf09d31c16daff00c69360883c83e.tar.bz2 uGFX-17b921204cfaf09d31c16daff00c69360883c83e.zip  | |
Split SSD1306 spi board example into 2 files.
Revert chibios 3.x use of bool as a base type for bool_t. back to char
bool is available on c++ compilers only!!!!
| -rw-r--r-- | boards/addons/gdisp/board_SSD1306_spi2.h | 115 | ||||
| -rw-r--r-- | drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c | 29 | ||||
| -rw-r--r-- | drivers/gdisp/SSD1306/gdisp_lld_config.h | 3 | 
3 files changed, 140 insertions, 7 deletions
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/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c b/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c index abea8365..2386c2d4 100644 --- a/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c +++ b/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c @@ -14,6 +14,7 @@  #include "src/gdisp/driver.h"  #include "board_SSD1306.h" +#include <string.h>   // for memset  /*===========================================================================*/  /* Driver local definitions.                                                 */ @@ -136,16 +137,32 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {  #if GDISP_HARDWARE_FLUSH  	LLDSPEC void gdisp_lld_flush(GDisplay *g) { -		unsigned	i; +		uint8_t * ram; +		unsigned pages;  		// Don't flush if we don't need it.  		if (!(g->flags & GDISP_FLG_NEEDFLUSH))  			return; +		ram = RAM(g); +		pages = GDISP_SCREEN_HEIGHT/8; +		acquire_bus(g);  		write_cmd(g, SSD1306_SETSTARTLINE | 0); -		for(i=0; i < GDISP_SCREEN_HEIGHT/8 * SSD1306_PAGE_WIDTH; i+=SSD1306_PAGE_WIDTH) -			write_data(g, RAM(g)+i, SSD1306_PAGE_WIDTH); +		while (pages--) { +			write_data(g, ram, SSD1306_PAGE_WIDTH); +			ram += SSD1306_PAGE_WIDTH; +		} +		release_bus(g); +	} +#endif + +#if GDISP_HARDWARE_CLEARS +	LLDSPEC void gdisp_lld_clear(GDisplay *g) { +		uint8_t fill = (g->p.color == Black) ? 0 : 0xff; +		int bytes = GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT/8; +		memset(RAM(g), fill, bytes); +		g->flags |= GDISP_FLG_NEEDFLUSH;  	}  #endif @@ -168,8 +185,8 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {  			y = GDISP_SCREEN_HEIGHT-1 - g->p.y;  			break;  		case GDISP_ROTATE_270: -			x = GDISP_SCREEN_HEIGHT-1 - g->p.y; -			x = g->p.x; +			x = GDISP_SCREEN_WIDTH-1 - g->p.y; +			y = g->p.x;  			break;  		}  		if (gdispColor2Native(g->p.color) != Black) @@ -199,7 +216,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {  			y = GDISP_SCREEN_HEIGHT-1 - g->p.y;  			break;  		case GDISP_ROTATE_270: -			x = GDISP_SCREEN_HEIGHT-1 - g->p.y; +			x = GDISP_SCREEN_WIDTH-1 - g->p.y;  			y = g->p.x;  			break;  		} diff --git a/drivers/gdisp/SSD1306/gdisp_lld_config.h b/drivers/gdisp/SSD1306/gdisp_lld_config.h index 2b805e86..9c502157 100644 --- a/drivers/gdisp/SSD1306/gdisp_lld_config.h +++ b/drivers/gdisp/SSD1306/gdisp_lld_config.h @@ -17,7 +17,8 @@  #define GDISP_HARDWARE_FLUSH			TRUE		// This controller requires flushing
  #define GDISP_HARDWARE_DRAWPIXEL		TRUE
  #define GDISP_HARDWARE_PIXELREAD		TRUE
 -#define GDISP_HARDWARE_CONTROL			TRUE
 +#define GDISP_HARDWARE_CONTROL      TRUE
 +#define GDISP_HARDWARE_CLEARS       TRUE
  #define GDISP_LLD_PIXELFORMAT			GDISP_PIXELFORMAT_MONO
  | 
