519 lines
20 KiB
C
Executable File
519 lines
20 KiB
C
Executable File
#include <linux/mutex.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/module.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/input.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/i2c.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/jiffies.h>
|
|
#include <linux/time.h>
|
|
#include <linux/cdev.h>
|
|
#include <asm/uaccess.h>
|
|
#include <linux/pm_runtime.h>
|
|
#include <linux/input/mt.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/async.h>
|
|
#include <linux/hrtimer.h>
|
|
#include <linux/init.h>
|
|
#include <linux/input.h>
|
|
#include <linux/ioport.h>
|
|
#include <linux/workqueue.h>
|
|
#include <linux/gpio.h>
|
|
#include <linux/irq.h>
|
|
#include <gsc3280/gpio.h>
|
|
#include <gsc3280/sysctl.h>
|
|
#include <asm/io.h>
|
|
|
|
#ifdef CONFIG_SSD1306_DEBUG
|
|
#define dbg(msg...) printk(KERN_INFO msg)
|
|
#else
|
|
#define dbg(msg...) do{}while(0)
|
|
#endif
|
|
|
|
struct gpio gsc3280_gpio[1] = {
|
|
{GSC3280_GPA(31), GPIOF_OUT_INIT_HIGH, "OLED_RST"},
|
|
};
|
|
|
|
#define gsc3280_set_gpio_reg_bit(reg) do{\
|
|
unsigned int reg_val = 0; \
|
|
reg_val = __raw_readl((volatile unsigned int *)(reg));\
|
|
reg_val |= (0x1<<gsc3280_gpio[0].gpio);\
|
|
__raw_writel(reg_val, (volatile unsigned int *)(reg));\
|
|
}while(0)
|
|
|
|
#define gsc3280_clr_gpio_reg_bit(reg) do{\
|
|
unsigned int reg_val = 0; \
|
|
reg_val = __raw_readl((volatile unsigned int *)(reg));\
|
|
reg_val &= ~(0x1<<gsc3280_gpio[0].gpio);\
|
|
__raw_writel(reg_val, (volatile unsigned int *)(reg));\
|
|
}while(0)
|
|
|
|
struct ssd1306_data{
|
|
int temp;
|
|
};
|
|
|
|
struct ssd1306_data *ssd1306_dev;
|
|
|
|
#define SSD1306_CMD 0
|
|
#define SSD1306_DAT 1
|
|
|
|
#define SSD1306_WIDTH 128
|
|
#define SSD1306_HEIGHT 64
|
|
|
|
static uint8_t s_chDispalyBuffer[128][8];
|
|
|
|
const uint8_t c_chFont1608[95][16] = {
|
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
|
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xCC,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
|
|
{0x00,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x00,0x00},/*""",2*/
|
|
{0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x00,0x00},/*"#",3*/
|
|
{0x00,0x00,0x0E,0x18,0x11,0x04,0x3F,0xFF,0x10,0x84,0x0C,0x78,0x00,0x00,0x00,0x00},/*"$",4*/
|
|
{0x0F,0x00,0x10,0x84,0x0F,0x38,0x00,0xC0,0x07,0x78,0x18,0x84,0x00,0x78,0x00,0x00},/*"%",5*/
|
|
{0x00,0x78,0x0F,0x84,0x10,0xC4,0x11,0x24,0x0E,0x98,0x00,0xE4,0x00,0x84,0x00,0x08},/*"&",6*/
|
|
{0x08,0x00,0x68,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
|
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x18,0x18,0x20,0x04,0x40,0x02,0x00,0x00},/*"(",8*/
|
|
{0x00,0x00,0x40,0x02,0x20,0x04,0x18,0x18,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*")",9*/
|
|
{0x02,0x40,0x02,0x40,0x01,0x80,0x0F,0xF0,0x01,0x80,0x02,0x40,0x02,0x40,0x00,0x00},/*"*",10*/
|
|
{0x00,0x80,0x00,0x80,0x00,0x80,0x0F,0xF8,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00},/*"+",11*/
|
|
{0x00,0x01,0x00,0x0D,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
|
|
{0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80},/*"-",13*/
|
|
{0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
|
|
{0x00,0x00,0x00,0x06,0x00,0x18,0x00,0x60,0x01,0x80,0x06,0x00,0x18,0x00,0x20,0x00},/*"/",15*/
|
|
{0x00,0x00,0x07,0xF0,0x08,0x08,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"0",16*/
|
|
{0x00,0x00,0x08,0x04,0x08,0x04,0x1F,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"1",17*/
|
|
{0x00,0x00,0x0E,0x0C,0x10,0x14,0x10,0x24,0x10,0x44,0x11,0x84,0x0E,0x0C,0x00,0x00},/*"2",18*/
|
|
{0x00,0x00,0x0C,0x18,0x10,0x04,0x11,0x04,0x11,0x04,0x12,0x88,0x0C,0x70,0x00,0x00},/*"3",19*/
|
|
{0x00,0x00,0x00,0xE0,0x03,0x20,0x04,0x24,0x08,0x24,0x1F,0xFC,0x00,0x24,0x00,0x00},/*"4",20*/
|
|
{0x00,0x00,0x1F,0x98,0x10,0x84,0x11,0x04,0x11,0x04,0x10,0x88,0x10,0x70,0x00,0x00},/*"5",21*/
|
|
{0x00,0x00,0x07,0xF0,0x08,0x88,0x11,0x04,0x11,0x04,0x18,0x88,0x00,0x70,0x00,0x00},/*"6",22*/
|
|
{0x00,0x00,0x1C,0x00,0x10,0x00,0x10,0xFC,0x13,0x00,0x1C,0x00,0x10,0x00,0x00,0x00},/*"7",23*/
|
|
{0x00,0x00,0x0E,0x38,0x11,0x44,0x10,0x84,0x10,0x84,0x11,0x44,0x0E,0x38,0x00,0x00},/*"8",24*/
|
|
{0x00,0x00,0x07,0x00,0x08,0x8C,0x10,0x44,0x10,0x44,0x08,0x88,0x07,0xF0,0x00,0x00},/*"9",25*/
|
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x03,0x0C,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
|
|
{0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
|
|
{0x00,0x00,0x00,0x80,0x01,0x40,0x02,0x20,0x04,0x10,0x08,0x08,0x10,0x04,0x00,0x00},/*"<",28*/
|
|
{0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x00,0x00},/*"=",29*/
|
|
{0x00,0x00,0x10,0x04,0x08,0x08,0x04,0x10,0x02,0x20,0x01,0x40,0x00,0x80,0x00,0x00},/*">",30*/
|
|
{0x00,0x00,0x0E,0x00,0x12,0x00,0x10,0x0C,0x10,0x6C,0x10,0x80,0x0F,0x00,0x00,0x00},/*"?",31*/
|
|
{0x03,0xE0,0x0C,0x18,0x13,0xE4,0x14,0x24,0x17,0xC4,0x08,0x28,0x07,0xD0,0x00,0x00},/*"@",32*/
|
|
{0x00,0x04,0x00,0x3C,0x03,0xC4,0x1C,0x40,0x07,0x40,0x00,0xE4,0x00,0x1C,0x00,0x04},/*"A",33*/
|
|
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x04,0x11,0x04,0x0E,0x88,0x00,0x70,0x00,0x00},/*"B",34*/
|
|
{0x03,0xE0,0x0C,0x18,0x10,0x04,0x10,0x04,0x10,0x04,0x10,0x08,0x1C,0x10,0x00,0x00},/*"C",35*/
|
|
{0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"D",36*/
|
|
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x04,0x17,0xC4,0x10,0x04,0x08,0x18,0x00,0x00},/*"E",37*/
|
|
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x00,0x17,0xC0,0x10,0x00,0x08,0x00,0x00,0x00},/*"F",38*/
|
|
{0x03,0xE0,0x0C,0x18,0x10,0x04,0x10,0x04,0x10,0x44,0x1C,0x78,0x00,0x40,0x00,0x00},/*"G",39*/
|
|
{0x10,0x04,0x1F,0xFC,0x10,0x84,0x00,0x80,0x00,0x80,0x10,0x84,0x1F,0xFC,0x10,0x04},/*"H",40*/
|
|
{0x00,0x00,0x10,0x04,0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x04,0x00,0x00,0x00,0x00},/*"I",41*/
|
|
{0x00,0x03,0x00,0x01,0x10,0x01,0x10,0x01,0x1F,0xFE,0x10,0x00,0x10,0x00,0x00,0x00},/*"J",42*/
|
|
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x03,0x80,0x14,0x64,0x18,0x1C,0x10,0x04,0x00,0x00},/*"K",43*/
|
|
{0x10,0x04,0x1F,0xFC,0x10,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x0C,0x00,0x00},/*"L",44*/
|
|
{0x10,0x04,0x1F,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x1F,0xFC,0x10,0x04,0x00,0x00},/*"M",45*/
|
|
{0x10,0x04,0x1F,0xFC,0x0C,0x04,0x03,0x00,0x00,0xE0,0x10,0x18,0x1F,0xFC,0x10,0x00},/*"N",46*/
|
|
{0x07,0xF0,0x08,0x08,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"O",47*/
|
|
{0x10,0x04,0x1F,0xFC,0x10,0x84,0x10,0x80,0x10,0x80,0x10,0x80,0x0F,0x00,0x00,0x00},/*"P",48*/
|
|
{0x07,0xF0,0x08,0x18,0x10,0x24,0x10,0x24,0x10,0x1C,0x08,0x0A,0x07,0xF2,0x00,0x00},/*"Q",49*/
|
|
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x00,0x11,0xC0,0x11,0x30,0x0E,0x0C,0x00,0x04},/*"R",50*/
|
|
{0x00,0x00,0x0E,0x1C,0x11,0x04,0x10,0x84,0x10,0x84,0x10,0x44,0x1C,0x38,0x00,0x00},/*"S",51*/
|
|
{0x18,0x00,0x10,0x00,0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x00,0x18,0x00,0x00,0x00},/*"T",52*/
|
|
{0x10,0x00,0x1F,0xF8,0x10,0x04,0x00,0x04,0x00,0x04,0x10,0x04,0x1F,0xF8,0x10,0x00},/*"U",53*/
|
|
{0x10,0x00,0x1E,0x00,0x11,0xE0,0x00,0x1C,0x00,0x70,0x13,0x80,0x1C,0x00,0x10,0x00},/*"V",54*/
|
|
{0x1F,0xC0,0x10,0x3C,0x00,0xE0,0x1F,0x00,0x00,0xE0,0x10,0x3C,0x1F,0xC0,0x00,0x00},/*"W",55*/
|
|
{0x10,0x04,0x18,0x0C,0x16,0x34,0x01,0xC0,0x01,0xC0,0x16,0x34,0x18,0x0C,0x10,0x04},/*"X",56*/
|
|
{0x10,0x00,0x1C,0x00,0x13,0x04,0x00,0xFC,0x13,0x04,0x1C,0x00,0x10,0x00,0x00,0x00},/*"Y",57*/
|
|
{0x08,0x04,0x10,0x1C,0x10,0x64,0x10,0x84,0x13,0x04,0x1C,0x04,0x10,0x18,0x00,0x00},/*"Z",58*/
|
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFE,0x40,0x02,0x40,0x02,0x40,0x02,0x00,0x00},/*"[",59*/
|
|
{0x00,0x00,0x30,0x00,0x0C,0x00,0x03,0x80,0x00,0x60,0x00,0x1C,0x00,0x03,0x00,0x00},/*"\",60*/
|
|
{0x00,0x00,0x40,0x02,0x40,0x02,0x40,0x02,0x7F,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},/*"]",61*/
|
|
{0x00,0x00,0x00,0x00,0x20,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x00,0x00},/*"^",62*/
|
|
{0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01},/*"_",63*/
|
|
{0x00,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
|
|
{0x00,0x00,0x00,0x98,0x01,0x24,0x01,0x44,0x01,0x44,0x01,0x44,0x00,0xFC,0x00,0x04},/*"a",65*/
|
|
{0x10,0x00,0x1F,0xFC,0x00,0x88,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x70,0x00,0x00},/*"b",66*/
|
|
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x00},/*"c",67*/
|
|
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x11,0x08,0x1F,0xFC,0x00,0x04},/*"d",68*/
|
|
{0x00,0x00,0x00,0xF8,0x01,0x44,0x01,0x44,0x01,0x44,0x01,0x44,0x00,0xC8,0x00,0x00},/*"e",69*/
|
|
{0x00,0x00,0x01,0x04,0x01,0x04,0x0F,0xFC,0x11,0x04,0x11,0x04,0x11,0x00,0x18,0x00},/*"f",70*/
|
|
{0x00,0x00,0x00,0xD6,0x01,0x29,0x01,0x29,0x01,0x29,0x01,0xC9,0x01,0x06,0x00,0x00},/*"g",71*/
|
|
{0x10,0x04,0x1F,0xFC,0x00,0x84,0x01,0x00,0x01,0x00,0x01,0x04,0x00,0xFC,0x00,0x04},/*"h",72*/
|
|
{0x00,0x00,0x01,0x04,0x19,0x04,0x19,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"i",73*/
|
|
{0x00,0x00,0x00,0x03,0x00,0x01,0x01,0x01,0x19,0x01,0x19,0xFE,0x00,0x00,0x00,0x00},/*"j",74*/
|
|
{0x10,0x04,0x1F,0xFC,0x00,0x24,0x00,0x40,0x01,0xB4,0x01,0x0C,0x01,0x04,0x00,0x00},/*"k",75*/
|
|
{0x00,0x00,0x10,0x04,0x10,0x04,0x1F,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"l",76*/
|
|
{0x01,0x04,0x01,0xFC,0x01,0x04,0x01,0x00,0x01,0xFC,0x01,0x04,0x01,0x00,0x00,0xFC},/*"m",77*/
|
|
{0x01,0x04,0x01,0xFC,0x00,0x84,0x01,0x00,0x01,0x00,0x01,0x04,0x00,0xFC,0x00,0x04},/*"n",78*/
|
|
{0x00,0x00,0x00,0xF8,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x00,0xF8,0x00,0x00},/*"o",79*/
|
|
{0x01,0x01,0x01,0xFF,0x00,0x85,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x70,0x00,0x00},/*"p",80*/
|
|
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x01,0x05,0x01,0xFF,0x00,0x01},/*"q",81*/
|
|
{0x01,0x04,0x01,0x04,0x01,0xFC,0x00,0x84,0x01,0x04,0x01,0x00,0x01,0x80,0x00,0x00},/*"r",82*/
|
|
{0x00,0x00,0x00,0xCC,0x01,0x24,0x01,0x24,0x01,0x24,0x01,0x24,0x01,0x98,0x00,0x00},/*"s",83*/
|
|
{0x00,0x00,0x01,0x00,0x01,0x00,0x07,0xF8,0x01,0x04,0x01,0x04,0x00,0x00,0x00,0x00},/*"t",84*/
|
|
{0x01,0x00,0x01,0xF8,0x00,0x04,0x00,0x04,0x00,0x04,0x01,0x08,0x01,0xFC,0x00,0x04},/*"u",85*/
|
|
{0x01,0x00,0x01,0x80,0x01,0x70,0x00,0x0C,0x00,0x10,0x01,0x60,0x01,0x80,0x01,0x00},/*"v",86*/
|
|
{0x01,0xF0,0x01,0x0C,0x00,0x30,0x01,0xC0,0x00,0x30,0x01,0x0C,0x01,0xF0,0x01,0x00},/*"w",87*/
|
|
{0x00,0x00,0x01,0x04,0x01,0x8C,0x00,0x74,0x01,0x70,0x01,0x8C,0x01,0x04,0x00,0x00},/*"x",88*/
|
|
{0x01,0x01,0x01,0x81,0x01,0x71,0x00,0x0E,0x00,0x18,0x01,0x60,0x01,0x80,0x01,0x00},/*"y",89*/
|
|
{0x00,0x00,0x01,0x84,0x01,0x0C,0x01,0x34,0x01,0x44,0x01,0x84,0x01,0x0C,0x00,0x00},/*"z",90*/
|
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x3E,0xFC,0x40,0x02,0x40,0x02},/*"{",91*/
|
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},/*"|",92*/
|
|
{0x00,0x00,0x40,0x02,0x40,0x02,0x3E,0xFC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
|
|
{0x00,0x00,0x60,0x00,0x80,0x00,0x80,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x20,0x00},/*"~",94*/
|
|
};
|
|
|
|
|
|
struct i2c_client *ssd1306_client;
|
|
|
|
static void ssd1306_write_byte(uint8_t chData, uint8_t chCmd)
|
|
{
|
|
uint8_t cmd = 0x00;
|
|
uint8_t tmp[2];
|
|
|
|
memset(tmp,0,2);
|
|
|
|
if (chCmd) {
|
|
cmd = 0x40;
|
|
} else {
|
|
cmd = 0x00;
|
|
}
|
|
|
|
tmp[0] = cmd;
|
|
tmp[1] = chData;
|
|
|
|
i2c_master_send(ssd1306_client, tmp , 2);
|
|
}
|
|
|
|
#if 0
|
|
int ssd1306_read_bytes(uint8_t *data, uint16_t len)
|
|
{
|
|
return i2c_master_recv(ssd1306_client, data, len);
|
|
}
|
|
#endif
|
|
|
|
|
|
void ssd1306_display_on(void)
|
|
{
|
|
printk(KERN_INFO "ssd1306_display_on\n");
|
|
ssd1306_write_byte(0x8D, SSD1306_CMD);
|
|
ssd1306_write_byte(0x14, SSD1306_CMD);
|
|
ssd1306_write_byte(0xAF, SSD1306_CMD);
|
|
}
|
|
|
|
/**
|
|
* @brief OLED turns off
|
|
*
|
|
* @param None
|
|
*
|
|
* @retval None
|
|
**/
|
|
void ssd1306_display_off(void)
|
|
{
|
|
ssd1306_write_byte(0x8D, SSD1306_CMD);
|
|
ssd1306_write_byte(0x10, SSD1306_CMD);
|
|
ssd1306_write_byte(0xAE, SSD1306_CMD);
|
|
}
|
|
|
|
void ssd1306_refresh_gram(void)
|
|
{
|
|
uint8_t i, j;
|
|
|
|
for (i = 0; i < 8; i ++) {
|
|
ssd1306_write_byte(0xB0 + i, SSD1306_CMD);
|
|
ssd1306_write_byte(0x02, SSD1306_CMD);
|
|
ssd1306_write_byte(0x10, SSD1306_CMD);
|
|
for (j = 0; j < 128; j ++) {
|
|
ssd1306_write_byte(s_chDispalyBuffer[j][i], SSD1306_DAT);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void ssd1306_clear_screen(uint8_t chFill)
|
|
{
|
|
memset(s_chDispalyBuffer,chFill, sizeof(s_chDispalyBuffer));
|
|
ssd1306_refresh_gram();
|
|
}
|
|
|
|
/**
|
|
* @brief Draws a piont on the screen
|
|
*
|
|
* @param chXpos: Specifies the X position
|
|
* @param chYpos: Specifies the Y position
|
|
* @param chPoint: 0: the point turns off 1: the piont turns on
|
|
*
|
|
* @retval None
|
|
**/
|
|
|
|
void ssd1306_draw_point(uint8_t chXpos, uint8_t chYpos, uint8_t chPoint)
|
|
{
|
|
uint8_t chPos, chBx, chTemp = 0;
|
|
|
|
if (chXpos > 127 || chYpos > 63) {
|
|
return;
|
|
}
|
|
chPos = 7 - chYpos / 8; //
|
|
chBx = chYpos % 8;
|
|
chTemp = 1 << (7 - chBx);
|
|
|
|
if (chPoint) {
|
|
s_chDispalyBuffer[chXpos][chPos] |= chTemp;
|
|
|
|
} else {
|
|
s_chDispalyBuffer[chXpos][chPos] &= ~chTemp;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Fills a rectangle
|
|
*
|
|
* @param chXpos1: Specifies the X position 1 (X top left position)
|
|
* @param chYpos1: Specifies the Y position 1 (Y top left position)
|
|
* @param chXpos2: Specifies the X position 2 (X bottom right position)
|
|
* @param chYpos3: Specifies the Y position 2 (Y bottom right position)
|
|
*
|
|
* @retval
|
|
**/
|
|
|
|
void ssd1306_fill_screen(uint8_t chXpos1, uint8_t chYpos1, uint8_t chXpos2, uint8_t chYpos2, uint8_t chDot)
|
|
{
|
|
uint8_t chXpos, chYpos;
|
|
|
|
for (chXpos = chXpos1; chXpos <= chXpos2; chXpos ++) {
|
|
for (chYpos = chYpos1; chYpos <= chYpos2; chYpos ++) {
|
|
ssd1306_draw_point(chXpos, chYpos, chDot);
|
|
}
|
|
}
|
|
|
|
ssd1306_refresh_gram();
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Displays one character at the specified position
|
|
*
|
|
* @param chXpos: Specifies the X position
|
|
* @param chYpos: Specifies the Y position
|
|
* @param chSize:
|
|
* @param chMode
|
|
* @retval
|
|
**/
|
|
void ssd1306_display_char(uint8_t chXpos, uint8_t chYpos, uint8_t chChr, uint8_t chSize, uint8_t chMode)
|
|
{
|
|
uint8_t i, j;
|
|
uint8_t chTemp, chYpos0 = chYpos;
|
|
|
|
chChr = chChr - ' ';
|
|
for (i = 0; i < chSize; i ++) {
|
|
if (chMode) {
|
|
chTemp = c_chFont1608[chChr][i];
|
|
} else {
|
|
chTemp = ~c_chFont1608[chChr][i];
|
|
}
|
|
|
|
for (j = 0; j < 8; j ++) {
|
|
if (chTemp & 0x80) {
|
|
ssd1306_draw_point(chXpos, chYpos, 1);
|
|
} else {
|
|
ssd1306_draw_point(chXpos, chYpos, 0);
|
|
}
|
|
chTemp <<= 1;
|
|
chYpos ++;
|
|
|
|
if ((chYpos - chYpos0) == chSize) {
|
|
chYpos = chYpos0;
|
|
chXpos ++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Displays a string on the screen
|
|
*
|
|
* @param chXpos: Specifies the X position
|
|
* @param chYpos: Specifies the Y position
|
|
* @param pchString: Pointer to a string to display on the screen
|
|
*
|
|
* @retval None
|
|
**/
|
|
void ssd1306_display_string(uint8_t chXpos, uint8_t chYpos, const uint8_t *pchString, uint8_t chSize, uint8_t chMode)
|
|
{
|
|
while (*pchString != '\0') {
|
|
if (chXpos > (SSD1306_WIDTH - chSize / 2)) {
|
|
chXpos = 0;
|
|
chYpos += chSize;
|
|
if (chYpos > (SSD1306_HEIGHT - chSize)) {
|
|
chYpos = chXpos = 0;
|
|
ssd1306_clear_screen(0x00);
|
|
}
|
|
}
|
|
|
|
ssd1306_display_char(chXpos, chYpos, *pchString, chSize, chMode);
|
|
chXpos += chSize / 2;
|
|
pchString ++;
|
|
}
|
|
}
|
|
|
|
|
|
void ssd1306_init(void)
|
|
{
|
|
|
|
printk(KERN_INFO "ssd1306_init\n");
|
|
ssd1306_write_byte(0xAE, SSD1306_CMD);//--turn off oled panel
|
|
ssd1306_write_byte(0x00, SSD1306_CMD);//---set low column address
|
|
ssd1306_write_byte(0x10, SSD1306_CMD);//---set high column address
|
|
ssd1306_write_byte(0x40, SSD1306_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
|
|
ssd1306_write_byte(0x81, SSD1306_CMD);//--set contrast control register
|
|
ssd1306_write_byte(0xCF, SSD1306_CMD);// Set SEG Output Current Brightness
|
|
ssd1306_write_byte(0xA1, SSD1306_CMD);//--Set SEG/Column Mapping
|
|
ssd1306_write_byte(0xC0, SSD1306_CMD);//Set COM/Row Scan Direction
|
|
ssd1306_write_byte(0xA6, SSD1306_CMD);//--set normal display
|
|
ssd1306_write_byte(0xA8, SSD1306_CMD);//--set multiplex ratio(1 to 64)
|
|
ssd1306_write_byte(0x3f, SSD1306_CMD);//--1/64 duty
|
|
ssd1306_write_byte(0xD3, SSD1306_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
|
|
ssd1306_write_byte(0x00, SSD1306_CMD);//-not offset
|
|
ssd1306_write_byte(0xd5, SSD1306_CMD);//--set display clock divide ratio/oscillator frequency
|
|
ssd1306_write_byte(0x80, SSD1306_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
|
|
ssd1306_write_byte(0xD9, SSD1306_CMD);//--set pre-charge period
|
|
ssd1306_write_byte(0xF1, SSD1306_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
|
|
ssd1306_write_byte(0xDA, SSD1306_CMD);//--set com pins hardware configuration
|
|
ssd1306_write_byte(0x12, SSD1306_CMD);
|
|
ssd1306_write_byte(0xDB, SSD1306_CMD);//--set vcomh
|
|
ssd1306_write_byte(0x40, SSD1306_CMD);//Set VCOM Deselect Level
|
|
ssd1306_write_byte(0x20, SSD1306_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
|
|
ssd1306_write_byte(0x02, SSD1306_CMD);//
|
|
ssd1306_write_byte(0x8D, SSD1306_CMD);//--set Charge Pump enable/disable
|
|
ssd1306_write_byte(0x14, SSD1306_CMD);//--set(0x10) disable
|
|
ssd1306_write_byte(0xA4, SSD1306_CMD);// Disable Entire Display On (0xa4/0xa5)
|
|
ssd1306_write_byte(0xA6, SSD1306_CMD);// Disable Inverse Display On (0xa6/a7)
|
|
ssd1306_write_byte(0xAF, SSD1306_CMD);//--turn on oled panel
|
|
ssd1306_display_on();
|
|
ssd1306_clear_screen(0xff);
|
|
|
|
}
|
|
|
|
#if 0
|
|
static int ssd1306_detect(struct i2c_adapter *adapter, int address, int kind)
|
|
{
|
|
printk(KERN_INFO "ssd1306_detect\n");
|
|
|
|
ssd1306_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
|
|
ssd1306_client->addr = address;
|
|
ssd1306_client->adapter = adapter;
|
|
ssd1306_client->driver = &ssd1306_driver;
|
|
strcpy(ssd1306_client->name, "ssd1306");
|
|
|
|
i2c_attach_client(ssd1306_client);
|
|
|
|
ssd1306_init();
|
|
|
|
ssd1306_clear_screen(0x00);
|
|
ssd1306_display_off();
|
|
|
|
ssd1306_display_string(18, 0, "hello, Linux!", 16, 1);
|
|
ssd1306_display_string(0, 16, "this is an i2c driver demo!", 16, 1);
|
|
ssd1306_refresh_gram();
|
|
ssd1306_display_on();
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int ssd1306_probe(struct i2c_adapter *adapter)
|
|
{
|
|
return i2c_probe(adapter, &addr_data, ssd1306_detect);
|
|
}
|
|
#endif
|
|
|
|
static int ssd1306_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|
{
|
|
int err;
|
|
|
|
printk(KERN_INFO "________________________ssd1306_probe\n");
|
|
|
|
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
|
err = -ENODEV;
|
|
return err;
|
|
}
|
|
|
|
ssd1306_client = client;
|
|
ssd1306_client->addr = client->addr;
|
|
|
|
ssd1306_dev = kzalloc(sizeof(*ssd1306_dev),GFP_KERNEL);
|
|
if(!ssd1306_dev)
|
|
{
|
|
err = -ENOMEM;
|
|
return -1;
|
|
}
|
|
|
|
i2c_set_clientdata(ssd1306_client, ssd1306_dev);
|
|
|
|
ssd1306_init();
|
|
|
|
ssd1306_clear_screen(0x00);
|
|
ssd1306_display_off();
|
|
|
|
ssd1306_display_string(18, 0, "hello, Linux!", 16, 1);
|
|
ssd1306_display_string(0, 16, "this is an i2c driver demo!", 16, 1);
|
|
ssd1306_refresh_gram();
|
|
ssd1306_display_on();
|
|
|
|
printk(KERN_INFO "ssd1306_work_ok\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int __devexit ssd1306_remove(struct i2c_client *client)
|
|
{
|
|
printk(KERN_INFO "ssd1306_detach\n");
|
|
|
|
ssd1306_display_off();
|
|
ssd1306_clear_screen(0x00);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const struct i2c_device_id ssd1306_id[]={
|
|
{"ssd1306", 0},
|
|
{ },
|
|
};
|
|
|
|
static struct i2c_driver ssd1306_driver = {
|
|
.driver = {
|
|
.name = "ssd1306",
|
|
.owner = THIS_MODULE,
|
|
},
|
|
.probe = ssd1306_probe,
|
|
.remove = __devexit_p(ssd1306_remove),
|
|
.id_table = ssd1306_id,
|
|
|
|
};
|
|
|
|
|
|
static int __init ssd1306_module_init(void)
|
|
{
|
|
int ret = -1;
|
|
|
|
printk(KERN_INFO "ssd1306 driver init...\n");
|
|
ret = i2c_add_driver(&ssd1306_driver);
|
|
if(ret < 0)
|
|
printk(KERN_INFO "add ssd1306 driver fail......\n");
|
|
return ret;
|
|
}
|
|
|
|
static void __exit ssd1306_module_exit(void)
|
|
{
|
|
printk(KERN_INFO "ssd1306 driver exit...\n");
|
|
i2c_del_driver(&ssd1306_driver);
|
|
}
|
|
|
|
module_init(ssd1306_module_init);
|
|
module_exit(ssd1306_module_exit);
|
|
|
|
MODULE_AUTHOR("songxingjia@china-cpu.com");
|
|
MODULE_DESCRIPTION("OLED SSD1306 DRIVER");
|
|
MODULE_LICENSE("GPL");
|