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.

This commit is contained in:
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