在linux下调试oled12864显示屏

通过i2c方式在linux3.10下调试oled12864显示屏
在这里插入图片描述
调试步骤:
1、确认硬件
1.1、确认硬件连接是spi还是i2c(本文采用的是通过i2c方式)。
1.2、检查硬件是否有肉眼可见的问题(虚焊或脱落)。
2、修改驱动代码
2.1、在drivers/video下选择合适的驱动代码(仅仅是找个驱动框架,也可以自己写),并在dts的对应i2c中添加对应的内容。
2.2、参考中景园中51单片机的代码,借用里面初始化代码和read、write函数,并在linux3.10下驱动代码中实现这些功能。
2.3、调通关键是i2c是否能读到设备地址的内容,如果能读到即代表完成了80%。
2.4、实现应用层需要调用驱动的接口。
2.5、写应用测试程序来验证屏幕能否正常显示。

本人调试遇到问题:
1、主控通过i2c不能读到oled屏设备内容,而且不断发送无法响应
分析:
1.1、检查是否有设备节点生成。
1.2、在i2c发送数据前将发送内容打印出来,确认发送内容是否存在问题。
1.3、通过示波器测量时钟信号和数据信号查看是否能测出来,并查看高低电平的值是多少。
1.4、前面3种办法无法查出问题,可以通过代码实现发送指定内容,然后在屏设备这边用逻积分析仪查看内容是否一致。
通过分析得知主控发送到oled的电压高低电平是0V和1.8V,但oled屏需要0V和3.3V才能驱动,所以硬件修改了下,然后就可以读到内容了。

参考博客:
https://blog.csdn.net/qq_33553024/article/details/84783587

附代码:(代码测试可用)
dts:
ssd1307: oled@3c {
compatible = “solomon,ssd1307fb-i2c”;
reg = <0x3c>;
reset-gpios = <&gpio2 GPIO_A10 5>;
};

drivers:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/fb.h>
#include <linux/uaccess.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/pwm.h>
#include <linux/delay.h>

#define SSD1307FB_WIDTH 128
#define SSD1307FB_HEIGHT 64

#define SSD1307FB_DATA 0x40
#define SSD1307FB_COMMAND 0x00

int mark = 0;

#define Max_Column 128
#define Max_Row 64

#define SSD1307FB_CONTRAST 0x81
#define SSD1307FB_SEG_REMAP_ON 0xa1
#define SSD1307FB_DISPLAY_OFF 0xae
#define SSD1307FB_DISPLAY_ON 0xaf
#define SSD1307FB_START_PAGE_ADDRESS 0xb0

