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.

ugfx_release_2.6
inmarket 2013-10-25 14:39:56 +10:00
parent 7a7e223d15
commit e0b2406da6
4 changed files with 32 additions and 18 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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.

View File

@ -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