aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gdisp
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2013-10-25 14:39:56 +1000
committerinmarket <andrewh@inmarket.com.au>2013-10-25 14:39:56 +1000
commite0b2406da613b02fce6af8aead160e43301a3852 (patch)
treead1b9368ac9ac6080bca13358ef45bc985778323 /drivers/gdisp
parent7a7e223d152b42553f7e6ce0220dd5d736b89c56 (diff)
downloaduGFX-e0b2406da613b02fce6af8aead160e43301a3852.tar.gz
uGFX-e0b2406da613b02fce6af8aead160e43301a3852.tar.bz2
uGFX-e0b2406da613b02fce6af8aead160e43301a3852.zip
Fix SSD1306 driver and board files to allow for seamless transfer of the command byte with the page line data without copying the data on to the stack.
Diffstat (limited to 'drivers/gdisp')
-rw-r--r--drivers/gdisp/SSD1306/board_SSD1306_i2c.h9
-rw-r--r--drivers/gdisp/SSD1306/board_SSD1306_spi.h9
-rw-r--r--drivers/gdisp/SSD1306/board_SSD1306_template.h6
-rw-r--r--drivers/gdisp/SSD1306/gdisp_lld.c26
4 files changed, 32 insertions, 18 deletions
diff --git a/drivers/gdisp/SSD1306/board_SSD1306_i2c.h b/drivers/gdisp/SSD1306/board_SSD1306_i2c.h
index 69c054f5..449d47ba 100644
--- a/drivers/gdisp/SSD1306/board_SSD1306_i2c.h
+++ b/drivers/gdisp/SSD1306/board_SSD1306_i2c.h
@@ -13,7 +13,8 @@
#ifndef _GDISP_LLD_BOARD_H
#define _GDISP_LLD_BOARD_H
-#define GDISP_BUS_MAX_TRANSFER_SIZE 64
+// 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.
@@ -116,14 +117,10 @@ static inline void write_cmd(GDisplay *g, uint8_t cmd) {
}
static inline void write_data(GDisplay *g, uint8_t* data, uint16_t length) {
- uint8_t command[1];
(void) g;
- command[0] = 0x40; // Co = 0, D/C = 1
-
i2cStart(&I2CD1, &i2cconfig);
- i2cMasterTransmitTimeout(&I2CD1, SSD1306_I2C_ADDRESS, command, 1, NULL, 0, MS2ST(10));
- i2cMasterTransmitTimeout(&I2CD1, SSD1306_I2C_ADDRESS, command, data, NULL, length, MS2ST(10));
+ i2cMasterTransmitTimeout(&I2CD1, SSD1306_I2C_ADDRESS, data, length, NULL, 0, MS2ST(10));
i2cStop(&I2CD1);
}
diff --git a/drivers/gdisp/SSD1306/board_SSD1306_spi.h b/drivers/gdisp/SSD1306/board_SSD1306_spi.h
index 476c51bf..5b481630 100644
--- a/drivers/gdisp/SSD1306/board_SSD1306_spi.h
+++ b/drivers/gdisp/SSD1306/board_SSD1306_spi.h
@@ -13,7 +13,8 @@
#ifndef _GDISP_LLD_BOARD_H
#define _GDISP_LLD_BOARD_H
-#define GDISP_BUS_MAX_TRANSFER_SIZE 64
+// 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.
@@ -49,10 +50,12 @@ static const SPIConfig spi1config = {
#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.
@@ -115,14 +118,10 @@ static inline void write_cmd(GDisplay *g, uint8_t cmd) {
}
static inline void write_data(GDisplay *g, uint8_t* data, uint16_t length) {
- uint8_t command[1];
(void) g;
- command[0] = 0x40; // Co = 0, D/C = 1
-
spiStart(&SPID1, &spi1config);
spiSelect(&SPID1);
- spiStartSend(&SPID1, 1, command);
spiStartSend(&SPID1, length, data);
spiUnselect(&SPID1);
spiStop(&SPID1);
diff --git a/drivers/gdisp/SSD1306/board_SSD1306_template.h b/drivers/gdisp/SSD1306/board_SSD1306_template.h
index ec7f44f5..5b4bd05c 100644
--- a/drivers/gdisp/SSD1306/board_SSD1306_template.h
+++ b/drivers/gdisp/SSD1306/board_SSD1306_template.h
@@ -17,12 +17,12 @@
#define _GDISP_LLD_BOARD_H
/**
- * @brief How many bytes to write in one operation when updating the display.
- * @note The screen size (in bytes) must evenly divide by this number.
+ * @brief Optional: A byte to prefix on each display page line.
+ * @note If not defined then no byte is prefixed on each page line.
*
* @notapi
*/
-#define GDISP_BUS_MAX_TRANSFER_SIZE 64
+//#define SSD1306_PAGE_PREFIX 0x40
/**
* @brief Initialise the board for the display.
diff --git a/drivers/gdisp/SSD1306/gdisp_lld.c b/drivers/gdisp/SSD1306/gdisp_lld.c
index 81b3b692..390a9282 100644
--- a/drivers/gdisp/SSD1306/gdisp_lld.c
+++ b/drivers/gdisp/SSD1306/gdisp_lld.c
@@ -36,6 +36,13 @@
#ifndef GDISP_INITIAL_BACKLIGHT
#define GDISP_INITIAL_BACKLIGHT 100
#endif
+#ifdef SSD1306_PAGE_PREFIX
+ #define SSD1306_PAGE_WIDTH (GDISP_SCREEN_WIDTH+1)
+ #define SSD1306_PAGE_OFFSET 1
+#else
+ #define SSD1306_PAGE_WIDTH GDISP_SCREEN_WIDTH
+ #define SSD1306_PAGE_OFFSET 0
+#endif
#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER<<0)
@@ -54,7 +61,7 @@
#define delay(us) gfxSleepMicroseconds(us)
#define delayms(ms) gfxSleepMilliseconds(ms)
-#define xyaddr(x, y) ((x) + ((y)>>3)*GDISP_SCREEN_WIDTH)
+#define xyaddr(x, y) (SSD1306_PAGE_OFFSET + (x) + ((y)>>3)*SSD1306_PAGE_WIDTH)
#define xybit(y) (1<<((y)&7))
/*===========================================================================*/
@@ -70,7 +77,18 @@
LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
// The private area is the display surface.
- g->priv = gfxAlloc(GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8);
+ g->priv = gfxAlloc(GDISP_SCREEN_HEIGHT/8 * SSD1306_PAGE_WIDTH);
+
+ // Fill in the prefix command byte on each page line of the display buffer
+ // We can do it during initialisation as this byte is never overwritten.
+ #ifdef SSD1306_PAGE_PREFIX
+ {
+ unsigned i;
+
+ for(i=0; i < GDISP_SCREEN_HEIGHT/8 * SSD1306_PAGE_WIDTH; i+=SSD1306_PAGE_WIDTH)
+ RAM(g)[i] = SSD1306_PAGE_PREFIX;
+ }
+ #endif
// Initialise the board interface
init_board(g);
@@ -131,8 +149,8 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
write_cmd(g, SSD1306_SETSTARTLINE | 0);
- for(i=0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT/8; i+=GDISP_BUS_MAX_TRANSFER_SIZE)
- write_data(g, RAM(g)+i, GDISP_BUS_MAX_TRANSFER_SIZE);
+ for(i=0; i < GDISP_SCREEN_HEIGHT/8 * SSD1306_PAGE_WIDTH; i+=SSD1306_PAGE_WIDTH)
+ write_data(g, RAM(g)+i, SSD1306_PAGE_WIDTH);
}
#endif