#if 1
unsigned char F6x8[][6] =
{
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},// sp
{0x00, 0x00, 0x00, 0x2f, 0x00, 0x00},// !
{0x00, 0x00, 0x07, 0x00, 0x07, 0x00},// "
{0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14},// #
{0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12},// $
{0x00, 0x62, 0x64, 0x08, 0x13, 0x23},// %
{0x00, 0x36, 0x49, 0x55, 0x22, 0x50},// &
{0x00, 0x00, 0x05, 0x03, 0x00, 0x00},// ’
{0x00, 0x00, 0x1c, 0x22, 0x41, 0x00},// (
{0x00, 0x00, 0x41, 0x22, 0x1c, 0x00},// )
{0x00, 0x14, 0x08, 0x3E, 0x08, 0x14},// *
{0x00, 0x08, 0x08, 0x3E, 0x08, 0x08},// +
{0x00, 0x00, 0x00, 0xA0, 0x60, 0x00},// ,
{0x00, 0x08, 0x08, 0x08, 0x08, 0x08},// -
{0x00, 0x00, 0x60, 0x60, 0x00, 0x00},// .
{0x00, 0x20, 0x10, 0x08, 0x04, 0x02},// /
{0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E},// 0
{0x00, 0x00, 0x42, 0x7F, 0x40, 0x00},// 1
{0x00, 0x42, 0x61, 0x51, 0x49, 0x46},// 2
{0x00, 0x21, 0x41, 0x45, 0x4B, 0x31},// 3
{0x00, 0x18, 0x14, 0x12, 0x7F, 0x10},// 4
{0x00, 0x27, 0x45, 0x45, 0x45, 0x39},// 5
{0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30},// 6
{0x00, 0x01, 0x71, 0x09, 0x05, 0x03},// 7
{0x00, 0x36, 0x49, 0x49, 0x49, 0x36},// 8
{0x00, 0x06, 0x49, 0x49, 0x29, 0x1E},// 9
{0x00, 0x00, 0x36, 0x36, 0x00, 0x00},// :
{0x00, 0x00, 0x56, 0x36, 0x00, 0x00},// ;
{0x00, 0x08, 0x14, 0x22, 0x41, 0x00},// <
{0x00, 0x14, 0x14, 0x14, 0x14, 0x14},// =
{0x00, 0x00, 0x41, 0x22, 0x14, 0x08},// >
{0x00, 0x02, 0x01, 0x51, 0x09, 0x06},// ?
{0x00, 0x32, 0x49, 0x59, 0x51, 0x3E},// @
{0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C},// A
{0x00, 0x7F, 0x49, 0x49, 0x49, 0x36},// B
{0x00, 0x3E, 0x41, 0x41, 0x41, 0x22},// C
{0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C},// D
{0x00, 0x7F, 0x49, 0x49, 0x49, 0x41},// E
{0x00, 0x7F, 0x09, 0x09, 0x09, 0x01},// F
{0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A},// G
{0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F},// H
{0x00, 0x00, 0x41, 0x7F, 0x41, 0x00},// I
{0x00, 0x20, 0x40, 0x41, 0x3F, 0x01},// J
{0x00, 0x7F, 0x08, 0x14, 0x22, 0x41},// K
{0x00, 0x7F, 0x40, 0x40, 0x40, 0x40},// L
{0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F},// M
{0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F},// N
{0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E},// O
{0x00, 0x7F, 0x09, 0x09, 0x09, 0x06},// P
{0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E},// Q
{0x00, 0x7F, 0x09, 0x19, 0x29, 0x46},// R
{0x00, 0x46, 0x49, 0x49, 0x49, 0x31},// S
{0x00, 0x01, 0x01, 0x7F, 0x01, 0x01},// T
{0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F},// U
{0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F},// V
{0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F},// W
{0x00, 0x63, 0x14, 0x08, 0x14, 0x63},// X
{0x00, 0x07, 0x08, 0x70, 0x08, 0x07},// Y
{0x00, 0x61, 0x51, 0x49, 0x45, 0x43},// Z
{0x00, 0x00, 0x7F, 0x41, 0x41, 0x00},// [
{0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55},// 55
{0x00, 0x00, 0x41, 0x41, 0x7F, 0x00},// ]
{0x00, 0x04, 0x02, 0x01, 0x02, 0x04},// ^
{0x00, 0x40, 0x40, 0x40, 0x40, 0x40},// _
{0x00, 0x00, 0x01, 0x02, 0x04, 0x00},// ’
{0x00, 0x20, 0x54, 0x54, 0x54, 0x78},// a
{0x00, 0x7F, 0x48, 0x44, 0x44, 0x38},// b
{0x00, 0x38, 0x44, 0x44, 0x44, 0x20},// c
{0x00, 0x38, 0x44, 0x44, 0x48, 0x7F},// d
{0x00, 0x38, 0x54, 0x54, 0x54, 0x18},// e
{0x00, 0x08, 0x7E, 0x09, 0x01, 0x02},// f
{0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C},// g
{0x00, 0x7F, 0x08, 0x04, 0x04, 0x78},// h
{0x00, 0x00, 0x44, 0x7D, 0x40, 0x00},// i
{0x00, 0x40, 0x80, 0x84, 0x7D, 0x00},// j
{0x00, 0x7F, 0x10, 0x28, 0x44, 0x00},// k
{0x00, 0x00, 0x41, 0x7F, 0x40, 0x00},// l
{0x00, 0x7C, 0x04, 0x18, 0x04, 0x78},// m
{0x00, 0x7C, 0x08, 0x04, 0x04, 0x78},// n
{0x00, 0x38, 0x44, 0x44, 0x44, 0x38},// o
{0x00, 0xFC, 0x24, 0x24, 0x24, 0x18},// p
{0x00, 0x18, 0x24, 0x24, 0x18, 0xFC},// q
{0x00, 0x7C, 0x08, 0x04, 0x04, 0x08},// r
{0x00, 0x48, 0x54, 0x54, 0x54, 0x20},// s
{0x00, 0x04, 0x3F, 0x44, 0x40, 0x20},// t
{0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C},// u
{0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C},// v
{0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C},// w
{0x00, 0x44, 0x28, 0x10, 0x28, 0x44},// x
{0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C},// y
{0x00, 0x44, 0x64, 0x54, 0x4C, 0x44},// z
{0x14, 0x14, 0x14, 0x14, 0x14, 0x14},// horiz lines

};

