diff --git a/boards/base/Olimex-SAM7EX256-GE8/board_SSD1306_i2c.h b/boards/base/Olimex-SAM7EX256-GE8/board_SSD1306_i2c.h new file mode 100644 index 00000000..0818c3a5 --- /dev/null +++ b/boards/base/Olimex-SAM7EX256-GE8/board_SSD1306_i2c.h @@ -0,0 +1,146 @@ +/* + * 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.org/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) { \ + uint8_t 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 inline void init_board(GDisplay *g) { + (void) g; + + I2C_INIT(); +} + +static inline void post_init_board(GDisplay *g) { + (void) g; +} + +static inline void setpin_reset(GDisplay *g, bool_t state) { + (void) g; + (void) state; +} + +static inline void set_backlight(GDisplay *g, uint8_t percent) { + (void) g; + (void) percent; +} + +static inline void acquire_bus(GDisplay *g) { + (void) g; + + I2C_GETBUS(); +} + +static inline void release_bus(GDisplay *g) { + (void) g; + + I2C_WAITCOMPLETE(); + I2C_RELEASEBUS(); +} + +static inline void write_cmd(GDisplay *g, uint8_t cmd) { + (void) g; + + I2C_WAITCOMPLETE(); + + // Command mode please + I2C_WRITECMDBYTE(cmd); +} + +static inline void write_data(GDisplay *g, uint8_t* data, uint16_t length) { + (void) g; + + I2C_WAITCOMPLETE(); + + // Data mode please + I2C_WRITEBYTES(data, length); +} + +#endif /* _GDISP_LLD_BOARD_H */ diff --git a/boards/base/Olimex-SAM7EX256-GE8/board_SSD1306.h b/boards/base/Olimex-SAM7EX256-GE8/board_SSD1306_spi.h similarity index 91% rename from boards/base/Olimex-SAM7EX256-GE8/board_SSD1306.h rename to boards/base/Olimex-SAM7EX256-GE8/board_SSD1306_spi.h index 137808da..3585d287 100644 --- a/boards/base/Olimex-SAM7EX256-GE8/board_SSD1306.h +++ b/boards/base/Olimex-SAM7EX256-GE8/board_SSD1306_spi.h @@ -10,6 +10,10 @@ #include "board_uext.h" +/* + * NOTE: This board file is for an SSD1306 running in SPI mode + * You will need to use a different board file for an SSD1306 running in I2C mode + */ // The various methods of driving the SPI interface #define SPI_METHOD_PIO 1 #define SPI_METHOD_AT91 2 @@ -28,6 +32,16 @@ //--------------------------------------------------------------------- +/* + * 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 9 (SCK) + * DISPLAY SDA UEXT PIN 8 (MOSI) + * DISPLAY RST UEXT PIN 5 (SCL) + * DISPLAY D/C UEXT PIN 6 (SDA) + */ #define PORT_RESET UEXT_PORT_PIN5 #define PIN_RESET UEXT_PORTPIN_PIN5 #define PORT_DC UEXT_PORT_PIN6 @@ -42,7 +56,7 @@ #define PinSet(port,pin) palSetPad((port), (pin)) #define PinClear(port,pin) palClearPad((port), (pin)) #else - #error "TLS8204 board file: Unsupported PIO method" + #error "SSD1306 board file: Unsupported PIO method" #endif #if SPI_METHOD == SPI_METHOD_PIO @@ -144,7 +158,7 @@ #define SPI_WRITEBYTES(pdata, len) spiSend(UEXT_SPI, len, pdata) #else - #error "TLS8204 board file: Unsupported SPI method" + #error "SSD1306 board file: Unsupported SPI method" #endif static inline void init_board(GDisplay *g) {