147 lines
3.7 KiB
C
147 lines
3.7 KiB
C
/*
|
|
* 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.io/license.html
|
|
*/
|
|
|
|
#ifndef _GDISP_LLD_BOARD_H
|
|
#define _GDISP_LLD_BOARD_H
|
|
|
|
#include "board_uext.h"
|
|
|
|
/*
|
|
* NOTE: This board file is for an SSD1306 running in I2C mode
|
|
* You will need to use a different board file for an SSD1306 running in SPI mode
|
|
*/
|
|
|
|
#define I2C_ADDRESS (0x78/2) // SSD1306 supports either 0x78 or 0x7A (including the write bit)
|
|
#define I2C_RATE 400000 // 400kHz is I2C FAST mode
|
|
|
|
// The various methods of driving the I2C interface
|
|
#define I2C_METHOD_CHIBIOS 3
|
|
|
|
// The various supported CPU's
|
|
#define CPU_AT91 1
|
|
|
|
// What methods are we using in this file
|
|
#define I2C_METHOD I2C_METHOD_CHIBIOS
|
|
#define CPU_METHOD CPU_AT91
|
|
|
|
// If using SPI_METHOD_CHIBIOS the CPU specific i2cconfig structure must be defined for your CPU
|
|
#if CPU_METHOD == CPU_AT91
|
|
#define I2C_CONFIG_REGISTER ((((MCK/I2C_RATE/2 - 3)>>8)<<16)|(((MCK/I2C_RATE/2 - 3)&0xFF)<<8)|(((MCK/I2C_RATE/2 - 3)&0xFF)<<0)) // For AT91SAM7: 8bit, CPOL=1, NCPHA = 0, ClockPhase=0, SCLK = 48Mhz/8 = 6MHz
|
|
#if I2C_METHOD == I2C_METHOD_CHIBIOS
|
|
// ChibiOS - Yuck! This structure is different on each platform.
|
|
// This is the one for the AT91
|
|
static const I2CConfig i2cconfig = {
|
|
I2C_CONFIG_REGISTER
|
|
};
|
|
#endif
|
|
#else
|
|
#error "SSD1306: Unsupported CPU"
|
|
#endif
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
/*
|
|
* Pin connection for the display to the UEXT connector:
|
|
*
|
|
* DISPLAY VCC UEXT PIN 1 (3.3V)
|
|
* DISPLAY GND UEXT PIN 2 (GND)
|
|
* DISPLAY SCL UEXT PIN 5 (SCL)
|
|
* DISPLAY SDA UEXT PIN 6 (SDA)
|
|
*/
|
|
|
|
#if I2C_METHOD == I2C_METHOD_CHIBIOS
|
|
|
|
/* ChibiOS can't send a separate data prefix byte in the same transaction as the real data.
|
|
* Nor does it support an address prefix to the data (such as an EEPROM would use).
|
|
* Instead we tell the driver to put it into the RAM buffer at the beginning of each page (Yuck!).
|
|
*
|
|
* Prefix bytes:
|
|
* 0x40 means all following bytes in this transaction go into the GDRAM.
|
|
* 0x00 means the following byte (singular) is a command byte.
|
|
*/
|
|
#define SSD1306_PAGE_PREFIX 0x40
|
|
|
|
#define I2C_INIT()
|
|
|
|
#define I2C_GETBUS() { \
|
|
i2cAcquireBus(UEXT_I2C); \
|
|
i2cStart(UEXT_I2C, &i2cconfig); \
|
|
}
|
|
|
|
#define I2C_RELEASEBUS() { \
|
|
i2cStop(UEXT_I2C); \
|
|
i2cReleaseBus(UEXT_I2C); \
|
|
}
|
|
|
|
#define I2C_WAITCOMPLETE()
|
|
#define I2C_WRITECMDBYTE(cmd) { \
|
|
gU8 data[2]; \
|
|
data[0] = 0; \
|
|
data[1] = cmd; \
|
|
i2cMasterTransmitTimeout (UEXT_I2C, I2C_ADDRESS, data, 2, 0, 0, TIME_INFINITE); \
|
|
}
|
|
#define I2C_WRITEBYTES(pdata, len) i2cMasterTransmitTimeout (UEXT_I2C, I2C_ADDRESS, pdata, length, 0, 0, TIME_INFINITE)
|
|
|
|
#else
|
|
#error "SSD1306 board file: Unsupported I2C method"
|
|
#endif
|
|
|
|
static GFXINLINE void init_board(GDisplay *g) {
|
|
(void) g;
|
|
|
|
I2C_INIT();
|
|
}
|
|
|
|
static GFXINLINE void post_init_board(GDisplay *g) {
|
|
(void) g;
|
|
}
|
|
|
|
static GFXINLINE void setpin_reset(GDisplay *g, gBool state) {
|
|
(void) g;
|
|
(void) state;
|
|
}
|
|
|
|
static GFXINLINE void set_backlight(GDisplay *g, gU8 percent) {
|
|
(void) g;
|
|
(void) percent;
|
|
}
|
|
|
|
static GFXINLINE void acquire_bus(GDisplay *g) {
|
|
(void) g;
|
|
|
|
I2C_GETBUS();
|
|
}
|
|
|
|
static GFXINLINE void release_bus(GDisplay *g) {
|
|
(void) g;
|
|
|
|
I2C_WAITCOMPLETE();
|
|
I2C_RELEASEBUS();
|
|
}
|
|
|
|
static GFXINLINE void write_cmd(GDisplay *g, gU8 cmd) {
|
|
(void) g;
|
|
|
|
I2C_WAITCOMPLETE();
|
|
|
|
// Command mode please
|
|
I2C_WRITECMDBYTE(cmd);
|
|
}
|
|
|
|
static GFXINLINE void write_data(GDisplay *g, gU8* data, gU16 length) {
|
|
(void) g;
|
|
|
|
I2C_WAITCOMPLETE();
|
|
|
|
// Data mode please
|
|
I2C_WRITEBYTES(data, length);
|
|
}
|
|
|
|
#endif /* _GDISP_LLD_BOARD_H */
|