/***816的点阵/

unsigned char F8X16[]=
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 0
0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1
0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2
0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3
0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4
0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5
0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6
0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//’ 7
0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8
0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9
0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10
0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14
0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15

0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17
0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18
0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20
0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21
0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22
0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23
0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25

0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26
0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27
0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29
0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30
0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31
0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32
0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33
0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34
0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35
0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38
0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40
0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41
0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42
0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43
0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44
0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45
0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47
0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49
0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50
0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51
0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53
0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54
0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55
0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56
0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57
0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58
0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59
0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60
0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61
0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63
0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 64
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65
0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66
0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67
0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69
0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71
0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72
0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73
0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74
0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75
0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77
0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79
0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80
0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81
0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83
0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84
0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86
0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87
0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89
0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90
0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91
0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92
0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93
0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94

};

unsigned char F16X32[]=
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 0 !"#$%&’()*+,-./

0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x0F,0x0F,0x06,0x00,0x00,0x00,0x00,0x00,0x00,/"!",0/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x80,0xE0,0x78,0x3C,0x1C,0x80,0xE0,0x78,0x3C,0x1C,0x00,0x00,0x00,
0x00,0x00,0x03,0x01,0x00,0x00,0x00,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/""",1/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,
0x00,0x38,0x38,0x38,0xF8,0x3F,0x38,0x38,0x38,0x38,0x38,0xF8,0x3F,0x38,0x38,0x00,
0x00,0x70,0x70,0xF0,0xFF,0x70,0x70,0x70,0x70,0x70,0xF0,0xFF,0x70,0x70,0x70,0x00,
0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,/"#",2/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x00,0x80,0x80,0x40,0xF0,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x1E,0x7F,0xF0,0xC0,0xFF,0x00,0x00,0x0C,0x0F,0x0F,0x00,0x00,0x00,
0x00,0x00,0xC0,0xC0,0xC0,0x00,0x01,0xFF,0x07,0x07,0x1E,0xFC,0xF0,0x00,0x00,0x00,
0x00,0x00,0x03,0x07,0x04,0x08,0x08,0x7F,0x08,0x0C,0x06,0x03,0x01,0x00,0x00,0x00,/"$",3/
/* (16 X 32 , 宋体 )*/

0x00,0x80,0xC0,0x40,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,
0x7E,0xFF,0x00,0x00,0x00,0xFF,0x7E,0x00,0xE0,0x1C,0x03,0x00,0x00,0x00,0x00,0x00,
0x00,0x01,0x03,0x02,0x83,0x61,0x1C,0x03,0xF8,0xFE,0x03,0x01,0x03,0xFE,0xF8,0x00,
0x00,0x00,0x00,0x0C,0x03,0x00,0x00,0x00,0x01,0x07,0x0C,0x08,0x0C,0x07,0x01,0x00,/"%",4/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x80,0xC0,0x40,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x7F,0xFF,0xC0,0x80,0x60,0x3F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xF8,0xFC,0x03,0x03,0x0F,0x3E,0x78,0xE0,0x80,0x81,0x71,0x0F,0x01,0x01,0x00,0x00,
0x01,0x03,0x06,0x0C,0x08,0x08,0x08,0x05,0x03,0x07,0x0E,0x0C,0x0C,0x06,0x03,0x00,/"&",5/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x1C,0x1C,0xFC,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x02,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/"’",6/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x60,0x30,0x08,0x04,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFC,0x0F,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x7F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x0C,0x18,0x20,0x40,0x00,/"(",7/
/* (16 X 32 , 宋体 )*/

