发 帖  
[问答]

请问一下如何去实现rk3288 i2c接口的OLED驱动呢

2442 OLED驱动 I2C接口 RK3288

*/
#define OLED_CMD_INIT       0x100001
#define OLED_CMD_CLEAR_ALL  0x100002
#define OLED_CMD_SHOW_STR    0x100003
#define OLED_CMD_SHOW_CN      0x100004
#define OLED_CMD_SHOW_BMP   0x100005
#define OLED_CMD_SET_POS        0X100006
#define OLED_CMD_FILL      0x100007
int fd;
inline static void OLED_SetPos(unsigned char x, unsigned char y)
{
ioctl(fd,OLED_CMD_SET_POS,((y&0xff)<<8)|(x&0xff));
}
inline static  void WriteDat(unsigned char data)
{
//ioctl(fd, OLED_CMD_SHOW_STR,data);
write(fd, &data, 1);
}
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
{
unsigned char c = 0,i = 0,j = 0;
switch(TextSize)
{
case 1:
{
while(ch[j] != '')
{
c = ch[j] - 32;
if(x > 126)
{
x = 0;
y++;
}
OLED_SetPos(x,y);
for(i=0;i<6;i++)
WriteDat(F6x8[c]);
x += 6;
j++;
}
}break;
case 2:
{
while(ch[j] != '')
{
c = ch[j] - 32;
if(x > 120)
{
x = 0;
y++;
}
OLED_SetPos(x,y);
for(i=0;i<8;i++)
WriteDat(F8X16[c*16+i]);
OLED_SetPos(x,y+1);
for(i=0;i<8;i++)
WriteDat(F8X16[c*16+i+8]);
x += 8;
j++;
}
}break;
}
}
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
{
unsigned char wm=0;
unsigned int  adder=32*N;
OLED_SetPos(x , y);
for(wm = 0;wm < 16;wm++)
{
WriteDat(F16x16[adder]);
adder += 1;
}
OLED_SetPos(x,y + 1);
for(wm = 0;wm < 16;wm++)
{
WriteDat(F16x16[adder]);
adder += 1;
}
}
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
{
unsigned int j=0;
unsigned char x,y;
  if(y1%8==0)
y = y1/8;
  else
y = y1/8 + 1;
for(y=y0;y {
OLED_SetPos(x0,y);
    for(x=x0;x {
WriteDat(BMP[j++]);
}
}
}
void print_usage(char *cmd)
{
    printf("Usage:n");
    printf("%s initn", cmd);
    printf("%s clearn", cmd);
    printf("%s x y n", cmd);
    printf("%s filln", cmd);
    printf("eg:n");
    printf("%s 2 0 chenxiaodann", cmd);
    printf("%s 0 0 126 7 bmp", cmd);
    printf("posX is 0,1,...,126n");
    printf("posY is 0,1,...,7n");
}
int main(int argc, char **argv)
{
    int do_init  = 0;
    int do_clear = 0;
    int do_show  = 0;
    int do_show_bmp = 0;
    int do_fill = 0;
    int posX=-1;
    int posY=-1;
    int x_end = -1;
    int y_end = -1;
    if (argc == 2 && !strcmp(argv[1], "init"))
        do_init = 1;
    if ((argc == 2) && !strcmp(argv[1], "clear"))
    {
        do_clear = 1;
    }
    if ((argc == 2) && !strcmp(argv[1], "fill"))
    {
        do_fill = 1;
    }
    if (argc == 4)
    {
        do_show = 1;
        posX = strtoul(argv[1], NULL, 0);
        posY = strtoul(argv[2], NULL, 0);
    }
    if (argc == 5)
    {
    do_show_bmp = 1;
        posX = strtoul(argv[1], NULL, 0);
        posY = strtoul(argv[2], NULL, 0);
        x_end = strtoul(argv[3], NULL, 0);
        y_end = strtoul(argv[4], NULL, 0);
printf("pos: %d %d %d %dn", posX, posY, x_end, y_end);
    }
    if (!do_init && !do_clear && !do_show && !do_fill && !do_show_bmp)
    {
        print_usage(argv[0]);
        return -1;
    }
    fd = open("/dev/i2c-oled", O_RDWR);
    if (fd < 0)
    {
        printf("can't open /dev/i2c-oledn");
        return -1;
    }
  if (do_init)
        ioctl(fd, OLED_CMD_INIT);
    else if (do_clear)
    {
        ioctl(fd, OLED_CMD_CLEAR_ALL);
    }
    else if (do_fill)
    {
        ioctl(fd, OLED_CMD_FILL, 1);
    }
    else if (do_show)
    {
        if (posX < 0 || posX > 126)
        {
            printf("x is 0,1,...,126n");
            return -1;
        }
        if (posY < 0 || posY > 7)
        {
            printf("y is 0,1,...,7n");
            return -1;
        }
OLED_ShowStr(posX, posY,argv[3],1);
    }
    else if(do_show_bmp)
    {
    printf("show bmp.n");
OLED_DrawBMP(posX, posY,x_end, y_end, (unsigned char *)BMP1);   
    }
    return 0;
}
驱动的移植,主要还是使用厂家提供的裸板程序,再按照linux的i2c框架添加进去,驱动部分就是注册一个i2c_driver结构体,里面有一个of_match_table 它表示能支持的设备的compatible属性。设备部分现在使用设备树文件,再注册完adapt之后就会去其节点下面的设备一个一个的取出去构造i2c_board_info结构体,其中设备的地址通过设备树的reg属性指定。再设备树的compatible和驱动文件的compatible匹配时就会调用probe函数,然后再probe里面把oled屏注册为一个字符设备,字符设备的fops负责设备的ioctl和write .
附上一张点亮的效果

原作者:风见暗含
0
2022-5-11 10:22:45   评论 分享淘帖 邀请回答 举报
2个回答
2022-5-16 09:05:42 评论

举报

撰写答案

你正在撰写答案

如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。

您需要登录后才可以回帖 登录/注册

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
快速回复 返回顶部 返回列表
关注微信公众号

电子发烧友网

电子发烧友论坛

社区合作
刘勇
联系电话:15994832713
邮箱地址:liuyong@huaqiu.com
社区管理
elecfans短短
微信:elecfans_666
邮箱:users@huaqiu.com
关闭

站长推荐 上一条 /6 下一条

快速回复 返回顶部 返回列表