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:
parent
7a7e223d15
commit
e0b2406da6
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user