0x00,0x04,0x08,0x30,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x01,0x0F,0xFC,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x40,0x20,0x18,0x0C,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/")",8/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x38,0x30,0x60,0x40,0x86,0xFF,0x8F,0x40,0x60,0x30,0x38,0x18,0x00,
0x00,0x00,0x18,0x1C,0x0C,0x06,0x02,0xF1,0xFF,0xE1,0x02,0x06,0x0C,0x1C,0x18,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/"",9*/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/"+",10/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x80,0xC7,0x47,0x3F,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/",",11/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/"-",12/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x06,0x0F,0x0F,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/".",13/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x70,0x18,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x70,0x1C,0x07,0x01,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xC0,0x70,0x1C,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x30,0x1C,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/"/",14/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x40,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xF0,0xFE,0x0F,0x01,0x00,0x00,0x00,0x00,0x01,0x07,0xFE,0xF0,0x00,0x00,
0x00,0x00,0x3F,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x3F,0x00,0x00,
0x00,0x00,0x00,0x01,0x03,0x06,0x0C,0x08,0x08,0x08,0x06,0x03,0x01,0x00,0x00,0x00,/“0”,0/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x01,0x01,0x01,0x01,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x08,0x08,0x08,0x0C,0x0F,0x0F,0x0C,0x08,0x08,0x08,0x00,0x00,0x00,/“1”,1/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x00,0x80,0x40,0x40,0x40,0x40,0x40,0xC0,0x80,0x80,0x00,0x00,0x00,
0x00,0x00,0x1E,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC1,0xFF,0x3E,0x00,0x00,
0x00,0x00,0x00,0x00,0x80,0x40,0x30,0x18,0x0C,0x06,0x03,0x01,0x00,0xC0,0x00,0x00,
0x00,0x00,0x0E,0x0D,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0E,0x03,0x00,0x00,/“2”,2/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x80,0x80,0x40,0x40,0x40,0x40,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x80,0xC1,0x7F,0x3E,0x00,0x00,0x00,
0x00,0x00,0xC0,0xC0,0x00,0x00,0x01,0x01,0x01,0x03,0x02,0x06,0xFC,0xF0,0x00,0x00,
0x00,0x00,0x03,0x07,0x04,0x08,0x08,0x08,0x08,0x08,0x04,0x06,0x03,0x00,0x00,0x00,/“3”,3/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x80,0x60,0x10,0x0C,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,
0x00,0x30,0x2C,0x26,0x21,0x20,0x20,0x20,0x20,0xFF,0xFF,0x20,0x20,0x20,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x0F,0x0F,0x08,0x08,0x08,0x00,0x00,/“4”,4/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,
0x00,0x00,0x00,0xFF,0x00,0x80,0x40,0x40,0x40,0x40,0xC0,0x80,0x00,0x00,0x00,0x00,
0x00,0x00,0xC0,0xC3,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,
0x00,0x00,0x03,0x04,0x04,0x08,0x08,0x08,0x08,0x08,0x04,0x07,0x03,0x00,0x00,0x00,/“5”,5/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x40,0x40,0x40,0x40,0x80,0x80,0x00,0x00,0x00,
0x00,0x00,0xE0,0xFC,0x07,0x81,0xC0,0x40,0x40,0x40,0xC0,0x83,0x03,0x00,0x00,0x00,
0x00,0x00,0x7F,0xFF,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,
0x00,0x00,0x00,0x01,0x07,0x06,0x0C,0x08,0x08,0x08,0x0C,0x06,0x03,0x00,0x00,0x00,/“6”,6/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,
0x00,0x00,0x0E,0x03,0x00,0x00,0x00,0x00,0x00,0xE0,0x18,0x06,0x01,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/“7”,7/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x00,0x80,0xC0,0x40,0x40,0x40,0x40,0xC0,0x80,0x00,0x00,0x00,0x00,
0x00,0x00,0x3E,0x7F,0xF1,0xC0,0xC0,0x80,0x00,0x00,0x80,0x41,0x7F,0x1E,0x00,0x00,
0x00,0xF0,0xFC,0x0E,0x02,0x01,0x01,0x01,0x03,0x07,0x0E,0x1E,0xFC,0xF0,0x00,0x00,
0x00,0x01,0x03,0x06,0x04,0x08,0x08,0x08,0x08,0x08,0x04,0x06,0x03,0x01,0x00,0x00,/“8”,8/
/* (16 X 32 , 宋体 )*/

0x00,0x00,0x00,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFE,0xF8,0x00,0x00,
0x00,0x01,0x03,0x07,0x0C,0x08,0x08,0x08,0x08,0x04,0x06,0xE1,0x7F,0x1F,0x00,0x00,
0x00,0x00,0x07,0x07,0x08,0x08,0x08,0x08,0x0C,0x06,0x03,0x01,0x00,0x00,0x00,0x00,/“9”,9/
/* (16 X 32 , 宋体 )*/

};
unsigned char Hzk[][32]={
// 灯(0) 光(1) 调(2) 节(3)

{0x80,0x70,0x00,0xFF,0x20,0x10,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x00},
{0x80,0x60,0x18,0x07,0x08,0x30,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00},/“灯”,0/
/* (16 X 16 , 宋体 )*/

{0x40,0x40,0x42,0x44,0x58,0xC0,0x40,0x7F,0x40,0xC0,0x50,0x48,0x46,0x40,0x40,0x00},
{0x80,0x80,0x40,0x20,0x18,0x07,0x00,0x00,0x00,0x3F,0x40,0x40,0x40,0x40,0x78,0x00},/“光”,1/
/* (16 X 16 , 宋体 )*/

{0x40,0x42,0xCC,0x00,0x00,0xFE,0x82,0x92,0x92,0xFE,0x92,0x92,0x82,0xFE,0x00,0x00},
{0x00,0x00,0x3F,0x10,0x88,0x7F,0x00,0x1E,0x12,0x12,0x12,0x5E,0x80,0x7F,0x00,0x00},/“调”,2/
/* (16 X 16 , 宋体 )*/

{0x04,0x44,0x44,0x44,0x5F,0x44,0xC4,0x44,0x44,0x44,0x5F,0x44,0xC4,0x04,0x04,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x08,0x10,0x08,0x07,0x00,0x00,0x00},/“节”,3/
/* (16 X 16 , 宋体 )*/
};
#endif

struct ssd1307fb_par {
struct i2c_client *client;
struct fb_info *info;
struct pwm_device *pwm;
u32 pwm_period;
int reset;
};

static struct fb_fix_screeninfo ssd1307fb_fix = {
.id = “Solomon SSD1307”,
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_MONO10,
.xpanstep = 0,
.ypanstep = 0,
.ywrapstep = 0,
.line_length = SSD1307FB_WIDTH / 8,
.accel = FB_ACCEL_NONE,
};

