aboutsummaryrefslogtreecommitdiffstats
path: root/boards/base/Olimex-SAM7EX256-GE8/board_SSD1306_i2c.h
blob: 7a9ef46a5181f08910c03e706898ad59f5ad4f43 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
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 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, uint8_t 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, uint8_t cmd) {
	(void) g;

	I2C_WAITCOMPLETE();

	// Command mode please
	I2C_WRITECMDBYTE(cmd);
}

static GFXINLINE 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 */