static struct fb_var_screeninfo ssd1307fb_var = {
.xres = SSD1307FB_WIDTH,
.yres = SSD1307FB_HEIGHT,
.xres_virtual = SSD1307FB_WIDTH,
.yres_virtual = SSD1307FB_HEIGHT,
.bits_per_pixel = 1,
};

static int ssd1307fb_write_array(struct i2c_client *client, u8 type, u8 *cmd, u32 len)
{
u8 *buf;
int ret = 0;

buf = kzalloc(len + 1, GFP_KERNEL);
if (!buf) {
	dev_err(&client->dev, "Couldn't allocate sending buffer.\n");
	return -ENOMEM;
}

buf[0] = type;
memcpy(buf + 1, cmd, len);

ret = i2c_master_send(client, buf, len + 1);

if (ret != len + 1) {
	dev_err(&client->dev, "Couldn't send I2C command.\n");
	goto error;
}

error:
kfree(buf);
return ret;
}

static inline int ssd1307fb_write_cmd_array(struct i2c_client *client, u8 *cmd, u32 len)
{
return ssd1307fb_write_array(client, SSD1307FB_COMMAND, cmd, len);
}

static inline int ssd1307fb_write_cmd(struct i2c_client *client, u8 cmd)
{
return ssd1307fb_write_cmd_array(client, &cmd, 1);
}

static inline int ssd1307fb_write_data_array(struct i2c_client *client, u8 *cmd, u32 len)
{
return ssd1307fb_write_array(client, SSD1307FB_DATA, cmd, len);
}

static inline int ssd1307fb_write_data(struct i2c_client *client, u8 data)
{
return ssd1307fb_write_data_array(client, &data, 1);
}

#if 1
void OLED_Set_Pos(struct i2c_client *client,unsigned char x, unsigned char y)
{
ssd1307fb_write_cmd(client,0xb0 + y);
ssd1307fb_write_cmd(client,((x & 0xf0) >> 4) | 0x10);
ssd1307fb_write_cmd(client,(x&0x0f)|0x01);
}

void OLED_Clear(struct i2c_client *client)
{
u8 i, n;
for (i = 0; i<8; i++)
{
//OLED_WR_Byte(0xb0 + i, OLED_CMD); //设置页地址(0~7)
//OLED_WR_Byte(0x00, OLED_CMD); //设置显示位置—列低地址
//OLED_WR_Byte(0x10, OLED_CMD); //设置显示位置—列高地址
//for (n = 0; n<128; n++)OLED_WR_Byte(0, OLED_DATA);
ssd1307fb_write_cmd(client,0xb0 + i);
ssd1307fb_write_cmd(client,0x00);
ssd1307fb_write_cmd(client,0x10);
for (n = 0; n<128; n++)
{
ssd1307fb_write_data(client,0);
}
} //更新显示
}

void OLED_Clear_direct_area(struct i2c_client *client,int x,int y)
{
u8 i, n;
for (i = 0; i<x; i++)
{
ssd1307fb_write_cmd(client,0xb0 + i);
ssd1307fb_write_cmd(client,0x00);
ssd1307fb_write_cmd(client,0x10);
for (n = 0; n<y; n++)
{
ssd1307fb_write_data(client,0);
}
} //更新显示
}

//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
void ssd1306_init(struct i2c_client *client)
{
ssd1307fb_write_cmd(client,0xAE);//–turn off oled panel
ssd1307fb_write_cmd(client,0x02);//—set low column address
ssd1307fb_write_cmd(client,0x10);//—set high column address
ssd1307fb_write_cmd(client,0x40);//–set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
ssd1307fb_write_cmd(client,0x81);//–set contrast control register
ssd1307fb_write_cmd(client,0xCF); // Set SEG Output Current Brightness
ssd1307fb_write_cmd(client,0xA1);//–Set SEG/Column Mapping 0xa0×óóò·′?? 0xa1?y3£
ssd1307fb_write_cmd(client,0xC8);//Set COM/Row Scan Direction 0xc0é???·′?? 0xc8?y3£
ssd1307fb_write_cmd(client,0xA6);//–set normal display
ssd1307fb_write_cmd(client,0xA8);//–set multiplex ratio(1 to 64)
ssd1307fb_write_cmd(client,0x3f);//–1/64 duty
ssd1307fb_write_cmd(client,0xD3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
ssd1307fb_write_cmd(client,0x00);//-not offset
ssd1307fb_write_cmd(client,0xd5);//–set display clock divide ratio/oscillator frequency
ssd1307fb_write_cmd(client,0x80);//–set divide ratio, Set Clock as 100 Frames/Sec
ssd1307fb_write_cmd(client,0xD9);//–set pre-charge period
ssd1307fb_write_cmd(client,0xF1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
ssd1307fb_write_cmd(client,0xDA);//–set com pins hardware configuration
ssd1307fb_write_cmd(client,0x12);
ssd1307fb_write_cmd(client,0xDB);//–set vcomh
ssd1307fb_write_cmd(client,0x40);//Set VCOM Deselect Level
ssd1307fb_write_cmd(client,0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
ssd1307fb_write_cmd(client,0x02);//
ssd1307fb_write_cmd(client,0x8D);//–set Charge Pump enable/disable
ssd1307fb_write_cmd(client,0x14);//–set(0x10) disable
ssd1307fb_write_cmd(client,0xA4);// Disable Entire Display On (0xa4/0xa5)
ssd1307fb_write_cmd(client,0xA6);// Disable Inverse Display On (0xa6/a7)
ssd1307fb_write_cmd(client,0xAF);//–turn on oled panel
ssd1307fb_write_cmd(client,0xAF); /display ON/
}

//m^n函数
u32 oled_pow(u8 m, u8 n)
{
u32 result = 1;
while (n–)result *= m;
return result;
}

void OLED_ShowChar(struct i2c_client client,u8 x, u8 y, u8 chr, u8 Char_Size)
{
unsigned char c = 0, i = 0;
c = chr - ’ ';//得到偏移后的值
if (x>Max_Column - 1) { x = 0; y = y + 2; }
if(Char_Size>16)
{
OLED_Set_Pos(client,x, y);
for (i = 0; i<16; i++)
//OLED_WR_Byte(F16X32[c
64 + i], OLED_DATA);
ssd1307fb_write_data(client,F16X32[c64 + i]);
OLED_Set_Pos(client,x, y + 1);
for (i = 0; i<16; i++)
//OLED_WR_Byte(F16X32[c
64 + i + 16], OLED_DATA);
ssd1307fb_write_data(client,F16X32[c64 + i + 16]);
OLED_Set_Pos(client,x, y + 2);
for (i = 0; i<16; i++)
//OLED_WR_Byte(F16X32[c
64+ i +32], OLED_DATA);
ssd1307fb_write_data(client,F16X32[c64+ i +32]);
OLED_Set_Pos(client,x, y + 3);
for (i = 0; i<16; i++)
//OLED_WR_Byte(F16X32[c
64 + i + 48], OLED_DATA);
ssd1307fb_write_data(client,F16X32[c*64 + i + 48]);
}
else if (Char_Size == 16)
{
OLED_Set_Pos(client,x, y);
for (i = 0; i<8; i++)
//OLED_WR_Byte(F8X16[c * 16 + i], OLED_DATA);
ssd1307fb_write_data(client,F8X16[c * 16 + i]);
OLED_Set_Pos(client,x, y + 1);
for (i = 0; i<8; i++)
//OLED_WR_Byte(F8X16[c * 16 + i + 8], OLED_DATA);
ssd1307fb_write_data(client,F8X16[c * 16 + i + 8]);
}
else
{
OLED_Set_Pos(client,x, y);
for (i = 0; i<6; i++)
//OLED_WR_Byte(F6x8[c][i], OLED_DATA);
ssd1307fb_write_data(client,F6x8[c][i]);
}
}

//显示2个数字
//x,y :起点坐标
//len :数字的位数
//size:字体大小
//mode:模式 0,填充模式;1,叠加模式
//num:数值(0~4294967295);
void OLED_ShowNum(struct i2c_client *client,u8 x, u8 y, u32 num, u8 len, u8 size2)
{
u8 t, temp;
u8 enshow = 0;
for (t = 0; t<len; t++)
{
temp = (num / oled_pow(10, len - t - 1)) % 10;
if (enshow == 0 && t<(len - 1))
{
if (temp == 0)
{
OLED_ShowChar(client,x + (size2 / 2)*t, y, ’ ', size2);
continue;
}
else enshow = 1;

	}
	OLED_ShowChar(client,x + (size2 / 2)*t, y, temp + '0', size2);
}

}

//显示一个字符号串
void OLED_ShowString(struct i2c_client *client,u8 x, u8 y, u8 *chr, u8 Char_Size)
{
unsigned char j = 0;

while (chr[j] != '\0')
{
	OLED_ShowChar(client,x, y, chr[j], Char_Size);
	x += 8;
	if (x>120) { x = 0; y += 2; }
	j++;
}

}

//显示汉字
void OLED_ShowCHinese(struct i2c_client *client,u8 x, u8 y, u8 no)
{
u8 t, adder = 0;
OLED_Set_Pos(client,x, y);
for (t = 0; t<16; t++)
{
//OLED_WR_Byte(Hzk[2 * no][t], OLED_DATA);
ssd1307fb_write_data(client,Hzk[2 * no][t]);
adder += 1;
}
OLED_Set_Pos(client,x, y + 1);
for (t = 0; t<16; t++)
{
//OLED_WR_Byte(Hzk[2 * no + 1][t], OLED_DATA);
ssd1307fb_write_data(client,Hzk[2 * no + 1][t]);
adder += 1;
}
}
#endif

static void ssd1307fb_update_display(struct ssd1307fb_par *par)
{
u8 *vmem = par->info->screen_base;
int i, j, k;

/*
 * The screen is divided in pages, each having a height of 8
 * pixels, and the width of the screen. When sending a byte of
 * data to the controller, it gives the 8 bits for the current
 * column. I.e, the first byte are the 8 bits of the first
 * column, then the 8 bits for the second column, etc.
 *
 *
 * Representation of the screen, assuming it is 5 bits
 * wide. Each letter-number combination is a bit that controls
 * one pixel.
 *
 * A0 A1 A2 A3 A4
 * B0 B1 B2 B3 B4
 * C0 C1 C2 C3 C4
 * D0 D1 D2 D3 D4
 * E0 E1 E2 E3 E4
 * F0 F1 F2 F3 F4
 * G0 G1 G2 G3 G4
 * H0 H1 H2 H3 H4
 *
 * If you want to update this screen, you need to send 5 bytes:
 *  (1) A0 B0 C0 D0 E0 F0 G0 H0
 *  (2) A1 B1 C1 D1 E1 F1 G1 H1
 *  (3) A2 B2 C2 D2 E2 F2 G2 H2
 *  (4) A3 B3 C3 D3 E3 F3 G3 H3
 *  (5) A4 B4 C4 D4 E4 F4 G4 H4
 */

for (i = 0; i < (SSD1307FB_HEIGHT / 8); i++) {
	ssd1307fb_write_cmd(par->client, SSD1307FB_START_PAGE_ADDRESS + (i + 1));
	ssd1307fb_write_cmd(par->client, 0x00);
	ssd1307fb_write_cmd(par->client, 0x10);

	for (j = 0; j < SSD1307FB_WIDTH; j++) {
		u8 buf = 0;
		for (k = 0; k < 8; k++) {
			u32 page_length = SSD1307FB_WIDTH * i;
			u32 index = page_length + (SSD1307FB_WIDTH * k + j) / 8;
			u8 byte = *(vmem + index);
			u8 bit = byte & (1 << (j % 8));
			bit = bit >> (j % 8);
			buf |= bit << k;
		}
		ssd1307fb_write_data(par->client, buf);
	}
}

}

static int ssd1307fb_open(struct fb_info *info, int user)
{
return 0;
}

static ssize_t ssd1307fb_write(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos)
{
struct ssd1307fb_par *par = info->par;
unsigned long total_size;
unsigned long p = *ppos;
u8 __iomem *dst;

total_size = info->fix.smem_len;

if (p > total_size)
	return -EINVAL;

if (count + p > total_size)
	count = total_size - p;

if (!count)
	return -EINVAL;

dst = (void __force *) (info->screen_base + p);

if (copy_from_user(dst, buf, count))
	return -EFAULT;

ssd1307fb_update_display(par);

*ppos += count;

return count;

}

static void ssd1307fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
struct ssd1307fb_par *par = info->par;
sys_fillrect(info, rect);
ssd1307fb_update_display(par);
}

static void ssd1307fb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{
struct ssd1307fb_par *par = info->par;
sys_copyarea(info, area);
ssd1307fb_update_display(par);
}

static void ssd1307fb_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct ssd1307fb_par *par = info->par;
sys_imageblit(info, image);
ssd1307fb_update_display(par);
}

struct ioctl_data{
int x;
int y;
int size;
char buf[40];
};

static int ssd1307fb_ioctl(struct fb_info *info, unsigned int cmd,unsigned long arg)
{
struct ssd1307fb_par *par = info->par;
struct ioctl_data val;

//printk("cmd =====ssd1307fb_ioctl===== %d \r\n",cmd);
memset(&val,0,sizeof(struct ioctl_data));

if (copy_from_user(&val,(struct ioctl_data*)arg,sizeof(struct ioctl_data))) 
{
	printk("======copy_from_user====failed== \r\n");
}

switch(cmd)
{
	case 1:   //show char
	{
		//printk("===========show char=========\r\n");
	}
	break;
	case 3:   //show string
	{
		OLED_ShowString(par->client,val.x,val.y,val.buf,val.size);
	}
	break;    //show chinese
	case 4:
	{
		//printk("===========show chinese=========\r\n");
		OLED_ShowCHinese(par->client,0,0,0);//中
		OLED_ShowCHinese(par->client,18,0,1);//景
		OLED_ShowCHinese(par->client,36,0,2);//园
		OLED_ShowCHinese(par->client,54,0,3);//电
		OLED_ShowCHinese(par->client,72,0,4);//子
		OLED_ShowCHinese(par->client,90,0,5);//科
		OLED_ShowCHinese(par->client,108,0,6);//技	
	}
	break;
	case 5:  //clear screen 
	{
		OLED_Clear(par->client); 
	}
	break;
	case 6:  //clear designated area 
	{
		OLED_Clear_direct_area(par->client,val.x,val.y); 
	}
	break;
	default:
	{
	
	}
	break;

}
return 0;

}

static struct fb_ops ssd1307fb_ops = {
.owner = THIS_MODULE,
.fb_read = fb_sys_read,
.fb_write = ssd1307fb_write,
.fb_fillrect = ssd1307fb_fillrect,
.fb_copyarea = ssd1307fb_copyarea,
.fb_imageblit = ssd1307fb_imageblit,
.fb_ioctl = ssd1307fb_ioctl,
.fb_open = ssd1307fb_open,
};

static void ssd1307fb_deferred_io(struct fb_info *info,
struct list_head *pagelist)
{
ssd1307fb_update_display(info->par);
}

static struct fb_deferred_io ssd1307fb_defio = {
.delay = HZ,
.deferred_io = ssd1307fb_deferred_io,
};

static int ssd1307fb_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct fb_info *info;
u32 vmem_size = SSD1307FB_WIDTH * SSD1307FB_HEIGHT / 8;
struct ssd1307fb_par *par;
u8 *vmem;
int ret;

if (!client->dev.of_node) {
	dev_err(&client->dev, "No device tree data found!\n");
	return -EINVAL;
}

info = framebuffer_alloc(sizeof(struct ssd1307fb_par), &client->dev);
if (!info) {
	dev_err(&client->dev, "Couldn't allocate framebuffer.\n");
	return -ENOMEM;
}

vmem = devm_kzalloc(&client->dev, vmem_size, GFP_KERNEL);
if (!vmem) {
	dev_err(&client->dev, "Couldn't allocate graphical memory.\n");
	ret = -ENOMEM;
	goto fb_alloc_error;
}

info->fbops = &ssd1307fb_ops;
info->fix = ssd1307fb_fix;
info->fbdefio = &ssd1307fb_defio;

info->var = ssd1307fb_var;
info->var.red.length = 1;
info->var.red.offset = 0;
info->var.green.length = 1;
info->var.green.offset = 0;
info->var.blue.length = 1;
info->var.blue.offset = 0;

info->screen_base = (u8 __force __iomem *)vmem;
info->fix.smem_start = (unsigned long)vmem;
info->fix.smem_len = vmem_size;

fb_deferred_io_init(info);

par = info->par;
par->info = info;
par->client = client;

par->reset = of_get_named_gpio(client->dev.of_node,
				 "reset-gpios", 0);
if (!gpio_is_valid(par->reset)) {
	ret = -EINVAL;
	goto reset_oled_error;
}
ret = devm_gpio_request_one(&client->dev, par->reset,
			    GPIOF_OUT_INIT_HIGH,
			    "oled-reset");
if (ret) {
	dev_err(&client->dev,
		"failed to request gpio %d: %d\n",
		par->reset, ret);
	goto reset_oled_error;
}

/* Reset the screen */
gpio_set_value(par->reset, 1);
mdelay(100);	
gpio_set_value(par->reset, 0);
mdelay(100);
gpio_set_value(par->reset, 1);

#if 1   
ssd1306_init(client);			//初始化OLED  
OLED_Clear(client); 
#endif

ret = register_framebuffer(info);
if (ret) {
	dev_err(&client->dev, "Couldn't register the framebuffer\n");
	goto fbreg_error;
}

i2c_set_clientdata(client, info);

return 0;

//remap_error:
//unregister_framebuffer(info);
//pwm_disable(par->pwm);
fbreg_error:
//pwm_put(par->pwm);
//pwm_error:
reset_oled_error:
fb_deferred_io_cleanup(info);
fb_alloc_error:
framebuffer_release(info);
return ret;
}

static int ssd1307fb_remove(struct i2c_client *client)
{
struct fb_info *info = i2c_get_clientdata(client);
struct ssd1307fb_par *par = info->par;

unregister_framebuffer(info);
pwm_disable(par->pwm);
pwm_put(par->pwm);
fb_deferred_io_cleanup(info);
framebuffer_release(info);

return 0;

}

static const struct i2c_device_id ssd1307fb_i2c_id[] = {
{ “ssd1307fb”, 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ssd1307fb_i2c_id);

static const struct of_device_id ssd1307fb_of_match[] = {
{ .compatible = “solomon,ssd1307fb-i2c” },
{},
};
MODULE_DEVICE_TABLE(of, ssd1307fb_of_match);

static struct i2c_driver ssd1307fb_driver = {
.probe = ssd1307fb_probe,
.remove = ssd1307fb_remove,
.id_table = ssd1307fb_i2c_id,
.driver = {
.name = “ssd1307fb”,
.of_match_table = of_match_ptr(ssd1307fb_of_match),
.owner = THIS_MODULE,
},
};

module_i2c_driver(ssd1307fb_driver);
MODULE_DESCRIPTION(“FB driver for the Solomon SSD1307 OLED controller”);
MODULE_AUTHOR(“Maxime Ripard maxime.ripard@free-electrons.com”);
MODULE_LICENSE(“GPL”);

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值